diff --git a/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx b/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx index aa9fbb19a37..96608586509 100644 --- a/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -52,381 +53,426 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include +#include #include +#include #include #include +#define C_CS(cs) \ + [](std::index_sequence) { \ + static_assert(std::is_array_v>); \ + return ConstStr<(cs)[indices]...>{}; \ + }(std::make_index_sequence{}) +#define C_SV(sv) \ + [](std::index_sequence) { \ + static_assert(std::same_as, std::string_view>); \ + return ConstStr<(sv)[indices]...>{}; \ + }(std::make_index_sequence<(sv).size()>{}) + using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -namespace o2 -{ -namespace aod +namespace o2::aod { using JoinedCollisions = soa::Join; using JoinedTracks = soa::Join; using JoinedCollisionsWithMc = soa::Join; using JoinedTracksWithMc = soa::Join; using JoinedMcCollisions = soa::Join; -} // namespace aod -} // namespace o2 +namespace derived_collision +{ +DECLARE_SOA_COLUMN(Vz, vz, std::int8_t); +DECLARE_SOA_COLUMN(Centrality, centrality, std::uint16_t); +DECLARE_SOA_COLUMN(NChargedParticlesAll, nChargedParticlesAll, std::uint16_t); +DECLARE_SOA_COLUMN(NChargedParticlesIn, nChargedParticlesIn, std::uint16_t); +DECLARE_SOA_COLUMN(NTracksAll, nTracksAll, std::uint16_t); +DECLARE_SOA_COLUMN(NTracksIn, nTracksIn, std::uint16_t); +} // namespace derived_collision + +DECLARE_SOA_TABLE(DerivedCollisions, "AOD", "DERIVEDCOLLISION", o2::soa::Index<>, derived_collision::Vz, derived_collision::Centrality, derived_collision::NChargedParticlesAll, derived_collision::NChargedParticlesIn, derived_collision::NTracksAll, derived_collision::NTracksIn); +using DerivedCollision = DerivedCollisions::iterator; + +namespace derived_particle +{ +DECLARE_SOA_INDEX_COLUMN(DerivedCollision, derivedCollision); +DECLARE_SOA_COLUMN(SignedEfficiency, signedEfficiency, std::int16_t); +} // namespace derived_particle + +DECLARE_SOA_TABLE(DerivedParticles, "AOD", "DERIVEDPARTICLE", o2::soa::Index<>, derived_particle::DerivedCollisionId, derived_particle::SignedEfficiency); +using DerivedParticle = DerivedParticles::iterator; + +namespace derived_track +{ +DECLARE_SOA_INDEX_COLUMN(DerivedCollision, derivedCollision); +DECLARE_SOA_COLUMN(SignedEfficiency, signedEfficiency, std::int16_t); +} // namespace derived_track + +DECLARE_SOA_TABLE(DerivedTracks, "AOD", "DERIVEDTRACK", o2::soa::Index<>, derived_track::DerivedCollisionId, derived_track::SignedEfficiency); +using DerivedTrack = DerivedTracks::iterator; +} // namespace o2::aod + +namespace +{ namespace fluctuation_calculator_base { -inline constexpr std::int8_t MaxOrder = 8; -inline constexpr std::uint8_t NExponentPairs = 36; -inline constexpr std::uint16_t NOrderVectors = 342; -inline constexpr std::array, NExponentPairs> ExponentPairs = {{{1, 1}, {2, 1}, {2, 2}, {3, 1}, {3, 2}, {3, 3}, {4, 1}, {4, 2}, {4, 3}, {4, 4}, {5, 1}, {5, 2}, {5, 3}, {5, 4}, {5, 5}, {6, 1}, {6, 2}, {6, 3}, {6, 4}, {6, 5}, {6, 6}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 5}, {7, 6}, {7, 7}, {8, 1}, {8, 2}, {8, 3}, {8, 4}, {8, 5}, {8, 6}, {8, 7}, {8, 8}}}; -inline constexpr std::array, NOrderVectors> OrderVectors = {{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {6, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}}; +inline constexpr std::int32_t NExponentPairs{36}; +inline constexpr std::int32_t NOrderVectors{342}; +inline constexpr std::array, NExponentPairs> ExponentPairs{{{1, 1}, {2, 1}, {2, 2}, {3, 1}, {3, 2}, {3, 3}, {4, 1}, {4, 2}, {4, 3}, {4, 4}, {5, 1}, {5, 2}, {5, 3}, {5, 4}, {5, 5}, {6, 1}, {6, 2}, {6, 3}, {6, 4}, {6, 5}, {6, 6}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 5}, {7, 6}, {7, 7}, {8, 1}, {8, 2}, {8, 3}, {8, 4}, {8, 5}, {8, 6}, {8, 7}, {8, 8}}}; +inline constexpr std::array, NOrderVectors> OrderVectors{ + {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {6, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}}; } // namespace fluctuation_calculator_base class FluctuationCalculatorTrack @@ -437,8 +483,8 @@ class FluctuationCalculatorTrack double getProductFast(const std::int32_t orderVectorIndex, const double weight = 1.) const { - double product = 1.; - for (std::int32_t const& iExponentPair : std::views::iota(0, static_cast(fluctuation_calculator_base::NExponentPairs))) { + double product{1.}; + for (std::int32_t const& iExponentPair : std::views::iota(0, fluctuation_calculator_base::NExponentPairs)) { if (fluctuation_calculator_base::OrderVectors[orderVectorIndex][iExponentPair]) { product *= std::pow(mQs[iExponentPair], fluctuation_calculator_base::OrderVectors[orderVectorIndex][iExponentPair]); } @@ -448,7 +494,7 @@ class FluctuationCalculatorTrack void init() { mQs.fill(0.); } void fill(const double charge, const double efficiency, const double weight = 1.) { - for (std::int32_t const& iExponentPair : std::views::iota(0, static_cast(fluctuation_calculator_base::NExponentPairs))) { + for (std::int32_t const& iExponentPair : std::views::iota(0, fluctuation_calculator_base::NExponentPairs)) { mQs[iExponentPair] += std::pow(charge, fluctuation_calculator_base::ExponentPairs[iExponentPair].first) / std::pow(efficiency, fluctuation_calculator_base::ExponentPairs[iExponentPair].second) * weight; } } @@ -457,21 +503,198 @@ class FluctuationCalculatorTrack std::array mQs; }; -struct PartNumFluc { - enum class CentralityDefinition { kFt0a = 0, - kFt0c, - kFt0m, - kNDefinitions }; - enum class ParticleSpecies { kPi = 0, - kKa, - kPr, - kNSpecies }; - enum class PidStrategy { kTpc = 0, - kTof, - kTpcAndTof, - kTpcTof, - kNStrategies }; +template +concept IsValidEnum = ((std::is_enum_v> && requires { std::remove_cvref_t::kN; }) && ...); +template +concept IsValid = IsValidEnum...> && ((es != std::remove_cvref_t::kN) && ...); + +template + requires IsValidEnum +inline constexpr std::int32_t toI(const E e) +{ + return static_cast(e); +} + +template + requires IsValidEnum +inline constexpr std::int32_t NEs{toI(E::kN)}; + +template + requires IsValidEnum +struct EnumInfo; + +enum class NameKind { kDefault = 0, + kLower, + kDisplay, + kDisplayLower, + kN }; +template + requires IsValidEnum +inline constexpr std::string_view getName(const std::int32_t index) +{ + if constexpr (nameKind == NameKind::kLower) { + return EnumInfo>::NamesLower.at(index); + } else if constexpr (nameKind == NameKind::kDisplay) { + return EnumInfo>::DisplayNames.at(index); + } else if constexpr (nameKind == NameKind::kDisplayLower) { + return EnumInfo>::DisplayNamesLower.at(index); + } else { + return EnumInfo>::Names.at(index); + } +} +template + requires IsValidEnum +inline constexpr std::string_view getName(const E e) +{ + return getName(toI(e)); +} +template + requires IsValidEnum +inline std::vector getDisplayNames() +{ + return std::vector(EnumInfo>::DisplayNames.begin(), EnumInfo>::DisplayNames.end()); +} + +enum class DataMode { kMcMcParticle = 0, + kMcTrack, + kRawTrack, + kN }; +enum class CentralityDefinition { kFt0a = 0, + kFt0c, + kFt0m, + kN }; +enum class DcaKind { kMean = 0, + kSigma, + kN }; +enum class DcaAxis { kXy = 0, + kZ, + kN }; +enum class Detector { kTpc = 0, + kTof, + kN }; +enum class PidStrategy { kTpc = 0, + kTpcTof, + kN }; +enum class PidStrategyAll { kTpc = 0, + kTof, + kTpcTofSeparated, + kTpcTofCombined, + kN }; +enum class ParticleSpecies { kPion = 0, + kKaon, + kProton, + kN }; +enum class ParticleSpeciesAll { kAll = 0, + kPion, + kKaon, + kProton, + kN }; +enum class ParticleNumber { kCharge = 0, + kKaon, + kProton, + kN }; +enum class ChargeSpecies { kPlus = 0, + kMinus, + kN }; +enum class ChargeNumber { kPlus = 0, + kMinus, + kTotal, + kNet, + kN }; + +template <> +struct EnumInfo { + static constexpr std::array> Names{"Mean", "Sigma"}; +}; +template <> +struct EnumInfo { + static constexpr std::array> Names{"Xy", "Z"}; + static constexpr std::array> DisplayNames{"Xy", "Z"}; +}; +template <> +struct EnumInfo { + static constexpr std::array> Names{"Tpc", "Tof"}; + static constexpr std::array> NamesLower{"tpc", "tof"}; + static constexpr std::array> DisplayNames{"TPC", "TOF"}; + static constexpr std::array> PidStrategyAllValues{PidStrategyAll::kTpc, PidStrategyAll::kTof}; +}; +template <> +struct EnumInfo { + static constexpr std::array> Names{"Tpc", "TpcTof"}; + static constexpr std::array> NamesLower{"tpc", "tpcTof"}; + static constexpr std::array> DisplayNames{"TPC", "TPC+TOF"}; + static constexpr std::array> PidStrategyAllValues{PidStrategyAll::kTpc, PidStrategyAll::kTpcTofCombined}; +}; +template <> +struct EnumInfo { + static constexpr std::array> Names{"Pi", "Ka", "Pr"}; + static constexpr std::array> DisplayNames{"Pion", "Kaon", "Proton"}; + static constexpr std::array> DisplayNamesLower{"pion", "kaon", "proton"}; + static constexpr std::array> ParticleSpeciesAllValues{ParticleSpeciesAll::kPion, ParticleSpeciesAll::kKaon, ParticleSpeciesAll::kProton}; +}; +template <> +struct EnumInfo { + static constexpr std::array> Names{"", "Pi", "Ka", "Pr"}; + static constexpr std::array> DisplayNames{"All", "Pion", "Kaon", "Proton"}; + static constexpr std::array> DisplayNamesLower{"all", "pion", "kaon", "proton"}; + static constexpr std::array> ParticleSpeciesValues{ParticleSpecies::kN, ParticleSpecies::kPion, ParticleSpecies::kKaon, ParticleSpecies::kProton}; + static constexpr std::array>, NEs> PdgCodes{{{0, 0}, {PDG_t::kPiPlus, PDG_t::kPiMinus}, {PDG_t::kKPlus, PDG_t::kKMinus}, {PDG_t::kProton, PDG_t::kProtonBar}}}; + static constexpr std::array> Masses{0., constants::physics::MassPiPlus, constants::physics::MassKPlus, constants::physics::MassProton}; +}; +template <> +struct EnumInfo { + static constexpr std::array> Names{"Ch", "Ka", "Pr"}; + static constexpr std::array> DisplayNames{"Charge", "Kaon", "Proton"}; + static constexpr std::array> DisplayNamesLower{"charge", "kaon", "proton"}; +}; +template <> +struct EnumInfo { + static constexpr std::array> Names{"P", "M"}; + static constexpr std::array> NamesLower{"p", "m"}; +}; +template <> +struct EnumInfo { + static constexpr std::array> Names{"P", "M", "T", "N"}; +}; +template + requires IsValidEnum +inline constexpr To getValue(const E e) +{ + if constexpr (std::is_same_v, PidStrategyAll>) { + return EnumInfo::PidStrategyAllValues[toI(e)]; + } else if constexpr (std::is_same_v, ParticleSpecies>) { + return EnumInfo::ParticleSpeciesValues[toI(e)]; + } else if constexpr (std::is_same_v, ParticleSpeciesAll>) { + return EnumInfo::ParticleSpeciesAllValues[toI(e)]; + } + return To::kN; +} +inline constexpr std::int32_t getPdgCode(const ParticleSpeciesAll e, const ChargeSpecies chargeSpecies) +{ + return EnumInfo::PdgCodes[toI(e)][toI(chargeSpecies)]; +} +inline constexpr double getMass(const ParticleSpeciesAll e) +{ + return EnumInfo::Masses[toI(e)]; +} + +template + requires std::is_arithmetic_v +inline constexpr std::int32_t nEnabled(const Configurable>& cfg) +{ + const LabeledArray& la{cfg.value}; + return std::count_if(la[0], la[0] + la.rows() * la.cols(), [](T x) { return x != T{}; }); +} +template + requires std::is_arithmetic_v +inline constexpr bool isEnabled(const Configurable>& cfg) +{ + return nEnabled(cfg) > 0; +} +} // namespace + +struct PartNumFluc { struct : ConfigurableGroup { Configurable cfgCcdbUrl{"cfgCcdbUrl", "http://ccdb-test.cern.ch:8080", "Url of CCDB"}; Configurable cfgCcdbPath{"cfgCcdbPath", "Users/f/fasi/test", "Path in CCDB"}; @@ -484,42 +707,25 @@ struct PartNumFluc { Configurable cfgFlagQaCentrality{"cfgFlagQaCentrality", false, "Centrality QA flag"}; Configurable cfgFlagQaTrack{"cfgFlagQaTrack", false, "Track QA flag"}; Configurable cfgFlagQaDca{"cfgFlagQaDca", false, "DCA QA flag"}; - Configurable cfgFlagQaAcceptance{"cfgFlagQaAcceptance", false, "Acceptance QA flag"}; - Configurable cfgFlagQaAcceptancePi{"cfgFlagQaAcceptancePi", false, "Pion acceptance QA flag"}; - Configurable cfgFlagQaAcceptanceKa{"cfgFlagQaAcceptanceKa", false, "Kaon acceptance QA flag"}; - Configurable cfgFlagQaAcceptancePr{"cfgFlagQaAcceptancePr", false, "(Anti)proton acceptance QA flag"}; - Configurable cfgFlagQaPhi{"cfgFlagQaPhi", false, "Phi QA flag"}; - Configurable cfgFlagQaPhiPi{"cfgFlagQaPhiPi", false, "Pion Phi QA flag"}; - Configurable cfgFlagQaPhiKa{"cfgFlagQaPhiKa", false, "Kaon Phi QA flag"}; - Configurable cfgFlagQaPhiPr{"cfgFlagQaPhiPr", false, "(Anti)proton Phi QA flag"}; - Configurable cfgFlagQaPid{"cfgFlagQaPid", false, "PID QA flag"}; - Configurable cfgFlagQaPidPi{"cfgFlagQaPidPi", false, "Pion PID QA flag"}; - Configurable cfgFlagQaPidKa{"cfgFlagQaPidKa", false, "Kaon PID QA flag"}; - Configurable cfgFlagQaPidPr{"cfgFlagQaPidPr", false, "(Anti)proton PID QA flag"}; + Configurable> cfgFlagQaAcceptance{"cfgFlagQaAcceptance", {std::array>{false, false, false, false}.data(), NEs, getDisplayNames()}, "Acceptance QA flag"}; + Configurable> cfgFlagQaPhi{"cfgFlagQaPhi", {std::array>{false, false, false, false}.data(), NEs, getDisplayNames()}, "Phi QA flag"}; + Configurable> cfgFlagQaPid{"cfgFlagQaPid", {std::array>{false, false, false, false}.data(), NEs, getDisplayNames()}, "PID QA flag"}; Configurable cfgFlagQaMc{"cfgFlagQaMc", false, "MC QA flag"}; - Configurable cfgFlagCalculationYieldPi{"cfgFlagCalculationYieldPi", false, "Pion yield calculation flag"}; - Configurable cfgFlagCalculationYieldKa{"cfgFlagCalculationYieldKa", false, "Kaon yield calculation flag"}; - Configurable cfgFlagCalculationYieldPr{"cfgFlagCalculationYieldPr", false, "(Anti)proton yield calculation flag"}; - Configurable cfgFlagCalculationPurityPi{"cfgFlagCalculationPurityPi", false, "Pion purity calculation flag"}; - Configurable cfgFlagCalculationPurityKa{"cfgFlagCalculationPurityKa", false, "Kaon purity calculation flag"}; - Configurable cfgFlagCalculationPurityPr{"cfgFlagCalculationPurityPr", false, "(Anti)proton purity calculation flag"}; - Configurable cfgFlagCalculationFractionPrimaryPi{"cfgFlagCalculationFractionPrimaryPi", false, "Pion primary fraction calculation flag"}; - Configurable cfgFlagCalculationFractionPrimaryKa{"cfgFlagCalculationFractionPrimaryKa", false, "Kaon primary fraction calculation flag"}; - Configurable cfgFlagCalculationFractionPrimaryPr{"cfgFlagCalculationFractionPrimaryPr", false, "(Anti)proton primary fraction calculation flag"}; - Configurable cfgFlagCalculationFluctuationCh{"cfgFlagCalculationFluctuationCh", false, "Charge number fluctuation calculation flag"}; - Configurable cfgFlagCalculationFluctuationKa{"cfgFlagCalculationFluctuationKa", false, "Kaon number fluctuation calculation flag"}; - Configurable cfgFlagCalculationFluctuationPr{"cfgFlagCalculationFluctuationPr", false, "(Anti)proton number fluctuation calculation flag"}; + Configurable> cfgFlagCalculationYield{"cfgFlagCalculationYield", {std::array>{false, false, false}.data(), NEs, getDisplayNames()}, "Yield calculation flag"}; + Configurable> cfgFlagCalculationPurity{"cfgFlagCalculationPurity", {std::array>{false, false, false}.data(), NEs, getDisplayNames()}, "Purity calculation flag"}; + Configurable> cfgFlagCalculationFractionPrimary{"cfgFlagCalculationFractionPrimary", {std::array>{false, false, false}.data(), NEs, getDisplayNames()}, "Primary fraction calculation flag"}; + Configurable> cfgFlagCalculationFluctuation{"cfgFlagCalculationFluctuation", {std::array>{false, false, false}.data(), NEs, getDisplayNames()}, "Fluctuation calculation flag"}; } groupAnalysis; struct : ConfigurableGroup { - Configurable cfgFlagRejectionRunBad{"cfgFlagRejectionRunBad", true, "Bad run rejection flag"}; + Configurable cfgFlagRejectionRunBad{"cfgFlagRejectionRunBad", false, "Bad run rejection flag"}; Configurable cfgFlagRejectionRunBadMc{"cfgFlagRejectionRunBadMc", false, "MC bad run rejection flag"}; Configurable cfgLabelFlagsRct{"cfgLabelFlagsRct", "CBT_hadronPID", "RCT flags label"}; - Configurable cfgBitsSelectionEvent{"cfgBitsSelectionEvent", 0b10000000001101000000000000000000000000000000000000ULL, "Event selection bits"}; + Configurable cfgBitsSelectionEvent{"cfgBitsSelectionEvent", std::uint64_t{0b10000000001101000000000000000000000000000000000000}, "Event selection bits"}; Configurable cfgFlagInelEvent{"cfgFlagInelEvent", true, "Flag of requiring inelastic event"}; Configurable cfgFlagInelEventMc{"cfgFlagInelEventMc", false, "Flag of requiring inelastic MC event"}; - Configurable cfgCutMaxAbsVertexZ{"cfgCutMaxAbsVertexZ", 6., "Maximum absolute vertex z position (cm)"}; - Configurable cfgCutMaxAbsVertexZMc{"cfgCutMaxAbsVertexZMc", 999., "Maximum absolute MC vertex z position (cm) for MC"}; + Configurable cfgCutMaxAbsVz{"cfgCutMaxAbsVz", 6., "Maximum absolute z-vertex position (cm)"}; + Configurable cfgFlagCutVzMc{"cfgFlagCutVzMc", false, "Flag of requiring MC z-vertex cut"}; Configurable cfgCutMinDeviationNPvContributors{"cfgCutMinDeviationNPvContributors", -4, "Minimum nPvContributors deviation from nGlobalTracks"}; Configurable cfgIndexDefinitionCentrality{"cfgIndexDefinitionCentrality", 2, "Centrality definition index"}; ConfigurableAxis cfgAxisCentrality{"cfgAxisCentrality", {VARIABLE_WIDTH, 0., 5., 10., 15., 20., 25., 30., 35., 40., 45., 50., 55., 60., 65., 70., 75., 80., 85., 90.}, "Centrality axis in fluctuation calculation"}; @@ -536,17 +742,12 @@ struct PartNumFluc { Configurable cfgCutMinTpcNCrossedRows{"cfgCutMinTpcNCrossedRows", 75, "Minimum number of crossed rows TPC"}; Configurable cfgCutMinTpcNCrossedRowsRatio{"cfgCutMinTpcNCrossedRowsRatio", 0.8, "Minimum ratio of crossed rows over findable clusters TPC"}; Configurable cfgFlagRecalibrationDca{"cfgFlagRecalibrationDca", false, "DCA recalibration flag"}; - Configurable cfgCutMaxAbsNSigmaDcaXy{"cfgCutMaxAbsNSigmaDcaXy", 2.5, "Maximum absolute nSigma of DCAxy (cm)"}; - Configurable cfgCutMaxAbsNSigmaDcaZ{"cfgCutMaxAbsNSigmaDcaZ", 2.5, "Maximum absolute nSigma of DCAz (cm)"}; + Configurable> cfgCutMaxAbsNSigmaDca{"cfgCutMaxAbsNSigmaDca", {std::array>{2.5, 2.5}.data(), NEs, getDisplayNames()}, "Maximum absolute nSigma of DCA (cm)"}; Configurable cfgCutMinPt{"cfgCutMinPt", 0.4, "Minimum pT (GeV/c)"}; Configurable cfgCutMaxPt{"cfgCutMaxPt", 2., "Maximum pT (GeV/c)"}; Configurable cfgCutMaxAbsEta{"cfgCutMaxAbsEta", 0.8, "Maximum absolute eta"}; - Configurable cfgThresholdPtTofPi{"cfgThresholdPtTofPi", 0.5, "pT (GeV/c) threshold for TOF pions"}; - Configurable cfgThresholdPtTofKa{"cfgThresholdPtTofKa", 0.5, "pT (GeV/c) threshold for TOF kaons"}; - Configurable cfgThresholdPtTofPr{"cfgThresholdPtTofPr", 0.8, "pT (GeV/c) threshold for TOF (anti)protons"}; - Configurable cfgFlagRecalibrationNSigmaPi{"cfgFlagRecalibrationNSigmaPi", false, "nSigmaPi recalibration flag"}; - Configurable cfgFlagRecalibrationNSigmaKa{"cfgFlagRecalibrationNSigmaKa", false, "nSigmaKa recalibration flag"}; - Configurable cfgFlagRecalibrationNSigmaPr{"cfgFlagRecalibrationNSigmaPr", false, "nSigmaPr recalibration flag"}; + Configurable> cfgThresholdPtTofPid{"cfgThresholdPtTofPid", {std::array>{0.5, 0.5, 0.8}.data(), NEs, getDisplayNames()}, "pT (GeV/c) threshold for TOF PID"}; + Configurable> cfgFlagRecalibrationNSigmaPid{"cfgFlagRecalibrationNSigmaPid", {std::array>{false, false, false}.data(), NEs, getDisplayNames()}, "nSigma PID recalibration flag"}; Configurable cfgFlagRejectionOthers{"cfgFlagRejectionOthers", false, "Other particle species rejection flag"}; Configurable cfgCutMaxAbsNSigmaPid{"cfgCutMaxAbsNSigmaPid", 2., "Maximum absolute nSigma for PID"}; Configurable cfgFlagMcParticlePhysicalPrimary{"cfgFlagMcParticlePhysicalPrimary", true, "Flag of requiring physical primary MC particle"}; @@ -558,82 +759,24 @@ struct PartNumFluc { Service pdg; Service ccdb; + Produces derivedCollision; + Produces derivedParticle; + Produces derivedTrack; + struct HolderCcdb { - std::map> runNumbersIndicesGroupIndices; - - std::vector fPtMeanDcaXyP; - std::vector fPtMeanDcaXyM; - std::vector fPtMeanDcaZP; - std::vector fPtMeanDcaZM; - std::vector fPtSigmaDcaXyP; - std::vector fPtSigmaDcaXyM; - std::vector fPtSigmaDcaZP; - std::vector fPtSigmaDcaZM; - - std::vector hCentralityPtEtaShiftTpcNSigmaPiP; - std::vector hCentralityPtEtaShiftTpcNSigmaPiM; - std::vector hCentralityPtEtaShiftTpcNSigmaKaP; - std::vector hCentralityPtEtaShiftTpcNSigmaKaM; - std::vector hCentralityPtEtaShiftTpcNSigmaPrP; - std::vector hCentralityPtEtaShiftTpcNSigmaPrM; - std::vector hCentralityPtEtaShiftTofNSigmaPiP; - std::vector hCentralityPtEtaShiftTofNSigmaPiM; - std::vector hCentralityPtEtaShiftTofNSigmaKaP; - std::vector hCentralityPtEtaShiftTofNSigmaKaM; - std::vector hCentralityPtEtaShiftTofNSigmaPrP; - std::vector hCentralityPtEtaShiftTofNSigmaPrM; - - std::vector hVzCentralityPtEtaEfficiencyTpcPiP; - std::vector hVzCentralityPtEtaEfficiencyTpcPiM; - std::vector hVzCentralityPtEtaEfficiencyTpcKaP; - std::vector hVzCentralityPtEtaEfficiencyTpcKaM; - std::vector hVzCentralityPtEtaEfficiencyTpcPrP; - std::vector hVzCentralityPtEtaEfficiencyTpcPrM; - std::vector hVzCentralityPtEtaEfficiencyTpcTofPiP; - std::vector hVzCentralityPtEtaEfficiencyTpcTofPiM; - std::vector hVzCentralityPtEtaEfficiencyTpcTofKaP; - std::vector hVzCentralityPtEtaEfficiencyTpcTofKaM; - std::vector hVzCentralityPtEtaEfficiencyTpcTofPrP; - std::vector hVzCentralityPtEtaEfficiencyTpcTofPrM; + static constexpr std::int32_t NDimensionsEfficiency{4}; + + std::map> runNumbersIndicesGroupIndices{}; + std::vector>, NEs>, NEs>> fPtDca{}; + std::vector>, NEs>, NEs>> hCentralityPtEtaShiftNSigmaPid{}; + std::vector>, NEs>, NEs>> hVzCentralityPtEtaEfficiency{}; void clear() { runNumbersIndicesGroupIndices.clear(); - - fPtMeanDcaXyP.clear(); - fPtMeanDcaXyM.clear(); - fPtMeanDcaZP.clear(); - fPtMeanDcaZM.clear(); - fPtSigmaDcaXyP.clear(); - fPtSigmaDcaXyM.clear(); - fPtSigmaDcaZP.clear(); - fPtSigmaDcaZM.clear(); - - hCentralityPtEtaShiftTpcNSigmaPiP.clear(); - hCentralityPtEtaShiftTpcNSigmaPiM.clear(); - hCentralityPtEtaShiftTpcNSigmaKaP.clear(); - hCentralityPtEtaShiftTpcNSigmaKaM.clear(); - hCentralityPtEtaShiftTpcNSigmaPrP.clear(); - hCentralityPtEtaShiftTpcNSigmaPrM.clear(); - hCentralityPtEtaShiftTofNSigmaPiP.clear(); - hCentralityPtEtaShiftTofNSigmaPiM.clear(); - hCentralityPtEtaShiftTofNSigmaKaP.clear(); - hCentralityPtEtaShiftTofNSigmaKaM.clear(); - hCentralityPtEtaShiftTofNSigmaPrP.clear(); - hCentralityPtEtaShiftTofNSigmaPrM.clear(); - - hVzCentralityPtEtaEfficiencyTpcPiP.clear(); - hVzCentralityPtEtaEfficiencyTpcPiM.clear(); - hVzCentralityPtEtaEfficiencyTpcKaP.clear(); - hVzCentralityPtEtaEfficiencyTpcKaM.clear(); - hVzCentralityPtEtaEfficiencyTpcPrP.clear(); - hVzCentralityPtEtaEfficiencyTpcPrM.clear(); - hVzCentralityPtEtaEfficiencyTpcTofPiP.clear(); - hVzCentralityPtEtaEfficiencyTpcTofPiM.clear(); - hVzCentralityPtEtaEfficiencyTpcTofKaP.clear(); - hVzCentralityPtEtaEfficiencyTpcTofKaM.clear(); - hVzCentralityPtEtaEfficiencyTpcTofPrP.clear(); - hVzCentralityPtEtaEfficiencyTpcTofPrM.clear(); + fPtDca.clear(); + hCentralityPtEtaShiftNSigmaPid.clear(); + hVzCentralityPtEtaEfficiency.clear(); } } holderCcdb; @@ -642,53 +785,54 @@ struct PartNumFluc { std::int32_t runIndex{}; std::int32_t runGroupIndex{}; double vz{}; - std::int32_t nChP{}; - std::int32_t nChM{}; - std::int32_t nKaP{}; - std::int32_t nKaM{}; - std::int32_t nPrP{}; - std::int32_t nPrM{}; + std::array>, NEs> numbers{}; + std::array>, NEs> numbersEff{}; - void clear() - { - *this = {}; - } + void clear() { *this = {}; } } holderMcEvent; struct HolderEvent { - static constexpr std::pair RangeCentrality = {0., 100.}; + static constexpr std::pair RangeCentrality{0., 100.}; std::int32_t runNumber{}; std::int32_t runIndex{}; std::int32_t runGroupIndex{}; double vz{}; - std::int32_t nGlobalTracksP{}; - std::int32_t nGlobalTracksM{}; - std::int32_t nPvContributorsP{}; - std::int32_t nPvContributorsM{}; - double meanDcaXyP{}; - double meanDcaXyM{}; - double meanSquareDcaXyP{}; - double meanSquareDcaXyM{}; - double meanDcaZP{}; - double meanDcaZM{}; - double meanSquareDcaZP{}; - double meanSquareDcaZM{}; - std::int32_t nTofBetaP{}; - std::int32_t nTofBetaM{}; + std::array> nGlobalTracks{}; + std::array> nPvContributors{}; + std::array>, NEs>, NEs> dca{}; + std::array> nTofBeta{}; double centrality{}; std::int32_t subgroupIndex{}; - std::int32_t nChP{}; - std::int32_t nChM{}; - std::int32_t nKaP{}; - std::int32_t nKaM{}; - std::int32_t nPrP{}; - std::int32_t nPrM{}; - - void clear() + std::array>, NEs> numbers{}; + + void clear() { *this = {}; } + std::int32_t getNGlobalTracks() const { return std::accumulate(nGlobalTracks.begin(), nGlobalTracks.end(), 0); } + std::int32_t getNPvContributors() const { return std::accumulate(nPvContributors.begin(), nPvContributors.end(), 0); } + template + requires IsValid + double getDca() const { - *this = {}; + const std::int32_t sumNGlobalTracks{getNGlobalTracks()}; + if (sumNGlobalTracks == 0) { + return 0.; + } + + double sumDca{}; + if constexpr (dcaKind == DcaKind::kSigma) { + const double meanDca{getDca()}; + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + sumDca += (std::pow(dca[toI(DcaKind::kSigma)][toI(dcaAxis)][iChargeSpecies], 2.) + std::pow(dca[toI(DcaKind::kMean)][toI(dcaAxis)][iChargeSpecies] - meanDca, 2.)) * nGlobalTracks[iChargeSpecies]; + } + return std::sqrt(sumDca / sumNGlobalTracks); + } + + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + sumDca += dca[toI(DcaKind::kMean)][toI(dcaAxis)][iChargeSpecies] * nGlobalTracks[iChargeSpecies]; + } + return sumDca / sumNGlobalTracks; } + std::int32_t getNTofBeta() const { return std::accumulate(nTofBeta.begin(), nTofBeta.end(), 0); } } holderEvent; struct HolderMcParticle { @@ -698,53 +842,52 @@ struct PartNumFluc { double eta{}; double phi{}; - void clear() - { - *this = {}; - } + void clear() { *this = {}; } } holderMcParticle; struct HolderTrack { - static constexpr double TruncationAbsNSigmaPid = 999.; - static constexpr double truncateNSigmaPid(const double value) { return (!(std::abs(value) < TruncationAbsNSigmaPid) ? -TruncationAbsNSigmaPid : value); } + static constexpr double TruncationAbsNSigmaPid{999.}; + static constexpr double truncateNSigmaPid(const double value) { return std::abs(value) < TruncationAbsNSigmaPid ? value : -TruncationAbsNSigmaPid; } - double dcaXY{}; - double dcaZ{}; + std::array> dca{}; std::int32_t sign{}; double p{}; double pt{}; double eta{}; double phi{}; - bool hasTpcPid{}; - double tpcNSigmaPi{}; - double tpcNSigmaKa{}; - double tpcNSigmaPr{}; - bool hasTofPid{}; - double tofNSigmaPi{}; - double tofNSigmaKa{}; - double tofNSigmaPr{}; - double tpcTofNSigmaPi{}; - double tpcTofNSigmaKa{}; - double tpcTofNSigmaPr{}; + std::array> hasPid{}; + std::array>, NEs> nSigmaPid{[] { + std::array>, NEs> a{}; + std::array> b{}; + b.fill(-TruncationAbsNSigmaPid); + a.fill(b); + return a; + }()}; + + void clear() { *this = {}; } + } holderTrack; - void clear() + struct HolderDerivedData { + template + static constexpr T convertFloor(const double value) { - *this = {}; + return std::numeric_limits::min() <= value && value <= std::numeric_limits::max() ? std::floor(value) : (std::is_signed_v ? std::numeric_limits::min() : std::numeric_limits::max()); } - } holderTrack; + template + static constexpr T convertRound(const double value) + { + return std::numeric_limits::min() <= value && value <= std::numeric_limits::max() ? std::round(value) : (std::is_signed_v ? std::numeric_limits::min() : std::numeric_limits::max()); + } + + std::uint16_t nChargedParticlesAll{}; + std::uint16_t nChargedParticlesIn{}; + std::uint16_t nTracksAll{}; + std::uint16_t nTracksIn{}; - std::unique_ptr fluctuationCalculatorTrackChP; - std::unique_ptr fluctuationCalculatorTrackChM; - std::unique_ptr fluctuationCalculatorTrackChT; - std::unique_ptr fluctuationCalculatorTrackChN; - std::unique_ptr fluctuationCalculatorTrackKaP; - std::unique_ptr fluctuationCalculatorTrackKaM; - std::unique_ptr fluctuationCalculatorTrackKaT; - std::unique_ptr fluctuationCalculatorTrackKaN; - std::unique_ptr fluctuationCalculatorTrackPrP; - std::unique_ptr fluctuationCalculatorTrackPrM; - std::unique_ptr fluctuationCalculatorTrackPrT; - std::unique_ptr fluctuationCalculatorTrackPrN; + void clear() { *this = {}; } + } holderDerivedData; + + std::array, NEs>, NEs> fluctuationCalculatorTrack{}; HistogramRegistry hrCalculationFluctuation{"hrCalculationFluctuation", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry hrCalculationFractionPrimary{"hrCalculationFractionPrimary", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -792,43 +935,58 @@ struct PartNumFluc { ccdb->setCreatedNotAfter(groupCcdb.cfgCcdbTimestampLatest.value > 0 ? groupCcdb.cfgCcdbTimestampLatest.value : std::chrono::time_point_cast(std::chrono::system_clock::now()).time_since_epoch().count()); } - const TList* const ccdbObject = ccdb->getForTimeStamp(groupCcdb.cfgCcdbPath.value, -1); + const TList* const ccdbObject{ccdb->getForTimeStamp(groupCcdb.cfgCcdbPath.value, -1)}; if (!ccdbObject || ccdbObject->IsA() != TList::Class()) { LOG(fatal) << "Invalid ccdb_object!"; } + holderCcdb.clear(); - const TGraph* const gRunNumberGroupIndex = dynamic_cast(ccdbObject->FindObject("gRunNumberGroupIndex")); - if (!gRunNumberGroupIndex || gRunNumberGroupIndex->IsA() != TGraph::Class()) { - LOG(fatal) << "Invalid gRunNumberGroupIndex!"; + std::int32_t nRunsBad{}; + std::int32_t nRunGroups{}; + { + const TGraph* const gRunNumberGroupIndex{dynamic_cast(ccdbObject->FindObject("gRunNumberGroupIndex"))}; + if (!gRunNumberGroupIndex || gRunNumberGroupIndex->IsA() != TGraph::Class()) { + LOG(fatal) << "Invalid gRunNumberGroupIndex!"; + } + for (std::int32_t const& iRun : std::views::iota(0, gRunNumberGroupIndex->GetN())) { + const std::int32_t runGroupIndex{static_cast(std::llrint(gRunNumberGroupIndex->GetY()[iRun]))}; + if (runGroupIndex == 0 || (groupEvent.cfgFlagRejectionRunBad.value && runGroupIndex < 0)) { + ++nRunsBad; + } + nRunGroups = std::max(nRunGroups, std::abs(runGroupIndex)); + holderCcdb.runNumbersIndicesGroupIndices[std::llrint(gRunNumberGroupIndex->GetX()[iRun])] = {iRun, runGroupIndex}; + } } - holderCcdb.clear(); - std::int32_t nRunsBad = 0; - std::int32_t nRunGroups = 0; - for (std::int32_t const& iRun : std::views::iota(0, gRunNumberGroupIndex->GetN())) { - const std::int32_t runGroupIndex = std::llrint(gRunNumberGroupIndex->GetY()[iRun]); - if (runGroupIndex == 0 || (groupEvent.cfgFlagRejectionRunBad.value && runGroupIndex < 0)) { - nRunsBad++; + if (groupEvent.cfgFlagRejectionRunBadMc.value) { + const TGraph* const gRunNumberGroupIndex{dynamic_cast(ccdbObject->FindObject("gRunNumberGroupIndex_mc"))}; + if (!gRunNumberGroupIndex || gRunNumberGroupIndex->IsA() != TGraph::Class()) { + LOG(fatal) << "Invalid gRunNumberGroupIndex_mc!"; + } + for (std::int32_t const& iRun : std::views::iota(0, gRunNumberGroupIndex->GetN())) { + if (std::llrint(gRunNumberGroupIndex->GetY()[iRun]) <= 0) { + auto iter = holderCcdb.runNumbersIndicesGroupIndices.find(std::llrint(gRunNumberGroupIndex->GetX()[iRun])); + if (iter != holderCcdb.runNumbersIndicesGroupIndices.end() && iter->second.second > 0) { + iter->second.second = -iter->second.second; + ++nRunsBad; + } + } } - nRunGroups = std::max(nRunGroups, std::abs(runGroupIndex)); - holderCcdb.runNumbersIndicesGroupIndices[std::llrint(gRunNumberGroupIndex->GetX()[iRun])] = std::pair(iRun, runGroupIndex); } if (holderCcdb.runNumbersIndicesGroupIndices.empty()) { LOG(info) << "No run process enabled."; } else { LOG(info) << "Number of runs: " << holderCcdb.runNumbersIndicesGroupIndices.size(); - for (const auto& [runNumber, runIndexGroupIndex] : holderCcdb.runNumbersIndicesGroupIndices) { - LOG(info) << "Enabling processing run: " << runNumber << " (" << std::abs(runIndexGroupIndex.second) << ")"; + if (nRunsBad <= 0) { + LOG(info) << "No run rejection enabled."; + } else { + LOG(info) << "Number of bad runs: " << nRunsBad; } - } - - if (nRunsBad <= 0) { - LOG(info) << "No run rejection enabled."; - } else { - LOG(info) << "Number of bad runs: " << nRunsBad; for (const auto& [runNumber, runIndexGroupIndex] : holderCcdb.runNumbersIndicesGroupIndices) { if (runIndexGroupIndex.second == 0 || (groupEvent.cfgFlagRejectionRunBad.value && runIndexGroupIndex.second < 0)) { - LOG(info) << "Enabling rejecting run: " << runNumber; + LOG(info) << "Enabling rejecting run: " << runNumber << " (" << runIndexGroupIndex.second << ")"; + } else { + LOG(info) << "Enabling processing run: " << runNumber << " (" << std::abs(runIndexGroupIndex.second) << ")"; } } } @@ -839,7 +997,7 @@ struct PartNumFluc { LOG(info) << "Enabling RCT flags label: " << groupEvent.cfgLabelFlagsRct.value; } - if ((groupEvent.cfgBitsSelectionEvent.value & ((1ULL << aod::evsel::EventSelectionFlags::kNsel) - 1)) == 0) { + if ((groupEvent.cfgBitsSelectionEvent.value & ((std::uint64_t{1} << aod::evsel::EventSelectionFlags::kNsel) - 1)) == 0) { LOG(info) << "No event selection bit enabled."; } else { for (std::int32_t const& iEvSel : std::views::iota(0, aod::evsel::EventSelectionFlags::kNsel)) { @@ -850,10 +1008,10 @@ struct PartNumFluc { } switch (groupEvent.cfgIndexDefinitionCentrality.value) { - case static_cast(CentralityDefinition::kFt0a): + case toI(CentralityDefinition::kFt0a): LOG(info) << "Enabling centrality definition: FT0A"; break; - case static_cast(CentralityDefinition::kFt0c): + case toI(CentralityDefinition::kFt0c): LOG(info) << "Enabling centrality definition: FT0C"; break; default: @@ -862,94 +1020,55 @@ struct PartNumFluc { } const auto readListRunGroup = [&](const std::int32_t runGroupIndex) -> const TList* { - const std::string name = Form("lRunGroup_%d", runGroupIndex); - const TList* const lRunGroup = dynamic_cast(ccdbObject->FindObject(name.c_str())); - if (!lRunGroup || lRunGroup->IsA() != TList::Class()) { + const char* const name{Form("lRunGroup_%d", runGroupIndex)}; + const TList* const lRunGroup{dynamic_cast(ccdbObject->FindObject(name))}; + if (!lRunGroup) { LOG(fatal) << "Invalid " << name << "!"; } return lRunGroup; }; - const auto readFormula = [&](const TList* const lRunGroup, const char* const nameBase, const bool doAddingSuffixMc, const std::int32_t runGroupIndex) -> const TFormula* { - const std::string name = Form("%s%s_runGroup%d", nameBase, doAddingSuffixMc ? "_mc" : "", runGroupIndex); - const TFormula* const formula = dynamic_cast(lRunGroup->FindObject(name.c_str())); - if (!formula || formula->IsA() != TFormula::Class()) { - LOG(fatal) << "Invalid " << name << "!"; - } - LOG(info) << "Reading from CCDB: " << formula->GetName() << " \"" << formula->GetExpFormula("clingp") << "\""; - return formula; - }; - const auto readH3 = [&](const TList* const lRunGroup, const char* const nameBase, const bool doAddingSuffixMc, const std::int32_t runGroupIndex) -> const TH3* { - const std::string name = Form("%s%s_runGroup%d", nameBase, doAddingSuffixMc ? "_mc" : "", runGroupIndex); - const TH3* const h3 = dynamic_cast(lRunGroup->FindObject(name.c_str())); - if (!h3 || !h3->InheritsFrom(TH3::Class())) { - LOG(fatal) << "Invalid " << name << "!"; - } - LOG(info) << "Reading from CCDB: " << h3->GetName(); - return h3; - }; - const auto readHn = [&](const TList* const lRunGroup, const char* const nameBase, const bool doAddingSuffixMc, const std::int32_t runGroupIndex, const std::int32_t nDimensions) -> const THnBase* { - const std::string name = Form("%s%s_runGroup%d", nameBase, doAddingSuffixMc ? "_mc" : "", runGroupIndex); - const THnBase* const hn = dynamic_cast(lRunGroup->FindObject(name.c_str())); - if (!hn || !hn->InheritsFrom(THnBase::Class()) || hn->GetNdimensions() != nDimensions) { - LOG(fatal) << "Invalid " << name << "!"; - } - LOG(info) << "Reading from CCDB: " << hn->GetName(); - return hn; - }; if (groupTrack.cfgFlagRecalibrationDca.value) { LOG(info) << "Enabling DCA recalibration."; - holderCcdb.fPtMeanDcaXyP.resize(nRunGroups); - holderCcdb.fPtMeanDcaXyM.resize(nRunGroups); - holderCcdb.fPtMeanDcaZP.resize(nRunGroups); - holderCcdb.fPtMeanDcaZM.resize(nRunGroups); - holderCcdb.fPtSigmaDcaXyP.resize(nRunGroups); - holderCcdb.fPtSigmaDcaXyM.resize(nRunGroups); - holderCcdb.fPtSigmaDcaZP.resize(nRunGroups); - holderCcdb.fPtSigmaDcaZM.resize(nRunGroups); + holderCcdb.fPtDca.resize(nRunGroups); for (std::int32_t const& iRunGroup : std::views::iota(0, nRunGroups)) { - const TList* const lRunGroup = readListRunGroup(iRunGroup + 1); - holderCcdb.fPtMeanDcaXyP[iRunGroup] = readFormula(lRunGroup, "fPtMeanDcaXyP", doprocessMc.value, iRunGroup + 1); - holderCcdb.fPtMeanDcaXyM[iRunGroup] = readFormula(lRunGroup, "fPtMeanDcaXyM", doprocessMc.value, iRunGroup + 1); - holderCcdb.fPtMeanDcaZP[iRunGroup] = readFormula(lRunGroup, "fPtMeanDcaZP", doprocessMc.value, iRunGroup + 1); - holderCcdb.fPtMeanDcaZM[iRunGroup] = readFormula(lRunGroup, "fPtMeanDcaZM", doprocessMc.value, iRunGroup + 1); - holderCcdb.fPtSigmaDcaXyP[iRunGroup] = readFormula(lRunGroup, "fPtSigmaDcaXyP", doprocessMc.value, iRunGroup + 1); - holderCcdb.fPtSigmaDcaXyM[iRunGroup] = readFormula(lRunGroup, "fPtSigmaDcaXyM", doprocessMc.value, iRunGroup + 1); - holderCcdb.fPtSigmaDcaZP[iRunGroup] = readFormula(lRunGroup, "fPtSigmaDcaZP", doprocessMc.value, iRunGroup + 1); - holderCcdb.fPtSigmaDcaZM[iRunGroup] = readFormula(lRunGroup, "fPtSigmaDcaZM", doprocessMc.value, iRunGroup + 1); - } - } - - if (groupTrack.cfgFlagRecalibrationNSigmaPi.value || groupTrack.cfgFlagRecalibrationNSigmaKa.value || groupTrack.cfgFlagRecalibrationNSigmaPr.value) { - const auto readH3ShiftNSigmaPid = [&](std::initializer_list*, const char*>> pairsVectorH3NameBase) { - for (const auto& [vectorH3, nameBase] : pairsVectorH3NameBase) { - vectorH3->resize(nRunGroups); - } - for (std::int32_t const& iRunGroup : std::views::iota(0, nRunGroups)) { - const TList* const lRunGroup = readListRunGroup(iRunGroup + 1); - for (const auto& [vectorH3, nameBase] : pairsVectorH3NameBase) { - (*vectorH3)[iRunGroup] = readH3(lRunGroup, nameBase, doprocessMc.value, iRunGroup + 1); + const TList* const lRunGroup{readListRunGroup(iRunGroup + 1)}; + for (std::int32_t const& iDcaKind : std::views::iota(0, NEs)) { + for (std::int32_t const& iDcaAxis : std::views::iota(0, NEs)) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + const char* const name{Form("fPt%sDca%s%s%s_runGroup%d", getName(iDcaKind).data(), getName(iDcaAxis).data(), getName(iChargeSpecies).data(), doprocessMc.value ? "_mc" : "", iRunGroup + 1)}; + holderCcdb.fPtDca[iRunGroup][iDcaKind][iDcaAxis][iChargeSpecies] = dynamic_cast(lRunGroup->FindObject(name)); + if (!holderCcdb.fPtDca[iRunGroup][iDcaKind][iDcaAxis][iChargeSpecies]) { + LOG(fatal) << "Invalid " << name << "!"; + } + LOG(info) << "Reading from CCDB: " << name << " \"" << holderCcdb.fPtDca[iRunGroup][iDcaKind][iDcaAxis][iChargeSpecies]->GetExpFormula("clingp") << "\""; + } } } - }; - - if (groupTrack.cfgFlagRecalibrationNSigmaPi.value) { - LOG(info) << "Enabling nSigmaPi recalibration."; - - readH3ShiftNSigmaPid({{&holderCcdb.hCentralityPtEtaShiftTpcNSigmaPiP, "hCentralityPtEtaShiftTpcNSigmaPiP"}, {&holderCcdb.hCentralityPtEtaShiftTpcNSigmaPiM, "hCentralityPtEtaShiftTpcNSigmaPiM"}, {&holderCcdb.hCentralityPtEtaShiftTofNSigmaPiP, "hCentralityPtEtaShiftTofNSigmaPiP"}, {&holderCcdb.hCentralityPtEtaShiftTofNSigmaPiM, "hCentralityPtEtaShiftTofNSigmaPiM"}}); } + } - if (groupTrack.cfgFlagRecalibrationNSigmaKa.value) { - LOG(info) << "Enabling nSigmaKa recalibration."; - - readH3ShiftNSigmaPid({{&holderCcdb.hCentralityPtEtaShiftTpcNSigmaKaP, "hCentralityPtEtaShiftTpcNSigmaKaP"}, {&holderCcdb.hCentralityPtEtaShiftTpcNSigmaKaM, "hCentralityPtEtaShiftTpcNSigmaKaM"}, {&holderCcdb.hCentralityPtEtaShiftTofNSigmaKaP, "hCentralityPtEtaShiftTofNSigmaKaP"}, {&holderCcdb.hCentralityPtEtaShiftTofNSigmaKaM, "hCentralityPtEtaShiftTofNSigmaKaM"}}); + for (std::int32_t const& iParticleSpecies : std::views::iota(0, NEs)) { + if (!groupTrack.cfgFlagRecalibrationNSigmaPid.value.get(iParticleSpecies)) { + continue; } - if (groupTrack.cfgFlagRecalibrationNSigmaPr.value) { - LOG(info) << "Enabling nSigmaPr recalibration."; + LOG(info) << "Enabling nSigma" << getName(iParticleSpecies) << " recalibration."; - readH3ShiftNSigmaPid({{&holderCcdb.hCentralityPtEtaShiftTpcNSigmaPrP, "hCentralityPtEtaShiftTpcNSigmaPrP"}, {&holderCcdb.hCentralityPtEtaShiftTpcNSigmaPrM, "hCentralityPtEtaShiftTpcNSigmaPrM"}, {&holderCcdb.hCentralityPtEtaShiftTofNSigmaPrP, "hCentralityPtEtaShiftTofNSigmaPrP"}, {&holderCcdb.hCentralityPtEtaShiftTofNSigmaPrM, "hCentralityPtEtaShiftTofNSigmaPrM"}}); + holderCcdb.hCentralityPtEtaShiftNSigmaPid.resize(nRunGroups); + for (std::int32_t const& iRunGroup : std::views::iota(0, nRunGroups)) { + const TList* const lRunGroup{readListRunGroup(iRunGroup + 1)}; + for (std::int32_t const& iDetector : std::views::iota(0, NEs)) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + const char* const name{Form("hCentralityPtEtaShift%sNSigma%s%s%s_runGroup%d", getName(iDetector).data(), getName(iParticleSpecies).data(), getName(iChargeSpecies).data(), doprocessMc.value ? "_mc" : "", iRunGroup + 1)}; + holderCcdb.hCentralityPtEtaShiftNSigmaPid[iRunGroup][iDetector][iParticleSpecies][iChargeSpecies] = dynamic_cast(lRunGroup->FindObject(name)); + if (!holderCcdb.hCentralityPtEtaShiftNSigmaPid[iRunGroup][iDetector][iParticleSpecies][iChargeSpecies]) { + LOG(fatal) << "Invalid " << name << "!"; + } + LOG(info) << "Reading from CCDB: " << name; + } + } } } @@ -963,68 +1082,49 @@ struct PartNumFluc { const HistogramConfigSpec hcsQaRun(HistType::kTProfile, {{static_cast(holderCcdb.runNumbersIndicesGroupIndices.size()), -0.5, holderCcdb.runNumbersIndicesGroupIndices.size() - 0.5, "Run Index"}}); - hrQaRun.add("QaRun/pRunIndexVx", ";;#LT#it{V}_{#it{x}}#GT (cm)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexVy", ";;#LT#it{V}_{#it{y}}#GT (cm)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexVz", ";;#LT#it{V}_{#it{z}}#GT (cm)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexMultiplicityFt0a", ";;FT0A #LTMultiplicity#GT", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexMultiplicityFt0c", ";;FT0C #LTMultiplicity#GT", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexCentralityFt0a", ";;FT0A #LTCentrality#GT", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexCentralityFt0c", ";;FT0C #LTCentrality#GT", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexCentralityFt0m", ";;FT0M #LTCentrality#GT", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexNGlobalTracks_p", ";;#LTnGlobalTracks#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexNGlobalTracks_m", ";;#LTnGlobalTracks#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexNPvContributors_p", ";;#LTnPvContributors#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexNPvContributors_m", ";;#LTnPvContributors#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexMeanDcaXy_p", ";;#LT#LTDCA_{#it{xy}}#GT_{event}#GT (cm) (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexMeanDcaXy_m", ";;#LT#LTDCA_{#it{xy}}#GT_{event}#GT (cm) (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexSigmaDcaXy_p", ";;#LT#it{#sigma}(DCA_{#it{xy}})_{event}#GT (cm) (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexSigmaDcaXy_m", ";;#LT#it{#sigma}(DCA_{#it{xy}})_{event}#GT (cm) (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexMeanDcaZ_p", ";;#LT#LTDCA_{#it{z}}#GT_{event}#GT (cm) (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexMeanDcaZ_m", ";;#LT#LTDCA_{#it{z}}#GT_{event}#GT (cm) (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexSigmaDcaZ_p", ";;#LT#it{#sigma}(DCA_{#it{z}})_{event}#GT (cm) (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexSigmaDcaZ_m", ";;#LT#it{#sigma}(DCA_{#it{z}})_{event}#GT (cm) (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexNTofBeta_p", ";;#LTnTofBeta#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexNTofBeta_m", ";;#LTnTofBeta#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexItsNCls_p", ";;ITS #LTnClusters#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexItsNCls_m", ";;ITS #LTnClusters#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexItsChi2NCls_p", ";;ITS #LT#it{#chi}^{2}/nClusters#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexItsChi2NCls_m", ";;ITS #LT#it{#chi}^{2}/nClusters#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcNCls_p", ";;TPC #LTnClusters#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcNCls_m", ";;TPC #LTnClusters#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcChi2NCls_p", ";;TPC #LT#it{#chi}^{2}/nClusters#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcChi2NCls_m", ";;TPC #LT#it{#chi}^{2}/nClusters#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcNClsSharedRatio_p", ";;TPC #LTnSharedClusters/nClusters#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcNClsSharedRatio_m", ";;TPC #LTnSharedClusters/nClusters#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcNCrossedRows_p", ";;TPC #LTnCrossedRows#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcNCrossedRows_m", ";;TPC #LTnCrossedRows#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcNCrossedRowsRatio_p", ";;TPC #LTnCrossedRows/nFindableClusters#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcNCrossedRowsRatio_m", ";;TPC #LTnCrossedRows/nFindableClusters#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexDcaXy_p", ";;#LTDCA_{#it{xy}}#GT (cm) (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexDcaXy_m", ";;#LTDCA_{#it{xy}}#GT (cm) (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexDcaZ_p", ";;#LTDCA_{#it{z}}#GT (cm) (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexDcaZ_m", ";;#LTDCA_{#it{z}}#GT (cm) (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexPt_p", ";;#LT#it{p}_{T}#GT (GeV/#it{c}) (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexPt_m", ";;#LT#it{p}_{T}#GT (GeV/#it{c}) (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexEta_p", ";;#LT#it{#eta}#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexEta_m", ";;#LT#it{#eta}#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexPhi_p", ";;#LT#it{#varphi}#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexPhi_m", ";;#LT#it{#varphi}#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcDeDx_p", ";;TPC #LTd#it{E}/d#it{x}#GT (a.u.) (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcDeDx_m", ";;TPC #LTd#it{E}/d#it{x}#GT (a.u.) (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcNSigmaPi_p", ";;TPC #LT#it{n}#it{#sigma}_{#pi}#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcNSigmaPi_m", ";;TPC #LT#it{n}#it{#sigma}_{#pi}#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcNSigmaKa_p", ";;TPC #LT#it{n}#it{#sigma}_{K}#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcNSigmaKa_m", ";;TPC #LT#it{n}#it{#sigma}_{K}#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcNSigmaPr_p", ";;TPC #LT#it{n}#it{#sigma}_{p}#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTpcNSigmaPr_m", ";;TPC #LT#it{n}#it{#sigma}_{p}#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTofInverseBeta_p", ";;TOF #LT1/#it{#beta}#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTofInverseBeta_m", ";;TOF #LT1/#it{#beta}#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTofNSigmaPi_p", ";;TOF #LT#it{n}#it{#sigma}_{#pi}#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTofNSigmaPi_m", ";;TOF #LT#it{n}#it{#sigma}_{#pi}#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTofNSigmaKa_p", ";;TOF #LT#it{n}#it{#sigma}_{K}#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTofNSigmaKa_m", ";;TOF #LT#it{n}#it{#sigma}_{K}#GT (#it{q}<0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTofNSigmaPr_p", ";;TOF #LT#it{n}#it{#sigma}_{p}#GT (#it{q}>0)", hcsQaRun); - hrQaRun.add("QaRun/pRunIndexTofNSigmaPr_m", ";;TOF #LT#it{n}#it{#sigma}_{p}#GT (#it{q}<0)", hcsQaRun); + for (const auto& [name, title, isChargeSpeciesSeparated] : std::to_array>( + {{"Vx", "#LT#it{V}_{#it{x}}#GT (cm)", false}, + {"Vy", "#LT#it{V}_{#it{y}}#GT (cm)", false}, + {"Vz", "#LT#it{V}_{#it{z}}#GT (cm)", false}, + {"MultiplicityFt0a", "FT0A #LTMultiplicity#GT", false}, + {"MultiplicityFt0c", "FT0C #LTMultiplicity#GT", false}, + {"CentralityFt0a", "FT0A #LTCentrality#GT", false}, + {"CentralityFt0c", "FT0C #LTCentrality#GT", false}, + {"CentralityFt0m", "FT0M #LTCentrality#GT", false}, + {"NGlobalTracks", "#LTnGlobalTracks#GT", true}, + {"NPvContributors", "#LTnPvContributors#GT", true}, + {Form("%sDca%s", getName(DcaKind::kMean).data(), getName(DcaAxis::kXy).data()), "#LT#LTDCA_{#it{xy}}#GT_{event}#GT (cm)", true}, + {Form("%sDca%s", getName(DcaKind::kSigma).data(), getName(DcaAxis::kXy).data()), "#LT#it{#sigma}(DCA_{#it{xy}})_{event}#GT (cm)", true}, + {Form("%sDca%s", getName(DcaKind::kMean).data(), getName(DcaAxis::kZ).data()), "#LT#LTDCA_{#it{z}}#GT_{event}#GT (cm)", true}, + {Form("%sDca%s", getName(DcaKind::kSigma).data(), getName(DcaAxis::kZ).data()), "#LT#it{#sigma}(DCA_{#it{z}})_{event}#GT (cm)", true}, + {"NTofBeta", "#LTnTofBeta#GT", true}, + {"ItsNCls", "ITS #LTnClusters#GT", true}, + {"ItsChi2NCls", "ITS #LT#it{#chi}^{2}/nClusters#GT", true}, + {"TpcNCls", "TPC #LTnClusters#GT", true}, + {"TpcChi2NCls", "TPC #LT#it{#chi}^{2}/nClusters#GT", true}, + {"TpcNClsSharedRatio", "TPC #LTnSharedClusters/nClusters#GT", true}, + {"TpcNCrossedRows", "TPC #LTnCrossedRows#GT", true}, + {"TpcNCrossedRowsRatio", "TPC #LTnCrossedRows/nFindableClusters#GT", true}, + {"DcaXy", "#LTDCA_{#it{xy}}#GT (cm)", true}, + {"DcaZ", "#LTDCA_{#it{z}}#GT (cm)", true}, + {"Pt", "#LT#it{p}_{T}#GT (GeV/#it{c})", true}, + {"Eta", "#LT#it{#eta}#GT", true}, + {"Phi", "#LT#it{#varphi}#GT", true}, + {"TpcDeDx", "TPC #LTd#it{E}/d#it{x}#GT (a.u.)", true}, + {Form("%sNSigma%s", getName(Detector::kTpc).data(), getName(ParticleSpecies::kPion).data()), Form("%s #LT#it{n}#it{#sigma}_{#pi}#GT", getName(Detector::kTpc).data()), true}, + {Form("%sNSigma%s", getName(Detector::kTpc).data(), getName(ParticleSpecies::kKaon).data()), Form("%s #LT#it{n}#it{#sigma}_{K}#GT", getName(Detector::kTpc).data()), true}, + {Form("%sNSigma%s", getName(Detector::kTpc).data(), getName(ParticleSpecies::kProton).data()), Form("%s #LT#it{n}#it{#sigma}_{p}#GT", getName(Detector::kTpc).data()), true}, + {"TofInverseBeta", "TOF #LT1/#it{#beta}#GT", true}, + {Form("%sNSigma%s", getName(Detector::kTof).data(), getName(ParticleSpecies::kPion).data()), Form("%s #LT#it{n}#it{#sigma}_{#pi}#GT", getName(Detector::kTof).data()), true}, + {Form("%sNSigma%s", getName(Detector::kTof).data(), getName(ParticleSpecies::kKaon).data()), Form("%s #LT#it{n}#it{#sigma}_{K}#GT", getName(Detector::kTof).data()), true}, + {Form("%sNSigma%s", getName(Detector::kTof).data(), getName(ParticleSpecies::kProton).data()), Form("%s #LT#it{n}#it{#sigma}_{p}#GT", getName(Detector::kTof).data()), true}})) { + if (!isChargeSpeciesSeparated) { + hrQaRun.add(Form("QaRun/pRunIndex%s", name.data()), Form(";;%s", title.data()), hcsQaRun); + } else { + hrQaRun.add(Form("QaRun/pRunIndex%s_%s", name.data(), getName(ChargeSpecies::kPlus).data()), Form(";;%s (#it{q}>0)", title.data()), hcsQaRun); + hrQaRun.add(Form("QaRun/pRunIndex%s_%s", name.data(), getName(ChargeSpecies::kMinus).data()), Form(";;%s (#it{q}<0)", title.data()), hcsQaRun); + } + } } if (groupAnalysis.cfgFlagQaEvent.value) { @@ -1037,7 +1137,7 @@ struct PartNumFluc { hrQaEvent.add("QaEvent/hVz", "", {HistType::kTH1D, {{300, -15., 15., "#it{V}_{#it{z}} (cm)"}}}); hrQaEvent.add("QaEvent/hNPvContributorsNGlobalTracks", ";nPvContributors;nGlobalTracks;", hcsQaEvent); hrQaEvent.add("QaEvent/hNGlobalTracksMeanDcaXy", ";nGlobalTracks;", {HistType::kTHnSparseD, {asNTracks, {250, -0.25, 0.25, "#LTDCA_{#it{xy}}#GT_{event} (cm)"}}}); - hrQaEvent.add("QaEvent/hNGlobalTracksMeanDcaXy_nPvContributorsCut", ";nGlobalTracks;", {HistType::kTHnSparseD, {asNTracks, {250, -0.25, 0.25, "#LTDCA_{#it{z}}#GT_{event} (cm)"}}}); + hrQaEvent.add("QaEvent/hNGlobalTracksMeanDcaXy_nPvContributorsCut", ";nGlobalTracks;", {HistType::kTHnSparseD, {asNTracks, {250, -0.25, 0.25, "#LTDCA_{#it{xy}}#GT_{event} (cm)"}}}); hrQaEvent.add("QaEvent/hNGlobalTracksMeanDcaZ", ";nGlobalTracks;", {HistType::kTHnSparseD, {asNTracks, {200, -2., 2., "#LTDCA_{#it{z}}#GT_{event} (cm)"}}}); hrQaEvent.add("QaEvent/hNGlobalTracksMeanDcaZ_nPvContributorsCut", ";nGlobalTracks;", {HistType::kTHnSparseD, {asNTracks, {200, -2., 2., "#LTDCA_{#it{z}}#GT_{event} (cm)"}}}); hrQaEvent.add("QaEvent/hNTofBetaNGlobalTracks", ";nTofBeta;nGlobalTracks;", hcsQaEvent); @@ -1057,16 +1157,16 @@ struct PartNumFluc { if (groupAnalysis.cfgFlagQaTrack.value) { LOG(info) << "Enabling track QA."; - hrQaTrack.add("QaTrack/hItsNCls_p", "", {HistType::kTH1D, {{10, -0.5, 9.5, "ITS nClusters"}}}); - hrQaTrack.add("QaTrack/hItsNCls_m", "", {HistType::kTH1D, {{10, -0.5, 9.5, "ITS nClusters"}}}); - hrQaTrack.add("QaTrack/hItsChi2NCls_p", "", {HistType::kTH1D, {{80, 0., 40., "ITS #it{#chi}^{2}/nClusters"}}}); - hrQaTrack.add("QaTrack/hItsChi2NCls_m", "", {HistType::kTH1D, {{80, 0., 40., "ITS #it{#chi}^{2}/nClusters"}}}); - hrQaTrack.add("QaTrack/hTpcNClsNClsShared_p", "", {HistType::kTHnSparseD, {{180, -0.5, 179.5, "TPC nClusters"}, {180, -0.5, 179.5, "TPC nSharedClusters"}}}); - hrQaTrack.add("QaTrack/hTpcNClsNClsShared_m", "", {HistType::kTHnSparseD, {{180, -0.5, 179.5, "TPC nClusters"}, {180, -0.5, 179.5, "TPC nSharedClusters"}}}); - hrQaTrack.add("QaTrack/hTpcChi2NCls_p", "", {HistType::kTH1D, {{100, 0., 5., "TPC #it{#chi}^{2}/nClusters"}}}); - hrQaTrack.add("QaTrack/hTpcChi2NCls_m", "", {HistType::kTH1D, {{100, 0., 5., "TPC #it{#chi}^{2}/nClusters"}}}); - hrQaTrack.add("QaTrack/hTpcNClsFindableNCrossedRows_p", "", {HistType::kTHnSparseD, {{180, -0.5, 179.5, "TPC nFindableClusters"}, {180, -0.5, 179.5, "TPC nCrossedRows"}}}); - hrQaTrack.add("QaTrack/hTpcNClsFindableNCrossedRows_m", "", {HistType::kTHnSparseD, {{180, -0.5, 179.5, "TPC nFindableClusters"}, {180, -0.5, 179.5, "TPC nCrossedRows"}}}); + for (const auto& [name, configSpec] : std::to_array>( + {{"ItsNCls", {HistType::kTH1D, {{10, -0.5, 9.5, "ITS nClusters"}}}}, + {"ItsChi2NCls", {HistType::kTH1D, {{80, 0., 40., "ITS #it{#chi}^{2}/nClusters"}}}}, + {"TpcNClsNClsShared", {HistType::kTHnSparseD, {{180, -0.5, 179.5, "TPC nClusters"}, {180, -0.5, 179.5, "TPC nSharedClusters"}}}}, + {"TpcChi2NCls", {HistType::kTH1D, {{100, 0., 5., "TPC #it{#chi}^{2}/nClusters"}}}}, + {"TpcNClsFindableNCrossedRows", {HistType::kTHnSparseD, {{180, -0.5, 179.5, "TPC nFindableClusters"}, {180, -0.5, 179.5, "TPC nCrossedRows"}}}}})) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrQaTrack.add(Form("QaTrack/h%s_%s", name.data(), getName(iChargeSpecies).data()), "", configSpec); + } + } } if (groupAnalysis.cfgFlagQaDca.value) { @@ -1074,227 +1174,96 @@ struct PartNumFluc { const AxisSpec asPt(200, 0., 2., "#it{p}_{T} (GeV/#it{c})"); - hrQaDca.add("QaDca/hPtDcaXy_p", "", {HistType::kTHnSparseD, {asPt, {500, -0.5, 0.5, "DCA_{#it{xy}} (cm)"}}}); - hrQaDca.add("QaDca/hPtDcaXy_m", "", {HistType::kTHnSparseD, {asPt, {500, -0.5, 0.5, "DCA_{#it{xy}} (cm)"}}}); - hrQaDca.add("QaDca/pPtDcaXy_p", ";;#LTDCA_{#it{xy}}#GT (cm)", {HistType::kTProfile, {asPt}}); - hrQaDca.add("QaDca/pPtDcaXy_m", ";;#LTDCA_{#it{xy}}#GT (cm)", {HistType::kTProfile, {asPt}}); - hrQaDca.add("QaDca/hPtDcaZ_p", "", {HistType::kTHnSparseD, {asPt, {500, -1., 1., "DCA_{#it{z}} (cm)"}}}); - hrQaDca.add("QaDca/hPtDcaZ_m", "", {HistType::kTHnSparseD, {asPt, {500, -1., 1., "DCA_{#it{z}} (cm)"}}}); - hrQaDca.add("QaDca/pPtDcaZ_p", ";;#LTDCA_{#it{z}}#GT (cm)", {HistType::kTProfile, {asPt}}); - hrQaDca.add("QaDca/pPtDcaZ_m", ";;#LTDCA_{#it{z}}#GT (cm)", {HistType::kTProfile, {asPt}}); + for (const auto& [name, title, configSpec] : std::to_array>( + {{"hPtDcaXy", "", {HistType::kTHnSparseD, {asPt, {500, -0.5, 0.5, "DCA_{#it{xy}} (cm)"}}}}, + {"pPtDcaXy", ";;#LTDCA_{#it{xy}}#GT (cm)", {HistType::kTProfile, {asPt}}}, + {"hPtDcaZ", "", {HistType::kTHnSparseD, {asPt, {500, -1., 1., "DCA_{#it{z}} (cm)"}}}}, + {"pPtDcaZ", ";;#LTDCA_{#it{z}}#GT (cm)", {HistType::kTProfile, {asPt}}}})) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrQaDca.add(Form("QaDca/%s_%s", name.data(), getName(iChargeSpecies).data()), title.data(), configSpec); + } + } } - if (groupAnalysis.cfgFlagQaAcceptance.value || groupAnalysis.cfgFlagQaAcceptancePi.value || groupAnalysis.cfgFlagQaAcceptanceKa.value || groupAnalysis.cfgFlagQaAcceptancePr.value) { - const AxisSpec asPt(250, 0., 2.5, "#it{p}_{T} (GeV/#it{c})"); - - if (groupAnalysis.cfgFlagQaAcceptance.value) { - LOG(info) << "Enabling acceptance QA."; - - const HistogramConfigSpec hcsQaAcceptance(HistType::kTHnSparseD, {{300, -1.5, 1.5, "#it{#eta}"}, asPt}); - - hrQaAcceptance.add("QaAcceptance/hEtaPt_tpcEdgeP", "", hcsQaAcceptance); - hrQaAcceptance.add("QaAcceptance/hEtaPt_tpcEdgeM", "", hcsQaAcceptance); - hrQaAcceptance.add("QaAcceptance/hEtaPt_tpcTofEdgeP", "", hcsQaAcceptance); - hrQaAcceptance.add("QaAcceptance/hEtaPt_tpcTofEdgeM", "", hcsQaAcceptance); + for (std::int32_t const& iParticleSpeciesAll : std::views::iota(0, NEs)) { + if (!groupAnalysis.cfgFlagQaAcceptance.value.get(iParticleSpeciesAll)) { + continue; } - if (groupAnalysis.cfgFlagQaAcceptancePi.value || groupAnalysis.cfgFlagQaAcceptanceKa.value || groupAnalysis.cfgFlagQaAcceptancePr.value) { - const HistogramConfigSpec hcsQaAcceptance(HistType::kTHnSparseD, {{300, -1.5, 1.5, "#it{y}"}, asPt}); - - if (groupAnalysis.cfgFlagQaAcceptancePi.value) { - LOG(info) << "Enabling pion acceptance QA."; - - hrQaAcceptance.add("QaAcceptance/hRapidityPt_tpcEdgePiP", "", hcsQaAcceptance); - hrQaAcceptance.add("QaAcceptance/hRapidityPt_tpcEdgePiM", "", hcsQaAcceptance); - hrQaAcceptance.add("QaAcceptance/hRapidityPt_tpcTofEdgePiP", "", hcsQaAcceptance); - hrQaAcceptance.add("QaAcceptance/hRapidityPt_tpcTofEdgePiM", "", hcsQaAcceptance); - } - - if (groupAnalysis.cfgFlagQaAcceptanceKa.value) { - LOG(info) << "Enabling kaon acceptance QA."; + LOG(info) << "Enabling " << getName(iParticleSpeciesAll) << " acceptance QA."; - hrQaAcceptance.add("QaAcceptance/hRapidityPt_tpcEdgeKaP", "", hcsQaAcceptance); - hrQaAcceptance.add("QaAcceptance/hRapidityPt_tpcEdgeKaM", "", hcsQaAcceptance); - hrQaAcceptance.add("QaAcceptance/hRapidityPt_tpcTofEdgeKaP", "", hcsQaAcceptance); - hrQaAcceptance.add("QaAcceptance/hRapidityPt_tpcTofEdgeKaM", "", hcsQaAcceptance); - } - - if (groupAnalysis.cfgFlagQaAcceptancePr.value) { - LOG(info) << "Enabling (anti)proton acceptance QA."; - - hrQaAcceptance.add("QaAcceptance/hRapidityPt_tpcEdgePrP", "", hcsQaAcceptance); - hrQaAcceptance.add("QaAcceptance/hRapidityPt_tpcEdgePrM", "", hcsQaAcceptance); - hrQaAcceptance.add("QaAcceptance/hRapidityPt_tpcTofEdgePrP", "", hcsQaAcceptance); - hrQaAcceptance.add("QaAcceptance/hRapidityPt_tpcTofEdgePrM", "", hcsQaAcceptance); + for (std::int32_t const& iPidStrategy : std::views::iota(0, NEs)) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrQaAcceptance.add(Form("QaAcceptance/h%sPt_%sEdge%s%s", iParticleSpeciesAll == toI(ParticleSpeciesAll::kAll) ? "Eta" : "Rapidity", getName(iPidStrategy).data(), getName(iParticleSpeciesAll).data(), getName(iChargeSpecies).data()), "", {HistType::kTHnSparseD, {{300, -1.5, 1.5, iParticleSpeciesAll == toI(ParticleSpeciesAll::kAll) ? "#it{#eta}" : "#it{y}"}, {250, 0., 2.5, "#it{p}_{T} (GeV/#it{c})"}}}); } } } - if (groupAnalysis.cfgFlagQaPhi.value || groupAnalysis.cfgFlagQaPhiPi.value || groupAnalysis.cfgFlagQaPhiKa.value || groupAnalysis.cfgFlagQaPhiPr.value) { - const HistogramConfigSpec hcsQaPhi(HistType::kTHnSparseF, {{{0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.}, "Centrality (%)"}, {20, 0., 2., "#it{p}_{T} (GeV/#it{c})"}, {16, -0.8, 0.8, "#it{#eta}"}, {360, 0., constants::math::TwoPI, "#it{#varphi} (rad)"}}); - - if (groupAnalysis.cfgFlagQaPhi.value) { - LOG(info) << "Enabling phi QA."; - - if (doprocessMc.value) { - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcTofP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcTofM", "", hcsQaPhi); - } else if (doprocessRaw.value) { - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcTofP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcTofM", "", hcsQaPhi); - } + for (std::int32_t const& iParticleSpeciesAll : std::views::iota(0, NEs)) { + if (!groupAnalysis.cfgFlagQaPhi.value.get(iParticleSpeciesAll)) { + continue; } - if (groupAnalysis.cfgFlagQaPhiPi.value) { - LOG(info) << "Enabling pion phi QA."; - - if (doprocessMc.value) { - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcPiP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcPiM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcPiP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcPiM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofPiP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofPiM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcPiP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcPiM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcTofPiP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcTofPiM", "", hcsQaPhi); - } else if (doprocessRaw.value) { - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcPiP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcPiM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcTofPiP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcTofPiM", "", hcsQaPhi); - } - } + LOG(info) << "Enabling " << getName(iParticleSpeciesAll) << " phi QA."; - if (groupAnalysis.cfgFlagQaPhiKa.value) { - LOG(info) << "Enabling kaon phi QA."; + const HistogramConfigSpec hcsQaPhi(HistType::kTHnSparseF, {{{0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.}, "Centrality (%)"}, {20, 0., 2., "#it{p}_{T} (GeV/#it{c})"}, {16, -0.8, 0.8, "#it{#eta}"}, {360, 0., constants::math::TwoPI, "#it{#varphi} (rad)"}}); - if (doprocessMc.value) { - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcKaP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcKaM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcKaP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcKaM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofKaP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofKaM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcKaP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcKaM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcTofKaP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcTofKaM", "", hcsQaPhi); - } else if (doprocessRaw.value) { - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcKaP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcKaM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcTofKaP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcTofKaM", "", hcsQaPhi); + if (doprocessMc.value) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrQaPhi.add(Form("QaPhi/hCentralityPtEtaPhiMc_mc%s%s", getName(iParticleSpeciesAll).data(), getName(iChargeSpecies).data()), "", hcsQaPhi); } - } - - if (groupAnalysis.cfgFlagQaPhiPr.value) { - LOG(info) << "Enabling (anti)proton phi QA."; - - if (doprocessMc.value) { - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcPrP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcPrM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcPrP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcPrM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofPrP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofPrM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcPrP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcPrM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcTofPrP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_mcTpcTofPrM", "", hcsQaPhi); - } else if (doprocessRaw.value) { - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcPrP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcPrM", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcTofPrP", "", hcsQaPhi); - hrQaPhi.add("QaPhi/hCentralityPtEtaPhi_tpcTofPrM", "", hcsQaPhi); + for (std::int32_t const& iPidStrategy : std::views::iota(0, NEs)) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrQaPhi.add(Form("QaPhi/hCentralityPtEtaPhiMc_mc%s%s%s", getName(iPidStrategy).data(), getName(iParticleSpeciesAll).data(), getName(iChargeSpecies).data()), "", hcsQaPhi); + hrQaPhi.add(Form("QaPhi/hCentralityPtEtaPhi_mc%s%s%s", getName(iPidStrategy).data(), getName(iParticleSpeciesAll).data(), getName(iChargeSpecies).data()), "", hcsQaPhi); + } + } + } else { + for (std::int32_t const& iPidStrategy : std::views::iota(0, NEs)) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrQaPhi.add(Form("QaPhi/hCentralityPtEtaPhi_%s%s%s", getName(iPidStrategy).data(), getName(iParticleSpeciesAll).data(), getName(iChargeSpecies).data()), "", hcsQaPhi); + } } } } - if (groupAnalysis.cfgFlagQaPid.value || groupAnalysis.cfgFlagQaPidPi.value || groupAnalysis.cfgFlagQaPidKa.value || groupAnalysis.cfgFlagQaPidPr.value) { - const AxisSpec asCentrality({0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.}, "Centrality (%)"); + for (std::int32_t const& iParticleSpeciesAll : std::views::iota(0, NEs)) { + if (!groupAnalysis.cfgFlagQaPid.value.get(iParticleSpeciesAll)) { + continue; + } - if (groupAnalysis.cfgFlagQaPid.value) { - LOG(info) << "Enabling PID QA."; + LOG(info) << "Enabling " << getName(iParticleSpeciesAll) << " PID QA."; + + const AxisSpec asCentrality({0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.}, "Centrality (%)"); + if (iParticleSpeciesAll == toI(ParticleSpeciesAll::kAll)) { const AxisSpec asPOverQ(350, -3.5, 3.5, "#it{p}/#it{q} (GeV/#it{c})"); const AxisSpec asEta(48, -1.2, 1.2, "#it{#eta}"); hrQaPid.add("QaPid/hCentralityPOverQEtaTpcLnDeDx", "", {HistType::kTHnSparseF, {asCentrality, asPOverQ, asEta, {240, 3., 9., "TPC ln(d#it{E}/d#it{x} (a.u.))"}}}); hrQaPid.add("QaPid/hCentralityPOverQEtaTofInverseBeta", "", {HistType::kTHnSparseF, {asCentrality, asPOverQ, asEta, {120, 0.5, 3.5, "TOF 1/#it{#beta}"}}}); - } - - if (groupAnalysis.cfgFlagQaPidPi.value || groupAnalysis.cfgFlagQaPidKa.value || groupAnalysis.cfgFlagQaPidPr.value) { + } else { const HistogramConfigSpec hcsQaPid(HistType::kTHnSparseF, {asCentrality, {40, 0., 2., "#it{p}_{T} (GeV/#it{c})"}, {32, -0.8, 0.8, "#it{#eta}"}, {300, -30., 30.}}); - if (groupAnalysis.cfgFlagQaPidPi.value) { - LOG(info) << "Enabling pion PID QA."; - - if (doprocessMc.value) { - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_mcPiP", ";;;;TPC #it{n}#it{#sigma}_{#pi};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_mcPiM", ";;;;TPC #it{n}#it{#sigma}_{#pi};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPi_mcPiP", ";;;;TOF #it{n}#it{#sigma}_{#pi};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPi_mcPiM", ";;;;TOF #it{n}#it{#sigma}_{#pi};", hcsQaPid); - } else if (doprocessRaw.value) { - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_p", ";;;;TPC #it{n}#it{#sigma}_{#pi};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_m", ";;;;TPC #it{n}#it{#sigma}_{#pi};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_tofPiP", ";;;;TPC #it{n}#it{#sigma}_{#pi};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPi_tofPiM", ";;;;TPC #it{n}#it{#sigma}_{#pi};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPi_tpcPiP", ";;;;TOF #it{n}#it{#sigma}_{#pi};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPi_tpcPiM", ";;;;TOF #it{n}#it{#sigma}_{#pi};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaPi_p", ";;;;TPC-TOF #it{n}#it{#sigma}_{#pi};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaPi_m", ";;;;TPC-TOF #it{n}#it{#sigma}_{#pi};", hcsQaPid); + constexpr std::array> ParticleSpeciesAllTitles{"", "#pi", "K", "p"}; + if (doprocessMc.value) { + for (std::int32_t const& iDetector : std::views::iota(0, NEs)) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrQaPid.add(Form("QaPid/hCentralityPtEta%sNSigma%s_mc%s%s", getName(iDetector).data(), getName(iParticleSpeciesAll).data(), getName(iParticleSpeciesAll).data(), getName(iChargeSpecies).data()), Form(";;;;%s #it{n}#it{#sigma}_{%s};", getName(iDetector).data(), ParticleSpeciesAllTitles[iParticleSpeciesAll].data()), hcsQaPid); + } } - } - - if (groupAnalysis.cfgFlagQaPidKa.value) { - LOG(info) << "Enabling kaon PID QA."; - - if (doprocessMc.value) { - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_mcKaP", ";;;;TPC #it{n}#it{#sigma}_{K};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_mcKaM", ";;;;TPC #it{n}#it{#sigma}_{K};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaKa_mcKaP", ";;;;TOF #it{n}#it{#sigma}_{K};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaKa_mcKaM", ";;;;TOF #it{n}#it{#sigma}_{K};", hcsQaPid); - } else if (doprocessRaw.value) { - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_p", ";;;;TPC #it{n}#it{#sigma}_{K};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_m", ";;;;TPC #it{n}#it{#sigma}_{K};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_tofKaP", ";;;;TPC #it{n}#it{#sigma}_{K};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaKa_tofKaM", ";;;;TPC #it{n}#it{#sigma}_{K};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaKa_tpcKaP", ";;;;TOF #it{n}#it{#sigma}_{K};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaKa_tpcKaM", ";;;;TOF #it{n}#it{#sigma}_{K};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaKa_p", ";;;;TPC-TOF #it{n}#it{#sigma}_{K};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaKa_m", ";;;;TPC-TOF #it{n}#it{#sigma}_{K};", hcsQaPid); + } else { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrQaPid.add(Form("QaPid/hCentralityPtEta%sNSigma%s_%s", getName(Detector::kTpc).data(), getName(iParticleSpeciesAll).data(), getName(iChargeSpecies).data()), Form(";;;;%s #it{n}#it{#sigma}_{%s};", getName(Detector::kTpc).data(), ParticleSpeciesAllTitles[iParticleSpeciesAll].data()), hcsQaPid); } - } - - if (groupAnalysis.cfgFlagQaPidPr.value) { - LOG(info) << "Enabling (anti)proton PID QA."; - - if (doprocessMc.value) { - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_mcPrP", ";;;;TPC #it{n}#it{#sigma}_{p};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_mcPrM", ";;;;TPC #it{n}#it{#sigma}_{p};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPr_mcPrP", ";;;;TOF #it{n}#it{#sigma}_{p};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPr_mcPrM", ";;;;TOF #it{n}#it{#sigma}_{p};", hcsQaPid); - } else if (doprocessRaw.value) { - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_p", ";;;;TPC #it{n}#it{#sigma}_{p};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_m", ";;;;TPC #it{n}#it{#sigma}_{p};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_tofPrP", ";;;;TPC #it{n}#it{#sigma}_{p};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcNSigmaPr_tofPrM", ";;;;TPC #it{n}#it{#sigma}_{p};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPr_tpcPrP", ";;;;TOF #it{n}#it{#sigma}_{p};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTofNSigmaPr_tpcPrM", ";;;;TOF #it{n}#it{#sigma}_{p};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaPr_p", ";;;;TPC-TOF #it{n}#it{#sigma}_{p};", hcsQaPid); - hrQaPid.add("QaPid/hCentralityPtEtaTpcTofNSigmaPr_m", ";;;;TPC-TOF #it{n}#it{#sigma}_{p};", hcsQaPid); + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrQaPid.add(Form("QaPid/hCentralityPtEta%sNSigma%s_%s%s%s", getName(Detector::kTpc).data(), getName(iParticleSpeciesAll).data(), getName(Detector::kTof).data(), getName(iParticleSpeciesAll).data(), getName(iChargeSpecies).data()), Form(";;;;%s #it{n}#it{#sigma}_{%s};", getName(Detector::kTpc).data(), ParticleSpeciesAllTitles[iParticleSpeciesAll].data()), hcsQaPid); + } + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrQaPid.add(Form("QaPid/hCentralityPtEta%sNSigma%s_%s%s%s", getName(Detector::kTof).data(), getName(iParticleSpeciesAll).data(), getName(Detector::kTpc).data(), getName(iParticleSpeciesAll).data(), getName(iChargeSpecies).data()), Form(";;;;%s #it{n}#it{#sigma}_{%s};", getName(Detector::kTof).data(), ParticleSpeciesAllTitles[iParticleSpeciesAll].data()), hcsQaPid); + } + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrQaPid.add(Form("QaPid/hCentralityPtEta%sNSigma%s_%s", getName(PidStrategy::kTpcTof).data(), getName(iParticleSpeciesAll).data(), getName(iChargeSpecies).data()), Form(";;;;%s #it{n}#it{#sigma}_{%s};", getName(PidStrategy::kTpcTof).data(), ParticleSpeciesAllTitles[iParticleSpeciesAll].data()), hcsQaPid); } } } @@ -1306,356 +1275,214 @@ struct PartNumFluc { const AxisSpec asCentrality(20, 0., 100., "Centrality (%)"); - hrQaMc.add("QaMc/hCentralityVzDeltaVz", "", {HistType::kTHnSparseF, {asCentrality, {200, -10., 10., "#it{V}_{#it{z}}^{Rec} (cm)"}, {200, -1., 1., "#it{V}_{#it{z}}^{Rec}#minus#it{V}_{#it{z}}^{Gen} (cm)"}}}); - hrQaMc.add("QaMc/hCentralityPtEtaDeltaPt", "", {HistType::kTHnSparseF, {asCentrality, {100, 0., 2., "#it{p}_{T}^{Rec} (GeV/#it{c})"}, {120, -1.2, 1.2, "#it{#eta}_{Rec}"}, {200, -1., 1., "#it{p}_{T}^{Rec}#minus#it{p}_{T}^{Gen} (GeV/#it{c})"}}}); - hrQaMc.add("QaMc/hCentralityPtEtaDeltaEta", "", {HistType::kTHnSparseF, {asCentrality, {100, 0., 2., "#it{p}_{T}^{Rec} (GeV/#it{c})"}, {120, -1.2, 1.2, "#it{#eta}_{Rec}"}, {200, -1., 1., "#it{#eta}_{Rec}#minus#it{#eta}_{Gen}"}}}); + hrQaMc.add("QaMc/hCentralityVzDeltaVz", "", {HistType::kTHnSparseF, {asCentrality, {static_cast(std::llrint(std::ceil(groupEvent.cfgCutMaxAbsVz.value))) * 20, -std::ceil(groupEvent.cfgCutMaxAbsVz.value), std::ceil(groupEvent.cfgCutMaxAbsVz.value), "#it{V}_{#it{z}}^{Rec} (cm)"}, {200, -0.2, 0.2, "#it{V}_{#it{z}}^{Rec}#minus#it{V}_{#it{z}}^{Gen} (cm)"}}}); + hrQaMc.add("QaMc/hCentralityPtEtaDeltaPt", "", {HistType::kTHnSparseF, {asCentrality, {200, 0., 2., "#it{p}_{T}^{Rec} (GeV/#it{c})"}, {24, -1.2, 1.2, "#it{#eta}_{Rec}"}, {320, -0.8, 0.8, "#it{p}_{T}^{Rec}#minus#it{p}_{T}^{Gen} (GeV/#it{c})"}}}); + hrQaMc.add("QaMc/hCentralityPtEtaDeltaEta", "", {HistType::kTHnSparseF, {asCentrality, {20, 0., 2., "#it{p}_{T}^{Rec} (GeV/#it{c})"}, {240, -1.2, 1.2, "#it{#eta}_{Rec}"}, {160, -0.4, 0.4, "#it{#eta}_{Rec}#minus#it{#eta}_{Gen}"}}}); } } - if (groupAnalysis.cfgFlagCalculationYieldPi.value || groupAnalysis.cfgFlagCalculationYieldKa.value || groupAnalysis.cfgFlagCalculationYieldPr.value) { - const HistogramConfigSpec hcsCalculationYield(HistType::kTHnSparseF, {{static_cast(std::llrint(std::ceil(groupEvent.cfgCutMaxAbsVertexZ.value))) * 2, -std::ceil(groupEvent.cfgCutMaxAbsVertexZ.value), std::ceil(groupEvent.cfgCutMaxAbsVertexZ.value), "#it{V}_{#it{z}} (cm)"}, {{0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.}, "Centrality (%)"}, {40, 0., 2., "#it{p}_{T} (GeV/#it{c})"}, {32, -0.8, 0.8, "#it{#eta}"}}); - - if (groupAnalysis.cfgFlagCalculationYieldPi.value) { - LOG(info) << "Enabling pion yield calculation."; - - if (doprocessMc.value) { - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcPiP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcPiM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcTpcPiP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcTpcPiM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcTpcTofPiP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcTpcTofPiM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_mcTpcPiP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_mcTpcPiM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_mcTpcTofPiP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_mcTpcTofPiM", "", hcsCalculationYield); - } else if (doprocessRaw.value) { - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_tpcPiP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_tpcPiM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_tpcTofPiP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_tpcTofPiM", "", hcsCalculationYield); - } + for (std::int32_t const& iParticleSpecies : std::views::iota(0, NEs)) { + if (!groupAnalysis.cfgFlagCalculationYield.value.get(iParticleSpecies)) { + continue; } + LOG(info) << "Enabling " << getName(iParticleSpecies) << " yield calculation."; - if (groupAnalysis.cfgFlagCalculationYieldKa.value) { - LOG(info) << "Enabling kaon yield calculation."; + const HistogramConfigSpec hcsCalculationYield(HistType::kTHnSparseF, {{static_cast(std::llrint(std::ceil(groupEvent.cfgCutMaxAbsVz.value))) * 2, -std::ceil(groupEvent.cfgCutMaxAbsVz.value), std::ceil(groupEvent.cfgCutMaxAbsVz.value), "#it{V}_{#it{z}} (cm)"}, {{0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.}, "Centrality (%)"}, {40, 0., 2., "#it{p}_{T} (GeV/#it{c})"}, {32, -0.8, 0.8, "#it{#eta}"}}); - if (doprocessMc.value) { - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcKaP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcKaM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcTpcKaP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcTpcKaM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcTpcTofKaP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcTpcTofKaM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_mcTpcKaP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_mcTpcKaM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_mcTpcTofKaP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_mcTpcTofKaM", "", hcsCalculationYield); - } else if (doprocessRaw.value) { - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_tpcKaP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_tpcKaM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_tpcTofKaP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_tpcTofKaM", "", hcsCalculationYield); + if (doprocessMc.value) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrCalculationYield.add(Form("CalculationYield/hVzCentralityPtEtaMc_mc%s%s", getName(iParticleSpecies).data(), getName(iChargeSpecies).data()), "", hcsCalculationYield); } - } - - if (groupAnalysis.cfgFlagCalculationYieldPr.value) { - LOG(info) << "Enabling (anti)proton yield calculation."; - - if (doprocessMc.value) { - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcPrP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcPrM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcTpcPrP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcTpcPrM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcTpcTofPrP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEtaMc_mcTpcTofPrM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_mcTpcPrP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_mcTpcPrM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_mcTpcTofPrP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_mcTpcTofPrM", "", hcsCalculationYield); - } else if (doprocessRaw.value) { - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_tpcPrP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_tpcPrM", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_tpcTofPrP", "", hcsCalculationYield); - hrCalculationYield.add("CalculationYield/hVzCentralityPtEta_tpcTofPrM", "", hcsCalculationYield); + for (std::int32_t const& iPidStrategy : std::views::iota(0, NEs)) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrCalculationYield.add(Form("CalculationYield/hVzCentralityPtEtaMc_mc%s%s%s", getName(iPidStrategy).data(), getName(iParticleSpecies).data(), getName(iChargeSpecies).data()), "", hcsCalculationYield); + hrCalculationYield.add(Form("CalculationYield/hVzCentralityPtEta_mc%s%s%s", getName(iPidStrategy).data(), getName(iParticleSpecies).data(), getName(iChargeSpecies).data()), "", hcsCalculationYield); + } + } + } else { + for (std::int32_t const& iPidStrategy : std::views::iota(0, NEs)) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrCalculationYield.add(Form("CalculationYield/hVzCentralityPtEta_%s%s%s", getName(iPidStrategy).data(), getName(iParticleSpecies).data(), getName(iChargeSpecies).data()), "", hcsCalculationYield); + } } } } if (doprocessMc.value) { - if (groupAnalysis.cfgFlagCalculationPurityPi.value || groupAnalysis.cfgFlagCalculationPurityKa.value || groupAnalysis.cfgFlagCalculationPurityPr.value) { - const HistogramConfigSpec hcsCalculationPurity(HistType::kTProfile3D, {{{0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.}, "Centrality (%)"}, {20, 0., 2., "#it{p}_{T} (GeV/#it{c})"}, {16, -0.8, 0.8, "#it{#eta}"}}); - - if (groupAnalysis.cfgFlagCalculationPurityPi.value) { - LOG(info) << "Enabling pion purity calculation."; - - hrCalculationPurity.add("CalculationPurity/pCentralityPtEtaPurityTpcPiP", "", hcsCalculationPurity); - hrCalculationPurity.add("CalculationPurity/pCentralityPtEtaPurityTpcPiM", "", hcsCalculationPurity); - hrCalculationPurity.add("CalculationPurity/pCentralityPtEtaPurityTpcTofPiP", "", hcsCalculationPurity); - hrCalculationPurity.add("CalculationPurity/pCentralityPtEtaPurityTpcTofPiM", "", hcsCalculationPurity); + for (std::int32_t const& iParticleSpecies : std::views::iota(0, NEs)) { + if (!groupAnalysis.cfgFlagCalculationPurity.value.get(iParticleSpecies)) { + continue; } - if (groupAnalysis.cfgFlagCalculationPurityKa.value) { - LOG(info) << "Enabling kaon purity calculation."; + LOG(info) << "Enabling " << getName(iParticleSpecies) << " purity calculation."; - hrCalculationPurity.add("CalculationPurity/pCentralityPtEtaPurityTpcKaP", "", hcsCalculationPurity); - hrCalculationPurity.add("CalculationPurity/pCentralityPtEtaPurityTpcKaM", "", hcsCalculationPurity); - hrCalculationPurity.add("CalculationPurity/pCentralityPtEtaPurityTpcTofKaP", "", hcsCalculationPurity); - hrCalculationPurity.add("CalculationPurity/pCentralityPtEtaPurityTpcTofKaM", "", hcsCalculationPurity); - } - - if (groupAnalysis.cfgFlagCalculationPurityPr.value) { - LOG(info) << "Enabling (anti)proton purity calculation."; + const HistogramConfigSpec hcsCalculationPurity(HistType::kTProfile3D, {{{0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.}, "Centrality (%)"}, {20, 0., 2., "#it{p}_{T} (GeV/#it{c})"}, {16, -0.8, 0.8, "#it{#eta}"}}); - hrCalculationPurity.add("CalculationPurity/pCentralityPtEtaPurityTpcPrP", "", hcsCalculationPurity); - hrCalculationPurity.add("CalculationPurity/pCentralityPtEtaPurityTpcPrM", "", hcsCalculationPurity); - hrCalculationPurity.add("CalculationPurity/pCentralityPtEtaPurityTpcTofPrP", "", hcsCalculationPurity); - hrCalculationPurity.add("CalculationPurity/pCentralityPtEtaPurityTpcTofPrM", "", hcsCalculationPurity); + for (std::int32_t const& iPidStrategy : std::views::iota(0, NEs)) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrCalculationPurity.add(Form("CalculationPurity/pCentralityPtEtaPurity%s%s%s", getName(iPidStrategy).data(), getName(iParticleSpecies).data(), getName(iChargeSpecies).data()), "", hcsCalculationPurity); + } } } } if (doprocessMc.value) { - if (groupAnalysis.cfgFlagCalculationFractionPrimaryPi.value || groupAnalysis.cfgFlagCalculationFractionPrimaryKa.value || groupAnalysis.cfgFlagCalculationFractionPrimaryPr.value) { - const HistogramConfigSpec hcsCalculationFractionPrimary(HistType::kTProfile3D, {{{0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.}, "Centrality (%)"}, {20, 0., 2., "#it{p}_{T} (GeV/#it{c})"}, {16, -0.8, 0.8, "#it{#eta}"}}); - - if (groupAnalysis.cfgFlagCalculationFractionPrimaryPi.value) { - LOG(info) << "Enabling pion primary fraction calculation."; - - hrCalculationFractionPrimary.add("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcPiP", "", hcsCalculationFractionPrimary); - hrCalculationFractionPrimary.add("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcPiM", "", hcsCalculationFractionPrimary); - hrCalculationFractionPrimary.add("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcTofPiP", "", hcsCalculationFractionPrimary); - hrCalculationFractionPrimary.add("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcTofPiM", "", hcsCalculationFractionPrimary); + for (std::int32_t const& iParticleSpecies : std::views::iota(0, NEs)) { + if (!groupAnalysis.cfgFlagCalculationFractionPrimary.value.get(iParticleSpecies)) { + continue; } - if (groupAnalysis.cfgFlagCalculationFractionPrimaryKa.value) { - LOG(info) << "Enabling kaon primary fraction calculation."; - - hrCalculationFractionPrimary.add("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcKaP", "", hcsCalculationFractionPrimary); - hrCalculationFractionPrimary.add("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcKaM", "", hcsCalculationFractionPrimary); - hrCalculationFractionPrimary.add("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcTofKaP", "", hcsCalculationFractionPrimary); - hrCalculationFractionPrimary.add("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcTofKaM", "", hcsCalculationFractionPrimary); - } + LOG(info) << "Enabling " << getName(iParticleSpecies) << " primary fraction calculation."; - if (groupAnalysis.cfgFlagCalculationFractionPrimaryPr.value) { - LOG(info) << "Enabling (anti)proton primary fraction calculation."; + const HistogramConfigSpec hcsCalculationFractionPrimary(HistType::kTProfile3D, {{{0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.}, "Centrality (%)"}, {20, 0., 2., "#it{p}_{T} (GeV/#it{c})"}, {16, -0.8, 0.8, "#it{#eta}"}}); - hrCalculationFractionPrimary.add("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcPrP", "", hcsCalculationFractionPrimary); - hrCalculationFractionPrimary.add("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcPrM", "", hcsCalculationFractionPrimary); - hrCalculationFractionPrimary.add("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcTofPrP", "", hcsCalculationFractionPrimary); - hrCalculationFractionPrimary.add("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcTofPrM", "", hcsCalculationFractionPrimary); + for (std::int32_t const& iPidStrategy : std::views::iota(0, NEs)) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + hrCalculationFractionPrimary.add(Form("CalculationFractionPrimary/pCentralityPtEtaFractionPrimary%s%s%s", getName(iPidStrategy).data(), getName(iParticleSpecies).data(), getName(iChargeSpecies).data()), "", hcsCalculationFractionPrimary); + } } } } - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value || groupAnalysis.cfgFlagCalculationFluctuationKa.value || groupAnalysis.cfgFlagCalculationFluctuationPr.value) { + if (nEnabled(groupAnalysis.cfgFlagCalculationFluctuation) > 1) { + LOG(fatal) << "Invalid " << groupAnalysis.cfgFlagCalculationFluctuation.name << "!"; + } + if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation) && groupEvent.cfgNSubgroups.value <= 0) { + LOG(fatal) << "Invalid " << groupEvent.cfgNSubgroups.name << "!"; + } + for (std::int32_t const& iParticleNumber : std::views::iota(0, NEs)) { + if (!groupAnalysis.cfgFlagCalculationFluctuation.value.get(iParticleNumber)) { + continue; + } + + LOG(info) << "Enabling " << getName(iParticleNumber) << " number fluctuation calculation."; + const AxisSpec asCentrality(groupEvent.cfgAxisCentrality, "Centrality (%)"); const HistogramConfigSpec hcsDistribution(HistType::kTHnSparseD, {asCentrality, {200, -0.5, 199.5}, {200, -0.5, 199.5}}); const HistogramConfigSpec hcsFluctuationCalculator(HistType::kTH3D, {asCentrality, {groupEvent.cfgNSubgroups.value, -0.5, groupEvent.cfgNSubgroups.value - 0.5, "Subgroup Index"}, {fluctuation_calculator_base::NOrderVectors, -0.5, fluctuation_calculator_base::NOrderVectors - 0.5, "Order Vector Index"}}); - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value) { - LOG(info) << "Enabling charge number fluctuation calculation."; - - fluctuationCalculatorTrackChP = std::make_unique(); - fluctuationCalculatorTrackChM = std::make_unique(); - fluctuationCalculatorTrackChT = std::make_unique(); - fluctuationCalculatorTrackChN = std::make_unique(); - - if (doprocessMc.value) { - hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNChPNChM_mc", ";;#it{N}(h^{+});#it{N}(h^{#minus});", hcsDistribution); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChP_mc", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChM_mc", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChT_mc", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChN_mc", "", hcsFluctuationCalculator); - } - hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNChPNChM", ";;#it{N}(h^{+});#it{N}(h^{#minus});", hcsDistribution); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChP", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChM", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChT", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorChN", "", hcsFluctuationCalculator); + for (std::int32_t const& iChargeNumber : std::views::iota(0, NEs)) { + fluctuationCalculatorTrack[iParticleNumber][iChargeNumber] = std::make_unique(); } - if (groupAnalysis.cfgFlagCalculationFluctuationKa.value) { - LOG(info) << "Enabling kaon number fluctuation calculation."; - - fluctuationCalculatorTrackKaP = std::make_unique(); - fluctuationCalculatorTrackKaM = std::make_unique(); - fluctuationCalculatorTrackKaT = std::make_unique(); - fluctuationCalculatorTrackKaN = std::make_unique(); - - if (doprocessMc.value) { - hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNKaPNKaM_mc", ";;#it{N}(K^{+});#it{N}(K^{#minus});", hcsDistribution); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaP_mc", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaM_mc", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaT_mc", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaN_mc", "", hcsFluctuationCalculator); + constexpr std::array> ParticleNumberTitles{"h", "K", "p"}; + constexpr std::array> ChargeSpeciesTitles{"+", "#minus"}; + if (doprocessMc.value) { + hrCalculationFluctuation.add(Form("CalculationFluctuation/hCentralityN%s%sN%s%s_mc", getName(iParticleNumber).data(), getName(ChargeSpecies::kPlus).data(), getName(iParticleNumber).data(), getName(ChargeSpecies::kMinus).data()), Form(";;#it{N}(%s^{%s});#it{N}(%s^{%s});", ParticleNumberTitles[iParticleNumber].data(), ChargeSpeciesTitles[toI(ChargeSpecies::kPlus)].data(), ParticleNumberTitles[iParticleNumber].data(), ChargeSpeciesTitles[toI(ChargeSpecies::kMinus)].data()), hcsDistribution); + hrCalculationFluctuation.add(Form("CalculationFluctuation/hCentralityN%s%sN%s%s_mcEff", getName(iParticleNumber).data(), getName(ChargeSpecies::kPlus).data(), getName(iParticleNumber).data(), getName(ChargeSpecies::kMinus).data()), Form(";;#it{N}(%s^{%s});#it{N}(%s^{%s});", ParticleNumberTitles[iParticleNumber].data(), ChargeSpeciesTitles[toI(ChargeSpecies::kPlus)].data(), ParticleNumberTitles[iParticleNumber].data(), ChargeSpeciesTitles[toI(ChargeSpecies::kMinus)].data()), hcsDistribution); + for (std::int32_t const& iChargeNumber : std::views::iota(0, NEs)) { + hrCalculationFluctuation.add(Form("CalculationFluctuation/hFluctuationCalculator%s%s_mc", getName(iParticleNumber).data(), getName(iChargeNumber).data()), "", hcsFluctuationCalculator); } - hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNKaPNKaM", ";;#it{N}(K^{+});#it{N}(K^{#minus});", hcsDistribution); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaP", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaM", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaT", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorKaN", "", hcsFluctuationCalculator); } + hrCalculationFluctuation.add(Form("CalculationFluctuation/hCentralityN%s%sN%s%s", getName(iParticleNumber).data(), getName(ChargeSpecies::kPlus).data(), getName(iParticleNumber).data(), getName(ChargeSpecies::kMinus).data()), Form(";;#it{N}(%s^{%s});#it{N}(%s^{%s});", ParticleNumberTitles[iParticleNumber].data(), ChargeSpeciesTitles[toI(ChargeSpecies::kPlus)].data(), ParticleNumberTitles[iParticleNumber].data(), ChargeSpeciesTitles[toI(ChargeSpecies::kMinus)].data()), hcsDistribution); + for (std::int32_t const& iChargeNumber : std::views::iota(0, NEs)) { + hrCalculationFluctuation.add(Form("CalculationFluctuation/hFluctuationCalculator%s%s", getName(iParticleNumber).data(), getName(iChargeNumber).data()), "", hcsFluctuationCalculator); + } + } - if (groupAnalysis.cfgFlagCalculationFluctuationPr.value) { - LOG(info) << "Enabling (anti)proton number fluctuation calculation."; - - fluctuationCalculatorTrackPrP = std::make_unique(); - fluctuationCalculatorTrackPrM = std::make_unique(); - fluctuationCalculatorTrackPrT = std::make_unique(); - fluctuationCalculatorTrackPrN = std::make_unique(); - - if (doprocessMc.value) { - hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNPrPNPrM_mc", ";;#it{N}(p);#it{N}(#bar{p});", hcsDistribution); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrP_mc", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrM_mc", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrT_mc", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrN_mc", "", hcsFluctuationCalculator); - } - hrCalculationFluctuation.add("CalculationFluctuation/hCentralityNPrPNPrM", ";;#it{N}(p);#it{N}(#bar{p});", hcsDistribution); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrP", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrM", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrT", "", hcsFluctuationCalculator); - hrCalculationFluctuation.add("CalculationFluctuation/hFluctuationCalculatorPrN", "", hcsFluctuationCalculator); + for (std::int32_t const& iParticleSpecies : std::views::iota(0, NEs)) { + if (!groupAnalysis.cfgFlagCalculationFluctuation.value.get(toI(ParticleNumber::kCharge)) && !(iParticleSpecies == toI(ParticleSpecies::kKaon) && groupAnalysis.cfgFlagCalculationFluctuation.value.get(toI(ParticleNumber::kKaon))) && !(iParticleSpecies == toI(ParticleSpecies::kProton) && groupAnalysis.cfgFlagCalculationFluctuation.value.get(toI(ParticleNumber::kProton)))) { + continue; } - const auto readHnEfficiency = [&](std::initializer_list*, const char*>> pairsVectorHnNameBase) { - for (const auto& [vectorHn, nameBase] : pairsVectorHnNameBase) { - vectorHn->resize(nRunGroups); - } - for (std::int32_t const& iRunGroup : std::views::iota(0, nRunGroups)) { - const TList* const lRunGroup = readListRunGroup(iRunGroup + 1); - for (const auto& [vectorHn, nameBase] : pairsVectorHnNameBase) { - (*vectorHn)[iRunGroup] = readHn(lRunGroup, nameBase, false, iRunGroup + 1, 4); + holderCcdb.hVzCentralityPtEtaEfficiency.resize(nRunGroups); + for (std::int32_t const& iRunGroup : std::views::iota(0, nRunGroups)) { + const TList* const lRunGroup{readListRunGroup(iRunGroup + 1)}; + for (std::int32_t const& iPidStrategy : std::views::iota(0, NEs)) { + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + const char* const name{Form("hVzCentralityPtEtaEfficiency%s%s%s_runGroup%d", getName(iPidStrategy).data(), getName(iParticleSpecies).data(), getName(iChargeSpecies).data(), iRunGroup + 1)}; + holderCcdb.hVzCentralityPtEtaEfficiency[iRunGroup][iPidStrategy][iParticleSpecies][iChargeSpecies] = dynamic_cast(lRunGroup->FindObject(name)); + if (!holderCcdb.hVzCentralityPtEtaEfficiency[iRunGroup][iPidStrategy][iParticleSpecies][iChargeSpecies] || holderCcdb.hVzCentralityPtEtaEfficiency[iRunGroup][iPidStrategy][iParticleSpecies][iChargeSpecies]->GetNdimensions() != HolderCcdb::NDimensionsEfficiency) { + LOG(fatal) << "Invalid " << name << "!"; + } + LOG(info) << "Reading from CCDB: " << name; } } - }; - - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value) { - readHnEfficiency({{&holderCcdb.hVzCentralityPtEtaEfficiencyTpcPiP, "hVzCentralityPtEtaEfficiencyTpcPiP"}, {&holderCcdb.hVzCentralityPtEtaEfficiencyTpcPiM, "hVzCentralityPtEtaEfficiencyTpcPiM"}, {&holderCcdb.hVzCentralityPtEtaEfficiencyTpcTofPiP, "hVzCentralityPtEtaEfficiencyTpcTofPiP"}, {&holderCcdb.hVzCentralityPtEtaEfficiencyTpcTofPiM, "hVzCentralityPtEtaEfficiencyTpcTofPiM"}}); - } - - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value || groupAnalysis.cfgFlagCalculationFluctuationKa.value) { - readHnEfficiency({{&holderCcdb.hVzCentralityPtEtaEfficiencyTpcKaP, "hVzCentralityPtEtaEfficiencyTpcKaP"}, {&holderCcdb.hVzCentralityPtEtaEfficiencyTpcKaM, "hVzCentralityPtEtaEfficiencyTpcKaM"}, {&holderCcdb.hVzCentralityPtEtaEfficiencyTpcTofKaP, "hVzCentralityPtEtaEfficiencyTpcTofKaP"}, {&holderCcdb.hVzCentralityPtEtaEfficiencyTpcTofKaM, "hVzCentralityPtEtaEfficiencyTpcTofKaM"}}); - } - - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value || groupAnalysis.cfgFlagCalculationFluctuationPr.value) { - readHnEfficiency({{&holderCcdb.hVzCentralityPtEtaEfficiencyTpcPrP, "hVzCentralityPtEtaEfficiencyTpcPrP"}, {&holderCcdb.hVzCentralityPtEtaEfficiencyTpcPrM, "hVzCentralityPtEtaEfficiencyTpcPrM"}, {&holderCcdb.hVzCentralityPtEtaEfficiencyTpcTofPrP, "hVzCentralityPtEtaEfficiencyTpcTofPrP"}, {&holderCcdb.hVzCentralityPtEtaEfficiencyTpcTofPrM, "hVzCentralityPtEtaEfficiencyTpcTofPrM"}}); } } } - template + template + requires IsValid double getEfficiency(const bool doUsingMcParticleMomentum) { - static_assert(particleSpecies == ParticleSpecies::kPi || particleSpecies == ParticleSpecies::kKa || particleSpecies == ParticleSpecies::kPr); - static_assert(pidStrategy == PidStrategy::kTpc || pidStrategy == PidStrategy::kTpcTof); - - static const std::array*, 2>, 2>, static_cast(ParticleSpecies::kNSpecies)> pointersVectorHistogramEfficiency = {{{{{&holderCcdb.hVzCentralityPtEtaEfficiencyTpcPiP, &holderCcdb.hVzCentralityPtEtaEfficiencyTpcTofPiP}, {&holderCcdb.hVzCentralityPtEtaEfficiencyTpcPiM, &holderCcdb.hVzCentralityPtEtaEfficiencyTpcTofPiM}}}, {{{&holderCcdb.hVzCentralityPtEtaEfficiencyTpcKaP, &holderCcdb.hVzCentralityPtEtaEfficiencyTpcTofKaP}, {&holderCcdb.hVzCentralityPtEtaEfficiencyTpcKaM, &holderCcdb.hVzCentralityPtEtaEfficiencyTpcTofKaM}}}, {{{&holderCcdb.hVzCentralityPtEtaEfficiencyTpcPrP, &holderCcdb.hVzCentralityPtEtaEfficiencyTpcTofPrP}, {&holderCcdb.hVzCentralityPtEtaEfficiencyTpcPrM, &holderCcdb.hVzCentralityPtEtaEfficiencyTpcTofPrM}}}}}; - - if constexpr (doProcessingMc) { - if (holderMcParticle.charge == 0) { - return 0.; - } - const THnBase* const hVzCentralityPtEtaEfficiency = pointersVectorHistogramEfficiency[static_cast(particleSpecies)][holderMcParticle.charge > 0 ? 0 : 1][pidStrategy == PidStrategy::kTpc ? 0 : 1]->at(std::abs(holderEvent.runGroupIndex) - 1); - return hVzCentralityPtEtaEfficiency ? (doUsingMcParticleMomentum ? hVzCentralityPtEtaEfficiency->GetBinContent(hVzCentralityPtEtaEfficiency->GetBin(std::array{holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta}.data())) : hVzCentralityPtEtaEfficiency->GetBinContent(hVzCentralityPtEtaEfficiency->GetBin(std::array{holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta}.data()))) : 0.; - } - - if (holderTrack.sign == 0) { - return 0.; - } - const THnBase* const hVzCentralityPtEtaEfficiency = pointersVectorHistogramEfficiency[static_cast(particleSpecies)][holderTrack.sign > 0 ? 0 : 1][pidStrategy == PidStrategy::kTpc ? 0 : 1]->at(std::abs(holderEvent.runGroupIndex) - 1); - return hVzCentralityPtEtaEfficiency ? hVzCentralityPtEtaEfficiency->GetBinContent(hVzCentralityPtEtaEfficiency->GetBin(std::array{holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta}.data())) : 0.; + const THnBase* const hVzCentralityPtEtaEfficiency{holderCcdb.hVzCentralityPtEtaEfficiency.at(std::abs(holderEvent.runGroupIndex) - 1)[toI(pidStrategy)][toI(particleSpecies)][toI(chargeSpecies)]}; + return hVzCentralityPtEtaEfficiency ? hVzCentralityPtEtaEfficiency->GetBinContent(hVzCentralityPtEtaEfficiency->GetBin(std::array{holderEvent.vz, holderEvent.centrality, doUsingMcParticleMomentum ? holderMcParticle.pt : holderTrack.pt, doUsingMcParticleMomentum ? holderMcParticle.eta : holderTrack.eta}.data())) : 0.; } - template + template + requires IsValid double getShiftNSigmaPid() { - static_assert(particleSpecies == ParticleSpecies::kPi || particleSpecies == ParticleSpecies::kKa || particleSpecies == ParticleSpecies::kPr); - static_assert(pidStrategy == PidStrategy::kTpc || pidStrategy == PidStrategy::kTof); - - if constexpr (particleSpecies == ParticleSpecies::kPi) { - if (!groupTrack.cfgFlagRecalibrationNSigmaPi.value) { - return 0.; - } - } else if constexpr (particleSpecies == ParticleSpecies::kKa) { - if (!groupTrack.cfgFlagRecalibrationNSigmaKa.value) { - return 0.; - } - } else if constexpr (particleSpecies == ParticleSpecies::kPr) { - if (!groupTrack.cfgFlagRecalibrationNSigmaPr.value) { - return 0.; - } - } else { + if (!groupTrack.cfgFlagRecalibrationNSigmaPid.value.get(toI(particleSpecies))) { return 0.; } - static const std::array*, 2>, 2>, static_cast(ParticleSpecies::kNSpecies)> pointersVectorHistogramShiftNSigmaPid = {{{{{&holderCcdb.hCentralityPtEtaShiftTpcNSigmaPiP, &holderCcdb.hCentralityPtEtaShiftTofNSigmaPiP}, {&holderCcdb.hCentralityPtEtaShiftTpcNSigmaPiM, &holderCcdb.hCentralityPtEtaShiftTofNSigmaPiM}}}, {{{&holderCcdb.hCentralityPtEtaShiftTpcNSigmaKaP, &holderCcdb.hCentralityPtEtaShiftTofNSigmaKaP}, {&holderCcdb.hCentralityPtEtaShiftTpcNSigmaKaM, &holderCcdb.hCentralityPtEtaShiftTofNSigmaKaM}}}, {{{&holderCcdb.hCentralityPtEtaShiftTpcNSigmaPrP, &holderCcdb.hCentralityPtEtaShiftTofNSigmaPrP}, {&holderCcdb.hCentralityPtEtaShiftTpcNSigmaPrM, &holderCcdb.hCentralityPtEtaShiftTofNSigmaPrM}}}}}; static const auto clampInAxis = [](const double value, const TAxis* const axis) { - const std::int32_t first = std::clamp(axis->GetFirst(), 1, axis->GetNbins()); - const std::int32_t last = std::clamp(axis->GetLast(), 1, axis->GetNbins()); + const std::int32_t first{std::clamp(axis->GetFirst(), 1, axis->GetNbins())}; + const std::int32_t last{std::clamp(axis->GetLast(), 1, axis->GetNbins())}; return first == last ? axis->GetBinCenter(first) : std::clamp(value, std::nextafter(axis->GetBinCenter(first), std::numeric_limits::infinity()), std::nextafter(axis->GetBinCenter(last), -std::numeric_limits::infinity())); }; if (holderTrack.sign == 0) { return 0.; } - const TH3* const hCentralityPtEtaShiftNSigmaPid = pointersVectorHistogramShiftNSigmaPid[static_cast(particleSpecies)][holderTrack.sign > 0 ? 0 : 1][pidStrategy == PidStrategy::kTpc ? 0 : 1]->at(std::abs(holderEvent.runGroupIndex) - 1); + const TH3* const hCentralityPtEtaShiftNSigmaPid{holderCcdb.hCentralityPtEtaShiftNSigmaPid.at(std::abs(holderEvent.runGroupIndex) - 1)[toI(detector)][toI(particleSpecies)][holderTrack.sign > 0 ? toI(ChargeSpecies::kPlus) : toI(ChargeSpecies::kMinus)]}; return hCentralityPtEtaShiftNSigmaPid ? hCentralityPtEtaShiftNSigmaPid->Interpolate(clampInAxis(holderEvent.centrality, hCentralityPtEtaShiftNSigmaPid->GetXaxis()), clampInAxis(holderTrack.pt, hCentralityPtEtaShiftNSigmaPid->GetYaxis()), clampInAxis(holderTrack.eta, hCentralityPtEtaShiftNSigmaPid->GetZaxis())) : 0.; } - template - std::int32_t isPid(const bool doRejectingOthers) + template + requires IsValid + bool isPid(const bool doRejectingOthers) { - static_assert(particleSpecies == ParticleSpecies::kPi || particleSpecies == ParticleSpecies::kKa || particleSpecies == ParticleSpecies::kPr); - static_assert(pidStrategy == PidStrategy::kTpc || pidStrategy == PidStrategy::kTof || pidStrategy == PidStrategy::kTpcAndTof || pidStrategy == PidStrategy::kTpcTof); - - static const std::array, static_cast(ParticleSpecies::kNSpecies)> pointersNSigmaPid = {{{&holderTrack.tpcNSigmaPi, &holderTrack.tofNSigmaPi, &holderTrack.tpcTofNSigmaPi}, {&holderTrack.tpcNSigmaKa, &holderTrack.tofNSigmaKa, &holderTrack.tpcTofNSigmaKa}, {&holderTrack.tpcNSigmaPr, &holderTrack.tofNSigmaPr, &holderTrack.tpcTofNSigmaPr}}}; - - if constexpr (pidStrategy == PidStrategy::kTpc) { - if (doRejectingOthers) { - if (!(std::abs(*pointersNSigmaPid[static_cast(particleSpecies)][0]) < std::min({groupTrack.cfgCutMaxAbsNSigmaPid.value, std::abs(*pointersNSigmaPid[(static_cast(particleSpecies) + 1) % static_cast(ParticleSpecies::kNSpecies)][0]), std::abs(*pointersNSigmaPid[(static_cast(particleSpecies) + 2) % static_cast(ParticleSpecies::kNSpecies)][0])}))) { - return 0; - } - } else { - if (!(std::abs(*pointersNSigmaPid[static_cast(particleSpecies)][0]) < groupTrack.cfgCutMaxAbsNSigmaPid.value)) { - return 0; + if constexpr (particleSpeciesAll == ParticleSpeciesAll::kAll) { + if constexpr (pidStrategyAll == PidStrategyAll::kTpc) { + if (!holderTrack.hasPid[toI(Detector::kTpc)]) { + return false; } - } - } else if constexpr (pidStrategy == PidStrategy::kTof) { - if (doRejectingOthers) { - if (!(std::abs(*pointersNSigmaPid[static_cast(particleSpecies)][1]) < std::min({groupTrack.cfgCutMaxAbsNSigmaPid.value, std::abs(*pointersNSigmaPid[(static_cast(particleSpecies) + 1) % static_cast(ParticleSpecies::kNSpecies)][1]), std::abs(*pointersNSigmaPid[(static_cast(particleSpecies) + 2) % static_cast(ParticleSpecies::kNSpecies)][1])}))) { - return 0; + } else if constexpr (pidStrategyAll == PidStrategyAll::kTof) { + if (!holderTrack.hasPid[toI(Detector::kTof)]) { + return false; } } else { - if (!(std::abs(*pointersNSigmaPid[static_cast(particleSpecies)][1]) < groupTrack.cfgCutMaxAbsNSigmaPid.value)) { - return 0; + if (!holderTrack.hasPid[toI(Detector::kTpc)] || !holderTrack.hasPid[toI(Detector::kTof)]) { + return false; } } - } else if constexpr (pidStrategy == PidStrategy::kTpcAndTof) { - if (doRejectingOthers) { - if (!(std::abs(*pointersNSigmaPid[static_cast(particleSpecies)][0]) < groupTrack.cfgCutMaxAbsNSigmaPid.value && std::abs(*pointersNSigmaPid[static_cast(particleSpecies)][1]) < std::min({groupTrack.cfgCutMaxAbsNSigmaPid.value, std::abs(*pointersNSigmaPid[(static_cast(particleSpecies) + 1) % static_cast(ParticleSpecies::kNSpecies)][1]), std::abs(*pointersNSigmaPid[(static_cast(particleSpecies) + 2) % static_cast(ParticleSpecies::kNSpecies)][1])}))) { - return 0; + } else { + constexpr std::int32_t ParticleSpeciesIndex{toI(getValue(particleSpeciesAll))}; + if constexpr (pidStrategyAll == PidStrategyAll::kTpcTofSeparated) { + if (!(std::abs(holderTrack.nSigmaPid[toI(PidStrategyAll::kTpc)][ParticleSpeciesIndex]) < groupTrack.cfgCutMaxAbsNSigmaPid.value)) { + return false; } - } else { - if (!(std::abs(*pointersNSigmaPid[static_cast(particleSpecies)][0]) < groupTrack.cfgCutMaxAbsNSigmaPid.value && std::abs(*pointersNSigmaPid[static_cast(particleSpecies)][1]) < groupTrack.cfgCutMaxAbsNSigmaPid.value)) { - return 0; + if (!(std::abs(holderTrack.nSigmaPid[toI(PidStrategyAll::kTof)][ParticleSpeciesIndex]) < groupTrack.cfgCutMaxAbsNSigmaPid.value)) { + return false; } - } - } else if constexpr (pidStrategy == PidStrategy::kTpcTof) { - if (doRejectingOthers) { - if (!(std::abs(*pointersNSigmaPid[static_cast(particleSpecies)][2]) < std::min({groupTrack.cfgCutMaxAbsNSigmaPid.value, std::abs(*pointersNSigmaPid[(static_cast(particleSpecies) + 1) % static_cast(ParticleSpecies::kNSpecies)][2]), std::abs(*pointersNSigmaPid[(static_cast(particleSpecies) + 2) % static_cast(ParticleSpecies::kNSpecies)][2])}))) { - return 0; + if (doRejectingOthers && !(std::abs(holderTrack.nSigmaPid[toI(PidStrategyAll::kTof)][ParticleSpeciesIndex]) < std::min(std::abs(holderTrack.nSigmaPid[toI(PidStrategyAll::kTof)][(ParticleSpeciesIndex + 1) % NEs]), std::abs(holderTrack.nSigmaPid[toI(PidStrategyAll::kTof)][(ParticleSpeciesIndex + 2) % NEs])))) { + return false; } } else { - if (!(std::abs(*pointersNSigmaPid[static_cast(particleSpecies)][2]) < groupTrack.cfgCutMaxAbsNSigmaPid.value)) { - return 0; + if (!(std::abs(holderTrack.nSigmaPid[toI(pidStrategyAll)][ParticleSpeciesIndex]) < groupTrack.cfgCutMaxAbsNSigmaPid.value)) { + return false; + } + if (doRejectingOthers && !(std::abs(holderTrack.nSigmaPid[toI(pidStrategyAll)][ParticleSpeciesIndex]) < std::min(std::abs(holderTrack.nSigmaPid[toI(pidStrategyAll)][(ParticleSpeciesIndex + 1) % NEs]), std::abs(holderTrack.nSigmaPid[toI(pidStrategyAll)][(ParticleSpeciesIndex + 2) % NEs])))) { + return false; } } - } else { - return 0; } - return holderTrack.sign; + return true; + } + + template + requires IsValid + bool isPid() + { + if constexpr (particleSpeciesAll != ParticleSpeciesAll::kAll) { + if (holderMcParticle.pdgCode != getPdgCode(particleSpeciesAll, chargeSpecies)) { + return false; + } + } + return true; } bool isGoodMomentum(const bool doUsingMcParticleMomentum) @@ -1681,25 +1508,21 @@ struct PartNumFluc { bool isGoodDca() { if (!groupTrack.cfgFlagRecalibrationDca.value) { - if (!(std::abs(holderTrack.dcaXY) < groupTrack.cfgCutMaxAbsNSigmaDcaXy.value)) { - return false; - } - if (!(std::abs(holderTrack.dcaZ) < groupTrack.cfgCutMaxAbsNSigmaDcaZ.value)) { - return false; + for (std::int32_t const& iDcaAxis : std::views::iota(0, NEs)) { + if (!(std::abs(holderTrack.dca[iDcaAxis]) < groupTrack.cfgCutMaxAbsNSigmaDca.value.get(iDcaAxis))) { + return false; + } } } else { if (holderTrack.sign == 0) { return false; } - const TFormula* const fPtMeanDcaXy = (holderTrack.sign > 0 ? holderCcdb.fPtMeanDcaXyP.at(std::abs(holderEvent.runGroupIndex) - 1) : holderCcdb.fPtMeanDcaXyM.at(std::abs(holderEvent.runGroupIndex) - 1)); - const TFormula* const fPtSigmaDcaXy = (holderTrack.sign > 0 ? holderCcdb.fPtSigmaDcaXyP.at(std::abs(holderEvent.runGroupIndex) - 1) : holderCcdb.fPtSigmaDcaXyM.at(std::abs(holderEvent.runGroupIndex) - 1)); - if (!fPtMeanDcaXy || !fPtSigmaDcaXy || !(std::abs(holderTrack.dcaXY - fPtMeanDcaXy->Eval(holderTrack.pt)) < groupTrack.cfgCutMaxAbsNSigmaDcaXy.value * fPtSigmaDcaXy->Eval(holderTrack.pt))) { - return false; - } - const TFormula* const fPtMeanDcaZ = (holderTrack.sign > 0 ? holderCcdb.fPtMeanDcaZP.at(std::abs(holderEvent.runGroupIndex) - 1) : holderCcdb.fPtMeanDcaZM.at(std::abs(holderEvent.runGroupIndex) - 1)); - const TFormula* const fPtSigmaDcaZ = (holderTrack.sign > 0 ? holderCcdb.fPtSigmaDcaZP.at(std::abs(holderEvent.runGroupIndex) - 1) : holderCcdb.fPtSigmaDcaZM.at(std::abs(holderEvent.runGroupIndex) - 1)); - if (!fPtMeanDcaZ || !fPtSigmaDcaZ || !(std::abs(holderTrack.dcaZ - fPtMeanDcaZ->Eval(holderTrack.pt)) < groupTrack.cfgCutMaxAbsNSigmaDcaZ.value * fPtSigmaDcaZ->Eval(holderTrack.pt))) { - return false; + const std::int32_t chargeSpeciesIndex{holderTrack.sign > 0 ? toI(ChargeSpecies::kPlus) : toI(ChargeSpecies::kMinus)}; + const std::array>, NEs>, NEs>& fPtDcaGroup{holderCcdb.fPtDca.at(std::abs(holderEvent.runGroupIndex) - 1)}; + for (std::int32_t const& iDcaAxis : std::views::iota(0, NEs)) { + if (!fPtDcaGroup[toI(DcaKind::kMean)][iDcaAxis][chargeSpeciesIndex] || !fPtDcaGroup[toI(DcaKind::kSigma)][iDcaAxis][chargeSpeciesIndex] || !(std::abs(holderTrack.dca[iDcaAxis] - fPtDcaGroup[toI(DcaKind::kMean)][iDcaAxis][chargeSpeciesIndex]->Eval(holderTrack.pt)) < groupTrack.cfgCutMaxAbsNSigmaDca.value.get(iDcaAxis) * fPtDcaGroup[toI(DcaKind::kSigma)][iDcaAxis][chargeSpeciesIndex]->Eval(holderTrack.pt))) { + return false; + } } } return true; @@ -1735,10 +1558,10 @@ struct PartNumFluc { return true; } - template + template bool isGoodMcParticle(const MP& mcParticle) { - if constexpr (doProcessingMc) { + if constexpr (isMc) { if (!mcParticle.isPhysicalPrimary()) { return false; } @@ -1746,202 +1569,513 @@ struct PartNumFluc { return true; } - template - void calculateFluctuation() + template + requires IsValid + void fillQaRunByTrackByChargeSpecies(const T& track) + { + const auto fill = [&](const auto& name, const auto value) { + hrQaRun.fill(C_CS("QaRun/pRunIndex") + name + C_CS("_") + C_SV(getName(chargeSpecies)), holderEvent.runIndex, value); + }; + const auto fillNSigmaPidByDetectorParticleSpecies = [&] + requires IsValid(detector), particleSpecies> + () { + const double nSigmaPid{holderTrack.nSigmaPid[toI(getValue(detector))][toI(particleSpecies)]}; + if (std::abs(nSigmaPid) < HolderTrack::TruncationAbsNSigmaPid) { + fill(C_SV(getName(detector)) + C_CS("NSigma") + C_SV(getName(particleSpecies)), nSigmaPid); + } + }; // NOLINT(readability/braces) + + fill(C_CS("ItsNCls"), track.itsNCls()); + fill(C_CS("ItsChi2NCls"), track.itsChi2NCl()); + fill(C_CS("TpcNCls"), track.tpcNClsFound()); + fill(C_CS("TpcChi2NCls"), track.tpcChi2NCl()); + fill(C_CS("TpcNClsSharedRatio"), track.tpcFractionSharedCls()); + fill(C_CS("TpcNCrossedRows"), track.tpcNClsCrossedRows()); + fill(C_CS("TpcNCrossedRowsRatio"), track.tpcCrossedRowsOverFindableCls()); + fill(C_CS("Dca") + C_SV(getName(DcaAxis::kXy)), holderTrack.dca[toI(DcaAxis::kXy)]); + fill(C_CS("Dca") + C_SV(getName(DcaAxis::kZ)), holderTrack.dca[toI(DcaAxis::kZ)]); + fill(C_CS("Pt"), holderTrack.pt); + fill(C_CS("Eta"), holderTrack.eta); + fill(C_CS("Phi"), holderTrack.phi); + if (holderTrack.hasPid[toI(Detector::kTpc)]) { + fill(C_SV(getName(Detector::kTpc)) + C_CS("DeDx"), track.tpcSignal()); + fillNSigmaPidByDetectorParticleSpecies.template operator()(); + fillNSigmaPidByDetectorParticleSpecies.template operator()(); + fillNSigmaPidByDetectorParticleSpecies.template operator()(); + } + if (holderTrack.hasPid[toI(Detector::kTof)]) { + fill(C_SV(getName(Detector::kTof)) + C_CS("InverseBeta"), 1. / track.beta()); + fillNSigmaPidByDetectorParticleSpecies.template operator()(); + fillNSigmaPidByDetectorParticleSpecies.template operator()(); + fillNSigmaPidByDetectorParticleSpecies.template operator()(); + } + } + + template + requires IsValid + void fillQaRunByEventByChargeSpecies() + { + const auto fill = [&](const auto& name, const auto value) { + hrQaRun.fill(C_CS("QaRun/pRunIndex") + name + C_CS("_") + C_SV(getName(chargeSpecies)), holderEvent.runIndex, value); + }; + + fill(C_CS("NGlobalTracks"), holderEvent.nGlobalTracks[toI(chargeSpecies)]); + fill(C_CS("NPvContributors"), holderEvent.nPvContributors[toI(chargeSpecies)]); + if (holderEvent.nGlobalTracks[toI(chargeSpecies)] > 0) { + fill(C_SV(getName(DcaKind::kMean)) + C_CS("Dca") + C_SV(getName(DcaAxis::kXy)), holderEvent.dca[toI(DcaKind::kMean)][toI(DcaAxis::kXy)][toI(chargeSpecies)]); + fill(C_SV(getName(DcaKind::kSigma)) + C_CS("Dca") + C_SV(getName(DcaAxis::kXy)), holderEvent.dca[toI(DcaKind::kSigma)][toI(DcaAxis::kXy)][toI(chargeSpecies)]); + fill(C_SV(getName(DcaKind::kMean)) + C_CS("Dca") + C_SV(getName(DcaAxis::kZ)), holderEvent.dca[toI(DcaKind::kMean)][toI(DcaAxis::kZ)][toI(chargeSpecies)]); + fill(C_SV(getName(DcaKind::kSigma)) + C_CS("Dca") + C_SV(getName(DcaAxis::kZ)), holderEvent.dca[toI(DcaKind::kSigma)][toI(DcaAxis::kZ)][toI(chargeSpecies)]); + } + fill(C_CS("NTofBeta"), holderEvent.nTofBeta[toI(chargeSpecies)]); + } + + template + requires IsValid + void fillQaTrackByChargeSpecies(const T& track) + { + const auto fill = [&](const auto& name, const auto... positionAndWeight) { + hrQaTrack.fill(C_CS("QaTrack/h") + name + C_CS("_") + C_SV(getName(chargeSpecies)), positionAndWeight...); + }; + + fill(C_CS("ItsNCls"), track.itsNCls()); + fill(C_CS("ItsChi2NCls"), track.itsChi2NCl()); + fill(C_CS("TpcNClsNClsShared"), track.tpcNClsFound(), track.tpcNClsShared()); + fill(C_CS("TpcChi2NCls"), track.tpcChi2NCl()); + fill(C_CS("TpcNClsFindableNCrossedRows"), track.tpcNClsFindable(), track.tpcNClsCrossedRows()); + } + + template + requires IsValid + void fillQaDcaByChargeSpecies() + { + const auto fillByDcaAxis = [&] + requires IsValid + () { + hrQaDca.fill(C_CS("QaDca/hPtDca") + C_SV(getName(dcaAxis)) + C_CS("_") + C_SV(getName(chargeSpecies)), holderTrack.pt, holderTrack.dca[toI(dcaAxis)]); + hrQaDca.fill(C_CS("QaDca/pPtDca") + C_SV(getName(dcaAxis)) + C_CS("_") + C_SV(getName(chargeSpecies)), holderTrack.pt, holderTrack.dca[toI(dcaAxis)]); + }; // NOLINT(readability/braces) + + fillByDcaAxis.template operator()(); + fillByDcaAxis.template operator()(); + } + + template + requires IsValid + void fillQaAcceptancebyParticleSpeciesAll(const T& track) { - const bool doUsingMcParticleMomentum = doProcessingMc && groupTrack.cfgFlagMcParticleMomentum.value; - if (!(isGoodMomentum(doUsingMcParticleMomentum) && holderTrack.hasTpcPid)) { + if (!groupAnalysis.cfgFlagQaAcceptance.value.get(toI(particleSpeciesAll)) || holderTrack.sign == 0) { return; } - const auto processSign = [&](const std::int32_t sign, const std::int32_t pdgCodeP, const std::int32_t pdgCodeM, std::int32_t& nP, std::int32_t& nM, std::unique_ptr& fluctuationCalculatorTrackP, std::unique_ptr& fluctuationCalculatorTrackM, std::unique_ptr& fluctuationCalculatorTrackT, std::unique_ptr& fluctuationCalculatorTrackN) { - if (std::abs(sign) != 1) { - return; + const auto fillByChargeSpecies = [&] + requires IsValid + (const auto& name, const auto value) { + const auto fillByPidStrategy = [&] + requires IsValid + () { + if (isPid(pidStrategy), particleSpeciesAll>(false)) { + hrQaAcceptance.fill(C_CS("QaAcceptance/h") + name + C_CS("Pt_") + C_SV(getName(pidStrategy)) + C_CS("Edge") + C_SV(getName(particleSpeciesAll)) + C_SV(getName(chargeSpecies)), value, holderTrack.pt); + } + }; // NOLINT(readability/braces) + + fillByPidStrategy.template operator()(); + fillByPidStrategy.template operator()(); + }; // NOLINT(readability/braces) + + if constexpr (particleSpeciesAll == ParticleSpeciesAll::kAll) { + if (holderTrack.sign > 0) { + fillByChargeSpecies.template operator()(C_CS("Eta"), holderTrack.eta); + } else { + fillByChargeSpecies.template operator()(C_CS("Eta"), holderTrack.eta); + } + } else { + if (holderTrack.sign > 0) { + fillByChargeSpecies.template operator()(C_CS("Rapidity"), track.rapidity(getMass(particleSpeciesAll))); + } else { + fillByChargeSpecies.template operator()(C_CS("Rapidity"), track.rapidity(getMass(particleSpeciesAll))); } - if constexpr (doProcessingMc) { - if (holderMcParticle.pdgCode != (sign > 0 ? pdgCodeP : pdgCodeM)) { - return; + } + } + + template + requires IsValid + void fillQaPhiByParticleSpeciesAll() + { + if (!groupAnalysis.cfgFlagQaPhi.value.get(toI(particleSpeciesAll))) { + return; + } + + const std::int32_t chargeSign{dataMode == DataMode::kMcMcParticle ? holderMcParticle.charge : holderTrack.sign}; + if (chargeSign == 0) { + return; + } + + const auto fillByChargeSpecies = [&] + requires IsValid + () { + if constexpr (dataMode == DataMode::kMcMcParticle) { + if (isPid()) { + hrQaPhi.fill(C_CS("QaPhi/hCentralityPtEtaPhiMc_mc") + C_SV(getName(particleSpeciesAll)) + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); } + } else { + const auto fillByPidStrategy = [&] + requires IsValid + () { + if constexpr (dataMode == DataMode::kMcTrack) { + if (isPid() && isPid(pidStrategy), particleSpeciesAll>(false)) { + hrQaPhi.fill(C_CS("QaPhi/hCentralityPtEtaPhiMc_mc") + C_SV(getName(pidStrategy)) + C_SV(getName(particleSpeciesAll)) + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); + hrQaPhi.fill(C_CS("QaPhi/hCentralityPtEtaPhi_mc") + C_SV(getName(pidStrategy)) + C_SV(getName(particleSpeciesAll)) + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); + } + } else { // dataMode == DataMode::kRawTrack + if (isPid(pidStrategy), particleSpeciesAll>(false)) { + hrQaPhi.fill(C_CS("QaPhi/hCentralityPtEtaPhi_") + C_SV(getName(pidStrategy)) + C_SV(getName(particleSpeciesAll)) + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); + } + } + }; // NOLINT(readability/braces) + + fillByPidStrategy.template operator()(); + fillByPidStrategy.template operator()(); } + }; // NOLINT(readability/braces) + + if (chargeSign > 0) { + fillByChargeSpecies.template operator()(); + } else { + fillByChargeSpecies.template operator()(); + } + } + + template + requires IsValid && (dataMode != DataMode::kMcMcParticle) + void fillQaPidByParticleSpeciesAll(const T& track) + { + if (!groupAnalysis.cfgFlagQaPid.value.get(toI(particleSpeciesAll)) || holderTrack.sign == 0) { + return; + } - const double efficiency = getEfficiency(doUsingMcParticleMomentum); - if (sign > 0) { - nP++; - fluctuationCalculatorTrackP->fill(1., efficiency); - fluctuationCalculatorTrackT->fill(1., efficiency); - fluctuationCalculatorTrackN->fill(1., efficiency); + if constexpr (particleSpeciesAll == ParticleSpeciesAll::kAll) { + if (isPid(PidStrategy::kTpc), ParticleSpeciesAll::kAll>(false)) { + hrQaPid.fill(C_CS("QaPid/hCentralityPOverQEtaTpcLnDeDx"), holderEvent.centrality, holderTrack.p / holderTrack.sign, holderTrack.eta, track.tpcSignal()); + } + if (isPid(PidStrategy::kTpcTof), ParticleSpeciesAll::kAll>(false)) { + hrQaPid.fill(C_CS("QaPid/hCentralityPOverQEtaTofInverseBeta"), holderEvent.centrality, holderTrack.p / holderTrack.sign, holderTrack.eta, 1. / track.beta()); + } + } else { + const auto fillByChargeSpecies = [&] + requires IsValid + () { + if constexpr (dataMode == DataMode::kMcTrack) { + if (isPid()) { + hrQaPid.fill(C_CS("QaPid/hCentralityPtEta") + C_SV(getName(Detector::kTpc)) + C_CS("NSigma") + C_SV(getName(particleSpeciesAll)) + C_CS("_mc") + C_SV(getName(particleSpeciesAll)) + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.nSigmaPid[toI(PidStrategyAll::kTpc)][toI(particleSpeciesAll)]); + hrQaPid.fill(C_CS("QaPid/hCentralityPtEta") + C_SV(getName(Detector::kTof)) + C_CS("NSigma") + C_SV(getName(particleSpeciesAll)) + C_CS("_mc") + C_SV(getName(particleSpeciesAll)) + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.nSigmaPid[toI(PidStrategyAll::kTof)][toI(particleSpeciesAll)]); + } + } else { // dataMode == DataMode::kRawTrack + hrQaPid.fill(C_CS("QaPid/hCentralityPtEta") + C_SV(getName(Detector::kTpc)) + C_CS("NSigma") + C_SV(getName(particleSpeciesAll)) + C_CS("_") + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.nSigmaPid[toI(PidStrategyAll::kTpc)][toI(particleSpeciesAll)]); + if (isPid(false)) { + hrQaPid.fill(C_CS("QaPid/hCentralityPtEta") + C_SV(getName(Detector::kTpc)) + C_CS("NSigma") + C_SV(getName(particleSpeciesAll)) + C_CS("_") + C_SV(getName(Detector::kTof)) + C_SV(getName(particleSpeciesAll)) + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.nSigmaPid[toI(PidStrategyAll::kTpc)][toI(particleSpeciesAll)]); + } + if (isPid(false)) { + hrQaPid.fill(C_CS("QaPid/hCentralityPtEta") + C_SV(getName(Detector::kTof)) + C_CS("NSigma") + C_SV(getName(particleSpeciesAll)) + C_CS("_") + C_SV(getName(Detector::kTpc)) + C_SV(getName(particleSpeciesAll)) + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.nSigmaPid[toI(PidStrategyAll::kTof)][toI(particleSpeciesAll)]); + } + hrQaPid.fill(C_CS("QaPid/hCentralityPtEta") + C_SV(getName(PidStrategy::kTpcTof)) + C_CS("NSigma") + C_SV(getName(particleSpeciesAll)) + C_CS("_") + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.nSigmaPid[toI(PidStrategyAll::kTpcTofCombined)][toI(particleSpeciesAll)]); + } + }; // NOLINT(readability/braces) + + if (holderTrack.sign > 0) { + fillByChargeSpecies.template operator()(); } else { - nM++; - fluctuationCalculatorTrackM->fill(1., efficiency); - fluctuationCalculatorTrackT->fill(1., efficiency); - fluctuationCalculatorTrackN->fill(-1., efficiency); + fillByChargeSpecies.template operator()(); } + } + } + + template + requires IsValid + void fillCalculationYieldByParticleSpecies() + { + if (!groupAnalysis.cfgFlagCalculationYield.value.get(toI(particleSpecies))) { + return; + } + + const std::int32_t chargeSign{dataMode == DataMode::kMcMcParticle ? holderMcParticle.charge : holderTrack.sign}; + if (chargeSign == 0) { + return; + } + + const auto fillByChargeSpecies = [&] + requires IsValid + () { + if constexpr (dataMode == DataMode::kMcMcParticle) { + if (isPid(particleSpecies), chargeSpecies>()) { + hrCalculationYield.fill(C_CS("CalculationYield/hVzCentralityPtEtaMc_mc") + C_SV(getName(particleSpecies)) + C_SV(getName(chargeSpecies)), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); + } + } else { + const auto fillByPidStrategy = [&] + requires IsValid + () { + if constexpr (dataMode == DataMode::kMcTrack) { + if (isPid(particleSpecies), chargeSpecies>() && isPid(pidStrategy), getValue(particleSpecies)>(groupTrack.cfgFlagRejectionOthers.value)) { + hrCalculationYield.fill(C_CS("CalculationYield/hVzCentralityPtEtaMc_mc") + C_SV(getName(pidStrategy)) + C_SV(getName(particleSpecies)) + C_SV(getName(chargeSpecies)), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); + hrCalculationYield.fill(C_CS("CalculationYield/hVzCentralityPtEta_mc") + C_SV(getName(pidStrategy)) + C_SV(getName(particleSpecies)) + C_SV(getName(chargeSpecies)), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); + } + } else { // dataMode == DataMode::kRawTrack + if (isPid(pidStrategy), getValue(particleSpecies)>(groupTrack.cfgFlagRejectionOthers.value)) { + hrCalculationYield.fill(C_CS("CalculationYield/hVzCentralityPtEta_") + C_SV(getName(pidStrategy)) + C_SV(getName(particleSpecies)) + C_SV(getName(chargeSpecies)), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); + } + } + }; // NOLINT(readability/braces) + + fillByPidStrategy.template operator()(); + fillByPidStrategy.template operator()(); + } + }; // NOLINT(readability/braces) + + if (chargeSign > 0) { + fillByChargeSpecies.template operator()(); + } else { + fillByChargeSpecies.template operator()(); + } + } + + template + requires IsValid + void fillCalculationPurityByParticleSpecies() + { + if (!groupAnalysis.cfgFlagCalculationPurity.value.get(toI(particleSpecies)) || holderTrack.sign == 0) { + return; + } + + const auto fillByChargeSpecies = [&] + requires IsValid + () { + const auto fillByPidStrategy = [&] + requires IsValid + () { + if (isPid(pidStrategy), getValue(particleSpecies)>(groupTrack.cfgFlagRejectionOthers.value)) { + hrCalculationPurity.fill(C_CS("CalculationPurity/pCentralityPtEtaPurity") + C_SV(getName(pidStrategy)) + C_SV(getName(particleSpecies)) + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderTrack.pt, holderTrack.eta, isPid(particleSpecies), chargeSpecies>() ? 1. : 0.); + } + }; // NOLINT(readability/braces) + + fillByPidStrategy.template operator()(); + fillByPidStrategy.template operator()(); + }; // NOLINT(readability/braces) + + if (holderTrack.sign > 0) { + fillByChargeSpecies.template operator()(); + } else { + fillByChargeSpecies.template operator()(); + } + } + + template + requires IsValid + void fillCalculationFractionPrimaryByParticleSpecies(const MP& mcParticle) + { + if (!groupAnalysis.cfgFlagCalculationFractionPrimary.value.get(toI(particleSpecies)) || holderTrack.sign == 0) { + return; + } + + const auto fillByChargeSpecies = [&] + requires IsValid + () { + const auto fillByPidStrategy = [&] + requires IsValid + () { + if (isPid(particleSpecies), chargeSpecies>() && isPid(pidStrategy), getValue(particleSpecies)>(groupTrack.cfgFlagRejectionOthers.value)) { + hrCalculationFractionPrimary.fill(C_CS("CalculationFractionPrimary/pCentralityPtEtaFractionPrimary") + C_SV(getName(pidStrategy)) + C_SV(getName(particleSpecies)) + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderTrack.pt, holderTrack.eta, mcParticle.isPhysicalPrimary() ? 1. : 0.); + } + }; // NOLINT(readability/braces) + + fillByPidStrategy.template operator()(); + fillByPidStrategy.template operator()(); }; // NOLINT(readability/braces) - const auto processSpecies = [&](const double thresholdPtTof, const std::int32_t pdgCodeP, const std::int32_t pdgCodeM, std::int32_t& nP, std::int32_t& nM, std::unique_ptr& fluctuationCalculatorTrackP, std::unique_ptr& fluctuationCalculatorTrackM, std::unique_ptr& fluctuationCalculatorTrackT, std::unique_ptr& fluctuationCalculatorTrackN) { - if ((doUsingMcParticleMomentum ? holderMcParticle.pt : holderTrack.pt) < thresholdPtTof) { - processSign.template operator()(isPid(groupTrack.cfgFlagRejectionOthers.value), pdgCodeP, pdgCodeM, nP, nM, fluctuationCalculatorTrackP, fluctuationCalculatorTrackM, fluctuationCalculatorTrackT, fluctuationCalculatorTrackN); - } else if (holderTrack.hasTofPid) { - processSign.template operator()(isPid(groupTrack.cfgFlagRejectionOthers.value), pdgCodeP, pdgCodeM, nP, nM, fluctuationCalculatorTrackP, fluctuationCalculatorTrackM, fluctuationCalculatorTrackT, fluctuationCalculatorTrackN); + if (holderTrack.sign > 0) { + fillByChargeSpecies.template operator()(); + } else { + fillByChargeSpecies.template operator()(); + } + } + + void initCalculationFluctuation() + { + for (std::int32_t const& iParticleNumber : std::views::iota(0, NEs)) { + if (groupAnalysis.cfgFlagCalculationFluctuation.value.get(iParticleNumber)) { + for (std::int32_t const& iChargeNumber : std::views::iota(0, NEs)) { + fluctuationCalculatorTrack[iParticleNumber][iChargeNumber]->init(); + } + } + } + } + + template + requires IsValid + void calculateFluctuationByParticleNumber() + { + if (!groupAnalysis.cfgFlagCalculationFluctuation.value.get(toI(particleNumber))) { + return; + } + + const std::int32_t chargeSign{dataMode == DataMode::kMcMcParticle ? holderMcParticle.charge : holderTrack.sign}; + if (chargeSign == 0) { + return; + } + + const bool doUsingMcParticleMomentum{dataMode == DataMode::kMcMcParticle || (dataMode == DataMode::kMcTrack && groupTrack.cfgFlagMcParticleMomentum.value)}; + if (!isGoodMomentum(doUsingMcParticleMomentum)) { + return; + } + + if constexpr (dataMode == DataMode::kMcMcParticle) { + ++holderDerivedData.nChargedParticlesIn; + } else { + ++holderDerivedData.nTracksIn; + } + + const auto calculateByParticleSpecies = [&] + requires IsValid && (particleNumber == ParticleNumber::kCharge || (particleNumber == ParticleNumber::kKaon && particleSpecies == ParticleSpecies::kKaon) || (particleNumber == ParticleNumber::kProton && particleSpecies == ParticleSpecies::kProton)) + () { + const auto calculateByChargeSpecies = [&] + requires IsValid + () { + if constexpr (dataMode != DataMode::kRawTrack) { + if (!isPid(particleSpecies), chargeSpecies>()) { + return; + } + } + + const bool doUsingTofPid{(doUsingMcParticleMomentum ? holderMcParticle.pt : holderTrack.pt) >= groupTrack.cfgThresholdPtTofPid.value.get(toI(particleSpecies))}; + if constexpr (dataMode != DataMode::kMcMcParticle) { + if (!(doUsingTofPid ? isPid(PidStrategy::kTpcTof), getValue(particleSpecies)>(groupTrack.cfgFlagRejectionOthers.value) : isPid(PidStrategy::kTpc), getValue(particleSpecies)>(groupTrack.cfgFlagRejectionOthers.value))) { + return; + } + } + + const double efficiency{doUsingTofPid ? getEfficiency(doUsingMcParticleMomentum) : getEfficiency(doUsingMcParticleMomentum)}; + const auto fill = [&] { + if constexpr (chargeSpecies == ChargeSpecies::kPlus) { + fluctuationCalculatorTrack[toI(particleNumber)][toI(ChargeNumber::kPlus)]->fill(1., efficiency); + fluctuationCalculatorTrack[toI(particleNumber)][toI(ChargeNumber::kNet)]->fill(1., efficiency); + } else { + fluctuationCalculatorTrack[toI(particleNumber)][toI(ChargeNumber::kMinus)]->fill(1., efficiency); + fluctuationCalculatorTrack[toI(particleNumber)][toI(ChargeNumber::kNet)]->fill(-1., efficiency); + } + fluctuationCalculatorTrack[toI(particleNumber)][toI(ChargeNumber::kTotal)]->fill(1., efficiency); + }; + if constexpr (dataMode == DataMode::kMcMcParticle) { + ++holderMcEvent.numbers[toI(particleNumber)][toI(chargeSpecies)]; + if (gRandom->Rndm() < efficiency) { + ++holderMcEvent.numbersEff[toI(particleNumber)][toI(chargeSpecies)]; + fill(); + } + derivedParticle(derivedCollision.lastIndex() + 1, HolderDerivedData::convertRound(std::copysign(1., chargeSign) * efficiency * 32767.)); + } else { + ++holderEvent.numbers[toI(particleNumber)][toI(chargeSpecies)]; + fill(); + derivedTrack(derivedCollision.lastIndex() + 1, HolderDerivedData::convertRound(std::copysign(1., chargeSign) * efficiency * 32767.)); + } + }; // NOLINT(readability/braces) + + if (chargeSign > 0) { + calculateByChargeSpecies.template operator()(); + } else { + calculateByChargeSpecies.template operator()(); } }; // NOLINT(readability/braces) - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value) { - processSpecies.template operator()(groupTrack.cfgThresholdPtTofPi.value, PDG_t::kPiPlus, PDG_t::kPiMinus, holderEvent.nChP, holderEvent.nChM, fluctuationCalculatorTrackChP, fluctuationCalculatorTrackChM, fluctuationCalculatorTrackChT, fluctuationCalculatorTrackChN); - processSpecies.template operator()(groupTrack.cfgThresholdPtTofKa.value, PDG_t::kKPlus, PDG_t::kKMinus, holderEvent.nChP, holderEvent.nChM, fluctuationCalculatorTrackChP, fluctuationCalculatorTrackChM, fluctuationCalculatorTrackChT, fluctuationCalculatorTrackChN); - processSpecies.template operator()(groupTrack.cfgThresholdPtTofPr.value, PDG_t::kProton, PDG_t::kProtonBar, holderEvent.nChP, holderEvent.nChM, fluctuationCalculatorTrackChP, fluctuationCalculatorTrackChM, fluctuationCalculatorTrackChT, fluctuationCalculatorTrackChN); + if constexpr (particleNumber == ParticleNumber::kKaon) { + calculateByParticleSpecies.template operator()(); + } else if constexpr (particleNumber == ParticleNumber::kProton) { + calculateByParticleSpecies.template operator()(); + } else { // particleNumber == ParticleNumber::kCharge + calculateByParticleSpecies.template operator()(); + calculateByParticleSpecies.template operator()(); + calculateByParticleSpecies.template operator()(); } - if (groupAnalysis.cfgFlagCalculationFluctuationKa.value) { - processSpecies.template operator()(groupTrack.cfgThresholdPtTofKa.value, PDG_t::kKPlus, PDG_t::kKMinus, holderEvent.nKaP, holderEvent.nKaM, fluctuationCalculatorTrackKaP, fluctuationCalculatorTrackKaM, fluctuationCalculatorTrackKaT, fluctuationCalculatorTrackKaN); + } + + template + requires IsValid + void fillCalculationFluctuationByParticleNumber() + { + if (!groupAnalysis.cfgFlagCalculationFluctuation.value.get(toI(particleNumber))) { + return; } - if (groupAnalysis.cfgFlagCalculationFluctuationPr.value) { - processSpecies.template operator()(groupTrack.cfgThresholdPtTofPr.value, PDG_t::kProton, PDG_t::kProtonBar, holderEvent.nPrP, holderEvent.nPrM, fluctuationCalculatorTrackPrP, fluctuationCalculatorTrackPrM, fluctuationCalculatorTrackPrT, fluctuationCalculatorTrackPrN); + + if constexpr (dataMode == DataMode::kMcMcParticle) { + hrCalculationFluctuation.fill(C_CS("CalculationFluctuation/hCentralityN") + C_SV(getName(particleNumber)) + C_SV(getName(ChargeSpecies::kPlus)) + C_CS("N") + C_SV(getName(particleNumber)) + C_SV(getName(ChargeSpecies::kMinus)) + C_CS("_mc"), holderEvent.centrality, holderMcEvent.numbers[toI(particleNumber)][toI(ChargeSpecies::kPlus)], holderMcEvent.numbers[toI(particleNumber)][toI(ChargeSpecies::kMinus)]); + hrCalculationFluctuation.fill(C_CS("CalculationFluctuation/hCentralityN") + C_SV(getName(particleNumber)) + C_SV(getName(ChargeSpecies::kPlus)) + C_CS("N") + C_SV(getName(particleNumber)) + C_SV(getName(ChargeSpecies::kMinus)) + C_CS("_mcEff"), holderEvent.centrality, holderMcEvent.numbersEff[toI(particleNumber)][toI(ChargeSpecies::kPlus)], holderMcEvent.numbersEff[toI(particleNumber)][toI(ChargeSpecies::kMinus)]); + } else { + hrCalculationFluctuation.fill(C_CS("CalculationFluctuation/hCentralityN") + C_SV(getName(particleNumber)) + C_SV(getName(ChargeSpecies::kPlus)) + C_CS("N") + C_SV(getName(particleNumber)) + C_SV(getName(ChargeSpecies::kMinus)), holderEvent.centrality, holderEvent.numbers[toI(particleNumber)][toI(ChargeSpecies::kPlus)], holderEvent.numbers[toI(particleNumber)][toI(ChargeSpecies::kMinus)]); } + + const auto fillByChargeNumber = [&] + requires IsValid + () { + for (std::int32_t const& iOrderVector : std::views::iota(0, fluctuation_calculator_base::NOrderVectors)) { + if constexpr (dataMode == DataMode::kMcMcParticle) { + hrCalculationFluctuation.fill(C_CS("CalculationFluctuation/hFluctuationCalculator") + C_SV(getName(particleNumber)) + C_SV(getName(chargeNumber)) + C_CS("_mc"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrack[toI(particleNumber)][toI(chargeNumber)]->getProductFast(iOrderVector)); + } else { + hrCalculationFluctuation.fill(C_CS("CalculationFluctuation/hFluctuationCalculator") + C_SV(getName(particleNumber)) + C_SV(getName(chargeNumber)), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrack[toI(particleNumber)][toI(chargeNumber)]->getProductFast(iOrderVector)); + } + } + }; // NOLINT(readability/braces) + + fillByChargeNumber.template operator()(); + fillByChargeNumber.template operator()(); + fillByChargeNumber.template operator()(); + fillByChargeNumber.template operator()(); } - template + template bool initTrack(const T& track) { holderTrack.clear(); - holderTrack.dcaXY = track.dcaXY(); - holderTrack.dcaZ = track.dcaZ(); + holderTrack.dca[toI(DcaAxis::kXy)] = track.dcaXY(); + holderTrack.dca[toI(DcaAxis::kZ)] = track.dcaZ(); holderTrack.sign = track.sign(); holderTrack.p = track.p(); holderTrack.pt = track.pt(); holderTrack.eta = track.eta(); holderTrack.phi = track.phi(); - holderTrack.hasTpcPid = (track.hasTPC() && track.tpcSignal() > 0.); - if (holderTrack.hasTpcPid) { - holderTrack.tpcNSigmaPi = HolderTrack::truncateNSigmaPid(track.tpcNSigmaPi() - getShiftNSigmaPid()); - holderTrack.tpcNSigmaKa = HolderTrack::truncateNSigmaPid(track.tpcNSigmaKa() - getShiftNSigmaPid()); - holderTrack.tpcNSigmaPr = HolderTrack::truncateNSigmaPid(track.tpcNSigmaPr() - getShiftNSigmaPid()); - } else { - holderTrack.tpcNSigmaPi = holderTrack.tpcNSigmaKa = holderTrack.tpcNSigmaPr = HolderTrack::truncateNSigmaPid(HolderTrack::TruncationAbsNSigmaPid); + holderTrack.hasPid[toI(Detector::kTpc)] = (track.hasTPC() && track.tpcSignal() > 0.); + if (holderTrack.hasPid[toI(Detector::kTpc)]) { + holderTrack.nSigmaPid[toI(PidStrategyAll::kTpc)] = {HolderTrack::truncateNSigmaPid(track.tpcNSigmaPi() - getShiftNSigmaPid()), HolderTrack::truncateNSigmaPid(track.tpcNSigmaKa() - getShiftNSigmaPid()), HolderTrack::truncateNSigmaPid(track.tpcNSigmaPr() - getShiftNSigmaPid())}; } - holderTrack.hasTofPid = (track.hasTOF() && track.beta() > 0.); - if (holderTrack.hasTofPid) { - holderTrack.tofNSigmaPi = HolderTrack::truncateNSigmaPid(track.tofNSigmaPi() - getShiftNSigmaPid()); - holderTrack.tofNSigmaKa = HolderTrack::truncateNSigmaPid(track.tofNSigmaKa() - getShiftNSigmaPid()); - holderTrack.tofNSigmaPr = HolderTrack::truncateNSigmaPid(track.tofNSigmaPr() - getShiftNSigmaPid()); - } else { - holderTrack.tofNSigmaPi = holderTrack.tofNSigmaKa = holderTrack.tofNSigmaPr = HolderTrack::truncateNSigmaPid(HolderTrack::TruncationAbsNSigmaPid); - } - if (holderTrack.hasTpcPid && holderTrack.hasTofPid) { - holderTrack.tpcTofNSigmaPi = HolderTrack::truncateNSigmaPid(std::copysign(std::hypot(holderTrack.tpcNSigmaPi, holderTrack.tofNSigmaPi), holderTrack.tpcNSigmaPi + holderTrack.tofNSigmaPi)); - holderTrack.tpcTofNSigmaKa = HolderTrack::truncateNSigmaPid(std::copysign(std::hypot(holderTrack.tpcNSigmaKa, holderTrack.tofNSigmaKa), holderTrack.tpcNSigmaKa + holderTrack.tofNSigmaKa)); - holderTrack.tpcTofNSigmaPr = HolderTrack::truncateNSigmaPid(std::copysign(std::hypot(holderTrack.tpcNSigmaPr, holderTrack.tofNSigmaPr), holderTrack.tpcNSigmaPr + holderTrack.tofNSigmaPr)); - } else { - holderTrack.tpcTofNSigmaPi = holderTrack.tpcTofNSigmaKa = holderTrack.tpcTofNSigmaPr = HolderTrack::truncateNSigmaPid(HolderTrack::TruncationAbsNSigmaPid); + holderTrack.hasPid[toI(Detector::kTof)] = (track.hasTOF() && track.beta() > 0.); + if (holderTrack.hasPid[toI(Detector::kTof)]) { + holderTrack.nSigmaPid[toI(PidStrategyAll::kTof)] = {HolderTrack::truncateNSigmaPid(track.tofNSigmaPi() - getShiftNSigmaPid()), HolderTrack::truncateNSigmaPid(track.tofNSigmaKa() - getShiftNSigmaPid()), HolderTrack::truncateNSigmaPid(track.tofNSigmaPr() - getShiftNSigmaPid())}; + if (holderTrack.hasPid[toI(Detector::kTpc)]) { + for (std::int32_t const& iParticleSpecies : std::views::iota(0, NEs)) { + holderTrack.nSigmaPid[toI(PidStrategyAll::kTpcTofCombined)][iParticleSpecies] = HolderTrack::truncateNSigmaPid(std::copysign(std::hypot(holderTrack.nSigmaPid[toI(PidStrategyAll::kTpc)][iParticleSpecies], holderTrack.nSigmaPid[toI(PidStrategyAll::kTof)][iParticleSpecies]), holderTrack.nSigmaPid[toI(PidStrategyAll::kTpc)][iParticleSpecies] + holderTrack.nSigmaPid[toI(PidStrategyAll::kTof)][iParticleSpecies])); + } + } } if constexpr (doInitingEvent) { - if (holderTrack.sign > 0) { - if (track.isPrimaryTrack()) { - holderEvent.nGlobalTracksP++; - if (track.isPVContributor()) { - holderEvent.nPvContributorsP++; - } - holderEvent.meanDcaXyP += holderTrack.dcaXY; - holderEvent.meanSquareDcaXyP += std::pow(holderTrack.dcaXY, 2.); - holderEvent.meanDcaZP += holderTrack.dcaZ; - holderEvent.meanSquareDcaZP += std::pow(holderTrack.dcaZ, 2.); - if (holderTrack.hasTofPid) { - holderEvent.nTofBetaP++; - } + if (track.isPrimaryTrack() && holderTrack.sign != 0) { + const std::int32_t chargeSpeciesIndex{toI(holderTrack.sign > 0 ? ChargeSpecies::kPlus : ChargeSpecies::kMinus)}; + ++holderEvent.nGlobalTracks[chargeSpeciesIndex]; + if (track.isPVContributor()) { + ++holderEvent.nPvContributors[chargeSpeciesIndex]; } - } else if (holderTrack.sign < 0) { - if (track.isPrimaryTrack()) { - holderEvent.nGlobalTracksM++; - if (track.isPVContributor()) { - holderEvent.nPvContributorsM++; - } - holderEvent.meanDcaXyM += holderTrack.dcaXY; - holderEvent.meanSquareDcaXyM += std::pow(holderTrack.dcaXY, 2.); - holderEvent.meanDcaZM += holderTrack.dcaZ; - holderEvent.meanSquareDcaZM += std::pow(holderTrack.dcaZ, 2.); - if (holderTrack.hasTofPid) { - holderEvent.nTofBetaM++; - } + for (std::int32_t const& iDcaAxis : std::views::iota(0, NEs)) { + holderEvent.dca[toI(DcaKind::kMean)][iDcaAxis][chargeSpeciesIndex] += holderTrack.dca[iDcaAxis]; + holderEvent.dca[toI(DcaKind::kSigma)][iDcaAxis][chargeSpeciesIndex] += std::pow(holderTrack.dca[iDcaAxis], 2.); + } + if (holderTrack.hasPid[toI(Detector::kTof)]) { + ++holderEvent.nTofBeta[chargeSpeciesIndex]; } } } if constexpr (doInitingEvent) { if (groupAnalysis.cfgFlagQaRun.value && track.isPrimaryTrack()) { - if (holderTrack.sign > 0.) { - hrQaRun.fill(HIST("QaRun/pRunIndexItsNCls_p"), holderEvent.runIndex, track.itsNCls()); - hrQaRun.fill(HIST("QaRun/pRunIndexItsChi2NCls_p"), holderEvent.runIndex, track.itsChi2NCl()); - hrQaRun.fill(HIST("QaRun/pRunIndexTpcNCls_p"), holderEvent.runIndex, track.tpcNClsFound()); - hrQaRun.fill(HIST("QaRun/pRunIndexTpcChi2NCls_p"), holderEvent.runIndex, track.tpcChi2NCl()); - hrQaRun.fill(HIST("QaRun/pRunIndexTpcNClsSharedRatio_p"), holderEvent.runIndex, track.tpcFractionSharedCls()); - hrQaRun.fill(HIST("QaRun/pRunIndexTpcNCrossedRows_p"), holderEvent.runIndex, track.tpcNClsCrossedRows()); - hrQaRun.fill(HIST("QaRun/pRunIndexTpcNCrossedRowsRatio_p"), holderEvent.runIndex, track.tpcCrossedRowsOverFindableCls()); - hrQaRun.fill(HIST("QaRun/pRunIndexDcaXy_p"), holderEvent.runIndex, holderTrack.dcaXY); - hrQaRun.fill(HIST("QaRun/pRunIndexDcaZ_p"), holderEvent.runIndex, holderTrack.dcaZ); - hrQaRun.fill(HIST("QaRun/pRunIndexPt_p"), holderEvent.runIndex, holderTrack.pt); - hrQaRun.fill(HIST("QaRun/pRunIndexEta_p"), holderEvent.runIndex, holderTrack.eta); - hrQaRun.fill(HIST("QaRun/pRunIndexPhi_p"), holderEvent.runIndex, holderTrack.phi); - if (holderTrack.hasTpcPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTpcDeDx_p"), holderEvent.runIndex, track.tpcSignal()); - if (std::abs(holderTrack.tpcNSigmaPi) < HolderTrack::TruncationAbsNSigmaPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTpcNSigmaPi_p"), holderEvent.runIndex, holderTrack.tpcNSigmaPi); - } - if (std::abs(holderTrack.tpcNSigmaKa) < HolderTrack::TruncationAbsNSigmaPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTpcNSigmaKa_p"), holderEvent.runIndex, holderTrack.tpcNSigmaKa); - } - if (std::abs(holderTrack.tpcNSigmaPr) < HolderTrack::TruncationAbsNSigmaPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTpcNSigmaPr_p"), holderEvent.runIndex, holderTrack.tpcNSigmaPr); - } - } - if (holderTrack.hasTofPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTofInverseBeta_p"), holderEvent.runIndex, 1. / track.beta()); - if (std::abs(holderTrack.tofNSigmaPi) < HolderTrack::TruncationAbsNSigmaPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTofNSigmaPi_p"), holderEvent.runIndex, holderTrack.tofNSigmaPi); - } - if (std::abs(holderTrack.tofNSigmaKa) < HolderTrack::TruncationAbsNSigmaPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTofNSigmaKa_p"), holderEvent.runIndex, holderTrack.tofNSigmaKa); - } - if (std::abs(holderTrack.tofNSigmaPr) < HolderTrack::TruncationAbsNSigmaPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTofNSigmaPr_p"), holderEvent.runIndex, holderTrack.tofNSigmaPr); - } - } - } else if (holderTrack.sign < 0.) { - hrQaRun.fill(HIST("QaRun/pRunIndexItsNCls_m"), holderEvent.runIndex, track.itsNCls()); - hrQaRun.fill(HIST("QaRun/pRunIndexItsChi2NCls_m"), holderEvent.runIndex, track.itsChi2NCl()); - hrQaRun.fill(HIST("QaRun/pRunIndexTpcNCls_m"), holderEvent.runIndex, track.tpcNClsFound()); - hrQaRun.fill(HIST("QaRun/pRunIndexTpcChi2NCls_m"), holderEvent.runIndex, track.tpcChi2NCl()); - hrQaRun.fill(HIST("QaRun/pRunIndexTpcNClsSharedRatio_m"), holderEvent.runIndex, track.tpcFractionSharedCls()); - hrQaRun.fill(HIST("QaRun/pRunIndexTpcNCrossedRows_m"), holderEvent.runIndex, track.tpcNClsCrossedRows()); - hrQaRun.fill(HIST("QaRun/pRunIndexTpcNCrossedRowsRatio_m"), holderEvent.runIndex, track.tpcCrossedRowsOverFindableCls()); - hrQaRun.fill(HIST("QaRun/pRunIndexDcaXy_m"), holderEvent.runIndex, holderTrack.dcaXY); - hrQaRun.fill(HIST("QaRun/pRunIndexDcaZ_m"), holderEvent.runIndex, holderTrack.dcaZ); - hrQaRun.fill(HIST("QaRun/pRunIndexPt_m"), holderEvent.runIndex, holderTrack.pt); - hrQaRun.fill(HIST("QaRun/pRunIndexEta_m"), holderEvent.runIndex, holderTrack.eta); - hrQaRun.fill(HIST("QaRun/pRunIndexPhi_m"), holderEvent.runIndex, holderTrack.phi); - if (holderTrack.hasTpcPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTpcDeDx_m"), holderEvent.runIndex, track.tpcSignal()); - if (std::abs(holderTrack.tpcNSigmaPi) < HolderTrack::TruncationAbsNSigmaPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTpcNSigmaPi_m"), holderEvent.runIndex, holderTrack.tpcNSigmaPi); - } - if (std::abs(holderTrack.tpcNSigmaKa) < HolderTrack::TruncationAbsNSigmaPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTpcNSigmaKa_m"), holderEvent.runIndex, holderTrack.tpcNSigmaKa); - } - if (std::abs(holderTrack.tpcNSigmaPr) < HolderTrack::TruncationAbsNSigmaPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTpcNSigmaPr_m"), holderEvent.runIndex, holderTrack.tpcNSigmaPr); - } - } - if (holderTrack.hasTofPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTofInverseBeta_m"), holderEvent.runIndex, 1. / track.beta()); - if (std::abs(holderTrack.tofNSigmaPi) < HolderTrack::TruncationAbsNSigmaPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTofNSigmaPi_m"), holderEvent.runIndex, holderTrack.tofNSigmaPi); - } - if (std::abs(holderTrack.tofNSigmaKa) < HolderTrack::TruncationAbsNSigmaPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTofNSigmaKa_m"), holderEvent.runIndex, holderTrack.tofNSigmaKa); - } - if (std::abs(holderTrack.tofNSigmaPr) < HolderTrack::TruncationAbsNSigmaPid) { - hrQaRun.fill(HIST("QaRun/pRunIndexTofNSigmaPr_m"), holderEvent.runIndex, holderTrack.tofNSigmaPr); - } - } + if (holderTrack.sign > 0) { + fillQaRunByTrackByChargeSpecies(track); + } else if (holderTrack.sign < 0) { + fillQaRunByTrackByChargeSpecies(track); } } } @@ -1949,17 +2083,9 @@ struct PartNumFluc { if constexpr (!doInitingEvent) { if (groupAnalysis.cfgFlagQaTrack.value && track.isPrimaryTrack()) { if (holderTrack.sign > 0) { - hrQaTrack.fill(HIST("QaTrack/hItsNCls_p"), track.itsNCls()); - hrQaTrack.fill(HIST("QaTrack/hItsChi2NCls_p"), track.itsChi2NCl()); - hrQaTrack.fill(HIST("QaTrack/hTpcNClsNClsShared_p"), track.tpcNClsFound(), track.tpcNClsShared()); - hrQaTrack.fill(HIST("QaTrack/hTpcChi2NCls_p"), track.tpcChi2NCl()); - hrQaTrack.fill(HIST("QaTrack/hTpcNClsFindableNCrossedRows_p"), track.tpcNClsFindable(), track.tpcNClsCrossedRows()); + fillQaTrackByChargeSpecies(track); } else if (holderTrack.sign < 0) { - hrQaTrack.fill(HIST("QaTrack/hItsNCls_m"), track.itsNCls()); - hrQaTrack.fill(HIST("QaTrack/hItsChi2NCls_m"), track.itsChi2NCl()); - hrQaTrack.fill(HIST("QaTrack/hTpcNClsNClsShared_m"), track.tpcNClsFound(), track.tpcNClsShared()); - hrQaTrack.fill(HIST("QaTrack/hTpcChi2NCls_m"), track.tpcChi2NCl()); - hrQaTrack.fill(HIST("QaTrack/hTpcNClsFindableNCrossedRows_m"), track.tpcNClsFindable(), track.tpcNClsCrossedRows()); + fillQaTrackByChargeSpecies(track); } } } @@ -1971,15 +2097,9 @@ struct PartNumFluc { if constexpr (!doInitingEvent) { if (groupAnalysis.cfgFlagQaDca.value) { if (holderTrack.sign > 0) { - hrQaDca.fill(HIST("QaDca/hPtDcaXy_p"), holderTrack.pt, holderTrack.dcaXY); - hrQaDca.fill(HIST("QaDca/pPtDcaXy_p"), holderTrack.pt, holderTrack.dcaXY); - hrQaDca.fill(HIST("QaDca/hPtDcaZ_p"), holderTrack.pt, holderTrack.dcaZ); - hrQaDca.fill(HIST("QaDca/pPtDcaZ_p"), holderTrack.pt, holderTrack.dcaZ); + fillQaDcaByChargeSpecies(); } else if (holderTrack.sign < 0) { - hrQaDca.fill(HIST("QaDca/hPtDcaXy_m"), holderTrack.pt, holderTrack.dcaXY); - hrQaDca.fill(HIST("QaDca/pPtDcaXy_m"), holderTrack.pt, holderTrack.dcaXY); - hrQaDca.fill(HIST("QaDca/hPtDcaZ_m"), holderTrack.pt, holderTrack.dcaZ); - hrQaDca.fill(HIST("QaDca/pPtDcaZ_m"), holderTrack.pt, holderTrack.dcaZ); + fillQaDcaByChargeSpecies(); } } } @@ -1989,105 +2109,23 @@ struct PartNumFluc { } if constexpr (!doInitingEvent) { - if ((groupAnalysis.cfgFlagQaAcceptance.value || groupAnalysis.cfgFlagQaAcceptancePi.value || groupAnalysis.cfgFlagQaAcceptanceKa.value || groupAnalysis.cfgFlagQaAcceptancePr.value) && ((holderTrack.eta > 0. && holderEvent.vz > groupEvent.cfgCutMaxAbsVertexZ.value - 1.) || (holderTrack.eta < 0. && holderEvent.vz < -groupEvent.cfgCutMaxAbsVertexZ.value + 1.)) && holderTrack.hasTpcPid) { - if (groupAnalysis.cfgFlagQaAcceptance.value) { - if (holderTrack.sign > 0) { - hrQaAcceptance.fill(HIST("QaAcceptance/hEtaPt_tpcEdgeP"), holderTrack.eta, holderTrack.pt); - } else if (holderTrack.sign < 0) { - hrQaAcceptance.fill(HIST("QaAcceptance/hEtaPt_tpcEdgeM"), holderTrack.eta, holderTrack.pt); - } - if (holderTrack.hasTofPid) { - if (holderTrack.sign > 0) { - hrQaAcceptance.fill(HIST("QaAcceptance/hEtaPt_tpcTofEdgeP"), holderTrack.eta, holderTrack.pt); - } else if (holderTrack.sign < 0) { - hrQaAcceptance.fill(HIST("QaAcceptance/hEtaPt_tpcTofEdgeM"), holderTrack.eta, holderTrack.pt); - } - } - } - - if (groupAnalysis.cfgFlagQaAcceptancePi.value) { - switch (isPid(false)) { - case 1: - hrQaAcceptance.fill(HIST("QaAcceptance/hRapidityPt_tpcEdgePiP"), track.rapidity(constants::physics::MassPiPlus), holderTrack.pt); - break; - case -1: - hrQaAcceptance.fill(HIST("QaAcceptance/hRapidityPt_tpcEdgePiM"), track.rapidity(constants::physics::MassPiPlus), holderTrack.pt); - break; - } - if (holderTrack.hasTofPid) { - switch (isPid(false)) { - case 1: - hrQaAcceptance.fill(HIST("QaAcceptance/hRapidityPt_tpcTofEdgePiP"), track.rapidity(constants::physics::MassPiPlus), holderTrack.pt); - break; - case -1: - hrQaAcceptance.fill(HIST("QaAcceptance/hRapidityPt_tpcTofEdgePiM"), track.rapidity(constants::physics::MassPiPlus), holderTrack.pt); - break; - } - } - } - - if (groupAnalysis.cfgFlagQaAcceptanceKa.value) { - switch (isPid(false)) { - case 1: - hrQaAcceptance.fill(HIST("QaAcceptance/hRapidityPt_tpcEdgeKaP"), track.rapidity(constants::physics::MassKPlus), holderTrack.pt); - break; - case -1: - hrQaAcceptance.fill(HIST("QaAcceptance/hRapidityPt_tpcEdgeKaM"), track.rapidity(constants::physics::MassKPlus), holderTrack.pt); - break; - } - if (holderTrack.hasTofPid) { - switch (isPid(false)) { - case 1: - hrQaAcceptance.fill(HIST("QaAcceptance/hRapidityPt_tpcTofEdgeKaP"), track.rapidity(constants::physics::MassKPlus), holderTrack.pt); - break; - case -1: - hrQaAcceptance.fill(HIST("QaAcceptance/hRapidityPt_tpcTofEdgeKaM"), track.rapidity(constants::physics::MassKPlus), holderTrack.pt); - break; - } - } - } - - if (groupAnalysis.cfgFlagQaAcceptancePr.value) { - switch (isPid(false)) { - case 1: - hrQaAcceptance.fill(HIST("QaAcceptance/hRapidityPt_tpcEdgePrP"), track.rapidity(constants::physics::MassProton), holderTrack.pt); - break; - case -1: - hrQaAcceptance.fill(HIST("QaAcceptance/hRapidityPt_tpcEdgePrM"), track.rapidity(constants::physics::MassProton), holderTrack.pt); - break; - } - if (holderTrack.hasTofPid) { - switch (isPid(false)) { - case 1: - hrQaAcceptance.fill(HIST("QaAcceptance/hRapidityPt_tpcTofEdgePrP"), track.rapidity(constants::physics::MassProton), holderTrack.pt); - break; - case -1: - hrQaAcceptance.fill(HIST("QaAcceptance/hRapidityPt_tpcTofEdgePrM"), track.rapidity(constants::physics::MassProton), holderTrack.pt); - break; - } - } - } - } - } - - if constexpr (!doInitingEvent) { - if (groupAnalysis.cfgFlagQaPid.value && holderTrack.hasTpcPid) { - hrQaPid.fill(HIST("QaPid/hCentralityPOverQEtaTpcLnDeDx"), holderEvent.centrality, holderTrack.p / holderTrack.sign, holderTrack.eta, track.tpcSignal()); - if (holderTrack.hasTofPid) { - hrQaPid.fill(HIST("QaPid/hCentralityPOverQEtaTofInverseBeta"), holderEvent.centrality, holderTrack.p / holderTrack.sign, holderTrack.eta, 1. / track.beta()); - } + if (isEnabled(groupAnalysis.cfgFlagQaAcceptance) && (holderTrack.eta * holderEvent.vz > 0. && std::abs(holderEvent.vz) > groupEvent.cfgCutMaxAbsVz.value - 1.)) { + fillQaAcceptancebyParticleSpeciesAll(track); + fillQaAcceptancebyParticleSpeciesAll(track); + fillQaAcceptancebyParticleSpeciesAll(track); + fillQaAcceptancebyParticleSpeciesAll(track); } } return true; } - template + template bool initMcParticle(const MP& mcParticle) { holderMcParticle.clear(); holderMcParticle.pdgCode = mcParticle.pdgCode(); - const TParticlePDG* particlePdg = pdg->GetParticle(mcParticle.pdgCode()); + const TParticlePDG* particlePdg{pdg->GetParticle(mcParticle.pdgCode())}; if (particlePdg) { holderMcParticle.charge = std::llrint(particlePdg->Charge()); } else { @@ -2101,23 +2139,23 @@ struct PartNumFluc { holderMcParticle.eta = mcParticle.eta(); holderMcParticle.phi = mcParticle.phi(); - if (!isGoodMcParticle(mcParticle)) { + if (!isGoodMcParticle(mcParticle)) { return false; } return true; } - template + template bool initEvent(const C& collision, const Ts& tracks) { holderEvent.clear(); holderEvent.vz = collision.posZ(); switch (groupEvent.cfgIndexDefinitionCentrality.value) { - case static_cast(CentralityDefinition::kFt0a): + case toI(CentralityDefinition::kFt0a): holderEvent.centrality = collision.centFT0A(); break; - case static_cast(CentralityDefinition::kFt0c): + case toI(CentralityDefinition::kFt0c): holderEvent.centrality = collision.centFT0C(); break; default: @@ -2125,142 +2163,122 @@ struct PartNumFluc { break; } - hrCounter.fill(HIST("hNEvents"), 0.); + hrCounter.fill(C_CS("hNEvents"), 0.); if (!collision.has_foundBC()) { - hrCounter.fill(HIST("hNEvents"), 2.); + hrCounter.fill(C_CS("hNEvents"), 2.); return false; } - const auto& bc = collision.template bc_as(); + const auto& bc{collision.template bc_as()}; holderEvent.runNumber = bc.runNumber(); if (holderCcdb.runNumbersIndicesGroupIndices.find(holderEvent.runNumber) == holderCcdb.runNumbersIndicesGroupIndices.end()) { - hrCounter.fill(HIST("hNEvents"), 2.); + hrCounter.fill(C_CS("hNEvents"), 2.); return false; } std::tie(holderEvent.runIndex, holderEvent.runGroupIndex) = holderCcdb.runNumbersIndicesGroupIndices.at(holderEvent.runNumber); if (holderEvent.runGroupIndex == 0 || (groupEvent.cfgFlagRejectionRunBad.value && holderEvent.runGroupIndex < 0)) { - hrCounter.fill(HIST("hNEvents"), 2.); + hrCounter.fill(C_CS("hNEvents"), 2.); return false; } if (!groupEvent.cfgLabelFlagsRct.value.empty() && !rctFlagsChecker.checkTable(collision)) { - hrCounter.fill(HIST("hNEvents"), 3.); + hrCounter.fill(C_CS("hNEvents"), 3.); return false; } for (std::int32_t const& iEvSel : std::views::iota(0, aod::evsel::EventSelectionFlags::kNsel)) { if (((groupEvent.cfgBitsSelectionEvent.value >> iEvSel) & 1) && !collision.selection_bit(iEvSel)) { - hrCounter.fill(HIST("hNEvents"), 4.); - hrCounter.fill(HIST("hNEvents"), 10. + iEvSel); + hrCounter.fill(C_CS("hNEvents"), 4.); + hrCounter.fill(C_CS("hNEvents"), 10. + iEvSel); return false; } } if (groupEvent.cfgFlagInelEvent.value && !collision.isInelGt0()) { - hrCounter.fill(HIST("hNEvents"), 5.); + hrCounter.fill(C_CS("hNEvents"), 5.); return false; } if (groupAnalysis.cfgFlagQaEvent.value) { - hrQaEvent.fill(HIST("QaEvent/hVxVy"), collision.posX(), collision.posY()); - hrQaEvent.fill(HIST("QaEvent/hVz"), holderEvent.vz); + hrQaEvent.fill(C_CS("QaEvent/hVxVy"), collision.posX(), collision.posY()); + hrQaEvent.fill(C_CS("QaEvent/hVz"), holderEvent.vz); } - if (!(std::abs(holderEvent.vz) < groupEvent.cfgCutMaxAbsVertexZ.value)) { - hrCounter.fill(HIST("hNEvents"), 6.); + if (!(std::abs(holderEvent.vz) < groupEvent.cfgCutMaxAbsVz.value)) { + hrCounter.fill(C_CS("hNEvents"), 6.); return false; } if (groupAnalysis.cfgFlagQaRun.value) { - hrQaRun.fill(HIST("QaRun/pRunIndexVx"), holderEvent.runIndex, collision.posX()); - hrQaRun.fill(HIST("QaRun/pRunIndexVy"), holderEvent.runIndex, collision.posY()); - hrQaRun.fill(HIST("QaRun/pRunIndexVz"), holderEvent.runIndex, holderEvent.vz); - hrQaRun.fill(HIST("QaRun/pRunIndexMultiplicityFt0a"), holderEvent.runIndex, collision.multZeqFT0A()); - hrQaRun.fill(HIST("QaRun/pRunIndexMultiplicityFt0c"), holderEvent.runIndex, collision.multZeqFT0C()); + hrQaRun.fill(C_CS("QaRun/pRunIndexVx"), holderEvent.runIndex, collision.posX()); + hrQaRun.fill(C_CS("QaRun/pRunIndexVy"), holderEvent.runIndex, collision.posY()); + hrQaRun.fill(C_CS("QaRun/pRunIndexVz"), holderEvent.runIndex, holderEvent.vz); + hrQaRun.fill(C_CS("QaRun/pRunIndexMultiplicityFt0a"), holderEvent.runIndex, collision.multZeqFT0A()); + hrQaRun.fill(C_CS("QaRun/pRunIndexMultiplicityFt0c"), holderEvent.runIndex, collision.multZeqFT0C()); if (HolderEvent::RangeCentrality.first <= collision.centFT0A() && collision.centFT0A() <= HolderEvent::RangeCentrality.second) { - hrQaRun.fill(HIST("QaRun/pRunIndexCentralityFt0a"), holderEvent.runIndex, collision.centFT0A()); + hrQaRun.fill(C_CS("QaRun/pRunIndexCentralityFt0a"), holderEvent.runIndex, collision.centFT0A()); } if (HolderEvent::RangeCentrality.first <= collision.centFT0C() && collision.centFT0C() <= HolderEvent::RangeCentrality.second) { - hrQaRun.fill(HIST("QaRun/pRunIndexCentralityFt0c"), holderEvent.runIndex, collision.centFT0C()); + hrQaRun.fill(C_CS("QaRun/pRunIndexCentralityFt0c"), holderEvent.runIndex, collision.centFT0C()); } if (HolderEvent::RangeCentrality.first <= collision.centFT0M() && collision.centFT0M() <= HolderEvent::RangeCentrality.second) { - hrQaRun.fill(HIST("QaRun/pRunIndexCentralityFt0m"), holderEvent.runIndex, collision.centFT0M()); + hrQaRun.fill(C_CS("QaRun/pRunIndexCentralityFt0m"), holderEvent.runIndex, collision.centFT0M()); } } for (const auto& track : tracks) { - if (!track.has_collision()) { + if (!track.has_collision() || track.collisionId() != collision.globalIndex()) { continue; } - initTrack(track); - } - if (holderEvent.nGlobalTracksP > 0.) { - holderEvent.meanDcaXyP /= holderEvent.nGlobalTracksP; - holderEvent.meanSquareDcaXyP /= holderEvent.nGlobalTracksP; - holderEvent.meanDcaZP /= holderEvent.nGlobalTracksP; - holderEvent.meanSquareDcaZP /= holderEvent.nGlobalTracksP; + initTrack(track); } - if (holderEvent.nGlobalTracksM > 0.) { - holderEvent.meanDcaXyM /= holderEvent.nGlobalTracksM; - holderEvent.meanSquareDcaXyM /= holderEvent.nGlobalTracksM; - holderEvent.meanDcaZM /= holderEvent.nGlobalTracksM; - holderEvent.meanSquareDcaZM /= holderEvent.nGlobalTracksM; + for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { + if (holderEvent.nGlobalTracks[iChargeSpecies] > 0) { + for (std::int32_t const& iDcaAxis : std::views::iota(0, NEs)) { + holderEvent.dca[toI(DcaKind::kMean)][iDcaAxis][iChargeSpecies] /= holderEvent.nGlobalTracks[iChargeSpecies]; + holderEvent.dca[toI(DcaKind::kSigma)][iDcaAxis][iChargeSpecies] = std::sqrt(std::max(0., holderEvent.dca[toI(DcaKind::kSigma)][iDcaAxis][iChargeSpecies] / holderEvent.nGlobalTracks[iChargeSpecies] - std::pow(holderEvent.dca[toI(DcaKind::kMean)][iDcaAxis][iChargeSpecies], 2.))); + } + } } if (groupAnalysis.cfgFlagQaRun.value) { - hrQaRun.fill(HIST("QaRun/pRunIndexNGlobalTracks_p"), holderEvent.runIndex, holderEvent.nGlobalTracksP); - hrQaRun.fill(HIST("QaRun/pRunIndexNGlobalTracks_m"), holderEvent.runIndex, holderEvent.nGlobalTracksM); - hrQaRun.fill(HIST("QaRun/pRunIndexNPvContributors_p"), holderEvent.runIndex, holderEvent.nPvContributorsP); - hrQaRun.fill(HIST("QaRun/pRunIndexNPvContributors_m"), holderEvent.runIndex, holderEvent.nPvContributorsM); - if (holderEvent.nGlobalTracksP > 0) { - hrQaRun.fill(HIST("QaRun/pRunIndexMeanDcaXy_p"), holderEvent.runIndex, holderEvent.meanDcaXyP); - hrQaRun.fill(HIST("QaRun/pRunIndexSigmaDcaXy_p"), holderEvent.runIndex, std::sqrt(holderEvent.meanSquareDcaXyP - std::pow(holderEvent.meanDcaXyP, 2.))); - hrQaRun.fill(HIST("QaRun/pRunIndexMeanDcaZ_p"), holderEvent.runIndex, holderEvent.meanDcaZP); - hrQaRun.fill(HIST("QaRun/pRunIndexSigmaDcaZ_p"), holderEvent.runIndex, std::sqrt(holderEvent.meanSquareDcaZP - std::pow(holderEvent.meanDcaZP, 2.))); - } - if (holderEvent.nGlobalTracksM > 0) { - hrQaRun.fill(HIST("QaRun/pRunIndexMeanDcaXy_m"), holderEvent.runIndex, holderEvent.meanDcaXyM); - hrQaRun.fill(HIST("QaRun/pRunIndexSigmaDcaXy_m"), holderEvent.runIndex, std::sqrt(holderEvent.meanSquareDcaXyM - std::pow(holderEvent.meanDcaXyM, 2.))); - hrQaRun.fill(HIST("QaRun/pRunIndexMeanDcaZ_m"), holderEvent.runIndex, holderEvent.meanDcaZM); - hrQaRun.fill(HIST("QaRun/pRunIndexSigmaDcaZ_m"), holderEvent.runIndex, std::sqrt(holderEvent.meanSquareDcaZM - std::pow(holderEvent.meanDcaZM, 2.))); - } - hrQaRun.fill(HIST("QaRun/pRunIndexNTofBeta_p"), holderEvent.runIndex, holderEvent.nTofBetaP); - hrQaRun.fill(HIST("QaRun/pRunIndexNTofBeta_m"), holderEvent.runIndex, holderEvent.nTofBetaM); + fillQaRunByEventByChargeSpecies(); + fillQaRunByEventByChargeSpecies(); } if (groupAnalysis.cfgFlagQaEvent.value) { - hrQaEvent.fill(HIST("QaEvent/hNPvContributorsNGlobalTracks"), holderEvent.nPvContributorsP + holderEvent.nPvContributorsM, holderEvent.nGlobalTracksP + holderEvent.nGlobalTracksM); - if (holderEvent.nGlobalTracksP + holderEvent.nGlobalTracksM > 0) { - hrQaEvent.fill(HIST("QaEvent/hNGlobalTracksMeanDcaXy"), holderEvent.nGlobalTracksP + holderEvent.nGlobalTracksM, (holderEvent.meanDcaXyP * holderEvent.nGlobalTracksP + holderEvent.meanDcaXyM * holderEvent.nGlobalTracksM) / (holderEvent.nGlobalTracksP + holderEvent.nGlobalTracksM)); - hrQaEvent.fill(HIST("QaEvent/hNGlobalTracksMeanDcaZ"), holderEvent.nGlobalTracksP + holderEvent.nGlobalTracksM, (holderEvent.meanDcaZP * holderEvent.nGlobalTracksP + holderEvent.meanDcaZM * holderEvent.nGlobalTracksM) / (holderEvent.nGlobalTracksP + holderEvent.nGlobalTracksM)); + hrQaEvent.fill(C_CS("QaEvent/hNPvContributorsNGlobalTracks"), holderEvent.getNPvContributors(), holderEvent.getNGlobalTracks()); + if (holderEvent.getNGlobalTracks() > 0) { + hrQaEvent.fill(C_CS("QaEvent/hNGlobalTracks") + C_SV(getName(DcaKind::kMean)) + C_CS("Dca") + C_SV(getName(DcaAxis::kXy)), holderEvent.getNGlobalTracks(), holderEvent.getDca()); + hrQaEvent.fill(C_CS("QaEvent/hNGlobalTracks") + C_SV(getName(DcaKind::kMean)) + C_CS("Dca") + C_SV(getName(DcaAxis::kZ)), holderEvent.getNGlobalTracks(), holderEvent.getDca()); } - hrQaEvent.fill(HIST("QaEvent/hNTofBetaNGlobalTracks"), holderEvent.nTofBetaP + holderEvent.nTofBetaM, holderEvent.nGlobalTracksP + holderEvent.nGlobalTracksM); + hrQaEvent.fill(C_CS("QaEvent/hNTofBetaNGlobalTracks"), holderEvent.getNTofBeta(), holderEvent.getNGlobalTracks()); } - if (!(holderEvent.nPvContributorsP + holderEvent.nPvContributorsM - holderEvent.nGlobalTracksP - holderEvent.nGlobalTracksM > groupEvent.cfgCutMinDeviationNPvContributors.value)) { - hrCounter.fill(HIST("hNEvents"), 7.); + if (!(holderEvent.getNPvContributors() - holderEvent.getNGlobalTracks() > groupEvent.cfgCutMinDeviationNPvContributors.value)) { + hrCounter.fill(C_CS("hNEvents"), 7.); return false; } - hrCounter.fill(HIST("hNEvents"), 1.); + hrCounter.fill(C_CS("hNEvents"), 1.); if (groupAnalysis.cfgFlagQaEvent.value) { - if (holderEvent.nGlobalTracksP + holderEvent.nGlobalTracksM > 0) { - hrQaEvent.fill(HIST("QaEvent/hNGlobalTracksMeanDcaXy_nPvContributorsCut"), holderEvent.nGlobalTracksP + holderEvent.nGlobalTracksM, (holderEvent.meanDcaXyP * holderEvent.nGlobalTracksP + holderEvent.meanDcaXyM * holderEvent.nGlobalTracksM) / (holderEvent.nGlobalTracksP + holderEvent.nGlobalTracksM)); - hrQaEvent.fill(HIST("QaEvent/hNGlobalTracksMeanDcaZ_nPvContributorsCut"), holderEvent.nGlobalTracksP + holderEvent.nGlobalTracksM, (holderEvent.meanDcaZP * holderEvent.nGlobalTracksP + holderEvent.meanDcaZM * holderEvent.nGlobalTracksM) / (holderEvent.nGlobalTracksP + holderEvent.nGlobalTracksM)); + if (holderEvent.getNGlobalTracks() > 0) { + hrQaEvent.fill(C_CS("QaEvent/hNGlobalTracks") + C_SV(getName(DcaKind::kMean)) + C_CS("Dca") + C_SV(getName(DcaAxis::kXy)) + C_CS("_nPvContributorsCut"), holderEvent.getNGlobalTracks(), holderEvent.getDca()); + hrQaEvent.fill(C_CS("QaEvent/hNGlobalTracks") + C_SV(getName(DcaKind::kMean)) + C_CS("Dca") + C_SV(getName(DcaAxis::kZ)) + C_CS("_nPvContributorsCut"), holderEvent.getNGlobalTracks(), holderEvent.getDca()); } - hrQaEvent.fill(HIST("QaEvent/hNTofBetaNGlobalTracks_nPvContributorsCut"), holderEvent.nTofBetaP + holderEvent.nTofBetaM, holderEvent.nGlobalTracksP + holderEvent.nGlobalTracksM); + hrQaEvent.fill(C_CS("QaEvent/hNTofBetaNGlobalTracks_nPvContributorsCut"), holderEvent.getNTofBeta(), holderEvent.getNGlobalTracks()); } if (groupAnalysis.cfgFlagQaCentrality.value) { - hrQaCentrality.fill(HIST("QaCentrality/hCentralityFt0a"), collision.centFT0A(), collision.multZeqFT0A()); - hrQaCentrality.fill(HIST("QaCentrality/hCentralityFt0c"), collision.centFT0C(), collision.multZeqFT0C()); - hrQaCentrality.fill(HIST("QaCentrality/hCentralityFt0m"), collision.centFT0M(), collision.multZeqFT0A() + collision.multZeqFT0C()); + hrQaCentrality.fill(C_CS("QaCentrality/hCentralityFt0a"), collision.centFT0A(), collision.multZeqFT0A()); + hrQaCentrality.fill(C_CS("QaCentrality/hCentralityFt0c"), collision.centFT0C(), collision.multZeqFT0C()); + hrQaCentrality.fill(C_CS("QaCentrality/hCentralityFt0m"), collision.centFT0M(), collision.multZeqFT0A() + collision.multZeqFT0C()); } return true; @@ -2269,337 +2287,103 @@ struct PartNumFluc { template bool initMcEvent(const MC& mcCollision) { + holderMcEvent.clear(); holderMcEvent.vz = mcCollision.posZ(); - hrCounter.fill(HIST("hNMcEvents"), 0.); + hrCounter.fill(C_CS("hNMcEvents"), 0.); if (!mcCollision.has_bc()) { - hrCounter.fill(HIST("hNMcEvents"), 2.); + hrCounter.fill(C_CS("hNMcEvents"), 2.); return false; } - const auto& bc = mcCollision.template bc_as(); + const auto& bc{mcCollision.template bc_as()}; holderMcEvent.runNumber = bc.runNumber(); if (holderCcdb.runNumbersIndicesGroupIndices.find(holderMcEvent.runNumber) == holderCcdb.runNumbersIndicesGroupIndices.end()) { - hrCounter.fill(HIST("hNMcEvents"), 2.); + hrCounter.fill(C_CS("hNMcEvents"), 2.); return false; } std::tie(holderMcEvent.runIndex, holderMcEvent.runGroupIndex) = holderCcdb.runNumbersIndicesGroupIndices.at(holderMcEvent.runNumber); - if (holderMcEvent.runGroupIndex == 0 || (groupEvent.cfgFlagRejectionRunBadMc.value && holderMcEvent.runGroupIndex < 0)) { - hrCounter.fill(HIST("hNMcEvents"), 2.); + if (holderMcEvent.runGroupIndex == 0 || (groupEvent.cfgFlagRejectionRunBad.value && holderMcEvent.runGroupIndex < 0)) { + hrCounter.fill(C_CS("hNMcEvents"), 2.); return false; } if (groupEvent.cfgFlagInelEventMc.value && !mcCollision.isInelGt0()) { - hrCounter.fill(HIST("hNMcEvents"), 3.); + hrCounter.fill(C_CS("hNMcEvents"), 3.); return false; } - if (!(std::abs(holderMcEvent.vz) < groupEvent.cfgCutMaxAbsVertexZMc.value)) { - hrCounter.fill(HIST("hNMcEvents"), 4.); + if (groupEvent.cfgFlagCutVzMc.value && !(std::abs(holderMcEvent.vz) < groupEvent.cfgCutMaxAbsVz.value)) { + hrCounter.fill(C_CS("hNMcEvents"), 4.); return false; } - hrCounter.fill(HIST("hNMcEvents"), 1.); + hrCounter.fill(C_CS("hNMcEvents"), 1.); return true; } void processRaw(const soa::Filtered::iterator& collision, const soa::Filtered& tracks, const aod::BCsWithTimestamps&) { - if (!initEvent(collision, tracks) || (!groupAnalysis.cfgFlagQaTrack.value && !groupAnalysis.cfgFlagQaDca.value && !(groupAnalysis.cfgFlagQaAcceptance.value || groupAnalysis.cfgFlagQaAcceptancePi.value || groupAnalysis.cfgFlagQaAcceptanceKa.value || groupAnalysis.cfgFlagQaAcceptancePr.value) && !(groupAnalysis.cfgFlagQaPhi.value || groupAnalysis.cfgFlagQaPhiPi.value || groupAnalysis.cfgFlagQaPhiKa.value || groupAnalysis.cfgFlagQaPhiPr.value) && !(groupAnalysis.cfgFlagQaPid.value || groupAnalysis.cfgFlagQaPidPi.value || groupAnalysis.cfgFlagQaPidKa.value || groupAnalysis.cfgFlagQaPidPr.value) && !(groupAnalysis.cfgFlagCalculationYieldPi.value || groupAnalysis.cfgFlagCalculationYieldKa.value || groupAnalysis.cfgFlagCalculationYieldPr.value) && !(groupAnalysis.cfgFlagCalculationFluctuationCh.value || groupAnalysis.cfgFlagCalculationFluctuationKa.value || groupAnalysis.cfgFlagCalculationFluctuationPr.value))) { + if (!initEvent(collision, tracks) || (!groupAnalysis.cfgFlagQaTrack.value && !groupAnalysis.cfgFlagQaDca.value && !isEnabled(groupAnalysis.cfgFlagQaAcceptance) && !isEnabled(groupAnalysis.cfgFlagQaPhi) && !isEnabled(groupAnalysis.cfgFlagQaPid) && !isEnabled(groupAnalysis.cfgFlagCalculationYield) && !isEnabled(groupAnalysis.cfgFlagCalculationFluctuation))) { return; } - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value || groupAnalysis.cfgFlagCalculationFluctuationKa.value || groupAnalysis.cfgFlagCalculationFluctuationPr.value) { + if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { holderEvent.subgroupIndex = gRandom->Integer(groupEvent.cfgNSubgroups.value); - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value) { - fluctuationCalculatorTrackChP->init(); - fluctuationCalculatorTrackChM->init(); - fluctuationCalculatorTrackChT->init(); - fluctuationCalculatorTrackChN->init(); - } - if (groupAnalysis.cfgFlagCalculationFluctuationKa.value) { - fluctuationCalculatorTrackKaP->init(); - fluctuationCalculatorTrackKaM->init(); - fluctuationCalculatorTrackKaT->init(); - fluctuationCalculatorTrackKaN->init(); - } - if (groupAnalysis.cfgFlagCalculationFluctuationPr.value) { - fluctuationCalculatorTrackPrP->init(); - fluctuationCalculatorTrackPrM->init(); - fluctuationCalculatorTrackPrT->init(); - fluctuationCalculatorTrackPrN->init(); - } + initCalculationFluctuation(); + holderDerivedData.clear(); } for (const auto& track : tracks) { - if (!track.has_collision() || !initTrack(track)) { + if (!track.has_collision() || track.collisionId() != collision.globalIndex()) { continue; } - if ((groupAnalysis.cfgFlagQaPhi.value || groupAnalysis.cfgFlagQaPhiPi.value || groupAnalysis.cfgFlagQaPhiKa.value || groupAnalysis.cfgFlagQaPhiPr.value) && holderTrack.hasTpcPid) { - if (groupAnalysis.cfgFlagQaPhi.value) { - if (holderTrack.sign > 0) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - } else if (holderTrack.sign < 0) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - } - if (holderTrack.hasTofPid) { - if (holderTrack.sign > 0) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcTofP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - } else if (holderTrack.sign < 0) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcTofM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - } - } - } - - if (groupAnalysis.cfgFlagQaPhiPi.value) { - switch (isPid(false)) { - case 1: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcPiP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - case -1: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcPiM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - } - switch (isPid(false)) { - case 1: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcTofPiP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - case -1: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcTofPiM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - } - } - - if (groupAnalysis.cfgFlagQaPhiKa.value) { - switch (isPid(false)) { - case 1: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcKaP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - case -1: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcKaM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - } - switch (isPid(false)) { - case 1: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcTofKaP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - case -1: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcTofKaM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - } - } - - if (groupAnalysis.cfgFlagQaPhiPr.value) { - switch (isPid(false)) { - case 1: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcPrP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - case -1: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcPrM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - } - switch (isPid(false)) { - case 1: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcTofPrP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - case -1: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_tpcTofPrM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - } - } + const bool isGood{initTrack(track)}; + if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation) && holderTrack.sign != 0) { + ++holderDerivedData.nTracksAll; } - - if ((groupAnalysis.cfgFlagQaPidPi.value || groupAnalysis.cfgFlagQaPidKa.value || groupAnalysis.cfgFlagQaPidPr.value) && holderTrack.hasTpcPid) { - if (groupAnalysis.cfgFlagQaPidPi.value) { - if (holderTrack.sign > 0) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaPi_p"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaPi); - } else if (holderTrack.sign < 0) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaPi_m"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaPi); - } - if (holderTrack.hasTofPid) { - switch (isPid(false)) { - case 1: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaPi_tofPiP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaPi); - break; - case -1: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaPi_tofPiM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaPi); - break; - } - switch (isPid(false)) { - case 1: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTofNSigmaPi_tpcPiP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tofNSigmaPi); - break; - case -1: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTofNSigmaPi_tpcPiM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tofNSigmaPi); - break; - } - if (holderTrack.sign > 0) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcTofNSigmaPi_p"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcTofNSigmaPi); - } else if (holderTrack.sign < 0) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcTofNSigmaPi_m"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcTofNSigmaPi); - } - } - } - - if (groupAnalysis.cfgFlagQaPidKa.value) { - if (holderTrack.sign > 0) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaKa_p"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaKa); - } else if (holderTrack.sign < 0) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaKa_m"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaKa); - } - if (holderTrack.hasTofPid) { - switch (isPid(false)) { - case 1: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaKa_tofKaP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaKa); - break; - case -1: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaKa_tofKaM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaKa); - break; - } - switch (isPid(false)) { - case 1: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTofNSigmaKa_tpcKaP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tofNSigmaKa); - break; - case -1: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTofNSigmaKa_tpcKaM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tofNSigmaKa); - break; - } - if (holderTrack.sign > 0) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcTofNSigmaKa_p"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcTofNSigmaKa); - } else if (holderTrack.sign < 0) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcTofNSigmaKa_m"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcTofNSigmaKa); - } - } - } - - if (groupAnalysis.cfgFlagQaPidPr.value) { - if (holderTrack.sign > 0) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaPr_p"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaPr); - } else if (holderTrack.sign < 0) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaPr_m"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaPr); - } - if (holderTrack.hasTofPid) { - switch (isPid(false)) { - case 1: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaPr_tofPrP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaPr); - break; - case -1: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaPr_tofPrM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaPr); - break; - } - switch (isPid(false)) { - case 1: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTofNSigmaPr_tpcPrP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tofNSigmaPr); - break; - case -1: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTofNSigmaPr_tpcPrM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tofNSigmaPr); - break; - } - if (holderTrack.sign > 0) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcTofNSigmaPr_p"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcTofNSigmaPr); - } else if (holderTrack.sign < 0) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcTofNSigmaPr_m"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcTofNSigmaPr); - } - } - } + if (!isGood) { + continue; } - if ((groupAnalysis.cfgFlagCalculationYieldPi.value || groupAnalysis.cfgFlagCalculationYieldKa.value || groupAnalysis.cfgFlagCalculationYieldPr.value) && holderTrack.hasTpcPid) { - if (groupAnalysis.cfgFlagCalculationYieldPi.value) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_tpcPiP"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - break; - case -1: - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_tpcPiM"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - break; - } - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_tpcTofPiP"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - break; - case -1: - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_tpcTofPiM"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - break; - } - } - - if (groupAnalysis.cfgFlagCalculationYieldKa.value) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_tpcKaP"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - break; - case -1: - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_tpcKaM"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - break; - } - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_tpcTofKaP"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - break; - case -1: - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_tpcTofKaM"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - break; - } - } - - if (groupAnalysis.cfgFlagCalculationYieldPr.value) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_tpcPrP"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - break; - case -1: - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_tpcPrM"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - break; - } - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_tpcTofPrP"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - break; - case -1: - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_tpcTofPrM"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - break; - } - } + if (isEnabled(groupAnalysis.cfgFlagQaPhi)) { + fillQaPhiByParticleSpeciesAll(); + fillQaPhiByParticleSpeciesAll(); + fillQaPhiByParticleSpeciesAll(); + fillQaPhiByParticleSpeciesAll(); } - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value || groupAnalysis.cfgFlagCalculationFluctuationKa.value || groupAnalysis.cfgFlagCalculationFluctuationPr.value) { - calculateFluctuation(); + if (isEnabled(groupAnalysis.cfgFlagQaPid)) { + fillQaPidByParticleSpeciesAll(track); + fillQaPidByParticleSpeciesAll(track); + fillQaPidByParticleSpeciesAll(track); + fillQaPidByParticleSpeciesAll(track); } - } - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hCentralityNChPNChM"), holderEvent.centrality, holderEvent.nChP, holderEvent.nChM); - for (std::int32_t const& iOrderVector : std::views::iota(0, static_cast(fluctuation_calculator_base::NOrderVectors))) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorChP"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackChP->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorChM"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackChM->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorChT"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackChT->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorChN"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackChN->getProductFast(iOrderVector)); + if (isEnabled(groupAnalysis.cfgFlagCalculationYield)) { + fillCalculationYieldByParticleSpecies(); + fillCalculationYieldByParticleSpecies(); + fillCalculationYieldByParticleSpecies(); } - } - if (groupAnalysis.cfgFlagCalculationFluctuationKa.value) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hCentralityNKaPNKaM"), holderEvent.centrality, holderEvent.nKaP, holderEvent.nKaM); - for (std::int32_t const& iOrderVector : std::views::iota(0, static_cast(fluctuation_calculator_base::NOrderVectors))) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorKaP"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackKaP->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorKaM"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackKaM->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorKaT"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackKaT->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorKaN"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackKaN->getProductFast(iOrderVector)); + + if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + calculateFluctuationByParticleNumber(); + calculateFluctuationByParticleNumber(); + calculateFluctuationByParticleNumber(); } } - if (groupAnalysis.cfgFlagCalculationFluctuationPr.value) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hCentralityNPrPNPrM"), holderEvent.centrality, holderEvent.nPrP, holderEvent.nPrM); - for (std::int32_t const& iOrderVector : std::views::iota(0, static_cast(fluctuation_calculator_base::NOrderVectors))) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorPrP"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackPrP->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorPrM"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackPrM->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorPrT"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackPrT->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorPrN"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackPrN->getProductFast(iOrderVector)); - } + + if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + fillCalculationFluctuationByParticleNumber(); + fillCalculationFluctuationByParticleNumber(); + fillCalculationFluctuationByParticleNumber(); + derivedCollision(HolderDerivedData::convertFloor(holderEvent.vz * 10.), HolderDerivedData::convertFloor(holderEvent.centrality * 500.), holderDerivedData.nChargedParticlesAll, holderDerivedData.nChargedParticlesIn, holderDerivedData.nTracksAll, holderDerivedData.nTracksIn); } } PROCESS_SWITCH(PartNumFluc, processRaw, "Process raw data", true); @@ -2615,669 +2399,139 @@ struct PartNumFluc { continue; } - const auto& tracks = tracksUngrouped.sliceBy(presliceTracksPerCollision, collision.globalIndex()); + const auto& tracks{tracksUngrouped.sliceBy(presliceTracksPerCollision, collision.globalIndex())}; if (!initEvent(collision, tracks)) { continue; } if (groupAnalysis.cfgFlagQaMc.value) { - hrQaMc.fill(HIST("QaMc/hCentralityVzDeltaVz"), holderEvent.centrality, holderEvent.vz, holderEvent.vz - holderMcEvent.vz); + hrQaMc.fill(C_CS("QaMc/hCentralityVzDeltaVz"), holderEvent.centrality, holderEvent.vz, holderEvent.vz - holderMcEvent.vz); } - if ((groupAnalysis.cfgFlagQaPhi.value || groupAnalysis.cfgFlagQaPhiPi.value || groupAnalysis.cfgFlagQaPhiKa.value || groupAnalysis.cfgFlagQaPhiPr.value) || (groupAnalysis.cfgFlagCalculationYieldPi.value || groupAnalysis.cfgFlagCalculationYieldKa.value || groupAnalysis.cfgFlagCalculationYieldPr.value) || (groupAnalysis.cfgFlagCalculationFluctuationCh.value || groupAnalysis.cfgFlagCalculationFluctuationKa.value || groupAnalysis.cfgFlagCalculationFluctuationPr.value)) { - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value || groupAnalysis.cfgFlagCalculationFluctuationKa.value || groupAnalysis.cfgFlagCalculationFluctuationPr.value) { + if (isEnabled(groupAnalysis.cfgFlagQaPhi) || isEnabled(groupAnalysis.cfgFlagCalculationYield) || isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { holderEvent.subgroupIndex = gRandom->Integer(groupEvent.cfgNSubgroups.value); - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value) { - fluctuationCalculatorTrackChP->init(); - fluctuationCalculatorTrackChM->init(); - fluctuationCalculatorTrackChT->init(); - fluctuationCalculatorTrackChN->init(); - } - if (groupAnalysis.cfgFlagCalculationFluctuationKa.value) { - fluctuationCalculatorTrackKaP->init(); - fluctuationCalculatorTrackKaM->init(); - fluctuationCalculatorTrackKaT->init(); - fluctuationCalculatorTrackKaN->init(); - } - if (groupAnalysis.cfgFlagCalculationFluctuationPr.value) { - fluctuationCalculatorTrackPrP->init(); - fluctuationCalculatorTrackPrM->init(); - fluctuationCalculatorTrackPrT->init(); - fluctuationCalculatorTrackPrN->init(); - } + initCalculationFluctuation(); + holderDerivedData.clear(); } for (const auto& mcParticle : mcParticles) { - if (!initMcParticle(mcParticle)) { + if (!mcParticle.has_mcCollision() || mcParticle.mcCollisionId() != mcCollision.globalIndex()) { continue; } - if (groupAnalysis.cfgFlagQaPhi.value) { - if (holderMcParticle.charge > 0) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcP"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - } else if (holderMcParticle.charge < 0) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcM"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - } + const bool isGood{initMcParticle(mcParticle)}; + if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation) && holderMcParticle.charge != 0) { + ++holderDerivedData.nChargedParticlesAll; + } + if (!isGood) { + continue; } - if ((groupAnalysis.cfgFlagQaPhiPi.value || groupAnalysis.cfgFlagQaPhiKa.value || groupAnalysis.cfgFlagQaPhiPr.value) || (groupAnalysis.cfgFlagCalculationYieldPi.value || groupAnalysis.cfgFlagCalculationYieldKa.value || groupAnalysis.cfgFlagCalculationYieldPr.value) || (groupAnalysis.cfgFlagCalculationFluctuationCh.value || groupAnalysis.cfgFlagCalculationFluctuationKa.value || groupAnalysis.cfgFlagCalculationFluctuationPr.value)) { - switch (holderMcParticle.pdgCode) { - case PDG_t::kPiPlus: - if (groupAnalysis.cfgFlagQaPhiPi.value) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcPiP"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - } - if (groupAnalysis.cfgFlagCalculationYieldPi.value) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcPiP"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - } - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value && isGoodMomentum(true)) { - holderMcEvent.nChP++; - fluctuationCalculatorTrackChP->fill(1., 1.); - fluctuationCalculatorTrackChT->fill(1., 1.); - fluctuationCalculatorTrackChN->fill(1., 1.); - } - break; - case PDG_t::kPiMinus: - if (groupAnalysis.cfgFlagQaPhiPi.value) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcPiM"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - } - if (groupAnalysis.cfgFlagCalculationYieldPi.value) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcPiM"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - } - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value && isGoodMomentum(true)) { - holderMcEvent.nChM++; - fluctuationCalculatorTrackChM->fill(1., 1.); - fluctuationCalculatorTrackChT->fill(1., 1.); - fluctuationCalculatorTrackChN->fill(-1., 1.); - } - break; - case PDG_t::kKPlus: - if (groupAnalysis.cfgFlagQaPhiKa.value) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcKaP"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - } - if (groupAnalysis.cfgFlagCalculationYieldKa.value) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcKaP"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - } - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value && isGoodMomentum(true)) { - holderMcEvent.nChP++; - fluctuationCalculatorTrackChP->fill(1., 1.); - fluctuationCalculatorTrackChT->fill(1., 1.); - fluctuationCalculatorTrackChN->fill(1., 1.); - } - if (groupAnalysis.cfgFlagCalculationFluctuationKa.value && isGoodMomentum(true)) { - holderMcEvent.nKaP++; - fluctuationCalculatorTrackKaP->fill(1., 1.); - fluctuationCalculatorTrackKaT->fill(1., 1.); - fluctuationCalculatorTrackKaN->fill(1., 1.); - } - break; - case PDG_t::kKMinus: - if (groupAnalysis.cfgFlagQaPhiKa.value) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcKaM"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - } - if (groupAnalysis.cfgFlagCalculationYieldKa.value) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcKaM"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - } - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value && isGoodMomentum(true)) { - holderMcEvent.nChM++; - fluctuationCalculatorTrackChM->fill(1., 1.); - fluctuationCalculatorTrackChT->fill(1., 1.); - fluctuationCalculatorTrackChN->fill(-1., 1.); - } - if (groupAnalysis.cfgFlagCalculationFluctuationKa.value && isGoodMomentum(true)) { - holderMcEvent.nKaM++; - fluctuationCalculatorTrackKaM->fill(1., 1.); - fluctuationCalculatorTrackKaT->fill(1., 1.); - fluctuationCalculatorTrackKaN->fill(-1., 1.); - } - break; - case PDG_t::kProton: - if (groupAnalysis.cfgFlagQaPhiPr.value) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcPrP"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - } - if (groupAnalysis.cfgFlagCalculationYieldPr.value) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcPrP"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - } - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value && isGoodMomentum(true)) { - holderMcEvent.nChP++; - fluctuationCalculatorTrackChP->fill(1., 1.); - fluctuationCalculatorTrackChT->fill(1., 1.); - fluctuationCalculatorTrackChN->fill(1., 1.); - } - if (groupAnalysis.cfgFlagCalculationFluctuationPr.value && isGoodMomentum(true)) { - holderMcEvent.nPrP++; - fluctuationCalculatorTrackPrP->fill(1., 1.); - fluctuationCalculatorTrackPrT->fill(1., 1.); - fluctuationCalculatorTrackPrN->fill(1., 1.); - } - break; - case PDG_t::kProtonBar: - if (groupAnalysis.cfgFlagQaPhiPr.value) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcPrM"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - } - if (groupAnalysis.cfgFlagCalculationYieldPr.value) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcPrM"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - } - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value && isGoodMomentum(true)) { - holderMcEvent.nChM++; - fluctuationCalculatorTrackChM->fill(1., 1.); - fluctuationCalculatorTrackChT->fill(1., 1.); - fluctuationCalculatorTrackChN->fill(-1., 1.); - } - if (groupAnalysis.cfgFlagCalculationFluctuationPr.value && isGoodMomentum(true)) { - holderMcEvent.nPrM++; - fluctuationCalculatorTrackPrM->fill(1., 1.); - fluctuationCalculatorTrackPrT->fill(1., 1.); - fluctuationCalculatorTrackPrN->fill(-1., 1.); - } - break; - } + if (isEnabled(groupAnalysis.cfgFlagQaPhi)) { + fillQaPhiByParticleSpeciesAll(); + fillQaPhiByParticleSpeciesAll(); + fillQaPhiByParticleSpeciesAll(); + fillQaPhiByParticleSpeciesAll(); } - } - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hCentralityNChPNChM_mc"), holderEvent.centrality, holderMcEvent.nChP, holderMcEvent.nChM); - for (std::int32_t const& iOrderVector : std::views::iota(0, static_cast(fluctuation_calculator_base::NOrderVectors))) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorChP_mc"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackChP->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorChM_mc"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackChM->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorChT_mc"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackChT->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorChN_mc"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackChN->getProductFast(iOrderVector)); + if (isEnabled(groupAnalysis.cfgFlagCalculationYield)) { + fillCalculationYieldByParticleSpecies(); + fillCalculationYieldByParticleSpecies(); + fillCalculationYieldByParticleSpecies(); } - } - if (groupAnalysis.cfgFlagCalculationFluctuationKa.value) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hCentralityNKaPNKaM_mc"), holderEvent.centrality, holderMcEvent.nKaP, holderMcEvent.nKaM); - for (std::int32_t const& iOrderVector : std::views::iota(0, static_cast(fluctuation_calculator_base::NOrderVectors))) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorKaP_mc"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackKaP->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorKaM_mc"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackKaM->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorKaT_mc"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackKaT->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorKaN_mc"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackKaN->getProductFast(iOrderVector)); + + if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + calculateFluctuationByParticleNumber(); + calculateFluctuationByParticleNumber(); + calculateFluctuationByParticleNumber(); } } - if (groupAnalysis.cfgFlagCalculationFluctuationPr.value) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hCentralityNPrPNPrM_mc"), holderEvent.centrality, holderMcEvent.nPrP, holderMcEvent.nPrM); - for (std::int32_t const& iOrderVector : std::views::iota(0, static_cast(fluctuation_calculator_base::NOrderVectors))) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorPrP_mc"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackPrP->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorPrM_mc"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackPrM->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorPrT_mc"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackPrT->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorPrN_mc"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackPrN->getProductFast(iOrderVector)); - } + + if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + fillCalculationFluctuationByParticleNumber(); + fillCalculationFluctuationByParticleNumber(); + fillCalculationFluctuationByParticleNumber(); } } - if (groupAnalysis.cfgFlagQaTrack.value || groupAnalysis.cfgFlagQaDca.value || (groupAnalysis.cfgFlagQaAcceptance.value || groupAnalysis.cfgFlagQaAcceptancePi.value || groupAnalysis.cfgFlagQaAcceptanceKa.value || groupAnalysis.cfgFlagQaAcceptancePr.value) || (groupAnalysis.cfgFlagQaPhi.value || groupAnalysis.cfgFlagQaPhiPi.value || groupAnalysis.cfgFlagQaPhiKa.value || groupAnalysis.cfgFlagQaPhiPr.value) || (groupAnalysis.cfgFlagQaPid.value || groupAnalysis.cfgFlagQaPidPi.value || groupAnalysis.cfgFlagQaPidKa.value || groupAnalysis.cfgFlagQaPidPr.value) || (groupAnalysis.cfgFlagCalculationYieldPi.value || groupAnalysis.cfgFlagCalculationYieldKa.value || groupAnalysis.cfgFlagCalculationYieldPr.value) || (groupAnalysis.cfgFlagCalculationPurityPi.value || groupAnalysis.cfgFlagCalculationPurityKa.value || groupAnalysis.cfgFlagCalculationPurityPr.value) || (groupAnalysis.cfgFlagCalculationFractionPrimaryPi.value || groupAnalysis.cfgFlagCalculationFractionPrimaryKa.value || groupAnalysis.cfgFlagCalculationFractionPrimaryPr.value) || (groupAnalysis.cfgFlagCalculationFluctuationCh.value || groupAnalysis.cfgFlagCalculationFluctuationKa.value || groupAnalysis.cfgFlagCalculationFluctuationPr.value)) { - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value || groupAnalysis.cfgFlagCalculationFluctuationKa.value || groupAnalysis.cfgFlagCalculationFluctuationPr.value) { - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value) { - fluctuationCalculatorTrackChP->init(); - fluctuationCalculatorTrackChM->init(); - fluctuationCalculatorTrackChT->init(); - fluctuationCalculatorTrackChN->init(); - } - if (groupAnalysis.cfgFlagCalculationFluctuationKa.value) { - fluctuationCalculatorTrackKaP->init(); - fluctuationCalculatorTrackKaM->init(); - fluctuationCalculatorTrackKaT->init(); - fluctuationCalculatorTrackKaN->init(); - } - if (groupAnalysis.cfgFlagCalculationFluctuationPr.value) { - fluctuationCalculatorTrackPrP->init(); - fluctuationCalculatorTrackPrM->init(); - fluctuationCalculatorTrackPrT->init(); - fluctuationCalculatorTrackPrN->init(); - } + if (groupAnalysis.cfgFlagQaTrack.value || groupAnalysis.cfgFlagQaDca.value || isEnabled(groupAnalysis.cfgFlagQaAcceptance) || isEnabled(groupAnalysis.cfgFlagQaPhi) || isEnabled(groupAnalysis.cfgFlagQaPid) || isEnabled(groupAnalysis.cfgFlagCalculationYield) || isEnabled(groupAnalysis.cfgFlagCalculationPurity) || isEnabled(groupAnalysis.cfgFlagCalculationFractionPrimary) || isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + initCalculationFluctuation(); } for (const auto& track : tracks) { - if (!track.has_collision() || !track.has_mcParticle()) { + if (!track.has_collision() || track.collisionId() != collision.globalIndex() || !track.has_mcParticle()) { continue; } - const auto& mcParticle = track.template mcParticle_as(); - if (!mcParticle.has_mcCollision() || !initTrack(track) || !initMcParticle(mcParticle)) { + const auto& mcParticle{track.template mcParticle_as()}; + if (!mcParticle.has_mcCollision() || mcParticle.mcCollisionId() != mcCollision.globalIndex()) { continue; } - if ((groupAnalysis.cfgFlagQaPhi.value || groupAnalysis.cfgFlagQaPhiPi.value || groupAnalysis.cfgFlagQaPhiKa.value || groupAnalysis.cfgFlagQaPhiPr.value) && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary()) && holderTrack.hasTpcPid) { - if (groupAnalysis.cfgFlagQaPhi.value) { - if (holderTrack.sign > 0.) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcP"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - } else if (holderTrack.sign < 0.) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcM"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - } - if (holderTrack.hasTofPid) { - if (holderTrack.sign > 0.) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofP"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcTofP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - } else if (holderTrack.sign < 0.) { - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofM"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcTofM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - } - } - } - - if (groupAnalysis.cfgFlagQaPhiPi.value) { - switch (holderMcParticle.pdgCode) { - case PDG_t::kPiPlus: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcPiP"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcPiP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - case PDG_t::kPiMinus: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcPiM"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcPiM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - } - if (holderTrack.hasTofPid) { - switch (holderMcParticle.pdgCode) { - case PDG_t::kPiPlus: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofPiP"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcTofPiP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - case PDG_t::kPiMinus: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofPiM"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcTofPiM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - } - } - } - - if (groupAnalysis.cfgFlagQaPhiKa.value) { - switch (holderMcParticle.pdgCode) { - case PDG_t::kKPlus: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcKaP"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcKaP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - case PDG_t::kKMinus: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcKaM"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcKaM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - } - if (holderTrack.hasTofPid) { - switch (holderMcParticle.pdgCode) { - case PDG_t::kKPlus: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofKaP"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcTofKaP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - case PDG_t::kKMinus: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofKaM"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcTofKaM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - } - } - } - - if (groupAnalysis.cfgFlagQaPhiPr.value) { - switch (holderMcParticle.pdgCode) { - case PDG_t::kProton: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcPrP"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcPrP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - case PDG_t::kProtonBar: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcPrM"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcPrM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - } - if (holderTrack.hasTofPid) { - switch (holderMcParticle.pdgCode) { - case PDG_t::kProton: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofPrP"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcTofPrP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - case PDG_t::kProtonBar: - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhiMc_mcTpcTofPrM"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderMcParticle.phi); - hrQaPhi.fill(HIST("QaPhi/hCentralityPtEtaPhi_mcTpcTofPrM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phi); - break; - } - } - } + const bool isGood{initTrack(track) && initMcParticle(mcParticle)}; + if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation) && holderTrack.sign != 0) { + ++holderDerivedData.nTracksAll; + } + if (!isGood) { + continue; } - if ((groupAnalysis.cfgFlagQaPidPi.value || groupAnalysis.cfgFlagQaPidKa.value || groupAnalysis.cfgFlagQaPidPr.value) && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary()) && holderTrack.hasTpcPid) { - if (groupAnalysis.cfgFlagQaPidPi.value) { - switch (holderMcParticle.pdgCode) { - case PDG_t::kPiPlus: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaPi_mcPiP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaPi); - if (holderTrack.hasTofPid) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTofNSigmaPi_mcPiP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tofNSigmaPi); - } - break; - case PDG_t::kPiMinus: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaPi_mcPiM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaPi); - if (holderTrack.hasTofPid) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTofNSigmaPi_mcPiM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tofNSigmaPi); - } - break; - } - } - - if (groupAnalysis.cfgFlagQaPidKa.value) { - switch (holderMcParticle.pdgCode) { - case PDG_t::kKPlus: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaKa_mcKaP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaKa); - if (holderTrack.hasTofPid) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTofNSigmaKa_mcKaP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tofNSigmaKa); - } - break; - case PDG_t::kKMinus: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaKa_mcKaM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaKa); - if (holderTrack.hasTofPid) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTofNSigmaKa_mcKaM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tofNSigmaKa); - } - break; - } - } + if (isEnabled(groupAnalysis.cfgFlagQaPhi)) { + fillQaPhiByParticleSpeciesAll(); + fillQaPhiByParticleSpeciesAll(); + fillQaPhiByParticleSpeciesAll(); + fillQaPhiByParticleSpeciesAll(); + } - if (groupAnalysis.cfgFlagQaPidPr.value) { - switch (holderMcParticle.pdgCode) { - case PDG_t::kProton: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaPr_mcPrP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaPr); - if (holderTrack.hasTofPid) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTofNSigmaPr_mcPrP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tofNSigmaPr); - } - break; - case PDG_t::kProtonBar: - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTpcNSigmaPr_mcPrM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tpcNSigmaPr); - if (holderTrack.hasTofPid) { - hrQaPid.fill(HIST("QaPid/hCentralityPtEtaTofNSigmaPr_mcPrM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.tofNSigmaPr); - } - break; - } - } + if (isEnabled(groupAnalysis.cfgFlagQaPid)) { + fillQaPidByParticleSpeciesAll(track); + fillQaPidByParticleSpeciesAll(track); + fillQaPidByParticleSpeciesAll(track); + fillQaPidByParticleSpeciesAll(track); } if (groupAnalysis.cfgFlagQaMc.value && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary())) { - hrQaMc.fill(HIST("QaMc/hCentralityPtEtaDeltaPt"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.pt - holderMcParticle.pt); - hrQaMc.fill(HIST("QaMc/hCentralityPtEtaDeltaEta"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.eta - holderMcParticle.eta); + hrQaMc.fill(C_CS("QaMc/hCentralityPtEtaDeltaPt"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.pt - holderMcParticle.pt); + hrQaMc.fill(C_CS("QaMc/hCentralityPtEtaDeltaEta"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.eta - holderMcParticle.eta); } - if ((groupAnalysis.cfgFlagCalculationYieldPi.value || groupAnalysis.cfgFlagCalculationYieldKa.value || groupAnalysis.cfgFlagCalculationYieldPr.value) && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary()) && holderTrack.hasTpcPid) { - if (groupAnalysis.cfgFlagCalculationYieldPi.value) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - if (holderMcParticle.pdgCode == PDG_t::kPiPlus) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcTpcPiP"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_mcTpcPiP"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - } - break; - case -1: - if (holderMcParticle.pdgCode == PDG_t::kPiMinus) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcTpcPiM"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_mcTpcPiM"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - } - break; - } - if (holderTrack.hasTofPid) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - if (holderMcParticle.pdgCode == PDG_t::kPiPlus) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcTpcTofPiP"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_mcTpcTofPiP"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - } - break; - case -1: - if (holderMcParticle.pdgCode == PDG_t::kPiMinus) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcTpcTofPiM"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_mcTpcTofPiM"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - } - break; - } - } - } - - if (groupAnalysis.cfgFlagCalculationYieldKa.value) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - if (holderMcParticle.pdgCode == PDG_t::kKPlus) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcTpcKaP"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_mcTpcKaP"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - } - break; - case -1: - if (holderMcParticle.pdgCode == PDG_t::kKMinus) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcTpcKaM"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_mcTpcKaM"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - } - break; - } - if (holderTrack.hasTofPid) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - if (holderMcParticle.pdgCode == PDG_t::kKPlus) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcTpcTofKaP"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_mcTpcTofKaP"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - } - break; - case -1: - if (holderMcParticle.pdgCode == PDG_t::kKMinus) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcTpcTofKaM"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_mcTpcTofKaM"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - } - break; - } - } - } - - if (groupAnalysis.cfgFlagCalculationYieldPr.value) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - if (holderMcParticle.pdgCode == PDG_t::kProton) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcTpcPrP"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_mcTpcPrP"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - } - break; - case -1: - if (holderMcParticle.pdgCode == PDG_t::kProtonBar) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcTpcPrM"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_mcTpcPrM"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - } - break; - } - if (holderTrack.hasTofPid) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - if (holderMcParticle.pdgCode == PDG_t::kProton) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcTpcTofPrP"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_mcTpcTofPrP"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - } - break; - case -1: - if (holderMcParticle.pdgCode == PDG_t::kProtonBar) { - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEtaMc_mcTpcTofPrM"), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); - hrCalculationYield.fill(HIST("CalculationYield/hVzCentralityPtEta_mcTpcTofPrM"), holderEvent.vz, holderEvent.centrality, holderTrack.pt, holderTrack.eta); - } - break; - } - } - } + if (isEnabled(groupAnalysis.cfgFlagCalculationYield) && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary())) { + fillCalculationYieldByParticleSpecies(); + fillCalculationYieldByParticleSpecies(); + fillCalculationYieldByParticleSpecies(); } - if ((groupAnalysis.cfgFlagCalculationPurityPi.value || groupAnalysis.cfgFlagCalculationPurityKa.value || groupAnalysis.cfgFlagCalculationPurityPr.value) && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary()) && holderTrack.hasTpcPid) { - if (groupAnalysis.cfgFlagCalculationPurityPi.value) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - hrCalculationPurity.fill(HIST("CalculationPurity/pCentralityPtEtaPurityTpcPiP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderMcParticle.pdgCode == PDG_t::kPiPlus ? 1. : 0.); - break; - case -1: - hrCalculationPurity.fill(HIST("CalculationPurity/pCentralityPtEtaPurityTpcPiM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderMcParticle.pdgCode == PDG_t::kPiMinus ? 1. : 0.); - break; - } - if (holderTrack.hasTofPid) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - hrCalculationPurity.fill(HIST("CalculationPurity/pCentralityPtEtaPurityTpcTofPiP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderMcParticle.pdgCode == PDG_t::kPiPlus ? 1. : 0.); - break; - case -1: - hrCalculationPurity.fill(HIST("CalculationPurity/pCentralityPtEtaPurityTpcTofPiM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderMcParticle.pdgCode == PDG_t::kPiMinus ? 1. : 0.); - break; - } - } - } - - if (groupAnalysis.cfgFlagCalculationPurityKa.value) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - hrCalculationPurity.fill(HIST("CalculationPurity/pCentralityPtEtaPurityTpcKaP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderMcParticle.pdgCode == PDG_t::kKPlus ? 1. : 0.); - break; - case -1: - hrCalculationPurity.fill(HIST("CalculationPurity/pCentralityPtEtaPurityTpcKaM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderMcParticle.pdgCode == PDG_t::kKMinus ? 1. : 0.); - break; - } - if (holderTrack.hasTofPid) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - hrCalculationPurity.fill(HIST("CalculationPurity/pCentralityPtEtaPurityTpcTofKaP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderMcParticle.pdgCode == PDG_t::kKPlus ? 1. : 0.); - break; - case -1: - hrCalculationPurity.fill(HIST("CalculationPurity/pCentralityPtEtaPurityTpcTofKaM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderMcParticle.pdgCode == PDG_t::kKMinus ? 1. : 0.); - break; - } - } - } - - if (groupAnalysis.cfgFlagCalculationPurityPr.value) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - hrCalculationPurity.fill(HIST("CalculationPurity/pCentralityPtEtaPurityTpcPrP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderMcParticle.pdgCode == PDG_t::kProton ? 1. : 0.); - break; - case -1: - hrCalculationPurity.fill(HIST("CalculationPurity/pCentralityPtEtaPurityTpcPrM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderMcParticle.pdgCode == PDG_t::kProtonBar ? 1. : 0.); - break; - } - if (holderTrack.hasTofPid) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - hrCalculationPurity.fill(HIST("CalculationPurity/pCentralityPtEtaPurityTpcTofPrP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderMcParticle.pdgCode == PDG_t::kProton ? 1. : 0.); - break; - case -1: - hrCalculationPurity.fill(HIST("CalculationPurity/pCentralityPtEtaPurityTpcTofPrM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderMcParticle.pdgCode == PDG_t::kProtonBar ? 1. : 0.); - break; - } - } - } + if (isEnabled(groupAnalysis.cfgFlagCalculationPurity) && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary())) { + fillCalculationPurityByParticleSpecies(); + fillCalculationPurityByParticleSpecies(); + fillCalculationPurityByParticleSpecies(); } - if ((groupAnalysis.cfgFlagCalculationFractionPrimaryPi.value || groupAnalysis.cfgFlagCalculationFractionPrimaryKa.value || groupAnalysis.cfgFlagCalculationFractionPrimaryPr.value) && holderTrack.hasTpcPid) { - if (groupAnalysis.cfgFlagCalculationFractionPrimaryPi.value) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - if (holderMcParticle.pdgCode == PDG_t::kPiPlus) { - hrCalculationFractionPrimary.fill(HIST("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcPiP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, mcParticle.isPhysicalPrimary() ? 1. : 0.); - } - break; - case -1: - if (holderMcParticle.pdgCode == PDG_t::kPiMinus) { - hrCalculationFractionPrimary.fill(HIST("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcPiM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, mcParticle.isPhysicalPrimary() ? 1. : 0.); - } - break; - } - if (holderTrack.hasTofPid) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - if (holderMcParticle.pdgCode == PDG_t::kPiPlus) { - hrCalculationFractionPrimary.fill(HIST("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcTofPiP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, mcParticle.isPhysicalPrimary() ? 1. : 0.); - } - break; - case -1: - if (holderMcParticle.pdgCode == PDG_t::kPiMinus) { - hrCalculationFractionPrimary.fill(HIST("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcTofPiM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, mcParticle.isPhysicalPrimary() ? 1. : 0.); - } - break; - } - } - } - - if (groupAnalysis.cfgFlagCalculationFractionPrimaryKa.value) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - if (holderMcParticle.pdgCode == PDG_t::kKPlus) { - hrCalculationFractionPrimary.fill(HIST("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcKaP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, mcParticle.isPhysicalPrimary() ? 1. : 0.); - } - break; - case -1: - if (holderMcParticle.pdgCode == PDG_t::kKMinus) { - hrCalculationFractionPrimary.fill(HIST("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcKaM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, mcParticle.isPhysicalPrimary() ? 1. : 0.); - } - break; - } - if (holderTrack.hasTofPid) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - if (holderMcParticle.pdgCode == PDG_t::kKPlus) { - hrCalculationFractionPrimary.fill(HIST("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcTofKaP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, mcParticle.isPhysicalPrimary() ? 1. : 0.); - } - break; - case -1: - if (holderMcParticle.pdgCode == PDG_t::kKMinus) { - hrCalculationFractionPrimary.fill(HIST("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcTofKaM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, mcParticle.isPhysicalPrimary() ? 1. : 0.); - } - break; - } - } - } - - if (groupAnalysis.cfgFlagCalculationFractionPrimaryPr.value) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - if (holderMcParticle.pdgCode == PDG_t::kProton) { - hrCalculationFractionPrimary.fill(HIST("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcPrP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, mcParticle.isPhysicalPrimary() ? 1. : 0.); - } - break; - case -1: - if (holderMcParticle.pdgCode == PDG_t::kProtonBar) { - hrCalculationFractionPrimary.fill(HIST("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcPrM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, mcParticle.isPhysicalPrimary() ? 1. : 0.); - } - break; - } - if (holderTrack.hasTofPid) { - switch (isPid(groupTrack.cfgFlagRejectionOthers.value)) { - case 1: - if (holderMcParticle.pdgCode == PDG_t::kProton) { - hrCalculationFractionPrimary.fill(HIST("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcTofPrP"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, mcParticle.isPhysicalPrimary() ? 1. : 0.); - } - break; - case -1: - if (holderMcParticle.pdgCode == PDG_t::kProtonBar) { - hrCalculationFractionPrimary.fill(HIST("CalculationFractionPrimary/pCentralityPtEtaFractionPrimaryTpcTofPrM"), holderEvent.centrality, holderTrack.pt, holderTrack.eta, mcParticle.isPhysicalPrimary() ? 1. : 0.); - } - break; - } - } - } + if (isEnabled(groupAnalysis.cfgFlagCalculationFractionPrimary)) { + fillCalculationFractionPrimaryByParticleSpecies(mcParticle); + fillCalculationFractionPrimaryByParticleSpecies(mcParticle); + fillCalculationFractionPrimaryByParticleSpecies(mcParticle); } - if ((groupAnalysis.cfgFlagCalculationFluctuationCh.value || groupAnalysis.cfgFlagCalculationFluctuationKa.value || groupAnalysis.cfgFlagCalculationFluctuationPr.value) && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary())) { - calculateFluctuation(); + if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation) && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary())) { + calculateFluctuationByParticleNumber(); + calculateFluctuationByParticleNumber(); + calculateFluctuationByParticleNumber(); } } - if (groupAnalysis.cfgFlagCalculationFluctuationCh.value) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hCentralityNChPNChM"), holderEvent.centrality, holderEvent.nChP, holderEvent.nChM); - for (std::int32_t const& iOrderVector : std::views::iota(0, static_cast(fluctuation_calculator_base::NOrderVectors))) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorChP"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackChP->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorChM"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackChM->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorChT"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackChT->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorChN"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackChN->getProductFast(iOrderVector)); - } - } - if (groupAnalysis.cfgFlagCalculationFluctuationKa.value) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hCentralityNKaPNKaM"), holderEvent.centrality, holderEvent.nKaP, holderEvent.nKaM); - for (std::int32_t const& iOrderVector : std::views::iota(0, static_cast(fluctuation_calculator_base::NOrderVectors))) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorKaP"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackKaP->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorKaM"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackKaM->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorKaT"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackKaT->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorKaN"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackKaN->getProductFast(iOrderVector)); - } - } - if (groupAnalysis.cfgFlagCalculationFluctuationPr.value) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hCentralityNPrPNPrM"), holderEvent.centrality, holderEvent.nPrP, holderEvent.nPrM); - for (std::int32_t const& iOrderVector : std::views::iota(0, static_cast(fluctuation_calculator_base::NOrderVectors))) { - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorPrP"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackPrP->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorPrM"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackPrM->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorPrT"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackPrT->getProductFast(iOrderVector)); - hrCalculationFluctuation.fill(HIST("CalculationFluctuation/hFluctuationCalculatorPrN"), holderEvent.centrality, holderEvent.subgroupIndex, iOrderVector, fluctuationCalculatorTrackPrN->getProductFast(iOrderVector)); - } + if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + fillCalculationFluctuationByParticleNumber(); + fillCalculationFluctuationByParticleNumber(); + fillCalculationFluctuationByParticleNumber(); + derivedCollision(HolderDerivedData::convertFloor(holderEvent.vz * 10.), HolderDerivedData::convertFloor(holderEvent.centrality * 500.), holderDerivedData.nChargedParticlesAll, holderDerivedData.nChargedParticlesIn, holderDerivedData.nTracksAll, holderDerivedData.nTracksIn); } } + + break; } } PROCESS_SWITCH(PartNumFluc, processMc, "Process MC data", false);