diff --git a/.clang-tidy b/.clang-tidy index 1d933b5937e..f5ae33b609c 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,21 +1,144 @@ +--- +Checks: + # - clang-analyzer-* # enabled by default + # - clang-diagnostic-* # enabled by default + - -clang-diagnostic-unknown-pragmas + - bugprone-* + - -bugprone-assert-side-effect + - -bugprone-bad-signal-to-kill-thread + - -bugprone-bitwise-pointer-cast + - -bugprone-bool-pointer-implicit-conversion + - -bugprone-compare-pointer-to-member-virtual-function + - -bugprone-crtp-constructor-accessibility + - -bugprone-easily-swappable-parameters # Too sensitive + - -bugprone-forwarding-reference-overload + - -bugprone-implicit-widening-of-multiplication-result # Specific cases irrelevant in this repo + - -bugprone-lambda-function-name + - -bugprone-no-escape + - -bugprone-posix-return + - -bugprone-signal-handler + - -bugprone-signed-char-misuse # Specific use cases. Probably very rare. + - -bugprone-spuriously-wake-up-functions + - -bugprone-suspicious-stringview-data-usage # Probably harmless in this repo + - -bugprone-unused-raii + - cppcoreguidelines-avoid-const-or-ref-data-members + - cppcoreguidelines-avoid-goto + - cppcoreguidelines-avoid-non-const-global-variables + - cppcoreguidelines-init-variables + - cppcoreguidelines-macro-usage + - cppcoreguidelines-misleading-capture-default-by-value + - cppcoreguidelines-missing-std-forward + - cppcoreguidelines-prefer-member-initializer + - cppcoreguidelines-pro-bounds-array-to-pointer-decay + - cppcoreguidelines-pro-type-const-cast + - cppcoreguidelines-pro-type-cstyle-cast + - cppcoreguidelines-pro-type-member-init + - cppcoreguidelines-pro-type-reinterpret-cast + - cppcoreguidelines-pro-type-static-cast-downcast + - cppcoreguidelines-pro-type-union-access + - cppcoreguidelines-rvalue-reference-param-not-moved + - cppcoreguidelines-slicing + - cppcoreguidelines-virtual-class-destructor + - google-default-arguments + # - google-explicit-constructor # triggered for O2 columns + - google-global-names-in-headers + # - misc-const-correctness # to be checked + - misc-header-include-cycle + - misc-include-cleaner + - misc-misplaced-const + - misc-redundant-expression + - misc-unconventional-assign-operator + - misc-unused-alias-decls + - misc-unused-parameters + - misc-unused-using-decls + - modernize-avoid-bind + - modernize-avoid-c-arrays + - modernize-concat-nested-namespaces + - modernize-deprecated-headers + - modernize-make-shared + - modernize-make-unique + - modernize-redundant-void-arg + - modernize-return-braced-init-list + - modernize-use-auto + - modernize-use-default-member-init + - modernize-use-designated-initializers + - modernize-use-equals-default + - modernize-use-equals-delete + - modernize-use-nodiscard + - modernize-use-nullptr + - modernize-use-override + - modernize-use-starts-ends-with + - performance-for-range-copy + - performance-implicit-conversion-in-loop + - performance-inefficient-algorithm + - performance-inefficient-string-concatenation + - performance-inefficient-vector-operation + - performance-move-const-arg + - performance-no-automatic-move + - performance-trivially-destructible + - performance-type-promotion-in-math-fn + - performance-unnecessary-copy-initialization + - performance-unnecessary-value-param # slow + - readability-avoid-unconditional-preprocessor-if + - readability-braces-around-statements + - readability-const-return-type + - readability-container-contains + - readability-container-data-pointer + - readability-container-size-empty + - readability-delete-null-pointer + - readability-duplicate-include + - readability-else-after-return + - readability-enum-initial-value + - readability-implicit-bool-conversion + - readability-inconsistent-declaration-parameter-name + - readability-misplaced-array-index + - readability-non-const-parameter + - readability-redundant-access-specifiers + - readability-redundant-casting + - readability-redundant-control-flow + - readability-redundant-declaration + - readability-redundant-member-init + - readability-redundant-preprocessor + - readability-redundant-string-cstr + - readability-redundant-string-init + - readability-reference-to-constructed-temporary + - readability-simplify-boolean-expr + - readability-static-definition-in-anonymous-namespace + - readability-string-compare + - readability-suspicious-call-argument +# Select which of the enabled checks should be reported as errors instead of warnings. +WarningsAsErrors: >- + *, + -readability-braces-around-statements, + -readability-suspicious-call-argument, CheckOptions: + modernize-avoid-c-arrays.AllowStringArrays: true + # Common tolerated conversions + bugprone-narrowing-conversions.WarnOnFloatingPointNarrowingConversion: false + bugprone-narrowing-conversions.WarnOnIntegerNarrowingConversion: false + bugprone-narrowing-conversions.WarnOnIntegerToFloatingPointNarrowingConversion: false + readability-implicit-bool-conversion.AllowLogicalOperatorConversion: true + readability-implicit-bool-conversion.AllowPointerConditions: true + # Some data model structs are missing some special functions by design. + cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions: true # Naming conventions - - { key: readability-identifier-naming.ClassCase, value: CamelCase } - - { key: readability-identifier-naming.ClassMemberPrefix, value: m } - - { key: readability-identifier-naming.ConceptCase, value: CamelCase } - - { key: readability-identifier-naming.ConstexprVariableCase, value: CamelCase } - - { key: readability-identifier-naming.EnumCase, value: CamelCase } - - { key: readability-identifier-naming.EnumConstantCase, value: CamelCase } - - { key: readability-identifier-naming.EnumConstantIgnoredRegexp, value: "^k?[A-Z][a-zA-Z0-9_]*$" } # Allow "k" prefix and non-trailing underscores in PDG names. - - { key: readability-identifier-naming.FunctionCase, value: camelBack } - - { key: readability-identifier-naming.MacroDefinitionCase, value: UPPER_CASE } - - { key: readability-identifier-naming.MacroDefinitionIgnoredRegexp, value: "^[A-Z][A-Z0-9_]*_$" } # Allow the trailing underscore in header guards. - - { key: readability-identifier-naming.MemberCase, value: camelBack } - - { key: readability-identifier-naming.NamespaceCase, value: lower_case } - - { key: readability-identifier-naming.ParameterCase, value: camelBack } - - { key: readability-identifier-naming.StructCase, value: CamelCase } - - { key: readability-identifier-naming.TemplateParameterCase, value: CamelCase } - - { key: readability-identifier-naming.TypeAliasCase, value: CamelCase } - - { key: readability-identifier-naming.TypedefCase, value: CamelCase } - - { key: readability-identifier-naming.TypeTemplateParameterCase, value: CamelCase } - - { key: readability-identifier-naming.VariableCase, value: camelBack } + readability-identifier-naming.ClassCase: CamelCase + readability-identifier-naming.ClassMemberPrefix: m + readability-identifier-naming.ConceptCase: CamelCase + readability-identifier-naming.ConstexprVariableCase: CamelCase + readability-identifier-naming.EnumCase: CamelCase + readability-identifier-naming.EnumConstantCase: CamelCase + readability-identifier-naming.EnumConstantIgnoredRegexp: "^k?[A-Z][a-zA-Z0-9_]*$" # Allow "k" prefix and non-trailing underscores in PDG names. + readability-identifier-naming.FunctionCase: camelBack + readability-identifier-naming.MacroDefinitionCase: UPPER_CASE + readability-identifier-naming.MacroDefinitionIgnoredRegexp: "^[A-Z][A-Z0-9_]*_$" # Allow the trailing underscore in header guards. + readability-identifier-naming.MemberCase: camelBack + readability-identifier-naming.NamespaceCase: lower_case + readability-identifier-naming.ParameterCase: camelBack + readability-identifier-naming.StructCase: CamelCase + readability-identifier-naming.TemplateParameterCase: CamelCase + readability-identifier-naming.TypeAliasCase: CamelCase + readability-identifier-naming.TypedefCase: CamelCase + readability-identifier-naming.TypeTemplateParameterCase: CamelCase + readability-identifier-naming.VariableCase: camelBack +... diff --git a/.github/workflows/mega-linter.yml b/.github/workflows/mega-linter.yml index a52b7b6f404..edaee8c9344 100644 --- a/.github/workflows/mega-linter.yml +++ b/.github/workflows/mega-linter.yml @@ -23,7 +23,7 @@ jobs: steps: # Git Checkout - name: Checkout Code - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: # Checkout the HEAD of the PR instead of the merge commit. ref: ${{ github.event.pull_request.head.sha }} @@ -32,13 +32,14 @@ jobs: fetch-depth: 0 # So we can use secrets.ALIBUILD_GITHUB_TOKEN to push later. persist-credentials: false + allow-unsafe-pr-checkout: true # needed for pull_request_target # MegaLinter - name: MegaLinter id: ml # You can override MegaLinter flavor used to have faster performances # More info at https://megalinter.io/flavors/ - uses: oxsecurity/megalinter@v9.5.0 + uses: oxsecurity/megalinter@v9.6.0 env: # All available variables are described in documentation: # https://megalinter.io/configuration/ diff --git a/.github/workflows/o2-linter.yml b/.github/workflows/o2-linter.yml index f5a1b39a950..1af5915fa89 100644 --- a/.github/workflows/o2-linter.yml +++ b/.github/workflows/o2-linter.yml @@ -30,10 +30,11 @@ jobs: echo BRANCH_HEAD="$branch_head" >> "$GITHUB_ENV" echo BRANCH_BASE="$branch_base" >> "$GITHUB_ENV" - name: Checkout Code - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: ref: ${{ env.BRANCH_HEAD }} fetch-depth: 0 # needed to get the full history + allow-unsafe-pr-checkout: true # needed for pull_request_target - name: Run tests id: linter run: | diff --git a/.mega-linter.yml b/.mega-linter.yml index befd6badf61..978f7cd0c22 100644 --- a/.mega-linter.yml +++ b/.mega-linter.yml @@ -42,6 +42,6 @@ PYTHON_RUFF_CONFIG_FILE: pyproject.toml CPP_CPPLINT_FILE_EXTENSIONS: [".C", ".c", ".c++", ".cc", ".cl", ".cpp", ".cu", ".cuh", ".cxx", ".cxx.in", ".h", ".h++", ".hh", ".h.in", ".hpp", ".hxx", ".inc", ".inl", ".macro"] CPP_CLANG_FORMAT_FILE_EXTENSIONS: [".C", ".c", ".c++", ".cc", ".cl", ".cpp", ".cu", ".cuh", ".cxx", ".cxx.in", ".h", ".h++", ".hh", ".h.in", ".hpp", ".hxx", ".inc", ".inl", ".macro"] CPP_CPPCHECK_FILE_EXTENSIONS: [".C", ".c", ".c++", ".cc", ".cl", ".cpp", ".cu", ".cuh", ".cxx", ".cxx.in", ".h", ".h++", ".hh", ".h.in", ".hpp", ".hxx", ".inc", ".inl", ".macro"] -CPP_CPPCHECK_ARGUMENTS: --language=c++ --std=c++20 --check-level=exhaustive --suppressions-list=cppcheck_config +CPP_CPPCHECK_ARGUMENTS: --language=c++ --std=c++20 --enable=style --check-level=exhaustive --suppressions-list=cppcheck_suppressions --inline-suppr --force REPOSITORY_GITLEAKS_PR_COMMITS_SCAN: true ACTION_ZIZMOR_UNSECURED_ENV_VARIABLES: [GITHUB_TOKEN] diff --git a/ALICE3/Core/OTFParticle.h b/ALICE3/Core/OTFParticle.h index 9f93ea59597..95c6c78c492 100644 --- a/ALICE3/Core/OTFParticle.h +++ b/ALICE3/Core/OTFParticle.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -58,6 +59,9 @@ class OTFParticle if (particle.has_mothers()) { mIndicesMother = {particle.mothersIds().front(), particle.mothersIds().back()}; } + if (particle.has_daughters()) { + mIndicesDaughter = {particle.daughtersIds().front(), particle.daughtersIds().back()}; + } if constexpr (requires { particle.decayerBits(); }) { mBits = particle.decayerBits(); } else { @@ -88,6 +92,14 @@ class OTFParticle mPz = pz; mE = e; } + void setIndexOffset(const std::size_t offset) + { + static constexpr int NotFound = -1; + mIndicesMother[0] = (mIndicesMother[0] >= 0) ? mIndicesMother[0] + static_cast(offset) : NotFound; + mIndicesMother[1] = (mIndicesMother[1] >= 0) ? mIndicesMother[1] + static_cast(offset) : NotFound; + mIndicesDaughter[0] = (mIndicesDaughter[0] >= 0) ? mIndicesDaughter[0] + static_cast(offset) : NotFound; + mIndicesDaughter[1] = (mIndicesDaughter[1] >= 0) ? mIndicesDaughter[1] + static_cast(offset) : NotFound; + } // Getters int pdgCode() const { return mPdgCode; } @@ -147,8 +159,8 @@ class OTFParticle std::span getMotherSpan() const { return hasMothers() ? std::span(mIndicesMother.data(), 2) : std::span(); } // Checks - bool hasDaughters() const { return (mIndicesDaughter[0] > 0); } - bool hasMothers() const { return (mIndicesMother[0] > 0); } + bool hasDaughters() const { return (mIndicesDaughter[0] >= 0); } + bool hasMothers() const { return (mIndicesMother[0] >= 0); } bool hasNaN() const { return std::isnan(mPx) || std::isnan(mPy) || std::isnan(mPz) || std::isnan(mE) || @@ -171,7 +183,7 @@ class OTFParticle private: int mPdgCode{}, mGlobalIndex{-1}; - int mCollisionId{}; + int mCollisionId{-1}; float mVx{}, mVy{}, mVz{}, mVt{}; float mPx{}, mPy{}, mPz{}, mE{}; bool mIsAlive{}, mIsFromMcParticles{false}; diff --git a/ALICE3/Core/TrackUtilities.cxx b/ALICE3/Core/TrackUtilities.cxx index 86b41e6245c..0b4d1dc08f7 100644 --- a/ALICE3/Core/TrackUtilities.cxx +++ b/ALICE3/Core/TrackUtilities.cxx @@ -29,13 +29,13 @@ #include void o2::upgrade::convertTLorentzVectorToO2Track(const int charge, - const TLorentzVector particle, - const std::vector productionVertex, + const TLorentzVector& particle, + const std::vector& productionVertex, o2::track::TrackParCov& o2track) { - std::array params; + std::array params = {0.}; std::array covm = {0.}; - float s, c, x; + float s{}, c{}, x{}; o2::math_utils::sincos(static_cast(particle.Phi()), s, c); o2::math_utils::rotateZInv(static_cast(productionVertex[0]), static_cast(productionVertex[1]), x, params[0], s, c); params[1] = static_cast(productionVertex[2]); @@ -48,20 +48,20 @@ void o2::upgrade::convertTLorentzVectorToO2Track(const int charge, new (&o2track)(o2::track::TrackParCov)(x, particle.Phi(), params, covm); } -float o2::upgrade::computeParticleVelocity(float momentum, float mass) +float o2::upgrade::computeParticleVelocity(const float momentum, const float mass) { const float a = momentum / mass; // uses light speed in cm/ps so output is in those units return o2::constants::physics::LightSpeedCm2PS * a / std::sqrt((1.f + a * a)); } -float o2::upgrade::computeTrackLength(o2::track::TrackParCov track, float radius, float magneticField) +float o2::upgrade::computeTrackLength(const o2::track::TrackParCov& track, const float radius, const float magneticField) { // don't make use of the track parametrization float length = -100; o2::math_utils::CircleXYf_t trcCircle; - float sna, csa; + float sna{}, csa{}; track.getCircleParams(magneticField, trcCircle, sna, csa); // distance between circle centers (one circle is at origin -> easy) @@ -69,8 +69,6 @@ float o2::upgrade::computeTrackLength(o2::track::TrackParCov track, float radius // condition of circles touching - if not satisfied returned length will be -100 if (centerDistance < trcCircle.rC + radius && centerDistance > std::fabs(trcCircle.rC - radius)) { - length = 0.0f; - // base radical direction const float ux = trcCircle.xC / centerDistance; const float uy = trcCircle.yC / centerDistance; @@ -87,17 +85,17 @@ float o2::upgrade::computeTrackLength(o2::track::TrackParCov track, float radius (centerDistance + trcCircle.rC + radius)); // possible intercept points of track and TOF layer in 2D plane - const float point1[2] = {radical * ux + displace * vx, radical * uy + displace * vy}; - const float point2[2] = {radical * ux - displace * vx, radical * uy - displace * vy}; + const std::array point1 = {radical * ux + displace * vx, radical * uy + displace * vy}; + const std::array point2 = {radical * ux - displace * vx, radical * uy - displace * vy}; // decide on correct intercept point - std::array mom; + std::array mom{}; track.getPxPyPzGlo(mom); const float scalarProduct1 = point1[0] * mom[0] + point1[1] * mom[1]; const float scalarProduct2 = point2[0] * mom[0] + point2[1] * mom[1]; // get start point - std::array startPoint; + std::array startPoint{}; track.getXYZGlo(startPoint); float cosAngle = -1000, modulus = -1000; diff --git a/ALICE3/Core/TrackUtilities.h b/ALICE3/Core/TrackUtilities.h index 0cdcc5da92b..f591cd05d0f 100644 --- a/ALICE3/Core/TrackUtilities.h +++ b/ALICE3/Core/TrackUtilities.h @@ -36,8 +36,8 @@ namespace o2::upgrade /// \param productionVertex where the particle was produced /// \param o2track the address of the resulting TrackParCov void convertTLorentzVectorToO2Track(const int charge, - const TLorentzVector particle, - const std::vector productionVertex, + const TLorentzVector& particle, + const std::vector& productionVertex, o2::track::TrackParCov& o2track); /// Function to convert a TLorentzVector into a perfect Track @@ -47,9 +47,9 @@ void convertTLorentzVectorToO2Track(const int charge, /// \param o2track the address of the resulting TrackParCov /// \param pdg the pdg service template -void convertTLorentzVectorToO2Track(int pdgCode, - TLorentzVector particle, - std::vector productionVertex, +void convertTLorentzVectorToO2Track(const int pdgCode, + const TLorentzVector& particle, + const std::vector& productionVertex, o2::track::TrackParCov& o2track, const PdgService& pdg) { @@ -80,7 +80,7 @@ void convertOTFParticleToO2Track(const OTFParticle& particle, /// \param o2track the address of the resulting TrackParCov /// \param pdg the pdg service template -void convertMCParticleToO2Track(McParticleType& particle, +void convertMCParticleToO2Track(const McParticleType& particle, o2::track::TrackParCov& o2track, const PdgService& pdg) { @@ -94,7 +94,7 @@ void convertMCParticleToO2Track(McParticleType& particle, /// \param o2track the address of the resulting TrackParCov /// \param pdg the pdg service template -o2::track::TrackParCov convertMCParticleToO2Track(McParticleType& particle, +o2::track::TrackParCov convertMCParticleToO2Track(const McParticleType& particle, const PdgService& pdg) { o2::track::TrackParCov o2track; @@ -105,13 +105,13 @@ o2::track::TrackParCov convertMCParticleToO2Track(McParticleType& particle, /// returns velocity in centimeters per picoseconds /// \param momentum the momentum of the track /// \param mass the mass of the particle -float computeParticleVelocity(float momentum, float mass); +float computeParticleVelocity(const float momentum, const float mass); /// function to calculate track length of this track up to a certain radius /// \param track the input track (TrackParCov) /// \param radius the radius of the layer you're calculating the length to /// \param magneticField the magnetic field to use when propagating -float computeTrackLength(o2::track::TrackParCov track, float radius, float magneticField); +float computeTrackLength(const o2::track::TrackParCov& track, const float radius, const float magneticField); } // namespace o2::upgrade diff --git a/ALICE3/DataModel/OTFStrangeness.h b/ALICE3/DataModel/OTFStrangeness.h index 395f1ab8681..03f180bb0ff 100644 --- a/ALICE3/DataModel/OTFStrangeness.h +++ b/ALICE3/DataModel/OTFStrangeness.h @@ -37,6 +37,8 @@ DECLARE_SOA_INDEX_COLUMN_FULL(PosTrack, posTrack, int, Tracks, "_Pos"); DECLARE_SOA_INDEX_COLUMN_FULL(NegTrack, negTrack, int, Tracks, "_Neg"); //! DECLARE_SOA_INDEX_COLUMN_FULL(BachTrack, bachTrack, int, Tracks, "_Bach"); //! +DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); + // topo vars DECLARE_SOA_COLUMN(DcaV0Daughters, dcaV0Daughters, float); DECLARE_SOA_COLUMN(DcaCascadeDaughters, dcaCascadeDaughters, float); @@ -70,6 +72,9 @@ DECLARE_SOA_TABLE(UpgradeCascades, "AOD", "UPGRADECASCADES", using UpgradeCascade = UpgradeCascades::iterator; +DECLARE_SOA_TABLE(A3CascadeMcLabels, "AOD", "A3CASCADEMCLABELS", + o2::soa::Index<>, otfcascade::McParticleId); + namespace otfv0 { DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! diff --git a/ALICE3/DataModel/prefilterDilepton.h b/ALICE3/DataModel/prefilterDilepton.h new file mode 100644 index 00000000000..9008231a0ed --- /dev/null +++ b/ALICE3/DataModel/prefilterDilepton.h @@ -0,0 +1,41 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \file collisionExtra.h +/// \author David Dobrigkeit Chinellato +/// \since 11/05/2023 +/// \brief Table for ALICE 3 collision-related info +/// + +#ifndef ALICE3_DATAMODEL_PREFILTERDILEPTON_H_ +#define ALICE3_DATAMODEL_PREFILTERDILEPTON_H_ + +// O2 includes +#include + +namespace o2::aod +{ + +namespace dileptonanalysisflags +{ +// DECLARE_SOA_COLUMN(IsMCEventSelected, isMCEventSelected, int); +DECLARE_SOA_COLUMN(IsEventCentSelected, isEventCentSelected, int); +DECLARE_SOA_COLUMN(IsTrackPrefilter, isTrackPrefilter, int); +} // namespace dileptonanalysisflags + +// DECLARE_SOA_TABLE(EventMCCuts, "AOD", "EVENTMCCUTS", emanalysisflags::IsMCEventSelected); +DECLARE_SOA_TABLE(DiEventCentCuts, "AOD", "DIEVENTCENTCUTS", dileptonanalysisflags::IsEventCentSelected); +DECLARE_SOA_TABLE(DiTrackPrefilter, "AOD", "DITRACKPREFILTER", dileptonanalysisflags::IsTrackPrefilter); + +} // namespace o2::aod + +#endif // ALICE3_DATAMODEL_PREFILTERDILEPTON_H_ diff --git a/ALICE3/TableProducer/OTF/onTheFlyDecayer.cxx b/ALICE3/TableProducer/OTF/onTheFlyDecayer.cxx index b568364b80c..a1c62ae29b9 100644 --- a/ALICE3/TableProducer/OTF/onTheFlyDecayer.cxx +++ b/ALICE3/TableProducer/OTF/onTheFlyDecayer.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -49,8 +50,8 @@ using namespace o2::framework; static constexpr int NumDecays = 7; static constexpr int NumParameters = 1; static constexpr int DefaultParameters[NumDecays][NumParameters]{{1}, {1}, {1}, {1}, {1}, {1}, {1}}; -static const std::vector ParameterNames{"enable"}; -static const std::vector ParticleNames{"K0s", +static const std::vector parameterNames{"enable"}; +static const std::vector particleNames{"K0s", "Lambda", "Anti-Lambda", "Xi", @@ -83,12 +84,12 @@ struct OnTheFlyDecayer { Configurable seed{"seed", 0, "Set seed for particle decayer"}; Configurable magneticField{"magneticField", 20., "Magnetic field (kG)"}; Configurable> enabledDecays{"enabledDecays", - {DefaultParameters[0], NumDecays, NumParameters, ParticleNames, ParameterNames}, + {DefaultParameters[0], NumDecays, NumParameters, particleNames, parameterNames}, "Enable option for particle to be decayed: 0 - no, 1 - yes"}; + std::size_t indexOffset = 0; + std::size_t particlesInDataframe = 0; static constexpr float PicoToNano = 1.e-3f; - int mCollisionId{-1}; - std::vector mEnabledDecays; void init(o2::framework::InitContext&) { @@ -98,7 +99,7 @@ struct OnTheFlyDecayer { decayer.setSeed(seed); decayer.setBField(magneticField); for (int i = 0; i < NumDecays; ++i) { - if (enabledDecays->get(ParticleNames[i].c_str(), "enable")) { + if (enabledDecays->get(particleNames[i].c_str(), "enable")) { LOG(info) << " --- Decay enabled: " << pdgCodes[i]; mEnabledDecays.push_back(pdgCodes[i]); } @@ -121,6 +122,10 @@ struct OnTheFlyDecayer { std::vector allParticles; void decayParticles(const int start, const int stop) { + if (start >= stop) { + return; + } + int ndau = 0; for (int i = start; i < stop; ++i) { o2::upgrade::OTFParticle& particle = allParticles[i]; @@ -135,6 +140,10 @@ struct OnTheFlyDecayer { particle.setBitOff(o2::upgrade::DecayerBits::IsAlive); std::vector decayStack = decayer.decayParticle(pdgDB, particle); + if (decayStack.empty()) { + continue; + } + const float decayRadius = decayer.getDecayRadius(); const float trackVelocity = o2::upgrade::computeParticleVelocity(particle.p(), pdgDB->GetParticle(particle.pdgCode())->Mass()); const int charge = pdgDB->GetParticle(particle.pdgCode())->Charge() / 3; @@ -151,20 +160,16 @@ struct OnTheFlyDecayer { } const float trackTimeNS = trackLength / trackVelocity * PicoToNano; - particle.setIndicesDaughter(allParticles.size(), allParticles.size() + (decayStack.size() - 1)); - for (o2::upgrade::OTFParticle daughter : decayStack) { - daughter.setIndicesMother(i, i); - daughter.setCollisionId(mCollisionId); + particle.setIndicesDaughter(particlesInDataframe - indexOffset + allParticles.size(), particlesInDataframe - indexOffset + allParticles.size() + (decayStack.size() - 1)); + for (auto& daughter : decayStack) { + daughter.setIndicesMother(particlesInDataframe - indexOffset + i, particlesInDataframe - indexOffset + i); + daughter.setCollisionId(particle.collisionId()); daughter.setBitOn(o2::upgrade::DecayerBits::IsAlive); daughter.setBitOff(o2::upgrade::DecayerBits::IsPrimary); - daughter.setProductionTime(trackTimeNS); + daughter.setProductionTime(particle.vt() + trackTimeNS); allParticles.push_back(daughter); - ndau++; } - } - - if (start >= stop) { - return; + ndau += decayStack.size(); } decayParticles(stop, stop + ndau); @@ -173,18 +178,16 @@ struct OnTheFlyDecayer { void process(aod::McCollisions_001From>::iterator const& collision, aod::McParticles_001From> const& mcParticles) { allParticles.clear(); + allParticles.reserve(mcParticles.size() * 2); + if (collision.globalIndex() == 0) { + particlesInDataframe = 0; + indexOffset = 0; + } // Reproduce collision table to have AOD origin - mCollisionId = collision.globalIndex(); - tableMcCollisions(collision.bcId(), - collision.generatorsID(), - collision.posX(), - collision.posY(), - collision.posZ(), - collision.t(), - collision.weight(), - collision.impactParameter(), - collision.eventPlaneAngle()); + tableMcCollisions(collision.bcId(), collision.generatorsID(), + collision.posX(), collision.posY(), collision.posZ(), collision.t(), + collision.weight(), collision.impactParameter(), collision.eventPlaneAngle()); // First we copy the particles from the table into a vector that is extendable for (const auto& particle : mcParticles) { @@ -195,7 +198,8 @@ struct OnTheFlyDecayer { decayParticles(0, allParticles.size()); // Fill output table - for (const auto& otfParticle : allParticles) { + for (auto& otfParticle : allParticles) { + otfParticle.setIndexOffset(indexOffset); if (otfParticle.hasNaN()) { histos.fill(HIST("hNaNBookkeeping"), 1); } else { @@ -203,11 +207,17 @@ struct OnTheFlyDecayer { } tableOTFDecayerBits(otfParticle.getBitsValue()); - tableMcParticles(otfParticle.collisionId(), otfParticle.pdgCode(), otfParticle.statusCode(), otfParticle.flags(), + tableMcParticles(tableMcCollisions.lastIndex(), otfParticle.pdgCode(), otfParticle.statusCode(), otfParticle.flags(), otfParticle.getMotherSpan(), otfParticle.getDaughters().data(), otfParticle.weight(), otfParticle.px(), otfParticle.py(), otfParticle.pz(), otfParticle.e(), otfParticle.vx(), otfParticle.vy(), otfParticle.vz(), otfParticle.vt()); } + + // Particles for later collisions in df's needs to have thier mother + // and daughter indices adjusted since their global index will be + // shifted due to the appending of decay products + indexOffset += (allParticles.size() - mcParticles.size()); + particlesInDataframe += allParticles.size(); } }; diff --git a/ALICE3/TableProducer/alice3MulticharmFinder.cxx b/ALICE3/TableProducer/alice3MulticharmFinder.cxx index fd4a7a47881..6b7d98f64a5 100644 --- a/ALICE3/TableProducer/alice3MulticharmFinder.cxx +++ b/ALICE3/TableProducer/alice3MulticharmFinder.cxx @@ -216,10 +216,6 @@ struct Alice3MulticharmFinder { std::array prong0mom; std::array prong1mom; std::array parentTrackCovMatrix; - - // charm daughters - int nSiliconHitsPiCC; - int nTPCHitsPiCC; } thisXiccCandidate; struct ProngInfo { @@ -714,7 +710,7 @@ struct Alice3MulticharmFinder { o2::track::TrackParCov xicTrack(thisXicCandidate.xyz, momentumC, thisXicCandidate.parentTrackCovMatrix, +1); float xicDecayRadius2D = std::hypot(thisXicCandidate.xyz[0], thisXicCandidate.xyz[1]); - if (xicDecayRadius2D < xiccMinDecayRadius) { + if (xicDecayRadius2D < xicMinDecayRadius) { continue; // do not take if radius too small, likely a primary combination } diff --git a/ALICE3/TableProducer/alice3strangenessFinder.cxx b/ALICE3/TableProducer/alice3strangenessFinder.cxx index 3599bc12d97..9b455a72382 100644 --- a/ALICE3/TableProducer/alice3strangenessFinder.cxx +++ b/ALICE3/TableProducer/alice3strangenessFinder.cxx @@ -74,33 +74,23 @@ struct Alice3strangenessFinder { HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - Produces v0CandidateIndices; // contains V0 candidate indices - Produces v0CandidateCores; // contains V0 candidate core information - Produces tableCascadeCores; - Produces tableCascadeIndices; + Produces v0CandidateIndices; // contains V0 candidate indices + Produces v0CandidateCores; // contains V0 candidate core information + Produces tableStoredCascCores; // contains stored cascade core information + Produces tableA3CascadeMcLabels; // contains cascade core MC labels + Produces tableCascIndices; // contains cascade indices Configurable buildCascade{"buildCascade", false, "build cascade candidates"}; - Configurable nSigmaTOF{"nSigmaTOF", 5.0f, "Nsigma for TOF PID (if enabled)"}; - Configurable dcaXYconstant{"dcaXYconstant", -1.0f, "[0] in |DCAxy| > [0]+[1]/pT"}; - Configurable dcaXYpTdep{"dcaXYpTdep", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; ConfigurableAxis axisK0Mass{"axisK0Mass", {200, 0.4f, 0.6f}, "K0 mass axis"}; ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.101f, 1.131f}, "Lambda mass axis"}; ConfigurableAxis axisXiMass{"axisXiMass", {200, 1.22f, 1.42f}, "Xi mass axis"}; - ConfigurableAxis axisMassOmega{"axisMassOmega", {200, 1.57f, 1.77f}, "Omega mass axis"}; + ConfigurableAxis axisOmegaMass{"axisOmegaMass", {200, 1.57f, 1.77f}, "Omega mass axis"}; ConfigurableAxis axisEta{"axisEta", {80, -4.f, 4.f}, "Eta axis"}; ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.025f, 0.05f, 0.075f, 0.1f, 0.125f, 0.15f, 0.175f, 0.2f, 0.225f, 0.25f, 0.275f, 0.3f, 0.325f, 0.35f, 0.375f, 0.4f, 0.425f, 0.45f, 0.475f, 0.5f, 0.525f, 0.55f, 0.575f, 0.6f, 0.625f, 0.65f, 0.675f, 0.7f, 0.725f, 0.75f, 0.775f, 0.8f, 0.82f, 0.85f, 0.875f, 0.9f, 0.925f, 0.95f, 0.975f, 1.0f, 1.05f, 1.1f}, "pt axis for QA histograms"}; - Configurable bachMinConstDCAxy{"bachMinConstDCAxy", -1.0f, "[0] in |DCAxy| > [0]+[1]/pT"}; - Configurable bachMinPtDepDCAxy{"bachMinPtDepDCAxy", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; - Configurable bachMinConstDCAz{"bachMinConstDCAz", -1.0f, "[0] in |DCAz| > [0]+[1]/pT"}; - Configurable bachMinPtDepDCAz{"bachMinPtDepDCAz", 0.0, "[1] in |DCAz| > [0]+[1]/pT"}; - - Configurable v0MaxDauDCA{"v0MaxDauDCA", 0.005f, "DCA between v0 daughters (cm)"}; - Configurable cascMaxDauDCA{"cascMaxDauDCA", 0.005f, "DCA between cascade daughters (cm)"}; - // DCA Fitter struct : ConfigurableGroup { std::string prefix = "cfgFitter"; @@ -123,7 +113,23 @@ struct Alice3strangenessFinder { Configurable maxIter{"maxIter", 30, "maximum number of iterations for vertex fitter"}; } cfgFitter; - Configurable acceptedLambdaMassWindow{"acceptedLambdaMassWindow", 0.2f, "accepted Lambda mass window around PDG mass"}; + // Pre-selections + struct : ConfigurableGroup { + std::string prefix = "presel"; + Configurable acceptedLambdaMassWindow{"acceptedLambdaMassWindow", 0.2f, "accepted Lambda mass window around PDG mass"}; + + Configurable posMinConstDCAxy{"posMinConstDCAxy", -1.0f, "[0] in |DCAxy| > [0]+[1]/pT"}; + Configurable posMinPtDepDCAxy{"posMinPtDepDCAxy", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; + + Configurable negMinConstDCAxy{"negMinConstDCAxy", -1.0f, "[0] in |DCAxy| > [0]+[1]/pT"}; + Configurable negMinPtDepDCAxy{"negMinPtDepDCAxy", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; + + Configurable bachMinConstDCAxy{"bachMinConstDCAxy", -1.0f, "[0] in |DCAxy| > [0]+[1]/pT"}; + Configurable bachMinPtDepDCAxy{"bachMinPtDepDCAxy", 0.0, "[1] in |DCAxy| > [0]+[1]/pT"}; + + Configurable v0MaxDauDCA{"v0MaxDauDCA", 0.005f, "DCA between v0 daughters (cm)"}; + Configurable cascMaxDauDCA{"cascMaxDauDCA", 0.005f, "DCA between cascade daughters (cm)"}; + } presel; // Operation Configurable magneticField{"magneticField", 20.0f, "Magnetic field (in kilogauss)"}; @@ -136,24 +142,22 @@ struct Alice3strangenessFinder { Configurable useOriginalTrackParams{"useOriginalTrackParams", false, "use original track parameters instead of the ones propagated to PCA (effective only if skipFitter is false) and for MC truth info"}; o2::vertexing::DCAFitterN<2> fitter; - o2::vertexing::DCAFitterN<3> fitter3; - Service pdgDB; // partitions for v0/casc dau tracks Partition positiveSecondaryTracksACTS = - aod::track::signed1Pt > 0.0f && nabs(aod::track::dcaXY) > dcaXYconstant + dcaXYpTdep* nabs(aod::track::signed1Pt); + aod::track::signed1Pt > 0.0f && nabs(aod::track::dcaXY) > presel.posMinConstDCAxy + presel.posMinPtDepDCAxy* nabs(aod::track::signed1Pt); Partition negativeSecondaryTracksACTS = - aod::track::signed1Pt < 0.0f && nabs(aod::track::dcaXY) > dcaXYconstant + dcaXYpTdep* nabs(aod::track::signed1Pt); + aod::track::signed1Pt < 0.0f && nabs(aod::track::dcaXY) > presel.negMinConstDCAxy + presel.negMinPtDepDCAxy* nabs(aod::track::signed1Pt); Partition bachelorTracksACTS = - nabs(aod::track::dcaXY) > bachMinConstDCAxy + bachMinPtDepDCAxy* nabs(aod::track::signed1Pt) && nabs(aod::track::dcaZ) > bachMinConstDCAz + bachMinPtDepDCAz* nabs(aod::track::signed1Pt); + nabs(aod::track::dcaXY) > presel.bachMinConstDCAxy + presel.bachMinPtDepDCAxy* nabs(aod::track::signed1Pt); Partition positiveSecondaryTracksOTF = - aod::track::signed1Pt > 0.0f && nabs(aod::track::dcaXY) > dcaXYconstant + dcaXYpTdep* nabs(aod::track::signed1Pt); + aod::track::signed1Pt > 0.0f && nabs(aod::track::dcaXY) > presel.posMinConstDCAxy + presel.posMinPtDepDCAxy* nabs(aod::track::signed1Pt); Partition negativeSecondaryTracksOTF = - aod::track::signed1Pt < 0.0f && nabs(aod::track::dcaXY) > dcaXYconstant + dcaXYpTdep* nabs(aod::track::signed1Pt); + aod::track::signed1Pt < 0.0f && nabs(aod::track::dcaXY) > presel.negMinConstDCAxy + presel.negMinPtDepDCAxy* nabs(aod::track::signed1Pt); Partition bachelorTracksOTF = - nabs(aod::track::dcaXY) > bachMinConstDCAxy + bachMinPtDepDCAxy* nabs(aod::track::signed1Pt) && nabs(aod::track::dcaZ) > bachMinConstDCAz + bachMinPtDepDCAz* nabs(aod::track::signed1Pt); + nabs(aod::track::dcaXY) > presel.bachMinConstDCAxy + presel.bachMinPtDepDCAxy* nabs(aod::track::signed1Pt); Partition positiveMCParticles = aod::mcparticle_alice3::charge > 0.0f; Partition negativeMCParticles = aod::mcparticle_alice3::charge < 0.0f; @@ -172,6 +176,7 @@ struct Alice3strangenessFinder { // Partition secondaryAntiProtons = nabs(aod::upgrade_tof::nSigmaProtonInnerTOF) < nSigmaTOF && nabs(aod::upgrade_tof::nSigmaProtonOuterTOF) < nSigmaTOF && aod::track::signed1Pt < 0.0f && nabs(aod::track::dcaXY) > dcaXYconstant + dcaXYpTdep* nabs(aod::track::signed1Pt); struct Candidate { + int index{-1}; // decay properties float dcaDau{}; float eta{}; @@ -202,7 +207,12 @@ struct Alice3strangenessFinder { fitter.setMaxIter(cfgFitter.maxIter); fitter.setMatCorrType(o2::base::Propagator::MatCorrType::USEMatCorrNONE); - histos.add("hFitterQA", "", kTH1D, {{10, 0, 10}}); // For QA reasons, counting found candidates at different stages + auto hFitterQA = histos.add("hFitterQA", "hFitterQA", kTH1D, {{10, 0, 10}}); + hFitterQA->GetXaxis()->SetBinLabel(1, "All"); // all fitter attempts + hFitterQA->GetXaxis()->SetBinLabel(2, "Processed"); // attempts that made the fitter.process() call + hFitterQA->GetXaxis()->SetBinLabel(3, "Found cands"); // nCand == 0 + hFitterQA->GetXaxis()->SetBinLabel(4, "Done"); // checks isPropagateTracksToVertexDone() + auto hFitterStatusCode = histos.add("hFitterStatusCode", "hFitterStatusCode", kTH1D, {{15, -0.5, 14.5}}); hFitterStatusCode->GetXaxis()->SetBinLabel(1, "None"); // no status set (should not be possible!) @@ -238,6 +248,9 @@ struct Alice3strangenessFinder { histos.add("hRadiusVsHitsNeg", "", kTH2D, {{400, 0, 400}, {12, 0.5, 12.5}}); // radius vs hist for MC studies histos.add("hRadiusVsHitsPos", "", kTH2D, {{400, 0, 400}, {12, 0.5, 12.5}}); // radius vs hist for MC studies + histos.add("hXiMass", "", kTH1D, {axisXiMass}); + histos.add("hOmegaMass", "", kTH1D, {axisOmegaMass}); + auto hV0Building = histos.add("hV0Building", "hV0Building", kTH1D, {{10, 0.5, 10.5}}); hV0Building->GetXaxis()->SetBinLabel(1, "Pair"); hV0Building->GetXaxis()->SetBinLabel(2, "Pdg check"); @@ -246,16 +259,17 @@ struct Alice3strangenessFinder { auto hCascadeBuilding = histos.add("hCascadeBuilding", "hCascadeBuilding", kTH1D, {{10, 0.5, 10.5}}); hCascadeBuilding->GetXaxis()->SetBinLabel(1, "Attempts"); hCascadeBuilding->GetXaxis()->SetBinLabel(2, "La mass window"); - hCascadeBuilding->GetXaxis()->SetBinLabel(3, "DCA Fitter"); + hCascadeBuilding->GetXaxis()->SetBinLabel(3, "Mc check"); + hCascadeBuilding->GetXaxis()->SetBinLabel(4, "DCA Fitter"); if (doprocessGenerated) { - histos.add("hGeneratedK0s", "hGeneratedK0s", kTH2D, {{axisPt}, {axisEta}}); - histos.add("hGeneratedLambda", "hGeneratedLambda", kTH2D, {{axisPt}, {axisEta}}); - histos.add("hGeneratedAntiLambda", "hGeneratedAntiLambda", kTH2D, {{axisPt}, {axisEta}}); - histos.add("hGeneratedXi", "hGeneratedXi", kTH2D, {{axisPt}, {axisEta}}); - histos.add("hGeneratedAntiXi", "hGeneratedAntiXi", kTH2D, {{axisPt}, {axisEta}}); - histos.add("hGeneratedOmega", "hGeneratedOmega", kTH2D, {{axisPt}, {axisEta}}); - histos.add("hGeneratedAntiOmega", "hGeneratedAntiOmega", kTH2D, {{axisPt}, {axisEta}}); + histos.add("Generated/hGeneratedK0s", "hGeneratedK0s", kTH2D, {{axisPt}, {axisEta}}); + histos.add("Generated/hGeneratedLambda", "hGeneratedLambda", kTH2D, {{axisPt}, {axisEta}}); + histos.add("Generated/hGeneratedAntiLambda", "hGeneratedAntiLambda", kTH2D, {{axisPt}, {axisEta}}); + histos.add("Generated/hGeneratedXi", "hGeneratedXi", kTH2D, {{axisPt}, {axisEta}}); + histos.add("Generated/hGeneratedAntiXi", "hGeneratedAntiXi", kTH2D, {{axisPt}, {axisEta}}); + histos.add("Generated/hGeneratedOmega", "hGeneratedOmega", kTH2D, {{axisPt}, {axisEta}}); + histos.add("Generated/hGeneratedAntiOmega", "hGeneratedAntiOmega", kTH2D, {{axisPt}, {axisEta}}); } histos.print(); @@ -287,6 +301,29 @@ struct Alice3strangenessFinder { return returnValue; } + template + bool checkSameMotherExtra(TTrackType const& track1, TTrackType const& track2) + { + bool returnValue = false; + if (track1.has_mcParticle() && track2.has_mcParticle()) { + auto mcParticle1 = track1.template mcParticle_as(); + auto mcParticle2 = track2.template mcParticle_as(); + if (mcParticle1.has_mothers() && mcParticle2.has_mothers()) { + for (const auto& mcParticleMother1 : mcParticle1.template mothers_as()) { + if (mcParticleMother1.has_mothers()) { + for (const auto& mcParticleGrandMother1 : mcParticleMother1.template mothers_as()) { + for (const auto& mcParticleMother2 : mcParticle2.template mothers_as()) { + if (mcParticleGrandMother1.globalIndex() == mcParticleMother2.globalIndex()) { + returnValue = true; + } + } + } + } + } + } + } // end association check + return returnValue; + } template bool buildDecayCandidateTwoBody(TTrackType const& t0, TTrackType const& t1, std::array vtx, Candidate& thisCandidate) { @@ -295,7 +332,6 @@ struct Alice3strangenessFinder { histos.fill(HIST("hPtPosDau"), t0.getPt()); if (!skipFitter) { - histos.fill(HIST("hFitterQA"), 0.5); //}-{}-{}-{}-{}-{}-{}-{}-{}-{} // Move close to minima @@ -396,25 +432,25 @@ struct Alice3strangenessFinder { void processGenerated(aod::McParticles const&) { for (const auto& mcParticle : trueK0s) { - histos.fill(HIST("hGeneratedK0s"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("Generated/hGeneratedK0s"), mcParticle.pt(), mcParticle.eta()); } for (const auto& mcParticle : trueLambda) { - histos.fill(HIST("hGeneratedLambda"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("Generated/hGeneratedLambda"), mcParticle.pt(), mcParticle.eta()); } for (const auto& mcParticle : trueAntiLambda) { - histos.fill(HIST("hGeneratedAntiLambda"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("Generated/hGeneratedAntiLambda"), mcParticle.pt(), mcParticle.eta()); } for (const auto& mcParticle : trueXi) { - histos.fill(HIST("hGeneratedXi"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("Generated/hGeneratedXi"), mcParticle.pt(), mcParticle.eta()); } for (const auto& mcParticle : trueAntiXi) { - histos.fill(HIST("hGeneratedAntiXi"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("Generated/hGeneratedAntiXi"), mcParticle.pt(), mcParticle.eta()); } for (const auto& mcParticle : trueOmega) { - histos.fill(HIST("hGeneratedOmega"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("Generated/hGeneratedOmega"), mcParticle.pt(), mcParticle.eta()); } for (const auto& mcParticle : trueAntiOmega) { - histos.fill(HIST("hGeneratedAntiOmega"), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("Generated/hGeneratedAntiOmega"), mcParticle.pt(), mcParticle.eta()); } } @@ -430,7 +466,6 @@ struct Alice3strangenessFinder { } o2::track::TrackParCov pos = getTrackParCov(posTrack); - for (auto const& negTrack : negTracksGrouped) { if (!negTrack.isReconstructed()) { continue; // no ghost tracks @@ -441,33 +476,35 @@ struct Alice3strangenessFinder { continue; // keep only if same mother } - // ACTS: pdg code attached to track - if constexpr (requires { posTrack.pdgCode(); }) { - if ((posTrack.pdgCode() != kPiPlus && negTrack.pdgCode() != kPiMinus) && isK0Gun) { - continue; - } - if ((posTrack.pdgCode() != kProton && negTrack.pdgCode() != kPiMinus) && isLambdaGun) { - continue; + if (isK0Gun || isLambdaGun) { + // ACTS: pdg code attached to track + if constexpr (requires { posTrack.pdgCode(); }) { + if ((posTrack.pdgCode() != kPiPlus && negTrack.pdgCode() != kPiMinus) && isK0Gun) { + continue; + } + if ((posTrack.pdgCode() != kProton && negTrack.pdgCode() != kPiMinus) && isLambdaGun) { + continue; + } + } else { + // OTF: pdg code from mcParticle table + if (!posTrack.has_mcParticle() && !negTrack.has_mcParticle()) { + continue; + } + auto mcParticlePos = posTrack.template mcParticle_as(); + auto mcParticleNeg = negTrack.template mcParticle_as(); + if ((mcParticlePos.pdgCode() != kPiPlus && mcParticleNeg.pdgCode() != kPiMinus) && isK0Gun) { + continue; + } + if ((mcParticlePos.pdgCode() != kProton && mcParticleNeg.pdgCode() != kPiMinus) && isLambdaGun) { + continue; + } } } - // OTF: pdg code from mcParticle table - if (!posTrack.has_mcParticle() && !negTrack.has_mcParticle()) { - continue; - } - auto mcParticlePos = posTrack.template mcParticle_as(); - auto mcParticleNeg = negTrack.template mcParticle_as(); - if ((mcParticlePos.pdgCode() != kPiPlus && mcParticleNeg.pdgCode() != kPiMinus) && isK0Gun) { - continue; - } - if ((mcParticlePos.pdgCode() != kProton && mcParticleNeg.pdgCode() != kPiMinus) && isLambdaGun) { - continue; - } - + Candidate v0Cand; histos.fill(HIST("hV0Building"), 2.0); o2::track::TrackParCov neg = getTrackParCov(negTrack); - Candidate v0cand; - if (!buildDecayCandidateTwoBody(pos, neg, vtx, v0cand)) { + if (!buildDecayCandidateTwoBody(pos, neg, vtx, v0Cand)) { continue; // failed at building candidate } @@ -490,27 +527,26 @@ struct Alice3strangenessFinder { negTrack.globalIndex(), -1); - v0CandidateCores(v0cand.posSV[0], v0cand.posSV[1], v0cand.posSV[2], - v0cand.pDau0[0], v0cand.pDau0[1], v0cand.pDau0[2], - v0cand.pDau1[0], v0cand.pDau1[1], v0cand.pDau1[2], - v0cand.dcaDau, posTrack.dcaXY(), negTrack.dcaXY(), - v0cand.cosPA, v0cand.dcaToPV); + v0CandidateCores(v0Cand.posSV[0], v0Cand.posSV[1], v0Cand.posSV[2], + v0Cand.pDau0[0], v0Cand.pDau0[1], v0Cand.pDau0[2], + v0Cand.pDau1[0], v0Cand.pDau1[1], v0Cand.pDau1[2], + v0Cand.dcaDau, posTrack.dcaXY(), negTrack.dcaXY(), + v0Cand.cosPA, v0Cand.dcaToPV); - o2::track::TrackParCov v0(v0cand.posSV, v0cand.p, v0cand.parentTrackCovMatrix, 0); - const float lambdaMassHypothesis = RecoDecay::m(std::array{std::array{v0cand.pDau0[0], v0cand.pDau0[1], v0cand.pDau0[2]}, - std::array{v0cand.pDau1[0], v0cand.pDau1[1], v0cand.pDau1[2]}}, + const float lambdaMassHypothesis = RecoDecay::m(std::array{std::array{v0Cand.pDau0[0], v0Cand.pDau0[1], v0Cand.pDau0[2]}, + std::array{v0Cand.pDau1[0], v0Cand.pDau1[1], v0Cand.pDau1[2]}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); - const float antiLambdaMassHypothesis = RecoDecay::m(std::array{std::array{v0cand.pDau0[0], v0cand.pDau0[1], v0cand.pDau0[2]}, - std::array{v0cand.pDau1[0], v0cand.pDau1[1], v0cand.pDau1[2]}}, + const float antiLambdaMassHypothesis = RecoDecay::m(std::array{std::array{v0Cand.pDau0[0], v0Cand.pDau0[1], v0Cand.pDau0[2]}, + std::array{v0Cand.pDau1[0], v0Cand.pDau1[1], v0Cand.pDau1[2]}}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); if (!buildCascade) { continue; // not building cascades, so skip the rest } - const bool inLambdaMassWindow = std::abs(lambdaMassHypothesis - o2::constants::physics::MassLambda0) < acceptedLambdaMassWindow; - const bool inAntiLambdaMassWindow = std::abs(antiLambdaMassHypothesis - o2::constants::physics::MassLambda0) < acceptedLambdaMassWindow; + const bool inLambdaMassWindow = std::abs(lambdaMassHypothesis - o2::constants::physics::MassLambda0) < presel.acceptedLambdaMassWindow; + const bool inAntiLambdaMassWindow = std::abs(antiLambdaMassHypothesis - o2::constants::physics::MassLambda0) < presel.acceptedLambdaMassWindow; if (!inLambdaMassWindow && !inAntiLambdaMassWindow) { continue; // Likely not a lambda, should not be considered for cascade building } @@ -530,15 +566,24 @@ struct Alice3strangenessFinder { } histos.fill(HIST("hCascadeBuilding"), 2.0); + Candidate cascCand; + if (mcSameMotherCheck) { + if ((!checkSameMotherExtra(posTrack, bachTrack) || !checkSameMotherExtra(negTrack, bachTrack))) { + continue; + } - // TODO mc same mother check + if (bachTrack.has_mcParticle()) { + auto bachParticle = bachTrack.template mcParticle_as(); + cascCand.index = bachParticle.mothersIds().front(); + } + } - Candidate cascCand; + histos.fill(HIST("hCascadeBuilding"), 3.0); o2::track::TrackParCov bach = getTrackParCov(bachTrack); + o2::track::TrackParCov v0(v0Cand.posSV, v0Cand.p, v0Cand.parentTrackCovMatrix, 0); if (!buildDecayCandidateTwoBody(v0, bach, vtx, cascCand)) { continue; // failed at building candidate } - histos.fill(HIST("hCascadeBuilding"), 3.0); const float massXi = RecoDecay::m(std::array{std::array{cascCand.pDau0[0], cascCand.pDau0[1], cascCand.pDau0[2]}, std::array{cascCand.pDau1[0], cascCand.pDau1[1], cascCand.pDau1[2]}}, @@ -560,22 +605,28 @@ struct Alice3strangenessFinder { bachTrack.px(), bachTrack.py(), bachTrack.pz(), vtx[0], vtx[1], vtx[2]); - tableCascadeIndices(0, // cascade index, dummy value - posTrack.globalIndex(), - negTrack.globalIndex(), - bachTrack.globalIndex(), - collision.globalIndex()); - - tableCascadeCores(bachTrack.sign(), massXi, massOm, - cascCand.posSV[0], cascCand.posSV[1], cascCand.posSV[2], - v0cand.posSV[0], v0cand.posSV[1], v0cand.posSV[2], - v0cand.pDau0[0], v0cand.pDau0[1], v0cand.pDau0[2], - v0cand.pDau1[0], v0cand.pDau1[1], v0cand.pDau1[2], - cascCand.pDau1[0], cascCand.pDau1[1], cascCand.pDau1[2], - cascCand.p[0], cascCand.p[1], cascCand.p[2], - v0cand.dcaDau, cascCand.dcaDau, - dcaPosToPV, dcaNegToPV, dcaBachToPV, - cascCand.dcaToPV, cascCand.dcaToPV); + histos.fill(HIST("hCascadeBuilding"), 4.0); + histos.fill(HIST("hXiMass"), massXi); + histos.fill(HIST("hOmegaMass"), massOm); + + tableA3CascadeMcLabels(cascCand.index); + tableCascIndices(0, // cascade index, dummy value + posTrack.globalIndex(), + negTrack.globalIndex(), + bachTrack.globalIndex(), + collision.globalIndex()); + + tableStoredCascCores(bachTrack.sign(), massXi, massOm, + cascCand.posSV[0], cascCand.posSV[1], cascCand.posSV[2], + v0Cand.posSV[0], v0Cand.posSV[1], v0Cand.posSV[2], + v0Cand.pDau0[0], v0Cand.pDau0[1], v0Cand.pDau0[2], + v0Cand.pDau1[0], v0Cand.pDau1[1], v0Cand.pDau1[2], + cascCand.pDau1[0], cascCand.pDau1[1], cascCand.pDau1[2], + cascCand.p[0], cascCand.p[1], cascCand.p[2], + v0Cand.dcaDau, cascCand.dcaDau, + dcaPosToPV, dcaNegToPV, dcaBachToPV, + cascCand.dcaToPV, cascCand.dcaToPV); // FIXME + } // end bachTrack } // end negTrack } // end posTrack diff --git a/ALICE3/Tasks/CMakeLists.txt b/ALICE3/Tasks/CMakeLists.txt index 8af7d1d1815..bd48a5533f9 100644 --- a/ALICE3/Tasks/CMakeLists.txt +++ b/ALICE3/Tasks/CMakeLists.txt @@ -39,6 +39,11 @@ o2physics_add_dpl_workflow(alice3-dilepton PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::FrameworkPhysicsSupport COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(alice3-prefilterdilepton + SOURCES alice3-prefilterdilepton.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(alice3-taskcorrelationddbar SOURCES alice3-taskcorrelationDDbar.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/ALICE3/Tasks/alice3-cdeuteron.cxx b/ALICE3/Tasks/alice3-cdeuteron.cxx index 6dc574189f2..1c4ebe5b578 100644 --- a/ALICE3/Tasks/alice3-cdeuteron.cxx +++ b/ALICE3/Tasks/alice3-cdeuteron.cxx @@ -26,14 +26,13 @@ #include #include #include +#include #include #include #include #include -#include - #include #include diff --git a/ALICE3/Tasks/alice3-dilepton.cxx b/ALICE3/Tasks/alice3-dilepton.cxx index 099e6205262..5586e066ceb 100644 --- a/ALICE3/Tasks/alice3-dilepton.cxx +++ b/ALICE3/Tasks/alice3-dilepton.cxx @@ -17,6 +17,7 @@ #include "ALICE3/DataModel/OTFCollision.h" #include "ALICE3/DataModel/OTFRICH.h" #include "ALICE3/DataModel/OTFTOF.h" +#include "ALICE3/DataModel/prefilterDilepton.h" #include "ALICE3/DataModel/tracksAlice3.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -38,8 +39,6 @@ #include #include -#include -#include #include using namespace o2; @@ -48,33 +47,17 @@ using namespace o2::soa; using namespace o2::framework; using namespace o2::framework::expressions; -struct Alice3Dilepton { - enum HFllType { - kUndef = -1, - kCe_Ce = 0, // ULS - kBe_Be = 1, // ULS - kBCe_BCe = 2, // ULS - kBCe_Be_SameB = 3, // ULS - kBCe_Be_DiffB = 4, // LS - }; - enum PairType { - kULS = 0, - kLSpp = 1, - kLSnn = 2, - }; - - SliceCache cache_mc; - SliceCache cache_rec; +struct Alice3Lepton { Service inspdg; Configurable pdg{"pdg", 11, "pdg code for analysis. dielectron:11, dimuon:13"}; - Configurable requireHFEid{"requireHFEid", true, "Require HFE identification for both leptons"}; - Configurable ptMin{"pt-min", 0.f, "Lower limit in pT"}; - Configurable ptMax{"pt-max", 5.f, "Upper limit in pT"}; - Configurable etaMin{"eta-min", -5.f, "Lower limit in eta"}; - Configurable etaMax{"eta-max", 5.f, "Upper limit in eta"}; - Configurable useGen{"use-gen", false, "Use generated (true) or smeared/reconstructed (false) values for fiducial cuts"}; + Configurable requireHFE{"requireHFE", false, "Require HFE"}; + Configurable ptMin{"ptMin", 0.f, "Lower limit in pT"}; + Configurable ptMax{"ptMax", 5.f, "Upper limit in pT"}; + Configurable etaMin{"etaMin", -5.f, "Lower limit in eta"}; + Configurable etaMax{"etaMax", 5.f, "Upper limit in eta"}; + Configurable useGen{"useGen", false, "Use generated (true) or smeared/reconstructed (false) values for fiducial cuts"}; Configurable selectReconstructed{"selectReconstructed", true, "Select only reconstructed tracks (true) or ghosts (false)"}; Configurable nSigmaEleCutOuterTOF{"nSigmaEleCutOuterTOF", 3., "Electron inclusion in outer TOF"}; Configurable nSigmaEleCutInnerTOF{"nSigmaEleCutInnerTOF", 3., "Electron inclusion in inner TOF"}; @@ -83,6 +66,8 @@ struct Alice3Dilepton { Configurable nSigmaElectronRich{"nSigmaElectronRich", 3., "Electron inclusion RICH"}; Configurable nSigmaPionRich{"nSigmaPionRich", 3., "Pion exclusion RICH"}; Configurable otfConfig{"otfConfig", 0, "OTF configuration flag"}; + Configurable minFITPart{"minFITPart", 0.f, "Minimum number of charged particles in the FIT acceptance"}; + Configurable maxFITPart{"maxFITPart", 0.f, "Maximum number of charged particles in the FIT acceptance"}; HistogramRegistry registry{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -116,16 +101,6 @@ struct Alice3Dilepton { registry.add("Generated/Particle/prodVz", "Particle Prod. Vertex Z", kTH1F, {axisProdz}); registry.add("Generated/Particle/ParticlesPerEvent", "Particles per event", kTH1F, {{100, 0, 100}}); registry.add("Generated/Particle/ParticlesFit", "Charged Particles in Fit acceptance per event", kTH1F, {{15000, 0, 15000}}); - - registry.add("Generated/Pair/ULS/Tried", "Pair tries", kTH1F, {{10, -0.5, 9.5}}); - registry.add("Generated/Pair/ULS/Mass", "Pair Mass", kTH1F, {axisM}); - registry.add("Generated/Pair/ULS/Pt", "Pair Pt", kTH1F, {axisPt}); - registry.add("Generated/Pair/ULS/Eta", "Pair Eta", kTH1F, {axisEta}); - registry.add("Generated/Pair/ULS/Phi", "Pair Phi", kTH1F, {axisPhi}); - registry.add("Generated/Pair/ULS/Mass_Pt", "Pair Mass vs. Pt", kTH2F, {axisM, axisPt}, true); - - registry.addClone("Generated/Pair/ULS/", "Generated/Pair/LSpp/"); - registry.addClone("Generated/Pair/ULS/", "Generated/Pair/LSnn/"); } if (doprocessRec) { @@ -143,7 +118,264 @@ struct Alice3Dilepton { registry.add("Reconstructed/Track/outerTOFTrackLength", "Track length outer TOF", kTH1F, {axisTrackLengthOuterTOF}); registry.addClone("Reconstructed/Track/", "Reconstructed/TrackPID/"); + registry.addClone("Reconstructed/Track/", "Reconstructed/TrackPIDPre/"); + } + } + + template + bool IsInAcceptance(TTrack const& track) + { + if (track.pt() < ptMin || ptMax < track.pt()) { + return false; + } + if (track.eta() < etaMin || etaMax < track.eta()) { + return false; + } + return true; + } + + // Functions for pid + template + bool electronIDTOF(TTrack const& track) + { + bool isElectron = false; + bool isEleOuterTOF = std::abs(track.nSigmaElectronOuterTOF()) < nSigmaEleCutOuterTOF; + bool isNotPionOuterTOF = std::abs(track.nSigmaPionOuterTOF()) > nSigmaPionCutOuterTOF; + isEleOuterTOF = isEleOuterTOF && isNotPionOuterTOF; + bool isEleInnerTOF = std::abs(track.nSigmaElectronInnerTOF()) < nSigmaEleCutInnerTOF; + bool isNotPionInnerTOF = std::abs(track.nSigmaPionInnerTOF()) > nSigmaPionCutInnerTOF; + isEleInnerTOF = isEleInnerTOF && isNotPionInnerTOF; + isElectron = (isEleOuterTOF || isEleInnerTOF); + return isElectron; + } + + template + bool electronIDRICH(TTrack const& track) + { + bool isElectron = false; + bool isEleRICH = std::abs(track.nSigmaElectronRich()) < nSigmaElectronRich; + bool isNotPionRICH = std::abs(track.nSigmaPionRich()) > nSigmaPionRich; + isElectron = isEleRICH && isNotPionRICH; + return isElectron; + } + + Preslice perMCCollision = o2::aod::mcparticle::mcCollisionId; + + void processGen(o2::aod::McCollisions const& mccollisions, aod::McParticles const& mcParticles) + { + for (const auto& mccollision : mccollisions) { + registry.fill(HIST("Generated/Event/VtxX"), mccollision.posX()); + registry.fill(HIST("Generated/Event/VtxY"), mccollision.posY()); + registry.fill(HIST("Generated/Event/VtxZ"), mccollision.posZ()); + + auto mcParticles_per_coll = mcParticles.sliceBy(perMCCollision, mccollision.globalIndex()); + int nParticlesInEvent = 0; + int nParticlesFIT = 0; + // Calculate the number of particles in the FIT acceptance + for (const auto& mcParticle : mcParticles_per_coll) { + if (mcParticle.isPhysicalPrimary()) { + if ((2.2 < mcParticle.eta() && mcParticle.eta() < 5.0) || (-3.4 < mcParticle.eta() && mcParticle.eta() < -2.3)) { + auto pdgParticle = inspdg->GetParticle(mcParticle.pdgCode()); + if (pdgParticle) { + float charge = pdgParticle->Charge() / 3.f; // Charge in units of |e| + if (std::abs(charge) >= 1.) { + nParticlesFIT++; + } + } + } + nParticlesInEvent++; + } + } + if (nParticlesFIT > minFITPart && nParticlesFIT < maxFITPart) { + for (const auto& mcParticle : mcParticles_per_coll) { + if (std::abs(mcParticle.pdgCode()) != pdg) { + continue; + } + if (!mcParticle.isPhysicalPrimary()) { + continue; + } + if (!IsInAcceptance(mcParticle)) { + continue; + } + registry.fill(HIST("Generated/Particle/Pt"), mcParticle.pt()); + registry.fill(HIST("Generated/Particle/Eta"), mcParticle.eta()); + registry.fill(HIST("Generated/Particle/Phi"), mcParticle.phi()); + registry.fill(HIST("Generated/Particle/Eta_Pt"), mcParticle.pt(), mcParticle.eta()); + + registry.fill(HIST("Generated/Particle/prodVx"), mcParticle.vx()); + registry.fill(HIST("Generated/Particle/prodVy"), mcParticle.vy()); + registry.fill(HIST("Generated/Particle/prodVz"), mcParticle.vz()); + } // end of mc particle loop + registry.fill(HIST("Generated/Particle/ParticlesPerEvent"), nParticlesInEvent); + registry.fill(HIST("Generated/Particle/ParticlesFit"), nParticlesFIT); + } + } // end of mc collision loop + } // end of processGen + + using MyTracksMC = soa::Join; + using Alice3Collision = soa::Join; + + Filter trackFilter = o2::aod::track_alice3::isReconstructed == selectReconstructed; + + using MyFilteredTracksMC = soa::Filtered; + Filter configFilter = (aod::upgrade_collision::lutConfigId == otfConfig); + Filter CollisionFilter = o2::aod::dileptonanalysisflags::isEventCentSelected == 1; + using MyFilteredAlice3Collision = soa::Filtered; + Preslice perCollision = aod::track::collisionId; + + void processRec(MyFilteredAlice3Collision const& collisions, + MyFilteredTracksMC const& tracks, + const o2::aod::McCollisions&, + const aod::McParticles& /*mcParticles*/) + { + for (const auto& collision : collisions) { + registry.fill(HIST("Reconstructed/Event/VtxX"), collision.posX()); + registry.fill(HIST("Reconstructed/Event/VtxY"), collision.posY()); + registry.fill(HIST("Reconstructed/Event/VtxZ"), collision.posZ()); + + auto tracks_coll = tracks.sliceBy(perCollision, collision.globalIndex()); + for (const auto& track : tracks_coll) { + if (!track.has_mcParticle()) { + continue; + } + const auto mcParticle = track.mcParticle_as(); + if (std::abs(mcParticle.pdgCode()) != pdg) { + continue; + } + if (!mcParticle.isPhysicalPrimary()) { + continue; + } + if (useGen) { + if (!IsInAcceptance(mcParticle)) { + continue; + } + } else { + if (!IsInAcceptance(track)) { + continue; + } + } + if (std::abs(mcParticle.pdgCode()) != pdg) { + continue; + } + if (!mcParticle.isPhysicalPrimary()) { + continue; + } + registry.fill(HIST("Reconstructed/Track/SigmaOTofvspt"), track.pt(), track.nSigmaElectronOuterTOF()); + registry.fill(HIST("Reconstructed/Track/SigmaITofvspt"), track.pt(), track.nSigmaElectronInnerTOF()); + registry.fill(HIST("Reconstructed/Track/SigmaRichvspt"), track.pt(), track.nSigmaElectronRich()); + registry.fill(HIST("Reconstructed/Track/outerTOFTrackLength"), track.outerTOFTrackLength()); + registry.fill(HIST("Reconstructed/Track/Pt"), track.pt()); + registry.fill(HIST("Reconstructed/Track/Eta"), track.eta()); + registry.fill(HIST("Reconstructed/Track/Phi"), track.phi()); + registry.fill(HIST("Reconstructed/Track/Eta_Pt"), track.pt(), track.eta()); + // implement pid + + bool isElectronTOF = electronIDTOF(track); + bool isElectronRICH = electronIDRICH(track); + + if (isElectronTOF || isElectronRICH) { + registry.fill(HIST("Reconstructed/TrackPID/SigmaOTofvspt"), track.pt(), track.nSigmaElectronOuterTOF()); + registry.fill(HIST("Reconstructed/TrackPID/SigmaITofvspt"), track.pt(), track.nSigmaElectronInnerTOF()); + registry.fill(HIST("Reconstructed/TrackPID/SigmaRichvspt"), track.pt(), track.nSigmaElectronRich()); + registry.fill(HIST("Reconstructed/TrackPID/outerTOFTrackLength"), track.outerTOFTrackLength()); + registry.fill(HIST("Reconstructed/TrackPID/Pt"), track.pt()); + registry.fill(HIST("Reconstructed/TrackPID/Eta"), track.eta()); + registry.fill(HIST("Reconstructed/TrackPID/Phi"), track.phi()); + registry.fill(HIST("Reconstructed/TrackPID/Eta_Pt"), track.pt(), track.eta()); + + if (track.isTrackPrefilter() == 0) { + registry.fill(HIST("Reconstructed/TrackPIDPre/SigmaOTofvspt"), track.pt(), track.nSigmaElectronOuterTOF()); + registry.fill(HIST("Reconstructed/TrackPIDPre/SigmaITofvspt"), track.pt(), track.nSigmaElectronInnerTOF()); + registry.fill(HIST("Reconstructed/TrackPIDPre/SigmaRichvspt"), track.pt(), track.nSigmaElectronRich()); + registry.fill(HIST("Reconstructed/TrackPIDPre/outerTOFTrackLength"), track.outerTOFTrackLength()); + registry.fill(HIST("Reconstructed/TrackPIDPre/Pt"), track.pt()); + registry.fill(HIST("Reconstructed/TrackPIDPre/Eta"), track.eta()); + registry.fill(HIST("Reconstructed/TrackPIDPre/Phi"), track.phi()); + registry.fill(HIST("Reconstructed/TrackPIDPre/Eta_Pt"), track.pt(), track.eta()); + } + } + } // end of track loop + } // end of collision loop + } // end of processRec + + void processDummy(Alice3Collision const&) + { + } + + PROCESS_SWITCH(Alice3Lepton, processGen, "Run for generated particle", false); + PROCESS_SWITCH(Alice3Lepton, processRec, "Run for reconstructed track", false); + PROCESS_SWITCH(Alice3Lepton, processDummy, "Dummy run", true); +}; + +struct Alice3Dilepton { + enum HFllType { + kUndef = -1, + kCe_Ce = 0, // ULS + kBe_Be = 1, // ULS + kBCe_BCe = 2, // ULS + kBCe_Be_SameB = 3, // ULS + kBCe_Be_DiffB = 4, // LS + }; + enum PairType { + kULS = 0, + kLSpp = 1, + kLSnn = 2, + }; + + SliceCache cache_mc; + SliceCache cache_rec; + + Configurable pdg{"pdg", 11, "pdg code for analysis. dielectron:11, dimuon:13"}; + Configurable requireHFEid{"requireHFEid", true, "Require HFE identification for both leptons"}; + Configurable ptMin{"ptMin", 0.f, "Lower limit in pT"}; + Configurable ptMax{"ptMax", 5.f, "Upper limit in pT"}; + Configurable etaMin{"etaMin", -5.f, "Lower limit in eta"}; + Configurable etaMax{"etaMax", 5.f, "Upper limit in eta"}; + Configurable useGen{"useGen", false, "Use generated (true) or smeared/reconstructed (false) values for fiducial cuts"}; + Configurable selectReconstructed{"selectReconstructed", true, "Select only reconstructed tracks (true) or ghosts (false)"}; + Configurable nSigmaEleCutOuterTOF{"nSigmaEleCutOuterTOF", 3., "Electron inclusion in outer TOF"}; + Configurable nSigmaEleCutInnerTOF{"nSigmaEleCutInnerTOF", 3., "Electron inclusion in inner TOF"}; + Configurable nSigmaPionCutOuterTOF{"nSigmaPionCutOuterTOF", 3., "Pion exclusion in outer TOF"}; + Configurable nSigmaPionCutInnerTOF{"nSigmaPionCutInnerTOF", 3., "Pion exclusion in inner TOF"}; + Configurable nSigmaElectronRich{"nSigmaElectronRich", 3., "Electron inclusion RICH"}; + Configurable nSigmaPionRich{"nSigmaPionRich", 3., "Pion exclusion RICH"}; + Configurable otfConfig{"otfConfig", 0, "OTF configuration flag"}; + Configurable cfg_apply_prefilter{"cfg_apply_prefilter", false, "flag to apply prefilter"}; + HistogramRegistry registry{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + void init(InitContext&) + { + const AxisSpec axisVz{100, -20, 20, "Vtx_{z}"}; + + const AxisSpec axisM{500, 0, 5, "#it{m}_{ll} (GeV/#it{c}^{2})"}; + const AxisSpec axisPt{1000, 0, 10, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisSigmaEl{200, -10, 10, "n#sigma_{El}"}; + const AxisSpec axisEta{1000, -5, 5, "#it{#eta}"}; + const AxisSpec axisDCAxy{1000, 0, 20, "DCA_{xy,ll} (#sigma)"}; + const AxisSpec axisPhi{360, 0, TMath::TwoPi(), "#it{#varphi} (rad.)"}; + + if (doprocessRecAll) { + registry.add("Reconstructed/Event/VtxZ", "Vertex Z", kTH1F, {axisVz}); + registry.add("Reconstructed/Track/Pt", "Track Pt", kTH1F, {axisPt}); + registry.add("Reconstructed/Track/SigmaOTofvspt", "Track #sigma oTOF", kTH2F, {axisPt, axisSigmaEl}); + registry.add("Reconstructed/Track/SigmaITofvspt", "Track #sigma iTOF", kTH2F, {axisPt, axisSigmaEl}); + registry.add("Reconstructed/Track/SigmaRichvspt", "Track #sigma RICH", kTH2F, {axisPt, axisSigmaEl}); + } + + if (doprocessGen) { + registry.add("Generated/Pair/ULS/Tried", "Pair tries", kTH1F, {{10, -0.5, 9.5}}); + registry.add("Generated/Pair/ULS/Mass", "Pair Mass", kTH1F, {axisM}); + registry.add("Generated/Pair/ULS/Pt", "Pair Pt", kTH1F, {axisPt}); + registry.add("Generated/Pair/ULS/Eta", "Pair Eta", kTH1F, {axisEta}); + registry.add("Generated/Pair/ULS/Phi", "Pair Phi", kTH1F, {axisPhi}); + registry.add("Generated/Pair/ULS/Mass_Pt", "Pair Mass vs. Pt", kTH2F, {axisM, axisPt}, true); + + registry.addClone("Generated/Pair/ULS/", "Generated/Pair/LSpp/"); + registry.addClone("Generated/Pair/ULS/", "Generated/Pair/LSnn/"); + } + + if (doprocessRec || doprocessRecAll) { registry.add("Reconstructed/Pair/ULS/Mass", "Pair Mass", kTH1F, {axisM}); registry.add("Reconstructed/Pair/ULS/Pt", "Pair Pt", kTH1F, {axisPt}); registry.add("Reconstructed/Pair/ULS/Eta", "Pair Eta", kTH1F, {axisEta}); @@ -153,15 +385,6 @@ struct Alice3Dilepton { registry.addClone("Reconstructed/Pair/ULS/", "Reconstructed/Pair/LSpp/"); registry.addClone("Reconstructed/Pair/ULS/", "Reconstructed/Pair/LSnn/"); - registry.add("ReconstructedFiltered/Pair/ULS/Mass", "Pair Mass", kTH1F, {axisM}); - registry.add("ReconstructedFiltered/Pair/ULS/Pt", "Pair Pt", kTH1F, {axisPt}); - registry.add("ReconstructedFiltered/Pair/ULS/Eta", "Pair Eta", kTH1F, {axisEta}); - registry.add("ReconstructedFiltered/Pair/ULS/Phi", "Pair Phi", kTH1F, {axisPhi}); - registry.add("ReconstructedFiltered/Pair/ULS/Mass_Pt", "Pair Mass vs. Pt", kTH2F, {axisM, axisPt}, true); - - registry.addClone("ReconstructedFiltered/Pair/ULS/", "ReconstructedFiltered/Pair/LSpp/"); - registry.addClone("ReconstructedFiltered/Pair/ULS/", "ReconstructedFiltered/Pair/LSnn/"); - HistogramConfigSpec hs_rec{HistType::kTHnSparseF, {axisM, axisPt, axisDCAxy}, 3}; registry.add("Reconstructed/Pair/ULS/hs_rec", "", hs_rec); registry.add("Reconstructed/Pair/LSpp/hs_rec", "", hs_rec); @@ -192,8 +415,6 @@ struct Alice3Dilepton { if (!p2.has_mothers()) return -1; - // LOGF(info,"original motherid1 = %d , motherid2 = %d", p1.mothersIds()[0], p2.mothersIds()[0]); - int motherid1 = p1.mothersIds()[0]; auto mother1 = mcparticles.iteratorAt(motherid1); int mother1_pdg = mother1.pdgCode(); @@ -202,8 +423,6 @@ struct Alice3Dilepton { auto mother2 = mcparticles.iteratorAt(motherid2); int mother2_pdg = mother2.pdgCode(); - // LOGF(info,"motherid1 = %d , motherid2 = %d", motherid1, motherid2); - if (motherid1 != motherid2) return -1; if (mother1_pdg != mother2_pdg) @@ -222,7 +441,6 @@ struct Alice3Dilepton { return -1; } - // LOGF(info, "%d is found.", mother1_pdg); return motherid1; } @@ -330,58 +548,53 @@ struct Alice3Dilepton { const float dcaXY_t2 = t2.dcaXY(); const float dcaXY_res_t1 = sqrt(t1.cYY()); const float dcaXY_res_t2 = sqrt(t2.cYY()); + float dcaXYinSigma_t1 = dcaXY_t1 / dcaXY_res_t1; + float dcaXYinSigma_t2 = dcaXY_t2 / dcaXY_res_t2; - pair_dca_xy = sqrt((dcaXY_t2 * dcaXY_t2 / dcaXY_res_t2 + dcaXY_t1 * dcaXY_t1 / dcaXY_res_t1) / 2.); + pair_dca_xy = sqrt((dcaXYinSigma_t1 * dcaXYinSigma_t1 + dcaXYinSigma_t2 * dcaXYinSigma_t2) / 2.); ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), std::abs(pdg) == 11 ? o2::constants::physics::MassElectron : o2::constants::physics::MassMuon); // reconstructed pt/eta/phi ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), std::abs(pdg) == 11 ? o2::constants::physics::MassElectron : o2::constants::physics::MassMuon); // reconstructed pt/eta/phi ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; return v12; } - template - void FillPairRecWithPrefilter(TTracks const& tracks1, TTracks const& tracks2, TMCTracks const& /*mcParticles*/) + template + void FillPairRecAll(TTracks const& tracks1, TTracks const& tracks2) { - std::vector prefilteredTracks; if constexpr (pairtype == PairType::kULS) { for (auto& [t1, t2] : combinations(soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - if (!t1.has_mcParticle() || !t2.has_mcParticle()) { - continue; - } - float pair_dca_xy = 999.f; ROOT::Math::PtEtaPhiMVector v12 = buildPairDCA(t1, t2, pair_dca_xy); - // prefilter for low-mass pairs - if (v12.M() > 0.10) { - continue; - } - // prefilter small opening angle pairs - if (std::cos(t1.phi() - t2.phi()) < 0.99) { - continue; - } - prefilteredTracks.push_back(t1.globalIndex()); - prefilteredTracks.push_back(t2.globalIndex()); + registry.fill(HIST("Reconstructed/Pair/ULS/Mass"), v12.M()); + registry.fill(HIST("Reconstructed/Pair/ULS/Pt"), v12.Pt()); + registry.fill(HIST("Reconstructed/Pair/ULS/Eta"), v12.Eta()); + registry.fill(HIST("Reconstructed/Pair/ULS/Phi"), v12.Phi() < 0.f ? v12.Phi() + TMath::TwoPi() : v12.Phi()); + registry.fill(HIST("Reconstructed/Pair/ULS/Mass_Pt"), v12.M(), v12.Pt()); + registry.fill(HIST("Reconstructed/Pair/ULS/hs_rec"), v12.M(), v12.Pt(), pair_dca_xy); } // end of unlike-sign pair loop - for (auto& [t1, t2] : combinations(soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - // Skipping tracks that are in the prefiltered list - if (std::find(prefilteredTracks.begin(), prefilteredTracks.end(), t1.globalIndex()) != prefilteredTracks.end()) { - continue; - } - if (std::find(prefilteredTracks.begin(), prefilteredTracks.end(), t2.globalIndex()) != prefilteredTracks.end()) { - continue; - } - + } else if constexpr (pairtype == PairType::kLSpp || pairtype == PairType::kLSnn) { + for (auto& [t1, t2] : combinations(soa::CombinationsStrictlyUpperIndexPolicy(tracks1, tracks2))) { float pair_dca_xy = 999.f; ROOT::Math::PtEtaPhiMVector v12 = buildPairDCA(t1, t2, pair_dca_xy); - registry.fill(HIST("ReconstructedFiltered/Pair/ULS/Mass"), v12.M()); - registry.fill(HIST("ReconstructedFiltered/Pair/ULS/Pt"), v12.Pt()); - registry.fill(HIST("ReconstructedFiltered/Pair/ULS/Eta"), v12.Eta()); - registry.fill(HIST("ReconstructedFiltered/Pair/ULS/Phi"), v12.Phi() < 0.f ? v12.Phi() + TMath::TwoPi() : v12.Phi()); - registry.fill(HIST("ReconstructedFiltered/Pair/ULS/Mass_Pt"), v12.M(), v12.Pt()); - registry.fill(HIST("ReconstructedFiltered/Pair/ULS/hs_rec"), v12.M(), v12.Pt(), pair_dca_xy); - } + if constexpr (pairtype == PairType::kLSpp) { + registry.fill(HIST("Reconstructed/Pair/LSpp/Mass"), v12.M()); + registry.fill(HIST("Reconstructed/Pair/LSpp/Pt"), v12.Pt()); + registry.fill(HIST("Reconstructed/Pair/LSpp/Eta"), v12.Eta()); + registry.fill(HIST("Reconstructed/Pair/LSpp/Mass_Pt"), v12.M(), v12.Pt()); + registry.fill(HIST("Reconstructed/Pair/LSpp/Phi"), v12.Phi() < 0.f ? v12.Phi() + TMath::TwoPi() : v12.Phi()); + registry.fill(HIST("Reconstructed/Pair/LSpp/hs_rec"), v12.M(), v12.Pt(), pair_dca_xy); + } else if constexpr (pairtype == PairType::kLSnn) { + registry.fill(HIST("Reconstructed/Pair/LSnn/Mass"), v12.M()); + registry.fill(HIST("Reconstructed/Pair/LSnn/Pt"), v12.Pt()); + registry.fill(HIST("Reconstructed/Pair/LSnn/Eta"), v12.Eta()); + registry.fill(HIST("Reconstructed/Pair/LSnn/Mass_Pt"), v12.M(), v12.Pt()); + registry.fill(HIST("Reconstructed/Pair/LSnn/Phi"), v12.Phi() < 0.f ? v12.Phi() + TMath::TwoPi() : v12.Phi()); + registry.fill(HIST("Reconstructed/Pair/LSnn/hs_rec"), v12.M(), v12.Pt(), pair_dca_xy); + } + } // end of like-sign pair loop } } @@ -410,7 +623,6 @@ struct Alice3Dilepton { if (motherid < 0 && hfee_type == HFllType::kUndef) { continue; } - // auto mother = mcparticles.iteratorAt(motherid); float pair_dca_xy = 999.f; ROOT::Math::PtEtaPhiMVector v12 = buildPairDCA(t1, t2, pair_dca_xy); @@ -445,7 +657,6 @@ struct Alice3Dilepton { if (motherid < 0 && hfee_type == HFllType::kUndef) { continue; } - // auto mother = mcparticles.iteratorAt(motherid); float pair_dca_xy = 999.f; ROOT::Math::PtEtaPhiMVector v12 = buildPairDCA(t1, t2, pair_dca_xy); @@ -497,7 +708,6 @@ struct Alice3Dilepton { continue; } registry.fill(HIST("Generated/Pair/ULS/Tried"), 4); - // auto mother = mcparticles.iteratorAt(motherid); ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), std::abs(pdg) == 11 ? o2::constants::physics::MassElectron : o2::constants::physics::MassMuon); ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), std::abs(pdg) == 11 ? o2::constants::physics::MassElectron : o2::constants::physics::MassMuon); @@ -579,81 +789,12 @@ struct Alice3Dilepton { } } - // Functions for pid - template - bool electronIDTOF(TTrack const& track) - { - bool isElectron = false; - bool isEleOuterTOF = std::abs(track.nSigmaElectronOuterTOF()) < nSigmaEleCutOuterTOF; - bool isNotPionOuterTOF = std::abs(track.nSigmaPionOuterTOF()) > nSigmaPionCutOuterTOF; - isEleOuterTOF = isEleOuterTOF && isNotPionOuterTOF; - bool isEleInnerTOF = std::abs(track.nSigmaElectronInnerTOF()) < nSigmaEleCutInnerTOF; - bool isNotPionInnerTOF = std::abs(track.nSigmaPionInnerTOF()) > nSigmaPionCutInnerTOF; - isEleInnerTOF = isEleInnerTOF && isNotPionInnerTOF; - isElectron = (isEleOuterTOF || isEleInnerTOF); - return isElectron; - } - - template - bool electronIDRICH(TTrack const& track) - { - bool isElectron = false; - bool isEleRICH = std::abs(track.nSigmaElectronRich()) < nSigmaElectronRich; - bool isNotPionRICH = std::abs(track.nSigmaPionRich()) > nSigmaPionRich; - isElectron = isEleRICH && isNotPionRICH; - return isElectron; - } - - Preslice perMCCollision = o2::aod::mcparticle::mcCollisionId; Partition pos_mcParticles = o2::aod::mcparticle::pdgCode == -pdg; //-11 or -13 Partition neg_mcParticles = o2::aod::mcparticle::pdgCode == pdg; // 11 or 13 void processGen(o2::aod::McCollisions const& mccollisions, aod::McParticles const& mcParticles) { for (const auto& mccollision : mccollisions) { - registry.fill(HIST("Generated/Event/VtxX"), mccollision.posX()); - registry.fill(HIST("Generated/Event/VtxY"), mccollision.posY()); - registry.fill(HIST("Generated/Event/VtxZ"), mccollision.posZ()); - - auto mcParticles_per_coll = mcParticles.sliceBy(perMCCollision, mccollision.globalIndex()); - int nParticlesInEvent = 0; - int nParticlesFIT = 0; - for (const auto& mcParticle : mcParticles_per_coll) { - if (mcParticle.isPhysicalPrimary()) { - if ((2.2 < mcParticle.eta() && mcParticle.eta() < 5.0) || (-3.4 < mcParticle.eta() && mcParticle.eta() < -2.3)) { - auto pdgParticle = inspdg->GetParticle(mcParticle.pdgCode()); - if (pdgParticle) { - float charge = pdgParticle->Charge() / 3.f; // Charge in units of |e| - if (std::abs(charge) >= 1.) { - nParticlesFIT++; - } - } - } - } - if (std::abs(mcParticle.pdgCode()) != pdg) { - continue; - } - if (!mcParticle.isPhysicalPrimary()) { - continue; - } - if (!IsInAcceptance(mcParticle)) { - continue; - } - nParticlesInEvent++; - - registry.fill(HIST("Generated/Particle/Pt"), mcParticle.pt()); - registry.fill(HIST("Generated/Particle/Eta"), mcParticle.eta()); - registry.fill(HIST("Generated/Particle/Phi"), mcParticle.phi()); - registry.fill(HIST("Generated/Particle/Eta_Pt"), mcParticle.pt(), mcParticle.eta()); - - registry.fill(HIST("Generated/Particle/prodVx"), mcParticle.vx()); - registry.fill(HIST("Generated/Particle/prodVy"), mcParticle.vy()); - registry.fill(HIST("Generated/Particle/prodVz"), mcParticle.vz()); - - } // end of mc particle loop - registry.fill(HIST("Generated/Particle/ParticlesPerEvent"), nParticlesInEvent); - registry.fill(HIST("Generated/Particle/ParticlesFit"), nParticlesFIT); - auto neg_mcParticles_coll = neg_mcParticles->sliceByCached(o2::aod::mcparticle::mcCollisionId, mccollision.globalIndex(), cache_mc); auto pos_mcParticles_coll = pos_mcParticles->sliceByCached(o2::aod::mcparticle::mcCollisionId, mccollision.globalIndex(), cache_mc); @@ -664,84 +805,28 @@ struct Alice3Dilepton { } // end of mc collision loop } // end of processGen - using MyTracksMC = soa::Join; - using Alice3Collision = soa::Join; + using MyTracksMC = soa::Join; + using Alice3Collision = soa::Join; + + Filter trackFilter = etaMin < o2::aod::track::eta && o2::aod::track::eta < etaMax && ptMin < o2::aod::track::pt && o2::aod::track::pt < ptMax && o2::aod::track_alice3::isReconstructed == selectReconstructed; + // Filter trackFilter = o2::aod::track_alice3::isReconstructed == selectReconstructed; + Filter pidFilter_electron = (nabs(o2::aod::upgrade_rich::nSigmaElectronRich) < nSigmaElectronRich && nSigmaPionRich < nabs(o2::aod::upgrade_rich::nSigmaPionRich)) || (nabs(o2::aod::upgrade_tof::nSigmaElectronOuterTOF) < nSigmaEleCutOuterTOF && nSigmaPionCutOuterTOF < nabs(o2::aod::upgrade_tof::nSigmaPionOuterTOF)) || (nabs(o2::aod::upgrade_tof::nSigmaElectronInnerTOF) < nSigmaEleCutInnerTOF && nSigmaPionCutInnerTOF < nabs(o2::aod::upgrade_tof::nSigmaPionInnerTOF)); + Filter prefilter_electron = ifnode(cfg_apply_prefilter.node(), o2::aod::dileptonanalysisflags::isTrackPrefilter == 0, o2::aod::dileptonanalysisflags::isTrackPrefilter == 0 || o2::aod::dileptonanalysisflags::isTrackPrefilter == 1); - // Filter trackFilter = etaMin < o2::aod::track::eta && - // o2::aod::track::eta < etaMax && - // ptMin < o2::aod::track::pt && - // o2::aod::track::pt < ptMax && - // o2::aod::track_alice3::isReconstructed == selectReconstructed; - Filter trackFilter = o2::aod::track_alice3::isReconstructed == selectReconstructed; using MyFilteredTracksMC = soa::Filtered; Filter configFilter = (aod::upgrade_collision::lutConfigId == otfConfig); + Filter CollisionFilter = o2::aod::dileptonanalysisflags::isEventCentSelected == 1; using MyFilteredAlice3Collision = soa::Filtered; Preslice perCollision = aod::track::collisionId; Partition posTracks = o2::aod::track::signed1Pt > 0.f; Partition negTracks = o2::aod::track::signed1Pt < 0.f; void processRec(MyFilteredAlice3Collision const& collisions, - MyFilteredTracksMC const& tracks, + MyFilteredTracksMC const& /*tracks*/, const o2::aod::McCollisions&, const aod::McParticles& mcParticles) { for (const auto& collision : collisions) { - registry.fill(HIST("Reconstructed/Event/VtxX"), collision.posX()); - registry.fill(HIST("Reconstructed/Event/VtxY"), collision.posY()); - registry.fill(HIST("Reconstructed/Event/VtxZ"), collision.posZ()); - - auto tracks_coll = tracks.sliceBy(perCollision, collision.globalIndex()); - for (const auto& track : tracks_coll) { - if (!track.has_mcParticle()) { - continue; - } - const auto mcParticle = track.mcParticle_as(); - if (std::abs(mcParticle.pdgCode()) != pdg) { - continue; - } - if (!mcParticle.isPhysicalPrimary()) { - continue; - } - if (useGen) { - if (!IsInAcceptance(mcParticle)) { - continue; - } - } else { - if (!IsInAcceptance(track)) { - continue; - } - } - if (std::abs(mcParticle.pdgCode()) != pdg) { - continue; - } - if (!mcParticle.isPhysicalPrimary()) { - continue; - } - registry.fill(HIST("Reconstructed/Track/SigmaOTofvspt"), track.pt(), track.nSigmaElectronOuterTOF()); - registry.fill(HIST("Reconstructed/Track/SigmaITofvspt"), track.pt(), track.nSigmaElectronInnerTOF()); - registry.fill(HIST("Reconstructed/Track/SigmaRichvspt"), track.pt(), track.nSigmaElectronRich()); - registry.fill(HIST("Reconstructed/Track/outerTOFTrackLength"), track.outerTOFTrackLength()); - registry.fill(HIST("Reconstructed/Track/Pt"), track.pt()); - registry.fill(HIST("Reconstructed/Track/Eta"), track.eta()); - registry.fill(HIST("Reconstructed/Track/Phi"), track.phi()); - registry.fill(HIST("Reconstructed/Track/Eta_Pt"), track.pt(), track.eta()); - // implement pid - - bool isElectronTOF = electronIDTOF(track); - bool isElectronRICH = electronIDRICH(track); - - if (isElectronTOF || isElectronRICH) { - registry.fill(HIST("Reconstructed/TrackPID/SigmaOTofvspt"), track.pt(), track.nSigmaElectronOuterTOF()); - registry.fill(HIST("Reconstructed/TrackPID/SigmaITofvspt"), track.pt(), track.nSigmaElectronInnerTOF()); - registry.fill(HIST("Reconstructed/TrackPID/SigmaRichvspt"), track.pt(), track.nSigmaElectronRich()); - registry.fill(HIST("Reconstructed/TrackPID/outerTOFTrackLength"), track.outerTOFTrackLength()); - registry.fill(HIST("Reconstructed/TrackPID/Pt"), track.pt()); - registry.fill(HIST("Reconstructed/TrackPID/Eta"), track.eta()); - registry.fill(HIST("Reconstructed/TrackPID/Phi"), track.phi()); - registry.fill(HIST("Reconstructed/TrackPID/Eta_Pt"), track.pt(), track.eta()); - } - } // end of track loop - // How is PID selection applied to tracks? auto negTracks_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache_rec); auto posTracks_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache_rec); @@ -752,11 +837,42 @@ struct Alice3Dilepton { } // end of collision loop } // end of processRec - PROCESS_SWITCH(Alice3Dilepton, processGen, "Run for generated particle", true); + void processRecAll(MyFilteredAlice3Collision const& collisions, + MyFilteredTracksMC const& tracks) + { + + for (const auto& track : tracks) { + registry.fill(HIST("Reconstructed/Track/Pt"), track.pt()); + registry.fill(HIST("Reconstructed/Track/SigmaOTofvspt"), track.pt(), track.nSigmaElectronOuterTOF()); + registry.fill(HIST("Reconstructed/Track/SigmaITofvspt"), track.pt(), track.nSigmaElectronInnerTOF()); + registry.fill(HIST("Reconstructed/Track/SigmaRichvspt"), track.pt(), track.nSigmaElectronRich()); + } + + for (const auto& collision : collisions) { + registry.fill(HIST("Reconstructed/Event/VtxZ"), collision.posZ()); + auto negTracks_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache_rec); + auto posTracks_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache_rec); + + FillPairRecAll(negTracks_coll, posTracks_coll); + FillPairRecAll(posTracks_coll, posTracks_coll); + FillPairRecAll(negTracks_coll, negTracks_coll); + + } // end of collision loop + } // end of processRec + + void processDummy(Alice3Collision const&) + { + } + + PROCESS_SWITCH(Alice3Dilepton, processGen, "Run for generated particle", false); PROCESS_SWITCH(Alice3Dilepton, processRec, "Run for reconstructed track", false); + PROCESS_SWITCH(Alice3Dilepton, processRecAll, "Run for reconstructed track", false); + PROCESS_SWITCH(Alice3Dilepton, processDummy, "Run dummy", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"alice3-dilepton"})}; + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; } diff --git a/ALICE3/Tasks/alice3-prefilterdilepton.cxx b/ALICE3/Tasks/alice3-prefilterdilepton.cxx new file mode 100644 index 00000000000..0226f88b30d --- /dev/null +++ b/ALICE3/Tasks/alice3-prefilterdilepton.cxx @@ -0,0 +1,308 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \file alice3-dilepton.cxx +/// \author s.scheid@cern.ch, daiki.sekihata@cern.ch +/// + +#include "ALICE3/DataModel/OTFRICH.h" +#include "ALICE3/DataModel/OTFTOF.h" +#include "ALICE3/DataModel/prefilterDilepton.h" +#include "ALICE3/DataModel/tracksAlice3.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include +#include + +#include +#include +#include +#include + +using namespace o2; +using namespace o2::aod; +using namespace o2::soa; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct Alice3DileptonEventCentSelection { + + Service inspdg; + + Produces eventCentSel; + Configurable minFITPart{"minFITPart", 0.f, "Minimum number of charged particles in the FIT acceptance"}; + Configurable maxFITPart{"maxFITPart", 0.f, "Maximum number of charged particles in the FIT acceptance"}; + + HistogramRegistry registry{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + void init(InitContext&) + { + registry.add("Generated/Before/ParticlesFit", "Charged Particles in Fit acceptance per event", kTH1F, {{15000, 0, 15000}}); + registry.add("Generated/After/ParticlesFit", "Charged Particles in Fit acceptance per event", kTH1F, {{15000, 0, 15000}}); + registry.add("Generated/Before/ParticlesEta", "Charged Particles per event", kTH1F, {{1200, -6, 6}}); + registry.add("Generated/After/ParticlesEta", "Charged Particles per event", kTH1F, {{1200, -6, 6}}); + } + + using MyEvents = soa::Join; + Preslice perMCCollision = o2::aod::mcparticle::mcCollisionId; + + void processGen(MyEvents::iterator const& event, o2::aod::McCollisions const&, aod::McParticles const& mcParticles) + { + if (!event.has_mcCollision()) { + eventCentSel(0); + } else { + auto mccollision = event.mcCollision(); + auto mcParticles_per_coll = mcParticles.sliceBy(perMCCollision, mccollision.globalIndex()); + int nParticlesFIT = 0; + for (const auto& mcParticle : mcParticles_per_coll) { + if (mcParticle.isPhysicalPrimary()) { + auto pdgParticle = inspdg->GetParticle(mcParticle.pdgCode()); + if (pdgParticle) { + float charge = pdgParticle->Charge() / 3.f; // Charge in units of |e| + if (std::abs(charge) >= 1.) { + registry.fill(HIST("Generated/Before/ParticlesEta"), mcParticle.eta()); + if ((2.2 < mcParticle.eta() && mcParticle.eta() < 5.0) || (-3.4 < mcParticle.eta() && mcParticle.eta() < -2.3)) { + nParticlesFIT++; + } + } + } + } + } // end of mc particle loop + registry.fill(HIST("Generated/Before/ParticlesFit"), nParticlesFIT); + if (nParticlesFIT > minFITPart && nParticlesFIT < maxFITPart) { + registry.fill(HIST("Generated/After/ParticlesFit"), nParticlesFIT); + for (const auto& mcParticle : mcParticles_per_coll) { + if (mcParticle.isPhysicalPrimary()) { + auto pdgParticle = inspdg->GetParticle(mcParticle.pdgCode()); + if (pdgParticle) { + float charge = pdgParticle->Charge() / 3.f; // Charge in units of |e| + if (std::abs(charge) >= 1.) { + registry.fill(HIST("Generated/After/ParticlesEta"), mcParticle.eta()); + } + } + } + } // end of mc particle loop + eventCentSel(1); + } else { + eventCentSel(0); + } + } // if mc collision loop + } // end of process + + void processDummy(MyEvents::iterator const&) + { + eventCentSel(1); + } + + PROCESS_SWITCH(Alice3DileptonEventCentSelection, processGen, "Select centrality", false); + PROCESS_SWITCH(Alice3DileptonEventCentSelection, processDummy, "Dummy", true); +}; + +struct Alice3DileptonPrefilter { + + Produces pfb_derived; + + SliceCache cache_mc; + SliceCache cache_rec; + + Service inspdg; + + Configurable ptMin{"ptMin", 0.f, "Lower limit in pT"}; + Configurable ptMax{"ptMax", 5.f, "Upper limit in pT"}; + Configurable etaMin{"etaMin", -5.f, "Lower limit in eta"}; + Configurable etaMax{"etaMax", 5.f, "Upper limit in eta"}; + Configurable maxMass{"maxMass", 5.f, "Upper limit in mass"}; + Configurable maxOp{"maxOp", 5.f, "Upper limit in opening angle"}; + Configurable nSigmaEleCutOuterTOF{"nSigmaEleCutOuterTOF", 3., "Electron inclusion in outer TOF"}; + Configurable nSigmaEleCutInnerTOF{"nSigmaEleCutInnerTOF", 3., "Electron inclusion in inner TOF"}; + Configurable nSigmaPionCutOuterTOF{"nSigmaPionCutOuterTOF", 3., "Pion exclusion in outer TOF"}; + Configurable nSigmaPionCutInnerTOF{"nSigmaPionCutInnerTOF", 3., "Pion exclusion in inner TOF"}; + Configurable nSigmaElectronRich{"nSigmaElectronRich", 3., "Electron inclusion RICH"}; + Configurable nSigmaPionRich{"nSigmaPionRich", 3., "Pion exclusion RICH"}; + + std::unordered_map map_pfb; // map track.globalIndex -> prefilter bit + + HistogramRegistry registry{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + using MyTracksMCs = soa::Join; + using MyTracksMC = MyTracksMCs::iterator; + using DileptonCollisions = soa::Join; + using DileptonCollision = DileptonCollisions::iterator; + + Preslice perCollision = aod::track::collisionId; + Partition posTracks = o2::aod::track::signed1Pt > 0.f; + Partition negTracks = o2::aod::track::signed1Pt < 0.f; + + void init(InitContext&) + { + const AxisSpec axisM{500, 0, 5, "#it{m}_{ll} (GeV/#it{c}^{2})"}; + const AxisSpec axisPt{1000, 0, 10, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisSigmaEl{200, -10, 10, "n#sigma_{El}"}; + const AxisSpec axisTrackLengthOuterTOF{300, 0., 300., "Track length (cm)"}; + const AxisSpec axisEta{1000, -5, 5, "#it{#eta}"}; + const AxisSpec axisPhi{360, 0, TMath::TwoPi(), "#it{#varphi} (rad.)"}; + const AxisSpec axisProdx{2000, -100, 100, "Prod. Vertex X (cm)"}; + const AxisSpec axisPrody{2000, -100, 100, "Prod. Vertex Y (cm)"}; + const AxisSpec axisProdz{2000, -100, 100, "Prod. Vertex Z (cm)"}; + + registry.add("Reconstructed/Pair/ULS/Mass_Pt", "Pair Mass vs. Pt", kTH2F, {axisM, axisPt}, true); + registry.add("ReconstructedFiltered/Pair/ULS/Mass_Pt", "Pair Mass vs. Pt", kTH2F, {axisM, axisPt}, true); + registry.add("Reconstructed/Track/Pt", "Track Pt", kTH1F, {axisPt}); + registry.add("Reconstructed/Track/Eta", "Track Eta", kTH1F, {axisEta}); + registry.add("Reconstructed/Track/Phi", "Track Phi", kTH1F, {axisPhi}); + registry.add("Reconstructed/Track/Eta_Pt", "Eta vs. Pt", kTH2F, {axisPt, axisEta}, true); + registry.add("Reconstructed/Track/SigmaOTofvspt", "Track #sigma oTOF", kTH2F, {axisPt, axisSigmaEl}); + registry.add("Reconstructed/Track/SigmaITofvspt", "Track #sigma iTOF", kTH2F, {axisPt, axisSigmaEl}); + registry.add("Reconstructed/Track/SigmaRichvspt", "Track #sigma RICH", kTH2F, {axisPt, axisSigmaEl}); + registry.add("Reconstructed/Track/outerTOFTrackLength", "Track length outer TOF", kTH1F, {axisTrackLengthOuterTOF}); + } + + void processPreFilter(DileptonCollisions const& collisions, MyTracksMCs const& tracks) + { + for (const auto& track : tracks) { + map_pfb[track.globalIndex()] = 0; + } // end of track loop + + for (const auto& collision : collisions) { + auto negTracks_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache_rec); + auto posTracks_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache_rec); + + if (collision.isEventCentSelected() == 0) { + for (const auto& pos : posTracks_coll) { + map_pfb[pos.globalIndex()] = 0; + } + for (const auto& neg : negTracks_coll) { + map_pfb[neg.globalIndex()] = 0; + } + continue; + } + + for (const auto& pos : posTracks_coll) { + if (!pos.isReconstructed()) { + continue; + } + if (pos.eta() < etaMin || etaMax < pos.eta()) { + continue; + } + if (pos.pt() < ptMin || ptMax < pos.pt()) { + continue; + } + if ((std::abs(pos.nSigmaElectronRich()) < nSigmaElectronRich && nSigmaPionRich < std::abs(pos.nSigmaPionRich())) || (std::abs(pos.nSigmaElectronOuterTOF()) < nSigmaEleCutOuterTOF && nSigmaPionCutOuterTOF < std::abs(pos.nSigmaPionOuterTOF())) || (std::abs(pos.nSigmaElectronInnerTOF()) < nSigmaEleCutInnerTOF && nSigmaPionCutInnerTOF < std::abs(pos.nSigmaPionInnerTOF()))) { + registry.fill(HIST("Reconstructed/Track/SigmaOTofvspt"), pos.pt(), pos.nSigmaElectronOuterTOF()); + registry.fill(HIST("Reconstructed/Track/SigmaITofvspt"), pos.pt(), pos.nSigmaElectronInnerTOF()); + registry.fill(HIST("Reconstructed/Track/SigmaRichvspt"), pos.pt(), pos.nSigmaElectronRich()); + registry.fill(HIST("Reconstructed/Track/outerTOFTrackLength"), pos.outerTOFTrackLength()); + registry.fill(HIST("Reconstructed/Track/Pt"), pos.pt()); + registry.fill(HIST("Reconstructed/Track/Eta"), pos.eta()); + registry.fill(HIST("Reconstructed/Track/Phi"), pos.phi()); + registry.fill(HIST("Reconstructed/Track/Eta_Pt"), pos.pt(), pos.eta()); + } + } + for (const auto& ele : negTracks_coll) { + if (!ele.isReconstructed()) { + continue; + } + if (ele.eta() < etaMin || etaMax < ele.eta()) { + continue; + } + if (ele.pt() < ptMin || ptMax < ele.pt()) { + continue; + } + if ((std::abs(ele.nSigmaElectronRich()) < nSigmaElectronRich && nSigmaPionRich < std::abs(ele.nSigmaPionRich())) || (std::abs(ele.nSigmaElectronOuterTOF()) < nSigmaEleCutOuterTOF && nSigmaPionCutOuterTOF < std::abs(ele.nSigmaPionOuterTOF())) || (std::abs(ele.nSigmaElectronInnerTOF()) < nSigmaEleCutInnerTOF && nSigmaPionCutInnerTOF < std::abs(ele.nSigmaPionInnerTOF()))) { + registry.fill(HIST("Reconstructed/Track/SigmaOTofvspt"), ele.pt(), ele.nSigmaElectronOuterTOF()); + registry.fill(HIST("Reconstructed/Track/SigmaITofvspt"), ele.pt(), ele.nSigmaElectronInnerTOF()); + registry.fill(HIST("Reconstructed/Track/SigmaRichvspt"), ele.pt(), ele.nSigmaElectronRich()); + registry.fill(HIST("Reconstructed/Track/outerTOFTrackLength"), ele.outerTOFTrackLength()); + registry.fill(HIST("Reconstructed/Track/Pt"), ele.pt()); + registry.fill(HIST("Reconstructed/Track/Eta"), ele.eta()); + registry.fill(HIST("Reconstructed/Track/Phi"), ele.phi()); + registry.fill(HIST("Reconstructed/Track/Eta_Pt"), ele.pt(), ele.eta()); + } + } + + for (const auto& [pos, ele] : combinations(CombinationsFullIndexPolicy(posTracks_coll, negTracks_coll))) { // ULS + if (!pos.isReconstructed()) { + continue; + } + if (pos.eta() < etaMin || etaMax < pos.eta()) { + continue; + } + if (pos.pt() < ptMin || ptMax < pos.pt()) { + continue; + } + if (!ele.isReconstructed()) { + continue; + } + if (ele.eta() < etaMin || etaMax < ele.eta()) { + continue; + } + if (ele.pt() < ptMin || ptMax < ele.pt()) { + continue; + } + if ((std::abs(pos.nSigmaElectronRich()) < nSigmaElectronRich && nSigmaPionRich < std::abs(pos.nSigmaPionRich())) || (std::abs(pos.nSigmaElectronOuterTOF()) < nSigmaEleCutOuterTOF && nSigmaPionCutOuterTOF < std::abs(pos.nSigmaPionOuterTOF())) || (std::abs(pos.nSigmaElectronInnerTOF()) < nSigmaEleCutInnerTOF && nSigmaPionCutInnerTOF < std::abs(pos.nSigmaPionInnerTOF()))) { + if ((std::abs(ele.nSigmaElectronRich()) < nSigmaElectronRich && nSigmaPionRich < std::abs(ele.nSigmaPionRich())) || (std::abs(ele.nSigmaElectronOuterTOF()) < nSigmaEleCutOuterTOF && nSigmaPionCutOuterTOF < std::abs(ele.nSigmaPionOuterTOF())) || (std::abs(ele.nSigmaElectronInnerTOF()) < nSigmaEleCutInnerTOF && nSigmaPionCutInnerTOF < std::abs(ele.nSigmaPionInnerTOF()))) { + ROOT::Math::PtEtaPhiMVector v1(pos.pt(), pos.eta(), pos.phi(), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(ele.pt(), ele.eta(), ele.phi(), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + float angle = ROOT::Math::VectorUtil::Angle(v1, v2); + o2::math_utils::bringToPMPi(angle); + + registry.fill(HIST("Reconstructed/Pair/ULS/Mass_Pt"), v12.M(), v12.Pt()); + + if (v12.M() < maxMass && angle < maxOp) { + map_pfb[pos.globalIndex()] = 1; + map_pfb[ele.globalIndex()] = 1; + registry.fill(HIST("ReconstructedFiltered/Pair/ULS/Mass_Pt"), v12.M(), v12.Pt()); + } + } + } + } + } // end of collision + + for (const auto& track : tracks) { + pfb_derived(map_pfb[track.globalIndex()]); + } // end of track loop + map_pfb.clear(); + } + + void processDummy(MyTracksMCs const& tracks) + { + for (int i = 0; i < tracks.size(); i++) { + pfb_derived(0); + } + } + + PROCESS_SWITCH(Alice3DileptonPrefilter, processPreFilter, "Run prefilter", false); + PROCESS_SWITCH(Alice3DileptonPrefilter, processDummy, "Dummy", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; +} diff --git a/ALICE3/Tasks/alice3DecayerQa.cxx b/ALICE3/Tasks/alice3DecayerQa.cxx index 18e075d567e..5b6ae287c44 100644 --- a/ALICE3/Tasks/alice3DecayerQa.cxx +++ b/ALICE3/Tasks/alice3DecayerQa.cxx @@ -163,8 +163,8 @@ struct Alice3DecayerQa { histos.fill(HIST("K0S/hHasDecayed"), 1); auto daughters = particle.daughtersIds(); if (daughters.size() == NV0Daughters) { - auto dau0 = particles.rawIteratorAt(daughters.front()); - auto dau1 = particles.rawIteratorAt(daughters.back()); + auto dau0 = particles.rawIteratorAt(daughters.front() - particles.offset()); + auto dau1 = particles.rawIteratorAt(daughters.back() - particles.offset()); // K0S -> pi+ pi- const bool k0sDecay = (dau0.pdgCode() == PDG_t::kPiPlus && dau1.pdgCode() == PDG_t::kPiMinus) || @@ -187,8 +187,8 @@ struct Alice3DecayerQa { histos.fill(HIST("Lambda/hHasDecayed"), 1); auto daughters = particle.daughtersIds(); if (daughters.size() == NV0Daughters) { - auto dau0 = particles.rawIteratorAt(daughters[0]); - auto dau1 = particles.rawIteratorAt(daughters[1]); + auto dau0 = particles.rawIteratorAt(daughters[0] - particles.offset()); + auto dau1 = particles.rawIteratorAt(daughters[1] - particles.offset()); // Lambda -> p pi- const bool lambdaDecay = (dau0.pdgCode() == PDG_t::kProton && dau1.pdgCode() == PDG_t::kPiMinus) || @@ -211,8 +211,8 @@ struct Alice3DecayerQa { histos.fill(HIST("XiMinus/hHasDecayed"), 1); auto daughters = particle.daughtersIds(); if (daughters.size() == NCascadeDaughters) { - auto dau0 = particles.rawIteratorAt(daughters.front()); - auto dau1 = particles.rawIteratorAt(daughters.back()); + auto dau0 = particles.rawIteratorAt(daughters.front() - particles.offset()); + auto dau1 = particles.rawIteratorAt(daughters.back() - particles.offset()); // Xi- -> Lambda pi- const bool xiDecay = (dau0.pdgCode() == PDG_t::kLambda0 && dau1.pdgCode() == PDG_t::kPiMinus) || @@ -228,8 +228,8 @@ struct Alice3DecayerQa { if (v0.has_daughters()) { auto v0daughters = v0.daughtersIds(); if (v0daughters.size() == NV0Daughters) { - auto v0dau0 = particles.rawIteratorAt(v0daughters.front()); - auto v0dau1 = particles.rawIteratorAt(v0daughters.back()); + auto v0dau0 = particles.rawIteratorAt(v0daughters.front() - particles.offset()); + auto v0dau1 = particles.rawIteratorAt(v0daughters.back() - particles.offset()); const bool lambdaDecay = (v0dau0.pdgCode() == PDG_t::kProton && v0dau1.pdgCode() == PDG_t::kPiMinus) || (v0dau0.pdgCode() == PDG_t::kPiMinus && v0dau1.pdgCode() == PDG_t::kProton); if (lambdaDecay) { diff --git a/ALICE3/Tasks/alice3Strangeness.cxx b/ALICE3/Tasks/alice3Strangeness.cxx index 499624cd6bf..3b54dcb6945 100644 --- a/ALICE3/Tasks/alice3Strangeness.cxx +++ b/ALICE3/Tasks/alice3Strangeness.cxx @@ -36,6 +36,9 @@ #include #include +#include +#include + #include #include @@ -51,7 +54,7 @@ using namespace o2::constants::math; using Alice3Tracks = soa::Join; using FullV0Candidates = soa::Join; -using FullCascadeCandidates = soa::Join; +using FullCascadeCandidates = soa::Join; using FullCollisions = soa::Join; struct Alice3Strangeness { @@ -66,15 +69,17 @@ struct Alice3Strangeness { ConfigurableAxis axisOmegaMass{"axisOmegaMass", {200, 1.57f, 1.77f}, ""}; ConfigurableAxis axisVertexZ{"axisVertexZ", {40, -20, 20}, "vertex Z (cm)"}; ConfigurableAxis axisDCA{"axisDCA", {200, 0, 5}, "DCA (cm)"}; - ConfigurableAxis axisV0Radius{"axisV0Radius", {50, 0.0, 100}, "V0 radius (cm)"}; + ConfigurableAxis axisRadius{"axisRadius", {50, 0.0, 100}, "V0 radius (cm)"}; ConfigurableAxis axisDCAV0Daughters{"axisDCAV0Daughters", {20, 0, 5}, "DCA V0 daughters"}; ConfigurableAxis axisPointingAngle{"axisPointingAngle", {40, 0.0f, 0.4f}, "pointing angle "}; + ConfigurableAxis axisCosPA{"axisCosPA", {100, 0.91f, 1.01f}, "cos(pointing angle) "}; ConfigurableAxis axisProperLifeTime{"axisProperLifeTime", {100, 0.0f, 100.0f}, "proper lifetime (cm)"}; + ConfigurableAxis axisNormalizedDecayLength{"axisNormalizedDecayLength", {100, 0.0f, 20}, "Normalized decay length"}; ConfigurableAxis axisEta{"axisEta", {100, -5.0f, 5.0f}, "eta"}; } histAxes; struct : ConfigurableGroup { - std::string prefix = "selectionFlags"; + std::string prefix = "v0SelectionFlags"; Configurable applyRapiditySelection{"applyRapiditySelection", true, "apply rapidity selection"}; Configurable applyDCAdaughterSelection{"applyDCAdaughterSelection", true, "apply DCA daughter selection"}; Configurable applyCosOfPAngleSelection{"applyCosOfPAngleSelection", true, "apply cosine of pointing angle selection"}; @@ -86,10 +91,10 @@ struct Alice3Strangeness { Configurable applyEtaDaughterSelection{"applyEtaDaughterSelection", true, "apply eta daughter selection"}; Configurable doQAforSelectionVariables{"doQAforSelectionVariables", false, "enable QA plots"}; Configurable analyseOnlyTrueV0s{"analyseOnlyTrueV0s", false, "analyse only true V0s from MC"}; - } selectionFlags; + } v0SelectionFlags; struct : ConfigurableGroup { - std::string prefix = "selectionValues"; + std::string prefix = "v0SelectionValues"; Configurable yK0Selection{"yK0Selection", 0.5f, "rapidity selection for K0"}; Configurable yLambdaSelection{"yLambdaSelection", 0.5f, "rapidity selection for Lambda"}; Configurable dcaDaughterSelection{"dcaDaughterSelection", 1.0f, "DCA daughter selection"}; @@ -104,9 +109,54 @@ struct Alice3Strangeness { Configurable etaDaughterSelection{"etaDaughterSelection", 0.8f, "eta daughter selection"}; Configurable acceptedLambdaMassWindow{"acceptedLambdaMassWindow", 0.2f, "accepted Lambda mass window around PDG mass"}; Configurable acceptedK0MassWindow{"acceptedK0MassWindow", 0.3f, "accepted K0 mass window around PDG mass"}; - Configurable acceptedXiMassWindow{"acceptedXiMassWindow", 0.5f, "accepted Xi mass window around PDG mass"}; - Configurable acceptedOmegaMassWindow{"acceptedOmegaMassWindow", 0.5f, "accepted Omega mass window around PDG mass"}; - } selectionValues; + } v0SelectionValues; + + struct : ConfigurableGroup { + std::string prefix = "cascadeSelectionValues"; + Configurable posMinConstDCAxy{"posMinConstDCAxy", 0.5f, "[0] in |DCAxy| > [0]+[1]/pT"}; + Configurable posMinPtDepDCAxy{"posMinPtDepDCAxy", 0.f, "[1] in |DCAxy| > [0]+[1]/pT"}; + Configurable posMinConstDCAz{"posMinConstDCAz", -1.f, "[1] in |DCAz| > [0]+[1]/pT"}; + Configurable posMinPtDepDCAz{"posMinPtDepDCAz", 0.f, "[0] in |DCAz| > [0]+[1]/pT"}; + Configurable negMinConstDCAxy{"negMinConstDCAxy", 0.5f, "[0] in |DCAxy| > [0]+[1]/pT"}; + Configurable negMinPtDepDCAxy{"negMinPtDepDCAxy", 0.f, "[1] in |DCAxy| > [0]+[1]/pT"}; + Configurable negMinConstDCAz{"negMinConstDCAz", -1.f, "[1] in |DCAz| > [0]+[1]/pT"}; + Configurable negMinPtDepDCAz{"negMinPtDepDCAz", 0.f, "[0] in |DCAz| > [0]+[1]/pT"}; + Configurable bachMinConstDCAxy{"bachMinConstDCAxy", 0.5f, "[0] in |DCAxy| > [0]+[1]/pT"}; + Configurable bachMinPtDepDCAxy{"bachMinPtDepDCAxy", 0.f, "[1] in |DCAxy| > [0]+[1]/pT"}; + Configurable bachMinConstDCAz{"bachMinConstDCAz", -1.f, "[1] in |DCAz| > [0]+[1]/pT"}; + Configurable bachMinPtDepDCAz{"bachMinPtDepDCAz", 0.f, "[0] in |DCAz| > [0]+[1]/pT"}; + Configurable laMaxDauDCA{"laMaxDauDCA", 0.5f, "DCA (cm) between lambda daughters"}; + Configurable laMinDecayRadius{"laMinDecayRadius", 0.5f, "Minimum lambda radius"}; + Configurable laMassWindow{"laMassWindow", 0.5f, "accepted la mass window around PDG mass"}; + Configurable laMinCosPA{"laMinCosPA", 0.98, "Min Lambda CosPA"}; + Configurable cascMaxDauDCA{"cascMaxDauDCA", 0.5f, "DCA (cm) between cascade daughters"}; + Configurable cascMaxNormalizedDecayLength{"cascMaxNormalizedDecayLength", 3, "Max cascade nomralized decay length (ctau/)"}; + Configurable cascMinCosPA{"cascMinCosPA", 0.98, "Minimum cascade CosPA"}; + Configurable cascMinDecayRadius{"cascMinDecayRadius", 0.5f, "Minimum cascade decay radius"}; + Configurable cascMassWindow{"cascMassWindow", 0.5f, "accepted cascade mass window around PDG mass"}; + Configurable competingMassRejection{"competingMassRejection", 0.5f, "competing mass rejection"}; + } cascadeSelectionValues; + + struct : ConfigurableGroup { + std::string prefix = "cascadeFlags"; + Configurable analyseCascade{"analyseCascade", 0, "0: Xi, 1: AntiXi, 2: Omega, 3: AntiOmega"}; + Configurable analyseOnlyTrueCascades{"analyseOnlyTrueCascades", false, "analyse only true cascades from MC"}; + Configurable posDCAxy{"posDCAxy", true, "enable posDCAxy selection"}; + Configurable posDCAz{"posDCAz", false, "enable posDCAz selection"}; + Configurable negDCAxy{"negDCAxy", true, "enable negDCAxy selection"}; + Configurable negDCAz{"negDCAz", false, "enable negDCAz selection"}; + Configurable bachDCAxy{"bachDCAxy", true, "enable bachDCAxy selection"}; + Configurable bachDCAz{"bachDCAz", false, "enable bachDCAz selection"}; + Configurable laMaxDauDCA{"laMaxDauDCA", true, "enable laMaxDauDCA selection"}; + Configurable laMinDecayRadius{"laMinDecayRadius", true, "enable laMinDecayRadius selection"}; + Configurable laMassWindow{"laMassWindow", true, "enable laMassWindow selection"}; + Configurable laMinCosPA{"laMinCosPA", true, "enable laMinCosPA selection"}; + Configurable cascMaxDauDCA{"cascMaxDauDCA", true, "enable cascMaxDauDCA selection"}; + Configurable cascMinDecayRadius{"cascMinDecayRadius", true, "enable cascMinDecayRadius selection"}; + Configurable cascMaxNormalizedDecayLength{"cascMaxNormalizedDecayLength", true, "enable cascMaxNormalizedDecayLength selection"}; + Configurable cascMinCosPA{"cascMinCosPA", true, "enable cascMinCosPA selection"}; + Configurable competingMassRejection{"competingMassRejection", false, "enable competingMassRejection selection"}; + } cascadeFlags; uint16_t appliedSelectionCheckMask; double selectionCheck; @@ -114,6 +164,41 @@ struct Alice3Strangeness { const int posDaugDCAselIDx = 3; static constexpr std::string_view KSelectionNames[] = {"DCAV0Daughters", "PointingAngle", "DCAtoPVNegDaughter", "DCAtoPVPosDaughter", "V0Radius", "ProperLifeTime"}; + static constexpr float ToMicrons = 1e+4f; + static constexpr float CtauXi = 4.91f; + static constexpr float CtauOmega = 2.461f; + + struct Cascade { + enum Type { Xi = 0, + AntiXi, + Omega, + AntiOmega }; + Type type{}; + + float pdgMass{}, pdgCompetingMass{}, ctau{}; + int sign{}, pdgCode{}; + + void setCascadeType(Type newType) + { + type = newType; + if (type == Xi || type == AntiXi) { + ctau = CtauXi; + pdgMass = o2::constants::physics::MassXiMinus; + pdgCompetingMass = o2::constants::physics::MassOmegaMinus; + pdgCode = (type == Xi) ? PDG_t::kXiMinus : kXiPlusBar; + sign = (type == Xi) ? -1 : 1; + } + + if (type == Omega || type == AntiOmega) { + ctau = CtauOmega; + pdgMass = o2::constants::physics::MassOmegaMinus; + pdgCompetingMass = o2::constants::physics::MassXiMinus; + pdgCode = (type == Omega) ? PDG_t::kOmegaMinus : kOmegaPlusBar; + sign = (type == Omega) ? -1 : 1; + } + } + } analysedCascade; + void init(InitContext&) { histos.add("K0/hMassAllCandidates", "", kTH2D, {histAxes.axisK0Mass, histAxes.axisPt}); @@ -135,35 +220,77 @@ struct Alice3Strangeness { histos.add("reconstructedCandidates/hArmeterosAfterAllSelections", "hArmeterosAfterAllSelections", kTH2D, {{100, -1.0f, 1.0f}, {200, 0.0f, 0.5f}}); if (doprocessFoundCascadeCandidates) { - histos.add("reconstructedCandidates/Xi/hMassAllCandidates", "hMassAllCandidates", kTH1D, {histAxes.axisXiMass}); - histos.add("reconstructedCandidates/Xi/hMassSelected", "hMassSelected", kTH1D, {histAxes.axisXiMass}); - histos.add("reconstructedCandidates/Omega/hMassAllCandidates", "hMassAllCandidates", kTH1D, {histAxes.axisOmegaMass}); - histos.add("reconstructedCandidates/Omega/hMassSelected", "hMassSelected", kTH1D, {histAxes.axisOmegaMass}); - - histos.addClone("reconstructedCandidates/Xi/", "reconstructedCandidates/AntiXi/"); - histos.addClone("reconstructedCandidates/Omega/", "reconstructedCandidates/AntiOmega/"); + analysedCascade.setCascadeType(static_cast(cascadeFlags.analyseCascade.value)); + histos.add("reconstructedCandidates/Cascade/hMassAllXiCandidates", "hMassAllXiCandidates", kTH1D, {histAxes.axisXiMass}); + histos.add("reconstructedCandidates/Cascade/hMassAllAntiXiCandidates", "hMassAllAntiXiCandidates", kTH1D, {histAxes.axisXiMass}); + histos.add("reconstructedCandidates/Cascade/hMassAllOmegaCandidates", "hMassAllOmegaCandidates", kTH1D, {histAxes.axisOmegaMass}); + histos.add("reconstructedCandidates/Cascade/hMassAllAntiOmegaCandidates", "hMassAllAntiOmegaCandidates", kTH1D, {histAxes.axisOmegaMass}); + + histos.add("reconstructedCandidates/Cascade/hMassSelectedXiCandidates", "hMassSelectedXiCandidates", kTH1D, {histAxes.axisXiMass}); + histos.add("reconstructedCandidates/Cascade/hMassSelectedAntiXiCandidates", "hMassSelectedAntiXiCandidates", kTH1D, {histAxes.axisXiMass}); + histos.add("reconstructedCandidates/Cascade/hMassSelectedOmegaCandidates", "hMassSelectedOmegaCandidates", kTH1D, {histAxes.axisOmegaMass}); + histos.add("reconstructedCandidates/Cascade/hMassSelectedAntiOmegaCandidates", "hMassSelectedAntiOmegaCandidates", kTH1D, {histAxes.axisOmegaMass}); + + histos.add("reconstructedCandidates/Cascade/h3dXiCandidates", "h3dXiCandidates", kTH3D, {histAxes.axisPt, histAxes.axisEta, histAxes.axisXiMass}); + histos.add("reconstructedCandidates/Cascade/h3dAntiXiCandidates", "h3dAntiXiCandidates", kTH3D, {histAxes.axisPt, histAxes.axisEta, histAxes.axisXiMass}); + histos.add("reconstructedCandidates/Cascade/h3dOmegaCandidates", "h3dOmegaCandidates", kTH3D, {histAxes.axisPt, histAxes.axisEta, histAxes.axisOmegaMass}); + histos.add("reconstructedCandidates/Cascade/h3dAntiOmegaCandidates", "h3dAntiOmegaCandidates", kTH3D, {histAxes.axisPt, histAxes.axisEta, histAxes.axisOmegaMass}); + + histos.add("reconstructedCandidates/Cascade/hSelectionQa", "hSelectionQa", kTH1D, {{20, 0.5, 20.5}}); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(1, "all candidates"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(2, "pos dcaXY"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(3, "neg dcaXY"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(4, "bach dcaXY"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(5, "pos dcaZ"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(6, "neg dcaZ"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(7, "bach dcaZ"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(8, "la dau dca"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(9, "la decay radius"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(10, "la mass window"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(11, "la cosPA"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(12, "casc dau dca"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(13, "casc norm decay length"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(14, "casc decay radius"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(15, "casc cosPA"); + histos.get(HIST("reconstructedCandidates/Cascade/hSelectionQa"))->GetXaxis()->SetBinLabel(16, "competing mass"); + + histos.add("reconstructedCandidates/Cascade/BeforeSelection/hPosDCAxy", "hPosDCAxy", kTH1D, {histAxes.axisDCA}); + histos.add("reconstructedCandidates/Cascade/BeforeSelection/hNegDCAxy", "hNegDCAxy", kTH1D, {histAxes.axisDCA}); + histos.add("reconstructedCandidates/Cascade/BeforeSelection/hBachDCAxy", "hBachDCAxy", kTH1D, {histAxes.axisDCA}); + histos.add("reconstructedCandidates/Cascade/BeforeSelection/hPosDCAz", "hPosDCAz", kTH1D, {histAxes.axisDCA}); + histos.add("reconstructedCandidates/Cascade/BeforeSelection/hNegDCAz", "hNegDCAz", kTH1D, {histAxes.axisDCA}); + histos.add("reconstructedCandidates/Cascade/BeforeSelection/hBachDCAz", "hBachDCAz", kTH1D, {histAxes.axisDCA}); + histos.add("reconstructedCandidates/Cascade/BeforeSelection/hLaDauDCA", "hLaDauDCA", kTH1D, {histAxes.axisDCA}); + histos.add("reconstructedCandidates/Cascade/BeforeSelection/hLaDecayRadius", "hLaDecayRadius", kTH1D, {histAxes.axisRadius}); + histos.add("reconstructedCandidates/Cascade/BeforeSelection/hLaMassWindow", "hLaMassWindow", kTH1D, {histAxes.axisLambdaMass}); + histos.add("reconstructedCandidates/Cascade/BeforeSelection/hLaCosPA", "hLaCosPA", kTH1D, {histAxes.axisCosPA}); + histos.add("reconstructedCandidates/Cascade/BeforeSelection/hCascDauDCA", "hCascDauDCA", kTH1D, {histAxes.axisDCA}); + histos.add("reconstructedCandidates/Cascade/BeforeSelection/hCascDecayLength", "hCascDecayLength", kTH1D, {histAxes.axisNormalizedDecayLength}); + histos.add("reconstructedCandidates/Cascade/BeforeSelection/hCascDecayRadius", "hCascDecayRadius", kTH1D, {histAxes.axisRadius}); + histos.add("reconstructedCandidates/Cascade/BeforeSelection/hCascCosPA", "hCascCosPA", kTH1D, {histAxes.axisCosPA}); + histos.addClone("reconstructedCandidates/Cascade/BeforeSelection/", "reconstructedCandidates/Cascade/AfterSelection/"); } - if (selectionFlags.doQAforSelectionVariables) { - if (!selectionFlags.applyDCADaughtersToPVSelection) { + if (v0SelectionFlags.doQAforSelectionVariables) { + if (!v0SelectionFlags.applyDCADaughtersToPVSelection) { histos.add("reconstructedCandidates/K0/hDCAtoPVNegDaughter", "hDCAtoPVNegDaughter", kTH3D, {histAxes.axisK0Mass, histAxes.axisPt, histAxes.axisDCA}); histos.add("reconstructedCandidates/K0/hDCAtoPVPosDaughter", "hDCAtoPVPosDaughter", kTH3D, {histAxes.axisK0Mass, histAxes.axisPt, histAxes.axisDCA}); histos.add("reconstructedCandidates/Lambda/hDCAtoPVNegDaughter", "hDCAtoPVNegDaughter", kTH3D, {histAxes.axisLambdaMass, histAxes.axisPt, histAxes.axisDCA}); histos.add("reconstructedCandidates/Lambda/hDCAtoPVPosDaughter", "hDCAtoPVPosDaughter", kTH3D, {histAxes.axisLambdaMass, histAxes.axisPt, histAxes.axisDCA}); } - if (!selectionFlags.applyV0RadiusSelection) { - histos.add("reconstructedCandidates/K0/hV0Radius", "hV0Radius", kTH3D, {histAxes.axisK0Mass, histAxes.axisPt, histAxes.axisV0Radius}); - histos.add("reconstructedCandidates/Lambda/hV0Radius", "hV0Radius", kTH3D, {histAxes.axisLambdaMass, histAxes.axisPt, histAxes.axisV0Radius}); + if (!v0SelectionFlags.applyV0RadiusSelection) { + histos.add("reconstructedCandidates/K0/hV0Radius", "hV0Radius", kTH3D, {histAxes.axisK0Mass, histAxes.axisPt, histAxes.axisRadius}); + histos.add("reconstructedCandidates/Lambda/hV0Radius", "hV0Radius", kTH3D, {histAxes.axisLambdaMass, histAxes.axisPt, histAxes.axisRadius}); } - if (!selectionFlags.applyDCAdaughterSelection) { + if (!v0SelectionFlags.applyDCAdaughterSelection) { histos.add("reconstructedCandidates/K0/hDCAV0Daughters", "hDCAV0Daughters", kTH3D, {histAxes.axisK0Mass, histAxes.axisPt, histAxes.axisDCAV0Daughters}); histos.add("reconstructedCandidates/Lambda/hDCAV0Daughters", "hDCAV0Daughters", kTH3D, {histAxes.axisLambdaMass, histAxes.axisPt, histAxes.axisDCAV0Daughters}); } - if (!selectionFlags.applyCosOfPAngleSelection) { + if (!v0SelectionFlags.applyCosOfPAngleSelection) { histos.add("reconstructedCandidates/K0/hPointingAngle", "hPointingAngle", kTH3D, {histAxes.axisK0Mass, histAxes.axisPt, histAxes.axisPointingAngle}); histos.add("reconstructedCandidates/Lambda/hPointingAngle", "hPointingAngle", kTH3D, {histAxes.axisLambdaMass, histAxes.axisPt, histAxes.axisPointingAngle}); } - if (!selectionFlags.applyLifetimeSelection) { + if (!v0SelectionFlags.applyLifetimeSelection) { histos.add("reconstructedCandidates/K0/hProperLifeTime", "hProperLifeTime", kTH3D, {histAxes.axisK0Mass, histAxes.axisPt, histAxes.axisProperLifeTime}); histos.add("reconstructedCandidates/Lambda/hProperLifeTime", "hProperLifeTime", kTH3D, {histAxes.axisLambdaMass, histAxes.axisPt, histAxes.axisProperLifeTime}); } @@ -171,19 +298,25 @@ struct Alice3Strangeness { histos.addClone("reconstructedCandidates/Lambda/", "reconstructedCandidates/AntiLambda/"); appliedSelectionCheckMask = 0; - if (!selectionFlags.applyDCAdaughterSelection) + if (!v0SelectionFlags.applyDCAdaughterSelection) { SETBIT(appliedSelectionCheckMask, 0); - if (!selectionFlags.applyCosOfPAngleSelection) + } + if (!v0SelectionFlags.applyCosOfPAngleSelection) { SETBIT(appliedSelectionCheckMask, 1); - if (!selectionFlags.applyDCADaughtersToPVSelection) { + } + if (!v0SelectionFlags.applyDCADaughtersToPVSelection) { SETBIT(appliedSelectionCheckMask, 2); SETBIT(appliedSelectionCheckMask, 3); } - if (!selectionFlags.applyV0RadiusSelection) + if (!v0SelectionFlags.applyV0RadiusSelection) { SETBIT(appliedSelectionCheckMask, 4); - if (!selectionFlags.applyLifetimeSelection) + } + if (!v0SelectionFlags.applyLifetimeSelection) { SETBIT(appliedSelectionCheckMask, 5); + } + histos.print(); } + void processAllFindableCandidates(aod::Collisions const& collisions, aod::McCollisions const&, aod::UpgradeV0s const& v0Recos, aod::UpgradeCascades const& cascRecos, Alice3Tracks const&) { for (const auto& collision : collisions) { @@ -193,8 +326,8 @@ struct Alice3Strangeness { } for (const auto& v0Cand : v0Recos) { - auto negV0Daughter = v0Cand.negTrack_as(); // de-reference neg track - auto posV0Daughter = v0Cand.posTrack_as(); // de-reference pos track + auto negV0Daughter = v0Cand.negTrack_as(); // de-reference negative track + auto posV0Daughter = v0Cand.posTrack_as(); // de-reference positive track bool isK0 = v0Cand.mK0() > 0; if (isK0) { @@ -202,19 +335,19 @@ struct Alice3Strangeness { histos.fill(HIST("K0/hSelections"), 0); // all candidates histos.fill(HIST("K0/hDCANegDaughter"), negV0Daughter.dcaXY()); histos.fill(HIST("K0/hDCAPosDaughter"), posV0Daughter.dcaXY()); - if (std::abs(negV0Daughter.dcaXY()) < selectionValues.dcaDaughtersToPVSelection) + if (std::abs(negV0Daughter.dcaXY()) < v0SelectionValues.dcaDaughtersToPVSelection) continue; histos.fill(HIST("K0/hSelections"), 1); // dcaXY cut - if (std::abs(posV0Daughter.dcaXY()) < selectionValues.dcaDaughtersToPVSelection) + if (std::abs(posV0Daughter.dcaXY()) < v0SelectionValues.dcaDaughtersToPVSelection) continue; histos.fill(HIST("K0/hSelections"), 2); // dcaXY cut - if (v0Cand.dcaV0Daughters() > selectionValues.dcaDaughterSelection) + if (v0Cand.dcaV0Daughters() > v0SelectionValues.dcaDaughterSelection) continue; histos.fill(HIST("K0/hSelections"), 3); // dca between daughters - if (v0Cand.v0Radius() < selectionValues.v0RadiusSelection) + if (v0Cand.v0Radius() < v0SelectionValues.v0RadiusSelection) continue; histos.fill(HIST("K0/hSelections"), 4); // radius cut - if (std::abs(negV0Daughter.eta()) > selectionValues.etaDaughterSelection || std::abs(posV0Daughter.eta()) > selectionValues.etaDaughterSelection) + if (std::abs(negV0Daughter.eta()) > v0SelectionValues.etaDaughterSelection || std::abs(posV0Daughter.eta()) > v0SelectionValues.etaDaughterSelection) continue; histos.fill(HIST("K0/hSelections"), 5); // eta cut histos.fill(HIST("K0/hMassSelected"), v0Cand.mK0(), v0Cand.pt()); @@ -222,9 +355,9 @@ struct Alice3Strangeness { } for (const auto& cascCand : cascRecos) { - // auto bach = cascCand.bachTrack_as(); // de-reference bach track - // auto neg = cascCand.negTrack_as(); // de-reference neg track - // auto pos = cascCand.posTrack_as(); // de-reference pos track + // auto bachelor = cascCand.bachTrack_as(); // de-reference bachelor track + // auto negative = cascCand.negTrack_as(); // de-reference negative track + // auto positive = cascCand.posTrack_as(); // de-reference positive track // Only XiMinus in the tracker for now histos.fill(HIST("Xi/hMassAllCandidates"), cascCand.mXi()); @@ -241,71 +374,71 @@ struct Alice3Strangeness { float collisionZ = collision.posZ(); histos.fill(HIST("hPVz"), collisionZ); for (auto const& v0 : v0Candidates) { - bool isK0 = std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) < selectionValues.acceptedK0MassWindow; - bool isLambda = std::abs(v0.mLambda() - o2::constants::physics::MassLambda0) < selectionValues.acceptedLambdaMassWindow; - bool isAntiLambda = std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) < selectionValues.acceptedLambdaMassWindow; + bool isK0 = std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) < v0SelectionValues.acceptedK0MassWindow; + bool isLambda = std::abs(v0.mLambda() - o2::constants::physics::MassLambda0) < v0SelectionValues.acceptedLambdaMassWindow; + bool isAntiLambda = std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) < v0SelectionValues.acceptedLambdaMassWindow; histos.fill(HIST("reconstructedCandidates/hArmeterosBeforeAllSelections"), v0.alpha(), v0.qtArm()); histos.fill(HIST("hV0CandidateCounter"), 0.5); - if (selectionFlags.applyRapiditySelection) { - if (isK0 && std::abs(v0.yK0Short()) > selectionValues.yK0Selection) + if (v0SelectionFlags.applyRapiditySelection) { + if (isK0 && std::abs(v0.yK0Short()) > v0SelectionValues.yK0Selection) continue; - if ((isLambda || isAntiLambda) && std::abs(v0.yLambda()) > selectionValues.yLambdaSelection) + if ((isLambda || isAntiLambda) && std::abs(v0.yLambda()) > v0SelectionValues.yLambdaSelection) continue; } histos.fill(HIST("hV0CandidateCounter"), 1.5); - if (selectionFlags.applyDCAdaughterSelection) { - if (std::abs(v0.dcaV0Daughters()) > selectionValues.dcaDaughterSelection) + if (v0SelectionFlags.applyDCAdaughterSelection) { + if (std::abs(v0.dcaV0Daughters()) > v0SelectionValues.dcaDaughterSelection) continue; } else { selectionCheck = v0.dcaV0Daughters(); } histos.fill(HIST("hV0CandidateCounter"), 2.5); - if (selectionFlags.applyCosOfPAngleSelection) { - if (v0.cosPA() < selectionValues.cosPAngleSelection) + if (v0SelectionFlags.applyCosOfPAngleSelection) { + if (v0.cosPA() < v0SelectionValues.cosPAngleSelection) continue; } else { selectionCheck = std::acos(v0.cosPA()); } histos.fill(HIST("hV0CandidateCounter"), 3.5); - if (selectionFlags.applyDCADaughtersToPVSelection) { - if ((std::abs(v0.dcaNegToPV()) < selectionValues.dcaDaughtersToPVSelection) || - (std::abs(v0.dcaPosToPV()) < selectionValues.dcaDaughtersToPVSelection)) + if (v0SelectionFlags.applyDCADaughtersToPVSelection) { + if ((std::abs(v0.dcaNegToPV()) < v0SelectionValues.dcaDaughtersToPVSelection) || + (std::abs(v0.dcaPosToPV()) < v0SelectionValues.dcaDaughtersToPVSelection)) continue; } else { selectionCheckPos = std::abs(v0.dcaPosToPV()); selectionCheck = std::abs(v0.dcaNegToPV()); } histos.fill(HIST("hV0CandidateCounter"), 4.5); - if (selectionFlags.applyV0RadiusSelection) { - if (v0.v0radius() < selectionValues.v0RadiusSelection) + if (v0SelectionFlags.applyV0RadiusSelection) { + if (v0.v0radius() < v0SelectionValues.v0RadiusSelection) continue; } else { selectionCheck = v0.v0radius(); } histos.fill(HIST("hV0CandidateCounter"), 5.5); if (isK0) { - if (selectionFlags.applyArmenterosSelection) { - if (v0.qtArm() < selectionValues.armenterosSelection * std::abs(v0.alpha())) + if (v0SelectionFlags.applyArmenterosSelection) { + if (v0.qtArm() < v0SelectionValues.armenterosSelection * std::abs(v0.alpha())) continue; } } histos.fill(HIST("hV0CandidateCounter"), 6.5); - if (isK0 && selectionFlags.applyCompetingMassRejection) { - if (std::abs(v0.mLambda() - o2::constants::physics::MassLambda0) < selectionValues.competingMassRejectionK0) + if (isK0 && v0SelectionFlags.applyCompetingMassRejection) { + if (std::abs(v0.mLambda() - o2::constants::physics::MassLambda0) < v0SelectionValues.competingMassRejectionK0) continue; - if (std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) < selectionValues.competingMassRejectionK0) + if (std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) < v0SelectionValues.competingMassRejectionK0) continue; } - if ((isLambda || isAntiLambda) && selectionFlags.applyCompetingMassRejection) { - if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) < selectionValues.competingMassRejectionLambda) + if ((isLambda || isAntiLambda) && v0SelectionFlags.applyCompetingMassRejection) { + if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) < v0SelectionValues.competingMassRejectionLambda) continue; } histos.fill(HIST("hV0CandidateCounter"), 7.5); - if (selectionFlags.applyLifetimeSelection) { - if (isK0 && v0.distOverTotMom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short > selectionValues.lifetimecutak0) + if (v0SelectionFlags.applyLifetimeSelection) { + if (isK0 && v0.distOverTotMom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short > v0SelectionValues.lifetimecutak0) continue; - if ((isLambda || isAntiLambda) && v0.distOverTotMom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 > selectionValues.lifetimecutambda) + if ((isLambda || isAntiLambda) && v0.distOverTotMom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 > v0SelectionValues.lifetimecutambda) continue; } else { if (isK0) @@ -316,8 +449,8 @@ struct Alice3Strangeness { histos.fill(HIST("hV0CandidateCounter"), 8.5); auto posTrack = v0.template posTrack_as(); auto negTrack = v0.template negTrack_as(); - if (selectionFlags.applyEtaDaughterSelection) { - if (std::abs(posTrack.eta()) > selectionValues.etaDaughterSelection || std::abs(negTrack.eta()) > selectionValues.etaDaughterSelection) + if (v0SelectionFlags.applyEtaDaughterSelection) { + if (std::abs(posTrack.eta()) > v0SelectionValues.etaDaughterSelection || std::abs(negTrack.eta()) > v0SelectionValues.etaDaughterSelection) continue; } histos.fill(HIST("reconstructedCandidates/hEtaDaughters"), posTrack.eta()); @@ -325,7 +458,7 @@ struct Alice3Strangeness { histos.fill(HIST("hV0CandidateCounter"), 9.5); histos.fill(HIST("reconstructedCandidates/hArmeterosAfterAllSelections"), v0.alpha(), v0.qtArm()); - if (selectionFlags.doQAforSelectionVariables) { + if (v0SelectionFlags.doQAforSelectionVariables) { static_for<0, 5>([&](auto i) { constexpr int In = i.value; if (TESTBIT(appliedSelectionCheckMask, In)) { @@ -355,45 +488,163 @@ struct Alice3Strangeness { } } - void processFoundCascadeCandidates(aod::Collision const&, FullCascadeCandidates const& cascadeCandidates, Alice3Tracks const&, aod::McParticles const&) + void processFoundCascadeCandidates(aod::Collision const& collision, FullCascadeCandidates const& cascadeCandidates, Alice3Tracks const&, aod::McParticles const&) { - for (const auto& casc : cascadeCandidates) { - const bool isXi = (std::abs(casc.mXi() - o2::constants::physics::MassXiMinus) < selectionValues.acceptedXiMassWindow) && casc.sign() > 0; - const bool isOm = (std::abs(casc.mOmega() - o2::constants::physics::MassOmegaMinus) < selectionValues.acceptedOmegaMassWindow) && casc.sign() > 0; - const bool isAntiXi = (std::abs(casc.mXi() - o2::constants::physics::MassXiMinus) < selectionValues.acceptedXiMassWindow) && casc.sign() < 0; - const bool isAntiOm = (std::abs(casc.mOmega() - o2::constants::physics::MassOmegaMinus) < selectionValues.acceptedOmegaMassWindow) && casc.sign() < 0; + for (const auto& cascade : cascadeCandidates) { + if (cascade.sign() < 0) { + histos.fill(HIST("reconstructedCandidates/Cascade/hMassAllXiCandidates"), cascade.mXi()); + histos.fill(HIST("reconstructedCandidates/Cascade/hMassAllOmegaCandidates"), cascade.mOmega()); + } else { + histos.fill(HIST("reconstructedCandidates/Cascade/hMassAllAntiXiCandidates"), cascade.mXi()); + histos.fill(HIST("reconstructedCandidates/Cascade/hMassAllAntiOmegaCandidates"), cascade.mOmega()); + } - if (isXi) { - histos.fill(HIST("reconstructedCandidates/Xi/hMassAllCandidates"), casc.mXi()); + auto positive = cascade.template posTrack_as(); + auto negative = cascade.template negTrack_as(); + auto bachelor = cascade.template bachelor_as(); + + const float posDCAxyCut = cascadeSelectionValues.posMinConstDCAxy + cascadeSelectionValues.posMinPtDepDCAxy / positive.pt(); + const float negDCAxyCut = cascadeSelectionValues.negMinConstDCAxy + cascadeSelectionValues.negMinPtDepDCAxy / negative.pt(); + const float bachDCAxyCut = cascadeSelectionValues.bachMinConstDCAxy + cascadeSelectionValues.bachMinPtDepDCAxy / bachelor.pt(); + const float posDCAzCut = cascadeSelectionValues.posMinConstDCAz + cascadeSelectionValues.posMinPtDepDCAz / positive.pt(); + const float negDCAzCut = cascadeSelectionValues.negMinConstDCAz + cascadeSelectionValues.negMinPtDepDCAz / negative.pt(); + const float bachDCAzCut = cascadeSelectionValues.bachMinConstDCAz + cascadeSelectionValues.bachMinPtDepDCAz / bachelor.pt(); + const float distanceFromPV = std::hypot(cascade.x() - collision.posX(), cascade.y() - collision.posY(), cascade.z() - collision.posZ()); + const float normalizedDecayLength = analysedCascade.pdgMass * distanceFromPV / (cascade.p() * analysedCascade.ctau); + + const float cascadeCandidateMass = (analysedCascade.type == Cascade::Xi || analysedCascade.type == Cascade::AntiXi) ? cascade.mXi() : cascade.mOmega(); + const float cascadeCompetingCandidateMass = (analysedCascade.type == Cascade::Xi || analysedCascade.type == Cascade::AntiXi) ? cascade.mOmega() : cascade.mXi(); + bool isAnalysedCascade = (std::abs(cascadeCandidateMass - analysedCascade.pdgMass) < cascadeSelectionValues.cascMassWindow) && (analysedCascade.sign * cascade.sign() > 0); + if (!isAnalysedCascade) { + continue; } - if (isOm) { - histos.fill(HIST("reconstructedCandidates/Omega/hMassAllCandidates"), casc.mOmega()); + histos.fill(HIST("reconstructedCandidates/Cascade/BeforeSelection/hPosDCAxy"), positive.dcaXY() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/BeforeSelection/hNegDCAxy"), negative.dcaXY() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/BeforeSelection/hBachDCAxy"), bachelor.dcaXY() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/BeforeSelection/hPosDCAz"), positive.dcaZ() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/BeforeSelection/hNegDCAz"), negative.dcaZ() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/BeforeSelection/hBachDCAz"), bachelor.dcaZ() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/BeforeSelection/hLaDauDCA"), cascade.dcaV0daughters() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/BeforeSelection/hLaDecayRadius"), cascade.v0radius()); + histos.fill(HIST("reconstructedCandidates/Cascade/BeforeSelection/hLaMassWindow"), cascade.mLambda()); + histos.fill(HIST("reconstructedCandidates/Cascade/BeforeSelection/hLaCosPA"), cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); + histos.fill(HIST("reconstructedCandidates/Cascade/BeforeSelection/hCascDauDCA"), cascade.dcacascdaughters() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/BeforeSelection/hCascDecayLength"), normalizedDecayLength); + histos.fill(HIST("reconstructedCandidates/Cascade/BeforeSelection/hCascDecayRadius"), cascade.cascradius()); + histos.fill(HIST("reconstructedCandidates/Cascade/BeforeSelection/hCascCosPA"), cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + + if (cascadeFlags.analyseOnlyTrueCascades) { + if (!cascade.has_mcParticle()) { + continue; + } + + auto mcCasc = cascade.template mcParticle_as(); + if (mcCasc.pdgCode() != analysedCascade.pdgCode) { + continue; + } } - if (isAntiXi) { - histos.fill(HIST("reconstructedCandidates/AntiXi/hMassAllCandidates"), casc.mXi()); + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 1 /* All candidates*/); + if (cascadeFlags.posDCAxy && std::abs(positive.dcaXY()) < posDCAxyCut) { + continue; } - if (isAntiOm) { - histos.fill(HIST("reconstructedCandidates/AntiOmega/hMassAllCandidates"), casc.mOmega()); + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 2 /* Pass pos dcaXY*/); + if (cascadeFlags.negDCAxy && std::abs(negative.dcaXY()) < negDCAxyCut) { + continue; } - // TODO Add selections - if (isXi) { - histos.fill(HIST("reconstructedCandidates/Xi/hMassSelected"), casc.mXi()); + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 3 /* Pass neg dcaXY*/); + if (cascadeFlags.bachDCAxy && std::abs(bachelor.dcaXY()) < bachDCAxyCut) { + continue; + } + + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 4 /* Pass bach dcaXY*/); + if (cascadeFlags.posDCAz && std::abs(positive.dcaZ()) < posDCAzCut) { + continue; + } + + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 5 /* Pass pos dcaZ*/); + if (cascadeFlags.negDCAz && std::abs(negative.dcaZ()) < negDCAzCut) { + continue; + } + + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 6 /* Pass neg dcaZ*/); + if (cascadeFlags.bachDCAz && std::abs(bachelor.dcaZ()) < bachDCAzCut) { + continue; + } + + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 7 /* Pass bach dcaZ*/); + if (cascadeFlags.laMaxDauDCA && cascade.dcaV0daughters() > cascadeSelectionValues.laMaxDauDCA) { + continue; + } + + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 8 /* Pass la dau dca*/); + if (cascadeFlags.laMinDecayRadius && cascade.v0radius() < cascadeSelectionValues.laMinDecayRadius) { + continue; } - if (isOm) { - histos.fill(HIST("reconstructedCandidates/Omega/hMassSelected"), casc.mOmega()); + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 9 /* Pass la decay radius*/); + if (cascadeFlags.laMassWindow && std::abs(cascade.mLambda() - o2::constants::physics::MassLambda0) > cascadeSelectionValues.laMassWindow) { + continue; } - if (isAntiXi) { - histos.fill(HIST("reconstructedCandidates/AntiXi/hMassSelected"), casc.mXi()); + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 10 /* Pass la mass window*/); + if (cascadeFlags.laMinCosPA && cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < cascadeSelectionValues.laMinCosPA) { + continue; } - if (isAntiOm) { - histos.fill(HIST("reconstructedCandidates/AntiOmega/hMassSelected"), casc.mOmega()); + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 11 /* Pass la cosPA*/); + if (cascadeFlags.cascMaxDauDCA && cascade.dcacascdaughters() > cascadeSelectionValues.cascMaxDauDCA) { + continue; + } + + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 12 /* Pass casc dau dca*/); + if (cascadeFlags.cascMaxNormalizedDecayLength && normalizedDecayLength > cascadeSelectionValues.cascMaxNormalizedDecayLength) { + continue; + } + + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 13 /* Pass casc norm decay length*/); + if (cascadeFlags.cascMinDecayRadius && cascade.cascradius() < cascadeSelectionValues.cascMinDecayRadius) { + continue; + } + + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 14 /* Pass casc decay radius*/); + if (cascadeFlags.cascMinCosPA && cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ()) < cascadeSelectionValues.cascMinCosPA) { + continue; + } + + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 15 /* Pass casc cosPA*/); + if (cascadeFlags.competingMassRejection && std::abs(cascadeCompetingCandidateMass - analysedCascade.pdgCompetingMass) < cascadeSelectionValues.competingMassRejection) { + continue; + } + + histos.fill(HIST("reconstructedCandidates/Cascade/hSelectionQa"), 16 /* Pass casc competing mass rej*/); + histos.fill(HIST("reconstructedCandidates/Cascade/AfterSelection/hPosDCAxy"), positive.dcaXY() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/AfterSelection/hNegDCAxy"), negative.dcaXY() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/AfterSelection/hBachDCAxy"), bachelor.dcaXY() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/AfterSelection/hPosDCAz"), positive.dcaZ() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/AfterSelection/hNegDCAz"), negative.dcaZ() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/AfterSelection/hBachDCAz"), bachelor.dcaZ() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/AfterSelection/hLaDauDCA"), cascade.dcaV0daughters() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/AfterSelection/hLaDecayRadius"), cascade.v0radius()); + histos.fill(HIST("reconstructedCandidates/Cascade/AfterSelection/hLaMassWindow"), cascade.mLambda()); + histos.fill(HIST("reconstructedCandidates/Cascade/AfterSelection/hLaCosPA"), cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); + histos.fill(HIST("reconstructedCandidates/Cascade/AfterSelection/hCascDauDCA"), cascade.dcacascdaughters() * ToMicrons); + histos.fill(HIST("reconstructedCandidates/Cascade/AfterSelection/hCascDecayLength"), normalizedDecayLength); + histos.fill(HIST("reconstructedCandidates/Cascade/AfterSelection/hCascDecayRadius"), cascade.cascradius()); + histos.fill(HIST("reconstructedCandidates/Cascade/AfterSelection/hCascCosPA"), cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + if (cascade.sign() < 0) { + histos.fill(HIST("reconstructedCandidates/Cascade/hMassSelectedXiCandidates"), cascade.mXi()); + histos.fill(HIST("reconstructedCandidates/Cascade/hMassSelectedOmegaCandidates"), cascade.mOmega()); + histos.fill(HIST("reconstructedCandidates/Cascade/h3dXiCandidates"), cascade.pt(), cascade.eta(), cascade.mXi()); + histos.fill(HIST("reconstructedCandidates/Cascade/h3dOmegaCandidates"), cascade.pt(), cascade.eta(), cascade.mOmega()); + } else { + histos.fill(HIST("reconstructedCandidates/Cascade/hMassSelectedAntiXiCandidates"), cascade.mXi()); + histos.fill(HIST("reconstructedCandidates/Cascade/hMassSelectedAntiOmegaCandidates"), cascade.mOmega()); + histos.fill(HIST("reconstructedCandidates/Cascade/h3dAntiXiCandidates"), cascade.pt(), cascade.eta(), cascade.mXi()); + histos.fill(HIST("reconstructedCandidates/Cascade/h3dAntiOmegaCandidates"), cascade.pt(), cascade.eta(), cascade.mOmega()); } } } diff --git a/Common/Core/EventPlaneHelper.cxx b/Common/Core/EventPlaneHelper.cxx index 9ffd39538a4..49fd347c8a1 100644 --- a/Common/Core/EventPlaneHelper.cxx +++ b/Common/Core/EventPlaneHelper.cxx @@ -61,7 +61,7 @@ double EventPlaneHelper::GetPhiFV0(int chno, o2::fv0::Geometry* fv0geom) return TMath::ATan2(chPos.y + offsetY, chPos.x + offsetX); } -double EventPlaneHelper::GetPhiFT0(int chno, o2::ft0::Geometry ft0geom) +double EventPlaneHelper::GetPhiFT0(int chno, const o2::ft0::Geometry& ft0geom) { /* Calculate the azimuthal angle in FT0 for the channel number 'chno'. The offset of FT0-A is taken into account if chno is between 0 and 95. */ @@ -74,14 +74,12 @@ double EventPlaneHelper::GetPhiFT0(int chno, o2::ft0::Geometry ft0geom) offsetY = mOffsetFT0AY; } - ft0geom.calculateChannelCenter(); auto chPos = ft0geom.getChannelCenter(chno); - /// printf("Channel id: %d X: %.3f Y: %.3f\n", chno, chPos.X(), chPos.Y()); return TMath::ATan2(chPos.Y() + offsetY, chPos.X() + offsetX); } -void EventPlaneHelper::SumQvectors(int det, int chno, float ampl, int nmod, TComplex& Qvec, float& sum, o2::ft0::Geometry ft0geom, o2::fv0::Geometry* fv0geom) +void EventPlaneHelper::SumQvectors(int det, int chno, float ampl, int nmod, TComplex& Qvec, float& sum, const o2::ft0::Geometry& ft0geom, o2::fv0::Geometry* fv0geom) { /* Calculate the complex Q-vector for the provided detector and channel number, before adding it to the total Q-vector given as argument. */ diff --git a/Common/Core/EventPlaneHelper.h b/Common/Core/EventPlaneHelper.h index 820af4336c2..1b1cc470db2 100644 --- a/Common/Core/EventPlaneHelper.h +++ b/Common/Core/EventPlaneHelper.h @@ -60,12 +60,12 @@ class EventPlaneHelper } // Methods to calculate the azimuthal angles for each part of FIT, given the channel number. - double GetPhiFT0(int chno, o2::ft0::Geometry ft0geom); + double GetPhiFT0(int chno, const o2::ft0::Geometry& ft0geom); double GetPhiFV0(int chno, o2::fv0::Geometry* fv0geom); // Method to get the Q-vector and sum of amplitudes for any channel in FIT, given // the detector and amplitude. - void SumQvectors(int det, int chno, float ampl, int nmod, TComplex& Qvec, float& sum, o2::ft0::Geometry ft0geom, o2::fv0::Geometry* fv0geom); + void SumQvectors(int det, int chno, float ampl, int nmod, TComplex& Qvec, float& sum, const o2::ft0::Geometry& ft0geom, o2::fv0::Geometry* fv0geom); // Method to get the bin corresponding to a centrality percentile, according to the // centClasses[] array defined in Tasks/qVectorsQA.cxx. diff --git a/Common/Core/TrackSelection.cxx b/Common/Core/TrackSelection.cxx index 6fe7a2e162b..6d73fb22d20 100644 --- a/Common/Core/TrackSelection.cxx +++ b/Common/Core/TrackSelection.cxx @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -27,12 +26,11 @@ bool TrackSelection::FulfillsITSHitRequirements(uint8_t itsClusterMap) const { - constexpr uint8_t bit = 1; - for (auto& itsRequirement : mRequiredITSHits) { - auto hits = std::count_if(itsRequirement.second.begin(), itsRequirement.second.end(), [&](auto&& requiredLayer) { return itsClusterMap & (bit << requiredLayer); }); - if ((itsRequirement.first == -1) && (hits > 0)) { + for (const auto& [minHits, layerMask] : mRequiredITSHits) { + int hits = __builtin_popcount(itsClusterMap & layerMask); + if ((minHits == -1) && (hits > 0)) { return false; // no hits were required in specified layers - } else if (hits < itsRequirement.first) { + } else if (hits < minHits) { return false; // not enough hits found in specified layers } } @@ -128,12 +126,20 @@ void TrackSelection::SetMaxDcaXYPtDep(std::function ptDepCut) void TrackSelection::SetRequireHitsInITSLayers(int8_t minNRequiredHits, std::set requiredLayers) { // layer 0 corresponds to the the innermost ITS layer - mRequiredITSHits.push_back(std::make_pair(minNRequiredHits, requiredLayers)); + uint8_t mask = 0; + for (const auto& layer : requiredLayers) { + mask |= (1u << layer); + } + mRequiredITSHits.push_back(std::make_pair(minNRequiredHits, mask)); LOG(info) << "Track selection, set require hits in ITS layers: " << static_cast(minNRequiredHits); } void TrackSelection::SetRequireNoHitsInITSLayers(std::set excludedLayers) { - mRequiredITSHits.push_back(std::make_pair(-1, excludedLayers)); + uint8_t mask = 0; + for (const auto& layer : excludedLayers) { + mask |= (1u << layer); + } + mRequiredITSHits.push_back(std::make_pair(-1, mask)); LOG(info) << "Track selection, set require no hits in ITS layers"; } diff --git a/Common/Core/TrackSelection.h b/Common/Core/TrackSelection.h index 5f8590cb85f..b803b3a33ff 100644 --- a/Common/Core/TrackSelection.h +++ b/Common/Core/TrackSelection.h @@ -268,10 +268,10 @@ class TrackSelection bool mRequireTPCRefit{false}; // require refit in TPC bool mRequireGoldenChi2{false}; // require golden chi2 cut (Run 2 only) - // vector of ITS requirements (minNRequiredHits in specific requiredLayers) - std::vector>> mRequiredITSHits{}; + // vector of ITS requirements (minNRequiredHits, bitmask of requiredLayers) + std::vector> mRequiredITSHits{}; - ClassDefNV(TrackSelection, 1); + ClassDefNV(TrackSelection, 2); }; #endif // COMMON_CORE_TRACKSELECTION_H_ diff --git a/Common/Core/fwdtrackUtilities.h b/Common/Core/fwdtrackUtilities.h index 53d5f74f931..8a06179f68d 100644 --- a/Common/Core/fwdtrackUtilities.h +++ b/Common/Core/fwdtrackUtilities.h @@ -18,7 +18,6 @@ #ifndef COMMON_CORE_FWDTRACKUTILITIES_H_ #define COMMON_CORE_FWDTRACKUTILITIES_H_ -#include #include #include #include @@ -29,6 +28,7 @@ #include #include +#include #include #include #include @@ -48,6 +48,16 @@ using SMatrix55 = ROOT::Math::SMatrix; using SMatrix5 = ROOT::Math::SVector; +template +concept is_fwd_track = requires(T t) { + { t.rAtAbsorberEnd() } -> std::same_as; +}; + +template +concept is_fwd_cov = requires(T t) { + { t.sigmaX() } -> std::same_as; +}; + /// Produce TrackParCovFwds for MFT and FwdTracks, w/ or w/o cov, with z shift template o2::track::TrackParCovFwd getTrackParCovFwdShift(TFwdTrack const& track, float zshift, TCovariance const&... covOpt) @@ -55,7 +65,7 @@ o2::track::TrackParCovFwd getTrackParCovFwdShift(TFwdTrack const& track, float z double chi2 = track.chi2(); if constexpr (sizeof...(covOpt) == 0) { // No covariance passed - if constexpr (std::is_same_v, aod::FwdTracks::iterator>) { + if constexpr (is_fwd_track) { if (track.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { chi2 = track.chi2() * (2.f * track.nClusters() - 5.f); } @@ -63,7 +73,7 @@ o2::track::TrackParCovFwd getTrackParCovFwdShift(TFwdTrack const& track, float z } else { // Covariance passed using TCov = std::decay_t; - if constexpr (std::is_same_v) { + if constexpr (is_fwd_cov) { if (track.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { chi2 = track.chi2() * (2.f * track.nClusters() - 5.f); } diff --git a/Common/Core/trackUtilities.h b/Common/Core/trackUtilities.h index 26f55491f05..a713675c6a9 100644 --- a/Common/Core/trackUtilities.h +++ b/Common/Core/trackUtilities.h @@ -20,12 +20,11 @@ #include "Common/Core/RecoDecay.h" #include +#include #include #include #include -#include - #include #include // std::move diff --git a/Common/DataModel/FwdTrackReAlignTables.h b/Common/DataModel/FwdTrackReAlignTables.h index 199a9c994c0..879d3fe7486 100644 --- a/Common/DataModel/FwdTrackReAlignTables.h +++ b/Common/DataModel/FwdTrackReAlignTables.h @@ -72,6 +72,19 @@ using FwdTrackRealign = FwdTracksReAlign::iterator; using FwdTrkCovRealign = FwdTrksCovReAlign::iterator; using FullFwdTracksRealign = soa::Join; using FullFwdTrackRealign = FullFwdTracksRealign::iterator; + +// ambiguity table for realigned muons +namespace fwdtrackrealignambiguous +{ +DECLARE_SOA_INDEX_COLUMN_FULL(FwdTrackRealign, fwdTrackRealign, int, FwdTracksReAlign, ""); //! FwdTracksReAlign index +DECLARE_SOA_SLICE_INDEX_COLUMN(BC, bc); + +} // namespace fwdtrackrealignambiguous + +DECLARE_SOA_TABLE(AmbiguousFwdTrksReAlign, "AOD", "AMBIFWDREALIGN", //! Table for FwdTracksReAlign which are not associated with a collision + o2::soa::Index<>, fwdtrackrealignambiguous::FwdTrackRealignId, fwdtrackrealignambiguous::BCIdSlice); + +using AmbiguousFwdTrkRealign = AmbiguousFwdTrksReAlign::iterator; } // namespace o2::aod #endif // COMMON_DATAMODEL_FWDTRACKREALIGNTABLES_H_ diff --git a/Common/DataModel/Multiplicity.h b/Common/DataModel/Multiplicity.h index 0d04cfc2a14..c2bdd2c6a75 100644 --- a/Common/DataModel/Multiplicity.h +++ b/Common/DataModel/Multiplicity.h @@ -100,8 +100,9 @@ DECLARE_SOA_COLUMN(TimeToNext, timeToNext, float); //! DECLARE_SOA_COLUMN(TimeToNeNext, timeToNeNext, float); //! // Extra information from FIT detectors -DECLARE_SOA_COLUMN(MultFV0AOuter, multFV0AOuter, float); //! FV0 without innermost ring DECLARE_SOA_COLUMN(FT0TriggerMask, ft0TriggerMask, uint8_t); //! +DECLARE_SOA_COLUMN(MultFV0AOuter, multFV0AOuter, float); //! FV0 without innermost ring +DECLARE_SOA_COLUMN(MultFT0AOuter, multFT0AOuter, float); //! FT0A without innermost ring } // namespace mult DECLARE_SOA_TABLE(FV0Mults, "AOD", "FV0MULT", //! Multiplicity with the FV0 detector @@ -260,7 +261,7 @@ DECLARE_SOA_COLUMN(MultCollidingBC, multCollidingBC, bool); //! CTP tri DECLARE_SOA_COLUMN(MultFT0PosZ, multFT0PosZ, float); //! Position along Z computed with the FT0 information within the BC DECLARE_SOA_COLUMN(MultFT0PosZValid, multFT0PosZValid, bool); //! Validity of the position along Z computed with the FT0 information } // namespace mult -DECLARE_SOA_TABLE(MultBCs, "AOD", "MULTBC", //! +DECLARE_SOA_TABLE(MultBCs_000, "AOD", "MULTBC", //! mult::MultFT0A, mult::MultFT0C, mult::MultFT0PosZ, @@ -283,11 +284,44 @@ DECLARE_SOA_TABLE(MultBCs, "AOD", "MULTBC", //! mult::MultCollidingBC, timestamp::Timestamp, bc::Flags); -using MultBC = MultBCs::iterator; -DECLARE_SOA_TABLE(MultBcSel, "AOD", "MULTBCSEL", //! BC selection bits joinable with multBCs +DECLARE_SOA_TABLE_VERSIONED(MultBCs_001, "AOD", "MULTBC", 1, //! + mult::MultFT0A, + mult::MultFT0C, + mult::MultFV0A, + mult::MultFDDA, + mult::MultFDDC, + mult::MultZNA, + mult::MultZNC, + mult::MultZEM1, + mult::MultZEM2, + mult::MultZPA, + mult::MultZPC, + mult::MultFV0AOuter, + mult::MultFT0AOuter); + +DECLARE_SOA_TABLE(MultBcSel_000, "AOD", "MULTBCSEL", //! BC selection bits joinable with multBCs evsel::Selection); +DECLARE_SOA_TABLE_VERSIONED(MultBcSel_001, "AOD", "MULTBCSEL", 1, //! BC selection bits joinable with multBCs + evsel::Selection, + evsel::Rct, + bc::Flags, + timestamp::Timestamp, + mult::MultFT0PosZ, + mult::MultFT0PosZValid, + mult::MultV0triggerBits, + mult::MultT0triggerBits, + mult::MultFDDtriggerBits, + mult::MultTriggerMask, + mult::MultCollidingBC, + mult::MultTVX, + mult::MultFV0OrA); + +using MultBCs = MultBCs_001; +using MultBcSel = MultBcSel_001; +using MultBC = MultBCs::iterator; + // crosslinks namespace mult { diff --git a/Common/TableProducer/CMakeLists.txt b/Common/TableProducer/CMakeLists.txt index 26af3c092f1..6526cb41772 100644 --- a/Common/TableProducer/CMakeLists.txt +++ b/Common/TableProducer/CMakeLists.txt @@ -34,11 +34,6 @@ o2physics_add_dpl_workflow(event-selection-service-run2 O2::DataFormatsITSMFT COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(multiplicity-table - SOURCES multiplicityTable.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(multcenttable SOURCES multCentTable.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -49,16 +44,6 @@ o2physics_add_dpl_workflow(multiplicity-extra-table PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(centrality-table - SOURCES centralityTable.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(timestamp - SOURCES timestamp.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(weak-decay-indices SOURCES weakDecayIndices.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -69,12 +54,6 @@ o2physics_add_dpl_workflow(ft0-corrected-table PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(track-propagation - SOURCES trackPropagation.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - - o2physics_add_dpl_workflow(propagationservice SOURCES propagationService.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DCAFitter KFParticle::KFParticle O2Physics::TPCDriftManager diff --git a/Common/TableProducer/Converters/CMakeLists.txt b/Common/TableProducer/Converters/CMakeLists.txt index 34ddc8efb3e..a8b14efaca3 100644 --- a/Common/TableProducer/Converters/CMakeLists.txt +++ b/Common/TableProducer/Converters/CMakeLists.txt @@ -113,3 +113,8 @@ o2physics_add_dpl_workflow(run2-tiny-to-full-pid SOURCES run2TinyToFullPID.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(mult-bcs-converter + SOURCES multBCsConverter.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/Common/TableProducer/Converters/multBCsConverter.cxx b/Common/TableProducer/Converters/multBCsConverter.cxx new file mode 100644 index 00000000000..c660b759832 --- /dev/null +++ b/Common/TableProducer/Converters/multBCsConverter.cxx @@ -0,0 +1,74 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file multBCsConverter.cxx +/// \brief Converts MultBCs and MultBcSel table from version 000 to 001 +/// \author Jesper Karlsson Gumrpecht + +#include "Common/DataModel/Multiplicity.h" + +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; + +struct MultBCsConverter { + Produces multBC; + Produces multBcSel; + + static constexpr float DummyValue = -1.f; + static constexpr int DummyRct = 0; + void process(soa::Join const& multBCs) + { + multBC.reserve(multBCs.size()); + multBcSel.reserve(multBCs.size()); + for (const auto& multbc : multBCs) { + multBC( + multbc.multFT0A(), + multbc.multFT0C(), + multbc.multFV0A(), + multbc.multFDDA(), + multbc.multFDDC(), + multbc.multZNA(), + multbc.multZNC(), + multbc.multZEM1(), + multbc.multZEM2(), + multbc.multZPA(), + multbc.multZPC(), + DummyValue, // dummy amplitude for FV0A Outer + DummyValue); // dummy amplitude for FT0A Outer + + multBcSel( + multbc.selection_raw(), + DummyRct, // all flags to false + multbc.flags(), + multbc.timestamp(), + multbc.multFT0PosZ(), + multbc.multFT0PosZValid(), + multbc.multV0triggerBits(), + multbc.multT0triggerBits(), + multbc.multFDDtriggerBits(), + multbc.multTriggerMask(), + multbc.multCollidingBC(), + multbc.multTVX(), + multbc.multFV0OrA()); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/Common/TableProducer/centralityTable.cxx b/Common/TableProducer/centralityTable.cxx deleted file mode 100644 index 26fc9dab09a..00000000000 --- a/Common/TableProducer/centralityTable.cxx +++ /dev/null @@ -1,795 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -// -/// \file centralityTable.cxx -/// \brief Task to produce the centrality tables associated to each of the required centrality estimators -/// -/// \author ALICE -// - -#include "Common/Core/MetadataHelper.h" -#include "Common/Core/TableHelper.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace o2; -using namespace o2::framework; - -o2::common::core::MetadataHelper metadataInfo; // Metadata helper - -static constexpr int kCentRun2V0Ms = 0; -static constexpr int kCentRun2V0As = 1; -static constexpr int kCentRun2SPDTrks = 2; -static constexpr int kCentRun2SPDClss = 3; -static constexpr int kCentRun2CL0s = 4; -static constexpr int kCentRun2CL1s = 5; -static constexpr int kCentFV0As = 6; -static constexpr int kCentFT0Ms = 7; -static constexpr int kCentFT0As = 8; -static constexpr int kCentFT0Cs = 9; -static constexpr int kCentFT0CVariant1s = 10; -static constexpr int kCentFDDMs = 11; -static constexpr int kCentNTPVs = 12; -static constexpr int kCentNGlobals = 13; -static constexpr int kCentMFTs = 14; -static constexpr int NTables = 15; -static constexpr int NParameters = 1; -static const std::vector tableNames{"CentRun2V0Ms", - "CentRun2V0As", - "CentRun2SPDTrks", - "CentRun2SPDClss", - "CentRun2CL0s", - "CentRun2CL1s", - "CentFV0As", - "CentFT0Ms", - "CentFT0As", - "CentFT0Cs", - "CentFT0CVariant1s", - "CentFDDMs", - "CentNTPVs", - "CentNGlobals", - "CentMFTs"}; -static const std::vector parameterNames{"Enable"}; -static const int defaultParameters[NTables][NParameters]{{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}}; - -struct CentralityTable { - Produces centRun2V0M; - Produces centRun2V0A; - Produces centRun2SPDTracklets; - Produces centRun2SPDClusters; - Produces centRun2CL0; - Produces centRun2CL1; - Produces centFV0A; - Produces centFT0M; - Produces centFT0A; - Produces centFT0C; - Produces centFT0CVariant1; - Produces centFDDM; - Produces centNTPV; - Produces centNGlobals; - Produces centMFTs; - Service ccdb; - Configurable> enabledTables{"enabledTables", - {defaultParameters[0], NTables, NParameters, tableNames, parameterNames}, - "Produce tables depending on needs. Values different than -1 override the automatic setup: the corresponding table can be set off (0) or on (1)"}; - struct : ConfigurableGroup { - Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "The CCDB endpoint url address"}; - Configurable ccdbPath{"ccdbPath", "Centrality/Estimators", "The CCDB path for centrality/multiplicity information"}; - Configurable genName{"genName", "", "Genearator name: HIJING, PYTHIA8, ... Default: \"\""}; - Configurable doNotCrashOnNull{"doNotCrashOnNull", false, {"Option to not crash on null and instead fill required tables with dummy info"}}; - Configurable reconstructionPass{"reconstructionPass", "", {"Apass to use when fetching the calibration tables. Empty (default) does not check for any pass. Use `metadata` to fetch it from the AO2D metadata. Otherwise it will override the metadata."}}; - } ccdbConfig; - - Configurable embedINELgtZEROselection{"embedINELgtZEROselection", false, {"Option to do percentile 100.5 if not INELgtZERO"}}; - Configurable produceHistograms{"produceHistograms", false, {"Option to produce debug histograms"}}; - ConfigurableAxis binsPercentile{"binsPercentile", {VARIABLE_WIDTH, 0, 0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009, 0.01, 0.011, 0.012, 0.013, 0.014, 0.015, 0.016, 0.017, 0.018, 0.019, 0.02, 0.021, 0.022, 0.023, 0.024, 0.025, 0.026, 0.027, 0.028, 0.029, 0.03, 0.031, 0.032, 0.033, 0.034, 0.035, 0.036, 0.037, 0.038, 0.039, 0.04, 0.041, 0.042, 0.043, 0.044, 0.045, 0.046, 0.047, 0.048, 0.049, 0.05, 0.051, 0.052, 0.053, 0.054, 0.055, 0.056, 0.057, 0.058, 0.059, 0.06, 0.061, 0.062, 0.063, 0.064, 0.065, 0.066, 0.067, 0.068, 0.069, 0.07, 0.071, 0.072, 0.073, 0.074, 0.075, 0.076, 0.077, 0.078, 0.079, 0.08, 0.081, 0.082, 0.083, 0.084, 0.085, 0.086, 0.087, 0.088, 0.089, 0.09, 0.091, 0.092, 0.093, 0.094, 0.095, 0.096, 0.097, 0.098, 0.099, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.4, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.5, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.6, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.7, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.8, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.9, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 5.0, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9, 6.0, 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 6.8, 6.9, 7.0, 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7, 7.8, 7.9, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, 8.9, 9.0, 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.8, 9.9, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0, 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0, 100.0}, "Binning of the percentile axis"}; - ConfigurableAxis binsPVcontr{"binsPVcontr", {100, 0.f, 100.f}, "PV mult."}; - - int mRunNumber; - struct TagRun2V0MCalibration { - bool mCalibrationStored = false; - TFormula* mMCScale = nullptr; - float mMCScalePars[6] = {0.0}; - TH1* mhVtxAmpCorrV0A = nullptr; - TH1* mhVtxAmpCorrV0C = nullptr; - TH1* mhMultSelCalib = nullptr; - } Run2V0MInfo; - struct TagRun2V0ACalibration { - bool mCalibrationStored = false; - TH1* mhVtxAmpCorrV0A = nullptr; - TH1* mhMultSelCalib = nullptr; - } Run2V0AInfo; - struct TagRun2SPDTrackletsCalibration { - bool mCalibrationStored = false; - TH1* mhVtxAmpCorr = nullptr; - TH1* mhMultSelCalib = nullptr; - } Run2SPDTksInfo; - struct TagRun2SPDClustersCalibration { - bool mCalibrationStored = false; - TH1* mhVtxAmpCorrCL0 = nullptr; - TH1* mhVtxAmpCorrCL1 = nullptr; - TH1* mhMultSelCalib = nullptr; - } Run2SPDClsInfo; - struct TagRun2CL0Calibration { - bool mCalibrationStored = false; - TH1* mhVtxAmpCorr = nullptr; - TH1* mhMultSelCalib = nullptr; - } Run2CL0Info; - struct TagRun2CL1Calibration { - bool mCalibrationStored = false; - TH1* mhVtxAmpCorr = nullptr; - TH1* mhMultSelCalib = nullptr; - } Run2CL1Info; - struct CalibrationInfo { - std::string name = ""; - bool mCalibrationStored = false; - TH1* mhMultSelCalib = nullptr; - float mMCScalePars[6] = {0.0}; - TFormula* mMCScale = nullptr; - explicit CalibrationInfo(std::string name) - : name(name), - mCalibrationStored(false), - mhMultSelCalib(nullptr), - mMCScalePars{0.0}, - mMCScale(nullptr) - { - } - bool isSane(bool fatalize = false) - { - if (!mhMultSelCalib) { - return true; - } - for (int i = 1; i < mhMultSelCalib->GetNbinsX() + 1; i++) { - if (mhMultSelCalib->GetXaxis()->GetBinLowEdge(i) > mhMultSelCalib->GetXaxis()->GetBinUpEdge(i)) { - if (fatalize) { - LOG(fatal) << "Centrality calibration table " << name << " has bins with low edge > up edge"; - } - LOG(warning) << "Centrality calibration table " << name << " has bins with low edge > up edge"; - return false; - } - } - return true; - } - }; - CalibrationInfo fv0aInfo = CalibrationInfo("FV0"); - CalibrationInfo ft0mInfo = CalibrationInfo("FT0"); - CalibrationInfo ft0aInfo = CalibrationInfo("FT0A"); - CalibrationInfo ft0cInfo = CalibrationInfo("FT0C"); - CalibrationInfo ft0cVariant1Info = CalibrationInfo("FT0Cvar1"); - CalibrationInfo fddmInfo = CalibrationInfo("FDD"); - CalibrationInfo ntpvInfo = CalibrationInfo("NTracksPV"); - CalibrationInfo nGlobalInfo = CalibrationInfo("NGlobal"); - CalibrationInfo mftInfo = CalibrationInfo("MFT"); - std::vector mEnabledTables; // Vector of enabled tables - std::array isTableEnabled; - - // Debug output - HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - OutputObj listCalib{"calib-list", OutputObjHandlingPolicy::QAObject}; - - void init(InitContext& context) - { - LOG(info) << "Initializing centrality table producer"; - if (doprocessRun3FT0 == true) { - LOG(fatal) << "FT0 only mode is automatically enabled in Run3 mode. Please disable it and enable processRun3."; - } - if (doprocessRun2 == false && doprocessRun3 == false && doprocessRun3Complete == false) { - LOGF(fatal, "Neither processRun2 nor processRun3 nor processRun3Complete enabled. Please choose one."); - } - if (doprocessRun2 == true && doprocessRun3 == true) { - LOGF(fatal, "Cannot enable processRun2 and processRun3 at the same time. Please choose one."); - } - - /* Checking the tables which are requested in the workflow and enabling them */ - for (int i = 0; i < NTables; i++) { - int f = enabledTables->get(tableNames[i].c_str(), "Enable"); - o2::common::core::enableFlagIfTableRequired(context, tableNames[i], f); - if (f == 1) { - if (tableNames[i].find("Run2") != std::string::npos) { - if (doprocessRun3) { - LOG(fatal) << "Cannot enable Run2 table `" << tableNames[i] << "` while running in Run3 mode. Please check and disable them."; - } - } else { - if (doprocessRun2) { - LOG(fatal) << "Cannot enable Run3 table `" << tableNames[i] << "` while running in Run2 mode. Please check and disable them."; - } - } - isTableEnabled[i] = true; - mEnabledTables.push_back(i); - } - } - - if (mEnabledTables.size() == 0) { - LOGF(fatal, "No table enabled. Please enable at least one table."); - } - std::sort(mEnabledTables.begin(), mEnabledTables.end()); - - // Check if FT0 is the only centrality needed - if (mEnabledTables.size() == 1 && isTableEnabled[kCentFT0Ms] == true) { - LOG(info) << "FT0 only mode is enabled"; - doprocessRun3FT0.value = true; - doprocessRun3.value = false; - } - - ccdb->setURL(ccdbConfig.ccdbUrl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); - mRunNumber = 0; - listCalib.setObject(new TList); - if (!produceHistograms.value) { - return; - } - - histos.add("FT0M/percentile", "FT0M percentile.", HistType::kTH1D, {{binsPercentile, "FT0M percentile"}}); - histos.add("FT0M/percentilevsPV", "percentile vs PV mult.", HistType::kTH2D, {{binsPercentile, "FT0M percentile"}, {binsPVcontr, "PV mult."}}); - histos.add("FT0M/MultvsPV", "FT0M mult. vs PV mult.", HistType::kTH2D, {{1000, 0, 5000, "FT0M mult."}, {binsPVcontr, "PV mult."}}); - - histos.add("FT0A/percentile", "FT0A percentile.", HistType::kTH1D, {{binsPercentile, "FT0A percentile"}}); - histos.add("FT0A/percentilevsPV", "percentile vs PV mult.", HistType::kTH2D, {{binsPercentile, "FT0A percentile"}, {binsPVcontr, "PV mult."}}); - histos.add("FT0A/MultvsPV", "FT0A mult. vs PV mult.", HistType::kTH2D, {{1000, 0, 5000, "FT0A mult."}, {binsPVcontr, "PV mult."}}); - - histos.add("FT0C/percentile", "FT0C percentile.", HistType::kTH1D, {{binsPercentile, "FT0C percentile"}}); - histos.add("FT0C/percentilevsPV", "percentile vs PV mult.", HistType::kTH2D, {{binsPercentile, "FT0C percentile"}, {binsPVcontr, "PV mult."}}); - histos.add("FT0C/MultvsPV", "FT0C mult. vs PV mult.", HistType::kTH2D, {{1000, 0, 5000, "FT0C mult."}, {binsPVcontr, "PV mult."}}); - - histos.addClone("FT0M/", "sel8FT0M/"); - histos.addClone("FT0C/", "sel8FT0C/"); - histos.addClone("FT0A/", "sel8FT0A/"); - - histos.print(); - } - - using BCsWithTimestampsAndRun2Infos = soa::Join; - - void processRun2(soa::Join::iterator const& collision, BCsWithTimestampsAndRun2Infos const&) - { - /* check the previous run number */ - auto bc = collision.bc_as(); - if (bc.runNumber() != mRunNumber) { - mRunNumber = bc.runNumber(); // mark that this run has been attempted already regardless of outcome - LOGF(debug, "timestamp=%llu", bc.timestamp()); - TList* callst = nullptr; - if (ccdbConfig.reconstructionPass.value == "") { - callst = ccdb->getForRun(ccdbConfig.ccdbPath, bc.runNumber()); - } else if (ccdbConfig.reconstructionPass.value == "metadata") { - std::map metadata; - metadata["RecoPassName"] = metadataInfo.get("RecoPassName"); - LOGF(info, "Loading CCDB for reconstruction pass (from metadata): %s", metadataInfo.get("RecoPassName")); - callst = ccdb->getSpecificForRun(ccdbConfig.ccdbPath, bc.runNumber(), metadata); - } else { - std::map metadata; - metadata["RecoPassName"] = ccdbConfig.reconstructionPass.value; - LOGF(info, "Loading CCDB for reconstruction pass (from provided argument): %s", ccdbConfig.reconstructionPass.value); - callst = ccdb->getSpecificForRun(ccdbConfig.ccdbPath, bc.runNumber(), metadata); - } - - Run2V0MInfo.mCalibrationStored = false; - Run2V0AInfo.mCalibrationStored = false; - Run2SPDTksInfo.mCalibrationStored = false; - Run2SPDClsInfo.mCalibrationStored = false; - Run2CL0Info.mCalibrationStored = false; - Run2CL1Info.mCalibrationStored = false; - if (callst != nullptr) { - auto getccdb = [callst](const char* ccdbhname) { - TH1* h = reinterpret_cast(callst->FindObject(ccdbhname)); - return h; - }; - auto getformulaccdb = [callst](const char* ccdbhname) { - TFormula* f = reinterpret_cast(callst->FindObject(ccdbhname)); - return f; - }; - if (isTableEnabled[kCentRun2V0Ms]) { - LOGF(debug, "Getting new histograms with %d run number for %d run number", mRunNumber, bc.runNumber()); - Run2V0MInfo.mhVtxAmpCorrV0A = getccdb("hVtx_fAmplitude_V0A_Normalized"); - Run2V0MInfo.mhVtxAmpCorrV0C = getccdb("hVtx_fAmplitude_V0C_Normalized"); - Run2V0MInfo.mhMultSelCalib = getccdb("hMultSelCalib_V0M"); - Run2V0MInfo.mMCScale = getformulaccdb(TString::Format("%s-V0M", ccdbConfig.genName->c_str()).Data()); - if ((Run2V0MInfo.mhVtxAmpCorrV0A != nullptr) && (Run2V0MInfo.mhVtxAmpCorrV0C != nullptr) && (Run2V0MInfo.mhMultSelCalib != nullptr)) { - if (ccdbConfig.genName->length() != 0) { - if (Run2V0MInfo.mMCScale != nullptr) { - for (int ixpar = 0; ixpar < 6; ++ixpar) { - Run2V0MInfo.mMCScalePars[ixpar] = Run2V0MInfo.mMCScale->GetParameter(ixpar); - } - } else { - if (!ccdbConfig.doNotCrashOnNull) { // default behaviour: crash - LOGF(fatal, "MC Scale information from V0M for run %d not available", bc.runNumber()); - } else { // only if asked: continue filling with non-valid values (105) - LOGF(info, "MC Scale information from V0M for run %d not available", bc.runNumber()); - } - } - } - Run2V0MInfo.mCalibrationStored = true; - } else { - if (!ccdbConfig.doNotCrashOnNull) { // default behaviour: crash - LOGF(fatal, "Calibration information from V0M for run %d corrupted", bc.runNumber()); - } else { // only if asked: continue filling with non-valid values (105) - LOGF(info, "Calibration information from V0M for run %d corrupted, will fill V0M tables with dummy values", bc.runNumber()); - } - } - } - if (isTableEnabled[kCentRun2V0As]) { - LOGF(debug, "Getting new histograms with %d run number for %d run number", mRunNumber, bc.runNumber()); - Run2V0AInfo.mhVtxAmpCorrV0A = getccdb("hVtx_fAmplitude_V0A_Normalized"); - Run2V0AInfo.mhMultSelCalib = getccdb("hMultSelCalib_V0A"); - if ((Run2V0AInfo.mhVtxAmpCorrV0A != nullptr) && (Run2V0AInfo.mhMultSelCalib != nullptr)) { - Run2V0AInfo.mCalibrationStored = true; - } else { - if (!ccdbConfig.doNotCrashOnNull) { // default behaviour: crash - LOGF(fatal, "Calibration information from V0A for run %d corrupted", bc.runNumber()); - } else { // only if asked: continue filling with non-valid values (105) - LOGF(info, "Calibration information from V0A for run %d corrupted, will fill V0A tables with dummy values", bc.runNumber()); - } - } - } - if (isTableEnabled[kCentRun2SPDTrks]) { - LOGF(debug, "Getting new histograms with %d run number for %d run number", mRunNumber, bc.runNumber()); - Run2SPDTksInfo.mhVtxAmpCorr = getccdb("hVtx_fnTracklets_Normalized"); - Run2SPDTksInfo.mhMultSelCalib = getccdb("hMultSelCalib_SPDTracklets"); - if ((Run2SPDTksInfo.mhVtxAmpCorr != nullptr) && (Run2SPDTksInfo.mhMultSelCalib != nullptr)) { - Run2SPDTksInfo.mCalibrationStored = true; - } else { - if (!ccdbConfig.doNotCrashOnNull) { // default behaviour: crash - LOGF(fatal, "Calibration information from SPD tracklets for run %d corrupted", bc.runNumber()); - } else { // only if asked: continue filling with non-valid values (105) - LOGF(info, "Calibration information from SPD tracklets for run %d corrupted, will fill SPD tracklets tables with dummy values", bc.runNumber()); - } - } - } - if (isTableEnabled[kCentRun2SPDClss]) { - LOGF(debug, "Getting new histograms with %d run number for %d run number", mRunNumber, bc.runNumber()); - Run2SPDClsInfo.mhVtxAmpCorrCL0 = getccdb("hVtx_fnSPDClusters0_Normalized"); - Run2SPDClsInfo.mhVtxAmpCorrCL1 = getccdb("hVtx_fnSPDClusters1_Normalized"); - Run2SPDClsInfo.mhMultSelCalib = getccdb("hMultSelCalib_SPDClusters"); - if ((Run2SPDClsInfo.mhVtxAmpCorrCL0 != nullptr) && (Run2SPDClsInfo.mhVtxAmpCorrCL1 != nullptr) && (Run2SPDClsInfo.mhMultSelCalib != nullptr)) { - Run2SPDClsInfo.mCalibrationStored = true; - } else { - if (!ccdbConfig.doNotCrashOnNull) { // default behaviour: crash - LOGF(fatal, "Calibration information from SPD clusters for run %d corrupted", bc.runNumber()); - } else { // only if asked: continue filling with non-valid values (105) - LOGF(info, "Calibration information from SPD clusters for run %d corrupted, will fill SPD clusters tables with dummy values", bc.runNumber()); - } - } - } - if (isTableEnabled[kCentRun2CL0s]) { - LOGF(debug, "Getting new histograms with %d run number for %d run number", mRunNumber, bc.runNumber()); - Run2CL0Info.mhVtxAmpCorr = getccdb("hVtx_fnSPDClusters0_Normalized"); - Run2CL0Info.mhMultSelCalib = getccdb("hMultSelCalib_CL0"); - if ((Run2CL0Info.mhVtxAmpCorr != nullptr) && (Run2CL0Info.mhMultSelCalib != nullptr)) { - Run2CL0Info.mCalibrationStored = true; - } else { - if (!ccdbConfig.doNotCrashOnNull) { // default behaviour: crash - LOGF(fatal, "Calibration information from CL0 multiplicity for run %d corrupted", bc.runNumber()); - } else { // only if asked: continue filling with non-valid values (105) - LOGF(info, "Calibration information from CL0 multiplicity for run %d corrupted, will fill CL0 multiplicity tables with dummy values", bc.runNumber()); - } - } - } - if (isTableEnabled[kCentRun2CL1s]) { - LOGF(debug, "Getting new histograms with %d run number for %d run number", mRunNumber, bc.runNumber()); - Run2CL1Info.mhVtxAmpCorr = getccdb("hVtx_fnSPDClusters1_Normalized"); - Run2CL1Info.mhMultSelCalib = getccdb("hMultSelCalib_CL1"); - if ((Run2CL1Info.mhVtxAmpCorr != nullptr) && (Run2CL1Info.mhMultSelCalib != nullptr)) { - Run2CL1Info.mCalibrationStored = true; - } else { - if (!ccdbConfig.doNotCrashOnNull) { // default behaviour: crash - LOGF(fatal, "Calibration information from CL1 multiplicity for run %d corrupted", bc.runNumber()); - } else { // only if asked: continue filling with non-valid values (105) - LOGF(info, "Calibration information from CL1 multiplicity for run %d corrupted, will fill CL1 multiplicity tables with dummy values", bc.runNumber()); - } - } - } - } else { - if (!ccdbConfig.doNotCrashOnNull) { // default behaviour: crash - LOGF(fatal, "Centrality calibration is not available in CCDB for run=%d at timestamp=%llu", bc.runNumber(), bc.timestamp()); - } else { // only if asked: continue filling with non-valid values (105) - LOGF(info, "Centrality calibration is not available in CCDB for run=%d at timestamp=%llu, will fill tables with dummy values", bc.runNumber(), bc.timestamp()); - } - } - } - - auto scaleMC = [](float x, const float pars[6]) { - return std::pow(((pars[0] + pars[1] * std::pow(x, pars[2])) - pars[3]) / pars[4], 1.0f / pars[5]); - }; - - if (isTableEnabled[kCentRun2V0Ms]) { - float cV0M = 105.0f; - if (Run2V0MInfo.mCalibrationStored) { - float v0m; - if (Run2V0MInfo.mMCScale != nullptr) { - v0m = scaleMC(collision.multFV0M(), Run2V0MInfo.mMCScalePars); - LOGF(debug, "Unscaled v0m: %f, scaled v0m: %f", collision.multFV0M(), v0m); - } else { - v0m = collision.multFV0A() * Run2V0MInfo.mhVtxAmpCorrV0A->GetBinContent(Run2V0MInfo.mhVtxAmpCorrV0A->FindFixBin(collision.posZ())) + - collision.multFV0C() * Run2V0MInfo.mhVtxAmpCorrV0C->GetBinContent(Run2V0MInfo.mhVtxAmpCorrV0C->FindFixBin(collision.posZ())); - } - cV0M = Run2V0MInfo.mhMultSelCalib->GetBinContent(Run2V0MInfo.mhMultSelCalib->FindFixBin(v0m)); - } - LOGF(debug, "centRun2V0M=%.0f", cV0M); - // fill centrality columns - centRun2V0M(cV0M); - } - if (isTableEnabled[kCentRun2V0As]) { - float cV0A = 105.0f; - if (Run2V0AInfo.mCalibrationStored) { - float v0a = collision.multFV0A() * Run2V0AInfo.mhVtxAmpCorrV0A->GetBinContent(Run2V0AInfo.mhVtxAmpCorrV0A->FindFixBin(collision.posZ())); - cV0A = Run2V0AInfo.mhMultSelCalib->GetBinContent(Run2V0AInfo.mhMultSelCalib->FindFixBin(v0a)); - } - LOGF(debug, "centRun2V0A=%.0f", cV0A); - // fill centrality columns - centRun2V0A(cV0A); - } - if (isTableEnabled[kCentRun2SPDTrks]) { - float cSPD = 105.0f; - if (Run2SPDTksInfo.mCalibrationStored) { - float spdm = collision.multTracklets() * Run2SPDTksInfo.mhVtxAmpCorr->GetBinContent(Run2SPDTksInfo.mhVtxAmpCorr->FindFixBin(collision.posZ())); - cSPD = Run2SPDTksInfo.mhMultSelCalib->GetBinContent(Run2SPDTksInfo.mhMultSelCalib->FindFixBin(spdm)); - } - LOGF(debug, "centSPDTracklets=%.0f", cSPD); - centRun2SPDTracklets(cSPD); - } - if (isTableEnabled[kCentRun2SPDClss]) { - float cSPD = 105.0f; - if (Run2SPDClsInfo.mCalibrationStored) { - float spdm = bc.spdClustersL0() * Run2SPDClsInfo.mhVtxAmpCorrCL0->GetBinContent(Run2SPDClsInfo.mhVtxAmpCorrCL0->FindFixBin(collision.posZ())) + - bc.spdClustersL1() * Run2SPDClsInfo.mhVtxAmpCorrCL1->GetBinContent(Run2SPDClsInfo.mhVtxAmpCorrCL1->FindFixBin(collision.posZ())); - cSPD = Run2SPDClsInfo.mhMultSelCalib->GetBinContent(Run2SPDClsInfo.mhMultSelCalib->FindFixBin(spdm)); - } - LOGF(debug, "centSPDClusters=%.0f", cSPD); - centRun2SPDClusters(cSPD); - } - if (isTableEnabled[kCentRun2CL0s]) { - float cCL0 = 105.0f; - if (Run2CL0Info.mCalibrationStored) { - float cl0m = bc.spdClustersL0() * Run2CL0Info.mhVtxAmpCorr->GetBinContent(Run2CL0Info.mhVtxAmpCorr->FindFixBin(collision.posZ())); - cCL0 = Run2CL0Info.mhMultSelCalib->GetBinContent(Run2CL0Info.mhMultSelCalib->FindFixBin(cl0m)); - } - LOGF(debug, "centCL0=%.0f", cCL0); - centRun2CL0(cCL0); - } - if (isTableEnabled[kCentRun2CL1s]) { - float cCL1 = 105.0f; - if (Run2CL1Info.mCalibrationStored) { - float cl1m = bc.spdClustersL1() * Run2CL1Info.mhVtxAmpCorr->GetBinContent(Run2CL1Info.mhVtxAmpCorr->FindFixBin(collision.posZ())); - cCL1 = Run2CL1Info.mhMultSelCalib->GetBinContent(Run2CL1Info.mhMultSelCalib->FindFixBin(cl1m)); - } - LOGF(debug, "centCL1=%.0f", cCL1); - centRun2CL1(cCL1); - } - } - - using BCsWithTimestamps = soa::Join; - - template - void produceRun3Tables(CollisionType const& collisions) - { - // do memory reservation for the relevant tables only, please - for (auto const& table : mEnabledTables) { - switch (table) { - case kCentFV0As: - centFV0A.reserve(collisions.size()); - break; - case kCentFT0Ms: - centFT0M.reserve(collisions.size()); - break; - case kCentFT0As: - centFT0A.reserve(collisions.size()); - break; - case kCentFT0Cs: - centFT0C.reserve(collisions.size()); - break; - case kCentFT0CVariant1s: - centFT0CVariant1.reserve(collisions.size()); - break; - case kCentFDDMs: - centFDDM.reserve(collisions.size()); - break; - case kCentNTPVs: - centNTPV.reserve(collisions.size()); - break; - case kCentNGlobals: - centNGlobals.reserve(collisions.size()); - break; - case kCentMFTs: - centMFTs.reserve(collisions.size()); - break; - default: - LOGF(fatal, "Table %d not supported in Run3", table); - break; - } - } - - for (auto const& collision : collisions) { - /* check the previous run number */ - auto bc = collision.template bc_as(); - if (bc.runNumber() != mRunNumber) { - mRunNumber = bc.runNumber(); // mark that this run has been attempted already regardless of outcome - LOGF(info, "timestamp=%llu, run number=%d", bc.timestamp(), bc.runNumber()); - TList* callst = nullptr; - // Check if the ccdb path is a root file - if (ccdbConfig.ccdbPath.value.find(".root") != std::string::npos) { - TFile f(ccdbConfig.ccdbPath.value.c_str(), "READ"); - f.GetObject(ccdbConfig.reconstructionPass.value.c_str(), callst); - if (!callst) { - f.ls(); - LOG(fatal) << "No calibration list " << ccdbConfig.reconstructionPass.value << " found in the file " << ccdbConfig.ccdbPath.value; - } - } else { - if (ccdbConfig.reconstructionPass.value == "") { - callst = ccdb->getForRun(ccdbConfig.ccdbPath, bc.runNumber()); - } else if (ccdbConfig.reconstructionPass.value == "metadata") { - std::map metadata; - metadata["RecoPassName"] = metadataInfo.get("RecoPassName"); - LOGF(info, "Loading CCDB for reconstruction pass (from metadata): %s", metadataInfo.get("RecoPassName")); - callst = ccdb->getSpecificForRun(ccdbConfig.ccdbPath, bc.runNumber(), metadata); - } else { - std::map metadata; - metadata["RecoPassName"] = ccdbConfig.reconstructionPass.value; - LOGF(info, "Loading CCDB for reconstruction pass (from provided argument): %s", ccdbConfig.reconstructionPass.value); - callst = ccdb->getSpecificForRun(ccdbConfig.ccdbPath, bc.runNumber(), metadata); - } - } - - fv0aInfo.mCalibrationStored = false; - ft0mInfo.mCalibrationStored = false; - ft0aInfo.mCalibrationStored = false; - ft0cInfo.mCalibrationStored = false; - ft0cVariant1Info.mCalibrationStored = false; - fddmInfo.mCalibrationStored = false; - ntpvInfo.mCalibrationStored = false; - nGlobalInfo.mCalibrationStored = false; - mftInfo.mCalibrationStored = false; - if (callst != nullptr) { - if (produceHistograms) { - listCalib->Add(callst->Clone(Form("%i", bc.runNumber()))); - } - LOGF(info, "Getting new histograms with %d run number for %d run number", mRunNumber, bc.runNumber()); - auto getccdb = [callst, bc](struct CalibrationInfo& estimator, const Configurable generatorName) { // TODO: to consider the name inside the estimator structure - estimator.mhMultSelCalib = reinterpret_cast(callst->FindObject(TString::Format("hCalibZeq%s", estimator.name.c_str()).Data())); - estimator.mMCScale = reinterpret_cast(callst->FindObject(TString::Format("%s-%s", generatorName->c_str(), estimator.name.c_str()).Data())); - if (estimator.mhMultSelCalib != nullptr) { - if (generatorName->length() != 0) { - LOGF(info, "Retrieving MC calibration for %d, generator name: %s", bc.runNumber(), generatorName->c_str()); - if (estimator.mMCScale != nullptr) { - for (int ixpar = 0; ixpar < 6; ++ixpar) { - estimator.mMCScalePars[ixpar] = estimator.mMCScale->GetParameter(ixpar); - LOGF(info, "Parameter index %i value %.5f", ixpar, estimator.mMCScalePars[ixpar]); - } - } else { - LOGF(warning, "MC Scale information from %s for run %d not available", estimator.name.c_str(), bc.runNumber()); - } - } - estimator.mCalibrationStored = true; - estimator.isSane(); - } else { - LOGF(info, "Calibration information from %s for run %d not available, will fill this estimator with invalid values and continue (no crash).", estimator.name.c_str(), bc.runNumber()); - } - }; - - for (auto const& table : mEnabledTables) { - switch (table) { - case kCentFV0As: - getccdb(fv0aInfo, ccdbConfig.genName); - break; - case kCentFT0Ms: - getccdb(ft0mInfo, ccdbConfig.genName); - break; - case kCentFT0As: - getccdb(ft0aInfo, ccdbConfig.genName); - break; - case kCentFT0Cs: - getccdb(ft0cInfo, ccdbConfig.genName); - break; - case kCentFT0CVariant1s: - getccdb(ft0cVariant1Info, ccdbConfig.genName); - break; - case kCentFDDMs: - getccdb(fddmInfo, ccdbConfig.genName); - break; - case kCentNTPVs: - getccdb(ntpvInfo, ccdbConfig.genName); - break; - case kCentNGlobals: - getccdb(nGlobalInfo, ccdbConfig.genName); - break; - case kCentMFTs: - getccdb(mftInfo, ccdbConfig.genName); - break; - default: - LOGF(fatal, "Table %d not supported in Run3", table); - break; - } - } - } else { - if (!ccdbConfig.doNotCrashOnNull) { // default behaviour: crash - LOGF(fatal, "Centrality calibration is not available in CCDB for run=%d at timestamp=%llu", bc.runNumber(), bc.timestamp()); - } else { // only if asked: continue filling with non-valid values (105) - LOGF(info, "Centrality calibration is not available in CCDB for run=%d at timestamp=%llu, will fill tables with dummy values", bc.runNumber(), bc.timestamp()); - } - } - } - - /** - * @brief Populates a table with data based on the given calibration information and multiplicity. - * - * @param table The table to populate. - * @param estimator The calibration information. - * @param multiplicity The multiplicity value. - */ - - auto populateTable = [&](auto& table, struct CalibrationInfo& estimator, float multiplicity) { - const bool assignOutOfRange = embedINELgtZEROselection && !collision.isInelGt0(); - auto scaleMC = [](float x, const float pars[6]) { - return std::pow(((pars[0] + pars[1] * std::pow(x, pars[2])) - pars[3]) / pars[4], 1.0f / pars[5]); - }; - - float percentile = 105.0f; - float scaledMultiplicity = multiplicity; - if (estimator.mCalibrationStored) { - if (estimator.mMCScale != nullptr) { - scaledMultiplicity = scaleMC(multiplicity, estimator.mMCScalePars); - LOGF(debug, "Unscaled %s multiplicity: %f, scaled %s multiplicity: %f", estimator.name.c_str(), multiplicity, estimator.name.c_str(), scaledMultiplicity); - } - percentile = estimator.mhMultSelCalib->GetBinContent(estimator.mhMultSelCalib->FindFixBin(scaledMultiplicity)); - if (assignOutOfRange) - percentile = 100.5f; - } - LOGF(debug, "%s centrality/multiplicity percentile = %.0f for a zvtx eq %s value %.0f", estimator.name.c_str(), percentile, estimator.name.c_str(), scaledMultiplicity); - table(percentile); - return percentile; - }; - - for (auto const& table : mEnabledTables) { - switch (table) { - case kCentFV0As: - if constexpr (enableCentFV0) { - populateTable(centFV0A, fv0aInfo, collision.multZeqFV0A()); - } - break; - case kCentFT0Ms: - if constexpr (enableCentFT0) { - const float perC = populateTable(centFT0M, ft0mInfo, collision.multZeqFT0A() + collision.multZeqFT0C()); - if (produceHistograms.value) { - histos.fill(HIST("FT0M/percentile"), perC); - histos.fill(HIST("FT0M/percentilevsPV"), perC, collision.multNTracksPV()); - histos.fill(HIST("FT0M/MultvsPV"), collision.multZeqFT0A() + collision.multZeqFT0C(), collision.multNTracksPV()); - if (collision.sel8()) { - histos.fill(HIST("sel8FT0M/percentile"), perC); - histos.fill(HIST("sel8FT0M/percentilevsPV"), perC, collision.multNTracksPV()); - histos.fill(HIST("sel8FT0M/MultvsPV"), collision.multZeqFT0A() + collision.multZeqFT0C(), collision.multNTracksPV()); - } - } - } - break; - case kCentFT0As: - if constexpr (enableCentFT0) { - const float perC = populateTable(centFT0A, ft0aInfo, collision.multZeqFT0A()); - if (produceHistograms.value) { - histos.fill(HIST("FT0A/percentile"), perC); - histos.fill(HIST("FT0A/percentilevsPV"), perC, collision.multNTracksPV()); - histos.fill(HIST("FT0A/MultvsPV"), collision.multZeqFT0A() + collision.multZeqFT0C(), collision.multNTracksPV()); - if (collision.sel8()) { - histos.fill(HIST("sel8FT0A/percentile"), perC); - histos.fill(HIST("sel8FT0A/percentilevsPV"), perC, collision.multNTracksPV()); - histos.fill(HIST("sel8FT0A/MultvsPV"), collision.multZeqFT0A() + collision.multZeqFT0C(), collision.multNTracksPV()); - } - } - } - break; - case kCentFT0Cs: - if constexpr (enableCentFT0) { - const float perC = populateTable(centFT0C, ft0cInfo, collision.multZeqFT0C()); - if (produceHistograms.value) { - histos.fill(HIST("FT0C/percentile"), perC); - histos.fill(HIST("FT0C/percentilevsPV"), perC, collision.multNTracksPV()); - histos.fill(HIST("FT0C/MultvsPV"), collision.multZeqFT0A() + collision.multZeqFT0C(), collision.multNTracksPV()); - if (collision.sel8()) { - histos.fill(HIST("sel8FT0C/percentile"), perC); - histos.fill(HIST("sel8FT0C/percentilevsPV"), perC, collision.multNTracksPV()); - histos.fill(HIST("sel8FT0C/MultvsPV"), collision.multZeqFT0A() + collision.multZeqFT0C(), collision.multNTracksPV()); - } - } - } - break; - case kCentFT0CVariant1s: - if constexpr (enableCentFT0) { - populateTable(centFT0CVariant1, ft0cVariant1Info, collision.multZeqFT0C()); - } - break; - case kCentFDDMs: - if constexpr (enableCentFDD) { - populateTable(centFDDM, fddmInfo, collision.multZeqFDDA() + collision.multZeqFDDC()); - } - break; - case kCentNTPVs: - if constexpr (enableCentNTPV) { - populateTable(centNTPV, ntpvInfo, collision.multZeqNTracksPV()); - } - break; - case kCentNGlobals: - if constexpr (enableCentNGlobal) { - populateTable(centNGlobals, nGlobalInfo, collision.multNTracksGlobal()); - } - break; - case kCentMFTs: - if constexpr (enableCentMFT) { - populateTable(centMFTs, mftInfo, collision.mftNtracks()); - } - break; - default: - LOGF(fatal, "Table %d not supported in Run3", table); - break; - } - } - } - } - - void processRun3Complete(soa::Join const& collisions, BCsWithTimestamps const&) - { - produceRun3Tables(collisions); - } - - void processRun3(soa::Join const& collisions, BCsWithTimestamps const&) - { - produceRun3Tables(collisions); - } - - void processRun3FT0(soa::Join const& collisions, BCsWithTimestamps const&) - { - produceRun3Tables(collisions); - } - - // Process switches - PROCESS_SWITCH(CentralityTable, processRun2, "Provide Run2 calibrated centrality/multiplicity percentiles tables", true); - PROCESS_SWITCH(CentralityTable, processRun3Complete, "Provide Run3 calibrated centrality/multiplicity percentiles tables using MFT and global tracks (requires extra subscriptions)", false); - PROCESS_SWITCH(CentralityTable, processRun3, "Provide Run3 calibrated centrality/multiplicity percentiles tables", false); - PROCESS_SWITCH(CentralityTable, processRun3FT0, "Provide Run3 calibrated centrality/multiplicity percentiles tables for FT0 only", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - metadataInfo.initMetadata(cfgc); - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} diff --git a/Common/TableProducer/fwdtrackToCollisionAssociator.cxx b/Common/TableProducer/fwdtrackToCollisionAssociator.cxx index 363b374f715..1de267d0e60 100644 --- a/Common/TableProducer/fwdtrackToCollisionAssociator.cxx +++ b/Common/TableProducer/fwdtrackToCollisionAssociator.cxx @@ -16,6 +16,7 @@ #include "Common/Core/CollisionAssociation.h" #include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/FwdTrackReAlignTables.h" #include #include @@ -44,6 +45,7 @@ struct FwdTrackToCollisionAssociation { CollisionAssociation collisionAssociator; Preslice muonsPerCollisions = aod::fwdtrack::collisionId; + Preslice realignmuonsPerCollisions = aod::fwdtrack::collisionId; Preslice mftsPerCollisions = aod::fwdtrack::collisionId; void init(InitContext const&) @@ -55,7 +57,7 @@ struct FwdTrackToCollisionAssociation { LOGP(fatal, "Exactly one process function between standard and time-based association should be enabled!"); } - if (!(doprocessMFTAssocWithTime || doprocessMFTStandardAssoc || doprocessFwdAssocWithTime || doprocessFwdStandardAssoc)) { + if (!(doprocessMFTAssocWithTime || doprocessMFTStandardAssoc || doprocessFwdAssocWithTime || doprocessFwdStandardAssoc || doprocessFwdRealignAssocWithTime || doprocessFwdRealignStandardAssoc)) { LOGP(fatal, "At least one process function should be enabled!"); } @@ -85,6 +87,22 @@ struct FwdTrackToCollisionAssociation { } PROCESS_SWITCH(FwdTrackToCollisionAssociation, processFwdStandardAssoc, "Use standard fwdtrack-to-collision association", false); + void processFwdRealignAssocWithTime(Collisions const& collisions, + FwdTracksReAlign const& muons, + AmbiguousFwdTrksReAlign const& ambiTracksFwd, + BCs const& bcs) + { + collisionAssociator.runAssocWithTime(collisions, muons, muons, ambiTracksFwd, bcs, fwdassociation, fwdreverseIndices); + } + PROCESS_SWITCH(FwdTrackToCollisionAssociation, processFwdRealignAssocWithTime, "Use fwdrealigntrack-to-collision association based on time", false); + + void processFwdRealignStandardAssoc(Collisions const& collisions, + FwdTracksReAlign const& muons) + { + collisionAssociator.runStandardAssoc(collisions, muons, realignmuonsPerCollisions, fwdassociation, fwdreverseIndices); + } + PROCESS_SWITCH(FwdTrackToCollisionAssociation, processFwdRealignStandardAssoc, "Use standard fwdrealigntrack-to-collision association", false); + void processMFTAssocWithTime(Collisions const& collisions, MFTTracks const& tracks, AmbiguousMFTTracks const& ambiguousTracks, diff --git a/Common/TableProducer/match-mft-ft0.cxx b/Common/TableProducer/match-mft-ft0.cxx index a6160cabe4b..43d43ebab84 100644 --- a/Common/TableProducer/match-mft-ft0.cxx +++ b/Common/TableProducer/match-mft-ft0.cxx @@ -124,11 +124,11 @@ T getCompatibleBCs(aod::AmbiguousMFTTrack const& atrack, aod::Collision const& c } if (bcIt != bcs.end() && maxBCId >= minBCId) { - T slice{{bcs.asArrowTable()->Slice(minBCId, maxBCId - minBCId + 1)}, (uint64_t)minBCId}; + auto slice = bcs.rawSlice(minBCId, maxBCId - minBCId + 1); bcs.copyIndexBindings(slice); return slice; } else { - T slice{{bcs.asArrowTable()->Slice(minBCId, maxBCId - minBCId)}, (uint64_t)minBCId}; + auto slice = bcs.rawSlice(minBCId, maxBCId - minBCId); bcs.copyIndexBindings(slice); return slice; } @@ -141,18 +141,10 @@ T getCompatibleBCs(aod::MFTTracks::iterator const& track, aod::Collision const& // define firstBC and lastBC (globalBC of beginning and end of the range, when no shift is applied) auto bcIt = collOrig.bc_as(); - // auto timstp = bcIt.timestamp(); int64_t firstBC = bcIt.globalBC() + (track.trackTime() - track.trackTimeRes()) / o2::constants::lhc::LHCBunchSpacingNS; int64_t lastBC = firstBC + 2 * track.trackTimeRes() / o2::constants::lhc::LHCBunchSpacingNS + 1; // to have a delta = 198 BC - // printf(">>>>>>>>>>>>>>>>>>>>>>>>>>> last-first %lld\n", lastBC-firstBC); - - // int collTimeResInBC = collOrig.collisionTimeRes()/o2::constants::lhc::LHCBunchSpacingNS; - - // int64_t collFirstBC = bcIt.globalBC() + (collOrig.collisionTime() - collOrig.collisionTimeRes())/o2::constants::lhc::LHCBunchSpacingNS; - // int64_t collLastBC = collFirstBC + 2*collOrig.collisionTimeRes()/o2::constants::lhc::LHCBunchSpacingNS +1; - int64_t minBCId = bcIt.globalIndex(); if ((int64_t)bcIt.globalBC() < firstBC + deltaBC) { @@ -195,9 +187,7 @@ T getCompatibleBCs(aod::MFTTracks::iterator const& track, aod::Collision const& { // means that the slice of compatible BCs is empty - T slice{{bcs.asArrowTable()->Slice(0, 0)}, (uint64_t)0}; - // bcs.copyIndexBindings(slice); REMOVED IT BECAUSE I DON'T KNOW WHAT IT DOES HERE - return slice; // returns an empty slice + return bcs.emptySlice(); } } } @@ -209,9 +199,7 @@ T getCompatibleBCs(aod::MFTTracks::iterator const& track, aod::Collision const& if (bcIt != bcs.end() && ((int64_t)bcIt.globalBC() > (int64_t)lastBC + deltaBC)) { // check the following element - T slice{{bcs.asArrowTable()->Slice(0, 0)}, (uint64_t)0}; - // bcs.copyIndexBindings(slice); REMOVED IT BECAUSE I DON'T KNOW WHAT IT DOES HERE - return slice; // returns an empty slice + return bcs.emptySlice(); } } @@ -222,15 +210,10 @@ T getCompatibleBCs(aod::MFTTracks::iterator const& track, aod::Collision const& } if (maxBCId < minBCId) { - if (bcIt == bcs.end()) { - printf("at the end of the bcs iterator %d\n", 1); - } - T slice{{bcs.asArrowTable()->Slice(0, 0)}, (uint64_t)0}; - // bcs.copyIndexBindings(slice); REMOVED IT BECAUSE I DON'T KNOW WHAT IT DOES HERE - return slice; // returns an empty slice + return bcs.emptySlice(); } - T slice{{bcs.asArrowTable()->Slice(minBCId, maxBCId - minBCId + 1)}, (uint64_t)minBCId}; + auto slice = bcs.rawSlice(minBCId, maxBCId - minBCId + 1); bcs.copyIndexBindings(slice); return slice; } diff --git a/Common/TableProducer/multiplicityExtraTable.cxx b/Common/TableProducer/multiplicityExtraTable.cxx index 7319a082c63..488ec9a1917 100644 --- a/Common/TableProducer/multiplicityExtraTable.cxx +++ b/Common/TableProducer/multiplicityExtraTable.cxx @@ -155,6 +155,8 @@ struct MultiplicityExtraTable { float multFV0A = 0.f; float multFDDA = 0.f; float multFDDC = 0.f; + float multFT0AOuter = 0.f; + float multFV0AOuter = 0.f; // ZDC amplitudes float multZEM1 = -1.f; @@ -195,8 +197,11 @@ struct MultiplicityExtraTable { multFT0TriggerBits = static_cast(triggers.to_ulong()); // calculate T0 charge - for (auto amplitude : ft0.amplitudeA()) { - multFT0A += amplitude; + for (size_t ii = 0; ii < ft0.amplitudeA().size(); ++ii) { + multFT0A += ft0.amplitudeA()[ii]; + if (ft0.channelA()[ii] > 31) { + multFT0AOuter += ft0.amplitudeA()[ii]; + } } for (auto amplitude : ft0.amplitudeC()) { multFT0C += amplitude; @@ -212,8 +217,13 @@ struct MultiplicityExtraTable { std::bitset<8> fV0Triggers = fv0.triggerMask(); multFV0TriggerBits = static_cast(fV0Triggers.to_ulong()); - for (auto amplitude : fv0.amplitude()) { + for (size_t ii = 0; ii < fv0.amplitude().size(); ii++) { + auto amplitude = fv0.amplitude()[ii]; + auto channel = fv0.channel()[ii]; multFV0A += amplitude; + if (channel > 7) { + multFV0AOuter += amplitude; + } } isFV0OrA = fV0Triggers[o2::fit::Triggers::bitA]; } else { @@ -254,15 +264,34 @@ struct MultiplicityExtraTable { bc2mult(bc2multArray[bc.globalIndex()]); multBC( - tru(multFT0A), tru(multFT0C), - tru(posZFT0), posZFT0valid, tru(multFV0A), - tru(multFDDA), tru(multFDDC), tru(multZNA), tru(multZNC), tru(multZEM1), - tru(multZEM2), tru(multZPA), tru(multZPC), Tvx, isFV0OrA, - multFV0TriggerBits, multFT0TriggerBits, multFDDTriggerBits, multBCTriggerMask, collidingBC, + tru(multFT0A), + tru(multFT0C), + tru(multFV0A), + tru(multFDDA), + tru(multFDDC), + tru(multZNA), + tru(multZNC), + tru(multZEM1), + tru(multZEM2), + tru(multZPA), + tru(multZPC), + tru(multFV0AOuter), + tru(multFT0AOuter)); + + multBcSel( + bc.selection_raw(), + bc.rct_raw(), + bc.flags(), bc.timestamp(), - bc.flags()); - - multBcSel(bc.selection_raw()); + tru(posZFT0), + posZFT0valid, + multFV0TriggerBits, + multFT0TriggerBits, + multFDDTriggerBits, + multBCTriggerMask, + collidingBC, + Tvx, + isFV0OrA); } } diff --git a/Common/TableProducer/multiplicityTable.cxx b/Common/TableProducer/multiplicityTable.cxx deleted file mode 100644 index 2c9ff5df025..00000000000 --- a/Common/TableProducer/multiplicityTable.cxx +++ /dev/null @@ -1,844 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -// -/// \file multiplicityTable.cxx -/// \brief Produces multiplicity tables -/// -/// \author ALICE -/// - -#include "PWGMM/Mult/DataModel/bestCollisionTable.h" - -#include "Common/Core/MetadataHelper.h" -#include "Common/Core/TableHelper.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -o2::common::core::MetadataHelper metadataInfo; // Metadata helper - -static constexpr int kFV0Mults = 0; -static constexpr int kFT0Mults = 1; -static constexpr int kFDDMults = 2; -static constexpr int kZDCMults = 3; -static constexpr int kTrackletMults = 4; -static constexpr int kTPCMults = 5; -static constexpr int kPVMults = 6; -static constexpr int kMultsExtra = 7; -static constexpr int kMultSelections = 8; -static constexpr int kFV0MultZeqs = 9; -static constexpr int kFT0MultZeqs = 10; -static constexpr int kFDDMultZeqs = 11; -static constexpr int kPVMultZeqs = 12; -static constexpr int kMultMCExtras = 13; -static constexpr int Ntables = 14; - -// Checking that the Zeq tables are after the normal ones -static_assert(kFV0Mults < kFV0MultZeqs); -static_assert(kFT0Mults < kFT0MultZeqs); -static_assert(kFDDMults < kFDDMultZeqs); -static_assert(kPVMults < kPVMultZeqs); - -static constexpr int Nparameters = 1; -static const std::vector tableNames{"FV0Mults", // 0 - "FT0Mults", // 1 - "FDDMults", // 2 - "ZDCMults", // 3 - "TrackletMults", // 4 - "TPCMults", // 5 - "PVMults", // 6 - "MultsExtra", // 7 - "MultSelections", // 8 - "FV0MultZeqs", // 9 - "FT0MultZeqs", // 10 - "FDDMultZeqs", // 11 - "PVMultZeqs", // 12 - "MultMCExtras"}; // 13 -static const std::vector parameterNames{"Enable"}; -static const int defaultParameters[Ntables][Nparameters]{{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}}; - -struct MultiplicityTable { - SliceCache cache; - Produces tableFV0; // 0 - Produces tableFV0AOuter; // 0-bis (produced with FV0) - Produces tableFT0; // 1 - Produces tableFDD; // 2 - Produces tableZDC; // 3 - Produces tableTracklet; // 4 - Produces tableTpc; // 5 - Produces tablePv; // 6 - Produces tableExtra; // 7 - Produces multSelections; // 8 - Produces tableFV0Zeqs; // 9 - Produces tableFT0Zeqs; // 10 - Produces tableFDDZeqs; // 11 - Produces tablePVZeqs; // 12 - Produces tableExtraMc; // 13 - Produces tableExtraMult2MCExtras; - Produces multHepMCHIs; // Not accounted for, produced using custom process function to avoid dependencies - Produces mftMults; // Not accounted for, produced using custom process function to avoid dependencies - Produces multsGlobal; // Not accounted for, produced based on process function processGlobalTrackingCounters - - // For vertex-Z corrections in calibration - Service ccdb; - Service pdg; - - using Run2Tracks = soa::Join; - Partition run2tracklets = (aod::track::trackType == static_cast(o2::aod::track::TrackTypeEnum::Run2Tracklet)); - Partition tracksWithTPC = (aod::track::tpcNClsFindable > (uint8_t)0); - Partition pvContribTracks = (nabs(aod::track::eta) < 0.8f) && ((aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor)); - Partition pvContribTracksEta1 = (nabs(aod::track::eta) < 1.0f) && ((aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor)); - Preslice perCol = aod::track::collisionId; - Preslice perColIU = aod::track::collisionId; - Preslice perCollisionMFT = o2::aod::fwdtrack::collisionId; - - using BCsWithRun3Matchings = soa::Join; - - // Configurable - Configurable doVertexZeq{"doVertexZeq", 1, "if 1: do vertex Z eq mult table"}; - Configurable fractionOfEvents{"fractionOfEvents", 2.0, "Fractions of events to keep in case the QA is used"}; - Configurable> enabledTables{"enabledTables", - {defaultParameters[0], Ntables, Nparameters, tableNames, parameterNames}, - "Produce tables depending on needs. Values different than -1 override the automatic setup: the corresponding table can be set off (0) or on (1)"}; - - struct : ConfigurableGroup { - Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "The CCDB endpoint url address"}; - Configurable ccdbPath{"ccdbPath", "Centrality/Calibration", "The CCDB path for centrality/multiplicity information"}; - Configurable reconstructionPass{"reconstructionPass", "", {"Apass to use when fetching the calibration tables. Empty (default) does not check for any pass. Use `metadata` to fetch it from the AO2D metadata. Otherwise it will override the metadata."}}; - } ccdbConfig; - - Configurable produceHistograms{"produceHistograms", false, {"Option to produce debug histograms"}}; - Configurable autoSetupFromMetadata{"autoSetupFromMetadata", true, {"Autosetup the Run 2 and Run 3 processing from the metadata"}}; - - int mRunNumber; - bool lCalibLoaded; - TList* lCalibObjects; - TProfile* hVtxZFV0A; - TProfile* hVtxZFT0A; - TProfile* hVtxZFT0C; - TProfile* hVtxZFDDA; - - TProfile* hVtxZFDDC; - TProfile* hVtxZNTracks; - std::vector mEnabledTables; // Vector of enabled tables - - // Debug output - HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::QAObject}; - OutputObj listCalib{"calib-list", OutputObjHandlingPolicy::QAObject}; - - unsigned int randomSeed = 0; - void init(InitContext& context) - { - // If both Run 2 and Run 3 data process flags are enabled then we check the metadata - if (autoSetupFromMetadata && metadataInfo.isFullyDefined()) { - LOG(info) << "Autosetting the processing from the metadata"; - if (doprocessRun2 == true && doprocessRun3 == true) { - if (metadataInfo.isRun3()) { - doprocessRun2.value = false; - } else { - doprocessRun3.value = false; - } - } - } - - randomSeed = static_cast(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); - if (doprocessRun2 == false && doprocessRun3 == false) { - LOGF(fatal, "Neither processRun2 nor processRun3 enabled. Please choose one."); - } - if (doprocessRun2 == true && doprocessRun3 == true) { - LOGF(fatal, "Cannot enable processRun2 and processRun3 at the same time. Please choose one."); - } - - bool tEnabled[Ntables] = {false}; - for (int i = 0; i < Ntables; i++) { - int f = enabledTables->get(tableNames[i].c_str(), "Enable"); - o2::common::core::enableFlagIfTableRequired(context, tableNames[i], f); - if (f == 1) { - tEnabled[i] = true; - mEnabledTables.push_back(i); - if (fractionOfEvents <= 1.f && (tableNames[i] != "MultsExtra")) { - LOG(fatal) << "Cannot have a fraction of events <= 1 and multiplicity table consumed."; - } - } - } - // Handle the custom cases. - if (tEnabled[kMultMCExtras]) { - if (enabledTables->get(tableNames[kMultMCExtras].c_str(), "Enable") == -1) { - doprocessMC.value = true; - LOG(info) << "Enabling MC processing due to " << tableNames[kMultMCExtras] << " table being enabled."; - } - } - - // Check that the tables are enabled consistenly - if (tEnabled[kFV0MultZeqs] && !tEnabled[kFV0Mults]) { // FV0 - mEnabledTables.push_back(kFV0Mults); - LOG(info) << "Cannot have the " << tableNames[kFV0MultZeqs] << " table enabled and not the one on " << tableNames[kFV0Mults] << ". Enabling it."; - } - if (tEnabled[kFT0MultZeqs] && !tEnabled[kFT0Mults]) { // FT0 - mEnabledTables.push_back(kFT0Mults); - LOG(info) << "Cannot have the " << tableNames[kFT0MultZeqs] << " table enabled and not the one on " << tableNames[kFT0Mults] << ". Enabling it."; - } - if (tEnabled[kFDDMultZeqs] && !tEnabled[kFDDMults]) { // FDD - mEnabledTables.push_back(kFDDMults); - LOG(info) << "Cannot have the " << tableNames[kFDDMultZeqs] << " table enabled and not the one on " << tableNames[kFDDMults] << ". Enabling it."; - } - if (tEnabled[kPVMultZeqs] && !tEnabled[kPVMults]) { // PV - mEnabledTables.push_back(kPVMults); - LOG(info) << "Cannot have the " << tableNames[kPVMultZeqs] << " table enabled and not the one on " << tableNames[kPVMults] << ". Enabling it."; - } - std::sort(mEnabledTables.begin(), mEnabledTables.end()); - - mRunNumber = 0; - lCalibLoaded = false; - lCalibObjects = nullptr; - hVtxZFV0A = nullptr; - hVtxZFT0A = nullptr; - hVtxZFT0C = nullptr; - hVtxZFDDA = nullptr; - hVtxZFDDC = nullptr; - hVtxZNTracks = nullptr; - - ccdb->setURL(ccdbConfig.ccdburl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); // don't fatal, please - exception is caught explicitly (as it should) - - listCalib.setObject(new TList); - if (!produceHistograms.value) { - return; - } - histos.add("FT0A", "FT0A vs FT0A eq.", HistType::kTH2D, {{1000, 0, 1000, "FT0A multiplicity"}, {1000, 0, 1000, "FT0A multiplicity eq."}}); - histos.add("FT0C", "FT0C vs FT0C eq.", HistType::kTH2D, {{1000, 0, 1000, "FT0C multiplicity"}, {1000, 0, 1000, "FT0C multiplicity eq."}}); - histos.add("FT0CMultvsPV", "FT0C vs mult.", HistType::kTH2D, {{1000, 0, 1000, "FT0C mult."}, {100, 0, 100, "PV mult."}}); - histos.add("FT0AMultvsPV", "FT0A vs mult.", HistType::kTH2D, {{1000, 0, 1000, "FT0A mult."}, {100, 0, 100, "PV mult."}}); - } - - /// Dummy process function for BCs, needed in case both Run2 and Run3 process functions are disabled - void process(aod::BCs const&) {} - - void processRun2(aod::Run2MatchedSparse::iterator const& collision, - Run2Tracks const&, - aod::BCs const&, - aod::Zdcs const&, - aod::FV0As const&, - aod::FV0Cs const&, - aod::FT0s const&) - { - float multFV0A = 0.f; - float multFV0C = 0.f; - float multFT0A = 0.f; - float multFT0C = 0.f; - float multFDDA = 0.f; - float multFDDC = 0.f; - float multZNA = 0.f; - float multZNC = 0.f; - - auto trackletsGrouped = run2tracklets->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - auto tracksGrouped = tracksWithTPC->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - int multTracklets = trackletsGrouped.size(); - int multTPC = tracksGrouped.size(); - int multNContribs = 0; - int multNContribsEta1 = 0; - int multNContribsEtaHalf = 0; - - if (collision.has_fv0a()) { - for (const auto& amplitude : collision.fv0a().amplitude()) { - multFV0A += amplitude; - } - } - if (collision.has_fv0c()) { - for (const auto& amplitude : collision.fv0c().amplitude()) { - multFV0C += amplitude; - } - } - if (collision.has_ft0()) { - auto ft0 = collision.ft0(); - for (const auto& amplitude : ft0.amplitudeA()) { - multFT0A += amplitude; - } - for (const auto& amplitude : ft0.amplitudeC()) { - multFT0C += amplitude; - } - } - if (collision.has_zdc()) { - auto zdc = collision.zdc(); - multZNA = zdc.energyCommonZNA(); - multZNC = zdc.energyCommonZNC(); - } - - // Try to do something Similar to https://github.com/alisw/AliPhysics/blob/22862a945004f719f8e9664c0264db46e7186a48/OADB/AliPPVsMultUtils.cxx#L541C26-L541C37 - for (const auto& tracklet : trackletsGrouped) { - if (std::abs(tracklet.eta()) < 1.0) { - multNContribsEta1++; - } - if (std::abs(tracklet.eta()) < 0.8) { - multNContribs++; - } - if (std::abs(tracklet.eta()) < 0.5) { - multNContribsEtaHalf++; - } - } - - LOGF(debug, "multFV0A=%5.0f multFV0C=%5.0f multFT0A=%5.0f multFT0C=%5.0f multFDDA=%5.0f multFDDC=%5.0f multZNA=%6.0f multZNC=%6.0f multTracklets=%i multTPC=%i multNContribsEta1=%i multNContribs=%i multNContribsEtaHalf=%i", multFV0A, multFV0C, multFT0A, multFT0C, multFDDA, multFDDC, multZNA, multZNC, multTracklets, multTPC, multNContribs, multNContribsEta1, multNContribsEtaHalf); - tableFV0(multFV0A, multFV0C); - tableFT0(multFT0A, multFT0C); - tableFDD(multFDDA, multFDDC); - tableZDC(multZNA, multZNC, 0.0f, 0.0f, 0.0f, 0.0f); - tableTracklet(multTracklets); - tableTpc(multTPC); - tablePv(multNContribs, multNContribsEta1, multNContribsEtaHalf); - } - - using Run3TracksIU = soa::Join; - Partition tracksIUWithTPC = (aod::track::tpcNClsFindable > (uint8_t)0); - Partition pvAllContribTracksIU = ((aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor)); - Partition pvContribTracksIU = (nabs(aod::track::eta) < 0.8f) && ((aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor)); - Partition pvContribTracksIUEta1 = (nabs(aod::track::eta) < 1.0f) && ((aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor)); - Partition pvContribTracksIUEtaHalf = (nabs(aod::track::eta) < 0.5f) && ((aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor)); - - void processRun3(soa::Join const& collisions, - Run3TracksIU const&, - BCsWithRun3Matchings const&, - aod::Zdcs const&, - aod::FV0As const&, - aod::FT0s const&, - aod::FDDs const&) - { - // reserve memory - for (const auto& i : mEnabledTables) { - switch (i) { - case kFV0Mults: // FV0 - tableFV0.reserve(collisions.size()); - tableFV0AOuter.reserve(collisions.size()); - break; - case kFT0Mults: // FT0 - tableFT0.reserve(collisions.size()); - break; - case kFDDMults: // FDD - tableFDD.reserve(collisions.size()); - break; - case kZDCMults: // ZDC - tableZDC.reserve(collisions.size()); - break; - case kTrackletMults: // Tracklets (Run 2 only, nothing to do) (to be removed!) - tableTracklet.reserve(collisions.size()); - break; - case kTPCMults: // TPC - tableTpc.reserve(collisions.size()); - break; - case kPVMults: // PV multiplicity - tablePv.reserve(collisions.size()); - break; - case kMultsExtra: // Extra information - tableExtra.reserve(collisions.size()); - break; - case kMultSelections: // Extra information - multSelections.reserve(collisions.size()); - break; - case kFV0MultZeqs: // Equalized multiplicity for FV0 - tableFV0Zeqs.reserve(collisions.size()); - break; - case kFT0MultZeqs: // Equalized multiplicity for FT0 - tableFT0Zeqs.reserve(collisions.size()); - break; - case kFDDMultZeqs: // Equalized multiplicity for FDD - tableFDDZeqs.reserve(collisions.size()); - break; - case kPVMultZeqs: // Equalized multiplicity for PV - tablePVZeqs.reserve(collisions.size()); - break; - case kMultMCExtras: // MC extra information (nothing to do in the data) - break; - default: - LOG(fatal) << "Unknown table requested: " << i; - break; - } - } - - // Initializing multiplicity values - float multFV0A = 0.f; - float multFV0AOuter = 0.f; - float multFV0C = 0.f; - float multFT0A = 0.f; - float multFT0C = 0.f; - float multFDDA = 0.f; - float multFDDC = 0.f; - float multZNA = -1.f; - float multZNC = -1.f; - float multZEM1 = -1.f; - float multZEM2 = -1.f; - float multZPA = -1.f; - float multZPC = -1.f; - - float multZeqFV0A = 0.f; - float multZeqFT0A = 0.f; - float multZeqFT0C = 0.f; - float multZeqFDDA = 0.f; - float multZeqFDDC = 0.f; - float multZeqNContribs = 0.f; - - for (auto const& collision : collisions) { - if ((fractionOfEvents < 1.f) && (static_cast(rand_r(&randomSeed)) / static_cast(RAND_MAX)) > fractionOfEvents) { // Skip events that are not sampled (only for the QA) - return; - } - int multNContribs = 0; - int multNContribsEta1 = 0; - int multNContribsEtaHalf = 0; - - /* check the previous run number */ - const auto& bc = collision.bc_as(); - if (doVertexZeq > 0) { - if (bc.runNumber() != mRunNumber) { - mRunNumber = bc.runNumber(); // mark this run as at least tried - if (ccdbConfig.reconstructionPass.value == "") { - lCalibObjects = ccdb->getForRun(ccdbConfig.ccdbPath, mRunNumber); - } else if (ccdbConfig.reconstructionPass.value == "metadata") { - std::map metadata; - metadata["RecoPassName"] = metadataInfo.get("RecoPassName"); - LOGF(info, "Loading CCDB for reconstruction pass (from metadata): %s", metadataInfo.get("RecoPassName")); - lCalibObjects = ccdb->getSpecificForRun(ccdbConfig.ccdbPath, mRunNumber, metadata); - } else { - std::map metadata; - metadata["RecoPassName"] = ccdbConfig.reconstructionPass.value; - LOGF(info, "Loading CCDB for reconstruction pass (from provided argument): %s", ccdbConfig.reconstructionPass.value); - lCalibObjects = ccdb->getSpecificForRun(ccdbConfig.ccdbPath, mRunNumber, metadata); - } - - if (lCalibObjects) { - if (produceHistograms) { - listCalib->Add(lCalibObjects->Clone(Form("%i", bc.runNumber()))); - } - - hVtxZFV0A = static_cast(lCalibObjects->FindObject("hVtxZFV0A")); - hVtxZFT0A = static_cast(lCalibObjects->FindObject("hVtxZFT0A")); - hVtxZFT0C = static_cast(lCalibObjects->FindObject("hVtxZFT0C")); - hVtxZFDDA = static_cast(lCalibObjects->FindObject("hVtxZFDDA")); - hVtxZFDDC = static_cast(lCalibObjects->FindObject("hVtxZFDDC")); - hVtxZNTracks = static_cast(lCalibObjects->FindObject("hVtxZNTracksPV")); - lCalibLoaded = true; - // Capture error - if (!hVtxZFV0A || !hVtxZFT0A || !hVtxZFT0C || !hVtxZFDDA || !hVtxZFDDC || !hVtxZNTracks) { - LOGF(error, "Problem loading CCDB objects! Please check"); - lCalibLoaded = false; - } - } else { - LOGF(error, "Problem loading CCDB object! Please check"); - lCalibLoaded = false; - } - } - } - - for (const auto& i : mEnabledTables) { - switch (i) { - case kFV0Mults: // FV0 - { - multFV0A = 0.f; - multFV0AOuter = 0.f; - multFV0C = 0.f; - // using FV0 row index from event selection task - if (collision.has_foundFV0()) { - const auto& fv0 = collision.foundFV0(); - for (size_t ii = 0; ii < fv0.amplitude().size(); ii++) { - auto amplitude = fv0.amplitude()[ii]; - auto channel = fv0.channel()[ii]; - multFV0A += amplitude; - if (channel > 7) { - multFV0AOuter += amplitude; - } - } - } else { - multFV0A = -999.f; - multFV0C = -999.f; - } - tableFV0(multFV0A, multFV0C); - tableFV0AOuter(multFV0AOuter); - LOGF(debug, "multFV0A=%5.0f multFV0C=%5.0f", multFV0A, multFV0C); - } break; - case kFT0Mults: // FT0 - { - multFT0A = 0.f; - multFT0C = 0.f; - // using FT0 row index from event selection task - if (collision.has_foundFT0()) { - const auto& ft0 = collision.foundFT0(); - for (const auto& amplitude : ft0.amplitudeA()) { - multFT0A += amplitude; - } - for (const auto& amplitude : ft0.amplitudeC()) { - multFT0C += amplitude; - } - } else { - multFT0A = -999.f; - multFT0C = -999.f; - } - tableFT0(multFT0A, multFT0C); - LOGF(debug, "multFT0A=%5.0f multFT0C=%5.0f", multFV0A, multFV0C); - } break; - case kFDDMults: // FDD - { - multFDDA = 0.f; - multFDDC = 0.f; - // using FDD row index from event selection task - if (collision.has_foundFDD()) { - const auto& fdd = collision.foundFDD(); - for (const auto& amplitude : fdd.chargeA()) { - multFDDA += amplitude; - } - for (const auto& amplitude : fdd.chargeC()) { - multFDDC += amplitude; - } - } else { - multFDDA = -999.f; - multFDDC = -999.f; - } - tableFDD(multFDDA, multFDDC); - LOGF(debug, "multFDDA=%5.0f multFDDC=%5.0f", multFDDA, multFDDC); - } break; - case kZDCMults: // ZDC - { - if (bc.has_zdc()) { - multZNA = bc.zdc().amplitudeZNA(); - multZNC = bc.zdc().amplitudeZNC(); - multZEM1 = bc.zdc().amplitudeZEM1(); - multZEM2 = bc.zdc().amplitudeZEM2(); - multZPA = bc.zdc().amplitudeZPA(); - multZPC = bc.zdc().amplitudeZPC(); - } else { - multZNA = -999.f; - multZNC = -999.f; - multZEM1 = -999.f; - multZEM2 = -999.f; - multZPA = -999.f; - multZPC = -999.f; - } - tableZDC(multZNA, multZNC, multZEM1, multZEM2, multZPA, multZPC); - LOGF(debug, "multZNA=%6.0f multZNC=%6.0f", multZNA, multZNC); - } break; - case kTrackletMults: // Tracklets (only Run2) nothing to do (to be removed!) - { - tableTracklet(0); - } break; - case kTPCMults: // TPC - { - const auto& tracksGrouped = tracksIUWithTPC->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - const int multTPC = tracksGrouped.size(); - tableTpc(multTPC); - LOGF(debug, "multTPC=%i", multTPC); - } break; - case kPVMults: // PV multiplicity - { - // use only one single grouping operation, then do loop - const auto& tracksThisCollision = pvContribTracksIUEta1.sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - multNContribsEta1 = tracksThisCollision.size(); - for (const auto& track : tracksThisCollision) { - if (std::abs(track.eta()) < 0.8) { - multNContribs++; - } - if (std::abs(track.eta()) < 0.5) { - multNContribsEtaHalf++; - } - } - - tablePv(multNContribs, multNContribsEta1, multNContribsEtaHalf); - LOGF(debug, "multNContribs=%i, multNContribsEta1=%i, multNContribsEtaHalf=%i", multNContribs, multNContribsEta1, multNContribsEtaHalf); - } break; - case kMultsExtra: // Extra - { - int nHasITS = 0, nHasTPC = 0, nHasTOF = 0, nHasTRD = 0; - int nITSonly = 0, nTPConly = 0, nITSTPC = 0; - const auto& pvAllContribsGrouped = pvAllContribTracksIU->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - const auto& tpcTracksGrouped = tracksIUWithTPC->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - - for (const auto& track : pvAllContribsGrouped) { - if (track.hasITS()) { - nHasITS++; - if (track.hasTPC()) - nITSTPC++; - if (!track.hasTPC() && !track.hasTOF() && !track.hasTRD()) - nITSonly++; - } - if (track.hasTPC()) { - nHasTPC++; - if (!track.hasITS() && !track.hasTOF() && !track.hasTRD()) - nTPConly++; - } - if (track.hasTOF()) - nHasTOF++; - if (track.hasTRD()) - nHasTRD++; - } - - int nAllTracksTPCOnly = 0; - int nAllTracksITSTPC = 0; - for (const auto& track : tpcTracksGrouped) { - if (track.hasITS()) { - nAllTracksITSTPC++; - } else { - nAllTracksTPCOnly++; - } - } - - tableExtra(collision.numContrib(), collision.chi2(), collision.collisionTimeRes(), - mRunNumber, collision.posZ(), collision.sel8(), - nHasITS, nHasTPC, nHasTOF, nHasTRD, nITSonly, nTPConly, nITSTPC, - nAllTracksTPCOnly, nAllTracksITSTPC, - collision.trackOccupancyInTimeRange(), - collision.ft0cOccupancyInTimeRange(), - collision.flags()); - } break; - case kMultSelections: // Multiplicity selections - { - multSelections(collision.selection_raw()); - } break; - case kFV0MultZeqs: // Z equalized FV0 - { - if (std::fabs(collision.posZ()) < 15.0f && lCalibLoaded) { - multZeqFV0A = hVtxZFV0A->Interpolate(0.0) * multFV0A / hVtxZFV0A->Interpolate(collision.posZ()); - } - tableFV0Zeqs(multZeqFV0A); - } break; - case kFT0MultZeqs: // Z equalized FT0 - { - if (std::fabs(collision.posZ()) < 15.0f && lCalibLoaded) { - multZeqFT0A = hVtxZFT0A->Interpolate(0.0) * multFT0A / hVtxZFT0A->Interpolate(collision.posZ()); - multZeqFT0C = hVtxZFT0C->Interpolate(0.0) * multFT0C / hVtxZFT0C->Interpolate(collision.posZ()); - } - if (produceHistograms.value) { - histos.fill(HIST("FT0A"), multFT0A, multZeqFT0A); - histos.fill(HIST("FT0C"), multFT0C, multZeqFT0C); - histos.fill(HIST("FT0AMultvsPV"), multZeqFT0A, multNContribs); - histos.fill(HIST("FT0CMultvsPV"), multZeqFT0C, multNContribs); - } - tableFT0Zeqs(multZeqFT0A, multZeqFT0C); - } break; - case kFDDMultZeqs: // Z equalized FDD - { - if (std::fabs(collision.posZ()) < 15.0f && lCalibLoaded) { - multZeqFDDA = hVtxZFDDA->Interpolate(0.0) * multFDDA / hVtxZFDDA->Interpolate(collision.posZ()); - multZeqFDDC = hVtxZFDDC->Interpolate(0.0) * multFDDC / hVtxZFDDC->Interpolate(collision.posZ()); - } - tableFDDZeqs(multZeqFDDA, multZeqFDDC); - } break; - case kPVMultZeqs: // Z equalized PV - { - if (std::fabs(collision.posZ()) < 15.0f && lCalibLoaded) { - multZeqNContribs = hVtxZNTracks->Interpolate(0.0) * multNContribs / hVtxZNTracks->Interpolate(collision.posZ()); - } - tablePVZeqs(multZeqNContribs); - } break; - case kMultMCExtras: // MC only (nothing to do) - { - } break; - default: // Default - { - LOG(fatal) << "Unknown table requested: " << i; - } break; - } - } - } - } - - // one loop better than multiple sliceby calls - // FIT FT0C: -3.3 < η < -2.1 - // FOT FT0A: 3.5 < η < 4.9 - Filter mcParticleFilter = (aod::mcparticle::eta < 7.0f) && (aod::mcparticle::eta > -7.0f); - using McParticlesFiltered = soa::Filtered; - - void processMC(aod::McCollision const& mcCollision, McParticlesFiltered const& mcParticles) - { - int multFT0A = 0; - int multFV0A = 0; - int multFT0C = 0; - int multFDDA = 0; - int multFDDC = 0; - int multBarrelEta05 = 0; - int multBarrelEta08 = 0; - int multBarrelEta10 = 0; - for (auto const& mcPart : mcParticles) { - if (!mcPart.isPhysicalPrimary()) { - continue; - } - - auto charge = 0.; - auto* p = pdg->GetParticle(mcPart.pdgCode()); - if (p != nullptr) { - charge = p->Charge(); - } - if (std::abs(charge) < 1e-3) { - continue; // reject neutral particles in counters - } - - if (std::abs(mcPart.eta()) < 1.0) { - multBarrelEta10++; - if (std::abs(mcPart.eta()) < 0.8) { - multBarrelEta08++; - if (std::abs(mcPart.eta()) < 0.5) { - multBarrelEta05++; - } - } - } - if (-3.3 < mcPart.eta() && mcPart.eta() < -2.1) - multFT0C++; - if (3.5 < mcPart.eta() && mcPart.eta() < 4.9) - multFT0A++; - if (2.2 < mcPart.eta() && mcPart.eta() < 5.0) - multFV0A++; - if (-6.9 < mcPart.eta() && mcPart.eta() < -4.9) - multFDDC++; - if (4.7 < mcPart.eta() && mcPart.eta() < 6.3) - multFDDA++; - } - tableExtraMc(multFT0A, multFT0C, multFV0A, multFDDA, multFDDC, multBarrelEta05, multBarrelEta08, multBarrelEta10, mcCollision.posZ()); - } - - void processMC2Mults(soa::Join::iterator const& collision) - { - tableExtraMult2MCExtras(collision.mcCollisionId()); // interlink - } - - Configurable minPtGlobalTrack{"minPtGlobalTrack", 0.15, "min. pT for global tracks"}; - Configurable maxPtGlobalTrack{"maxPtGlobalTrack", 1e+10, "max. pT for global tracks"}; - Configurable minNclsITSGlobalTrack{"minNclsITSGlobalTrack", 5, "min. number of ITS clusters for global tracks"}; - Configurable minNclsITSibGlobalTrack{"minNclsITSibGlobalTrack", 1, "min. number of ITSib clusters for global tracks"}; - - using Run3Tracks = soa::Join; - Partition pvContribGlobalTracksEta1 = (minPtGlobalTrack < aod::track::pt && aod::track::pt < maxPtGlobalTrack) && (nabs(aod::track::eta) < 1.0f) && ((aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor)) && requireQualityTracksInFilter(); - - void processHepMCHeavyIons(aod::HepMCHeavyIons const& hepmchis) - { - for (auto const& hepmchi : hepmchis) { - multHepMCHIs(hepmchi.mcCollisionId(), - hepmchi.ncollHard(), - hepmchi.npartProj(), - hepmchi.npartTarg(), - hepmchi.ncoll(), - hepmchi.impactParameter()); - } - } - - void processGlobalTrackingCounters(aod::Collision const& collision, soa::Join const& tracksIU, Run3Tracks const&) - { - // counter from Igor - int nGlobalTracks = 0; - int multNbrContribsEta05GlobalTrackWoDCA = 0; - int multNbrContribsEta08GlobalTrackWoDCA = 0; - int multNbrContribsEta10GlobalTrackWoDCA = 0; - - auto pvContribGlobalTracksEta1PerCollision = pvContribGlobalTracksEta1->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - - for (const auto& track : pvContribGlobalTracksEta1PerCollision) { - if (track.itsNCls() < minNclsITSGlobalTrack || track.itsNClsInnerBarrel() < minNclsITSibGlobalTrack) { - continue; - } - multNbrContribsEta10GlobalTrackWoDCA++; - - if (std::abs(track.eta()) < 0.8) { - multNbrContribsEta08GlobalTrackWoDCA++; - } - if (std::abs(track.eta()) < 0.5) { - multNbrContribsEta05GlobalTrackWoDCA++; - } - } - - for (const auto& track : tracksIU) { - if (std::fabs(track.eta()) < 0.8 && track.tpcNClsFound() >= 80 && track.tpcNClsCrossedRows() >= 100) { - if (track.isGlobalTrack()) { - nGlobalTracks++; - } - } - } - - LOGF(debug, "nGlobalTracks = %d, multNbrContribsEta08GlobalTrackWoDCA = %d, multNbrContribsEta10GlobalTrackWoDCA = %d, multNbrContribsEta05GlobalTrackWoDCA = %d", nGlobalTracks, multNbrContribsEta08GlobalTrackWoDCA, multNbrContribsEta10GlobalTrackWoDCA, multNbrContribsEta05GlobalTrackWoDCA); - - multsGlobal(nGlobalTracks, multNbrContribsEta08GlobalTrackWoDCA, multNbrContribsEta10GlobalTrackWoDCA, multNbrContribsEta05GlobalTrackWoDCA); - } - - void processRun3MFT(soa::Join::iterator const&, - o2::aod::MFTTracks const& mftTracks, - soa::SmallGroups const& retracks) - { - int nAllTracks = 0; - int nTracks = 0; - - for (const auto& track : mftTracks) { - if (track.nClusters() >= 5) { // hardcoded for now - nAllTracks++; - } - } - - if (retracks.size() > 0) { - for (const auto& retrack : retracks) { - auto track = retrack.mfttrack(); - if (track.nClusters() < 5) { - continue; // min cluster requirement - } - if ((track.eta() > -2.0f) && (track.eta() < -3.9f)) { - continue; // too far to be of true interest - } - if (std::abs(retrack.bestDCAXY()) > 2.0f) { - continue; // does not point to PV properly - } - nTracks++; - } - } - mftMults(nAllTracks, nTracks); - } - - // Process switches - PROCESS_SWITCH(MultiplicityTable, processRun2, "Produce Run 2 multiplicity tables. Autoset if both processRun2 and processRun3 are enabled", true); - PROCESS_SWITCH(MultiplicityTable, processRun3, "Produce Run 3 multiplicity tables. Autoset if both processRun2 and processRun3 are enabled", true); - PROCESS_SWITCH(MultiplicityTable, processGlobalTrackingCounters, "Produce Run 3 global counters", false); - PROCESS_SWITCH(MultiplicityTable, processMC, "Produce MC multiplicity tables", false); - PROCESS_SWITCH(MultiplicityTable, processMC2Mults, "Produce MC -> Mult map", false); - PROCESS_SWITCH(MultiplicityTable, processHepMCHeavyIons, "Produce MultHepMCHIs tables", false); - PROCESS_SWITCH(MultiplicityTable, processRun3MFT, "Produce MFT mult tables", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - // Parse the metadata - metadataInfo.initMetadata(cfgc); - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} diff --git a/Common/TableProducer/muonRealignment.cxx b/Common/TableProducer/muonRealignment.cxx index f15780546b2..5b1a597a73c 100644 --- a/Common/TableProducer/muonRealignment.cxx +++ b/Common/TableProducer/muonRealignment.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,6 @@ #include -#include #include #include diff --git a/Common/TableProducer/occupancyTableProducer.cxx b/Common/TableProducer/occupancyTableProducer.cxx index c3075e01d54..9289ccb7a16 100644 --- a/Common/TableProducer/occupancyTableProducer.cxx +++ b/Common/TableProducer/occupancyTableProducer.cxx @@ -433,51 +433,43 @@ struct OccupancyTableProducer { template void executeOccProducerProcessing(B const& BCs, C const& collisions, T const& tracks) { - if (tableMode == checkTableMode) { + if constexpr (tableMode == checkTableMode) { if (buildFlag00OccTable) { executeOccProducerProcessing(BCs, collisions, tracks); } else { executeOccProducerProcessing(BCs, collisions, tracks); } - } - if constexpr (tableMode == checkTableMode) { return; } - if (meanTableMode == checkTableMode) { + if constexpr (meanTableMode == checkTableMode) { if (buildFlag01OccMeanTable) { executeOccProducerProcessing(BCs, collisions, tracks); } else { executeOccProducerProcessing(BCs, collisions, tracks); } - } - if constexpr (meanTableMode == checkTableMode) { return; } - if (robustTableMode == checkTableMode) { + if constexpr (robustTableMode == checkTableMode) { if (buildFlag02OccRobustTable) { executeOccProducerProcessing(BCs, collisions, tracks); } else { executeOccProducerProcessing(BCs, collisions, tracks); } - } - if constexpr (robustTableMode == checkTableMode) { return; } - if (meanRobustTableMode == checkTableMode) { + if constexpr (meanRobustTableMode == checkTableMode) { if (buildFlag03OccMeanRobustTable) { executeOccProducerProcessing(BCs, collisions, tracks); } else { executeOccProducerProcessing(BCs, collisions, tracks); } - } - if constexpr (meanRobustTableMode == checkTableMode) { return; } - if constexpr (tableMode == checkTableMode || meanTableMode == checkTableMode || robustTableMode == checkTableMode || meanRobustTableMode == checkTableMode) { + if constexpr (tableMode == checkTableMode || meanTableMode == checkTableMode || robustTableMode == checkTableMode) { return; } else { @@ -802,7 +794,7 @@ struct OccupancyTableProducer { auto& vecOccPrimUnfm80 = occPrimUnfm80[i]; float meanOccPrimUnfm80 = TMath::Mean(vecOccPrimUnfm80.size(), vecOccPrimUnfm80.data()); - normalizeVector(vecOccPrimUnfm80, meanOccPrimUnfm80 / meanOccPrimUnfm80); + // normalizeVector(vecOccPrimUnfm80, meanOccPrimUnfm80 / meanOccPrimUnfm80); if constexpr (processMode == kProcessFullOccTableProducer || processMode == kProcessOnlyOccPrim || processMode == kProcessOnlyOccT0V0Prim || processMode == kProcessOnlyOccFDDT0V0Prim || processMode == kProcessOnlyOccNtrackDet || processMode == kProcessOnlyOccMultExtra) { if constexpr (tableMode == fillOccTable) { @@ -1699,20 +1691,22 @@ struct TrackMeanOccTableProducer { { occupancyQA.fill(HIST("occTrackQA/") + HIST(OccDire[occMode]) + HIST(OccNames[occName]), occValue); if (fillQA1) { - occupancyQA.fill(HIST("occTrackQA/LogRatio/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), std::log(std::abs(occValue / occRobustValue))); + float logRatio = std::log(occValue / occRobustValue); + float weighted = logRatio * std::sqrt(occValue + occRobustValue); + occupancyQA.fill(HIST("occTrackQA/LogRatio/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), logRatio); if (fillQA2) { int two = 2, twenty = 20, fifty = 50, twoHundred = 200; if (std::abs(std::log(occValue / occRobustValue)) < two) { // conditional filling start - occupancyQA.fill(HIST("occTrackQA/Condition1/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), (std::log(occValue / occRobustValue)) * std::sqrt(occValue + occRobustValue)); + occupancyQA.fill(HIST("occTrackQA/Condition1/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), weighted); if (std::abs(occRobustValue + occValue) > twoHundred) { - occupancyQA.fill(HIST("occTrackQA/Condition4/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), (std::log(occValue / occRobustValue)) * std::sqrt(occValue + occRobustValue)); - occupancyQA.fill(HIST("occTrackQA/Condition3/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), (std::log(occValue / occRobustValue)) * std::sqrt(occValue + occRobustValue)); - occupancyQA.fill(HIST("occTrackQA/Condition2/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), (std::log(occValue / occRobustValue)) * std::sqrt(occValue + occRobustValue)); + occupancyQA.fill(HIST("occTrackQA/Condition4/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), weighted); + occupancyQA.fill(HIST("occTrackQA/Condition3/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), weighted); + occupancyQA.fill(HIST("occTrackQA/Condition2/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), weighted); } else if (std::abs(occRobustValue + occValue) > fifty) { - occupancyQA.fill(HIST("occTrackQA/Condition3/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), (std::log(occValue / occRobustValue)) * std::sqrt(occValue + occRobustValue)); - occupancyQA.fill(HIST("occTrackQA/Condition2/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), (std::log(occValue / occRobustValue)) * std::sqrt(occValue + occRobustValue)); + occupancyQA.fill(HIST("occTrackQA/Condition3/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), weighted); + occupancyQA.fill(HIST("occTrackQA/Condition2/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), weighted); } else if (std::abs(occRobustValue + occValue) > twenty) { - occupancyQA.fill(HIST("occTrackQA/Condition2/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), (std::log(occValue / occRobustValue)) * std::sqrt(occValue + occRobustValue)); + occupancyQA.fill(HIST("occTrackQA/Condition2/") + HIST(OccDire[occRobustMode]) + HIST(OccDire[occMode]) + HIST(OccNames[occName]), weighted); } } // conditional filling end } @@ -1762,29 +1756,25 @@ struct TrackMeanOccTableProducer { return; } - if (meanTableMode == checkTableMode) { + if constexpr (meanTableMode == checkTableMode) { if (buildFlag00MeanTable) { executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, executeInThisBlock); } else { executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, executeInThisBlock); } - } - if constexpr (meanTableMode == checkTableMode) { return; } - if (weightMeanTableMode == checkTableMode) { + if constexpr (weightMeanTableMode == checkTableMode) { if (buildFlag01WeightMeanTable) { executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, executeInThisBlock); } else { executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, executeInThisBlock); } - } - if constexpr (weightMeanTableMode == checkTableMode) { return; } - if (qaMode == checkQAMode) { + if constexpr (qaMode == checkQAMode) { if (fillQA1 || fillQA2) { if (occsRobustT0V0Prim.size() == 0) { LOG(error) << "DEBUG :: ERROR ERROR ERROR :: OccsRobustT0V0Prim.size() == 0 :: Check \"occupancy-table-producer\" for \"buildOnlyOccsT0V0Prim == true\" & \"processOnlyOccT0V0PrimUnfm == true\""; @@ -1794,8 +1784,6 @@ struct TrackMeanOccTableProducer { } else { executeTrackOccProducerProcessing(BCs, collisions, tracks, tracksQA, occsRobustT0V0Prim, occs, executeInThisBlock); } - } - if constexpr (qaMode == checkQAMode) { return; } @@ -1803,7 +1791,7 @@ struct TrackMeanOccTableProducer { // BCs.bindExternalIndices(&occsNTrackDet); // BCs.bindExternalIndices(&occsRobust); - if constexpr (meanTableMode == checkTableMode || weightMeanTableMode == checkTableMode || qaMode == checkQAMode) { + if constexpr (meanTableMode == checkTableMode || weightMeanTableMode == checkTableMode) { return; } else { occupancyQA.fill(HIST("h_DFcount_Lvl2"), processMode); @@ -1958,16 +1946,16 @@ struct TrackMeanOccTableProducer { if (doAmbgUpdate) { // sKipping ambiguous tracks for now, will be updated in future continue; } - if (doCollisionUpdate || doAmbgUpdate) { // collision.globalIndex() != oldCollisionIndex){ //don't update if info is same as old collision + if (doCollisionUpdate) { // collision.globalIndex() != oldCollisionIndex){ //don't update if info is same as old collision if (doCollisionUpdate) { oldCollisionIndex = collision.globalIndex(); bc = collision.template bc_as(); } - if (doAmbgUpdate) { - // to be updated later - // bc = collisions.iteratorAt(2).bc_as(); - // bc = ambgTracks.iteratorAt(0).bc_as(); - } + // if (doAmbgUpdate) { + // to be updated later + // bc = collisions.iteratorAt(2).bc_as(); + // bc = ambgTracks.iteratorAt(0).bc_as(); + // } // LOG(info)<<" What happens in the case when the collision id is = -1 and it tries to obtain bc" getTimingInfo(bc, lastRun, nBCsPerTF, bcSOR, time, tfIdThis, bcInTF); } @@ -2421,7 +2409,6 @@ struct TrackMeanOccTableProducer { { occupancyQA.fill(HIST("h_DFcount_Lvl0"), kProcessNothing); return; - occupancyQA.fill(HIST("h_DFcount_Lvl1"), kProcessNothing); } PROCESS_SWITCH(TrackMeanOccTableProducer, processNothing, "process Nothing From Track Mean Occ Table Producer", true); diff --git a/Common/TableProducer/qVectorsTable.cxx b/Common/TableProducer/qVectorsTable.cxx index ba8af37b094..50b362ff3bf 100644 --- a/Common/TableProducer/qVectorsTable.cxx +++ b/Common/TableProducer/qVectorsTable.cxx @@ -256,6 +256,7 @@ struct qVectorsTable { AxisSpec axisChID = {220, 0, 220}; fv0geom = o2::fv0::Geometry::instance(o2::fv0::Geometry::eUninitialized); + ft0geom.calculateChannelCenter(); histosQA.add("ChTracks", "", {HistType::kTHnSparseF, {axisPt, axisEta, axisPhi, axixCent}}); histosQA.add("FT0Amp", "", {HistType::kTH2F, {axisFITamp, axisChID}}); diff --git a/Common/TableProducer/timestamp.cxx b/Common/TableProducer/timestamp.cxx deleted file mode 100644 index 30ad84150c5..00000000000 --- a/Common/TableProducer/timestamp.cxx +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// -/// \file timestamp.cxx -/// \author Nicolò Jacazio -/// \since 2020-06-22 -/// \brief A task to fill the timestamp table from run number. -/// Uses headers from CCDB -/// -#include "Common/Core/MetadataHelper.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -using namespace o2::framework; -using namespace o2::header; -using namespace o2; - -o2::common::core::MetadataHelper metadataInfo; // Metadata helper - -struct TimestampTask { - Produces timestampTable; /// Table with SOR timestamps produced by the task - Service ccdb; /// CCDB manager to access orbit-reset timestamp - o2::ccdb::CcdbApi ccdb_api; /// API to access CCDB headers - Configurable fatalOnInvalidTimestamp{"fatalOnInvalidTimestamp", false, "Generate fatal error for invalid timestamps"}; - std::map mapRunToOrbitReset; /// Cache of orbit reset timestamps - std::map> mapRunToRunDuration; /// Cache of run duration timestamps - int lastRunNumber = 0; /// Last run number processed - int64_t orbitResetTimestamp = 0; /// Orbit-reset timestamp in us - std::pair runDuration; /// Pair of SOR and EOR timestamps - - // Configurables - Configurable verbose{"verbose", false, "verbose mode"}; - Configurable rct_path{"rct-path", "RCT/Info/RunInformation", "path to the ccdb RCT objects for the SOR timestamps"}; - Configurable orbit_reset_path{"orbit-reset-path", "CTP/Calib/OrbitReset", "path to the ccdb orbit-reset objects"}; - Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "URL of the CCDB database"}; - Configurable isRun2MC{"isRun2MC", -1, "Running mode: enable only for Run 2 MC. Timestamps are set to SOR timestamp. Default: -1 (autoset from metadata) 0 (Standard) 1 (Run 2 MC)"}; - - void init(o2::framework::InitContext&) - { - LOGF(info, "Initializing TimestampTask"); - ccdb->setURL(url.value); // Setting URL of CCDB manager from configuration - ccdb_api.init(url.value); - if (!ccdb_api.isHostReachable()) { - LOGF(fatal, "CCDB host %s is not reacheable, cannot go forward", url.value.data()); - } - if (isRun2MC.value == -1) { - if ((!metadataInfo.isRun3()) && metadataInfo.isMC()) { - isRun2MC.value = 1; - LOG(info) << "Autosetting the Run2 MC mode based on metadata"; - } else { - isRun2MC.value = 0; - } - } - } - - void process(aod::BC const& bc) - { - int runNumber = bc.runNumber(); - // We need to set the orbit-reset timestamp for the run number. - // This is done with caching if the run number was already processed before. - // If not the orbit-reset timestamp for the run number is queried from CCDB and added to the cache - if (runNumber == lastRunNumber) { // The run number coincides to the last run processed - LOGF(debug, "Using orbit-reset timestamp from last call"); - } else if (mapRunToOrbitReset.count(runNumber)) { // The run number was already requested before: getting it from cache! - LOGF(debug, "Getting orbit-reset timestamp from cache"); - orbitResetTimestamp = mapRunToOrbitReset[runNumber]; - runDuration = mapRunToRunDuration[runNumber]; - } else { // The run was not requested before: need to acccess CCDB! - LOGF(debug, "Getting start-of-run and end-of-run timestamps from CCDB"); - runDuration = ccdb->getRunDuration(runNumber, true); /// fatalise if timestamps are not found - int64_t sorTimestamp = runDuration.first; // timestamp of the SOR/SOX/STF in ms - int64_t eorTimestamp = runDuration.second; // timestamp of the EOR/EOX/ETF in ms - - const bool isUnanchoredRun3MC = runNumber >= 300000 && runNumber < 500000; - if (isRun2MC.value == 1 || isUnanchoredRun3MC) { - // isRun2MC: bc/orbit distributions are not simulated in Run2 MC. All bcs are set to 0. - // isUnanchoredRun3MC: assuming orbit-reset is done in the beginning of each run - // Setting orbit-reset timestamp to start-of-run timestamp - orbitResetTimestamp = sorTimestamp * 1000; // from ms to us - } else if (runNumber < 300000) { // Run 2 - LOGF(debug, "Getting orbit-reset timestamp using start-of-run timestamp from CCDB"); - auto ctp = ccdb->getForTimeStamp>(orbit_reset_path.value.data(), sorTimestamp); - orbitResetTimestamp = (*ctp)[0]; - } else { - // sometimes orbit is reset after SOR. Using EOR timestamps for orbitReset query is more reliable - LOGF(debug, "Getting orbit-reset timestamp using end-of-run timestamp from CCDB"); - auto ctp = ccdb->getForTimeStamp>(orbit_reset_path.value.data(), eorTimestamp / 2 + sorTimestamp / 2); - orbitResetTimestamp = (*ctp)[0]; - } - - // Adding the timestamp to the cache map - std::pair::iterator, bool> check; - check = mapRunToOrbitReset.insert(std::pair(runNumber, orbitResetTimestamp)); - if (!check.second) { - LOGF(fatal, "Run number %i already existed with a orbit-reset timestamp of %llu", runNumber, check.first->second); - } - mapRunToRunDuration[runNumber] = runDuration; - LOGF(info, "Add new run number %i with orbit-reset timestamp %llu, SOR: %llu, EOR: %llu to cache", runNumber, orbitResetTimestamp, runDuration.first, runDuration.second); - } - - if (verbose.value) { - LOGF(info, "Orbit-reset timestamp for run number %i found: %llu us", runNumber, orbitResetTimestamp); - } - int64_t timestamp{(orbitResetTimestamp + int64_t(bc.globalBC() * o2::constants::lhc::LHCBunchSpacingNS * 1e-3)) / 1000}; // us -> ms - if (timestamp < runDuration.first || timestamp > runDuration.second) { - if (fatalOnInvalidTimestamp.value) { - LOGF(fatal, "Timestamp %llu us is out of run duration [%llu, %llu] ms", timestamp, runDuration.first, runDuration.second); - } else { - LOGF(debug, "Timestamp %llu us is out of run duration [%llu, %llu] ms", timestamp, runDuration.first, runDuration.second); - } - } - timestampTable(timestamp); - } -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - // Parse the metadata - metadataInfo.initMetadata(cfgc); - - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} diff --git a/Common/TableProducer/trackPropagation.cxx b/Common/TableProducer/trackPropagation.cxx deleted file mode 100644 index cb27b54210f..00000000000 --- a/Common/TableProducer/trackPropagation.cxx +++ /dev/null @@ -1,377 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -// -// Task to add a table of track parameters propagated to the primary vertex -// - -#include "Common/Core/TableHelper.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/Tools/TrackTuner.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -// The Run 3 AO2D stores the tracks at the point of innermost update. For a track with ITS this is the innermost (or second innermost) -// ITS layer. For a track without ITS, this is the TPC inner wall or for loopers in the TPC even a radius beyond that. -// In order to use the track parameters, the tracks have to be propagated to the collision vertex which is done by this task. -// The task consumes the TracksIU and TracksCovIU tables and produces Tracks and TracksCov to which then the user analysis can subscribe. -// -// This task is not needed for Run 2 converted data. -// There are two versions of the task (see process flags), one producing also the covariance matrix and the other only the tracks table. - -using namespace o2; -using namespace o2::framework; -// using namespace o2::framework::expressions; - -struct TrackPropagation { - Produces tracksParPropagated; - Produces tracksParExtensionPropagated; - - Produces tracksParCovPropagated; - Produces tracksParCovExtensionPropagated; - - Produces tracksDCA; - Produces tracksDCACov; - - Produces tunertable; - - Service ccdb; - - bool fillTracksDCA = false; - bool fillTracksDCACov = false; - int runNumber = -1; - - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; - - const o2::dataformats::MeanVertexObject* mMeanVtx = nullptr; - o2::parameters::GRPMagField* grpmag = nullptr; - o2::base::MatLayerCylSet* lut = nullptr; - TrackTuner trackTunerObj; - - Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; - Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; - Configurable minPropagationRadius{"minPropagationDistance", o2::constants::geom::XTPCInnerRef + 0.1, "Only tracks which are at a smaller radius will be propagated, defaults to TPC inner wall"}; - // for TrackTuner only (MC smearing) - Configurable useTrackTuner{"useTrackTuner", false, "Apply track tuner corrections to MC"}; - Configurable fillTrackTunerTable{"fillTrackTunerTable", false, "flag to fill track tuner table"}; - Configurable trackTunerConfigSource{"trackTunerConfigSource", aod::track_tuner::InputString, "1: input string; 2: TrackTuner Configurables"}; - Configurable trackTunerParams{"trackTunerParams", "debugInfo=0|updateTrackDCAs=1|updateTrackCovMat=1|updateCurvature=0|updateCurvatureIU=0|updatePulls=0|isInputFileFromCCDB=1|pathInputFile=Users/m/mfaggin/test/inputsTrackTuner/PbPb2022|nameInputFile=trackTuner_DataLHC22sPass5_McLHC22l1b2_run529397.root|pathFileQoverPt=Users/h/hsharma/qOverPtGraphs|nameFileQoverPt=D0sigma_Data_removal_itstps_MC_LHC22b1b.root|usePvRefitCorrections=0|qOverPtMC=-1.|qOverPtData=-1.", "TrackTuner parameter initialization (format: =|=)"}; - ConfigurableAxis axisPtQA{"axisPtQA", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for QA histograms"}; - OutputObj trackTunedTracks{TH1D("trackTunedTracks", "", 1, 0.5, 1.5), OutputObjHandlingPolicy::AnalysisObject}; - - // OutputObj hDCAxyVsPtRec{TH2F("hDCAxyVsPtRec", ";DCAxy;PtRec", 600, -0.15, 0.15, axisPtQA)}; - // OutputObj hDCAxyVsPtMC{TH2F("hDCAxyVsPtMC", ";DCAxy;PtMC", 600, -0.15, 0.15, axisPtQA)}; - - using TracksIUWithMc = soa::Join; - - HistogramRegistry registry{"registry"}; - - void init(o2::framework::InitContext& initContext) - { - int nEnabledProcesses = 0; - if (doprocessStandard) { - LOG(info) << "Enabling processStandard"; - nEnabledProcesses++; - } - if (doprocessCovarianceMc) { - LOG(info) << "Enabling processCovarianceMc"; - nEnabledProcesses++; - } - - if (doprocessCovariance) { - LOG(info) << "Enabling processCovariance"; - nEnabledProcesses++; - } - - if (doprocessStandardWithPID) { - LOG(info) << "Enabling processStandardWithPID"; - nEnabledProcesses++; - } - if (doprocessCovarianceWithPID) { - LOG(info) << "Enabling processCovarianceWithPID"; - nEnabledProcesses++; - } - if (nEnabledProcesses != 1) { - LOG(fatal) << "Exactly one process flag must be set to true. Please choose one."; - } - // Checking if the tables are requested in the workflow and enabling them - fillTracksDCA = o2::common::core::isTableRequiredInWorkflow(initContext, "TracksDCA"); - fillTracksDCACov = o2::common::core::isTableRequiredInWorkflow(initContext, "TracksDCACov"); - - ccdb->setURL(ccdburl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - - // Histograms for track tuner - AxisSpec axisBinsDCA = {600, -0.15f, 0.15f, "#it{dca}_{xy} (cm)"}; - registry.add("hDCAxyVsPtRec", "hDCAxyVsPtRec", kTH2F, {axisBinsDCA, axisPtQA}); - registry.add("hDCAxyVsPtMC", "hDCAxyVsPtMC", kTH2F, {axisBinsDCA, axisPtQA}); - registry.add("hDCAzVsPtRec", "hDCAzVsPtRec", kTH2F, {axisBinsDCA, axisPtQA}); - registry.add("hDCAzVsPtMC", "hDCAzVsPtMC", kTH2F, {axisBinsDCA, axisPtQA}); - - /// TrackTuner initialization - if (useTrackTuner) { - std::string outputStringParams = ""; - switch (trackTunerConfigSource) { - case aod::track_tuner::InputString: - outputStringParams = trackTunerObj.configParams(trackTunerParams); - break; - case aod::track_tuner::Configurables: - outputStringParams = trackTunerObj.configParams(); - break; - - default: - LOG(fatal) << "TrackTuner configuration source not defined. Fix it! (Supported options: input string (1); Configurables (2))"; - break; - } - - trackTunerObj.getDcaGraphs(); - trackTunedTracks->SetTitle(outputStringParams.c_str()); - trackTunedTracks->GetXaxis()->SetBinLabel(1, "all tracks"); - } - } - - void initCCDB(aod::BCsWithTimestamps::iterator const& bc) - { - if (runNumber == bc.runNumber()) { - return; - } - - // load matLUT for this timestamp - if (!lut) { - LOG(info) << "Loading material look-up table for timestamp: " << bc.timestamp(); - lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->getForTimeStamp(lutPath, bc.timestamp())); - } else { - LOG(info) << "Material look-up table already in place. Not reloading."; - } - - grpmag = ccdb->getForTimeStamp(grpmagPath, bc.timestamp()); - LOG(info) << "Setting magnetic field to current " << grpmag->getL3Current() << " A for run " << bc.runNumber() << " from its GRPMagField CCDB object"; - o2::base::Propagator::initFieldFromGRP(grpmag); - o2::base::Propagator::Instance()->setMatLUT(lut); - mMeanVtx = ccdb->getForTimeStamp(mVtxPath, bc.timestamp()); - runNumber = bc.runNumber(); - } - - // Running variables - std::array mDcaInfo; - o2::dataformats::DCA mDcaInfoCov; - o2::dataformats::VertexBase mVtx; - o2::track::TrackParametrization mTrackPar; - o2::track::TrackParametrizationWithError mTrackParCov; - - template - void fillTrackTables(TTrack const& tracks, - TParticle const&, - aod::Collisions const&, - aod::BCsWithTimestamps const& bcs) - { - if (bcs.size() == 0) { - return; - } - initCCDB(bcs.begin()); - - if constexpr (fillCovMat) { - tracksParCovPropagated.reserve(tracks.size()); - tracksParCovExtensionPropagated.reserve(tracks.size()); - if (fillTracksDCACov) { - tracksDCACov.reserve(tracks.size()); - } - } else { - tracksParPropagated.reserve(tracks.size()); - tracksParExtensionPropagated.reserve(tracks.size()); - if (fillTracksDCA) { - tracksDCA.reserve(tracks.size()); - } - } - - for (auto& track : tracks) { - if constexpr (fillCovMat) { - if (fillTracksDCA || fillTracksDCACov) { - mDcaInfoCov.set(999, 999, 999, 999, 999); - } - setTrackParCov(track, mTrackParCov); - if constexpr (useTrkPid) { - mTrackParCov.setPID(track.pidForTracking()); - } - } else { - if (fillTracksDCA) { - mDcaInfo[0] = 999; - mDcaInfo[1] = 999; - } - setTrackPar(track, mTrackPar); - if constexpr (useTrkPid) { - mTrackPar.setPID(track.pidForTracking()); - } - } - // auto trackParCov = getTrackParCov(track); - aod::track::TrackTypeEnum trackType = (aod::track::TrackTypeEnum)track.trackType(); - // std::array trackPxPyPz; - // std::array trackPxPyPzTuned = {0.0, 0.0, 0.0}; - double q2OverPtNew = -9999.; - // Only propagate tracks which have passed the innermost wall of the TPC (e.g. skipping loopers etc). Others fill unpropagated. - if (track.trackType() == aod::track::TrackIU && track.x() < minPropagationRadius) { - if constexpr (isMc && fillCovMat) { // checking MC and fillCovMat block begins - // bool hasMcParticle = track.has_mcParticle(); - if (useTrackTuner) { - trackTunedTracks->Fill(1); // all tracks - bool hasMcParticle = track.has_mcParticle(); - if (hasMcParticle) { - auto mcParticle = track.mcParticle(); - trackTunerObj.tuneTrackParams(mcParticle, mTrackParCov, matCorr, &mDcaInfoCov, trackTunedTracks); - q2OverPtNew = mTrackParCov.getQ2Pt(); - } - } - } // MC and fillCovMat block ends - bool isPropagationOK = true; - - if (track.has_collision()) { - auto const& collision = track.collision(); - if constexpr (fillCovMat) { - mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - isPropagationOK = o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, mTrackParCov, 2.f, matCorr, &mDcaInfoCov); - } else { - isPropagationOK = o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, mTrackPar, 2.f, matCorr, &mDcaInfo); - } - } else { - if constexpr (fillCovMat) { - mVtx.setPos({mMeanVtx->getX(), mMeanVtx->getY(), mMeanVtx->getZ()}); - mVtx.setCov(mMeanVtx->getSigmaX() * mMeanVtx->getSigmaX(), 0.0f, mMeanVtx->getSigmaY() * mMeanVtx->getSigmaY(), 0.0f, 0.0f, mMeanVtx->getSigmaZ() * mMeanVtx->getSigmaZ()); - isPropagationOK = o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, mTrackParCov, 2.f, matCorr, &mDcaInfoCov); - } else { - isPropagationOK = o2::base::Propagator::Instance()->propagateToDCABxByBz({mMeanVtx->getX(), mMeanVtx->getY(), mMeanVtx->getZ()}, mTrackPar, 2.f, matCorr, &mDcaInfo); - } - } - if (isPropagationOK) { - trackType = aod::track::Track; - } - // filling some QA histograms for track tuner test purpose - if constexpr (isMc && fillCovMat) { // checking MC and fillCovMat block begins - if (track.has_mcParticle() && isPropagationOK) { - auto mcParticle1 = track.mcParticle(); - // && abs(mcParticle1.pdgCode())==211 - if (mcParticle1.isPhysicalPrimary()) { - registry.fill(HIST("hDCAxyVsPtRec"), mDcaInfoCov.getY(), mTrackParCov.getPt()); - registry.fill(HIST("hDCAxyVsPtMC"), mDcaInfoCov.getY(), mcParticle1.pt()); - registry.fill(HIST("hDCAzVsPtRec"), mDcaInfoCov.getZ(), mTrackParCov.getPt()); - registry.fill(HIST("hDCAzVsPtMC"), mDcaInfoCov.getZ(), mcParticle1.pt()); - } - } - } // MC and fillCovMat block ends - } - // Filling modified Q/Pt values at IU/production point by track tuner in track tuner table - if (useTrackTuner && fillTrackTunerTable) { - tunertable(q2OverPtNew); - } - // LOG(info) << " trackPropagation (this value filled in tuner table)--> " << q2OverPtNew; - if constexpr (fillCovMat) { - tracksParPropagated(track.collisionId(), trackType, mTrackParCov.getX(), mTrackParCov.getAlpha(), mTrackParCov.getY(), mTrackParCov.getZ(), mTrackParCov.getSnp(), mTrackParCov.getTgl(), mTrackParCov.getQ2Pt()); - tracksParExtensionPropagated(mTrackParCov.getPt(), mTrackParCov.getP(), mTrackParCov.getEta(), mTrackParCov.getPhi()); - // TODO do we keep the rho as 0? Also the sigma's are duplicated information - tracksParCovPropagated(std::sqrt(mTrackParCov.getSigmaY2()), std::sqrt(mTrackParCov.getSigmaZ2()), std::sqrt(mTrackParCov.getSigmaSnp2()), - std::sqrt(mTrackParCov.getSigmaTgl2()), std::sqrt(mTrackParCov.getSigma1Pt2()), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - tracksParCovExtensionPropagated(mTrackParCov.getSigmaY2(), mTrackParCov.getSigmaZY(), mTrackParCov.getSigmaZ2(), mTrackParCov.getSigmaSnpY(), - mTrackParCov.getSigmaSnpZ(), mTrackParCov.getSigmaSnp2(), mTrackParCov.getSigmaTglY(), mTrackParCov.getSigmaTglZ(), mTrackParCov.getSigmaTglSnp(), - mTrackParCov.getSigmaTgl2(), mTrackParCov.getSigma1PtY(), mTrackParCov.getSigma1PtZ(), mTrackParCov.getSigma1PtSnp(), mTrackParCov.getSigma1PtTgl(), - mTrackParCov.getSigma1Pt2()); - if (fillTracksDCA) { - tracksDCA(mDcaInfoCov.getY(), mDcaInfoCov.getZ()); - } - if (fillTracksDCACov) { - tracksDCACov(mDcaInfoCov.getSigmaY2(), mDcaInfoCov.getSigmaZ2()); - } - } else { - tracksParPropagated(track.collisionId(), trackType, mTrackPar.getX(), mTrackPar.getAlpha(), mTrackPar.getY(), mTrackPar.getZ(), mTrackPar.getSnp(), mTrackPar.getTgl(), mTrackPar.getQ2Pt()); - tracksParExtensionPropagated(mTrackPar.getPt(), mTrackPar.getP(), mTrackPar.getEta(), mTrackPar.getPhi()); - if (fillTracksDCA) { - tracksDCA(mDcaInfo[0], mDcaInfo[1]); - } - } - } - } - - void processStandard(aod::StoredTracksIU const& tracks, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) - { - fillTrackTables(tracks, tracks, collisions, bcs); - } - PROCESS_SWITCH(TrackPropagation, processStandard, "Process without covariance", true); - - void processStandardWithPID(soa::Join const& tracks, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) - { - fillTrackTables, /*Particle*/ soa::Join, /*isMc = */ false, /*fillCovMat =*/false, /*useTrkPid =*/true>(tracks, tracks, collisions, bcs); - } - PROCESS_SWITCH(TrackPropagation, processStandardWithPID, "Process without covariance and with PID in tracking", false); - - // ----------------------- - void processCovarianceMc(TracksIUWithMc const& tracks, aod::McParticles const& mcParticles, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) - { - // auto table_extension = soa::Extend(tracks); - fillTrackTables(tracks, mcParticles, collisions, bcs); - } - PROCESS_SWITCH(TrackPropagation, processCovarianceMc, "Process with covariance on MC", false); - - void processCovariance(soa::Join const& tracks, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) - { - fillTrackTables, /*Particle*/ soa::Join, /*isMc = */ false, /*fillCovMat =*/true, /*useTrkPid =*/false>(tracks, tracks, collisions, bcs); - } - PROCESS_SWITCH(TrackPropagation, processCovariance, "Process with covariance", false); - // ------------------------ - - void processCovarianceWithPID(soa::Join const& tracks, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) - { - fillTrackTables, /*Particle*/ soa::Join, /*isMc = */ false, /*fillCovMat =*/true, /*useTrkPid =*/false>(tracks, tracks, collisions, bcs); - } - PROCESS_SWITCH(TrackPropagation, processCovarianceWithPID, "Process with covariance and with PID in tracking", false); -}; - -//**************************************************************************************** -/** - * Workflow definition. - */ -//**************************************************************************************** -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; - return workflow; -} diff --git a/Common/TableProducer/zdcExtraTableProducer.cxx b/Common/TableProducer/zdcExtraTableProducer.cxx index f0a5cc9080e..e04c55f30d7 100644 --- a/Common/TableProducer/zdcExtraTableProducer.cxx +++ b/Common/TableProducer/zdcExtraTableProducer.cxx @@ -33,6 +33,9 @@ #include #include +#include + +#include #include #include @@ -52,10 +55,12 @@ struct ZdcExtraTableProducer { // Configurable nBins{"nBins", 400, "n bins"}; Configurable maxZN{"maxZN", 399.5, "Max ZN signal"}; - Configurable tdcCut{"tdcCut", false, "Flag for TDC cut"}; - Configurable tdcZNmincut{"tdcZNmincut", -2.5, "Min ZN TDC cut"}; - Configurable tdcZNmaxcut{"tdcZNmaxcut", 2.5, "Max ZN TDC cut"}; - Configurable cfgUsePMC{"cfgUsePMC", true, "Use common PM (true) or sum of PMs (false) "}; + Configurable applyTdcCut{"applyTdcCut", false, "Flag for TDC cut"}; + Configurable tdcZnMin{"tdcZnMin", -2.5, "Min ZN TDC cut"}; + Configurable tdcZnMax{"tdcZnMax", 2.5, "Max ZN TDC cut"}; + Configurable useCfactor{"useCfactor", true, "Use C normalization factor (depends on multiplicity) for centroid calculation"}; + Configurable usePMC{"usePMC", true, "Use common PM (true) or sum of PMs (false) "}; + // Event selections Configurable cfgEvSelSel8{"cfgEvSelSel8", true, "Event selection: sel8"}; Configurable cfgEvSelVtxZ{"cfgEvSelVtxZ", 10, "Event selection: zVtx"}; @@ -66,11 +71,10 @@ struct ZdcExtraTableProducer { Configurable cfgEvSelsNoCollInTimeRangeStandard{"cfgEvSelsNoCollInTimeRangeStandard", false, "Event selection: no collision in time range standard"}; Configurable cfgEvSelsIsVertexITSTPC{"cfgEvSelsIsVertexITSTPC", false, "Event selection: is vertex ITSTPC"}; Configurable cfgEvSelsIsGoodITSLayersAll{"cfgEvSelsIsGoodITSLayersAll", false, "Event selection: is good ITS layers all"}; - // Calibration settings - Configurable cfgCalibrationDownscaling{"cfgCalibrationDownscaling", 1.f, "Percentage of events to be saved to derived table"}; // Output settings - Configurable cfgSaveQaHistos{"cfgSaveQaHistos", false, "Flag to save QA histograms"}; + Configurable calibrationDownscaling{"calibrationDownscaling", 1.f, "Percentage of events to be saved to derived table"}; + Configurable saveQaHistos{"saveQaHistos", false, "Flag to save QA histograms"}; enum SelectionCriteria { ZVtxCut, @@ -102,7 +106,7 @@ struct ZdcExtraTableProducer { registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(IsGoodITSLayersAll + 1, "IsGoodITSLayersAll"); // Skip histogram registration if QA flag is false - if (!cfgSaveQaHistos) { + if (!saveQaHistos) { return; } @@ -124,10 +128,10 @@ struct ZdcExtraTableProducer { } template - uint8_t eventSelected(TCollision collision) + uint8_t eventSelected(TCollision const& collision) { uint8_t selectionBits = 0; - bool selected; + bool selected = false; registry.fill(HIST("hEventCount"), AllEvents); @@ -234,11 +238,11 @@ struct ZdcExtraTableProducer { double tdcZNA = zdc.timeZNA(); // OR we can select a narrow window in both ZN TDCs using the configurable parameters - if (tdcCut) { // a narrow TDC window is set - if ((tdcZNC >= tdcZNmincut) && (tdcZNC <= tdcZNmaxcut)) { + if (applyTdcCut) { // a narrow TDC window is set + if ((tdcZNC >= tdcZnMin) && (tdcZNC <= tdcZnMax)) { isZNChit = true; } - if ((tdcZNA >= tdcZNmincut) && (tdcZNA <= tdcZNmaxcut)) { + if ((tdcZNA >= tdcZnMin) && (tdcZNA <= tdcZnMax)) { isZNAhit = true; } } else { // if no window on TDC is set @@ -252,8 +256,8 @@ struct ZdcExtraTableProducer { // double sumZNC = 0; double sumZNA = 0; - double pmqZNC[4] = {}; - double pmqZNA[4] = {}; + std::array pmqZNC = {}; + std::array pmqZNA = {}; // if (isZNChit) { for (int it = 0; it < NTowers; it++) { @@ -261,7 +265,7 @@ struct ZdcExtraTableProducer { sumZNC += pmqZNC[it]; } - if (cfgSaveQaHistos) { + if (saveQaHistos) { registry.get(HIST("ZNCpmc"))->Fill(pmcZNC); registry.get(HIST("ZNCpm1"))->Fill(pmqZNC[0]); registry.get(HIST("ZNCpm2"))->Fill(pmqZNC[1]); @@ -276,7 +280,7 @@ struct ZdcExtraTableProducer { sumZNA += pmqZNA[it]; } // - if (cfgSaveQaHistos) { + if (saveQaHistos) { registry.get(HIST("ZNApmc"))->Fill(pmcZNA); registry.get(HIST("ZNApm1"))->Fill(pmqZNA[0]); registry.get(HIST("ZNApm2"))->Fill(pmqZNA[1]); @@ -291,8 +295,8 @@ struct ZdcExtraTableProducer { constexpr float kBeamEne = 5.36 * 0.5; // Provide coordinates of centroid over ZN (side C) front face - constexpr float X[4] = {-1.75, 1.75, -1.75, 1.75}; - constexpr float Y[4] = {-1.75, -1.75, 1.75, 1.75}; + constexpr std::array X = {-1.75, 1.75, -1.75, 1.75}; + constexpr std::array Y = {-1.75, -1.75, 1.75, 1.75}; constexpr float kAlpha = 0.395; // saturation correction float numXZNC = 0., numYZNC = 0., denZNC = 0.; @@ -318,8 +322,8 @@ struct ZdcExtraTableProducer { float zncCommon = 0; float znaCommon = 0; - // Use sum of PMTs (cfgUsePMC == false) when common PMT is saturated - if (cfgUsePMC) { + // Use sum of PMTs (usePMC == false) when common PMT is saturated + if (usePMC) { zncCommon = pmcZNC; znaCommon = pmcZNA; } else { @@ -327,11 +331,17 @@ struct ZdcExtraTableProducer { znaCommon = sumZNA; } - float centroidZNC[2], centroidZNA[2]; + std::array centroidZNC = {}; + std::array centroidZNA = {}; if (denZNC != 0.) { - float nSpecnC = zncCommon / kBeamEne; - float cZNC = 1.89358 - 0.71262 / (nSpecnC + 0.71789); + float cZNC = 1.0; + + if (useCfactor) { + float nSpecnC = zncCommon / kBeamEne; + cZNC = 1.89358 - 0.71262 / (nSpecnC + 0.71789); + } + centroidZNC[0] = cZNC * numXZNC / denZNC; centroidZNC[1] = cZNC * numYZNC / denZNC; } else { @@ -340,15 +350,19 @@ struct ZdcExtraTableProducer { } // if (denZNA != 0.) { - float nSpecnA = znaCommon / kBeamEne; - float cZNA = 1.89358 - 0.71262 / (nSpecnA + 0.71789); + float cZNA = 1.0; + if (useCfactor) { + float nSpecnA = znaCommon / kBeamEne; + cZNA = 1.89358 - 0.71262 / (nSpecnA + 0.71789); + } + centroidZNA[0] = cZNA * numXZNA / denZNA; centroidZNA[1] = cZNA * numYZNA / denZNA; } else { centroidZNA[0] = 999.; centroidZNA[1] = 999.; } - if (cfgSaveQaHistos) { + if (saveQaHistos) { if (isZNChit) { registry.get(HIST("ZNCCentroid"))->Fill(centroidZNC[0], centroidZNC[1]); } @@ -361,7 +375,7 @@ struct ZdcExtraTableProducer { auto vx = collision.posX(); auto vy = collision.posY(); - if ((isZNAhit || isZNChit) && (gRandom->Uniform() < cfgCalibrationDownscaling)) { + if ((isZNAhit || isZNChit) && (gRandom->Uniform() < calibrationDownscaling)) { zdcextras(pmcZNA, pmqZNA[0], pmqZNA[1], pmqZNA[2], pmqZNA[3], tdcZNA, centroidZNA[0], centroidZNA[1], pmcZNC, pmqZNC[0], pmqZNC[1], pmqZNC[2], pmqZNC[3], tdcZNC, centroidZNC[0], centroidZNC[1], centrality, vx, vy, vz, foundBC.timestamp(), foundBC.runNumber(), evSelection); } } diff --git a/Common/Tasks/CMakeLists.txt b/Common/Tasks/CMakeLists.txt index 5c09a5e1d0d..bc40024c43e 100644 --- a/Common/Tasks/CMakeLists.txt +++ b/Common/Tasks/CMakeLists.txt @@ -102,4 +102,9 @@ o2physics_add_dpl_workflow(muon-qa o2physics_add_dpl_workflow(zdc-table-reader SOURCES zdcTableReader.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) \ No newline at end of file + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(zdc-extra-table-reader + SOURCES zdcExtraTableReader.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/Common/Tasks/centralityQa.cxx b/Common/Tasks/centralityQa.cxx index 4baf784205a..b1889f5e00f 100644 --- a/Common/Tasks/centralityQa.cxx +++ b/Common/Tasks/centralityQa.cxx @@ -24,11 +24,15 @@ #include #include #include +#include +#include +#include #include #include -#include +#include +#include #include #include diff --git a/Common/Tasks/centralityStudy.cxx b/Common/Tasks/centralityStudy.cxx index 1bfab6c5835..5180e216be9 100644 --- a/Common/Tasks/centralityStudy.cxx +++ b/Common/Tasks/centralityStudy.cxx @@ -253,6 +253,9 @@ struct centralityStudy { histos.add("hFT0C_Collisions", "hFT0C_Collisions", kTH1D, {axisMultUltraFineFT0C}); histos.add("hFT0M_Collisions", "hFT0M_Collisions", kTH1D, {axisMultUltraFineFT0M}); histos.add("hFV0A_Collisions", "hFV0A_Collisions", kTH1D, {axisMultUltraFineFV0A}); + histos.add("hFT0AOuter_Collisions", "hFT0AOuter_Collisions", kTH1D, {axisMultUltraFineFT0A}); + histos.add("hFT0MOuterA_Collisions", "hFT0MOuterA_Collisions", kTH1D, {axisMultUltraFineFT0M}); + histos.add("hNGlobalTracks", "hNGlobalTracks", kTH1D, {axisMultUltraFineGlobalTracks}); histos.add("hNMFTTracks", "hNMFTTracks", kTH1D, {axisMultUltraFineMFTTracks}); histos.add("hNPVContributors", "hNPVContributors", kTH1D, {axisMultUltraFinePVContributors}); @@ -272,6 +275,7 @@ struct centralityStudy { // 2d correlation of fit signals histos.add("hFT0AVsFT0C", "hFT0AVsFT0C", kTH2F, {axisMultFT0C, axisMultFT0A}); histos.add("hFV0AVsFT0C", "hFV0AVsFT0C", kTH2F, {axisMultFT0C, axisMultFV0A}); + histos.add("hFT0AOuterVsFT0C", "hFT0AOuterVsFT0C", kTH2F, {axisMultFT0C, axisMultFT0A}); histos.add("hFDDAVsFT0C", "hFDDAVsFT0C", kTH2F, {axisMultFT0C, axisMultFDDA}); histos.add("hFDDCVsFT0C", "hFDDCVsFT0C", kTH2F, {axisMultFT0C, axisMultFDDC}); } @@ -344,7 +348,9 @@ struct centralityStudy { histos.add("hFT0C_BCs", "hFT0C_BCs", kTH1D, {axisMultUltraFineFT0C}); histos.add("hFT0A_BCs", "hFT0A_BCs", kTH1D, {axisMultUltraFineFT0A}); + histos.add("hFT0AOuter_BCs", "hFT0AOuter_BCs", kTH1D, {axisMultUltraFineFT0A}); histos.add("hFT0M_BCs", "hFT0M_BCs", kTH1D, {axisMultUltraFineFT0M}); + histos.add("hFT0MOuterA_BCs", "hFT0MOuterA_BCs", kTH1D, {axisMultUltraFineFT0M}); histos.add("hFV0A_BCs", "hFV0A_BCs", kTH1D, {axisMultUltraFineFV0A}); histos.add("hInteractionRate_BCs", "hInteractionRate_BCs", kTH1D, {axisInteractionRate}); @@ -512,6 +518,8 @@ struct centralityStudy { histPointers.insert({histPath + "hFT0C_Collisions", histos.add((histPath + "hFT0C_Collisions").c_str(), "hFT0C_Collisions", {kTH1D, {{axisMultUltraFineFT0C}}})}); histPointers.insert({histPath + "hFT0A_Collisions", histos.add((histPath + "hFT0A_Collisions").c_str(), "hFT0A_Collisions", {kTH1D, {{axisMultUltraFineFT0A}}})}); + histPointers.insert({histPath + "hFT0AOuter_Collisions", histos.add((histPath + "hFT0AOuter_Collisions").c_str(), "hFT0AOuter_Collisions", {kTH1D, {{axisMultUltraFineFT0C}}})}); + histPointers.insert({histPath + "hFT0MOuterA_Collisions", histos.add((histPath + "hFT0MOuterA_Collisions").c_str(), "hFT0MOuterA_Collisions", {kTH1D, {{axisMultUltraFineFT0A}}})}); histPointers.insert({histPath + "hFT0M_Collisions", histos.add((histPath + "hFT0M_Collisions").c_str(), "hFT0M_Collisions", {kTH1D, {{axisMultUltraFineFT0M}}})}); histPointers.insert({histPath + "hFV0A_Collisions", histos.add((histPath + "hFV0A_Collisions").c_str(), "hFV0A_Collisions", {kTH1D, {{axisMultUltraFineFV0A}}})}); histPointers.insert({histPath + "hNGlobalTracks", histos.add((histPath + "hNGlobalTracks").c_str(), "hNGlobalTracks", {kTH1D, {{axisMultUltraFineGlobalTracks}}})}); @@ -546,6 +554,7 @@ struct centralityStudy { histPointers.insert({histPath + "hFV0AVsFT0C", histos.add((histPath + "hFV0AVsFT0C").c_str(), "hFV0AVsFT0C", {kTH2F, {{axisMultFT0C, axisMultFV0A}}})}); histPointers.insert({histPath + "hFDDAVsFT0C", histos.add((histPath + "hFDDAVsFT0C").c_str(), "hFDDAVsFT0C", {kTH2F, {{axisMultFT0C, axisMultFDDA}}})}); histPointers.insert({histPath + "hFDDCVsFT0C", histos.add((histPath + "hFDDCVsFT0C").c_str(), "hFDDCVsFT0C", {kTH2F, {{axisMultFT0C, axisMultFDDC}}})}); + histPointers.insert({histPath + "hFT0AOuterVsFT0C", histos.add((histPath + "hFT0AOuterVsFT0C").c_str(), "hFT0AOuterVsFT0C", {kTH2F, {{axisMultFT0C, axisMultFT0A}}})}); } if (doprocessCollisionsWithCentrality || ccdbSettings.fetchCentralityCalibration) { @@ -795,14 +804,18 @@ struct centralityStudy { getHist(TH1, histPath + "hCollisionSelection")->Fill(15); } if (evsel.rejectIsFlangeEvent) { - if constexpr (requires { collision.ft0TriggerMask(); }) { - constexpr int IsFlangeEventId = 7; - std::bitset<8> ft0TriggerMask = collision.ft0TriggerMask(); - if (ft0TriggerMask[IsFlangeEventId]) { - return; + if constexpr (requires { collision.has_multBC(); }) { + if (collision.has_multBC()) { + auto multbc = collision.template multBC_as>(); + constexpr int IsFlangeEventId = 7; + std::bitset<8> ft0TriggerMask = multbc.multT0triggerBits(); + if (ft0TriggerMask[IsFlangeEventId]) { + return; + } } } } + histos.fill(HIST("hCollisionSelection"), 16 /* reject flange events */); if (studies.doRunByRunHistograms) { getHist(TH1, histPath + "hCollisionSelection")->Fill(16); @@ -949,25 +962,37 @@ struct centralityStudy { if constexpr (requires { collision.has_multBC(); }) { if (collision.has_multBC()) { - auto multbc = collision.template multBC_as(); + auto multbc = collision.template multBC_as>(); + histos.fill(HIST("hFT0AOuter_Collisions"), multbc.multFT0AOuter() * scale.factorFT0A); + histos.fill(HIST("hFT0MOuterA_Collisions"), multbc.multFT0AOuter() + multbc.multFT0C() * scale.factorFT0M); + if (studies.do2DPlots) { + histos.fill(HIST("hFT0AOuterVsFT0C"), multbc.multFT0C() * scale.factorFT0C, multbc.multFT0AOuter() * scale.factorFT0A); + } + const uint64_t bcTimestamp = multbc.timestamp(); const float interactionRate = mRateFetcher.fetch(ccdb.service, bcTimestamp, mRunNumber, ccdbSettings.irSource.value, ccdbSettings.irCrashOnNull) / 1000.; // kHz histos.fill(HIST("hInteractionRate"), interactionRate); if (doprocessCollisionsWithCentrality || ccdbSettings.fetchCentralityCalibration) { histos.fill(HIST("hInteractionRateVsCentrality"), centFT0C, interactionRate); - } - if (studies.doRunByRunHistograms) { - getHist(TH2, histPath + "hInteractionRateVsCentrality")->Fill(centFT0C, interactionRate); + if (studies.doRunByRunHistograms) { + getHist(TH2, histPath + "hInteractionRateVsCentrality")->Fill(centFT0C, interactionRate); + } } if (studies.doRunByRunHistograms) { getHist(TH1, histPath + "hInteractionRate")->Fill(interactionRate); + getHist(TH1, histPath + "hFT0AOuter_Collisions")->Fill(multbc.multFT0AOuter() * scale.factorFT0A); + getHist(TH1, histPath + "hFT0MOuterA_Collisions")->Fill(multbc.multFT0AOuter() + multbc.multFT0C() * scale.factorFT0M); + if (studies.do2DPlots) { + getHist(TH2, histPath + "hFT0AOuterVsFT0C")->Fill(multbc.multFT0C() * scale.factorFT0C, multbc.multFT0AOuter() * scale.factorFT0A); + } + if (studies.doTimeStudies) { const float hoursAfterStartOfRun = static_cast(bcTimestamp - startOfRunTimestamp) / 3600000.0; getHist(TH2, histPath + "hFT0AVsTime")->Fill(hoursAfterStartOfRun, collision.multFT0A()); getHist(TH2, histPath + "hFT0CVsTime")->Fill(hoursAfterStartOfRun, collision.multFT0C()); getHist(TH2, histPath + "hFT0MVsTime")->Fill(hoursAfterStartOfRun, collision.multFT0M()); getHist(TH2, histPath + "hFV0AVsTime")->Fill(hoursAfterStartOfRun, collision.multFV0A()); - getHist(TH2, histPath + "hFV0AOuterVsTime")->Fill(hoursAfterStartOfRun, collision.multFV0AOuter()); + getHist(TH2, histPath + "hFV0AOuterVsTime")->Fill(hoursAfterStartOfRun, multbc.multFV0AOuter()); getHist(TH2, histPath + "hMFTTracksVsTime")->Fill(hoursAfterStartOfRun, collision.mftNtracks()); getHist(TH2, histPath + "hNGlobalVsTime")->Fill(hoursAfterStartOfRun, collision.multNTracksGlobal()); getHist(TH2, histPath + "hNTPVContributorsVsTime")->Fill(hoursAfterStartOfRun, collision.multPVTotalContributors()); @@ -980,22 +1005,22 @@ struct centralityStudy { } } - void processCollisions(soa::Join::iterator const& collision, aod::MultBCs const&) + void processCollisions(soa::Join::iterator const& collision, soa::Join const&) { genericProcessCollision(collision); } - void processCollisionsWithResolutionStudy(soa::Join::iterator const& collision, soa::Join const&) + void processCollisionsWithResolutionStudy(soa::Join::iterator const& collision, soa::Join const&) { genericProcessCollision(collision); } - void processCollisionsWithCentrality(soa::Join::iterator const& collision, aod::MultBCs const&) + void processCollisionsWithCentrality(soa::Join::iterator const& collision, soa::Join const&) { genericProcessCollision(collision); } - void processCollisionsWithCentralityWithNeighbours(soa::Join::iterator const& collision) + void processCollisionsWithCentralityWithNeighbours(soa::Join::iterator const& collision) { genericProcessCollision(collision); } @@ -1088,7 +1113,7 @@ struct centralityStudy { return true; } - void processBCs(soa::Join const& multbcs, soa::Join const&) + void processBCs(soa::Join const& multbcs, soa::Join const&) { // process BCs, calculate FT0C distribution for (const auto& multbc : multbcs) { @@ -1099,7 +1124,9 @@ struct centralityStudy { // if we got here, we also finally fill the FT0C histogram, please histos.fill(HIST("hFT0C_BCs"), multbc.multFT0C() * scale.factorFT0C); histos.fill(HIST("hFT0A_BCs"), multbc.multFT0A() * scale.factorFT0A); + histos.fill(HIST("hFT0AOuter_BCs"), multbc.multFT0AOuter() * scale.factorFT0A); histos.fill(HIST("hFT0M_BCs"), (multbc.multFT0A() + multbc.multFT0C()) * scale.factorFT0M); + histos.fill(HIST("hFT0MOuterA_BCs"), (multbc.multFT0AOuter() + multbc.multFT0C()) * scale.factorFT0M); histos.fill(HIST("hFV0A_BCs"), multbc.multFV0A() * scale.factorFV0A); histos.fill(HIST("hFV0AT0C_BCs"), (multbc.multFV0A() + multbc.multFT0C()) * scale.factorFV0AT0C); @@ -1124,7 +1151,7 @@ struct centralityStudy { } if (multbc.has_ft0Mult()) { - auto multco = multbc.ft0Mult_as>(); + auto multco = multbc.ft0Mult_as>(); if (multbc.multFT0PosZValid()) { histos.fill(HIST("hVertexZ_BCvsCO"), multco.multPVz(), multbc.multFT0PosZ()); } diff --git a/Common/Tasks/zdcExtraTableReader.cxx b/Common/Tasks/zdcExtraTableReader.cxx new file mode 100644 index 00000000000..6fc573631b5 --- /dev/null +++ b/Common/Tasks/zdcExtraTableReader.cxx @@ -0,0 +1,1052 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file zdcExtraTableReader.cxx +/// \brief Task reading AOD/ZDCEXTRA table +/// \author Uliana Dmitrieva , INFN Torino + +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/ZDCExtra.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; + +namespace +{ + +std::unordered_map gEventCounter; +std::unordered_map gCentroidZNA; +std::unordered_map gCentroidZNC; +std::unordered_map gPmcZNA; +std::unordered_map gPm1ZNA; +std::unordered_map gPm2ZNA; +std::unordered_map gPm3ZNA; +std::unordered_map gPm4ZNA; +std::unordered_map gSumZNA; +std::unordered_map gPmcZNC; +std::unordered_map gPm1ZNC; +std::unordered_map gPm2ZNC; +std::unordered_map gPm3ZNC; +std::unordered_map gPm4ZNC; +std::unordered_map gSumZNC; +std::unordered_map gQxVsCentZNA; +std::unordered_map gQyVsCentZNA; +std::unordered_map gQxVsVxZNA; +std::unordered_map gQyVsVxZNA; +std::unordered_map gQxVsVyZNA; +std::unordered_map gQyVsVyZNA; +std::unordered_map gQxVsVzZNA; +std::unordered_map gQyVsVzZNA; +std::unordered_map gQxVsCentZNC; +std::unordered_map gQyVsCentZNC; +std::unordered_map gQxVsVxZNC; +std::unordered_map gQyVsVxZNC; +std::unordered_map gQxVsVyZNC; +std::unordered_map gQyVsVyZNC; +std::unordered_map gQxVsVzZNC; +std::unordered_map gQyVsVzZNC; +std::unordered_map gQxQyVsCent; +std::unordered_map gQyQxVsCent; +std::unordered_map gQxQxVsCent; +std::unordered_map gQyQyVsCent; + +std::unordered_map gQx5DZNA; +std::unordered_map gQy5DZNA; +std::unordered_map gQx5DZNC; +std::unordered_map gQy5DZNC; + +std::unordered_map gPsiZNA; +std::unordered_map gPsiZNC; + +std::unordered_map gVx; +std::unordered_map gVy; + +// centroid stability vs timestamp +std::unordered_map gQxVsTimeZNA; +std::unordered_map gQyVsTimeZNA; +std::unordered_map gQxVsTimeZNC; +std::unordered_map gQyVsTimeZNC; + +std::unordered_map gShiftProfileZNA; +std::unordered_map gShiftProfileZNC; + +TH1* gCurrentEventCounter{nullptr}; +TH2* gCurrentCentroidZNA{nullptr}; +TH2* gCurrentCentroidZNC{nullptr}; +TH1* gCurrentPmcZNA{nullptr}; +TH1* gCurrentPm1ZNA{nullptr}; +TH1* gCurrentPm2ZNA{nullptr}; +TH1* gCurrentPm3ZNA{nullptr}; +TH1* gCurrentPm4ZNA{nullptr}; +TH1* gCurrentSumZNA{nullptr}; +TH1* gCurrentPmcZNC{nullptr}; +TH1* gCurrentPm1ZNC{nullptr}; +TH1* gCurrentPm2ZNC{nullptr}; +TH1* gCurrentPm3ZNC{nullptr}; +TH1* gCurrentPm4ZNC{nullptr}; +TH1* gCurrentSumZNC{nullptr}; +TH2* gCurrentQxVsCentZNA{nullptr}; +TH2* gCurrentQyVsCentZNA{nullptr}; +TH2* gCurrentQxVsVxZNA{nullptr}; +TH2* gCurrentQyVsVxZNA{nullptr}; +TH2* gCurrentQxVsVyZNA{nullptr}; +TH2* gCurrentQyVsVyZNA{nullptr}; +TH2* gCurrentQxVsVzZNA{nullptr}; +TH2* gCurrentQyVsVzZNA{nullptr}; +TH2* gCurrentQxVsCentZNC{nullptr}; +TH2* gCurrentQyVsCentZNC{nullptr}; +TH2* gCurrentQxVsVxZNC{nullptr}; +TH2* gCurrentQyVsVxZNC{nullptr}; +TH2* gCurrentQxVsVyZNC{nullptr}; +TH2* gCurrentQyVsVyZNC{nullptr}; +TH2* gCurrentQxVsVzZNC{nullptr}; +TH2* gCurrentQyVsVzZNC{nullptr}; +TH2* gCurrentQxQyVsCent{nullptr}; +TH2* gCurrentQyQxVsCent{nullptr}; +TH2* gCurrentQxQxVsCent{nullptr}; +TH2* gCurrentQyQyVsCent{nullptr}; + +THn* gCurrentQxZNA{nullptr}; +THn* gCurrentQyZNA{nullptr}; +THn* gCurrentQxZNC{nullptr}; +THn* gCurrentQyZNC{nullptr}; + +TH1* gCurrentPsiZNA{nullptr}; +TH1* gCurrentPsiZNC{nullptr}; + +TH1* gCurrentVx{nullptr}; +TH1* gCurrentVy{nullptr}; + +TH2* gCurrentQxVsTimeZNA{nullptr}; +TH2* gCurrentQyVsTimeZNA{nullptr}; +TH2* gCurrentQxVsTimeZNC{nullptr}; +TH2* gCurrentQyVsTimeZNC{nullptr}; + +TProfile3D* gCurrentShiftProfileZNA{nullptr}; +TProfile3D* gCurrentShiftProfileZNC{nullptr}; + +} // namespace + +// Helper for 4D recentering maps +double getMeanQFromMap(THn* h, double cent, double vx, double vy, double vz) +{ + if (!h) { + LOGF(fatal, "[MeanQ] Null THn pointer"); + } + + TAxis* axCent = h->GetAxis(0); + TAxis* axVx = h->GetAxis(1); + TAxis* axVy = h->GetAxis(2); + TAxis* axVz = h->GetAxis(3); + + if (!axCent || !axVx || !axVy || !axVz) { + LOGF(fatal, "[MeanQ] One of THn axes is null"); + } + + int binCent = axCent->FindFixBin(cent); + int binVx = axVx->FindFixBin(vx); + int binVy = axVy->FindFixBin(vy); + int binVz = axVz->FindFixBin(vz); + + std::array idx = {binCent, binVx, binVy, binVz}; + return h->GetBinContent(idx.data()); +} + +// Helper for 1D recentering maps: returns mean Q for coordinate x +// If bin out of range, returns 0.0 +double getMeanQ1D(TH1* h, double x) +{ + if (!h) { + LOGF(fatal, "[MeanQ1D] Null TH1 pointer"); + } + int bin = h->FindFixBin(x); + if (bin < 1 || bin > h->GetNbinsX()) { + return 0.0; + } + return h->GetBinContent(bin); +} + +struct ZdcExtraTableReader { + + Configurable nBinsZN{"nBinsZN", 2000, "n bins for ZN histograms"}; + Configurable maxZN{"maxZN", 399.5, "Max ZN signal"}; + Configurable applyTdcCut{"applyTdcCut", true, "Flag for TDC cut"}; + Configurable tdcZnMin{"tdcZnMin", -2.5, "Min ZN TDC cut"}; + Configurable tdcZnMax{"tdcZnMax", 2.5, "Max ZN TDC cut"}; + Configurable plotPMs{"plotPMs", false, "Flag to plot individual PMs"}; + + ConfigurableAxis qxyAxis{"qxyAxis", {100, -2.0f, 2.0f}, ""}; + + Configurable vxNbins{"vxNbins", 50, "Bins in Vx"}; + Configurable vxMin{"vxMin", -0.1f, "Vx lower edge"}; + Configurable vxMax{"vxMax", 0.1f, "Vx upper edge"}; + + Configurable vyNbins{"vyNbins", 50, "Bins in Vy"}; + Configurable vyMin{"vyMin", -0.1f, "Vy lower edge"}; + Configurable vyMax{"vyMax", 0.1f, "Vy upper edge"}; + + Configurable vzNbins{"vzNbins", 50, "Bins in Vz"}; + Configurable vzMin{"vzMin", -10.0f, "Vz lower edge"}; + Configurable vzMax{"vzMax", 10.0f, "Vz upper edge"}; + + Configurable centNbins{"centNbins", 16, "Bins in centrality"}; + Configurable centMin{"centMin", 0.0f, "Centrality lower edge"}; + Configurable centMax{"centMax", 80.0f, "Centrality upper edge"}; + + Configurable phiNbins{"phiNbins", 60, "Bins in phi"}; + + Configurable minNTowersFired{"minNTowersFired", 2, "Minimum number of towers fired for Q-vector determination"}; + + Configurable qNbins5D{"qNbins5D", 4, "Bins in each dimension for 5D histograms"}; + Configurable plot5D{"plot5D", false, "Flag to plot 5D histograms"}; + + Configurable calibrationStep{"calibrationStep", 1, "Calibration step"}; + Configurable isFineCalibrationStep{"isFineCalibrationStep", false, "Calibration: base or refine"}; + + Configurable applyBeamSpotCorrection{"applyBeamSpotCorrection", true, "Beam spot correction"}; + + Configurable applySel8{"applySel8", true, "Event selection: Sel8"}; + Configurable applyZVtxCut{"applyZVtxCut", true, "Event selection: zVtx cut set in producer (tipically < 10 cm)"}; + Configurable applyOccupancyCut{"applyOccupancyCut", false, "Event selection: occupancy cut set in producer"}; + Configurable selectNoSameBunchPileupEvents{"selectNoSameBunchPileupEvents", false, "Event selection: no same bunch pileup"}; + Configurable selectGoodZvtxFT0vsPV{"selectGoodZvtxFT0vsPV", false, "Event selection: good Zvtx FT0 vs PV"}; + Configurable applyNoCollInTimeRangeStandard{"applyNoCollInTimeRangeStandard", false, "Event selection: no collision in time range standard"}; + Configurable selectVertexITSTPC{"selectVertexITSTPC", false, "Event selection: vertex ITS TPC"}; + Configurable selectGoodITSLayersAll{"selectGoodITSLayersAll", false, "Event selection: good ITS layers all"}; + + Configurable applyShiftCorrection{"applyShiftCorrection", false, "Apply shift correction (Read from CCDB)"}; + Configurable fillShiftHistos{"fillShiftHistos", false, "Fill shift profiles (Write to output)"}; + Configurable nHarmonics{"nHarmonics", 10, "Number of harmonics"}; + + Configurable qRecenteringCcdb{"qRecenteringCcdb", "Users/u/udmitrie/ZDC/LHC24ar_apass2", "Recentering maps containing step folder"}; + + // CCDB + Service ccdb{}; + + // Struct to hold calibration data for a single step + struct CalibStepData { + // 5D maps (Base) + THn* hMeanQxZNA{nullptr}; + THn* hMeanQyZNA{nullptr}; + THn* hMeanQxZNC{nullptr}; + THn* hMeanQyZNC{nullptr}; + + // 1D maps (Refine) + TH1* hMeanQxCentZNA{nullptr}; + TH1* hMeanQyCentZNA{nullptr}; + TH1* hMeanQxCentZNC{nullptr}; + TH1* hMeanQyCentZNC{nullptr}; + + TH1* hMeanQxVzZNA{nullptr}; + TH1* hMeanQyVzZNA{nullptr}; + TH1* hMeanQxVzZNC{nullptr}; + TH1* hMeanQyVzZNC{nullptr}; + + TH1* hMeanQxVxZNA{nullptr}; + TH1* hMeanQyVxZNA{nullptr}; + TH1* hMeanQxVxZNC{nullptr}; + TH1* hMeanQyVxZNC{nullptr}; + + TH1* hMeanQxVyZNA{nullptr}; + TH1* hMeanQyVyZNA{nullptr}; + TH1* hMeanQxVyZNC{nullptr}; + TH1* hMeanQyVyZNC{nullptr}; + + // Destructor to handle cleanup automatically + ~CalibStepData() + { + delete hMeanQxZNA; + delete hMeanQyZNA; + delete hMeanQxZNC; + delete hMeanQyZNC; + + delete hMeanQxCentZNA; + delete hMeanQyCentZNA; + delete hMeanQxCentZNC; + delete hMeanQyCentZNC; + + delete hMeanQxVzZNA; + delete hMeanQyVzZNA; + delete hMeanQxVzZNC; + delete hMeanQyVzZNC; + + delete hMeanQxVxZNA; + delete hMeanQyVxZNA; + delete hMeanQxVxZNC; + delete hMeanQyVxZNC; + + delete hMeanQxVyZNA; + delete hMeanQyVyZNA; + delete hMeanQxVyZNC; + delete hMeanQyVyZNC; + } + }; + + // Cache container: Vector index = Step index (0-based, so step 1 is at index 0) + std::vector calibCache; + + // Vertex correction cache + TH1* hMeanVx{nullptr}; + TH1* hMeanVy{nullptr}; + + // Phase shift correction cache + TProfile3D* shiftProfileZNA{nullptr}; + TProfile3D* shiftProfileZNC{nullptr}; + + HistogramRegistry histos{"histos"}; + + enum EvSelBits { // same bits as in zdcExtraTableProducer.cxx + ZVtxCut, + Sel8, + OccupancyCut, + NoSameBunchPileup, + IsGoodZvtxFT0vsPV, + NoCollInTimeRangeStandard, + IsVertexITSTPC, + IsGoodITSLayersAll, + AllEvents, + NEventSelections + }; + + int currentRunNumber{-1}; + + // Helper to safely clone a histogram and detach from file + template + T* safeClone(TObject* obj) + { + if (!obj) { + return nullptr; + } + T* cloned = dynamic_cast(obj->Clone()); + if (cloned) { + + if (dynamic_cast(cloned)) { + dynamic_cast(cloned)->SetDirectory(nullptr); + } + } + return cloned; + } + + void clearCache() + { + delete hMeanVx; + hMeanVx = nullptr; + + delete hMeanVy; + hMeanVy = nullptr; + + delete shiftProfileZNA; + shiftProfileZNA = nullptr; + + delete shiftProfileZNC; + shiftProfileZNC = nullptr; + + calibCache.clear(); + } + + void initHistos(const int runNumber) + { + if (runNumber == currentRunNumber) { + return; + } + currentRunNumber = runNumber; + + if (!gEventCounter.contains(runNumber)) { + // if new run, initialize histograms + + const AxisSpec axisCounter{1, 0, +1, ""}; + const AxisSpec axisZN{nBinsZN, -0.5, maxZN, "(a.u.)"}; + const AxisSpec axisCent = {centNbins, centMin, centMax, "Centrality (%)"}; + const AxisSpec axisVx = {vxNbins, vxMin, vxMax, "V_{x} (cm)"}; + const AxisSpec axisVy = {vyNbins, vyMin, vyMax, "V_{y} (cm)"}; + const AxisSpec axisVz = {vzNbins, vzMin, vzMax, "V_{z} (cm)"}; + + const AxisSpec axisCent5D = {qNbins5D, centMin, centMax, "Centrality (%)"}; + const AxisSpec axisVx5D = {qNbins5D, vxMin, vxMax, "V_{x} (cm)"}; + const AxisSpec axisVy5D = {qNbins5D, vyMin, vyMax, "V_{y} (cm)"}; + const AxisSpec axisVz5D = {qNbins5D, vzMin, vzMax, "V_{z} (cm)"}; + + const AxisSpec axisQx{qxyAxis, "Q_{x}"}; + const AxisSpec axisQy{qxyAxis, "Q_{y}"}; + const AxisSpec axisQxQy = {qxyAxis, ""}; + + const AxisSpec axisPhi = {phiNbins, -1.0f * o2::constants::math::PI, 1.0f * o2::constants::math::PI, "#phi"}; + + const AxisSpec axisTime = {90, 0, 90, "Time (minutes)"}; // 90 minutes + + gEventCounter[runNumber] = histos.add(Form("%i/eventCounter", runNumber), "Number of Event; ; #Events Passed Cut", kTH1D, {{NEventSelections, 0, NEventSelections}}).get(); + gEventCounter[runNumber]->GetXaxis()->SetBinLabel(AllEvents + 1, "allEvents"); + gEventCounter[runNumber]->GetXaxis()->SetBinLabel(ZVtxCut + 1, "zVtxCut"); + gEventCounter[runNumber]->GetXaxis()->SetBinLabel(Sel8 + 1, "Sel8"); + gEventCounter[runNumber]->GetXaxis()->SetBinLabel(OccupancyCut + 1, "occupancyCut"); + gEventCounter[runNumber]->GetXaxis()->SetBinLabel(NoSameBunchPileup + 1, "NoSameBunchPileup"); + gEventCounter[runNumber]->GetXaxis()->SetBinLabel(IsGoodZvtxFT0vsPV + 1, "isGoodZvtxFT0vsPV"); + gEventCounter[runNumber]->GetXaxis()->SetBinLabel(NoCollInTimeRangeStandard + 1, "noCollInTimeRangeStandard"); + gEventCounter[runNumber]->GetXaxis()->SetBinLabel(IsVertexITSTPC + 1, "isVertexITSTPC"); + gEventCounter[runNumber]->GetXaxis()->SetBinLabel(IsGoodITSLayersAll + 1, "isGoodITSLayersAll"); + + gCentroidZNA[runNumber] = histos.add(Form("%i/CentroidZNA", runNumber), "ZNA Centroid; Q_{X}; Q_{Y}", kTH2F, {{50, -1.5, 1.5}, {50, -1.5, 1.5}}).get(); + gCentroidZNC[runNumber] = histos.add(Form("%i/CentroidZNC", runNumber), "ZNC Centroid; Q_{X}; Q_{Y}", kTH2F, {{50, -1.5, 1.5}, {50, -1.5, 1.5}}).get(); + gPmcZNA[runNumber] = histos.add(Form("%i/pmcZNA", runNumber), "; E_{PMC}^{ZNA} (TeV);", kTH1F, {{nBinsZN, -0.5, maxZN}}).get(); + gPm1ZNA[runNumber] = histos.add(Form("%i/pm1ZNA", runNumber), "; E_{PM1}^{ZNA} (a.u.);", kTH1F, {{nBinsZN, -0.5, maxZN}}).get(); + gPm2ZNA[runNumber] = histos.add(Form("%i/pm2ZNA", runNumber), "; E_{PM2}^{ZNA} (a.u.);", kTH1F, {{nBinsZN, -0.5, maxZN}}).get(); + gPm3ZNA[runNumber] = histos.add(Form("%i/pm3ZNA", runNumber), "; E_{PM3}^{ZNA} (a.u.);", kTH1F, {{nBinsZN, -0.5, maxZN}}).get(); + gPm4ZNA[runNumber] = histos.add(Form("%i/pm4ZNA", runNumber), "; E_{PM4}^{ZNA} (a.u.);", kTH1F, {{nBinsZN, -0.5, maxZN}}).get(); + gSumZNA[runNumber] = histos.add(Form("%i/sumZNA", runNumber), "; E_{sum PMs}^{ZNA} (a.u.);", kTH1F, {{nBinsZN, -0.5, maxZN}}).get(); + gPmcZNC[runNumber] = histos.add(Form("%i/pmcZNC", runNumber), "; E_{PMC}^{ZNC} (TeV);", kTH1F, {{nBinsZN, -0.5, maxZN}}).get(); + gPm1ZNC[runNumber] = histos.add(Form("%i/pm1ZNC", runNumber), "; E_{PM1}^{ZNC} (a.u.);", kTH1F, {{nBinsZN, -0.5, maxZN}}).get(); + gPm2ZNC[runNumber] = histos.add(Form("%i/pm2ZNC", runNumber), "; E_{PM2}^{ZNC} (a.u.);", kTH1F, {{nBinsZN, -0.5, maxZN}}).get(); + gPm3ZNC[runNumber] = histos.add(Form("%i/pm3ZNC", runNumber), "; E_{PM3}^{ZNC} (a.u.);", kTH1F, {{nBinsZN, -0.5, maxZN}}).get(); + gPm4ZNC[runNumber] = histos.add(Form("%i/pm4ZNC", runNumber), "; E_{PM4}^{ZNC} (a.u.);", kTH1F, {{nBinsZN, -0.5, maxZN}}).get(); + gSumZNC[runNumber] = histos.add(Form("%i/sumZNC", runNumber), "; E_{sum PMs}^{ZNC} (a.u.);", kTH1F, {{nBinsZN, -0.5, maxZN}}).get(); + gQxVsCentZNA[runNumber] = histos.add(Form("%i/QxVsCentZNA", runNumber), "Q_{x}^{ZNA} vs Centrality", kTH2F, {axisCent, axisQx}).get(); + gQyVsCentZNA[runNumber] = histos.add(Form("%i/QyVsCentZNA", runNumber), "Q_{y}^{ZNA} vs Centrality", kTH2F, {axisCent, axisQy}).get(); + gQxVsVxZNA[runNumber] = histos.add(Form("%i/QxVsVxZNA", runNumber), "Q_{x}^{ZNA} vs V_{x}; V_{x} (cm); Q_{x}", kTH2F, {axisVx, axisQx}).get(); + gQyVsVxZNA[runNumber] = histos.add(Form("%i/QyVsVxZNA", runNumber), "Q_{y}^{ZNA} vs V_{x}; V_{x} (cm); Q_{y}", kTH2F, {axisVx, axisQy}).get(); + gQxVsVyZNA[runNumber] = histos.add(Form("%i/QxVsVyZNA", runNumber), "Q_{x}^{ZNA} vs V_{y}; V_{y} (cm); Q_{x}", kTH2F, {axisVy, axisQx}).get(); + gQyVsVyZNA[runNumber] = histos.add(Form("%i/QyVsVyZNA", runNumber), "Q_{y}^{ZNA} vs V_{y}; V_{y} (cm); Q_{y}", kTH2F, {axisVy, axisQy}).get(); + gQxVsVzZNA[runNumber] = histos.add(Form("%i/QxVsVzZNA", runNumber), "Q_{x}^{ZNA} vs V_{z}; V_{z} (cm); Q_{x}", kTH2F, {axisVz, axisQx}).get(); + gQyVsVzZNA[runNumber] = histos.add(Form("%i/QyVsVzZNA", runNumber), "Q_{y}^{ZNA} vs V_{z}; V_{z} (cm); Q_{y}", kTH2F, {axisVz, axisQy}).get(); + gQxVsCentZNC[runNumber] = histos.add(Form("%i/QxVsCentZNC", runNumber), "Q_{x}^{ZNC} vs Centrality; Centrality (%); Q_{x}", kTH2F, {axisCent, axisQx}).get(); + gQyVsCentZNC[runNumber] = histos.add(Form("%i/QyVsCentZNC", runNumber), "Q_{y}^{ZNC} vs Centrality; Centrality (%); Q_{y}", kTH2F, {axisCent, axisQy}).get(); + gQxVsVxZNC[runNumber] = histos.add(Form("%i/QxVsVxZNC", runNumber), "Q_{x}^{ZNC} vs V_{x}; V_{x} (cm); Q_{x}", kTH2F, {axisVx, axisQx}).get(); + gQyVsVxZNC[runNumber] = histos.add(Form("%i/QyVsVxZNC", runNumber), "Q_{y}^{ZNC} vs V_{x}; V_{x} (cm); Q_{y}", kTH2F, {axisVx, axisQy}).get(); + gQxVsVyZNC[runNumber] = histos.add(Form("%i/QxVsVyZNC", runNumber), "Q_{x}^{ZNC} vs V_{y}; V_{y} (cm); Q_{x}", kTH2F, {axisVy, axisQx}).get(); + gQyVsVyZNC[runNumber] = histos.add(Form("%i/QyVsVyZNC", runNumber), "Q_{y}^{ZNC} vs V_{y}; V_{y} (cm); Q_{y}", kTH2F, {axisVy, axisQy}).get(); + gQxVsVzZNC[runNumber] = histos.add(Form("%i/QxVsVzZNC", runNumber), "Q_{x}^{ZNC} vs V_{z}; V_{z} (cm); Q_{x}", kTH2F, {axisVz, axisQx}).get(); + gQyVsVzZNC[runNumber] = histos.add(Form("%i/QyVsVzZNC", runNumber), "Q_{y}^{ZNC} vs V_{z}; V_{z} (cm); Q_{y}", kTH2F, {axisVz, axisQy}).get(); + gQxQyVsCent[runNumber] = histos.add(Form("%i/QxQyVsCent", runNumber), "Q_{x}^{ZNC}Q_{y}^{ZNC} vs Centrality; Centrality (%); Q_{x}^{ZNA}Q_{y}^{ZNC}", kTH2F, {axisCent, {50, -1.5, 1.5}}).get(); + gQyQxVsCent[runNumber] = histos.add(Form("%i/QyQxVsCent", runNumber), "Q_{y}^{ZNC}Q_{x}^{ZNC} vs Centrality; Centrality (%); Q_{y}^{ZNA}Q_{x}^{ZNC}", kTH2F, {axisCent, {50, -1.5, 1.5}}).get(); + gQxQxVsCent[runNumber] = histos.add(Form("%i/QxQxVsCent", runNumber), "Q_{x}^{ZNC}Q_{x}^{ZNC} vs Centrality; Centrality (%); Q_{x}^{ZNA}Q_{x}^{ZNC}", kTH2F, {axisCent, {50, -1.5, 1.5}}).get(); + gQyQyVsCent[runNumber] = histos.add(Form("%i/QyQyVsCent", runNumber), "Q_{y}^{ZNC}Q_{y}^{ZNC} vs Centrality; Centrality (%); Q_{y}^{ZNA}Q_{y}^{ZNC}", kTH2F, {axisCent, {50, -1.5, 1.5}}).get(); + + gQx5DZNA[runNumber] = histos.add(Form("%i/Qx5DZNA", runNumber), "Qx recenter map ZNA", kTHnF, {axisCent5D, axisVx5D, axisVy5D, axisVz5D, axisQx}, true).get(); + gQy5DZNA[runNumber] = histos.add(Form("%i/Qy5DZNA", runNumber), "Qy recenter map ZNA", kTHnF, {axisCent5D, axisVx5D, axisVy5D, axisVz5D, axisQy}, true).get(); + gQx5DZNC[runNumber] = histos.add(Form("%i/Qx5DZNC", runNumber), "Qx recenter map ZNC", kTHnF, {axisCent5D, axisVx5D, axisVy5D, axisVz5D, axisQx}, true).get(); + gQy5DZNC[runNumber] = histos.add(Form("%i/Qy5DZNC", runNumber), "Qy recenter map ZNC", kTHnF, {axisCent5D, axisVx5D, axisVy5D, axisVz5D, axisQy}, true).get(); + + gPsiZNA[runNumber] = histos.add(Form("%i/PsiZNA", runNumber), ";#Phi_{ZNA} (rad)", kTH1F, {axisPhi}).get(); + gPsiZNC[runNumber] = histos.add(Form("%i/PsiZNC", runNumber), ";#Phi_{ZNC} (rad)", kTH1F, {axisPhi}).get(); + + gVx[runNumber] = histos.add(Form("%i/Vx", runNumber), "V_{x} distribution; V_{x} (cm); Entries", kTH1F, {axisVx}).get(); + gVy[runNumber] = histos.add(Form("%i/Vy", runNumber), "V_{y} distribution; V_{y} (cm); Entries", kTH1F, {axisVy}).get(); + + gQxVsTimeZNA[runNumber] = histos.add(Form("%i/QxVsTimeZNA", runNumber), "Q_{x}^{ZNA} vs Time; Time (minutes); Q_{x}", kTH2F, {axisTime, axisQx}).get(); + gQyVsTimeZNA[runNumber] = histos.add(Form("%i/QyVsTimeZNA", runNumber), "Q_{y}^{ZNA} vs Time; Time (minutes); Q_{y}", kTH2F, {axisTime, axisQy}).get(); + gQxVsTimeZNC[runNumber] = histos.add(Form("%i/QxVsTimeZNC", runNumber), "Q_{x}^{ZNC} vs Time; Time (minutes); Q_{x}", kTH2F, {axisTime, axisQx}).get(); + gQyVsTimeZNC[runNumber] = histos.add(Form("%i/QyVsTimeZNC", runNumber), "Q_{y}^{ZNC} vs Time; Time (minutes); Q_{y}", kTH2F, {axisTime, axisQy}).get(); + + gShiftProfileZNA[runNumber] = histos.add(Form("%i/ShiftProfileZNA", runNumber), "ZNA Shift Coeffs;Cent;Type;Harmonic", kTProfile3D, {axisCent, {2, 0, 2}, {nHarmonics, 0, static_cast(nHarmonics)}}).get(); + gShiftProfileZNC[runNumber] = histos.add(Form("%i/ShiftProfileZNC", runNumber), "ZNC Shift Coeffs;Cent;Type;Harmonic", kTProfile3D, {axisCent, {2, 0, 2}, {nHarmonics, 0, static_cast(nHarmonics)}}).get(); + } + + gCurrentEventCounter = gEventCounter[currentRunNumber]; + gCurrentCentroidZNA = gCentroidZNA[currentRunNumber]; + gCurrentCentroidZNC = gCentroidZNC[currentRunNumber]; + gCurrentPmcZNA = gPmcZNA[currentRunNumber]; + gCurrentPm1ZNA = gPm1ZNA[currentRunNumber]; + gCurrentPm2ZNA = gPm2ZNA[currentRunNumber]; + gCurrentPm3ZNA = gPm3ZNA[currentRunNumber]; + gCurrentPm4ZNA = gPm4ZNA[currentRunNumber]; + gCurrentSumZNA = gSumZNA[currentRunNumber]; + gCurrentPmcZNC = gPmcZNC[currentRunNumber]; + gCurrentPm1ZNC = gPm1ZNC[currentRunNumber]; + gCurrentPm2ZNC = gPm2ZNC[currentRunNumber]; + gCurrentPm3ZNC = gPm3ZNC[currentRunNumber]; + gCurrentPm4ZNC = gPm4ZNC[currentRunNumber]; + gCurrentSumZNC = gSumZNC[currentRunNumber]; + gCurrentQxVsCentZNA = gQxVsCentZNA[currentRunNumber]; + gCurrentQyVsCentZNA = gQyVsCentZNA[currentRunNumber]; + gCurrentQxVsVxZNA = gQxVsVxZNA[currentRunNumber]; + gCurrentQyVsVxZNA = gQyVsVxZNA[currentRunNumber]; + gCurrentQxVsVyZNA = gQxVsVyZNA[currentRunNumber]; + gCurrentQyVsVyZNA = gQyVsVyZNA[currentRunNumber]; + gCurrentQxVsVzZNA = gQxVsVzZNA[currentRunNumber]; + gCurrentQyVsVzZNA = gQyVsVzZNA[currentRunNumber]; + gCurrentQxVsCentZNC = gQxVsCentZNC[currentRunNumber]; + gCurrentQyVsCentZNC = gQyVsCentZNC[currentRunNumber]; + gCurrentQxVsVxZNC = gQxVsVxZNC[currentRunNumber]; + gCurrentQyVsVxZNC = gQyVsVxZNC[currentRunNumber]; + gCurrentQxVsVyZNC = gQxVsVyZNC[currentRunNumber]; + gCurrentQyVsVyZNC = gQyVsVyZNC[currentRunNumber]; + gCurrentQxVsVzZNC = gQxVsVzZNC[currentRunNumber]; + gCurrentQyVsVzZNC = gQyVsVzZNC[currentRunNumber]; + gCurrentQxQyVsCent = gQxQyVsCent[currentRunNumber]; + gCurrentQyQxVsCent = gQyQxVsCent[currentRunNumber]; + gCurrentQxQxVsCent = gQxQxVsCent[currentRunNumber]; + gCurrentQyQyVsCent = gQyQyVsCent[currentRunNumber]; + + gCurrentQxZNA = gQx5DZNA[currentRunNumber]; + gCurrentQyZNA = gQy5DZNA[currentRunNumber]; + gCurrentQxZNC = gQx5DZNC[currentRunNumber]; + gCurrentQyZNC = gQy5DZNC[currentRunNumber]; + + gCurrentPsiZNA = gPsiZNA[currentRunNumber]; + gCurrentPsiZNC = gPsiZNC[currentRunNumber]; + + gCurrentVx = gVx[currentRunNumber]; + gCurrentVy = gVy[currentRunNumber]; + + gCurrentQxVsTimeZNA = gQxVsTimeZNA[currentRunNumber]; + gCurrentQyVsTimeZNA = gQyVsTimeZNA[currentRunNumber]; + gCurrentQxVsTimeZNC = gQxVsTimeZNC[currentRunNumber]; + gCurrentQyVsTimeZNC = gQyVsTimeZNC[currentRunNumber]; + + gCurrentShiftProfileZNA = gShiftProfileZNA[currentRunNumber]; + gCurrentShiftProfileZNC = gShiftProfileZNC[currentRunNumber]; + } + + // Optimized method to load ALL calibrations for the new run at once + void loadCalibrations(int runNumber) + { + clearCache(); + + // Vertex Calibration + if (applyBeamSpotCorrection) { + std::string folder = Form("%s/step0", qRecenteringCcdb.value.c_str()); + auto* lst = ccdb->getForRun(folder, runNumber); + if (lst) { + hMeanVx = safeClone(lst->FindObject("hMeanVx")); + hMeanVy = safeClone(lst->FindObject("hMeanVy")); + } else { + LOGF(error, " >> CCDB TList is NULL for path: %s. Check object type (TList vs TFile).", folder.c_str()); + } + } + + // Step Calibrations + std::size_t targetSteps = (calibrationStep > 0) ? static_cast(calibrationStep.value) : 0; + calibCache.resize(targetSteps); + + for (std::size_t stepIdx = 0; stepIdx < targetSteps; ++stepIdx) { + int step = static_cast(stepIdx + 1); + + // Load 5D (Base) + std::string folderBase = Form("%s/step%d_base", qRecenteringCcdb.value.c_str(), step); + auto* lstBase = ccdb->getForRun(folderBase, runNumber); + + if (!lstBase) { + LOGF(error, " >> CCDB TList is NULL for path: %s. Check object type (TList vs TFile).", folderBase.c_str()); + continue; + } + + calibCache[stepIdx].hMeanQxZNA = safeClone(lstBase->FindObject("hMeanQxZNA")); + calibCache[stepIdx].hMeanQyZNA = safeClone(lstBase->FindObject("hMeanQyZNA")); + calibCache[stepIdx].hMeanQxZNC = safeClone(lstBase->FindObject("hMeanQxZNC")); + calibCache[stepIdx].hMeanQyZNC = safeClone(lstBase->FindObject("hMeanQyZNC")); + + // Load 1D (Refine) + if ((step != calibrationStep) || isFineCalibrationStep) { + std::string folderRefine = Form("%s/step%d_refine", qRecenteringCcdb.value.c_str(), step); + auto* lstRefine = ccdb->getForRun(folderRefine, runNumber); + + if (!lstRefine) { + LOGF(error, " >> CCDB TList is NULL for path: %s. Check object type (TList vs TFile).", folderRefine.c_str()); + continue; + } + + calibCache[stepIdx].hMeanQxCentZNA = safeClone(lstRefine->FindObject("hMeanQxCentZNA")); + calibCache[stepIdx].hMeanQyCentZNA = safeClone(lstRefine->FindObject("hMeanQyCentZNA")); + calibCache[stepIdx].hMeanQxCentZNC = safeClone(lstRefine->FindObject("hMeanQxCentZNC")); + calibCache[stepIdx].hMeanQyCentZNC = safeClone(lstRefine->FindObject("hMeanQyCentZNC")); + + calibCache[stepIdx].hMeanQxVzZNA = safeClone(lstRefine->FindObject("hMeanQxVzZNA")); + calibCache[stepIdx].hMeanQyVzZNA = safeClone(lstRefine->FindObject("hMeanQyVzZNA")); + calibCache[stepIdx].hMeanQxVzZNC = safeClone(lstRefine->FindObject("hMeanQxVzZNC")); + calibCache[stepIdx].hMeanQyVzZNC = safeClone(lstRefine->FindObject("hMeanQyVzZNC")); + + calibCache[stepIdx].hMeanQxVxZNA = safeClone(lstRefine->FindObject("hMeanQxVxZNA")); + calibCache[stepIdx].hMeanQyVxZNA = safeClone(lstRefine->FindObject("hMeanQyVxZNA")); + calibCache[stepIdx].hMeanQxVxZNC = safeClone(lstRefine->FindObject("hMeanQxVxZNC")); + calibCache[stepIdx].hMeanQyVxZNC = safeClone(lstRefine->FindObject("hMeanQyVxZNC")); + + calibCache[stepIdx].hMeanQxVyZNA = safeClone(lstRefine->FindObject("hMeanQxVyZNA")); + calibCache[stepIdx].hMeanQyVyZNA = safeClone(lstRefine->FindObject("hMeanQyVyZNA")); + calibCache[stepIdx].hMeanQxVyZNC = safeClone(lstRefine->FindObject("hMeanQxVyZNC")); + calibCache[stepIdx].hMeanQyVyZNC = safeClone(lstRefine->FindObject("hMeanQyVyZNC")); + } + } // end of step loop + + if (applyShiftCorrection) { + std::string folder = Form("%s/psiHarm", qRecenteringCcdb.value.c_str()); + + // LOGF(info, "Loading Shift Correction from %s for runNumber %d", folder.c_str(), runNumber); + + // Attempt to fetch TList from CCDB + auto* lst = ccdb->getForRun(folder, runNumber); + + if (!lst) { + LOGF(error, " >> CCDB TList is NULL for path: %s. Check object type (TList vs TFile).", folder.c_str()); + return; + } + + // Important: Object names must match exactly what was saved + shiftProfileZNA = safeClone(lst->FindObject("ShiftProfileZNA")); + shiftProfileZNC = safeClone(lst->FindObject("ShiftProfileZNC")); + + if (shiftProfileZNA) { + shiftProfileZNA->SetDirectory(nullptr); // Detach from file + // LOGF(info, " >> ShiftProfileZNA found! Entries: %.0f, Mean: %f", shiftProfileZNA->GetEntries(), shiftProfileZNA->GetMean()); + } else { + LOGF(error, " >> ShiftProfileZNA NOT found in TList! Content follows:"); + lst->Print(); + } + + if (shiftProfileZNC) { + shiftProfileZNC->SetDirectory(nullptr); + // LOGF(info, " >> ShiftProfileZNC found! Entries: %.0f", shiftProfileZNC->GetEntries()); + } else { + LOGF(error, " >> ShiftProfileZNC NOT found in TList!"); + } + } + } // end of loadCalibrations() + + ~ZdcExtraTableReader() + { + clearCache(); + } + + /// Initializes histograms and other resources before event processing. + void init(InitContext&) + { + const AxisSpec axisCounter{1, 0, +1, ""}; + histos.add("eventCounter", "eventCounter", kTH1F, {axisCounter}); + + // CCDB + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setFatalWhenNull(false); + } // end of init() + + void process(aod::ZdcExtras::iterator const& zdc) + { + + // Apply event selection + + if (applySel8 && !TESTBIT(zdc.selectionBits(), Sel8)) { + return; + } + if (applyZVtxCut && !TESTBIT(zdc.selectionBits(), ZVtxCut)) { + return; + } + if (applyOccupancyCut && !TESTBIT(zdc.selectionBits(), OccupancyCut)) { + return; + } + if (selectNoSameBunchPileupEvents && !TESTBIT(zdc.selectionBits(), NoSameBunchPileup)) { + return; + } + if (selectGoodZvtxFT0vsPV && !TESTBIT(zdc.selectionBits(), IsGoodZvtxFT0vsPV)) { + return; + } + if (applyNoCollInTimeRangeStandard && !TESTBIT(zdc.selectionBits(), NoCollInTimeRangeStandard)) { + return; + } + if (selectVertexITSTPC && !TESTBIT(zdc.selectionBits(), IsVertexITSTPC)) { + return; + } + if (selectGoodITSLayersAll && !TESTBIT(zdc.selectionBits(), IsGoodITSLayersAll)) { + return; + } + + const int runNumber = zdc.runNumber(); + + const uint64_t timestamp = zdc.timestamp(); // in milliseconds + + // Convert timestamp to hours from run start (approximate) + // Store first timestamp of run to calculate relative time + static std::unordered_map runStartTime; + if (!runStartTime.contains(runNumber)) { + runStartTime[runNumber] = timestamp; + } + + double timeInMinutes = (timestamp - runStartTime[runNumber]) / 60000.0; // ms -> minutes + + // Initialization block if Run Number changes + if (runNumber != currentRunNumber) { + initHistos(runNumber); // Init output histograms + loadCalibrations(runNumber); // Load all steps from CCDB once + currentRunNumber = runNumber; + } + + histos.fill(HIST("eventCounter"), 0.5); + + gCurrentEventCounter->Fill(AllEvents); + + // Fill histogram for all bits that passed + for (int bit = 0; bit < NEventSelections + 1; bit++) { + if (TESTBIT(zdc.selectionBits(), bit)) { + gCurrentEventCounter->Fill(bit); + } + } + + bool isZNChit = false, isZNAhit = false; + + double tdcZNC = zdc.zncTdc(); + double tdcZNA = zdc.znaTdc(); + + if (applyTdcCut) { // TDC window is set + if ((tdcZNC >= tdcZnMin) && (tdcZNC <= tdcZnMax)) { + isZNChit = true; + } + if ((tdcZNA >= tdcZnMin) && (tdcZNA <= tdcZnMax)) { + isZNAhit = true; + } + } else { // if no window on TDC is set + if (zdc.zncTowC() > -1.) { + isZNChit = true; + } + if (zdc.znaTowC() > -1.) { + isZNAhit = true; + } + } + + bool isZNASpDeterminable = false; + bool isZNCSpDeterminable = false; + + constexpr float QvectorMaxValue = 990.0; + + if (isZNAhit) { + int activeTowersZNA = static_cast(zdc.znaTow1() > 0.) + static_cast(zdc.znaTow2() > 0.) + static_cast(zdc.znaTow3() > 0.) + static_cast(zdc.znaTow4() > 0.); + float znaSum = zdc.znaTow1() + zdc.znaTow2() + zdc.znaTow3() + zdc.znaTow4(); + if (activeTowersZNA >= minNTowersFired && znaSum > 0 && zdc.znaQx() < QvectorMaxValue) { + isZNASpDeterminable = true; + } + } + + if (isZNChit) { + int activeTowersZNC = static_cast(zdc.zncTow1() > 0.) + static_cast(zdc.zncTow2() > 0.) + static_cast(zdc.zncTow3() > 0.) + static_cast(zdc.zncTow4() > 0.); + float zncSum = zdc.zncTow1() + zdc.zncTow2() + zdc.zncTow3() + zdc.zncTow4(); + if (activeTowersZNC >= minNTowersFired && zncSum > 0 && zdc.zncQx() < QvectorMaxValue) { + isZNCSpDeterminable = true; + } + } + + if (plotPMs) { + if (isZNAhit) { + gCurrentPmcZNA->Fill(zdc.znaTowC()); + gCurrentPm1ZNA->Fill(zdc.znaTow1()); + gCurrentPm2ZNA->Fill(zdc.znaTow2()); + gCurrentPm3ZNA->Fill(zdc.znaTow3()); + gCurrentPm4ZNA->Fill(zdc.znaTow4()); + + float znaSum = zdc.znaTow1() + zdc.znaTow2() + zdc.znaTow3() + zdc.znaTow4(); + gCurrentSumZNA->Fill(znaSum); + } + + if (isZNChit) { + gCurrentPmcZNC->Fill(zdc.zncTowC()); + gCurrentPm1ZNC->Fill(zdc.zncTow1()); + gCurrentPm2ZNC->Fill(zdc.zncTow2()); + gCurrentPm3ZNC->Fill(zdc.zncTow3()); + gCurrentPm4ZNC->Fill(zdc.zncTow4()); + + float zncSum = zdc.zncTow1() + zdc.zncTow2() + zdc.zncTow3() + zdc.zncTow4(); + gCurrentSumZNC->Fill(zncSum); + } + } // end of if (plotPMs) + + double qxZNArec = 0., qyZNArec = 0.; + double qxZNCrec = 0., qyZNCrec = 0.; + + double cent = zdc.centrality(); + double vx = zdc.vx(); + double vy = zdc.vy(); + double vz = zdc.vz(); + + if (applyBeamSpotCorrection) { + // Use cached vertex pointers + if (hMeanVx && hMeanVy) { + vx -= hMeanVx->GetBinContent(1); + vy -= hMeanVy->GetBinContent(1); + } + } + + // -------- ZNA -------- + if (isZNASpDeterminable) { + double qx = zdc.znaQx(); + double qy = zdc.znaQy(); + + qxZNArec = qx; + qyZNArec = qy; + + for (int step = 1; step <= calibrationStep; step++) { + + int cacheIdx = step - 1; + // Check if index is valid within cached vector + if (cacheIdx >= static_cast(calibCache.size())) { + continue; + } + + const auto& calib = calibCache[cacheIdx]; + + // Apply 5D Base calibration + if (calib.hMeanQxZNA && calib.hMeanQyZNA) { + qxZNArec -= getMeanQFromMap(calib.hMeanQxZNA, cent, vx, vy, vz); + qyZNArec -= getMeanQFromMap(calib.hMeanQyZNA, cent, vx, vy, vz); + } + + if ((step != calibrationStep) || isFineCalibrationStep) { + // Apply 1D Refine calibration + qxZNArec -= getMeanQ1D(calib.hMeanQxCentZNA, cent); + qyZNArec -= getMeanQ1D(calib.hMeanQyCentZNA, cent); + + qxZNArec -= getMeanQ1D(calib.hMeanQxVzZNA, vz); + qyZNArec -= getMeanQ1D(calib.hMeanQyVzZNA, vz); + + qxZNArec -= getMeanQ1D(calib.hMeanQxVxZNA, vx); + qyZNArec -= getMeanQ1D(calib.hMeanQyVxZNA, vx); + + qxZNArec -= getMeanQ1D(calib.hMeanQxVyZNA, vy); + qyZNArec -= getMeanQ1D(calib.hMeanQyVyZNA, vy); + } + } + + std::array valuesQxZNA = {cent, vx, vy, vz, qxZNArec}; + std::array valuesQyZNA = {cent, vx, vy, vz, qyZNArec}; + + gCurrentCentroidZNA->Fill(qxZNArec, qyZNArec); + + gCurrentQxVsCentZNA->Fill(cent, qxZNArec); + gCurrentQyVsCentZNA->Fill(cent, qyZNArec); + gCurrentQxVsVxZNA->Fill(vx, qxZNArec); + gCurrentQyVsVxZNA->Fill(vx, qyZNArec); + gCurrentQxVsVyZNA->Fill(vy, qxZNArec); + gCurrentQyVsVyZNA->Fill(vy, qyZNArec); + gCurrentQxVsVzZNA->Fill(vz, qxZNArec); + gCurrentQyVsVzZNA->Fill(vz, qyZNArec); + + // Fill time-dependent plots + gCurrentQxVsTimeZNA->Fill(timeInMinutes, qxZNArec); + gCurrentQyVsTimeZNA->Fill(timeInMinutes, qyZNArec); + + if (plot5D) { + gCurrentQxZNA->Fill(valuesQxZNA.data()); + gCurrentQyZNA->Fill(valuesQyZNA.data()); + } + + // Calculate raw/recentered angle + double psiZNA = std::atan2(qyZNArec, qxZNArec); + + // Apply Correction (Read Mode) + // Checks if correction is enabled AND if the map from CCDB was loaded successfully + if (applyShiftCorrection && shiftProfileZNA) { + double deltaPsi = 0.0; + + // Loop over harmonics (usually 1 to 10) + for (int iHarm = 1; iHarm <= nHarmonics; iHarm++) { + // Retrieve coefficients from TProfile3D + // Axis mapping: + // X: Centrality + // Y: Type (0.5 for Sin, 1.5 for Cos) + // Z: Harmonic index (iHarm - 0.5 maps to bin 1, 2, etc.) + + int binSin = shiftProfileZNA->FindFixBin(cent, 0.5, static_cast(iHarm) - 0.5); + int binCos = shiftProfileZNA->FindFixBin(cent, 1.5, static_cast(iHarm) - 0.5); + + double coeffSin = shiftProfileZNA->GetBinContent(binSin); + double coeffCos = shiftProfileZNA->GetBinContent(binCos); + + // Fourier flattening formula: + // DeltaPsi = sum( (2/k) * ( *sin(k*psi) - *cos(k*psi) ) ) + // Note: signs depend on definition, this matches the standard correction logic + deltaPsi += (2.0 / iHarm) * (-coeffSin * std::cos(iHarm * psiZNA) + coeffCos * std::sin(iHarm * psiZNA)); + } + + // DEBUG: Print only if shift is actually happening for first few events + static int debugPrintCount = 0; + constexpr int MaxDebugPrints = 10; + constexpr double PsiTolerance = 1e-6; + + if (debugPrintCount < MaxDebugPrints && std::abs(deltaPsi) > PsiTolerance) { + LOGF(info, "ZNA Shift: Cent %.1f, Raw %.3f (Delta %.4f)", cent, psiZNA, deltaPsi); + debugPrintCount++; + } + + // Apply the calculated shift + psiZNA += deltaPsi; + + // Wrap angle to [-pi, pi] range + psiZNA = RecoDecay::constrainAngle(psiZNA, -o2::constants::math::PI); + } + + // Fill Shift Profiles (Write Mode) + // Used to generate calibration for the next step or to verify correction (QA) + if (fillShiftHistos && gCurrentShiftProfileZNA) { + for (int iHarm = 1; iHarm <= nHarmonics; iHarm++) { + // Fill Sin component (Y = 0.5) + gCurrentShiftProfileZNA->Fill(cent, 0.5, static_cast(iHarm) - 0.5, std::sin(iHarm * psiZNA)); + // Fill Cos component (Y = 1.5) + gCurrentShiftProfileZNA->Fill(cent, 1.5, static_cast(iHarm) - 0.5, std::cos(iHarm * psiZNA)); + } + } + + // Fill final analysis histogram with the best available Psi (Raw or Corrected) + gCurrentPsiZNA->Fill(psiZNA); + } + + // -------- ZNC -------- + if (isZNCSpDeterminable) { + double qx = zdc.zncQx(); + double qy = zdc.zncQy(); + + qxZNCrec = qx; + qyZNCrec = qy; + + // Iterate through steps using cached vector + for (int step = 1; step <= calibrationStep; step++) { + + int cacheIdx = step - 1; + if (cacheIdx >= static_cast(calibCache.size())) + continue; + + const auto& calib = calibCache[cacheIdx]; + + // Apply 5D Base calibration + if (calib.hMeanQxZNC && calib.hMeanQyZNC) { + qxZNCrec -= getMeanQFromMap(calib.hMeanQxZNC, cent, vx, vy, vz); + qyZNCrec -= getMeanQFromMap(calib.hMeanQyZNC, cent, vx, vy, vz); + } + + if ((step != calibrationStep) || isFineCalibrationStep) { + + // Apply 1D Refine calibration + qxZNCrec -= getMeanQ1D(calib.hMeanQxCentZNC, cent); + qyZNCrec -= getMeanQ1D(calib.hMeanQyCentZNC, cent); + + qxZNCrec -= getMeanQ1D(calib.hMeanQxVzZNC, vz); + qyZNCrec -= getMeanQ1D(calib.hMeanQyVzZNC, vz); + + qxZNCrec -= getMeanQ1D(calib.hMeanQxVxZNC, vx); + qyZNCrec -= getMeanQ1D(calib.hMeanQyVxZNC, vx); + + qxZNCrec -= getMeanQ1D(calib.hMeanQxVyZNC, vy); + qyZNCrec -= getMeanQ1D(calib.hMeanQyVyZNC, vy); + } + } + + std::array valuesQxZNC = {cent, vx, vy, vz, qxZNCrec}; + std::array valuesQyZNC = {cent, vx, vy, vz, qyZNCrec}; + + gCurrentCentroidZNC->Fill(qxZNCrec, qyZNCrec); + + gCurrentQxVsCentZNC->Fill(cent, qxZNCrec); + gCurrentQyVsCentZNC->Fill(cent, qyZNCrec); + gCurrentQxVsVxZNC->Fill(vx, qxZNCrec); + gCurrentQyVsVxZNC->Fill(vx, qyZNCrec); + gCurrentQxVsVyZNC->Fill(vy, qxZNCrec); + gCurrentQyVsVyZNC->Fill(vy, qyZNCrec); + gCurrentQxVsVzZNC->Fill(vz, qxZNCrec); + gCurrentQyVsVzZNC->Fill(vz, qyZNCrec); + + // Fill time-dependent plots + gCurrentQxVsTimeZNC->Fill(timeInMinutes, qxZNCrec); + gCurrentQyVsTimeZNC->Fill(timeInMinutes, qyZNCrec); + + if (plot5D) { + gCurrentQxZNC->Fill(valuesQxZNC.data()); + gCurrentQyZNC->Fill(valuesQyZNC.data()); + } + + // Calculate raw/recentered angle + double psiZNC = std::atan2(qyZNCrec, qxZNCrec); + + // Apply Correction (Read Mode) + // Checks if correction is enabled AND if the map from CCDB was loaded successfully + if (applyShiftCorrection && shiftProfileZNC) { + double deltaPsi = 0.0; + + // Loop over harmonics (usually 1 to 10) + for (int iHarm = 1; iHarm <= nHarmonics; iHarm++) { + // Retrieve coefficients from TProfile3D + // Axis mapping: + // X: Centrality + // Y: Type (0.5 for Sin, 1.5 for Cos) + // Z: Harmonic index (iHarm - 0.5 maps to bin 1, 2, etc.) + + int binSin = shiftProfileZNC->FindFixBin(cent, 0.5, static_cast(iHarm) - 0.5); + int binCos = shiftProfileZNC->FindFixBin(cent, 1.5, static_cast(iHarm) - 0.5); + + double coeffSin = shiftProfileZNC->GetBinContent(binSin); + double coeffCos = shiftProfileZNC->GetBinContent(binCos); + + // Fourier flattening formula: + // DeltaPsi = sum( (2/k) * ( *sin(k*psi) - *cos(k*psi) ) ) + // Note: signs depend on definition, this matches the standard correction logic + deltaPsi += (2.0 / iHarm) * (-coeffSin * std::cos(iHarm * psiZNC) + coeffCos * std::sin(iHarm * psiZNC)); + } + + // Apply the calculated shift + psiZNC += deltaPsi; + + // Wrap angle to [-pi, pi] range + psiZNC = RecoDecay::constrainAngle(psiZNC, -o2::constants::math::PI); + } + + // Fill Shift Profiles (Write Mode) + // Used to generate calibration for the next step or to verify correction (QA) + if (fillShiftHistos && gCurrentShiftProfileZNC) { + for (int iHarm = 1; iHarm <= nHarmonics; iHarm++) { + // Fill Sin component (Y = 0.5) + gCurrentShiftProfileZNC->Fill(cent, 0.5, static_cast(iHarm) - 0.5, std::sin(iHarm * psiZNC)); + // Fill Cos component (Y = 1.5) + gCurrentShiftProfileZNC->Fill(cent, 1.5, static_cast(iHarm) - 0.5, std::cos(iHarm * psiZNC)); + } + } + + // Fill final analysis histogram with the best available Psi (Raw or Corrected) + gCurrentPsiZNC->Fill(psiZNC); + } + + if (isZNASpDeterminable && isZNCSpDeterminable) { + gCurrentQxQyVsCent->Fill(cent, qxZNArec * qyZNCrec); + gCurrentQyQxVsCent->Fill(cent, qyZNArec * qxZNCrec); + gCurrentQxQxVsCent->Fill(cent, qxZNArec * qxZNCrec); + gCurrentQyQyVsCent->Fill(cent, qyZNArec * qyZNCrec); + } + + gCurrentVx->Fill(vx); + gCurrentVy->Fill(vy); + + } // end of process() (= end of loop through collisions with ZDC) +}; // end of struct ZdcExtraTableReader + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/Common/Tools/EventSelectionModule.h b/Common/Tools/EventSelectionModule.h index eb4108bf6e6..c73255aff6f 100644 --- a/Common/Tools/EventSelectionModule.h +++ b/Common/Tools/EventSelectionModule.h @@ -310,6 +310,7 @@ class BcSelectionModule return; } bcselbuffer.clear(); + bcselbuffer.reserve(bcs.size()); for (const auto& bc : bcs) { uint64_t timestamp = timestamps[bc.globalIndex()]; par = ccdb->template getForTimeStamp("EventSelection/EventSelectionParams", timestamp); @@ -453,6 +454,7 @@ class BcSelectionModule int run = bcs.iteratorAt(0).runNumber(); + bcselbuffer.reserve(bcs.size()); // bc loop for (auto bc : bcs) { // o2-linter: disable=const-ref-in-for-loop (use bc as nonconst iterator) uint64_t timestamp = timestamps[bc.globalIndex()]; @@ -1505,7 +1507,7 @@ class EventSelectionModule // TODO apply other cuts for sel8? // TODO introduce array of sel[0]... sel[8] or similar? bool sel8 = false; - if (lastRun < 568873) // o2-linter: disable=magic-number (pre-2026 data & MC: require all three bits: TVX, TF and ROF border cuts) + if (lastRun < 568873 || lastRun >= 572103) // o2-linter: disable=magic-number (pre-2026 and Pb-Pb 2026 (data & MC): require all three bits: TVX, TF and ROF border cuts) sel8 = BITCHECK64(bcselEntry.selection, aod::evsel::kIsTriggerTVX) && BITCHECK64(bcselEntry.selection, aod::evsel::kNoTimeFrameBorder) && BITCHECK64(bcselEntry.selection, aod::evsel::kNoITSROFrameBorder); else // for pp 2026: sel8 without kNoITSROFrameBorder bit, because the cross-ROF reconstruction for ITS will be On (the switch by a runNumber is a temporary solution) sel8 = BITCHECK64(bcselEntry.selection, aod::evsel::kIsTriggerTVX) && BITCHECK64(bcselEntry.selection, aod::evsel::kNoTimeFrameBorder); diff --git a/Common/Tools/PID/pidTPCModule.h b/Common/Tools/PID/pidTPCModule.h index 24c7683b70c..0a39c41ff0c 100644 --- a/Common/Tools/PID/pidTPCModule.h +++ b/Common/Tools/PID/pidTPCModule.h @@ -553,14 +553,14 @@ class pidTPCModule track_properties[counter_track_props + 1] = trk.tgl(); track_properties[counter_track_props + 2] = trk.signed1Pt(); track_properties[counter_track_props + 3] = o2::track::pid_constants::sMasses[j]; - track_properties[counter_track_props + 4] = trk.has_collision() ? mults[trk.collisionId()] / 11000. : 1.; + track_properties[counter_track_props + 4] = (trk.has_collision() && mults.size() > 0) ? mults[trk.collisionId()] / 11000. : 1.; track_properties[counter_track_props + 5] = std::sqrt(nNclNormalization / trk.tpcNClsFound()); if (input_dimensions == ExpectedInputDimensionsNNV2 && networkVersion == NetworkVersionV2) { - track_properties[counter_track_props + 6] = trk.has_collision() ? collisions.iteratorAt(trk.collisionId()).ft0cOccupancyInTimeRange() / 60000. : 1.; + track_properties[counter_track_props + 6] = (trk.has_collision() && mults.size() > 0) ? collisions.iteratorAt(trk.collisionId()).ft0cOccupancyInTimeRange() / 60000. : 1.; } if (input_dimensions == ExpectedInputDimensionsNNV3 && networkVersion == NetworkVersionV3) { - track_properties[counter_track_props + 6] = trk.has_collision() ? collisions.iteratorAt(trk.collisionId()).ft0cOccupancyInTimeRange() / 60000. : 1.; - if (trk.has_collision()) { + track_properties[counter_track_props + 6] = (trk.has_collision() && mults.size() > 0) ? collisions.iteratorAt(trk.collisionId()).ft0cOccupancyInTimeRange() / 60000. : 1.; + if (trk.has_collision() && mults.size() > 0) { if (collsys == CollisionSystemType::kCollSyspp) { track_properties[counter_track_props + 7] = hadronicRateForCollision[trk.collisionId()] / 1500.; } else { @@ -577,8 +577,8 @@ class pidTPCModule } if (input_dimensions == ExpectedInputDimensionsNNV4 && networkVersion == NetworkVersionV4) { - track_properties[counter_track_props + 6] = trk.has_collision() ? collisions.iteratorAt(trk.collisionId()).ft0cOccupancyInTimeRange() / 60000. : 1.; - if (trk.has_collision()) { + track_properties[counter_track_props + 6] = (trk.has_collision() && mults.size() > 0) ? collisions.iteratorAt(trk.collisionId()).ft0cOccupancyInTimeRange() / 60000. : 1.; + if (trk.has_collision() && mults.size() > 0) { if (collsys == CollisionSystemType::kCollSyspp) { track_properties[counter_track_props + 7] = hadronicRateForCollision[trk.collisionId()] / 1500.; } else { @@ -706,7 +706,7 @@ class pidTPCModule // faster counting for (const auto& track : tracks) { if (track.hasTPC()) { - if (track.collisionId() > -1) { + if (track.has_collision() && cols.size() > 0) { pidmults[track.collisionId()]++; } totalTPCtracks++; @@ -792,7 +792,7 @@ class pidTPCModule float tpcSignalToEvaluatePID = trk.tpcSignal(); int64_t multTPC = 0; - if (trk.has_collision()) { + if (trk.has_collision() && cols.size() > 0) { multTPC = pidmults[trk.collisionId()]; } @@ -812,7 +812,7 @@ class pidTPCModule double hadronicRate; int occupancy; - if (trk.has_collision()) { + if (trk.has_collision() && cols.size() > 0) { auto collision = cols.iteratorAt(trk.collisionId()); hadronicRate = hadronicRateForCollision[trk.collisionId()]; occupancy = collision.trackOccupancyInTimeRange(); @@ -873,7 +873,7 @@ class pidTPCModule } } - const auto& bc = trk.has_collision() ? cols.rawIteratorAt(trk.collisionId()).template bc_as() : bcs.begin(); + const auto& bc = trk.has_collision() && cols.size() > 0 ? cols.rawIteratorAt(trk.collisionId()).template bc_as() : bcs.begin(); if (useCCDBParam && pidTPCopts.ccdbTimestamp.value == 0 && !ccdb->isCachedObjectValid(pidTPCopts.ccdbPath.value, bc.timestamp())) { // Updating parametrisation only if the initial timestamp is 0 if (pidTPCopts.recoPass.value == "") { LOGP(info, "Retrieving latest TPC response object for timestamp {}:", bc.timestamp()); diff --git a/DPG/Tasks/AOTTrack/PID/HMPID/hmpidTableProducer.cxx b/DPG/Tasks/AOTTrack/PID/HMPID/hmpidTableProducer.cxx index 7e4cb37c9ef..0e7c1e3b464 100644 --- a/DPG/Tasks/AOTTrack/PID/HMPID/hmpidTableProducer.cxx +++ b/DPG/Tasks/AOTTrack/PID/HMPID/hmpidTableProducer.cxx @@ -51,6 +51,7 @@ using namespace o2::constants::physics; struct HmpidTableProducer { Produces hmpidAnalysis; + Produces hmpidAnalysisMC; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -80,6 +81,16 @@ struct HmpidTableProducer { aod::pidTOFFullPi, aod::pidTOFFullKa, aod::pidTOFFullPr, aod::pidTOFFullDe>; + using TrackCandidatesMC = soa::Join; + + std::unordered_set mCollisionsWithHmpid; + void init(o2::framework::InitContext&) { ccdb->setURL(ccdbConfig.ccdbUrl); @@ -294,42 +305,37 @@ struct HmpidTableProducer { } PROCESS_SWITCH(HmpidTableProducer, processEvent, "Process event level", true); - void processHmpid( + template + void runHmpidAnalysis( aod::HMPIDs const& hmpids, - TrackCandidates const&, + TTrackTable const&, CollisionCandidates const&, aod::BCsWithTimestamps const&) { - static std::unordered_set collisionsWithHmpid; - for (auto const& t : hmpids) { - const auto& globalTrack = t.track_as(); + const auto& globalTrack = t.template track_as(); if (!globalTrack.has_collision()) continue; - const auto& col = globalTrack.collision_as(); - initCCDB(col.bc_as()); + const auto& col = globalTrack.template collision_as(); + initCCDB(col.template bc_as()); uint32_t collId = col.globalIndex(); - // Track quality selection if ((requireITS && !globalTrack.hasITS()) || (requireTPC && !globalTrack.hasTPC()) || - (requireTOF && !globalTrack.hasTOF())) { + (requireTOF && !globalTrack.hasTOF())) continue; - } - if (collisionsWithHmpid.insert(collId).second) { + if (mCollisionsWithHmpid.insert(collId).second) histos.fill(HIST("eventsHmpid"), 0.5); - } // clusSize diagnostics histos.fill(HIST("hClusSize"), t.hmpidClusSize()); bool isCorrupt = (t.hmpidClusSize() <= 0); - if (isCorrupt) { + if (isCorrupt) histos.fill(HIST("hClusSizeCorrupt"), t.hmpidClusSize()); - } // --- M2: clusSize encoding --- int chamberM2 = t.hmpidClusSize() / 1000000; @@ -354,7 +360,7 @@ struct HmpidTableProducer { int16_t charge = globalTrack.sign(); auto prop = o2::base::Propagator::Instance(); - double bz = static_cast(prop->getNominalBz()); // positive sign + double bz = static_cast(prop->getNominalBz()); int chamberM1 = getHmpidChamber(x, p, bz, charge); @@ -374,35 +380,30 @@ struct HmpidTableProducer { // Legend: // bin 0 = clusSize > 0, chamber found (M2 ok) - // bin 1 = clusSize > 0, chamber not found (non dovrebbe mai accadere) + // bin 1 = clusSize > 0, chamber not found // bin 2 = clusSize <= 0, M1 recovery (corrupt, M1 ok) // bin 3 = clusSize <= 0, M1 fails (corrupt, skipped) - if (!isCorrupt && chamberM3 >= 0) { + if (!isCorrupt && chamberM3 >= 0) histos.fill(HIST("hChamberAssignment"), 0.); - } else if (!isCorrupt && chamberM3 < 0) { + else if (!isCorrupt && chamberM3 < 0) histos.fill(HIST("hChamberAssignment"), 1.); - } else if (isCorrupt && chamberM3 >= 0) { + else if (isCorrupt && chamberM3 >= 0) histos.fill(HIST("hChamberAssignment"), 2.); - } else { + else histos.fill(HIST("hChamberAssignment"), 3.); - } histos.fill(HIST("hChamberM3"), chamberM3); histos.fill(HIST("hChamberM3vsM2"), chamberM2, chamberM3); - // Skip track if chamber undetermined - if (chamberM3 < 0) { + if (chamberM3 < 0) continue; - } - // Fill photon charges float hmpidPhotsCharge2[o2::aod::kDimPhotonsCharge]; - for (int i = 0; i < o2::aod::kDimPhotonsCharge; i++) { + for (int i = 0; i < o2::aod::kDimPhotonsCharge; i++) hmpidPhotsCharge2[i] = t.hmpidPhotsCharge()[i]; - } - // Fill output table + // fill hmpid table hmpidAnalysis( t.hmpidSignal(), t.hmpidMom(), globalTrack.p(), t.hmpidXTrack(), t.hmpidYTrack(), @@ -422,9 +423,40 @@ struct HmpidTableProducer { globalTrack.tpcNSigmaDe(), globalTrack.tofNSigmaDe(), col.centFV0A()); + // fill hmpid table for mc tracks if running on MC + if constexpr (isMC) { + if (globalTrack.has_mcParticle()) { + const auto& mc = globalTrack.mcParticle(); + hmpidAnalysisMC(mc.pdgCode(), mc.vx(), mc.vy(), mc.vz(), mc.isPhysicalPrimary(), mc.getProcess()); + } else { + hmpidAnalysisMC(-1, 0.f, 0.f, 0.f, false, -100); + } + } + } // end HMPID loop } + + // process real data + void processHmpid(aod::HMPIDs const& hmpids, + TrackCandidates const& tracks, + CollisionCandidates const& cols, + aod::BCsWithTimestamps const& bcs) + { + // isMC False + runHmpidAnalysis(hmpids, tracks, cols, bcs); + } PROCESS_SWITCH(HmpidTableProducer, processHmpid, "Process HMPID entries", true); + + // process MC + void processHmpidMC(aod::HMPIDs const& hmpids, + TrackCandidatesMC const& tracks, + CollisionCandidates const& cols, + aod::BCsWithTimestamps const& bcs, + aod::McParticles const&) + { + runHmpidAnalysis(hmpids, tracks, cols, bcs); + } + PROCESS_SWITCH(HmpidTableProducer, processHmpidMC, "Process HMPID MC entries", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfg) diff --git a/DPG/Tasks/AOTTrack/PID/HMPID/tableHMPID.h b/DPG/Tasks/AOTTrack/PID/HMPID/tableHMPID.h index 6844da6c519..1fcf9980763 100644 --- a/DPG/Tasks/AOTTrack/PID/HMPID/tableHMPID.h +++ b/DPG/Tasks/AOTTrack/PID/HMPID/tableHMPID.h @@ -34,22 +34,18 @@ DECLARE_SOA_COLUMN(ChargeMip, chargeMip, float); DECLARE_SOA_COLUMN(ClusterSize, clusterSize, float); DECLARE_SOA_COLUMN(Chamber, chamber, float); DECLARE_SOA_COLUMN(PhotonsCharge, photonsCharge, float[kDimPhotonsCharge]); - DECLARE_SOA_COLUMN(EtaTrack, etaTrack, float); DECLARE_SOA_COLUMN(PhiTrack, phiTrack, float); DECLARE_SOA_COLUMN(Px, px, float); DECLARE_SOA_COLUMN(Py, py, float); DECLARE_SOA_COLUMN(Pz, pz, float); - DECLARE_SOA_COLUMN(ItsNCluster, itsNCluster, float); DECLARE_SOA_COLUMN(TpcNCluster, tpcNCluster, float); DECLARE_SOA_COLUMN(TpcNClsCrossedRows, tpcNClsCrossedRows, float); DECLARE_SOA_COLUMN(TpcChi2, tpcChi2, float); DECLARE_SOA_COLUMN(ItsChi2, itsChi2, float); - DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); DECLARE_SOA_COLUMN(DcaZ, dcaZ, float); - DECLARE_SOA_COLUMN(TpcNSigmaPi, tpcNSigmaPi, float); DECLARE_SOA_COLUMN(TofNSigmaPi, tofNSigmaPi, float); DECLARE_SOA_COLUMN(TpcNSigmaKa, tpcNSigmaKa, float); @@ -59,7 +55,6 @@ DECLARE_SOA_COLUMN(TofNSigmaPr, tofNSigmaPr, float); DECLARE_SOA_COLUMN(TpcNSigmaDe, tpcNSigmaDe, float); DECLARE_SOA_COLUMN(TofNSigmaDe, tofNSigmaDe, float); DECLARE_SOA_COLUMN(Centrality, centrality, float); - } // namespace variables_table DECLARE_SOA_TABLE(HmpidAnalysis, "AOD", "HMPIDANALYSIS", @@ -97,6 +92,28 @@ DECLARE_SOA_TABLE(HmpidAnalysis, "AOD", "HMPIDANALYSIS", variables_table::TofNSigmaDe, variables_table::Centrality); +// ----------------------------------------------------------------------- +// MC truth table +// ----------------------------------------------------------------------- +namespace hmpid_mc +{ +DECLARE_SOA_COLUMN(PdgCode, pdgCode, int); +DECLARE_SOA_COLUMN(McVx, mcVx, float); +DECLARE_SOA_COLUMN(McVy, mcVy, float); +DECLARE_SOA_COLUMN(McVz, mcVz, float); +DECLARE_SOA_COLUMN(IsPhysPrimary, isPhysPrimary, bool); +DECLARE_SOA_COLUMN(ProcessCode, processCode, int); + +} // namespace hmpid_mc + +DECLARE_SOA_TABLE(HmpidAnalysisMC, "AOD", "HMPIDANALYSISMC", + hmpid_mc::PdgCode, + hmpid_mc::McVx, + hmpid_mc::McVy, + hmpid_mc::McVz, + hmpid_mc::IsPhysPrimary, + hmpid_mc::ProcessCode); + } // namespace o2::aod #endif // DPG_TASKS_AOTTRACK_PID_HMPID_TABLEHMPID_H_ diff --git a/DPG/Tasks/AOTTrack/derivedDataCreatorD0Calibration.cxx b/DPG/Tasks/AOTTrack/derivedDataCreatorD0Calibration.cxx index 33a4a2a9ed7..4e41c0e44c6 100644 --- a/DPG/Tasks/AOTTrack/derivedDataCreatorD0Calibration.cxx +++ b/DPG/Tasks/AOTTrack/derivedDataCreatorD0Calibration.cxx @@ -117,8 +117,9 @@ struct DerivedDataCreatorD0Calibration { std::string prefix = "ml"; } cfgMl; - using TracksWCovExtraPid = soa::Join; - using TracksWCovExtraPidAndQa = soa::Join; + using TracksWCovExtraPid = soa::Join; + using TracksWCovExtraTmoPid = soa::Join; + using TracksWCovExtraTmoPidAndQa = soa::Join; using CollisionsWEvSel = soa::Join; using TrackMeanOccs = soa::Join; @@ -183,12 +184,12 @@ struct DerivedDataCreatorD0Calibration { } // main function - template + template void runDataCreation(CollisionsWEvSel const& collisions, aod::TrackAssoc const& trackIndices, TTracks const&, aod::BCsWithTimestamps const&, - TrackMeanOccs const&, + TTrackMeanOccs const&, TTrackQa const&) { std::map selectedCollisions; // map with indices of selected collisions (key: original AOD Collision table index, value: D0 collision index) @@ -232,8 +233,10 @@ struct DerivedDataCreatorD0Calibration { continue; } auto trackParCovPos = getTrackParCov(trackPos); - o2::dataformats::DCA dcaPos; - trackParCovPos.propagateToDCA(primaryVertex, bz, &dcaPos); + o2::dataformats::DCA dcaPos(trackPos.dcaXY(), trackPos.dcaZ(), trackPos.cYY(), trackPos.cZY(), trackPos.cZZ()); + if (trackPos.collisionId() != collision.globalIndex()) { + trackParCovPos.propagateToDCA(primaryVertex, bz, &dcaPos); + } if (!isSelectedTrackDca(cfgTrackCuts.binsPt, cfgTrackCuts.limitsDca, trackParCovPos.getPt(), dcaPos.getY(), dcaPos.getZ())) { continue; } @@ -268,12 +271,42 @@ struct DerivedDataCreatorD0Calibration { continue; } auto trackParCovNeg = getTrackParCov(trackNeg); - o2::dataformats::DCA dcaNeg; - trackParCovNeg.propagateToDCA(primaryVertex, bz, &dcaNeg); + o2::dataformats::DCA dcaNeg(trackNeg.dcaXY(), trackNeg.dcaZ(), trackNeg.cYY(), trackNeg.cZY(), trackNeg.cZZ()); + if (trackNeg.collisionId() != collision.globalIndex()) { + trackParCovNeg.propagateToDCA(primaryVertex, bz, &dcaNeg); + } if (!isSelectedTrackDca(cfgTrackCuts.binsPt, cfgTrackCuts.limitsDca, trackParCovNeg.getPt(), dcaNeg.getY(), dcaNeg.getZ())) { continue; } + // preselections + // pt + std::array pVecNoVtxD0 = RecoDecay::pVec(trackPos.pVector(), trackNeg.pVector()); + float ptNoVtxD0 = RecoDecay::pt(pVecNoVtxD0); + if (ptNoVtxD0 - ptTolerance < cfgCandCuts.ptMin) { + continue; + } + int ptBinNoVtxD0 = findBin(cfgTrackCuts.binsPt, ptNoVtxD0 + ptTolerance); // assuming tighter selections at lower pT + if (ptBinNoVtxD0 < 0) { + continue; + } + + // random downsampling already here + if (cfgDownsampling.apply) { + int ptBinWeights{0}; + if (ptNoVtxD0 < histDownSampl->GetBinLowEdge(1)) { + ptBinWeights = 1; + } else if (ptNoVtxD0 > histDownSampl->GetXaxis()->GetBinUpEdge(histDownSampl->GetNbinsX())) { + ptBinWeights = histDownSampl->GetNbinsX(); + } else { + ptBinWeights = histDownSampl->GetXaxis()->FindBin(ptNoVtxD0); + } + float weight = histDownSampl->GetBinContent(ptBinWeights); + if (gRandom->Rndm() > weight) { + continue; + } + } + int pidTrackNegKaon{-1}; int pidTrackNegPion{-1}; if (cfgTrackCuts.usePidTpcOnly) { @@ -288,7 +321,6 @@ struct DerivedDataCreatorD0Calibration { pidTrackNegPion = selectorPion.statusTpcAndTof(trackNeg); } - // preselections // PID uint8_t massHypo{D0MassHypo::D0AndD0Bar}; // both mass hypotheses a priori if (pidTrackPosPion == TrackSelectorPID::Rejected || pidTrackNegKaon == TrackSelectorPID::Rejected) { @@ -301,17 +333,6 @@ struct DerivedDataCreatorD0Calibration { continue; } - // pt - std::array pVecNoVtxD0 = RecoDecay::pVec(trackPos.pVector(), trackNeg.pVector()); - float ptNoVtxD0 = RecoDecay::pt(pVecNoVtxD0); - if (ptNoVtxD0 - ptTolerance < cfgCandCuts.ptMin) { - continue; - } - int ptBinNoVtxD0 = findBin(cfgTrackCuts.binsPt, ptNoVtxD0 + ptTolerance); // assuming tighter selections at lower pT - if (ptBinNoVtxD0 < 0) { - continue; - } - // d0xd0 if (dcaPos.getY() * dcaNeg.getY() > cfgCandCuts.topologicalCuts->get(ptBinNoVtxD0, "max d0d0")) { continue; @@ -361,22 +382,6 @@ struct DerivedDataCreatorD0Calibration { continue; } - // random downsampling already here - if (cfgDownsampling.apply) { - int ptBinWeights{0}; - if (ptD0 < histDownSampl->GetBinLowEdge(1)) { - ptBinWeights = 1; - } else if (ptD0 > histDownSampl->GetXaxis()->GetBinUpEdge(histDownSampl->GetNbinsX())) { - ptBinWeights = histDownSampl->GetNbinsX(); - } else { - ptBinWeights = histDownSampl->GetXaxis()->FindBin(ptD0); - } - float weight = histDownSampl->GetBinContent(ptBinWeights); - if (gRandom->Rndm() > weight) { - continue; - } - } - // d0xd0 if (dcaPos.getY() * dcaNeg.getY() > cfgCandCuts.topologicalCuts->get(ptBinD0, "max d0d0")) { continue; @@ -514,18 +519,20 @@ struct DerivedDataCreatorD0Calibration { uint8_t twmoFT0CUnfm80{0u}; uint8_t tmoRobustT0V0PrimUnfm80{0u}; uint8_t twmoRobustT0V0PrimUnfm80{0u}; - if (trackPos.has_tmo()) { - auto tmoFromTrack = trackPos.template tmo_as(); // obtain track mean occupancies - tmoPrimUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoPrimUnfm80()); - tmoFV0AUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoFV0AUnfm80()); - tmoFT0AUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoFT0AUnfm80()); - tmoFT0CUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoFT0CUnfm80()); - twmoPrimUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoPrimUnfm80()); - twmoFV0AUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoFV0AUnfm80()); - twmoFT0AUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoFT0AUnfm80()); - twmoFT0CUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoFT0CUnfm80()); - tmoRobustT0V0PrimUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoRobustT0V0PrimUnfm80()); - twmoRobustT0V0PrimUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoRobustT0V0PrimUnfm80()); + if constexpr (withTrackOcc) { + if (trackPos.has_tmo()) { + auto tmoFromTrack = trackPos.template tmo_as(); // obtain track mean occupancies + tmoPrimUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoPrimUnfm80()); + tmoFV0AUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoFV0AUnfm80()); + tmoFT0AUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoFT0AUnfm80()); + tmoFT0CUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoFT0CUnfm80()); + twmoPrimUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoPrimUnfm80()); + twmoFV0AUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoFV0AUnfm80()); + twmoFT0AUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoFT0AUnfm80()); + twmoFT0CUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoFT0CUnfm80()); + tmoRobustT0V0PrimUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoRobustT0V0PrimUnfm80()); + twmoRobustT0V0PrimUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoRobustT0V0PrimUnfm80()); + } } float tpcTime0{0.f}; float tpcdEdxNorm{0.f}; @@ -679,18 +686,20 @@ struct DerivedDataCreatorD0Calibration { uint8_t twmoFT0CUnfm80{0u}; uint8_t tmoRobustT0V0PrimUnfm80{0u}; uint8_t twmoRobustT0V0PrimUnfm80{0u}; - if (trackNeg.has_tmo()) { - auto tmoFromTrack = trackNeg.template tmo_as(); // obtain track mean occupancies - tmoPrimUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoPrimUnfm80()); - tmoFV0AUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoFV0AUnfm80()); - tmoFT0AUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoFT0AUnfm80()); - tmoFT0CUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoFT0CUnfm80()); - twmoPrimUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoPrimUnfm80()); - twmoFV0AUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoFV0AUnfm80()); - twmoFT0AUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoFT0AUnfm80()); - twmoFT0CUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoFT0CUnfm80()); - tmoRobustT0V0PrimUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoRobustT0V0PrimUnfm80()); - twmoRobustT0V0PrimUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoRobustT0V0PrimUnfm80()); + if constexpr (withTrackOcc) { + if (trackNeg.has_tmo()) { + auto tmoFromTrack = trackNeg.template tmo_as(); // obtain track mean occupancies + tmoPrimUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoPrimUnfm80()); + tmoFV0AUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoFV0AUnfm80()); + tmoFT0AUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoFT0AUnfm80()); + tmoFT0CUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoFT0CUnfm80()); + twmoPrimUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoPrimUnfm80()); + twmoFV0AUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoFV0AUnfm80()); + twmoFT0AUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoFT0AUnfm80()); + twmoFT0CUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoFT0CUnfm80()); + tmoRobustT0V0PrimUnfm80 = getCompressedOccupancy(tmoFromTrack.tmoRobustT0V0PrimUnfm80()); + twmoRobustT0V0PrimUnfm80 = getCompressedOccupancy(tmoFromTrack.twmoRobustT0V0PrimUnfm80()); + } } float tpcTime0{0.f}; float tpcdEdxNorm{0.f}; @@ -868,24 +877,33 @@ struct DerivedDataCreatorD0Calibration { // process functions void processWithTrackQa(CollisionsWEvSel const& collisions, aod::TrackAssoc const& trackIndices, - TracksWCovExtraPidAndQa const& tracks, + TracksWCovExtraTmoPidAndQa const& tracks, aod::BCsWithTimestamps const& bcs, TrackMeanOccs const& occ, aod::TracksQAVersion const& trackQa) { - runDataCreation(collisions, trackIndices, tracks, bcs, occ, trackQa); + runDataCreation(collisions, trackIndices, tracks, bcs, occ, trackQa); } PROCESS_SWITCH(DerivedDataCreatorD0Calibration, processWithTrackQa, "Process with trackQA enabled", false); void processNoTrackQa(CollisionsWEvSel const& collisions, aod::TrackAssoc const& trackIndices, - TracksWCovExtraPid const& tracks, + TracksWCovExtraTmoPid const& tracks, aod::BCsWithTimestamps const& bcs, TrackMeanOccs const& occ) { - runDataCreation(collisions, trackIndices, tracks, bcs, occ, nullptr); + runDataCreation(collisions, trackIndices, tracks, bcs, occ, nullptr); + } + PROCESS_SWITCH(DerivedDataCreatorD0Calibration, processNoTrackQa, "Process without trackQA enabled", false); + + void processNoTrackQaAndOcc(CollisionsWEvSel const& collisions, + aod::TrackAssoc const& trackIndices, + TracksWCovExtraPid const& tracks, + aod::BCsWithTimestamps const& bcs) + { + runDataCreation(collisions, trackIndices, tracks, bcs, nullptr, nullptr); } - PROCESS_SWITCH(DerivedDataCreatorD0Calibration, processNoTrackQa, "Process without trackQA enabled", true); + PROCESS_SWITCH(DerivedDataCreatorD0Calibration, processNoTrackQaAndOcc, "Process without trackQA and trackMeanOcc enabled", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/DPG/Tasks/AOTTrack/qaEfficiency.cxx b/DPG/Tasks/AOTTrack/qaEfficiency.cxx index 20abc845190..b8b5bc4631e 100644 --- a/DPG/Tasks/AOTTrack/qaEfficiency.cxx +++ b/DPG/Tasks/AOTTrack/qaEfficiency.cxx @@ -110,6 +110,9 @@ std::array, nParticles> hPtGeneratedRecoEv; std::array, nParticles> hPtItsPrm; std::array, nParticles> hPtItsTpcPrm; std::array, nParticles> hPtTrkItsTpcPrm; +std::array, nParticles> hDeltaPtVsPtTrkItsTpcPrm; +std::array, nParticles> hPtGenVsPtTrkItsTpcPrm; +std::array, nParticles> hPtGenVsPIDTrkItsTpcPrm; std::array, nParticles> hPtItsTpcTofPrm; std::array, nParticles> hPtTrkItsTpcTofPrm; std::array, nParticles> hPtGeneratedPrm; @@ -325,6 +328,7 @@ struct QaEfficiency { const AxisSpec axisPhi{phiBins, "#it{#varphi} (rad)"}; const AxisSpec axisRadius{radiusBins, "Radius (cm)"}; const AxisSpec axisOcc{occBins, "Occupancy"}; + const AxisSpec axisPIDFlag{16, -0.5, 15.5, "PID flag (top 4 bits)"}; const char* partName = particleName(pdgSign, id); LOG(info) << "Preparing histograms for particle: " << partName << " pdgSign " << pdgSign; @@ -376,6 +380,9 @@ struct QaEfficiency { hPtItsPrm[histogramIndex] = histos.add(Form("MC/pdg%i/pt/prm/its", PDGs[histogramIndex]), "ITS tracks (primaries) " + tagPt, kTH1D, {axisPt}); hPtItsTpcPrm[histogramIndex] = histos.add(Form("MC/pdg%i/pt/prm/its_tpc", PDGs[histogramIndex]), "ITS-TPC tracks (primaries) " + tagPt, kTH1D, {axisPt}); hPtTrkItsTpcPrm[histogramIndex] = histos.add(Form("MC/pdg%i/pt/prm/trk/its_tpc", PDGs[histogramIndex]), "ITS-TPC tracks (reco primaries) " + tagPt, kTH1D, {axisPt}); + hDeltaPtVsPtTrkItsTpcPrm[histogramIndex] = histos.add(Form("MC/pdg%i/pt/prm/generated_vs_reco_delta", PDGs[histogramIndex]), "Abs(Gen - Reco) pT vs Gen pT (primaries) " + tagPt, kTH2D, {axisPt, axisPt}); + hPtGenVsPtTrkItsTpcPrm[histogramIndex] = histos.add(Form("MC/pdg%i/pt/prm/generated_vs_reco", PDGs[histogramIndex]), "Reco pT vs Gen pT (primaries) " + tagPt, kTH2D, {axisPt, axisPt}); + hPtGenVsPIDTrkItsTpcPrm[histogramIndex] = histos.add(Form("MC/pdg%i/pt/prm/generated_vs_reco_pid_tracking", PDGs[histogramIndex]), "PID for tracking vs Gen pT (primaries) " + tagPt, kTH2D, {axisPt, axisPIDFlag}); hPtItsTpcTofPrm[histogramIndex] = histos.add(Form("MC/pdg%i/pt/prm/its_tpc_tof", PDGs[histogramIndex]), "ITS-TPC-TOF tracks (primaries) " + tagPt, kTH1D, {axisPt}); hPtTrkItsTpcTofPrm[histogramIndex] = histos.add(Form("MC/pdg%i/pt/prm/trk/its_tpc_tof", PDGs[histogramIndex]), "ITS-TPC-TOF tracks (reco primaries) " + tagPt, kTH1D, {axisPt}); hPtGeneratedPrm[histogramIndex] = histos.add(Form("MC/pdg%i/pt/prm/generated", PDGs[histogramIndex]), "Generated (primaries) " + tagPt, kTH1D, {axisPt}); @@ -1156,6 +1163,9 @@ struct QaEfficiency { if (passedITS && passedTPC) { hPtItsTpcPrm[histogramIndex]->Fill(mcParticle.pt()); hPtTrkItsTpcPrm[histogramIndex]->Fill(track.pt()); + hDeltaPtVsPtTrkItsTpcPrm[histogramIndex]->Fill(mcParticle.pt(), abs(track.pt() - mcParticle.pt())); + hPtGenVsPtTrkItsTpcPrm[histogramIndex]->Fill(mcParticle.pt(), track.pt()); + hPtGenVsPIDTrkItsTpcPrm[histogramIndex]->Fill(mcParticle.pt(), track.pidForTracking()); hEtaItsTpcPrm[histogramIndex]->Fill(mcParticle.eta()); hEtaTrkItsTpcPrm[histogramIndex]->Fill(track.eta()); hPhiItsTpcPrm[histogramIndex]->Fill(mcParticle.phi()); diff --git a/DPG/Tasks/AOTTrack/qaImpPar.cxx b/DPG/Tasks/AOTTrack/qaImpPar.cxx index 7e758dd7ec2..28d1db77bd9 100644 --- a/DPG/Tasks/AOTTrack/qaImpPar.cxx +++ b/DPG/Tasks/AOTTrack/qaImpPar.cxx @@ -116,6 +116,7 @@ struct QaImpactPar { Configurable nCustomMinITShits{"n_customMinITShits", 0, "Minimum number of layers crossed by a track among those in \"customITShitmap\""}; Configurable customForceITSTPCmatching{"custom_forceITSTPCmatching", false, "Consider or not only ITS-TPC macthed tracks when using custom ITS hitmap"}; Configurable downsamplingFraction{"downsamplingFraction", 1.1, "Fraction of tracks to be used to fill the output objects"}; + Configurable eventGeneratorHF{"eventGeneratorHF", -1, "If positive, enable event selection using subGeneratorId information (HF). The value indicates which events to keep (0 = MB, 4 = charm triggered, 5 = beauty triggered)"}; /// Custom cut selection objects TrackSelection selector_ITShitmap; @@ -201,6 +202,12 @@ struct QaImpactPar { const o2::aod::McCollisions&, o2::aod::BCsWithTimestamps const&) { + /// SubgeneratorID check for HF MC + /// Useful to select MB gap events in HF-dedicated MC productions + if (eventGeneratorHF >= 0 && collision.mcCollision().getSubGeneratorId() != eventGeneratorHF) { + return; + } + /// here call the template processReco function auto bc = collision.bc_as(); processReco(collision, tracksUnfiltered, tracks, tracksIU, mcParticles, bc); @@ -216,6 +223,12 @@ struct QaImpactPar { const o2::aod::McCollisions&, o2::aod::BCsWithTimestamps const&) { + /// SubgeneratorID check for HF MC + /// Useful to select MB gap events in HF-dedicated MC productions + if (eventGeneratorHF >= 0 && collision.mcCollision().getSubGeneratorId() != eventGeneratorHF) { + return; + } + /// here call the template processReco function auto bc = collision.bc_as(); processReco(collision, tracksUnfiltered, tracks, tracksIU, mcParticles, bc); diff --git a/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx b/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx index 7bc4d190d6e..3aaa024874e 100644 --- a/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx +++ b/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include #include #include @@ -88,13 +90,11 @@ struct TreeWriterTpcV0 { Configurable nClNorm{"nClNorm", 152., "Number of cluster normalization. Run 2: 159, Run 3 152"}; Configurable applyEvSel{"applyEvSel", 2, "Flag to apply rapidity cut: 0 -> no event selection, 1 -> Run 2 event selection, 2 -> Run 3 event selection"}; Configurable trackSelection{"trackSelection", 0, "Track selection: 0 -> No Cut, 1 -> kGlobalTrack, 2 -> kGlobalTrackWoPtEta, 3 -> kGlobalTrackWoDCA, 4 -> kQualityTracks, 5 -> kInAcceptanceTracks"}; - Configurable irSource{"irSource", "T0VTX", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; /// Configurables downsampling Configurable dwnSmplFactorPi{"dwnSmplFactorPi", 1., "downsampling factor for pions, default fraction to keep is 1."}; Configurable dwnSmplFactorPr{"dwnSmplFactorPr", 1., "downsampling factor for protons, default fraction to keep is 1."}; Configurable dwnSmplFactorEl{"dwnSmplFactorEl", 1., "downsampling factor for electrons, default fraction to keep is 1."}; Configurable dwnSmplFactorKa{"dwnSmplFactorKa", 1., "downsampling factor for kaons, default fraction to keep is 1."}; - Configurable sqrtSNN{"sqrtSNN", 5360., "sqrt(s_NN), used for downsampling with the Tsallis distribution"}; Configurable downsamplingTsalisPions{"downsamplingTsalisPions", -1., "Downsampling factor to reduce the number of pions"}; Configurable downsamplingTsalisProtons{"downsamplingTsalisProtons", -1., "Downsampling factor to reduce the number of protons"}; Configurable downsamplingTsalisElectrons{"downsamplingTsalisElectrons", -1., "Downsampling factor to reduce the number of electrons"}; @@ -103,11 +103,19 @@ struct TreeWriterTpcV0 { Configurable maxPt4dwnsmplTsalisProtons{"maxPt4dwnsmplTsalisProtons", 100., "Maximum Pt for applying downsampling factor of protons"}; Configurable maxPt4dwnsmplTsalisElectrons{"maxPt4dwnsmplTsalisElectrons", 100., "Maximum Pt for applying downsampling factor of electrons"}; Configurable maxPt4dwnsmplTsalisKaons{"maxPt4dwnsmplTsalisKaons", 100., "Maximum Pt for applying downsampling factor of kaons"}; + // Configurables for output tables reservation size + Configurable reserveV0Ratio{"reserveV0Ratio", 0.05, "Ratio of how many tracks from V0s are expected in the output table to the input V0 table size"}; + Configurable reserveCascRatio{"reserveCascRatio", 0.0025, "Ratio of how many tracks from cascades are expected in the output table to the input Cascade table size"}; + Configurable saveReserveQaHisto{"saveReserveQaHisto", true, "Flag to save the DF-wise ratio of output table size to that of input table"}; // Configurables for run condtion table Configurable rctLabel{"rctLabel", "CBT_hadronPID", "select 1 [CBT, CBT_hadronPID, CBT_muon_glo] see O2Physics/Common/CCDB/RCTSelectionFlags.h"}; Configurable checkZdc{"checkZdc", false, "set ZDC flag for PbPb"}; Configurable treatLimitedAcceptanceAsBad{"treatLimitedAcceptanceAsBad", false, "reject all events where the detectors relevant for the specified Runlist are flagged as LimitedAcceptance"}; Configurable requireGoodRct{"requireGoodRct", false, "require good detector flag in run condtion table"}; + // Configurable for the path of CCDB General Run Parameters LHC Interface information + Configurable ccdbPathGrpLhcIf{"ccdbPathGrpLhcIf", "GLO/Config/GRPLHCIF", "Path on the CCDB for the GRPLHCIF object"}; + + HistogramRegistry registry{"registry", {}}; // an arbitrary value of N sigma TOF assigned by TOF task to tracks which are not matched to TOF hits constexpr static float NSigmaTofUnmatched{o2::aod::v0data::kNoTOFValue}; @@ -182,6 +190,11 @@ struct TreeWriterTpcV0 { ccdb->setFatalWhenNull(false); rctChecker.init(rctLabel, checkZdc, treatLimitedAcceptanceAsBad); + + if (saveReserveQaHisto) { + registry.add("hV0OutputRatio", "V0 out/in ratio;V0 out/in ratio;Entries", {HistType::kTH1F, {{100, 0, reserveV0Ratio}}}); + registry.add("hCascOutputRatio", "Casc out/in ratio;Casc out/in ratio;Entries", {HistType::kTH1F, {{100, 0, reserveCascRatio}}}); + } } template @@ -263,7 +276,7 @@ struct TreeWriterTpcV0 { void fillSkimmedV0Table(V0Casc const& v0casc, T const& track, aod::TracksQA const& trackQA, const bool existTrkQA, C const& collision, const float nSigmaTPC, const float nSigmaTOF, const float nSigmaITS, const float dEdxExp, const o2::track::PID::ID id, const int runnumber, const double dwnSmplFactor, const float hadronicRate, const int bcGlobalIndex, const int bcTimeFrameId, const int bcBcInTimeFrame, const OccupancyValues& occValues, const bool isGoodRctEvent) { const double ncl = track.tpcNClsFound(); - const double nclPID = track.tpcNClsFindableMinusPID(); + const double nclPID = track.tpcNClsPID(); const double p = track.tpcInnerParam(); const double mass = o2::track::pid_constants::sMasses[id]; const double bg = p / mass; @@ -422,6 +435,19 @@ struct TreeWriterTpcV0 { aod::pidits::ITSNSigmaEl, aod::pidits::ITSNSigmaPi, aod::pidits::ITSNSigmaKa, aod::pidits::ITSNSigmaPr>(myTracks); + int nV0Entries{0}; + int nCascEntries{0}; + + const int64_t expectedOutputTableSize = static_cast(reserveV0Ratio * myV0s.size() + reserveCascRatio * myCascs.size()); + if constexpr (ModeId == ModeWithdEdxTrkQA || ModeId == ModeStandard) { + rowTPCTree.reserve(expectedOutputTableSize); + } else { + rowTPCTreeWithTrkQA.reserve(expectedOutputTableSize); + } + + std::string irSource{}; + float sqrtSNN{}; + bool isFirstCollision{true}; for (const auto& collision : collisions) { if (!isEventSelected(collision, applyEvSel)) { continue; @@ -434,18 +460,20 @@ struct TreeWriterTpcV0 { const auto v0s = myV0s.sliceBy(perCollisionV0s, static_cast(collision.globalIndex())); const auto cascs = myCascs.sliceBy(perCollisionCascs, static_cast(collision.globalIndex())); const auto bc = collision.bc_as(); + if (isFirstCollision) { + evaluateIrSourceAndSqrtSnn(ccdb, ccdbPathGrpLhcIf, bc.timestamp(), irSource, sqrtSNN); + } + isFirstCollision = false; const int runnumber = bc.runNumber(); - const auto hadronicRate = mRateFetcher.fetch(ccdb.service, bc.timestamp(), runnumber, irSource) * OneToKilo; + const auto hadronicRate = !irSource.empty() ? mRateFetcher.fetch(ccdb.service, bc.timestamp(), runnumber, irSource) * OneToKilo : 0.; const int bcGlobalIndex = bc.globalIndex(); int bcTimeFrameId{}, bcBcInTimeFrame{}; if constexpr (ModeId == ModeWithdEdxTrkQA || ModeId == ModeStandard) { bcTimeFrameId = UndefValueInt; bcBcInTimeFrame = UndefValueInt; - rowTPCTree.reserve(2 * v0s.size() + cascs.size()); } else if constexpr (ModeId == ModeWithTrkQA) { bcTimeFrameId = bc.tfId(); bcBcInTimeFrame = bc.bcInTF(); - rowTPCTreeWithTrkQA.reserve(2 * v0s.size() + cascs.size()); } auto getTrackQA = [&](const TrksType::iterator& track) { @@ -481,7 +509,9 @@ struct TreeWriterTpcV0 { evaluateOccupancyVariables(dauTrack, occValues); } fillSkimmedV0Table(mother, dauTrack, trackQAInstance, existTrkQA, collision, daughter.tpcNSigma, daughter.tofNSigma, daughter.itsNSigma, daughter.tpcExpSignal, daughter.id, runnumber, daughter.dwnSmplFactor, hadronicRate, bcGlobalIndex, bcTimeFrameId, bcBcInTimeFrame, occValues, isGoodRctEvent); + return true; } + return false; }; /// Loop over v0 candidates @@ -493,8 +523,12 @@ struct TreeWriterTpcV0 { const auto posTrack = v0.posTrack_as(); const auto negTrack = v0.negTrack_as(); - fillDaughterTrack(v0, posTrack, v0, true); - fillDaughterTrack(v0, negTrack, v0, false); + if (fillDaughterTrack(v0, posTrack, v0, true)) { + ++nV0Entries; + } + if (fillDaughterTrack(v0, negTrack, v0, false)) { + ++nV0Entries; + } } /// Loop over cascade candidates @@ -506,9 +540,23 @@ struct TreeWriterTpcV0 { const auto bachTrack = casc.bachelor_as(); // Omega and antiomega const auto isDaughterPositive = cascId == MotherAntiOmega ? true : false; - fillDaughterTrack(casc, bachTrack, casc, isDaughterPositive); + if (fillDaughterTrack(casc, bachTrack, casc, isDaughterPositive)) { + ++nCascEntries; + } } } + LOG(info) << "runV0() summary:"; + LOG(info) << "V0 table size = " << myV0s.size(); + LOG(info) << "Cascade table size = " << myCascs.size(); + LOG(info) << "nV0Entries = " << nV0Entries; + LOG(info) << "nCascEntries = " << nCascEntries; + LOG(info) << "nV0Entries / V0 table size = " << static_cast(nV0Entries) / myV0s.size(); + LOG(info) << "nCascEntries / Cascade table size = " << static_cast(nCascEntries) / myCascs.size(); + + if (saveReserveQaHisto) { + registry.fill(HIST("hV0OutputRatio"), static_cast(nV0Entries) / myV0s.size()); + registry.fill(HIST("hCascOutputRatio"), static_cast(nCascEntries) / myCascs.size()); + } } /// runV0 void processStandard(Colls const& collisions, @@ -591,7 +639,6 @@ struct TreeWriterTpcTof { Configurable nClNorm{"nClNorm", 152., "Number of cluster normalization. Run 2: 159, Run 3 152"}; Configurable applyEvSel{"applyEvSel", 2, "Flag to apply rapidity cut: 0 -> no event selection, 1 -> Run 2 event selection, 2 -> Run 3 event selection"}; Configurable trackSelection{"trackSelection", 1, "Track selection: 0 -> No Cut, 1 -> kGlobalTrack, 2 -> kGlobalTrackWoPtEta, 3 -> kGlobalTrackWoDCA, 4 -> kQualityTracks, 5 -> kInAcceptanceTracks"}; - Configurable irSource{"irSource", "T0VTX", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; /// Triton Configurable maxMomTPCOnlyTr{"maxMomTPCOnlyTr", 1.5, "Maximum momentum for TPC only cut triton"}; Configurable maxMomHardCutOnlyTr{"maxMomHardCutOnlyTr", 50, "Maximum TPC inner momentum for triton"}; @@ -626,17 +673,23 @@ struct TreeWriterTpcTof { Configurable nSigmaTofTpctofPi{"nSigmaTofTpctofPi", 4., "number of sigma for TOF cut for TPC and TOF combined pion"}; Configurable dwnSmplFactorPi{"dwnSmplFactorPi", 1., "downsampling factor for pions, default fraction to keep is 1."}; /// pT dependent downsampling - Configurable sqrtSNN{"sqrtSNN", 5360., "sqrt(s_NN), used for downsampling with the Tsallis distribution"}; Configurable downsamplingTsalisTritons{"downsamplingTsalisTritons", -1., "Downsampling factor to reduce the number of tritons"}; Configurable downsamplingTsalisDeuterons{"downsamplingTsalisDeuterons", -1., "Downsampling factor to reduce the number of deuterons"}; Configurable downsamplingTsalisProtons{"downsamplingTsalisProtons", -1., "Downsampling factor to reduce the number of protons"}; Configurable downsamplingTsalisKaons{"downsamplingTsalisKaons", -1., "Downsampling factor to reduce the number of kaons"}; Configurable downsamplingTsalisPions{"downsamplingTsalisPions", -1., "Downsampling factor to reduce the number of pions"}; + // Configurable for output table reservation size + Configurable reserveTrackRatio{"reserveTrackRatio", 0.003, "Ratio of how many tracks are expected in the output table to the input Tracks table size"}; + Configurable saveReserveQaHisto{"saveReserveQaHisto", true, "Flag to save the DF-wise ratio of output table size to that of input table"}; // Configurables for run condtion table Configurable rctLabel{"rctLabel", "CBT_hadronPID", "select 1 [CBT, CBT_hadronPID, CBT_muon_glo] see O2Physics/Common/CCDB/RCTSelectionFlags.h"}; Configurable checkZdc{"checkZdc", false, "set ZDC flag for PbPb"}; Configurable treatLimitedAcceptanceAsBad{"treatLimitedAcceptanceAsBad", false, "reject all events where the detectors relevant for the specified Runlist are flagged as LimitedAcceptance"}; Configurable requireGoodRct{"requireGoodRct", false, "require good detector flag in run condtion table"}; + // Configurable for the path of CCDB General Run Parameters LHC Interface information + Configurable ccdbPathGrpLhcIf{"ccdbPathGrpLhcIf", "GLO/Config/GRPLHCIF", "Path on the CCDB for the GRPLHCIF object"}; + + HistogramRegistry registry{"registry", {}}; struct TofTrack { bool isApplyHardCutOnly; @@ -692,13 +745,17 @@ struct TreeWriterTpcTof { ccdb->setFatalWhenNull(false); rctChecker.init(rctLabel, checkZdc, treatLimitedAcceptanceAsBad); + + if (saveReserveQaHisto) { + registry.add("hTrackOutputRatio", "Track out/in ratio;Track out/in ratio;Entries", {HistType::kTH1F, {{100, 0, reserveTrackRatio}}}); + } } template void fillSkimmedTpcTofTable(T const& track, aod::TracksQA const& trackQA, const bool existTrkQA, C const& collision, const float nSigmaTPC, const float nSigmaTOF, const float nSigmaITS, const float dEdxExp, const o2::track::PID::ID id, const int runnumber, const double dwnSmplFactor, const double hadronicRate, const int bcGlobalIndex, const int bcTimeFrameId, const int bcBcInTimeFrame, const OccupancyValues& occValues, const bool isGoodRctEvent) { const double ncl = track.tpcNClsFound(); - const double nclPID = track.tpcNClsFindableMinusPID(); + const double nclPID = track.tpcNClsPID(); const double p = track.tpcInnerParam(); const double mass = o2::track::pid_constants::sMasses[id]; const double bg = p / mass; @@ -803,6 +860,17 @@ struct TreeWriterTpcTof { labelTrack2TrackQA.at(trackId) = trackQA.globalIndex(); } } + + const int64_t expectedOutputTableSize = static_cast(reserveTrackRatio * myTracks.size()); + if constexpr (ModeId == ModeWithdEdxTrkQA || ModeId == ModeStandard) { + rowTPCTOFTree.reserve(expectedOutputTableSize); + } else { + rowTPCTOFTreeWithTrkQA.reserve(expectedOutputTableSize); + } + + std::string irSource{}; + float sqrtSNN{}; + bool isFirstCollision{true}; for (const auto& collision : collisions) { const auto tracks = myTracks.sliceBy(perCollisionTracksType, collision.globalIndex()); if (!isEventSelected(collision, applyEvSel)) { @@ -822,18 +890,20 @@ struct TreeWriterTpcTof { } const auto bc = collision.bc_as(); + if (isFirstCollision) { + evaluateIrSourceAndSqrtSnn(ccdb, ccdbPathGrpLhcIf, bc.timestamp(), irSource, sqrtSNN); + } + isFirstCollision = false; const int runnumber = bc.runNumber(); - const auto hadronicRate = mRateFetcher.fetch(ccdb.service, bc.timestamp(), runnumber, irSource) * OneToKilo; + const auto hadronicRate = !irSource.empty() ? mRateFetcher.fetch(ccdb.service, bc.timestamp(), runnumber, irSource) * OneToKilo : 0.; const int bcGlobalIndex = bc.globalIndex(); int bcTimeFrameId{}, bcBcInTimeFrame{}; if constexpr (ModeId == ModeStandard || ModeId == ModeWithdEdxTrkQA) { bcTimeFrameId = UndefValueInt; bcBcInTimeFrame = UndefValueInt; - rowTPCTOFTree.reserve(tracks.size()); } else { bcTimeFrameId = bc.tfId(); bcBcInTimeFrame = bc.bcInTF(); - rowTPCTOFTreeWithTrkQA.reserve(tracks.size()); } for (auto const& trk : tracksWithITSPid) { if (!isTrackSelected(trk, trackSelection)) { @@ -875,6 +945,14 @@ struct TreeWriterTpcTof { } } /// Loop tracks } + LOG(info) << "runTof() summary:"; + LOG(info) << "Track table size = " << myTracks.size(); + LOG(info) << "nTrackEntries = " << rowTPCTOFTree.lastIndex() + 1; + LOG(info) << "nTrackEntries / Track table size = " << static_cast((rowTPCTOFTree.lastIndex() + 1)) / myTracks.size(); + + if (saveReserveQaHisto) { + registry.fill(HIST("hTrackOutputRatio"), static_cast((rowTPCTOFTree.lastIndex() + 1)) / myTracks.size()); + } } /// runTof void processStandard(Colls const& collisions, diff --git a/DPG/Tasks/TPC/utilsTpcSkimsTableCreator.h b/DPG/Tasks/TPC/utilsTpcSkimsTableCreator.h index b8550e094d7..a3b3dcddc17 100644 --- a/DPG/Tasks/TPC/utilsTpcSkimsTableCreator.h +++ b/DPG/Tasks/TPC/utilsTpcSkimsTableCreator.h @@ -22,13 +22,20 @@ #include "tpcSkimsTableCreator.h" +#include "Common/Core/CollisionTypeHelper.h" #include "Common/DataModel/OccupancyTables.h" +#include +#include #include +#include +#include #include #include +#include +#include namespace o2::dpg_tpcskimstablecreator { @@ -112,6 +119,27 @@ double tpcSignalGeneric(const TrkType& track) } } +/// Determine interaction rate source and sqrtSNN from CCDB +void evaluateIrSourceAndSqrtSnn(const o2::framework::Service& ccdb, const std::string& ccdbPathGrpLhcIf, const uint64_t timestamp, std::string& irSource, float& sqrtSNN) +{ + o2::parameters::GRPLHCIFData* genRunParams = ccdb->template getForTimeStamp(ccdbPathGrpLhcIf, timestamp); + if (genRunParams != nullptr) { + const auto collSys = CollisionSystemType::getCollisionTypeFromGrp(genRunParams); + if (collSys == CollisionSystemType::kCollSyspp) { + irSource = "T0VTX"; + } else { + irSource = "ZNC hadronic"; + } + sqrtSNN = genRunParams->getSqrtS(); + LOG(info) << "irSource determined from General Run Parameters: " << irSource; + LOG(info) << "sqrtSNN determined from General Run Parameters: " << sqrtSNN << " GeV"; + } else { + irSource = ""; + sqrtSNN = 5360.f; + LOG(warning) << "No General Run Parameters object found. irSource will remain undefined, sqrtSNN defaulted to 5360 GeV"; + } +} + struct OccupancyValues { float tmoPrimUnfm80{UndefValueFloat}; float tmoFV0AUnfm80{UndefValueFloat}; diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 4f15d00a342..a4d00d6d416 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -245,6 +245,7 @@ DECLARE_SOA_COLUMN(Charge, charge, int8_t); //! Charge of c DECLARE_SOA_COLUMN(Prong0Id, prong0Id, int); //! Track id of charm hadron prong0 DECLARE_SOA_COLUMN(Prong1Id, prong1Id, int); //! Track id of charm hadron prong1 DECLARE_SOA_COLUMN(Prong2Id, prong2Id, int); //! Track id of charm hadron prong2 +DECLARE_SOA_COLUMN(CascId, cascId, int); //! Cascade id of the Ξ prong in Ξc → Ξππ candidates DECLARE_SOA_COLUMN(Prong0Pt, prong0Pt, float); //! Track pT of charm hadron prong0 DECLARE_SOA_COLUMN(Prong1Pt, prong1Pt, float); //! Track pT of charm hadron prong1 DECLARE_SOA_COLUMN(Prong2Pt, prong2Pt, float); //! Track pT of charm hadron prong2 @@ -258,7 +259,19 @@ DECLARE_SOA_COLUMN(CandidateSelFlag, candidateSelFlag, int); //! Selection o DECLARE_SOA_COLUMN(BDTBkg, bdtBkg, float); //! Background score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTPrompt, bdtPrompt, float); //! Prompt signal score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTFD, bdtFD, float); //! Feed-down score using Boosted Decision Tree for charm hadron -DECLARE_SOA_COLUMN(FlagMc, flagMc, int); //! To select MC particle among charm hadrons, { DplusToPiKPi = 1, LcToPKPi = 17, DsToKKPi = 6, XicToPKPi = 21, N3ProngD = 2ecays }; +DECLARE_SOA_COLUMN(CascBachelorTrackId, cascBachelorTrackId, int); //! Bachelor track ID from Ξ cascade (Ξc± → Ξππ) +DECLARE_SOA_COLUMN(CascPosTrackId, cascPosTrackId, int); //! Positive track ID from Λ in Ξ cascade (Ξc± → Ξππ) +DECLARE_SOA_COLUMN(CascNegTrackId, cascNegTrackId, int); //! Negative track ID from Λ in Ξ cascade (Ξc± → Ξππ) +DECLARE_SOA_COLUMN(CascBachelorPt, cascBachelorPt, float); //! pT of the bachelor track from the Xi cascade +DECLARE_SOA_COLUMN(CascBachelorPhi, cascBachelorPhi, float); //! phi of the bachelor track from the Xi cascade +DECLARE_SOA_COLUMN(CascBachelorEta, cascBachelorEta, float); //! eta of the bachelor track from the Xi cascade +DECLARE_SOA_COLUMN(CascPosPt, cascPosPt, float); //! pT of the positive Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascPosPhi, cascPosPhi, float); //! phi of the positive Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascPosEta, cascPosEta, float); //! eta of the positive Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascNegPt, cascNegPt, float); //! pT of the negative Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascNegPhi, cascNegPhi, float); //! phi of the negative Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(CascNegEta, cascNegEta, float); //! eta of the negative Lambda daughter track from the Xi cascade +DECLARE_SOA_COLUMN(FlagMc, flagMc, int); //! MC matching flag for the selected charm hadron decay channel DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int); //! flag for reconstruction level matching (1 for prompt, 2 for non-prompt) DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int); //! flag for generator level matching (1 for prompt, 2 for non-prompt) DECLARE_SOA_COLUMN(IsCandidateSwapped, isCandidateSwapped, int); //! swapping of the prongs order (0 for Lc -> pkpi, 1 for Lc -> pikp) @@ -270,12 +283,12 @@ DECLARE_SOA_COLUMN(KT, kT, float); //! kT distribu DECLARE_SOA_COLUMN(MT, mT, float); //! Transverse mass distribution DECLARE_SOA_COLUMN(CharmM, charmM, float); //! Charm hadron mass DECLARE_SOA_COLUMN(CharmDaughM, charmDaughM, float); //! Charm hadron daughter mass -DECLARE_SOA_COLUMN(CharmTrkM, charmtrkM, float); //! Charm hadron track mass +DECLARE_SOA_COLUMN(CharmTrkM, charmtrkM, float); //! Invariant-mass difference of the charm-track pair DECLARE_SOA_COLUMN(CharmPt, charmPt, float); //! Transverse momentum of charm hadron for result task DECLARE_SOA_COLUMN(CharmEta, charmEta, float); //! Eta of charm hadron for result task DECLARE_SOA_COLUMN(CharmPhi, charmPhi, float); //! Phi of charm hadron for result task DECLARE_SOA_COLUMN(Mult, mult, int); //! Charge particle multiplicity -DECLARE_SOA_COLUMN(MultPercentile, multPercentile, float); //! Multiplicity precentile +DECLARE_SOA_COLUMN(MultPercentile, multPercentile, float); //! Multiplicity percentile DECLARE_SOA_COLUMN(PairSign, pairSign, int8_t); //! Selection between like sign (1) and unlike sign pair (2) DECLARE_SOA_COLUMN(ProcessType, processType, int64_t); //! Selection between same-event (1), and mixed-event (2) DECLARE_SOA_DYNAMIC_COLUMN(M, m, //! @@ -388,6 +401,16 @@ DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, RecoDecayPtEtaPhi::pVector(pt2, eta2, phi2))); }); //! Eta distribution of charm hadron } // namespace fdhf_dstar +namespace fdhf_xic +{ +DECLARE_SOA_DYNAMIC_COLUMN(Y, y, //! + [](float pt0, float phi0, float eta0, float pt1, float phi1, float eta1, float pt2, float phi2, float eta2) -> float { return RecoDecay::y(RecoDecay::pVec( + RecoDecayPtEtaPhi::pVector(pt0, eta0, phi0), + RecoDecayPtEtaPhi::pVector(pt1, eta1, phi1), + RecoDecayPtEtaPhi::pVector(pt2, eta2, phi2)), + o2::constants::physics::MassXiCPlus); }); //! Rapidity distribution of Xic candidates +} // namespace fdhf_xic + DECLARE_SOA_TABLE(FDHfCand3Prong, "AOD", "FDHFCAND3PRONG", //! Table to store the derived data for charm 3prong candidates o2::soa::Index<>, femtodreamparticle::FDCollisionId, @@ -416,6 +439,49 @@ DECLARE_SOA_TABLE(FDHfCand3Prong, "AOD", "FDHFCAND3PRONG", //! Table to store th fdhf::Phi, fdhf::Pt); +DECLARE_SOA_TABLE(FDHfCand3ProngXic, "AOD", "FDHFXIC3PRONG", //! Table to store the derived data for Ξc → Ξππ candidates + o2::soa::Index<>, + femtodreamparticle::FDCollisionId, + fdhf::TimeStamp, + fdhf::Charge, + fdhf::CascId, + fdhf::Prong1Id, + fdhf::Prong2Id, + fdhf::CascBachelorTrackId, + fdhf::CascPosTrackId, + fdhf::CascNegTrackId, + fdhf::Prong0Pt, + fdhf::Prong1Pt, + fdhf::Prong2Pt, + fdhf::Prong0Eta, + fdhf::Prong1Eta, + fdhf::Prong2Eta, + fdhf::Prong0Phi, + fdhf::Prong1Phi, + fdhf::Prong2Phi, + fdhf::CandidateSelFlag, + fdhf::BDTBkg, + fdhf::BDTPrompt, + fdhf::BDTFD, + fdhf::M, + fdhf::P, + fdhf_xic::Y, + fdhf::Eta, + fdhf::Phi, + fdhf::Pt); + +DECLARE_SOA_TABLE(FDHfCand3ProngXicQa, "AOD", "FDHFXIC3PQA", //! QA extension table for Ξ daughters in Ξc → Ξππ candidates + o2::soa::Index<>, + fdhf::CascBachelorPt, + fdhf::CascBachelorPhi, + fdhf::CascBachelorEta, + fdhf::CascPosPt, + fdhf::CascPosPhi, + fdhf::CascPosEta, + fdhf::CascNegPt, + fdhf::CascNegPhi, + fdhf::CascNegEta); + DECLARE_SOA_TABLE(FDHfCand2Prong, "AOD", "FDHFCAND2PRONG", //! Table to store the derived data for charm 3prong candidates o2::soa::Index<>, femtodreamparticle::FDCollisionId, @@ -681,8 +747,16 @@ static constexpr std::string_view ParticleOriginMCTruthName[kNOriginMCTruthTypes "_Material", "_NotPrimary", "_Fake", + "_WrongCollision", "_SecondaryDaughterLambda", - "_SecondaryDaughterSigmaPlus"}; + "_SecondaryDaughterSigmaPlus", + "_SecondaryDaughterSigma0", + "_SecondaryDaughterXiMinus", + "_SecondaryDaughterXi0", + "_SecondaryDaughterOmegaMinus", + "_SecondaryDaughterXistar0", + "_SecondaryDaughterXistarMinus", + "_Else"}; /// Distinguished between reconstructed and truth enum MCType { diff --git a/PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt b/PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt index a10cc46db09..25d872112b4 100644 --- a/PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt +++ b/PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt @@ -83,3 +83,8 @@ o2physics_add_dpl_workflow(net-prot-cumulants SOURCES netprotcumulants.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(strongly-intensive-corr + SOURCES stronglyIntensiveCorr.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx b/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx index 76d4ef30e91..a60f36a8c3a 100644 --- a/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx @@ -60,13 +60,9 @@ enum RunType { // Structure to handle net charge fluctuation analysis struct NetchargeFluctuations { - // Macro to define configurable parameters with default values and help text - -#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; - // Services for PDG and CCDB (Calibration and Condition Database) - Service pdgService; // Particle data group service - Service ccdb; // CCDB manager service + Service pdgService{}; // Particle data group service + Service ccdb{}; // CCDB manager service // Random number generator for statistical fluctuations, initialized with seed 0 TRandom3* fRndm = new TRandom3(0); @@ -80,10 +76,22 @@ struct NetchargeFluctuations { // CCDB related configurations Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable cfgUrlCCDB{"cfgUrlCCDB", "http://alice-ccdb.cern.ch", "url of ccdb"}; - Configurable cfgPathCCDB{"cfgPathCCDB", "Users/n/nimalik/My/Object/pn", "Path for ccdb-object"}; + Configurable cfgPathCCDB{"cfgPathCCDB", "Users/n/nimalik/PosNeg_cent/PbPb/LHC24g3_medium", "Path for ccdb-object"}; Configurable cfgLoadEff{"cfgLoadEff", true, "Load efficiency"}; Configurable cfgEffNue{"cfgEffNue", false, "efficiency correction to nu_dyn"}; + Configurable cfgCentEstimator{"cfgCentEstimator", 0, "0=FT0C, 1=FT0A, 2=FT0M"}; + Configurable cut05{"cut05", 155, "0-5% boundary"}; + Configurable cut10{"cut10", 130, "5-10% boundary"}; + Configurable cut20{"cut20", 97, "10-20% boundary"}; + Configurable cut30{"cut30", 71, "20-30% boundary"}; + Configurable cut40{"cut40", 52, "30-40% boundary"}; + Configurable cut50{"cut50", 36, "40-50% boundary"}; + Configurable cut60{"cut60", 26, "50-60% boundary"}; + Configurable cut70{"cut70", 19, "60-70% boundary"}; + Configurable cut80{"cut80", 11, "70-80% boundary"}; + Configurable cut90{"cut90", 5, "80-90% boundary"}; + // Track and event selection cuts Configurable vertexZcut{"vertexZcut", 10.f, "Vertex Z"}; Configurable etaCut{"etaCut", 0.8f, "Eta cut"}; @@ -95,10 +103,14 @@ struct NetchargeFluctuations { Configurable itsChiCut{"itsChiCut", 36., "ITS chi2 cluster cut"}; Configurable tpcChiCut{"tpcChiCut", 4., "TPC chi2 cluster cut"}; Configurable centMin{"centMin", 0.0f, "cenrality min for delta eta"}; - Configurable centMax{"centMax", 10.0f, "cenrality max for delta eta"}; + Configurable centMax{"centMax", 5.0f, "cenrality max for delta eta"}; Configurable cfgNSubsample{"cfgNSubsample", 30, "Number of subsamples for Error"}; Configurable deltaEta{"deltaEta", 8, "Delta eta bin count"}; Configurable threshold{"threshold", 1e-6, "Delta eta bin count"}; + Configurable ft0Cmin{"ft0Cmin", -3.3, "FT0C min"}; + Configurable ft0Cmax{"ft0Cmax", -2.1, "FT0C max"}; + Configurable ft0Amin{"ft0Amin", 3.5, "FT0A min"}; + Configurable ft0Amax{"ft0Amax", 4.9, "FT0A max"}; // Event selections Configurable cSel8Trig{"cSel8Trig", true, "Sel8 (T0A + T0C) Selection Run3"}; // sel8 @@ -123,15 +135,17 @@ struct NetchargeFluctuations { Configurable cPVcont{"cPVcont", false, "primary vertex contributor"}; // Configurable to enable multiplicity correlation cuts - O2_DEFINE_CONFIGURABLE(cfgEvSelMultCorrelation, bool, false, "Multiplicity correlation cut") + Configurable cfgEvSelMultCorrelation{"cfgEvSelMultCorrelation", false, "Multiplicity correlation cut"}; // Struct grouping multiplicity vs centrality/vertex cuts and related parameters struct : ConfigurableGroup { // Flags to enable specific multiplicity correlation cuts - O2_DEFINE_CONFIGURABLE(cfgMultPVT0CCutEnabled, bool, true, "Enable PV multiplicity vs T0C centrality cut") - O2_DEFINE_CONFIGURABLE(cfgMultGlobalFT0CCutEnabled, bool, true, "Enable globalTracks vs FT0C multiplicity cut") - O2_DEFINE_CONFIGURABLE(cfgMultGlobalPVCutEnabled, bool, true, "Enable globalTracks vs PV multiplicity cut") + Configurable cfgMultPVT0CCutEnabled{"cfgMultPVT0CCutEnabled", true, "Enable PV multiplicity vs T0C centrality cut"}; + + Configurable cfgMultGlobalFT0CCutEnabled{"cfgMultGlobalFT0CCutEnabled", true, "Enable globalTracks vs FT0C multiplicity cut"}; + + Configurable cfgMultGlobalPVCutEnabled{"cfgMultGlobalPVCutEnabled", true, "Enable globalTracks vs PV multiplicity cut"}; // Parameter values for PV multiplicity vs FT0C centrality cut (polynomial coefficients, etc.) Configurable> cfgMultPVT0CCutPars{"cfgMultPVT0CCutPars", @@ -166,8 +180,8 @@ struct NetchargeFluctuations { // Histogram pointer for CCDB efficiency // TH1D* efficiency = nullptr; - TH1D* efficiencyPos = nullptr; - TH1D* efficiencyNeg = nullptr; + TH2F* efficiencyPos = nullptr; + TH2F* efficiencyNeg = nullptr; // Filters for selecting collisions and tracks Filter collisionFilter = nabs(aod::collision::posZ) <= vertexZcut; @@ -246,6 +260,10 @@ struct NetchargeFluctuations { histogramRegistry.add("QA/hCentrality", "", kTH1F, {centAxis}); histogramRegistry.add("QA/hMultiplicity", "", kTH1F, {multAxis}); + histogramRegistry.add("cent/multFT0C", "", kTH1F, {nchAxis}); + histogramRegistry.add("cent/multFT0A", "", kTH1F, {nchAxis}); + histogramRegistry.add("cent/multFT0M", "", kTH1F, {nchAxis}); + histogramRegistry.add("gen/hVtxZ_before", "", kTH1F, {vtxzAxis}); histogramRegistry.add("gen/hVtxZ_after", "", kTH1F, {vtxzAxis}); histogramRegistry.add("gen/hPt", "", kTH1F, {ptAxis}); @@ -347,9 +365,21 @@ struct NetchargeFluctuations { histogramRegistry.add("QA/hNchPV", "", kTH1F, {nchAxis}); histogramRegistry.add("eff/hPt_np_gen", "", kTH1F, {ptAxis}); + histogramRegistry.add("eff/hPt_hEta_np_gen", "", kTH2F, {ptAxis, etaAxis}); histogramRegistry.add("eff/hPt_nm_gen", "", kTH1F, {ptAxis}); + histogramRegistry.add("eff/hPt_hEta_nm_gen", "", kTH2F, {ptAxis, etaAxis}); + histogramRegistry.add("eff/cent/hPt_np_gen", "", kTH1F, {ptAxis}); + histogramRegistry.add("eff/cent/hPt_hEta_np_gen", "", kTH2F, {ptAxis, etaAxis}); + histogramRegistry.add("eff/cent/hPt_nm_gen", "", kTH1F, {ptAxis}); + histogramRegistry.add("eff/cent/hPt_hEta_nm_gen", "", kTH2F, {ptAxis, etaAxis}); histogramRegistry.add("eff/hPt_np", "", kTH1F, {ptAxis}); + histogramRegistry.add("eff/hPt_hEta_np", "", kTH2F, {ptAxis, etaAxis}); histogramRegistry.add("eff/hPt_nm", "", kTH1F, {ptAxis}); + histogramRegistry.add("eff/hPt_hEta_nm", "", kTH2F, {ptAxis, etaAxis}); + histogramRegistry.add("eff/cent/hPt_np", "", kTH1F, {ptAxis}); + histogramRegistry.add("eff/cent/hPt_hEta_np", "", kTH2F, {ptAxis, etaAxis}); + histogramRegistry.add("eff/cent/hPt_nm", "", kTH1F, {ptAxis}); + histogramRegistry.add("eff/cent/hPt_hEta_nm", "", kTH2F, {ptAxis, etaAxis}); // QA histograms for multiplicity correlations histogramRegistry.add("MultCorrelationPlots/globalTracks_PV_bef", "", {HistType::kTH2D, {nchAxis, nchAxis}}); @@ -369,16 +399,15 @@ struct NetchargeFluctuations { cfgFunCoeff.fMultPVT0CCutLow = new TF1("fMultPVT0CCutLow", - "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x - 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", - 0, 100); - cfgFunCoeff.fMultPVT0CCutLow->SetParameters(&(cfgFunCoeff.multPVT0CCutPars[0])); + "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x - 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); + cfgFunCoeff.fMultPVT0CCutLow->SetParameters(cfgFunCoeff.multPVT0CCutPars.data()); // Upper cut function: 4th-order polynomial plus 3.5 sigma deviation cfgFunCoeff.fMultPVT0CCutHigh = new TF1("fMultPVT0CCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x + 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); - cfgFunCoeff.fMultPVT0CCutHigh->SetParameters(&(cfgFunCoeff.multPVT0CCutPars[0])); + cfgFunCoeff.fMultPVT0CCutHigh->SetParameters(cfgFunCoeff.multPVT0CCutPars.data()); // --- Initialize globalTracks vs FT0C multiplicity cut functions --- // Lower cut function @@ -386,14 +415,14 @@ struct NetchargeFluctuations { new TF1("fMultGlobalFT0CCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x - 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); - cfgFunCoeff.fMultGlobalFT0CCutLow->SetParameters(&(cfgFunCoeff.multGlobalFT0CPars[0])); + cfgFunCoeff.fMultGlobalFT0CCutLow->SetParameters(cfgFunCoeff.multGlobalFT0CPars.data()); // Upper cut function cfgFunCoeff.fMultGlobalFT0CCutHigh = new TF1("fMultGlobalFT0CCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x + 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); - cfgFunCoeff.fMultGlobalFT0CCutHigh->SetParameters(&(cfgFunCoeff.multGlobalFT0CPars[0])); + cfgFunCoeff.fMultGlobalFT0CCutHigh->SetParameters(cfgFunCoeff.multGlobalFT0CPars.data()); // --- Initialize globalTracks vs PV multiplicity cut functions --- // Lower cut: linear + cubic term minus 3.5 sigma @@ -402,14 +431,14 @@ struct NetchargeFluctuations { new TF1("fMultGlobalPVCutLow", "[0]+[1]*x - 3.5*([2]+[3]*x+[4]*x*x+[5]*x*x*x)", 0, 100); - cfgFunCoeff.fMultGlobalPVCutLow->SetParameters(&(cfgFunCoeff.multGlobalPVCutPars[0])); + cfgFunCoeff.fMultGlobalPVCutLow->SetParameters(cfgFunCoeff.multGlobalPVCutPars.data()); // Upper cut: linear + cubic term plus 3.5 sigma cfgFunCoeff.fMultGlobalPVCutHigh = new TF1("fMultGlobalPVCutHigh", "[0]+[1]*x + 3.5*([2]+[3]*x+[4]*x*x+[5]*x*x*x)", 0, 100); - cfgFunCoeff.fMultGlobalPVCutHigh->SetParameters(&(cfgFunCoeff.multGlobalPVCutPars[0])); + cfgFunCoeff.fMultGlobalPVCutHigh->SetParameters(cfgFunCoeff.multGlobalPVCutPars.data()); // --- Load efficiency histogram from CCDB if (cfgLoadEff) { @@ -417,9 +446,10 @@ struct NetchargeFluctuations { ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); - TList* list = ccdb->getForTimeStamp(cfgPathCCDB.value, 1); - efficiencyPos = reinterpret_cast(list->FindObject("efficiency_Pos_Run3")); - efficiencyNeg = reinterpret_cast(list->FindObject("efficiency_Neg_Run3")); + auto* list = ccdb->getForTimeStamp(cfgPathCCDB.value, 1); + efficiencyPos = dynamic_cast(list->FindObject("efficiency_Pos")); + efficiencyNeg = dynamic_cast(list->FindObject("efficiency_Neg")); + // Log fatal error if efficiency histogram is not found if (!efficiencyPos || !efficiencyNeg) { LOGF(info, "FATAL!! Could not find required histograms in CCDB"); @@ -431,26 +461,31 @@ struct NetchargeFluctuations { { if (cfgFunCoeff.cfgMultPVT0CCutEnabled) { - if (pvTrack < cfgFunCoeff.fMultPVT0CCutLow->Eval(centrality)) + if (pvTrack < cfgFunCoeff.fMultPVT0CCutLow->Eval(centrality)) { return false; - if (pvTrack > cfgFunCoeff.fMultPVT0CCutHigh->Eval(centrality)) + } + if (pvTrack > cfgFunCoeff.fMultPVT0CCutHigh->Eval(centrality)) { return false; + } } - if (cfgFunCoeff.cfgMultGlobalFT0CCutEnabled) { - if (globalNch < cfgFunCoeff.fMultGlobalFT0CCutLow->Eval(centrality)) + if (globalNch < cfgFunCoeff.fMultGlobalFT0CCutLow->Eval(centrality)) { return false; - if (globalNch > cfgFunCoeff.fMultGlobalFT0CCutHigh->Eval(centrality)) + } + if (globalNch > cfgFunCoeff.fMultGlobalFT0CCutHigh->Eval(centrality)) { return false; + } } if (cfgFunCoeff.cfgMultGlobalPVCutEnabled) { - if (globalNch < cfgFunCoeff.fMultGlobalPVCutLow->Eval(pvTrack)) + if (globalNch < cfgFunCoeff.fMultGlobalPVCutLow->Eval(pvTrack)) { return false; - if (globalNch > cfgFunCoeff.fMultGlobalPVCutHigh->Eval(pvTrack)) + } + if (globalNch > cfgFunCoeff.fMultGlobalPVCutHigh->Eval(pvTrack)) { return false; + } } return true; @@ -460,8 +495,9 @@ struct NetchargeFluctuations { bool selCollision(C const& coll, float& cent, float& mult) { - if (std::abs(coll.posZ()) >= vertexZcut) + if (std::abs(coll.posZ()) >= vertexZcut) { return false; + } if constexpr (run == kRun3) { if (cSel8Trig && !coll.sel8()) { return false; @@ -485,19 +521,24 @@ struct NetchargeFluctuations { mult = coll.multFV0M(); // multiplicity for run2 } - if (cNoItsROBorder && !coll.selection_bit(aod::evsel::kNoITSROFrameBorder)) + if (cNoItsROBorder && !coll.selection_bit(aod::evsel::kNoITSROFrameBorder)) { return false; - if (cTFBorder && !coll.selection_bit(aod::evsel::kNoTimeFrameBorder)) + } + if (cTFBorder && !coll.selection_bit(aod::evsel::kNoTimeFrameBorder)) { return false; - if (cPileupReject && !coll.selection_bit(aod::evsel::kNoSameBunchPileup)) + } + if (cPileupReject && !coll.selection_bit(aod::evsel::kNoSameBunchPileup)) { return false; - if (cZVtxTimeDiff && !coll.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) + } + if (cZVtxTimeDiff && !coll.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { return false; - if (cItsTpcVtx && !coll.selection_bit(aod::evsel::kIsVertexITSTPC)) + } + if (cItsTpcVtx && !coll.selection_bit(aod::evsel::kIsVertexITSTPC)) { return false; - if (cfgUseGoodItsLayerAllCut && !(coll.selection_bit(aod::evsel::kIsGoodITSLayersAll))) + } + if (cfgUseGoodItsLayerAllCut && !(coll.selection_bit(aod::evsel::kIsGoodITSLayersAll))) { return false; - + } return true; } @@ -532,33 +573,43 @@ struct NetchargeFluctuations { template bool selTrack(T const& track) { - if (!track.isGlobalTrack()) + if (!track.isGlobalTrack()) { return false; - if (cPVcont && !track.isPVContributor()) + } + if (cPVcont && !track.isPVContributor()) { return false; - if (std::fabs(track.eta()) >= etaCut) + } + if (std::fabs(track.eta()) >= etaCut) { return false; - if (track.pt() <= ptMinCut || track.pt() >= ptMaxCut) + } + if (track.pt() <= ptMinCut || track.pt() >= ptMaxCut) { return false; - if (track.sign() == 0) + } + if (track.sign() == 0) { return false; - if (cDcaXy && std::fabs(track.dcaXY()) >= dcaXYCut) + } + if (cDcaXy && std::fabs(track.dcaXY()) >= dcaXYCut) { return false; - if (cDcaZ && std::fabs(track.dcaZ()) >= dcaZCut) + } + if (cDcaZ && std::fabs(track.dcaZ()) >= dcaZCut) { return false; - if (cTpcCr && track.tpcNClsCrossedRows() <= tpcCrossCut) + } + if (cTpcCr && track.tpcNClsCrossedRows() <= tpcCrossCut) { return false; - if (cItsChi && track.itsChi2NCl() >= itsChiCut) + } + if (cItsChi && track.itsChi2NCl() >= itsChiCut) { return false; - if (cTpcChi && track.tpcChi2NCl() >= tpcChiCut) + } + if (cTpcChi && track.tpcChi2NCl() >= tpcChiCut) { return false; + } return true; } - double getEfficiency(float pt, int sign) + double getEfficiency(float pt, float eta, int sign) { - TH1D* hEff = nullptr; + TH2F* hEff = nullptr; if (sign > 0) { hEff = efficiencyPos; @@ -569,11 +620,15 @@ struct NetchargeFluctuations { if (!hEff) { return 1e-6; } - int bin = hEff->GetXaxis()->FindBin(pt); - if (bin < 1 || bin > hEff->GetNbinsX()) { - return 1e-6; + int binx = hEff->GetXaxis()->FindBin(pt); + int biny = hEff->GetYaxis()->FindBin(eta); + + if (binx < 1 || binx > hEff->GetNbinsX() || + biny < 1 || biny > hEff->GetNbinsY()) { + return -1; } - double eff = hEff->GetBinContent(bin); + + double eff = hEff->GetBinContent(binx, biny); return eff; } @@ -617,7 +672,7 @@ struct NetchargeFluctuations { return; } - float globalNch = tracks.size(); + auto globalNch = tracks.size(); float pvTrack = coll.multNTracksPV(); histogramRegistry.fill(HIST("QA/hCentFT0C"), cent); @@ -646,10 +701,11 @@ struct NetchargeFluctuations { for (const auto& track : tracks) { fillBeforeQA(track); - if (!selTrack(track)) + if (!selTrack(track)) { continue; + } - double eff = getEfficiency(track.pt(), track.sign()); + double eff = getEfficiency(track.pt(), track.eta(), track.sign()); if (eff < threshold) { continue; } @@ -715,8 +771,8 @@ struct NetchargeFluctuations { return; } - int globalNch = inputTracks.size(); - int pvTrack = coll.multNTracksPV(); + auto globalNch = inputTracks.size(); + float pvTrack = coll.multNTracksPV(); histogramRegistry.fill(HIST("QA/hCentFT0C"), cent); histogramRegistry.fill(HIST("QA/hNchGlobal"), globalNch); @@ -745,23 +801,35 @@ struct NetchargeFluctuations { for (const auto& track : inputTracks) { fillBeforeQA(track); - if (!selTrack(track)) + if (!selTrack(track)) { continue; + } nch += 1; fillAfterQA(track); if (track.sign() == 1) { histogramRegistry.fill(HIST("eff/hPt_np"), track.pt()); + histogramRegistry.fill(HIST("eff/hPt_hEta_np"), track.pt(), track.eta()); + if (cent >= centMin && cent < centMax) { + histogramRegistry.fill(HIST("eff/cent/hPt_np"), track.pt()); + histogramRegistry.fill(HIST("eff/cent/hPt_hEta_np"), track.pt(), track.eta()); + } } else if (track.sign() == -1) { histogramRegistry.fill(HIST("eff/hPt_nm"), track.pt()); + histogramRegistry.fill(HIST("eff/hPt_hEta_nm"), track.pt(), track.eta()); + if (cent >= centMin && cent < centMax) { + histogramRegistry.fill(HIST("eff/cent/hPt_nm"), track.pt()); + histogramRegistry.fill(HIST("eff/cent/hPt_hEta_nm"), track.pt(), track.eta()); + } } histogramRegistry.fill(HIST("QA/cent_hEta"), cent, track.eta()); histogramRegistry.fill(HIST("QA/cent_hPt"), cent, track.pt()); - double eff = getEfficiency(track.pt(), track.sign()); - if (eff < threshold) + double eff = getEfficiency(track.pt(), track.eta(), track.sign()); + if (eff < threshold) { continue; + } double weight = 1.0 / eff; histogramRegistry.fill(HIST("data/hPt_cor"), track.pt(), weight); histogramRegistry.fill(HIST("data/hEta_cor"), track.eta(), weight); @@ -801,40 +869,56 @@ struct NetchargeFluctuations { int posGen = 0, negGen = 0, posNegGen = 0, termNGen = 0, termPGen = 0, nchGen = 0; const auto& mccolgen = coll.template mcCollision_as(); - if (std::abs(mccolgen.posZ()) >= vertexZcut) + if (std::abs(mccolgen.posZ()) >= vertexZcut) { return; + } const auto& mcpartgen = mcParticles.sliceByCached(aod::mcparticle::mcCollisionId, mccolgen.globalIndex(), cache); histogramRegistry.fill(HIST("gen/hVtxZ_after"), mccolgen.posZ()); for (const auto& mcpart : mcpartgen) { - if (std::fabs(mcpart.eta()) >= etaCut) + if (std::fabs(mcpart.eta()) >= etaCut) { continue; - if (!mcpart.isPhysicalPrimary()) + } + if (!mcpart.isPhysicalPrimary()) { continue; + } int pid = mcpart.pdgCode(); - auto sign = 0; + int sign = 0; auto* pd = pdgService->GetParticle(pid); if (pd != nullptr) { - sign = pd->Charge() / 3.; + sign = static_cast(pd->Charge() / 3.0); } - if (sign == 0) + if (sign == 0) { continue; + } if (std::abs(pid) != kElectron && std::abs(pid) != kMuonMinus && std::abs(pid) != kPiPlus && std::abs(pid) != kKPlus && - std::abs(pid) != kProton) + std::abs(pid) != kProton) { continue; - if (std::fabs(mcpart.eta()) >= etaCut) + } + if (std::fabs(mcpart.eta()) >= etaCut) { continue; + } if ((mcpart.pt() <= ptMinCut) || (mcpart.pt() >= ptMaxCut)) { continue; } if (sign == 1) { histogramRegistry.fill(HIST("eff/hPt_np_gen"), mcpart.pt()); + histogramRegistry.fill(HIST("eff/hPt_hEta_np_gen"), mcpart.pt(), mcpart.eta()); + if (cent >= centMin && cent < centMax) { + histogramRegistry.fill(HIST("eff/cent/hPt_np_gen"), mcpart.pt()); + histogramRegistry.fill(HIST("eff/cent/hPt_hEta_np_gen"), mcpart.pt(), mcpart.eta()); + } + } else if (sign == -1) { histogramRegistry.fill(HIST("eff/hPt_nm_gen"), mcpart.pt()); + histogramRegistry.fill(HIST("eff/hPt_hEta_nm_gen"), mcpart.pt(), mcpart.eta()); + if (cent >= centMin && cent < centMax) { + histogramRegistry.fill(HIST("eff/cent/hPt_nm_gen"), mcpart.pt()); + histogramRegistry.fill(HIST("eff/cent/hPt_hEta_nm_gen"), mcpart.pt(), mcpart.eta()); + } } - histogramRegistry.fill(HIST("gen/hPt"), mcpart.pt()); histogramRegistry.fill(HIST("gen/cent_hPt"), cent, mcpart.pt()); histogramRegistry.fill(HIST("gen/hEta"), mcpart.eta()); @@ -879,16 +963,19 @@ struct NetchargeFluctuations { void calculationDeltaEta(C const& coll, T const& tracks, float deta1, float deta2) { float cent = -1, mult = -1; - if (!selCollision(coll, cent, mult)) + if (!selCollision(coll, cent, mult)) { return; + } - int globalNch = tracks.size(); - int pvTrack = coll.multNTracksPV(); - if (cfgEvSelMultCorrelation && !eventSelected(globalNch, pvTrack, cent)) + auto globalNch = tracks.size(); + float pvTrack = coll.multNTracksPV(); + if (cfgEvSelMultCorrelation && !eventSelected(globalNch, pvTrack, cent)) { return; + } - if (!(cent >= centMin && cent < centMax)) + if (cent < centMin || cent >= centMax) { return; + } histogramRegistry.fill(HIST("data/delta_eta_cent"), cent); int fpos = 0, fneg = 0, termp = 0, termn = 0, posneg = 0; @@ -901,16 +988,19 @@ struct NetchargeFluctuations { for (const auto& track : tracks) { - if (!selTrack(track)) + if (!selTrack(track)) { continue; + } double eta = track.eta(); - if (eta < deta1 || eta > deta2) + if (eta < deta1 || eta > deta2) { continue; + } - double eff = getEfficiency(track.pt(), track.sign()); - if (eff < threshold) + double eff = getEfficiency(track.pt(), track.eta(), track.sign()); + if (eff < threshold) { continue; + } double weight = 1.0 / eff; @@ -990,20 +1080,25 @@ struct NetchargeFluctuations { { (void)mcCollisions; - if (!coll.has_mcCollision()) + if (!coll.has_mcCollision()) { return; + } float cent = -1, mult = -1; - if (!selCollision(coll, cent, mult)) + if (!selCollision(coll, cent, mult)) { return; + } - int globalNch = inputTracks.size(); - int pvTrack = coll.multNTracksPV(); - if (cfgEvSelMultCorrelation && !eventSelected(globalNch, pvTrack, cent)) + auto globalNch = inputTracks.size(); + float pvTrack = coll.multNTracksPV(); + if (cfgEvSelMultCorrelation && !eventSelected(globalNch, pvTrack, cent)) { return; + } - if (!(cent >= centMin && cent < centMax)) + if (cent < centMin || cent >= centMax) { return; + } + histogramRegistry.fill(HIST("data/delta_eta_cent"), cent); float deltaEtaWidth = deta2 - deta1 + 1e-5f; @@ -1015,16 +1110,20 @@ struct NetchargeFluctuations { double nchCor = 0.0, termpW = 0.0, termnW = 0.0, posnegW = 0.0; for (const auto& track : inputTracks) { - if (!selTrack(track)) + if (!selTrack(track)) { continue; + } double eta = track.eta(); - if (eta < deta1 || eta > deta2) + if (eta < deta1 || eta > deta2) { continue; + } histogramRegistry.fill(HIST("data/delta_eta_eta"), eta); - double eff = getEfficiency(track.pt(), track.sign()); - if (eff < threshold) + double eff = getEfficiency(track.pt(), track.eta(), track.sign()); + + if (eff < threshold) { continue; + } double weight = 1.0 / eff; nch += 1; nchCor += weight; @@ -1073,39 +1172,267 @@ struct NetchargeFluctuations { const auto& mccolgen = coll.template mcCollision_as(); - if (std::abs(mccolgen.posZ()) >= vertexZcut) + if (std::abs(mccolgen.posZ()) >= vertexZcut) { return; + } const auto& mcpartgen = mcParticles.sliceByCached(aod::mcparticle::mcCollisionId, mccolgen.globalIndex(), cache); int posGen = 0, negGen = 0, posNegGen = 0, termNGen = 0, termPGen = 0, nchGen = 0; for (const auto& mcpart : mcpartgen) { - if (!mcpart.isPhysicalPrimary()) + if (!mcpart.isPhysicalPrimary()) { + continue; + } + + int pid = mcpart.pdgCode(); + auto sign = 0; + auto* pd = pdgService->GetParticle(pid); + if (pd != nullptr) { + sign = static_cast(pd->Charge() / 3.0); + } + if (sign == 0) { + continue; + } + if (std::abs(pid) != kElectron && + std::abs(pid) != kMuonMinus && + std::abs(pid) != kPiPlus && + std::abs(pid) != kKPlus && + std::abs(pid) != kProton) { + continue; + } + + if (std::fabs(mcpart.eta()) >= etaCut) { + continue; + } + if ((mcpart.pt() <= ptMinCut) || (mcpart.pt() >= ptMaxCut)) { + continue; + } + + double mcEta = mcpart.eta(); + if (mcEta < deta1 || mcEta > deta2) { + continue; + } + + histogramRegistry.fill(HIST("gen/delta_eta_eta"), mcpart.eta()); + + nchGen += 1; + if (sign == 1) { + posGen += 1; + } + if (sign == -1) { + negGen += 1; + } + } + + termPGen = posGen * (posGen - 1); + termNGen = negGen * (negGen - 1); + posNegGen = posGen * negGen; + + histogramRegistry.fill(HIST("gen/delta_eta_pos"), deltaEtaWidth, posGen); + histogramRegistry.fill(HIST("gen/delta_eta_neg"), deltaEtaWidth, negGen); + histogramRegistry.fill(HIST("gen/delta_eta_termp"), deltaEtaWidth, termPGen); + histogramRegistry.fill(HIST("gen/delta_eta_termn"), deltaEtaWidth, termNGen); + histogramRegistry.fill(HIST("gen/delta_eta_pos_sq"), deltaEtaWidth, posGen * posGen); + histogramRegistry.fill(HIST("gen/delta_eta_neg_sq"), deltaEtaWidth, negGen * negGen); + histogramRegistry.fill(HIST("gen/delta_eta_posneg"), deltaEtaWidth, posNegGen); + histogramRegistry.fill(HIST("gen/delta_eta_nch"), deltaEtaWidth, nchGen); + + float lRandom = fRndm->Rndm(); + int sampleIndex = static_cast(cfgNSubsample * lRandom); + + histogramRegistry.fill(HIST("subsample/delta_eta/gen/pos"), deltaEtaWidth, sampleIndex, posGen); + histogramRegistry.fill(HIST("subsample/delta_eta/gen/neg"), deltaEtaWidth, sampleIndex, negGen); + histogramRegistry.fill(HIST("subsample/delta_eta/gen/termp"), deltaEtaWidth, sampleIndex, termPGen); + histogramRegistry.fill(HIST("subsample/delta_eta/gen/termn"), deltaEtaWidth, sampleIndex, termNGen); + histogramRegistry.fill(HIST("subsample/delta_eta/gen/pos_sq"), deltaEtaWidth, sampleIndex, posGen * posGen); + histogramRegistry.fill(HIST("subsample/delta_eta/gen/neg_sq"), deltaEtaWidth, sampleIndex, negGen * negGen); + histogramRegistry.fill(HIST("subsample/delta_eta/gen/posneg"), deltaEtaWidth, sampleIndex, posNegGen); + + } // void + + float getCentrality(aod::McParticles const& particles) + { + int multFT0A = 0; + int multFT0C = 0; + + for (auto const& part : particles) { + + if (!part.isPhysicalPrimary()) { continue; + } + + // FT0C + if (part.eta() > ft0Cmin && part.eta() < ft0Cmax) { + multFT0C++; + } + + // FT0A + if (part.eta() > ft0Amin && part.eta() < ft0Amax) { + multFT0A++; + } + } + + int multFT0M = multFT0A + multFT0C; + // LOGF(info, "multFT0C = %d", multFT0C); + histogramRegistry.fill(HIST("cent/multFT0C"), multFT0C); + histogramRegistry.fill(HIST("cent/multFT0A"), multFT0A); + histogramRegistry.fill(HIST("cent/multFT0M"), multFT0M); + + int multEstimator = 0; + + if (cfgCentEstimator == 0) { + multEstimator = multFT0C; + } else if (cfgCentEstimator == 1) { + multEstimator = multFT0A; + } else { + multEstimator = multFT0M; + } + // centrality cuts + if (multEstimator >= cut05) + return 2.5; + if (multEstimator >= cut10) + return 7.5; + if (multEstimator >= cut20) + return 15; + if (multEstimator >= cut30) + return 25; + if (multEstimator >= cut40) + return 35; + if (multEstimator >= cut50) + return 45; + if (multEstimator >= cut60) + return 55; + if (multEstimator >= cut70) + return 65; + if (multEstimator >= cut80) + return 75; + if (multEstimator >= cut90) + return 85; + + return -1; + } + + void mcPredictionsCent(aod::McCollision const& collision, aod::McParticles const& particles) + { + (void)collision; + int posGen = 0, negGen = 0, posNegGen = 0, termNGen = 0, termPGen = 0, nchGen = 0; + auto cent = getCentrality(particles); + + if (cent < 0) { + return; + } + + for (auto const& mcpart : particles) { + + if (!mcpart.isPhysicalPrimary()) { + continue; + } int pid = mcpart.pdgCode(); auto sign = 0; auto* pd = pdgService->GetParticle(pid); if (pd != nullptr) { - sign = pd->Charge() / 3.; + sign = static_cast(pd->Charge() / 3.0); } - if (sign == 0) + if (sign == 0) { continue; + } if (std::abs(pid) != kElectron && std::abs(pid) != kMuonMinus && std::abs(pid) != kPiPlus && std::abs(pid) != kKPlus && - std::abs(pid) != kProton) + std::abs(pid) != kProton) { continue; + } - if (std::fabs(mcpart.eta()) >= etaCut) + if (std::fabs(mcpart.eta()) >= etaCut) { continue; - if ((mcpart.pt() <= ptMinCut) || (mcpart.pt() >= ptMaxCut)) + } + + if (mcpart.pt() <= ptMinCut || mcpart.pt() >= ptMaxCut) { continue; + } + + histogramRegistry.fill(HIST("gen/hPt"), mcpart.pt()); + histogramRegistry.fill(HIST("gen/cent_hPt"), cent, mcpart.pt()); + histogramRegistry.fill(HIST("gen/hEta"), mcpart.eta()); + histogramRegistry.fill(HIST("gen/cent_hEta"), cent, mcpart.eta()); + histogramRegistry.fill(HIST("gen/hSign"), sign); + histogramRegistry.fill(HIST("gen/hPt_eta"), mcpart.pt(), mcpart.eta()); + + nchGen += 1; + if (sign == 1) { + posGen += 1; + } + if (sign == -1) { + negGen += 1; + } + } + // LOGF(info, "cent = %d nch = %d", cent, nchGen); + termPGen = posGen * (posGen - 1); + termNGen = negGen * (negGen - 1); + posNegGen = posGen * negGen; + histogramRegistry.fill(HIST("gen/cent_pos"), cent, posGen); + histogramRegistry.fill(HIST("gen/cent_neg"), cent, negGen); + histogramRegistry.fill(HIST("gen/cent_termp"), cent, termPGen); + histogramRegistry.fill(HIST("gen/cent_termn"), cent, termNGen); + histogramRegistry.fill(HIST("gen/cent_pos_sq"), cent, posGen * posGen); + histogramRegistry.fill(HIST("gen/cent_neg_sq"), cent, negGen * negGen); + histogramRegistry.fill(HIST("gen/cent_posneg"), cent, posNegGen); + histogramRegistry.fill(HIST("gen/cent_nch"), cent, nchGen); + histogramRegistry.fill(HIST("gen/nch"), nchGen); + + float lRandom = fRndm->Rndm(); + int sampleIndex = static_cast(cfgNSubsample * lRandom); + + histogramRegistry.fill(HIST("subsample/gen/pos"), cent, sampleIndex, posGen); + histogramRegistry.fill(HIST("subsample/gen/neg"), cent, sampleIndex, negGen); + histogramRegistry.fill(HIST("subsample/gen/termp"), cent, sampleIndex, termPGen); + histogramRegistry.fill(HIST("subsample/gen/termn"), cent, sampleIndex, termNGen); + histogramRegistry.fill(HIST("subsample/gen/pos_sq"), cent, sampleIndex, posGen * posGen); + histogramRegistry.fill(HIST("subsample/gen/neg_sq"), cent, sampleIndex, negGen * negGen); + histogramRegistry.fill(HIST("subsample/gen/posneg"), cent, sampleIndex, posNegGen); + } // void + + void mcPredictionsDeltaEta(aod::McCollision const& collision, aod::McParticles const& particles, float deta1, float deta2) + { + (void)collision; + + float deltaEtaWidth = deta2 - deta1 + 1e-5f; + + int posGen = 0, negGen = 0, posNegGen = 0, termNGen = 0, termPGen = 0, nchGen = 0; + for (const auto& mcpart : particles) { + if (!mcpart.isPhysicalPrimary()) { + continue; + } + int pid = mcpart.pdgCode(); + auto sign = 0; + auto* pd = pdgService->GetParticle(pid); + if (pd != nullptr) { + sign = static_cast(pd->Charge() / 3.0); + } + if (sign == 0) { + continue; + } + if (std::abs(pid) != kElectron && + std::abs(pid) != kMuonMinus && + std::abs(pid) != kPiPlus && + std::abs(pid) != kKPlus && + std::abs(pid) != kProton) { + continue; + } + + if (std::fabs(mcpart.eta()) >= etaCut) { + continue; + } + if ((mcpart.pt() <= ptMinCut) || (mcpart.pt() >= ptMaxCut)) { + continue; + } double mcEta = mcpart.eta(); - if (mcEta < deta1 || mcEta > deta2) + if (mcEta < deta1 || mcEta > deta2) { continue; + } histogramRegistry.fill(HIST("gen/delta_eta_eta"), mcpart.eta()); @@ -1203,6 +1530,18 @@ struct NetchargeFluctuations { } PROCESS_SWITCH(NetchargeFluctuations, processMcRun2, "Process reconstructed", false); + + void processMcPrediction(aod::McCollision const& collision, aod::McParticles const& particles) + { + mcPredictionsCent(collision, particles); + for (int ii = 0; ii < deltaEta; ii++) { + float etaMin = -0.1f * (ii + 1); + float etaMax = 0.1f * (ii + 1); + mcPredictionsDeltaEta(collision, particles, etaMin, etaMax); + } + } + + PROCESS_SWITCH(NetchargeFluctuations, processMcPrediction, "Process Prediction", false); }; // struct diff --git a/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx b/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx index 2f2dc18d5bb..5705c659277 100644 --- a/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/partNumFluc.cxx @@ -70,10 +70,11 @@ #include #include -#define C_CS(cs) \ - [](std::index_sequence) { \ - static_assert(std::is_array_v>); \ - return ConstStr<(cs)[indices]...>{}; \ +#define C_CS(cs) \ + [](std::index_sequence) { \ + static_assert(std::is_array_v> && \ + std::same_as>, char>); \ + return ConstStr<(cs)[indices]...>{}; \ }(std::make_index_sequence{}) #define C_SV(sv) \ [](std::index_sequence) { \ @@ -95,22 +96,22 @@ using JoinedMcCollisions = soa::Join; namespace mini_mc_collision { -DECLARE_SOA_COLUMN(NMcParticlesChargedAll, nMcParticlesChargedAll, std::uint16_t); -DECLARE_SOA_COLUMN(NMcParticlesChargedIn, nMcParticlesChargedIn, std::uint16_t); +DECLARE_SOA_COLUMN(NMcParticlesP, nMcParticlesP, std::uint16_t); +DECLARE_SOA_COLUMN(NMcParticlesM, nMcParticlesM, std::uint16_t); } // namespace mini_mc_collision -DECLARE_SOA_TABLE(MiniMcCollisions, "AOD", "MINIMCCOLLISION", soa::Index<>, mini_mc_collision::NMcParticlesChargedAll, mini_mc_collision::NMcParticlesChargedIn); +DECLARE_SOA_TABLE(MiniMcCollisions, "AOD", "MINIMCCOLLISION", soa::Index<>, mini_mc_collision::NMcParticlesP, mini_mc_collision::NMcParticlesM); using MiniMcCollision = MiniMcCollisions::iterator; namespace mini_collision { DECLARE_SOA_COLUMN(Vz, vz, std::int8_t); DECLARE_SOA_COLUMN(Centrality, centrality, std::uint16_t); -DECLARE_SOA_COLUMN(NTracksAll, nTracksAll, std::uint16_t); -DECLARE_SOA_COLUMN(NTracksIn, nTracksIn, std::uint16_t); +DECLARE_SOA_COLUMN(NTracksP, nTracksP, std::uint16_t); +DECLARE_SOA_COLUMN(NTracksM, nTracksM, std::uint16_t); } // namespace mini_collision -DECLARE_SOA_TABLE(MiniCollisions, "AOD", "MINICOLLISION", soa::Index<>, mini_collision::Vz, mini_collision::Centrality, mini_collision::NTracksAll, mini_collision::NTracksIn); +DECLARE_SOA_TABLE(MiniCollisions, "AOD", "MINICOLLISION", soa::Index<>, mini_collision::Vz, mini_collision::Centrality, mini_collision::NTracksP, mini_collision::NTracksM); using MiniCollision = MiniCollisions::iterator; namespace mini_mc_particle @@ -141,16 +142,15 @@ inline constexpr std::int32_t NExponentKeys{MaxOrder * (MaxOrder + 1) / 2}; inline constexpr std::array, NExponentKeys> ExponentKeys{[] { std::array, NExponentKeys> result{}; std::int32_t index{}; - for (std::int8_t const& iExponent : std::views::iota(1, MaxOrder + 1)) { - for (std::int8_t const& jExponent : std::views::iota(1, iExponent + 1)) { - result[index++] = {iExponent, jExponent}; + for (std::int32_t const& iExponent : std::views::iota(1, MaxOrder + 1)) { + for (std::int32_t const& jExponent : std::views::iota(1, iExponent + 1)) { + result[index++] = {static_cast(iExponent), static_cast(jExponent)}; } } return result; }()}; inline constexpr std::int32_t NOrderKeys{[] { - std::array counts{}; - counts[0] = 1; + std::array counts{1}; for (std::array const& exponentKey /*o2-linter: disable=const-ref-in-for-loop*/ : ExponentKeys) { const std::int32_t weight{exponentKey[0]}; for (std::int32_t const& sum : std::views::iota(weight, MaxOrder + 1)) { @@ -176,7 +176,7 @@ inline constexpr std::array, NOrderKeys> } const std::int32_t weight{ExponentKeys[position][0]}; - for (std::int8_t power{}; sum + power * weight <= target; ++power) { + for (std::int32_t power{}; sum + power * weight <= target; ++power) { current[position] = power; self(self, position + 1, sum + power * weight, target); } @@ -236,11 +236,13 @@ template requires IsValidEnum struct EnumInfo; -enum class NameKind { kDefault = 0, - kLower, - kDisplay, - kDisplayLower, - kN }; +enum class NameKind { + kDefault = 0, + kLower, + kDisplay, + kDisplayLower, + kN +}; template requires IsValidEnum inline constexpr std::string_view getName(const std::int32_t index) @@ -548,19 +550,15 @@ struct PartNumFluc { 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()); } - aod::mini_mc_collision::NMcParticlesChargedAll::type nMcParticlesChargedAll{}; - aod::mini_mc_collision::NMcParticlesChargedIn::type nMcParticlesChargedIn{}; - aod::mini_collision::NTracksAll::type nTracksAll{}; - aod::mini_collision::NTracksIn::type nTracksIn{}; + std::array> nMcParticles{}; + std::array> nTracks{}; std::vector signedEfficienciesMcParticle{[] {std::vector v{}; v.reserve(256); return v; }()}; std::vector signedEfficienciesTrack{[] {std::vector v{}; v.reserve(256); return v; }()}; void clear() { - nMcParticlesChargedAll = {}; - nMcParticlesChargedIn = {}; - nTracksAll = {}; - nTracksIn = {}; + nMcParticles = {}; + nTracks = {}; signedEfficienciesMcParticle.clear(); signedEfficienciesTrack.clear(); } @@ -580,20 +578,21 @@ 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", {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> cfgFlagsQaAcceptance{"cfgFlagsQaAcceptance", {std::array>{false, false, false, false}.data(), NEs, getDisplayNames()}, "Acceptance QA flags"}; + Configurable> cfgFlagsQaPhi{"cfgFlagsQaPhi", {std::array>{false, false, false, false}.data(), NEs, getDisplayNames()}, "Phi QA flags"}; + Configurable> cfgFlagsQaPid{"cfgFlagsQaPid", {std::array>{false, false, false, false}.data(), NEs, getDisplayNames()}, "PID QA flags"}; Configurable cfgFlagQaMc{"cfgFlagQaMc", false, "MC QA 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"}; + Configurable> cfgFlagsCalculationYield{"cfgFlagsCalculationYield", {std::array>{false, false, false}.data(), NEs, getDisplayNames()}, "Yield calculation flags"}; + Configurable> cfgFlagsCalculationPurity{"cfgFlagsCalculationPurity", {std::array>{false, false, false}.data(), NEs, getDisplayNames()}, "Purity calculation flags"}; + Configurable> cfgFlagsCalculationFractionPrimary{"cfgFlagsCalculationFractionPrimary", {std::array>{false, false, false}.data(), NEs, getDisplayNames()}, "Primary fraction calculation flags"}; + Configurable> cfgFlagsCalculationFluctuation{"cfgFlagsCalculationFluctuation", {std::array>{false, false, false}.data(), NEs, getDisplayNames()}, "Fluctuation calculation flags"}; } groupAnalysis; struct : ConfigurableGroup { 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> cfgFlagsRct{"cfgFlagsRct", {std::array{false, true, true}.data(), 3, {"ZDC", "Acceptance", "Table"}}, "RCT flags"}; 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"}; @@ -601,7 +600,7 @@ struct PartNumFluc { 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"}; + ConfigurableAxis cfgAxisCentrality{"cfgAxisCentrality", {18, 0., 90.}, "Centrality axis in fluctuation calculation"}; Configurable cfgNSubgroups{"cfgNSubgroups", 20, "Number of subgroups in fluctuation calculation"}; } groupEvent; @@ -615,14 +614,14 @@ 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> cfgCutMaxAbsNSigmaDca{"cfgCutMaxAbsNSigmaDca", {std::array>{2.5, 2.5}.data(), NEs, getDisplayNames()}, "Maximum absolute nSigma of DCA (cm)"}; + Configurable> cfgCutsMaxAbsNSigmaDca{"cfgCutsMaxAbsNSigmaDca", {std::array>{2.5, 2.5}.data(), NEs, getDisplayNames()}, "Maximum absolute nSigma values 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> 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> cfgThresholdsPtTofPid{"cfgThresholdsPtTofPid", {std::array>{0.5, 0.5, 0.8}.data(), NEs, getDisplayNames()}, "pT (GeV/c) thresholds for TOF PID"}; + Configurable> cfgFlagsRecalibrationNSigmaPid{"cfgFlagsRecalibrationNSigmaPid", {std::array>{false, false, false}.data(), NEs, getDisplayNames()}, "nSigma PID recalibration flags"}; Configurable cfgFlagRejectionOthers{"cfgFlagRejectionOthers", false, "Other particle species rejection flag"}; - Configurable cfgCutMaxAbsNSigmaPid{"cfgCutMaxAbsNSigmaPid", 2., "Maximum absolute nSigma for PID"}; + Configurable> cfgCutsMaxAbsNSigmaPid{"cfgCutsMaxAbsNSigmaPid", {std::array>{2., 2., 2.}.data(), NEs, getDisplayNames()}, "Maximum absolute nSigma values for PID"}; Configurable cfgFlagMcParticlePhysicalPrimary{"cfgFlagMcParticlePhysicalPrimary", true, "Flag of requiring physical primary MC particle"}; Configurable cfgFlagMcParticleMomentum{"cfgFlagMcParticleMomentum", true, "Flag of using momentum of MC particle"}; } groupTrack; @@ -648,7 +647,7 @@ struct PartNumFluc { Service ccdb; Filter filterCollision = (aod::evsel::sel8 == true); - Filter filterTrack = requireQualityTracksInFilter(); + Filter filterTrack = (requireQualityTracksInFilter() && requireTrackCutInFilter(TrackSelectionFlags::kGoldenChi2)); Filter filterMcCollision = (aod::mccollisionprop::numRecoCollision > 0); Preslice presliceTracksPerCollision{aod::track::collisionId}; @@ -672,7 +671,7 @@ struct PartNumFluc { } if (!groupEvent.cfgLabelFlagsRct.value.empty()) { - rctFlagsChecker.init(groupEvent.cfgLabelFlagsRct.value, false, true, true); + rctFlagsChecker.init(groupEvent.cfgLabelFlagsRct.value, groupEvent.cfgFlagsRct.value.get("ZDC"), groupEvent.cfgFlagsRct.value.get("Acceptance"), groupEvent.cfgFlagsRct.value.get("Table")); } ccdb->setURL(groupCcdb.cfgCcdbUrl.value); @@ -684,7 +683,7 @@ struct PartNumFluc { } const TList* const ccdbObject{ccdb->get(groupCcdb.cfgCcdbPath.value)}; if (!ccdbObject || ccdbObject->IsA() != TList::Class()) { - LOG(fatal) << "Invalid ccdb_object!"; + LOG(fatal) << "Invalid CCDB object!"; } holderCcdb.clear(); @@ -739,10 +738,19 @@ struct PartNumFluc { } if (groupEvent.cfgLabelFlagsRct.value.empty()) { - LOG(info) << "No RCT flags enabled."; + LOG(info) << "No RCT flags label enabled."; } else { LOG(info) << "Enabling RCT flags label: " << groupEvent.cfgLabelFlagsRct.value; } + if (groupEvent.cfgFlagsRct.value.get("ZDC")) { + LOG(info) << "Enabling RCT flag: ZDC"; + } + if (!groupEvent.cfgLabelFlagsRct.value.empty() && groupEvent.cfgFlagsRct.value.get("Acceptance")) { + LOG(info) << "Enabling RCT flag: acceptance"; + } + if (groupEvent.cfgFlagsRct.value.get("Table")) { + LOG(info) << "Enabling RCT flag: table"; + } if ((groupEvent.cfgBitsSelectionEvent.value & ((std::uint64_t{1} << aod::evsel::EventSelectionFlags::kNsel) - 1)) == 0) { LOG(info) << "No event selection bit enabled."; @@ -766,14 +774,14 @@ struct PartNumFluc { break; } - const auto readListRunGroup = [&](const std::int32_t runGroupIndex) -> const TList* { + const auto readListRunGroup{[&](const std::int32_t runGroupIndex) -> const TList* { 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; - }; + }}; if (groupTrack.cfgFlagRecalibrationDca.value) { LOG(info) << "Enabling DCA recalibration."; @@ -797,7 +805,7 @@ struct PartNumFluc { } for (std::int32_t const& iParticleSpecies : std::views::iota(0, NEs)) { - if (!groupTrack.cfgFlagRecalibrationNSigmaPid.value.get(iParticleSpecies)) { + if (!groupTrack.cfgFlagsRecalibrationNSigmaPid.value.get(iParticleSpecies)) { continue; } @@ -894,11 +902,8 @@ struct PartNumFluc { if (groupAnalysis.cfgFlagQaCentrality.value) { LOG(info) << "Enabling centrality QA."; - const AxisSpec asCentrality(20, 0., 100., "Centrality (%)"); - - hrQaCentrality.add("QaCentrality/hCentralityFt0a", "", {HistType::kTHnSparseF, {asCentrality, {12000, 0., 12000., "FT0A Multiplicity"}}}); - hrQaCentrality.add("QaCentrality/hCentralityFt0c", "", {HistType::kTHnSparseF, {asCentrality, {3000, 0., 3000., "FT0C Multiplicity"}}}); - hrQaCentrality.add("QaCentrality/hCentralityFt0m", "", {HistType::kTHnSparseF, {asCentrality, {15000, 0., 15000., "FT0M Multiplicity"}}}); + hrQaCentrality.add("QaCentrality/hCentralitySelection", "", {HistType::kTHnSparseD, {{100, 0., 100., "Centrality (%)"}, {10 + aod::evsel::EventSelectionFlags::kNsel, -0.5, 9.5 + static_cast(aod::evsel::EventSelectionFlags::kNsel), "Selection"}}}); + hrQaCentrality.add("QaCentrality/hCentralityMultiplicity", "", {HistType::kTHnSparseD, {{100, 0., 100., "Centrality (%)"}, {200, -0.5, 199.5, "Multiplicity"}}}); } if (groupAnalysis.cfgFlagQaTrack.value) { @@ -919,13 +924,14 @@ struct PartNumFluc { if (groupAnalysis.cfgFlagQaDca.value) { LOG(info) << "Enabling DCA QA."; - const AxisSpec asPt(200, 0., 2., "#it{p}_{T} (GeV/#it{c})"); + const AxisSpec asPt(40, 0., 2., "#it{p}_{T} (GeV/#it{c})"); + const HistogramConfigSpec hcsQaDcaProfile(HistType::kTProfile3D, {asPt, {24, -1.2, 1.2, "#it{#eta}"}, {constants::math::NSectors, 0., constants::math::TwoPI, "#it{#varphi} (rad)"}}); 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}}}})) { + {{"hPtDcaXy", "", {HistType::kTHnSparseD, {asPt, {250, -0.25, 0.25, "DCA_{#it{xy}} (cm)"}}}}, + {"pPtEtaPhiIuDcaXy", ";;#LTDCA_{#it{xy}}#GT (cm)", hcsQaDcaProfile}, + {"hPtDcaZ", "", {HistType::kTHnSparseD, {asPt, {250, -0.5, 0.5, "DCA_{#it{z}} (cm)"}}}}, + {"pPtEtaPhiIuDcaZ", ";;#LTDCA_{#it{z}}#GT (cm)", hcsQaDcaProfile}})) { 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); } @@ -933,7 +939,7 @@ struct PartNumFluc { } for (std::int32_t const& iParticleSpeciesAll : std::views::iota(0, NEs)) { - if (!groupAnalysis.cfgFlagQaAcceptance.value.get(iParticleSpeciesAll)) { + if (!groupAnalysis.cfgFlagsQaAcceptance.value.get(iParticleSpeciesAll)) { continue; } @@ -947,13 +953,13 @@ struct PartNumFluc { } for (std::int32_t const& iParticleSpeciesAll : std::views::iota(0, NEs)) { - if (!groupAnalysis.cfgFlagQaPhi.value.get(iParticleSpeciesAll)) { + if (!groupAnalysis.cfgFlagsQaPhi.value.get(iParticleSpeciesAll)) { continue; } LOG(info) << "Enabling " << getName(iParticleSpeciesAll) << " 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)"}}); + 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})"}, {24, -1.2, 1.2, "#it{#eta}"}, {360, 0., constants::math::TwoPI, "#it{#varphi} (rad)"}}); for (std::int32_t const& iPidStrategy : std::views::iota(0, NEs)) { for (std::int32_t const& iChargeSpecies : std::views::iota(0, NEs)) { @@ -964,7 +970,7 @@ struct PartNumFluc { } for (std::int32_t const& iParticleSpeciesAll : std::views::iota(0, NEs)) { - if (!groupAnalysis.cfgFlagQaPid.value.get(iParticleSpeciesAll)) { + if (!groupAnalysis.cfgFlagsQaPid.value.get(iParticleSpeciesAll)) { continue; } @@ -1011,14 +1017,14 @@ struct PartNumFluc { const AxisSpec asCentrality(20, 0., 100., "Centrality (%)"); - 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}"}}}); + hrQaMc.add("QaMc/hCentralityVzMcDeltaVz", "", {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}}^{Gen} (cm)"}, {200, -0.2, 0.2, "#it{V}_{#it{z}}^{Rec}#minus#it{V}_{#it{z}}^{Gen} (cm)"}}}); + hrQaMc.add("QaMc/hCentralityPtMcEtaMcDeltaPt", "", {HistType::kTHnSparseF, {asCentrality, {200, 0., 2., "#it{p}_{T}^{Gen} (GeV/#it{c})"}, {24, -1.2, 1.2, "#it{#eta}_{Gen}"}, {320, -0.8, 0.8, "#it{p}_{T}^{Rec}#minus#it{p}_{T}^{Gen} (GeV/#it{c})"}}}); + hrQaMc.add("QaMc/hCentralityPtMcEtaMcDeltaEta", "", {HistType::kTHnSparseF, {asCentrality, {20, 0., 2., "#it{p}_{T}^{Gen} (GeV/#it{c})"}, {240, -1.2, 1.2, "#it{#eta}_{Gen}"}, {160, -0.4, 0.4, "#it{#eta}_{Rec}#minus#it{#eta}_{Gen}"}}}); } } for (std::int32_t const& iParticleSpecies : std::views::iota(0, NEs)) { - if (!groupAnalysis.cfgFlagCalculationYield.value.get(iParticleSpecies)) { + if (!groupAnalysis.cfgFlagsCalculationYield.value.get(iParticleSpecies)) { continue; } LOG(info) << "Enabling " << getName(iParticleSpecies) << " yield calculation."; @@ -1027,12 +1033,15 @@ struct PartNumFluc { 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); + hrCalculationYield.add(Form("CalculationYield/hVzCentralityPtMcEtaMc_mc%s%s", getName(iParticleSpecies).data(), getName(iChargeSpecies).data()), "", 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); + if (groupTrack.cfgFlagMcParticleMomentum.value) { + hrCalculationYield.add(Form("CalculationYield/hVzCentralityPtMcEtaMc_mc%s%s%s", getName(iPidStrategy).data(), getName(iParticleSpecies).data(), getName(iChargeSpecies).data()), "", hcsCalculationYield); + } else { + hrCalculationYield.add(Form("CalculationYield/hVzCentralityPtEta_mc%s%s%s", getName(iPidStrategy).data(), getName(iParticleSpecies).data(), getName(iChargeSpecies).data()), "", hcsCalculationYield); + } } } } else { @@ -1046,7 +1055,7 @@ struct PartNumFluc { if (doprocessMc.value) { for (std::int32_t const& iParticleSpecies : std::views::iota(0, NEs)) { - if (!groupAnalysis.cfgFlagCalculationPurity.value.get(iParticleSpecies)) { + if (!groupAnalysis.cfgFlagsCalculationPurity.value.get(iParticleSpecies)) { continue; } @@ -1064,7 +1073,7 @@ struct PartNumFluc { if (doprocessMc.value) { for (std::int32_t const& iParticleSpecies : std::views::iota(0, NEs)) { - if (!groupAnalysis.cfgFlagCalculationFractionPrimary.value.get(iParticleSpecies)) { + if (!groupAnalysis.cfgFlagsCalculationFractionPrimary.value.get(iParticleSpecies)) { continue; } @@ -1080,14 +1089,14 @@ struct PartNumFluc { } } - if (nEnabled(groupAnalysis.cfgFlagCalculationFluctuation) > 1) { - LOG(fatal) << "Invalid " << groupAnalysis.cfgFlagCalculationFluctuation.name << "!"; + if (nEnabled(groupAnalysis.cfgFlagsCalculationFluctuation) > 1) { + LOG(fatal) << "Invalid " << groupAnalysis.cfgFlagsCalculationFluctuation.name << "!"; } - if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation) && groupEvent.cfgNSubgroups.value <= 0) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationFluctuation) && 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)) { + if (!groupAnalysis.cfgFlagsCalculationFluctuation.value.get(iParticleNumber)) { continue; } @@ -1117,7 +1126,7 @@ struct PartNumFluc { } 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)))) { + if (!groupAnalysis.cfgFlagsCalculationFluctuation.value.get(toI(ParticleNumber::kCharge)) && !(iParticleSpecies == toI(ParticleSpecies::kKaon) && groupAnalysis.cfgFlagsCalculationFluctuation.value.get(toI(ParticleNumber::kKaon))) && !(iParticleSpecies == toI(ParticleSpecies::kProton) && groupAnalysis.cfgFlagsCalculationFluctuation.value.get(toI(ParticleNumber::kProton)))) { continue; } @@ -1150,15 +1159,15 @@ struct PartNumFluc { requires IsValid double getShiftNSigmaPid() { - if (!groupTrack.cfgFlagRecalibrationNSigmaPid.value.get(toI(particleSpecies))) { + if (!groupTrack.cfgFlagsRecalibrationNSigmaPid.value.get(toI(particleSpecies))) { return 0.; } - static const auto clampInAxis = [](const double value, const TAxis* const axis) { + 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())}; 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.; @@ -1188,17 +1197,17 @@ struct PartNumFluc { } 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)) { + if (!(std::abs(holderTrack.nSigmaPid[toI(PidStrategyAll::kTpc)][ParticleSpeciesIndex]) < groupTrack.cfgCutsMaxAbsNSigmaPid.value.get(ParticleSpeciesIndex))) { return false; } - if (!(std::abs(holderTrack.nSigmaPid[toI(PidStrategyAll::kTof)][ParticleSpeciesIndex]) < groupTrack.cfgCutMaxAbsNSigmaPid.value)) { + if (!(std::abs(holderTrack.nSigmaPid[toI(PidStrategyAll::kTof)][ParticleSpeciesIndex]) < groupTrack.cfgCutsMaxAbsNSigmaPid.value.get(ParticleSpeciesIndex))) { return false; } 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(holderTrack.nSigmaPid[toI(pidStrategyAll)][ParticleSpeciesIndex]) < groupTrack.cfgCutMaxAbsNSigmaPid.value)) { + if (!(std::abs(holderTrack.nSigmaPid[toI(pidStrategyAll)][ParticleSpeciesIndex]) < groupTrack.cfgCutsMaxAbsNSigmaPid.value.get(ParticleSpeciesIndex))) { 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])))) { @@ -1245,7 +1254,7 @@ struct PartNumFluc { { if (!groupTrack.cfgFlagRecalibrationDca.value) { for (std::int32_t const& iDcaAxis : std::views::iota(0, NEs)) { - if (!(std::abs(holderTrack.dca[iDcaAxis]) < groupTrack.cfgCutMaxAbsNSigmaDca.value.get(iDcaAxis))) { + if (!(std::abs(holderTrack.dca[iDcaAxis]) < groupTrack.cfgCutsMaxAbsNSigmaDca.value.get(iDcaAxis))) { return false; } } @@ -1256,7 +1265,7 @@ struct PartNumFluc { 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))) { + 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.cfgCutsMaxAbsNSigmaDca.value.get(iDcaAxis) * fPtDcaGroup[toI(DcaKind::kSigma)][iDcaAxis][chargeSpeciesIndex]->Eval(holderTrack.pt))) { return false; } } @@ -1309,17 +1318,18 @@ struct PartNumFluc { requires IsValid void fillQaRunByTrackByChargeSpecies(const T& track) { - const auto fill = [&](const auto& name, const auto value) { + 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) + }}; + 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()); @@ -1351,9 +1361,9 @@ struct PartNumFluc { requires IsValid void fillQaRunByEventByChargeSpecies() { - const auto fill = [&](const auto& name, const auto value) { + 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)]); @@ -1370,9 +1380,9 @@ struct PartNumFluc { requires IsValid void fillQaTrackByChargeSpecies(const T& track) { - const auto fill = [&](const auto& name, const auto... positionAndWeight) { + 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()); @@ -1385,12 +1395,13 @@ struct PartNumFluc { 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) + 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/pPtEtaPhiIuDca") + C_SV(getName(dcaAxis)) + C_CS("_") + C_SV(getName(chargeSpecies)), holderTrack.pt, holderTrack.eta, holderTrack.phiIu, holderTrack.dca[toI(dcaAxis)]); + }}; // NOLINT(readability/braces) fillByDcaAxis.template operator()(); fillByDcaAxis.template operator()(); @@ -1400,24 +1411,26 @@ struct PartNumFluc { requires IsValid void fillQaAcceptancebyParticleSpeciesAll(const T& track) { - if (!groupAnalysis.cfgFlagQaAcceptance.value.get(toI(particleSpeciesAll)) || holderTrack.sign == 0) { + if (!groupAnalysis.cfgFlagsQaAcceptance.value.get(toI(particleSpeciesAll)) || holderTrack.sign == 0) { 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) + 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) + fillByPidStrategy.template operator()(); + fillByPidStrategy.template operator()(); + }}; // NOLINT(readability/braces) if constexpr (particleSpeciesAll == ParticleSpeciesAll::kAll) { if (holderTrack.sign > 0) { @@ -1438,7 +1451,7 @@ struct PartNumFluc { requires IsValid && (dataMode != DataMode::kMcMcParticle) void fillQaPhiByParticleSpeciesAll() { - if (!groupAnalysis.cfgFlagQaPhi.value.get(toI(particleSpeciesAll))) { + if (!groupAnalysis.cfgFlagsQaPhi.value.get(toI(particleSpeciesAll))) { return; } @@ -1447,28 +1460,30 @@ struct PartNumFluc { return; } - const auto fillByChargeSpecies = [&] - requires IsValid - () { - const auto fillByPidStrategy = [&] - requires IsValid + const auto fillByChargeSpecies{ + [&] + requires IsValid () { - if constexpr (dataMode == DataMode::kMcTrack) { - if (isPid() && isPid(pidStrategy), particleSpeciesAll>(false)) { - 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); - hrQaPhi.fill(C_CS("QaPhi/hCentralityPtEtaPhiIu_mc") + C_SV(getName(pidStrategy)) + C_SV(getName(particleSpeciesAll)) + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phiIu); - } - } 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); - hrQaPhi.fill(C_CS("QaPhi/hCentralityPtEtaPhiIu_") + C_SV(getName(pidStrategy)) + C_SV(getName(particleSpeciesAll)) + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phiIu); - } - } - }; // NOLINT(readability/braces) + const auto fillByPidStrategy{ + [&] + requires IsValid + () { + if constexpr (dataMode == DataMode::kMcTrack) { + if (isPid() && isPid(pidStrategy), particleSpeciesAll>(false)) { + 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); + hrQaPhi.fill(C_CS("QaPhi/hCentralityPtEtaPhiIu_mc") + C_SV(getName(pidStrategy)) + C_SV(getName(particleSpeciesAll)) + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phiIu); + } + } 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); + hrQaPhi.fill(C_CS("QaPhi/hCentralityPtEtaPhiIu_") + C_SV(getName(pidStrategy)) + C_SV(getName(particleSpeciesAll)) + C_SV(getName(chargeSpecies)), holderEvent.centrality, holderTrack.pt, holderTrack.eta, holderTrack.phiIu); + } + } + }}; // NOLINT(readability/braces) - fillByPidStrategy.template operator()(); - fillByPidStrategy.template operator()(); - }; // NOLINT(readability/braces) + fillByPidStrategy.template operator()(); + fillByPidStrategy.template operator()(); + }}; // NOLINT(readability/braces) if (chargeSign > 0) { fillByChargeSpecies.template operator()(); @@ -1481,7 +1496,7 @@ struct PartNumFluc { requires IsValid && (dataMode != DataMode::kMcMcParticle) void fillQaPidByParticleSpeciesAll(const T& track) { - if (!groupAnalysis.cfgFlagQaPid.value.get(toI(particleSpeciesAll)) || holderTrack.sign == 0) { + if (!groupAnalysis.cfgFlagsQaPid.value.get(toI(particleSpeciesAll)) || holderTrack.sign == 0) { return; } @@ -1493,25 +1508,26 @@ struct PartNumFluc { 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)]); + 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)]); } - 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) + }}; // NOLINT(readability/braces) if (holderTrack.sign > 0) { fillByChargeSpecies.template operator()(); @@ -1525,7 +1541,7 @@ struct PartNumFluc { requires IsValid void fillCalculationYieldByParticleSpecies() { - if (!groupAnalysis.cfgFlagCalculationYield.value.get(toI(particleSpecies))) { + if (!groupAnalysis.cfgFlagsCalculationYield.value.get(toI(particleSpecies))) { return; } @@ -1534,33 +1550,38 @@ struct PartNumFluc { 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); - } + const auto fillByChargeSpecies{ + [&] + requires IsValid + () { + if constexpr (dataMode == DataMode::kMcMcParticle) { + if (isPid(particleSpecies), chargeSpecies>()) { + hrCalculationYield.fill(C_CS("CalculationYield/hVzCentralityPtMcEtaMc_mc") + C_SV(getName(particleSpecies)) + C_SV(getName(chargeSpecies)), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); } - }; // NOLINT(readability/braces) + } else { + const auto fillByPidStrategy{ + [&] + requires IsValid + () { + if constexpr (dataMode == DataMode::kMcTrack) { + if (isPid(particleSpecies), chargeSpecies>() && isPid(pidStrategy), getValue(particleSpecies)>(groupTrack.cfgFlagRejectionOthers.value)) { + if (groupTrack.cfgFlagMcParticleMomentum.value) { + hrCalculationYield.fill(C_CS("CalculationYield/hVzCentralityPtMcEtaMc_mc") + C_SV(getName(pidStrategy)) + C_SV(getName(particleSpecies)) + C_SV(getName(chargeSpecies)), holderEvent.vz, holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta); + } else { + 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) + fillByPidStrategy.template operator()(); + fillByPidStrategy.template operator()(); + } + }}; // NOLINT(readability/braces) if (chargeSign > 0) { fillByChargeSpecies.template operator()(); @@ -1573,24 +1594,26 @@ struct PartNumFluc { requires IsValid void fillCalculationPurityByParticleSpecies() { - if (!groupAnalysis.cfgFlagCalculationPurity.value.get(toI(particleSpecies)) || holderTrack.sign == 0) { + if (!groupAnalysis.cfgFlagsCalculationPurity.value.get(toI(particleSpecies)) || holderTrack.sign == 0) { return; } - const auto fillByChargeSpecies = [&] - requires IsValid - () { - const auto fillByPidStrategy = [&] - requires IsValid + const auto fillByChargeSpecies{ + [&] + 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) + 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) + fillByPidStrategy.template operator()(); + fillByPidStrategy.template operator()(); + }}; // NOLINT(readability/braces) if (holderTrack.sign > 0) { fillByChargeSpecies.template operator()(); @@ -1603,24 +1626,26 @@ struct PartNumFluc { requires IsValid void fillCalculationFractionPrimaryByParticleSpecies(const MP& mcParticle) { - if (!groupAnalysis.cfgFlagCalculationFractionPrimary.value.get(toI(particleSpecies)) || holderTrack.sign == 0) { + if (!groupAnalysis.cfgFlagsCalculationFractionPrimary.value.get(toI(particleSpecies)) || holderTrack.sign == 0) { return; } - const auto fillByChargeSpecies = [&] - requires IsValid - () { - const auto fillByPidStrategy = [&] - requires IsValid + const auto fillByChargeSpecies{ + [&] + 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) + 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) + fillByPidStrategy.template operator()(); + fillByPidStrategy.template operator()(); + }}; // NOLINT(readability/braces) if (holderTrack.sign > 0) { fillByChargeSpecies.template operator()(); @@ -1632,7 +1657,7 @@ struct PartNumFluc { void initCalculationFluctuation() { for (std::int32_t const& iParticleNumber : std::views::iota(0, NEs)) { - if (groupAnalysis.cfgFlagCalculationFluctuation.value.get(iParticleNumber)) { + if (groupAnalysis.cfgFlagsCalculationFluctuation.value.get(iParticleNumber)) { for (std::int32_t const& iChargeNumber : std::views::iota(0, NEs)) { fluctuationCalculatorTrack[iParticleNumber][iChargeNumber]->init(); } @@ -1644,7 +1669,7 @@ struct PartNumFluc { requires IsValid void calculateFluctuationByParticleNumber() { - if (!groupAnalysis.cfgFlagCalculationFluctuation.value.get(toI(particleNumber))) { + if (!groupAnalysis.cfgFlagsCalculationFluctuation.value.get(toI(particleNumber))) { return; } @@ -1659,61 +1684,64 @@ struct PartNumFluc { } if constexpr (dataMode == DataMode::kMcMcParticle) { - ++holderDerivedData.nMcParticlesChargedIn; + ++holderDerivedData.nMcParticles[toI(chargeSign > 0 ? ChargeSpecies::kPlus : ChargeSpecies::kMinus)]; } else { - ++holderDerivedData.nTracksIn; + ++holderDerivedData.nTracks[toI(chargeSign > 0 ? ChargeSpecies::kPlus : ChargeSpecies::kMinus)]; } - 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 + const auto calculateByParticleSpecies{ + [&] + requires IsValid && (particleNumber == ParticleNumber::kCharge || (particleNumber == ParticleNumber::kKaon && particleSpecies == ParticleSpecies::kKaon) || (particleNumber == ParticleNumber::kProton && particleSpecies == ParticleSpecies::kProton)) () { - if constexpr (dataMode != DataMode::kRawTrack) { - if (!isPid(particleSpecies), chargeSpecies>()) { - return; - } - } + 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 bool doUsingTofPid{(doUsingMcParticleMomentum ? holderMcParticle.pt : holderTrack.pt) >= groupTrack.cfgThresholdsPtTofPid.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(); - } - holderDerivedData.signedEfficienciesMcParticle.push_back(HolderDerivedData::convertRound(std::copysign(std::numeric_limits::max(), chargeSign) * efficiency)); + 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(); + } + holderDerivedData.signedEfficienciesMcParticle.push_back(HolderDerivedData::convertRound(std::copysign(std::numeric_limits::max(), chargeSign) * efficiency)); + } else { + ++holderEvent.numbers[toI(particleNumber)][toI(chargeSpecies)]; + fill(); + holderDerivedData.signedEfficienciesTrack.push_back(HolderDerivedData::convertRound(std::copysign(std::numeric_limits::max(), chargeSign) * efficiency)); + } + }}; // NOLINT(readability/braces) + + if (chargeSign > 0) { + calculateByChargeSpecies.template operator()(); } else { - ++holderEvent.numbers[toI(particleNumber)][toI(chargeSpecies)]; - fill(); - holderDerivedData.signedEfficienciesTrack.push_back(HolderDerivedData::convertRound(std::copysign(std::numeric_limits::max(), chargeSign) * efficiency)); + calculateByChargeSpecies.template operator()(); } - }; // NOLINT(readability/braces) - - if (chargeSign > 0) { - calculateByChargeSpecies.template operator()(); - } else { - calculateByChargeSpecies.template operator()(); - } - }; // NOLINT(readability/braces) + }}; // NOLINT(readability/braces) if constexpr (particleNumber == ParticleNumber::kKaon) { calculateByParticleSpecies.template operator()(); @@ -1730,7 +1758,7 @@ struct PartNumFluc { requires IsValid void fillCalculationFluctuationByParticleNumber() { - if (!groupAnalysis.cfgFlagCalculationFluctuation.value.get(toI(particleNumber))) { + if (!groupAnalysis.cfgFlagsCalculationFluctuation.value.get(toI(particleNumber))) { return; } @@ -1741,17 +1769,18 @@ struct PartNumFluc { 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& iOrderKey : std::views::iota(0, fluctuation_calculator_base::NOrderKeys)) { - 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, iOrderKey, fluctuationCalculatorTrack[toI(particleNumber)][toI(chargeNumber)]->getProduct(iOrderKey)); - } else { - hrCalculationFluctuation.fill(C_CS("CalculationFluctuation/hFluctuationCalculator") + C_SV(getName(particleNumber)) + C_SV(getName(chargeNumber)), holderEvent.centrality, holderEvent.subgroupIndex, iOrderKey, fluctuationCalculatorTrack[toI(particleNumber)][toI(chargeNumber)]->getProduct(iOrderKey)); + const auto fillByChargeNumber{ + [&] + requires IsValid + () { + for (std::int32_t const& iOrderKey : std::views::iota(0, fluctuation_calculator_base::NOrderKeys)) { + 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, iOrderKey, fluctuationCalculatorTrack[toI(particleNumber)][toI(chargeNumber)]->getProduct(iOrderKey)); + } else { + hrCalculationFluctuation.fill(C_CS("CalculationFluctuation/hFluctuationCalculator") + C_SV(getName(particleNumber)) + C_SV(getName(chargeNumber)), holderEvent.centrality, holderEvent.subgroupIndex, iOrderKey, fluctuationCalculatorTrack[toI(particleNumber)][toI(chargeNumber)]->getProduct(iOrderKey)); + } } - } - }; // NOLINT(readability/braces) + }}; // NOLINT(readability/braces) fillByChargeNumber.template operator()(); fillByChargeNumber.template operator()(); @@ -1771,9 +1800,9 @@ struct PartNumFluc { holderTrack.eta = track.eta(); holderTrack.phi = track.phi(); { - const std::int64_t localIndexTrackIu = track.globalIndex() - tracksIu.offset(); - if (0 <= localIndexTrackIu && localIndexTrackIu < static_cast(tracksIu.size())) { - const auto& trackIu = tracksIu.iteratorAt(localIndexTrackIu); + const std::int64_t localIndexTrackIu{track.globalIndex() - static_cast(tracksIu.offset())}; + if (0 <= localIndexTrackIu && localIndexTrackIu < tracksIu.size()) { + const auto& trackIu{tracksIu.iteratorAt(localIndexTrackIu)}; if (track.globalIndex() == trackIu.globalIndex()) { holderTrack.phiIu = trackIu.phi(); } else { @@ -1853,7 +1882,7 @@ struct PartNumFluc { } if constexpr (!doInitingEvent) { - if (isEnabled(groupAnalysis.cfgFlagQaAcceptance) && (holderTrack.eta * holderEvent.vz > 0. && std::abs(holderEvent.vz) > groupEvent.cfgCutMaxAbsVz.value - 1.)) { + if (isEnabled(groupAnalysis.cfgFlagsQaAcceptance) && (holderTrack.eta * holderEvent.vz > 0. && std::abs(holderEvent.vz) > groupEvent.cfgCutMaxAbsVz.value - 1.)) { fillQaAcceptancebyParticleSpeciesAll(track); fillQaAcceptancebyParticleSpeciesAll(track); fillQaAcceptancebyParticleSpeciesAll(track); @@ -1907,9 +1936,15 @@ struct PartNumFluc { } hrCounter.fill(C_CS("hNEvents"), 0.); + if (groupAnalysis.cfgFlagQaCentrality.value) { + hrQaCentrality.fill(C_CS("QaCentrality/hCentralitySelection"), holderEvent.centrality, 0.); + } if (!collision.has_foundBC()) { hrCounter.fill(C_CS("hNEvents"), 2.); + if (groupAnalysis.cfgFlagQaCentrality.value) { + hrQaCentrality.fill(C_CS("QaCentrality/hCentralitySelection"), holderEvent.centrality, 2.); + } return false; } @@ -1918,6 +1953,9 @@ struct PartNumFluc { if (holderCcdb.runNumbersIndicesGroupIndices.find(holderEvent.runNumber) == holderCcdb.runNumbersIndicesGroupIndices.end()) { hrCounter.fill(C_CS("hNEvents"), 2.); + if (groupAnalysis.cfgFlagQaCentrality.value) { + hrQaCentrality.fill(C_CS("QaCentrality/hCentralitySelection"), holderEvent.centrality, 2.); + } return false; } @@ -1925,11 +1963,17 @@ struct PartNumFluc { if (holderEvent.runGroupIndex == 0 || (groupEvent.cfgFlagRejectionRunBad.value && holderEvent.runGroupIndex < 0)) { hrCounter.fill(C_CS("hNEvents"), 2.); + if (groupAnalysis.cfgFlagQaCentrality.value) { + hrQaCentrality.fill(C_CS("QaCentrality/hCentralitySelection"), holderEvent.centrality, 2.); + } return false; } if (!groupEvent.cfgLabelFlagsRct.value.empty() && !rctFlagsChecker.checkTable(collision)) { hrCounter.fill(C_CS("hNEvents"), 3.); + if (groupAnalysis.cfgFlagQaCentrality.value) { + hrQaCentrality.fill(C_CS("QaCentrality/hCentralitySelection"), holderEvent.centrality, 3.); + } return false; } @@ -1937,12 +1981,19 @@ struct PartNumFluc { if (((groupEvent.cfgBitsSelectionEvent.value >> iEvSel) & 1) && !collision.selection_bit(iEvSel)) { hrCounter.fill(C_CS("hNEvents"), 4.); hrCounter.fill(C_CS("hNEvents"), 10. + iEvSel); + if (groupAnalysis.cfgFlagQaCentrality.value) { + hrQaCentrality.fill(C_CS("QaCentrality/hCentralitySelection"), holderEvent.centrality, 4.); + hrQaCentrality.fill(C_CS("QaCentrality/hCentralitySelection"), holderEvent.centrality, 10. + iEvSel); + } return false; } } if (groupEvent.cfgFlagInelEvent.value && !collision.isInelGt0()) { hrCounter.fill(C_CS("hNEvents"), 5.); + if (groupAnalysis.cfgFlagQaCentrality.value) { + hrQaCentrality.fill(C_CS("QaCentrality/hCentralitySelection"), holderEvent.centrality, 5.); + } return false; } @@ -1953,6 +2004,9 @@ struct PartNumFluc { if (!(std::abs(holderEvent.vz) < groupEvent.cfgCutMaxAbsVz.value)) { hrCounter.fill(C_CS("hNEvents"), 6.); + if (groupAnalysis.cfgFlagQaCentrality.value) { + hrQaCentrality.fill(C_CS("QaCentrality/hCentralitySelection"), holderEvent.centrality, 6.); + } return false; } @@ -2005,10 +2059,16 @@ struct PartNumFluc { if (!(holderEvent.getNPvContributors() - holderEvent.getNGlobalTracks() > groupEvent.cfgCutMinDeviationNPvContributors.value)) { hrCounter.fill(C_CS("hNEvents"), 7.); + if (groupAnalysis.cfgFlagQaCentrality.value) { + hrQaCentrality.fill(C_CS("QaCentrality/hCentralitySelection"), holderEvent.centrality, 7.); + } return false; } hrCounter.fill(C_CS("hNEvents"), 1.); + if (groupAnalysis.cfgFlagQaCentrality.value) { + hrQaCentrality.fill(C_CS("QaCentrality/hCentralitySelection"), holderEvent.centrality, 1.); + } if (groupAnalysis.cfgFlagQaEvent.value) { if (holderEvent.getNGlobalTracks() > 0) { @@ -2019,9 +2079,7 @@ struct PartNumFluc { } if (groupAnalysis.cfgFlagQaCentrality.value) { - 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()); + hrQaCentrality.fill(C_CS("QaCentrality/hCentralityMultiplicity"), holderEvent.centrality, collision.multNTracksPVeta1()); } return true; @@ -2072,11 +2130,11 @@ struct PartNumFluc { void processRaw(const soa::Filtered::iterator& collision, const soa::Filtered& tracks, const aod::TracksIU& tracksIu, const aod::BCsWithTimestamps&) { - if (!initEvent(collision, tracks, tracksIu) || (!groupAnalysis.cfgFlagQaTrack.value && !groupAnalysis.cfgFlagQaDca.value && !isEnabled(groupAnalysis.cfgFlagQaAcceptance) && !isEnabled(groupAnalysis.cfgFlagQaPhi) && !isEnabled(groupAnalysis.cfgFlagQaPid) && !isEnabled(groupAnalysis.cfgFlagCalculationYield) && !isEnabled(groupAnalysis.cfgFlagCalculationFluctuation))) { + if (!initEvent(collision, tracks, tracksIu) || (!groupAnalysis.cfgFlagQaTrack.value && !groupAnalysis.cfgFlagQaDca.value && !isEnabled(groupAnalysis.cfgFlagsQaAcceptance) && !isEnabled(groupAnalysis.cfgFlagsQaPhi) && !isEnabled(groupAnalysis.cfgFlagsQaPid) && !isEnabled(groupAnalysis.cfgFlagsCalculationYield) && !isEnabled(groupAnalysis.cfgFlagsCalculationFluctuation))) { return; } - if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationFluctuation)) { holderEvent.subgroupIndex = gRandom->Integer(groupEvent.cfgNSubgroups.value); initCalculationFluctuation(); holderDerivedData.clear(); @@ -2087,46 +2145,42 @@ struct PartNumFluc { continue; } - const bool isGood{initTrack(track, tracksIu)}; - if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation) && holderTrack.sign != 0) { - ++holderDerivedData.nTracksAll; - } - if (!isGood) { + if (!initTrack(track, tracksIu)) { continue; } - if (isEnabled(groupAnalysis.cfgFlagQaPhi)) { + if (isEnabled(groupAnalysis.cfgFlagsQaPhi)) { fillQaPhiByParticleSpeciesAll(); fillQaPhiByParticleSpeciesAll(); fillQaPhiByParticleSpeciesAll(); fillQaPhiByParticleSpeciesAll(); } - if (isEnabled(groupAnalysis.cfgFlagQaPid)) { + if (isEnabled(groupAnalysis.cfgFlagsQaPid)) { fillQaPidByParticleSpeciesAll(track); fillQaPidByParticleSpeciesAll(track); fillQaPidByParticleSpeciesAll(track); fillQaPidByParticleSpeciesAll(track); } - if (isEnabled(groupAnalysis.cfgFlagCalculationYield)) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationYield)) { fillCalculationYieldByParticleSpecies(); fillCalculationYieldByParticleSpecies(); fillCalculationYieldByParticleSpecies(); } - if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationFluctuation)) { calculateFluctuationByParticleNumber(); calculateFluctuationByParticleNumber(); calculateFluctuationByParticleNumber(); } } - if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationFluctuation)) { fillCalculationFluctuationByParticleNumber(); fillCalculationFluctuationByParticleNumber(); fillCalculationFluctuationByParticleNumber(); - miniCollision(HolderDerivedData::convertFloor(holderEvent.vz * 10.), HolderDerivedData::convertFloor(holderEvent.centrality * 500.), holderDerivedData.nTracksAll, holderDerivedData.nTracksIn); + miniCollision(HolderDerivedData::convertFloor(holderEvent.vz * 10.), HolderDerivedData::convertFloor(holderEvent.centrality * 500.), holderDerivedData.nTracks[toI(ChargeSpecies::kPlus)], holderDerivedData.nTracks[toI(ChargeSpecies::kMinus)]); for (auto const& signedEfficiency : holderDerivedData.signedEfficienciesTrack) { miniTrack(miniCollision.lastIndex(), signedEfficiency); } @@ -2153,11 +2207,11 @@ struct PartNumFluc { } if (groupAnalysis.cfgFlagQaMc.value) { - hrQaMc.fill(C_CS("QaMc/hCentralityVzDeltaVz"), holderEvent.centrality, holderEvent.vz, holderEvent.vz - holderMcEvent.vz); + hrQaMc.fill(C_CS("QaMc/hCentralityVzMcDeltaVz"), holderEvent.centrality, holderMcEvent.vz, holderEvent.vz - holderMcEvent.vz); } - if (isEnabled(groupAnalysis.cfgFlagCalculationYield) || isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { - if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationYield) || isEnabled(groupAnalysis.cfgFlagsCalculationFluctuation)) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationFluctuation)) { holderEvent.subgroupIndex = gRandom->Integer(groupEvent.cfgNSubgroups.value); initCalculationFluctuation(); holderDerivedData.clear(); @@ -2168,36 +2222,32 @@ struct PartNumFluc { continue; } - const bool isGood{initMcParticle(mcParticle)}; - if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation) && holderMcParticle.charge != 0) { - ++holderDerivedData.nMcParticlesChargedAll; - } - if (!isGood) { + if (!initMcParticle(mcParticle)) { continue; } - if (isEnabled(groupAnalysis.cfgFlagCalculationYield)) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationYield)) { fillCalculationYieldByParticleSpecies(); fillCalculationYieldByParticleSpecies(); fillCalculationYieldByParticleSpecies(); } - if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationFluctuation)) { calculateFluctuationByParticleNumber(); calculateFluctuationByParticleNumber(); calculateFluctuationByParticleNumber(); } } - if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationFluctuation)) { fillCalculationFluctuationByParticleNumber(); fillCalculationFluctuationByParticleNumber(); fillCalculationFluctuationByParticleNumber(); } } - 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)) { + if (groupAnalysis.cfgFlagQaTrack.value || groupAnalysis.cfgFlagQaDca.value || isEnabled(groupAnalysis.cfgFlagsQaAcceptance) || isEnabled(groupAnalysis.cfgFlagsQaPhi) || isEnabled(groupAnalysis.cfgFlagsQaPid) || isEnabled(groupAnalysis.cfgFlagsCalculationYield) || isEnabled(groupAnalysis.cfgFlagsCalculationPurity) || isEnabled(groupAnalysis.cfgFlagsCalculationFractionPrimary) || isEnabled(groupAnalysis.cfgFlagsCalculationFluctuation)) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationFluctuation)) { initCalculationFluctuation(); } @@ -2211,22 +2261,18 @@ struct PartNumFluc { continue; } - const bool isGood{initTrack(track, tracksIu) && initMcParticle(mcParticle)}; - if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation) && holderTrack.sign != 0) { - ++holderDerivedData.nTracksAll; - } - if (!isGood) { + if (!initTrack(track, tracksIu) || !initMcParticle(mcParticle)) { continue; } - if (isEnabled(groupAnalysis.cfgFlagQaPhi)) { + if (isEnabled(groupAnalysis.cfgFlagsQaPhi)) { fillQaPhiByParticleSpeciesAll(); fillQaPhiByParticleSpeciesAll(); fillQaPhiByParticleSpeciesAll(); fillQaPhiByParticleSpeciesAll(); } - if (isEnabled(groupAnalysis.cfgFlagQaPid)) { + if (isEnabled(groupAnalysis.cfgFlagsQaPid)) { fillQaPidByParticleSpeciesAll(track); fillQaPidByParticleSpeciesAll(track); fillQaPidByParticleSpeciesAll(track); @@ -2234,41 +2280,41 @@ struct PartNumFluc { } if (groupAnalysis.cfgFlagQaMc.value && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary())) { - 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); + hrQaMc.fill(C_CS("QaMc/hCentralityPtMcEtaMcDeltaPt"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderTrack.pt - holderMcParticle.pt); + hrQaMc.fill(C_CS("QaMc/hCentralityPtMcEtaMcDeltaEta"), holderEvent.centrality, holderMcParticle.pt, holderMcParticle.eta, holderTrack.eta - holderMcParticle.eta); } - if (isEnabled(groupAnalysis.cfgFlagCalculationYield) && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary())) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationYield) && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary())) { fillCalculationYieldByParticleSpecies(); fillCalculationYieldByParticleSpecies(); fillCalculationYieldByParticleSpecies(); } - if (isEnabled(groupAnalysis.cfgFlagCalculationPurity) && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary())) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationPurity) && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary())) { fillCalculationPurityByParticleSpecies(); fillCalculationPurityByParticleSpecies(); fillCalculationPurityByParticleSpecies(); } - if (isEnabled(groupAnalysis.cfgFlagCalculationFractionPrimary)) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationFractionPrimary)) { fillCalculationFractionPrimaryByParticleSpecies(mcParticle); fillCalculationFractionPrimaryByParticleSpecies(mcParticle); fillCalculationFractionPrimaryByParticleSpecies(mcParticle); } - if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation) && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary())) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationFluctuation) && (!groupTrack.cfgFlagMcParticlePhysicalPrimary.value || mcParticle.isPhysicalPrimary())) { calculateFluctuationByParticleNumber(); calculateFluctuationByParticleNumber(); calculateFluctuationByParticleNumber(); } } - if (isEnabled(groupAnalysis.cfgFlagCalculationFluctuation)) { + if (isEnabled(groupAnalysis.cfgFlagsCalculationFluctuation)) { fillCalculationFluctuationByParticleNumber(); fillCalculationFluctuationByParticleNumber(); fillCalculationFluctuationByParticleNumber(); - miniMcCollision(holderDerivedData.nMcParticlesChargedAll, holderDerivedData.nMcParticlesChargedIn); - miniCollision(HolderDerivedData::convertFloor(holderEvent.vz * 10.), HolderDerivedData::convertFloor(holderEvent.centrality * 500.), holderDerivedData.nTracksAll, holderDerivedData.nTracksIn); + miniMcCollision(holderDerivedData.nMcParticles[toI(ChargeSpecies::kPlus)], holderDerivedData.nMcParticles[toI(ChargeSpecies::kMinus)]); + miniCollision(HolderDerivedData::convertFloor(holderEvent.vz * 10.), HolderDerivedData::convertFloor(holderEvent.centrality * 500.), holderDerivedData.nTracks[toI(ChargeSpecies::kPlus)], holderDerivedData.nTracks[toI(ChargeSpecies::kMinus)]); for (auto const& signedEfficiency : holderDerivedData.signedEfficienciesMcParticle) { miniMcParticle(miniMcCollision.lastIndex(), signedEfficiency); } diff --git a/PWGCF/EbyEFluctuations/Tasks/stronglyIntensiveCorr.cxx b/PWGCF/EbyEFluctuations/Tasks/stronglyIntensiveCorr.cxx new file mode 100644 index 00000000000..6fa2543523b --- /dev/null +++ b/PWGCF/EbyEFluctuations/Tasks/stronglyIntensiveCorr.cxx @@ -0,0 +1,1157 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file stronglyIntensiveCorr.cxx +/// \brief Forward-backward multiplicity correlations for inclusive charged particles. +/// \author Iwona Sputowska + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct StronglyIntensiveCorr { + // ------------------------------------------------------------------ + // Configurables + // ------------------------------------------------------------------ + + Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; + Configurable cfgEtaWidth{"cfgEtaWidth", 0.2f, "FB window width"}; + Configurable cfgCutEta{"cfgCutEta", 0.8f, "absolute eta cut"}; + Configurable cfgCutPtLower{"cfgCutPtLower", 0.2f, "Lower pT cut"}; + Configurable cfgCutPtUpper{"cfgCutPtUpper", 5.0f, "Upper pT cut"}; + Configurable cfgCutTrackDcaZ{"cfgCutTrackDcaZ", 2.0f, "Maximum DCAz"}; + + Configurable cfgITScluster{"cfgITScluster", 5, "Minimum number of ITS clusters"}; + Configurable cfgTPCcluster{"cfgTPCcluster", 50, "Minimum number of TPC clusters"}; + Configurable cfgTPCnCrossedRows{"cfgTPCnCrossedRows", 70, "Minimum number of TPC crossed rows"}; + Configurable cfgCutTpcChi2NCl{"cfgCutTpcChi2NCl", 2.5f, "Maximum TPC chi2/NCl"}; + Configurable cfgCutItsChi2NCl{"cfgCutItsChi2NCl", 36.0f, "Maximum ITS chi2/NCl"}; + + Configurable cfgRequireGlobalTrack{"cfgRequireGlobalTrack", true, "Require isGlobalTrack OR isGlobalTrackSDD"}; + Configurable cfgUseDCAzCut{"cfgUseDCAzCut", true, "Use DCAz cut"}; + Configurable cfgSel8Trig{"cfgSel8Trig", true, "Require sel8"}; + + Configurable cfgCentMin{"cfgCentMin", 0.0f, "Minimum centrality"}; + Configurable cfgCentMax{"cfgCentMax", 90.0f, "Maximum centrality"}; + Configurable cfgCentralityChoice{"cfgCentralityChoice", 0, "Centrality estimator: 0=FT0C, 1=FT0M"}; + Configurable cfgCentWindowWidth{"cfgCentWindowWidth", 10.0f, "Centrality window width around class centers"}; + + Configurable cfgNSubsamples{"cfgNSubsamples", 20, "Number of subsamples; max is NSubsamplesMax"}; + + Configurable cfgEvSelkNoSameBunchPileup{"cfgEvSelkNoSameBunchPileup", true, "Pileup removal"}; + Configurable cfgUseGoodITSLayerAllCut{"cfgUseGoodITSLayerAllCut", true, "Remove time intervals with bad ITS layers"}; + Configurable cfgEvSelUseGoodZvtxFT0vsPV{"cfgEvSelUseGoodZvtxFT0vsPV", true, "Good z-vertex FT0 vs PV cut"}; + + Configurable cfgUseOnlyPhysicalPrimary{"cfgUseOnlyPhysicalPrimary", true, "MC truth: require physical primary"}; + Configurable cfgUseOnlyChargedMC{"cfgUseOnlyChargedMC", true, "MC truth: require charged particle"}; + + // ------------------------------------------------------------------ + // FB binning + // ------------------------------------------------------------------ + static constexpr int NEtaGaps = 8; + static constexpr int NPtBins = 6; + static constexpr int NPhiBins = 16; + static constexpr int NSubsamplesMax = 20; + static constexpr int NCentClasses = 8; + static constexpr double TwoPi = 6.28318530717958647692; + + std::array etaCenter = {0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0}; + + std::array ptEdges = {0.2, 0.5, 0.8, 1.0, 1.5, 2.0, 5.0}; + std::array centEdges = {0., 10., 20., 30., 40., 50., 60., 70., 80.}; + + using EtaPtPhiArray = std::array, NPtBins>, NEtaGaps>; + + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + Service pdg{}; + + Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; + + // Intentionally loose track filter: manual cuts are done in selTrack(), so QA before/after sees tracks. + Filter trackFilter = (aod::track::pt > -1.0f); + + using AodCollisions = soa::Filtered>; + using AodCollision = AodCollisions::iterator; + + using AodTracks = soa::Filtered>; + + using MyMCRecCollisions = soa::Filtered>; + using MyMCRecCollision = MyMCRecCollisions::iterator; + + using MyMCTracks = soa::Filtered>; + + Preslice perCollision = aod::track::collisionId; + Preslice perMcCollision = aod::mcparticle::mcCollisionId; + + // ------------------------------------------------------------------ + // Init + // ------------------------------------------------------------------ + void init(InitContext&) + { + AxisSpec centAxis = {100, 0.0, 100.0, "centrality (%)"}; + std::vector centClassEdges(centEdges.begin(), centEdges.end()); + AxisSpec centClassAxis = {centClassEdges, "centrality class (%)"}; + AxisSpec etaGapAxis = {NEtaGaps, -0.05, 1.55, "#Delta#eta"}; + AxisSpec nAxis = {500, 0.0, 500.0, "N"}; + AxisSpec counterAxis = {20, 0.5, 20.5, "counter"}; + AxisSpec ptAxis = {{0.2, 0.5, 0.8, 1.0, 1.5, 2.0, 5.0}, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec phiAxis = {NPhiBins, 0.0, TwoPi, "#varphi"}; + AxisSpec subsampleAxis = {NSubsamplesMax, -0.5, static_cast(NSubsamplesMax) - 0.5, "subsample"}; + + AxisSpec nchAxis = {500, 0.0, 500.0, "N_{ch}"}; + AxisSpec nchPvAxis = {1000, 0.0, 1000.0, "N_{ch}^{PV}"}; + AxisSpec itsClsAxis = {21, -0.5, 20.5, "N ITS clusters"}; + AxisSpec tpcClsAxis = {201, -0.5, 200.5, "N TPC clusters / crossed rows"}; + AxisSpec chi2ITSAxis = {100, 0.0, 50.0, "#chi^{2}_{ITS}/N_{cls}"}; + AxisSpec chi2TPCAxis = {100, 0.0, 5.0, "#chi^{2}_{TPC}/N_{cls}"}; + AxisSpec dcaXYAxis = {200, -0.5, 0.5, "DCA_{xy} (cm)"}; + AxisSpec dcaZAxis = {200, -2.0, 2.0, "DCA_{z} (cm)"}; + AxisSpec etaAxis = {160, -1.6, 1.6, "#eta"}; + AxisSpec ptFullAxis = {200, 0.0, 10.0, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec phiAxisFull = {64, 0.0, TwoPi, "#varphi"}; + AxisSpec chargeAxis = {5, -2.5, 2.5, "charge"}; + AxisSpec vtxZAxis = {240, -30.0, 30.0, "V_{z} (cm)"}; + + // Event QA + histos.add("QA/eventCounter", "event counter", kTH1D, {counterAxis}); + histos.add("QA/trackCounter", "track counter", kTH1D, {counterAxis}); + histos.add("QA/hTrackSliceSize", "number of tracks in collision-associated slice before manual cuts", kTH1D, {{500, -0.5, 499.5}}); + histos.add("QA/hGlobalTrackFlags", "global-track flags: 1=all, 2=isGlobalTrack, 3=isGlobalTrackSDD, 4=global OR SDD, 5=fail both", kTH1D, {counterAxis}); + histos.add("QA/hCentrality", "centrality", kTH1D, {centAxis}); + histos.add("QA/hNF", "nF", kTH1D, {nAxis}); + histos.add("QA/hNB", "nB", kTH1D, {nAxis}); + histos.add("QA/hNFvsNB", "nF vs nB", kTH2D, {nAxis, nAxis}); + histos.add("QA/fb/nFvsCent", "nF vs centrality;centrality (%);nF", kTH2D, {centAxis, nAxis}); + histos.add("QA/fb/nBvsCent", "nB vs centrality;centrality (%);nB", kTH2D, {centAxis, nAxis}); + histos.add("QA/fb/nFvsNB", "nF vs nB;nF;nB", kTH2D, {nAxis, nAxis}); + histos.add("QA/fb/nFminusNB", "nF-nB;nF-nB;Counts", kTH1D, {{500, -250.0, 250.0}}); + histos.add("QA/fb/nFplusNB", "nF+nB;nF+nB;Counts", kTH1D, {{500, 0.0, 500.0}}); + + histos.add("QA/mcReco/nRecoAll", "MC reco all selected;n;Counts", kTH1D, {nAxis}); + histos.add("QA/mcReco/nRecoPrimary", "MC reco primary selected;n;Counts", kTH1D, {nAxis}); + histos.add("QA/mcReco/nRecoSecondary", "MC reco secondary selected;n;Counts", kTH1D, {nAxis}); + histos.add("QA/mcReco/nRecoFake", "MC reco fake/unmatched selected;n;Counts", kTH1D, {nAxis}); + + histos.add("eventQA/before/nPVeta1TracksVsCent", "before;centrality (%);N_{ch}^{PV, |#eta|<1}", kTH2D, {centAxis, nchAxis}); + histos.add("eventQA/after/nPVeta1TracksVsCent", "after;centrality (%);N_{ch}^{PV, |#eta|<1}", kTH2D, {centAxis, nchAxis}); + histos.add("eventQA/before/nPVTracksVsCent", "before;centrality (%);N_{ch}^{PV}", kTH2D, {centAxis, nchPvAxis}); + histos.add("eventQA/after/nPVTracksVsCent", "after;centrality (%);N_{ch}^{PV}", kTH2D, {centAxis, nchPvAxis}); + histos.add("eventQA/before/vtxZ", "before event selection;V_{z} (cm);Counts", kTH1D, {vtxZAxis}); + histos.add("eventQA/after/vtxZ", "after event selection;V_{z} (cm);Counts", kTH1D, {vtxZAxis}); + histos.add("eventQA/before/centFT0C", "before;FT0C centrality (%);Counts", kTH1D, {centAxis}); + histos.add("eventQA/after/centFT0C", "after;FT0C centrality (%);Counts", kTH1D, {centAxis}); + histos.add("eventQA/before/centFT0M", "before;FT0M centrality (%);Counts", kTH1D, {centAxis}); + histos.add("eventQA/after/centFT0M", "after;FT0M centrality (%);Counts", kTH1D, {centAxis}); + histos.add("eventQA/before/centFT0CvsFT0M", "before;FT0C;FT0M", kTH2D, {centAxis, centAxis}); + histos.add("eventQA/after/centFT0CvsFT0M", "after;FT0C;FT0M", kTH2D, {centAxis, centAxis}); + + // Track QA + histos.add("trackQA/before/nITSClusters", "before;N ITS clusters;Counts", kTH1D, {itsClsAxis}); + histos.add("trackQA/after/nITSClusters", "after;N ITS clusters;Counts", kTH1D, {itsClsAxis}); + histos.add("trackQA/before/chi2prITScls", "before;#chi^{2}_{ITS}/N_{cls};Counts", kTH1D, {chi2ITSAxis}); + histos.add("trackQA/after/chi2prITScls", "after;#chi^{2}_{ITS}/N_{cls};Counts", kTH1D, {chi2ITSAxis}); + histos.add("trackQA/before/nTPCClusters", "before;N TPC clusters;Counts", kTH1D, {tpcClsAxis}); + histos.add("trackQA/after/nTPCClusters", "after;N TPC clusters;Counts", kTH1D, {tpcClsAxis}); + histos.add("trackQA/before/chi2prTPCcls", "before;#chi^{2}_{TPC}/N_{cls};Counts", kTH1D, {chi2TPCAxis}); + histos.add("trackQA/after/chi2prTPCcls", "after;#chi^{2}_{TPC}/N_{cls};Counts", kTH1D, {chi2TPCAxis}); + histos.add("trackQA/before/nTPCCrossedRows", "before;N TPC crossed rows;Counts", kTH1D, {tpcClsAxis}); + histos.add("trackQA/after/nTPCCrossedRows", "after;N TPC crossed rows;Counts", kTH1D, {tpcClsAxis}); + histos.add("trackQA/before/eta", "before;#eta;Counts", kTH1D, {etaAxis}); + histos.add("trackQA/after/eta", "after;#eta;Counts", kTH1D, {etaAxis}); + histos.add("trackQA/before/pt", "before;#it{p}_{T} (GeV/#it{c});Counts", kTH1D, {ptFullAxis}); + histos.add("trackQA/after/pt", "after;#it{p}_{T} (GeV/#it{c});Counts", kTH1D, {ptFullAxis}); + histos.add("trackQA/before/dcaXY", "before;DCA_{xy} (cm);Counts", kTH1D, {dcaXYAxis}); + histos.add("trackQA/after/dcaXY", "after;DCA_{xy} (cm);Counts", kTH1D, {dcaXYAxis}); + histos.add("trackQA/before/dcaZ", "before;DCA_{z} (cm);Counts", kTH1D, {dcaZAxis}); + histos.add("trackQA/after/dcaZ", "after;DCA_{z} (cm);Counts", kTH1D, {dcaZAxis}); + histos.add("trackQA/before/phi", "before;#varphi;Counts", kTH1D, {phiAxisFull}); + histos.add("trackQA/after/phi", "after;#varphi;Counts", kTH1D, {phiAxisFull}); + histos.add("trackQA/before/charge", "before;charge;Counts", kTH1D, {chargeAxis}); + histos.add("trackQA/after/charge", "after;charge;Counts", kTH1D, {chargeAxis}); + histos.add("trackQA/before/ptVsEta", "before;#eta;#it{p}_{T}", kTH2D, {etaAxis, ptFullAxis}); + histos.add("trackQA/after/ptVsEta", "after;#eta;#it{p}_{T}", kTH2D, {etaAxis, ptFullAxis}); + histos.add("trackQA/before/dcaXYvsPt", "before;DCA_{xy};#it{p}_{T}", kTH2D, {dcaXYAxis, ptFullAxis}); + histos.add("trackQA/after/dcaXYvsPt", "after;DCA_{xy};#it{p}_{T}", kTH2D, {dcaXYAxis, ptFullAxis}); + histos.add("trackQA/before/dcaZvsPt", "before;DCA_{z};#it{p}_{T}", kTH2D, {dcaZAxis, ptFullAxis}); + histos.add("trackQA/after/dcaZvsPt", "after;DCA_{z};#it{p}_{T}", kTH2D, {dcaZAxis, ptFullAxis}); + + // Chosen centrality binning, default 0-10 ... 70-80. + + histos.add("SIcentClass/pNF_cent_etaGap", ";centrality class (%);#Delta#eta", kTProfile2D, {centClassAxis, etaGapAxis}); + histos.add("SIcentClass/pNB_cent_etaGap", ";centrality class (%);#Delta#eta", kTProfile2D, {centClassAxis, etaGapAxis}); + histos.add("SIcentClass/pNF2_cent_etaGap", ";centrality class (%);#Delta#eta", kTProfile2D, {centClassAxis, etaGapAxis}); + histos.add("SIcentClass/pNB2_cent_etaGap", ";centrality class (%);#Delta#eta", kTProfile2D, {centClassAxis, etaGapAxis}); + histos.add("SIcentClass/pNFNB_cent_etaGap", ";centrality class (%);#Delta#eta", kTProfile2D, {centClassAxis, etaGapAxis}); + + histos.add("SIcentWindow/pNF_cent_etaGap", " in centrality window;centrality class (%);#Delta#eta", kTProfile2D, {centClassAxis, etaGapAxis}); + histos.add("SIcentWindow/pNB_cent_etaGap", " in centrality window;centrality class (%);#Delta#eta", kTProfile2D, {centClassAxis, etaGapAxis}); + histos.add("SIcentWindow/pNF2_cent_etaGap", " in centrality window;centrality class (%);#Delta#eta", kTProfile2D, {centClassAxis, etaGapAxis}); + histos.add("SIcentWindow/pNB2_cent_etaGap", " in centrality window;centrality class (%);#Delta#eta", kTProfile2D, {centClassAxis, etaGapAxis}); + histos.add("SIcentWindow/pNFNB_cent_etaGap", " in centrality window;centrality class (%);#Delta#eta", kTProfile2D, {centClassAxis, etaGapAxis}); + + // Differential eta-gap x pT x phi moments. + histos.add("SI3D/pNF_etaGapPtPhi", ";#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("SI3D/pNB_etaGapPtPhi", ";#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("SI3D/pNF2_etaGapPtPhi", ";#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("SI3D/pNB2_etaGapPtPhi", ";#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("SI3D/pNFNB_etaGapPtPhi", ";#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("SI3D/pF20_etaGapPtPhi", ";#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("SI3D/pB20_etaGapPtPhi", ";#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("SI3D/pF11_etaGapPtPhi", ";#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + + // Subsample centrality-window output. + histos.add("SubsampleCentWindow/pNF_sub_cent_etaGap", " subsamples;subsample;centrality class (%);#Delta#eta", kTProfile3D, {subsampleAxis, centClassAxis, etaGapAxis}); + histos.add("SubsampleCentWindow/pNB_sub_cent_etaGap", " subsamples;subsample;centrality class (%);#Delta#eta", kTProfile3D, {subsampleAxis, centClassAxis, etaGapAxis}); + histos.add("SubsampleCentWindow/pNF2_sub_cent_etaGap", " subsamples;subsample;centrality class (%);#Delta#eta", kTProfile3D, {subsampleAxis, centClassAxis, etaGapAxis}); + histos.add("SubsampleCentWindow/pNB2_sub_cent_etaGap", " subsamples;subsample;centrality class (%);#Delta#eta", kTProfile3D, {subsampleAxis, centClassAxis, etaGapAxis}); + histos.add("SubsampleCentWindow/pNFNB_sub_cent_etaGap", " subsamples;subsample;centrality class (%);#Delta#eta", kTProfile3D, {subsampleAxis, centClassAxis, etaGapAxis}); + + // THnSparse sums per subsample for differential studies. + histos.add("SubsampleSI3D/EventCount_sub_etaGapPtPhi", "event count;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleSI3D/SumNF_sub_etaGapPtPhi", "sum nF;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleSI3D/SumNB_sub_etaGapPtPhi", "sum nB;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleSI3D/SumNF2_sub_etaGapPtPhi", "sum nF^{2};subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleSI3D/SumNB2_sub_etaGapPtPhi", "sum nB^{2};subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleSI3D/SumNFNB_sub_etaGapPtPhi", "sum nF nB;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleSI3D/SumF20_sub_etaGapPtPhi", "sum nF(nF-1);subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleSI3D/SumB20_sub_etaGapPtPhi", "sum nB(nB-1);subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleSI3D/SumF11_sub_etaGapPtPhi", "sum nF nB;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + + histos.add("Reco/SI3D/pNF_etaGapPtPhi", " reco;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("Reco/SI3D/pNB_etaGapPtPhi", " reco;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("Reco/SI3D/pNF2_etaGapPtPhi", " reco;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("Reco/SI3D/pNB2_etaGapPtPhi", " reco;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("Reco/SI3D/pNFNB_etaGapPtPhi", " reco;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + + histos.add("Prim/SI3D/pNF_etaGapPtPhi", " primary reco;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("Prim/SI3D/pNB_etaGapPtPhi", " primary reco;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("Prim/SI3D/pNF2_etaGapPtPhi", " primary reco;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("Prim/SI3D/pNB2_etaGapPtPhi", " primary reco;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("Prim/SI3D/pNFNB_etaGapPtPhi", " primary reco;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + + histos.add("Gen/SI3D/pNF_etaGapPtPhi", " generated;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("Gen/SI3D/pNB_etaGapPtPhi", " generated;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("Gen/SI3D/pNF2_etaGapPtPhi", " generated;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("Gen/SI3D/pNB2_etaGapPtPhi", " generated;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + histos.add("Gen/SI3D/pNFNB_etaGapPtPhi", " generated;#Delta#eta;#it{p}_{T};#varphi", kTProfile3D, {etaGapAxis, ptAxis, phiAxis}); + + // Sample-separated MC subsample sums for SI3D. + // Axes: subsample x eta gap x pT x phi. EventCount is the denominator. + histos.add("SubsampleRecoSI3D/EventCount_sub_etaGapPtPhi", "event count reco;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleRecoSI3D/SumNF_sub_etaGapPtPhi", "sum nF reco;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleRecoSI3D/SumNB_sub_etaGapPtPhi", "sum nB reco;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleRecoSI3D/SumNF2_sub_etaGapPtPhi", "sum nF^{2} reco;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleRecoSI3D/SumNB2_sub_etaGapPtPhi", "sum nB^{2} reco;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleRecoSI3D/SumNFNB_sub_etaGapPtPhi", "sum nF nB reco;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + + histos.add("SubsamplePrimSI3D/EventCount_sub_etaGapPtPhi", "event count primary reco;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsamplePrimSI3D/SumNF_sub_etaGapPtPhi", "sum nF primary reco;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsamplePrimSI3D/SumNB_sub_etaGapPtPhi", "sum nB primary reco;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsamplePrimSI3D/SumNF2_sub_etaGapPtPhi", "sum nF^{2} primary reco;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsamplePrimSI3D/SumNB2_sub_etaGapPtPhi", "sum nB^{2} primary reco;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsamplePrimSI3D/SumNFNB_sub_etaGapPtPhi", "sum nF nB primary reco;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + + histos.add("SubsampleGenSI3D/EventCount_sub_etaGapPtPhi", "event count generated;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleGenSI3D/SumNF_sub_etaGapPtPhi", "sum nF generated;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleGenSI3D/SumNB_sub_etaGapPtPhi", "sum nB generated;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleGenSI3D/SumNF2_sub_etaGapPtPhi", "sum nF^{2} generated;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleGenSI3D/SumNB2_sub_etaGapPtPhi", "sum nB^{2} generated;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + histos.add("SubsampleGenSI3D/SumNFNB_sub_etaGapPtPhi", "sum nF nB generated;subsample;#Delta#eta;#it{p}_{T};#varphi", kTHnSparseD, {subsampleAxis, etaGapAxis, ptAxis, phiAxis}); + } + + // ------------------------------------------------------------------ + // Helpers + // ------------------------------------------------------------------ + template + float getCentrality(C const& coll) const + { + switch (cfgCentralityChoice.value) { + case 0: + return coll.centFT0C(); + case 1: + return coll.centFT0M(); + default: + return -999.f; + } + } + + int getCentClass(float cent) const + { + for (int ic = 0; ic < NCentClasses; ++ic) { + if (cent >= centEdges[ic] && cent < centEdges[ic + 1]) { + return ic; + } + } + return -1; + } + + double getCentClassCenter(int ic) const + { + if (ic < 0 || ic >= NCentClasses) { + return -999.0; + } + return 0.5 * (centEdges[ic] + centEdges[ic + 1]); + } + + int getCentWindowClass(float cent) const + { + const double halfWidth = 0.5 * static_cast(cfgCentWindowWidth.value); + if (halfWidth <= 0.0) { + return -1; + } + + for (int ic = 0; ic < NCentClasses; ++ic) { + const double center = getCentClassCenter(ic); + if (cent >= center - halfWidth && cent < center + halfWidth) { + return ic; + } + } + return -1; + } + + template + int getSubsampleIndex(C const& coll) const + { + const int nSubsamples = std::min(std::max(cfgNSubsamples.value, 0), NSubsamplesMax); + if (nSubsamples <= 0) { + return -1; + } + return static_cast(coll.globalIndex() % nSubsamples); + } + + int getPtBin(double pt) const + { + for (int ipt = 0; ipt < NPtBins; ++ipt) { + if (pt >= ptEdges[ipt] && pt < ptEdges[ipt + 1]) { + return ipt; + } + } + return -1; + } + + int getPhiBin(double phi) const + { + while (phi < 0.0) { + phi += TwoPi; + } + while (phi >= TwoPi) { + phi -= TwoPi; + } + + const int iphi = static_cast(phi / TwoPi * NPhiBins); + if (iphi < 0 || iphi >= NPhiBins) { + return -1; + } + return iphi; + } + + bool isChargedMCParticle(int pdgCode) const + { + auto* particle = pdg->GetParticle(pdgCode); + if (!particle) { + return false; + } + + constexpr double MinAbsCharge = 0.0; + return std::abs(particle->Charge()) > MinAbsCharge; + } + + template + bool selCollision(C const& coll, float& cent) + { + histos.fill(HIST("QA/eventCounter"), 1); + + if (std::abs(coll.posZ()) > cfgCutVertex.value) { + return false; + } + histos.fill(HIST("QA/eventCounter"), 2); + + if (cfgSel8Trig.value && !coll.sel8()) { + return false; + } + histos.fill(HIST("QA/eventCounter"), 3); + + if (cfgUseGoodITSLayerAllCut.value && !coll.selection_bit(aod::evsel::kIsGoodITSLayersAll)) { + return false; + } + histos.fill(HIST("QA/eventCounter"), 4); + + if (cfgEvSelkNoSameBunchPileup.value && !coll.selection_bit(aod::evsel::kNoSameBunchPileup)) { + return false; + } + histos.fill(HIST("QA/eventCounter"), 5); + + if (cfgEvSelUseGoodZvtxFT0vsPV.value && !coll.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + histos.fill(HIST("QA/eventCounter"), 6); + + constexpr float MinCentrality = 0.f; + constexpr float MaxCentrality = 100.f; + + cent = getCentrality(coll); + if (!std::isfinite(cent) || cent < MinCentrality || cent >= MaxCentrality) { + return false; + } + if (cent < cfgCentMin.value || cent >= cfgCentMax.value) { + return false; + } + histos.fill(HIST("QA/eventCounter"), 7); + + return true; + } + + template + void fillTrackQABefore(T const& track) + { + histos.fill(HIST("trackQA/before/nITSClusters"), track.itsNCls()); + histos.fill(HIST("trackQA/before/chi2prITScls"), track.itsChi2NCl()); + histos.fill(HIST("trackQA/before/nTPCClusters"), track.tpcNClsFound()); + histos.fill(HIST("trackQA/before/chi2prTPCcls"), track.tpcChi2NCl()); + histos.fill(HIST("trackQA/before/nTPCCrossedRows"), track.tpcNClsCrossedRows()); + histos.fill(HIST("trackQA/before/eta"), track.eta()); + histos.fill(HIST("trackQA/before/pt"), track.pt()); + histos.fill(HIST("trackQA/before/dcaXY"), track.dcaXY()); + histos.fill(HIST("trackQA/before/dcaZ"), track.dcaZ()); + histos.fill(HIST("trackQA/before/phi"), track.phi()); + histos.fill(HIST("trackQA/before/charge"), track.sign()); + histos.fill(HIST("trackQA/before/ptVsEta"), track.eta(), track.pt()); + histos.fill(HIST("trackQA/before/dcaXYvsPt"), track.dcaXY(), track.pt()); + histos.fill(HIST("trackQA/before/dcaZvsPt"), track.dcaZ(), track.pt()); + } + + template + void fillTrackQAAfter(T const& track) + { + histos.fill(HIST("trackQA/after/nITSClusters"), track.itsNCls()); + histos.fill(HIST("trackQA/after/chi2prITScls"), track.itsChi2NCl()); + histos.fill(HIST("trackQA/after/nTPCClusters"), track.tpcNClsFound()); + histos.fill(HIST("trackQA/after/chi2prTPCcls"), track.tpcChi2NCl()); + histos.fill(HIST("trackQA/after/nTPCCrossedRows"), track.tpcNClsCrossedRows()); + histos.fill(HIST("trackQA/after/dcaXYvsPt"), track.dcaXY(), track.pt()); + histos.fill(HIST("trackQA/after/dcaZvsPt"), track.dcaZ(), track.pt()); + histos.fill(HIST("trackQA/after/eta"), track.eta()); + histos.fill(HIST("trackQA/after/pt"), track.pt()); + histos.fill(HIST("trackQA/after/dcaXY"), track.dcaXY()); + histos.fill(HIST("trackQA/after/dcaZ"), track.dcaZ()); + histos.fill(HIST("trackQA/after/phi"), track.phi()); + histos.fill(HIST("trackQA/after/charge"), track.sign()); + histos.fill(HIST("trackQA/after/ptVsEta"), track.eta(), track.pt()); + } + + template + bool selTrack(T const& track) + { + histos.fill(HIST("QA/trackCounter"), 1); + + histos.fill(HIST("QA/hGlobalTrackFlags"), 1); + const bool isGlobal = track.isGlobalTrack(); + const bool isGlobalSDD = track.isGlobalTrackSDD(); + if (isGlobal) { + histos.fill(HIST("QA/hGlobalTrackFlags"), 2); + } + if (isGlobalSDD) { + histos.fill(HIST("QA/hGlobalTrackFlags"), 3); + } + if (isGlobal || isGlobalSDD) { + histos.fill(HIST("QA/hGlobalTrackFlags"), 4); + } else { + histos.fill(HIST("QA/hGlobalTrackFlags"), 5); + } + + if (cfgRequireGlobalTrack.value && !(isGlobal || isGlobalSDD)) { + return false; + } + histos.fill(HIST("QA/trackCounter"), 2); + + if (track.tpcNClsFound() < cfgTPCcluster.value) { + return false; + } + histos.fill(HIST("QA/trackCounter"), 3); + + if (track.tpcNClsCrossedRows() < cfgTPCnCrossedRows.value) { + return false; + } + histos.fill(HIST("QA/trackCounter"), 4); + + if (track.itsNCls() < cfgITScluster.value) { + return false; + } + histos.fill(HIST("QA/trackCounter"), 5); + + if (track.tpcChi2NCl() >= cfgCutTpcChi2NCl.value) { + return false; + } + histos.fill(HIST("QA/trackCounter"), 6); + + if (track.itsChi2NCl() >= cfgCutItsChi2NCl.value) { + return false; + } + histos.fill(HIST("QA/trackCounter"), 7); + + if (track.pt() < cfgCutPtLower.value || track.pt() >= cfgCutPtUpper.value) { + return false; + } + histos.fill(HIST("QA/trackCounter"), 8); + + if (std::abs(track.eta()) >= cfgCutEta.value) { + return false; + } + histos.fill(HIST("QA/trackCounter"), 9); + + // No DCAxy cut here. It is kept only for QA. + histos.fill(HIST("QA/trackCounter"), 10); + + if (cfgUseDCAzCut.value && std::abs(track.dcaZ()) > cfgCutTrackDcaZ.value) { + return false; + } + histos.fill(HIST("QA/trackCounter"), 11); + + if (track.sign() == 0) { + return false; + } + histos.fill(HIST("QA/trackCounter"), 12); + + return true; + } + + template + bool selMCParticle(P const& particle) + { + if (cfgUseOnlyPhysicalPrimary.value && !particle.isPhysicalPrimary()) { + return false; + } + if (cfgUseOnlyChargedMC.value && !isChargedMCParticle(particle.pdgCode())) { + return false; + } + if (particle.pt() < cfgCutPtLower.value || particle.pt() >= cfgCutPtUpper.value) { + return false; + } + if (std::abs(particle.eta()) >= cfgCutEta.value) { + return false; + } + return true; + } + + void addToFBCounters(double eta, double pt, double phi, + std::array& nF, + std::array& nB, + EtaPtPhiArray& nFPtPhi, + EtaPtPhiArray& nBPtPhi) + { + const int ipt = getPtBin(pt); + const int iphi = getPhiBin(phi); + const bool fillPtPhi = (ipt >= 0 && iphi >= 0); + + for (int i = 0; i < NEtaGaps; ++i) { + const double etaLow = etaCenter[i] - cfgEtaWidth.value / 2.0; + const double etaHigh = etaCenter[i] + cfgEtaWidth.value / 2.0; + + if (eta > etaLow && eta < etaHigh) { + nF[i] += 1.0; + if (fillPtPhi) { + nFPtPhi[i][ipt][iphi] += 1.0; + } + } + + if (eta > -etaHigh && eta < -etaLow) { + nB[i] += 1.0; + if (fillPtPhi) { + nBPtPhi[i][ipt][iphi] += 1.0; + } + } + } + } + + void fillFBQA(float cent, + std::array const& nF, + std::array const& nB) + { + constexpr int DefaultGapBin = 0; + const double nf = nF[DefaultGapBin]; + const double nb = nB[DefaultGapBin]; + + histos.fill(HIST("QA/fb/nFvsCent"), cent, nf); + histos.fill(HIST("QA/fb/nBvsCent"), cent, nb); + histos.fill(HIST("QA/fb/nFvsNB"), nf, nb); + histos.fill(HIST("QA/fb/nFminusNB"), nf - nb); + histos.fill(HIST("QA/fb/nFplusNB"), nf + nb); + } + + void fillInclusiveEtaGapMoments(std::array const& nF, + std::array const& nB) + { + for (int i = 0; i < NEtaGaps; ++i) { + + histos.fill(HIST("QA/hNF"), nF[i]); + histos.fill(HIST("QA/hNB"), nB[i]); + histos.fill(HIST("QA/hNFvsNB"), nF[i], nB[i]); + } + } + + void fillCentClassEtaGapMoments(int centClass, + std::array const& nF, + std::array const& nB) + { + if (centClass < 0 || centClass >= NCentClasses) { + return; + } + + const double centCenter = getCentClassCenter(centClass); + for (int i = 0; i < NEtaGaps; ++i) { + const double gap = 2.0 * (etaCenter[i] - cfgEtaWidth.value / 2.0); + histos.fill(HIST("SIcentClass/pNF_cent_etaGap"), centCenter, gap, nF[i]); + histos.fill(HIST("SIcentClass/pNB_cent_etaGap"), centCenter, gap, nB[i]); + histos.fill(HIST("SIcentClass/pNF2_cent_etaGap"), centCenter, gap, nF[i] * nF[i]); + histos.fill(HIST("SIcentClass/pNB2_cent_etaGap"), centCenter, gap, nB[i] * nB[i]); + histos.fill(HIST("SIcentClass/pNFNB_cent_etaGap"), centCenter, gap, nF[i] * nB[i]); + } + } + + void fillCentWindowEtaGapMoments(int centWindowClass, + std::array const& nF, + std::array const& nB) + { + if (centWindowClass < 0 || centWindowClass >= NCentClasses) { + return; + } + + const double centCenter = getCentClassCenter(centWindowClass); + for (int i = 0; i < NEtaGaps; ++i) { + const double gap = 2.0 * (etaCenter[i] - cfgEtaWidth.value / 2.0); + histos.fill(HIST("SIcentWindow/pNF_cent_etaGap"), centCenter, gap, nF[i]); + histos.fill(HIST("SIcentWindow/pNB_cent_etaGap"), centCenter, gap, nB[i]); + histos.fill(HIST("SIcentWindow/pNF2_cent_etaGap"), centCenter, gap, nF[i] * nF[i]); + histos.fill(HIST("SIcentWindow/pNB2_cent_etaGap"), centCenter, gap, nB[i] * nB[i]); + histos.fill(HIST("SIcentWindow/pNFNB_cent_etaGap"), centCenter, gap, nF[i] * nB[i]); + } + } + + void fillSubsampleCentWindowEtaGapMoments(int isub, + int centWindowClass, + std::array const& nF, + std::array const& nB) + { + if (isub < 0 || isub >= NSubsamplesMax) { + return; + } + if (centWindowClass < 0 || centWindowClass >= NCentClasses) { + return; + } + + const double centCenter = getCentClassCenter(centWindowClass); + for (int i = 0; i < NEtaGaps; ++i) { + const double gap = 2.0 * (etaCenter[i] - cfgEtaWidth.value / 2.0); + histos.fill(HIST("SubsampleCentWindow/pNF_sub_cent_etaGap"), isub, centCenter, gap, nF[i]); + histos.fill(HIST("SubsampleCentWindow/pNB_sub_cent_etaGap"), isub, centCenter, gap, nB[i]); + histos.fill(HIST("SubsampleCentWindow/pNF2_sub_cent_etaGap"), isub, centCenter, gap, nF[i] * nF[i]); + histos.fill(HIST("SubsampleCentWindow/pNB2_sub_cent_etaGap"), isub, centCenter, gap, nB[i] * nB[i]); + histos.fill(HIST("SubsampleCentWindow/pNFNB_sub_cent_etaGap"), isub, centCenter, gap, nF[i] * nB[i]); + } + } + + void fillDifferentialEtaPtPhiMoments(EtaPtPhiArray const& nF, + EtaPtPhiArray const& nB) + { + for (int igap = 0; igap < NEtaGaps; ++igap) { + const double gap = 2.0 * (etaCenter[igap] - cfgEtaWidth.value / 2.0); + for (int ipt = 0; ipt < NPtBins; ++ipt) { + const double ptCenter = 0.5 * (ptEdges[ipt] + ptEdges[ipt + 1]); + for (int iphi = 0; iphi < NPhiBins; ++iphi) { + const double phiCenter = (iphi + 0.5) * TwoPi / NPhiBins; + const double nf = nF[igap][ipt][iphi]; + const double nb = nB[igap][ipt][iphi]; + + histos.fill(HIST("SI3D/pNF_etaGapPtPhi"), gap, ptCenter, phiCenter, nf); + histos.fill(HIST("SI3D/pNB_etaGapPtPhi"), gap, ptCenter, phiCenter, nb); + histos.fill(HIST("SI3D/pNF2_etaGapPtPhi"), gap, ptCenter, phiCenter, nf * nf); + histos.fill(HIST("SI3D/pNB2_etaGapPtPhi"), gap, ptCenter, phiCenter, nb * nb); + histos.fill(HIST("SI3D/pNFNB_etaGapPtPhi"), gap, ptCenter, phiCenter, nf * nb); + histos.fill(HIST("SI3D/pF20_etaGapPtPhi"), gap, ptCenter, phiCenter, nf * (nf - 1.0)); + histos.fill(HIST("SI3D/pB20_etaGapPtPhi"), gap, ptCenter, phiCenter, nb * (nb - 1.0)); + histos.fill(HIST("SI3D/pF11_etaGapPtPhi"), gap, ptCenter, phiCenter, nf * nb); + } + } + } + } + + void fillRecoDifferentialEtaPtPhiMoments(EtaPtPhiArray const& nF, + EtaPtPhiArray const& nB) + { + for (int igap = 0; igap < NEtaGaps; ++igap) { + const double gap = 2.0 * (etaCenter[igap] - cfgEtaWidth.value / 2.0); + for (int ipt = 0; ipt < NPtBins; ++ipt) { + const double ptCenter = 0.5 * (ptEdges[ipt] + ptEdges[ipt + 1]); + for (int iphi = 0; iphi < NPhiBins; ++iphi) { + const double phiCenter = (iphi + 0.5) * TwoPi / NPhiBins; + const double nf = nF[igap][ipt][iphi]; + const double nb = nB[igap][ipt][iphi]; + + histos.fill(HIST("Reco/SI3D/pNF_etaGapPtPhi"), gap, ptCenter, phiCenter, nf); + histos.fill(HIST("Reco/SI3D/pNB_etaGapPtPhi"), gap, ptCenter, phiCenter, nb); + histos.fill(HIST("Reco/SI3D/pNF2_etaGapPtPhi"), gap, ptCenter, phiCenter, nf * nf); + histos.fill(HIST("Reco/SI3D/pNB2_etaGapPtPhi"), gap, ptCenter, phiCenter, nb * nb); + histos.fill(HIST("Reco/SI3D/pNFNB_etaGapPtPhi"), gap, ptCenter, phiCenter, nf * nb); + } + } + } + } + void fillPrimDifferentialEtaPtPhiMoments(EtaPtPhiArray const& nF, + EtaPtPhiArray const& nB) + { + for (int igap = 0; igap < NEtaGaps; ++igap) { + const double gap = 2.0 * (etaCenter[igap] - cfgEtaWidth.value / 2.0); + + for (int ipt = 0; ipt < NPtBins; ++ipt) { + const double ptCenter = 0.5 * (ptEdges[ipt] + ptEdges[ipt + 1]); + + for (int iphi = 0; iphi < NPhiBins; ++iphi) { + const double phiCenter = (iphi + 0.5) * TwoPi / NPhiBins; + + const double nf = nF[igap][ipt][iphi]; + const double nb = nB[igap][ipt][iphi]; + + histos.fill(HIST("Prim/SI3D/pNF_etaGapPtPhi"), gap, ptCenter, phiCenter, nf); + histos.fill(HIST("Prim/SI3D/pNB_etaGapPtPhi"), gap, ptCenter, phiCenter, nb); + histos.fill(HIST("Prim/SI3D/pNF2_etaGapPtPhi"), gap, ptCenter, phiCenter, nf * nf); + histos.fill(HIST("Prim/SI3D/pNB2_etaGapPtPhi"), gap, ptCenter, phiCenter, nb * nb); + histos.fill(HIST("Prim/SI3D/pNFNB_etaGapPtPhi"), gap, ptCenter, phiCenter, nf * nb); + } + } + } + } + void fillGenDifferentialEtaPtPhiMoments(EtaPtPhiArray const& nF, + EtaPtPhiArray const& nB) + { + for (int igap = 0; igap < NEtaGaps; ++igap) { + const double gap = 2.0 * (etaCenter[igap] - cfgEtaWidth.value / 2.0); + + for (int ipt = 0; ipt < NPtBins; ++ipt) { + const double ptCenter = 0.5 * (ptEdges[ipt] + ptEdges[ipt + 1]); + + for (int iphi = 0; iphi < NPhiBins; ++iphi) { + const double phiCenter = (iphi + 0.5) * TwoPi / NPhiBins; + + const double nf = nF[igap][ipt][iphi]; + const double nb = nB[igap][ipt][iphi]; + + histos.fill(HIST("Gen/SI3D/pNF_etaGapPtPhi"), gap, ptCenter, phiCenter, nf); + histos.fill(HIST("Gen/SI3D/pNB_etaGapPtPhi"), gap, ptCenter, phiCenter, nb); + histos.fill(HIST("Gen/SI3D/pNF2_etaGapPtPhi"), gap, ptCenter, phiCenter, nf * nf); + histos.fill(HIST("Gen/SI3D/pNB2_etaGapPtPhi"), gap, ptCenter, phiCenter, nb * nb); + histos.fill(HIST("Gen/SI3D/pNFNB_etaGapPtPhi"), gap, ptCenter, phiCenter, nf * nb); + } + } + } + } + + void fillRecoSubsampleDifferentialEtaPtPhiMoments(int isub, + EtaPtPhiArray const& nF, + EtaPtPhiArray const& nB) + { + if (isub < 0 || isub >= NSubsamplesMax) { + return; + } + + for (int igap = 0; igap < NEtaGaps; ++igap) { + const double gap = 2.0 * (etaCenter[igap] - cfgEtaWidth.value / 2.0); + for (int ipt = 0; ipt < NPtBins; ++ipt) { + const double ptCenter = 0.5 * (ptEdges[ipt] + ptEdges[ipt + 1]); + for (int iphi = 0; iphi < NPhiBins; ++iphi) { + const double phiCenter = (iphi + 0.5) * TwoPi / NPhiBins; + const double nf = nF[igap][ipt][iphi]; + const double nb = nB[igap][ipt][iphi]; + + histos.fill(HIST("SubsampleRecoSI3D/EventCount_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, 1.0); + histos.fill(HIST("SubsampleRecoSI3D/SumNF_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nf); + histos.fill(HIST("SubsampleRecoSI3D/SumNB_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nb); + histos.fill(HIST("SubsampleRecoSI3D/SumNF2_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nf * nf); + histos.fill(HIST("SubsampleRecoSI3D/SumNB2_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nb * nb); + histos.fill(HIST("SubsampleRecoSI3D/SumNFNB_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nf * nb); + } + } + } + } + + void fillPrimSubsampleDifferentialEtaPtPhiMoments(int isub, + EtaPtPhiArray const& nF, + EtaPtPhiArray const& nB) + { + if (isub < 0 || isub >= NSubsamplesMax) { + return; + } + + for (int igap = 0; igap < NEtaGaps; ++igap) { + const double gap = 2.0 * (etaCenter[igap] - cfgEtaWidth.value / 2.0); + for (int ipt = 0; ipt < NPtBins; ++ipt) { + const double ptCenter = 0.5 * (ptEdges[ipt] + ptEdges[ipt + 1]); + for (int iphi = 0; iphi < NPhiBins; ++iphi) { + const double phiCenter = (iphi + 0.5) * TwoPi / NPhiBins; + const double nf = nF[igap][ipt][iphi]; + const double nb = nB[igap][ipt][iphi]; + + histos.fill(HIST("SubsamplePrimSI3D/EventCount_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, 1.0); + histos.fill(HIST("SubsamplePrimSI3D/SumNF_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nf); + histos.fill(HIST("SubsamplePrimSI3D/SumNB_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nb); + histos.fill(HIST("SubsamplePrimSI3D/SumNF2_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nf * nf); + histos.fill(HIST("SubsamplePrimSI3D/SumNB2_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nb * nb); + histos.fill(HIST("SubsamplePrimSI3D/SumNFNB_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nf * nb); + } + } + } + } + + void fillGenSubsampleDifferentialEtaPtPhiMoments(int isub, + EtaPtPhiArray const& nF, + EtaPtPhiArray const& nB) + { + if (isub < 0 || isub >= NSubsamplesMax) { + return; + } + + for (int igap = 0; igap < NEtaGaps; ++igap) { + const double gap = 2.0 * (etaCenter[igap] - cfgEtaWidth.value / 2.0); + for (int ipt = 0; ipt < NPtBins; ++ipt) { + const double ptCenter = 0.5 * (ptEdges[ipt] + ptEdges[ipt + 1]); + for (int iphi = 0; iphi < NPhiBins; ++iphi) { + const double phiCenter = (iphi + 0.5) * TwoPi / NPhiBins; + const double nf = nF[igap][ipt][iphi]; + const double nb = nB[igap][ipt][iphi]; + + histos.fill(HIST("SubsampleGenSI3D/EventCount_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, 1.0); + histos.fill(HIST("SubsampleGenSI3D/SumNF_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nf); + histos.fill(HIST("SubsampleGenSI3D/SumNB_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nb); + histos.fill(HIST("SubsampleGenSI3D/SumNF2_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nf * nf); + histos.fill(HIST("SubsampleGenSI3D/SumNB2_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nb * nb); + histos.fill(HIST("SubsampleGenSI3D/SumNFNB_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nf * nb); + } + } + } + } + + void fillSubsampleDifferentialEtaPtPhiMoments(int isub, + EtaPtPhiArray const& nF, + EtaPtPhiArray const& nB) + { + if (isub < 0 || isub >= NSubsamplesMax) { + return; + } + + for (int igap = 0; igap < NEtaGaps; ++igap) { + const double gap = 2.0 * (etaCenter[igap] - cfgEtaWidth.value / 2.0); + for (int ipt = 0; ipt < NPtBins; ++ipt) { + const double ptCenter = 0.5 * (ptEdges[ipt] + ptEdges[ipt + 1]); + for (int iphi = 0; iphi < NPhiBins; ++iphi) { + const double phiCenter = (iphi + 0.5) * TwoPi / NPhiBins; + const double nf = nF[igap][ipt][iphi]; + const double nb = nB[igap][ipt][iphi]; + + histos.fill(HIST("SubsampleSI3D/EventCount_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, 1.0); + histos.fill(HIST("SubsampleSI3D/SumNF_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nf); + histos.fill(HIST("SubsampleSI3D/SumNB_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nb); + histos.fill(HIST("SubsampleSI3D/SumNF2_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nf * nf); + histos.fill(HIST("SubsampleSI3D/SumNB2_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nb * nb); + histos.fill(HIST("SubsampleSI3D/SumNFNB_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nf * nb); + histos.fill(HIST("SubsampleSI3D/SumF20_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nf * (nf - 1.0)); + histos.fill(HIST("SubsampleSI3D/SumB20_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nb * (nb - 1.0)); + histos.fill(HIST("SubsampleSI3D/SumF11_sub_etaGapPtPhi"), isub, gap, ptCenter, phiCenter, nf * nb); + } + } + } + } + + template + void fillEventQABefore(C const& coll, float centBefore) + { + histos.fill(HIST("eventQA/before/vtxZ"), coll.posZ()); + histos.fill(HIST("eventQA/before/nPVeta1TracksVsCent"), centBefore, coll.multNTracksPVeta1()); + histos.fill(HIST("eventQA/before/nPVTracksVsCent"), centBefore, coll.multNTracksPV()); + histos.fill(HIST("eventQA/before/centFT0C"), coll.centFT0C()); + histos.fill(HIST("eventQA/before/centFT0M"), coll.centFT0M()); + histos.fill(HIST("eventQA/before/centFT0CvsFT0M"), coll.centFT0C(), coll.centFT0M()); + } + + template + void fillEventQAAfter(C const& coll, float cent) + { + histos.fill(HIST("eventQA/after/vtxZ"), coll.posZ()); + histos.fill(HIST("eventQA/after/nPVeta1TracksVsCent"), cent, coll.multNTracksPVeta1()); + histos.fill(HIST("eventQA/after/nPVTracksVsCent"), cent, coll.multNTracksPV()); + histos.fill(HIST("eventQA/after/centFT0C"), coll.centFT0C()); + histos.fill(HIST("eventQA/after/centFT0M"), coll.centFT0M()); + histos.fill(HIST("eventQA/after/centFT0CvsFT0M"), coll.centFT0C(), coll.centFT0M()); + } + + template + void fillAllFBOutputs(C const& coll, + float cent, + std::array const& nF, + std::array const& nB, + EtaPtPhiArray const& nFPtPhi, + EtaPtPhiArray const& nBPtPhi) + { + const int centClass = getCentClass(cent); + const int centWindowClass = getCentWindowClass(cent); + const int subsampleIndex = getSubsampleIndex(coll); + + histos.fill(HIST("QA/hCentrality"), cent); + fillFBQA(cent, nF, nB); + fillInclusiveEtaGapMoments(nF, nB); + fillCentClassEtaGapMoments(centClass, nF, nB); + fillCentWindowEtaGapMoments(centWindowClass, nF, nB); + fillSubsampleCentWindowEtaGapMoments(subsampleIndex, centWindowClass, nF, nB); + fillDifferentialEtaPtPhiMoments(nFPtPhi, nBPtPhi); + fillSubsampleDifferentialEtaPtPhiMoments(subsampleIndex, nFPtPhi, nBPtPhi); + } + + // ------------------------------------------------------------------ + // Data + // ------------------------------------------------------------------ + void processData(AodCollision const& coll, AodTracks const& tracks) + { + float cent = -999.0f; + const float centBefore = getCentrality(coll); + fillEventQABefore(coll, centBefore); + + if (!selCollision(coll, cent)) { + return; + } + fillEventQAAfter(coll, cent); + + std::array nF{}; + std::array nB{}; + EtaPtPhiArray nFPtPhi{}; + EtaPtPhiArray nBPtPhi{}; + + histos.fill(HIST("QA/hTrackSliceSize"), static_cast(tracks.size())); + + for (auto const& track : tracks) { + fillTrackQABefore(track); + if (!selTrack(track)) { + continue; + } + fillTrackQAAfter(track); + + addToFBCounters(track.eta(), track.pt(), track.phi(), nF, nB, nFPtPhi, nBPtPhi); + } + + fillAllFBOutputs(coll, cent, nF, nB, nFPtPhi, nBPtPhi); + } + PROCESS_SWITCH(StronglyIntensiveCorr, processData, "process real data", true); + + // ------------------------------------------------------------------ + // MC reconstructed: selected reco tracks with MC label. + // This is still reconstructed-level kinematics/cuts. + // ------------------------------------------------------------------ + void processMCRec(MyMCRecCollision const& coll, + MyMCTracks const& tracks, + aod::McParticles const&) + { + float cent = -999.0f; + const float centBefore = getCentrality(coll); + fillEventQABefore(coll, centBefore); + + if (!selCollision(coll, cent)) { + return; + } + fillEventQAAfter(coll, cent); + + std::array nF{}; + std::array nB{}; + EtaPtPhiArray nFPtPhi{}; + EtaPtPhiArray nBPtPhi{}; + int nRecoAll = 0; + int nRecoPrimary = 0; + int nRecoSecondary = 0; + int nRecoFake = 0; + + histos.fill(HIST("QA/hTrackSliceSize"), static_cast(tracks.size())); + + for (auto const& track : tracks) { + fillTrackQABefore(track); + + if (!selTrack(track)) { + continue; + } + + ++nRecoAll; + + if (!track.has_mcParticle()) { + ++nRecoFake; + continue; + } + + auto mcParticle = track.template mcParticle_as(); + + if (mcParticle.isPhysicalPrimary() && isChargedMCParticle(mcParticle.pdgCode())) { + ++nRecoPrimary; + } else { + ++nRecoSecondary; + } + + fillTrackQAAfter(track); + + addToFBCounters(track.eta(), track.pt(), track.phi(), nF, nB, nFPtPhi, nBPtPhi); + } + histos.fill(HIST("QA/mcReco/nRecoAll"), nRecoAll); + histos.fill(HIST("QA/mcReco/nRecoPrimary"), nRecoPrimary); + histos.fill(HIST("QA/mcReco/nRecoSecondary"), nRecoSecondary); + histos.fill(HIST("QA/mcReco/nRecoFake"), nRecoFake); + const int subsampleIndex = getSubsampleIndex(coll); + + // For MC running with all switches enabled, do not fill common SI histograms here. + // Keep Reco/Prim/Gen separated in multidimensional outputs. + fillRecoDifferentialEtaPtPhiMoments(nFPtPhi, nBPtPhi); + fillRecoSubsampleDifferentialEtaPtPhiMoments(subsampleIndex, nFPtPhi, nBPtPhi); + } + PROCESS_SWITCH(StronglyIntensiveCorr, processMCRec, "process MC reconstructed tracks", false); + + // ------------------------------------------------------------------ + // MC primary reconstructed: selected reco tracks matched to physical-primary charged MC particles. + // ------------------------------------------------------------------ + void processMCPrimaryReco(MyMCRecCollision const& coll, + MyMCTracks const& tracks, + aod::McParticles const&) + { + float cent = -999.0f; + const float centBefore = getCentrality(coll); + fillEventQABefore(coll, centBefore); + + if (!selCollision(coll, cent)) { + return; + } + fillEventQAAfter(coll, cent); + + std::array nF{}; + std::array nB{}; + EtaPtPhiArray nFPtPhi{}; + EtaPtPhiArray nBPtPhi{}; + + histos.fill(HIST("QA/hTrackSliceSize"), static_cast(tracks.size())); + + for (auto const& track : tracks) { + fillTrackQABefore(track); + if (!selTrack(track)) { + continue; + } + if (!track.has_mcParticle()) { + continue; + } + + auto mcParticle = track.template mcParticle_as(); + if (cfgUseOnlyPhysicalPrimary.value && !mcParticle.isPhysicalPrimary()) { + continue; + } + if (cfgUseOnlyChargedMC.value && !isChargedMCParticle(mcParticle.pdgCode())) { + continue; + } + + fillTrackQAAfter(track); + addToFBCounters(track.eta(), track.pt(), track.phi(), nF, nB, nFPtPhi, nBPtPhi); + } + + const int subsampleIndex = getSubsampleIndex(coll); + + // For MC running with all switches enabled, do not fill common SI histograms here. + // Keep Reco/Prim/Gen separated in multidimensional outputs. + fillPrimDifferentialEtaPtPhiMoments(nFPtPhi, nBPtPhi); + fillPrimSubsampleDifferentialEtaPtPhiMoments(subsampleIndex, nFPtPhi, nBPtPhi); + } + PROCESS_SWITCH(StronglyIntensiveCorr, processMCPrimaryReco, "process MC primary reconstructed tracks", false); + + // ------------------------------------------------------------------ + // MC generated: generator-level charged physical primaries from aod::McParticles. + // Uses reconstructed collision only to get event selection + centrality and then maps to mcCollisionId. + // ------------------------------------------------------------------ + void processMCGenerated(MyMCRecCollision const& coll, + aod::McParticles const& mcParticles) + { + if (!coll.has_mcCollision()) { + return; + } + + float cent = -999.0f; + const float centBefore = getCentrality(coll); + fillEventQABefore(coll, centBefore); + + if (!selCollision(coll, cent)) { + return; + } + fillEventQAAfter(coll, cent); + + std::array nF{}; + std::array nB{}; + EtaPtPhiArray nFPtPhi{}; + EtaPtPhiArray nBPtPhi{}; + + auto particlesThisCollision = mcParticles.sliceBy(perMcCollision, coll.mcCollisionId()); + + for (auto const& particle : particlesThisCollision) { + if (!selMCParticle(particle)) { + continue; + } + addToFBCounters(particle.eta(), particle.pt(), particle.phi(), nF, nB, nFPtPhi, nBPtPhi); + } + + const int subsampleIndex = getSubsampleIndex(coll); + + // For MC running with all switches enabled, do not fill common SI histograms here. + // Keep Reco/Prim/Gen separated in multidimensional outputs. + fillGenDifferentialEtaPtPhiMoments(nFPtPhi, nBPtPhi); + fillGenSubsampleDifferentialEtaPtPhiMoments(subsampleIndex, nFPtPhi, nBPtPhi); + } + PROCESS_SWITCH(StronglyIntensiveCorr, processMCGenerated, "process MC generated particles", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx b/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx index 701dd2d8eaa..cad391d55a1 100644 --- a/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx @@ -103,6 +103,7 @@ struct V0ptHadPiKaProt { }; Configurable cfgIsMC{"cfgIsMC", false, "Run MC"}; + Configurable cfgMcClosure{"cfgMcClosure", false, "Calculate v0(pT) at Gen and Rec level to check Mc Closure"}; Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgCutTpcChi2NCl{"cfgCutTpcChi2NCl", 2.5f, "Maximum TPCchi2NCl"}; Configurable cfgCutItsChi2NCl{"cfgCutItsChi2NCl", 36.0f, "Maximum ITSchi2NCl"}; @@ -115,8 +116,7 @@ struct V0ptHadPiKaProt { Configurable cfgnSigmaCutTPC{"cfgnSigmaCutTPC", 2.0f, "PID nSigma cut for TPC"}; Configurable cfgnSigmaCutTOF{"cfgnSigmaCutTOF", 2.0f, "PID nSigma cut for TOF"}; Configurable cfgUseNewSeperationPid{"cfgUseNewSeperationPid", false, "Use seperation based PID cuts (NEW)"}; - Configurable cfgnSigmaCutTPCHigherPt{"cfgnSigmaCutTPCHigherPt", 2.0f, "PID nSigma cut for TPC at higher pt"}; - Configurable cfgnSigmaCutTOFHigherPt{"cfgnSigmaCutTOFHigherPt", 2.0f, "PID nSigma cut for TOF at higher pt"}; + Configurable cfgnSigmaCutTPCorTOFHigherPt{"cfgnSigmaCutTPCorTOFHigherPt", 2.0f, "PID nSigma cut for TPC at higher pt"}; Configurable cfgnSigmaSeperationCut{"cfgnSigmaSeperationCut", 3.5f, "PID nSigma of other species must be greater than the vale"}; Configurable cfgnSigmaCutCombTPCTOF{"cfgnSigmaCutCombTPCTOF", 2.0f, "PID nSigma combined cut for TPC and TOF"}; ConfigurableAxis nchAxis{"nchAxis", {5000, 0.5, 5000.5}, ""}; @@ -157,6 +157,7 @@ struct V0ptHadPiKaProt { Configurable cfgV02WeightedFill{"cfgV02WeightedFill", false, "Fill profiles related to v2 with multiplicity-based weights?"}; Configurable cfgV02WeightedOption3Fill{"cfgV02WeightedOption3Fill", false, "Fill profiles related to v2 with multiplicity-based weights according to Option3, triplet weighting for "}; Configurable cfgUseDominanceCut{"cfgUseDominanceCut", true, "Require particle selecting species' nSigma to be smallest among other two"}; + Configurable cfgUseSeperationCutLowPt{"cfgUseSeperationCutLowPt", false, "Use separation cut for low pT"}; // pT dep DCAxy and DCAz cuts Configurable cfgUsePtDepDCAxy{"cfgUsePtDepDCAxy", true, "Use pt-dependent DCAxy cut"}; @@ -207,11 +208,16 @@ struct V0ptHadPiKaProt { // Output HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry histosAnalysis{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry histosAnalysis{"HistosAnalysis", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry histosMc{"HistosMc", {}, OutputObjHandlingPolicy::AnalysisObject}; + std::vector>> subSample; std::vector>> subSampleV02; std::vector>> subSampleV02weighted; std::vector>> subSampleV02weightedOption3; + std::vector>> subSampleMcGen; + std::vector>> subSampleMcRecRaw; + std::vector>> subSampleMcRecCorr; TRandom3* funRndm = new TRandom3(0); // Phi weight histograms initialization @@ -373,6 +379,11 @@ struct V0ptHadPiKaProt { histos.add("h2DnsigmaPionTofVsPtAfterCut", "2D hist of nSigmaTOF vs. pT (pion)", kTH2F, {ptAxis, nSigmaAxis}); histos.add("h2DnsigmaKaonTofVsPtAfterCut", "2D hist of nSigmaTOF vs. pT (kaon)", kTH2F, {ptAxis, nSigmaAxis}); histos.add("h2DnsigmaProtonTofVsPtAfterCut", "2D hist of nSigmaTOF vs. pT (proton)", kTH2F, {ptAxis, nSigmaAxis}); + + histos.add("h2DnsigmaPionTpcVsTofInterimCut", "3D hist of nSigmaTPC vs. nSigmaTOF (pion)", kTH3F, {ptAxis, nSigmaAxis, nSigmaAxis}); + histos.add("h2DnsigmaKaonTpcVsTofInterimCut", "3D hist of nSigmaTPC vs. nSigmaTOF (kaon)", kTH3F, {ptAxis, nSigmaAxis, nSigmaAxis}); + histos.add("h2DnsigmaProtonTpcVsTofInterimCut", "3D hist of nSigmaTPC vs. nSigmaTOF (proton)", kTH3F, {ptAxis, nSigmaAxis, nSigmaAxis}); + histos.add("h2DnsigmaPionTpcVsTofAfterCut", "3D hist of nSigmaTPC vs. nSigmaTOF (pion)", kTH3F, {ptAxis, nSigmaAxis, nSigmaAxis}); histos.add("h2DnsigmaKaonTpcVsTofAfterCut", "3D hist of nSigmaTPC vs. nSigmaTOF (kaon)", kTH3F, {ptAxis, nSigmaAxis, nSigmaAxis}); histos.add("h2DnsigmaProtonTpcVsTofAfterCut", "3D hist of nSigmaTPC vs. nSigmaTOF (proton)", kTH3F, {ptAxis, nSigmaAxis, nSigmaAxis}); @@ -382,64 +393,146 @@ struct V0ptHadPiKaProt { // Analysis profiles - histos.add("Prof_A_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_C_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_D_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); - histos.add("Prof_Bone_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); - histos.add("Prof_Btwo_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); - - histos.add("Prof_A_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_C_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_D_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); - histos.add("Prof_Bone_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); - histos.add("Prof_Btwo_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); - - histos.add("Prof_A_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_C_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_D_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); - histos.add("Prof_Bone_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); - histos.add("Prof_Btwo_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); - - histos.add("Prof_A_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_C_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_D_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); - histos.add("Prof_Bone_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); - histos.add("Prof_Btwo_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + // v0(pT) analysis for data + if (!cfgIsMC) { + histos.add("Prof_A_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_C_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_D_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("Prof_Bone_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("Prof_Btwo_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + + histos.add("Prof_A_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_C_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_D_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("Prof_Bone_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("Prof_Btwo_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + + histos.add("Prof_A_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_C_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_D_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("Prof_Bone_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("Prof_Btwo_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + + histos.add("Prof_A_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_C_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_D_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("Prof_Bone_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("Prof_Btwo_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + } + if (cfgIsMC && cfgMcClosure) { + + // v0(pT) analysis for MC generated + histos.add("McClosure/Generated/Prof_A_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("McClosure/Generated/Prof_C_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("McClosure/Generated/Prof_D_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("McClosure/Generated/Prof_Bone_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("McClosure/Generated/Prof_Btwo_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + + histos.add("McClosure/Generated/Prof_A_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("McClosure/Generated/Prof_C_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("McClosure/Generated/Prof_D_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("McClosure/Generated/Prof_Bone_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("McClosure/Generated/Prof_Btwo_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + + histos.add("McClosure/Generated/Prof_A_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("McClosure/Generated/Prof_C_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("McClosure/Generated/Prof_D_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("McClosure/Generated/Prof_Bone_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("McClosure/Generated/Prof_Btwo_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + + histos.add("McClosure/Generated/Prof_A_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("McClosure/Generated/Prof_C_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("McClosure/Generated/Prof_D_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("McClosure/Generated/Prof_Bone_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("McClosure/Generated/Prof_Btwo_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + + // v0(pT) analysis for MC reconstructed efficiency raw + histosMc.add("McClosure/Reconstructed/Raw/Prof_A_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_C_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_D_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_Bone_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_Btwo_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + + histosMc.add("McClosure/Reconstructed/Raw/Prof_A_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_C_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_D_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_Bone_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_Btwo_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + + histosMc.add("McClosure/Reconstructed/Raw/Prof_A_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_C_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_D_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_Bone_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_Btwo_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + + histosMc.add("McClosure/Reconstructed/Raw/Prof_A_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_C_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_D_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_Bone_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Raw/Prof_Btwo_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + + // v0(pT) analysis for MC reconstructed efficiency corrected + histosMc.add("McClosure/Reconstructed/Corr/Prof_A_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_C_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_D_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_Bone_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_Btwo_had", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + + histosMc.add("McClosure/Reconstructed/Corr/Prof_A_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_C_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_D_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_Bone_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_Btwo_pi", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + + histosMc.add("McClosure/Reconstructed/Corr/Prof_A_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_C_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_D_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_Bone_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_Btwo_ka", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + + histosMc.add("McClosure/Reconstructed/Corr/Prof_A_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_C_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_D_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_Bone_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histosMc.add("McClosure/Reconstructed/Corr/Prof_Btwo_prot", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + } // Analysis profile for v02(pT) - histos.add("Prof_XY", "", {HistType::kTProfile2D, {centAxis, noAxis}}); - histos.add("Prof_XYZ_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_Z_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_XYZ_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_Z_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_XYZ_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_Z_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_XYZ_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_Z_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - - // check with different normalization for event averaging - if (cfgV02WeightedFill) { - histos.add("Prof_XY_weighted", "", {HistType::kTProfile2D, {centAxis, noAxis}}); - histos.add("Prof_XYZ_weighted_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_Z_weighted_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_XYZ_weighted_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_Z_weighted_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_XYZ_weighted_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_Z_weighted_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_XYZ_weighted_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_Z_weighted_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - } + if (!cfgIsMC) { + histos.add("Prof_XY", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("Prof_XYZ_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_Z_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_XYZ_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_Z_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_XYZ_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_Z_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_XYZ_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_Z_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + + // check with different normalization for event averaging + if (cfgV02WeightedFill) { + histos.add("Prof_XY_weighted", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("Prof_XYZ_weighted_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_Z_weighted_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_XYZ_weighted_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_Z_weighted_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_XYZ_weighted_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_Z_weighted_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_XYZ_weighted_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_Z_weighted_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + } - if (cfgV02WeightedOption3Fill) { - histos.add("Prof_XY_weightedOption3", "", {HistType::kTProfile2D, {centAxis, noAxis}}); - histos.add("Prof_XYZ_weightedOption3_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_Z_weightedOption3_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_XYZ_weightedOption3_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_Z_weightedOption3_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_XYZ_weightedOption3_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_Z_weightedOption3_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_XYZ_weightedOption3_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); - histos.add("Prof_Z_weightedOption3_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + if (cfgV02WeightedOption3Fill) { + histos.add("Prof_XY_weightedOption3", "", {HistType::kTProfile2D, {centAxis, noAxis}}); + histos.add("Prof_XYZ_weightedOption3_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_Z_weightedOption3_had", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_XYZ_weightedOption3_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_Z_weightedOption3_pi", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_XYZ_weightedOption3_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_Z_weightedOption3_ka", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_XYZ_weightedOption3_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + histos.add("Prof_Z_weightedOption3_prot", "", {HistType::kTProfile2D, {centAxis, ptAxis}}); + } } // initial array @@ -447,69 +540,163 @@ struct V0ptHadPiKaProt { subSampleV02.resize(cfgNSubsample); subSampleV02weighted.resize(cfgNSubsample); subSampleV02weightedOption3.resize(cfgNSubsample); + if (cfgIsMC && cfgMcClosure) { + subSampleMcGen.resize(cfgNSubsample); + subSampleMcRecRaw.resize(cfgNSubsample); + subSampleMcRecCorr.resize(cfgNSubsample); + } + for (int i = 0; i < cfgNSubsample; i++) { subSample[i].resize(20); subSampleV02[i].resize(9); subSampleV02weighted[i].resize(9); subSampleV02weightedOption3[i].resize(9); + + if (cfgIsMC && cfgMcClosure) { + subSampleMcGen[i].resize(20); + subSampleMcRecRaw[i].resize(20); + subSampleMcRecCorr[i].resize(20); + } } for (int i = 0; i < cfgNSubsample; i++) { - subSample[i][0] = std::get>(histos.add(Form("subSample_%d/Prof_A_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSample[i][1] = std::get>(histos.add(Form("subSample_%d/Prof_C_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSample[i][2] = std::get>(histos.add(Form("subSample_%d/Prof_D_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - subSample[i][3] = std::get>(histos.add(Form("subSample_%d/Prof_Bone_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - subSample[i][4] = std::get>(histos.add(Form("subSample_%d/Prof_Btwo_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - - subSample[i][5] = std::get>(histos.add(Form("subSample_%d/Prof_A_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSample[i][6] = std::get>(histos.add(Form("subSample_%d/Prof_C_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSample[i][7] = std::get>(histos.add(Form("subSample_%d/Prof_D_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - subSample[i][8] = std::get>(histos.add(Form("subSample_%d/Prof_Bone_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - subSample[i][9] = std::get>(histos.add(Form("subSample_%d/Prof_Btwo_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - - subSample[i][10] = std::get>(histos.add(Form("subSample_%d/Prof_A_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSample[i][11] = std::get>(histos.add(Form("subSample_%d/Prof_C_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSample[i][12] = std::get>(histos.add(Form("subSample_%d/Prof_D_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - subSample[i][13] = std::get>(histos.add(Form("subSample_%d/Prof_Bone_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - subSample[i][14] = std::get>(histos.add(Form("subSample_%d/Prof_Btwo_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - - subSample[i][15] = std::get>(histos.add(Form("subSample_%d/Prof_A_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSample[i][16] = std::get>(histos.add(Form("subSample_%d/Prof_C_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSample[i][17] = std::get>(histos.add(Form("subSample_%d/Prof_D_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - subSample[i][18] = std::get>(histos.add(Form("subSample_%d/Prof_Bone_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - subSample[i][19] = std::get>(histos.add(Form("subSample_%d/Prof_Btwo_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - - subSampleV02[i][0] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_XY", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - subSampleV02[i][1] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_XYZ_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02[i][2] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_Z_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02[i][3] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_XYZ_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02[i][4] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_Z_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02[i][5] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_XYZ_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02[i][6] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_Z_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02[i][7] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_XYZ_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02[i][8] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_Z_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - if (cfgV02WeightedFill) { - subSampleV02weighted[i][0] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_XY_weighted", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - subSampleV02weighted[i][1] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_XYZ_weighted_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02weighted[i][2] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_Z_weighted_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02weighted[i][3] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_XYZ_weighted_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02weighted[i][4] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_Z_weighted_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02weighted[i][5] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_XYZ_weighted_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02weighted[i][6] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_Z_weighted_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02weighted[i][7] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_XYZ_weighted_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02weighted[i][8] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_Z_weighted_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - } + if (!cfgIsMC) { + subSample[i][0] = std::get>(histos.add(Form("subSample_%d/Prof_A_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSample[i][1] = std::get>(histos.add(Form("subSample_%d/Prof_C_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSample[i][2] = std::get>(histos.add(Form("subSample_%d/Prof_D_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSample[i][3] = std::get>(histos.add(Form("subSample_%d/Prof_Bone_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSample[i][4] = std::get>(histos.add(Form("subSample_%d/Prof_Btwo_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + + subSample[i][5] = std::get>(histos.add(Form("subSample_%d/Prof_A_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSample[i][6] = std::get>(histos.add(Form("subSample_%d/Prof_C_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSample[i][7] = std::get>(histos.add(Form("subSample_%d/Prof_D_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSample[i][8] = std::get>(histos.add(Form("subSample_%d/Prof_Bone_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSample[i][9] = std::get>(histos.add(Form("subSample_%d/Prof_Btwo_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + + subSample[i][10] = std::get>(histos.add(Form("subSample_%d/Prof_A_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSample[i][11] = std::get>(histos.add(Form("subSample_%d/Prof_C_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSample[i][12] = std::get>(histos.add(Form("subSample_%d/Prof_D_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSample[i][13] = std::get>(histos.add(Form("subSample_%d/Prof_Bone_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSample[i][14] = std::get>(histos.add(Form("subSample_%d/Prof_Btwo_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + + subSample[i][15] = std::get>(histos.add(Form("subSample_%d/Prof_A_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSample[i][16] = std::get>(histos.add(Form("subSample_%d/Prof_C_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSample[i][17] = std::get>(histos.add(Form("subSample_%d/Prof_D_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSample[i][18] = std::get>(histos.add(Form("subSample_%d/Prof_Bone_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSample[i][19] = std::get>(histos.add(Form("subSample_%d/Prof_Btwo_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + } + + if (cfgIsMC && cfgMcClosure) { + // generated + subSampleMcGen[i][0] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_A_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcGen[i][1] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_C_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcGen[i][2] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_D_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcGen[i][3] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_Bone_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcGen[i][4] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_Btwo_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + + subSampleMcGen[i][5] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_A_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcGen[i][6] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_C_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcGen[i][7] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_D_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcGen[i][8] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_Bone_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcGen[i][9] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_Btwo_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + + subSampleMcGen[i][10] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_A_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcGen[i][11] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_C_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcGen[i][12] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_D_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcGen[i][13] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_Bone_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcGen[i][14] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_Btwo_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + + subSampleMcGen[i][15] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_A_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcGen[i][16] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_C_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcGen[i][17] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_D_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcGen[i][18] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_Bone_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcGen[i][19] = std::get>(histos.add(Form("McClosure/Generated/subSample_%d/Prof_Btwo_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + + // reconstruced/Raw + subSampleMcRecRaw[i][0] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_A_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecRaw[i][1] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_C_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecRaw[i][2] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_D_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecRaw[i][3] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_Bone_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecRaw[i][4] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_Btwo_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + + subSampleMcRecRaw[i][5] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_A_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecRaw[i][6] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_C_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecRaw[i][7] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_D_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecRaw[i][8] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_Bone_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecRaw[i][9] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_Btwo_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + + subSampleMcRecRaw[i][10] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_A_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecRaw[i][11] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_C_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecRaw[i][12] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_D_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecRaw[i][13] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_Bone_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecRaw[i][14] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_Btwo_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + + subSampleMcRecRaw[i][15] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_A_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecRaw[i][16] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_C_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecRaw[i][17] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_D_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecRaw[i][18] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_Bone_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecRaw[i][19] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Raw/subSample_%d/Prof_Btwo_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + + // reconstruced/Corr + subSampleMcRecCorr[i][0] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_A_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecCorr[i][1] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_C_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecCorr[i][2] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_D_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecCorr[i][3] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_Bone_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecCorr[i][4] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_Btwo_had", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + + subSampleMcRecCorr[i][5] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_A_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecCorr[i][6] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_C_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecCorr[i][7] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_D_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecCorr[i][8] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_Bone_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecCorr[i][9] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_Btwo_pi", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + + subSampleMcRecCorr[i][10] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_A_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecCorr[i][11] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_C_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecCorr[i][12] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_D_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecCorr[i][13] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_Bone_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecCorr[i][14] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_Btwo_ka", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + + subSampleMcRecCorr[i][15] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_A_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecCorr[i][16] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_C_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleMcRecCorr[i][17] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_D_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecCorr[i][18] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_Bone_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleMcRecCorr[i][19] = std::get>(histosMc.add(Form("McClosure/Reconstructed/Corr/subSample_%d/Prof_Btwo_prot", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + } + + if (!cfgIsMC) { + subSampleV02[i][0] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_XY", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleV02[i][1] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_XYZ_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02[i][2] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_Z_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02[i][3] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_XYZ_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02[i][4] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_Z_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02[i][5] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_XYZ_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02[i][6] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_Z_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02[i][7] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_XYZ_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02[i][8] = std::get>(histosAnalysis.add(Form("subSampleV02_%d/Prof_Z_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - if (cfgV02WeightedOption3Fill) { - subSampleV02weightedOption3[i][0] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_XY_weightedOption3", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); - subSampleV02weightedOption3[i][1] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_XYZ_weightedOption3_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02weightedOption3[i][2] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_Z_weightedOption3_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02weightedOption3[i][3] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_XYZ_weightedOption3_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02weightedOption3[i][4] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_Z_weightedOption3_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02weightedOption3[i][5] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_XYZ_weightedOption3_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02weightedOption3[i][6] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_Z_weightedOption3_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02weightedOption3[i][7] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_XYZ_weightedOption3_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); - subSampleV02weightedOption3[i][8] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_Z_weightedOption3_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + if (cfgV02WeightedFill) { + subSampleV02weighted[i][0] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_XY_weighted", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleV02weighted[i][1] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_XYZ_weighted_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02weighted[i][2] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_Z_weighted_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02weighted[i][3] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_XYZ_weighted_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02weighted[i][4] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_Z_weighted_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02weighted[i][5] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_XYZ_weighted_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02weighted[i][6] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_Z_weighted_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02weighted[i][7] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_XYZ_weighted_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02weighted[i][8] = std::get>(histosAnalysis.add(Form("subSampleV02weighted_%d/Prof_Z_weighted_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + } + + if (cfgV02WeightedOption3Fill) { + subSampleV02weightedOption3[i][0] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_XY_weightedOption3", i), "", {HistType::kTProfile2D, {centAxis, noAxis}})); + subSampleV02weightedOption3[i][1] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_XYZ_weightedOption3_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02weightedOption3[i][2] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_Z_weightedOption3_had", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02weightedOption3[i][3] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_XYZ_weightedOption3_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02weightedOption3[i][4] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_Z_weightedOption3_pi", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02weightedOption3[i][5] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_XYZ_weightedOption3_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02weightedOption3[i][6] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_Z_weightedOption3_ka", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02weightedOption3[i][7] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_XYZ_weightedOption3_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + subSampleV02weightedOption3[i][8] = std::get>(histosAnalysis.add(Form("subSampleV02weightedOption3_%d/Prof_Z_weightedOption3_prot", i), "", {HistType::kTProfile2D, {centAxis, ptAxis}})); + } } } @@ -599,11 +786,17 @@ struct V0ptHadPiKaProt { partNsigmaTpcOrItsPr = candidate.tpcNSigmaPr(); } + bool separatedFromOthers = true; + if (cfgUseSeperationCutLowPt) { + separatedFromOthers = std::abs(partNsigmaTpcOrItsPi) > cfgnSigmaSeperationCut && std::abs(partNsigmaTpcOrItsKa) > cfgnSigmaSeperationCut; + } + if (candidate.pt() > cfgCutPtLower && candidate.pt() <= cfgCutPtUpperTPC) { - if (!candidate.hasTOF() && std::abs(partNsigmaTpcOrItsPr) < cfgnSigmaCutTPC) { + + if (!candidate.hasTOF() && std::abs(partNsigmaTpcOrItsPr) < cfgnSigmaCutTPC && separatedFromOthers) { flag = 1; } - if (candidate.hasTOF() && std::abs(partNsigmaTpcOrItsPr) < cfgnSigmaCutTPC && std::abs(candidate.tofNSigmaPr()) < cfgnSigmaCutTOF) { + if (candidate.hasTOF() && std::abs(partNsigmaTpcOrItsPr) < cfgnSigmaCutTPC && std::abs(candidate.tofNSigmaPr()) < cfgnSigmaCutTOF && separatedFromOthers) { flag = 1; } } @@ -621,7 +814,7 @@ struct V0ptHadPiKaProt { flag2 += 1; if (cfgUseNewSeperationPid) { - if (std::abs(partNsigmaTpcOrItsPr) < cfgnSigmaCutTPCHigherPt && std::abs(candidate.tofNSigmaPr()) < cfgnSigmaCutTOFHigherPt) { + if (std::abs(partNsigmaTpcOrItsPr) < cfgnSigmaCutTPCorTOFHigherPt && std::abs(candidate.tofNSigmaPr()) < cfgnSigmaCutTPCorTOFHigherPt) { if (!(flag2 > 1) && std::abs(partNsigmaTpcOrItsPi) > cfgnSigmaSeperationCut && std::abs(candidate.tofNSigmaPi()) > cfgnSigmaSeperationCut && std::abs(partNsigmaTpcOrItsKa) > cfgnSigmaSeperationCut && std::abs(candidate.tofNSigmaKa()) > cfgnSigmaSeperationCut) flag = 1; } @@ -634,6 +827,8 @@ struct V0ptHadPiKaProt { } if (!(flag2 > 1) && passDominance) { + histos.fill(HIST("h2DnsigmaProtonTpcVsTofInterimCut"), candidate.pt(), candidate.tpcNSigmaPr(), candidate.tofNSigmaPr()); + if (combNSigmaPr < cfgnSigmaCutCombTPCTOF) { flag = 1; } @@ -666,11 +861,17 @@ struct V0ptHadPiKaProt { partNsigmaTpcOrItsPr = candidate.tpcNSigmaPr(); } + bool separatedFromOthers = true; + if (cfgUseSeperationCutLowPt) { + separatedFromOthers = std::abs(partNsigmaTpcOrItsKa) > cfgnSigmaSeperationCut && std::abs(partNsigmaTpcOrItsPr) > cfgnSigmaSeperationCut; + } + if (candidate.pt() > cfgCutPtLower && candidate.pt() <= cfgCutPtUpperTPC) { - if (!candidate.hasTOF() && std::abs(partNsigmaTpcOrItsPi) < cfgnSigmaCutTPC) { + + if (!candidate.hasTOF() && std::abs(partNsigmaTpcOrItsPi) < cfgnSigmaCutTPC && separatedFromOthers) { flag = 1; } - if (candidate.hasTOF() && std::abs(partNsigmaTpcOrItsPi) < cfgnSigmaCutTPC && std::abs(candidate.tofNSigmaPi()) < cfgnSigmaCutTOF) { + if (candidate.hasTOF() && std::abs(partNsigmaTpcOrItsPi) < cfgnSigmaCutTPC && std::abs(candidate.tofNSigmaPi()) < cfgnSigmaCutTOF && separatedFromOthers) { flag = 1; } } @@ -688,7 +889,7 @@ struct V0ptHadPiKaProt { flag2 += 1; if (cfgUseNewSeperationPid) { - if (std::abs(partNsigmaTpcOrItsPi) < cfgnSigmaCutTPCHigherPt && std::abs(candidate.tofNSigmaPi()) < cfgnSigmaCutTOFHigherPt) { + if (std::abs(partNsigmaTpcOrItsPi) < cfgnSigmaCutTPCorTOFHigherPt && std::abs(candidate.tofNSigmaPi()) < cfgnSigmaCutTPCorTOFHigherPt) { if (!(flag2 > 1) && std::abs(partNsigmaTpcOrItsKa) > cfgnSigmaSeperationCut && std::abs(candidate.tofNSigmaKa()) > cfgnSigmaSeperationCut && std::abs(partNsigmaTpcOrItsPr) > cfgnSigmaSeperationCut && std::abs(candidate.tofNSigmaPr()) > cfgnSigmaSeperationCut) flag = 1; } @@ -701,6 +902,7 @@ struct V0ptHadPiKaProt { } if (!(flag2 > 1) && passDominance) { + histos.fill(HIST("h2DnsigmaPionTpcVsTofInterimCut"), candidate.pt(), candidate.tpcNSigmaPi(), candidate.tofNSigmaPi()); if (combNSigmaPi < cfgnSigmaCutCombTPCTOF) { flag = 1; } @@ -733,11 +935,17 @@ struct V0ptHadPiKaProt { partNsigmaTpcOrItsPr = candidate.tpcNSigmaPr(); } + bool separatedFromOthers = true; + if (cfgUseSeperationCutLowPt) { + separatedFromOthers = std::abs(partNsigmaTpcOrItsPi) > cfgnSigmaSeperationCut && std::abs(partNsigmaTpcOrItsPr) > cfgnSigmaSeperationCut; + } + if (candidate.pt() > cfgCutPtLower && candidate.pt() <= cfgCutPtUpperTPC) { - if (!candidate.hasTOF() && std::abs(partNsigmaTpcOrItsKa) < cfgnSigmaCutTPC) { + + if (!candidate.hasTOF() && std::abs(partNsigmaTpcOrItsKa) < cfgnSigmaCutTPC && separatedFromOthers) { flag = 1; } - if (candidate.hasTOF() && std::abs(partNsigmaTpcOrItsKa) < cfgnSigmaCutTPC && std::abs(candidate.tofNSigmaKa()) < cfgnSigmaCutTOF) { + if (candidate.hasTOF() && std::abs(partNsigmaTpcOrItsKa) < cfgnSigmaCutTPC && std::abs(candidate.tofNSigmaKa()) < cfgnSigmaCutTOF && separatedFromOthers) { flag = 1; } } @@ -755,7 +963,7 @@ struct V0ptHadPiKaProt { flag2 += 1; if (cfgUseNewSeperationPid) { - if (std::abs(partNsigmaTpcOrItsKa) < cfgnSigmaCutTPCHigherPt && std::abs(candidate.tofNSigmaKa()) < cfgnSigmaCutTOFHigherPt) { + if (std::abs(partNsigmaTpcOrItsKa) < cfgnSigmaCutTPCorTOFHigherPt && std::abs(candidate.tofNSigmaKa()) < cfgnSigmaCutTPCorTOFHigherPt) { if (!(flag2 > 1) && std::abs(partNsigmaTpcOrItsPi) > cfgnSigmaSeperationCut && std::abs(candidate.tofNSigmaPi()) > cfgnSigmaSeperationCut && std::abs(partNsigmaTpcOrItsPr) > cfgnSigmaSeperationCut && std::abs(candidate.tofNSigmaPr()) > cfgnSigmaSeperationCut) flag = 1; } @@ -768,6 +976,7 @@ struct V0ptHadPiKaProt { } if (!(flag2 > 1) && passDominance) { + histos.fill(HIST("h2DnsigmaKaonTpcVsTofInterimCut"), candidate.pt(), candidate.tpcNSigmaKa(), candidate.tofNSigmaKa()); if (combNSigmaKa < cfgnSigmaCutCombTPCTOF) { flag = 1; } @@ -1091,6 +1300,22 @@ struct V0ptHadPiKaProt { histos.fill(HIST("MCGenerated/hMC"), 4.5); histos.fill(HIST("MCGenerated/hCentgen"), cent); + // initialization of generated level variables for MCclosure + int nbinsHad = 20; + int nbinsPid = 18; + double binsarray[21] = {0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.5, 4.0, 5.0, 6.0, 8.0, 10.0}; + TH1D* fPtProfileHadMcGen = new TH1D("fPtProfileHadMcGen", "fPtProfileHadMcGen", 20, binsarray); + TH1D* fPtProfilePiMcGen = new TH1D("fPtProfilePiMcGen", "fPtProfilePiMcGen", 20, binsarray); + TH1D* fPtProfileKaMcGen = new TH1D("fPtProfileKaMcGen", "fPtProfileKaMcGen", 20, binsarray); + TH1D* fPtProfileProtMcGen = new TH1D("fPtProfileProtMcGen", "fPtProfileProtMcGen", 20, binsarray); + double pTsumEtaLeftHadMcGen = 0.0; + double nSumEtaLeftHadMcGen = 0.0; + double pTsumEtaRightHadMcGen = 0.0; + double nSumEtaRightHadMcGen = 0.0; + double nSumEtaLeftPiMcGen = 0.0; + double nSumEtaLeftKaMcGen = 0.0; + double nSumEtaLeftProtMcGen = 0.0; + // creating phi, pt, eta dstribution of generted MC particles // Generated track variables @@ -1119,9 +1344,122 @@ struct V0ptHadPiKaProt { if (pdgcode == PDG_t::kProton) histos.fill(HIST("MCGenerated/hPtEtaPhiProton_gen"), mcParticle.pt(), mcParticle.eta(), mcParticle.phi()); + + if (cfgMcClosure) { + double trkPt = mcParticle.pt(); + double trkEta = mcParticle.eta(); + + // generated (true) + double effweight = 1.0; + double effweightPion = 1.0; + double effweightKaon = 1.0; + double effweightProton = 1.0; + + if (trkEta < cfgCutEtaLeft) { + fPtProfileHadMcGen->Fill(trkPt); + pTsumEtaLeftHadMcGen += trkPt * effweight; + nSumEtaLeftHadMcGen += effweight; + } + if (trkEta > cfgCutEtaRight) { + pTsumEtaRightHadMcGen += trkPt * effweight; + nSumEtaRightHadMcGen += effweight; + } + + if (trkPt < cfgCutPtUpperPID) { + if (trkEta < cfgCutEtaLeft) { + if (pdgcode == PDG_t::kPiPlus) { + fPtProfilePiMcGen->Fill(trkPt, effweightPion); + nSumEtaLeftPiMcGen += effweightPion; + } + if (pdgcode == PDG_t::kKPlus) { + fPtProfileKaMcGen->Fill(trkPt, effweightKaon); + nSumEtaLeftKaMcGen += effweightKaon; + } + if (pdgcode == PDG_t::kProton && trkPt > cfgCutPtLowerProt) { + fPtProfileProtMcGen->Fill(trkPt, effweightProton); + nSumEtaLeftProtMcGen += effweightProton; + } + } + } + } // end of if(cfgMcClosure) } } } //! end particle loop + + if (cfgMcClosure) { + // selecting subsample and filling profiles + float lRandom = funRndm->Rndm(); + int sampleIndex = static_cast(cfgNSubsample * lRandom); + + // MC generated + if (nSumEtaRightHadMcGen > 0 && nSumEtaLeftHadMcGen > 0) { + for (int i = 0; i < nbinsHad; i++) { + histos.get(HIST("McClosure/Generated/Prof_A_had"))->Fill(cent, fPtProfileHadMcGen->GetBinCenter(i + 1), (fPtProfileHadMcGen->GetBinContent(i + 1) / nSumEtaLeftHadMcGen)); + histos.get(HIST("McClosure/Generated/Prof_C_had"))->Fill(cent, fPtProfileHadMcGen->GetBinCenter(i + 1), ((fPtProfileHadMcGen->GetBinContent(i + 1) / nSumEtaLeftHadMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + histos.get(HIST("McClosure/Generated/Prof_Bone_had"))->Fill(cent, 0.5, (pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen)); + histos.get(HIST("McClosure/Generated/Prof_Btwo_had"))->Fill(cent, 0.5, (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen)); + histos.get(HIST("McClosure/Generated/Prof_D_had"))->Fill(cent, 0.5, ((pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + + subSampleMcGen[sampleIndex][0]->Fill(cent, fPtProfileHadMcGen->GetBinCenter(i + 1), (fPtProfileHadMcGen->GetBinContent(i + 1) / nSumEtaLeftHadMcGen)); + subSampleMcGen[sampleIndex][1]->Fill(cent, fPtProfileHadMcGen->GetBinCenter(i + 1), ((fPtProfileHadMcGen->GetBinContent(i + 1) / nSumEtaLeftHadMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + subSampleMcGen[sampleIndex][2]->Fill(cent, 0.5, ((pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + subSampleMcGen[sampleIndex][3]->Fill(cent, 0.5, (pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen)); + subSampleMcGen[sampleIndex][4]->Fill(cent, 0.5, (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen)); + } + } + + if (nSumEtaRightHadMcGen > 0 && nSumEtaLeftHadMcGen > 0 && nSumEtaLeftPiMcGen > 0) { + for (int i = 0; i < nbinsPid; i++) { + histos.get(HIST("McClosure/Generated/Prof_A_pi"))->Fill(cent, fPtProfilePiMcGen->GetBinCenter(i + 1), (fPtProfilePiMcGen->GetBinContent(i + 1) / nSumEtaLeftPiMcGen)); + histos.get(HIST("McClosure/Generated/Prof_C_pi"))->Fill(cent, fPtProfilePiMcGen->GetBinCenter(i + 1), ((fPtProfilePiMcGen->GetBinContent(i + 1) / nSumEtaLeftPiMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + histos.get(HIST("McClosure/Generated/Prof_Bone_pi"))->Fill(cent, 0.5, (pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen)); + histos.get(HIST("McClosure/Generated/Prof_Btwo_pi"))->Fill(cent, 0.5, (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen)); + histos.get(HIST("McClosure/Generated/Prof_D_pi"))->Fill(cent, 0.5, ((pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + + subSampleMcGen[sampleIndex][5]->Fill(cent, fPtProfilePiMcGen->GetBinCenter(i + 1), (fPtProfilePiMcGen->GetBinContent(i + 1) / nSumEtaLeftPiMcGen)); + subSampleMcGen[sampleIndex][6]->Fill(cent, fPtProfilePiMcGen->GetBinCenter(i + 1), ((fPtProfilePiMcGen->GetBinContent(i + 1) / nSumEtaLeftPiMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + subSampleMcGen[sampleIndex][7]->Fill(cent, 0.5, ((pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + subSampleMcGen[sampleIndex][8]->Fill(cent, 0.5, (pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen)); + subSampleMcGen[sampleIndex][9]->Fill(cent, 0.5, (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen)); + } + } + + if (nSumEtaRightHadMcGen > 0 && nSumEtaLeftHadMcGen > 0 && nSumEtaLeftKaMcGen > 0) { + for (int i = 0; i < nbinsPid; i++) { + histos.get(HIST("McClosure/Generated/Prof_A_ka"))->Fill(cent, fPtProfileKaMcGen->GetBinCenter(i + 1), (fPtProfileKaMcGen->GetBinContent(i + 1) / nSumEtaLeftKaMcGen)); + histos.get(HIST("McClosure/Generated/Prof_C_ka"))->Fill(cent, fPtProfileKaMcGen->GetBinCenter(i + 1), ((fPtProfileKaMcGen->GetBinContent(i + 1) / nSumEtaLeftKaMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + histos.get(HIST("McClosure/Generated/Prof_Bone_ka"))->Fill(cent, 0.5, (pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen)); + histos.get(HIST("McClosure/Generated/Prof_Btwo_ka"))->Fill(cent, 0.5, (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen)); + histos.get(HIST("McClosure/Generated/Prof_D_ka"))->Fill(cent, 0.5, ((pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + + subSampleMcGen[sampleIndex][10]->Fill(cent, fPtProfileKaMcGen->GetBinCenter(i + 1), (fPtProfileKaMcGen->GetBinContent(i + 1) / nSumEtaLeftKaMcGen)); + subSampleMcGen[sampleIndex][11]->Fill(cent, fPtProfileKaMcGen->GetBinCenter(i + 1), ((fPtProfileKaMcGen->GetBinContent(i + 1) / nSumEtaLeftKaMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + subSampleMcGen[sampleIndex][12]->Fill(cent, 0.5, ((pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + subSampleMcGen[sampleIndex][13]->Fill(cent, 0.5, (pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen)); + subSampleMcGen[sampleIndex][14]->Fill(cent, 0.5, (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen)); + } + } + if (nSumEtaRightHadMcGen > 0 && nSumEtaLeftHadMcGen > 0 && nSumEtaLeftProtMcGen > 0) { + for (int i = 1; i < nbinsPid; i++) { + histos.get(HIST("McClosure/Generated/Prof_A_prot"))->Fill(cent, fPtProfileProtMcGen->GetBinCenter(i + 1), (fPtProfileProtMcGen->GetBinContent(i + 1) / nSumEtaLeftProtMcGen)); + histos.get(HIST("McClosure/Generated/Prof_C_prot"))->Fill(cent, fPtProfileProtMcGen->GetBinCenter(i + 1), ((fPtProfileProtMcGen->GetBinContent(i + 1) / nSumEtaLeftProtMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + histos.get(HIST("McClosure/Generated/Prof_Bone_prot"))->Fill(cent, 0.5, (pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen)); + histos.get(HIST("McClosure/Generated/Prof_Btwo_prot"))->Fill(cent, 0.5, (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen)); + histos.get(HIST("McClosure/Generated/Prof_D_prot"))->Fill(cent, 0.5, ((pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + + subSampleMcGen[sampleIndex][15]->Fill(cent, fPtProfileProtMcGen->GetBinCenter(i + 1), (fPtProfileProtMcGen->GetBinContent(i + 1) / nSumEtaLeftProtMcGen)); + subSampleMcGen[sampleIndex][16]->Fill(cent, fPtProfileProtMcGen->GetBinCenter(i + 1), ((fPtProfileProtMcGen->GetBinContent(i + 1) / nSumEtaLeftProtMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + subSampleMcGen[sampleIndex][17]->Fill(cent, 0.5, ((pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen) * (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen))); + subSampleMcGen[sampleIndex][18]->Fill(cent, 0.5, (pTsumEtaLeftHadMcGen / nSumEtaLeftHadMcGen)); + subSampleMcGen[sampleIndex][19]->Fill(cent, 0.5, (pTsumEtaRightHadMcGen / nSumEtaRightHadMcGen)); + } + } + } + + fPtProfileHadMcGen->Delete(); + fPtProfilePiMcGen->Delete(); + fPtProfileKaMcGen->Delete(); + fPtProfileProtMcGen->Delete(); } PROCESS_SWITCH(V0ptHadPiKaProt, processMCGen, "Process Monte-carlo generated data", false); @@ -1202,6 +1540,37 @@ struct V0ptHadPiKaProt { } } //! end mc particle loop + // MC reconstructed Analysis variables for v0(pT) + int nbinsHad = 20; + int nbinsPid = 18; + double binsarray[21] = {0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.5, 4.0, 5.0, 6.0, 8.0, 10.0}; + + // Raw + TH1D* fPtProfileHadMcRecRaw = new TH1D("fPtProfileHadMcRecRaw", "fPtProfileHadMcRecRaw", 20, binsarray); + TH1D* fPtProfilePiMcRecRaw = new TH1D("fPtProfilePiMcRecRaw", "fPtProfilePiMcRecRaw", 20, binsarray); + TH1D* fPtProfileKaMcRecRaw = new TH1D("fPtProfileKaMcRecRaw", "fPtProfileKaMcRecRaw", 20, binsarray); + TH1D* fPtProfileProtMcRecRaw = new TH1D("fPtProfileProtMcRecRaw", "fPtProfileProtMcRecRaw", 20, binsarray); + double pTsumEtaLeftHadMcRecRaw = 0.0; + double nSumEtaLeftHadMcRecRaw = 0.0; + double pTsumEtaRightHadMcRecRaw = 0.0; + double nSumEtaRightHadMcRecRaw = 0.0; + double nSumEtaLeftPiMcRecRaw = 0.0; + double nSumEtaLeftKaMcRecRaw = 0.0; + double nSumEtaLeftProtMcRecRaw = 0.0; + + // Eff corrected + TH1D* fPtProfileHadMcRecCorr = new TH1D("fPtProfileHadMcRecCorr", "fPtProfileHadMcRecCorr", 20, binsarray); + TH1D* fPtProfilePiMcRecCorr = new TH1D("fPtProfilePiMcRecCorr", "fPtProfilePiMcRecCorr", 20, binsarray); + TH1D* fPtProfileKaMcRecCorr = new TH1D("fPtProfileKaMcRecCorr", "fPtProfileKaMcRecCorr", 20, binsarray); + TH1D* fPtProfileProtMcRecCorr = new TH1D("fPtProfileProtMcRecCorr", "fPtProfileProtMcRecCorr", 20, binsarray); + double pTsumEtaLeftHadMcRecCorr = 0.0; + double nSumEtaLeftHadMcRecCorr = 0.0; + double pTsumEtaRightHadMcRecCorr = 0.0; + double nSumEtaRightHadMcRecCorr = 0.0; + double nSumEtaLeftPiMcRecCorr = 0.0; + double nSumEtaLeftKaMcRecCorr = 0.0; + double nSumEtaLeftProtMcRecCorr = 0.0; + for (const auto& track : tracks) { // Loop over tracks if (!track.has_collision()) { @@ -1332,9 +1701,230 @@ struct V0ptHadPiKaProt { if (pdgcodeRec == PDG_t::kProton) histos.fill(HIST("MCReconstructed/hPtEtaPhiTrueProtonTrack"), track.pt(), track.eta(), track.phi()); } + + if (cfgMcClosure) { + double trkPt = particle.pt(); + double trkEta = particle.eta(); + + // Raw + double effweight = 1.0; + double effweightPion = 1.0; + double effweightKaon = 1.0; + double effweightProton = 1.0; + + if (track.sign() != 0) { + if (trkEta < cfgCutEtaLeft) { + fPtProfileHadMcRecRaw->Fill(trkPt); + pTsumEtaLeftHadMcRecRaw += trkPt * effweight; + nSumEtaLeftHadMcRecRaw += effweight; + } + if (trkEta > cfgCutEtaRight) { + pTsumEtaRightHadMcRecRaw += trkPt * effweight; + nSumEtaRightHadMcRecRaw += effweight; + } + } + + if (trkPt < cfgCutPtUpperPID) { + if (trkEta < cfgCutEtaLeft) { + if (isPion) { + fPtProfilePiMcRecRaw->Fill(trkPt, effweightPion); + nSumEtaLeftPiMcRecRaw += effweightPion; + } + if (isKaon) { + fPtProfileKaMcRecRaw->Fill(trkPt, effweightKaon); + nSumEtaLeftKaMcRecRaw += effweightKaon; + } + if (isProton && trkPt > cfgCutPtLowerProt) { + fPtProfileProtMcRecRaw->Fill(trkPt, effweightProton); + nSumEtaLeftProtMcRecRaw += effweightProton; + } + } + } + + // Efficiency corrected + if (cfgLoadPtEffWeights) { + effweight = getEffWeightAllCharged(track); // NUE weight + effweightPion = getEffWeightPion(track); // NUE weight for pion + effweightKaon = getEffWeightKaon(track); // NUE weight for kaon + effweightProton = getEffWeightProton(track); // NUE weight for proton + } + if (track.sign() != 0) { + if (trkEta < cfgCutEtaLeft) { + fPtProfileHadMcRecCorr->Fill(trkPt); + pTsumEtaLeftHadMcRecCorr += trkPt * effweight; + nSumEtaLeftHadMcRecCorr += effweight; + } + if (trkEta > cfgCutEtaRight) { + pTsumEtaRightHadMcRecCorr += trkPt * effweight; + nSumEtaRightHadMcRecCorr += effweight; + } + } + + if (trkPt < cfgCutPtUpperPID) { + if (trkEta < cfgCutEtaLeft) { + if (isPion) { + fPtProfilePiMcRecCorr->Fill(trkPt, effweightPion); + nSumEtaLeftPiMcRecCorr += effweightPion; + } + if (isKaon) { + fPtProfileKaMcRecCorr->Fill(trkPt, effweightKaon); + nSumEtaLeftKaMcRecCorr += effweightKaon; + } + if (isProton && trkPt > cfgCutPtLowerProt) { + fPtProfileProtMcRecCorr->Fill(trkPt, effweightProton); + nSumEtaLeftProtMcRecCorr += effweightProton; + } + } + } + } // end of if(cfgMcClosure) } } } // end track loop + + if (cfgMcClosure) { + // selecting subsample and filling profiles + float lRandom = funRndm->Rndm(); + int sampleIndex = static_cast(cfgNSubsample * lRandom); + + // MC reconstructed Raw; not corrected for efficiency + if (nSumEtaRightHadMcRecRaw > 0 && nSumEtaLeftHadMcRecRaw > 0) { + for (int i = 0; i < nbinsHad; i++) { + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_A_had"))->Fill(cent, fPtProfileHadMcRecRaw->GetBinCenter(i + 1), (fPtProfileHadMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftHadMcRecRaw)); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_C_had"))->Fill(cent, fPtProfileHadMcRecRaw->GetBinCenter(i + 1), ((fPtProfileHadMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftHadMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_Bone_had"))->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw)); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_Btwo_had"))->Fill(cent, 0.5, (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw)); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_D_had"))->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + + subSampleMcRecRaw[sampleIndex][0]->Fill(cent, fPtProfileHadMcRecRaw->GetBinCenter(i + 1), (fPtProfileHadMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftHadMcRecRaw)); + subSampleMcRecRaw[sampleIndex][1]->Fill(cent, fPtProfileHadMcRecRaw->GetBinCenter(i + 1), ((fPtProfileHadMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftHadMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + subSampleMcRecRaw[sampleIndex][2]->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + subSampleMcRecRaw[sampleIndex][3]->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw)); + subSampleMcRecRaw[sampleIndex][4]->Fill(cent, 0.5, (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw)); + } + } + + if (nSumEtaRightHadMcRecRaw > 0 && nSumEtaLeftHadMcRecRaw > 0 && nSumEtaLeftPiMcRecRaw > 0) { + for (int i = 0; i < nbinsPid; i++) { + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_A_pi"))->Fill(cent, fPtProfilePiMcRecRaw->GetBinCenter(i + 1), (fPtProfilePiMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftPiMcRecRaw)); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_C_pi"))->Fill(cent, fPtProfilePiMcRecRaw->GetBinCenter(i + 1), ((fPtProfilePiMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftPiMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_Bone_pi"))->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw)); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_Btwo_pi"))->Fill(cent, 0.5, (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw)); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_D_pi"))->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + + subSampleMcRecRaw[sampleIndex][5]->Fill(cent, fPtProfilePiMcRecRaw->GetBinCenter(i + 1), (fPtProfilePiMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftPiMcRecRaw)); + subSampleMcRecRaw[sampleIndex][6]->Fill(cent, fPtProfilePiMcRecRaw->GetBinCenter(i + 1), ((fPtProfilePiMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftPiMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + subSampleMcRecRaw[sampleIndex][7]->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + subSampleMcRecRaw[sampleIndex][8]->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw)); + subSampleMcRecRaw[sampleIndex][9]->Fill(cent, 0.5, (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw)); + } + } + + if (nSumEtaRightHadMcRecRaw > 0 && nSumEtaLeftHadMcRecRaw > 0 && nSumEtaLeftKaMcRecRaw > 0) { + for (int i = 0; i < nbinsPid; i++) { + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_A_ka"))->Fill(cent, fPtProfileKaMcRecRaw->GetBinCenter(i + 1), (fPtProfileKaMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftKaMcRecRaw)); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_C_ka"))->Fill(cent, fPtProfileKaMcRecRaw->GetBinCenter(i + 1), ((fPtProfileKaMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftKaMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_Bone_ka"))->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw)); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_Btwo_ka"))->Fill(cent, 0.5, (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw)); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_D_ka"))->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + + subSampleMcRecRaw[sampleIndex][10]->Fill(cent, fPtProfileKaMcRecRaw->GetBinCenter(i + 1), (fPtProfileKaMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftKaMcRecRaw)); + subSampleMcRecRaw[sampleIndex][11]->Fill(cent, fPtProfileKaMcRecRaw->GetBinCenter(i + 1), ((fPtProfileKaMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftKaMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + subSampleMcRecRaw[sampleIndex][12]->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + subSampleMcRecRaw[sampleIndex][13]->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw)); + subSampleMcRecRaw[sampleIndex][14]->Fill(cent, 0.5, (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw)); + } + } + if (nSumEtaRightHadMcRecRaw > 0 && nSumEtaLeftHadMcRecRaw > 0 && nSumEtaLeftProtMcRecRaw > 0) { + for (int i = 1; i < nbinsPid; i++) { + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_A_prot"))->Fill(cent, fPtProfileProtMcRecRaw->GetBinCenter(i + 1), (fPtProfileProtMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftProtMcRecRaw)); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_C_prot"))->Fill(cent, fPtProfileProtMcRecRaw->GetBinCenter(i + 1), ((fPtProfileProtMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftProtMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_Bone_prot"))->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw)); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_Btwo_prot"))->Fill(cent, 0.5, (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw)); + histosMc.get(HIST("McClosure/Reconstructed/Raw/Prof_D_prot"))->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + + subSampleMcRecRaw[sampleIndex][15]->Fill(cent, fPtProfileProtMcRecRaw->GetBinCenter(i + 1), (fPtProfileProtMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftProtMcRecRaw)); + subSampleMcRecRaw[sampleIndex][16]->Fill(cent, fPtProfileProtMcRecRaw->GetBinCenter(i + 1), ((fPtProfileProtMcRecRaw->GetBinContent(i + 1) / nSumEtaLeftProtMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + subSampleMcRecRaw[sampleIndex][17]->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw) * (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw))); + subSampleMcRecRaw[sampleIndex][18]->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecRaw / nSumEtaLeftHadMcRecRaw)); + subSampleMcRecRaw[sampleIndex][19]->Fill(cent, 0.5, (pTsumEtaRightHadMcRecRaw / nSumEtaRightHadMcRecRaw)); + } + } + + // MC Reconstructed Efficiency corrected + + if (nSumEtaRightHadMcRecCorr > 0 && nSumEtaLeftHadMcRecCorr > 0) { + for (int i = 0; i < nbinsHad; i++) { + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_A_had"))->Fill(cent, fPtProfileHadMcRecCorr->GetBinCenter(i + 1), (fPtProfileHadMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftHadMcRecCorr)); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_C_had"))->Fill(cent, fPtProfileHadMcRecCorr->GetBinCenter(i + 1), ((fPtProfileHadMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftHadMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_Bone_had"))->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr)); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_Btwo_had"))->Fill(cent, 0.5, (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr)); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_D_had"))->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + + subSampleMcRecCorr[sampleIndex][0]->Fill(cent, fPtProfileHadMcRecCorr->GetBinCenter(i + 1), (fPtProfileHadMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftHadMcRecCorr)); + subSampleMcRecCorr[sampleIndex][1]->Fill(cent, fPtProfileHadMcRecCorr->GetBinCenter(i + 1), ((fPtProfileHadMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftHadMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + subSampleMcRecCorr[sampleIndex][2]->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + subSampleMcRecCorr[sampleIndex][3]->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr)); + subSampleMcRecCorr[sampleIndex][4]->Fill(cent, 0.5, (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr)); + } + } + + if (nSumEtaRightHadMcRecCorr > 0 && nSumEtaLeftHadMcRecCorr > 0 && nSumEtaLeftPiMcRecCorr > 0) { + for (int i = 0; i < nbinsPid; i++) { + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_A_pi"))->Fill(cent, fPtProfilePiMcRecCorr->GetBinCenter(i + 1), (fPtProfilePiMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftPiMcRecCorr)); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_C_pi"))->Fill(cent, fPtProfilePiMcRecCorr->GetBinCenter(i + 1), ((fPtProfilePiMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftPiMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_Bone_pi"))->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr)); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_Btwo_pi"))->Fill(cent, 0.5, (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr)); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_D_pi"))->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + + subSampleMcRecCorr[sampleIndex][5]->Fill(cent, fPtProfilePiMcRecCorr->GetBinCenter(i + 1), (fPtProfilePiMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftPiMcRecCorr)); + subSampleMcRecCorr[sampleIndex][6]->Fill(cent, fPtProfilePiMcRecCorr->GetBinCenter(i + 1), ((fPtProfilePiMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftPiMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + subSampleMcRecCorr[sampleIndex][7]->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + subSampleMcRecCorr[sampleIndex][8]->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr)); + subSampleMcRecCorr[sampleIndex][9]->Fill(cent, 0.5, (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr)); + } + } + + if (nSumEtaRightHadMcRecCorr > 0 && nSumEtaLeftHadMcRecCorr > 0 && nSumEtaLeftKaMcRecCorr > 0) { + for (int i = 0; i < nbinsPid; i++) { + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_A_ka"))->Fill(cent, fPtProfileKaMcRecCorr->GetBinCenter(i + 1), (fPtProfileKaMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftKaMcRecCorr)); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_C_ka"))->Fill(cent, fPtProfileKaMcRecCorr->GetBinCenter(i + 1), ((fPtProfileKaMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftKaMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_Bone_ka"))->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr)); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_Btwo_ka"))->Fill(cent, 0.5, (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr)); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_D_ka"))->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + + subSampleMcRecCorr[sampleIndex][10]->Fill(cent, fPtProfileKaMcRecCorr->GetBinCenter(i + 1), (fPtProfileKaMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftKaMcRecCorr)); + subSampleMcRecCorr[sampleIndex][11]->Fill(cent, fPtProfileKaMcRecCorr->GetBinCenter(i + 1), ((fPtProfileKaMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftKaMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + subSampleMcRecCorr[sampleIndex][12]->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + subSampleMcRecCorr[sampleIndex][13]->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr)); + subSampleMcRecCorr[sampleIndex][14]->Fill(cent, 0.5, (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr)); + } + } + if (nSumEtaRightHadMcRecCorr > 0 && nSumEtaLeftHadMcRecCorr > 0 && nSumEtaLeftProtMcRecCorr > 0) { + for (int i = 1; i < nbinsPid; i++) { + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_A_prot"))->Fill(cent, fPtProfileProtMcRecCorr->GetBinCenter(i + 1), (fPtProfileProtMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftProtMcRecCorr)); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_C_prot"))->Fill(cent, fPtProfileProtMcRecCorr->GetBinCenter(i + 1), ((fPtProfileProtMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftProtMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_Bone_prot"))->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr)); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_Btwo_prot"))->Fill(cent, 0.5, (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr)); + histosMc.get(HIST("McClosure/Reconstructed/Corr/Prof_D_prot"))->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + + subSampleMcRecCorr[sampleIndex][15]->Fill(cent, fPtProfileProtMcRecCorr->GetBinCenter(i + 1), (fPtProfileProtMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftProtMcRecCorr)); + subSampleMcRecCorr[sampleIndex][16]->Fill(cent, fPtProfileProtMcRecCorr->GetBinCenter(i + 1), ((fPtProfileProtMcRecCorr->GetBinContent(i + 1) / nSumEtaLeftProtMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + subSampleMcRecCorr[sampleIndex][17]->Fill(cent, 0.5, ((pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr) * (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr))); + subSampleMcRecCorr[sampleIndex][18]->Fill(cent, 0.5, (pTsumEtaLeftHadMcRecCorr / nSumEtaLeftHadMcRecCorr)); + subSampleMcRecCorr[sampleIndex][19]->Fill(cent, 0.5, (pTsumEtaRightHadMcRecCorr / nSumEtaRightHadMcRecCorr)); + } + } + } + + fPtProfileHadMcRecRaw->Delete(); + fPtProfilePiMcRecRaw->Delete(); + fPtProfileKaMcRecRaw->Delete(); + fPtProfileProtMcRecRaw->Delete(); + + fPtProfileHadMcRecCorr->Delete(); + fPtProfilePiMcRecCorr->Delete(); + fPtProfileKaMcRecCorr->Delete(); + fPtProfileProtMcRecCorr->Delete(); } PROCESS_SWITCH(V0ptHadPiKaProt, processMCRec, "Process Monte-carlo reconstructed data", false); @@ -1375,6 +1965,7 @@ struct V0ptHadPiKaProt { int nbinsHad = 20; int nbinsPid = 18; double binsarray[21] = {0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.5, 4.0, 5.0, 6.0, 8.0, 10.0}; + TH1D* fPtProfileHad = new TH1D("fPtProfileHad", "fPtProfileHad", 20, binsarray); TH1D* fPtProfilePi = new TH1D("fPtProfilePi", "fPtProfilePi", 20, binsarray); TH1D* fPtProfileKa = new TH1D("fPtProfileKa", "fPtProfileKa", 20, binsarray); diff --git a/PWGCF/Femto/Core/baseSelection.h b/PWGCF/Femto/Core/baseSelection.h index 9ecf9edfe6d..469c1f6c521 100644 --- a/PWGCF/Femto/Core/baseSelection.h +++ b/PWGCF/Femto/Core/baseSelection.h @@ -257,7 +257,7 @@ class BaseSelection /// \brief Check whether all required and optional cuts are passed. /// \return True if all minimal cuts pass and, if optional cuts are present, at least one of them passes. - bool passesAllRequiredSelections() const + [[nodiscard]] bool passesAllRequiredSelections() const { if (mHasMinimalSelection && !mHasOptionalSelection) { return mPassesMinimalSelections; @@ -275,14 +275,14 @@ class BaseSelection /// \brief Check whether the optional selection for a specific observable is passed. /// \param observableIndex Index of the observable. /// \return True if at least one optional selection for this observable is fulfilled. - bool passesOptionalSelection(int observableIndex) const + [[nodiscard]] bool passesOptionalSelection(int observableIndex) const { return mSelectionContainers.at(observableIndex).passesAsOptionalCut(); } /// \brief Assemble the global selection bitmask from all individual observable selections. /// \tparam HistName Name of the histogram used to track selection statistics. - template + template void assembleBitmask() { mHistRegistry->fill(HIST(HistName), mNSelection); @@ -391,7 +391,7 @@ class BaseSelection /// \brief Initialize histograms and set bitmask offsets for all configured observables. /// \tparam HistName Name of the histogram to create in the registry. /// \param registry Pointer to the histogram registry. - template + template void setupContainers(o2::framework::HistogramRegistry* registry) { mHistRegistry = registry; diff --git a/PWGCF/Femto/Core/cascadeBuilder.h b/PWGCF/Femto/Core/cascadeBuilder.h index 4b2fb7863b0..2a7e7f0180a 100644 --- a/PWGCF/Femto/Core/cascadeBuilder.h +++ b/PWGCF/Femto/Core/cascadeBuilder.h @@ -37,11 +37,8 @@ #include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::cascadebuilder { -namespace cascadebuilder -{ - struct ConfCascadeFilters : o2::framework::ConfigurableGroup { std::string prefix = std::string("CascadeFilters"); o2::framework::Configurable ptMin{"ptMin", 0.f, "Minimum pT"}; @@ -62,7 +59,9 @@ struct ConfCascadeFilters : o2::framework::ConfigurableGroup { o2::framework::Configurable massLambdaMax{"massLambdaMax", 1.2f, "Maximum Lambda mass"}; }; +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define CASCADE_DEFAULT_BITS \ + o2::framework::Configurable passThrough{"passThrough", false, "If true, all Cascades are passed through. Bits for all selections are stored."}; \ o2::framework::Configurable> cascadeCpaMin{"cascadeCpaMin", {0.95f}, "Minimum cosine of pointing angle"}; \ o2::framework::Configurable> cascadeTransRadMin{"cascadeTransRadMin", {0.9f}, "Minimum transverse radius (cm)"}; \ o2::framework::Configurable> cascadeDcaDauMax{"cascadeDcaDauMax", {0.25f}, "Maximum DCA between the daughters at decay vertex (cm)"}; \ @@ -90,18 +89,19 @@ struct ConfOmegaBits : o2::framework::ConfigurableGroup { #undef CASCADE_DEFAULT_BITS -#define CASCADE_DEFAULT_SELECTION(defaultMassMin, defaultMassMax, defaultPdgCode) \ - o2::framework::Configurable pdgCodeAbs{"pdgCodeAbs", defaultPdgCode, "Cascade PDG code. Set sign to +1 to select antiparticle"}; \ - o2::framework::Configurable sign{"sign", -1, "Sign of the charge of the Cascade"}; \ - o2::framework::Configurable ptMin{"ptMin", 0.f, "Minimum pT"}; \ - o2::framework::Configurable ptMax{"ptMax", 999.f, "Maximum pT"}; \ - o2::framework::Configurable etaMin{"etaMin", -10.f, "Minimum eta"}; \ - o2::framework::Configurable etaMax{"etaMax", 10.f, "Maximum eta"}; \ - o2::framework::Configurable phiMin{"phiMin", 0.f, "Minimum eta"}; \ - o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; \ - o2::framework::Configurable massMin{"massMin", defaultMassMin, "Minimum invariant mass for Cascade"}; \ - o2::framework::Configurable massMax{"massMax", defaultMassMax, "Maximum invariant mass for Cascade"}; \ - o2::framework::Configurable mask{"mask", 0x0, "Bitmask for cascade selection"}; +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define CASCADE_DEFAULT_SELECTION(defaultMassMin, defaultMassMax, defaultPdgCode) \ + o2::framework::Configurable pdgCodeAbs{"pdgCodeAbs", (defaultPdgCode), "Cascade PDG code. Set sign to +1 to select antiparticle"}; \ + o2::framework::Configurable sign{"sign", -1, "Sign of the charge of the Cascade"}; \ + o2::framework::Configurable ptMin{"ptMin", 0.f, "Minimum pT"}; \ + o2::framework::Configurable ptMax{"ptMax", 999.f, "Maximum pT"}; \ + o2::framework::Configurable etaMin{"etaMin", -10.f, "Minimum eta"}; \ + o2::framework::Configurable etaMax{"etaMax", 10.f, "Maximum eta"}; \ + o2::framework::Configurable phiMin{"phiMin", 0.f, "Minimum eta"}; \ + o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; \ + o2::framework::Configurable massMin{"massMin", (defaultMassMin), "Minimum invariant mass for Cascade"}; \ + o2::framework::Configurable massMax{"massMax", (defaultMassMax), "Maximum invariant mass for Cascade"}; \ + o2::framework::Configurable mask{"mask", 0x0, "Bitmask for cascade selection"}; struct ConfXiSelection : o2::framework::ConfigurableGroup { std::string prefix = std::string("XiSelection"); @@ -113,6 +113,8 @@ struct ConfOmegaSelection : o2::framework::ConfigurableGroup { CASCADE_DEFAULT_SELECTION(1.57, 1.77, 3334) }; +#undef CASCADE_DEFAULT_SELECTION + /// The different selections this task is capable of doing enum CascadeSels { // selections for cascades @@ -169,29 +171,37 @@ const std::unordered_map cascadeSelectionNames = { /// \class FemtoDreamTrackCuts /// \brief Cut class to contain and execute all cuts applied to tracks -template -class CascadeSelection : public BaseSelection +template +class CascadeSelection : public BaseSelection { public: CascadeSelection() = default; - ~CascadeSelection() = default; + ~CascadeSelection() override = default; template void configure(o2::framework::HistogramRegistry* registry, T1 const& config, T2 const& filter) { + // check for pass through mode + mPassThrough = config.passThrough.value; + + // if pass through mode is activated, each cut is neutral (i.e. neither minimal nor optional and we do + // store all bits, so the most permissive bit is not skipped for minimal selections) + const bool isMinimalCut = !mPassThrough; + const bool skipMostPermissiveBit = !mPassThrough; + if constexpr (modes::isEqual(cascadeType, modes::Cascade::kXi)) { mXiMassLowerLimit = filter.massXiMin.value; mXiMassUpperLimit = filter.massXiMax.value; mOmegaMassLowerLimit = filter.rejectMassOmegaMin.value; mOmegaMassUpperLimit = filter.rejectMassOmegaMax.value; - this->addSelection(kBachelorTpcPion, cascadeSelectionNames.at(kBachelorTpcPion), config.bachelorTpcPion.value, limits::kAbsUpperLimit, true, true, false); + this->addSelection(kBachelorTpcPion, cascadeSelectionNames.at(kBachelorTpcPion), config.bachelorTpcPion.value, limits::kAbsUpperLimit, skipMostPermissiveBit, isMinimalCut, false); } if constexpr (modes::isEqual(cascadeType, modes::Cascade::kOmega)) { mOmegaMassLowerLimit = filter.massOmegaMin.value; mOmegaMassUpperLimit = filter.massOmegaMax.value; mXiMassLowerLimit = filter.rejectMassXiMin.value; mXiMassUpperLimit = filter.rejectMassXiMax.value; - this->addSelection(kBachelorTpcKaon, cascadeSelectionNames.at(kBachelorTpcKaon), config.bachelorTpcKaon.value, limits::kAbsUpperLimit, true, true, false); + this->addSelection(kBachelorTpcKaon, cascadeSelectionNames.at(kBachelorTpcKaon), config.bachelorTpcKaon.value, limits::kAbsUpperLimit, skipMostPermissiveBit, isMinimalCut, false); } mPtMin = filter.ptMin.value; @@ -203,19 +213,19 @@ class CascadeSelection : public BaseSelectionaddSelection(kPosDauTpc, cascadeSelectionNames.at(kPosDauTpc), config.posDauTpc.value, limits::kAbsUpperLimit, true, true, false); - this->addSelection(kNegDauTpc, cascadeSelectionNames.at(kNegDauTpc), config.negDauTpc.value, limits::kAbsUpperLimit, true, true, false); + this->addSelection(kPosDauTpc, cascadeSelectionNames.at(kPosDauTpc), config.posDauTpc.value, limits::kAbsUpperLimit, skipMostPermissiveBit, isMinimalCut, false); + this->addSelection(kNegDauTpc, cascadeSelectionNames.at(kNegDauTpc), config.negDauTpc.value, limits::kAbsUpperLimit, skipMostPermissiveBit, isMinimalCut, false); - this->addSelection(kCascadeCpaMin, cascadeSelectionNames.at(kCascadeCpaMin), config.cascadeCpaMin.value, limits::kLowerLimit, true, true, false); - this->addSelection(kCascadeTransRadMin, cascadeSelectionNames.at(kCascadeTransRadMin), config.cascadeTransRadMin.value, limits::kLowerLimit, true, true, false); - this->addSelection(kCascadeDcaDaughMax, cascadeSelectionNames.at(kCascadeDcaDaughMax), config.cascadeDcaDauMax.value, limits::kAbsUpperLimit, true, true, false); - this->addSelection(kLambdaCpaMin, cascadeSelectionNames.at(kLambdaCpaMin), config.lambdaCpaMin.value, limits::kLowerLimit, true, true, false); - this->addSelection(kLambdaTransRadMin, cascadeSelectionNames.at(kLambdaTransRadMin), config.lambdaTransRadMin.value, limits::kLowerLimit, true, true, false); - this->addSelection(kLambdaDcaDauMax, cascadeSelectionNames.at(kLambdaDcaDauMax), config.lambdaDcaDauMax.value, limits::kAbsUpperLimit, true, true, false); - this->addSelection(kLambdaDcaToPvMin, cascadeSelectionNames.at(kLambdaDcaToPvMin), config.lambdaDcaToPvMin.value, limits::kLowerLimit, true, true, false); - this->addSelection(kDauAbsEtaMax, cascadeSelectionNames.at(kDauAbsEtaMax), config.dauAbsEtaMax.value, limits::kAbsUpperLimit, true, true, false); - this->addSelection(kDauDcaMin, cascadeSelectionNames.at(kDauDcaMin), config.dauDcaMin.value, limits::kAbsLowerLimit, true, true, false); - this->addSelection(kDauTpcClsMin, cascadeSelectionNames.at(kDauTpcClsMin), config.dauTpcClustersMin.value, limits::kLowerLimit, true, true, false); + this->addSelection(kCascadeCpaMin, cascadeSelectionNames.at(kCascadeCpaMin), config.cascadeCpaMin.value, limits::kLowerLimit, skipMostPermissiveBit, isMinimalCut, false); + this->addSelection(kCascadeTransRadMin, cascadeSelectionNames.at(kCascadeTransRadMin), config.cascadeTransRadMin.value, limits::kLowerLimit, skipMostPermissiveBit, isMinimalCut, false); + this->addSelection(kCascadeDcaDaughMax, cascadeSelectionNames.at(kCascadeDcaDaughMax), config.cascadeDcaDauMax.value, limits::kAbsUpperLimit, skipMostPermissiveBit, isMinimalCut, false); + this->addSelection(kLambdaCpaMin, cascadeSelectionNames.at(kLambdaCpaMin), config.lambdaCpaMin.value, limits::kLowerLimit, skipMostPermissiveBit, isMinimalCut, false); + this->addSelection(kLambdaTransRadMin, cascadeSelectionNames.at(kLambdaTransRadMin), config.lambdaTransRadMin.value, limits::kLowerLimit, skipMostPermissiveBit, isMinimalCut, false); + this->addSelection(kLambdaDcaDauMax, cascadeSelectionNames.at(kLambdaDcaDauMax), config.lambdaDcaDauMax.value, limits::kAbsUpperLimit, skipMostPermissiveBit, isMinimalCut, false); + this->addSelection(kLambdaDcaToPvMin, cascadeSelectionNames.at(kLambdaDcaToPvMin), config.lambdaDcaToPvMin.value, limits::kLowerLimit, skipMostPermissiveBit, isMinimalCut, false); + this->addSelection(kDauAbsEtaMax, cascadeSelectionNames.at(kDauAbsEtaMax), config.dauAbsEtaMax.value, limits::kAbsUpperLimit, skipMostPermissiveBit, isMinimalCut, false); + this->addSelection(kDauDcaMin, cascadeSelectionNames.at(kDauDcaMin), config.dauDcaMin.value, limits::kAbsLowerLimit, skipMostPermissiveBit, isMinimalCut, false); + this->addSelection(kDauTpcClsMin, cascadeSelectionNames.at(kDauTpcClsMin), config.dauTpcClustersMin.value, limits::kLowerLimit, skipMostPermissiveBit, isMinimalCut, false); this->setupContainers(registry); }; @@ -307,6 +317,8 @@ class CascadeSelection : public BaseSelection produceOmegaExtras{"produceOmegaExtras", -1, "Produce OmegaExtras (-1: auto; 0 off; 1 on)"}; }; -template +template class CascadeBuilder { public: @@ -390,11 +404,11 @@ class CascadeBuilder int64_t posDaughterIndex = 0; int64_t negDaughterIndex = 0; for (const auto& cascade : cascades) { - if (!mCascadeSelection.checkFilters(cascade)) { + if (!mCascadeSelection.passThroughAllCascades() && !mCascadeSelection.checkFilters(cascade)) { continue; } mCascadeSelection.applySelections(cascade, tracks, col); - if (!mCascadeSelection.passesAllRequiredSelections()) { + if (!mCascadeSelection.passThroughAllCascades() && !mCascadeSelection.passesAllRequiredSelections()) { continue; } @@ -424,11 +438,11 @@ class CascadeBuilder int64_t posDaughterIndex = 0; int64_t negDaughterIndex = 0; for (const auto& cascade : cascades) { - if (!mCascadeSelection.checkFilters(cascade)) { + if (!mCascadeSelection.passThroughAllCascades() && !mCascadeSelection.checkFilters(cascade)) { continue; } mCascadeSelection.applySelections(cascade, tracks, col); - if (!mCascadeSelection.passesAllRequiredSelections()) { + if (!mCascadeSelection.passThroughAllCascades() && !mCascadeSelection.passesAllRequiredSelections()) { continue; } @@ -438,19 +452,17 @@ class CascadeBuilder bachelorIndex = trackBuilder.template getDaughterIndex(col, collisionProducts, mcCols, bachelor, trackProducts, mcParticles, mcBuilder, mcProducts); auto posDaughter = cascade.template posTrack_as(); - posDaughterIndex = trackBuilder.template getDaughterIndex(col, collisionProducts, mcCols, posDaughter, trackProducts, mcParticles, mcBuilder, mcProducts); + posDaughterIndex = trackBuilder.template getDaughterIndex(col, collisionProducts, mcCols, posDaughter, trackProducts, mcParticles, mcBuilder, mcProducts); auto negDaughter = cascade.template negTrack_as(); - negDaughterIndex = trackBuilder.template getDaughterIndex(col, collisionProducts, mcCols, negDaughter, trackProducts, mcParticles, mcBuilder, mcProducts); + negDaughterIndex = trackBuilder.template getDaughterIndex(col, collisionProducts, mcCols, negDaughter, trackProducts, mcParticles, mcBuilder, mcProducts); fillCascade(collisionProducts, cascadeProducts, cascade, col, bachelorIndex, posDaughterIndex, negDaughterIndex); if constexpr (modes::isEqual(cascadeType, modes::Cascade::kXi)) { mcBuilder.template fillMcXiWithLabel(col, mcCols, cascade, mcParticles, mcProducts); - ; } if constexpr (modes::isEqual(cascadeType, modes::Cascade::kOmega)) { mcBuilder.template fillMcOmegaWithLabel(col, mcCols, cascade, mcParticles, mcProducts); - ; } } } @@ -481,7 +493,7 @@ class CascadeBuilder cascade.v0cosPA(col.posX(), col.posY(), col.posZ()), cascade.dcaV0daughters(), cascade.v0radius(), - cascade.dcav0topv(col.posY(), col.posY(), col.posZ())); + cascade.dcav0topv(col.posX(), col.posY(), col.posZ())); } } if constexpr (modes::isEqual(cascadeType, modes::Cascade::kOmega)) { @@ -507,7 +519,7 @@ class CascadeBuilder cascade.v0cosPA(col.posX(), col.posY(), col.posZ()), cascade.dcaV0daughters(), cascade.v0radius(), - cascade.dcav0topv(col.posY(), col.posY(), col.posZ())); + cascade.dcav0topv(col.posX(), col.posY(), col.posZ())); } } } @@ -525,6 +537,5 @@ class CascadeBuilder bool mProduceOmegaExtras = false; }; -} // namespace cascadebuilder -} // namespace o2::analysis::femto +} // namespace o2::analysis::femto::cascadebuilder #endif // PWGCF_FEMTO_CORE_CASCADEBUILDER_H_ diff --git a/PWGCF/Femto/Core/cascadeHistManager.h b/PWGCF/Femto/Core/cascadeHistManager.h index 749f2f16631..686a46cd29f 100644 --- a/PWGCF/Femto/Core/cascadeHistManager.h +++ b/PWGCF/Femto/Core/cascadeHistManager.h @@ -36,9 +36,7 @@ #include #include -namespace o2::analysis::femto -{ -namespace cascadehistmanager +namespace o2::analysis::femto::cascadehistmanager { // enum for track histograms enum CascadeHist { @@ -90,7 +88,7 @@ enum CascadeHist { constexpr std::size_t MaxSecondary = 3; -template +template struct ConfCascadeBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; o2::framework::ConfigurableAxis pt{"pt", {{600, 0, 6}}, "Pt"}; @@ -106,7 +104,7 @@ using ConfXiBinning = ConfCascadeBinning; constexpr const char PrefixOmegaBinning[] = "OmegaBinning"; using ConfOmegaBinning = ConfCascadeBinning; -template +template struct ConfCascadeQaBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; o2::framework::Configurable plot2d{"plot2d", true, "Enable 2d Qa histograms"}; @@ -136,7 +134,7 @@ constexpr std::array, kCascadeHistLast> HistT {kEta, o2::framework::HistType::kTH1F, "hEta", "Pseudorapdity; #eta; Entries"}, {kPhi, o2::framework::HistType::kTH1F, "hPhi", "Azimuthal angle; #varphi; Entries"}, {kMass, o2::framework::HistType::kTH1F, "hMass", "Invariant Mass; m_{Inv} (GeV/#it{c}^{2}); Entries"}, - {kSign, o2::framework::HistType::kTH1F, "hSign", "Sign (-1 -> antiparticle, 0 -> self conjugate, +1 -> particle); sign; Entries"}, + {kSign, o2::framework::HistType::kTH1F, "hSign", "Sign (-1 -> particle, 0 -> self conjugate, +1 -> antiparticle); sign; Entries"}, {kPtVsMass, o2::framework::HistType::kTH2F, "hPtVsMass", "Transverse momentum vs invariant mass; p_{T} (GeV/#it{c}); m_{Inv} (GeV/#it{c}^{2})"}, {kMassXi, o2::framework::HistType::kTH1F, "hMassXi", "Mass #Xi; m_{#Lambda#pi} (GeV/#it{c}^{2}); Entries"}, {kMassOmega, o2::framework::HistType::kTH1F, "hMassOmega", "mass #Omega; m_{#LambdaK} (GeV/#it{c}^{2}); Entries"}, @@ -172,50 +170,54 @@ constexpr std::array, kCascadeHistLast> HistT {kSecondaryOther, o2::framework::HistType::kTH2F, "hFromSecondaryOther", "Particles from every other secondary decay; p_{T} (GeV/#it{c}); cos(#alpha)"}}, }; +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define CASCADE_HIST_ANALYSIS_MAP(conf) \ - {kPt, {conf.pt}}, \ - {kEta, {conf.eta}}, \ - {kPhi, {conf.phi}}, \ - {kMass, {conf.mass}}, \ - {kSign, {conf.sign}}, \ - {kPtVsMass, {conf.pt, conf.mass}}, - -#define CASCADE_HIST_MC_MAP(conf) \ - {kTruePtVsPt, {conf.pt, conf.pt}}, \ - {kTrueEtaVsEta, {conf.eta, conf.eta}}, \ - {kTruePhiVsPhi, {conf.phi, conf.phi}}, \ - {kPdg, {conf.pdgCodes}}, \ - {kPdgMother, {conf.pdgCodes}}, \ - {kPdgPartonicMother, {conf.pdgCodes}}, - -#define CASCADE_HIST_QA_MAP(confAnalysis, confQa) \ - {kCosPa, {confQa.cosPa}}, \ - {kDecayDauDca, {confQa.dauDcaAtDecay}}, \ - {kTransRadius, {confQa.transRadius}}, \ - {kLambdaCosPa, {confQa.lambdaCosPa}}, \ - {kLambdaDauDca, {confQa.lambdaDauDca}}, \ - {kLambdaTransRadius, {confQa.lambdaTransRadius}}, \ - {kLambdaDcaToPv, {confQa.lambdaDcaToPv}}, \ - {kPtVsEta, {confAnalysis.pt, confAnalysis.eta}}, \ - {kPtVsPhi, {confAnalysis.pt, confAnalysis.phi}}, \ - {kPhiVsEta, {confAnalysis.phi, confAnalysis.eta}}, \ - {kPtVsCosPa, {confAnalysis.pt, confQa.cosPa}}, \ - {kMassXi, {confQa.massXi}}, \ - {kMassOmega, {confQa.massOmega}}, \ - {kPtVsMassXi, {confAnalysis.pt, confQa.massXi}}, \ - {kPtVsMassOmega, {confAnalysis.pt, confQa.massOmega}}, \ - {kMassXiVsMassOmega, {confQa.massXi, confQa.massOmega}}, - -#define CASCADE_HIST_MC_QA_MAP(confAnalysis, confQa) \ - {kNoMcParticle, {confAnalysis.pt, confQa.cosPa}}, \ - {kPrimary, {confAnalysis.pt, confQa.cosPa}}, \ - {kFromWrongCollision, {confAnalysis.pt, confQa.cosPa}}, \ - {kFromMaterial, {confAnalysis.pt, confQa.cosPa}}, \ - {kMissidentified, {confAnalysis.pt, confQa.cosPa}}, \ - {kSecondary1, {confAnalysis.pt, confQa.cosPa}}, \ - {kSecondary2, {confAnalysis.pt, confQa.cosPa}}, \ - {kSecondary3, {confAnalysis.pt, confQa.cosPa}}, \ - {kSecondaryOther, {confAnalysis.pt, confQa.cosPa}}, + {kPt, {(conf).pt}}, \ + {kEta, {(conf).eta}}, \ + {kPhi, {(conf).phi}}, \ + {kMass, {(conf).mass}}, \ + {kSign, {(conf).sign}}, \ + {kPtVsMass, {(conf).pt, (conf).mass}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define CASCADE_HIST_MC_MAP(conf) \ + {kTruePtVsPt, {(conf).pt, (conf).pt}}, \ + {kTrueEtaVsEta, {(conf).eta, (conf).eta}}, \ + {kTruePhiVsPhi, {(conf).phi, (conf).phi}}, \ + {kPdg, {(conf).pdgCodes}}, \ + {kPdgMother, {(conf).pdgCodes}}, \ + {kPdgPartonicMother, {(conf).pdgCodes}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define CASCADE_HIST_QA_MAP(confAnalysis, confQa) \ + {kCosPa, {(confQa).cosPa}}, \ + {kDecayDauDca, {(confQa).dauDcaAtDecay}}, \ + {kTransRadius, {(confQa).transRadius}}, \ + {kLambdaCosPa, {(confQa).lambdaCosPa}}, \ + {kLambdaDauDca, {(confQa).lambdaDauDca}}, \ + {kLambdaTransRadius, {(confQa).lambdaTransRadius}}, \ + {kLambdaDcaToPv, {(confQa).lambdaDcaToPv}}, \ + {kPtVsEta, {(confAnalysis).pt, (confAnalysis).eta}}, \ + {kPtVsPhi, {(confAnalysis).pt, (confAnalysis).phi}}, \ + {kPhiVsEta, {(confAnalysis).phi, (confAnalysis).eta}}, \ + {kPtVsCosPa, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kMassXi, {(confQa).massXi}}, \ + {kMassOmega, {(confQa).massOmega}}, \ + {kPtVsMassXi, {(confAnalysis).pt, (confQa).massXi}}, \ + {kPtVsMassOmega, {(confAnalysis).pt, (confQa).massOmega}}, \ + {kMassXiVsMassOmega, {(confQa).massXi, (confQa).massOmega}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define CASCADE_HIST_MC_QA_MAP(confAnalysis, confQa) \ + {kNoMcParticle, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kPrimary, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kFromWrongCollision, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kFromMaterial, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kMissidentified, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kSecondary1, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kSecondary2, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kSecondary3, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kSecondaryOther, {(confAnalysis).pt, (confQa).cosPa}}, template auto makeCascadeHistSpecMap(const T& confBinningAnalysis) @@ -269,10 +271,10 @@ constexpr std::string_view McDir = "MC/"; /// \class FemtoDreamEventHisto /// \brief Class for histogramming event properties // template -template class CascadeHistManager { @@ -331,7 +333,7 @@ class CascadeHistManager mPosDauManager.template init(registry, PosDauSpecs, absCharge, signPlus, posDauPdgCodeAbs); mNegDauManager.template init(registry, NegDauSpecs, absCharge, signMinus, negDauPdgCodeAbs); - if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { initAnalysis(cascadeSpecs); } if constexpr (modes::isFlagSet(mode, modes::Mode::kMc)) { @@ -397,7 +399,7 @@ class CascadeHistManager mPosDauManager.template init(registry, PosDauSpecs, absCharge, signPlus, posDauPdgCodeAbs, ConfPosDauQaBinning); mNegDauManager.template init(registry, NegDauSpecs, absCharge, signMinus, negDauPdgCodeAbs, ConfNegDauQaBinning); - if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { initAnalysis(cascadeSpecs); } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { @@ -418,7 +420,7 @@ class CascadeHistManager auto bachelor = tracks.rawIteratorAt(cascadeCandidate.bachelorId() - tracks.offset()); mBachelorManager.template fill(bachelor, tracks); - if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { fillAnalysis(cascadeCandidate); } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { @@ -436,7 +438,7 @@ class CascadeHistManager auto bachelor = tracks.rawIteratorAt(cascadeCandidate.bachelorId() - tracks.offset()); mBachelorManager.template fill(bachelor, tracks, mcParticles, mcMothers, mcPartonicMothers); - if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { this->fillAnalysis(cascadeCandidate); } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { @@ -618,16 +620,16 @@ class CascadeHistManager mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(McDir) + HIST(getHistName(kPdg, HistTable)), mcParticle.pdgCode()); // get mother - if (cascadeCandidate.has_fMcMother()) { - auto mother = cascadeCandidate.template fMcMother_as(); + if (mcParticle.has_fMcMother()) { + auto mother = mcParticle.template fMcMother_as(); mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(McDir) + HIST(getHistName(kPdgMother, HistTable)), mother.pdgCode()); } else { mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(McDir) + HIST(getHistName(kPdgMother, HistTable)), 0); } // get partonic mother - if (cascadeCandidate.has_fMcPartMoth()) { - auto partonicMother = cascadeCandidate.template fMcPartMoth_as(); + if (mcParticle.has_fMcPartMoth()) { + auto partonicMother = mcParticle.template fMcPartMoth_as(); mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(McDir) + HIST(getHistName(kPdgPartonicMother, HistTable)), partonicMother.pdgCode()); } else { mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(McDir) + HIST(getHistName(kPdgPartonicMother, HistTable)), 0); @@ -652,8 +654,8 @@ class CascadeHistManager mHistogramRegistry->fill(HIST(cascadePrefix) + HIST(McDir) + HIST(getHistName(kFromMaterial, HistTable)), cascadeCandidate.pt(), cascadeCandidate.cascadeCosPa()); break; case modes::McOrigin::kFromSecondaryDecay: - if (cascadeCandidate.has_fMcMother()) { - auto mother = cascadeCandidate.template fMcMother_as(); + if (mcParticle.has_fMcMother()) { + auto mother = mcParticle.template fMcMother_as(); int motherPdgCode = std::abs(mother.pdgCode()); // Switch on PDG of the mother if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel1 && motherPdgCode == mPdgCodesSecondaryMother[0]) { @@ -687,6 +689,5 @@ class CascadeHistManager trackhistmanager::TrackHistManager mPosDauManager; trackhistmanager::TrackHistManager mNegDauManager; }; -}; // namespace cascadehistmanager -}; // namespace o2::analysis::femto +} // namespace o2::analysis::femto::cascadehistmanager #endif // PWGCF_FEMTO_CORE_CASCADEHISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/closePairRejection.h b/PWGCF/Femto/Core/closePairRejection.h index 4175758fa91..3747ebd633e 100644 --- a/PWGCF/Femto/Core/closePairRejection.h +++ b/PWGCF/Femto/Core/closePairRejection.h @@ -1,4 +1,4 @@ -// Copyright 2019-2022 CERN and copyright holders of ALICE O2. +// Copyright 2019-2025 CERN and copyright holders of ALICE O2. // See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. // All rights not expressly granted are reserved. // @@ -38,9 +38,7 @@ #include #include -namespace o2::analysis::femto -{ -namespace closepairrejection +namespace o2::analysis::femto::closepairrejection { // enum for track histograms enum CprHist { @@ -61,7 +59,7 @@ enum CprHist { }; // template configurable group for Cpr -template +template struct ConfCpr : o2::framework::ConfigurableGroup { std::string prefix = std::string(Prefix); o2::framework::Configurable cutAverage{"cutAverage", true, "Apply CPR if the average deta-dphistar is below the configured values"}; @@ -80,6 +78,7 @@ struct ConfCpr : o2::framework::ConfigurableGroup { o2::framework::ConfigurableAxis binningCorrelationPhi{"binningCorrelationPhi", {{720, 0, o2::constants::math::TwoPI}}, "Phi binning for correlation plot"}; o2::framework::ConfigurableAxis binningCorrelationEta{"binningCorrelationEta", {{160, -0.8, 0.8}}, "Eta binning for correlation plot"}; o2::framework::Configurable seed{"seed", -1, "Seed to randomize particle 1 and particle 2. Set to negative value to deactivate. Set to 0 to generate unique seed in time."}; + o2::framework::Configurable magField{"magField", 5, "MC ONLY: In case of pure MC processing (no reconstruction), set magnetic field in kG"}; }; constexpr const char PrefixCprTrackTrack[] = "CprTrackTrack"; @@ -126,6 +125,8 @@ constexpr char PrefixTrackCascadeBachelorSe[] = "CPR_TrackCascadeBachelor/SE/"; constexpr char PrefixTrackCascadeBachelorMe[] = "CPR_TrackCascadeBachelor/ME/"; constexpr char PrefixTrackKinkSe[] = "CPR_TrackKink/SE/"; constexpr char PrefixTrackKinkMe[] = "CPR_TrackKink/ME/"; +constexpr char PrefixMcParticleMcParticleSe[] = "CPR_McParticleMcParticle/SE/"; +constexpr char PrefixMcParticleMcParticleMe[] = "CPR_McParticleMcParticle/ME/"; // must be in sync with enum TrackVariables // the enum gives the correct index in the array @@ -162,7 +163,7 @@ auto makeCprHistSpecMap(const T& confCpr) }; }; -template +template class CloseTrackRejection { public: @@ -202,7 +203,7 @@ class CloseTrackRejection mPlotAngularCorrelation = confCpr.plotAngularCorrelation.value; if (confCpr.seed.value >= 0) { - uint64_t randomSeed; + uint64_t randomSeed = 0; mRandomizeTracks = true; if (confCpr.seed.value == 0) { randomSeed = static_cast(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); @@ -343,7 +344,7 @@ class CloseTrackRejection } } - bool isClosePair() const + [[nodiscard]] bool isClosePair() const { if (!mIsActivated) { return false; @@ -368,7 +369,7 @@ class CloseTrackRejection return isCloseAverage || isCloseAnyRadius; } - bool isActivated() const { return mIsActivated; } + [[nodiscard]] bool isActivated() const { return mIsActivated; } private: std::optional phistar(float magfield, float radius, float signedPt, float phi) @@ -418,7 +419,7 @@ class CloseTrackRejection std::uniform_int_distribution mSwapDist{0, 1}; }; -template +template class ClosePairRejectionTrackTrack { public: @@ -434,18 +435,18 @@ class ClosePairRejectionTrackTrack void setMagField(float magField) { mCtr.setMagField(magField); } template - void setPair(T1 const& track1, T2 const& track2, T3 const& /*tracks*/) + void setPair(T1 const& track1, T2 const& track2, T3 const& /*tracks*/) // pass track table for compatibility with other classes { mCtr.compute(track1, track2); } - bool isClosePair() const { return mCtr.isClosePair(); } + [[nodiscard]] bool isClosePair() const { return mCtr.isClosePair(); } void fill(float kstar) { mCtr.fill(kstar); } private: CloseTrackRejection mCtr; }; -template +template class ClosePairRejectionV0V0 { public: @@ -478,7 +479,7 @@ class ClosePairRejectionV0V0 mCtrNeg.compute(negDau1, negDau2); } - bool isClosePair() const { return mCtrPos.isClosePair() || mCtrNeg.isClosePair(); } + [[nodiscard]] bool isClosePair() const { return mCtrPos.isClosePair() || mCtrNeg.isClosePair(); } void fill(float kstar) { @@ -491,7 +492,7 @@ class ClosePairRejectionV0V0 CloseTrackRejection mCtrNeg; }; -template +template class ClosePairRejectionTrackV0 // can also be used for any particle type that has pos/neg daughters, like resonances { public: @@ -518,7 +519,7 @@ class ClosePairRejectionTrackV0 // can also be used for any particle type that h } } - bool isClosePair() const { return mCtr.isClosePair(); } + [[nodiscard]] bool isClosePair() const { return mCtr.isClosePair(); } void fill(float kstar) { mCtr.fill(kstar); } @@ -526,7 +527,7 @@ class ClosePairRejectionTrackV0 // can also be used for any particle type that h CloseTrackRejection mCtr; }; -template +template class ClosePairRejectionTrackCascade { public: @@ -563,11 +564,7 @@ class ClosePairRejectionTrackCascade } } - bool - isClosePair() const - { - return mCtrBachelor.isClosePair(); - } + [[nodiscard]] bool isClosePair() const { return mCtrBachelor.isClosePair(); } void fill(float kstar) { @@ -580,7 +577,7 @@ class ClosePairRejectionTrackCascade CloseTrackRejection mCtrV0Daughter; }; -template +template class ClosePairRejectionTrackKink { public: @@ -605,13 +602,36 @@ class ClosePairRejectionTrackKink mCtr.compute(track, daughter); } - bool isClosePair() const { return mCtr.isClosePair(); } + [[nodiscard]] bool isClosePair() const { return mCtr.isClosePair(); } + void fill(float kstar) { mCtr.fill(kstar); } + + private: + CloseTrackRejection mCtr; +}; + +template +class ClosePairRejectionMcParticleMcParticle +{ + public: + template + void init(o2::framework::HistogramRegistry* registry, + std::map> const& specs, + T const& confCpr) + { + mCtr.init(registry, specs, confCpr, 1, 1); + mCtr.setMagField(confCpr.magField.value); + } + template + void setPair(T1 const& mcParticle1, T2 const& mcParticle2) + { + mCtr.compute(mcParticle1, mcParticle2); + } + [[nodiscard]] bool isClosePair() const { return mCtr.isClosePair(); } void fill(float kstar) { mCtr.fill(kstar); } private: CloseTrackRejection mCtr; }; -}; // namespace closepairrejection -}; // namespace o2::analysis::femto +}; // namespace o2::analysis::femto::closepairrejection #endif // PWGCF_FEMTO_CORE_CLOSEPAIRREJECTION_H_ diff --git a/PWGCF/Femto/Core/closeTripletRejection.h b/PWGCF/Femto/Core/closeTripletRejection.h index c75bc2cea37..f9b5b788762 100644 --- a/PWGCF/Femto/Core/closeTripletRejection.h +++ b/PWGCF/Femto/Core/closeTripletRejection.h @@ -21,15 +21,11 @@ #include #include -#include #include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::closetripletrejection { -namespace closetripletrejection -{ - constexpr const char PrefixCtrTrackTrackTrack[] = "CtrTrackTrackTrack"; using ConfCtrTrackTrackTrack = closepairrejection::ConfCpr; @@ -61,9 +57,9 @@ constexpr char PrefixTrack2CascadeBachelorSe[] = "CPR_Track2CascadeBachelor/SE/" constexpr char PrefixTrack1CascadeBachelorMe[] = "CPR_Track1CascadeBachelor/ME/"; constexpr char PrefixTrack2CascadeBachelorMe[] = "CPR_Track2CascadeBachelor/ME/"; -template +template class CloseTripletRejectionTrackTrackTrack { public: @@ -96,7 +92,7 @@ class CloseTripletRejectionTrackTrackTrack mCtrTrack23.setPair(track2, track3, trackTable); mCtrTrack13.setPair(track1, track3, trackTable); } - bool isCloseTriplet() const + [[nodiscard]] bool isCloseTriplet() const { return mCtrTrack12.isClosePair() || mCtrTrack23.isClosePair() || mCtrTrack13.isClosePair(); } @@ -114,9 +110,9 @@ class CloseTripletRejectionTrackTrackTrack closepairrejection::ClosePairRejectionTrackTrack mCtrTrack13; }; -template +template class CloseTripletRejectionTrackTrackV0 { public: @@ -148,7 +144,7 @@ class CloseTripletRejectionTrackTrackV0 mCtrTrack1V0.setPair(track1, v0, trackTable); mCtrTrack2V0.setPair(track2, v0, trackTable); } - bool isCloseTriplet() const + [[nodiscard]] bool isCloseTriplet() const { return mCtrTrack12.isClosePair() || mCtrTrack1V0.isClosePair() || mCtrTrack2V0.isClosePair(); } @@ -166,11 +162,11 @@ class CloseTripletRejectionTrackTrackV0 closepairrejection::ClosePairRejectionTrackV0 mCtrTrack2V0; }; -template +template class CloseTripletRejectionTrackTrackCascade { public: @@ -206,7 +202,7 @@ class CloseTripletRejectionTrackTrackCascade mCtrTrack1Cascade.setPair(track1, cascade, trackTable); mCtrTrack2Cascade.setPair(track2, cascade, trackTable); } - bool isCloseTriplet() const + [[nodiscard]] bool isCloseTriplet() const { return mCtrTrack12.isClosePair() || mCtrTrack1Cascade.isClosePair() || mCtrTrack2Cascade.isClosePair(); } @@ -224,6 +220,5 @@ class CloseTripletRejectionTrackTrackCascade closepairrejection::ClosePairRejectionTrackCascade mCtrTrack2Cascade; }; -}; // namespace closetripletrejection -}; // namespace o2::analysis::femto +} // namespace o2::analysis::femto::closetripletrejection #endif // PWGCF_FEMTO_CORE_CLOSETRIPLETREJECTION_H_ diff --git a/PWGCF/Femto/Core/collisionBuilder.h b/PWGCF/Femto/Core/collisionBuilder.h index 7eababf75a5..8bce654f441 100644 --- a/PWGCF/Femto/Core/collisionBuilder.h +++ b/PWGCF/Femto/Core/collisionBuilder.h @@ -41,11 +41,8 @@ #include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::collisionbuilder { -namespace collisionbuilder -{ - // configurables for collision selection struct ConfCollisionFilters : o2::framework::ConfigurableGroup { std::string prefix = std::string("CollisionFilter"); @@ -112,7 +109,7 @@ struct ConfCollisionSelection : o2::framework::ConfigurableGroup { o2::framework::Configurable centMax{"centMax", 100.f, "Maximum centrality (multiplicity percentile)"}; o2::framework::Configurable magFieldMin{"magFieldMin", -5, "Minimum magnetic field strength (kG)"}; o2::framework::Configurable magFieldMax{"magFieldMax", 5, "Maximum magnetic field strength (kG)"}; - o2::framework::Configurable collisionMask{"collisionMask", 0x0, "Bitmask for collision"}; + o2::framework::Configurable collisionMask{"collisionMask", 0x0, "Bitmask for collision"}; }; /// enum for all collision selections @@ -166,12 +163,12 @@ const std::unordered_map collisionSelectionNames = { }; -template -class CollisionSelection : public BaseSelection +template +class CollisionSelection : public BaseSelection { public: CollisionSelection() = default; - ~CollisionSelection() = default; + ~CollisionSelection() override = default; template void configure(o2::framework::HistogramRegistry* registry, T1 const& filter, T2 const& config) @@ -219,9 +216,9 @@ class CollisionSelection : public BaseSelectionaddSelection(kIsGoodItsLayersAll, collisionSelectionNames.at(kIsGoodItsLayersAll), config.isGoodItsLayersAll.value); } - const bool isMinimalCut = mPassThrough ? false : true; - const bool isOptionalCut = mPassThrough ? false : true; - const bool skipMostPermissiveBit = mPassThrough ? false : true; + const bool isMinimalCut = !mPassThrough; + const bool isOptionalCut = !mPassThrough; + const bool skipMostPermissiveBit = !mPassThrough; this->addSelection(kOccupancyMin, collisionSelectionNames.at(kOccupancyMin), config.occupancyMin.value, limits::kLowerLimit, skipMostPermissiveBit, isMinimalCut, false); this->addSelection(kOccupancyMax, collisionSelectionNames.at(kOccupancyMax), config.occupancyMax.value, limits::kUpperLimit, skipMostPermissiveBit, isMinimalCut, false); @@ -251,7 +248,7 @@ class CollisionSelection : public BaseSelection void setCentrality(const T& col) @@ -263,7 +260,7 @@ class CollisionSelection : public BaseSelection void setMultiplicity(const T& col) @@ -276,7 +273,7 @@ class CollisionSelection : public BaseSelection bool checkFilters(T const& col) const @@ -334,7 +331,7 @@ class CollisionSelection : public BaseSelectionassembleBitmask(); }; - bool passThroughAllCollisions() const { return mPassThrough; } + [[nodiscard]] bool passThroughAllCollisions() const { return mPassThrough; } protected: template @@ -411,7 +408,7 @@ struct ConfCollisionTables : o2::framework::ConfigurableGroup { o2::framework::Configurable produceQns{"produceQns", -1, "Produce Qn (-1: auto; 0 off; 1 on)"}; }; -template +template class CollisionBuilder { public: @@ -652,7 +649,6 @@ class CollisionBuilderDerivedToDerived } }; -} // namespace collisionbuilder -} // namespace o2::analysis::femto +} // namespace o2::analysis::femto::collisionbuilder ; #endif // PWGCF_FEMTO_CORE_COLLISIONBUILDER_H_ diff --git a/PWGCF/Femto/Core/collisionHistManager.h b/PWGCF/Femto/Core/collisionHistManager.h index 39d78a0e6ad..338da0ac63c 100644 --- a/PWGCF/Femto/Core/collisionHistManager.h +++ b/PWGCF/Femto/Core/collisionHistManager.h @@ -29,11 +29,8 @@ #include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::colhistmanager { -namespace colhistmanager -{ - enum ColHist { kPosZ, kMult, @@ -52,8 +49,12 @@ enum ColHist { kCentVsSphericity, kMultVsSphericity, // mc - kTrueCentVsCent, - kTrueMultVsMult, + kTruePosZ, // pure mc-truth, no reco collision (kMc without kReco) + kTrueCent, // pure mc-truth, no reco collision (kMc without kReco) + kTrueMult, // pure mc-truth, no reco collision (kMc without kReco) + kTruePosZVsPosZ, // reco-vs-truth correlation (kReco and kMc both set) + kTrueCentVsCent, // reco-vs-truth correlation (kReco and kMc both set) + kTrueMultVsMult, // reco-vs-truth correlation (kReco and kMc both set) kColHistLast }; @@ -80,31 +81,42 @@ constexpr std::array, kColHistLast> HistTable = { {kMultVsSphericity, o2::framework::HistType::kTH2F, "hMultVsSphericity", "Multiplicity vs Sphericity; Multiplicity; Sphericity"}, {kCentVsSphericity, o2::framework::HistType::kTH2F, "hCentVsSphericity", "Centrality vs Sphericity; Centrality (%); Sphericity"}, // mc + {kTruePosZ, o2::framework::HistType::kTH1F, "hTruePosZ", "True vertex Z (mc-truth collision); V_{Z,True} (cm); Entries"}, + {kTrueCent, o2::framework::HistType::kTH1F, "hTrueCent", "True centrality (mc-truth collision); Centrality_{True} (%); Entries"}, + {kTrueMult, o2::framework::HistType::kTH1F, "hTrueMult", "True multiplicity (mc-truth collision); Multiplicity_{True}; Entries"}, + {kTruePosZVsPosZ, o2::framework::HistType::kTH2F, "hTruePosZVsPosZ", "True Vertex Z vs Vertex Z; V_{Z,True} (cm); V_{Z} (cm)"}, {kTrueCentVsCent, o2::framework::HistType::kTH2F, "hTrueCentVsCent", "True centrality vs centrality; Centrality_{True} (%); Centrality (%)"}, {kTrueMultVsMult, o2::framework::HistType::kTH2F, "hTrueMultVsMult", "True multiplicity vs multiplicity; Multiplicity_{True}; Multiplicity"}, }}; +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define COL_HIST_ANALYSIS_MAP(conf) \ - {kPosZ, {conf.vtxZ}}, \ - {kMult, {conf.mult}}, \ - {kCent, {conf.cent}}, \ - {kMagField, {conf.magField}}, - -#define COL_HIST_QA_MAP(confAnalysis, confQa) \ - {kPosX, {confQa.vtxXY}}, \ - {kPosY, {confQa.vtxXY}}, \ - {kPos, {confQa.vtx}}, \ - {kSphericity, {confQa.sphericity}}, \ - {kOccupancy, {confQa.occupancy}}, \ - {kPoszVsMult, {confAnalysis.vtxZ, confAnalysis.mult}}, \ - {kPoszVsCent, {confAnalysis.vtxZ, confAnalysis.cent}}, \ - {kCentVsMult, {confAnalysis.cent, confAnalysis.mult}}, \ - {kMultVsSphericity, {confAnalysis.mult, confQa.sphericity}}, \ - {kCentVsSphericity, {confBinningAnalysis.cent, confQa.sphericity}}, - -#define COL_HIST_MC_MAP(conf) \ - {kTrueMultVsMult, {conf.mult, conf.mult}}, \ - {kTrueCentVsCent, {conf.cent, conf.cent}}, + {kPosZ, {(conf).vtxZ}}, \ + {kMult, {(conf).mult}}, \ + {kCent, {(conf).cent}}, \ + {kMagField, {(conf).magField}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define COL_HIST_QA_MAP(confAnalysis, confQa) \ + {kPosX, {(confQa).vtxXY}}, \ + {kPosY, {(confQa).vtxXY}}, \ + {kPos, {(confQa).vtx}}, \ + {kSphericity, {(confQa).sphericity}}, \ + {kOccupancy, {(confQa).occupancy}}, \ + {kPoszVsMult, {(confAnalysis).vtxZ, (confAnalysis).mult}}, \ + {kPoszVsCent, {(confAnalysis).vtxZ, (confAnalysis).cent}}, \ + {kCentVsMult, {(confAnalysis).cent, (confAnalysis).mult}}, \ + {kMultVsSphericity, {(confAnalysis).mult, (confQa).sphericity}}, \ + {kCentVsSphericity, {confBinningAnalysis.cent, (confQa).sphericity}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define COL_HIST_MC_MAP(conf) \ + {kTruePosZ, {(conf).vtxZ}}, \ + {kTrueCent, {(conf).cent}}, \ + {kTrueMult, {(conf).mult}}, \ + {kTruePosZVsPosZ, {(conf).vtxZ, (conf).vtxZ}}, \ + {kTrueCentVsCent, {(conf).cent, (conf).cent}}, \ + {kTrueMultVsMult, {(conf).mult, (conf).mult}}, template auto makeColHistSpecMap(const T& confBinningAnalysis) @@ -138,6 +150,10 @@ auto makeColMcQaHistSpecMap(const T1& confBinningAnalysis, const T2& confBinning COL_HIST_MC_MAP(confBinningAnalysis)}; } +// pure mc-truth collision (no reco counterpart) uses kTruePosZ/kTrueCent/kTrueMult, +// which are already included in makeColMcHistSpecMap()/makeColMcQaHistSpecMap() above — +// no separate spec-map builder needed; just don't pass a reco collision to fill(). + #undef COL_HIST_ANALYSIS_MAP #undef COL_HIST_QA_MAP #undef COL_HIST_MC_MAP @@ -155,8 +171,8 @@ struct ConfCollisionQaBinning : o2::framework::ConfigurableGroup { o2::framework::Configurable plot2d{"plot2d", true, "Enable 2d QA histograms"}; o2::framework::ConfigurableAxis vtx{"vtx", {120, 0.f, 12.f}, "Vertex position binning"}; o2::framework::ConfigurableAxis vtxXY{"vtxXY", {100, -1.f, 1.f}, "Vertex X/Y binning"}; - o2::framework::ConfigurableAxis sphericity{"sphericity", {100, 0.f, 1.f}, "Spericity Binning"}; - o2::framework::ConfigurableAxis occupancy{"occupancy", {500, 0.f, 5000.f}, "Spericity Binning"}; + o2::framework::ConfigurableAxis sphericity{"sphericity", {100, 0.f, 1.f}, "Sphericity Binning"}; + o2::framework::ConfigurableAxis occupancy{"occupancy", {500, 0.f, 5000.f}, "Occupancy Binning"}; }; class CollisionHistManager @@ -171,15 +187,20 @@ class CollisionHistManager T const& /*ConfCollisionBinning*/) { mHistogramRegistry = registry; - if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco)) { initAnalysis(Specs); } if constexpr (isFlagSet(mode, modes::Mode::kQa)) { initQa(Specs); } - if constexpr (isFlagSet(mode, modes::Mode::kMc)) { + // reco-vs-truth correlation: requires BOTH a reco collision and mc info + if constexpr (isFlagSet(mode, modes::Mode::kReco) && isFlagSet(mode, modes::Mode::kMc)) { initMc(Specs); } + // pure mc-truth collision: requires mc info WITHOUT a reco collision + if constexpr (isFlagSet(mode, modes::Mode::kMc) && !isFlagSet(mode, modes::Mode::kReco)) { + initMcTruth(Specs); + } } template @@ -198,27 +219,32 @@ class CollisionHistManager init(registry, Specs, ConfCollisionBinning); } + // single-collision fill: reco-only, qa-only, or pure mc-truth (kMc without kReco) template void fill(T const& col) { - if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco)) { fillAnalysis(col); } if constexpr (isFlagSet(mode, modes::Mode::kQa)) { fillQa(col); } + if constexpr (isFlagSet(mode, modes::Mode::kMc) && !isFlagSet(mode, modes::Mode::kReco)) { + fillMc(col); + } } + // two-argument fill: reco collision + its matched mc collision, for True-vs-Reco correlation template void fill(T1 const& col, T2 const& mcCols) { - if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco)) { fillAnalysis(col); } if constexpr (isFlagSet(mode, modes::Mode::kQa)) { fillQa(col); } - if constexpr (isFlagSet(mode, modes::Mode::kMc)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco) && isFlagSet(mode, modes::Mode::kMc)) { fillMc(col, mcCols); } } @@ -250,11 +276,22 @@ class CollisionHistManager } } + // reco-vs-truth correlation histograms (kReco and kMc both set) void initMc(std::map> const& Specs) { std::string mcDir = std::string(McDir); - mHistogramRegistry->add(mcDir + getHistNameV2(kTrueMultVsMult, HistTable), getHistDesc(kTrueMultVsMult, HistTable), getHistType(kTrueMultVsMult, HistTable), {Specs.at(kTrueMultVsMult)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePosZVsPosZ, HistTable), getHistDesc(kTruePosZVsPosZ, HistTable), getHistType(kTruePosZVsPosZ, HistTable), {Specs.at(kTruePosZVsPosZ)}); mHistogramRegistry->add(mcDir + getHistNameV2(kTrueCentVsCent, HistTable), getHistDesc(kTrueCentVsCent, HistTable), getHistType(kTrueCentVsCent, HistTable), {Specs.at(kTrueCentVsCent)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueMultVsMult, HistTable), getHistDesc(kTrueMultVsMult, HistTable), getHistType(kTrueMultVsMult, HistTable), {Specs.at(kTrueMultVsMult)}); + } + + // pure mc-truth collision: 1D only, no reco collision exists (kMc without kReco) + void initMcTruth(std::map> const& Specs) + { + std::string mcDir = std::string(McDir); + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePosZ, HistTable), getHistDesc(kTruePosZ, HistTable), getHistType(kTruePosZ, HistTable), {Specs.at(kTruePosZ)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueCent, HistTable), getHistDesc(kTrueCent, HistTable), getHistType(kTrueCent, HistTable), {Specs.at(kTrueCent)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueMult, HistTable), getHistDesc(kTrueMult, HistTable), getHistType(kTrueMult, HistTable), {Specs.at(kTrueMult)}); } template @@ -283,6 +320,7 @@ class CollisionHistManager } } + // reco collision + matched mc collision: fill reco-vs-truth 2D correlations template void fillMc(T1 const& col, T2 const& /*mcCols*/) { @@ -290,13 +328,22 @@ class CollisionHistManager return; } auto mcCol = col.template fMcCol_as(); - mHistogramRegistry->fill(HIST(McDir) + HIST(getHistName(kTrueMultVsMult, HistTable)), mcCol.mult(), col.mult()); + mHistogramRegistry->fill(HIST(McDir) + HIST(getHistName(kTruePosZVsPosZ, HistTable)), mcCol.posZ(), col.posZ()); mHistogramRegistry->fill(HIST(McDir) + HIST(getHistName(kTrueCentVsCent, HistTable)), mcCol.cent(), col.cent()); + mHistogramRegistry->fill(HIST(McDir) + HIST(getHistName(kTrueMultVsMult, HistTable)), mcCol.mult(), col.mult()); + } + + // pure mc-truth collision: 'col' here IS the truth collision, no reco object exists + template + void fillMc(T const& col) + { + mHistogramRegistry->fill(HIST(McDir) + HIST(getHistName(kTruePosZ, HistTable)), col.posZ()); + mHistogramRegistry->fill(HIST(McDir) + HIST(getHistName(kTrueCent, HistTable)), col.cent()); + mHistogramRegistry->fill(HIST(McDir) + HIST(getHistName(kTrueMult, HistTable)), col.mult()); } o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; bool mPlot2d = false; -}; // namespace femtounitedcolhistmanager -}; // namespace colhistmanager -}; // namespace o2::analysis::femto +}; +} // namespace o2::analysis::femto::colhistmanager #endif // PWGCF_FEMTO_CORE_COLLISIONHISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/dataTypes.h b/PWGCF/Femto/Core/dataTypes.h index c873bf14020..19e39de5828 100644 --- a/PWGCF/Femto/Core/dataTypes.h +++ b/PWGCF/Femto/Core/dataTypes.h @@ -18,9 +18,7 @@ #include -namespace o2::aod -{ -namespace femtodatatypes +namespace o2::analysis::femto::datatypes { // Note: Length of the bitmask is the limit of how many selections can be configured @@ -59,8 +57,6 @@ using ParticleType = uint16_t; using MomentumType = uint16_t; using TransverseMassType = uint16_t; -} // namespace femtodatatypes - -} // namespace o2::aod +} // namespace o2::analysis::femto::datatypes #endif // PWGCF_FEMTO_CORE_DATATYPES_H_ diff --git a/PWGCF/Femto/Core/femtoUtils.h b/PWGCF/Femto/Core/femtoUtils.h index f0a72abf4bd..1e0e87fb4e3 100644 --- a/PWGCF/Femto/Core/femtoUtils.h +++ b/PWGCF/Femto/Core/femtoUtils.h @@ -142,8 +142,9 @@ inline float calcPtnew(float pxMother, float pyMother, float pzMother, float pxD // Calculate mother momentum and direction versor float pMother = std::sqrt(pxMother * pxMother + pyMother * pyMother + pzMother * pzMother); - if (pMother < almost0) + if (pMother < almost0) { return -999.f; + } float versorX = pxMother / pMother; float versorY = pyMother / pMother; @@ -161,22 +162,26 @@ inline float calcPtnew(float pxMother, float pyMother, float pzMother, float pxD float b = -4.f * scalarProduct * k; float c = 4.f * ePi * ePi * massSigmaMinus * massSigmaMinus - k * k; - if (std::abs(a) < almost0) + if (std::abs(a) < almost0) { return -999.f; + } float d = b * b - 4.f * a * c; - if (d < 0.f) + if (d < 0.f) { return -999.f; + } float sqrtD = std::sqrt(d); float p1 = (-b + sqrtD) / (2.f * a); float p2 = (-b - sqrtD) / (2.f * a); // Pick physical solution: prefer P2 if positive, otherwise P1 - if (p2 < 0.f && p1 < 0.f) + if (p2 < 0.f && p1 < 0.f) { return -999.f; - if (p2 < 0.f) + } + if (p2 < 0.f) { return p1; + } // Choose solution closest to original momentum float p1Diff = std::abs(p1 - pMother); diff --git a/PWGCF/Femto/Core/histManager.h b/PWGCF/Femto/Core/histManager.h index ceadf18f38a..a0070a08f9f 100644 --- a/PWGCF/Femto/Core/histManager.h +++ b/PWGCF/Femto/Core/histManager.h @@ -21,11 +21,8 @@ #include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::histmanager { -namespace histmanager -{ - // plot level for secondaries during mc processing enum SecondaryPlotLevel { kSecondaryPlotLevel1 = 1, @@ -35,8 +32,16 @@ enum SecondaryPlotLevel { template struct HistInfo { - Hist hist; - o2::framework::HistType histtype; + constexpr HistInfo(Hist h, + o2::framework::HistType t, + std::string_view n, + std::string_view d) + : hist(h), histtype(t), histname(n), histdesc(d) + { + } + + Hist hist{}; + o2::framework::HistType histtype{o2::framework::kUndefinedHist}; std::string_view histname; std::string_view histdesc; }; @@ -80,6 +85,5 @@ constexpr const char* getHistDesc(EnumType variable, const ArrayType& array) return it != array.end() ? it->histdesc.data() : ""; } -} // namespace histmanager -} // namespace o2::analysis::femto +} // namespace o2::analysis::femto::histmanager #endif // PWGCF_FEMTO_CORE_HISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/kinkBuilder.h b/PWGCF/Femto/Core/kinkBuilder.h index 99e87514824..f8bc0e310f1 100644 --- a/PWGCF/Femto/Core/kinkBuilder.h +++ b/PWGCF/Femto/Core/kinkBuilder.h @@ -41,11 +41,8 @@ #include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::kinkbuilder { -namespace kinkbuilder -{ - // filters applied in the producer task struct ConfKinkFilters : o2::framework::ConfigurableGroup { std::string prefix = std::string("KinkFilters"); @@ -62,6 +59,7 @@ struct ConfKinkFilters : o2::framework::ConfigurableGroup { }; // selections bits for all kinks +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define KINK_DEFAULT_BITS \ o2::framework::Configurable> kinkTopoDcaMax{"kinkTopoDcaMax", {2.0f}, "Maximum kink topological DCA"}; \ o2::framework::Configurable> transRadMin{"transRadMin", {20.f}, "Minimum transverse radius (cm)"}; \ @@ -94,20 +92,21 @@ struct ConfSigmaPlusBits : o2::framework::ConfigurableGroup { #undef KINK_DEFAULT_BITS // base selection for analysis task for kinks -#define KINK_DEFAULT_SELECTIONS(defaultMassMin, defaultMassMax, defaultPdgCode) \ - o2::framework::Configurable pdgCodeAbs{"pdgCodeAbs", defaultPdgCode, "PDG code. Select antipartilce via sign"}; \ - o2::framework::Configurable ptMin{"ptMin", 0.f, "Minimum pT"}; \ - o2::framework::Configurable ptMax{"ptMax", 999.f, "Maximum pT"}; \ - o2::framework::Configurable etaMin{"etaMin", -10.f, "Minimum eta"}; \ - o2::framework::Configurable etaMax{"etaMax", 10.f, "Maximum eta"}; \ - o2::framework::Configurable phiMin{"phiMin", 0.f, "Minimum phi"}; \ - o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; \ - o2::framework::Configurable massMin{"massMin", defaultMassMin, "Minimum invariant mass for Sigma"}; \ - o2::framework::Configurable massMax{"massMax", defaultMassMax, "Maximum invariant mass for Sigma"}; \ - o2::framework::Configurable mask{"mask", 0x0, "Bitmask for kink selection"}; +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define KINK_DEFAULT_SELECTIONS(defaultMassMin, defaultMassMax, defaultPdgCode) \ + o2::framework::Configurable pdgCodeAbs{"pdgCodeAbs", (defaultPdgCode), "PDG code. Select antipartilce via sign"}; \ + o2::framework::Configurable ptMin{"ptMin", 0.f, "Minimum pT"}; \ + o2::framework::Configurable ptMax{"ptMax", 999.f, "Maximum pT"}; \ + o2::framework::Configurable etaMin{"etaMin", -10.f, "Minimum eta"}; \ + o2::framework::Configurable etaMax{"etaMax", 10.f, "Maximum eta"}; \ + o2::framework::Configurable phiMin{"phiMin", 0.f, "Minimum phi"}; \ + o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; \ + o2::framework::Configurable massMin{"massMin", (defaultMassMin), "Minimum invariant mass for Sigma"}; \ + o2::framework::Configurable massMax{"massMax", (defaultMassMax), "Maximum invariant mass for Sigma"}; \ + o2::framework::Configurable mask{"mask", 0x0, "Bitmask for kink selection"}; // base selection for analysis task for sigmas -template +template struct ConfSigmaSelection : o2::framework::ConfigurableGroup { std::string prefix = Prefix; KINK_DEFAULT_SELECTIONS(1.1, 1.3, 3112) @@ -115,7 +114,7 @@ struct ConfSigmaSelection : o2::framework::ConfigurableGroup { }; // base selection for analysis task for sigma plus -template +template struct ConfSigmaPlusSelection : o2::framework::ConfigurableGroup { std::string prefix = Prefix; KINK_DEFAULT_SELECTIONS(1.1, 1.3, 3222) @@ -177,12 +176,12 @@ const std::unordered_map kinkSelectionNames = { /// \class KinkCuts /// \brief Cut class to contain and execute all cuts applied to kinks -template -class KinkSelection : public BaseSelection +template +class KinkSelection : public BaseSelection { public: KinkSelection() = default; - ~KinkSelection() = default; + ~KinkSelection() override = default; template void configure(o2::framework::HistogramRegistry* registry, T1& config, T2& filter) @@ -339,13 +338,13 @@ class KinkSelection : public BaseSelection produceSigmaPlusExtras{"produceSigmaPlusExtras", -1, "Produce SigmaPlusExtras (-1: auto; 0 off; 1 on)"}; }; -template +template class KinkBuilder { public: @@ -606,20 +605,14 @@ class KinkBuilderDerivedToDerived bool collisionHasTooFewSigma(T1 const& col, T2 const& /*sigmaTable*/, T3& partitionSigma, T4& cache) { auto sigmaSlice = partitionSigma->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); - if (sigmaSlice.size() >= mLimitSigma) { - return false; - } - return true; + return sigmaSlice.size() < mLimitSigma; } template bool collisionHasTooFewSigmaPlus(T1 const& col, T2 const& /*sigmaPlusTable*/, T3& partitionSigmaPlus, T4& cache) { auto sigmaPlusSlice = partitionSigmaPlus->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); - if (sigmaPlusSlice.size() >= mLimitSigmaPlus) { - return false; - } - return true; + return sigmaPlusSlice.size() < mLimitSigmaPlus; } template @@ -668,7 +661,5 @@ class KinkBuilderDerivedToDerived int mLimitSigma = 0; int mLimitSigmaPlus = 0; }; - -} // namespace kinkbuilder -} // namespace o2::analysis::femto +} // namespace o2::analysis::femto::kinkbuilder #endif // PWGCF_FEMTO_CORE_KINKBUILDER_H_ diff --git a/PWGCF/Femto/Core/kinkHistManager.h b/PWGCF/Femto/Core/kinkHistManager.h index f0a5c5dae3f..1ffe73e272b 100644 --- a/PWGCF/Femto/Core/kinkHistManager.h +++ b/PWGCF/Femto/Core/kinkHistManager.h @@ -37,9 +37,7 @@ #include #include -namespace o2::analysis::femto -{ -namespace kinkhistmanager +namespace o2::analysis::femto::kinkhistmanager { // enum for kink histograms enum KinkHist { @@ -88,24 +86,26 @@ enum KinkHist { constexpr std::size_t MaxSecondary = 3; -#define KINK_DEFAULT_BINNING(defaultMassMin, defaultMassMax) \ - o2::framework::ConfigurableAxis pt{"pt", {{600, 0, 6}}, "Pt"}; \ - o2::framework::ConfigurableAxis eta{"eta", {{300, -1.5, 1.5}}, "Eta"}; \ - o2::framework::ConfigurableAxis phi{"phi", {{720, 0, 1.f * o2::constants::math::TwoPI}}, "Phi"}; \ - o2::framework::ConfigurableAxis mass{"mass", {{200, defaultMassMin, defaultMassMax}}, "Mass"}; \ - o2::framework::ConfigurableAxis sign{"sign", {{3, -1.5, 1.5}}, "Sign"}; \ +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define KINK_DEFAULT_BINNING(defaultMassMin, defaultMassMax) \ + o2::framework::ConfigurableAxis pt{"pt", {{600, 0, 6}}, "Pt"}; \ + o2::framework::ConfigurableAxis eta{"eta", {{300, -1.5, 1.5}}, "Eta"}; \ + o2::framework::ConfigurableAxis phi{"phi", {{720, 0, 1.f * o2::constants::math::TwoPI}}, "Phi"}; \ + o2::framework::ConfigurableAxis mass{"mass", {{200, (defaultMassMin), (defaultMassMax)}}, "Mass"}; \ + o2::framework::ConfigurableAxis sign{"sign", {{3, -1.5, 1.5}}, "Sign"}; \ o2::framework::ConfigurableAxis pdgCodes{"pdgCodes", {{8001, -4000.5, 4000.5}}, "PDG codes of selected V0s"}; -template +template struct ConfSigmaBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; KINK_DEFAULT_BINNING(1.1, 1.3) }; -template +template struct ConfSigmaPlusBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; KINK_DEFAULT_BINNING(1.1, 1.3) }; + #undef KINK_DEFAULT_BINNING constexpr const char PrefixSigmaBinning1[] = "SigmaBinning1"; @@ -114,7 +114,7 @@ using ConfSigmaBinning1 = ConfSigmaBinning; constexpr const char PrefixSigmaPlusBinning1[] = "SigmaPlusBinning1"; using ConfSigmaPlusBinning1 = ConfSigmaPlusBinning; -template +template struct ConfKinkQaBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; o2::framework::Configurable plot2d{"plot2d", true, "Enable 2d QA h histograms"}; @@ -171,46 +171,50 @@ constexpr std::array, kKinkHistLast> HistTable = {kSecondary3, o2::framework::HistType::kTH2F, "hFromSecondary3", "Particles from seconary decay; p_{T} (GeV/#it{c}); kink angle"}, {kSecondaryOther, o2::framework::HistType::kTH2F, "hFromSecondaryOther", "Particles from every other seconary decay; p_{T} (GeV/#it{c}); kink angle"}}}; +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define KINK_HIST_ANALYSIS_MAP(conf) \ - {kPt, {conf.pt}}, \ - {kEta, {conf.eta}}, \ - {kPhi, {conf.phi}}, \ - {kMass, {conf.mass}}, \ - {kSign, {conf.sign}}, - -#define KINK_HIST_MC_MAP(conf) \ - {kTruePt, {conf.pt}}, \ - {kTrueEta, {conf.eta}}, \ - {kTruePhi, {conf.phi}}, \ - {kPdg, {conf.pdgCodes}}, \ - {kPdgMother, {conf.pdgCodes}}, \ - {kPdgPartonicMother, {conf.pdgCodes}}, - -#define KINK_HIST_QA_MAP(confAnalysis, confQa) \ - {kKinkAngle, {confQa.kinkAngle}}, \ - {kDcaMothToPV, {confQa.dcaMothToPV}}, \ - {kDcaDaugToPV, {confQa.dcaDaugToPV}}, \ - {kDecayVtxX, {confQa.decayVertex}}, \ - {kDecayVtxY, {confQa.decayVertex}}, \ - {kDecayVtxZ, {confQa.decayVertex}}, \ - {kDecayVtx, {confQa.decayVertex}}, \ - {kTransRadius, {confQa.transRadius}}, \ - {kPtVsEta, {confAnalysis.pt, confAnalysis.eta}}, \ - {kPtVsPhi, {confAnalysis.pt, confAnalysis.phi}}, \ - {kPhiVsEta, {confAnalysis.phi, confAnalysis.eta}}, \ - {kPtVsKinkAngle, {confAnalysis.pt, confQa.kinkAngle}}, \ - {kPtVsDecayRadius, {confAnalysis.pt, confQa.transRadius}}, - -#define KINK_HIST_MC_QA_MAP(confAnalysis, confQa) \ - {kNoMcParticle, {confAnalysis.pt, confQa.kinkAngle}}, \ - {kPrimary, {confAnalysis.pt, confQa.kinkAngle}}, \ - {kFromWrongCollision, {confAnalysis.pt, confQa.kinkAngle}}, \ - {kFromMaterial, {confAnalysis.pt, confQa.kinkAngle}}, \ - {kMissidentified, {confAnalysis.pt, confQa.kinkAngle}}, \ - {kSecondary1, {confAnalysis.pt, confQa.kinkAngle}}, \ - {kSecondary2, {confAnalysis.pt, confQa.kinkAngle}}, \ - {kSecondary3, {confAnalysis.pt, confQa.kinkAngle}}, \ - {kSecondaryOther, {confAnalysis.pt, confQa.kinkAngle}}, + {kPt, {(conf).pt}}, \ + {kEta, {(conf).eta}}, \ + {kPhi, {(conf).phi}}, \ + {kMass, {(conf).mass}}, \ + {kSign, {(conf).sign}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define KINK_HIST_MC_MAP(conf) \ + {kTruePt, {(conf).pt}}, \ + {kTrueEta, {(conf).eta}}, \ + {kTruePhi, {(conf).phi}}, \ + {kPdg, {(conf).pdgCodes}}, \ + {kPdgMother, {(conf).pdgCodes}}, \ + {kPdgPartonicMother, {(conf).pdgCodes}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define KINK_HIST_QA_MAP(confAnalysis, confQa) \ + {kKinkAngle, {(confQa).kinkAngle}}, \ + {kDcaMothToPV, {(confQa).dcaMothToPV}}, \ + {kDcaDaugToPV, {(confQa).dcaDaugToPV}}, \ + {kDecayVtxX, {(confQa).decayVertex}}, \ + {kDecayVtxY, {(confQa).decayVertex}}, \ + {kDecayVtxZ, {(confQa).decayVertex}}, \ + {kDecayVtx, {(confQa).decayVertex}}, \ + {kTransRadius, {(confQa).transRadius}}, \ + {kPtVsEta, {(confAnalysis).pt, (confAnalysis).eta}}, \ + {kPtVsPhi, {(confAnalysis).pt, (confAnalysis).phi}}, \ + {kPhiVsEta, {(confAnalysis).phi, (confAnalysis).eta}}, \ + {kPtVsKinkAngle, {(confAnalysis).pt, (confQa).kinkAngle}}, \ + {kPtVsDecayRadius, {(confAnalysis).pt, (confQa).transRadius}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define KINK_HIST_MC_QA_MAP(confAnalysis, confQa) \ + {kNoMcParticle, {(confAnalysis).pt, (confQa).kinkAngle}}, \ + {kPrimary, {(confAnalysis).pt, (confQa).kinkAngle}}, \ + {kFromWrongCollision, {(confAnalysis).pt, (confQa).kinkAngle}}, \ + {kFromMaterial, {(confAnalysis).pt, (confQa).kinkAngle}}, \ + {kMissidentified, {(confAnalysis).pt, (confQa).kinkAngle}}, \ + {kSecondary1, {(confAnalysis).pt, (confQa).kinkAngle}}, \ + {kSecondary2, {(confAnalysis).pt, (confQa).kinkAngle}}, \ + {kSecondary3, {(confAnalysis).pt, (confQa).kinkAngle}}, \ + {kSecondaryOther, {(confAnalysis).pt, (confQa).kinkAngle}}, template auto makeKinkHistSpecMap(const T& confBinningAnalysis) @@ -263,8 +267,8 @@ constexpr std::string_view McDir = "MC/"; constexpr int AbsChargeDaughters = 1; -template class KinkHistManager { @@ -307,7 +311,7 @@ class KinkHistManager } mChaDauManager.template init(registry, ChaDauSpecs, absCharge, chaDauCharge, chaDauPdgCodeAbs); - if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco)) { this->initAnalysis(KinkSpecs); } if constexpr (isFlagSet(mode, modes::Mode::kQa)) { @@ -356,7 +360,7 @@ class KinkHistManager } mChaDauManager.template init(registry, ChaDauSpecs, absCharge, chaDauCharge, chaDauPdgCodeAbs, ConfChaDauBinningQa); - if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco)) { this->initAnalysis(KinkSpecs); } if constexpr (isFlagSet(mode, modes::Mode::kQa)) { @@ -374,7 +378,7 @@ class KinkHistManager // auto chaDaughter = kinkcandidate.template chaDau_as(); auto chaDaughter = tracks.rawIteratorAt(kinkCandidate.chaDauId() - tracks.offset()); mChaDauManager.template fill(chaDaughter, tracks); - if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco)) { this->fillAnalysis(kinkCandidate); } if constexpr (isFlagSet(mode, modes::Mode::kQa)) { @@ -387,7 +391,7 @@ class KinkHistManager { auto chaDaughter = tracks.rawIteratorAt(kinkCandidate.chaDauId() - tracks.offset()); mChaDauManager.template fill(chaDaughter, tracks, mcParticles, mcMothers, mcPartonicMothers); - if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { this->fillAnalysis(kinkCandidate); } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { @@ -559,16 +563,16 @@ class KinkHistManager mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kPdg, HistTable)), mcParticle.pdgCode()); // get mother - if (kinkCandidate.has_fMcMother()) { - auto mother = kinkCandidate.template fMcMother_as(); + if (mcParticle.has_fMcMother()) { + auto mother = mcParticle.template fMcMother_as(); mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kPdgMother, HistTable)), mother.pdgCode()); } else { mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kPdgMother, HistTable)), 0); } // get partonic mother - if (kinkCandidate.has_fMcPartMoth()) { - auto partonicMother = kinkCandidate.template fMcPartMoth_as(); + if (mcParticle.has_fMcPartMoth()) { + auto partonicMother = mcParticle.template fMcPartMoth_as(); mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kPdgPartonicMother, HistTable)), partonicMother.pdgCode()); } else { mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kPdgPartonicMother, HistTable)), 0); @@ -593,8 +597,8 @@ class KinkHistManager mHistogramRegistry->fill(HIST(kinkPrefix) + HIST(McDir) + HIST(getHistName(kFromMaterial, HistTable)), kinkCandidate.pt(), kinkCandidate.kinkAngle()); break; case modes::McOrigin::kFromSecondaryDecay: - if (kinkCandidate.has_fMcMother()) { - auto mother = kinkCandidate.template fMcMother_as(); + if (mcParticle.has_fMcMother()) { + auto mother = mcParticle.template fMcMother_as(); int motherPdgCode = std::abs(mother.pdgCode()); // Switch on PDG of the mother if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel1 && motherPdgCode == mPdgCodesSecondaryMother[0]) { @@ -625,6 +629,5 @@ class KinkHistManager int mPlotNSecondaries = 0; std::array mPdgCodesSecondaryMother = {0}; }; -}; // namespace kinkhistmanager -}; // namespace o2::analysis::femto +}; // namespace o2::analysis::femto::kinkhistmanager #endif // PWGCF_FEMTO_CORE_KINKHISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/mcBuilder.h b/PWGCF/Femto/Core/mcBuilder.h index 812de9b7fca..425f391e4c5 100644 --- a/PWGCF/Femto/Core/mcBuilder.h +++ b/PWGCF/Femto/Core/mcBuilder.h @@ -21,6 +21,7 @@ #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/DataModel/FemtoTables.h" +#include #include #include #include @@ -33,11 +34,11 @@ #include #include -namespace o2::analysis::femto -{ -namespace mcbuilder +namespace o2::analysis::femto::mcbuilder { +constexpr int ProducedByDecay = 4; + struct ConfMc : o2::framework::ConfigurableGroup { std::string prefix = std::string("MonteCarlo"); o2::framework::Configurable passThrough{"passThrough", false, "Passthrough all MC collisions and particles"}; @@ -49,6 +50,7 @@ struct McBuilderProducts : o2::framework::ProducesGroup { o2::framework::Produces producedMcParticles; o2::framework::Produces producedMothers; o2::framework::Produces producedPartonicMothers; + o2::framework::Produces producedMcMotherLabels; o2::framework::Produces producedCollisionLabels; o2::framework::Produces producedTrackLabels; @@ -66,8 +68,9 @@ struct ConfMcTables : o2::framework::ConfigurableGroup { o2::framework::Configurable produceMcParticles{"produceMcParticles", -1, "Produce MC particles (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable produceMcMothers{"produceMcMothers", -1, "Produce MC mother particles (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable produceMcPartonicMothers{"produceMcPartonicMothers", -1, "Produce MC partonic mother particles (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable producedMcMotherLabels{"producedMcMotherLabels", -1, "Produce mother/partonic-mother labels (-1: auto; 0 off; 1 on)"}; - o2::framework::Configurable producedCollisionLabels{"producedCollisionLabels", -1, "Produce MC partonic mother particles (-1: auto; 0 off; 1 on)"}; + o2::framework::Configurable producedCollisionLabels{"producedCollisionLabels", -1, "Produce MC collision labels (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable producedTrackLabels{"producedTrackLabels", -1, "Produce track labels (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable producedLambdaLabels{"producedLambdaLabels", -1, "Produce lambda labels (-1: auto; 0 off; 1 on)"}; o2::framework::Configurable producedK0shortLabels{"producedK0shortLabels", -1, "Produce k0short labels (-1: auto; 0 off; 1 on)"}; @@ -77,6 +80,38 @@ struct ConfMcTables : o2::framework::ConfigurableGroup { o2::framework::Configurable producedOmegaLabels{"producedOmegaLabels", -1, "Produce omega labels (-1: auto; 0 off; 1 on)"}; }; +// filter/selections for mc collision and mc particles + +struct ConfMcCollisionFilters : o2::framework::ConfigurableGroup { + std::string prefix = std::string("McCollisionFilter"); + o2::framework::Configurable vtxZMin{"vtxZMin", -10.f, "Minimum vertex Z position (cm)"}; + o2::framework::Configurable vtxZMax{"vtxZMax", 10.f, "Maximum vertex Z position (cm)"}; + o2::framework::Configurable multMin{"multMin", 0.f, "Minimum multiplicity"}; + o2::framework::Configurable multMax{"multMax", 5000.f, "Maximum multiplicity"}; + o2::framework::Configurable centMin{"centMin", 0.f, "Minimum centrality (multiplicity percentile)"}; + o2::framework::Configurable centMax{"centMax", 100.f, "Maximum centrality (multiplicity percentile)"}; +}; + +template +struct ConfMcParticleSelection : o2::framework::ConfigurableGroup { + std::string prefix = std::string(Prefix); + // kinematic cuts for filtering tracks + o2::framework::Configurable ptMin{"ptMin", 0.2f, "Minimum pT"}; + o2::framework::Configurable ptMax{"ptMax", 6.f, "Maximum pT"}; + o2::framework::Configurable etaMin{"etaMin", -0.9f, "Minimum eta"}; + o2::framework::Configurable etaMax{"etaMax", 0.9f, "Maximum eta"}; + o2::framework::Configurable phiMin{"phiMin", 0.f, "Minimum phi"}; + o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; + o2::framework::Configurable pdgCodeAbs{"pdgCodeAbs", 2212, "Absolute value of PDG code. Set sign of charge to -1 for antiparticle."}; + o2::framework::Configurable chargeSign{"chargeSign", 1, "Particle charge sign: +1 for positive, -1 for negative, 0 for both"}; +}; + +constexpr const char PrefixMcParticleSelection1[] = "McParticleSelection1"; +constexpr const char PrefixMcParticleSelection2[] = "McParticleSelection2"; + +using ConfMcParticleSelection1 = ConfMcParticleSelection; +using ConfMcParticleSelection2 = ConfMcParticleSelection; + class McBuilder { public: @@ -92,6 +127,7 @@ class McBuilder mProduceMcParticles = utils::enableTable("FMcParticles_001", table.produceMcParticles.value, initContext); mProduceMcMothers = utils::enableTable("FMcMothers_001", table.produceMcMothers.value, initContext); mProduceMcPartonicMothers = utils::enableTable("FMcPartMoths_001", table.produceMcPartonicMothers.value, initContext); + mProduceMcMotherLabels = utils::enableTable("FMcMotherLabels", table.producedMcMotherLabels.value, initContext); mProduceCollisionLabels = utils::enableTable("FColLabels", table.producedCollisionLabels.value, initContext); mProduceTrackLabels = utils::enableTable("FTrackLabels", table.producedTrackLabels.value, initContext); @@ -104,6 +140,7 @@ class McBuilder if (mProduceMcCollisions || mProduceCollisionLabels || mProduceMcParticles || mProduceMcMothers || mProduceMcPartonicMothers || + mProduceMcMotherLabels || mProduceTrackLabels || mProduceLambdaLabels || mProduceK0shortLabels || mProduceSigmaLabels || mProduceSigmaPlusLabels || @@ -143,34 +180,61 @@ class McBuilder } } + template + void fillMcCollision(T1 const& mcCol, T2& mcProducts) + { + float centrality = -1; + float multiplicity = -1; + if constexpr (modes::isFlagSet(system, modes::System::kPP)) { + centrality = mcCol.centFT0M(); + multiplicity = mcCol.multMCNParticlesEta08(); + } + if constexpr (modes::isFlagSet(system, modes::System::kPbPb)) { + centrality = mcCol.centFT0C(); + multiplicity = mcCol.multMCNParticlesEta08(); + } + + mcProducts.producedMcCollisions( + mcCol.posZ(), + multiplicity, + centrality); + mCollisionMap.emplace(mcCol.globalIndex(), mcProducts.producedMcCollisions.lastIndex()); + } + + template + void fillMcParticle(T1 const& mcParticle, T2 const& mcParticles, T3 const& mcCol, T4& mcProducts) + { + this->getOrCreateMcParticleRow(mcParticle, mcParticles, mcCol, mcProducts); + } + template void fillMcTrackWithLabel(T1 const& col, T2 const& mcCols, T3 const& track, T4 const& mcParticles, T5& mcProducts) { if (!mProduceTrackLabels) { - mcProducts.producedTrackLabels(-1, -1, -1); + mcProducts.producedTrackLabels(-1); return; } - fillMcLabelGeneric(col, mcCols, track, mcParticles, mcProducts, [](auto& prod, int64_t p, int64_t m, int64_t pm) { prod.producedTrackLabels(p, m, pm); }); + fillMcLabelGeneric(col, mcCols, track, mcParticles, mcProducts, [](auto& prod, int64_t p) { prod.producedTrackLabels(p); }); } template void fillMcLambdaWithLabel(T1 const& col, T2 const& mcCols, T3 const& lambda, T4 const& mcParticles, T5& mcProducts) { if (!mProduceLambdaLabels) { - mcProducts.producedLambdaLabels(-1, -1, -1); + mcProducts.producedLambdaLabels(-1); return; } - fillMcLabelGeneric(col, mcCols, lambda, mcParticles, mcProducts, [](auto& prod, int64_t p, int64_t m, int64_t pm) { prod.producedLambdaLabels(p, m, pm); }); + fillMcLabelGeneric(col, mcCols, lambda, mcParticles, mcProducts, [](auto& prod, int64_t p) { prod.producedLambdaLabels(p); }); } template void fillMcK0shortWithLabel(T1 const& col, T2 const& mcCols, T3 const& k0short, T4 const& mcParticles, T5& mcProducts) { if (!mProduceK0shortLabels) { - mcProducts.producedK0shortLabels(-1, -1, -1); + mcProducts.producedK0shortLabels(-1); return; } - fillMcLabelGeneric(col, mcCols, k0short, mcParticles, mcProducts, [](auto& prod, int64_t p, int64_t m, int64_t pm) { prod.producedK0shortLabels(p, m, pm); }); + fillMcLabelGeneric(col, mcCols, k0short, mcParticles, mcProducts, [](auto& prod, int64_t p) { prod.producedK0shortLabels(p); }); } template @@ -179,7 +243,7 @@ class McBuilder if (!mProduceSigmaLabels) { return; } - fillMcLabelGeneric(col, mcCols, sigmaDaughter, mcParticles, mcProducts, [](auto& prod, int64_t p, int64_t m, int64_t pm) { prod.producedSigmaLabels(p, m, pm); }, true); + fillMcLabelGeneric(col, mcCols, sigmaDaughter, mcParticles, mcProducts, [](auto& prod, int64_t p) { prod.producedSigmaLabels(p); }, true); } template @@ -188,27 +252,27 @@ class McBuilder if (!mProduceSigmaPlusLabels) { return; } - fillMcLabelGeneric(col, mcCols, sigmaPlusDaughter, mcParticles, mcProducts, [](auto& prod, int64_t p, int64_t m, int64_t pm) { prod.producedSigmaPlusLabels(p, m, pm); }, true); + fillMcLabelGeneric(col, mcCols, sigmaPlusDaughter, mcParticles, mcProducts, [](auto& prod, int64_t p) { prod.producedSigmaPlusLabels(p); }, true); } template void fillMcXiWithLabel(T1 const& col, T2 const& mcCols, T3 const& xi, T4 const& mcParticles, T5& mcProducts) { if (!mProduceXiLabels) { - mcProducts.producedXiLabels(-1, -1, -1); + mcProducts.producedXiLabels(-1); return; } - fillMcLabelGeneric(col, mcCols, xi, mcParticles, mcProducts, [](auto& prod, int64_t p, int64_t m, int64_t pm) { prod.producedXiLabels(p, m, pm); }); + fillMcLabelGeneric(col, mcCols, xi, mcParticles, mcProducts, [](auto& prod, int64_t p) { prod.producedXiLabels(p); }); } template void fillMcOmegaWithLabel(T1 const& col, T2 const& mcCols, T3 const& omega, T4 const& mcParticles, T5& mcProducts) { if (!mProduceOmegaLabels) { - mcProducts.producedOmegaLabels(-1, -1, -1); + mcProducts.producedOmegaLabels(-1); return; } - fillMcLabelGeneric(col, mcCols, omega, mcParticles, mcProducts, [](auto& prod, int64_t p, int64_t m, int64_t pm) { prod.producedOmegaLabels(p, m, pm); }); + fillMcLabelGeneric(col, mcCols, omega, mcParticles, mcProducts, [](auto& prod, int64_t p) { prod.producedOmegaLabels(p); }); } bool fillAnyTable() const { return mFillAnyTable; } @@ -226,43 +290,57 @@ class McBuilder mMcPartonicMotherMap.reserve(mcParticles.size()); } + // mc only, then there is only 1 mc collision + template + void reset(T const& mcParticles) + { + mCollisionMap.clear(); + mMcParticleMap.clear(); + mMcParticleMap.reserve(mcParticles.size()); + mMcMotherMap.clear(); + mMcMotherMap.reserve(mcParticles.size()); + mMcPartonicMotherMap.clear(); + mMcPartonicMotherMap.reserve(mcParticles.size()); + } + private: - template - void fillMcCollision(T1 const& mcCol, T2& mcProducts) + template + modes::McOrigin getOrigin(T1 const& col, T2 const& /*mcCols*/, T3 const& mcParticle) { - float centrality = -1; - if constexpr (modes::isFlagSet(system, modes::System::kPP)) { - centrality = mcCol.centFT0M(); + // whether a particle is misidentified or not can only be checked by qa/pair task later so it is not set here + + // check if reconstructed collision has a generated collision + if (!col.has_mcCollision()) { + return modes::McOrigin::kFromWrongCollision; } - if constexpr (modes::isFlagSet(system, modes::System::kPbPb)) { - centrality = mcCol.centFT0C(); + + // now check collision ids, if they do not match, then the track belongs to another collision + if (col.mcCollisionId() != mcParticle.mcCollisionId()) { + return modes::McOrigin::kFromWrongCollision; } - mcProducts.producedMcCollisions(mcCol.multMCNParticlesEta08(), centrality); - mCollisionMap.emplace(mcCol.globalIndex(), mcProducts.producedMcCollisions.lastIndex()); + if (mcParticle.isPhysicalPrimary()) { + return modes::McOrigin::kPhysicalPrimary; + } + + if (mcParticle.has_mothers() && mcParticle.getProcess() == ProducedByDecay) { + return modes::McOrigin::kFromSecondaryDecay; + } + + // not a primary and not from a decay and not from a wrong collision, we label as material + return modes::McOrigin::kFromMaterial; } - template - modes::McOrigin getOrigin(T1 const& col, T2 const& /*mcCols*/, T3 const& mcParticle) + template + modes::McOrigin getOrigin(T1 const& mcParticle) { - // constants - const int producedByDecay = 4; - // check if reconstructed collision has a generated collision - if (col.has_mcCollision()) { - // now check collision ids, if they do not match, then the track belongs to another collision - if (col.mcCollisionId() != mcParticle.mcCollisionId()) { - return modes::McOrigin::kFromWrongCollision; - } - if (mcParticle.isPhysicalPrimary()) { - return modes::McOrigin::kPhysicalPrimary; - } else if (mcParticle.has_mothers() && mcParticle.getProcess() == producedByDecay) { - return modes::McOrigin::kFromSecondaryDecay; - } else { - // not a primary and not from a decay, we label as material - return modes::McOrigin::kFromMaterial; - } + if (mcParticle.isPhysicalPrimary()) { + return modes::McOrigin::kPhysicalPrimary; + } + if (mcParticle.has_mothers() && mcParticle.getProcess() == ProducedByDecay) { + return modes::McOrigin::kFromSecondaryDecay; } - return modes::McOrigin::kFromWrongCollision; + return modes::McOrigin::kFromMaterial; } template @@ -279,81 +357,79 @@ class McBuilder return it->second; } - template - void fillMcLabelGeneric(T1 const& col, - T2 const& mcCols, - T3 const& particle, - T4 const& mcParticles, - T5& mcProducts, - T6 writeLabels, - bool startFromMotherParticle = false) + /// Mc-only entry point: no reconstructed collision to match against, so origin + /// is derived purely from the mc particle itself. + template + int64_t getOrCreateMcParticleRow(T1 const& mcParticle, T2 const& mcParticles, T3 const& mcCol, T4& mcProducts) { - if (!particle.has_mcParticle()) { - writeLabels(mcProducts, -1, -1, -1); - return; - } - - auto mcParticle = particle.template mcParticle_as(); - auto mcCol = mcParticle.template mcCollision_as(); + auto origin = this->getOrigin(mcParticle); + return this->buildMcParticleRow(mcParticle, mcParticles, mcCol, origin, mcProducts); + } - if (startFromMotherParticle) { - // in case of e.g. sigmas we do not reconstruct the mother but the daughter, so here we want to start from the mother particle - auto mcDaughterParticle = particle.template mcParticle_as(); - if (!mcDaughterParticle.has_mothers()) { - writeLabels(mcProducts, -1, -1, -1); - return; - } - auto mothersOfDaughter = mcDaughterParticle.template mothers_as(); - mcParticle = mothersOfDaughter.front(); - } + /// Reco-matched entry point: origin is derived by comparing the reconstructed + /// collision against the mc collision. + template + int64_t getOrCreateMcParticleRow(T1 const& col, T2 const& mcCols, T3 const& mcParticle, T4 const& mcParticles, T5 const& mcCol, T6& mcProducts) + { + auto origin = this->getOrigin(col, mcCols, mcParticle); + return this->buildMcParticleRow(mcParticle, mcParticles, mcCol, origin, mcProducts); + } + /// Find-or-create the FMcParticles row for mcParticle. On first creation, also + /// resolves the mother / partonic mother (with kinematics) and writes the single + /// corresponding FMcMotherLabels row, so it always stays in lockstep, one row + /// per FMcParticles row. + template + int64_t buildMcParticleRow(T1 const& mcParticle, T2 const& mcParticles, T3 const& mcCol, modes::McOrigin origin, T4& mcProducts) + { int64_t mcParticleIndex = mcParticle.globalIndex(); - int64_t mcParticleRow = -1; - // MC particle auto itP = mMcParticleMap.find(mcParticleIndex); if (itP != mMcParticleMap.end()) { - mcParticleRow = itP->second; - } else { - auto origin = this->getOrigin(col, mcCols, mcParticle); - int64_t mcColId = this->getMcColId(mcCol, mcProducts); - - mcProducts.producedMcParticles( - mcColId, - static_cast(origin), - mcParticle.pdgCode(), - mcParticle.pt() * utils::signum(mcParticle.pdgCode()), - mcParticle.eta(), - mcParticle.phi()); - - mcParticleRow = mcProducts.producedMcParticles.lastIndex(); - mMcParticleMap[mcParticleIndex] = mcParticleRow; + return itP->second; } - // MC mother + int64_t mcColId = this->getMcColId(mcCol, mcProducts); + + mcProducts.producedMcParticles( + mcColId, + static_cast(origin), + mcParticle.pdgCode(), + mcParticle.pt() * utils::signum(mcParticle.pdgCode()), + mcParticle.eta(), + mcParticle.phi()); + + int64_t mcParticleRow = mcProducts.producedMcParticles.lastIndex(); + mMcParticleMap[mcParticleIndex] = mcParticleRow; + + // --- mother --- int64_t mcMotherRow = -1; if (mcParticle.has_mothers()) { - auto mothers = mcParticle.template mothers_as(); - auto mcMotherIndex = mothers.front().globalIndex(); + auto mothers = mcParticle.template mothers_as(); + auto motherParticle = mothers.front(); + auto mcMotherIndex = motherParticle.globalIndex(); auto itM = mMcMotherMap.find(mcMotherIndex); if (itM != mMcMotherMap.end()) { mcMotherRow = itM->second; } else { - mcProducts.producedMothers(mothers.front().pdgCode()); + auto motherOrigin = this->getOrigin(motherParticle); + mcProducts.producedMothers( + static_cast(motherOrigin), + motherParticle.pdgCode(), + motherParticle.pt() * utils::signum(motherParticle.pdgCode()), + motherParticle.eta(), + motherParticle.phi()); mcMotherRow = mcProducts.producedMothers.lastIndex(); mMcMotherMap[mcMotherIndex] = mcMotherRow; } } - // Partonic mother + // --- partonic mother --- int64_t mcPartonicMotherRow = -1; - int64_t mcPartonicMotherIndex = -1; - if (mFindLastPartonicMother) { - mcPartonicMotherIndex = this->findLastPartonicMother(mcParticle, mcParticles); - } else { - mcPartonicMotherIndex = this->findFirstPartonicMother(mcParticle, mcParticles); - } + int64_t mcPartonicMotherIndex = mFindLastPartonicMother + ? this->findLastPartonicMother(mcParticle, mcParticles) + : this->findFirstPartonicMother(mcParticle, mcParticles); if (mcPartonicMotherIndex >= 0) { auto itPM = mMcPartonicMotherMap.find(mcPartonicMotherIndex); if (itPM != mMcPartonicMotherMap.end()) { @@ -366,7 +442,45 @@ class McBuilder } } - writeLabels(mcProducts, mcParticleRow, mcMotherRow, mcPartonicMotherRow); + // exactly one FMcMotherLabels row per FMcParticles row, written here and only here + if (mProduceMcMotherLabels) { + mcProducts.producedMcMotherLabels(mcMotherRow, mcPartonicMotherRow); + } + + return mcParticleRow; + } + + template + void fillMcLabelGeneric(T1 const& col, + T2 const& mcCols, + T3 const& particle, + T4 const& mcParticles, + T5& mcProducts, + T6 writeLabels, + bool startFromMotherParticle = false) + { + if (!particle.has_mcParticle()) { + writeLabels(mcProducts, -1); + return; + } + + auto mcParticle = particle.template mcParticle_as(); + auto mcCol = mcParticle.template mcCollision_as(); + + if (startFromMotherParticle) { + // in case of e.g. sigmas we do not reconstruct the mother but the daughter, so here we want to start from the mother particle + auto mcDaughterParticle = particle.template mcParticle_as(); + if (!mcDaughterParticle.has_mothers()) { + writeLabels(mcProducts, -1); + return; + } + auto mothersOfDaughter = mcDaughterParticle.template mothers_as(); + mcParticle = mothersOfDaughter.front(); + } + + int64_t mcParticleRow = this->getOrCreateMcParticleRow(col, mcCols, mcParticle, mcParticles, mcCol, mcProducts); + + writeLabels(mcProducts, mcParticleRow); } template @@ -383,18 +497,21 @@ class McBuilder // keep for now, might be needed later // && ((80 < std::abs(o2::mcgenstatus::getGenStatusCode(p.statusCode())) && std::abs(o2::mcgenstatus::getGenStatusCode(p.statusCode())) < 90) || (100 < std::abs(o2::mcgenstatus::getGenStatusCode(p.statusCode())) && std::abs(o2::mcgenstatus::getGenStatusCode(p.statusCode())) < 110))) { // Pythia: mother range - for (int i = motherIds[0]; i <= motherIds[1]; i++) + for (int i = motherIds[0]; i <= motherIds[1]; i++) { allMotherIds.push_back(i); + } } else { // Otherwise just use them as given - for (const int& id : motherIds) + for (const int& id : motherIds) { allMotherIds.push_back(id); + } } // Loop over all mothers for (const int& i : allMotherIds) { - if (i < 0 || i >= mcParticles.size()) + if (i < 0 || i >= mcParticles.size()) { continue; + } const auto& mother = mcParticles.iteratorAt(i); int pdgAbs = std::abs(mother.pdgCode()); // Is it a parton? (quark or gluon) @@ -403,8 +520,9 @@ class McBuilder } // Recurse upward int64_t found = this->findFirstPartonicMother(mother, mcParticles); - if (found != -1) + if (found != -1) { return found; + } } // No partonic ancestor found return -1; @@ -417,8 +535,9 @@ class McBuilder int64_t currentIndex = mcParticle.globalIndex(); while (currentIndex >= 0 && currentIndex < mcParticles.size()) { const auto& current = mcParticles.iteratorAt(currentIndex); - if (!current.has_mothers()) + if (!current.has_mothers()) { break; + } auto motherIds = current.mothersIds(); int nextIndex = -1; const int defaultMotherSize = 2; @@ -432,8 +551,10 @@ class McBuilder } } } - if (nextIndex < 0 || nextIndex >= mcParticles.size()) + + if (nextIndex < 0 || nextIndex >= mcParticles.size()) { break; + } const auto& mother = mcParticles.iteratorAt(nextIndex); int pdgAbs = std::abs(mother.pdgCode()); int status = std::abs(o2::mcgenstatus::getGenStatusCode(mother.statusCode())); @@ -441,11 +562,12 @@ class McBuilder const int isBeamParticleLowerLimit = 11; const int isBeamParticleUpperLimit = 19; bool isBeam = (status >= isBeamParticleLowerLimit && status <= isBeamParticleUpperLimit); - if (isBeam) + if (isBeam) { return lastPartonIndex; - if (isParton) + } + if (isParton) { lastPartonIndex = nextIndex; - + } currentIndex = nextIndex; } return -1; @@ -467,6 +589,7 @@ class McBuilder bool mProduceSigmaPlusLabels = false; bool mProduceXiLabels = false; bool mProduceOmegaLabels = false; + bool mProduceMcMotherLabels = false; std::unordered_map mCollisionMap; @@ -474,9 +597,6 @@ class McBuilder std::unordered_map mMcMotherMap; std::unordered_map mMcPartonicMotherMap; }; - -} // namespace mcbuilder -// -} // namespace o2::analysis::femto +} // namespace o2::analysis::femto::mcbuilder #endif // PWGCF_FEMTO_CORE_MCBUILDER_H_ diff --git a/PWGCF/Femto/Core/mcParticleHistManager.h b/PWGCF/Femto/Core/mcParticleHistManager.h new file mode 100644 index 00000000000..b226e10459a --- /dev/null +++ b/PWGCF/Femto/Core/mcParticleHistManager.h @@ -0,0 +1,312 @@ +// Copyright 2019-2025 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file mcParticleHistManager.h +/// \brief histogram manager for mc particle histograms +/// \author Anton Riedel, TU München, anton.riedel@cern.ch + +#ifndef PWGCF_FEMTO_CORE_MCPARTICLEHISTMANAGER_H_ +#define PWGCF_FEMTO_CORE_MCPARTICLEHISTMANAGER_H_ + +#include "PWGCF/Femto/Core/histManager.h" +#include "PWGCF/Femto/Core/modes.h" + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace o2::analysis::femto::mcparticlehistmanager +{ +// enum for mc particle histograms +enum McParticleHist { + // kinemtics + kPt, + kEta, + kPhi, + kSign, + // pdg codes + kPdg, + kPdgMother, + kPdgPartonicMother, + // mother kinematics + kMotherPt, + kMotherEta, + kMotherPhi, + kMotherSign, + // origin (kept in sync with TrackHist, even though some categories + // are not expected to be populated for pure MC truth particles) + kOrigin, + kNoMcParticle, + kPrimary, + kFromWrongCollision, + kFromMaterial, + kMissidentified, + kSecondary1, + kSecondary2, + kSecondary3, + kSecondaryOther, + + kMcParticleHistLast +}; + +constexpr std::size_t MaxSecondary = 3; + +template +struct ConfMcParticleBinning : o2::framework::ConfigurableGroup { + std::string prefix = Prefix; + o2::framework::ConfigurableAxis pt{"pt", {{600, 0, 6}}, "Pt"}; + o2::framework::ConfigurableAxis eta{"eta", {{300, -1.5, 1.5}}, "Eta"}; + o2::framework::ConfigurableAxis phi{"phi", {{720, 0, 1.f * o2::constants::math::TwoPI}}, "Phi"}; + o2::framework::ConfigurableAxis sign{"sign", {{3, -1.5, 1.5}}, "Sign"}; + o2::framework::ConfigurableAxis pdgCodes{"pdgCodes", {{8001, -4000.5, 4000.5}}, "PDG codes of selected particles"}; + o2::framework::Configurable plotOrigins{"plotOrigins", true, "Plot pt distributions for different particle origins"}; + o2::framework::Configurable> pdgCodesForMothersOfSecondary{"pdgCodesForMothersOfSecondary", {3122}, "PDG codes of mothers of secondaries (Max 3 will be considered)"}; +}; + +constexpr const char PrefixMcParticleBinning1[] = "McParticleBinning1"; +constexpr const char PrefixMcParticleBinning2[] = "McParticleBinning2"; + +using ConfMcParticleBinning1 = ConfMcParticleBinning; +using ConfMcParticleBinning2 = ConfMcParticleBinning; + +// the enum gives the correct index in the array +constexpr std::array, kMcParticleHistLast> + HistTable = { + { + {kPt, o2::framework::HistType::kTH1F, "hPt", "Transverse Momentum; p_{T} (GeV/#it{c}); Entries"}, + {kEta, o2::framework::HistType::kTH1F, "hEta", "Pseudorapidity; #eta; Entries"}, + {kPhi, o2::framework::HistType::kTH1F, "hPhi", "Azimuthal angle; #varphi; Entries"}, + {kSign, o2::framework::HistType::kTH1F, "hSign", "Sign of charge; Sign; Entries"}, + {kPdg, o2::framework::HistType::kTH1F, "hPdg", "PDG code of the particle; PDG Code; Entries"}, + {kPdgMother, o2::framework::HistType::kTH1F, "hPdgMother", "PDG code of the mother; PDG Code; Entries"}, + {kPdgPartonicMother, o2::framework::HistType::kTH1F, "hPdgPartonicMother", "PDG code of the partonic mother; PDG Code; Entries"}, + {kMotherPt, o2::framework::HistType::kTH1F, "hMotherPt", "Mother transverse momentum; p_{T} (GeV/#it{c}); Entries"}, + {kMotherEta, o2::framework::HistType::kTH1F, "hMotherEta", "Mother pseudorapidity; #eta; Entries"}, + {kMotherPhi, o2::framework::HistType::kTH1F, "hMotherPhi", "Mother azimuthal angle; #varphi; Entries"}, + {kMotherSign, o2::framework::HistType::kTH1F, "hMotherSign", "Sign of mother charge; Sign; Entries"}, + {kOrigin, o2::framework::HistType::kTH1F, "hOrigin", "Status Codes (=Origin); Status Code; Entries"}, + {kNoMcParticle, o2::framework::HistType::kTH1F, "hNoMcParticle", "Particles with no associated MC information; p_{T} (GeV/#it{c}); Entries"}, + {kPrimary, o2::framework::HistType::kTH1F, "hPrimary", "Primary particles; p_{T} (GeV/#it{c}); Entries"}, + {kFromWrongCollision, o2::framework::HistType::kTH1F, "hFromWrongCollision", "Particles associated to wrong collision; p_{T} (GeV/#it{c}); Entries"}, + {kFromMaterial, o2::framework::HistType::kTH1F, "hFromMaterial", "Particles from material; p_{T} (GeV/#it{c}); Entries"}, + {kMissidentified, o2::framework::HistType::kTH1F, "hMissidentified", "Missidentified particles (fake/wrong PDG code); p_{T} (GeV/#it{c}); Entries"}, + {kSecondary1, o2::framework::HistType::kTH1F, "hFromSecondary1", "Particles from secondary decay; p_{T} (GeV/#it{c}); Entries"}, + {kSecondary2, o2::framework::HistType::kTH1F, "hFromSecondary2", "Particles from secondary decay; p_{T} (GeV/#it{c}); Entries"}, + {kSecondary3, o2::framework::HistType::kTH1F, "hFromSecondary3", "Particles from secondary decay; p_{T} (GeV/#it{c}); Entries"}, + {kSecondaryOther, o2::framework::HistType::kTH1F, "hFromSecondaryOther", "Particles from every other secondary decay; p_{T} (GeV/#it{c}); Entries"}, + }}; + +template +auto makeMcParticleHistSpecMap(const T& confBinning) +{ + return std::map>{ + {kPt, {confBinning.pt}}, + {kEta, {confBinning.eta}}, + {kPhi, {confBinning.phi}}, + {kSign, {confBinning.sign}}, + {kPdg, {confBinning.pdgCodes}}, + {kPdgMother, {confBinning.pdgCodes}}, + {kPdgPartonicMother, {confBinning.pdgCodes}}, + {kMotherPt, {confBinning.pt}}, + {kMotherEta, {confBinning.eta}}, + {kMotherPhi, {confBinning.phi}}, + {kMotherSign, {confBinning.sign}}, + {kNoMcParticle, {confBinning.pt}}, + {kPrimary, {confBinning.pt}}, + {kFromWrongCollision, {confBinning.pt}}, + {kFromMaterial, {confBinning.pt}}, + {kMissidentified, {confBinning.pt}}, + {kSecondary1, {confBinning.pt}}, + {kSecondary2, {confBinning.pt}}, + {kSecondary3, {confBinning.pt}}, + {kSecondaryOther, {confBinning.pt}}, + }; +} + +inline constexpr char PrefixMcParticle1[] = "McParticle1/"; +inline constexpr char PrefixMcParticle2[] = "McParticle2/"; + +constexpr std::string_view McDir = "MC/"; + +template +class McParticleHistManager +{ + public: + McParticleHistManager() = default; + ~McParticleHistManager() = default; + + // init with origin histograms enabled, controlled via confBinning.plotOrigins + template + void init(o2::framework::HistogramRegistry* registry, + std::map> const& Specs, + T const& confBinning) + { + mHistogramRegistry = registry; + + std::string mcDir = std::string(prefix) + std::string(McDir); + mHistogramRegistry->add(mcDir + getHistNameV2(kPt, HistTable), getHistDesc(kPt, HistTable), getHistType(kPt, HistTable), {Specs.at(kPt)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kEta, HistTable), getHistDesc(kEta, HistTable), getHistType(kEta, HistTable), {Specs.at(kEta)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kPhi, HistTable), getHistDesc(kPhi, HistTable), getHistType(kPhi, HistTable), {Specs.at(kPhi)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kSign, HistTable), getHistDesc(kSign, HistTable), getHistType(kSign, HistTable), {Specs.at(kSign)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kPdg, HistTable), getHistDesc(kPdg, HistTable), getHistType(kPdg, HistTable), {Specs.at(kPdg)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kPdgMother, HistTable), getHistDesc(kPdgMother, HistTable), getHistType(kPdgMother, HistTable), {Specs.at(kPdgMother)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kPdgPartonicMother, HistTable), getHistDesc(kPdgPartonicMother, HistTable), getHistType(kPdgPartonicMother, HistTable), {Specs.at(kPdgPartonicMother)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kMotherPt, HistTable), getHistDesc(kMotherPt, HistTable), getHistType(kMotherPt, HistTable), {Specs.at(kMotherPt)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kMotherEta, HistTable), getHistDesc(kMotherEta, HistTable), getHistType(kMotherEta, HistTable), {Specs.at(kMotherEta)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kMotherPhi, HistTable), getHistDesc(kMotherPhi, HistTable), getHistType(kMotherPhi, HistTable), {Specs.at(kMotherPhi)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kMotherSign, HistTable), getHistDesc(kMotherSign, HistTable), getHistType(kMotherSign, HistTable), {Specs.at(kMotherSign)}); + + this->enableOptionalHistograms(confBinning); + this->initOrigin(Specs); + } + + template + void fill(T1 const& mcParticle, T2 const& /*mcMothers*/, T3 const& /*mcPartonicMothers*/) + { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kPt, HistTable)), mcParticle.pt()); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kEta, HistTable)), mcParticle.eta()); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kPhi, HistTable)), mcParticle.phi()); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kSign, HistTable)), mcParticle.sign()); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kPdg, HistTable)), mcParticle.pdgCode()); + + bool hasMother = mcParticle.has_fMcMother(); + if (hasMother) { + auto mother = mcParticle.template fMcMother_as(); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kPdgMother, HistTable)), mother.pdgCode()); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kMotherPt, HistTable)), mother.pt()); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kMotherEta, HistTable)), mother.eta()); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kMotherPhi, HistTable)), mother.phi()); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kMotherSign, HistTable)), mother.sign()); + } else { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kPdgMother, HistTable)), 0); + } + + if (mcParticle.has_fMcPartMoth()) { + auto partonicMother = mcParticle.template fMcPartMoth_as(); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kPdgPartonicMother, HistTable)), partonicMother.pdgCode()); + } else { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kPdgPartonicMother, HistTable)), 0); + } + + if (mPlotOrigins) { + // NOTE: kNoMcParticle and kMissidentified are kept here only for enum/histogram + // symmetry with TrackHist — they describe reco-vs-truth mismatches that cannot + // occur for a pure MC-truth particle, so these bins are expected to stay empty + // unless the producer assigns those origin codes for some other reason + // (e.g. pileup-associated particles tagged as kFromWrongCollision). + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kOrigin, HistTable)), mcParticle.origin()); + switch (static_cast(mcParticle.origin())) { + case modes::McOrigin::kNoMcParticle: + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kNoMcParticle, HistTable)), mcParticle.pt()); + break; + case modes::McOrigin::kPhysicalPrimary: + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kPrimary, HistTable)), mcParticle.pt()); + break; + case modes::McOrigin::kFromWrongCollision: + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kFromWrongCollision, HistTable)), mcParticle.pt()); + break; + case modes::McOrigin::kFromMaterial: + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kFromMaterial, HistTable)), mcParticle.pt()); + break; + case modes::McOrigin::kMissidentified: + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kMissidentified, HistTable)), mcParticle.pt()); + break; + case modes::McOrigin::kFromSecondaryDecay: + if (hasMother) { + auto mother = mcParticle.template fMcMother_as(); + int motherPdgCode = std::abs(mother.pdgCode()); + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel1 && motherPdgCode == mPdgCodesSecondaryMother[0]) { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kSecondary1, HistTable)), mcParticle.pt()); + } else if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel2 && motherPdgCode == mPdgCodesSecondaryMother[1]) { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kSecondary2, HistTable)), mcParticle.pt()); + } else if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel3 && motherPdgCode == mPdgCodesSecondaryMother[2]) { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kSecondary3, HistTable)), mcParticle.pt()); + } else { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kSecondaryOther, HistTable)), mcParticle.pt()); + } + } + break; + default: + LOG(warn) << "Encountered mc particle with unknown origin!"; + break; + } + } + } + + private: + template + void enableOptionalHistograms(T const& confBinning) + { + mPlotOrigins = confBinning.plotOrigins.value; + mPlotNSecondaries = confBinning.pdgCodesForMothersOfSecondary.value.size(); + + for (std::size_t i = 0; i < MaxSecondary; i++) { + if (i < confBinning.pdgCodesForMothersOfSecondary.value.size()) { + mPdgCodesSecondaryMother.at(i) = std::abs(confBinning.pdgCodesForMothersOfSecondary.value.at(i)); + } else { + mPdgCodesSecondaryMother.at(i) = 0; + } + } + } + + void initOrigin(std::map> const& Specs) + { + if (!mPlotOrigins) { + return; + } + std::string mcDir = std::string(prefix) + std::string(McDir); + + // mc origin axis can be configured here + const o2::framework::AxisSpec axisOrigin = {static_cast(modes::McOrigin::kMcOriginLast), -0.5, static_cast(modes::McOrigin::kMcOriginLast) - 0.5}; + mHistogramRegistry->add(mcDir + getHistNameV2(kOrigin, HistTable), getHistDesc(kOrigin, HistTable), getHistType(kOrigin, HistTable), {axisOrigin}); + mHistogramRegistry->get(HIST(prefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kNoMcParticle), modes::mcOriginToString(modes::McOrigin::kNoMcParticle)); + mHistogramRegistry->get(HIST(prefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kFromWrongCollision), modes::mcOriginToString(modes::McOrigin::kFromWrongCollision)); + mHistogramRegistry->get(HIST(prefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kPhysicalPrimary), modes::mcOriginToString(modes::McOrigin::kPhysicalPrimary)); + mHistogramRegistry->get(HIST(prefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kFromSecondaryDecay), modes::mcOriginToString(modes::McOrigin::kFromSecondaryDecay)); + mHistogramRegistry->get(HIST(prefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kFromMaterial), modes::mcOriginToString(modes::McOrigin::kFromMaterial)); + mHistogramRegistry->get(HIST(prefix) + HIST(McDir) + HIST(histmanager::getHistName(kOrigin, HistTable)))->GetXaxis()->SetBinLabel(1 + static_cast(modes::McOrigin::kMissidentified), modes::mcOriginToString(modes::McOrigin::kMissidentified)); + + mHistogramRegistry->add(mcDir + getHistNameV2(kNoMcParticle, HistTable), getHistDesc(kNoMcParticle, HistTable), getHistType(kNoMcParticle, HistTable), {Specs.at(kNoMcParticle)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kPrimary, HistTable), getHistDesc(kPrimary, HistTable), getHistType(kPrimary, HistTable), {Specs.at(kPrimary)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kFromWrongCollision, HistTable), getHistDesc(kFromWrongCollision, HistTable), getHistType(kFromWrongCollision, HistTable), {Specs.at(kFromWrongCollision)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kFromMaterial, HistTable), getHistDesc(kFromMaterial, HistTable), getHistType(kFromMaterial, HistTable), {Specs.at(kFromMaterial)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kMissidentified, HistTable), getHistDesc(kMissidentified, HistTable), getHistType(kMissidentified, HistTable), {Specs.at(kMissidentified)}); + + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel1) { + mHistogramRegistry->add(mcDir + getHistNameV2(kSecondary1, HistTable), getHistDesc(kSecondary1, HistTable), getHistType(kSecondary1, HistTable), {Specs.at(kSecondary1)}); + } + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel2) { + mHistogramRegistry->add(mcDir + getHistNameV2(kSecondary2, HistTable), getHistDesc(kSecondary2, HistTable), getHistType(kSecondary2, HistTable), {Specs.at(kSecondary2)}); + } + if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel3) { + mHistogramRegistry->add(mcDir + getHistNameV2(kSecondary3, HistTable), getHistDesc(kSecondary3, HistTable), getHistType(kSecondary3, HistTable), {Specs.at(kSecondary3)}); + } + mHistogramRegistry->add(mcDir + getHistNameV2(kSecondaryOther, HistTable), getHistDesc(kSecondaryOther, HistTable), getHistType(kSecondaryOther, HistTable), {Specs.at(kSecondaryOther)}); + } + + o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; + bool mPlotOrigins = true; + int mPlotNSecondaries = 0; + std::array mPdgCodesSecondaryMother = {0}; +}; +} // namespace o2::analysis::femto::mcparticlehistmanager +#endif // PWGCF_FEMTO_CORE_MCPARTICLEHISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/modes.h b/PWGCF/Femto/Core/modes.h index 5e1d18ce162..e3694abbf53 100644 --- a/PWGCF/Femto/Core/modes.h +++ b/PWGCF/Femto/Core/modes.h @@ -18,15 +18,18 @@ #include "PWGCF/Femto/Core/dataTypes.h" -#include - #include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::modes { -namespace modes + +template +constexpr std::underlying_type_t bit(uint64_t n) { + using U = std::underlying_type_t; + return static_cast(U{1} << n); +} // check if flag is set template @@ -45,26 +48,28 @@ constexpr bool isEqual(T lhs, T rhs) } enum class Mode : uint32_t { - kAnalysis = BIT(0), - kQa = BIT(1), - kMc = BIT(2), - kSe = BIT(3), - kMe = BIT(4), - kAnalysis_Qa = kAnalysis | kQa, - kAnalysis_Mc = kAnalysis | kMc, - kAnalysis_Qa_Mc = kAnalysis | kQa | kMc, - kSe_Analysis = kAnalysis | kSe, - kMe_Analysis = kAnalysis | kMe, - kSe_Analysis_Mc = kAnalysis | kSe | kMc, - kMe_Analysis_Mc = kAnalysis | kMe | kMc, + kReco = bit(0), + kQa = bit(1), + kMc = bit(2), + kSe = bit(3), + kMe = bit(4), + kReco_Qa = kReco | kQa, + kReco_Mc = kReco | kMc, + kReco_Qa_Mc = kReco | kQa | kMc, + kSe_Reco = kSe | kReco, + kMe_Reco = kMe | kReco, + kSe_Reco_Mc = kSe | kReco | kMc, + kMe_Reco_Mc = kMe | kReco | kMc, + kSe_Mc = kSe | kMc, + kMe_Mc = kMe | kMc, }; enum class System : uint32_t { - kPP = BIT(0), - kPbPb = BIT(1), - kMC = BIT(2), - kRun3 = BIT(3), - kRun2 = BIT(4), + kPP = bit(0), + kPbPb = bit(1), + kMC = bit(2), + kRun3 = bit(3), + kRun2 = bit(4), kPP_Run3 = kPP | kRun3, kPP_Run3_MC = kPP | kRun3 | kMC, kPP_Run2 = kPP | kRun2, @@ -73,27 +78,28 @@ enum class System : uint32_t { kPbPb_Run2 = kPbPb | kRun2, }; -enum class MomentumType : o2::aod::femtodatatypes::MomentumType { +enum class MomentumType : o2::analysis::femto::datatypes::MomentumType { kPt = 0, // transverse momentum kPAtPv = 1, // momentum at primary vertex kPTpc = 2, // momentum at inner wall of tpc }; -enum class TransverseMassType : o2::aod::femtodatatypes::TransverseMassType { +enum class TransverseMassType : o2::analysis::femto::datatypes::TransverseMassType { kAveragePdgMass = 0, kReducedPdgMass = 1, kMt4Vector = 2 }; -enum class Particle : o2::aod::femtodatatypes::ParticleType { - kTrack = 0, - kTwoTrackResonance = 1, - kV0 = 2, - kKink = 3, - kCascade = 4, +enum class Particle : o2::analysis::femto::datatypes::ParticleType { + mcParticle = 0, + kTrack = 1, + kTwoTrackResonance = 2, + kV0 = 3, + kKink = 4, + kCascade = 5, }; -enum class McOrigin : o2::aod::femtodatatypes::McOriginType { +enum class McOrigin : o2::analysis::femto::datatypes::McOriginType { kNoMcParticle = 0, // no associated mc particle normally indicated a wrongly reconstruced partilce kFromWrongCollision = 1, // partilce originates from the wrong collision or a collision which was wrongly reconstructed (like a split vertex) kPhysicalPrimary = 2, // primary particle @@ -125,7 +131,7 @@ constexpr const char* mcOriginToString(McOrigin origin) } } -enum class Track : o2::aod::femtodatatypes::TrackType { +enum class Track : o2::analysis::femto::datatypes::TrackType { kTrack, kV0Daughter, kCascadeBachelor, @@ -133,30 +139,29 @@ enum class Track : o2::aod::femtodatatypes::TrackType { kKinkDaughter }; -enum class V0 : o2::aod::femtodatatypes::V0Type { +enum class V0 : o2::analysis::femto::datatypes::V0Type { kLambda, kAntiLambda, kK0short }; -enum class Kink : o2::aod::femtodatatypes::KinkType { +enum class Kink : o2::analysis::femto::datatypes::KinkType { kSigma, kSigmaPlus }; -enum class Cascade : o2::aod::femtodatatypes::CascadeType { +enum class Cascade : o2::analysis::femto::datatypes::CascadeType { kXi, kOmega }; // enum of supported resonances -enum class TwoTrackResonance : o2::aod::femtodatatypes::TwoTrackResonanceType { +enum class TwoTrackResonance : o2::analysis::femto::datatypes::TwoTrackResonanceType { kRho0, kPhi, kKstar0, kKstar0Bar }; -}; // namespace modes -}; // namespace o2::analysis::femto +}; // namespace o2::analysis::femto::modes #endif // PWGCF_FEMTO_CORE_MODES_H_ diff --git a/PWGCF/Femto/Core/pairBuilder.h b/PWGCF/Femto/Core/pairBuilder.h index 0342342f9f9..879cd2486ba 100644 --- a/PWGCF/Femto/Core/pairBuilder.h +++ b/PWGCF/Femto/Core/pairBuilder.h @@ -20,6 +20,7 @@ #include "PWGCF/Femto/Core/closePairRejection.h" #include "PWGCF/Femto/Core/collisionHistManager.h" #include "PWGCF/Femto/Core/kinkHistManager.h" +#include "PWGCF/Femto/Core/mcParticleHistManager.h" #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/Core/pairCleaner.h" #include "PWGCF/Femto/Core/pairHistManager.h" @@ -42,15 +43,12 @@ #include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::pairbuilder { -namespace pairbuilder -{ - const int64_t nLimitPartitionIdenticalParticles = 2; const int64_t nLimitPartitionParticles = 1; -template +template class PairTrackTrackBuilder { public: @@ -287,18 +285,18 @@ class PairTrackTrackBuilder std::uniform_int_distribution<> mDist; }; -template class PairV0V0Builder @@ -542,14 +540,14 @@ class PairV0V0Builder std::uniform_int_distribution<> mDist; }; -template class PairTrackV0Builder { @@ -709,14 +707,14 @@ class PairTrackV0Builder int mMixingDepth = 5; }; -template class PairTrackTwoTrackResonanceBuilder { @@ -820,18 +818,18 @@ class PairTrackTwoTrackResonanceBuilder int mMixingDepth = 5; }; -template class PairV0TwoTrackResonanceBuilder @@ -944,13 +942,13 @@ class PairV0TwoTrackResonanceBuilder int mMixingDepth = 5; }; -template class PairTrackKinkBuilder { @@ -1093,17 +1091,17 @@ class PairTrackKinkBuilder int mMixingDepth = 5; }; -template class PairTrackCascadeBuilder { @@ -1253,7 +1251,183 @@ class PairTrackCascadeBuilder int mMixingDepth = 5; }; -} // namespace pairbuilder -} // namespace o2::analysis::femto +template +class PairMcParticleMcParticleBuilder +{ + public: + PairMcParticleMcParticleBuilder() = default; + ~PairMcParticleMcParticleBuilder() = default; + + template + void init(o2::framework::HistogramRegistry* registry, + T1 const& confCollisionBinning, + T2 const& confMcParticleSelection1, + T3 const& confMcParticleSelection2, + T4 const& confMcParticleBinning1, + T5 const& confMcParticleBinning2, + T6 const& confMcParticleCleaner1, + T7 const& confMcParticleCleaner2, + T8 const& confCpr, + T9 const& confMixing, + T10 const& confPairBinning, + T11 const& confPairCuts, + std::map> const& colHistSpec, + std::map> const& mcParticleHistSpec1, + std::map> const& mcParticleHistSpec2, + std::map> const& pairHistSpec, + std::map> const& cprHistSpec) + { + + // check if correlate the same tracks or not + mSameSpecies = confMixing.sameSpecies.value; + + mColHistManager.template init(registry, colHistSpec, confCollisionBinning); + mPairHistManagerSe.template init(registry, pairHistSpec, confPairBinning, confPairCuts, confMixing); + mPairHistManagerMe.template init(registry, pairHistSpec, confPairBinning, confPairCuts, confMixing); + mPc.template init(confPairCuts); + + if (mSameSpecies) { + mMcParticleCleaner1.init(confMcParticleCleaner1); + + mMcParticleHistManager1.init(registry, mcParticleHistSpec1, confMcParticleBinning1); + + mPairHistManagerSe.setMass(confMcParticleSelection1.pdgCodeAbs.value, confMcParticleSelection1.pdgCodeAbs.value); + mPairHistManagerSe.setCharge(1, 1); + mCprSe.init(registry, cprHistSpec, confCpr); + + mPairHistManagerMe.setMass(confMcParticleSelection1.pdgCodeAbs.value, confMcParticleSelection1.pdgCodeAbs.value); + mPairHistManagerMe.setCharge(1, 1); + mCprMe.init(registry, cprHistSpec, confCpr); + } else { + mMcParticleCleaner1.init(confMcParticleCleaner1); + mMcParticleCleaner2.init(confMcParticleCleaner2); + mMcParticleHistManager1.init(registry, mcParticleHistSpec1, confMcParticleBinning1); + mMcParticleHistManager2.init(registry, mcParticleHistSpec2, confMcParticleBinning2); + + mPairHistManagerSe.setMass(confMcParticleSelection1.pdgCodeAbs.value, confMcParticleSelection2.pdgCodeAbs.value); + mPairHistManagerSe.setCharge(1, 1); + mCprSe.init(registry, cprHistSpec, confCpr); + + mPairHistManagerMe.setMass(confMcParticleSelection1.pdgCodeAbs.value, confMcParticleSelection2.pdgCodeAbs.value); + mPairHistManagerMe.setCharge(1, 1); + mCprMe.init(registry, cprHistSpec, confCpr); + } + + // setup mixing + mMixingPolicy = static_cast(confMixing.policy.value); + mMixingDepth = confMixing.depth.value; + + // setup rng if necessary + if (confMixing.seed.value >= 0) { + uint64_t randomSeed = 0; + mMixIdenticalParticles = true; + if (confMixing.seed.value == 0) { + randomSeed = static_cast(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + } else { + randomSeed = static_cast(confMixing.seed.value); + } + mRng = std::mt19937(randomSeed); + mDist = std::uniform_int_distribution(static_cast(pairprocesshelpers::kOrder12), static_cast(pairprocesshelpers::kOrder21)); + } + } + + // only mc + template + void processSameEvent(T1 const& col, T2 const& mcParticles, T3 const& mcMothers, T4 const& mcPartonicMothers, T5& partition1, T6& partition2, T7& cache) + { + if (mSameSpecies) { + auto mcParticleSlice = partition1->sliceByCached(o2::aod::femtomcparticle::fMcColId, col.globalIndex(), cache); + + if (mcParticleSlice.size() < nLimitPartitionIdenticalParticles) { + return; + } + mColHistManager.template fill(col); + pairprocesshelpers::PairOrder pairOrder = pairprocesshelpers::kOrder12; + if (mMixIdenticalParticles) { + pairOrder = static_cast(mDist(mRng)); + } + pairprocesshelpers::processSameEvent(mcParticleSlice, mcParticles, mcMothers, mcPartonicMothers, col, mMcParticleHistManager1, mPairHistManagerSe, mMcParticleCleaner1, mCprSe, mPc, pairOrder); + } else { + auto mcParticleSlice1 = partition1->sliceByCached(o2::aod::femtomcparticle::fMcColId, col.globalIndex(), cache); + auto mcParticleSlice2 = partition2->sliceByCached(o2::aod::femtomcparticle::fMcColId, col.globalIndex(), cache); + if (mcParticleSlice1.size() < nLimitPartitionParticles || mcParticleSlice2.size() < nLimitPartitionParticles) { + return; + } + mColHistManager.template fill(col); + pairprocesshelpers::processSameEvent(mcParticleSlice1, mcParticleSlice2, mcParticles, mcMothers, mcPartonicMothers, col, mMcParticleHistManager1, mMcParticleHistManager2, mPairHistManagerSe, mMcParticleCleaner1, mMcParticleCleaner2, mCprSe, mPc); + } + } + + template + void processMixedEvent(T1 const& cols, T2 const& mcParticles, T3 const& mcMothers, T4 const& mcPartonicMothers, T5& partition1, T6& partition2, T7& cache, T8& binsVtxMult, T9& binsVtxCent, T10& binsVtxMultCent) + { + if (mSameSpecies) { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + pairprocesshelpers::processMixedEvent(cols, partition1, partition1, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMult, mMixingDepth, mPairHistManagerMe, mMcParticleCleaner1, mMcParticleCleaner1, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxCent): + pairprocesshelpers::processMixedEvent(cols, partition1, partition1, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxCent, mMixingDepth, mPairHistManagerMe, mMcParticleCleaner1, mMcParticleCleaner1, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + pairprocesshelpers::processMixedEvent(cols, partition1, partition1, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMultCent, mMixingDepth, mPairHistManagerMe, mMcParticleCleaner1, mMcParticleCleaner1, mCprMe, mPc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } else { + switch (mMixingPolicy) { + case static_cast(pairhistmanager::kVtxMult): + pairprocesshelpers::processMixedEvent(cols, partition1, partition2, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMult, mMixingDepth, mPairHistManagerMe, mMcParticleCleaner1, mMcParticleCleaner2, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxCent): + pairprocesshelpers::processMixedEvent(cols, partition1, partition2, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxCent, mMixingDepth, mPairHistManagerMe, mMcParticleCleaner1, mMcParticleCleaner2, mCprMe, mPc); + break; + case static_cast(pairhistmanager::kVtxMultCent): + pairprocesshelpers::processMixedEvent(cols, partition1, partition2, mcParticles, mcMothers, mcPartonicMothers, cache, binsVtxMultCent, mMixingDepth, mPairHistManagerMe, mMcParticleCleaner1, mMcParticleCleaner2, mCprMe, mPc); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + + private: + colhistmanager::CollisionHistManager mColHistManager; + mcparticlehistmanager::McParticleHistManager mMcParticleHistManager1; + mcparticlehistmanager::McParticleHistManager mMcParticleHistManager2; + pairhistmanager::PairHistManager mPairHistManagerSe; + pairhistmanager::PairHistManager mPairHistManagerMe; + closepairrejection::ClosePairRejectionMcParticleMcParticle mCprSe; + closepairrejection::ClosePairRejectionMcParticleMcParticle mCprMe; + paircleaner::McParticleMcParticlePairCleaner mPc; + particlecleaner::ParticleCleaner mMcParticleCleaner1; + particlecleaner::ParticleCleaner mMcParticleCleaner2; + pairhistmanager::MixingPolicy mMixingPolicy = pairhistmanager::MixingPolicy::kVtxMult; + int mMixingDepth = 5; + bool mSameSpecies = false; + bool mMixIdenticalParticles = false; + std::mt19937 mRng; + std::uniform_int_distribution<> mDist; +}; + +} // namespace o2::analysis::femto::pairbuilder #endif // PWGCF_FEMTO_CORE_PAIRBUILDER_H_ diff --git a/PWGCF/Femto/Core/pairCleaner.h b/PWGCF/Femto/Core/pairCleaner.h index 0daa9a8e508..bb795a6332f 100644 --- a/PWGCF/Femto/Core/pairCleaner.h +++ b/PWGCF/Femto/Core/pairCleaner.h @@ -20,11 +20,8 @@ #include -namespace o2::analysis::femto +namespace o2::analysis::femto::paircleaner { -namespace paircleaner -{ - class BasePairCleaner { public: @@ -45,39 +42,73 @@ class BasePairCleaner protected: template - bool isCleanTrackPair(T1 const& track1, T2 const& track2) const + bool isCleanParticlePair(T1 const& particle1, T2 const& particle2) const { - return track1.globalIndex() != track2.globalIndex(); + return particle1.globalIndex() != particle2.globalIndex(); }; + // mc only template - bool pairHasCommonAncestor(T1 const& particle1, T2 const& particle2, T3 const& /*partonicMothers*/) const + bool mcPairHasCommonAncestor(T1 const& particle1, T2 const& particle2, T3 const& /*partonicMothers*/) const { // if one of the two particles has no associated partonic mother, we cannot know if they have a common anchestor, so we break out with false if (!particle1.has_fMcPartMoth() || !particle2.has_fMcPartMoth()) { return false; } - // get mc particles + + // get partonic mothers auto partonicMother1 = particle1.template fMcPartMoth_as(); auto partonicMother2 = particle2.template fMcPartMoth_as(); - // get partonic mothers + return partonicMother1.globalIndex() == partonicMother2.globalIndex(); }; template - bool pairHasNonCommonAncestor(T1 const& particle1, T2 const& particle2, T3 const& /*partonicMothers*/) const + bool mcPairHasNonCommonAncestor(T1 const& particle1, T2 const& particle2, T3 const& /*partonicMothers*/) const { - // if one of the two particles has no associated partonic mother, we cannot now if they have a non-common anchestor, so we break out with false + // if one of the two particles has no associated partonic mother, we cannot know if they have a common anchestor, so we break out with false if (!particle1.has_fMcPartMoth() || !particle2.has_fMcPartMoth()) { return false; } - // get mc particles + + // get partonic mothers auto partonicMother1 = particle1.template fMcPartMoth_as(); auto partonicMother2 = particle2.template fMcPartMoth_as(); - // get partonic mothers + return partonicMother1.globalIndex() != partonicMother2.globalIndex(); }; + // reco + mc + template + bool pairHasCommonAncestor(T1 const& particle1, T2 const& particle2, T3 const& /*mcparticles*/, T4 const& partonicMothers) const + { + // if one of the two particles has no associated mc particle, we cannot know if they have a common anchestor, so we break out with false + if (!particle1.has_fMcParticle() || !particle2.has_fMcParticle()) { + return false; + } + + // get mc particles + auto mcParticle1 = particle1.template fMcParticle_as(); + auto mcParticle2 = particle2.template fMcParticle_as(); + + return this->mcPairHasCommonAncestor(mcParticle1, mcParticle2, partonicMothers); + }; + + template + bool pairHasNonCommonAncestor(T1 const& particle1, T2 const& particle2, T3 const& /*mcparticles*/, T4 const& partonicMothers) const + { + // if one of the two particles has no associated mc particle, we cannot know if they have a common anchestor, so we break out with false + if (!particle1.has_fMcParticle() || !particle2.has_fMcParticle()) { + return false; + } + + // get mc particles + auto mcParticle1 = particle1.template fMcParticle_as(); + auto mcParticle2 = particle2.template fMcParticle_as(); + + return this->mcPairHasNonCommonAncestor(mcParticle1, mcParticle2, partonicMothers); + }; + bool mMixPairsWithCommonAncestor = false; bool mMixPairsWithNonCommonAncestor = false; }; @@ -90,11 +121,11 @@ class TrackTrackPairCleaner : public BasePairCleaner template bool isCleanPair(T1 const& track1, T2 const& track2, T3 const& /*trackTable*/) const { - return this->isCleanTrackPair(track1, track2); + return this->isCleanParticlePair(track1, track2); } - template - bool isCleanPair(T1 const& track1, T2 const& track2, T3 const& trackTable, T4 const& partonicMothers) const + template + bool isCleanPair(T1 const& track1, T2 const& track2, T3 const& trackTable, T4 const& mcParticles, T5 const& partonicMothers) const { if (!this->isCleanPair(track1, track2, trackTable)) { return false; @@ -102,10 +133,10 @@ class TrackTrackPairCleaner : public BasePairCleaner // pair is clean // no check if we require common or non-common ancestry if (mMixPairsWithCommonAncestor) { - return this->pairHasCommonAncestor(track1, track2, partonicMothers); + return this->pairHasCommonAncestor(track1, track2, mcParticles, partonicMothers); } if (mMixPairsWithNonCommonAncestor) { - return this->pairHasNonCommonAncestor(track1, track2, partonicMothers); + return this->pairHasNonCommonAncestor(track1, track2, mcParticles, partonicMothers); } return true; } @@ -123,12 +154,12 @@ class V0V0PairCleaner : public BasePairCleaner // also works for particles decay auto posDaughter2 = trackTable.rawIteratorAt(v02.posDauId() - trackTable.offset()); auto negDaughter2 = trackTable.rawIteratorAt(v02.negDauId() - trackTable.offset()); // check all charge combinations - return this->isCleanTrackPair(posDaughter1, posDaughter2) && this->isCleanTrackPair(negDaughter1, negDaughter2) && - this->isCleanTrackPair(posDaughter1, negDaughter2) && this->isCleanTrackPair(negDaughter1, posDaughter2); + return this->isCleanParticlePair(posDaughter1, posDaughter2) && this->isCleanParticlePair(negDaughter1, negDaughter2) && + this->isCleanParticlePair(posDaughter1, negDaughter2) && this->isCleanParticlePair(negDaughter1, posDaughter2); } - template - bool isCleanPair(T1 const& v01, T2 const& v02, T3 const& trackTable, T4 const& partonicMothers) const + template + bool isCleanPair(T1 const& v01, T2 const& v02, T3 const& trackTable, T4 const& mcParticles, T5 const& partonicMothers) const { if (!this->isCleanPair(v01, v02, trackTable)) { return false; @@ -136,10 +167,10 @@ class V0V0PairCleaner : public BasePairCleaner // also works for particles decay // pair is clean // no check if we require common or non-common ancestry if (mMixPairsWithCommonAncestor) { - return this->pairHasCommonAncestor(v01, v02, partonicMothers); + return this->pairHasCommonAncestor(v01, v02, mcParticles, partonicMothers); } if (mMixPairsWithNonCommonAncestor) { - return this->pairHasNonCommonAncestor(v01, v02, partonicMothers); + return this->pairHasNonCommonAncestor(v01, v02, mcParticles, partonicMothers); } return true; } @@ -154,11 +185,11 @@ class TrackV0PairCleaner : public BasePairCleaner // also works for particles de { auto posDaughter = trackTable.rawIteratorAt(v0.posDauId() - trackTable.offset()); auto negDaughter = trackTable.rawIteratorAt(v0.negDauId() - trackTable.offset()); - return (this->isCleanTrackPair(posDaughter, track) && this->isCleanTrackPair(negDaughter, track)); + return (this->isCleanParticlePair(posDaughter, track) && this->isCleanParticlePair(negDaughter, track)); } - template - bool isCleanPair(T1 const& track1, T2 const& v0, T3 const& trackTable, T4 const& partonicMothers) const + template + bool isCleanPair(T1 const& track1, T2 const& v0, T3 const& trackTable, T4 const& mcParticles, T5 const& partonicMothers) const { if (!this->isCleanPair(track1, v0, trackTable)) { return false; @@ -166,10 +197,10 @@ class TrackV0PairCleaner : public BasePairCleaner // also works for particles de // pair is clean // now check if we require common or non-common ancestry if (mMixPairsWithCommonAncestor) { - return this->pairHasCommonAncestor(track1, v0, partonicMothers); + return this->pairHasCommonAncestor(track1, v0, mcParticles, partonicMothers); } if (mMixPairsWithNonCommonAncestor) { - return this->pairHasNonCommonAncestor(track1, v0, partonicMothers); + return this->pairHasNonCommonAncestor(track1, v0, mcParticles, partonicMothers); } return true; } @@ -183,11 +214,11 @@ class TrackKinkPairCleaner : public BasePairCleaner bool isCleanPair(const T1& track, const T2& kink, const T3& trackTable) const { auto chaDaughter = trackTable.rawIteratorAt(kink.chaDauId() - trackTable.offset()); - return this->isCleanTrackPair(chaDaughter, track); + return this->isCleanParticlePair(chaDaughter, track); } - template - bool isCleanPair(T1 const& track1, T2 const& kink, T3 const& trackTable, T4 const& partonicMothers) const + template + bool isCleanPair(T1 const& track1, T2 const& kink, T3 const& trackTable, T4 const& mcParticles, T5 const& partonicMothers) const { if (!this->isCleanPair(track1, kink, trackTable)) { return false; @@ -195,10 +226,10 @@ class TrackKinkPairCleaner : public BasePairCleaner // pair is clean // now check if we require common or non-common ancestry if (mMixPairsWithCommonAncestor) { - return this->pairHasCommonAncestor(track1, kink, partonicMothers); + return this->pairHasCommonAncestor(track1, kink, mcParticles, partonicMothers); } if (mMixPairsWithNonCommonAncestor) { - return this->pairHasNonCommonAncestor(track1, kink, partonicMothers); + return this->pairHasNonCommonAncestor(track1, kink, mcParticles, partonicMothers); } return true; } @@ -214,11 +245,11 @@ class TrackCascadePairCleaner : public BasePairCleaner auto bachelor = trackTable.rawIteratorAt(cascade.bachelorId() - trackTable.offset()); auto posDaughter = trackTable.rawIteratorAt(cascade.posDauId() - trackTable.offset()); auto negDaughter = trackTable.rawIteratorAt(cascade.negDauId() - trackTable.offset()); - return (this->isCleanTrackPair(bachelor, track) && this->isCleanTrackPair(posDaughter, track) && this->isCleanTrackPair(negDaughter, track)); + return (this->isCleanParticlePair(bachelor, track) && this->isCleanParticlePair(posDaughter, track) && this->isCleanParticlePair(negDaughter, track)); } - template - bool isCleanPair(T1 const& track1, T2 const& cascade, T3 const& trackTable, T4 const& partonicMothers) const + template + bool isCleanPair(T1 const& track1, T2 const& cascade, T3 const& trackTable, T4 const& mcParticles, T5 const& partonicMothers) const { if (!this->isCleanPair(track1, cascade, trackTable)) { return false; @@ -226,15 +257,44 @@ class TrackCascadePairCleaner : public BasePairCleaner // pair is clean // now check if we require common or non-common ancestry if (mMixPairsWithCommonAncestor) { - return this->pairHasCommonAncestor(track1, cascade, partonicMothers); + return this->pairHasCommonAncestor(track1, cascade, mcParticles, partonicMothers); } if (mMixPairsWithNonCommonAncestor) { - return this->pairHasNonCommonAncestor(track1, cascade, partonicMothers); + return this->pairHasNonCommonAncestor(track1, cascade, mcParticles, partonicMothers); } return true; } }; -} // namespace paircleaner -} // namespace o2::analysis::femto + +class McParticleMcParticlePairCleaner : public BasePairCleaner +{ + public: + McParticleMcParticlePairCleaner() = default; + + template + bool isCleanPair(T1 const& particle1, T2 const& particle2) const + { + return this->isCleanParticlePair(particle1, particle2); + } + + template + bool isCleanPair(T1 const& particle1, T2 const& particle2, T3 const& partonicMothers) const + { + if (!this->isCleanPair(particle1, particle2)) { + return false; + } + // pair is clean + // no check if we require common or non-common ancestry + if (mMixPairsWithCommonAncestor) { + return this->mcPairHasCommonAncestor(particle1, particle2, partonicMothers); + } + if (mMixPairsWithNonCommonAncestor) { + return this->mcPairHasNonCommonAncestor(particle1, particle2, partonicMothers); + } + return true; + } +}; + +} // namespace o2::analysis::femto::paircleaner #endif // PWGCF_FEMTO_CORE_PAIRCLEANER_H_ diff --git a/PWGCF/Femto/Core/pairHistManager.h b/PWGCF/Femto/Core/pairHistManager.h index 2eba72cd057..2d9365d8de0 100644 --- a/PWGCF/Femto/Core/pairHistManager.h +++ b/PWGCF/Femto/Core/pairHistManager.h @@ -42,9 +42,7 @@ #include #include -namespace o2::analysis::femto -{ -namespace pairhistmanager +namespace o2::analysis::femto::pairhistmanager { // enum for pair histograms enum PairHist { @@ -94,13 +92,39 @@ enum PairHist { kKstarVsMtVsMinvVsPt1VsPt2VsMultVsCent, // dalitz plots kDalitz, // between a track and pos/neg daughter of another particle - // mc + // reco-vs-mc-truth correlation (requires BOTH a reco pair and matched mc info) kTrueKstarVsKstar, kTrueKtVsKt, kTrueMtVsMt, kTrueMinvVsMinv, kTrueMultVsMult, kTrueCentVsCent, + // pure mc-truth pair (no reco counterpart, kMc without kReco) + kTrueKstar, + kTrueKt, + kTrueMt, + kTrueMinv1D, + kTruePt1VsPt2, + kTruePt1VsKstar, + kTruePt2VsKstar, + kTruePt1VsKt, + kTruePt2VsKt, + kTruePt1VsMt, + kTruePt2VsMt, + kTrueKstarVsKt, + kTrueKstarVsMt, + kTrueKstarVsMult, + kTrueKstarVsCent, + kTrueDeltaEtaDeltaPhi, + kTrueQout, + kTrueQside, + kTrueQlong, + kTrueQoutQsideQlong, + kTrueKstarVsMtVsMult, + kTrueKstarVsMtVsMultVsCent, + kTrueKstarVsMtVsPt1VsPt2, + kTrueKstarVsMtVsPt1VsPt2VsMult, + kTrueKstarVsMtVsPt1VsPt2VsMultVsCent, // mixing qa kSeNpart1VsNpart2, // number of unique particles 1 vs unique number of particles 2 in each same event @@ -143,25 +167,25 @@ struct ConfMixing : o2::framework::ConfigurableGroup { struct ConfPairBinning : o2::framework::ConfigurableGroup { std::string prefix = std::string("PairBinning"); - o2::framework::Configurable usePdgMass{"usePdgMass", true, "Use PDF masses for 4-vectors. If false, use reconstructed mass (if available)"}; - o2::framework::Configurable plot1D{"plot1D", true, "Enable 1D histograms"}; - o2::framework::Configurable plot2D{"plot2D", true, "Enable 2D histograms"}; - o2::framework::Configurable plotKstarVsMtVsMult{"plotKstarVsMtVsMult", false, "Enable 3D histogram (Kstar Vs Mt Vs Mult)"}; - o2::framework::Configurable plotKstarVsMtVsMultVsCent{"plotKstarVsMtVsMultVsCent", false, "Enable 4D histogram (Kstar Vs Mt Vs Mult Vs Cent)"}; - o2::framework::Configurable plotKstarVsMtVsPt1VsPt2{"plotKstarVsMtVsPt1VsPt2", false, "Enable 4D histogram (Kstar Vs Mt Vs Pt1 Vs Pt2 Vs Mult)"}; - o2::framework::Configurable plotKstarVsMtVsPt1VsPt2VsMult{"plotKstarVsMtVsPt1VsPt2VsMult", false, "Enable 5D histogram (Kstar Vs Mt Vs Pt1 Vs Pt2 Vs Mult)"}; - o2::framework::Configurable plotKstarVsMtVsPt1VsPt2VsMultVsCent{"plotKstarVsMtVsPt1VsPt2VsMultVsCent", false, "Enable 6D histogram (Kstar Vs Mt Vs Pt1 Vs Pt2 Vs Mult Vs Cent)"}; - o2::framework::Configurable plotKstarVsMtVsMass1VsMass2{"plotKstarVsMtVsMass1VsMass2", false, "Enable 4D histogram (Kstar Vs Mt Vs Mass1 Vs Mass2)"}; - o2::framework::Configurable plotKstarVsMtVsMass1VsMass2VsMult{"plotKstarVsMtVsMass1VsMass2VsMult", false, "Enable 5D histogram (Kstar Vs Mt Vs Mass1 Vs Mass2 Vs Mult)"}; - o2::framework::Configurable plotKstarVsMtVsMass1VsMass2VsMultVsCent{"plotKstarVsMtVsMass1VsMass2VsMultVsCent", false, "Enable 6D histogram (Kstar Vs Mt Vs Mass1 Vs Mass2 Vs Mult Vs Cent)"}; - o2::framework::Configurable plotKstarVsMtVsMass1VsMass2VsPt1VsPt2{"plotKstarVsMtVsMass1VsMass2VsPt1VsPt2", false, "Enable 6D histogram (Kstar Vs Mt Vs Pt1 Vs Pt2 Vs Mass1 Vs Mass2)"}; - o2::framework::Configurable plotKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMult{"plotKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMult", false, "Enable 7D histogram (Kstar Vs Mt Vs Pt1 Vs Pt2 Vs Mass1 Vs Mass2 Vs Mult)"}; - o2::framework::Configurable plotKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMultVsCent{"plotKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMultVsCent", false, "Enable 8D histogram (Kstar Vs Mt Vs Pt1 Vs Pt2 Vs Mass1 Vs Mass2 Vs Mult Vs Cent)"}; - o2::framework::Configurable plotKstarVsMtVsMinv1VsPt1VsPt2{"plotKstarVsMtVsMinv1VsPt1VsPt2", false, "Enable 5D histogram (Kstar Vs Mt Vs Minv Vs Pt1 Vs Pt2)"}; - o2::framework::Configurable plotKstarVsMtVsMinv1VsPt1VsPt2VsMult{"plotKstarVsMtVsMinv1VsPt1VsPt2VsMult", false, "Enable 6D histogram (Kstar Vs Mt Vs Minv Vs Pt1 Vs Pt2 Vs Mult)"}; - o2::framework::Configurable plotKstarVsMtVsMinv1VsPt1VsPt2VsMultVsCent{"plotKstarVsMtVsMinv1VsPt1VsPt2VsMultVsCent", false, "Enable 7D histogram (Kstar Vs Mt Vs Minv Vs Pt1 Vs Pt2 Vs Mult Vs Cent)"}; - o2::framework::Configurable plotDalitz{"plotDalitz", false, "Enable dalitz plot"}; - o2::framework::Configurable plotDeltaEtaDeltaPhi{"plotDeltaEtaDeltaPhi", false, "Plot #Delta#phi vs #Delta#eta"}; + o2::framework::Configurable usePdgMass{"usePdgMass", true, "(Reco) Use PDF masses for 4-vectors. If false, use reconstructed mass (if available). Not consulted for pure mc-truth pairs, which always use PDG mass"}; + o2::framework::Configurable plot1D{"plot1D", true, "(Reco/Mc) Enable 1D histograms"}; + o2::framework::Configurable plot2D{"plot2D", true, "(Reco/Mc) Enable 2D histograms"}; + o2::framework::Configurable plotKstarVsMtVsMult{"plotKstarVsMtVsMult", false, "(Reco/Mc) Enable 3D histogram (Kstar Vs Mt Vs Mult)"}; + o2::framework::Configurable plotKstarVsMtVsMultVsCent{"plotKstarVsMtVsMultVsCent", false, "(Reco/Mc) Enable 4D histogram (Kstar Vs Mt Vs Mult Vs Cent)"}; + o2::framework::Configurable plotKstarVsMtVsPt1VsPt2{"plotKstarVsMtVsPt1VsPt2", false, "(Reco/Mc) Enable 4D histogram (Kstar Vs Mt Vs Pt1 Vs Pt2)"}; + o2::framework::Configurable plotKstarVsMtVsPt1VsPt2VsMult{"plotKstarVsMtVsPt1VsPt2VsMult", false, "(Reco/Mc) Enable 5D histogram (Kstar Vs Mt Vs Pt1 Vs Pt2 Vs Mult)"}; + o2::framework::Configurable plotKstarVsMtVsPt1VsPt2VsMultVsCent{"plotKstarVsMtVsPt1VsPt2VsMultVsCent", false, "(Reco/Mc) Enable 6D histogram (Kstar Vs Mt Vs Pt1 Vs Pt2 Vs Mult Vs Cent)"}; + o2::framework::Configurable plotKstarVsMtVsMass1VsMass2{"plotKstarVsMtVsMass1VsMass2", false, "(Reco) Enable 4D histogram (Kstar Vs Mt Vs Mass1 Vs Mass2)"}; + o2::framework::Configurable plotKstarVsMtVsMass1VsMass2VsMult{"plotKstarVsMtVsMass1VsMass2VsMult", false, "(Reco) Enable 5D histogram (Kstar Vs Mt Vs Mass1 Vs Mass2 Vs Mult)"}; + o2::framework::Configurable plotKstarVsMtVsMass1VsMass2VsMultVsCent{"plotKstarVsMtVsMass1VsMass2VsMultVsCent", false, "(Reco) Enable 6D histogram (Kstar Vs Mt Vs Mass1 Vs Mass2 Vs Mult Vs Cent)"}; + o2::framework::Configurable plotKstarVsMtVsMass1VsMass2VsPt1VsPt2{"plotKstarVsMtVsMass1VsMass2VsPt1VsPt2", false, "(Reco) Enable 6D histogram (Kstar Vs Mt Vs Pt1 Vs Pt2 Vs Mass1 Vs Mass2)"}; + o2::framework::Configurable plotKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMult{"plotKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMult", false, "(Reco) Enable 7D histogram (Kstar Vs Mt Vs Pt1 Vs Pt2 Vs Mass1 Vs Mass2 Vs Mult)"}; + o2::framework::Configurable plotKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMultVsCent{"plotKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMultVsCent", false, "(Reco) Enable 8D histogram (Kstar Vs Mt Vs Pt1 Vs Pt2 Vs Mass1 Vs Mass2 Vs Mult Vs Cent)"}; + o2::framework::Configurable plotKstarVsMtVsMinv1VsPt1VsPt2{"plotKstarVsMtVsMinv1VsPt1VsPt2", false, "(Reco) Enable 5D histogram (Kstar Vs Mt Vs Minv Vs Pt1 Vs Pt2)"}; + o2::framework::Configurable plotKstarVsMtVsMinv1VsPt1VsPt2VsMult{"plotKstarVsMtVsMinv1VsPt1VsPt2VsMult", false, "(Reco) Enable 6D histogram (Kstar Vs Mt Vs Minv Vs Pt1 Vs Pt2 Vs Mult)"}; + o2::framework::Configurable plotKstarVsMtVsMinv1VsPt1VsPt2VsMultVsCent{"plotKstarVsMtVsMinv1VsPt1VsPt2VsMultVsCent", false, "(Reco) Enable 7D histogram (Kstar Vs Mt Vs Minv Vs Pt1 Vs Pt2 Vs Mult Vs Cent)"}; + o2::framework::Configurable plotDalitz{"plotDalitz", false, "(Reco) Enable dalitz plot. Not supported for pure mc-truth pairs (no trackTable/daughter structure)"}; + o2::framework::Configurable plotDeltaEtaDeltaPhi{"plotDeltaEtaDeltaPhi", false, "(Reco/Mc) Plot #Delta#phi vs #Delta#eta"}; o2::framework::ConfigurableAxis kstar{"kstar", {{600, 0, 6}}, "kstar"}; o2::framework::ConfigurableAxis kt{"kt", {{600, 0, 6}}, "kt"}; o2::framework::ConfigurableAxis mt{"mt", {{500, 0.8, 5.8}}, "mt"}; @@ -178,7 +202,7 @@ struct ConfPairBinning : o2::framework::ConfigurableGroup { o2::framework::Configurable transverseMassType{"transverseMassType", static_cast(modes::TransverseMassType::kAveragePdgMass), "Type of transverse mass (0-> Average Pdg Mass, 1-> Reduced Pdg Mass, 2-> Mt from combined 4 vector)"}; o2::framework::ConfigurableAxis binningDeltaEta{"binningDeltaEta", {{35, -1.6, 1.6}}, "Delta eta"}; o2::framework::ConfigurableAxis binningDeltaPhi{"binningDeltaPhi", {{35, -o2::constants::math::PIHalf, 3 * o2::constants::math::PIHalf}}, "Delta phi"}; - o2::framework::Configurable plotBertschPratt{"plotBertschPratt", false, "Enable 1D projections and 3D (q_out, q_side, q_long) Bertsch-Pratt histograms in LCMS"}; + o2::framework::Configurable plotBertschPratt{"plotBertschPratt", false, "(Reco/Mc) Enable 1D projections and 3D (q_out, q_side, q_long) Bertsch-Pratt histograms in LCMS"}; o2::framework::ConfigurableAxis qout{"qout", {{300, -1.5f, 1.5f}}, "q_{out} (GeV/c) in LCMS"}; o2::framework::ConfigurableAxis qside{"qside", {{300, -1.5f, 1.5f}}, "q_{side} (GeV/c) in LCMS"}; o2::framework::ConfigurableAxis qlong{"qlong", {{300, -1.5f, 1.5f}}, "q_{long} (GeV/c) in LCMS"}; @@ -209,7 +233,7 @@ constexpr std::array, kPairHistogramLast> {kMinv, o2::framework::HistType::kTH1F, "hMinv", "invariant mass; m_{Inv} (GeV/#it{c}^{2}); Entries"}, // 2D {kPt1VsPt2, o2::framework::HistType::kTH2F, "hPt1VsPt2", " p_{T,1} vs p_{T,2}; p_{T,1} (GeV/#it{c}); p_{T,2} (GeV/#it{c})"}, - {kPt1VsKstar, o2::framework::HistType::kTH2F, "hPt1VsKstar", "p_{T,1} vs k*; p_{T,2} (GeV/#it{c}); k* (GeV/#it{c})"}, + {kPt1VsKstar, o2::framework::HistType::kTH2F, "hPt1VsKstar", "p_{T,1} vs k*; p_{T,1} (GeV/#it{c}); k* (GeV/#it{c})"}, {kPt2VsKstar, o2::framework::HistType::kTH2F, "hPt2VsKstar", "p_{T,2} vs k*; p_{T,2} (GeV/#it{c}); k* (GeV/#it{c})"}, {kPt1VsKt, o2::framework::HistType::kTH2F, "hPt1VsKt", "p_{T,1} vs k_{T}; p_{T,1} (GeV/#it{c}); k_{T} (GeV/#it{c})"}, {kPt2VsKt, o2::framework::HistType::kTH2F, "hPt2VsKt", "p_{T,2} vs k_{T}; p_{T,2} (GeV/#it{c}); k_{T} (GeV/#it{c})"}, @@ -217,8 +241,8 @@ constexpr std::array, kPairHistogramLast> {kPt2VsMt, o2::framework::HistType::kTH2F, "hPt2VsMt", "p_{T,2} vs m_{T}; p_{T,2} (GeV/#it{c}); m_{T} (GeV/#it{c}^{2})"}, {kKstarVsKt, o2::framework::HistType::kTH2F, "hKstarVsKt", "k* vs k_{T}; k* (GeV/#it{c}); k_{T} (GeV/#it{c})"}, {kKstarVsMt, o2::framework::HistType::kTH2F, "hKstarVsMt", "k* vs m_{T}; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2})"}, - {kKstarVsCent, o2::framework::HistType::kTH2F, "hKstarVsCent", "k* vs Centrality (Mult. Percentile); k* (GeV/#it{c}); Centrality (%)"}, {kKstarVsMult, o2::framework::HistType::kTH2F, "hKstarVsMult", "k* vs Multiplicity; k* (GeV/#it{c}); Multiplicity"}, + {kKstarVsCent, o2::framework::HistType::kTH2F, "hKstarVsCent", "k* vs Centrality (Mult. Percentile); k* (GeV/#it{c}); Centrality (%)"}, // 2D with mass {kKstarVsMass1, o2::framework::HistType::kTH2F, "hKstarVsMass1", "k* vs m_{1}; k* (GeV/#it{c}); m_{1} (GeV/#it{c}^{2})"}, {kKstarVsMass2, o2::framework::HistType::kTH2F, "hKstarVsMass2", "k* vs m_{2}; k* (GeV/#it{c}); m_{2} (GeV/#it{c}^{2})"}, @@ -234,26 +258,54 @@ constexpr std::array, kPairHistogramLast> {kKstarVsMtVsPt1VsPt2VsMult, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsPt1VsPt2VsMult", "k* vs m_{T} vs p_{T,1} vs p_{T,2} vs multiplicity; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}); p_{T,2} (GeV/#it{c}); Multiplicity;"}, {kKstarVsMtVsPt1VsPt2VsMultVsCent, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsPt1VsPt2VsMultVsCent", "k* vs m_{T} vs p_{T,1} vs p_{T,2} vs multiplicity vs centrality; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}); p_{T,2} (GeV/#it{c}); Multiplicity; Centrality;"}, // n-D with mass - {kKstarVsMtVsMass1VsMass2, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMass1VsMass2", "k* vs m_{T} vs m_{1} vs m_{2}; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2});"}, - {kKstarVsMtVsMass1VsMass2VsMult, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMass1VsMass2VsMult", "k* vs m_{T} vs m_{1} vs m_{2} vs multiplicity; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); Multiplicity;"}, - {kKstarVsMtVsMass1VsMass2VsMultVsCent, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMass1VsMass2VsMultVsCent", "k* vs m_{T} vs m_{1} vs m_{2} vs multiplicity vs centrality; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); Multiplicity; Centrality (%);"}, + {kKstarVsMtVsMass1VsMass2, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMass1VsMass2", "k* vs m_{T} vs m_{1} vs m_{2}; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); m_{2} (GeV/#it{c}^{2});"}, + {kKstarVsMtVsMass1VsMass2VsMult, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMass1VsMass2VsMult", "k* vs m_{T} vs m_{1} vs m_{2} vs multiplicity; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); m_{2} (GeV/#it{c}^{2}); Multiplicity;"}, + {kKstarVsMtVsMass1VsMass2VsMultVsCent, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMass1VsMass2VsMultVsCent", "k* vs m_{T} vs m_{1} vs m_{2} vs multiplicity vs centrality; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); m_{2} (GeV/#it{c}^{2}); Multiplicity; Centrality (%);"}, // n-D with pt and mass - {kKstarVsMtVsMass1VsMass2VsPt1VsPt2, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMass1VsMass2VsPt1VsPt2", "k* vs m_{T} vs m_{1} vs m_{2} vs p_{T,1} vs p_{T,2}; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}); p_{T,2} (GeV/#it{c});"}, - {kKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMult, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMult", "k* vs m_{T} vs m_{1} vs m_{2} vs p_{T,1} vs p_{T,2} vs multiplicity; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}); p_{T,2} (GeV/#it{c}); Multiplicity;"}, - {kKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMultVsCent, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMultVsCent", "k* vs m_{T} vs m_{1} vs m_{2} vs p_{T,1} vs p_{T,2} vs multiplicity vs centrality; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}); p_{T,2} (GeV/#it{c}); Multiplicity; Centrality (%);"}, + {kKstarVsMtVsMass1VsMass2VsPt1VsPt2, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMass1VsMass2VsPt1VsPt2", "k* vs m_{T} vs m_{1} vs m_{2} vs p_{T,1} vs p_{T,2}; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); m_{2} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}); p_{T,2} (GeV/#it{c});"}, + {kKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMult, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMult", "k* vs m_{T} vs m_{1} vs m_{2} vs p_{T,1} vs p_{T,2} vs multiplicity; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); m_{2} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}); p_{T,2} (GeV/#it{c}); Multiplicity;"}, + {kKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMultVsCent, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMultVsCent", "k* vs m_{T} vs m_{1} vs m_{2} vs p_{T,1} vs p_{T,2} vs multiplicity vs centrality; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{1} (GeV/#it{c}^{2}); m_{2} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}); p_{T,2} (GeV/#it{c}); Multiplicity; Centrality (%);"}, {kKstarVsMtVsMinvVsPt1VsPt2, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMinvVsPt1VsPt2", "k* vs m_{T} vs m_{Inv} vs p_{T,1} vs p_{T,2}; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{Inv} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}); p_{T,2} (GeV/#it{c})"}, {kKstarVsMtVsMinvVsPt1VsPt2VsMult, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMinvVsPt1VsPt2VsMult", "k* vs m_{T} vs m_{Inv} vs p_{T,1} vs p_{T,2} vs multiplicity; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{Inv} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}); p_{T,2} (GeV/#it{c}); Multiplicity"}, {kKstarVsMtVsMinvVsPt1VsPt2VsMultVsCent, o2::framework::HistType::kTHnSparseF, "hKstarVsMtVsMinvVsPt1VsPt2VsMultVsCent", "k* vs m_{T} vs m_{Inv} vs p_{T,1} vs p_{T,2} vs multiplicity vs centrality; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); m_{Inv} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}); p_{T,2} (GeV/#it{c}); Multiplicity; Centrality (%)"}, {kDalitz, o2::framework::HistType::kTHnSparseF, "hDalitz", "Dalitz plot; k* (GeV/#it{c}); m^{2}_{123} (GeV/#it{c}^{2})^{2}; m^{2}_{12} (GeV/#it{c}^{2})^{2}; m^{2}_{13} (GeV/#it{c}^{2})^{2};"}, + // reco-vs-mc-truth correlation {kTrueKstarVsKstar, o2::framework::HistType::kTH2F, "hTrueKstarVsKstar", "k*_{True} vs k*; k*_{True} (GeV/#it{c}); k* (GeV/#it{c})"}, {kTrueKtVsKt, o2::framework::HistType::kTH2F, "hTrueKtVsKt", "k_{T,True} vs k_{T}; k_{T,True} (GeV/#it{c}); k_{T} (GeV/#it{c})"}, {kTrueMtVsMt, o2::framework::HistType::kTH2F, "hTrueMtVsMt", "m_{T,True} vs m_{T}; m_{T,True} (GeV/#it{c}^{2}); m_{T} (GeV/#it{c}^{2})"}, {kTrueMinvVsMinv, o2::framework::HistType::kTH2F, "hTrueMinvVsMinv", "m_{Inv,True} vs m_{Inv}; m_{Inv,True} (GeV/#it{c}^{2}); m_{Inv} (GeV/#it{c}^{2})"}, {kTrueMultVsMult, o2::framework::HistType::kTH2F, "hTrueMultVsMult", "Multiplicity_{True} vs Multiplicity; Multiplicity_{True} ; Multiplicity"}, {kTrueCentVsCent, o2::framework::HistType::kTH2F, "hTrueCentVsCent", "Centrality_{True} vs Centrality; Centrality_{True} (%); Centrality (%)"}, + // pure mc-truth pair (no reco counterpart) + {kTrueKstar, o2::framework::HistType::kTH1F, "hTrueKstar", "k* (mc-truth pair); k*_{True} (GeV/#it{c}); Entries"}, + {kTrueKt, o2::framework::HistType::kTH1F, "hTrueKt", "transverse momentum (mc-truth pair); k_{T,True} (GeV/#it{c}); Entries"}, + {kTrueMt, o2::framework::HistType::kTH1F, "hTrueMt", "transverse mass (mc-truth pair); m_{T,True} (GeV/#it{c}^{2}); Entries"}, + {kTrueMinv1D, o2::framework::HistType::kTH1F, "hTrueMinv", "invariant mass (mc-truth pair); m_{Inv,True} (GeV/#it{c}^{2}); Entries"}, + {kTruePt1VsPt2, o2::framework::HistType::kTH2F, "hTruePt1VsPt2", "p_{T,1} vs p_{T,2} (mc-truth pair); p_{T,1,True} (GeV/#it{c}); p_{T,2,True} (GeV/#it{c})"}, + {kTruePt1VsKstar, o2::framework::HistType::kTH2F, "hTruePt1VsKstar", "p_{T,1} vs k* (mc-truth pair); p_{T,1,True} (GeV/#it{c}); k*_{True} (GeV/#it{c})"}, + {kTruePt2VsKstar, o2::framework::HistType::kTH2F, "hTruePt2VsKstar", "p_{T,2} vs k* (mc-truth pair); p_{T,2,True} (GeV/#it{c}); k*_{True} (GeV/#it{c})"}, + {kTruePt1VsKt, o2::framework::HistType::kTH2F, "hTruePt1VsKt", "p_{T,1} vs k_{T} (mc-truth pair); p_{T,1,True} (GeV/#it{c}); k_{T,True} (GeV/#it{c})"}, + {kTruePt2VsKt, o2::framework::HistType::kTH2F, "hTruePt2VsKt", "p_{T,2} vs k_{T} (mc-truth pair); p_{T,2,True} (GeV/#it{c}); k_{T,True} (GeV/#it{c})"}, + {kTruePt1VsMt, o2::framework::HistType::kTH2F, "hTruePt1VsMt", "p_{T,1} vs m_{T} (mc-truth pair); p_{T,1,True} (GeV/#it{c}); m_{T,True} (GeV/#it{c}^{2})"}, + {kTruePt2VsMt, o2::framework::HistType::kTH2F, "hTruePt2VsMt", "p_{T,2} vs m_{T} (mc-truth pair); p_{T,2,True} (GeV/#it{c}); m_{T,True} (GeV/#it{c}^{2})"}, + {kTrueKstarVsKt, o2::framework::HistType::kTH2F, "hTrueKstarVsKt", "k* vs k_{T} (mc-truth pair); k*_{True} (GeV/#it{c}); k_{T,True} (GeV/#it{c})"}, + {kTrueKstarVsMt, o2::framework::HistType::kTH2F, "hTrueKstarVsMt", "k* vs m_{T} (mc-truth pair); k*_{True} (GeV/#it{c}); m_{T,True} (GeV/#it{c}^{2})"}, + {kTrueKstarVsMult, o2::framework::HistType::kTH2F, "hTrueKstarVsMult", "k* vs Multiplicity (mc-truth pair); k*_{True} (GeV/#it{c}); Multiplicity_{True}"}, + {kTrueKstarVsCent, o2::framework::HistType::kTH2F, "hTrueKstarVsCent", "k* vs Centrality (mc-truth pair); k*_{True} (GeV/#it{c}); Centrality_{True} (%)"}, + {kTrueDeltaEtaDeltaPhi, o2::framework::HistType::kTH2F, "hTrueDeltaEtaDeltaPhi", "#Delta#phi vs #Delta#eta (mc-truth pair); #Delta#phi_{True}; #Delta#eta_{True}"}, + {kTrueQout, o2::framework::HistType::kTH1F, "hTrueQout", "q_{out} in LCMS (mc-truth pair); q_{out,True} (GeV/#it{c}); Entries"}, + {kTrueQside, o2::framework::HistType::kTH1F, "hTrueQside", "q_{side} in LCMS (mc-truth pair); q_{side,True} (GeV/#it{c}); Entries"}, + {kTrueQlong, o2::framework::HistType::kTH1F, "hTrueQlong", "q_{long} in LCMS (mc-truth pair); q_{long,True} (GeV/#it{c}); Entries"}, + {kTrueQoutQsideQlong, o2::framework::HistType::kTH3F, "hTrueQoutQsideQlong", "Bertsch-Pratt 3D (mc-truth pair); q_{out,True} (GeV/#it{c}); q_{side,True} (GeV/#it{c}); q_{long,True} (GeV/#it{c})"}, + {kTrueKstarVsMtVsMult, o2::framework::HistType::kTHnSparseF, "hTrueKstarVsMtVsMult", "k* vs m_{T} vs multiplicity (mc-truth pair); k*_{True} (GeV/#it{c}); m_{T,True} (GeV/#it{c}^{2}); Multiplicity_{True};"}, + {kTrueKstarVsMtVsMultVsCent, o2::framework::HistType::kTHnSparseF, "hTrueKstarVsMtVsMultVsCent", "k* vs m_{T} vs multiplicity vs centrality (mc-truth pair); k*_{True} (GeV/#it{c}); m_{T,True} (GeV/#it{c}^{2}); Multiplicity_{True}; Centrality_{True} (%);"}, + {kTrueKstarVsMtVsPt1VsPt2, o2::framework::HistType::kTHnSparseF, "hTrueKstarVsMtVsPt1VsPt2", "k* vs m_{T} vs p_{T,1} vs p_{T,2} (mc-truth pair); k*_{True} (GeV/#it{c}); m_{T,True} (GeV/#it{c}^{2}); p_{T,1,True} (GeV/#it{c}); p_{T,2,True} (GeV/#it{c});"}, + {kTrueKstarVsMtVsPt1VsPt2VsMult, o2::framework::HistType::kTHnSparseF, "hTrueKstarVsMtVsPt1VsPt2VsMult", "k* vs m_{T} vs p_{T,1} vs p_{T,2} vs multiplicity (mc-truth pair); k*_{True} (GeV/#it{c}); m_{T,True} (GeV/#it{c}^{2}); p_{T,1,True} (GeV/#it{c}); p_{T,2,True} (GeV/#it{c}); Multiplicity_{True};"}, + {kTrueKstarVsMtVsPt1VsPt2VsMultVsCent, o2::framework::HistType::kTHnSparseF, "hTrueKstarVsMtVsPt1VsPt2VsMultVsCent", "k* vs m_{T} vs p_{T,1} vs p_{T,2} vs multiplicity vs centrality (mc-truth pair); k*_{True} (GeV/#it{c}); m_{T,True} (GeV/#it{c}^{2}); p_{T,1,True} (GeV/#it{c}); p_{T,2,True} (GeV/#it{c}); Multiplicity_{True}; Centrality_{True} (%);"}, + // mixing qa {kSeNpart1VsNpart2, o2::framework::HistType::kTH2F, "hSeNpart1VsNpart2", "# unique particle 1 vs # unique particle 2 in each same event; # partilce 1; # particle 2"}, - {kMeMixingWindowRaw, o2::framework::HistType::kTH1F, "hMeMixingWindowRaw", "Raw Mixing Window; Raw Mixing Window ; Entries"}, - {kMeMixingWindowEffective, o2::framework::HistType::kTH1F, "hMeMixingWindowEffective", "Effective Mixing Window; Effective Mixing Windown ; Entries"}, + {kMeMixingWindowRaw, o2::framework::HistType::kTH1F, "hMeMixingWindowRaw", "Raw Mixing Window; Raw Mixing Window Entries"}, + {kMeMixingWindowEffective, o2::framework::HistType::kTH1F, "hMeMixingWindowEffective", "Effective Mixing Window; Effective Mixing Window; Entries"}, {kMeNpart1VsNpart2, o2::framework::HistType::kTH2F, "hMeNpart1VsNpart2", "# unique particle 1 vs # unique partilce 2 in each mixing bin; # partilce 1; # particle 2"}, {kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2, o2::framework::HistType::kTHnSparseF, "hVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2", "Mixing bins; V_{z,1} (cm); multiplicity_{1}; centrality_{1} (%); V_{z,2} (cm); multiplicity_{2}; centrality_{2} (%)"}, // angular @@ -265,79 +317,133 @@ constexpr std::array, kPairHistogramLast> {kQoutQsideQlong, o2::framework::HistType::kTH3F, "hQoutQsideQlong", "Bertsch-Pratt 3D; q_{out} (GeV/#it{c}); q_{side} (GeV/#it{c}); q_{long} (GeV/#it{c})"}, }}; -#define PAIR_HIST_ANALYSIS_MAP(confAnalysis, confMixing) \ - {kKstar, {confAnalysis.kstar}}, \ - {kKt, {confAnalysis.kt}}, \ - {kMt, {confAnalysis.mt}}, \ - {kMinv, {confAnalysis.massInv}}, \ - {kPt1VsPt2, {confAnalysis.pt1, confAnalysis.pt2}}, \ - {kPt1VsKstar, {confAnalysis.pt1, confAnalysis.kstar}}, \ - {kPt2VsKstar, {confAnalysis.pt2, confAnalysis.kstar}}, \ - {kPt1VsKt, {confAnalysis.pt1, confAnalysis.kt}}, \ - {kPt2VsKt, {confAnalysis.pt2, confAnalysis.kt}}, \ - {kPt1VsMt, {confAnalysis.pt1, confAnalysis.mt}}, \ - {kPt2VsMt, {confAnalysis.pt2, confAnalysis.mt}}, \ - {kKstarVsKt, {confAnalysis.kstar, confAnalysis.kt}}, \ - {kKstarVsMt, {confAnalysis.kstar, confAnalysis.mt}}, \ - {kKstarVsMult, {confAnalysis.kstar, confAnalysis.multiplicity}}, \ - {kKstarVsCent, {confAnalysis.kstar, confAnalysis.centrality}}, \ - {kKstarVsMass1, {confAnalysis.kstar, confAnalysis.mass1}}, \ - {kKstarVsMass2, {confAnalysis.kstar, confAnalysis.mass2}}, \ - {kMass1VsMass2, {confAnalysis.mass1, confAnalysis.mass2}}, \ - {kKstarVsMinv, {confAnalysis.kstar, confAnalysis.massInv}}, \ - {kPt1VsMinv, {confAnalysis.pt1, confAnalysis.massInv}}, \ - {kPt2VsMinv, {confAnalysis.pt2, confAnalysis.massInv}}, \ - {kKstarVsMtVsMult, {confAnalysis.kstar, confAnalysis.mt, confAnalysis.multiplicity}}, \ - {kKstarVsMtVsMultVsCent, {confAnalysis.kstar, confAnalysis.mt, confAnalysis.multiplicity, confAnalysis.centrality}}, \ - {kKstarVsMtVsPt1VsPt2, {confAnalysis.kstar, confAnalysis.mt, confAnalysis.pt1, confAnalysis.pt2}}, \ - {kKstarVsMtVsPt1VsPt2VsMult, {confAnalysis.kstar, confAnalysis.mt, confAnalysis.pt1, confAnalysis.pt2, confAnalysis.multiplicity}}, \ - {kKstarVsMtVsPt1VsPt2VsMultVsCent, {confAnalysis.kstar, confAnalysis.mt, confAnalysis.pt1, confAnalysis.pt2, confAnalysis.multiplicity, confAnalysis.centrality}}, \ - {kKstarVsMtVsMass1VsMass2, {confAnalysis.kstar, confAnalysis.mt, confAnalysis.mass1, confAnalysis.mass2}}, \ - {kKstarVsMtVsMass1VsMass2VsMult, {confAnalysis.kstar, confAnalysis.mt, confAnalysis.mass1, confAnalysis.mass2, confAnalysis.multiplicity}}, \ - {kKstarVsMtVsMass1VsMass2VsMultVsCent, {confAnalysis.kstar, confAnalysis.mt, confAnalysis.mass1, confAnalysis.mass2, confAnalysis.multiplicity, confAnalysis.centrality}}, \ - {kKstarVsMtVsMass1VsMass2VsPt1VsPt2, {confAnalysis.kstar, confAnalysis.mt, confAnalysis.mass1, confAnalysis.mass2, confAnalysis.pt1, confAnalysis.pt2}}, \ - {kKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMult, {confAnalysis.kstar, confAnalysis.mt, confAnalysis.mass1, confAnalysis.mass2, confAnalysis.pt1, confAnalysis.pt2, confAnalysis.multiplicity}}, \ - {kKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMultVsCent, {confAnalysis.kstar, confAnalysis.mt, confAnalysis.mass1, confAnalysis.mass2, confAnalysis.pt1, confAnalysis.pt2, confAnalysis.multiplicity, confAnalysis.centrality}}, \ - {kKstarVsMtVsMinvVsPt1VsPt2, {confAnalysis.kstar, confAnalysis.mt, confAnalysis.massInv, confAnalysis.pt1, confAnalysis.pt2}}, \ - {kKstarVsMtVsMinvVsPt1VsPt2VsMult, {confAnalysis.kstar, confAnalysis.mt, confAnalysis.massInv, confAnalysis.pt1, confAnalysis.pt2, confAnalysis.multiplicity}}, \ - {kKstarVsMtVsMinvVsPt1VsPt2VsMultVsCent, {confAnalysis.kstar, confAnalysis.mt, confAnalysis.massInv, confAnalysis.pt1, confAnalysis.pt2, confAnalysis.multiplicity, confAnalysis.centrality}}, \ - {kDalitz, {confAnalysis.kstar, confAnalysis.dalitzMtot, confAnalysis.dalitzM12, confAnalysis.dalitzM13}}, \ - {kDeltaEtaDeltaPhi, {confAnalysis.binningDeltaPhi, confAnalysis.binningDeltaEta}}, \ - {kSeNpart1VsNpart2, {confMixing.particleBinning, confMixing.particleBinning}}, \ - {kMeMixingWindowRaw, {confMixing.particleBinning}}, \ - {kMeMixingWindowEffective, {confMixing.particleBinning}}, \ - {kMeNpart1VsNpart2, {confMixing.particleBinning, confMixing.particleBinning}}, \ - {kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2, {confMixing.vtxBins, confMixing.multBins, confMixing.centBins, confMixing.vtxBins, confMixing.multBins, confMixing.centBins}}, \ - {kQout, {confAnalysis.qout}}, \ - {kQside, {confAnalysis.qside}}, \ - {kQlong, {confAnalysis.qlong}}, \ - {kQoutQsideQlong, {confAnalysis.qout, confAnalysis.qside, confAnalysis.qlong}}, - -#define PAIR_HIST_MC_MAP(conf) \ - {kTrueKstarVsKstar, {conf.kstar, conf.kstar}}, \ - {kTrueKtVsKt, {conf.kt, conf.kt}}, \ - {kTrueMtVsMt, {conf.mt, conf.mt}}, \ - {kTrueMinvVsMinv, {conf.massInv, conf.massInv}}, \ - {kTrueMultVsMult, {conf.multiplicity, conf.multiplicity}}, \ - {kTrueCentVsCent, {conf.centrality, conf.centrality}}, +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define PAIR_HIST_ANALYSIS_MAP(confAnalysis) \ + {kKstar, {(confAnalysis).kstar}}, \ + {kKt, {(confAnalysis).kt}}, \ + {kMt, {(confAnalysis).mt}}, \ + {kMinv, {(confAnalysis).massInv}}, \ + {kPt1VsPt2, {(confAnalysis).pt1, (confAnalysis).pt2}}, \ + {kPt1VsKstar, {(confAnalysis).pt1, (confAnalysis).kstar}}, \ + {kPt2VsKstar, {(confAnalysis).pt2, (confAnalysis).kstar}}, \ + {kPt1VsKt, {(confAnalysis).pt1, (confAnalysis).kt}}, \ + {kPt2VsKt, {(confAnalysis).pt2, (confAnalysis).kt}}, \ + {kPt1VsMt, {(confAnalysis).pt1, (confAnalysis).mt}}, \ + {kPt2VsMt, {(confAnalysis).pt2, (confAnalysis).mt}}, \ + {kKstarVsKt, {(confAnalysis).kstar, (confAnalysis).kt}}, \ + {kKstarVsMt, {(confAnalysis).kstar, (confAnalysis).mt}}, \ + {kKstarVsMult, {(confAnalysis).kstar, (confAnalysis).multiplicity}}, \ + {kKstarVsCent, {(confAnalysis).kstar, (confAnalysis).centrality}}, \ + {kKstarVsMass1, {(confAnalysis).kstar, (confAnalysis).mass1}}, \ + {kKstarVsMass2, {(confAnalysis).kstar, (confAnalysis).mass2}}, \ + {kMass1VsMass2, {(confAnalysis).mass1, (confAnalysis).mass2}}, \ + {kKstarVsMinv, {(confAnalysis).kstar, (confAnalysis).massInv}}, \ + {kPt1VsMinv, {(confAnalysis).pt1, (confAnalysis).massInv}}, \ + {kPt2VsMinv, {(confAnalysis).pt2, (confAnalysis).massInv}}, \ + {kKstarVsMtVsMult, {(confAnalysis).kstar, (confAnalysis).mt, (confAnalysis).multiplicity}}, \ + {kKstarVsMtVsMultVsCent, {(confAnalysis).kstar, (confAnalysis).mt, (confAnalysis).multiplicity, (confAnalysis).centrality}}, \ + {kKstarVsMtVsPt1VsPt2, {(confAnalysis).kstar, (confAnalysis).mt, (confAnalysis).pt1, (confAnalysis).pt2}}, \ + {kKstarVsMtVsPt1VsPt2VsMult, {(confAnalysis).kstar, (confAnalysis).mt, (confAnalysis).pt1, (confAnalysis).pt2, (confAnalysis).multiplicity}}, \ + {kKstarVsMtVsPt1VsPt2VsMultVsCent, {(confAnalysis).kstar, (confAnalysis).mt, (confAnalysis).pt1, (confAnalysis).pt2, (confAnalysis).multiplicity, (confAnalysis).centrality}}, \ + {kKstarVsMtVsMass1VsMass2, {(confAnalysis).kstar, (confAnalysis).mt, (confAnalysis).mass1, (confAnalysis).mass2}}, \ + {kKstarVsMtVsMass1VsMass2VsMult, {(confAnalysis).kstar, (confAnalysis).mt, (confAnalysis).mass1, (confAnalysis).mass2, (confAnalysis).multiplicity}}, \ + {kKstarVsMtVsMass1VsMass2VsMultVsCent, {(confAnalysis).kstar, (confAnalysis).mt, (confAnalysis).mass1, (confAnalysis).mass2, (confAnalysis).multiplicity, (confAnalysis).centrality}}, \ + {kKstarVsMtVsMass1VsMass2VsPt1VsPt2, {(confAnalysis).kstar, (confAnalysis).mt, (confAnalysis).mass1, (confAnalysis).mass2, (confAnalysis).pt1, (confAnalysis).pt2}}, \ + {kKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMult, {(confAnalysis).kstar, (confAnalysis).mt, (confAnalysis).mass1, (confAnalysis).mass2, (confAnalysis).pt1, (confAnalysis).pt2, (confAnalysis).multiplicity}}, \ + {kKstarVsMtVsMass1VsMass2VsPt1VsPt2VsMultVsCent, {(confAnalysis).kstar, (confAnalysis).mt, (confAnalysis).mass1, (confAnalysis).mass2, (confAnalysis).pt1, (confAnalysis).pt2, (confAnalysis).multiplicity, (confAnalysis).centrality}}, \ + {kKstarVsMtVsMinvVsPt1VsPt2, {(confAnalysis).kstar, (confAnalysis).mt, (confAnalysis).massInv, (confAnalysis).pt1, (confAnalysis).pt2}}, \ + {kKstarVsMtVsMinvVsPt1VsPt2VsMult, {(confAnalysis).kstar, (confAnalysis).mt, (confAnalysis).massInv, (confAnalysis).pt1, (confAnalysis).pt2, (confAnalysis).multiplicity}}, \ + {kKstarVsMtVsMinvVsPt1VsPt2VsMultVsCent, {(confAnalysis).kstar, (confAnalysis).mt, (confAnalysis).massInv, (confAnalysis).pt1, (confAnalysis).pt2, (confAnalysis).multiplicity, (confAnalysis).centrality}}, \ + {kDalitz, {(confAnalysis).kstar, (confAnalysis).dalitzMtot, (confAnalysis).dalitzM12, (confAnalysis).dalitzM13}}, \ + {kDeltaEtaDeltaPhi, {(confAnalysis).binningDeltaPhi, (confAnalysis).binningDeltaEta}}, \ + {kQout, {(confAnalysis).qout}}, \ + {kQside, {(confAnalysis).qside}}, \ + {kQlong, {(confAnalysis).qlong}}, \ + {kQoutQsideQlong, {(confAnalysis).qout, (confAnalysis).qside, (confAnalysis).qlong}}, + +// mixing-qa entries are independent of reco vs mc-truth status — both the reco +// analysis path and the pure mc-truth path need them whenever kSe/kMe is set +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define PAIR_HIST_MIXING_QA_MAP(confMixing) \ + {kSeNpart1VsNpart2, {(confMixing).particleBinning, (confMixing).particleBinning}}, \ + {kMeMixingWindowRaw, {(confMixing).particleBinning}}, \ + {kMeMixingWindowEffective, {(confMixing).particleBinning}}, \ + {kMeNpart1VsNpart2, {(confMixing).particleBinning, (confMixing).particleBinning}}, \ + {kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2, {(confMixing).vtxBins, (confMixing).multBins, (confMixing).centBins, (confMixing).vtxBins, (confMixing).multBins, (confMixing).centBins}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define PAIR_HIST_MC_MAP(conf) \ + {kTrueKstarVsKstar, {(conf).kstar, (conf).kstar}}, \ + {kTrueKtVsKt, {(conf).kt, (conf).kt}}, \ + {kTrueMtVsMt, {(conf).mt, (conf).mt}}, \ + {kTrueMinvVsMinv, {(conf).massInv, (conf).massInv}}, \ + {kTrueMultVsMult, {(conf).multiplicity, (conf).multiplicity}}, \ + {kTrueCentVsCent, {(conf).centrality, (conf).centrality}}, + +// pure mc-truth pair (no reco counterpart) — reuses the same analysis binning, +// since there is no separate "true" axis (conf)iguration: the truth value IS the +// analysis-level value for this path. +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define PAIR_HIST_MC_TRUTH_MAP(conf) \ + {kTrueKstar, {(conf).kstar}}, \ + {kTrueKt, {(conf).kt}}, \ + {kTrueMt, {(conf).mt}}, \ + {kTrueMinv1D, {(conf).massInv}}, \ + {kTruePt1VsPt2, {(conf).pt1, (conf).pt2}}, \ + {kTruePt1VsKstar, {(conf).pt1, (conf).kstar}}, \ + {kTruePt2VsKstar, {(conf).pt2, (conf).kstar}}, \ + {kTruePt1VsKt, {(conf).pt1, (conf).kt}}, \ + {kTruePt2VsKt, {(conf).pt2, (conf).kt}}, \ + {kTruePt1VsMt, {(conf).pt1, (conf).mt}}, \ + {kTruePt2VsMt, {(conf).pt2, (conf).mt}}, \ + {kTrueKstarVsKt, {(conf).kstar, (conf).kt}}, \ + {kTrueKstarVsMt, {(conf).kstar, (conf).mt}}, \ + {kTrueKstarVsMult, {(conf).kstar, (conf).multiplicity}}, \ + {kTrueKstarVsCent, {(conf).kstar, (conf).centrality}}, \ + {kTrueDeltaEtaDeltaPhi, {(conf).binningDeltaPhi, (conf).binningDeltaEta}}, \ + {kTrueQout, {(conf).qout}}, \ + {kTrueQside, {(conf).qside}}, \ + {kTrueQlong, {(conf).qlong}}, \ + {kTrueQoutQsideQlong, {(conf).qout, (conf).qside, (conf).qlong}}, \ + {kTrueKstarVsMtVsMult, {(conf).kstar, (conf).mt, (conf).multiplicity}}, \ + {kTrueKstarVsMtVsMultVsCent, {(conf).kstar, (conf).mt, (conf).multiplicity, (conf).centrality}}, \ + {kTrueKstarVsMtVsPt1VsPt2, {(conf).kstar, (conf).mt, (conf).pt1, (conf).pt2}}, \ + {kTrueKstarVsMtVsPt1VsPt2VsMult, {(conf).kstar, (conf).mt, (conf).pt1, (conf).pt2, (conf).multiplicity}}, \ + {kTrueKstarVsMtVsPt1VsPt2VsMultVsCent, {(conf).kstar, (conf).mt, (conf).pt1, (conf).pt2, (conf).multiplicity, (conf).centrality}}, template auto makePairHistSpecMap(T1 const& confPairBinning, T2 const& confMixing) { return std::map>{ - PAIR_HIST_ANALYSIS_MAP(confPairBinning, confMixing)}; + PAIR_HIST_ANALYSIS_MAP(confPairBinning) + PAIR_HIST_MIXING_QA_MAP(confMixing)}; }; template auto makePairMcHistSpecMap(T1 const& confPairBinning, T2 const& confMixing) { return std::map>{ - PAIR_HIST_ANALYSIS_MAP(confPairBinning, confMixing) - PAIR_HIST_MC_MAP(confPairBinning)}; + PAIR_HIST_ANALYSIS_MAP(confPairBinning) + PAIR_HIST_MIXING_QA_MAP(confMixing) + PAIR_HIST_MC_MAP(confPairBinning)}; +}; + +// for the pure mc-truth-only pair builder (kMc without kReco): needs both the +// mc-truth binning AND the mixing-qa entries (kSe/kMe histograms are filled +// for this path too, via initSeMixingQa/initMeMixingQa being gated on kSe/kMe +// alone, independent of kReco/kMc). +template +auto makePairMcTruthHistSpecMap(T1 const& confPairBinning, T2 const& confMixing) +{ + return std::map>{ + PAIR_HIST_MC_TRUTH_MAP(confPairBinning) + PAIR_HIST_MIXING_QA_MAP(confMixing)}; }; #undef PAIR_HIST_ANALYSIS_MAP +#undef PAIR_HIST_MIXING_QA_MAP #undef PAIR_HIST_MC_MAP +#undef PAIR_HIST_MC_TRUTH_MAP constexpr char PrefixTrackTrackSe[] = "TrackTrack/SE/"; constexpr char PrefixTrackTrackMe[] = "TrackTrack/ME/"; @@ -360,11 +466,14 @@ constexpr char PrefixTrackCascadeMe[] = "TrackCascade/ME/"; constexpr char PrefixTrackKinkSe[] = "TrackKink/SE/"; constexpr char PrefixTrackKinkMe[] = "TrackKink/ME/"; +constexpr char PrefixMcParticleMcParticleSe[] = "McParticleMcParticle/SE/"; +constexpr char PrefixMcParticleMcParticleMe[] = "McParticleMcParticle/ME/"; + constexpr std::string_view AnalysisDir = "Analysis/"; constexpr std::string_view MixingQaDir = "MixingQA/"; constexpr std::string_view McDir = "MC/"; -template class PairHistManager @@ -426,14 +535,20 @@ class PairHistManager mPairCorrelationQa = ConfMixing.enablePairCorrelationQa.value; mEventMixingQa = ConfMixing.enableEventMixingQa.value; - if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco)) { initAnalysis(Specs); } - if constexpr (isFlagSet(mode, modes::Mode::kMc)) { + // reco-vs-truth correlation: requires BOTH a reco pair and matched mc info + if constexpr (isFlagSet(mode, modes::Mode::kReco) && isFlagSet(mode, modes::Mode::kMc)) { initMc(Specs); } + // pure mc-truth pair: requires mc info WITHOUT a reco pair + if constexpr (isFlagSet(mode, modes::Mode::kMc) && !isFlagSet(mode, modes::Mode::kReco)) { + initMcTruth(Specs); + } + if constexpr (isFlagSet(mode, modes::Mode::kSe)) { initSeMixingQa(Specs); } @@ -559,8 +674,8 @@ class PairHistManager auto mcParticle1 = particle1.template fMcParticle_as(); auto mcParticle2 = particle2.template fMcParticle_as(); - mTrueParticle1 = ROOT::Math::PtEtaPhiMVector(mAbsCharge1 * mcParticle1.pt(), mcParticle1.eta(), mcParticle1.phi(), mPdgMass1); - mTrueParticle2 = ROOT::Math::PtEtaPhiMVector(mAbsCharge2 * mcParticle2.pt(), mcParticle2.eta(), mcParticle2.phi(), mPdgMass2); + mTrueParticle1 = ROOT::Math::PtEtaPhiMVector(mcParticle1.pt(), mcParticle1.eta(), mcParticle1.phi(), mPdgMass1); + mTrueParticle2 = ROOT::Math::PtEtaPhiMVector(mcParticle2.pt(), mcParticle2.eta(), mcParticle2.phi(), mPdgMass2); // compute true kinematics mTrueKt = getKt(mTrueParticle1, mTrueParticle2); @@ -600,6 +715,49 @@ class PairHistManager mTrueCent = 0.5f * (mcCol1.cent() + mcCol2.cent()); } + // pure mc-truth pair: particles ARE the truth, no reco track/trackTable exists. + // Mass is always the PDG mass here — there is no "reconstructed mass" concept + // for a truth particle, so mUsePdgMass is not consulted in this path. + // NOTE: Dalitz plots are not supported here — there is no trackTable/daughter + // structure for a pure mc-truth particle-particle pair. + template + void setPairMcTruth(T1 const& particle1, T2 const& particle2) + { + mTrueParticle1 = ROOT::Math::PtEtaPhiMVector(particle1.pt(), particle1.eta(), particle1.phi(), mPdgMass1); + mTrueParticle2 = ROOT::Math::PtEtaPhiMVector(particle2.pt(), particle2.eta(), particle2.phi(), mPdgMass2); + + mTrueKt = getKt(mTrueParticle1, mTrueParticle2); + mTrueMt = getMt(mTrueParticle1, mTrueParticle2); + mTrueMinv = getMinv(mTrueParticle1, mTrueParticle2); + mTrueKstar = getKstar(mTrueParticle1, mTrueParticle2); + + if (mPlotBertschPratt) { + std::tie(mTrueQout, mTrueQside, mTrueQlong) = computeBertschPrattLCMS(mTrueParticle1, mTrueParticle2); + } + if (mPlotDeltaEtaDeltaPhi) { + mTrueDeltaEta = particle1.eta() - particle2.eta(); + mTrueDeltaPhi = RecoDecay::constrainAngle(particle1.phi() - particle2.phi(), -o2::constants::math::PIHalf); + } + } + + // same-event: single (truth) collision for true mult/cent + template + void setPairMcTruth(T1 const& particle1, T2 const& particle2, T3 const& col) + { + setPairMcTruth(particle1, particle2); + mTrueMult = col.mult(); + mTrueCent = col.cent(); + } + + // mixed-event: two (truth) collisions, averaged mult/cent — same convention as setPair + template + void setPairMcTruth(T1 const& particle1, T2 const& particle2, T3 const& col1, T4 const& col2) + { + setPairMcTruth(particle1, particle2); + mTrueMult = 0.5f * (col1.mult() + col2.mult()); + mTrueCent = 0.5f * (col1.cent() + col2.cent()); + } + bool checkPairCuts() const { return (!(mKstarMin > 0.f) || mKstar > mKstarMin) && @@ -617,12 +775,15 @@ class PairHistManager template void fill() { - if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco)) { fillAnalysis(); } - if constexpr (isFlagSet(mode, modes::Mode::kMc)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco) && isFlagSet(mode, modes::Mode::kMc)) { fillMc(); } + if constexpr (isFlagSet(mode, modes::Mode::kMc) && !isFlagSet(mode, modes::Mode::kReco)) { + fillMcTruth(); + } } template @@ -768,6 +929,7 @@ class PairHistManager } } + // reco-vs-truth correlation histograms (kReco and kMc both set) void initMc(std::map> const& Specs) { std::string mcDir = std::string(prefix) + std::string(McDir); @@ -779,24 +941,75 @@ class PairHistManager mHistogramRegistry->add(mcDir + getHistNameV2(kTrueCentVsCent, HistTable), getHistDesc(kTrueCentVsCent, HistTable), getHistType(kTrueCentVsCent, HistTable), {Specs.at(kTrueCentVsCent)}); } + // pure mc-truth pair (no reco counterpart, kMc without kReco) — reuses the + // same mPlot1d/mPlot2d/mPlotDeltaEtaDeltaPhi/mPlotBertschPratt flags as the + // reco analysis path, since these are histogram-content flags, not mode flags + void initMcTruth(std::map> const& Specs) + { + std::string mcDir = std::string(prefix) + std::string(McDir); + if (mPlot1d) { + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueKstar, HistTable), getHistDesc(kTrueKstar, HistTable), getHistType(kTrueKstar, HistTable), {Specs.at(kTrueKstar)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueKt, HistTable), getHistDesc(kTrueKt, HistTable), getHistType(kTrueKt, HistTable), {Specs.at(kTrueKt)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueMt, HistTable), getHistDesc(kTrueMt, HistTable), getHistType(kTrueMt, HistTable), {Specs.at(kTrueMt)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueMinv1D, HistTable), getHistDesc(kTrueMinv1D, HistTable), getHistType(kTrueMinv1D, HistTable), {Specs.at(kTrueMinv1D)}); + } + if (mPlot2d) { + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePt1VsPt2, HistTable), getHistDesc(kTruePt1VsPt2, HistTable), getHistType(kTruePt1VsPt2, HistTable), {Specs.at(kTruePt1VsPt2)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePt1VsKstar, HistTable), getHistDesc(kTruePt1VsKstar, HistTable), getHistType(kTruePt1VsKstar, HistTable), {Specs.at(kTruePt1VsKstar)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePt2VsKstar, HistTable), getHistDesc(kTruePt2VsKstar, HistTable), getHistType(kTruePt2VsKstar, HistTable), {Specs.at(kTruePt2VsKstar)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePt1VsKt, HistTable), getHistDesc(kTruePt1VsKt, HistTable), getHistType(kTruePt1VsKt, HistTable), {Specs.at(kTruePt1VsKt)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePt2VsKt, HistTable), getHistDesc(kTruePt2VsKt, HistTable), getHistType(kTruePt2VsKt, HistTable), {Specs.at(kTruePt2VsKt)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePt1VsMt, HistTable), getHistDesc(kTruePt1VsMt, HistTable), getHistType(kTruePt1VsMt, HistTable), {Specs.at(kTruePt1VsMt)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTruePt2VsMt, HistTable), getHistDesc(kTruePt2VsMt, HistTable), getHistType(kTruePt2VsMt, HistTable), {Specs.at(kTruePt2VsMt)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueKstarVsKt, HistTable), getHistDesc(kTrueKstarVsKt, HistTable), getHistType(kTrueKstarVsKt, HistTable), {Specs.at(kTrueKstarVsKt)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueKstarVsMt, HistTable), getHistDesc(kTrueKstarVsMt, HistTable), getHistType(kTrueKstarVsMt, HistTable), {Specs.at(kTrueKstarVsMt)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueKstarVsMult, HistTable), getHistDesc(kTrueKstarVsMult, HistTable), getHistType(kTrueKstarVsMult, HistTable), {Specs.at(kTrueKstarVsMult)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueKstarVsCent, HistTable), getHistDesc(kTrueKstarVsCent, HistTable), getHistType(kTrueKstarVsCent, HistTable), {Specs.at(kTrueKstarVsCent)}); + } + if (mPlotDeltaEtaDeltaPhi) { + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueDeltaEtaDeltaPhi, HistTable), getHistDesc(kTrueDeltaEtaDeltaPhi, HistTable), getHistType(kTrueDeltaEtaDeltaPhi, HistTable), {Specs.at(kTrueDeltaEtaDeltaPhi)}); + } + if (mPlotBertschPratt) { + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueQout, HistTable), getHistDesc(kTrueQout, HistTable), getHistType(kTrueQout, HistTable), {Specs.at(kTrueQout)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueQside, HistTable), getHistDesc(kTrueQside, HistTable), getHistType(kTrueQside, HistTable), {Specs.at(kTrueQside)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueQlong, HistTable), getHistDesc(kTrueQlong, HistTable), getHistType(kTrueQlong, HistTable), {Specs.at(kTrueQlong)}); + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueQoutQsideQlong, HistTable), getHistDesc(kTrueQoutQsideQlong, HistTable), getHistType(kTrueQoutQsideQlong, HistTable), {Specs.at(kTrueQoutQsideQlong)}); + } + if (mPlotKstarVsMtVsMult) { + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueKstarVsMtVsMult, HistTable), getHistDesc(kTrueKstarVsMtVsMult, HistTable), getHistType(kTrueKstarVsMtVsMult, HistTable), {Specs.at(kTrueKstarVsMtVsMult)}); + } + if (mPlotKstarVsMtVsMultVsCent) { + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueKstarVsMtVsMultVsCent, HistTable), getHistDesc(kTrueKstarVsMtVsMultVsCent, HistTable), getHistType(kTrueKstarVsMtVsMultVsCent, HistTable), {Specs.at(kTrueKstarVsMtVsMultVsCent)}); + } + if (mPlotKstarVsMtVsPt1VsPt2) { + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueKstarVsMtVsPt1VsPt2, HistTable), getHistDesc(kTrueKstarVsMtVsPt1VsPt2, HistTable), getHistType(kTrueKstarVsMtVsPt1VsPt2, HistTable), {Specs.at(kTrueKstarVsMtVsPt1VsPt2)}); + } + if (mPlotKstarVsMtVsPt1VsPt2VsMult) { + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueKstarVsMtVsPt1VsPt2VsMult, HistTable), getHistDesc(kTrueKstarVsMtVsPt1VsPt2VsMult, HistTable), getHistType(kTrueKstarVsMtVsPt1VsPt2VsMult, HistTable), {Specs.at(kTrueKstarVsMtVsPt1VsPt2VsMult)}); + } + if (mPlotKstarVsMtVsPt1VsPt2VsMultVsCent) { + mHistogramRegistry->add(mcDir + getHistNameV2(kTrueKstarVsMtVsPt1VsPt2VsMultVsCent, HistTable), getHistDesc(kTrueKstarVsMtVsPt1VsPt2VsMultVsCent, HistTable), getHistType(kTrueKstarVsMtVsPt1VsPt2VsMultVsCent, HistTable), {Specs.at(kTrueKstarVsMtVsPt1VsPt2VsMultVsCent)}); + } + } + void initSeMixingQa(std::map> const& Specs) { - std::string mcDir = std::string(prefix) + std::string(MixingQaDir); + std::string dir = std::string(prefix) + std::string(MixingQaDir); if (mPairCorrelationQa) { - mHistogramRegistry->add(mcDir + getHistNameV2(kSeNpart1VsNpart2, HistTable), getHistDesc(kSeNpart1VsNpart2, HistTable), getHistType(kSeNpart1VsNpart2, HistTable), {Specs.at(kSeNpart1VsNpart2)}); + mHistogramRegistry->add(dir + getHistNameV2(kSeNpart1VsNpart2, HistTable), getHistDesc(kSeNpart1VsNpart2, HistTable), getHistType(kSeNpart1VsNpart2, HistTable), {Specs.at(kSeNpart1VsNpart2)}); } } void initMeMixingQa(std::map> const& Specs) { - std::string mcDir = std::string(prefix) + std::string(MixingQaDir); + std::string dir = std::string(prefix) + std::string(MixingQaDir); if (mPairCorrelationQa) { - mHistogramRegistry->add(mcDir + getHistNameV2(kMeMixingWindowRaw, HistTable), getHistDesc(kMeMixingWindowRaw, HistTable), getHistType(kMeMixingWindowRaw, HistTable), {Specs.at(kMeMixingWindowRaw)}); - mHistogramRegistry->add(mcDir + getHistNameV2(kMeMixingWindowEffective, HistTable), getHistDesc(kMeMixingWindowEffective, HistTable), getHistType(kMeMixingWindowEffective, HistTable), {Specs.at(kMeMixingWindowEffective)}); - mHistogramRegistry->add(mcDir + getHistNameV2(kMeNpart1VsNpart2, HistTable), getHistDesc(kMeNpart1VsNpart2, HistTable), getHistType(kMeNpart1VsNpart2, HistTable), {Specs.at(kMeNpart1VsNpart2)}); + mHistogramRegistry->add(dir + getHistNameV2(kMeMixingWindowRaw, HistTable), getHistDesc(kMeMixingWindowRaw, HistTable), getHistType(kMeMixingWindowRaw, HistTable), {Specs.at(kMeMixingWindowRaw)}); + mHistogramRegistry->add(dir + getHistNameV2(kMeMixingWindowEffective, HistTable), getHistDesc(kMeMixingWindowEffective, HistTable), getHistType(kMeMixingWindowEffective, HistTable), {Specs.at(kMeMixingWindowEffective)}); + mHistogramRegistry->add(dir + getHistNameV2(kMeNpart1VsNpart2, HistTable), getHistDesc(kMeNpart1VsNpart2, HistTable), getHistType(kMeNpart1VsNpart2, HistTable), {Specs.at(kMeNpart1VsNpart2)}); } if (mEventMixingQa) { - mHistogramRegistry->add(mcDir + getHistNameV2(kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2, HistTable), getHistDesc(kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2, HistTable), getHistType(kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2, HistTable), {Specs.at(kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2)}); + mHistogramRegistry->add(dir + getHistNameV2(kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2, HistTable), getHistDesc(kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2, HistTable), getHistType(kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2, HistTable), {Specs.at(kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2)}); } } @@ -889,6 +1102,7 @@ class PairHistManager } } + // reco-vs-truth correlation fill (kReco and kMc both set) void fillMc() { if (mHasMcPair) { @@ -903,6 +1117,56 @@ class PairHistManager } } + // pure mc-truth pair fill (kMc without kReco) — uses the same mTrue* members + // that setPairMcTruth() populated; no mHasMcPair/mHasMcCol gating needed since + // there is no missing-link case here (the particles ARE the truth particles) + void fillMcTruth() + { + if (mPlot1d) { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueKstar, HistTable)), mTrueKstar); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueKt, HistTable)), mTrueKt); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueMt, HistTable)), mTrueMt); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueMinv1D, HistTable)), mTrueMinv); + } + if (mPlot2d) { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTruePt1VsPt2, HistTable)), mTrueParticle1.Pt(), mTrueParticle2.Pt()); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTruePt1VsKstar, HistTable)), mTrueParticle1.Pt(), mTrueKstar); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTruePt2VsKstar, HistTable)), mTrueParticle2.Pt(), mTrueKstar); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTruePt1VsKt, HistTable)), mTrueParticle1.Pt(), mTrueKt); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTruePt2VsKt, HistTable)), mTrueParticle2.Pt(), mTrueKt); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTruePt1VsMt, HistTable)), mTrueParticle1.Pt(), mTrueMt); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTruePt2VsMt, HistTable)), mTrueParticle2.Pt(), mTrueMt); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueKstarVsKt, HistTable)), mTrueKstar, mTrueKt); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueKstarVsMt, HistTable)), mTrueKstar, mTrueMt); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueKstarVsMult, HistTable)), mTrueKstar, mTrueMult); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueKstarVsCent, HistTable)), mTrueKstar, mTrueCent); + } + if (mPlotDeltaEtaDeltaPhi) { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueDeltaEtaDeltaPhi, HistTable)), mTrueDeltaPhi, mTrueDeltaEta); + } + if (mPlotBertschPratt) { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueQout, HistTable)), mTrueQout); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueQside, HistTable)), mTrueQside); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueQlong, HistTable)), mTrueQlong); + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueQoutQsideQlong, HistTable)), mTrueQout, mTrueQside, mTrueQlong); + } + if (mPlotKstarVsMtVsMult) { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueKstarVsMtVsMult, HistTable)), mTrueKstar, mTrueMt, mTrueMult); + } + if (mPlotKstarVsMtVsMultVsCent) { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueKstarVsMtVsMultVsCent, HistTable)), mTrueKstar, mTrueMt, mTrueMult, mTrueCent); + } + if (mPlotKstarVsMtVsPt1VsPt2) { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueKstarVsMtVsPt1VsPt2, HistTable)), mTrueKstar, mTrueMt, mTrueParticle1.Pt(), mTrueParticle2.Pt()); + } + if (mPlotKstarVsMtVsPt1VsPt2VsMult) { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueKstarVsMtVsPt1VsPt2VsMult, HistTable)), mTrueKstar, mTrueMt, mTrueParticle1.Pt(), mTrueParticle2.Pt(), mTrueMult); + } + if (mPlotKstarVsMtVsPt1VsPt2VsMultVsCent) { + mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kTrueKstarVsMtVsPt1VsPt2VsMultVsCent, HistTable)), mTrueKstar, mTrueMt, mTrueParticle1.Pt(), mTrueParticle2.Pt(), mTrueMult, mTrueCent); + } + } + float getKt(ROOT::Math::PtEtaPhiMVector const& part1, ROOT::Math::PtEtaPhiMVector const& part2) { auto sum = (part1 + part2); @@ -987,9 +1251,9 @@ class PairHistManager const double kside2 = (p2.Py() * tPx - p2.Px() * tPy) / tPt; const double klong2 = gammaL * (p2.Pz() - betaL * p2.E()); - float qOut = static_cast(kout1 - kout2); - float qSide = static_cast(kside1 - kside2); - float qLong = static_cast(klong1 - klong2); + auto qOut = static_cast(kout1 - kout2); + auto qSide = static_cast(kside1 - kside2); + auto qLong = static_cast(klong1 - klong2); return {qOut, qSide, qLong}; } @@ -1007,8 +1271,8 @@ class PairHistManager int mAbsCharge1 = 1; int mAbsCharge2 = 1; - ROOT::Math::PtEtaPhiMVector mParticle1{}; - ROOT::Math::PtEtaPhiMVector mParticle2{}; + ROOT::Math::PtEtaPhiMVector mParticle1; + ROOT::Math::PtEtaPhiMVector mParticle2; float mRecoMass1 = 0.f; float mRecoMass2 = 0.f; float mKstar = 0.f; @@ -1021,15 +1285,22 @@ class PairHistManager double mMass13 = 0.; double mMassTot2 = 0.; - // mc - ROOT::Math::PtEtaPhiMVector mTrueParticle1{}; - ROOT::Math::PtEtaPhiMVector mTrueParticle2{}; + // mc (used for both reco-vs-truth correlation AND pure mc-truth-only pairs — + // for the latter, these are simply the primary/only kinematic values, not a + // "true" comparison against anything) + ROOT::Math::PtEtaPhiMVector mTrueParticle1; + ROOT::Math::PtEtaPhiMVector mTrueParticle2; float mTrueKstar = 0.f; float mTrueKt = 0.f; float mTrueMt = 0.f; float mTrueMinv = 0.f; float mTrueMult = 0.f; float mTrueCent = 0.f; + float mTrueQout = 0.f; + float mTrueQside = 0.f; + float mTrueQlong = 0.f; + float mTrueDeltaEta = 0.f; + float mTrueDeltaPhi = 0.f; // cuts bool mHasMcPair = false; @@ -1082,10 +1353,8 @@ class PairHistManager bool mPairCorrelationQa = false; bool mEventMixingQa = false; - std::unordered_set mParticles1PerEvent = {}; - std::unordered_set mParticles2PerEvent = {}; + std::unordered_set mParticles1PerEvent; + std::unordered_set mParticles2PerEvent; }; - -}; // namespace pairhistmanager -}; // namespace o2::analysis::femto +}; // namespace o2::analysis::femto::pairhistmanager #endif // PWGCF_FEMTO_CORE_PAIRHISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/pairProcessHelpers.h b/PWGCF/Femto/Core/pairProcessHelpers.h index da40ff73a7c..b4d05f37be5 100644 --- a/PWGCF/Femto/Core/pairProcessHelpers.h +++ b/PWGCF/Femto/Core/pairProcessHelpers.h @@ -23,12 +23,10 @@ #include #include +#include -namespace o2::analysis::femto +namespace o2::analysis::femto::pairprocesshelpers { -namespace pairprocesshelpers -{ - enum PairOrder : uint8_t { kOrder12, kOrder21 @@ -130,7 +128,7 @@ void processSameEvent(T1 const& SliceParticle, continue; } // check if pair is clean - if (!PcManager.isCleanPair(p1, p2, TrackTable, mcPartonicMothers)) { + if (!PcManager.isCleanPair(p1, p2, TrackTable, mcParticles, mcPartonicMothers)) { continue; } // check if pair is close @@ -263,7 +261,7 @@ void processSameEvent(T1 const& SliceParticle1, continue; } // pair cleaning - if (!PcManager.isCleanPair(p1, p2, TrackTable, mcPartonicMothers)) { + if (!PcManager.isCleanPair(p1, p2, TrackTable, mcParticles, mcPartonicMothers)) { continue; } // Close pair rejection @@ -280,6 +278,131 @@ void processSameEvent(T1 const& SliceParticle1, } PairHistManager.fillMixingQaSe(); } +// process same event for identical particles, mc truth only (no track table, no reco collisions) +template +void processSameEvent(T1 const& SliceParticle, + T2 const& /*mcParticles*/, + T3 const& mcMothers, + T4 const& mcPartonicMothers, + T5 const& Collision, + T6& ParticleHistManager, + T7& PairHistManager, + T8& ParticleCleaner, + T9& CprManager, + T10& PcManager, + PairOrder pairOrder) +{ + PairHistManager.resetTrackedParticlesPerEvent(); + for (auto const& part : SliceParticle) { + if (!ParticleCleaner.isClean(part, mcMothers, mcPartonicMothers)) { + continue; + } + ParticleHistManager.fill(part, mcMothers, mcPartonicMothers); + } + for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(SliceParticle, SliceParticle))) { + if (!ParticleCleaner.isClean(p1, mcMothers, mcPartonicMothers) || + !ParticleCleaner.isClean(p2, mcMothers, mcPartonicMothers)) { + continue; + } + if (!PcManager.isCleanPair(p1, p2, mcPartonicMothers)) { + continue; + } + CprManager.setPair(p1, p2); + if (CprManager.isClosePair()) { + continue; + } + switch (pairOrder) { + case kOrder12: + PairHistManager.setPairMcTruth(p1, p2, Collision); + break; + case kOrder21: + PairHistManager.setPairMcTruth(p2, p1, Collision); + break; + default: + PairHistManager.setPairMcTruth(p1, p2, Collision); + } + CprManager.fill(PairHistManager.getKstar()); + if (PairHistManager.checkPairCuts()) { + PairHistManager.template fill(); + PairHistManager.trackParticlesPerEvent(p1, p2); + } + } + PairHistManager.fillMixingQaSe(); +} + +// process same event for non-identical particles, mc truth only +template +void processSameEvent(T1 const& SliceParticle1, + T2 const& SliceParticle2, + T3 const& /*mcParticles*/, + T4 const& mcMothers, + T5 const& mcPartonicMothers, + T6 const& Collision, + T7& ParticleHistManager1, + T8& ParticleHistManager2, + T9& PairHistManager, + T10& ParticleCleaner1, + T11& ParticleCleaner2, + T12& CprManager, + T13& PcManager) +{ + PairHistManager.resetTrackedParticlesPerEvent(); + for (auto const& part : SliceParticle1) { + if (!ParticleCleaner1.isClean(part, mcMothers, mcPartonicMothers)) { + continue; + } + ParticleHistManager1.fill(part, mcMothers, mcPartonicMothers); + } + for (auto const& part : SliceParticle2) { + if (!ParticleCleaner2.isClean(part, mcMothers, mcPartonicMothers)) { + continue; + } + ParticleHistManager2.fill(part, mcMothers, mcPartonicMothers); + } + for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(SliceParticle1, SliceParticle2))) { + if (!ParticleCleaner1.isClean(p1, mcMothers, mcPartonicMothers) || + !ParticleCleaner2.isClean(p2, mcMothers, mcPartonicMothers)) { + continue; + } + if (!PcManager.isCleanPair(p1, p2, mcPartonicMothers)) { + continue; + } + CprManager.setPair(p1, p2); + if (CprManager.isClosePair()) { + continue; + } + PairHistManager.setPairMcTruth(p1, p2, Collision); + CprManager.fill(PairHistManager.getKstar()); + if (PairHistManager.checkPairCuts()) { + PairHistManager.template fill(); + PairHistManager.trackParticlesPerEvent(p1, p2); + } + } + PairHistManager.fillMixingQaSe(); +} // mixed event in data template sliceByCached(o2::aod::femtobase::stored::fColId, 0, cache))> sliceParticle1; + for (auto const& [collision1, collision2] : o2::soa::selfCombinations(policy, depth, -1, Collisions, Collisions)) { // --- new window --- @@ -318,6 +447,7 @@ void processMixedEvent(T1 const& Collisions, windowSizeRaw = 0; windowSizeEffective = 0; lastCollisionIndex = collision1.globalIndex(); + sliceParticle1.emplace(Partition1->sliceByCached(o2::aod::femtobase::stored::fColId, collision1.globalIndex(), cache)); } ++windowSizeRaw; @@ -329,20 +459,18 @@ void processMixedEvent(T1 const& Collisions, CprManager.setMagField(collision1.magField()); - auto sliceParticle1 = Partition1->sliceByCached(o2::aod::femtobase::stored::fColId, collision1.globalIndex(), cache); - auto sliceParticle2 = Partition2->sliceByCached(o2::aod::femtobase::stored::fColId, collision2.globalIndex(), cache); PairHistManager.resetTrackedParticlesPerEvent(); - if (sliceParticle1.size() == 0 || sliceParticle2.size() == 0) { + if (sliceParticle1->size() == 0 || sliceParticle2.size() == 0) { PairHistManager.fillMixingQaMePerEvent(); continue; } bool hasValidPair = false; PairHistManager.fillMixingQaMe(collision1, collision2); - for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(sliceParticle1, sliceParticle2))) { + for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(*sliceParticle1, sliceParticle2))) { if (!PcManager.isCleanPair(p1, p2, TrackTable)) { continue; @@ -415,6 +543,12 @@ void processMixedEvent(T1 const& Collisions, int windowSizeRaw = 0; int windowSizeEffective = 0; + // collision1 is fixed across each mixing window, so its track slice is + // materialized once per window and reused for every mixing partner, instead + // of being re-sliced (a fresh arrow Slice + selection copy, the dominant cost + // on the heaviest femto trains) on every (collision1, collision2) pair. + std::optionalsliceByCached(o2::aod::femtobase::stored::fColId, 0, cache))> sliceParticle1; + for (auto const& [collision1, collision2] : o2::soa::selfCombinations(policy, depth, -1, Collisions, Collisions)) { if (collision1.globalIndex() != lastCollisionIndex) { if (lastCollisionIndex != -1) { @@ -423,6 +557,7 @@ void processMixedEvent(T1 const& Collisions, windowSizeRaw = 0; windowSizeEffective = 0; lastCollisionIndex = collision1.globalIndex(); + sliceParticle1.emplace(Partition1->sliceByCached(o2::aod::femtobase::stored::fColId, collision1.globalIndex(), cache)); } ++windowSizeRaw; @@ -434,13 +569,11 @@ void processMixedEvent(T1 const& Collisions, CprManager.setMagField(collision1.magField()); - auto sliceParticle1 = Partition1->sliceByCached(o2::aod::femtobase::stored::fColId, collision1.globalIndex(), cache); - auto sliceParticle2 = Partition2->sliceByCached(o2::aod::femtobase::stored::fColId, collision2.globalIndex(), cache); PairHistManager.resetTrackedParticlesPerEvent(); - if (sliceParticle1.size() == 0 || sliceParticle2.size() == 0) { + if (sliceParticle1->size() == 0 || sliceParticle2.size() == 0) { PairHistManager.fillMixingQaMePerEvent(); continue; } @@ -448,7 +581,7 @@ void processMixedEvent(T1 const& Collisions, bool hasValidPair = false; PairHistManager.fillMixingQaMe(collision1, collision2); - for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(sliceParticle1, sliceParticle2))) { + for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(*sliceParticle1, sliceParticle2))) { if (!ParticleCleaner1.isClean(p1, mcParticles, mcMothers, mcPartonicMothers) || !ParticleCleaner2.isClean(p2, mcParticles, mcMothers, mcPartonicMothers)) { @@ -486,8 +619,108 @@ void processMixedEvent(T1 const& Collisions, PairHistManager.fillMixingQaMePerMixingBin(windowSizeRaw, windowSizeEffective); } } +// process mixed event, mc truth only (no track table, collisions already mc truth so no separate mcCollisions) +template +void processMixedEvent(T1 const& Collisions, + T2& Partition1, + T3& Partition2, + T4 const& /*mcParticles*/, + T5 const& mcMothers, + T6 const& mcPartonicMothers, + T7& cache, + T8 const& policy, + T9 const& depth, + T10& PairHistManager, + T11& ParticleCleaner1, + T12& ParticleCleaner2, + T13& CprManager, + T14& PcManager) +{ + int64_t lastCollisionIndex = -1; + int windowSizeRaw = 0; + int windowSizeEffective = 0; + + std::optionalsliceByCached(o2::aod::femtomcparticle::fMcColId, 0, cache))> sliceParticle1; + + for (auto const& [collision1, collision2] : o2::soa::selfCombinations(policy, depth, -1, Collisions, Collisions)) { + + if (collision1.globalIndex() != lastCollisionIndex) { + if (lastCollisionIndex != -1) { + PairHistManager.fillMixingQaMePerMixingBin(windowSizeRaw, windowSizeEffective); + } + windowSizeRaw = 0; + windowSizeEffective = 0; + lastCollisionIndex = collision1.globalIndex(); + sliceParticle1.emplace(Partition1->sliceByCached(o2::aod::femtomcparticle::fMcColId, collision1.globalIndex(), cache)); + } + + ++windowSizeRaw; + + auto sliceParticle2 = Partition2->sliceByCached(o2::aod::femtomcparticle::fMcColId, collision2.globalIndex(), cache); + + PairHistManager.resetTrackedParticlesPerEvent(); + + if (sliceParticle1->size() == 0 || sliceParticle2.size() == 0) { + PairHistManager.fillMixingQaMePerEvent(); + continue; + } + + bool hasValidPair = false; + PairHistManager.fillMixingQaMe(collision1, collision2); + + for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(*sliceParticle1, sliceParticle2))) { + + if (!ParticleCleaner1.isClean(p1, mcMothers, mcPartonicMothers) || + !ParticleCleaner2.isClean(p2, mcMothers, mcPartonicMothers)) { + continue; + } + + if (!PcManager.isCleanPair(p1, p2, mcPartonicMothers)) { + continue; + } + + CprManager.setPair(p1, p2); + if (CprManager.isClosePair()) { + continue; + } + + PairHistManager.setPairMcTruth(p1, p2, collision1, collision2); + + CprManager.fill(PairHistManager.getKstar()); + + if (PairHistManager.checkPairCuts()) { + hasValidPair = true; + PairHistManager.trackParticlesPerEvent(p1, p2); + PairHistManager.template fill(); + } + } + + if (hasValidPair) { + ++windowSizeEffective; + } + + PairHistManager.fillMixingQaMePerEvent(); + } + + if (windowSizeRaw > 0) { + PairHistManager.fillMixingQaMePerMixingBin(windowSizeRaw, windowSizeEffective); + } +} -} // namespace pairprocesshelpers -} // namespace o2::analysis::femto +} // namespace o2::analysis::femto::pairprocesshelpers #endif // PWGCF_FEMTO_CORE_PAIRPROCESSHELPERS_H_ diff --git a/PWGCF/Femto/Core/particleCleaner.h b/PWGCF/Femto/Core/particleCleaner.h index 110cda597f5..9974c20cb47 100644 --- a/PWGCF/Femto/Core/particleCleaner.h +++ b/PWGCF/Femto/Core/particleCleaner.h @@ -21,12 +21,9 @@ #include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::particlecleaner { -namespace particlecleaner -{ - -template +template struct ConfParticleCleaner : o2::framework::ConfigurableGroup { std::string prefix = std::string(Prefix); o2::framework::Configurable activate{"activate", false, "Activate particle cleaner"}; @@ -78,6 +75,11 @@ constexpr const char PrefixOmegaCleaner2[] = "OmegaCleaner2"; using ConfOmegaCleaner1 = ConfParticleCleaner; using ConfOmegaCleaner2 = ConfParticleCleaner; +constexpr const char PrefixMcParticleCleaner1[] = "McParticleCleaner1"; +constexpr const char PrefixMcParticleCleaner2[] = "McParticleCleaner2"; +using ConfMcParticleCleaner1 = ConfParticleCleaner; +using ConfMcParticleCleaner2 = ConfParticleCleaner; + class ParticleCleaner { public: @@ -103,12 +105,36 @@ class ParticleCleaner mRejectedPartonicMotherPdgCodes = confMpc.rejectPartonicMotherPdgCodes.value; } + /// mc + reco template bool isClean(T1 const& particle, T2 const& /*mcParticles*/, - T3 const& /*mcMothers*/, - T4 const& /*mcPartonicMothers*/) + T3 const& mcMothers, + T4 const& mcPartonicMothers) + { + if (!mActivate) { + return true; + } + + // No MC particle at all → no mother/partonic-mother info is reachable either, + // since that lookup now goes through the mc particle row. + if (!particle.has_fMcParticle()) { + return !mRejectParticleWithoutMcParticle && mRequiredPdgCodes.empty() && + !mRejectParticleWithoutMcMother && mRequiredMotherPdgCodes.empty() && + !mRejectParticleWithoutMcPartonicMother && mRequiredPartonicMotherPdgCodes.empty(); + } + + auto mcParticle = particle.template fMcParticle_as(); + return this->isClean(mcParticle, mcMothers, mcPartonicMothers); + } + + // mc only + template + bool isClean(T1 const& mcParticle, + T2 const& /*mcMothers*/, + T3 const& /*mcPartonicMothers*/) { + if (!mActivate) { return true; } @@ -123,40 +149,32 @@ class ParticleCleaner bool hasPartonicMotherWithRejectedPdgCode = false; // MC particle - if (!particle.has_fMcParticle()) { - if (mRejectParticleWithoutMcParticle || !mRequiredPdgCodes.empty()) { - return false; - } - } else { - auto mcParticle = particle.template fMcParticle_as(); - - if (!mRequiredPdgCodes.empty()) { - hasRequiredPdgCode = false; - for (int const& pdgCode : mRequiredPdgCodes) { - if (pdgCode == mcParticle.pdgCode()) { - hasRequiredPdgCode = true; - break; - } + if (!mRequiredPdgCodes.empty()) { + hasRequiredPdgCode = false; + for (int const& pdgCode : mRequiredPdgCodes) { + if (pdgCode == mcParticle.pdgCode()) { + hasRequiredPdgCode = true; + break; } } + } - if (!mRejectedPdgCodes.empty()) { - for (int const& pdgCode : mRejectedPdgCodes) { - if (pdgCode == mcParticle.pdgCode()) { - hasRejectedPdgCode = true; - break; - } + if (!mRejectedPdgCodes.empty()) { + for (int const& pdgCode : mRejectedPdgCodes) { + if (pdgCode == mcParticle.pdgCode()) { + hasRejectedPdgCode = true; + break; } } } - // MC mother - if (!particle.has_fMcMother()) { + // MC mother — looked up via mcParticle (T2 must be Join) + if (!mcParticle.has_fMcMother()) { if (mRejectParticleWithoutMcMother || !mRequiredMotherPdgCodes.empty()) { return false; } } else { - auto mother = particle.template fMcMother_as(); + auto mother = mcParticle.template fMcMother_as(); if (!mRequiredMotherPdgCodes.empty()) { hasMotherWithRequiredPdgCode = false; @@ -178,14 +196,14 @@ class ParticleCleaner } } - // MC partonic mother - if (!particle.has_fMcPartMoth()) { + // MC partonic mother — same idea, via mcParticle + if (!mcParticle.has_fMcPartMoth()) { if (mRejectParticleWithoutMcPartonicMother || !mRequiredPartonicMotherPdgCodes.empty()) { return false; } } else { - auto partonicMother = particle.template fMcPartMoth_as(); + auto partonicMother = mcParticle.template fMcPartMoth_as(); if (!mRequiredPartonicMotherPdgCodes.empty()) { hasPartonicMotherWithRequiredPdgCode = false; @@ -217,15 +235,14 @@ class ParticleCleaner bool mRejectParticleWithoutMcParticle = true; bool mRejectParticleWithoutMcMother = true; bool mRejectParticleWithoutMcPartonicMother = true; - std::vector mRequiredPdgCodes{}; - std::vector mRejectedPdgCodes{}; - std::vector mRequiredMotherPdgCodes{}; - std::vector mRejectedMotherPdgCodes{}; - std::vector mRequiredPartonicMotherPdgCodes{}; - std::vector mRejectedPartonicMotherPdgCodes{}; + std::vector mRequiredPdgCodes; + std::vector mRejectedPdgCodes; + std::vector mRequiredMotherPdgCodes; + std::vector mRejectedMotherPdgCodes; + std::vector mRequiredPartonicMotherPdgCodes; + std::vector mRejectedPartonicMotherPdgCodes; }; -} // namespace particlecleaner -} // namespace o2::analysis::femto +} // namespace o2::analysis::femto::particlecleaner #endif // PWGCF_FEMTO_CORE_PARTICLECLEANER_H_ diff --git a/PWGCF/Femto/Core/partitions.h b/PWGCF/Femto/Core/partitions.h index aac05f3ea91..cb32840b0d7 100644 --- a/PWGCF/Femto/Core/partitions.h +++ b/PWGCF/Femto/Core/partitions.h @@ -17,139 +17,169 @@ #define PWGCF_FEMTO_CORE_PARTITIONS_H_ // collsion selection -#define MAKE_COLLISION_FILTER(selection) \ - (o2::aod::femtocollisions::posZ >= selection.vtxZMin && o2::aod::femtocollisions::posZ <= selection.vtxZMax) && \ - (o2::aod::femtocollisions::mult >= selection.multMin && o2::aod::femtocollisions::mult <= selection.multMax) && \ - (o2::aod::femtocollisions::cent >= selection.centMin && o2::aod::femtocollisions::cent <= selection.centMax) && \ - (o2::aod::femtocollisions::magField >= o2::framework::expressions::as(selection.magFieldMin) && \ - o2::aod::femtocollisions::magField <= o2::framework::expressions::as(selection.magFieldMax)) && \ - ncheckbit(o2::aod::femtocollisions::mask, selection.collisionMask) +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define MAKE_COLLISION_FILTER(selection) \ + (o2::aod::femtocollisions::posZ >= (selection).vtxZMin && o2::aod::femtocollisions::posZ <= (selection).vtxZMax) && \ + (o2::aod::femtocollisions::mult >= (selection).multMin && o2::aod::femtocollisions::mult <= (selection).multMax) && \ + (o2::aod::femtocollisions::cent >= (selection).centMin && o2::aod::femtocollisions::cent <= (selection).centMax) && \ + (o2::aod::femtocollisions::magField >= o2::framework::expressions::as((selection).magFieldMin) && \ + o2::aod::femtocollisions::magField <= o2::framework::expressions::as((selection).magFieldMax)) && \ + ncheckbit(o2::aod::femtocollisions::mask, (selection).collisionMask) // macro for track momentum, i.e. ||q|*pT/q| * cosh(eta) // there is no ncosh function, so we have to make our own, i.e. cosh(x) = (exp(x)+exp(-x))/2 +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define TRACK_MOMENTUM(chargeAbs, signedPt, eta) (nabs((chargeAbs) * (signedPt)) * (nexp(eta) + nexp(-1.f * (eta))) / 2.f) // standard track partition -#define MAKE_TRACK_PARTITION(selection) \ - ifnode(selection.chargeSign.node() != 0, ifnode(selection.chargeSign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ - (nabs(selection.chargeAbs * o2::aod::femtobase::stored::signedPt) > selection.ptMin) && \ - (nabs(selection.chargeAbs * o2::aod::femtobase::stored::signedPt) < selection.ptMax) && \ - (o2::aod::femtobase::stored::eta > selection.etaMin) && \ - (o2::aod::femtobase::stored::eta < selection.etaMax) && \ - (o2::aod::femtobase::stored::phi > selection.phiMin) && \ - (o2::aod::femtobase::stored::phi < selection.phiMax) && \ - ifnode(TRACK_MOMENTUM(selection.chargeAbs, o2::aod::femtobase::stored::signedPt, o2::aod::femtobase::stored::eta) <= selection.pidThres, \ - ncheckbit(o2::aod::femtotracks::mask, selection.maskLowMomentum) && \ - (o2::aod::femtotracks::mask & selection.rejectionMaskLowMomentum) == static_cast(0), \ - ncheckbit(o2::aod::femtotracks::mask, selection.maskHighMomentum) && \ - (o2::aod::femtotracks::mask & selection.rejectionMaskHighMomentum) == static_cast(0)) +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define MAKE_TRACK_PARTITION(selection) \ + ifnode((selection).chargeSign.node() != 0, ifnode((selection).chargeSign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs((selection).chargeAbs * o2::aod::femtobase::stored::signedPt) > (selection).ptMin) && \ + (nabs((selection).chargeAbs * o2::aod::femtobase::stored::signedPt) < (selection).ptMax) && \ + (o2::aod::femtobase::stored::eta > (selection).etaMin) && \ + (o2::aod::femtobase::stored::eta < (selection).etaMax) && \ + (o2::aod::femtobase::stored::phi > (selection).phiMin) && \ + (o2::aod::femtobase::stored::phi < (selection).phiMax) && \ + ifnode(TRACK_MOMENTUM((selection).chargeAbs, o2::aod::femtobase::stored::signedPt, o2::aod::femtobase::stored::eta) <= (selection).pidThres, \ + ncheckbit(o2::aod::femtotracks::mask, (selection).maskLowMomentum) && \ + (o2::aod::femtotracks::mask & (selection).rejectionMaskLowMomentum) == static_cast(0), \ + ncheckbit(o2::aod::femtotracks::mask, (selection).maskHighMomentum) && \ + (o2::aod::femtotracks::mask & (selection).rejectionMaskHighMomentum) == static_cast(0)) // track partition with optional mass cut -#define MAKE_TRACK_PARTITION_WITH_MASS(selection) \ - MAKE_TRACK_PARTITION(selection) && \ - (o2::aod::femtobase::stored::mass > selection.massMin) && \ - (o2::aod::femtobase::stored::mass < selection.massMax) +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define MAKE_TRACK_PARTITION_WITH_MASS(selection) \ + MAKE_TRACK_PARTITION((selection)) && \ + (o2::aod::femtobase::stored::mass > (selection).massMin) && \ + (o2::aod::femtobase::stored::mass < (selection).massMax) // partition for phis and rhos, i.e. resonance that are their own antiparticle -#define MAKE_RESONANCE_0_PARTITON(selection) \ - (o2::aod::femtobase::stored::pt > selection.ptMin) && \ - (o2::aod::femtobase::stored::pt < selection.ptMax) && \ - (o2::aod::femtobase::stored::eta > selection.etaMin) && \ - (o2::aod::femtobase::stored::eta < selection.etaMax) && \ - (o2::aod::femtobase::stored::phi > selection.phiMin) && \ - (o2::aod::femtobase::stored::phi < selection.phiMax) && \ - (o2::aod::femtobase::stored::mass > selection.massMin) && \ - (o2::aod::femtobase::stored::mass < selection.massMax) && \ - ifnode(o2::aod::femtotwotrackresonances::posDauHasHighMomentum, \ - ncheckbit(o2::aod::femtotwotrackresonances::maskPosDau, selection.posDauMaskAboveThres), \ - ncheckbit(o2::aod::femtotwotrackresonances::maskPosDau, selection.posDauMaskBelowThres)) && \ - ifnode(o2::aod::femtotwotrackresonances::negDauHasHighMomentum, \ - ncheckbit(o2::aod::femtotwotrackresonances::maskNegDau, selection.negDauMaskAboveThres), \ - ncheckbit(o2::aod::femtotwotrackresonances::maskNegDau, selection.negDauMaskBelowThres)) +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define MAKE_RESONANCE_0_PARTITON(selection) \ + (o2::aod::femtobase::stored::pt > (selection).ptMin) && \ + (o2::aod::femtobase::stored::pt < (selection).ptMax) && \ + (o2::aod::femtobase::stored::eta > (selection).etaMin) && \ + (o2::aod::femtobase::stored::eta < (selection).etaMax) && \ + (o2::aod::femtobase::stored::phi > (selection).phiMin) && \ + (o2::aod::femtobase::stored::phi < (selection).phiMax) && \ + (o2::aod::femtobase::stored::mass > (selection).massMin) && \ + (o2::aod::femtobase::stored::mass < (selection).massMax) && \ + ifnode(o2::aod::femtotwotrackresonances::posDauHasHighMomentum, \ + ncheckbit(o2::aod::femtotwotrackresonances::maskPosDau, (selection).posDauMaskAboveThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::maskPosDau, (selection).posDauMaskBelowThres)) && \ + ifnode(o2::aod::femtotwotrackresonances::negDauHasHighMomentum, \ + ncheckbit(o2::aod::femtotwotrackresonances::maskNegDau, (selection).negDauMaskAboveThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::maskNegDau, (selection).negDauMaskBelowThres)) // partition for kstars, they have distinct antiparticle -#define MAKE_RESONANCE_1_PARTITON(selection) \ - ifnode(selection.sign.node() != 0, \ - ifnode(selection.sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ - (nabs(o2::aod::femtobase::stored::signedPt) > selection.ptMin) && \ - (nabs(o2::aod::femtobase::stored::signedPt) < selection.ptMax) && \ - (o2::aod::femtobase::stored::eta > selection.etaMin) && \ - (o2::aod::femtobase::stored::eta < selection.etaMax) && \ - (o2::aod::femtobase::stored::phi > selection.phiMin) && \ - (o2::aod::femtobase::stored::phi < selection.phiMax) && \ - (o2::aod::femtobase::stored::mass > selection.massMin) && \ - (o2::aod::femtobase::stored::mass < selection.massMax) && \ - ifnode(o2::aod::femtotwotrackresonances::posDauHasHighMomentum, \ - ncheckbit(o2::aod::femtotwotrackresonances::maskPosDau, selection.posDauMaskAboveThres), \ - ncheckbit(o2::aod::femtotwotrackresonances::maskPosDau, selection.posDauMaskBelowThres)) && \ - ifnode(o2::aod::femtotwotrackresonances::negDauHasHighMomentum, \ - ncheckbit(o2::aod::femtotwotrackresonances::maskNegDau, selection.negDauMaskAboveThres), \ - ncheckbit(o2::aod::femtotwotrackresonances::maskNegDau, selection.negDauMaskBelowThres)) +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define MAKE_RESONANCE_1_PARTITON(selection) \ + ifnode((selection).sign.node() != 0, \ + ifnode((selection).sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs(o2::aod::femtobase::stored::signedPt) > (selection).ptMin) && \ + (nabs(o2::aod::femtobase::stored::signedPt) < (selection).ptMax) && \ + (o2::aod::femtobase::stored::eta > (selection).etaMin) && \ + (o2::aod::femtobase::stored::eta < (selection).etaMax) && \ + (o2::aod::femtobase::stored::phi > (selection).phiMin) && \ + (o2::aod::femtobase::stored::phi < (selection).phiMax) && \ + (o2::aod::femtobase::stored::mass > (selection).massMin) && \ + (o2::aod::femtobase::stored::mass < (selection).massMax) && \ + ifnode(o2::aod::femtotwotrackresonances::posDauHasHighMomentum, \ + ncheckbit(o2::aod::femtotwotrackresonances::maskPosDau, (selection).posDauMaskAboveThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::maskPosDau, (selection).posDauMaskBelowThres)) && \ + ifnode(o2::aod::femtotwotrackresonances::negDauHasHighMomentum, \ + ncheckbit(o2::aod::femtotwotrackresonances::maskNegDau, (selection).negDauMaskAboveThres), \ + ncheckbit(o2::aod::femtotwotrackresonances::maskNegDau, (selection).negDauMaskBelowThres)) // partition for lambdas -#define MAKE_LAMBDA_PARTITION(selection) \ - ifnode(selection.sign.node() != 0, \ - ifnode(selection.sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ - (nabs(o2::aod::femtobase::stored::signedPt) > selection.ptMin) && \ - (nabs(o2::aod::femtobase::stored::signedPt) < selection.ptMax) && \ - (o2::aod::femtobase::stored::eta > selection.etaMin) && \ - (o2::aod::femtobase::stored::eta < selection.etaMax) && \ - (o2::aod::femtobase::stored::phi > selection.phiMin) && \ - (o2::aod::femtobase::stored::phi < selection.phiMax) && \ - (o2::aod::femtobase::stored::mass > selection.massMin) && \ - (o2::aod::femtobase::stored::mass < selection.massMax) && \ - ncheckbit(o2::aod::femtov0s::mask, selection.mask) +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define MAKE_LAMBDA_PARTITION(selection) \ + ifnode((selection).sign.node() != 0, \ + ifnode((selection).sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs(o2::aod::femtobase::stored::signedPt) > (selection).ptMin) && \ + (nabs(o2::aod::femtobase::stored::signedPt) < (selection).ptMax) && \ + (o2::aod::femtobase::stored::eta > (selection).etaMin) && \ + (o2::aod::femtobase::stored::eta < (selection).etaMax) && \ + (o2::aod::femtobase::stored::phi > (selection).phiMin) && \ + (o2::aod::femtobase::stored::phi < (selection).phiMax) && \ + (o2::aod::femtobase::stored::mass > (selection).massMin) && \ + (o2::aod::femtobase::stored::mass < (selection).massMax) && \ + ncheckbit(o2::aod::femtov0s::mask, (selection).mask) // partition for k0shorts // need special partition since k0shorts have no antiparticle -#define MAKE_K0SHORT_PARTITION(selection) \ - (o2::aod::femtobase::stored::pt > selection.ptMin) && \ - (o2::aod::femtobase::stored::pt < selection.ptMax) && \ - (o2::aod::femtobase::stored::eta > selection.etaMin) && \ - (o2::aod::femtobase::stored::eta < selection.etaMax) && \ - (o2::aod::femtobase::stored::phi > selection.phiMin) && \ - (o2::aod::femtobase::stored::phi < selection.phiMax) && \ - (o2::aod::femtobase::stored::mass > selection.massMin) && \ - (o2::aod::femtobase::stored::mass < selection.massMax) && \ - ncheckbit(o2::aod::femtov0s::mask, selection.mask) - -#define MAKE_CASCADE_PARTITION(selection) \ - ifnode(selection.sign.node() != 0, \ - ifnode(selection.sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ - (nabs(o2::aod::femtobase::stored::signedPt) > selection.ptMin) && \ - (nabs(o2::aod::femtobase::stored::signedPt) < selection.ptMax) && \ - (o2::aod::femtobase::stored::eta > selection.etaMin) && \ - (o2::aod::femtobase::stored::eta < selection.etaMax) && \ - (o2::aod::femtobase::stored::phi > selection.phiMin) && \ - (o2::aod::femtobase::stored::phi < selection.phiMax) && \ - (o2::aod::femtobase::stored::mass > selection.massMin) && \ - (o2::aod::femtobase::stored::mass < selection.massMax) && \ - ncheckbit(o2::aod::femtocascades::mask, selection.mask) - -#define MAKE_SIGMA_PARTITION(selection) \ - ifnode(selection.sign.node() != 0, \ - ifnode(selection.sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ - (nabs(o2::aod::femtobase::stored::signedPt) > selection.ptMin) && \ - (nabs(o2::aod::femtobase::stored::signedPt) < selection.ptMax) && \ - (o2::aod::femtobase::stored::eta > selection.etaMin) && \ - (o2::aod::femtobase::stored::eta < selection.etaMax) && \ - (o2::aod::femtobase::stored::phi > selection.phiMin) && \ - (o2::aod::femtobase::stored::phi < selection.phiMax) && \ - (o2::aod::femtobase::stored::mass > selection.massMin) && \ - (o2::aod::femtobase::stored::mass < selection.massMax) && \ - ncheckbit(o2::aod::femtokinks::mask, selection.mask) - -#define MAKE_SIGMAPLUS_PARTITION(selection) \ - ifnode(selection.sign.node() != 0, \ - ifnode(selection.sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ - (nabs(o2::aod::femtobase::stored::signedPt) > selection.ptMin) && \ - (nabs(o2::aod::femtobase::stored::signedPt) < selection.ptMax) && \ - (o2::aod::femtobase::stored::eta > selection.etaMin) && \ - (o2::aod::femtobase::stored::eta < selection.etaMax) && \ - (o2::aod::femtobase::stored::phi > selection.phiMin) && \ - (o2::aod::femtobase::stored::phi < selection.phiMax) && \ - (o2::aod::femtobase::stored::mass > selection.massMin) && \ - (o2::aod::femtobase::stored::mass < selection.massMax) && \ - ncheckbit(o2::aod::femtokinks::mask, selection.mask) +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define MAKE_K0SHORT_PARTITION(selection) \ + (o2::aod::femtobase::stored::pt > (selection).ptMin) && \ + (o2::aod::femtobase::stored::pt < (selection).ptMax) && \ + (o2::aod::femtobase::stored::eta > (selection).etaMin) && \ + (o2::aod::femtobase::stored::eta < (selection).etaMax) && \ + (o2::aod::femtobase::stored::phi > (selection).phiMin) && \ + (o2::aod::femtobase::stored::phi < (selection).phiMax) && \ + (o2::aod::femtobase::stored::mass > (selection).massMin) && \ + (o2::aod::femtobase::stored::mass < (selection).massMax) && \ + ncheckbit(o2::aod::femtov0s::mask, (selection).mask) + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define MAKE_CASCADE_PARTITION(selection) \ + ifnode((selection).sign.node() != 0, \ + ifnode((selection).sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs(o2::aod::femtobase::stored::signedPt) > (selection).ptMin) && \ + (nabs(o2::aod::femtobase::stored::signedPt) < (selection).ptMax) && \ + (o2::aod::femtobase::stored::eta > (selection).etaMin) && \ + (o2::aod::femtobase::stored::eta < (selection).etaMax) && \ + (o2::aod::femtobase::stored::phi > (selection).phiMin) && \ + (o2::aod::femtobase::stored::phi < (selection).phiMax) && \ + (o2::aod::femtobase::stored::mass > (selection).massMin) && \ + (o2::aod::femtobase::stored::mass < (selection).massMax) && \ + ncheckbit(o2::aod::femtocascades::mask, (selection).mask) + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define MAKE_SIGMA_PARTITION(selection) \ + ifnode((selection).sign.node() != 0, \ + ifnode((selection).sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs(o2::aod::femtobase::stored::signedPt) > (selection).ptMin) && \ + (nabs(o2::aod::femtobase::stored::signedPt) < (selection).ptMax) && \ + (o2::aod::femtobase::stored::eta > (selection).etaMin) && \ + (o2::aod::femtobase::stored::eta < (selection).etaMax) && \ + (o2::aod::femtobase::stored::phi > (selection).phiMin) && \ + (o2::aod::femtobase::stored::phi < (selection).phiMax) && \ + (o2::aod::femtobase::stored::mass > (selection).massMin) && \ + (o2::aod::femtobase::stored::mass < (selection).massMax) && \ + ncheckbit(o2::aod::femtokinks::mask, (selection).mask) + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define MAKE_SIGMAPLUS_PARTITION(selection) \ + ifnode((selection).sign.node() != 0, \ + ifnode((selection).sign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs(o2::aod::femtobase::stored::signedPt) > (selection).ptMin) && \ + (nabs(o2::aod::femtobase::stored::signedPt) < (selection).ptMax) && \ + (o2::aod::femtobase::stored::eta > (selection).etaMin) && \ + (o2::aod::femtobase::stored::eta < (selection).etaMax) && \ + (o2::aod::femtobase::stored::phi > (selection).phiMin) && \ + (o2::aod::femtobase::stored::phi < (selection).phiMax) && \ + (o2::aod::femtobase::stored::mass > (selection).massMin) && \ + (o2::aod::femtobase::stored::mass < (selection).massMax) && \ + ncheckbit(o2::aod::femtokinks::mask, (selection).mask) + +// macros for mc collisions (mc only) +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define MAKE_MC_COLLISION_FILTER(selection) \ + (o2::aod::femtocollisions::posZ >= (selection).vtxZMin && o2::aod::femtocollisions::posZ <= (selection).vtxZMax) && \ + (o2::aod::femtocollisions::mult >= (selection).multMin && o2::aod::femtocollisions::mult <= (selection).multMax) && \ + (o2::aod::femtocollisions::cent >= (selection).centMin && o2::aod::femtocollisions::cent <= (selection).centMax) + +// macros for mc particle (mc only) +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define MAKE_MC_PARTICLE_PARTITION(selection) \ + ifnode((selection).pdgCodeAbs.node() == 0, true, (selection).pdgCodeAbs == nabs(o2::aod::femtomcparticle::pdgCode)) && \ + ifnode((selection).chargeSign.node() != 0, ifnode((selection).chargeSign.node() > 0, o2::aod::femtobase::stored::signedPt > 0.f, o2::aod::femtobase::stored::signedPt < 0.f), true) && \ + (nabs(o2::aod::femtobase::stored::signedPt) > (selection).ptMin) && \ + (nabs(o2::aod::femtobase::stored::signedPt) < (selection).ptMax) && \ + (o2::aod::femtobase::stored::eta > (selection).etaMin) && \ + (o2::aod::femtobase::stored::eta < (selection).etaMax) && \ + (o2::aod::femtobase::stored::phi > (selection).phiMin) && \ + (o2::aod::femtobase::stored::phi < (selection).phiMax) #endif // PWGCF_FEMTO_CORE_PARTITIONS_H_ diff --git a/PWGCF/Femto/Core/selectionContainer.h b/PWGCF/Femto/Core/selectionContainer.h index fe5616f8302..4e9e1718e16 100644 --- a/PWGCF/Femto/Core/selectionContainer.h +++ b/PWGCF/Femto/Core/selectionContainer.h @@ -228,17 +228,17 @@ class SelectionContainer /// \brief Get comments attached to the selection thresholds. /// \return Vector of comment strings. - std::string getComment(int selectionIndex) const + [[nodiscard]] std::string getComment(int selectionIndex) const { if (mComments.empty()) { - return std::string(""); + return std::string{""}; } return mComments.at(selectionIndex); } /// \brief Get the name of this selection. /// \return Selection name string. - std::string const& getSelectionName() const { return mSelectionName; } + [[nodiscard]] std::string const& getSelectionName() const { return mSelectionName; } /// \brief Update threshold values by re-evaluating the internal TF1 functions at a given point. /// \param value Input value at which to evaluate the functions. @@ -354,10 +354,9 @@ class SelectionContainer { if (!mSkipMostPermissiveBit) { return mBitmask; - } else { - // remove the first (most permissive) bit since it corresponds to the minimal selection and is always true - return mBitmask >> 1; } + // remove the first (most permissive) bit since it corresponds to the minimal selection and is always true + return mBitmask >> 1; } /// \brief Manually set the internal bitmask. @@ -374,7 +373,7 @@ class SelectionContainer /// \brief Check whether the mandatory (minimal) cut condition is fulfilled. /// \return True if the minimal selection passes or if this container is not marked as a minimal cut. - bool passesAsMinimalCut() const + [[nodiscard]] bool passesAsMinimalCut() const { if (mIsMinimalCut) { // if any bit is set the loosest threshold passed; since thresholds are ordered, @@ -387,7 +386,7 @@ class SelectionContainer /// \brief Check whether any optional cut is fulfilled. /// \return True if at least one optional threshold is passed, false if this container is not marked as optional. - bool passesAsOptionalCut() const + [[nodiscard]] bool passesAsOptionalCut() const { if (mIsOptionalCut) { // if any bit is set the loosest threshold passed @@ -411,12 +410,12 @@ class SelectionContainer /// For function-based selections, mSelectionValues is always populated (initialised at the midpoint), /// so this check is safe for both static and function-based containers. /// \return True if no thresholds are configured. - bool isEmpty() const { return mSelectionValues.empty(); } + [[nodiscard]] bool isEmpty() const { return mSelectionValues.empty(); } /// \brief Get the number of bits this container contributes to the global bitmask. /// If the most permissive bit is skipped, the contribution is reduced by one. /// \return Number of bits to add to the global bitmask offset. - int getShift() const + [[nodiscard]] int getShift() const { if (mSelectionValues.empty()) { return 0; @@ -433,16 +432,16 @@ class SelectionContainer /// \brief Get the bit offset of this container within the global bitmask. /// \return Bit offset. - int getOffset() const { return mOffset; } + [[nodiscard]] int getOffset() const { return mOffset; } /// \brief Get the total number of configured selection thresholds. /// \return Number of thresholds. - std::size_t getNSelections() const { return mSelectionValues.size(); } + [[nodiscard]] std::size_t getNSelections() const { return mSelectionValues.size(); } /// \brief Build a histogram bin label string encoding the full configuration of a single threshold. /// \param selectionIndex Index of the threshold within this container. /// \return Encoded label string. - std::string getBinLabel(int selectionIndex) const + [[nodiscard]] std::string getBinLabel(int selectionIndex) const { std::ostringstream oss; std::string sectionDelimiter = ":::"; @@ -477,10 +476,10 @@ class SelectionContainer return oss.str(); } - std::string getValueAsString(int selectionIndex) const + [[nodiscard]] std::string getValueAsString(int selectionIndex) const { if (this->isEmpty()) { - return std::string("No value configured"); + return std::string{"No value configured"}; } if (!mSelectionFunctions.empty()) { return std::string(mSelectionFunctions.at(selectionIndex).GetExpFormula().Data()); @@ -497,7 +496,7 @@ class SelectionContainer /// Calling this for the skipped most-permissive threshold is a fatal error. /// \param selectionIndex Index of the threshold within this container. /// \return Global bit position. - int getBitPosition(int selectionIndex) const + [[nodiscard]] int getBitPosition(int selectionIndex) const { if (selectionIndex == 0 && mSkipMostPermissiveBit) { LOG(fatal) << "Trying to accessed the bit position of a skipped selection. Breaking..."; @@ -505,14 +504,13 @@ class SelectionContainer } if (mSkipMostPermissiveBit) { return mOffset + selectionIndex - 1; - } else { - return mOffset + selectionIndex; } + return mOffset + selectionIndex; } /// \brief Get the string representation of the configured limit type. /// \return Human-readable limit type name. - std::string getLimitTypeAsString() const { return limits::limitTypeAsStrings.at(mLimitType); } + [[nodiscard]] std::string getLimitTypeAsString() const { return limits::limitTypeAsStrings.at(mLimitType); } /// \brief Get the configured static threshold values. /// \return Const reference to the vector of threshold values. @@ -520,19 +518,19 @@ class SelectionContainer /// \brief Get the configured TF1 threshold functions. /// \return Const reference to the vector of TF1 functions. - std::vector const& getSelectionFunction() const { return mSelectionFunctions; } + [[nodiscard]] std::vector const& getSelectionFunction() const { return mSelectionFunctions; } /// \brief Check whether this container is marked as a mandatory (minimal) cut. /// \return True if this is a minimal cut. - bool isMinimalCut() const { return mIsMinimalCut; } + [[nodiscard]] bool isMinimalCut() const { return mIsMinimalCut; } /// \brief Check whether this container is marked as an optional cut. /// \return True if this is an optional cut. - bool isOptionalCut() const { return mIsOptionalCut; } + [[nodiscard]] bool isOptionalCut() const { return mIsOptionalCut; } /// \brief Check whether the most permissive threshold bit is skipped when assembling the bitmask. /// \return True if the most permissive bit is skipped. - bool skipMostPermissiveBit() const { return mSkipMostPermissiveBit; } + [[nodiscard]] [[nodiscard]] bool skipMostPermissiveBit() const { return mSkipMostPermissiveBit; } private: /// \brief Sort static threshold values from most permissive to most restrictive based on the limit type. @@ -600,15 +598,15 @@ class SelectionContainer } } - std::string mSelectionName = ""; + std::string mSelectionName; std::vector mSelectionValues = {}; ///< Threshold values, sorted from most permissive to most restrictive - std::vector mSelectionFunctions = {}; ///< TF1 threshold functions (empty for static selections) + std::vector mSelectionFunctions; ///< TF1 threshold functions (empty for static selections) std::vector> mSelectionRanges = {}; ///< Lower and upper bounds for kRange selections, one pair per threshold limits::LimitType mLimitType = limits::kLimitTypeLast; ///< Comparison type applied during evaluation bool mSkipMostPermissiveBit = false; ///< If true, the most permissive threshold does not occupy a bit in the global bitmask bool mIsMinimalCut = false; ///< If true, this selection is mandatory; failing it rejects the candidate bool mIsOptionalCut = false; ///< If true, this selection is optional; passing it accepts the candidate - std::vector mComments = {}; ///< Optional comments per threshold, in the same order as mSelectionValues + std::vector mComments; ///< Optional comments per threshold, in the same order as mSelectionValues std::bitset mBitmask = {}; ///< Bitmask indicating which thresholds were passed during the last evaluation int mOffset = 0; ///< Bit offset of this container within the global bitmask }; diff --git a/PWGCF/Femto/Core/trackBuilder.h b/PWGCF/Femto/Core/trackBuilder.h index 4cfbf44664f..7a8d4147a93 100644 --- a/PWGCF/Femto/Core/trackBuilder.h +++ b/PWGCF/Femto/Core/trackBuilder.h @@ -35,11 +35,8 @@ #include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::trackbuilder { -namespace trackbuilder -{ - struct ConfTrackFilters : o2::framework::ConfigurableGroup { std::string prefix = std::string("TrackFilters"); // kinematic cuts for filtering tracks @@ -130,7 +127,7 @@ struct ConfTrackBits : o2::framework::ConfigurableGroup { }; // define the template structure for TrackSelection -template +template struct ConfTrackSelection : public o2::framework::ConfigurableGroup { std::string prefix = Prefix; // Unique prefix based on the template argument // configuration parameters @@ -145,13 +142,13 @@ struct ConfTrackSelection : public o2::framework::ConfigurableGroup { o2::framework::Configurable phiMin{"phiMin", 0.f, "Minimum phi"}; o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; o2::framework::Configurable massMin{"massMin", 0.f, "Minimum TOF mass (only used if enabled)"}; - o2::framework::Configurable massMax{"massMax", 2.f, "Maximum TOF mass (only used if enabled)"}; + o2::framework::Configurable massMax{"massMax", 99.f, "Maximum TOF mass (only used if enabled)"}; // track selection masks - o2::framework::Configurable maskLowMomentum{"maskLowMomentum", 1ul, "Bitmask for selections below momentum threshold"}; - o2::framework::Configurable maskHighMomentum{"maskHighMomentum", 2ul, "Bitmask for selections above momentum threshold"}; + o2::framework::Configurable maskLowMomentum{"maskLowMomentum", 1ul, "Bitmask for selections below momentum threshold"}; + o2::framework::Configurable maskHighMomentum{"maskHighMomentum", 2ul, "Bitmask for selections above momentum threshold"}; // track rejection masks - o2::framework::Configurable rejectionMaskLowMomentum{"rejectionMaskLowMomentum", 0ul, "Bitmask for rejections below momentum threshold"}; - o2::framework::Configurable rejectionMaskHighMomentum{"rejectionMaskHighMomentum", 0ul, "Bitmask for rejections above momentum threshold"}; + o2::framework::Configurable rejectionMaskLowMomentum{"rejectionMaskLowMomentum", 0ul, "Bitmask for rejections below momentum threshold"}; + o2::framework::Configurable rejectionMaskHighMomentum{"rejectionMaskHighMomentum", 0ul, "Bitmask for rejections above momentum threshold"}; // momentum threshold for PID usage o2::framework::Configurable pidThres{"pidThres", 1.2f, "Momentum threshold for using TPCTOF/TOF pid for tracks with large momentum (GeV/c)"}; }; @@ -241,7 +238,7 @@ const std::unordered_map trackSelectionNames = { {kTPCcRowsMin, "Min. number of crossed TPC rows"}, {kTPCnClsOvercRowsMin, "Min. fraction of TPC clusters over TPC crossed rows"}, {kTPCsClsMax, "Max. number of shared TPC clusters"}, - {kTPCsClsMax, "Max. number of shared TPC clusters"}, + // NOTE: removed duplicate {kTPCsClsMax, ...} entry that was here (harmless but dead duplicate key). {kTPCsClsFracMax, "Max. fractions of shared TPC clusters"}, {kITSnClsMin, "Min. number of ITS clusters"}, {kITSnClsIbMin, "Min. number of ITS clusters in the inner barrel"}, @@ -290,12 +287,12 @@ const std::unordered_map trackSelectionNames = { /// \class FemtoDreamTrackCuts /// \brief Cut class to contain and execute all cuts applied to tracks -template -class TrackSelection : public BaseSelection +template +class TrackSelection : public BaseSelection { public: TrackSelection() = default; - ~TrackSelection() = default; + ~TrackSelection() override = default; template void configure(o2::framework::HistogramRegistry* registry, T1& config, T2& filter) @@ -312,9 +309,9 @@ class TrackSelection : public BaseSelectionaddSelection(kTPCnClsMin, trackSelectionNames.at(kTPCnClsMin), config.tpcClustersMin.value, limits::kLowerLimit, skipMostPermissiveBit, isMinimalCut, false); @@ -474,11 +471,7 @@ class TrackSelection : public BaseSelectionassembleBitmask(); } - bool - passThroughAllTracks() const - { - return mPassThrough; - } + [[nodiscard]] bool passThroughAllTracks() const { return mPassThrough; } protected: float mElectronTofThres = 99.f; @@ -530,7 +523,7 @@ struct ConfTrackTables : o2::framework::ConfigurableGroup { o2::framework::Configurable produceHeliumPids{"produceHeliumPids", -1, "Produce HeliumPids (-1: auto; 0 off; 1 on)"}; }; -template +template class TrackBuilder { public: @@ -588,20 +581,23 @@ class TrackBuilder } template - void fillTrack(T1 const& track, T2& trackProducts, T3& collisionProducts) + bool fillTrack(T1 const& track, T2& trackProducts, T3& collisionProducts) { - if (mProduceTracks) { - trackProducts.producedTracks(collisionProducts.producedCollision.lastIndex(), - track.pt() * track.sign(), - track.eta(), - track.phi()); - indexMap.emplace(track.globalIndex(), trackProducts.producedTracks.lastIndex()); + if (!mProduceTracks) { + return false; } + + trackProducts.producedTracks(collisionProducts.producedCollision.lastIndex(), + track.pt() * track.sign(), + track.eta(), + track.phi()); + indexMap.emplace(track.globalIndex(), trackProducts.producedTracks.lastIndex()); + if (mProduceTrackMasks) { if constexpr (type == modes::Track::kTrack) { trackProducts.producedTrackMasks(mTrackSelection.getBitmask()); } else { - trackProducts.producedTrackMasks(static_cast(0u)); + trackProducts.producedTrackMasks(static_cast(0u)); } } if (mProduceTrackMass) { @@ -672,6 +668,7 @@ class TrackBuilder } trackProducts.producedHeliumPids(itsHe, track.tpcNSigmaHe(), track.tofNSigmaHe()); } + return true; } template @@ -681,6 +678,7 @@ class TrackBuilder return; } for (const auto& trackWithItsPid : tracksWithItsPid) { + // NOTE: passThrough is intentionally not wired in here yet for the MC path (to be added later). if (!mTrackSelection.checkFilters(trackWithItsPid)) { continue; } @@ -696,13 +694,16 @@ class TrackBuilder } template - void fillMcTrack(T1 const& col, T2& collisionProducts, T3 const& mcCols, T4 const& track, T5 const& trackWithItsPid, T6& trackProducts, T7 const& mcParticles, T8& mcBuilder, T9& mcProducts) + bool fillMcTrack(T1 const& col, T2& collisionProducts, T3 const& mcCols, T4 const& track, T5 const& trackWithItsPid, T6& trackProducts, T7 const& mcParticles, T8& mcBuilder, T9& mcProducts) { + // NOTE: return value added, mirroring fillTrack(), so getDaughterIndex can detect + // whether a row was actually added before trusting lastIndex(). if (!mProduceTracks) { - return; + return false; } this->template fillTrack(trackWithItsPid, trackProducts, collisionProducts); mcBuilder.template fillMcTrackWithLabel(col, mcCols, track, mcParticles, mcProducts); + return true; } template @@ -711,11 +712,13 @@ class TrackBuilder auto result = utils::getIndex(daughter.globalIndex(), indexMap); if (result) { return result.value(); - } else { - this->fillTrack(daughter, trackProducts, collisionProducts); - int64_t idx = trackProducts.producedTracks.lastIndex(); - return idx; } + if (!this->template fillTrack(daughter, trackProducts, collisionProducts)) { + LOG(fatal) << "Trying to register a daughter track, but FTracks table is disabled. " + << "Enable TrackTables.produceTracks when V0/Cascade/Kink tables that need daughter indices are enabled."; + } + // daughter is last track which was added added + return trackProducts.producedTracks.lastIndex(); } template @@ -725,11 +728,13 @@ class TrackBuilder if (result) { // daugher already in track table return result.value(); - } else { - this->fillMcTrack(col, collisionProducts, mcCols, daughter, daughter, trackProducts, mcParticles, mcBuilder, mcProducts); - // daughter is last track which was added added - return trackProducts.producedTracks.lastIndex(); } + if (!this->template fillMcTrack(col, collisionProducts, mcCols, daughter, daughter, trackProducts, mcParticles, mcBuilder, mcProducts)) { + LOG(fatal) << "Trying to register a MC daughter track, but FTracks table is disabled. " + << "Enable TrackTables.produceTracks when V0/Cascade/Kink tables that need daughter indices are enabled."; + } + // daughter is last track which was added added + return trackProducts.producedTracks.lastIndex(); } template @@ -833,11 +838,10 @@ class TrackBuilderDerivedToDerived auto result = utils::getIndex(daughter.globalIndex(), indexMap); if (result) { return result.value(); - } else { - this->fillTrack(daughter, trackProducts, collisionProducts); - int64_t idx = trackProducts.producedTracks.lastIndex(); - return idx; } + this->fillTrack(daughter, trackProducts, collisionProducts); + int64_t idx = trackProducts.producedTracks.lastIndex(); + return idx; } private: @@ -846,9 +850,6 @@ class TrackBuilderDerivedToDerived std::unordered_map indexMap; // for mapping tracks to daughers of lambdas, cascades and resonances ... }; - -} // namespace trackbuilder -// -} // namespace o2::analysis::femto +} // namespace o2::analysis::femto::trackbuilder #endif // PWGCF_FEMTO_CORE_TRACKBUILDER_H_ diff --git a/PWGCF/Femto/Core/trackHistManager.h b/PWGCF/Femto/Core/trackHistManager.h index c01704a4f4b..af36c02acf6 100644 --- a/PWGCF/Femto/Core/trackHistManager.h +++ b/PWGCF/Femto/Core/trackHistManager.h @@ -35,11 +35,8 @@ #include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::trackhistmanager { -namespace trackhistmanager -{ - // enum for track histograms enum TrackHist { // kinemtics @@ -143,7 +140,7 @@ enum TrackHist { constexpr std::size_t MaxSecondary = 3; -template +template struct ConfTrackBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; o2::framework::ConfigurableAxis pt{"pt", {{600, 0, 6}}, "Pt"}; @@ -187,7 +184,7 @@ using ConfPionMinusBinning = ConfTrackBinning; using ConfKaonPlusBinning = ConfTrackBinning; using ConfKaonMinusBinning = ConfTrackBinning; -template +template struct ConfTrackQaBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; o2::framework::Configurable momentumType{"momentumType", static_cast(modes::MomentumType::kPAtPv), "Momentum on x-axis (0->Pt, 1->P at PV, 2->P at TPC inner wall)"}; @@ -354,7 +351,7 @@ constexpr std::array, kTrackHistLast> {kPdg, o2::framework::HistType::kTH1F, "hPdg", "PDG Codes of selected tracks; PDG Code; Entries"}, {kPdgMother, o2::framework::HistType::kTH1F, "hPdgMother", "PDG Codes of mother of selected tracks; PDG Code; Entries"}, {kPdgPartonicMother, o2::framework::HistType::kTH1F, "hPdgPartonicMother", "PDG Codes of partonic mother selected tracks; PDG Code; Entries"}, - {kTruePtVsPt, o2::framework::HistType::kTH2F, "hTruePtVsPt", "True transverse momentum vs transverse momentum; p_{T,True} (GeV/#it{c}); p_{T,True} (GeV/#it{c})"}, + {kTruePtVsPt, o2::framework::HistType::kTH2F, "hTruePtVsPt", "True transverse momentum vs transverse momentum; p_{T,True} (GeV/#it{c}); p_{T} (GeV/#it{c})"}, {kTrueEtaVsEta, o2::framework::HistType::kTH2F, "hTrueEtaVsEta", "True pseudorapdity vs pseudorapdity; #eta_{True}; #eta"}, {kTruePhiVsPhi, o2::framework::HistType::kTH2F, "hTruePhiVsPhi", "True azimuthal angle vs azimuthal angle; #varphi_{True}; #varphi"}, {kNoMcParticle, o2::framework::HistType::kTHnSparseF, "hNoMcParticle", "Wrongly reconstructed particles; p_{T} (GeV/#it{c}); DCA_{xy} (cm); DCA_{z} (cm);"}, @@ -368,97 +365,101 @@ constexpr std::array, kTrackHistLast> {kSecondaryOther, o2::framework::HistType::kTHnSparseF, "hFromSecondaryOther", "Particles from every other seconary decay; p_{T} (GeV/#it{c}); DCA_{xy} (cm); DCA_{z} (cm);"}, }}; +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define TRACK_HIST_ANALYSIS_MAP(conf) \ - {kPt, {conf.pt}}, \ - {kEta, {conf.eta}}, \ - {kPhi, {conf.phi}}, \ - {kSign, {conf.sign}}, \ - {kMass, {conf.mass}}, - -#define TRACK_HIST_QA_MAP(confAnalysis, confQa) \ - {kPAtPv, {confQa.p}}, \ - {kPTpc, {confQa.p}}, \ - {kItsCluster, {confQa.itsCluster}}, \ - {kItsClusterIb, {confQa.itsClusterIb}}, \ - {kPtVsEta, {confAnalysis.pt, confAnalysis.eta}}, \ - {kPtVsPhi, {confAnalysis.pt, confAnalysis.phi}}, \ - {kPhiVsEta, {confAnalysis.phi, confAnalysis.eta}}, \ - {kPtVsItsCluster, {confAnalysis.pt, confQa.itsCluster}}, \ - {kPtVsTpcCluster, {confAnalysis.pt, confQa.tpcCluster}}, \ - {kPtVsTpcCrossedRows, {confAnalysis.pt, confQa.tpcCrossedRows}}, \ - {kPtVsTpcClusterOverCrossedRows, {confAnalysis.pt, confQa.tpcClusterOverCrossedRows}}, \ - {kPtVsTpcClusterShared, {confAnalysis.pt, confQa.tpcClusterShared}}, \ - {kPtVsTpcClusterFractionShared, {confAnalysis.pt, confQa.tpcClusterFractionShared}}, \ - {kTpcClusterVsTpcCrossedRows, {confQa.tpcCluster, confQa.tpcCrossedRows}}, \ - {kTpcClusterVsTpcClusterShared, {confQa.tpcCluster, confQa.tpcClusterShared}}, \ - {kTpcCrossedRows, {confQa.tpcCrossedRows}}, \ - {kTpcCluster, {confQa.tpcCluster}}, \ - {kTpcClusterOverCrossedRows, {confQa.tpcClusterOverCrossedRows}}, \ - {kTpcClusterShared, {confQa.tpcClusterShared}}, \ - {kTpcClusterFractionShared, {confQa.tpcClusterFractionShared}}, \ - {kPtVsDcaxy, {confAnalysis.pt, confQa.dcaXy}}, \ - {kPtVsDcaz, {confAnalysis.pt, confQa.dcaZ}}, \ - {kPtVsDca, {confAnalysis.pt, confQa.dca}}, \ - {kPtVsDcaxyVsDcaz, {confAnalysis.pt, confQa.dcaXy, confQa.dcaZ}}, \ - {kPVsPTpc, {confQa.p, confQa.p}}, \ - {kItsSignal, {confQa.p, confQa.itsSignal}}, \ - {kItsElectron, {confQa.p, confQa.itsElectron}}, \ - {kItsPion, {confQa.p, confQa.itsPion}}, \ - {kItsKaon, {confQa.p, confQa.itsKaon}}, \ - {kItsProton, {confQa.p, confQa.itsProton}}, \ - {kItsDeuteron, {confQa.p, confQa.itsDeuteron}}, \ - {kItsTriton, {confQa.p, confQa.itsTriton}}, \ - {kItsHelium, {confQa.p, confQa.itsHelium}}, \ - {kTpcSignal, {confQa.p, confQa.tpcSignal}}, \ - {kTpcElectron, {confQa.p, confQa.tpcElectron}}, \ - {kTpcPion, {confQa.p, confQa.tpcPion}}, \ - {kTpcKaon, {confQa.p, confQa.tpcKaon}}, \ - {kTpcProton, {confQa.p, confQa.tpcProton}}, \ - {kTpcDeuteron, {confQa.p, confQa.tpcDeuteron}}, \ - {kTpcTriton, {confQa.p, confQa.tpcTriton}}, \ - {kTpcHelium, {confQa.p, confQa.tpcHelium}}, \ - {kTofBeta, {confQa.p, confQa.tofBeta}}, \ - {kTofMass, {confQa.p, confQa.tofMass}}, \ - {kTofElectron, {confQa.p, confQa.tofElectron}}, \ - {kTofPion, {confQa.p, confQa.tofPion}}, \ - {kTofKaon, {confQa.p, confQa.tofKaon}}, \ - {kTofProton, {confQa.p, confQa.tofProton}}, \ - {kTofDeuteron, {confQa.p, confQa.tofDeuteron}}, \ - {kTofTriton, {confQa.p, confQa.tofTriton}}, \ - {kTofHelium, {confQa.p, confQa.tofHelium}}, \ - {kTpcitsElectron, {confQa.p, confQa.tpcitsElectron}}, \ - {kTpcitsPion, {confQa.p, confQa.tpcitsPion}}, \ - {kTpcitsKaon, {confQa.p, confQa.tpcitsKaon}}, \ - {kTpcitsProton, {confQa.p, confQa.tpcitsProton}}, \ - {kTpcitsDeuteron, {confQa.p, confQa.tpcitsDeuteron}}, \ - {kTpcitsTriton, {confQa.p, confQa.tpcitsTriton}}, \ - {kTpcitsHelium, {confQa.p, confQa.tpcitsHelium}}, \ - {kTpctofElectron, {confQa.p, confQa.tpctofElectron}}, \ - {kTpctofPion, {confQa.p, confQa.tpctofPion}}, \ - {kTpctofKaon, {confQa.p, confQa.tpctofKaon}}, \ - {kTpctofProton, {confQa.p, confQa.tpctofProton}}, \ - {kTpctofDeuteron, {confQa.p, confQa.tpctofDeuteron}}, \ - {kTpctofTriton, {confQa.p, confQa.tpctofTriton}}, \ - {kTpctofHelium, {confQa.p, confQa.tpctofHelium}}, - -#define TRACK_HIST_MC_MAP(conf) \ - {kTruePtVsPt, {conf.pt, conf.pt}}, \ - {kTrueEtaVsEta, {conf.eta, conf.eta}}, \ - {kTruePhiVsPhi, {conf.phi, conf.phi}}, \ - {kPdg, {conf.pdgCodes}}, \ - {kPdgMother, {conf.pdgCodes}}, \ - {kPdgPartonicMother, {conf.pdgCodes}}, - -#define TRACK_HIST_MC_QA_MAP(confAnalysis, confQa) \ - {kNoMcParticle, {confAnalysis.pt, confQa.dcaXy, confQa.dcaZ}}, \ - {kPrimary, {confAnalysis.pt, confQa.dcaXy, confQa.dcaZ}}, \ - {kFromWrongCollision, {confAnalysis.pt, confQa.dcaXy, confQa.dcaZ}}, \ - {kFromMaterial, {confAnalysis.pt, confQa.dcaXy, confQa.dcaZ}}, \ - {kMissidentified, {confAnalysis.pt, confQa.dcaXy, confQa.dcaZ}}, \ - {kSecondary1, {confAnalysis.pt, confQa.dcaXy, confQa.dcaZ}}, \ - {kSecondary2, {confAnalysis.pt, confQa.dcaXy, confQa.dcaZ}}, \ - {kSecondary3, {confAnalysis.pt, confQa.dcaXy, confQa.dcaZ}}, \ - {kSecondaryOther, {confAnalysis.pt, confQa.dcaXy, confQa.dcaZ}}, + {kPt, {(conf).pt}}, \ + {kEta, {(conf).eta}}, \ + {kPhi, {(conf).phi}}, \ + {kSign, {(conf).sign}}, \ + {kMass, {(conf).mass}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define TRACK_HIST_QA_MAP(confAnalysis, confQa) \ + {kPAtPv, {(confQa).p}}, \ + {kPTpc, {(confQa).p}}, \ + {kItsCluster, {(confQa).itsCluster}}, \ + {kItsClusterIb, {(confQa).itsClusterIb}}, \ + {kPtVsEta, {(confAnalysis).pt, (confAnalysis).eta}}, \ + {kPtVsPhi, {(confAnalysis).pt, (confAnalysis).phi}}, \ + {kPhiVsEta, {(confAnalysis).phi, (confAnalysis).eta}}, \ + {kPtVsItsCluster, {(confAnalysis).pt, (confQa).itsCluster}}, \ + {kPtVsTpcCluster, {(confAnalysis).pt, (confQa).tpcCluster}}, \ + {kPtVsTpcCrossedRows, {(confAnalysis).pt, (confQa).tpcCrossedRows}}, \ + {kPtVsTpcClusterOverCrossedRows, {(confAnalysis).pt, (confQa).tpcClusterOverCrossedRows}}, \ + {kPtVsTpcClusterShared, {(confAnalysis).pt, (confQa).tpcClusterShared}}, \ + {kPtVsTpcClusterFractionShared, {(confAnalysis).pt, (confQa).tpcClusterFractionShared}}, \ + {kTpcClusterVsTpcCrossedRows, {(confQa).tpcCluster, (confQa).tpcCrossedRows}}, \ + {kTpcClusterVsTpcClusterShared, {(confQa).tpcCluster, (confQa).tpcClusterShared}}, \ + {kTpcCrossedRows, {(confQa).tpcCrossedRows}}, \ + {kTpcCluster, {(confQa).tpcCluster}}, \ + {kTpcClusterOverCrossedRows, {(confQa).tpcClusterOverCrossedRows}}, \ + {kTpcClusterShared, {(confQa).tpcClusterShared}}, \ + {kTpcClusterFractionShared, {(confQa).tpcClusterFractionShared}}, \ + {kPtVsDcaxy, {(confAnalysis).pt, (confQa).dcaXy}}, \ + {kPtVsDcaz, {(confAnalysis).pt, (confQa).dcaZ}}, \ + {kPtVsDca, {(confAnalysis).pt, (confQa).dca}}, \ + {kPtVsDcaxyVsDcaz, {(confAnalysis).pt, (confQa).dcaXy, (confQa).dcaZ}}, \ + {kPVsPTpc, {(confQa).p, (confQa).p}}, \ + {kItsSignal, {(confQa).p, (confQa).itsSignal}}, \ + {kItsElectron, {(confQa).p, (confQa).itsElectron}}, \ + {kItsPion, {(confQa).p, (confQa).itsPion}}, \ + {kItsKaon, {(confQa).p, (confQa).itsKaon}}, \ + {kItsProton, {(confQa).p, (confQa).itsProton}}, \ + {kItsDeuteron, {(confQa).p, (confQa).itsDeuteron}}, \ + {kItsTriton, {(confQa).p, (confQa).itsTriton}}, \ + {kItsHelium, {(confQa).p, (confQa).itsHelium}}, \ + {kTpcSignal, {(confQa).p, (confQa).tpcSignal}}, \ + {kTpcElectron, {(confQa).p, (confQa).tpcElectron}}, \ + {kTpcPion, {(confQa).p, (confQa).tpcPion}}, \ + {kTpcKaon, {(confQa).p, (confQa).tpcKaon}}, \ + {kTpcProton, {(confQa).p, (confQa).tpcProton}}, \ + {kTpcDeuteron, {(confQa).p, (confQa).tpcDeuteron}}, \ + {kTpcTriton, {(confQa).p, (confQa).tpcTriton}}, \ + {kTpcHelium, {(confQa).p, (confQa).tpcHelium}}, \ + {kTofBeta, {(confQa).p, (confQa).tofBeta}}, \ + {kTofMass, {(confQa).p, (confQa).tofMass}}, \ + {kTofElectron, {(confQa).p, (confQa).tofElectron}}, \ + {kTofPion, {(confQa).p, (confQa).tofPion}}, \ + {kTofKaon, {(confQa).p, (confQa).tofKaon}}, \ + {kTofProton, {(confQa).p, (confQa).tofProton}}, \ + {kTofDeuteron, {(confQa).p, (confQa).tofDeuteron}}, \ + {kTofTriton, {(confQa).p, (confQa).tofTriton}}, \ + {kTofHelium, {(confQa).p, (confQa).tofHelium}}, \ + {kTpcitsElectron, {(confQa).p, (confQa).tpcitsElectron}}, \ + {kTpcitsPion, {(confQa).p, (confQa).tpcitsPion}}, \ + {kTpcitsKaon, {(confQa).p, (confQa).tpcitsKaon}}, \ + {kTpcitsProton, {(confQa).p, (confQa).tpcitsProton}}, \ + {kTpcitsDeuteron, {(confQa).p, (confQa).tpcitsDeuteron}}, \ + {kTpcitsTriton, {(confQa).p, (confQa).tpcitsTriton}}, \ + {kTpcitsHelium, {(confQa).p, (confQa).tpcitsHelium}}, \ + {kTpctofElectron, {(confQa).p, (confQa).tpctofElectron}}, \ + {kTpctofPion, {(confQa).p, (confQa).tpctofPion}}, \ + {kTpctofKaon, {(confQa).p, (confQa).tpctofKaon}}, \ + {kTpctofProton, {(confQa).p, (confQa).tpctofProton}}, \ + {kTpctofDeuteron, {(confQa).p, (confQa).tpctofDeuteron}}, \ + {kTpctofTriton, {(confQa).p, (confQa).tpctofTriton}}, \ + {kTpctofHelium, {(confQa).p, (confQa).tpctofHelium}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define TRACK_HIST_MC_MAP(conf) \ + {kTruePtVsPt, {(conf).pt, (conf).pt}}, \ + {kTrueEtaVsEta, {(conf).eta, (conf).eta}}, \ + {kTruePhiVsPhi, {(conf).phi, (conf).phi}}, \ + {kPdg, {(conf).pdgCodes}}, \ + {kPdgMother, {(conf).pdgCodes}}, \ + {kPdgPartonicMother, {(conf).pdgCodes}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define TRACK_HIST_MC_QA_MAP(confAnalysis, confQa) \ + {kNoMcParticle, {(confAnalysis).pt, (confQa).dcaXy, (confQa).dcaZ}}, \ + {kPrimary, {(confAnalysis).pt, (confQa).dcaXy, (confQa).dcaZ}}, \ + {kFromWrongCollision, {(confAnalysis).pt, (confQa).dcaXy, (confQa).dcaZ}}, \ + {kFromMaterial, {(confAnalysis).pt, (confQa).dcaXy, (confQa).dcaZ}}, \ + {kMissidentified, {(confAnalysis).pt, (confQa).dcaXy, (confQa).dcaZ}}, \ + {kSecondary1, {(confAnalysis).pt, (confQa).dcaXy, (confQa).dcaZ}}, \ + {kSecondary2, {(confAnalysis).pt, (confQa).dcaXy, (confQa).dcaZ}}, \ + {kSecondary3, {(confAnalysis).pt, (confQa).dcaXy, (confQa).dcaZ}}, \ + {kSecondaryOther, {(confAnalysis).pt, (confQa).dcaXy, (confQa).dcaZ}}, template auto makeTrackHistSpecMap(const T& confBinningAnalysis) @@ -530,7 +531,7 @@ constexpr std::string_view QaDir = "QA/"; constexpr std::string_view PidDir = "PID/"; constexpr std::string_view McDir = "MC/"; -template +template class TrackHistManager { public: @@ -546,7 +547,7 @@ class TrackHistManager mHistogramRegistry = registry; mAbsCharge = std::abs(ConfTrackSelection.chargeAbs.value); mPdgCode = std::abs(ConfTrackSelection.pdgCodeAbs.value) * ConfTrackSelection.chargeSign.value; - if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco)) { this->initAnalysis(Specs); } if constexpr (isFlagSet(mode, modes::Mode::kQa)) { @@ -567,7 +568,7 @@ class TrackHistManager mHistogramRegistry = registry; mAbsCharge = std::abs(ChargeAbs); mPdgCode = std::abs(PdgCodeAbs) * ChargeSign; - if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco)) { this->initAnalysis(Specs); } if constexpr (isFlagSet(mode, modes::Mode::kQa)) { @@ -604,7 +605,7 @@ class TrackHistManager template void fill(T1 const& track, T2 const& /*trackTable*/) { - if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco)) { this->fillAnalysis(track); } if constexpr (isFlagSet(mode, modes::Mode::kQa)) { @@ -615,7 +616,7 @@ class TrackHistManager template void fill(T1 const& track, T2 const& /*trackTable*/, T3 const& mcParticles, T4 const& mcMothers, T5 const& mcPartonicMothers) { - if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco)) { this->fillAnalysis(track); } if constexpr (isFlagSet(mode, modes::Mode::kQa)) { @@ -963,16 +964,16 @@ class TrackHistManager mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kPdg, HistTable)), mcParticle.pdgCode()); // get mother - if (track.has_fMcMother()) { - auto mother = track.template fMcMother_as(); + if (mcParticle.has_fMcMother()) { + auto mother = mcParticle.template fMcMother_as(); mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kPdgMother, HistTable)), mother.pdgCode()); } else { mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kPdgMother, HistTable)), 0); } // get partonic mother - if (track.has_fMcPartMoth()) { - auto partonicMother = track.template fMcPartMoth_as(); + if (mcParticle.has_fMcPartMoth()) { + auto partonicMother = mcParticle.template fMcPartMoth_as(); mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kPdgPartonicMother, HistTable)), partonicMother.pdgCode()); } else { mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kPdgPartonicMother, HistTable)), 0); @@ -997,8 +998,8 @@ class TrackHistManager mHistogramRegistry->fill(HIST(prefix) + HIST(McDir) + HIST(getHistName(kFromMaterial, HistTable)), track.pt(), track.dcaXY(), track.dcaZ()); break; case modes::McOrigin::kFromSecondaryDecay: - if (track.has_fMcMother()) { - auto mother = track.template fMcMother_as(); + if (mcParticle.has_fMcMother()) { + auto mother = mcParticle.template fMcMother_as(); int motherPdgCode = std::abs(mother.pdgCode()); // Switch on PDG of the mother if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel1 && motherPdgCode == mPdgCodesSecondaryMother[0]) { @@ -1038,7 +1039,5 @@ class TrackHistManager std::array mPdgCodesSecondaryMother = {0}; modes::MomentumType mMomentumType = modes::MomentumType::kPAtPv; }; -}; // namespace trackhistmanager -// aespace trackhistmanager -}; // namespace o2::analysis::femto +} // namespace o2::analysis::femto::trackhistmanager #endif // PWGCF_FEMTO_CORE_TRACKHISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/tripletBuilder.h b/PWGCF/Femto/Core/tripletBuilder.h index 332535629e4..0184d442ea7 100644 --- a/PWGCF/Femto/Core/tripletBuilder.h +++ b/PWGCF/Femto/Core/tripletBuilder.h @@ -39,33 +39,31 @@ #include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::tripletbuilder { -namespace tripletbuilder -{ - const int64_t nLimitPartitionIdenticalParticles123 = 3; const int64_t nLimitPartitionIdenticalParticles12 = 2; const int64_t nLimitPartitionParticles = 1; -template +template class TripletTrackTrackTrackBuilder { public: TripletTrackTrackTrackBuilder() = default; ~TripletTrackTrackTrackBuilder() = default; - template (registry, colHistSpec, confCollisionBinning); - mTripletHistManagerSe.template init(registry, pairHistSpec, confTripletBinning, confTripletCuts); - mTripletHistManagerMe.template init(registry, pairHistSpec, confTripletBinning, confTripletCuts); + mColHistManager.template init(registry, colHistSpec, confCollisionBinning); + mTripletHistManagerSe.template init(registry, pairHistSpec, confTripletBinning, confTripletCuts, confMixing); + mTripletHistManagerMe.template init(registry, pairHistSpec, confTripletBinning, confTripletCuts, confMixing); - mTc.template init(confTripletCuts); + mTc.template init(confTripletCuts); if (mTrack1Track2Track3AreSameSpecies) { // Track1 & Track2 & Track3 are the same particle species - mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); + mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection1.pdgCodeAbs.value, confTrackSelection1.pdgCodeAbs.value); mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value); @@ -123,8 +121,8 @@ class TripletTrackTrackTrackBuilder mCtrMe.init(registry, cprHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value); } else if (mTrack1Track2AreSameSpecies) { // Track1 & Track2 & are the same particle species and track 3 is something else - mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); - mTrackHistManager3.template init(registry, trackHistSpec3, confTrackSelection2); + mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); + mTrackHistManager3.template init(registry, trackHistSpec3, confTrackSelection3); mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection1.pdgCodeAbs.value, confTrackSelection3.pdgCodeAbs.value); mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value, confTrackSelection3.chargeAbs.value); @@ -135,9 +133,9 @@ class TripletTrackTrackTrackBuilder mCtrMe.init(registry, cprHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value, confTrackSelection3.chargeAbs.value); } else { // all three tracks are different - mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); - mTrackHistManager2.template init(registry, trackHistSpec2, confTrackSelection2); - mTrackHistManager3.template init(registry, trackHistSpec3, confTrackSelection3); + mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); + mTrackHistManager2.template init(registry, trackHistSpec2, confTrackSelection2); + mTrackHistManager3.template init(registry, trackHistSpec3, confTrackSelection3); mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection2.pdgCodeAbs.value, confTrackSelection3.pdgCodeAbs.value); mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value, confTrackSelection3.chargeAbs.value); @@ -268,7 +266,7 @@ class TripletTrackTrackTrackBuilder tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition1, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); break; default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; } } else if (mTrack1Track2AreSameSpecies) { switch (mMixingPolicy) { @@ -282,7 +280,7 @@ class TripletTrackTrackTrackBuilder tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); break; default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; } } else { switch (mMixingPolicy) { @@ -296,7 +294,7 @@ class TripletTrackTrackTrackBuilder tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); break; default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; } } } @@ -316,7 +314,7 @@ class TripletTrackTrackTrackBuilder tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition1, trackTable, mcParticles, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); break; default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; } } else if (mTrack1Track2AreSameSpecies) { switch (mMixingPolicy) { @@ -330,7 +328,7 @@ class TripletTrackTrackTrackBuilder tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); break; default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; } } else { switch (mMixingPolicy) { @@ -344,7 +342,7 @@ class TripletTrackTrackTrackBuilder tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); break; default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; } } } @@ -370,26 +368,27 @@ class TripletTrackTrackTrackBuilder }; template + auto& prefixTrack1, + auto& prefixTrack2, + auto& prefixV0, + auto& prefixPosDau, + auto& prefixNegDau, + auto& prefixSe, + auto& prefixMe, + auto& prefixCtrSeTrack1Track2, + auto& prefixCtrSeTrack1V0, + auto& prefixCtrSeTrack2V0, + auto& prefixCtrMeTrack1Track2, + auto& prefixCtrMeTrack1V0, + auto& prefixCtrMeTrack2V0> class TripletTrackTrackV0Builder { public: TripletTrackTrackV0Builder() = default; ~TripletTrackTrackV0Builder() = default; - template (registry, colHistSpec, confCollisionBinning); - mTripletHistManagerSe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts); - mTripletHistManagerMe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts); + mColHistManager.template init(registry, colHistSpec, confCollisionBinning); + mTripletHistManagerSe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts, confMixing); + mTripletHistManagerMe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts, confMixing); - mTc.template init(confTripletCuts); + mTc.template init(confTripletCuts); if (mTrack1Track2AreSameSpecies) { // Track1 & Track2 & are the same particle species and track 3 is something else - mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); - mV0HistManager.template init(registry, v0histSpec, confV0Selection, posDauhistSpec, negDauhistSpec); + mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); + mV0HistManager.template init(registry, v0histSpec, confV0Selection, posDauhistSpec, negDauhistSpec); mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection1.pdgCodeAbs.value, confV0Selection.pdgCodeAbs.value); mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value, 1); @@ -447,9 +446,9 @@ class TripletTrackTrackV0Builder mCtrMe.init(registry, ctrHistSpec, confCtr, confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value); } else { // all three tracks are different - mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); - mTrackHistManager2.template init(registry, trackHistSpec2, confTrackSelection2); - mV0HistManager.template init(registry, v0histSpec, confV0Selection, posDauhistSpec, negDauhistSpec); + mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); + mTrackHistManager2.template init(registry, trackHistSpec2, confTrackSelection2); + mV0HistManager.template init(registry, v0histSpec, confV0Selection, posDauhistSpec, negDauhistSpec); mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection2.pdgCodeAbs.value, confV0Selection.pdgCodeAbs.value); mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value, 1); @@ -553,7 +552,7 @@ class TripletTrackTrackV0Builder tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); break; default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; } } else { switch (mMixingPolicy) { @@ -567,7 +566,7 @@ class TripletTrackTrackV0Builder tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); break; default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; } } } @@ -587,7 +586,7 @@ class TripletTrackTrackV0Builder tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); break; default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; } } else { switch (mMixingPolicy) { @@ -601,7 +600,7 @@ class TripletTrackTrackV0Builder tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); break; default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; } } } @@ -626,31 +625,32 @@ class TripletTrackTrackV0Builder }; template + auto& prefixTrack1, + auto& prefixTrack2, + auto& prefixCascade, + auto& prefixBachelor, + auto& prefixPosDau, + auto& prefixNegDau, + auto& prefixSe, + auto& prefixMe, + auto& prefixCtrTrack1Track2Se, + auto& prefixCprBachelorTrack1Se, + auto& prefixCprBachelorTrack2Se, + auto& prefixCprV0DaughterTrack1Se, + auto& prefixCprV0DaughterTrack2Se, + auto& prefixCtrTrack1Track2Me, + auto& prefixCprBachelorTrack1Me, + auto& prefixCprBachelorTrack2Me, + auto& prefixCprV0DaughterTrack1Me, + auto& prefixCprV0DaughterTrack2Me> class TripletTrackTrackCascadeBuilder { public: TripletTrackTrackCascadeBuilder() = default; ~TripletTrackTrackCascadeBuilder() = default; - template >& colHistSpec, - std::map>& trackHistSpec1, - std::map>& trackHistSpec2, - std::map>& cascadeHistSpec, - std::map>& bachelorHistSpec, - std::map>& posDauHistSpec, - std::map>& negDauHistSpec, - std::map>& tripletHistSpec, - std::map>& cprHistSpecBachelor, - std::map>& cprHistSpecV0Daughter, - std::map>& ctrHistSpec) + std::map> const& colHistSpec, + std::map> const& trackHistSpec1, + std::map> const& trackHistSpec2, + std::map> const& cascadeHistSpec, + std::map> const& bachelorHistSpec, + std::map> const& posDauHistSpec, + std::map> const& negDauHistSpec, + std::map> const& tripletHistSpec, + std::map> const& cprHistSpecBachelor, + std::map> const& cprHistSpecV0Daughter, + std::map> const& ctrHistSpec) { // check if correlate the same tracks or not mTrack1Track2AreSameSpecies = confMixing.particle12AreSameSpecies.value; - mColHistManager.template init(registry, colHistSpec, confCollisionBinning); - mTripletHistManagerSe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts); - mTripletHistManagerMe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts); + mColHistManager.template init(registry, colHistSpec, confCollisionBinning); + mTripletHistManagerSe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts, confMixing); + mTripletHistManagerMe.template init(registry, tripletHistSpec, confTripletBinning, confTripletCuts, confMixing); - mTc.template init(confTripletCuts); + mTc.template init(confTripletCuts); if (mTrack1Track2AreSameSpecies) { // Track1 & Track2 & are the same particle species and track 3 is something else - mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); - mCascadeHistManager.template init(registry, cascadeHistSpec, confCascadeSelection, bachelorHistSpec, posDauHistSpec, negDauHistSpec); + mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); + mCascadeHistManager.template init(registry, cascadeHistSpec, confCascadeSelection, bachelorHistSpec, posDauHistSpec, negDauHistSpec); mTrackCleaner.init(confTrackCleaner); mCascadeCleaner.init(confCascadeCleaner); mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection1.pdgCodeAbs.value, confCascadeSelection.pdgCodeAbs.value); @@ -721,9 +721,9 @@ class TripletTrackTrackCascadeBuilder mCtrMe.init(registry, ctrHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, confCtr, confCprBachelor, confCprV0Daughter, confTrackSelection1.chargeAbs.value, confTrackSelection1.chargeAbs.value); } else { // all three tracks are different - mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); - mTrackHistManager2.template init(registry, trackHistSpec2, confTrackSelection2); - mCascadeHistManager.template init(registry, cascadeHistSpec, confCascadeSelection, bachelorHistSpec, posDauHistSpec, negDauHistSpec); + mTrackHistManager1.template init(registry, trackHistSpec1, confTrackSelection1); + mTrackHistManager2.template init(registry, trackHistSpec2, confTrackSelection2); + mCascadeHistManager.template init(registry, cascadeHistSpec, confCascadeSelection, bachelorHistSpec, posDauHistSpec, negDauHistSpec); mTripletHistManagerSe.setMass(confTrackSelection1.pdgCodeAbs.value, confTrackSelection2.pdgCodeAbs.value, confCascadeSelection.pdgCodeAbs.value); mTripletHistManagerSe.setCharge(confTrackSelection1.chargeAbs.value, confTrackSelection2.chargeAbs.value, 1); @@ -827,7 +827,7 @@ class TripletTrackTrackCascadeBuilder tripletprocesshelpers::processMixedEvent(cols, partition1, partition1, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); break; default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; } } else { switch (mMixingPolicy) { @@ -841,7 +841,7 @@ class TripletTrackTrackCascadeBuilder tripletprocesshelpers::processMixedEvent(cols, partition1, partition2, partition3, trackTable, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); break; default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; } } } @@ -861,7 +861,7 @@ class TripletTrackTrackCascadeBuilder tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition1, partition3, trackTable, mcParticles, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); break; default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; } } else { switch (mMixingPolicy) { @@ -875,7 +875,7 @@ class TripletTrackTrackCascadeBuilder tripletprocesshelpers::processMixedEvent(cols, mcCols, partition1, partition2, partition3, trackTable, mcParticles, cache, binsVtxMultCent, mMixingDepth, mTripletHistManagerMe, mCtrMe, mTc); break; default: - LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + LOG(fatal) << "Invalid binning policy specifed. Breaking..."; } } } @@ -901,7 +901,6 @@ class TripletTrackTrackCascadeBuilder std::uniform_int_distribution<> mDist; }; -} // namespace tripletbuilder -} // namespace o2::analysis::femto +} // namespace o2::analysis::femto::tripletbuilder #endif // PWGCF_FEMTO_CORE_TRIPLETBUILDER_H_ diff --git a/PWGCF/Femto/Core/tripletCleaner.h b/PWGCF/Femto/Core/tripletCleaner.h index a92b78eccc6..c40a0760bbb 100644 --- a/PWGCF/Femto/Core/tripletCleaner.h +++ b/PWGCF/Femto/Core/tripletCleaner.h @@ -18,27 +18,24 @@ #include "PWGCF/Femto/Core/pairCleaner.h" -namespace o2::analysis::femto +namespace o2::analysis::femto::tripletcleaner { -namespace tripletcleaner -{ - class TrackTrackTrackTripletCleaner : public paircleaner::BasePairCleaner { public: TrackTrackTrackTripletCleaner() = default; - ~TrackTrackTrackTripletCleaner() = default; + ~TrackTrackTrackTripletCleaner() override = default; template bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& track3, T4 const& /*trackTable*/) const { - return this->isCleanTrackPair(track1, track2) && - this->isCleanTrackPair(track2, track3) && - this->isCleanTrackPair(track1, track3); + return this->isCleanParticlePair(track1, track2) && + this->isCleanParticlePair(track2, track3) && + this->isCleanParticlePair(track1, track3); } - template - bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& track3, T4 const& trackTable, T5 const& partonicMothers) const + template + bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& track3, T4 const& trackTable, T5 const& mcParticles, T6 const& partonicMothers) const { if (!this->isCleanTriplet(track1, track2, track3, trackTable)) { return false; @@ -46,14 +43,14 @@ class TrackTrackTrackTripletCleaner : public paircleaner::BasePairCleaner // pair is clean // no check if we require common or non-common ancestry if (mMixPairsWithCommonAncestor) { - return this->pairHasCommonAncestor(track1, track2, partonicMothers) && - this->pairHasCommonAncestor(track2, track3, partonicMothers) && - this->pairHasCommonAncestor(track1, track3, partonicMothers); + return this->pairHasCommonAncestor(track1, track2, mcParticles, partonicMothers) && + this->pairHasCommonAncestor(track2, track3, mcParticles, partonicMothers) && + this->pairHasCommonAncestor(track1, track3, mcParticles, partonicMothers); } if (mMixPairsWithNonCommonAncestor) { - return this->pairHasNonCommonAncestor(track1, track2, partonicMothers) && - this->pairHasNonCommonAncestor(track2, track3, partonicMothers) && - this->pairHasNonCommonAncestor(track1, track3, partonicMothers); + return this->pairHasNonCommonAncestor(track1, track2, mcParticles, partonicMothers) && + this->pairHasNonCommonAncestor(track2, track3, mcParticles, partonicMothers) && + this->pairHasNonCommonAncestor(track1, track3, mcParticles, partonicMothers); } return true; } @@ -63,22 +60,22 @@ class TrackTrackV0TripletCleaner : public paircleaner::BasePairCleaner { public: TrackTrackV0TripletCleaner() = default; - ~TrackTrackV0TripletCleaner() = default; + ~TrackTrackV0TripletCleaner() override = default; template bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& v0, T4 const& trackTable) const { auto posDaughter = trackTable.rawIteratorAt(v0.posDauId() - trackTable.offset()); auto negDaughter = trackTable.rawIteratorAt(v0.negDauId() - trackTable.offset()); - return this->isCleanTrackPair(track1, track2) && - this->isCleanTrackPair(track1, posDaughter) && - this->isCleanTrackPair(track1, negDaughter) && - this->isCleanTrackPair(track2, posDaughter) && - this->isCleanTrackPair(track2, negDaughter); + return this->isCleanParticlePair(track1, track2) && + this->isCleanParticlePair(track1, posDaughter) && + this->isCleanParticlePair(track1, negDaughter) && + this->isCleanParticlePair(track2, posDaughter) && + this->isCleanParticlePair(track2, negDaughter); } - template - bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& v0, T4 const& trackTable, T5 const& partonicMothers) const + template + bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& v0, T4 const& trackTable, T5 const& mcParticles, T6 const& partonicMothers) const { if (!this->isCleanTriplet(track1, track2, v0, trackTable)) { return false; @@ -86,14 +83,14 @@ class TrackTrackV0TripletCleaner : public paircleaner::BasePairCleaner // pair is clean // no check if we require common or non-common ancestry if (mMixPairsWithCommonAncestor) { - return this->pairHasCommonAncestor(track1, track2, partonicMothers) && - this->pairHasCommonAncestor(track1, v0, partonicMothers) && - this->pairHasCommonAncestor(track2, v0, partonicMothers); + return this->pairHasCommonAncestor(track1, track2, mcParticles, partonicMothers) && + this->pairHasCommonAncestor(track1, v0, mcParticles, partonicMothers) && + this->pairHasCommonAncestor(track2, v0, mcParticles, partonicMothers); } if (mMixPairsWithNonCommonAncestor) { - return this->pairHasNonCommonAncestor(track1, track2, partonicMothers) && - this->pairHasNonCommonAncestor(track1, v0, partonicMothers) && - this->pairHasNonCommonAncestor(track2, v0, partonicMothers); + return this->pairHasNonCommonAncestor(track1, track2, mcParticles, partonicMothers) && + this->pairHasNonCommonAncestor(track1, v0, mcParticles, partonicMothers) && + this->pairHasNonCommonAncestor(track2, v0, mcParticles, partonicMothers); } return true; } @@ -103,7 +100,7 @@ class TrackTrackCascadeTripletCleaner : public paircleaner::BasePairCleaner { public: TrackTrackCascadeTripletCleaner() = default; - ~TrackTrackCascadeTripletCleaner() = default; + ~TrackTrackCascadeTripletCleaner() override = default; template bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& cascade, T4 const& trackTable) const @@ -111,17 +108,17 @@ class TrackTrackCascadeTripletCleaner : public paircleaner::BasePairCleaner auto bachelor = trackTable.rawIteratorAt(cascade.bachelorId() - trackTable.offset()); auto posDaughter = trackTable.rawIteratorAt(cascade.posDauId() - trackTable.offset()); auto negDaughter = trackTable.rawIteratorAt(cascade.negDauId() - trackTable.offset()); - return this->isCleanTrackPair(track1, track2) && - this->isCleanTrackPair(track1, posDaughter) && - this->isCleanTrackPair(track1, negDaughter) && - this->isCleanTrackPair(track1, bachelor) && - this->isCleanTrackPair(track2, posDaughter) && - this->isCleanTrackPair(track2, negDaughter) && - this->isCleanTrackPair(track2, bachelor); + return this->isCleanParticlePair(track1, track2) && + this->isCleanParticlePair(track1, posDaughter) && + this->isCleanParticlePair(track1, negDaughter) && + this->isCleanParticlePair(track1, bachelor) && + this->isCleanParticlePair(track2, posDaughter) && + this->isCleanParticlePair(track2, negDaughter) && + this->isCleanParticlePair(track2, bachelor); } - template - bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& cascade, T4 const& trackTable, T5 const& partonicMothers) const + template + bool isCleanTriplet(T1 const& track1, T2 const& track2, T3 const& cascade, T4 const& trackTable, T5 const& mcParticles, T6 const& partonicMothers) const { if (!this->isCleanTriplet(track1, track2, cascade, trackTable)) { return false; @@ -129,20 +126,19 @@ class TrackTrackCascadeTripletCleaner : public paircleaner::BasePairCleaner // pair is clean // no check if we require common or non-common ancestry if (mMixPairsWithCommonAncestor) { - return this->pairHasCommonAncestor(track1, track2, partonicMothers) && - this->pairHasCommonAncestor(track1, cascade, partonicMothers) && - this->pairHasCommonAncestor(track2, cascade, partonicMothers); + return this->pairHasCommonAncestor(track1, track2, mcParticles, partonicMothers) && + this->pairHasCommonAncestor(track1, cascade, mcParticles, partonicMothers) && + this->pairHasCommonAncestor(track2, cascade, mcParticles, partonicMothers); } if (mMixPairsWithNonCommonAncestor) { - return this->pairHasNonCommonAncestor(track1, track2, partonicMothers) && - this->pairHasNonCommonAncestor(track1, cascade, partonicMothers) && - this->pairHasNonCommonAncestor(track2, cascade, partonicMothers); + return this->pairHasNonCommonAncestor(track1, track2, mcParticles, partonicMothers) && + this->pairHasNonCommonAncestor(track1, cascade, mcParticles, partonicMothers) && + this->pairHasNonCommonAncestor(track2, cascade, mcParticles, partonicMothers); } return true; } }; -} // namespace tripletcleaner -} // namespace o2::analysis::femto +} // namespace o2::analysis::femto::tripletcleaner #endif // PWGCF_FEMTO_CORE_TRIPLETCLEANER_H_ diff --git a/PWGCF/Femto/Core/tripletHistManager.h b/PWGCF/Femto/Core/tripletHistManager.h index c6dba6ce17a..ca1e0779369 100644 --- a/PWGCF/Femto/Core/tripletHistManager.h +++ b/PWGCF/Femto/Core/tripletHistManager.h @@ -30,14 +30,14 @@ #include #include +#include #include #include #include +#include #include -namespace o2::analysis::femto -{ -namespace triplethistmanager +namespace o2::analysis::femto::triplethistmanager { // enum for pair histograms enum TripletHist { @@ -69,6 +69,13 @@ enum TripletHist { kTrueMultVsMult, kTrueCentVsCent, + // mixing qa + kSeNpart1VsNpart2VsNpart3, // unique particles 1,2,3 in each same event + kMeMixingWindowRaw, // mixing window size + kMeMixingWindowEffective, // mixing window size, counting event triplets with particle triplets + kMeNpart1VsNpart2VsNpart3, // unique particles 1,2,3 in each mixed event + kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2VsVtz3VsMult3VsCent3, // correlation of event properties in each mixing bin (super heavy! use with caution) + kTripletHistogramLast }; @@ -90,6 +97,9 @@ struct ConfMixing : o2::framework::ConfigurableGroup { o2::framework::Configurable seed{"seed", -1, "Seed to randomize particle 1/2/3 (if they are identical). Set to negative value to deactivate. Set to 0 to generate unique seed in time."}; o2::framework::Configurable particle123AreSameSpecies{"particle123AreSameSpecies", false, "Particle 1,2 and 3 are of the same species"}; o2::framework::Configurable particle12AreSameSpecies{"particle12AreSameSpecies", false, "Particle 1 and 2 are of the same species"}; + o2::framework::Configurable enablePairCorrelationQa{"enablePairCorrelationQa", true, "Enable triplet-level correlation QA (same-event + mixed-event)"}; + o2::framework::Configurable enableEventMixingQa{"enableEventMixingQa", false, "Enable QA of event properties used in event mixing (vtx, multiplicity, centrality)"}; + o2::framework::ConfigurableAxis particleBinning{"particleBinning", {20, -0.5f, 19.5f}, "Binning for particle number correlation in triplets"}; }; struct ConfTripletBinning : o2::framework::ConfigurableGroup { @@ -101,7 +111,7 @@ struct ConfTripletBinning : o2::framework::ConfigurableGroup { o2::framework::Configurable plotQ3VsMtVsMult{"plotQ3VsMtVsMult", false, "Enable 3D histogram (Q3 vs Mt vs Mult)"}; o2::framework::Configurable plotQ3VsMtVsMultVsCent{"plotQ3VsMtVsMultVsCent", false, "Enable 4D histogram (Q3 vs Mt vs Mult Vs Cent)"}; o2::framework::Configurable plotQ3VsMtVsPt1VsPt2VsPt3VsMult{"plotQ3VsMtVsPt1VsPt2VsPt3VsMult", false, "Enable 6D histogram (Q3 vs Mt Vs Pt1 vs Pt2 vs Pt3 vs Mult)"}; - o2::framework::Configurable plotQ3VsMtVsPt1VsPt2VsPt3VsMultVsCent{"plotQ3VsMtVsPt1VsPt2VsPt3VsMultVsCent", false, "Enable 3D histogram (Q3 vs Mt Vs Pt1 vs Pt2 vs Pt3 vs Mult vs Cent)"}; + o2::framework::Configurable plotQ3VsMtVsPt1VsPt2VsPt3VsMultVsCent{"plotQ3VsMtVsPt1VsPt2VsPt3VsMultVsCent", false, "Enable 7D histogram (Q3 vs Mt Vs Pt1 vs Pt2 vs Pt3 vs Mult vs Cent)"}; o2::framework::ConfigurableAxis q3{"q3", {{600, 0, 6}}, "q3"}; o2::framework::ConfigurableAxis mt{"mt", {{500, 0.8, 5.8}}, "mt"}; o2::framework::ConfigurableAxis multiplicity{"multiplicity", {{50, 0, 200}}, "multiplicity"}; @@ -133,60 +143,73 @@ constexpr std::array, kTripletHistogramLast> {kQ3, o2::framework::HistType::kTH1F, "hQ3", "Q_{3}; Q_{3} (GeV/#it{c}); Entries"}, {kMt, o2::framework::HistType::kTH1F, "hMt", "transverse mass; m_{T} (GeV/#it{c}^{2}); Entries"}, // 2D - {kPt1VsQ3, o2::framework::HistType::kTH2F, "hPt1VsQ3", " p_{T,1} vs Q_{3}; p_{T,1} (GeV/#it{c}); Q_{3} (GeV/#it{c})"}, + {kPt1VsQ3, o2::framework::HistType::kTH2F, "hPt1VsQ3", "p_{T,1} vs Q_{3}; p_{T,1} (GeV/#it{c}); Q_{3} (GeV/#it{c})"}, {kPt2VsQ3, o2::framework::HistType::kTH2F, "hPt2VsQ3", "p_{T,2} vs Q_{3}; p_{T,2} (GeV/#it{c}); Q_{3} (GeV/#it{c})"}, - {kPt3VsQ3, o2::framework::HistType::kTH2F, "hPt3VsQ3", "p_{T,3} vs Q_{3}; p_{T,2} (GeV/#it{c}); Q_{3} (GeV/#it{c})"}, + {kPt3VsQ3, o2::framework::HistType::kTH2F, "hPt3VsQ3", "p_{T,3} vs Q_{3}; p_{T,3} (GeV/#it{c}); Q_{3} (GeV/#it{c})"}, {kQ3VsMt, o2::framework::HistType::kTH2F, "hQ3VsMt", "Q_{3} vs m_{T}; Q_{3} (GeV/#it{c}); m_{T} (GeV/#it{c}^{2})"}, {kQ3VsMult, o2::framework::HistType::kTH2F, "hQ3VsMult", "Q_{3} vs Multiplicity; Q_{3} (GeV/#it{c}); Multiplicity"}, {kQ3VsCent, o2::framework::HistType::kTH2F, "hQ3VsCent", "Q_{3} vs Centrality; Q_{3} (GeV/#it{c}); Centrality"}, // n-D - {kPt1VsPt2VsPt3, o2::framework::HistType::kTHnSparseF, "hPt1VsPt2VsPt3", "k* vs m_{T} vs multiplicity; k* (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); Multiplicity"}, - {kQ3VsPt1VsPt2VsPt3, o2::framework::HistType::kTHnSparseF, "hQ3VsPt1VsPt2VsPt3", "Q_{3} vs p_{T,1} vs p_{T,2} vs p_{T,3}; Q_{3} (GeV/#it{c}); p_{T,1} (GeV/#it{c}) ; p_{T,2} (GeV/#it{c}); p_{T,3} (GeV/#it{c})"}, + {kPt1VsPt2VsPt3, o2::framework::HistType::kTHnSparseF, "hPt1VsPt2VsPt3", "p_{T,1} vs p_{T,2} vs p_{T,3}; p_{T,1} (GeV/#it{c});p_{T,2} (GeV/#it{c});p_{T,3} (GeV/#it{c});"}, + {kQ3VsPt1VsPt2VsPt3, o2::framework::HistType::kTHnSparseF, "hQ3VsPt1VsPt2VsPt3", "Q_{3} vs p_{T,1} vs p_{T,2} vs p_{T,3}; Q_{3} (GeV/#it{c}); p_{T,1} (GeV/#it{c}); p_{T,2} (GeV/#it{c}); p_{T,3} (GeV/#it{c});"}, {kQ3VsMtVsMult, o2::framework::HistType::kTHnSparseF, "hQ3VsMtVsMult", "Q_{3} vs m_{T} vs multiplicity; Q_{3} (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); Multiplicity"}, - {kQ3VsMtVsMultVsCent, o2::framework::HistType::kTHnSparseF, "hQ3VsMtVsMultVsCent", "Q_{3} vs m_{T} vs multiplicity vs centrality; Q_{3} (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); Multiplicity; Centrality"}, + {kQ3VsMtVsMultVsCent, o2::framework::HistType::kTHnSparseF, "hQ3VsMtVsMultVsCent", "Q_{3} vs m_{T} vs multiplicity vs centrality; Q_{3} (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); Multiplicity; Centrality (%);"}, // n-D with mass - {kQ3VsMtVsPt1VsPt2VsPt3VsMult, o2::framework::HistType::kTHnSparseF, "hQ3VsMtVsPt1VsPt2VsPt3VsMult", "Q_{3} vs m_{T} vs p_{T,1} vs p_{T,2} vs p_{T,3} vs multiplicity; Q_{3} (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}) ; p_{T,2} (GeV/#it{c}); p_{T,3} (GeV/#it{c}) ; Multiplicity"}, - {kQ3VsMtVsPt1VsPt2VsPt3VsMultVsCent, o2::framework::HistType::kTHnSparseF, "hQ3VsMtVsPt1VsPt2VsPt3VsMultVsCent", "Q_{3} vs m_{T} vs p_{T,1} vs p_{T,2} vs p_{T,3} vs multiplicity vs centrality; Q_{3} (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}) ; p_{T,2} (GeV/#it{c}); p_{T,3} (GeV/#it{c}) vs multiplicity vs centrality"}, + {kQ3VsMtVsPt1VsPt2VsPt3VsMult, o2::framework::HistType::kTHnSparseF, "hQ3VsMtVsPt1VsPt2VsPt3VsMult", "Q_{3} vs m_{T} vs p_{T,1} vs p_{T,2} vs p_{T,3} vs multiplicity; Q_{3} (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}) ; p_{T,2} (GeV/#it{c}); p_{T,3} (GeV/#it{c}); Multiplicity;"}, + {kQ3VsMtVsPt1VsPt2VsPt3VsMultVsCent, o2::framework::HistType::kTHnSparseF, "hQ3VsMtVsPt1VsPt2VsPt3VsMultVsCent", "Q_{3} vs m_{T} vs p_{T,1} vs p_{T,2} vs p_{T,3} vs multiplicity vs centrality; Q_{3} (GeV/#it{c}); m_{T} (GeV/#it{c}^{2}); p_{T,1} (GeV/#it{c}) ; p_{T,2} (GeV/#it{c}); p_{T,3} (GeV/#it{c}); Multiplicity; Centrality (%);"}, {kTrueQ3VsQ3, o2::framework::HistType::kTH2F, "hTrueQ3VsQ3", "Q_{3,True} vs Q_{3}; Q_{3,true} (GeV/#it{c}); Q_{3} (GeV/#it{c})"}, {kTrueMtVsMt, o2::framework::HistType::kTH2F, "hTrueMtVsMt", "m_{T,True} vs m_{T}; m_{T,True} (GeV/#it{c}^{2}); m_{T} (GeV/#it{c}^{2})"}, {kTrueMultVsMult, o2::framework::HistType::kTH2F, "hTrueMultVsMult", "Multiplicity_{True} vs Multiplicity; Multiplicity_{True} ; Multiplicity"}, {kTrueCentVsCent, o2::framework::HistType::kTH2F, "hTrueCentVsCent", "Centrality_{True} vs Centrality; Centrality_{True} (%); Centrality (%)"}, + // mixing qa + {kSeNpart1VsNpart2VsNpart3, o2::framework::HistType::kTHnSparseF, "hSeNpart1VsNpart2VsNpart3", "# unique particle 1 vs # unique particle 2 vs # unique particle 3 in each same event; # particle 1; # particle 2; # particle 3;"}, + {kMeMixingWindowRaw, o2::framework::HistType::kTH1F, "hMeMixingWindowRaw", "Raw Mixing Window; Raw Mixing Window; Entries"}, + {kMeMixingWindowEffective, o2::framework::HistType::kTH1F, "hMeMixingWindowEffective", "Effective Mixing Window; Effective Mixing Window; Entries"}, + {kMeNpart1VsNpart2VsNpart3, o2::framework::HistType::kTHnSparseF, "hMeNpart1VsNpart2VsNpart3", "# unique particle 1 vs # unique particle 2 vs # unique particle 3 in each mixing bin; # particle 1; # particle 2; # particle 3;"}, + {kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2VsVtz3VsMult3VsCent3, o2::framework::HistType::kTHnSparseF, "hVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2VsVtz3VsMult3VsCent3", "Mixing bins; V_{z,1} (cm); mult_{1}; cent_{1} (%); V_{z,2} (cm); mult_{2}; cent_{2} (%); V_{z,3} (cm); mult_{3}; cent_{3} (%);"}, }}; -#define TRIPLET_HIST_ANALYSIS_MAP(conf) \ - {kQ3, {conf.q3}}, \ - {kMt, {conf.mt}}, \ - {kPt1VsQ3, {conf.pt1, conf.q3}}, \ - {kPt2VsQ3, {conf.pt2, conf.q3}}, \ - {kPt3VsQ3, {conf.pt3, conf.q3}}, \ - {kQ3VsMt, {conf.q3, conf.mt}}, \ - {kQ3VsMult, {conf.q3, conf.multiplicity}}, \ - {kQ3VsCent, {conf.q3, conf.centrality}}, \ - {kPt1VsPt2VsPt3, {conf.pt1, conf.pt2, conf.pt3}}, \ - {kQ3VsPt1VsPt2VsPt3, {conf.q3, conf.pt1, conf.pt2, conf.pt3}}, \ - {kQ3VsMtVsMult, {conf.q3, conf.mt, conf.multiplicity}}, \ - {kQ3VsMtVsMultVsCent, {conf.q3, conf.mt, conf.multiplicity, conf.centrality}}, \ - {kQ3VsMtVsPt1VsPt2VsPt3VsMult, {conf.q3, conf.mt, conf.pt1, conf.pt2, conf.pt3, conf.multiplicity}}, \ - {kQ3VsMtVsPt1VsPt2VsPt3VsMultVsCent, {conf.q3, conf.mt, conf.pt1, conf.pt2, conf.pt3, conf.multiplicity, conf.centrality}}, - -#define TRIPLET_HIST_MC_MAP(conf) \ - {kTrueQ3VsQ3, {conf.q3, conf.q3}}, \ - {kTrueMtVsMt, {conf.mt, conf.mt}}, \ - {kTrueMultVsMult, {conf.multiplicity, conf.multiplicity}}, \ - {kTrueCentVsCent, {conf.centrality, conf.centrality}}, - -template -auto makeTripletHistSpecMap(const T& confPairBinning) +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define TRIPLET_HIST_ANALYSIS_MAP(conf, confMixing) \ + {kQ3, {(conf).q3}}, \ + {kMt, {(conf).mt}}, \ + {kPt1VsQ3, {(conf).pt1, (conf).q3}}, \ + {kPt2VsQ3, {(conf).pt2, (conf).q3}}, \ + {kPt3VsQ3, {(conf).pt3, (conf).q3}}, \ + {kQ3VsMt, {(conf).q3, (conf).mt}}, \ + {kQ3VsMult, {(conf).q3, (conf).multiplicity}}, \ + {kQ3VsCent, {(conf).q3, (conf).centrality}}, \ + {kPt1VsPt2VsPt3, {(conf).pt1, (conf).pt2, (conf).pt3}}, \ + {kQ3VsPt1VsPt2VsPt3, {(conf).q3, (conf).pt1, (conf).pt2, (conf).pt3}}, \ + {kQ3VsMtVsMult, {(conf).q3, (conf).mt, (conf).multiplicity}}, \ + {kQ3VsMtVsMultVsCent, {(conf).q3, (conf).mt, (conf).multiplicity, (conf).centrality}}, \ + {kQ3VsMtVsPt1VsPt2VsPt3VsMult, {(conf).q3, (conf).mt, (conf).pt1, (conf).pt2, (conf).pt3, (conf).multiplicity}}, \ + {kQ3VsMtVsPt1VsPt2VsPt3VsMultVsCent, {(conf).q3, (conf).mt, (conf).pt1, (conf).pt2, (conf).pt3, (conf).multiplicity, (conf).centrality}}, \ + {kSeNpart1VsNpart2VsNpart3, {(confMixing).particleBinning, (confMixing).particleBinning, (confMixing).particleBinning}}, \ + {kMeMixingWindowRaw, {(confMixing).particleBinning}}, \ + {kMeMixingWindowEffective, {(confMixing).particleBinning}}, \ + {kMeNpart1VsNpart2VsNpart3, {(confMixing).particleBinning, (confMixing).particleBinning, (confMixing).particleBinning}}, \ + {kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2VsVtz3VsMult3VsCent3, {(confMixing).vtxBins, (confMixing).multBins, (confMixing).centBins, (confMixing).vtxBins, (confMixing).multBins, (confMixing).centBins, (confMixing).vtxBins, (confMixing).multBins, (confMixing).centBins}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define TRIPLET_HIST_MC_MAP(conf) \ + {kTrueQ3VsQ3, {(conf).q3, (conf).q3}}, \ + {kTrueMtVsMt, {(conf).mt, (conf).mt}}, \ + {kTrueMultVsMult, {(conf).multiplicity, (conf).multiplicity}}, \ + {kTrueCentVsCent, {(conf).centrality, (conf).centrality}}, + +template +auto makeTripletHistSpecMap(T1 const& confPairBinning, T2 const& confMixing) { return std::map>{ - TRIPLET_HIST_ANALYSIS_MAP(confPairBinning)}; + TRIPLET_HIST_ANALYSIS_MAP(confPairBinning, confMixing)}; }; -template -auto makeTripletMcHistSpecMap(const T& confPairBinning) +template +auto makeTripletMcHistSpecMap(T1 const& confPairBinning, T2 const& confMixing) { return std::map>{ - TRIPLET_HIST_ANALYSIS_MAP(confPairBinning) + TRIPLET_HIST_ANALYSIS_MAP(confPairBinning, confMixing) TRIPLET_HIST_MC_MAP(confPairBinning)}; }; @@ -206,7 +229,7 @@ constexpr std::string_view AnalysisDir = "Analysis/"; constexpr std::string_view QaDir = "QA/"; constexpr std::string_view McDir = "MC/"; -template @@ -216,11 +239,12 @@ class TripletHistManager TripletHistManager() = default; ~TripletHistManager() = default; - template + template void init(o2::framework::HistogramRegistry* registry, std::map> const& Specs, T1 const& ConfTripletBinning, - T2 const& ConfTripletCuts) + T2 const& ConfTripletCuts, + T3 const& ConfMixing) { mHistogramRegistry = registry; @@ -244,13 +268,22 @@ class TripletHistManager mPlotQ3VsMtVsPt1VsPt2VsPt3VsMult = ConfTripletBinning.plotQ3VsMtVsPt1VsPt2VsPt3VsMult.value; mPlotQ3VsMtVsPt1VsPt2VsPt3VsMultVsCent = ConfTripletBinning.plotQ3VsMtVsPt1VsPt2VsPt3VsMultVsCent.value; - if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + mPairCorrelationQa = ConfMixing.enablePairCorrelationQa.value; + mEventMixingQa = ConfMixing.enableEventMixingQa.value; + + if constexpr (isFlagSet(mode, modes::Mode::kReco)) { initAnalysis(Specs); } if constexpr (isFlagSet(mode, modes::Mode::kMc)) { initMc(Specs); } + if constexpr (isFlagSet(mode, modes::Mode::kSe)) { + initSeMixingQa(Specs); + } + if constexpr (isFlagSet(mode, modes::Mode::kMe)) { + initMeMixingQa(Specs); + } } void setMass(int PdgParticle1, int PdgParticle2, int PdgParticle3) @@ -359,7 +392,7 @@ class TripletHistManager mHasMcCol = true; auto mcCol1 = col1.template fMcCol_as(); auto mcCol2 = col2.template fMcCol_as(); - auto mcCol3 = col2.template fMcCol_as(); + auto mcCol3 = col3.template fMcCol_as(); mTrueMult = (mcCol1.mult() + mcCol2.mult() + mcCol3.mult()) / 3.f; mTrueCent = (mcCol1.cent() + mcCol2.cent() + mcCol3.cent()) / 3.f; } @@ -375,7 +408,7 @@ class TripletHistManager template void fill() { - if constexpr (isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (isFlagSet(mode, modes::Mode::kReco)) { fillAnalysis(); } if constexpr (isFlagSet(mode, modes::Mode::kMc)) { @@ -385,6 +418,60 @@ class TripletHistManager float getQ3() const { return mQ3; } + template + void trackParticlesPerEvent(T1 const& particle1, T2 const& particle2, T3 const& particle3) + { + if (!mPairCorrelationQa) { + return; + } + mParticles1PerEvent.insert(particle1.globalIndex()); + mParticles2PerEvent.insert(particle2.globalIndex()); + mParticles3PerEvent.insert(particle3.globalIndex()); + } + + template + void fillMixingQaMe(T1 const& col1, T2 const& col2, T3 const& col3) + { + if (mEventMixingQa) { + mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(getHistName(kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2VsVtz3VsMult3VsCent3, HistTable)), + col1.posZ(), col1.mult(), col1.cent(), + col2.posZ(), col2.mult(), col2.cent(), + col3.posZ(), col3.mult(), col3.cent()); + } + } + + void resetTrackedParticlesPerEvent() + { + mParticles1PerEvent.clear(); + mParticles1PerEvent.reserve(100); + mParticles2PerEvent.clear(); + mParticles2PerEvent.reserve(100); + mParticles3PerEvent.clear(); + mParticles3PerEvent.reserve(100); + } + + void fillMixingQaSe() + { + if (mPairCorrelationQa) { + mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(getHistName(kSeNpart1VsNpart2VsNpart3, HistTable)), mParticles1PerEvent.size(), mParticles2PerEvent.size(), mParticles3PerEvent.size()); + } + } + + void fillMixingQaMePerEvent() + { + if (mPairCorrelationQa) { + mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(getHistName(kMeNpart1VsNpart2VsNpart3, HistTable)), mParticles1PerEvent.size(), mParticles2PerEvent.size(), mParticles3PerEvent.size()); + } + } + + void fillMixingQaMePerMixingBin(int windowSizeRaw, int windowSizeEffective) + { + if (mPairCorrelationQa) { + mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(getHistName(kMeMixingWindowRaw, HistTable)), windowSizeRaw); + mHistogramRegistry->fill(HIST(prefix) + HIST(QaDir) + HIST(getHistName(kMeMixingWindowEffective, HistTable)), windowSizeEffective); + } + } + private: ROOT::Math::PxPyPzEVector getqij(ROOT::Math::PxPyPzEVector const& vi, ROOT::Math::PxPyPzEVector const& vj) { @@ -454,6 +541,27 @@ class TripletHistManager mHistogramRegistry->add(mcDir + getHistNameV2(kTrueCentVsCent, HistTable), getHistDesc(kTrueCentVsCent, HistTable), getHistType(kTrueCentVsCent, HistTable), {Specs.at(kTrueCentVsCent)}); } + void initSeMixingQa(std::map> const& Specs) + { + std::string dir = std::string(prefix) + std::string(QaDir); + if (mPairCorrelationQa) { + mHistogramRegistry->add(dir + getHistNameV2(kSeNpart1VsNpart2VsNpart3, HistTable), getHistDesc(kSeNpart1VsNpart2VsNpart3, HistTable), getHistType(kSeNpart1VsNpart2VsNpart3, HistTable), {Specs.at(kSeNpart1VsNpart2VsNpart3)}); + } + } + + void initMeMixingQa(std::map> const& Specs) + { + std::string dir = std::string(prefix) + std::string(QaDir); + if (mPairCorrelationQa) { + mHistogramRegistry->add(dir + getHistNameV2(kMeMixingWindowRaw, HistTable), getHistDesc(kMeMixingWindowRaw, HistTable), getHistType(kMeMixingWindowRaw, HistTable), {Specs.at(kMeMixingWindowRaw)}); + mHistogramRegistry->add(dir + getHistNameV2(kMeMixingWindowEffective, HistTable), getHistDesc(kMeMixingWindowEffective, HistTable), getHistType(kMeMixingWindowEffective, HistTable), {Specs.at(kMeMixingWindowEffective)}); + mHistogramRegistry->add(dir + getHistNameV2(kMeNpart1VsNpart2VsNpart3, HistTable), getHistDesc(kMeNpart1VsNpart2VsNpart3, HistTable), getHistType(kMeNpart1VsNpart2VsNpart3, HistTable), {Specs.at(kMeNpart1VsNpart2VsNpart3)}); + } + if (mEventMixingQa) { + mHistogramRegistry->add(dir + getHistNameV2(kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2VsVtz3VsMult3VsCent3, HistTable), getHistDesc(kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2VsVtz3VsMult3VsCent3, HistTable), getHistType(kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2VsVtz3VsMult3VsCent3, HistTable), {Specs.at(kMeVtz1VsMult1VsCent1VsVtz2VsMult2VsCent2VsVtz3VsMult3VsCent3)}); + } + } + void fillAnalysis() { if (mPlot1d) { @@ -540,9 +648,9 @@ class TripletHistManager int mAbsCharge1 = 1; int mAbsCharge2 = 1; int mAbsCharge3 = 1; - ROOT::Math::PtEtaPhiMVector mParticle1{}; - ROOT::Math::PtEtaPhiMVector mParticle2{}; - ROOT::Math::PtEtaPhiMVector mParticle3{}; + ROOT::Math::PtEtaPhiMVector mParticle1; + ROOT::Math::PtEtaPhiMVector mParticle2; + ROOT::Math::PtEtaPhiMVector mParticle3; float mMass1 = 0.f; float mMass2 = 0.f; float mMass3 = 0.f; @@ -552,9 +660,9 @@ class TripletHistManager float mCent = 0.f; // mc - ROOT::Math::PtEtaPhiMVector mTrueParticle1{}; - ROOT::Math::PtEtaPhiMVector mTrueParticle2{}; - ROOT::Math::PtEtaPhiMVector mTrueParticle3{}; + ROOT::Math::PtEtaPhiMVector mTrueParticle1; + ROOT::Math::PtEtaPhiMVector mTrueParticle2; + ROOT::Math::PtEtaPhiMVector mTrueParticle3; float mTrueQ3 = 0.f; float mTrueMt = 0.f; float mTrueMult = 0.f; @@ -565,8 +673,6 @@ class TripletHistManager bool mHasMcCol = false; float mQ3Min = -1.f; float mQ3Max = -1.f; - float mKtMin = -1.f; - float mKtMax = -1.f; float mMtMin = -1.f; float mMtMax = -1.f; @@ -580,8 +686,14 @@ class TripletHistManager bool mPlotQ3VsMtVsMultVsCent = false; bool mPlotQ3VsMtVsPt1VsPt2VsPt3VsMult = false; bool mPlotQ3VsMtVsPt1VsPt2VsPt3VsMultVsCent = false; -}; -}; // namespace triplethistmanager -}; // namespace o2::analysis::femto + // mixing qa + bool mPairCorrelationQa = false; + bool mEventMixingQa = false; + + std::unordered_set mParticles1PerEvent; + std::unordered_set mParticles2PerEvent; + std::unordered_set mParticles3PerEvent; +}; +} // namespace o2::analysis::femto::triplethistmanager #endif // PWGCF_FEMTO_CORE_TRIPLETHISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/tripletProcessHelpers.h b/PWGCF/Femto/Core/tripletProcessHelpers.h index 75538ae024d..4d02566c120 100644 --- a/PWGCF/Femto/Core/tripletProcessHelpers.h +++ b/PWGCF/Femto/Core/tripletProcessHelpers.h @@ -10,7 +10,7 @@ // or submit itself to any jurisdiction. /// \file tripletProcessHelpers.h -/// \brief process functions used in pair tasks +/// \brief process functions used in triplet tasks /// \author anton.riedel@tum.de, TU München, anton.riedel@tum.de #ifndef PWGCF_FEMTO_CORE_TRIPLETPROCESSHELPERS_H_ @@ -20,17 +20,15 @@ #include "PWGCF/Femto/DataModel/FemtoTables.h" #include +#include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::tripletprocesshelpers { -namespace tripletprocesshelpers -{ - enum TripletOrder : uint8_t { kOrder123, // no swap - kOrder213, // first two swap 1&2 so we can use them for the case that particle 1 & 2 are the same species, particle 3 is something else + kOrder213, // swap 1&2: for the case that particle 1 & 2 are the same species, particle 3 is something else kOrder132, // swap 2&3 kOrder321, // swap 1&2&3 }; @@ -53,6 +51,8 @@ void processSameEvent(T1 const& SliceParticle, T7& TcManager, TripletOrder tripletOrder) { + TripletHistManager.resetTrackedParticlesPerEvent(); + for (auto const& part : SliceParticle) { ParticleHistManager.template fill(part, TrackTable); } @@ -89,27 +89,23 @@ void processSameEvent(T1 const& SliceParticle, break; } - // fill deta-dphi histograms with !3 cutoff + // fill deta-dphi histograms with q3 cutoff CtrManager.fill(TripletHistManager.getQ3()); // if triplet cuts are configured check them before filling if (TripletHistManager.checkTripletCuts()) { TripletHistManager.template fill(); + TripletHistManager.trackParticlesPerEvent(p1, p2, p3); } } + + TripletHistManager.fillMixingQaSe(); } // process same event for identical 2 particles and 1 other particle template + typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8, typename T9> void processSameEvent(T1 const& SliceParticle1, // 1&2 have same species T2 const& SliceParticle3, T3 const& TrackTable, @@ -119,8 +115,10 @@ void processSameEvent(T1 const& SliceParticle1, // 1&2 have same species T7& TripletHistManager, T8& CtrManager, T9& TcManager, - TripletOrder triplerOrder) + TripletOrder tripletOrder) { + TripletHistManager.resetTrackedParticlesPerEvent(); + for (auto const& part : SliceParticle1) { ParticleHistManager1.template fill(part, TrackTable); } @@ -128,40 +126,44 @@ void processSameEvent(T1 const& SliceParticle1, // 1&2 have same species ParticleHistManager3.template fill(part, TrackTable); } - for (auto const& [p1, p2, p3] : o2::soa::combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(SliceParticle1, SliceParticle1, SliceParticle3))) { + for (auto const& p3 : SliceParticle3) { + for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(SliceParticle1, SliceParticle1))) { - // check if triplet is clean - if (!TcManager.isCleanTriplet(p1, p2, p3, TrackTable)) { - continue; - } + // check if triplet is clean + if (!TcManager.isCleanTriplet(p1, p2, p3, TrackTable)) { + continue; + } - // check if triplet is close - CtrManager.setTriplet(p1, p2, p3, TrackTable); - if (CtrManager.isCloseTriplet()) { - continue; - } + // check if triplet is close + CtrManager.setTriplet(p1, p2, p3, TrackTable); + if (CtrManager.isCloseTriplet()) { + continue; + } - // Randomize triplet order if enabled - switch (triplerOrder) { - case kOrder123: - TripletHistManager.setTriplet(p1, p2, p3, Collision); - break; - case kOrder213: - TripletHistManager.setTriplet(p1, p2, p3, Collision); - break; - default: - TripletHistManager.setTriplet(p1, p2, p3, Collision); - break; - } + // Randomize triplet order if enabled + // only kOrder123 and kOrder213 are meaningful here since particle 1 & 2 are the same species + switch (tripletOrder) { + case kOrder213: + TripletHistManager.setTriplet(p2, p1, p3, Collision); + break; + case kOrder123: + default: + TripletHistManager.setTriplet(p1, p2, p3, Collision); + break; + } - // fill deta-dphi histograms with !3 cutoff - CtrManager.fill(TripletHistManager.getQ3()); + // fill deta-dphi histograms with q3 cutoff + CtrManager.fill(TripletHistManager.getQ3()); - // if triplet cuts are configured check them before filling - if (TripletHistManager.checkTripletCuts()) { - TripletHistManager.template fill(); + // if triplet cuts are configured check them before filling + if (TripletHistManager.checkTripletCuts()) { + TripletHistManager.template fill(); + TripletHistManager.trackParticlesPerEvent(p1, p2, p3); + } } } + + TripletHistManager.fillMixingQaSe(); } // process same event for 3 different particles @@ -189,6 +191,8 @@ void processSameEvent(T1 const& SliceParticle1, T10& CtrManager, T11& TcManager) { + TripletHistManager.resetTrackedParticlesPerEvent(); + for (auto const& part : SliceParticle1) { ParticleHistManager1.template fill(part, TrackTable); } @@ -199,7 +203,7 @@ void processSameEvent(T1 const& SliceParticle1, ParticleHistManager3.template fill(part, TrackTable); } - for (auto const& [p1, p2, p3] : o2::soa::combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(SliceParticle1, SliceParticle2, SliceParticle3))) { + for (auto const& [p1, p2, p3] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(SliceParticle1, SliceParticle2, SliceParticle3))) { // check if triplet is clean if (!TcManager.isCleanTriplet(p1, p2, p3, TrackTable)) { @@ -214,17 +218,20 @@ void processSameEvent(T1 const& SliceParticle1, TripletHistManager.setTriplet(p1, p2, p3, Collision); - // fill deta-dphi histograms with !3 cutoff + // fill deta-dphi histograms with q3 cutoff CtrManager.fill(TripletHistManager.getQ3()); // if triplet cuts are configured check them before filling if (TripletHistManager.checkTripletCuts()) { TripletHistManager.template fill(); + TripletHistManager.trackParticlesPerEvent(p1, p2, p3); } } + + TripletHistManager.fillMixingQaSe(); } -// // process same event for 3 identical particles with mc information +// process same event for 3 identical particles with mc information template (part, TrackTable, mcParticles, mcMothers, mcPartonicMothers); } + for (auto const& [p1, p2, p3] : o2::soa::combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(SliceParticle, SliceParticle, SliceParticle))) { - // check if pair is clean - if (!TcManager.isCleanTriplet(p1, p2, p3, TrackTable, mcPartonicMothers)) { + // check if triplet is clean + if (!TcManager.isCleanTriplet(p1, p2, p3, TrackTable, mcParticles, mcPartonicMothers)) { continue; } - // check if pair is close + // check if triplet is close CtrManager.setTriplet(p1, p2, p3, TrackTable); if (CtrManager.isCloseTriplet()) { continue; } - // Randomize pair order if enabled - // - switch (swapTriplet) { - case 3: - TripletHistManager.setTripletMc(p1, p3, p2, mcParticles, Collision, mcCollisions); + // Randomize triplet order if enabled + switch (tripletOrder) { + case kOrder123: + TripletHistManager.setTripletMc(p1, p2, p3, mcParticles, Collision, mcCollisions); break; - case 2: + case kOrder213: TripletHistManager.setTripletMc(p2, p1, p3, mcParticles, Collision, mcCollisions); break; - case 1: - TripletHistManager.setTripletMc(p1, p2, p3, mcParticles, Collision, mcCollisions); + case kOrder132: + TripletHistManager.setTripletMc(p1, p3, p2, mcParticles, Collision, mcCollisions); + break; + case kOrder321: + TripletHistManager.setTripletMc(p3, p2, p1, mcParticles, Collision, mcCollisions); break; default: TripletHistManager.setTripletMc(p1, p2, p3, mcParticles, Collision, mcCollisions); break; } - // float threshold = 0.5f; // fill deta-dphi histograms with q3 cutoff CtrManager.fill(TripletHistManager.getQ3()); - // if pair cuts are configured check them before filling + // if triplet cuts are configured check them before filling if (TripletHistManager.checkTripletCuts()) { TripletHistManager.template fill(); + TripletHistManager.trackParticlesPerEvent(p1, p2, p3); } } + + TripletHistManager.fillMixingQaSe(); } // process same event for 2 identical particles and one other with mc information template + typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13> void processSameEvent(T1 const& SliceParticle1, T2 const& SliceParticle3, T3 const& TrackTable, @@ -317,47 +320,53 @@ void processSameEvent(T1 const& SliceParticle1, T11& TripletHistManager, T12& CtrManager, T13& TcManager, - int swapTriplet) + TripletOrder tripletOrder) { + TripletHistManager.resetTrackedParticlesPerEvent(); + for (auto const& part : SliceParticle1) { ParticleHistManager1.template fill(part, TrackTable, mcParticles, mcMothers, mcPartonicMothers); } for (auto const& part : SliceParticle3) { ParticleHistManager3.template fill(part, TrackTable, mcParticles, mcMothers, mcPartonicMothers); } - for (auto const& [p1, p2, p3] : o2::soa::combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(SliceParticle1, SliceParticle1, SliceParticle3))) { - // check if pair is clean - if (!TcManager.isCleanTriplet(p1, p2, p3, TrackTable, mcPartonicMothers)) { - continue; - } - // check if pair is close - CtrManager.setTriplet(p1, p2, p3, TrackTable); - if (CtrManager.isCloseTriplet()) { - continue; - } - // Randomize pair order if enabled - // - switch (swapTriplet) { - case 2: - TripletHistManager.setTripletMc(p2, p1, p3, mcParticles, Collision, mcCollisions); - break; - case 1: - TripletHistManager.setTripletMc(p1, p2, p3, mcParticles, Collision, mcCollisions); - break; - default: - TripletHistManager.setTripletMc(p1, p2, p3, mcParticles, Collision, mcCollisions); - break; - } - // fill deta-dphi histograms with q3 cutoff - CtrManager.fill(TripletHistManager.getQ3()); - // if pair cuts are configured check them before filling - if (TripletHistManager.checkTripletCuts()) { - TripletHistManager.template fill(); + + for (auto const& p3 : SliceParticle3) { + for (auto const& [p1, p2] : o2::soa::combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(SliceParticle1, SliceParticle1))) { + // check if triplet is clean + if (!TcManager.isCleanTriplet(p1, p2, p3, TrackTable, mcParticles, mcPartonicMothers)) { + continue; + } + // check if triplet is close + CtrManager.setTriplet(p1, p2, p3, TrackTable); + if (CtrManager.isCloseTriplet()) { + continue; + } + // Randomize triplet order if enabled + // only kOrder123 and kOrder213 are meaningful here since particle 1 & 2 are the same species + switch (tripletOrder) { + case kOrder213: + TripletHistManager.setTripletMc(p2, p1, p3, mcParticles, Collision, mcCollisions); + break; + case kOrder123: + default: + TripletHistManager.setTripletMc(p1, p2, p3, mcParticles, Collision, mcCollisions); + break; + } + // fill deta-dphi histograms with q3 cutoff + CtrManager.fill(TripletHistManager.getQ3()); + // if triplet cuts are configured check them before filling + if (TripletHistManager.checkTripletCuts()) { + TripletHistManager.template fill(); + TripletHistManager.trackParticlesPerEvent(p1, p2, p3); + } } } + + TripletHistManager.fillMixingQaSe(); } -// process same event for 3 different particles +// process same event for 3 different particles with mc information template (part, TrackTable, mcParticles, mcMothers, mcPartonicMothers); } @@ -399,12 +410,13 @@ void processSameEvent(T1 const& SliceParticle1, for (auto const& part : SliceParticle3) { ParticleHistManager3.template fill(part, TrackTable, mcParticles, mcMothers, mcPartonicMothers); } - for (auto const& [p1, p2, p3] : o2::soa::combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(SliceParticle1, SliceParticle2, SliceParticle3))) { - // check if pair is clean - if (!TcManager.isCleanTriplet(p1, p2, p3, TrackTable, mcPartonicMothers)) { + + for (auto const& [p1, p2, p3] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(SliceParticle1, SliceParticle2, SliceParticle3))) { + // check if triplet is clean + if (!TcManager.isCleanTriplet(p1, p2, p3, TrackTable, mcParticles, mcPartonicMothers)) { continue; } - // check if pair is close + // check if triplet is close CtrManager.setTriplet(p1, p2, p3, TrackTable); if (CtrManager.isCloseTriplet()) { continue; @@ -412,11 +424,14 @@ void processSameEvent(T1 const& SliceParticle1, TripletHistManager.setTripletMc(p1, p2, p3, mcParticles, Collision, mcCollisions); // fill deta-dphi histograms with q3 cutoff CtrManager.fill(TripletHistManager.getQ3()); - // if pair cuts are configured check them before filling + // if triplet cuts are configured check them before filling if (TripletHistManager.checkTripletCuts()) { TripletHistManager.template fill(); + TripletHistManager.trackParticlesPerEvent(p1, p2, p3); } } + + TripletHistManager.fillMixingQaSe(); } // process mixed event @@ -444,19 +459,47 @@ void processMixedEvent(T1 const& Collisions, T10& CtrManager, T11& TcManager) { + int64_t lastCollisionIndex = -1; + int windowSizeRaw = 0; + int windowSizeEffective = 0; + for (auto const& [collision1, collision2, collision3] : o2::soa::selfCombinations(policy, depth, -1, Collisions, Collisions, Collisions)) { + + // --- new window --- + if (collision1.globalIndex() != lastCollisionIndex) { + if (lastCollisionIndex != -1) { + TripletHistManager.fillMixingQaMePerMixingBin(windowSizeRaw, windowSizeEffective); + } + windowSizeRaw = 0; + windowSizeEffective = 0; + lastCollisionIndex = collision1.globalIndex(); + } + + ++windowSizeRaw; + if (collision1.magField() != collision2.magField() || collision2.magField() != collision3.magField() || collision1.magField() != collision3.magField()) { + LOG(warn) << "Tried mixing events with different magnetic field."; continue; } + CtrManager.setMagField(collision1.magField()); + auto sliceParticle1 = Partition1->sliceByCached(o2::aod::femtobase::stored::fColId, collision1.globalIndex(), cache); auto sliceParticle2 = Partition2->sliceByCached(o2::aod::femtobase::stored::fColId, collision2.globalIndex(), cache); auto sliceParticle3 = Partition3->sliceByCached(o2::aod::femtobase::stored::fColId, collision3.globalIndex(), cache); + + TripletHistManager.resetTrackedParticlesPerEvent(); + if (sliceParticle1.size() == 0 || sliceParticle2.size() == 0 || sliceParticle3.size() == 0) { + TripletHistManager.fillMixingQaMePerEvent(); continue; } + + bool hasValidTriplet = false; + TripletHistManager.fillMixingQaMe(collision1, collision2, collision3); + for (auto const& [p1, p2, p3] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(sliceParticle1, sliceParticle2, sliceParticle3))) { // pair cleaning if (!TcManager.isCleanTriplet(p1, p2, p3, TrackTable)) { @@ -467,12 +510,27 @@ void processMixedEvent(T1 const& Collisions, if (CtrManager.isCloseTriplet()) { continue; } + TripletHistManager.setTriplet(p1, p2, p3, collision1, collision2, collision3); CtrManager.fill(TripletHistManager.getQ3()); + if (TripletHistManager.checkTripletCuts()) { + hasValidTriplet = true; + TripletHistManager.trackParticlesPerEvent(p1, p2, p3); TripletHistManager.template fill(); } } + + if (hasValidTriplet) { + ++windowSizeEffective; + } + + TripletHistManager.fillMixingQaMePerEvent(); + } + + // --- final window --- + if (windowSizeRaw > 0) { + TripletHistManager.fillMixingQaMePerMixingBin(windowSizeRaw, windowSizeEffective); } } @@ -505,19 +563,46 @@ void processMixedEvent(T1 const& Collisions, T12& CtrManager, T13& TcManager) { + int64_t lastCollisionIndex = -1; + int windowSizeRaw = 0; + int windowSizeEffective = 0; + for (auto const& [collision1, collision2, collision3] : o2::soa::selfCombinations(policy, depth, -1, Collisions, Collisions, Collisions)) { + + if (collision1.globalIndex() != lastCollisionIndex) { + if (lastCollisionIndex != -1) { + TripletHistManager.fillMixingQaMePerMixingBin(windowSizeRaw, windowSizeEffective); + } + windowSizeRaw = 0; + windowSizeEffective = 0; + lastCollisionIndex = collision1.globalIndex(); + } + + ++windowSizeRaw; + if (collision1.magField() != collision2.magField() || collision2.magField() != collision3.magField() || collision1.magField() != collision3.magField()) { + LOG(warn) << "Tried mixing events with different magnetic field."; continue; } + CtrManager.setMagField(collision1.magField()); + auto sliceParticle1 = Partition1->sliceByCached(o2::aod::femtobase::stored::fColId, collision1.globalIndex(), cache); auto sliceParticle2 = Partition2->sliceByCached(o2::aod::femtobase::stored::fColId, collision2.globalIndex(), cache); auto sliceParticle3 = Partition3->sliceByCached(o2::aod::femtobase::stored::fColId, collision3.globalIndex(), cache); + + TripletHistManager.resetTrackedParticlesPerEvent(); + if (sliceParticle1.size() == 0 || sliceParticle2.size() == 0 || sliceParticle3.size() == 0) { + TripletHistManager.fillMixingQaMePerEvent(); continue; } + + bool hasValidTriplet = false; + TripletHistManager.fillMixingQaMe(collision1, collision2, collision3); + for (auto const& [p1, p2, p3] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(sliceParticle1, sliceParticle2, sliceParticle3))) { // pair cleaning if (!TcManager.isCleanTriplet(p1, p2, p3, TrackTable)) { @@ -528,16 +613,29 @@ void processMixedEvent(T1 const& Collisions, if (CtrManager.isCloseTriplet()) { continue; } + TripletHistManager.setTripletMc(p1, p2, p3, mcParticles, collision1, collision2, collision3, mcCollisions); CtrManager.fill(TripletHistManager.getQ3()); + if (TripletHistManager.checkTripletCuts()) { + hasValidTriplet = true; + TripletHistManager.trackParticlesPerEvent(p1, p2, p3); TripletHistManager.template fill(); } } + + if (hasValidTriplet) { + ++windowSizeEffective; + } + + TripletHistManager.fillMixingQaMePerEvent(); + } + + if (windowSizeRaw > 0) { + TripletHistManager.fillMixingQaMePerMixingBin(windowSizeRaw, windowSizeEffective); } } -} // namespace tripletprocesshelpers -} // namespace o2::analysis::femto +} // namespace o2::analysis::femto::tripletprocesshelpers #endif // PWGCF_FEMTO_CORE_TRIPLETPROCESSHELPERS_H_ diff --git a/PWGCF/Femto/Core/twoTrackResonanceBuilder.h b/PWGCF/Femto/Core/twoTrackResonanceBuilder.h index 147c082fb61..126f447b7d0 100644 --- a/PWGCF/Femto/Core/twoTrackResonanceBuilder.h +++ b/PWGCF/Femto/Core/twoTrackResonanceBuilder.h @@ -33,15 +33,11 @@ #include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) #include -#include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::twotrackresonancebuilder { -namespace twotrackresonancebuilder -{ - -template +template struct ConfTwoTrackResonanceFilters : o2::framework::ConfigurableGroup { std::string prefix = Prefix; o2::framework::Configurable ptMin{"ptMin", 0.2f, "Minimum pT"}; @@ -61,20 +57,21 @@ using ConfRhoFilters = ConfTwoTrackResonanceFilters; using ConfPhiFilters = ConfTwoTrackResonanceFilters; using ConfKstarFilters = ConfTwoTrackResonanceFilters; -#define TWOTRACKRESONANCE_DEFAULT_SELECTION(defaultPdgCode, defaultMassMin, defaultMassMax) \ - o2::framework::Configurable pdgCodeAbs{"pdgCodeAbs", defaultPdgCode, "Resonance PDG code. Set sign to minus 1 for antiparticle"}; \ - o2::framework::Configurable ptMin{"ptMin", 0.f, "Minimum pT"}; \ - o2::framework::Configurable ptMax{"ptMax", 6.f, "Maximum pT"}; \ - o2::framework::Configurable etaMin{"etaMin", -0.9f, "Minimum eta"}; \ - o2::framework::Configurable etaMax{"etaMax", 0.9f, "Maximum eta"}; \ - o2::framework::Configurable phiMin{"phiMin", 0.f, "Minimum phi"}; \ - o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; \ - o2::framework::Configurable massMin{"massMin", defaultMassMin, "Minimum invariant mass for Resonance"}; \ - o2::framework::Configurable massMax{"massMax", defaultMassMax, "Maximum invariant mass for Resonance"}; \ - o2::framework::Configurable posDauMaskBelowThres{"posDauMaskBelowThres", 0x10u, "Bitmask for positive daughter below threshold"}; \ - o2::framework::Configurable posDauMaskAboveThres{"posDauMaskAboveThres", 0x8u, "Bitmask for positive daughter above threshold"}; \ - o2::framework::Configurable negDauMaskBelowThres{"negDauMaskBelowThres", 0x2u, "Bitmask for negative daughter below threshold"}; \ - o2::framework::Configurable negDauMaskAboveThres{"negDauMaskAboveThres", 0x1u, "Bitmask for negative daughter above threshold"}; +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define TWOTRACKRESONANCE_DEFAULT_SELECTION(defaultPdgCode, defaultMassMin, defaultMassMax) \ + o2::framework::Configurable pdgCodeAbs{"pdgCodeAbs", (defaultPdgCode), "Resonance PDG code. Set sign to minus 1 for antiparticle"}; \ + o2::framework::Configurable ptMin{"ptMin", 0.f, "Minimum pT"}; \ + o2::framework::Configurable ptMax{"ptMax", 6.f, "Maximum pT"}; \ + o2::framework::Configurable etaMin{"etaMin", -0.9f, "Minimum eta"}; \ + o2::framework::Configurable etaMax{"etaMax", 0.9f, "Maximum eta"}; \ + o2::framework::Configurable phiMin{"phiMin", 0.f, "Minimum phi"}; \ + o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; \ + o2::framework::Configurable massMin{"massMin", (defaultMassMin), "Minimum invariant mass for Resonance"}; \ + o2::framework::Configurable massMax{"massMax", (defaultMassMax), "Maximum invariant mass for Resonance"}; \ + o2::framework::Configurable posDauMaskBelowThres{"posDauMaskBelowThres", 0x10u, "Bitmask for positive daughter below threshold"}; \ + o2::framework::Configurable posDauMaskAboveThres{"posDauMaskAboveThres", 0x8u, "Bitmask for positive daughter above threshold"}; \ + o2::framework::Configurable negDauMaskBelowThres{"negDauMaskBelowThres", 0x2u, "Bitmask for negative daughter below threshold"}; \ + o2::framework::Configurable negDauMaskAboveThres{"negDauMaskAboveThres", 0x1u, "Bitmask for negative daughter above threshold"}; struct ConfPhiSelection : o2::framework::ConfigurableGroup { std::string prefix = std::string("PhiSelection"); @@ -205,7 +202,7 @@ class TwoTrackResonanceBuilder mMass = vecResonance.M(); } - bool checkFilters() const + [[nodiscard]] bool checkFilters() const { return ((mMass > mMassMin && mMass < mMassMax) && (mPt > mPtMin && mPt < mPtMax) && @@ -325,6 +322,5 @@ class TwoTrackResonanceBuilder }; // namespace twotrackresonancebuilder -} // namespace twotrackresonancebuilder -} // namespace o2::analysis::femto +} // namespace o2::analysis::femto::twotrackresonancebuilder #endif // PWGCF_FEMTO_CORE_TWOTRACKRESONANCEBUILDER_H_ diff --git a/PWGCF/Femto/Core/twoTrackResonanceHistManager.h b/PWGCF/Femto/Core/twoTrackResonanceHistManager.h index 561d3f5830c..a683dbf1d4c 100644 --- a/PWGCF/Femto/Core/twoTrackResonanceHistManager.h +++ b/PWGCF/Femto/Core/twoTrackResonanceHistManager.h @@ -35,9 +35,7 @@ #include #include -namespace o2::analysis::femto -{ -namespace twotrackresonancehistmanager +namespace o2::analysis::femto::twotrackresonancehistmanager { // enum for track histograms enum TwoTrackResonanceHist { @@ -46,20 +44,21 @@ enum TwoTrackResonanceHist { kEta, kPhi, kMass, + kPtVsMass, kSign, // 2d qa kPtVsEta, kPtVsPhi, kPhiVsEta, - kPtVsMass, kTwoTrackResonanceHistLast }; -#define TWOTRACKRESONANCE_DEFAULT_BINNING(defaultMassMin, defaultMassMax) \ - o2::framework::ConfigurableAxis pt{"pt", {{600, 0, 6}}, "Pt"}; \ - o2::framework::ConfigurableAxis eta{"eta", {{300, -1.5, 1.5}}, "Eta"}; \ - o2::framework::ConfigurableAxis phi{"phi", {{720, 0, 1.f * o2::constants::math::TwoPI}}, "Phi"}; \ - o2::framework::ConfigurableAxis mass{"mass", {{200, defaultMassMin, defaultMassMax}}, "Mass"}; \ +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define TWOTRACKRESONANCE_DEFAULT_BINNING(defaultMassMin, defaultMassMax) \ + o2::framework::ConfigurableAxis pt{"pt", {{600, 0, 6}}, "Pt"}; \ + o2::framework::ConfigurableAxis eta{"eta", {{300, -1.5, 1.5}}, "Eta"}; \ + o2::framework::ConfigurableAxis phi{"phi", {{720, 0, 1.f * o2::constants::math::TwoPI}}, "Phi"}; \ + o2::framework::ConfigurableAxis mass{"mass", {{200, (defaultMassMin), (defaultMassMax)}}, "Mass"}; \ o2::framework::ConfigurableAxis sign{"sign", {{3, -1.5, 1.5}}, "Sign"}; struct ConfPhiBinning : o2::framework::ConfigurableGroup { @@ -89,32 +88,40 @@ constexpr std::array, kTwoTrackReso {kPhiVsEta, o2::framework::HistType::kTH2F, "hPhiVsEta", "#varphi vs #eta; #varphi ; #eta"}, {kPtVsMass, o2::framework::HistType::kTH2F, "hPtVsMass", "p_{T} vs invariant mass; p_{T} (GeV/#it{c}); m (GeV/#it{c}^{2})"}}}; +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define TWOTRACKRESONANCE_HIST_ANALYSIS_MAP(conf) \ + {kPt, {(conf).pt}}, \ + {kEta, {(conf).eta}}, \ + {kPhi, {(conf).phi}}, \ + {kMass, {(conf).mass}}, \ + {kSign, {(conf).sign}}, \ + {kPtVsMass, {(conf).pt, (conf).mass}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define TWOTRACKRESONANCE_HIST_QA_MAP(conf) \ + {kPtVsEta, {(conf).pt, (conf).eta}}, \ + {kPtVsPhi, {(conf).pt, (conf).phi}}, \ + {kPhiVsEta, {(conf).phi, (conf).eta}}, \ + {kPtVsMass, {(conf).pt, (conf).mass}}, + template std::map> makeTwoTrackResonanceHistSpecMap(const T& confBinningAnalysis) { return std::map>{ - {kPt, {confBinningAnalysis.pt}}, - {kEta, {confBinningAnalysis.eta}}, - {kPhi, {confBinningAnalysis.phi}}, - {kMass, {confBinningAnalysis.mass}}, - {kSign, {confBinningAnalysis.sign}}}; + TWOTRACKRESONANCE_HIST_ANALYSIS_MAP(confBinningAnalysis)}; }; template auto makeTwoTrackResonanceQaHistSpecMap(const T& confBinningAnalysis) { return std::map>{ - {kPt, {confBinningAnalysis.pt}}, - {kEta, {confBinningAnalysis.eta}}, - {kPhi, {confBinningAnalysis.phi}}, - {kMass, {confBinningAnalysis.mass}}, - {kSign, {confBinningAnalysis.sign}}, - {kPtVsEta, {confBinningAnalysis.pt, confBinningAnalysis.eta}}, - {kPtVsPhi, {confBinningAnalysis.pt, confBinningAnalysis.phi}}, - {kPhiVsEta, {confBinningAnalysis.phi, confBinningAnalysis.eta}}, - {kPtVsMass, {confBinningAnalysis.pt, confBinningAnalysis.mass}}}; + TWOTRACKRESONANCE_HIST_ANALYSIS_MAP(confBinningAnalysis) + TWOTRACKRESONANCE_HIST_QA_MAP(confBinningAnalysis)}; }; +#undef TWOTRACKRESONANCE_HIST_ANALYSIS_MAP +#undef TWOTRACKRESONANCE_HIST_QA_MAP + constexpr char PrefixRho[] = "Rho0/"; constexpr char PrefixPhi[] = "Phi/"; constexpr char PrefixKstar[] = "Kstar0/"; @@ -122,9 +129,9 @@ constexpr char PrefixKstar[] = "Kstar0/"; constexpr std::string_view AnalysisDir = "Analysis/"; constexpr std::string_view QaDir = "QA/"; -template class TwoTrackResonanceHistManager { @@ -170,7 +177,7 @@ class TwoTrackResonanceHistManager mPosDauManager.template init(registry, PosDauSpecs, absCharge, signPlus, posDauPdgCodeAbs); mNegDauManager.template init(registry, NegDauSpecs, absCharge, signMinus, negDauPdgCodeAbs); - if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { initAnalysis(ResoSpecs); } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { @@ -218,7 +225,7 @@ class TwoTrackResonanceHistManager mPosDauManager.template init(registry, PosDauSpecs, absCharge, signPlus, posDauPdgCodeAbs, ConfPosDauBinningQa); mNegDauManager.template init(registry, NegDauSpecs, absCharge, signMinus, negDauPdgCodeAbs, ConfNegDauBinningQa); - if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { initAnalysis(ResoSpecs); } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { @@ -236,7 +243,7 @@ class TwoTrackResonanceHistManager mPosDauManager.template fill(posDaughter, tracks); auto negDaughter = tracks.rawIteratorAt(resonance.negDauId() - tracks.offset()); mNegDauManager.template fill(negDaughter, tracks); - if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { fillAnalysis(resonance); } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { @@ -253,6 +260,7 @@ class TwoTrackResonanceHistManager mHistogramRegistry->add(analysisDir + getHistNameV2(kPhi, HistTable), getHistDesc(kPhi, HistTable), getHistType(kPhi, HistTable), {ResoSpecs.at(kPhi)}); mHistogramRegistry->add(analysisDir + getHistNameV2(kMass, HistTable), getHistDesc(kMass, HistTable), getHistType(kMass, HistTable), {ResoSpecs.at(kMass)}); mHistogramRegistry->add(analysisDir + getHistNameV2(kSign, HistTable), getHistDesc(kSign, HistTable), getHistType(kSign, HistTable), {ResoSpecs.at(kSign)}); + mHistogramRegistry->add(analysisDir + getHistNameV2(kPtVsMass, HistTable), getHistDesc(kPtVsMass, HistTable), getHistType(kPtVsMass, HistTable), {ResoSpecs.at(kPtVsMass)}); } void initQa(std::map> const& ResoSpecs) { @@ -260,7 +268,6 @@ class TwoTrackResonanceHistManager mHistogramRegistry->add(qaDir + getHistNameV2(kPtVsEta, HistTable), getHistDesc(kPtVsEta, HistTable), getHistType(kPtVsEta, HistTable), {ResoSpecs.at(kPtVsEta)}); mHistogramRegistry->add(qaDir + getHistNameV2(kPtVsPhi, HistTable), getHistDesc(kPtVsPhi, HistTable), getHistType(kPtVsPhi, HistTable), {ResoSpecs.at(kPtVsPhi)}); mHistogramRegistry->add(qaDir + getHistNameV2(kPhiVsEta, HistTable), getHistDesc(kPhiVsEta, HistTable), getHistType(kPhiVsEta, HistTable), {ResoSpecs.at(kPhiVsEta)}); - mHistogramRegistry->add(qaDir + getHistNameV2(kPtVsMass, HistTable), getHistDesc(kPtVsMass, HistTable), getHistType(kPtVsMass, HistTable), {ResoSpecs.at(kPtVsMass)}); } template @@ -270,6 +277,7 @@ class TwoTrackResonanceHistManager mHistogramRegistry->fill(HIST(resoPrefix) + HIST(AnalysisDir) + HIST(getHistName(kEta, HistTable)), resonance.eta()); mHistogramRegistry->fill(HIST(resoPrefix) + HIST(AnalysisDir) + HIST(getHistName(kPhi, HistTable)), resonance.phi()); mHistogramRegistry->fill(HIST(resoPrefix) + HIST(AnalysisDir) + HIST(getHistName(kMass, HistTable)), resonance.mass()); + mHistogramRegistry->fill(HIST(resoPrefix) + HIST(AnalysisDir) + HIST(getHistName(kPtVsMass, HistTable)), resonance.pt(), resonance.mass()); if constexpr (modes::isEqual(reso, modes::TwoTrackResonance::kPhi) || modes::isEqual(reso, modes::TwoTrackResonance::kRho0)) { mHistogramRegistry->fill(HIST(resoPrefix) + HIST(AnalysisDir) + HIST(getHistName(kSign, HistTable)), 0); } @@ -284,7 +292,6 @@ class TwoTrackResonanceHistManager mHistogramRegistry->fill(HIST(resoPrefix) + HIST(QaDir) + HIST(getHistName(kPtVsEta, HistTable)), resonance.pt(), resonance.eta()); mHistogramRegistry->fill(HIST(resoPrefix) + HIST(QaDir) + HIST(getHistName(kPtVsPhi, HistTable)), resonance.pt(), resonance.phi()); mHistogramRegistry->fill(HIST(resoPrefix) + HIST(QaDir) + HIST(getHistName(kPhiVsEta, HistTable)), resonance.phi(), resonance.eta()); - mHistogramRegistry->fill(HIST(resoPrefix) + HIST(QaDir) + HIST(getHistName(kPtVsMass, HistTable)), resonance.pt(), resonance.mass()); } o2::framework::HistogramRegistry* mHistogramRegistry = nullptr; @@ -292,6 +299,5 @@ class TwoTrackResonanceHistManager trackhistmanager::TrackHistManager mNegDauManager; int mPdgCode = 0; }; -}; // namespace twotrackresonancehistmanager -}; // namespace o2::analysis::femto +}; // namespace o2::analysis::femto::twotrackresonancehistmanager #endif // PWGCF_FEMTO_CORE_TWOTRACKRESONANCEHISTMANAGER_H_ diff --git a/PWGCF/Femto/Core/v0Builder.h b/PWGCF/Femto/Core/v0Builder.h index 6277283f8b8..8ce1b3888bf 100644 --- a/PWGCF/Femto/Core/v0Builder.h +++ b/PWGCF/Femto/Core/v0Builder.h @@ -37,11 +37,8 @@ #include #include -namespace o2::analysis::femto +namespace o2::analysis::femto::v0builder { -namespace v0builder -{ - // filters applied in the producer task struct ConfV0Filters : o2::framework::ConfigurableGroup { std::string prefix = std::string("V0Filters"); @@ -53,15 +50,18 @@ struct ConfV0Filters : o2::framework::ConfigurableGroup { o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; o2::framework::Configurable massMinLambda{"massMinLambda", 1.f, "Minimum mass for Lambda hypothesis"}; o2::framework::Configurable massMaxLambda{"massMaxLambda", 1.2f, "Maximum mass for Lambda hypothesis"}; + o2::framework::Configurable rejectHypothesisK0short{"rejectHypothesisK0short", true, "Rejection of K0short hypothesis for Lambda candidates"}; + o2::framework::Configurable rejectMassMinK0short{"rejectMassMinK0short", 0.48f, "Minimum mass to rejection K0short hypothesis for Lambda candidates"}; + o2::framework::Configurable rejectMassMaxK0short{"rejectMassMaxK0short", 0.5f, "Maximum mass to rejection K0short hypothesis for Lambda candidates"}; o2::framework::Configurable massMinK0short{"massMinK0short", 0.45f, "Minimum mass for K0Short hypothesis"}; o2::framework::Configurable massMaxK0short{"massMaxK0short", 0.53f, "Maximum mass for K0Short hypothesis"}; + o2::framework::Configurable rejectHypothesisLambda{"rejectHypothesisLambda", true, "Rejection of Lambda hypothesis for K0short candidates"}; o2::framework::Configurable rejectMassMinLambda{"rejectMassMinLambda", 1.11f, "Minimum mass to rejection K0short hypothesis for Lambda candidates"}; o2::framework::Configurable rejectMassMaxLambda{"rejectMassMaxLambda", 1.12f, "Maximum mass to rejection K0short hypothesis for Lambda candidates"}; - o2::framework::Configurable rejectMassMinK0short{"rejectMassMinK0short", 0.48f, "Minimum mass to rejection K0short hypothesis for Lambda candidates"}; - o2::framework::Configurable rejectMassMaxK0short{"rejectMassMaxK0short", 0.5f, "Maximum mass to rejection K0short hypothesis for Lambda candidates"}; }; // selections bits for all v0s +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define V0_DEFAULT_BITS \ o2::framework::Configurable passThrough{"passThrough", false, "If true, all V0s are passed through. Bits for all selections are stored."}; \ o2::framework::Configurable> dcaDauMax{"dcaDauMax", {1.5f}, "Maximum DCA between the daughters at decay vertex (cm)"}; \ @@ -94,20 +94,21 @@ struct ConfK0shortBits : o2::framework::ConfigurableGroup { #undef V0_DEFAULT_BITS // base selection for analysis task for v0s -#define V0_DEFAULT_SELECTIONS(defaultMassMin, defaultMassMax, defaultPdgCode) \ - o2::framework::Configurable pdgCodeAbs{"pdgCodeAbs", defaultPdgCode, "PDG code. Set sign to -1 for antiparticle"}; \ - o2::framework::Configurable ptMin{"ptMin", 0.f, "Minimum pT"}; \ - o2::framework::Configurable ptMax{"ptMax", 999.f, "Maximum pT"}; \ - o2::framework::Configurable etaMin{"etaMin", -10.f, "Minimum eta"}; \ - o2::framework::Configurable etaMax{"etaMax", 10.f, "Maximum eta"}; \ - o2::framework::Configurable phiMin{"phiMin", 0.f, "Minimum eta"}; \ - o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; \ - o2::framework::Configurable massMin{"massMin", defaultMassMin, "Minimum invariant mass for Lambda"}; \ - o2::framework::Configurable massMax{"massMax", defaultMassMax, "Maximum invariant mass for Lambda"}; \ - o2::framework::Configurable mask{"mask", 0, "Bitmask for v0 selection"}; +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define V0_DEFAULT_SELECTIONS(defaultMassMin, defaultMassMax, defaultPdgCode) \ + o2::framework::Configurable pdgCodeAbs{"pdgCodeAbs", (defaultPdgCode), "PDG code. Set sign to -1 for antiparticle"}; \ + o2::framework::Configurable ptMin{"ptMin", 0.f, "Minimum pT"}; \ + o2::framework::Configurable ptMax{"ptMax", 999.f, "Maximum pT"}; \ + o2::framework::Configurable etaMin{"etaMin", -10.f, "Minimum eta"}; \ + o2::framework::Configurable etaMax{"etaMax", 10.f, "Maximum eta"}; \ + o2::framework::Configurable phiMin{"phiMin", 0.f, "Minimum eta"}; \ + o2::framework::Configurable phiMax{"phiMax", 1.f * o2::constants::math::TwoPI, "Maximum phi"}; \ + o2::framework::Configurable massMin{"massMin", (defaultMassMin), "Minimum invariant mass for Lambda"}; \ + o2::framework::Configurable massMax{"massMax", (defaultMassMax), "Maximum invariant mass for Lambda"}; \ + o2::framework::Configurable mask{"mask", 0, "Bitmask for v0 selection"}; // base selection for analysis task for lambdas -template +template struct ConfLambdaSelection : o2::framework::ConfigurableGroup { std::string prefix = Prefix; V0_DEFAULT_SELECTIONS(1.0, 1.2, 3122) @@ -115,7 +116,7 @@ struct ConfLambdaSelection : o2::framework::ConfigurableGroup { }; // base selection for analysis task for k0short -template +template struct ConfK0shortSelection : o2::framework::ConfigurableGroup { std::string prefix = Prefix; V0_DEFAULT_SELECTIONS(0.47, 0.51, 310) @@ -178,12 +179,12 @@ const std::unordered_map v0SelectionNames = { /// \class FemtoDreamTrackCuts /// \brief Cut class to contain and execute all cuts applied to tracks -template -class V0Selection : public BaseSelection +template +class V0Selection : public BaseSelection { public: V0Selection() = default; - ~V0Selection() = default; + ~V0Selection() override = default; template void configure(o2::framework::HistogramRegistry* registry, T1& config, T2& filter) @@ -200,12 +201,13 @@ class V0Selection : public BaseSelectionaddSelection(kPosDaughTpcPion, v0SelectionNames.at(kPosDaughTpcPion), config.posDauTpcPion.value, limits::kAbsUpperLimit, skipMostPermissiveBit, isMinimalCut, false); @@ -233,7 +236,7 @@ class V0Selection : public BaseSelectionaddSelection(kTransRadMin, v0SelectionNames.at(kTransRadMin), config.transRadMin.value, limits::kLowerLimit, skipMostPermissiveBit, isMinimalCut, false); this->addSelection(kTransRadMax, v0SelectionNames.at(kTransRadMax), config.transRadMax.value, limits::kUpperLimit, skipMostPermissiveBit, isMinimalCut, false); this->addSelection(kDauAbsEtaMax, v0SelectionNames.at(kDauAbsEtaMax), config.dauAbsEtaMax.value, limits::kAbsUpperLimit, skipMostPermissiveBit, isMinimalCut, false); - this->addSelection(kDauDcaMin, v0SelectionNames.at(kDauDcaMin), config.dauDcaMin.value, limits::kAbsLowerFunctionLimit, skipMostPermissiveBit, isMinimalCut, false); + this->addSelection(kDauDcaMin, v0SelectionNames.at(kDauDcaMin), config.dauDcaMin.value, limits::kAbsLowerLimit, skipMostPermissiveBit, isMinimalCut, false); this->addSelection(kDauTpcClsMin, v0SelectionNames.at(kDauTpcClsMin), config.dauTpcClustersMin.value, limits::kLowerLimit, skipMostPermissiveBit, isMinimalCut, false); this->setupContainers(registry); @@ -290,31 +293,33 @@ class V0Selection : public BaseSelection mMassLambdaLowerLimit && v0.mLambda() < mMassLambdaUpperLimit) && // inside Λ - (v0.mK0Short() < mMassK0shortLowerLimit || v0.mK0Short() > mMassK0shortUpperLimit); // outside K0s + return (v0.mLambda() > mMassLambdaLowerLimit && v0.mLambda() < mMassLambdaUpperLimit) && // inside Λ + (!mRejectK0shortHypothesis || (v0.mK0Short() < mMassK0shortLowerLimit || v0.mK0Short() > mMassK0shortUpperLimit)); // outside K0s } if constexpr (modes::isEqual(v0Type, modes::V0::kAntiLambda)) { - return (v0.mAntiLambda() > mMassLambdaLowerLimit && v0.mAntiLambda() < mMassLambdaUpperLimit) && // inside Λbar - (v0.mK0Short() < mMassK0shortLowerLimit || v0.mK0Short() > mMassK0shortUpperLimit); // outside K0s + return (v0.mAntiLambda() > mMassLambdaLowerLimit && v0.mAntiLambda() < mMassLambdaUpperLimit) && // inside Λbar + (!mRejectK0shortHypothesis || (v0.mK0Short() < mMassK0shortLowerLimit || v0.mK0Short() > mMassK0shortUpperLimit)); // outside K0s } if constexpr (modes::isEqual(v0Type, modes::V0::kK0short)) { - return (v0.mK0Short() > mMassK0shortLowerLimit && v0.mK0Short() < mMassK0shortUpperLimit) && // inside K0s - (v0.mLambda() < mMassLambdaLowerLimit || v0.mLambda() > mMassLambdaUpperLimit) && // outside Λ - (v0.mAntiLambda() < mMassLambdaLowerLimit || v0.mAntiLambda() > mMassLambdaUpperLimit); // outside Λbar + return (v0.mK0Short() > mMassK0shortLowerLimit && v0.mK0Short() < mMassK0shortUpperLimit) && // inside K0s + (!mRejectLambdaHypothesis || (v0.mLambda() < mMassLambdaLowerLimit || v0.mLambda() > mMassLambdaUpperLimit)) && // outside Λ + (!mRejectLambdaHypothesis || (v0.mAntiLambda() < mMassLambdaLowerLimit || v0.mAntiLambda() > mMassLambdaUpperLimit)); // outside Λbar } return false; } - bool passThroughAllV0s() const { return mPassThrough; } + [[nodiscard]] bool passThroughAllV0s() const { return mPassThrough; } protected: float mMassK0shortLowerLimit = 0.483f; float mMassK0shortUpperLimit = 0.503f; + bool mRejectK0shortHypothesis = false; float mMassLambdaLowerLimit = 1.105f; float mMassLambdaUpperLimit = 1.125f; + bool mRejectLambdaHypothesis = false; bool mPassThrough = false; @@ -346,7 +351,7 @@ struct ConfV0Tables : o2::framework::ConfigurableGroup { o2::framework::Configurable produceK0shortExtras{"produceK0shortExtras", -1, "Produce K0shortExtras (-1: auto; 0 off; 1 on)"}; }; -template +template class V0Builder { public: @@ -466,7 +471,8 @@ class V0Builder template void fillLambda(T1& collisionProducts, T2& v0Products, T3 const& v0, float sign, int64_t posDaughterIndex, int64_t negDaughterIndex) { - float mass, massAnti; + float mass = 0; + float massAnti = 0; if (sign > 0.f) { mass = v0.mLambda(); massAnti = v0.mAntiLambda(); @@ -527,7 +533,7 @@ class V0Builder } } - bool fillAnyTable() const { return mFillAnyTable; } + [[nodiscard]] bool fillAnyTable() const { return mFillAnyTable; } private: V0Selection mV0Selection; @@ -574,20 +580,14 @@ class V0BuilderDerivedToDerived bool collisionHasTooFewLambdas(T1 const& col, T2 const& /*lambdaTable*/, T3& partitionLambda, T4& cache) { auto lambdaSlice = partitionLambda->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); - if (lambdaSlice.size() >= mLimitLambda) { - return false; - } - return true; + return lambdaSlice.size() < mLimitLambda; } template bool collisionHasTooFewK0shorts(T1 const& col, T2 const& /*k0shortTable*/, T3& partitionK0short, T4& cache) { auto k0shortSlice = partitionK0short->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); - if (k0shortSlice.size() >= mLimitK0short) { - return false; - } - return true; + return k0shortSlice.size() < mLimitK0short; } template @@ -647,6 +647,5 @@ class V0BuilderDerivedToDerived int mLimitK0short = 0; }; -} // namespace v0builder -} // namespace o2::analysis::femto +} // namespace o2::analysis::femto::v0builder #endif // PWGCF_FEMTO_CORE_V0BUILDER_H_ diff --git a/PWGCF/Femto/Core/v0HistManager.h b/PWGCF/Femto/Core/v0HistManager.h index cdb87a09e8d..faf6d057195 100644 --- a/PWGCF/Femto/Core/v0HistManager.h +++ b/PWGCF/Femto/Core/v0HistManager.h @@ -36,9 +36,7 @@ #include #include -namespace o2::analysis::femto -{ -namespace v0histmanager +namespace o2::analysis::femto::v0histmanager { // enum for track histograms enum V0Hist { @@ -95,24 +93,26 @@ enum V0Hist { constexpr std::size_t MaxSecondary = 3; -#define V0_DEFAULT_BINNING(defaultMassMin, defaultMassMax) \ - o2::framework::ConfigurableAxis pt{"pt", {{600, 0, 6}}, "Pt"}; \ - o2::framework::ConfigurableAxis eta{"eta", {{300, -1.5, 1.5}}, "Eta"}; \ - o2::framework::ConfigurableAxis phi{"phi", {{720, 0, 1.f * o2::constants::math::TwoPI}}, "Phi"}; \ - o2::framework::ConfigurableAxis mass{"mass", {{200, defaultMassMin, defaultMassMax}}, "Mass"}; \ - o2::framework::ConfigurableAxis sign{"sign", {{3, -1.5, 1.5}}, "Sign"}; \ +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define V0_DEFAULT_BINNING(defaultMassMin, defaultMassMax) \ + o2::framework::ConfigurableAxis pt{"pt", {{600, 0, 6}}, "Pt"}; \ + o2::framework::ConfigurableAxis eta{"eta", {{300, -1.5, 1.5}}, "Eta"}; \ + o2::framework::ConfigurableAxis phi{"phi", {{720, 0, 1.f * o2::constants::math::TwoPI}}, "Phi"}; \ + o2::framework::ConfigurableAxis mass{"mass", {{200, (defaultMassMin), (defaultMassMax)}}, "Mass"}; \ + o2::framework::ConfigurableAxis sign{"sign", {{3, -1.5, 1.5}}, "Sign"}; \ o2::framework::ConfigurableAxis pdgCodes{"pdgCodes", {{8001, -4000.5, 4000.5}}, "MC ONLY: PDG codes of reconstructed V0s"}; -template +template struct ConfLambdaBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; V0_DEFAULT_BINNING(1.0, 1.2) }; -template +template struct ConfK0shortBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; V0_DEFAULT_BINNING(0.475, 0.515) }; + #undef V0_DEFAULT_BINNING constexpr const char PrefixLambdaBinning1[] = "LambdaBinning1"; @@ -120,7 +120,7 @@ using ConfLambdaBinning1 = ConfLambdaBinning; constexpr const char PrefixK0shortBinning1[] = "K0shortBinning1"; using ConfK0shortBinning1 = ConfK0shortBinning; -template +template struct ConfV0QaBinning : o2::framework::ConfigurableGroup { std::string prefix = Prefix; o2::framework::Configurable plot2d{"plot2d", true, "Generate various 2D QA plots"}; @@ -188,54 +188,58 @@ constexpr std::array, kV0HistLast> HistTable = { {kSecondaryOther, o2::framework::HistType::kTH2F, "hFromSecondaryOther", "Particles from every other secondary decay; p_{T} (GeV/#it{c}); cos(#alpha)"}}, }; +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define V0_HIST_ANALYSIS_MAP(conf) \ - {kPt, {conf.pt}}, \ - {kEta, {conf.eta}}, \ - {kPhi, {conf.phi}}, \ - {kMass, {conf.mass}}, \ - {kSign, {conf.sign}}, \ - {kPtVsMass, {conf.pt, conf.mass}}, - -#define V0_HIST_MC_MAP(conf) \ - {kTruePtVsPt, {conf.pt, conf.pt}}, \ - {kTrueEtaVsEta, {conf.eta, conf.eta}}, \ - {kTruePhiVsPhi, {conf.phi, conf.phi}}, \ - {kPdg, {conf.pdgCodes}}, \ - {kPdgMother, {conf.pdgCodes}}, \ - {kPdgPartonicMother, {conf.pdgCodes}}, - -#define V0_HIST_QA_MAP(confAnalysis, confQa) \ - {kCosPa, {confQa.cosPa}}, \ - {kDecayDauDca, {confQa.dauDcaAtDecay}}, \ - {kDecayVtxX, {confQa.decayVertex}}, \ - {kDecayVtxY, {confQa.decayVertex}}, \ - {kDecayVtxZ, {confQa.decayVertex}}, \ - {kDecayVtx, {confQa.decayVertex}}, \ - {kTransRadius, {confQa.transRadius}}, \ - {kPtVsEta, {confAnalysis.pt, confAnalysis.eta}}, \ - {kPtVsPhi, {confAnalysis.pt, confAnalysis.phi}}, \ - {kPhiVsEta, {confAnalysis.phi, confAnalysis.eta}}, \ - {kPtVsCosPa, {confAnalysis.pt, confQa.cosPa}}, \ - {kMassLambda, {confQa.massLambda}}, \ - {kMassAntiLambda, {confQa.massAntiLambda}}, \ - {kMassK0short, {confQa.massK0short}}, \ - {kPtVsLambdaMass, {confAnalysis.pt, confQa.massLambda}}, \ - {kPtVsAntiLambdaMass, {confAnalysis.pt, confQa.massAntiLambda}}, \ - {kPtVsK0shortMass, {confAnalysis.pt, confQa.massK0short}}, \ - {kLambdaMassVsAntiLambdaMass, {confQa.massLambda, confQa.massAntiLambda}}, \ - {kK0shortMassVsLambdaMass, {confQa.massK0short, confQa.massLambda}}, \ - {kK0shortMassVsAntiLambdaMass, {confQa.massK0short, confQa.massAntiLambda}}, - -#define V0_HIST_MC_QA_MAP(confAnalysis, confQa) \ - {kNoMcParticle, {confAnalysis.pt, confQa.cosPa}}, \ - {kPrimary, {confAnalysis.pt, confQa.cosPa}}, \ - {kFromWrongCollision, {confAnalysis.pt, confQa.cosPa}}, \ - {kFromMaterial, {confAnalysis.pt, confQa.cosPa}}, \ - {kMissidentified, {confAnalysis.pt, confQa.cosPa}}, \ - {kSecondary1, {confAnalysis.pt, confQa.cosPa}}, \ - {kSecondary2, {confAnalysis.pt, confQa.cosPa}}, \ - {kSecondary3, {confAnalysis.pt, confQa.cosPa}}, \ - {kSecondaryOther, {confAnalysis.pt, confQa.cosPa}}, + {kPt, {(conf).pt}}, \ + {kEta, {(conf).eta}}, \ + {kPhi, {(conf).phi}}, \ + {kMass, {(conf).mass}}, \ + {kSign, {(conf).sign}}, \ + {kPtVsMass, {(conf).pt, (conf).mass}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define V0_HIST_MC_MAP(conf) \ + {kTruePtVsPt, {(conf).pt, (conf).pt}}, \ + {kTrueEtaVsEta, {(conf).eta, (conf).eta}}, \ + {kTruePhiVsPhi, {(conf).phi, (conf).phi}}, \ + {kPdg, {(conf).pdgCodes}}, \ + {kPdgMother, {(conf).pdgCodes}}, \ + {kPdgPartonicMother, {(conf).pdgCodes}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define V0_HIST_QA_MAP(confAnalysis, confQa) \ + {kCosPa, {(confQa).cosPa}}, \ + {kDecayDauDca, {(confQa).dauDcaAtDecay}}, \ + {kDecayVtxX, {(confQa).decayVertex}}, \ + {kDecayVtxY, {(confQa).decayVertex}}, \ + {kDecayVtxZ, {(confQa).decayVertex}}, \ + {kDecayVtx, {(confQa).decayVertex}}, \ + {kTransRadius, {(confQa).transRadius}}, \ + {kPtVsEta, {(confAnalysis).pt, (confAnalysis).eta}}, \ + {kPtVsPhi, {(confAnalysis).pt, (confAnalysis).phi}}, \ + {kPhiVsEta, {(confAnalysis).phi, (confAnalysis).eta}}, \ + {kPtVsCosPa, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kMassLambda, {(confQa).massLambda}}, \ + {kMassAntiLambda, {(confQa).massAntiLambda}}, \ + {kMassK0short, {(confQa).massK0short}}, \ + {kPtVsLambdaMass, {(confAnalysis).pt, (confQa).massLambda}}, \ + {kPtVsAntiLambdaMass, {(confAnalysis).pt, (confQa).massAntiLambda}}, \ + {kPtVsK0shortMass, {(confAnalysis).pt, (confQa).massK0short}}, \ + {kLambdaMassVsAntiLambdaMass, {(confQa).massLambda, (confQa).massAntiLambda}}, \ + {kK0shortMassVsLambdaMass, {(confQa).massK0short, (confQa).massLambda}}, \ + {kK0shortMassVsAntiLambdaMass, {(confQa).massK0short, (confQa).massAntiLambda}}, + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define V0_HIST_MC_QA_MAP(confAnalysis, confQa) \ + {kNoMcParticle, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kPrimary, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kFromWrongCollision, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kFromMaterial, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kMissidentified, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kSecondary1, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kSecondary2, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kSecondary3, {(confAnalysis).pt, (confQa).cosPa}}, \ + {kSecondaryOther, {(confAnalysis).pt, (confQa).cosPa}}, template auto makeV0HistSpecMap(const T& confBinningAnalysis) @@ -291,9 +295,9 @@ constexpr std::string_view McDir = "MC/"; /// \class FemtoDreamEventHisto /// \brief Class for histogramming event properties // template -template class V0HistManager { @@ -337,7 +341,7 @@ class V0HistManager mPosDauManager.template init(registry, PosDauSpecs, absCharge, signPlus, posDauPdgCodeAbs); mNegDauManager.template init(registry, NegDauSpecs, absCharge, signMinus, negDauPdgCodeAbs); - if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { this->initAnalysis(V0Specs); } if constexpr (modes::isFlagSet(mode, modes::Mode::kMc)) { @@ -385,7 +389,7 @@ class V0HistManager mPosDauManager.template init(registry, PosDauSpecs, absCharge, signPlus, posDauPdgCode, ConfPosDauBinningQa); mNegDauManager.template init(registry, NegDauSpecs, absCharge, signMinus, negDauPdgCode, ConfNegDauBinningQa); - if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { this->initAnalysis(V0Specs); } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { @@ -404,7 +408,7 @@ class V0HistManager auto negDaughter = tracks.rawIteratorAt(v0candidate.negDauId() - tracks.offset()); mNegDauManager.template fill(negDaughter, tracks); - if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { this->fillAnalysis(v0candidate); } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { @@ -419,7 +423,7 @@ class V0HistManager mPosDauManager.template fill(posDaughter, tracks, mcParticles, mcMothers, mcPartonicMothers); auto negDaughter = tracks.rawIteratorAt(v0candidate.negDauId() - tracks.offset()); mNegDauManager.template fill(negDaughter, tracks, mcParticles, mcMothers, mcPartonicMothers); - if constexpr (modes::isFlagSet(mode, modes::Mode::kAnalysis)) { + if constexpr (modes::isFlagSet(mode, modes::Mode::kReco)) { this->fillAnalysis(v0candidate); } if constexpr (modes::isFlagSet(mode, modes::Mode::kQa)) { @@ -563,7 +567,8 @@ class V0HistManager mHistogramRegistry->fill(HIST(v0Prefix) + HIST(QaDir) + HIST(getHistName(kPtVsCosPa, HistTable)), v0candidate.pt(), v0candidate.cosPa()); if constexpr (modes::isEqual(v0, modes::V0::kLambda) || modes::isEqual(v0, modes::V0::kAntiLambda)) { - float massLambda, massAntiLambda; + float massLambda = 0; + float massAntiLambda = 0; if (v0candidate.sign() > 0) { massLambda = v0candidate.mass(); massAntiLambda = v0candidate.massAnti(); @@ -629,16 +634,16 @@ class V0HistManager mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kPdg, HistTable)), mcParticle.pdgCode()); // get mother - if (v0Candidate.has_fMcMother()) { - auto mother = v0Candidate.template fMcMother_as(); + if (mcParticle.has_fMcMother()) { + auto mother = mcParticle.template fMcMother_as(); mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kPdgMother, HistTable)), mother.pdgCode()); } else { mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kPdgMother, HistTable)), 0); } // get partonic mother - if (v0Candidate.has_fMcPartMoth()) { - auto partonicMother = v0Candidate.template fMcPartMoth_as(); + if (mcParticle.has_fMcPartMoth()) { + auto partonicMother = mcParticle.template fMcPartMoth_as(); mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kPdgPartonicMother, HistTable)), partonicMother.pdgCode()); } else { mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kPdgPartonicMother, HistTable)), 0); @@ -663,8 +668,8 @@ class V0HistManager mHistogramRegistry->fill(HIST(v0Prefix) + HIST(McDir) + HIST(getHistName(kFromMaterial, HistTable)), v0Candidate.pt(), v0Candidate.cosPa()); break; case modes::McOrigin::kFromSecondaryDecay: - if (v0Candidate.has_fMcMother()) { - auto mother = v0Candidate.template fMcMother_as(); + if (mcParticle.has_fMcMother()) { + auto mother = mcParticle.template fMcMother_as(); int motherPdgCode = std::abs(mother.pdgCode()); // Switch on PDG of the mother if (mPlotNSecondaries >= histmanager::kSecondaryPlotLevel1 && motherPdgCode == mPdgCodesSecondaryMother[0]) { @@ -697,6 +702,5 @@ class V0HistManager trackhistmanager::TrackHistManager mPosDauManager; trackhistmanager::TrackHistManager mNegDauManager; }; -}; // namespace v0histmanager -}; // namespace o2::analysis::femto +}; // namespace o2::analysis::femto::v0histmanager #endif // PWGCF_FEMTO_CORE_V0HISTMANAGER_H_ diff --git a/PWGCF/Femto/DataModel/FemtoTables.h b/PWGCF/Femto/DataModel/FemtoTables.h index 5792f152278..b47bd33f9ca 100644 --- a/PWGCF/Femto/DataModel/FemtoTables.h +++ b/PWGCF/Femto/DataModel/FemtoTables.h @@ -33,8 +33,8 @@ namespace o2::aod { namespace femtocollisions { -DECLARE_SOA_COLUMN(Mask, mask, femtodatatypes::CollisionMaskType); //! Bitmask for collision selections -DECLARE_SOA_COLUMN(CollisionTag, collisionTag, femtodatatypes::CollisionTagType); //! Bitmask for collision selections +DECLARE_SOA_COLUMN(Mask, mask, o2::analysis::femto::datatypes::CollisionMaskType); //! Bitmask for collision selections +DECLARE_SOA_COLUMN(CollisionTag, collisionTag, o2::analysis::femto::datatypes::CollisionTagType); //! Bitmask for collision selections DECLARE_SOA_COLUMN(PosX, posX, float); //! x coordinate of vertex DECLARE_SOA_COLUMN(PosY, posY, float); //! y coordinate of vertex @@ -146,7 +146,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(Theta, theta, //! theta namespace femtotracks { // columns for track selections -DECLARE_SOA_COLUMN(Mask, mask, femtodatatypes::TrackMaskType); //! Bitmask for track selections +DECLARE_SOA_COLUMN(Mask, mask, o2::analysis::femto::datatypes::TrackMaskType); //! Bitmask for track selections // columns for DCA DECLARE_SOA_COLUMN(DcaXY, dcaXY, float); //! Dca in XY plane @@ -331,11 +331,11 @@ using FTrackPids = soa::Join, - femtomccollisions::Mult, - femtomccollisions::Cent); + femtocollisions::PosZ, //! Multiplicity of the event as given by the generator in |eta|<0.8 + femtocollisions::Mult, + femtocollisions::Cent); using FMcCols = FMcCols_001; using FMcCol = FMcCols_001::iterator; namespace femtomcparticle { -DECLARE_SOA_COLUMN(Origin, origin, femtodatatypes::McOriginType); //! Multiplicity of the event as given by the generator in |eta|<0.8 -DECLARE_SOA_COLUMN(PdgCode, pdgCode, int); //! Multiplicity of the event as given by the generator in |eta|<0.8 -DECLARE_SOA_INDEX_COLUMN(FMcCol, fMcCol); //! +DECLARE_SOA_COLUMN(Origin, origin, o2::analysis::femto::datatypes::McOriginType); //! Multiplicity of the event as given by the generator in |eta|<0.8 +DECLARE_SOA_COLUMN(PdgCode, pdgCode, int); //! Multiplicity of the event as given by the generator in |eta|<0.8 +DECLARE_SOA_INDEX_COLUMN(FMcCol, fMcCol); //! } // namespace femtomcparticle // table for basic track information @@ -746,8 +747,20 @@ using FMcParticles = FMcParticles_001; using FMcParticle = FMcParticles::iterator; DECLARE_SOA_TABLE_STAGED_VERSIONED(FMcMothers_001, "FMCMOTHER", 1, //! first direct mother of the monte carlo particle - o2::soa::Index<>, - femtomcparticle::PdgCode); + o2::soa::Index<>, // no collision index needed since the mother is retrieved from the daughter mc particle + femtomcparticle::Origin, + femtomcparticle::PdgCode, + femtobase::stored::SignedPt, + femtobase::stored::Eta, + femtobase::stored::Phi, + femtobase::dynamic::Sign, + femtobase::dynamic::Pt, + femtobase::dynamic::P, + femtobase::dynamic::Px, + femtobase::dynamic::Py, + femtobase::dynamic::Pz, + femtobase::dynamic::Theta); + using FMcMothers = FMcMothers_001; using FMcMother = FMcMothers::iterator; @@ -766,41 +779,24 @@ DECLARE_SOA_INDEX_COLUMN(FMcMother, fMcMother); //! DECLARE_SOA_INDEX_COLUMN(FMcPartMoth, fMcPartMoth); //! } // namespace femtolabels -DECLARE_SOA_TABLE(FColLabels, "AOD", "FCOLMCLABEL", - femtolabels::FMcColId); +DECLARE_SOA_TABLE(FColLabels, "AOD", "FCOLMCLABEL", femtolabels::FMcColId); -DECLARE_SOA_TABLE(FTrackLabels, "AOD", "FTRACKLABEL", - femtolabels::FMcParticleId, - femtolabels::FMcMotherId, - femtolabels::FMcPartMothId); +DECLARE_SOA_TABLE(FTrackLabels, "AOD", "FTRACKLABEL", femtolabels::FMcParticleId); -DECLARE_SOA_TABLE(FLambdaLabels, "AOD", "FLAMBDALABEL", - femtolabels::FMcParticleId, - femtolabels::FMcMotherId, - femtolabels::FMcPartMothId); +DECLARE_SOA_TABLE(FLambdaLabels, "AOD", "FLAMBDALABEL", femtolabels::FMcParticleId); -DECLARE_SOA_TABLE(FK0shortLabels, "AOD", "FK0SHORTLABEL", - femtolabels::FMcParticleId, - femtolabels::FMcMotherId, - femtolabels::FMcPartMothId); +DECLARE_SOA_TABLE(FK0shortLabels, "AOD", "FK0SHORTLABEL", femtolabels::FMcParticleId); -DECLARE_SOA_TABLE(FSigmaLabels, "AOD", "FSIGMALABEL", - femtolabels::FMcParticleId, - femtolabels::FMcMotherId, - femtolabels::FMcPartMothId); +DECLARE_SOA_TABLE(FSigmaLabels, "AOD", "FSIGMALABEL", femtolabels::FMcParticleId); -DECLARE_SOA_TABLE(FSigmaPlusLabels, "AOD", "FSIGMAPLUSLABEL", - femtolabels::FMcParticleId, - femtolabels::FMcMotherId, - femtolabels::FMcPartMothId); +DECLARE_SOA_TABLE(FSigmaPlusLabels, "AOD", "FSIGMAPLUSLABEL", femtolabels::FMcParticleId); -DECLARE_SOA_TABLE(FXiLabels, "AOD", "FXILABEL", - femtolabels::FMcParticleId, - femtolabels::FMcMotherId, - femtolabels::FMcPartMothId); +DECLARE_SOA_TABLE(FXiLabels, "AOD", "FXILABEL", femtolabels::FMcParticleId); + +DECLARE_SOA_TABLE(FOmegaLabels, "AOD", "FOMEGALABEL", femtolabels::FMcParticleId); -DECLARE_SOA_TABLE(FOmegaLabels, "AOD", "FOMEGALABEL", - femtolabels::FMcParticleId, +// for mc only processing, we also need Labels pointing from mc particles to mothers and partonic mothers +DECLARE_SOA_TABLE(FMcMotherLabels, "AOD", "FMCMOTHERLABEL", femtolabels::FMcMotherId, femtolabels::FMcPartMothId); diff --git a/PWGCF/Femto/FemtoNuclei/DataModel/HadronNucleiTables.h b/PWGCF/Femto/FemtoNuclei/DataModel/HadronNucleiTables.h index c26513b6e30..ce8e83575fe 100644 --- a/PWGCF/Femto/FemtoNuclei/DataModel/HadronNucleiTables.h +++ b/PWGCF/Femto/FemtoNuclei/DataModel/HadronNucleiTables.h @@ -43,6 +43,7 @@ DECLARE_SOA_COLUMN(DcaxyNu, dcaxyNu, float); DECLARE_SOA_COLUMN(DcazNu, dcazNu, float); DECLARE_SOA_COLUMN(DcaxyHad, dcaxyHad, float); DECLARE_SOA_COLUMN(DcazHad, dcazHad, float); +DECLARE_SOA_COLUMN(DcaPair, dcaPair, float); DECLARE_SOA_COLUMN(SignalTPCNu, signalTPCNu, float); DECLARE_SOA_COLUMN(InnerParamTPCNu, innerParamTPCNu, float); @@ -51,12 +52,18 @@ DECLARE_SOA_COLUMN(InnerParamTPCHad, innerParamTPCHad, float); DECLARE_SOA_COLUMN(NClsTPCNu, nClsTPCNu, uint8_t); DECLARE_SOA_COLUMN(NSigmaTPCNu, nSigmaTPCNu, float); DECLARE_SOA_COLUMN(NSigmaTPCHad, nSigmaTPCHad, float); +DECLARE_SOA_COLUMN(NSigmaTPCHadPi, nSigmaTPCHadPi, float); +DECLARE_SOA_COLUMN(NSigmaTPCHadKa, nSigmaTPCHadKa, float); +DECLARE_SOA_COLUMN(NSigmaTPCHadPr, nSigmaTPCHadPr, float); +DECLARE_SOA_COLUMN(NSigmaTOFHadPi, nSigmaTOFHadPi, float); +DECLARE_SOA_COLUMN(NSigmaTOFHadKa, nSigmaTOFHadKa, float); +DECLARE_SOA_COLUMN(NSigmaTOFHadPr, nSigmaTOFHadPr, float); DECLARE_SOA_COLUMN(Chi2TPCNu, chi2TPCNu, float); DECLARE_SOA_COLUMN(Chi2TPCHad, chi2TPCHad, float); DECLARE_SOA_COLUMN(MassTOFNu, massTOFNu, float); DECLARE_SOA_COLUMN(MassTOFHad, massTOFHad, float); -DECLARE_SOA_COLUMN(HaddTrkNu, pidTrkNu, uint32_t); -DECLARE_SOA_COLUMN(HaddTrkHad, pidTrkHad, uint32_t); +DECLARE_SOA_COLUMN(PidTrkNu, pidTrkNu, uint32_t); +DECLARE_SOA_COLUMN(PidTrkHad, pidTrkHad, uint32_t); DECLARE_SOA_COLUMN(TrackIDHad, trackIDHad, int); DECLARE_SOA_COLUMN(TrackIDNu, trackIDNu, int); @@ -78,12 +85,39 @@ DECLARE_SOA_COLUMN(MultiplicityFT0C, multiplicityFT0C, float); } // namespace hadron_nuclei_tables DECLARE_SOA_TABLE(HadronNucleiTable, "AOD", "HADNUCLEITABLE", - hadron_nuclei_tables::PtHad, hadron_nuclei_tables::PtNu, - hadron_nuclei_tables::InnerParamTPCHad, + hadron_nuclei_tables::EtaNu, + hadron_nuclei_tables::PhiNu, + hadron_nuclei_tables::PtHad, + hadron_nuclei_tables::EtaHad, + hadron_nuclei_tables::PhiHad, + hadron_nuclei_tables::DcaxyNu, + hadron_nuclei_tables::DcazNu, + hadron_nuclei_tables::DcaxyHad, + hadron_nuclei_tables::DcazHad, + hadron_nuclei_tables::DcaPair, + hadron_nuclei_tables::SignalTPCNu, hadron_nuclei_tables::InnerParamTPCNu, - hadron_nuclei_tables::TrackIDHad, - hadron_nuclei_tables::TrackIDNu) + hadron_nuclei_tables::SignalTPCHad, + hadron_nuclei_tables::InnerParamTPCHad, + hadron_nuclei_tables::NClsTPCNu, + hadron_nuclei_tables::NSigmaTPCNu, + hadron_nuclei_tables::NSigmaTPCHadPi, + hadron_nuclei_tables::NSigmaTPCHadKa, + hadron_nuclei_tables::NSigmaTPCHadPr, + hadron_nuclei_tables::NSigmaTOFHadPi, + hadron_nuclei_tables::NSigmaTOFHadKa, + hadron_nuclei_tables::NSigmaTOFHadPr, + hadron_nuclei_tables::Chi2TPCNu, + hadron_nuclei_tables::Chi2TPCHad, + hadron_nuclei_tables::MassTOFNu, + hadron_nuclei_tables::MassTOFHad, + hadron_nuclei_tables::PidTrkNu, + hadron_nuclei_tables::PidTrkHad, + hadron_nuclei_tables::ItsClusterSizeNu, + hadron_nuclei_tables::ItsClusterSizeHad, + hadron_nuclei_tables::SharedClustersNu, + hadron_nuclei_tables::SharedClustersHad) DECLARE_SOA_TABLE(HadronHyperTable, "AOD", "HADHYPERTABLE", hadron_nuclei_tables::PtHyp, hadron_nuclei_tables::EtaHyp, @@ -103,7 +137,7 @@ DECLARE_SOA_TABLE(HadronHyperTable, "AOD", "HADHYPERTABLE", hadron_nuclei_tables::Chi2TPCHad, hadron_nuclei_tables::Chi2TPCNu, hadron_nuclei_tables::MassTOFHad, - hadron_nuclei_tables::HaddTrkHad, + hadron_nuclei_tables::PidTrkHad, hadron_nuclei_tables::ItsClusterSizeHad, hadron_nuclei_tables::ItsClusterSizeNu, hadron_nuclei_tables::SharedClustersHad, diff --git a/PWGCF/Femto/FemtoNuclei/TableProducer/HadNucleiFemto.cxx b/PWGCF/Femto/FemtoNuclei/TableProducer/HadNucleiFemto.cxx index 7d0365417e5..7d1b8580535 100644 --- a/PWGCF/Femto/FemtoNuclei/TableProducer/HadNucleiFemto.cxx +++ b/PWGCF/Femto/FemtoNuclei/TableProducer/HadNucleiFemto.cxx @@ -16,7 +16,6 @@ /// \date 2025-04-10 #include "PWGCF/Femto/FemtoNuclei/DataModel/HadronNucleiTables.h" -#include "PWGCF/FemtoWorld/Core/FemtoWorldMath.h" #include "PWGLF/DataModel/LFHypernucleiTables.h" #include "PWGLF/Utils/svPoolCreator.h" @@ -55,7 +54,10 @@ #include #include -#include +#include +#include +#include +#include #include #include @@ -64,7 +66,6 @@ #include #include #include -#include #include #include @@ -80,9 +81,19 @@ using TrackCandidates = soa::Join betheBlochParNames{"p0", "p1", "p2", "p3", "p4", "resolution"}; -static constexpr std::array tmpRadiiTPC{{85.f, 105.f, 125.f, 145.f, 165.f, 185.f, 205.f, 225.f, 245.f}}; +constexpr std::array BetheBlochDefault{-136.71, 0.441, 0.2269, 1.347, 0.8035, 0.09, + -321.34, 0.6539, 1.591, 0.8225, 2.363, 0.09}; +const std::vector betheBlochParticleNames{"De", "He3"}; +const std::vector betheBlochParNames{"p0", "p1", "p2", "p3", "p4", "resolution"}; +constexpr std::array tmpRadiiTPC{{85.f, 105.f, 125.f, 145.f, 165.f, 185.f, 205.f, 225.f, 245.f}}; +constexpr int DeuteronPDG = o2::constants::physics::Pdg::kDeuteron; +constexpr int He3PDG = o2::constants::physics::Pdg::kHelium3; +constexpr float He3RigidityMin = 0.8f; +constexpr int He3TPCNClsFoundMin = 110; +constexpr float He3TPCChi2NClMin = 0.5f; +constexpr float He3TPCNSigmaMax = 3.0f; +constexpr float He3ITSNSigmaMin = -1.5f; +using PairLorentzVector = ROOT::Math::LorentzVector>; enum Selections { kNoCuts = 0, @@ -91,18 +102,16 @@ enum Selections { kAll }; -float MassHad = 0; - } // namespace struct HadNucandidate { - float recoPtNu() const { return signNu * std::hypot(momNu[0], momNu[1]); } - float recoPhiNu() const { return std::atan2(momNu[1], momNu[0]); } - float recoEtaNu() const { return std::asinh(momNu[2] / std::abs(recoPtNu())); } - float recoPtHad() const { return signHad * std::hypot(momHad[0], momHad[1]); } - float recoPhiHad() const { return std::atan2(momHad[1], momHad[0]); } - float recoEtaHad() const { return std::asinh(momHad[2] / std::abs(recoPtHad())); } + [[nodiscard]] float recoPtNu() const { return signNu * std::hypot(momNu[0], momNu[1]); } + [[nodiscard]] float recoPhiNu() const { return std::atan2(momNu[1], momNu[0]); } + [[nodiscard]] float recoEtaNu() const { return std::asinh(momNu[2] / std::abs(recoPtNu())); } + [[nodiscard]] float recoPtHad() const { return signHad * std::hypot(momHad[0], momHad[1]); } + [[nodiscard]] float recoPhiHad() const { return std::atan2(momHad[1], momHad[0]); } + [[nodiscard]] float recoEtaHad() const { return std::asinh(momHad[2] / std::abs(recoPtHad())); } std::array momNu = {99.f, 99.f, 99.f}; std::array momHad = {99.f, 99.f, 99.f}; @@ -116,6 +125,7 @@ struct HadNucandidate { float dcazNu = -10.f; float dcaxyHad = -10.f; float dcazHad = -10.f; + float dcaPair = -10.f; uint16_t tpcSignalNu = 0u; uint16_t tpcSignalHad = 0u; @@ -128,6 +138,12 @@ struct HadNucandidate { float chi2TPCHad = -10.f; float nSigmaNu = -10.f; float nSigmaHad = -10.f; + float nSigmaTPCHadPi = -10.f; + float nSigmaTPCHadKa = -10.f; + float nSigmaTPCHadPr = -10.f; + float nSigmaTOFHadPi = -10.f; + float nSigmaTOFHadKa = -10.f; + float nSigmaTOFHadPr = -10.f; float tpcPrnsigma = -10.f; float tofPrnsigma = -10.f; uint32_t pidTrkNu = 0xFFFFF; // PID in tracking @@ -161,12 +177,12 @@ struct HadNucleiFemto { Produces mOutputMultiplicityTable; // Particle species configuration + Configurable settingNuPDGCode{"settingNuPDGCode", static_cast(DeuteronPDG), "Nucleus - PDG code"}; Configurable settingHadPDGCode{"settingHadPDGCode", 211, "Hadron - PDG code"}; // Event selection and mixing configuration Configurable settingCutVertex{"settingCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable settingNoMixedEvents{"settingNoMixedEvents", 5, "Number of mixed events per event"}; Configurable settingEnableBkgUS{"settingEnableBkgUS", false, "Enable US background"}; - Configurable settingSaferME{"settingSaferME", false, "For Safer ME"}; Configurable settingSaveUSandLS{"settingSaveUSandLS", true, "Save All Pairs"}; // Common track-quality cuts Configurable settingCutEta{"settingCutEta", 0.8f, "Eta cut on daughter track"}; @@ -175,29 +191,26 @@ struct HadNucleiFemto { Configurable settingCutChi2tpcHigh{"settingCutChi2tpcHigh", 4.f, "High cut on TPC chi2"}; Configurable settingCutChi2NClITS{"settingCutChi2NClITS", 36.f, "Maximum ITS Chi2 for tracks"}; // Hadron purity and PID cuts - Configurable settingCutHadptMin{"settingCutHadptMin", 0.14f, "Minimum PT cut on Had"}; - Configurable settingCutHadptMax{"settingCutHadptMax", 4.0f, "Maximum PT cut on Had"}; - Configurable settingCutHadDCAxyMin{"settingCutHadDCAxyMin", 0.3f, "DCAxy Min for Had"}; - Configurable settingCutHadDCAzMin{"settingCutHadDCAzMin", 0.3f, "DCAz Min for Had"}; Configurable settingCutPinMinTOFHad{"settingCutPinMinTOFHad", 0.5f, "Minimum Pin to apply the TOF cut on hadrons"}; Configurable settingCutNsigmaTPCHad{"settingCutNsigmaTPCHad", 3.0f, "Value of the TPC Nsigma cut on Had"}; Configurable settingCutNsigmaTOFHad{"settingCutNsigmaTOFHad", 3.0f, "Value of the hsdron TOF Nsigma cut"}; - Configurable settingCutNsigmaTOFTPCHad{"settingCutNsigmaTOFTPCHad", 3.0f, "Value of the hsdron TOF TPC combNsigma cut"}; Configurable settingCutNsigTPCPrMin{"settingCutNsigTPCPrMin", 3.0f, "Minimum TPC Pr Nsigma cut for rejection"}; Configurable settingCutNsigTPCPiMin{"settingCutNsigTPCPiMin", 3.0f, "Minimum TPC Pi Nsigma cut for rejection"}; - Configurable settingCutNsigTPCKaMin{"settingCutNsigTPCKaMin", 3.0f, "Minimum TPC Ka Nsigma cut for rejection"}; Configurable settingCutNsigTOFPrMin{"settingCutNsigTOFPrMin", 3.0f, "Minimum TOF Pr Nsigma cut for rejection"}; Configurable settingCutNsigTOFPiMin{"settingCutNsigTOFPiMin", 3.0f, "Minimum TOF Pi Nsigma cut for rejection"}; - Configurable settingCutNsigTOFKaMin{"settingCutNsigTOFKaMin", 3.0f, "Minimum TOF Ka Nsigma cut for rejection"}; - Configurable settingEnablePionProtonRejection{"settingEnablePionProtonRejection", true, "If true, apply proton rejection in the pion PID"}; - Configurable settingEnablePionKaonRejection{"settingEnablePionKaonRejection", true, "If true, apply kaon rejection in the pion PID"}; - Configurable settingUsePionReferencePIDCuts{"settingUsePionReferencePIDCuts", false, "If true, use the reference pion track/PID cuts from the pi-p study"}; - Configurable settingPionRefPtMin{"settingPionRefPtMin", 0.14f, "Minimum pT for the reference pion track cuts"}; - Configurable settingPionRefPtMax{"settingPionRefPtMax", 2.5f, "Maximum pT for the reference pion track cuts"}; - Configurable settingPionRefITSInnerBarrelMin{"settingPionRefITSInnerBarrelMin", 3, "Minimum ITS inner barrel clusters for the reference pion track cuts"}; - Configurable settingPionRefITSNClsMin{"settingPionRefITSNClsMin", 7, "Minimum ITS clusters for the reference pion track cuts"}; - Configurable settingPionRefTPCNClsFoundMin{"settingPionRefTPCNClsFoundMin", 80, "Minimum found TPC clusters for the reference pion track cuts"}; - Configurable settingPionRefTPCCrossedRowsMin{"settingPionRefTPCCrossedRowsMin", 90, "Minimum crossed TPC rows for the reference pion track cuts"}; + Configurable settingHadptMin{"settingHadptMin", 0.14f, "Minimum pT for the reference pion track cuts"}; + Configurable settingHadptMax{"settingHadptMax", 2.5f, "Maximum pT for the reference pion track cuts"}; + Configurable settingPionITSInnerBarrelMin{"settingPionITSInnerBarrelMin", 3, "Minimum ITS inner barrel clusters for the reference pion track cuts"}; + Configurable settingPionITSNClsMin{"settingPionITSNClsMin", 7, "Minimum ITS clusters for the reference pion track cuts"}; + Configurable settingPionTPCNClsFoundMin{"settingPionTPCNClsFoundMin", 80, "Minimum found TPC clusters for the reference pion track cuts"}; + Configurable settingPionTPCCrossedRowsMin{"settingPionTPCCrossedRowsMin", 90, "Minimum crossed TPC rows for the reference pion track cuts"}; + Configurable settingPionDCAxyOffset{"settingPionDCAxyOffset", 0.004f, "DCAxy offset for the reference pion track cuts"}; + Configurable settingPionDCAxyPtCoeff{"settingPionDCAxyPtCoeff", 0.013f, "DCAxy 1/pT coefficient for the reference pion track cuts"}; + Configurable settingPionDCAzOffset{"settingPionDCAzOffset", 0.004f, "DCAz offset for the reference pion track cuts"}; + Configurable settingPionDCAzPtCoeff{"settingPionDCAzPtCoeff", 0.013f, "DCAz 1/pT coefficient for the reference pion track cuts"}; + Configurable settingPionMomCombMin{"settingPionMomCombMin", 0.5f, "Minimum momentum to use combined TPC+TOF PID for reference pions"}; + Configurable settingPionTPCNsigMax{"settingPionTPCNsigMax", 3.0f, "Maximum TPC n-sigma for reference pions below the TOF threshold"}; + Configurable settingPionCombNsigMax{"settingPionCombNsigMax", 3.0f, "Maximum combined TPC+TOF n-sigma for reference pions"}; // Deuteron purity and PID cuts Configurable settingCutPinMinDe{"settingCutPinMinDe", 0.0f, "Minimum Pin for De"}; Configurable settingCutClSizeItsDe{"settingCutClSizeItsDe", 4.0f, "Minimum ITS cluster size for De"}; @@ -207,8 +220,9 @@ struct HadNucleiFemto { Configurable settingCutNsigmaTPCDe{"settingCutNsigmaTPCDe", 2.5f, "Value of the TPC Nsigma cut on De"}; Configurable settingCutNsigmaITSDe{"settingCutNsigmaITSDe", 2.5f, "Value of the ITD Nsigma cut on De"}; Configurable settingCutNsigmaTOFTPCDe{"settingCutNsigmaTOFTPCDe", 2.5f, "Value of the De TOF TPC combNsigma cut"}; + Configurable settingReqSingleNsig{"settingReqSingleNsig", false, "If true, also require individual TPC and TOF n-sigma cuts in branches using combined TPC+TOF PID"}; Configurable settingUseProtonMassForKstarMt{"settingUseProtonMassForKstarMt", false, "If true, use proton mass instead of deuteron mass for kstar and mT"}; - Configurable settingEnableClosePairRejection{"settingEnableClosePairRejection", false, "Enable close pair rejection for deuteron-hadron track pairs"}; + Configurable settingEnableClosePairRejection{"settingEnableClosePairRejection", false, "Enable close pair rejection for nucleus-hadron track pairs"}; Configurable settingClosePairDeltaPhiMax{"settingClosePairDeltaPhiMax", 0.01f, "Maximum delta phi star for close pair rejection"}; Configurable settingClosePairDeltaEtaMax{"settingClosePairDeltaEtaMax", 0.01f, "Maximum delta eta for close pair rejection"}; Configurable settingClosePairRadiusMode{"settingClosePairRadiusMode", 1, "Close pair rejection mode: 0 = PV, 1 = average phi star, 2 = specific TPC radius"}; @@ -231,7 +245,7 @@ struct HadNucleiFemto { Configurable settingGeoPath{"settingGeoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; Configurable settingPidPath{"settingPidPath", "", "Path to the PID response object"}; - Configurable> settingBetheBlochParams{"settingBetheBlochParams", {betheBlochDefault[0], 1, 6, {"De"}, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for De"}; + Configurable> settingBetheBlochParams{"settingBetheBlochParams", {BetheBlochDefault.data(), 2, 6, betheBlochParticleNames, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for the selected nucleus"}; Configurable settingCompensatePIDinTracking{"settingCompensatePIDinTracking", false, "If true, divide tpcInnerParam by the electric charge"}; Configurable settingMaterialCorrection{"settingMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrNONE), "Material correction type"}; @@ -247,16 +261,16 @@ struct HadNucleiFemto { SameKindPair mPair{binningPolicy, settingNoMixedEvents, -1, &cache}; // Pair hyperPair{binningPolicy, settingNoMixedEvents, -1, &cache}; - std::array mBBparamsDe; - std::vector mRecoCollisionIDs; + std::array mBBparamsNucleus{}; + float mMassHad{0.f}; std::vector mGoodCollisions; std::vector mTrackPairs; std::vector mTrackHypPairs; o2::vertexing::DCAFitterN<2> mFitter; - int mRunNumber; - float mDbz; - Service mCcdb; + int mRunNumber{0}; + float mDbz{0.f}; + Service mCcdb{}; Zorro mZorro; OutputObj mZorroSummary{"zorroSummary"}; @@ -268,18 +282,17 @@ struct HadNucleiFemto { {"hCentrality", "Centrality", {HistType::kTH1F, {{100, 0.0f, 100.0f}}}}, {"hSkipReasons", "Why storedEvent skipped;Reason;Counts", {HistType::kTH1F, {{5, -0.5, 4.5}}}}, {"hEvents", "; Events;", {HistType::kTH1F, {{3, -0.5, 2.5}}}}, - {"hEmptyPool", "svPoolCreator did not find track pairs false/true", {HistType::kTH1F, {{2, -0.5, 1.5}}}}, // Candidate topology and kinematics {"hTrackSel", "Accepted hadron tracks", {HistType::kTH1F, {{Selections::kAll, -0.5, static_cast(Selections::kAll) - 0.5}}}}, - {"hTrackSelDe", "Accepted deuteron tracks", {HistType::kTH1F, {{Selections::kAll, -0.5, static_cast(Selections::kAll) - 0.5}}}}, - {"hDePairFlow", "Deuteron pair-building flow;step;counts", {HistType::kTH1F, {{3, -0.5, 2.5}}}}, + {"hTrackSelNu", "Accepted nucleus tracks", {HistType::kTH1F, {{Selections::kAll, -0.5, static_cast(Selections::kAll) - 0.5}}}}, + {"hNuPairFlow", "Nucleus pair-building flow;step;counts", {HistType::kTH1F, {{3, -0.5, 2.5}}}}, {"hdcaxyNu", ";DCA_{xy} (cm)", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, {"hdcazNu", ";DCA_{z} (cm)", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, {"hNClsNuITS", ";N_{ITS} Cluster", {HistType::kTH1F, {{20, -10.0f, 10.0f}}}}, - {"hNuPt", "#it{p}_{T} distribution; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hSingleNuPt", "#it{p}_{T} distribution; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, + {"hNuPt", "#it{p}_{T} distribution; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{280, -7.0f, 7.0f}}}}, + {"hSingleNuPt", "#it{p}_{T} distribution; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{280, -7.0f, 7.0f}}}}, {"hNuPin", "#it{p} distribution; #it{p} (GeV/#it{c})", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, {"hSingleNuPin", "#it{p} distribution; #it{p} (GeV/#it{c})", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, {"hNuEta", "eta distribution; #eta(Nu)", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, @@ -288,8 +301,8 @@ struct HadNucleiFemto { {"hdcaxyHad", ";DCA_{xy} (cm)", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, {"hdcazHad", ";DCA_{z} (cm)", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, {"hNClsHadITS", ";N_{ITS} Cluster", {HistType::kTH1F, {{20, -10.0f, 10.0f}}}}, - {"hHadPt", "Pt distribution; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{160, -4.0f, 4.0f}}}}, - {"hSingleHadPt", "#it{p}_{T} distribution; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{120, -3.0f, 3.0f}}}}, + {"hHadPt", "Pt distribution; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{280, -7.0f, 7.0f}}}}, + {"hSingleHadPt", "#it{p}_{T} distribution; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{280, -7.0f, 7.0f}}}}, {"hHadPin", "P distribution; #it{p} (GeV/#it{c})", {HistType::kTH1F, {{120, -4.0f, 4.0f}}}}, {"hHadEta", "eta distribution; #eta(had)", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, {"hHadPhi", "phi distribution; phi(had)", {HistType::kTH1F, {{600, -4.0f, 4.0f}}}}, @@ -301,23 +314,23 @@ struct HadNucleiFemto { {"h2dEdxHadcandidates", "dEdx distribution; #it{p} (GeV/#it{c}); dE/dx (a.u.)", {HistType::kTH2F, {{200, -5.0f, 5.0f}, {100, 0.0f, 2000.0f}}}}, {"h2dEdx", "dEdx distribution; #it{p} (GeV/#it{c}); dE/dx (a.u.)", {HistType::kTH2F, {{200, -5.0f, 5.0f}, {100, 0.0f, 2000.0f}}}}, - // Deuteron PID - {"h2NsigmaNuTPC", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{100, -2.0f, 2.0f}, {200, -5.0f, 5.0f}}}}, - {"h2NsigmaNuComb", "NsigmaNu TPCTOF comb distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{comb}(Nu)", {HistType::kTH2F, {{100, -2.0f, 2.0f}, {100, 0.0f, 5.0f}}}}, - {"h2NsigmaNuTPC_preselection", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, - {"h2NsigmaNuTPC_preselecComp", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, - {"h2NSigmaNuITS_preselection", "NsigmaNu ITS distribution; signed #it{p}_{T} (GeV/#it{c}); n#sigma_{ITS} Nu", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {120, -3.0f, 3.0f}}}}, - {"h2NSigmaNuITS", "NsigmaNu ITS distribution; signed #it{p}_{T} (GeV/#it{c}); n#sigma_{ITS} Nu", {HistType::kTH2F, {{100, -2.0f, 2.0f}, {120, -3.0f, 3.0f}}}}, - {"h2NsigmaNuTOF", "NsigmaNu TOF distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(Nu)", {HistType::kTH2F, {{200, -5.0f, 5.0f}, {200, -5.0f, 5.0f}}}}, - {"h2NsigmaNuTOF_preselection", "NsigmaNu TOF distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(Nu)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, + // Nucleus PID + {"h2NsigmaNuTPC", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {200, -5.0f, 5.0f}}}}, + {"h2NsigmaNuComb", "NsigmaNu TPCTOF comb distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{comb}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {100, 0.0f, 5.0f}}}}, + {"h2NsigmaNuTPC_preselection", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, + {"h2NsigmaNuTPC_preselecComp", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, + {"h2NSigmaNuITS_preselection", "NsigmaNu ITS distribution; signed #it{p}_{T} (GeV/#it{c}); n#sigma_{ITS} Nu", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {120, -3.0f, 3.0f}}}}, + {"h2NSigmaNuITS", "NsigmaNu ITS distribution; signed #it{p}_{T} (GeV/#it{c}); n#sigma_{ITS} Nu", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {120, -3.0f, 3.0f}}}}, + {"h2NsigmaNuTOF", "NsigmaNu TOF distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {200, -5.0f, 5.0f}}}}, + {"h2NsigmaNuTOF_preselection", "NsigmaNu TOF distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, // Hadron PID - {"h2NsigmaHadComb", "NsigmaHad TPCTOF comb distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{comb}(had)", {HistType::kTH2F, {{100, -2.0f, 2.0f}, {100, 0.0f, 5.0f}}}}, - {"h2NsigmaHadTPC", "NsigmaHad TPC distribution; #it{p}_{T}(GeV/#it{c}); n#sigma_{TPC}(p)", {HistType::kTH2F, {{200, -5.0f, 5.0f}, {200, -5.0f, 5.0f}}}}, - {"h2NsigmaHadTPC_preselection", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, - {"h2NsigmaHadTOF", "NsigmaHad TOF distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(p)", {HistType::kTH2F, {{200, -5.0f, 5.0f}, {200, -5.0f, 5.0f}}}}, - {"h2NsigmaHadTOF_preselection", "NsigmaHad TOF distribution; #iit{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(p)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, - {"h2NsigmaHadComb_preselection", "NsigmaHad TPCTOF comb distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{comb}(had)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, 0.0f, 5.0f}}}}, + {"h2NsigmaHadComb", "NsigmaHad TPCTOF comb distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{comb}(had)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {100, 0.0f, 5.0f}}}}, + {"h2NsigmaHadTPC", "NsigmaHad TPC distribution; #it{p}_{T}(GeV/#it{c}); n#sigma_{TPC}(p)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {200, -5.0f, 5.0f}}}}, + {"h2NsigmaHadTPC_preselection", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, + {"h2NsigmaHadTOF", "NsigmaHad TOF distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(p)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {200, -5.0f, 5.0f}}}}, + {"h2NsigmaHadTOF_preselection", "NsigmaHad TOF distribution; #iit{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(p)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, + {"h2NsigmaHadComb_preselection", "NsigmaHad TPCTOF comb distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{comb}(had)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {100, 0.0f, 5.0f}}}}, {"h2NsigmaHadPrTPC", "NsigmaHad TPC distribution; #it{p}_{T}(GeV/#it{c}); n#sigma_{TPC}(p)", {HistType::kTH1F, {{200, -5.0f, 5.0f}}}}, {"h2NsigmaHadPiTPC", "NsigmaHad TPC distribution; #it{p}_{T}(GeV/#it{c}); n#sigma_{TPC}(pi)", {HistType::kTH1F, {{200, -5.0f, 5.0f}}}}, {"h2NsigmaHadKaTPC", "NsigmaHad TPC distribution; #it{p}_{T}(GeV/#it{c}); n#sigma_{TPC}(K)", {HistType::kTH1F, {{200, -5.0f, 5.0f}}}}, @@ -326,20 +339,19 @@ struct HadNucleiFemto { {"h2NsigmaHadKaTOF", "NsigmaHad TOF distribution; #it{p}_{T}(GeV/#it{c}); n#sigma_{TPC}(K)", {HistType::kTH1F, {{200, -5.0f, 5.0f}}}}, // Purity - {"purity/h2NsigmaNuTPC_preselection", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, - {"purity/h2NsigmaNuTPC_preselecComp", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, - {"purity/h2NSigmaNuITS_preselection", "NsigmaNu ITS distribution; signed #it{p}_{T} (GeV/#it{c}); n#sigma_{ITS} Nu", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {120, -3.0f, 3.0f}}}}, - {"purity/h2NsigmaNuTOF_preselection", "NsigmaNu TOF distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(Nu)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, - {"purity/h2NsigmaNuComb_preselection", "NsigmaNu TPCTOF comb distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{comb}(Nu)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, 0.0f, 5.0f}}}}, - {"purity/h2NsigmaHadTPC_preselection", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, - {"purity/h2NsigmaHadTOF_preselection", "NsigmaHad TOF distribution; #iit{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(p)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, - {"purity/h2NsigmaHadComb_preselection", "NsigmaHad TPCTOF comb distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{comb}(had)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, 0.0f, 5.0f}}}}, + {"purity/h2NsigmaNuTPC_preselection", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, + {"purity/h2NsigmaNuTPC_preselecComp", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, + {"purity/h2NSigmaNuITS_preselection", "NsigmaNu ITS distribution; signed #it{p}_{T} (GeV/#it{c}); n#sigma_{ITS} Nu", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {120, -3.0f, 3.0f}}}}, + {"purity/h2NsigmaNuTOF_preselection", "NsigmaNu TOF distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, + {"purity/h2NsigmaNuComb_preselection", "NsigmaNu TPCTOF comb distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{comb}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {100, 0.0f, 5.0f}}}}, + {"purity/h2NsigmaHadTPC_preselection", "NsigmaNu TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(Nu)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, + {"purity/h2NsigmaHadTOF_preselection", "NsigmaHad TOF distribution; #iit{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(p)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {400, -10.0f, 10.0f}}}}, + {"purity/h2NsigmaHadComb_preselection", "NsigmaHad TPCTOF comb distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{comb}(had)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {100, 0.0f, 5.0f}}}}, // Hypertriton - {"hHe3TPCnsigma", "NsigmaHe3 TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(He3)", {HistType::kTH2F, {{100, -2.0f, 2.0f}, {200, -5.0f, 5.0f}}}}, + {"hHe3TPCnsigma", "NsigmaHe3 TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(He3)", {HistType::kTH2F, {{280, -7.0f, 7.0f}, {200, -5.0f, 5.0f}}}}, {"hHe3P", "Pin distribution; p (GeV/#it{c})", {HistType::kTH1F, {{120, -3.0f, 3.0f}}}}, {"hHe3P_preselected", "Pin distribution_preselected; p (GeV/#it{c})", {HistType::kTH1F, {{120, -3.0f, 3.0f}}}}, - {"hNHypsPerPrevColl", "Number of V0Hypers in previous collision used for mixing;N_{V0Hypers};Entries", {HistType::kTH2F, {{4000, 0.0f, 4000.0f}, {50, -0.5, 49.5}}}}, // Correlation observables {"hkStar_LS_M", ";kStar (GeV/c)", {HistType::kTH1F, {{300, 0.0f, 3.0f}}}}, @@ -354,7 +366,7 @@ struct HadNucleiFemto { {"hkStaVsCent_LS_A", ";kStar (GeV/c);Centrality", {HistType::kTH2F, {{300, 0.0f, 3.0f}, {100, 0.0f, 100.0f}}}}, {"hkStaVsCent_US_M", ";kStar (GeV/c);Centrality", {HistType::kTH2F, {{300, 0.0f, 3.0f}, {100, 0.0f, 100.0f}}}}, {"hkStaVsCent_US_A", ";kStar (GeV/c);Centrality", {HistType::kTH2F, {{300, 0.0f, 3.0f}, {100, 0.0f, 100.0f}}}}, - {"hNuHadtInvMass", "; M(Nu + p) (GeV/#it{c}^{2})", {HistType::kTH1F, {{300, 3.74f, 4.34f}}}}, + {"hNuHadtInvMass", "; M(Nu + had) (GeV/#it{c}^{2})", {HistType::kTH1F, {{500, 2.5f, 4.5f}}}}, // Mixed-event {"hisBkgEM", "; isBkgEM;", {HistType::kTH1F, {{3, -1, 2}}}}}, @@ -362,52 +374,6 @@ struct HadNucleiFemto { false, true}; - int numOfCentBins = 40; - int numOfVertexZBins = 30; - float Vz_low = -10.0f; - float Vz_high = 10.0f; - float Vz_step = (Vz_high - Vz_low) / numOfVertexZBins; - - struct EventRef { - uint64_t collisionId; - }; - - struct PoolBin { - std::deque events; - }; - - std::vector All_Event_pool; - bool isInitialized = false; - - int nPoolBins() const { return numOfVertexZBins * numOfCentBins; } - - void initializePools() - { - All_Event_pool.clear(); - All_Event_pool.resize(nPoolBins()); - isInitialized = true; - } - - int where_pool(float vz, float v0Centr) const - { - float CentBinWidth = 100.0 / numOfCentBins; // = 2.5 - - int iy = static_cast(std::floor(v0Centr / CentBinWidth)); - if (iy < 0) - iy = 0; - if (iy >= numOfCentBins) - iy = numOfCentBins - 1; - - int ix = static_cast(std::floor((vz - Vz_low) / Vz_step)); - if (ix < 0) - ix = 0; - if (ix >= numOfVertexZBins) - ix = numOfVertexZBins - 1; - - int bin = ix + numOfVertexZBins * iy; - return bin; - } - void init(o2::framework::InitContext&) { mZorroSummary.setObject(mZorro.getZorroSummary()); @@ -429,24 +395,22 @@ struct HadNucleiFemto { mFitter.setMatCorrType(static_cast(mat)); const int numParticles = 5; + const char* betheBlochLabel = nucleusBetheBlochLabel(); for (int i = 0; i < numParticles; i++) { - mBBparamsDe[i] = settingBetheBlochParams->get("De", Form("p%i", i)); + mBBparamsNucleus[i] = settingBetheBlochParams->get(betheBlochLabel, Form("p%i", i)); } - mBBparamsDe[5] = settingBetheBlochParams->get("De", "resolution"); + mBBparamsNucleus[5] = settingBetheBlochParams->get(betheBlochLabel, "resolution"); std::vector selectionLabels = {"All", "Track selection", "PID"}; for (int i = 0; i < Selections::kAll; i++) { mQaRegistry.get(HIST("hTrackSel"))->GetXaxis()->SetBinLabel(i + 1, selectionLabels[i].c_str()); - mQaRegistry.get(HIST("hTrackSelDe"))->GetXaxis()->SetBinLabel(i + 1, selectionLabels[i].c_str()); + mQaRegistry.get(HIST("hTrackSelNu"))->GetXaxis()->SetBinLabel(i + 1, selectionLabels[i].c_str()); } - std::vector eventsLabels = {"All", "Selected", "Zorro De events"}; + std::vector eventsLabels = {"All", "Selected", "Zorro selected events"}; for (int i = 0; i < Selections::kAll; i++) { mQaRegistry.get(HIST("hEvents"))->GetXaxis()->SetBinLabel(i + 1, eventsLabels[i].c_str()); } - - mQaRegistry.get(HIST("hEmptyPool"))->GetXaxis()->SetBinLabel(1, "False"); - mQaRegistry.get(HIST("hEmptyPool"))->GetXaxis()->SetBinLabel(2, "True"); } void initCCDB(const aod::BCsWithTimestamps::iterator& bc) @@ -455,14 +419,14 @@ struct HadNucleiFemto { return; } if (settingSkimmedProcessing) { - mZorro.initCCDB(mCcdb.service, bc.runNumber(), bc.timestamp(), "fDe"); + mZorro.initCCDB(mCcdb.service, bc.runNumber(), bc.timestamp(), useHelium3Nucleus() ? "fHe" : "fDe"); mZorro.populateHistRegistry(mQaRegistry, bc.runNumber()); } mRunNumber = bc.runNumber(); const float defaultBzValue = -999.0f; auto run3GrpTimestamp = bc.timestamp(); - o2::parameters::GRPObject* grpo = mCcdb->getForTimeStamp(settingGrpPath, run3GrpTimestamp); - o2::parameters::GRPMagField* grpmag = 0x0; + auto* grpo = mCcdb->getForTimeStamp(settingGrpPath, run3GrpTimestamp); + o2::parameters::GRPMagField* grpmag = nullptr; if (grpo) { o2::base::Propagator::initFieldFromGRP(grpo); if (settingDbz < defaultBzValue) { @@ -529,40 +493,31 @@ struct HadNucleiFemto { const int minTPCNClsFound = 90; const int minTPCNClsCrossedRows = 70; const float crossedRowsToFindableRatio = 0.83f; - if (candidate.itsNCls() < settingCutNCls || - candidate.tpcNClsFound() < minTPCNClsFound || - candidate.tpcNClsCrossedRows() < minTPCNClsCrossedRows || - candidate.tpcNClsCrossedRows() < crossedRowsToFindableRatio * candidate.tpcNClsFindable() || - candidate.tpcChi2NCl() > settingCutChi2tpcHigh || - candidate.tpcChi2NCl() < settingCutChi2tpcLow || - candidate.itsChi2NCl() > settingCutChi2NClITS) { - return false; - } - - return true; - } - - bool useReferencePionCuts() const - { - return settingUsePionReferencePIDCuts.value && settingHadPDGCode.value == static_cast(PDG_t::kPiPlus); + return !(candidate.itsNCls() < settingCutNCls || + candidate.tpcNClsFound() < minTPCNClsFound || + candidate.tpcNClsCrossedRows() < minTPCNClsCrossedRows || + candidate.tpcNClsCrossedRows() < crossedRowsToFindableRatio * candidate.tpcNClsFindable() || + candidate.tpcChi2NCl() > settingCutChi2tpcHigh || + candidate.tpcChi2NCl() < settingCutChi2tpcLow || + candidate.itsChi2NCl() > settingCutChi2NClITS); } template - bool selectTrackPionReference(const Ttrack& candidate) + bool selectTrackPion(const Ttrack& candidate) { if (std::abs(candidate.eta()) > settingCutEta) { return false; } const float absPt = std::abs(candidate.pt()); - if (absPt < settingPionRefPtMin || absPt > settingPionRefPtMax) { + if (absPt < settingHadptMin || absPt > settingHadptMax) { return false; } - if (candidate.itsNClsInnerBarrel() < settingPionRefITSInnerBarrelMin || - candidate.itsNCls() < settingPionRefITSNClsMin || - candidate.tpcNClsFound() < settingPionRefTPCNClsFoundMin || - candidate.tpcNClsCrossedRows() < settingPionRefTPCCrossedRowsMin) { + if (candidate.itsNClsInnerBarrel() < settingPionITSInnerBarrelMin || + candidate.itsNCls() < settingPionITSNClsMin || + candidate.tpcNClsFound() < settingPionTPCNClsFoundMin || + candidate.tpcNClsCrossedRows() < settingPionTPCCrossedRowsMin) { return false; } @@ -570,13 +525,9 @@ struct HadNucleiFemto { return false; } - const float pionDCAxyMax = 0.004f + 0.013f / absPt; - const float pionDCAzMax = 0.004f + 0.013f / absPt; - if (std::abs(candidate.dcaXY()) > pionDCAxyMax || std::abs(candidate.dcaZ()) > pionDCAzMax) { - return false; - } - - return true; + const float pionDCAxyMax = settingPionDCAxyOffset + settingPionDCAxyPtCoeff / absPt; + const float pionDCAzMax = settingPionDCAzOffset + settingPionDCAzPtCoeff / absPt; + return !(std::abs(candidate.dcaXY()) > pionDCAxyMax || std::abs(candidate.dcaZ()) > pionDCAzMax); } template @@ -585,8 +536,8 @@ struct HadNucleiFemto { if (settingHadPDGCode.value == static_cast(PDG_t::kProton)) { return selectTrackProton(candidate); } - if (useReferencePionCuts()) { - return selectTrackPionReference(candidate); + if (settingHadPDGCode.value == static_cast(PDG_t::kPiPlus)) { + return selectTrackPion(candidate); } return selectTrack(candidate); } @@ -614,11 +565,7 @@ struct HadNucleiFemto { } const float prDCAxyMax = 105.e-3f + 30.5e-3f / std::pow(absPt, 1.1f); - if (std::abs(candidate.dcaXY()) >= prDCAxyMax || std::abs(candidate.dcaZ()) >= protonDCAzMax) { - return false; - } - - return true; + return !(std::abs(candidate.dcaXY()) >= prDCAxyMax || std::abs(candidate.dcaZ()) >= protonDCAzMax); } template @@ -636,17 +583,82 @@ struct HadNucleiFemto { constexpr int minITSNClsInnerBarrel = 1; const float tpcCrossedRowsOverFound = candidate.tpcNClsFound() > 0 ? static_cast(candidate.tpcNClsCrossedRows()) / candidate.tpcNClsFound() : 0.f; - if (candidate.tpcNClsFound() < minTPCNClsFound || - candidate.tpcNClsCrossedRows() < minTPCNClsCrossedRows || - tpcCrossedRowsOverFound < minTPCCrossedRowsOverFound || - candidate.tpcNClsShared() > maxTPCNClsShared || - candidate.tpcFractionSharedCls() > maxSharedTPCFraction || - candidate.itsNCls() < settingCutNCls || - candidate.itsNClsInnerBarrel() < minITSNClsInnerBarrel) { + return !(candidate.tpcNClsFound() < minTPCNClsFound || + candidate.tpcNClsCrossedRows() < minTPCNClsCrossedRows || + tpcCrossedRowsOverFound < minTPCCrossedRowsOverFound || + candidate.tpcNClsShared() > maxTPCNClsShared || + candidate.tpcFractionSharedCls() > maxSharedTPCFraction || + candidate.itsNCls() < settingCutNCls || + candidate.itsNClsInnerBarrel() < minITSNClsInnerBarrel); + } + + bool useDeuteronNucleus() const + { + return settingNuPDGCode.value == DeuteronPDG; + } + + bool useHelium3Nucleus() const + { + return settingNuPDGCode.value == He3PDG; + } + + const char* nucleusBetheBlochLabel() const + { + return useHelium3Nucleus() ? "He3" : "De"; + } + + float nucleusChargeFactor() const + { + return useHelium3Nucleus() ? 2.f : 1.f; + } + + float nucleusMass() const + { + if (useHelium3Nucleus()) { + return static_cast(o2::constants::physics::MassHelium3); + } + return static_cast(o2::constants::physics::MassDeuteron); + } + + template + bool selectTrackHe3(const Ttrack& candidate) + { + if (std::abs(candidate.eta()) > settingCutEta) { return false; } - return true; + constexpr int minTPCNClsCrossedRows = 70; + constexpr float crossedRowsToFindableRatio = 0.8f; + return !(candidate.itsNCls() < settingCutNCls || + candidate.tpcNClsFound() < He3TPCNClsFoundMin || + candidate.tpcNClsCrossedRows() < minTPCNClsCrossedRows || + candidate.tpcNClsCrossedRows() < crossedRowsToFindableRatio * candidate.tpcNClsFindable() || + candidate.tpcChi2NCl() > settingCutChi2tpcHigh || + candidate.tpcChi2NCl() < He3TPCChi2NClMin || + candidate.itsChi2NCl() > settingCutChi2NClITS); + } + + template + bool selectTrackNu(const Ttrack& candidate) + { + if (useHelium3Nucleus()) { + return selectTrackHe3(candidate); + } + if (useDeuteronNucleus()) { + return selectTrackDe(candidate); + } + LOG(info) << "invalid nucleus PDG code"; + return false; + } + + void fillNucleusTrackSelection(const Selections selection) + { + mQaRegistry.fill(HIST("hTrackSelNu"), selection); + } + + void fillNucleusPairFlow(const int step) + { + mQaRegistry.fill(HIST("hNuPairFlow"), step); } template @@ -669,14 +681,14 @@ struct HadNucleiFemto { } template - float averagePhiStar(const Ttrack1& track1, const Ttrack2& track2) const + float averagePhiStar(const Ttrack1& firstTrack, const Ttrack2& secondTrack) const { constexpr float invalidPhiStar = 999.f; float dPhiAvg = 0.f; int meaningfulEntries = 0; for (const auto& radius : tmpRadiiTPC) { - const float phi1 = phiAtSpecificRadiiTPC(track1, radius); - const float phi2 = phiAtSpecificRadiiTPC(track2, radius); + const float phi1 = phiAtSpecificRadiiTPC(firstTrack, radius); + const float phi2 = phiAtSpecificRadiiTPC(secondTrack, radius); if (phi1 == invalidPhiStar || phi2 == invalidPhiStar) { continue; } @@ -690,7 +702,7 @@ struct HadNucleiFemto { } template - bool isClosePair(const Ttrack1& track1, const Ttrack2& track2) + bool isClosePair(const Ttrack1& firstTrack, const Ttrack2& secondTrack) { constexpr int closePairRadiusModePv = 0; constexpr int closePairRadiusModeSpecificTpc = 2; @@ -698,14 +710,14 @@ struct HadNucleiFemto { if (!settingEnableClosePairRejection.value) { return false; } - if (track1.sign() != track2.sign()) { + if (firstTrack.sign() != secondTrack.sign()) { return false; } - const float deta = track1.eta() - track2.eta(); - const float dphiAtPV = wrapDeltaPhi(track1.phi() - track2.phi()); - const float dphiAtSpecificRadius = wrapDeltaPhi(phiAtSpecificRadiiTPC(track1, settingClosePairSpecificRadius.value) - phiAtSpecificRadiiTPC(track2, settingClosePairSpecificRadius.value)); - const float dphiAvg = averagePhiStar(track1, track2); + const float deta = firstTrack.eta() - secondTrack.eta(); + const float dphiAtPV = wrapDeltaPhi(firstTrack.phi() - secondTrack.phi()); + const float dphiAtSpecificRadius = wrapDeltaPhi(phiAtSpecificRadiiTPC(firstTrack, settingClosePairSpecificRadius.value) - phiAtSpecificRadiiTPC(secondTrack, settingClosePairSpecificRadius.value)); + const float dphiAvg = averagePhiStar(firstTrack, secondTrack); float dphiToCut = dphiAvg; if (settingClosePairRadiusMode.value == closePairRadiusModePv) { @@ -765,6 +777,10 @@ struct HadNucleiFemto { if (combNsigma > protonCombNsigmaMax) { return false; } + if (settingReqSingleNsig.value && + (std::abs(tpcNSigmaPr) > protonCombNsigmaMax || std::abs(tofNSigmaPr) > protonCombNsigmaMax)) { + return false; + } mQaRegistry.fill(HIST("h2NsigmaHadTPC"), candidate.sign() * candidate.pt(), tpcNSigmaPr); mQaRegistry.fill(HIST("h2NsigmaHadTOF"), candidate.sign() * candidate.pt(), tofNSigmaPr); @@ -779,22 +795,27 @@ struct HadNucleiFemto { auto tpcNSigmaKa = candidate.tpcNSigmaKa(); float DeDCAxyMin = 0.004 + (0.013 / candidate.pt()); float DeDCAzMin = 0.004 + (0.013 / candidate.pt()); - if (std::abs(candidate.dcaXY()) > DeDCAxyMin || std::abs(candidate.dcaZ()) > DeDCAzMin) + if (std::abs(candidate.dcaXY()) > DeDCAxyMin || std::abs(candidate.dcaZ()) > DeDCAzMin) { return false; + } mQaRegistry.fill(HIST("h2NsigmaHadTPC_preselection"), candidate.tpcInnerParam(), tpcNSigmaKa); - if (std::abs(candidate.pt()) < settingCutHadptMin || std::abs(candidate.pt()) > settingCutHadptMax) + if (std::abs(candidate.pt()) < settingHadptMin || std::abs(candidate.pt()) > settingHadptMax) { return false; + } // reject protons and pions - if (std::abs(candidate.tpcNSigmaPr()) < settingCutNsigTPCPrMin || std::abs(candidate.tpcNSigmaPi()) < settingCutNsigTPCPiMin) + if (std::abs(candidate.tpcNSigmaPr()) < settingCutNsigTPCPrMin || std::abs(candidate.tpcNSigmaPi()) < settingCutNsigTPCPiMin) { return false; + } mQaRegistry.fill(HIST("h2NsigmaHadPrTPC"), candidate.tpcNSigmaPr()); mQaRegistry.fill(HIST("h2NsigmaHadPiTPC"), candidate.tpcNSigmaPi()); - if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < settingCutNsigTOFPrMin) + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < settingCutNsigTOFPrMin) { return false; - if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < settingCutNsigTOFPiMin) + } + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < settingCutNsigTOFPiMin) { return false; + } mQaRegistry.fill(HIST("h2NsigmaHadPrTOF"), candidate.tofNSigmaPr()); mQaRegistry.fill(HIST("h2NsigmaHadPiTOF"), candidate.tofNSigmaPi()); // rejection end @@ -813,7 +834,8 @@ struct HadNucleiFemto { mQaRegistry.fill(HIST("h2NsigmaHadTOF"), candidate.sign() * candidate.pt(), tofNSigmaKa); mQaRegistry.fill(HIST("h2dEdxHadcandidates"), candidate.sign() * candidate.tpcInnerParam(), candidate.tpcSignal()); return true; - } else if (candidate.tpcInnerParam() < settingCutPinMinTOFHad) { + } + if (candidate.tpcInnerParam() < settingCutPinMinTOFHad) { if (std::abs(tpcNSigmaKa) > settingCutNsigmaTPCHad) { return false; } @@ -827,90 +849,40 @@ struct HadNucleiFemto { template bool selectionPIDPion(const Ttrack& candidate) { - if (useReferencePionCuts()) { - constexpr float pionRefPCombMin = 0.5f; - constexpr float pionRefTPCNsigmaMax = 3.0f; - constexpr float pionRefCombNsigmaMax = 3.0f; - - const float tpcNSigmaPi = candidate.tpcNSigmaPi(); - const float absP = std::abs(candidate.p()); - mQaRegistry.fill(HIST("h2NsigmaHadTPC_preselection"), candidate.sign() * candidate.tpcInnerParam(), tpcNSigmaPi); - - if (absP <= pionRefPCombMin) { - if (std::abs(tpcNSigmaPi) > pionRefTPCNsigmaMax) { - return false; - } - mQaRegistry.fill(HIST("h2NsigmaHadTPC"), candidate.sign() * candidate.pt(), tpcNSigmaPi); - mQaRegistry.fill(HIST("h2dEdxHadcandidates"), candidate.sign() * candidate.tpcInnerParam(), candidate.tpcSignal()); - return true; - } - - if (!candidate.hasTOF()) { - return false; - } + const float tpcNSigmaPi = candidate.tpcNSigmaPi(); + const float absP = std::abs(candidate.p()); + mQaRegistry.fill(HIST("h2NsigmaHadTPC_preselection"), candidate.sign() * candidate.tpcInnerParam(), tpcNSigmaPi); - const float tofNSigmaPi = candidate.tofNSigmaPi(); - const float combNsigma = std::sqrt(tofNSigmaPi * tofNSigmaPi + tpcNSigmaPi * tpcNSigmaPi); - mQaRegistry.fill(HIST("h2NsigmaHadTOF_preselection"), candidate.sign() * candidate.pt(), tofNSigmaPi); - mQaRegistry.fill(HIST("h2NsigmaHadComb_preselection"), candidate.sign() * candidate.pt(), combNsigma); - if (combNsigma > pionRefCombNsigmaMax) { + if (absP <= settingPionMomCombMin) { + if (std::abs(tpcNSigmaPi) > settingPionTPCNsigMax) { return false; } mQaRegistry.fill(HIST("h2NsigmaHadTPC"), candidate.sign() * candidate.pt(), tpcNSigmaPi); - mQaRegistry.fill(HIST("h2NsigmaHadTOF"), candidate.sign() * candidate.pt(), tofNSigmaPi); - mQaRegistry.fill(HIST("h2NsigmaHadComb"), candidate.sign() * candidate.pt(), combNsigma); mQaRegistry.fill(HIST("h2dEdxHadcandidates"), candidate.sign() * candidate.tpcInnerParam(), candidate.tpcSignal()); return true; } - if (std::abs(candidate.dcaXY()) > settingCutHadDCAxyMin || std::abs(candidate.dcaZ()) > settingCutHadDCAzMin) + if (!candidate.hasTOF()) { return false; + } - auto tpcNSigmaPi = candidate.tpcNSigmaPi(); - mQaRegistry.fill(HIST("h2NsigmaHadTPC_preselection"), candidate.sign() * candidate.tpcInnerParam(), tpcNSigmaPi); - if (std::abs(candidate.pt()) < settingCutHadptMin || std::abs(candidate.pt()) > settingCutHadptMax) - return false; - // reject protons and kaons - if (settingEnablePionProtonRejection && std::abs(candidate.tpcNSigmaPr()) < settingCutNsigTPCPrMin) - return false; - if (settingEnablePionKaonRejection && std::abs(candidate.tpcNSigmaKa()) < settingCutNsigTPCKaMin) - return false; - mQaRegistry.fill(HIST("h2NsigmaHadPrTPC"), candidate.tpcNSigmaPr()); - mQaRegistry.fill(HIST("h2NsigmaHadKaTPC"), candidate.tpcNSigmaKa()); - if (settingEnablePionProtonRejection && candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < settingCutNsigTOFPrMin) + const float tofNSigmaPi = candidate.tofNSigmaPi(); + const float combNsigma = std::sqrt(tofNSigmaPi * tofNSigmaPi + tpcNSigmaPi * tpcNSigmaPi); + mQaRegistry.fill(HIST("h2NsigmaHadTOF_preselection"), candidate.sign() * candidate.pt(), tofNSigmaPi); + mQaRegistry.fill(HIST("h2NsigmaHadComb_preselection"), candidate.sign() * candidate.pt(), combNsigma); + if (combNsigma > settingPionCombNsigMax) { return false; - if (settingEnablePionKaonRejection && candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < settingCutNsigTOFKaMin) + } + if (settingReqSingleNsig.value && + (std::abs(tpcNSigmaPi) > settingPionCombNsigMax || std::abs(tofNSigmaPi) > settingPionCombNsigMax)) { return false; - mQaRegistry.fill(HIST("h2NsigmaHadPrTOF"), candidate.tofNSigmaPr()); - if (candidate.hasTOF()) { - mQaRegistry.fill(HIST("h2NsigmaHadKaTOF"), candidate.tofNSigmaKa()); } - if (candidate.hasTOF() && std::abs(candidate.pt()) > settingCutPinMinTOFHad) { - auto tofNSigmaPi = candidate.tofNSigmaPi(); - auto combNsigma = std::sqrt(tofNSigmaPi * tofNSigmaPi + tpcNSigmaPi * tpcNSigmaPi); - - mQaRegistry.fill(HIST("h2NsigmaHadTOF_preselection"), candidate.pt(), tofNSigmaPi); - if (std::abs(tofNSigmaPi) > settingCutNsigmaTOFHad) { - return false; - } - if (std::abs(tpcNSigmaPi) > settingCutNsigmaTPCHad) { - return false; - } - mQaRegistry.fill(HIST("h2NsigmaHadTPC"), candidate.sign() * candidate.pt(), tpcNSigmaPi); - mQaRegistry.fill(HIST("h2NsigmaHadTOF"), candidate.sign() * candidate.pt(), tofNSigmaPi); - mQaRegistry.fill(HIST("h2NsigmaHadComb"), candidate.sign() * candidate.pt(), combNsigma); - mQaRegistry.fill(HIST("h2dEdxHadcandidates"), candidate.sign() * candidate.tpcInnerParam(), candidate.tpcSignal()); - return true; - } else if (std::abs(candidate.pt()) <= settingCutPinMinTOFHad) { - if (std::abs(tpcNSigmaPi) > settingCutNsigmaTPCHad) { - return false; - } - mQaRegistry.fill(HIST("h2NsigmaHadTPC"), candidate.sign() * candidate.pt(), tpcNSigmaPi); - mQaRegistry.fill(HIST("h2dEdxHadcandidates"), candidate.sign() * candidate.tpcInnerParam(), candidate.tpcSignal()); - return true; - } - return false; + mQaRegistry.fill(HIST("h2NsigmaHadTPC"), candidate.sign() * candidate.pt(), tpcNSigmaPi); + mQaRegistry.fill(HIST("h2NsigmaHadTOF"), candidate.sign() * candidate.pt(), tofNSigmaPi); + mQaRegistry.fill(HIST("h2NsigmaHadComb"), candidate.sign() * candidate.pt(), combNsigma); + mQaRegistry.fill(HIST("h2dEdxHadcandidates"), candidate.sign() * candidate.tpcInnerParam(), candidate.tpcSignal()); + return true; } template @@ -919,13 +891,13 @@ struct HadNucleiFemto { bool PID = false; if (settingHadPDGCode == PDG_t::kPiPlus) { PID = selectionPIDPion(candidate); - MassHad = o2::constants::physics::MassPiPlus; + mMassHad = o2::constants::physics::MassPiPlus; } else if (settingHadPDGCode == PDG_t::kKPlus) { PID = selectionPIDKaon(candidate); - MassHad = o2::constants::physics::MassKPlus; + mMassHad = o2::constants::physics::MassKPlus; } else if (settingHadPDGCode == PDG_t::kProton) { PID = selectionPIDProton(candidate); - MassHad = o2::constants::physics::MassProton; + mMassHad = o2::constants::physics::MassProton; } else { LOG(info) << "invalid PDG code"; } @@ -950,8 +922,24 @@ struct HadNucleiFemto { template float computeNSigmaDe(const Ttrack& candidate) { - float expTPCSignal = o2::common::BetheBlochAleph(static_cast(candidate.tpcInnerParam() / constants::physics::MassDeuteron), mBBparamsDe[0], mBBparamsDe[1], mBBparamsDe[2], mBBparamsDe[3], mBBparamsDe[4]); - double resoTPC{expTPCSignal * mBBparamsDe[5]}; + float expTPCSignal = o2::common::BetheBlochAleph(static_cast(candidate.tpcInnerParam() / constants::physics::MassDeuteron), mBBparamsNucleus[0], mBBparamsNucleus[1], mBBparamsNucleus[2], mBBparamsNucleus[3], mBBparamsNucleus[4]); + double resoTPC{expTPCSignal * mBBparamsNucleus[5]}; + return static_cast((candidate.tpcSignal() - expTPCSignal) / resoTPC); + } + + template + float correctedTPCInnerParamHe3(const Ttrack& candidate) const + { + const bool heliumPID = candidate.pidForTracking() == o2::track::PID::Helium3 || candidate.pidForTracking() == o2::track::PID::Alpha; + return (heliumPID && settingCompensatePIDinTracking.value) ? candidate.tpcInnerParam() / 2.f : candidate.tpcInnerParam(); + } + + template + float computeNSigmaHe3(const Ttrack& candidate) + { + const float correctedTPCinnerParam = correctedTPCInnerParamHe3(candidate); + float expTPCSignal = o2::common::BetheBlochAleph(static_cast(correctedTPCinnerParam * 2.f / constants::physics::MassHelium3), mBBparamsNucleus[0], mBBparamsNucleus[1], mBBparamsNucleus[2], mBBparamsNucleus[3], mBBparamsNucleus[4]); + double resoTPC{expTPCSignal * mBBparamsNucleus[5]}; return static_cast((candidate.tpcSignal() - expTPCSignal) / resoTPC); } @@ -964,7 +952,7 @@ struct HadNucleiFemto { if (std::abs(tpcInnerParam) < settingCutPinMinDe) { return false; } - float tpcNSigmaDe; + float tpcNSigmaDe = 0.f; if (settingUseBBcomputeDeNsigma) { tpcNSigmaDe = computeNSigmaDe(candidate); } else { @@ -973,16 +961,18 @@ struct HadNucleiFemto { mQaRegistry.fill(HIST("h2NsigmaNuTPC_preselection"), candidate.sign() * candidate.pt(), tpcNSigmaDe); mQaRegistry.fill(HIST("h2NsigmaNuTPC_preselecComp"), candidate.sign() * candidate.pt(), candidate.tpcNSigmaDe()); - if (std::abs(candidate.pt()) < settingCutDeptMin || std::abs(candidate.pt()) > settingCutDeptMax) + if (std::abs(candidate.pt()) < settingCutDeptMin || std::abs(candidate.pt()) > settingCutDeptMax) { return false; + } const float absPt = std::abs(candidate.pt()); if (absPt <= 0.f) { return false; } const float deDCAxyMax = 0.004f + 0.013f / absPt; const float deDCAzMax = 0.004f + 0.013f / absPt; - if (std::abs(candidate.dcaXY()) > deDCAxyMax || std::abs(candidate.dcaZ()) > deDCAzMax) + if (std::abs(candidate.dcaXY()) > deDCAxyMax || std::abs(candidate.dcaZ()) > deDCAzMax) { return false; + } if (candidate.hasTOF() && candidate.tpcInnerParam() > settingCutPinMinTOFITSDe) { auto tofNSigmaDe = candidate.tofNSigmaDe(); @@ -991,17 +981,22 @@ struct HadNucleiFemto { if (combNsigma > settingCutNsigmaTOFTPCDe) { return false; } + if (settingReqSingleNsig.value && + (std::abs(tpcNSigmaDe) > settingCutNsigmaTOFTPCDe || std::abs(tofNSigmaDe) > settingCutNsigmaTOFTPCDe)) { + return false; + } mQaRegistry.fill(HIST("h2dEdxNucandidates"), candidate.sign() * tpcInnerParam, candidate.tpcSignal()); mQaRegistry.fill(HIST("h2NsigmaNuComb"), candidate.sign() * candidate.pt(), combNsigma); mQaRegistry.fill(HIST("h2NsigmaNuTPC"), candidate.sign() * candidate.pt(), tpcNSigmaDe); mQaRegistry.fill(HIST("h2NsigmaNuTOF"), candidate.sign() * candidate.pt(), tofNSigmaDe); return true; - } else if (candidate.tpcInnerParam() <= settingCutPinMinTOFITSDe) { + } + if (candidate.tpcInnerParam() <= settingCutPinMinTOFITSDe) { if (std::abs(tpcNSigmaDe) > settingCutNsigmaTPCDe) { return false; } - o2::aod::ITSResponse mResponseITS; - auto itsnSigmaDe = mResponseITS.nSigmaITS(candidate.itsClusterSizes(), candidate.p(), candidate.eta()); + o2::aod::ITSResponse itsResponse; + auto itsnSigmaDe = itsResponse.nSigmaITS(candidate.itsClusterSizes(), candidate.p(), candidate.eta()); mQaRegistry.fill(HIST("h2NSigmaNuITS_preselection"), candidate.sign() * candidate.pt(), itsnSigmaDe); if (std::abs(itsnSigmaDe) > settingCutNsigmaITSDe) { return false; @@ -1014,6 +1009,56 @@ struct HadNucleiFemto { return false; } + template + bool selectionPIDHe3(const Ttrack& candidate) + { + const float correctedTPCinnerParam = correctedTPCInnerParamHe3(candidate); + mQaRegistry.fill(HIST("h2dEdx"), candidate.sign() * correctedTPCinnerParam, candidate.tpcSignal()); + + if (correctedTPCinnerParam < He3RigidityMin) { + return false; + } + + const float nSigmaHe3 = computeNSigmaHe3(candidate); + mQaRegistry.fill(HIST("h2NsigmaNuTPC_preselection"), candidate.sign() * 2.f * candidate.pt(), nSigmaHe3); + if (std::abs(nSigmaHe3) > He3TPCNSigmaMax) { + return false; + } + + o2::aod::ITSResponse itsResponse; + const float itsNsigmaHe3 = itsResponse.nSigmaITS(candidate.itsClusterSizes(), 2.f * candidate.p(), candidate.eta()); + mQaRegistry.fill(HIST("h2NSigmaNuITS_preselection"), candidate.sign() * 2.f * candidate.pt(), itsNsigmaHe3); + if (itsNsigmaHe3 < He3ITSNSigmaMin) { + return false; + } + + mQaRegistry.fill(HIST("h2dEdxNucandidates"), candidate.sign() * correctedTPCinnerParam, candidate.tpcSignal()); + mQaRegistry.fill(HIST("h2NsigmaNuTPC"), candidate.sign() * 2.f * candidate.pt(), nSigmaHe3); + mQaRegistry.fill(HIST("h2NSigmaNuITS"), candidate.sign() * 2.f * candidate.pt(), itsNsigmaHe3); + return true; + } + + template + bool selectionPIDNu(const Ttrack& candidate) + { + if (useHelium3Nucleus()) { + return selectionPIDHe3(candidate); + } + if (useDeuteronNucleus()) { + return selectionPIDDe(candidate); + } + return false; + } + + template + float getNucleusTPCNSigma(const Ttrack& candidate) + { + if (useHelium3Nucleus()) { + return computeNSigmaHe3(candidate); + } + return computeNSigmaDe(candidate); + } + float averageClusterSizeCosl(uint32_t itsClusterSizes, float eta) { float average = 0; @@ -1022,7 +1067,7 @@ struct HadNucleiFemto { const int nlayerITS = 7; for (int layer = 0; layer < nlayerITS; layer++) { - if ((itsClusterSizes >> (layer * 4)) & 0xf) { + if (((itsClusterSizes >> (layer * 4)) & 0xf) != 0u) { nclusters++; average += (itsClusterSizes >> (layer * 4)) & 0xf; } @@ -1049,6 +1094,37 @@ struct HadNucleiFemto { return true; } + float computePairKstar(const std::array& momHad, const float massHad, const std::array& momNu, const float massNu) const + { + const PairLorentzVector vecHad(momHad[0], momHad[1], momHad[2], massHad); + const PairLorentzVector vecNu(momNu[0], momNu[1], momNu[2], massNu); + const PairLorentzVector trackSum = vecHad + vecNu; + + const float beta = trackSum.Beta(); + const float betax = beta * std::cos(trackSum.Phi()) * std::sin(trackSum.Theta()); + const float betay = beta * std::sin(trackSum.Phi()) * std::sin(trackSum.Theta()); + const float betaz = beta * std::cos(trackSum.Theta()); + + PairLorentzVector partHadCMS(vecHad); + PairLorentzVector partNuCMS(vecNu); + + const ROOT::Math::Boost boostPRF = ROOT::Math::Boost(-betax, -betay, -betaz); + partHadCMS = boostPRF(partHadCMS); + partNuCMS = boostPRF(partNuCMS); + + const PairLorentzVector trackRelK = partHadCMS - partNuCMS; + return 0.5f * trackRelK.P(); + } + + float computePairMT(const std::array& momHad, const float massHad, const std::array& momNu, const float massNu) const + { + const PairLorentzVector vecHad(momHad[0], momHad[1], momHad[2], massHad); + const PairLorentzVector vecNu(momNu[0], momNu[1], momNu[2], massNu); + const PairLorentzVector trackSum = vecHad + vecNu; + const float kT = 0.5f * trackSum.Pt(); + return std::sqrt(kT * kT + std::pow(0.5f * (massHad + massNu), 2.f)); + } + // ================================================================================================================== template @@ -1070,6 +1146,7 @@ struct HadNucleiFemto { mQaRegistry.fill(HIST("hSkipReasons"), 1); return false; } + hadNucand.dcaPair = std::sqrt(std::abs(mFitter.getChi2AtPCACandidate())); // associate collision id as the one that minimises the distance between the vertex and the PCAs of the daughters double distanceMin = -1; @@ -1098,10 +1175,14 @@ struct HadNucleiFemto { hadNucand.collisionID = collBracket.getMin(); } + const float nuChargeFactor = nucleusChargeFactor(); hadNucand.momNu = std::array{trackDe.px(), trackDe.py(), trackDe.pz()}; + for (auto i = 0u; i < hadNucand.momNu.size(); ++i) { + hadNucand.momNu[i] *= nuChargeFactor; + } hadNucand.momHad = std::array{trackHad.px(), trackHad.py(), trackHad.pz()}; float invMass = 0; - invMass = RecoDecay::m(std::array, 2>{hadNucand.momNu, hadNucand.momHad}, std::array{static_cast(o2::constants::physics::MassDeuteron), MassHad}); + invMass = RecoDecay::m(std::array, 2>{hadNucand.momNu, hadNucand.momHad}, std::array{nucleusMass(), mMassHad}); hadNucand.signNu = trackDe.sign(); hadNucand.signHad = trackHad.sign(); @@ -1113,13 +1194,19 @@ struct HadNucleiFemto { hadNucand.dcazHad = trackHad.dcaZ(); hadNucand.tpcSignalNu = trackDe.tpcSignal(); - hadNucand.momNuTPC = trackDe.tpcInnerParam(); + hadNucand.momNuTPC = useHelium3Nucleus() ? correctedTPCInnerParamHe3(trackDe) : trackDe.tpcInnerParam(); hadNucand.tpcSignalHad = trackHad.tpcSignal(); hadNucand.momHadTPC = trackHad.tpcInnerParam(); hadNucand.nTPCClustersNu = trackDe.tpcNClsFound(); - hadNucand.nSigmaNu = computeNSigmaDe(trackDe); + hadNucand.nSigmaNu = getNucleusTPCNSigma(trackDe); hadNucand.nSigmaHad = getHadronTPCNSigma(trackHad); + hadNucand.nSigmaTPCHadPi = trackHad.tpcNSigmaPi(); + hadNucand.nSigmaTPCHadKa = trackHad.tpcNSigmaKa(); + hadNucand.nSigmaTPCHadPr = trackHad.tpcNSigmaPr(); + hadNucand.nSigmaTOFHadPi = trackHad.tofNSigmaPi(); + hadNucand.nSigmaTOFHadKa = trackHad.tofNSigmaKa(); + hadNucand.nSigmaTOFHadPr = trackHad.tofNSigmaPr(); hadNucand.chi2TPCNu = trackDe.tpcChi2NCl(); hadNucand.chi2TPCHad = trackHad.tpcChi2NCl(); @@ -1147,8 +1234,7 @@ struct HadNucleiFemto { if (trackDe.hasTOF()) { float beta = o2::pid::tof::Beta::GetBeta(trackDe); beta = std::min(1.f - 1.e-6f, std::max(1.e-4f, beta)); /// sometimes beta > 1 or < 0, to be checked - float tpcInnerParamDe = trackDe.tpcInnerParam(); - hadNucand.massTOFNu = tpcInnerParamDe * std::sqrt(1.f / (beta * beta) - 1.f); + hadNucand.massTOFNu = hadNucand.momNuTPC * nuChargeFactor * std::sqrt(1.f / (beta * beta) - 1.f); } if (trackHad.hasTOF()) { float beta = o2::pid::tof::Beta::GetBeta(trackHad); @@ -1156,9 +1242,9 @@ struct HadNucleiFemto { hadNucand.massTOFHad = trackHad.tpcInnerParam() * std::sqrt(1.f / (beta * beta) - 1.f); } - const float massLightNucleusForKstarMt = settingUseProtonMassForKstarMt ? static_cast(o2::constants::physics::MassProton) : static_cast(o2::constants::physics::MassDeuteron); - hadNucand.kstar = o2::analysis::femtoWorld::FemtoWorldMath::getkstar(trackHad, MassHad, trackDe, massLightNucleusForKstarMt); - hadNucand.mT = o2::analysis::femtoWorld::FemtoWorldMath::getmT(trackHad, MassHad, trackDe, massLightNucleusForKstarMt); + const float massLightNucleusForKstarMt = useHelium3Nucleus() ? static_cast(o2::constants::physics::MassHelium3) : (settingUseProtonMassForKstarMt ? static_cast(o2::constants::physics::MassProton) : static_cast(o2::constants::physics::MassDeuteron)); + hadNucand.kstar = computePairKstar(hadNucand.momHad, mMassHad, hadNucand.momNu, massLightNucleusForKstarMt); + hadNucand.mT = computePairMT(hadNucand.momHad, mMassHad, hadNucand.momNu, massLightNucleusForKstarMt); return true; } @@ -1190,7 +1276,7 @@ struct HadNucleiFemto { hadHypercand.momHad = std::array{trackHad.px(), trackHad.py(), trackHad.pz()}; float invMass = 0; - invMass = RecoDecay::m(std::array, 2>{hadHypercand.momNu, hadHypercand.momHad}, std::array{static_cast(o2::constants::physics::MassHelium3), MassHad}); + invMass = RecoDecay::m(std::array, 2>{hadHypercand.momNu, hadHypercand.momHad}, std::array{static_cast(o2::constants::physics::MassHelium3), mMassHad}); hadHypercand.signHad = trackHad.sign(); if (V0Hyper.isMatter()) { @@ -1235,19 +1321,22 @@ struct HadNucleiFemto { for (const auto& track0 : tracks) { mQaRegistry.fill(HIST("hTrackSel"), Selections::kNoCuts); + fillNucleusTrackSelection(Selections::kNoCuts); - if (!selectTrackDe(track0)) { + if (!selectTrackNu(track0)) { continue; } mQaRegistry.fill(HIST("hTrackSel"), Selections::kTrackCuts); + fillNucleusTrackSelection(Selections::kTrackCuts); - if (!selectionPIDDe(track0)) { + if (!selectionPIDNu(track0)) { continue; } mQaRegistry.fill(HIST("hTrackSel"), Selections::kPID); - mQaRegistry.fill(HIST("hSingleNuPt"), track0.pt() * track0.sign()); - mQaRegistry.fill(HIST("hSingleNuPin"), track0.tpcInnerParam() * track0.sign()); - mQaRegistry.fill(HIST("hDePairFlow"), 0); + fillNucleusTrackSelection(Selections::kPID); + mQaRegistry.fill(HIST("hSingleNuPt"), track0.pt() * track0.sign() * nucleusChargeFactor()); + mQaRegistry.fill(HIST("hSingleNuPin"), (useHelium3Nucleus() ? correctedTPCInnerParamHe3(track0) : track0.tpcInnerParam()) * track0.sign()); + fillNucleusPairFlow(0); bool hasHadronSelected = false; bool hasStoredPair = false; @@ -1285,10 +1374,10 @@ struct HadNucleiFemto { } if (hasHadronSelected) { - mQaRegistry.fill(HIST("hDePairFlow"), 1); + fillNucleusPairFlow(1); } if (hasStoredPair) { - mQaRegistry.fill(HIST("hDePairFlow"), 2); + fillNucleusPairFlow(2); } } } @@ -1329,7 +1418,7 @@ struct HadNucleiFemto { void pairTracksEventMixing(T& DeCands, T& hadCands) { for (const auto& DeCand : DeCands) { - if (!selectTrackDe(DeCand) || !selectionPIDDe(DeCand)) { + if (!selectTrackNu(DeCand) || !selectionPIDNu(DeCand)) { continue; } for (const auto& hadCand : hadCands) { @@ -1351,39 +1440,43 @@ struct HadNucleiFemto { } } - template - void pairHyperEventMixing(T1& hadCands, T2& hypCands) - { - for (const auto& hypCand : hypCands) { - if (!selectionPIDHyper(hypCand)) { - continue; - } - for (const auto& hadCand : hadCands) { - if (!selectTrackHadron(hadCand) || !selectionPIDHadron(hadCand)) { - continue; - } - - SVCand pair; - pair.tr0Idx = hypCand.globalIndex(); - pair.tr1Idx = hadCand.globalIndex(); - const int collIdx = hypCand.collisionId(); - CollBracket collBracket{collIdx, collIdx}; - pair.collBracket = collBracket; - mTrackHypPairs.push_back(pair); - } - } - } - template void fillTable(const HadNucandidate& hadNucand, const Tcoll& collision) { mOutputDataTable( - hadNucand.recoPtHad(), hadNucand.recoPtNu(), - hadNucand.momHadTPC, + hadNucand.recoEtaNu(), + hadNucand.recoPhiNu(), + hadNucand.recoPtHad(), + hadNucand.recoEtaHad(), + hadNucand.recoPhiHad(), + hadNucand.dcaxyNu, + hadNucand.dcazNu, + hadNucand.dcaxyHad, + hadNucand.dcazHad, + hadNucand.dcaPair, + hadNucand.tpcSignalNu, hadNucand.momNuTPC, - hadNucand.trackIDHad, - hadNucand.trackIDNu); + hadNucand.tpcSignalHad, + hadNucand.momHadTPC, + hadNucand.nTPCClustersNu, + hadNucand.nSigmaNu, + hadNucand.nSigmaTPCHadPi, + hadNucand.nSigmaTPCHadKa, + hadNucand.nSigmaTPCHadPr, + hadNucand.nSigmaTOFHadPi, + hadNucand.nSigmaTOFHadKa, + hadNucand.nSigmaTOFHadPr, + hadNucand.chi2TPCNu, + hadNucand.chi2TPCHad, + hadNucand.massTOFNu, + hadNucand.massTOFHad, + hadNucand.pidTrkNu, + hadNucand.pidTrkHad, + hadNucand.itsClSizeNu, + hadNucand.itsClSizeHad, + hadNucand.sharedClustersNu, + hadNucand.sharedClustersHad); if (settingFillMultiplicity) { mOutputMultiplicityTable( collision.globalIndex(), @@ -1557,7 +1650,7 @@ struct HadNucleiFemto { pairTracksSameEvent(trackTableThisCollision, collision.centFT0C()); - if (mTrackPairs.size() == 0) { + if (mTrackPairs.empty()) { continue; } @@ -1589,7 +1682,7 @@ struct HadNucleiFemto { pairTracksSameEventHyper(trackTableThisCollision, hypdTableThisCollision); - if (mTrackHypPairs.size() == 0) { + if (mTrackHypPairs.empty()) { continue; } @@ -1619,91 +1712,8 @@ struct HadNucleiFemto { } PROCESS_SWITCH(HadNucleiFemto, processMixedEvent, "Process Mixed event", false); - /*void processMixedEventHyper(const CollisionsFull& collisions, o2::aod::DataHypCandsWColl const& V0Hypers, const TrackCandidates& hadtracks) - { - LOG(debug) << "Processing mixed event for hypertriton"; - mTrackHypPairs.clear(); - - for (const auto& [c1, tracks1, c2, V0Hypers2] : hyperPair) { - if (!c1.sel8() || !c2.sel8()) { - continue; - } - - mQaRegistry.fill(HIST("hNcontributor"), c2.numContrib()); - //mQaRegistry.fill(HIST("hCentrality"), c2.centFT0C()); - mQaRegistry.fill(HIST("hVtxZ"), c2.posZ()); - - pairHyperEventMixing(tracks1, V0Hypers2); - } -} -PROCESS_SWITCH(HadNucleiFemto, processMixedEventHyper, "Process Mixed event", false);*/ - - void processMixedEventHyperPool(const CollisionsFull& collisions, o2::aod::DataHypCandsWColl const& V0Hypers, const TrackCandidates& hadtracks) - { - mTrackHypPairs.clear(); - if (!isInitialized) { - initializePools(); - LOG(info) << "Initialized event pool with size = " << All_Event_pool.size(); - } - for (auto const& collision : collisions) { - if (!collision.sel8()) { - mQaRegistry.fill(HIST("hSkipReasons"), 0); - continue; - } - mQaRegistry.fill(HIST("hNcontributor"), collision.numContrib()); - mQaRegistry.fill(HIST("hCentrality"), collision.centFT0C()); - mQaRegistry.fill(HIST("hVtxZ"), collision.posZ()); - - int poolIndexHad = where_pool(collision.posZ(), collision.centFT0C()); - if (poolIndexHad < 0 || static_cast(poolIndexHad) >= All_Event_pool.size()) { - continue; - } - auto& pool = All_Event_pool[poolIndexHad]; - - const uint64_t collIdxHad = collision.globalIndex(); - auto trackTableThisCollision = hadtracks.sliceBy(mPerCol, collIdxHad); - trackTableThisCollision.bindExternalIndices(&hadtracks); - - for (auto const& storedEvent : pool.events) { - const uint64_t collIdxHyp = storedEvent.collisionId; - if (settingSaferME) { - if (static_cast(collIdxHyp) > collisions.size()) { - mQaRegistry.fill(HIST("hSkipReasons"), 4); - continue; - } - } - - auto hypdTablepreviousCollision = V0Hypers.sliceBy(hypPerCol, collIdxHyp); - hypdTablepreviousCollision.bindExternalIndices(&V0Hypers); - if (hypdTablepreviousCollision.size() == 0) { - mQaRegistry.fill(HIST("hSkipReasons"), 1); - continue; - } - - auto firstHyp = hypdTablepreviousCollision.iteratorAt(0); - int poolIndexHyp = where_pool(firstHyp.zPrimVtx(), firstHyp.centralityFT0C()); - if (poolIndexHyp != poolIndexHad) { - mQaRegistry.fill(HIST("hSkipReasons"), 2); - continue; - } - mQaRegistry.fill(HIST("hNHypsPerPrevColl"), collIdxHyp, hypdTablepreviousCollision.size()); - - pairHyperEventMixing(trackTableThisCollision, hypdTablepreviousCollision); - } - - if (static_cast(pool.events.size()) >= settingNoMixedEvents) { - pool.events.pop_front(); - } - pool.events.push_back({collIdxHad}); - } - fillPairsHyper(collisions, hadtracks, V0Hypers, /*isMixedEvent*/ true); - } - PROCESS_SWITCH(HadNucleiFemto, processMixedEventHyperPool, "Process Mixed event", false); - void processPurity(const CollisionsFull& collisions, const TrackCandidates& tracks, const aod::BCsWithTimestamps& bcs) { - o2::aod::ITSResponse itsResponse; - for (const auto& collision : collisions) { if (!selectCollision(collision, bcs)) { continue; @@ -1714,24 +1724,23 @@ PROCESS_SWITCH(HadNucleiFemto, processMixedEventHyper, "Process Mixed event", fa trackTableThisCollision.bindExternalIndices(&tracks); for (const auto& track : trackTableThisCollision) { - constexpr float pionRefPCombMin = 0.5f; const bool passTrackHad = selectTrackHadron(track); - const bool passTrackDe = selectTrackDe(track); + const bool passTrackNu = selectTrackNu(track); mQaRegistry.fill(HIST("hTrackSel"), Selections::kNoCuts); if (passTrackHad) { mQaRegistry.fill(HIST("hTrackSel"), Selections::kTrackCuts); } - mQaRegistry.fill(HIST("hTrackSelDe"), Selections::kNoCuts); - if (passTrackDe) { - mQaRegistry.fill(HIST("hTrackSelDe"), Selections::kTrackCuts); + fillNucleusTrackSelection(Selections::kNoCuts); + if (passTrackNu) { + fillNucleusTrackSelection(Selections::kTrackCuts); } if (passTrackHad && settingHadPDGCode == PDG_t::kPiPlus) { const float tpcNSigmaHad = track.tpcNSigmaPi(); mQaRegistry.fill(HIST("purity/h2NsigmaHadTPC_preselection"), track.sign() * track.pt(), tpcNSigmaHad); - if (useReferencePionCuts() ? (track.hasTOF() && std::abs(track.p()) > pionRefPCombMin) : (track.hasTOF() && std::abs(track.pt()) > settingCutPinMinTOFHad)) { + if (track.hasTOF() && std::abs(track.p()) > settingPionMomCombMin) { const float tofNSigmaHad = track.tofNSigmaPi(); const float combNsigmaHad = std::sqrt(tofNSigmaHad * tofNSigmaHad + tpcNSigmaHad * tpcNSigmaHad); mQaRegistry.fill(HIST("purity/h2NsigmaHadTOF_preselection"), track.sign() * track.pt(), tofNSigmaHad); @@ -1758,24 +1767,39 @@ PROCESS_SWITCH(HadNucleiFemto, processMixedEventHyper, "Process Mixed event", fa } } - if (passTrackDe) { + if (passTrackNu && useDeuteronNucleus()) { const float tpcNSigmaDe = settingUseBBcomputeDeNsigma ? computeNSigmaDe(track) : track.tpcNSigmaDe(); - mQaRegistry.fill(HIST("purity/h2NsigmaNuTPC_preselection"), track.sign() * track.pt(), tpcNSigmaDe); - mQaRegistry.fill(HIST("purity/h2NsigmaNuTPC_preselecComp"), track.sign() * track.pt(), track.tpcNSigmaDe()); - if (track.hasTOF() && track.tpcInnerParam() > settingCutPinMinTOFITSDe) { - const float tofNSigmaDe = track.tofNSigmaDe(); - const float combNsigmaDe = std::sqrt(tofNSigmaDe * tofNSigmaDe + tpcNSigmaDe * tpcNSigmaDe); - mQaRegistry.fill(HIST("purity/h2NsigmaNuTOF_preselection"), track.sign() * track.pt(), tofNSigmaDe); - mQaRegistry.fill(HIST("purity/h2NsigmaNuComb_preselection"), track.sign() * track.pt(), combNsigmaDe); - } else if (track.tpcInnerParam() <= settingCutPinMinTOFITSDe) { + const float absTPCInnerParam = std::abs(track.tpcInnerParam()); + if (absTPCInnerParam > settingCutPinMinTOFITSDe) { + mQaRegistry.fill(HIST("purity/h2NsigmaNuTPC_preselection"), track.sign() * track.pt(), tpcNSigmaDe); + mQaRegistry.fill(HIST("purity/h2NsigmaNuTPC_preselecComp"), track.sign() * track.pt(), track.tpcNSigmaDe()); + if (track.hasTOF()) { + const float tofNSigmaDe = track.tofNSigmaDe(); + const float combNsigmaDe = std::sqrt(tofNSigmaDe * tofNSigmaDe + tpcNSigmaDe * tpcNSigmaDe); + mQaRegistry.fill(HIST("purity/h2NsigmaNuTOF_preselection"), track.sign() * track.pt(), tofNSigmaDe); + mQaRegistry.fill(HIST("purity/h2NsigmaNuComb_preselection"), track.sign() * track.pt(), combNsigmaDe); + } + } else { + o2::aod::ITSResponse itsResponse; const float itsNSigmaDe = itsResponse.nSigmaITS(track.itsClusterSizes(), track.p(), track.eta()); mQaRegistry.fill(HIST("purity/h2NSigmaNuITS_preselection"), track.sign() * track.pt(), itsNSigmaDe); + if (std::abs(itsNSigmaDe) <= settingCutNsigmaITSDe) { + mQaRegistry.fill(HIST("purity/h2NsigmaNuTPC_preselection"), track.sign() * track.pt(), tpcNSigmaDe); + mQaRegistry.fill(HIST("purity/h2NsigmaNuTPC_preselecComp"), track.sign() * track.pt(), track.tpcNSigmaDe()); + } } + } else if (passTrackNu && useHelium3Nucleus()) { + const float tpcNSigmaHe3 = computeNSigmaHe3(track); + const float signedPtHe3 = track.sign() * 2.f * track.pt(); + mQaRegistry.fill(HIST("purity/h2NsigmaNuTPC_preselection"), signedPtHe3, tpcNSigmaHe3); + o2::aod::ITSResponse itsResponse; + const float itsNSigmaHe3 = itsResponse.nSigmaITS(track.itsClusterSizes(), 2.f * track.p(), track.eta()); + mQaRegistry.fill(HIST("purity/h2NSigmaNuITS_preselection"), signedPtHe3, itsNSigmaHe3); } const bool isHadronSelected = passTrackHad && selectionPIDHadron(track); - const bool isDeuteronSelected = passTrackDe && selectionPIDDe(track); - if (!isHadronSelected && !isDeuteronSelected) { + const bool isNucleusSelected = passTrackNu && selectionPIDNu(track); + if (!isHadronSelected && !isNucleusSelected) { continue; } @@ -1784,15 +1808,15 @@ PROCESS_SWITCH(HadNucleiFemto, processMixedEventHyper, "Process Mixed event", fa mQaRegistry.fill(HIST("hSingleHadPt"), track.pt() * track.sign()); } - if (isDeuteronSelected) { - mQaRegistry.fill(HIST("hTrackSelDe"), Selections::kPID); - mQaRegistry.fill(HIST("hSingleNuPt"), track.pt() * track.sign()); - mQaRegistry.fill(HIST("hSingleNuPin"), track.tpcInnerParam() * track.sign()); + if (isNucleusSelected) { + fillNucleusTrackSelection(Selections::kPID); + mQaRegistry.fill(HIST("hSingleNuPt"), track.pt() * track.sign() * nucleusChargeFactor()); + mQaRegistry.fill(HIST("hSingleNuPin"), (useHelium3Nucleus() ? correctedTPCInnerParamHe3(track) : track.tpcInnerParam()) * track.sign()); } } } } - PROCESS_SWITCH(HadNucleiFemto, processPurity, "Process for pion and deuteron purity QA", false); + PROCESS_SWITCH(HadNucleiFemto, processPurity, "Process for hadron and nucleus purity QA", false); }; WorkflowSpec defineDataProcessing(const ConfigContext& cfgc) diff --git a/PWGCF/Femto/Macros/cutculatorGui.py b/PWGCF/Femto/Macros/cutculator_gui.py old mode 100755 new mode 100644 similarity index 61% rename from PWGCF/Femto/Macros/cutculatorGui.py rename to PWGCF/Femto/Macros/cutculator_gui.py index 6fc210f0ed2..a5beb43ff2f --- a/PWGCF/Femto/Macros/cutculatorGui.py +++ b/PWGCF/Femto/Macros/cutculator_gui.py @@ -37,6 +37,7 @@ ACCENT = "#89b4fa" # blue – minimal ACCENT_OPT = "#a6e3a1" # green – optional ACCENT_REJ = "#f38ba8" # red – rejection / neutral +ACCENT_ALWAYS = "#cba6f7" # purple – loosest/always-true (no bit set) FG = "#cdd6f4" FG_DIM = "#6c7086" BORDER = "#45475a" @@ -81,6 +82,17 @@ def bin_type(b): return "neutral" +def has_only_skipped_minimal_bins(group): + """ + Returns True when a group has at least one minimal bin but ALL of them have + BitPosition=="X" — meaning the cut is the loosest (always-true) selection + and no bit needs to be set. The group should still be displayed so the + user knows the cut exists. + """ + minimal = [b for b in group if b.get("MinimalCut", "0") == "1" and b.get("OptionalCut", "0") == "0"] + return bool(minimal) and all(b.get("BitPosition", "X").upper() == "X" for b in minimal) + + def load_bins_from_hist(hist): nbins = hist.GetNbinsX() bins = [] @@ -105,8 +117,8 @@ def __init__(self, rootfile=None, tdir="femto-producer"): super().__init__() self.title("CutCulator") self.configure(bg=BG) - self.geometry("920x720") - self.minsize(780, 560) + self.geometry("980x820") + self.minsize(780, 600) self.resizable(True, True) self._rootfile_path = rootfile @@ -153,14 +165,23 @@ def _build_ui(self): # ── legend ── legend = tk.Frame(self, bg=BG, pady=4, padx=18) legend.pack(fill="x") - for color, label in [(ACCENT, "Minimal"), (ACCENT_OPT, "Optional"), (ACCENT_REJ, "Neutral")]: + for color, label in [ + (ACCENT, "Minimal"), + (ACCENT_OPT, "Optional"), + (ACCENT_REJ, "Neutral"), + (ACCENT_ALWAYS, "Loosest (no bit set)"), + ]: dot = tk.Label(legend, text="●", font=FONT_BODY, bg=BG, fg=color) dot.pack(side="left") tk.Label(legend, text=label, font=FONT_SMALL, bg=BG, fg=FG_DIM).pack(side="left", padx=(2, 12)) + # ── main paned area: selection list (top) + summary (bottom) ── + paned = tk.PanedWindow(self, orient="vertical", bg=BORDER, sashwidth=4, sashrelief="flat") + paned.pack(fill="both", expand=True, padx=12, pady=4) + # ── scrollable selection area ── - outer = tk.Frame(self, bg=BG) - outer.pack(fill="both", expand=True, padx=12, pady=4) + outer = tk.Frame(paned, bg=BG) + paned.add(outer, stretch="always", minsize=200) self._canvas = tk.Canvas(outer, bg=BG, highlightthickness=0, bd=0) vsb = ttk.Scrollbar(outer, orient="vertical", command=self._canvas.yview) @@ -176,6 +197,32 @@ def _build_ui(self): self._canvas.bind_all("", self._on_mousewheel) self._canvas.bind_all("", self._on_mousewheel) + # ── summary panel ── + summary_outer = tk.Frame(paned, bg=BG_CARD) + paned.add(summary_outer, stretch="never", minsize=120) + + summary_hdr = tk.Frame(summary_outer, bg=BG_CARD, pady=5, padx=10) + summary_hdr.pack(fill="x") + tk.Label(summary_hdr, text="Selected cuts", font=FONT_HEAD, bg=BG_CARD, fg=FG).pack(side="left") + self._lbl_summary_empty = tk.Label(summary_hdr, text="(none)", font=FONT_SMALL, bg=BG_CARD, fg=FG_DIM) + self._lbl_summary_empty.pack(side="left", padx=8) + + tk.Frame(summary_outer, bg=BORDER, height=1).pack(fill="x") + + summary_scroll_outer = tk.Frame(summary_outer, bg=BG_CARD) + summary_scroll_outer.pack(fill="both", expand=True) + + self._summary_canvas = tk.Canvas(summary_scroll_outer, bg=BG_CARD, highlightthickness=0, bd=0, height=100) + summary_vsb = ttk.Scrollbar(summary_scroll_outer, orient="vertical", command=self._summary_canvas.yview) + self._summary_canvas.configure(yscrollcommand=summary_vsb.set) + summary_vsb.pack(side="right", fill="y") + self._summary_canvas.pack(side="left", fill="both", expand=True) + + self._summary_inner = tk.Frame(self._summary_canvas, bg=BG_CARD) + self._summary_canvas_win = self._summary_canvas.create_window((0, 0), window=self._summary_inner, anchor="nw") + self._summary_inner.bind("", self._on_summary_inner_configure) + self._summary_canvas.bind("", self._on_summary_canvas_configure) + # ── bottom result bar ── bottom = tk.Frame(self, bg=BG_CARD, pady=10, padx=18) bottom.pack(fill="x", side="bottom") @@ -224,6 +271,12 @@ def _on_inner_configure(self, _e=None): def _on_canvas_configure(self, e): self._canvas.itemconfig(self._canvas_win, width=e.width) + def _on_summary_inner_configure(self, _e=None): + self._summary_canvas.configure(scrollregion=self._summary_canvas.bbox("all")) + + def _on_summary_canvas_configure(self, e): + self._summary_canvas.itemconfig(self._summary_canvas_win, width=e.width) + def _on_mousewheel(self, e): if e.num == 4: self._canvas.yview_scroll(-1, "units") @@ -292,13 +345,17 @@ def _build_selections(self): self._on_inner_configure() def _build_group_card(self, sel_name, group): - # categorise + # categorise into selectable bins minimal = [(i, b) for i, b in enumerate(group) if bin_type(b) == "minimal"] optional = [(i, b) for i, b in enumerate(group) if bin_type(b) == "optional"] neutral = [(i, b) for i, b in enumerate(group) if bin_type(b) == "neutral"] - if not (minimal or optional or neutral): - return # nothing to show (all "skip") + # detect loosest/always-true: minimal bins exist but all have BitPosition==X + loosest_only = has_only_skipped_minimal_bins(group) + + # skip entirely if there is truly nothing to show + if not (minimal or optional or neutral or loosest_only): + return card = tk.Frame(self._inner, bg=BG_CARD, bd=0, highlightthickness=1, highlightbackground=BORDER) card.pack(fill="x", padx=10, pady=5, ipadx=8, ipady=6) @@ -308,27 +365,42 @@ def _build_group_card(self, sel_name, group): hdr.pack(fill="x", padx=6, pady=(4, 2)) tk.Label(hdr, text=sel_name, font=FONT_HEAD, bg=BG_CARD, fg=FG).pack(side="left") - # show the loosest (most permissive) minimal threshold as a hint. - # the truly loosest threshold has mSkipMostPermissiveBit=true so its - # BitPosition is "X" — it lands in the "skip" category. check there first, - # then fall back to the loosest bit-carrying minimal bin. - skipped_minimal = [ - b for b in group if b.get("MinimalCut", "0") == "1" and b.get("BitPosition", "X").upper() == "X" - ] - if skipped_minimal: - loosest_val = format_value_with_comment(skipped_minimal[0]) + if loosest_only: + # All minimal bins are BitPosition==X → loosest cut, no bit set tk.Label( - hdr, text=f"minimal cut → loosest selection: {loosest_val}", font=FONT_SMALL, bg=BG_CARD, fg=FG_DIM + hdr, + text="loosest selection — no bit set", + font=FONT_SMALL, + bg=BG_CARD, + fg=ACCENT_ALWAYS, ).pack(side="left", padx=10) - elif minimal: - loosest_val = format_value_with_comment(minimal[0][1]) - tk.Label( - hdr, text=f"minimal cut → loosest selection: {loosest_val}", font=FONT_SMALL, bg=BG_CARD, fg=FG_DIM - ).pack(side="left", padx=10) - elif optional: - tk.Label(hdr, text="optional", font=FONT_SMALL, bg=BG_CARD, fg=ACCENT_OPT).pack(side="left", padx=10) - elif neutral: - tk.Label(hdr, text="neutral", font=FONT_SMALL, bg=BG_CARD, fg=ACCENT_REJ).pack(side="left", padx=10) + else: + # show the loosest (most permissive) minimal threshold as a hint + skipped_minimal = [ + b for b in group if b.get("MinimalCut", "0") == "1" and b.get("BitPosition", "X").upper() == "X" + ] + if skipped_minimal: + loosest_val = format_value_with_comment(skipped_minimal[0]) + tk.Label( + hdr, + text=f"minimal cut → loosest selection: {loosest_val}", + font=FONT_SMALL, + bg=BG_CARD, + fg=FG_DIM, + ).pack(side="left", padx=10) + elif minimal: + loosest_val = format_value_with_comment(minimal[0][1]) + tk.Label( + hdr, + text=f"minimal cut → loosest selection: {loosest_val}", + font=FONT_SMALL, + bg=BG_CARD, + fg=FG_DIM, + ).pack(side="left", padx=10) + elif optional: + tk.Label(hdr, text="optional", font=FONT_SMALL, bg=BG_CARD, fg=ACCENT_OPT).pack(side="left", padx=10) + elif neutral: + tk.Label(hdr, text="neutral", font=FONT_SMALL, bg=BG_CARD, fg=ACCENT_REJ).pack(side="left", padx=10) # separator tk.Frame(card, bg=BORDER, height=1).pack(fill="x", padx=6, pady=2) @@ -337,19 +409,41 @@ def _build_group_card(self, sel_name, group): bins_frame = tk.Frame(card, bg=BG_CARD) bins_frame.pack(fill="x", padx=6, pady=4) - for i, b in minimal: - self._build_bin_row(bins_frame, sel_name, i, b, "minimal") - for i, b in optional: - self._build_bin_row(bins_frame, sel_name, i, b, "optional") - for i, b in neutral: - self._build_bin_row(bins_frame, sel_name, i, b, "neutral") + if loosest_only: + # Display loosest minimal bins as informational rows — no checkbox, no bit + for b in group: + if b.get("MinimalCut", "0") == "1" and b.get("OptionalCut", "0") == "0": + self._build_loosest_row(bins_frame, b) + else: + for i, b in minimal: + self._build_bin_row(bins_frame, sel_name, i, b, "minimal") + for i, b in optional: + self._build_bin_row(bins_frame, sel_name, i, b, "optional") + for i, b in neutral: + self._build_bin_row(bins_frame, sel_name, i, b, "neutral") + + def _build_loosest_row(self, parent, b): + """Informational row for a loosest/always-true cut — no checkbox, no bit.""" + label_text = format_value_with_comment(b) + + row = tk.Frame(parent, bg=BG_CARD) + row.pack(fill="x", pady=1) + + tk.Label(row, text="●", font=FONT_BODY, bg=BG_CARD, fg=ACCENT_ALWAYS).pack(side="left", padx=(0, 4)) + tk.Label( + row, + text=label_text, + font=FONT_BODY, + bg=BG_CARD, + fg=FG_DIM, # dimmed to signal non-interactive + ).pack(side="left", fill="x", expand=True) + # no bit-position badge since it's "X" def _build_bin_row(self, parent, sel_name, idx, b, kind): color = {"minimal": ACCENT, "optional": ACCENT_OPT, "neutral": ACCENT_REJ}[kind] label_text = format_value_with_comment(b) var = tk.BooleanVar(value=False) - self._vars[(sel_name, idx)] = var row = tk.Frame(parent, bg=BG_CARD) @@ -358,7 +452,7 @@ def _build_bin_row(self, parent, sel_name, idx, b, kind): # coloured dot tk.Label(row, text="●", font=FONT_BODY, bg=BG_CARD, fg=color).pack(side="left", padx=(0, 4)) - # checkbox styled as a toggle button + # checkbox cb = tk.Checkbutton( row, text=label_text, @@ -382,22 +476,105 @@ def _build_bin_row(self, parent, sel_name, idx, b, kind): if pos.upper() != "X": tk.Label(row, text=f"bit {pos}", font=FONT_SMALL, bg=BG_CARD, fg=FG_DIM, width=8).pack(side="right", padx=4) - # ── Bitmask computation ─────────────────────────────────────────────────── + # ── Bitmask computation + summary update ────────────────────────────────── def _update_bitmask(self): bitmask = 0 + selected_entries = [] # list of (sel_name, label_text, bit_pos, color, is_loosest) + + # User-selected cuts (from checkboxes) for (sel_name, idx), var in self._vars.items(): if not var.get(): continue b = self._groups[sel_name][idx] pos = b.get("BitPosition", "X") - if pos.upper() == "X": - continue - bitmask |= 1 << int(pos) + kind = bin_type(b) + color = {"minimal": ACCENT, "optional": ACCENT_OPT, "neutral": ACCENT_REJ}.get(kind, FG_DIM) + + if pos.upper() != "X": + bitmask |= 1 << int(pos) + label_text = format_value_with_comment(b) + selected_entries.append((sel_name, label_text, pos, color, False)) + + # Loosest-only cuts: always shown in summary, never set a bit + for sel_name, group in self._groups.items(): + if has_only_skipped_minimal_bins(group): + for b in group: + if b.get("MinimalCut", "0") == "1" and b.get("OptionalCut", "0") == "0": + label_text = format_value_with_comment(b) + selected_entries.append((sel_name, label_text, "X", ACCENT_ALWAYS, True)) self._lbl_dec.config(text=str(bitmask)) self._lbl_hex.config(text=hex(bitmask)) self._lbl_bin.config(text=bin(bitmask)) + self._rebuild_summary(selected_entries) + + def _rebuild_summary(self, entries): + """Rebuild the selected-cuts summary panel.""" + for w in self._summary_inner.winfo_children(): + w.destroy() + + if not entries: + self._lbl_summary_empty.config(text="(none)") + self._on_summary_inner_configure() + return + + self._lbl_summary_empty.config(text="") + + # group by selection name, preserving is_loosest flag + by_name = {} + for sel_name, label_text, pos, color, is_loosest in entries: + by_name.setdefault(sel_name, []).append((label_text, pos, color, is_loosest)) + + for sel_name, items in by_name.items(): + block = tk.Frame(self._summary_inner, bg=BG_CARD) + block.pack(fill="x", padx=10, pady=(3, 0)) + + # name on its own line — no truncation + tk.Label( + block, + text=f"{sel_name}:", + font=FONT_BODY, + bg=BG_CARD, + fg=FG, + anchor="w", + ).pack(fill="x") + + # values indented below the name + values_row = tk.Frame(block, bg=BG_CARD) + values_row.pack(fill="x", padx=(16, 0), pady=(0, 2)) + + for label_text, pos, color, is_loosest in items: + entry_frame = tk.Frame(values_row, bg=BG_CARD) + entry_frame.pack(side="left", padx=(0, 12)) + + tk.Label(entry_frame, text="●", font=FONT_SMALL, bg=BG_CARD, fg=color).pack(side="left") + tk.Label( + entry_frame, + text=label_text, + font=FONT_SMALL, + bg=BG_CARD, + fg=FG_DIM if is_loosest else FG, + ).pack(side="left", padx=(2, 0)) + if is_loosest: + tk.Label( + entry_frame, + text="(no bit)", + font=FONT_SMALL, + bg=BG_CARD, + fg=ACCENT_ALWAYS, + ).pack(side="left", padx=(4, 0)) + elif pos.upper() != "X": + tk.Label( + entry_frame, + text=f"[bit {pos}]", + font=FONT_SMALL, + bg=BG_CARD, + fg=FG_DIM, + ).pack(side="left", padx=(4, 0)) + + self._on_summary_inner_configure() + # ── Utilities ───────────────────────────────────────────────────────────── def _copy(self, text): self.clipboard_clear() diff --git a/PWGCF/Femto/TableProducer/femtoProducer.cxx b/PWGCF/Femto/TableProducer/femtoProducer.cxx index bf18ec255bd..d77a0c7c408 100644 --- a/PWGCF/Femto/TableProducer/femtoProducer.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducer.cxx @@ -33,6 +33,7 @@ #include "Common/DataModel/TrackSelectionTables.h" #include +#include #include #include #include @@ -48,9 +49,7 @@ using namespace o2::analysis::femto; -namespace o2::analysis::femto -{ -namespace consumeddata +namespace o2::analysis::femto::rawinputs { using Run3PpCollisions = o2::soa::Join; using Run3PpMcRecoCollisions = o2::soa::Join; @@ -78,11 +77,12 @@ using Run3Kinks = o2::aod::KinkCands; using Run3McGenParticles = o2::aod::McParticles; -} // namespace consumeddata -} // namespace o2::analysis::femto +} // namespace o2::analysis::femto::rawinputs struct FemtoProducer { + o2::framework::Preslice perMcCollision = o2::aod::mcparticle::mcCollisionId; + // ccdb collisionbuilder::ConfCcdb confCcdb; @@ -140,20 +140,30 @@ struct FemtoProducer { o2::framework::HistogramRegistry hRegistry{"FemtoProducer", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; // data members - o2::framework::Service ccdb; /// Accessing the CCDB + o2::framework::Service ccdb = {}; /// Accessing the CCDB void init(o2::framework::InitContext& context) { - if ((xiBuilder.fillAnyTable() || omegaBuilder.fillAnyTable()) && (!doprocessTracksV0sCascadesRun3pp && !doprocessTracksV0sCascadesKinksRun3pp)) { + if ((xiBuilder.fillAnyTable() || omegaBuilder.fillAnyTable()) && + (!doprocessTracksV0sCascadesRun3pp && !doprocessTracksV0sCascadesKinksRun3pp && !doprocessTracksV0sCascadesRun3ppMc)) { LOG(fatal) << "At least one cascade table is enabled, but wrong process function is enabled. Breaking..."; } - if ((lambdaBuilder.fillAnyTable() || antilambdaBuilder.fillAnyTable() || k0shortBuilder.fillAnyTable()) && (!doprocessTracksV0sCascadesRun3pp && !doprocessTracksV0sRun3pp && !doprocessTracksV0sCascadesKinksRun3pp && !doprocessTracksV0sRun3ppMc)) { + if ((lambdaBuilder.fillAnyTable() || antilambdaBuilder.fillAnyTable() || k0shortBuilder.fillAnyTable()) && + (!doprocessTracksV0sCascadesRun3pp && !doprocessTracksV0sRun3pp && !doprocessTracksV0sCascadesKinksRun3pp && + !doprocessTracksV0sRun3ppMc && !doprocessTracksV0sRun3PbPb && !doprocessTracksV0sRun3PbPbMc && + !doprocessTracksV0sCascadesRun3ppMc && !doprocessTracksV0sKinksRun3ppMc)) { LOG(fatal) << "At least one v0 table is enabled, but wrong process function is enabled. Breaking..."; } - if ((sigmaBuilder.fillAnyTable() || sigmaPlusBuilder.fillAnyTable()) && (!doprocessTracksKinksRun3pp && !doprocessTracksV0sCascadesKinksRun3pp && !doprocessTracksKinksRun3ppMc)) { + if ((sigmaBuilder.fillAnyTable() || sigmaPlusBuilder.fillAnyTable()) && + (!doprocessTracksKinksRun3pp && !doprocessTracksV0sCascadesKinksRun3pp && + !doprocessTracksKinksRun3ppMc && !doprocessTracksV0sKinksRun3ppMc)) { LOG(fatal) << "At least one kink table is enabled, but wrong process function is enabled. Breaking..."; } - if (mcBuilder.fillAnyTable() && (!doprocessTracksV0sRun3ppMc && !doprocessTracksKinksRun3ppMc)) { + if (mcBuilder.fillAnyTable() && + (!doprocessTracksV0sRun3ppMc && !doprocessTracksKinksRun3ppMc && + !doprocessTracksV0sCascadesRun3ppMc && !doprocessTracksV0sKinksRun3ppMc && + !doprocessTracksRun3ppMc && !doprocessTracksRun3PbPbMc && !doprocessTracksV0sRun3PbPbMc && + !doprocessMcOnly)) { LOG(fatal) << "At least one mc table is enabled, but wrong process function is enabled. Breaking..."; } @@ -188,6 +198,7 @@ struct FemtoProducer { mcBuilder.init(confMc, confMcTables, context); hRegistry.print(); + LOG(warn) << __LINE__; } // processing collisions @@ -197,13 +208,11 @@ struct FemtoProducer { collisionBuilder.reset(); auto bc = col.template bc_as(); collisionBuilder.initCollision(bc, col, tracks, ccdb, hRegistry); - if (!collisionBuilder.checkCollision(col)) { - return false; - } // do not fill collsions into the table here // collisions are filled if at least one partilce is found in the collisions - return true; + return collisionBuilder.checkCollision(col); } + template bool processMcCollisions(T1 const& col, T2 const& mcCols, T3 const& /* bcs*/, T4 const& tracks, T5 const& mcParticles) { @@ -211,12 +220,9 @@ struct FemtoProducer { mcBuilder.reset(mcCols, mcParticles); // we call this function always first so we reset the mcBuilder here auto bc = col.template bc_as(); collisionBuilder.initCollision(bc, col, tracks, ccdb, hRegistry); - if (!collisionBuilder.checkCollision(col, mcCols)) { - return false; - } // do not fill collsions into the table here // collisions are filled if at least one partilce is found in the collisions - return true; + return collisionBuilder.checkCollision(col, mcCols); } // processing tracks @@ -280,57 +286,57 @@ struct FemtoProducer { } // proccess functions - void processTracksRun3pp(consumeddata::Run3PpCollisions::iterator const& col, + void processTracksRun3pp(rawinputs::Run3PpCollisions::iterator const& col, o2::aod::BCsWithTimestamps const& bcs, - consumeddata::Run3FullPidTracks const& tracks) + rawinputs::Run3FullPidTracks const& tracks) { if (!processCollisions(col, bcs, tracks)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); processTracks(col, tracksWithItsPid); } PROCESS_SWITCH(FemtoProducer, processTracksRun3pp, "Process tracks", true); - void processTracksRun3PbPb(consumeddata::Run3PbPbCollisions::iterator const& col, + void processTracksRun3PbPb(rawinputs::Run3PbPbCollisions::iterator const& col, o2::aod::BCsWithTimestamps const& bcs, - consumeddata::Run3FullPidTracks const& tracks) + rawinputs::Run3FullPidTracks const& tracks) { if (!processCollisions(col, bcs, tracks)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); processTracks(col, tracksWithItsPid); } PROCESS_SWITCH(FemtoProducer, processTracksRun3PbPb, "Process tracks in PbPB collisions", false); // process tracks and v0s - void processTracksV0sRun3pp(consumeddata::Run3PpCollisions::iterator const& col, + void processTracksV0sRun3pp(rawinputs::Run3PpCollisions::iterator const& col, o2::aod::BCsWithTimestamps const& bcs, - consumeddata::Run3FullPidTracks const& tracks, - consumeddata::Run3Vzeros const& v0s) + rawinputs::Run3FullPidTracks const& tracks, + rawinputs::Run3Vzeros const& v0s) { if (!processCollisions(col, bcs, tracks)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); processTracks(col, tracksWithItsPid); processV0s(col, tracks, v0s); }; PROCESS_SWITCH(FemtoProducer, processTracksV0sRun3pp, "Process tracks and v0s", false); - void processTracksV0sRun3PbPb(consumeddata::Run3PbPbCollisions::iterator const& col, + void processTracksV0sRun3PbPb(rawinputs::Run3PbPbCollisions::iterator const& col, o2::aod::BCsWithTimestamps const& bcs, - consumeddata::Run3FullPidTracks const& tracks, - consumeddata::Run3Vzeros const& v0s) + rawinputs::Run3FullPidTracks const& tracks, + rawinputs::Run3Vzeros const& v0s) { if (!processCollisions(col, bcs, tracks)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); processTracks(col, tracksWithItsPid); processV0s(col, tracks, v0s); @@ -338,15 +344,15 @@ struct FemtoProducer { PROCESS_SWITCH(FemtoProducer, processTracksV0sRun3PbPb, "Process tracks and v0s in PbPB collisions", false); // process tracks and kinks - void processTracksKinksRun3pp(consumeddata::Run3PpCollisions::iterator const& col, + void processTracksKinksRun3pp(rawinputs::Run3PpCollisions::iterator const& col, o2::aod::BCsWithTimestamps const& bcs, - consumeddata::Run3FullPidTracks const& tracks, - consumeddata::Run3Kinks const& kinks) + rawinputs::Run3FullPidTracks const& tracks, + rawinputs::Run3Kinks const& kinks) { if (!processCollisions(col, bcs, tracks)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); processTracks(col, tracksWithItsPid); processKinks(col, tracks, kinks); @@ -354,16 +360,16 @@ struct FemtoProducer { PROCESS_SWITCH(FemtoProducer, processTracksKinksRun3pp, "Process tracks and kinks", false); // process tracks, v0s and cascades - void processTracksV0sCascadesRun3pp(consumeddata::Run3PpCollisions::iterator const& col, + void processTracksV0sCascadesRun3pp(rawinputs::Run3PpCollisions::iterator const& col, o2::aod::BCsWithTimestamps const& bcs, - consumeddata::Run3FullPidTracks const& tracks, - consumeddata::Run3Vzeros const& v0s, - consumeddata::Run3Cascades const& cascades) + rawinputs::Run3FullPidTracks const& tracks, + rawinputs::Run3Vzeros const& v0s, + rawinputs::Run3Cascades const& cascades) { if (!processCollisions(col, bcs, tracks)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); processTracks(col, tracksWithItsPid); processV0s(col, tracks, v0s); @@ -372,17 +378,17 @@ struct FemtoProducer { PROCESS_SWITCH(FemtoProducer, processTracksV0sCascadesRun3pp, "Provide Tracks, V0s and Cascades for Run3", false); // process tracks, v0s, cascades and kinks - void processTracksV0sCascadesKinksRun3pp(consumeddata::Run3PpCollisions::iterator const& col, + void processTracksV0sCascadesKinksRun3pp(rawinputs::Run3PpCollisions::iterator const& col, o2::aod::BCsWithTimestamps const& bcs, - consumeddata::Run3FullPidTracks const& tracks, - consumeddata::Run3Vzeros const& v0s, - consumeddata::Run3Cascades const& cascades, - consumeddata::Run3Kinks const& kinks) + rawinputs::Run3FullPidTracks const& tracks, + rawinputs::Run3Vzeros const& v0s, + rawinputs::Run3Cascades const& cascades, + rawinputs::Run3Kinks const& kinks) { if (!processCollisions(col, bcs, tracks)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); processTracks(col, tracksWithItsPid); processV0s(col, tracks, v0s); @@ -392,65 +398,65 @@ struct FemtoProducer { PROCESS_SWITCH(FemtoProducer, processTracksV0sCascadesKinksRun3pp, "Provide Tracks, V0s and Cascades for Run3", false); // process monte carlo tracks - void processTracksRun3ppMc(consumeddata::Run3PpMcRecoCollisions::iterator const& col, - consumeddata::Run3PpMcGenCollisions const& mcCols, + void processTracksRun3ppMc(rawinputs::Run3PpMcRecoCollisions::iterator const& col, + rawinputs::Run3PpMcGenCollisions const& mcCols, o2::aod::BCsWithTimestamps const& bcs, - consumeddata::Run3McRecoTracks const& tracks, - consumeddata::Run3McGenParticles const& mcParticles) + rawinputs::Run3McRecoTracks const& tracks, + rawinputs::Run3McGenParticles const& mcParticles) { if (!processMcCollisions(col, mcCols, bcs, tracks, mcParticles)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); } PROCESS_SWITCH(FemtoProducer, processTracksRun3ppMc, "Provide reconstructed and generated Tracks", false); - void processTracksRun3PbPbMc(consumeddata::Run3PbPbMcRecoCollisions::iterator const& col, - consumeddata::Run3PbPbMcGenCollisions const& mcCols, + void processTracksRun3PbPbMc(rawinputs::Run3PbPbMcRecoCollisions::iterator const& col, + rawinputs::Run3PbPbMcGenCollisions const& mcCols, o2::aod::BCsWithTimestamps const& bcs, - consumeddata::Run3McRecoTracks const& tracks, - consumeddata::Run3McGenParticles const& mcParticles) + rawinputs::Run3McRecoTracks const& tracks, + rawinputs::Run3McGenParticles const& mcParticles) { if (!processMcCollisions(col, mcCols, bcs, tracks, mcParticles)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); } PROCESS_SWITCH(FemtoProducer, processTracksRun3PbPbMc, "Provide reconstructed and generated Tracks in PbPb collisions", false); // process monte carlo tracks and v0s - void processTracksV0sRun3ppMc(consumeddata::Run3PpMcRecoCollisions::iterator const& col, - consumeddata::Run3PpMcGenCollisions const& mcCols, + void processTracksV0sRun3ppMc(rawinputs::Run3PpMcRecoCollisions::iterator const& col, + rawinputs::Run3PpMcGenCollisions const& mcCols, o2::aod::BCsWithTimestamps const& bcs, - consumeddata::Run3McRecoTracks const& tracks, - consumeddata::Run3RecoVzeros const& v0s, - consumeddata::Run3McGenParticles const& mcParticles) + rawinputs::Run3McRecoTracks const& tracks, + rawinputs::Run3RecoVzeros const& v0s, + rawinputs::Run3McGenParticles const& mcParticles) { if (!processMcCollisions(col, mcCols, bcs, tracks, mcParticles)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); processMcV0s(col, mcCols, tracks, v0s, mcParticles); } PROCESS_SWITCH(FemtoProducer, processTracksV0sRun3ppMc, "Provide reconstructed and generated tracks and v0s", false); - void processTracksV0sRun3PbPbMc(consumeddata::Run3PbPbMcRecoCollisions::iterator const& col, - consumeddata::Run3PbPbMcGenCollisions const& mcCols, + void processTracksV0sRun3PbPbMc(rawinputs::Run3PbPbMcRecoCollisions::iterator const& col, + rawinputs::Run3PbPbMcGenCollisions const& mcCols, o2::aod::BCsWithTimestamps const& bcs, - consumeddata::Run3McRecoTracks const& tracks, - consumeddata::Run3RecoVzeros const& v0s, - consumeddata::Run3McGenParticles const& mcParticles) + rawinputs::Run3McRecoTracks const& tracks, + rawinputs::Run3RecoVzeros const& v0s, + rawinputs::Run3McGenParticles const& mcParticles) { if (!processMcCollisions(col, mcCols, bcs, tracks, mcParticles)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); processMcV0s(col, mcCols, tracks, v0s, mcParticles); @@ -458,17 +464,17 @@ struct FemtoProducer { PROCESS_SWITCH(FemtoProducer, processTracksV0sRun3PbPbMc, "Provide reconstructed and generated tracks and v0s in PbPb collisions", false); // process monte carlo tracks and kinks - void processTracksKinksRun3ppMc(consumeddata::Run3PpMcRecoCollisions::iterator const& col, - consumeddata::Run3PpMcGenCollisions const& mcCols, + void processTracksKinksRun3ppMc(rawinputs::Run3PpMcRecoCollisions::iterator const& col, + rawinputs::Run3PpMcGenCollisions const& mcCols, o2::aod::BCsWithTimestamps const& bcs, - consumeddata::Run3McRecoTracks const& tracks, - consumeddata::Run3Kinks const& kinks, - consumeddata::Run3McGenParticles const& mcParticles) + rawinputs::Run3McRecoTracks const& tracks, + rawinputs::Run3Kinks const& kinks, + rawinputs::Run3McGenParticles const& mcParticles) { if (!processMcCollisions(col, mcCols, bcs, tracks, mcParticles)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); processMcKinks(col, mcCols, tracks, kinks, mcParticles); @@ -476,18 +482,18 @@ struct FemtoProducer { PROCESS_SWITCH(FemtoProducer, processTracksKinksRun3ppMc, "Provide reconstructed and generated tracks and kinks", false); // process monte carlo tracks and v0s and kinks (adding cascades later here) - void processTracksV0sKinksRun3ppMc(consumeddata::Run3PpMcRecoCollisions::iterator const& col, - consumeddata::Run3PpMcGenCollisions const& mcCols, + void processTracksV0sKinksRun3ppMc(rawinputs::Run3PpMcRecoCollisions::iterator const& col, + rawinputs::Run3PpMcGenCollisions const& mcCols, o2::aod::BCsWithTimestamps const& bcs, - consumeddata::Run3McRecoTracks const& tracks, - consumeddata::Run3RecoVzeros const& v0s, - consumeddata::Run3Kinks const& kinks, - consumeddata::Run3McGenParticles const& mcParticles) + rawinputs::Run3McRecoTracks const& tracks, + rawinputs::Run3RecoVzeros const& v0s, + rawinputs::Run3Kinks const& kinks, + rawinputs::Run3McGenParticles const& mcParticles) { if (!processMcCollisions(col, mcCols, bcs, tracks, mcParticles)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); processMcV0s(col, mcCols, tracks, v0s, mcParticles); @@ -496,28 +502,43 @@ struct FemtoProducer { PROCESS_SWITCH(FemtoProducer, processTracksV0sKinksRun3ppMc, "Provide reconstructed and generated tracks and v0s and kinks", false); // process monte carlo tracks and v0s - void processTracksV0sCascadesRun3ppMc(consumeddata::Run3PpMcRecoCollisions::iterator const& col, - consumeddata::Run3PpMcGenCollisions const& mcCols, + void processTracksV0sCascadesRun3ppMc(rawinputs::Run3PpMcRecoCollisions::iterator const& col, + rawinputs::Run3PpMcGenCollisions const& mcCols, o2::aod::BCsWithTimestamps const& bcs, - consumeddata::Run3McRecoTracks const& tracks, - consumeddata::Run3RecoVzeros const& v0s, - consumeddata::Run3RecoCascades const& cascades, - consumeddata::Run3McGenParticles const& mcParticles) + rawinputs::Run3McRecoTracks const& tracks, + rawinputs::Run3RecoVzeros const& v0s, + rawinputs::Run3RecoCascades const& cascades, + rawinputs::Run3McGenParticles const& mcParticles) { if (!processMcCollisions(col, mcCols, bcs, tracks, mcParticles)) { return; } - auto tracksWithItsPid = o2::soa::Attach(tracks); processMcTracks(col, mcCols, tracks, tracksWithItsPid, mcParticles); processMcV0s(col, mcCols, tracks, v0s, mcParticles); processMcCascades(col, mcCols, tracks, cascades, mcParticles); } PROCESS_SWITCH(FemtoProducer, processTracksV0sCascadesRun3ppMc, "Provide reconstructed and generated tracks and v0s", false); + + // process generator level only input (for MCGEN datasets) + // do not preslice mcParticles tables for each collision, otherwise the finding of the partonic mother can fail + void processMcOnly(o2::aod::McCollisions const& mcCols, o2::aod::McParticles const& mcParticles) + { + mcBuilder.reset(mcParticles); + for (const auto& mcCol : mcCols) { + mcBuilder.fillMcCollision(mcCol, mcProducts); + auto particlesThisCollision = mcParticles.sliceBy(perMcCollision, mcCol.globalIndex()); + for (const auto& mcParticle : particlesThisCollision) { + mcBuilder.fillMcParticle(mcParticle, mcParticles, mcCol, mcProducts); + } + } + } + PROCESS_SWITCH(FemtoProducer, processMcOnly, "Provide generated particles", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { - o2::framework::WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + o2::framework::WorkflowSpec workflow{adaptAnalysisTask(context)}; return workflow; } diff --git a/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx b/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx index f64ae54b657..6b1d326ac32 100644 --- a/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducerDerivedToDerived.cxx @@ -96,7 +96,7 @@ struct FemtoProducerDerivedToDerived { v0Builder.init(confV0Builder); kinkBuilder.init(confKinkBuilder); - if ((doprocessTracks + doprocessTracksLambdas + doprocessTracksK0shorts + doprocessTracksSigma + doprocessTracksSigmaPlus) > 1) { + if ((static_cast(doprocessTracks) + static_cast(doprocessTracksLambdas) + static_cast(doprocessTracksK0shorts) + static_cast(doprocessTracksSigma) + static_cast(doprocessTracksSigmaPlus)) > 1) { LOG(fatal) << "Only one proccess function can be activated"; } } @@ -167,8 +167,8 @@ struct FemtoProducerDerivedToDerived { PROCESS_SWITCH(FemtoProducerDerivedToDerived, processTracksSigmaPlus, "Process sigmaPlus and tracks", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { - o2::framework::WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + o2::framework::WorkflowSpec workflow{adaptAnalysisTask(context)}; return workflow; } diff --git a/PWGCF/Femto/TableProducer/femtoProducerKinkPtConverter.cxx b/PWGCF/Femto/TableProducer/femtoProducerKinkPtConverter.cxx index 46dfd292186..8f61ef26d16 100644 --- a/PWGCF/Femto/TableProducer/femtoProducerKinkPtConverter.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducerKinkPtConverter.cxx @@ -106,8 +106,8 @@ struct FemtoProducerKinkPtConverter { } }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { - o2::framework::WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + o2::framework::WorkflowSpec workflow{adaptAnalysisTask(context)}; return workflow; } diff --git a/PWGCF/Femto/TableProducer/femtoProducerResonances.cxx b/PWGCF/Femto/TableProducer/femtoProducerResonances.cxx index 1eaba0fa6bd..38b787c2c0e 100644 --- a/PWGCF/Femto/TableProducer/femtoProducerResonances.cxx +++ b/PWGCF/Femto/TableProducer/femtoProducerResonances.cxx @@ -103,8 +103,8 @@ struct FemtoProducerResonances { PROCESS_SWITCH(FemtoProducerResonances, processKstar0, "Build Kstar0/Kstar0bar candidates", true); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { - o2::framework::WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + o2::framework::WorkflowSpec workflow{adaptAnalysisTask(context)}; return workflow; } diff --git a/PWGCF/Femto/Tasks/CMakeLists.txt b/PWGCF/Femto/Tasks/CMakeLists.txt index ccfc8ee237e..9e612ee28a4 100644 --- a/PWGCF/Femto/Tasks/CMakeLists.txt +++ b/PWGCF/Femto/Tasks/CMakeLists.txt @@ -34,6 +34,11 @@ o2physics_add_dpl_workflow(femto-cascade-qa PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(femto-mc-particle-qa + SOURCES femtoMcParticleQa.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(femto-pair-track-track SOURCES femtoPairTrackTrack.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore @@ -69,6 +74,11 @@ o2physics_add_dpl_workflow(femto-pair-v0-v0 PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(femto-pair-mc-particle-mc-particle + SOURCES femtoPairMcParticleMcParticle.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(femto-pair-efficiency SOURCES femtoPairEfficiency.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore diff --git a/PWGCF/Femto/Tasks/femtoCascadeQa.cxx b/PWGCF/Femto/Tasks/femtoCascadeQa.cxx index 80a19160b94..9b627838165 100644 --- a/PWGCF/Femto/Tasks/femtoCascadeQa.cxx +++ b/PWGCF/Femto/Tasks/femtoCascadeQa.cxx @@ -57,6 +57,8 @@ struct FemtoCascadeQa { using FemtoOmegasWithLabel = o2::soa::Join; using FemtoTracksWithLabel = o2::soa::Join; + using FemtoMcParticlesWithLabel = o2::soa::Join; + o2::framework::SliceCache cache; // setup collisions @@ -122,7 +124,7 @@ struct FemtoCascadeQa { void init(o2::framework::InitContext&) { - if ((doprocessXi + doprocessXiMc + doprocessOmega + doprocessOmegaMc) > 1) { + if ((static_cast(doprocessXi) + static_cast(doprocessXiMc) + static_cast(doprocessOmega) + static_cast(doprocessOmegaMc)) > 1) { LOG(fatal) << "Only one process can be activated"; } bool processData = doprocessXi || doprocessOmega; @@ -139,31 +141,31 @@ struct FemtoCascadeQa { if (processData) { colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); - colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); bachelorHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confBachelorBinning, confBachelorQaBinning); posDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confPosDaughterBinning, confPosDaughterQaBinning); negDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confNegDaughterBinning, confNegDaughterQaBinning); if (doprocessXi) { xiHistSpec = cascadehistmanager::makeCascadeQaHistSpecMap(confXiBinning, confXiQaBinning); - xiHistManager.init(&hRegistry, xiHistSpec, confXiSelection, confXiQaBinning, bachelorHistSpec, confBachelorQaBinning, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); + xiHistManager.init(&hRegistry, xiHistSpec, confXiSelection, confXiQaBinning, bachelorHistSpec, confBachelorQaBinning, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); } if (doprocessOmega) { omegaHistSpec = cascadehistmanager::makeCascadeQaHistSpecMap(confOmegaBinning, confOmegaQaBinning); - omegaHistManager.init(&hRegistry, omegaHistSpec, confOmegaSelection, confOmegaQaBinning, bachelorHistSpec, confBachelorQaBinning, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); + omegaHistManager.init(&hRegistry, omegaHistSpec, confOmegaSelection, confOmegaQaBinning, bachelorHistSpec, confBachelorQaBinning, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); } } else { colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); - colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); bachelorHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confBachelorBinning, confBachelorQaBinning); posDaughterHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confPosDaughterBinning, confPosDaughterQaBinning); negDaughterHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confNegDaughterBinning, confNegDaughterQaBinning); if (doprocessXiMc) { xiHistSpec = cascadehistmanager::makeCascadeMcQaHistSpecMap(confXiBinning, confXiQaBinning); - xiHistManager.init(&hRegistry, xiHistSpec, confXiSelection, confXiQaBinning, bachelorHistSpec, confBachelorQaBinning, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); + xiHistManager.init(&hRegistry, xiHistSpec, confXiSelection, confXiQaBinning, bachelorHistSpec, confBachelorQaBinning, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); } if (doprocessOmegaMc) { omegaHistSpec = cascadehistmanager::makeCascadeMcQaHistSpecMap(confOmegaBinning, confOmegaQaBinning); - omegaHistManager.init(&hRegistry, omegaHistSpec, confOmegaSelection, confOmegaQaBinning, bachelorHistSpec, confBachelorQaBinning, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); + omegaHistManager.init(&hRegistry, omegaHistSpec, confOmegaSelection, confOmegaQaBinning, bachelorHistSpec, confBachelorQaBinning, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); } } hRegistry.print(); @@ -175,25 +177,25 @@ struct FemtoCascadeQa { if (xiSlice.size() == 0) { return; } - colHistManager.fill(col); + colHistManager.fill(col); for (auto const& xi : xiSlice) { - xiHistManager.fill(xi, tracks); + xiHistManager.fill(xi, tracks); } } PROCESS_SWITCH(FemtoCascadeQa, processXi, "Process Xis", true); - void processXiMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processXiMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { auto xiSlice = xiWithLabelPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); if (xiSlice.size() == 0) { return; } - colHistManager.fill(col, mcCols); + colHistManager.fill(col, mcCols); for (auto const& xi : xiSlice) { if (!xiCleaner.isClean(xi, mcParticles, mcMothers, mcPartonicMothers)) { continue; } - xiHistManager.fill(xi, tracks, mcParticles, mcMothers, mcPartonicMothers); + xiHistManager.fill(xi, tracks, mcParticles, mcMothers, mcPartonicMothers); } } PROCESS_SWITCH(FemtoCascadeQa, processXiMc, "Process Xis with MC information", false); @@ -204,34 +206,34 @@ struct FemtoCascadeQa { if (omegaSlice.size() == 0) { return; } - colHistManager.fill(col); + colHistManager.fill(col); for (auto const& omega : omegaSlice) { - omegaHistManager.fill(omega, tracks); + omegaHistManager.fill(omega, tracks); } } PROCESS_SWITCH(FemtoCascadeQa, processOmega, "Process Omegas", false); - void processOmegaMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoOmegasWithLabel const& /*omegas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processOmegaMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoOmegasWithLabel const& /*omegas*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { auto omegaSlice = omegaWithLabelPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); if (omegaSlice.size() == 0) { return; } - colHistManager.fill(col, mcCols); + colHistManager.fill(col, mcCols); for (auto const& omega : omegaSlice) { if (!omegaCleaner.isClean(omega, mcParticles, mcMothers, mcPartonicMothers)) { continue; } - omegaHistManager.fill(omega, tracks, mcParticles, mcMothers, mcPartonicMothers); + omegaHistManager.fill(omega, tracks, mcParticles, mcMothers, mcPartonicMothers); } } PROCESS_SWITCH(FemtoCascadeQa, processOmegaMc, "Process Omegas with MC information", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { o2::framework::WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoKinkQa.cxx b/PWGCF/Femto/Tasks/femtoKinkQa.cxx index 7b0c17d210a..877c0905b83 100644 --- a/PWGCF/Femto/Tasks/femtoKinkQa.cxx +++ b/PWGCF/Femto/Tasks/femtoKinkQa.cxx @@ -60,6 +60,8 @@ struct FemtoKinkQa { using FemtoSigmaPlusWithLabel = o2::soa::Join; using FemtoTracksWithLabel = o2::soa::Join; + using FemtoMcParticlesWithLabel = o2::soa::Join; + o2::framework::SliceCache cache; // setup for collisions @@ -118,7 +120,7 @@ struct FemtoKinkQa { void init(o2::framework::InitContext&) { - if ((doprocessSigma + doprocessSigmaMc + doprocessSigmaPlus + doprocessSigmaPlusMc) > 1) { + if ((static_cast(doprocessSigma) + static_cast(doprocessSigmaMc) + static_cast(doprocessSigmaPlus) + static_cast(doprocessSigmaPlusMc)) > 1) { LOG(fatal) << "Only one process can be activated"; } @@ -134,27 +136,27 @@ struct FemtoKinkQa { if (processData) { colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); - colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); chaDauHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confKinkChaDaughterBinning, confKinkChaDaughterQaBinning); if (doprocessSigma) { sigmaHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaBinning, confSigmaQaBinning); - sigmaHistManager.init(&hRegistry, sigmaHistSpec, confSigmaSelection, confSigmaQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); + sigmaHistManager.init(&hRegistry, sigmaHistSpec, confSigmaSelection, confSigmaQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); } if (doprocessSigmaPlus) { sigmaPlusHistSpec = kinkhistmanager::makeKinkQaHistSpecMap(confSigmaPlusBinning, confSigmaPlusQaBinning); - sigmaPlusHistManager.init(&hRegistry, sigmaPlusHistSpec, confSigmaPlusSelection, confSigmaPlusQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); + sigmaPlusHistManager.init(&hRegistry, sigmaPlusHistSpec, confSigmaPlusSelection, confSigmaPlusQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); } } else { colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); - colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); chaDauHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confKinkChaDaughterBinning, confKinkChaDaughterQaBinning); if (doprocessSigmaMc) { sigmaHistSpec = kinkhistmanager::makeKinkMcQaHistSpecMap(confSigmaBinning, confSigmaQaBinning); - sigmaHistManager.init(&hRegistry, sigmaHistSpec, confSigmaSelection, confSigmaQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); + sigmaHistManager.init(&hRegistry, sigmaHistSpec, confSigmaSelection, confSigmaQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); } if (doprocessSigmaPlusMc) { sigmaPlusHistSpec = kinkhistmanager::makeKinkMcQaHistSpecMap(confSigmaPlusBinning, confSigmaPlusQaBinning); - sigmaPlusHistManager.init(&hRegistry, sigmaPlusHistSpec, confSigmaPlusSelection, confSigmaPlusQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); + sigmaPlusHistManager.init(&hRegistry, sigmaPlusHistSpec, confSigmaPlusSelection, confSigmaPlusQaBinning, chaDauHistSpec, confKinkChaDaughterQaBinning); } } hRegistry.print(); @@ -166,25 +168,25 @@ struct FemtoKinkQa { if (sigmaSlice.size() == 0) { return; } - colHistManager.fill(col); + colHistManager.fill(col); for (auto const& sigma : sigmaSlice) { - sigmaHistManager.fill(sigma, tracks); + sigmaHistManager.fill(sigma, tracks); } } PROCESS_SWITCH(FemtoKinkQa, processSigma, "Process sigmas", true); - void processSigmaMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmasWithLabel const& /*sigmas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processSigmaMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmasWithLabel const& /*sigmas*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { auto sigmaSlice = sigmaWithLabelPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); if (sigmaSlice.size() == 0) { return; } - colHistManager.fill(col, mcCols); + colHistManager.fill(col, mcCols); for (auto const& sigma : sigmaSlice) { if (!sigmaCleaner.isClean(sigma, mcParticles, mcMothers, mcPartonicMothers)) { continue; } - sigmaHistManager.fill(sigma, tracks, mcParticles, mcMothers, mcPartonicMothers); + sigmaHistManager.fill(sigma, tracks, mcParticles, mcMothers, mcPartonicMothers); } } PROCESS_SWITCH(FemtoKinkQa, processSigmaMc, "Process sigmas", false); @@ -195,34 +197,34 @@ struct FemtoKinkQa { if (sigmaPlusSlice.size() == 0) { return; } - colHistManager.fill(col); + colHistManager.fill(col); for (auto const& sp : sigmaPlusSlice) { - sigmaPlusHistManager.fill(sp, tracks); + sigmaPlusHistManager.fill(sp, tracks); } } PROCESS_SWITCH(FemtoKinkQa, processSigmaPlus, "Process sigma plus", false); - void processSigmaPlusMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusWithLabel const& /*sigmaPlus*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processSigmaPlusMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusWithLabel const& /*sigmaPlus*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { auto sigmaPlusSlice = sigmaPlusWithLabelPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); if (sigmaPlusSlice.size() == 0) { return; } - colHistManager.fill(col, mcCols); + colHistManager.fill(col, mcCols); for (auto const& sigmaPlus : sigmaPlusSlice) { if (!sigmaPlusCleaner.isClean(sigmaPlus, mcParticles, mcMothers, mcPartonicMothers)) { continue; } - sigmaPlusHistManager.fill(sigmaPlus, tracks, mcParticles, mcMothers, mcPartonicMothers); + sigmaPlusHistManager.fill(sigmaPlus, tracks, mcParticles, mcMothers, mcPartonicMothers); } } PROCESS_SWITCH(FemtoKinkQa, processSigmaPlusMc, "Process sigmas", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { o2::framework::WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoMcParticleQa.cxx b/PWGCF/Femto/Tasks/femtoMcParticleQa.cxx new file mode 100644 index 00000000000..22e96ddaedb --- /dev/null +++ b/PWGCF/Femto/Tasks/femtoMcParticleQa.cxx @@ -0,0 +1,107 @@ +// Copyright 2019-2025 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file femtoMcParticleQa.cxx +/// \brief QA task for tracks +/// \author Anton Riedel, TU München, anton.riedel@cern.ch + +#include "PWGCF/Femto/Core/collisionHistManager.h" +#include "PWGCF/Femto/Core/mcBuilder.h" +#include "PWGCF/Femto/Core/mcParticleHistManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/particleCleaner.h" +#include "PWGCF/Femto/Core/partitions.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace o2::analysis::femto; + +struct FemtoMcParticleQa { + + // setup tables + using FemtoMcCollisions = o2::aod::FMcCols; + using FilteredFemtoMcCollisions = o2::soa::Filtered; + using FilteredFemtoMcCollision = FilteredFemtoMcCollisions::iterator; + + using FemtoMcParticles = o2::soa::Join; + + o2::framework::SliceCache cache; + + // setup collisions + mcbuilder::ConfMcCollisionFilters collisionSelection; + o2::framework::expressions::Filter collisionFilter = MAKE_MC_COLLISION_FILTER(collisionSelection); + colhistmanager::ConfCollisionBinning confCollisionBinning; + colhistmanager::CollisionHistManager colHistManager; + + // setup mc particles + mcbuilder::ConfMcParticleSelection1 confMcParticleSelection1; + mcparticlehistmanager::ConfMcParticleBinning1 confMcParticleBinning1; + mcparticlehistmanager::McParticleHistManager mcParticleHistManager1; + + o2::framework::Partition mcParticlesPartition1 = MAKE_MC_PARTICLE_PARTITION(confMcParticleSelection1); + o2::framework::Preslice perColReco = o2::aod::femtomcparticle::fMcColId; + + particlecleaner::ConfMcParticleCleaner1 confMcParticleCleaner1; + particlecleaner::ParticleCleaner mcParticleCleaner; + + o2::framework::HistogramRegistry hRegistry{"FemtoMcParticleQA", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; + + void init(o2::framework::InitContext&) + { + mcParticleCleaner.init(confMcParticleCleaner1); + + std::map> colHistSpec; + std::map> mcParticleHistSpec; + + colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning); + mcParticleHistSpec = mcparticlehistmanager::makeMcParticleHistSpecMap(confMcParticleBinning1); + mcParticleHistManager1.init(&hRegistry, mcParticleHistSpec, confMcParticleBinning1); + + hRegistry.print(); + }; + + void process(FilteredFemtoMcCollision const& col, FemtoMcParticles const& /*mcParticles*/, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + auto mcParticleSlice = mcParticlesPartition1->sliceByCached(o2::aod::femtomcparticle::fMcColId, col.globalIndex(), cache); + if (mcParticleSlice.size() == 0) { + return; + } + colHistManager.fill(col); + for (auto const& mcParticle : mcParticleSlice) { + if (!mcParticleCleaner.isClean(mcParticle, mcMothers, mcPartonicMothers)) { + continue; + } + mcParticleHistManager1.fill(mcParticle, mcMothers, mcPartonicMothers); + } + } +}; + +o2::framework::WorkflowSpec + defineDataProcessing(o2::framework::ConfigContext const& context) +{ + o2::framework::WorkflowSpec workflow{ + adaptAnalysisTask(context), + }; + return workflow; +} diff --git a/PWGCF/Femto/Tasks/femtoPairMcParticleMcParticle.cxx b/PWGCF/Femto/Tasks/femtoPairMcParticleMcParticle.cxx new file mode 100644 index 00000000000..0c0a4553359 --- /dev/null +++ b/PWGCF/Femto/Tasks/femtoPairMcParticleMcParticle.cxx @@ -0,0 +1,149 @@ +// Copyright 2019-2025 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file femtoPairMcParticleMcParticle.cxx +/// \brief Tasks that computes correlation between two tracks +/// \author Anton Riedel, TU München, anton.riedel@cern.ch + +#include "PWGCF/Femto/Core/closePairRejection.h" +#include "PWGCF/Femto/Core/collisionHistManager.h" +#include "PWGCF/Femto/Core/mcBuilder.h" +#include "PWGCF/Femto/Core/mcParticleHistManager.h" +#include "PWGCF/Femto/Core/modes.h" +#include "PWGCF/Femto/Core/pairBuilder.h" +#include "PWGCF/Femto/Core/pairHistManager.h" +#include "PWGCF/Femto/Core/particleCleaner.h" +#include "PWGCF/Femto/Core/partitions.h" +#include "PWGCF/Femto/DataModel/FemtoTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace o2::analysis::femto; + +struct FemtoPairMcParticleMcParticle { + + // setup tables + using FemtoMcCollisions = o2::aod::FMcCols; + using FilteredFemtoMcCollisions = o2::soa::Filtered; + using FilteredFemtoMcCollision = FilteredFemtoMcCollisions::iterator; + + using FemtoMcParticles = o2::soa::Join; + + o2::framework::SliceCache cache; + + // setup collisions + mcbuilder::ConfMcCollisionFilters collisionSelection; + o2::framework::expressions::Filter collisionFilter = MAKE_MC_COLLISION_FILTER(collisionSelection); + colhistmanager::ConfCollisionBinning confCollisionBinning; + colhistmanager::CollisionHistManager colHistManager; + + // setup mc particles + mcbuilder::ConfMcParticleSelection1 confMcParticleSelection1; + mcparticlehistmanager::ConfMcParticleBinning1 confMcParticleBinning1; + mcparticlehistmanager::McParticleHistManager mcParticleHistManager1; + particlecleaner::ConfMcParticleCleaner1 confMcParticleCleaner1; + particlecleaner::ParticleCleaner mcParticleCleaner1; + + o2::framework::Partition mcParticlesPartition1 = MAKE_MC_PARTICLE_PARTITION(confMcParticleSelection1); + + mcbuilder::ConfMcParticleSelection2 confMcParticleSelection2; + mcparticlehistmanager::ConfMcParticleBinning2 confMcParticleBinning2; + mcparticlehistmanager::McParticleHistManager mcParticleHistManager2; + particlecleaner::ConfMcParticleCleaner2 confMcParticleCleaner2; + particlecleaner::ParticleCleaner mcParticleCleaner2; + + o2::framework::Partition mcParticlesPartition2 = MAKE_MC_PARTICLE_PARTITION(confMcParticleSelection1); + + o2::framework::Preslice perColParticles = o2::aod::femtomcparticle::fMcColId; + + // setup pairs + pairhistmanager::ConfPairBinning confPairBinning; + pairhistmanager::ConfPairCuts confPairCuts; + + closepairrejection::ConfCprTrackTrack confCpr; + + pairbuilder::PairMcParticleMcParticleBuilder< + mcparticlehistmanager::PrefixMcParticle1, + mcparticlehistmanager::PrefixMcParticle2, + pairhistmanager::PrefixMcParticleMcParticleSe, + pairhistmanager::PrefixMcParticleMcParticleMe, + closepairrejection::PrefixMcParticleMcParticleSe, + closepairrejection::PrefixMcParticleMcParticleMe> + pairMcParticleMcParticleBuilder; + + // setup mixing + std::vector defaultVtxBins{10, -10, 10}; + std::vector defaultMultBins{50, 0, 200}; + std::vector defaultCentBins{10, 0, 100}; + o2::framework::ColumnBinningPolicy mixBinsVtxMult{{defaultVtxBins, defaultMultBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxCent{{defaultVtxBins, defaultCentBins}, true}; + o2::framework::ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; + pairhistmanager::ConfMixing confMixing; + + o2::framework::HistogramRegistry hRegistry{"FemtoMcParticleMcParticle", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; + + void init(o2::framework::InitContext&) + { + // setup columnpolicy for binning + // default values are used during instantiation, so we need to explicity update them here + mixBinsVtxMult = {{confMixing.vtxBins, confMixing.multBins.value}, true}; + mixBinsVtxCent = {{confMixing.vtxBins.value, confMixing.centBins.value}, true}; + mixBinsVtxMultCent = {{confMixing.vtxBins.value, confMixing.multBins.value, confMixing.centBins.value}, true}; + + // setup histogram specs + std::map> colHistSpec; + std::map> mcParticleHistSpec1; + std::map> mcParticleHistSpec2; + std::map> pairHistSpec; + std::map> cprHistSpec = closepairrejection::makeCprHistSpecMap(confCpr); + + colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); + mcParticleHistSpec1 = mcparticlehistmanager::makeMcParticleHistSpecMap(confMcParticleBinning1); + mcParticleHistSpec2 = mcparticlehistmanager::makeMcParticleHistSpecMap(confMcParticleBinning2); + pairHistSpec = pairhistmanager::makePairMcTruthHistSpecMap(confPairBinning, confMixing); + pairMcParticleMcParticleBuilder.init(&hRegistry, confCollisionBinning, confMcParticleSelection1, confMcParticleSelection2, confMcParticleBinning1, confMcParticleBinning2, confMcParticleCleaner1, confMcParticleCleaner2, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, mcParticleHistSpec1, mcParticleHistSpec2, pairHistSpec, cprHistSpec); + + hRegistry.print(); + }; + + void processSameEvent(FilteredFemtoMcCollision const& col, FemtoMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + pairMcParticleMcParticleBuilder.processSameEvent(col, mcParticles, mcMothers, mcPartonicMothers, mcParticlesPartition1, mcParticlesPartition2, cache); + } + PROCESS_SWITCH(FemtoPairMcParticleMcParticle, processSameEvent, "Enable processing same event processing", true); + + void processMixedEvent(FilteredFemtoMcCollisions const& cols, FemtoMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + { + pairMcParticleMcParticleBuilder.processMixedEvent(cols, mcParticles, mcMothers, mcPartonicMothers, mcParticlesPartition1, mcParticlesPartition2, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + } + PROCESS_SWITCH(FemtoPairMcParticleMcParticle, processMixedEvent, "Enable processing mixed event processing", true); +}; + +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) +{ + o2::framework::WorkflowSpec workflow{ + adaptAnalysisTask(context), + }; + return workflow; +} diff --git a/PWGCF/Femto/Tasks/femtoPairTrackCascade.cxx b/PWGCF/Femto/Tasks/femtoPairTrackCascade.cxx index 59cbf706fb1..e9433fb4f2b 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackCascade.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackCascade.cxx @@ -63,6 +63,8 @@ struct FemtoPairTrackCascade { using FemtoXisWithLabel = o2::soa::Join; using FemtoOmegasWithLabel = o2::soa::Join; + using FemtoMcParticlesWithLabel = o2::soa::Join; + o2::framework::SliceCache cache; // setup collisions @@ -200,11 +202,11 @@ struct FemtoPairTrackCascade { pairTrackCascadeHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confMixing); if (processXi) { xiHistSpec = cascadehistmanager::makeCascadeHistSpecMap(confXiBinning); - pairTrackXiBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confXiSelection, confXiCleaner, confCprBachelor, confCprV0Daughter, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, xiHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, pairTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter); + pairTrackXiBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confXiSelection, confXiCleaner, confCprBachelor, confCprV0Daughter, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, xiHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, pairTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter); } else { omegaHistSpec = cascadehistmanager::makeCascadeHistSpecMap(confOmegaBinning); pairTrackCascadeHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confMixing); - pairTrackOmegaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confOmegaSelection, confOmegaCleaner, confCprBachelor, confCprV0Daughter, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, omegaHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, pairTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter); + pairTrackOmegaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confOmegaSelection, confOmegaCleaner, confCprBachelor, confCprV0Daughter, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, omegaHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, pairTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter); } } else { colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); @@ -215,67 +217,67 @@ struct FemtoPairTrackCascade { pairTrackCascadeHistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning, confMixing); if (processXi) { xiHistSpec = cascadehistmanager::makeCascadeMcHistSpecMap(confXiBinning); - pairTrackXiBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confXiSelection, confXiCleaner, confCprBachelor, confCprV0Daughter, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, xiHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, pairTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter); + pairTrackXiBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confXiSelection, confXiCleaner, confCprBachelor, confCprV0Daughter, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, xiHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, pairTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter); } else { omegaHistSpec = cascadehistmanager::makeCascadeMcHistSpecMap(confOmegaBinning); - pairTrackOmegaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confOmegaSelection, confOmegaCleaner, confCprBachelor, confCprV0Daughter, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, omegaHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, pairTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter); + pairTrackOmegaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confOmegaSelection, confOmegaCleaner, confCprBachelor, confCprV0Daughter, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, omegaHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, pairTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter); } } }; void processXiSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoXis const& xis) { - pairTrackXiBuilder.processSameEvent(col, tracks, trackPartition, xis, xiPartition, cache); + pairTrackXiBuilder.processSameEvent(col, tracks, trackPartition, xis, xiPartition, cache); } PROCESS_SWITCH(FemtoPairTrackCascade, processXiSameEvent, "Enable processing same event processing for tracks and xis", true); - void processXiSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& xis, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processXiSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& xis, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairTrackXiBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, xis, xiWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + pairTrackXiBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, xis, xiWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoPairTrackCascade, processXiSameEventMc, "Enable processing same event processing for tracks and xis with mc information", false); void processXiMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoXis const& /*xis*/) { - pairTrackXiBuilder.processMixedEvent(cols, tracks, trackPartition, xiPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackXiBuilder.processMixedEvent(cols, tracks, trackPartition, xiPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackCascade, processXiMixedEvent, "Enable processing mixed event processing for tracks and xis", true); - void processXiMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processXiMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairTrackXiBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, xiWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackXiBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, xiWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackCascade, processXiMixedEventMc, "Enable processing mixed event processing for tracks and xis with mc information", false); void processOmegaSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoOmegas const& omegas) { - pairTrackOmegaBuilder.processSameEvent(col, tracks, trackPartition, omegas, omegaPartition, cache); + pairTrackOmegaBuilder.processSameEvent(col, tracks, trackPartition, omegas, omegaPartition, cache); } PROCESS_SWITCH(FemtoPairTrackCascade, processOmegaSameEvent, "Enable processing same event processing for tracks and omegas", false); - void processOmegaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoOmegasWithLabel const& omegas, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processOmegaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoOmegasWithLabel const& omegas, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairTrackOmegaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, omegas, omegaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + pairTrackOmegaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, omegas, omegaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoPairTrackCascade, processOmegaSameEventMc, "Enable processing same event processing for tracks and omegas with mc information", false); void processOmegaMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoOmegas const& /*omegas*/) { - pairTrackOmegaBuilder.processMixedEvent(cols, tracks, trackPartition, omegaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackOmegaBuilder.processMixedEvent(cols, tracks, trackPartition, omegaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackCascade, processOmegaMixedEvent, "Enable processing mixed event processing for tracks and omegas", false); - void processOmegaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processOmegaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairTrackOmegaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, omegaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackOmegaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, omegaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackCascade, processOmegaMixedEventMc, "Enable processing mixed event processing for tracks and omegas with mc information", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { o2::framework::WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx b/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx index 2b0730109f3..dd7ac4bfbb1 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackKink.cxx @@ -64,6 +64,8 @@ struct FemtoPairTrackKink { using FemtoSigmasWithLabel = o2::soa::Join; using FemtoSigmaPlusWithLabel = o2::soa::Join; + using FemtoMcParticlesWithLabel = o2::soa::Join; + o2::framework::SliceCache cache; // setup collisions @@ -184,10 +186,10 @@ struct FemtoPairTrackKink { pairTrackKinkHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confMixing); if (processSigma) { sigmaHistSpec = kinkhistmanager::makeKinkHistSpecMap(confSigmaBinning); - pairTrackSigmaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confSigmaSelection, confSigmaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec); + pairTrackSigmaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confSigmaSelection, confSigmaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec); } else { sigmaPlusHistSpec = kinkhistmanager::makeKinkHistSpecMap(confSigmaPlusBinning); - pairTrackSigmaPlusBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confSigmaPlusSelection, confSigmaPlusCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaPlusHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec); + pairTrackSigmaPlusBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confSigmaPlusSelection, confSigmaPlusCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaPlusHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec); } } else { colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); @@ -196,10 +198,10 @@ struct FemtoPairTrackKink { pairTrackKinkHistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning, confMixing); if (processSigma) { sigmaHistSpec = kinkhistmanager::makeKinkMcHistSpecMap(confSigmaBinning); - pairTrackSigmaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confSigmaSelection, confSigmaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec); + pairTrackSigmaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confSigmaSelection, confSigmaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec); } else { sigmaPlusHistSpec = kinkhistmanager::makeKinkMcHistSpecMap(confSigmaPlusBinning); - pairTrackSigmaPlusBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confSigmaPlusSelection, confSigmaPlusCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaPlusHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec); + pairTrackSigmaPlusBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, confSigmaPlusSelection, confSigmaPlusCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, sigmaPlusHistSpec, chaDauSpec, pairTrackKinkHistSpec, cprHistSpec); } } hRegistry.print(); @@ -207,57 +209,57 @@ struct FemtoPairTrackKink { void processSigmaSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoSigmas const& sigmas) { - pairTrackSigmaBuilder.processSameEvent(col, tracks, trackPartition, sigmas, sigmaPartition, cache); + pairTrackSigmaBuilder.processSameEvent(col, tracks, trackPartition, sigmas, sigmaPartition, cache); } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaSameEvent, "Enable processing same event processing for tracks and sigmas", true); - void processSigmaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmasWithLabel const& sigmas, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processSigmaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmasWithLabel const& sigmas, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairTrackSigmaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, sigmas, sigmaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + pairTrackSigmaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, sigmas, sigmaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaSameEventMc, "Enable processing same event processing for tracks and sigmas with MC information", false); void processSigmaMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoSigmas const& /*sigmas*/) { - pairTrackSigmaBuilder.processMixedEvent(cols, tracks, trackPartition, sigmaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackSigmaBuilder.processMixedEvent(cols, tracks, trackPartition, sigmaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaMixedEvent, "Enable processing mixed event processing for tracks and sigmas", true); - void processSigmaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmasWithLabel const& /*sigmas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processSigmaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmasWithLabel const& /*sigmas*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairTrackSigmaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, sigmaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackSigmaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, sigmaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaMixedEventMc, "Enable processing mixed event processing for tracks and sigmas with MC information", false); void processSigmaPlusSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoSigmaPlus const& sigmaplus) { - pairTrackSigmaPlusBuilder.processSameEvent(col, tracks, trackPartition, sigmaplus, sigmaPlusPartition, cache); + pairTrackSigmaPlusBuilder.processSameEvent(col, tracks, trackPartition, sigmaplus, sigmaPlusPartition, cache); } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaPlusSameEvent, "Enable processing same event processing for tracks and sigma plus", false); - void processSigmaPlusSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusWithLabel const& sigmaplus, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processSigmaPlusSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusWithLabel const& sigmaplus, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairTrackSigmaPlusBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, sigmaplus, sigmaPlusWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + pairTrackSigmaPlusBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, sigmaplus, sigmaPlusWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaPlusSameEventMc, "Enable processing same event processing for tracks and sigma plus with MC information", false); void processSigmaPlusMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoSigmaPlus const& /*sigmaplus*/) { - pairTrackSigmaPlusBuilder.processMixedEvent(cols, tracks, trackPartition, sigmaPlusPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackSigmaPlusBuilder.processMixedEvent(cols, tracks, trackPartition, sigmaPlusPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaPlusMixedEvent, "Enable processing mixed event processing for tracks and sigma plus", false); - void processSigmaPlusMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusWithLabel const& /*sigmaplus*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processSigmaPlusMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoSigmaPlusWithLabel const& /*sigmaplus*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairTrackSigmaPlusBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, sigmaPlusWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackSigmaPlusBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, sigmaPlusWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackKink, processSigmaPlusMixedEventMc, "Enable processing mixed event processing for tracks and sigma plus with MC information", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { o2::framework::WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx b/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx index 688d95a4d0a..ddf110af478 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackTrack.cxx @@ -60,6 +60,8 @@ struct FemtoPairTrackTrack { using FemtoTracksWithLabel = o2::soa::Join; + using FemtoMcParticlesWithLabel = o2::soa::Join; + o2::framework::SliceCache cache; // setup collisions @@ -116,7 +118,7 @@ struct FemtoPairTrackTrack { void init(o2::framework::InitContext&) { - if ((doprocessSameEvent + doprocessSameEventWithMass + doprocessSameEventMc) > 1 || (doprocessMixedEvent + doprocessMixedEventWithMass + doprocessMixedEventMc) > 1) { + if ((static_cast(doprocessSameEvent) + static_cast(doprocessSameEventWithMass) + static_cast(doprocessSameEventMc)) > 1 || (static_cast(doprocessMixedEvent) + static_cast(doprocessMixedEventWithMass) + static_cast(doprocessMixedEventMc)) > 1) { LOG(fatal) << "More than 1 same or mixed event process function is activated. Breaking..."; } bool processData = doprocessSameEvent || doprocessMixedEvent || doprocessSameEventWithMass || doprocessMixedEventWithMass; @@ -143,58 +145,58 @@ struct FemtoPairTrackTrack { trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning1); trackHistSpec2 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning2); pairHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confMixing); - pairTrackTrackBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confTrackCleaner2, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec1, trackHistSpec2, pairHistSpec, cprHistSpec); + pairTrackTrackBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confTrackCleaner2, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec1, trackHistSpec2, pairHistSpec, cprHistSpec); } else { colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); trackHistSpec1 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning1); trackHistSpec2 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning2); pairHistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning, confMixing); - pairTrackTrackBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confTrackCleaner2, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec1, trackHistSpec2, pairHistSpec, cprHistSpec); + pairTrackTrackBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confTrackCleaner2, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec1, trackHistSpec2, pairHistSpec, cprHistSpec); } hRegistry.print(); }; void processSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks) { - pairTrackTrackBuilder.processSameEvent(col, tracks, trackPartition1, trackPartition2, cache); + pairTrackTrackBuilder.processSameEvent(col, tracks, trackPartition1, trackPartition2, cache); } PROCESS_SWITCH(FemtoPairTrackTrack, processSameEvent, "Enable processing same event processing", true); void processSameEventWithMass(FilteredFemtoCollision const& col, FemtoTracksWithMass const& tracks) { - pairTrackTrackBuilder.processSameEvent(col, tracks, trackWithMassPartition1, trackWithMassPartition2, cache); + pairTrackTrackBuilder.processSameEvent(col, tracks, trackWithMassPartition1, trackWithMassPartition2, cache); } PROCESS_SWITCH(FemtoPairTrackTrack, processSameEventWithMass, "Enable processing same event processing (with track masses)", false); - void processSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairTrackTrackBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, mcParticles, mcMothers, mcPartonicMothers, cache); + pairTrackTrackBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoPairTrackTrack, processSameEventMc, "Enable processing same event processing", false); void processMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks) { - pairTrackTrackBuilder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackTrackBuilder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackTrack, processMixedEvent, "Enable processing mixed event processing", true); void processMixedEventWithMass(FilteredFemtoCollisions const& cols, FemtoTracksWithMass const& tracks) { - pairTrackTrackBuilder.processMixedEvent(cols, tracks, trackWithMassPartition1, trackWithMassPartition2, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackTrackBuilder.processMixedEvent(cols, tracks, trackWithMassPartition1, trackWithMassPartition2, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackTrack, processMixedEventWithMass, "Enable processing mixed event processing (with track masses)", false); - void processMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairTrackTrackBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackTrackBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackTrack, processMixedEventMc, "Enable processing mixed event processing", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { o2::framework::WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoPairTrackTwoTrackResonance.cxx b/PWGCF/Femto/Tasks/femtoPairTrackTwoTrackResonance.cxx index ff71243e53c..f5fb9088aa5 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackTwoTrackResonance.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackTwoTrackResonance.cxx @@ -151,7 +151,7 @@ struct FemtoPairTrackTwoTrackResonance { void init(o2::framework::InitContext&) { - if (((doprocessPhiSameEvent || doprocessPhiMixedEvent) + (doprocessKstar0SameEvent || doprocessKstar0MixedEvent)) + (doprocessRho0SameEvent || doprocessRho0MixedEvent) > 1) { + if ((static_cast(doprocessPhiSameEvent || doprocessPhiMixedEvent) + static_cast(doprocessKstar0SameEvent || doprocessKstar0MixedEvent)) + static_cast(doprocessRho0SameEvent || doprocessRho0MixedEvent) > 1) { LOG(fatal) << "Can only process SE/ME for phi-tracks, rho-tracks or k0*-tracks"; } @@ -172,65 +172,65 @@ struct FemtoPairTrackTwoTrackResonance { if (doprocessPhiSameEvent || doprocessPhiMixedEvent) { auto phiHistSpec = twotrackresonancehistmanager::makeTwoTrackResonanceHistSpecMap(confPhiBinning); auto pairTrackPhiHistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confMixing); - pairTrackPhiBuilder.init(&hRegistry, confCollisionBinning, trackSelection, phiSelection, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, phiHistSpec, posDauSpec, negDauSpec, pairTrackPhiHistSpec, cprHistSpec); + pairTrackPhiBuilder.init(&hRegistry, confCollisionBinning, trackSelection, phiSelection, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, phiHistSpec, posDauSpec, negDauSpec, pairTrackPhiHistSpec, cprHistSpec); } // setup for kstar0 if (doprocessKstar0SameEvent || doprocessKstar0MixedEvent) { auto kstar0HistSpec = twotrackresonancehistmanager::makeTwoTrackResonanceHistSpecMap(confKstar0Binning); auto pairTrackKstar0HistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confMixing); - pairTrackKstar0Builder.init(&hRegistry, confCollisionBinning, trackSelection, kstar0Selection, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, kstar0HistSpec, posDauSpec, negDauSpec, pairTrackKstar0HistSpec, cprHistSpec); + pairTrackKstar0Builder.init(&hRegistry, confCollisionBinning, trackSelection, kstar0Selection, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, kstar0HistSpec, posDauSpec, negDauSpec, pairTrackKstar0HistSpec, cprHistSpec); } // setup for kstar0 if (doprocessRho0SameEvent || doprocessRho0MixedEvent) { auto rho0HistSpec = twotrackresonancehistmanager::makeTwoTrackResonanceHistSpecMap(confRho0Binning); auto pairTrackRho0HistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confMixing); - pairTrackRho0Builder.init(&hRegistry, confCollisionBinning, trackSelection, rho0Selection, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, rho0HistSpec, posDauSpec, negDauSpec, pairTrackRho0HistSpec, cprHistSpec); + pairTrackRho0Builder.init(&hRegistry, confCollisionBinning, trackSelection, rho0Selection, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, rho0HistSpec, posDauSpec, negDauSpec, pairTrackRho0HistSpec, cprHistSpec); } }; void processPhiSameEvent(FilteredCollision const& col, FemtoTracks const& tracks, FemtoPhis const& phis) { - pairTrackPhiBuilder.processSameEvent(col, tracks, trackPartition, phis, phiPartition, cache); + pairTrackPhiBuilder.processSameEvent(col, tracks, trackPartition, phis, phiPartition, cache); } PROCESS_SWITCH(FemtoPairTrackTwoTrackResonance, processPhiSameEvent, "Enable processing same event processing for tracks and phis", true); void processPhiMixedEvent(FilteredCollisions const& cols, FemtoTracks const& tracks, FemtoPhis const& /*phis*/) { - pairTrackPhiBuilder.processMixedEvent(cols, tracks, trackPartition, phiPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackPhiBuilder.processMixedEvent(cols, tracks, trackPartition, phiPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackTwoTrackResonance, processPhiMixedEvent, "Enable processing mixed event processing for tracks and phis", true); void processKstar0SameEvent(FilteredCollision const& col, FemtoTracks const& tracks, FemtoKstar0s const& kstar0s) { - pairTrackKstar0Builder.processSameEvent(col, tracks, trackPartition, kstar0s, kstar0Partition, cache); + pairTrackKstar0Builder.processSameEvent(col, tracks, trackPartition, kstar0s, kstar0Partition, cache); } PROCESS_SWITCH(FemtoPairTrackTwoTrackResonance, processKstar0SameEvent, "Enable processing same event processing for tracks and kstar0s", false); void processKstar0MixedEvent(FilteredCollisions const& cols, FemtoTracks const& tracks, FemtoKstar0s const& /*kstar0s*/) { - pairTrackKstar0Builder.processMixedEvent(cols, tracks, trackPartition, kstar0Partition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackKstar0Builder.processMixedEvent(cols, tracks, trackPartition, kstar0Partition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackTwoTrackResonance, processKstar0MixedEvent, "Enable processing mixed event processing for tracks and kstar0s", false); void processRho0SameEvent(FilteredCollision const& col, FemtoTracks const& tracks, FemtoRho0s const& rho0s) { - pairTrackRho0Builder.processSameEvent(col, tracks, trackPartition, rho0s, rho0Partition, cache); + pairTrackRho0Builder.processSameEvent(col, tracks, trackPartition, rho0s, rho0Partition, cache); } PROCESS_SWITCH(FemtoPairTrackTwoTrackResonance, processRho0SameEvent, "Enable processing same event processing for tracks and rho0s", false); void processRho0MixedEvent(FilteredCollisions const& cols, FemtoTracks const& tracks, FemtoRho0s const& /*rho0s*/) { - pairTrackRho0Builder.processMixedEvent(cols, tracks, trackPartition, rho0Partition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackRho0Builder.processMixedEvent(cols, tracks, trackPartition, rho0Partition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackTwoTrackResonance, processRho0MixedEvent, "Enable processing mixed event processing for tracks and rho0s", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { o2::framework::WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx b/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx index 6747aabb561..69087f58180 100644 --- a/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx +++ b/PWGCF/Femto/Tasks/femtoPairTrackV0.cxx @@ -63,6 +63,8 @@ struct FemtoPairTrackV0 { using FemtoLambdasWithLabel = o2::soa::Join; using FemtoK0shortsWithLabel = o2::soa::Join; + using FemtoMcParticlesWithLabel = o2::soa::Join; + o2::framework::SliceCache cache; // setup collisions @@ -188,10 +190,10 @@ struct FemtoPairTrackV0 { pairTrackV0HistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confMixing); if (processLambda) { lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); - pairTrackLambdaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, lambdaSelection, confLambdaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairTrackV0HistSpec, cprHistSpec); + pairTrackLambdaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, lambdaSelection, confLambdaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairTrackV0HistSpec, cprHistSpec); } else { k0shortHistSpec = v0histmanager::makeV0HistSpecMap(confK0shortBinning); - pairTrackK0shortBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, lambdaSelection, confTrackCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairTrackV0HistSpec, cprHistSpec); + pairTrackK0shortBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, lambdaSelection, confTrackCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairTrackV0HistSpec, cprHistSpec); } } else { colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); @@ -201,10 +203,10 @@ struct FemtoPairTrackV0 { pairTrackV0HistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning, confMixing); if (processLambda) { lambdaHistSpec = v0histmanager::makeV0McHistSpecMap(confLambdaBinning); - pairTrackLambdaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, lambdaSelection, confLambdaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairTrackV0HistSpec, cprHistSpec); + pairTrackLambdaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, lambdaSelection, confLambdaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairTrackV0HistSpec, cprHistSpec); } else { k0shortHistSpec = v0histmanager::makeV0McHistSpecMap(confK0shortBinning); - pairTrackK0shortBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, lambdaSelection, confLambdaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairTrackV0HistSpec, cprHistSpec); + pairTrackK0shortBuilder.init(&hRegistry, confCollisionBinning, confTrackSelection, confTrackCleaner, lambdaSelection, confLambdaCleaner, confCpr, confMixing, confPairBinning, confPairCuts, colHistSpec, trackHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairTrackV0HistSpec, cprHistSpec); } } hRegistry.print(); @@ -212,57 +214,57 @@ struct FemtoPairTrackV0 { void processLambdaSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoLambdas const& lambdas) { - pairTrackLambdaBuilder.processSameEvent(col, tracks, trackPartition, lambdas, lambdaPartition, cache); + pairTrackLambdaBuilder.processSameEvent(col, tracks, trackPartition, lambdas, lambdaPartition, cache); } PROCESS_SWITCH(FemtoPairTrackV0, processLambdaSameEvent, "Enable processing same event processing for tracks and lambdas", true); - void processLambdaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& lambdas, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processLambdaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& lambdas, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairTrackLambdaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, lambdas, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + pairTrackLambdaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, lambdas, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoPairTrackV0, processLambdaSameEventMc, "Enable processing same event processing for tracks and lambdas with MC information", false); void processLambdaMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoLambdas const& /*lambas*/) { - pairTrackLambdaBuilder.processMixedEvent(cols, tracks, trackPartition, lambdaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackLambdaBuilder.processMixedEvent(cols, tracks, trackPartition, lambdaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackV0, processLambdaMixedEvent, "Enable processing mixed event processing for tracks and lambdas", true); - void processLambdaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processLambdaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambas*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairTrackLambdaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackLambdaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackV0, processLambdaMixedEventMc, "Enable processing mixed event processing for tracks and lambdas with MC information", false); void processK0shortSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoK0shorts const& k0shorts) { - pairTrackK0shortBuilder.processSameEvent(col, tracks, trackPartition, k0shorts, k0shortPartition, cache); + pairTrackK0shortBuilder.processSameEvent(col, tracks, trackPartition, k0shorts, k0shortPartition, cache); } PROCESS_SWITCH(FemtoPairTrackV0, processK0shortSameEvent, "Enable processing same event processing for tracks and k0shorts", false); - void processK0shortSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& k0shorts, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processK0shortSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& k0shorts, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairTrackK0shortBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, k0shorts, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + pairTrackK0shortBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition, k0shorts, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoPairTrackV0, processK0shortSameEventMc, "Enable processing same event processing for tracks and k0shorts with MC information", false); void processK0shortMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoK0shorts const& /*k0shorts*/) { - pairTrackK0shortBuilder.processMixedEvent(cols, tracks, trackPartition, k0shortPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackK0shortBuilder.processMixedEvent(cols, tracks, trackPartition, k0shortPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackV0, processK0shortMixedEvent, "Enable processing mixed event processing for tracks and k0shorts", false); - void processK0shortMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& /*k0shorts*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processK0shortMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& /*k0shorts*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairTrackK0shortBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairTrackK0shortBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairTrackV0, processK0shortMixedEventMc, "Enable processing mixed event processing for tracks and k0shorts with mc information", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { o2::framework::WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoPairV0TwoTrackResonance.cxx b/PWGCF/Femto/Tasks/femtoPairV0TwoTrackResonance.cxx index 80211c7020a..6a0e25e40d2 100644 --- a/PWGCF/Femto/Tasks/femtoPairV0TwoTrackResonance.cxx +++ b/PWGCF/Femto/Tasks/femtoPairV0TwoTrackResonance.cxx @@ -19,8 +19,8 @@ #include "PWGCF/Femto/Core/modes.h" #include "PWGCF/Femto/Core/pairBuilder.h" #include "PWGCF/Femto/Core/pairHistManager.h" +#include "PWGCF/Femto/Core/particleCleaner.h" #include "PWGCF/Femto/Core/partitions.h" -#include "PWGCF/Femto/Core/trackBuilder.h" #include "PWGCF/Femto/Core/trackHistManager.h" #include "PWGCF/Femto/Core/twoTrackResonanceBuilder.h" #include "PWGCF/Femto/Core/twoTrackResonanceHistManager.h" @@ -243,12 +243,12 @@ struct FemtoPairV0TwoTrackResonance { { // all pair combinations share the same histogram prefixes, so only one combination can be processed per workflow instance - if ((doprocessLambdaPhiSameEvent || doprocessLambdaPhiMixedEvent) + - (doprocessLambdaKstar0SameEvent || doprocessLambdaKstar0MixedEvent) + - (doprocessLambdaRho0SameEvent || doprocessLambdaRho0MixedEvent) + - (doprocessK0shortPhiSameEvent || doprocessK0shortPhiMixedEvent) + - (doprocessK0shortKstar0SameEvent || doprocessK0shortKstar0MixedEvent) + - (doprocessK0shortRho0SameEvent || doprocessK0shortRho0MixedEvent) > + if (static_cast(doprocessLambdaPhiSameEvent || doprocessLambdaPhiMixedEvent) + + static_cast(doprocessLambdaKstar0SameEvent || doprocessLambdaKstar0MixedEvent) + + static_cast(doprocessLambdaRho0SameEvent || doprocessLambdaRho0MixedEvent) + + static_cast(doprocessK0shortPhiSameEvent || doprocessK0shortPhiMixedEvent) + + static_cast(doprocessK0shortKstar0SameEvent || doprocessK0shortKstar0MixedEvent) + + static_cast(doprocessK0shortRho0SameEvent || doprocessK0shortRho0MixedEvent) > 1) { LOG(fatal) << "Can only process one v0-resonance combination (lambda/k0short x phi/kstar0/rho0)"; } @@ -277,128 +277,128 @@ struct FemtoPairV0TwoTrackResonance { if (doprocessLambdaPhiSameEvent || doprocessLambdaPhiMixedEvent) { auto lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); auto phiHistSpec = twotrackresonancehistmanager::makeTwoTrackResonanceHistSpecMap(confPhiBinning); - pairLambdaPhiBuilder.init(&hRegistry, confCollisionBinning, lambdaSelection, phiSelection, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, v0PosDauSpec, v0NegDauSpec, phiHistSpec, resoPosDauSpec, resoNegDauSpec, pairV0TwoTrackResonanceHistSpec, cprHistSpecPos, cprHistSpecNeg); + pairLambdaPhiBuilder.init(&hRegistry, confCollisionBinning, lambdaSelection, phiSelection, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, v0PosDauSpec, v0NegDauSpec, phiHistSpec, resoPosDauSpec, resoNegDauSpec, pairV0TwoTrackResonanceHistSpec, cprHistSpecPos, cprHistSpecNeg); } // setup for lambda-kstar0 if (doprocessLambdaKstar0SameEvent || doprocessLambdaKstar0MixedEvent) { auto lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); auto kstar0HistSpec = twotrackresonancehistmanager::makeTwoTrackResonanceHistSpecMap(confKstar0Binning); - pairLambdaKstar0Builder.init(&hRegistry, confCollisionBinning, lambdaSelection, kstar0Selection, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, v0PosDauSpec, v0NegDauSpec, kstar0HistSpec, resoPosDauSpec, resoNegDauSpec, pairV0TwoTrackResonanceHistSpec, cprHistSpecPos, cprHistSpecNeg); + pairLambdaKstar0Builder.init(&hRegistry, confCollisionBinning, lambdaSelection, kstar0Selection, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, v0PosDauSpec, v0NegDauSpec, kstar0HistSpec, resoPosDauSpec, resoNegDauSpec, pairV0TwoTrackResonanceHistSpec, cprHistSpecPos, cprHistSpecNeg); } // setup for lambda-rho0 if (doprocessLambdaRho0SameEvent || doprocessLambdaRho0MixedEvent) { auto lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); auto rho0HistSpec = twotrackresonancehistmanager::makeTwoTrackResonanceHistSpecMap(confRho0Binning); - pairLambdaRho0Builder.init(&hRegistry, confCollisionBinning, lambdaSelection, rho0Selection, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, v0PosDauSpec, v0NegDauSpec, rho0HistSpec, resoPosDauSpec, resoNegDauSpec, pairV0TwoTrackResonanceHistSpec, cprHistSpecPos, cprHistSpecNeg); + pairLambdaRho0Builder.init(&hRegistry, confCollisionBinning, lambdaSelection, rho0Selection, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, v0PosDauSpec, v0NegDauSpec, rho0HistSpec, resoPosDauSpec, resoNegDauSpec, pairV0TwoTrackResonanceHistSpec, cprHistSpecPos, cprHistSpecNeg); } // setup for k0short-phi if (doprocessK0shortPhiSameEvent || doprocessK0shortPhiMixedEvent) { auto k0shortHistSpec = v0histmanager::makeV0HistSpecMap(confK0shortBinning); auto phiHistSpec = twotrackresonancehistmanager::makeTwoTrackResonanceHistSpecMap(confPhiBinning); - pairK0shortPhiBuilder.init(&hRegistry, confCollisionBinning, k0shortSelection, phiSelection, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, v0PosDauSpec, v0NegDauSpec, phiHistSpec, resoPosDauSpec, resoNegDauSpec, pairV0TwoTrackResonanceHistSpec, cprHistSpecPos, cprHistSpecNeg); + pairK0shortPhiBuilder.init(&hRegistry, confCollisionBinning, k0shortSelection, phiSelection, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, v0PosDauSpec, v0NegDauSpec, phiHistSpec, resoPosDauSpec, resoNegDauSpec, pairV0TwoTrackResonanceHistSpec, cprHistSpecPos, cprHistSpecNeg); } // setup for k0short-kstar0 if (doprocessK0shortKstar0SameEvent || doprocessK0shortKstar0MixedEvent) { auto k0shortHistSpec = v0histmanager::makeV0HistSpecMap(confK0shortBinning); auto kstar0HistSpec = twotrackresonancehistmanager::makeTwoTrackResonanceHistSpecMap(confKstar0Binning); - pairK0shortKstar0Builder.init(&hRegistry, confCollisionBinning, k0shortSelection, kstar0Selection, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, v0PosDauSpec, v0NegDauSpec, kstar0HistSpec, resoPosDauSpec, resoNegDauSpec, pairV0TwoTrackResonanceHistSpec, cprHistSpecPos, cprHistSpecNeg); + pairK0shortKstar0Builder.init(&hRegistry, confCollisionBinning, k0shortSelection, kstar0Selection, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, v0PosDauSpec, v0NegDauSpec, kstar0HistSpec, resoPosDauSpec, resoNegDauSpec, pairV0TwoTrackResonanceHistSpec, cprHistSpecPos, cprHistSpecNeg); } // setup for k0short-rho0 if (doprocessK0shortRho0SameEvent || doprocessK0shortRho0MixedEvent) { auto k0shortHistSpec = v0histmanager::makeV0HistSpecMap(confK0shortBinning); auto rho0HistSpec = twotrackresonancehistmanager::makeTwoTrackResonanceHistSpecMap(confRho0Binning); - pairK0shortRho0Builder.init(&hRegistry, confCollisionBinning, k0shortSelection, rho0Selection, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, v0PosDauSpec, v0NegDauSpec, rho0HistSpec, resoPosDauSpec, resoNegDauSpec, pairV0TwoTrackResonanceHistSpec, cprHistSpecPos, cprHistSpecNeg); + pairK0shortRho0Builder.init(&hRegistry, confCollisionBinning, k0shortSelection, rho0Selection, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, v0PosDauSpec, v0NegDauSpec, rho0HistSpec, resoPosDauSpec, resoNegDauSpec, pairV0TwoTrackResonanceHistSpec, cprHistSpecPos, cprHistSpecNeg); } } // lambda-phi void processLambdaPhiSameEvent(FilteredCollision const& col, FemtoTracks const& tracks, FemtoLambdas const& /*lambdas*/, FemtoPhis const& /*phis*/) { - pairLambdaPhiBuilder.processSameEvent(col, tracks, lambdaPartition, phiPartition, cache); + pairLambdaPhiBuilder.processSameEvent(col, tracks, lambdaPartition, phiPartition, cache); } PROCESS_SWITCH(FemtoPairV0TwoTrackResonance, processLambdaPhiSameEvent, "Enable processing same event processing for lambdas and phis", true); void processLambdaPhiMixedEvent(FilteredCollisions const& cols, FemtoTracks const& tracks, FemtoLambdas const& /*lambdas*/, FemtoPhis const& /*phis*/) { - pairLambdaPhiBuilder.processMixedEvent(cols, tracks, lambdaPartition, phiPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairLambdaPhiBuilder.processMixedEvent(cols, tracks, lambdaPartition, phiPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairV0TwoTrackResonance, processLambdaPhiMixedEvent, "Enable processing mixed event processing for lambdas and phis", true); // lambda-kstar0 void processLambdaKstar0SameEvent(FilteredCollision const& col, FemtoTracks const& tracks, FemtoLambdas const& /*lambdas*/, FemtoKstar0s const& /*kstar0s*/) { - pairLambdaKstar0Builder.processSameEvent(col, tracks, lambdaPartition, kstar0Partition, cache); + pairLambdaKstar0Builder.processSameEvent(col, tracks, lambdaPartition, kstar0Partition, cache); } PROCESS_SWITCH(FemtoPairV0TwoTrackResonance, processLambdaKstar0SameEvent, "Enable processing same event processing for lambdas and kstar0s", false); void processLambdaKstar0MixedEvent(FilteredCollisions const& cols, FemtoTracks const& tracks, FemtoLambdas const& /*lambdas*/, FemtoKstar0s const& /*kstar0s*/) { - pairLambdaKstar0Builder.processMixedEvent(cols, tracks, lambdaPartition, kstar0Partition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairLambdaKstar0Builder.processMixedEvent(cols, tracks, lambdaPartition, kstar0Partition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairV0TwoTrackResonance, processLambdaKstar0MixedEvent, "Enable processing mixed event processing for lambdas and kstar0s", false); // lambda-rho0 void processLambdaRho0SameEvent(FilteredCollision const& col, FemtoTracks const& tracks, FemtoLambdas const& /*lambdas*/, FemtoRho0s const& /*rho0s*/) { - pairLambdaRho0Builder.processSameEvent(col, tracks, lambdaPartition, rho0Partition, cache); + pairLambdaRho0Builder.processSameEvent(col, tracks, lambdaPartition, rho0Partition, cache); } PROCESS_SWITCH(FemtoPairV0TwoTrackResonance, processLambdaRho0SameEvent, "Enable processing same event processing for lambdas and rho0s", false); void processLambdaRho0MixedEvent(FilteredCollisions const& cols, FemtoTracks const& tracks, FemtoLambdas const& /*lambdas*/, FemtoRho0s const& /*rho0s*/) { - pairLambdaRho0Builder.processMixedEvent(cols, tracks, lambdaPartition, rho0Partition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairLambdaRho0Builder.processMixedEvent(cols, tracks, lambdaPartition, rho0Partition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairV0TwoTrackResonance, processLambdaRho0MixedEvent, "Enable processing mixed event processing for lambdas and rho0s", false); // k0short-phi void processK0shortPhiSameEvent(FilteredCollision const& col, FemtoTracks const& tracks, FemtoK0shorts const& /*k0shorts*/, FemtoPhis const& /*phis*/) { - pairK0shortPhiBuilder.processSameEvent(col, tracks, k0shortPartition, phiPartition, cache); + pairK0shortPhiBuilder.processSameEvent(col, tracks, k0shortPartition, phiPartition, cache); } PROCESS_SWITCH(FemtoPairV0TwoTrackResonance, processK0shortPhiSameEvent, "Enable processing same event processing for k0shorts and phis", false); void processK0shortPhiMixedEvent(FilteredCollisions const& cols, FemtoTracks const& tracks, FemtoK0shorts const& /*k0shorts*/, FemtoPhis const& /*phis*/) { - pairK0shortPhiBuilder.processMixedEvent(cols, tracks, k0shortPartition, phiPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairK0shortPhiBuilder.processMixedEvent(cols, tracks, k0shortPartition, phiPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairV0TwoTrackResonance, processK0shortPhiMixedEvent, "Enable processing mixed event processing for k0shorts and phis", false); // k0short-kstar0 void processK0shortKstar0SameEvent(FilteredCollision const& col, FemtoTracks const& tracks, FemtoK0shorts const& /*k0shorts*/, FemtoKstar0s const& /*kstar0s*/) { - pairK0shortKstar0Builder.processSameEvent(col, tracks, k0shortPartition, kstar0Partition, cache); + pairK0shortKstar0Builder.processSameEvent(col, tracks, k0shortPartition, kstar0Partition, cache); } PROCESS_SWITCH(FemtoPairV0TwoTrackResonance, processK0shortKstar0SameEvent, "Enable processing same event processing for k0shorts and kstar0s", false); void processK0shortKstar0MixedEvent(FilteredCollisions const& cols, FemtoTracks const& tracks, FemtoK0shorts const& /*k0shorts*/, FemtoKstar0s const& /*kstar0s*/) { - pairK0shortKstar0Builder.processMixedEvent(cols, tracks, k0shortPartition, kstar0Partition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairK0shortKstar0Builder.processMixedEvent(cols, tracks, k0shortPartition, kstar0Partition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairV0TwoTrackResonance, processK0shortKstar0MixedEvent, "Enable processing mixed event processing for k0shorts and kstar0s", false); // k0short-rho0 void processK0shortRho0SameEvent(FilteredCollision const& col, FemtoTracks const& tracks, FemtoK0shorts const& /*k0shorts*/, FemtoRho0s const& /*rho0s*/) { - pairK0shortRho0Builder.processSameEvent(col, tracks, k0shortPartition, rho0Partition, cache); + pairK0shortRho0Builder.processSameEvent(col, tracks, k0shortPartition, rho0Partition, cache); } PROCESS_SWITCH(FemtoPairV0TwoTrackResonance, processK0shortRho0SameEvent, "Enable processing same event processing for k0shorts and rho0s", false); void processK0shortRho0MixedEvent(FilteredCollisions const& cols, FemtoTracks const& tracks, FemtoK0shorts const& /*k0shorts*/, FemtoRho0s const& /*rho0s*/) { - pairK0shortRho0Builder.processMixedEvent(cols, tracks, k0shortPartition, rho0Partition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairK0shortRho0Builder.processMixedEvent(cols, tracks, k0shortPartition, rho0Partition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairV0TwoTrackResonance, processK0shortRho0MixedEvent, "Enable processing mixed event processing for k0shorts and rho0s", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { o2::framework::WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoPairV0V0.cxx b/PWGCF/Femto/Tasks/femtoPairV0V0.cxx index 02cedd702f5..9fc0e01a639 100644 --- a/PWGCF/Femto/Tasks/femtoPairV0V0.cxx +++ b/PWGCF/Femto/Tasks/femtoPairV0V0.cxx @@ -61,7 +61,9 @@ struct FemtoPairV0V0 { using FemtoTracksWithLabel = o2::soa::Join; using FemtoLambdasWithLabel = o2::soa::Join; using FemtoK0shortsWithLabel = o2::soa::Join; - // + + using FemtoMcParticlesWithLabel = o2::soa::Join; + o2::framework::SliceCache cache; // setup collisions @@ -188,14 +190,14 @@ struct FemtoPairV0V0 { if (processLambdaLambda) { lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); pairV0V0HistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confMixing); - pairLambdaLambdaBuilder.init(&hRegistry, confCollisionBinning, confLambdaSelection, confLambdaSelection, confLambdaCleaner, confLambdaCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); + pairLambdaLambdaBuilder.init(&hRegistry, confCollisionBinning, confLambdaSelection, confLambdaSelection, confLambdaCleaner, confLambdaCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); } // setup for k0short if (doprocessK0shortK0shortSameEvent || doprocessK0shortK0shortMixedEvent) { k0shortHistSpec = v0histmanager::makeV0HistSpecMap(confK0shortBinning); pairV0V0HistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confMixing); - pairK0shortK0shortBuilder.init(&hRegistry, confCollisionBinning, confK0shortSelection, confK0shortSelection, confK0shortCleaner, confK0shortCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); + pairK0shortK0shortBuilder.init(&hRegistry, confCollisionBinning, confK0shortSelection, confK0shortSelection, confK0shortCleaner, confK0shortCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); } } else { colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); @@ -204,71 +206,71 @@ struct FemtoPairV0V0 { if (processLambdaLambda) { lambdaHistSpec = v0histmanager::makeV0McHistSpecMap(confLambdaBinning); pairV0V0HistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning, confMixing); - pairLambdaLambdaBuilder.init(&hRegistry, confCollisionBinning, confLambdaSelection, confLambdaSelection, confLambdaCleaner, confLambdaCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); + pairLambdaLambdaBuilder.init(&hRegistry, confCollisionBinning, confLambdaSelection, confLambdaSelection, confLambdaCleaner, confLambdaCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); } // setup for k0short if (doprocessK0shortK0shortSameEvent || doprocessK0shortK0shortMixedEvent) { k0shortHistSpec = v0histmanager::makeV0McHistSpecMap(confK0shortBinning); pairV0V0HistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning, confMixing); - pairK0shortK0shortBuilder.init(&hRegistry, confCollisionBinning, confK0shortSelection, confK0shortSelection, confK0shortCleaner, confK0shortCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); + pairK0shortK0shortBuilder.init(&hRegistry, confCollisionBinning, confK0shortSelection, confK0shortSelection, confK0shortCleaner, confK0shortCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); } } }; void processLambdaLambdaSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoLambdas const& lambdas) { - pairLambdaLambdaBuilder.processSameEvent(col, tracks, lambdas, lambdaPartition, lambdaPartition, cache); + pairLambdaLambdaBuilder.processSameEvent(col, tracks, lambdas, lambdaPartition, lambdaPartition, cache); } PROCESS_SWITCH(FemtoPairV0V0, processLambdaLambdaSameEvent, "Enable processing same event processing for lambda-lambda", true); - void processLambdaLambdaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& lambdas, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processLambdaLambdaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& lambdas, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairLambdaLambdaBuilder.processSameEvent(col, mcCols, tracks, lambdas, lambdaWithLabelPartition, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + pairLambdaLambdaBuilder.processSameEvent(col, mcCols, tracks, lambdas, lambdaWithLabelPartition, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoPairV0V0, processLambdaLambdaSameEventMc, "Enable processing same event processing for lambda-lambda with mc information", false); void processLambdaLambdaMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoLambdas const& lambdas) { - pairLambdaLambdaBuilder.processMixedEvent(cols, tracks, lambdas, lambdaPartition, lambdaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairLambdaLambdaBuilder.processMixedEvent(cols, tracks, lambdas, lambdaPartition, lambdaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairV0V0, processLambdaLambdaMixedEvent, "Enable processing mixed event processing for lambda-lambda", true); - void processLambdaLambdaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambdas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processLambdaLambdaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambdas*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairLambdaLambdaBuilder.processMixedEvent(cols, mcCols, tracks, lambdaWithLabelPartition, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairLambdaLambdaBuilder.processMixedEvent(cols, mcCols, tracks, lambdaWithLabelPartition, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairV0V0, processLambdaLambdaMixedEventMc, "Enable processing mixed event processing for lambda-lambda with mc information", false); void processK0shortK0shortSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoK0shorts const& k0shorts) { - pairK0shortK0shortBuilder.processSameEvent(col, tracks, k0shorts, k0shortPartition, k0shortPartition, cache); + pairK0shortK0shortBuilder.processSameEvent(col, tracks, k0shorts, k0shortPartition, k0shortPartition, cache); } PROCESS_SWITCH(FemtoPairV0V0, processK0shortK0shortSameEvent, "Enable processing same event processing for k0short-k0short", false); - void processK0shortK0shortSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& k0shorts, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processK0shortK0shortSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& k0shorts, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairK0shortK0shortBuilder.processSameEvent(col, mcCols, tracks, k0shorts, k0shortWithLabelPartition, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + pairK0shortK0shortBuilder.processSameEvent(col, mcCols, tracks, k0shorts, k0shortWithLabelPartition, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoPairV0V0, processK0shortK0shortSameEventMc, "Enable processing same event processing for k0short-k0short with mc information", false); void processK0shortK0shortMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoK0shorts const& k0shorts) { - pairK0shortK0shortBuilder.processMixedEvent(cols, tracks, k0shorts, k0shortPartition, k0shortPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairK0shortK0shortBuilder.processMixedEvent(cols, tracks, k0shorts, k0shortPartition, k0shortPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairV0V0, processK0shortK0shortMixedEvent, "Enable processing mixed event processing for k0short-k0short", false); - void processK0shortK0shortMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& /*k0shorts*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processK0shortK0shortMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& /*k0shorts*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairK0shortK0shortBuilder.processMixedEvent(cols, mcCols, tracks, k0shortWithLabelPartition, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairK0shortK0shortBuilder.processMixedEvent(cols, mcCols, tracks, k0shortWithLabelPartition, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairV0V0, processK0shortK0shortMixedEventMc, "Enable processing mixed event processing for k0short-k0short with mc information", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { o2::framework::WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoTrackQa.cxx b/PWGCF/Femto/Tasks/femtoTrackQa.cxx index 27ef50fa3a7..7a460bb3c15 100644 --- a/PWGCF/Femto/Tasks/femtoTrackQa.cxx +++ b/PWGCF/Femto/Tasks/femtoTrackQa.cxx @@ -53,6 +53,8 @@ struct FemtoTrackQa { using FemtoTracksWithLabel = o2::soa::Join; + using FemtoMcParticlesWithLabel = o2::soa::Join; + o2::framework::SliceCache cache; // setup collisions @@ -81,7 +83,7 @@ struct FemtoTrackQa { void init(o2::framework::InitContext&) { - if ((doprocessData + doprocessMc) > 1) { + if ((static_cast(doprocessData) + static_cast(doprocessMc)) > 1) { LOG(fatal) << "More than 1 process function is activated. Breaking..."; } bool processData = doprocessData; @@ -92,14 +94,14 @@ struct FemtoTrackQa { if (processData) { colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); - colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); trackHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confTrackBinning, confTrackQaBinning); - trackHistManager.init(&hRegistry, trackHistSpec, confTrackSelection, confTrackQaBinning); + trackHistManager.init(&hRegistry, trackHistSpec, confTrackSelection, confTrackQaBinning); } else { colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); - colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); trackHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confTrackBinning, confTrackQaBinning); - trackHistManager.init(&hRegistry, trackHistSpec, confTrackSelection, confTrackQaBinning); + trackHistManager.init(&hRegistry, trackHistSpec, confTrackSelection, confTrackQaBinning); } hRegistry.print(); }; @@ -110,35 +112,35 @@ struct FemtoTrackQa { if (trackSlice.size() == 0) { return; } - colHistManager.fill(col); + colHistManager.fill(col); for (auto const& track : trackSlice) { - trackHistManager.fill(track, tracks); + trackHistManager.fill(track, tracks); } }; PROCESS_SWITCH(FemtoTrackQa, processData, "Track QA in Data", true); - void processMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { auto trackSlice = trackWithLabelPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); if (trackSlice.size() == 0) { return; } - colHistManager.fill(col, mcCols); + colHistManager.fill(col, mcCols); for (auto const& track : trackSlice) { if (!trackCleaner.isClean(track, mcParticles, mcMothers, mcPartonicMothers)) { continue; } - trackHistManager.fill(track, tracks, mcParticles, mcMothers, mcPartonicMothers); + trackHistManager.fill(track, tracks, mcParticles, mcMothers, mcPartonicMothers); } } PROCESS_SWITCH(FemtoTrackQa, processMc, "Track QA in Monte Carlo", false); }; o2::framework::WorkflowSpec - defineDataProcessing(o2::framework::ConfigContext const& cfgc) + defineDataProcessing(o2::framework::ConfigContext const& context) { o2::framework::WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoTripletTrackTrackCascade.cxx b/PWGCF/Femto/Tasks/femtoTripletTrackTrackCascade.cxx index ae9f0ca2783..013d9a3eb6c 100644 --- a/PWGCF/Femto/Tasks/femtoTripletTrackTrackCascade.cxx +++ b/PWGCF/Femto/Tasks/femtoTripletTrackTrackCascade.cxx @@ -63,6 +63,8 @@ struct FemtoTripletTrackTrackCascade { using FemtoXisWithLabel = o2::soa::Join; using FemtoOmegasWithLabel = o2::soa::Join; + using FemtoMcParticlesWithLabel = o2::soa::Join; + o2::framework::SliceCache cache; // setup collisions collisionbuilder::ConfCollisionSelection collisionSelection; @@ -179,7 +181,7 @@ struct FemtoTripletTrackTrackCascade { void init(o2::framework::InitContext&) { - if ((doprocessXiSameEvent + doprocessXiSameEventMc) > 1 || (doprocessXiMixedEvent + doprocessXiMixedEventMc) > 1 || (doprocessOmegaSameEvent + doprocessOmegaSameEventMc) > 1 || (doprocessOmegaMixedEvent + doprocessOmegaMixedEventMc) > 1) { + if ((static_cast(doprocessXiSameEvent) + static_cast(doprocessXiSameEventMc)) > 1 || (static_cast(doprocessXiMixedEvent) + static_cast(doprocessXiMixedEventMc)) > 1 || (static_cast(doprocessOmegaSameEvent) + static_cast(doprocessOmegaSameEventMc)) > 1 || (static_cast(doprocessOmegaMixedEvent) + static_cast(doprocessOmegaMixedEventMc)) > 1) { LOG(fatal) << "More than 1 same or mixed event process function is activated. Breaking..."; } bool processData = doprocessXiSameEvent || doprocessXiMixedEvent || doprocessOmegaSameEvent || doprocessOmegaMixedEvent; @@ -223,14 +225,14 @@ struct FemtoTripletTrackTrackCascade { bachelorHistSpec = trackhistmanager::makeTrackHistSpecMap(confBachelorBinning); posDauSpec = trackhistmanager::makeTrackHistSpecMap(confPosDauBinning); negDauSpec = trackhistmanager::makeTrackHistSpecMap(confNegDauBinning); - tripletTrackTrackCascadeHistSpec = triplethistmanager::makeTripletHistSpecMap(confTripletBinning); + tripletTrackTrackCascadeHistSpec = triplethistmanager::makeTripletHistSpecMap(confTripletBinning, confMixing); if (processXi) { xiHistSpec = cascadehistmanager::makeCascadeHistSpecMap(confXiBinning); - tripletTrackTrackXiBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confCtr, confXiSelection, confXiCleaner, confCprBachelor, confCprV0Daughter, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, xiHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, tripletTrackTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, ctrHistSpec); + tripletTrackTrackXiBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confCtr, confXiSelection, confXiCleaner, confCprBachelor, confCprV0Daughter, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, xiHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, tripletTrackTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, ctrHistSpec); } else { omegaHistSpec = cascadehistmanager::makeCascadeHistSpecMap(confOmegaBinning); - tripletTrackTrackOmegaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confCtr, confOmegaSelection, confOmegaCleaner, confCprBachelor, confCprV0Daughter, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, omegaHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, tripletTrackTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, ctrHistSpec); + tripletTrackTrackOmegaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confCtr, confOmegaSelection, confOmegaCleaner, confCprBachelor, confCprV0Daughter, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, omegaHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, tripletTrackTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, ctrHistSpec); } } else { colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); @@ -239,13 +241,13 @@ struct FemtoTripletTrackTrackCascade { bachelorHistSpec = trackhistmanager::makeTrackMcHistSpecMap(confBachelorBinning); posDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confPosDauBinning); negDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confNegDauBinning); - tripletTrackTrackCascadeHistSpec = triplethistmanager::makeTripletMcHistSpecMap(confTripletBinning); + tripletTrackTrackCascadeHistSpec = triplethistmanager::makeTripletMcHistSpecMap(confTripletBinning, confMixing); if (processXi) { xiHistSpec = cascadehistmanager::makeCascadeMcHistSpecMap(confXiBinning); - tripletTrackTrackXiBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confCtr, confXiSelection, confXiCleaner, confCprBachelor, confCprV0Daughter, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, xiHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, tripletTrackTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, ctrHistSpec); + tripletTrackTrackXiBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confCtr, confXiSelection, confXiCleaner, confCprBachelor, confCprV0Daughter, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, xiHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, tripletTrackTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, ctrHistSpec); } else { omegaHistSpec = cascadehistmanager::makeCascadeMcHistSpecMap(confOmegaBinning); - tripletTrackTrackOmegaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confCtr, confOmegaSelection, confOmegaCleaner, confCprBachelor, confCprV0Daughter, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, omegaHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, tripletTrackTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, ctrHistSpec); + tripletTrackTrackOmegaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackCleaner1, confCtr, confOmegaSelection, confOmegaCleaner, confCprBachelor, confCprV0Daughter, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, omegaHistSpec, bachelorHistSpec, posDauSpec, negDauSpec, tripletTrackTrackCascadeHistSpec, cprHistSpecBachelor, cprHistSpecV0Daughter, ctrHistSpec); } } hRegistry.print(); @@ -253,57 +255,57 @@ struct FemtoTripletTrackTrackCascade { void processXiSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoXis const& /*xis*/) { - tripletTrackTrackXiBuilder.processSameEvent(col, tracks, trackPartition1, trackPartition2, xiPartition, cache); + tripletTrackTrackXiBuilder.processSameEvent(col, tracks, trackPartition1, trackPartition2, xiPartition, cache); } PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processXiSameEvent, "Enable processing same event processing for tracks and xis", true); - void processXiSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processXiSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - tripletTrackTrackXiBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, xiWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + tripletTrackTrackXiBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, xiWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processXiSameEventMc, "Enable processing same event processing for tracks and xis with mc information", false); void processXiMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoXis const& /*xis*/) { - tripletTrackTrackXiBuilder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, xiPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + tripletTrackTrackXiBuilder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, xiPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processXiMixedEvent, "Enable processing mixed event processing for tracks and xis", true); - void processXiMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& /*mcMothers*/, o2::aod::FMcPartMoths const& /*mcPartonicMothers*/) + void processXiMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& /*mcMothers*/, o2::aod::FMcPartMoths const& /*mcPartonicMothers*/) { - tripletTrackTrackXiBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, xiWithLabelPartition, mcParticles, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + tripletTrackTrackXiBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, xiWithLabelPartition, mcParticles, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processXiMixedEventMc, "Enable processing mixed event processing for tracks and xis with mc information", false); void processOmegaSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoOmegas const& /*omega*/) { - tripletTrackTrackOmegaBuilder.processSameEvent(col, tracks, trackPartition1, trackPartition2, omegaPartition, cache); + tripletTrackTrackOmegaBuilder.processSameEvent(col, tracks, trackPartition1, trackPartition2, omegaPartition, cache); } PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processOmegaSameEvent, "Enable processing same event processing for tracks and omegas", false); - void processOmegaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoOmegasWithLabel const& /*omegas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processOmegaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoOmegasWithLabel const& /*omegas*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - tripletTrackTrackOmegaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, omegaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + tripletTrackTrackOmegaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, omegaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processOmegaSameEventMc, "Enable processing same event processing for tracks and omegas with mc information", false); void processOmegaMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoOmegas const& /*omegas*/) { - tripletTrackTrackOmegaBuilder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, omegaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + tripletTrackTrackOmegaBuilder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, omegaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processOmegaMixedEvent, "Enable processing mixed event processing for tracks and omegas", false); - void processOmegaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& /*mcMothers*/, o2::aod::FMcPartMoths const& /*mcPartonicMothers*/) + void processOmegaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoXisWithLabel const& /*xis*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& /*mcMothers*/, o2::aod::FMcPartMoths const& /*mcPartonicMothers*/) { - tripletTrackTrackOmegaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, omegaWithLabelPartition, mcParticles, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + tripletTrackTrackOmegaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, omegaWithLabelPartition, mcParticles, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoTripletTrackTrackCascade, processOmegaMixedEventMc, "Enable processing mixed event processing for tracks and omegas with mc information", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { o2::framework::WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoTripletTrackTrackTrack.cxx b/PWGCF/Femto/Tasks/femtoTripletTrackTrackTrack.cxx index 05dcdd5b153..16e780089d7 100644 --- a/PWGCF/Femto/Tasks/femtoTripletTrackTrackTrack.cxx +++ b/PWGCF/Femto/Tasks/femtoTripletTrackTrackTrack.cxx @@ -57,6 +57,8 @@ struct FemtoTripletTrackTrackTrack { using FemtoTracksWithLabel = o2::soa::Join; + using FemtoMcParticlesWithLabel = o2::soa::Join; + o2::framework::SliceCache cache; // setup collisions @@ -115,7 +117,7 @@ struct FemtoTripletTrackTrackTrack { void init(o2::framework::InitContext&) { - if ((doprocessSameEvent + doprocessSameEventMc) > 1 || (doprocessMixedEvent + doprocessMixedEventMc) > 1) { + if ((static_cast(doprocessSameEvent) + static_cast(doprocessSameEventMc)) > 1 || (static_cast(doprocessMixedEvent) + static_cast(doprocessMixedEventMc)) > 1) { LOG(fatal) << "More than 1 same or mixed event process function is activated. Breaking..."; } bool processData = doprocessSameEvent || doprocessMixedEvent; @@ -144,48 +146,48 @@ struct FemtoTripletTrackTrackTrack { trackHistSpec1 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning1); trackHistSpec2 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning2); trackHistSpec3 = trackhistmanager::makeTrackHistSpecMap(confTrackBinning3); - tripletHistSpec = triplethistmanager::makeTripletHistSpecMap(confTripletBinning); - tripletTrackTrackTrackBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackSelections3, confCtr, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, trackHistSpec3, tripletHistSpec, ctrHistSpec); + tripletHistSpec = triplethistmanager::makeTripletHistSpecMap(confTripletBinning, confMixing); + tripletTrackTrackTrackBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackSelections3, confCtr, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, trackHistSpec3, tripletHistSpec, ctrHistSpec); } else { colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); trackHistSpec1 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning1); trackHistSpec2 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning2); trackHistSpec3 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning3); - tripletHistSpec = triplethistmanager::makeTripletMcHistSpecMap(confTripletBinning); - tripletTrackTrackTrackBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackSelections3, confCtr, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, trackHistSpec3, tripletHistSpec, ctrHistSpec); + tripletHistSpec = triplethistmanager::makeTripletMcHistSpecMap(confTripletBinning, confMixing); + tripletTrackTrackTrackBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confTrackSelections3, confCtr, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, trackHistSpec3, tripletHistSpec, ctrHistSpec); } hRegistry.print(); }; void processSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks) { - tripletTrackTrackTrackBuilder.processSameEvent(col, tracks, trackPartition1, trackPartition2, trackPartition3, cache); + tripletTrackTrackTrackBuilder.processSameEvent(col, tracks, trackPartition1, trackPartition2, trackPartition3, cache); } PROCESS_SWITCH(FemtoTripletTrackTrackTrack, processSameEvent, "Enable processing same event processing", true); - void processSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - tripletTrackTrackTrackBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, trackWithLabelPartition3, mcParticles, mcMothers, mcPartonicMothers, cache); + tripletTrackTrackTrackBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, trackWithLabelPartition3, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoTripletTrackTrackTrack, processSameEventMc, "Enable processing same event processing", false); void processMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks) { - tripletTrackTrackTrackBuilder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, trackPartition3, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + tripletTrackTrackTrackBuilder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, trackPartition3, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoTripletTrackTrackTrack, processMixedEvent, "Enable processing mixed event processing", true); - void processMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, o2::aod::FMcParticles const& mcParticles) + void processMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoMcParticlesWithLabel const& mcParticles) { - tripletTrackTrackTrackBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, trackWithLabelPartition3, mcParticles, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + tripletTrackTrackTrackBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, trackWithLabelPartition3, mcParticles, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoTripletTrackTrackTrack, processMixedEventMc, "Enable processing mixed event processing", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { o2::framework::WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoTripletTrackTrackV0.cxx b/PWGCF/Femto/Tasks/femtoTripletTrackTrackV0.cxx index 370cee244a3..a6c74f1c4c1 100644 --- a/PWGCF/Femto/Tasks/femtoTripletTrackTrackV0.cxx +++ b/PWGCF/Femto/Tasks/femtoTripletTrackTrackV0.cxx @@ -64,6 +64,8 @@ struct FemtoTripletTrackTrackV0 { using FemtoLambdasWithLabel = o2::soa::Join; // using FemtoK0shortsWithLabel = o2::soa::Join; + using FemtoMcParticlesWithLabel = o2::soa::Join; + o2::framework::SliceCache cache; // setup collisions @@ -131,11 +133,11 @@ struct FemtoTripletTrackTrackV0 { o2::framework::ColumnBinningPolicy mixBinsVtxMultCent{{defaultVtxBins, defaultMultBins, defaultCentBins}, true}; triplethistmanager::ConfMixing confMixing; - o2::framework::HistogramRegistry hRegistry{"FemtoTrackTrackTrack", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; + o2::framework::HistogramRegistry hRegistry{"FemtoTrackTrackV0", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; void init(o2::framework::InitContext&) { - if ((doprocessSameEvent + doprocessSameEventMc) > 1 || (doprocessMixedEvent + doprocessMixedEventMc) > 1) { + if ((static_cast(doprocessSameEvent) + static_cast(doprocessSameEventMc)) > 1 || (static_cast(doprocessMixedEvent) + static_cast(doprocessMixedEventMc)) > 1) { LOG(fatal) << "More than 1 same or mixed event process function is activated. Breaking..."; } bool processData = doprocessSameEvent || doprocessMixedEvent; @@ -146,7 +148,7 @@ struct FemtoTripletTrackTrackV0 { // setup columnpolicy for binning // default values are used during instantiation, so we need to explicity update them here - mixBinsVtxMult = {{confMixing.vtxBins, confMixing.multBins.value}, true}; + mixBinsVtxMult = {{confMixing.vtxBins.value, confMixing.multBins.value}, true}; mixBinsVtxCent = {{confMixing.vtxBins.value, confMixing.centBins.value}, true}; mixBinsVtxMultCent = {{confMixing.vtxBins.value, confMixing.multBins.value, confMixing.centBins.value}, true}; @@ -168,8 +170,8 @@ struct FemtoTripletTrackTrackV0 { lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); posDauSpec = trackhistmanager::makeTrackHistSpecMap(confPosDauBinning); negDauSpec = trackhistmanager::makeTrackHistSpecMap(confNegDauBinning); - tripletHistSpec = triplethistmanager::makeTripletHistSpecMap(confTripletBinning); - tripletTrackTrackLambdaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confLambdaSelection, confCtr, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, lambdaHistSpec, posDauSpec, negDauSpec, tripletHistSpec, ctrHistSpec); + tripletHistSpec = triplethistmanager::makeTripletHistSpecMap(confTripletBinning, confMixing); + tripletTrackTrackLambdaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confLambdaSelection, confCtr, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, lambdaHistSpec, posDauSpec, negDauSpec, tripletHistSpec, ctrHistSpec); } else { colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); trackHistSpec1 = trackhistmanager::makeTrackMcHistSpecMap(confTrackBinning1); @@ -177,41 +179,41 @@ struct FemtoTripletTrackTrackV0 { lambdaHistSpec = v0histmanager::makeV0McHistSpecMap(confLambdaBinning); posDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confPosDauBinning); negDauSpec = trackhistmanager::makeTrackMcHistSpecMap(confNegDauBinning); - tripletHistSpec = triplethistmanager::makeTripletMcHistSpecMap(confTripletBinning); - tripletTrackTrackLambdaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confLambdaSelection, confCtr, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, lambdaHistSpec, posDauSpec, negDauSpec, tripletHistSpec, ctrHistSpec); + tripletHistSpec = triplethistmanager::makeTripletMcHistSpecMap(confTripletBinning, confMixing); + tripletTrackTrackLambdaBuilder.init(&hRegistry, confCollisionBinning, confTrackSelections1, confTrackSelections2, confLambdaSelection, confCtr, confMixing, confTripletBinning, confTripletCuts, colHistSpec, trackHistSpec1, trackHistSpec2, lambdaHistSpec, posDauSpec, negDauSpec, tripletHistSpec, ctrHistSpec); } hRegistry.print(); }; void processSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoLambdas const& /*lambdas*/) { - tripletTrackTrackLambdaBuilder.processSameEvent(col, tracks, trackPartition1, trackPartition2, lambdaPartition, cache); + tripletTrackTrackLambdaBuilder.processSameEvent(col, tracks, trackPartition1, trackPartition2, lambdaPartition, cache); } PROCESS_SWITCH(FemtoTripletTrackTrackV0, processSameEvent, "Enable processing same event processing", true); - void processSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdas const& /*lambdas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambdas*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - tripletTrackTrackLambdaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + tripletTrackTrackLambdaBuilder.processSameEvent(col, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, lambdaWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoTripletTrackTrackV0, processSameEventMc, "Enable processing same event processing", false); void processMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoLambdas const& /*lambdas*/) { - tripletTrackTrackLambdaBuilder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, lambdaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + tripletTrackTrackLambdaBuilder.processMixedEvent(cols, tracks, trackPartition1, trackPartition2, lambdaPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoTripletTrackTrackV0, processMixedEvent, "Enable processing mixed event processing", true); - void processMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdas const& /*lambdas*/, o2::aod::FMcParticles const& mcParticles) + void processMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambdas*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& /*mcMothers*/, o2::aod::FMcPartMoths const& /*mcPartonicMothers*/) { - tripletTrackTrackLambdaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, lambdaWithLabelPartition, mcParticles, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + tripletTrackTrackLambdaBuilder.processMixedEvent(cols, mcCols, tracks, trackWithLabelPartition1, trackWithLabelPartition2, lambdaWithLabelPartition, mcParticles, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoTripletTrackTrackV0, processMixedEventMc, "Enable processing mixed event processing", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { o2::framework::WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx b/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx index 36e663bc6d7..7e22720b6c6 100644 --- a/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx +++ b/PWGCF/Femto/Tasks/femtoTwotrackresonanceQa.cxx @@ -35,38 +35,35 @@ #include #include -using namespace o2::aod; -using namespace o2::framework; -using namespace o2::framework::expressions; using namespace o2::analysis::femto; struct FemtoTwotrackresonanceQa { // setup tables - using FemtoCollisions = o2::soa::Join; + using FemtoCollisions = o2::soa::Join; using FemtoCollision = FemtoCollisions::iterator; using FilteredFemtoCollisions = o2::soa::Filtered; using FilteredFemtoCollision = FilteredFemtoCollisions::iterator; - using FemtoPhis = o2::soa::Join; - using FemtoRho0s = o2::soa::Join; - using FemtoKstar0s = o2::soa::Join; - using FemtoTracks = o2::soa::Join; + using FemtoPhis = o2::soa::Join; + using FemtoRho0s = o2::soa::Join; + using FemtoKstar0s = o2::soa::Join; + using FemtoTracks = o2::soa::Join; - SliceCache cache; + o2::framework::SliceCache cache; // setup for collisions collisionbuilder::ConfCollisionSelection collisionSelection; - Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); + o2::framework::expressions::Filter collisionFilter = MAKE_COLLISION_FILTER(collisionSelection); colhistmanager::CollisionHistManager colHistManager; colhistmanager::ConfCollisionBinning confCollisionBinning; colhistmanager::ConfCollisionQaBinning confCollisionQaBinning; // setup for phis twotrackresonancebuilder::ConfPhiSelection confPhiSelection; - Partition phiPartition = MAKE_RESONANCE_0_PARTITON(confPhiSelection); - Preslice perColPhis = femtobase::stored::fColId; + o2::framework::Partition phiPartition = MAKE_RESONANCE_0_PARTITON(confPhiSelection); + o2::framework::Preslice perColPhis = o2::aod::femtobase::stored::fColId; twotrackresonancehistmanager::ConfPhiBinning confPhiBinning; twotrackresonancehistmanager::TwoTrackResonanceHistManager< @@ -78,8 +75,8 @@ struct FemtoTwotrackresonanceQa { // setup for rho0s twotrackresonancebuilder::ConfRho0Selection confRho0Selection; - Partition rho0Partition = MAKE_RESONANCE_0_PARTITON(confRho0Selection); - Preslice perColRhos = femtobase::stored::fColId; + o2::framework::Partition rho0Partition = MAKE_RESONANCE_0_PARTITON(confRho0Selection); + o2::framework::Preslice perColRhos = o2::aod::femtobase::stored::fColId; twotrackresonancehistmanager::ConfRho0Binning confRho0Binning; twotrackresonancehistmanager::TwoTrackResonanceHistManager< @@ -91,8 +88,8 @@ struct FemtoTwotrackresonanceQa { // setup for kstar0s twotrackresonancebuilder::ConfKstar0Selection confKstar0Selection; - Partition kstar0Partition = MAKE_RESONANCE_1_PARTITON(confKstar0Selection); - Preslice perColKstars = femtobase::stored::fColId; + o2::framework::Partition kstar0Partition = MAKE_RESONANCE_1_PARTITON(confKstar0Selection); + o2::framework::Preslice perColKstars = o2::aod::femtobase::stored::fColId; twotrackresonancehistmanager::ConfKstar0Binning confKstar0Binning; twotrackresonancehistmanager::TwoTrackResonanceHistManager< @@ -108,80 +105,80 @@ struct FemtoTwotrackresonanceQa { trackhistmanager::ConfResonanceNegDauBinning confNegDaughterBinning; trackhistmanager::ConfResonanceNegDauQaBinning confNegDaughterQaBinning; - HistogramRegistry hRegistry{"ResonanceQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + o2::framework::HistogramRegistry hRegistry{"ResonanceQA", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject}; - void init(InitContext&) + void init(o2::framework::InitContext&) { // create a map for histogram specs auto colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); - colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); auto posDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confPosDaughterBinning, confPosDaughterQaBinning); auto negDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confNegDaughterBinning, confNegDaughterQaBinning); - if ((doprocessPhis + doprocessRho0s + doprocessKstar0s) > 1) { + if ((static_cast(doprocessPhis) + static_cast(doprocessRho0s) + static_cast(doprocessKstar0s)) > 1) { LOG(fatal) << "Only one process can be activated"; } if (doprocessPhis) { auto phiHistSpec = twotrackresonancehistmanager::makeTwoTrackResonanceQaHistSpecMap(confPhiBinning); - phiHistManager.init(&hRegistry, phiHistSpec, confPhiSelection, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); + phiHistManager.init(&hRegistry, phiHistSpec, confPhiSelection, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); } if (doprocessRho0s) { auto rho0HistSpec = twotrackresonancehistmanager::makeTwoTrackResonanceQaHistSpecMap(confRho0Binning); - rho0HistManager.init(&hRegistry, rho0HistSpec, confRho0Selection, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); + rho0HistManager.init(&hRegistry, rho0HistSpec, confRho0Selection, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); } if (doprocessKstar0s) { auto kstar0HistSpec = twotrackresonancehistmanager::makeTwoTrackResonanceQaHistSpecMap(confKstar0Binning); - kstar0HistManager.init(&hRegistry, kstar0HistSpec, confKstar0Selection, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); + kstar0HistManager.init(&hRegistry, kstar0HistSpec, confKstar0Selection, posDaughterHistSpec, confPosDaughterQaBinning, negDaughterHistSpec, confNegDaughterQaBinning); } }; void processPhis(FilteredFemtoCollision const& col, FemtoPhis const& /*phis*/, FemtoTracks const& tracks) { - auto phiSlice = phiPartition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto phiSlice = phiPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); if (phiSlice.size() == 0) { return; } - colHistManager.fill(col); + colHistManager.fill(col); for (auto const& phi : phiSlice) { - phiHistManager.fill(phi, tracks); + phiHistManager.fill(phi, tracks); } }; PROCESS_SWITCH(FemtoTwotrackresonanceQa, processPhis, "Process Phis", true); void processRho0s(FilteredFemtoCollision const& col, FemtoRho0s const& /*rho0s*/, FemtoTracks const& tracks) { - auto rho0Slice = rho0Partition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto rho0Slice = rho0Partition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); if (rho0Slice.size() == 0) { return; } - colHistManager.fill(col); + colHistManager.fill(col); for (auto const& rho0 : rho0Slice) { - rho0HistManager.fill(rho0, tracks); + rho0HistManager.fill(rho0, tracks); } }; PROCESS_SWITCH(FemtoTwotrackresonanceQa, processRho0s, "Process Rho0s", false); void processKstar0s(FilteredFemtoCollision const& col, FemtoKstar0s const& /*kstar0s*/, FemtoTracks const& tracks) { - auto kstar0Slice = kstar0Partition->sliceByCached(femtobase::stored::fColId, col.globalIndex(), cache); + auto kstar0Slice = kstar0Partition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); if (kstar0Slice.size() == 0) { return; } - colHistManager.fill(col); + colHistManager.fill(col); for (auto const& kstar0 : kstar0Slice) { - kstar0HistManager.fill(kstar0, tracks); + kstar0HistManager.fill(kstar0, tracks); } }; PROCESS_SWITCH(FemtoTwotrackresonanceQa, processKstar0s, "Process Kstar0s", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { - WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + o2::framework::WorkflowSpec workflow{ + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto/Tasks/femtoV0Qa.cxx b/PWGCF/Femto/Tasks/femtoV0Qa.cxx index 9d8af3870bd..bcd8aa7a246 100644 --- a/PWGCF/Femto/Tasks/femtoV0Qa.cxx +++ b/PWGCF/Femto/Tasks/femtoV0Qa.cxx @@ -58,6 +58,8 @@ struct FemtoV0Qa { using FemtoK0shortsWithLabel = o2::soa::Join; using FemtoTracksWithLabel = o2::soa::Join; + using FemtoMcParticlesWithLabel = o2::soa::Join; + o2::framework::SliceCache cache; // setup for collisions @@ -120,7 +122,7 @@ struct FemtoV0Qa { void init(o2::framework::InitContext&) { - if ((doprocessLambda + doprocessLambdaMc + doprocessK0short + doprocessK0shortMc) != 1) { + if ((static_cast(doprocessLambda) + static_cast(doprocessLambdaMc) + static_cast(doprocessK0short) + static_cast(doprocessK0shortMc)) != 1) { LOG(fatal) << "Only one process can be activated"; } bool processData = doprocessLambda || doprocessK0short; @@ -136,29 +138,29 @@ struct FemtoV0Qa { if (processData) { colHistSpec = colhistmanager::makeColQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); - colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); posDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confV0PosDaughterBinning, confV0PosDaughterQaBinning); negDaughterHistSpec = trackhistmanager::makeTrackQaHistSpecMap(confV0NegDaughterBinning, confV0NegDaughterQaBinning); if (doprocessLambda) { lambdaHistSpec = v0histmanager::makeV0QaHistSpecMap(confLambdaBinning, confLambdaQaBinning); - lambdaHistManager.init(&hRegistry, lambdaHistSpec, confLambdaSelection, confLambdaQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); + lambdaHistManager.init(&hRegistry, lambdaHistSpec, confLambdaSelection, confLambdaQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); } if (doprocessK0short) { k0shortHistSpec = v0histmanager::makeV0QaHistSpecMap(confK0shortBinning, confK0shortQaBinning); - k0shortHistManager.init(&hRegistry, k0shortHistSpec, confK0shortSelection, confK0shortQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); + k0shortHistManager.init(&hRegistry, k0shortHistSpec, confK0shortSelection, confK0shortQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); } } else { colHistSpec = colhistmanager::makeColMcQaHistSpecMap(confCollisionBinning, confCollisionQaBinning); - colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); + colHistManager.init(&hRegistry, colHistSpec, confCollisionBinning, confCollisionQaBinning); posDaughterHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confV0PosDaughterBinning, confV0PosDaughterQaBinning); negDaughterHistSpec = trackhistmanager::makeTrackMcQaHistSpecMap(confV0NegDaughterBinning, confV0NegDaughterQaBinning); if (doprocessLambdaMc) { lambdaHistSpec = v0histmanager::makeV0McQaHistSpecMap(confLambdaBinning, confLambdaQaBinning); - lambdaHistManager.init(&hRegistry, lambdaHistSpec, confLambdaSelection, confLambdaQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); + lambdaHistManager.init(&hRegistry, lambdaHistSpec, confLambdaSelection, confLambdaQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); } if (doprocessK0shortMc) { k0shortHistSpec = v0histmanager::makeV0McQaHistSpecMap(confK0shortBinning, confK0shortQaBinning); - k0shortHistManager.init(&hRegistry, k0shortHistSpec, confK0shortSelection, confK0shortQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); + k0shortHistManager.init(&hRegistry, k0shortHistSpec, confK0shortSelection, confK0shortQaBinning, posDaughterHistSpec, confV0PosDaughterQaBinning, negDaughterHistSpec, confV0NegDaughterQaBinning); } } hRegistry.print(); @@ -170,25 +172,25 @@ struct FemtoV0Qa { if (k0shortSlice.size() == 0) { return; } - colHistManager.fill(col); + colHistManager.fill(col); for (auto const& k0short : k0shortSlice) { - k0shortHistManager.fill(k0short, tracks); + k0shortHistManager.fill(k0short, tracks); } } PROCESS_SWITCH(FemtoV0Qa, processK0short, "Process k0shorts", false); - void processK0shortMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& /*k0shorts*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processK0shortMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& /*k0shorts*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { auto k0shortSlice = k0shortWithLabelPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); if (k0shortSlice.size() == 0) { return; } - colHistManager.fill(col, mcCols); + colHistManager.fill(col, mcCols); for (auto const& k0short : k0shortSlice) { if (!k0shortCleaner.isClean(k0short, mcParticles, mcMothers, mcPartonicMothers)) { continue; } - k0shortHistManager.fill(k0short, tracks, mcParticles, mcMothers, mcPartonicMothers); + k0shortHistManager.fill(k0short, tracks, mcParticles, mcMothers, mcPartonicMothers); } } PROCESS_SWITCH(FemtoV0Qa, processK0shortMc, "Process k0shorts with MC information", false); @@ -199,34 +201,34 @@ struct FemtoV0Qa { if (lambdaSlice.size() == 0) { return; } - colHistManager.fill(col); + colHistManager.fill(col); for (auto const& lambda : lambdaSlice) { - lambdaHistManager.fill(lambda, tracks); + lambdaHistManager.fill(lambda, tracks); } } PROCESS_SWITCH(FemtoV0Qa, processLambda, "Process lambdas", true); - void processLambdaMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambdas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processLambdaMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambdas*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { auto lambdaSlice = lambdaWithLabelPartition->sliceByCached(o2::aod::femtobase::stored::fColId, col.globalIndex(), cache); if (lambdaSlice.size() == 0) { return; } - colHistManager.fill(col, mcCols); + colHistManager.fill(col, mcCols); for (auto const& lambda : lambdaSlice) { if (!lambdaCleaner.isClean(lambda, mcParticles, mcMothers, mcPartonicMothers)) { continue; } - lambdaHistManager.fill(lambda, tracks, mcParticles, mcMothers, mcPartonicMothers); + lambdaHistManager.fill(lambda, tracks, mcParticles, mcMothers, mcPartonicMothers); } } PROCESS_SWITCH(FemtoV0Qa, processLambdaMc, "Process lambdas with MC informaton", false); }; -o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& context) { o2::framework::WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(context), }; return workflow; } diff --git a/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx b/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx index 5086015e84a..22c2d5d4fe0 100644 --- a/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx +++ b/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx @@ -182,11 +182,13 @@ struct singleTrackSelector { registry.add("hNEvents_MCGen", "hNEvents_MCGen", {HistType::kTH1F, {{1, 0.f, 1.f}}}); registry.add("hGen_EtaPhiPt_Proton", "Gen (anti)protons in true collisions", {HistType::kTH3F, {{100, -1., 1., "#eta"}, {157, 0., o2::constants::math::TwoPI, "#phi"}, {100, -5.f, 5.f, "p_{T} GeV/c"}}}); registry.add("hGen_EtaPhiPt_Deuteron", "Gen (anti)deuteron in true collisions", {HistType::kTH3F, {{100, -1., 1., "#eta"}, {157, 0., o2::constants::math::TwoPI, "#phi"}, {100, -5.f, 5.f, "p_{T} GeV/c"}}}); + registry.add("hGen_EtaYPt_Deuteron", "Gen (anti)deuteron in true collisions", {HistType::kTH3F, {{100, -1., 1., "#eta"}, {100, -1., 1., "y"}, {100, -5.f, 5.f, "p_{T} GeV/c"}}}); registry.add("hGen_EtaPhiPt_Helium3", "Gen (anti)Helium3 in true collisions", {HistType::kTH3F, {{100, -1., 1., "#eta"}, {157, 0., o2::constants::math::TwoPI, "#phi"}, {100, -5.f, 5.f, "p_{T} GeV/c"}}}); registry.add("hGen_EtaPhiPt_Triton", "Gen (anti)triton in true collisions", {HistType::kTH3F, {{100, -1., 1., "#eta"}, {157, 0., o2::constants::math::TwoPI, "#phi"}, {100, -5.f, 5.f, "p_{T} GeV/c"}}}); registry.add("hGen_EtaYPt_Triton", "Gen (anti)triton in true collisions", {HistType::kTH3F, {{100, -1., 1., "#eta"}, {100, -1., 1., "y"}, {100, -5.f, 5.f, "p_{T} GeV/c"}}}); registry.add("hReco_EtaPhiPt_Proton", "Gen (anti)protons in reco collisions", {HistType::kTH3F, {{100, -1., 1., "#eta"}, {157, 0., o2::constants::math::TwoPI, "#phi"}, {100, -5.f, 5.f, "p_{T} GeV/c"}}}); registry.add("hReco_EtaPhiPt_Deuteron", "Gen (anti)deuteron in reco collisions", {HistType::kTH3F, {{100, -1., 1., "#eta"}, {157, 0., o2::constants::math::TwoPI, "#phi"}, {100, -5.f, 5.f, "p_{T} GeV/c"}}}); + registry.add("hReco_EtaYPt_Deuteron", "Gen (anti)deuteron in reco collisions", {HistType::kTH3F, {{100, -1., 1., "#eta"}, {100, -1., 1., "y"}, {100, -5.f, 5.f, "p_{T} GeV/c"}}}); registry.add("hReco_EtaPhiPt_Helium3", "Gen (anti)Helium3 in reco collisions", {HistType::kTH3F, {{100, -1., 1., "#eta"}, {157, 0., o2::constants::math::TwoPI, "#phi"}, {100, -5.f, 5.f, "p_{T} GeV/c"}}}); registry.add("hReco_EtaPhiPt_Triton", "Gen (anti)triton in reco collisions", {HistType::kTH3F, {{100, -1., 1., "#eta"}, {157, 0., o2::constants::math::TwoPI, "#phi"}, {100, -5.f, 5.f, "p_{T} GeV/c"}}}); registry.add("hReco_EtaYPt_Triton", "Gen (anti)triton in reco collisions", {HistType::kTH3F, {{100, -1., 1., "#eta"}, {100, -1., 1., "y"}, {100, -5.f, 5.f, "p_{T} GeV/c"}}}); @@ -571,8 +573,10 @@ struct singleTrackSelector { if (mcParticle.pdgCode() == 1000010020) { registry.fill(HIST("hReco_EtaPhiPt_Deuteron"), mcParticle.eta(), mcParticle.phi(), mcParticle.pt()); + registry.fill(HIST("hReco_EtaYPt_Deuteron"), mcParticle.eta(), mcParticle.y(), mcParticle.pt()); } else if (mcParticle.pdgCode() == -1000010020) { registry.fill(HIST("hReco_EtaPhiPt_Deuteron"), mcParticle.eta(), mcParticle.phi(), mcParticle.pt() * -1); + registry.fill(HIST("hReco_EtaYPt_Deuteron"), mcParticle.eta(), mcParticle.y(), mcParticle.pt() * -1); } if (mcParticle.pdgCode() == 2212) { @@ -620,8 +624,10 @@ struct singleTrackSelector { } if (mcParticle.pdgCode() == 1000010020) { registry.fill(HIST("hGen_EtaPhiPt_Deuteron"), mcParticle.eta(), mcParticle.phi(), mcParticle.pt()); + registry.fill(HIST("hGen_EtaYPt_Deuteron"), mcParticle.eta(), mcParticle.y(), mcParticle.pt()); } else if (mcParticle.pdgCode() == -1000010020) { registry.fill(HIST("hGen_EtaPhiPt_Deuteron"), mcParticle.eta(), mcParticle.phi(), mcParticle.pt() * -1); + registry.fill(HIST("hGen_EtaYPt_Deuteron"), mcParticle.eta(), mcParticle.y(), mcParticle.pt() * -1); } if (mcParticle.pdgCode() == 2212) { diff --git a/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h index 8371f683515..ae3e12e9f69 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h +++ b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h @@ -209,10 +209,11 @@ class FemtoDreamParticleHisto { /// Particle-type specific histograms std::string folderSuffix = static_cast(o2::aod::femtodreamMCparticle::MCTypeName[o2::aod::femtodreamMCparticle::MCType::kTruth]).c_str(); + const auto nMcOriginTypes = static_cast(o2::aod::femtodreamMCparticle::ParticleOriginMCTruth::kNOriginMCTruthTypes); mHistogramRegistry->add((folderName + folderSuffix + "/hPt_ReconNoFake").c_str(), "; #it{p}_{T} (GeV/#it{c}); Entries", o2::framework::HistType::kTH1F, {{240, 0, 6}}); mHistogramRegistry->add((folderName + folderSuffix + "/hPDG").c_str(), "; PDG; Entries", o2::framework::HistType::kTH1I, {{6001, -3000.5, 3000.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hOrigin_MC").c_str(), "; Origin; Entries", o2::framework::HistType::kTH1I, {{7, -0.5, 6.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hOrigin_MC").c_str(), "; Origin; Entries", o2::framework::HistType::kTH1I, {{nMcOriginTypes, -0.5, static_cast(nMcOriginTypes) - 0.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hNoMCtruthCounter").c_str(), "; Counter; Entries", o2::framework::HistType::kTH1I, {{1, -0.5, 0.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hPt_DiffTruthReco").c_str(), "; p^{truth}_{T}; (p^{reco}_{T} - p^{truth}_{T}) / p^{truth}_{T}", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, {200, -1, 1}}); mHistogramRegistry->add((folderName + folderSuffix + "/hEta_DiffTruthReco").c_str(), "; #eta^{truth}; #eta^{reco} - #eta^{truth}", o2::framework::HistType::kTH2F, {{200, -1, 1}, {200, -1, 1}}); @@ -229,6 +230,7 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_Else").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{6001, -3000.5, 3000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterLambda").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterSigmaplus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/Debug/hPDGmother_SecondaryDaughterOmegaMinus").c_str(), "; PDG mother; Entries", o2::framework::HistType::kTH1I, {{12001, -6000.5, 6000.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Secondary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); @@ -237,6 +239,7 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterOmegaMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTHnSparseF, {tempFitVarpTAxis, tempFitVarAxis, dcazAxis, multAxis}); } else { mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Primary").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); @@ -246,6 +249,7 @@ class FemtoDreamParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Fake").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterLambda").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterSigmaplus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); + mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_SecondaryDaughterOmegaMinus").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAxy_Else").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", o2::framework::HistType::kTH2F, {tempFitVarpTAxis, tempFitVarAxis}); } @@ -616,6 +620,11 @@ class FemtoDreamParticleHisto mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigmaplus"), part.pt(), part.tempFitVar(), part.dcaZ(), mult); break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterOmegaMinus): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_SecondaryDaughterOmegaMinus"), part.fdExtMCParticle().motherPDG()); + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterOmegaMinus"), + part.pt(), part.tempFitVar(), part.dcaZ(), mult); + break; case (o2::aod::femtodreamMCparticle::kElse): mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/Debug/hPDGmother_Else"), part.fdExtMCParticle().motherPDG()); mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_Else"), @@ -654,6 +663,10 @@ class FemtoDreamParticleHisto mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterSigmaplus"), part.pt(), part.tempFitVar()); break; + case (o2::aod::femtodreamMCparticle::kSecondaryDaughterOmegaMinus): + mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_SecondaryDaughterOmegaMinus"), + part.pt(), part.tempFitVar()); + break; case (o2::aod::femtodreamMCparticle::kElse): mHistogramRegistry->fill(HIST(o2::aod::femtodreamparticle::ParticleTypeName[mParticleType]) + HIST(mFolderSuffix[mFolderSuffixType]) + HIST("_MC/hDCAxy_Else"), part.pt(), part.tempFitVar()); diff --git a/PWGCF/FemtoDream/Core/femtoDreamUtils.h b/PWGCF/FemtoDream/Core/femtoDreamUtils.h index efc075671c1..fde124f5db4 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamUtils.h +++ b/PWGCF/FemtoDream/Core/femtoDreamUtils.h @@ -74,6 +74,9 @@ inline float getMass(int pdgCode) case o2::constants::physics::Pdg::kLambdaCPlus: mass = o2::constants::physics::MassLambdaCPlus; break; + case o2::constants::physics::Pdg::kXiCPlus: + mass = o2::constants::physics::MassXiCPlus; + break; case o2::constants::physics::Pdg::kDeuteron: mass = o2::constants::physics::MassDeuteron; break; @@ -99,11 +102,29 @@ inline float getMass(int pdgCode) return mass; } -inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, int motherPDG) +inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, int motherPDG, int daughterPDG = 0) { int partOrigin = 0; + const auto absMotherPDG = std::abs(motherPDG); + const auto absDaughterPDG = std::abs(daughterPDG); + const bool isTrackLike = partType == o2::aod::femtodreamparticle::ParticleType::kTrack || + partType == o2::aod::femtodreamparticle::ParticleType::kV0Child || + partType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child || + partType == o2::aod::femtodreamparticle::ParticleType::kCascadeBachelor; + + if (absDaughterPDG == kKPlus && isTrackLike) { + switch (absMotherPDG) { + case kOmegaMinus: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterOmegaMinus; + break; + default: + partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondary; + } + return partOrigin; + } + if (partType == o2::aod::femtodreamparticle::ParticleType::kTrack) { - switch (std::abs(motherPDG)) { + switch (absMotherPDG) { case kLambda0: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterLambda; break; @@ -115,7 +136,7 @@ inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, } // switch } else if (partType == o2::aod::femtodreamparticle::ParticleType::kV0) { - switch (std::abs(motherPDG)) { + switch (absMotherPDG) { case kSigma0: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterSigma0; break; @@ -130,7 +151,7 @@ inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, } } else if (partType == o2::aod::femtodreamparticle::ParticleType::kV0Child || partType == o2::aod::femtodreamparticle::ParticleType::kCascadeV0Child || partType == o2::aod::femtodreamparticle::ParticleType::kCascadeBachelor) { - switch (abs(motherPDG)) { + switch (absMotherPDG) { case kLambda0: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterLambda; break; @@ -142,7 +163,7 @@ inline int checkDaughterType(o2::aod::femtodreamparticle::ParticleType partType, } // switch } else if (partType == o2::aod::femtodreamparticle::ParticleType::kCascade) { - switch (std::abs(motherPDG)) { + switch (absMotherPDG) { case kOmegaMinus: partOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kSecondaryDaughterOmegaMinus; break; diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx index 8d2a80b00c4..a35faf8c8a7 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx @@ -214,7 +214,7 @@ struct femtoDreamProducerReducedTask { } else if (particleMC.isPhysicalPrimary()) { particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kPrimary; } else if (motherparticleMC.isPhysicalPrimary() && particleMC.getProcess() == 4) { - particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode(), pdgCode); } else if (particleMC.getGenStatusCode() == -1) { particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kMaterial; } else { diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx index 9f47d915620..bb88a135cb2 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx @@ -672,7 +672,7 @@ struct femtoDreamProducerTask { auto motherparticleMC = motherparticlesMC.front(); pdgCodeMother = motherparticleMC.pdgCode(); TrackRegistry.fill(HIST("AnalysisQA/Mother"), pdgCodeMother); - particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode(), pdgCode); // check if particle is material // particle is from inelastic hadronic interaction -> getProcess() == 23 // particle is generated during transport -> getGenStatusCode() == -1 diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx index 9b0f753ef9c..03779b09ed9 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTaskReso.cxx @@ -928,7 +928,7 @@ struct FemtoDreamProducerTaskReso { auto motherparticleMC = motherparticlesMC.front(); pdgCodeMother = motherparticleMC.pdgCode(); trackRegistry.fill(HIST("AnalysisQA/Mother"), pdgCodeMother); - particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMC.pdgCode(), pdgCode); // check if particle is material // particle is from inelastic hadronic interaction -> getProcess() == 23 // particle is generated during transport -> getGenStatusCode() == -1 diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h index f50f105b5b8..abcfc8efada 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h @@ -20,7 +20,6 @@ #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSpherHarMath.h" -#include #include #include diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index a112f5f4768..45567334289 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -590,10 +590,10 @@ struct FemtoUniverseProducerTask { void init(InitContext&) { - if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackCascadeData || doprocessTrackV0Cascade || doprocessTrackD0mesonData || doprocessTrackD0DataML || doprocessTrackCentRun2Data || doprocessTrackV0CentRun2Data || doprocessTrackCentRun3Data || doprocessV0CentRun3Data || doprocessCascadeCentRun3Data || doprocessTrackDataCentPP) == false && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth || doprocessTrackMCGen || doprocessTruthAndFullMCV0 || doprocessTrackD0MC || doprocessTruthAndFullMCCasc || doprocessFullMCCent || doprocessTrackCentRun3DataMC || doprocessTruthAndFullMCCentRun3 || doprocessTruthAndFullMCCentRun3V0) == false) { + if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackCascadeData || doprocessTrackV0Cascade || doprocessTrackD0mesonData || doprocessTrackD0DataML || doprocessTrackCentRun2Data || doprocessTrackV0CentRun2Data || doprocessTrackCentRun3Data || doprocessV0CentRun3Data || doprocessCascadeCentRun3Data || doprocessTrackDataCentPP) == false && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth || doprocessTrackMCGen || doprocessTruthAndFullMCV0 || doprocessTrackD0MC || doprocessTruthAndFullMCCasc || doprocessFullMCCent || doprocessTrackCentRun3DataMC || doprocessTruthAndFullMCCentRun3 || doprocessTruthAndFullMCCentRun3V0 || doprocessTruthAndFullMCCentRun3Casc) == false) { LOGF(fatal, "Neither processFullData nor processFullMC enabled. Please choose one."); } - if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackCascadeData || doprocessTrackV0Cascade || doprocessTrackD0mesonData || doprocessTrackD0DataML || doprocessTrackCentRun2Data || doprocessTrackV0CentRun2Data || doprocessTrackCentRun3Data || doprocessV0CentRun3Data || doprocessCascadeCentRun3Data || doprocessTrackDataCentPP) == true && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth || doprocessTrackMCGen || doprocessTruthAndFullMCV0 || doprocessTrackD0MC || doprocessTruthAndFullMCCasc || doprocessFullMCCent || doprocessTrackCentRun3DataMC || doprocessTruthAndFullMCCentRun3 || doprocessTruthAndFullMCCentRun3V0) == true) { + if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackCascadeData || doprocessTrackV0Cascade || doprocessTrackD0mesonData || doprocessTrackD0DataML || doprocessTrackCentRun2Data || doprocessTrackV0CentRun2Data || doprocessTrackCentRun3Data || doprocessV0CentRun3Data || doprocessCascadeCentRun3Data || doprocessTrackDataCentPP) == true && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth || doprocessTrackMCGen || doprocessTruthAndFullMCV0 || doprocessTrackD0MC || doprocessTruthAndFullMCCasc || doprocessFullMCCent || doprocessTrackCentRun3DataMC || doprocessTruthAndFullMCCentRun3 || doprocessTruthAndFullMCCentRun3V0 || doprocessTruthAndFullMCCentRun3Casc) == true) { LOGF(fatal, "Cannot enable process Data and process MC at the same time. " "Please choose one."); @@ -2805,12 +2805,17 @@ struct FemtoUniverseProducerTask { // recos std::set recoMcIds; + std::set mcColIds; + recoMcIds.clear(); + mcColIds.clear(); + for (const auto& col : collisions) { auto groupedTracks = tracks.sliceBy(perCollisionTracks, col.globalIndex()); auto groupedCascParts = fullCascades.sliceBy(perCollisionCascs, col.globalIndex()); getMagneticFieldTesla(col.bc_as()); const auto colcheck = fillCollisionsCentRun3(col); if (colcheck) { + mcColIds.insert(col.mcCollisionId()); fillTracks(groupedTracks); fillCascade(col, groupedCascParts, groupedTracks); } @@ -2822,11 +2827,14 @@ struct FemtoUniverseProducerTask { // truth for (const auto& mccol : mccols) { - auto groupedCollisions = collisions.sliceBy(recoCollsPerMCCollCentPbPb, mccol.globalIndex()); + if (confCollMCTruthOnlyReco && !mcColIds.contains(mccol.globalIndex())) { + continue; + } + auto groupedCollisions = collisions.sliceBy(recoCollsPerMCCollCentPbPb, mccol.globalIndex()); // slicing for MC collisions + auto groupedMCParticles = mcParticles.sliceBy(perMCCollision, mccol.globalIndex()); // slicing for MC particles for (const auto& col : groupedCollisions) { const auto colcheck = fillMCTruthCollisionsCentRun3(col); // fills the reco collisions for mc collision if (colcheck) { - auto groupedMCParticles = mcParticles.sliceBy(perMCCollision, mccol.globalIndex()); outputCollExtra(1.0, 1.0); fillParticles(groupedMCParticles, recoMcIds); // fills mc particles } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx index a53ce06567f..f8c99fb90d7 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx @@ -68,6 +68,7 @@ struct FemtoUniverseEfficiencyBase { /// Particle selection part /// Configurables for both particles + ConfigurableAxis confHistCutsVsPtBins{"confHistCutsVsPtBins", {500, 0., 5.}, "Binning of the pT in the Cuts Vs pT plot"}; ConfigurableAxis confTempFitVarpTBins{"confTempFitVarpTBins", {20, 0.5, 4.05}, "Binning of the pT in the pT vs. TempFitVar plot"}; ConfigurableAxis confTempFitVarPDGBins{"confTempFitVarPDGBins", {6000, -2300, 2300}, "Binning of the PDG code in the pT vs. TempFitVar plot"}; ConfigurableAxis confTempFitVarCPABins{"confTempFitVarCPABins", {1000, 0.9, 1}, "Binning of the pointing angle cosinus in the pT vs. TempFitVar plot"}; @@ -79,12 +80,16 @@ struct FemtoUniverseEfficiencyBase { Configurable confMomPion{"confMomPion", 0.75, "Momentum threshold for pion identification using TOF"}; Configurable confNsigmaCombinedProton{"confNsigmaCombinedProton", 3.0, "TPC and TOF Proton Sigma (combined) for momentum > confMomProton"}; Configurable confNsigmaTPCProton{"confNsigmaTPCProton", 3.0, "TPC Proton Sigma for momentum < confMomProton"}; - Configurable confNsigmaPrRejectPiNsigma{"confNsigmaPrRejectPiNsigma", 2.0, "Reject if a proton could be a pion within a givien nSigma value"}; - Configurable confNsigmaPrRejectKaNsigma{"confNsigmaPrRejectKaNsigma", 2.0, "Reject if a proton could be a kaon within a givien nSigma value"}; + Configurable confNsigmaTPCPrRejectPiNsigma{"confNsigmaTPCPrRejectPiNsigma", 3.0, "Reject if a proton could be a pion within a givien TPC nSigma value"}; + Configurable confNsigmaTPCPrRejectKaNsigma{"confNsigmaTPCPrRejectKaNsigma", 2.0, "Reject if a proton could be a kaon within a givien TPC nSigma value"}; + Configurable confNsigmaCombPrRejectPiNsigma{"confNsigmaCombPrRejectPiNsigma", 4.2, "Reject if a proton could be a pion within a givien nSigma comb. value"}; + Configurable confNsigmaCombPrRejectKaNsigma{"confNsigmaCombPrRejectKaNsigma", 2.8, "Reject if a proton could be a kaon within a givien nSigma comb. value"}; Configurable confNsigmaCombinedPion{"confNsigmaCombinedPion", 3.0, "TPC and TOF Pion Sigma (combined) for momentum > confMomPion"}; Configurable confNsigmaTPCPion{"confNsigmaTPCPion", 3.0, "TPC Pion Sigma for momentum < confMomPion"}; - Configurable confNsigmaPiRejectKaNsigma{"confNsigmaPiRejectKaNsigma", 2.0, "Reject if a pion could be a kaon within a givien nSigma value"}; - Configurable confNsigmaPiRejectPrNsigma{"confNsigmaPiRejectPrNsigma", 2.0, "Reject if a pion could be a proton within a givien nSigma value"}; + Configurable confNsigmaTPCPiRejectKaNsigma{"confNsigmaTPCPiRejectKaNsigma", 2.0, "Reject if a pion could be a kaon within a givien TPC nSigma value"}; + Configurable confNsigmaTPCPiRejectPrNsigma{"confNsigmaTPCPiRejectPrNsigma", 2.0, "Reject if a pion could be a proton within a givien TPC nSigma value"}; + Configurable confNsigmaCombPiRejectKaNsigma{"confNsigmaCombPiRejectKaNsigma", 2.8, "Reject if a pion could be a kaon within a givien comb. nSigma value"}; + Configurable confNsigmaCombPiRejectPrNsigma{"confNsigmaCombPiRejectPrNsigma", 2.8, "Reject if a pion could be a proton within a givien comb. nSigma value"}; Configurable confPDGCheckMCReco{"confPDGCheckMCReco", true, "Check PDG code of MC reco paricles"}; } ConfBothTracks; @@ -130,8 +135,10 @@ struct FemtoUniverseEfficiencyBase { Configurable confMomKaonLF{"confMomKaonLF", 0.5, "Momentum threshold for kaon identification using TOF (LF selection)"}; Configurable confNSigmaTPCKaonLF{"confNSigmaTPCKaonLF", 3.0, "TPC Kaon Sigma as in LF"}; Configurable confNSigmaCombKaonLF{"confNSigmaCombKaonLF", 3.0, "TPC and TOF Kaon Sigma (combined) as in LF"}; - Configurable confNsigmaKaRejectPiNsigma{"confNsigmaKaRejectPiNsigma", 3.0, "Reject if a kaon could be a pion within a given nSigma value"}; - Configurable confNsigmaKaRejectPrNsigma{"confNsigmaKaRejectPrNsigma", 3.0, "Reject if a kaon could be a proton within a given nSigma value"}; + Configurable confNsigmaTPCKaRejectPiNsigma{"confNsigmaTPCKaRejectPiNsigma", 1.0, "Reject if a kaon could be a pion within a given TPC nSigma value"}; + Configurable confNsigmaTPCKaRejectPrNsigma{"confNsigmaTPCKaRejectPrNsigma", 2.0, "Reject if a kaon could be a proton within a given TPC nSigma value"}; + Configurable confNsigmaCombKaRejectPiNsigma{"confNsigmaCombKaRejectPiNsigma", 1.4, "Reject if a kaon could be a pion within a given comb. nSigma value"}; + Configurable confNsigmaCombKaRejectPrNsigma{"confNsigmaCombKaRejectPrNsigma", 2.8, "Reject if a kaon could be a proton within a given comb. nSigma value"}; } ConfKaonSelection; /// Deuteron configurables @@ -201,10 +208,11 @@ struct FemtoUniverseEfficiencyBase { { eventHisto.init(&qaRegistry); - registryCuts.add("part1/cutsVspT", ";#it{p}_{T} (GeV/c) ;Cut no.", {HistType::kTH2F, {{500, 0, 5}, {7, 0, 7}}}); + registryCuts.add("part1/cutsVspT", ";#it{p}_{T} (GeV/c) ;Cut no.", {HistType::kTH2F, {{confHistCutsVsPtBins}, {7, 0, 7}}}); trackHistoPartOneGen.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarPDGBins, confIsMCGen, confPDGCodePartOne, false); trackHistoPartOneRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarDCABins, confIsMCReco, confPDGCodePartOne, confIsDebug); registryMCOrigin.add("part1/hRecoPt", " ;#it{p}_{T} (GeV/c); Entries", {HistType::kTH1F, {{confTempFitVarpTBins}}}); + registryMCOrigin.add("part1/hRecoPtBeforePDGCheck", " ;#it{p}_{T} (GeV/c); Entries", {HistType::kTH1F, {{confTempFitVarpTBins}}}); registryMCOrigin.add("part1/hTruthPt", " ;#it{p}_{T} (GeV/c); Entries", {HistType::kTH1F, {{confTempFitVarpTBins}}}); registryTOFMatch.add("part1/hTofMatchPtBeforePIDAllPart", " ;#it{p}_{T} (GeV/c); Entries", {HistType::kTH1F, {{confTempFitVarpTBins}}}); registryTOFMatch.add("part1/hTofMatchPtBeforePIDPartWithTof", " ;#it{p}_{T} (GeV/c); Entries", {HistType::kTH1F, {{confTempFitVarpTBins}}}); @@ -232,10 +240,11 @@ struct FemtoUniverseEfficiencyBase { } if (!confIsSame) { - registryCuts.add("part2/cutsVspT", ";#it{p}_{T} (GeV/c) ;Cut no.", {HistType::kTH2F, {{500, 0, 5}, {7, 0, 7}}}); + registryCuts.add("part2/cutsVspT", ";#it{p}_{T} (GeV/c) ;Cut no.", {HistType::kTH2F, {{confHistCutsVsPtBins}, {7, 0, 7}}}); trackHistoPartTwoGen.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarPDGBins, confIsMCGen, confPDGCodePartTwo, false); trackHistoPartTwoRec.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarDCABins, confIsMCReco, confPDGCodePartTwo, confIsDebug); registryMCOrigin.add("part2/hRecoPt", " ;#it{p}_{T} (GeV/c); Entries", {HistType::kTH1F, {{confTempFitVarpTBins}}}); + registryMCOrigin.add("part2/hRecoPtBeforePDGCheck", " ;#it{p}_{T} (GeV/c); Entries", {HistType::kTH1F, {{confTempFitVarpTBins}}}); registryMCOrigin.add("part2/hTruthPt", " ;#it{p}_{T} (GeV/c); Entries", {HistType::kTH1F, {{confTempFitVarpTBins}}}); registryTOFMatch.add("part2/hTofMatchPtBeforePIDAllPart", " ;#it{p}_{T} (GeV/c); Entries", {HistType::kTH1F, {{confTempFitVarpTBins}}}); registryTOFMatch.add("part2/hTofMatchPtBeforePIDPartWithTof", " ;#it{p}_{T} (GeV/c); Entries", {HistType::kTH1F, {{confTempFitVarpTBins}}}); @@ -296,18 +305,18 @@ struct FemtoUniverseEfficiencyBase { } if (mom <= ConfBothTracks.confMomProton || !partHasTof) { - if (std::abs(nsigmaTPCPi) < ConfBothTracks.confNsigmaPrRejectPiNsigma) { + if (std::abs(nsigmaTPCPi) < ConfBothTracks.confNsigmaTPCPrRejectPiNsigma) { return true; - } else if (std::abs(nsigmaTPCKa) < ConfBothTracks.confNsigmaPrRejectKaNsigma) { + } else if (std::abs(nsigmaTPCKa) < ConfBothTracks.confNsigmaTPCPrRejectKaNsigma) { return true; } else { return false; } } if (mom > ConfBothTracks.confMomProton && partHasTof) { - if (std::sqrt(std::pow(nsigmaTPCPi, 2) + std::pow(nsigmaTOFPi, 2)) < ConfBothTracks.confNsigmaPrRejectPiNsigma) { + if (std::sqrt(std::pow(nsigmaTPCPi, 2) + std::pow(nsigmaTOFPi, 2)) < ConfBothTracks.confNsigmaCombPrRejectPiNsigma) { return true; - } else if (std::sqrt(std::pow(nsigmaTPCKa, 2) + std::pow(nsigmaTOFKa, 2)) < ConfBothTracks.confNsigmaPrRejectKaNsigma) { + } else if (std::sqrt(std::pow(nsigmaTPCKa, 2) + std::pow(nsigmaTOFKa, 2)) < ConfBothTracks.confNsigmaCombPrRejectKaNsigma) { return true; } else { return false; @@ -402,16 +411,16 @@ struct FemtoUniverseEfficiencyBase { } if (mom <= ConfKaonSelection.confMomKaonLF || !partHasTof) { - if (std::abs(nsigmaTPCPi) < ConfKaonSelection.confNsigmaKaRejectPiNsigma) { + if (std::abs(nsigmaTPCPi) < ConfKaonSelection.confNsigmaTPCKaRejectPiNsigma) { return true; - } else if (std::abs(nsigmaTPCPr) < ConfKaonSelection.confNsigmaKaRejectPrNsigma) { + } else if (std::abs(nsigmaTPCPr) < ConfKaonSelection.confNsigmaTPCKaRejectPrNsigma) { return true; } } if (mom > ConfKaonSelection.confMomKaonLF && partHasTof) { - if (std::sqrt(std::pow(nsigmaTPCPi, 2) + std::pow(nsigmaTOFPi, 2)) < ConfKaonSelection.confNsigmaKaRejectPiNsigma) { + if (std::sqrt(std::pow(nsigmaTPCPi, 2) + std::pow(nsigmaTOFPi, 2)) < ConfKaonSelection.confNsigmaCombKaRejectPiNsigma) { return true; - } else if (std::sqrt(std::pow(nsigmaTPCPr, 2) + std::pow(nsigmaTOFPr, 2)) < ConfKaonSelection.confNsigmaKaRejectPrNsigma) { + } else if (std::sqrt(std::pow(nsigmaTPCPr, 2) + std::pow(nsigmaTOFPr, 2)) < ConfKaonSelection.confNsigmaCombKaRejectPrNsigma) { return true; } else { return false; @@ -453,16 +462,16 @@ struct FemtoUniverseEfficiencyBase { } if (mom <= ConfBothTracks.confMomPion || !partHasTof) { - if (std::abs(nsigmaTPCKa) < ConfBothTracks.confNsigmaPiRejectKaNsigma) { + if (std::abs(nsigmaTPCKa) < ConfBothTracks.confNsigmaTPCPiRejectKaNsigma) { return true; - } else if (std::abs(nsigmaTPCPr) < ConfBothTracks.confNsigmaPiRejectPrNsigma) { + } else if (std::abs(nsigmaTPCPr) < ConfBothTracks.confNsigmaTPCPiRejectPrNsigma) { return true; } } if (mom > ConfBothTracks.confMomPion && partHasTof) { - if (std::sqrt(std::pow(nsigmaTPCKa, 2) + std::pow(nsigmaTOFKa, 2)) < ConfBothTracks.confNsigmaPiRejectKaNsigma) { + if (std::sqrt(std::pow(nsigmaTPCKa, 2) + std::pow(nsigmaTOFKa, 2)) < ConfBothTracks.confNsigmaCombPiRejectKaNsigma) { return true; - } else if (std::sqrt(std::pow(nsigmaTPCPr, 2) + std::pow(nsigmaTOFPr, 2)) < ConfBothTracks.confNsigmaPiRejectPrNsigma) { + } else if (std::sqrt(std::pow(nsigmaTPCPr, 2) + std::pow(nsigmaTOFPr, 2)) < ConfBothTracks.confNsigmaCombPiRejectPrNsigma) { return true; } else { return false; @@ -710,6 +719,7 @@ struct FemtoUniverseEfficiencyBase { continue; } registryCuts.fill(HIST("part1/cutsVspT"), part.pt(), 5); + registryMCOrigin.fill(HIST("part1/hRecoPtBeforePDGCheck"), part.pt()); if (ConfBothTracks.confPDGCheckMCReco && !(std::abs(mcParticle.pdgMCTruth()) == std::abs(confPDGCodePartOne))) { continue; @@ -799,6 +809,7 @@ struct FemtoUniverseEfficiencyBase { continue; } registryCuts.fill(HIST("part2/cutsVspT"), part.pt(), 5); + registryMCOrigin.fill(HIST("part2/hRecoPtBeforePDGCheck"), part.pt()); if (ConfBothTracks.confPDGCheckMCReco && !(std::abs(mcParticle.pdgMCTruth()) == std::abs(confPDGCodePartTwo))) { continue; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx index 658d621303f..90f071fbe16 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx @@ -48,12 +48,14 @@ #include #include +#include #include #include #include #include #include #include +#include #include using namespace o2; @@ -63,8 +65,6 @@ using namespace o2::framework::expressions; using namespace o2::analysis::femto_universe; using namespace o2::aod::pidutils; -// /* CONFIGURABLE NUMBER LIMIT REACHED? Add configurables to structs if anything else needed -> configurables, partitions, histograms .... */ /// - struct femtoUniversePairTaskTrackCascadeExtended { Service pdgMC; @@ -75,10 +75,9 @@ struct femtoUniversePairTaskTrackCascadeExtended { ConfigurableAxis confChildTempFitVarpTBins{"confChildTempFitVarpTBins", {20, 0.5, 4.05}, "V0 child: pT binning of the pT vs. TempFitVar plot"}; ConfigurableAxis confChildTempFitVarBins{"confChildTempFitVarBins", {300, -0.15, 0.15}, "V0 child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; - struct : o2::framework::ConfigurableGroup { - Configurable confCascInvMassLowLimit{"confCascInvMassLowLimit", 1.315, "Lower limit of the Casc invariant mass"}; - Configurable confCascInvMassUpLimit{"confCascInvMassUpLimit", 1.325, "Upper limit of the Casc invariant mass"}; - } cascInvMassCuts; + Configurable confCascInvMassLowLimit{"confCascInvMassLowLimit", 1.315, "Lower limit of the Casc invariant mass"}; + Configurable confCascInvMassUpLimit{"confCascInvMassUpLimit", 1.325, "Upper limit of the Casc invariant mass"}; + /// applying narrow cut struct : o2::framework::ConfigurableGroup { Configurable confZVertexCut{"confZVertexCut", 10.f, "Event sel: Maximum z-Vertex (cm)"}; @@ -95,32 +94,37 @@ struct femtoUniversePairTaskTrackCascadeExtended { Configurable confChargePart2{"confChargePart2", 1, "sign of track particle 2"}; Configurable confHPtPart1{"confHPtPart1", 4.0f, "higher limit for pt of track particle"}; Configurable confLPtPart1{"confLPtPart1", 0.5f, "lower limit for pt of track particle"}; - Configurable confNsigmaCombinedParticle{"confNsigmaCombinedParticle", 3.0, "combined TPC and TOF Sigma for track particle for momentum > Confmom"}; + Configurable confNsigmaCombinedParticle{"confNsigmaCombinedParticle", 3.0, "combined TPC and TOF Sigma for track particle for momentum > cascparticleconfigs.confmom"}; } trackparticleconfigs; /// configurations for cascades - Configurable confCascPDGCode{"confCascPDGCode", 3312, "Particle 2 (Cascade) - PDG code"}; - Configurable confCascType1{"confCascType1", 0, "select one of the Cascades (Omega = 0, Xi = 1, anti-Omega = 2, anti-Xi = 3) for track-cascade and cascade-cascade combination"}; - Configurable confCascType2{"confCascType2", 0, "select one of the Cascades (Omega = 0, Xi = 1, anti-Omega = 2, anti-Xi = 3) for cascade-cascade combination"}; struct : o2::framework::ConfigurableGroup { + Configurable confCascPDGCode{"confCascPDGCode", 3312, "Particle 2 (Cascade) - PDG code"}; + Configurable confCascType1{"confCascType1", 0, "select one of the Cascades (Omega = 0, Xi = 1, anti-Omega = 2, anti-Xi = 3) for track-cascade and cascade-cascade combination"}; + Configurable confCascType2{"confCascType2", 0, "select one of the Cascades (Omega = 0, Xi = 1, anti-Omega = 2, anti-Xi = 3) for cascade-cascade combination"}; Configurable confHPtPart2{"confHPtPart2", 4.0f, "higher limit for pt of cascade"}; Configurable confLPtPart2{"confLPtPart2", 0.3f, "lower limit for pt of cascade"}; - } cascPtLimits; // Structs here only to make space for additional configurables/histograms/partitions - Configurable confmom{"confmom", 0.75, "momentum threshold for particle identification using TOF"}; - Configurable confNsigmaTPCParticle{"confNsigmaTPCParticle", 3.0, "TPC Sigma for particle (track) momentum < Confmom"}; - Configurable confNsigmaTPCParticleChild{"confNsigmaTPCParticleChild", 3.0, "TPC Sigma for particle (daugh & bach) momentum < Confmom"}; - Configurable confNsigmaTOFParticleChild{"confNsigmaTOFParticleChild", 3.0, "TOF Sigma for particle (daugh & bach) momentum > Confmom"}; - Configurable confUseStrangenessTOF{"confUseStrangenessTOF", true, "Enable strangeness TOF for cascade PID"}; + Configurable confmom{"confmom", 0.75, "momentum threshold for particle identification using TOF"}; + Configurable confNsigmaTPCParticle{"confNsigmaTPCParticle", 3.0, "TPC Sigma for particle (track) momentum < cascparticleconfigs.confmom"}; + Configurable confNsigmaTPCParticleChild{"confNsigmaTPCParticleChild", 3.0, "TPC Sigma for particle (daugh & bach) momentum < cascparticleconfigs.confmom"}; + Configurable confNsigmaTOFParticleChild{"confNsigmaTOFParticleChild", 3.0, "TOF Sigma for particle (daugh & bach) momentum > cascparticleconfigs.confmom"}; + Configurable confUseStrangenessTOF{"confUseStrangenessTOF", true, "Enable strangeness TOF for cascade PID"}; + Configurable confQARejectByPDG{"confQARejectByPDG", false, "Reject particle 2 by PDG code (only for QA)"}; + } cascparticleconfigs; + + /// configurations for correlation part - CPR + struct : o2::framework::ConfigurableGroup { + Configurable confIsCPR{"confIsCPR", false, "Close Pair Rejection"}; + Configurable confCPRdeltaPhiCutMax{"confCPRdeltaPhiCutMax", 0.0, "Delta Phi max cut for Close Pair Rejection"}; + Configurable confCPRdeltaPhiCutMin{"confCPRdeltaPhiCutMin", 0.0, "Delta Phi min cut for Close Pair Rejection"}; + Configurable confCPRdeltaEtaCutMax{"confCPRdeltaEtaCutMax", 0.0, "Delta Eta max cut for Close Pair Rejection"}; + Configurable confCPRdeltaEtaCutMin{"confCPRdeltaEtaCutMin", 0.0, "Delta Eta min cut for Close Pair Rejection"}; + Configurable confCPRPlotPerRadii{"confCPRPlotPerRadii", false, "Plot CPR per radii"}; + Configurable confCPRChosenRadii{"confCPRChosenRadii", 0.0, "Delta Eta cut for Close Pair Rejection"}; + Configurable confIsSameSignCPR{"confIsSameSignCPR", false, "Close Pair Rejection for same sign children of cascades"}; + } cprconfigs; /// configurations for correlation part - Configurable confIsCPR{"confIsCPR", false, "Close Pair Rejection"}; - Configurable confCPRdeltaPhiCutMax{"confCPRdeltaPhiCutMax", 0.0, "Delta Phi max cut for Close Pair Rejection"}; - Configurable confCPRdeltaPhiCutMin{"confCPRdeltaPhiCutMin", 0.0, "Delta Phi min cut for Close Pair Rejection"}; - Configurable confCPRdeltaEtaCutMax{"confCPRdeltaEtaCutMax", 0.0, "Delta Eta max cut for Close Pair Rejection"}; - Configurable confCPRdeltaEtaCutMin{"confCPRdeltaEtaCutMin", 0.0, "Delta Eta min cut for Close Pair Rejection"}; - Configurable confCPRPlotPerRadii{"confCPRPlotPerRadii", false, "Plot CPR per radii"}; - Configurable confCPRChosenRadii{"confCPRChosenRadii", 0.0, "Delta Eta cut for Close Pair Rejection"}; - Configurable confIsSameSignCPR{"confIsSameSignCPR", false, "Close Pair Rejection for same sign children of cascades"}; ConfigurableAxis confkstarBins{"confkstarBins", {1500, 0., 6.}, "binning kstar"}; ConfigurableAxis confMultBins{"confMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; ConfigurableAxis confkTBins{"confkTBins", {150, 0., 9.}, "binning kT"}; @@ -169,11 +173,14 @@ struct femtoUniversePairTaskTrackCascadeExtended { Partition partsTrackTwoBasic = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::mAntiLambda == trackparticleconfigs.confChargePart2) && (nabs(aod::femtouniverseparticle::eta) < narrowcuts.confEta) && (aod::femtouniverseparticle::pt < trackparticleconfigs.confHPtPart1) && (aod::femtouniverseparticle::pt > trackparticleconfigs.confLPtPart1); /// Partition for cascades using extended table - Partition partsTwoFull = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)) && (aod::femtouniverseparticle::pt < cascPtLimits.confHPtPart2) && (aod::femtouniverseparticle::pt > cascPtLimits.confLPtPart2); + Partition partsTwoFull = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)) && (aod::femtouniverseparticle::pt < cascparticleconfigs.confHPtPart2) && (aod::femtouniverseparticle::pt > cascparticleconfigs.confLPtPart2); + + /// Partition for cascades using extended MC reco table + Partition partsTwoMCrecoFull = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)) && (aod::femtouniverseparticle::pt < cascparticleconfigs.confHPtPart2) && (aod::femtouniverseparticle::pt > cascparticleconfigs.confLPtPart2); /// Partition for cascades using bitmask (without extended table) - Partition partsTwoBasic = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)) && (aod::femtouniverseparticle::pt < cascPtLimits.confHPtPart2) && (aod::femtouniverseparticle::pt > cascPtLimits.confLPtPart2); - Partition partsTwoMCgenBasic = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (aod::femtouniverseparticle::pt < cascPtLimits.confHPtPart2) && (aod::femtouniverseparticle::pt > cascPtLimits.confLPtPart2); + Partition partsTwoBasic = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)) && (aod::femtouniverseparticle::pt < cascparticleconfigs.confHPtPart2) && (aod::femtouniverseparticle::pt > cascparticleconfigs.confLPtPart2); + Partition partsTwoMCgenBasic = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (aod::femtouniverseparticle::pt < cascparticleconfigs.confHPtPart2) && (aod::femtouniverseparticle::pt > cascparticleconfigs.confLPtPart2); /// Histogramming for track particle FemtoUniverseParticleHisto trackHistoPartOnePos; @@ -220,12 +227,12 @@ struct femtoUniversePairTaskTrackCascadeExtended { bool invMCascade(float invMassXi, float invMassOmega, int cascType) { - return (((cascType == 1 || cascType == 3) && (invMassXi > cascInvMassCuts.confCascInvMassLowLimit && invMassXi < cascInvMassCuts.confCascInvMassUpLimit)) || ((cascType == 0 || cascType == 2) && (invMassOmega > cascInvMassCuts.confCascInvMassLowLimit && invMassOmega < cascInvMassCuts.confCascInvMassUpLimit))); + return (((cascType == 1 || cascType == 3) && (invMassXi > confCascInvMassLowLimit && invMassXi < confCascInvMassUpLimit)) || ((cascType == 0 || cascType == 2) && (invMassOmega > confCascInvMassLowLimit && invMassOmega < confCascInvMassUpLimit))); } bool isNSigmaTPC(float nsigmaTPCParticle) { - if (std::abs(nsigmaTPCParticle) < confNsigmaTPCParticleChild) { + if (std::abs(nsigmaTPCParticle) < cascparticleconfigs.confNsigmaTPCParticleChild) { return true; } else { return false; @@ -235,8 +242,8 @@ struct femtoUniversePairTaskTrackCascadeExtended { bool isNSigmaTOF(float mom, float nsigmaTOFParticle, float hasTOF) { // Cut only on daughter and bachelor tracks, that have TOF signal - if (mom > confmom && hasTOF == 1) { - if (std::abs(nsigmaTOFParticle) < confNsigmaTOFParticleChild) { + if (mom > cascparticleconfigs.confmom && hasTOF == 1) { + if (std::abs(nsigmaTOFParticle) < cascparticleconfigs.confNsigmaTOFParticleChild) { return true; } else { return false; @@ -248,8 +255,8 @@ struct femtoUniversePairTaskTrackCascadeExtended { bool isNSigmaCombined(float mom, float nsigmaTPCParticle, float nsigmaTOFParticle, bool hasTOF) { - if (mom <= confmom) { - return (std::abs(nsigmaTPCParticle) < confNsigmaTPCParticle); + if (mom <= cascparticleconfigs.confmom) { + return (std::abs(nsigmaTPCParticle) < cascparticleconfigs.confNsigmaTPCParticle); } else if (hasTOF == 1) { return (TMath::Hypot(nsigmaTOFParticle, nsigmaTPCParticle) < trackparticleconfigs.confNsigmaCombinedParticle); } else { @@ -260,7 +267,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { template bool isNSigmaCombinedBitmask(float mom, const T& part) { - if (mom <= confmom) { + if (mom <= cascparticleconfigs.confmom) { return ((part.pidCut() & (1u << trackparticleconfigs.confTrackChoicePartOne)) != 0); } else if ((part.pidCut() & 512u) != 0) { return ((part.pidCut() & (64u << trackparticleconfigs.confTrackChoicePartOne)) != 0); @@ -348,8 +355,8 @@ struct femtoUniversePairTaskTrackCascadeExtended { registryMCgen.add("plus/MCgenCasc", "MC gen cascades;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); registryMCgen.add("minus/MCgenCasc", "MC gen cascades;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); - registryMCgen.add("plus/MCgenAllPt", "MC gen all;#it{p}_{T} (GeV/c); #eta", {HistType::kTH1F, {{500, 0, 5}}}); - registryMCgen.add("minus/MCgenAllPt", "MC gen all;#it{p}_{T} (GeV/c); #eta", {HistType::kTH1F, {{500, 0, 5}}}); + registryMCgen.add("plus/MCgenAllPt", "MC gen all;#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + registryMCgen.add("minus/MCgenAllPt", "MC gen all;#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); registryMCgen.add("plus/MCgenPr", "MC gen protons;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); registryMCgen.add("minus/MCgenPr", "MC gen protons;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); @@ -361,8 +368,8 @@ struct femtoUniversePairTaskTrackCascadeExtended { registryMCreco.add("plus/MCrecoCascade", "MC reco Cascades;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); registryMCreco.add("minus/MCrecoCascade", "MC reco Cascades;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); - registryMCreco.add("plus/MCrecoAllPt", "MC reco all;#it{p}_{T} (GeV/c); #eta", {HistType::kTH1F, {{500, 0, 5}}}); - registryMCreco.add("minus/MCrecoAllPt", "MC reco all;#it{p}_{T} (GeV/c); #eta", {HistType::kTH1F, {{500, 0, 5}}}); + registryMCreco.add("plus/MCrecoAllPt", "MC reco all;#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + registryMCreco.add("minus/MCrecoAllPt", "MC reco all;#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); registryMCreco.add("plus/MCrecoPr", "MC reco protons;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); registryMCreco.add("minus/MCrecoPr", "MC reco protons;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); @@ -380,20 +387,20 @@ struct femtoUniversePairTaskTrackCascadeExtended { sameEventCont.init(&resultRegistry, confkstarBins, confMultBins, confkTBins, confmTBins, confMultBins3D, confmTBins3D, confEtaBins, confPhiBins, confIsMC, confUse3D); mixedEventCont.init(&resultRegistry, confkstarBins, confMultBins, confkTBins, confmTBins, confMultBins3D, confmTBins3D, confEtaBins, confPhiBins, confIsMC, confUse3D); - sameEventCont.setPDGCodes(trackparticleconfigs.confTrkPDGCodePartOne, confCascPDGCode); - mixedEventCont.setPDGCodes(trackparticleconfigs.confTrkPDGCodePartOne, confCascPDGCode); + sameEventCont.setPDGCodes(trackparticleconfigs.confTrkPDGCodePartOne, cascparticleconfigs.confCascPDGCode); + mixedEventCont.setPDGCodes(trackparticleconfigs.confTrkPDGCodePartOne, cascparticleconfigs.confCascPDGCode); pairCleaner.init(&qaRegistry); pairCleanerTrack.init(&qaRegistry); pairCleanerCasc.init(&qaRegistry); - if (confIsCPR.value) { + if (cprconfigs.confIsCPR.value) { if (doprocessSameEvent || doprocessSameEventBitmask || doprocessMixedEvent || doprocessMixedEventBitmask) - pairCloseRejection.init(&resultRegistry, &qaRegistry, twotracksconfigs.confDeltaEtaAxis, twotracksconfigs.confDeltaPhiStarAxis, confCPRdeltaPhiCutMin.value, confCPRdeltaPhiCutMax.value, confCPRdeltaEtaCutMin.value, confCPRdeltaEtaCutMax.value, confCPRChosenRadii.value, confCPRPlotPerRadii.value, 0, 0, confIsSameSignCPR.value); + pairCloseRejection.init(&resultRegistry, &qaRegistry, twotracksconfigs.confDeltaEtaAxis, twotracksconfigs.confDeltaPhiStarAxis, cprconfigs.confCPRdeltaPhiCutMin.value, cprconfigs.confCPRdeltaPhiCutMax.value, cprconfigs.confCPRdeltaEtaCutMin.value, cprconfigs.confCPRdeltaEtaCutMax.value, cprconfigs.confCPRChosenRadii.value, cprconfigs.confCPRPlotPerRadii.value, 0, 0, cprconfigs.confIsSameSignCPR.value); if (doprocessSameEventTrack || doprocessSameEventTrackBitmask || doprocessMixedEventTrack || doprocessMixedEventTrackBitmask) - pairCloseRejectionTrack.init(&resultRegistry, &qaRegistry, twotracksconfigs.confDeltaEtaAxis, twotracksconfigs.confDeltaPhiStarAxis, confCPRdeltaPhiCutMin.value, confCPRdeltaPhiCutMax.value, confCPRdeltaEtaCutMin.value, confCPRdeltaEtaCutMax.value, confCPRChosenRadii.value, confCPRPlotPerRadii.value, 0, 0, confIsSameSignCPR.value); + pairCloseRejectionTrack.init(&resultRegistry, &qaRegistry, twotracksconfigs.confDeltaEtaAxis, twotracksconfigs.confDeltaPhiStarAxis, cprconfigs.confCPRdeltaPhiCutMin.value, cprconfigs.confCPRdeltaPhiCutMax.value, cprconfigs.confCPRdeltaEtaCutMin.value, cprconfigs.confCPRdeltaEtaCutMax.value, cprconfigs.confCPRChosenRadii.value, cprconfigs.confCPRPlotPerRadii.value, 0, 0, cprconfigs.confIsSameSignCPR.value); if (doprocessSameEventCasc || doprocessSameEventCascBitmask || doprocessMixedEventCasc || doprocessMixedEventCascBitmask) - pairCloseRejectionCasc.init(&resultRegistry, &qaRegistry, twotracksconfigs.confDeltaEtaAxis, twotracksconfigs.confDeltaPhiStarAxis, confCPRdeltaPhiCutMin.value, confCPRdeltaPhiCutMax.value, confCPRdeltaEtaCutMin.value, confCPRdeltaEtaCutMax.value, confCPRChosenRadii.value, confCPRPlotPerRadii.value, 0, 0, confIsSameSignCPR.value); + pairCloseRejectionCasc.init(&resultRegistry, &qaRegistry, twotracksconfigs.confDeltaEtaAxis, twotracksconfigs.confDeltaPhiStarAxis, cprconfigs.confCPRdeltaPhiCutMin.value, cprconfigs.confCPRdeltaPhiCutMax.value, cprconfigs.confCPRdeltaEtaCutMin.value, cprconfigs.confCPRdeltaEtaCutMax.value, cprconfigs.confCPRChosenRadii.value, cprconfigs.confCPRPlotPerRadii.value, 0, 0, cprconfigs.confIsSameSignCPR.value); } if (!ccdbEffLoader.confLocalEfficiency.value.empty()) { @@ -402,11 +409,11 @@ struct femtoUniversePairTaskTrackCascadeExtended { LOGF(fatal, "Could not load efficiency histogram from %s", ccdbEffLoader.confLocalEfficiency.value.c_str()); if (doprocessSameEvent || doprocessSameEventBitmask || doprocessMixedEvent || doprocessMixedEventBitmask) { pEffHistp1 = (trackparticleconfigs.confChargePart1 > 0) ? std::unique_ptr(plocalEffFile.get()->Get("PrPlus")) : std::unique_ptr(plocalEffFile.get()->Get("PrMinus")); // note: works only for protons for now - pEffHistp2 = (confCascType1 == 0 || confCascType1 == 1) ? std::unique_ptr(plocalEffFile.get()->Get("Cascade")) : std::unique_ptr(plocalEffFile.get()->Get("AntiCascade")); + pEffHistp2 = (cascparticleconfigs.confCascType1 == 0 || cascparticleconfigs.confCascType1 == 1) ? std::unique_ptr(plocalEffFile.get()->Get("Cascade")) : std::unique_ptr(plocalEffFile.get()->Get("AntiCascade")); LOGF(info, "Loaded efficiency histograms for track-Cascade."); } else if (doprocessSameEventCasc || doprocessSameEventCascBitmask || doprocessMixedEventCasc || doprocessMixedEventCascBitmask) { - pEffHistp1 = (confCascType1 == 0 || confCascType1 == 1) ? std::unique_ptr(plocalEffFile.get()->Get("Cascade")) : std::unique_ptr(plocalEffFile.get()->Get("AntiCascade")); - pEffHistp2 = (confCascType2 == 0 || confCascType2 == 1) ? std::unique_ptr(plocalEffFile.get()->Get("Cascade")) : std::unique_ptr(plocalEffFile.get()->Get("AntiCascade")); + pEffHistp1 = (cascparticleconfigs.confCascType1 == 0 || cascparticleconfigs.confCascType1 == 1) ? std::unique_ptr(plocalEffFile.get()->Get("Cascade")) : std::unique_ptr(plocalEffFile.get()->Get("AntiCascade")); + pEffHistp2 = (cascparticleconfigs.confCascType2 == 0 || cascparticleconfigs.confCascType2 == 1) ? std::unique_ptr(plocalEffFile.get()->Get("Cascade")) : std::unique_ptr(plocalEffFile.get()->Get("AntiCascade")); LOGF(info, "Loaded efficiency histograms for Cascade-Cascade."); } else if (doprocessSameEventTrack || doprocessSameEventTrackBitmask || doprocessMixedEventTrack || doprocessMixedEventTrackBitmask) { pEffHistp1 = (trackparticleconfigs.confChargePart1 > 0) ? std::unique_ptr(plocalEffFile.get()->Get("PrPlus")) : std::unique_ptr(plocalEffFile.get()->Get("PrMinus")); // note: works only for protons for now @@ -420,11 +427,11 @@ struct femtoUniversePairTaskTrackCascadeExtended { ccdb->setCreatedNotAfter(std::max(ccdbEffLoader.confCCDBNoLaterThanTrack.value, ccdbEffLoader.confCCDBNoLaterThanCasc.value)); if (doprocessSameEvent || doprocessSameEventBitmask || doprocessMixedEvent || doprocessMixedEventBitmask) { pEffHistp1 = (trackparticleconfigs.confChargePart1 > 0) ? std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/PrPlus", ccdbEffLoader.confCCDBNoLaterThanTrack.value)) : std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/PrMinus", ccdbEffLoader.confCCDBNoLaterThanTrack.value)); /// works only for protons - pEffHistp2 = (confCascType1 == 0 || confCascType1 == 1) ? std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/Cascade", ccdbEffLoader.confCCDBNoLaterThanCasc.value)) : std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/AntiCascade", ccdbEffLoader.confCCDBNoLaterThanCasc.value)); + pEffHistp2 = (cascparticleconfigs.confCascType1 == 0 || cascparticleconfigs.confCascType1 == 1) ? std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/Cascade", ccdbEffLoader.confCCDBNoLaterThanCasc.value)) : std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/AntiCascade", ccdbEffLoader.confCCDBNoLaterThanCasc.value)); LOGF(info, "Loaded efficiency histograms for track-Cascade from CCDB"); } else if (doprocessSameEventCasc || doprocessSameEventCascBitmask || doprocessMixedEventCasc || doprocessMixedEventCascBitmask) { - pEffHistp1 = (confCascType1 == 0 || confCascType1 == 1) ? std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/Cascade", ccdbEffLoader.confCCDBNoLaterThanCasc.value)) : std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/AntiCascade", ccdbEffLoader.confCCDBNoLaterThanCasc.value)); - pEffHistp2 = (confCascType2 == 0 || confCascType2 == 1) ? std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/Cascade", ccdbEffLoader.confCCDBNoLaterThanCasc.value)) : std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/AntiCascade", ccdbEffLoader.confCCDBNoLaterThanCasc.value)); + pEffHistp1 = (cascparticleconfigs.confCascType1 == 0 || cascparticleconfigs.confCascType1 == 1) ? std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/Cascade", ccdbEffLoader.confCCDBNoLaterThanCasc.value)) : std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/AntiCascade", ccdbEffLoader.confCCDBNoLaterThanCasc.value)); + pEffHistp2 = (cascparticleconfigs.confCascType2 == 0 || cascparticleconfigs.confCascType2 == 1) ? std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/Cascade", ccdbEffLoader.confCCDBNoLaterThanCasc.value)) : std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/AntiCascade", ccdbEffLoader.confCCDBNoLaterThanCasc.value)); LOGF(info, "Loaded efficiency histograms for Cascade-Cascade from CCDB."); } else if (doprocessSameEventTrack || doprocessSameEventTrackBitmask || doprocessMixedEventTrack || doprocessMixedEventTrackBitmask) { pEffHistp1 = (trackparticleconfigs.confChargePart1 > 0) ? std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/PrPlus", ccdbEffLoader.confCCDBNoLaterThanTrack.value)) : std::unique_ptr(ccdb->getForTimeStamp(ccdbEffLoader.confCCDBEfficiency.value + "/PrMinus", ccdbEffLoader.confCCDBNoLaterThanTrack.value)); /// works only for protons @@ -452,10 +459,10 @@ struct femtoUniversePairTaskTrackCascadeExtended { if constexpr (std::experimental::is_detected::value) { float posChildTPC, negChildTPC, bachelorTPC, posChildTOF, negChildTOF, bachelorTOF; - if (!isParticleTPC(posChild, CascChildTable[confCascType1][0], &posChildTPC) || !isParticleTPC(negChild, CascChildTable[confCascType1][1], &negChildTPC) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2], &bachelorTPC)) + if (!isParticleTPC(posChild, CascChildTable[cascparticleconfigs.confCascType1][0], &posChildTPC) || !isParticleTPC(negChild, CascChildTable[cascparticleconfigs.confCascType1][1], &negChildTPC) || !isParticleTPC(bachelor, CascChildTable[cascparticleconfigs.confCascType1][2], &bachelorTPC)) continue; - if (!isParticleTOF(posChild, CascChildTable[confCascType1][0], &posChildTOF) || !isParticleTOF(negChild, CascChildTable[confCascType1][1], &negChildTOF) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2], &bachelorTOF)) + if (!isParticleTOF(posChild, CascChildTable[cascparticleconfigs.confCascType1][0], &posChildTOF) || !isParticleTOF(negChild, CascChildTable[cascparticleconfigs.confCascType1][1], &negChildTOF) || !isParticleTOF(bachelor, CascChildTable[cascparticleconfigs.confCascType1][2], &bachelorTOF)) continue; CascQAExtra.fill(HIST("hPtXi"), part.pt()); @@ -476,10 +483,10 @@ struct femtoUniversePairTaskTrackCascadeExtended { if constexpr (std::experimental::is_detected::value) { float posChildTPCExt, negChildTPCExt, bachelorTPCExt, posChildTOFExt, negChildTOFExt, bachelorTOFExt; - if (!isParticleTPC(posChildExt, CascChildTable[confCascType1][0], &posChildTPCExt) || !isParticleTPC(negChildExt, CascChildTable[confCascType1][1], &negChildTPCExt) || !isParticleTPC(bachelorExt, CascChildTable[confCascType1][2], &bachelorTPCExt)) + if (!isParticleTPC(posChildExt, CascChildTable[cascparticleconfigs.confCascType1][0], &posChildTPCExt) || !isParticleTPC(negChildExt, CascChildTable[cascparticleconfigs.confCascType1][1], &negChildTPCExt) || !isParticleTPC(bachelorExt, CascChildTable[cascparticleconfigs.confCascType1][2], &bachelorTPCExt)) continue; - if (!isParticleTOF(posChildExt, CascChildTable[confCascType1][0], &posChildTOFExt) || !isParticleTOF(negChildExt, CascChildTable[confCascType1][1], &negChildTOFExt) || !isParticleTOF(bachelorExt, CascChildTable[confCascType1][2], &bachelorTOFExt)) + if (!isParticleTOF(posChildExt, CascChildTable[cascparticleconfigs.confCascType1][0], &posChildTOFExt) || !isParticleTOF(negChildExt, CascChildTable[cascparticleconfigs.confCascType1][1], &negChildTOFExt) || !isParticleTOF(bachelorExt, CascChildTable[cascparticleconfigs.confCascType1][2], &bachelorTOFExt)) continue; CascQAExtra.fill(HIST("hDCAV0Daughters"), casc.dcaV0daughters()); @@ -496,9 +503,48 @@ struct femtoUniversePairTaskTrackCascadeExtended { } } - /// track - cascade correlations + // Additional cascade QA plots for MC template - void doSameEvent(const FilteredFDCollision& col, const TableType& parts, PartitionType& partsOne, PartitionType& partsTwo) + void doCascadeMCQA([[maybe_unused]] const FilteredFDCollision& col, const TableType& parts, PartitionType& partsTwo, aod::FdMCParticles const& mcparts) + { + auto groupPartsTwo = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + + // Basic particle loop + for (const auto& part : groupPartsTwo) { + auto mcPartId = part.fdMCParticleId(); + if (mcPartId == -1) + continue; // no MC particle + const auto& mcpart = mcparts.iteratorAt(mcPartId); + + if (cascparticleconfigs.confQARejectByPDG && ((cascparticleconfigs.confCascType1 == 0 && mcpart.pdgMCTruth() == kOmegaMinus) || (cascparticleconfigs.confCascType1 == 1 && mcpart.pdgMCTruth() == kXiMinus) || (cascparticleconfigs.confCascType1 == 2 && mcpart.pdgMCTruth() == kOmegaPlusBar) || (cascparticleconfigs.confCascType1 == 3 && mcpart.pdgMCTruth() == kXiPlusBar))) + continue; + + CascQAExtra.fill(HIST("hMassXi"), part.mLambda()); + + const auto& posChild = parts.iteratorAt(part.globalIndex() - 3 - parts.begin().globalIndex()); + const auto& negChild = parts.iteratorAt(part.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& bachelor = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); + + if constexpr (std::experimental::is_detected::value) { + float posChildTPC, negChildTPC, bachelorTPC, posChildTOF, negChildTOF, bachelorTOF; + if (!isParticleTPC(posChild, CascChildTable[cascparticleconfigs.confCascType1][0], &posChildTPC) || !isParticleTPC(negChild, CascChildTable[cascparticleconfigs.confCascType1][1], &negChildTPC) || !isParticleTPC(bachelor, CascChildTable[cascparticleconfigs.confCascType1][2], &bachelorTPC)) + continue; + + if (!isParticleTOF(posChild, CascChildTable[cascparticleconfigs.confCascType1][0], &posChildTOF) || !isParticleTOF(negChild, CascChildTable[cascparticleconfigs.confCascType1][1], &negChildTOF) || !isParticleTOF(bachelor, CascChildTable[cascparticleconfigs.confCascType1][2], &bachelorTOF)) + continue; + + CascQAExtra.fill(HIST("hPtXi"), part.pt()); + CascQAExtra.fill(HIST("hEtaXi"), part.eta()); + CascQAExtra.fill(HIST("hPhiXi"), part.phi()); + CascQAExtra.fill(HIST("hMassXiSelected"), part.mLambda()); + CascQAExtra.fill(HIST("hInvMpT"), part.pt(), part.mLambda()); + } + } + } + + /// track - cascade correlations + template + void doSameEvent(const FilteredFDCollision& col, const TableType& parts, PartitionType& partsOne, PartitionType& partsTwo, [[maybe_unused]] MCParticles mcParts = nullptr) { const auto& magFieldTesla = col.magField(); @@ -510,7 +556,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { const int multCol = confUseCent ? col.multV0M() : col.multNtr(); for (const auto& part : groupPartsTwo) { - if (!invMCascade(part.mLambda(), part.mAntiLambda(), confCascType1)) /// mLambda stores Xi mass, mAntiLambda stores Omega mass + if (!invMCascade(part.mLambda(), part.mAntiLambda(), cascparticleconfigs.confCascType1)) /// mLambda stores Xi mass, mAntiLambda stores Omega mass continue; const auto& posChild = parts.iteratorAt(part.globalIndex() - 3 - parts.begin().globalIndex()); @@ -519,10 +565,10 @@ struct femtoUniversePairTaskTrackCascadeExtended { /// Child particles must pass this condition to be selected if constexpr (std::experimental::is_detected::value) { float posChildTPC, negChildTPC, bachelorTPC, posChildTOF, negChildTOF, bachelorTOF; - if (!isParticleTPC(posChild, CascChildTable[confCascType1][0], &posChildTPC) || !isParticleTPC(negChild, CascChildTable[confCascType1][1], &negChildTPC) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2], &bachelorTPC)) + if (!isParticleTPC(posChild, CascChildTable[cascparticleconfigs.confCascType1][0], &posChildTPC) || !isParticleTPC(negChild, CascChildTable[cascparticleconfigs.confCascType1][1], &negChildTPC) || !isParticleTPC(bachelor, CascChildTable[cascparticleconfigs.confCascType1][2], &bachelorTPC)) continue; - if (!isParticleTOF(posChild, CascChildTable[confCascType1][0], &posChildTOF) || !isParticleTOF(negChild, CascChildTable[confCascType1][1], &negChildTOF) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2], &bachelorTOF)) + if (!isParticleTOF(posChild, CascChildTable[cascparticleconfigs.confCascType1][0], &posChildTOF) || !isParticleTOF(negChild, CascChildTable[cascparticleconfigs.confCascType1][1], &negChildTOF) || !isParticleTOF(bachelor, CascChildTable[cascparticleconfigs.confCascType1][2], &bachelorTOF)) continue; posChildHistos.fillQA(posChild); @@ -539,14 +585,14 @@ struct femtoUniversePairTaskTrackCascadeExtended { cascQAHistos.fillQA(part); } else { - if ((posChild.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + if ((posChild.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][2])) == 0) continue; - if (confUseStrangenessTOF) { - if (((confCascType1 == 1 || confCascType1 == 3) && (part.pidCut() & 7) != 7) || ((confCascType1 == 0 || confCascType1 == 2) && (part.pidCut() & 56) != 56)) + if (cascparticleconfigs.confUseStrangenessTOF) { + if (((cascparticleconfigs.confCascType1 == 1 || cascparticleconfigs.confCascType1 == 3) && (part.pidCut() & 7) != 7) || ((cascparticleconfigs.confCascType1 == 0 || cascparticleconfigs.confCascType1 == 2) && (part.pidCut() & 56) != 56)) continue; } else { - if ((posChild.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + if ((posChild.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][2])) == 0) continue; } @@ -590,7 +636,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { // Cascade inv mass cut (mLambda stores Xi mass, mAntiLambda stores Omega mass) - if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), confCascType1)) + if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), cascparticleconfigs.confCascType1)) continue; // PID if constexpr (std::experimental::is_detected::value) { @@ -605,7 +651,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } - if (confIsCPR.value) { + if (cprconfigs.confIsCPR.value) { if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla, femto_universe_container::EventType::same)) { continue; } @@ -616,25 +662,28 @@ struct femtoUniversePairTaskTrackCascadeExtended { const auto& bachelor = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); /// Child particles must pass this condition to be selected if constexpr (std::experimental::is_detected::value) { - if (!isParticleTPC(posChild, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2])) + if (!isParticleTPC(posChild, CascChildTable[cascparticleconfigs.confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[cascparticleconfigs.confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[cascparticleconfigs.confCascType1][2])) continue; - if (!isParticleTOF(posChild, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[confCascType1][1]) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2])) + if (!isParticleTOF(posChild, CascChildTable[cascparticleconfigs.confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[cascparticleconfigs.confCascType1][1]) || !isParticleTOF(bachelor, CascChildTable[cascparticleconfigs.confCascType1][2])) continue; } else { - if ((posChild.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + if ((posChild.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][2])) == 0) continue; - if (confUseStrangenessTOF) { - if (((confCascType1 == 1 || confCascType1 == 3) && (p2.pidCut() & 7) != 7) || ((confCascType1 == 0 || confCascType1 == 2) && (p2.pidCut() & 56) != 56)) + if (cascparticleconfigs.confUseStrangenessTOF) { + if (((cascparticleconfigs.confCascType1 == 1 || cascparticleconfigs.confCascType1 == 3) && (p2.pidCut() & 7) != 7) || ((cascparticleconfigs.confCascType1 == 0 || cascparticleconfigs.confCascType1 == 2) && (p2.pidCut() & 56) != 56)) continue; } else { - if ((posChild.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + if ((posChild.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][2])) == 0) continue; } } float weight = 1.0f; if (pEffHistp1) weight = pEffHistp1.get()->GetBinContent(pEffHistp1->FindBin(p1.pt(), p1.eta())) * pEffHistp2.get()->GetBinContent(pEffHistp2->FindBin(p2.pt(), p2.eta())); - sameEventCont.setPair(p1, p2, multCol, confUse3D, weight); + if constexpr (std::is_same::value) + sameEventCont.setPair(p1, p2, multCol, confUse3D, weight); + else + sameEventCont.setPair(p1, p2, multCol, confUse3D, weight); } } @@ -644,6 +693,12 @@ struct femtoUniversePairTaskTrackCascadeExtended { } PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processCascadeQA, "Enable additional QA for cascades", false); + void processCascadeMCQA([[maybe_unused]] const FilteredFDCollision& col, const FemtoRecoFullParticles& parts, aod::FdMCParticles const& mcparts) + { + doCascadeMCQA(col, parts, partsTwoMCrecoFull, mcparts); + } + PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processCascadeMCQA, "Enable additional QA for cascades in MC (when processCascadeQA is off)", false); + void processSameEvent(const FilteredFDCollision& col, const FemtoFullParticles& parts) { doSameEvent(col, parts, partsTrackOneFull, partsTwoFull); @@ -671,7 +726,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { const int multCol = confUseCent ? col.multV0M() : col.multNtr(); for (const auto& part : groupPartsTwo) { - if (!invMCascade(part.mLambda(), part.mAntiLambda(), confCascType1)) /// mLambda stores Xi mass, mAntiLambda stores Omega mass + if (!invMCascade(part.mLambda(), part.mAntiLambda(), cascparticleconfigs.confCascType1)) /// mLambda stores Xi mass, mAntiLambda stores Omega mass continue; if constexpr (std::experimental::is_detected::value) @@ -684,22 +739,22 @@ struct femtoUniversePairTaskTrackCascadeExtended { const auto& bachelor = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); /// Check daughters of first cascade if constexpr (std::experimental::is_detected::value) { - if (!isParticleTPC(posChild, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2])) + if (!isParticleTPC(posChild, CascChildTable[cascparticleconfigs.confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[cascparticleconfigs.confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[cascparticleconfigs.confCascType1][2])) continue; - if (!isParticleTOF(posChild, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[confCascType1][1]) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2])) + if (!isParticleTOF(posChild, CascChildTable[cascparticleconfigs.confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[cascparticleconfigs.confCascType1][1]) || !isParticleTOF(bachelor, CascChildTable[cascparticleconfigs.confCascType1][2])) continue; posChildHistos.fillQA(posChild); negChildHistos.fillQA(negChild); bachHistos.fillQABase(bachelor, HIST("hBachelor")); } else { - if ((posChild.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + if ((posChild.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][2])) == 0) continue; - if (confUseStrangenessTOF) { - if (((confCascType1 == 1 || confCascType1 == 3) && (part.pidCut() & 7) != 7) || ((confCascType1 == 0 || confCascType1 == 2) && (part.pidCut() & 56) != 56)) + if (cascparticleconfigs.confUseStrangenessTOF) { + if (((cascparticleconfigs.confCascType1 == 1 || cascparticleconfigs.confCascType1 == 3) && (part.pidCut() & 7) != 7) || ((cascparticleconfigs.confCascType1 == 0 || cascparticleconfigs.confCascType1 == 2) && (part.pidCut() & 56) != 56)) continue; } else { - if ((posChild.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + if ((posChild.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][2])) == 0) continue; } @@ -711,10 +766,10 @@ struct femtoUniversePairTaskTrackCascadeExtended { auto pairDuplicateCheckFunc = [&](auto& p1, auto& p2) -> void { // Cascade inv mass cut for p1 (mLambda stores Xi mass, mAntiLambda stores Omega mass) - if (!invMCascade(p1.mLambda(), p1.mAntiLambda(), confCascType1)) + if (!invMCascade(p1.mLambda(), p1.mAntiLambda(), cascparticleconfigs.confCascType1)) return; // Cascade inv mass cut for p2 - if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), confCascType2)) + if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), cascparticleconfigs.confCascType2)) return; // track cleaning & checking for duplicate pairs if (!pairCleanerCasc.isCleanPair(p1, p2, parts)) { @@ -736,9 +791,9 @@ struct femtoUniversePairTaskTrackCascadeExtended { auto pairProcessFunc = [&](auto& p1, auto& p2) -> bool { if (cascDuplicates.contains(p1.globalIndex()) || cascDuplicates.contains(p2.globalIndex())) return false; - if (!invMCascade(p1.mLambda(), p1.mAntiLambda(), confCascType1)) + if (!invMCascade(p1.mLambda(), p1.mAntiLambda(), cascparticleconfigs.confCascType1)) return false; - if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), confCascType2)) + if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), cascparticleconfigs.confCascType2)) return false; const auto& posChild1 = parts.iteratorAt(p1.globalIndex() - 3 - parts.begin().globalIndex()); @@ -746,18 +801,18 @@ struct femtoUniversePairTaskTrackCascadeExtended { const auto& bachelor1 = parts.iteratorAt(p1.globalIndex() - 1 - parts.begin().globalIndex()); /// Child particles must pass this condition to be selected if constexpr (std::experimental::is_detected::value) { - if (!isParticleTPC(posChild1, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild1, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor1, CascChildTable[confCascType1][2])) + if (!isParticleTPC(posChild1, CascChildTable[cascparticleconfigs.confCascType1][0]) || !isParticleTPC(negChild1, CascChildTable[cascparticleconfigs.confCascType1][1]) || !isParticleTPC(bachelor1, CascChildTable[cascparticleconfigs.confCascType1][2])) return false; - if (!isParticleTOF(posChild1, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild1, CascChildTable[confCascType1][1]) || !isParticleTOF(bachelor1, CascChildTable[confCascType1][2])) + if (!isParticleTOF(posChild1, CascChildTable[cascparticleconfigs.confCascType1][0]) || !isParticleTOF(negChild1, CascChildTable[cascparticleconfigs.confCascType1][1]) || !isParticleTOF(bachelor1, CascChildTable[cascparticleconfigs.confCascType1][2])) return false; } else { - if ((posChild1.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild1.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor1.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + if ((posChild1.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][0])) == 0 || (negChild1.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][1])) == 0 || (bachelor1.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][2])) == 0) return false; - if (confUseStrangenessTOF) { - if (((confCascType1 == 1 || confCascType1 == 3) && (p1.pidCut() & 7) != 7) || ((confCascType1 == 0 || confCascType1 == 2) && (p1.pidCut() & 56) != 56)) + if (cascparticleconfigs.confUseStrangenessTOF) { + if (((cascparticleconfigs.confCascType1 == 1 || cascparticleconfigs.confCascType1 == 3) && (p1.pidCut() & 7) != 7) || ((cascparticleconfigs.confCascType1 == 0 || cascparticleconfigs.confCascType1 == 2) && (p1.pidCut() & 56) != 56)) return false; } else { - if ((posChild1.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild1.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0 || (bachelor1.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + if ((posChild1.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][0])) == 0 || (negChild1.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][1])) == 0 || (bachelor1.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][2])) == 0) return false; } } @@ -767,23 +822,23 @@ struct femtoUniversePairTaskTrackCascadeExtended { const auto& bachelor2 = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); /// Child particles must pass this condition to be selected if constexpr (std::experimental::is_detected::value) { - if (!isParticleTPC(posChild2, CascChildTable[confCascType2][0]) || !isParticleTPC(negChild2, CascChildTable[confCascType2][1]) || !isParticleTPC(bachelor2, CascChildTable[confCascType2][2])) + if (!isParticleTPC(posChild2, CascChildTable[cascparticleconfigs.confCascType2][0]) || !isParticleTPC(negChild2, CascChildTable[cascparticleconfigs.confCascType2][1]) || !isParticleTPC(bachelor2, CascChildTable[cascparticleconfigs.confCascType2][2])) return false; - if (!isParticleTOF(posChild2, CascChildTable[confCascType2][0]) || !isParticleTOF(negChild2, CascChildTable[confCascType2][1]) || !isParticleTOF(bachelor2, CascChildTable[confCascType2][2])) + if (!isParticleTOF(posChild2, CascChildTable[cascparticleconfigs.confCascType2][0]) || !isParticleTOF(negChild2, CascChildTable[cascparticleconfigs.confCascType2][1]) || !isParticleTOF(bachelor2, CascChildTable[cascparticleconfigs.confCascType2][2])) return false; } else { - if ((posChild2.pidCut() & (1u << CascChildTable[confCascType2][0])) == 0 || (negChild2.pidCut() & (1u << CascChildTable[confCascType2][1])) == 0 || (bachelor2.pidCut() & (1u << CascChildTable[confCascType2][2])) == 0) + if ((posChild2.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType2][0])) == 0 || (negChild2.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType2][1])) == 0 || (bachelor2.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType2][2])) == 0) return false; - if (confUseStrangenessTOF) { - if (((confCascType2 == 1 || confCascType2 == 3) && (p2.pidCut() & 7) != 7) || ((confCascType2 == 0 || confCascType2 == 2) && (p2.pidCut() & 56) != 56)) + if (cascparticleconfigs.confUseStrangenessTOF) { + if (((cascparticleconfigs.confCascType2 == 1 || cascparticleconfigs.confCascType2 == 3) && (p2.pidCut() & 7) != 7) || ((cascparticleconfigs.confCascType2 == 0 || cascparticleconfigs.confCascType2 == 2) && (p2.pidCut() & 56) != 56)) return false; } else { - if ((posChild2.pidCut() & (8u << CascChildTable[confCascType2][0])) == 0 || (negChild2.pidCut() & (8u << CascChildTable[confCascType2][1])) == 0 || (bachelor2.pidCut() & (8u << CascChildTable[confCascType2][2])) == 0) + if ((posChild2.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType2][0])) == 0 || (negChild2.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType2][1])) == 0 || (bachelor2.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType2][2])) == 0) return false; } } - if (confIsCPR.value) { + if (cprconfigs.confIsCPR.value) { if (pairCloseRejectionCasc.isClosePair(p1, p2, parts, magFieldTesla, femto_universe_container::EventType::same)) { return false; } @@ -918,7 +973,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { return; } - if (confIsCPR.value) { + if (cprconfigs.confIsCPR.value) { if (pairCloseRejectionTrack.isClosePair(p1, p2, parts, magFieldTesla, femto_universe_container::EventType::same)) { return; } @@ -955,8 +1010,8 @@ struct femtoUniversePairTaskTrackCascadeExtended { PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processSameEventTrackBitmask, "Enable processing same event for track - track using bitmask for PID", false); /// track - cascade correlations - template - void doMixedEvent(const FilteredFDCollisions& cols, const TableType& parts, PartitionType& partsOne, PartitionType& partsTwo) + template + void doMixedEvent(const FilteredFDCollisions& cols, const TableType& parts, PartitionType& partsOne, PartitionType& partsTwo, [[maybe_unused]] MCParticles mcParts = nullptr) { ColumnBinningPolicy colBinningMult{{confVtxBins, confMultBins}, true}; ColumnBinningPolicy colBinningCent{{confVtxBins, confMultBins}, true}; @@ -975,7 +1030,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { } for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { // Cascade inv mass cut (mLambda stores Xi mass, mAntiLambda stores Omega mass) - if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), confCascType1)) + if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), cascparticleconfigs.confCascType1)) continue; // PID if constexpr (std::experimental::is_detected::value) { @@ -992,18 +1047,18 @@ struct femtoUniversePairTaskTrackCascadeExtended { const auto& bachelor = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); /// Child particles must pass this condition to be selected if constexpr (std::experimental::is_detected::value) { - if (!isParticleTPC(posChild, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2])) + if (!isParticleTPC(posChild, CascChildTable[cascparticleconfigs.confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[cascparticleconfigs.confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[cascparticleconfigs.confCascType1][2])) continue; - if (!isParticleTOF(posChild, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[confCascType1][1]) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2])) + if (!isParticleTOF(posChild, CascChildTable[cascparticleconfigs.confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[cascparticleconfigs.confCascType1][1]) || !isParticleTOF(bachelor, CascChildTable[cascparticleconfigs.confCascType1][2])) continue; } else { - if ((posChild.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + if ((posChild.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][2])) == 0) continue; - if (confUseStrangenessTOF) { - if (((confCascType1 == 1 || confCascType1 == 3) && (p2.pidCut() & 7) != 7) || ((confCascType1 == 0 || confCascType1 == 2) && (p2.pidCut() & 56) != 56)) + if (cascparticleconfigs.confUseStrangenessTOF) { + if (((cascparticleconfigs.confCascType1 == 1 || cascparticleconfigs.confCascType1 == 3) && (p2.pidCut() & 7) != 7) || ((cascparticleconfigs.confCascType1 == 0 || cascparticleconfigs.confCascType1 == 2) && (p2.pidCut() & 56) != 56)) continue; } else { - if ((posChild.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + if ((posChild.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][2])) == 0) continue; } } @@ -1012,7 +1067,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } - if (confIsCPR.value) { + if (cprconfigs.confIsCPR.value) { if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla1, femto_universe_container::EventType::mixed)) { continue; } @@ -1021,7 +1076,10 @@ struct femtoUniversePairTaskTrackCascadeExtended { float weight = 1.0f; if (pEffHistp1) weight = pEffHistp1.get()->GetBinContent(pEffHistp1->FindBin(p1.pt(), p1.eta())) * pEffHistp2.get()->GetBinContent(pEffHistp2->FindBin(p2.pt(), p2.eta())); - mixedEventCont.setPair(p1, p2, multCol, confUse3D, weight); + if constexpr (std::is_same::value) + mixedEventCont.setPair(p1, p2, multCol, confUse3D, weight); + else + mixedEventCont.setPair(p1, p2, multCol, confUse3D, weight); } }; @@ -1070,10 +1128,10 @@ struct femtoUniversePairTaskTrackCascadeExtended { } for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { // Cascade inv mass cut for p1 (mLambda stores Xi mass, mAntiLambda stores Omega mass) - if (!invMCascade(p1.mLambda(), p1.mAntiLambda(), confCascType1)) + if (!invMCascade(p1.mLambda(), p1.mAntiLambda(), cascparticleconfigs.confCascType1)) continue; // Cascade inv mass cut for p2 - if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), confCascType2)) + if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), cascparticleconfigs.confCascType2)) continue; const auto& posChild1 = parts.iteratorAt(p1.globalIndex() - 3 - parts.begin().globalIndex()); @@ -1081,18 +1139,18 @@ struct femtoUniversePairTaskTrackCascadeExtended { const auto& bachelor1 = parts.iteratorAt(p1.globalIndex() - 1 - parts.begin().globalIndex()); /// Child particles must pass this condition to be selected if constexpr (std::experimental::is_detected::value) { - if (!isParticleTPC(posChild1, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild1, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor1, CascChildTable[confCascType1][2])) + if (!isParticleTPC(posChild1, CascChildTable[cascparticleconfigs.confCascType1][0]) || !isParticleTPC(negChild1, CascChildTable[cascparticleconfigs.confCascType1][1]) || !isParticleTPC(bachelor1, CascChildTable[cascparticleconfigs.confCascType1][2])) continue; - if (!isParticleTOF(posChild1, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild1, CascChildTable[confCascType1][1]) || !isParticleTOF(bachelor1, CascChildTable[confCascType1][2])) + if (!isParticleTOF(posChild1, CascChildTable[cascparticleconfigs.confCascType1][0]) || !isParticleTOF(negChild1, CascChildTable[cascparticleconfigs.confCascType1][1]) || !isParticleTOF(bachelor1, CascChildTable[cascparticleconfigs.confCascType1][2])) continue; } else { - if ((posChild1.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild1.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor1.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + if ((posChild1.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][0])) == 0 || (negChild1.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][1])) == 0 || (bachelor1.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][2])) == 0) continue; - if (confUseStrangenessTOF) { - if (((confCascType1 == 1 || confCascType1 == 3) && (p1.pidCut() & 7) != 7) || ((confCascType1 == 0 || confCascType1 == 2) && (p1.pidCut() & 56) != 56)) + if (cascparticleconfigs.confUseStrangenessTOF) { + if (((cascparticleconfigs.confCascType1 == 1 || cascparticleconfigs.confCascType1 == 3) && (p1.pidCut() & 7) != 7) || ((cascparticleconfigs.confCascType1 == 0 || cascparticleconfigs.confCascType1 == 2) && (p1.pidCut() & 56) != 56)) continue; } else { - if ((posChild1.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild1.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0 || (bachelor1.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + if ((posChild1.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][0])) == 0 || (negChild1.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][1])) == 0 || (bachelor1.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][2])) == 0) continue; } } @@ -1102,18 +1160,18 @@ struct femtoUniversePairTaskTrackCascadeExtended { const auto& bachelor2 = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); /// Child particles must pass this condition to be selected if constexpr (std::experimental::is_detected::value) { - if (!isParticleTPC(posChild2, CascChildTable[confCascType2][0]) || !isParticleTPC(negChild2, CascChildTable[confCascType2][1]) || !isParticleTPC(bachelor2, CascChildTable[confCascType2][2])) + if (!isParticleTPC(posChild2, CascChildTable[cascparticleconfigs.confCascType2][0]) || !isParticleTPC(negChild2, CascChildTable[cascparticleconfigs.confCascType2][1]) || !isParticleTPC(bachelor2, CascChildTable[cascparticleconfigs.confCascType2][2])) continue; - if (!isParticleTOF(posChild2, CascChildTable[confCascType2][0]) || !isParticleTOF(negChild2, CascChildTable[confCascType2][1]) || !isParticleTOF(bachelor2, CascChildTable[confCascType2][2])) + if (!isParticleTOF(posChild2, CascChildTable[cascparticleconfigs.confCascType2][0]) || !isParticleTOF(negChild2, CascChildTable[cascparticleconfigs.confCascType2][1]) || !isParticleTOF(bachelor2, CascChildTable[cascparticleconfigs.confCascType2][2])) continue; } else { - if ((posChild2.pidCut() & (1u << CascChildTable[confCascType2][0])) == 0 || (negChild2.pidCut() & (1u << CascChildTable[confCascType2][1])) == 0 || (bachelor2.pidCut() & (1u << CascChildTable[confCascType2][2])) == 0) + if ((posChild2.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType2][0])) == 0 || (negChild2.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType2][1])) == 0 || (bachelor2.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType2][2])) == 0) continue; - if (confUseStrangenessTOF) { - if (((confCascType2 == 1 || confCascType2 == 3) && (p2.pidCut() & 7) != 7) || ((confCascType2 == 0 || confCascType2 == 2) && (p2.pidCut() & 56) != 56)) + if (cascparticleconfigs.confUseStrangenessTOF) { + if (((cascparticleconfigs.confCascType2 == 1 || cascparticleconfigs.confCascType2 == 3) && (p2.pidCut() & 7) != 7) || ((cascparticleconfigs.confCascType2 == 0 || cascparticleconfigs.confCascType2 == 2) && (p2.pidCut() & 56) != 56)) continue; } else { - if ((posChild2.pidCut() & (8u << CascChildTable[confCascType2][0])) == 0 || (negChild2.pidCut() & (8u << CascChildTable[confCascType2][1])) == 0 || (bachelor2.pidCut() & (8u << CascChildTable[confCascType2][2])) == 0) + if ((posChild2.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType2][0])) == 0 || (negChild2.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType2][1])) == 0 || (bachelor2.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType2][2])) == 0) continue; } } @@ -1121,7 +1179,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { if (!pairCleanerCasc.isCleanPair(p1, p2, parts)) { continue; } - if (confIsCPR.value) { + if (cprconfigs.confIsCPR.value) { if (pairCloseRejectionCasc.isClosePair(p1, p2, parts, magFieldTesla1, femto_universe_container::EventType::mixed)) { continue; } @@ -1190,7 +1248,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { continue; } - if (confIsCPR.value) { + if (cprconfigs.confIsCPR.value) { if (pairCloseRejectionTrack.isClosePair(p1, p2, parts, magFieldTesla1, femto_universe_container::EventType::mixed)) { continue; } @@ -1228,7 +1286,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { for (const auto& part : groupPartsTwo) { int pdgCode = static_cast(part.pidCut()); - if ((confCascType1 == 0 && pdgCode != kOmegaMinus) || (confCascType1 == 2 && pdgCode != kOmegaPlusBar) || (confCascType1 == 1 && pdgCode != kXiMinus) || (confCascType1 == 3 && pdgCode != kXiPlusBar)) + if ((cascparticleconfigs.confCascType1 == 0 && pdgCode != kOmegaMinus) || (cascparticleconfigs.confCascType1 == 2 && pdgCode != kOmegaPlusBar) || (cascparticleconfigs.confCascType1 == 1 && pdgCode != kXiMinus) || (cascparticleconfigs.confCascType1 == 3 && pdgCode != kXiPlusBar)) continue; cascQAHistos.fillQA(part); } @@ -1253,7 +1311,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { if (static_cast(p1.pidCut()) != trackparticleconfigs.confTrkPDGCodePartOne) continue; int pdgCodeCasc = static_cast(p2.pidCut()); - if ((confCascType1 == 0 && pdgCodeCasc != kOmegaMinus) || (confCascType1 == 2 && pdgCodeCasc != kOmegaPlusBar) || (confCascType1 == 1 && pdgCodeCasc != kXiMinus) || (confCascType1 == 3 && pdgCodeCasc != kXiPlusBar)) + if ((cascparticleconfigs.confCascType1 == 0 && pdgCodeCasc != kOmegaMinus) || (cascparticleconfigs.confCascType1 == 2 && pdgCodeCasc != kOmegaPlusBar) || (cascparticleconfigs.confCascType1 == 1 && pdgCodeCasc != kXiMinus) || (cascparticleconfigs.confCascType1 == 3 && pdgCodeCasc != kXiPlusBar)) continue; sameEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); } @@ -1271,22 +1329,22 @@ struct femtoUniversePairTaskTrackCascadeExtended { for (const auto& part : groupPartsTwo) { int pdgCode = static_cast(part.pidCut()); - if ((confCascType1 == 0 && pdgCode != kOmegaMinus) || (confCascType1 == 2 && pdgCode != kOmegaPlusBar) || (confCascType1 == 1 && pdgCode != kXiMinus) || (confCascType1 == 3 && pdgCode != kXiPlusBar)) + if ((cascparticleconfigs.confCascType1 == 0 && pdgCode != kOmegaMinus) || (cascparticleconfigs.confCascType1 == 2 && pdgCode != kOmegaPlusBar) || (cascparticleconfigs.confCascType1 == 1 && pdgCode != kXiMinus) || (cascparticleconfigs.confCascType1 == 3 && pdgCode != kXiPlusBar)) continue; cascQAHistos.fillQA(part); } auto pairProcessFunc = [&](auto& p1, auto& p2) -> void { int pdgCodeCasc1 = static_cast(p1.pidCut()); - if ((confCascType1 == 0 && pdgCodeCasc1 != kOmegaMinus) || (confCascType1 == 2 && pdgCodeCasc1 != kOmegaPlusBar) || (confCascType1 == 1 && pdgCodeCasc1 != kXiMinus) || (confCascType1 == 3 && pdgCodeCasc1 != kXiPlusBar)) + if ((cascparticleconfigs.confCascType1 == 0 && pdgCodeCasc1 != kOmegaMinus) || (cascparticleconfigs.confCascType1 == 2 && pdgCodeCasc1 != kOmegaPlusBar) || (cascparticleconfigs.confCascType1 == 1 && pdgCodeCasc1 != kXiMinus) || (cascparticleconfigs.confCascType1 == 3 && pdgCodeCasc1 != kXiPlusBar)) return; int pdgCodeCasc2 = static_cast(p2.pidCut()); - if ((confCascType2 == 0 && pdgCodeCasc2 != kOmegaMinus) || (confCascType2 == 2 && pdgCodeCasc2 != kOmegaPlusBar) || (confCascType2 == 1 && pdgCodeCasc2 != kXiMinus) || (confCascType2 == 3 && pdgCodeCasc2 != kXiPlusBar)) + if ((cascparticleconfigs.confCascType2 == 0 && pdgCodeCasc2 != kOmegaMinus) || (cascparticleconfigs.confCascType2 == 2 && pdgCodeCasc2 != kOmegaPlusBar) || (cascparticleconfigs.confCascType2 == 1 && pdgCodeCasc2 != kXiMinus) || (cascparticleconfigs.confCascType2 == 3 && pdgCodeCasc2 != kXiPlusBar)) return; sameEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); }; - if (confCascType1 == confCascType2) { + if (cascparticleconfigs.confCascType1 == cascparticleconfigs.confCascType2) { for (const auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsTwo, groupPartsTwo))) pairProcessFunc(p1, p2); } else { @@ -1317,7 +1375,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { if (static_cast(p1.pidCut()) != trackparticleconfigs.confTrkPDGCodePartOne) continue; int pdgCodeCasc = static_cast(p2.pidCut()); - if ((confCascType1 == 0 && pdgCodeCasc != kOmegaMinus) || (confCascType1 == 2 && pdgCodeCasc != kOmegaPlusBar) || (confCascType1 == 1 && pdgCodeCasc != kXiMinus) || (confCascType1 == 3 && pdgCodeCasc != kXiPlusBar)) + if ((cascparticleconfigs.confCascType1 == 0 && pdgCodeCasc != kOmegaMinus) || (cascparticleconfigs.confCascType1 == 2 && pdgCodeCasc != kOmegaPlusBar) || (cascparticleconfigs.confCascType1 == 1 && pdgCodeCasc != kXiMinus) || (cascparticleconfigs.confCascType1 == 3 && pdgCodeCasc != kXiPlusBar)) continue; mixedEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); } @@ -1344,10 +1402,10 @@ struct femtoUniversePairTaskTrackCascadeExtended { } for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { int pdgCodeCasc1 = static_cast(p1.pidCut()); - if ((confCascType1 == 0 && pdgCodeCasc1 != kOmegaMinus) || (confCascType1 == 2 && pdgCodeCasc1 != kOmegaPlusBar) || (confCascType1 == 1 && pdgCodeCasc1 != kXiMinus) || (confCascType1 == 3 && pdgCodeCasc1 != kXiPlusBar)) + if ((cascparticleconfigs.confCascType1 == 0 && pdgCodeCasc1 != kOmegaMinus) || (cascparticleconfigs.confCascType1 == 2 && pdgCodeCasc1 != kOmegaPlusBar) || (cascparticleconfigs.confCascType1 == 1 && pdgCodeCasc1 != kXiMinus) || (cascparticleconfigs.confCascType1 == 3 && pdgCodeCasc1 != kXiPlusBar)) continue; int pdgCodeCasc2 = static_cast(p2.pidCut()); - if ((confCascType2 == 0 && pdgCodeCasc2 != kOmegaMinus) || (confCascType2 == 2 && pdgCodeCasc2 != kOmegaPlusBar) || (confCascType2 == 1 && pdgCodeCasc2 != kXiMinus) || (confCascType2 == 3 && pdgCodeCasc2 != kXiPlusBar)) + if ((cascparticleconfigs.confCascType2 == 0 && pdgCodeCasc2 != kOmegaMinus) || (cascparticleconfigs.confCascType2 == 2 && pdgCodeCasc2 != kOmegaPlusBar) || (cascparticleconfigs.confCascType2 == 1 && pdgCodeCasc2 != kXiMinus) || (cascparticleconfigs.confCascType2 == 3 && pdgCodeCasc2 != kXiPlusBar)) continue; mixedEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); } @@ -1355,6 +1413,20 @@ struct femtoUniversePairTaskTrackCascadeExtended { } PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processMixedEventCascMCgen, "Enable processing mixed event MC truth for cascade - cascade", false); + // WIP: process same event mc truth and reco + void processSameEventMCReco(FilteredFDCollision const& col, FemtoRecoFullParticles const& parts, aod::FdMCParticles const& mcparts) + { + doSameEvent(col, parts, partsTrackOneFullMc, partsTwoMCrecoFull, mcparts); + } + PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processSameEventMCReco, "Enable processing same event for track - V0 MC Reco", false); + + // WIP: process mixed event mc truth and reco + void processMixedEventMCReco(FilteredFDCollisions const& cols, FemtoRecoFullParticles const& parts, aod::FdMCParticles const& mcparts) + { + doMixedEvent(cols, parts, partsTrackOneFullMc, partsTwoMCrecoFull, mcparts); + } + PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processMixedEventMCReco, "Enable processing mixed event for track - V0 for MC Reco", false); + /// This function fills MC truth particles from derived MC table void processMCgen(aod::FDParticles const& parts) { @@ -1368,10 +1440,10 @@ struct femtoUniversePairTaskTrackCascadeExtended { continue; } - if ((confCascType1 == 0 && pdgCode == kOmegaMinus) || (confCascType1 == 1 && pdgCode == kXiMinus)) { + if ((cascparticleconfigs.confCascType1 == 0 && pdgCode == kOmegaMinus) || (cascparticleconfigs.confCascType1 == 1 && pdgCode == kXiMinus)) { registryMCgen.fill(HIST("plus/MCgenCasc"), part.pt(), part.eta()); continue; - } else if ((confCascType1 == 0 && pdgCode == kOmegaPlusBar) || (confCascType1 == 1 && pdgCode == kXiPlusBar)) { + } else if ((cascparticleconfigs.confCascType1 == 0 && pdgCode == kOmegaPlusBar) || (cascparticleconfigs.confCascType1 == 1 && pdgCode == kXiPlusBar)) { registryMCgen.fill(HIST("minus/MCgenCasc"), part.pt(), part.eta()); continue; } @@ -1406,49 +1478,49 @@ struct femtoUniversePairTaskTrackCascadeExtended { const auto& mcpart = mcparts.iteratorAt(mcPartId); // if (part.partType() == aod::femtouniverseparticle::ParticleType::kCascade) { - if (!invMCascade(part.mLambda(), part.mAntiLambda(), confCascType1)) /// mLambda stores Xi mass, mAntiLambda stores Omega mass + if (!invMCascade(part.mLambda(), part.mAntiLambda(), cascparticleconfigs.confCascType1)) /// mLambda stores Xi mass, mAntiLambda stores Omega mass continue; - if ((confCascType1 == 0 && mcpart.pdgMCTruth() == kOmegaMinus) || (confCascType1 == 1 && mcpart.pdgMCTruth() == kXiMinus)) { + if ((cascparticleconfigs.confCascType1 == 0 && mcpart.pdgMCTruth() == kOmegaMinus) || (cascparticleconfigs.confCascType1 == 1 && mcpart.pdgMCTruth() == kXiMinus)) { const auto& posChild = parts.iteratorAt(part.globalIndex() - 3 - parts.begin().globalIndex()); const auto& negChild = parts.iteratorAt(part.globalIndex() - 2 - parts.begin().globalIndex()); const auto& bachelor = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); /// Daughters that do not pass this condition are not selected if constexpr (std::experimental::is_detected::value) { - if (!isParticleTPC(posChild, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2])) + if (!isParticleTPC(posChild, CascChildTable[cascparticleconfigs.confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[cascparticleconfigs.confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[cascparticleconfigs.confCascType1][2])) continue; - if (!isParticleTOF(posChild, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[confCascType1][1]) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2])) + if (!isParticleTOF(posChild, CascChildTable[cascparticleconfigs.confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[cascparticleconfigs.confCascType1][1]) || !isParticleTOF(bachelor, CascChildTable[cascparticleconfigs.confCascType1][2])) continue; } else { - if ((posChild.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + if ((posChild.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1][2])) == 0) continue; - if (confUseStrangenessTOF) { - if (((confCascType1 == 1) && (part.pidCut() & 7) != 7) || ((confCascType1 == 0) && (part.pidCut() & 56) != 56)) + if (cascparticleconfigs.confUseStrangenessTOF) { + if (((cascparticleconfigs.confCascType1 == 1) && (part.pidCut() & 7) != 7) || ((cascparticleconfigs.confCascType1 == 0) && (part.pidCut() & 56) != 56)) continue; } else { - if ((posChild.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + if ((posChild.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1][2])) == 0) continue; } } registryMCreco.fill(HIST("plus/MCrecoCascade"), mcpart.pt(), mcpart.eta()); - } else if ((confCascType1 == 0 && mcpart.pdgMCTruth() == kOmegaPlusBar) || (confCascType1 == 1 && mcpart.pdgMCTruth() == kXiPlusBar)) { + } else if ((cascparticleconfigs.confCascType1 == 0 && mcpart.pdgMCTruth() == kOmegaPlusBar) || (cascparticleconfigs.confCascType1 == 1 && mcpart.pdgMCTruth() == kXiPlusBar)) { const auto& posChild = parts.iteratorAt(part.globalIndex() - 3 - parts.begin().globalIndex()); const auto& negChild = parts.iteratorAt(part.globalIndex() - 2 - parts.begin().globalIndex()); const auto& bachelor = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); /// Daughters that do not pass this condition are not selected if constexpr (std::experimental::is_detected::value) { - if (!isParticleTPC(posChild, CascChildTable[confCascType1 + 2][0]) || !isParticleTPC(negChild, CascChildTable[confCascType1 + 2][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType1 + 2][2])) + if (!isParticleTPC(posChild, CascChildTable[cascparticleconfigs.confCascType1 + 2][0]) || !isParticleTPC(negChild, CascChildTable[cascparticleconfigs.confCascType1 + 2][1]) || !isParticleTPC(bachelor, CascChildTable[cascparticleconfigs.confCascType1 + 2][2])) continue; - if (!isParticleTOF(posChild, CascChildTable[confCascType1 + 2][0]) || !isParticleTOF(negChild, CascChildTable[confCascType1 + 2][1]) || !isParticleTOF(bachelor, CascChildTable[confCascType1 + 2][2])) + if (!isParticleTOF(posChild, CascChildTable[cascparticleconfigs.confCascType1 + 2][0]) || !isParticleTOF(negChild, CascChildTable[cascparticleconfigs.confCascType1 + 2][1]) || !isParticleTOF(bachelor, CascChildTable[cascparticleconfigs.confCascType1 + 2][2])) continue; } else { - if ((posChild.pidCut() & (1u << CascChildTable[confCascType1 + 2][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[confCascType1 + 2][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType1 + 2][2])) == 0) + if ((posChild.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1 + 2][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1 + 2][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[cascparticleconfigs.confCascType1 + 2][2])) == 0) continue; - if (confUseStrangenessTOF) { - if (((confCascType1 == 1) && (part.pidCut() & 7) != 7) || ((confCascType1 == 0) && (part.pidCut() & 56) != 56)) + if (cascparticleconfigs.confUseStrangenessTOF) { + if (((cascparticleconfigs.confCascType1 == 1) && (part.pidCut() & 7) != 7) || ((cascparticleconfigs.confCascType1 == 0) && (part.pidCut() & 56) != 56)) continue; } else { - if ((posChild.pidCut() & (8u << CascChildTable[confCascType1 + 2][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[confCascType1 + 2][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[confCascType1 + 2][2])) == 0) + if ((posChild.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1 + 2][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1 + 2][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[cascparticleconfigs.confCascType1 + 2][2])) == 0) continue; } } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx index e156ddedab2..62536648430 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx @@ -171,12 +171,14 @@ struct FemtoUniversePairTaskTrackD0 { } ConfMlOpt; Configurable> binsPt{"binsPt", std::vector{hf_cuts_d0_to_pi_k::vecBinsPt}, "pT bin limits"}; + Configurable> binsPtTH3{"binsPtTH3", std::vector{hf_cuts_d0_to_pi_k::vecBinsPt}, "pT bin limits"}; Configurable confChooseD0trackCorr{"confChooseD0trackCorr", 0, "If 0 correlations with D0s, if 1 with D0bars"}; - // Correlated background for D0/D0bar candidates - Configurable fillCorrBkgs{"fillCorrBkgs", false, "Fill histograms with correlated background candidates"}; - // Configurable to enable BDT vs pT histograms for D0/D0bar at MC Reco level - Configurable fillBDTvsPt{"fillBDTvsPt", true, "Fill BDT vs pT histograms for D0/D0bar candidates"}; - + struct : o2::framework::ConfigurableGroup { + // Correlated background for D0/D0bar candidates + Configurable fillCorrBkgs{"fillCorrBkgs", false, "Fill histograms with correlated background candidates"}; + // Configurable to enable BDT vs pT histograms for D0/D0bar at MC Reco level + Configurable fillBDTvsPt{"fillBDTvsPt", true, "Fill BDT vs pT histograms for D0/D0bar candidates"}; + } ConfFill; // Efficiency Configurable doEfficiencyCorr{"doEfficiencyCorr", false, "Apply efficiency corrections"}; @@ -511,6 +513,7 @@ struct FemtoUniversePairTaskTrackD0 { // D0/D0bar histograms auto vbins = (std::vector)binsPt; + auto vPtBinsTH3 = (std::vector)binsPtTH3; if (doEfficiencyCorr) { registry.add("D0D0bar_oneMassHypo/hMassVsPtEffCorr", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); registry.add("D0D0bar_oneMassHypo/hMassVsPtD0EffCorr", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); @@ -530,14 +533,14 @@ struct FemtoUniversePairTaskTrackD0 { registry.add("DebugBdt/hBdtScore1", ";BDT score;Entries", {HistType::kTH1F, {axisBdtScore}}); registry.add("DebugBdt/hBdtScore2", ";BDT score;Entries", {HistType::kTH1F, {axisBdtScore}}); registry.add("DebugBdt/hBdtScore3", ";BDT score;Entries", {HistType::kTH1F, {axisBdtScore}}); - if (fillBDTvsPt) { + if (ConfFill.fillBDTvsPt) { registry.add("DebugBdtMcReco/hBdtScore1VsPt", ";BDT score;#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {axisBdtScore, {vbins}}}); registry.add("DebugBdtMcReco/hBdtScore2VsPt", ";BDT score;#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {axisBdtScore, {vbins}}}); registry.add("DebugBdtMcReco/hBdtScore3VsPt", ";BDT score;#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {axisBdtScore, {vbins}}}); - registry.add("DebugBdtMcReco/hBdtScore3VsPtVsMassPromptD0", ";BDT score;#it{p}_{T} (GeV/#it{c});M(K#pi) (GeV/#it{c}^{2})", {HistType::kTH3F, {axisBdtScore, {vbins}, confInvMassBins}}); - registry.add("DebugBdtMcReco/hBdtScore3VsPtVsMassNonPromptD0", ";BDT score;#it{p}_{T} (GeV/#it{c});M(K#pi) (GeV/#it{c}^{2})", {HistType::kTH3F, {axisBdtScore, {vbins}, confInvMassBins}}); - registry.add("DebugBdtMcReco/hBdtScore3VsPtVsMassPromptD0bar", ";BDT score;#it{p}_{T} (GeV/#it{c});M(K#pi) (GeV/#it{c}^{2})", {HistType::kTH3F, {axisBdtScore, {vbins}, confInvMassBins}}); - registry.add("DebugBdtMcReco/hBdtScore3VsPtVsMassNonPromptD0bar", ";BDT score;#it{p}_{T} (GeV/#it{c});M(K#pi) (GeV/#it{c}^{2})", {HistType::kTH3F, {axisBdtScore, {vbins}, confInvMassBins}}); + registry.add("DebugBdtMcReco/hBdtScore3VsPtVsMassPromptD0", ";BDT score;#it{p}_{T} (GeV/#it{c});M(K#pi) (GeV/#it{c}^{2})", {HistType::kTH3F, {axisBdtScore, {vPtBinsTH3}, confInvMassBins}}); + registry.add("DebugBdtMcReco/hBdtScore3VsPtVsMassNonPromptD0", ";BDT score;#it{p}_{T} (GeV/#it{c});M(K#pi) (GeV/#it{c}^{2})", {HistType::kTH3F, {axisBdtScore, {vPtBinsTH3}, confInvMassBins}}); + registry.add("DebugBdtMcReco/hBdtScore3VsPtVsMassPromptD0bar", ";BDT score;#it{p}_{T} (GeV/#it{c});M(K#pi) (GeV/#it{c}^{2})", {HistType::kTH3F, {axisBdtScore, {vPtBinsTH3}, confInvMassBins}}); + registry.add("DebugBdtMcReco/hBdtScore3VsPtVsMassNonPromptD0bar", ";BDT score;#it{p}_{T} (GeV/#it{c});M(K#pi) (GeV/#it{c}^{2})", {HistType::kTH3F, {axisBdtScore, {vPtBinsTH3}, confInvMassBins}}); } if (applyMLOpt) { registry.add("D0D0bar_MLSel/hMassVsPt1", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); @@ -580,7 +583,7 @@ struct FemtoUniversePairTaskTrackD0 { mcRecoRegistry.add("hMassVsPtD0barPrompt", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); mcRecoRegistry.add("hMassVsPtD0barNonPrompt", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); // Histograms for D0/D0bar correlated backgrounds - if (fillCorrBkgs) { + if (ConfFill.fillCorrBkgs) { mcRecoRegistry.add("hMassVsPtD0ToPiKaPi", "2-prong candidates;inv. mass (#pi^{+} K^{-} #pi^{0}) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); mcRecoRegistry.add("hMassVsPtD0ToPiPi", "2-prong candidates;inv. mass (#pi^{+} #pi^{-}) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); mcRecoRegistry.add("hMassVsPtD0ToPiPiPi", "2-prong candidates;inv. mass (#pi^{+} #pi^{-} #pi^{0}) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); @@ -609,16 +612,20 @@ struct FemtoUniversePairTaskTrackD0 { mcTruthRegistry.add("hMcGenD0Pt", "MC Truth all D0s;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {vbins}}); mcTruthRegistry.add("hMcGenD0Prompt", "MC Truth prompt D0s;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); mcTruthRegistry.add("hMcGenD0PromptPt", "MC Truth prompt D0s;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {vbins}}); + mcTruthRegistry.add("hMcGenD0PromptPtLessBins", "MC Truth prompt D0s;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {vPtBinsTH3}}); mcTruthRegistry.add("hMcGenD0NonPrompt", "MC Truth non-prompt D0s;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); mcTruthRegistry.add("hMcGenD0NonPromptPt", "MC Truth non-prompt D0s;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {vbins}}); + mcTruthRegistry.add("hMcGenD0NonPromptPtLessBins", "MC Truth non-prompt D0s;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {vPtBinsTH3}}); mcTruthRegistry.add("hMcGenD0bar", "MC Truth all D0bars;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); mcTruthRegistry.add("hMcGenD0barPt", "MC Truth all D0bars;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {vbins}}); mcTruthRegistry.add("hMcGenD0barPrompt", "MC Truth prompt D0bars;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); mcTruthRegistry.add("hMcGenD0barPromptPt", "MC Truth prompt D0s;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {vbins}}); + mcTruthRegistry.add("hMcGenD0barPromptPtLessBins", "MC Truth prompt D0s;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {vPtBinsTH3}}); mcTruthRegistry.add("hMcGenD0barNonPrompt", "MC Truth non-prompt D0bars;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); mcTruthRegistry.add("hMcGenD0barNonPromptPt", "MC Truth non-prompt D0s;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {vbins}}); - mcTruthRegistry.add("hMcGenAllPositivePt", "MC Truth all positive;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{360, 0, 36}}}); - mcTruthRegistry.add("hMcGenAllNegativePt", "MC Truth all negative;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{360, 0, 36}}}); + mcTruthRegistry.add("hMcGenD0barNonPromptPtLessBins", "MC Truth non-prompt D0s;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {vPtBinsTH3}}); + mcTruthRegistry.add("hMcGenAllPositivePt", "MC Truth all positive;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); + mcTruthRegistry.add("hMcGenAllNegativePt", "MC Truth all negative;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); mcTruthRegistry.add("hMcGenKpPtVsEta", "MC Truth K+;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); mcTruthRegistry.add("hMcGenKmPtVsEta", "MC Truth K-;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); mcTruthRegistry.add("hMcGenPipPtVsEta", "MC Truth #pi+;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); @@ -938,7 +945,7 @@ struct FemtoUniversePairTaskTrackD0 { continue; } } - trackHistoPartTrack.fillQA(track); + trackHistoPartTrack.fillQA(track); tpcNSigmaPi = trackCuts.getNsigmaTPC(track, o2::track::PID::Pion); tofNSigmaPi = trackCuts.getNsigmaTOF(track, o2::track::PID::Pion); @@ -1469,7 +1476,7 @@ struct FemtoUniversePairTaskTrackD0 { } } } else if ((part.partType() == aod::femtouniverseparticle::ParticleType::kD0) && (part.pt() > ConfDmesons.confMinPtD0D0barReco) && (part.pt() < ConfDmesons.confMaxPtD0D0barReco)) { - if (fillBDTvsPt && std::abs(mcpart.pdgMCTruth()) == o2::constants::physics::Pdg::kD0) { + if (ConfFill.fillBDTvsPt && std::abs(mcpart.pdgMCTruth()) == o2::constants::physics::Pdg::kD0) { registry.fill(HIST("DebugBdtMcReco/hBdtScore1VsPt"), part.decayVtxX(), part.pt()); registry.fill(HIST("DebugBdtMcReco/hBdtScore2VsPt"), part.decayVtxY(), part.pt()); registry.fill(HIST("DebugBdtMcReco/hBdtScore3VsPt"), part.decayVtxZ(), part.pt()); @@ -1483,14 +1490,14 @@ struct FemtoUniversePairTaskTrackD0 { mcRecoRegistry.fill(HIST("hMcRecD0Prompt"), part.pt(), part.eta()); mcRecoRegistry.fill(HIST("hMcRecD0PromptPt"), part.pt()); mcRecoRegistry.fill(HIST("hMcRecD0PromptPhi"), part.phi()); - if (fillBDTvsPt) { + if (ConfFill.fillBDTvsPt) { registry.fill(HIST("DebugBdtMcReco/hBdtScore3VsPtVsMassPromptD0"), part.decayVtxZ(), part.pt(), part.mLambda()); } } else if (part.tpcNClsFound() == 1) { // non-prompt candidates mcRecoRegistry.fill(HIST("hMcRecD0NonPrompt"), part.pt(), part.eta()); mcRecoRegistry.fill(HIST("hMcRecD0NonPromptPt"), part.pt()); mcRecoRegistry.fill(HIST("hMcRecD0NonPromptPhi"), part.phi()); - if (fillBDTvsPt) { + if (ConfFill.fillBDTvsPt) { registry.fill(HIST("DebugBdtMcReco/hBdtScore3VsPtVsMassNonPromptD0"), part.decayVtxZ(), part.pt(), part.mAntiLambda()); } } @@ -1502,13 +1509,13 @@ struct FemtoUniversePairTaskTrackD0 { if (part.tpcNClsFound() == 0) { // prompt candidates mcRecoRegistry.fill(HIST("hMcRecD0barPrompt"), part.pt(), part.eta()); mcRecoRegistry.fill(HIST("hMcRecD0barPromptPt"), part.pt()); - if (fillBDTvsPt) { + if (ConfFill.fillBDTvsPt) { registry.fill(HIST("DebugBdtMcReco/hBdtScore3VsPtVsMassPromptD0bar"), part.decayVtxZ(), part.pt(), part.mLambda()); } } else if (part.tpcNClsFound() == 1) { // non-prompt candidates mcRecoRegistry.fill(HIST("hMcRecD0barNonPrompt"), part.pt(), part.eta()); mcRecoRegistry.fill(HIST("hMcRecD0barNonPromptPt"), part.pt()); - if (fillBDTvsPt) { + if (ConfFill.fillBDTvsPt) { registry.fill(HIST("DebugBdtMcReco/hBdtScore3VsPtVsMassNonPromptD0bar"), part.decayVtxZ(), part.pt(), part.mAntiLambda()); } } @@ -1538,7 +1545,7 @@ struct FemtoUniversePairTaskTrackD0 { } else { mcRecoRegistry.fill(HIST("hMassVsPtD0Bkg"), part.mLambda(), part.pt(), weight); } - if (fillCorrBkgs) { + if (ConfFill.fillCorrBkgs) { if (part.sign() == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiKPi0) { // D0 -> pi+K-pi0 mcRecoRegistry.fill(HIST("hMassVsPtD0ToPiKaPi"), part.mLambda(), part.pt(), weight); } else if (part.sign() == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiPi) { // D0 -> pi+pi- @@ -1562,7 +1569,7 @@ struct FemtoUniversePairTaskTrackD0 { } else { mcRecoRegistry.fill(HIST("hMassVsPtD0barBkg"), part.mAntiLambda(), part.pt(), weight); } - if (fillCorrBkgs) { + if (ConfFill.fillCorrBkgs) { if (part.sign() == -o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiKPi0) { // D0 -> pi+K-pi0 mcRecoRegistry.fill(HIST("hMassVsPtD0barToPiKaPi"), part.mLambda(), part.pt(), weight); } else if (part.sign() == -o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiPi) { // D0 -> pi+pi- @@ -1597,18 +1604,7 @@ struct FemtoUniversePairTaskTrackD0 { if (!pdgParticle) { continue; } - - if (pdgParticle->Charge() > 0.0) { - mcTruthRegistry.fill(HIST("hMcGenAllPositivePt"), part.pt()); - } - if (pdgCode == PDG_t::kPiPlus) { - mcTruthRegistry.fill(HIST("hMcGenPipPtVsEta"), part.pt(), part.eta()); - mcTruthRegistry.fill(HIST("hMcGenPipPt"), part.pt()); - } - if (pdgCode == PDG_t::kKPlus) { - mcTruthRegistry.fill(HIST("hMcGenKpPtVsEta"), part.pt(), part.eta()); - mcTruthRegistry.fill(HIST("hMcGenKpPt"), part.pt()); - } + // filling the histograms for generated D0 and D0bar mesons if (pdgCode == o2::constants::physics::Pdg::kD0) { if (std::abs(hfFlagMcGen) == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { mcTruthRegistry.fill(HIST("hMcGenD0"), part.pt(), part.eta()); @@ -1616,12 +1612,45 @@ struct FemtoUniversePairTaskTrackD0 { if (static_cast(part.mAntiLambda()) == genPromptD0) { mcTruthRegistry.fill(HIST("hMcGenD0Prompt"), part.pt(), part.eta()); mcTruthRegistry.fill(HIST("hMcGenD0PromptPt"), part.pt()); + mcTruthRegistry.fill(HIST("hMcGenD0PromptPtLessBins"), part.pt()); } else if (static_cast(part.mAntiLambda()) == genNonPromptD0) { mcTruthRegistry.fill(HIST("hMcGenD0NonPrompt"), part.pt(), part.eta()); mcTruthRegistry.fill(HIST("hMcGenD0NonPromptPt"), part.pt()); + mcTruthRegistry.fill(HIST("hMcGenD0NonPromptPtLessBins"), part.pt()); } } } + if (pdgCode == o2::constants::physics::Pdg::kD0Bar) { + if (std::abs(hfFlagMcGen) == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { + mcTruthRegistry.fill(HIST("hMcGenD0bar"), part.pt(), part.eta()); + mcTruthRegistry.fill(HIST("hMcGenD0barPt"), part.pt()); + if (static_cast(part.mAntiLambda()) == genPromptD0) { + mcTruthRegistry.fill(HIST("hMcGenD0barPrompt"), part.pt(), part.eta()); + mcTruthRegistry.fill(HIST("hMcGenD0barPromptPt"), part.pt()); + mcTruthRegistry.fill(HIST("hMcGenD0barPromptPtLessBins"), part.pt()); + } else if (static_cast(part.mAntiLambda()) == genNonPromptD0) { + mcTruthRegistry.fill(HIST("hMcGenD0barNonPrompt"), part.pt(), part.eta()); + mcTruthRegistry.fill(HIST("hMcGenD0barNonPromptPt"), part.pt()); + mcTruthRegistry.fill(HIST("hMcGenD0barNonPromptPtLessBins"), part.pt()); + } + } + } + // filling the histograms for identified hadrons + if (part.pt() < ConfTrack.confTrackLowPtCut || part.pt() > ConfTrack.confTrackHighPtCut || std::abs(part.eta()) > ConfTrack.confTrackEtaMax) { + continue; + } + if (pdgParticle->Charge() > 0.0) { + mcTruthRegistry.fill(HIST("hMcGenAllPositivePt"), part.pt()); + } + if (pdgCode == PDG_t::kPiPlus) { + mcTruthRegistry.fill(HIST("hMcGenPipPtVsEta"), part.pt(), part.eta()); + mcTruthRegistry.fill(HIST("hMcGenPipPt"), part.pt()); + } + if (pdgCode == PDG_t::kKPlus) { + mcTruthRegistry.fill(HIST("hMcGenKpPtVsEta"), part.pt(), part.eta()); + mcTruthRegistry.fill(HIST("hMcGenKpPt"), part.pt()); + } + if (pdgCode == PDG_t::kProton) { mcTruthRegistry.fill(HIST("hMcGenPrPtVsEta"), part.pt(), part.eta()); mcTruthRegistry.fill(HIST("hMcGenPrPt"), part.pt()); @@ -1638,19 +1667,6 @@ struct FemtoUniversePairTaskTrackD0 { mcTruthRegistry.fill(HIST("hMcGenKmPtVsEta"), part.pt(), part.eta()); mcTruthRegistry.fill(HIST("hMcGenKmPt"), part.pt()); } - if (pdgCode == o2::constants::physics::Pdg::kD0Bar) { - if (std::abs(hfFlagMcGen) == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { - mcTruthRegistry.fill(HIST("hMcGenD0bar"), part.pt(), part.eta()); - mcTruthRegistry.fill(HIST("hMcGenD0barPt"), part.pt()); - if (static_cast(part.mAntiLambda()) == genPromptD0) { - mcTruthRegistry.fill(HIST("hMcGenD0barPrompt"), part.pt(), part.eta()); - mcTruthRegistry.fill(HIST("hMcGenD0barPromptPt"), part.pt()); - } else if (static_cast(part.mAntiLambda()) == genNonPromptD0) { - mcTruthRegistry.fill(HIST("hMcGenD0barNonPrompt"), part.pt(), part.eta()); - mcTruthRegistry.fill(HIST("hMcGenD0barNonPromptPt"), part.pt()); - } - } - } if (pdgCode == -PDG_t::kProton) { mcTruthRegistry.fill(HIST("hMcGenAntiPrPtVsEta"), part.pt(), part.eta()); mcTruthRegistry.fill(HIST("hMcGenAntiPrPt"), part.pt()); diff --git a/PWGCF/FemtoWorld/Tasks/femtoPairLambdaAntilambda.cxx b/PWGCF/FemtoWorld/Tasks/femtoPairLambdaAntilambda.cxx index 138573a1763..1257291a825 100644 --- a/PWGCF/FemtoWorld/Tasks/femtoPairLambdaAntilambda.cxx +++ b/PWGCF/FemtoWorld/Tasks/femtoPairLambdaAntilambda.cxx @@ -63,6 +63,8 @@ struct FemtoPairLambdaAntilambda { using FemtoLambdasWithLabel = o2::soa::Join; using FemtoK0shortsWithLabel = o2::soa::Join; + using FemtoMcParticlesWithLabel = o2::soa::Join; + o2::framework::SliceCache cache; // setup collisions @@ -194,14 +196,14 @@ struct FemtoPairLambdaAntilambda { if (processLambdaLambda) { lambdaHistSpec = v0histmanager::makeV0HistSpecMap(confLambdaBinning); pairV0V0HistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confMixing); - pairLambdaLambdaBuilder.init(&hRegistry, confCollisionBinning, confLambdaSelection, confLambdaSelection2, confLambdaCleaner, confLambdaCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); + pairLambdaLambdaBuilder.init(&hRegistry, confCollisionBinning, confLambdaSelection, confLambdaSelection2, confLambdaCleaner, confLambdaCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); } // setup for k0short if (doprocessK0shortK0shortSameEvent || doprocessK0shortK0shortMixedEvent) { k0shortHistSpec = v0histmanager::makeV0HistSpecMap(confK0shortBinning); pairV0V0HistSpec = pairhistmanager::makePairHistSpecMap(confPairBinning, confMixing); - pairK0shortK0shortBuilder.init(&hRegistry, confCollisionBinning, confK0shortSelection, confK0shortSelection, confK0shortCleaner, confK0shortCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); + pairK0shortK0shortBuilder.init(&hRegistry, confCollisionBinning, confK0shortSelection, confK0shortSelection, confK0shortCleaner, confK0shortCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); } } else { colHistSpec = colhistmanager::makeColMcHistSpecMap(confCollisionBinning); @@ -210,63 +212,63 @@ struct FemtoPairLambdaAntilambda { if (processLambdaLambda) { lambdaHistSpec = v0histmanager::makeV0McHistSpecMap(confLambdaBinning); pairV0V0HistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning, confMixing); - pairLambdaLambdaBuilder.init(&hRegistry, confCollisionBinning, confLambdaSelection, confLambdaSelection2, confLambdaCleaner, confLambdaCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); + pairLambdaLambdaBuilder.init(&hRegistry, confCollisionBinning, confLambdaSelection, confLambdaSelection2, confLambdaCleaner, confLambdaCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, lambdaHistSpec, lambdaHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); } // setup for k0short if (doprocessK0shortK0shortSameEvent || doprocessK0shortK0shortMixedEvent) { k0shortHistSpec = v0histmanager::makeV0McHistSpecMap(confK0shortBinning); pairV0V0HistSpec = pairhistmanager::makePairMcHistSpecMap(confPairBinning, confMixing); - pairK0shortK0shortBuilder.init(&hRegistry, confCollisionBinning, confK0shortSelection, confK0shortSelection, confK0shortCleaner, confK0shortCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); + pairK0shortK0shortBuilder.init(&hRegistry, confCollisionBinning, confK0shortSelection, confK0shortSelection, confK0shortCleaner, confK0shortCleaner, confCprPos, confCprNeg, confMixing, confPairBinning, confPairCuts, colHistSpec, k0shortHistSpec, k0shortHistSpec, posDauSpec, negDauSpec, pairV0V0HistSpec, cprHistSpecPos, cprHistSpecNeg); } } }; void processLambdaLambdaSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoLambdas const& lambdas) { - pairLambdaLambdaBuilder.processSameEvent(col, tracks, lambdas, lambdaPartition, lambdaPartition2, cache); + pairLambdaLambdaBuilder.processSameEvent(col, tracks, lambdas, lambdaPartition, lambdaPartition2, cache); } PROCESS_SWITCH(FemtoPairLambdaAntilambda, processLambdaLambdaSameEvent, "Enable processing same event processing for lambda-lambda", true); - void processLambdaLambdaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& lambdas, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processLambdaLambdaSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& lambdas, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairLambdaLambdaBuilder.processSameEvent(col, mcCols, tracks, lambdas, lambdaWithLabelPartition, lambdaWithLabelPartition2, mcParticles, mcMothers, mcPartonicMothers, cache); + pairLambdaLambdaBuilder.processSameEvent(col, mcCols, tracks, lambdas, lambdaWithLabelPartition, lambdaWithLabelPartition2, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoPairLambdaAntilambda, processLambdaLambdaSameEventMc, "Enable processing same event processing for lambda-lambda with mc information", false); void processLambdaLambdaMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoLambdas const& lambdas) { - pairLambdaLambdaBuilder.processMixedEvent(cols, tracks, lambdas, lambdaPartition, lambdaPartition2, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairLambdaLambdaBuilder.processMixedEvent(cols, tracks, lambdas, lambdaPartition, lambdaPartition2, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairLambdaAntilambda, processLambdaLambdaMixedEvent, "Enable processing mixed event processing for lambda-lambda", true); - void processLambdaLambdaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambdas*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processLambdaLambdaMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoLambdasWithLabel const& /*lambdas*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairLambdaLambdaBuilder.processMixedEvent(cols, mcCols, tracks, lambdaWithLabelPartition, lambdaWithLabelPartition2, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairLambdaLambdaBuilder.processMixedEvent(cols, mcCols, tracks, lambdaWithLabelPartition, lambdaWithLabelPartition2, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairLambdaAntilambda, processLambdaLambdaMixedEventMc, "Enable processing mixed event processing for lambda-lambda with mc information", false); void processK0shortK0shortSameEvent(FilteredFemtoCollision const& col, FemtoTracks const& tracks, FemtoK0shorts const& k0shorts) { - pairK0shortK0shortBuilder.processSameEvent(col, tracks, k0shorts, k0shortPartition, k0shortPartition, cache); + pairK0shortK0shortBuilder.processSameEvent(col, tracks, k0shorts, k0shortPartition, k0shortPartition, cache); } PROCESS_SWITCH(FemtoPairLambdaAntilambda, processK0shortK0shortSameEvent, "Enable processing same event processing for k0short-k0short", false); - void processK0shortK0shortSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& k0shorts, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processK0shortK0shortSameEventMc(FilteredFemtoCollisionWithLabel const& col, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& k0shorts, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairK0shortK0shortBuilder.processSameEvent(col, mcCols, tracks, k0shorts, k0shortWithLabelPartition, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); + pairK0shortK0shortBuilder.processSameEvent(col, mcCols, tracks, k0shorts, k0shortWithLabelPartition, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache); } PROCESS_SWITCH(FemtoPairLambdaAntilambda, processK0shortK0shortSameEventMc, "Enable processing same event processing for k0short-k0short with mc information", false); void processK0shortK0shortMixedEvent(FilteredFemtoCollisions const& cols, FemtoTracks const& tracks, FemtoK0shorts const& k0shorts) { - pairK0shortK0shortBuilder.processMixedEvent(cols, tracks, k0shorts, k0shortPartition, k0shortPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairK0shortK0shortBuilder.processMixedEvent(cols, tracks, k0shorts, k0shortPartition, k0shortPartition, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairLambdaAntilambda, processK0shortK0shortMixedEvent, "Enable processing mixed event processing for k0short-k0short", false); - void processK0shortK0shortMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& /*k0shorts*/, o2::aod::FMcParticles const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) + void processK0shortK0shortMixedEventMc(FilteredFemtoCollisionsWithLabel const& cols, o2::aod::FMcCols const& mcCols, FemtoTracksWithLabel const& tracks, FemtoK0shortsWithLabel const& /*k0shorts*/, FemtoMcParticlesWithLabel const& mcParticles, o2::aod::FMcMothers const& mcMothers, o2::aod::FMcPartMoths const& mcPartonicMothers) { - pairK0shortK0shortBuilder.processMixedEvent(cols, mcCols, tracks, k0shortWithLabelPartition, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); + pairK0shortK0shortBuilder.processMixedEvent(cols, mcCols, tracks, k0shortWithLabelPartition, k0shortWithLabelPartition, mcParticles, mcMothers, mcPartonicMothers, cache, mixBinsVtxMult, mixBinsVtxCent, mixBinsVtxMultCent); } PROCESS_SWITCH(FemtoPairLambdaAntilambda, processK0shortK0shortMixedEventMc, "Enable processing mixed event processing for k0short-k0short with mc information", false); }; diff --git a/PWGCF/Flow/TableProducer/zdcQVectors.cxx b/PWGCF/Flow/TableProducer/zdcQVectors.cxx index ea9339394f4..c646b410b5e 100644 --- a/PWGCF/Flow/TableProducer/zdcQVectors.cxx +++ b/PWGCF/Flow/TableProducer/zdcQVectors.cxx @@ -106,10 +106,10 @@ struct ZdcQVectors { Produces spTableZDC; struct : ConfigurableGroup { - Configurable cfgEvtUseRCTFlagChecker{"cfgEvtUseRCTFlagChecker", false, "Evt sel: use RCT flag checker"}; + Configurable cfgEvtUseRCTFlagChecker{"cfgEvtUseRCTFlagChecker", true, "Evt sel: use RCT flag checker"}; Configurable cfgEvtRCTFlagCheckerLabel{"cfgEvtRCTFlagCheckerLabel", "CBT_hadronPID", "Evt sel: RCT flag checker label (CBT, CBT_hadronPID)"}; // all Labels can be found in Common/CCDB/RCTSelectionFlags.h - Configurable cfgEvtRCTFlagCheckerZDCCheck{"cfgEvtRCTFlagCheckerZDCCheck", false, "Evt sel: RCT flag checker ZDC check"}; - Configurable cfgEvtRCTFlagCheckerLimitAcceptAsBad{"cfgEvtRCTFlagCheckerLimitAcceptAsBad", false, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; + Configurable cfgEvtRCTFlagCheckerZDCCheck{"cfgEvtRCTFlagCheckerZDCCheck", true, "Evt sel: RCT flag checker ZDC check"}; + Configurable cfgEvtRCTFlagCheckerLimitAcceptAsBad{"cfgEvtRCTFlagCheckerLimitAcceptAsBad", true, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; } rctFlags; RCTFlagsChecker rctChecker; @@ -271,17 +271,17 @@ struct ZdcQVectors { registry.add(Form("QA/before/hSPplaneC"), "hSPplaneC", kTH2D, {axisPsiC, axisCent10}); registry.add(Form("QA/before/hSPplaneFull"), "hSPplaneFull", kTH2D, {{100, -PI, PI}, axisCent10}); for (const auto& side : sides) { - registry.add(Form("QA/before/hZN%s_Qx_vs_Qy", side), Form("hZN%s_Qx_vs_Qy", side), kTH2F, {axisQ, axisQ}); + registry.add(Form("recentering/before/hZN%s_Qx_vs_Qy", side), Form("hZN%s_Qx_vs_Qy", side), kTH2F, {axisQ, axisQ}); } for (const auto& COORD1 : capCOORDS) { for (const auto& COORD2 : capCOORDS) { // Now we get: & vs. Centrality - registry.add(Form("QA/before/hQ%sA_Q%sC_vs_cent", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_cent", COORD1, COORD2), kTProfile, {axisCent}); - registry.add(Form("QA/before/hQ%sA_Q%sC_vs_vx", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_vx", COORD1, COORD2), kTProfile, {axisVx}); - registry.add(Form("QA/before/hQ%sA_Q%sC_vs_vy", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_vy", COORD1, COORD2), kTProfile, {axisVy}); - registry.add(Form("QA/before/hQ%sA_Q%sC_vs_vz", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_vz", COORD1, COORD2), kTProfile, {axisVz}); - registry.add(Form("QA/before/hQ%sA_Q%sC_vs_timestamp", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_timestamp", COORD1, COORD2), kTProfile, {axisTimestamp}); + registry.add(Form("recentering/before/hQ%sA_Q%sC_vs_cent", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_cent", COORD1, COORD2), kTProfile, {axisCent}); + registry.add(Form("recentering/before/hQ%sA_Q%sC_vs_vx", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_vx", COORD1, COORD2), kTProfile, {axisVx}); + registry.add(Form("recentering/before/hQ%sA_Q%sC_vs_vy", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_vy", COORD1, COORD2), kTProfile, {axisVy}); + registry.add(Form("recentering/before/hQ%sA_Q%sC_vs_vz", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_vz", COORD1, COORD2), kTProfile, {axisVz}); + registry.add(Form("recentering/before/hQ%sA_Q%sC_vs_timestamp", COORD1, COORD2), Form("hQ%sA_Q%sC_vs_timestamp", COORD1, COORD2), kTProfile, {axisTimestamp}); } } @@ -289,15 +289,20 @@ struct ZdcQVectors { // Sides is {A,C} and capcoords is {X,Y} for (const auto& side : sides) { for (const auto& coord : capCOORDS) { - registry.add(Form("QA/before/hQ%s%s_vs_cent", coord, side), Form("hQ%s%s_vs_cent", coord, side), {HistType::kTProfile, {axisCent10}}); - registry.add(Form("QA/before/hQ%s%s_vs_vx", coord, side), Form("hQ%s%s_vs_vx", coord, side), {HistType::kTProfile, {axisVx}}); - registry.add(Form("QA/before/hQ%s%s_vs_vy", coord, side), Form("hQ%s%s_vs_vy", coord, side), {HistType::kTProfile, {axisVy}}); - registry.add(Form("QA/before/hQ%s%s_vs_vz", coord, side), Form("hQ%s%s_vs_vz", coord, side), {HistType::kTProfile, {axisVz}}); - registry.add(Form("QA/before/hQ%s%s_vs_timestamp", coord, side), Form("hQ%s%s_vs_timestamp", coord, side), {HistType::kTProfile, {axisTimestamp}}); - registry.add(Form("QA/Q%s%s_vs_iteration", coord, side), Form("hQ%s%s_vs_iteration", coord, side), {HistType::kTH2D, {{25, 0, 25}, axisQ}}); + registry.add(Form("recentering/before/hQ%s%s_vs_cent", coord, side), Form("hQ%s%s_vs_cent", coord, side), {HistType::kTProfile, {axisCent10}}); + registry.add(Form("recentering/before/hQ%s%s_vs_vx", coord, side), Form("hQ%s%s_vs_vx", coord, side), {HistType::kTProfile, {axisVx}}); + registry.add(Form("recentering/before/hQ%s%s_vs_vy", coord, side), Form("hQ%s%s_vs_vy", coord, side), {HistType::kTProfile, {axisVy}}); + registry.add(Form("recentering/before/hQ%s%s_vs_vz", coord, side), Form("hQ%s%s_vs_vz", coord, side), {HistType::kTProfile, {axisVz}}); + registry.add(Form("recentering/before/hQ%s%s_vs_timestamp", coord, side), Form("hQ%s%s_vs_timestamp", coord, side), {HistType::kTProfile, {axisTimestamp}}); + registry.add(Form("recentering/Q%s%s_vs_iteration", coord, side), Form("hQ%s%s_vs_iteration", coord, side), {HistType::kTH2D, {{35, 0, 35}, axisQ}}); } // end of capCOORDS } // end of sides + registry.add("recentering/before/ZNA_Qx_vs_Centrality", "ZNA_Qx_vs_Centrality", kTH2D, {{100, 0, 100}, {200, -2, 2}}); + registry.add("recentering/before/ZNA_Qy_vs_Centrality", "ZNA_Qy_vs_Centrality", kTH2D, {{100, 0, 100}, {200, -2, 2}}); + registry.add("recentering/before/ZNC_Qx_vs_Centrality", "ZNC_Qx_vs_Centrality", kTH2D, {{100, 0, 100}, {200, -2, 2}}); + registry.add("recentering/before/ZNC_Qy_vs_Centrality", "ZNC_Qy_vs_Centrality", kTH2D, {{100, 0, 100}, {200, -2, 2}}); + registry.add("QA/centrality_before", "centrality_before", kTH1D, {{100, 0, 100}}); registry.add("QA/centrality_after", "centrality_after", kTH1D, {{100, 0, 100}}); @@ -315,48 +320,36 @@ struct ZdcQVectors { registry.add("QA/shift/DeltaPsiZDCC", "DeltaPsiZDCC", kTH2D, {axisPsiCShifted, axisPsiC}); registry.add("QA/shift/DeltaPsiZDCAC", "DeltaPsiZDCAC", kTH2D, {axisPsiA, axisPsiC}); - registry.add("QA/before/ZNA_pmC", "ZNA_pmC", kTProfile, {{1, 0, 1.}}); - registry.add("QA/before/ZNA_pm1", "ZNA_pm1", kTProfile, {{1, 0, 1.}}); - registry.add("QA/before/ZNA_pm2", "ZNA_pm2", kTProfile, {{1, 0, 1.}}); - registry.add("QA/before/ZNA_pm3", "ZNA_pm3", kTProfile, {{1, 0, 1.}}); - registry.add("QA/before/ZNA_pm4", "ZNA_pm4", kTProfile, {{1, 0, 1.}}); + registry.add("QA/ZNA_pmC", "ZNA_pmC", kTProfile, {{1, 0, 1.}}); + registry.add("QA/ZNA_pm1", "ZNA_pm1", kTProfile, {{1, 0, 1.}}); + registry.add("QA/ZNA_pm2", "ZNA_pm2", kTProfile, {{1, 0, 1.}}); + registry.add("QA/ZNA_pm3", "ZNA_pm3", kTProfile, {{1, 0, 1.}}); + registry.add("QA/ZNA_pm4", "ZNA_pm4", kTProfile, {{1, 0, 1.}}); - registry.add("QA/before/ZNC_pmC", "ZNC_pmC", kTProfile, {{1, 0, 1.}}); - registry.add("QA/before/ZNC_pm1", "ZNC_pm1", kTProfile, {{1, 0, 1.}}); - registry.add("QA/before/ZNC_pm2", "ZNC_pm2", kTProfile, {{1, 0, 1.}}); - registry.add("QA/before/ZNC_pm3", "ZNC_pm3", kTProfile, {{1, 0, 1.}}); - registry.add("QA/before/ZNC_pm4", "ZNC_pm4", kTProfile, {{1, 0, 1.}}); + registry.add("QA/ZNC_pmC", "ZNC_pmC", kTProfile, {{1, 0, 1.}}); + registry.add("QA/ZNC_pm1", "ZNC_pm1", kTProfile, {{1, 0, 1.}}); + registry.add("QA/ZNC_pm2", "ZNC_pm2", kTProfile, {{1, 0, 1.}}); + registry.add("QA/ZNC_pm3", "ZNC_pm3", kTProfile, {{1, 0, 1.}}); + registry.add("QA/ZNC_pm4", "ZNC_pm4", kTProfile, {{1, 0, 1.}}); registry.add("QA/before/ZNA_Qx", "ZNA_Qx", kTProfile, {{1, 0, 1.}}); registry.add("QA/before/ZNA_Qy", "ZNA_Qy", kTProfile, {{1, 0, 1.}}); registry.add("QA/before/ZNC_Qx", "ZNC_Qx", kTProfile, {{1, 0, 1.}}); registry.add("QA/before/ZNC_Qy", "ZNC_Qy", kTProfile, {{1, 0, 1.}}); - registry.add("QA/before/ZNA_Qx_vs_Centrality", "ZNA_Qx_vs_Centrality", kTH2D, {{100, 0, 100}, {200, -2, 2}}); - registry.add("QA/before/ZNA_Qy_vs_Centrality", "ZNA_Qy_vs_Centrality", kTH2D, {{100, 0, 100}, {200, -2, 2}}); - registry.add("QA/before/ZNC_Qx_vs_Centrality", "ZNC_Qx_vs_Centrality", kTH2D, {{100, 0, 100}, {200, -2, 2}}); - registry.add("QA/before/ZNC_Qy_vs_Centrality", "ZNC_Qy_vs_Centrality", kTH2D, {{100, 0, 100}, {200, -2, 2}}); - - registry.add("QA/before/ZNA_pmC_vs_Centrality", "ZNA_pmC_vs_Centrality", kTH2D, {{100, 0, 100}, {300, 0, 300}}); - registry.add("QA/before/ZNA_pmSUM_vs_Centrality", "ZNA_pmSUM_vs_Centrality", kTH2D, {{100, 0, 100}, {300, 0, 300}}); - registry.add("QA/before/ZNA_pm1_vs_Centrality", "ZNA_pm1_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); - registry.add("QA/before/ZNA_pm2_vs_Centrality", "ZNA_pm2_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); - registry.add("QA/before/ZNA_pm3_vs_Centrality", "ZNA_pm3_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); - registry.add("QA/before/ZNA_pm4_vs_Centrality", "ZNA_pm4_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); - - registry.add("QA/before/ZNC_pmC_vs_Centrality", "ZNC_pmC_vs_Centrality", kTH2D, {{100, 0, 100}, {300, 0, 300}}); - registry.add("QA/before/ZNC_pmSUM_vs_Centrality", "ZNC_pmSUM_vs_Centrality", kTH2D, {{100, 0, 100}, {300, 0, 300}}); - registry.add("QA/before/ZNC_pm1_vs_Centrality", "ZNC_pm1_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); - registry.add("QA/before/ZNC_pm2_vs_Centrality", "ZNC_pm2_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); - registry.add("QA/before/ZNC_pm3_vs_Centrality", "ZNC_pm3_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); - registry.add("QA/before/ZNC_pm4_vs_Centrality", "ZNC_pm4_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); - - registry.addClone("QA/before/", "QA/after/"); - - registry.add("QA/before/ZNA_Qx_noEq", "ZNA_Qx_noEq", kTProfile, {{1, 0, 1.}}); - registry.add("QA/before/ZNA_Qy_noEq", "ZNA_Qy_noEq", kTProfile, {{1, 0, 1.}}); - registry.add("QA/before/ZNC_Qx_noEq", "ZNC_Qx_noEq", kTProfile, {{1, 0, 1.}}); - registry.add("QA/before/ZNC_Qy_noEq", "ZNC_Qy_noEq", kTProfile, {{1, 0, 1.}}); + registry.add("QA/ZNA_pmC_vs_Centrality", "ZNA_pmC_vs_Centrality", kTH2D, {{100, 0, 100}, {300, 0, 300}}); + registry.add("QA/ZNA_pmSUM_vs_Centrality", "ZNA_pmSUM_vs_Centrality", kTH2D, {{100, 0, 100}, {300, 0, 300}}); + registry.add("QA/ZNA_pm1_vs_Centrality", "ZNA_pm1_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); + registry.add("QA/ZNA_pm2_vs_Centrality", "ZNA_pm2_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); + registry.add("QA/ZNA_pm3_vs_Centrality", "ZNA_pm3_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); + registry.add("QA/ZNA_pm4_vs_Centrality", "ZNA_pm4_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); + + registry.add("QA/ZNC_pmC_vs_Centrality", "ZNC_pmC_vs_Centrality", kTH2D, {{100, 0, 100}, {300, 0, 300}}); + registry.add("QA/ZNC_pmSUM_vs_Centrality", "ZNC_pmSUM_vs_Centrality", kTH2D, {{100, 0, 100}, {300, 0, 300}}); + registry.add("QA/ZNC_pm1_vs_Centrality", "ZNC_pm1_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); + registry.add("QA/ZNC_pm2_vs_Centrality", "ZNC_pm2_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); + registry.add("QA/ZNC_pm3_vs_Centrality", "ZNC_pm3_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); + registry.add("QA/ZNC_pm4_vs_Centrality", "ZNC_pm4_vs_Centrality", kTH2D, {{100, 0, 100}, {100, 0, 1}}); } // Tower mean energies vs. centrality used for tower gain equalisation @@ -384,6 +377,8 @@ struct ZdcQVectors { registry.add("CutAnalysis/hvertex_vy", "hvertex_vy", kTProfile2D, {{1, 0., 1.}, {nEventSelections + 5, 0, nEventSelections + 5}}); registry.add("CutAnalysis/hvertex_vz", "hvertex_vz", kTProfile2D, {{1, 0., 1.}, {nEventSelections + 5, 0, nEventSelections + 5}}); } + registry.addClone("recentering/before/", "recentering/after/"); + registry.addClone("QA/before/", "QA/after/"); } } @@ -540,63 +535,63 @@ struct ZdcQVectors { return; static constexpr std::string_view Time[] = {"before", "after"}; - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hZNA_Qx_vs_Qy"), qxa, qya); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hZNC_Qx_vs_Qy"), qxc, qyc); - - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QXC_vs_cent"), centrality, qxa * qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QYC_vs_cent"), centrality, qya * qyc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QXC_vs_cent"), centrality, qya * qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QYC_vs_cent"), centrality, qxa * qyc); - - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_vs_cent"), centrality, qxa); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_vs_cent"), centrality, qya); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXC_vs_cent"), centrality, qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYC_vs_cent"), centrality, qyc); - - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_vs_vx"), v[0], qxa); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_vs_vx"), v[0], qya); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXC_vs_vx"), v[0], qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYC_vs_vx"), v[0], qyc); - - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QXC_vs_vx"), v[0], qxa * qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QYC_vs_vx"), v[0], qya * qyc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QXC_vs_vx"), v[0], qya * qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QYC_vs_vx"), v[0], qxa * qyc); - - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_vs_vy"), v[1], qxa); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_vs_vy"), v[1], qya); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXC_vs_vy"), v[1], qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYC_vs_vy"), v[1], qyc); - - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QXC_vs_vy"), v[1], qxa * qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QYC_vs_vy"), v[1], qya * qyc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QXC_vs_vy"), v[1], qya * qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QYC_vs_vy"), v[1], qxa * qyc); - - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_vs_vz"), v[2], qxa); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_vs_vz"), v[2], qya); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXC_vs_vz"), v[2], qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYC_vs_vz"), v[2], qyc); - - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QXC_vs_vz"), v[2], qxa * qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QYC_vs_vz"), v[2], qya * qyc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QXC_vs_vz"), v[2], qya * qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QYC_vs_vz"), v[2], qxa * qyc); - - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_vs_timestamp"), rsTimestamp, qxa); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_vs_timestamp"), rsTimestamp, qya); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXC_vs_timestamp"), rsTimestamp, qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYC_vs_timestamp"), rsTimestamp, qyc); - - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QXC_vs_timestamp"), rsTimestamp, qxa * qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QYC_vs_timestamp"), rsTimestamp, qya * qyc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQYA_QXC_vs_timestamp"), rsTimestamp, qya * qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/hQXA_QYC_vs_timestamp"), rsTimestamp, qxa * qyc); - - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/ZNA_Qx_vs_Centrality"), centrality, qxa); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/ZNA_Qy_vs_Centrality"), centrality, qya); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/ZNC_Qx_vs_Centrality"), centrality, qxc); - registry.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/ZNC_Qy_vs_Centrality"), centrality, qyc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hZNA_Qx_vs_Qy"), qxa, qya); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hZNC_Qx_vs_Qy"), qxc, qyc); + + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_QXC_vs_cent"), centrality, qxa * qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_QYC_vs_cent"), centrality, qya * qyc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_QXC_vs_cent"), centrality, qya * qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_QYC_vs_cent"), centrality, qxa * qyc); + + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_vs_cent"), centrality, qxa); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_vs_cent"), centrality, qya); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXC_vs_cent"), centrality, qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYC_vs_cent"), centrality, qyc); + + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_vs_vx"), v[0], qxa); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_vs_vx"), v[0], qya); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXC_vs_vx"), v[0], qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYC_vs_vx"), v[0], qyc); + + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_QXC_vs_vx"), v[0], qxa * qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_QYC_vs_vx"), v[0], qya * qyc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_QXC_vs_vx"), v[0], qya * qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_QYC_vs_vx"), v[0], qxa * qyc); + + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_vs_vy"), v[1], qxa); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_vs_vy"), v[1], qya); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXC_vs_vy"), v[1], qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYC_vs_vy"), v[1], qyc); + + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_QXC_vs_vy"), v[1], qxa * qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_QYC_vs_vy"), v[1], qya * qyc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_QXC_vs_vy"), v[1], qya * qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_QYC_vs_vy"), v[1], qxa * qyc); + + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_vs_vz"), v[2], qxa); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_vs_vz"), v[2], qya); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXC_vs_vz"), v[2], qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYC_vs_vz"), v[2], qyc); + + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_QXC_vs_vz"), v[2], qxa * qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_QYC_vs_vz"), v[2], qya * qyc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_QXC_vs_vz"), v[2], qya * qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_QYC_vs_vz"), v[2], qxa * qyc); + + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_vs_timestamp"), rsTimestamp, qxa); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_vs_timestamp"), rsTimestamp, qya); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXC_vs_timestamp"), rsTimestamp, qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYC_vs_timestamp"), rsTimestamp, qyc); + + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_QXC_vs_timestamp"), rsTimestamp, qxa * qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_QYC_vs_timestamp"), rsTimestamp, qya * qyc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQYA_QXC_vs_timestamp"), rsTimestamp, qya * qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/hQXA_QYC_vs_timestamp"), rsTimestamp, qxa * qyc); + + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/ZNA_Qx_vs_Centrality"), centrality, qxa); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/ZNA_Qy_vs_Centrality"), centrality, qya); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/ZNC_Qx_vs_Centrality"), centrality, qxc); + registry.fill(HIST("recentering/") + HIST(Time[ft]) + HIST("/ZNC_Qy_vs_Centrality"), centrality, qyc); // add psi!! double psiA = 1.0 * std::atan2(qxc, qxa); @@ -759,8 +754,9 @@ struct ZdcQVectors { const auto& foundBC = collision.foundBC_as(); runnumber = foundBC.runNumber(); - if (cfgFillHistRegistry && !cfgFillNothing) + if (cfgFillHistRegistry && !cfgFillNothing) { registry.fill(HIST("QA/centrality_before"), cent); + } registry.fill(HIST("hEventCount"), evSel_FilteredEvent); @@ -844,13 +840,8 @@ struct ZdcQVectors { } // load the calibration histos for iteration 0 step 0 (Energy Calibration) - loadCalibrations(cfgEnergyCal.value); - - if (!cal.calibfilesLoaded[0]) { - if (counter < 1) { - LOGF(info, " --> No Energy calibration files found.. -> Only Energy calibration will be done. "); - } - } + if (!cfgNoGain) + loadCalibrations(cfgEnergyCal.value); // load the calibrations for the mean v loadCalibrations(cfgMeanv.value); @@ -876,19 +867,12 @@ struct ZdcQVectors { } } - // Do not continue if Energy calibration is not loaded - if (!cal.calibfilesLoaded[0]) { - counter++; - isSelected = false; - spTableZDC(runnumber, cents, v, foundBC.timestamp(), 0, 0, 0, 0, isSelected, eventSelectionFlags); - lastRunNumber = runnumber; - return; - } - // Now start gain equalisation! // Fill the list with calibration constants. - for (int tower = 0; tower < (nTowers + 2); tower++) { - meanEZN[tower] = getCorrection(namesEcal[tower].Data()); + if (!cfgNoGain) { + for (int tower = 0; tower < (nTowers + 2); tower++) { + meanEZN[tower] = getCorrection(namesEcal[tower].Data()); + } } // Use the calibration constants but now only loop over towers 1-4 @@ -896,9 +880,13 @@ struct ZdcQVectors { std::vector towersNocom = {1, 2, 3, 4, 6, 7, 8, 9}; for (const auto& tower : towersNocom) { - if (meanEZN[tower] > 0) { - double ecommon = (tower > nTowersPerSide) ? meanEZN[5] : meanEZN[0]; - e[calibtower] = eZN[calibtower] * (0.25 * ecommon) / meanEZN[tower]; + if (cfgNoGain) { + e[calibtower] = eZN[calibtower]; + } else { + if (meanEZN[tower] > 0) { + double ecommon = (tower > nTowersPerSide) ? meanEZN[5] : meanEZN[0]; + e[calibtower] = eZN[calibtower] * (0.25 * ecommon) / meanEZN[tower]; + } } calibtower++; } @@ -911,60 +899,35 @@ struct ZdcQVectors { registry.fill(HIST("QA/ZNC_Energy"), bincenter, eZN[i + 4]); registry.fill(HIST("QA/ZNC_Energy"), bincenter + 4, e[i + 4]); - registry.get(HIST("QA/before/ZNA_pmC"))->Fill(Form("%d", runnumber), meanEZN[0]); - registry.get(HIST("QA/before/ZNA_pm1"))->Fill(Form("%d", runnumber), eZN[0]); - registry.get(HIST("QA/before/ZNA_pm2"))->Fill(Form("%d", runnumber), eZN[1]); - registry.get(HIST("QA/before/ZNA_pm3"))->Fill(Form("%d", runnumber), eZN[2]); - registry.get(HIST("QA/before/ZNA_pm4"))->Fill(Form("%d", runnumber), eZN[3]); - - registry.get(HIST("QA/before/ZNC_pmC"))->Fill(Form("%d", runnumber), meanEZN[5]); - registry.get(HIST("QA/before/ZNC_pm1"))->Fill(Form("%d", runnumber), eZN[4]); - registry.get(HIST("QA/before/ZNC_pm2"))->Fill(Form("%d", runnumber), eZN[5]); - registry.get(HIST("QA/before/ZNC_pm3"))->Fill(Form("%d", runnumber), eZN[6]); - registry.get(HIST("QA/before/ZNC_pm4"))->Fill(Form("%d", runnumber), eZN[7]); - - registry.get(HIST("QA/after/ZNA_pm1"))->Fill(Form("%d", runnumber), e[0]); - registry.get(HIST("QA/after/ZNA_pm2"))->Fill(Form("%d", runnumber), e[1]); - registry.get(HIST("QA/after/ZNA_pm3"))->Fill(Form("%d", runnumber), e[2]); - registry.get(HIST("QA/after/ZNA_pm4"))->Fill(Form("%d", runnumber), e[3]); - registry.get(HIST("QA/after/ZNC_pm1"))->Fill(Form("%d", runnumber), e[4]); - registry.get(HIST("QA/after/ZNC_pm2"))->Fill(Form("%d", runnumber), e[5]); - registry.get(HIST("QA/after/ZNC_pm3"))->Fill(Form("%d", runnumber), e[6]); - registry.get(HIST("QA/after/ZNC_pm4"))->Fill(Form("%d", runnumber), e[7]); - - double sumZNAbefore = eZN[0] + eZN[1] + eZN[2] + eZN[3]; - double sumZNAafter = e[0] + e[1] + e[2] + e[3]; - - double sumZNCbefore = eZN[4] + eZN[5] + eZN[6] + eZN[7]; - double sumZNCafter = e[4] + e[5] + e[6] + e[7]; - - registry.fill(HIST("QA/") + HIST("before") + HIST("/ZNA_pmC_vs_Centrality"), centrality, zdcCol.energyCommonZNA()); - registry.fill(HIST("QA/") + HIST("before") + HIST("/ZNA_pmSUM_vs_Centrality"), centrality, sumZNAbefore); - registry.fill(HIST("QA/") + HIST("before") + HIST("/ZNA_pm1_vs_Centrality"), centrality, eZN[0] / sumZNAbefore); - registry.fill(HIST("QA/") + HIST("before") + HIST("/ZNA_pm2_vs_Centrality"), centrality, eZN[1] / sumZNAbefore); - registry.fill(HIST("QA/") + HIST("before") + HIST("/ZNA_pm3_vs_Centrality"), centrality, eZN[2] / sumZNAbefore); - registry.fill(HIST("QA/") + HIST("before") + HIST("/ZNA_pm4_vs_Centrality"), centrality, eZN[3] / sumZNAbefore); - - registry.fill(HIST("QA/") + HIST("before") + HIST("/ZNC_pmC_vs_Centrality"), centrality, zdcCol.energyCommonZNC()); - registry.fill(HIST("QA/") + HIST("before") + HIST("/ZNC_pmSUM_vs_Centrality"), centrality, sumZNCbefore); - registry.fill(HIST("QA/") + HIST("before") + HIST("/ZNC_pm1_vs_Centrality"), centrality, eZN[4] / sumZNCbefore); - registry.fill(HIST("QA/") + HIST("before") + HIST("/ZNC_pm2_vs_Centrality"), centrality, eZN[5] / sumZNCbefore); - registry.fill(HIST("QA/") + HIST("before") + HIST("/ZNC_pm3_vs_Centrality"), centrality, eZN[6] / sumZNCbefore); - registry.fill(HIST("QA/") + HIST("before") + HIST("/ZNC_pm4_vs_Centrality"), centrality, eZN[7] / sumZNCbefore); - - registry.fill(HIST("QA/") + HIST("after") + HIST("/ZNA_pmC_vs_Centrality"), centrality, zdcCol.energyCommonZNA()); - registry.fill(HIST("QA/") + HIST("after") + HIST("/ZNA_pmSUM_vs_Centrality"), centrality, sumZNAafter); - registry.fill(HIST("QA/") + HIST("after") + HIST("/ZNA_pm1_vs_Centrality"), centrality, e[0] / sumZNAafter); - registry.fill(HIST("QA/") + HIST("after") + HIST("/ZNA_pm2_vs_Centrality"), centrality, e[1] / sumZNAafter); - registry.fill(HIST("QA/") + HIST("after") + HIST("/ZNA_pm3_vs_Centrality"), centrality, e[2] / sumZNAafter); - registry.fill(HIST("QA/") + HIST("after") + HIST("/ZNA_pm4_vs_Centrality"), centrality, e[3] / sumZNAafter); - - registry.fill(HIST("QA/") + HIST("after") + HIST("/ZNC_pmC_vs_Centrality"), centrality, zdcCol.energyCommonZNC()); - registry.fill(HIST("QA/") + HIST("after") + HIST("/ZNC_pmSUM_vs_Centrality"), centrality, sumZNCafter); - registry.fill(HIST("QA/") + HIST("after") + HIST("/ZNC_pm1_vs_Centrality"), centrality, e[4] / sumZNCafter); - registry.fill(HIST("QA/") + HIST("after") + HIST("/ZNC_pm2_vs_Centrality"), centrality, e[5] / sumZNCafter); - registry.fill(HIST("QA/") + HIST("after") + HIST("/ZNC_pm3_vs_Centrality"), centrality, e[6] / sumZNCafter); - registry.fill(HIST("QA/") + HIST("after") + HIST("/ZNC_pm4_vs_Centrality"), centrality, e[7] / sumZNCafter); + registry.get(HIST("QA/ZNA_pmC"))->Fill(Form("%d", runnumber), zdcCol.energyCommonZNA()); + registry.get(HIST("QA/ZNC_pmC"))->Fill(Form("%d", runnumber), zdcCol.energyCommonZNC()); + registry.get(HIST("QA/ZNA_pm1"))->Fill(Form("%d", runnumber), e[0]); + registry.get(HIST("QA/ZNA_pm2"))->Fill(Form("%d", runnumber), e[1]); + registry.get(HIST("QA/ZNA_pm3"))->Fill(Form("%d", runnumber), e[2]); + registry.get(HIST("QA/ZNA_pm4"))->Fill(Form("%d", runnumber), e[3]); + registry.get(HIST("QA/ZNC_pm1"))->Fill(Form("%d", runnumber), e[4]); + registry.get(HIST("QA/ZNC_pm2"))->Fill(Form("%d", runnumber), e[5]); + registry.get(HIST("QA/ZNC_pm3"))->Fill(Form("%d", runnumber), e[6]); + registry.get(HIST("QA/ZNC_pm4"))->Fill(Form("%d", runnumber), e[7]); + + double sumZNA = e[0] + e[1] + e[2] + e[3]; + double sumZNC = e[4] + e[5] + e[6] + e[7]; + + registry.fill(HIST("QA/ZNA_pmC_vs_Centrality"), centrality, zdcCol.energyCommonZNA()); + registry.fill(HIST("QA/ZNA_pmSUM_vs_Centrality"), centrality, sumZNA); + + registry.fill(HIST("QA/ZNC_pmC_vs_Centrality"), centrality, zdcCol.energyCommonZNC()); + registry.fill(HIST("QA/ZNC_pmSUM_vs_Centrality"), centrality, sumZNC); + + registry.fill(HIST("QA/ZNA_pm1_vs_Centrality"), centrality, e[0] / sumZNA); + registry.fill(HIST("QA/ZNA_pm2_vs_Centrality"), centrality, e[1] / sumZNA); + registry.fill(HIST("QA/ZNA_pm3_vs_Centrality"), centrality, e[2] / sumZNA); + registry.fill(HIST("QA/ZNA_pm4_vs_Centrality"), centrality, e[3] / sumZNA); + + registry.fill(HIST("QA/ZNC_pm1_vs_Centrality"), centrality, e[4] / sumZNC); + registry.fill(HIST("QA/ZNC_pm2_vs_Centrality"), centrality, e[5] / sumZNC); + registry.fill(HIST("QA/ZNC_pm3_vs_Centrality"), centrality, e[6] / sumZNC); + registry.fill(HIST("QA/ZNC_pm4_vs_Centrality"), centrality, e[7] / sumZNC); } } @@ -976,12 +939,6 @@ struct ZdcQVectors { sumZN[side] += energy; xEnZN[side] += (side == 0) ? -1.0 * pxZDC[sector] * energy : pxZDC[sector] * energy; yEnZN[side] += pyZDC[sector] * energy; - - // Also calculate the Q-vector for the non-equalized energy - double energyNoEq = std::pow(eZN[tower], alphaZDC); - sumZN_noEq[side] += energyNoEq; - xEnZN_noEq[side] += (side == 0) ? -1.0 * pxZDC[sector] * energyNoEq : pxZDC[sector] * energyNoEq; - yEnZN_noEq[side] += pyZDC[sector] * energyNoEq; } // "QXA", "QYA", "QXC", "QYC" @@ -991,10 +948,6 @@ struct ZdcQVectors { q[i * 2] = xEnZN[i] / sumZN[i]; // for QXA[0] and QXC[2] q[i * 2 + 1] = yEnZN[i] / sumZN[i]; // for QYA[1] and QYC[3] } - if (sumZN_noEq[i] > 0) { - qNoEq[i * 2] = xEnZN_noEq[i] / sumZN_noEq[i]; // for QXA[0] and QXC[2] - qNoEq[i * 2 + 1] = yEnZN_noEq[i] / sumZN_noEq[i]; // for QYA[1] and QYC[3] - } } if (cfgFillHistRegistry && !cfgFillNothing) { @@ -1002,15 +955,6 @@ struct ZdcQVectors { registry.get(HIST("QA/before/ZNA_Qy"))->Fill(Form("%d", runnumber), q[1]); registry.get(HIST("QA/before/ZNC_Qx"))->Fill(Form("%d", runnumber), q[2]); registry.get(HIST("QA/before/ZNC_Qy"))->Fill(Form("%d", runnumber), q[3]); - - registry.get(HIST("QA/before/ZNA_Qx_noEq"))->Fill(Form("%d", runnumber), qNoEq[0]); - registry.get(HIST("QA/before/ZNA_Qy_noEq"))->Fill(Form("%d", runnumber), qNoEq[1]); - registry.get(HIST("QA/before/ZNC_Qx_noEq"))->Fill(Form("%d", runnumber), qNoEq[2]); - registry.get(HIST("QA/before/ZNC_Qy_noEq"))->Fill(Form("%d", runnumber), qNoEq[3]); - } - - if (cfgNoGain) { - q = qNoEq; } if (cal.calibfilesLoaded[1]) { @@ -1057,6 +1001,13 @@ struct ZdcQVectors { corrQyA.push_back(getCorrection(names[0][1].Data(), it, 1)); corrQxC.push_back(getCorrection(names[0][2].Data(), it, 1)); corrQyC.push_back(getCorrection(names[0][3].Data(), it, 1)); + + if (cfgFillHistRegistry && !cfgFillNothing) { + registry.get(HIST("recentering/QXA_vs_iteration"))->Fill(pb + 1, q[0] - std::accumulate(corrQxA.begin(), corrQxA.end(), 0.0)); + registry.get(HIST("recentering/QYA_vs_iteration"))->Fill(pb + 1, q[1] - std::accumulate(corrQyA.begin(), corrQyA.end(), 0.0)); + registry.get(HIST("recentering/QXC_vs_iteration"))->Fill(pb + 1, q[2] - std::accumulate(corrQxC.begin(), corrQxC.end(), 0.0)); + registry.get(HIST("recentering/QYC_vs_iteration"))->Fill(pb + 1, q[3] - std::accumulate(corrQyC.begin(), corrQyC.end(), 0.0)); + } pb++; for (int step = 2; step <= nSteps; step++) { @@ -1064,6 +1015,14 @@ struct ZdcQVectors { corrQyA.push_back(getCorrection(names[step - 1][1].Data(), it, step)); corrQxC.push_back(getCorrection(names[step - 1][2].Data(), it, step)); corrQyC.push_back(getCorrection(names[step - 1][3].Data(), it, step)); + + if (cfgFillHistRegistry && !cfgFillNothing) { + registry.get(HIST("recentering/QXA_vs_iteration"))->Fill(pb + 1, q[0] - std::accumulate(corrQxA.begin(), corrQxA.end(), 0.0)); + registry.get(HIST("recentering/QYA_vs_iteration"))->Fill(pb + 1, q[1] - std::accumulate(corrQyA.begin(), corrQyA.end(), 0.0)); + registry.get(HIST("recentering/QXC_vs_iteration"))->Fill(pb + 1, q[2] - std::accumulate(corrQxC.begin(), corrQxC.end(), 0.0)); + registry.get(HIST("recentering/QYC_vs_iteration"))->Fill(pb + 1, q[3] - std::accumulate(corrQyC.begin(), corrQyC.end(), 0.0)); + } + pb++; } @@ -1072,6 +1031,13 @@ struct ZdcQVectors { corrQyA.push_back(getCorrection(namesTS[1].Data(), it, 6)); corrQxC.push_back(getCorrection(namesTS[2].Data(), it, 6)); corrQyC.push_back(getCorrection(namesTS[3].Data(), it, 6)); + + if (cfgFillHistRegistry && !cfgFillNothing) { + registry.get(HIST("recentering/QXA_vs_iteration"))->Fill(pb + 1, q[0] - std::accumulate(corrQxA.begin(), corrQxA.end(), 0.0)); + registry.get(HIST("recentering/QYA_vs_iteration"))->Fill(pb + 1, q[1] - std::accumulate(corrQyA.begin(), corrQyA.end(), 0.0)); + registry.get(HIST("recentering/QXC_vs_iteration"))->Fill(pb + 1, q[2] - std::accumulate(corrQxC.begin(), corrQxC.end(), 0.0)); + registry.get(HIST("recentering/QYC_vs_iteration"))->Fill(pb + 1, q[3] - std::accumulate(corrQyC.begin(), corrQyC.end(), 0.0)); + } pb++; } } @@ -1086,15 +1052,6 @@ struct ZdcQVectors { qRec[2] -= totalCorrectionQxC; qRec[3] -= totalCorrectionQyC; - if (cfgFillHistRegistry && !cfgFillNothing) { - for (int cor = 0; cor < pb; cor++) { - registry.get(HIST("QA/QXA_vs_iteration"))->Fill(cor, qRec[0]); - registry.get(HIST("QA/QYA_vs_iteration"))->Fill(cor, qRec[1]); - registry.get(HIST("QA/QXC_vs_iteration"))->Fill(cor, qRec[2]); - registry.get(HIST("QA/QYC_vs_iteration"))->Fill(cor, qRec[3]); - } - } - // do shift for psi. double psiZDCA = 1.0 * std::atan2(qRec[1], qRec[0]); double psiZDCC = 1.0 * std::atan2(qRec[3], qRec[2]); @@ -1181,7 +1138,7 @@ struct ZdcQVectors { double qYcShift = std::hypot(qRec[2], qRec[3]) * std::sin(psiZDCCshift); if (isSelected && cfgFillHistRegistry && !cfgFillNothing) { - fillCommonRegistry(qRec[0], qRec[1], qRec[2], qRec[3], v, centrality, rsTimestamp); + fillCommonRegistry(qXaShift, qYaShift, qXcShift, qYcShift, v, centrality, rsTimestamp); registry.fill(HIST("QA/centrality_after"), centrality); registry.get(HIST("QA/after/ZNA_Qx"))->Fill(Form("%d", runnumber), qXaShift); registry.get(HIST("QA/after/ZNA_Qy"))->Fill(Form("%d", runnumber), qYaShift); diff --git a/PWGCF/Flow/Tasks/flowDirectedFlowTask.cxx b/PWGCF/Flow/Tasks/flowDirectedFlowTask.cxx index 394002fd878..c91f1b567e9 100644 --- a/PWGCF/Flow/Tasks/flowDirectedFlowTask.cxx +++ b/PWGCF/Flow/Tasks/flowDirectedFlowTask.cxx @@ -279,6 +279,8 @@ struct flowDirectedFlowTask { q1 = q1C; } else if (cfgq1mode == 3) { q1 = q1Mean; + } else if (cfgq1mode == 4) { + q1 = std::sqrt(std::pow(qxA + qxC, 2) + std::pow(qyA + qyC, 2)); } else { q1 = q1Full; } diff --git a/PWGCF/Flow/Tasks/flowEseTask.cxx b/PWGCF/Flow/Tasks/flowEseTask.cxx index 5b091a8c200..fa9f997c49e 100644 --- a/PWGCF/Flow/Tasks/flowEseTask.cxx +++ b/PWGCF/Flow/Tasks/flowEseTask.cxx @@ -52,13 +52,11 @@ #include #include -#include #include #include #include #include #include -#include #include #include @@ -157,14 +155,17 @@ struct FlowEseTask { ConfigurableAxis rapAxis{"rapAxis", {10, -0.5, 0.5}, "Rapidity axis"}; ConfigurableAxis qqAxis{"qqAxis", {100, -0.1, 0.1}, "qq axis"}; ConfigurableAxis multAxis{"multAxis", {300, 0, 2700}, "multiplicity"}; - ConfigurableAxis qvecAxis{"qvecAxis", {600, 0, 600}, "range of Qvector Module"}; + ConfigurableAxis qvecAxisCent0010{"qvecAxisCent0010", {100, 0, 900}, "q2 axis for 0-10"}; + ConfigurableAxis qvecAxisCent1020{"qvecAxisCent1020", {100, 0, 600}, "q2 axis for 10-20"}; + ConfigurableAxis qvecAxisCent2030{"qvecAxisCent2030", {100, 0, 500}, "q2 axis for 20-30"}; + ConfigurableAxis qvecAxisCent3040{"qvecAxisCent3040", {100, 0, 400}, "q2 axis for 30-40"}; + ConfigurableAxis qvecAxisCent4050{"qvecAxisCent4050", {100, 0, 350}, "q2 axis for 40-50"}; + ConfigurableAxis qvecAxisCent5060{"qvecAxisCent5060", {100, 0, 300}, "q2 axis for 50-60"}; + ConfigurableAxis qvecAxisCent6070{"qvecAxisCent6070", {100, 0, 200}, "q2 axis for 60-70"}; + ConfigurableAxis qvecAxisCent7080{"qvecAxisCent7080", {100, 0, 200}, "q2 axis for 70-80"}; ConfigurableAxis lowerQAxis = {"lowerQAxis", {800, 0.0, 800.0}, "range of lowerQ QAplots"}; ConfigurableAxis upperQAxis = {"upperQAxis", {300, 0.0, 6.0}, "range of upperQ QAplots"}; - Configurable> cfgQ2SelBin{"cfgQ2SelBin", {0, 10, 20, 30, 40, 50, 60, 70, 80, 100}, "centrality bins for q2 selection"}; - Configurable> cfgQ2Low{"cfgQ2Low", {124.2131f, 109.1698f, 91.9999f, 73.8884f, 56.9597f, 42.3456f, 30.2032f, 20.3889f, 0.0000f}, ""}; - Configurable> cfgQ2High{"cfgQ2High", {202.9085f, 171.5700f, 142.6870f, 116.0087f, 91.4749f, 69.2724f, 49.8817f, 33.8359f, 0.0000f}, ""}; - static constexpr float MinAmplitudeThreshold = 1e-5f; static constexpr int ShiftLevel = 10; static constexpr int LambdaId = 3122; @@ -173,25 +174,30 @@ struct FlowEseTask { static constexpr std::array CentValues = {2.5f, 7.5f, 15.0f, 25.0f, 35.0f, 45.0f, 55.0f, 65.0f, 75.0f}; static constexpr float EtaAcceptance = 0.8f; static constexpr float CentUpperLimit = 80.0f; + static constexpr int NQ2CentBins = 8; + static constexpr float Q2CentMin = 0.0f; + static constexpr float Q2CentMax = 80.0f; + static constexpr float Q2CentBinWidth = 10.0f; EventPlaneHelper helperEP; TF1* fMultPVCutLow = nullptr; TF1* fMultPVCutHigh = nullptr; - int detId; - int refAId; - int refBId; + int detId = -1; + int refAId = -1; + int refBId = -1; - int qvecDetInd; - int qvecRefAInd; - int qvecRefBInd; + int qvecDetInd = -1; + int qvecRefAInd = -1; + int qvecRefBInd = -1; - float centrality; + float centrality = -1.0f; - double angle; - double psi; - double relphi; + double angle = 0.0; + double psi = 0.0; + double relphi = 0.0; + double productPhi = 0.0; int currentRunNumber = -999; int lastRunNumber = -999; @@ -223,42 +229,47 @@ struct FlowEseTask { } } - enum class Q2Group { - Low, - Mid, - High - }; - - bool q2sel(float q2, Q2Group q2Group) + int q2CentBin(float cent) const { - if (cfgQ2SelBin->empty() || cfgQ2Low->empty() || cfgQ2High->empty()) { - return false; + if (cent < Q2CentMin || cent >= Q2CentMax) { + return -1; } + return static_cast(cent / Q2CentBinWidth); + } - auto it = std::upper_bound(cfgQ2SelBin->begin(), cfgQ2SelBin->end(), centrality); - int idx = std::distance(cfgQ2SelBin->begin(), it) - 1; - if (idx < 0) { - idx = 0; - } - if (idx >= static_cast(cfgQ2Low->size())) { - idx = cfgQ2Low->size() - 1; - } - if (idx >= static_cast(cfgQ2High->size())) { - idx = cfgQ2High->size() - 1; + const char* q2CentSuffix(int centBin) const + { + static constexpr const char* Q2CentSuffixes[] = { + "cent00_10", "cent10_20", "cent20_30", "cent30_40", + "cent40_50", "cent50_60", "cent60_70", "cent70_80"}; + if (centBin < 0 || centBin >= NQ2CentBins) { + return nullptr; } + return Q2CentSuffixes[centBin]; + } - float low = cfgQ2Low->at(idx); - float high = cfgQ2High->at(idx); - if (q2Group == Q2Group::Low) { - return q2 < low; - } - if (q2Group == Q2Group::Mid) { - return q2 >= low && q2 < high; - } - if (q2Group == Q2Group::High) { - return q2 >= high; + auto& q2Axis(int centBin) + { + switch (centBin) { + case 0: + return qvecAxisCent0010; + case 1: + return qvecAxisCent1020; + case 2: + return qvecAxisCent2030; + case 3: + return qvecAxisCent3040; + case 4: + return qvecAxisCent4050; + case 5: + return qvecAxisCent5060; + case 6: + return qvecAxisCent6070; + case 7: + return qvecAxisCent7080; + default: + return qvecAxisCent0010; } - return false; } template @@ -285,20 +296,26 @@ struct FlowEseTask { histos.add(Form("histQvecCent"), "", {HistType::kTH3F, {lowerQAxis, upperQAxis, centQaAxis}}); histos.add(Form("histVertex"), "", {HistType::kTHnSparseF, {vertexAxis, vertexAxis, vertexAxis, centAxis}}); - histos.add(Form("histV2_q2"), "", {HistType::kTHnSparseF, {centAxis, ptAxis, cosAxis, qvecAxis}}); + for (int iCent = 0; iCent < NQ2CentBins; ++iCent) { + histos.add(Form("histV2_q2_%s", q2CentSuffix(iCent)), "", {HistType::kTHnSparseF, {centAxis, ptAxis, cosAxis, q2Axis(iCent)}}); + } histos.add("QA/CentDist", "", {HistType::kTH1F, {centQaAxis}}); histos.add("QA/PVzDist", "", {HistType::kTH1F, {pVzQaAxis}}); for (auto i = 2; i < cfgnMods + 2; i++) { histos.add(Form("psi%d/h_lambda_cos", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, epAxis}}); histos.add(Form("psi%d/h_alambda_cos", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, epAxis}}); - histos.add(Form("psi%d/h_lambda_cos_q2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, qvecAxis}}); - histos.add(Form("psi%d/h_alambda_cos_q2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, qvecAxis}}); + for (int iCent = 0; iCent < NQ2CentBins; ++iCent) { + histos.add(Form("psi%d/h_lambda_cos_q2_%s", i, q2CentSuffix(iCent)), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, q2Axis(iCent)}}); + histos.add(Form("psi%d/h_alambda_cos_q2_%s", i, q2CentSuffix(iCent)), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, q2Axis(iCent)}}); + } histos.add(Form("psi%d/h_lambda_cos2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, epAxis}}); histos.add(Form("psi%d/h_alambda_cos2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, epAxis}}); - histos.add(Form("psi%d/h_lambda_cos2_q2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, qvecAxis}}); - histos.add(Form("psi%d/h_alambda_cos2_q2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, qvecAxis}}); + for (int iCent = 0; iCent < NQ2CentBins; ++iCent) { + histos.add(Form("psi%d/h_lambda_cos2_q2_%s", i, q2CentSuffix(iCent)), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, q2Axis(iCent)}}); + histos.add(Form("psi%d/h_alambda_cos2_q2_%s", i, q2CentSuffix(iCent)), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, q2Axis(iCent)}}); + } if (cfgRapidityDep) { histos.add(Form("psi%d/h_lambda_cos2_rap", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, rapAxis}}); @@ -307,16 +324,12 @@ struct FlowEseTask { histos.add(Form("psi%d/h_lambda_cossin", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); histos.add(Form("psi%d/h_alambda_cossin", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add(Form("psi%d/h_lambda_cossin_SP", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add(Form("psi%d/h_alambda_cossin_SP", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); - histos.add(Form("psi%d/h_lambda_cossin_q2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, qvecAxis}}); - histos.add(Form("psi%d/h_alambda_cossin_q2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, qvecAxis}}); - if (i == CorrLevel[0]) { - histos.add("psi2/h_lambda_cossin_q2low", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); - histos.add("psi2/h_lambda_cossin_q2mid", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); - histos.add("psi2/h_lambda_cossin_q2high", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); - histos.add("psi2/h_alambda_cossin_q2low", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); - histos.add("psi2/h_alambda_cossin_q2mid", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); - histos.add("psi2/h_alambda_cossin_q2high", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + for (int iCent = 0; iCent < NQ2CentBins; ++iCent) { + histos.add(Form("psi%d/h_lambda_cossin_q2_%s", i, q2CentSuffix(iCent)), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, q2Axis(iCent)}}); + histos.add(Form("psi%d/h_alambda_cossin_q2_%s", i, q2CentSuffix(iCent)), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, q2Axis(iCent)}}); } if (cfgAccAzimuth) { @@ -326,23 +339,8 @@ struct FlowEseTask { histos.add(Form("psi%d/h_lambda_vncos", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); histos.add(Form("psi%d/h_lambda_vnsin", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); - histos.add(Form("psi%d/h_lambda_vncos_q2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, qvecAxis}}); - histos.add(Form("psi%d/h_lambda_vnsin_q2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, qvecAxis}}); - if (i == CorrLevel[0]) { - histos.add("psi2/h_lambda_vncos_q2low", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); - histos.add("psi2/h_lambda_vncos_q2mid", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); - histos.add("psi2/h_lambda_vncos_q2high", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); - } - histos.add(Form("psi%d/h_alambda_vncos", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); histos.add(Form("psi%d/h_alambda_vnsin", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); - histos.add(Form("psi%d/h_alambda_vncos_q2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, qvecAxis}}); - histos.add(Form("psi%d/h_alambda_vnsin_q2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, qvecAxis}}); - if (i == CorrLevel[0]) { - histos.add("psi2/h_alambda_vncos_q2low", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); - histos.add("psi2/h_alambda_vncos_q2mid", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); - histos.add("psi2/h_alambda_vncos_q2high", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); - } } histos.add("QA/ptspec_l", "", {HistType::kTH3F, {massAxis, ptAxis, centAxis}}); histos.add("QA/ptspec_al", "", {HistType::kTH3F, {massAxis, ptAxis, centAxis}}); @@ -436,48 +434,25 @@ struct FlowEseTask { histos.add(Form("psi%d/QA/qqAxis_RefA_RefB_yy", i), "", {HistType::kTH2F, {centQaAxis, qqAxis}}); if (i == CorrLevel[0]) { - histos.add("psi2/QA/qqAxis_Det_RefA_xx_q2", "", {HistType::kTH3F, {centQaAxis, qqAxis, qvecAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefB_xx_q2", "", {HistType::kTH3F, {centQaAxis, qqAxis, qvecAxis}}); - histos.add("psi2/QA/qqAxis_RefA_RefB_xx_q2", "", {HistType::kTH3F, {centQaAxis, qqAxis, qvecAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefA_yy_q2", "", {HistType::kTH3F, {centQaAxis, qqAxis, qvecAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefB_yy_q2", "", {HistType::kTH3F, {centQaAxis, qqAxis, qvecAxis}}); - histos.add("psi2/QA/qqAxis_RefA_RefB_yy_q2", "", {HistType::kTH3F, {centQaAxis, qqAxis, qvecAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefA_xx_q2low", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefA_xx_q2mid", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefA_xx_q2high", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefB_xx_q2low", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefB_xx_q2mid", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefB_xx_q2high", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_RefA_RefB_xx_q2low", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_RefA_RefB_xx_q2mid", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_RefA_RefB_xx_q2high", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefA_yy_q2low", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefA_yy_q2mid", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefA_yy_q2high", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefB_yy_q2low", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefB_yy_q2mid", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_Det_RefB_yy_q2high", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_RefA_RefB_yy_q2low", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_RefA_RefB_yy_q2mid", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); - histos.add("psi2/QA/qqAxis_RefA_RefB_yy_q2high", "", {HistType::kTH2F, {centQaAxis, qqAxis}}); + for (int iCent = 0; iCent < NQ2CentBins; ++iCent) { + histos.add(Form("psi2/QA/qqAxis_Det_RefA_xx_q2_%s", q2CentSuffix(iCent)), "", {HistType::kTH3F, {centQaAxis, qqAxis, q2Axis(iCent)}}); + histos.add(Form("psi2/QA/qqAxis_Det_RefB_xx_q2_%s", q2CentSuffix(iCent)), "", {HistType::kTH3F, {centQaAxis, qqAxis, q2Axis(iCent)}}); + histos.add(Form("psi2/QA/qqAxis_RefA_RefB_xx_q2_%s", q2CentSuffix(iCent)), "", {HistType::kTH3F, {centQaAxis, qqAxis, q2Axis(iCent)}}); + histos.add(Form("psi2/QA/qqAxis_Det_RefA_yy_q2_%s", q2CentSuffix(iCent)), "", {HistType::kTH3F, {centQaAxis, qqAxis, q2Axis(iCent)}}); + histos.add(Form("psi2/QA/qqAxis_Det_RefB_yy_q2_%s", q2CentSuffix(iCent)), "", {HistType::kTH3F, {centQaAxis, qqAxis, q2Axis(iCent)}}); + histos.add(Form("psi2/QA/qqAxis_RefA_RefB_yy_q2_%s", q2CentSuffix(iCent)), "", {HistType::kTH3F, {centQaAxis, qqAxis, q2Axis(iCent)}}); + } } histos.add(Form("psi%d/QA/EPRes_Det_RefA", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); histos.add(Form("psi%d/QA/EPRes_Det_RefB", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); histos.add(Form("psi%d/QA/EPRes_RefA_RefB", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); if (i == CorrLevel[0]) { - histos.add("psi2/QA/EPRes_Det_RefA_q2", "", {HistType::kTH3F, {centQaAxis, cosAxis, qvecAxis}}); - histos.add("psi2/QA/EPRes_Det_RefB_q2", "", {HistType::kTH3F, {centQaAxis, cosAxis, qvecAxis}}); - histos.add("psi2/QA/EPRes_RefA_RefB_q2", "", {HistType::kTH3F, {centQaAxis, cosAxis, qvecAxis}}); - histos.add("psi2/QA/EPRes_Det_RefA_q2low", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_Det_RefA_q2mid", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_Det_RefA_q2high", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_Det_RefB_q2low", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_Det_RefB_q2mid", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_Det_RefB_q2high", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_RefA_RefB_q2low", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_RefA_RefB_q2mid", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_RefA_RefB_q2high", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); + for (int iCent = 0; iCent < NQ2CentBins; ++iCent) { + histos.add(Form("psi2/QA/EPRes_Det_RefA_q2_%s", q2CentSuffix(iCent)), "", {HistType::kTH3F, {centQaAxis, cosAxis, q2Axis(iCent)}}); + histos.add(Form("psi2/QA/EPRes_Det_RefB_q2_%s", q2CentSuffix(iCent)), "", {HistType::kTH3F, {centQaAxis, cosAxis, q2Axis(iCent)}}); + histos.add(Form("psi2/QA/EPRes_RefA_RefB_q2_%s", q2CentSuffix(iCent)), "", {HistType::kTH3F, {centQaAxis, cosAxis, q2Axis(iCent)}}); + } } histos.add(Form("psi%d/QA/EP_FT0C_shifted", i), "", {HistType::kTH2F, {centQaAxis, epQaAxis}}); @@ -487,20 +462,6 @@ struct FlowEseTask { histos.add(Form("psi%d/QA/EPRes_FT0C_FT0A_shifted", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); histos.add(Form("psi%d/QA/EPRes_FT0C_FV0A_shifted", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); histos.add(Form("psi%d/QA/EPRes_FT0A_FV0A_shifted", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - if (i == CorrLevel[0]) { - histos.add("psi2/QA/EPRes_FT0C_FT0A_shifted_q2", "", {HistType::kTH3F, {centQaAxis, cosAxis, qvecAxis}}); - histos.add("psi2/QA/EPRes_FT0C_FV0A_shifted_q2", "", {HistType::kTH3F, {centQaAxis, cosAxis, qvecAxis}}); - histos.add("psi2/QA/EPRes_FT0A_FV0A_shifted_q2", "", {HistType::kTH3F, {centQaAxis, cosAxis, qvecAxis}}); - histos.add("psi2/QA/EPRes_FT0C_FT0A_shifted_q2low", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_FT0C_FT0A_shifted_q2mid", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_FT0C_FT0A_shifted_q2high", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_FT0C_FV0A_shifted_q2low", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_FT0C_FV0A_shifted_q2mid", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_FT0C_FV0A_shifted_q2high", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_FT0A_FV0A_shifted_q2low", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_FT0A_FV0A_shifted_q2mid", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - histos.add("psi2/QA/EPRes_FT0A_FV0A_shifted_q2high", "", {HistType::kTH2F, {centQaAxis, cosAxis}}); - } } } @@ -597,7 +558,7 @@ struct FlowEseTask { return false; if (std::abs(candidate.dcanegtopv()) < cfgDCAPiToPVMin) return false; - } else if (!lambdaTag) { + } else { if (std::abs(candidate.dcapostopv()) < cfgDCAPiToPVMin) return false; if (std::abs(candidate.dcanegtopv()) < cfgDCAPrToPVMin) @@ -749,52 +710,101 @@ struct FlowEseTask { double qqDetRefAyy = collision.qvecIm()[qvecDetInd] * collision.qvecIm()[qvecRefAInd]; double qqDetRefByy = collision.qvecIm()[qvecDetInd] * collision.qvecIm()[qvecRefBInd]; double qqRefARefByy = collision.qvecIm()[qvecRefAInd] * collision.qvecIm()[qvecRefBInd]; - histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_xx_q2"), centrality, qqDetRefAxx, q2); - histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_xx_q2"), centrality, qqDetRefBxx, q2); - histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_xx_q2"), centrality, qqRefARefBxx, q2); - histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_yy_q2"), centrality, qqDetRefAyy, q2); - histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_yy_q2"), centrality, qqDetRefByy, q2); - histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_yy_q2"), centrality, qqRefARefByy, q2); - if (q2sel(q2, Q2Group::Low)) { - histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_xx_q2low"), centrality, qqDetRefAxx); - histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_xx_q2low"), centrality, qqDetRefBxx); - histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_xx_q2low"), centrality, qqRefARefBxx); - histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_yy_q2low"), centrality, qqDetRefAyy); - histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_yy_q2low"), centrality, qqDetRefByy); - histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_yy_q2low"), centrality, qqRefARefByy); - } else if (q2sel(q2, Q2Group::Mid)) { - histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_xx_q2mid"), centrality, qqDetRefAxx); - histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_xx_q2mid"), centrality, qqDetRefBxx); - histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_xx_q2mid"), centrality, qqRefARefBxx); - histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_yy_q2mid"), centrality, qqDetRefAyy); - histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_yy_q2mid"), centrality, qqDetRefByy); - histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_yy_q2mid"), centrality, qqRefARefByy); - } else if (q2sel(q2, Q2Group::High)) { - histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_xx_q2high"), centrality, qqDetRefAxx); - histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_xx_q2high"), centrality, qqDetRefBxx); - histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_xx_q2high"), centrality, qqRefARefBxx); - histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_yy_q2high"), centrality, qqDetRefAyy); - histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_yy_q2high"), centrality, qqDetRefByy); - histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_yy_q2high"), centrality, qqRefARefByy); - } + const int q2Cent = q2CentBin(centrality); double epResDetRefA = std::cos(std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) - std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd])); double epResDetRefB = std::cos(std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) - std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd])); double epResRefARefB = std::cos(std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) - std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd])); - histos.fill(HIST("psi2/QA/EPRes_Det_RefA_q2"), centrality, epResDetRefA, q2); - histos.fill(HIST("psi2/QA/EPRes_Det_RefB_q2"), centrality, epResDetRefB, q2); - histos.fill(HIST("psi2/QA/EPRes_RefA_RefB_q2"), centrality, epResRefARefB, q2); - if (q2sel(q2, Q2Group::Low)) { - histos.fill(HIST("psi2/QA/EPRes_Det_RefA_q2low"), centrality, epResDetRefA); - histos.fill(HIST("psi2/QA/EPRes_Det_RefB_q2low"), centrality, epResDetRefB); - histos.fill(HIST("psi2/QA/EPRes_RefA_RefB_q2low"), centrality, epResRefARefB); - } else if (q2sel(q2, Q2Group::Mid)) { - histos.fill(HIST("psi2/QA/EPRes_Det_RefA_q2mid"), centrality, epResDetRefA); - histos.fill(HIST("psi2/QA/EPRes_Det_RefB_q2mid"), centrality, epResDetRefB); - histos.fill(HIST("psi2/QA/EPRes_RefA_RefB_q2mid"), centrality, epResRefARefB); - } else if (q2sel(q2, Q2Group::High)) { - histos.fill(HIST("psi2/QA/EPRes_Det_RefA_q2high"), centrality, epResDetRefA); - histos.fill(HIST("psi2/QA/EPRes_Det_RefB_q2high"), centrality, epResDetRefB); - histos.fill(HIST("psi2/QA/EPRes_RefA_RefB_q2high"), centrality, epResRefARefB); + switch (q2Cent) { + case 0: + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_xx_q2_cent00_10"), centrality, qqDetRefAxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_xx_q2_cent00_10"), centrality, qqDetRefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_xx_q2_cent00_10"), centrality, qqRefARefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_yy_q2_cent00_10"), centrality, qqDetRefAyy, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_yy_q2_cent00_10"), centrality, qqDetRefByy, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_yy_q2_cent00_10"), centrality, qqRefARefByy, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefA_q2_cent00_10"), centrality, epResDetRefA, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefB_q2_cent00_10"), centrality, epResDetRefB, q2); + histos.fill(HIST("psi2/QA/EPRes_RefA_RefB_q2_cent00_10"), centrality, epResRefARefB, q2); + break; + case 1: + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_xx_q2_cent10_20"), centrality, qqDetRefAxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_xx_q2_cent10_20"), centrality, qqDetRefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_xx_q2_cent10_20"), centrality, qqRefARefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_yy_q2_cent10_20"), centrality, qqDetRefAyy, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_yy_q2_cent10_20"), centrality, qqDetRefByy, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_yy_q2_cent10_20"), centrality, qqRefARefByy, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefA_q2_cent10_20"), centrality, epResDetRefA, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefB_q2_cent10_20"), centrality, epResDetRefB, q2); + histos.fill(HIST("psi2/QA/EPRes_RefA_RefB_q2_cent10_20"), centrality, epResRefARefB, q2); + break; + case 2: + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_xx_q2_cent20_30"), centrality, qqDetRefAxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_xx_q2_cent20_30"), centrality, qqDetRefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_xx_q2_cent20_30"), centrality, qqRefARefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_yy_q2_cent20_30"), centrality, qqDetRefAyy, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_yy_q2_cent20_30"), centrality, qqDetRefByy, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_yy_q2_cent20_30"), centrality, qqRefARefByy, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefA_q2_cent20_30"), centrality, epResDetRefA, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefB_q2_cent20_30"), centrality, epResDetRefB, q2); + histos.fill(HIST("psi2/QA/EPRes_RefA_RefB_q2_cent20_30"), centrality, epResRefARefB, q2); + break; + case 3: + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_xx_q2_cent30_40"), centrality, qqDetRefAxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_xx_q2_cent30_40"), centrality, qqDetRefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_xx_q2_cent30_40"), centrality, qqRefARefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_yy_q2_cent30_40"), centrality, qqDetRefAyy, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_yy_q2_cent30_40"), centrality, qqDetRefByy, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_yy_q2_cent30_40"), centrality, qqRefARefByy, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefA_q2_cent30_40"), centrality, epResDetRefA, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefB_q2_cent30_40"), centrality, epResDetRefB, q2); + histos.fill(HIST("psi2/QA/EPRes_RefA_RefB_q2_cent30_40"), centrality, epResRefARefB, q2); + break; + case 4: + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_xx_q2_cent40_50"), centrality, qqDetRefAxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_xx_q2_cent40_50"), centrality, qqDetRefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_xx_q2_cent40_50"), centrality, qqRefARefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_yy_q2_cent40_50"), centrality, qqDetRefAyy, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_yy_q2_cent40_50"), centrality, qqDetRefByy, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_yy_q2_cent40_50"), centrality, qqRefARefByy, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefA_q2_cent40_50"), centrality, epResDetRefA, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefB_q2_cent40_50"), centrality, epResDetRefB, q2); + histos.fill(HIST("psi2/QA/EPRes_RefA_RefB_q2_cent40_50"), centrality, epResRefARefB, q2); + break; + case 5: + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_xx_q2_cent50_60"), centrality, qqDetRefAxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_xx_q2_cent50_60"), centrality, qqDetRefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_xx_q2_cent50_60"), centrality, qqRefARefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_yy_q2_cent50_60"), centrality, qqDetRefAyy, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_yy_q2_cent50_60"), centrality, qqDetRefByy, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_yy_q2_cent50_60"), centrality, qqRefARefByy, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefA_q2_cent50_60"), centrality, epResDetRefA, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefB_q2_cent50_60"), centrality, epResDetRefB, q2); + histos.fill(HIST("psi2/QA/EPRes_RefA_RefB_q2_cent50_60"), centrality, epResRefARefB, q2); + break; + case 6: + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_xx_q2_cent60_70"), centrality, qqDetRefAxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_xx_q2_cent60_70"), centrality, qqDetRefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_xx_q2_cent60_70"), centrality, qqRefARefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_yy_q2_cent60_70"), centrality, qqDetRefAyy, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_yy_q2_cent60_70"), centrality, qqDetRefByy, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_yy_q2_cent60_70"), centrality, qqRefARefByy, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefA_q2_cent60_70"), centrality, epResDetRefA, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefB_q2_cent60_70"), centrality, epResDetRefB, q2); + histos.fill(HIST("psi2/QA/EPRes_RefA_RefB_q2_cent60_70"), centrality, epResRefARefB, q2); + break; + case 7: + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_xx_q2_cent70_80"), centrality, qqDetRefAxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_xx_q2_cent70_80"), centrality, qqDetRefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_xx_q2_cent70_80"), centrality, qqRefARefBxx, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_yy_q2_cent70_80"), centrality, qqDetRefAyy, q2); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_yy_q2_cent70_80"), centrality, qqDetRefByy, q2); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_yy_q2_cent70_80"), centrality, qqRefARefByy, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefA_q2_cent70_80"), centrality, epResDetRefA, q2); + histos.fill(HIST("psi2/QA/EPRes_Det_RefB_q2_cent70_80"), centrality, epResDetRefB, q2); + histos.fill(HIST("psi2/QA/EPRes_RefA_RefB_q2_cent70_80"), centrality, epResRefARefB, q2); + break; + default: + break; } } else if (nmode == CorrLevel[1]) { histos.fill(HIST("psi3/QA/EP_Det"), centrality, std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) / static_cast(nmode)); @@ -858,27 +868,6 @@ struct FlowEseTask { histos.fill(HIST("psi2/QA/EPRes_FT0C_FT0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFT0A - deltapsiFT0A))); histos.fill(HIST("psi2/QA/EPRes_FT0C_FV0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFV0A - deltapsiFV0A))); histos.fill(HIST("psi2/QA/EPRes_FT0A_FV0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0A + deltapsiFT0A - psidefFV0A - deltapsiFV0A))); - double q2 = getQ2(collision); - double epResFT0CFT0AShifted = std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFT0A - deltapsiFT0A)); - double epResFT0CFV0AShifted = std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFV0A - deltapsiFV0A)); - double epResFT0AFV0AShifted = std::cos(static_cast(nmode) * (psidefFT0A + deltapsiFT0A - psidefFV0A - deltapsiFV0A)); - histos.fill(HIST("psi2/QA/EPRes_FT0C_FT0A_shifted_q2"), centrality, epResFT0CFT0AShifted, q2); - histos.fill(HIST("psi2/QA/EPRes_FT0C_FV0A_shifted_q2"), centrality, epResFT0CFV0AShifted, q2); - histos.fill(HIST("psi2/QA/EPRes_FT0A_FV0A_shifted_q2"), centrality, epResFT0AFV0AShifted, q2); - if (q2sel(q2, Q2Group::Low)) { - histos.fill(HIST("psi2/QA/EPRes_FT0C_FT0A_shifted_q2low"), centrality, epResFT0CFT0AShifted); - histos.fill(HIST("psi2/QA/EPRes_FT0C_FV0A_shifted_q2low"), centrality, epResFT0CFV0AShifted); - histos.fill(HIST("psi2/QA/EPRes_FT0A_FV0A_shifted_q2low"), centrality, epResFT0AFV0AShifted); - } else if (q2sel(q2, Q2Group::Mid)) { - histos.fill(HIST("psi2/QA/EPRes_FT0C_FT0A_shifted_q2mid"), centrality, epResFT0CFT0AShifted); - histos.fill(HIST("psi2/QA/EPRes_FT0C_FV0A_shifted_q2mid"), centrality, epResFT0CFV0AShifted); - histos.fill(HIST("psi2/QA/EPRes_FT0A_FV0A_shifted_q2mid"), centrality, epResFT0AFV0AShifted); - } else if (q2sel(q2, Q2Group::High)) { - histos.fill(HIST("psi2/QA/EPRes_FT0C_FT0A_shifted_q2high"), centrality, epResFT0CFT0AShifted); - histos.fill(HIST("psi2/QA/EPRes_FT0C_FV0A_shifted_q2high"), centrality, epResFT0CFV0AShifted); - histos.fill(HIST("psi2/QA/EPRes_FT0A_FV0A_shifted_q2high"), centrality, epResFT0AFV0AShifted); - } - } else if (nmode == CorrLevel[1]) { histos.fill(HIST("psi3/QA/EP_FT0C_shifted"), centrality, psidefFT0C + deltapsiFT0C); histos.fill(HIST("psi3/QA/EP_FT0A_shifted"), centrality, psidefFT0A + deltapsiFT0A); @@ -911,9 +900,37 @@ struct FlowEseTask { continue; } if (nmode == CorrLevel[0]) { - histos.fill(HIST("histV2_q2"), collision.centFT0C(), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode))), - std::sqrt(collision.qvecFT0CReVec()[0] * collision.qvecFT0CReVec()[0] + collision.qvecFT0CImVec()[0] * collision.qvecFT0CImVec()[0]) * std::sqrt(collision.sumAmplFT0C())); + const auto cent = centrality; + const auto trackV2 = std::cos(static_cast(nmode) * (trk.phi() - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode))); + const auto trackQ2 = std::sqrt(collision.qvecFT0CReVec()[0] * collision.qvecFT0CReVec()[0] + collision.qvecFT0CImVec()[0] * collision.qvecFT0CImVec()[0]) * std::sqrt(collision.sumAmplFT0C()); + switch (q2CentBin(cent)) { + case 0: + histos.fill(HIST("histV2_q2_cent00_10"), cent, trk.pt(), trackV2, trackQ2); + break; + case 1: + histos.fill(HIST("histV2_q2_cent10_20"), cent, trk.pt(), trackV2, trackQ2); + break; + case 2: + histos.fill(HIST("histV2_q2_cent20_30"), cent, trk.pt(), trackV2, trackQ2); + break; + case 3: + histos.fill(HIST("histV2_q2_cent30_40"), cent, trk.pt(), trackV2, trackQ2); + break; + case 4: + histos.fill(HIST("histV2_q2_cent40_50"), cent, trk.pt(), trackV2, trackQ2); + break; + case 5: + histos.fill(HIST("histV2_q2_cent50_60"), cent, trk.pt(), trackV2, trackQ2); + break; + case 6: + histos.fill(HIST("histV2_q2_cent60_70"), cent, trk.pt(), trackV2, trackQ2); + break; + case 7: + histos.fill(HIST("histV2_q2_cent70_80"), cent, trk.pt(), trackV2, trackQ2); + break; + default: + break; + } } } @@ -972,6 +989,8 @@ struct FlowEseTask { angle = protonBoostedVec.Pz() / protonBoostedVec.P(); psi = safeATan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) / static_cast(nmode); relphi = TVector2::Phi_0_2pi(static_cast(nmode) * (LambdaVec.Phi() - psi)); + productPhi = std::sin(static_cast(nmode) * LambdaVec.Phi()) * collision.qvecRe()[qvecDetInd] - + std::cos(static_cast(nmode) * LambdaVec.Phi()) * collision.qvecIm()[qvecDetInd]; if (cfgShiftCorr) { auto deltapsiFT0C = 0.0; @@ -1029,34 +1048,60 @@ struct FlowEseTask { q2 = std::sqrt(collision.qvecFT0CReVec()[0] * collision.qvecFT0CReVec()[0] + collision.qvecFT0CImVec()[0] * collision.qvecFT0CImVec()[0]) * collision.sumAmplFT0C() / std::sqrt(collision.multFT0C()); else q2 = std::sqrt(collision.qvecFT0CReVec()[0] * collision.qvecFT0CReVec()[0] + collision.qvecFT0CImVec()[0] * collision.qvecFT0CImVec()[0]) * std::sqrt(collision.sumAmplFT0C()); + const int q2Cent = q2CentBin(centrality); if (lambdaTag) { histos.fill(HIST("psi2/h_lambda_cos"), v0.mLambda(), v0.pt(), angle * weight, centrality, relphi); histos.fill(HIST("psi2/h_lambda_cos2"), v0.mLambda(), v0.pt(), angle * angle, centrality, relphi); histos.fill(HIST("psi2/h_lambda_cossin"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); + histos.fill(HIST("psi2/h_lambda_cossin_SP"), v0.mLambda(), v0.pt(), angle * productPhi * weight, centrality); histos.fill(HIST("psi2/h_lambda_vncos"), v0.mLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); histos.fill(HIST("psi2/h_lambda_vnsin"), v0.mLambda(), v0.pt(), std::sin(relphi), centrality); - histos.fill(HIST("psi2/h_lambda_cos_q2"), v0.mLambda(), v0.pt(), angle * weight, centrality, q2); - histos.fill(HIST("psi2/h_lambda_cos2_q2"), v0.mLambda(), v0.pt(), angle * angle, centrality, q2); - histos.fill(HIST("psi2/h_lambda_cossin_q2"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); - if (q2sel(q2, Q2Group::Low)) { - histos.fill(HIST("psi2/h_lambda_cossin_q2low"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); - } else if (q2sel(q2, Q2Group::Mid)) { - histos.fill(HIST("psi2/h_lambda_cossin_q2mid"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); - } else if (q2sel(q2, Q2Group::High)) { - histos.fill(HIST("psi2/h_lambda_cossin_q2high"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); - } - histos.fill(HIST("psi2/h_lambda_vncos_q2"), v0.mLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality, q2); - if (q2sel(q2, Q2Group::Low)) { - histos.fill(HIST("psi2/h_lambda_vncos_q2low"), v0.mLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); - } else if (q2sel(q2, Q2Group::Mid)) { - histos.fill(HIST("psi2/h_lambda_vncos_q2mid"), v0.mLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); - } else if (q2sel(q2, Q2Group::High)) { - histos.fill(HIST("psi2/h_lambda_vncos_q2high"), v0.mLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); + switch (q2Cent) { + case 0: + histos.fill(HIST("psi2/h_lambda_cos_q2_cent00_10"), v0.mLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cos2_q2_cent00_10"), v0.mLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cossin_q2_cent00_10"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + case 1: + histos.fill(HIST("psi2/h_lambda_cos_q2_cent10_20"), v0.mLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cos2_q2_cent10_20"), v0.mLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cossin_q2_cent10_20"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + case 2: + histos.fill(HIST("psi2/h_lambda_cos_q2_cent20_30"), v0.mLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cos2_q2_cent20_30"), v0.mLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cossin_q2_cent20_30"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + case 3: + histos.fill(HIST("psi2/h_lambda_cos_q2_cent30_40"), v0.mLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cos2_q2_cent30_40"), v0.mLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cossin_q2_cent30_40"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + case 4: + histos.fill(HIST("psi2/h_lambda_cos_q2_cent40_50"), v0.mLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cos2_q2_cent40_50"), v0.mLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cossin_q2_cent40_50"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + case 5: + histos.fill(HIST("psi2/h_lambda_cos_q2_cent50_60"), v0.mLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cos2_q2_cent50_60"), v0.mLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cossin_q2_cent50_60"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + case 6: + histos.fill(HIST("psi2/h_lambda_cos_q2_cent60_70"), v0.mLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cos2_q2_cent60_70"), v0.mLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cossin_q2_cent60_70"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + case 7: + histos.fill(HIST("psi2/h_lambda_cos_q2_cent70_80"), v0.mLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cos2_q2_cent70_80"), v0.mLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_lambda_cossin_q2_cent70_80"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + default: + break; } - histos.fill(HIST("psi2/h_lambda_vnsin_q2"), v0.mLambda(), v0.pt(), std::sin(relphi), centrality, q2); - if (cfgRapidityDep) { histos.fill(HIST("psi2/h_lambda_cos2_rap"), v0.mLambda(), v0.pt(), angle * angle, centrality, v0.yLambda(), weight); } @@ -1103,29 +1148,54 @@ struct FlowEseTask { histos.fill(HIST("psi2/h_alambda_cos"), v0.mAntiLambda(), v0.pt(), angle * weight, centrality, relphi); histos.fill(HIST("psi2/h_alambda_cos2"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, relphi); histos.fill(HIST("psi2/h_alambda_cossin"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); + histos.fill(HIST("psi2/h_alambda_cossin_SP"), v0.mAntiLambda(), v0.pt(), angle * productPhi * weight, centrality); histos.fill(HIST("psi2/h_alambda_vncos"), v0.mAntiLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); histos.fill(HIST("psi2/h_alambda_vnsin"), v0.mAntiLambda(), v0.pt(), std::sin(relphi), centrality); - histos.fill(HIST("psi2/h_alambda_cos_q2"), v0.mAntiLambda(), v0.pt(), angle * weight, centrality, q2); - histos.fill(HIST("psi2/h_alambda_cos2_q2"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, q2); - histos.fill(HIST("psi2/h_alambda_cossin_q2"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); - if (q2sel(q2, Q2Group::Low)) { - histos.fill(HIST("psi2/h_alambda_cossin_q2low"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); - } else if (q2sel(q2, Q2Group::Mid)) { - histos.fill(HIST("psi2/h_alambda_cossin_q2mid"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); - } else if (q2sel(q2, Q2Group::High)) { - histos.fill(HIST("psi2/h_alambda_cossin_q2high"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); - } - histos.fill(HIST("psi2/h_alambda_vncos_q2"), v0.mAntiLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality, q2); - if (q2sel(q2, Q2Group::Low)) { - histos.fill(HIST("psi2/h_alambda_vncos_q2low"), v0.mAntiLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); - } else if (q2sel(q2, Q2Group::Mid)) { - histos.fill(HIST("psi2/h_alambda_vncos_q2mid"), v0.mAntiLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); - } else if (q2sel(q2, Q2Group::High)) { - histos.fill(HIST("psi2/h_alambda_vncos_q2high"), v0.mAntiLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); + switch (q2Cent) { + case 0: + histos.fill(HIST("psi2/h_alambda_cos_q2_cent00_10"), v0.mAntiLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cos2_q2_cent00_10"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cossin_q2_cent00_10"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + case 1: + histos.fill(HIST("psi2/h_alambda_cos_q2_cent10_20"), v0.mAntiLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cos2_q2_cent10_20"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cossin_q2_cent10_20"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + case 2: + histos.fill(HIST("psi2/h_alambda_cos_q2_cent20_30"), v0.mAntiLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cos2_q2_cent20_30"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cossin_q2_cent20_30"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + case 3: + histos.fill(HIST("psi2/h_alambda_cos_q2_cent30_40"), v0.mAntiLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cos2_q2_cent30_40"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cossin_q2_cent30_40"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + case 4: + histos.fill(HIST("psi2/h_alambda_cos_q2_cent40_50"), v0.mAntiLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cos2_q2_cent40_50"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cossin_q2_cent40_50"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + case 5: + histos.fill(HIST("psi2/h_alambda_cos_q2_cent50_60"), v0.mAntiLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cos2_q2_cent50_60"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cossin_q2_cent50_60"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + case 6: + histos.fill(HIST("psi2/h_alambda_cos_q2_cent60_70"), v0.mAntiLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cos2_q2_cent60_70"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cossin_q2_cent60_70"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + case 7: + histos.fill(HIST("psi2/h_alambda_cos_q2_cent70_80"), v0.mAntiLambda(), v0.pt(), angle * weight, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cos2_q2_cent70_80"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, q2); + histos.fill(HIST("psi2/h_alambda_cossin_q2_cent70_80"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality, q2); + break; + default: + break; } - histos.fill(HIST("psi2/h_alambda_vnsin_q2"), v0.mAntiLambda(), v0.pt(), std::sin(relphi), centrality, q2); - if (cfgRapidityDep) { histos.fill(HIST("psi2/h_alambda_cos2_rap"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, v0.yLambda(), weight); } diff --git a/PWGCF/Flow/Tasks/flowEventPlane.cxx b/PWGCF/Flow/Tasks/flowEventPlane.cxx index 43459c95606..294a9fea522 100644 --- a/PWGCF/Flow/Tasks/flowEventPlane.cxx +++ b/PWGCF/Flow/Tasks/flowEventPlane.cxx @@ -18,7 +18,6 @@ #include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" @@ -63,6 +62,31 @@ using namespace o2::constants::math; namespace o2::aod { +namespace colspcalib +{ +DECLARE_SOA_COLUMN(RunNumber, runNumber, int); +DECLARE_SOA_COLUMN(Timestamp, timestamp, uint64_t); +DECLARE_SOA_COLUMN(Cent, cent, float); +DECLARE_SOA_COLUMN(Vx, vx, float); +DECLARE_SOA_COLUMN(Vy, vy, float); +DECLARE_SOA_COLUMN(Vz, vz, float); +DECLARE_SOA_COLUMN(ZnaEnergyCommon, znaEnergyCommon, float); +DECLARE_SOA_COLUMN(ZncEnergyCommon, zncEnergyCommon, float); +DECLARE_SOA_COLUMN(ZnaEnergy, znaEnergy, float[4]); +DECLARE_SOA_COLUMN(ZncEnergy, zncEnergy, float[4]); +} // namespace colspcalib +DECLARE_SOA_TABLE(ColSpCalib, "AOD", "COLSPCALIB", o2::soa::Index<>, + colspcalib::RunNumber, + colspcalib::Timestamp, + colspcalib::Cent, + colspcalib::Vx, + colspcalib::Vy, + colspcalib::Vz, + colspcalib::ZnaEnergyCommon, + colspcalib::ZncEnergyCommon, + colspcalib::ZnaEnergy, + colspcalib::ZncEnergy); + namespace colspext { DECLARE_SOA_COLUMN(SelColFlag, selColFlag, bool); @@ -71,7 +95,7 @@ DECLARE_SOA_COLUMN(Ya, ya, float); DECLARE_SOA_COLUMN(Xc, xc, float); DECLARE_SOA_COLUMN(Yc, yc, float); } // namespace colspext -DECLARE_SOA_TABLE(ColSPExt, "AOD", "COLSPEXT", o2::soa::Index<>, +DECLARE_SOA_TABLE(ColSPExt, "AOD", "COLSPSEXT", o2::soa::Index<>, colspext::SelColFlag, colspext::Xa, colspext::Ya, @@ -137,6 +161,130 @@ enum V0Type { kAntiLambda }; +struct SpCalibTableProducer { + // Table producer + Produces colSpCalibTable; + + // Configurables + // Collisions + Configurable cMinZVtx{"cMinZVtx", -10.0, "Min VtxZ cut"}; + Configurable cMaxZVtx{"cMaxZVtx", 10.0, "Max VtxZ cut"}; + Configurable cMinCent{"cMinCent", 0., "Minumum Centrality"}; + Configurable cMaxCent{"cMaxCent", 100.0, "Maximum Centrality"}; + Configurable cSel8Trig{"cSel8Trig", true, "Sel8 (T0A + T0C) Selection Run3"}; + Configurable cPileupReject{"cPileupReject", true, "Pileup rejection"}; + Configurable cZVtxTimeDiff{"cZVtxTimeDiff", true, "z-vtx time diff selection"}; + Configurable cIsGoodITSLayers{"cIsGoodITSLayers", true, "Good ITS Layers All"}; + Configurable cMinOccupancy{"cMinOccupancy", 0, "Minimum FT0C Occupancy"}; + Configurable cMaxOccupancy{"cMaxOccupancy", 1e6, "Maximum FT0C Occupancy"}; + + // Histogram Registry. + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // Run number + uint64_t runNum = 0, timestamp = 0; + float mult = 0., cent = 0., posX = 0., posY = 0., posZ = 0.; + + void init(InitContext const&) + { + // Histogram collision + histos.add("hCent", "Centrality", kTH1F, {{100, 0., 100., "FT0C%"}}); + histos.add("hVz", "V_{z}", kTH1F, {{100, -10., 10., "V_{z}(cm)"}}); + } + + template + bool selCollision(C const& col) + { + if (col.posZ() <= cMinZVtx || col.posZ() >= cMaxZVtx) { // VtxZ selection + return false; + } + + if (cSel8Trig && !col.sel8()) { // Sel8 selection + return false; + } + + cent = col.centFT0C(); + if (cent <= cMinCent || cent >= cMaxCent) { // Centrality selection + return false; + } + + if (col.ft0cOccupancyInTimeRange() < cMinOccupancy || col.ft0cOccupancyInTimeRange() > cMaxOccupancy) { // Occupancy cut + return false; + } + + if (cPileupReject && !col.selection_bit(aod::evsel::kNoSameBunchPileup)) { // Pile-up rejection + return false; + } + + if (cZVtxTimeDiff && !col.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { // ZvtxFT0 vs PV + return false; + } + + if (cIsGoodITSLayers && !col.selection_bit(aod::evsel::kIsGoodITSLayersAll)) { // All ITS layer active + return false; + } + + // Set Multiplicity + mult = col.multTPC(); + + return true; + } + + template + void analyzeCollision(B const& bc, C const& collision) + { + // Check zdc + if (!bc.has_zdc()) { + return; + } + + // Event selection + if (!selCollision(collision)) { + return; + } + posX = collision.posX(); + posY = collision.posY(); + posZ = collision.posZ(); + + auto zdc = bc.zdc(); + auto znaEnergy = zdc.energySectorZNA(); + auto zncEnergy = zdc.energySectorZNC(); + auto znaEnergyCommon = zdc.energyCommonZNA(); + auto zncEnergyCommon = zdc.energyCommonZNC(); + + // check energy deposits + if (znaEnergyCommon <= 0 || zncEnergyCommon <= 0 || znaEnergy[0] <= 0 || znaEnergy[1] <= 0 || znaEnergy[2] <= 0 || znaEnergy[3] <= 0 || zncEnergy[0] <= 0 || zncEnergy[1] <= 0 || zncEnergy[2] <= 0 || zncEnergy[3] <= 0) { + return; + } + + // Fill collision table + histos.fill(HIST("hCent"), cent); + histos.fill(HIST("hVz"), posZ); + colSpCalibTable(runNum, timestamp, cent, posX, posY, posZ, znaEnergyCommon, zncEnergyCommon, znaEnergy.data(), zncEnergy.data()); + + // Done + return; + } + + using BCsRun3 = soa::Join; + using CollisionsRun3 = soa::Join; + + void processDummy(CollisionsRun3::iterator const&) {} + + PROCESS_SWITCH(SpCalibTableProducer, processDummy, "Dummy process", true); + + void processFEP(CollisionsRun3::iterator const& collision, BCsRun3 const&, aod::Zdcs const&) + { + // Get bunch crossing + auto bc = collision.template foundBC_as(); + runNum = collision.template foundBC_as().runNumber(); + timestamp = collision.template foundBC_as().timestamp(); + analyzeCollision(bc, collision); + } + + PROCESS_SWITCH(SpCalibTableProducer, processFEP, "Flow Event Plane Table Producer", false); +}; + struct SpectatorPlaneTableProducer { // Table producer Produces colSPExtTable; @@ -149,35 +297,31 @@ struct SpectatorPlaneTableProducer { Configurable cMinCent{"cMinCent", 0., "Minumum Centrality"}; Configurable cMaxCent{"cMaxCent", 100.0, "Maximum Centrality"}; Configurable cSel8Trig{"cSel8Trig", true, "Sel8 (T0A + T0C) Selection Run3"}; - Configurable cTriggerTvxSel{"cTriggerTvxSel", false, "Trigger Time and Vertex Selection"}; - Configurable cTFBorder{"cTFBorder", false, "Timeframe Border Selection"}; - Configurable cNoItsROBorder{"cNoItsROBorder", false, "No ITSRO Border Cut"}; - Configurable cItsTpcVtx{"cItsTpcVtx", false, "ITS+TPC Vertex Selection"}; Configurable cPileupReject{"cPileupReject", true, "Pileup rejection"}; - Configurable cZVtxTimeDiff{"cZVtxTimeDiff", false, "z-vtx time diff selection"}; + Configurable cZVtxTimeDiff{"cZVtxTimeDiff", true, "z-vtx time diff selection"}; Configurable cIsGoodITSLayers{"cIsGoodITSLayers", true, "Good ITS Layers All"}; Configurable cMinOccupancy{"cMinOccupancy", 0, "Minimum FT0C Occupancy"}; Configurable cMaxOccupancy{"cMaxOccupancy", 1e6, "Maximum FT0C Occupancy"}; - // Gain calibration - Configurable cDoGainCalib{"cDoGainCalib", false, "Gain Calib Flag"}; - Configurable cUseAlphaZDC{"cUseAlphaZDC", true, "Use Alpha ZDC"}; - // Coarse binning factor - Configurable cAxisCBF{"cAxisCBF", 5, "Coarse Bin Factor"}; + Configurable cAxisCBF{"cAxisCBF", 10, "Coarse Bin Factor"}; // Cent Vx Vy Vz Bins - Configurable cAxisCentBins{"cAxisCentBins", 20, "NBins Centrality"}; - Configurable cAxisVxyBins{"cAxisVxyBins", 20, "NBins Vx Vy"}; - Configurable cAxisVzBins{"cAxisVzBins", 20, "NBins Vz"}; - Configurable cAxisVxMin{"cAxisVxMin", -0.06, "Vx Min"}; - Configurable cAxisVxMax{"cAxisVxMax", -0.02, "Vx Max"}; + Configurable cAxisCentBins{"cAxisCentBins", 50, "NBins Centrality"}; + Configurable cAxisVxyBins{"cAxisVxyBins", 50, "NBins Vx Vy"}; + Configurable cAxisVzBins{"cAxisVzBins", 50, "NBins Vz"}; + Configurable cAxisVxMin{"cAxisVxMin", -0.01, "Vx Min"}; + Configurable cAxisVxMax{"cAxisVxMax", 0.01, "Vx Max"}; Configurable cAxisVyMin{"cAxisVyMin", -0.01, "Vy Min"}; - Configurable cAxisVyMax{"cAxisVyMax", 0.006, "Vy Max"}; + Configurable cAxisVyMax{"cAxisVyMax", 0.01, "Vy Max"}; + Configurable cRecentVxVy{"cRecentVxVy", true, "Vx / Vy recentering"}; // Corrections - Configurable cApplyRecentCorr{"cApplyRecentCorr", false, "Apply recentering"}; - Configurable> cCorrFlagVector{"cCorrFlagVector", {0, 0, 0, 0, 0, 0}, "Correction Flag"}; + Configurable cLoadCorrection{"cLoadCorrection", true, "Load corrections"}; + Configurable cDoGainCalib{"cDoGainCalib", true, "Gain Calib Flag"}; + Configurable cUseAlphaZDC{"cUseAlphaZDC", true, "Use Alpha ZDC"}; + Configurable cApplyRecentCorr{"cApplyRecentCorr", true, "Apply recentering"}; + Configurable> cCorrFlagVector{"cCorrFlagVector", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, "Correction Flag"}; // CCDB Configurable cCcdbUrl{"cCcdbUrl", "http://ccdb-test.cern.ch:8080", "url of ccdb"}; @@ -228,9 +372,11 @@ struct SpectatorPlaneTableProducer { // Container for histograms struct CorrectionHistContainer { + TProfile* hVx; + TProfile* hVy; std::array hGainCalib; - std::array, 4>, 6> vCoarseCorrHist; - std::array, 4>, 6> vFineCorrHist; + std::array, 4>, 14> vCoarseCorrHist; + std::array, 4>, 14> vFineCorrHist; } CorrectionHistContainer; // Run number @@ -276,6 +422,10 @@ struct SpectatorPlaneTableProducer { histos.add("Event/hVy", "V_{y}", kTH1F, {axisVy}); histos.add("Event/hVz", "V_{z}", kTH1F, {axisVz}); + // Vx / Vy Recent + histos.add("Event/hVxVsCent", " Vs Cent", kTProfile, {axisCent}); + histos.add("Event/hVyVsCent", " Vs Cent", kTProfile, {axisCent}); + // Gain calib histos.add("QA/GainCalib/hZNASignal", "ZNA Signal", kTH2F, {{4, 0, 4}, {axisZDCEnergy}}); histos.add("QA/GainCalib/hZNCSignal", "ZNC Signal", kTH2F, {{4, 0, 4}, {axisZDCEnergy}}); @@ -324,6 +474,7 @@ struct SpectatorPlaneTableProducer { histos.add("DF/hQaQc", "X^{A}_{1}X^{C}_{1} + Y^{A}_{1}Y^{C}_{1}", kTProfile, {axisCent}); } + // Select collsion template bool selCollision(C const& col) { @@ -344,22 +495,6 @@ struct SpectatorPlaneTableProducer { return false; } - if (cTriggerTvxSel && !col.selection_bit(aod::evsel::kIsTriggerTVX)) { // Time and Vertex trigger - return false; - } - - if (cTFBorder && !col.selection_bit(aod::evsel::kNoTimeFrameBorder)) { // Time frame border - return false; - } - - if (cNoItsROBorder && !col.selection_bit(aod::evsel::kNoITSROFrameBorder)) { // ITS Readout frame border - return false; - } - - if (cItsTpcVtx && !col.selection_bit(aod::evsel::kIsVertexITSTPC)) { // ITS+TPC Vertex - return false; - } - if (cPileupReject && !col.selection_bit(aod::evsel::kNoSameBunchPileup)) { // Pile-up rejection return false; } @@ -373,7 +508,7 @@ struct SpectatorPlaneTableProducer { } // Set Multiplicity - mult = col.multNTracksHasTPC(); + mult = col.multTPC(); return true; } @@ -381,6 +516,14 @@ struct SpectatorPlaneTableProducer { // Load Gain Calibrations and ZDC Q-Vector Recentering Corrections void loadCorrections() { + // Load Vx / Vy recentering + if (cRecentVxVy) { + std::string ccdbPath = static_cast(cCcdbPath) + "/VxVyRecent" + "/Run" + std::to_string(cRunNum); + auto ccdbObj = ccdbService->getForTimeStamp(ccdbPath, nolaterthan.value); + CorrectionHistContainer.hVx = reinterpret_cast(ccdbObj->FindObject("hVx")); + CorrectionHistContainer.hVy = reinterpret_cast(ccdbObj->FindObject("hVy")); + } + // Load ZDC gain calibration if (cDoGainCalib) { std::string ccdbPath = static_cast(cCcdbPath) + "/GainCalib" + "/Run" + std::to_string(cRunNum); @@ -444,8 +587,8 @@ struct SpectatorPlaneTableProducer { { float vA = 0., vC = 0.; for (int i = 0; i < static_cast(eA.size()); ++i) { - vA = CorrectionHistContainer.hGainCalib[0]->GetBinContent(CorrectionHistContainer.hGainCalib[0]->FindBin(i + 0.5, vz + 0.00001)); - vC = CorrectionHistContainer.hGainCalib[1]->GetBinContent(CorrectionHistContainer.hGainCalib[1]->FindBin(i + 0.5, vz + 0.00001)); + vA = CorrectionHistContainer.hGainCalib[0]->GetBinContent(CorrectionHistContainer.hGainCalib[0]->FindBin(i + 0.5, vz)); + vC = CorrectionHistContainer.hGainCalib[1]->GetBinContent(CorrectionHistContainer.hGainCalib[1]->FindBin(i + 0.5, vz)); eA[i] *= vA; eC[i] *= vC; } @@ -459,10 +602,10 @@ struct SpectatorPlaneTableProducer { int cntrx = 0; for (auto const& v : CorrectionHistContainer.vCoarseCorrHist[itr]) { for (auto const& h : v) { - binarray[kCent] = h->GetAxis(kCent)->FindBin(vCollParam[kCent] + 0.0001); - binarray[kVx] = h->GetAxis(kVx)->FindBin(vCollParam[kVx] + 0.0001); - binarray[kVy] = h->GetAxis(kVy)->FindBin(vCollParam[kVy] + 0.0001); - binarray[kVz] = h->GetAxis(kVz)->FindBin(vCollParam[kVz] + 0.0001); + binarray[kCent] = h->GetAxis(kCent)->FindBin(vCollParam[kCent]); + binarray[kVx] = h->GetAxis(kVx)->FindBin(vCollParam[kVx]); + binarray[kVy] = h->GetAxis(kVy)->FindBin(vCollParam[kVy]); + binarray[kVz] = h->GetAxis(kVz)->FindBin(vCollParam[kVz]); vAvgOutput[cntrx] += h->GetBinContent(h->GetBin(binarray)); } ++cntrx; @@ -472,7 +615,7 @@ struct SpectatorPlaneTableProducer { for (auto const& v : CorrectionHistContainer.vFineCorrHist[itr]) { int cntry = 0; for (auto const& h : v) { - vAvgOutput[cntrx] += h->GetBinContent(h->GetXaxis()->FindBin(vCollParam[cntry] + 0.0001)); + vAvgOutput[cntrx] += h->GetBinContent(h->GetXaxis()->FindBin(vCollParam[cntry])); ++cntry; } ++cntrx; @@ -482,7 +625,7 @@ struct SpectatorPlaneTableProducer { return vAvgOutput; } - void applyCorrection(std::array const& inputParam, std::array& outputParam) + void applyCorrection(const std::array& inputParam, std::array& outputParam) { std::vector vCorrFlags = static_cast>(cCorrFlagVector); int nitr = vCorrFlags.size(); @@ -505,7 +648,7 @@ struct SpectatorPlaneTableProducer { // Get averages std::vector vAvg = getAvgCorrFactors(i, corrType, inputParam); - // Apply correction + // Apply recentering outputParam[kXa] -= vAvg[kXa]; outputParam[kYa] -= vAvg[kYa]; outputParam[kXc] -= vAvg[kXc]; @@ -544,6 +687,11 @@ struct SpectatorPlaneTableProducer { template bool analyzeCollision(B const& bc, C const& collision, std::array& vSP) { + // Check ZDC + if (!bc.has_zdc()) { + return false; + } + // Event selection if (!selCollision(collision)) { return false; @@ -553,34 +701,40 @@ struct SpectatorPlaneTableProducer { posZ = collision.posZ(); std::array vCollParam = {cent, posX, posY, posZ}; - // Fill event QA - histos.fill(HIST("Event/hCent"), cent); - histos.fill(HIST("Event/hVx"), posX); - histos.fill(HIST("Event/hVy"), posY); - histos.fill(HIST("Event/hVz"), posZ); - - // check zdc - if (!bc.has_zdc()) { - return false; - } - + // Zdc information auto zdc = bc.zdc(); auto znaEnergy = zdc.energySectorZNA(); auto zncEnergy = zdc.energySectorZNC(); auto znaEnergyCommon = zdc.energyCommonZNA(); auto zncEnergyCommon = zdc.energyCommonZNC(); - // check energy deposits + // Check energy deposits if (znaEnergyCommon <= 0 || zncEnergyCommon <= 0 || znaEnergy[0] <= 0 || znaEnergy[1] <= 0 || znaEnergy[2] <= 0 || znaEnergy[3] <= 0 || zncEnergy[0] <= 0 || zncEnergy[1] <= 0 || zncEnergy[2] <= 0 || zncEnergy[3] <= 0) { return false; } + // Selected Collision with required ZDC + // Fill avg Vx / Vy + histos.fill(HIST("Event/hVxVsCent"), cent, posX); + histos.fill(HIST("Event/hVyVsCent"), cent, posY); + + // Apply Vx / Vy recentering + if (cRecentVxVy) { + vCollParam[kVx] -= CorrectionHistContainer.hVx->GetBinContent(CorrectionHistContainer.hVx->FindBin(cent)); + vCollParam[kVy] -= CorrectionHistContainer.hVy->GetBinContent(CorrectionHistContainer.hVy->FindBin(cent)); + } + + // Apply Vx / Vy selection [-10., 10.] mm + if (std::abs(vCollParam[kVx]) >= cAxisVxMax || std::abs(vCollParam[kVy]) >= cAxisVyMax) { + return false; + } + // Fill gain calib histograms + histos.fill(HIST("QA/hZNAEnergyCommon"), vCollParam[kVz], znaEnergyCommon); + histos.fill(HIST("QA/hZNCEnergyCommon"), vCollParam[kVz], zncEnergyCommon); for (int iCh = 0; iCh < kXYAC; ++iCh) { histos.fill(HIST("QA/hZNASignal"), iCh + 0.5, vCollParam[kVz], znaEnergy[iCh]); histos.fill(HIST("QA/hZNCSignal"), iCh + 0.5, vCollParam[kVz], zncEnergy[iCh]); - histos.fill(HIST("QA/hZNAEnergyCommon"), vCollParam[kVz], znaEnergyCommon); - histos.fill(HIST("QA/hZNCEnergyCommon"), vCollParam[kVz], zncEnergyCommon); } // Do gain calibration @@ -594,6 +748,12 @@ struct SpectatorPlaneTableProducer { histos.fill(HIST("QA/GainCalib/hZNCSignal"), iCh + 0.5, zncEnergy[iCh]); } + // Fill event QA + histos.fill(HIST("Event/hCent"), vCollParam[kCent]); + histos.fill(HIST("Event/hVx"), vCollParam[kVx]); + histos.fill(HIST("Event/hVy"), vCollParam[kVy]); + histos.fill(HIST("Event/hVz"), vCollParam[kVz]); + auto alphaZDC = 0.395; const double x[4] = {-1.75, 1.75, -1.75, 1.75}; const double y[4] = {-1.75, -1.75, 1.75, 1.75}; @@ -703,8 +863,12 @@ struct SpectatorPlaneTableProducer { } using BCsRun3 = soa::Join; - using CollisionsRun3 = soa::Join; - using Tracks = soa::Join; + using CollisionsRun3 = soa::Join; + using Tracks = soa::Join; + + void processDummy(CollisionsRun3::iterator const&) {} + + PROCESS_SWITCH(SpectatorPlaneTableProducer, processDummy, "Dummy process", true); void processSpectatorPlane(CollisionsRun3::iterator const& collision, BCsRun3 const&, aod::Zdcs const&) { @@ -712,7 +876,7 @@ struct SpectatorPlaneTableProducer { auto bc = collision.template foundBC_as(); cRunNum = collision.template foundBC_as().runNumber(); - if (lRunNum != cRunNum) { + if (cLoadCorrection && lRunNum != cRunNum) { loadCorrections(); } @@ -746,7 +910,7 @@ struct SpectatorPlaneTableProducer { colSPExtTable(colSPExtFlag, vSP[kXa], vSP[kYa], vSP[kXc], vSP[kYc]); } - PROCESS_SWITCH(SpectatorPlaneTableProducer, processSpectatorPlane, "Spectator Plane Process", true); + PROCESS_SWITCH(SpectatorPlaneTableProducer, processSpectatorPlane, "Spectator Plane Process", false); void processIdHadrons(Tracks const& tracks) { @@ -764,7 +928,8 @@ struct SpectatorPlaneTableProducer { struct FlowEventPlane { // Tracks - Configurable cNEtaBins{"cNEtaBins", 5, "# of eta bins"}; + Configurable cEtaBins{"cEtaBins", 5, "# of eta bins"}; + Configurable cEtaCut{"cEtaCut", 0.8, "Rapidity cut"}; // Pi,Ka,Pr Configurable cMinPtPi{"cMinPtPi", 0.2, "Pion min pT"}; @@ -772,10 +937,7 @@ struct FlowEventPlane { Configurable cMinPtPr{"cMinPtPr", 0.5, "Proton min pT"}; // Resonance - Configurable cNRapBins{"cNRapBins", 5, "# of y bins"}; Configurable cPhiInvMassBins{"cPhiInvMassBins", 500, "# of Phi mass bins"}; - Configurable cKStarInvMassBins{"cKStarInvMassBins", 200, "# of Phi mass bins"}; - Configurable cResRapCut{"cResRapCut", 0.5, "Resonance rapidity cut"}; // V0 // Tracks @@ -788,15 +950,13 @@ struct FlowEventPlane { Configurable cMinDcaProtonToPV{"cMinDcaProtonToPV", 0.01, "Minimum Proton DCAr to PV"}; Configurable cMinDcaPionToPV{"cMinDcaPionToPV", 0.1, "Minimum Pion DCAr to PV"}; Configurable cDcaV0Dau{"cDcaV0Dau", 1., "DCA between V0 daughters"}; - Configurable cDcaV0ToPv{"cDcaV0ToPv", 0.1, "DCA V0 to PV"}; Configurable cMinV0Radius{"cMinV0Radius", 0.5, "Minimum V0 radius from PV"}; Configurable cK0ShortCTau{"cK0ShortCTau", 20.0, "Decay length cut K0Short"}; Configurable cLambdaCTau{"cLambdaCTau", 30.0, "Decay length cut Lambda"}; - Configurable cK0ShortCosPA{"cK0ShortCosPA", 0.998, "K0Short CosPA"}; - Configurable cLambdaCosPA{"cLambdaCosPA", 0.998, "Lambda CosPA"}; + Configurable cK0ShortCosPA{"cK0ShortCosPA", 0.97, "K0Short CosPA"}; + Configurable cLambdaCosPA{"cLambdaCosPA", 0.98, "Lambda CosPA"}; Configurable cK0SMassRej{"cK0SMassRej", 0.01, "Reject K0Short Candidates"}; Configurable cArmPodSel{"cArmPodSel", 0.2, "Armentros-Podolanski Selection for K0S"}; - Configurable cV0RapCut{"cV0RapCut", 0.8, "V0 rap cut"}; Configurable cK0SMinPt{"cK0SMinPt", 0.4, "K0S Min pT"}; Configurable cK0SMaxPt{"cK0SMaxPt", 6.0, "K0S Max pT"}; Configurable cLambdaMinPt{"cLambdaMinPt", 0.6, "Lambda Min pT"}; @@ -810,8 +970,6 @@ struct FlowEventPlane { std::array vSP = {0., 0., 0., 0.}; std::map> mResoDauMass = {{kPhi0, {MassKaonCharged, MassKaonCharged}}, {kKStar, {MassPionCharged, MassKaonCharged}}}; std::map mResoMass = {{kPhi0, MassPhi}, {kKStar, MassKaonCharged}}; - std::map mV0Ctau = {{kK0S, cK0ShortCTau}, {kLambda, cLambdaCTau}, {kAntiLambda, cLambdaCTau}}; - std::map mV0CosPA = {{kK0S, cK0ShortCosPA}, {kLambda, cLambdaCosPA}, {kAntiLambda, cLambdaCosPA}}; void init(InitContext const&) { @@ -822,14 +980,13 @@ struct FlowEventPlane { const AxisSpec axisV1{400, -4, 4, "v_{1}"}; const AxisSpec axisTrackPt{100, 0., 10., "p_{T} (GeV/#it{c})"}; - const AxisSpec axisTrackEta{cNEtaBins, -0.8, 0.8, "#eta"}; + const AxisSpec axisTrackEta{cEtaBins, -0.8, 0.8, "#eta"}; const AxisSpec axisTrackDcaXY{60, -0.15, 0.15, "DCA_{XY}"}; const AxisSpec axisTrackDcaZ{230, -1.15, 1.15, "DCA_{XY}"}; const AxisSpec axisTrackdEdx{360, 20, 200, "#frac{dE}{dx}"}; const AxisSpec axisTrackNSigma{161, -4.025, 4.025, {"n#sigma"}}; const AxisSpec axisPhiInvMass{cPhiInvMassBins, 0.99, 1.12, "M_{KK} (GeV/#it{c}^{2}"}; - const AxisSpec axisKStarInvMass{cKStarInvMassBins, 0.8, 1.2, "M_{#piK} (GeV/#it{c}^{2}"}; const AxisSpec axisMomPID(80, 0, 4, "p_{T} (GeV/#it{c})"); const AxisSpec axisNsigma(401, -10.025, 10.025, {"n#sigma"}); const AxisSpec axisdEdx(360, 20, 200, "#frac{dE}{dx}"); @@ -881,12 +1038,6 @@ struct FlowEventPlane { histos.add("Reso/Phi/Sig/hQuC", "hPhiQuC", kTProfile3D, {axisCent, axisTrackEta, axisPhiInvMass}); histos.add("Reso/Phi/Bkg/hQuA", "hPhiQuA", kTProfile3D, {axisCent, axisTrackEta, axisPhiInvMass}); histos.add("Reso/Phi/Bkg/hQuC", "hPhiQuC", kTProfile3D, {axisCent, axisTrackEta, axisPhiInvMass}); - histos.add("Reso/KStar/hSigCentEtaInvMass", "hUSCentEtaInvMass", kTH3F, {axisCent, axisTrackEta, axisKStarInvMass}); - histos.add("Reso/KStar/hBkgCentEtaInvMass", "hLSCentEtaInvMass", kTH3F, {axisCent, axisTrackEta, axisKStarInvMass}); - histos.add("Reso/KStar/Sig/hQuA", "hKStarQuA", kTProfile3D, {axisCent, axisTrackEta, axisKStarInvMass}); - histos.add("Reso/KStar/Sig/hQuC", "hKStarQuC", kTProfile3D, {axisCent, axisTrackEta, axisKStarInvMass}); - histos.add("Reso/KStar/Bkg/hQuA", "hKStarQuA", kTProfile3D, {axisCent, axisTrackEta, axisKStarInvMass}); - histos.add("Reso/KStar/Bkg/hQuC", "hKStarQuC", kTProfile3D, {axisCent, axisTrackEta, axisKStarInvMass}); } // Lambda @@ -906,12 +1057,12 @@ struct FlowEventPlane { histos.add("V0/Lambda/QA/hPosNsigPiVsP", "TPC n#sigma Pos Prong", kTH2F, {axisMomPID, axisNsigma}); histos.add("V0/Lambda/QA/hNegNsigPiVsP", "TPC n#sigma Neg Prong", kTH2F, {axisMomPID, axisNsigma}); histos.addClone("V0/Lambda/", "V0/K0Short/"); - histos.add("V0/Lambda/hMassVsRap", "hMassVsRap", kTH3F, {axisCent, axisLambdaInvMass, axisTrackEta}); + histos.add("V0/Lambda/hMassVsRap", "hMassVsRap", kTH3F, {axisCent, axisTrackEta, axisLambdaInvMass}); histos.add("V0/Lambda/Flow/hQuA", "hQuA", kTProfile3D, {axisCent, axisTrackEta, axisLambdaInvMass}); histos.add("V0/Lambda/Flow/hQuC", "hQuC", kTProfile3D, {axisCent, axisTrackEta, axisLambdaInvMass}); histos.addClone("V0/Lambda/", "V0/AntiLambda/"); histos.addClone("V0/Lambda/", "V0/LambdaAntiLambda/"); - histos.add("V0/K0Short/hMassVsRap", "hMassVsRap", kTH3F, {axisCent, axisK0ShortInvMass, axisTrackEta}); + histos.add("V0/K0Short/hMassVsRap", "hMassVsRap", kTH3F, {axisCent, axisTrackEta, axisK0ShortInvMass}); histos.add("V0/K0Short/Flow/hQuA", "hQuA", kTProfile3D, {axisCent, axisTrackEta, axisK0ShortInvMass}); histos.add("V0/K0Short/Flow/hQuC", "hQuC", kTProfile3D, {axisCent, axisTrackEta, axisK0ShortInvMass}); } @@ -1086,7 +1237,7 @@ struct FlowEventPlane { // Apply pseudo-rapidity acceptance std::array v = {track1.px() + track2.px(), track1.py() + track2.py(), track1.pz() + track2.pz()}; - if (std::abs(RecoDecay::eta(v)) >= cResRapCut) { + if (std::abs(RecoDecay::eta(v)) >= cEtaCut) { continue; } @@ -1128,8 +1279,8 @@ struct FlowEventPlane { } using CollisionsRun3 = soa::Join; - using Tracks = soa::Join; - using TracksV0s = soa::Join; + using Tracks = soa::Join; + using TracksV0s = soa::Join; // Partitions SliceCache cache; @@ -1138,7 +1289,7 @@ struct FlowEventPlane { Partition kaonTrackPartition = (aod::tracksid::isCharged == true) && (aod::tracksid::isKaon == true); Partition protonTrackPartition = (aod::tracksid::isCharged == true) && (aod::tracksid::isProton == true); - void processDummy(CollisionsRun3::iterator const&) {} + void processDummy(aod::Collisions const&) {} PROCESS_SWITCH(FlowEventPlane, processDummy, "Dummy process", true); @@ -1201,12 +1352,10 @@ struct FlowEventPlane { } // Track partitions - auto pionTracks = pionTrackPartition->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto kaonTracks = kaonTrackPartition->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); // Resonance flow getResoFlow(kaonTracks, kaonTracks, vSP); - getResoFlow(pionTracks, kaonTracks, vSP); } PROCESS_SWITCH(FlowEventPlane, processResoFlow, "Resonance flow process", false); @@ -1219,7 +1368,7 @@ struct FlowEventPlane { // Loop over v0s for (auto const& v0 : V0s) { // Topological and kinematic selections - if (std::abs(v0.eta()) >= cV0RapCut || v0.dcaV0daughters() >= cDcaV0Dau || v0.dcav0topv() >= cDcaV0ToPv || v0.v0radius() <= cMinV0Radius || v0.v0Type() != cV0TypeSelection) { + if (std::abs(v0.eta()) >= cEtaCut || v0.dcaV0daughters() >= cDcaV0Dau || v0.v0radius() <= cMinV0Radius || v0.v0Type() != cV0TypeSelection) { continue; } @@ -1236,31 +1385,31 @@ struct FlowEventPlane { float ctauLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * MassLambda0; // K0Short - if (selV0DauTracks(v0, postrack, negtrack) && v0.v0cosPA() > mV0CosPA.at(kK0S) && ctauK0Short < mV0Ctau.at(kK0S) && v0.qtarm() >= cArmPodSel * std::abs(v0.alpha()) && v0.pt() >= cK0SMinPt && v0.pt() < cK0SMaxPt) { + if (selV0DauTracks(v0, postrack, negtrack) && v0.v0cosPA() > cK0ShortCosPA && ctauK0Short < cK0ShortCTau && v0.qtarm() >= cArmPodSel * std::abs(v0.alpha()) && v0.pt() >= cK0SMinPt && v0.pt() < cK0SMaxPt) { fillV0QAHist(collision, v0, tracks); - histos.fill(HIST("V0/K0Short/hMassVsRap"), cent, v0.mK0Short(), v0.eta()); + histos.fill(HIST("V0/K0Short/hMassVsRap"), cent, v0.eta(), v0.mK0Short()); histos.fill(HIST("V0/K0Short/Flow/hQuA"), cent, v0.eta(), v0.mK0Short(), v1a); histos.fill(HIST("V0/K0Short/Flow/hQuC"), cent, v0.eta(), v0.mK0Short(), v1c); } // Lambda - if (selV0DauTracks(v0, postrack, negtrack) && v0.v0cosPA() > mV0CosPA.at(kLambda) && ctauLambda < mV0Ctau.at(kLambda) && std::abs(v0.mK0Short() - MassK0Short) >= cK0SMassRej && v0.pt() >= cLambdaMinPt && v0.pt() < cLambdaMaxPt) { + if (selV0DauTracks(v0, postrack, negtrack) && v0.v0cosPA() > cLambdaCosPA && ctauLambda < cLambdaCTau && std::abs(v0.mK0Short() - MassK0Short) >= cK0SMassRej && v0.qtarm() < cArmPodSel * std::abs(v0.alpha()) && v0.alpha() > 0 && v0.pt() >= cLambdaMinPt && v0.pt() < cLambdaMaxPt) { fillV0QAHist(collision, v0, tracks); - histos.fill(HIST("V0/Lambda/hMassVsRap"), cent, v0.mLambda(), v0.eta()); + histos.fill(HIST("V0/Lambda/hMassVsRap"), cent, v0.eta(), v0.mLambda()); histos.fill(HIST("V0/Lambda/Flow/hQuA"), cent, v0.eta(), v0.mLambda(), v1a); histos.fill(HIST("V0/Lambda/Flow/hQuC"), cent, v0.eta(), v0.mLambda(), v1c); - histos.fill(HIST("V0/LambdaAntiLambda/hMassVsRap"), cent, v0.mLambda(), v0.eta()); + histos.fill(HIST("V0/LambdaAntiLambda/hMassVsRap"), cent, v0.eta(), v0.mLambda()); histos.fill(HIST("V0/LambdaAntiLambda/Flow/hQuA"), cent, v0.eta(), v0.mLambda(), v1a); histos.fill(HIST("V0/LambdaAntiLambda/Flow/hQuC"), cent, v0.eta(), v0.mLambda(), v1c); } // AntiLambda - if (selV0DauTracks(v0, postrack, negtrack) && v0.v0cosPA() > mV0CosPA.at(kAntiLambda) && ctauLambda < mV0Ctau.at(kAntiLambda) && std::abs(v0.mK0Short() - MassK0Short) >= cK0SMassRej && v0.pt() >= cLambdaMinPt && v0.pt() < cLambdaMaxPt) { + if (selV0DauTracks(v0, postrack, negtrack) && v0.v0cosPA() > cLambdaCosPA && ctauLambda < cLambdaCTau && std::abs(v0.mK0Short() - MassK0Short) >= cK0SMassRej && v0.qtarm() < cArmPodSel * std::abs(v0.alpha()) && v0.alpha() < 0 && v0.pt() >= cLambdaMinPt && v0.pt() < cLambdaMaxPt) { fillV0QAHist(collision, v0, tracks); - histos.fill(HIST("V0/AntiLambda/hMassVsRap"), cent, v0.mAntiLambda(), v0.eta()); + histos.fill(HIST("V0/AntiLambda/hMassVsRap"), cent, v0.eta(), v0.mAntiLambda()); histos.fill(HIST("V0/AntiLambda/Flow/hQuA"), cent, v0.eta(), v0.mAntiLambda(), v1a); histos.fill(HIST("V0/AntiLambda/Flow/hQuC"), cent, v0.eta(), v0.mAntiLambda(), v1c); - histos.fill(HIST("V0/LambdaAntiLambda/hMassVsRap"), cent, v0.mAntiLambda(), v0.eta()); + histos.fill(HIST("V0/LambdaAntiLambda/hMassVsRap"), cent, v0.eta(), v0.mAntiLambda()); histos.fill(HIST("V0/LambdaAntiLambda/Flow/hQuA"), cent, v0.eta(), v0.mAntiLambda(), v1a); histos.fill(HIST("V0/LambdaAntiLambda/Flow/hQuC"), cent, v0.eta(), v0.mAntiLambda(), v1c); } @@ -1272,6 +1421,7 @@ struct FlowEventPlane { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ + adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc)}; } diff --git a/PWGCF/Flow/Tasks/flowFlucGfwPp.cxx b/PWGCF/Flow/Tasks/flowFlucGfwPp.cxx index b481ac7068b..9a253ab83b8 100644 --- a/PWGCF/Flow/Tasks/flowFlucGfwPp.cxx +++ b/PWGCF/Flow/Tasks/flowFlucGfwPp.cxx @@ -121,7 +121,7 @@ struct FlowFlucGfwPp { O2_DEFINE_CONFIGURABLE(cfgNbootstrap, int, 10, "Number of subsamples") O2_DEFINE_CONFIGURABLE(cfgIsMC, bool, false, "Is MC event") - O2_DEFINE_CONFIGURABLE(cfgCentEstimator, int, 0, "0:FT0C; 1:FT0CVariant1; 2:FT0M; 3:FV0A, 4:NTPV, 5:NGlobals, 6:MFT") + O2_DEFINE_CONFIGURABLE(cfgCentEstimator, int, 0, "0:FT0C; 1:FT0CVariant1; 2:FT0M; 3:FV0A, 4:NTPV, 5:NGlobals") O2_DEFINE_CONFIGURABLE(cfgUseNch, bool, false, "Do correlations as function of Nch") O2_DEFINE_CONFIGURABLE(cfgQvecQA, bool, false, "Enable filling QA for q-Vec of TPC") O2_DEFINE_CONFIGURABLE(cfgFillWeights, bool, false, "Fill NUA weights") @@ -171,6 +171,7 @@ struct FlowFlucGfwPp { O2_DEFINE_CONFIGURABLE(cfgUseNegativeEtaHalfForq2, bool, true, "If true, use -eta half for qn selection; otherwise use +eta half"); O2_DEFINE_CONFIGURABLE(cfgQnSelectionHarmonic, int, 2, "Harmonic n used to build the reduced q_n vector for event shape selection, use 2 for q2 and 3 for q3"); O2_DEFINE_CONFIGURABLE(cfgQnHistMax, float, 6., "Upper range for q_n calibration histograms"); + O2_DEFINE_CONFIGURABLE(cfgQnTrkAbsEtaMax, float, 0.5, "Upper range for abs eta of tracks contributing to q_n"); O2_DEFINE_CONFIGURABLE(cfgBypassQnSelection, bool, false, "Bypass q_n event shape selection and fill one integral q-bin"); O2_DEFINE_CONFIGURABLE(cfgMinPtOnTPC, float, 0.2, "minimum transverse momentum selection for TPC tracks participating in Q-vector reconstruction"); O2_DEFINE_CONFIGURABLE(cfgMaxPtOnTPC, float, 5., "maximum transverse momentum selection for TPC tracks participating in Q-vector reconstruction"); @@ -277,8 +278,7 @@ struct FlowFlucGfwPp { kCentFT0M, kCentFV0A, kCentNTPV, - kCentNGlobal, - kCentMFT + kCentNGlobal }; enum EventSelFlags { kFilteredEvent = 1, @@ -337,11 +337,11 @@ struct FlowFlucGfwPp { o2::framework::expressions::Filter collisionFilter = nabs(aod::collision::posZ) < cfgVtxZ; o2::framework::expressions::Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && (aod::track::itsChi2NCl < cfgChi2PrITSCls) && (aod::track::tpcChi2NCl < cfgChi2PrTPCCls) && nabs(aod::track::dcaZ) < cfgDCAz; - Preslice perCollision = aod::track::collisionId; o2::framework::expressions::Filter mcCollFilter = nabs(aod::mccollision::posZ) < cfgVtxZ; o2::framework::expressions::Filter mcParticlesFilter = (aod::mcparticle::eta > o2::analysis::gfwflowflucpp::etalow && aod::mcparticle::eta < o2::analysis::gfwflowflucpp::etaup && aod::mcparticle::pt > o2::analysis::gfwflowflucpp::ptlow && aod::mcparticle::pt < o2::analysis::gfwflowflucpp::ptup); using GFWTracks = soa::Filtered>; + using GFWTracksMC = soa::Filtered>; void init(InitContext const&) { @@ -415,8 +415,7 @@ struct FlowFlucGfwPp { {kCentFT0M, "FT0M"}, {kCentFV0A, "FV0A"}, {kCentNTPV, "NTPV"}, - {kCentNGlobal, "NGlobals"}, - {kCentMFT, "MFT"}}; + {kCentNGlobal, "NGlobals"}}; sCentralityEstimator = centEstimatorMap.at(cfgCentEstimator); sCentralityEstimator += " centrality (%)"; AxisSpec centAxis = {o2::analysis::gfwflowflucpp::centbinning, sCentralityEstimator.c_str()}; @@ -503,7 +502,7 @@ struct FlowFlucGfwPp { } } - if (doprocessData) { + if (doprocessData || doprocessMC) { registry.add("trackQA/before/phi_eta_vtxZ", "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); registry.add("trackQA/before/pt_dcaXY_dcaZ", "", {HistType::kTH3D, {ptAxis, dcaXYAXis, dcaZAXis}}); registry.add("trackQA/before/nch_pt", "#it{p}_{T} vs multiplicity; N_{ch}; #it{p}_{T}", {HistType::kTH2D, {nchAxis, ptAxis}}); @@ -530,24 +529,20 @@ struct FlowFlucGfwPp { registry.add("eventQA/before/globalTracks_multV0A", "", {HistType::kTH2D, {v0aAxis, nchAxis}}); registry.add("eventQA/before/multV0A_multT0A", "", {HistType::kTH2D, {t0aAxis, v0aAxis}}); - if (doprocessData) { - registry.add("eventQA/before/centrality", "", {HistType::kTH1D, {centAxis}}); - registry.add("eventQA/before/globalTracks_centT0C", "", {HistType::kTH2D, {centAxis, nchAxis}}); - registry.add("eventQA/before/PVTracks_centT0C", "", {HistType::kTH2D, {centAxis, multpvAxis}}); - registry.add("eventQA/before/multT0C_centT0C", "", {HistType::kTH2D, {centAxis, t0cAxis}}); - - registry.add("eventQA/before/centT0M_centT0C", "", {HistType::kTH2D, {centAxis, centAxis}}); - registry.add("eventQA/before/centV0A_centT0C", "", {HistType::kTH2D, {centAxis, centAxis}}); - registry.add("eventQA/before/centGlobal_centT0C", "", {HistType::kTH2D, {centAxis, centAxis}}); - registry.add("eventQA/before/centNTPV_centT0C", "", {HistType::kTH2D, {centAxis, centAxis}}); - registry.add("eventQA/before/centMFT_centT0C", "", {HistType::kTH2D, {centAxis, centAxis}}); - - if (cfgIsMC) { - registry.add("MCGen/trackQA/phi_eta_vtxZ", "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); - registry.add("MCGen/trackQA/nch_pt", "#it{p}_{T} vs multiplicity; N_{ch}; #it{p}_{T}", {HistType::kTH2D, {nchAxis, ptAxis}}); - registry.add("MCGen/trackQA/pt_ref", "", {HistType::kTH1D, {{100, o2::analysis::gfwflowflucpp::ptreflow, o2::analysis::gfwflowflucpp::ptrefup}}}); - registry.add("MCGen/trackQA/pt_poi", "", {HistType::kTH1D, {{100, o2::analysis::gfwflowflucpp::ptpoilow, o2::analysis::gfwflowflucpp::ptpoiup}}}); - } + registry.add("eventQA/before/centrality", "", {HistType::kTH1D, {centAxis}}); + registry.add("eventQA/before/globalTracks_centT0C", "", {HistType::kTH2D, {centAxis, nchAxis}}); + registry.add("eventQA/before/PVTracks_centT0C", "", {HistType::kTH2D, {centAxis, multpvAxis}}); + registry.add("eventQA/before/multT0C_centT0C", "", {HistType::kTH2D, {centAxis, t0cAxis}}); + + registry.add("eventQA/before/centT0M_centT0C", "", {HistType::kTH2D, {centAxis, centAxis}}); + registry.add("eventQA/before/centV0A_centT0C", "", {HistType::kTH2D, {centAxis, centAxis}}); + registry.add("eventQA/before/centGlobal_centT0C", "", {HistType::kTH2D, {centAxis, centAxis}}); + registry.add("eventQA/before/centNTPV_centT0C", "", {HistType::kTH2D, {centAxis, centAxis}}); + if (cfgIsMC || doprocessMC) { + registry.add("MCGen/trackQA/phi_eta_vtxZ", "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); + registry.add("MCGen/trackQA/nch_pt", "#it{p}_{T} vs multiplicity; N_{ch}; #it{p}_{T}", {HistType::kTH2D, {nchAxis, ptAxis}}); + registry.add("MCGen/trackQA/pt_ref", "", {HistType::kTH1D, {{100, o2::analysis::gfwflowflucpp::ptreflow, o2::analysis::gfwflowflucpp::ptrefup}}}); + registry.add("MCGen/trackQA/pt_poi", "", {HistType::kTH1D, {{100, o2::analysis::gfwflowflucpp::ptpoilow, o2::analysis::gfwflowflucpp::ptpoiup}}}); } registry.addClone("eventQA/before/", "eventQA/after/"); @@ -1020,14 +1015,14 @@ struct FlowFlucGfwPp { registry.fill(HIST("qvecQA/ChTracks"), trk.pt(), trk.eta(), trk.phi()); } - if (trk.eta() > 0) { + if (trk.eta() > 0 && std::fabs(trk.eta()) < cfgQnTrkAbsEtaMax) { // In qVectorsTable this branch is additionally guarded by useDetector["QvectorTPCposs"] || useDetector["QvectorBPoss"]. // Here TPCpos is always computed because the downstream ESE selector can require it. qvec.qVectTPCPos[0] += trk.pt() * std::cos(trk.phi() * nMode); qvec.qVectTPCPos[1] += trk.pt() * std::sin(trk.phi() * nMode); qvec.trkTPCPosLabel.push_back(trk.globalIndex()); qvec.nTrkTPCPos++; - } else if (trk.eta() < 0) { + } else if (trk.eta() < 0 && std::fabs(trk.eta()) < cfgQnTrkAbsEtaMax) { // In qVectorsTable this branch is additionally guarded by useDetector["QvectorTPCnegs"] || useDetector["QvectorBNegs"]. // Here TPCneg is always computed because the downstream ESE selector can require it. qvec.qVectTPCNeg[0] += trk.pt() * std::cos(trk.phi() * nMode); @@ -1172,6 +1167,48 @@ struct FlowFlucGfwPp { lRandom, qPtmp, run); } + template + void processGenCollision(TCollision collision, TParticles particles, const int& mcCollisionId, const XAxis& xaxis, const int& run, const int& qPtmp) + { + if (xaxis.multiplicity < cfgFixedMultMin || xaxis.multiplicity > cfgFixedMultMax) + return; + + if (cfgFillQA && xaxis.centrality >= 0) + registry.fill(HIST("eventQA/after/centrality"), xaxis.centrality); + if (cfgFillQA) + registry.fill(HIST("eventQA/after/multiplicity"), xaxis.multiplicity); + + fGFW->Clear(); + float lRandom = fRndm->Rndm(); + float vtxz = collision.posZ(); + + AcceptedTracks acceptedTracks{0, 0, 0, 0}; + for (const auto& particle : particles) { + if (particle.mcCollisionId() != mcCollisionId) + continue; + processTrack(particle, vtxz, xaxis.multiplicity, run, acceptedTracks); + } + + if (cfgConsistentEventFlag & kRequireBothEtaSides) + if (!acceptedTracks.nPos || !acceptedTracks.nNeg) + return; + if (cfgConsistentEventFlag & kRequireFullFourParticleTracks) + if (acceptedTracks.nFull < kMinTracksForFourParticleCorrelation) + return; + if (cfgConsistentEventFlag & kRequireTwoTracksInBothEtaSides) + if (acceptedTracks.nPos < kMinTracksPerEtaSideForGapCorrelation || + acceptedTracks.nNeg < kMinTracksPerEtaSideForGapCorrelation) + return; + if (cfgConsistentEventFlag & kRequireTwoTracksInThreeEtaRegions) + if (acceptedTracks.nPos < kMinTracksPerEtaRegionForThreeSubevents || + acceptedTracks.nMid < kMinTracksPerEtaRegionForThreeSubevents || + acceptedTracks.nNeg < kMinTracksPerEtaRegionForThreeSubevents) + return; + + fillOutputContainers(cfgUseNch ? static_cast(xaxis.multiplicity) : xaxis.centrality, + lRandom, qPtmp, run); + } + bool isStable(int pdg) { if (std::abs(pdg) == PDG_t::kPiPlus) @@ -1334,8 +1371,6 @@ struct FlowFlucGfwPp { return collision.centNTPV(); case kCentNGlobal: return collision.centNGlobal(); - case kCentMFT: - return collision.centMFT(); default: return collision.centFT0C(); } @@ -1352,7 +1387,6 @@ struct FlowFlucGfwPp { registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("centV0A_centT0C"), collision.centFT0C(), collision.centFV0A()); registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("centGlobal_centT0C"), collision.centFT0C(), collision.centNGlobal()); registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("centNTPV_centT0C"), collision.centFT0C(), collision.centNTPV()); - registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("centMFT_centT0C"), collision.centFT0C(), collision.centMFT()); } registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("globalTracks_PVTracks"), collision.multNTracksPV(), xaxis.multiplicity); registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("globalTracks_multT0A"), collision.multFT0A(), xaxis.multiplicity); @@ -1406,8 +1440,7 @@ struct FlowFlucGfwPp { void processData(soa::Filtered>::iterator const& collision, + aod::CentFV0As, aod::CentNTPVs, aod::CentNGlobals>>::iterator const& collision, aod::BCsWithTimestamps const&, GFWTracks const& tracks) { auto bc = collision.bc_as(); @@ -1487,7 +1520,7 @@ struct FlowFlucGfwPp { } PROCESS_SWITCH(FlowFlucGfwPp, processData, "Process analysis for non-derived data", false); - void processq2(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, GFWTracks const& tracks) + void processq2(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, GFWTracks const& tracks) { float count{0.5}; fillQnEventCounter(count++); @@ -1521,6 +1554,82 @@ struct FlowFlucGfwPp { fillQnCalibrationHistograms(centr, multi, qvecPos, qvecNeg); } PROCESS_SWITCH(FlowFlucGfwPp, processq2, "Process analysis for filling q_n-vector calibration histograms", true); + + void processMC(soa::Filtered>::iterator const& collision, + aod::BCsWithTimestamps const&, GFWTracksMC const& tracks, aod::McCollisions const&, aod::McParticles const& mcParticles) + { + auto bc = collision.bc_as(); + int run = bc.runNumber(); + if (run != lastRun) { + lastRun = run; + LOGF(info, "run = %d", run); + if (cfgRunByRun) { + if (std::find(runNumbers.begin(), runNumbers.end(), run) == runNumbers.end()) { + LOGF(info, "Creating histograms for run %d", run); + createRunByRunHistograms(run); + runNumbers.push_back(run); + } + if (!cfgFillWeights) + loadCorrections(bc); + } + } + if (!cfgFillWeights && !cfgRunByRun) + loadCorrections(bc); + + registry.fill(HIST("eventQA/eventSel"), kFilteredEvent); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(kFilteredEvent); + + if (!collision.sel8()) + return; + + registry.fill(HIST("eventQA/eventSel"), kSel8); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(kSel8); + + if (cfgDoOccupancySel) { + int occupancy = collision.trackOccupancyInTimeRange(); + if (occupancy < 0 || occupancy > cfgOccupancySelection) + return; + } + + registry.fill(HIST("eventQA/eventSel"), kOccupancy); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(kOccupancy); + + const XAxis xaxis{ + getCentrality(collision), + collision.multNTracksPV(), + (cfgTimeDependent) ? getTimeSinceStartOfFill(bc.timestamp(), *firstRunOfCurrentFill) : -1.0}; + + if (cfgTimeDependent && run == *firstRunOfCurrentFill && + firstRunOfCurrentFill != o2::analysis::gfwflowflucpp::firstRunsOfFill.end() - 1) + ++firstRunOfCurrentFill; + + if (cfgFillQA) + fillEventQA(collision, xaxis); + + registry.fill(HIST("eventQA/before/centrality"), xaxis.centrality); + registry.fill(HIST("eventQA/before/multiplicity"), xaxis.multiplicity); + + if (!eventSelected(collision, xaxis.multiplicity, xaxis.centrality, run)) + return; + + if (cfgFillQA) + fillEventQA(collision, xaxis); + + processCollision(collision, tracks, xaxis, run, 0); + + if (!collision.has_mcCollision()) + return; + + const auto genCollision = collision.template mcCollision_as(); + processGenCollision(genCollision, mcParticles, collision.mcCollisionId(), xaxis, run, 0); + } + PROCESS_SWITCH(FlowFlucGfwPp, processMC, "Process analysis for Monte-Carlo data", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/Flow/Tasks/flowSP.cxx b/PWGCF/Flow/Tasks/flowSP.cxx index 37b48ee0f50..3f11c04a52e 100644 --- a/PWGCF/Flow/Tasks/flowSP.cxx +++ b/PWGCF/Flow/Tasks/flowSP.cxx @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -76,21 +77,21 @@ struct FlowSP { // event selection configurable group struct : ConfigurableGroup { - O2_DEFINE_CONFIGURABLE(cEvtUseRCTFlagChecker, bool, false, "Evt sel: use RCT flag checker"); + O2_DEFINE_CONFIGURABLE(cEvtUseRCTFlagChecker, bool, true, "Evt sel: use RCT flag checker"); O2_DEFINE_CONFIGURABLE(cEvtRCTFlagCheckerLabel, std::string, "CBT_hadronPID", "Evt sel: RCT flag checker label (CBT, CBT_hadronPID)"); // all Labels can be found in Common/CCDB/RCTSelectionFlags.h - O2_DEFINE_CONFIGURABLE(cEvtRCTFlagCheckerZDCCheck, bool, false, "Evt sel: RCT flag checker ZDC check"); - O2_DEFINE_CONFIGURABLE(cEvtRCTFlagCheckerLimitAcceptAsBad, bool, false, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"); + O2_DEFINE_CONFIGURABLE(cEvtRCTFlagCheckerZDCCheck, bool, true, "Evt sel: RCT flag checker ZDC check"); + O2_DEFINE_CONFIGURABLE(cEvtRCTFlagCheckerLimitAcceptAsBad, bool, true, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"); O2_DEFINE_CONFIGURABLE(cEvSelsUseAdditionalEventCut, bool, true, "Bool to enable Additional Event Cut"); O2_DEFINE_CONFIGURABLE(cEvSelsMaxOccupancy, int, 10000, "Maximum occupancy of selected events"); O2_DEFINE_CONFIGURABLE(cEvSelsMinOccupancy, int, 0, "Minimum occupancy of selected events"); O2_DEFINE_CONFIGURABLE(cEvSelsNoSameBunchPileupCut, bool, true, "kNoSameBunchPileupCut"); O2_DEFINE_CONFIGURABLE(cEvSelsIsGoodZvtxFT0vsPV, bool, true, "kIsGoodZvtxFT0vsPV"); O2_DEFINE_CONFIGURABLE(cEvSelsNoCollInTimeRangeStandard, bool, true, "kNoCollInTimeRangeStandard"); - O2_DEFINE_CONFIGURABLE(cEvSelsNoCollInTimeRangeNarrow, bool, true, "kNoCollInTimeRangeNarrow"); + O2_DEFINE_CONFIGURABLE(cEvSelsNoCollInTimeRangeNarrow, bool, false, "kNoCollInTimeRangeNarrow"); O2_DEFINE_CONFIGURABLE(cEvSelsDoOccupancySel, bool, true, "Bool for event selection on detector occupancy"); O2_DEFINE_CONFIGURABLE(cEvSelsIsVertexITSTPC, bool, true, "Selects collisions with at least one ITS-TPC track"); O2_DEFINE_CONFIGURABLE(cEvSelsIsGoodITSLayersAll, bool, true, "Cut time intervals with dead ITS staves"); - O2_DEFINE_CONFIGURABLE(cEvSelsIsGoodITSLayer0123, bool, true, "Cut time intervals with dead ITS staves"); + O2_DEFINE_CONFIGURABLE(cEvSelsIsGoodITSLayer0123, bool, false, "Cut time intervals with dead ITS staves"); // QA Plots O2_DEFINE_CONFIGURABLE(cFillEventQA, bool, false, "Fill histograms for event QA"); @@ -117,13 +118,13 @@ struct FlowSP { O2_DEFINE_CONFIGURABLE(cCentNGlobal, bool, false, "Set centrality estimator to CentNGlobal"); // Standard selections O2_DEFINE_CONFIGURABLE(cTrackSelsDCAxy, float, 0.2, "Cut on DCA in the transverse direction (cm)"); - O2_DEFINE_CONFIGURABLE(cTrackSelsDCAz, float, 2, "Cut on DCA in the longitudinal direction (cm)"); + O2_DEFINE_CONFIGURABLE(cTrackSelsDCAz, float, 0.2, "Cut on DCA in the longitudinal direction (cm)"); O2_DEFINE_CONFIGURABLE(cTrackSelsNcls, float, 70, "Cut on number of TPC clusters found"); O2_DEFINE_CONFIGURABLE(cTrackSelsFshcls, float, 0.4, "Cut on fraction of shared TPC clusters found"); O2_DEFINE_CONFIGURABLE(cTrackSelsPtmin, float, 0.2, "minimum pt (GeV/c)"); O2_DEFINE_CONFIGURABLE(cTrackSelsPtmax, float, 10, "maximum pt (GeV/c)"); O2_DEFINE_CONFIGURABLE(cTrackSelsEta, float, 0.8, "eta cut"); - O2_DEFINE_CONFIGURABLE(cIsMCReco, bool, true, "Is MC Reco"); + O2_DEFINE_CONFIGURABLE(cIsMCReco, bool, false, "Is MC Reco"); O2_DEFINE_CONFIGURABLE(cEvSelsVtxZ, float, 10, "vertex cut (cm)"); O2_DEFINE_CONFIGURABLE(cMagField, float, 99999, "Configurable magnetic field;default CCDB will be queried"); O2_DEFINE_CONFIGURABLE(cCentMin, float, 0, "Minimum cenrality for selected events"); @@ -136,11 +137,11 @@ struct FlowSP { O2_DEFINE_CONFIGURABLE(cUseNUA1D, bool, true, "Use 1D NUA weights (only phi)"); O2_DEFINE_CONFIGURABLE(cUseNUA2D, bool, false, "Use 2D NUA weights (phi and eta)"); O2_DEFINE_CONFIGURABLE(cUseNUE2D, bool, false, "Use 2D NUE weights"); - O2_DEFINE_CONFIGURABLE(cUseNUE3D, bool, false, "Use 3D NUE weights (pt, eta, centrality)"); + O2_DEFINE_CONFIGURABLE(cUseNUE3D, bool, true, "Use 3D NUE weights (pt, eta, centrality)"); O2_DEFINE_CONFIGURABLE(cUseNUE2Deta, bool, false, "Use 2D NUE weights TRUE: (pt and eta) FALSE: (pt and centrality)"); // Additional track Selections O2_DEFINE_CONFIGURABLE(cTrackSelsUseAdditionalTrackCut, bool, false, "Bool to enable Additional Track Cut"); - O2_DEFINE_CONFIGURABLE(cTrackSelsDoDCApt, bool, false, "Apply Pt dependent DCAz cut"); + O2_DEFINE_CONFIGURABLE(cTrackSelsDoDCApt, bool, true, "Apply Pt dependent DCAz cut"); O2_DEFINE_CONFIGURABLE(cTrackSelsDCApt1, float, 0.1, "DcaZ < const + (a * b) / pt^1.1 -> this sets a"); O2_DEFINE_CONFIGURABLE(cTrackSelsDCApt2, float, 0.035, "DcaZ < const + (a * b) / pt^1.1 -> this sets b"); O2_DEFINE_CONFIGURABLE(cTrackSelsDCAptConsMin, float, 0.1, "DcaZ < const + (a * b) / pt^1.1 -> this sets const"); @@ -150,21 +151,19 @@ struct FlowSP { O2_DEFINE_CONFIGURABLE(cHarm, int, 1, "Flow harmonic n for ux and uy: (Cos(n*phi), Sin(n*phi))"); O2_DEFINE_CONFIGURABLE(cHarmMixed, int, 2, "Flow harmonic n for ux and uy in mixed harmonics (MH): (Cos(n*phi), Sin(n*phi))"); // settings for CCDB data - O2_DEFINE_CONFIGURABLE(cCCDBdir_QQ, std::string, "Users/c/ckoster/ZDC/LHC23_PbPb_pass5/meanQQ/Default", "ccdb dir for average QQ values in 1% centrality bins"); + O2_DEFINE_CONFIGURABLE(cCCDBdir_QQ, std::string, "Users/c/ckoster/ZDC/LHC23_PbPb_pass5/meanQQ/noGain", "ccdb dir for average QQ values in 1% centrality bins"); O2_DEFINE_CONFIGURABLE(cCCDBdir_SP, std::string, "", "ccdb dir for average event plane resolution in 1% centrality bins"); - O2_DEFINE_CONFIGURABLE(cCCDB_NUA, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass5/Default", "ccdb dir for NUA corrections"); + O2_DEFINE_CONFIGURABLE(cCCDB_NUA, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass5/noGain/Default", "ccdb dir for NUA corrections"); O2_DEFINE_CONFIGURABLE(cCCDB_NUE, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass5/NUE/Default", "ccdb dir for NUE corrections (pt)"); O2_DEFINE_CONFIGURABLE(cCCDB_NUE2D, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass5/NUE/2D", "ccdb dir for NUE 2D corrections (pt, eta)"); - O2_DEFINE_CONFIGURABLE(cCCDB_NUE3D, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass5/NUE/3D", "ccdb dir for NUE 3D corrections (pt, eta, centrality)"); - O2_DEFINE_CONFIGURABLE(cCCDBdir_centrality, std::string, "", "ccdb dir for Centrality corrections"); + O2_DEFINE_CONFIGURABLE(cCCDB_NUE3D, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass5/NUE3D/Default", "ccdb dir for NUE 3D corrections (pt, eta, centrality)"); + O2_DEFINE_CONFIGURABLE(cCCDBdir_centrality, std::string, "Users/c/ckoster/flowSP/LHC23_PbPb_pass5/centWeight/Default", "ccdb dir for Centrality corrections"); O2_DEFINE_CONFIGURABLE(cCCDBdir_meanPt, std::string, "", "ccdb dir for Mean Pt corrections"); - // Confogirable axis - // ConfigurableAxis axisCentrality{"axisCentrality", {20, 0, 100}, "Centrality bins for vn "}; - // ConfigurableAxis axisMomentum{"axisMomentum", {20, 0, 10}, "Momentum bins for vn"}; - // ConfigurableAxis axisEtaVn{"axisEtaVn", {8, -0.8, 0.8}, "Eta bins for vn"}; - // Configurables containing vector + O2_DEFINE_CONFIGURABLE(cUsePredeFinedSigma, bool, true, "Use one of the pre-defines settings for the multiplicity vs. centrality plots"); + O2_DEFINE_CONFIGURABLE(cUsePredeFinedSigmaYear, int, 2023, "Predifine what year you want to use (2023/2024)"); + O2_DEFINE_CONFIGURABLE(cUsePredeFinedSigmaNsigma, int, 2, "Sigma used for cuts (1,2,3)"); Configurable> cEvSelsMultPv{"cEvSelsMultPv", std::vector{2223.49, -75.1444, 0.963572, -0.00570399, 1.34877e-05, 3790.99, -137.064, 2.13044, -0.017122, 5.82834e-05}, "Multiplicity cuts (PV) first 5 parameters cutLOW last 5 cutHIGH (Default is +-2sigma pass5) "}; Configurable> cEvSelsMult{"cEvSelsMult", std::vector{1301.56, -41.4615, 0.478224, -0.00239449, 4.46966e-06, 2967.6, -102.927, 1.47488, -0.0106534, 3.28622e-05}, "Multiplicity cuts (Global) first 5 parameters cutLOW last 5 cutHIGH (Default is +-2sigma pass5) "}; Configurable> cPtBinning{"cPtBinning", std::vector{0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}, "pT binning for vn"}; @@ -260,6 +259,21 @@ struct FlowSP { double meanPxC = 0; } spm; + struct PtMaps { + std::unique_ptr meanPTMap = std::make_unique("meanPTMap", "meanPTMap", 8, -0.8, 0.8); + std::unique_ptr meanPTMapPos = std::make_unique("meanPTMapPos", "meanPTMapPos", 8, -0.8, 0.8); + std::unique_ptr meanPTMapNeg = std::make_unique("meanPTMapNeg", "meanPTMapNeg", 8, -0.8, 0.8); + + std::unique_ptr relPxA = std::make_unique("relPxA", "relPxA", 8, -0.8, 0.8); + std::unique_ptr relPxC = std::make_unique("relPxC", "relPxC", 8, -0.8, 0.8); + + std::unique_ptr relPxANeg = std::make_unique("relPxANeg", "relPxANeg", 8, -0.8, 0.8); + std::unique_ptr relPxAPos = std::make_unique("relPxAPos", "relPxAPos", 8, -0.8, 0.8); + + std::unique_ptr relPxCNeg = std::make_unique("relPxCNeg", "relPxCNeg", 8, -0.8, 0.8); + std::unique_ptr relPxCPos = std::make_unique("relPxCPos", "relPxCPos", 8, -0.8, 0.8); + } ptmaps; + OutputObj fWeights{GFWWeights("weights")}; OutputObj fWeightsPOS{GFWWeights("weights_positive")}; OutputObj fWeightsNEG{GFWWeights("weights_negative")}; @@ -268,13 +282,13 @@ struct FlowSP { HistogramRegistry histos{"QAhistos", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; // Event selection cuts - TF1* fPhiCutLow = nullptr; - TF1* fPhiCutHigh = nullptr; - TF1* fMultPVCutLow = nullptr; - TF1* fMultPVCutHigh = nullptr; - TF1* fMultCutLow = nullptr; - TF1* fMultCutHigh = nullptr; - TF1* fMultMultPVCut = nullptr; + std::unique_ptr fPhiCutLow = nullptr; + std::unique_ptr fPhiCutHigh = nullptr; + std::unique_ptr fMultPVCutLow = nullptr; + std::unique_ptr fMultPVCutHigh = nullptr; + std::unique_ptr fMultCutLow = nullptr; + std::unique_ptr fMultCutHigh = nullptr; + std::unique_ptr fMultMultPVCut = nullptr; enum SelectionCriteria { evSel_FilteredEvent, @@ -379,6 +393,7 @@ struct FlowSP { rctChecker.init(cfg.cEvtRCTFlagCheckerLabel, cfg.cEvtRCTFlagCheckerZDCCheck, cfg.cEvtRCTFlagCheckerLimitAcceptAsBad); histos.add("hCentrality", "Centrality; Centrality (%); ", {HistType::kTH1D, {axisCent}}); + histos.add("hCentralityCW", "Centrality; Centrality (%); Weighted counts", {HistType::kTH1D, {axisCent}}); histos.add("hEventCount", "Number of Event; Cut; #Events Passed Cut", {HistType::kTH1D, {{nEventSelections, 0, nEventSelections}}}); histos.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(evSel_FilteredEvent + 1, "Filtered events"); @@ -454,7 +469,6 @@ struct FlowSP { histos.add("QA/after/PsiA_vs_Vz", "", {HistType::kTH2D, {axisPhiPlane, axisVz}}); histos.add("QA/after/PsiC_vs_Vz", "", {HistType::kTH2D, {axisPhiPlane, axisVz}}); histos.add("QA/after/PsiFull_vs_Vz", "", {HistType::kTH2D, {axisPhiPlane, axisVz}}); - // histos.add("QA/after/DeltaPsivsPx", "", {HistType::kTH3D, {axisCent, axisPhiPlane, axisPx}}); } if (cfg.cFillQABefore) { @@ -537,8 +551,8 @@ struct FlowSP { registry.add("trackMCReco/after/incl/hIsPhysicalPrimary", "", {HistType::kTH3D, {{2, 0, 2}, axisCentrality, axisPt}}); registry.get(HIST("trackMCReco/after/incl/hIsPhysicalPrimary"))->GetXaxis()->SetBinLabel(1, "Secondary"); registry.get(HIST("trackMCReco/after/incl/hIsPhysicalPrimary"))->GetXaxis()->SetBinLabel(2, "Primary"); - registry.add("trackMCReco/hTrackSize_unFiltered", "", {HistType::kTH2D, {{100, 0, 200000}, axisCentrality}}); - registry.add("trackMCReco/hTrackSize_Filtered", "", {HistType::kTH2D, {{100, 0, 20000}, axisCentrality}}); + registry.add("trackMCReco/hTrackSize_unFiltered", "", {HistType::kTH2D, {{100, 0, 4000}, axisCentrality}}); + registry.add("trackMCReco/hTrackSize_Filtered", "", {HistType::kTH2D, {{100, 0, 4000}, axisCentrality}}); registry.add("trackMCReco/after/incl/hPt_hadron", "", {HistType::kTH3D, {axisPt, axisEta, axisCentrality}}); registry.add("trackMCReco/after/incl/hPt_proton", "", {HistType::kTH3D, {axisPt, axisEta, axisCentrality}}); registry.add("trackMCReco/after/incl/hPt_pion", "", {HistType::kTH3D, {axisPt, axisEta, axisCentrality}}); @@ -556,6 +570,8 @@ struct FlowSP { registry.add("QQCorrelations/qAXqCY", "", kTProfile, {axisCent}); registry.add("QQCorrelations/qAYqCX", "", kTProfile, {axisCent}); registry.add("QQCorrelations/qAXYqCXY", "", kTProfile, {axisCent}); + registry.add("shift/ShiftZDCC", "ShiftZDCC", kTProfile3D, {{100, 0, 100}, {2, 0, 2}, {10, 0, 10}}); + registry.add("shift/ShiftZDCA", "ShiftZDCA", kTProfile3D, {{100, 0, 100}, {2, 0, 2}, {10, 0, 10}}); if (cfg.cFillGeneralV1Histos) { // track properties per centrality and per eta, pt bin @@ -611,8 +627,7 @@ struct FlowSP { registry.add("incl/vnFull_EP", "", kTProfile3D, {axisPt, axisEtaVn, axisCentrality}); } if (cfg.cFillEventPlaneQA) { - histos.add("QA/hSPplaneA", "hSPplaneA", kTH1D, {axisPhiPlane}); - histos.add("QA/hSPplaneC", "hSPplaneC", kTH1D, {axisPhiPlane}); + histos.add("QA/hSPplaneAC", "hSPplaneAC", kTH2D, {axisPhiPlane, axisPhiPlane}); histos.add("QA/hSPplaneFull", "hSPplaneFull", kTH1D, {axisPhiPlane}); histos.add("QA/hCosPhiACosPhiC", "hCosPhiACosPhiC; Centrality(%); #LT Cos(#Psi^{A})Cos(#Psi^{C})#GT", kTProfile, {axisCent}); histos.add("QA/hSinPhiASinPhiC", "hSinPhiASinPhiC; Centrality(%); #LT Sin(#Psi^{A})Sin(#Psi^{C})#GT", kTProfile, {axisCent}); @@ -680,13 +695,51 @@ struct FlowSP { } if (cfg.cEvSelsUseAdditionalEventCut) { - fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); - fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); - fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); - fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); - - std::vector paramsMultPVCut = cfg.cEvSelsMultPv; - std::vector paramsMultCut = cfg.cEvSelsMult; + fMultPVCutLow = std::make_unique("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); + fMultPVCutHigh = std::make_unique("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); + fMultCutLow = std::make_unique("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); + fMultCutHigh = std::make_unique("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); + + std::vector paramsMultPVCut; + std::vector paramsMultCut; + int y2023 = 2023; + int y2024 = 2024; + std::array nSigma = {1, 2, 3}; + + if (cfg.cUsePredeFinedSigma) { + if (cfg.cUsePredeFinedSigmaYear == y2023) { + if (cfg.cUsePredeFinedSigmaNsigma == nSigma[0]) { + paramsMultPVCut = {2615.47, -90.5747, 1.25125, -0.00847075, 2.41183e-05, 3399.72, -121.652, 1.84077, -0.0142886, 4.71449e-05}; + paramsMultCut = {1716.84, -56.5663, 0.715202, -0.00426007, 1.05075e-05, 2550.82, -87.4873, 1.22205, -0.00852644, 2.54248e-05}; + } else if (cfg.cUsePredeFinedSigmaNsigma == nSigma[1]) { + paramsMultPVCut = {2223.49, -75.1444, 0.963572, -0.00570399, 1.34877e-05, 3790.99, -137.064, 2.13044, -0.017122, 5.82834e-05}; + paramsMultCut = {1301.56, -41.4615, 0.478224, -0.00239449, 4.46966e-06, 2967.6, -102.927, 1.47488, -0.0106534, 3.28622e-05}; + } else if (cfg.cUsePredeFinedSigmaNsigma == nSigma[2]) { + paramsMultPVCut = {1837.75, -60.852, 0.724331, -0.00366975, 6.47562e-06, 4182.12, -152.459, 2.41955, -0.0199481, 6.93894e-05}; + paramsMultCut = {885.976, -26.3397, 0.240114, -0.000496168, -1.82704e-06, 3384.43, -118.377, 1.72823, -0.0127887, 4.03432e-05}; + } else { + LOGF(fatal, "nSigma can only be 1-3 please reset the variable or give the parameters manually and set cfg.cUsePredeFinedSigma to FALSE"); + } + } else if (cfg.cUsePredeFinedSigmaYear == y2024) { + if (cfg.cUsePredeFinedSigmaNsigma == nSigma[0]) { + paramsMultPVCut = {2726.93, -100.128, 1.45046, -0.0099354, 2.71182e-05, 3404.72, -126.569, 1.92500, -0.0142653, 4.31645e-05}; + paramsMultCut = {1858.77, -66.6070, 0.929146, -0.00606961, 1.57639e-05, 2672.43, -96.7708, 1.39109, -0.00942498, 2.54268e-05}; + } else if (cfg.cUsePredeFinedSigmaNsigma == nSigma[1]) { + paramsMultPVCut = {2390.04, -87.3154, 1.23176, -0.00806869, 2.06624e-05, 3744.26, -139.927, 2.16863, -0.0165329, 5.17269e-05}; + paramsMultCut = {1451.23, -51.4314, 0.694609, -0.00433959, 1.06698e-05, 3080.42, -112.071, 1.63166, -0.0112533, 3.10348e-05}; + } else if (cfg.cUsePredeFinedSigmaNsigma == nSigma[2]) { + paramsMultPVCut = {2053.64, -74.5950, 1.01563, -0.00621473, 1.41276e-05, 4083.79, -153.304, 2.41333, -0.0188198, 6.03974e-05}; + paramsMultCut = {1042.50, -35.9374, 0.440681, -0.00222218, 3.20643e-06, 3488.53, -127.396, 1.87339, -0.0131007, 3.67434e-05}; + } else { + LOGF(fatal, "cUsePredeFinedSigmaNsigma can only be 1-3 please reset the variable or give the parameters manually and set cUsePredeFinedSigma to FALSE"); + } + } else { + LOGF(fatal, "cUsePredeFinedSigmaYear can only be 2023/2024 please reset the variable or give the parameters manually and set cUsePredeFinedSigma to FALSE"); + } + } else { + paramsMultPVCut = cfg.cEvSelsMultPv; + paramsMultCut = cfg.cEvSelsMult; + } // number of parameters required in cfg.cEvSelsMultPv and cfg.cEvSelsMult. (5 Low + 5 High) uint64_t nParams = 10; @@ -704,8 +757,8 @@ struct FlowSP { } if (cfg.cTrackSelsUseAdditionalTrackCut) { - fPhiCutLow = new TF1("fPhiCutLow", "0.06/x+pi/18.0-0.06", 0, 100); - fPhiCutHigh = new TF1("fPhiCutHigh", "0.1/x+pi/18.0+0.06", 0, 100); + fPhiCutLow = std::make_unique("fPhiCutLow", "0.06/x+pi/18.0-0.06", 0, 100); + fPhiCutHigh = std::make_unique("fPhiCutHigh", "0.1/x+pi/18.0+0.06", 0, 100); } } // end of init @@ -1125,7 +1178,6 @@ struct FlowSP { histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiA_vs_Vz"), psiA, collision.posZ(), spm.centWeight); histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiC_vs_Vz"), psiC, collision.posZ(), spm.centWeight); histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/PsiFull_vs_Vz"), psiFull, collision.posZ(), spm.centWeight); - // histos.fill(HIST("QA/") + HIST(Time[ft]) + HIST("/DeltaPsivsPx"), spm.centrality, psiA - psiC - constants::math::PI, track.px(), spm.centWeight); } } return; @@ -1135,20 +1187,27 @@ struct FlowSP { inline void fillHistograms(TrackObject track) { double weight = spm.wacc[ct][pt] * spm.weff[ct][pt] * spm.centWeight; - int scale = 1.0; - int minusQ = -1.0; + float scale = 1.0; + float minusQ = -1.0; if (track.eta() < 0) scale = -1.0; + const double invSqrtQQ = 1.0 / std::sqrt(std::fabs(spm.corrQQ)); + const double invSqrtQQx = 1.0 / std::sqrt(std::fabs(spm.corrQQx)); + const double invSqrtQQy = 1.0 / std::sqrt(std::fabs(spm.corrQQy)); + const double uqA = spm.uy * spm.qyA + spm.ux * spm.qxA; + const double uqC = spm.uy * spm.qyC + spm.ux * spm.qxC; + const double invMeanPtQQ = 1.0 / spm.meanPtWeight; + if (cfg.cFillGeneralV1Histos) { - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAodd"), track.pt(), track.eta(), spm.centrality, scale * (spm.uy * spm.qyA + spm.ux * spm.qxA) / std::sqrt(std::fabs(spm.corrQQ)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCodd"), track.pt(), track.eta(), spm.centrality, scale * (spm.uy * spm.qyC + spm.ux * spm.qxC) / std::sqrt(std::fabs(spm.corrQQ)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnOdd"), track.pt(), track.eta(), spm.centrality, scale * 0.5 * ((spm.uy * spm.qyA + spm.ux * spm.qxA) - (spm.uy * spm.qyC + spm.ux * spm.qxC)) / std::sqrt(std::fabs(spm.corrQQ)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnEven"), track.pt(), track.eta(), spm.centrality, 0.5 * ((spm.uy * spm.qyA + spm.ux * spm.qxA) + (spm.uy * spm.qyC + spm.ux * spm.qxC)) / std::sqrt(std::fabs(spm.corrQQ)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnA"), track.pt(), track.eta(), spm.centrality, (spm.uy * spm.qyA + spm.ux * spm.qxA) / std::sqrt(std::fabs(spm.corrQQ)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnC"), track.pt(), track.eta(), spm.centrality, (spm.uy * spm.qyC + spm.ux * spm.qxC) / std::sqrt(std::fabs(spm.corrQQ)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCSetPlane"), track.pt(), track.eta(), spm.centrality, (spm.uy + spm.ux) / std::sqrt(std::fabs(spm.corrQQ)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnASetPlane"), track.pt(), track.eta(), spm.centrality, (minusQ * spm.ux - spm.uy) / std::sqrt(std::fabs(spm.corrQQ)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAodd"), track.pt(), track.eta(), spm.centrality, scale * (uqA)*invSqrtQQ, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCodd"), track.pt(), track.eta(), spm.centrality, scale * (uqC)*invSqrtQQ, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnOdd"), track.pt(), track.eta(), spm.centrality, scale * 0.5 * ((uqA) - (uqC)) * invSqrtQQ, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnEven"), track.pt(), track.eta(), spm.centrality, 0.5 * ((uqA) + (uqC)) * invSqrtQQ, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnA"), track.pt(), track.eta(), spm.centrality, (uqA)*invSqrtQQ, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnC"), track.pt(), track.eta(), spm.centrality, (uqC)*invSqrtQQ, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCSetPlane"), track.pt(), track.eta(), spm.centrality, (spm.uy + spm.ux) * invSqrtQQ, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnASetPlane"), track.pt(), track.eta(), spm.centrality, (minusQ * spm.ux - spm.uy) * invSqrtQQ, weight); } if (cfg.cFillMixedHarmonics) { @@ -1159,10 +1218,10 @@ struct FlowSP { } if (cfg.cFillXandYterms) { - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAx"), track.pt(), track.eta(), spm.centrality, (spm.ux * spm.qxA) / std::sqrt(std::fabs(spm.corrQQx)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAy"), track.pt(), track.eta(), spm.centrality, (spm.uy * spm.qyA) / std::sqrt(std::fabs(spm.corrQQy)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCx"), track.pt(), track.eta(), spm.centrality, (spm.ux * spm.qxC) / std::sqrt(std::fabs(spm.corrQQx)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCy"), track.pt(), track.eta(), spm.centrality, (spm.uy * spm.qyC) / std::sqrt(std::fabs(spm.corrQQy)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAx"), track.pt(), track.eta(), spm.centrality, (spm.ux * spm.qxA) * invSqrtQQx, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnAy"), track.pt(), track.eta(), spm.centrality, (spm.uy * spm.qyA) * invSqrtQQy, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCx"), track.pt(), track.eta(), spm.centrality, (spm.ux * spm.qxC) * invSqrtQQx, weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("vnCy"), track.pt(), track.eta(), spm.centrality, (spm.uy * spm.qyC) * invSqrtQQy, weight); } if (cfg.cFillEventPlane) { // only fill for inclusive! @@ -1172,23 +1231,23 @@ struct FlowSP { } if (cfg.cFillMeanPT) { - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A3D"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyA + spm.ux * spm.qxA) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C3D"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyC + spm.ux * spm.qxC) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A3D"), track.pt(), track.eta(), spm.centrality, track.pt() * ((uqA) * (invSqrtQQ * invMeanPtQQ)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C3D"), track.pt(), track.eta(), spm.centrality, track.pt() * ((uqC) * (invSqrtQQ * invMeanPtQQ)), weight); if (cfg.cFillMeanPTextra) { registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/hMeanPtEtaCent"), track.eta(), spm.centrality, track.pt(), weight); registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/hMeanPtCent"), spm.centrality, track.pt(), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A"), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyA + spm.ux * spm.qxA) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C"), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyC + spm.ux * spm.qxC) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A"), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyA + spm.ux * spm.qxA) * (invSqrtQQ * invMeanPtQQ)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C"), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyC + spm.ux * spm.qxC) * (invSqrtQQ * invMeanPtQQ)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1Aodd"), track.eta(), spm.centrality, track.pt() * scale * ((spm.uy * spm.qyA + spm.ux * spm.qxA) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1Codd"), track.eta(), spm.centrality, track.pt() * scale * ((spm.uy * spm.qyC + spm.ux * spm.qxC) / (std::sqrt(std::fabs(spm.corrQQ)) * spm.meanPtWeight)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1Aodd"), track.eta(), spm.centrality, track.pt() * scale * ((spm.uy * spm.qyA + spm.ux * spm.qxA) * (invSqrtQQ * invMeanPtQQ)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1Codd"), track.eta(), spm.centrality, track.pt() * scale * ((spm.uy * spm.qyC + spm.ux * spm.qxC) * (invSqrtQQ * invMeanPtQQ)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A3Dx"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.ux * spm.qxA) / (std::sqrt(std::fabs(spm.corrQQx)) * spm.meanPtWeight)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C3Dx"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.ux * spm.qxC) / (std::sqrt(std::fabs(spm.corrQQx)) * spm.meanPtWeight)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A3Dx"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.ux * spm.qxA) * (invSqrtQQx * invMeanPtQQ)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C3Dx"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.ux * spm.qxC) * (invSqrtQQx * invMeanPtQQ)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A3Dy"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyA) / (std::sqrt(std::fabs(spm.corrQQy)) * spm.meanPtWeight)), weight); - registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C3Dy"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyC) / (std::sqrt(std::fabs(spm.corrQQy)) * spm.meanPtWeight)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1A3Dy"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyA) * (invSqrtQQy * invMeanPtQQ)), weight); + registry.fill(HIST(Charge[ct]) + HIST(Species[pt]) + HIST("meanPT/ptV1C3Dy"), track.pt(), track.eta(), spm.centrality, track.pt() * ((spm.uy * spm.qyC) * (invSqrtQQy * invMeanPtQQ)), weight); } } } @@ -1199,26 +1258,28 @@ struct FlowSP { if (!cfg.cFillTrackQA) return; + double weight = spm.wacc[ct][par] * spm.weff[ct][par] * spm.centWeight; + static constexpr std::string_view Time[] = {"before/", "after/"}; // NOTE: species[kUnidentified] = "" (when nocfg.cTrackSelDo) { if (cfg.cTrackSelDoTrackQAvsCent) { - histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_Eta"), track.pt(), track.eta(), spm.centrality, spm.wacc[ct][par] * spm.weff[ct][par]); + histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_Eta"), track.pt(), track.eta(), spm.centrality, weight); histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPt_Eta_uncorrected"), track.pt(), track.eta(), spm.centrality); - histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta"), track.phi(), track.eta(), spm.centrality, spm.wacc[ct][par] * spm.weff[ct][par]); + histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta"), track.phi(), track.eta(), spm.centrality, weight); histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_uncorrected"), track.phi(), track.eta(), spm.centrality); } else { histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_Pt"), track.phi(), track.eta(), track.pt()); - histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_Pt_corrected"), track.phi(), track.eta(), track.pt(), spm.wacc[ct][par] * spm.weff[ct][par]); + histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_Pt_corrected"), track.phi(), track.eta(), track.pt(), weight); } histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_vz"), track.phi(), track.eta(), spm.vz); histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hPhi_Eta_vz_corrected"), track.phi(), track.eta(), spm.vz, spm.wacc[ct][par]); - histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAxy_pt"), track.pt(), track.dcaXY(), spm.wacc[ct][par] * spm.weff[ct][par]); - histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAz_pt"), track.pt(), track.dcaZ(), spm.wacc[ct][par] * spm.weff[ct][par]); - histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hSharedClusters_pt"), track.pt(), track.tpcFractionSharedCls(), spm.wacc[ct][par] * spm.weff[ct][par]); - histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_pt"), track.pt(), track.tpcNClsCrossedRows(), spm.wacc[ct][par] * spm.weff[ct][par]); - histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_vs_SharedClusters"), track.tpcNClsCrossedRows(), track.tpcFractionSharedCls(), spm.wacc[ct][par] * spm.weff[ct][par]); - histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hMeanPtEta"), track.eta(), spm.centrality, track.pt(), spm.wacc[ct][par] * spm.weff[ct][par]); + histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAxy_pt"), track.pt(), track.dcaXY(), weight); + histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hDCAz_pt"), track.pt(), track.dcaZ(), weight); + histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hSharedClusters_pt"), track.pt(), track.tpcFractionSharedCls(), weight); + histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_pt"), track.pt(), track.tpcNClsCrossedRows(), weight); + histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hCrossedRows_vs_SharedClusters"), track.tpcNClsCrossedRows(), track.tpcFractionSharedCls(), weight); + histos.fill(HIST(Charge[ct]) + HIST(Species[par]) + HIST("QA/") + HIST(Time[ft]) + HIST("hMeanPtEta"), track.eta(), spm.centrality, track.pt(), weight); } template @@ -1362,6 +1423,8 @@ struct FlowSP { spm.psiA = 1.0 * std::atan2(spm.qyA, spm.qxA); spm.psiC = 1.0 * std::atan2(spm.qyC, spm.qxC); + int nshift = 10; // no. of iterations + // https://twiki.cern.ch/twiki/pub/ALICE/DirectedFlowAnalysisNote/vn_ZDC_ALICE_INT_NOTE_version02.pdf spm.psiFull = 1.0 * std::atan2(spm.qyA + spm.qyC, spm.qxA + spm.qxC); @@ -1372,13 +1435,18 @@ struct FlowSP { registry.fill(HIST("QQCorrelations/qAXYqCXY"), spm.centrality, spm.qyA * spm.qxC + spm.qxA * spm.qyC); registry.fill(HIST("QQCorrelations/qAqCX"), spm.centrality, spm.qxA * spm.qxC); registry.fill(HIST("QQCorrelations/qAqCY"), spm.centrality, spm.qyA * spm.qyC); + for (int ishift = 1; ishift <= nshift; ishift++) { + registry.fill(HIST("shift/ShiftZDCC"), spm.centrality, 0.5, ishift - 0.5, std::sin(ishift * 1.0 * spm.psiC)); + registry.fill(HIST("shift/ShiftZDCC"), spm.centrality, 1.5, ishift - 0.5, std::cos(ishift * 1.0 * spm.psiC)); + registry.fill(HIST("shift/ShiftZDCA"), spm.centrality, 0.5, ishift - 0.5, std::sin(ishift * 1.0 * spm.psiA)); + registry.fill(HIST("shift/ShiftZDCA"), spm.centrality, 1.5, ishift - 0.5, std::cos(ishift * 1.0 * spm.psiA)); + } if (cfg.cFillEventQA) { histos.fill(HIST("QA/hCentFull"), spm.centrality, 1); } if (cfg.cFillEventPlaneQA) { - histos.fill(HIST("QA/hSPplaneA"), spm.psiA, 1); - histos.fill(HIST("QA/hSPplaneC"), spm.psiC, 1); + histos.fill(HIST("QA/hSPplaneAC"), spm.psiA, spm.psiC, 1); histos.fill(HIST("QA/hSPplaneFull"), spm.psiFull, 1); histos.fill(HIST("QA/hCosPhiACosPhiC"), spm.centrality, std::cos(spm.psiA) * std::cos(spm.psiC)); histos.fill(HIST("QA/hSinPhiASinPhiC"), spm.centrality, std::sin(spm.psiA) * std::sin(spm.psiC)); @@ -1428,29 +1496,34 @@ struct FlowSP { conf.clCentrality = true; } double centW = conf.hCentrality->GetBinContent(conf.hCentrality->FindBin(spm.centrality)); - if (centW < 0) { + if (centW <= 0) { spm.centWeight = 0.; LOGF(fatal, "Centrality weight cannot be negative .. setting to 0. for (%.2f)", spm.centrality); + } else { + spm.centWeight = centW; } } + // Always fill centrality histogram after event selections! + histos.fill(HIST("hCentralityCW"), spm.centrality, spm.centWeight); + fillEventQA(collision, tracks); - TProfile* meanPTMap = new TProfile("meanPTMap", "meanPTMap", 8, -0.8, 0.8); - TProfile* meanPTMapPos = new TProfile("meanPTMapPos", "meanPTMapPos", 8, -0.8, 0.8); - TProfile* meanPTMapNeg = new TProfile("meanPTMapNeg", "meanPTMapNeg", 8, -0.8, 0.8); + ptmaps.meanPTMap->Reset(); + ptmaps.meanPTMapPos->Reset(); + ptmaps.meanPTMapNeg->Reset(); - TProfile* relPxA = new TProfile("relPxA", "relPxA", 8, -0.8, 0.8); - TProfile* relPxC = new TProfile("relPxC", "relPxC", 8, -0.8, 0.8); + ptmaps.relPxA->Reset(); + ptmaps.relPxC->Reset(); - TProfile* relPxANeg = new TProfile("relPxANeg", "relPxANeg", 8, -0.8, 0.8); - TProfile* relPxAPos = new TProfile("relPxAPos", "relPxAPos", 8, -0.8, 0.8); + ptmaps.relPxANeg->Reset(); + ptmaps.relPxAPos->Reset(); - TProfile* relPxCNeg = new TProfile("relPxCNeg", "relPxCNeg", 8, -0.8, 0.8); - TProfile* relPxCPos = new TProfile("relPxCPos", "relPxCPos", 8, -0.8, 0.8); + ptmaps.relPxCNeg->Reset(); + ptmaps.relPxCPos->Reset(); double sumPxAEvent = 0; - int meanPxEventCount = 0; + double meanPxEventCount = 0; double sumPxCEvent = 0; for (const auto& track : tracks) { @@ -1555,26 +1628,31 @@ struct FlowSP { sumPxCEvent += spm.meanPxC * weightIncl; meanPxEventCount += weightIncl; - meanPTMap->Fill(track.eta(), track.pt(), weightIncl); - relPxA->Fill(track.eta(), drelPxA, weightIncl); - relPxC->Fill(track.eta(), drelPxC, weightIncl); + ptmaps.meanPTMap->Fill(track.eta(), track.pt(), weightIncl); + ptmaps.relPxA->Fill(track.eta(), drelPxA, weightIncl); + ptmaps.relPxC->Fill(track.eta(), drelPxC, weightIncl); if (spm.charge == kPositive) { - meanPTMapPos->Fill(track.eta(), track.pt(), weightPos); - relPxAPos->Fill(track.eta(), drelPxA, weightPos); - relPxCPos->Fill(track.eta(), drelPxC, weightPos); + ptmaps.meanPTMapPos->Fill(track.eta(), track.pt(), weightPos); + ptmaps.relPxAPos->Fill(track.eta(), drelPxA, weightPos); + ptmaps.relPxCPos->Fill(track.eta(), drelPxC, weightPos); } if (spm.charge == kNegative) { - meanPTMapNeg->Fill(track.eta(), track.pt(), weightNeg); - relPxANeg->Fill(track.eta(), drelPxA, weightNeg); - relPxCNeg->Fill(track.eta(), drelPxC, weightNeg); + ptmaps.meanPTMapNeg->Fill(track.eta(), track.pt(), weightNeg); + ptmaps.relPxANeg->Fill(track.eta(), drelPxA, weightNeg); + ptmaps.relPxCNeg->Fill(track.eta(), drelPxC, weightNeg); } } // end of track loop - double meanPxAEvent = sumPxAEvent / meanPxEventCount; - double meanPxCEvent = sumPxCEvent / meanPxEventCount; + double meanPxAEvent = 0; + double meanPxCEvent = 0; + + if (meanPxEventCount > 0) { + meanPxAEvent = sumPxAEvent / meanPxEventCount; + meanPxCEvent = sumPxCEvent / meanPxEventCount; + } if (cfg.cFillMeanPTextra) { registry.fill(HIST("incl/meanPT/meanPxA"), spm.centrality, spm.psiA - spm.psiC, meanPxAEvent); @@ -1587,18 +1665,18 @@ struct FlowSP { int nBinsEta = 8; for (int etabin = 1; etabin <= nBinsEta; etabin++) { // eta bin is 1 --> Find centbin!! - double eta = meanPTMap->GetXaxis()->GetBinCenter(etabin); - double meanPt = meanPTMap->GetBinContent(etabin); - double meanPtPos = meanPTMapPos->GetBinContent(etabin); - double meanPtNeg = meanPTMapNeg->GetBinContent(etabin); + double eta = ptmaps.meanPTMap->GetXaxis()->GetBinCenter(etabin); + double meanPt = ptmaps.meanPTMap->GetBinContent(etabin); + double meanPtPos = ptmaps.meanPTMapPos->GetBinContent(etabin); + double meanPtNeg = ptmaps.meanPTMapNeg->GetBinContent(etabin); - double drelPxA = relPxA->GetBinContent(etabin); - double drelPxANeg = relPxANeg->GetBinContent(etabin); - double drelPxAPos = relPxAPos->GetBinContent(etabin); + double drelPxA = ptmaps.relPxA->GetBinContent(etabin); + double drelPxANeg = ptmaps.relPxANeg->GetBinContent(etabin); + double drelPxAPos = ptmaps.relPxAPos->GetBinContent(etabin); - double drelPxC = relPxC->GetBinContent(etabin); - double drelPxCNeg = relPxCNeg->GetBinContent(etabin); - double drelPxCPos = relPxCPos->GetBinContent(etabin); + double drelPxC = ptmaps.relPxC->GetBinContent(etabin); + double drelPxCNeg = ptmaps.relPxCNeg->GetBinContent(etabin); + double drelPxCPos = ptmaps.relPxCPos->GetBinContent(etabin); if (meanPt != 0) { registry.fill(HIST("incl/meanPT/meanRelPtA"), eta, spm.centrality, drelPxA / meanPt, spm.centWeight); @@ -1613,16 +1691,6 @@ struct FlowSP { } } } - - delete meanPTMap; - delete meanPTMapPos; - delete meanPTMapNeg; - delete relPxA; - delete relPxANeg; - delete relPxAPos; - delete relPxC; - delete relPxCNeg; - delete relPxCPos; } PROCESS_SWITCH(FlowSP, processData, "Process analysis for non-derived data", true); @@ -1721,11 +1789,10 @@ struct FlowSP { conf.clCentrality = true; } double centW = conf.hCentrality->GetBinContent(conf.hCentrality->FindBin(spm.centrality)); - if (centW < 0) { - spm.centWeight = 1. / centW; - } else { + + if (centW <= 0) { + spm.centWeight = 0; LOGF(fatal, "Centrality weight cannot be negative .. setting to 0. for (%.2f)", spm.centrality); - spm.centWeight = 0.; } } @@ -1997,6 +2064,8 @@ struct FlowSP { // get tracks that belong to reconstructed collision auto trackSlice = tracks.sliceBy(trackPerCollision, col.globalIndex()); + // get filtered tracks that belong to reconstructed collision + // mcReco uses filtered tracks auto filteredTrackSlice = filteredTracks.sliceBy(trackPerCollision, col.globalIndex()); spm.centrality = col.centFT0C(); diff --git a/PWGCF/Flow/Tasks/flowTask.cxx b/PWGCF/Flow/Tasks/flowTask.cxx index b3e57cdb226..bb30eddfe97 100644 --- a/PWGCF/Flow/Tasks/flowTask.cxx +++ b/PWGCF/Flow/Tasks/flowTask.cxx @@ -76,6 +76,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::analysis::genericframework; +using namespace o2::analysis::genericframework::eventweight; using namespace o2::aod::rctsel; #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; @@ -158,6 +159,7 @@ struct FlowTask { O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") O2_DEFINE_CONFIGURABLE(cfgEfficiencyForNch, std::string, "", "CCDB path to efficiency object, only for Nch correction") O2_DEFINE_CONFIGURABLE(cfgAcceptance, std::string, "", "CCDB path to acceptance object") + O2_DEFINE_CONFIGURABLE(cfgUserPtVnEvWeightEnabled, bool, false, "0: use unity weight; 1: use multiplicity weight") O2_DEFINE_CONFIGURABLE(cfgUseSmallMemory, bool, false, "Use small memory mode") O2_DEFINE_CONFIGURABLE(cfgConsistentEventFlag, int, 0, "Flag to select consistent events - 0: off, 1: v2{2} gap calculable, 2: v2{4} full calculable, 4: v2{4} gap calculable, 8: v2{4} 3sub calculable") Configurable> cfgConsistentEventVector{"cfgConsistentEventVector", std::vector{-0.8, -0.5, -0.4, 0.4, 0.5, 0.8}, "eta regions: left(min,max), mid(min,max), right(min,max)"}; @@ -659,6 +661,10 @@ struct FlowTask { gfwConfigs.Print(); fFCpt->setUseCentralMoments(cfgUseCentralMoments); fFCpt->setUseGapMethod(true); + if (!cfgUserIO.cfgUserPtVnEvWeightEnabled) + fFCpt->setEventWeight(EventWeight::UnityWeight); + else + fFCpt->setEventWeight(EventWeight::TupleWeight); fFCpt->initialise(axisIndependent, cfgMpar, gfwConfigs, cfgNbootstrap); if (cfgEtaGapPtPtEnabled) { for (int i = 0; i < 4; ++i) { // o2-linter: disable=magic-number (maximum of 4 subevents) @@ -677,6 +683,10 @@ struct FlowTask { if (doprocessMCGen) { fFCptgen->setUseCentralMoments(cfgUseCentralMoments); fFCptgen->setUseGapMethod(true); + if (!cfgUserIO.cfgUserPtVnEvWeightEnabled) + fFCptgen->setEventWeight(EventWeight::UnityWeight); + else + fFCptgen->setEventWeight(EventWeight::TupleWeight); fFCptgen->initialise(axisIndependent, cfgMpar, gfwConfigs, cfgNbootstrap); if (cfgEtaGapPtPtEnabled) fFCptgen->initialiseSubevent(axisIndependent, cfgMpar, etagapsPtPt.size(), cfgNbootstrap); @@ -1281,6 +1291,7 @@ struct FlowTask { double nTracksCorrected = 0; int magnetfield = 0; float independent = cent; + float nTracksUncorrected = 0; if (cfgUseNch) independent = static_cast(tracks.size()); if (cfgFuncParas.cfgShowTPCsectorOverlap) { @@ -1324,6 +1335,7 @@ struct FlowTask { for (const auto& track : tracks) { if (trackSelectedForNch(track) && setNchEffWeights(weffForNch, track.pt())) { nTracksCorrected += weffForNch; + nTracksUncorrected++; } if (!trackSelected(track)) continue; @@ -1414,7 +1426,7 @@ struct FlowTask { if (!cfgUsePtRef && withinPtPOI) fillPtSums(track, weff); } - registry.fill(HIST("hTrackCorrection2d"), tracks.size(), nTracksCorrected); + registry.fill(HIST("hTrackCorrection2d"), nTracksUncorrected, nTracksCorrected); if (cfgUseNch && cfgUseNchCorrected) { independent = nTracksCorrected; } diff --git a/PWGCF/Flow/Tasks/flowZdcTask.cxx b/PWGCF/Flow/Tasks/flowZdcTask.cxx index 6d8e581ab84..fb7cf802eab 100644 --- a/PWGCF/Flow/Tasks/flowZdcTask.cxx +++ b/PWGCF/Flow/Tasks/flowZdcTask.cxx @@ -61,7 +61,6 @@ struct FlowZdcTask { Configurable eventSelection{"eventSelection", 1, "event selection"}; Configurable maxZem{"maxZem", 3099.5, "Max ZEM signal"}; // for ZDC info and analysis - Configurable nBinsADC{"nBinsADC", 1000, "nbinsADC"}; Configurable maxZn{"maxZn", 125.5, "Max ZN signal"}; Configurable maxZp{"maxZp", 125.5, "Max ZP signal"}; // configs for process QA @@ -206,34 +205,16 @@ struct FlowZdcTask { xAxis->SetBinLabel(16, "Within TDC cut?"); if (doprocessQA) { - histos.add("ZNVsFT0A", ";T0A (#times 1/100);ZNA+ZNC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZn}}}); - histos.add("ZNVsFT0C", ";T0C (#times 1/100);ZNA+ZNC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZn}}}); - histos.add("ZNVsFT0M", ";T0A+T0C (#times 1/100);ZNA+ZNC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZn}}}); - histos.add("CommonZNVsFT0M", ";T0A+T0C (#times 1/100);ZNA+ZNC Common Energy;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZn}}}); - histos.add("ZNVsCent", ";T0C cent;ZNA + ZNC Amplitude;", kTH2F, {{{nBinsCent, 0., maxCent}, {nBinsZDC, -0.5, maxZn}}}); - histos.add("ZPVsFT0A", ";T0A (#times 1/100);ZPA+ZPC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZp}}}); - histos.add("ZPVsFT0C", ";T0C (#times 1/100);ZPA+ZPC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZp}}}); - histos.add("ZPVsFT0M", ";T0A+T0C (#times 1/100);ZPA+ZPC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZp}}}); - histos.add("ZPVsCent", ";T0C cent;ZPA + ZPC Amplitude;", kTH2F, {{{nBinsCent, 0., maxCent}, {nBinsZDC, -0.5, maxZp}}}); - histos.add("CommonZPVsFT0M", ";T0A+T0C (#times 1/100);ZPA+ZPC Common Energy;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZp}}}); - histos.add("ZNAVsFT0A", ";T0A (#times 1/100);ZNA Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZn}}}); histos.add("ZNAVsFT0C", ";T0C (#times 1/100);ZNA Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZn}}}); - histos.add("ZNAVsCent", ";T0C cent;ZNA Amplitude;", kTH2F, {{{nBinsCent, 0., maxCent}, {nBinsZDC, -0.5, maxZn}}}); histos.add("ZNAVsFT0M", ";T0A+T0C (#times 1/100);ZNA Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZn}}}); - histos.add("ZNCVsFT0A", ";T0A (#times 1/100);ZNC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZn}}}); histos.add("ZNCVsFT0C", ";T0C (#times 1/100);ZNC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZn}}}); histos.add("ZNCVsFT0M", ";T0A+T0C (#times 1/100);ZNC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZn}}}); - histos.add("ZNCVsCent", ";T0C cent;ZNC Amplitude;", kTH2F, {{{nBinsCent, 0., maxCent}, {nBinsZDC, -0.5, maxZn}}}); histos.add("ZPAZNAVsFT0M", ";T0A+T0C (#times 1/100);ZPA Amplitude;ZNA Amplitude;", kTH3F, {{{nBinsAmpFT0M, 0., maxAmpFT0M}, {nBinsZP, -0.5, maxZp}, {nBinsZN, -0.5, maxZn}}}); histos.add("ZPCZNCVsFT0M", ";T0A+T0C (#times 1/100);ZPC Amplitude;ZNC Amplitude;", kTH3F, {{{nBinsAmpFT0M, 0., maxAmpFT0M}, {nBinsZP, -0.5, maxZp}, {nBinsZN, -0.5, maxZn}}}); - histos.add("ZPAVsFT0A", ";T0A (#times 1/100);ZPA Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZp}}}); histos.add("ZPAVsFT0C", ";T0C (#times 1/100);ZPA Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZp}}}); histos.add("ZPAVsFT0M", ";T0A+T0C (#times 1/100);ZPA Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZp}}}); - histos.add("ZPAVsCent", ";T0C cent;ZPA Amplitude;", kTH2F, {{{nBinsCent, 0., maxCent}, {nBinsZDC, -0.5, maxZp}}}); - histos.add("ZPCVsFT0A", ";T0A (#times 1/100);ZPC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZp}}}); histos.add("ZPCVsFT0C", ";T0C (#times 1/100);ZPC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZp}}}); histos.add("ZPCVsFT0M", ";T0A+T0C (#times 1/100);ZPC Amplitude;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsZDC, -0.5, maxZp}}}); - histos.add("ZPCVsCent", ";T0C cent;ZPC Amplitude;", kTH2F, {{{nBinsCent, 0., maxCent}, {nBinsZDC, -0.5, maxZp}}}); histos.add("ZN", ";ZNA+ZNC;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); histos.add("ZNA", ";ZNA Amplitude;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); histos.add("ZPA", ";ZPA Amplitude;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZp}}); @@ -267,11 +248,9 @@ struct FlowZdcTask { histos.add("debunch", ";t_{ZDC}-t_{ZDA};t_{ZDC}+t_{ZDA}", kTH2F, {{{nBinsTDC, minTdcZn, maxTdcZn}, {nBinsTDC, minTdcZp, maxTdcZp}}}); histos.add("GlbTracks", "Nch", kTH1F, {{nBinsNch, minNch, maxNch}}); histos.add("ampFT0C", ";T0C (#times 1/100);", kTH1F, {{nBinsAmpFT0, 0., maxAmpFT0}}); - histos.add("ampFT0A", ";T0A (#times 1/100);", kTH1F, {{nBinsAmpFT0, 0., maxAmpFT0}}); histos.add("ampFT0M", ";T0A+T0C (#times 1/100);", kTH1F, {{nBinsAmpFT0, 0., maxAmpFT0M}}); histos.add("NchVsFT0C", ";T0C (#times 1/100, -3.3 < #eta < -2.1);#it{N}_{ch} (|#eta|<0.8);", kTH2F, {{{nBinsAmpFT0, 0., 950.}, {nBinsNch, minNch, maxNch}}}); histos.add("NchVsFT0M", ";T0A+T0C (#times 1/100, -3.3 < #eta < -2.1 and 3.5 < #eta < 4.9);#it{N}_{ch} (|#eta|<0.8);", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0M}, {nBinsNch, minNch, maxNch}}}); - histos.add("NchVsFT0A", ";T0A (#times 1/100, 3.5 < #eta < 4.9);#it{N}_{ch} (|#eta|<0.8);", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsNch, minNch, maxNch}}}); histos.add("NchVsEt", ";#it{E}_{T} (|#eta|<0.8);#LTITS+TPC tracks#GT (|#eta|<0.8);", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsNch, minNch, maxNch}}}); histos.add("NchVsMeanPt", ";#it{N}_{ch} (|#eta|<0.8);#LT[#it{p}_{T}]#GT (|#eta|<0.8);", kTProfile, {{nBinsNch, minNch, maxNch}}); histos.add("NchVsNPV", ";#it{N}_{PV} (|#eta|<1);ITS+TPC tracks (|#eta|<0.8);", kTH2F, {{{300, -0.5, 5999.5}, {nBinsNch, minNch, maxNch}}}); @@ -280,8 +259,6 @@ struct FlowZdcTask { histos.add("ZNAVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZn}}}); histos.add("ZPAVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZPA;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZp}}}); histos.add("ZPCVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZPA;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZp}}}); - histos.add("ZNVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA+ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZn}}}); - histos.add("ZPVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZPA+ZPC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZp}}}); } if (doprocessZdc) { histos.add("ampZna", ";ZNA Amplitude;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); @@ -415,7 +392,6 @@ struct FlowZdcTask { } histos.fill(HIST("hEventCounter"), EvCutLabel::Zdc); auto zdc = foundBC.zdc(); - auto cent = collision.centFT0C(); float aT0A = 0., aT0C = 0.; if (foundBC.has_ft0()) { @@ -498,10 +474,8 @@ struct FlowZdcTask { histos.fill(HIST("T0Ccent"), collision.centFT0C()); histos.fill(HIST("GlbTracks"), glbTracks); histos.fill(HIST("ampFT0C"), aT0C / 100.); - histos.fill(HIST("ampFT0A"), aT0A / 100.); histos.fill(HIST("ampFT0M"), (aT0A + aT0C) / 100.); // charged particle correlations - histos.fill(HIST("NchVsFT0A"), aT0A / 100., glbTracks); histos.fill(HIST("NchVsFT0C"), aT0C / 100., glbTracks); histos.fill(HIST("NchVsFT0M"), (aT0A + aT0C) / 100., glbTracks); histos.fill(HIST("hNchvsNPV"), collision.multNTracksPVeta1(), tracks.size()); @@ -542,37 +516,29 @@ struct FlowZdcTask { if ((tZNA >= minTdcZn) && (tZNA <= maxTdcZn)) { histos.fill(HIST("ZNA"), znA); histos.fill(HIST("ZNACommon"), commonSumZna); - histos.fill(HIST("ZNAVsFT0A"), aT0A / 100., znA); histos.fill(HIST("ZNAVsFT0C"), aT0C / 100., znA); histos.fill(HIST("ZNAVsFT0M"), (aT0A + aT0C) / 100., znA); - histos.fill(HIST("ZNAVsCent"), cent, znA); histos.fill(HIST("ZNAVsNch"), glbTracks, znA); } if ((tZNC >= minTdcZn) && (tZNC <= maxTdcZn)) { histos.fill(HIST("ZNC"), znC); histos.fill(HIST("ZNCCommon"), commonSumZnc); - histos.fill(HIST("ZNCVsFT0A"), aT0A / 100., znC); histos.fill(HIST("ZNCVsFT0C"), aT0C / 100., znC); histos.fill(HIST("ZNCVsFT0M"), (aT0A + aT0C) / 100., znC); - histos.fill(HIST("ZNCVsCent"), cent, znC); histos.fill(HIST("ZNCVsNch"), glbTracks, znC); } if ((tZPA >= minTdcZp) && (tZPA <= maxTdcZp)) { histos.fill(HIST("ZPA"), zpA); histos.fill(HIST("ZPACommon"), commonSumZpa); - histos.fill(HIST("ZPAVsFT0A"), aT0A / 100., zpA); histos.fill(HIST("ZPAVsFT0C"), aT0C / 100., zpA); histos.fill(HIST("ZPAVsFT0M"), (aT0A + aT0C) / 100., zpA); - histos.fill(HIST("ZPAVsCent"), cent, zpA); histos.fill(HIST("ZPAVsNch"), glbTracks, zpA); } if ((tZPC >= minTdcZp) && (tZPC <= maxTdcZp)) { histos.fill(HIST("ZPC"), zpC); histos.fill(HIST("ZPCCommon"), commonSumZpc); - histos.fill(HIST("ZPCVsFT0A"), aT0A / 100., zpC); histos.fill(HIST("ZPCVsFT0C"), aT0C / 100., zpC); histos.fill(HIST("ZPCVsFT0M"), (aT0A + aT0C) / 100., zpC); - histos.fill(HIST("ZPCVsCent"), cent, zpC); histos.fill(HIST("ZPCVsNch"), glbTracks, zpC); } if (((tZNA >= minTdcZn) && (tZNA <= maxTdcZn)) && ((tZNC >= minTdcZn) && (tZNC <= maxTdcZn))) @@ -581,21 +547,10 @@ struct FlowZdcTask { histos.fill(HIST("ZNAVsZNC"), znC, znA); histos.fill(HIST("CommonZNAVsZNC"), commonSumZnc, commonSumZna); histos.fill(HIST("ZN"), znA + znC); - histos.fill(HIST("ZNVsFT0C"), aT0C / 100., znA + znC); - histos.fill(HIST("ZNVsFT0M"), (aT0A + aT0C) / 100., znA + znC); - histos.fill(HIST("CommonZNVsFT0M"), (aT0A + aT0C) / 100., commonSumZna + commonSumZnc); - histos.fill(HIST("ZNVsCent"), cent, znA + znC); - histos.fill(HIST("ZNVsNch"), glbTracks, znA + znC); } if (((tZPA >= minTdcZp) && (tZPA <= maxTdcZp)) && ((tZPC >= minTdcZp) && (tZPC <= maxTdcZp))) { histos.fill(HIST("ZPAVsZPC"), zpC, zpA); histos.fill(HIST("CommonZPAVsZPC"), commonSumZpc, commonSumZpa); - histos.fill(HIST("ZPVsFT0A"), aT0A / 100., zpA + zpC); - histos.fill(HIST("ZPVsFT0C"), aT0C / 100., zpA + zpC); - histos.fill(HIST("ZPVsFT0M"), (aT0A + aT0C) / 100., zpA + zpC); - histos.fill(HIST("CommonZPVsFT0M"), (aT0A + aT0C) / 100., commonSumZpa + commonSumZpc); - histos.fill(HIST("ZPVsCent"), cent, zpA + zpC); - histos.fill(HIST("ZPVsNch"), glbTracks, zpA + zpC); } if (((tZNA >= minTdcZn) && (tZNA <= maxTdcZn)) && ((tZPA >= minTdcZp) && (tZPA <= maxTdcZp))) { histos.fill(HIST("ZNAVsZPA"), zpA, znA); @@ -626,33 +581,16 @@ struct FlowZdcTask { histos.fill(HIST("ZPACommon"), commonSumZpa); histos.fill(HIST("ZPCCommon"), commonSumZpc); histos.fill(HIST("ZN"), znA + znC); - histos.fill(HIST("ZPVsFT0A"), aT0A / 100., zpA + zpC); - histos.fill(HIST("ZPVsFT0C"), aT0C / 100., zpA + zpC); - histos.fill(HIST("ZPVsFT0M"), (aT0A + aT0C) / 100., zpA + zpC); - histos.fill(HIST("CommonZPVsFT0M"), (aT0A + aT0C) / 100., commonSumZpa + commonSumZpc); - histos.fill(HIST("ZPAVsFT0A"), aT0A / 100., zpA); histos.fill(HIST("ZPAVsFT0C"), aT0C / 100., zpA); histos.fill(HIST("ZPAVsFT0M"), (aT0A + aT0C) / 100., zpA); - histos.fill(HIST("ZNVsFT0C"), aT0C / 100., znA + znC); - histos.fill(HIST("ZNVsFT0M"), (aT0A + aT0C) / 100., znA + znC); - histos.fill(HIST("CommonZNVsFT0M"), (aT0A + aT0C) / 100., commonSumZna + commonSumZnc); - histos.fill(HIST("ZPCVsFT0A"), aT0A / 100., zpC); histos.fill(HIST("ZPCVsFT0C"), aT0C / 100., zpC); histos.fill(HIST("ZPCVsFT0M"), (aT0A + aT0C) / 100., zpC); - histos.fill(HIST("ZNCVsFT0A"), aT0A / 100., znC); histos.fill(HIST("ZNCVsFT0C"), aT0C / 100., znC); histos.fill(HIST("ZNCVsFT0M"), (aT0A + aT0C) / 100., znC); - histos.fill(HIST("ZNAVsFT0A"), aT0A / 100., znA); histos.fill(HIST("ZNAVsFT0C"), aT0C / 100., znA); histos.fill(HIST("ZNAVsFT0M"), (aT0A + aT0C) / 100., znA); - histos.fill(HIST("ZNAVsCent"), cent, znA); - histos.fill(HIST("ZNCVsCent"), cent, znC); - histos.fill(HIST("ZPVsCent"), cent, zpA + zpC); - histos.fill(HIST("ZPAVsCent"), cent, zpA); - histos.fill(HIST("ZPCVsCent"), cent, zpC); histos.fill(HIST("ZPAVsNch"), glbTracks, zpA); histos.fill(HIST("ZPCVsNch"), glbTracks, zpC); - histos.fill(HIST("ZNVsNch"), glbTracks, znA + znC); histos.fill(HIST("ZNCVsNch"), glbTracks, znC); histos.fill(HIST("ZNAVsNch"), glbTracks, znA); histos.fill(HIST("ZPAZNAVsFT0M"), (aT0A + aT0C) / 100., zpA, znA); diff --git a/PWGCF/Flow/Tasks/pidFlowPtCorr.cxx b/PWGCF/Flow/Tasks/pidFlowPtCorr.cxx index d779826c5fd..62f3bb41843 100644 --- a/PWGCF/Flow/Tasks/pidFlowPtCorr.cxx +++ b/PWGCF/Flow/Tasks/pidFlowPtCorr.cxx @@ -147,6 +147,8 @@ struct PidFlowPtCorr { O2_DEFINE_CONFIGURABLE(cfgOutPutPtSpectra, bool, false, "output pt spectra for data, MC and RECO"); O2_DEFINE_CONFIGURABLE(cfgCheck2MethodDiff, bool, false, "check difference between v2' && v2''"); O2_DEFINE_CONFIGURABLE(cfgClosureTest, int, 0, "choose (val) percent particle from charged to pass Pion PID selection"); + + O2_DEFINE_CONFIGURABLE(cfgProcessQAOutput, bool, false, "QA plots for processQA"); } switchsOpts; /** @@ -222,7 +224,7 @@ struct PidFlowPtCorr { ConfigurableAxis cfgaxisBootstrap{"cfgaxisBootstrap", {30, 0, 30}, "cfgaxisBootstrap"}; } meanptC22GraphOpts; - AxisSpec axisMultiplicity{{0, 5, 10, 15, 20, 30, 40, 50, 60, 70, 80, 90}, "Centrality (%)"}; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 80, 90}, "Centrality (%)"}; // configurable @@ -230,7 +232,7 @@ struct PidFlowPtCorr { // filter and using // data Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::eta) < trkQualityOpts.cfgCutEta.value); + Filter trackFilter = ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (nabs(aod::track::eta) < trkQualityOpts.cfgCutEta.value); using TracksPID = soa::Join; // data tracks filter @@ -309,6 +311,7 @@ struct PidFlowPtCorr { funcFillCorrectionGraph, funcProcessReco, funcProcessSim, + funcProcessQA, funcNumber }; @@ -324,10 +327,6 @@ struct PidFlowPtCorr { TF1* fT0AV0ASigma = nullptr; // Declare the pt, mult and phi Axis; - int nPtBins = 0; - TAxis* fPtAxis = nullptr; - - TAxis* fMultAxis = nullptr; std::vector funcEff; TH1D* hFindPtBin; @@ -374,13 +373,6 @@ struct PidFlowPtCorr { cfgMultPVCutPara = evtSeleOpts.cfgMultPVCut; // Set the pt, mult and phi Axis; - o2::framework::AxisSpec axisPt = cfgaxisPt; - nPtBins = axisPt.binEdges.size() - 1; - fPtAxis = new TAxis(nPtBins, &(axisPt.binEdges)[0]); - - o2::framework::AxisSpec axisMult = axisMultiplicity; - int nMultBins = axisMult.binEdges.size() - 1; - fMultAxis = new TAxis(nMultBins, &(axisMult.binEdges)[0]); if (dcaCutOpts.cfgDCAxyNSigma) { dcaCutOpts.fPtDepDCAxy = new TF1("ptDepDCAxy", Form("[0]*%s", dcaCutOpts.cfgDCAxy->c_str()), 0.001, 1000); @@ -557,6 +549,8 @@ struct PidFlowPtCorr { oba4Ch->Add(new TNamed("hMeanPtWeightOne", "hMeanPtWeightOne")); oba4Ch->Add(new TNamed("ptAveWeightOne", "ptAveWeightOne")); oba4Ch->Add(new TNamed("ptSquareAveWeightOne", "ptSquareAveWeightOne")); + + oba4Ch->Add(new TNamed("hMeanPtWeightFull", "hMeanPtWeightFull")); // end fill TObjArray for charged // init fFCCh @@ -572,6 +566,8 @@ struct PidFlowPtCorr { oba4PID->Add(new TNamed("covV2PtPID", "covV2PtPID")); oba4PID->Add(new TNamed("c22TrackWeightPID", "c22TrackWeightPID")); + oba4PID->Add(new TNamed("hMeanPtWeightCharged", "hMeanPtWeightCharged")); + fFCPi->SetName("FlowContainerPi"); fFCPi->Initialize(oba4PID, axisMultiplicity, cfgFlowNbootstrap); @@ -617,6 +613,28 @@ struct PidFlowPtCorr { // end pid // end init tprofile3d for <2'> - meanpt + /// @note init QA plot for processQA + if (switchsOpts.cfgProcessQAOutput.value) { + /// @note track QA + registry.add("hProcessQA/hDCAz", "DCAz after collision cuts; DCAz (cm); Pt", {HistType::kTH2D, {{200, -5, 5}, {200, 0, 3}}}); + registry.add("hProcessQA/hDCAxy", "DCAxy after cuts; DCAxy (cm); Pt", {HistType::kTH2D, {{200, -0.5, 0.5}, {200, 0, 5}}}); + + registry.add("hProcessQA/hChi2prTPCcls", "#chi^{2}/cluster for the TPC track segment", {HistType::kTH1D, {{100, 0., 5.}}}); + registry.add("hProcessQA/hChi2prITScls", "#chi^{2}/cluster for the ITS track", {HistType::kTH1D, {{100, 0., 50.}}}); + + registry.add("hProcessQA/hnTPCClu", "Number of found TPC clusters", {HistType::kTH1D, {{100, 40, 180}}}); + registry.add("hProcessQA/hnITSClu", "Number of found ITS clusters", {HistType::kTH1D, {{10, 0, 10}}}); + registry.add("hProcessQA/hnTPCCrossedRow", "Number of crossed TPC Rows", {HistType::kTH1D, {{100, 40, 180}}}); + // end track QA + + /// @note evetn QA + registry.add("hProcessQA/centVsMult", "cent Vs Mult;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {axisMultiplicity, cfgaxisNch}}); + registry.add("hProcessQA/IR", "", {HistType::kTH1D, {{100, 0, 100}}}); + registry.add("hProcessQA/Occupacy", "", {HistType::kTH1D, {{1000, 0, 10000}}}); + // end evetn QA + } + // end init QA plot for processQA + // fgfw set up and correlation config setup // Data stored in fGFW double etaMax = trkQualityOpts.cfgCutEta.value; @@ -1082,6 +1100,8 @@ struct PidFlowPtCorr { registry.fill(HIST("meanptCentNbs/hCharged"), ptSum / nch, cent, rndm * cfgFlowNbootstrap, val, nch * dnx); registry.fill(HIST("meanptCentNbs/hChargedMeanpt"), ptSum / nch, cent, rndm * cfgFlowNbootstrap, ptSum / nch, 1.); + + fFCCh->FillProfile("hMeanPtWeightFull", cent, (ptSum / nch), nch * dnx, rndm); } /** @@ -1124,6 +1144,9 @@ struct PidFlowPtCorr { registry.fill(HIST("meanptCentNbs/hChargedPionWithNpair"), pidPtSum / nPid, cent, rndm * cfgFlowNbootstrap, val, dnx); registry.fill(HIST("meanptCentNbs/hPionMeanpt"), pidPtSum / nPid, cent, rndm * cfgFlowNbootstrap, pidPtSum / nPid, 1.); + fFCPi->FillProfile("hMeanPtWeightFull", cent, (pidPtSum / nPid), nPid * npairPid, rndm); + fFCPi->FillProfile("hMeanPtWeightCharged", cent, (pidPtSum / nPid), dnx * nPid, rndm); + if (switchsOpts.cfgClosureTest.value != 0) { double npair4c22pure = fGFW->Calculate(corrconfigs.at(29), 0, true).real(); if (npair4c22pure > minVal4Float) @@ -1159,6 +1182,9 @@ struct PidFlowPtCorr { registry.fill(HIST("meanptCentNbs/hChargedKaonWithNpair"), pidPtSum / nPid, cent, rndm * cfgFlowNbootstrap, val, dnx); registry.fill(HIST("meanptCentNbs/hKaonMeanpt"), pidPtSum / nPid, cent, rndm * cfgFlowNbootstrap, pidPtSum / nPid, 1.); + fFCKa->FillProfile("hMeanPtWeightFull", cent, (pidPtSum / nPid), nPid * npairPid, rndm); + fFCKa->FillProfile("hMeanPtWeightCharged", cent, (pidPtSum / nPid), dnx * nPid, rndm); + break; // end kaon @@ -1176,6 +1202,9 @@ struct PidFlowPtCorr { registry.fill(HIST("meanptCentNbs/hChargedProtonWithNpair"), pidPtSum / nPid, cent, rndm * cfgFlowNbootstrap, val, dnx); registry.fill(HIST("meanptCentNbs/hProtonMeanpt"), pidPtSum / nPid, cent, rndm * cfgFlowNbootstrap, pidPtSum / nPid, 1.); + fFCPr->FillProfile("hMeanPtWeightFull", cent, (pidPtSum / nPid), nPid * npairPid, rndm); + fFCPr->FillProfile("hMeanPtWeightCharged", cent, (pidPtSum / nPid), dnx * nPid, rndm); + break; // end proton @@ -1661,7 +1690,7 @@ struct PidFlowPtCorr { break; default: - LOGF(warning, "could not find event count graph"); + // LOGF(warning, "could not find event count graph"); break; } } @@ -2395,6 +2424,65 @@ struct PidFlowPtCorr { } PROCESS_SWITCH(PidFlowPtCorr, fillCorrectionGraph, "", true); + void processQA(AodCollisions::iterator const& collision, aod::BCsWithTimestamps const&, AodTracks const& tracks) + { + if (!switchsOpts.cfgProcessQAOutput.value) { + LOGF(fatal, "processQAOutput no open!"); + } + + /// @note init && collision cut + int nTot = tracks.size(); + auto bc = collision.bc_as(); + int runNumber = bc.runNumber(); + double interactionRate = rateFetcher.fetch(ccdb.service, bc.timestamp(), runNumber, "ZNC hadronic") * 1.e-3; + // end init + + /// @note collision cut + // include : 1.track.size 2.collision.sel8 3. evenSelected + if (nTot < 1) + return; + + const auto cent = collision.centFT0C(); + if (!collision.sel8()) + return; + + /// @note event qa + registry.fill(HIST("hProcessQA/centVsMult"), cent, tracks.size()); + registry.fill(HIST("hProcessQA/IR"), interactionRate); + registry.fill(HIST("hProcessQA/Occupacy"), collision.trackOccupancyInTimeRange()); + // end event qa + + // i dont want to fill event count again as it's filled in other 5 function + if (!eventSelected(collision, cent, interactionRate, MyFunctionName::funcProcessQA)) + return; + // end init && collision cut + + /// @note track loop + for (const auto& track : tracks) { + /// @note select global track + // track cut isnt applied, this is track QA function! + if (!track.hasITS()) + continue; + if (!track.hasTPC()) + continue; + // end select global track + + /// @note fill QA graphs + registry.fill(HIST("hProcessQA/hDCAz"), track.dcaZ(), track.pt()); + registry.fill(HIST("hProcessQA/hDCAxy"), track.dcaXY(), track.pt()); + + registry.fill(HIST("hProcessQA/hChi2prTPCcls"), track.tpcChi2NCl()); + registry.fill(HIST("hProcessQA/hChi2prITScls"), track.itsChi2NCl()); + + registry.fill(HIST("hProcessQA/hnTPCClu"), track.tpcNClsFound()); + registry.fill(HIST("hProcessQA/hnITSClu"), track.itsNCls()); + registry.fill(HIST("hProcessQA/hnTPCCrossedRow"), track.tpcNClsCrossedRows()); + // end fill QA grahps + } + // end track loop + } + PROCESS_SWITCH(PidFlowPtCorr, processQA, "", true); + /** * @brief this main function is used to check the PID performance of ITS TOC TPC, also used to do QA * @note open switch outputQA if use it diff --git a/PWGCF/GenericFramework/Tasks/CMakeLists.txt b/PWGCF/GenericFramework/Tasks/CMakeLists.txt index 6238192e1be..73a9f7a5396 100644 --- a/PWGCF/GenericFramework/Tasks/CMakeLists.txt +++ b/PWGCF/GenericFramework/Tasks/CMakeLists.txt @@ -18,7 +18,13 @@ o2physics_add_dpl_workflow(flow-gfw-light-ions SOURCES flowGfwLightIons.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(flow-gfw-v02 SOURCES flowGfwV02.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore - COMPONENT_NAME Analysis) \ No newline at end of file + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(flow-gfw-nonflow + SOURCES flowGfwNonflow.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx index a1fc3847727..94314746bdb 100644 --- a/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx +++ b/PWGCF/GenericFramework/Tasks/flowGenericFramework.cxx @@ -84,37 +84,9 @@ using namespace o2; using namespace o2::framework; using namespace o2::analysis::genericframework; -#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; +#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, (DEFAULT), (HELP)}; // NOLINT(bugprone-macro-parentheses) -namespace o2::analysis::gfw -{ -std::vector ptbinning = {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}; -float ptpoilow = 0.2, ptpoiup = 10.0; -float ptreflow = 0.2, ptrefup = 3.0; -float ptlow = 0.2, ptup = 10.0; -int etabins = 16; -float etalow = -0.8, etaup = 0.8; -int vtxZbins = 40; -float vtxZlow = -10.0, vtxZup = 10.0; -int phibins = 72; -float philow = 0.0; -float phiup = o2::constants::math::TwoPI; -int nchbins = 300; -float nchlow = 0; -float nchup = 3000; -std::vector centbinning(90); -int nBootstrap = 10; -GFWRegions regions; -GFWCorrConfigs configs; -GFWCorrConfigs configsV02; -GFWCorrConfigs configsV0; -std::vector> etagapsPtPt; -std::vector multGlobalCorrCutPars; -std::vector multPVCorrCutPars; -std::vector multGlobalPVCorrCutPars; -std::vector multGlobalV0ACutPars; -std::vector multGlobalT0ACutPars; -} // namespace o2::analysis::gfw +constexpr float DefaultMagneticFieldCut = 99999.f; template auto projectMatrix(Array2D const& mat, std::array& array1, std::array& array2, std::array& array3) @@ -140,9 +112,9 @@ auto readMatrix(Array2D const& mat, P& array) // static constexpr float LongArrayFloat[3][20] = {{1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}, {2.1, 2.2, 2.3, -2.1, -2.2, -2.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}, {3.1, 3.2, 3.3, -3.1, -3.2, -3.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}}; // static constexpr int LongArrayInt[3][20] = {{1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1}, {2, 2, 2, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1}, {3, 3, 3, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1}}; -static constexpr float LongArrayFloat[20][3] = {{1.1, 2.1, 3.1}, {1.2, 2.2, 3.2}, {1.3, 2.3, 3.3}, {-1.1, -2.1, -3.1}, {-1.2, -2.2, -3.2}, {-1.3, -2.3, -3.3}, {1.1, 1.1, 1.1}, {1.2, 1.2, 1.2}, {1.3, 1.3, 1.3}, {-1.1, -1.1, -1.1}, {-1.2, -1.2, -1.2}, {-1.3, -1.3, -1.3}, {1.1, 1.1, 1.1}, {1.2, 1.2, 1.2}, {1.3, 1.3, 1.3}, {-1.1, -1.1, -1.1}, {-1.2, -1.2, -1.2}, {-1.3, -1.3, -1.3}, {1.1, 1.1, 1.1}, {1.2, 1.2, 1.2}}; -static constexpr int LongArrayInt[20][3] = {{1, 2, 3}, {1, 2, 3}, {1, 2, 3}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {1, 1, 1}, {1, 1, 1}}; -static constexpr double LongArrayDouble[4][2] = {{-0.8, -0.5}, {0.5, 0.8}, {-2, -2}, {-2, -2}}; +static constexpr std::array, 20> LongArrayFloat = {{{{1.1, 2.1, 3.1}}, {{1.2, 2.2, 3.2}}, {{1.3, 2.3, 3.3}}, {{-1.1, -2.1, -3.1}}, {{-1.2, -2.2, -3.2}}, {{-1.3, -2.3, -3.3}}, {{1.1, 1.1, 1.1}}, {{1.2, 1.2, 1.2}}, {{1.3, 1.3, 1.3}}, {{-1.1, -1.1, -1.1}}, {{-1.2, -1.2, -1.2}}, {{-1.3, -1.3, -1.3}}, {{1.1, 1.1, 1.1}}, {{1.2, 1.2, 1.2}}, {{1.3, 1.3, 1.3}}, {{-1.1, -1.1, -1.1}}, {{-1.2, -1.2, -1.2}}, {{-1.3, -1.3, -1.3}}, {{1.1, 1.1, 1.1}}, {{1.2, 1.2, 1.2}}}}; +static constexpr std::array, 20> LongArrayInt = {{{{1, 2, 3}}, {{1, 2, 3}}, {{1, 2, 3}}, {{0, 0, 0}}, {{0, 0, 0}}, {{0, 0, 0}}, {{1, 1, 1}}, {{1, 1, 1}}, {{1, 1, 1}}, {{0, 0, 0}}, {{0, 0, 0}}, {{0, 0, 0}}, {{1, 1, 1}}, {{1, 1, 1}}, {{1, 1, 1}}, {{0, 0, 0}}, {{0, 0, 0}}, {{0, 0, 0}}, {{1, 1, 1}}, {{1, 1, 1}}}}; +static constexpr std::array, 4> LongArrayDouble = {{{{-0.8, -0.5}}, {{0.5, 0.8}}, {{-2, -2}}, {{-2, -2}}}}; struct FlowGenericFramework { O2_DEFINE_CONFIGURABLE(cfgNbootstrap, int, 10, "Number of subsamples") @@ -154,8 +126,8 @@ struct FlowGenericFramework { struct : ConfigurableGroup{ O2_DEFINE_CONFIGURABLE(cfgFillWeights, bool, false, "Fill NUA weights") O2_DEFINE_CONFIGURABLE(cfgFillQA, bool, false, "Fill QA histograms") - O2_DEFINE_CONFIGURABLE(cfgFillRunByRunQA, bool, false, "Fill histograms on a run-by-run basis")} cfgFill; - O2_DEFINE_CONFIGURABLE(cfgMultCut, bool, false, "Use additional event cut on mult correlations"); + O2_DEFINE_CONFIGURABLE(cfgFillV0QA, bool, true, "Fill QA histograms for V0 reconstruction") + O2_DEFINE_CONFIGURABLE(cfgFillRunByRunQA, bool, false, "Fill histograms on a run-by-run basis")} cfgFill; O2_DEFINE_CONFIGURABLE(cfgUseCentralMoments, bool, true, "Use central moments in vn-pt calculations") O2_DEFINE_CONFIGURABLE(cfgUsePID, bool, true, "Enable PID information") O2_DEFINE_CONFIGURABLE(cfgUseGapMethod, bool, false, "Use gap method in vn-pt calculations") @@ -168,16 +140,16 @@ struct FlowGenericFramework { O2_DEFINE_CONFIGURABLE(cfgUsePIDEfficiencies, bool, false, "Use species dependent efficiencies") O2_DEFINE_CONFIGURABLE(cfgUse2DEfficiency, bool, false, "Toggle the use of 2D (pt, centrality) efficiency versus centrality integrated efficiency")} cfgEfficiency; O2_DEFINE_CONFIGURABLE(cfgAcceptance, std::string, "", "CCDB path to acceptance object") - O2_DEFINE_CONFIGURABLE(cfgPtmin, float, 0.2, "minimum pt (GeV/c)"); - O2_DEFINE_CONFIGURABLE(cfgPtmax, float, 10, "maximum pt (GeV/c)"); struct : ConfigurableGroup { Configurable> cfgEtaNptV02{"cfgEtaNptV02", {-0.5, 0.5}, "eta cut for v02 fractional spectra"}; Configurable> cfgEtaNptV0{"cfgEtaNptV0", {-0.5, 0.5}, "eta cut for v0 fractional spectra"}; Configurable> cfgEta{"cfgEta", {-0.8, 0.8}, "eta cut"}; Configurable> cfgEtaNch{"cfgEtaNch", {-0.5, 0.5}, "eta cut for nch selection"}; Configurable> cfgEtaPtPt{"cfgEtaPtPt", {-0.5, 0.5}, "eta for pt-pt correlation"}; + O2_DEFINE_CONFIGURABLE(cfgPtMin, float, 0.2, "minimum pt (GeV/c)"); + O2_DEFINE_CONFIGURABLE(cfgPtmax, float, 10, "maximum pt (GeV/c)"); } cfgKinematics; - Configurable> cfgPtPtGaps{"cfgPtPtGaps", {LongArrayDouble[0], 4, 2, {"subevent 1", "subevent 2", "subevent 3", "subevent 4"}, {"etamin", "etamax"}}, "{etamin,etamax} for all ptpt-subevents"}; + Configurable> cfgPtPtGaps{"cfgPtPtGaps", {LongArrayDouble.front().data(), 4, 2, {"subevent 1", "subevent 2", "subevent 3", "subevent 4"}, {"etamin", "etamax"}}, "{etamin,etamax} for all ptpt-subevents"}; O2_DEFINE_CONFIGURABLE(cfgUsePIDTotal, bool, false, "use fraction of PID total"); O2_DEFINE_CONFIGURABLE(cfgVtxZ, float, 10, "vertex cut (cm)"); struct : ConfigurableGroup { @@ -204,9 +176,12 @@ struct FlowGenericFramework { O2_DEFINE_CONFIGURABLE(cfgTVXinTRD, bool, true, "TVXinTRD - Use TVXinTRD (reject TRD triggered events)"); O2_DEFINE_CONFIGURABLE(cfgIsVertexITSTPC, bool, true, "IsVertexITSTPC - Selects collisions with at least one ITS-TPC track"); } cfgEventCutFlags; - O2_DEFINE_CONFIGURABLE(cfgOccupancySelection, int, 2000, "Max occupancy selection, -999 to disable"); - O2_DEFINE_CONFIGURABLE(cfgDoOccupancySel, bool, true, "Bool for event selection on detector occupancy"); - O2_DEFINE_CONFIGURABLE(cfgMagField, float, 99999, "Configurable magnetic field; default CCDB will be queried"); + struct ConfigurableGroup { + O2_DEFINE_CONFIGURABLE(cfgOccupancySelection, int, 2000, "Max occupancy selection, -999 to disable"); + O2_DEFINE_CONFIGURABLE(cfgDoOccupancySel, bool, true, "Bool for event selection on detector occupancy"); + O2_DEFINE_CONFIGURABLE(cfgMagField, float, 99999, "Configurable magnetic field; default CCDB will be queried"); + O2_DEFINE_CONFIGURABLE(cfgMultCut, bool, false, "Use additional event cut on mult correlations"); + } cfgEventSelection; O2_DEFINE_CONFIGURABLE(cfgUseDensityDependentCorrection, bool, false, "Use density dependent efficiency correction based on Run 2 measurements"); Configurable> cfgTrackDensityP0{"cfgTrackDensityP0", std::vector{0.7217476707, 0.7384792571, 0.7542625668, 0.7640680200, 0.7701951667, 0.7755299053, 0.7805901710, 0.7849446786, 0.7957356586, 0.8113039262, 0.8211968966, 0.8280558878, 0.8329342135}, "parameter 0 for track density efficiency correction"}; Configurable> cfgTrackDensityP1{"cfgTrackDensityP1", std::vector{-2.169488e-05, -2.191913e-05, -2.295484e-05, -2.556538e-05, -2.754463e-05, -2.816832e-05, -2.846502e-05, -2.843857e-05, -2.705974e-05, -2.477018e-05, -2.321730e-05, -2.203315e-05, -2.109474e-05}, "parameter 1 for track density efficiency correction"}; @@ -226,9 +201,9 @@ struct FlowGenericFramework { O2_DEFINE_CONFIGURABLE(cfgGlobalT0AHighSigma, float, 4, "Number of sigma deviations above expected value in global vs T0A correlation"); } cfgMultCorrCuts; struct : ConfigurableGroup { - Configurable> nSigmas{"nSigmas", {LongArrayFloat[0], 6, 3, {"pos_pi", "pos_ka", "pos_pr", "neg_pi", "neg_ka", "neg_pr"}, {"TPC", "TOF", "ITS"}}, "Labeled array for n-sigma values for TPC, TOF, ITS for pions, kaons, protons (positive and negative)"}; - Configurable> resonanceCuts{"resonanceCuts", {LongArrayFloat[0], 14, 3, {"cos_PAs", "massMin", "massMax", "PosTrackPt", "NegTrackPt", "DCAPosToPVMin", "DCANegToPVMin", "DCAxDaughters", "Lifetime", "RadiusMin", "RadiusMax", "Rapidity", "ArmPodMin", "MassRejection"}, {"K0", "Lambda", "Phi"}}, "Labeled array (float) for various cuts on resonances"}; - Configurable> resonanceSwitches{"resonanceSwitches", {LongArrayInt[0], 8, 3, {"UseParticle", "UseCosPA", "NMassBins", "UseDCAxDaughters", "UseProperLifetime", "UseV0Radius", "UseArmPodCut", "UseCompetingMassRejection"}, {"K0", "Lambda", "Phi"}}, "Labeled array (int) for various cuts on resonances"}; + Configurable> nSigmas{"nSigmas", {LongArrayFloat.front().data(), 6, 3, {"pos_pi", "pos_ka", "pos_pr", "neg_pi", "neg_ka", "neg_pr"}, {"TPC", "TOF", "ITS"}}, "Labeled array for n-sigma values for TPC, TOF, ITS for pions, kaons, protons (positive and negative)"}; + Configurable> resonanceCuts{"resonanceCuts", {LongArrayFloat.front().data(), 14, 3, {"cos_PAs", "massMin", "massMax", "PosTrackPt", "NegTrackPt", "DCAPosToPVMin", "DCANegToPVMin", "DCAxDaughters", "Lifetime", "RadiusMin", "RadiusMax", "Rapidity", "ArmPodMin", "MassRejection"}, {"K0", "Lambda", "Phi"}}, "Labeled array (float) for various cuts on resonances"}; + Configurable> resonanceSwitches{"resonanceSwitches", {LongArrayInt.front().data(), 8, 3, {"UseParticle", "UseCosPA", "NMassBins", "UseDCAxDaughters", "UseProperLifetime", "UseV0Radius", "UseArmPodCut", "UseCompetingMassRejection"}, {"K0", "Lambda", "Phi"}}, "Labeled array (int) for various cuts on resonances"}; O2_DEFINE_CONFIGURABLE(cfgUseLsPhi, bool, true, "Use LikeSign for Phi v2") O2_DEFINE_CONFIGURABLE(cfgUseOnlyTPC, bool, true, "Use only TPC PID for daughter selection") O2_DEFINE_CONFIGURABLE(cfgFakeKaonCut, float, 0.1f, "Maximum difference in measured momentum and TPC inner ring momentum of particle") @@ -261,9 +236,42 @@ struct FlowGenericFramework { ConfigurableAxis axisNsigmaTPC{"axisNsigmaTPC", {80, -5, 5}, "nsigmaTPC axis"}; ConfigurableAxis axisNsigmaTOF{"axisNsigmaTOF", {80, -5, 5}, "nsigmaTOF axis"}; + struct GFWMemberCache { + std::vector ptbinning = {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}; + float ptpoilow = 0.2; + float ptpoiup = 10.0; + float ptreflow = 0.2; + float ptrefup = 3.0; + float ptlow = 0.2; + float ptup = 10.0; + int etabins = 16; + float etalow = -0.8; + float etaup = 0.8; + int vtxZbins = 40; + float vtxZlow = -10.0; + float vtxZup = 10.0; + int phibins = 72; + float philow = 0.0; + float phiup = o2::constants::math::TwoPI; + int nchbins = 300; + float nchlow = 0; + float nchup = 3000; + std::vector centbinning = std::vector(90); + GFWRegions regions; + GFWCorrConfigs configs; + GFWCorrConfigs configsV02; + GFWCorrConfigs configsV0; + std::vector> etagapsPtPt; + std::vector multGlobalCorrCutPars; + std::vector multPVCorrCutPars; + std::vector multGlobalPVCorrCutPars; + std::vector multGlobalV0ACutPars; + std::vector multGlobalT0ACutPars; + } gfwMemberCache; + // Connect to ccdb - Service ccdb; - Service pdgDB; + Service ccdb{}; + Service pdgDB{}; o2::aod::ITSResponse itsResponse; @@ -281,11 +289,11 @@ struct FlowGenericFramework { HistogramRegistry registry{"registry"}; HistogramRegistry registryQA{"registryQA"}; - std::array, 14> resoCutVals; - std::array, 8> resoSwitchVals; - std::array tofNsigmaCut; - std::array itsNsigmaCut; - std::array tpcNsigmaCut; + std::array, 14> resoCutVals{}; + std::array, 8> resoSwitchVals{}; + std::array tofNsigmaCut{}; + std::array itsNsigmaCut{}; + std::array tpcNsigmaCut{}; enum FractionSetup { FractionV02 = 0, @@ -369,14 +377,27 @@ struct FlowGenericFramework { SpeciesCount }; enum EfficiencySpecies { - EfficiencyCharged = ChargedID, - EfficiencyPion = PionID, - EfficiencyKaon = KaonID, - EfficiencyProton = ProtonID, - EfficiencyK0 = 4, + EfficiencyCharged = 0, + EfficiencyPion, + EfficiencyKaon, + EfficiencyProton, + EfficiencyK0, EfficiencyLambda, EfficiencySpeciesCount }; + enum V0EfficiencyStage { + V0EfficiencyCandidate = 0, + V0EfficiencyDaughterMCLabels, + V0EfficiencyDaughterMothers, + V0EfficiencyCommonPrimaryMother, + V0EfficiencyMotherSpecies, + V0EfficiencyMotherRapidity, + V0EfficiencyGeneratedDaughterEta, + V0EfficiencyRecoDaughterEta, + V0EfficiencySelection, + V0EfficiencyFilled, + V0EfficiencyStageCount + }; enum ResoIDs { K0Sideband1 = 0, K0Signal, @@ -388,10 +409,10 @@ struct FlowGenericFramework { }; enum OutputSpecies { K0 = 0, - Lambda = 1, - PhiMeson = 2, - LambdaBar = 3, - RefParticle = 4, + Lambda, + PhiMeson, + LambdaBar, + RefParticle, OutputSpeciesCount }; enum ParticleCuts { @@ -445,25 +466,24 @@ struct FlowGenericFramework { std::vector corrconfigsV0; TRandom3* fRndm = new TRandom3(0); - TAxis* fPtAxis; + TAxis* fPtAxis = nullptr; int lastRun = -1; std::vector runNumbers; // Density dependent eff correction std::vector funcEff; - TH1D* hFindPtBin; - TF1* funcV2; - TF1* funcV3; - TF1* funcV4; + TH1D* hFindPtBin = nullptr; + TF1* funcV2 = nullptr; + TF1* funcV3 = nullptr; + TF1* funcV4 = nullptr; struct DensityCorr { - double psi2Est; - double psi3Est; - double psi4Est; - double v2; - double v3; - double v4; - int density; - DensityCorr() : psi2Est(0.), psi3Est(0.), psi4Est(0.), v2(0.), v3(0.), v4(0.), density(0) {} + double psi2Est = 0.; + double psi3Est = 0.; + double psi4Est = 0.; + double v2 = 0.; + double v3 = 0.; + double v4 = 0.; + int density = 0; }; // Event selection cuts - multiplicity correlation @@ -488,64 +508,70 @@ struct FlowGenericFramework { void init(InitContext const&) { LOGF(info, "FlowGenericFramework::init()"); - o2::analysis::gfw::regions.SetNames(cfgRegions->GetNames()); - o2::analysis::gfw::regions.SetEtaMin(cfgRegions->GetEtaMin()); - o2::analysis::gfw::regions.SetEtaMax(cfgRegions->GetEtaMax()); - o2::analysis::gfw::regions.SetpTDifs(cfgRegions->GetpTDifs()); - o2::analysis::gfw::regions.SetBitmasks(cfgRegions->GetBitmasks()); - o2::analysis::gfw::configs.SetCorrs(cfgCorrConfig->GetCorrs()); - o2::analysis::gfw::configs.SetHeads(cfgCorrConfig->GetHeads()); - o2::analysis::gfw::configs.SetpTDifs(cfgCorrConfig->GetpTDifs()); - o2::analysis::gfw::configs.SetpTCorrMasks(cfgCorrConfig->GetpTCorrMasks()); - o2::analysis::gfw::regions.Print(); - o2::analysis::gfw::configs.Print(); - o2::analysis::gfw::configsV02.SetCorrs(cfgCorrConfigV02->GetCorrs()); - o2::analysis::gfw::configsV02.SetHeads(cfgCorrConfigV02->GetHeads()); - o2::analysis::gfw::configsV02.SetpTDifs(cfgCorrConfigV02->GetpTDifs()); - o2::analysis::gfw::configsV02.SetpTCorrMasks(cfgCorrConfigV02->GetpTCorrMasks()); - o2::analysis::gfw::configsV02.Print(); - o2::analysis::gfw::configsV0.SetCorrs(cfgCorrConfigV0->GetCorrs()); - o2::analysis::gfw::configsV0.SetHeads(cfgCorrConfigV0->GetHeads()); - o2::analysis::gfw::configsV0.SetpTDifs(cfgCorrConfigV0->GetpTDifs()); - o2::analysis::gfw::configsV0.SetpTCorrMasks(cfgCorrConfigV0->GetpTCorrMasks()); - o2::analysis::gfw::configsV0.Print(); - o2::analysis::gfw::ptbinning = cfgGFWBinning->GetPtBinning(); - o2::analysis::gfw::ptpoilow = cfgGFWBinning->GetPtPOImin(); - o2::analysis::gfw::ptpoiup = cfgGFWBinning->GetPtPOImax(); - o2::analysis::gfw::ptreflow = cfgGFWBinning->GetPtRefMin(); - o2::analysis::gfw::ptrefup = cfgGFWBinning->GetPtRefMax(); - o2::analysis::gfw::ptlow = cfgPtmin; - o2::analysis::gfw::ptup = cfgPtmax; - o2::analysis::gfw::etabins = cfgGFWBinning->GetEtaBins(); - o2::analysis::gfw::vtxZbins = cfgGFWBinning->GetVtxZbins(); - o2::analysis::gfw::phibins = cfgGFWBinning->GetPhiBins(); - o2::analysis::gfw::philow = 0.0f; - o2::analysis::gfw::phiup = o2::constants::math::TwoPI; - o2::analysis::gfw::nchbins = cfgGFWBinning->GetNchBins(); - o2::analysis::gfw::nchlow = cfgGFWBinning->GetNchMin(); - o2::analysis::gfw::nchup = cfgGFWBinning->GetNchMax(); - o2::analysis::gfw::centbinning = cfgGFWBinning->GetCentBinning(); + gfwMemberCache.regions.SetNames(cfgRegions->GetNames()); + gfwMemberCache.regions.SetEtaMin(cfgRegions->GetEtaMin()); + gfwMemberCache.regions.SetEtaMax(cfgRegions->GetEtaMax()); + gfwMemberCache.regions.SetpTDifs(cfgRegions->GetpTDifs()); + gfwMemberCache.regions.SetBitmasks(cfgRegions->GetBitmasks()); + gfwMemberCache.configs.SetCorrs(cfgCorrConfig->GetCorrs()); + gfwMemberCache.configs.SetHeads(cfgCorrConfig->GetHeads()); + gfwMemberCache.configs.SetpTDifs(cfgCorrConfig->GetpTDifs()); + gfwMemberCache.configs.SetpTCorrMasks(cfgCorrConfig->GetpTCorrMasks()); + gfwMemberCache.regions.Print(); + gfwMemberCache.configs.Print(); + gfwMemberCache.configsV02.SetCorrs(cfgCorrConfigV02->GetCorrs()); + gfwMemberCache.configsV02.SetHeads(cfgCorrConfigV02->GetHeads()); + gfwMemberCache.configsV02.SetpTDifs(cfgCorrConfigV02->GetpTDifs()); + gfwMemberCache.configsV02.SetpTCorrMasks(cfgCorrConfigV02->GetpTCorrMasks()); + gfwMemberCache.configsV02.Print(); + gfwMemberCache.configsV0.SetCorrs(cfgCorrConfigV0->GetCorrs()); + gfwMemberCache.configsV0.SetHeads(cfgCorrConfigV0->GetHeads()); + gfwMemberCache.configsV0.SetpTDifs(cfgCorrConfigV0->GetpTDifs()); + gfwMemberCache.configsV0.SetpTCorrMasks(cfgCorrConfigV0->GetpTCorrMasks()); + gfwMemberCache.configsV0.Print(); + gfwMemberCache.ptbinning = cfgGFWBinning->GetPtBinning(); + gfwMemberCache.ptpoilow = cfgGFWBinning->GetPtPOImin(); + gfwMemberCache.ptpoiup = cfgGFWBinning->GetPtPOImax(); + gfwMemberCache.ptreflow = cfgGFWBinning->GetPtRefMin(); + gfwMemberCache.ptrefup = cfgGFWBinning->GetPtRefMax(); + gfwMemberCache.ptlow = cfgKinematics.cfgPtMin; + gfwMemberCache.ptup = cfgKinematics.cfgPtmax; + gfwMemberCache.etabins = cfgGFWBinning->GetEtaBins(); + gfwMemberCache.vtxZbins = cfgGFWBinning->GetVtxZbins(); + gfwMemberCache.phibins = cfgGFWBinning->GetPhiBins(); + gfwMemberCache.philow = 0.0f; + gfwMemberCache.phiup = o2::constants::math::TwoPI; + gfwMemberCache.nchbins = cfgGFWBinning->GetNchBins(); + gfwMemberCache.nchlow = cfgGFWBinning->GetNchMin(); + gfwMemberCache.nchup = cfgGFWBinning->GetNchMax(); + gfwMemberCache.centbinning = cfgGFWBinning->GetCentBinning(); cfgGFWBinning->Print(); LOGF(info, "Eta cuts: Filter [%.1f,%.1f] | Nch [%.1f,%.1f] | Npt v02 [%.1f, %.1f] | Npt v0 [%.1f, %.1f] | Pt-Pt [%.1f, %.1f]", cfgKinematics.cfgEta->first, cfgKinematics.cfgEta->second, cfgKinematics.cfgEtaNch->first, cfgKinematics.cfgEtaNch->second, cfgKinematics.cfgEtaNptV02->first, cfgKinematics.cfgEtaNptV02->second, cfgKinematics.cfgEtaNptV0->first, cfgKinematics.cfgEtaNptV0->second, cfgKinematics.cfgEtaPtPt->first, cfgKinematics.cfgEtaPtPt->second); - o2::analysis::gfw::multGlobalCorrCutPars = cfgMultCorrCuts.cfgMultGlobalCutPars; - o2::analysis::gfw::multPVCorrCutPars = cfgMultCorrCuts.cfgMultPVCutPars; - o2::analysis::gfw::multGlobalPVCorrCutPars = cfgMultCorrCuts.cfgMultGlobalPVCutPars; - o2::analysis::gfw::multGlobalV0ACutPars = cfgMultCorrCuts.cfgMultGlobalV0ACutPars; - o2::analysis::gfw::multGlobalT0ACutPars = cfgMultCorrCuts.cfgMultGlobalT0ACutPars; + gfwMemberCache.multGlobalCorrCutPars = cfgMultCorrCuts.cfgMultGlobalCutPars; + gfwMemberCache.multPVCorrCutPars = cfgMultCorrCuts.cfgMultPVCutPars; + gfwMemberCache.multGlobalPVCorrCutPars = cfgMultCorrCuts.cfgMultGlobalPVCutPars; + gfwMemberCache.multGlobalV0ACutPars = cfgMultCorrCuts.cfgMultGlobalV0ACutPars; + gfwMemberCache.multGlobalT0ACutPars = cfgMultCorrCuts.cfgMultGlobalT0ACutPars; projectMatrix(cfgPIDCuts.nSigmas->getData(), tpcNsigmaCut, tofNsigmaCut, itsNsigmaCut); readMatrix(cfgPIDCuts.resonanceCuts->getData(), resoCutVals); readMatrix(cfgPIDCuts.resonanceSwitches->getData(), resoSwitchVals); printResoCuts(); - int nPtPtSubMax = 4; - for (int i = 0; i < nPtPtSubMax; ++i) { - if (cfgPtPtGaps->getData()[i][0] < -1. || cfgPtPtGaps->getData()[i][1] < -1.) + const auto& ptPtGaps = cfgPtPtGaps->getData(); + + for (uint32_t i = 0; i < ptPtGaps.rows; ++i) { + const auto etaMin = ptPtGaps(i, 0); + const auto etaMax = ptPtGaps(i, 1); + + if (etaMin < -1. || etaMax < -1.) { continue; - o2::analysis::gfw::etagapsPtPt.push_back(std::make_pair(cfgPtPtGaps->getData()[i][0], cfgPtPtGaps->getData()[i][1])); + } + + gfwMemberCache.etagapsPtPt.emplace_back(etaMin, etaMax); } - for (const auto& [etamin, etamax] : o2::analysis::gfw::etagapsPtPt) { + for (const auto& [etamin, etamax] : gfwMemberCache.etagapsPtPt) { LOGF(info, "pt-pt subevent: {%.1f,%.1f}", etamin, etamax); } @@ -563,17 +589,17 @@ struct FlowGenericFramework { LOGF(info, "Flag %d is %senabled", cut.histBin, (cut.enabled) ? "" : "not "); } - AxisSpec phiAxis = {o2::analysis::gfw::phibins, o2::analysis::gfw::philow, o2::analysis::gfw::phiup, "#phi"}; + AxisSpec phiAxis = {gfwMemberCache.phibins, gfwMemberCache.philow, gfwMemberCache.phiup, "#phi"}; AxisSpec phiModAxis = {100, 0, constants::math::PI / 9, "fmod(#varphi,#pi/9)"}; - AxisSpec etaAxis = {o2::analysis::gfw::etabins, cfgKinematics.cfgEta->first, cfgKinematics.cfgEta->second, "#eta"}; - AxisSpec vtxAxis = {o2::analysis::gfw::vtxZbins, -cfgVtxZ, cfgVtxZ, "Vtx_{z} (cm)"}; - AxisSpec ptAxis = {o2::analysis::gfw::ptbinning, "#it{p}_{T} GeV/#it{c}"}; + AxisSpec etaAxis = {gfwMemberCache.etabins, cfgKinematics.cfgEta->first, cfgKinematics.cfgEta->second, "#eta"}; + AxisSpec vtxAxis = {gfwMemberCache.vtxZbins, -cfgVtxZ, cfgVtxZ, "Vtx_{z} (cm)"}; + AxisSpec ptAxis = {gfwMemberCache.ptbinning, "#it{p}_{T} GeV/#it{c}"}; std::string sCentralityEstimator = centNamesMap[cfgCentEstimator] + " centrality (%)"; - AxisSpec centAxis = {o2::analysis::gfw::centbinning, sCentralityEstimator.c_str()}; + AxisSpec centAxis = {gfwMemberCache.centbinning, sCentralityEstimator.c_str()}; std::vector nchbinning; - int nchskip = (o2::analysis::gfw::nchup - o2::analysis::gfw::nchlow) / o2::analysis::gfw::nchbins; - for (int i = 0; i <= o2::analysis::gfw::nchbins; ++i) { - nchbinning.push_back(nchskip * i + o2::analysis::gfw::nchlow + 0.5); + const double nchskip = (gfwMemberCache.nchup - gfwMemberCache.nchlow) / gfwMemberCache.nchbins; + for (int i = 0; i <= gfwMemberCache.nchbins; ++i) { + nchbinning.push_back(nchskip * i + gfwMemberCache.nchlow + 0.5); } AxisSpec nchAxis = {nchbinning, "N_{ch}"}; AxisSpec bAxis = {200, 0, 20, "#it{b}"}; @@ -589,6 +615,7 @@ struct FlowGenericFramework { AxisSpec singleCount = {1, 0, 1}; AxisSpec efficiencyParticleAxis = {EfficiencySpeciesCount, -0.5, static_cast(EfficiencySpeciesCount) - 0.5, "particle"}; AxisSpec efficiencyStepAxis = {EfficiencyStepCount, -0.5, static_cast(EfficiencyStepCount) - 0.5, "generated/reconstructed"}; + AxisSpec v0EfficiencyStageAxis = {V0EfficiencyStageCount, -0.5, static_cast(V0EfficiencyStageCount) - 0.5, "stage"}; ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); @@ -596,20 +623,22 @@ struct FlowGenericFramework { int64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); ccdb->setCreatedNotAfter(now); - int ptbins = o2::analysis::gfw::ptbinning.size() - 1; - fPtAxis = new TAxis(ptbins, &o2::analysis::gfw::ptbinning[0]); + const int ptbins = static_cast(gfwMemberCache.ptbinning.size() - 1); + fPtAxis = new TAxis(ptbins, gfwMemberCache.ptbinning.data()); if (doprocessMCGen || doprocessOnTheFly) { if (cfgFill.cfgFillQA) { registryQA.add("MCGen/before/pt_gen", "", {HistType::kTH1D, {ptAxis}}); registryQA.add("MCGen/before/phi_eta_vtxZ_gen", "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); registryQA.addClone("MCGen/before/", "MCGen/after/"); - if (doprocessOnTheFly) + if (doprocessOnTheFly) { registryQA.add("MCGen/impactParameter", "", {HistType::kTH2D, {{bAxis, nchAxis}}}); + } } } if (doprocessEfficiency) { registry.add("Efficiency/efficiencyHist", "; #it{p}_{T}^{MC}; Centrality (%)", {HistType::kTHnSparseF, {{ptAxis, centAxis, efficiencyParticleAxis, efficiencyStepAxis}}}); + registry.add("Efficiency/v0RecoDebug", "; #it{p}_{T}; Centrality (%)", {HistType::kTHnSparseF, {{ptAxis, centAxis, efficiencyParticleAxis, v0EfficiencyStageAxis}}}); } if (doprocessMCReco || doprocessData || doprocessRun2 || doprocessEfficiency) { if (cfgFill.cfgFillQA) { @@ -623,8 +652,8 @@ struct FlowGenericFramework { registryQA.add("trackQA/before/nTPCCrossedRows", "Number of crossed TPC Rows", {HistType::kTH1D, {{100, 40, 180}}}); registryQA.addClone("trackQA/before/", "trackQA/after/"); - registryQA.add("trackQA/after/pt_ref", "; #it{p}_{T}; Counts", {HistType::kTH1D, {{100, o2::analysis::gfw::ptreflow, o2::analysis::gfw::ptrefup}}}); - registryQA.add("trackQA/after/pt_poi", "; #it{p}_{T}; Counts", {HistType::kTH1D, {{100, o2::analysis::gfw::ptpoilow, o2::analysis::gfw::ptpoiup}}}); + registryQA.add("trackQA/after/pt_ref", "; #it{p}_{T}; Counts", {HistType::kTH1D, {{100, gfwMemberCache.ptreflow, gfwMemberCache.ptrefup}}}); + registryQA.add("trackQA/after/pt_poi", "; #it{p}_{T}; Counts", {HistType::kTH1D, {{100, gfwMemberCache.ptpoilow, gfwMemberCache.ptpoiup}}}); registryQA.add("trackQA/after/Nch_corrected", "; N_{ch}; Counts", {HistType::kTH1D, {nchAxis}}); registryQA.add("trackQA/after/Nch_uncorrected", "; N_{ch}; Counts", {HistType::kTH1D, {nchAxis}}); registryQA.add("trackQA/after/etaNch", "; #eta; Counts", {HistType::kTH1D, {etaAxis}}); @@ -675,14 +704,15 @@ struct FlowGenericFramework { AxisSpec axisLambdaMass = {resoSwitchVals[MassBins][Lambda], resoCutVals[MassMin][Lambda], resoCutVals[MassMax][Lambda]}; // QA histograms for V0s - if (resoSwitchVals[UseParticle][K0]) { - if (cfgFill.cfgFillQA) { + if (resoSwitchVals[UseParticle][K0] != 0) { + if (cfgFill.cfgFillV0QA) { registryQA.add("K0/PiPlusTPC_K0", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTPC}}}); registryQA.add("K0/PiMinusTPC_K0", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTPC}}}); registryQA.add("K0/PiPlusTOF_K0", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTOF}}}); registryQA.add("K0/PiMinusTOF_K0", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTOF}}}); registryQA.add("K0/hK0Phi", "", {HistType::kTH1D, {phiAxis}}); registryQA.add("K0/hK0Eta", "", {HistType::kTH1D, {etaAxis}}); + registryQA.add("K0/hK0AP", "", {HistType::kTH2D, {{100, -1, 1}, {100, 0, 5.}}}); registryQA.add("K0/hK0Mass_sparse", "", {HistType::kTHnSparseF, {{axisK0Mass, ptAxis, nchAxis}}}); registryQA.add("K0/hK0s", "", {HistType::kTH1D, {singleCount}}); registryQA.add("K0/hK0s_corrected", "", {HistType::kTH1D, {singleCount}}); @@ -703,14 +733,15 @@ struct FlowGenericFramework { registryQA.get(HIST("K0/hK0Count"))->GetXaxis()->SetBinLabel(FillV0DaughterTrackSelection, "v0 Daughter track selection"); } - if (resoSwitchVals[UseParticle][Lambda]) { - if (cfgFill.cfgFillQA) { + if (resoSwitchVals[UseParticle][Lambda] != 0) { + if (cfgFill.cfgFillV0QA) { registryQA.add("Lambda/PrPlusTPC_L", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTPC}}}); registryQA.add("Lambda/PiMinusTPC_L", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTPC}}}); registryQA.add("Lambda/PrPlusTOF_L", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTOF}}}); registryQA.add("Lambda/PiMinusTOF_L", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTOF}}}); registryQA.add("Lambda/hLambdaPhi", "", {HistType::kTH1D, {phiAxis}}); registryQA.add("Lambda/hLambdaEta", "", {HistType::kTH1D, {etaAxis}}); + registryQA.add("Lambda/hLambdaAP", "", {HistType::kTH2D, {{100, -1, 1}, {100, 0, 5.}}}); registryQA.add("Lambda/hLambdaMass_sparse", "", {HistType::kTHnSparseF, {{axisLambdaMass, ptAxis, nchAxis}}}); registryQA.add("Lambda/PiPlusTPC_AL", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTPC}}}); registryQA.add("Lambda/PrMinusTPC_AL", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTPC}}}); @@ -718,6 +749,7 @@ struct FlowGenericFramework { registryQA.add("Lambda/PrMinusTOF_AL", "", {HistType::kTH2D, {{ptAxis, axisNsigmaTOF}}}); registryQA.add("Lambda/hAntiLambdaPhi", "", {HistType::kTH1D, {phiAxis}}); registryQA.add("Lambda/hAntiLambdaEta", "", {HistType::kTH1D, {etaAxis}}); + registryQA.add("Lambda/hAntiLambdaAP", "", {HistType::kTH2D, {{100, -1, 1}, {100, 0, 5.}}}); registryQA.add("Lambda/hAntiLambdaMass_sparse", "", {HistType::kTHnSparseF, {{axisLambdaMass, ptAxis, nchAxis}}}); registryQA.add("Lambda/hLambdas", "", {HistType::kTH1D, {singleCount}}); registryQA.add("Lambda/hLambdas_corrected", "", {HistType::kTH1D, {singleCount}}); @@ -777,31 +809,35 @@ struct FlowGenericFramework { histosResoNpt[setup][LambdaSideband2] = std::make_unique(Form("npt%sLambdaSB2", setupName), "; #it{p}_{T} (GeV/#it{c}; Count", ptAxis.binEdges.size() - 1, ptAxis.binEdges.data()); } - if (o2::analysis::gfw::regions.GetSize() < 0) + if (gfwMemberCache.regions.GetSize() < 0) { LOGF(error, "Configuration contains vectors of different size - check the GFWRegions configurable"); - for (auto i(0); i < o2::analysis::gfw::regions.GetSize(); ++i) { - fGFW->AddRegion(o2::analysis::gfw::regions.GetNames()[i], o2::analysis::gfw::regions.GetEtaMin()[i], o2::analysis::gfw::regions.GetEtaMax()[i], (o2::analysis::gfw::regions.GetpTDifs()[i]) ? ptbins + 1 : 1, o2::analysis::gfw::regions.GetBitmasks()[i]); } - for (auto i = 0; i < o2::analysis::gfw::configs.GetSize(); ++i) { - corrconfigs.push_back(fGFW->GetCorrelatorConfig(o2::analysis::gfw::configs.GetCorrs()[i], o2::analysis::gfw::configs.GetHeads()[i], o2::analysis::gfw::configs.GetpTDifs()[i])); + for (auto i(0); i < gfwMemberCache.regions.GetSize(); ++i) { + fGFW->AddRegion(gfwMemberCache.regions.GetNames()[i], gfwMemberCache.regions.GetEtaMin()[i], gfwMemberCache.regions.GetEtaMax()[i], (gfwMemberCache.regions.GetpTDifs()[i] != 0) ? ptbins + 1 : 1, gfwMemberCache.regions.GetBitmasks()[i]); + } + for (auto i = 0; i < gfwMemberCache.configs.GetSize(); ++i) { + corrconfigs.push_back(fGFW->GetCorrelatorConfig(gfwMemberCache.configs.GetCorrs()[i], gfwMemberCache.configs.GetHeads()[i], gfwMemberCache.configs.GetpTDifs()[i] != 0)); } - if (corrconfigs.empty()) + if (corrconfigs.empty()) { LOGF(error, "Configuration contains vectors of different size - check the GFWCorrConfig configurable"); + } // Radial flow configs - for (auto i = 0; i < o2::analysis::gfw::configsV02.GetSize(); ++i) { - corrconfigsV02.push_back(fGFW->GetCorrelatorConfig(o2::analysis::gfw::configsV02.GetCorrs()[i], o2::analysis::gfw::configsV02.GetHeads()[i], o2::analysis::gfw::configsV02.GetpTDifs()[i])); + for (auto i = 0; i < gfwMemberCache.configsV02.GetSize(); ++i) { + corrconfigsV02.push_back(fGFW->GetCorrelatorConfig(gfwMemberCache.configsV02.GetCorrs()[i], gfwMemberCache.configsV02.GetHeads()[i], gfwMemberCache.configsV02.GetpTDifs()[i] != 0)); } - if (corrconfigsV02.empty()) + if (corrconfigsV02.empty()) { LOGF(error, "Radial (V02) configuration contains vectors of different size - check the GFWCorrConfig configurable"); - for (auto i = 0; i < o2::analysis::gfw::configsV0.GetSize(); ++i) { - corrconfigsV0.push_back(fGFW->GetCorrelatorConfig(o2::analysis::gfw::configsV0.GetCorrs()[i], o2::analysis::gfw::configsV0.GetHeads()[i], o2::analysis::gfw::configsV0.GetpTDifs()[i])); } - if (corrconfigsV0.empty()) + for (auto i = 0; i < gfwMemberCache.configsV0.GetSize(); ++i) { + corrconfigsV0.push_back(fGFW->GetCorrelatorConfig(gfwMemberCache.configsV0.GetCorrs()[i], gfwMemberCache.configsV0.GetHeads()[i], gfwMemberCache.configsV0.GetpTDifs()[i] != 0)); + } + if (corrconfigsV0.empty()) { LOGF(error, "Radial (V0) configuration contains vectors of different size - check the GFWCorrConfig configurable"); + } fGFW->CreateRegions(); - TObjArray* oba = new TObjArray(); + auto oba = new TObjArray(); addConfigObjectsToObjArray(oba, corrconfigs); addConfigObjectsToObjArray(oba, corrconfigsV02); addConfigObjectsToObjArray(oba, corrconfigsV0); @@ -820,8 +856,8 @@ struct FlowGenericFramework { fFCpt->setUseCentralMoments(cfgUseCentralMoments); fFCpt->setUseGapMethod(cfgUseGapMethod); - fFCpt->initialise(multAxis, cfgMpar, o2::analysis::gfw::configs, cfgNbootstrap); - fFCpt->initialiseSubevent(multAxis, cfgMpar, o2::analysis::gfw::etagapsPtPt.size(), cfgNbootstrap); + fFCpt->initialise(multAxis, cfgMpar, gfwMemberCache.configs, cfgNbootstrap); + fFCpt->initialiseSubevent(multAxis, cfgMpar, gfwMemberCache.etagapsPtPt.size(), cfgNbootstrap); fPtDepDCAxy = new TF1("ptDepDCAxy", Form("[0]*%s", cfgTrackCuts.cfgDCAxyPtDep->c_str()), 0.001, 100); fPtDepDCAxy->SetParameter(0, cfgTrackCuts.cfgDCAxyNSigma / 7.); @@ -832,47 +868,55 @@ struct FlowGenericFramework { } // Multiplicity correlation cuts - if (cfgMultCut) { + if (cfgEventSelection.cfgMultCut) { fMultPVCutLow = new TF1("fMultPVCutLow", cfgMultCorrCuts.cfgMultCorrLowCutFunction->c_str(), 0, 100); - fMultPVCutLow->SetParameters(&(o2::analysis::gfw::multPVCorrCutPars[0])); + fMultPVCutLow->SetParameters(gfwMemberCache.multPVCorrCutPars.data()); fMultPVCutHigh = new TF1("fMultPVCutHigh", cfgMultCorrCuts.cfgMultCorrHighCutFunction->c_str(), 0, 100); - fMultPVCutHigh->SetParameters(&(o2::analysis::gfw::multPVCorrCutPars[0])); + fMultPVCutHigh->SetParameters(gfwMemberCache.multPVCorrCutPars.data()); fMultCutLow = new TF1("fMultCutLow", cfgMultCorrCuts.cfgMultCorrLowCutFunction->c_str(), 0, 100); - fMultCutLow->SetParameters(&(o2::analysis::gfw::multGlobalCorrCutPars[0])); + fMultCutLow->SetParameters(gfwMemberCache.multGlobalCorrCutPars.data()); fMultCutHigh = new TF1("fMultCutHigh", cfgMultCorrCuts.cfgMultCorrHighCutFunction->c_str(), 0, 100); - fMultCutHigh->SetParameters(&(o2::analysis::gfw::multGlobalCorrCutPars[0])); + fMultCutHigh->SetParameters(gfwMemberCache.multGlobalCorrCutPars.data()); fMultPVGlobalCutHigh = new TF1("fMultPVGlobalCutHigh", cfgMultCorrCuts.cfgMultGlobalPVCorrCutFunction->c_str(), 0, nchbinning.back()); - fMultPVGlobalCutHigh->SetParameters(&(o2::analysis::gfw::multGlobalPVCorrCutPars[0])); + fMultPVGlobalCutHigh->SetParameters(gfwMemberCache.multGlobalPVCorrCutPars.data()); LOGF(info, "Global V0A function: %s in range 0-%g", cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), v0aAxis.binEdges.back()); fMultGlobalV0ACutLow = new TF1("fMultGlobalV0ACutLow", cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, v0aAxis.binEdges.back()); - for (std::size_t i = 0; i < o2::analysis::gfw::multGlobalV0ACutPars.size(); ++i) - fMultGlobalV0ACutLow->SetParameter(i, o2::analysis::gfw::multGlobalV0ACutPars[i]); - fMultGlobalV0ACutLow->SetParameter(o2::analysis::gfw::multGlobalV0ACutPars.size(), cfgMultCorrCuts.cfgGlobalV0ALowSigma); - for (int i = 0; i < fMultGlobalV0ACutLow->GetNpar(); ++i) + for (std::size_t i = 0; i < gfwMemberCache.multGlobalV0ACutPars.size(); ++i) { + fMultGlobalV0ACutLow->SetParameter(i, gfwMemberCache.multGlobalV0ACutPars[i]); + } + fMultGlobalV0ACutLow->SetParameter(gfwMemberCache.multGlobalV0ACutPars.size(), cfgMultCorrCuts.cfgGlobalV0ALowSigma); + for (int i = 0; i < fMultGlobalV0ACutLow->GetNpar(); ++i) { LOGF(info, "fMultGlobalV0ACutLow par %d = %g", i, fMultGlobalV0ACutLow->GetParameter(i)); + } fMultGlobalV0ACutHigh = new TF1("fMultGlobalV0ACutHigh", cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, v0aAxis.binEdges.back()); - for (std::size_t i = 0; i < o2::analysis::gfw::multGlobalV0ACutPars.size(); ++i) - fMultGlobalV0ACutHigh->SetParameter(i, o2::analysis::gfw::multGlobalV0ACutPars[i]); - fMultGlobalV0ACutHigh->SetParameter(o2::analysis::gfw::multGlobalV0ACutPars.size(), cfgMultCorrCuts.cfgGlobalV0AHighSigma); - for (int i = 0; i < fMultGlobalV0ACutHigh->GetNpar(); ++i) + for (std::size_t i = 0; i < gfwMemberCache.multGlobalV0ACutPars.size(); ++i) { + fMultGlobalV0ACutHigh->SetParameter(i, gfwMemberCache.multGlobalV0ACutPars[i]); + } + fMultGlobalV0ACutHigh->SetParameter(gfwMemberCache.multGlobalV0ACutPars.size(), cfgMultCorrCuts.cfgGlobalV0AHighSigma); + for (int i = 0; i < fMultGlobalV0ACutHigh->GetNpar(); ++i) { LOGF(info, "fMultGlobalV0ACutHigh par %d = %g", i, fMultGlobalV0ACutHigh->GetParameter(i)); + } LOGF(info, "Global T0A function: %s", cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str()); fMultGlobalT0ACutLow = new TF1("fMultGlobalT0ACutLow", cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, t0aAxis.binEdges.back()); - for (std::size_t i = 0; i < o2::analysis::gfw::multGlobalT0ACutPars.size(); ++i) - fMultGlobalT0ACutLow->SetParameter(i, o2::analysis::gfw::multGlobalT0ACutPars[i]); - fMultGlobalT0ACutLow->SetParameter(o2::analysis::gfw::multGlobalT0ACutPars.size(), cfgMultCorrCuts.cfgGlobalT0ALowSigma); - for (int i = 0; i < fMultGlobalT0ACutLow->GetNpar(); ++i) + for (std::size_t i = 0; i < gfwMemberCache.multGlobalT0ACutPars.size(); ++i) { + fMultGlobalT0ACutLow->SetParameter(i, gfwMemberCache.multGlobalT0ACutPars[i]); + } + fMultGlobalT0ACutLow->SetParameter(gfwMemberCache.multGlobalT0ACutPars.size(), cfgMultCorrCuts.cfgGlobalT0ALowSigma); + for (int i = 0; i < fMultGlobalT0ACutLow->GetNpar(); ++i) { LOGF(info, "fMultGlobalT0ACutLow par %d = %g", i, fMultGlobalT0ACutLow->GetParameter(i)); + } fMultGlobalT0ACutHigh = new TF1("fMultGlobalT0ACutHigh", cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, t0aAxis.binEdges.back()); - for (std::size_t i = 0; i < o2::analysis::gfw::multGlobalT0ACutPars.size(); ++i) - fMultGlobalT0ACutHigh->SetParameter(i, o2::analysis::gfw::multGlobalT0ACutPars[i]); - fMultGlobalT0ACutHigh->SetParameter(o2::analysis::gfw::multGlobalT0ACutPars.size(), cfgMultCorrCuts.cfgGlobalT0AHighSigma); - for (int i = 0; i < fMultGlobalT0ACutHigh->GetNpar(); ++i) + for (std::size_t i = 0; i < gfwMemberCache.multGlobalT0ACutPars.size(); ++i) { + fMultGlobalT0ACutHigh->SetParameter(i, gfwMemberCache.multGlobalT0ACutPars[i]); + } + fMultGlobalT0ACutHigh->SetParameter(gfwMemberCache.multGlobalT0ACutPars.size(), cfgMultCorrCuts.cfgGlobalT0AHighSigma); + for (int i = 0; i < fMultGlobalT0ACutHigh->GetNpar(); ++i) { LOGF(info, "fMultGlobalT0ACutHigh par %d = %g", i, fMultGlobalT0ACutHigh->GetParameter(i)); + } } if (cfgTrackCuts.cfgTPCSectorCut) { @@ -882,7 +926,7 @@ struct FlowGenericFramework { // Density dependent corrections if (cfgUseDensityDependentCorrection) { std::vector pTEffBins = {0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.4, 1.8, 2.2, 2.6, 3.0}; - hFindPtBin = new TH1D("hFindPtBin", "hFindPtBin", pTEffBins.size() - 1, &pTEffBins[0]); + hFindPtBin = new TH1D("hFindPtBin", "hFindPtBin", pTEffBins.size() - 1, pTEffBins.data()); funcEff.resize(pTEffBins.size() - 1); // LHC24g3 Eff std::vector f1p0 = cfgTrackDensityP0; @@ -900,7 +944,7 @@ struct FlowGenericFramework { } } - static constexpr std::string_view FillTimeName[] = {"before/", "after/"}; + static constexpr std::array FillTimeName = {"before/", "after/"}; void printResoCuts() { @@ -924,15 +968,17 @@ struct FlowGenericFramework { // Determine row label width size_t rowLabelWidth = 0; - for (const auto& rowName : lbl.labels_rows) + for (const auto& rowName : lbl.labels_rows) { rowLabelWidth = std::max(rowLabelWidth, rowName.size()); + } rowLabelWidth += 2; // for ": " // Print header std::ostringstream header; header << std::setw(rowLabelWidth) << " "; - for (size_t c = 0; c < nCols; ++c) + for (size_t c = 0; c < nCols; ++c) { header << std::setw(colWidths[c]) << lbl.labels_cols[c] << " "; + } LOGF(info, "%s", header.str().c_str()); // Print rows @@ -958,14 +1004,16 @@ struct FlowGenericFramework { // ----- Resonance Cuts ----- std::vector> resoCutsVals(resoCutVals.size()); - for (size_t r = 0; r < resoCutVals.size(); ++r) + for (size_t r = 0; r < resoCutVals.size(); ++r) { resoCutsVals[r] = std::vector(resoCutVals[r].begin(), resoCutVals[r].end()); + } printTable(cfgPIDCuts.resonanceCuts.value, resoCutsVals, "Resonance Cuts"); // ----- Resonance Switches ----- std::vector> resoSwitchValsF(resoSwitchVals.size()); - for (size_t r = 0; r < resoSwitchVals.size(); ++r) + for (size_t r = 0; r < resoSwitchVals.size(); ++r) { resoSwitchValsF[r] = std::vector(resoSwitchVals[r].begin(), resoSwitchVals[r].end()); + } printTable(cfgPIDCuts.resonanceSwitches.value, resoSwitchValsF, "Resonance Switches"); } enum QAFillTime { @@ -980,7 +1028,7 @@ struct FlowGenericFramework { std::string suffix = "_ptDiff"; for (auto i = 0; i < fPtAxis->GetNbins(); ++i) { std::string index = Form("_pt_%i", i + 1); - oba->Add(new TNamed(it->Head.c_str() + index, it->Head.c_str() + suffix)); + oba->Add(new TNamed(it->Head + index, it->Head + suffix)); } } else { oba->Add(new TNamed(it->Head.c_str(), it->Head.c_str())); @@ -1008,8 +1056,9 @@ struct FlowGenericFramework { void loadCorrections(aod::BCsWithTimestamps::iterator const& bc) { uint64_t timestamp = bc.timestamp(); - if (!cfgRunByRun && cfg.correctionsLoaded) + if (!cfgRunByRun && cfg.correctionsLoaded) { return; + } if (!cfgAcceptance.value.empty()) { std::string runstr = (cfgRunByRun) ? "RunByRun/" : ""; cfg.mAcceptance.clear(); @@ -1024,14 +1073,16 @@ struct FlowGenericFramework { } } // Run-by-run efficiencies are not supported at the moment - if (cfg.correctionsLoaded) + if (cfg.correctionsLoaded) { return; + } if (!cfgEfficiency.cfgEfficiencyPath.value.empty()) { if (!cfgEfficiency.cfgUsePIDEfficiencies) { - if (cfgEfficiency.cfgUse2DEfficiency) + if (cfgEfficiency.cfgUse2DEfficiency) { cfg.mEfficiency = ccdb->getForTimeStamp(cfgEfficiency.cfgEfficiencyPath, timestamp); - else + } else { cfg.mEfficiency = ccdb->getForTimeStamp(cfgEfficiency.cfgEfficiencyPath, timestamp); + } if (cfg.mEfficiency == nullptr) { LOGF(fatal, "Could not load efficiency histogram from %s", cfgEfficiency.cfgEfficiencyPath.value.c_str()); } @@ -1039,12 +1090,14 @@ struct FlowGenericFramework { } else { std::vector species = {"ch", "pi", "ka", "pr", "k0", "lambda"}; for (const auto& sp : species) { - if (cfgEfficiency.cfgUse2DEfficiency) + if (cfgEfficiency.cfgUse2DEfficiency) { cfg.mPIDEfficiencies.push_back(ccdb->getForTimeStamp(cfgEfficiency.cfgEfficiencyPath.value + "/" + sp, timestamp)); - else + } else { cfg.mPIDEfficiencies.push_back(ccdb->getForTimeStamp(cfgEfficiency.cfgEfficiencyPath.value + "/" + sp, timestamp)); - if (cfg.mPIDEfficiencies.back() == nullptr) + } + if (cfg.mPIDEfficiencies.back() == nullptr) { LOGF(fatal, "Could not load PID efficiency histograms from %s", cfgEfficiency.cfgEfficiencyPath.value + "/" + sp); + } LOGF(info, "Loaded PID efficiency histogram from %s", cfgEfficiency.cfgEfficiencyPath.value + "/" + sp); } } @@ -1053,41 +1106,46 @@ struct FlowGenericFramework { } template - double getAcceptance(TTrack track, const double& vtxz, int index) + double getAcceptance(const TTrack& track, const double& vtxz, int index) { // 0 ref, 1 ch, 2 pi, 3 ka, 4 pr double wacc = 1; - if (!cfg.mAcceptance.empty()) + if (!cfg.mAcceptance.empty()) { wacc = cfg.mAcceptance[index]->getNUA(track.phi(), track.eta(), vtxz); + } return wacc; } template - double getEfficiency(TTrack track, const float& centrality, int pidIndex = 0) + double getEfficiency(const TTrack& track, const float& centrality, int pidIndex = 0) { //-1 ref, 0 ch, 1 pi, 2 ka, 3 pr, 4 k0, 5 lambda double eff = 1.; if (!cfgEfficiency.cfgUsePIDEfficiencies) { - if (!cfg.mEfficiency) + if (!cfg.mEfficiency) { return eff; - if (cfgEfficiency.cfgUse2DEfficiency) + } + if (cfgEfficiency.cfgUse2DEfficiency) { eff = dynamic_cast(cfg.mEfficiency)->GetBinContent(dynamic_cast(cfg.mEfficiency)->FindBin(track.pt(), centrality)); - else + } else { eff = dynamic_cast(cfg.mEfficiency)->GetBinContent(dynamic_cast(cfg.mEfficiency)->FindBin(track.pt())); + } } else { - if (cfg.mPIDEfficiencies.empty()) + if (cfg.mPIDEfficiencies.empty()) { return eff; - if (cfgEfficiency.cfgUse2DEfficiency) + } + if (cfgEfficiency.cfgUse2DEfficiency) { eff = dynamic_cast(cfg.mPIDEfficiencies[pidIndex])->GetBinContent(dynamic_cast(cfg.mPIDEfficiencies[pidIndex])->FindBin(track.pt(), centrality)); - else + } else { eff = dynamic_cast(cfg.mPIDEfficiencies[pidIndex])->GetBinContent(dynamic_cast(cfg.mPIDEfficiencies[pidIndex])->FindBin(track.pt())); + } } - if (eff == 0) + if (eff == 0) { return -1.; - else - return 1. / eff; + } + return 1. / eff; } template - int getNsigmaPID(TTrack track) + int getNsigmaPID(const TTrack& track) { // Computing Nsigma arrays for pion, kaon, and protons std::array nSigmaTPC = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()}; @@ -1097,21 +1155,24 @@ struct FlowGenericFramework { // Choose which nSigma to use std::array nSigmaToUse = (track.pt() > cfgPIDCuts.cfgTofPtCut && track.hasTOF()) ? nSigmaCombined : nSigmaTPC; - if (track.pt() > cfgPIDCuts.cfgTofPtCut && !track.hasTOF()) + if (track.pt() > cfgPIDCuts.cfgTofPtCut && !track.hasTOF()) { return 0; + } const int numSpecies = 3; int pidCount = 0; // Select particle with the lowest nsigma for (int i = 0; i < numSpecies; ++i) { if (std::abs(nSigmaToUse[i]) < nsigma) { - if (pidCount > 0 && cfgPIDCuts.cfgUseStrictPID) + if (pidCount > 0 && cfgPIDCuts.cfgUseStrictPID) { return 0; // more than one particle with low nsigma + } pidCount++; pid = i; - if (!cfgPIDCuts.cfgUseStrictPID) + if (!cfgPIDCuts.cfgUseStrictPID) { nsigma = std::abs(nSigmaToUse[i]); + } } } @@ -1119,7 +1180,7 @@ struct FlowGenericFramework { } template - int getNsigmaPIDAssymmetric(TTrack track) + int getNsigmaPIDAssymmetric(const TTrack& track) { // Computing Nsigma arrays for pion, kaon, and protons std::array nSigmaTPC = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()}; @@ -1130,7 +1191,7 @@ struct FlowGenericFramework { std::array nSigmaToUse = cfgPIDCuts.cfgUseItsPID ? nSigmaITS : nSigmaTPC; // Choose which nSigma to use: TPC or ITS std::array detectorNsigmaCut = cfgPIDCuts.cfgUseItsPID ? itsNsigmaCut : tpcNsigmaCut; // Choose which nSigma to use: TPC or ITS - bool isPion, isKaon, isProton; + bool isPion = false, isKaon = false, isProton = false; bool isDetectedPion = nSigmaToUse[0] < detectorNsigmaCut[0] && nSigmaToUse[0] > detectorNsigmaCut[0 + 3]; bool isDetectedKaon = nSigmaToUse[1] < detectorNsigmaCut[1] && nSigmaToUse[1] > detectorNsigmaCut[1 + 3]; bool isDetectedProton = nSigmaToUse[2] < detectorNsigmaCut[2] && nSigmaToUse[2] > detectorNsigmaCut[2 + 3]; @@ -1141,7 +1202,9 @@ struct FlowGenericFramework { if (track.pt() > cfgPIDCuts.cfgTofPtCut && !track.hasTOF()) { return 0; - } else if (track.pt() > cfgPIDCuts.cfgTofPtCut && track.hasTOF()) { + } + + if (track.pt() > cfgPIDCuts.cfgTofPtCut && track.hasTOF()) { isPion = isTofPion && isDetectedPion; isKaon = isTofKaon && isDetectedKaon; isProton = isTofProton && isDetectedProton; @@ -1169,7 +1232,7 @@ struct FlowGenericFramework { } template - bool eventSelected(TCollision collision, const int multTrk, const float& centrality, const int run) + bool eventSelected(const TCollision& collision, const int multTrk, const float& centrality, const int run) { // Cut on trigger alias if (cfgEventCutFlags.cfgTVXinTRD) { @@ -1179,32 +1242,38 @@ struct FlowGenericFramework { return false; } registryQA.fill(HIST("eventQA/eventSel"), TVXinTRD); - if (cfgFill.cfgFillRunByRunQA) + if (cfgFill.cfgFillRunByRunQA) { th1sList[run][EventSel]->Fill(TVXinTRD); + } } // Cut on event selection flags for (const auto& cut : eventcutflags) { - if (!cut.enabled) + if (!cut.enabled) { continue; - if (!collision.selection_bit(cut.flag)) + } + if (!collision.selection_bit(cut.flag)) { return false; + } registryQA.fill(HIST("eventQA/eventSel"), cut.histBin); - if (cfgFill.cfgFillRunByRunQA) + if (cfgFill.cfgFillRunByRunQA) { th1sList[run][EventSel]->Fill(cut.histBin); + } } // Cut on vertex - if (!selectVertex(collision)) + if (!selectVertex(collision)) { return false; + } // Cut on multiplicity correlations - data driven - if (cfgMultCut) { - if (!selectMultiplicityCorrelation(collision, multTrk, centrality, run)) + if (cfgEventSelection.cfgMultCut) { + if (!selectMultiplicityCorrelation(collision, multTrk, centrality, run)) { return false; + } } return true; } template - bool selectVertex(TCollision collision) + bool selectVertex(const TCollision& collision) { float vtxz = -999; if (collision.numContrib() > 1) { @@ -1212,81 +1281,103 @@ struct FlowGenericFramework { float zRes = std::sqrt(collision.covZZ()); float minZRes = 0.25; int minNContrib = 20; - if (zRes > minZRes && collision.numContrib() < minNContrib) + if (zRes > minZRes && collision.numContrib() < minNContrib) { vtxz = -999; + } } - if (vtxz > o2::analysis::gfw::vtxZup || vtxz < o2::analysis::gfw::vtxZlow) + if (vtxz > gfwMemberCache.vtxZup || vtxz < gfwMemberCache.vtxZlow) { return false; - else - return true; + } + + return true; } template - bool selectMultiplicityCorrelation(TCollision collision, const int multTrk, const float& centrality, const int run) + bool selectMultiplicityCorrelation(const TCollision& collision, const int multTrk, const float& centrality, const int run) { auto multNTracksPV = collision.multNTracksPV(); - if (multNTracksPV < fMultPVCutLow->Eval(centrality)) + if (multNTracksPV < fMultPVCutLow->Eval(centrality)) { return false; - if (multNTracksPV > fMultPVCutHigh->Eval(centrality)) + } + if (multNTracksPV > fMultPVCutHigh->Eval(centrality)) { return false; - if (multTrk < fMultCutLow->Eval(centrality)) + } + if (multTrk < fMultCutLow->Eval(centrality)) { return false; - if (multTrk > fMultCutHigh->Eval(centrality)) + } + if (multTrk > fMultCutHigh->Eval(centrality)) { return false; - if (multTrk > fMultPVGlobalCutHigh->Eval(collision.multNTracksPV())) + } + if (multTrk > fMultPVGlobalCutHigh->Eval(collision.multNTracksPV())) { return false; + } - if (!(cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFV0A()) < fMultGlobalV0ACutLow->Eval(multTrk)) + if (!(cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFV0A()) < fMultGlobalV0ACutLow->Eval(multTrk)) { return false; - if (!(cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFV0A()) > fMultGlobalV0ACutHigh->Eval(multTrk)) + } + if (!(cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFV0A()) > fMultGlobalV0ACutHigh->Eval(multTrk)) { return false; - if (!(cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFT0A()) < fMultGlobalT0ACutLow->Eval(multTrk)) + } + if (!(cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFT0A()) < fMultGlobalT0ACutLow->Eval(multTrk)) { return false; - if (!(cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFT0A()) > fMultGlobalT0ACutHigh->Eval(multTrk)) + } + if (!(cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFT0A()) > fMultGlobalT0ACutHigh->Eval(multTrk)) { return false; + } registryQA.fill(HIST("eventQA/eventSel"), MultCuts); - if (cfgFill.cfgFillRunByRunQA) + if (cfgFill.cfgFillRunByRunQA) { th1sList[run][EventSel]->Fill(MultCuts); + } return true; } template - bool trackSelected(TTrack track, const int field) + bool trackSelected(const TTrack& track, const int field) { if (cfgTrackCuts.cfgTPCSectorCut) { double phimodn = track.phi(); - if (field < 0) // for negative polarity field + if (field < 0) { // for negative polarity field phimodn = o2::constants::math::TwoPI - phimodn; - if (track.sign() < 0) // for negative charge + } + if (track.sign() < 0) { // for negative charge phimodn = o2::constants::math::TwoPI - phimodn; - if (phimodn < 0) + } + if (phimodn < 0) { LOGF(warning, "phi < 0: %g", phimodn); + } phimodn += o2::constants::math::PI / 18.0; // to center gap in the middle phimodn = fmod(phimodn, o2::constants::math::PI / 9.0); - if (cfgFill.cfgFillQA) + if (cfgFill.cfgFillQA) { registryQA.fill(HIST("trackQA/before/pt_phi"), track.pt(), phimodn); - if (phimodn < fPhiCutHigh->Eval(track.pt()) && phimodn > fPhiCutLow->Eval(track.pt())) + } + if (phimodn < fPhiCutHigh->Eval(track.pt()) && phimodn > fPhiCutLow->Eval(track.pt())) { return false; // reject track - if (cfgFill.cfgFillQA) + } + if (cfgFill.cfgFillQA) { registryQA.fill(HIST("trackQA/after/pt_phi"), track.pt(), phimodn); + } } - if (cfgTrackCuts.cfgDCAxyNSigma && (std::fabs(track.dcaXY()) > fPtDepDCAxy->Eval(track.pt()))) + if (cfgTrackCuts.cfgDCAxyNSigma && (std::fabs(track.dcaXY()) > fPtDepDCAxy->Eval(track.pt()))) { return false; - if (!cfgTrackCuts.cfgDCAzPtDep.value.empty() && std::fabs(track.dcaZ() > fPtDepDCAz->Eval(track.pt()))) + } + if (!cfgTrackCuts.cfgDCAzPtDep.value.empty() && std::fabs(track.dcaZ() > fPtDepDCAz->Eval(track.pt()))) { return false; + } return ((track.tpcNClsCrossedRows() >= cfgTrackCuts.cfgNTPCXrows) && (track.tpcNClsFound() >= cfgTrackCuts.cfgNTPCCls) && (track.itsNCls() >= cfgTrackCuts.cfgMinNITSCls)); } template - bool nchSelected(TTrack track) + bool nchSelected(const TTrack& track) { // Renormalise to default cut const float defaultNsigma = 7; - if (cfgTrackCuts.cfgDCAxyNSigma && (std::fabs(track.dcaXY()) > defaultNsigma / cfgTrackCuts.cfgDCAxyNSigma * fPtDepDCAxy->Eval(track.pt()))) + if (cfgTrackCuts.cfgDCAxyNSigma && (std::fabs(track.dcaXY()) > defaultNsigma / cfgTrackCuts.cfgDCAxyNSigma * fPtDepDCAxy->Eval(track.pt()))) { return false; - if (!cfgTrackCuts.cfgDCAzPtDep.value.empty() && std::fabs(track.dcaZ() > fPtDepDCAz->Eval(track.pt()))) + } + if (!cfgTrackCuts.cfgDCAzPtDep.value.empty() && std::fabs(track.dcaZ() > fPtDepDCAz->Eval(track.pt()))) { return false; + } int tpcNClsCrossedRowsDefault = 70; int tpcNClsFoundDefault = 50; int itsNclsDefault = 5; @@ -1299,21 +1390,24 @@ struct FlowGenericFramework { }; template - void fillWeights(const TTrack track, const double vtxz, const int pid_index, const int run) + void fillWeights(const TTrack& track, const double vtxz, const int pid_index, const int run) { if (cfgUsePID) { - double ptpidmins[] = {o2::analysis::gfw::ptpoilow, o2::analysis::gfw::ptpoilow, 0.3, 0.5}; // min pt for ch, pi, ka, pr - double ptpidmaxs[] = {o2::analysis::gfw::ptpoiup, o2::analysis::gfw::ptpoiup, 6.0, 6.0}; // max pt for ch, pi, ka, pr - bool withinPtPOI = (ptpidmins[pid_index] < track.pt()) && (track.pt() < ptpidmaxs[pid_index]); // within POI pT range - bool withinPtRef = (o2::analysis::gfw::ptreflow < track.pt()) && (track.pt() < o2::analysis::gfw::ptrefup); // within RF pT range + std::array ptpidmins = {gfwMemberCache.ptpoilow, gfwMemberCache.ptpoilow, 0.3, 0.5}; // min pt for ch, pi, ka, pr + std::array ptpidmaxs = {gfwMemberCache.ptpoiup, gfwMemberCache.ptpoiup, 6.0, 6.0}; // max pt for ch, pi, ka, pr + bool withinPtPOI = (ptpidmins[pid_index] < track.pt()) && (track.pt() < ptpidmaxs[pid_index]); // within POI pT range + bool withinPtRef = (gfwMemberCache.ptreflow < track.pt()) && (track.pt() < gfwMemberCache.ptrefup); // within RF pT range if (cfgFill.cfgFillRunByRunQA) { - if (withinPtRef && !pid_index) + if (withinPtRef && !pid_index) { th3sList[run][NUAref]->Fill(track.phi(), track.eta(), vtxz); // pt-subset of charged particles for ref flow - if (withinPtPOI) + } + if (withinPtPOI) { th3sList[run][NUAch + pid_index]->Fill(track.phi(), track.eta(), vtxz); // charged and id'ed particle weights + } } else { - if (withinPtRef && !pid_index) + if (withinPtRef && !pid_index) { registryQA.fill(HIST("phi_eta_vtxz_ref"), track.phi(), track.eta(), vtxz); // pt-subset of charged particles for ref flow + } if (withinPtPOI) { switch (pid_index) { case 0: @@ -1328,28 +1422,30 @@ struct FlowGenericFramework { case 3: registryQA.fill(HIST("phi_eta_vtxz_pr"), track.phi(), track.eta(), vtxz); // proton weights break; + default: + break; } } } } else { - if (cfgFill.cfgFillRunByRunQA) + if (cfgFill.cfgFillRunByRunQA) { th3sList[run][NUAref]->Fill(track.phi(), track.eta(), vtxz); - else + } else { registryQA.fill(HIST("phi_eta_vtxz_ref"), track.phi(), track.eta(), vtxz); + } } - return; } void createRunByRunHistograms(const int run) { LOGF(info, "Creating histograms for run %d", run); - AxisSpec phiAxis = {o2::analysis::gfw::phibins, o2::analysis::gfw::philow, o2::analysis::gfw::phiup, "#phi"}; + AxisSpec phiAxis = {gfwMemberCache.phibins, gfwMemberCache.philow, gfwMemberCache.phiup, "#phi"}; AxisSpec phiModAxis = {100, 0, constants::math::PI / 9, "fmod(#varphi,#pi/9)"}; - AxisSpec etaAxis = {o2::analysis::gfw::etabins, cfgKinematics.cfgEta->first, cfgKinematics.cfgEta->second, "#eta"}; - AxisSpec vtxAxis = {o2::analysis::gfw::vtxZbins, -cfgVtxZ, cfgVtxZ, "Vtx_{z} (cm)"}; - AxisSpec nchAxis = {o2::analysis::gfw::nchbins, o2::analysis::gfw::nchlow, o2::analysis::gfw::nchup, "N_{ch}"}; - AxisSpec centAxis = {o2::analysis::gfw::centbinning, "Centrality (%)"}; - AxisSpec ptAxis = {o2::analysis::gfw::ptbinning, "#it{p}_{T} GeV/#it{c}"}; + AxisSpec etaAxis = {gfwMemberCache.etabins, cfgKinematics.cfgEta->first, cfgKinematics.cfgEta->second, "#eta"}; + AxisSpec vtxAxis = {gfwMemberCache.vtxZbins, -cfgVtxZ, cfgVtxZ, "Vtx_{z} (cm)"}; + AxisSpec nchAxis = {gfwMemberCache.nchbins, gfwMemberCache.nchlow, gfwMemberCache.nchup, "N_{ch}"}; + AxisSpec centAxis = {gfwMemberCache.centbinning, "Centrality (%)"}; + AxisSpec ptAxis = {gfwMemberCache.ptbinning, "#it{p}_{T} GeV/#it{c}"}; std::vector> histos(TH1NameCount); histos[Phi] = registryQA.add(Form("%d/phi", run), "", {HistType::kTH1D, {phiAxis}}); histos[Eta] = registryQA.add(Form("%d/eta", run), "", {HistType::kTH1D, {etaAxis}}); @@ -1385,7 +1481,6 @@ struct FlowGenericFramework { } histos3d[PtPhiMult] = registryQA.add(Form("%d/pt_phi_mult", run), "", {HistType::kTH3D, {ptAxis, phiModAxis, (cfgUseNch) ? nchAxis : centAxis}}); th3sList.insert(std::make_pair(run, histos3d)); - return; } struct AcceptedTracks { @@ -1409,48 +1504,61 @@ struct FlowGenericFramework { void fillNptRegistry(FractionSetup setup, const float& centmult, const NptHistos& nptHistos, const NptDenominators& dns) { - if (dns[ChargedID] <= 0) + if (dns[ChargedID] <= 0) { return; + } for (int i = 1; i <= fPtAxis->GetNbins(); ++i) { if (setup == FractionV02) { registry.fill(HIST("npt_v02_ch"), fPtAxis->GetBinCenter(i), centmult, nptHistos[ChargedID]->GetBinContent(i) / dns[ChargedID], cfgEventWeight.cfgUseMultiplicityFractionWeights ? dns[ChargedID] : 1.0); - if (dns[PionID] > 0) + if (dns[PionID] > 0) { registry.fill(HIST("npt_v02_pi"), fPtAxis->GetBinCenter(i), centmult, nptHistos[PionID]->GetBinContent(i) / dns[PionID], cfgEventWeight.cfgUseMultiplicityFractionWeights ? dns[PionID] : 1.0); - if (dns[KaonID] > 0) + } + if (dns[KaonID] > 0) { registry.fill(HIST("npt_v02_ka"), fPtAxis->GetBinCenter(i), centmult, nptHistos[KaonID]->GetBinContent(i) / dns[KaonID], cfgEventWeight.cfgUseMultiplicityFractionWeights ? dns[KaonID] : 1.0); - if (dns[ProtonID] > 0) + } + if (dns[ProtonID] > 0) { registry.fill(HIST("npt_v02_pr"), fPtAxis->GetBinCenter(i), centmult, nptHistos[ProtonID]->GetBinContent(i) / dns[ProtonID], cfgEventWeight.cfgUseMultiplicityFractionWeights ? dns[ProtonID] : 1.0); + } } else { registry.fill(HIST("npt_v0_ch"), fPtAxis->GetBinCenter(i), centmult, nptHistos[ChargedID]->GetBinContent(i) / dns[ChargedID], cfgEventWeight.cfgUseMultiplicityFractionWeights ? dns[ChargedID] : 1.0); - if (dns[PionID] > 0) + if (dns[PionID] > 0) { registry.fill(HIST("npt_v0_pi"), fPtAxis->GetBinCenter(i), centmult, nptHistos[PionID]->GetBinContent(i) / dns[PionID], cfgEventWeight.cfgUseMultiplicityFractionWeights ? dns[PionID] : 1.0); - if (dns[KaonID] > 0) + } + if (dns[KaonID] > 0) { registry.fill(HIST("npt_v0_ka"), fPtAxis->GetBinCenter(i), centmult, nptHistos[KaonID]->GetBinContent(i) / dns[KaonID], cfgEventWeight.cfgUseMultiplicityFractionWeights ? dns[KaonID] : 1.0); - if (dns[ProtonID] > 0) + } + if (dns[ProtonID] > 0) { registry.fill(HIST("npt_v0_pr"), fPtAxis->GetBinCenter(i), centmult, nptHistos[ProtonID]->GetBinContent(i) / dns[ProtonID], cfgEventWeight.cfgUseMultiplicityFractionWeights ? dns[ProtonID] : 1.0); + } } } } void fillNptHistos(NptHistos& nptHistos, const float pt, const int pidIndex, const double weightCh, const double weightPid) { - if (weightCh > 0) + if (weightCh > 0) { nptHistos[ChargedID]->Fill(pt, weightCh); - if (pidIndex == PionID && weightPid > 0) + } + if (pidIndex == PionID && weightPid > 0) { nptHistos[PionID]->Fill(pt, weightPid); - if (pidIndex == KaonID && weightPid > 0) + } + if (pidIndex == KaonID && weightPid > 0) { nptHistos[KaonID]->Fill(pt, weightPid); - if (pidIndex == ProtonID && weightPid > 0) + } + if (pidIndex == ProtonID && weightPid > 0) { nptHistos[ProtonID]->Fill(pt, weightPid); + } } void fillNptHistosForEta(const float eta, const float pt, const int pidIndex, const double weightCh, const double weightPid) { - if (eta > cfgKinematics.cfgEtaNptV02->first && eta < cfgKinematics.cfgEtaNptV02->second) + if (eta > cfgKinematics.cfgEtaNptV02->first && eta < cfgKinematics.cfgEtaNptV02->second) { fillNptHistos(histosNpt[FractionV02], pt, pidIndex, weightCh, weightPid); - if (eta > cfgKinematics.cfgEtaNptV0->first && eta < cfgKinematics.cfgEtaNptV0->second) + } + if (eta > cfgKinematics.cfgEtaNptV0->first && eta < cfgKinematics.cfgEtaNptV0->second) { fillNptHistos(histosNpt[FractionV0], pt, pidIndex, weightCh, weightPid); + } } template @@ -1462,32 +1570,37 @@ struct FlowGenericFramework { fFCpt->fillSubeventPtProfiles(centmult, rndm); fFCpt->fillCMProfiles(centmult, rndm); fFCpt->fillCMSubeventProfiles(centmult, rndm); - if (!cfgUseGapMethod) + if (!cfgUseGapMethod) { fFCpt->fillVnPtStdProfiles(centmult, rndm); + } for (uint l_ind = 0; l_ind < corrconfigs.size(); ++l_ind) { if (!corrconfigs.at(l_ind).pTDif) { auto dnx = fGFW->Calculate(corrconfigs.at(l_ind), 0, kTRUE).real(); - if (dnx == 0) + if (dnx == 0) { continue; + } auto val = fGFW->Calculate(corrconfigs.at(l_ind), 0, kFALSE).real() / dnx; if (std::abs(val) < 1) { - if (corrconfigs.at(l_ind).Head.find("3pcW") != std::string::npos && cfgEventWeight.cfgUseMultiplicityFractionWeights) + if (corrconfigs.at(l_ind).Head.find("3pcW") != std::string::npos && cfgEventWeight.cfgUseMultiplicityFractionWeights) { dnx *= histosNpt[FractionV02][ChargedID]->Integral(); + } (dt == Gen) ? fFCgen->FillProfile(corrconfigs.at(l_ind).Head.c_str(), centmult, val, cfgEventWeight.cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm) : fFC->FillProfile(corrconfigs.at(l_ind).Head.c_str(), centmult, val, cfgEventWeight.cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm); if (cfgUseGapMethod) { - fFCpt->fillVnPtProfiles(centmult, val, dnx, rndm, o2::analysis::gfw::configs.GetpTCorrMasks()[l_ind]); + fFCpt->fillVnPtProfiles(centmult, val, dnx, rndm, gfwMemberCache.configs.GetpTCorrMasks()[l_ind]); } } continue; } for (int i = 1; i <= fPtAxis->GetNbins(); i++) { auto dnx = fGFW->Calculate(corrconfigs.at(l_ind), i - 1, kTRUE).real(); - if (dnx == 0) + if (dnx == 0) { continue; + } auto val = fGFW->Calculate(corrconfigs.at(l_ind), i - 1, kFALSE).real() / dnx; - if (std::abs(val) < 1) + if (std::abs(val) < 1) { (dt == Gen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigs.at(l_ind).Head.c_str(), i), centmult, val, cfgEventWeight.cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconfigs.at(l_ind).Head.c_str(), i), centmult, val, cfgEventWeight.cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm); + } } } @@ -1499,65 +1612,73 @@ struct FlowGenericFramework { fillNptRegistry(FractionV02, centmult, nptV02, dnsV02); fillNptRegistry(FractionV0, centmult, nptV0, dnsV0); - if (corrconfigsV02.size() < SpeciesCount) + if (corrconfigsV02.size() < SpeciesCount) { return; + } if (dnsV02[ChargedID] > 0) { for (uint l_ind = 0; l_ind < SpeciesCount; ++l_ind) { for (int i = 1; i <= fPtAxis->GetNbins(); i++) { auto dnx = fGFW->Calculate(corrconfigsV02.at(l_ind), i - 1, kTRUE).real(); - if (dnx == 0) + if (dnx == 0) { continue; + } auto val = fGFW->Calculate(corrconfigsV02.at(l_ind), i - 1, kFALSE).real() / dnx; if (std::abs(val) < 1 && dnsV02[l_ind] > 0) { - if (cfgEventWeight.cfgUseMultiplicityFractionWeights) + if (cfgEventWeight.cfgUseMultiplicityFractionWeights) { dnx *= dnsV02[l_ind]; + } (dt == Gen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigsV02.at(l_ind).Head.c_str(), i), centmult, val * nptV02[l_ind]->GetBinContent(i) / dnsV02[l_ind], cfgEventWeight.cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconfigsV02.at(l_ind).Head.c_str(), i), centmult, val * nptV02[l_ind]->GetBinContent(i) / dnsV02[l_ind], cfgEventWeight.cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm); } } } } - if (corrconfigsV0.size() < SpeciesCount) + if (corrconfigsV0.size() < SpeciesCount) { return; + } double mpt = 0; double dnx = 0; if (cfgKinematics.cfgEtaPtPt->first * cfgKinematics.cfgEtaPtPt->second >= 0) { - if (fFCpt->corrDen[1] == 0.) + if (fFCpt->corrDen[1] == 0.) { return; + } dnx = fFCpt->corrDen[1]; mpt = fFCpt->corrNum[1] / dnx; } else { - if (fFCpt->corrDenSub[0][1] == 0. || fFCpt->corrDenSub[1][1] == 0.) + if (fFCpt->corrDenSub[0][1] == 0. || fFCpt->corrDenSub[1][1] == 0.) { return; + } double mptSub1 = fFCpt->corrNumSub[0][1] / fFCpt->corrDenSub[0][1]; double mptSub2 = fFCpt->corrNumSub[1][1] / fFCpt->corrDenSub[1][1]; dnx = 0.5 * (fFCpt->corrDenSub[0][1] + fFCpt->corrDenSub[1][1]); mpt = 0.5 * (mptSub1 + mptSub2); } - if (std::isnan(mpt)) + if (std::isnan(mpt)) { return; + } for (uint l_ind = 0; l_ind < SpeciesCount; ++l_ind) { for (int i = 1; i <= fPtAxis->GetNbins(); i++) { if (dnsV0[l_ind] > 0) { double profileWeight = dnx; - if (cfgEventWeight.cfgUseMultiplicityFractionWeights) + if (cfgEventWeight.cfgUseMultiplicityFractionWeights) { profileWeight *= dnsV0[l_ind]; + } (dt == Gen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigsV0.at(l_ind).Head.c_str(), i), centmult, mpt * nptV0[l_ind]->GetBinContent(i) / dnsV0[l_ind], cfgEventWeight.cfgUseMultiplicityFlowWeights ? profileWeight : 1.0, rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconfigsV0.at(l_ind).Head.c_str(), i), centmult, mpt * nptV0[l_ind]->GetBinContent(i) / dnsV0[l_ind], cfgEventWeight.cfgUseMultiplicityFlowWeights ? profileWeight : 1.0, rndm); } } } - return; } template - void fillResonanceOutput(FractionSetup setup, const float& centrality, const double& rndm) + void fillResonanceOutput(FractionSetup setup, const float& centmult, const double& rndm) { if (setup == FractionV02) { - if (histosNpt[FractionV02][ChargedID]->Integral() <= 0) + if (histosNpt[FractionV02][ChargedID]->Integral() <= 0) { return; + } double dnK0SB1 = histosNpt[FractionV02][ChargedID]->Integral(); double dnK0Sig = histosNpt[FractionV02][ChargedID]->Integral(); @@ -1576,18 +1697,24 @@ struct FlowGenericFramework { } for (int i = 1; i <= fPtAxis->GetNbins(); ++i) { - if (dnK0SB1 > 0) - registry.fill(HIST("npt_v02_K0_sb1"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[FractionV02][K0Sideband1]->GetBinContent(i) / dnK0SB1, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnK0SB1 : 1.); - if (dnK0Sig > 0) - registry.fill(HIST("npt_v02_K0_sig"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[FractionV02][K0Signal]->GetBinContent(i) / dnK0Sig, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnK0Sig : 1.); - if (dnK0SB2 > 0) - registry.fill(HIST("npt_v02_K0_sb2"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[FractionV02][K0Sideband2]->GetBinContent(i) / dnK0SB2, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnK0SB2 : 1.); - if (dnLambdaSB1 > 0) - registry.fill(HIST("npt_v02_Lambda_sb1"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[FractionV02][LambdaSideband1]->GetBinContent(i) / dnLambdaSB1, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnLambdaSB1 : 1.); - if (dnLambdaSig > 0) - registry.fill(HIST("npt_v02_Lambda_sig"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[FractionV02][LambdaSignal]->GetBinContent(i) / dnLambdaSig, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnLambdaSig : 1.); - if (dnLambdaSB2 > 0) - registry.fill(HIST("npt_v02_Lambda_sb2"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[FractionV02][LambdaSideband2]->GetBinContent(i) / dnLambdaSB2, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnLambdaSB2 : 1.); + if (dnK0SB1 > 0) { + registry.fill(HIST("npt_v02_K0_sb1"), fPtAxis->GetBinCenter(i), centmult, histosResoNpt[FractionV02][K0Sideband1]->GetBinContent(i) / dnK0SB1, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnK0SB1 : 1.); + } + if (dnK0Sig > 0) { + registry.fill(HIST("npt_v02_K0_sig"), fPtAxis->GetBinCenter(i), centmult, histosResoNpt[FractionV02][K0Signal]->GetBinContent(i) / dnK0Sig, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnK0Sig : 1.); + } + if (dnK0SB2 > 0) { + registry.fill(HIST("npt_v02_K0_sb2"), fPtAxis->GetBinCenter(i), centmult, histosResoNpt[FractionV02][K0Sideband2]->GetBinContent(i) / dnK0SB2, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnK0SB2 : 1.); + } + if (dnLambdaSB1 > 0) { + registry.fill(HIST("npt_v02_Lambda_sb1"), fPtAxis->GetBinCenter(i), centmult, histosResoNpt[FractionV02][LambdaSideband1]->GetBinContent(i) / dnLambdaSB1, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnLambdaSB1 : 1.); + } + if (dnLambdaSig > 0) { + registry.fill(HIST("npt_v02_Lambda_sig"), fPtAxis->GetBinCenter(i), centmult, histosResoNpt[FractionV02][LambdaSignal]->GetBinContent(i) / dnLambdaSig, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnLambdaSig : 1.); + } + if (dnLambdaSB2 > 0) { + registry.fill(HIST("npt_v02_Lambda_sb2"), fPtAxis->GetBinCenter(i), centmult, histosResoNpt[FractionV02][LambdaSideband2]->GetBinContent(i) / dnLambdaSB2, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnLambdaSB2 : 1.); + } } std::vector dns = {dnK0SB1, dnK0Sig, dnK0SB2, dnLambdaSB1, dnLambdaSig, dnLambdaSB2}; @@ -1595,19 +1722,22 @@ struct FlowGenericFramework { for (uint l_ind = 4; l_ind < corrconfigsV02.size(); ++l_ind) { for (int i = 1; i <= fPtAxis->GetNbins(); i++) { auto dnx = fGFW->Calculate(corrconfigsV02.at(l_ind), i - 1, kTRUE).real(); - if (dnx == 0) + if (dnx == 0) { continue; + } auto val = fGFW->Calculate(corrconfigsV02.at(l_ind), i - 1, kFALSE).real() / dnx; if (std::abs(val) < 1 && dns[l_ind - 4] > 0) { - if (cfgEventWeight.cfgUseMultiplicityFractionWeights) + if (cfgEventWeight.cfgUseMultiplicityFractionWeights) { dnx *= dns[l_ind - 4]; - (dt == Gen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigsV02.at(l_ind).Head.c_str(), i), centrality, val * histosResoNpt[FractionV02][l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], cfgEventWeight.cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconfigsV02.at(l_ind).Head.c_str(), i), centrality, val * histosResoNpt[FractionV02][l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], cfgEventWeight.cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm); + } + (dt == Gen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigsV02.at(l_ind).Head.c_str(), i), centmult, val * histosResoNpt[FractionV02][l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], cfgEventWeight.cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconfigsV02.at(l_ind).Head.c_str(), i), centmult, val * histosResoNpt[FractionV02][l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], cfgEventWeight.cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm); } } } } else { - if (histosNpt[FractionV0][ChargedID]->Integral() <= 0) + if (histosNpt[FractionV0][ChargedID]->Integral() <= 0) { return; + } double dnK0SB1 = histosNpt[FractionV0][ChargedID]->Integral(); double dnK0Sig = histosNpt[FractionV0][ChargedID]->Integral(); @@ -1626,66 +1756,81 @@ struct FlowGenericFramework { } for (int i = 1; i <= fPtAxis->GetNbins(); ++i) { - if (dnK0SB1 > 0) - registry.fill(HIST("npt_v0_K0_sb1"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[FractionV0][K0Sideband1]->GetBinContent(i) / dnK0SB1, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnK0SB1 : 1.); - if (dnK0Sig > 0) - registry.fill(HIST("npt_v0_K0_sig"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[FractionV0][K0Signal]->GetBinContent(i) / dnK0Sig, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnK0Sig : 1.); - if (dnK0SB2 > 0) - registry.fill(HIST("npt_v0_K0_sb2"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[FractionV0][K0Sideband2]->GetBinContent(i) / dnK0SB2, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnK0SB2 : 1.); - if (dnLambdaSB1 > 0) - registry.fill(HIST("npt_v0_Lambda_sb1"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[FractionV0][LambdaSideband1]->GetBinContent(i) / dnLambdaSB1, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnLambdaSB1 : 1.); - if (dnLambdaSig > 0) - registry.fill(HIST("npt_v0_Lambda_sig"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[FractionV0][LambdaSignal]->GetBinContent(i) / dnLambdaSig, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnLambdaSig : 1.); - if (dnLambdaSB2 > 0) - registry.fill(HIST("npt_v0_Lambda_sb2"), fPtAxis->GetBinCenter(i), centrality, histosResoNpt[FractionV0][LambdaSideband2]->GetBinContent(i) / dnLambdaSB2, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnLambdaSB2 : 1.); + if (dnK0SB1 > 0) { + registry.fill(HIST("npt_v0_K0_sb1"), fPtAxis->GetBinCenter(i), centmult, histosResoNpt[FractionV0][K0Sideband1]->GetBinContent(i) / dnK0SB1, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnK0SB1 : 1.); + } + if (dnK0Sig > 0) { + registry.fill(HIST("npt_v0_K0_sig"), fPtAxis->GetBinCenter(i), centmult, histosResoNpt[FractionV0][K0Signal]->GetBinContent(i) / dnK0Sig, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnK0Sig : 1.); + } + if (dnK0SB2 > 0) { + registry.fill(HIST("npt_v0_K0_sb2"), fPtAxis->GetBinCenter(i), centmult, histosResoNpt[FractionV0][K0Sideband2]->GetBinContent(i) / dnK0SB2, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnK0SB2 : 1.); + } + if (dnLambdaSB1 > 0) { + registry.fill(HIST("npt_v0_Lambda_sb1"), fPtAxis->GetBinCenter(i), centmult, histosResoNpt[FractionV0][LambdaSideband1]->GetBinContent(i) / dnLambdaSB1, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnLambdaSB1 : 1.); + } + if (dnLambdaSig > 0) { + registry.fill(HIST("npt_v0_Lambda_sig"), fPtAxis->GetBinCenter(i), centmult, histosResoNpt[FractionV0][LambdaSignal]->GetBinContent(i) / dnLambdaSig, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnLambdaSig : 1.); + } + if (dnLambdaSB2 > 0) { + registry.fill(HIST("npt_v0_Lambda_sb2"), fPtAxis->GetBinCenter(i), centmult, histosResoNpt[FractionV0][LambdaSideband2]->GetBinContent(i) / dnLambdaSB2, cfgEventWeight.cfgUseMultiplicityFractionWeights ? dnLambdaSB2 : 1.); + } } std::vector dns = {dnK0SB1, dnK0Sig, dnK0SB2, dnLambdaSB1, dnLambdaSig, dnLambdaSB2}; - if (fFCpt->corrDenSub[0][1] == 0. || fFCpt->corrDenSub[1][1] == 0.) + if (fFCpt->corrDenSub[0][1] == 0. || fFCpt->corrDenSub[1][1] == 0.) { return; + } double mpt = 0; double dnx = 0; if (cfgKinematics.cfgEtaPtPt->first * cfgKinematics.cfgEtaPtPt->second >= 0) { - if (fFCpt->corrDen[1] == 0.) + if (fFCpt->corrDen[1] == 0.) { return; + } dnx = fFCpt->corrDen[1]; mpt = fFCpt->corrNum[1] / dnx; } else { - if (fFCpt->corrDenSub[0][1] == 0. || fFCpt->corrDenSub[1][1] == 0.) + if (fFCpt->corrDenSub[0][1] == 0. || fFCpt->corrDenSub[1][1] == 0.) { return; + } double mptSub1 = fFCpt->corrNumSub[0][1] / fFCpt->corrDenSub[0][1]; double mptSub2 = fFCpt->corrNumSub[1][1] / fFCpt->corrDenSub[1][1]; dnx = 0.5 * (fFCpt->corrDenSub[0][1] + fFCpt->corrDenSub[1][1]); mpt = 0.5 * (mptSub1 + mptSub2); } - if (std::isnan(mpt)) + if (std::isnan(mpt)) { return; + } for (uint l_ind = 4; l_ind < corrconfigsV0.size(); ++l_ind) { for (int i = 1; i <= fPtAxis->GetNbins(); i++) { - if (dns[l_ind - 4] > 0) - if (cfgEventWeight.cfgUseMultiplicityFractionWeights) + if (dns[l_ind - 4] > 0) { + if (cfgEventWeight.cfgUseMultiplicityFractionWeights) { dnx *= dns[l_ind - 4]; - (dt == Gen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigsV0.at(l_ind).Head.c_str(), i), centrality, mpt * histosResoNpt[FractionV0][l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], 1.0, rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconfigsV0.at(l_ind).Head.c_str(), i), centrality, mpt * histosResoNpt[FractionV0][l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], 1.0, rndm); + } + } + (dt == Gen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigsV0.at(l_ind).Head.c_str(), i), centmult, mpt * histosResoNpt[FractionV0][l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], 1.0, rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconfigsV0.at(l_ind).Head.c_str(), i), centmult, mpt * histosResoNpt[FractionV0][l_ind - 4]->GetBinContent(i) / dns[l_ind - 4], 1.0, rndm); } } } } template - void processCollision(TCollision collision, TTracks tracks, TV0s v0s, const float& centrality, const int field, const int run) + void processCollision(const TCollision& collision, const TTracks& tracks, const TV0s& v0s, const float& centrality, const int field, const int run) { - if (tracks.size() < 1) + if (tracks.size() < 1) { return; - if (dt != Gen && (centrality < o2::analysis::gfw::centbinning.front() || centrality > o2::analysis::gfw::centbinning.back())) + } + if (dt != Gen && (centrality < gfwMemberCache.centbinning.front() || centrality > gfwMemberCache.centbinning.back())) { return; + } if (dt != Gen) { registryQA.fill(HIST("eventQA/eventSel"), TrackCent); - if (cfgFill.cfgFillRunByRunQA) + if (cfgFill.cfgFillRunByRunQA) { th1sList[run][EventSel]->Fill(TrackCent); + } } float vtxz = collision.posZ(); if (dt != Gen && cfgFill.cfgFillRunByRunQA) { @@ -1707,7 +1852,7 @@ struct FlowGenericFramework { double q3x = 0, q3y = 0; double q4x = 0, q4y = 0; for (const auto& track : tracks) { - bool withinPtRef = (o2::analysis::gfw::ptreflow < track.pt()) && (track.pt() < o2::analysis::gfw::ptrefup); // within RF pT rang + bool withinPtRef = (gfwMemberCache.ptreflow < track.pt()) && (track.pt() < gfwMemberCache.ptrefup); // within RF pT rang if (withinPtRef) { q2x += std::cos(2 * track.phi()); q2y += std::sin(2 * track.phi()); @@ -1735,8 +1880,9 @@ struct FlowGenericFramework { AcceptedTracks acceptedTracks; // Reset fraction histograms per event for (const auto& vec : histosNpt) { - for (const auto& h : vec) + for (const auto& h : vec) { h->Reset("ICESM"); + } } for (const auto& track : tracks) { processTrack(track, vtxz, field, run, densitycorrections, centrality, acceptedTracks); @@ -1746,7 +1892,7 @@ struct FlowGenericFramework { registryQA.fill(HIST("trackQA/after/Nch_uncorrected"), acceptedTracks.totaluncorr); } - int multiplicity = 0; + float multiplicity = 0.f; switch (cfgUseNchCorrection) { case 0: multiplicity = tracks.size(); @@ -1762,64 +1908,79 @@ struct FlowGenericFramework { break; } - if (cfgFill.cfgFillWeights) + if (cfgFill.cfgFillWeights) { return; + } fillOutputContainers
((cfgUseNch) ? multiplicity : centrality, lRandom); // Reset fraction histograms per event - for (const auto& vec : histosResoNpt) - for (const auto& h : vec) + for (const auto& vec : histosResoNpt) { + for (const auto& h : vec) { h->Reset("ICESM"); + } + } // Process V0s only for reconstructed-track workflows. if constexpr (dt != Gen) { - for (const auto& v0 : v0s) + for (const auto& v0 : v0s) { processV0(v0, tracks, collision, centrality); + } } else { - for (const auto& particle : tracks) + for (const auto& particle : tracks) { processV0(particle, tracks, collision, centrality); + } } for (auto setup = 0; setup < FractionSetupCount; ++setup) { auto fractionSetup = static_cast(setup); - fillResonanceOutput
(fractionSetup, centrality, lRandom); + fillResonanceOutput
(fractionSetup, (cfgUseNch) ? multiplicity : centrality, lRandom); } } template - inline void processTrack(TTrack const& track, const float& vtxz, const int field, const int run, DensityCorr densitycorrections, const float& centrality, AcceptedTracks& acceptedTracks) + inline void processTrack(const TTrack& track, const float& vtxz, const int field, const int run, const DensityCorr& densitycorrections, const float& centrality, AcceptedTracks& acceptedTracks) { if constexpr (framework::has_type_v) { - if (track.mcParticleId() < 0 || !(track.has_mcParticle())) + if (track.mcParticleId() < 0 || !(track.has_mcParticle())) { return; + } auto mcParticle = track.mcParticle(); - if (!mcParticle.isPhysicalPrimary()) + if (!mcParticle.isPhysicalPrimary()) { return; - if (cfgFill.cfgFillQA) + } + if (cfgFill.cfgFillQA) { fillTrackQA(track, vtxz); - if (mcParticle.eta() < o2::analysis::gfw::etalow || mcParticle.eta() > o2::analysis::gfw::etaup || mcParticle.pt() < o2::analysis::gfw::ptlow || mcParticle.pt() > o2::analysis::gfw::ptup) + } + if (mcParticle.eta() < gfwMemberCache.etalow || mcParticle.eta() > gfwMemberCache.etaup || mcParticle.pt() < gfwMemberCache.ptlow || mcParticle.pt() > gfwMemberCache.ptup) { return; + } // Select tracks with nominal cuts always - if (!nchSelected(track)) + if (!nchSelected(track)) { return; + } double weffCh = getEfficiency(track, centrality, 0); if (track.eta() > cfgKinematics.cfgEtaNch->first && track.eta() < cfgKinematics.cfgEtaNch->second) { - if (weffCh > 0) + if (weffCh > 0) { acceptedTracks.total += (cfgUseNchCorrection) ? weffCh : 1.0; + } ++acceptedTracks.totaluncorr; } - if (!trackSelected(track, field)) + if (!trackSelected(track, field)) { return; + } int pidIndex = 0; - if (std::abs(mcParticle.pdgCode()) == kPiPlus) + if (std::abs(mcParticle.pdgCode()) == kPiPlus) { pidIndex = PionID; - if (std::abs(mcParticle.pdgCode()) == kKPlus) + } + if (std::abs(mcParticle.pdgCode()) == kKPlus) { pidIndex = KaonID; - if (std::abs(mcParticle.pdgCode()) == kProton) + } + if (std::abs(mcParticle.pdgCode()) == kProton) { pidIndex = ProtonID; + } double weff = getEfficiency(track, centrality, pidIndex); double nptWeightCh = (weffCh > 0) ? ((cfgUseNchCorrection) ? weffCh : 1.0) : -1.0; double nptWeightPid = (weff > 0) ? ((cfgUseNchCorrection) ? weff : 1.0) : -1.0; @@ -1839,20 +2000,26 @@ struct FlowGenericFramework { } } else if constexpr (framework::has_type_v) { - if (!track.isPhysicalPrimary()) + if (!track.isPhysicalPrimary()) { return; - if (cfgFill.cfgFillQA) + } + if (cfgFill.cfgFillQA) { fillTrackQA(track, vtxz); - if (track.eta() < o2::analysis::gfw::etalow || track.eta() > o2::analysis::gfw::etaup || track.pt() < o2::analysis::gfw::ptlow || track.pt() > o2::analysis::gfw::ptup) + } + if (track.eta() < gfwMemberCache.etalow || track.eta() > gfwMemberCache.etaup || track.pt() < gfwMemberCache.ptlow || track.pt() > gfwMemberCache.ptup) { return; + } int pidIndex = 0; - if (std::abs(track.pdgCode()) == kPiPlus) + if (std::abs(track.pdgCode()) == kPiPlus) { pidIndex = PionID; - if (std::abs(track.pdgCode()) == kKPlus) + } + if (std::abs(track.pdgCode()) == kKPlus) { pidIndex = KaonID; - if (std::abs(track.pdgCode()) == kProton) + } + if (std::abs(track.pdgCode()) == kProton) { pidIndex = ProtonID; + } if (track.eta() > cfgKinematics.cfgEtaNch->first && track.eta() < cfgKinematics.cfgEtaNch->second) { ++acceptedTracks.total; @@ -1862,23 +2029,28 @@ struct FlowGenericFramework { fillPtSums(track, centrality, vtxz); fillGFW(track, centrality, vtxz, pidIndex, densitycorrections); - if (cfgFill.cfgFillQA) + if (cfgFill.cfgFillQA) { fillTrackQA(track, vtxz); + } } else { - if (cfgFill.cfgFillQA) + if (cfgFill.cfgFillQA) { fillTrackQA(track, vtxz); + } // Select tracks with nominal cuts always - if (!nchSelected(track)) + if (!nchSelected(track)) { return; + } double weffCh = getEfficiency(track, centrality, 0); if (track.eta() > cfgKinematics.cfgEtaNch->first && track.eta() < cfgKinematics.cfgEtaNch->second) { - if (weffCh > 0) + if (weffCh > 0) { acceptedTracks.total += (cfgUseNchCorrection) ? weffCh : 1.0; + } ++acceptedTracks.totaluncorr; } - if (!trackSelected(track, field)) + if (!trackSelected(track, field)) { return; + } // int pidIndex = 0; // if (cfgUsePID) Need PID for v02 int pidIndex = getNsigmaPID(track); @@ -1904,108 +2076,128 @@ struct FlowGenericFramework { } template - inline void processV0(TV0 v0, TTracks tracks, TCollision collision, const float& centrality) + inline void processV0(const TV0& v0, const TTracks& tracks, const TCollision& collision, const float& centrality) { if constexpr (dt == Reco) { using V0TrackTable = std::decay_t; auto postrack = v0.template posTrack_as(); auto negtrack = v0.template negTrack_as(); - if (resoSwitchVals[UseParticle][K0]) { + if (resoSwitchVals[UseParticle][K0] != 0) { double weff = 1; bool fillK0 = true; if (cfgEfficiency.cfgUsePIDEfficiencies) { weff = getEfficiency(v0, centrality, 4); - if (weff < 0) + if (weff < 0) { fillK0 = false; + } } if (fillK0) { auto k0Selection = selectK0(collision, v0, tracks); if (k0Selection.selected) { for (auto setup = 0; setup < FractionSetupCount; ++setup) { auto fractionSetup = static_cast(setup); - if (!selectionV0DaughterEta(postrack, fractionSetup) || !selectionV0DaughterEta(negtrack, fractionSetup)) + if (!selectionV0DaughterEta(postrack, fractionSetup) || !selectionV0DaughterEta(negtrack, fractionSetup)) { continue; + } - if (cfgFill.cfgFillQA && fractionSetup == FractionV02) + if (cfgFill.cfgFillV0QA && fractionSetup == FractionV02) { fillV0QA(k0Selection, v0, postrack, negtrack, centrality, weff); + } registryQA.fill(HIST("K0/hK0Count"), (fractionSetup == FractionV02) ? FillV02DaughterTrackSelection : FillV0DaughterTrackSelection); - if (v0.mK0Short() > cfgPIDCuts.cfgK0SideBand1Min && v0.mK0Short() < cfgPIDCuts.cfgK0SideBand1Max) + if (v0.mK0Short() > cfgPIDCuts.cfgK0SideBand1Min && v0.mK0Short() < cfgPIDCuts.cfgK0SideBand1Max) { histosResoNpt[fractionSetup][K0Sideband1]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); - if (v0.mK0Short() > cfgPIDCuts.cfgK0SignalMin && v0.mK0Short() < cfgPIDCuts.cfgK0SignalMax) + } + if (v0.mK0Short() > cfgPIDCuts.cfgK0SignalMin && v0.mK0Short() < cfgPIDCuts.cfgK0SignalMax) { histosResoNpt[fractionSetup][K0Signal]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); - if (v0.mK0Short() > cfgPIDCuts.cfgK0SideBand2Min && v0.mK0Short() < cfgPIDCuts.cfgK0SideBand2Max) + } + if (v0.mK0Short() > cfgPIDCuts.cfgK0SideBand2Min && v0.mK0Short() < cfgPIDCuts.cfgK0SideBand2Max) { histosResoNpt[fractionSetup][K0Sideband2]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); + } } } } } - if (resoSwitchVals[UseParticle][Lambda]) { + if (resoSwitchVals[UseParticle][Lambda] != 0) { double weff = 1.; bool fillLambda = true; if (cfgEfficiency.cfgUsePIDEfficiencies) { weff = getEfficiency(v0, centrality, 5); - if (weff < 0) + if (weff < 0) { fillLambda = false; + } } if (fillLambda) { auto lambdaSelection = selectLambda(collision, v0, tracks); if (lambdaSelection.selected) { for (auto setup = 0; setup < FractionSetupCount; ++setup) { auto fractionSetup = static_cast(setup); - if (!selectionLambdaDaughterEta(postrack, negtrack, lambdaSelection, fractionSetup)) + if (!selectionLambdaDaughterEta(postrack, negtrack, lambdaSelection, fractionSetup)) { continue; + } registryQA.fill(HIST("Lambda/hLambdaCount"), (fractionSetup == FractionV02) ? FillV02DaughterTrackSelection : FillV0DaughterTrackSelection); - if (cfgFill.cfgFillQA && fractionSetup == FractionV02) + if (cfgFill.cfgFillV0QA && fractionSetup == FractionV02) { fillV0QA(lambdaSelection, v0, postrack, negtrack, centrality, weff); + } - if (v0.mLambda() > cfgPIDCuts.cfgLambdaSideBand1Min && v0.mLambda() < cfgPIDCuts.cfgLambdaSideBand1Max) + if (v0.mLambda() > cfgPIDCuts.cfgLambdaSideBand1Min && v0.mLambda() < cfgPIDCuts.cfgLambdaSideBand1Max) { histosResoNpt[fractionSetup][LambdaSideband1]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); - if (v0.mLambda() > cfgPIDCuts.cfgLambdaSignalMin && v0.mLambda() < cfgPIDCuts.cfgLambdaSignalMax) + } + if (v0.mLambda() > cfgPIDCuts.cfgLambdaSignalMin && v0.mLambda() < cfgPIDCuts.cfgLambdaSignalMax) { histosResoNpt[fractionSetup][LambdaSignal]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); - if (v0.mLambda() > cfgPIDCuts.cfgLambdaSideBand2Min && v0.mLambda() < cfgPIDCuts.cfgLambdaSideBand2Max) + } + if (v0.mLambda() > cfgPIDCuts.cfgLambdaSideBand2Min && v0.mLambda() < cfgPIDCuts.cfgLambdaSideBand2Max) { histosResoNpt[fractionSetup][LambdaSideband2]->Fill(v0.pt(), (cfgUseNchCorrection) ? weff : 1.0); + } } } } } } else { - if (!v0.isPhysicalPrimary()) + if (!v0.isPhysicalPrimary()) { return; - if (!v0.has_daughters()) + } + if (!v0.has_daughters()) { return; + } bool isK0 = (v0.pdgCode() == PDG_t::kK0Short); bool isLambda = (v0.pdgCode() == PDG_t::kLambda0); - if (!isK0 && !isLambda) + if (!isK0 && !isLambda) { return; + } // To match reconstructed - check that daughters are within v02/v0 eta acceptance bool isWithinV0Acceptance = true; bool isWithinV02Acceptance = true; for (const auto& d : v0.template daughters_as()) { - if (d.eta() < cfgKinematics.cfgEtaNptV02->first || d.eta() > cfgKinematics.cfgEtaNptV02->second) + if (d.eta() < cfgKinematics.cfgEtaNptV02->first || d.eta() > cfgKinematics.cfgEtaNptV02->second) { isWithinV02Acceptance = false; + } if (d.eta() < cfgKinematics.cfgEtaNptV0->first || d.eta() > cfgKinematics.cfgEtaNptV0->second) { isWithinV0Acceptance = false; } } if (isK0) { - if (isWithinV02Acceptance) + if (isWithinV02Acceptance) { histosResoNpt[FractionV02][K0Signal]->Fill(v0.pt(), 1.0); - if (isWithinV0Acceptance) + } + if (isWithinV0Acceptance) { histosResoNpt[FractionV0][K0Signal]->Fill(v0.pt(), 1.0); + } } if (isLambda) { - if (isWithinV02Acceptance) + if (isWithinV02Acceptance) { histosResoNpt[FractionV02][LambdaSignal]->Fill(v0.pt(), 1.0); - if (isWithinV0Acceptance) + } + if (isWithinV0Acceptance) { histosResoNpt[FractionV0][LambdaSignal]->Fill(v0.pt(), 1.0); + } } } } @@ -2023,61 +2215,74 @@ struct FlowGenericFramework { }; template - bool selectionV0Daughter(TTrack const& track, int pid) + bool selectionV0Daughter(const TTrack& track, int pid) { - if (!(track.itsNCls() > cfgTrackCuts.cfgMinNITSCls)) + if (!(track.itsNCls() > cfgTrackCuts.cfgMinNITSCls)) { return 0; - if (!track.hasTPC()) + } + if (!track.hasTPC()) { return false; - if (track.tpcNClsFound() < cfgTrackCuts.cfgNTPCCls) + } + if (track.tpcNClsFound() < cfgTrackCuts.cfgNTPCCls) { return false; - if (!(track.tpcNClsCrossedRows() > cfgTrackCuts.cfgNTPCXrows)) + } + if (!(track.tpcNClsCrossedRows() > cfgTrackCuts.cfgNTPCXrows)) { return 0; + } if (cfgPIDCuts.cfgUseOnlyTPC) { - if (pid == Pions && std::abs(track.tpcNSigmaPi()) > cfgPIDCuts.cfgTPCNsigmaCut) + if (pid == Pions && std::abs(track.tpcNSigmaPi()) > cfgPIDCuts.cfgTPCNsigmaCut) { return false; - if (pid == Kaons && std::abs(track.tpcNSigmaKa()) > cfgPIDCuts.cfgTPCNsigmaCut) + } + if (pid == Kaons && std::abs(track.tpcNSigmaKa()) > cfgPIDCuts.cfgTPCNsigmaCut) { return false; - if (pid == Protons && std::abs(track.tpcNSigmaPr()) > cfgPIDCuts.cfgTPCNsigmaCut) + } + if (pid == Protons && std::abs(track.tpcNSigmaPr()) > cfgPIDCuts.cfgTPCNsigmaCut) { return false; + } } else { int partIndex = cfgPIDCuts.cfgUseAsymmetricPID ? getNsigmaPIDAssymmetric(track) : getNsigmaPID(track); int pidIndex = partIndex - 1; // 0 = pion, 1 = kaon, 2 = proton - if (pidIndex != pid) + if (pidIndex != pid) { return false; + } } return true; } template - bool selectionV0DaughterEta(TTrack const& track, FractionSetup setup) + bool selectionV0DaughterEta(const TTrack& track, FractionSetup setup) { const auto [etaMin, etaMax] = getFractionEtaRange(setup); - if (track.eta() < etaMin || track.eta() > etaMax) + if (track.eta() < etaMin || track.eta() > etaMax) { return false; - if (cfgFill.cfgFillQA) { - if (setup == FractionV02) + } + if (cfgFill.cfgFillV0QA) { + if (setup == FractionV02) { registryQA.fill(HIST("trackQA/after/etaV02"), track.eta()); - if (setup == FractionV0) + } + if (setup == FractionV0) { registryQA.fill(HIST("trackQA/after/etaV0"), track.eta()); + } } return true; } template - bool selectionLambdaDaughterEta(TTrack const& postrack, TTrack const& negtrack, const V0Selection& lambdaSelection, FractionSetup setup) + bool selectionLambdaDaughterEta(const TTrack& postrack, const TTrack& negtrack, const V0Selection& lambdaSelection, FractionSetup setup) { - if (lambdaSelection.isL && (!selectionV0DaughterEta(postrack, setup) || !selectionV0DaughterEta(negtrack, setup))) + if (lambdaSelection.isL && (!selectionV0DaughterEta(postrack, setup) || !selectionV0DaughterEta(negtrack, setup))) { return false; - if (lambdaSelection.isAL && (!selectionV0DaughterEta(postrack, setup) || !selectionV0DaughterEta(negtrack, setup))) + } + if (lambdaSelection.isAL && (!selectionV0DaughterEta(postrack, setup) || !selectionV0DaughterEta(negtrack, setup))) { return false; + } return true; } template - V0Selection selectK0(TCollision const& collision, TV0 const& v0, TTracks const&) + V0Selection selectK0(const TCollision& collision, const TV0& v0, const TTracks&) { using V0TrackTable = std::decay_t; @@ -2089,56 +2294,69 @@ struct FlowGenericFramework { auto negtrack = v0.template negTrack_as(); registryQA.fill(HIST("K0/hK0Count"), FillCandidate); - if (postrack.pt() < resoCutVals[PosTrackPt][K0] || negtrack.pt() < resoCutVals[NegTrackPt][K0]) + if (postrack.pt() < resoCutVals[PosTrackPt][K0] || negtrack.pt() < resoCutVals[NegTrackPt][K0]) { return selection; + } registryQA.fill(HIST("K0/hK0Count"), FillDaughterPt); - if (massK0s < resoCutVals[MassMin][K0] && massK0s > resoCutVals[MassMax][K0]) + if (massK0s < resoCutVals[MassMin][K0] && massK0s > resoCutVals[MassMax][K0]) { return selection; + } registryQA.fill(HIST("K0/hK0Count"), FillMassCut); // Rapidity correction - if (v0.yK0Short() > resoCutVals[Rapidity][K0]) + if (v0.yK0Short() > resoCutVals[Rapidity][K0]) { return selection; + } registryQA.fill(HIST("K0/hK0Count"), FillRapidityCut); // DCA cuts for K0short - if (std::abs(v0.dcapostopv()) < resoCutVals[DCAPosToPVMin][K0] || std::abs(v0.dcanegtopv()) < resoCutVals[DCANegToPVMin][K0]) + if (std::abs(v0.dcapostopv()) < resoCutVals[DCAPosToPVMin][K0] || std::abs(v0.dcanegtopv()) < resoCutVals[DCANegToPVMin][K0]) { return selection; + } registryQA.fill(HIST("K0/hK0Count"), FillDCAtoPV); - if (resoSwitchVals[UseDCAxDaughters][K0] && std::abs(v0.dcaV0daughters()) > resoCutVals[DCAxDaughters][K0]) + if (resoSwitchVals[UseDCAxDaughters][K0] != 0 && std::abs(v0.dcaV0daughters()) > resoCutVals[DCAxDaughters][K0]) { return selection; + } registryQA.fill(HIST("K0/hK0Count"), FillDCAxDaughters); // v0 radius cuts - if (resoSwitchVals[UseV0Radius][K0] && (v0.v0radius() < resoCutVals[RadiusMin][K0] || v0.v0radius() > resoCutVals[RadiusMax][K0])) + if (resoSwitchVals[UseV0Radius][K0] != 0 && (v0.v0radius() < resoCutVals[RadiusMin][K0] || v0.v0radius() > resoCutVals[RadiusMax][K0])) { return selection; + } registryQA.fill(HIST("K0/hK0Count"), FillV0Radius); // cosine pointing angle cuts - if (v0.v0cosPA() < resoCutVals[CosPA][K0]) + if (v0.v0cosPA() < resoCutVals[CosPA][K0]) { return selection; + } registryQA.fill(HIST("K0/hK0Count"), FillCosPA); // Proper lifetime - if (resoSwitchVals[UseProperLifetime][K0] && v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * massK0Short > resoCutVals[LifeTime][K0]) + if (resoSwitchVals[UseProperLifetime][K0] != 0 && v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * massK0Short > resoCutVals[LifeTime][K0]) { return selection; + } registryQA.fill(HIST("K0/hK0Count"), FillProperLifetime); // ArmenterosPodolanskiCut - if (resoSwitchVals[UseArmPodCut][K0] && (v0.qtarm() / std::abs(v0.alpha())) < resoCutVals[ArmPodMin][K0]) + if (resoSwitchVals[UseArmPodCut][K0] != 0 && (v0.qtarm() / std::abs(v0.alpha())) < resoCutVals[ArmPodMin][K0]) { return selection; + } registryQA.fill(HIST("K0/hK0Count"), FillArmPodCut); - if (resoSwitchVals[UseCompetingMassRejection][K0]) { - if (std::abs(v0.mLambda() - o2::constants::physics::MassLambda0) < resoCutVals[MassRejection][K0]) + if (resoSwitchVals[UseCompetingMassRejection][K0] != 0) { + if (std::abs(v0.mLambda() - o2::constants::physics::MassLambda0) < resoCutVals[MassRejection][K0]) { return selection; - if (std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) < resoCutVals[MassRejection][K0]) + } + if (std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) < resoCutVals[MassRejection][K0]) { return selection; + } } registryQA.fill(HIST("K0/hK0Count"), FillCompetingMass); - if (!selectionV0Daughter(postrack, Pions) || !selectionV0Daughter(negtrack, Pions)) + if (!selectionV0Daughter(postrack, Pions) || !selectionV0Daughter(negtrack, Pions)) { return selection; + } selection.selected = true; selection.isK0 = true; + registryQA.fill(HIST("K0/hK0AP"), v0.alpha(), v0.qtarm()); return selection; } template - V0Selection selectLambda(TCollision const& collision, TV0 const& v0, TTracks const&) + V0Selection selectLambda(const TCollision& collision, const TV0& v0, const TTracks&) { using V0TrackTable = std::decay_t; V0Selection selection; @@ -2151,14 +2369,17 @@ struct FlowGenericFramework { auto negtrack = v0.template negTrack_as(); registryQA.fill(HIST("Lambda/hLambdaCount"), FillCandidate); - if (postrack.pt() < resoCutVals[PosTrackPt][Lambda] || negtrack.pt() < resoCutVals[NegTrackPt][Lambda]) + if (postrack.pt() < resoCutVals[PosTrackPt][Lambda] || negtrack.pt() < resoCutVals[NegTrackPt][Lambda]) { return selection; + } registryQA.fill(HIST("Lambda/hLambdaCount"), FillDaughterPt); - if (mlambda > resoCutVals[MassMin][Lambda] && mlambda < resoCutVals[MassMax][Lambda]) + if (mlambda > resoCutVals[MassMin][Lambda] && mlambda < resoCutVals[MassMax][Lambda]) { selection.isL = true; - if (mantilambda > resoCutVals[MassMin][Lambda] && mantilambda < resoCutVals[MassMax][Lambda]) + } + if (mantilambda > resoCutVals[MassMin][Lambda] && mantilambda < resoCutVals[MassMax][Lambda]) { selection.isAL = true; + } if (!selection.isL && !selection.isAL) { return selection; @@ -2166,50 +2387,63 @@ struct FlowGenericFramework { registryQA.fill(HIST("Lambda/hLambdaCount"), FillMassCut); // Rapidity correction - if (v0.yLambda() > resoCutVals[Rapidity][Lambda]) + if (v0.yLambda() > resoCutVals[Rapidity][Lambda]) { return selection; + } registryQA.fill(HIST("Lambda/hLambdaCount"), FillRapidityCut); // DCA cuts for lambda and antilambda if (selection.isL) { - if (std::abs(v0.dcapostopv()) < resoCutVals[DCAPosToPVMin][Lambda] || std::abs(v0.dcanegtopv()) < resoCutVals[DCANegToPVMin][Lambda]) + if (std::abs(v0.dcapostopv()) < resoCutVals[DCAPosToPVMin][Lambda] || std::abs(v0.dcanegtopv()) < resoCutVals[DCANegToPVMin][Lambda]) { return selection; + } } if (selection.isAL) { - if (std::abs(v0.dcapostopv()) < resoCutVals[DCANegToPVMin][Lambda] || std::abs(v0.dcanegtopv()) < resoCutVals[DCAPosToPVMin][Lambda]) + if (std::abs(v0.dcapostopv()) < resoCutVals[DCANegToPVMin][Lambda] || std::abs(v0.dcanegtopv()) < resoCutVals[DCAPosToPVMin][Lambda]) { return selection; + } } registryQA.fill(HIST("Lambda/hLambdaCount"), FillDCAtoPV); - if (resoSwitchVals[UseDCAxDaughters][Lambda] && std::abs(v0.dcaV0daughters()) > resoCutVals[DCAxDaughters][Lambda]) + if (resoSwitchVals[UseDCAxDaughters][Lambda] != 0 && std::abs(v0.dcaV0daughters()) > resoCutVals[DCAxDaughters][Lambda]) { return selection; + } registryQA.fill(HIST("Lambda/hLambdaCount"), FillDCAxDaughters); // v0 radius cuts - if (resoSwitchVals[UseV0Radius][Lambda] && (v0.v0radius() < resoCutVals[RadiusMin][Lambda] || v0.v0radius() > resoCutVals[RadiusMax][Lambda])) + if (resoSwitchVals[UseV0Radius][Lambda] != 0 && (v0.v0radius() < resoCutVals[RadiusMin][Lambda] || v0.v0radius() > resoCutVals[RadiusMax][Lambda])) { return selection; + } registryQA.fill(HIST("Lambda/hLambdaCount"), FillV0Radius); // cosine pointing angle cuts - if (v0.v0cosPA() < resoCutVals[CosPA][Lambda]) + if (v0.v0cosPA() < resoCutVals[CosPA][Lambda]) { return selection; + } registryQA.fill(HIST("Lambda/hLambdaCount"), FillCosPA); // Proper lifetime - if (resoSwitchVals[UseProperLifetime][Lambda] && v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * massLambda > resoCutVals[LifeTime][Lambda]) + if (resoSwitchVals[UseProperLifetime][Lambda] != 0 && v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * massLambda > resoCutVals[LifeTime][Lambda]) { return selection; + } registryQA.fill(HIST("Lambda/hLambdaCount"), FillProperLifetime); // ArmenterosPodolanskiCut - if (resoSwitchVals[UseArmPodCut][Lambda] && (v0.qtarm() / std::abs(v0.alpha())) < resoCutVals[ArmPodMin][Lambda]) + if (resoSwitchVals[UseArmPodCut][Lambda] != 0 && (v0.qtarm() / std::abs(v0.alpha())) < resoCutVals[ArmPodMin][Lambda]) { return selection; + } registryQA.fill(HIST("Lambda/hLambdaCount"), FillArmPodCut); - if (resoSwitchVals[UseCompetingMassRejection][Lambda]) { - if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) < resoCutVals[MassRejection][Lambda]) + if (resoSwitchVals[UseCompetingMassRejection][Lambda] != 0) { + if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) < resoCutVals[MassRejection][Lambda]) { return selection; + } } registryQA.fill(HIST("Lambda/hLambdaCount"), FillCompetingMass); if (selection.isL) { - if (!selectionV0Daughter(postrack, Protons) || !selectionV0Daughter(negtrack, Pions)) + if (!selectionV0Daughter(postrack, Protons) || !selectionV0Daughter(negtrack, Pions)) { + registryQA.fill(HIST("Lambda/hLambdaAP"), v0.alpha(), v0.qtarm()); return selection; + } } if (selection.isAL) { - if (!selectionV0Daughter(postrack, Pions) || !selectionV0Daughter(negtrack, Protons)) + if (!selectionV0Daughter(postrack, Pions) || !selectionV0Daughter(negtrack, Protons)) { + registryQA.fill(HIST("Lambda/hAntiLambdaAP"), v0.alpha(), v0.qtarm()); return selection; + } } selection.selected = true; @@ -2217,20 +2451,22 @@ struct FlowGenericFramework { } template - inline void fillPtSums(TTrack track, const float& centrality, const double& vtxz) + inline void fillPtSums(const TTrack& track, const float& centrality, const double& vtxz) { double wacc = (dt == Gen) ? 1. : getAcceptance(track, vtxz, 0); double weff = (dt == Gen) ? 1. : getEfficiency(track, centrality); - if (weff < 0) + if (weff < 0) { return; + } // Fill the nominal sums - if (track.eta() > cfgKinematics.cfgEtaPtPt->first && track.eta() < cfgKinematics.cfgEtaPtPt->second) + if (track.eta() > cfgKinematics.cfgEtaPtPt->first && track.eta() < cfgKinematics.cfgEtaPtPt->second) { fFCpt->fill(weff, track.pt()); + } // Fill the subevent sums std::size_t index = 0; - for (const auto& [etamin, etamax] : o2::analysis::gfw::etagapsPtPt) { + for (const auto& [etamin, etamax] : gfwMemberCache.etagapsPtPt) { if (etamin < track.eta() && track.eta() < etamax) { fFCpt->fillSub(weff, track.pt(), index); } @@ -2245,40 +2481,49 @@ struct FlowGenericFramework { } template - inline void fillGFW(TTrack track, const float& centrality, const double& vtxz, int pid_index, DensityCorr densitycorrections) + inline void fillGFW(const TTrack& track, const float& centrality, const double& vtxz, int pid_index, const DensityCorr& densitycorrections) { if (cfgUsePID) { // Analysing POI flow with id'ed particles - double ptmins[] = {o2::analysis::gfw::ptpoilow, o2::analysis::gfw::ptpoilow, 0.3, 0.5}; - double ptmaxs[] = {o2::analysis::gfw::ptpoiup, o2::analysis::gfw::ptpoiup, 6.0, 6.0}; - bool withinPtRef = (track.pt() > o2::analysis::gfw::ptreflow && track.pt() < o2::analysis::gfw::ptrefup); + std::array ptmins = {gfwMemberCache.ptpoilow, gfwMemberCache.ptpoilow, 0.3, 0.5}; + std::array ptmaxs = {gfwMemberCache.ptpoiup, gfwMemberCache.ptpoiup, 6.0, 6.0}; + bool withinPtRef = (track.pt() > gfwMemberCache.ptreflow && track.pt() < gfwMemberCache.ptrefup); bool withinPtPOI = (track.pt() > ptmins[pid_index] && track.pt() < ptmaxs[pid_index]); bool withinPtNch = (track.pt() > ptmins[0] && track.pt() < ptmaxs[0]); - if (!withinPtPOI && !withinPtRef) + if (!withinPtPOI && !withinPtRef) { return; + } double waccRef = (dt == Gen) ? 1. : getAcceptance(track, vtxz, 0); double waccPOI = (dt == Gen) ? 1. : withinPtPOI ? getAcceptance(track, vtxz, pid_index + 1) : getAcceptance(track, vtxz, 0); // - if (withinPtRef && withinPtPOI && pid_index) + if (withinPtRef && withinPtPOI && pid_index) { waccRef = waccPOI; // if particle is both (then it's overlap), override ref with POI - if (withinPtRef) + } + if (withinPtRef) { fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), waccRef, 1); - if (withinPtPOI && pid_index) + } + if (withinPtPOI && pid_index) { fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), waccPOI, (1 << (pid_index + 1))); - if (withinPtNch) + } + if (withinPtNch) { fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), waccPOI, 2); - if (withinPtPOI && withinPtRef && pid_index) + } + if (withinPtPOI && withinPtRef && pid_index) { fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), waccPOI, (1 << (pid_index + 5))); - if (withinPtNch && withinPtRef) + } + if (withinPtNch && withinPtRef) { fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), waccPOI, 32); + } } else { // Analysing only integrated flow - bool withinPtRef = (track.pt() > o2::analysis::gfw::ptreflow && track.pt() < o2::analysis::gfw::ptrefup); - bool withinPtPOI = (track.pt() > o2::analysis::gfw::ptpoilow && track.pt() < o2::analysis::gfw::ptpoiup); - if (!withinPtPOI && !withinPtRef) + bool withinPtRef = (track.pt() > gfwMemberCache.ptreflow && track.pt() < gfwMemberCache.ptrefup); + bool withinPtPOI = (track.pt() > gfwMemberCache.ptpoilow && track.pt() < gfwMemberCache.ptpoiup); + if (!withinPtPOI && !withinPtRef) { return; + } double weff = (dt == Gen) ? 1. : getEfficiency(track, centrality, 0); - if (weff < 0) + if (weff < 0) { return; + } if (cfgUseDensityDependentCorrection && withinPtRef && dt != Gen) { double fphi = densitycorrections.v2 * std::cos(2 * (track.phi() - densitycorrections.psi2Est)) + densitycorrections.v3 * std::cos(3 * (track.phi() - densitycorrections.psi3Est)) + densitycorrections.v4 * std::cos(4 * (track.phi() - densitycorrections.psi4Est)); fphi = (1 + 2 * fphi); @@ -2292,18 +2537,20 @@ struct FlowGenericFramework { } } double wacc = (dt == Gen) ? 1. : getAcceptance(track, vtxz, 0); - if (withinPtRef) + if (withinPtRef) { fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), weff * wacc, 1); - if (withinPtPOI) + } + if (withinPtPOI) { fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), weff * wacc, 2); - if (withinPtRef && withinPtPOI) + } + if (withinPtRef && withinPtPOI) { fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), weff * wacc, 4); + } } - return; } template - inline void fillTrackQA(TTrack track, const float vtxz) + inline void fillTrackQA(const TTrack& track, const float vtxz) { if constexpr (dt == Gen) { registryQA.fill(HIST("MCGen/") + HIST(FillTimeName[ft]) + HIST("phi_eta_vtxZ_gen"), track.phi(), track.eta(), vtxz); @@ -2323,16 +2570,18 @@ struct FlowGenericFramework { registryQA.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("pt_ref"), track.pt()); registryQA.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("pt_poi"), track.pt()); - if (track.eta() > cfgKinematics.cfgEtaNch->first && track.eta() < cfgKinematics.cfgEtaNch->second) + if (track.eta() > cfgKinematics.cfgEtaNch->first && track.eta() < cfgKinematics.cfgEtaNch->second) { registryQA.fill(HIST("trackQA/after/etaNch"), track.eta()); - if (track.eta() > cfgKinematics.cfgEtaPtPt->first && track.eta() < cfgKinematics.cfgEtaPtPt->second && cfgFill.cfgFillQA) + } + if (track.eta() > cfgKinematics.cfgEtaPtPt->first && track.eta() < cfgKinematics.cfgEtaPtPt->second && cfgFill.cfgFillQA) { registryQA.fill(HIST("trackQA/after/etaPtPt"), track.eta()); + } } } } template - inline void fillV0QA(const V0Selection& selection, TV0 const& v0, TTrack postrack, TTrack negtrack, const float& centrality, const float& weff) + inline void fillV0QA(const V0Selection& selection, TV0 const& v0, const TTrack& postrack, const TTrack& negtrack, const float& centrality, const float& weff) { if (selection.isK0) { registryQA.fill(HIST("K0/hK0Mass_sparse"), v0.mK0Short(), v0.pt(), centrality); @@ -2344,8 +2593,9 @@ struct FlowGenericFramework { registryQA.fill(HIST("K0/PiMinusTOF_K0"), negtrack.pt(), negtrack.tofNSigmaKa()); registryQA.fill(HIST("K0/hK0s"), 0.5, 1); - if (cfgEfficiency.cfgUsePIDEfficiencies) + if (cfgEfficiency.cfgUsePIDEfficiencies) { registryQA.fill(HIST("K0/hK0s_corrected"), 0.5, weff); + } } if (selection.isL) { registryQA.fill(HIST("Lambda/hLambdaMass_sparse"), v0.mLambda(), v0.pt(), centrality); @@ -2367,13 +2617,14 @@ struct FlowGenericFramework { } if (selection.isL || selection.isAL) { registryQA.fill(HIST("Lambda/hLambdas"), 0.5, 1); - if (cfgEfficiency.cfgUsePIDEfficiencies) + if (cfgEfficiency.cfgUsePIDEfficiencies) { registryQA.fill(HIST("Lambda/hLambdas_corrected"), 0.5, weff); + } } } template - float getCentrality(TCollision collision) + float getCentrality(const TCollision& collision) { switch (cfgCentEstimator) { case CentFT0C: @@ -2395,8 +2646,8 @@ struct FlowGenericFramework { } } - template - inline void fillEventQA(CollisionObject collision, TracksObject tracks) + template + inline void fillEventQA(const TCollision& collision, const TTracks& tracks) { registryQA.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("globalTracks_centT0C"), collision.centFT0C(), tracks.size()); registryQA.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("PVTracks_centT0C"), collision.centFT0C(), collision.multNTracksPV()); @@ -2405,11 +2656,10 @@ struct FlowGenericFramework { registryQA.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("globalTracks_multV0A"), collision.multFV0A(), tracks.size()); registryQA.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("multV0A_multT0A"), collision.multFT0A(), collision.multFV0A()); registryQA.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("multT0C_centT0C"), collision.centFT0C(), collision.multFT0C()); - return; } o2::framework::expressions::Filter collisionFilter = nabs(aod::collision::posZ) < cfgVtxZ; - o2::framework::expressions::Filter trackFilter = (aod::track::eta > cfgKinematics.cfgEta->first) && (aod::track::eta < cfgKinematics.cfgEta->second) && (aod::track::pt > cfgPtmin) && (aod::track::pt < cfgPtmax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::itsChi2NCl < cfgTrackCuts.cfgChi2PrITSCls) && (aod::track::tpcChi2NCl < cfgTrackCuts.cfgChi2PrTPCCls) && nabs(aod::track::dcaZ) < cfgTrackCuts.cfgDCAz; + o2::framework::expressions::Filter trackFilter = (aod::track::eta > cfgKinematics.cfgEta->first) && (aod::track::eta < cfgKinematics.cfgEta->second) && (aod::track::pt > cfgKinematics.cfgPtMin) && (aod::track::pt < cfgKinematics.cfgPtmax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::itsChi2NCl < cfgTrackCuts.cfgChi2PrITSCls) && (aod::track::tpcChi2NCl < cfgTrackCuts.cfgChi2PrTPCCls) && nabs(aod::track::dcaZ) < cfgTrackCuts.cfgDCAz; using GFWCollisions = soa::Filtered>; using GFWMCCollisions = soa::Join; @@ -2434,52 +2684,64 @@ struct FlowGenericFramework { LOGF(info, "run = %d", run); if (cfgRunByRun) { if (std::find(runNumbers.begin(), runNumbers.end(), run) == runNumbers.end()) { - if (cfgFill.cfgFillRunByRunQA) + if (cfgFill.cfgFillRunByRunQA) { createRunByRunHistograms(run); + } runNumbers.push_back(run); } else { LOGF(info, "run %d already in runNumbers", run); } - if (!cfgFill.cfgFillWeights) + if (!cfgFill.cfgFillWeights) { loadCorrections(bc); + } } } - if (!cfgFill.cfgFillWeights && !cfgRunByRun) + if (!cfgFill.cfgFillWeights && !cfgRunByRun) { loadCorrections(bc); + } registryQA.fill(HIST("eventQA/eventSel"), 0.5); - if (cfgFill.cfgFillRunByRunQA) + if (cfgFill.cfgFillRunByRunQA) { th1sList[run][EventSel]->Fill(0.5); - if (!collision.sel8()) + } + if (!collision.sel8()) { return; + } registryQA.fill(HIST("eventQA/eventSel"), 1.5); - if (cfgFill.cfgFillRunByRunQA) + if (cfgFill.cfgFillRunByRunQA) { th1sList[run][EventSel]->Fill(1.5); + } float centrality = getCentrality(collision); - if (cfgDoOccupancySel) { + if (cfgEventSelection.cfgDoOccupancySel) { int occupancy = collision.trackOccupancyInTimeRange(); - if (cfgFill.cfgFillQA) + if (cfgFill.cfgFillQA) { registryQA.fill(HIST("eventQA/before/occ_mult_cent"), occupancy, tracks.size(), centrality); - if (occupancy < 0 || occupancy > cfgOccupancySelection) + } + if (occupancy < 0 || occupancy > cfgEventSelection.cfgOccupancySelection) { return; - if (cfgFill.cfgFillQA) + } + if (cfgFill.cfgFillQA) { registryQA.fill(HIST("eventQA/after/occ_mult_cent"), occupancy, tracks.size(), centrality); + } } registryQA.fill(HIST("eventQA/eventSel"), 2.5); - if (cfgFill.cfgFillRunByRunQA) + if (cfgFill.cfgFillRunByRunQA) { th1sList[run][EventSel]->Fill(2.5); - if (cfgFill.cfgFillQA) + } + if (cfgFill.cfgFillQA) { fillEventQA(collision, tracks); + } registryQA.fill(HIST("eventQA/before/centrality"), centrality); registryQA.fill(HIST("eventQA/before/multiplicity"), tracks.size()); - if (!eventSelected(collision, tracks.size(), centrality, run)) + if (!eventSelected(collision, tracks.size(), centrality, run)) { return; - if (cfgFill.cfgFillQA) + } + if (cfgFill.cfgFillQA) { fillEventQA(collision, tracks); + } registryQA.fill(HIST("eventQA/after/centrality"), centrality); registryQA.fill(HIST("eventQA/after/multiplicity"), tracks.size()); // Get magnetic field polarity - int defaultMagCut = 99999; - auto field = (cfgMagField == defaultMagCut) ? getMagneticField(bc.timestamp()) : cfgMagField; + auto field = (cfgEventSelection.cfgMagField == DefaultMagneticFieldCut) ? getMagneticField(bc.timestamp()) : static_cast(cfgEventSelection.cfgMagField); processCollision(collision, tracks, v0s, centrality, field, run); } @@ -2491,45 +2753,54 @@ struct FlowGenericFramework { int run = bc.runNumber(); if (run != lastRun) { lastRun = run; - if (cfgFill.cfgFillRunByRunQA) + if (cfgFill.cfgFillRunByRunQA) { createRunByRunHistograms(run); + } } registryQA.fill(HIST("eventQA/eventSel"), 0.5); - if (cfgFill.cfgFillRunByRunQA) + if (cfgFill.cfgFillRunByRunQA) { th1sList[run][EventSel]->Fill(0.5); + } - if (!collision.sel8()) + if (!collision.sel8()) { return; + } registryQA.fill(HIST("eventQA/eventSel"), 1.5); - if (cfgFill.cfgFillRunByRunQA) + if (cfgFill.cfgFillRunByRunQA) { th1sList[run][EventSel]->Fill(1.5); + } const auto centrality = getCentrality(collision); - if (cfgDoOccupancySel) { + if (cfgEventSelection.cfgDoOccupancySel) { int occupancy = collision.trackOccupancyInTimeRange(); registryQA.fill(HIST("eventQA/before/occ_mult_cent"), occupancy, tracks.size(), centrality); - if (occupancy < 0 || occupancy > cfgOccupancySelection) + if (occupancy < 0 || occupancy > cfgEventSelection.cfgOccupancySelection) { return; + } registryQA.fill(HIST("eventQA/after/occ_mult_cent"), occupancy, tracks.size(), centrality); } registryQA.fill(HIST("eventQA/eventSel"), 2.5); - if (cfgFill.cfgFillRunByRunQA) + if (cfgFill.cfgFillRunByRunQA) { th1sList[run][EventSel]->Fill(2.5); + } - if (cfgFill.cfgFillQA) + if (cfgFill.cfgFillQA) { fillEventQA(collision, tracks); - if (!eventSelected(collision, tracks.size(), centrality, run)) + } + if (!eventSelected(collision, tracks.size(), centrality, run)) { return; - if (cfgFill.cfgFillQA) + } + if (cfgFill.cfgFillQA) { fillEventQA(collision, tracks); + } - if (!cfgFill.cfgFillWeights) + if (!cfgFill.cfgFillWeights) { loadCorrections(bc); - int defaultMagCut = 99999; - auto field = (cfgMagField == defaultMagCut) ? getMagneticField(bc.timestamp()) : cfgMagField; + } + auto field = (cfgEventSelection.cfgMagField == DefaultMagneticFieldCut) ? getMagneticField(bc.timestamp()) : static_cast(cfgEventSelection.cfgMagField); processCollision(collision, tracks, v0s, centrality, field, run); } PROCESS_SWITCH(FlowGenericFramework, processMCReco, "Process analysis for MC reconstructed events", false); @@ -2537,8 +2808,9 @@ struct FlowGenericFramework { o2::framework::expressions::Filter mcCollFilter = nabs(aod::mccollision::posZ) < cfgVtxZ; void processMCGen(soa::Filtered::iterator const& mcCollision, soa::SmallGroups> const& collisions, aod::McParticles const& particles, aod::V0Datas const& v0s) { - if (collisions.size() != 1) + if (collisions.size() != 1) { return; + } float centrality = -1; for (const auto& collision : collisions) { centrality = getCentrality(collision); @@ -2557,146 +2829,216 @@ struct FlowGenericFramework { PROCESS_SWITCH(FlowGenericFramework, processOnTheFly, "Process analysis for MC on-the-fly generated events", false); template - bool isGeneratedEfficiencyV0(TParticle const& particle, int pdgCode, int resonanceIndex) + bool isGeneratedEfficiencyV0(const TParticle& particle, int pdgCode, int resonanceIndex) { return particle.isPhysicalPrimary() && std::abs(particle.pdgCode()) == pdgCode && std::abs(particle.y()) < resoCutVals[Rapidity][resonanceIndex]; } template - bool isGeneratedEfficiencyTrack(TParticle const& particle) + bool isGeneratedEfficiencyTrack(const TParticle& particle) { auto pdgParticle = pdgDB->GetParticle(particle.pdgCode()); - return pdgParticle && pdgParticle->Charge() != 0 && particle.isPhysicalPrimary() && particle.eta() > o2::analysis::gfw::etalow && particle.eta() < o2::analysis::gfw::etaup && particle.pt() > o2::analysis::gfw::ptlow && particle.pt() < o2::analysis::gfw::ptup; + return pdgParticle && pdgParticle->Charge() != 0 && particle.isPhysicalPrimary() && particle.eta() > gfwMemberCache.etalow && particle.eta() < gfwMemberCache.etaup && particle.pt() > gfwMemberCache.ptlow && particle.pt() < gfwMemberCache.ptup; } template - int getEfficiencyTruthPID(TParticle const& particle) + int getEfficiencyTruthPID(const TParticle& particle) { - if (std::abs(particle.pdgCode()) == kPiPlus) + if (std::abs(particle.pdgCode()) == kPiPlus) { return EfficiencyPion; - if (std::abs(particle.pdgCode()) == kKPlus) + } + if (std::abs(particle.pdgCode()) == kKPlus) { return EfficiencyKaon; - if (std::abs(particle.pdgCode()) == kProton) + } + if (std::abs(particle.pdgCode()) == kProton) { return EfficiencyProton; + } return EfficiencyCharged; } template - void fillGeneratedEfficiencyTrack(TParticle const& particle, float centrality) + void fillGeneratedEfficiencyTrack(const TParticle& particle, float centrality) { - if (!isGeneratedEfficiencyTrack(particle)) + if (!isGeneratedEfficiencyTrack(particle)) { return; - if (particle.eta() <= cfgKinematics.cfgEta->first || particle.eta() >= cfgKinematics.cfgEta->second) + } + if (particle.eta() <= cfgKinematics.cfgEta->first || particle.eta() >= cfgKinematics.cfgEta->second) { return; + } const int pidIndex = getEfficiencyTruthPID(particle); registry.fill(HIST("Efficiency/efficiencyHist"), particle.pt(), centrality, EfficiencyCharged, EfficiencyGenerated); - if (pidIndex != EfficiencyCharged) + if (pidIndex != EfficiencyCharged) { registry.fill(HIST("Efficiency/efficiencyHist"), particle.pt(), centrality, pidIndex, EfficiencyGenerated); + } } template - void fillGeneratedEfficiencyV0(TParticle const& particle, int particleIndex, float centrality) + void fillGeneratedEfficiencyV0(const TParticle& particle, int particleIndex, float centrality) { - if (!particle.has_daughters()) + if (!particle.has_daughters()) { return; + } for (const auto& daughter : particle.template daughters_as()) { - if (daughter.eta() <= cfgKinematics.cfgEta->first || daughter.eta() >= cfgKinematics.cfgEta->second) + if (daughter.eta() <= cfgKinematics.cfgEta->first || daughter.eta() >= cfgKinematics.cfgEta->second) { return; + } } registry.fill(HIST("Efficiency/efficiencyHist"), particle.pt(), centrality, particleIndex, EfficiencyGenerated); } template - bool isEfficiencyEventSelected(TCollision const& collision, const int multTrk, float& centrality) + bool isEfficiencyEventSelected(const TCollision& collision, const int multTrk, float& centrality) { - if (!collision.sel8()) + if (!collision.sel8()) { return false; + } centrality = getCentrality(collision); - if (centrality < o2::analysis::gfw::centbinning.front() || centrality > o2::analysis::gfw::centbinning.back()) + if (centrality < gfwMemberCache.centbinning.front() || centrality > gfwMemberCache.centbinning.back()) { return false; - if (cfgDoOccupancySel) { + } + if (cfgEventSelection.cfgDoOccupancySel) { int occupancy = collision.trackOccupancyInTimeRange(); - if (occupancy < 0 || occupancy > cfgOccupancySelection) + if (occupancy < 0 || occupancy > cfgEventSelection.cfgOccupancySelection) { return false; + } } const int run = 0; return eventSelected(collision, multTrk, centrality, run); } template - bool isWithinEfficiencyEtaAcceptance(TTrack const& track) + bool isWithinEfficiencyEtaAcceptance(const TTrack& track) { return track.eta() > cfgKinematics.cfgEta->first && track.eta() < cfgKinematics.cfgEta->second; } template - bool areGeneratedDaughtersWithinEfficiencyEtaAcceptance(TParticle const& particle) + bool areGeneratedDaughtersWithinEfficiencyEtaAcceptance(const TParticle& particle) { - if (!particle.has_daughters()) + if (!particle.has_daughters()) { return false; + } for (const auto& daughter : particle.template daughters_as()) { - if (daughter.eta() <= cfgKinematics.cfgEta->first || daughter.eta() >= cfgKinematics.cfgEta->second) + if (daughter.eta() <= cfgKinematics.cfgEta->first || daughter.eta() >= cfgKinematics.cfgEta->second) { return false; + } } return true; } + void fillV0EfficiencyRecoDebug(float pt, float centrality, int particleIndex, int stage) + { + registry.fill(HIST("Efficiency/v0RecoDebug"), pt, centrality, particleIndex, stage); + } + + template + void fillEnabledV0EfficiencyRecoDebug(const TV0& v0, float centrality, int stage) + { + if (resoSwitchVals[UseParticle][K0] != 0) { + fillV0EfficiencyRecoDebug(v0.pt(), centrality, EfficiencyK0, stage); + } + if (resoSwitchVals[UseParticle][Lambda] != 0) { + fillV0EfficiencyRecoDebug(v0.pt(), centrality, EfficiencyLambda, stage); + } + } + template - void fillEfficiencyRecoTrack(TTrack const& track, int field, float centrality) + void fillEfficiencyRecoTrack(const TTrack& track, int field, float centrality) { - if (track.mcParticleId() < 0 || !track.has_mcParticle()) + if (track.mcParticleId() < 0 || !track.has_mcParticle()) { return; + } auto mcParticle = track.mcParticle(); - if (!isGeneratedEfficiencyTrack(mcParticle)) + if (!isGeneratedEfficiencyTrack(mcParticle)) { return; - if (!trackSelected(track, field)) + } + if (!trackSelected(track, field)) { return; - if (!isWithinEfficiencyEtaAcceptance(mcParticle) || !isWithinEfficiencyEtaAcceptance(track)) + } + if (!isWithinEfficiencyEtaAcceptance(mcParticle) || !isWithinEfficiencyEtaAcceptance(track)) { return; + } const int pidIndex = getEfficiencyTruthPID(mcParticle); registry.fill(HIST("Efficiency/efficiencyHist"), mcParticle.pt(), centrality, EfficiencyCharged, EfficiencyReconstructed); - if (pidIndex != EfficiencyCharged) + if (pidIndex != EfficiencyCharged) { registry.fill(HIST("Efficiency/efficiencyHist"), mcParticle.pt(), centrality, pidIndex, EfficiencyReconstructed); + } } template - void fillEfficiencyRecoV0(TV0 const& v0, TCollision const& collision, TTracks const& tracks, float centrality) + void fillEfficiencyRecoV0(const TV0& v0, const TCollision& collision, const TTracks& tracks, float centrality) { using V0TrackTable = std::decay_t; + fillEnabledV0EfficiencyRecoDebug(v0, centrality, V0EfficiencyCandidate); + auto postrack = v0.template posTrack_as(); auto negtrack = v0.template negTrack_as(); - if (!postrack.has_mcParticle() || !negtrack.has_mcParticle()) + if (!postrack.has_mcParticle() || !negtrack.has_mcParticle()) { return; + } + fillEnabledV0EfficiencyRecoDebug(v0, centrality, V0EfficiencyDaughterMCLabels); + auto posMcParticle = postrack.template mcParticle_as(); auto negMcParticle = negtrack.template mcParticle_as(); - if (!posMcParticle.has_mothers() || !negMcParticle.has_mothers()) + if (!posMcParticle.has_mothers() || !negMcParticle.has_mothers()) { return; + } + fillEnabledV0EfficiencyRecoDebug(v0, centrality, V0EfficiencyDaughterMothers); for (const auto& posMother : posMcParticle.template mothers_as()) { for (const auto& negMother : negMcParticle.template mothers_as()) { - if (posMother.globalIndex() != negMother.globalIndex() || !posMother.isPhysicalPrimary()) + if (posMother.globalIndex() != negMother.globalIndex() || !posMother.isPhysicalPrimary()) { continue; + } int pdgCode = std::abs(posMother.pdgCode()); - if (pdgCode == PDG_t::kK0Short && resoSwitchVals[UseParticle][K0]) { - if (std::abs(posMother.y()) >= resoCutVals[Rapidity][K0]) + if (pdgCode == PDG_t::kK0Short && resoSwitchVals[UseParticle][K0] != 0) { + fillV0EfficiencyRecoDebug(posMother.pt(), centrality, EfficiencyK0, V0EfficiencyCommonPrimaryMother); + fillV0EfficiencyRecoDebug(posMother.pt(), centrality, EfficiencyK0, V0EfficiencyMotherSpecies); + if (std::abs(posMother.y()) >= resoCutVals[Rapidity][K0]) { return; + } + fillV0EfficiencyRecoDebug(posMother.pt(), centrality, EfficiencyK0, V0EfficiencyMotherRapidity); + if (!areGeneratedDaughtersWithinEfficiencyEtaAcceptance(posMother)) { + return; + } + fillV0EfficiencyRecoDebug(posMother.pt(), centrality, EfficiencyK0, V0EfficiencyGeneratedDaughterEta); + if (!isWithinEfficiencyEtaAcceptance(postrack) || !isWithinEfficiencyEtaAcceptance(negtrack)) { + return; + } + fillV0EfficiencyRecoDebug(posMother.pt(), centrality, EfficiencyK0, V0EfficiencyRecoDaughterEta); auto selection = selectK0(collision, v0, tracks); if (selection.selected) { - if (areGeneratedDaughtersWithinEfficiencyEtaAcceptance(posMother) && isWithinEfficiencyEtaAcceptance(postrack) && isWithinEfficiencyEtaAcceptance(negtrack)) - registry.fill(HIST("Efficiency/efficiencyHist"), posMother.pt(), centrality, EfficiencyK0, EfficiencyReconstructed); + fillV0EfficiencyRecoDebug(posMother.pt(), centrality, EfficiencyK0, V0EfficiencySelection); + registry.fill(HIST("Efficiency/efficiencyHist"), posMother.pt(), centrality, EfficiencyK0, EfficiencyReconstructed); + fillV0EfficiencyRecoDebug(posMother.pt(), centrality, EfficiencyK0, V0EfficiencyFilled); } return; - } else if (pdgCode == PDG_t::kLambda0 && resoSwitchVals[UseParticle][Lambda]) { - if (std::abs(posMother.y()) >= resoCutVals[Rapidity][Lambda]) + } + + if (pdgCode == PDG_t::kLambda0 && resoSwitchVals[UseParticle][Lambda] != 0) { + fillV0EfficiencyRecoDebug(posMother.pt(), centrality, EfficiencyLambda, V0EfficiencyCommonPrimaryMother); + fillV0EfficiencyRecoDebug(posMother.pt(), centrality, EfficiencyLambda, V0EfficiencyMotherSpecies); + if (std::abs(posMother.y()) >= resoCutVals[Rapidity][Lambda]) { + return; + } + fillV0EfficiencyRecoDebug(posMother.pt(), centrality, EfficiencyLambda, V0EfficiencyMotherRapidity); + if (!areGeneratedDaughtersWithinEfficiencyEtaAcceptance(posMother)) { + return; + } + fillV0EfficiencyRecoDebug(posMother.pt(), centrality, EfficiencyLambda, V0EfficiencyGeneratedDaughterEta); + if (!isWithinEfficiencyEtaAcceptance(postrack) || !isWithinEfficiencyEtaAcceptance(negtrack)) { return; + } + fillV0EfficiencyRecoDebug(posMother.pt(), centrality, EfficiencyLambda, V0EfficiencyRecoDaughterEta); auto selection = selectLambda(collision, v0, tracks); if (selection.selected) { - if (areGeneratedDaughtersWithinEfficiencyEtaAcceptance(posMother) && isWithinEfficiencyEtaAcceptance(postrack) && isWithinEfficiencyEtaAcceptance(negtrack)) - registry.fill(HIST("Efficiency/efficiencyHist"), posMother.pt(), centrality, EfficiencyLambda, EfficiencyReconstructed); + fillV0EfficiencyRecoDebug(posMother.pt(), centrality, EfficiencyLambda, V0EfficiencySelection); + registry.fill(HIST("Efficiency/efficiencyHist"), posMother.pt(), centrality, EfficiencyLambda, EfficiencyReconstructed); + fillV0EfficiencyRecoDebug(posMother.pt(), centrality, EfficiencyLambda, V0EfficiencyFilled); } return; } @@ -2714,12 +3056,14 @@ struct FlowGenericFramework { for (const auto& collision : collisions) { int tracksThisCollision = 0; for (const auto& track : tracks) { - if (track.collisionId() == collision.globalIndex()) + if (track.collisionId() == collision.globalIndex()) { ++tracksThisCollision; + } } float centrality = -1.f; - if (!isEfficiencyEventSelected(collision, tracksThisCollision, centrality)) + if (!isEfficiencyEventSelected(collision, tracksThisCollision, centrality)) { continue; + } if (!hasSelectedCollision || collision.numContrib() > bestNumContrib) { hasSelectedCollision = true; bestNumContrib = collision.numContrib(); @@ -2727,33 +3071,39 @@ struct FlowGenericFramework { selectedCentrality = centrality; } } - if (!hasSelectedCollision) + if (!hasSelectedCollision) { return; + } for (const auto& particle : mcParticles) { - if (particle.mcCollisionId() != mcCollision.globalIndex()) + if (particle.mcCollisionId() != mcCollision.globalIndex()) { continue; + } fillGeneratedEfficiencyTrack(particle, selectedCentrality); - if (isGeneratedEfficiencyV0(particle, PDG_t::kK0Short, K0) && resoSwitchVals[UseParticle][K0]) + if (isGeneratedEfficiencyV0(particle, PDG_t::kK0Short, K0) && resoSwitchVals[UseParticle][K0] != 0) { fillGeneratedEfficiencyV0(particle, EfficiencyK0, selectedCentrality); - if (isGeneratedEfficiencyV0(particle, PDG_t::kLambda0, Lambda) && resoSwitchVals[UseParticle][Lambda]) + } + if (isGeneratedEfficiencyV0(particle, PDG_t::kLambda0, Lambda) && resoSwitchVals[UseParticle][Lambda] != 0) { fillGeneratedEfficiencyV0(particle, EfficiencyLambda, selectedCentrality); + } } for (const auto& collision : collisions) { - if (collision.globalIndex() != bestCollisionIndex) + if (collision.globalIndex() != bestCollisionIndex) { continue; + } auto bc = collision.template bc_as(); - int defaultMagCut = 99999; - auto field = (cfgMagField == defaultMagCut) ? getMagneticField(bc.timestamp()) : cfgMagField; + auto field = (cfgEventSelection.cfgMagField == DefaultMagneticFieldCut) ? getMagneticField(bc.timestamp()) : static_cast(cfgEventSelection.cfgMagField); for (const auto& track : tracks) { - if (track.collisionId() != bestCollisionIndex) + if (track.collisionId() != bestCollisionIndex) { continue; + } fillEfficiencyRecoTrack(track, field, selectedCentrality); } for (const auto& v0 : v0s) { - if (v0.collisionId() != bestCollisionIndex) + if (v0.collisionId() != bestCollisionIndex) { continue; + } fillEfficiencyRecoV0(v0, collision, tracks, selectedCentrality); } break; @@ -2767,16 +3117,18 @@ struct FlowGenericFramework { int run = bc.runNumber(); if (run != lastRun) { lastRun = run; - if (cfgFill.cfgFillRunByRunQA) + if (cfgFill.cfgFillRunByRunQA) { createRunByRunHistograms(run); + } } - if (!collision.sel7()) + if (!collision.sel7()) { return; + } const auto centrality = collision.centRun2V0M(); - if (!cfgFill.cfgFillWeights) + if (!cfgFill.cfgFillWeights) { loadCorrections(bc); - int defaultMagCut = 99999; - auto field = (cfgMagField == defaultMagCut) ? getMagneticField(bc.timestamp()) : cfgMagField; + } + auto field = (cfgEventSelection.cfgMagField == DefaultMagneticFieldCut) ? getMagneticField(bc.timestamp()) : static_cast(cfgEventSelection.cfgMagField); processCollision(collision, tracks, v0s, centrality, field, run); } PROCESS_SWITCH(FlowGenericFramework, processRun2, "Process analysis for Run 2 converted data", false); diff --git a/PWGCF/GenericFramework/Tasks/flowGfwNonflow.cxx b/PWGCF/GenericFramework/Tasks/flowGfwNonflow.cxx new file mode 100644 index 00000000000..60f248df1fa --- /dev/null +++ b/PWGCF/GenericFramework/Tasks/flowGfwNonflow.cxx @@ -0,0 +1,1179 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file flowGfwNonflow.cxx +/// \brief Task to analyse scaled non-flow subtraction of flow cumulants +/// \author Emil Gorm Nielsen, NBI, emil.gorm.nielsen@cern.ch +/// \since 06/07/2026 + +#include "PWGCF/GenericFramework/Core/FlowContainer.h" +#include "PWGCF/GenericFramework/Core/FlowPtContainer.h" +#include "PWGCF/GenericFramework/Core/GFW.h" +#include "PWGCF/GenericFramework/Core/GFWConfig.h" +#include "PWGCF/GenericFramework/Core/GFWWeights.h" + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::analysis::genericframework; + +constexpr float DefaultMagneticFieldCut = 99999.f; +static constexpr std::array, 4> LongArrayDouble = {{{{-0.8, -0.5}}, {{0.5, 0.8}}, {{-2, -2}}, {{-2, -2}}}}; + +struct FlowGfwNonflow { + Configurable cfgNbootstrap{"cfgNbootstrap", 10, "Number of subsamples"}; + Configurable cfgMpar{"cfgMpar", 4, "Highest order of pt-pt correlations"}; + Configurable cfgCentEstimator{"cfgCentEstimator", 0, "0:FT0C; 1:FT0CVariant1; 2:FT0M; 3:FT0A, 4:NTPV, 5:NGlobal, 6:MFT"}; + Configurable cfgUseNch{"cfgUseNch", false, "Do correlations as function of Nch"}; + Configurable cfgUseNchCorrection{"cfgUseNchCorrection", 1, "Use correction for Nch; 0: Use size of tracks table, 1: Use efficiency-corrected Nch values, 2: Use uncorrected Nch values"}; + Configurable cfgRunByRun{"cfgRunByRun", false, "Use run-by-run NUA"}; + Configurable cfgFillQA{"cfgFillQA", false, "Fill QA histograms"}; + Configurable cfgUseCentralMoments{"cfgUseCentralMoments", true, "Use central moments in vn-pt calculations"}; + Configurable cfgUseMultiplicityFlowWeights{"cfgUseMultiplicityFlowWeights", true, "Enable or disable the use of multiplicity-based event weighting"}; + struct : ConfigurableGroup { + Configurable cfgEfficiencyPath{"cfgEfficiencyPath", "", "CCDB path to efficiency object"}; + Configurable cfgUse2DEfficiency{"cfgUse2DEfficiency", false, "Toggle the use of 2D (pt, centrality) efficiency versus centrality integrated efficiency"}; + Configurable cfgAcceptancePath{"cfgAcceptancePath", "", "CCDB path to acceptance object"}; + } cfgCorrections; + struct : ConfigurableGroup { + Configurable> cfgEta{"cfgEta", {-0.8, 0.8}, "eta cut"}; + Configurable> cfgEtaNch{"cfgEtaNch", {-0.5, 0.5}, "eta cut for nch selection"}; + Configurable> cfgEtaPtPt{"cfgEtaPtPt", {-0.5, 0.5}, "eta for pt-pt correlation"}; + Configurable> cfgPtCut{"cfgPtCut", {0.2, 5.0}, "minimum and maximum pt (GeV/c)"}; + } cfgKinematics; + Configurable> cfgPtPtGaps{"cfgPtPtGaps", {LongArrayDouble.front().data(), 4, 2, {"subevent 1", "subevent 2", "subevent 3", "subevent 4"}, {"etamin", "etamax"}}, "{etamin,etamax} for all ptpt-subevents"}; + struct : ConfigurableGroup { + Configurable cfgDCAxyNSigma{"cfgDCAxyNSigma", 7, "Cut on number of sigma deviations from expected DCA in the transverse direction"}; + Configurable cfgDCAxyPtDep{"cfgDCAxyPtDep", "(0.0105 + 0.0350/(x^1.1))", "Functional form of pt-dependent 7 sigma DCAxy cut"}; + Configurable cfgDCAzPtDep{"cfgDCAzPtDep", "(0.0105 + 0.0350/(x^1.1))", "Functional form of pt-dependent DCAz cut"}; + Configurable cfgDCAz{"cfgDCAz", 2, "Cut on DCA in the longitudinal direction (cm)"}; + Configurable cfgNTPCCls{"cfgNTPCCls", 50, "Cut on number of TPC clusters found"}; + Configurable cfgNTPCXrows{"cfgNTPCXrows", 70, "Cut on number of TPC crossed rows"}; + Configurable cfgMinNITSCls{"cfgMinNITSCls", 5, "Cut on minimum number of ITS clusters found"}; + Configurable cfgChi2PrITSCls{"cfgChi2PrITSCls", 36, "Cut on chi^2 per ITS clusters found"}; + Configurable cfgChi2PrTPCCls{"cfgChi2PrTPCCls", 2.5, "Cut on chi^2 per TPC clusters found"}; + Configurable cfgTPCSectorCut{"cfgTPCSectorCut", false, "Cut on pt-phi distribution"}; + } cfgTrackCuts; + struct : ConfigurableGroup { + Configurable cfgNoSameBunchPileupCut{"cfgNoSameBunchPileupCut", true, "NoSameBunchPileupCut"}; + Configurable cfgIsGoodZvtxFT0vsPV{"cfgIsGoodZvtxFT0vsPV", true, "IsGoodZvtxFT0vsPV"}; + Configurable cfgIsGoodITSLayersAll{"cfgIsGoodITSLayersAll", true, "IsGoodITSLayersAll"}; + Configurable cfgNoCollInTimeRangeStandard{"cfgNoCollInTimeRangeStandard", true, "NoCollInTimeRangeStandard"}; + Configurable cfgNoCollInRofStandard{"cfgNoCollInRofStandard", true, "NoCollInRofStandard"}; + Configurable cfgNoHighMultCollInPrevRof{"cfgNoHighMultCollInPrevRof", true, "NoHighMultCollInPrevRof"}; + Configurable cfgNoITSROFrameBorder{"cfgNoITSROFrameBorder", true, "NoITSROFrameBorder"}; + Configurable cfgNoTimeFrameBorder{"cfgNoTimeFrameBorder", true, "NoTimeFrameBorder"}; + Configurable cfgTVXinTRD{"cfgTVXinTRD", true, "TVXinTRD - Use TVXinTRD (reject TRD triggered events)"}; + Configurable cfgIsVertexITSTPC{"cfgIsVertexITSTPC", true, "IsVertexITSTPC - Selects collisions with at least one ITS-TPC track"}; + } cfgEventCutFlags; + struct : ConfigurableGroup { + Configurable cfgOccupancySelection{"cfgOccupancySelection", 2000, "Max occupancy selection, -999 to disable"}; + Configurable cfgDoOccupancySel{"cfgDoOccupancySel", true, "Bool for event selection on detector occupancy"}; + Configurable cfgMagField{"cfgMagField", 99999, "Configurable magnetic field; default CCDB will be queried"}; + Configurable cfgMultCut{"cfgMultCut", false, "Use additional event cut on mult correlations"}; + Configurable cfgVtxZ{"cfgVtxZ", 10, "vertex cut (cm)"}; + } cfgEventSelection; + struct : ConfigurableGroup { + Configurable> cfgMultGlobalCutPars{"cfgMultGlobalCutPars", std::vector{2272.16, -76.6932, 1.01204, -0.00631545, 1.59868e-05, 136.336, -4.97006, 0.121199, -0.0015921, 7.66197e-06}, "Global vs FT0C multiplicity cut parameter values"}; + Configurable> cfgMultPVCutPars{"cfgMultPVCutPars", std::vector{3074.43, -106.192, 1.46176, -0.00968364, 2.61923e-05, 182.128, -7.43492, 0.193901, -0.00256715, 1.22594e-05}, "PV vs FT0C multiplicity cut parameter values"}; + Configurable> cfgMultGlobalPVCutPars{"cfgMultGlobalPVCutPars", std::vector{-0.223013, 0.715849, 0.664242, 0.0829653, -0.000503733, 1.21185e-06}, "Global vs PV multiplicity cut parameter values"}; + Configurable cfgMultCorrHighCutFunction{"cfgMultCorrHighCutFunction", "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"}; + Configurable cfgMultCorrLowCutFunction{"cfgMultCorrLowCutFunction", "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"}; + Configurable cfgMultGlobalPVCorrCutFunction{"cfgMultGlobalPVCorrCutFunction", "[0] + [1]*x + 3*([2] + [3]*x + [4]*x*x + [5]*x*x*x)", "Functional for global vs pv multiplicity correlation cut"}; + Configurable cfgMultGlobalASideCorrCutFunction{"cfgMultGlobalASideCorrCutFunction", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x + [10]*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", "Functional for global vs V0A multiplicity low correlation cut"}; + Configurable> cfgMultGlobalV0ACutPars{"cfgMultGlobalV0ACutPars", std::vector{567.785, 172.715, 0.77888, -0.00693466, 1.40564e-05, 679.853, 66.8068, -0.444332, 0.00115002, -4.92064e-07}, "Global vs FV0A multiplicity cut parameter values"}; + Configurable> cfgMultGlobalT0ACutPars{"cfgMultGlobalT0ACutPars", std::vector{241.618, 61.8402, 0.348049, -0.00306078, 6.20357e-06, 315.235, 29.1491, -0.188639, 0.00044528, -9.08912e-08}, "Global vs FT0A multiplicity cut parameter values"}; + Configurable cfgGlobalV0ALowSigma{"cfgGlobalV0ALowSigma", -3, "Number of sigma deviations below expected value in global vs V0A correlation"}; + Configurable cfgGlobalV0AHighSigma{"cfgGlobalV0AHighSigma", 4, "Number of sigma deviations above expected value in global vs V0A correlation"}; + Configurable cfgGlobalT0ALowSigma{"cfgGlobalT0ALowSigma", -3., "Number of sigma deviations below expected value in global vs T0A correlation"}; + Configurable cfgGlobalT0AHighSigma{"cfgGlobalT0AHighSigma", 4, "Number of sigma deviations above expected value in global vs T0A correlation"}; + } cfgMultCorrCuts; + + Configurable cfgGFWBinning{"cfgGFWBinning", {40, 16, 72, 300, 0, 3000, 0.2, 10.0, 0.2, 3.0, {0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.5, 5, 5.5, 6, 7, 8, 9, 10}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90}}, "Configuration for binning"}; + Configurable cfgRegions{"cfgRegions", {{"refN", "refP", "refFull"}, {-0.8, 0.4, -0.8}, {-0.4, 0.8, 0.8}, {0, 0, 0}, {1, 1, 1}}, "Configurations for GFW regions"}; + + Configurable cfgCorrConfig{"cfgCorrConfig", {{"refP {2} refN {-2}", "refP {3} refN {-3}", "refP {4} refN {-4}", "refFull {2 -2}", "refFull {2 2 -2 -2}"}, {"ChGap22", "ChGap32", "ChGap42", "ChFull22", "ChFull24"}, {0, 0, 0, 0, 0}, {1, 1, 1, 0, 0}}, "Configurations for each correlation to calculate"}; + + struct GFWMemberCache { + std::vector ptbinning = {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}; + float ptpoilow = 0.2; + float ptpoiup = 10.0; + float ptreflow = 0.2; + float ptrefup = 3.0; + float ptlow = 0.2; + float ptup = 10.0; + int etabins = 16; + float etalow = -0.8; + float etaup = 0.8; + int vtxZbins = 40; + int phibins = 72; + float philow = 0.0; + float phiup = o2::constants::math::TwoPI; + int nchbins = 300; + float nchlow = 0; + float nchup = 3000; + std::vector centbinning = std::vector(90); + GFWRegions regions; + GFWCorrConfigs configs; + std::vector> etagapsPtPt; + std::vector multGlobalCorrCutPars; + std::vector multPVCorrCutPars; + std::vector multGlobalPVCorrCutPars; + std::vector multGlobalV0ACutPars; + std::vector multGlobalT0ACutPars; + } gfwMemberCache; + + // Connect to ccdb + Service ccdb{}; + + struct Config { + TH1* mEfficiency = nullptr; + std::vector mAcceptance; + bool correctionsLoaded = false; + } correctionsConfig; + + // Outputs + OutputObj fFC{FlowContainer("FlowContainer")}; + OutputObj fFCgen{FlowContainer("FlowContainer_gen")}; + OutputObj fFCpt{FlowPtContainer("FlowPtContainer")}; + HistogramRegistry registry{"registry"}; + + // Enums + enum CentEstimators { + CentFT0C = 0, + CentFT0CVariant1, + CentFT0M, + CentFV0A, + CentNTPV, + CentNGlobal, + CentMFT + }; + std::map centNamesMap = {{CentFT0C, "FT0C"}, {CentFT0CVariant1, "FT0C variant1"}, {CentFT0M, "FT0M"}, {CentFV0A, "FV0A"}, {CentNTPV, "NTPV"}, {CentNGlobal, "NGlobal"}, {CentMFT, "MFT"}}; + enum EventSelFlags { + FilteredEvent = 1, + Sel8, + Occupancy, + TVXinTRD, + NoSameBunchPileup, + IsGoodZvtxFT0vsPV, + NoCollInTimeRangeStandard, + NoCollInRofStandard, + NoHighMultCollInPrevRof, + NoTimeFrameBorder, + NoITSROFrameBorder, + IsVertexITSTPC, + IsGoodITSLayersAll, + MultCuts, + TrackCent + }; + struct EventCut { + bool enabled; + int histBin; + int flag; // just store the enum + }; + std::vector eventcutflags; + enum ParticleIDs { + ChargedID = 0, + PionID, + KaonID, + ProtonID, + SpeciesCount + }; + + // Generic Framework + GFW* fGFW = new GFW(); + std::vector corrconfigs; + TRandom3* fRndm = new TRandom3(0); + TAxis* fPtAxis = nullptr; + int lastRun = -1; + std::map> recipNHistograms; + + // Track selection - DCA functions + TF1* fPtDepDCAxy = nullptr; + TF1* fPtDepDCAz = nullptr; + + // Event selection cuts - multiplicity correlation + TF1* fMultPVCutLow = nullptr; + TF1* fMultPVCutHigh = nullptr; + TF1* fMultCutLow = nullptr; + TF1* fMultCutHigh = nullptr; + TF1* fMultPVGlobalCutHigh = nullptr; + TF1* fMultGlobalV0ACutLow = nullptr; + TF1* fMultGlobalV0ACutHigh = nullptr; + TF1* fMultGlobalT0ACutLow = nullptr; + TF1* fMultGlobalT0ACutHigh = nullptr; + + // Track selection - pt-phi cuts + TF1* fPhiCutLow = nullptr; + TF1* fPhiCutHigh = nullptr; + + void init(InitContext const&) + { + gfwMemberCache.regions.SetNames(cfgRegions->GetNames()); + gfwMemberCache.regions.SetEtaMin(cfgRegions->GetEtaMin()); + gfwMemberCache.regions.SetEtaMax(cfgRegions->GetEtaMax()); + gfwMemberCache.regions.SetpTDifs(cfgRegions->GetpTDifs()); + gfwMemberCache.regions.SetBitmasks(cfgRegions->GetBitmasks()); + gfwMemberCache.configs.SetCorrs(cfgCorrConfig->GetCorrs()); + gfwMemberCache.configs.SetHeads(cfgCorrConfig->GetHeads()); + gfwMemberCache.configs.SetpTDifs(cfgCorrConfig->GetpTDifs()); + gfwMemberCache.configs.SetpTCorrMasks(cfgCorrConfig->GetpTCorrMasks()); + gfwMemberCache.regions.Print(); + gfwMemberCache.configs.Print(); + gfwMemberCache.ptbinning = cfgGFWBinning->GetPtBinning(); + gfwMemberCache.ptpoilow = cfgGFWBinning->GetPtPOImin(); + gfwMemberCache.ptpoiup = cfgGFWBinning->GetPtPOImax(); + gfwMemberCache.ptreflow = cfgGFWBinning->GetPtRefMin(); + gfwMemberCache.ptrefup = cfgGFWBinning->GetPtRefMax(); + gfwMemberCache.ptlow = cfgKinematics.cfgPtCut->first; + gfwMemberCache.ptup = cfgKinematics.cfgPtCut->second; + gfwMemberCache.etabins = cfgGFWBinning->GetEtaBins(); + gfwMemberCache.vtxZbins = cfgGFWBinning->GetVtxZbins(); + gfwMemberCache.phibins = cfgGFWBinning->GetPhiBins(); + gfwMemberCache.philow = 0.0f; + gfwMemberCache.phiup = o2::constants::math::TwoPI; + gfwMemberCache.nchbins = cfgGFWBinning->GetNchBins(); + gfwMemberCache.nchlow = cfgGFWBinning->GetNchMin(); + gfwMemberCache.nchup = cfgGFWBinning->GetNchMax(); + gfwMemberCache.centbinning = cfgGFWBinning->GetCentBinning(); + cfgGFWBinning->Print(); + gfwMemberCache.multGlobalCorrCutPars = cfgMultCorrCuts.cfgMultGlobalCutPars; + gfwMemberCache.multPVCorrCutPars = cfgMultCorrCuts.cfgMultPVCutPars; + gfwMemberCache.multGlobalPVCorrCutPars = cfgMultCorrCuts.cfgMultGlobalPVCutPars; + gfwMemberCache.multGlobalV0ACutPars = cfgMultCorrCuts.cfgMultGlobalV0ACutPars; + gfwMemberCache.multGlobalT0ACutPars = cfgMultCorrCuts.cfgMultGlobalT0ACutPars; + + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + int64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + ccdb->setCreatedNotAfter(now); + + // Setup event cuts + eventcutflags.push_back({cfgEventCutFlags.cfgNoSameBunchPileupCut, NoSameBunchPileup, o2::aod::evsel::kNoSameBunchPileup}); + eventcutflags.push_back({cfgEventCutFlags.cfgIsGoodZvtxFT0vsPV, IsGoodZvtxFT0vsPV, o2::aod::evsel::kIsGoodZvtxFT0vsPV}); + eventcutflags.push_back({cfgEventCutFlags.cfgNoCollInTimeRangeStandard, NoCollInTimeRangeStandard, o2::aod::evsel::kNoCollInTimeRangeStandard}); + eventcutflags.push_back({cfgEventCutFlags.cfgNoCollInRofStandard, NoCollInRofStandard, o2::aod::evsel::kNoCollInRofStandard}); + eventcutflags.push_back({cfgEventCutFlags.cfgNoHighMultCollInPrevRof, NoHighMultCollInPrevRof, o2::aod::evsel::kNoHighMultCollInPrevRof}); + eventcutflags.push_back({cfgEventCutFlags.cfgNoTimeFrameBorder, NoTimeFrameBorder, o2::aod::evsel::kNoTimeFrameBorder}); + eventcutflags.push_back({cfgEventCutFlags.cfgNoITSROFrameBorder, NoITSROFrameBorder, o2::aod::evsel::kNoITSROFrameBorder}); + eventcutflags.push_back({cfgEventCutFlags.cfgIsVertexITSTPC, IsVertexITSTPC, o2::aod::evsel::kIsVertexITSTPC}); + eventcutflags.push_back({cfgEventCutFlags.cfgIsGoodITSLayersAll, IsGoodITSLayersAll, o2::aod::evsel::kIsGoodITSLayersAll}); + for (const auto& cut : eventcutflags) { + LOGF(info, "Flag %d is %senabled", cut.histBin, (cut.enabled) ? "" : "not "); + } + + AxisSpec phiAxis = {gfwMemberCache.phibins, gfwMemberCache.philow, gfwMemberCache.phiup, "#phi"}; + AxisSpec phiModAxis = {100, 0, constants::math::PI / 9, "fmod(#varphi,#pi/9)"}; + AxisSpec etaAxis = {gfwMemberCache.etabins, cfgKinematics.cfgEta->first, cfgKinematics.cfgEta->second, "#eta"}; + AxisSpec vtxAxis = {gfwMemberCache.vtxZbins, -cfgEventSelection.cfgVtxZ, cfgEventSelection.cfgVtxZ, "Vtx_{z} (cm)"}; + AxisSpec ptAxis = {gfwMemberCache.ptbinning, "#it{p}_{T} GeV/#it{c}"}; + std::string sCentralityEstimator = centNamesMap[cfgCentEstimator] + " centrality (%)"; + AxisSpec centAxis = {gfwMemberCache.centbinning, sCentralityEstimator.c_str()}; + std::vector nchbinning; + const double nchskip = (gfwMemberCache.nchup - gfwMemberCache.nchlow) / gfwMemberCache.nchbins; + for (int i = 0; i <= gfwMemberCache.nchbins; ++i) { + nchbinning.push_back(nchskip * i + gfwMemberCache.nchlow + 0.5); + } + AxisSpec nchAxis = {nchbinning, "N_{ch}"}; + AxisSpec bAxis = {200, 0, 20, "#it{b}"}; + AxisSpec t0cAxis = {1000, 0, 50000, "N_{ch} (T0C)"}; + AxisSpec t0aAxis = {1800, 0, 180000, "N_{ch} (T0A)"}; + AxisSpec v0aAxis = {1800, 0, 180000, "N_{ch} (V0A)"}; + AxisSpec multpvAxis = {3500, 0, 3500, "N_{ch} (PV)"}; + AxisSpec occAxis = {500, 0, 5000, "occupancy"}; + AxisSpec multAxis = (cfgUseNch) ? nchAxis : centAxis; + AxisSpec dcaZAXis = {200, -2, 2, "DCA_{z} (cm)"}; + AxisSpec dcaXYAXis = {200, -1, 1, "DCA_{xy} (cm)"}; + + if (cfgFillQA) { + registry.add("trackQA/before/phi_eta_vtxZ", "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); + registry.add("trackQA/before/pt_dcaXY_dcaZ", "", {HistType::kTH3D, {ptAxis, dcaXYAXis, dcaZAXis}}); + registry.add("trackQA/before/pt_phi", "", {HistType::kTH2D, {ptAxis, phiModAxis}}); + registry.add("trackQA/before/chi2prTPCcls", "#chi^{2}/cluster for the TPC track segment", {HistType::kTH1D, {{100, 0., 5.}}}); + registry.add("trackQA/before/chi2prITScls", "#chi^{2}/cluster for the ITS track", {HistType::kTH1D, {{100, 0., 50.}}}); + registry.add("trackQA/before/nTPCClusters", "Number of found TPC clusters", {HistType::kTH1D, {{100, 40, 180}}}); + registry.add("trackQA/before/nITSClusters", "Number of found ITS clusters", {HistType::kTH1D, {{100, 0, 20}}}); + registry.add("trackQA/before/nTPCCrossedRows", "Number of crossed TPC Rows", {HistType::kTH1D, {{100, 40, 180}}}); + registry.addClone("trackQA/before/", "trackQA/after/"); + registry.add("trackQA/after/pt_ref", "; #it{p}_{T}; Counts", {HistType::kTH1D, {{100, gfwMemberCache.ptreflow, gfwMemberCache.ptrefup}}}); + registry.add("trackQA/after/pt_poi", "; #it{p}_{T}; Counts", {HistType::kTH1D, {{100, gfwMemberCache.ptpoilow, gfwMemberCache.ptpoiup}}}); + registry.add("trackQA/after/Nch_corrected", "; N_{ch}; Counts", {HistType::kTH1D, {nchAxis}}); + registry.add("trackQA/after/Nch_uncorrected", "; N_{ch}; Counts", {HistType::kTH1D, {nchAxis}}); + registry.add("trackQA/after/etaNch", "; #eta; Counts", {HistType::kTH1D, {etaAxis}}); + registry.add("trackQA/after/etaPtPt", "; #eta; Counts", {HistType::kTH1D, {etaAxis}}); + + registry.add("eventQA/before/globalTracks_centT0C", "; FT0C centrality (%); N_{global}", {HistType::kTH2D, {centAxis, nchAxis}}); + registry.add("eventQA/before/PVTracks_centT0C", "; FT0C centrality (%); N_{PV}", {HistType::kTH2D, {centAxis, multpvAxis}}); + registry.add("eventQA/before/globalTracks_PVTracks", "; N_{PV}; N_{global}", {HistType::kTH2D, {multpvAxis, nchAxis}}); + registry.add("eventQA/before/globalTracks_multT0A", "; multT0A; N_{global}", {HistType::kTH2D, {t0aAxis, nchAxis}}); + registry.add("eventQA/before/globalTracks_multV0A", "; multV0A; N_{global}", {HistType::kTH2D, {v0aAxis, nchAxis}}); + registry.add("eventQA/before/multV0A_multT0A", "; multV0A; multT0A", {HistType::kTH2D, {t0aAxis, v0aAxis}}); + registry.add("eventQA/before/multT0C_centT0C", "; multT0C; FT0C centrality (%)", {HistType::kTH2D, {centAxis, t0cAxis}}); + registry.add("eventQA/before/occ_mult_cent", "; occupancy; N_{ch}; centrality (%)", {HistType::kTH3D, {occAxis, nchAxis, centAxis}}); + } + registry.add("eventQA/before/centrality", "; centrality (%); Counts", {HistType::kTH1D, {centAxis}}); + registry.add("eventQA/before/multiplicity", "; N_{ch}; Counts", {HistType::kTH1D, {nchAxis}}); + registry.addClone("eventQA/before/", "eventQA/after/"); + registry.add("eventQA/eventSel", "Number of Events;; Counts", {HistType::kTH1D, {{15, 0.5, 15.5}}}); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(FilteredEvent, "Filtered event"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(Sel8, "sel8"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(Occupancy, "occupancy"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(TVXinTRD, "TVXinTRD"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(NoSameBunchPileup, "NoSameBunchPileup"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(IsGoodZvtxFT0vsPV, "IsGoodZvtxFT0vsPV"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(NoCollInTimeRangeStandard, "NoCollInTimeRangeStandard"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(NoCollInRofStandard, "NoCollInRofStandard"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(NoHighMultCollInPrevRof, "NoHighMultCollInPrevRof"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(NoTimeFrameBorder, "NoTimeFrameBorder"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(NoITSROFrameBorder, "NoITSROFrameBorder"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(IsVertexITSTPC, "IsVertexITSTPC"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(IsGoodITSLayersAll, "IsGoodITSLayersAll"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(MultCuts, "after Mult cuts"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(TrackCent, "has track + within cent"); + + const int ptbins = static_cast(gfwMemberCache.ptbinning.size() - 1); + fPtAxis = new TAxis(ptbins, gfwMemberCache.ptbinning.data()); + + if (gfwMemberCache.regions.GetSize() < 0) { + LOGF(error, "Configuration contains vectors of different size - check the GFWRegions configurable"); + } + for (auto i(0); i < gfwMemberCache.regions.GetSize(); ++i) { + fGFW->AddRegion(gfwMemberCache.regions.GetNames()[i], gfwMemberCache.regions.GetEtaMin()[i], gfwMemberCache.regions.GetEtaMax()[i], (gfwMemberCache.regions.GetpTDifs()[i] != 0) ? ptbins + 1 : 1, gfwMemberCache.regions.GetBitmasks()[i]); + } + for (auto i = 0; i < gfwMemberCache.configs.GetSize(); ++i) { + corrconfigs.push_back(fGFW->GetCorrelatorConfig(gfwMemberCache.configs.GetCorrs()[i], gfwMemberCache.configs.GetHeads()[i], gfwMemberCache.configs.GetpTDifs()[i] != 0)); + const auto& head = gfwMemberCache.configs.GetHeads()[i]; + std::string histName = "inverseN"; + histName += head; + recipNHistograms[histName] = registry.add(histName, " centrality (%); ", HistType::kTProfile, {centAxis}); + } + if (corrconfigs.empty()) { + LOGF(error, "Configuration contains vectors of different size - check the GFWCorrConfig configurable"); + } + fGFW->CreateRegions(); + auto oba = new TObjArray(); + addConfigObjectsToObjArray(oba, corrconfigs); + fFC->SetName("FlowContainer"); + fFC->SetXAxis(fPtAxis); + fFC->Initialize(oba, multAxis, cfgNbootstrap); + fFCgen->SetName("FlowContainer_gen"); + fFCgen->SetXAxis(fPtAxis); + fFCgen->Initialize(oba, multAxis, cfgNbootstrap); + delete oba; + + const auto& ptPtGaps = cfgPtPtGaps->getData(); + for (uint32_t i = 0; i < ptPtGaps.rows; ++i) { + const auto etaMin = ptPtGaps(i, 0); + const auto etaMax = ptPtGaps(i, 1); + + if (etaMin < -1. || etaMax < -1.) { + continue; + } + + gfwMemberCache.etagapsPtPt.emplace_back(etaMin, etaMax); + } + for (const auto& [etamin, etamax] : gfwMemberCache.etagapsPtPt) { + LOGF(info, "pt-pt subevent: {%.1f,%.1f}", etamin, etamax); + } + + fFCpt->setUseCentralMoments(cfgUseCentralMoments); + fFCpt->setUseGapMethod(true); + fFCpt->initialise(multAxis, cfgMpar, gfwMemberCache.configs, cfgNbootstrap); + fFCpt->initialiseSubevent(multAxis, cfgMpar, gfwMemberCache.etagapsPtPt.size(), cfgNbootstrap); + + fPtDepDCAxy = new TF1("ptDepDCAxy", Form("[0]*%s", cfgTrackCuts.cfgDCAxyPtDep->c_str()), 0.001, 100); + fPtDepDCAxy->SetParameter(0, cfgTrackCuts.cfgDCAxyNSigma / 7.); + LOGF(info, "DCAxy pt-dependence function: %s", Form("[0]*%s", cfgTrackCuts.cfgDCAxyPtDep->c_str())); + if (!cfgTrackCuts.cfgDCAzPtDep.value.empty()) { + fPtDepDCAz = new TF1("ptDepDCAz", Form("%s", cfgTrackCuts.cfgDCAzPtDep->c_str()), 0.001, 100); + LOGF(info, "DCAz pt-dependence function: %s", Form("%s", cfgTrackCuts.cfgDCAzPtDep->c_str())); + } + + // Multiplicity correlation cuts + if (cfgEventSelection.cfgMultCut) { + fMultPVCutLow = new TF1("fMultPVCutLow", cfgMultCorrCuts.cfgMultCorrLowCutFunction->c_str(), 0, 100); + fMultPVCutLow->SetParameters(gfwMemberCache.multPVCorrCutPars.data()); + fMultPVCutHigh = new TF1("fMultPVCutHigh", cfgMultCorrCuts.cfgMultCorrHighCutFunction->c_str(), 0, 100); + fMultPVCutHigh->SetParameters(gfwMemberCache.multPVCorrCutPars.data()); + fMultCutLow = new TF1("fMultCutLow", cfgMultCorrCuts.cfgMultCorrLowCutFunction->c_str(), 0, 100); + fMultCutLow->SetParameters(gfwMemberCache.multGlobalCorrCutPars.data()); + fMultCutHigh = new TF1("fMultCutHigh", cfgMultCorrCuts.cfgMultCorrHighCutFunction->c_str(), 0, 100); + fMultCutHigh->SetParameters(gfwMemberCache.multGlobalCorrCutPars.data()); + fMultPVGlobalCutHigh = new TF1("fMultPVGlobalCutHigh", cfgMultCorrCuts.cfgMultGlobalPVCorrCutFunction->c_str(), 0, nchbinning.back()); + fMultPVGlobalCutHigh->SetParameters(gfwMemberCache.multGlobalPVCorrCutPars.data()); + + LOGF(info, "Global V0A function: %s in range 0-%g", cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), v0aAxis.binEdges.back()); + fMultGlobalV0ACutLow = new TF1("fMultGlobalV0ACutLow", cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, v0aAxis.binEdges.back()); + for (std::size_t i = 0; i < gfwMemberCache.multGlobalV0ACutPars.size(); ++i) { + fMultGlobalV0ACutLow->SetParameter(i, gfwMemberCache.multGlobalV0ACutPars[i]); + } + fMultGlobalV0ACutLow->SetParameter(gfwMemberCache.multGlobalV0ACutPars.size(), cfgMultCorrCuts.cfgGlobalV0ALowSigma); + for (int i = 0; i < fMultGlobalV0ACutLow->GetNpar(); ++i) { + LOGF(info, "fMultGlobalV0ACutLow par %d = %g", i, fMultGlobalV0ACutLow->GetParameter(i)); + } + + fMultGlobalV0ACutHigh = new TF1("fMultGlobalV0ACutHigh", cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, v0aAxis.binEdges.back()); + for (std::size_t i = 0; i < gfwMemberCache.multGlobalV0ACutPars.size(); ++i) { + fMultGlobalV0ACutHigh->SetParameter(i, gfwMemberCache.multGlobalV0ACutPars[i]); + } + fMultGlobalV0ACutHigh->SetParameter(gfwMemberCache.multGlobalV0ACutPars.size(), cfgMultCorrCuts.cfgGlobalV0AHighSigma); + for (int i = 0; i < fMultGlobalV0ACutHigh->GetNpar(); ++i) { + LOGF(info, "fMultGlobalV0ACutHigh par %d = %g", i, fMultGlobalV0ACutHigh->GetParameter(i)); + } + + LOGF(info, "Global T0A function: %s", cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str()); + fMultGlobalT0ACutLow = new TF1("fMultGlobalT0ACutLow", cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, t0aAxis.binEdges.back()); + for (std::size_t i = 0; i < gfwMemberCache.multGlobalT0ACutPars.size(); ++i) { + fMultGlobalT0ACutLow->SetParameter(i, gfwMemberCache.multGlobalT0ACutPars[i]); + } + fMultGlobalT0ACutLow->SetParameter(gfwMemberCache.multGlobalT0ACutPars.size(), cfgMultCorrCuts.cfgGlobalT0ALowSigma); + for (int i = 0; i < fMultGlobalT0ACutLow->GetNpar(); ++i) { + LOGF(info, "fMultGlobalT0ACutLow par %d = %g", i, fMultGlobalT0ACutLow->GetParameter(i)); + } + + fMultGlobalT0ACutHigh = new TF1("fMultGlobalT0ACutHigh", cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, t0aAxis.binEdges.back()); + for (std::size_t i = 0; i < gfwMemberCache.multGlobalT0ACutPars.size(); ++i) { + fMultGlobalT0ACutHigh->SetParameter(i, gfwMemberCache.multGlobalT0ACutPars[i]); + } + fMultGlobalT0ACutHigh->SetParameter(gfwMemberCache.multGlobalT0ACutPars.size(), cfgMultCorrCuts.cfgGlobalT0AHighSigma); + for (int i = 0; i < fMultGlobalT0ACutHigh->GetNpar(); ++i) { + LOGF(info, "fMultGlobalT0ACutHigh par %d = %g", i, fMultGlobalT0ACutHigh->GetParameter(i)); + } + } + } + + static constexpr std::array FillTimeName = {"before/", "after/"}; + + void addConfigObjectsToObjArray(TObjArray* oba, const std::vector& configs) + { + for (auto it = configs.begin(); it != configs.end(); ++it) { + if (it->pTDif) { + std::string suffix = "_ptDiff"; + for (auto i = 0; i < fPtAxis->GetNbins(); ++i) { + std::string index = Form("_pt_%i", i + 1); + oba->Add(new TNamed(it->Head + index, it->Head + suffix)); + } + } else { + oba->Add(new TNamed(it->Head.c_str(), it->Head.c_str())); + } + } + } + + int getMagneticField(uint64_t timestamp) + { + // TODO done only once (and not per run). Will be replaced by CCDBConfigurable + // static o2::parameters::GRPObject* grpo = nullptr; + static o2::parameters::GRPMagField* grpo = nullptr; + if (grpo == nullptr) { + // grpo = ccdb->getForTimeStamp("GLO/GRP/GRP", timestamp); + grpo = ccdb->getForTimeStamp("GLO/Config/GRPMagField", timestamp); + if (grpo == nullptr) { + LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); + return 0; + } + LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); + } + return grpo->getNominalL3Field(); + } + + void loadCorrections(aod::BCsWithTimestamps::iterator const& bc) + { + uint64_t timestamp = bc.timestamp(); + if (!cfgRunByRun && correctionsConfig.correctionsLoaded) { + return; + } + if (!cfgCorrections.cfgAcceptancePath.value.empty()) { + std::string runstr = (cfgRunByRun) ? "RunByRun/" : ""; + correctionsConfig.mAcceptance.clear(); + correctionsConfig.mAcceptance.push_back(ccdb->getForTimeStamp(cfgCorrections.cfgAcceptancePath.value + runstr, timestamp)); + } + // Run-by-run efficiencies are not supported at the moment + if (correctionsConfig.correctionsLoaded) { + return; + } + if (!cfgCorrections.cfgEfficiencyPath.value.empty()) { + if (cfgCorrections.cfgUse2DEfficiency) { + correctionsConfig.mEfficiency = ccdb->getForTimeStamp(cfgCorrections.cfgEfficiencyPath, timestamp); + } else { + correctionsConfig.mEfficiency = ccdb->getForTimeStamp(cfgCorrections.cfgEfficiencyPath, timestamp); + } + if (correctionsConfig.mEfficiency == nullptr) { + LOGF(fatal, "Could not load efficiency histogram from %s", cfgCorrections.cfgEfficiencyPath.value.c_str()); + } + LOGF(info, "Loaded efficiency histogram from %s", cfgCorrections.cfgEfficiencyPath.value.c_str()); + } + correctionsConfig.correctionsLoaded = true; + } + + template + double getAcceptance(const TTrack& track, const double& vtxz) + { // 0 ref, 1 ch, 2 pi, 3 ka, 4 pr + double wacc = 1; + if (!correctionsConfig.mAcceptance.empty()) { + wacc = correctionsConfig.mAcceptance[0]->getNUA(track.phi(), track.eta(), vtxz); + } + return wacc; + } + + template + double getEfficiency(const TTrack& track, const float& centrality) + { //-1 ref, 0 ch, 1 pi, 2 ka, 3 pr, 4 k0, 5 lambda + double eff = 1.; + if (!correctionsConfig.mEfficiency) { + return eff; + } + if (cfgCorrections.cfgUse2DEfficiency) { + eff = dynamic_cast(correctionsConfig.mEfficiency)->GetBinContent(dynamic_cast(correctionsConfig.mEfficiency)->FindBin(track.pt(), centrality)); + } else { + eff = dynamic_cast(correctionsConfig.mEfficiency)->GetBinContent(dynamic_cast(correctionsConfig.mEfficiency)->FindBin(track.pt())); + } + if (eff == 0) { + return -1.; + } + return 1. / eff; + } + + template + bool eventSelected(const TCollision& collision, const int multTrk, const float& centrality) + { + // Cut on trigger alias + if (cfgEventCutFlags.cfgTVXinTRD) { + if (collision.alias_bit(TVXinTRD)) { + // TRD triggered + // "CMTVX-B-NOPF-TRD,minbias_TVX" + return false; + } + registry.fill(HIST("eventQA/eventSel"), TVXinTRD); + } + // Cut on event selection flags + for (const auto& cut : eventcutflags) { + if (!cut.enabled) { + continue; + } + if (!collision.selection_bit(cut.flag)) { + return false; + } + registry.fill(HIST("eventQA/eventSel"), cut.histBin); + } + // Cut on vertex + if (!selectVertex(collision)) { + return false; + } + // Cut on multiplicity correlations - data driven + if (cfgEventSelection.cfgMultCut) { + if (!selectMultiplicityCorrelation(collision, multTrk, centrality)) { + return false; + } + } + return true; + } + + template + bool selectVertex(const TCollision& collision) + { + float vtxz = -999; + if (collision.numContrib() > 1) { + vtxz = collision.posZ(); + float zRes = std::sqrt(collision.covZZ()); + float minZRes = 0.25; + int minNContrib = 20; + if (zRes > minZRes && collision.numContrib() < minNContrib) { + vtxz = -999; + } + } + if (vtxz > cfgEventSelection.cfgVtxZ || vtxz < -cfgEventSelection.cfgVtxZ) { + return false; + } + + return true; + } + + template + bool selectMultiplicityCorrelation(const TCollision& collision, const int multTrk, const float& centrality) + { + auto multNTracksPV = collision.multNTracksPV(); + if (multNTracksPV < fMultPVCutLow->Eval(centrality)) { + return false; + } + if (multNTracksPV > fMultPVCutHigh->Eval(centrality)) { + return false; + } + if (multTrk < fMultCutLow->Eval(centrality)) { + return false; + } + if (multTrk > fMultCutHigh->Eval(centrality)) { + return false; + } + if (multTrk > fMultPVGlobalCutHigh->Eval(collision.multNTracksPV())) { + return false; + } + + if (!(cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFV0A()) < fMultGlobalV0ACutLow->Eval(multTrk)) { + return false; + } + if (!(cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFV0A()) > fMultGlobalV0ACutHigh->Eval(multTrk)) { + return false; + } + if (!(cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFT0A()) < fMultGlobalT0ACutLow->Eval(multTrk)) { + return false; + } + if (!(cfgMultCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFT0A()) > fMultGlobalT0ACutHigh->Eval(multTrk)) { + return false; + } + registry.fill(HIST("eventQA/eventSel"), MultCuts); + return true; + } + + template + bool trackSelected(const TTrack& track, const int field) + { + if (cfgTrackCuts.cfgTPCSectorCut) { + double phimodn = track.phi(); + if (field < 0) { // for negative polarity field + phimodn = o2::constants::math::TwoPI - phimodn; + } + if (track.sign() < 0) { // for negative charge + phimodn = o2::constants::math::TwoPI - phimodn; + } + if (phimodn < 0) { + LOGF(warning, "phi < 0: %g", phimodn); + } + + phimodn += o2::constants::math::PI / 18.0; // to center gap in the middle + phimodn = fmod(phimodn, o2::constants::math::PI / 9.0); + if (cfgFillQA) { + registry.fill(HIST("trackQA/before/pt_phi"), track.pt(), phimodn); + } + if (phimodn < fPhiCutHigh->Eval(track.pt()) && phimodn > fPhiCutLow->Eval(track.pt())) { + return false; // reject track + } + if (cfgFillQA) { + registry.fill(HIST("trackQA/after/pt_phi"), track.pt(), phimodn); + } + } + if (cfgTrackCuts.cfgDCAxyNSigma && (std::fabs(track.dcaXY()) > fPtDepDCAxy->Eval(track.pt()))) { + return false; + } + if (!cfgTrackCuts.cfgDCAzPtDep.value.empty() && std::fabs(track.dcaZ() > fPtDepDCAz->Eval(track.pt()))) { + return false; + } + return ((track.tpcNClsCrossedRows() >= cfgTrackCuts.cfgNTPCXrows) && (track.tpcNClsFound() >= cfgTrackCuts.cfgNTPCCls) && (track.itsNCls() >= cfgTrackCuts.cfgMinNITSCls)); + } + + template + bool nchSelected(const TTrack& track) + { + // Renormalise to default cut + const float defaultNsigma = 7; + if (cfgTrackCuts.cfgDCAxyNSigma && (std::fabs(track.dcaXY()) > defaultNsigma / cfgTrackCuts.cfgDCAxyNSigma * fPtDepDCAxy->Eval(track.pt()))) { + return false; + } + if (!cfgTrackCuts.cfgDCAzPtDep.value.empty() && std::fabs(track.dcaZ() > fPtDepDCAz->Eval(track.pt()))) { + return false; + } + int tpcNClsCrossedRowsDefault = 70; + int tpcNClsFoundDefault = 50; + int itsNclsDefault = 5; + return ((track.tpcNClsCrossedRows() >= tpcNClsCrossedRowsDefault) && (track.tpcNClsFound() >= tpcNClsFoundDefault) && (track.itsNCls() >= itsNclsDefault)); + } + + enum DataType { + Reco, + Gen + }; + + template + void fillOutputContainers(const float& centmult, const double& rndm, const float& multiplicity) + { + fFCpt->calculateCorrelations(); + fFCpt->calculateSubeventCorrelations(); + fFCpt->fillPtProfiles(centmult, rndm); + fFCpt->fillSubeventPtProfiles(centmult, rndm); + fFCpt->fillCMProfiles(centmult, rndm); + fFCpt->fillCMSubeventProfiles(centmult, rndm); + + for (std::size_t l_ind = 0; l_ind < corrconfigs.size(); ++l_ind) { + if (!corrconfigs.at(l_ind).pTDif) { + auto dnx = fGFW->Calculate(corrconfigs.at(l_ind), 0, true).real(); + if (dnx == 0) { + continue; + } + const auto corrOrder = gfwMemberCache.configs.GetHeads()[l_ind].back(); + const auto& head = gfwMemberCache.configs.GetHeads()[l_ind]; + std::string histName = "inverseN"; + histName += head; + const int m = corrOrder - '0'; + recipNHistograms.at(histName)->Fill(centmult, 1. / std::pow(multiplicity, m - 1), dnx); + auto val = fGFW->Calculate(corrconfigs.at(l_ind), 0, false).real() / dnx; + if (std::abs(val) < 1) { + fFC->FillProfile(corrconfigs.at(l_ind).Head.c_str(), centmult, val, cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm); + fFCpt->fillVnPtProfiles(centmult, val, dnx, rndm, gfwMemberCache.configs.GetpTCorrMasks()[l_ind]); + } + continue; + } + for (int i = 1; i <= fPtAxis->GetNbins(); i++) { + auto dnx = fGFW->Calculate(corrconfigs.at(l_ind), i - 1, true).real(); + if (dnx == 0) { + continue; + } + auto val = fGFW->Calculate(corrconfigs.at(l_ind), i - 1, false).real() / dnx; + if (std::abs(val) < 1) { + fFC->FillProfile(Form("%s_pt_%i", corrconfigs.at(l_ind).Head.c_str(), i), centmult, val, cfgUseMultiplicityFlowWeights ? dnx : 1.0, rndm); + } + } + } + } + + template + inline void fillPtSums(const TTrack& track, const float& centrality) + { + double weff = (dt == Gen) ? 1. : getEfficiency(track, centrality); + if (weff < 0) { + return; + } + // Fill the nominal sums + if (track.eta() > cfgKinematics.cfgEtaPtPt->first && track.eta() < cfgKinematics.cfgEtaPtPt->second) { + fFCpt->fill(weff, track.pt()); + } + // Fill the subevent sums + std::size_t index = 0; + for (const auto& [etamin, etamax] : gfwMemberCache.etagapsPtPt) { + if (etamin < track.eta() && track.eta() < etamax) { + fFCpt->fillSub(weff, track.pt(), index); + } + ++index; + } + } + + template + inline void fillGFW(const TTrack& track, const float& centrality, const double& vtxz) + { + bool withinPtRef = (track.pt() > gfwMemberCache.ptreflow && track.pt() < gfwMemberCache.ptrefup); + bool withinPtPOI = (track.pt() > gfwMemberCache.ptpoilow && track.pt() < gfwMemberCache.ptpoiup); + if (!withinPtPOI && !withinPtRef) { + return; + } + double weff = (dt == Gen) ? 1. : getEfficiency(track, centrality); + if (weff < 0) { + return; + } + double wacc = (dt == Gen) ? 1. : getAcceptance(track, vtxz); + if (withinPtRef) { + fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), weff * wacc, 1); + } + if (withinPtPOI) { + fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), weff * wacc, 2); + } + if (withinPtRef && withinPtPOI) { + fGFW->Fill(track.eta(), fPtAxis->FindBin(track.pt()) - 1, track.phi(), weff * wacc, 4); + } + } + + template + float getCentrality(const TCollision& collision) + { + switch (cfgCentEstimator) { + case CentFT0C: + return collision.centFT0C(); + case CentFT0CVariant1: + return collision.centFT0CVariant1(); + case CentFT0M: + return collision.centFT0M(); + case CentFV0A: + return collision.centFV0A(); + case CentNTPV: + return collision.centNTPV(); + case CentNGlobal: + return collision.centNGlobal(); + case CentMFT: + return collision.centMFT(); + default: + return collision.centFT0C(); + } + } + + enum QAFillTime { + Before, + After + }; + + template + inline void fillTrackQA(const TTrack& track, const float vtxz) + { + if constexpr (dt == Gen) { + registry.fill(HIST("MCGen/") + HIST(FillTimeName[ft]) + HIST("phi_eta_vtxZ_gen"), track.phi(), track.eta(), vtxz); + registry.fill(HIST("MCGen/") + HIST(FillTimeName[ft]) + HIST("pt_gen"), track.pt()); + } else { + double wacc = getAcceptance(track, vtxz); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("phi_eta_vtxZ"), track.phi(), track.eta(), vtxz, (ft == After) ? wacc : 1.0); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("pt_dcaXY_dcaZ"), track.pt(), track.dcaXY(), track.dcaZ()); + + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("chi2prTPCcls"), track.tpcChi2NCl()); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("chi2prITScls"), track.itsChi2NCl()); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("nTPCClusters"), track.tpcNClsFound()); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("nITSClusters"), track.itsNCls()); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("nTPCCrossedRows"), track.tpcNClsCrossedRows()); + + if (ft == After) { + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("pt_ref"), track.pt()); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("pt_poi"), track.pt()); + + if (track.eta() > cfgKinematics.cfgEtaNch->first && track.eta() < cfgKinematics.cfgEtaNch->second) { + registry.fill(HIST("trackQA/after/etaNch"), track.eta()); + } + if (track.eta() > cfgKinematics.cfgEtaPtPt->first && track.eta() < cfgKinematics.cfgEtaPtPt->second && cfgFillQA) { + registry.fill(HIST("trackQA/after/etaPtPt"), track.eta()); + } + } + } + } + + template + inline void fillEventQA(const TCollision& collision, const TTracks& tracks) + { + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("globalTracks_centT0C"), collision.centFT0C(), tracks.size()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("PVTracks_centT0C"), collision.centFT0C(), collision.multNTracksPV()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("globalTracks_PVTracks"), collision.multNTracksPV(), tracks.size()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("globalTracks_multT0A"), collision.multFT0A(), tracks.size()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("globalTracks_multV0A"), collision.multFV0A(), tracks.size()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("multV0A_multT0A"), collision.multFT0A(), collision.multFV0A()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("multT0C_centT0C"), collision.centFT0C(), collision.multFT0C()); + } + + struct AcceptedTracks { + float total = 0; + unsigned int totaluncorr = 0; + }; + + template + void processCollision(const TCollision& collision, const TTracks& tracks, const float& centrality, const float& field) + { + if (tracks.size() < 1) { + return; + } + if (dt != Gen && (centrality < gfwMemberCache.centbinning.front() || centrality > gfwMemberCache.centbinning.back())) { + return; + } + if (dt != Gen) { + registry.fill(HIST("eventQA/eventSel"), TrackCent); + } + float vtxz = collision.posZ(); + + fGFW->Clear(); + fFCpt->clearVector(); + + float lRandom = fRndm->Rndm(); + + // process tracks + AcceptedTracks acceptedTracks; + for (const auto& track : tracks) { + processTrack(track, vtxz, field, centrality, acceptedTracks); + } + if (dt != Gen && cfgFillQA) { + registry.fill(HIST("trackQA/after/Nch_corrected"), acceptedTracks.total); + registry.fill(HIST("trackQA/after/Nch_uncorrected"), acceptedTracks.totaluncorr); + } + + float multiplicity = 0.f; + switch (cfgUseNchCorrection) { + case 0: + multiplicity = tracks.size(); + break; + case 1: + multiplicity = acceptedTracks.total; + break; + case 2: + multiplicity = acceptedTracks.totaluncorr; + break; + default: + multiplicity = tracks.size(); + break; + } + + fillOutputContainers
((cfgUseNch) ? multiplicity : centrality, lRandom, multiplicity); + } + + template + inline void processTrack(const TTrack& track, const float& vtxz, const float& field, const float& centrality, AcceptedTracks& acceptedTracks) + { + if constexpr (framework::has_type_v) { + if (track.mcParticleId() < 0 || !(track.has_mcParticle())) { + return; + } + auto mcParticle = track.mcParticle(); + if (!mcParticle.isPhysicalPrimary()) { + return; + } + if (cfgFillQA) { + fillTrackQA(track, vtxz); + } + if (mcParticle.eta() < gfwMemberCache.etalow || mcParticle.eta() > gfwMemberCache.etaup || mcParticle.pt() < gfwMemberCache.ptlow || mcParticle.pt() > gfwMemberCache.ptup) { + return; + } + // Select tracks with nominal cuts always + if (!nchSelected(track)) { + return; + } + double weffCh = getEfficiency(track, centrality); + if (track.eta() > cfgKinematics.cfgEtaNch->first && track.eta() < cfgKinematics.cfgEtaNch->second) { + if (weffCh > 0) { + acceptedTracks.total += (cfgUseNchCorrection) ? weffCh : 1.0; + } + ++acceptedTracks.totaluncorr; + } + + if (!trackSelected(track, field)) { + return; + } + + fillPtSums(track, centrality); + fillGFW(mcParticle, centrality, vtxz); + if (cfgFillQA) { + fillTrackQA(track, vtxz); + } + + } else if constexpr (framework::has_type_v) { + if (!track.isPhysicalPrimary()) { + return; + } + if (cfgFillQA) { + fillTrackQA(track, vtxz); + } + if (track.eta() < gfwMemberCache.etalow || track.eta() > gfwMemberCache.etaup || track.pt() < gfwMemberCache.ptlow || track.pt() > gfwMemberCache.ptup) { + return; + } + + if (track.eta() > cfgKinematics.cfgEtaNch->first && track.eta() < cfgKinematics.cfgEtaNch->second) { + ++acceptedTracks.total; + ++acceptedTracks.totaluncorr; + } + + fillPtSums(track, centrality); + fillGFW(track, centrality, vtxz); + if (cfgFillQA) { + fillTrackQA(track, vtxz); + } + + } else { + if (cfgFillQA) { + fillTrackQA(track, vtxz); + } + // Select tracks with nominal cuts always + if (!nchSelected(track)) { + return; + } + double weffCh = getEfficiency(track, centrality); + if (track.eta() > cfgKinematics.cfgEtaNch->first && track.eta() < cfgKinematics.cfgEtaNch->second) { + if (weffCh > 0) { + acceptedTracks.total += (cfgUseNchCorrection) ? weffCh : 1.0; + } + ++acceptedTracks.totaluncorr; + } + if (!trackSelected(track, field)) { + return; + } + + fillPtSums(track, centrality); + fillGFW(track, centrality, vtxz); + + if (cfgFillQA) { + fillTrackQA(track, vtxz); + } + } + } + + o2::framework::expressions::Filter collisionFilter = nabs(aod::collision::posZ) < cfgEventSelection.cfgVtxZ; + o2::framework::expressions::Filter trackFilter = (aod::track::eta > cfgKinematics.cfgEta->first) && (aod::track::eta < cfgKinematics.cfgEta->second) && (aod::track::pt > cfgKinematics.cfgPtCut->first) && (aod::track::pt < cfgKinematics.cfgPtCut->second) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::itsChi2NCl < cfgTrackCuts.cfgChi2PrITSCls) && (aod::track::tpcChi2NCl < cfgTrackCuts.cfgChi2PrTPCCls) && nabs(aod::track::dcaZ) < cfgTrackCuts.cfgDCAz; + + using GFWCollisions = soa::Filtered>; + using GFWMCCollisions = soa::Join; + using GFWTracks = soa::Filtered>; + using GFWMCTracks = soa::Filtered>; + + SliceCache cache; + Partition posTracks = aod::track::signed1Pt > 0.0f; + Partition negTracks = aod::track::signed1Pt < 0.0f; + + double massKaPlus = o2::constants::physics::MassKPlus; + double massLambda = o2::constants::physics::MassLambda; + double massK0Short = o2::constants::physics::MassK0Short; + + void processData(GFWCollisions::iterator const& collision, aod::BCsWithTimestamps const&, GFWTracks const& tracks) + { + auto bc = collision.bc_as(); + int run = bc.runNumber(); + if (run != lastRun) { + lastRun = run; + LOGF(info, "run = %d", run); + if (cfgRunByRun) { + loadCorrections(bc); + } + } + if (!cfgRunByRun) { + loadCorrections(bc); + } + registry.fill(HIST("eventQA/eventSel"), 0.5); + if (!collision.sel8()) { + return; + } + registry.fill(HIST("eventQA/eventSel"), 1.5); + + float centrality = getCentrality(collision); + if (cfgEventSelection.cfgDoOccupancySel) { + int occupancy = collision.trackOccupancyInTimeRange(); + if (cfgFillQA) { + registry.fill(HIST("eventQA/before/occ_mult_cent"), occupancy, tracks.size(), centrality); + } + if (occupancy < 0 || occupancy > cfgEventSelection.cfgOccupancySelection) { + return; + } + if (cfgFillQA) { + registry.fill(HIST("eventQA/after/occ_mult_cent"), occupancy, tracks.size(), centrality); + } + } + registry.fill(HIST("eventQA/eventSel"), 2.5); + + if (cfgFillQA) { + fillEventQA(collision, tracks); + } + registry.fill(HIST("eventQA/before/centrality"), centrality); + registry.fill(HIST("eventQA/before/multiplicity"), tracks.size()); + if (!eventSelected(collision, tracks.size(), centrality)) { + return; + } + if (cfgFillQA) { + fillEventQA(collision, tracks); + } + registry.fill(HIST("eventQA/after/centrality"), centrality); + registry.fill(HIST("eventQA/after/multiplicity"), tracks.size()); + // Get magnetic field polarity + auto field = (cfgEventSelection.cfgMagField == DefaultMagneticFieldCut) ? getMagneticField(bc.timestamp()) : static_cast(cfgEventSelection.cfgMagField); + + processCollision(collision, tracks, centrality, field); + } + PROCESS_SWITCH(FlowGfwNonflow, processData, "Process analysis for non-derived data", true); + + void processMCReco(GFWCollisions::iterator const& collision, aod::BCsWithTimestamps const&, GFWMCTracks const& tracks, aod::McParticles const&) + { + auto bc = collision.bc_as(); + int run = bc.runNumber(); + if (run != lastRun) { + lastRun = run; + LOGF(info, "run = %d", run); + if (cfgRunByRun) { + loadCorrections(bc); + } + } + if (!cfgRunByRun) { + loadCorrections(bc); + } + + registry.fill(HIST("eventQA/eventSel"), 0.5); + + if (!collision.sel8()) { + return; + } + + registry.fill(HIST("eventQA/eventSel"), 1.5); + + const auto centrality = getCentrality(collision); + + if (cfgEventSelection.cfgDoOccupancySel) { + int occupancy = collision.trackOccupancyInTimeRange(); + registry.fill(HIST("eventQA/before/occ_mult_cent"), occupancy, tracks.size(), centrality); + if (occupancy < 0 || occupancy > cfgEventSelection.cfgOccupancySelection) { + return; + } + registry.fill(HIST("eventQA/after/occ_mult_cent"), occupancy, tracks.size(), centrality); + } + registry.fill(HIST("eventQA/eventSel"), 2.5); + + if (cfgFillQA) { + fillEventQA(collision, tracks); + } + if (!eventSelected(collision, tracks.size(), centrality)) { + return; + } + if (cfgFillQA) { + fillEventQA(collision, tracks); + } + loadCorrections(bc); + auto field = (cfgEventSelection.cfgMagField == DefaultMagneticFieldCut) ? getMagneticField(bc.timestamp()) : static_cast(cfgEventSelection.cfgMagField); + processCollision(collision, tracks, centrality, field); + } + PROCESS_SWITCH(FlowGfwNonflow, processMCReco, "Process analysis for MC reconstructed events", false); + + o2::framework::expressions::Filter mcCollFilter = nabs(aod::mccollision::posZ) < cfgEventSelection.cfgVtxZ; + void processMCGen(soa::Filtered::iterator const& mcCollision, soa::SmallGroups> const& collisions, aod::McParticles const& particles) + { + if (collisions.size() != 1) { + return; + } + float centrality = -1; + for (const auto& collision : collisions) { + centrality = getCentrality(collision); + } + processCollision(mcCollision, particles, centrality, -999); + } + PROCESS_SWITCH(FlowGfwNonflow, processMCGen, "Process analysis for MC generated events", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + }; +} diff --git a/PWGCF/JCorran/Tasks/jEPFlowAnalysis.cxx b/PWGCF/JCorran/Tasks/jEPFlowAnalysis.cxx index 37ca51b137e..19e6527b5b1 100644 --- a/PWGCF/JCorran/Tasks/jEPFlowAnalysis.cxx +++ b/PWGCF/JCorran/Tasks/jEPFlowAnalysis.cxx @@ -45,6 +45,7 @@ #include #include +#include #include #include @@ -72,6 +73,11 @@ using MyCollisionsMC = soa::Join; struct JEPFlowAnalysis { + enum Q2selMethod { + kNosel = 0, + kHsel, + kHistsel + }; Service pdg; @@ -134,14 +140,21 @@ struct JEPFlowAnalysis { Configurable cfgShiftPath{"cfgShiftPath", "Users/j/junlee/Qvector/QvecCalib/Shift", "Path for Shift"}; Configurable cfgVertexZ{"cfgVertexZ", 10.0, "Maximum vertex Z selection"}; - Configurable cfgq2analysis{"cfgq2analysis", false, "ese analysis flag"}; + Configurable cfgq2analysis{"cfgq2analysis", 0, "ese analysis selection mode"}; Configurable> cfgMultq2SelBin{"cfgMultq2SelBin", {0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 100}, ""}; Configurable> cfgMultq2high{"cfgMultq2high", {}, ""}; Configurable> cfgMultq2low{"cfgMultq2low", {}, ""}; + Configurable cfgQ2SelFrac{"cfgQ2SelFrac", 0.5, "ese analysis q2 selection with cfgq2analysis=2"}; Configurable cfgJetSubEvtSel{"cfgJetSubEvtSel", 0, "0: none, 1: Ratio, 2: relative ratio"}; Configurable> cfgJetSubEvlSelVar{"cfgJetSubEvlSelVar", {}, ""}; + Configurable cfgQselHistPath{"cfgQselHistPath", "", "CCDB path for q2 histogram"}; + Configurable cfgEventQAonly{"cfgEventQAonly", false, "event loop only"}; + + Configurable cfgSelEvtTwoHP{"cfgSelEvtTwoHP", false, "event selection with two high pT"}; + Configurable cfgHighPtSel{"cfgHighPtSel", 5.0, "pT threshold with cfgSelEvtTwoHP"}; + Configurable cfgDetName{"cfgDetName", "FT0C", "The name of detector to be analyzed"}; Configurable cfgRefAName{"cfgRefAName", "TPCPos", "The name of detector for reference A"}; Configurable cfgRefBName{"cfgRefBName", "TPCNeg", "The name of detector for reference B"}; @@ -164,29 +177,35 @@ struct JEPFlowAnalysis { Filter trackFilter = (aod::track::pt > cfgTrackCuts.cfgPtMin) && (nabs(aod::track::eta) < cfgTrackCuts.cfgEtaMax); - int detId; - int refAId; - int refBId; - int harmInd; + int detId = 0; + int refAId = 4; + int refBId = 5; + int harmInd = 0; int currentRunNumber = -999; int lastRunNumber = -999; - float cent; + float cent = -1.; float minQvecAmp = 1e-5; float minChg = 0.1; - float q2Mag; + float q2Mag = -1.; - float activity; - float qOvecM; - float highestPt; - float hPtPhi; + float activity = -1.; + float qOvecM = -1.; + float highestPt = -1.; + float hPtPhi = -999.; std::vector shiftprofile{}; std::string fullCCDBShiftCorrPath; THn* effMap = nullptr; + TH3F* q2Map = nullptr; + float q2selHigh = 100.; + float q2selLow = 0.; + + int nHighPt = 0; + int minnHighPt = 2; std::vector ft0RelGainConst{}; std::vector fv0RelGainConst{}; @@ -399,6 +418,25 @@ struct JEPFlowAnalysis { q2Mag = std::sqrt(std::pow(qx_shifted[0], 2) + std::pow(qy_shifted[0], 2)); + if (cfgq2analysis == kHistsel) { + q2selHigh = q2Map->GetBinContent(q2Map->GetXaxis()->FindBin(i + 2), q2Map->GetYaxis()->FindBin(cent), q2Map->GetZaxis()->FindBin(cfgQ2SelFrac)); + q2selLow = q2Map->GetBinContent(q2Map->GetXaxis()->FindBin(i + 2), q2Map->GetYaxis()->FindBin(cent), q2Map->GetZaxis()->FindBin(1. - cfgQ2SelFrac)); + } + + if (cfgSelEvtTwoHP && i == 0) { + nHighPt = 0; + for (const auto& track : tracks) { + if (cfgTrkSelFlag && trackSel(track)) + continue; + + if (track.pt() > cfgHighPtSel) + nHighPt++; + } + } + + if (cfgSelEvtTwoHP && nHighPt < minnHighPt) + continue; + epFlowHistograms.fill(HIST("EpDet"), i + 2, cent, eps[0]); epFlowHistograms.fill(HIST("EpRefA"), i + 2, cent, eps[1]); epFlowHistograms.fill(HIST("EpRefB"), i + 2, cent, eps[2]); @@ -416,7 +454,13 @@ struct JEPFlowAnalysis { epFlowHistograms.fill(HIST("EpResQvecRefARefBxx"), i + 2, cent, qx_shifted[1] * qx_shifted[2] + qy_shifted[1] * qy_shifted[2]); epFlowHistograms.fill(HIST("EpResQvecRefARefBxy"), i + 2, cent, qx_shifted[2] * qy_shifted[1] - qx_shifted[1] * qy_shifted[2]); - if (cfgq2analysis) { + if (cfgJetSubEvtSel) { + epFlowHistograms.fill(HIST("EpResQvecEvslDetRefAxx"), i + 2, cent, qx_shifted[0] * qx_shifted[1] + qy_shifted[0] * qy_shifted[1]); + epFlowHistograms.fill(HIST("EpResQvecEvslDetRefBxx"), i + 2, cent, qx_shifted[0] * qx_shifted[2] + qy_shifted[0] * qy_shifted[2]); + epFlowHistograms.fill(HIST("EpResQvecEvslRefARefBxx"), i + 2, cent, qx_shifted[1] * qx_shifted[2] + qy_shifted[1] * qy_shifted[2]); + } + + if (cfgq2analysis == kHsel) { if (q2sel(q2Mag, true)) { epFlowHistograms.fill(HIST("EpResQvecDetRefAxx_q2high"), i + 2, cent, qx_shifted[0] * qx_shifted[1] + qy_shifted[0] * qy_shifted[1]); epFlowHistograms.fill(HIST("EpResQvecDetRefBxx_q2high"), i + 2, cent, qx_shifted[0] * qx_shifted[2] + qy_shifted[0] * qy_shifted[2]); @@ -426,6 +470,20 @@ struct JEPFlowAnalysis { epFlowHistograms.fill(HIST("EpResQvecDetRefBxx_q2low"), i + 2, cent, qx_shifted[0] * qx_shifted[2] + qy_shifted[0] * qy_shifted[2]); epFlowHistograms.fill(HIST("EpResQvecRefARefBxx_q2low"), i + 2, cent, qx_shifted[1] * qx_shifted[2] + qy_shifted[1] * qy_shifted[2]); } + } else if (cfgq2analysis == kHistsel) { + if (q2Mag > q2selHigh) { + epFlowHistograms.fill(HIST("EpResQvecDetRefAxx_q2high"), i + 2, cent, qx_shifted[0] * qx_shifted[1] + qy_shifted[0] * qy_shifted[1]); + epFlowHistograms.fill(HIST("EpResQvecDetRefBxx_q2high"), i + 2, cent, qx_shifted[0] * qx_shifted[2] + qy_shifted[0] * qy_shifted[2]); + epFlowHistograms.fill(HIST("EpResQvecRefARefBxx_q2high"), i + 2, cent, qx_shifted[1] * qx_shifted[2] + qy_shifted[1] * qy_shifted[2]); + } else if (q2Mag < q2selLow) { + epFlowHistograms.fill(HIST("EpResQvecDetRefAxx_q2low"), i + 2, cent, qx_shifted[0] * qx_shifted[1] + qy_shifted[0] * qy_shifted[1]); + epFlowHistograms.fill(HIST("EpResQvecDetRefBxx_q2low"), i + 2, cent, qx_shifted[0] * qx_shifted[2] + qy_shifted[0] * qy_shifted[2]); + epFlowHistograms.fill(HIST("EpResQvecRefARefBxx_q2low"), i + 2, cent, qx_shifted[1] * qx_shifted[2] + qy_shifted[1] * qy_shifted[2]); + } + } + + if (cfgEventQAonly) { + continue; } highestPt = 0.0; @@ -452,12 +510,18 @@ struct JEPFlowAnalysis { epFlowHistograms.fill(HIST("SPvnxx"), i + 2, cent, track.pt(), track.eta(), (std::cos(track.phi() * static_cast(i + 2)) * qx_shifted[0] + std::sin(track.phi() * static_cast(i + 2)) * qy_shifted[0]), weight); epFlowHistograms.fill(HIST("SPvnxy"), i + 2, cent, track.pt(), track.eta(), (std::sin(track.phi() * static_cast(i + 2)) * qx_shifted[0] - std::cos(track.phi() * static_cast(i + 2)) * qy_shifted[0]), weight); - if (cfgq2analysis) { + if (cfgq2analysis == kHsel) { if (q2sel(q2Mag, true)) { epFlowHistograms.fill(HIST("SPvnxx_q2high"), i + 2, cent, track.pt(), track.eta(), (std::cos(track.phi() * static_cast(i + 2)) * qx_shifted[0] + std::sin(track.phi() * static_cast(i + 2)) * qy_shifted[0]), weight); } else if (q2sel(q2Mag, false)) { epFlowHistograms.fill(HIST("SPvnxx_q2low"), i + 2, cent, track.pt(), track.eta(), (std::cos(track.phi() * static_cast(i + 2)) * qx_shifted[0] + std::sin(track.phi() * static_cast(i + 2)) * qy_shifted[0]), weight); } + } else if (cfgq2analysis == kHistsel) { + if (q2Mag > q2selHigh) { + epFlowHistograms.fill(HIST("SPvnxx_q2high"), i + 2, cent, track.pt(), track.eta(), (std::cos(track.phi() * static_cast(i + 2)) * qx_shifted[0] + std::sin(track.phi() * static_cast(i + 2)) * qy_shifted[0]), weight); + } else if (q2Mag < q2selLow) { + epFlowHistograms.fill(HIST("SPvnxx_q2low"), i + 2, cent, track.pt(), track.eta(), (std::cos(track.phi() * static_cast(i + 2)) * qx_shifted[0] + std::sin(track.phi() * static_cast(i + 2)) * qy_shifted[0]), weight); + } } } if (i == 0) { // second harmonic only @@ -468,7 +532,7 @@ struct JEPFlowAnalysis { epFlowHistograms.fill(HIST("hQoverM2Q2"), cent, q2Mag, qOvecM); epFlowHistograms.fill(HIST("hQoverMdphi"), cent, RecoDecay::constrainAngle(hPtPhi - eps[0], -constants::math::PI), qOvecM); - epFlowHistograms.fill(HIST("hActivitydphi"), cent, RecoDecay::constrainAngle(hPtPhi - eps[0], -constants::math::PI), activity); + epFlowHistograms.fill(HIST("hActivitydphi"), cent, RecoDecay::constrainAngle(hPtPhi - eps[0], -constants::math::PI), highestPt, activity); } } } @@ -495,6 +559,7 @@ struct JEPFlowAnalysis { rctChecker.init(rctCut.cfgEvtRCTFlagCheckerLabel, rctCut.cfgEvtRCTFlagCheckerZDCCheck, rctCut.cfgEvtRCTFlagCheckerLimitAcceptAsBad); fv0geom = o2::fv0::Geometry::instance(o2::fv0::Geometry::eUninitialized); + ft0geom.calculateChannelCenter(); detId = getdetId(cfgDetName); refAId = getdetId(cfgRefAName); @@ -539,7 +604,7 @@ struct JEPFlowAnalysis { epFlowHistograms.add("hQoverM2Q2", "", {HistType::kTH3F, {axisCent, axisQ2, axisAmpR}}); epFlowHistograms.add("hActivity", "", {HistType::kTH3F, {axisCent, axisPt, axisActR}}); - epFlowHistograms.add("hActivitydphi", "", {HistType::kTH3F, {axisCent, axisEvtPl, axisActR}}); + epFlowHistograms.add("hActivitydphi", "", {HistType::kTHnSparseF, {axisCent, axisEvtPl, axisPt, axisActR}}); epFlowHistograms.add("vncos", "", {HistType::kTHnSparseF, {axisMod, axisCent, axisPt, axisCos}}); epFlowHistograms.add("vnsin", "", {HistType::kTHnSparseF, {axisMod, axisCent, axisPt, axisCos}}); @@ -550,6 +615,11 @@ struct JEPFlowAnalysis { epFlowHistograms.add("EpResQvecDetRefBxy", "", {HistType::kTH3F, {axisMod, axisCent, axisQvec}}); epFlowHistograms.add("EpResQvecRefARefBxx", "", {HistType::kTH3F, {axisMod, axisCent, axisQvec}}); epFlowHistograms.add("EpResQvecRefARefBxy", "", {HistType::kTH3F, {axisMod, axisCent, axisQvec}}); + + epFlowHistograms.add("EpResQvecEvslDetRefAxx", "", {HistType::kTH3F, {axisMod, axisCent, axisQvec}}); + epFlowHistograms.add("EpResQvecEvslDetRefBxx", "", {HistType::kTH3F, {axisMod, axisCent, axisQvec}}); + epFlowHistograms.add("EpResQvecEvslRefARefBxx", "", {HistType::kTH3F, {axisMod, axisCent, axisQvec}}); + if (cfgq2analysis) { epFlowHistograms.add("EpResQvecDetRefAxx_q2high", "", {HistType::kTH3F, {axisMod, axisCent, axisQvec}}); epFlowHistograms.add("EpResQvecDetRefBxx_q2high", "", {HistType::kTH3F, {axisMod, axisCent, axisQvec}}); @@ -630,6 +700,16 @@ struct JEPFlowAnalysis { } } + if (cfgq2analysis == kHistsel) { + auto bc = coll.bc_as(); + currentRunNumber = bc.runNumber(); + if (currentRunNumber != lastRunNumber) { + std::string fullPath; + fullPath = cfgQselHistPath; + q2Map = ccdb->getForTimeStamp(cfgQselHistPath, bc.timestamp()); + } + } + cent = coll.cent(); epFlowHistograms.fill(HIST("hCentrality"), cent); epFlowHistograms.fill(HIST("hVertex"), coll.posZ()); @@ -656,6 +736,9 @@ struct JEPFlowAnalysis { qOvecM = calcFT0CRawQVecMag(coll, 2) / coll.qvecAmp()[detId]; // second order activity = calcFT0CLocalActivity(coll); + epFlowHistograms.fill(HIST("hQoverMCnt"), cent, qOvecM); + epFlowHistograms.fill(HIST("hActivityCnt"), cent, activity); + if (cfgJetSubEvtSel & 1) { if (cfgJetSubEvlSelVar->at(0) < qOvecM) { return; @@ -666,7 +749,6 @@ struct JEPFlowAnalysis { return; } } - fillvn(coll, tracks); } PROCESS_SWITCH(JEPFlowAnalysis, processDefault, "default process", true); @@ -682,7 +764,7 @@ struct JEPFlowAnalysis { return; } - float cent = coll.centFT0C(); + cent = coll.centFT0C(); if (cfgEffCor) { auto bc = coll.bc_as(); @@ -723,7 +805,7 @@ struct JEPFlowAnalysis { } } - float cent = coll.centFT0C(); + cent = coll.centFT0C(); for (const auto& mcParticle : mcParticles) { if (std::abs(mcParticle.eta()) > cfgTrackCuts.cfgEtaMax) diff --git a/PWGCF/MultiparticleCorrelations/Tasks/multiharmonicCorrelations.cxx b/PWGCF/MultiparticleCorrelations/Tasks/multiharmonicCorrelations.cxx index 6c88ab6ab2c..6768b8dd5bc 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/multiharmonicCorrelations.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/multiharmonicCorrelations.cxx @@ -9,6 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include "Common/CCDB/EventSelectionParams.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -26,6 +27,7 @@ #include #include +#include #include #include #include @@ -38,6 +40,7 @@ #include +#include #include #include #include @@ -98,11 +101,12 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to Configurable cfDryRun{"cfDryRun", false, "book all histos and run without filling and calculating anything"}; // example for built-in type (float, string, etc.) Configurable> cfPtBins{"cfPtBins", {1000, 0., 8.}, "nPtBins, ptMin, ptMax"}; // example for an array Configurable> cfPhiBins{"cfPhiBins", {360, 0., o2::constants::math::TwoPI}, "nPhiBins, phiMin, phiMax"}; - Configurable> cfCentrBins{"cfCentrBins", {100, 0., 80.}, "nCentrBins, centrMin, centrMax"}; + Configurable> cfCentrBins{"cfCentrBins", {80, 0., 80.}, "nCentrBins, centrMin, centrMax"}; Configurable> cfXBins{"cfXBins", {1000, -0.04, -0.01}, "nXBins, xMin, xMax"}; Configurable> cfYBins{"cfYBins", {1000, -0.01, 0.006}, "nYBins, yMin, yMax"}; Configurable> cfZBins{"cfZBins", {1000, -20., 20.}, "nZBins, zMin, zMax"}; Configurable> cfMultBins{"cfMultBins", {50, 0, 2e4}, "nMultBins, multMin, multMax"}; + Configurable> cfMselBins{"cfMselBins", {50, 0, 1e3}, "nMselBins, mselMin, mselMax"}; Configurable> cfTPCnclsBins{"cfTPCnclsBins", {100, 0., 200.}, "ntpcnclsBins, tpnclsMin, tpcnclsMax"}; Configurable> cfDCAxyBins{"cfDCAxyBins", {1000, -0.5, 0.5}, "ndcaxyBins, dcaxyMin, dcaxyMax"}; Configurable> cfDCAzBins{"cfDCAzBins", {1000, -3., 3.}, "ndcazBins, dcazMin, dcazMax"}; @@ -111,13 +115,22 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to Configurable cfCent{"cfCent", "FT0C", "centrality estimator"}; Configurable cfMult{"cfMult", "TPC", "multiplicity"}; Configurable cfQA{"cfQA", true, "quality assurance"}; + Configurable cfInitsim{"cfInitsim", false, "init histograms of sim"}; + Configurable cfUseWeights{"cfUseWeights", true, "use weights"}; + Configurable cfToyModel{"cfToyModel", true, "phi-distribution from toy model"}; + Configurable cfNest{"cfNest", true, "nested loops"}; + Configurable cfTechcuts{"cfTechcuts", true, "technical cuts"}; Configurable> cfVertexZ{"cfVertexZ", {-10, 10.}, "vertex z position range: {min, max}[cm], with convention: min <= Vz < max"}; Configurable> cfPt{"cfPt", {0.2, 5.0}, "transverse momentum range"}; Configurable> cfEta{"cfEta", {-0.8, 0.8}, "eta range"}; + Configurable> cfDCAxy{"cfDCAxy", {-0.5, 0.5}, "dca xy range"}; + Configurable> cfDCAz{"cfDCAz", {-0.2, 0.2}, "dca z range"}; + Configurable cftpcNClsFoundmin{"cftpcNClsFoundmin", 70., "tpcNClsFoundmin"}; + Configurable cftpcChi2NClmax{"cftpcChi2NClmax", 4., "tpcChi2NClmax"}; Configurable> cfRuns{"cfRuns", {544091, 544095, 544098, 544116, 544121, 544122, 544123, 544124}, "List of run numbers to analyze"}; - Configurable cfFileWithWeights{"cfFileWithWeights", "/alice-ccdb.cern.ch/Users/p/pengchon/weightsfile01", "path to external ROOT file which holds all particle weights"}; + Configurable cfFileWithWeights{"cfFileWithWeights", "/alice-ccdb.cern.ch/Users/p/pengchon/weightsfile06", "path to external ROOT file which holds all particle weights"}; // *) Define and initialize all data members to be called in the main process* functions: // **) Task configuration: @@ -142,10 +155,11 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to TList* fEventHistogramsList = NULL; TH1F* fHistCentr[2] = {NULL}; TH1I* fHistMult[2] = {NULL}; + TH1F* fHistMsel[2] = {NULL}; TH1F* fHistX[2] = {NULL}; TH1F* fHistY[2] = {NULL}; TH1F* fHistZ[2] = {NULL}; - TH1I* fHistNContr = NULL; + TH1I* fHistNContr[2] = {NULL}; TH1F* fEventHistograms[eEventHistograms_N][2][2] = {{{NULL}}}; //! [ type - see enum eEventHistograms ][reco,sim][before, after event cuts] } event; @@ -156,6 +170,7 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to } qa; static constexpr int maxHarmonic = 7; + static constexpr int maxPower = 5; struct CorrelationVariables { TList* fCorrelationVariablesList = NULL; TProfile* pv22_centr = NULL; @@ -163,7 +178,13 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to TProfile* pv42_centr = NULL; TProfile* pfour32_centr = NULL; TProfile* pfour42_centr = NULL; - TComplex Qvector[maxHarmonic]; + TComplex Qvector[maxHarmonic][maxPower]; + std::vector vecphi; + std::vector vecwei; + TProfile* nestedLoops[maxHarmonic] = {NULL}; + TProfile* pv2_nest = NULL; + TProfile* pv3_nest = NULL; + TProfile* pv4_nest = NULL; } cor; struct PhiHist { @@ -171,6 +192,11 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to std::unordered_map histMap; } phih; + struct WeightsHist { + TList* fWeightsHistList = NULL; + std::unordered_map weightsmap; + } wh; + TObject* GetObjectFromList(TList* list, const char* objectName) { // Get TObject pointer from TList, even if it's in some nested TList. Foreseen @@ -231,15 +257,15 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to string pathstr = filePath; const string pathalien = "/alice/cern.ch/"; const string pathccdb = "/alice-ccdb.cern.ch/"; - if (pathstr.find(pathalien) == 0) { + if (pathstr.starts_with(pathalien)) { bFileIsInAliEn = true; - } else if (pathstr.find(pathccdb) == 0) { + } else if (pathstr.starts_with(pathccdb)) { bFileIsInCCDB = true; } LOGF(info, "bFileIsInCCDB= %d", bFileIsInCCDB); if (bFileIsInAliEn) { - TGrid* alien = TGrid::Connect("alien", gSystem->Getenv("USER"), "", ""); // do not forget to add #include to the preamble of your analysis task + const TGrid* alien = TGrid::Connect("alien", gSystem->Getenv("USER"), "", ""); // do not forget to add #include to the preamble of your analysis task if (!alien) { LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } @@ -345,8 +371,13 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to float vertexZmin = static_cast(vertexZ[0]); float vertexZmax = static_cast(vertexZ[1]); float posZ = collision.posZ(); - if (posZ < vertexZmin || posZ > vertexZmax || (!collision.sel8())) + float NContrcut = 2.; + if (posZ < vertexZmin || posZ > vertexZmax || (!collision.sel8()) || collision.numContrib() < NContrcut) return false; + if (cfTechcuts) { + if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard) || !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard) || !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC) || !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll) || !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV) || !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) + return false; + } return true; } @@ -361,28 +392,51 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to float etacutmin = static_cast(Eta[0]); float etacutmax = static_cast(Eta[1]); float eta = track.eta(); - if (pt < ptcutmin || pt > ptcutmax || eta < etacutmin || eta > etacutmax) + vector dcaXY = cfDCAxy.value; + float dcaxycutmin = static_cast(dcaXY[0]); + float dcaxycutmax = static_cast(dcaXY[1]); + float dcaxy = track.dcaXY(); + vector dcaZ = cfDCAz.value; + float dcazcutmin = static_cast(dcaZ[0]); + float dcazcutmax = static_cast(dcaZ[1]); + float dcaz = track.dcaZ(); + if (pt < ptcutmin || pt > ptcutmax || eta < etacutmin || eta > etacutmax || dcaxy < dcaxycutmin || dcaxy > dcaxycutmax || dcaz < dcazcutmin || dcaz > dcazcutmax || (!track.isPrimaryTrack()) || (!track.isPVContributor()) || track.tpcNClsFound() < cftpcNClsFoundmin.value || track.tpcChi2NCl() > cftpcChi2NClmax) return false; return true; } - TComplex Q(Int_t n) + TComplex Q(int n, int p) { // Using the fact that Q{-n,p} = Q{n,p}^*. if (n >= 0) { - return cor.Qvector[n]; + return cor.Qvector[n][p]; } - return TComplex::Conjugate(cor.Qvector[-n]); + return TComplex::Conjugate(cor.Qvector[-n][p]); } + TComplex Two(Int_t n1, Int_t n2) + { + // Generic two-particle correlation . + TComplex two = Q(n1, 1) * Q(n2, 1) - Q(n1 + n2, 2); + return two; + + } // TComplex Two(Int_t n1, Int_t n2) TComplex Four(Int_t n1, Int_t n2, Int_t n3, Int_t n4) { // Generic four-particle correlation . - TComplex four = Q(n1) * Q(n2) * Q(n3) * Q(n4) - Q(n1 + n2) * Q(n3) * Q(n4) - Q(n2) * Q(n1 + n3) * Q(n4) - Q(n1) * Q(n2 + n3) * Q(n4) + 2. * Q(n1 + n2 + n3) * Q(n4) - Q(n2) * Q(n3) * Q(n1 + n4) + Q(n2 + n3) * Q(n1 + n4) - Q(n1) * Q(n3) * Q(n2 + n4) + Q(n1 + n3) * Q(n2 + n4) + 2. * Q(n3) * Q(n1 + n2 + n4) - Q(n1) * Q(n2) * Q(n3 + n4) + Q(n1 + n2) * Q(n3 + n4) + 2. * Q(n2) * Q(n1 + n3 + n4) + 2. * Q(n1) * Q(n2 + n3 + n4) - 6. * Q(n1 + n2 + n3 + n4); - + TComplex four = Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n4, 1) - Q(n1 + n2, 2) * Q(n3, 1) * Q(n4, 1) - Q(n2, 1) * Q(n1 + n3, 2) * Q(n4, 1) - Q(n1, 1) * Q(n2 + n3, 2) * Q(n4, 1) + 2. * Q(n1 + n2 + n3, 3) * Q(n4, 1) - Q(n2, 1) * Q(n3, 1) * Q(n1 + n4, 2) + Q(n2 + n3, 2) * Q(n1 + n4, 2) - Q(n1, 1) * Q(n3, 1) * Q(n2 + n4, 2) + Q(n1 + n3, 2) * Q(n2 + n4, 2) + 2. * Q(n3, 1) * Q(n1 + n2 + n4, 3) - Q(n1, 1) * Q(n2, 1) * Q(n3 + n4, 2) + Q(n1 + n2, 2) * Q(n3 + n4, 2) + 2. * Q(n2, 1) * Q(n1 + n3 + n4, 3) + 2. * Q(n1, 1) * Q(n2 + n3 + n4, 3) - 6. * Q(n1 + n2 + n3 + n4, 4); return four; - } // TComplex Four(Int_t n1, Int_t n2, Int_t n3, Int_t n4) + static double pdf(const double* x, const double* par) + { + double y = 1; + int harm = 6; + for (int i = 0; i < harm; i = i + 1) { + y = y + 2 * (0.04 + (i + 1.) * 0.01) * TMath::Cos((i + 1) * (x[0] - par[0])); + } + return y; + } + template void Steer(T1 const& collision, T2 const& tracks) { @@ -391,27 +445,30 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to return; } // Print current run number: - // LOGF(info, "Run number: %d", collision.bc().runNumber()); int currentRun = collision.bc().runNumber(); auto it = phih.histMap.find(currentRun); - float zrec = 0., zsim = 0., centr = 0, M = 0.; + auto histweight = wh.weightsmap.find(currentRun); + float centr = 0, M = 0., msel = 0.; + // TF1* f = new TF1("f", pdf, 0, TMath::TwoPi(), 1); + TF1* f = new TF1("f", + "1 +" + "2 * (0.05) * cos(1 * (x - [0])) +" + "2 * (0.06) * cos(2 * (x - [0])) +" + "2 * (0.07) * cos(3 * (x - [0])) +" + "2 * (0.08) * cos(4 * (x - [0])) +" + "2 * (0.09) * cos(5 * (x - [0])) +" + "2 * (0.10) * cos(6 * (x - [0]))", + 0, TMath::TwoPi()); + f->SetParameters(0.); if constexpr (rs == eRec || rs == eRecAndSim) { - event.fHistX[eRec]->Fill(collision.posX()); - event.fHistY[eRec]->Fill(collision.posY()); - event.fHistZ[eRec]->Fill(collision.posZ()); - event.fEventHistograms[eVertexZ][eRec][0]->Fill(collision.posZ()); - zrec = collision.posZ(); - event.fHistNContr->Fill(collision.numContrib()); if (cfCent.value == "FT0C") centr = collision.centFT0C(); else if (cfCent.value == "FT0M") centr = collision.centFT0M(); else if (cfCent.value == "FT0A") centr = collision.centFT0A(); - event.fHistCentr[eRec]->Fill(centr); - std::string multType = "TPC"; if (cfMult.value == "TPC") M = collision.multTPC(); else if (cfMult.value == "FV0M") @@ -422,7 +479,30 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to M = collision.multFT0M(); else if (cfMult.value == "NTracksPV") M = collision.multNTracksPV(); - event.fHistMult[eRec]->Fill(M); + + event.fHistX[eBefore]->Fill(collision.posX()); + event.fHistY[eBefore]->Fill(collision.posY()); + event.fHistZ[eBefore]->Fill(collision.posZ()); + event.fHistCentr[eBefore]->Fill(centr); + event.fHistMult[eBefore]->Fill(M); + event.fHistNContr[eBefore]->Fill(collision.numContrib()); + + event.fEventHistograms[eVertexZ][eRec][0]->Fill(collision.posZ()); + + // *) Event cuts: + float centrcut = 80.; + if (!EventCuts(collision) || centr > centrcut) { // Main call for event cuts + return; + } + + event.fHistX[eAfter]->Fill(collision.posX()); + event.fHistY[eAfter]->Fill(collision.posY()); + event.fHistZ[eAfter]->Fill(collision.posZ()); + event.fHistCentr[eAfter]->Fill(centr); + event.fHistMult[eAfter]->Fill(M); + event.fHistNContr[eAfter]->Fill(collision.numContrib()); + + event.fEventHistograms[eVertexZ][eRec][1]->Fill(collision.posZ()); qa.fQAM_NC->Fill(M, collision.numContrib()); if constexpr (rs == eRecAndSim) { @@ -432,28 +512,32 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to event.fHistX[eSim]->Fill(mccollision.posX()); event.fHistY[eSim]->Fill(mccollision.posY()); event.fHistZ[eSim]->Fill(mccollision.posZ()); - event.fEventHistograms[eVertexZ][eSim][0]->Fill(mccollision.posZ()); - zsim = mccollision.posZ(); + event.fEventHistograms[eVertexZ][eSim][1]->Fill(mccollision.posZ()); event.fHistCentr[eSim]->Fill(centrsim); qa.fQA->Fill(centrsim, centr); centr = centrsim; } + } - // *) Event cuts: - float centrcut = 80.; - if (!EventCuts(collision) || centr > centrcut) { // Main call for event cuts - return; + // before loop over particles + float phi = 0, weight = 1.; + vector().swap(cor.vecphi); + vector().swap(cor.vecwei); + for (int ih = 0; ih < maxHarmonic; ih++) { + for (int ip = 0; ip < maxPower; ip++) { + cor.Qvector[ih][ip] = TComplex(0., 0.); } - event.fEventHistograms[eVertexZ][eRec][1]->Fill(zrec); - if constexpr (rs == eRecAndSim) - event.fEventHistograms[eVertexZ][eSim][1]->Fill(zsim); } - // before loop over particles - float phi = 0, weight = 0; + /* for (int ih = 0; ih < maxHarmonic; ih++) { - cor.Qvector[ih] = TComplex(0., 0.); + for (int ip = 0; ip < maxPower; ip++) { + LOGF(info, "Qvector[%d][%d]=%f, ", ih, ip, cor.Qvector[ih][ip].Rho2()); + } + LOGF(info, "\n"); } + LOGF(info, "\n\n"); + */ // Main loop over particles: for (const auto& track : tracks) { @@ -462,20 +546,50 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to float ptrec = 0., ptsim = 0.; if constexpr (rs == eRec || rs == eRecAndSim) { // Fill track pt distribution: - pc.fHistPt[eRec]->Fill(track.pt()); + + pc.fHistPt[eBefore]->Fill(track.pt()); + pc.fHistPhi[eBefore]->Fill(track.phi()); + pc.fHistCharge[eBefore]->Fill(track.sign()); + pc.fHistTPCncls[eBefore]->Fill(track.tpcNClsFindable()); + pc.fHistTracksdcaXY[eBefore]->Fill(track.dcaXY()); + pc.fHistTracksdcaZ[eBefore]->Fill(track.dcaZ()); + event.fEventHistograms[ePt][eRec][0]->Fill(track.pt()); ptrec = track.pt(); + + // *) Particle cuts: + if (!ParticleCuts(track)) { // Main call for particle cuts. + continue; // not return!! + } + pc.fHistPt[eAfter]->Fill(track.pt()); + pc.fHistPhi[eAfter]->Fill(track.phi()); + pc.fHistCharge[eAfter]->Fill(track.sign()); + pc.fHistTPCncls[eAfter]->Fill(track.tpcNClsFindable()); + pc.fHistTracksdcaXY[eAfter]->Fill(track.dcaXY()); + pc.fHistTracksdcaZ[eAfter]->Fill(track.dcaZ()); + + event.fEventHistograms[ePt][eRec][1]->Fill(ptrec); + phi = track.phi(); + if (cfToyModel) { + phi = f->GetRandom(); + } + cor.vecphi.push_back(phi); if (it != phih.histMap.end()) { it->second->Fill(phi); } - pc.fHistPhi[eRec]->Fill(track.phi()); - pc.fHistCharge[eRec]->Fill(track.sign()); - pc.fHistTPCncls[eRec]->Fill(track.tpcNClsFindable()); - pc.fHistTracksdcaXY[eRec]->Fill(track.dcaXY()); - pc.fHistTracksdcaZ[eRec]->Fill(track.dcaZ()); - weight = 1.; // pc.histWeights->GetBinContent(phi); + if (cfUseWeights) { + if (histweight != wh.weightsmap.end() && histweight->second) { + weight = histweight->second->GetBinContent(histweight->second->FindBin(phi)); + } else { + LOG(warning) << "No weights found for run " << currentRun << ", using weight=1"; + weight = 1; + } + } else { + weight = 1; + } + cor.vecwei.push_back(weight); // ... and corresponding MC truth simulated: // See https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx @@ -489,42 +603,76 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to pc.fHistPt[eSim]->Fill(mcparticle.pt()); event.fEventHistograms[ePt][eSim][0]->Fill(mcparticle.pt()); ptsim = mcparticle.pt(); + event.fEventHistograms[ePt][eSim][0]->Fill(ptsim); phi = mcparticle.phi(); pc.fHistPhi[eSim]->Fill(mcparticle.phi()); - // pc.fHistCharge[eSim]->Fill(mcparticle.sign()); - // pc.fHistTPCncls[eSim]->Fill(mcparticle.tpcNClsFindable()); - // pc.fHistTracksdcaXY[eSim]->Fill(mcparticle.dcaXY()); - // pc.fHistTracksdcaZ[eSim]->Fill(mcparticle.dcaZ()); } // end of if constexpr (rs == eRecAndSim) - // *) Particle cuts: - if (!ParticleCuts(track)) { // Main call for particle cuts. - continue; // not return!! - } - event.fEventHistograms[ePt][eRec][1]->Fill(ptrec); - if constexpr (rs == eRecAndSim) - event.fEventHistograms[ePt][eSim][0]->Fill(ptsim); - } // if constexpr (rs == eRec || rs == eRecAndSim) // analysis in the loop over particle + msel = msel + 1; for (int ih = 0; ih < maxHarmonic; ih++) { - cor.Qvector[ih] += TComplex(weight * TMath::Cos(ih * phi), weight * TMath::Sin(ih * phi)); + for (int ip = 0; ip < maxPower; ip++) { + cor.Qvector[ih][ip] += TComplex(std::pow(weight, ip) * TMath::Cos(ih * phi), std::pow(weight, ip) * TMath::Sin(ih * phi)); + } } } // end of for (auto track: tracks) + event.fHistMsel[eAfter]->Fill(msel); + + if (cfNest) { + float phi1 = 0., phi2 = 0., weight1 = 1., weight2 = 2.; + for (Int_t c = 0; c < maxHarmonic; c++) { + delete cor.nestedLoops[c]; + cor.nestedLoops[c] = new TProfile("", "", 1, 0., 1.); + cor.nestedLoops[c]->Sumw2(); + } + for (int i1 = 0; i1 < static_cast(cor.vecphi.size()); i1++) { // nested loop of particles + phi1 = cor.vecphi[i1]; + weight1 = cor.vecwei[i1]; + for (int i2 = 0; i2 < static_cast(cor.vecphi.size()); i2++) { + if (i2 == i1) { + continue; + } + phi2 = cor.vecphi[i2]; + weight2 = cor.vecwei[i2]; + cor.nestedLoops[0]->Fill(0.5, TMath::Cos(2 * phi1 - 2 * phi2), weight1 * weight2); + cor.nestedLoops[1]->Fill(0.5, TMath::Cos(3 * phi1 - 3 * phi2), weight1 * weight2); + cor.nestedLoops[2]->Fill(0.5, TMath::Cos(4 * phi1 - 4 * phi2), weight1 * weight2); + } + } // end of two nested loop + } + // calculate correlations - float four32 = Four(3, 2, -3, -2).Re() / Four(0, 0, 0, 0).Re(); - float four42 = Four(4, 2, -4, -2).Re() / Four(0, 0, 0, 0).Re(); - float v22 = (Q(2).Rho2() - M) / (M * (M - 1.)); - float v32 = (Q(3).Rho2() - M) / (M * (M - 1.)); - float v42 = (Q(4).Rho2() - M) / (M * (M - 1.)); - - cor.pv22_centr->Fill(centr, v22, M * (M - 1)); - cor.pv32_centr->Fill(centr, v32, M * (M - 1)); - cor.pv42_centr->Fill(centr, v42, M * (M - 1)); - cor.pfour32_centr->Fill(centr, four32, M * (M - 1)); - cor.pfour42_centr->Fill(centr, four42, M * (M - 1)); + float Mmin = 4.; + if (msel < Mmin) + return; + float wTwo = Two(0, 0).Re(); + float wFour = Four(0, 0, 0, 0).Re(); + float four32 = Four(3, 2, -3, -2).Re() / wFour; + float four42 = Four(4, 2, -4, -2).Re() / wFour; + float v22 = Two(2, -2).Re() / wTwo; + float v32 = Two(3, -3).Re() / wTwo; + float v42 = Two(4, -4).Re() / wTwo; + if (std::isnan(v22) || std::isnan(v32) || std::isnan(v42) || std::isnan(four32) || std::isnan(four42)) { + LOGF(info, "\033[1;31m%s std::isnan(v22) || std::isnan(v32) || std::isnan(v42) || std::isnan(four32) || std::isnan(four42)\033[0m", __FUNCTION__); + LOGF(error, "v22 = %f\nv32 = %f\nv42 = %f\nfour32=%f\nv42 = %f\n", v22, v32, v42, four32, four42); + return; + } + + cor.pv22_centr->Fill(centr, v22, wTwo); + cor.pv32_centr->Fill(centr, v32, wTwo); + cor.pv42_centr->Fill(centr, v42, wTwo); + cor.pfour32_centr->Fill(centr, four32, wFour); + cor.pfour42_centr->Fill(centr, four42, wFour); + if (cfNest) { + cor.pv2_nest->Fill(centr, cor.nestedLoops[0]->GetBinContent(1), wTwo); + cor.pv3_nest->Fill(centr, cor.nestedLoops[1]->GetBinContent(1), wTwo); + cor.pv4_nest->Fill(centr, cor.nestedLoops[2]->GetBinContent(1), wTwo); + + LOGF(info, "v22=%f, v22_nest=%f", v22, cor.nestedLoops[0]->GetBinContent(1)); + } } // end of template void Steer(T1 const& collision, T2 const& tracks) // *) Initialize and book all objects: @@ -571,6 +719,11 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to phih.fPhiHistList->SetOwner(true); fBaseList->Add(phih.fPhiHistList); + wh.fWeightsHistList = new TList(); + wh.fWeightsHistList->SetName("WeightsHistograms"); + wh.fWeightsHistList->SetOwner(true); + fBaseList->Add(wh.fWeightsHistList); + // *) Book pt distribution with binning defined through configurables in the json file: vector l_pt_bins = cfPtBins.value; // define local array and initialize it from an array set in the configurables vector l_phi_bins = cfPhiBins.value; @@ -579,6 +732,7 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to vector l_y_bins = cfYBins.value; vector l_z_bins = cfZBins.value; vector l_mult_bins = cfMultBins.value; + vector l_msel_bins = cfMselBins.value; vector l_tpcncls_bins = cfTPCnclsBins.value; vector l_dcaxy_bins = cfDCAxyBins.value; vector l_dcaz_bins = cfDCAzBins.value; @@ -591,6 +745,7 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to int nBinsy = static_cast(l_y_bins[0]); int nBinsz = static_cast(l_z_bins[0]); int nBinsmult = static_cast(l_mult_bins[0]); + int nBinsmsel = static_cast(l_msel_bins[0]); int nBinscharge = 2; int nBinstpcncls = static_cast(l_tpcncls_bins[0]); int nBinsdcaxy = static_cast(l_dcaxy_bins[0]); @@ -611,6 +766,8 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to float maxz = l_z_bins[2]; float minmult = l_mult_bins[1]; float maxmult = l_mult_bins[2]; + float minmsel = l_msel_bins[1]; + float maxmsel = l_msel_bins[2]; float mincharge = -2.; float maxcharge = 2.; float mintpcncls = l_tpcncls_bins[1]; @@ -619,84 +776,8 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to float maxdcaxy = l_dcaxy_bins[2]; float mindcaz = l_dcaz_bins[1]; float maxdcaz = l_dcaz_bins[2]; - float maxncontr = l_ncontr_bins[1]; - float minncontr = l_ncontr_bins[2]; - - pc.fHistPt[eRec] = new TH1F("fHistPt[eRec]", "pt distribution for reconstructed particles", nBins, min, max); - pc.fHistPhi[eRec] = new TH1F("fHistPhi[eRec]", "phi distribution for reconstructed particles", nBinsphi, minphi, maxphi); - pc.fHistCharge[eRec] = new TH1F("fHistCharge[eRec]", "charge distribution for reconstructed particles", nBinscharge, mincharge, maxcharge); - pc.fHistTPCncls[eRec] = new TH1F("fHistTPCncls[eRec]", "tpcncls distribution for reconstructed particles", nBinstpcncls, mintpcncls, maxtpcncls); - pc.fHistTracksdcaXY[eRec] = new TH1F("fHistTracksdcaXY[eRec]", "dcaxy distribution for reconstructed particles", nBinsdcaxy, mindcaxy, maxdcaxy); - pc.fHistTracksdcaZ[eRec] = new TH1F("fHistTracksdcaZ[eRec]", "dcaz distribution for reconstructed particles", nBinsdcaz, mindcaz, maxdcaz); - pc.fHistPt[eRec]->GetXaxis()->SetTitle("p_{T}"); - pc.fHistPhi[eRec]->GetXaxis()->SetTitle("phi"); - pc.fHistCharge[eRec]->GetXaxis()->SetTitle("charge"); - pc.fHistTPCncls[eRec]->GetXaxis()->SetTitle("TPCNClsFindable"); - pc.fHistTracksdcaXY[eRec]->GetXaxis()->SetTitle("DCA XY"); - pc.fHistTracksdcaZ[eRec]->GetXaxis()->SetTitle("DCA Z"); - pc.fParticleHistogramsList->Add(pc.fHistPt[eRec]); - pc.fParticleHistogramsList->Add(pc.fHistPhi[eRec]); - pc.fParticleHistogramsList->Add(pc.fHistCharge[eRec]); - pc.fParticleHistogramsList->Add(pc.fHistTPCncls[eRec]); - pc.fParticleHistogramsList->Add(pc.fHistTracksdcaXY[eRec]); - pc.fParticleHistogramsList->Add(pc.fHistTracksdcaZ[eRec]); - - pc.fHistPt[eSim] = new TH1F("fHistPt[eSim]", "pt distribution for simulated particles", nBins, min, max); - pc.fHistPhi[eSim] = new TH1F("fHistPhi[eSim]", "phi distribution for simulated particles", nBinsphi, minphi, maxphi); - pc.fHistCharge[eSim] = new TH1F("fHistCharge[eSim]", "charge distribution for simulated particles", nBinscharge, mincharge, maxcharge); - pc.fHistTPCncls[eSim] = new TH1F("fHistTPCncls[eSim]", "tpcncls distribution for simulated particles", nBinstpcncls, minphi, maxtpcncls); - pc.fHistTracksdcaXY[eSim] = new TH1F("fHistTracksdcaXY[eSim]", "dcaxy distribution for simulated particles", nBinsdcaxy, mindcaxy, maxdcaxy); - pc.fHistTracksdcaZ[eSim] = new TH1F("fHistTracksdcaZ[eSim]", "dcaz distribution for simulated particles", nBinsdcaz, mindcaz, maxdcaz); - pc.fHistPt[eSim]->GetXaxis()->SetTitle("p_{T}"); - pc.fHistPhi[eSim]->GetXaxis()->SetTitle("phi"); - pc.fHistCharge[eSim]->GetXaxis()->SetTitle("charge"); - pc.fHistTPCncls[eSim]->GetXaxis()->SetTitle("TPCNClsFindable"); - pc.fHistTracksdcaXY[eSim]->GetXaxis()->SetTitle("DCA XY"); - pc.fHistTracksdcaZ[eSim]->GetXaxis()->SetTitle("DCA Z"); - pc.fParticleHistogramsList->Add(pc.fHistPt[eSim]); - pc.fParticleHistogramsList->Add(pc.fHistPhi[eSim]); - pc.fParticleHistogramsList->Add(pc.fHistCharge[eSim]); - pc.fParticleHistogramsList->Add(pc.fHistTPCncls[eSim]); - pc.fParticleHistogramsList->Add(pc.fHistTracksdcaXY[eSim]); - pc.fParticleHistogramsList->Add(pc.fHistTracksdcaZ[eSim]); - - pc.histWeights = GetHistogramWithWeights(cfFileWithWeights.value.c_str(), "000123456"); - pc.fParticleHistogramsList->Add(pc.histWeights); - - event.fHistCentr[eRec] = new TH1F("fHistCentr[eRec]", "centrality distribution for reconstructed particles", nBinscentr, mincentr, maxcentr); - event.fHistX[eRec] = new TH1F("fHistX[eRec]", "posX distribution for reconstructed particles", nBinsx, minx, maxx); - event.fHistY[eRec] = new TH1F("fHistY[eRec]", "posY distribution for reconstructed particles", nBinsy, miny, maxy); - event.fHistZ[eRec] = new TH1F("fHistZ[eRec]", "posZ distribution for reconstructed particles", nBinsz, minz, maxz); - event.fHistMult[eRec] = new TH1I("fHistMult[eRec]", "mult distribution for reconstructed particles", nBinsmult, minmult, maxmult); - event.fHistNContr = new TH1I("fHistNContr", "NContr distribution", nBinsncontr, minncontr, maxncontr); - event.fHistCentr[eRec]->GetXaxis()->SetTitle("centrality"); - event.fHistX[eRec]->GetXaxis()->SetTitle("x"); - event.fHistY[eRec]->GetXaxis()->SetTitle("y"); - event.fHistZ[eRec]->GetXaxis()->SetTitle("z"); - event.fHistMult[eRec]->GetXaxis()->SetTitle("multiplicity"); - event.fHistNContr->GetXaxis()->SetTitle("numContrib"); - event.fEventHistogramsList->Add(event.fHistCentr[eRec]); - event.fEventHistogramsList->Add(event.fHistX[eRec]); - event.fEventHistogramsList->Add(event.fHistY[eRec]); - event.fEventHistogramsList->Add(event.fHistZ[eRec]); - event.fEventHistogramsList->Add(event.fHistMult[eRec]); - event.fEventHistogramsList->Add(event.fHistNContr); - - event.fHistCentr[eSim] = new TH1F("fHistCentr[eSim]", "centrality distribution for simulated particles", nBinscentr, mincentr, maxcentr); - event.fHistX[eSim] = new TH1F("fHistX[eSim]", "posX distribution for simulated particles", nBinsx, minx, maxx); - event.fHistY[eSim] = new TH1F("fHistY[eSim]", "posY distribution for simulated particles", nBinsy, miny, maxy); - event.fHistZ[eSim] = new TH1F("fHistZ[eSim]", "posZ distribution for simulated particles", nBinsz, minz, maxz); - event.fHistMult[eSim] = new TH1I("fHistMult[eSim]", "mult distribution for simulated particles", nBinsmult, minmult, maxmult); - event.fHistCentr[eSim]->GetXaxis()->SetTitle("centrality"); - event.fHistX[eSim]->GetXaxis()->SetTitle("x"); - event.fHistY[eSim]->GetXaxis()->SetTitle("y"); - event.fHistZ[eSim]->GetXaxis()->SetTitle("z"); - event.fHistMult[eSim]->GetXaxis()->SetTitle("multiplicity"); - event.fEventHistogramsList->Add(event.fHistCentr[eSim]); - event.fEventHistogramsList->Add(event.fHistX[eSim]); - event.fEventHistogramsList->Add(event.fHistY[eSim]); - event.fEventHistogramsList->Add(event.fHistZ[eSim]); - event.fEventHistogramsList->Add(event.fHistMult[eSim]); + float minncontr = l_ncontr_bins[1]; + float maxncontr = l_ncontr_bins[2]; const char* cevent[] = {"vertexZ", "Pt"}; const char* cpro[] = {"rec", "sim"}; @@ -711,15 +792,111 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to if (i == 1) event.fEventHistograms[i][j][k] = new TH1F(histname, histtitle, nBins, min, max); event.fEventHistograms[i][j][k]->GetXaxis()->SetTitle(Form("%s", cevent[i])); - event.fEventHistogramsList->Add(event.fEventHistograms[i][j][k]); + // event.fEventHistogramsList->Add(event.fEventHistograms[i][j][k]); } } } + for (int icut = 0; icut < eCut_N; icut++) { + pc.fHistPt[icut] = new TH1F(Form("fHistPt[%s]", ccut[icut]), Form("pt distribution %s cut for reconstructed particles", ccut[icut]), nBins, min, max); + pc.fHistPhi[icut] = new TH1F(Form("fHistPhi[%s]", ccut[icut]), Form("phi distribution %s cut for reconstructed particles", ccut[icut]), nBinsphi, minphi, maxphi); + pc.fHistCharge[icut] = new TH1F(Form("fHistCharge[%s]", ccut[icut]), Form("charge distribution %s cut for reconstructed particles", ccut[icut]), nBinscharge, mincharge, maxcharge); + pc.fHistTPCncls[icut] = new TH1F(Form("fHistTPCncls[%s]", ccut[icut]), Form("tpcncls distribution %s cut for reconstructed particles", ccut[icut]), nBinstpcncls, mintpcncls, maxtpcncls); + pc.fHistTracksdcaXY[icut] = new TH1F(Form("fHistTracksdcaXY[%s]", ccut[icut]), Form("dcaxy distribution %s cut for reconstructed particles", ccut[icut]), nBinsdcaxy, mindcaxy, maxdcaxy); + pc.fHistTracksdcaZ[icut] = new TH1F(Form("fHistTracksdcaZ[%s]", ccut[icut]), Form("dcaz distribution %s cut for reconstructed particles", ccut[icut]), nBinsdcaz, mindcaz, maxdcaz); + pc.fHistPt[icut]->GetXaxis()->SetTitle("p_{T}"); + pc.fHistPhi[icut]->GetXaxis()->SetTitle("phi"); + pc.fHistCharge[icut]->GetXaxis()->SetTitle("charge"); + pc.fHistTPCncls[icut]->GetXaxis()->SetTitle("TPCNClsFindable"); + pc.fHistTracksdcaXY[icut]->GetXaxis()->SetTitle("DCA XY"); + pc.fHistTracksdcaZ[icut]->GetXaxis()->SetTitle("DCA Z"); + pc.fParticleHistogramsList->Add(pc.fHistPt[icut]); + pc.fParticleHistogramsList->Add(pc.fHistPhi[icut]); + pc.fParticleHistogramsList->Add(pc.fHistCharge[icut]); + pc.fParticleHistogramsList->Add(pc.fHistTPCncls[icut]); + pc.fParticleHistogramsList->Add(pc.fHistTracksdcaXY[icut]); + pc.fParticleHistogramsList->Add(pc.fHistTracksdcaZ[icut]); + + // init eventhist + event.fHistCentr[icut] = new TH1F(Form("fHistCentr[%s]", ccut[icut]), Form("centrality distribution %s cut for reconstructed particles", ccut[icut]), nBinscentr, mincentr, maxcentr); + event.fHistX[icut] = new TH1F(Form("fHistX[%s]", ccut[icut]), Form("posX distribution %s cut for reconstructed particles", ccut[icut]), nBinsx, minx, maxx); + event.fHistY[icut] = new TH1F(Form("fHistY[%s]", ccut[icut]), Form("posY distribution %s cut for reconstructed particles", ccut[icut]), nBinsy, miny, maxy); + event.fHistZ[icut] = new TH1F(Form("fHistZ[%s]", ccut[icut]), Form("posZ distribution %s cut for reconstructed particles", ccut[icut]), nBinsz, minz, maxz); + event.fHistMult[icut] = new TH1I(Form("fHistMult[%s]", ccut[icut]), Form("mult distribution %s cut for reconstructed particles", ccut[icut]), nBinsmult, minmult, maxmult); + event.fHistMsel[icut] = new TH1F(Form("fHistMsel[%s]", ccut[icut]), Form("selected tracks %s cut", ccut[icut]), nBinsmsel, minmsel, maxmsel); + event.fHistNContr[icut] = new TH1I(Form("fHistNContr[%s]", ccut[icut]), Form("NContr distribution %s cut", ccut[icut]), nBinsncontr, minncontr, maxncontr); + event.fHistCentr[icut]->GetXaxis()->SetTitle(Form("centrality, %s", cfCent.value.c_str())); + event.fHistX[icut]->GetXaxis()->SetTitle("x"); + event.fHistY[icut]->GetXaxis()->SetTitle("y"); + event.fHistZ[icut]->GetXaxis()->SetTitle("z"); + event.fHistMult[icut]->GetXaxis()->SetTitle(Form("multiplicity, %s", cfMult.value.c_str())); + event.fHistMsel[icut]->GetXaxis()->SetTitle("selected tracks"); + event.fHistNContr[icut]->GetXaxis()->SetTitle("numContrib"); + event.fEventHistogramsList->Add(event.fHistCentr[icut]); + event.fEventHistogramsList->Add(event.fHistX[icut]); + event.fEventHistogramsList->Add(event.fHistY[icut]); + event.fEventHistogramsList->Add(event.fHistZ[icut]); + event.fEventHistogramsList->Add(event.fHistMult[icut]); + event.fEventHistogramsList->Add(event.fHistMsel[icut]); + event.fEventHistogramsList->Add(event.fHistNContr[icut]); + } + + // init of sim histograms + if (cfInitsim) { + pc.fHistPt[eSim] = new TH1F("fHistPt[eSim]", "pt distribution for simulated particles", nBins, min, max); + pc.fHistPhi[eSim] = new TH1F("fHistPhi[eSim]", "phi distribution for simulated particles", nBinsphi, minphi, maxphi); + pc.fHistCharge[eSim] = new TH1F("fHistCharge[eSim]", "charge distribution for simulated particles", nBinscharge, mincharge, maxcharge); + pc.fHistTPCncls[eSim] = new TH1F("fHistTPCncls[eSim]", "tpcncls distribution for simulated particles", nBinstpcncls, minphi, maxtpcncls); + pc.fHistTracksdcaXY[eSim] = new TH1F("fHistTracksdcaXY[eSim]", "dcaxy distribution for simulated particles", nBinsdcaxy, mindcaxy, maxdcaxy); + pc.fHistTracksdcaZ[eSim] = new TH1F("fHistTracksdcaZ[eSim]", "dcaz distribution for simulated particles", nBinsdcaz, mindcaz, maxdcaz); + pc.fHistPt[eSim]->GetXaxis()->SetTitle("p_{T}"); + pc.fHistPhi[eSim]->GetXaxis()->SetTitle("phi"); + pc.fHistCharge[eSim]->GetXaxis()->SetTitle("charge"); + pc.fHistTPCncls[eSim]->GetXaxis()->SetTitle("TPCNClsFindable"); + pc.fHistTracksdcaXY[eSim]->GetXaxis()->SetTitle("DCA XY"); + pc.fHistTracksdcaZ[eSim]->GetXaxis()->SetTitle("DCA Z"); + pc.fParticleHistogramsList->Add(pc.fHistPt[eSim]); + pc.fParticleHistogramsList->Add(pc.fHistPhi[eSim]); + pc.fParticleHistogramsList->Add(pc.fHistCharge[eSim]); + pc.fParticleHistogramsList->Add(pc.fHistTPCncls[eSim]); + pc.fParticleHistogramsList->Add(pc.fHistTracksdcaXY[eSim]); + pc.fParticleHistogramsList->Add(pc.fHistTracksdcaZ[eSim]); + + event.fHistCentr[eSim] = new TH1F("fHistCentr[eSim]", "centrality distribution for simulated particles", nBinscentr, mincentr, maxcentr); + event.fHistX[eSim] = new TH1F("fHistX[eSim]", "posX distribution for simulated particles", nBinsx, minx, maxx); + event.fHistY[eSim] = new TH1F("fHistY[eSim]", "posY distribution for simulated particles", nBinsy, miny, maxy); + event.fHistZ[eSim] = new TH1F("fHistZ[eSim]", "posZ distribution for simulated particles", nBinsz, minz, maxz); + event.fHistMult[eSim] = new TH1I("fHistMult[eSim]", "mult distribution for simulated particles", nBinsmult, minmult, maxmult); + event.fHistCentr[eSim]->GetXaxis()->SetTitle("centrality"); + event.fHistX[eSim]->GetXaxis()->SetTitle("x"); + event.fHistY[eSim]->GetXaxis()->SetTitle("y"); + event.fHistZ[eSim]->GetXaxis()->SetTitle("z"); + event.fHistMult[eSim]->GetXaxis()->SetTitle("multiplicity"); + event.fEventHistogramsList->Add(event.fHistCentr[eSim]); + event.fEventHistogramsList->Add(event.fHistX[eSim]); + event.fEventHistogramsList->Add(event.fHistY[eSim]); + event.fEventHistogramsList->Add(event.fHistZ[eSim]); + event.fEventHistogramsList->Add(event.fHistMult[eSim]); + } + + // loading weights + for (const int& run : targetRuns) { + std::string runStr = std::to_string(run); + TH1F* histweights = GetHistogramWithWeights(cfFileWithWeights.value.c_str(), runStr.c_str()); + if (!histweights) { + LOG(fatal) << "Failed to load weights for run " << run; + return; + } + histweights->SetName(Form("histWithEfficiencyCorrections_%d", run)); + wh.fWeightsHistList->Add(histweights); + wh.weightsmap[run] = histweights; + } + qa.fQA = new TH2F("QA_centr", "quality assurance of centrality", nBinscentr, mincentr, maxcentr, nBinscentr, mincentr, maxcentr); qa.fQAM_NC = new TH2F("QAM_NC", "quality assurance of mult vs. NContributors", nBinsmult, minmult, maxmult, nBinsncontr, minncontr, maxncontr); if (cfQA) { - qa.fQAList->Add(qa.fQA); + if (cfInitsim) + qa.fQAList->Add(qa.fQA); qa.fQAList->Add(qa.fQAM_NC); } @@ -730,6 +907,9 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to cor.pv42_centr = new TProfile("pv42", "profile of v_{4}^{2}", 9, quantiles); cor.pfour32_centr = new TProfile("pfour32", "profile of v_{2}^{2}*v_{3}^{2}", 9, quantiles); cor.pfour42_centr = new TProfile("pfour42", "profile of v_{2}^{2}*v_{4}^{2}", 9, quantiles); + cor.pv2_nest = new TProfile("pv2_nest", "profile of v_{2} from nest", 9, quantiles); + cor.pv3_nest = new TProfile("pv3_nest", "profile of v_{3} from nest", 9, quantiles); + cor.pv4_nest = new TProfile("pv4_nest", "profile of v_{4} from nest", 9, quantiles); cor.pv22_centr->GetYaxis()->SetTitle("v_{2}^{2}"); cor.pv32_centr->GetYaxis()->SetTitle("v_{3}^{2}"); cor.pv42_centr->GetYaxis()->SetTitle("v_{4}^{2}"); @@ -740,11 +920,22 @@ struct MultiharmonicCorrelations { // this name is used in lower-case format to cor.pfour42_centr->GetYaxis()->SetTitle("v_{2}^{2}v_{4}^{2}"); cor.pfour32_centr->GetXaxis()->SetTitle("centrality"); cor.pfour42_centr->GetXaxis()->SetTitle("centrality"); + cor.pv2_nest->GetYaxis()->SetTitle("v_{2}"); + cor.pv3_nest->GetYaxis()->SetTitle("v_{3}"); + cor.pv4_nest->GetYaxis()->SetTitle("v_{4}"); + cor.pv2_nest->GetXaxis()->SetTitle("centrality"); + cor.pv3_nest->GetXaxis()->SetTitle("centrality"); + cor.pv4_nest->GetXaxis()->SetTitle("centrality"); cor.fCorrelationVariablesList->Add(cor.pv22_centr); cor.fCorrelationVariablesList->Add(cor.pv32_centr); cor.fCorrelationVariablesList->Add(cor.pv42_centr); cor.fCorrelationVariablesList->Add(cor.pfour32_centr); cor.fCorrelationVariablesList->Add(cor.pfour42_centr); + if (cfNest) { + cor.fCorrelationVariablesList->Add(cor.pv2_nest); + cor.fCorrelationVariablesList->Add(cor.pv3_nest); + cor.fCorrelationVariablesList->Add(cor.pv4_nest); + } // init of phi hist for different runs for (const int& run : targetRuns) { diff --git a/PWGCF/MultiparticleCorrelations/Tasks/multiparticleCumulants.cxx b/PWGCF/MultiparticleCorrelations/Tasks/multiparticleCumulants.cxx index 0b5ceafdd47..fba1ce3cf58 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/multiparticleCumulants.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/multiparticleCumulants.cxx @@ -16,7 +16,7 @@ #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/TrackSelectionTables.h" // needed for aod::TracksDCA table +#include "Common/DataModel/TrackSelectionTables.h" #include #include @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -37,13 +38,16 @@ #include #include #include +#include #include #include #include +#include #include #include +#include #include #include @@ -51,8 +55,8 @@ using namespace o2; using namespace o2::framework; // Definitions of join tables for Run 3 analysis: -using EventSelection = soa::Join; -using CollisionRec = soa::Join::iterator; // use in json "isMC": "true" for "event-selection-task" +using EventSelection = soa::Join; +using CollisionRec = soa::Join::iterator; using CollisionRecSim = soa::Join::iterator; using CollisionSim = aod::McCollision; using TracksRec = soa::Join; @@ -65,12 +69,16 @@ using TrackSim = aod::McParticles::iterator; using namespace std; // *) Define enums: -enum EnRlMc { eRl = 0, - eMc }; +enum EnRlMc { + eRl = 0, + eMc +}; -enum EnRecSim { eRec = 0, - eSim, - eRecAndSim }; +enum EnRecSim { + eRec = 0, + eSim, + eRecAndSim +}; enum EnProcess { eProcessRec = 0, // Run 3, only reconstructed @@ -89,7 +97,7 @@ enum EnEventHistograms { eEventHistograms_N }; -const char* eventHistNames[eEventHistograms_N] = { +static constexpr std::array EventHistNames = { "Centrality", "Multiplicity", "VertexX", @@ -103,7 +111,7 @@ enum EnParticleHistograms { eParticleHistograms_N }; -const char* particleHistNames[eParticleHistograms_N] = { +static constexpr std::array ParticleHistNames = { "Pt", "Phi"}; @@ -113,23 +121,67 @@ enum EnQAHistograms { eQAHistograms_N }; +enum EnCorrHistograms { + eCorrCent, + eCorrMult, + eCorrHistograms_N +}; + +static constexpr std::array CorrHistNames = { + "Centrality", + "Multiplicity", +}; + +enum EnCentEstm { + eCentFT0C, + eCentFT0M, + eCentFV0A, + eCentEstm_N +}; + +static constexpr std::array CentEstmNames = { + "FT0C", + "FT0M", + "FV0A"}; + +enum EnMultEstm { + eMultFT0C, + eMultFT0M, + eMultFV0A, + eMultEstm_N +}; + +static constexpr std::array MultEstmNames = { + "FT0C", + "FT0M", + "FV0A"}; + +enum EnCutBeforeAfter { + eBefore, + eAfter, + eCutBeforeAfter_N +}; + +static constexpr std::array CutBeforeAfterNames = { + "before", + "after", +}; + // *) Main task: struct MultiparticleCumulants { // this name is used in lower-case format to name the TDirectoryFile in AnalysisResults.root // *) Base TList to hold all output objects: TString sBaseListName = "Default list name"; // yes, I declare it separately, because I need it also later in BailOut() function - OutputObj fBaseList{sBaseListName.Data(), - OutputObjHandlingPolicy::AnalysisObject, - OutputObjSourceType::OutputObjSource}; + OutputObj fBaseList{sBaseListName.Data(), OutputObjHandlingPolicy::AnalysisObject, OutputObjSourceType::OutputObjSource}; // *) Service: - Service ccdb; // support for offline callibration data base - Service pdg; + Service ccdb{}; // support for offline callibration data base + Service pdg{}; // *) Define configurables: - Configurable cfDryRun{"cfDryRun", false, "book all histos and run without filling and calculating anything"}; // example for built-in type (float, string, etc.) - Configurable cfCentEstm{"cfCentEstm", "FT0M", "centrality estimator: FT0M, FV0A, NTPV, FT0C"}; - Configurable cfMultEstm{"cfMultEstm", "FT0A", "multiplicity estimator: FT0A, FT0C, FT0M, FV0A, FV0C, NTracksPV"}; + Configurable cfDryRun{"cfDryRun", false, "book all histos and run without filling and calculating anything"}; + Configurable cfCentEstm{"cfCentEstm", "FT0M", "centrality estimator: TBD"}; + Configurable cfMultEstm{"cfMultEstm", "FV0A", "multiplicity estimator: TBD"}; Configurable cfQASwitch{"cfQASwitch", true, "quality assurance switch"}; Configurable cfWeightSwitch{"cfWeightSwitch", true, "weight switch"}; @@ -140,6 +192,8 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam Configurable cfSel8CutSwitch{"cfSel8CutSwitch", true, "Sel8 cut switch"}; Configurable cfCentCutSwitch{"cfCentCutSwitch", true, "centrality cut switch"}; Configurable cfNumContribCutSwitch{"cfNumContribCutSwitch", true, "NContribution cut switch"}; + Configurable cfCentCorrCutSwitch{"cfCentCorrCutSwitch", true, "centrality correlation cut switch"}; + Configurable cfMultCorrCutSwitch{"cfMultCorrCutSwitch", true, "multiplicity correlation cut switch"}; // *) Particle cut switches Configurable cfPtCutSwitch{"cfPtCutSwitch", true, "Pt cut switch"}; @@ -153,6 +207,8 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam Configurable> cfVertexZCut{"cfVertexZCut", {-10., 10.}, "vertex z position range: {min, max}[cm]"}; Configurable> cfCentCut{"cfCentCut", {10., 20.}, "centrality range: {min, max}[%]"}; Configurable> cfNumContribCut{"cfNumContribCut", {0, 3000.}, "NContribution range: {min, max}"}; + Configurable cfCentCorrCut{"cfCentCorrCut", 5, "centrality difference maximum"}; + Configurable cfMultCorrCut{"cfMultCorrCut", 0.2, "multiplicity difference maximum"}; // *) Particle cut Configurable> cfPtCut{"cfPtCut", {0.2, 5.0}, "Pt range: {min, max}[GeV], with convention: min <= Pt < max"}; @@ -162,9 +218,8 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam Configurable> cfDCAXYCut{"cfDCAXYCut", {-3.2, 3.2}, "range of distance-of-closest-approach (DCA) of the extrapolated track to the primary position in XY-direction: {min, max}[cm]"}; Configurable> cfDCAZCut{"cfDCAZCut", {-2.4, 2.4}, "range of distance-of-closest-approach (DCA) of the extrapolated track to the primary position in Z-direction: {min, max}[cm]"}; - // *) + // *) Others Configurable cfFileWithWeights{"cfFileWithWeights", "/scratch3/go52dab/O2tutorial/tutorial3-6/weights.root", "path to external ROOT file which holds all particle weights in O2 format"}; - Configurable cfRunNumber{"cfRunNumber", "000123456", "run number"}; // *) Bins Configurable> cfPtBins{"cfPtBins", {1000, 0., 100.}, "nPtBins, ptMin, ptMax"}; @@ -179,10 +234,11 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam // *) Define and initialize all data members to be called in the main process* functions: // **) Task configuration: struct TaskConfiguration { - bool fProcess[eProcess_N] = {kFALSE}; // Set what to process. See enum EnProcess for full description. Set via implicit variables within a PROCESS_SWITCH clause. - bool fDryRun = kFALSE; // book all histos and run without filling and calculating anything + std::array fProcess = {{false}}; // Set what to process. See enum EnProcess for full description. Set via implicit variables within a PROCESS_SWITCH clause. + bool fDryRun = false; + std::string fCentEstm = "FT0M"; - std::string fMultEstm = "FT0A"; + std::string fMultEstm = "FV0A"; bool fPrintSwitch = true; @@ -190,6 +246,8 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam bool fSel8CutSwitch = true; bool fCentCutSwitch = true; bool fNumContribCutSwitch = true; + bool fCentCorrCutSwitch = true; + bool fMultCorrCutSwitch = true; bool fPtCutSwitch = true; bool fEtaCutSwitch = true; @@ -201,6 +259,8 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam std::vector fVertexZCut = {-10., 10.}; std::vector fCentCut = {10., 20.}; std::vector fNumContribCut = {0, 3000.}; + float fCentCorrCut = 5; + float fMultCorrCut = 0.2; std::vector fPtCut = {0.2, 5.0}; std::vector fEtaCut = {-0.8, 0.8}; @@ -219,44 +279,85 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam std::vector fVerZBins = {-50., 50.}; std::vector fNumContribBins = {0, 5000}; - std::string fFileWithWeights = "/scratch3/go52dab/O2tutorial/tutorial3-6/weights.root"; - std::string fRunNumber = "000123456"; - } tc; // you have to prepend "tc." for all objects name in this group later in the code + std::string fFileWithWeights = "/scratch3/go52dab/O2tutorial/analysis_code/weights.root"; + + } tc; - // **) Particle histograms: struct ParticleHistograms { - TList* fParticleHistogramsList = NULL; //!, 2>, eParticleHistograms_N> fParticleHistograms{}; + } pc; - // **) Event histograms: struct EventHistograms { - TList* fEventHistogramsList = NULL; //!, 2>, eEventHistograms_N> fEventHistograms{}; } ev; struct QAHistograms { bool fQASwitch = kTRUE; - TList* fQAHistogramsList = NULL; - TH2F* fQAHistograms[eQAHistograms_N][2] = {{NULL}}; //[type][before/after cut] + TList* fQAHistogramsList = nullptr; + std::array, eQAHistograms_N> fQAHistograms{}; // [type][before/after cut] } qa; + struct CorrHistograms { + TList* fCorrHistogramsList = nullptr; + std::array, eMultEstm_N>, eMultEstm_N>, eCorrHistograms_N> fCorrHistograms{}; + } cr; + struct WeightHistograms { bool fWeightSwitch = kTRUE; - TList* fWeightHistogramsList = NULL; - std::vector fWeightHistograms; + TList* fWeightHistogramsList = nullptr; + // Fill phi/pt histograms with that run number: + std::map fPtRealByRunMap; // MC rec (too lazy to change name) data pt histograms, valid if processMonteCarlo + std::map fPtMCByRunMap; // MC sim (too lazy to change name) data pt histograms, valid if processMonteCarlo + std::map fPhiByRunMap; // Phi histograms, valid if processRealData + // Make weight histograms locally. Upload weight histograms to CCDB: + std::vector fWeightHistograms; // Get all weight histograms with that run number + std::map fPhiWeightHistogramsMap; // Get phi weight histograms + std::map fPtWeightHistogramsMap; // Get pt weight histograms + // Null weight histograms. Use them when no weight histograms found in the given run number: + TH1F* fDummyPhiWeightHistogram = nullptr; + TH1F* fDummyPtWeightHistogram = nullptr; } wt; struct EventByEventQuantities { + int fRunNumber = 0; float fReferenceMultiplicity = 0.; float fCentrality = 0.; float fCentralitySim = 0.; float fImpactParameter = 0.; float fNumContrib = 0.; + std::array, eCutBeforeAfter_N> fTwoParticleCorrelationEbye = {{{0., 0., 0.}, {0., 0., 0.}}}; //<2> [before, after][v2^2, v3^2, v4^2] + std::array, eCutBeforeAfter_N> fFourParticleCorrelationEbye = {{{0., 0.}, {0., 0.}}}; //<4> [before, after][v3^2 v2^2, v4^2 v2^2] } ebye; - template - bool ctEventCuts(T1 const& collision) + struct MultiparticleCorrelationProfile { + TList* fMultiparticleCorrelationProfilesList = nullptr; + std::map fMultiparticleCorrelationByRunMap; + std::array fTwoParticleCorrelationProfiles = {{nullptr}}; + std::array fFourParticleCorrelationProfiles = {{nullptr}}; + } mc; + + struct MultiparticleCorrelationCalculation { + int h1 = 0; + int h2 = 0; + int h3 = 0; + int h4 = 0; + int h5 = 0; + int h6 = 0; + int h7 = 0; + int h8 = 0; + // Book Q-vector components: + static constexpr int MaxCorrelator = 4; // <> + static constexpr int MaxHarmonic = 5; // n+1 in vn, in this case n=4 as we need v2, v3, v4 + static constexpr int MaxPower = MaxCorrelator + 1; + static constexpr int NumSC = 2; // need SC(3,2) and SC(4,2) + std::array, MaxHarmonic> fQvectorBefore; + std::array, MaxHarmonic> fQvectorAfter; // All needed Q-vector components + } mcc; + + template + bool ctEventCuts(T1 const& collision, T2 const& rlCollisionCentAll, T3 const& rlCollisionMultAll) { bool pass = true; @@ -264,33 +365,70 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam bool bSel8Cut = true; bool bCentCut = true; bool bNumContribCut = true; + bool bCentCorrCut = true; + bool bMultCorrCut = true; // *) For real event and MC event - bVertexZCut = collision.posZ() < tc.fVertexZCut[1] && collision.posZ() > tc.fVertexZCut[0]; + bVertexZCut = collision.posZ() < tc.fVertexZCut[1] && + collision.posZ() > tc.fVertexZCut[0]; // *) For real event only if constexpr (rm == eRl) { + // *) Sel8Cut bSel8Cut = collision.sel8(); - bCentCut = ebye.fCentrality < tc.fCentCut[1] && ebye.fCentrality > tc.fCentCut[0]; - bNumContribCut = ebye.fNumContrib < tc.fNumContribCut[1] && ebye.fNumContrib > tc.fNumContribCut[0]; + // *) CentCut + bCentCut = ebye.fCentrality < tc.fCentCut[1] && + ebye.fCentrality > tc.fCentCut[0]; + // *) NumContribCut + bNumContribCut = ebye.fNumContrib < tc.fNumContribCut[1] && + ebye.fNumContrib > tc.fNumContribCut[0]; + // *) CentCorrCut + float iCent = 0.; + float jCent = 0.; + for (int i = 0; i < eCentEstm_N; i++) { + iCent = rlCollisionCentAll[i]; + for (int j = i + 1; j < eCentEstm_N; j++) { + jCent = rlCollisionCentAll[j]; + bCentCorrCut = std::abs((iCent - jCent)) < tc.fCentCorrCut; + } + } + // *) MultCorrCut + float iMult = 0.; + float jMult = 0.; + for (int i = 0; i < eMultEstm_N; i++) { + iMult = rlCollisionMultAll[i]; + for (int j = i + 1; j < eMultEstm_N; j++) { + jMult = rlCollisionMultAll[j]; + bMultCorrCut = std::abs((iMult - jMult) / iMult) < tc.fMultCorrCut; + } + } } // *) For MC event only if constexpr (rm == eMc) { - bCentCut = ebye.fCentralitySim < tc.fCentCut[1] && ebye.fCentralitySim > tc.fCentCut[0]; + // *) CentCut + bCentCut = ebye.fCentralitySim < tc.fCentCut[1] && + ebye.fCentralitySim > tc.fCentCut[0]; } + // *) Combine all switches if (tc.fVertexZCutSwitch) { - pass = pass && bVertexZCut; + pass &= bVertexZCut; } if (tc.fSel8CutSwitch) { - pass = pass && bSel8Cut; + pass &= bSel8Cut; } if (tc.fCentCutSwitch) { - pass = pass && bCentCut; + pass &= bCentCut; } if (tc.fNumContribCutSwitch) { - pass = pass && bNumContribCut; + pass &= bNumContribCut; + } + if (tc.fCentCorrCutSwitch) { + pass &= bCentCorrCut; + } + if (tc.fMultCorrCutSwitch) { + pass &= bMultCorrCut; } return pass; @@ -314,58 +452,122 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam // *) For real event only if constexpr (rm == eRl) { - bSignCut = (track.sign() == -1 && tc.fSignCut[0]) || (track.sign() == 0 && tc.fSignCut[1]) || (track.sign() == 1 && tc.fSignCut[2]); - bTpcNClsFoundCut = track.tpcNClsFound() < tc.fTpcNClsFoundCut[1] && track.tpcNClsFound() > tc.fTpcNClsFoundCut[0]; - bDCAXYCut = track.dcaXY() < tc.fDCAXYCut[1] && track.dcaXY() > tc.fDCAXYCut[0]; - bDCAZCut = track.dcaZ() < tc.fDCAZCut[1] && track.dcaZ() > tc.fDCAZCut[0]; + bSignCut = (track.sign() == -1 && tc.fSignCut[0]) || + (track.sign() == 0 && tc.fSignCut[1]) || + (track.sign() == 1 && tc.fSignCut[2]); + bTpcNClsFoundCut = track.tpcNClsFound() < tc.fTpcNClsFoundCut[1] && + track.tpcNClsFound() > tc.fTpcNClsFoundCut[0]; + bDCAXYCut = track.dcaXY() < tc.fDCAXYCut[1] && + track.dcaXY() > tc.fDCAXYCut[0]; + bDCAZCut = track.dcaZ() < tc.fDCAZCut[1] && + track.dcaZ() > tc.fDCAZCut[0]; } // *) For mc event only if constexpr (rm == eMc) { - // TDatabasePDG *db= TDatabasePDG::Instance(); TParticlePDG* particle = pdg->GetParticle(track.pdgCode()); - if (!particle) { // LOGF(warning, "PDG code %d not found", track.pdgCode()); bSignCut = false; } else { // LOGF(info, "PDG code %d found", track.pdgCode()); float charge = particle->Charge(); - bSignCut = (charge < 0 && tc.fSignCut[0]) || (charge == 0 && tc.fSignCut[1]) || (charge > 0 && tc.fSignCut[2]); + bSignCut = (charge < 0 && tc.fSignCut[0]) || + (charge == 0 && tc.fSignCut[1]) || + (charge > 0 && tc.fSignCut[2]); } } if (tc.fPtCutSwitch) { - pass = pass && bPtCut; + pass &= bPtCut; } if (tc.fEtaCutSwitch) { - pass = pass && bEtaCut; + pass &= bEtaCut; } if (tc.fSignCutSwitch) { - pass = pass && bSignCut; + pass &= bSignCut; } if (tc.fTpcNClsFoundCutSwitch) { - pass = pass && bTpcNClsFoundCut; + pass &= bTpcNClsFoundCut; } if (tc.fDCAXYCutSwitch) { - pass = pass && bDCAXYCut; + pass &= bDCAXYCut; } if (tc.fDCAZCutSwitch) { - pass = pass && bDCAZCut; + pass &= bDCAZCut; } return pass; } + TComplex mccQ(int n, int p, EnCutBeforeAfter eba) + { + // Using the fact that Q{-n,p} = Q{n,p}^*. + + if (eba == eBefore) { + if (n >= 0) { + return mcc.fQvectorBefore[n][p]; + } + return TComplex::Conjugate(mcc.fQvectorBefore[-n][p]); + } + if (n >= 0) { + return mcc.fQvectorAfter[n][p]; + } + return TComplex::Conjugate(mcc.fQvectorAfter[-n][p]); + } + + template + TComplex mccRecursion(int n, std::array harmonic, EnCutBeforeAfter eba, int mult = 1, int skip = 0) + { + // Calculate multi-particle correlators by using recursion (an improved faster version) originally developed by Kristjan Gulbrandsen (gulbrand@nbi.dk). + + int nm1 = n - 1; + TComplex c(mccQ(harmonic[nm1], mult, eba)); + if (nm1 == 0) { + return c; + } + c *= mccRecursion(nm1, harmonic, eba); + if (nm1 == skip) { + return c; + } + + int multp1 = mult + 1; + int nm2 = n - 2; + int counter1 = 0; + int hhold = harmonic[counter1]; + harmonic[counter1] = harmonic[nm2]; + harmonic[nm2] = hhold + harmonic[nm1]; + TComplex c2(mccRecursion(nm1, harmonic, eba, multp1, nm2)); + int counter2 = n - 3; + while (counter2 >= skip) { + harmonic[nm2] = harmonic[counter1]; + harmonic[counter1] = hhold; + ++counter1; + hhold = harmonic[counter1]; + harmonic[counter1] = harmonic[nm2]; + harmonic[nm2] = hhold + harmonic[nm1]; + c2 += mccRecursion(nm1, harmonic, eba, multp1, counter2); + --counter2; + } + harmonic[nm2] = harmonic[counter1]; + harmonic[counter1] = hhold; + + if (mult == 1) { + return c - c2; + } + return c - static_cast(mult) * c2; + } + TObject* getObjectFromList(TList* list, const char* objectName) { - // Get TObject pointer from TList, even if it's in some nested TList. Foreseen - // to be used to fetch histograms or profiles from files directly. + // Get TObject pointer from TList, even if it's in some nested TList. + // Foreseen to be used to fetch histograms or profiles from files directly. // Some ideas taken from TCollection::ls() - // If you have added histograms directly to files (without TList's), then you can fetch them directly with - // file->Get("hist-name"). + // If you have added histograms directly to files (without TList's), then + // you can fetch them directly with file->Get("hist-name"). - // Usage: TH1D *hist = (TH1D*) getObjectFromList("some-valid-TList-pointer","some-object-name"); + // Usage: TH1D* hist = (TH1D*) + // getObjectFromList("some-valid-TList-pointer","some-object-name"); // Insanity checks: if (!list) { @@ -375,7 +577,7 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } if (0 == list->GetEntries()) { - return NULL; + return nullptr; } // The object is in the current base list: @@ -385,32 +587,34 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam } // Otherwise, search for the object recursively in the nested lists: - TObject* objectIter; // iterator object in the loop below + TObject* objectIter = nullptr; // iterator object in the loop below TIter next(list); while ((objectIter = next())) // double round braces are to silence the warnings { if (TString(objectIter->ClassName()).EqualTo("TList")) { - objectFinal = getObjectFromList(reinterpret_cast(objectIter), objectName); - if (objectFinal) + objectFinal = getObjectFromList(dynamic_cast(objectIter), objectName); + if (objectFinal) { return objectFinal; + } } } // while(objectIter = next()) - return NULL; + return nullptr; - } // TObject* getObjectFromList(TList *list, char *objectName) + } // TObject* getObjectFromList(TList* list, char* objectName) std::vector getHistogramsWithWeights(const char* filePath, const char* runNumber) { // a) Return value: std::vector histograms; - TList* baseList = NULL; // base top-level list in the TFile, e.g. named "ccdb_object" - TList* listWithRuns = NULL; // nested list with run-wise TList's holding run-specific weights + TList* baseList = nullptr; // base top-level list in the TFile, e.g. named "ccdb_object" + TList* listWithRuns = nullptr; // nested list with run-wise TList's holding run-specific weights // c) Determine from filePath if the file in on a local machine, or in home dir AliEn, or in CCDB: - // Algorithm: If filePath begins with "/alice/data/CCDB/" then it's in home dir AliEn. - // If filePath begins with "/alice-ccdb.cern.ch/" then it's in CCDB. Therefore, files in AliEn and CCDB must be specified with abs path, - // for local files both abs and relative paths are just fine. + // Algorithm: + // If filePath begins with "/alice/data/CCDB/" then it's in home dir AliEn. + // If filePath begins with "/alice-ccdb.cern.ch/" then it's in CCDB. + // Therefore, files in AliEn and CCDB must be specified with abs path, for local files both abs and relative paths are just fine. bool bFileIsInAliEn = false; bool bFileIsInCCDB = false; @@ -424,7 +628,7 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam if (bFileIsInAliEn) { // File you want to access is in your home dir in AliEn: - TGrid* alien = TGrid::Connect("alien", gSystem->Getenv("USER"), "", ""); // do not forget to add #include to the preamble of your analysis task + const TGrid* alien = TGrid::Connect("alien", gSystem->Getenv("USER"), "", ""); // do not forget to add #include to the preamble of your analysis task if (!alien) { LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } @@ -434,49 +638,53 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam } weightsFile->GetObject("ccdb_object", baseList); if (!baseList) { - weightsFile->ls(); LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } // Finally, from the top-level TList, get the desired nested TList => the technical problem here is that it can be nested at any level, - // for thare there is a helper utility function getObjectFromList(...) , see its implementation further below - listWithRuns = reinterpret_cast(getObjectFromList(baseList, runNumber)); + // for thare there is a helper utility function GetObjectFromList(...) , see its implementation further below + listWithRuns = dynamic_cast(getObjectFromList(baseList, runNumber)); if (!listWithRuns) { TString runNumberWithLeadingZeroes = "000"; runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number - listWithRuns = reinterpret_cast(getObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + listWithRuns = dynamic_cast(getObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); if (!listWithRuns) { - LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + LOGF(warning, "\033[1;31m%s at line %d : this crash can happen if in the output file there is no list with weights for the current runnumber = %s\033[0m", __FUNCTION__, __LINE__, runNumber); + histograms = {nullptr}; + return histograms; } } } else if (bFileIsInCCDB) { // File you want to access is in your home dir in CCDB: // Remember that here I do not access the file; instead, I directly access the object in that file. - // My home dir in CCDB: https://alice-ccdb.cern.ch/browse/Users/a/abilandz/ => adapt for your case + // My home dir in CCDB: https://alice-ccdb.cern.ch/browse/Users/a/abilandz/ => adapt for your case ccdb->setURL("https://alice-ccdb.cern.ch"); // to be able to use "ccdb" this object in your analysis task, see 4b/ below - baseList = reinterpret_cast(ccdb->get(TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data())); - baseList->ls(); + baseList = dynamic_cast(ccdb->get(TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data())); if (!baseList) { LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } - listWithRuns = reinterpret_cast(getObjectFromList(baseList, runNumber)); + listWithRuns = dynamic_cast(getObjectFromList(baseList, runNumber)); if (!listWithRuns) { TString runNumberWithLeadingZeroes = "000"; runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number - listWithRuns = reinterpret_cast(getObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + listWithRuns = dynamic_cast(getObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); if (!listWithRuns) { - LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + LOGF(warning, "\033[1;31m%s at line %d : this crash can happen if in the output file there is no list with weights for the current runnumber = %s\033[0m", __FUNCTION__, __LINE__, runNumber); + histograms = {nullptr}; + return histograms; } } - // OK, we got the desired TList with efficiency corrections, after that we can use the common code for all 3 cases (local, AliEn, CCDB, that common code is below) + // OK, we got the desired TList with efficiency corrections, after that we + // can use the common code for all 3 cases (local, AliEn, CCDB, that + // common code is below) } else { // this is the local case, please handle this one now: // Check if the external ROOT file exists at specified path: if (gSystem->AccessPathName(filePath, kFileExists)) { - LOGF(info, "\033[1;33m if(gSystem->AccessPathName(filePath,kFileExists)), filePath = %s \033[0m", filePath); + LOGF(info, "\033[1;33m if(gSystem->AccessPathName(filePath, kFileExists)), filePath = %s \033[0m", filePath); LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } @@ -488,18 +696,18 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam weightsFile->GetObject("ccdb_object", baseList); if (!baseList) { - weightsFile->ls(); LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } - listWithRuns = reinterpret_cast(getObjectFromList(baseList, runNumber)); // baseList->FindObject(runNumber) + listWithRuns = dynamic_cast(getObjectFromList(baseList, runNumber)); if (!listWithRuns) { TString runNumberWithLeadingZeroes = "000"; runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number - listWithRuns = reinterpret_cast(getObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + listWithRuns = dynamic_cast(getObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); if (!listWithRuns) { - baseList->ls(); - LOGF(fatal, "\033[1;31m%s at line %d : this crash can happen if in the output file there is no list with weights for the current run number = %s\033[0m", __FUNCTION__, __LINE__, runNumber); + LOGF(warning, "\033[1;31m%s at line %d : this crash can happen if in the output file there is no list with weights for the current runnumber = %s\033[0m", __FUNCTION__, __LINE__, runNumber); + histograms = {nullptr}; + return histograms; } } } @@ -519,10 +727,12 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam continue; } - hist->SetDirectory(0); + hist->SetDirectory(nullptr); auto* histClone = dynamic_cast(hist->Clone()); if (!histClone) { - LOGF(fatal, "Failed to clone histogram %s", hist->GetName()); + LOGF(warning, "Failed to clone histogram %s", hist->GetName()); + histograms = {nullptr}; + return histograms; } histClone->SetTitle(Form("%s:%s", filePath, histClone->GetName())); histograms.push_back(histClone); @@ -531,9 +741,9 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam return histograms; } - // *) Define all member functions to be called in the main process* functions: + //* ) Define all member functions to be called in the main process* functions: template - void Steer(T1 const& collision, T2 const& tracks) + void runLoop(T1 const& collision, T2 const& tracks) { // Dry run: @@ -541,364 +751,629 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam return; } - if (tc.fPrintSwitch) { - // Print current run number: - LOGF(info, "Run number: %d", collision.bc().runNumber()); + // Book Q-vector arrays: + for (int h = 0; h < mcc.MaxHarmonic; h++) { + for (int p = 0; p < mcc.MaxPower; p++) { + mcc.fQvectorBefore[h][p] = TComplex(0., 0.); + mcc.fQvectorAfter[h][p] = TComplex(0., 0.); + } + } + + // Get run number: + ebye.fRunNumber = collision.bc().runNumber(); + std::string stringRunNumber = std::to_string(ebye.fRunNumber); + + // Book phi histogram with this run number: + if (!wt.fPhiByRunMap.contains(ebye.fRunNumber)) { + // wt.fPhiByRunMap[ebye.fRunNumber] = new TH1F(Form("hPhi_run%d", ebye.fRunNumber), Form("phi distribution for run %d", ebye.fRunNumber), static_cast(tc.fPhiBins[0]), tc.fPhiBins[1], tc.fPhiBins[2]); + // wt.fPhiByRunMap[ebye.fRunNumber]->SetDirectory(nullptr); + // wt.fWeightHistogramsList->Add(wt.fPhiByRunMap[ebye.fRunNumber]); + auto* hPhi = new TH1F(Form("hPhi_run%d", ebye.fRunNumber), Form("phi distribution for run %d", ebye.fRunNumber), static_cast(tc.fPhiBins[0]), tc.fPhiBins[1], tc.fPhiBins[2]); + hPhi->SetDirectory(nullptr); + wt.fPhiByRunMap.try_emplace(ebye.fRunNumber, hPhi); + wt.fWeightHistogramsList->Add(wt.fPhiByRunMap[ebye.fRunNumber]); + } + + // Book pt MC rec histogram with this run number: + if (!wt.fPtRealByRunMap.contains(ebye.fRunNumber)) { + // wt.fPtRealByRunMap[ebye.fRunNumber] = new TH1F(Form("hPtReal_run%d", ebye.fRunNumber), Form("pt MC rec distribution for run %d", ebye.fRunNumber), static_cast(tc.fPtBins[0]), tc.fPtBins[1], tc.fPtBins[2]); + // wt.fPtRealByRunMap[ebye.fRunNumber]->SetDirectory(nullptr); + // wt.fWeightHistogramsList->Add(wt.fPtRealByRunMap[ebye.fRunNumber]); + auto* hPtReal = new TH1F(Form("hPtReal_run%d", ebye.fRunNumber), Form("pt MC rec distribution for run %d", ebye.fRunNumber), static_cast(tc.fPtBins[0]), tc.fPtBins[1], tc.fPtBins[2]); + hPtReal->SetDirectory(nullptr); + wt.fPtRealByRunMap.try_emplace(ebye.fRunNumber, hPtReal); + wt.fWeightHistogramsList->Add(wt.fPtRealByRunMap[ebye.fRunNumber]); + } + + // Book pt MC sim histogram with this run number: + if (!wt.fPtMCByRunMap.contains(ebye.fRunNumber)) { + // wt.fPtMCByRunMap[ebye.fRunNumber] = new TH1F(Form("hPtMC_run%d", ebye.fRunNumber), Form("pt MC sim distribution for run %d", ebye.fRunNumber), static_cast(tc.fPtBins[0]), tc.fPtBins[1], tc.fPtBins[2]); + // wt.fPtMCByRunMap[ebye.fRunNumber]->SetDirectory(nullptr); + // wt.fWeightHistogramsList->Add(wt.fPtMCByRunMap[ebye.fRunNumber]); + auto* hPtMC = new TH1F(Form("hPtMC_run%d", ebye.fRunNumber), Form("pt MC sim distribution for run %d", ebye.fRunNumber), static_cast(tc.fPtBins[0]), tc.fPtBins[1], tc.fPtBins[2]); + hPtMC->SetDirectory(nullptr); + wt.fPtMCByRunMap.try_emplace(ebye.fRunNumber, hPtMC); + wt.fWeightHistogramsList->Add(wt.fPtMCByRunMap[ebye.fRunNumber]); + } + + // Get phi and pt weight histogram with this run number: + if (wt.fWeightSwitch && !wt.fPhiWeightHistogramsMap.contains(ebye.fRunNumber)) { + + TH1F* phiWeightHist = dynamic_cast(wt.fDummyPhiWeightHistogram->Clone(Form("wPhi_run%d", ebye.fRunNumber))); + TH1F* ptWeightHist = dynamic_cast(wt.fDummyPtWeightHistogram->Clone(Form("wPt_run%d", ebye.fRunNumber))); + + wt.fWeightHistograms = getHistogramsWithWeights(tc.fFileWithWeights.c_str(), stringRunNumber.c_str()); + + for (auto const& hist : wt.fWeightHistograms) { + if (!hist) { + LOGF(warning, "Fail to loop weight histograms"); + continue; + } + TString histName = hist->GetName(); + if (histName.BeginsWith("wPhi")) { + delete phiWeightHist; + phiWeightHist = dynamic_cast(hist->Clone(Form("wPhi_run%d", ebye.fRunNumber))); + break; + } + } + + for (auto const& hist : wt.fWeightHistograms) { + if (!hist) { + LOGF(warning, "Fail to loop weight histograms"); + continue; + } + TString histName = hist->GetName(); + if (histName.BeginsWith("wPt")) { + delete ptWeightHist; + ptWeightHist = dynamic_cast(hist->Clone(Form("wPt_run%d", ebye.fRunNumber))); + break; + } + } + + phiWeightHist->SetDirectory(nullptr); + wt.fPhiWeightHistogramsMap.try_emplace(ebye.fRunNumber, phiWeightHist); + wt.fWeightHistogramsList->Add(wt.fPhiWeightHistogramsMap[ebye.fRunNumber]); + + ptWeightHist->SetDirectory(nullptr); + wt.fPtWeightHistogramsMap.try_emplace(ebye.fRunNumber, ptWeightHist); + wt.fWeightHistogramsList->Add(wt.fPtWeightHistogramsMap[ebye.fRunNumber]); } + // Multiparticle correlation list with this run number: + if (!mc.fMultiparticleCorrelationByRunMap.contains(ebye.fRunNumber)) { + mc.fMultiparticleCorrelationByRunMap.try_emplace(ebye.fRunNumber, new TList()); + mc.fMultiparticleCorrelationByRunMap[ebye.fRunNumber]->SetName(Form("mcc_run%d", ebye.fRunNumber)); + mc.fMultiparticleCorrelationProfilesList->Add(mc.fMultiparticleCorrelationByRunMap[ebye.fRunNumber]); + + mc.fTwoParticleCorrelationProfiles[eBefore] = nullptr; + mc.fTwoParticleCorrelationProfiles[eAfter] = nullptr; + mc.fFourParticleCorrelationProfiles[eBefore] = nullptr; + mc.fFourParticleCorrelationProfiles[eAfter] = nullptr; + + mc.fTwoParticleCorrelationProfiles[eBefore] = new TProfile("prof2Before", "2-p correlation before cut", 3, 2., 5.); + mc.fTwoParticleCorrelationProfiles[eAfter] = new TProfile("prof2After", "2-p correlation after cut", 3, 2., 5.); + mc.fTwoParticleCorrelationProfiles[eBefore]->Sumw2(); + mc.fTwoParticleCorrelationProfiles[eAfter]->Sumw2(); + mc.fMultiparticleCorrelationByRunMap[ebye.fRunNumber]->Add(mc.fTwoParticleCorrelationProfiles[eBefore]); + mc.fMultiparticleCorrelationByRunMap[ebye.fRunNumber]->Add(mc.fTwoParticleCorrelationProfiles[eAfter]); + + mc.fFourParticleCorrelationProfiles[eBefore] = new TProfile("prof4Before", "4-p correlation before cut", 2, 3., 5.); + mc.fFourParticleCorrelationProfiles[eAfter] = new TProfile("prof4After", "4-p correlation after cut", 2, 3., 5.); + mc.fFourParticleCorrelationProfiles[eBefore]->Sumw2(); + mc.fFourParticleCorrelationProfiles[eAfter]->Sumw2(); + mc.fMultiparticleCorrelationByRunMap[ebye.fRunNumber]->Add(mc.fFourParticleCorrelationProfiles[eBefore]); + mc.fMultiparticleCorrelationByRunMap[ebye.fRunNumber]->Add(mc.fFourParticleCorrelationProfiles[eAfter]); + } + + // Real data centrality: + std::array rlCollisionCentAll = { + collision.centFT0C(), + collision.centFT0M(), + collision.centFV0A()}; + float rlCollisionCent = 0.; - if (tc.fCentEstm == "FT0M") - rlCollisionCent = collision.centFT0M(); - else if (tc.fCentEstm == "FV0A") - rlCollisionCent = collision.centFV0A(); - else if (tc.fCentEstm == "NTPV") - rlCollisionCent = collision.centNTPV(); - else if (tc.fCentEstm == "FT0C") - rlCollisionCent = collision.centFT0C(); + for (int i = 0; i < eCentEstm_N; i++) { + if (tc.fPrintSwitch) { + LOGF(info, "%s Centrality: %f", CentEstmNames[i], + rlCollisionCentAll[i]); + } + if (tc.fCentEstm == CentEstmNames[i]) { + rlCollisionCent = rlCollisionCentAll[i]; + } + } + + // Real data multiplicity: + std::array rlCollisionMultAll = { + static_cast(collision.multFT0C()), + static_cast(collision.multFT0M()), + static_cast(collision.multFV0A())}; float rlCollisionMult = 0.; - if (tc.fMultEstm == "FT0A") - rlCollisionMult = collision.multFT0A(); - else if (tc.fMultEstm == "FT0C") - rlCollisionMult = collision.multFT0C(); - else if (tc.fMultEstm == "FT0M") - rlCollisionMult = collision.multFT0M(); - else if (tc.fMultEstm == "FV0A") - rlCollisionMult = collision.multFV0A(); - else if (tc.fMultEstm == "FV0C") - rlCollisionMult = collision.multFV0C(); - else if (tc.fMultEstm == "NTracksPV") - rlCollisionMult = collision.multNTracksPV(); + for (int i = 0; i < eMultEstm_N; i++) { + if (tc.fPrintSwitch) { + LOGF(info, "%s Multiplicity: %f", MultEstmNames[i], rlCollisionMultAll[i]); + } + if (tc.fMultEstm == MultEstmNames[i]) { + rlCollisionMult = rlCollisionMultAll[i]; + } + } + + // Real data nContrib: float rlCollisionNumContrib = 0.; rlCollisionNumContrib = static_cast(collision.numContrib()); + // Event-by-event quantity: + ebye.fCentrality = rlCollisionCent; + ebye.fReferenceMultiplicity = rlCollisionMult; + ebye.fNumContrib = rlCollisionNumContrib; + + // Print... if (tc.fPrintSwitch) { - // Print centrality estimated with "FT0M" estimator: - LOGF(info, "Centrality: %f", rlCollisionCent); - // Print multiplicity: + LOGF(info, "Run number: %d", ebye.fRunNumber); + + LOGF(info, "Centrality: %f", rlCollisionCent); LOGF(info, "Multiplicity: %f", static_cast(rlCollisionMult)); - // Print vertex position: LOGF(info, "Vertex X position: %f", collision.posX()); LOGF(info, "Vertex Y position: %f", collision.posY()); LOGF(info, "Vertex Z position: %f", collision.posZ()); - // Print NContributors LOGF(info, "NContributors: %f", static_cast(rlCollisionNumContrib)); } - ebye.fCentrality = rlCollisionCent; - ebye.fReferenceMultiplicity = rlCollisionMult; - ebye.fNumContrib = rlCollisionNumContrib; + // If Rec or RecAndSim: if constexpr (rs == eRec || rs == eRecAndSim) { - ev.fEventHistograms[eCent][eRec][0]->Fill(rlCollisionCent); - ev.fEventHistograms[eMult][eRec][0]->Fill(rlCollisionMult); - ev.fEventHistograms[eVertexX][eRec][0]->Fill(collision.posX()); - ev.fEventHistograms[eVertexY][eRec][0]->Fill(collision.posY()); - ev.fEventHistograms[eVertexZ][eRec][0]->Fill(collision.posZ()); - ev.fEventHistograms[eNumContrib][eRec][0]->Fill(rlCollisionNumContrib); - - if (ctEventCuts(collision)) { - ev.fEventHistograms[eCent][eRec][1]->Fill(rlCollisionCent); - ev.fEventHistograms[eMult][eRec][1]->Fill(rlCollisionMult); - ev.fEventHistograms[eVertexX][eRec][1]->Fill(collision.posX()); - ev.fEventHistograms[eVertexY][eRec][1]->Fill(collision.posY()); - ev.fEventHistograms[eVertexZ][eRec][1]->Fill(collision.posZ()); - ev.fEventHistograms[eNumContrib][eRec][1]->Fill(rlCollisionNumContrib); + + // Fill real event histograms before cut: + ev.fEventHistograms[eCent][eRec][eBefore]->Fill(rlCollisionCent); + ev.fEventHistograms[eMult][eRec][eBefore]->Fill(rlCollisionMult); + ev.fEventHistograms[eVertexX][eRec][eBefore]->Fill(collision.posX()); + ev.fEventHistograms[eVertexY][eRec][eBefore]->Fill(collision.posY()); + ev.fEventHistograms[eVertexZ][eRec][eBefore]->Fill(collision.posZ()); + ev.fEventHistograms[eNumContrib][eRec][eBefore]->Fill(rlCollisionNumContrib); + + // Fill centrality correlation histograms before cut: + for (int i = 0; i < eCentEstm_N; i++) { + for (int j = i + 1; j < eCentEstm_N; j++) { + auto* h = cr.fCorrHistograms[eCorrCent][i][j][eBefore]; + if (!h) { + LOGF(fatal, "Missing histogram cr.fCorrHistograms[eCorrCent][%d][%d][eBefore]", i, j); + } + h->Fill(rlCollisionCentAll[i], rlCollisionCentAll[j]); + } } + // Fill multiplicity correlation histograms before cut: + for (int i = 0; i < eMultEstm_N; i++) { + for (int j = i + 1; j < eMultEstm_N; j++) { + auto* h = cr.fCorrHistograms[eCorrMult][i][j][eBefore]; + if (!h) { + LOGF(fatal, "Missing histogram cr.fCorrHistograms[eCorrMult][%d][%d][eBefore]", i, j); + } + h->Fill(rlCollisionMultAll[i], rlCollisionMultAll[j]); + } + } + + // If RecAndSim: if constexpr (rs == eRecAndSim) { if (!collision.has_mcCollision()) { if (tc.fPrintSwitch) { LOGF(warning, " No MC collision for this collision, skip..."); } - return; - } + } else { + // Define MC collision: + auto mccollision = collision.mcCollision(); - auto mccollision = collision.mcCollision(); // McCollisionLabels + // Define MC centrality: + float mcCollisionCent = 0.; + float b = mccollision.impactParameter() * std::pow(10, -15); // convert fm to m + float xs = 7.71 * std::pow(10, -28); // convert barn to m^2 + mcCollisionCent = o2::constants::math::PI * b * b / xs * 100; - float mcCollisionCent = 0.; + // Event-by-event quantity: + ebye.fCentralitySim = mcCollisionCent; + ebye.fImpactParameter = b; - float b = mccollision.impactParameter() * std::pow(10, -15); // convert fm to m - float xs = 7.71 * std::pow(10, -28); // convert barn to m^2 - mcCollisionCent = o2::constants::math::PI * b * b / xs * 100; + if (tc.fPrintSwitch) { + LOGF(info, "mc impact param (fm): %f", mccollision.impactParameter()); + LOGF(info, "mc centrality: %f", mcCollisionCent); + } - ebye.fCentralitySim = mcCollisionCent; - ebye.fImpactParameter = b; + // Fill MC event histograms before cut: + ev.fEventHistograms[eCent][eSim][eBefore]->Fill(mcCollisionCent); + ev.fEventHistograms[eVertexX][eSim][eBefore]->Fill(mccollision.posX()); + ev.fEventHistograms[eVertexY][eSim][eBefore]->Fill(mccollision.posY()); + ev.fEventHistograms[eVertexZ][eSim][eBefore]->Fill(mccollision.posZ()); + + // Fill MC event histograms after cut: + if (ctEventCuts(mccollision, rlCollisionCentAll, rlCollisionMultAll)) { + ev.fEventHistograms[eCent][eSim][eAfter]->Fill(mcCollisionCent); + ev.fEventHistograms[eVertexX][eSim][eAfter]->Fill(mccollision.posX()); + ev.fEventHistograms[eVertexY][eSim][eAfter]->Fill(mccollision.posY()); + ev.fEventHistograms[eVertexZ][eSim][eAfter]->Fill(mccollision.posZ()); + } - if (tc.fPrintSwitch) { - LOGF(info, "mc impact param (fm): %f", mccollision.impactParameter()); - LOGF(info, "mc centrality: %f", mcCollisionCent); + if (qa.fQASwitch) { + qa.fQAHistograms[eQACent][eBefore]->Fill(rlCollisionCent, mcCollisionCent); + qa.fQAHistograms[eQAMultNumContrib][eBefore]->Fill(rlCollisionMult, rlCollisionNumContrib); + if (ctEventCuts(collision, rlCollisionCentAll, rlCollisionMultAll) && + ctEventCuts(mccollision, rlCollisionCentAll, rlCollisionMultAll)) { + qa.fQAHistograms[eQACent][eAfter]->Fill(rlCollisionCent, mcCollisionCent); + qa.fQAHistograms[eQAMultNumContrib][eAfter]->Fill(rlCollisionMult, rlCollisionNumContrib); + } + } } + } - ev.fEventHistograms[eCent][eSim][0]->Fill(mcCollisionCent); - ev.fEventHistograms[eVertexX][eSim][0]->Fill(mccollision.posX()); - ev.fEventHistograms[eVertexY][eSim][0]->Fill(mccollision.posY()); - ev.fEventHistograms[eVertexZ][eSim][0]->Fill(mccollision.posZ()); - - if (ctEventCuts(mccollision)) { - ev.fEventHistograms[eCent][eSim][1]->Fill(mcCollisionCent); - ev.fEventHistograms[eVertexX][eSim][1]->Fill(mccollision.posX()); - ev.fEventHistograms[eVertexY][eSim][1]->Fill(mccollision.posY()); - ev.fEventHistograms[eVertexZ][eSim][1]->Fill(mccollision.posZ()); + // Fill real event histograms after cut + if (ctEventCuts(collision, rlCollisionCentAll, rlCollisionMultAll)) { + ev.fEventHistograms[eCent][eRec][eAfter]->Fill(rlCollisionCent); + ev.fEventHistograms[eMult][eRec][eAfter]->Fill(rlCollisionMult); + ev.fEventHistograms[eVertexX][eRec][eAfter]->Fill(collision.posX()); + ev.fEventHistograms[eVertexY][eRec][eAfter]->Fill(collision.posY()); + ev.fEventHistograms[eVertexZ][eRec][eAfter]->Fill(collision.posZ()); + ev.fEventHistograms[eNumContrib][eRec][eAfter]->Fill(rlCollisionNumContrib); + + // Fill centrality correlation histograms after cut: + if (tc.fCentCorrCutSwitch) { + for (int i = 0; i < eCentEstm_N; i++) { + for (int j = i + 1; j < eCentEstm_N; j++) { + auto* h = cr.fCorrHistograms[eCorrCent][i][j][eAfter]; + if (!h) { + LOGF(fatal, "Missing histogram cr.fCorrHistograms[eCorrCent][%d][%d][eAfter]", i, j); + } + h->Fill(rlCollisionCentAll[i], rlCollisionCentAll[j]); + } + } } - if (qa.fQASwitch) { - qa.fQAHistograms[eQACent][0]->Fill(rlCollisionCent, mcCollisionCent); - qa.fQAHistograms[eQAMultNumContrib][0]->Fill(rlCollisionMult, rlCollisionNumContrib); - if (ctEventCuts(collision) && ctEventCuts(mccollision)) { - qa.fQAHistograms[eQACent][1]->Fill(rlCollisionCent, mcCollisionCent); - qa.fQAHistograms[eQAMultNumContrib][1]->Fill(rlCollisionMult, rlCollisionNumContrib); + // Fill multiplicity correlation histograms after cut: + if (tc.fMultCorrCutSwitch) { + for (int i = 0; i < eMultEstm_N; i++) { + for (int j = i + 1; j < eMultEstm_N; j++) { + auto* h = cr.fCorrHistograms[eCorrMult][i][j][eAfter]; + if (!h) { + LOGF(fatal, "Missing histogram cr.fCorrHistograms[eCorrMult][%d][%d][eAfter]", i, j); + } + h->Fill(rlCollisionMultAll[i], rlCollisionMultAll[j]); + } } } + + // Fail the event cut, skip this collision: + } else { + return; } } + int nTracksBefore = tracks.size(); + int nTracksAfter = 0; + + // Calculate Q-vectors for available angles and weights: + double dPhi = 0.; // particle angle + double dPt = 0.; + double wPhi = 1.; // particle weight + double wPt = 1.; + double wPhiToPowerP = 1.; // particle weight raised to power p. wPhi is actually wPt*wPhi but I'm too lazy to change the name. + // Main loop over particles: for (auto const& track : tracks) { // LOGF(info, "Track azimuthal angle: %f", track.phi()); // LOGF(info, "Transverse momentum: %f", track.pt()); - // Fill reconstructed ...: if constexpr (rs == eRec || rs == eRecAndSim) { - // Fill track pt distribution: - pc.fParticleHistograms[ePt][eRec][0]->Fill(track.pt()); - pc.fParticleHistograms[ePhi][eRec][0]->Fill(track.phi()); + // Fill phi/pt real histogram with this run number: + wt.fPhiByRunMap.at(ebye.fRunNumber)->Fill(track.phi()); + wt.fPtRealByRunMap.at(ebye.fRunNumber)->Fill(track.pt()); + + // Fill track histograms before cut: + pc.fParticleHistograms[ePt][eRec][eBefore]->Fill(track.pt()); + pc.fParticleHistograms[ePhi][eRec][eBefore]->Fill(track.phi()); + + // Calculating Q-vector before cut: + dPhi = track.phi(); + dPt = track.pt(); + if (wt.fWeightSwitch) { + if (!wt.fPhiWeightHistogramsMap.contains(ebye.fRunNumber) || !wt.fPhiWeightHistogramsMap.at(ebye.fRunNumber)) { + LOGF(fatal, "Missing Phi weight histogram for run %d", ebye.fRunNumber); + } + if (!wt.fPtWeightHistogramsMap.contains(ebye.fRunNumber) || !wt.fPtWeightHistogramsMap.at(ebye.fRunNumber)) { + LOGF(fatal, "Missing Pt weight histogram for run %d", ebye.fRunNumber); + } + + auto* histPhi = wt.fPhiWeightHistogramsMap.at(ebye.fRunNumber); + auto* histPt = wt.fPtWeightHistogramsMap.at(ebye.fRunNumber); + wPhi = histPhi->GetBinContent(histPhi->GetXaxis()->FindBin(dPhi)); + wPt = histPt->GetBinContent(histPt->GetXaxis()->FindBin(dPt)); + wPhi *= wPt; + } + + for (int h = 0; h < mcc.MaxHarmonic; h++) { + for (int p = 0; p < mcc.MaxPower; p++) { + if (wt.fWeightSwitch) { + wPhiToPowerP = std::pow(wPhi, p); + } + mcc.fQvectorBefore[h][p] += TComplex(wPhiToPowerP * std::cos(h * dPhi), wPhiToPowerP * std::sin(h * dPhi)); + } + } if (ctParticleCuts(track)) { - pc.fParticleHistograms[ePt][eRec][1]->Fill(track.pt()); - pc.fParticleHistograms[ePhi][eRec][1]->Fill(track.phi()); + + // Fill particle histograms after cut: + pc.fParticleHistograms[ePt][eRec][eAfter]->Fill(track.pt()); + pc.fParticleHistograms[ePhi][eRec][eAfter]->Fill(track.phi()); + + // Calculating Q-vector after cut: + for (int h = 0; h < mcc.MaxHarmonic; h++) { + for (int p = 0; p < mcc.MaxPower; p++) { + if (wt.fWeightSwitch) { + wPhiToPowerP = std::pow(wPhi, p); + } + mcc.fQvectorAfter[h][p] += TComplex(wPhiToPowerP * std::cos(h * dPhi), wPhiToPowerP * std::sin(h * dPhi)); + } + } + + nTracksAfter += 1; } // ... // ... and corresponding MC truth simulated: - // See https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx - // See https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo + // See + // https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx + // See + // https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html#montecarlo if constexpr (rs == eRecAndSim) { if (!track.has_mcParticle()) { if (tc.fPrintSwitch) { LOGF(warning, " No MC particle for this track, skip..."); } - return; - } - auto mcparticle = track.mcParticle(); // corresponding MC truth simulated particle - pc.fParticleHistograms[ePt][eSim][0]->Fill(mcparticle.pt()); - pc.fParticleHistograms[ePhi][eSim][0]->Fill(mcparticle.phi()); - if (ctParticleCuts(mcparticle)) { - pc.fParticleHistograms[ePt][eSim][1]->Fill(mcparticle.pt()); - pc.fParticleHistograms[ePhi][eSim][1]->Fill(mcparticle.phi()); + } else { + // Corresponding MC truth simulated particle + auto mcparticle = track.mcParticle(); + + // Fill pt MC sim histogram with this run number: + wt.fPtMCByRunMap.at(ebye.fRunNumber)->Fill(mcparticle.pt()); + + // Fill MC particle histograms before cut: + pc.fParticleHistograms[ePt][eSim][eBefore]->Fill(mcparticle.pt()); + pc.fParticleHistograms[ePhi][eSim][eBefore]->Fill(mcparticle.phi()); + + if (ctParticleCuts(mcparticle)) { + // Fill MC particle histograms after cut: + pc.fParticleHistograms[ePt][eSim][eAfter]->Fill(mcparticle.pt()); + pc.fParticleHistograms[ePhi][eSim][eAfter]->Fill(mcparticle.phi()); + } } } // end of if constexpr (rs == eRecAndSim) { - } // if constexpr (rs == eRec || rs == eRecAndSim) { - } // end of for (int64_t i = 0; i < tracks.size(); i++) { - } // end of template void Steer(T1 const& collision, T2 const& tracks) { + for (int i = 0; i < mcc.MaxHarmonic - 2; i++) { + mcc.h1 = -(i + 2); + mcc.h2 = i + 2; + std::array harmonicsTwoNum = {mcc.h1, mcc.h2}; + std::array harmonicsTwoDen = {0, 0}; + + TComplex twoRecursionBefore = mccRecursion(2, harmonicsTwoNum, eBefore) / mccRecursion(2, harmonicsTwoDen, eBefore).Re(); + double wTwoRecursionBefore = mccRecursion(2, harmonicsTwoDen, eBefore).Re(); + ebye.fTwoParticleCorrelationEbye[eBefore][i] = twoRecursionBefore.Re(); + + TComplex twoRecursionAfter = mccRecursion(2, harmonicsTwoNum, eAfter) / mccRecursion(2, harmonicsTwoDen, eAfter).Re(); + double wTwoRecursionAfter = mccRecursion(2, harmonicsTwoDen, eAfter).Re(); + ebye.fTwoParticleCorrelationEbye[eAfter][i] = twoRecursionAfter.Re(); + + if (nTracksBefore > 1) { + mc.fTwoParticleCorrelationProfiles[eBefore]->Fill(i + 2.5, ebye.fTwoParticleCorrelationEbye[eBefore][i], wTwoRecursionBefore); + } + if (nTracksAfter > 1) { + mc.fTwoParticleCorrelationProfiles[eAfter]->Fill(i + 2.5, ebye.fTwoParticleCorrelationEbye[eAfter][i], wTwoRecursionAfter); + } + } + + for (int i = 0; i < mcc.NumSC; i++) { + // 4-p correlations: + mcc.h1 = -(i + 3); + mcc.h2 = -2; + mcc.h3 = 2; + mcc.h4 = i + 3; + std::array harmonicsFourNum = {mcc.h1, mcc.h2, mcc.h3, mcc.h4}; + std::array harmonicsFourDen = {0, 0, 0, 0}; + + TComplex fourRecursionBefore = mccRecursion(4, harmonicsFourNum, eBefore) / mccRecursion(4, harmonicsFourDen, eBefore).Re(); + double wFourRecursionBefore = mccRecursion(4, harmonicsFourDen, eBefore).Re(); + ebye.fFourParticleCorrelationEbye[eBefore][i] = fourRecursionBefore.Re(); + + TComplex fourRecursionAfter = mccRecursion(4, harmonicsFourNum, eAfter) / mccRecursion(4, harmonicsFourDen, eAfter).Re(); + double wFourRecursionAfter = mccRecursion(4, harmonicsFourDen, eAfter).Re(); + ebye.fFourParticleCorrelationEbye[eAfter][i] = fourRecursionAfter.Re(); + + if (nTracksBefore > mcc.MaxCorrelator) { + mc.fFourParticleCorrelationProfiles[eBefore]->Fill(i + 3.5, ebye.fFourParticleCorrelationEbye[eBefore][i], wFourRecursionBefore); + } + if (nTracksAfter > mcc.MaxCorrelator) { + mc.fFourParticleCorrelationProfiles[eAfter]->Fill(i + 3.5, ebye.fFourParticleCorrelationEbye[eAfter][i], wFourRecursionAfter); + } + } + } template - void BookParticleHistograms(T1 const& lPcBins, ParticleHistograms& pc) + void bookParticleHistograms(T1 const& lPcBins) { - // *) structure: - // hists without cut - // - name - // - new hists - // └ rec - // └ sim - // hists with cut - // - name - // - new hists - // └ rec - // └ sim - - std::vector lPtBins = lPcBins[histType]; // define local array and initialize it from an array set in the configurables + const auto& lPtBins = lPcBins[histType]; // define local array and initialize it from an array set in the configurables int nBinsPt = static_cast(lPtBins[0]); float minPt = lPtBins[1]; float maxPt = lPtBins[2]; - std::string nameRecNocut = std::string("fHist") + particleHistNames[histType] + std::string("[eRec][before cut]"); - std::string nameSimNocut = std::string("fHist") + particleHistNames[histType] + std::string("[eSim][before cut]"); - std::string nameRecNocutfull = particleHistNames[histType] + std::string(" distribution for reconstructed particles"); - std::string nameSimNocutfull = particleHistNames[histType] + std::string(" distribution for simulated particles"); - - if (doprocessRec || doprocessRecSim) { - pc.fParticleHistograms[histType][eRec][0] = new TH1F(nameRecNocut.c_str(), nameRecNocutfull.c_str(), nBinsPt, minPt, maxPt); - pc.fParticleHistograms[histType][eRec][0]->GetXaxis()->SetTitle(particleHistNames[histType]); - pc.fParticleHistogramsList->Add(pc.fParticleHistograms[histType][eRec][0]); - } - - if (doprocessSim || doprocessRecSim) { - pc.fParticleHistograms[histType][eSim][0] = new TH1F(nameSimNocut.c_str(), nameSimNocutfull.c_str(), nBinsPt, minPt, maxPt); - pc.fParticleHistograms[histType][eSim][0]->GetXaxis()->SetTitle(particleHistNames[histType]); - pc.fParticleHistogramsList->Add(pc.fParticleHistograms[histType][eSim][0]); - } + for (int ba = 0; ba < eCutBeforeAfter_N; ba++) { - std::string nameRecCut = std::string("fHist") + particleHistNames[histType] + std::string("[eRec][after cut]"); - std::string nameSimCut = std::string("fHist") + particleHistNames[histType] + std::string("[eSim][after cut]"); - std::string nameRecCutfull = particleHistNames[histType] + std::string(" distribution for reconstructed particles"); - std::string nameSimCutfull = particleHistNames[histType] + std::string(" distribution for simulated particles"); + std::string nameRec = Form("fHist%s[eRec][%s cut]", ParticleHistNames[histType], CutBeforeAfterNames[ba]); + std::string nameSim = Form("fHist%s[eSim][%s cut]", ParticleHistNames[histType], CutBeforeAfterNames[ba]); + std::string nameRecfull = Form("%s distribution for reconstructed particles", ParticleHistNames[histType]); + std::string nameSimfull = Form("%s distribution for simulated particles", ParticleHistNames[histType]); - if (doprocessRec || doprocessRecSim) { - pc.fParticleHistograms[histType][eRec][1] = new TH1F(nameRecCut.c_str(), nameRecCutfull.c_str(), nBinsPt, minPt, maxPt); - pc.fParticleHistograms[histType][eRec][1]->GetXaxis()->SetTitle(particleHistNames[histType]); - pc.fParticleHistogramsList->Add(pc.fParticleHistograms[histType][eRec][1]); - } + if (doprocessRec || doprocessRecSim) { + pc.fParticleHistograms[histType][eRec][ba] = new TH1F(nameRec.c_str(), nameRecfull.c_str(), nBinsPt, minPt, maxPt); + pc.fParticleHistograms[histType][eRec][ba]->GetXaxis()->SetTitle(ParticleHistNames[histType]); + pc.fParticleHistogramsList->Add(pc.fParticleHistograms[histType][eRec][ba]); + } - if (doprocessSim || doprocessRecSim) { - pc.fParticleHistograms[histType][eSim][1] = new TH1F(nameSimCut.c_str(), nameSimCutfull.c_str(), nBinsPt, minPt, maxPt); - pc.fParticleHistograms[histType][eSim][1]->GetXaxis()->SetTitle(particleHistNames[histType]); - pc.fParticleHistogramsList->Add(pc.fParticleHistograms[histType][eSim][1]); + if (doprocessSim || doprocessRecSim) { + pc.fParticleHistograms[histType][eSim][ba] = new TH1F(nameSim.c_str(), nameSimfull.c_str(), nBinsPt, minPt, maxPt); + pc.fParticleHistograms[histType][eSim][ba]->GetXaxis()->SetTitle(ParticleHistNames[histType]); + pc.fParticleHistogramsList->Add(pc.fParticleHistograms[histType][eSim][ba]); + } } } template - void BookEventHistograms(T1 const& lEvBins, EventHistograms& ev) + void bookEventHistograms(T1 const& lEvBins) { - // *) structure: - // hists without cut - // - name - // └ centrality + estimator - // └ multiplicity + estimator - // └ others - // - new hists - // └ rec - // └ sim (without multiplicity and nContrib) - // hists with cut - // - name - // └ centrality + estimator - // └ multiplicity + estimator - // └ others - // - new hists - // └ rec - // └ sim (without multiplicity and nContrib) - - std::vector lCentBins = lEvBins[histType]; // define local array and initialize it from an array set in the configurables + const auto& lCentBins = lEvBins[histType]; // define local array and initialize it from an array set in the configurables int nBinsCent = static_cast(lCentBins[0]); float minCent = lCentBins[1]; float maxCent = lCentBins[2]; - std::string nameRecNocut = std::string("fHist") + eventHistNames[histType] + std::string("[eRec][before cut]"); - std::string nameSimNocut = std::string("fHist") + eventHistNames[histType] + std::string("[eSim][before cut]"); - std::string nameRecNocutfull; - std::string nameSimNocutfull; - - if constexpr (histType == eCent) { - std::string nameRecNocutfull = tc.fCentEstm + eventHistNames[histType] + std::string(" distribution for reconstructed events"); - std::string nameSimNocutfull = tc.fCentEstm + eventHistNames[histType] + std::string(" distribution for simulated events"); - } else if constexpr (histType == eMult) { - std::string nameRecNocutfull = tc.fMultEstm + eventHistNames[histType] + std::string(" distribution for reconstructed events"); - std::string nameSimNocutfull = tc.fMultEstm + eventHistNames[histType] + std::string(" distribution for simulated events"); - } else { - std::string nameRecNocutfull = eventHistNames[histType] + std::string(" distribution for reconstructed events"); - std::string nameSimNocutfull = eventHistNames[histType] + std::string(" distribution for simulated events"); - } + for (int ba = 0; ba < eCutBeforeAfter_N; ba++) { - if (doprocessRec || doprocessRecSim) { - ev.fEventHistograms[histType][eRec][0] = new TH1F(nameRecNocut.c_str(), nameRecNocutfull.c_str(), nBinsCent, minCent, maxCent); - ev.fEventHistograms[histType][eRec][0]->GetXaxis()->SetTitle(eventHistNames[histType]); - ev.fEventHistogramsList->Add(ev.fEventHistograms[histType][eRec][0]); - } + std::string nameRec = Form("fHist%s[eRec][%s cut]", EventHistNames[histType], CutBeforeAfterNames[ba]); + std::string nameSim = Form("fHist%s[eSim][%s cut]", EventHistNames[histType], CutBeforeAfterNames[ba]); + std::string nameRecfull; + std::string nameSimfull; - if (doprocessSim || doprocessRecSim) { - if constexpr (histType != eNumContrib && histType != eMult) { - ev.fEventHistograms[histType][eSim][0] = new TH1F(nameSimNocut.c_str(), nameSimNocutfull.c_str(), nBinsCent, minCent, maxCent); - ev.fEventHistograms[histType][eSim][0]->GetXaxis()->SetTitle(eventHistNames[histType]); - ev.fEventHistogramsList->Add(ev.fEventHistograms[histType][eSim][0]); - } // No nContrib and multiplicity for processSim + if constexpr (histType == eCent) { + nameRecfull = Form("%s %s distribution for reconstructed events", tc.fCentEstm.c_str(), EventHistNames[histType]); + nameSimfull = Form("%s %s distribution for simulated events", tc.fCentEstm.c_str(), EventHistNames[histType]); + } else if constexpr (histType == eMult) { + nameRecfull = Form("%s %s distribution for reconstructed events", tc.fMultEstm.c_str(), EventHistNames[histType]); + nameSimfull = Form("%s %s distribution for simulated events", tc.fMultEstm.c_str(), EventHistNames[histType]); + } else { + nameRecfull = Form("%s distribution for reconstructed events", EventHistNames[histType]); + nameSimfull = Form("%s distribution for simulated events", EventHistNames[histType]); + } + + if (doprocessRec || doprocessRecSim) { + ev.fEventHistograms[histType][eRec][ba] = new TH1F(nameRec.c_str(), nameRecfull.c_str(), nBinsCent, minCent, maxCent); + ev.fEventHistograms[histType][eRec][ba]->GetXaxis()->SetTitle(EventHistNames[histType]); + ev.fEventHistogramsList->Add(ev.fEventHistograms[histType][eRec][ba]); + } + + if (doprocessSim || doprocessRecSim) { + if constexpr (histType != eNumContrib && histType != eMult) { + ev.fEventHistograms[histType][eSim][ba] = new TH1F(nameSim.c_str(), nameSimfull.c_str(), nBinsCent, minCent, maxCent); + ev.fEventHistograms[histType][eSim][ba]->GetXaxis()->SetTitle(EventHistNames[histType]); + ev.fEventHistogramsList->Add(ev.fEventHistograms[histType][eSim][ba]); + } // No nContrib and multiplicity for processSim + } } + } - std::string nameRecCut = std::string("fHist") + eventHistNames[histType] + std::string("[eRec][after cut]"); - std::string nameSimCut = std::string("fHist") + eventHistNames[histType] + std::string("[eSim][after cut]"); - std::string nameRecCutfull; - std::string nameSimCutfull; - - if constexpr (histType == eCent) { - std::string nameRecCutfull = tc.fCentEstm + eventHistNames[histType] + std::string(" distribution for reconstructed events"); - std::string nameSimCutfull = tc.fCentEstm + eventHistNames[histType] + std::string(" distribution for simulated events"); - } else if constexpr (histType == eMult) { - std::string nameRecCutfull = tc.fMultEstm + eventHistNames[histType] + std::string(" distribution for reconstructed events"); - std::string nameSimCutfull = tc.fMultEstm + eventHistNames[histType] + std::string(" distribution for simulated events"); + template + void bookQAHistograms(T1 const& lQABins) + { + int nBinsCentX = 0; + float minCentX = 0.; + float maxCentX = 0.; + int nBinsCentY = 0; + float minCentY = 0.; + float maxCentY = 0.; + int nBinsCent = 0; + float minCent = 0.; + float maxCent = 0.; + + if (histType == eMult) { + const auto& lCentBinsX = lQABins[1]; // MultBins + nBinsCentX = static_cast(lCentBinsX[0]); + minCentX = lCentBinsX[1]; + maxCentX = lCentBinsX[2]; + const auto& lCentBinsY = lQABins[2]; // nContribBins + nBinsCentY = static_cast(lCentBinsY[0]); + minCentY = lCentBinsY[1]; + maxCentY = lCentBinsY[2]; } else { - std::string nameRecCutfull = eventHistNames[histType] + std::string(" distribution for reconstructed events"); - std::string nameSimCutfull = eventHistNames[histType] + std::string(" distribution for simulated events"); + const auto& lCentBins = lQABins[histType]; + nBinsCent = static_cast(lCentBins[0]); + minCent = lCentBins[1]; + maxCent = lCentBins[2]; } - if (doprocessRec || doprocessRecSim) { - ev.fEventHistograms[histType][eRec][1] = new TH1F(nameRecCut.c_str(), nameRecCutfull.c_str(), nBinsCent, minCent, maxCent); - ev.fEventHistograms[histType][eRec][1]->GetXaxis()->SetTitle(eventHistNames[histType]); - ev.fEventHistogramsList->Add(ev.fEventHistograms[histType][eRec][1]); - } + for (int ba = 0; ba < eCutBeforeAfter_N; ba++) { + std::string name = Form("fHist%s[%s cut]", EventHistNames[histType], CutBeforeAfterNames[ba]); + std::string namefull; - if (doprocessSim || doprocessRecSim) { - if constexpr (histType != eNumContrib && histType != eMult) { - ev.fEventHistograms[histType][eSim][1] = new TH1F(nameSimCut.c_str(), nameSimCutfull.c_str(), nBinsCent, minCent, maxCent); - ev.fEventHistograms[histType][eSim][1]->GetXaxis()->SetTitle(eventHistNames[histType]); - ev.fEventHistogramsList->Add(ev.fEventHistograms[histType][eSim][1]); + if constexpr (histType == eCent) { + namefull = Form("Quality assurance of %s %s", tc.fCentEstm.c_str(), EventHistNames[histType]); + } else if constexpr (histType == eMult) { + namefull = Form("Quality assurance of %s %s vs. NContributors", tc.fMultEstm.c_str(), EventHistNames[histType]); + } else { + namefull = Form("Quality assurance of %s", EventHistNames[histType]); } + + if constexpr (histType == eMult) { + qa.fQAHistograms[histType][ba] = new TH2F(name.c_str(), namefull.c_str(), nBinsCentX, minCentX, maxCentX, nBinsCentY, minCentY, maxCentY); + qa.fQAHistograms[histType][ba]->GetYaxis()->SetTitle("NContributors"); + qa.fQAHistograms[histType][ba]->GetXaxis()->SetTitle("Reference multiplicity"); + } else { + qa.fQAHistograms[histType][ba] = new TH2F(name.c_str(), namefull.c_str(), nBinsCent, minCent, maxCent, nBinsCent, minCent, maxCent); + qa.fQAHistograms[histType][ba]->GetYaxis()->SetTitle(Form("Simulated %s", EventHistNames[histType])); + qa.fQAHistograms[histType][ba]->GetXaxis()->SetTitle(Form("Reconstructed %s", EventHistNames[histType])); + } + qa.fQAHistogramsList->Add(qa.fQAHistograms[histType][ba]); } } - template - void BookQAHistograms(T1 const& lQABins, QAHistograms& qa) + template + void bookCorrHistograms(T1 const& lCrBins) { - // *) structure: - // hists without cut - // └ simulated centrality vs. reconstructed centrality - // └ nContrib vs. multiplicity - // └ others - // hists with cut - // └ simulated centrality vs. reconstructed centrality - // └ nContrib vs. multiplicity - // └ others - - std::vector lCentBins = lQABins[histType]; + + const auto& lCentBins = lCrBins[histType]; // define local array and initialize it from an array set in the configurables int nBinsCent = static_cast(lCentBins[0]); float minCent = lCentBins[1]; float maxCent = lCentBins[2]; - std::string nameNocut = std::string("fHist") + eventHistNames[histType] + std::string("[before cut]"); - std::string nameNocutfull; - if constexpr (histType == eCent) { - std::string nameNocutfull = std::string("Quality assurance of ") + tc.fCentEstm + eventHistNames[histType]; - } else if constexpr (histType == eNumContrib) { - std::string nameNocutfull = std::string("Quality assurance of ") + tc.fMultEstm + eventHistNames[histType] + std::string(" vs. NContributors"); - } else { - std::string nameNocutfull = std::string("Quality assurance of ") + eventHistNames[histType]; - } + for (int ba = 0; ba < eCutBeforeAfter_N; ba++) { + std::string name; + std::string namefull = Form("%s correlation %s cut", CorrHistNames[histType], CutBeforeAfterNames[ba]); - qa.fQAHistograms[histType][0] = new TH2F(nameNocut.c_str(), nameNocutfull.c_str(), nBinsCent, minCent, maxCent, nBinsCent, minCent, maxCent); - if constexpr (histType == eNumContrib) { - qa.fQAHistograms[histType][0]->GetYaxis()->SetTitle("NContributors"); - qa.fQAHistograms[histType][0]->GetXaxis()->SetTitle("Reference multiplicity"); - } else { - qa.fQAHistograms[histType][0]->GetYaxis()->SetTitle(Form("Simulated %s", eventHistNames[histType])); - qa.fQAHistograms[histType][0]->GetXaxis()->SetTitle(Form("Reconstructed %s", eventHistNames[histType])); - } - qa.fQAHistogramsList->Add(qa.fQAHistograms[histType][0]); - - std::string nameCut = std::string("fHist") + eventHistNames[histType] + std::string("[after cut]"); - std::string nameCutfull; - if constexpr (histType == eCent) { - std::string nameCutfull = std::string("Quality assurance of ") + tc.fCentEstm + eventHistNames[histType]; - } else if constexpr (histType == eNumContrib) { - std::string nameCutfull = std::string("Quality assurance of ") + tc.fMultEstm + eventHistNames[histType]; - } else { - std::string nameCutfull = std::string("Quality assurance of ") + eventHistNames[histType]; - } + int nEstm = 0; + if constexpr (histType == eCorrCent) { + nEstm = eCentEstm_N; + } else if constexpr (histType == eCorrMult) { + nEstm = eMultEstm_N; + } + for (int i = 0; i < nEstm; i++) { + + std::string titleX; + if (histType == eCorrCent) { + titleX = Form("%s %s", CentEstmNames[i], CorrHistNames[histType]); + } else if (histType == eCorrMult) { + titleX = Form("%s %s", MultEstmNames[i], CorrHistNames[histType]); + // x axis bin... + } - qa.fQAHistograms[histType][1] = new TH2F(nameCut.c_str(), nameCutfull.c_str(), nBinsCent, minCent, maxCent, nBinsCent, minCent, maxCent); - if constexpr (histType == eNumContrib) { - qa.fQAHistograms[histType][1]->GetYaxis()->SetTitle("NContributors"); - qa.fQAHistograms[histType][1]->GetXaxis()->SetTitle("Reference multiplicity"); - } else { - qa.fQAHistograms[histType][1]->GetYaxis()->SetTitle(Form("Simulated %s", eventHistNames[histType])); - qa.fQAHistograms[histType][1]->GetXaxis()->SetTitle(Form("Reconstructed %s", eventHistNames[histType])); + for (int j = i + 1; j < nEstm; j++) { + + std::string titleY; + if (histType == eCorrCent) { + name = Form("fHist%s[%s vs. %s][%s cut]", CorrHistNames[histType], CentEstmNames[i], CentEstmNames[j], CutBeforeAfterNames[ba]); + titleY = Form("%s %s", CentEstmNames[j], CorrHistNames[histType]); + cr.fCorrHistograms[histType][i][j][ba] = new TH2F(name.c_str(), namefull.c_str(), nBinsCent, minCent, maxCent, nBinsCent, minCent, maxCent); + } else if (histType == eCorrMult) { + name = Form("fHist%s[%s vs. %s][%s cut]", CorrHistNames[histType], MultEstmNames[i], MultEstmNames[j], CutBeforeAfterNames[ba]); + titleY = Form("%s %s", MultEstmNames[j], CorrHistNames[histType]); + // y axis bins... + cr.fCorrHistograms[histType][i][j][ba] = new TH2F(name.c_str(), namefull.c_str(), nBinsCent, minCent, maxCent, nBinsCent, minCent, maxCent); + } + + cr.fCorrHistograms[histType][i][j][ba]->GetYaxis()->SetTitle(titleY.c_str()); + cr.fCorrHistograms[histType][i][j][ba]->GetXaxis()->SetTitle(titleX.c_str()); + cr.fCorrHistogramsList->Add(cr.fCorrHistograms[histType][i][j][ba]); + } + } } - qa.fQAHistogramsList->Add(qa.fQAHistograms[histType][1]); } // *) Initialize and book all objects: @@ -907,7 +1382,8 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam // ... code to book and initialize all analysis objects ... - // *) Set automatically what to process, from an implicit variable "doprocessSomeProcessName" within a PROCESS_SWITCH clause: + // *) Set automatically what to process, from an implicit variable + // "doprocessSomeProcessName" within a PROCESS_SWITCH clause: tc.fProcess[eProcessRec] = doprocessRec; tc.fProcess[eProcessRecSim] = doprocessRecSim; tc.fProcess[eProcessSim] = doprocessSim; @@ -921,6 +1397,8 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam tc.fSel8CutSwitch = cfSel8CutSwitch; tc.fCentCutSwitch = cfCentCutSwitch; tc.fNumContribCutSwitch = cfNumContribCutSwitch; + tc.fCentCorrCutSwitch = cfCentCorrCutSwitch; + tc.fMultCorrCutSwitch = cfMultCorrCutSwitch; tc.fPtCutSwitch = cfPtCutSwitch; tc.fEtaCutSwitch = cfEtaCutSwitch; @@ -932,6 +1410,8 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam tc.fVertexZCut = cfVertexZCut; tc.fCentCut = cfCentCut; tc.fNumContribCut = cfNumContribCut; + tc.fCentCorrCut = cfCentCorrCut; + tc.fMultCorrCut = cfMultCorrCut; tc.fPtCut = cfPtCut; tc.fEtaCut = cfEtaCut; @@ -952,13 +1432,12 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam tc.fPrintSwitch = cfPrintSwitch; tc.fFileWithWeights = cfFileWithWeights; - tc.fRunNumber = cfRunNumber; qa.fQASwitch = cfQASwitch; wt.fWeightSwitch = cfWeightSwitch; // *) Book base list: - TList* temp = new TList(); + auto* temp = new TList(); temp->SetOwner(kTRUE); fBaseList.setObject(temp); @@ -983,26 +1462,41 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam wt.fWeightHistogramsList->SetOwner(kTRUE); fBaseList->Add(wt.fWeightHistogramsList); + cr.fCorrHistogramsList = new TList(); + cr.fCorrHistogramsList->SetName("CorrelationHistograms"); + cr.fCorrHistogramsList->SetOwner(kTRUE); + fBaseList->Add(cr.fCorrHistogramsList); + + mc.fMultiparticleCorrelationProfilesList = new TList(); + mc.fMultiparticleCorrelationProfilesList->SetName("MultiparticleCorrelationProfiles"); + mc.fMultiparticleCorrelationProfilesList->SetOwner(kTRUE); + fBaseList->Add(mc.fMultiparticleCorrelationProfilesList); + std::vector> lPcBins = {tc.fPtBins, tc.fPhiBins}; std::vector> lEvBins = {tc.fCentBins, tc.fMultBins, tc.fVerXBins, tc.fVerYBins, tc.fVerZBins, tc.fNumContribBins}; std::vector> lQABins = {tc.fCentBins, tc.fMultBins, tc.fNumContribBins}; - - BookParticleHistograms(lPcBins, pc); - BookParticleHistograms(lPcBins, pc); - BookEventHistograms(lEvBins, ev); - BookEventHistograms(lEvBins, ev); - BookEventHistograms(lEvBins, ev); - BookEventHistograms(lEvBins, ev); - BookEventHistograms(lEvBins, ev); - BookEventHistograms(lEvBins, ev); - BookQAHistograms(lQABins, qa); - BookQAHistograms(lQABins, qa); - - if (wt.fWeightSwitch) { - wt.fWeightHistograms = getHistogramsWithWeights(tc.fFileWithWeights.c_str(), tc.fRunNumber.c_str()); - for (auto* hist : wt.fWeightHistograms) { - wt.fWeightHistogramsList->Add(hist); - } + std::vector> lCrBins = {tc.fCentBins, tc.fMultBins}; + + bookParticleHistograms(lPcBins); + bookParticleHistograms(lPcBins); + bookEventHistograms(lEvBins); + bookEventHistograms(lEvBins); + bookEventHistograms(lEvBins); + bookEventHistograms(lEvBins); + bookEventHistograms(lEvBins); + bookEventHistograms(lEvBins); + bookQAHistograms(lQABins); + bookQAHistograms(lQABins); + bookCorrHistograms(lCrBins); // if switch on ... + bookCorrHistograms(lCrBins); + + wt.fDummyPhiWeightHistogram = new TH1F("fDummyPhiWeightHistogram", "Dummy phi weight histogram", static_cast(tc.fPhiBins[0]), tc.fPhiBins[1], tc.fPhiBins[2]); + for (int i = 1; i <= wt.fDummyPhiWeightHistogram->GetNbinsX(); i++) { + wt.fDummyPhiWeightHistogram->SetBinContent(i, 1.); + } + wt.fDummyPtWeightHistogram = new TH1F("fDummyPtWeightHistogram", "Dummy pt weight histogram", static_cast(tc.fPtBins[0]), tc.fPtBins[1], tc.fPtBins[2]); + for (int i = 1; i <= wt.fDummyPtWeightHistogram->GetNbinsX(); i++) { + wt.fDummyPtWeightHistogram->SetBinContent(i, 1.); } } // end of void init(InitContext&) { @@ -1011,9 +1505,8 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam void processRec(CollisionRec const& collision, aod::BCs const&, TracksRec const& tracks) { // ... - // *) Steer all analysis steps: - Steer(collision, tracks); + runLoop(collision, tracks); } PROCESS_SWITCH(MultiparticleCumulants, processRec, "process only reconstructed data", true); // yes, keep always one process switch "true", so that there is default running version @@ -1022,7 +1515,7 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam // B) Process both reconstructed and corresponding MC truth simulated data: void processRecSim(CollisionRecSim const& collision, aod::BCs const&, TracksRecSim const& tracks, aod::McParticles const&, aod::McCollisions const&) { - Steer(collision, tracks); + runLoop(collision, tracks); } PROCESS_SWITCH(MultiparticleCumulants, processRecSim, "process both reconstructed and corresponding MC truth simulated data", false); @@ -1031,7 +1524,7 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam // C) Process only simulated data: void processSim(CollisionSim const& /*collision*/, aod::BCs const&, TracksSim const& /*tracks*/) { - // Steer(collision, tracks); // TBI 20241105 not ready yet, but I do not really need this one urgently, since RecSim is working, and I need that one for efficiencies... + // runLoop(collision, tracks); // TBI 20241105 not ready yet, but I do not really need this one urgently, since RecSim is working, and I need that one for efficiencies... } PROCESS_SWITCH(MultiparticleCumulants, processSim, "process only simulated data", false); @@ -1040,7 +1533,5 @@ struct MultiparticleCumulants { // this name is used in lower-case format to nam // *) The final touch: WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{ - adaptAnalysisTask(cfgc), - }; + return WorkflowSpec{adaptAnalysisTask(cfgc)}; } // WorkflowSpec... diff --git a/PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h b/PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h index 62f906a38ae..a6c9e2286ce 100644 --- a/PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h +++ b/PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h @@ -117,7 +117,8 @@ DECLARE_SOA_TABLE(UpcLRCollisions, "AOD", "UPCLRCOLLISION", lrcorrcolltable::Multiplicity, lrcorrcolltable::TotalFT0AmplitudeA, lrcorrcolltable::TotalFT0AmplitudeC, - lrcorrcolltable::TotalFV0AmplitudeA); + lrcorrcolltable::TotalFV0AmplitudeA, + timestamp::Timestamp); using UpcLRCollision = UpcLRCollisions::iterator; DECLARE_SOA_TABLE(UpcSgLRCollisions, "AOD", "UPCSGLRCOLLISION", @@ -159,6 +160,7 @@ DECLARE_SOA_COLUMN(Eta, eta, float); DECLARE_SOA_COLUMN(Phi, phi, float); DECLARE_SOA_COLUMN(IsCA, isCA, bool); DECLARE_SOA_COLUMN(IsReassigned, isReassigned, bool); +DECLARE_SOA_COLUMN(IsTrackFT0Outer, isTrackFT0Outer, bool); enum TrackPid { kSpCharge, @@ -193,7 +195,8 @@ DECLARE_SOA_TABLE(LRFt0aTracks, "AOD", "LRFT0ATRACK", lrcorrtrktable::ChannelID, lrcorrtrktable::Amplitude, lrcorrtrktable::Eta, - lrcorrtrktable::Phi); + lrcorrtrktable::Phi, + lrcorrtrktable::IsTrackFT0Outer); using LRFt0aTrack = LRFt0aTracks::iterator; DECLARE_SOA_TABLE(LRFt0cTracks, "AOD", "LRFT0CTRACK", @@ -202,7 +205,8 @@ DECLARE_SOA_TABLE(LRFt0cTracks, "AOD", "LRFT0CTRACK", lrcorrtrktable::ChannelID, lrcorrtrktable::Amplitude, lrcorrtrktable::Eta, - lrcorrtrktable::Phi); + lrcorrtrktable::Phi, + lrcorrtrktable::IsTrackFT0Outer); using LRFt0cTrack = LRFt0cTracks::iterator; DECLARE_SOA_TABLE(LRV0Tracks, "AOD", "LRV0TRACK", @@ -250,7 +254,8 @@ DECLARE_SOA_TABLE(UpcLRFt0aTracks, "AOD", "UPCLRFT0ATRACK", lrcorrtrktable::ChannelID, lrcorrtrktable::Amplitude, lrcorrtrktable::Eta, - lrcorrtrktable::Phi); + lrcorrtrktable::Phi, + lrcorrtrktable::IsTrackFT0Outer); using UpcLRFt0aTrack = UpcLRFt0aTracks::iterator; DECLARE_SOA_TABLE(UpcLRFt0cTracks, "AOD", "UPCLRFT0CTRACK", @@ -259,7 +264,8 @@ DECLARE_SOA_TABLE(UpcLRFt0cTracks, "AOD", "UPCLRFT0CTRACK", lrcorrtrktable::ChannelID, lrcorrtrktable::Amplitude, lrcorrtrktable::Eta, - lrcorrtrktable::Phi); + lrcorrtrktable::Phi, + lrcorrtrktable::IsTrackFT0Outer); using UpcLRFt0cTrack = UpcLRFt0cTracks::iterator; DECLARE_SOA_TABLE(UpcLRV0Tracks, "AOD", "UPCLRV0TRACK", diff --git a/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx b/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx index 0eaaf4a4f82..5a11c2ae50d 100644 --- a/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx +++ b/PWGCF/TwoParticleCorrelations/TableProducer/longrangeMaker.cxx @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -55,7 +56,7 @@ #include #include -#include +#include #include @@ -67,9 +68,7 @@ #include #include #include -#include #include -#include #include using namespace o2; @@ -83,11 +82,20 @@ using namespace o2::constants::math; auto static constexpr CintZero = 0; auto static constexpr KminFt0cCell = 96; auto static constexpr TotFt0Channels = 208; +auto static constexpr MinFt0aDeadChannelOuter = 60; +auto static constexpr MinFt0aMirrorChannelOuter = 92; +auto static constexpr MaxFt0aMirrorChannelOuter = 95; +auto static constexpr MinFt0aOuterRing = 32; +auto static constexpr Ft0cDeadChannelInner = 139; +auto static constexpr Ft0cMirrorChannelInner = 115; +auto static constexpr MinFt0cDeadChannelOuter = 176; +auto static constexpr MinFt0cMirrorChannelOuter = 144; +auto static constexpr MaxFt0cMirrorChannelOuter = 147; +auto static constexpr MinFt0cOuterRing = 144; + AxisSpec axisEvent{20, 0.5, 20.5, "#Event", "EventAxis"}; AxisSpec axisTrackSel{10, 0.5, 10.5, "#Track", "TrackAxis"}; auto static constexpr KminCharge = 3.0f; -static constexpr std::string_view species[] = {"Pi", "Ka", "Pr"}; -static constexpr std::array speciesIds{kPiPlus, kKPlus, kProton}; enum KindOfV0 { kLambda = 0, @@ -102,6 +110,7 @@ struct LongrangeMaker { } cfgCcdbParam; struct : ConfigurableGroup { + std::string prefix = "EventSelection_group"; Configurable isApplyTrigTvx{"isApplyTrigTvx", false, "Enable Ft0a and Ft0c coincidence"}; Configurable isApplyTfborder{"isApplyTfborder", false, "Enable TF border cut"}; Configurable isApplyItsRofborder{"isApplyItsRofborder", false, "Enable ITS ROF border cut"}; @@ -128,11 +137,12 @@ struct LongrangeMaker { } cfgevtsel; struct : ConfigurableGroup { - Configurable cfgItsPattern{"cfgItsPattern", 1, "0 = Run3ITSibAny, 1 = Run3ITSallAny, 2 = Run3ITSall7Layers, 3 = Run3ITSibTwo"}; + std::string prefix = "MidTrackSelection_group"; Configurable cfgEtaCut{"cfgEtaCut", 0.8f, "Eta range to consider"}; Configurable cfgPtCutMin{"cfgPtCutMin", 0.2f, "minimum accepted track pT"}; Configurable cfgPtCutMax{"cfgPtCutMax", 10.0f, "maximum accepted track pT"}; - Configurable cfgPtCutMult{"cfgPtCutMult", 3.0f, "maximum track pT for multiplicity classification"}; + Configurable cfgPtCutMinForMult{"cfgPtCutMinForMult", 0.2f, "minimum track pT for multiplicity classification"}; + Configurable cfgPtCutMaxForMult{"cfgPtCutMaxForMult", 3.0f, "maximum track pT for multiplicity classification"}; Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 70.f, "cut on minimum number of TPC crossed rows"}; Configurable minTPCNClsFound{"minTPCNClsFound", 50.f, "cut on minimum value of TPC found clusters"}; Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.8f, "cut on minNCrossedRowsOverFindableClustersTPC"}; @@ -140,12 +150,13 @@ struct LongrangeMaker { Configurable maxChi2PerClusterITS{"maxChi2PerClusterITS", 36.f, "cut on maximum value of ITS chi2 per cluster"}; Configurable maxDcaZ{"maxDcaZ", 2.0f, "cut on maximum abs value of DCA z"}; Configurable maxDcaXY{"maxDcaXY", 1.0f, "cut on maximum abs value of DCA xy"}; + Configurable applyEffCorr{"applyEffCorr", true, "Enable efficiency correction"}; + Configurable cfgEffccdbPath{"cfgEffccdbPath", "Users/a/abmodak/Efficiency/OO/default", "Browse track eff object from CCDB"}; } cfgtrksel; struct : ConfigurableGroup { + std::string prefix = "MftTrackSelection_group"; Configurable cfgUseChi2Cut{"cfgUseChi2Cut", false, "Use condition on MFT track: chi2/Nclusters"}; - Configurable cfgRequireCA{"cfgRequireCA", false, "Use Cellular Automaton track-finding algorithm"}; - Configurable cfgRequireLTF{"cfgRequireLTF", false, "Use LTF track-finding algorithm"}; Configurable useMftPtCut{"useMftPtCut", true, "Choose to apply MFT track pT cut"}; Configurable cfgMftCluster{"cfgMftCluster", 5, "cut on MFT Cluster"}; Configurable cfgMftEtaMax{"cfgMftEtaMax", -2.4f, "Maximum MFT eta cut"}; @@ -158,16 +169,20 @@ struct LongrangeMaker { } cfgmfttrksel; struct : ConfigurableGroup { + std::string prefix = "FitTrackSelection_group"; Configurable cfgFt0aEtaMax{"cfgFt0aEtaMax", 4.9f, "Maximum FT0A eta cut"}; Configurable cfgFt0aEtaMin{"cfgFt0aEtaMin", 3.5f, "Minimum FT0A eta cut"}; Configurable cfgFt0cEtaMax{"cfgFt0cEtaMax", -2.1f, "Maximum FT0C eta cut"}; Configurable cfgFt0cEtaMin{"cfgFt0cEtaMin", -3.3f, "Minimum FT0C eta cut"}; Configurable cfgVerbosity{"cfgVerbosity", 0, "print statement"}; Configurable useGainCalib{"useGainCalib", true, "use gain calibration"}; + Configurable applyMirrorFt0a{"applyMirrorFt0a", true, "consider Mirror 92-95 into 60-63"}; + Configurable applyMirrorFt0c{"applyMirrorFt0c", true, "consider Mirror 144-147 into 176-179 and Mirror 115 into 139"}; Configurable confGainPath{"confGainPath", "Analysis/EventPlane/GainEq/FT0", "Path to gain calibration"}; } cfgfittrksel; struct : ConfigurableGroup { + std::string prefix = "V0TrackSelection_group"; Configurable minTPCcrossedrows{"minTPCcrossedrows", 70.f, "cut on minimum number of crossed rows in TPC"}; Configurable minTPCcrossedrowsoverfindcls{"minTPCcrossedrowsoverfindcls", 0.8f, "cut on minimum value of the ratio between crossed rows and findable clusters in the TPC"}; Configurable v0etaCut{"v0etaCut", 0.8f, "maximum v0 track pseudorapidity"}; @@ -195,14 +210,12 @@ struct LongrangeMaker { } cfgv0trksel; struct : ConfigurableGroup { - ConfigurableAxis axisVtx = {"axisVtx", {20, -10, 10}, "Vertex axis"}; - ConfigurableAxis axisMult = {"axisMult", {100, 0, 100}, "Multiplicity axis"}; - ConfigurableAxis axisEta = {"axisEta", {20, -1, 1}, "eta axis"}; - ConfigurableAxis axisPt = {"axisPt", {10, 0, 10}, "pT axis"}; - ConfigurableAxis axisSpecies = {"axisSpecies", {4, 0.5, 4.5}, "Species axis"}; + std::string prefix = "ConfigAxis_group"; ConfigurableAxis axisAmplitude{"axisAmplitude", {5000, 0, 10000}, "FT0 amplitude"}; ConfigurableAxis axisChannel{"axisChannel", {208, 0, 208}, "FT0 channel"}; ConfigurableAxis axisMFTAmbDegree{"axisMFTAmbDegree", {50, -0.5, 49.5}, "Track Ambiguity axis"}; + ConfigurableAxis axisEta = {"axisEta", {100, -5, 5}, "eta axis"}; + ConfigurableAxis axisPhi{"axisPhi", {72, 0, TwoPI}, "#phi axis"}; } cfgAxis; Configurable> itsNsigmaPidCut{"itsNsigmaPidCut", std::vector{3, 2.5, 2, -3, -2.5, -2}, "ITS n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma"}; @@ -210,7 +223,6 @@ struct LongrangeMaker { Configurable> tofNsigmaPidCut{"tofNsigmaPidCut", std::vector{1.5, 1.5, 1.5, -1.5, -1.5, -1.5}, "TOF n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma"}; Configurable cfgTofPidPtCut{"cfgTofPidPtCut", 0.3f, "Minimum pt to use TOF N-sigma"}; Configurable isUseItsPid{"isUseItsPid", false, "Use ITS PID for particle identification"}; - Configurable isUseCentEst{"isUseCentEst", false, "Centrality based classification"}; Service ccdb; Service pdg; @@ -232,6 +244,10 @@ struct LongrangeMaker { Configurable sgCuts{"sgCuts", {}, "SG event cuts"}; Configurable cfgGapSide{"cfgGapSide", 2, "cut on UPC events"}; + // corrections + TH3D* hTrkEff = nullptr; + bool fLoadTrkEffCorr = false; + void init(InitContext&) { ccdb->setURL(cfgCcdbParam.cfgURL); @@ -261,7 +277,8 @@ struct LongrangeMaker { x->SetBinLabel(12, "ApplyNoCollInTimeRangeStrict"); x->SetBinLabel(13, "ApplyNoHighMultCollInPrevRof"); x->SetBinLabel(14, "ApplyOccupancySelection"); - x->SetBinLabel(15, "reject flange event"); + x->SetBinLabel(15, "ZvertexSelection"); + x->SetBinLabel(16, "reject flange event"); histos.add("hSelectionResult", "hSelectionResult", kTH1I, {{5, -0.5, 4.5}}); histos.add("hMftTrkSel", "hMftTrkSel", kTH1D, {axisTrackSel}, false); @@ -287,28 +304,19 @@ struct LongrangeMaker { histos.add("FT0A_Amp_gaincorrected", "FT0A_Amp_gaincorrected", kTH1D, {cfgAxis.axisAmplitude}); histos.add("FT0A_Channel_vs_Amp", "FT0A_Channel_vs_Amp", kTH2D, {cfgAxis.axisChannel, cfgAxis.axisAmplitude}); histos.add("FT0A_Channel_vs_Amp_gaincorrected", "FT0A_Channel_vs_Amp_gaincorrected", kTH2D, {cfgAxis.axisChannel, cfgAxis.axisAmplitude}); + histos.add("FT0A_Channel_vs_eta", "FT0A_Channel_vs_eta", kTH2D, {cfgAxis.axisEta, cfgAxis.axisChannel}); + histos.add("FT0A_Channel_vs_phi", "FT0A_Channel_vs_phi", kTH2D, {cfgAxis.axisPhi, cfgAxis.axisChannel}); histos.add("FT0C_Amp", "FT0C_Amp", kTH1D, {cfgAxis.axisAmplitude}); histos.add("FT0C_Amp_gaincorrected", "FT0C_Amp_gaincorrected", kTH1D, {cfgAxis.axisAmplitude}); histos.add("FT0C_Channel_vs_Amp", "FT0C_Channel_vs_Amp", kTH2D, {cfgAxis.axisChannel, cfgAxis.axisAmplitude}); histos.add("FT0C_Channel_vs_Amp_gaincorrected", "FT0C_Channel_vs_Amp_gaincorrected", kTH2D, {cfgAxis.axisChannel, cfgAxis.axisAmplitude}); + histos.add("FT0C_Channel_vs_eta", "FT0C_Channel_vs_eta", kTH2D, {cfgAxis.axisEta, cfgAxis.axisChannel}); + histos.add("FT0C_Channel_vs_phi", "FT0C_Channel_vs_phi", kTH2D, {cfgAxis.axisPhi, cfgAxis.axisChannel}); + histos.add("h3DVtxZetaPhi", "", kTH3D, {{20, -10, 10}, {16, -0.8, +0.8}, {100, 0., TwoPI}}); - if (doprocessTPCtrackEff || doprocessMFTtrackEff) { - histos.add("hGenMCdndpt", "hGenMCdndpt", kTHnSparseD, {cfgAxis.axisVtx, cfgAxis.axisMult, cfgAxis.axisEta, cfgAxis.axisPt, cfgAxis.axisSpecies}, false); - histos.add("hRecMCdndpt", "hRecMCdndpt", kTHnSparseD, {cfgAxis.axisVtx, cfgAxis.axisMult, cfgAxis.axisEta, cfgAxis.axisPt, cfgAxis.axisSpecies}, false); - auto hGenSpecies = histos.get(HIST("hGenMCdndpt")); - auto hRecSpecies = histos.get(HIST("hRecMCdndpt")); - auto* axisGen = hGenSpecies->GetAxis(4); - auto* axisRec = hRecSpecies->GetAxis(4); - for (auto i = 0U; i < speciesIds.size(); ++i) { - axisGen->SetBinLabel(i + 1, species[i].data()); - axisRec->SetBinLabel(i + 1, species[i].data()); - } - axisGen->SetBinLabel(4, "Other"); - axisRec->SetBinLabel(4, "Other"); - } - - myTrackFilter = getGlobalTrackSelectionRun3ITSMatch(cfgtrksel.cfgItsPattern, TrackSelection::GlobalTrackRun3DCAxyCut::Default); + myTrackFilter = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, + TrackSelection::GlobalTrackRun3DCAxyCut::Default); myTrackFilter.SetPtRange(cfgtrksel.cfgPtCutMin, cfgtrksel.cfgPtCutMax); myTrackFilter.SetEtaRange(-cfgtrksel.cfgEtaCut, cfgtrksel.cfgEtaCut); myTrackFilter.SetMinNCrossedRowsTPC(cfgtrksel.minNCrossedRowsTPC); @@ -368,9 +376,8 @@ struct LongrangeMaker { if (!isEventSelected(col)) { return; } - auto multiplicity = countNTracks(tracks); - auto centrality = selColCent(col); auto bc = col.bc_as(); + loadEffCorrection(bc.timestamp()); // retrieve FT0 gain info from CCDB ft0gainvalues.clear(); ft0gainvalues = {}; @@ -388,6 +395,11 @@ struct LongrangeMaker { ft0gainvalues.push_back(1.); } } + float multiplicity = countNTracks(tracks, col.posZ()); + float centrality = selColCent(col); + if (cfgfittrksel.cfgVerbosity > 0) { + LOGF(info, "Event multiplicity = %f | centrality = %f", multiplicity, centrality); + } lrcollision(bc.runNumber(), col.posZ(), multiplicity, centrality, bc.timestamp()); // track loop @@ -418,6 +430,7 @@ struct LongrangeMaker { track.dcaZ(), pid); } + histos.fill(HIST("h3DVtxZetaPhi"), col.posZ(), track.eta(), track.phi()); } // ft0 loop @@ -430,7 +443,7 @@ struct LongrangeMaker { return; } } - histos.fill(HIST("EventHist"), 15); + histos.fill(HIST("EventHist"), 16); for (std::size_t iCh = 0; iCh < ft0.channelA().size(); iCh++) { auto chanelid = ft0.channelA()[iCh]; float ampl = ft0.amplitudeA()[iCh]; @@ -447,11 +460,25 @@ struct LongrangeMaker { chanelid, gainampl, eta, - phi); + phi, + chanelid >= MinFt0aOuterRing); + if (cfgfittrksel.applyMirrorFt0a) { + int mirrorId = getFt0aDeadChannelId(chanelid); + if (mirrorId >= 0) { + lrft0atracks(lrcollision.lastIndex(), + mirrorId, + gainampl, + getEtaFT0(mirrorId, 0), + getPhiFT0(mirrorId, 0), + mirrorId >= MinFt0aOuterRing); + } + } histos.fill(HIST("FT0A_Amp"), ampl); histos.fill(HIST("FT0A_Channel_vs_Amp"), chanelid, ampl); histos.fill(HIST("FT0A_Amp_gaincorrected"), gainampl); histos.fill(HIST("FT0A_Channel_vs_Amp_gaincorrected"), chanelid, gainampl); + histos.fill(HIST("FT0A_Channel_vs_eta"), eta, chanelid); + histos.fill(HIST("FT0A_Channel_vs_phi"), phi, chanelid); } for (std::size_t iCh = 0; iCh < ft0.channelC().size(); iCh++) { auto chanelid = ft0.channelC()[iCh] + KminFt0cCell; @@ -469,11 +496,25 @@ struct LongrangeMaker { chanelid, gainampl, eta, - phi); + phi, + chanelid >= MinFt0cOuterRing); + if (cfgfittrksel.applyMirrorFt0c) { + int mirrorId = getFt0cDeadChannelId(chanelid); + if (mirrorId >= 0) { + lrft0ctracks(lrcollision.lastIndex(), + mirrorId, + gainampl, + getEtaFT0(mirrorId, 1), + getPhiFT0(mirrorId, 1), + mirrorId >= MinFt0cOuterRing); + } + } histos.fill(HIST("FT0C_Amp"), ampl); histos.fill(HIST("FT0C_Channel_vs_Amp"), chanelid, ampl); histos.fill(HIST("FT0C_Amp_gaincorrected"), gainampl); histos.fill(HIST("FT0C_Channel_vs_Amp_gaincorrected"), chanelid, gainampl); + histos.fill(HIST("FT0C_Channel_vs_eta"), eta, chanelid); + histos.fill(HIST("FT0C_Channel_vs_phi"), phi, chanelid); } } @@ -566,6 +607,7 @@ struct LongrangeMaker { } auto bc = col.template foundBC_as(); + loadEffCorrection(bc.timestamp()); auto newbc = bc; // obtain slice of compatible BCs auto bcRange = udhelpers::compatibleBCs(col, cfgSgCuts.NDtcoll(), bcs, cfgSgCuts.minNBCs()); @@ -581,8 +623,8 @@ struct LongrangeMaker { upchelpers::FITInfo fitInfo{}; udhelpers::getFITinfo(fitInfo, newbc, bcs, ft0s, fv0as, fdds); - auto multiplicity = countNTracks(tracks); - upclrcollision(bc.globalBC(), bc.runNumber(), col.posZ(), multiplicity, fitInfo.ampFT0A, fitInfo.ampFT0C, fitInfo.timeFV0A); + float multiplicity = countNTracks(tracks, col.posZ()); + upclrcollision(bc.globalBC(), bc.runNumber(), col.posZ(), multiplicity, fitInfo.ampFT0A, fitInfo.ampFT0C, fitInfo.timeFV0A, bc.timestamp()); upcsglrcollision(issgevent); if (newbc.has_zdc()) { auto zdc = newbc.zdc(); @@ -636,7 +678,8 @@ struct LongrangeMaker { chanelid, ampl, eta, - phi); + phi, + chanelid >= MinFt0aOuterRing); } for (std::size_t iCh = 0; iCh < ft0.channelC().size(); iCh++) { auto chanelid = ft0.channelC()[iCh] + KminFt0cCell; @@ -650,7 +693,8 @@ struct LongrangeMaker { chanelid, ampl, eta, - phi); + phi, + chanelid >= MinFt0cOuterRing); } } @@ -740,7 +784,7 @@ struct LongrangeMaker { { auto multiplicity = 0; for (const auto& particle : mcparticles) { - if (!isGenPartSelected(particle) || std::abs(particle.eta()) > cfgtrksel.cfgEtaCut || particle.pt() < cfgtrksel.cfgPtCutMin || particle.pt() > cfgtrksel.cfgPtCutMult) + if (!isGenPartSelected(particle) || std::abs(particle.eta()) > cfgtrksel.cfgEtaCut || particle.pt() < cfgtrksel.cfgPtCutMinForMult || particle.pt() > cfgtrksel.cfgPtCutMaxForMult) continue; multiplicity++; } @@ -753,10 +797,8 @@ struct LongrangeMaker { if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex()) { continue; } - auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex()); - auto multiplicity = countNTracks(recTracksPart); - auto centrality = selColCent(RecCol); auto bc = RecCol.bc_as(); + loadEffCorrection(bc.timestamp()); ft0gainvalues.clear(); ft0gainvalues = {}; if (cfgfittrksel.useGainCalib) { @@ -773,6 +815,9 @@ struct LongrangeMaker { ft0gainvalues.push_back(1.); } } + auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex()); + float multiplicity = countNTracks(recTracksPart, RecCol.posZ()); + float centrality = selColCent(RecCol); lrcollision(bc.runNumber(), RecCol.posZ(), multiplicity, centrality, bc.timestamp()); lrcollisionMcLabel(RecCol.mcCollisionId()); @@ -809,6 +854,7 @@ struct LongrangeMaker { track.dcaZ(), pid); } + histos.fill(HIST("h3DVtxZetaPhi"), RecCol.posZ(), track.eta(), track.phi()); } // ft0 loop @@ -827,11 +873,25 @@ struct LongrangeMaker { chanelid, gainampl, eta, - phi); + phi, + chanelid >= MinFt0aOuterRing); + if (cfgfittrksel.applyMirrorFt0a) { + int mirrorId = getFt0aDeadChannelId(chanelid); + if (mirrorId >= 0) { + lrft0atracks(lrcollision.lastIndex(), + mirrorId, + gainampl, + getEtaFT0(mirrorId, 0), + getPhiFT0(mirrorId, 0), + mirrorId >= MinFt0aOuterRing); + } + } histos.fill(HIST("FT0A_Amp"), ampl); histos.fill(HIST("FT0A_Channel_vs_Amp"), chanelid, ampl); histos.fill(HIST("FT0A_Amp_gaincorrected"), gainampl); histos.fill(HIST("FT0A_Channel_vs_Amp_gaincorrected"), chanelid, gainampl); + histos.fill(HIST("FT0A_Channel_vs_eta"), chanelid, eta); + histos.fill(HIST("FT0A_Channel_vs_phi"), chanelid, phi); } for (std::size_t iCh = 0; iCh < ft0.channelC().size(); iCh++) { auto chanelid = ft0.channelC()[iCh] + KminFt0cCell; @@ -846,11 +906,25 @@ struct LongrangeMaker { chanelid, gainampl, eta, - phi); + phi, + chanelid >= MinFt0cOuterRing); + if (cfgfittrksel.applyMirrorFt0c) { + int mirrorId = getFt0cDeadChannelId(chanelid); + if (mirrorId >= 0) { + lrft0ctracks(lrcollision.lastIndex(), + mirrorId, + gainampl, + getEtaFT0(mirrorId, 1), + getPhiFT0(mirrorId, 1), + mirrorId >= MinFt0cOuterRing); + } + } histos.fill(HIST("FT0C_Amp"), ampl); histos.fill(HIST("FT0C_Channel_vs_Amp"), chanelid, ampl); histos.fill(HIST("FT0C_Amp_gaincorrected"), gainampl); histos.fill(HIST("FT0C_Channel_vs_Amp_gaincorrected"), chanelid, gainampl); + histos.fill(HIST("FT0C_Channel_vs_eta"), chanelid, eta); + histos.fill(HIST("FT0C_Channel_vs_phi"), chanelid, phi); } } @@ -895,15 +969,22 @@ struct LongrangeMaker { } } - void processMCGen(ColMCTrueTable::iterator const& mcCollision, aod::McParticles const& mcparticles) + void processMCGen(aod::McCollisions::iterator const& mcCollision, aod::McParticles const& mcparticles) { auto multiplicity = 0; + auto multMCFT0A = 0; + auto multMCFT0C = 0; for (const auto& particle : mcparticles) { - if (!isGenPartSelected(particle) || std::abs(particle.eta()) > cfgtrksel.cfgEtaCut || particle.pt() < cfgtrksel.cfgPtCutMin || particle.pt() > cfgtrksel.cfgPtCutMult) + if (!isGenPartSelected(particle)) continue; - multiplicity++; + if (std::abs(particle.eta()) < cfgtrksel.cfgEtaCut && particle.pt() > cfgtrksel.cfgPtCutMinForMult && particle.pt() < cfgtrksel.cfgPtCutMaxForMult) + multiplicity++; + if (cfgfittrksel.cfgFt0cEtaMin < particle.eta() && particle.eta() < cfgfittrksel.cfgFt0cEtaMax) + multMCFT0C++; + if (cfgfittrksel.cfgFt0aEtaMin < particle.eta() && particle.eta() < cfgfittrksel.cfgFt0aEtaMax) + multMCFT0A++; } - lrmccollision(mcCollision.posZ(), multiplicity, mcCollision.multMCFT0A(), mcCollision.multMCFT0C()); + lrmccollision(mcCollision.posZ(), multiplicity, multMCFT0A, multMCFT0C); for (const auto& particle : mcparticles) { if (!isGenPartSelected(particle)) { @@ -923,125 +1004,6 @@ struct LongrangeMaker { } } - void processTPCtrackEff(ColMCTrueTable::iterator const& mcCollision, ColMCRecTable const& RecCols, - TrksMCRecTable const& RecTracks, aod::McParticles const& mcparticles) - { - if (std::abs(mcCollision.posZ()) >= cfgevtsel.cfgVtxCut) { - return; - } - auto multiplicity = 0; - bool atLeastOne = false; - for (const auto& RecCol : RecCols) { - if (!isEventSelected(RecCol)) - continue; - if (std::abs(RecCol.posZ()) >= cfgevtsel.cfgVtxCut) - continue; - if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex()) - continue; - if (isUseCentEst) { - multiplicity = selColCent(RecCol); - } else { - auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex()); - multiplicity = countNTracks(recTracksPart); - } - atLeastOne = true; - } - for (const auto& particle : mcparticles) { - if (!isGenPartSelected(particle) || std::abs(particle.eta()) > cfgtrksel.cfgEtaCut || particle.pt() < cfgtrksel.cfgPtCutMin || particle.pt() > cfgtrksel.cfgPtCutMax) - continue; - if (atLeastOne) { - auto pos = std::distance(speciesIds.begin(), std::find(speciesIds.begin(), speciesIds.end(), particle.pdgCode())) + 1; - histos.fill(HIST("hGenMCdndpt"), mcCollision.posZ(), multiplicity, particle.eta(), particle.pt(), pos); - } - } - for (const auto& RecCol : RecCols) { - if (!isEventSelected(RecCol)) - continue; - if (std::abs(RecCol.posZ()) >= cfgevtsel.cfgVtxCut) - continue; - if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex()) - continue; - auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex()); - for (const auto& track : recTracksPart) { - if (!track.isGlobalTrack()) - continue; - if (!myTrackFilter.IsSelected(track)) - continue; - if (!track.has_mcParticle()) - continue; - auto particle = track.mcParticle(); - if (RecCol.mcCollisionId() != particle.mcCollisionId()) - continue; - if (particle.isPhysicalPrimary()) { - auto pos = std::distance(speciesIds.begin(), std::find(speciesIds.begin(), speciesIds.end(), particle.pdgCode())) + 1; - histos.fill(HIST("hRecMCdndpt"), mcCollision.posZ(), multiplicity, particle.eta(), particle.pt(), pos); - } - } - } - } - void processMFTtrackEff(ColMCTrueTable::iterator const& mcCollision, ColMCRecTable const& RecCols, - TrksMCRecTable const& RecTracks, MftTrkMCRecTable const&, - aod::BestCollisionsFwd3d const& reassoMftTracks, aod::McParticles const& mcparticles) - { - if (std::abs(mcCollision.posZ()) >= cfgevtsel.cfgVtxCut) { - return; - } - auto multiplicity = 0; - bool atLeastOne = false; - for (const auto& RecCol : RecCols) { - if (!isEventSelected(RecCol)) - continue; - if (std::abs(RecCol.posZ()) >= cfgevtsel.cfgVtxCut) - continue; - if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex()) - continue; - if (isUseCentEst) { - multiplicity = selColCent(RecCol); - } else { - auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex()); - multiplicity = countNTracks(recTracksPart); - } - atLeastOne = true; - } - for (const auto& particle : mcparticles) { - if (!isGenPartSelected(particle) || particle.eta() > cfgmfttrksel.cfgMftEtaMax || particle.eta() < cfgmfttrksel.cfgMftEtaMin || particle.pt() < cfgmfttrksel.cfgMftPtCutMin || particle.pt() > cfgmfttrksel.cfgMftPtCutMax) - continue; - if (atLeastOne) - histos.fill(HIST("hGenMCdndpt"), mcCollision.posZ(), multiplicity, particle.eta(), particle.pt(), 1.0); - } - for (const auto& RecCol : RecCols) { - if (!isEventSelected(RecCol)) - continue; - if (std::abs(RecCol.posZ()) >= cfgevtsel.cfgVtxCut) - continue; - if (cfgevtsel.isApplyBestCollIndex && RecCol.globalIndex() != mcCollision.bestCollisionIndex()) - continue; - - auto recTracksPart = reassoMftTracks.sliceBy(perColMftTrack, RecCol.globalIndex()); - for (const auto& reassoMftTrack : recTracksPart) { - if (!isMftBestTrackSelected(reassoMftTrack)) - continue; - auto track = reassoMftTrack.mfttrack_as(); - if (!isMftTrackSelected(track)) { - continue; - } - if (cfgmfttrksel.cfgRequireCA && !track.isCA()) { - continue; - } - if (cfgmfttrksel.cfgRequireLTF && track.isCA()) { - continue; - } - if (!track.has_mcParticle()) - continue; - auto particle = track.mcParticle(); - if (RecCol.mcCollisionId() != particle.mcCollisionId()) - continue; - if (particle.isPhysicalPrimary()) - histos.fill(HIST("hRecMCdndpt"), mcCollision.posZ(), multiplicity, particle.eta(), particle.pt(), 1.0); - } - } - } - template bool isGenPartSelected(CheckGenPart const& particle) { @@ -1117,22 +1079,29 @@ struct LongrangeMaker { return false; } histos.fill(HIST("EventHist"), 14); + if (std::abs(col.posZ()) >= cfgevtsel.cfgVtxCut) { + return false; + } + histos.fill(HIST("EventHist"), 15); return true; } template - int countNTracks(countTrk const& tracks) + float countNTracks(countTrk const& tracks, float vz) { - auto nTrk = 0; + float nTrk = 0.f; for (const auto& track : tracks) { if (!track.isGlobalTrack()) continue; if (!myTrackFilter.IsSelected(track)) continue; - if (track.pt() < cfgtrksel.cfgPtCutMin || track.pt() > cfgtrksel.cfgPtCutMult) { + if (track.pt() < cfgtrksel.cfgPtCutMinForMult || track.pt() > cfgtrksel.cfgPtCutMaxForMult) { continue; } - nTrk++; + float trkeff = 1.0f; + if (cfgtrksel.applyEffCorr) + trkeff = getTrkEffCorr(vz, track.eta(), track.pt()); + nTrk += trkeff; } return nTrk; } @@ -1201,6 +1170,24 @@ struct LongrangeMaker { } } + int getFt0aDeadChannelId(int channelId) + { + if (channelId >= MinFt0aMirrorChannelOuter && channelId <= MaxFt0aMirrorChannelOuter) + return MinFt0aDeadChannelOuter + (channelId - MinFt0aMirrorChannelOuter); + else + return -1; + } + + int getFt0cDeadChannelId(int channelId) + { + if (channelId >= MinFt0cMirrorChannelOuter && channelId <= MaxFt0cMirrorChannelOuter) + return MinFt0cDeadChannelOuter + (channelId - MinFt0cMirrorChannelOuter); + else if (channelId == Ft0cMirrorChannelInner) + return Ft0cDeadChannelInner; + else + return -1; + } + double getPhiFT0(uint chno, int i) { ft0Det.calculateChannelCenter(); @@ -1390,12 +1377,40 @@ struct LongrangeMaker { return true; } + void loadEffCorrection(uint64_t timestamp) + { + if (fLoadTrkEffCorr) { + return; + } + if (cfgtrksel.cfgEffccdbPath.value.empty() == false) { + hTrkEff = ccdb->getForTimeStamp(cfgtrksel.cfgEffccdbPath, timestamp); + if (hTrkEff == nullptr) { + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgtrksel.cfgEffccdbPath.value.c_str()); + } + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgtrksel.cfgEffccdbPath.value.c_str(), (void*)hTrkEff); + } + fLoadTrkEffCorr = true; + } + + float getTrkEffCorr(float posZ, float eta, float pt) + { + if (!cfgtrksel.applyEffCorr || !hTrkEff) { + return 1.0; + } + int zBin = hTrkEff->GetXaxis()->FindBin(posZ); + int etaBin = hTrkEff->GetYaxis()->FindBin(eta); + int ptBin = hTrkEff->GetZaxis()->FindBin(pt); + float effweight = 1.0 / hTrkEff->GetBinContent(zBin, etaBin, ptBin); + if (!std::isfinite(effweight) || effweight <= 0) { + return 1.0; + } + return effweight; + } + PROCESS_SWITCH(LongrangeMaker, processData, "process All collisions", false); PROCESS_SWITCH(LongrangeMaker, processUpc, "process UPC collisions", false); PROCESS_SWITCH(LongrangeMaker, processMCGen, "process MC generated collisions", false); PROCESS_SWITCH(LongrangeMaker, processMCRec, "process MC both gen and rec collisions", false); - PROCESS_SWITCH(LongrangeMaker, processTPCtrackEff, "process TPC track efficiency", false); - PROCESS_SWITCH(LongrangeMaker, processMFTtrackEff, "process MFT track efficiency", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt b/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt index cc11633c634..e95f85f0f87 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt +++ b/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt @@ -43,8 +43,8 @@ o2physics_add_dpl_workflow(dpt-dpt-per-run-extra-qc PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore O2Physics::AnalysisCCDB COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(corr-sparse - SOURCES corrSparse.cxx +o2physics_add_dpl_workflow(corr-reso + SOURCES corrReso.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore COMPONENT_NAME Analysis) @@ -112,3 +112,8 @@ o2physics_add_dpl_workflow(corr-fit SOURCES corrFit.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore O2Physics::AnalysisCCDB O2Physics::GFWCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(casc-di-hadron-corr + SOURCES cascDiHadronCorr.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore O2Physics::AnalysisCCDB O2Physics::GFWCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/TwoParticleCorrelations/Tasks/cascDiHadronCorr.cxx b/PWGCF/TwoParticleCorrelations/Tasks/cascDiHadronCorr.cxx new file mode 100644 index 00000000000..ed9a3c4a56c --- /dev/null +++ b/PWGCF/TwoParticleCorrelations/Tasks/cascDiHadronCorr.cxx @@ -0,0 +1,1823 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file cascDiHadronCorr.cxx +/// \brief This task is to caculate cascades di-hadron correlation +/// \author Fuchun Cui(fcui@cern.ch) +/// \since jun/17/2026 + +#include "PWGCF/Core/CorrelationContainer.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace constants::math; + +// define the filtered collisions and tracks +#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; + +struct CascDiHadronCorr { + Service ccdb; + + O2_DEFINE_CONFIGURABLE(cfgCutVtxZ, float, 10.0f, "Accepted z-vertex range") + O2_DEFINE_CONFIGURABLE(cfgCutPtMin, float, 0.2f, "minimum accepted track pT") + O2_DEFINE_CONFIGURABLE(cfgCutPtMax, float, 10.0f, "maximum accepted track pT") + O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta cut") + O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5f, "max chi2 per TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCclu, float, 50.0f, "minimum TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCCrossedRows, float, 70.0f, "minimum TPC crossed rows") + O2_DEFINE_CONFIGURABLE(cfgCutITSclu, float, 5.0f, "minimum ITS clusters") + O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "max DCA to vertex z") + O2_DEFINE_CONFIGURABLE(cfgCutMerging, float, 0.0, "Merging cut on track merge") + O2_DEFINE_CONFIGURABLE(cfgSelCollByNch, bool, false, "Select collisions by Nch or centrality") + O2_DEFINE_CONFIGURABLE(cfgCutMultMin, int, 0, "Minimum multiplicity for collision") + O2_DEFINE_CONFIGURABLE(cfgCutMultMax, int, 10, "Maximum multiplicity for collision") + O2_DEFINE_CONFIGURABLE(cfgCutCentMin, float, 0.0f, "Minimum centrality for collision") + O2_DEFINE_CONFIGURABLE(cfgCutCentMax, float, 100.0f, "Maximum centrality for collision") + O2_DEFINE_CONFIGURABLE(cfgMixEventNumMin, int, 1, "Minimum number of events to mix") + O2_DEFINE_CONFIGURABLE(cfgRadiusLow, float, 0.8, "Low radius for merging cut") + O2_DEFINE_CONFIGURABLE(cfgRadiusHigh, float, 2.5, "High radius for merging cut") + O2_DEFINE_CONFIGURABLE(cfgSampleSize, double, 10, "Sample size for mixed event") + O2_DEFINE_CONFIGURABLE(cfgCentEstimator, int, 0, "0:FT0C; 1:FT0CVariant1; 2:FT0M; 3:FT0A") + O2_DEFINE_CONFIGURABLE(cfgCentTableUnavailable, bool, false, "if a dataset does not provide centrality information") + O2_DEFINE_CONFIGURABLE(cfgUseAdditionalEventCut, bool, false, "Use additional event cut on mult correlations") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoSameBunchPileup, bool, false, "rejects collisions which are associated with the same found-by-T0 bunch crossing") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoITSROFrameBorder, bool, false, "reject events at ITS ROF border") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoTimeFrameBorder, bool, false, "reject events at TF border") + O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodZvtxFT0vsPV, bool, false, "removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference, use this cut at low multiplicities with caution") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInTimeRangeStandard, bool, false, "no collisions in specified time range") + O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodITSLayersAll, bool, true, "cut time intervals with dead ITS staves") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInRofStandard, bool, false, "no other collisions in this Readout Frame with per-collision multiplicity above threshold") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoHighMultCollInPrevRof, bool, false, "veto an event if FT0C amplitude in previous ITS ROF is above threshold") + O2_DEFINE_CONFIGURABLE(cfgEvSelMultCorrelation, bool, true, "Multiplicity correlation cut") + O2_DEFINE_CONFIGURABLE(cfgEvSelV0AT0ACut, bool, true, "V0A T0A 5 sigma cut") + O2_DEFINE_CONFIGURABLE(cfgEvSelOccupancy, bool, true, "Occupancy cut") + O2_DEFINE_CONFIGURABLE(cfgCutOccupancyHigh, int, 2000, "High cut on TPC occupancy") + O2_DEFINE_CONFIGURABLE(cfgCutOccupancyLow, int, 0, "Low cut on TPC occupancy") + O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") + O2_DEFINE_CONFIGURABLE(cfgCentralityWeight, std::string, "", "CCDB path to centrality weight object") + O2_DEFINE_CONFIGURABLE(cfgLocalEfficiency, bool, false, "Use local efficiency object") + O2_DEFINE_CONFIGURABLE(cfgVerbosity, bool, false, "Verbose output") + O2_DEFINE_CONFIGURABLE(cfgUseEventWeights, bool, false, "Use event weights for mixed event") + O2_DEFINE_CONFIGURABLE(cfgUsePtOrder, bool, false, "enable trigger pT < associated pT cut") + O2_DEFINE_CONFIGURABLE(cfgUsePtOrderInMixEvent, bool, true, "enable trigger pT < associated pT cut in mixed event") + O2_DEFINE_CONFIGURABLE(cfgUseCFStepAll, bool, true, "Filling kCFStepAll") + O2_DEFINE_CONFIGURABLE(cfgSoloPtTrack, bool, false, "Skip trigger tracks that are alone in their pT bin for same process") + O2_DEFINE_CONFIGURABLE(cfgSingleSoloPtTrack, bool, false, "Skip associated tracks that are alone in their pT bin for same process, works only if cfgSoloPtTrack is enabled") + O2_DEFINE_CONFIGURABLE(cfgNSigmapid, std::vector, (std::vector{3, 3, 3}), "tpc NSigma for Pion Proton Kaon") + O2_DEFINE_CONFIGURABLE(cfgOutputXi, bool, true, "Output Xi-charged correlation") + O2_DEFINE_CONFIGURABLE(cfgOutputOmega, bool, false, "Output Omega-charged correlation") + struct : ConfigurableGroup { + O2_DEFINE_CONFIGURABLE(cfgMultCentHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 10.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultCentLowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultT0CCutEnabled, bool, false, "Enable Global multiplicity vs T0C centrality cut") + Configurable> cfgMultT0CCutPars{"cfgMultT0CCutPars", std::vector{143.04, -4.58368, 0.0766055, -0.000727796, 2.86153e-06, 23.3108, -0.36304, 0.00437706, -4.717e-05, 1.98332e-07}, "Global multiplicity vs T0C centrality cut parameter values"}; + O2_DEFINE_CONFIGURABLE(cfgMultPVT0CCutEnabled, bool, false, "Enable PV multiplicity vs T0C centrality cut") + Configurable> cfgMultPVT0CCutPars{"cfgMultPVT0CCutPars", std::vector{195.357, -6.15194, 0.101313, -0.000955828, 3.74793e-06, 30.0326, -0.43322, 0.00476265, -5.11206e-05, 2.13613e-07}, "PV multiplicity vs T0C centrality cut parameter values"}; + O2_DEFINE_CONFIGURABLE(cfgMultMultPVHighCutFunction, std::string, "[0]+[1]*x + 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultPVLowCutFunction, std::string, "[0]+[1]*x - 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultGlobalPVCutEnabled, bool, false, "Enable global multiplicity vs PV multiplicity cut") + Configurable> cfgMultGlobalPVCutPars{"cfgMultGlobalPVCutPars", std::vector{-0.140809, 0.734344, 2.77495, 0.0165935}, "PV multiplicity vs T0C centrality cut parameter values"}; + O2_DEFINE_CONFIGURABLE(cfgMultMultV0AHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 4.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultV0ALowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultV0ACutEnabled, bool, false, "Enable global multiplicity vs V0A multiplicity cut") + Configurable> cfgMultMultV0ACutPars{"cfgMultMultV0ACutPars", std::vector{534.893, 184.344, 0.423539, -0.00331436, 5.34622e-06, 871.239, 53.3735, -0.203528, 0.000122758, 5.41027e-07}, "Global multiplicity vs V0A multiplicity cut parameter values"}; + std::vector multT0CCutPars; + std::vector multPVT0CCutPars; + std::vector multGlobalPVCutPars; + std::vector multMultV0ACutPars; + TF1* fMultPVT0CCutLow = nullptr; + TF1* fMultPVT0CCutHigh = nullptr; + TF1* fMultT0CCutLow = nullptr; + TF1* fMultT0CCutHigh = nullptr; + TF1* fMultGlobalPVCutLow = nullptr; + TF1* fMultGlobalPVCutHigh = nullptr; + TF1* fMultMultV0ACutLow = nullptr; + TF1* fMultMultV0ACutHigh = nullptr; + TF1* fT0AV0AMean = nullptr; + TF1* fT0AV0ASigma = nullptr; + } cfgFuncParas; + struct : ConfigurableGroup { + std::string prefix = "cascBuilderOpts"; + // topological cut for cascade + O2_DEFINE_CONFIGURABLE(cfgcasc_radius, float, 0.5f, "minimum decay radius") + O2_DEFINE_CONFIGURABLE(cfgcasc_casccospa, float, 0.99f, "minimum cosine of pointing angle") + O2_DEFINE_CONFIGURABLE(cfgcasc_v0cospa, float, 0.99f, "minimum cosine of pointing angle") + O2_DEFINE_CONFIGURABLE(cfgcasc_dcav0topv, float, 0.01f, "minimum daughter DCA to PV") + O2_DEFINE_CONFIGURABLE(cfgcasc_dcabachtopv, float, 0.01f, "minimum bachelor DCA to PV") + O2_DEFINE_CONFIGURABLE(cfgcasc_dcaLapitopv, float, 0.1f, "minimum pion from casc->Lambda->Pi DCA to PV") + O2_DEFINE_CONFIGURABLE(cfgcasc_dcaLaprtopv, float, 0.1f, "minimum proton from casc->Lambda->Pr DCA to PV") + O2_DEFINE_CONFIGURABLE(cfgcasc_dcacascdau, float, 0.3f, "maximum DCA among cascade daughters") + O2_DEFINE_CONFIGURABLE(cfgcasc_dcav0dau, float, 1.0f, "maximum DCA among V0 daughters") + O2_DEFINE_CONFIGURABLE(cfgcasc_mlambdawindow, float, 0.04f, "Invariant mass window of lambda") + O2_DEFINE_CONFIGURABLE(cfgcasc_compmassrej, float, 0.008f, "competing mass rejection of cascades") + } cascBuilderOpts; + struct : ConfigurableGroup { + std::string prefix = "trkQualityOpts"; + O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta range for tracks") + O2_DEFINE_CONFIGURABLE(cfgCutPtDauMin, float, 0.2f, "Minimal pT for daughter tracks") + O2_DEFINE_CONFIGURABLE(cfgCutPtDauMax, float, 10.0f, "Maximal pT for daughter tracks") + // track quality selections for daughter track + O2_DEFINE_CONFIGURABLE(cfgMaxITSNCls, int, 10, "check maximum number of ITS clusters") + O2_DEFINE_CONFIGURABLE(cfgMinITSNCls, int, -1, "check minimum number of ITS clusters") + O2_DEFINE_CONFIGURABLE(cfgTPCNCls, int, 0, "check minimum number of TPC hits") + O2_DEFINE_CONFIGURABLE(cfgTPCCrossedRows, int, 0, "check minimum number of TPC crossed rows") + } trkQualityOpts; + + SliceCache cache; + + ConfigurableAxis axisVertex{"axisVertex", {10, -10, 10}, "vertex axis for histograms"}; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 10, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260}, "multiplicity axis for histograms"}; + ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, "centrality axis for histograms"}; + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt axis for histograms"}; + ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -PIHalf, PIHalf * 3}, "delta phi axis for histograms"}; + ConfigurableAxis axisDeltaEta{"axisDeltaEta", {48, -2.4, 2.4}, "delta eta axis for histograms"}; + ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt trigger axis for histograms"}; + ConfigurableAxis axisPtAssoc{"axisPtAssoc", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt associated axis for histograms"}; + ConfigurableAxis axisVtxMix{"axisVtxMix", {VARIABLE_WIDTH, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "vertex axis for mixed event histograms"}; + ConfigurableAxis axisMultMix{"axisMultMix", {VARIABLE_WIDTH, 0, 10, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260}, "multiplicity / centrality axis for mixed event histograms"}; + ConfigurableAxis axisSample{"axisSample", {cfgSampleSize, 0, cfgSampleSize}, "sample axis for histograms"}; + ConfigurableAxis axisInvMass{"axisInvMass", {VARIABLE_WIDTH, 1.7, 1.75, 1.8, 1.85, 1.9, 1.95, 2.0, 5.0}, "invariant mass axis for histograms"}; + + ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"}; + ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"}; + ConfigurableAxis axisPtEfficiency{"axisPtEfficiency", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt axis for efficiency histograms"}; + + // make the filters and cuts. + Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVtxZ); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + using FilteredCollisions = soa::Filtered>; + using FilteredTracks = soa::Filtered>; + using FilteredTracksWithMCLabels = soa::Filtered>; + using TracksPID = soa::Join; + using DaughterTracks = soa::Join; + + // Filter for MCParticle + Filter particleFilter = (nabs(aod::mcparticle::eta) < cfgCutEta) && (aod::mcparticle::pt > cfgCutPtMin) && (aod::mcparticle::pt < cfgCutPtMax); + using FilteredMcParticles = soa::Filtered; + + // Filter for MCcollisions + Filter mccollisionFilter = nabs(aod::mccollision::posZ) < cfgCutVtxZ; + using FilteredMcCollisions = soa::Filtered; + + using SmallGroupMcCollisions = soa::SmallGroups>; + + Preslice perCollision = aod::cascdata::collisionId; + PresliceUnsorted collisionPerMCCollision = aod::mccollisionlabel::mcCollisionId; + + // Corrections + TH3D* mEfficiency = nullptr; + TH1D* mCentralityWeight = nullptr; + bool correctionsLoaded = false; + + // Define the outputs + OutputObj same{"sameEvent"}; + OutputObj mixed{"mixedEvent"}; + HistogramRegistry registry{"registry"}; + + // define global variables + TRandom3* gRandom = new TRandom3(); + enum CentEstimators { + kCentFT0C = 0, + kCentFT0CVariant1, + kCentFT0M, + kCentFV0A, + // Count the total number of enum + kCount_CentEstimators + }; + enum EventType { + SameEvent = 1, + MixedEvent = 3 + }; + + // buffer for mixevents + struct ValidCollision { + struct ValidParticle { + float eta; + float phi; + float pt; + int region; + float efficiency; + float efficiencyError; + int type; + }; + float pvz; + float mult; + std::vector trigParticles; + std::vector assocParticles; + void addValidParticle(float eta, float phi, float pt, int region, float efficiency, float efficiencyError, int type) + { + ValidParticle particle{eta, phi, pt, region, efficiency, efficiencyError, type}; + + if (type == -1) { + trigParticles.push_back(particle); + } else { + assocParticles.push_back(particle); + } + } + }; + using ValidCollisions = std::vector>; + ValidCollisions validCollisions; + + double masslow = 0; + double massup = 0; + + // persistent caches + std::vector efficiencyAssociatedCache; + + std::vector cfgNSigma; + + void init(InitContext&) + { + if (cfgCentTableUnavailable && !cfgSelCollByNch) { + LOGF(fatal, "Centrality table is unavailable, cannot select collisions by centrality"); + } + const AxisSpec axisPhi{72, 0.0, constants::math::TwoPI, "#varphi"}; + const AxisSpec axisEta{40, -1., 1., "#eta"}; + o2::framework::AxisSpec axismass = axisInvMass; + int nMasssBinEdges = axismass.binEdges.size(); + masslow = axismass.binEdges[0]; + massup = axismass.binEdges[nMasssBinEdges - 1]; + cfgNSigma = cfgNSigmapid; + + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + auto now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + ccdb->setCreatedNotAfter(now); + + LOGF(info, "Starting init"); + + // Event Counter + if (doprocessSame && cfgUseAdditionalEventCut) { + registry.add("hEventCountSpecific", "Number of Event;; Count", {HistType::kTH1D, {{12, 0, 12}}}); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(1, "after sel8"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(2, "kNoSameBunchPileup"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(3, "kNoITSROFrameBorder"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(4, "kNoTimeFrameBorder"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(5, "kIsGoodZvtxFT0vsPV"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(6, "kNoCollInTimeRangeStandard"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(7, "kIsGoodITSLayersAll"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(8, "kNoCollInRofStandard"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(9, "kNoHighMultCollInPrevRof"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(10, "occupancy"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(11, "MultCorrelation"); + registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(12, "cfgEvSelV0AT0ACut"); + } + + if (cfgEvSelMultCorrelation) { + cfgFuncParas.multT0CCutPars = cfgFuncParas.cfgMultT0CCutPars; + cfgFuncParas.multPVT0CCutPars = cfgFuncParas.cfgMultPVT0CCutPars; + cfgFuncParas.multGlobalPVCutPars = cfgFuncParas.cfgMultGlobalPVCutPars; + cfgFuncParas.multMultV0ACutPars = cfgFuncParas.cfgMultMultV0ACutPars; + cfgFuncParas.fMultPVT0CCutLow = new TF1("fMultPVT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultPVT0CCutLow->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); + cfgFuncParas.fMultPVT0CCutHigh = new TF1("fMultPVT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultPVT0CCutHigh->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); + + cfgFuncParas.fMultT0CCutLow = new TF1("fMultT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultT0CCutLow->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); + cfgFuncParas.fMultT0CCutHigh = new TF1("fMultT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultT0CCutHigh->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); + + cfgFuncParas.fMultGlobalPVCutLow = new TF1("fMultGlobalPVCutLow", cfgFuncParas.cfgMultMultPVLowCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultGlobalPVCutLow->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); + cfgFuncParas.fMultGlobalPVCutHigh = new TF1("fMultGlobalPVCutHigh", cfgFuncParas.cfgMultMultPVHighCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultGlobalPVCutHigh->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); + + cfgFuncParas.fMultMultV0ACutLow = new TF1("fMultMultV0ACutLow", cfgFuncParas.cfgMultMultV0ALowCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultMultV0ACutLow->SetParameters(&(cfgFuncParas.multMultV0ACutPars[0])); + cfgFuncParas.fMultMultV0ACutHigh = new TF1("fMultMultV0ACutHigh", cfgFuncParas.cfgMultMultV0AHighCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultMultV0ACutHigh->SetParameters(&(cfgFuncParas.multMultV0ACutPars[0])); + + cfgFuncParas.fT0AV0AMean = new TF1("fT0AV0AMean", "[0]+[1]*x", 0, 200000); + cfgFuncParas.fT0AV0AMean->SetParameters(-1601.0581, 9.417652e-01); + cfgFuncParas.fT0AV0ASigma = new TF1("fT0AV0ASigma", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 200000); + cfgFuncParas.fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); + } + + std::string hCentTitle = "Centrality distribution, Estimator " + std::to_string(cfgCentEstimator); + // Make histograms to check the distributions after cuts + if (doprocessSame) { + registry.add("deltaEta_deltaPhi_same", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); // check to see the delta eta and delta phi distribution + registry.add("deltaEta_deltaPhi_mixed", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); + registry.add("Phi", "Phi", {HistType::kTH1D, {axisPhi}}); + registry.add("Eta", "Eta", {HistType::kTH1D, {axisEta}}); + registry.add("EtaCorrected", "EtaCorrected", {HistType::kTH1D, {axisEta}}); + registry.add("pT", "pT", {HistType::kTH1D, {axisPtTrigger}}); + registry.add("pTCorrected", "pTCorrected", {HistType::kTH1D, {axisPtTrigger}}); + registry.add("Nch", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); + registry.add("Nch_used", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); // histogram to see how many events are in the same and mixed event + registry.add("Centrality", hCentTitle.c_str(), {HistType::kTH1D, {{100, 0, 100}}}); + registry.add("CentralityWeighted", hCentTitle.c_str(), {HistType::kTH1D, {{100, 0, 100}}}); + registry.add("Centrality_used", hCentTitle.c_str(), {HistType::kTH1D, {{100, 0, 100}}}); // histogram to see how many events are in the same and mixed event + registry.add("zVtx", "zVtx", {HistType::kTH1D, {axisVertex}}); + registry.add("zVtx_used", "zVtx_used", {HistType::kTH1D, {axisVertex}}); + registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); + } + if (cfgSoloPtTrack && doprocessSame) { + registry.add("Nch_final_pt", "pT", {HistType::kTH1D, {axisPtTrigger}}); + registry.add("Solo_tracks_trigger", "pT", {HistType::kTH1D, {axisPtTrigger}}); + if (!cfgSingleSoloPtTrack) { + registry.add("Solo_tracks_assoc", "pT", {HistType::kTH1D, {axisPtAssoc}}); + } + } + if (cfgOutputXi || cfgOutputOmega) { + if (!cfgCentTableUnavailable) + registry.add("Invmass", "", {HistType::kTHnSparseF, {{axisPtTrigger, axisInvMass, axisEta, axisCentrality}}}); + } + + registry.add("eventcount", "bin", {HistType::kTH1F, {{4, 0, 4, "bin"}}}); // histogram to see how many events are in the same and mixed event + if (doprocessMCSame && doprocessOntheflySame) { + LOGF(fatal, "Full simulation and on-the-fly processing of same event not supported"); + } + if (doprocessMCMixed && doprocessOntheflyMixed) { + LOGF(fatal, "Full simulation and on-the-fly processing of mixed event not supported"); + } + if (doprocessMCSame) { + registry.add("MCTrue/MCeventcount", "MCeventcount", {HistType::kTH1F, {{5, 0, 5, "bin"}}}); // histogram to see how many events are in the same and mixed event + registry.get(HIST("MCTrue/MCeventcount"))->GetXaxis()->SetBinLabel(2, "same all"); + registry.get(HIST("MCTrue/MCeventcount"))->GetXaxis()->SetBinLabel(3, "same reco"); + registry.get(HIST("MCTrue/MCeventcount"))->GetXaxis()->SetBinLabel(4, "mixed all"); + registry.get(HIST("MCTrue/MCeventcount"))->GetXaxis()->SetBinLabel(5, "mixed reco"); + registry.add("MCTrue/MCCentrality", hCentTitle.c_str(), {HistType::kTH1D, {axisCentrality}}); + registry.add("MCTrue/MCNch", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); + registry.add("MCTrue/MCzVtx", "MCzVtx", {HistType::kTH1D, {axisVertex}}); + registry.add("MCTrue/MCPhi", "MCPhi", {HistType::kTH1D, {axisPhi}}); + registry.add("MCTrue/MCEta", "MCEta", {HistType::kTH1D, {axisEta}}); + registry.add("MCTrue/MCpT", "MCpT", {HistType::kTH1D, {axisPtTrigger}}); + registry.add("MCTrue/MCTrig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); + registry.add("MCTrue/MCdeltaEta_deltaPhi_same", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); // check to see the delta eta and delta phi distribution + registry.add("MCTrue/MCdeltaEta_deltaPhi_mixed", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); + } + if (doprocessMCEfficiency) { + registry.add("MCEffeventcount", "bin", {HistType::kTH1F, {{5, 0, 5, "bin"}}}); + registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(1, "All"); + registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(2, "MC"); + registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(3, "Reco Primary"); + registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(4, "Reco All"); + registry.get(HIST("MCEffeventcount"))->GetXaxis()->SetBinLabel(5, "Fake"); + } + + LOGF(info, "Initializing correlation container"); + std::vector corrAxis = {{axisSample, "Sample"}, + {axisVertex, "z-vtx (cm)"}, + {axisPtTrigger, "p_{T} (GeV/c)"}, + {axisPtAssoc, "p_{T} (GeV/c)"}, + {axisDeltaPhi, "#Delta#varphi (rad)"}, + {axisDeltaEta, "#Delta#eta"}}; + std::vector effAxis = { + {axisEtaEfficiency, "#eta"}, + {axisPtEfficiency, "p_{T} (GeV/c)"}, + {axisVertexEfficiency, "z-vtx (cm)"}, + }; + std::vector userAxis; + if (cfgOutputXi || cfgOutputOmega) + userAxis.emplace_back(axisInvMass, "m (GeV/c^2)"); + + same.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, userAxis)); + mixed.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, userAxis)); + + o2::framework::AxisSpec axisMult = axisMultiplicity; + o2::framework::AxisSpec axisVtx = axisVertex; + int nMultBins = axisMult.binEdges.size() - 1; + int nVtxBins = axisVtx.binEdges.size() - 1; + validCollisions.resize(nMultBins * nVtxBins); + + LOGF(info, "End of init"); + } + + int getMagneticField(uint64_t timestamp) + { + // Get the magnetic field + static o2::parameters::GRPMagField* grpo = nullptr; + if (grpo == nullptr) { + grpo = ccdb->getForTimeStamp("/GLO/Config/GRPMagField", timestamp); + if (grpo == nullptr) { + LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); + return 0; + } + LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); + } + return grpo->getNominalL3Field(); + } + + template + float getCentrality(TCollision const& collision) + { + float cent; + switch (cfgCentEstimator) { + case kCentFT0C: + cent = collision.centFT0C(); + break; + case kCentFT0CVariant1: + cent = collision.centFT0CVariant1(); + break; + case kCentFT0M: + cent = collision.centFT0M(); + break; + case kCentFV0A: + cent = collision.centFV0A(); + break; + default: + cent = collision.centFT0C(); + } + return cent; + } + + template + bool trackSelected(TTrack track) + { + if (std::abs(track.eta()) > cfgCutEta) { + return false; + } + if (std::abs(track.pt()) < cfgCutPtMin || std::abs(track.pt()) > cfgCutPtMax) { + return false; + } + if ((track.tpcNClsFound() < cfgCutTPCclu) || (track.tpcNClsCrossedRows() < cfgCutTPCCrossedRows) || (track.itsNCls() < cfgCutITSclu)) { + return false; + } + return true; + } + + template + bool cascSelected(TTrackCasc casc, float posX, float posY, float posZ) + { + if (std::abs(casc.eta()) > cfgCutEta) { + return false; + } + if (std::abs(casc.pt()) < cfgCutPtMin || std::abs(casc.pt()) > cfgCutPtMax) { + return false; + } + + auto bachelor = casc.template bachelor_as(); + auto posdau = casc.template posTrack_as(); + auto negdau = casc.template negTrack_as(); + + if (bachelor.pt() < trkQualityOpts.cfgCutPtDauMin.value || bachelor.pt() > trkQualityOpts.cfgCutPtDauMax.value) + return false; + if (posdau.pt() < trkQualityOpts.cfgCutPtDauMin.value || posdau.pt() > trkQualityOpts.cfgCutPtDauMax.value) + return false; + if (negdau.pt() < trkQualityOpts.cfgCutPtDauMin.value || negdau.pt() > trkQualityOpts.cfgCutPtDauMax.value) + return false; + if (std::fabs(bachelor.eta()) > trkQualityOpts.cfgCutEta.value) + return false; + if (std::fabs(posdau.eta()) > trkQualityOpts.cfgCutEta.value) + return false; + if (std::fabs(negdau.eta()) > trkQualityOpts.cfgCutEta.value) + return false; + + // track quality check + if (bachelor.itsNCls() <= trkQualityOpts.cfgMinITSNCls.value) + return false; + if (posdau.itsNCls() <= trkQualityOpts.cfgMinITSNCls.value) + return false; + if (negdau.itsNCls() <= trkQualityOpts.cfgMinITSNCls.value) + return false; + if (bachelor.itsNCls() >= trkQualityOpts.cfgMaxITSNCls.value) + return false; + if (posdau.itsNCls() >= trkQualityOpts.cfgMaxITSNCls.value) + return false; + if (negdau.itsNCls() >= trkQualityOpts.cfgMaxITSNCls.value) + return false; + + if (bachelor.tpcNClsFound() <= trkQualityOpts.cfgTPCNCls.value) + return false; + if (posdau.tpcNClsFound() <= trkQualityOpts.cfgTPCNCls.value) + return false; + if (negdau.tpcNClsFound() <= trkQualityOpts.cfgTPCNCls.value) + return false; + if (bachelor.tpcNClsCrossedRows() <= trkQualityOpts.cfgTPCCrossedRows.value) + return false; + if (posdau.tpcNClsCrossedRows() <= trkQualityOpts.cfgTPCCrossedRows.value) + return false; + if (negdau.tpcNClsCrossedRows() <= trkQualityOpts.cfgTPCCrossedRows.value) + return false; + + if (cfgOutputXi) { + if (casc.mXi() > massup || casc.mXi() < masslow) + return false; + if (casc.sign() < 0) { + if (std::fabs(bachelor.tpcNSigmaPi()) > cfgNSigma[0]) + return false; + if (std::fabs(posdau.tpcNSigmaPr()) > cfgNSigma[1]) + return false; + if (std::fabs(negdau.tpcNSigmaPi()) > cfgNSigma[0]) + return false; + if (std::fabs(casc.dcapostopv()) < cascBuilderOpts.cfgcasc_dcaLaprtopv.value) + return false; + if (std::fabs(casc.dcanegtopv()) < cascBuilderOpts.cfgcasc_dcaLapitopv.value) + return false; + } else if (casc.sign() > 0) { + if (std::fabs(bachelor.tpcNSigmaPi()) > cfgNSigma[0]) + return false; + if (std::fabs(negdau.tpcNSigmaPr()) > cfgNSigma[1]) + return false; + if (std::fabs(posdau.tpcNSigmaPi()) > cfgNSigma[0]) + return false; + if (std::fabs(casc.dcanegtopv()) < cascBuilderOpts.cfgcasc_dcaLaprtopv.value) + return false; + if (std::fabs(casc.dcapostopv()) < cascBuilderOpts.cfgcasc_dcaLapitopv.value) + return false; + } + if (casc.cascradius() < cascBuilderOpts.cfgcasc_radius.value) + return false; + if (casc.casccosPA(posX, posY, posZ) < cascBuilderOpts.cfgcasc_casccospa.value) + return false; + if (casc.v0cosPA(posX, posY, posZ) < cascBuilderOpts.cfgcasc_v0cospa.value) + return false; + if (std::fabs(casc.dcav0topv(posX, posY, posZ)) < cascBuilderOpts.cfgcasc_dcav0topv.value) + return false; + if (std::fabs(casc.dcabachtopv()) < cascBuilderOpts.cfgcasc_dcabachtopv.value) + return false; + if (casc.dcacascdaughters() > cascBuilderOpts.cfgcasc_dcacascdau.value) + return false; + if (casc.dcaV0daughters() > cascBuilderOpts.cfgcasc_dcav0dau.value) + return false; + if (std::fabs(casc.mLambda() - o2::constants::physics::MassLambda0) > cascBuilderOpts.cfgcasc_mlambdawindow.value) + return false; + } + if (cfgOutputOmega) { + if (casc.mOmega() > massup || casc.mOmega() < masslow) + return false; + if (casc.sign() < 0) { + if (std::fabs(bachelor.tpcNSigmaKa()) > cfgNSigma[2]) + return false; + if (std::fabs(posdau.tpcNSigmaPr()) > cfgNSigma[1]) + return false; + if (std::fabs(negdau.tpcNSigmaPi()) > cfgNSigma[0]) + return false; + if (std::fabs(casc.dcapostopv()) < cascBuilderOpts.cfgcasc_dcaLaprtopv.value) + return false; + if (std::fabs(casc.dcanegtopv()) < cascBuilderOpts.cfgcasc_dcaLapitopv.value) + return false; + } else if (casc.sign() > 0) { + if (std::fabs(bachelor.tpcNSigmaKa()) > cfgNSigma[2]) + return false; + if (std::fabs(negdau.tpcNSigmaPr()) > cfgNSigma[1]) + return false; + if (std::fabs(posdau.tpcNSigmaPi()) > cfgNSigma[0]) + return false; + if (std::fabs(casc.dcanegtopv()) < cascBuilderOpts.cfgcasc_dcaLaprtopv.value) + return false; + if (std::fabs(casc.dcapostopv()) < cascBuilderOpts.cfgcasc_dcaLapitopv.value) + return false; + } + if (casc.cascradius() < cascBuilderOpts.cfgcasc_radius.value) + return false; + if (casc.casccosPA(posX, posY, posZ) < cascBuilderOpts.cfgcasc_casccospa.value) + return false; + if (casc.v0cosPA(posX, posY, posZ) < cascBuilderOpts.cfgcasc_v0cospa.value) + return false; + if (std::fabs(casc.dcav0topv(posX, posY, posZ)) < cascBuilderOpts.cfgcasc_dcav0topv.value) + return false; + if (std::fabs(casc.dcabachtopv()) < cascBuilderOpts.cfgcasc_dcabachtopv.value) + return false; + if (casc.dcacascdaughters() > cascBuilderOpts.cfgcasc_dcacascdau.value) + return false; + if (casc.dcaV0daughters() > cascBuilderOpts.cfgcasc_dcav0dau.value) + return false; + if (std::fabs(casc.mLambda() - o2::constants::physics::MassLambda0) > cascBuilderOpts.cfgcasc_mlambdawindow.value) + return false; + } + return true; + } + + template + bool genTrackSelected(TTrack track) + { + if (!track.isPhysicalPrimary()) { + return false; + } + if (!track.producedByGenerator()) { + return false; + } + if (std::abs(track.eta()) > cfgCutEta) { + return false; + } + if (std::abs(track.pt()) < cfgCutPtMin || std::abs(track.pt()) > cfgCutPtMax) { + return false; + } + return true; + } + + void loadCorrection(uint64_t timestamp) + { + if (correctionsLoaded) { + return; + } + if (cfgEfficiency.value.empty() == false) { + if (cfgLocalEfficiency > 0) { + TFile* fEfficiencyTrigger = TFile::Open(cfgEfficiency.value.c_str(), "READ"); + mEfficiency = reinterpret_cast(fEfficiencyTrigger->Get("ccdb_object")); + } else { + mEfficiency = ccdb->getForTimeStamp(cfgEfficiency, timestamp); + } + if (mEfficiency == nullptr) { + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgEfficiency.value.c_str()); + } + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgEfficiency.value.c_str(), (void*)mEfficiency); + } + if (cfgCentralityWeight.value.empty() == false) { + mCentralityWeight = ccdb->getForTimeStamp(cfgCentralityWeight, timestamp); + if (mCentralityWeight == nullptr) { + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgCentralityWeight.value.c_str()); + } + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgCentralityWeight.value.c_str(), (void*)mCentralityWeight); + } + correctionsLoaded = true; + } + + bool getEfficiencyCorrection(float& weight_nue, float eta, float pt, float posZ) + { + float eff = 1.; + if (mEfficiency) { + int etaBin = mEfficiency->GetXaxis()->FindBin(eta); + int ptBin = mEfficiency->GetYaxis()->FindBin(pt); + int zBin = mEfficiency->GetZaxis()->FindBin(posZ); + eff = mEfficiency->GetBinContent(etaBin, ptBin, zBin); + } else { + eff = 1.0; + } + if (eff == 0) + return false; + weight_nue = 1. / eff; + return true; + } + + bool getCentralityWeight(float& weightCent, const float centrality) + { + float weight = 1.; + if (mCentralityWeight) + weight = mCentralityWeight->GetBinContent(mCentralityWeight->FindBin(centrality)); + else + weight = 1.0; + if (weight == 0) + return false; + weightCent = weight; + return true; + } + + // fill multiple histograms + template + void fillYield(TCollision collision, TTracks tracks) // function to fill the yield and etaphi histograms. + { + float weff1 = 1; + float vtxz = collision.posZ(); + for (auto const& track1 : tracks) { + if (!trackSelected(track1)) + continue; + if (!getEfficiencyCorrection(weff1, track1.eta(), track1.pt(), vtxz)) + continue; + registry.fill(HIST("Phi"), RecoDecay::constrainAngle(track1.phi(), 0.0)); + registry.fill(HIST("Eta"), track1.eta()); + registry.fill(HIST("EtaCorrected"), track1.eta(), weff1); + registry.fill(HIST("pT"), track1.pt()); + registry.fill(HIST("pTCorrected"), track1.pt(), weff1); + } + } + + template + float getDPhiStar(TTrack const& track1, TTrackAssoc const& track2, float radius, int magField) + { + float charge1 = track1.sign(); + float charge2 = track2.sign(); + + float phi1 = track1.phi(); + float phi2 = track2.phi(); + + float pt1 = track1.pt(); + float pt2 = track2.pt(); + + int fbSign = (magField > 0) ? 1 : -1; + + float dPhiStar = phi1 - phi2 - charge1 * fbSign * std::asin(0.075 * radius / pt1) + charge2 * fbSign * std::asin(0.075 * radius / pt2); + + if (dPhiStar > constants::math::PI) + dPhiStar = constants::math::TwoPI - dPhiStar; + if (dPhiStar < -constants::math::PI) + dPhiStar = -constants::math::TwoPI - dPhiStar; + + return dPhiStar; + } + + template + void fillCorrelations(TTracks tracks1, TCollision currentCollision, float posZ, int bin, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms (use buffer, only for mixevent) + { + float triggerWeight = 1.0f; + float associatedWeight = 1.0f; + if (currentCollision.assocParticles.size() == 0) + return; + // loop over all validCollisions in buffer + for (const auto& collision : validCollisions[bin]) { + double fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + + // Cache efficiency for particles (too many FindBin lookups) + if (mEfficiency) { + efficiencyAssociatedCache.clear(); + efficiencyAssociatedCache.reserve(collision.assocParticles.size()); + for (const auto& track2 : collision.assocParticles) { + float weff = 1.; + getEfficiencyCorrection(weff, track2.eta, track2.pt, posZ); + efficiencyAssociatedCache.push_back(weff); + } + } + + // loop over all tracks + for (const auto& track1 : tracks1) { + if (!trackSelected(track1)) + continue; + if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ)) + continue; + + int index = 0; + for (const auto& track2 : collision.assocParticles) { + if (mEfficiency) { + associatedWeight = efficiencyAssociatedCache[index]; + index++; + } + if (cfgUsePtOrder && cfgUsePtOrderInMixEvent && track1.pt() <= track2.pt) + continue; // For pt-differential correlations in mixed events, skip if the trigger pt is less than the associate pt + + float deltaPhi = RecoDecay::constrainAngle(track1.phi() - track2.phi, -PIHalf); + float deltaEta = track1.eta() - track2.eta; + + mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt, deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + registry.fill(HIST("deltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + } + } + } + } + + template + void fillCorrelationsCasc(TTracks tracks1, TCollision currentCollision, float posX, float posY, float posZ, int bin, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms (use buffer, only for mixevent) + { + float triggerWeight = 1.0f; + float associatedWeight = 1.0f; + if (currentCollision.assocParticles.size() == 0) + return; + // loop over all validCollisions in buffer + for (const auto& collision : validCollisions[bin]) { + double fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + + // Cache efficiency for particles (too many FindBin lookups) + if (mEfficiency) { + efficiencyAssociatedCache.clear(); + efficiencyAssociatedCache.reserve(collision.assocParticles.size()); + for (const auto& track2 : collision.assocParticles) { + float weff = 1.; + getEfficiencyCorrection(weff, track2.eta, track2.pt, posZ); + efficiencyAssociatedCache.push_back(weff); + } + } + + // loop over all tracks + for (const auto& track1 : tracks1) { + if (!cascSelected(track1, posX, posY, posZ)) + continue; + if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ)) + continue; + + int index = 0; + for (const auto& track2 : collision.assocParticles) { + if (mEfficiency) { + associatedWeight = efficiencyAssociatedCache[index]; + index++; + } + if (cfgUsePtOrder && cfgUsePtOrderInMixEvent && track1.pt() <= track2.pt) + continue; // For pt-differential correlations in mixed events, skip if the trigger pt is less than the associate pt + + float deltaPhi = RecoDecay::constrainAngle(track1.phi() - track2.phi, -PIHalf); + float deltaEta = track1.eta() - track2.eta; + + if (cfgOutputXi) + mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt, deltaPhi, deltaEta, track1.mXi(), eventWeight * triggerWeight * associatedWeight); + if (cfgOutputOmega) + mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt, deltaPhi, deltaEta, track1.mOmega(), eventWeight * triggerWeight * associatedWeight); + registry.fill(HIST("deltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + } + } + } + } + + template + void fillCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, int system, int magneticField, float cent, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + { + // Cache efficiency for particles (too many FindBin lookups) + if (mEfficiency) { + efficiencyAssociatedCache.clear(); + efficiencyAssociatedCache.reserve(tracks2.size()); + for (const auto& track2 : tracks2) { + float weff = 1.; + getEfficiencyCorrection(weff, track2.eta(), track2.pt(), posZ); + efficiencyAssociatedCache.push_back(weff); + } + } + + if (!cfgCentTableUnavailable) + registry.fill(HIST("Centrality_used"), cent); + registry.fill(HIST("Nch_used"), tracks1.size()); + + double fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + + float triggerWeight = 1.0f; + float associatedWeight = 1.0f; + // loop over all tracks + for (auto const& track1 : tracks1) { + + if (!trackSelected(track1)) + continue; + if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ)) + continue; + if (system == SameEvent) { + registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight); + } + + for (auto const& track2 : tracks2) { + + if (!trackSelected(track2)) + continue; + if (mEfficiency) { + associatedWeight = efficiencyAssociatedCache[track2.filteredIndex()]; + } + + if (!cfgUsePtOrder && track1.globalIndex() == track2.globalIndex()) + continue; // For pt-differential correlations, skip if the trigger and associate are the same track + if (cfgUsePtOrder && system == SameEvent && track1.pt() <= track2.pt()) + continue; // Without pt-differential correlations, skip if the trigger pt is less than the associate pt + if (cfgUsePtOrder && system == MixedEvent && cfgUsePtOrderInMixEvent && track1.pt() <= track2.pt()) + continue; // For pt-differential correlations in mixed events, skip if the trigger pt is less than the associate pt + + float deltaPhi = RecoDecay::constrainAngle(track1.phi() - track2.phi(), -PIHalf); + float deltaEta = track1.eta() - track2.eta(); + + if (std::abs(deltaEta) < cfgCutMerging) { + + double dPhiStarHigh = getDPhiStar(track1, track2, cfgRadiusHigh, magneticField); + double dPhiStarLow = getDPhiStar(track1, track2, cfgRadiusLow, magneticField); + + const double kLimit = 3.0 * cfgCutMerging; + + bool bIsBelow = false; + + if (std::abs(dPhiStarLow) < kLimit || std::abs(dPhiStarHigh) < kLimit || dPhiStarLow * dPhiStarHigh < 0) { + for (double rad(cfgRadiusLow); rad < cfgRadiusHigh; rad += 0.01) { + double dPhiStar = getDPhiStar(track1, track2, rad, magneticField); + if (std::abs(dPhiStar) < kLimit) { + bIsBelow = true; + break; + } + } + if (bIsBelow) + continue; + } + } + + // fill the right sparse and histograms + if (system == SameEvent) { + same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + registry.fill(HIST("deltaEta_deltaPhi_same"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + } else if (system == MixedEvent) { + mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + registry.fill(HIST("deltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + } + } + } + } + + template + void fillCorrelationsCasc(TTracks tracks1, TTracksAssoc tracks2, float posX, float posY, float posZ, int system, int magneticField, float cent, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + { + // Cache efficiency for particles (too many FindBin lookups) + if (mEfficiency) { + efficiencyAssociatedCache.clear(); + efficiencyAssociatedCache.reserve(tracks2.size()); + for (const auto& track2 : tracks2) { + float weff = 1.; + getEfficiencyCorrection(weff, track2.eta(), track2.pt(), posZ); + efficiencyAssociatedCache.push_back(weff); + } + } + + if (system == SameEvent) { + if (!cfgCentTableUnavailable) + registry.fill(HIST("Centrality_used"), cent); + registry.fill(HIST("Nch_used"), tracks1.size()); + } + + double fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + + float triggerWeight = 1.0f; + float associatedWeight = 1.0f; + // loop over all tracks + for (auto const& track1 : tracks1) { + + if (!cascSelected(track1, posX, posY, posZ)) + continue; + if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ)) + continue; + if (system == SameEvent) { + registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight); + if (!cfgCentTableUnavailable && cfgOutputXi) + registry.fill(HIST("Invmass"), track1.pt(), track1.mXi(), track1.eta(), cent, eventWeight * triggerWeight); + if (!cfgCentTableUnavailable && cfgOutputOmega) + registry.fill(HIST("Invmass"), track1.pt(), track1.mOmega(), track1.eta(), cent, eventWeight * triggerWeight); + } + + auto bachelor = track1.template bachelor_as(); + auto posdau = track1.template posTrack_as(); + auto negdau = track1.template negTrack_as(); + + for (auto const& track2 : tracks2) { + + if (!trackSelected(track2)) + continue; + if (mEfficiency) { + associatedWeight = efficiencyAssociatedCache[track2.filteredIndex()]; + } + + if (!cfgUsePtOrder && bachelor.globalIndex() == track2.globalIndex()) + continue; // For pt-differential correlations, skip if the trigger bachelor and associate are the same track + if (!cfgUsePtOrder && posdau.globalIndex() == track2.globalIndex()) + continue; // For pt-differential correlations, skip if the trigger posdau and associate are the same track + if (!cfgUsePtOrder && negdau.globalIndex() == track2.globalIndex()) + continue; // For pt-differential correlations, skip if the trigger negdau and associate are the same track + if (cfgUsePtOrder && system == SameEvent && track1.pt() <= track2.pt()) + continue; // Without pt-differential correlations, skip if the trigger pt is less than the associate pt + if (cfgUsePtOrder && system == MixedEvent && cfgUsePtOrderInMixEvent && track1.pt() <= track2.pt()) + continue; // For pt-differential correlations in mixed events, skip if the trigger pt is less than the associate pt + + float deltaPhi = RecoDecay::constrainAngle(track1.phi() - track2.phi(), -PIHalf); + float deltaEta = track1.eta() - track2.eta(); + + if (std::abs(deltaEta) < cfgCutMerging) { + + double dPhiStarHigh = getDPhiStar(track1, track2, cfgRadiusHigh, magneticField); + double dPhiStarLow = getDPhiStar(track1, track2, cfgRadiusLow, magneticField); + + const double kLimit = 3.0 * cfgCutMerging; + + bool bIsBelow = false; + + if (std::abs(dPhiStarLow) < kLimit || std::abs(dPhiStarHigh) < kLimit || dPhiStarLow * dPhiStarHigh < 0) { + for (double rad(cfgRadiusLow); rad < cfgRadiusHigh; rad += 0.01) { + double dPhiStar = getDPhiStar(track1, track2, rad, magneticField); + if (std::abs(dPhiStar) < kLimit) { + bIsBelow = true; + break; + } + } + if (bIsBelow) + continue; + } + } + + // fill the right sparse and histograms + if (system == SameEvent) { + registry.fill(HIST("deltaEta_deltaPhi_same"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + if (cfgOutputXi) + same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, track1.mXi(), eventWeight * triggerWeight * associatedWeight); + if (cfgOutputOmega) + same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, track1.mOmega(), eventWeight * triggerWeight * associatedWeight); + } else if (system == MixedEvent) { + registry.fill(HIST("deltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + if (cfgOutputXi) + mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, track1.mXi(), eventWeight * triggerWeight * associatedWeight); + if (cfgOutputOmega) + mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, track1.mOmega(), eventWeight * triggerWeight * associatedWeight); + } + } + } + } + + template + void fillCorrelationsExcludeSoloTracks(TTracks tracks1, TTracksAssoc tracks2, float posZ, int magneticField, float cent, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + { + std::vector tracksSkipIndices; + std::vector tracks2SkipIndices; + + findBiasedTracks(tracks1, tracksSkipIndices, posZ); + if (!cfgSingleSoloPtTrack) { // only look for the solo pt tracks if we want to skip both + findBiasedTracks(tracks2, tracks2SkipIndices, posZ); + } + + // Cache efficiency for particles (too many FindBin lookups) + if (mEfficiency) { + efficiencyAssociatedCache.clear(); + efficiencyAssociatedCache.reserve(tracks2.size()); + for (const auto& track2 : tracks2) { + float weff = 1.; + getEfficiencyCorrection(weff, track2.eta(), track2.pt(), posZ); + efficiencyAssociatedCache.push_back(weff); + } + } + + if (!cfgCentTableUnavailable) + registry.fill(HIST("Centrality_used"), cent); + registry.fill(HIST("Nch_used"), tracks1.size()); + + double fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + + float triggerWeight = 1.0f; + float associatedWeight = 1.0f; + // loop over all tracks + for (auto const& track1 : tracks1) { + + if (!trackSelected(track1)) + continue; + if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ)) + continue; + + registry.fill(HIST("Nch_final_pt"), track1.pt()); + + if (std::find(tracksSkipIndices.begin(), tracksSkipIndices.end(), track1.globalIndex()) != tracksSkipIndices.end()) { + registry.fill(HIST("Solo_tracks_trigger"), track1.pt()); + continue; // Skip the track1 if it is alone in pt bin + } + registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight); + + for (auto const& track2 : tracks2) { + + if (!trackSelected(track2)) + continue; + if (mEfficiency) { + associatedWeight = efficiencyAssociatedCache[track2.filteredIndex()]; + } + if (!cfgUsePtOrder && track1.globalIndex() == track2.globalIndex()) + continue; // For pt-differential correlations, skip if the trigger and associate are the same track + if (cfgUsePtOrder && track1.pt() <= track2.pt()) + continue; // Without pt-differential correlations, skip if the trigger pt is less than the associate pt + if (!cfgSingleSoloPtTrack) { // avoid skipping the second track if we only want one + if (std::find(tracks2SkipIndices.begin(), tracks2SkipIndices.end(), track2.globalIndex()) != tracks2SkipIndices.end()) { + registry.fill(HIST("Solo_tracks_assoc"), track2.pt()); + continue; // Skip the track2 if it is alone in pt bin + } + } + + float deltaPhi = RecoDecay::constrainAngle(track1.phi() - track2.phi(), -PIHalf); + float deltaEta = track1.eta() - track2.eta(); + + if (std::abs(deltaEta) < cfgCutMerging) { + + double dPhiStarHigh = getDPhiStar(track1, track2, cfgRadiusHigh, magneticField); + double dPhiStarLow = getDPhiStar(track1, track2, cfgRadiusLow, magneticField); + + const double kLimit = 3.0 * cfgCutMerging; + + bool bIsBelow = false; + + if (std::abs(dPhiStarLow) < kLimit || std::abs(dPhiStarHigh) < kLimit || dPhiStarLow * dPhiStarHigh < 0) { + for (double rad(cfgRadiusLow); rad < cfgRadiusHigh; rad += 0.01) { + double dPhiStar = getDPhiStar(track1, track2, rad, magneticField); + if (std::abs(dPhiStar) < kLimit) { + bIsBelow = true; + break; + } + } + if (bIsBelow) + continue; + } + } + + // fill the right sparse and histograms + same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + registry.fill(HIST("deltaEta_deltaPhi_same"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + } + } + } + + template + void fillMCCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, int system, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + { + double fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + + float triggerWeight = 1.0f; + float associatedWeight = 1.0f; + // loop over all tracks + for (auto const& track1 : tracks1) { + if (step >= CorrelationContainer::kCFStepTrackedOnlyPrim && !track1.isPhysicalPrimary()) + continue; + if (doprocessOntheflySame && !genTrackSelected(track1)) + continue; + + if (system == SameEvent && (doprocessMCSame || doprocessOntheflySame)) + registry.fill(HIST("MCTrue/MCTrig_hist"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight); + + for (auto const& track2 : tracks2) { + + if (step >= CorrelationContainer::kCFStepTrackedOnlyPrim && !track2.isPhysicalPrimary()) + continue; + if (doprocessOntheflyMixed && !genTrackSelected(track2)) + continue; + + if (!cfgUsePtOrder && track1.globalIndex() == track2.globalIndex()) + continue; // For pt-differential correlations, skip if the trigger and associate are the same track + if (cfgUsePtOrder && system == SameEvent && track1.pt() <= track2.pt()) + continue; // Without pt-differential correlations, skip if the trigger pt is less than the associate pt + if (cfgUsePtOrder && system == MixedEvent && cfgUsePtOrderInMixEvent && track1.pt() <= track2.pt()) + continue; // For pt-differential correlations in mixed events, skip if the trigger pt is less than the associate pt + + float deltaPhi = RecoDecay::constrainAngle(track1.phi() - track2.phi(), -PIHalf); + float deltaEta = track1.eta() - track2.eta(); + + // fill the right sparse and histograms + if (system == SameEvent) { + same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + if (doprocessMCSame || doprocessOntheflySame) + registry.fill(HIST("MCTrue/MCdeltaEta_deltaPhi_same"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + } else if (system == MixedEvent) { + mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + if (doprocessMCMixed || doprocessOntheflyMixed) + registry.fill(HIST("MCTrue/MCdeltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + } + } + } + } + + template + bool eventSelected(TCollision collision, const int multTrk, const float centrality, const bool fillCounter) + { + registry.fill(HIST("hEventCountSpecific"), 0.5); + if (cfgEvSelkNoSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + // rejects collisions which are associated with the same "found-by-T0" bunch crossing + // https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof + return 0; + } + if (fillCounter && cfgEvSelkNoSameBunchPileup) + registry.fill(HIST("hEventCountSpecific"), 1.5); + if (cfgEvSelkNoITSROFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + return 0; + } + if (fillCounter && cfgEvSelkNoITSROFrameBorder) + registry.fill(HIST("hEventCountSpecific"), 2.5); + if (cfgEvSelkNoTimeFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + return 0; + } + if (fillCounter && cfgEvSelkNoTimeFrameBorder) + registry.fill(HIST("hEventCountSpecific"), 3.5); + if (cfgEvSelkIsGoodZvtxFT0vsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + // removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference + // use this cut at low multiplicities with caution + return 0; + } + if (fillCounter && cfgEvSelkIsGoodZvtxFT0vsPV) + registry.fill(HIST("hEventCountSpecific"), 4.5); + if (cfgEvSelkNoCollInTimeRangeStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + // no collisions in specified time range + return 0; + } + if (fillCounter && cfgEvSelkNoCollInTimeRangeStandard) + registry.fill(HIST("hEventCountSpecific"), 5.5); + if (cfgEvSelkIsGoodITSLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + // from Jan 9 2025 AOT meeting + // cut time intervals with dead ITS staves + return 0; + } + if (fillCounter && cfgEvSelkIsGoodITSLayersAll) + registry.fill(HIST("hEventCountSpecific"), 6.5); + if (cfgEvSelkNoCollInRofStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + // no other collisions in this Readout Frame with per-collision multiplicity above threshold + return 0; + } + if (fillCounter && cfgEvSelkNoCollInRofStandard) + registry.fill(HIST("hEventCountSpecific"), 7.5); + if (cfgEvSelkNoHighMultCollInPrevRof && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + // veto an event if FT0C amplitude in previous ITS ROF is above threshold + return 0; + } + if (fillCounter && cfgEvSelkNoHighMultCollInPrevRof) + registry.fill(HIST("hEventCountSpecific"), 8.5); + auto occupancy = collision.trackOccupancyInTimeRange(); + if (cfgEvSelOccupancy && (occupancy < cfgCutOccupancyLow || occupancy > cfgCutOccupancyHigh)) + return 0; + if (fillCounter && cfgEvSelOccupancy) + registry.fill(HIST("hEventCountSpecific"), 9.5); + + auto multNTracksPV = collision.multNTracksPV(); + if (cfgEvSelMultCorrelation) { + if (cfgFuncParas.cfgMultPVT0CCutEnabled && !cfgCentTableUnavailable) { + if (multNTracksPV < cfgFuncParas.fMultPVT0CCutLow->Eval(centrality)) + return 0; + if (multNTracksPV > cfgFuncParas.fMultPVT0CCutHigh->Eval(centrality)) + return 0; + } + if (cfgFuncParas.cfgMultT0CCutEnabled && !cfgCentTableUnavailable) { + if (multTrk < cfgFuncParas.fMultT0CCutLow->Eval(centrality)) + return 0; + if (multTrk > cfgFuncParas.fMultT0CCutHigh->Eval(centrality)) + return 0; + } + if (cfgFuncParas.cfgMultGlobalPVCutEnabled) { + if (multTrk < cfgFuncParas.fMultGlobalPVCutLow->Eval(multNTracksPV)) + return 0; + if (multTrk > cfgFuncParas.fMultGlobalPVCutHigh->Eval(multNTracksPV)) + return 0; + } + if (cfgFuncParas.cfgMultMultV0ACutEnabled) { + if (collision.multFV0A() < cfgFuncParas.fMultMultV0ACutLow->Eval(multTrk)) + return 0; + if (collision.multFV0A() > cfgFuncParas.fMultMultV0ACutHigh->Eval(multTrk)) + return 0; + } + } + if (fillCounter && cfgEvSelMultCorrelation) + registry.fill(HIST("hEventCountSpecific"), 10.5); + + // V0A T0A 5 sigma cut + float sigma = 5.0; + if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - cfgFuncParas.fT0AV0AMean->Eval(collision.multFT0A())) > sigma * cfgFuncParas.fT0AV0ASigma->Eval(collision.multFT0A()))) + return 0; + if (fillCounter && cfgEvSelV0AT0ACut) + registry.fill(HIST("hEventCountSpecific"), 11.5); + + return 1; + } + + void findBiasedTracks(FilteredTracks const& tracks, std::vector& tracksSkipIndices, float posZ) + { + // Find the tracks that are alone in their pT bin + tracksSkipIndices.clear(); + static const std::vector& ptBins = axisPtTrigger.value; + static const size_t nPtBins = ptBins.size() - 1; + + std::vector numberOfTracksInBin(nPtBins, 0); + std::vector firstTrackIndex(nPtBins, -1); + + float triggerWeight = 1.0f; + + // Count tracks per bin and remember the first track id in each bin + for (const auto& track : tracks) { + if (!trackSelected(track)) + continue; + if (!getEfficiencyCorrection(triggerWeight, track.eta(), track.pt(), posZ)) + continue; + double pt = track.pt(); + auto binEdgeIt = std::upper_bound(ptBins.begin(), ptBins.end(), pt); + if (binEdgeIt == ptBins.begin() || binEdgeIt == ptBins.end()) + continue; // skip pt bins out of range + + size_t binIndex = static_cast(std::distance(ptBins.begin(), binEdgeIt) - 1); + + if (numberOfTracksInBin[binIndex] == 0) { + firstTrackIndex[binIndex] = track.globalIndex(); + } + ++numberOfTracksInBin[binIndex]; + } + + // Collect track ids for bins that have exactly one track + for (size_t i = 0; i < nPtBins; ++i) { + if (numberOfTracksInBin[i] == 1) { + tracksSkipIndices.push_back(firstTrackIndex[i]); + } + } + } + + void processSame(FilteredCollisions::iterator const& collision, FilteredTracks const& tracks, aod::CascDatas const& cascades, aod::BCsWithTimestamps const&, DaughterTracks const&) + { + if (!collision.sel8()) + return; + auto bc = collision.bc_as(); + float cent = -1.; + float weightCent = 1.0f; + if (!cfgCentTableUnavailable) { + cent = getCentrality(collision); + } + if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent, true)) + return; + loadCorrection(bc.timestamp()); + if (!cfgCentTableUnavailable) { + getCentralityWeight(weightCent, cent); + registry.fill(HIST("Centrality"), cent); + registry.fill(HIST("CentralityWeighted"), cent, weightCent); + } + registry.fill(HIST("Nch"), tracks.size()); + registry.fill(HIST("zVtx"), collision.posZ()); + + if (cfgSelCollByNch && (tracks.size() < cfgCutMultMin || tracks.size() >= cfgCutMultMax)) { + return; + } + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent < cfgCutCentMin || cent >= cfgCutCentMax)) { + return; + } + + registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin + fillYield(collision, tracks); + + same->fillEvent(tracks.size(), CorrelationContainer::kCFStepReconstructed); + if (!cfgSoloPtTrack) { + if (!cfgOutputOmega && !cfgOutputXi) + fillCorrelations(tracks, tracks, collision.posZ(), SameEvent, getMagneticField(bc.timestamp()), cent, weightCent); + else + fillCorrelationsCasc(cascades, tracks, collision.posX(), collision.posY(), collision.posZ(), SameEvent, getMagneticField(bc.timestamp()), cent, weightCent); + } else { + fillCorrelationsExcludeSoloTracks(tracks, tracks, collision.posZ(), getMagneticField(bc.timestamp()), cent, weightCent); + } + } + PROCESS_SWITCH(CascDiHadronCorr, processSame, "Process same event", true); + + // the process for filling the mixed events + void processMixed(FilteredCollisions const& collisions, FilteredTracks const& tracks, aod::BCsWithTimestamps const&) + { + + auto getTracksSize = [&tracks, this](FilteredCollisions::iterator const& collision) { + auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); + auto mult = associatedTracks.size(); + return mult; + }; + + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; + + auto tracksTuple = std::make_tuple(tracks, tracks); + Pair pairs{binningOnVtxAndMult, cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, tracks1, collision2, tracks2] = *it; + if (!collision1.sel8() || !collision2.sel8()) + continue; + + if (cfgSelCollByNch && (tracks1.size() < cfgCutMultMin || tracks1.size() >= cfgCutMultMax)) + continue; + + if (cfgSelCollByNch && (tracks2.size() < cfgCutMultMin || tracks2.size() >= cfgCutMultMax)) + continue; + + float cent1 = -1; + float cent2 = -1; + if (!cfgCentTableUnavailable) { + cent1 = getCentrality(collision1); + cent2 = getCentrality(collision2); + } + if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), cent1, false)) + continue; + if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), cent2, false)) + continue; + + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent1 < cfgCutCentMin || cent1 >= cfgCutCentMax)) + continue; + + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent2 < cfgCutCentMin || cent2 >= cfgCutCentMax)) + continue; + + registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin + auto bc = collision1.bc_as(); + loadCorrection(bc.timestamp()); + float eventWeight = 1.0f; + if (cfgUseEventWeights) { + eventWeight = 1.0f / it.currentWindowNeighbours(); + } + float weightCent = 1.0f; + if (!cfgCentTableUnavailable) + getCentralityWeight(weightCent, cent1); + + if (!cfgOutputOmega && !cfgOutputXi) + fillCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, getMagneticField(bc.timestamp()), cent1, eventWeight * weightCent); + } + } + + PROCESS_SWITCH(CascDiHadronCorr, processMixed, "Process mixed events", false); + + void processMixedCasc(FilteredCollisions const& collisions, FilteredTracks const& tracks, aod::CascDatas const& cascades, aod::BCsWithTimestamps const&, DaughterTracks const&) + { + + auto getTracksSize = [&tracks, this](FilteredCollisions::iterator const& collision) { + auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); + auto mult = associatedTracks.size(); + return mult; + }; + + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; + + auto tracksTuple = std::make_tuple(cascades, tracks); + Pair pairs{binningOnVtxAndMult, cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, tracks1, collision2, tracks2] = *it; + if (!collision1.sel8() || !collision2.sel8()) + continue; + + if (cfgSelCollByNch && (tracks1.size() < cfgCutMultMin || tracks1.size() >= cfgCutMultMax)) + continue; + + if (cfgSelCollByNch && (tracks2.size() < cfgCutMultMin || tracks2.size() >= cfgCutMultMax)) + continue; + + float cent1 = -1; + float cent2 = -1; + if (!cfgCentTableUnavailable) { + cent1 = getCentrality(collision1); + cent2 = getCentrality(collision2); + } + if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), cent1, false)) + continue; + if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), cent2, false)) + continue; + + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent1 < cfgCutCentMin || cent1 >= cfgCutCentMax)) + continue; + + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent2 < cfgCutCentMin || cent2 >= cfgCutCentMax)) + continue; + + registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin + auto bc = collision1.bc_as(); + loadCorrection(bc.timestamp()); + float eventWeight = 1.0f; + if (cfgUseEventWeights) { + eventWeight = 1.0f / it.currentWindowNeighbours(); + } + float weightCent = 1.0f; + if (!cfgCentTableUnavailable) + getCentralityWeight(weightCent, cent1); + + fillCorrelationsCasc(tracks1, tracks2, collision1.posX(), collision1.posY(), collision1.posZ(), MixedEvent, getMagneticField(bc.timestamp()), cent1, eventWeight * weightCent); + } + } + PROCESS_SWITCH(CascDiHadronCorr, processMixedCasc, "Process mixed events", true); + + // the process for filling the mixed events by buffer + void processMixedBuffer(FilteredCollisions::iterator const& collision, FilteredTracks const& tracks) + { + ValidCollision currentCollision; + int nBinsMult = 0; + int binMult = 0; + int nBinsVtxZ = 0; + int binVtxZ = 0; + currentCollision.pvz = collision.posZ(); + currentCollision.mult = tracks.size(); + + nBinsMult = registry.get(HIST("Nch"))->GetNbinsX(); + binMult = registry.get(HIST("Nch"))->GetXaxis()->FindBin(tracks.size()) - 1; + nBinsVtxZ = registry.get(HIST("zVtx"))->GetNbinsX(); + binVtxZ = registry.get(HIST("zVtx"))->GetXaxis()->FindBin(collision.posZ()) - 1; + if (binVtxZ < 0 || binVtxZ > nBinsVtxZ - 1 || binMult < 0 || binMult > nBinsMult - 1) + return; + int bin = binMult * nBinsVtxZ + binVtxZ; + + if (!collision.sel8()) + return; + + if (cfgSelCollByNch && tracks.size() < cfgCutMultMin) + return; + + float cent = -1; + if (!cfgCentTableUnavailable) { + cent = getCentrality(collision); + } + if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent, false)) + return; + + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent < cfgCutCentMin || cent >= cfgCutCentMax)) + return; + + float weightCent = 1.0f; + if (!cfgCentTableUnavailable) + getCentralityWeight(weightCent, cent); + + for (const auto& track : tracks) { + if (!trackSelected(track)) + continue; + currentCollision.addValidParticle(track.eta(), track.phi(), track.pt(), 0, 1, 1, 1); + } + + fillCorrelations(tracks, currentCollision, collision.posZ(), bin, weightCent); + if (validCollisions[bin].size() >= static_cast(cfgMixEventNumMin)) { + validCollisions[bin].erase(validCollisions[bin].begin()); + } + validCollisions[bin].push_back(currentCollision); + } + + PROCESS_SWITCH(CascDiHadronCorr, processMixedBuffer, "Process mixed events", false); + + void processMixedBufferCasc(FilteredCollisions::iterator const& collision, FilteredTracks const& tracks, aod::CascDatas const& cascades, DaughterTracks const&) + { + ValidCollision currentCollision; + int nBinsMult = 0; + int binMult = 0; + int nBinsVtxZ = 0; + int binVtxZ = 0; + currentCollision.pvz = collision.posZ(); + currentCollision.mult = tracks.size(); + + nBinsMult = registry.get(HIST("Nch"))->GetNbinsX(); + binMult = registry.get(HIST("Nch"))->GetXaxis()->FindBin(tracks.size()) - 1; + nBinsVtxZ = registry.get(HIST("zVtx"))->GetNbinsX(); + binVtxZ = registry.get(HIST("zVtx"))->GetXaxis()->FindBin(collision.posZ()) - 1; + if (binVtxZ < 0 || binVtxZ > nBinsVtxZ - 1 || binMult < 0 || binMult > nBinsMult - 1) + return; + int bin = binMult * nBinsVtxZ + binVtxZ; + + if (!collision.sel8()) + return; + + if (cfgSelCollByNch && tracks.size() < cfgCutMultMin) + return; + + float cent = -1; + if (!cfgCentTableUnavailable) { + cent = getCentrality(collision); + } + if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent, false)) + return; + + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent < cfgCutCentMin || cent >= cfgCutCentMax)) + return; + + float weightCent = 1.0f; + if (!cfgCentTableUnavailable) + getCentralityWeight(weightCent, cent); + + for (const auto& track : tracks) { + if (!trackSelected(track)) + continue; + currentCollision.addValidParticle(track.eta(), track.phi(), track.pt(), 0, 1, 1, 1); + } + + fillCorrelationsCasc(cascades, currentCollision, collision.posX(), collision.posY(), collision.posZ(), bin, weightCent); + if (validCollisions[bin].size() >= static_cast(cfgMixEventNumMin)) { + validCollisions[bin].erase(validCollisions[bin].begin()); + } + validCollisions[bin].push_back(currentCollision); + } + PROCESS_SWITCH(CascDiHadronCorr, processMixedBufferCasc, "Process mixed events", true); + + int getSpecies(int pdgCode) + { + switch (std::abs(pdgCode)) { + case PDG_t::kXiMinus: // Xi + return 1; + case PDG_t::kOmegaMinus: // Omega + return 2; + default: // NOTE. The efficiency histogram is hardcoded to contain 4 species. Anything special will have the last slot. + return 3; + } + } + + void processMCEfficiency(FilteredMcCollisions::iterator const& mcCollision, soa::SmallGroups> const& collisions, soa::Join const& Cascades, FilteredMcParticles const& mcParticles, DaughterTracks const&) + { + registry.fill(HIST("MCEffeventcount"), 0.5); + if (cfgSelCollByNch && (mcParticles.size() < cfgCutMultMin || mcParticles.size() >= cfgCutMultMax)) { + return; + } + // Primaries + for (const auto& mcParticle : mcParticles) { + if (mcParticle.isPhysicalPrimary()) { + if ((cfgOutputXi && getSpecies(mcParticle.pdgCode()) == getSpecies(PDG_t::kXiMinus)) || (cfgOutputOmega && getSpecies(mcParticle.pdgCode()) == getSpecies(PDG_t::kOmegaMinus))) { + registry.fill(HIST("MCEffeventcount"), 1.5); + same->getTrackHistEfficiency()->Fill(CorrelationContainer::MC, mcParticle.eta(), mcParticle.pt(), getSpecies(mcParticle.pdgCode()), 0., mcCollision.posZ()); + } + } + } + for (const auto& collision : collisions) { + auto groupedCascades = Cascades.sliceBy(perCollision, collision.globalIndex()); + if (cfgVerbosity) { + LOGF(info, " Reconstructed collision at vtx-z = %f", collision.posZ()); + LOGF(info, " which has %d tracks", groupedCascades.size()); + } + + for (const auto& casc : groupedCascades) { + if (!cascSelected(casc, collision.posX(), collision.posY(), collision.posZ())) + continue; + if (casc.has_mcParticle()) { + auto mcParticle = casc.mcParticle_as(); + if (mcParticle.isPhysicalPrimary()) { + registry.fill(HIST("MCEffeventcount"), 2.5); + same->getTrackHistEfficiency()->Fill(CorrelationContainer::RecoPrimaries, mcParticle.eta(), mcParticle.pt(), getSpecies(mcParticle.pdgCode()), 0., mcCollision.posZ()); + } + registry.fill(HIST("MCEffeventcount"), 3.5); + same->getTrackHistEfficiency()->Fill(CorrelationContainer::RecoAll, mcParticle.eta(), mcParticle.pt(), (cfgOutputXi * getSpecies(PDG_t::kXiMinus) + cfgOutputOmega * getSpecies(PDG_t::kOmegaMinus)), 0., mcCollision.posZ()); + } else { + // fake casc + registry.fill(HIST("MCEffeventcount"), 4.5); + same->getTrackHistEfficiency()->Fill(CorrelationContainer::Fake, casc.eta(), casc.pt(), 0, 0., mcCollision.posZ()); + } + } + } + } + PROCESS_SWITCH(CascDiHadronCorr, processMCEfficiency, "MC: Extract efficiencies", false); + + void processMCSame(FilteredMcCollisions::iterator const& mcCollision, FilteredMcParticles const& mcParticles, SmallGroupMcCollisions const& collisions) + { + if (cfgVerbosity) { + LOGF(info, "processMCSame. MC collision: %d, particles: %d, collisions: %d", mcCollision.globalIndex(), mcParticles.size(), collisions.size()); + } + + float cent = -1; + if (!cfgCentTableUnavailable) { + for (const auto& collision : collisions) { + cent = getCentrality(collision); + } + } + + if (cfgSelCollByNch && (mcParticles.size() < cfgCutMultMin || mcParticles.size() >= cfgCutMultMax)) { + return; + } + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent < cfgCutCentMin || cent >= cfgCutCentMax)) { + return; + } + + registry.fill(HIST("MCTrue/MCeventcount"), SameEvent); // because its same event i put it in the 1 bin + if (!cfgCentTableUnavailable) + registry.fill(HIST("MCTrue/MCCentrality"), cent); + registry.fill(HIST("MCTrue/MCNch"), mcParticles.size()); + registry.fill(HIST("MCTrue/MCzVtx"), mcCollision.posZ()); + for (const auto& mcParticle : mcParticles) { + if (mcParticle.isPhysicalPrimary()) { + registry.fill(HIST("MCTrue/MCPhi"), mcParticle.phi()); + registry.fill(HIST("MCTrue/MCEta"), mcParticle.eta()); + registry.fill(HIST("MCTrue/MCpT"), mcParticle.pt()); + } + } + + if (cfgUseCFStepAll) { + same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepAll); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f); + } + + if (collisions.size() == 0) { + return; + } + + registry.fill(HIST("MCTrue/MCeventcount"), 2.5); + same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepTrackedOnlyPrim); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f); + } + PROCESS_SWITCH(CascDiHadronCorr, processMCSame, "Process MC same event", false); + + void processMCMixed(FilteredMcCollisions const& mcCollisions, FilteredMcParticles const& mcParticles, SmallGroupMcCollisions const& collisions) + { + auto getTracksSize = [&mcParticles, this](FilteredMcCollisions::iterator const& mcCollision) { + auto associatedTracks = mcParticles.sliceByCached(o2::aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), this->cache); + auto mult = associatedTracks.size(); + return mult; + }; + + using MixedBinning = FlexibleBinningPolicy, o2::aod::mccollision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; + + auto tracksTuple = std::make_tuple(mcParticles, mcParticles); + Pair pairs{binningOnVtxAndMult, cfgMixEventNumMin, -1, mcCollisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, tracks1, collision2, tracks2] = *it; + + if (cfgSelCollByNch && (tracks1.size() < cfgCutMultMin || tracks1.size() >= cfgCutMultMax)) + continue; + + if (cfgSelCollByNch && (tracks2.size() < cfgCutMultMin || tracks2.size() >= cfgCutMultMax)) + continue; + + auto groupedCollisions = collisions.sliceBy(collisionPerMCCollision, collision1.globalIndex()); + if (cfgVerbosity > 0) { + LOGF(info, "Found %d related collisions", groupedCollisions.size()); + } + float cent = -1; + if (!cfgCentTableUnavailable) { + for (const auto& collision : groupedCollisions) { + cent = getCentrality(collision); + } + } + + if (!cfgSelCollByNch && !cfgCentTableUnavailable && groupedCollisions.size() != 0 && (cent < cfgCutCentMin || cent >= cfgCutCentMax)) + continue; + + registry.fill(HIST("MCTrue/MCeventcount"), MixedEvent); // fill the mixed event in the 3 bin + float eventWeight = 1.0f; + if (cfgUseEventWeights) { + eventWeight = 1.0f / it.currentWindowNeighbours(); + } + + if (cfgUseCFStepAll) + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, eventWeight); + + if (groupedCollisions.size() == 0) { + continue; + } + + registry.fill(HIST("MCTrue/MCeventcount"), 4.5); + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, eventWeight); + } + } + PROCESS_SWITCH(CascDiHadronCorr, processMCMixed, "Process MC mixed events", false); + void processOntheflySame(aod::McCollisions::iterator const& mcCollision, aod::McParticles const& mcParticles) + { + if (cfgVerbosity) { + LOGF(info, "processOntheflySame. MC collision: %d, particles: %d", mcCollision.globalIndex(), mcParticles.size()); + } + + if (cfgSelCollByNch && (mcParticles.size() < cfgCutMultMin || mcParticles.size() >= cfgCutMultMax)) { + return; + } + + registry.fill(HIST("MCTrue/MCeventcount"), SameEvent); // because its same event i put it in the 1 bin + registry.fill(HIST("MCTrue/MCNch"), mcParticles.size()); + registry.fill(HIST("MCTrue/MCzVtx"), mcCollision.posZ()); + for (const auto& mcParticle : mcParticles) { + if (mcParticle.isPhysicalPrimary()) { + registry.fill(HIST("MCTrue/MCPhi"), mcParticle.phi()); + registry.fill(HIST("MCTrue/MCEta"), mcParticle.eta()); + registry.fill(HIST("MCTrue/MCpT"), mcParticle.pt()); + } + } + + if (cfgUseCFStepAll) { + same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepAll); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f); + } + + same->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepTrackedOnlyPrim); + fillMCCorrelations(mcParticles, mcParticles, mcCollision.posZ(), SameEvent, 1.0f); + } + PROCESS_SWITCH(CascDiHadronCorr, processOntheflySame, "Process on-the-fly same event", false); + + void processOntheflyMixed(aod::McCollisions const& mcCollisions, aod::McParticles const& mcParticles) + { + auto getTracksSize = [&mcParticles, this](aod::McCollisions::iterator const& mcCollision) { + auto associatedTracks = mcParticles.sliceByCached(o2::aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), this->cache); + auto mult = associatedTracks.size(); + return mult; + }; + + using MixedBinning = FlexibleBinningPolicy, o2::aod::mccollision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; + + auto tracksTuple = std::make_tuple(mcParticles, mcParticles); + Pair pairs{binningOnVtxAndMult, cfgMixEventNumMin, -1, mcCollisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, tracks1, collision2, tracks2] = *it; + + if (cfgSelCollByNch && (tracks1.size() < cfgCutMultMin || tracks1.size() >= cfgCutMultMax)) + continue; + + if (cfgSelCollByNch && (tracks2.size() < cfgCutMultMin || tracks2.size() >= cfgCutMultMax)) + continue; + + registry.fill(HIST("MCTrue/MCeventcount"), MixedEvent); // fill the mixed event in the 3 bin + float eventWeight = 1.0f; + if (cfgUseEventWeights) { + eventWeight = 1.0f / it.currentWindowNeighbours(); + } + + if (cfgUseCFStepAll) + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, eventWeight); + + fillMCCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, eventWeight); + } + } + PROCESS_SWITCH(CascDiHadronCorr, processOntheflyMixed, "Process on-the-fly mixed events", false); +}; +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + }; +} diff --git a/PWGCF/TwoParticleCorrelations/Tasks/corrFit.cxx b/PWGCF/TwoParticleCorrelations/Tasks/corrFit.cxx index dc343428a4c..cfe62237bb1 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/corrFit.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/corrFit.cxx @@ -10,7 +10,7 @@ // or submit itself to any jurisdiction. /// \file corrFit.cxx -/// \brief Ultra long range correlation using forward FIT detectors and TPC, with foxus on multiplicity dependence +/// \brief Ultra long range correlation using forward FIT detectors and TPC, with focus on multiplicity dependence /// \author Thor Jensen (thor.kjaersgaard.jensen@cern.ch) #include "PWGCF/Core/CorrelationContainer.h" @@ -21,6 +21,9 @@ #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponseITS.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" #include @@ -31,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +43,7 @@ #include #include #include +#include #include #include @@ -61,9 +66,11 @@ using namespace o2::aod::rctsel; using namespace constants::math; #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; +static constexpr float LongArrayFloat[3][20] = {{1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}, {2.1, 2.2, 2.3, -2.1, -2.2, -2.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}, {3.1, 3.2, 3.3, -3.1, -3.2, -3.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}}; +static constexpr int LongArrayInt[3][20] = {{1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1}, {2, 2, 2, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1}, {3, 3, 3, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1}}; struct CorrFit { - + o2::aod::ITSResponse itsResponse; Service ccdb; O2_DEFINE_CONFIGURABLE(cfgUseAdditionalEventCut, bool, true, "Use additional event cut on mult correlations") @@ -76,6 +83,7 @@ struct CorrFit { O2_DEFINE_CONFIGURABLE(cfgMinMultForCorrelations, int, 0, "minimum multiplicity for correlations") O2_DEFINE_CONFIGURABLE(cfgMaxMultForCorrelations, int, 20, "maximum multiplicity for correlations") O2_DEFINE_CONFIGURABLE(cfgRefMultiplicity, bool, false, "Use multiplicity of reference tracks for multiplicity correlation cut instead of Nch") + Configurable> cfgRunRemoveList{"cfgRunRemoveList", std::vector{-1}, "excluded run numbers"}; struct : ConfigurableGroup{ O2_DEFINE_CONFIGURABLE(cfgPtCutMin, float, 0.2f, "minimum accepted track pT") @@ -85,35 +93,13 @@ struct CorrFit { O2_DEFINE_CONFIGURABLE(cfgCutTPCclu, float, 50.0f, "minimum TPC clusters") O2_DEFINE_CONFIGURABLE(cfgCutTPCCrossedRows, float, 70.0f, "minimum TPC crossed rows") O2_DEFINE_CONFIGURABLE(cfgCutITSclu, float, 5.0f, "minimum ITS clusters") - O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "max DCA to vertex z") - - } cfgTrackCuts; + O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "max DCA to vertex z")} cfgTrackCuts; struct : ConfigurableGroup{ - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoSameBunchPileup, bool, false, "rejects collisions which are associated with the same found-by-T0 bunch crossing") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoITSROFrameBorder, bool, false, "reject events at ITS ROF border") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoTimeFrameBorder, bool, false, "reject events at TF border") - O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodZvtxFT0vsPV, bool, false, "removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference, use this cut at low multiplicities with caution") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInTimeRangeStandard, bool, false, "no collisions in specified time range") - O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodITSLayer0123, bool, true, "cut time intervals with dead ITS layers 0,1,2,3") - O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodITSLayersAll, bool, false, "cut time intervals with dead ITS staves") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInRofStandard, bool, false, "no other collisions in this Readout Frame with per-collision multiplicity above threshold") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoHighMultCollInPrevRof, bool, false, "veto an event if FT0C amplitude in previous ITS ROF is above threshold") - O2_DEFINE_CONFIGURABLE(cfgEvSelMultCorrelation, bool, false, "Multiplicity correlation cut") - O2_DEFINE_CONFIGURABLE(cfgEvSelV0AT0ACut, bool, false, "V0A T0A 5 sigma cut") - O2_DEFINE_CONFIGURABLE(cfgEvSelOccupancy, bool, false, "Occupancy cut") - O2_DEFINE_CONFIGURABLE(cfgCutOccupancyHigh, int, 2000, "High cut on TPC occupancy") - O2_DEFINE_CONFIGURABLE(cfgCutOccupancyLow, int, 0, "Low cut on TPC occupancy") - - } cfgEventSelection; + O2_DEFINE_CONFIGURABLE(cfgCutOccupancyHigh, int, 2000, "High cut on TPC occupancy") + O2_DEFINE_CONFIGURABLE(cfgCutOccupancyLow, int, 0, "Low cut on TPC occupancy")} cfgEventSelection; - struct : ConfigurableGroup{ - O2_DEFINE_CONFIGURABLE(cfgSystematicsVariation, bool, false, "Enable systematics variation for track cuts") - O2_DEFINE_CONFIGURABLE(cfgSystematicsCutChi2prTPCcls, float, 3.0f, "max chi2 per TPC clusters for systematics variation") - O2_DEFINE_CONFIGURABLE(cfgSystematicsCutTPCclu, float, 40.0f, "minimum TPC clusters for systematics variation") - O2_DEFINE_CONFIGURABLE(cfgSystematicsCutTPCCrossedRows, float, 60.0f, "minimum TPC crossed rows for systematics variation") - O2_DEFINE_CONFIGURABLE(cfgSystematicsCutITSclu, float, 4.0f, "minimum ITS clusters for systematics variation") - O2_DEFINE_CONFIGURABLE(cfgSystematicsCutDCAz, float, 1.5f, "max DCA to vertex z for systematics variation")} cfgSystematics; + Configurable> cfgUseEventCuts{"cfgUseEventCuts", {LongArrayInt[0], 14, 1, {"Filtered Events", "Sel8", "kNoTimeFrameBorder", "kNoITSROFrameBorder", "kNoSameBunchPileup", "kIsGoodZvtxFT0vsPV", "kNoCollInTimeRangeStandard", "kIsGoodITSLayersAll", "kIsGoodITSLayer0123", "kNoCollInRofStandard", "kNoHighMultCollInPrevRof", "Occupancy", "Multcorrelation", "T0AV0ACut"}, {"EvCuts"}}, "Labeled array (int) for various cuts on resonances"}; O2_DEFINE_CONFIGURABLE(cfgMinMixEventNum, int, 5, "Minimum number of events to mix") O2_DEFINE_CONFIGURABLE(cfgMergingCut, float, 0.02, "Merging cut on track merge") @@ -127,6 +113,7 @@ struct CorrFit { O2_DEFINE_CONFIGURABLE(cfgLocalEfficiency, bool, false, "Use local efficiency object") O2_DEFINE_CONFIGURABLE(cfgLocalEfficiencyNch, bool, false, "Use local multiplicity dependent efficiency object"); O2_DEFINE_CONFIGURABLE(cfgUseEventWeights, bool, false, "Use event weights for mixed event") + O2_DEFINE_CONFIGURABLE(cfgCentEstimator, int, 0, "0:FT0C; 1:FT0CVariant1; 2:FT0M; 3:FT0A") struct : ConfigurableGroup { O2_DEFINE_CONFIGURABLE(cfgMultCentHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 10.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); @@ -157,8 +144,19 @@ struct CorrFit { TF1* fMultMultV0ACutHigh = nullptr; TF1* fT0AV0AMean = nullptr; TF1* fT0AV0ASigma = nullptr; + O2_DEFINE_CONFIGURABLE(cfgV0AT0Acut, int, 5, "V0AT0A cut") } cfgFuncParas; + struct : ConfigurableGroup { + O2_DEFINE_CONFIGURABLE(cfgTofPtCut, float, 0.4f, "Minimum pt to use TOF N-sigma") + O2_DEFINE_CONFIGURABLE(cfgUseItsPID, bool, false, "Use ITS PID for particle identification") + O2_DEFINE_CONFIGURABLE(cfgPIDParticle, int, 0, "1 = pion, 2 = kaon, 3 = proton, 4 = kshort, 5 = lambda, 6 = phi, 0 for no PID") + O2_DEFINE_CONFIGURABLE(cfgGetNsigmaQA, bool, false, "Get QA histograms for selection of pions, kaons, and protons") + O2_DEFINE_CONFIGURABLE(cfgGetdEdx, bool, false, "Get dEdx histograms for pions, kaons, and protons") + O2_DEFINE_CONFIGURABLE(cfgPIDUseRejection, bool, true, "True: use exclusion exclusion criteria for PID determination, false: don't use exclusion") + Configurable> nSigmas{"nSigmas", {LongArrayFloat[0], 6, 3, {"UpCut_pi", "UpCut_ka", "UpCut_pr", "LowCut_pi", "LowCut_ka", "LowCut_pr"}, {"TPC", "TOF", "ITS"}}, "Labeled array for n-sigma values for TPC, TOF, ITS for pions, kaons, protons (positive and negative)"}; + } cfgPIDConfigs; + Configurable cfgCutFV0{"cfgCutFV0", 50., "FV0A threshold"}; Configurable cfgCutFT0A{"cfgCutFT0A", 150., "FT0A threshold"}; Configurable cfgCutFT0C{"cfgCutFT0C", 50., "FT0C threshold"}; @@ -170,7 +168,7 @@ struct CorrFit { ConfigurableAxis axisMult{"axisMult", {10, 0, 100}, "multiplicity axis for histograms"}; ConfigurableAxis axisEta{"axisEta", {40, -1., 1.}, "eta axis for histograms"}; ConfigurableAxis axisPhi{"axisPhi", {72, 0.0, constants::math::TwoPI}, "phi axis for histograms"}; - ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt axis for histograms"}; + ConfigurableAxis axisPtFiner{"axisPtFiner", {98, 0.2, 10.0}, "pt axis for histograms"}; ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -PIHalf, PIHalf * 3}, "delta phi axis for histograms"}; ConfigurableAxis axisDeltaEtaTpcFt0a{"axisDeltaEtaTpcFt0a", {32, -5.8, -2.6}, "delta eta axis, -5.8~-2.6 for TPC-FT0A,"}; ConfigurableAxis axisDeltaEtaTpcFt0c{"axisDeltaEtaTpcFt0c", {32, 1.2, 4.2}, "delta eta axis, 1.2~4.2 for TPC-FT0C"}; @@ -181,6 +179,7 @@ struct CorrFit { ConfigurableAxis axisVtxMix{"axisVtxMix", {VARIABLE_WIDTH, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "vertex axis for mixed event histograms"}; ConfigurableAxis axisMultMix{"axisMultMix", {VARIABLE_WIDTH, 0, 10, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260}, "multiplicity / centrality axis for mixed event histograms"}; ConfigurableAxis axisSample{"axisSample", {cfgSampleSize, 0, cfgSampleSize}, "sample axis for histograms"}; + ConfigurableAxis axisParticle{"axisParticle", {4, 0, 4}, "particle axis for correlation container"}; ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"}; ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"}; @@ -188,6 +187,12 @@ struct CorrFit { ConfigurableAxis axisAmplitudeFt0a{"axisAmplitudeFt0a", {5000, 0, 1000}, "FT0A amplitude"}; ConfigurableAxis axisChannelFt0aAxis{"axisChannelFt0aAxis", {96, 0.0, 96.0}, "FT0A channel"}; + ConfigurableAxis axisNsigmaTPC{"axisNsigmaTPC", {80, -5, 5}, "nsigmaTPC axis"}; + ConfigurableAxis axisNsigmaTOF{"axisNsigmaTOF", {80, -5, 5}, "nsigmaTOF axis"}; + ConfigurableAxis axisNsigmaITS{"axisNsigmaITS", {80, -5, 5}, "nsigmaITS axis"}; + ConfigurableAxis axisTpcSignal{"axisTpcSignal", {250, 0, 250}, "dEdx axis for TPC"}; + ConfigurableAxis axisSigma{"axisSigma", {200, 0, 20}, "sigma axis for TPC"}; + Configurable cfgGainEqPath{"cfgGainEqPath", "Analysis/EventPlane/GainEq", "CCDB path for gain equalization constants"}; Configurable cfgCorrLevel{"cfgCorrLevel", 0, "calibration step: 0 = no corr, 1 = gain corr"}; ConfigurableAxis cfgaxisFITamp{"cfgaxisFITamp", {1000, 0, 5000}, ""}; @@ -195,10 +200,10 @@ struct CorrFit { AxisSpec axisChID = {220, 0, 220}; Filter collisionFilter = (nabs(aod::collision::posZ) < cfgZVtxCut); - Filter trackFilter = (nabs(aod::track::eta) < cfgTrackCuts.cfgEtaCut) && (cfgTrackCuts.cfgPtCutMin < aod::track::pt) && (cfgTrackCuts.cfgPtCutMax > aod::track::pt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgTrackCuts.cfgCutChi2prTPCcls) && (aod::track::dcaZ < cfgTrackCuts.cfgCutDCAz); + Filter trackFilter = (nabs(aod::track::eta) < cfgTrackCuts.cfgEtaCut) && (cfgTrackCuts.cfgPtCutMin < aod::track::pt) && (cfgTrackCuts.cfgPtCutMax > aod::track::pt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)); using FilteredCollisions = soa::Filtered>; - using FilteredTracks = soa::Filtered>; + using FilteredTracks = soa::Filtered>; // FT0 geometry o2::ft0::Geometry ft0Det; @@ -237,6 +242,61 @@ struct CorrFit { kFT0C = 1 }; + enum PIDIndex { + kCharged = 0, + kPions, + kKaons, + kProtons, + kK0, + kLambda, + kPhi + }; + enum PiKpArrayIndex { + iPionUp = 0, + iKaonUp, + iProtonUp, + iPionLow, + iKaonLow, + iProtonLow + }; + enum DetectorType { + kTPC = 0, + kTOF, + kITS + }; + + enum EventCutTypes { + kFilteredEvents = 0, + kAfterSel8, + kUseNoTimeFrameBorder, + kUseNoITSROFrameBorder, + kUseNoSameBunchPileup, + kUseGoodZvtxFT0vsPV, + kUseNoCollInTimeRangeStandard, + kUseGoodITSLayersAll, + kUseGoodITSLayer0123, + kUseNoCollInRofStandard, + kUseNoHighMultCollInPrevRof, + kUseOccupancy, + kUseMultCorrCut, + kUseT0AV0ACut, + kNEventCuts + }; + + enum EventCutType { + kEvCut1 = 0, + kNEvCutTypes = 1 + }; + + enum CentEstimators { + kCentFT0C = 0, + kCentFT0CVariant1, + kCentFT0M, + kCentFV0A, + // Count the total number of enum + kCount_CentEstimators + }; + RCTFlagsChecker rctChecker{"CBT"}; void init(InitContext&) @@ -253,53 +313,111 @@ struct CorrFit { registry.add("hEventCountRct", "Number of Event;; Count", {HistType::kTH1D, {{2, 0, 2}}}); registry.get(HIST("hEventCountRct"))->GetXaxis()->SetBinLabel(1, "rct fail"); registry.get(HIST("hEventCountRct"))->GetXaxis()->SetBinLabel(2, "rct pass"); - registry.add("hEventCountSpecific", "Number of Event;; Count", {HistType::kTH1D, {{13, 0, 13}}}); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(1, "after sel8"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(2, "kNoSameBunchPileup"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(3, "kNoITSROFrameBorder"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(4, "kNoTimeFrameBorder"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(5, "kIsGoodZvtxFT0vsPV"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(6, "kNoCollInTimeRangeStandard"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(7, "kIsGoodITSLayer0123"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(8, "kIsGoodITSLayersAll"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(9, "kNoCollInRofStandard"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(10, "kNoHighMultCollInPrevRof"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(11, "occupancy"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(12, "MultCorrelation"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(13, "cfgEvSelV0AT0ACut"); + registry.add("hEventCount", "Number of Event;; Count", {HistType::kTH1D, {{14, -0.5, 13.5}}}); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kFilteredEvents + 1, "Filtered events"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kAfterSel8 + 1, "After sel8"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseNoTimeFrameBorder + 1, "kNoTimeFrameBorder"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseNoITSROFrameBorder + 1, "kNoITSROFrameBorder"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseNoSameBunchPileup + 1, "kNoSameBunchPileup"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseGoodZvtxFT0vsPV + 1, "kIsGoodZvtxFT0vsPV"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseNoCollInTimeRangeStandard + 1, "kNoCollInTimeRangeStandard"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseGoodITSLayersAll + 1, "kIsGoodITSLayersAll"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseGoodITSLayer0123 + 1, "kIsGoodITSLayer0123"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseNoCollInRofStandard + 1, "kNoCollInRofStandard"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseNoHighMultCollInPrevRof + 1, "kNoHighMultCollInPrevRof"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseOccupancy + 1, "Occupancy Cut"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseMultCorrCut + 1, "MultCorrelation Cut"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseT0AV0ACut + 1, "T0AV0A cut"); } if ((doprocessSameFt0aFt0c || doprocessSameTpcFt0a || doprocessSameTpcFt0c || doprocessSameTPC) && cfgQaCheck) { - registry.add("hPassedEventSelection", "Number of Event;; Count", {HistType::kTH1D, {{12, 0, 12}}}); - registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(1, "all tracks"); - registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(2, "after sel8"); - registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(3, "kNoSameBunchPileup"); - registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(4, "kNoTimeFrameBorder"); - registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(5, "kNoITSROFrameBorder"); - registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(6, "kIsGoodZvtxFT0vsPV"); - registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(7, "kNoCollInTimeRangeStandard"); - registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(8, "kIsGoodITSLayer0123"); - registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(9, "kIsGoodITSLayersAll"); - registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(10, "kNoCollInRofStandard"); - registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(11, "kNoHighMultCollInPrevRof"); - registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(12, "occupancy"); + registry.add("hPassedEventSelection", "Number of Event;; Count", {HistType::kTH1D, {{12, -0.5, 11.5}}}); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kFilteredEvents + 1, "Filtered events"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kAfterSel8 + 1, "After sel8"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseNoTimeFrameBorder + 1, "kNoTimeFrameBorder"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseNoITSROFrameBorder + 1, "kNoITSROFrameBorder"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseNoSameBunchPileup + 1, "kNoSameBunchPileup"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseGoodZvtxFT0vsPV + 1, "kIsGoodZvtxFT0vsPV"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseNoCollInTimeRangeStandard + 1, "kNoCollInTimeRangeStandard"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseGoodITSLayersAll + 1, "kIsGoodITSLayersAll"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseGoodITSLayer0123 + 1, "kIsGoodITSLayer0123"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseNoCollInRofStandard + 1, "kNoCollInRofStandard"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseNoHighMultCollInPrevRof + 1, "kNoHighMultCollInPrevRof"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseOccupancy + 1, "Occupancy Cut"); + } + + // Multiplicity correlation cuts + if (cfgUseEventCuts->getData()[kUseMultCorrCut][kEvCut1]) { + cfgFuncParas.multT0CCutPars = cfgFuncParas.cfgMultT0CCutPars; + cfgFuncParas.multPVT0CCutPars = cfgFuncParas.cfgMultPVT0CCutPars; + cfgFuncParas.multGlobalPVCutPars = cfgFuncParas.cfgMultGlobalPVCutPars; + cfgFuncParas.multMultV0ACutPars = cfgFuncParas.cfgMultMultV0ACutPars; + cfgFuncParas.fMultPVT0CCutLow = new TF1("fMultPVT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultPVT0CCutLow->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); + cfgFuncParas.fMultPVT0CCutHigh = new TF1("fMultPVT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultPVT0CCutHigh->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); + + cfgFuncParas.fMultT0CCutLow = new TF1("fMultT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultT0CCutLow->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); + cfgFuncParas.fMultT0CCutHigh = new TF1("fMultT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultT0CCutHigh->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); + + cfgFuncParas.fMultGlobalPVCutLow = new TF1("fMultGlobalPVCutLow", cfgFuncParas.cfgMultMultPVLowCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultGlobalPVCutLow->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); + cfgFuncParas.fMultGlobalPVCutHigh = new TF1("fMultGlobalPVCutHigh", cfgFuncParas.cfgMultMultPVHighCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultGlobalPVCutHigh->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); + + cfgFuncParas.fMultMultV0ACutLow = new TF1("fMultMultV0ACutLow", cfgFuncParas.cfgMultMultV0ALowCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultMultV0ACutLow->SetParameters(&(cfgFuncParas.multMultV0ACutPars[0])); + cfgFuncParas.fMultMultV0ACutHigh = new TF1("fMultMultV0ACutHigh", cfgFuncParas.cfgMultMultV0AHighCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultMultV0ACutHigh->SetParameters(&(cfgFuncParas.multMultV0ACutPars[0])); + } + if (cfgUseEventCuts->getData()[kUseT0AV0ACut][kEvCut1]) { + cfgFuncParas.fT0AV0AMean = new TF1("fT0AV0AMean", "[0]+[1]*x", 0, 200000); + cfgFuncParas.fT0AV0AMean->SetParameters(-1601.0581, 9.417652e-01); + cfgFuncParas.fT0AV0ASigma = new TF1("fT0AV0ASigma", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 200000); + cfgFuncParas.fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); } if (doprocessSameTPC || doprocessSameFt0aFt0c || doprocessSameTpcFt0a || doprocessSameTpcFt0c) { registry.add("Phi", "Phi", {HistType::kTH1D, {axisPhi}}); registry.add("Eta", "Eta", {HistType::kTH1D, {axisEta}}); registry.add("EtaCorrected", "EtaCorrected", {HistType::kTH1D, {axisEta}}); - registry.add("pT", "pT", {HistType::kTH1D, {axisPtTrigger}}); - registry.add("pTCorrected", "pTCorrected", {HistType::kTH1D, {axisPtTrigger}}); + registry.add("hParticleCounts", "hParticleCounts", {HistType::kTH1D, {axisParticle}}); + registry.add("hParticleSelected", "hParticleSelected", {HistType::kTH2D, {axisParticle, axisPtTrigger}}); + registry.add("pTFiner", "pTFiner", {HistType::kTH1D, {axisPtFiner}}); + registry.add("pTFinerCorrected", "pTFinerCorrected", {HistType::kTH1D, {axisPtFiner}}); registry.add("Nch", "N_{ch}", {HistType::kTH1D, {axisMult}}); registry.add("zVtx", "zVtx", {HistType::kTH1D, {axisVertex}}); if (doprocessSameFt0aFt0c || doprocessSameTpcFt0a || doprocessSameTpcFt0c) { registry.add("FT0Amp", "", {HistType::kTH2F, {axisChID, axisFit}}); registry.add("FT0AmpCorrect", "", {HistType::kTH2F, {axisChID, axisFit}}); } - if (cfgQaCheck) { - registry.add("Nch_corrected", "N_{ch} corrected", {HistType::kTH1D, {axisMult}}); + if (cfgPIDConfigs.cfgGetNsigmaQA) { + if (!cfgPIDConfigs.cfgUseItsPID) { + registry.add("TofTpcNsigma_before", "", {HistType::kTHnSparseD, {{axisNsigmaTPC, axisNsigmaTOF, axisPtTrigger}}}); + registry.add("TofTpcNsigma_after", "", {HistType::kTHnSparseD, {{axisNsigmaTPC, axisNsigmaTOF, axisPtTrigger}}}); + } // TPC-TOF PID QA hists + if (cfgPIDConfigs.cfgUseItsPID) { + registry.add("TofItsNsigma_before", "", {HistType::kTHnSparseD, {{axisNsigmaITS, axisNsigmaTOF, axisPtTrigger}}}); + registry.add("TofItsNsigma_after", "", {HistType::kTHnSparseD, {{axisNsigmaITS, axisNsigmaTOF, axisPtTrigger}}}); + } // ITS-TOF PID QA hists + } // end of PID QA hists + + if (cfgPIDConfigs.cfgGetdEdx) { + registry.add("TpcdEdx_ptwise_beforeCut", "", {HistType::kTHnSparseD, {{axisPtTrigger, axisTpcSignal, axisNsigmaTOF}}}); + registry.add("ExpTpcdEdx_ptwise_beforeCut", "", {HistType::kTHnSparseD, {{axisPtTrigger, axisTpcSignal, axisNsigmaTOF}}}); + registry.add("ExpSigma_ptwise_beforeCut", "", {HistType::kTHnSparseD, {{axisPtTrigger, axisSigma, axisNsigmaTOF}}}); + + registry.add("TpcdEdx_ptwise_afterCut", "", {HistType::kTHnSparseD, {{axisPtTrigger, axisTpcSignal, axisNsigmaTOF}}}); + registry.add("ExpTpcdEdx_ptwise_afterCut", "", {HistType::kTHnSparseD, {{axisPtTrigger, axisTpcSignal, axisNsigmaTOF}}}); + registry.add("ExpSigma_ptwise_afterCut", "", {HistType::kTHnSparseD, {{axisPtTrigger, axisSigma, axisNsigmaTOF}}}); } + + } // end of single particle distribution histograms + + if (cfgQaCheck) { + registry.add("Nch_corrected", "N_{ch} corrected", {HistType::kTH1D, {axisMult}}); } if (doprocessSameTpcFt0a) { @@ -386,6 +504,30 @@ struct CorrFit { LOGF(info, "End of init"); } + + template + float getCentrality(TCollision const& collision) + { + float cent; + switch (cfgCentEstimator) { + case kCentFT0C: + cent = collision.centFT0C(); + break; + case kCentFT0CVariant1: + cent = collision.centFT0CVariant1(); + break; + case kCentFT0M: + cent = collision.centFT0M(); + break; + case kCentFV0A: + cent = collision.centFV0A(); + break; + default: + cent = collision.centFT0C(); + } + return cent; + } + template bool eventRct(TCollision const& collision, const bool fillCounter) { @@ -402,99 +544,119 @@ struct CorrFit { } template - bool eventSelected(TCollision const& collision, const int multTrk, const bool fillCounter) + bool eventSelected(TCollision const& collision, const int mult, const bool fillCounter) { - registry.fill(HIST("hEventCountSpecific"), 0.5); - if (cfgEventSelection.cfgEvSelkNoSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { - // rejects collisions which are associated with the same "found-by-T0" bunch crossing - // https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof + if (cfgUseEventCuts->getData()[kUseNoTimeFrameBorder][kEvCut1] && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { return 0; } - if (fillCounter && cfgEventSelection.cfgEvSelkNoSameBunchPileup) - registry.fill(HIST("hEventCountSpecific"), 1.5); - if (cfgEventSelection.cfgEvSelkNoITSROFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + if (fillCounter && cfgUseEventCuts->getData()[kUseNoTimeFrameBorder][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseNoTimeFrameBorder); + + if (cfgUseEventCuts->getData()[kUseNoITSROFrameBorder][kEvCut1] && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { return 0; } - if (fillCounter && cfgEventSelection.cfgEvSelkNoITSROFrameBorder) - registry.fill(HIST("hEventCountSpecific"), 2.5); - if (cfgEventSelection.cfgEvSelkNoTimeFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + if (fillCounter && cfgUseEventCuts->getData()[kUseNoITSROFrameBorder][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseNoITSROFrameBorder); + + if (cfgUseEventCuts->getData()[kUseNoSameBunchPileup][kEvCut1] && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + // rejects collisions which are associated with the same "found-by-T0" bunch crossing + // https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof return 0; } - if (fillCounter && cfgEventSelection.cfgEvSelkNoTimeFrameBorder) - registry.fill(HIST("hEventCountSpecific"), 3.5); - if (cfgEventSelection.cfgEvSelkIsGoodZvtxFT0vsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + if (fillCounter && cfgUseEventCuts->getData()[kUseNoSameBunchPileup][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseNoSameBunchPileup); + + if (cfgUseEventCuts->getData()[kUseGoodZvtxFT0vsPV][kEvCut1] && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { // removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference // use this cut at low multiplicities with caution return 0; } - if (fillCounter && cfgEventSelection.cfgEvSelkIsGoodZvtxFT0vsPV) - registry.fill(HIST("hEventCountSpecific"), 4.5); - if (cfgEventSelection.cfgEvSelkNoCollInTimeRangeStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + if (fillCounter && cfgUseEventCuts->getData()[kUseGoodZvtxFT0vsPV][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseGoodZvtxFT0vsPV); + + if (cfgUseEventCuts->getData()[kUseNoCollInTimeRangeStandard][kEvCut1] && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { // no collisions in specified time range return 0; } - if (fillCounter && cfgEventSelection.cfgEvSelkNoCollInTimeRangeStandard) - registry.fill(HIST("hEventCountSpecific"), 5.5); - if (cfgEventSelection.cfgEvSelkIsGoodITSLayer0123 && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayer0123)) { + if (fillCounter && cfgUseEventCuts->getData()[kUseNoCollInTimeRangeStandard][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseNoCollInTimeRangeStandard); + + if (cfgUseEventCuts->getData()[kUseGoodITSLayersAll][kEvCut1] && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { // from Jan 9 2025 AOT meeting // cut time intervals with dead ITS staves return 0; } - if (fillCounter && cfgEventSelection.cfgEvSelkIsGoodITSLayer0123) - registry.fill(HIST("hEventCountSpecific"), 6.5); - if (cfgEventSelection.cfgEvSelkIsGoodITSLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { - // from Jan 9 2025 AOT meeting - // cut time intervals with dead ITS staves + if (fillCounter && cfgUseEventCuts->getData()[kUseGoodITSLayersAll][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseGoodITSLayersAll); + + if (cfgUseEventCuts->getData()[kUseGoodITSLayer0123][kEvCut1] && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayer0123)) { return 0; } + if (fillCounter && cfgUseEventCuts->getData()[kUseGoodITSLayer0123][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseGoodITSLayer0123); - if (fillCounter && cfgEventSelection.cfgEvSelkIsGoodITSLayersAll) - registry.fill(HIST("hEventCountSpecific"), 7.5); - - if (cfgEventSelection.cfgEvSelkNoCollInRofStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + if (cfgUseEventCuts->getData()[kUseNoCollInRofStandard][kEvCut1] && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { // no other collisions in this Readout Frame with per-collision multiplicity above threshold return 0; } - if (fillCounter && cfgEventSelection.cfgEvSelkNoCollInRofStandard) - registry.fill(HIST("hEventCountSpecific"), 8.5); - if (cfgEventSelection.cfgEvSelkNoHighMultCollInPrevRof && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + + if (fillCounter && cfgUseEventCuts->getData()[kUseNoCollInRofStandard][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseNoCollInRofStandard); + + if (cfgUseEventCuts->getData()[kUseNoHighMultCollInPrevRof][kEvCut1] && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { // veto an event if FT0C amplitude in previous ITS ROF is above threshold return 0; } - if (fillCounter && cfgEventSelection.cfgEvSelkNoHighMultCollInPrevRof) - registry.fill(HIST("hEventCountSpecific"), 9.5); - auto occupancy = collision.trackOccupancyInTimeRange(); - if (cfgEventSelection.cfgEvSelOccupancy && (occupancy < cfgEventSelection.cfgCutOccupancyLow || occupancy > cfgEventSelection.cfgCutOccupancyHigh)) - return 0; - if (fillCounter && cfgEventSelection.cfgEvSelOccupancy) - registry.fill(HIST("hEventCountSpecific"), 10.5); + if (fillCounter && cfgUseEventCuts->getData()[kUseNoHighMultCollInPrevRof][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseNoHighMultCollInPrevRof); auto multNTracksPV = collision.multNTracksPV(); + auto occupancy = collision.trackOccupancyInTimeRange(); - if (cfgFuncParas.cfgMultGlobalPVCutEnabled) { - if (multTrk < cfgFuncParas.fMultGlobalPVCutLow->Eval(multNTracksPV)) - return 0; - if (multTrk > cfgFuncParas.fMultGlobalPVCutHigh->Eval(multNTracksPV)) - return 0; + if (cfgUseEventCuts->getData()[kUseOccupancy][kEvCut1] && (occupancy < cfgEventSelection.cfgCutOccupancyLow || occupancy > cfgEventSelection.cfgCutOccupancyHigh)) { + return 0; } - if (cfgFuncParas.cfgMultMultV0ACutEnabled) { - if (collision.multFV0A() < cfgFuncParas.fMultMultV0ACutLow->Eval(multTrk)) - return 0; - if (collision.multFV0A() > cfgFuncParas.fMultMultV0ACutHigh->Eval(multTrk)) - return 0; + if (fillCounter && cfgUseEventCuts->getData()[kUseOccupancy][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseOccupancy); + + if (cfgUseEventCuts->getData()[kUseMultCorrCut][kEvCut1]) { + float cent = getCentrality(collision); + if (cfgFuncParas.cfgMultPVT0CCutEnabled) { + if (multNTracksPV < cfgFuncParas.fMultPVT0CCutLow->Eval(cent)) + return 0; + if (multNTracksPV > cfgFuncParas.fMultPVT0CCutHigh->Eval(cent)) + return 0; + } + if (cfgFuncParas.cfgMultT0CCutEnabled) { + if (mult < cfgFuncParas.fMultT0CCutLow->Eval(cent)) + return 0; + if (mult > cfgFuncParas.fMultT0CCutHigh->Eval(cent)) + return 0; + } + if (cfgFuncParas.cfgMultGlobalPVCutEnabled) { + if (mult < cfgFuncParas.fMultGlobalPVCutLow->Eval(multNTracksPV)) + return 0; + if (mult > cfgFuncParas.fMultGlobalPVCutHigh->Eval(multNTracksPV)) + return 0; + } + if (cfgFuncParas.cfgMultMultV0ACutEnabled) { + if (collision.multFV0A() < cfgFuncParas.fMultMultV0ACutLow->Eval(mult)) + return 0; + if (collision.multFV0A() > cfgFuncParas.fMultMultV0ACutHigh->Eval(mult)) + return 0; + } } - if (fillCounter && cfgEventSelection.cfgEvSelMultCorrelation) - registry.fill(HIST("hEventCountSpecific"), 11.5); + if (fillCounter && cfgUseEventCuts->getData()[kUseMultCorrCut][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseMultCorrCut); // V0A T0A 5 sigma cut - float sigma = 5.0; - if (cfgEventSelection.cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - cfgFuncParas.fT0AV0AMean->Eval(collision.multFT0A())) > sigma * cfgFuncParas.fT0AV0ASigma->Eval(collision.multFT0A()))) + if (cfgUseEventCuts->getData()[kUseT0AV0ACut][kEvCut1] && (std::fabs(collision.multFV0A() - cfgFuncParas.fT0AV0AMean->Eval(collision.multFT0A())) > cfgFuncParas.cfgV0AT0Acut * cfgFuncParas.fT0AV0ASigma->Eval(collision.multFT0A()))) return 0; - if (fillCounter && cfgEventSelection.cfgEvSelV0AT0ACut) - registry.fill(HIST("hEventCountSpecific"), 12.5); + if (fillCounter && cfgUseEventCuts->getData()[kUseT0AV0ACut][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseT0AV0ACut); return 1; } @@ -502,52 +664,51 @@ struct CorrFit { template void eventSelectedIndividually(TCollision const& collision) { - - registry.fill(HIST("hPassedEventSelection"), 0.5); + registry.fill(HIST("hPassedEventSelection"), kFilteredEvents); if (collision.sel8()) { - registry.fill(HIST("hPassedEventSelection"), 1.5); - } - - if (collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { - registry.fill(HIST("hPassedEventSelection"), 2.5); + registry.fill(HIST("hPassedEventSelection"), kAfterSel8); } if (collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { - registry.fill(HIST("hPassedEventSelection"), 3.5); + registry.fill(HIST("hPassedEventSelection"), kUseNoTimeFrameBorder); } if (collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { - registry.fill(HIST("hPassedEventSelection"), 4.5); + registry.fill(HIST("hPassedEventSelection"), kUseNoITSROFrameBorder); + } + + if (collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + registry.fill(HIST("hPassedEventSelection"), kUseNoSameBunchPileup); } if (collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { - registry.fill(HIST("hPassedEventSelection"), 5.5); + registry.fill(HIST("hPassedEventSelection"), kUseGoodZvtxFT0vsPV); } if (collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { - registry.fill(HIST("hPassedEventSelection"), 6.5); + registry.fill(HIST("hPassedEventSelection"), kUseNoCollInTimeRangeStandard); } - if (collision.selection_bit(o2::aod::evsel::kIsGoodITSLayer0123)) { - registry.fill(HIST("hPassedEventSelection"), 7.5); + if (collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + registry.fill(HIST("hPassedEventSelection"), kUseGoodITSLayersAll); } - if (collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { - registry.fill(HIST("hPassedEventSelection"), 8.5); + if (collision.selection_bit(o2::aod::evsel::kIsGoodITSLayer0123)) { + registry.fill(HIST("hPassedEventSelection"), kUseGoodITSLayer0123); } if (collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { - registry.fill(HIST("hPassedEventSelection"), 9.5); + registry.fill(HIST("hPassedEventSelection"), kUseNoCollInRofStandard); } if (collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { - registry.fill(HIST("hPassedEventSelection"), 10.5); + registry.fill(HIST("hPassedEventSelection"), kUseNoHighMultCollInPrevRof); } auto occupancy = collision.trackOccupancyInTimeRange(); - if (cfgEventSelection.cfgEvSelOccupancy && (occupancy < cfgEventSelection.cfgCutOccupancyLow || occupancy > cfgEventSelection.cfgCutOccupancyHigh)) { - registry.fill(HIST("hPassedEventSelection"), 11.5); + if (cfgUseEventCuts->getData()[kUseOccupancy][kEvCut1] && (occupancy < cfgEventSelection.cfgCutOccupancyLow || occupancy > cfgEventSelection.cfgCutOccupancyHigh)) { + registry.fill(HIST("hPassedEventSelection"), kUseOccupancy); } } @@ -593,13 +754,7 @@ struct CorrFit { template bool trackSelected(TTrack const& track) { - return ((track.tpcNClsFound() >= cfgTrackCuts.cfgCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgTrackCuts.cfgCutTPCCrossedRows) && (track.itsNCls() >= cfgTrackCuts.cfgCutITSclu)); - } - - template - bool trackSelectedSystematics(TTrack const& track) - { - return ((track.tpcNClsFound() >= cfgSystematics.cfgSystematicsCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgSystematics.cfgSystematicsCutTPCCrossedRows) && (track.itsNCls() >= cfgSystematics.cfgSystematicsCutITSclu)); + return ((track.tpcNClsFound() >= cfgTrackCuts.cfgCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgTrackCuts.cfgCutTPCCrossedRows) && (track.itsNCls() >= cfgTrackCuts.cfgCutITSclu) && (track.tpcChi2NCl() < cfgTrackCuts.cfgCutChi2prTPCcls) && (track.dcaZ() < cfgTrackCuts.cfgCutDCAz)); } template @@ -679,6 +834,65 @@ struct CorrFit { } } + template + int getNsigmaPID(TTrack track, bool fillYields) + { + // Computing Nsigma arrays for pion, kaon, and protons + std::array nSigmaTPC = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()}; + std::array nSigmaTOF = {track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr()}; + std::array nSigmaITS = {itsResponse.nSigmaITS(track), itsResponse.nSigmaITS(track), itsResponse.nSigmaITS(track)}; + int pid = -1; // -1 = not identified, 1 = pion, 2 = kaon, 3 = proton + + std::array nSigmaToUse = cfgPIDConfigs.cfgUseItsPID ? nSigmaITS : nSigmaTPC; // Choose which nSigma to use: TPC or ITS + int kIndexDetector = cfgPIDConfigs.cfgUseItsPID ? kITS : kTPC; // Choose which nSigma to use: TPC or ITS + + bool isPion, isKaon, isProton; + bool isDetectedPion = nSigmaToUse[iPionUp] < cfgPIDConfigs.nSigmas->getData()[iPionUp][kIndexDetector] && nSigmaToUse[iPionUp] > cfgPIDConfigs.nSigmas->getData()[iPionLow][kIndexDetector]; + bool isDetectedKaon = nSigmaToUse[iKaonUp] < cfgPIDConfigs.nSigmas->getData()[iKaonUp][kIndexDetector] && nSigmaToUse[iKaonUp] > cfgPIDConfigs.nSigmas->getData()[iKaonLow][kIndexDetector]; + bool isDetectedProton = nSigmaToUse[iProtonUp] < cfgPIDConfigs.nSigmas->getData()[iProtonUp][kIndexDetector] && nSigmaToUse[iProtonUp] > cfgPIDConfigs.nSigmas->getData()[iProtonLow][kIndexDetector]; + + bool isTofPion = nSigmaTOF[iPionUp] < cfgPIDConfigs.nSigmas->getData()[iPionUp][kTOF] && nSigmaTOF[iPionUp] > cfgPIDConfigs.nSigmas->getData()[iPionLow][kTOF]; + bool isTofKaon = nSigmaTOF[iKaonUp] < cfgPIDConfigs.nSigmas->getData()[iKaonUp][kTOF] && nSigmaTOF[iKaonUp] > cfgPIDConfigs.nSigmas->getData()[iKaonLow][kTOF]; + bool isTofProton = nSigmaTOF[iProtonUp] < cfgPIDConfigs.nSigmas->getData()[iProtonUp][kTOF] && nSigmaTOF[iProtonUp] > cfgPIDConfigs.nSigmas->getData()[iProtonLow][kTOF]; + + if (track.pt() > cfgPIDConfigs.cfgTofPtCut && !track.hasTOF()) { + return -1; + } else if (track.pt() > cfgPIDConfigs.cfgTofPtCut && track.hasTOF()) { + isPion = isTofPion && isDetectedPion; + isKaon = isTofKaon && isDetectedKaon; + isProton = isTofProton && isDetectedProton; + } else { + isPion = isDetectedPion; + isKaon = isDetectedKaon; + isProton = isDetectedProton; + } + + if (cfgPIDConfigs.cfgPIDUseRejection && ((isPion && isKaon) || (isPion && isProton) || (isKaon && isProton))) { + return -1; // more than one particle satisfy the criteria + } + + if (fillYields) + registry.fill(HIST("hParticleCounts"), kCharged); + + if (isPion) { + pid = kPions; + if (fillYields) + registry.fill(HIST("hParticleCounts"), kPions); + } else if (isKaon) { + pid = kKaons; + if (fillYields) + registry.fill(HIST("hParticleCounts"), kKaons); + } else if (isProton) { + pid = kProtons; + if (fillYields) + registry.fill(HIST("hParticleCounts"), kProtons); + } else { + return -1; // no particle satisfies the criteria + } + + return pid; // -1 = not identified, 1 = pion, 2 = kaon, 3 = proton + } + void loadCorrection(uint64_t timestamp) { if (correctionsLoaded) { @@ -720,20 +934,20 @@ struct CorrFit { correctionsLoaded = true; } - bool getEfficiencyCorrection_Nch(float& weight_Nch, float pt) + bool getEfficiencyCorrectionNch(float& weightNch, float pt) { - float eff_Nch = 1.; + float effNch = 1.; if (mEfficiencyNch) { int ptBin = mEfficiencyNch->FindBin(pt); - eff_Nch = mEfficiencyNch->GetBinContent(ptBin); + effNch = mEfficiencyNch->GetBinContent(ptBin); } else { - eff_Nch = 1.0; + effNch = 1.0; } - if (eff_Nch == 0) + if (effNch == 0) return false; - weight_Nch = 1. / eff_Nch; + weightNch = 1. / effNch; return true; } @@ -775,7 +989,7 @@ struct CorrFit { void trackCounter(TTracks tracks, double& multiplicity) // function to count the number of tracks in the event and fill the histogram { double nTracksCorrected = 0; - float weight_Nch = 1.0f; + float weightNch = 1.0f; for (auto const& track : tracks) { if (cfgRefMultiplicity) { @@ -783,15 +997,147 @@ struct CorrFit { continue; } - if (!getEfficiencyCorrection_Nch(weight_Nch, track.pt())) { + if (!getEfficiencyCorrectionNch(weightNch, track.pt())) { continue; } - nTracksCorrected += weight_Nch; + nTracksCorrected += weightNch; } multiplicity = nTracksCorrected; } + template + void fillYield(TCollision collision, TTracks tracks) // function to fill the yield and etaphi histograms. + { + + float weff1 = 1.0; + float zvtx = collision.posZ(); + + for (auto const& track1 : tracks) { + + if (!trackSelected(track1)) { + continue; + } + if (cfgPIDConfigs.cfgPIDParticle && getNsigmaPID(track1, true) != cfgPIDConfigs.cfgPIDParticle) + continue; // if PID is selected, check if the track has the right PID + + if (!getEfficiencyCorrection(weff1, track1.eta(), track1.pt(), zvtx)) { + continue; + } + + registry.fill(HIST("Phi"), RecoDecay::constrainAngle(track1.phi(), 0.0)); + registry.fill(HIST("Eta"), track1.eta()); + registry.fill(HIST("EtaCorrected"), track1.eta(), weff1); + registry.fill(HIST("pTFiner"), track1.pt()); + registry.fill(HIST("pTFinerCorrected"), track1.pt(), weff1); + registry.fill(HIST("hParticleSelected"), cfgPIDConfigs.cfgPIDParticle.value, track1.pt()); + } + } + + template + void fillNsigmaBeforeCut(TTrack track1, int pid) // function to fill the QA before Nsigma selection + { + switch (pid) { + case kPions: // For Pions + if (!cfgPIDConfigs.cfgUseItsPID) { + if (cfgPIDConfigs.cfgGetNsigmaQA) + registry.fill(HIST("TofTpcNsigma_before"), track1.tpcNSigmaPi(), track1.tofNSigmaPi(), track1.pt()); + if (cfgPIDConfigs.cfgGetdEdx) { + double tpcExpSignalPi = track1.tpcSignal() - (track1.tpcNSigmaPi() * track1.tpcExpSigmaPi()); + + registry.fill(HIST("TpcdEdx_ptwise_beforeCut"), track1.pt(), track1.tpcSignal(), track1.tofNSigmaPi()); + registry.fill(HIST("ExpTpcdEdx_ptwise_beforeCut"), track1.pt(), tpcExpSignalPi, track1.tofNSigmaPi()); + registry.fill(HIST("ExpSigma_ptwise_beforeCut"), track1.pt(), track1.tpcExpSigmaPi(), track1.tofNSigmaPi()); + } + } + if (cfgPIDConfigs.cfgGetNsigmaQA && cfgPIDConfigs.cfgUseItsPID) + registry.fill(HIST("TofItsNsigma_before"), itsResponse.nSigmaITS(track1), track1.tofNSigmaPi(), track1.pt()); + break; + case kKaons: // For Kaons + if (!cfgPIDConfigs.cfgUseItsPID) { + if (cfgPIDConfigs.cfgGetNsigmaQA) + registry.fill(HIST("TofTpcNsigma_before"), track1.tpcNSigmaKa(), track1.tofNSigmaKa(), track1.pt()); + if (cfgPIDConfigs.cfgGetdEdx) { + double tpcExpSignalKa = track1.tpcSignal() - (track1.tpcNSigmaKa() * track1.tpcExpSigmaKa()); + + registry.fill(HIST("TpcdEdx_ptwise_beforeCut"), track1.pt(), track1.tpcSignal(), track1.tofNSigmaKa()); + registry.fill(HIST("ExpTpcdEdx_ptwise_beforeCut"), track1.pt(), tpcExpSignalKa, track1.tofNSigmaKa()); + registry.fill(HIST("ExpSigma_ptwise_beforeCut"), track1.pt(), track1.tpcExpSigmaKa(), track1.tofNSigmaKa()); + } + } + if (cfgPIDConfigs.cfgGetNsigmaQA && cfgPIDConfigs.cfgUseItsPID) + registry.fill(HIST("TofItsNsigma_before"), itsResponse.nSigmaITS(track1), track1.tofNSigmaKa(), track1.pt()); + break; + case kProtons: // For Protons + if (!cfgPIDConfigs.cfgUseItsPID) { + if (cfgPIDConfigs.cfgGetNsigmaQA) + registry.fill(HIST("TofTpcNsigma_before"), track1.tpcNSigmaPr(), track1.tofNSigmaPr(), track1.pt()); + if (cfgPIDConfigs.cfgGetdEdx) { + double tpcExpSignalPr = track1.tpcSignal() - (track1.tpcNSigmaPr() * track1.tpcExpSigmaPr()); + + registry.fill(HIST("TpcdEdx_ptwise_beforeCut"), track1.pt(), track1.tpcSignal(), track1.tofNSigmaPr()); + registry.fill(HIST("ExpTpcdEdx_ptwise_beforeCut"), track1.pt(), tpcExpSignalPr, track1.tofNSigmaPr()); + registry.fill(HIST("ExpSigma_ptwise_beforeCut"), track1.pt(), track1.tpcExpSigmaPr(), track1.tofNSigmaPr()); + } + } + if (cfgPIDConfigs.cfgGetNsigmaQA && cfgPIDConfigs.cfgUseItsPID) + registry.fill(HIST("TofItsNsigma_before"), itsResponse.nSigmaITS(track1), track1.tofNSigmaPr(), track1.pt()); + break; + } + } // end of fillNsigmaBeforeCut + + template + void fillNsigmaAfterCut(TTrack track1, int pid) // function to fill the QA after Nsigma selection + { + switch (pid) { + case kPions: // For Pions + if (!cfgPIDConfigs.cfgUseItsPID) { + if (cfgPIDConfigs.cfgGetdEdx) { + double tpcExpSignalPi = track1.tpcSignal() - (track1.tpcNSigmaPi() * track1.tpcExpSigmaPi()); + + registry.fill(HIST("TpcdEdx_ptwise_afterCut"), track1.pt(), track1.tpcSignal(), track1.tofNSigmaPi()); + registry.fill(HIST("ExpTpcdEdx_ptwise_afterCut"), track1.pt(), tpcExpSignalPi, track1.tofNSigmaPi()); + registry.fill(HIST("ExpSigma_ptwise_afterCut"), track1.pt(), track1.tpcExpSigmaPi(), track1.tofNSigmaPi()); + } + if (cfgPIDConfigs.cfgGetNsigmaQA) + registry.fill(HIST("TofTpcNsigma_after"), track1.tpcNSigmaPi(), track1.tofNSigmaPi(), track1.pt()); + } + if (cfgPIDConfigs.cfgUseItsPID) + registry.fill(HIST("TofItsNsigma_after"), itsResponse.nSigmaITS(track1), track1.tofNSigmaPi(), track1.pt()); + break; + case kKaons: // For Kaons + if (!cfgPIDConfigs.cfgUseItsPID) { + if (cfgPIDConfigs.cfgGetdEdx) { + double tpcExpSignalKa = track1.tpcSignal() - (track1.tpcNSigmaKa() * track1.tpcExpSigmaKa()); + + registry.fill(HIST("TpcdEdx_ptwise_afterCut"), track1.pt(), track1.tpcSignal(), track1.tofNSigmaKa()); + registry.fill(HIST("ExpTpcdEdx_ptwise_afterCut"), track1.pt(), tpcExpSignalKa, track1.tofNSigmaKa()); + registry.fill(HIST("ExpSigma_ptwise_afterCut"), track1.pt(), track1.tpcExpSigmaKa(), track1.tofNSigmaKa()); + } + if (cfgPIDConfigs.cfgGetNsigmaQA) + registry.fill(HIST("TofTpcNsigma_after"), track1.tpcNSigmaKa(), track1.tofNSigmaKa(), track1.pt()); + } + if (cfgPIDConfigs.cfgUseItsPID) + registry.fill(HIST("TofItsNsigma_after"), itsResponse.nSigmaITS(track1), track1.tofNSigmaKa(), track1.pt()); + break; + case kProtons: // For Protons + if (!cfgPIDConfigs.cfgUseItsPID) { + if (cfgPIDConfigs.cfgGetdEdx) { + double tpcExpSignalPr = track1.tpcSignal() - (track1.tpcNSigmaPr() * track1.tpcExpSigmaPr()); + + registry.fill(HIST("TpcdEdx_ptwise_afterCut"), track1.pt(), track1.tpcSignal(), track1.tofNSigmaPr()); + registry.fill(HIST("ExpTpcdEdx_ptwise_afterCut"), track1.pt(), tpcExpSignalPr, track1.tofNSigmaPr()); + registry.fill(HIST("ExpSigma_ptwise_afterCut"), track1.pt(), track1.tpcExpSigmaPr(), track1.tofNSigmaPr()); + } + if (cfgPIDConfigs.cfgGetNsigmaQA) + registry.fill(HIST("TofTpcNsigma_after"), track1.tpcNSigmaPr(), track1.tofNSigmaPr(), track1.pt()); + } + if (cfgPIDConfigs.cfgUseItsPID && cfgPIDConfigs.cfgGetNsigmaQA) + registry.fill(HIST("TofItsNsigma_after"), itsResponse.nSigmaITS(track1), track1.tofNSigmaPr(), track1.pt()); + break; + } // end of switch + } + template void fillCorrelationsTPCFT0(TTracks tracks1, TFT0s const& ft0, float posZ, int system, int multiplicity, int corType, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms { @@ -805,10 +1151,14 @@ struct CorrFit { if (!trackSelected(track1)) continue; - if (cfgSystematics.cfgSystematicsVariation) { - if (!trackSelectedSystematics(track1)) - continue; - } + if (cfgPIDConfigs.cfgPIDParticle > kCharged) + fillNsigmaBeforeCut(track1, cfgPIDConfigs.cfgPIDParticle); + + if (cfgPIDConfigs.cfgPIDParticle && getNsigmaPID(track1, false) != cfgPIDConfigs.cfgPIDParticle) + continue; // if PID is selected, check if the track has the right PID + + if (cfgPIDConfigs.cfgPIDParticle > kCharged) + fillNsigmaAfterCut(track1, cfgPIDConfigs.cfgPIDParticle); if (!getEfficiencyCorrection(triggerWeight, track1.pt(), track1.eta(), posZ)) continue; @@ -875,32 +1225,6 @@ struct CorrFit { } } - template - void fillYield(TCollision collision, TTracks tracks) // function to fill the yield and etaphi histograms. - { - - float weff1 = 1.0; - float zvtx = collision.posZ(); - registry.fill(HIST("zVtx"), zvtx); - registry.fill(HIST("Nch"), tracks.size()); - - for (auto const& track1 : tracks) { - - if (!trackSelected(track1)) { - continue; - } - if (!getEfficiencyCorrection_Nch(weff1, track1.pt())) { - continue; - } - - registry.fill(HIST("Phi"), RecoDecay::constrainAngle(track1.phi(), 0.0)); - registry.fill(HIST("Eta"), track1.eta()); - registry.fill(HIST("EtaCorrected"), track1.eta(), weff1); - registry.fill(HIST("pT"), track1.pt()); - registry.fill(HIST("pTCorrected"), track1.pt(), weff1); - } - } - template void fillCorrelationsFT0AFT0C(TFT0s const& ft0Col1, TFT0s const& ft0Col2, float posZ, int system, int multiplicity, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms { @@ -966,7 +1290,17 @@ struct CorrFit { if (!trackSelected(track1)) continue; - if (!getEfficiencyCorrection_Nch(triggerWeight, track1.pt())) + // Fill Nsigma QA + if (cfgPIDConfigs.cfgPIDParticle > kCharged) + fillNsigmaBeforeCut(track1, cfgPIDConfigs.cfgPIDParticle); + + if (cfgPIDConfigs.cfgPIDParticle && getNsigmaPID(track1, false) != cfgPIDConfigs.cfgPIDParticle) + continue; // if PID is selected, check if the track has the right PID + + if (cfgPIDConfigs.cfgPIDParticle > kCharged) + fillNsigmaAfterCut(track1, cfgPIDConfigs.cfgPIDParticle); + + if (!getEfficiencyCorrectionNch(triggerWeight, track1.pt())) continue; if (system == SameEvent) { @@ -978,7 +1312,7 @@ struct CorrFit { if (!trackSelected(track2)) continue; - if (!getEfficiencyCorrection_Nch(associateWeight, track2.pt())) + if (!getEfficiencyCorrectionNch(associateWeight, track2.pt())) continue; if (cfgRefpTt) { @@ -1033,6 +1367,17 @@ struct CorrFit { } } + bool isGoodRun(int runNumber) + { + for (const auto& ExcludedRun : cfgRunRemoveList.value) { + if (runNumber == ExcludedRun) { + return false; + } + } + + return true; + } + void processSameTpcFt0a(FilteredCollisions::iterator const& collision, FilteredTracks const& tracks, aod::FT0s const&, aod::BCsWithTimestamps const&) { if (cfgQaCheck) { @@ -1047,6 +1392,12 @@ struct CorrFit { auto bc = collision.bc_as(); + int currentRunNumber = bc.runNumber(); + if (!cfgRunRemoveList.value.empty()) { + if (!isGoodRun(currentRunNumber)) // Rejects runs if bad run number + return; + } + if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), true)) return; @@ -1118,6 +1469,12 @@ struct CorrFit { registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin auto bc = collision1.bc_as(); + int currentRunNumber = bc.runNumber(); + if (!cfgRunRemoveList.value.empty()) { + if (!isGoodRun(currentRunNumber)) // Rejects runs if bad run number + return; + } + loadAlignParam(bc.timestamp()); loadCorrection(bc.timestamp()); float eventWeight = 1.0f; @@ -1128,8 +1485,8 @@ struct CorrFit { trackCounter(tracks1, multiplicity); } - if (cfgQaCheck) { - registry.fill(HIST("Nch_corrected"), multiplicity); + if (multiplicity > cfgMaxMultForCorrelations || multiplicity < cfgMinMultForCorrelations) { + return; } const auto& ft0 = collision2.foundFT0(); @@ -1152,6 +1509,11 @@ struct CorrFit { return; auto bc = collision.bc_as(); + int currentRunNumber = bc.runNumber(); + if (!cfgRunRemoveList.value.empty()) { + if (!isGoodRun(currentRunNumber)) // Rejects runs if bad run number + return; + } if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), true)) return; @@ -1177,6 +1539,10 @@ struct CorrFit { registry.fill(HIST("Nch_corrected"), multiplicity); } + if (multiplicity > cfgMaxMultForCorrelations || multiplicity < cfgMinMultForCorrelations) { + return; + } + fillCorrelationsTPCFT0(tracks, ft0, collision.posZ(), SameEvent, multiplicity, kFT0C, 1.0f); } PROCESS_SWITCH(CorrFit, processSameTpcFt0c, "Process same event for TPC-FT0C correlation", false); @@ -1215,6 +1581,11 @@ struct CorrFit { registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin auto bc = collision1.bc_as(); + int currentRunNumber = bc.runNumber(); + if (!cfgRunRemoveList.value.empty()) { + if (!isGoodRun(currentRunNumber)) // Rejects runs if bad run number + return; + } loadAlignParam(bc.timestamp()); loadCorrection(bc.timestamp()); float eventWeight = 1.0f; @@ -1226,8 +1597,8 @@ struct CorrFit { trackCounter(tracks, multiplicity); } - if (cfgQaCheck) { - registry.fill(HIST("Nch_corrected"), multiplicity); + if (multiplicity > cfgMaxMultForCorrelations || multiplicity < cfgMinMultForCorrelations) { + return; } fillCorrelationsTPCFT0(tracks1, ft0, collision1.posZ(), MixedEvent, multiplicity, kFT0C, eventWeight); @@ -1249,6 +1620,11 @@ struct CorrFit { return; auto bc = collision.bc_as(); + int currentRunNumber = bc.runNumber(); + if (!cfgRunRemoveList.value.empty()) { + if (!isGoodRun(currentRunNumber)) // Rejects runs if bad run number + return; + } if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), true)) return; @@ -1277,6 +1653,10 @@ struct CorrFit { registry.fill(HIST("Nch_corrected"), multiplicity); } + if (multiplicity > cfgMaxMultForCorrelations || multiplicity < cfgMinMultForCorrelations) { + return; + } + fillCorrelationsFT0AFT0C(ft0, ft0, collision.posZ(), SameEvent, multiplicity, eventWeight); } PROCESS_SWITCH(CorrFit, processSameFt0aFt0c, "Process same event for FT0A-FT0C correlation", true); @@ -1315,6 +1695,11 @@ struct CorrFit { continue; auto bc = collision1.bc_as(); + int currentRunNumber = bc.runNumber(); + if (!cfgRunRemoveList.value.empty()) { + if (!isGoodRun(currentRunNumber)) // Rejects runs if bad run number + return; + } loadAlignParam(bc.timestamp()); loadCorrection(bc.timestamp()); float eventWeight = 1.0f; @@ -1328,9 +1713,10 @@ struct CorrFit { trackCounter(tracks1, multiplicity); } - if (cfgQaCheck) { - registry.fill(HIST("Nch_corrected"), multiplicity); + if (multiplicity > cfgMaxMultForCorrelations || multiplicity < cfgMinMultForCorrelations) { + return; } + registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin fillCorrelationsFT0AFT0C(ft0Col1, ft0Col2, collision1.posZ(), MixedEvent, multiplicity, eventWeight); @@ -1351,6 +1737,11 @@ struct CorrFit { return; auto bc = collision.bc_as(); + int currentRunNumber = bc.runNumber(); + if (!cfgRunRemoveList.value.empty()) { + if (!isGoodRun(currentRunNumber)) // Rejects runs if bad run number + return; + } if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), true)) return; @@ -1370,6 +1761,10 @@ struct CorrFit { registry.fill(HIST("Nch_corrected"), multiplicity); } + if (multiplicity > cfgMaxMultForCorrelations || multiplicity < cfgMinMultForCorrelations) { + return; + } + fillCorrelations(tracks, tracks, collision.posZ(), SameEvent, multiplicity, getMagneticField(bc.timestamp())); } PROCESS_SWITCH(CorrFit, processSameTPC, "Process same event for TPC-TPC correlation", false); @@ -1404,7 +1799,15 @@ struct CorrFit { continue; registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin - loadCorrection(collision1.bc_as().timestamp()); + + auto bc = collision1.bc_as(); + int currentRunNumber = bc.runNumber(); + if (!cfgRunRemoveList.value.empty()) { + if (!isGoodRun(currentRunNumber)) // Rejects runs if bad run number + return; + } + + loadCorrection(bc.timestamp()); double multiplicity = tracks1.size(); @@ -1412,11 +1815,16 @@ struct CorrFit { trackCounter(tracks1, multiplicity); } + if (multiplicity > cfgMaxMultForCorrelations || multiplicity < cfgMinMultForCorrelations) { + return; + } + fillCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, multiplicity, getMagneticField(collision1.bc_as().timestamp())); } } PROCESS_SWITCH(CorrFit, processMixedTPC, "Process mixed events for TPC-TPC correlation", false); }; + WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ diff --git a/PWGCF/TwoParticleCorrelations/Tasks/corrReso.cxx b/PWGCF/TwoParticleCorrelations/Tasks/corrReso.cxx new file mode 100644 index 00000000000..fc61ae24d7d --- /dev/null +++ b/PWGCF/TwoParticleCorrelations/Tasks/corrReso.cxx @@ -0,0 +1,1738 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file corrReso.cxx +/// \brief Ultra long range correlation using forward FIT detectors and TPC, with focus on resonances +/// \author Thor Jensen (thor.kjaersgaard.jensen@cern.ch) + +#include "PWGCF/Core/CorrelationContainer.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/RCTSelectionFlags.h" +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponseITS.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::aod::rctsel; +using namespace constants::math; + +#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; + +static constexpr float LongArrayFloat[3][20] = {{1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}, {2.1, 2.2, 2.3, -2.1, -2.2, -2.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}, {3.1, 3.2, 3.3, -3.1, -3.2, -3.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}}; +static constexpr int LongArrayInt[3][20] = {{1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1}, {2, 2, 2, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1}, {3, 3, 3, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1}}; + +struct CorrReso { + o2::aod::ITSResponse itsResponse; + Service ccdb; + + O2_DEFINE_CONFIGURABLE(cfgUseAdditionalEventCut, bool, true, "Use additional event cut on mult correlations") + O2_DEFINE_CONFIGURABLE(cfgZVtxCut, float, 10.0f, "Accepted z-vertex range") + O2_DEFINE_CONFIGURABLE(cfgUseTransverseMomentum, bool, false, "Use transverse momentum for correlation container") + O2_DEFINE_CONFIGURABLE(cfgQaCheck, bool, true, "Enable QA histograms for event selection") + O2_DEFINE_CONFIGURABLE(cfgStrictTrackCounter, bool, false, "Strict track counter for multiplicity correlation cut, counts only tracks that pass all cuts and are used in the correlation") + O2_DEFINE_CONFIGURABLE(cfgRefpTt, bool, false, "Apply upper pT cut on reference tracks") + O2_DEFINE_CONFIGURABLE(cfgRefpTMax, float, 3.0f, "maximum pT for reference tracks if cfgRefpTt is true") + O2_DEFINE_CONFIGURABLE(cfgMinMultForCorrelations, int, 0, "minimum multiplicity for correlations") + O2_DEFINE_CONFIGURABLE(cfgMaxMultForCorrelations, int, 20, "maximum multiplicity for correlations") + O2_DEFINE_CONFIGURABLE(cfgRefMultiplicity, bool, false, "Use multiplicity of reference tracks for multiplicity correlation cut instead of Nch") + Configurable> cfgRunRemoveList{"cfgRunRemoveList", std::vector{-1}, "excluded run numbers"}; + + struct : ConfigurableGroup{ + O2_DEFINE_CONFIGURABLE(cfgPtCutMin, float, 0.2f, "minimum accepted track pT") + O2_DEFINE_CONFIGURABLE(cfgPtCutMax, float, 10.0f, "maximum accepted track pT") + O2_DEFINE_CONFIGURABLE(cfgEtaCut, float, 0.8f, "Eta cut") + O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5f, "max chi2 per TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCclu, float, 50.0f, "minimum TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCCrossedRows, float, 70.0f, "minimum TPC crossed rows") + O2_DEFINE_CONFIGURABLE(cfgCutITSclu, float, 5.0f, "minimum ITS clusters") + O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "max DCA to vertex z")} cfgTrackCuts; + + struct : ConfigurableGroup{ + O2_DEFINE_CONFIGURABLE(cfgCutOccupancyHigh, int, 2000, "High cut on TPC occupancy") + O2_DEFINE_CONFIGURABLE(cfgCutOccupancyLow, int, 0, "Low cut on TPC occupancy")} cfgEventSelection; + + Configurable> cfgUseEventCuts{"cfgUseEventCuts", {LongArrayInt[0], 14, 1, {"Filtered Events", "Sel8", "kNoTimeFrameBorder", "kNoITSROFrameBorder", "kNoSameBunchPileup", "kIsGoodZvtxFT0vsPV", "kNoCollInTimeRangeStandard", "kIsGoodITSLayersAll", "kIsGoodITSLayer0123", "kNoCollInRofStandard", "kNoHighMultCollInPrevRof", "Occupancy", "Multcorrelation", "T0AV0ACut"}, {"EvCuts"}}, "Labeled array (int) for various cuts on resonances"}; + + O2_DEFINE_CONFIGURABLE(cfgMinMixEventNum, int, 5, "Minimum number of events to mix") + O2_DEFINE_CONFIGURABLE(cfgSampleSize, double, 10, "Sample size for mixed event") + O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") + O2_DEFINE_CONFIGURABLE(cfgEfficiencyNch, std::string, "", "CCDB path to multiplicity dependent efficiency object") + O2_DEFINE_CONFIGURABLE(cfgCentralityWeight, std::string, "", "CCDB path to centrality weight object") + O2_DEFINE_CONFIGURABLE(cfgLocalEfficiency, bool, false, "Use local efficiency object") + O2_DEFINE_CONFIGURABLE(cfgLocalEfficiencyNch, bool, false, "Use local multiplicity dependent efficiency object"); + O2_DEFINE_CONFIGURABLE(cfgUseEventWeights, bool, false, "Use event weights for mixed event") + O2_DEFINE_CONFIGURABLE(cfgCentEstimator, int, 0, "0:FT0C; 1:FT0CVariant1; 2:FT0M; 3:FT0A") + + struct : ConfigurableGroup { + O2_DEFINE_CONFIGURABLE(cfgMultCentHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 10.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultCentLowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultT0CCutEnabled, bool, false, "Enable Global multiplicity vs T0C centrality cut") + Configurable> cfgMultT0CCutPars{"cfgMultT0CCutPars", std::vector{143.04, -4.58368, 0.0766055, -0.000727796, 2.86153e-06, 23.3108, -0.36304, 0.00437706, -4.717e-05, 1.98332e-07}, "Global multiplicity vs T0C centrality cut parameter values"}; + O2_DEFINE_CONFIGURABLE(cfgMultPVT0CCutEnabled, bool, false, "Enable PV multiplicity vs T0C centrality cut") + Configurable> cfgMultPVT0CCutPars{"cfgMultPVT0CCutPars", std::vector{195.357, -6.15194, 0.101313, -0.000955828, 3.74793e-06, 30.0326, -0.43322, 0.00476265, -5.11206e-05, 2.13613e-07}, "PV multiplicity vs T0C centrality cut parameter values"}; + O2_DEFINE_CONFIGURABLE(cfgMultMultPVHighCutFunction, std::string, "[0]+[1]*x + 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultPVLowCutFunction, std::string, "[0]+[1]*x - 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultGlobalPVCutEnabled, bool, false, "Enable global multiplicity vs PV multiplicity cut") + Configurable> cfgMultGlobalPVCutPars{"cfgMultGlobalPVCutPars", std::vector{-0.140809, 0.734344, 2.77495, 0.0165935}, "PV multiplicity vs T0C centrality cut parameter values"}; + O2_DEFINE_CONFIGURABLE(cfgMultMultV0AHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 4.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultV0ALowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultV0ACutEnabled, bool, false, "Enable global multiplicity vs V0A multiplicity cut") + Configurable> cfgMultMultV0ACutPars{"cfgMultMultV0ACutPars", std::vector{534.893, 184.344, 0.423539, -0.00331436, 5.34622e-06, 871.239, 53.3735, -0.203528, 0.000122758, 5.41027e-07}, "Global multiplicity vs V0A multiplicity cut parameter values"}; + std::vector multT0CCutPars; + std::vector multPVT0CCutPars; + std::vector multGlobalPVCutPars; + std::vector multMultV0ACutPars; + TF1* fMultPVT0CCutLow = nullptr; + TF1* fMultPVT0CCutHigh = nullptr; + TF1* fMultT0CCutLow = nullptr; + TF1* fMultT0CCutHigh = nullptr; + TF1* fMultGlobalPVCutLow = nullptr; + TF1* fMultGlobalPVCutHigh = nullptr; + TF1* fMultMultV0ACutLow = nullptr; + TF1* fMultMultV0ACutHigh = nullptr; + TF1* fT0AV0AMean = nullptr; + TF1* fT0AV0ASigma = nullptr; + O2_DEFINE_CONFIGURABLE(cfgV0AT0Acut, int, 5, "V0AT0A cut") + } cfgFuncParas; + + struct : ConfigurableGroup { + O2_DEFINE_CONFIGURABLE(cfgUseOnlyTPC, bool, true, "Use only TPC PID for daughter selection") + O2_DEFINE_CONFIGURABLE(cfgUseAntiLambda, bool, true, "Use AntiLambda candidates for analysis") + O2_DEFINE_CONFIGURABLE(cfgPIDUseRejection, bool, true, "True: use exclusion exclusion criteria for PID determination, false: don't use exclusion") + O2_DEFINE_CONFIGURABLE(cfgTpcCut, float, 3.0f, "TPC N-sigma cut for pions, kaons, protons") + O2_DEFINE_CONFIGURABLE(cfgPIDParticle, int, 0, "4 = kshort, 5 = lambda, 6 = phi, 0 for no PID") + O2_DEFINE_CONFIGURABLE(cfgUseItsPID, bool, true, "Use ITS PID for particle identification") + O2_DEFINE_CONFIGURABLE(cfgTofPtCut, float, 0.4f, "Minimum pt to use TOF N-sigma") + Configurable> nSigmas{"nSigmas", {LongArrayFloat[0], 6, 3, {"UpCut_pi", "UpCut_ka", "UpCut_pr", "LowCut_pi", "LowCut_ka", "LowCut_pr"}, {"TPC", "TOF", "ITS"}}, "Labeled array for n-sigma values for TPC, TOF, ITS for pions, kaons, protons (positive and negative)"}; + Configurable> cfgResoCuts{"cfgResoCuts", {LongArrayFloat[0], 12, 3, {"cos_PAs", "massMin", "massMax", "PosTrackPt", "NegTrackPt", "DCAPosToPVMin", "DCANegToPVMin", "Lifetime", "RadiusMin", "RadiusMax", "Rapidity", "ArmPodMinVal"}, {"K0", "Lambda", "Phi"}}, "Labeled array (float) for various cuts on resonances"}; + Configurable> cfgResoSwitches{"cfgResoSwitches", {LongArrayInt[0], 6, 3, {"UseCosPA", "NMassBins", "DCABetDaug", "UseProperLifetime", "UseV0Radius", "UseArmPodCut"}, {"K0", "Lambda", "Phi"}}, "Labeled array (int) for various cuts on resonances"}; + } cfgPIDConfigs; + + Configurable cfgCutFV0{"cfgCutFV0", 50., "FV0A threshold"}; + Configurable cfgCutFT0A{"cfgCutFT0A", 150., "FT0A threshold"}; + Configurable cfgCutFT0C{"cfgCutFT0C", 50., "FT0C threshold"}; + Configurable cfgCutZDC{"cfgCutZDC", 10., "ZDC threshold"}; + + SliceCache cache; + + ConfigurableAxis axisVertex{"axisVertex", {10, -10, 10}, "vertex axis for histograms"}; + ConfigurableAxis axisMult{"axisMult", {10, 0, 100}, "multiplicity axis for histograms"}; + ConfigurableAxis axisEta{"axisEta", {40, -1., 1.}, "eta axis for histograms"}; + ConfigurableAxis axisPhi{"axisPhi", {72, 0.0, constants::math::TwoPI}, "phi axis for histograms"}; + ConfigurableAxis axisPtFiner{"axisPtFiner", {98, 0.2, 10.0}, "pt axis for histograms"}; + ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -PIHalf, PIHalf * 3}, "delta phi axis for histograms"}; + ConfigurableAxis axisDeltaEtaTpcFt0a{"axisDeltaEtaTpcFt0a", {32, -5.8, -2.6}, "delta eta axis, -5.8~-2.6 for TPC-FT0A,"}; + ConfigurableAxis axisDeltaEtaTpcFt0c{"axisDeltaEtaTpcFt0c", {32, 1.2, 4.2}, "delta eta axis, 1.2~4.2 for TPC-FT0C"}; + ConfigurableAxis axisDeltaEtaFt0aFt0c{"axisDeltaEtaFt0aFt0c", {32, -1.5, 3.0}, "delta eta axis"}; + ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt trigger axis for histograms"}; + ConfigurableAxis axisVtxMix{"axisVtxMix", {VARIABLE_WIDTH, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "vertex axis for mixed event histograms"}; + ConfigurableAxis axisMultMix{"axisMultMix", {VARIABLE_WIDTH, 0, 10, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260}, "multiplicity / centrality axis for mixed event histograms"}; + ConfigurableAxis axisSample{"axisSample", {cfgSampleSize, 0, cfgSampleSize}, "sample axis for histograms"}; + ConfigurableAxis axisNch{"axisNch", {VARIABLE_WIDTH, 0, 10, 50, 70, 100}, "multiplicity axis for correlation container"}; + + ConfigurableAxis axisNsigmaTPC{"axisNsigmaTPC", {80, -5, 5}, "nsigmaTPC axis"}; + ConfigurableAxis axisNsigmaTOF{"axisNsigmaTOF", {80, -5, 5}, "nsigmaTOF axis"}; + + ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"}; + ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"}; + ConfigurableAxis axisPtEfficiency{"axisPtEfficiency", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt axis for efficiency histograms"}; + ConfigurableAxis axisAmplitudeFt0a{"axisAmplitudeFt0a", {5000, 0, 1000}, "FT0A amplitude"}; + ConfigurableAxis axisChannelFt0aAxis{"axisChannelFt0aAxis", {96, 0.0, 96.0}, "FT0A channel"}; + + Configurable cfgGainEqPath{"cfgGainEqPath", "Analysis/EventPlane/GainEq", "CCDB path for gain equalization constants"}; + Configurable cfgCorrLevel{"cfgCorrLevel", 0, "calibration step: 0 = no corr, 1 = gain corr"}; + ConfigurableAxis cfgaxisFITamp{"cfgaxisFITamp", {1000, 0, 5000}, ""}; + AxisSpec axisFit{cfgaxisFITamp, "fit amplitude"}; + AxisSpec axisChID = {220, 0, 220}; + + Filter collisionFilter = (nabs(aod::collision::posZ) < cfgZVtxCut); + Filter trackFilter = (nabs(aod::track::eta) < cfgTrackCuts.cfgEtaCut) && (cfgTrackCuts.cfgPtCutMin < aod::track::pt) && (cfgTrackCuts.cfgPtCutMax > aod::track::pt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)); + + using FilteredCollisions = soa::Filtered>; + using FilteredTracks = soa::Filtered>; + using V0TrackCandidate = aod::V0Datas; + + // FT0 geometry + o2::ft0::Geometry ft0Det; + static constexpr uint64_t Ft0IndexA = 96; + std::vector* offsetFT0; + std::vector cstFT0RelGain{}; + + // Corrections + TH3D* mEfficiency = nullptr; + TH1D* mEfficiencyNch = nullptr; + TH1D* mCentralityWeight = nullptr; + bool correctionsLoaded = false; + + // Define the outputs + OutputObj sameTpcFt0a{"sameEvent_TPC_FT0A"}; + OutputObj mixedTpcFt0a{"mixedEvent_TPC_FT0A"}; + OutputObj sameTpcFt0c{"sameEvent_TPC_FT0C"}; + OutputObj mixedTpcFt0c{"mixedEvent_TPC_FT0C"}; + OutputObj sameFt0aFt0c{"sameEvent_FT0A_FT0C"}; + OutputObj mixedFt0aFt0c{"mixedEvent_FT0A_FT0C"}; + + HistogramRegistry registry{"registry"}; + + // define global variables + TRandom3* gRandom = new TRandom3(); + + enum EventType { + SameEvent = 1, + MixedEvent = 3 + }; + + enum FITIndex { + kFT0A = 0, + kFT0C = 1 + }; + + enum PIDIndex { + kCharged = 0, + kPions, + kKaons, + kProtons, + kK0, + kLambda, + kPhi + }; + + enum PiKpArrayIndex { + iPionUp = 0, + iKaonUp, + iProtonUp, + iPionLow, + iKaonLow, + iProtonLow + }; + enum ResoArrayIndex { + iK0 = 0, + iLambda = 1, + iPhi = 2, + NResoParticles = 3 + }; + enum ResoParticleCuts { + kCosPA = 0, + kMassMin, + kMassMax, + kPosTrackPt, + kNegTrackPt, + kDCAPosToPVMin, + kDCANegToPVMin, + kLifeTime, + kRadiusMin, + kRadiusMax, + kRapidity, + kArmPodMinVal, + kNParticleCuts + }; + enum ResoParticleSwitches { + kUseCosPA = 0, + kMassBins, + kDCABetDaug, + kUseProperLifetime, + kUseV0Radius, + kUseArmPodCut, + kNParticleSwitches + }; + enum DetectorType { + kTPC = 0, + kTOF, + kITS + }; + + enum EventCutTypes { + kFilteredEvents = 0, + kAfterSel8, + kUseNoTimeFrameBorder, + kUseNoITSROFrameBorder, + kUseNoSameBunchPileup, + kUseGoodZvtxFT0vsPV, + kUseNoCollInTimeRangeStandard, + kUseGoodITSLayersAll, + kUseGoodITSLayer0123, + kUseNoCollInRofStandard, + kUseNoHighMultCollInPrevRof, + kUseOccupancy, + kUseMultCorrCut, + kUseT0AV0ACut, + kNEventCuts + }; + + enum EventCutType { + kEvCut1 = 0, + kNEvCutTypes = 1 + }; + + enum CentEstimators { + kCentFT0C = 0, + kCentFT0CVariant1, + kCentFT0M, + kCentFV0A, + // Count the total number of enum + kCount_CentEstimators + }; + + RCTFlagsChecker rctChecker{"CBT"}; + + void init(InitContext&) + { + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + auto now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + ccdb->setCreatedNotAfter(now); + + LOGF(info, "Starting init"); + + if (cfgPIDConfigs.cfgPIDParticle < kK0) { + LOGF(fatal, "The input number does not correspond to any particle"); + return; + } + + // Creating mass axis depending on particle - 4 = kshort, 5 = lambda, 6 = phi + AxisSpec axisInvMass = {10, 0, 1, "mass"}; + if (cfgPIDConfigs.cfgPIDParticle == kK0) + axisInvMass = {cfgPIDConfigs.cfgResoSwitches->getData()[kMassBins][iK0], cfgPIDConfigs.cfgResoCuts->getData()[kMassMin][iK0], cfgPIDConfigs.cfgResoCuts->getData()[kMassMax][iK0], "M_{#pi^{+}#pi^{-}} (GeV/c^{2})"}; + if (cfgPIDConfigs.cfgPIDParticle == kLambda) + axisInvMass = {cfgPIDConfigs.cfgResoSwitches->getData()[kMassBins][iLambda], cfgPIDConfigs.cfgResoCuts->getData()[kMassMin][iLambda], cfgPIDConfigs.cfgResoCuts->getData()[kMassMax][iLambda], "M_{p#pi^{-}} (GeV/c^{2})"}; + if (cfgPIDConfigs.cfgPIDParticle == kPhi) + axisInvMass = {cfgPIDConfigs.cfgResoSwitches->getData()[kMassBins][iPhi], cfgPIDConfigs.cfgResoCuts->getData()[kMassMin][iPhi], cfgPIDConfigs.cfgResoCuts->getData()[kMassMax][iPhi], "M_{K^{+}K^{-}} (GeV/c^{2})"}; + + if (doprocessSameTpcFt0a || doprocessSameTpcFt0c) { + if (cfgPIDConfigs.cfgPIDParticle == kK0) { // For K0 + registry.add("PiPlusTPC_K0", "", {HistType::kTH2D, {{axisPtFiner, axisNsigmaTPC}}}); + registry.add("PiMinusTPC_K0", "", {HistType::kTH2D, {{axisPtFiner, axisNsigmaTPC}}}); + registry.add("PiPlusTOF_K0", "", {HistType::kTH2D, {{axisPtFiner, axisNsigmaTOF}}}); + registry.add("PiMinusTOF_K0", "", {HistType::kTH2D, {{axisPtFiner, axisNsigmaTOF}}}); + registry.add("hK0Phi", "", {HistType::kTH1D, {axisPhi}}); + registry.add("hK0Eta", "", {HistType::kTH1D, {axisEta}}); + + registry.add("hK0Count", "Number of K0;; Count", {HistType::kTH1D, {{11, 0, 11}}}); + registry.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(1, "K0 candidates"); + registry.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(2, "Daughter pt"); + registry.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(3, "Mass cut"); + registry.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(4, "Rapidity cut"); + registry.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(5, "DCA to PV"); + registry.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(6, "DCA between daughters"); + registry.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(7, "V0radius"); + registry.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(8, "CosPA"); + registry.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(9, "Proper lifetime"); + registry.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(10, "ArmenterosPod"); + registry.get(HIST("hK0Count"))->GetXaxis()->SetBinLabel(11, "Daughter track selection"); + } + if (cfgPIDConfigs.cfgPIDParticle == kLambda) { // For Lambda + registry.add("PrPlusTPC_La", "", {HistType::kTH2D, {{axisPtFiner, axisNsigmaTPC}}}); + registry.add("PiMinusTPC_La", "", {HistType::kTH2D, {{axisPtFiner, axisNsigmaTPC}}}); + registry.add("PrPlusTOF_La", "", {HistType::kTH2D, {{axisPtFiner, axisNsigmaTOF}}}); + registry.add("PiMinusTOF_La", "", {HistType::kTH2D, {{axisPtFiner, axisNsigmaTOF}}}); + + if (cfgPIDConfigs.cfgUseAntiLambda) { + registry.add("PrMinusTPC_Al", "", {HistType::kTH2D, {{axisPtFiner, axisNsigmaTPC}}}); + registry.add("PiPlusTPC_Al", "", {HistType::kTH2D, {{axisPtFiner, axisNsigmaTPC}}}); + registry.add("PrMinusTOF_Al", "", {HistType::kTH2D, {{axisPtFiner, axisNsigmaTOF}}}); + registry.add("PiPlusTOF_Al", "", {HistType::kTH2D, {{axisPtFiner, axisNsigmaTOF}}}); + } + + registry.add("hLambdaPhi", "", {HistType::kTH1D, {axisPhi}}); + registry.add("hLambdaEta", "", {HistType::kTH1D, {axisEta}}); + + registry.add("hLambdaCount", "Number of Lambda;; Count", {HistType::kTH1D, {{10, 0, 10}}}); + registry.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(1, "Lambda candidates"); + registry.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(2, "Daughter pt"); + registry.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(3, "Mass cut"); + registry.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(4, "Rapidity cut"); + registry.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(5, "DCA to PV"); + registry.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(6, "DCA between daughters"); + registry.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(7, "V0radius"); + registry.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(8, "CosPA"); + registry.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(9, "Proper lifetime"); + registry.get(HIST("hLambdaCount"))->GetXaxis()->SetBinLabel(10, "Daughter track selection"); + } + } + if (doprocessSameFt0aFt0c || doprocessSameTpcFt0a || doprocessSameTpcFt0c) { + registry.add("hEventCountRct", "Number of Event;; Count", {HistType::kTH1D, {{2, 0, 2}}}); + registry.get(HIST("hEventCountRct"))->GetXaxis()->SetBinLabel(1, "rct fail"); + registry.get(HIST("hEventCountRct"))->GetXaxis()->SetBinLabel(2, "rct pass"); + registry.add("hEventCount", "Number of Event;; Count", {HistType::kTH1D, {{14, -0.5, 13.5}}}); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kFilteredEvents + 1, "Filtered events"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kAfterSel8 + 1, "After sel8"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseNoTimeFrameBorder + 1, "kNoTimeFrameBorder"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseNoITSROFrameBorder + 1, "kNoITSROFrameBorder"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseNoSameBunchPileup + 1, "kNoSameBunchPileup"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseGoodZvtxFT0vsPV + 1, "kIsGoodZvtxFT0vsPV"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseNoCollInTimeRangeStandard + 1, "kNoCollInTimeRangeStandard"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseGoodITSLayersAll + 1, "kIsGoodITSLayersAll"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseGoodITSLayer0123 + 1, "kIsGoodITSLayer0123"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseNoCollInRofStandard + 1, "kNoCollInRofStandard"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseNoHighMultCollInPrevRof + 1, "kNoHighMultCollInPrevRof"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseOccupancy + 1, "Occupancy Cut"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseMultCorrCut + 1, "MultCorrelation Cut"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kUseT0AV0ACut + 1, "T0AV0A cut"); + } + + if ((doprocessSameFt0aFt0c || doprocessSameTpcFt0a || doprocessSameTpcFt0c) && cfgQaCheck) { + registry.add("hPassedEventSelection", "Number of Event;; Count", {HistType::kTH1D, {{12, -0.5, 11.5}}}); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kFilteredEvents + 1, "Filtered events"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kAfterSel8 + 1, "After sel8"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseNoTimeFrameBorder + 1, "kNoTimeFrameBorder"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseNoITSROFrameBorder + 1, "kNoITSROFrameBorder"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseNoSameBunchPileup + 1, "kNoSameBunchPileup"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseGoodZvtxFT0vsPV + 1, "kIsGoodZvtxFT0vsPV"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseNoCollInTimeRangeStandard + 1, "kNoCollInTimeRangeStandard"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseGoodITSLayersAll + 1, "kIsGoodITSLayersAll"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseGoodITSLayer0123 + 1, "kIsGoodITSLayer0123"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseNoCollInRofStandard + 1, "kNoCollInRofStandard"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseNoHighMultCollInPrevRof + 1, "kNoHighMultCollInPrevRof"); + registry.get(HIST("hPassedEventSelection"))->GetXaxis()->SetBinLabel(kUseOccupancy + 1, "Occupancy Cut"); + } + + // Multiplicity correlation cuts + if (cfgUseEventCuts->getData()[kUseMultCorrCut][kEvCut1]) { + cfgFuncParas.multT0CCutPars = cfgFuncParas.cfgMultT0CCutPars; + cfgFuncParas.multPVT0CCutPars = cfgFuncParas.cfgMultPVT0CCutPars; + cfgFuncParas.multGlobalPVCutPars = cfgFuncParas.cfgMultGlobalPVCutPars; + cfgFuncParas.multMultV0ACutPars = cfgFuncParas.cfgMultMultV0ACutPars; + cfgFuncParas.fMultPVT0CCutLow = new TF1("fMultPVT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultPVT0CCutLow->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); + cfgFuncParas.fMultPVT0CCutHigh = new TF1("fMultPVT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultPVT0CCutHigh->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); + + cfgFuncParas.fMultT0CCutLow = new TF1("fMultT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultT0CCutLow->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); + cfgFuncParas.fMultT0CCutHigh = new TF1("fMultT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultT0CCutHigh->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); + + cfgFuncParas.fMultGlobalPVCutLow = new TF1("fMultGlobalPVCutLow", cfgFuncParas.cfgMultMultPVLowCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultGlobalPVCutLow->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); + cfgFuncParas.fMultGlobalPVCutHigh = new TF1("fMultGlobalPVCutHigh", cfgFuncParas.cfgMultMultPVHighCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultGlobalPVCutHigh->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); + + cfgFuncParas.fMultMultV0ACutLow = new TF1("fMultMultV0ACutLow", cfgFuncParas.cfgMultMultV0ALowCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultMultV0ACutLow->SetParameters(&(cfgFuncParas.multMultV0ACutPars[0])); + cfgFuncParas.fMultMultV0ACutHigh = new TF1("fMultMultV0ACutHigh", cfgFuncParas.cfgMultMultV0AHighCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultMultV0ACutHigh->SetParameters(&(cfgFuncParas.multMultV0ACutPars[0])); + } + if (cfgUseEventCuts->getData()[kUseT0AV0ACut][kEvCut1]) { + cfgFuncParas.fT0AV0AMean = new TF1("fT0AV0AMean", "[0]+[1]*x", 0, 200000); + cfgFuncParas.fT0AV0AMean->SetParameters(-1601.0581, 9.417652e-01); + cfgFuncParas.fT0AV0ASigma = new TF1("fT0AV0ASigma", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 200000); + cfgFuncParas.fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); + } + + if (doprocessSameTpcFt0a || doprocessSameTpcFt0c || doprocessSameFt0aFt0c) { + registry.add("Phi", "Phi", {HistType::kTH1D, {axisPhi}}); + registry.add("Eta", "Eta", {HistType::kTH1D, {axisEta}}); + registry.add("EtaCorrected", "EtaCorrected", {HistType::kTH1D, {axisEta}}); + registry.add("pTFiner", "pTFiner", {HistType::kTH1D, {axisPtFiner}}); + registry.add("pTFinerCorrected", "pTFinerCorrected", {HistType::kTH1D, {axisPtFiner}}); + registry.add("Nch", "N_{ch}", {HistType::kTH1D, {axisMult}}); + registry.add("zVtx", "zVtx", {HistType::kTH1D, {axisVertex}}); + + registry.add("FT0Amp", "", {HistType::kTH2F, {axisChID, axisFit}}); + registry.add("FT0AmpCorrect", "", {HistType::kTH2F, {axisChID, axisFit}}); + } // end of single particle distribution histograms + + if (cfgQaCheck) { + registry.add("Nch_corrected", "N_{ch} corrected", {HistType::kTH1D, {axisMult}}); + } + + if (doprocessSameTpcFt0a) { + registry.add("deltaEta_deltaPhi_same_TPC_FT0A", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0a}}); // check to see the delta eta and delta phi distribution + registry.add("deltaEta_deltaPhi_mixed_TPC_FT0A", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0a}}); + registry.add("Assoc_amp_same_TPC_FT0A", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); + registry.add("Assoc_amp_mixed_TPC_FT0A", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); + registry.add("Trig_hist_TPC_FT0A", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger, axisInvMass}}}); + } + if (doprocessSameTpcFt0c) { + registry.add("deltaEta_deltaPhi_same_TPC_FT0C", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0c}}); // check to see the delta eta and delta phi distribution + registry.add("deltaEta_deltaPhi_mixed_TPC_FT0C", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0c}}); + registry.add("Assoc_amp_same_TPC_FT0C", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); + registry.add("Assoc_amp_mixed_TPC_FT0C", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); + registry.add("Trig_hist_TPC_FT0C", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger, axisInvMass}}}); + } + if (doprocessSameFt0aFt0c) { + registry.add("deltaEta_deltaPhi_same_FT0A_FT0C", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaFt0aFt0c}}); // check to see the delta eta and delta phi distribution + registry.add("deltaEta_deltaPhi_mixed_FT0A_FT0C", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaFt0aFt0c}}); + registry.add("Trig_hist_FT0A_FT0C", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); + } + + registry.add("eventcount", "bin", {HistType::kTH1F, {{4, 0, 4, "bin"}}}); // histogram to see how many events are in the same and mixed event + + LOGF(info, "Initializing correlation container"); + + // Initialize Nch-related histograms and containers + + std::vector corrAxisTpcFt0a = {{axisSample, "Sample"}, + {axisVertex, "z-vtx (cm)"}, + {axisPtTrigger, "p_{T} (GeV/c)"}, + {axisInvMass}, + {axisDeltaPhi, "#Delta#varphi (rad)"}, + {axisDeltaEtaTpcFt0a, "#Delta#eta"}}; + + std::vector corrAxisTpcFt0c = {{axisSample, "Sample"}, + {axisVertex, "z-vtx (cm)"}, + {axisPtTrigger, "p_{T} (GeV/c)"}, + {axisInvMass}, + {axisDeltaPhi, "#Delta#varphi (rad)"}, + {axisDeltaEtaTpcFt0c, "#Delta#eta"}}; + + std::vector corrAxisFt0aFt0c = {{axisSample, "Sample"}, + {axisVertex, "z-vtx (cm)"}, + {axisPtTrigger, "p_{T} (GeV/c)"}, + {axisNch, "N_{ch}"}, + {axisDeltaPhi, "#Delta#varphi (rad)"}, + {axisDeltaEtaFt0aFt0c, "#Delta#eta"}}; + + std::vector effAxis = { + {axisEtaEfficiency, "#eta"}, + {axisPtEfficiency, "p_{T} (GeV/c)"}, + {axisVertexEfficiency, "z-vtx (cm)"}, + }; + std::vector userAxis; + + if (doprocessSameTpcFt0a) { + sameTpcFt0a.setObject(new CorrelationContainer("sameEvent_TPC_FT0A", "sameEvent_TPC_FT0A", corrAxisTpcFt0a, effAxis, userAxis)); + mixedTpcFt0a.setObject(new CorrelationContainer("mixedEvent_TPC_FT0A", "mixedEvent_TPC_FT0A", corrAxisTpcFt0a, effAxis, userAxis)); + } + if (doprocessSameTpcFt0c) { + sameTpcFt0c.setObject(new CorrelationContainer("sameEvent_TPC_FT0C", "sameEvent_TPC_FT0C", corrAxisTpcFt0c, effAxis, userAxis)); + mixedTpcFt0c.setObject(new CorrelationContainer("mixedEvent_TPC_FT0C", "mixedEvent_TPC_FT0C", corrAxisTpcFt0c, effAxis, userAxis)); + } + if (doprocessSameFt0aFt0c) { + sameFt0aFt0c.setObject(new CorrelationContainer("sameEvent_FT0A_FT0C", "sameEvent_FT0A_FT0C", corrAxisFt0aFt0c, effAxis, userAxis)); + mixedFt0aFt0c.setObject(new CorrelationContainer("mixedEvent_FT0A_FT0C", "mixedEvent_FT0A_FT0C", corrAxisFt0aFt0c, effAxis, userAxis)); + } + + LOGF(info, "End of init"); + } + + template + float getCentrality(TCollision const& collision) + { + float cent; + switch (cfgCentEstimator) { + case kCentFT0C: + cent = collision.centFT0C(); + break; + case kCentFT0CVariant1: + cent = collision.centFT0CVariant1(); + break; + case kCentFT0M: + cent = collision.centFT0M(); + break; + case kCentFV0A: + cent = collision.centFV0A(); + break; + default: + cent = collision.centFT0C(); + } + return cent; + } + + template + bool eventRct(TCollision const& collision, const bool fillCounter) + { + if (!rctChecker(collision)) { + if (fillCounter) + registry.fill(HIST("hEventCountRct"), 0.5); + + return 0; + } + if (fillCounter) + registry.fill(HIST("hEventCountRct"), 1.5); + + return 1; + } + + template + bool eventSelected(TCollision const& collision, const int mult, const bool fillCounter) + { + if (cfgUseEventCuts->getData()[kUseNoTimeFrameBorder][kEvCut1] && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + return 0; + } + if (fillCounter && cfgUseEventCuts->getData()[kUseNoTimeFrameBorder][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseNoTimeFrameBorder); + + if (cfgUseEventCuts->getData()[kUseNoITSROFrameBorder][kEvCut1] && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + return 0; + } + if (fillCounter && cfgUseEventCuts->getData()[kUseNoITSROFrameBorder][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseNoITSROFrameBorder); + + if (cfgUseEventCuts->getData()[kUseNoSameBunchPileup][kEvCut1] && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + // rejects collisions which are associated with the same "found-by-T0" bunch crossing + // https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof + return 0; + } + if (fillCounter && cfgUseEventCuts->getData()[kUseNoSameBunchPileup][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseNoSameBunchPileup); + + if (cfgUseEventCuts->getData()[kUseGoodZvtxFT0vsPV][kEvCut1] && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + // removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference + // use this cut at low multiplicities with caution + return 0; + } + if (fillCounter && cfgUseEventCuts->getData()[kUseGoodZvtxFT0vsPV][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseGoodZvtxFT0vsPV); + + if (cfgUseEventCuts->getData()[kUseNoCollInTimeRangeStandard][kEvCut1] && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + // no collisions in specified time range + return 0; + } + + if (fillCounter && cfgUseEventCuts->getData()[kUseNoCollInTimeRangeStandard][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseNoCollInTimeRangeStandard); + + if (cfgUseEventCuts->getData()[kUseGoodITSLayersAll][kEvCut1] && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + // from Jan 9 2025 AOT meeting + // cut time intervals with dead ITS staves + return 0; + } + + if (fillCounter && cfgUseEventCuts->getData()[kUseGoodITSLayersAll][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseGoodITSLayersAll); + + if (cfgUseEventCuts->getData()[kUseGoodITSLayer0123][kEvCut1] && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayer0123)) { + return 0; + } + if (fillCounter && cfgUseEventCuts->getData()[kUseGoodITSLayer0123][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseGoodITSLayer0123); + + if (cfgUseEventCuts->getData()[kUseNoCollInRofStandard][kEvCut1] && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + // no other collisions in this Readout Frame with per-collision multiplicity above threshold + return 0; + } + + if (fillCounter && cfgUseEventCuts->getData()[kUseNoCollInRofStandard][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseNoCollInRofStandard); + + if (cfgUseEventCuts->getData()[kUseNoHighMultCollInPrevRof][kEvCut1] && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + // veto an event if FT0C amplitude in previous ITS ROF is above threshold + return 0; + } + if (fillCounter && cfgUseEventCuts->getData()[kUseNoHighMultCollInPrevRof][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseNoHighMultCollInPrevRof); + + auto multNTracksPV = collision.multNTracksPV(); + auto occupancy = collision.trackOccupancyInTimeRange(); + + if (cfgUseEventCuts->getData()[kUseOccupancy][kEvCut1] && (occupancy < cfgEventSelection.cfgCutOccupancyLow || occupancy > cfgEventSelection.cfgCutOccupancyHigh)) { + return 0; + } + if (fillCounter && cfgUseEventCuts->getData()[kUseOccupancy][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseOccupancy); + + if (cfgUseEventCuts->getData()[kUseMultCorrCut][kEvCut1]) { + float cent = getCentrality(collision); + if (cfgFuncParas.cfgMultPVT0CCutEnabled) { + if (multNTracksPV < cfgFuncParas.fMultPVT0CCutLow->Eval(cent)) + return 0; + if (multNTracksPV > cfgFuncParas.fMultPVT0CCutHigh->Eval(cent)) + return 0; + } + if (cfgFuncParas.cfgMultT0CCutEnabled) { + if (mult < cfgFuncParas.fMultT0CCutLow->Eval(cent)) + return 0; + if (mult > cfgFuncParas.fMultT0CCutHigh->Eval(cent)) + return 0; + } + if (cfgFuncParas.cfgMultGlobalPVCutEnabled) { + if (mult < cfgFuncParas.fMultGlobalPVCutLow->Eval(multNTracksPV)) + return 0; + if (mult > cfgFuncParas.fMultGlobalPVCutHigh->Eval(multNTracksPV)) + return 0; + } + if (cfgFuncParas.cfgMultMultV0ACutEnabled) { + if (collision.multFV0A() < cfgFuncParas.fMultMultV0ACutLow->Eval(mult)) + return 0; + if (collision.multFV0A() > cfgFuncParas.fMultMultV0ACutHigh->Eval(mult)) + return 0; + } + } + + if (fillCounter && cfgUseEventCuts->getData()[kUseMultCorrCut][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseMultCorrCut); + + // V0A T0A 5 sigma cut + if (cfgUseEventCuts->getData()[kUseT0AV0ACut][kEvCut1] && (std::fabs(collision.multFV0A() - cfgFuncParas.fT0AV0AMean->Eval(collision.multFT0A())) > cfgFuncParas.cfgV0AT0Acut * cfgFuncParas.fT0AV0ASigma->Eval(collision.multFT0A()))) + return 0; + if (fillCounter && cfgUseEventCuts->getData()[kUseT0AV0ACut][kEvCut1]) + registry.fill(HIST("hEventCount"), kUseT0AV0ACut); + + return 1; + } + + template + void eventSelectedIndividually(TCollision const& collision) + { + registry.fill(HIST("hPassedEventSelection"), kFilteredEvents); + + if (collision.sel8()) { + registry.fill(HIST("hPassedEventSelection"), kAfterSel8); + } + + if (collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + registry.fill(HIST("hPassedEventSelection"), kUseNoTimeFrameBorder); + } + + if (collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + registry.fill(HIST("hPassedEventSelection"), kUseNoITSROFrameBorder); + } + + if (collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + registry.fill(HIST("hPassedEventSelection"), kUseNoSameBunchPileup); + } + + if (collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + registry.fill(HIST("hPassedEventSelection"), kUseGoodZvtxFT0vsPV); + } + + if (collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + registry.fill(HIST("hPassedEventSelection"), kUseNoCollInTimeRangeStandard); + } + + if (collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + registry.fill(HIST("hPassedEventSelection"), kUseGoodITSLayersAll); + } + + if (collision.selection_bit(o2::aod::evsel::kIsGoodITSLayer0123)) { + registry.fill(HIST("hPassedEventSelection"), kUseGoodITSLayer0123); + } + + if (collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + registry.fill(HIST("hPassedEventSelection"), kUseNoCollInRofStandard); + } + + if (collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + registry.fill(HIST("hPassedEventSelection"), kUseNoHighMultCollInPrevRof); + } + + auto occupancy = collision.trackOccupancyInTimeRange(); + if (cfgUseEventCuts->getData()[kUseOccupancy][kEvCut1] && (occupancy < cfgEventSelection.cfgCutOccupancyLow || occupancy > cfgEventSelection.cfgCutOccupancyHigh)) { + registry.fill(HIST("hPassedEventSelection"), kUseOccupancy); + } + } + + double getPhiFT0(uint64_t chno, int i) + { + // offsetFT0[0]: FT0A, offsetFT0[1]: FT0C + if (i > 1 || i < 0) { + LOGF(fatal, "kFIT Index %d out of range", i); + } + + ft0Det.calculateChannelCenter(); + auto chPos = ft0Det.getChannelCenter(chno); + return RecoDecay::phi(chPos.X() + (*offsetFT0)[i].getX(), chPos.Y() + (*offsetFT0)[i].getY()); + } + + double getEtaFT0(uint64_t chno, int i) + { + // offsetFT0[0]: FT0A, offsetFT0[1]: FT0C + if (i > 1 || i < 0) { + LOGF(fatal, "kFIT Index %d out of range", i); + } + ft0Det.calculateChannelCenter(); + auto chPos = ft0Det.getChannelCenter(chno); + auto x = chPos.X() + (*offsetFT0)[i].getX(); + auto y = chPos.Y() + (*offsetFT0)[i].getY(); + auto z = chPos.Z() + (*offsetFT0)[i].getZ(); + if (chno >= Ft0IndexA) { + z = -z; + } + auto r = std::sqrt(x * x + y * y); + auto theta = std::atan2(r, z); + return -std::log(std::tan(0.5 * theta)); + } + + void loadAlignParam(uint64_t timestamp) + { + offsetFT0 = ccdb->getForTimeStamp>("FT0/Calib/Align", timestamp); + if (offsetFT0 == nullptr) { + LOGF(fatal, "Could not load FT0/Calib/Align for timestamp %d", timestamp); + } + } + + template + bool trackSelected(TTrack const& track) + { + return ((track.tpcNClsFound() >= cfgTrackCuts.cfgCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgTrackCuts.cfgCutTPCCrossedRows) && (track.itsNCls() >= cfgTrackCuts.cfgCutITSclu) && (track.tpcChi2NCl() < cfgTrackCuts.cfgCutChi2prTPCcls) && (track.dcaZ() < cfgTrackCuts.cfgCutDCAz)); + } + + void loadGain(aod::BCsWithTimestamps::iterator const& bc) + { + cstFT0RelGain.clear(); + cstFT0RelGain = {}; + std::string fullPath; + + auto timestamp = bc.timestamp(); + constexpr int ChannelsFT0 = 208; + if (cfgCorrLevel == 0) { + for (auto i{0u}; i < ChannelsFT0; i++) { + cstFT0RelGain.push_back(1.); + } + } else { + fullPath = cfgGainEqPath; + fullPath += "/FT0"; + const auto objft0Gain = ccdb->getForTimeStamp>(fullPath, timestamp); + if (!objft0Gain) { + for (auto i{0u}; i < ChannelsFT0; i++) { + cstFT0RelGain.push_back(1.); + } + } else { + cstFT0RelGain = *(objft0Gain); + } + } + } + + template + void getChannel(TFT0s const& ft0, std::size_t const& iCh, int& id, float& ampl, int fitType, int system) + { + if (fitType == kFT0C) { + id = ft0.channelC()[iCh]; + id = id + Ft0IndexA; + ampl = ft0.amplitudeC()[iCh]; + if (system == SameEvent) + registry.fill(HIST("FT0Amp"), id, ampl); + ampl = ampl / cstFT0RelGain[id]; + if (system == SameEvent) { + registry.fill(HIST("FT0AmpCorrect"), id, ampl); + } + } else if (fitType == kFT0A) { + id = ft0.channelA()[iCh]; + ampl = ft0.amplitudeA()[iCh]; + if (system == SameEvent) + registry.fill(HIST("FT0Amp"), id, ampl); + ampl = ampl / cstFT0RelGain[id]; + if (system == SameEvent) { + registry.fill(HIST("FT0AmpCorrect"), id, ampl); + } + } else { + LOGF(fatal, "Cor Index %d out of range", fitType); + } + } + + template + int getNsigmaPID(TTrack track) + { + // Computing Nsigma arrays for pion, kaon, and protons + std::array nSigmaTPC = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()}; + std::array nSigmaTOF = {track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr()}; + std::array nSigmaITS = {itsResponse.nSigmaITS(track), itsResponse.nSigmaITS(track), itsResponse.nSigmaITS(track)}; + int pid = -1; // -1 = not identified, 1 = pion, 2 = kaon, 3 = proton + + std::array nSigmaToUse = cfgPIDConfigs.cfgUseItsPID ? nSigmaITS : nSigmaTPC; // Choose which nSigma to use: TPC or ITS + int kIndexDetector = cfgPIDConfigs.cfgUseItsPID ? kITS : kTPC; // Choose which nSigma to use: TPC or ITS + + bool isPion, isKaon, isProton; + bool isDetectedPion = nSigmaToUse[iPionUp] < cfgPIDConfigs.nSigmas->getData()[iPionUp][kIndexDetector] && nSigmaToUse[iPionUp] > cfgPIDConfigs.nSigmas->getData()[iPionLow][kIndexDetector]; + bool isDetectedKaon = nSigmaToUse[iKaonUp] < cfgPIDConfigs.nSigmas->getData()[iKaonUp][kIndexDetector] && nSigmaToUse[iKaonUp] > cfgPIDConfigs.nSigmas->getData()[iKaonLow][kIndexDetector]; + bool isDetectedProton = nSigmaToUse[iProtonUp] < cfgPIDConfigs.nSigmas->getData()[iProtonUp][kIndexDetector] && nSigmaToUse[iProtonUp] > cfgPIDConfigs.nSigmas->getData()[iProtonLow][kIndexDetector]; + + bool isTofPion = nSigmaTOF[iPionUp] < cfgPIDConfigs.nSigmas->getData()[iPionUp][kTOF] && nSigmaTOF[iPionUp] > cfgPIDConfigs.nSigmas->getData()[iPionLow][kTOF]; + bool isTofKaon = nSigmaTOF[iKaonUp] < cfgPIDConfigs.nSigmas->getData()[iKaonUp][kTOF] && nSigmaTOF[iKaonUp] > cfgPIDConfigs.nSigmas->getData()[iKaonLow][kTOF]; + bool isTofProton = nSigmaTOF[iProtonUp] < cfgPIDConfigs.nSigmas->getData()[iProtonUp][kTOF] && nSigmaTOF[iProtonUp] > cfgPIDConfigs.nSigmas->getData()[iProtonLow][kTOF]; + + if (track.pt() > cfgPIDConfigs.cfgTofPtCut && !track.hasTOF()) { + return -1; + } else if (track.pt() > cfgPIDConfigs.cfgTofPtCut && track.hasTOF()) { + isPion = isTofPion && isDetectedPion; + isKaon = isTofKaon && isDetectedKaon; + isProton = isTofProton && isDetectedProton; + } else { + isPion = isDetectedPion; + isKaon = isDetectedKaon; + isProton = isDetectedProton; + } + + if (cfgPIDConfigs.cfgPIDUseRejection && ((isPion && isKaon) || (isPion && isProton) || (isKaon && isProton))) { + return -1; // more than one particle satisfy the criteria + } + + if (isPion) { + pid = kPions; + } else if (isKaon) { + pid = kKaons; + } else if (isProton) { + pid = kProtons; + } else { + return -1; // no particle satisfies the criteria + } + + return pid; // -1 = not identified, 1 = pion, 2 = kaon, 3 = proton + } + + template + bool selectionV0Daughter(TTrack const& track, int pid) + { + if (!(track.itsNCls() > cfgTrackCuts.cfgCutITSclu)) + return false; + if (!track.hasTPC()) + return false; + if (!(track.tpcNClsFound() >= cfgTrackCuts.cfgCutTPCclu)) + return false; + if (!(track.tpcNClsCrossedRows() >= cfgTrackCuts.cfgCutTPCCrossedRows)) + return false; + if (!(track.dcaZ() < cfgTrackCuts.cfgCutDCAz)) + return false; + + if (cfgPIDConfigs.cfgUseOnlyTPC) { + if (pid == kPions && std::abs(track.tpcNSigmaPi()) > cfgPIDConfigs.cfgTpcCut) + return false; + if (pid == kKaons && std::abs(track.tpcNSigmaKa()) > cfgPIDConfigs.cfgTpcCut) + return false; + if (pid == kProtons && std::abs(track.tpcNSigmaPr()) > cfgPIDConfigs.cfgTpcCut) + return false; + } else { + int partIndex = getNsigmaPID(track); + int pidIndex = partIndex; // 1 = pion, 2 = kaon, 3 = proton + if (pidIndex != pid) + return false; + } + + return true; + } + + void loadCorrection(uint64_t timestamp) + { + if (correctionsLoaded) { + return; + } + if (cfgEfficiency.value.empty() == false) { + if (cfgLocalEfficiency) { + TFile* fEfficiencyTrigger = TFile::Open(cfgEfficiency.value.c_str(), "READ"); + mEfficiency = reinterpret_cast(fEfficiencyTrigger->Get("ccdb_object")); + + } else { + mEfficiency = ccdb->getForTimeStamp(cfgEfficiency, timestamp); + } + if (mEfficiency == nullptr) { + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgEfficiency.value.c_str()); + } + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgEfficiency.value.c_str(), (void*)mEfficiency); + } + if (cfgEfficiencyNch.value.empty() == false) { + if (cfgLocalEfficiencyNch) { + TFile* fEfficiencyTrigger = TFile::Open(cfgEfficiencyNch.value.c_str(), "READ"); + mEfficiencyNch = reinterpret_cast(fEfficiencyTrigger->Get("ccdb_object")); + + } else { + mEfficiencyNch = ccdb->getForTimeStamp(cfgEfficiencyNch, timestamp); + } + if (!mEfficiencyNch) { + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgEfficiencyNch.value.c_str()); + } + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgEfficiencyNch.value.c_str(), (void*)mEfficiencyNch); + } + if (cfgCentralityWeight.value.empty() == false) { + mCentralityWeight = ccdb->getForTimeStamp(cfgCentralityWeight, timestamp); + if (mCentralityWeight == nullptr) { + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgCentralityWeight.value.c_str()); + } + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgCentralityWeight.value.c_str(), (void*)mCentralityWeight); + } + correctionsLoaded = true; + } + + bool getEfficiencyCorrectionNch(float& weightNch, float pt) + { + float effNch = 1.; + if (mEfficiencyNch) { + + int ptBin = mEfficiencyNch->FindBin(pt); + effNch = mEfficiencyNch->GetBinContent(ptBin); + + } else { + effNch = 1.0; + } + if (effNch == 0) + return false; + weightNch = 1. / effNch; + return true; + } + + bool getEfficiencyCorrection(float& weight, float pt, float eta, float vertex) + { + float eff = 1.; + if (mEfficiency) { + + int etaBin = mEfficiency->GetXaxis()->FindBin(eta); // use the eta bin corresponding to eta=0 for the trigger particle efficiency + int ptBin = mEfficiency->GetYaxis()->FindBin(pt); + int vertexBin = mEfficiency->GetZaxis()->FindBin(vertex); // use the vertex bin corresponding to z=0 for the trigger particle efficiency + eff = mEfficiency->GetBinContent(etaBin, ptBin, vertexBin); + + } else { + eff = 1.0; + } + if (eff == 0) + return false; + weight = 1. / eff; + return true; + } + + template + void trackCounter(TTracks tracks, double& multiplicity) // function to count the number of tracks in the event and fill the histogram + { + double nTracksCorrected = 0; + float weightNch = 1.0f; + for (auto const& track : tracks) { + + if (cfgRefMultiplicity) { + if (track.pt() > cfgRefpTMax) + continue; + } + + if (!getEfficiencyCorrectionNch(weightNch, track.pt())) { + continue; + } + + nTracksCorrected += weightNch; + } + multiplicity = nTracksCorrected; + } + + template + void fillYield(TCollision collision, TTracks tracks) // function to fill the yield and etaphi histograms. + { + + float weff1 = 1.0; + float zvtx = collision.posZ(); + + for (auto const& track1 : tracks) { + + if (!trackSelected(track1)) { + continue; + } + + if (!getEfficiencyCorrection(weff1, track1.eta(), track1.pt(), zvtx)) { + continue; + } + + registry.fill(HIST("Phi"), RecoDecay::constrainAngle(track1.phi(), 0.0)); + registry.fill(HIST("Eta"), track1.eta()); + registry.fill(HIST("EtaCorrected"), track1.eta(), weff1); + registry.fill(HIST("pTFiner"), track1.pt()); + registry.fill(HIST("pTFinerCorrected"), track1.pt(), weff1); + } + } + + template + bool isSelectedK0(V0 const& candidate, float posZ, float posY, float posX) + { + double mk0 = candidate.mK0Short(); + + // separate the positive and negative V0 daughters + auto postrack = candidate.template posTrack_as(); + auto negtrack = candidate.template negTrack_as(); + + registry.fill(HIST("hK0Count"), 0.5); + if (postrack.pt() < cfgPIDConfigs.cfgResoCuts->getData()[kPosTrackPt][iK0] || negtrack.pt() < cfgPIDConfigs.cfgResoCuts->getData()[kNegTrackPt][iK0]) + return false; + registry.fill(HIST("hK0Count"), 1.5); + if (mk0 < cfgPIDConfigs.cfgResoCuts->getData()[kMassMin][iK0] && mk0 > cfgPIDConfigs.cfgResoCuts->getData()[kMassMax][iK0]) + return false; + registry.fill(HIST("hK0Count"), 2.5); + // Rapidity correction + if (candidate.yK0Short() > cfgPIDConfigs.cfgResoCuts->getData()[kRapidity][iK0]) + return false; + registry.fill(HIST("hK0Count"), 3.5); + // DCA cuts for K0short + if (std::abs(candidate.dcapostopv()) < cfgPIDConfigs.cfgResoCuts->getData()[kDCAPosToPVMin][iK0] || std::abs(candidate.dcanegtopv()) < cfgPIDConfigs.cfgResoCuts->getData()[kDCANegToPVMin][iK0]) + return false; + registry.fill(HIST("hK0Count"), 4.5); + if (std::abs(candidate.dcaV0daughters()) > cfgPIDConfigs.cfgResoSwitches->getData()[kDCABetDaug][iK0]) + return false; + registry.fill(HIST("hK0Count"), 5.5); + // v0 radius cuts + if (cfgPIDConfigs.cfgResoSwitches->getData()[kUseV0Radius][iK0] && (candidate.v0radius() < cfgPIDConfigs.cfgResoCuts->getData()[kRadiusMin][iK0] || candidate.v0radius() > cfgPIDConfigs.cfgResoCuts->getData()[kRadiusMax][iK0])) + return false; + registry.fill(HIST("hK0Count"), 6.5); + // cosine pointing angle cuts + if (candidate.v0cosPA() < cfgPIDConfigs.cfgResoCuts->getData()[kCosPA][iK0]) + return false; + registry.fill(HIST("hK0Count"), 7.5); + // Proper lifetime + float cTauK0 = candidate.distovertotmom(posX, posY, posZ) * massK0Short; + if (cfgPIDConfigs.cfgResoSwitches->getData()[kUseProperLifetime][iK0] && std::abs(cTauK0) > cfgPIDConfigs.cfgResoCuts->getData()[kLifeTime][iK0]) + return false; + registry.fill(HIST("hK0Count"), 8.5); + // ArmenterosPodolanskiCut + if (cfgPIDConfigs.cfgResoSwitches->getData()[kUseArmPodCut][iK0] && (candidate.qtarm() / std::abs(candidate.alpha())) < cfgPIDConfigs.cfgResoCuts->getData()[kArmPodMinVal][iK0]) + return false; + registry.fill(HIST("hK0Count"), 9.5); + // Selection on V0 daughters + if (!selectionV0Daughter(postrack, kPions) || !selectionV0Daughter(negtrack, kPions)) + return false; + registry.fill(HIST("hK0Count"), 10.5); + + registry.fill(HIST("hK0Phi"), candidate.phi()); + registry.fill(HIST("hK0Eta"), candidate.eta()); + registry.fill(HIST("PiPlusTPC_K0"), postrack.pt(), postrack.tpcNSigmaPi()); + registry.fill(HIST("PiPlusTOF_K0"), postrack.pt(), postrack.tofNSigmaPi()); + registry.fill(HIST("PiMinusTPC_K0"), negtrack.pt(), negtrack.tpcNSigmaPi()); + registry.fill(HIST("PiMinusTOF_K0"), negtrack.pt(), negtrack.tofNSigmaPi()); + + return true; + } + + template + bool isSelectedLambda(V0 const& candidate, float posZ, float posY, float posX) + { + bool isL = false; // Is lambda candidate + bool isAL = false; // Is anti-lambda candidate + + double mlambda = candidate.mLambda(); + double mantilambda = candidate.mAntiLambda(); + + // separate the positive and negative V0 daughters + auto postrack = candidate.template posTrack_as(); + auto negtrack = candidate.template negTrack_as(); + + registry.fill(HIST("hLambdaCount"), 0.5); + if (postrack.pt() < cfgPIDConfigs.cfgResoCuts->getData()[kPosTrackPt][iLambda] || negtrack.pt() < cfgPIDConfigs.cfgResoCuts->getData()[kNegTrackPt][iLambda]) + return false; + + registry.fill(HIST("hLambdaCount"), 1.5); + if (mlambda > cfgPIDConfigs.cfgResoCuts->getData()[kMassMin][iLambda] && mlambda < cfgPIDConfigs.cfgResoCuts->getData()[kMassMax][iLambda]) + isL = true; + if (mantilambda > cfgPIDConfigs.cfgResoCuts->getData()[kMassMin][iLambda] && mantilambda < cfgPIDConfigs.cfgResoCuts->getData()[kMassMax][iLambda]) + isAL = true; + + if (!isL && !isAL) { + return false; + } + registry.fill(HIST("hLambdaCount"), 2.5); + + // Rapidity correction + if (candidate.yLambda() > cfgPIDConfigs.cfgResoCuts->getData()[kRapidity][iLambda]) + return false; + registry.fill(HIST("hLambdaCount"), 3.5); + // DCA cuts for lambda and antilambda + if (isL) { + if (std::abs(candidate.dcapostopv()) < cfgPIDConfigs.cfgResoCuts->getData()[kDCAPosToPVMin][iLambda] || std::abs(candidate.dcanegtopv()) < cfgPIDConfigs.cfgResoCuts->getData()[kDCANegToPVMin][iLambda]) + return false; + } + if (isAL) { + if (std::abs(candidate.dcapostopv()) < cfgPIDConfigs.cfgResoCuts->getData()[kDCANegToPVMin][iLambda] || std::abs(candidate.dcanegtopv()) < cfgPIDConfigs.cfgResoCuts->getData()[kDCAPosToPVMin][iLambda]) + return false; + } + registry.fill(HIST("hLambdaCount"), 4.5); + if (std::abs(candidate.dcaV0daughters()) > cfgPIDConfigs.cfgResoSwitches->getData()[kDCABetDaug][iLambda]) + return false; + registry.fill(HIST("hLambdaCount"), 5.5); + // v0 radius cuts + if (cfgPIDConfigs.cfgResoSwitches->getData()[kUseV0Radius][iLambda] && (candidate.v0radius() < cfgPIDConfigs.cfgResoCuts->getData()[kRadiusMin][iLambda] || candidate.v0radius() > cfgPIDConfigs.cfgResoCuts->getData()[kRadiusMax][iLambda])) + return false; + registry.fill(HIST("hLambdaCount"), 6.5); + // cosine pointing angle cuts + if (candidate.v0cosPA() < cfgPIDConfigs.cfgResoCuts->getData()[kCosPA][iLambda]) + return false; + registry.fill(HIST("hLambdaCount"), 7.5); + // Proper lifetime + float cTauLambda = candidate.distovertotmom(posX, posY, posZ) * massLambda; + if (cfgPIDConfigs.cfgResoSwitches->getData()[kUseProperLifetime][iLambda] && cTauLambda > cfgPIDConfigs.cfgResoCuts->getData()[kLifeTime][iLambda]) + return false; + registry.fill(HIST("hLambdaCount"), 8.5); + if (isL) { + if (!selectionV0Daughter(postrack, kProtons) || !selectionV0Daughter(negtrack, kPions)) + return false; + } + if (isAL) { + if (!selectionV0Daughter(postrack, kPions) || !selectionV0Daughter(negtrack, kProtons)) + return false; + } + registry.fill(HIST("hLambdaCount"), 9.5); + + if (!cfgPIDConfigs.cfgUseAntiLambda && isAL) { // Reject the track if it is antilambda + return false; + } + + registry.fill(HIST("hLambdaPhi"), candidate.phi()); + registry.fill(HIST("hLambdaEta"), candidate.eta()); + if (isL) { + registry.fill(HIST("PrPlusTPC_La"), postrack.pt(), postrack.tpcNSigmaPr()); + registry.fill(HIST("PrPlusTOF_La"), postrack.pt(), postrack.tofNSigmaPr()); + registry.fill(HIST("PiMinusTPC_La"), negtrack.pt(), negtrack.tpcNSigmaPi()); + registry.fill(HIST("PiMinusTOF_La"), negtrack.pt(), negtrack.tofNSigmaPi()); + } + if (cfgPIDConfigs.cfgUseAntiLambda && isAL) { + registry.fill(HIST("PrMinusTPC_Al"), negtrack.pt(), negtrack.tpcNSigmaPr()); + registry.fill(HIST("PrMinusTOF_Al"), negtrack.pt(), negtrack.tofNSigmaPr()); + registry.fill(HIST("PiPlusTPC_Al"), postrack.pt(), postrack.tpcNSigmaPi()); + registry.fill(HIST("PiPlusTOF_Al"), postrack.pt(), postrack.tofNSigmaPi()); + } + + return true; + } + + template + void fillCorrelationsTPCFT0(TV0Tracks tracks1, TFT0s const& ft0, float posZ, float posY, float posX, int system, int corType, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + { + int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + + float triggerWeight = 1.0f; + // loop over all tracks + for (auto const& track1 : tracks1) { + double resoMass = -1; + + // 4 = kshort, 5 = lambda, 6 = phi + if (cfgPIDConfigs.cfgPIDParticle == kK0) { + if (!isSelectedK0(track1, posZ, posY, posX)) + continue; // Reject if called for K0 but V0 is not K0 + + resoMass = track1.mK0Short(); + } + + if (cfgPIDConfigs.cfgPIDParticle == kLambda) { + if (!isSelectedLambda(track1, posZ, posY, posX)) + continue; // Reject if called for Lambda but V0 is not lambda + + resoMass = track1.mLambda(); + } + + if (system == SameEvent) { + if (corType == kFT0C) { + registry.fill(HIST("Trig_hist_TPC_FT0C"), fSampleIndex, posZ, track1.pt(), resoMass, eventWeight * triggerWeight); + } else if (corType == kFT0A) { + registry.fill(HIST("Trig_hist_TPC_FT0A"), fSampleIndex, posZ, track1.pt(), resoMass, eventWeight * triggerWeight); + } + } + + std::size_t channelSize = 0; + if (corType == kFT0C) { + channelSize = ft0.channelC().size(); + } else if (corType == kFT0A) { + channelSize = ft0.channelA().size(); + } else { + LOGF(fatal, "Cor Index %d out of range", corType); + } + for (std::size_t iCh = 0; iCh < channelSize; iCh++) { + int chanelid = 0; + float ampl = 0.; + getChannel(ft0, iCh, chanelid, ampl, corType, system); + + auto phi = getPhiFT0(chanelid, corType); + auto eta = getEtaFT0(chanelid, corType); + + float deltaPhi = RecoDecay::constrainAngle(track1.phi() - phi, -PIHalf); + float deltaEta = track1.eta() - eta; + // fill the right sparse and histograms + if (system == SameEvent) { + if (corType == kFT0A) { + if (cfgQaCheck) { + registry.fill(HIST("Assoc_amp_same_TPC_FT0A"), chanelid, ampl); + registry.fill(HIST("deltaEta_deltaPhi_same_TPC_FT0A"), deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + } + sameTpcFt0a->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), resoMass, deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + } else if (corType == kFT0C) { + if (cfgQaCheck) { + registry.fill(HIST("Assoc_amp_same_TPC_FT0C"), chanelid, ampl); + registry.fill(HIST("deltaEta_deltaPhi_same_TPC_FT0C"), deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + } + sameTpcFt0c->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), resoMass, deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + } + } else if (system == MixedEvent) { + if (corType == kFT0A) { + if (cfgQaCheck) { + registry.fill(HIST("Assoc_amp_mixed_TPC_FT0A"), chanelid, ampl); + registry.fill(HIST("deltaEta_deltaPhi_mixed_TPC_FT0A"), deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + } + mixedTpcFt0a->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), resoMass, deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + } else if (corType == kFT0C) { + if (cfgQaCheck) { + registry.fill(HIST("Assoc_amp_mixed_TPC_FT0C"), chanelid, ampl); + registry.fill(HIST("deltaEta_deltaPhi_mixed_TPC_FT0C"), deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + } + mixedTpcFt0c->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), resoMass, deltaPhi, deltaEta, ampl * eventWeight * triggerWeight); + } + } + } + } + } + + template + void fillCorrelationsFT0AFT0C(TFT0s const& ft0Col1, TFT0s const& ft0Col2, float posZ, int system, int multiplicity, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + { + int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + + float triggerWeight = 1.0f; + std::size_t channelASize = ft0Col1.channelA().size(); + std::size_t channelCSize = ft0Col2.channelC().size(); + // loop over all tracks + for (std::size_t iChA = 0; iChA < channelASize; iChA++) { + + int chanelAid = 0; + float amplA = 0.; + getChannel(ft0Col1, iChA, chanelAid, amplA, kFT0A, system); + auto phiA = getPhiFT0(chanelAid, kFT0A); + auto etaA = getEtaFT0(chanelAid, kFT0A); + + if (system == SameEvent) { + registry.fill(HIST("Trig_hist_FT0A_FT0C"), fSampleIndex, posZ, 0.5, eventWeight * amplA); + } + + for (std::size_t iChC = 0; iChC < channelCSize; iChC++) { + int chanelCid = 0; + float amplC = 0.; + getChannel(ft0Col2, iChC, chanelCid, amplC, kFT0C, system); + auto phiC = getPhiFT0(chanelCid, kFT0C); + auto etaC = getEtaFT0(chanelCid, kFT0C); + float deltaPhi = RecoDecay::constrainAngle(phiA - phiC, -PIHalf); + float deltaEta = etaA - etaC; + + // fill the right sparse and histograms + if (system == SameEvent) { + if (cfgQaCheck) { + registry.fill(HIST("deltaEta_deltaPhi_same_FT0A_FT0C"), deltaPhi, deltaEta, amplA * amplC * eventWeight * triggerWeight); + } + sameFt0aFt0c->getPairHist()->Fill(step, fSampleIndex, posZ, 0.5, multiplicity, deltaPhi, deltaEta, amplA * amplC * eventWeight * triggerWeight); + } else if (system == MixedEvent) { + if (cfgQaCheck) { + registry.fill(HIST("deltaEta_deltaPhi_mixed_FT0A_FT0C"), deltaPhi, deltaEta, amplA * amplC * eventWeight * triggerWeight); + } + mixedFt0aFt0c->getPairHist()->Fill(step, fSampleIndex, posZ, 0.5, multiplicity, deltaPhi, deltaEta, amplA * amplC * eventWeight * triggerWeight); + } + } + } + } + + bool isGoodRun(int runNumber) + { + for (const auto& ExcludedRun : cfgRunRemoveList.value) { + if (runNumber == ExcludedRun) { + return false; + } + } + + return true; + } + + double massKaPlus = o2::constants::physics::MassKPlus; // same as MassKMinus + double massLambda = o2::constants::physics::MassLambda; // same as MassLambda0 and MassLambda0Bar + double massK0Short = o2::constants::physics::MassK0Short; // same as o2::constants::physics::MassK0 and o2::constants::physics::MassK0Bar + + void processSameTpcFt0a(FilteredCollisions::iterator const& collision, FilteredTracks const& tracks, aod::FT0s const&, aod::BCsWithTimestamps const&, aod::V0Datas const& V0s) + { + registry.fill(HIST("hEventCount"), kFilteredEvents); + + if (cfgQaCheck) { + eventSelectedIndividually(collision); + } + + if (!collision.sel8()) + return; + + registry.fill(HIST("hEventCount"), kAfterSel8); + + if (!eventRct(collision, true)) + return; + + auto bc = collision.bc_as(); + + int currentRunNumber = bc.runNumber(); + if (!cfgRunRemoveList.value.empty()) { + if (!isGoodRun(currentRunNumber)) // Rejects runs if bad run number + return; + } + + if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), true)) + return; + + if (!collision.has_foundFT0()) + return; + + loadAlignParam(bc.timestamp()); + loadGain(bc); + loadCorrection(bc.timestamp()); + float eventWeight = 1.0f; + + registry.fill(HIST("zVtx"), collision.posZ()); + + registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin + + fillYield(collision, tracks); + + double multiplicity = tracks.size(); + + if (cfgQaCheck) + registry.fill(HIST("Nch"), multiplicity); + + if (cfgStrictTrackCounter) { + trackCounter(tracks, multiplicity); + } + + if (cfgQaCheck) { + registry.fill(HIST("Nch_corrected"), multiplicity); + } + + if (multiplicity > cfgMaxMultForCorrelations || multiplicity < cfgMinMultForCorrelations) { + return; + } + + const auto& ft0 = collision.foundFT0(); + fillCorrelationsTPCFT0(V0s, ft0, collision.posZ(), collision.posY(), collision.posX(), SameEvent, kFT0A, eventWeight); + } + PROCESS_SWITCH(CorrReso, processSameTpcFt0a, "Process same event for TPC-FT0 correlation", false); + + void processMixedTpcFt0a(FilteredCollisions const& collisions, FilteredTracks const& tracks, aod::FT0s const&, aod::BCsWithTimestamps const&, aod::V0Datas const& V0s) + { + + auto getTracksSize = [&tracks, this](FilteredCollisions::iterator const& collision) { + auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); + auto mult = associatedTracks.size(); + return mult; + }; + + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; + + auto tracksTuple = std::make_tuple(V0s, tracks); + Pair pairs{binningOnVtxAndMult, cfgMinMixEventNum, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, v0s1, collision2, tracks2] = *it; + + if (!collision1.sel8() || !collision2.sel8()) + continue; + + if (!eventRct(collision1, false) || !eventRct(collision2, false)) + continue; + + auto tracks1 = tracks.sliceByCached(o2::aod::track::collisionId, collision1.globalIndex(), this->cache); + + if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), false)) + continue; + if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), false)) + continue; + + if (!(collision1.has_foundFT0() && collision2.has_foundFT0())) + continue; + + registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin + + auto bc = collision1.bc_as(); + int currentRunNumber = bc.runNumber(); + if (!cfgRunRemoveList.value.empty()) { + if (!isGoodRun(currentRunNumber)) // Rejects runs if bad run number + return; + } + + loadAlignParam(bc.timestamp()); + loadCorrection(bc.timestamp()); + float eventWeight = 1.0f; + + double multiplicity = tracks1.size(); + + if (cfgStrictTrackCounter) { + trackCounter(tracks1, multiplicity); + } + + if (multiplicity > cfgMaxMultForCorrelations || multiplicity < cfgMinMultForCorrelations) { + return; + } + + const auto& ft0 = collision2.foundFT0(); + fillCorrelationsTPCFT0(v0s1, ft0, collision1.posZ(), collision1.posY(), collision1.posX(), MixedEvent, kFT0A, eventWeight); + } + } + PROCESS_SWITCH(CorrReso, processMixedTpcFt0a, "Process mixed events for TPC-FT0A correlation", false); + + void processSameTpcFt0c(FilteredCollisions::iterator const& collision, FilteredTracks const& tracks, aod::FT0s const&, aod::BCsWithTimestamps const&, aod::V0Datas const& V0s) + { + registry.fill(HIST("hEventCount"), kFilteredEvents); + + if (cfgQaCheck) { + eventSelectedIndividually(collision); + } + + if (!collision.sel8()) + return; + + registry.fill(HIST("hEventCount"), kAfterSel8); + + if (!eventRct(collision, true)) + return; + + auto bc = collision.bc_as(); + int currentRunNumber = bc.runNumber(); + if (!cfgRunRemoveList.value.empty()) { + if (!isGoodRun(currentRunNumber)) // Rejects runs if bad run number + return; + } + + if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), true)) + return; + if (!collision.has_foundFT0()) + return; + loadAlignParam(bc.timestamp()); + loadGain(bc); + loadCorrection(bc.timestamp()); + + registry.fill(HIST("zVtx"), collision.posZ()); + + registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin + + const auto& ft0 = collision.foundFT0(); + + double multiplicity = tracks.size(); + + if (cfgQaCheck) + registry.fill(HIST("Nch"), multiplicity); + + if (cfgStrictTrackCounter) { + trackCounter(tracks, multiplicity); + } + + if (cfgQaCheck) { + registry.fill(HIST("Nch_corrected"), multiplicity); + } + + if (multiplicity > cfgMaxMultForCorrelations || multiplicity < cfgMinMultForCorrelations) { + return; + } + + fillCorrelationsTPCFT0(V0s, ft0, collision.posZ(), collision.posY(), collision.posX(), SameEvent, kFT0C, 1.0f); + } + PROCESS_SWITCH(CorrReso, processSameTpcFt0c, "Process same event for TPC-FT0C correlation", false); + + void processMixedTpcFt0c(FilteredCollisions const& collisions, FilteredTracks const& tracks, aod::FT0s const&, aod::BCsWithTimestamps const&, aod::V0Datas const& V0s) + { + + auto getTracksSize = [&tracks, this](FilteredCollisions::iterator const& collision) { + auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); + auto mult = associatedTracks.size(); + return mult; + }; + + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; + + auto tracksTuple = std::make_tuple(V0s, tracks); + Pair pairs{binningOnVtxAndMult, cfgMinMixEventNum, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, v0s1, collision2, tracks2] = *it; + if (!collision1.sel8() || !collision2.sel8()) + continue; + + if (!eventRct(collision1, false) || !eventRct(collision2, false)) + continue; + + auto tracks1 = tracks.sliceByCached(o2::aod::track::collisionId, collision1.globalIndex(), this->cache); + + if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), false)) + continue; + + if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), false)) + continue; + + if (!(collision1.has_foundFT0() && collision2.has_foundFT0())) + continue; + + registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin + auto bc = collision1.bc_as(); + int currentRunNumber = bc.runNumber(); + if (!cfgRunRemoveList.value.empty()) { + if (!isGoodRun(currentRunNumber)) // Rejects runs if bad run number + return; + } + loadAlignParam(bc.timestamp()); + loadCorrection(bc.timestamp()); + float eventWeight = 1.0f; + + const auto& ft0 = collision2.foundFT0(); + double multiplicity = tracks1.size(); + + if (cfgStrictTrackCounter) { + trackCounter(tracks, multiplicity); + } + + if (multiplicity > cfgMaxMultForCorrelations || multiplicity < cfgMinMultForCorrelations) { + return; + } + + fillCorrelationsTPCFT0(v0s1, ft0, collision1.posZ(), collision1.posY(), collision1.posX(), MixedEvent, kFT0C, eventWeight); + } + } + PROCESS_SWITCH(CorrReso, processMixedTpcFt0c, "Process mixed events for TPC-FT0C correlation", false); + + void processSameFt0aFt0c(FilteredCollisions::iterator const& collision, FilteredTracks const& tracks, aod::FT0s const&, aod::BCsWithTimestamps const&) + { + registry.fill(HIST("hEventCount"), kFilteredEvents); + + if (cfgQaCheck) { + eventSelectedIndividually(collision); + } + + if (!collision.sel8()) + return; + + registry.fill(HIST("hEventCount"), kAfterSel8); + + if (!eventRct(collision, true)) + return; + + auto bc = collision.bc_as(); + int currentRunNumber = bc.runNumber(); + if (!cfgRunRemoveList.value.empty()) { + if (!isGoodRun(currentRunNumber)) // Rejects runs if bad run number + return; + } + + if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), true)) + return; + + if (!collision.has_foundFT0()) + return; + + loadAlignParam(bc.timestamp()); + loadGain(bc); + loadCorrection(bc.timestamp()); + float eventWeight = 1.0f; + + const auto& ft0 = collision.foundFT0(); + + fillYield(collision, tracks); + + registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin + + double multiplicity = tracks.size(); + + if (cfgQaCheck) + registry.fill(HIST("Nch"), multiplicity); + + if (cfgStrictTrackCounter) { + trackCounter(tracks, multiplicity); + } + + if (cfgQaCheck) { + registry.fill(HIST("Nch_corrected"), multiplicity); + } + + if (multiplicity > cfgMaxMultForCorrelations || multiplicity < cfgMinMultForCorrelations) { + return; + } + + fillCorrelationsFT0AFT0C(ft0, ft0, collision.posZ(), SameEvent, multiplicity, eventWeight); + } + PROCESS_SWITCH(CorrReso, processSameFt0aFt0c, "Process same event for FT0A-FT0C correlation", true); + + void processMixedFt0aFt0c(FilteredCollisions const& collisions, FilteredTracks const& tracks, aod::FT0s const&, aod::BCsWithTimestamps const&) + { + + auto getTracksSize = [&tracks, this](FilteredCollisions::iterator const& collision) { + auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); + auto mult = associatedTracks.size(); + return mult; + }; + + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; + + auto tracksTuple = std::make_tuple(tracks, tracks); + Pair pairs{binningOnVtxAndMult, cfgMinMixEventNum, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, tracks1, collision2, tracks2] = *it; + + // should have the same event to TPC-FT0A/C correlations + if (!collision1.sel8() || !collision2.sel8()) + continue; + + if (!eventRct(collision1, false) || !eventRct(collision2, false)) + continue; + + if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), false)) + continue; + if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), false)) + continue; + + if (!(collision1.has_foundFT0() && collision2.has_foundFT0())) + continue; + + auto bc = collision1.bc_as(); + int currentRunNumber = bc.runNumber(); + if (!cfgRunRemoveList.value.empty()) { + if (!isGoodRun(currentRunNumber)) // Rejects runs if bad run number + return; + } + loadAlignParam(bc.timestamp()); + loadCorrection(bc.timestamp()); + float eventWeight = 1.0f; + + const auto& ft0Col1 = collision1.foundFT0(); + const auto& ft0Col2 = collision2.foundFT0(); + + double multiplicity = tracks1.size(); + + if (cfgStrictTrackCounter) { + trackCounter(tracks1, multiplicity); + } + + if (multiplicity > cfgMaxMultForCorrelations || multiplicity < cfgMinMultForCorrelations) { + return; + } + + registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin + + fillCorrelationsFT0AFT0C(ft0Col1, ft0Col2, collision1.posZ(), MixedEvent, multiplicity, eventWeight); + } + } + PROCESS_SWITCH(CorrReso, processMixedFt0aFt0c, "Process mixed events for FT0A-FT0C correlation", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + }; +} diff --git a/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx b/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx deleted file mode 100644 index 08a490c2e1d..00000000000 --- a/PWGCF/TwoParticleCorrelations/Tasks/corrSparse.cxx +++ /dev/null @@ -1,2125 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file CorrSparse.cxx -/// \brief Provides a sparse with usefull two particle correlation info -/// \author Thor Jensen (thor.kjaersgaard.jensen@cern.ch) - -#include "PWGCF/Core/CorrelationContainer.h" -#include "PWGMM/Mult/DataModel/bestCollisionTable.h" - -#include "Common/CCDB/EventSelectionParams.h" -#include "Common/Core/RecoDecay.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using namespace constants::math; - -namespace o2::aod -{ -namespace corrsparse -{ -DECLARE_SOA_COLUMN(Multiplicity, multiplicity, int); -} -DECLARE_SOA_TABLE(Multiplicity, "AOD", "MULTIPLICITY", - corrsparse::Multiplicity); - -} // namespace o2::aod - -// define the filtered collisions and tracks -#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; - -// static constexpr float LongArrayFloat[3][20] = {{1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}, {2.1, 2.2, 2.3, -2.1, -2.2, -2.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}, {3.1, 3.2, 3.3, -3.1, -3.2, -3.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}}; -// static constexpr int LongArrayInt[3][20] = {{1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1}, {2, 2, 2, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1}, {3, 3, 3, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1}}; - -struct CorrSparse { - Service ccdb; - - O2_DEFINE_CONFIGURABLE(cfgUseAdditionalEventCut, bool, false, "Use additional event cut on mult correlations") - O2_DEFINE_CONFIGURABLE(cfgZVtxCut, float, 10.0f, "Accepted z-vertex range") - O2_DEFINE_CONFIGURABLE(cfgQaCheck, bool, false, "Fill QA histograms for multiplicity and zVtx for events used in the analysis") - - struct : ConfigurableGroup{ - O2_DEFINE_CONFIGURABLE(cfgPtCutMin, float, 0.2f, "minimum accepted track pT") - O2_DEFINE_CONFIGURABLE(cfgPtCutMax, float, 10.0f, "maximum accepted track pT") - O2_DEFINE_CONFIGURABLE(cfgEtaCut, float, 0.8f, "Eta cut") - O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5f, "max chi2 per TPC clusters") - O2_DEFINE_CONFIGURABLE(cfgCutTPCclu, float, 50.0f, "minimum TPC clusters") - O2_DEFINE_CONFIGURABLE(cfgCutTPCCrossedRows, float, 70.0f, "minimum TPC crossed rows") - O2_DEFINE_CONFIGURABLE(cfgCutITSclu, float, 5.0f, "minimum ITS clusters") - O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "max DCA to vertex z") - - } cfgTrackCuts; - - struct : ConfigurableGroup{ - - O2_DEFINE_CONFIGURABLE(processFV0, bool, true, "Process FV0 correlations") - O2_DEFINE_CONFIGURABLE(processFT0A, bool, true, "Process FT0A correlations") - O2_DEFINE_CONFIGURABLE(processFT0C, bool, true, "Process FT0C correlations") - O2_DEFINE_CONFIGURABLE(processMFT, bool, true, "Process MFT correlations") - O2_DEFINE_CONFIGURABLE(withGain, bool, false, "Use gain for FT0A and FT0C") - - } cfgDetectorConfig; - - struct : ConfigurableGroup { - O2_DEFINE_CONFIGURABLE(cfgPtCutMinMFT, float, 0.5f, "minimum accepted MFT track pT") - O2_DEFINE_CONFIGURABLE(cfgPtCutMaxMFT, float, 10.0f, "maximum accepted MFT track pT") - O2_DEFINE_CONFIGURABLE(etaMftTrackMin, float, -3.6, "Minimum eta for MFT track") - O2_DEFINE_CONFIGURABLE(etaMftTrackMax, float, -2.5, "Maximum eta for MFT track") - O2_DEFINE_CONFIGURABLE(nClustersMftTrack, int, 5, "Minimum number of clusters for MFT track") - Configurable cutBestCollisionId{"cutBestCollisionId", 0, "cut on the best collision Id used in a filter"}; - Configurable etaMftTrackMaxFilter{"etaMftTrackMaxFilter", -2.0f, "Maximum value for the eta of MFT tracks when used in filter"}; - Configurable etaMftTrackMinFilter{"etaMftTrackMinFilter", -3.9f, "Minimum value for the eta of MFT tracks when used in filter"}; - Configurable mftMaxDCAxy{"mftMaxDCAxy", 2.0f, "Cut on dcaXY for MFT tracks"}; - Configurable mftMaxDCAz{"mftMaxDCAz", 2.0f, "Cut on dcaZ for MFT tracks"}; - } cfgMftConfig; - - struct : ConfigurableGroup{ - O2_DEFINE_CONFIGURABLE(cfgMinMult, int, 0, "Minimum multiplicity for collision") - O2_DEFINE_CONFIGURABLE(cfgMaxMult, int, 10, "Maximum multiplicity for collision") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoSameBunchPileup, bool, false, "rejects collisions which are associated with the same found-by-T0 bunch crossing") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoITSROFrameBorder, bool, false, "reject events at ITS ROF border") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoTimeFrameBorder, bool, false, "reject events at TF border") - O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodZvtxFT0vsPV, bool, false, "removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference, use this cut at low multiplicities with caution") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInTimeRangeStandard, bool, false, "no collisions in specified time range") - O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodITSLayer0123, bool, true, "cut time intervals with dead ITS layers 0,1,2,3") - O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodITSLayersAll, bool, true, "cut time intervals with dead ITS staves") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInRofStandard, bool, false, "no other collisions in this Readout Frame with per-collision multiplicity above threshold") - O2_DEFINE_CONFIGURABLE(cfgEvSelkNoHighMultCollInPrevRof, bool, false, "veto an event if FT0C amplitude in previous ITS ROF is above threshold") - O2_DEFINE_CONFIGURABLE(cfgEvSelMultCorrelation, bool, true, "Multiplicity correlation cut") - O2_DEFINE_CONFIGURABLE(cfgEvSelV0AT0ACut, bool, true, "V0A T0A 5 sigma cut") - O2_DEFINE_CONFIGURABLE(cfgEvSelOccupancy, bool, true, "Occupancy cut") - O2_DEFINE_CONFIGURABLE(cfgCutOccupancyHigh, int, 2000, "High cut on TPC occupancy") - O2_DEFINE_CONFIGURABLE(cfgCutOccupancyLow, int, 0, "Low cut on TPC occupancy") - - } cfgEventSelection; - - struct : ConfigurableGroup{ - - O2_DEFINE_CONFIGURABLE(cfgRejectFT0AInside, bool, false, "Rejection of inner ring channels of the FT0A detector") - O2_DEFINE_CONFIGURABLE(cfgRejectFT0AOutside, bool, false, "Rejection of outer ring channels of the FT0A detector") - O2_DEFINE_CONFIGURABLE(cfgRejectFT0CInside, bool, false, "Rejection of inner ring channels of the FT0C detector") - O2_DEFINE_CONFIGURABLE(cfgRejectFT0COutside, bool, false, "Rejection of outer ring channels of the FT0C detector") - O2_DEFINE_CONFIGURABLE(cfgRemapFT0ADeadChannels, bool, false, "If true, remap FT0A channels 60-63 to amplitudes from 92-95 respectively") - O2_DEFINE_CONFIGURABLE(cfgRemapFT0CDeadChannels, bool, false, "If true, remap FT0C channels 177->145, 176->144, 178->146, 179->147, 139->115")} cfgFITConfig; - - O2_DEFINE_CONFIGURABLE(cfgMinMixEventNum, int, 5, "Minimum number of events to mix") - O2_DEFINE_CONFIGURABLE(cfgMergingCut, float, 0.02, "Merging cut on track merge") - O2_DEFINE_CONFIGURABLE(cfgApplyTwoTrackEfficiency, bool, true, "Apply two track efficiency for tpc tpc") - O2_DEFINE_CONFIGURABLE(cfgRadiusLow, float, 0.8, "Low radius for merging cut") - O2_DEFINE_CONFIGURABLE(cfgRadiusHigh, float, 2.5, "High radius for merging cut") - O2_DEFINE_CONFIGURABLE(cfgSampleSize, double, 10, "Sample size for mixed event") - O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") - O2_DEFINE_CONFIGURABLE(cfgCentralityWeight, std::string, "", "CCDB path to centrality weight object") - O2_DEFINE_CONFIGURABLE(cfgLocalEfficiency, bool, false, "Use local efficiency object") - O2_DEFINE_CONFIGURABLE(cfgUseEventWeights, bool, false, "Use event weights for mixed event") - - struct : ConfigurableGroup { - O2_DEFINE_CONFIGURABLE(cfgMultCentHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 10.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); - O2_DEFINE_CONFIGURABLE(cfgMultCentLowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); - O2_DEFINE_CONFIGURABLE(cfgMultT0CCutEnabled, bool, false, "Enable Global multiplicity vs T0C centrality cut") - Configurable> cfgMultT0CCutPars{"cfgMultT0CCutPars", std::vector{143.04, -4.58368, 0.0766055, -0.000727796, 2.86153e-06, 23.3108, -0.36304, 0.00437706, -4.717e-05, 1.98332e-07}, "Global multiplicity vs T0C centrality cut parameter values"}; - O2_DEFINE_CONFIGURABLE(cfgMultPVT0CCutEnabled, bool, false, "Enable PV multiplicity vs T0C centrality cut") - Configurable> cfgMultPVT0CCutPars{"cfgMultPVT0CCutPars", std::vector{195.357, -6.15194, 0.101313, -0.000955828, 3.74793e-06, 30.0326, -0.43322, 0.00476265, -5.11206e-05, 2.13613e-07}, "PV multiplicity vs T0C centrality cut parameter values"}; - O2_DEFINE_CONFIGURABLE(cfgMultMultPVHighCutFunction, std::string, "[0]+[1]*x + 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); - O2_DEFINE_CONFIGURABLE(cfgMultMultPVLowCutFunction, std::string, "[0]+[1]*x - 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); - O2_DEFINE_CONFIGURABLE(cfgMultGlobalPVCutEnabled, bool, false, "Enable global multiplicity vs PV multiplicity cut") - Configurable> cfgMultGlobalPVCutPars{"cfgMultGlobalPVCutPars", std::vector{-0.140809, 0.734344, 2.77495, 0.0165935}, "PV multiplicity vs T0C centrality cut parameter values"}; - O2_DEFINE_CONFIGURABLE(cfgMultMultV0AHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 4.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); - O2_DEFINE_CONFIGURABLE(cfgMultMultV0ALowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); - O2_DEFINE_CONFIGURABLE(cfgMultMultV0ACutEnabled, bool, false, "Enable global multiplicity vs V0A multiplicity cut") - Configurable> cfgMultMultV0ACutPars{"cfgMultMultV0ACutPars", std::vector{534.893, 184.344, 0.423539, -0.00331436, 5.34622e-06, 871.239, 53.3735, -0.203528, 0.000122758, 5.41027e-07}, "Global multiplicity vs V0A multiplicity cut parameter values"}; - std::vector multT0CCutPars; - std::vector multPVT0CCutPars; - std::vector multGlobalPVCutPars; - std::vector multMultV0ACutPars; - TF1* fMultPVT0CCutLow = nullptr; - TF1* fMultPVT0CCutHigh = nullptr; - TF1* fMultT0CCutLow = nullptr; - TF1* fMultT0CCutHigh = nullptr; - TF1* fMultGlobalPVCutLow = nullptr; - TF1* fMultGlobalPVCutHigh = nullptr; - TF1* fMultMultV0ACutLow = nullptr; - TF1* fMultMultV0ACutHigh = nullptr; - TF1* fT0AV0AMean = nullptr; - TF1* fT0AV0ASigma = nullptr; - } cfgFuncParas; - - Configurable cfgCutFV0{"cfgCutFV0", 50., "FV0A threshold"}; - Configurable cfgCutFT0A{"cfgCutFT0A", 150., "FT0A threshold"}; - Configurable cfgCutFT0C{"cfgCutFT0C", 50., "FT0C threshold"}; - Configurable cfgCutZDC{"cfgCutZDC", 10., "ZDC threshold"}; - - SliceCache cache; - SliceCache cacheNch; - - ConfigurableAxis axisVertex{"axisVertex", {10, -10, 10}, "vertex axis for histograms"}; - ConfigurableAxis axisEta{"axisEta", {40, -1., 1.}, "eta axis for histograms"}; - ConfigurableAxis axisPhi{"axisPhi", {72, 0.0, constants::math::TwoPI}, "phi axis for histograms"}; - ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt axis for histograms"}; - ConfigurableAxis axisAmbiguity{"axisAmbiguity", {100, 0, 100}, "MFT track ambiguity axis for histograms"}; - - ConfigurableAxis axisEtaMft{"axisEtaMFT", {40, -3.6, -2.4}, "eta axis for MFT tracks in histograms"}; - ConfigurableAxis axisEtaFt0a{"axisEtaFT0A", {40, 3.5, 4.9}, "eta axis for FT0A in histograms"}; - ConfigurableAxis axisEtaFt0c{"axisEtaFT0C", {40, -3.3, -2.1}, "eta axis for FT0C in histograms"}; - ConfigurableAxis axisEtaFv0{"axisEtaFV0", {40, 2.2, 5.1}, "eta axis for FV0 in histograms"}; - - ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -PIHalf, PIHalf * 3}, "delta phi axis for histograms"}; - ConfigurableAxis axisDeltaEta{"axisDeltaEta", {48, -1.6, 1.6}, "delta eta axis for histograms"}; - ConfigurableAxis axisDeltaEtaTpcMft{"axisDeltaEtaTPCMFT", {48, 1.6, 4.6}, "delta eta axis for TPC-MFT histograms"}; - ConfigurableAxis axisDeltaEtaTpcFv0{"axisDeltaEtaTPCFV0", {48, -1.7, -5.9}, "delta eta axis for TPC-FV0 histograms"}; - ConfigurableAxis axisDeltaEtaTpcFt0a{"axisDeltaEtaTPCFT0A", {48, -5.7, -2.7}, "delta eta axis for TPC-FT0A histograms"}; - ConfigurableAxis axisDeltaEtaTpcFt0c{"axisDeltaEtaTPCFT0C", {48, 1.3, 4.1}, "delta eta axis for TPC-FT0C histograms"}; - ConfigurableAxis axisDeltaEtaMftFt0c{"axisDeltaEtaMFTFT0C", {48, -2.0, 0.6}, "delta eta axis for MFT-FT0C histograms"}; - ConfigurableAxis axisDeltaEtaMftFt0a{"axisDeltaEtaMFTFT0A", {48, -8.5, -5.9}, "delta eta axis for MFT-FT0A histograms"}; - ConfigurableAxis axisDeltaEtaMftFv0{"axisDeltaEtaMFTFV0", {48, -8.6, -4.7}, "delta eta axis for MFT-FV0 histograms"}; - ConfigurableAxis axisDeltaEtaFt0s{"axisDeltaEtaFT0S", {48, -8.6, 5.0}, "delta eta axis for FT0S histograms"}; - - ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt trigger axis for histograms"}; - ConfigurableAxis axisPtAssoc{"axisPtAssoc", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt associated axis for histograms"}; - ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100}, "multiplicity / centrality axis for histograms"}; - ConfigurableAxis vtxMix{"vtxMix", {VARIABLE_WIDTH, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "vertex axis for mixed event histograms"}; - ConfigurableAxis multMix{"multMix", {VARIABLE_WIDTH, 0, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100}, "multiplicity / centrality axis for mixed event histograms"}; - ConfigurableAxis axisSample{"axisSample", {cfgSampleSize, 0, cfgSampleSize}, "sample axis for histograms"}; - - ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"}; - ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"}; - ConfigurableAxis axisPtEfficiency{"axisPtEfficiency", {VARIABLE_WIDTH, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0}, "pt axis for efficiency histograms"}; - - ConfigurableAxis axisAmplitudeFt0a{"axisAmplitudeFt0a", {5000, 0, 1000}, "FT0A amplitude"}; - ConfigurableAxis axisChannelFt0aAxis{"axisChannelFt0aAxis", {96, 0.0, 96.0}, "FT0A channel"}; - - Configurable cfgGainEqPath{"cfgGainEqPath", "Analysis/EventPlane/GainEq", "CCDB path for gain equalization constants"}; - Configurable cfgCorrLevel{"cfgCorrLevel", 1, "calibration step: 0 = no corr, 1 = gain corr"}; - ConfigurableAxis cfgaxisFITamp{"cfgaxisFITamp", {1000, 0, 5000}, ""}; - AxisSpec axisFit{cfgaxisFITamp, "fit amplitude"}; - AxisSpec axisChID = {220, 0, 220}; - - // make the filters and cuts. - Filter collisionFilter = (nabs(aod::collision::posZ) < cfgZVtxCut); - Filter trackFilter = (nabs(aod::track::eta) < cfgTrackCuts.cfgEtaCut) && (cfgTrackCuts.cfgPtCutMin < aod::track::pt) && (cfgTrackCuts.cfgPtCutMax > aod::track::pt) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t)true)) && (aod::track::tpcChi2NCl < cfgTrackCuts.cfgCutChi2prTPCcls) && (aod::track::dcaZ < cfgTrackCuts.cfgCutDCAz); - - Filter mftTrackEtaFilter = ((aod::fwdtrack::eta < cfgMftConfig.etaMftTrackMaxFilter) && (aod::fwdtrack::eta > cfgMftConfig.etaMftTrackMinFilter)); - - // Filters below will be used for uncertainties - Filter mftTrackCollisionIdFilter = (aod::fwdtrack::bestCollisionId >= 0); - Filter mftTrackDcaXYFilter = (nabs(aod::fwdtrack::bestDCAXY) < cfgMftConfig.mftMaxDCAxy); - // Filter mftTrackDcaZFilter = (nabs(aod::fwdtrack::bestDCAZ) < cfgMftConfig.mftMaxDCAz); - - // using AodCollisions = soa::Filtered>; // aod::CentFT0Cs - // using AodTracks = soa::Filtered>; - - using AodCollisions = soa::Filtered>; - using AodTracks = soa::Filtered>; - using FilteredMftTracks = soa::Filtered; - using Reassociated2DMftTracks = aod::BestCollisionsFwd; - - Preslice perColGlobal = aod::track::collisionId; - - // FT0 geometry - o2::ft0::Geometry ft0Det; - o2::fv0::Geometry* fv0Det{}; - static constexpr uint64_t Ft0IndexA = 96; - std::vector* offsetFT0; - std::vector* offsetFV0; - - std::vector cstFT0RelGain{}; - - // Corrections - TH3D* mEfficiency = nullptr; - TH1D* mCentralityWeight = nullptr; - bool correctionsLoaded = false; - - // Define the outputs - - OutputObj same{"sameEvent"}; - OutputObj mixed{"mixedEvent"}; - - HistogramRegistry registry{"registry"}; - - // Define Global variables - - enum EventCutTypes { - kFilteredEvents = 0, - kAfterSel8, - kUseNoTimeFrameBorder, - kUseNoITSROFrameBorder, - kUseNoSameBunchPileup, - kUseGoodZvtxFT0vsPV, - kUseNoCollInTimeRangeStandard, - kUseGoodITSLayersAll, - kUseGoodITSLayer0123, - kUseNoCollInRofStandard, - kUseNoHighMultCollInPrevRof, - kUseOccupancy, - kUseMultCorrCut, - kUseT0AV0ACut, - kUseVertexITSTPC, - kUseTVXinTRD, - kNEventCuts - }; - - enum EventType { - SameEvent = 1, - MixedEvent = 3 - }; - - enum FITIndex { - kFT0A = 0, - kFT0C, - kFV0 - }; - - enum DetectorChannels { - kFT0AInnerRingMin = 0, - kFT0AInnerRingMax = 31, - kFT0AOuterRingMin = 32, - kFT0AOuterRingMax = 95, - kFT0CInnerRingMin = 96, - kFT0CInnerRingMax = 143, - kFT0COuterRingMin = 144, - kFT0COuterRingMax = 207 - }; - - std::array, 16> eventCuts; - - void init(InitContext&) - { - - const AxisSpec axisPhi{72, 0.0, constants::math::TwoPI, "#varphi"}; - const AxisSpec axisEta{40, -1., 1., "#eta"}; - const AxisSpec axisEtaFull{90, -4., 5., "#eta"}; - - ccdb->setURL("http://alice-ccdb.cern.ch"); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - - auto now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - ccdb->setCreatedNotAfter(now); - fv0Det = o2::fv0::Geometry::instance(o2::fv0::Geometry::eUninitialized); - - LOGF(info, "Starting init"); - - // Event Counter - if ((doprocessSameTpcFIT || doprocessSameTpcMft || doprocessSameTPC || doprocessSameMFTFIT || doprocessSameTpcMftReassociated2D || doprocessSameMftReassociated2DFIT || doprocessSameFT0s) && cfgUseAdditionalEventCut) { - registry.add("hEventCountSpecific", "Number of Event;; Count", {HistType::kTH1D, {{13, 0, 13}}}); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(1, "after sel8"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(2, "kNoSameBunchPileup"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(3, "kNoITSROFrameBorder"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(4, "kNoTimeFrameBorder"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(5, "kIsGoodZvtxFT0vsPV"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(6, "kNoCollInTimeRangeStandard"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(7, "kIsGoodITSLayer0123"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(8, "kIsGoodITSLayersAll"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(9, "kNoCollInRofStandard"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(10, "kNoHighMultCollInPrevRof"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(11, "occupancy"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(12, "MultCorrelation"); - registry.get(HIST("hEventCountSpecific"))->GetXaxis()->SetBinLabel(13, "cfgEvSelV0AT0ACut"); - } - - if (doprocessSameTpcMftReassociated2D || doprocessSameMftReassociated2DFIT) { - registry.add("hEventCountMftReassoc", "Number of Events;; Count", {HistType::kTH1D, {{4, 0, 4}}}); - registry.get(HIST("hEventCountMftReassoc"))->GetXaxis()->SetBinLabel(1, "all MFT tracks"); - registry.get(HIST("hEventCountMftReassoc"))->GetXaxis()->SetBinLabel(2, "MFT tracks after selection"); - registry.get(HIST("hEventCountMftReassoc"))->GetXaxis()->SetBinLabel(3, "ambiguous MFT tracks"); - registry.get(HIST("hEventCountMftReassoc"))->GetXaxis()->SetBinLabel(4, "non-ambiguous MFT tracks"); - - registry.add("ReassociatedMftTracks", "Reassociated MFT tracks", {HistType::kTH1D, {{2, 0, 2}}}); - registry.get(HIST("ReassociatedMftTracks"))->GetXaxis()->SetBinLabel(1, "Not Reassociated MFT tracks"); - registry.get(HIST("ReassociatedMftTracks"))->GetXaxis()->SetBinLabel(2, "Reassociated MFT tracks"); - } - - // Make histograms to check the distributions after cuts - if (doprocessSameTpcFIT || doprocessSameTpcMft || doprocessSameTPC || doprocessSameMFTFIT || doprocessSameTpcMftReassociated2D || doprocessSameMftReassociated2DFIT || doprocessSameFT0s) { - registry.add("Phi", "Phi", {HistType::kTH1D, {axisPhi}}); - if (doprocessSameMFTFIT) { - registry.add("Eta", "EtaMFT", {HistType::kTH1D, {axisEtaMft}}); - } - if (doprocessSameTpcFIT || doprocessSameTpcMft || doprocessSameTPC || doprocessSameTpcMftReassociated2D) { - registry.add("Eta", "Eta", {HistType::kTH1D, {axisEta}}); - } - registry.add("EtaCorrected", "EtaCorrected", {HistType::kTH1D, {axisEta}}); - registry.add("pT", "pT", {HistType::kTH1D, {axisPtTrigger}}); - registry.add("pTCorrected", "pTCorrected", {HistType::kTH1D, {axisPtTrigger}}); - registry.add("Nch", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); - registry.add("Nch_used", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); // histogram to see how many events are in the same and mixed event - registry.add("zVtx", "zVtx", {HistType::kTH1D, {axisVertex}}); - registry.add("zVtx_used", "zVtx_used", {HistType::kTH1D, {axisVertex}}); - - if (doprocessSameTpcFIT || doprocessSameMFTFIT || doprocessSameMftReassociated2DFIT || doprocessSameFT0s) { - registry.add("FT0Amp", "", {HistType::kTH2F, {axisChID, axisFit}}); - registry.add("FV0Amp", "", {HistType::kTH2F, {axisChID, axisFit}}); - registry.add("FT0AmpCorrect", "", {HistType::kTH2F, {axisChID, axisFit}}); - registry.add("EtaPhi", "", {HistType::kTH2F, {axisEtaFull, axisPhi}}); - } - } - - if (doprocessSameTpcFIT) { - - if (cfgDetectorConfig.processFT0A) { - registry.add("deltaEta_deltaPhi_same_TPC_FT0A", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0a}}); // check to see the delta eta and delta phi distribution - registry.add("deltaEta_deltaPhi_mixed_TPC_FT0A", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0a}}); - registry.add("Assoc_amp_same", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); - registry.add("Assoc_amp_mixed", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); - registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); - } - if (cfgDetectorConfig.processFT0C) { - registry.add("deltaEta_deltaPhi_same_TPC_FT0C", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0c}}); // check to see the delta eta and delta phi distribution - registry.add("deltaEta_deltaPhi_mixed_TPC_FT0C", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFt0c}}); - registry.add("Assoc_amp_same", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); - registry.add("Assoc_amp_mixed", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); - registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); - } - if (cfgDetectorConfig.processFV0) { - registry.add("deltaEta_deltaPhi_same_TPC_FV0", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFv0}}); // check to see the delta eta and delta phi distribution - registry.add("deltaEta_deltaPhi_same_TPC_FV0", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFv0}}); // check to see the delta eta and delta phi distribution - registry.add("deltaEta_deltaPhi_mixed_TPC_FV0", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcFv0}}); - registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); - } - } - - if (doprocessSameMFTFIT || doprocessSameMftReassociated2DFIT) { - - if (cfgDetectorConfig.processFT0A) { - registry.add("deltaEta_deltaPhi_same_MFT_FT0A", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaMftFt0a}}); // check to see the delta eta and delta phi distribution - registry.add("deltaEta_deltaPhi_mixed_MFT_FT0A", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaMftFt0a}}); - registry.add("Assoc_amp_same", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); - registry.add("Assoc_amp_mixed", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); - registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); - } - if (cfgDetectorConfig.processFT0C) { - registry.add("deltaEta_deltaPhi_same_MFT_FT0C", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaMftFt0c}}); // check to see the delta eta and delta phi distribution - registry.add("deltaEta_deltaPhi_mixed_MFT_FT0C", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaMftFt0c}}); - registry.add("Assoc_amp_same", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); - registry.add("Assoc_amp_mixed", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); - registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); - } - if (cfgDetectorConfig.processFV0) { - registry.add("deltaEta_deltaPhi_same_MFT_FV0", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaMftFv0}}); // check to see the delta eta and delta phi distribution - registry.add("deltaEta_deltaPhi_mixed_MFT_FV0", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaMftFv0}}); - registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); - registry.add("Assoc_amp_same", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); - registry.add("Assoc_amp_mixed", "", {HistType::kTH2D, {axisChannelFt0aAxis, axisAmplitudeFt0a}}); - } - } - - if (doprocessSameTpcMft || doprocessSameTpcMftReassociated2D) { - registry.add("deltaEta_deltaPhi_same_TPC_MFT", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcMft}}); // check to see the delta eta and delta phi distribution - registry.add("deltaEta_deltaPhi_mixed_TPC_MFT", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaTpcMft}}); - registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); - } - - if (doprocessSameTPC) { - registry.add("deltaEta_deltaPhi_same_TPC_TPC", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); // check to see the delta eta and delta phi distribution - registry.add("deltaEta_deltaPhi_mixed_TPC_TPC", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); - registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); - } - - if (doprocessSameFT0s) { - registry.add("deltaEta_deltaPhi_same_FT0A_FT0C", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaFt0s}}); // check to see the delta eta and delta phi distribution - registry.add("deltaEta_deltaPhi_mixed_FT0A_FT0C", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEtaFt0s}}); - registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); - } - - registry.add("eventcount", "bin", {HistType::kTH1F, {{4, 0, 4, "bin"}}}); // histogram to see how many events are in the same and mixed event - - LOGF(info, "Initializing correlation container"); - - std::vector corrAxisTpcFt0c = {{axisSample, "Sample"}, - {axisVertex, "z-vtx (cm)"}, - {axisPtTrigger, "p_{T} (GeV/c)"}, - {axisPtAssoc, "p_{T} (GeV/c)"}, - {axisDeltaPhi, "#Delta#varphi (rad)"}, - {axisDeltaEtaTpcFt0c, "#Delta#eta"}}; - - std::vector effAxis = { - {axisEtaEfficiency, "#eta"}, - {axisPtEfficiency, "p_{T} (GeV/c)"}, - {axisVertexEfficiency, "z-vtx (cm)"}, - }; - - std::vector userAxis; - - // Correlation axis For TPC-FIT - - std::vector corrAxisTpcFt0a = {{axisSample, "Sample"}, - {axisVertex, "z-vtx (cm)"}, - {axisPtTrigger, "p_{T} (GeV/c)"}, - {axisPtAssoc, "p_{T} (GeV/c)"}, - {axisDeltaPhi, "#Delta#varphi (rad)"}, - {axisDeltaEtaTpcFt0a, "#Delta#eta"}}; - std::vector corrAxisTpcFv0 = {{axisSample, "Sample"}, - {axisVertex, "z-vtx (cm)"}, - {axisPtTrigger, "p_{T} (GeV/c)"}, - {axisPtAssoc, "p_{T} (GeV/c)"}, - {axisDeltaPhi, "#Delta#varphi (rad)"}, - {axisDeltaEtaTpcFv0, "#Delta#eta"}}; - - // correlation axis for TPC-TPC - std::vector corrAxisTpcTpc = {{axisSample, "Sample"}, - {axisVertex, "z-vtx (cm)"}, - {axisPtTrigger, "p_{T} (GeV/c)"}, - {axisPtAssoc, "p_{T} (GeV/c)"}, - {axisDeltaPhi, "#Delta#varphi (rad)"}, - {axisDeltaEta, "#Delta#eta"}}; - - // Correlation axis For TPC-MFT - std::vector corrAxisTpcMft = {{axisSample, "Sample"}, - {axisVertex, "z-vtx (cm)"}, - {axisPtTrigger, "p_{T} (GeV/c)"}, - {axisPtAssoc, "p_{T} (GeV/c)"}, - {axisDeltaPhi, "#Delta#varphi (rad)"}, - {axisDeltaEtaTpcMft, "#Delta#eta"}}; - - // Correlation axis For MFT-FIT - std::vector corrAxisMftFt0a = {{axisSample, "Sample"}, - {axisVertex, "z-vtx (cm)"}, - {axisPtTrigger, "p_{T} (GeV/c)"}, - {axisPtAssoc, "p_{T} (GeV/c)"}, - {axisDeltaPhi, "#Delta#varphi (rad)"}, - {axisDeltaEtaMftFt0a, "#Delta#eta"}}; - std::vector corrAxisMftFt0c = {{axisSample, "Sample"}, - {axisVertex, "z-vtx (cm)"}, - {axisPtTrigger, "p_{T} (GeV/c)"}, - {axisPtAssoc, "p_{T} (GeV/c)"}, - {axisDeltaPhi, "#Delta#varphi (rad)"}, - {axisDeltaEtaMftFt0c, "#Delta#eta"}}; - std::vector corrAxisMftFv0 = {{axisSample, "Sample"}, - {axisVertex, "z-vtx (cm)"}, - {axisPtTrigger, "p_{T} (GeV/c)"}, - {axisPtAssoc, "p_{T} (GeV/c)"}, - {axisDeltaPhi, "#Delta#varphi (rad)"}, - {axisDeltaEtaMftFv0, "#Delta#eta"}}; - - std::vector corrAxisFT0s = {{axisSample, "Sample"}, - {axisVertex, "z-vtx (cm)"}, - {axisPtTrigger, "p_{T} (GeV/c)"}, - {axisPtAssoc, "p_{T} (GeV/c)"}, - {axisDeltaPhi, "#Delta#varphi (rad)"}, - {axisDeltaEtaFt0s, "#Delta#eta"}}; - - if (doprocessSameTpcFIT) { - if (cfgDetectorConfig.processFT0A) { - same.setObject(new CorrelationContainer("sameEvent_TPC_FT0A", "sameEvent_TPC_FT0A", corrAxisTpcFt0a, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer("mixedEvent_TPC_FT0A", "mixedEvent_TPC_FT0A", corrAxisTpcFt0a, effAxis, userAxis)); - } - if (cfgDetectorConfig.processFT0C) { - same.setObject(new CorrelationContainer("sameEvent_TPC_FT0C", "sameEvent_TPC_FT0C", corrAxisTpcFt0c, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer("mixedEvent_TPC_FT0C", "mixedEvent_TPC_FT0C", corrAxisTpcFt0c, effAxis, userAxis)); - } - if (cfgDetectorConfig.processFV0) { - same.setObject(new CorrelationContainer("sameEvent_TPC_FV0", "sameEvent_TPC_FV0", corrAxisTpcFv0, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer("mixedEvent_TPC_FV0", "mixedEvent_TPC_FV0", corrAxisTpcFv0, effAxis, userAxis)); - } - } - - if (doprocessSameMFTFIT) { - if (cfgDetectorConfig.processFT0A) { - same.setObject(new CorrelationContainer("sameEvent_MFT_FT0A", "sameEvent_MFT_FT0A", corrAxisMftFt0a, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer("mixedEvent_MFT_FT0A", "mixedEvent_MFT_FT0A", corrAxisMftFt0a, effAxis, userAxis)); - } - if (cfgDetectorConfig.processFT0C) { - same.setObject(new CorrelationContainer("sameEvent_MFT_FT0C", "sameEvent_MFT_FT0C", corrAxisMftFt0c, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer("mixedEvent_MFT_FT0C", "mixedEvent_MFT_FT0C", corrAxisMftFt0c, effAxis, userAxis)); - } - if (cfgDetectorConfig.processFV0) { - same.setObject(new CorrelationContainer("sameEvent_MFT_FV0", "sameEvent_MFT_FV0", corrAxisMftFv0, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer("mixedEvent_MFT_FV0", "mixedEvent_MFT_FV0", corrAxisMftFv0, effAxis, userAxis)); - } - } - - if (doprocessSameMftReassociated2DFIT) { - if (cfgDetectorConfig.processFT0A) { - same.setObject(new CorrelationContainer("sameEvent_MFT_Reassociated2D_FT0A", "sameEvent_MFT_Reassociated2D_FT0A", corrAxisMftFt0a, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer("mixedEvent_MFT_Reassociated2D_FT0A", "mixedEvent_MFT_Reassociated2D_FT0A", corrAxisMftFt0a, effAxis, userAxis)); - } - if (cfgDetectorConfig.processFT0C) { - same.setObject(new CorrelationContainer("sameEvent_MFT_Reassociated2D_FT0C", "sameEvent_MFT_Reassociated2D_FT0C", corrAxisMftFt0c, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer("mixedEvent_MFT_Reassociated2D_FT0C", "mixedEvent_MFT_Reassociated2D_FT0C", corrAxisMftFt0c, effAxis, userAxis)); - } - if (cfgDetectorConfig.processFV0) { - same.setObject(new CorrelationContainer("sameEvent_MFT_Reassociated2D_FV0", "sameEvent_MFT_Reassociated2D_FV0", corrAxisMftFv0, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer("mixedEvent_MFT_Reassociated2D_FV0", "mixedEvent_MFT_Reassociated2D_FV0", corrAxisMftFv0, effAxis, userAxis)); - } - } - - if (doprocessSameTPC) { - same.setObject(new CorrelationContainer("sameEvent_TPC_TPC", "sameEvent_TPC_TPC", corrAxisTpcTpc, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer("mixedEvent_TPC_TPC", "mixedEvent_TPC_TPC", corrAxisTpcTpc, effAxis, userAxis)); - } - - if (doprocessSameTpcMft) { - same.setObject(new CorrelationContainer("sameEvent_TPC_MFT", "sameEvent_TPC_MFT", corrAxisTpcMft, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer("mixedEvent_TPC_MFT", "mixedEvent_TPC_MFT", corrAxisTpcMft, effAxis, userAxis)); - } - - if (doprocessSameTpcMftReassociated2D) { - same.setObject(new CorrelationContainer("sameEvent_TPC_MFT_Reassociated2D", "sameEvent_TPC_MFT_Reassociated2D", corrAxisTpcMft, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer("mixedEvent_TPC_MFT_Reassociated2D", "mixedEvent_TPC_MFT_Reassociated2D", corrAxisTpcMft, effAxis, userAxis)); - } - - if (doprocessSameFT0s) { - same.setObject(new CorrelationContainer("sameEvent_FT0A_FT0C", "sameEvent_FT0A_FT0C", corrAxisTpcFt0c, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer("mixedEvent_FT0A_FT0C", "mixedEvent_FT0A_FT0C", corrAxisTpcFt0c, effAxis, userAxis)); - } - LOGF(info, "End of init"); - } - - TRandom3* gRandom = new TRandom3(); - - template - bool eventSelected(TCollision collision, const int multTrk, const bool fillCounter) - { - registry.fill(HIST("hEventCountSpecific"), 0.5); - if (cfgEventSelection.cfgEvSelkNoSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { - // rejects collisions which are associated with the same "found-by-T0" bunch crossing - // https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof - return 0; - } - if (fillCounter && cfgEventSelection.cfgEvSelkNoSameBunchPileup) - registry.fill(HIST("hEventCountSpecific"), 1.5); - if (cfgEventSelection.cfgEvSelkNoITSROFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { - return 0; - } - if (fillCounter && cfgEventSelection.cfgEvSelkNoITSROFrameBorder) - registry.fill(HIST("hEventCountSpecific"), 2.5); - if (cfgEventSelection.cfgEvSelkNoTimeFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { - return 0; - } - if (fillCounter && cfgEventSelection.cfgEvSelkNoTimeFrameBorder) - registry.fill(HIST("hEventCountSpecific"), 3.5); - if (cfgEventSelection.cfgEvSelkIsGoodZvtxFT0vsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { - // removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference - // use this cut at low multiplicities with caution - return 0; - } - if (fillCounter && cfgEventSelection.cfgEvSelkIsGoodZvtxFT0vsPV) - registry.fill(HIST("hEventCountSpecific"), 4.5); - if (cfgEventSelection.cfgEvSelkNoCollInTimeRangeStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { - // no collisions in specified time range - return 0; - } - if (fillCounter && cfgEventSelection.cfgEvSelkNoCollInTimeRangeStandard) - registry.fill(HIST("hEventCountSpecific"), 5.5); - - if (cfgEventSelection.cfgEvSelkIsGoodITSLayer0123 && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayer0123)) { - // from Jan 9 2025 AOT meeting - // cut time intervals with dead ITS staves - return 0; - } - if (fillCounter && cfgEventSelection.cfgEvSelkIsGoodITSLayer0123) - registry.fill(HIST("hEventCountSpecific"), 6.5); - - if (cfgEventSelection.cfgEvSelkIsGoodITSLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { - // from Jan 9 2025 AOT meeting - // cut time intervals with dead ITS staves - return 0; - } - - if (fillCounter && cfgEventSelection.cfgEvSelkIsGoodITSLayersAll) - registry.fill(HIST("hEventCountSpecific"), 7.5); - - if (cfgEventSelection.cfgEvSelkNoCollInRofStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { - // no other collisions in this Readout Frame with per-collision multiplicity above threshold - return 0; - } - if (fillCounter && cfgEventSelection.cfgEvSelkNoCollInRofStandard) - registry.fill(HIST("hEventCountSpecific"), 8.5); - if (cfgEventSelection.cfgEvSelkNoHighMultCollInPrevRof && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { - // veto an event if FT0C amplitude in previous ITS ROF is above threshold - return 0; - } - if (fillCounter && cfgEventSelection.cfgEvSelkNoHighMultCollInPrevRof) - registry.fill(HIST("hEventCountSpecific"), 9.5); - auto occupancy = collision.trackOccupancyInTimeRange(); - if (cfgEventSelection.cfgEvSelOccupancy && (occupancy < cfgEventSelection.cfgCutOccupancyLow || occupancy > cfgEventSelection.cfgCutOccupancyHigh)) - return 0; - if (fillCounter && cfgEventSelection.cfgEvSelOccupancy) - registry.fill(HIST("hEventCountSpecific"), 10.5); - - auto multNTracksPV = collision.multNTracksPV(); - - if (cfgFuncParas.cfgMultGlobalPVCutEnabled) { - if (multTrk < cfgFuncParas.fMultGlobalPVCutLow->Eval(multNTracksPV)) - return 0; - if (multTrk > cfgFuncParas.fMultGlobalPVCutHigh->Eval(multNTracksPV)) - return 0; - } - if (cfgFuncParas.cfgMultMultV0ACutEnabled) { - if (collision.multFV0A() < cfgFuncParas.fMultMultV0ACutLow->Eval(multTrk)) - return 0; - if (collision.multFV0A() > cfgFuncParas.fMultMultV0ACutHigh->Eval(multTrk)) - return 0; - } - - if (fillCounter && cfgEventSelection.cfgEvSelMultCorrelation) - registry.fill(HIST("hEventCountSpecific"), 11.5); - - // V0A T0A 5 sigma cut - float sigma = 5.0; - if (cfgEventSelection.cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - cfgFuncParas.fT0AV0AMean->Eval(collision.multFT0A())) > sigma * cfgFuncParas.fT0AV0ASigma->Eval(collision.multFT0A()))) - return 0; - if (fillCounter && cfgEventSelection.cfgEvSelV0AT0ACut) - registry.fill(HIST("hEventCountSpecific"), 12.5); - - return 1; - } - - double getPhiFV0(uint64_t chno) - { - o2::fv0::Point3Dsimple chPos{}; - int const cellsInLeft[] = {0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27, 32, 40, 33, 41, 34, 42, 35, 43}; - bool const isChnoInLeft = std::find(std::begin(cellsInLeft), std::end(cellsInLeft), chno) != std::end(cellsInLeft); - - if (isChnoInLeft) { - chPos = fv0Det->getReadoutCenter(chno); - return RecoDecay::phi(chPos.x + (*offsetFV0)[0].getX(), chPos.y + (*offsetFV0)[0].getY()); - } else { - chPos = fv0Det->getReadoutCenter(chno); - return RecoDecay::phi(chPos.x + (*offsetFV0)[1].getX(), chPos.y + (*offsetFV0)[1].getY()); - } - } - - double getPhiFT0(uint64_t chno, int i) - { - // offsetFT0[0]: FT0A, offsetFT0[1]: FT0C - if (i > 1 || i < 0) { - LOGF(fatal, "kFIT Index %d out of range", i); - } - - ft0Det.calculateChannelCenter(); - auto chPos = ft0Det.getChannelCenter(chno); - return RecoDecay::phi(chPos.X() + (*offsetFT0)[i].getX(), chPos.Y() + (*offsetFT0)[i].getY()); - } - - double getEtaFV0(uint64_t chno) - { - - int const cellsInLeft[] = {0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27, 32, 40, 33, 41, 34, 42, 35, 43}; - bool const isChnoInLeft = std::find(std::begin(cellsInLeft), std::end(cellsInLeft), chno) != std::end(cellsInLeft); - - o2::fv0::Point3Dsimple chPos{}; - chPos = fv0Det->getReadoutCenter(chno); - - float offsetX, offsetY, offsetZ; - - if (isChnoInLeft) { - offsetX = (*offsetFV0)[0].getX(); - offsetY = (*offsetFV0)[0].getY(); - offsetZ = (*offsetFV0)[0].getZ(); - } else { - offsetX = (*offsetFV0)[1].getX(); - offsetY = (*offsetFV0)[1].getY(); - offsetZ = (*offsetFV0)[1].getZ(); - } - - auto x = chPos.x + offsetX; - auto y = chPos.y + offsetY; - auto z = chPos.z + offsetZ; - - auto r = std::sqrt(x * x + y * y); - auto theta = std::atan2(r, z); - - return -std::log(std::tan(0.5 * theta)); - } - - double getEtaFT0(uint64_t chno, int i) - { - // offsetFT0[0]: FT0A, offsetFT0[1]: FT0C - if (i > 1 || i < 0) { - LOGF(fatal, "kFIT Index %d out of range", i); - } - ft0Det.calculateChannelCenter(); - auto chPos = ft0Det.getChannelCenter(chno); - auto x = chPos.X() + (*offsetFT0)[i].getX(); - auto y = chPos.Y() + (*offsetFT0)[i].getY(); - auto z = chPos.Z() + (*offsetFT0)[i].getZ(); - if (chno >= Ft0IndexA) { - z = -z; - } - auto r = std::sqrt(x * x + y * y); - auto theta = std::atan2(r, z); - return -std::log(std::tan(0.5 * theta)); - } - - template - bool isAcceptedMftTrack(TTrack const& mftTrack) - { - // cut on the eta of MFT tracks - if (mftTrack.eta() < cfgMftConfig.etaMftTrackMin || mftTrack.eta() > cfgMftConfig.etaMftTrackMax) { - return false; - } - - // cut on the number of clusters of the reconstructed MFT track - if (mftTrack.nClusters() < cfgMftConfig.nClustersMftTrack) { - return false; - } - - if (mftTrack.pt() < cfgMftConfig.cfgPtCutMinMFT || mftTrack.pt() > cfgMftConfig.cfgPtCutMaxMFT) { - return false; - } - - return true; - } - - template - bool isAmbiguousMftTrack(TTrack const& mftTrack, bool fillHistogram) - { - if (mftTrack.ambDegree() > 1) { - if (fillHistogram) { - registry.fill(HIST("hEventCountMftReassoc"), 2.5); // fill histogram for events with at least one ambiguous track); - } - return false; - } - registry.fill(HIST("hEventCountMftReassoc"), 3.5); // fill histogram for events without ambiguous tracks - return true; - } - - void loadAlignParam(uint64_t timestamp) - { - offsetFT0 = ccdb->getForTimeStamp>("FT0/Calib/Align", timestamp); - offsetFV0 = ccdb->getForTimeStamp>("FV0/Calib/Align", timestamp); - if (offsetFT0 == nullptr) { - LOGF(fatal, "Could not load FT0/Calib/Align for timestamp %d", timestamp); - } - if (offsetFV0 == nullptr) { - LOGF(fatal, "Could not load FV0/Calib/Align for timestamp %d", timestamp); - } - } - - void loadGain(aod::BCsWithTimestamps::iterator const& bc) - { - cstFT0RelGain.clear(); - cstFT0RelGain = {}; - std::string fullPath; - - auto timestamp = bc.timestamp(); - constexpr int ChannelsFT0 = 208; - if (cfgCorrLevel == 0) { - for (auto i{0u}; i < ChannelsFT0; i++) { - cstFT0RelGain.push_back(1.); - } - } else { - fullPath = cfgGainEqPath; - fullPath += "/FT0"; - const auto objft0Gain = ccdb->getForTimeStamp>(fullPath, timestamp); - if (!objft0Gain) { - for (auto i{0u}; i < ChannelsFT0; i++) { - cstFT0RelGain.push_back(1.); - } - } else { - cstFT0RelGain = *(objft0Gain); - } - } - } - - template - void getChannelWithGain(TFT0s const& ft0, std::size_t const& iCh, int& id, float& ampl, int fitType) - { - if (fitType == kFT0C) { - id = ft0.channelC()[iCh]; - id = id + Ft0IndexA; - ampl = ft0.amplitudeC()[iCh]; - registry.fill(HIST("FT0Amp"), id, ampl); - ampl = ampl / cstFT0RelGain[id]; - registry.fill(HIST("FT0AmpCorrect"), id, ampl); - } else if (fitType == kFT0A) { - id = ft0.channelA()[iCh]; - ampl = ft0.amplitudeA()[iCh]; - registry.fill(HIST("FT0Amp"), id, ampl); - ampl = ampl / cstFT0RelGain[id]; - registry.fill(HIST("FT0AmpCorrect"), id, ampl); - } else { - LOGF(fatal, "Cor Index %d out of range", fitType); - } - } - - void loadCorrection(uint64_t timestamp) - { - if (correctionsLoaded) { - return; - } - if (cfgEfficiency.value.empty() == false) { - if (cfgLocalEfficiency > 0) { - TFile* fEfficiencyTrigger = TFile::Open(cfgEfficiency.value.c_str(), "READ"); - mEfficiency = reinterpret_cast(fEfficiencyTrigger->Get("ccdb_object")); - } else { - mEfficiency = ccdb->getForTimeStamp(cfgEfficiency, timestamp); - } - if (mEfficiency == nullptr) { - LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgEfficiency.value.c_str()); - } - LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgEfficiency.value.c_str(), (void*)mEfficiency); - } - if (cfgCentralityWeight.value.empty() == false) { - mCentralityWeight = ccdb->getForTimeStamp(cfgCentralityWeight, timestamp); - if (mCentralityWeight == nullptr) { - LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgCentralityWeight.value.c_str()); - } - LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgCentralityWeight.value.c_str(), (void*)mCentralityWeight); - } - correctionsLoaded = true; - } - - bool getEfficiencyCorrection(float& weight_nue, float eta, float pt, float posZ) - { - float eff = 1.; - if (mEfficiency) { - int etaBin = mEfficiency->GetXaxis()->FindBin(eta); - int ptBin = mEfficiency->GetYaxis()->FindBin(pt); - int zBin = mEfficiency->GetZaxis()->FindBin(posZ); - eff = mEfficiency->GetBinContent(etaBin, ptBin, zBin); - } else { - eff = 1.0; - } - if (eff == 0) - return false; - weight_nue = 1. / eff; - return true; - } - - template - void getChannelFT0(TFT0s const& ft0, std::size_t const& iCh, int& id, float& ampl, int fitType) - { - if (fitType == kFT0C) { - id = ft0.channelC()[iCh]; - id = id + Ft0IndexA; - ampl = ft0.amplitudeC()[iCh]; - } else if (fitType == kFT0A) { - id = ft0.channelA()[iCh]; - ampl = ft0.amplitudeA()[iCh]; - } else { - LOGF(fatal, "Cor Index %d out of range", fitType); - } - registry.fill(HIST("FT0Amp"), id, ampl); - } - - template - void getChannelFV0(TFT0s const& fv0, std::size_t const& iCh, int& id, float& ampl) - { - id = fv0.channel()[iCh]; - ampl = fv0.amplitude()[iCh]; - registry.fill(HIST("FV0Amp"), id, ampl); - } - - template - bool trackSelected(TTrack track) - { - return ((track.tpcNClsFound() >= cfgTrackCuts.cfgCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgTrackCuts.cfgCutTPCCrossedRows) && (track.itsNCls() >= cfgTrackCuts.cfgCutITSclu)); - } - - int getMagneticField(uint64_t timestamp) - { - // Get the magnetic field - static o2::parameters::GRPMagField* grpo = nullptr; - if (grpo == nullptr) { - grpo = ccdb->getForTimeStamp("/GLO/Config/GRPMagField", timestamp); - if (grpo == nullptr) { - LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); - return 0; - } - LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); - } - return grpo->getNominalL3Field(); - } - - // fill multiple histograms - template - void fillYield(TCollision collision, TTracks tracks) // function to fill the yield and etaphi histograms. - { - registry.fill(HIST("zVtx"), collision.posZ()); - registry.fill(HIST("Nch"), tracks.size()); - - float weff1 = 1.0; - float zvtx = collision.posZ(); - - for (auto const& track1 : tracks) { - - if constexpr (std::is_same_v) { - if (!isAcceptedMftTrack(track1)) { - continue; - } - } else { - if (!trackSelected(track1)) { - continue; - } - if (!getEfficiencyCorrection(weff1, track1.eta(), track1.pt(), zvtx)) { - continue; - } - } - - registry.fill(HIST("Phi"), RecoDecay::constrainAngle(track1.phi(), 0.0)); - registry.fill(HIST("Eta"), track1.eta()); - registry.fill(HIST("EtaCorrected"), track1.eta(), weff1); - registry.fill(HIST("pT"), track1.pt()); - registry.fill(HIST("pTCorrected"), track1.pt(), weff1); - } - } - - template - float getDPhiStar(TTrack const& track1, TTrackAssoc const& track2, float radius, int magField) - { - float charge1 = track1.sign(); - float charge2 = track2.sign(); - - float phi1 = track1.phi(); - float phi2 = track2.phi(); - - float pt1 = track1.pt(); - float pt2 = track2.pt(); - - int fbSign = (magField > 0) ? 1 : -1; - - float dPhiStar = phi1 - phi2 - charge1 * fbSign * std::asin(0.075 * radius / pt1) + charge2 * fbSign * std::asin(0.075 * radius / pt2); - - if (dPhiStar > constants::math::PI) - dPhiStar = constants::math::TwoPI - dPhiStar; - if (dPhiStar < -constants::math::PI) - dPhiStar = -constants::math::TwoPI - dPhiStar; - - return dPhiStar; - } - - // Correlations for detectors and TPC - - ////////////////////////////// - //////////MFT/TPC-FIT//////// - //////////////////////////// - template - void fillCorrelationsFIT(TTracks tracks1, TTracksAssociated tracks2, FITs const&, float posZ, int system, int corType, float multiplicity) - { - - int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); - float triggerWeight = 1.0f; - - // loop over all tracks - if (cfgQaCheck) { - - if (system == SameEvent) { - registry.fill(HIST("Nch_used"), multiplicity); - registry.fill(HIST("zVtx_used"), posZ); - } - } - - for (auto const& track1 : tracks1) { - - if constexpr (std::is_same_v) { - - if (!isAcceptedMftTrack(track1)) { - continue; - } - } else { - if (!trackSelected(track1)) { - continue; - } - - if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ)) - continue; - } - - if (system == SameEvent) { - registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), triggerWeight); - } - - // if using FV0A for correlations / using FV0A as associated particles - if constexpr (std::is_same_v) { - - std::size_t channelSize = tracks2.channel().size(); - for (std::size_t iCh = 0; iCh < channelSize; iCh++) { - int channelID = 0; - float amplitude = 0.; - - getChannelFV0(tracks2, iCh, channelID, amplitude); - - auto phi = getPhiFV0(channelID); - auto eta = getEtaFV0(channelID); - - float deltaPhi = RecoDecay::constrainAngle(track1.phi() - phi, -PIHalf); - float deltaEta = track1.eta() - eta; - - if (system == SameEvent) { - if (cfgDetectorConfig.processMFT) { - registry.fill(HIST("deltaEta_deltaPhi_same_MFT_FV0"), deltaPhi, deltaEta, amplitude * triggerWeight); - } else { - registry.fill(HIST("deltaEta_deltaPhi_same_TPC_FV0"), deltaPhi, deltaEta, amplitude * triggerWeight); - } - - registry.fill(HIST("Assoc_amp_same"), channelID, amplitude); - same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track1.pt(), deltaPhi, deltaEta, amplitude * triggerWeight); - - } else if (system == MixedEvent) { - if (cfgDetectorConfig.processMFT) { - registry.fill(HIST("deltaEta_deltaPhi_mixed_MFT_FV0"), deltaPhi, deltaEta, amplitude); - } else { - registry.fill(HIST("deltaEta_deltaPhi_mixed_TPC_FV0"), deltaPhi, deltaEta, amplitude); - } - registry.fill(HIST("Assoc_amp_mixed"), channelID, amplitude); - mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track1.pt(), deltaPhi, deltaEta, amplitude); - } - } - } - - // if using FT0A and FT0C for correlations / using FT0A and FT0C as associated particles - if constexpr (std::is_same_v) { - - std::size_t channelSize = 0; - if (corType == kFT0C) { - channelSize = tracks2.channelC().size(); - } else if (corType == kFT0A) { - channelSize = tracks2.channelA().size(); - } else { - LOGF(fatal, "Cor Index %d out of range", corType); - } - - for (std::size_t iCh = 0; iCh < channelSize; iCh++) { - int channelID = 0; - float amplitude = 0.; - if (cfgDetectorConfig.withGain) { - getChannelWithGain(tracks2, iCh, channelID, amplitude, corType); - } else { - getChannelFT0(tracks2, iCh, channelID, amplitude, corType); - } - - // reject depending on FT0C/FT0A rings - if (corType == kFT0C) { - if ((cfgFITConfig.cfgRejectFT0CInside && (channelID >= kFT0CInnerRingMin && channelID <= kFT0CInnerRingMax)) || (cfgFITConfig.cfgRejectFT0COutside && (channelID >= kFT0COuterRingMin && channelID <= kFT0COuterRingMax))) - continue; - } - if (corType == kFT0A) { - if ((cfgFITConfig.cfgRejectFT0AInside && (channelID >= kFT0AInnerRingMin && channelID <= kFT0AInnerRingMax)) || (cfgFITConfig.cfgRejectFT0AOutside && (channelID >= kFT0AOuterRingMin && channelID <= kFT0AOuterRingMax))) - continue; - } - - auto phi = getPhiFT0(channelID, corType); - auto eta = getEtaFT0(channelID, corType); - - float deltaPhi = RecoDecay::constrainAngle(track1.phi() - phi, -PIHalf); - float deltaEta = track1.eta() - eta; - - if (system == SameEvent) { - if (corType == kFT0A) { - if (cfgDetectorConfig.processMFT) { - registry.fill(HIST("deltaEta_deltaPhi_same_MFT_FT0A"), deltaPhi, deltaEta, amplitude * triggerWeight); - } else { - registry.fill(HIST("deltaEta_deltaPhi_same_TPC_FT0A"), deltaPhi, deltaEta, amplitude * triggerWeight); - } - registry.fill(HIST("Assoc_amp_same"), channelID, amplitude); - same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track1.pt(), deltaPhi, deltaEta, amplitude * triggerWeight); - } - if (corType == kFT0C) { - if (cfgDetectorConfig.processMFT) { - registry.fill(HIST("deltaEta_deltaPhi_same_MFT_FT0C"), deltaPhi, deltaEta, amplitude * triggerWeight); - } else { - registry.fill(HIST("deltaEta_deltaPhi_same_TPC_FT0C"), deltaPhi, deltaEta, amplitude * triggerWeight); - } - registry.fill(HIST("Assoc_amp_same"), channelID, amplitude); - same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track1.pt(), deltaPhi, deltaEta, amplitude * triggerWeight); - } - } else if (system == MixedEvent) { - if (corType == kFT0A) { - if (cfgDetectorConfig.processMFT) { - registry.fill(HIST("deltaEta_deltaPhi_mixed_MFT_FT0A"), deltaPhi, deltaEta, amplitude); - } else { - registry.fill(HIST("deltaEta_deltaPhi_mixed_TPC_FT0A"), deltaPhi, deltaEta, amplitude); - } - registry.fill(HIST("Assoc_amp_mixed"), channelID, amplitude); - mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track1.pt(), deltaPhi, deltaEta, amplitude); - } - if (corType == kFT0C) { - if (cfgDetectorConfig.processMFT) { - registry.fill(HIST("deltaEta_deltaPhi_mixed_MFT_FT0C"), deltaPhi, deltaEta, amplitude); - } else { - registry.fill(HIST("deltaEta_deltaPhi_mixed_TPC_FT0C"), deltaPhi, deltaEta, amplitude); - } - registry.fill(HIST("Assoc_amp_mixed"), channelID, amplitude); - mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track1.pt(), deltaPhi, deltaEta, amplitude); - } - } - } - } - } - } - ////////////////////////// - //////////MFT-Reassociated///////// - ////////////////////////// - - template - void fillCorrelationsMftReassociatedFIT(TTracks tracks1, TTracksAssociated tracks2, FITs const&, float posZ, int system, int corType, float multiplicity, bool cutAmbiguousTracks) - { - int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); - float triggerWeight = 1.0f; - - // loop over all tracks - if (cfgQaCheck) { - - if (system == SameEvent) { - registry.fill(HIST("Nch_used"), multiplicity); - registry.fill(HIST("zVtx_used"), posZ); - } - } - - for (auto const& track1 : tracks1) { - - auto reassociatedMftTrack = track1.template mfttrack_as(); - - if (!isAcceptedMftTrack(reassociatedMftTrack)) { - continue; - } - - if (isAmbiguousMftTrack(track1, false)) { - if (cutAmbiguousTracks) { - continue; - } - } - - if (system == SameEvent) { - - registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, reassociatedMftTrack.pt(), triggerWeight); - } - - if constexpr (std::is_same_v) { - - std::size_t channelSize = tracks2.channel().size(); - for (std::size_t iCh = 0; iCh < channelSize; iCh++) { - int channelID = 0; - float amplitude = 0.; - - getChannelFV0(tracks2, iCh, channelID, amplitude); - - auto phi = getPhiFV0(channelID); - auto eta = getEtaFV0(channelID); - - float deltaPhi = RecoDecay::constrainAngle(reassociatedMftTrack.phi() - phi, -PIHalf); - float deltaEta = reassociatedMftTrack.eta() - eta; - - if (system == SameEvent) { - registry.fill(HIST("Assoc_amp_same"), channelID, amplitude); - same->getPairHist()->Fill(step, fSampleIndex, posZ, reassociatedMftTrack.pt(), reassociatedMftTrack.pt(), deltaPhi, deltaEta, amplitude * triggerWeight); - registry.fill(HIST("deltaEta_deltaPhi_same_MFT_FV0"), deltaPhi, deltaEta, amplitude * triggerWeight); - } else if (system == MixedEvent) { - registry.fill(HIST("Assoc_amp_mixed"), channelID, amplitude); - mixed->getPairHist()->Fill(step, fSampleIndex, posZ, reassociatedMftTrack.pt(), reassociatedMftTrack.pt(), deltaPhi, deltaEta, amplitude); - registry.fill(HIST("deltaEta_deltaPhi_mixed_MFT_FV0"), deltaPhi, deltaEta, amplitude); - } - } - } - - // if using FT0A and FT0C for correlations / using FT0A and FT0C as associated particles - if constexpr (std::is_same_v) { - - std::size_t channelSize = 0; - if (corType == kFT0C) { - channelSize = tracks2.channelC().size(); - } else if (corType == kFT0A) { - channelSize = tracks2.channelA().size(); - } else { - LOGF(fatal, "Cor Index %d out of range", corType); - } - - for (std::size_t iCh = 0; iCh < channelSize; iCh++) { - int channelID = 0; - float amplitude = 0.; - getChannelWithGain(tracks2, iCh, channelID, amplitude, corType); - - // reject depending on FT0C/FT0A rings - if (corType == kFT0C) { - if ((cfgFITConfig.cfgRejectFT0CInside && (channelID >= kFT0CInnerRingMin && channelID <= kFT0CInnerRingMax)) || (cfgFITConfig.cfgRejectFT0COutside && (channelID >= kFT0COuterRingMin && channelID <= kFT0COuterRingMax))) - continue; - } - if (corType == kFT0A) { - if ((cfgFITConfig.cfgRejectFT0AInside && (channelID >= kFT0AInnerRingMin && channelID <= kFT0AInnerRingMax)) || (cfgFITConfig.cfgRejectFT0AOutside && (channelID >= kFT0AOuterRingMin && channelID <= kFT0AOuterRingMax))) - continue; - } - - auto phi = getPhiFT0(channelID, corType); - auto eta = getEtaFT0(channelID, corType); - - float deltaPhi = RecoDecay::constrainAngle(reassociatedMftTrack.phi() - phi, -PIHalf); - float deltaEta = reassociatedMftTrack.eta() - eta; - - if (system == SameEvent) { - if (corType == kFT0A) { - registry.fill(HIST("Assoc_amp_same"), channelID, amplitude); - same->getPairHist()->Fill(step, fSampleIndex, posZ, reassociatedMftTrack.pt(), reassociatedMftTrack.pt(), deltaPhi, deltaEta, amplitude * triggerWeight); - registry.fill(HIST("deltaEta_deltaPhi_same_MFT_FT0A"), deltaPhi, deltaEta, amplitude * triggerWeight); - } - if (corType == kFT0C) { - registry.fill(HIST("Assoc_amp_same"), channelID, amplitude); - same->getPairHist()->Fill(step, fSampleIndex, posZ, reassociatedMftTrack.pt(), reassociatedMftTrack.pt(), deltaPhi, deltaEta, amplitude * triggerWeight); - registry.fill(HIST("deltaEta_deltaPhi_same_MFT_FT0C"), deltaPhi, deltaEta, amplitude * triggerWeight); - } - } else if (system == MixedEvent) { - if (corType == kFT0A) { - registry.fill(HIST("Assoc_amp_mixed"), channelID, amplitude); - mixed->getPairHist()->Fill(step, fSampleIndex, posZ, reassociatedMftTrack.pt(), reassociatedMftTrack.pt(), deltaPhi, deltaEta, amplitude); - registry.fill(HIST("deltaEta_deltaPhi_mixed_MFT_FT0A"), deltaPhi, deltaEta, amplitude); - } - if (corType == kFT0C) { - registry.fill(HIST("Assoc_amp_mixed"), channelID, amplitude); - mixed->getPairHist()->Fill(step, fSampleIndex, posZ, reassociatedMftTrack.pt(), reassociatedMftTrack.pt(), deltaPhi, deltaEta, amplitude); - registry.fill(HIST("deltaEta_deltaPhi_mixed_MFT_FT0C"), deltaPhi, deltaEta, amplitude); - } - } - } - } - } - } - - template - void fillCorrelationsMftReassociatedTracks(TTracks tracks1, TTracksAssoc tracks2, float multiplicity, float posZ, int system, int magneticField, bool cutAmbiguousTracks) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms - { - - int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); - float triggerWeight = 1.0f; - - auto loopCounter = 0; - if (cfgQaCheck) { - - if (system == SameEvent) { - registry.fill(HIST("Nch_used"), multiplicity); - registry.fill(HIST("zVtx_used"), posZ); - } - } - // loop over all tracks - for (auto const& track1 : tracks1) { - - loopCounter++; - - if (!trackSelected(track1)) - continue; - - if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ)) - continue; - - if (system == SameEvent) { - registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), triggerWeight); - } - - for (auto const& track2 : tracks2) { - - if (!cutAmbiguousTracks && system == SameEvent && (loopCounter == 1)) { - registry.fill(HIST("hEventCountMftReassoc"), 0.5); // fill histogram for events with at least one reassociated track); - } - - auto reassociatedMftTrack = track2.template mfttrack_as(); - - if (!isAcceptedMftTrack(reassociatedMftTrack)) { - continue; - } - - if (!cutAmbiguousTracks && system == SameEvent && (loopCounter == 1)) { - registry.fill(HIST("hEventCountMftReassoc"), 1.5); // fill histogram for events with at least one reassociated track after track selection); - } - - if (isAmbiguousMftTrack(track2, (!cutAmbiguousTracks && system == SameEvent && (loopCounter == 1)))) { - - if (SameEvent && (loopCounter == 1)) { - registry.fill(HIST("ReassociatedMftTracks"), 0.5); - } - if (cutAmbiguousTracks) { - continue; - } - } - - if (reassociatedMftTrack.collisionId() != track2.bestCollisionId()) { - if (SameEvent && (loopCounter == 1)) { - registry.fill(HIST("ReassociatedMftTracks"), 1.5); - } - } - - float deltaPhi = RecoDecay::constrainAngle(track1.phi() - reassociatedMftTrack.phi(), -PIHalf); - float deltaEta = track1.eta() - reassociatedMftTrack.eta(); - - if (cfgApplyTwoTrackEfficiency && std::abs(deltaEta) < cfgMergingCut) { - - double dPhiStarHigh = getDPhiStar(track1, reassociatedMftTrack, cfgRadiusHigh, magneticField); - double dPhiStarLow = getDPhiStar(track1, reassociatedMftTrack, cfgRadiusLow, magneticField); - - const double kLimit = 3.0 * cfgMergingCut; - - bool bIsBelow = false; - - if (std::abs(dPhiStarLow) < kLimit || std::abs(dPhiStarHigh) < kLimit || dPhiStarLow * dPhiStarHigh < 0) { - for (double rad(cfgRadiusLow); rad < cfgRadiusHigh; rad += 0.01) { - double dPhiStar = getDPhiStar(track1, reassociatedMftTrack, rad, magneticField); - if (std::abs(dPhiStar) < kLimit) { - bIsBelow = true; - break; - } - } - if (bIsBelow) - continue; - } - } - - // fill the right sparse and histograms - if (system == SameEvent) { - - same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), reassociatedMftTrack.pt(), deltaPhi, deltaEta); - registry.fill(HIST("deltaEta_deltaPhi_same_TPC_MFT"), deltaPhi, deltaEta); - } else if (system == MixedEvent) { - - mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), reassociatedMftTrack.pt(), deltaPhi, deltaEta); - registry.fill(HIST("deltaEta_deltaPhi_mixed_TPC_MFT"), deltaPhi, deltaEta); - } - } - } - } - - /////////////////////////////////////// - //////////TPC-TPC and TPC-MFT///////// - ///////////////////////////////////// - template - void fillCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, float multiplicity, int system, int magneticField) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms - { - - int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); - - float triggerWeight = 1.0f; - - if (cfgQaCheck) { - if (system == SameEvent) { - registry.fill(HIST("Nch_used"), multiplicity); - registry.fill(HIST("zVtx_used"), posZ); - } - } - // loop over all tracks - for (auto const& track1 : tracks1) { - - if constexpr (std::is_same_v) { - if (!isAcceptedMftTrack(track1)) { - continue; - } - } else { - if (!trackSelected(track1)) - continue; - - if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ)) - continue; - } - - if (system == SameEvent) { - registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), triggerWeight); - } - - for (auto const& track2 : tracks2) { - - if constexpr (std::is_same_v) { - if (!isAcceptedMftTrack(track2)) { - continue; - } - } else { - if (!trackSelected(track2)) - continue; - - if (track1.pt() <= track2.pt()) - continue; // skip if the trigger pt is less than the associate pt - } - - float deltaPhi = RecoDecay::constrainAngle(track1.phi() - track2.phi(), -PIHalf); - float deltaEta = track1.eta() - track2.eta(); - - if (cfgApplyTwoTrackEfficiency && std::abs(deltaEta) < cfgMergingCut) { - - double dPhiStarHigh = getDPhiStar(track1, track2, cfgRadiusHigh, magneticField); - double dPhiStarLow = getDPhiStar(track1, track2, cfgRadiusLow, magneticField); - - const double kLimit = 3.0 * cfgMergingCut; - - bool bIsBelow = false; - - if (std::abs(dPhiStarLow) < kLimit || std::abs(dPhiStarHigh) < kLimit || dPhiStarLow * dPhiStarHigh < 0) { - for (double rad(cfgRadiusLow); rad < cfgRadiusHigh; rad += 0.01) { - double dPhiStar = getDPhiStar(track1, track2, rad, magneticField); - if (std::abs(dPhiStar) < kLimit) { - bIsBelow = true; - break; - } - } - if (bIsBelow) - continue; - } - } - - // fill the right sparse and histograms - if (system == SameEvent) { - if (cfgDetectorConfig.processMFT) { - same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta); - registry.fill(HIST("deltaEta_deltaPhi_same_TPC_MFT"), deltaPhi, deltaEta); - } else { - same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta); - registry.fill(HIST("deltaEta_deltaPhi_same_TPC_TPC"), deltaPhi, deltaEta); - } - } else if (system == MixedEvent) { - if (cfgDetectorConfig.processMFT) { - mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta); - registry.fill(HIST("deltaEta_deltaPhi_mixed_TPC_MFT"), deltaPhi, deltaEta); - } else { - mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta); - registry.fill(HIST("deltaEta_deltaPhi_mixed_TPC_TPC"), deltaPhi, deltaEta); - } - } - } - } - } - - template - void fillCorrelationsFT0s(TFT0s const& ft01, TFT0s const& ft02, float posZ, int multiplicity, int system, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms - { - int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); - - if (cfgQaCheck) { - if (system == SameEvent) { - registry.fill(HIST("zVtx_used"), posZ); - registry.fill(HIST("Nch"), multiplicity); - registry.fill(HIST("Nch_used_ft0c"), ft02.channelC().size()); - registry.fill(HIST("Nch_used_ft0a"), ft01.channelA().size()); - } - } - - float triggerWeight = 1.0f; - std::size_t channelASize = ft01.channelA().size(); - std::size_t channelCSize = ft02.channelC().size(); - // loop over all tracks - for (std::size_t iChA = 0; iChA < channelASize; iChA++) { - - int chanelAid = 0; - float amplA = 0.; - if (cfgDetectorConfig.withGain) { - getChannelWithGain(ft01, iChA, chanelAid, amplA, kFT0A); - } else { - getChannelFT0(ft01, iChA, chanelAid, amplA, kFT0A); - } - auto phiA = getPhiFT0(chanelAid, kFT0A); - auto etaA = getEtaFT0(chanelAid, kFT0A); - - if (system == SameEvent) { - registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, 0.5, eventWeight * amplA); - } - - for (std::size_t iChC = 0; iChC < channelCSize; iChC++) { - int chanelCid = 0; - float amplC = 0.; - if (cfgDetectorConfig.withGain) { - getChannelWithGain(ft02, iChC, chanelCid, amplC, kFT0C); - } else { - getChannelFT0(ft02, iChC, chanelCid, amplC, kFT0C); - } - auto phiC = getPhiFT0(chanelCid, kFT0C); - auto etaC = getEtaFT0(chanelCid, kFT0C); - float deltaPhi = RecoDecay::constrainAngle(phiA - phiC, -PIHalf); - float deltaEta = etaA - etaC; - - // fill the right sparse and histograms - if (system == SameEvent) { - registry.fill(HIST("deltaEta_deltaPhi_same_FT0A_FT0C"), deltaPhi, deltaEta, amplA * amplC * eventWeight * triggerWeight); - same->getPairHist()->Fill(step, fSampleIndex, posZ, 0.5, 0.5, deltaPhi, deltaEta, amplA * amplC * eventWeight * triggerWeight); - } else if (system == MixedEvent) { - registry.fill(HIST("deltaEta_deltaPhi_mixed_FT0A_FT0C"), deltaPhi, deltaEta, amplA * amplC * eventWeight * triggerWeight); - mixed->getPairHist()->Fill(step, fSampleIndex, posZ, 0.5, 0.5, deltaPhi, deltaEta, amplA * amplC * eventWeight * triggerWeight); - } - } - } - } - ////////////////////////////////////// - ////// Same event processing ///////// - ////////////////////////////////////// - - //////////////////////////////////// - /////////// Fwrd-Bwrd ///////////// - //////////////////////////////////// - - void processSameMFTFIT(AodCollisions::iterator const& collision, AodTracks const& tpctracks, aod::MFTTracks const& mfts, aod::FT0s const& ft0as, aod::FV0As const& fv0as, aod::BCsWithTimestamps const&) - { - - if (!collision.sel8()) - return; - - auto bc = collision.bc_as(); - - if (cfgUseAdditionalEventCut && !eventSelected(collision, tpctracks.size(), true)) - return; - - if (!collision.has_foundFT0()) - return; - loadAlignParam(bc.timestamp()); - if (cfgDetectorConfig.withGain) { - loadGain(bc); - } - - loadCorrection(bc.timestamp()); - - if ((tpctracks.size() < cfgEventSelection.cfgMinMult || tpctracks.size() >= cfgEventSelection.cfgMaxMult)) { - return; - } - if (mfts.size() == 0) { - return; - } - - registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin - fillYield(collision, mfts); - const auto& multiplicity = tpctracks.size(); - - if (cfgDetectorConfig.processFV0) { - if (collision.has_foundFV0()) { - same->fillEvent(mfts.size(), CorrelationContainer::kCFStepReconstructed); - const auto& fv0 = collision.foundFV0(); - fillCorrelationsFIT(mfts, fv0, fv0as, collision.posZ(), SameEvent, kFV0, multiplicity); - } - } - if (cfgDetectorConfig.processFT0C) { - if (collision.has_foundFT0()) { - same->fillEvent(mfts.size(), CorrelationContainer::kCFStepReconstructed); - const auto& ft0 = collision.foundFT0(); - fillCorrelationsFIT(mfts, ft0, ft0as, collision.posZ(), SameEvent, kFT0C, multiplicity); - } - } - if (cfgDetectorConfig.processFT0A) { - if (collision.has_foundFT0()) { - same->fillEvent(mfts.size(), CorrelationContainer::kCFStepReconstructed); - const auto& ft0 = collision.foundFT0(); - fillCorrelationsFIT(mfts, ft0, ft0as, collision.posZ(), SameEvent, kFT0A, multiplicity); - } - } - } - PROCESS_SWITCH(CorrSparse, processSameMFTFIT, "Process same event for MFT-FIT correlation", true); - - void processSameMftReassociated2DFIT(AodCollisions::iterator const& collision, AodTracks const& tpctracks, - soa::SmallGroups const& reassociatedMftTracks, - FilteredMftTracks const&, - aod::FT0s const& ft0as, aod::FV0As const& fv0as, aod::BCsWithTimestamps const&) - { - if (!collision.sel8()) - return; - - auto bc = collision.bc_as(); - - if (cfgUseAdditionalEventCut && !eventSelected(collision, tpctracks.size(), true)) - return; - - if (!collision.has_foundFT0()) - return; - loadAlignParam(bc.timestamp()); - loadGain(bc); - loadCorrection(bc.timestamp()); - - if ((tpctracks.size() < cfgEventSelection.cfgMinMult || tpctracks.size() >= cfgEventSelection.cfgMaxMult)) { - return; - } - if (reassociatedMftTracks.size() == 0) { - return; - } - - registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin - const auto& multiplicity = tpctracks.size(); - - if (cfgDetectorConfig.processFV0) { - if (collision.has_foundFV0()) { - same->fillEvent(reassociatedMftTracks.size(), CorrelationContainer::kCFStepReconstructed); - const auto& fv0 = collision.foundFV0(); - fillCorrelationsMftReassociatedFIT(reassociatedMftTracks, fv0, fv0as, collision.posZ(), SameEvent, kFV0, multiplicity, false); - } - } - if (cfgDetectorConfig.processFT0C) { - if (collision.has_foundFT0()) { - same->fillEvent(reassociatedMftTracks.size(), CorrelationContainer::kCFStepReconstructed); - const auto& ft0 = collision.foundFT0(); - fillCorrelationsMftReassociatedFIT(reassociatedMftTracks, ft0, ft0as, collision.posZ(), SameEvent, kFT0C, multiplicity, false); - } - } - if (cfgDetectorConfig.processFT0A) { - if (collision.has_foundFT0()) { - same->fillEvent(reassociatedMftTracks.size(), CorrelationContainer::kCFStepReconstructed); - const auto& ft0 = collision.foundFT0(); - fillCorrelationsMftReassociatedFIT(reassociatedMftTracks, ft0, ft0as, collision.posZ(), SameEvent, kFT0A, multiplicity, false); - } - } - } - PROCESS_SWITCH(CorrSparse, processSameMftReassociated2DFIT, "Process same event for MFT-FIT correlation with reassociated tracks", false); - - ///////////////////////// - ////////Mid-Mid////////// - //////////////////////// - - void processSameTPC(AodCollisions::iterator const& collision, AodTracks const& tracks, aod::BCsWithTimestamps const&) - { - - auto bc = collision.bc_as(); - - if (!collision.sel8()) - return; - - if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), true)) - return; - - loadCorrection(bc.timestamp()); - - fillYield(collision, tracks); - - if (tracks.size() < cfgEventSelection.cfgMinMult || tracks.size() >= cfgEventSelection.cfgMaxMult) { - return; - } - - registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin - - fillCorrelations(tracks, tracks, collision.posZ(), tracks.size(), SameEvent, getMagneticField(bc.timestamp())); - } - PROCESS_SWITCH(CorrSparse, processSameTPC, "Process same event for TPC-TPC correlation", false); - - ///////////////////// - ////////back-Mid-Fwrd////// - ///////////////////// - - void processSameTpcFIT(AodCollisions::iterator const& collision, AodTracks const& tracks, aod::FT0s const& ft0as, aod::FV0As const& fv0as, aod::BCsWithTimestamps const&) - { - if (!collision.sel8()) - return; - auto bc = collision.bc_as(); - if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), true)) - return; - if (!collision.has_foundFT0() && !collision.has_foundFV0()) - return; - - registry.fill(HIST("Nch"), tracks.size()); - registry.fill(HIST("zVtx"), collision.posZ()); - - if ((tracks.size() < cfgEventSelection.cfgMinMult || tracks.size() >= cfgEventSelection.cfgMaxMult)) { - return; - } - - loadAlignParam(bc.timestamp()); - if (cfgDetectorConfig.withGain) { - loadGain(bc); - } - - loadCorrection(bc.timestamp()); - - registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin - fillYield(collision, tracks); - - const auto& multiplicity = tracks.size(); - - if (cfgDetectorConfig.processFV0) { - same->fillEvent(tracks.size(), CorrelationContainer::kCFStepReconstructed); - const auto& fv0 = collision.foundFV0(); - fillCorrelationsFIT(tracks, fv0, fv0as, collision.posZ(), SameEvent, kFV0, multiplicity); - } - if (cfgDetectorConfig.processFT0C) { - same->fillEvent(tracks.size(), CorrelationContainer::kCFStepReconstructed); - const auto& ft0 = collision.foundFT0(); - fillCorrelationsFIT(tracks, ft0, ft0as, collision.posZ(), SameEvent, kFT0C, multiplicity); - } - if (cfgDetectorConfig.processFT0A) { - same->fillEvent(tracks.size(), CorrelationContainer::kCFStepReconstructed); - const auto& ft0 = collision.foundFT0(); - fillCorrelationsFIT(tracks, ft0, ft0as, collision.posZ(), SameEvent, kFT0A, multiplicity); - } - } - PROCESS_SWITCH(CorrSparse, processSameTpcFIT, "process for forward or backwards correlations with TPC", false); - - void processSameTpcMft(AodCollisions::iterator const& collision, AodTracks const& tracks, aod::MFTTracks const& mfts, aod::BCsWithTimestamps const&) - { - if (!collision.sel8()) - return; - - auto bc = collision.bc_as(); - - if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), true)) - return; - - loadCorrection(bc.timestamp()); - - registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin - - fillYield(collision, tracks); - - if (tracks.size() < cfgEventSelection.cfgMinMult || tracks.size() >= cfgEventSelection.cfgMaxMult) { - return; - } - - fillCorrelations(tracks, mfts, collision.posZ(), tracks.size(), SameEvent, getMagneticField(bc.timestamp())); - } - PROCESS_SWITCH(CorrSparse, processSameTpcMft, "Process same event for TPC-MFT correlation", false); - - void processSameTpcMftReassociated2D(AodCollisions::iterator const& collision, AodTracks const& tracks, - soa::SmallGroups const& reassociatedMftTracks, - FilteredMftTracks const&, - aod::BCsWithTimestamps const&) - { - if (!collision.sel8()) - return; - - auto bc = collision.bc_as(); - - if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), true)) - return; - - loadCorrection(bc.timestamp()); - - registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin - - fillYield(collision, tracks); - - if (tracks.size() < cfgEventSelection.cfgMinMult || tracks.size() >= cfgEventSelection.cfgMaxMult) { - return; - } - - fillCorrelationsMftReassociatedTracks(tracks, reassociatedMftTracks, tracks.size(), collision.posZ(), SameEvent, getMagneticField(bc.timestamp()), false); - } - PROCESS_SWITCH(CorrSparse, processSameTpcMftReassociated2D, "Process same event for TPC-MFT correlation with reassociated tracks", false); - - void processSameFT0s(AodCollisions::iterator const& collision, AodTracks const& tracks, aod::FT0s const&, aod::BCsWithTimestamps const&) - { - if (!collision.sel8()) - return; - - auto bc = collision.bc_as(); - - if (cfgUseAdditionalEventCut && !eventSelected(collision, 0, true)) - return; - - if (!collision.has_foundFT0()) - return; - - loadAlignParam(bc.timestamp()); - if (cfgDetectorConfig.withGain) { - loadGain(bc); - } - loadCorrection(bc.timestamp()); - - if ((tracks.size() < cfgEventSelection.cfgMinMult || tracks.size() >= cfgEventSelection.cfgMaxMult)) { - return; - } - - registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin - - const auto& ft0s = collision.foundFT0(); - auto multiplicity = tracks.size(); - - fillCorrelationsFT0s(ft0s, ft0s, collision.posZ(), multiplicity, SameEvent, 1.0f); - } - PROCESS_SWITCH(CorrSparse, processSameFT0s, "Process same event for FT0 correlation", false); - //////////////////////////////////// - ////// Mixed event processing ////// - //////////////////////////////////// - - ///////////////////////////////////////// - ////////////// Fwrd- Bwrd////////////// - //////////////////////////////////////// - - void processMixedMFTFIT(AodCollisions const& collisions, AodTracks const& tpctracks, aod::MFTTracks const& mfts, aod::FT0s const& ft0as, aod::FV0As const& fv0as, aod::BCsWithTimestamps const&) - { - - auto getTracksSize = [&tpctracks, this](AodCollisions::iterator const& collision) { - auto associatedTracks = tpctracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); - auto mult = associatedTracks.size(); - return mult; - }; - - using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; - - MixedBinning binningOnVtxAndMult{{getTracksSize}, {vtxMix, multMix}, true}; - - auto tracksTuple = std::make_tuple(mfts, mfts); - Pair pair{binningOnVtxAndMult, cfgMinMixEventNum, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip - - for (auto it = pair.begin(); it != pair.end(); it++) { - auto& [collision1, tracks1, collision2, tracks2] = *it; - - if (!collision1.sel8() || !collision2.sel8()) - continue; - - if (collision1.globalIndex() == collision2.globalIndex()) { - continue; - } - - auto slicedtracks = tpctracks.sliceBy(perColGlobal, collision1.globalIndex()); - auto multiplicity = slicedtracks.size(); - - if ((multiplicity < cfgEventSelection.cfgMinMult || multiplicity >= cfgEventSelection.cfgMaxMult)) - continue; - - if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), false)) - continue; - - if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), false)) - continue; - - auto bc = collision1.bc_as(); - loadAlignParam(bc.timestamp()); - - loadCorrection(bc.timestamp()); - - if (cfgDetectorConfig.processFT0A) { - if (!collision1.has_foundFT0() && !collision2.has_foundFT0()) - continue; - - const auto& ft0 = collision2.foundFT0(); - fillCorrelationsFIT(tracks1, ft0, ft0as, collision1.posZ(), MixedEvent, kFT0A, multiplicity); - } - if (cfgDetectorConfig.processFT0C) { - if (!collision1.has_foundFT0() && !collision2.has_foundFT0()) - continue; - - const auto& ft0 = collision2.foundFT0(); - fillCorrelationsFIT(tracks1, ft0, ft0as, collision1.posZ(), MixedEvent, kFT0C, multiplicity); - } - if (cfgDetectorConfig.processFV0) { - if (collision1.has_foundFV0() && collision2.has_foundFV0()) { - const auto& fv0 = collision2.foundFV0(); - fillCorrelationsFIT(tracks1, fv0, fv0as, collision1.posZ(), MixedEvent, kFV0, multiplicity); - } - } - } - } - PROCESS_SWITCH(CorrSparse, processMixedMFTFIT, "Process mixed events for MFT-FIT correlation", true); - - ///////////////////////////// - //////////Mid-Mid/////////// - //////////////////////////// - - void processMixedTpcTpc(AodCollisions const& collisions, AodTracks const& tracks, aod::BCsWithTimestamps const&) - { - - auto getTracksSize = [&tracks, this](AodCollisions::iterator const& collision) { - auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); - auto mult = associatedTracks.size(); - return mult; - }; - - using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; - - MixedBinning binningOnVtxAndMult{{getTracksSize}, {vtxMix, multMix}, true}; - - auto tracksTuple = std::make_tuple(tracks, tracks); - Pair pair{binningOnVtxAndMult, cfgMinMixEventNum, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip - for (auto const& [collision1, tracks1, collision2, tracks2] : pair) { - - if (!collision1.sel8() || !collision2.sel8()) - continue; - - if (collision1.globalIndex() == collision2.globalIndex()) { - continue; - } - - registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin - auto bc = collision1.bc_as(); - - loadCorrection(bc.timestamp()); - - if ((tracks1.size() < cfgEventSelection.cfgMinMult || tracks1.size() >= cfgEventSelection.cfgMaxMult)) - continue; - - if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), false)) - continue; - if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), false)) - continue; - - fillCorrelations(tracks1, tracks2, collision1.posZ(), tracks1.size(), MixedEvent, getMagneticField(bc.timestamp())); - } - } - PROCESS_SWITCH(CorrSparse, processMixedTpcTpc, "Process mixed events for TPC-TPC correlation", false); - - ////////////////////////////// - /////// back-Mid-Fwrd /////// - ///////////////////////////// - - void processMixedTpcFIT(AodCollisions const& collisions, AodTracks const& tracks, aod::FV0As const& fv0as, aod::FT0s const& ft0as, aod::BCsWithTimestamps const&) - { - auto getTracksSize = [&tracks, this](AodCollisions::iterator const& collision) { - auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); - auto mult = associatedTracks.size(); - return mult; - }; - - using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; - - MixedBinning binningOnVtxAndMult{{getTracksSize}, {vtxMix, multMix}, true}; - - auto tracksTuple = std::make_tuple(tracks, tracks); - Pair pair{binningOnVtxAndMult, cfgMinMixEventNum, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip - - for (auto it = pair.begin(); it != pair.end(); it++) { - auto& [collision1, tracks1, collision2, tracks2] = *it; - - if (!collision1.sel8() || !collision2.sel8()) - continue; - - if (collision1.globalIndex() == collision2.globalIndex()) { - continue; - } - - if ((tracks1.size() < cfgEventSelection.cfgMinMult || tracks1.size() >= cfgEventSelection.cfgMaxMult)) - continue; - - if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), false)) - continue; - if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), false)) - continue; - - if (!(collision1.has_foundFT0() && collision2.has_foundFT0())) - continue; - - registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin - auto bc = collision1.bc_as(); - loadAlignParam(bc.timestamp()); - loadCorrection(bc.timestamp()); - - auto multiplicity = tracks1.size(); - - if (cfgDetectorConfig.processFT0A) { - const auto& ft0 = collision2.foundFT0(); - fillCorrelationsFIT(tracks1, ft0, ft0as, collision1.posZ(), MixedEvent, kFT0A, multiplicity); - } - if (cfgDetectorConfig.processFT0C) { - const auto& ft0 = collision2.foundFT0(); - fillCorrelationsFIT(tracks1, ft0, ft0as, collision1.posZ(), MixedEvent, kFT0C, multiplicity); - } - if (cfgDetectorConfig.processFV0) { - const auto& fv0 = collision2.foundFV0(); - fillCorrelationsFIT(tracks1, fv0, fv0as, collision1.posZ(), MixedEvent, kFV0, multiplicity); - } - } - } - PROCESS_SWITCH(CorrSparse, processMixedTpcFIT, "Process mixed events for TPC-FIT correlation", false); - - void processMixedTpcMFT(AodCollisions const& collisions, AodTracks const& tracks, aod::MFTTracks const& MFTtracks, aod::BCsWithTimestamps const&) - { - - auto getTracksSize = [&tracks, this](AodCollisions::iterator const& collision) { - auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); - auto mult = associatedTracks.size(); - return mult; - }; - - using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; - - MixedBinning binningOnVtxAndMult{{getTracksSize}, {vtxMix, multMix}, true}; - - auto tracksTuple = std::make_tuple(tracks, MFTtracks); - Pair pair{binningOnVtxAndMult, cfgMinMixEventNum, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip - for (auto const& [collision1, tracks1, collision2, tracks2] : pair) { - - if (!collision1.sel8() || !collision2.sel8()) - continue; - - if (collision1.globalIndex() == collision2.globalIndex()) { - continue; - } - - registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin - auto bc = collision1.bc_as(); - - loadCorrection(bc.timestamp()); - - if ((tracks1.size() < cfgEventSelection.cfgMinMult || tracks1.size() >= cfgEventSelection.cfgMaxMult)) - continue; - - fillCorrelations(tracks1, tracks2, collision1.posZ(), tracks1.size(), MixedEvent, getMagneticField(bc.timestamp())); - } - } - PROCESS_SWITCH(CorrSparse, processMixedTpcMFT, "Process mixed events for TPC-MFT correlation", false); - - void processMixedFT0s(AodCollisions const& collisions, AodTracks const& tracks, aod::FT0s const&, aod::BCsWithTimestamps const&) - { - - auto getTracksSize = [&tracks, this](AodCollisions::iterator const& collision) { - auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); - auto mult = associatedTracks.size(); - return mult; - }; - - using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; - - MixedBinning binningOnVtxAndMult{{getTracksSize}, {vtxMix, multMix}, true}; - - auto tracksTuple = std::make_tuple(tracks, tracks); - Pair pair{binningOnVtxAndMult, cfgMinMixEventNum, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip - - for (auto it = pair.begin(); it != pair.end(); it++) { - auto& [collision1, tracks1, collision2, tracks2] = *it; - - if (!collision1.sel8() || !collision2.sel8()) - continue; - - if (collision1.globalIndex() == collision2.globalIndex()) { - continue; - } - - if ((tracks1.size() < cfgEventSelection.cfgMinMult || tracks1.size() >= cfgEventSelection.cfgMaxMult)) - continue; - - if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), false)) - continue; - if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), false)) - continue; - - if (!(collision1.has_foundFT0() && collision2.has_foundFT0())) - continue; - - registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin - auto bc = collision1.bc_as(); - loadAlignParam(bc.timestamp()); - loadCorrection(bc.timestamp()); - - auto multiplicity = tracks1.size(); - - const auto& ft0_1 = collision1.foundFT0(); - const auto& ft0_2 = collision2.foundFT0(); - fillCorrelationsFT0s(ft0_1, ft0_2, collision1.posZ(), multiplicity, MixedEvent, 1.0f); - } - } - PROCESS_SWITCH(CorrSparse, processMixedFT0s, "Process mixed events for FT0 correlation", false); -}; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc), - }; -} diff --git a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx index ffeeeb323c9..bd09a8f37c7 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -65,13 +66,15 @@ namespace lambdacollision { DECLARE_SOA_COLUMN(Cent, cent, float); DECLARE_SOA_COLUMN(Mult, mult, float); +DECLARE_SOA_COLUMN(BField, bField, float); } // namespace lambdacollision DECLARE_SOA_TABLE(LambdaCollisions, "AOD", "LAMBDACOLS", o2::soa::Index<>, lambdacollision::Cent, lambdacollision::Mult, aod::collision::PosX, aod::collision::PosY, - aod::collision::PosZ); + aod::collision::PosZ, + lambdacollision::BField); using LambdaCollision = LambdaCollisions::iterator; namespace lambdamcgencollision @@ -88,9 +91,6 @@ using LambdaMcGenCollision = LambdaMcGenCollisions::iterator; namespace lambdatrack { DECLARE_SOA_INDEX_COLUMN(LambdaCollision, lambdaCollision); -DECLARE_SOA_COLUMN(Px, px, float); -DECLARE_SOA_COLUMN(Py, py, float); -DECLARE_SOA_COLUMN(Pz, pz, float); DECLARE_SOA_COLUMN(Pt, pt, float); DECLARE_SOA_COLUMN(Eta, eta, float); DECLARE_SOA_COLUMN(Phi, phi, float); @@ -98,14 +98,13 @@ DECLARE_SOA_COLUMN(Rap, rap, float); DECLARE_SOA_COLUMN(Mass, mass, float); DECLARE_SOA_COLUMN(PosTrackId, posTrackId, int64_t); DECLARE_SOA_COLUMN(NegTrackId, negTrackId, int64_t); +DECLARE_SOA_COLUMN(PosTrackKin, posTrackKin, float[3]); +DECLARE_SOA_COLUMN(NegTrackKin, negTrackKin, float[3]); DECLARE_SOA_COLUMN(PartType, partType, int8_t); DECLARE_SOA_COLUMN(CorrFact, corrFact, float); } // namespace lambdatrack DECLARE_SOA_TABLE(LambdaTracks, "AOD", "LAMBDATRACKS", o2::soa::Index<>, lambdatrack::LambdaCollisionId, - lambdatrack::Px, - lambdatrack::Py, - lambdatrack::Pz, lambdatrack::Pt, lambdatrack::Eta, lambdatrack::Phi, @@ -113,6 +112,8 @@ DECLARE_SOA_TABLE(LambdaTracks, "AOD", "LAMBDATRACKS", o2::soa::Index<>, lambdatrack::Mass, lambdatrack::PosTrackId, lambdatrack::NegTrackId, + lambdatrack::PosTrackKin, + lambdatrack::NegTrackKin, lambdatrack::PartType, lambdatrack::CorrFact); using LambdaTrack = LambdaTracks::iterator; @@ -120,9 +121,6 @@ using LambdaTrack = LambdaTracks::iterator; namespace kaontrack { DECLARE_SOA_INDEX_COLUMN(LambdaCollision, lambdaCollision); -DECLARE_SOA_COLUMN(Px, px, float); -DECLARE_SOA_COLUMN(Py, py, float); -DECLARE_SOA_COLUMN(Pz, pz, float); DECLARE_SOA_COLUMN(Pt, pt, float); DECLARE_SOA_COLUMN(Eta, eta, float); DECLARE_SOA_COLUMN(Phi, phi, float); @@ -134,9 +132,6 @@ DECLARE_SOA_COLUMN(CorrFact, corrFact, float); } // namespace kaontrack DECLARE_SOA_TABLE(KaonTracks, "AOD", "KAONTRACKS", o2::soa::Index<>, kaontrack::LambdaCollisionId, - kaontrack::Px, - kaontrack::Py, - kaontrack::Pz, kaontrack::Pt, kaontrack::Eta, kaontrack::Phi, @@ -160,15 +155,24 @@ DECLARE_SOA_TABLE(LambdaTracksExt, "AOD", "LAMBDATRACKSEXT", using LambdaTrackExt = LambdaTracksExt::iterator; +namespace kaontrackext +{ +DECLARE_SOA_COLUMN(KaonSharingLambdaDau, kaonSharingLambdaDau, bool); +DECLARE_SOA_COLUMN(KaonSharingLambdaDauIds, kaonSharingLambdaDauIds, std::vector); +DECLARE_SOA_COLUMN(TrueKaonFlag, trueKaonFlag, bool); +} // namespace kaontrackext +DECLARE_SOA_TABLE(KaonTracksExt, "AOD", "KAONTRACKSEXT", + kaontrackext::KaonSharingLambdaDau, + kaontrackext::KaonSharingLambdaDauIds, + kaontrackext::TrueKaonFlag); +using KaonTrackExt = KaonTracksExt::iterator; + namespace lambdamcgentrack { DECLARE_SOA_INDEX_COLUMN(LambdaMcGenCollision, lambdaMcGenCollision); } DECLARE_SOA_TABLE(LambdaMcGenTracks, "AOD", "LMCGENTRACKS", o2::soa::Index<>, lambdamcgentrack::LambdaMcGenCollisionId, - o2::aod::mcparticle::Px, - o2::aod::mcparticle::Py, - o2::aod::mcparticle::Pz, lambdatrack::Pt, lambdatrack::Eta, lambdatrack::Phi, @@ -186,9 +190,6 @@ DECLARE_SOA_INDEX_COLUMN(LambdaMcGenCollision, lambdaMcGenCollision); } DECLARE_SOA_TABLE(KaonMcGenTracks, "AOD", "KMCGENTRACKS", o2::soa::Index<>, kaonmcgentrack::LambdaMcGenCollisionId, - o2::aod::mcparticle::Px, - o2::aod::mcparticle::Py, - o2::aod::mcparticle::Pz, kaontrack::Pt, kaontrack::Eta, kaontrack::Phi, @@ -290,7 +291,7 @@ struct LambdaTableProducer { Produces kaonMCGenTrackTable; // Centrality Axis - ConfigurableAxis cCentBins{"cCentBins", {VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 50.f, 80.0f, 100.f}, "Variable Centrality Bins"}; + ConfigurableAxis cCentBins{"cCentBins", {VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f}, "Variable Centrality Bins"}; // Collisions Configurable cCentEstimator{"cCentEstimator", 1, "Centrality Estimator : 0-FT0M, 1-FT0C"}; @@ -360,6 +361,7 @@ struct LambdaTableProducer { // Initialize CCDB Service Service ccdb; + o2::parameters::GRPMagField* grpo = nullptr; // Histogram Registry. HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -517,6 +519,20 @@ struct LambdaTableProducer { histos.get(HIST("Tracks/h1f_kaon_sel"))->GetXaxis()->SetBinLabel(KaonLabels::kKaonPassAllSel, "kKaonPassAllSel"); } + // Get magnetic field + float getMagneticField(int64_t const& timestamp) + { + if (grpo == nullptr) { + grpo = ccdb->getForTimeStamp("GLO/Config/GRPMagField", timestamp); + if (grpo == nullptr) { + LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); + return 1; + } + } + auto field = std::lround(5.f * grpo->getL3Current() / 30000.f); + return 0.1 * field; + } + template bool selCollision(C const& col) { @@ -918,7 +934,8 @@ struct LambdaTableProducer { histos.fill(HIST("Events/h2f_pvmult_vs_cent"), cent, collision.multNTracksPV()); // Fill Collision Table - lambdaCollisionTable(cent, mult, collision.posX(), collision.posY(), collision.posZ()); + float magField = getMagneticField(collision.template foundBC_as().timestamp()); + lambdaCollisionTable(cent, mult, collision.posX(), collision.posY(), collision.posZ(), magField); // initialize v0track objects ParticleType partType = kLambda; @@ -963,15 +980,18 @@ struct LambdaTableProducer { fillLambdaQAHistos(collision, v0, tracks); } + // Daughter kinematics + std::array posTrackKin = {postrack.pt(), postrack.eta(), postrack.phi()}; + std::array negTrackKin = {negtrack.pt(), negtrack.eta(), negtrack.phi()}; + // Fill Lambda/AntiLambda Table - lambdaTrackTable(lambdaCollisionTable.lastIndex(), v0.px(), v0.py(), v0.pz(), - v0.pt(), v0.eta(), v0.phi(), v0.yLambda(), lambdaMass, - v0.template posTrack_as().index(), v0.template negTrack_as().index(), + lambdaTrackTable(lambdaCollisionTable.lastIndex(), v0.pt(), v0.eta(), v0.phi(), v0.yLambda(), lambdaMass, + v0.template posTrack_as().index(), v0.template negTrack_as().index(), posTrackKin.data(), negTrackKin.data(), (int8_t)partType, lambdaCorrFact); } // Loop over tracks to select Kaon - float kaonCorrFact = 0.; + float kaonCorrFact = 1.; for (auto const& track : tracks) { // Check corresponding MC particle if constexpr (dmc == kMC) { @@ -1007,8 +1027,7 @@ struct LambdaTableProducer { } // Fill table - kaonTrackTable(lambdaCollisionTable.lastIndex(), track.px(), track.py(), track.pz(), - track.pt(), track.eta(), track.phi(), rap, MassKaonCharged, + kaonTrackTable(lambdaCollisionTable.lastIndex(), track.pt(), track.eta(), track.phi(), rap, MassKaonCharged, track.globalIndex(), (int8_t)partType, kaonCorrFact); } } @@ -1069,8 +1088,7 @@ struct LambdaTableProducer { histos.fill(HIST("McGen/h1f_antilambda_daughter_PDG"), mcpart.pdgCode()); } // Fill table - lambdaMCGenTrackTable(lambdaMCGenCollisionTable.lastIndex(), mcpart.px(), mcpart.py(), mcpart.pz(), - mcpart.pt(), mcpart.eta(), mcpart.phi(), mcpart.y(), RecoDecay::m(mcpart.p(), mcpart.e()), + lambdaMCGenTrackTable(lambdaMCGenCollisionTable.lastIndex(), mcpart.pt(), mcpart.eta(), mcpart.phi(), mcpart.y(), RecoDecay::m(mcpart.p(), mcpart.e()), daughterIDs[0], daughterIDs[1], (int8_t)partType, 1.); } @@ -1084,8 +1102,7 @@ struct LambdaTableProducer { // histos.fill(HIST("KaonTracks/h1f_tracks_info"), kGenAccKaon); // Fill table - kaonMCGenTrackTable(lambdaMCGenCollisionTable.lastIndex(), mcpart.px(), mcpart.py(), mcpart.pz(), - mcpart.pt(), mcpart.eta(), mcpart.phi(), mcpart.y(), RecoDecay::m(mcpart.p(), mcpart.e()), + kaonMCGenTrackTable(lambdaMCGenCollisionTable.lastIndex(), mcpart.pt(), mcpart.eta(), mcpart.phi(), mcpart.y(), RecoDecay::m(mcpart.p(), mcpart.e()), mcpart.globalIndex(), (int8_t)partType, 1.); } } @@ -1186,23 +1203,32 @@ struct LambdaTableProducer { }; struct LambdaTracksExtProducer { - + // Tables Produces lambdaTrackExtTable; + Produces kaonTrackExtTable; // Configurables Configurable cAcceptAllLambda{"cAcceptAllLambda", false, "Accept all Lambda"}; Configurable cRejAllLambdaShaDau{"cRejAllLambdaShaDau", true, "Reject all Lambda sharing daughters"}; + Configurable cAcceptAllKaon{"cAcceptAllKaon", false, "Accept all Kaons"}; + Configurable cRejAllKaonShaLaDau{"cRejAllKaonShaLaDau", true, "Reject all Kaons sharing Lambda daughters"}; + + // Two-track cuts + Configurable cApplyTwoTrackCut{"cApplyTwoTrackCut", false, "Flag for two track cut"}; + Configurable cTpcRadii{"cTpcRadii", 0.80, "TPC Radius for DPhiStar"}; + Configurable cDEtaCut{"cDEtaCut", 0.01, "DEta cut"}; + Configurable cDPhiStarCut{"cDPhiStarCut", 0.01, "DPhiStar cut"}; // Histogram Registry. HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + // Global objects + float magField = 0.; + void init(InitContext const&) { // Axis Specifications const AxisSpec axisMult(10, 0, 10); - const AxisSpec axisMass(100, 1.06, 1.16, "Inv Mass (GeV/#it{c}^{2})"); - const AxisSpec axisCPA(100, 0.995, 1.0, "cos(#theta_{PA})"); - const AxisSpec axisDcaDau(75, 0., 1.5, "Daug DCA (#sigma)"); const AxisSpec axisDEta(320, -1.6, 1.6, "#Delta#eta"); const AxisSpec axisDPhi(640, -PIHalf, 3. * PIHalf, "#Delta#varphi"); @@ -1211,26 +1237,22 @@ struct LambdaTracksExtProducer { histos.add("h1i_totantilambda_mult", "Multiplicity", kTH1I, {axisMult}); histos.add("h1i_lambda_mult", "Multiplicity", kTH1I, {axisMult}); histos.add("h1i_antilambda_mult", "Multiplicity", kTH1I, {axisMult}); + + histos.add("h1i_totkaplus_mult", "Multiplicity", kTH1I, {axisMult}); + histos.add("h1i_totkaminus_mult", "Multiplicity", kTH1I, {axisMult}); + histos.add("h1i_kaplus_mult", "Multiplicity", kTH1I, {axisMult}); + histos.add("h1i_kaminus_mult", "Multiplicity", kTH1I, {axisMult}); + histos.add("h2d_n2_etaphi_LaP_LaM", "#rho_{2}^{SharePair}", kTH2D, {axisDEta, axisDPhi}); histos.add("h2d_n2_etaphi_LaP_LaP", "#rho_{2}^{SharePair}", kTH2D, {axisDEta, axisDPhi}); histos.add("h2d_n2_etaphi_LaM_LaM", "#rho_{2}^{SharePair}", kTH2D, {axisDEta, axisDPhi}); - // InvMass, DcaDau and CosPA - histos.add("Reco/h1f_lambda_invmass", "M_{p#pi}", kTH1F, {axisMass}); - histos.add("Reco/h1f_antilambda_invmass", "M_{p#pi}", kTH1F, {axisMass}); - histos.addClone("Reco/", "SharingDau/"); - } - - template - void fillHistos(T const& track) - { - static constexpr std::string_view SubDir[] = {"Reco/", "SharingDau/"}; + histos.add("h2d_n2_etaphi_KaPLaP", "#rho_{2}", kTH2D, {axisDEta, axisDPhi}); + histos.add("h2d_n2_etaphi_KaPLaM", "#rho_{2}", kTH2D, {axisDEta, axisDPhi}); + histos.add("h2d_n2_etaphi_KaMLaP", "#rho_{2}", kTH2D, {axisDEta, axisDPhi}); + histos.add("h2d_n2_etaphi_KaMLaM", "#rho_{2}", kTH2D, {axisDEta, axisDPhi}); - if (track.partType() == kLambda) { - histos.fill(HIST(SubDir[sd]) + HIST("h1f_lambda_invmass"), track.mass()); - } else { - histos.fill(HIST(SubDir[sd]) + HIST("h1f_antilambda_invmass"), track.mass()); - } + histos.add("h2d_n2_detadphi", "#rho_{2}", kTH2D, {axisDEta, axisDPhi}); } void processDummy(aod::LambdaCollisions::iterator const&) {} @@ -1273,13 +1295,7 @@ struct LambdaTracksExtProducer { } } - // fill QA histograms - if (lambdaSharingDauFlag) { - fillHistos(lambda); - } else { - fillHistos(lambda); - } - + // Accept/Reject if (cAcceptAllLambda) { // Accept all lambda trueLambdaFlag = true; } else if (cRejAllLambdaShaDau && !lambdaSharingDauFlag) { // Reject all lambda sharing daughter @@ -1295,7 +1311,7 @@ struct LambdaTracksExtProducer { } } - // fill LambdaTrackExt table + // Fill LambdaTrackExt table lambdaTrackExtTable(lambdaSharingDauFlag, vSharedDauLambdaIndex, trueLambdaFlag); } @@ -1318,6 +1334,136 @@ struct LambdaTracksExtProducer { } PROCESS_SWITCH(LambdaTracksExtProducer, processLambdaTrackExt, "Process for lambda track extension", false); + + template + bool checkClosePair(A const& v1, A const& v2, const int& charge1, const int& charge2) + { + // DPhiStar + float dphistar = 0.; + float arg1 = 0.15 * magField * charge1 * cTpcRadii / v1[0]; + float arg2 = 0.15 * magField * charge2 * cTpcRadii / v2[0]; + if (std::abs(arg1) < 1.0 && std::abs(arg2) < 1.0) { + dphistar = v1[2] - v2[2] + std::asin(arg1) - std::asin(arg2); + } else { + dphistar = 99.; + } + + // DEta + float deta = v1[1] - v2[1]; + + // Check close-pair + if (std::abs(deta) < cDEtaCut && std::abs(dphistar) < cDPhiStarCut) { + return true; + } + + return false; + } + + template + bool isClosePair(T const& track, V const& lambda) + { + // Close pair flag + bool retFlag = false; + + // Assign kinematics + std::array trackKin = {track.pt(), track.eta(), track.phi()}; + std::array lambdaPosTrackKin = {lambda.posTrackKin()[0], lambda.posTrackKin()[1], lambda.posTrackKin()[2]}; + std::array lambdaNegTrackKin = {lambda.negTrackKin()[0], lambda.negTrackKin()[1], lambda.negTrackKin()[2]}; + + if (track.partType() == kKaonPlus) { + retFlag = checkClosePair(trackKin, lambdaPosTrackKin, 1, 1) || checkClosePair(trackKin, lambdaNegTrackKin, 1, -1); + } else if (track.partType() == kKaonMinus) { + retFlag = checkClosePair(trackKin, lambdaPosTrackKin, -1, 1) || checkClosePair(trackKin, lambdaNegTrackKin, -1, -1); + } else { + return false; + } + + // Fill QA + if (retFlag) { + histos.fill(HIST("h2d_n2_detadphi"), track.eta() - lambda.eta(), RecoDecay::constrainAngle(track.phi() - lambda.phi(), -PIHalf)); + } + + return retFlag; + } + + void processKaonTrackExt(aod::LambdaCollisions::iterator const& collision, aod::LambdaTracks const& lambdaTracks, aod::KaonTracks const& kaonTracks) + { + magField = collision.bField(); + int nTotKaonPlus = 0, nTotKaonMinus = 0, nSelKaonPlus = 0, nSelKaonMinus = 0; + + for (auto const& kaonTrack : kaonTracks) { + bool kaonSharingLambdaDauFlag = false, closeTrackPairFlag = false, trueKaonFlag = false; + std::vector vKaonShareDauLambdaIndex; + + if (kaonTrack.partType() == kKaonPlus) { + ++nTotKaonPlus; + } else if (kaonTrack.partType() == kKaonMinus) { + ++nTotKaonMinus; + } + + for (auto const& lambdaTrack : lambdaTracks) { + // Removal based on shared track index + if (kaonTrack.kaonTrackId() == lambdaTrack.posTrackId() || kaonTrack.kaonTrackId() == lambdaTrack.negTrackId()) { + vKaonShareDauLambdaIndex.push_back(kaonTrack.kaonTrackId()); + kaonSharingLambdaDauFlag = true; + + // Fill Deta-Dphi Histogram + if (kaonTrack.partType() == kKaonPlus && lambdaTrack.partType() == kLambda) { + histos.fill(HIST("h2d_n2_etaphi_KaPLaP"), kaonTrack.eta() - lambdaTrack.eta(), RecoDecay::constrainAngle(kaonTrack.phi() - lambdaTrack.phi(), -PIHalf)); + } else if (kaonTrack.partType() == kKaonPlus && lambdaTrack.partType() == kAntiLambda) { + histos.fill(HIST("h2d_n2_etaphi_KaPLaM"), kaonTrack.eta() - lambdaTrack.eta(), RecoDecay::constrainAngle(kaonTrack.phi() - lambdaTrack.phi(), -PIHalf)); + } else if (kaonTrack.partType() == kKaonMinus && lambdaTrack.partType() == kLambda) { + histos.fill(HIST("h2d_n2_etaphi_KaMLaP"), kaonTrack.eta() - lambdaTrack.eta(), RecoDecay::constrainAngle(kaonTrack.phi() - lambdaTrack.phi(), -PIHalf)); + } else if (kaonTrack.partType() == kKaonMinus && lambdaTrack.partType() == kAntiLambda) { + histos.fill(HIST("h2d_n2_etaphi_KaMLaM"), kaonTrack.eta() - lambdaTrack.eta(), RecoDecay::constrainAngle(kaonTrack.phi() - lambdaTrack.phi(), -PIHalf)); + } + } + + // Two-track cuts + if (cApplyTwoTrackCut) { + closeTrackPairFlag |= isClosePair(kaonTrack, lambdaTrack); + } + } + + // Accept / Reject + if (cAcceptAllKaon) { + trueKaonFlag = true; + } else if (cRejAllKaonShaLaDau && !kaonSharingLambdaDauFlag && !closeTrackPairFlag) { + trueKaonFlag = true; + } + + // Multiplicity of selected kaons + if (trueKaonFlag) { + if (kaonTrack.partType() == kKaonPlus) { + ++nSelKaonPlus; + } else if (kaonTrack.partType() == kKaonMinus) { + ++nSelKaonMinus; + } + } + + // Fill LambdaTrackExt table + kaonTrackExtTable(kaonSharingLambdaDauFlag, vKaonShareDauLambdaIndex, trueKaonFlag); + } + + // Fill multiplicity histograms + if (nTotKaonPlus != 0) { + histos.fill(HIST("h1i_totkaplus_mult"), nTotKaonPlus); + } + + if (nTotKaonMinus != 0) { + histos.fill(HIST("h1i_totkaminus_mult"), nTotKaonMinus); + } + + if (nSelKaonPlus != 0) { + histos.fill(HIST("h1i_kaplus_mult"), nSelKaonPlus); + } + + if (nSelKaonMinus != 0) { + histos.fill(HIST("h1i_kaminus_mult"), nSelKaonMinus); + } + } + + PROCESS_SWITCH(LambdaTracksExtProducer, processKaonTrackExt, "Process for kaon track extension", false); }; struct LambdaR2Correlation { @@ -1326,8 +1472,8 @@ struct LambdaR2Correlation { Configurable cLambdaPtMin{"cLambdaPtMin", 0.7, "Lambda pT Min"}; Configurable cLambdaPtMax{"cLambdaPtMax", 3.4, "Lambda pT Max"}; Configurable cKaonNPtBins{"cKaonNPtBins", 20, "N pT Bins"}; - Configurable cKaonPtMin{"cKaonPtMin", 0.4, "Kaon pT Min"}; - Configurable cKaonPtMax{"cKaonPtMax", 2.4, "Kaon pT Max"}; + Configurable cKaonPtMin{"cKaonPtMin", 0.3, "Kaon pT Min"}; + Configurable cKaonPtMax{"cKaonPtMax", 2.2, "Kaon pT Max"}; Configurable cNRapBins{"cNRapBins", 10, "N Rapidity Bins"}; Configurable cMinRap{"cMinRap", -0.5, "Minimum Rapidity"}; @@ -1335,8 +1481,12 @@ struct LambdaR2Correlation { Configurable cNPhiBins{"cNPhiBins", 36, "N Phi Bins"}; Configurable cAnaPairs{"cAnaPairs", false, "Analyze Pairs Flag"}; + // Lambda Kaon femtoscopic correction + Configurable cApplyFemtoPtSel{"cApplyFemtoPtSel", false, "Femto pT selection"}; + Configurable cFemtoPtCut{"cFemtoPtCut", 0.02, "Kaon--Lambda Femto pT cut"}; + // Centrality Axis - ConfigurableAxis cCentBins{"cCentBins", {VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 50.f, 80.0f, 100.f}, "Variable Mult-Bins"}; + ConfigurableAxis cCentBins{"cCentBins", {VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f}, "Variable Mult-Bins"}; // Histogram Registry. HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -1386,8 +1536,6 @@ struct LambdaR2Correlation { histos.add("Event/Reco/h1f_collision_posz", "V_{Z} Distribution", kTH1F, {axisPosZ}); histos.add("Event/Reco/h1f_ft0m_mult_percentile", "FT0M (%)", kTH1F, {axisCent}); histos.add("Event/Reco/h2f_Mult_vs_Centrality", "N_{ch} vs FT0M(%)", kTProfile, {axisCent}); - histos.add("Event/Reco/h2f_lambda_mult", "#Lambda - Multiplicity", kTProfile, {axisCent}); - histos.add("Event/Reco/h2f_antilambda_mult", "#bar{#Lambda} - Multiplicity", kTProfile, {axisCent}); // Efficiency Histograms // Single Particle Efficiencies @@ -1402,12 +1550,12 @@ struct LambdaR2Correlation { // Single and Two Particle Densities // 1D Histograms - histos.add("Reco/h3f_n1_centmasspt_LaP", "#rho_{1}^{#Lambda}", kTH3F, {axisCent, axisMass, axisPtLambda}); - histos.add("Reco/h3f_n1_centmasspt_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH3F, {axisCent, axisMass, axisPtLambda}); - histos.add("Reco/h4f_n1_ptrapphi_LaP", "#rho_{1}^{#Lambda}", kTHnSparseF, {axisCent, axisPtLambda, axisRap, axisPhi}); - histos.add("Reco/h4f_n1_ptrapphi_LaM", "#rho_{1}^{#bar{#Lambda}}", kTHnSparseF, {axisCent, axisPtLambda, axisRap, axisPhi}); - histos.add("Reco/h4f_n1_ptrapphi_KaP", "#rho_{1}^{K^{#plus}}", kTHnSparseF, {axisCent, axisPtKaon, axisRap, axisPhi}); - histos.add("Reco/h4f_n1_ptrapphi_KaM", "#rho_{1}^{K^{#minus}}", kTHnSparseF, {axisCent, axisPtKaon, axisRap, axisPhi}); + histos.add("Reco/h3f_n1_centptmass_LaP", "#rho_{1}^{#Lambda}", kTH3F, {axisCent, axisPtLambda, axisMass}); + histos.add("Reco/h3f_n1_centptmass_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH3F, {axisCent, axisPtLambda, axisMass}); + histos.add("Reco/h3f_n1_centptrap_LaP", "#rho_{1}^{#Lambda}", kTH3F, {axisCent, axisPtLambda, axisRap}); + histos.add("Reco/h3f_n1_centptrap_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH3F, {axisCent, axisPtLambda, axisRap}); + histos.add("Reco/h3f_n1_centptrap_KaP", "#rho_{1}^{K^{#plus}}", kTH3F, {axisCent, axisPtKaon, axisRap}); + histos.add("Reco/h3f_n1_centptrap_KaM", "#rho_{1}^{K^{#minus}}", kTH3F, {axisCent, axisPtKaon, axisRap}); // rho1 for R2 RapPhi histos.add("Reco/h3f_n1_rapphi_LaP", "#rho_{1}^{#Lambda}", kTH3F, {axisCent, axisRap, axisPhi}); @@ -1465,6 +1613,14 @@ struct LambdaR2Correlation { float corfac = p1.corrFact() * p2.corrFact(); + // Lambda-Kaon Femto pT cut + if (cApplyFemtoPtSel && (part_pair == kLambdaKaonPlus || part_pair == kLambdaKaonMinus || part_pair == kAntiLambdaKaonPlus || part_pair == kAntiLambdaKaonMinus)) { + float dpt = p1.pt() - p2.pt(); + if (std::abs(dpt) < cFemtoPtCut) { + return; + } + } + if (rapbin1 >= 0 && rapbin2 >= 0 && phibin1 >= 0 && phibin2 >= 0 && rapbin1 < nrapbins && rapbin2 < nrapbins && phibin1 < nphibins && phibin2 < nphibins) { int rapphix = rapbin1 * nphibins + phibin1; @@ -1480,34 +1636,20 @@ struct LambdaR2Correlation { static constexpr std::string_view SubDirRecGen[] = {"Reco/", "McGen/"}; static constexpr std::string_view SubDirHist[] = {"LaP", "LaM", "KaP", "KaM"}; - int ntrk = 0; - for (auto const& track : tracks) { - // count tracks - ++ntrk; - // Efficiency Plots histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("Efficiency/h2f_n1_centpt_") + HIST(SubDirHist[part]), cent, track.pt()); histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("Efficiency/h3f_n1_centptrap_") + HIST(SubDirHist[part]), cent, track.pt(), track.rap()); // QA Plots if (part == kLambda || part == kAntiLambda) { - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("h3f_n1_centmasspt_") + HIST(SubDirHist[part]), cent, track.mass(), track.pt()); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("h3f_n1_centptmass_") + HIST(SubDirHist[part]), cent, track.pt(), track.mass()); } - histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("h4f_n1_ptrapphi_") + HIST(SubDirHist[part]), cent, track.pt(), track.rap(), track.phi(), track.corrFact()); + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("h3f_n1_centptrap_") + HIST(SubDirHist[part]), cent, track.pt(), track.rap(), track.corrFact()); // Rho1 for N1RapPhi histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST("h3f_n1_rapphi_") + HIST(SubDirHist[part]), cent, track.rap(), track.phi(), track.corrFact()); } - - // fill multiplicity histograms - if (ntrk != 0) { - if (part == kLambda) { - histos.fill(HIST("Event/") + HIST(SubDirRecGen[rec_gen]) + HIST("h2f_lambda_mult"), cent, ntrk); - } else if (part == kAntiLambda) { - histos.fill(HIST("Event/") + HIST(SubDirRecGen[rec_gen]) + HIST("h2f_antilambda_mult"), cent, ntrk); - } - } } template @@ -1526,13 +1668,13 @@ struct LambdaR2Correlation { using LambdaCollisions = aod::LambdaCollisions; using LambdaTracks = soa::Join; - using KaonTracks = aod::KaonTracks; + using KaonTracks = soa::Join; SliceCache cache; Partition partLambdaTracks = (aod::lambdatrack::partType == (int8_t)kLambda) && (aod::lambdatrackext::trueLambdaFlag == true); Partition partAntiLambdaTracks = (aod::lambdatrack::partType == (int8_t)kAntiLambda) && (aod::lambdatrackext::trueLambdaFlag == true); - Partition partKaonPlusTracks = (aod::kaontrack::partType == (int8_t)kKaonPlus); - Partition partKaonMinusTracks = (aod::kaontrack::partType == (int8_t)kKaonMinus); + Partition partKaonPlusTracks = (aod::kaontrack::partType == (int8_t)kKaonPlus) && (aod::kaontrackext::trueKaonFlag == true); + Partition partKaonMinusTracks = (aod::kaontrack::partType == (int8_t)kKaonMinus) && (aod::kaontrackext::trueKaonFlag == true); void processDummy(aod::LambdaCollisions::iterator const&) {} diff --git a/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx b/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx index 36e1e416722..c49559df02c 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx @@ -19,8 +19,15 @@ #include "PWGCF/TwoParticleCorrelations/DataModel/LongRangeDerived.h" #include "PWGUD/Core/SGSelector.h" +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/McCollisionExtra.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include #include #include #include @@ -31,11 +38,14 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -51,11 +61,16 @@ using namespace o2::aod::fwdtrack; using namespace o2::aod::evsel; using namespace o2::constants::math; +auto static constexpr KminCharge = 3.0f; + struct LongrangecorrDerived { SliceCache cache; SGSelector sgSelector; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + TrackSelection myTrackFilter; + Service pdg; + Service ccdb; struct : ConfigurableGroup { Configurable cfgNmixedevent{"cfgNmixedevent", 5, "how many events are mixed"}; @@ -65,11 +80,19 @@ struct LongrangecorrDerived { Configurable cfgVtxCut{"cfgVtxCut", 10.0f, "Vertex Z range to consider"}; Configurable isUseCentEst{"isUseCentEst", false, "Centrality based classification"}; Configurable isUseDataLikeMult{"isUseDataLikeMult", 0, "Data like mult/cent classification"}; + Configurable cfgVerbosity{"cfgVerbosity", 0, "print statement"}; + Configurable cfgEtaCut{"cfgEtaCut", 0.8f, "Eta range to consider"}; + Configurable cfgPtCutMin{"cfgPtCutMin", 0.2f, "minimum accepted track pT"}; + Configurable cfgPtCutMax{"cfgPtCutMax", 10.0f, "maximum accepted track pT"}; Configurable cfgTpcMinNclsFound{"cfgTpcMinNclsFound", 50.0f, ""}; Configurable cfgTpcMinNCrossedRows{"cfgTpcMinNCrossedRows", 70.0f, ""}; Configurable cfgTpcMaxChi2PerCluster{"cfgTpcMaxChi2PerCluster", 4.0f, ""}; Configurable cfgTpcMaxDcaZ{"cfgTpcMaxDcaZ", 1.0f, ""}; + Configurable applyEffCorr{"applyEffCorr", true, "Enable efficiency correction"}; + Configurable applyAccCorr{"applyAccCorr", false, "Enable NUA correction"}; + Configurable cfgEffccdbPath{"cfgEffccdbPath", "Users/a/abmodak/Efficiency/OO/default", "Browse track eff object from CCDB"}; + Configurable cfgAccccdbPath{"cfgAccccdbPath", "Users/a/abmodak/Acceptance/OO/default", "Browse track eff object from CCDB"}; Configurable cfgMftCluster{"cfgMftCluster", 5, "cut on MFT Cluster"}; Configurable cfgMftDcaxy{"cfgMftDcaxy", 2.0f, "cut on DCA xy for MFT tracks"}; @@ -78,9 +101,14 @@ struct LongrangecorrDerived { Configurable cfgRejectNonAmbTrk{"cfgRejectNonAmbTrk", false, "Condition to reject Non-Ambiguous tracks"}; Configurable cfgRequireCA{"cfgRequireCA", false, "Use Cellular Automaton track-finding algorithm"}; Configurable cfgRequireLTF{"cfgRequireLTF", false, "Use LTF track-finding algorithm"}; + Configurable cfgRequireFt0aOuterRing{"cfgRequireFt0aOuterRing", false, "Consider FT0A Outer Ring"}; + Configurable cfgRequireFt0aInnerRing{"cfgRequireFt0aInnerRing", false, "Consider FT0A Inner Ring"}; + Configurable cfgRequireFt0cOuterRing{"cfgRequireFt0cOuterRing", false, "Consider FT0C Outer Ring"}; + Configurable cfgRequireFt0cInnerRing{"cfgRequireFt0cInnerRing", false, "Consider FT0C Inner Ring"}; } cfgSel; struct : ConfigurableGroup { + ConfigurableAxis axisMultQA{"axisMultQA", {500, -0.5, 499.5}, "multiplicity QA axis"}; ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 10, 15, 25, 50, 60, 1000}, "multiplicity axis"}; ConfigurableAxis axisPhi{"axisPhi", {96, 0, TwoPI}, "#phi axis"}; ConfigurableAxis axisEtaTrig{"axisEtaTrig", {40, -1., 1.}, "#eta trig axis"}; @@ -121,6 +149,11 @@ struct LongrangecorrDerived { OutputObj same{"sameEvent"}; OutputObj mixed{"mixedEvent"}; + // corrections + TH3D* hTrkEff = nullptr; + TH3D* hTrkAcc = nullptr; + bool fLoadTrkEffCorr = false; + using CollsTable = aod::LRCollisions; using TrksTable = aod::LRMidTracks; using MftTrksTable = aod::LRMftTracks; @@ -171,46 +204,121 @@ struct LongrangecorrDerived { {cfgAxis.axisEtaEfficiency, "#eta"}}; std::vector userAxis = {{cfgAxis.axisInvMass, "m (GeV/c^2)"}}; - same.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, userAxis)); - - histos.add("hMultiplicity", "hMultiplicity", kTH1D, {cfgAxis.axisMultiplicity}); - histos.add("hCentrality", "hCentrality", kTH1D, {cfgAxis.axisMultiplicity}); - histos.add("hVertexZ", "hVertexZ", kTH1D, {cfgAxis.axisVtxZ}); + if (!(doprocessTPCtrackEff)) { + + same.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, userAxis)); + mixed.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, userAxis)); + + histos.add("hMultiplicity", "hMultiplicity", kTH1D, {cfgAxis.axisMultQA}); + histos.add("hCentrality", "hCentrality", kTH1D, {cfgAxis.axisMultQA}); + histos.add("hVertexZ", "hVertexZ", kTH1D, {cfgAxis.axisVtxZ}); + + histos.add("hGapSide", "hGapSide", kTH1I, {{5, -0.5, 4.5}}); + histos.add("hTrueGapSide", "hTrueGapSide", kTH1I, {{6, -1.5, 4.5}}); + histos.add("hTrueGapSide_AfterSel", "hTrueGapSide_AfterSel", kTH1I, {{6, -1.5, 4.5}}); + + histos.add("Trig_eta", "Trig_eta", kTH1D, {cfgAxis.axisEtaTrig}); + histos.add("Trig_eta_corrected", "Trig_eta_corrected", kTH1D, {cfgAxis.axisEtaTrig}); + histos.add("Trig_phi", "Trig_phi", kTH1D, {cfgAxis.axisPhi}); + histos.add("Trig_phi_corrected", "Trig_phi_corrected", kTH1D, {cfgAxis.axisPhi}); + histos.add("Trig_etavsphi", "Trig_etavsphi", kTH2D, {cfgAxis.axisPhi, cfgAxis.axisEtaTrig}); + histos.add("Trig_pt", "Trig_pt", kTH1D, {cfgAxis.axisPtTrigger}); + histos.add("Trig_pt_corrected", "Trig_pt_corrected", kTH1D, {cfgAxis.axisPtTrigger}); + histos.add("Trig_invMass", "Trig_invMass", kTH1D, {cfgAxis.axisInvMassQA}); + histos.add("Trig_hist", "Trig_hist", kTHnSparseF, {cfgAxis.axisSample, cfgAxis.axisVtxZ, cfgAxis.axisMultiplicity, cfgAxis.axisPtTrigger, cfgAxis.axisInvMass}); + histos.add("Trig_amp", "Trig_amp", kTH1D, {cfgAxis.axisAmplitude}); + histos.add("Channel_vs_Trig_amp", "Channel_vs_Trig_amp", kTH2D, {cfgAxis.axisChannel, cfgAxis.axisAmplitude}); + + histos.add("Assoc_eta", "Assoc_eta", kTH1D, {cfgAxis.axisEtaAssoc}); + histos.add("Assoc_phi", "Assoc_phi", kTH1D, {cfgAxis.axisPhi}); + histos.add("Assoc_etavsphi", "Assoc_etavsphi", kTH2D, {cfgAxis.axisPhi, cfgAxis.axisEtaAssoc}); + histos.add("Assoc_amp", "Assoc_amp", kTH1D, {cfgAxis.axisAmplitude}); + histos.add("Channel_vs_Assoc_amp", "Channel_vs_Assoc_amp", kTH2D, {cfgAxis.axisChannel, cfgAxis.axisAmplitude}); + + histos.add("deltaEta_deltaPhi_same", "deltaEta_deltaPhi_same", kTH2D, {cfgAxis.axisDeltaPhi, cfgAxis.axisDeltaEta}); + histos.add("deltaEta_deltaPhi_mixed", "deltaEta_deltaPhi_mixed", kTH2D, {cfgAxis.axisDeltaPhi, cfgAxis.axisDeltaEta}); + + histos.add("TPCNClsFound", "TPCNClsFound", kTH1D, {cfgAxis.axisTPCNClsFound}); + histos.add("TPCNClsCrossedRows", "TPCNClsCrossedRows", kTH1D, {cfgAxis.axisTPCNClsCrossedRows}); + histos.add("TPCChi2NCl", "TPCChi2NCl", kTH1D, {cfgAxis.axisTPCChi2NCl}); + histos.add("TPCdcaZ", "TPCdcaZ", kTH1D, {cfgAxis.axisTPCdcaZ}); + + histos.add("MFTNClusters", "MFTNClusters", kTH1D, {cfgAxis.axisMFTNClusters}); + histos.add("MFTbestDCAXY", "MFTbestDCAXY", kTH1D, {cfgAxis.axisMFTbestDCAXY}); + histos.add("MFTbestDCAZ", "MFTbestDCAZ", kTH1D, {cfgAxis.axisMFTbestDCAZ}); + + histos.add("ReassignedMFTtrackAmbDegree", "ReassignedMFTtrackAmbDegree", kTH1D, {cfgAxis.axisMFTAmbDegree}); + histos.add("AssignedMFTtrackAmbDegree", "AssignedMFTtrackAmbDegree", kTH1D, {cfgAxis.axisMFTAmbDegree}); + } - histos.add("hGapSide", "hGapSide", kTH1I, {{5, -0.5, 4.5}}); - histos.add("hTrueGapSide", "hTrueGapSide", kTH1I, {{6, -1.5, 4.5}}); - histos.add("hTrueGapSide_AfterSel", "hTrueGapSide_AfterSel", kTH1I, {{6, -1.5, 4.5}}); + if (doprocessTPCtrackEff) { + histos.add("hGenMCdndpt", "hGenMCdndpt", kTH3D, {cfgAxis.axisVtxZ, cfgAxis.axisEtaEfficiency, cfgAxis.axisPtEfficiency}); + histos.add("hRecMCdndpt", "hRecMCdndpt", kTH3D, {cfgAxis.axisVtxZ, cfgAxis.axisEtaEfficiency, cfgAxis.axisPtEfficiency}); + } - histos.add("Trig_eta", "Trig_eta", kTH1D, {cfgAxis.axisEtaTrig}); - histos.add("Trig_phi", "Trig_phi", kTH1D, {cfgAxis.axisPhi}); - histos.add("Trig_etavsphi", "Trig_etavsphi", kTH2D, {cfgAxis.axisPhi, cfgAxis.axisEtaTrig}); - histos.add("Trig_pt", "Trig_pt", kTH1D, {cfgAxis.axisPtTrigger}); - histos.add("Trig_invMass", "Trig_invMass", kTH1D, {cfgAxis.axisInvMassQA}); - histos.add("Trig_hist", "Trig_hist", kTHnSparseF, {cfgAxis.axisSample, cfgAxis.axisVtxZ, cfgAxis.axisMultiplicity, cfgAxis.axisPtTrigger, cfgAxis.axisInvMass}); - histos.add("Trig_amp", "Trig_amp", kTH1D, {cfgAxis.axisAmplitude}); - histos.add("Channel_vs_Trig_amp", "Channel_vs_Trig_amp", kTH2D, {cfgAxis.axisChannel, cfgAxis.axisAmplitude}); + myTrackFilter = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, + TrackSelection::GlobalTrackRun3DCAxyCut::Default); + myTrackFilter.SetPtRange(cfgSel.cfgPtCutMin, cfgSel.cfgPtCutMax); + myTrackFilter.SetEtaRange(-cfgSel.cfgEtaCut, cfgSel.cfgEtaCut); + myTrackFilter.SetMinNCrossedRowsTPC(cfgSel.cfgTpcMinNCrossedRows); + myTrackFilter.SetMinNClustersTPC(cfgSel.cfgTpcMinNclsFound); + myTrackFilter.SetMaxChi2PerClusterTPC(cfgSel.cfgTpcMaxChi2PerCluster); + myTrackFilter.SetMaxDcaZ(cfgSel.cfgTpcMaxDcaZ); + myTrackFilter.print(); + } - histos.add("Assoc_eta", "Assoc_eta", kTH1D, {cfgAxis.axisEtaAssoc}); - histos.add("Assoc_phi", "Assoc_phi", kTH1D, {cfgAxis.axisPhi}); - histos.add("Assoc_etavsphi", "Assoc_etavsphi", kTH2D, {cfgAxis.axisPhi, cfgAxis.axisEtaAssoc}); - histos.add("Assoc_amp", "Assoc_amp", kTH1D, {cfgAxis.axisAmplitude}); - histos.add("Channel_vs_Assoc_amp", "Channel_vs_Assoc_amp", kTH2D, {cfgAxis.axisChannel, cfgAxis.axisAmplitude}); + void loadEffCorrection(uint64_t timestamp) + { + if (fLoadTrkEffCorr) { + return; + } + if (cfgSel.cfgEffccdbPath.value.empty() == false) { + hTrkEff = ccdb->getForTimeStamp(cfgSel.cfgEffccdbPath, timestamp); + if (hTrkEff == nullptr) { + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgSel.cfgEffccdbPath.value.c_str()); + } + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgSel.cfgEffccdbPath.value.c_str(), (void*)hTrkEff); + } - histos.add("deltaEta_deltaPhi_same", "deltaEta_deltaPhi_same", kTH2D, {cfgAxis.axisDeltaPhi, cfgAxis.axisDeltaEta}); - histos.add("deltaEta_deltaPhi_mixed", "deltaEta_deltaPhi_mixed", kTH2D, {cfgAxis.axisDeltaPhi, cfgAxis.axisDeltaEta}); + if (cfgSel.cfgAccccdbPath.value.empty() == false) { + hTrkAcc = ccdb->getForTimeStamp(cfgSel.cfgAccccdbPath, timestamp); + if (hTrkAcc == nullptr) { + LOGF(fatal, "Could not load NUA histogram for trigger particles from %s", cfgSel.cfgAccccdbPath.value.c_str()); + } + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgSel.cfgAccccdbPath.value.c_str(), (void*)hTrkAcc); + } - histos.add("TPCNClsFound", "TPCNClsFound", kTH1D, {cfgAxis.axisTPCNClsFound}); - histos.add("TPCNClsCrossedRows", "TPCNClsCrossedRows", kTH1D, {cfgAxis.axisTPCNClsCrossedRows}); - histos.add("TPCChi2NCl", "TPCChi2NCl", kTH1D, {cfgAxis.axisTPCChi2NCl}); - histos.add("TPCdcaZ", "TPCdcaZ", kTH1D, {cfgAxis.axisTPCdcaZ}); + fLoadTrkEffCorr = true; + } - histos.add("MFTNClusters", "MFTNClusters", kTH1D, {cfgAxis.axisMFTNClusters}); - histos.add("MFTbestDCAXY", "MFTbestDCAXY", kTH1D, {cfgAxis.axisMFTbestDCAXY}); - histos.add("MFTbestDCAZ", "MFTbestDCAZ", kTH1D, {cfgAxis.axisMFTbestDCAZ}); + float getTrkEffCorr(float posZ, float eta, float pt) + { + if (!cfgSel.applyEffCorr || !hTrkEff) { + return 1.0; + } + int zBin = hTrkEff->GetXaxis()->FindBin(posZ); + int etaBin = hTrkEff->GetYaxis()->FindBin(eta); + int ptBin = hTrkEff->GetZaxis()->FindBin(pt); + float effweight = 1.0 / hTrkEff->GetBinContent(zBin, etaBin, ptBin); + if (!std::isfinite(effweight) || effweight <= 0) { + return 1.0; + } + return effweight; + } - histos.add("ReassignedMFTtrackAmbDegree", "ReassignedMFTtrackAmbDegree", kTH1D, {cfgAxis.axisMFTAmbDegree}); - histos.add("AssignedMFTtrackAmbDegree", "AssignedMFTtrackAmbDegree", kTH1D, {cfgAxis.axisMFTAmbDegree}); + float getTrkAccCorr(float posZ, float eta, float phi) + { + if (!cfgSel.applyAccCorr || !hTrkAcc) { + return 1.0; + } + int zBin = hTrkAcc->GetXaxis()->FindBin(posZ); + int etaBin = hTrkAcc->GetYaxis()->FindBin(eta); + int phiBin = hTrkAcc->GetZaxis()->FindBin(phi); + float nua = hTrkAcc->GetBinContent(zBin, etaBin, phiBin); + if (!std::isfinite(nua) || nua <= 0) { + return 1.0; + } + return nua; } template @@ -258,16 +366,19 @@ struct LongrangecorrDerived { } template - void fillTrigTrackQA(TTrack const& track) + void fillTrigTrackQA(TTrack const& track, float trigAmpl, float trkeff, float trkAcc) { histos.fill(HIST("Trig_etavsphi"), track.phi(), track.eta()); histos.fill(HIST("Trig_eta"), track.eta()); histos.fill(HIST("Trig_phi"), track.phi()); + histos.fill(HIST("Trig_eta_corrected"), track.eta(), trkeff); + histos.fill(HIST("Trig_phi_corrected"), track.phi(), trkAcc); if constexpr (requires { track.channelID(); }) { - histos.fill(HIST("Trig_amp"), track.amplitude()); - histos.fill(HIST("Channel_vs_Trig_amp"), track.channelID(), track.amplitude()); + histos.fill(HIST("Trig_amp"), trigAmpl); + histos.fill(HIST("Channel_vs_Trig_amp"), track.channelID(), trigAmpl); } else { histos.fill(HIST("Trig_pt"), track.pt()); + histos.fill(HIST("Trig_pt_corrected"), track.pt(), trkeff); } if constexpr (requires { track.invMass(); }) { histos.fill(HIST("Trig_invMass"), track.invMass()); @@ -291,14 +402,14 @@ struct LongrangecorrDerived { } template - void fillAssocTrackQA(TTrack const& track) + void fillAssocTrackQA(TTrack const& track, float assoAmpl) { histos.fill(HIST("Assoc_etavsphi"), track.phi(), track.eta()); histos.fill(HIST("Assoc_eta"), track.eta()); histos.fill(HIST("Assoc_phi"), track.phi()); if constexpr (requires { track.channelID(); }) { - histos.fill(HIST("Assoc_amp"), track.amplitude()); - histos.fill(HIST("Channel_vs_Assoc_amp"), track.channelID(), track.amplitude()); + histos.fill(HIST("Assoc_amp"), assoAmpl); + histos.fill(HIST("Channel_vs_Assoc_amp"), track.channelID(), assoAmpl); } if constexpr (requires { track.nClusters(); }) { histos.fill(HIST("MFTNClusters"), track.nClusters()); @@ -336,11 +447,8 @@ struct LongrangecorrDerived { int fSampleIndex = gRandom->Uniform(0, cfgSel.cfgSampleSize); for (auto const& triggerTrack : triggers) { auto trigAmpl = 1.0f; - if constexpr (requires { triggerTrack.channelID(); }) { - trigAmpl = triggerTrack.amplitude(); - } else { - trigAmpl = 1.0; - } + auto trkeff = 1.0f; + auto trkAcc = 1.0f; if (!isTrackSelected(triggerTrack)) continue; @@ -352,41 +460,71 @@ struct LongrangecorrDerived { if (cfgSel.cfgV0Mask != 0 && (cfgSel.cfgV0Mask & (1u << static_cast(triggerTrack.v0Type()))) == 0u) continue; } + + if constexpr (requires { triggerTrack.channelID(); }) { + if (cfgSel.cfgRequireFt0aOuterRing && !triggerTrack.isTrackFT0Outer()) + continue; + if (cfgSel.cfgRequireFt0aInnerRing && triggerTrack.isTrackFT0Outer()) + continue; + trigAmpl = triggerTrack.amplitude(); + } else { + trigAmpl = 1.0; + } + + if constexpr (step == CorrelationContainer::kCFStepCorrected) { + if constexpr (requires { triggerTrack.trackType(); }) { + trkeff = getTrkEffCorr(vz, triggerTrack.eta(), triggerTrack.pt()); + trkAcc = getTrkAccCorr(vz, triggerTrack.eta(), triggerTrack.phi()); + } else { + trkeff = 1.0; + trkAcc = 1.0; + } + } + + if (cfgSel.cfgVerbosity > 0) { + LOGF(info, "NUE correction factor: %f | NUA correction factor: %f", trkeff, trkAcc); + } + if (!mixing) { - fillTrigTrackQA(triggerTrack); + fillTrigTrackQA(triggerTrack, trigAmpl, trkeff, trkAcc); if constexpr (requires { triggerTrack.channelID(); }) { - histos.fill(HIST("Trig_hist"), fSampleIndex, vz, multiplicity, 1.0, 1.0, eventWeight * trigAmpl); + histos.fill(HIST("Trig_hist"), fSampleIndex, vz, multiplicity, 1.0, 1.0, eventWeight * trigAmpl * trkeff * trkAcc); } else if constexpr (requires { triggerTrack.invMass(); }) { - histos.fill(HIST("Trig_hist"), fSampleIndex, vz, multiplicity, triggerTrack.pt(), triggerTrack.invMass(), eventWeight * trigAmpl); + histos.fill(HIST("Trig_hist"), fSampleIndex, vz, multiplicity, triggerTrack.pt(), triggerTrack.invMass(), eventWeight * trigAmpl * trkeff * trkAcc); } else { - histos.fill(HIST("Trig_hist"), fSampleIndex, vz, multiplicity, triggerTrack.pt(), 1.0, eventWeight * trigAmpl); + histos.fill(HIST("Trig_hist"), fSampleIndex, vz, multiplicity, triggerTrack.pt(), 1.0, eventWeight * trigAmpl * trkeff * trkAcc); } } for (auto const& assoTrack : assocs) { auto assoAmpl = 1.0f; + + if (!isTrackSelected(assoTrack)) + continue; + if constexpr (requires { assoTrack.channelID(); }) { + if (cfgSel.cfgRequireFt0cOuterRing && !assoTrack.isTrackFT0Outer()) + continue; + if (cfgSel.cfgRequireFt0cInnerRing && assoTrack.isTrackFT0Outer()) + continue; assoAmpl = assoTrack.amplitude(); } else { assoAmpl = 1.0f; } - if (!isTrackSelected(assoTrack)) - continue; - float deltaPhi = RecoDecay::constrainAngle(triggerTrack.phi() - assoTrack.phi(), -PIHalf); float deltaEta = triggerTrack.eta() - assoTrack.eta(); if (!mixing) { - fillAssocTrackQA(assoTrack); - histos.fill(HIST("deltaEta_deltaPhi_same"), deltaPhi, deltaEta, eventWeight * trigAmpl * assoAmpl); + fillAssocTrackQA(assoTrack, assoAmpl); + histos.fill(HIST("deltaEta_deltaPhi_same"), deltaPhi, deltaEta, eventWeight * trigAmpl * assoAmpl * trkeff * trkAcc); } else { - histos.fill(HIST("deltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, eventWeight * trigAmpl * assoAmpl); + histos.fill(HIST("deltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, eventWeight * trigAmpl * assoAmpl * trkeff * trkAcc); } if constexpr (requires { triggerTrack.channelID(); }) { - target->getPairHist()->Fill(step, fSampleIndex, vz, multiplicity, 1.0, deltaPhi, deltaEta, 1.0, eventWeight * trigAmpl * assoAmpl); + target->getPairHist()->Fill(step, fSampleIndex, vz, multiplicity, 1.0, deltaPhi, deltaEta, 1.0, eventWeight * trigAmpl * assoAmpl * trkeff * trkAcc); } else if constexpr (requires { triggerTrack.invMass(); }) { - target->getPairHist()->Fill(step, fSampleIndex, vz, multiplicity, triggerTrack.pt(), deltaPhi, deltaEta, triggerTrack.invMass(), eventWeight * trigAmpl * assoAmpl); + target->getPairHist()->Fill(step, fSampleIndex, vz, multiplicity, triggerTrack.pt(), deltaPhi, deltaEta, triggerTrack.invMass(), eventWeight * trigAmpl * assoAmpl * trkeff * trkAcc); } else { - target->getPairHist()->Fill(step, fSampleIndex, vz, multiplicity, triggerTrack.pt(), deltaPhi, deltaEta, 1.0, eventWeight * trigAmpl * assoAmpl); + target->getPairHist()->Fill(step, fSampleIndex, vz, multiplicity, triggerTrack.pt(), deltaPhi, deltaEta, 1.0, eventWeight * trigAmpl * assoAmpl * trkeff * trkAcc); } } // associated tracks } // trigger tracks @@ -398,6 +536,7 @@ struct LongrangecorrDerived { if (std::abs(col.posZ()) >= cfgSel.cfgVtxCut) { return; } + loadEffCorrection(col.timestamp()); fillCollQA(col); auto multiplicity = 1.0f; if constexpr (requires { col.centrality(); }) { @@ -408,7 +547,11 @@ struct LongrangecorrDerived { } else { multiplicity = col.multiplicity(); } - fillCorrHist(same, triggers, assocs, false, col.posZ(), multiplicity, 1.0); + if (cfgSel.applyEffCorr) { + fillCorrHist(same, triggers, assocs, false, col.posZ(), multiplicity, 1.0); + } else { + fillCorrHist(same, triggers, assocs, false, col.posZ(), multiplicity, 1.0); + } } // process same template @@ -446,9 +589,23 @@ struct LongrangecorrDerived { continue; } } + if (std::abs(col1.posZ()) >= cfgSel.cfgVtxCut || std::abs(col2.posZ()) >= cfgSel.cfgVtxCut) { + continue; + } float eventweight = 1.0f / it.currentWindowNeighbours(); auto multiplicity = getMultiplicity(col1); - fillCorrHist(mixed, tracks1, tracks2, true, col1.posZ(), multiplicity, eventweight); + int bin = binningOnVtxAndMult.getBin(std::tuple(col1.posZ(), multiplicity)); + loadEffCorrection(col1.timestamp()); + + if (cfgSel.cfgVerbosity > 0) { + LOGF(info, "processMixed: Mixed collisions bin: %d pair: [%d, %d] %d (%.3f, %.3f), %d (%.3f, %.3f)", bin, it.isNewWindow(), it.currentWindowNeighbours(), col1.globalIndex(), col1.posZ(), col1.multiplicity(), col2.globalIndex(), col2.posZ(), col2.multiplicity()); + } + + if (cfgSel.applyEffCorr) { + fillCorrHist(mixed, tracks1, tracks2, true, col1.posZ(), multiplicity, eventweight); + } else { + fillCorrHist(mixed, tracks1, tracks2, true, col1.posZ(), multiplicity, eventweight); + } } // pair loop } // process mixed @@ -782,6 +939,87 @@ struct LongrangecorrDerived { processMcGenMixed(mccollisions, ft0as, ft0cs); } + using ColMCTrueTable = soa::Join; + using ColMCRecTable = soa::SmallGroups>; + using TrksMCRecTable = soa::Join; + Preslice perColMidtrack = aod::track::collisionId; + + template + bool isEventSelected(CheckCol const& col) + { + if (!col.sel8()) + return false; + if (!col.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + return false; + if (!col.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + return false; + if (!col.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) + return false; + if (std::abs(col.posZ()) >= cfgSel.cfgVtxCut) + return false; + return true; + } + + template + bool isGenPartSelected(CheckGenPart const& particle) + { + if (!particle.isPhysicalPrimary() || !particle.producedByGenerator()) + return false; + auto pdgParticle = pdg->GetParticle(particle.pdgCode()); + if (pdgParticle == nullptr) + return false; + if (std::abs(pdgParticle->Charge()) < KminCharge) + return false; + return true; + } + + void processTPCtrackEff(ColMCTrueTable::iterator const& mcCollision, ColMCRecTable const& RecCols, + TrksMCRecTable const& RecTracks, aod::McParticles const& mcparticles) + { + if (std::abs(mcCollision.posZ()) >= cfgSel.cfgVtxCut) { + return; + } + bool atLeastOne = false; + for (const auto& RecCol : RecCols) { + if (!isEventSelected(RecCol)) + continue; + if (RecCol.globalIndex() != mcCollision.bestCollisionIndex()) + continue; + auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex()); + atLeastOne = true; + } + for (const auto& particle : mcparticles) { + if (!isGenPartSelected(particle) || + std::abs(particle.eta()) > cfgSel.cfgEtaCut || + particle.pt() < cfgSel.cfgPtCutMin || + particle.pt() > cfgSel.cfgPtCutMax) + continue; + if (atLeastOne) + histos.fill(HIST("hGenMCdndpt"), mcCollision.posZ(), particle.eta(), particle.pt()); + } + for (const auto& RecCol : RecCols) { + if (!isEventSelected(RecCol)) + continue; + if (RecCol.globalIndex() != mcCollision.bestCollisionIndex()) + continue; + auto recTracksPart = RecTracks.sliceBy(perColMidtrack, RecCol.globalIndex()); + for (const auto& track : recTracksPart) { + if (!track.isGlobalTrack()) + continue; + if (!myTrackFilter.IsSelected(track)) + continue; + if (!track.has_mcParticle()) + continue; + auto particle = track.mcParticle(); + if (RecCol.mcCollisionId() != particle.mcCollisionId()) + continue; + if (particle.isPhysicalPrimary()) { + histos.fill(HIST("hRecMCdndpt"), mcCollision.posZ(), particle.eta(), particle.pt()); + } + } + } + } + PROCESS_SWITCH(LongrangecorrDerived, processTpcft0aSE, "same event TPC vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processTpcft0aME, "mixed event TPC vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processTpcft0cSE, "same event TPC vs FT0C", false); @@ -828,6 +1066,7 @@ struct LongrangecorrDerived { PROCESS_SWITCH(LongrangecorrDerived, processMcGenMftft0aME, "mixed MC gen event MFT vs FT0A", false); PROCESS_SWITCH(LongrangecorrDerived, processMcGenFt0aft0cSE, "same MC gen event FT0A vs FT0C", false); PROCESS_SWITCH(LongrangecorrDerived, processMcGenFt0aft0cME, "mixed MC gen event FT0A vs FT0C", false); + PROCESS_SWITCH(LongrangecorrDerived, processTPCtrackEff, "process TPC track efficiency", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx b/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx index b70f6037b85..c04207d4381 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/nucleibalance.cxx @@ -86,13 +86,14 @@ struct Nucleibalance { O2_DEFINE_CONFIGURABLE(cfgCutMCPt, float, 0.5f, "Minimal pT for MC particles (AO2D-MC mode)") O2_DEFINE_CONFIGURABLE(cfgCutMCEta, float, 0.8f, "Eta range for MC particles (AO2D-MC mode)") O2_DEFINE_CONFIGURABLE(cfgUseFT0M, int, 1, "Use FT0M centrality (0-100) as multiplicity axis (1=ON, 0=use Ntracks/multiplicity())") - // Track-quality options (AO2D mode). Default selection corresponds to global tracks. - O2_DEFINE_CONFIGURABLE(cfgTPCNClsMin, int, 70, "Minimum number of TPC clusters (tpcNClsFound) in AO2D mode") - O2_DEFINE_CONFIGURABLE(cfgDcaXYMax, float, 0.1f, "Max |DCA_{xy}| to PV (cm) in AO2D mode") - O2_DEFINE_CONFIGURABLE(cfgDcaZMax, float, 0.2f, "Max |DCA_{z}| to PV (cm) in AO2D mode") - O2_DEFINE_CONFIGURABLE(chi2pertpccluster, float, 2.5f, "Maximum Chi2/cluster for the TPC track segment in AO2D mode") - O2_DEFINE_CONFIGURABLE(chi2peritscluster, float, 36.f, "Maximum Chi2/cluster for the ITS track segment in AO2D mode") - O2_DEFINE_CONFIGURABLE(itsnclusters, int, 5, "Minimum number of ITS clusters in AO2D mode") + // Track-quality options. Default selection corresponds to global tracks. + O2_DEFINE_CONFIGURABLE(cfgTPCNClsMin, int, 70, "Minimum number of TPC clusters (tpcNClsFound)") + O2_DEFINE_CONFIGURABLE(cfgDcaXYMax, float, 0.1f, "Max |DCA_{xy}| to PV (cm)") + O2_DEFINE_CONFIGURABLE(cfgDcaZMax, float, 0.2f, "Max |DCA_{z}| to PV (cm)") + O2_DEFINE_CONFIGURABLE(cfgRequirePrimaryTrack, int, 1, "Require isPrimaryTrack()= true (1=ON, 0=OFF)") + O2_DEFINE_CONFIGURABLE(chi2pertpccluster, float, 2.5f, "Maximum Chi2/cluster for the TPC track segment") + O2_DEFINE_CONFIGURABLE(chi2peritscluster, float, 36.f, "Maximum Chi2/cluster for the ITS track segment") + O2_DEFINE_CONFIGURABLE(itsnclusters, int, 1, "Minimum number of ITS clusters") O2_DEFINE_CONFIGURABLE(cfgPtOrder, int, 1, "Only consider pairs for which pT,1 < pT,2 (0 = OFF, 1 = ON)"); O2_DEFINE_CONFIGURABLE(cfgTriggerCharge, int, 0, "Select on charge of trigger particle: 0 = all; 1 = positive; -1 = negative"); @@ -343,6 +344,15 @@ struct Nucleibalance { return false; } } + // Match the standard Lambda(1520) task option `cfgPrimaryTrack`: + // require primary tracks when the corresponding selection column is available. + if (cfgRequirePrimaryTrack.value != 0) { + if constexpr (requires { trk.isPrimaryTrack(); }) { + if (!trk.isPrimaryTrack()) { + return false; + } + } + } if constexpr (requires { trk.itsNCls(); }) { if (itsnclusters.value > 0 && trk.itsNCls() < itsnclusters.value) { @@ -1680,7 +1690,7 @@ struct Lambdastarproxy { // PID strategy values static constexpr int PidStrategyRectangular = 0; static constexpr int PidStrategyCircularTPCAndTOF = 1; - static constexpr int PidStrategyTOFOnly = 2; + static constexpr int PidStrategyNucleiDeuteronTPC = 2; // Basic configuration for event and track selection Configurable lstarCutVertex{"lstarCutVertex", float{CutVertexDefault}, "Accepted z-vertex range (cm)"}; Configurable lstarCutPtMin{"lstarCutPtMin", float{CutPtMinDefault}, "Minimal pT for tracks (GeV/c)"}; @@ -1700,16 +1710,28 @@ struct Lambdastarproxy { Configurable lstarCutNsigmaTOFKaon{"lstarCutNsigmaTOFKaon", float{NsigmaTOFDefault}, "|nSigma^{TOF}_{K}| cut"}; Configurable lstarCutNsigmaTPCDe{"lstarCutNsigmaTPCDe", float{NsigmaTPCDefault}, "|nSigma^{TPC}_{d}| cut"}; Configurable lstarCutNsigmaTOFDe{"lstarCutNsigmaTOFDe", float{NsigmaTOFDefault}, "|nSigma^{TOF}_{d}| cut"}; + Configurable lstarEnableTOFNsigmaCutDe{"lstarEnableTOFNsigmaCutDe", 0, "Enable deuteron-only TOF nSigma cut in PID strategy 2"}; + Configurable lstarProxyUseProtonPIDAsDeuteron{"lstarProxyUseProtonPIDAsDeuteron", 0, "Closure/control test: keep proxy candidates that pass the normal deuteron selection and are also proton-like, then build p_proxy = p_track/2"}; + // Optional deuteron-only TOF auxiliary selections. + // Defaults are OFF, so strategy 2 remains TPC nSigma only for deuterons. + Configurable lstarEnableBetaCutDe{"lstarEnableBetaCutDe", 0, "Enable deuteron-only TOF beta cut using beta() > lstarBetaCutDe"}; + Configurable lstarBetaCutDe{"lstarBetaCutDe", 0.4f, "Minimum TOF beta for deuteron-only beta cut"}; + Configurable lstarEnableExpSignalTOFDe{"lstarEnableExpSignalTOFDe", 0, "Enable deuteron-only TOF expected-signal-difference cut when lstarTOFExpSignalDiffDeMax > 0"}; + Configurable lstarTOFExpSignalDiffDeMax{"lstarTOFExpSignalDiffDeMax", -1.f, "Maximum |tofExpSignalDiffDe| for deuterons; <=0 disables the numeric cut"}; + // PID strategy for final K/p/d candidate selection. - // 0 = rectangular cuts: |TPC| < cut and, if TOF exists, |TOF| < cut + // 0 = pT-ref dependent rectangular cuts: + // pT < pTref: require |TPC| < TPC cut only + // pT >= pTref and TOF exists: require |TPC| < TPC cut and |TOF| < TOF cut + // pT >= pTref and TOF missing: reject // 1 = pT-ref dependent circular cut: // pT < pTref: require |TPC| < TPC cut only // pT >= pTref and TOF exists: require sqrt(TPC^2 + TOF^2) < circular cut // pT >= pTref and TOF missing: reject - // 2 = TOF-only above pTref: - // pT < pTref: require |TPC| < TPC cut only - // pT >= pTref: require TOF hit and |TOF| < TOF cut - Configurable lstarPidStrategy{"lstarPidStrategy", int{PidStrategyRectangular}, "PID strategy: 0=rectangular TPC/TOF, 1=pTref circular TPC+TOF, 2=pTref TOF-only"}; + // 2 = hybrid official-like PID: + // deuterons: require |TPC_d| < TPC cut only + // kaons/protons: use the Lambda(1520)-like pT-ref circular TPC+TOF logic + Configurable lstarPidStrategy{"lstarPidStrategy", int{PidStrategyRectangular}, "PID strategy: 0=pTref rectangular TPC/TOF, 1=pTref circular TPC+TOF, 2=hybrid: K/p circular, d TPC-only"}; Configurable lstarPidCircularCutKaon{"lstarPidCircularCutKaon", 2.0f, "Circular PID cut sqrt(nSigmaTPC_K^2+nSigmaTOF_K^2) for kaons"}; Configurable lstarPidCircularCutPr{"lstarPidCircularCutPr", 2.0f, "Circular PID cut sqrt(nSigmaTPC_p^2+nSigmaTOF_p^2) for protons"}; @@ -1720,8 +1742,12 @@ struct Lambdastarproxy { Configurable lstarPidPtRefDe{"lstarPidPtRefDe", 0.8f, "pT reference for deuteron PID strategy"}; // Track quality + Configurable lstarRequireINELgt0{"lstarRequireINELgt0", 1, "Require INEL>0 event selection using isInelGt0() when available; fallback to multNTracksPVeta1()/numContrib()"}; Configurable lstarRequireGlobalTrack{"lstarRequireGlobalTrack", bool{RequireGlobalTrackDefault}, "Require global tracks (default)"}; - Configurable lstarTPCNClsMin{"lstarTPCNClsMin", int{TPCNClsMinDefault}, "Minimum number of TPC clusters (tpcNClsFound)"}; + Configurable lstarRequirePrimaryTrack{"lstarRequirePrimaryTrack", 1, "Require isPrimaryTrack() for Lambda* proxy candidates when the column is available"}; + Configurable lstarOnlyGlobalTrackCuts{"lstarOnlyGlobalTrackCuts", 0, "If enabled, apply only the global-track plus primary-track requirements and skip additional ITS/TPC/DCA/chi2 track-quality cuts"}; + Configurable lstarTPCNClsMin{"lstarTPCNClsMin", int{TPCNClsMinDefault}, "Minimum number of TPC crossed rows (tpcNClsCrossedRows)"}; + Configurable lstarTPCCrossedRowsOverFindableMin{"lstarTPCCrossedRowsOverFindableMin", 0.8f, "Minimum TPC crossed rows over findable clusters"}; Configurable lstarDcaXYMax{"lstarDcaXYMax", float{DcaXYMaxDefault}, "Max |DCA_{xy}| to PV (cm)"}; Configurable lstarDcaZMax{"lstarDcaZMax", float{DcaZMaxDefault}, "Max |DCA_{z}| to PV (cm)"}; Configurable lstarChi2PerTPCCluster{"lstarChi2PerTPCCluster", float{Chi2PerTPCClusterDefault}, "Maximum Chi2/cluster for the TPC track segment"}; @@ -1738,6 +1764,9 @@ struct Lambdastarproxy { Configurable lstarNoMixedEvents{"lstarNoMixedEvents", int{NoMixedEventsDefault}, "Number of previous events kept for mixed-event background"}; Configurable lstarMixZvtxMax{"lstarMixZvtxMax", float{MixZvtxMaxDefault}, "Max |Δzvtx| (cm) for event mixing"}; Configurable lstarMixMultMax{"lstarMixMultMax", float{MixMultMaxDefault}, "Max |Δmult| for event mixing"}; + // Master switch for PID QA histogram filling. + // Inclusive PID-QA histograms are filled before final PID cuts, after event/track-quality cuts. + // Candidate-level nSigma/TOF/DCA histograms are filled after final PID cuts. Configurable lstarEnablePidQA{"lstarEnablePidQA", 0, "Enable PID QA histograms (dE/dx, TOF #beta, proxy invariant-mass QA, etc.): 1 = ON, 0 = OFF"}; Configurable lstarEnableSparse{"lstarEnableSparse", 1, "Enable THnSparse invariant-mass histograms (#Lambda^{*} pK and proxy); 1 = ON, 0 = OFF"}; Configurable lstarLambdaAbsYMax{"lstarLambdaAbsYMax", 0.5f, "Max |y_{pK}| (or y_{proxy K}) for #Lambda^{*} candidates"}; @@ -1790,6 +1819,22 @@ struct Lambdastarproxy { template bool keepCollisionAO2D(TCollision const& collision) const { + // Prefer the official event-selection flag when available. + if (lstarRequireINELgt0.value != 0) { + bool isINELgt0 = true; + + if constexpr (requires { collision.isInelGt0(); }) { + isINELgt0 = collision.isInelGt0(); + } else if constexpr (requires { collision.multNTracksPVeta1(); }) { + isINELgt0 = collision.multNTracksPVeta1() > 0; + } else if constexpr (requires { collision.numContrib(); }) { + isINELgt0 = collision.numContrib() > 0; + } + + if (!isINELgt0) { + return false; + } + } if (lstarCfgTrigger.value == TriggerNone) { return true; } else if (lstarCfgTrigger.value == TriggerSel8) { @@ -1903,14 +1948,40 @@ struct Lambdastarproxy { } } + // Always require primary tracks + if (lstarRequirePrimaryTrack.value != 0) { + if constexpr (requires { trk.isPrimaryTrack(); }) { + if (!trk.isPrimaryTrack()) { + return false; + } + } + } + + // Optional official-baseline mode: use only the O2 global-track and primary-track definitions. + // This bypasses the extra explicit ITS/TPC/DCA/chi2 cuts below. + if (lstarOnlyGlobalTrackCuts.value != 0) { + return true; + } + if constexpr (requires { trk.itsNCls(); }) { if (lstarITSNClusters.value > 0 && trk.itsNCls() < lstarITSNClusters.value) { return false; } } - if constexpr (requires { trk.tpcNClsFound(); }) { - if (lstarTPCNClsMin.value > 0 && trk.tpcNClsFound() < lstarTPCNClsMin.value) { + if constexpr (requires { trk.tpcNClsCrossedRows(); }) { + if (lstarTPCNClsMin.value > 0 && trk.tpcNClsCrossedRows() < lstarTPCNClsMin.value) { + return false; + } + } else if constexpr (requires { trk.tpcNClsFindable(); trk.tpcCrossedRowsOverFindableCls(); }) { + if (lstarTPCNClsMin.value > 0 && trk.tpcNClsFindable() * trk.tpcCrossedRowsOverFindableCls() < lstarTPCNClsMin.value) { + return false; + } + } + + if constexpr (requires { trk.tpcCrossedRowsOverFindableCls(); }) { + if (lstarTPCCrossedRowsOverFindableMin.value > 0.f && + trk.tpcCrossedRowsOverFindableCls() < lstarTPCCrossedRowsOverFindableMin.value) { return false; } } @@ -2037,6 +2108,7 @@ struct Lambdastarproxy { "#Lambda^{*} proxy invariant mass from (d/2 + K);M_{p_{proxy}K} (GeV/c^{2});Counts", HistType::kTH1F, {massAxis}); + // Inclusive PID QA before final candidate PID cuts: after track-quality cuts only // TPC dE/dx vs total momentum histos.add("hTPCdEdxVsP", "TPC dE/dx vs p;p (GeV/c);dE/dx (arb. units);Counts", @@ -2047,7 +2119,8 @@ struct Lambdastarproxy { "TOF #beta vs p;p (GeV/c);#beta_{TOF};Counts", HistType::kTH2F, {pAxis, betaAxis}); - // --- Per-species PID QA (tagged) --- + // --- Per-species inclusive PID QA before final candidate PID cuts --- + // Species tagging here uses classifyPidSpecies() and is meant only for QA. histos.add("hTPCdEdxVsP_Pi", "TPC dE/dx vs p (tagged #pi);p (GeV/c);dE/dx (arb. units);Counts", HistType::kTH2F, {pAxis, dEdxAxis}); @@ -2137,7 +2210,7 @@ struct Lambdastarproxy { "TOF n#sigma_{K} vs p; p (GeV/c); n#sigma^{TOF}_{K};Counts", HistType::kTH2F, {pAxis, nsAxis}); - // --- Additional pT-based PID QA for the final selected K/p/d candidates --- + // --- Candidate PID QA after final selected K/p/d PID cuts --- // These histograms are needed for PID studies in the same pT intervals used by the analysis. histos.add("hTOFBetaVsPt_K", "TOF #beta vs p_{T} for selected K;p_{T} (GeV/c);#beta_{TOF};Counts", @@ -2327,14 +2400,48 @@ struct Lambdastarproxy { return true; // fallback: if column not present, assume available } - bool passFinalCandidatePID(float pt, - float nsTPC, - float nsTOF, - bool hasTof, - float tpcCut, - float tofCut, - float circularCut, - float ptRef) const + template + bool passOptionalDeuteronTOFExtras(const TTrack& trk) const + { + const bool needTOF = + (lstarEnableBetaCutDe.value != 0) || + (lstarEnableExpSignalTOFDe.value != 0 && lstarTOFExpSignalDiffDeMax.value > 0.f); + + if (needTOF) { + if constexpr (requires { trk.hasTOF(); }) { + if (!trk.hasTOF()) { + return false; + } + } + } + + if (lstarEnableBetaCutDe.value != 0) { + if constexpr (requires { trk.beta(); }) { + if (trk.beta() <= lstarBetaCutDe.value) { + return false; + } + } else { + return false; + } + } + + if (lstarEnableExpSignalTOFDe.value != 0 && + lstarTOFExpSignalDiffDeMax.value > 0.f) { + if constexpr (requires { trk.tofExpSignalDiffDe(); }) { + if (std::abs(trk.tofExpSignalDiffDe()) > lstarTOFExpSignalDiffDeMax.value) { + return false; + } + } else { + return false; + } + } + + return true; + } + + bool passFinalCandidatePID(float pt, float nsTPC, float nsTOF, bool hasTof, + float tpcCut, float tofCut, float circularCut, + float ptRef, bool isDeuteron = false) const { // Strategy 1: analysis-note style circular TPC+TOF cut if (lstarPidStrategy.value == PidStrategyCircularTPCAndTOF) { @@ -2349,8 +2456,22 @@ struct Lambdastarproxy { return std::sqrt(nsTPC * nsTPC + nsTOF * nsTOF) < circularCut; } - // Strategy 2: TOF-only above pTref - if (lstarPidStrategy.value == PidStrategyTOFOnly) { + if (lstarPidStrategy.value == PidStrategyNucleiDeuteronTPC) { + // For deuterons, use TPC nσ as the main hard PID selection. + // If the optional deuteron TOF nσ cut is enabled, apply it only when + // the track has a valid TOF match. Tracks without TOF are kept with + // the TPC-only decision, avoiding an additional TOF-matching efficiency loss. + if (isDeuteron) { + if (std::abs(nsTPC) >= tpcCut) { + return false; + } + if (lstarEnableTOFNsigmaCutDe.value != 0 && hasTof) { + return std::abs(nsTOF) < tofCut; + } + return true; + } + + // For kaons/protons, use the Lambda(1520)-like pT-ref circular TPC+TOF logic. if (pt < ptRef) { return std::abs(nsTPC) < tpcCut; } @@ -2359,11 +2480,18 @@ struct Lambdastarproxy { return false; } - return std::abs(nsTOF) < tofCut; + return std::sqrt(nsTPC * nsTPC + nsTOF * nsTOF) < circularCut; } - // Strategy 0: old rectangular logic - return (std::abs(nsTPC) < tpcCut) && (!hasTof || (std::abs(nsTOF) < tofCut)); + // Strategy 0: pT-ref dependent rectangular TPC+TOF cut. + // Below pTref use TPC only; above pTref require TOF and apply both TPC and TOF cuts. + if (pt < ptRef) { + return std::abs(nsTPC) < tpcCut; + } + if (!hasTof) { + return false; + } + return (std::abs(nsTPC) < tpcCut) && (std::abs(nsTOF) < tofCut); } // Return: 0=#pi, 1=K, 2=p, 3=d, -1=unclassified @@ -2457,87 +2585,6 @@ struct Lambdastarproxy { constexpr double MassProton = o2::constants::physics::MassProton; constexpr double MassKaonCharged = o2::constants::physics::MassKaonCharged; - // --- Inclusive PID QA: keep #pi/K/p/d bands in TPC dE/dx and TOF beta plots --- - if (lstarEnablePidQA.value != 0) { - for (auto const& trk : tracks) { - if (trk.pt() < lstarCutPtMin.value || std::abs(trk.eta()) > lstarCutEtaMax.value) { - continue; - } - if (!passTrackQuality(trk)) { - continue; - } - if (trk.sign() == 0) { - continue; - } - // Inclusive PID QA - fillTPCdEdxVsPIfAvailable(trk); - fillTOFBetaVsPIfAvailable(trk); - - // Per-species PID-QA (tagged) histograms - const int sp = classifyPidSpecies(trk); - switch (sp) { - case 0: { // pion - if constexpr (requires { trk.tpcSignal(); }) { - histos.fill(HIST("hTPCdEdxVsP_Pi"), trk.p(), trk.tpcSignal()); - } - if constexpr (requires { trk.beta(); }) { - const bool hasTof = hasTOFMatch(trk); - const float beta = trk.beta(); - if (hasTof && beta > TofBetaMin && beta < TofBetaMax) { - histos.fill(HIST("hTOFBetaVsP_Pi"), trk.p(), beta); - } - } - break; - } - - case 1: { // kaon - if constexpr (requires { trk.tpcSignal(); }) { - histos.fill(HIST("hTPCdEdxVsP_K"), trk.p(), trk.tpcSignal()); - } - if constexpr (requires { trk.beta(); }) { - const bool hasTof = hasTOFMatch(trk); - const float beta = trk.beta(); - if (hasTof && beta > TofBetaMin && beta < TofBetaMax) { - histos.fill(HIST("hTOFBetaVsP_K"), trk.p(), beta); - } - } - break; - } - - case 2: { // proton - if constexpr (requires { trk.tpcSignal(); }) { - histos.fill(HIST("hTPCdEdxVsP_P"), trk.p(), trk.tpcSignal()); - } - if constexpr (requires { trk.beta(); }) { - const bool hasTof = hasTOFMatch(trk); - const float beta = trk.beta(); - if (hasTof && beta > TofBetaMin && beta < TofBetaMax) { - histos.fill(HIST("hTOFBetaVsP_P"), trk.p(), beta); - } - } - break; - } - - case 3: { // deuteron - if constexpr (requires { trk.tpcSignal(); }) { - histos.fill(HIST("hTPCdEdxVsP_D"), trk.p(), trk.tpcSignal()); - } - if constexpr (requires { trk.beta(); }) { - const bool hasTof = hasTOFMatch(trk); - const float beta = trk.beta(); - if (hasTof && beta > TofBetaMin && beta < TofBetaMax) { - histos.fill(HIST("hTOFBetaVsP_D"), trk.p(), beta); - } - } - break; - } - - default: - break; - } - } - } - std::vector kaonCands; std::vector proxyCands; std::vector protonCands; @@ -2547,7 +2594,9 @@ struct Lambdastarproxy { float eventMultFallback = 0.f; // fallback mixing variable: number of selected charged tracks (after quality cuts) - // Inclusive PID QA loop: count all selected charged tracks for fallback multiplicity + // Inclusive track loop before final candidate PID cuts. + // It counts selected charged tracks for fallback multiplicity and when enabled, + // fills inclusive PID QA after track-quality cuts but before final K/p/d PID cuts. for (auto const& trk : tracks) { if (trk.pt() < lstarCutPtMin.value || std::abs(trk.eta()) > lstarCutEtaMax.value) { continue; @@ -2646,25 +2695,44 @@ struct Lambdastarproxy { const float etaD = trkD.eta(); const float phiD = trkD.phi(); - // PID for deuteron candidates + // PID for proxy candidates. + // Normal mode: use the standard deuteron PID and build p_proxy = p_d / 2. + // Closure/control mode: select the subset of standard deuteron-proxy candidates + // that are also proton-like. This tests proton contamination inside the deuteron + // selection, not all proton candidates. + const bool useProtonAsProxy = (lstarProxyUseProtonPIDAsDeuteron.value != 0); + const float nsTPCDe = trkD.tpcNSigmaDe(); const float nsTOFDe = trkD.tofNSigmaDe(); const bool hasTofDe = hasTOFMatch(trkD); - const bool isDeuteron = passFinalCandidatePID(ptD, - nsTPCDe, - nsTOFDe, - hasTofDe, - lstarCutNsigmaTPCDe.value, - lstarCutNsigmaTOFDe.value, - lstarPidCircularCutDe.value, - lstarPidPtRefDe.value); - if (!isDeuteron) { + + if (!passOptionalDeuteronTOFExtras(trkD)) { + continue; + } + + const bool passesDeuteronSelection = passFinalCandidatePID(ptD, nsTPCDe, nsTOFDe, hasTofDe, + lstarCutNsigmaTPCDe.value, lstarCutNsigmaTOFDe.value, + lstarPidCircularCutDe.value, lstarPidPtRefDe.value, + true); + if (!passesDeuteronSelection) { continue; } + if (useProtonAsProxy) { + const float nsTPCPrAsProxy = trkD.tpcNSigmaPr(); + const float nsTOFPrAsProxy = trkD.tofNSigmaPr(); + const bool passesProtonSelection = passFinalCandidatePID(ptD, nsTPCPrAsProxy, nsTOFPrAsProxy, hasTofDe, + lstarCutNsigmaTPCPr.value, lstarCutNsigmaTOFPr.value, + lstarPidCircularCutPr.value, lstarPidPtRefPr.value, + false); + if (!passesProtonSelection) { + continue; + } + } + const double pD = static_cast(ptD) * std::cosh(static_cast(etaD)); - // QA histos for deuteron PID and kinematics + // Candidate QA after final deuteron PID cut if (lstarEnablePidQA.value != 0) { histos.fill(HIST("hDeuteronProxyPt"), ptD); histos.fill(HIST("hDeuteronProxyEta"), etaD); @@ -2724,7 +2792,7 @@ struct Lambdastarproxy { lstarCutNsigmaTPCPr.value, lstarCutNsigmaTOFPr.value, lstarPidCircularCutPr.value, - lstarPidPtRefPr.value); + lstarPidPtRefPr.value, false); if (!isProton) { continue; } @@ -2786,7 +2854,7 @@ struct Lambdastarproxy { lstarCutNsigmaTPCKaon.value, lstarCutNsigmaTOFKaon.value, lstarPidCircularCutKaon.value, - lstarPidPtRefKaon.value); + lstarPidPtRefKaon.value, false); if (!isKaon) { continue; } diff --git a/PWGDQ/Core/AnalysisCompositeCut.cxx b/PWGDQ/Core/AnalysisCompositeCut.cxx index cbf0f328283..8be1abf6e60 100644 --- a/PWGDQ/Core/AnalysisCompositeCut.cxx +++ b/PWGDQ/Core/AnalysisCompositeCut.cxx @@ -13,17 +13,13 @@ #include "AnalysisCut.h" -#include - #include -ClassImp(AnalysisCompositeCut) - - //____________________________________________________________________________ - AnalysisCompositeCut::AnalysisCompositeCut(bool useAND) : AnalysisCut(), - fOptionUseAND(useAND), - fCutList(), - fCompositeCutList() +//____________________________________________________________________________ +AnalysisCompositeCut::AnalysisCompositeCut(bool useAND) : AnalysisCut(), + fOptionUseAND(useAND), + fCutList(), + fCompositeCutList() { // // default constructor diff --git a/PWGDQ/Core/AnalysisCompositeCut.h b/PWGDQ/Core/AnalysisCompositeCut.h index a6b3f6afda4..7e78faebfd6 100644 --- a/PWGDQ/Core/AnalysisCompositeCut.h +++ b/PWGDQ/Core/AnalysisCompositeCut.h @@ -19,7 +19,6 @@ #include "PWGDQ/Core/AnalysisCut.h" -#include #include #include @@ -36,8 +35,8 @@ class AnalysisCompositeCut : public AnalysisCut void AddCut(AnalysisCut* cut) { - if (cut->IsA() == AnalysisCompositeCut::Class()) { - fCompositeCutList.push_back(*(AnalysisCompositeCut*)cut); + if (auto* composite = dynamic_cast(cut)) { + fCompositeCutList.push_back(*composite); } else { fCutList.push_back(*cut); } @@ -52,8 +51,6 @@ class AnalysisCompositeCut : public AnalysisCut bool fOptionUseAND; // true (default): apply AND on all cuts; false: use OR std::vector fCutList; // list of cuts std::vector fCompositeCutList; // list of composite cuts - - ClassDef(AnalysisCompositeCut, 2); }; #endif // PWGDQ_CORE_ANALYSISCOMPOSITECUT_H_ diff --git a/PWGDQ/Core/AnalysisCut.cxx b/PWGDQ/Core/AnalysisCut.cxx index a1dae4ce6b0..63c67d1a94f 100644 --- a/PWGDQ/Core/AnalysisCut.cxx +++ b/PWGDQ/Core/AnalysisCut.cxx @@ -21,8 +21,6 @@ using std::cout; using std::endl; -ClassImp(AnalysisCut); - std::vector AnalysisCut::fgUsedVars = {}; //____________________________________________________________________________ diff --git a/PWGDQ/Core/AnalysisCut.h b/PWGDQ/Core/AnalysisCut.h index 990de29abb4..bb06c423182 100644 --- a/PWGDQ/Core/AnalysisCut.h +++ b/PWGDQ/Core/AnalysisCut.h @@ -72,8 +72,6 @@ class AnalysisCut : public TNamed protected: std::vector fCuts; - - ClassDef(AnalysisCut, 2); }; //____________________________________________________________________________ diff --git a/PWGDQ/Core/CMakeLists.txt b/PWGDQ/Core/CMakeLists.txt index 41ceb661bf9..835c14c17ae 100644 --- a/PWGDQ/Core/CMakeLists.txt +++ b/PWGDQ/Core/CMakeLists.txt @@ -22,17 +22,3 @@ o2physics_add_library(PWGDQCore MCProng.cxx MCSignal.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DCAFitter O2::GlobalTracking O2Physics::AnalysisCore KFParticle::KFParticle O2Physics::MLCore) - -o2physics_target_root_dictionary(PWGDQCore - HEADERS AnalysisCut.h - AnalysisCompositeCut.h - VarManager.h - HistogramManager.h - CutsLibrary.h - MixingHandler.h - MixingLibrary.h - HistogramsLibrary.h - MCProng.h - MCSignal.h - MCSignalLibrary.h - LINKDEF PWGDQCoreLinkDef.h) diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index bcc8a1ba788..8c069d64920 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -45,7 +45,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) // TODO: Agree on some conventions for the naming // Think of possible customization of the predefined cuts via names - AnalysisCompositeCut* cut = new AnalysisCompositeCut(cutName, cutName); + auto* cut = new AnalysisCompositeCut(cutName, cutName); std::string nameStr = cutName; // /////////////////////////////////////////////// @@ -54,30 +54,30 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) // // // see CutsLubrary.h for the description // // /////////////////////////////////////////////// - if (!nameStr.compare("Electron2022")) { + if (nameStr == "Electron2022") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug5")); return cut; } - if (!nameStr.compare("Electron2023")) { + if (nameStr == "Electron2023") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug5_noCorr")); return cut; } - if (!nameStr.compare("Electron2025_1")) { - AnalysisCut* kineCut = new AnalysisCut("kineCut", "kine cut"); + if (nameStr == "Electron2025_1") { + auto* kineCut = new AnalysisCut("kineCut", "kine cut"); kineCut->AddCut(VarManager::kP, 1.0, 1000.0); kineCut->AddCut(VarManager::kEta, -0.9, 0.9); - AnalysisCut* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); + auto* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); qualityCuts->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 4.0); qualityCuts->AddCut(VarManager::kTPCncls, 70, 161.); qualityCuts->AddCut(VarManager::kTrackDCAz, -0.5, 0.5); - AnalysisCut* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); + auto* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); pidCuts->AddCut(VarManager::kTPCnSigmaEl, -3.0, 4.0, false, VarManager::kPin, 0.0, 5.0); pidCuts->AddCut(VarManager::kTPCnSigmaEl, -1.5, 4.0, false, VarManager::kPin, 5.0, 1000.0); pidCuts->AddCut(VarManager::kTPCnSigmaPi, 2.5, 999, false, VarManager::kPin, 0.0, 5.0); @@ -89,18 +89,18 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("Electron2025_2")) { - AnalysisCut* kineCut = new AnalysisCut("kineCut", "kine cut"); + if (nameStr == "Electron2025_2") { + auto* kineCut = new AnalysisCut("kineCut", "kine cut"); kineCut->AddCut(VarManager::kP, 1.0, 1000.0); kineCut->AddCut(VarManager::kEta, -0.9, 0.9); - AnalysisCut* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); + auto* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); qualityCuts->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 4.0); qualityCuts->AddCut(VarManager::kTPCncls, 70, 161.); qualityCuts->AddCut(VarManager::kTrackDCAz, -0.5, 0.5); - AnalysisCut* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); + auto* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); pidCuts->AddCut(VarManager::kTPCnSigmaEl, -3.0, 4.0, false, VarManager::kPin, 0.0, 5.0); pidCuts->AddCut(VarManager::kTPCnSigmaEl, -2.0, 4.0, false, VarManager::kPin, 5.0, 1000.0); pidCuts->AddCut(VarManager::kTPCnSigmaPi, 2.0, 999, false, VarManager::kPin, 0.0, 5.0); @@ -112,18 +112,18 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("Electron2025_3")) { - AnalysisCut* kineCut = new AnalysisCut("kineCut", "kine cut"); + if (nameStr == "Electron2025_3") { + auto* kineCut = new AnalysisCut("kineCut", "kine cut"); kineCut->AddCut(VarManager::kP, 1.0, 1000.0); kineCut->AddCut(VarManager::kEta, -0.9, 0.9); - AnalysisCut* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); + auto* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); qualityCuts->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 4.0); qualityCuts->AddCut(VarManager::kTPCncls, 70, 161.); qualityCuts->AddCut(VarManager::kTrackDCAz, -0.5, 0.5); - AnalysisCut* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); + auto* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); pidCuts->AddCut(VarManager::kTPCnSigmaEl, -2.5, 4.0, false, VarManager::kPin, 0.0, 5.0); pidCuts->AddCut(VarManager::kTPCnSigmaEl, -2.0, 4.0, false, VarManager::kPin, 5.0, 1000.0); pidCuts->AddCut(VarManager::kTPCnSigmaPr, 2.5, 999, false, VarManager::kPin, 0.0, 5.0); @@ -134,18 +134,18 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("Electron2025_4")) { - AnalysisCut* kineCut = new AnalysisCut("kineCut", "kine cut"); + if (nameStr == "Electron2025_4") { + auto* kineCut = new AnalysisCut("kineCut", "kine cut"); kineCut->AddCut(VarManager::kP, 1.0, 1000.0); kineCut->AddCut(VarManager::kEta, -0.9, 0.9); - AnalysisCut* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); + auto* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); qualityCuts->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 4.0); qualityCuts->AddCut(VarManager::kTPCncls, 70, 161.); qualityCuts->AddCut(VarManager::kTrackDCAz, -0.5, 0.5); - AnalysisCut* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); + auto* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); pidCuts->AddCut(VarManager::kTPCnSigmaEl, -2.5, 4.0, false, VarManager::kPin, 0.0, 5.0); pidCuts->AddCut(VarManager::kTPCnSigmaEl, -1.5, 4.0, false, VarManager::kPin, 5.0, 1000.0); pidCuts->AddCut(VarManager::kTPCnSigmaPi, 2.5, 999, false, VarManager::kPin, 0.0, 5.0); @@ -157,18 +157,18 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("Electron2025_5")) { - AnalysisCut* kineCut = new AnalysisCut("kineCut", "kine cut"); + if (nameStr == "Electron2025_5") { + auto* kineCut = new AnalysisCut("kineCut", "kine cut"); kineCut->AddCut(VarManager::kP, 1.0, 1000.0); kineCut->AddCut(VarManager::kEta, -0.9, 0.9); - AnalysisCut* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); + auto* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); qualityCuts->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 4.0); qualityCuts->AddCut(VarManager::kTPCncls, 70, 161.); qualityCuts->AddCut(VarManager::kTrackDCAz, -0.5, 0.5); - AnalysisCut* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); + auto* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); pidCuts->AddCut(VarManager::kTPCnSigmaEl, -2.25, 4.0, false, VarManager::kPin, 0.0, 5.0); pidCuts->AddCut(VarManager::kTPCnSigmaEl, -1.5, 4.0, false, VarManager::kPin, 5.0, 1000.0); pidCuts->AddCut(VarManager::kTPCnSigmaPi, 2.5, 999, false, VarManager::kPin, 0.0, 5.0); @@ -180,41 +180,69 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("LowMassElectron2023")) { + if (nameStr == "Electron2025_4_ldong") { + auto* kineCut = new AnalysisCut("kineCut", "kine cut"); + kineCut->AddCut(VarManager::kP, 1.0, 1000.0); + kineCut->AddCut(VarManager::kEta, -0.9, 0.9); + + auto* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); + qualityCuts->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); + qualityCuts->AddCut(VarManager::kIsSPDany, 0.5, 1.5); + qualityCuts->AddCut(VarManager::kITSchi2, 0.0, 5.0); + qualityCuts->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + qualityCuts->AddCut(VarManager::kTPCncls, 70, 161.); + qualityCuts->AddCut(VarManager::kTrackDCAz, -0.5, 0.5); + qualityCuts->AddCut(VarManager::kTrackDCAxy, -0.5, 0.5); + + auto* pidCuts = new AnalysisCut("pidCuts", "pid cuts"); + pidCuts->AddCut(VarManager::kTPCnSigmaEl, -2.5, 4.0, false, VarManager::kPin, 0.0, 5.0); + pidCuts->AddCut(VarManager::kTPCnSigmaEl, -1.5, 4.0, false, VarManager::kPin, 5.0, 1000.0); + pidCuts->AddCut(VarManager::kTPCnSigmaPi, 2.7, 999, false, VarManager::kPin, 0.0, 5.0); + pidCuts->AddCut(VarManager::kTPCnSigmaPi, 2.7, 999, false, VarManager::kPin, 5.0, 1000.0); + pidCuts->AddCut(VarManager::kTPCnSigmaPr, 3.0, 999, false, VarManager::kPin, 0.0, 5.0); + pidCuts->AddCut(VarManager::kTPCnSigmaPr, 2.7, 999, false, VarManager::kPin, 5.0, 1000.0); + + cut->AddCut(kineCut); + cut->AddCut(qualityCuts); + cut->AddCut(pidCuts); + return cut; + } + + if (nameStr == "LowMassElectron2023") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("LooseGlobalTrackRun3")); cut->AddCut(GetAnalysisCut("lmee_pp_502TeV_TOFloose_pionrej")); return cut; } - if (!nameStr.compare("MuonLow2022")) { + if (nameStr == "MuonLow2022") { cut->AddCut(GetAnalysisCut("muonLowPt2")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("MuonHigh2022")) { + if (nameStr == "MuonHigh2022") { cut->AddCut(GetAnalysisCut("muonHighPt2")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("MuonLow2023")) { + if (nameStr == "MuonLow2023") { cut->AddCut(GetAnalysisCut("muonLowPt2")); cut->AddCut(GetAnalysisCut("muonQualityCuts10SigmaPDCA")); cut->AddCut(GetAnalysisCut("MCHMID")); return cut; } - if (!nameStr.compare("MuonHigh2023")) { + if (nameStr == "MuonHigh2023") { cut->AddCut(GetAnalysisCut("muonHighPt6")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); cut->AddCut(GetAnalysisCut("MCHMID")); return cut; } - if (!nameStr.compare("ElectronForEMu")) { + if (nameStr == "ElectronForEMu") { cut->AddCut(GetAnalysisCut("jpsiKineSkimmed")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaLoose")); return cut; } - if (!nameStr.compare("MuonForEMu")) { + if (nameStr == "MuonForEMu") { cut->AddCut(GetAnalysisCut("muonLowPt5")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); cut->AddCut(GetAnalysisCut("MCHMID")); @@ -224,14 +252,14 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) // End of Cuts for CEFP // // /////////////////////////////////////////////// - if (!nameStr.compare("jpsiO2MCdebugCuts")) { + if (nameStr == "jpsiO2MCdebugCuts") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("electronPID1")); return cut; } - if (!nameStr.compare("jpsiBenchmarkCuts")) { + if (nameStr == "jpsiBenchmarkCuts") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityBenchmark")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); @@ -239,21 +267,21 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts2")) { + if (nameStr == "jpsiO2MCdebugCuts2") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("electronPIDnsigma")); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts2_Corr")) { + if (nameStr == "jpsiO2MCdebugCuts2_Corr") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug2")); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts2_prefiltered1")) { + if (nameStr == "jpsiO2MCdebugCuts2_prefiltered1") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("electronPIDnsigma")); @@ -261,47 +289,47 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts3")) { + if (nameStr == "jpsiO2MCdebugCuts3") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaMedium")); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts4")) { + if (nameStr == "jpsiO2MCdebugCuts4") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaLoose")); return cut; } - if (!nameStr.compare("electronSelection1_ionut")) { + if (nameStr == "electronSelection1_ionut") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaMedium")); return cut; } - if (!nameStr.compare("jpsiKineDcaQualitynoPID")) { + if (nameStr == "jpsiKineDcaQualitynoPID") { cut->AddCut(GetAnalysisCut("jpsiKineSkimmed")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); return cut; } - if (!nameStr.compare("jpsiKineDcaQualitynoPID2")) { + if (nameStr == "jpsiKineDcaQualitynoPID2") { cut->AddCut(GetAnalysisCut("jpsiKineSkimmed")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); return cut; } - if (!nameStr.compare("electronSelection1_ionut_withTOFPID")) { + if (nameStr == "electronSelection1_ionut_withTOFPID") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaMedium_withLargeTOFPID")); return cut; } - if (!nameStr.compare("electronSelection1_idstoreh")) { // same as electronSelection1_ionut, but with kIsSPDAny -> kIsITSibAny + if (nameStr == "electronSelection1_idstoreh") { // same as electronSelection1_ionut, but with kIsSPDAny -> kIsITSibAny cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); @@ -309,7 +337,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("electronSelection1pos_ionut")) { + if (nameStr == "electronSelection1pos_ionut") { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); @@ -317,7 +345,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) cut->AddCut(GetAnalysisCut("electronPIDnsigmaMedium")); return cut; } - if (!nameStr.compare("electronSelection1neg_ionut")) { + if (nameStr == "electronSelection1neg_ionut") { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); @@ -326,7 +354,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("electronSelection2_ionut")) { + if (nameStr == "electronSelection2_ionut") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); @@ -334,7 +362,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) cut->AddCut(GetAnalysisCut("insideTPCsector")); return cut; } - if (!nameStr.compare("electronSelection2pos_ionut")) { + if (nameStr == "electronSelection2pos_ionut") { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); @@ -343,7 +371,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) cut->AddCut(GetAnalysisCut("insideTPCsector")); return cut; } - if (!nameStr.compare("electronSelection2neg_ionut")) { + if (nameStr == "electronSelection2neg_ionut") { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); @@ -353,14 +381,14 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts4_Corr")) { + if (nameStr == "jpsiO2MCdebugCuts4_Corr") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug1")); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts5")) { + if (nameStr == "jpsiO2MCdebugCuts5") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaVeryLoose")); @@ -368,7 +396,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts6")) { + if (nameStr == "jpsiO2MCdebugCuts6") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaVeryVeryLoose")); @@ -376,7 +404,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts7")) { + if (nameStr == "jpsiO2MCdebugCuts7") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaOpen")); @@ -384,7 +412,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts7_Corr")) { + if (nameStr == "jpsiO2MCdebugCuts7_Corr") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug5")); @@ -392,7 +420,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts7_noCorr")) { + if (nameStr == "jpsiO2MCdebugCuts7_noCorr") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug5_noCorr")); @@ -400,7 +428,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts7_Corr_2")) { + if (nameStr == "jpsiO2MCdebugCuts7_Corr_2") { cut->AddCut(GetAnalysisCut("jpsiStandardKine2")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug5")); @@ -408,7 +436,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts7_Corr_3")) { + if (nameStr == "jpsiO2MCdebugCuts7_Corr_3") { cut->AddCut(GetAnalysisCut("jpsiStandardKine3")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug5")); @@ -416,28 +444,28 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts8")) { + if (nameStr == "jpsiO2MCdebugCuts8") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("electronPID1shiftUp")); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts9")) { + if (nameStr == "jpsiO2MCdebugCuts9") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("electronPID1shiftDown")); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts10_Corr")) { + if (nameStr == "jpsiO2MCdebugCuts10_Corr") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); // no cut on ITS clusters cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug2")); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts10_Corr_Amb")) { + if (nameStr == "jpsiO2MCdebugCuts10_Corr_Amb") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); // no cut on ITS clusters cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug2")); @@ -445,133 +473,133 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts11_Corr")) { + if (nameStr == "jpsiO2MCdebugCuts11_Corr") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug3")); // cut on 1 ITS cluster cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug2")); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts12")) { + if (nameStr == "jpsiO2MCdebugCuts12") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); // no cut on ITS clusters cut->AddCut(GetAnalysisCut("electronPIDnsigmaVeryLoose")); // with 3 sigma El TOF return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts_Pdependent_Corr")) { + if (nameStr == "jpsiO2MCdebugCuts_Pdependent_Corr") { cut->AddCut(GetAnalysisCut("jpsiStandardKine4")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("pidCut_lowP_Corr")); - AnalysisCompositeCut* pidCut_highP = new AnalysisCompositeCut("pidCut_highP", "pidCut_highP", kFALSE); + auto* pidCut_highP = new AnalysisCompositeCut("pidCut_highP", "pidCut_highP", kFALSE); pidCut_highP->AddCut(GetAnalysisCut("EleInclusion_highP_Corr")); pidCut_highP->AddCut(GetAnalysisCut("PionExclusion_highP_Corr")); cut->AddCut(pidCut_highP); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts_Pdependent")) { + if (nameStr == "jpsiO2MCdebugCuts_Pdependent") { cut->AddCut(GetAnalysisCut("jpsiStandardKine4")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("pidCut_lowP")); - AnalysisCompositeCut* pidCut_highP = new AnalysisCompositeCut("pidCut_highP", "pidCut_highP", kFALSE); + auto* pidCut_highP = new AnalysisCompositeCut("pidCut_highP", "pidCut_highP", kFALSE); pidCut_highP->AddCut(GetAnalysisCut("EleInclusion_highP")); pidCut_highP->AddCut(GetAnalysisCut("PionExclusion_highP")); cut->AddCut(pidCut_highP); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts_Pdependent2_Corr")) { + if (nameStr == "jpsiO2MCdebugCuts_Pdependent2_Corr") { cut->AddCut(GetAnalysisCut("jpsiStandardKine4")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("pidCut_lowP_Corr")); - AnalysisCompositeCut* pidCut_highP = new AnalysisCompositeCut("pidCut_highP", "pidCut_highP", kFALSE); + auto* pidCut_highP = new AnalysisCompositeCut("pidCut_highP", "pidCut_highP", kFALSE); pidCut_highP->AddCut(GetAnalysisCut("EleInclusion_highP2_Corr")); pidCut_highP->AddCut(GetAnalysisCut("PionExclusion_highP_Corr")); cut->AddCut(pidCut_highP); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts_Pdependent2")) { + if (nameStr == "jpsiO2MCdebugCuts_Pdependent2") { cut->AddCut(GetAnalysisCut("jpsiStandardKine4")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("pidCut_lowP")); - AnalysisCompositeCut* pidCut_highP = new AnalysisCompositeCut("pidCut_highP", "pidCut_highP", kFALSE); + auto* pidCut_highP = new AnalysisCompositeCut("pidCut_highP", "pidCut_highP", kFALSE); pidCut_highP->AddCut(GetAnalysisCut("EleInclusion_highP2")); pidCut_highP->AddCut(GetAnalysisCut("PionExclusion_highP")); cut->AddCut(pidCut_highP); return cut; } - if (!nameStr.compare("JpsiPWGSkimmedCuts1")) { // please do not remove or modify, this is used for the common Skimmed tree production, (Xiaozhi Bai) + if (nameStr == "JpsiPWGSkimmedCuts1") { // please do not remove or modify, this is used for the common Skimmed tree production, (Xiaozhi Bai) cut->AddCut(GetAnalysisCut("jpsiKineSkimmed")); cut->AddCut(GetAnalysisCut("electronTrackQualitySkimmed")); cut->AddCut(GetAnalysisCut("electronPIDLooseSkimmed")); return cut; } - if (!nameStr.compare("JpsiPWGSkimmedCuts1")) { // please do not remove or modify, this is used for the common Skimmed tree production, (Xiaozhi Bai) + if (nameStr == "JpsiPWGSkimmedCuts1") { // please do not remove or modify, this is used for the common Skimmed tree production, (Xiaozhi Bai) cut->AddCut(GetAnalysisCut("jpsiKineSkimmed")); cut->AddCut(GetAnalysisCut("electronTrackQualitySkimmed")); cut->AddCut(GetAnalysisCut("electronPIDLooseSkimmed")); return cut; } - if (!nameStr.compare("JpsiPWGSkimmedCuts2")) { + if (nameStr == "JpsiPWGSkimmedCuts2") { cut->AddCut(GetAnalysisCut("jpsiKineSkimmed")); cut->AddCut(GetAnalysisCut("electronTrackQualitySkimmed")); cut->AddCut(GetAnalysisCut("electronPIDLooseSkimmed2")); return cut; } - if (!nameStr.compare("JpsiPWGSkimmedCuts3")) { + if (nameStr == "JpsiPWGSkimmedCuts3") { cut->AddCut(GetAnalysisCut("jpsiKineSkimmed")); cut->AddCut(GetAnalysisCut("electronTrackQualitySkimmed2")); cut->AddCut(GetAnalysisCut("electronPIDLooseSkimmed2")); return cut; } - if (!nameStr.compare("JpsiPWGSkimmedCuts4")) { + if (nameStr == "JpsiPWGSkimmedCuts4") { cut->AddCut(GetAnalysisCut("jpsiKineSkimmed")); cut->AddCut(GetAnalysisCut("electronTrackQualitySkimmed2")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug9")); // loose cut return cut; } - if (!nameStr.compare("JpsiPWGSkimmedCuts5")) { + if (nameStr == "JpsiPWGSkimmedCuts5") { cut->AddCut(GetAnalysisCut("electronTrackQualitySkimmed3")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug8")); return cut; } - if (!nameStr.compare("pidElectron_ionut")) { + if (nameStr == "pidElectron_ionut") { cut->AddCut(GetAnalysisCut("pidcalib_ele")); cut->AddCut(GetAnalysisCut("jpsiStandardKine3")); return cut; } - if (!nameStr.compare("pidElectron_ionut_posEta")) { + if (nameStr == "pidElectron_ionut_posEta") { cut->AddCut(GetAnalysisCut("pidcalib_ele")); cut->AddCut(GetAnalysisCut("jpsiPIDcalibKine_posEta")); return cut; } - if (!nameStr.compare("pidElectron_ionut_negEta")) { + if (nameStr == "pidElectron_ionut_negEta") { cut->AddCut(GetAnalysisCut("pidcalib_ele")); cut->AddCut(GetAnalysisCut("jpsiPIDcalibKine_negEta")); return cut; } - if (!nameStr.compare("pidPion_ionut")) { + if (nameStr == "pidPion_ionut") { cut->AddCut(GetAnalysisCut("pidcalib_pion")); cut->AddCut(GetAnalysisCut("jpsiStandardKine3")); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts13_Corr")) { + if (nameStr == "jpsiO2MCdebugCuts13_Corr") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); // no cut on ITS clusters cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug2")); @@ -579,14 +607,14 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts14")) { + if (nameStr == "jpsiO2MCdebugCuts14") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaSkewed")); return cut; } - if (!nameStr.compare("jpsiO2MCdebugCuts14andDCA")) { + if (nameStr == "jpsiO2MCdebugCuts14andDCA") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaSkewed")); @@ -594,14 +622,14 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("emu_electronCuts")) { + if (nameStr == "emu_electronCuts") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaSkewed")); return cut; } - if (!nameStr.compare("emu_electronCuts_tof")) { + if (nameStr == "emu_electronCuts_tof") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaSkewed")); @@ -609,14 +637,14 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("emu_electronCuts_tightTPC")) { + if (nameStr == "emu_electronCuts_tightTPC") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaSkewed_2")); return cut; } - if (!nameStr.compare("emu_electronCuts_tof_tightTPC")) { + if (nameStr == "emu_electronCuts_tof_tightTPC") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaSkewed_2")); @@ -624,14 +652,14 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiKineAndQuality")) { + if (nameStr == "jpsiKineAndQuality") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQuality")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); return cut; } - if (!nameStr.compare("jpsiPID1")) { + if (nameStr == "jpsiPID1") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); // standard kine cuts usually are applied via Filter in the task cut->AddCut(GetAnalysisCut("electronStandardQuality")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); @@ -639,7 +667,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiPID2")) { + if (nameStr == "jpsiPID2") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQuality")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); @@ -647,7 +675,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiPIDnsigma")) { + if (nameStr == "jpsiPIDnsigma") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQuality")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); @@ -655,44 +683,44 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("pionPIDCut1")) { + if (nameStr == "pionPIDCut1") { cut->AddCut(GetAnalysisCut("pionQualityCut1")); cut->AddCut(GetAnalysisCut("pionPIDnsigma")); return cut; } - if (!nameStr.compare("pionPIDCut2")) { + if (nameStr == "pionPIDCut2") { cut->AddCut(GetAnalysisCut("pionQualityCut2")); cut->AddCut(GetAnalysisCut("pionPIDnsigma")); return cut; } - if (!nameStr.compare("PIDCalibElectron")) { + if (nameStr == "PIDCalibElectron") { cut->AddCut(GetAnalysisCut("pidcalib_ele")); return cut; } - if (!nameStr.compare("PIDCalibPion")) { + if (nameStr == "PIDCalibPion") { cut->AddCut(GetAnalysisCut("pidcalib_pion")); return cut; } - if (!nameStr.compare("PIDCalibKaon")) { + if (nameStr == "PIDCalibKaon") { cut->AddCut(GetAnalysisCut("pidcalib_kaon")); return cut; } - if (!nameStr.compare("PIDCalibProton")) { + if (nameStr == "PIDCalibProton") { cut->AddCut(GetAnalysisCut("pidcalib_proton")); return cut; } - if (!nameStr.compare("PIDCalib_basic")) { + if (nameStr == "PIDCalib_basic") { cut->AddCut(GetAnalysisCut("pidbasic")); return cut; } - if (!nameStr.compare("PIDefficiency_wPID")) { + if (nameStr == "PIDefficiency_wPID") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQuality")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); @@ -701,7 +729,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("PIDefficiency_woPID")) { + if (nameStr == "PIDefficiency_woPID") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQuality")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); @@ -709,34 +737,34 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("highPtHadron")) { + if (nameStr == "highPtHadron") { cut->AddCut(GetAnalysisCut("highPtHadron")); return cut; } - if (!nameStr.compare("rho0Cuts")) { + if (nameStr == "rho0Cuts") { cut->AddCut(GetAnalysisCut("rho0Kine")); cut->AddCut(GetAnalysisCut("pionQuality")); cut->AddCut(GetAnalysisCut("pionPIDnsigma")); return cut; } - if (!nameStr.compare("rho0Kine")) { + if (nameStr == "rho0Kine") { cut->AddCut(GetAnalysisCut("rho0Kine")); return cut; } - if (!nameStr.compare("openEtaSel")) { + if (nameStr == "openEtaSel") { cut->AddCut(GetAnalysisCut("openEtaSel")); return cut; } - if (!nameStr.compare("hasTOF")) { + if (nameStr == "hasTOF") { cut->AddCut(GetAnalysisCut("hasTOF")); return cut; } - if (!nameStr.compare("singleGapTrackCuts1")) { + if (nameStr == "singleGapTrackCuts1") { cut->AddCut(GetAnalysisCut("muonLowPt")); cut->AddCut(GetAnalysisCut("SPDany")); cut->AddCut(GetAnalysisCut("openEtaSel")); @@ -744,7 +772,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("singleGapTrackCuts2")) { + if (nameStr == "singleGapTrackCuts2") { cut->AddCut(GetAnalysisCut("muonLowPt3")); cut->AddCut(GetAnalysisCut("ITSiball")); cut->AddCut(GetAnalysisCut("openEtaSel")); @@ -752,41 +780,41 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("singleGapTrackCuts3")) { + if (nameStr == "singleGapTrackCuts3") { cut->AddCut(GetAnalysisCut("PIDStandardKine2")); cut->AddCut(GetAnalysisCut("SPDany")); - AnalysisCompositeCut* cut_notpc = new AnalysisCompositeCut("NoTPC", "NoTPC", kTRUE); + auto* cut_notpc = new AnalysisCompositeCut("NoTPC", "NoTPC", kTRUE); cut_notpc->AddCut(GetAnalysisCut("noTPC")); - AnalysisCompositeCut* cut_tpcpid = new AnalysisCompositeCut("pid_TPC", "pid_TPC", kTRUE); + auto* cut_tpcpid = new AnalysisCompositeCut("pid_TPC", "pid_TPC", kTRUE); cut_tpcpid->AddCut(GetAnalysisCut("pionQuality")); - AnalysisCompositeCut* cut_OR = new AnalysisCompositeCut("OR", "OR", kFALSE); + auto* cut_OR = new AnalysisCompositeCut("OR", "OR", kFALSE); cut_OR->AddCut(cut_notpc); cut_OR->AddCut(cut_tpcpid); cut->AddCut(cut_OR); return cut; } - if (!nameStr.compare("singleGapTrackCuts4")) { + if (nameStr == "singleGapTrackCuts4") { cut->AddCut(GetAnalysisCut("PIDStandardKine2")); cut->AddCut(GetAnalysisCut("ITSibany")); - AnalysisCompositeCut* cut_notpc = new AnalysisCompositeCut("NoTPC", "NoTPC", kTRUE); + auto* cut_notpc = new AnalysisCompositeCut("NoTPC", "NoTPC", kTRUE); cut_notpc->AddCut(GetAnalysisCut("noTPC")); - AnalysisCompositeCut* cut_tpcpid = new AnalysisCompositeCut("pid_TPC", "pid_TPC", kTRUE); + auto* cut_tpcpid = new AnalysisCompositeCut("pid_TPC", "pid_TPC", kTRUE); cut_tpcpid->AddCut(GetAnalysisCut("pionQuality")); - AnalysisCompositeCut* cut_OR = new AnalysisCompositeCut("OR", "OR", kFALSE); + auto* cut_OR = new AnalysisCompositeCut("OR", "OR", kFALSE); cut_OR->AddCut(cut_notpc); cut_OR->AddCut(cut_tpcpid); cut->AddCut(cut_OR); return cut; } - if (!nameStr.compare("PIDCalib")) { + if (nameStr == "PIDCalib") { cut->AddCut(GetAnalysisCut("PIDStandardKine")); // standard kine cuts usually are applied via Filter in the task cut->AddCut(GetAnalysisCut("electronStandardQuality")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); @@ -794,50 +822,50 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("NoPID")) { + if (nameStr == "NoPID") { cut->AddCut(GetAnalysisCut("PIDStandardKine2")); // standard kine cuts usually are applied via Filter in the task cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly2")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); return cut; } - if (!nameStr.compare("KineCutOnly")) { + if (nameStr == "KineCutOnly") { cut->AddCut(GetAnalysisCut("PIDStandardKine")); // standard kine cuts usually are applied via Filter in the task return cut; } - if (!nameStr.compare("KineCutOnly2")) { + if (nameStr == "KineCutOnly2") { cut->AddCut(GetAnalysisCut("PIDStandardKine2")); // standard kine cuts usually are applied via Filter in the task return cut; } - if (!nameStr.compare("KineCutOnly3")) { + if (nameStr == "KineCutOnly3") { cut->AddCut(GetAnalysisCut("PIDStandardKine3")); // standard kine cuts usually are applied via Filter in the task return cut; } - if (!nameStr.compare("kaonPID")) { + if (nameStr == "kaonPID") { cut->AddCut(GetAnalysisCut("PIDStandardKine")); // standard kine cuts usually are applied via Filter in the task cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("kaonPIDnsigma")); return cut; } - if (!nameStr.compare("kaonPID2")) { + if (nameStr == "kaonPID2") { cut->AddCut(GetAnalysisCut("PIDStandardKine")); // standard kine cuts usually are applied via Filter in the task cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("kaonPIDnsigma2")); return cut; } - if (!nameStr.compare("kaonPID3")) { + if (nameStr == "kaonPID3") { cut->AddCut(GetAnalysisCut("AssocKine")); // standard kine cuts usually are applied via Filter in the task cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("kaonPID_TPCnTOF")); return cut; } - if (!nameStr.compare("kaonPID3_withDCA")) { // same as kaonPID3 but with cut on DCA and SPDAny->ITSAny + if (nameStr == "kaonPID3_withDCA") { // same as kaonPID3 but with cut on DCA and SPDAny->ITSAny cut->AddCut(GetAnalysisCut("AssocKine")); // standard kine cuts usually are applied via Filter in the task cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); @@ -845,344 +873,344 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("kaonPID4")) { + if (nameStr == "kaonPID4") { cut->AddCut(GetAnalysisCut("kaonPID_TPCnTOF")); return cut; } - if (!nameStr.compare("kaonPID5")) { + if (nameStr == "kaonPID5") { cut->AddCut(GetAnalysisCut("kaonPIDnsigma")); return cut; } - if (!nameStr.compare("kaonPID6")) { + if (nameStr == "kaonPID6") { cut->AddCut(GetAnalysisCut("kaonPIDnsigma700")); return cut; } - if (!nameStr.compare("kaonPIDTPCTOForTPC")) { - AnalysisCompositeCut* cut_tpctof_nSigma = new AnalysisCompositeCut("pid_TPCTOFnSigma", "pid_TPCTOFnSigma", kTRUE); + if (nameStr == "kaonPIDTPCTOForTPC") { + auto* cut_tpctof_nSigma = new AnalysisCompositeCut("pid_TPCTOFnSigma", "pid_TPCTOFnSigma", kTRUE); cut_tpctof_nSigma->AddCut(GetAnalysisCut("hasTOF")); cut_tpctof_nSigma->AddCut(GetAnalysisCut("kaonPID_TPCnTOF")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut("noTOF")); cut_tpc_nSigma->AddCut(GetAnalysisCut("kaonPIDnsigma")); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("kaon_nsigma", "kaon_nsigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("kaon_nsigma", "kaon_nsigma", kFALSE); cut_pid_OR->AddCut(cut_tpctof_nSigma); cut_pid_OR->AddCut(cut_tpc_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare("kaonPIDTPCTOForTPC700")) { - AnalysisCompositeCut* cut_tpctof_nSigma = new AnalysisCompositeCut("pid_TPCTOFnSigma", "pid_TPCTOFnSigma", kTRUE); + if (nameStr == "kaonPIDTPCTOForTPC700") { + auto* cut_tpctof_nSigma = new AnalysisCompositeCut("pid_TPCTOFnSigma", "pid_TPCTOFnSigma", kTRUE); cut_tpctof_nSigma->AddCut(GetAnalysisCut("hasTOF")); cut_tpctof_nSigma->AddCut(GetAnalysisCut("kaonPID_TPCnTOF")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut("noTOF")); cut_tpc_nSigma->AddCut(GetAnalysisCut("kaonPIDnsigma700")); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("kaon_nsigma", "kaon_nsigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("kaon_nsigma", "kaon_nsigma", kFALSE); cut_pid_OR->AddCut(cut_tpctof_nSigma); cut_pid_OR->AddCut(cut_tpc_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare("kaonPosPID4")) { + if (nameStr == "kaonPosPID4") { cut->AddCut(GetAnalysisCut("kaonPID_TPCnTOF")); cut->AddCut(GetAnalysisCut("posTrack")); return cut; } - if (!nameStr.compare("kaonPosPID4Pt05")) { + if (nameStr == "kaonPosPID4Pt05") { cut->AddCut(GetAnalysisCut("kaonPID_TPCnTOF")); cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("muonLowPt")); return cut; } - if (!nameStr.compare("kaonNegPID4")) { + if (nameStr == "kaonNegPID4") { cut->AddCut(GetAnalysisCut("kaonPID_TPCnTOF")); cut->AddCut(GetAnalysisCut("negTrack")); return cut; } - if (!nameStr.compare("kaonNegPID4Pt05")) { + if (nameStr == "kaonNegPID4Pt05") { cut->AddCut(GetAnalysisCut("kaonPID_TPCnTOF")); cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("muonLowPt")); return cut; } - if (!nameStr.compare("pionPID")) { + if (nameStr == "pionPID") { cut->AddCut(GetAnalysisCut("pionPID_TPCnTOF")); return cut; } - if (!nameStr.compare("pionPID2")) { + if (nameStr == "pionPID2") { cut->AddCut(GetAnalysisCut("pionPIDnsigma")); return cut; } - if (!nameStr.compare("pionPIDTPCTOForTPC")) { - AnalysisCompositeCut* cut_tpctof_nSigma = new AnalysisCompositeCut("pid_TPCTOFnSigma", "pid_TPCTOFnSigma", kTRUE); + if (nameStr == "pionPIDTPCTOForTPC") { + auto* cut_tpctof_nSigma = new AnalysisCompositeCut("pid_TPCTOFnSigma", "pid_TPCTOFnSigma", kTRUE); cut_tpctof_nSigma->AddCut(GetAnalysisCut("pionPID_TPCnTOF")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut("pionPIDnsigma")); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("pion_nsigma", "pion_nsigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("pion_nsigma", "pion_nsigma", kFALSE); cut_pid_OR->AddCut(cut_tpctof_nSigma); cut_pid_OR->AddCut(cut_tpc_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare("pionPosPID")) { + if (nameStr == "pionPosPID") { cut->AddCut(GetAnalysisCut("pionPID_TPCnTOF")); cut->AddCut(GetAnalysisCut("posTrack")); return cut; } - if (!nameStr.compare("pionPosPID2")) { + if (nameStr == "pionPosPID2") { cut->AddCut(GetAnalysisCut("pionPIDnsigma")); cut->AddCut(GetAnalysisCut("posTrack")); return cut; } - if (!nameStr.compare("pionNegPID")) { + if (nameStr == "pionNegPID") { cut->AddCut(GetAnalysisCut("pionPID_TPCnTOF")); cut->AddCut(GetAnalysisCut("negTrack")); return cut; } - if (!nameStr.compare("pionNegPID2")) { + if (nameStr == "pionNegPID2") { cut->AddCut(GetAnalysisCut("pionPIDnsigma")); cut->AddCut(GetAnalysisCut("negTrack")); return cut; } - if (!nameStr.compare("protonPosPID")) { + if (nameStr == "protonPosPID") { cut->AddCut(GetAnalysisCut("protonPID_TPCnTOF")); cut->AddCut(GetAnalysisCut("posTrack")); return cut; } - if (!nameStr.compare("protonPosPIDPt05")) { + if (nameStr == "protonPosPIDPt05") { cut->AddCut(GetAnalysisCut("protonPID_TPCnTOF")); cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("muonLowPt")); return cut; } - if (!nameStr.compare("protonNegPID")) { + if (nameStr == "protonNegPID") { cut->AddCut(GetAnalysisCut("protonPID_TPCnTOF")); cut->AddCut(GetAnalysisCut("negTrack")); return cut; } - if (!nameStr.compare("protonNegPIDPt05")) { + if (nameStr == "protonNegPIDPt05") { cut->AddCut(GetAnalysisCut("protonPID_TPCnTOF")); cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("muonLowPt")); return cut; } - if (!nameStr.compare("protonPIDPV")) { + if (nameStr == "protonPIDPV") { cut->AddCut(GetAnalysisCut("protonPID_TPCnTOF2")); cut->AddCut(GetAnalysisCut("protonPVcut")); return cut; } - if (!nameStr.compare("protonPIDPV2")) { + if (nameStr == "protonPIDPV2") { cut->AddCut(GetAnalysisCut("protonPID_TPCnTOF2")); return cut; } - if (!nameStr.compare("PrimaryTrack_DCAz")) { + if (nameStr == "PrimaryTrack_DCAz") { cut->AddCut(GetAnalysisCut("PrimaryTrack_DCAz")); return cut; } - if (!nameStr.compare("posPrimaryTrack_DCAz")) { + if (nameStr == "posPrimaryTrack_DCAz") { cut->AddCut(GetAnalysisCut("PrimaryTrack_DCAz")); cut->AddCut(GetAnalysisCut("posTrack")); return cut; } - if (!nameStr.compare("negPrimaryTrack_DCAz")) { + if (nameStr == "negPrimaryTrack_DCAz") { cut->AddCut(GetAnalysisCut("PrimaryTrack_DCAz")); cut->AddCut(GetAnalysisCut("negTrack")); return cut; } - if (!nameStr.compare("posStandardPrimaryTrackDCA")) { + if (nameStr == "posStandardPrimaryTrackDCA") { cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCA")); cut->AddCut(GetAnalysisCut("posTrack")); return cut; } - if (!nameStr.compare("negStandardPrimaryTrackDCA")) { + if (nameStr == "negStandardPrimaryTrackDCA") { cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCA")); cut->AddCut(GetAnalysisCut("negTrack")); return cut; } - if (!nameStr.compare("posTrack")) { + if (nameStr == "posTrack") { cut->AddCut(GetAnalysisCut("posTrack")); return cut; } - if (!nameStr.compare("negTrack")) { + if (nameStr == "negTrack") { cut->AddCut(GetAnalysisCut("negTrack")); return cut; } - if (!nameStr.compare("posTrackKaonRej")) { + if (nameStr == "posTrackKaonRej") { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("kaonRejNsigma")); return cut; } - if (!nameStr.compare("negTrackKaonRej")) { + if (nameStr == "negTrackKaonRej") { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("kaonRejNsigma")); return cut; } - if (!nameStr.compare("pTLow05")) { + if (nameStr == "pTLow05") { cut->AddCut(GetAnalysisCut("muonLowPt")); return cut; } - if (!nameStr.compare("pTLow04")) { + if (nameStr == "pTLow04") { cut->AddCut(GetAnalysisCut("pTLow04")); return cut; } - if (!nameStr.compare("pTLow03")) { + if (nameStr == "pTLow03") { cut->AddCut(GetAnalysisCut("pTLow03")); return cut; } - if (!nameStr.compare("pTLow02")) { + if (nameStr == "pTLow02") { cut->AddCut(GetAnalysisCut("pTLow02")); return cut; } - if (!nameStr.compare("pTLow05DCAzHigh03")) { + if (nameStr == "pTLow05DCAzHigh03") { cut->AddCut(GetAnalysisCut("muonLowPt")); cut->AddCut(GetAnalysisCut("PrimaryTrack_DCAz")); return cut; } - if (!nameStr.compare("pTLow04DCAzHigh03")) { + if (nameStr == "pTLow04DCAzHigh03") { cut->AddCut(GetAnalysisCut("pTLow04")); cut->AddCut(GetAnalysisCut("PrimaryTrack_DCAz")); return cut; } - if (!nameStr.compare("pTLow03DCAzHigh03")) { + if (nameStr == "pTLow03DCAzHigh03") { cut->AddCut(GetAnalysisCut("pTLow03")); cut->AddCut(GetAnalysisCut("PrimaryTrack_DCAz")); return cut; } // NOTE Below there are several TPC pid cuts used for studies of the Run3 TPC post PID calib. - if (!nameStr.compare("Jpsi_TPCPost_calib_debug1")) { + if (nameStr == "Jpsi_TPCPost_calib_debug1") { cut->AddCut(GetAnalysisCut("jpsi_trackCut_debug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug1")); return cut; } - if (!nameStr.compare("Jpsi_TPCPost_calib_debug2")) { + if (nameStr == "Jpsi_TPCPost_calib_debug2") { cut->AddCut(GetAnalysisCut("jpsi_trackCut_debug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug2")); return cut; } - if (!nameStr.compare("Jpsi_TPCPost_calib_noITSCuts_debug2")) { + if (nameStr == "Jpsi_TPCPost_calib_noITSCuts_debug2") { cut->AddCut(GetAnalysisCut("jpsi_trackCut_noITSCuts_debug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug2")); return cut; } - if (!nameStr.compare("Jpsi_TPCPost_calib_debug3")) { + if (nameStr == "Jpsi_TPCPost_calib_debug3") { cut->AddCut(GetAnalysisCut("jpsi_trackCut_debug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug3")); return cut; } - if (!nameStr.compare("Jpsi_TPCPost_calib_debug4")) { + if (nameStr == "Jpsi_TPCPost_calib_debug4") { cut->AddCut(GetAnalysisCut("jpsi_trackCut_debug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug4")); return cut; } - if (!nameStr.compare("Jpsi_TPCPost_calib_noITSCuts_debug4")) { + if (nameStr == "Jpsi_TPCPost_calib_noITSCuts_debug4") { cut->AddCut(GetAnalysisCut("jpsi_trackCut_noITSCuts_debug")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug4")); return cut; } - if (!nameStr.compare("Jpsi_TPCPost_calib_debug6")) { + if (nameStr == "Jpsi_TPCPost_calib_debug6") { cut->AddCut(GetAnalysisCut("jpsi_trackCut_debug2")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug6")); return cut; } - if (!nameStr.compare("Jpsi_TPCPost_calib_debug7")) { + if (nameStr == "Jpsi_TPCPost_calib_debug7") { cut->AddCut(GetAnalysisCut("jpsi_trackCut_debug2")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug7")); return cut; } - if (!nameStr.compare("Jpsi_TPCPost_calib_debug8")) { + if (nameStr == "Jpsi_TPCPost_calib_debug8") { cut->AddCut(GetAnalysisCut("jpsi_trackCut_debug5")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug8")); return cut; } - if (!nameStr.compare("Jpsi_TPCPost_calib_debug9")) { + if (nameStr == "Jpsi_TPCPost_calib_debug9") { cut->AddCut(GetAnalysisCut("jpsi_trackCut_debug4")); cut->AddCut(GetAnalysisCut("electronPIDLooseSkimmed3")); return cut; } - if (!nameStr.compare("Jpsi_TPCPost_calib_debug10")) { + if (nameStr == "Jpsi_TPCPost_calib_debug10") { cut->AddCut(GetAnalysisCut("jpsiKineSkimmed")); cut->AddCut(GetAnalysisCut("jpsi_trackCut_debug6")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug10")); return cut; } - if (!nameStr.compare("LMee_TPCPost_calib_debug1")) { + if (nameStr == "LMee_TPCPost_calib_debug1") { cut->AddCut(GetAnalysisCut("lmee_trackCut_debug")); cut->AddCut(GetAnalysisCut("lmee_TPCPID_debug1")); return cut; } - if (!nameStr.compare("ITSalone_prefilter")) { + if (nameStr == "ITSalone_prefilter") { cut->AddCut(GetAnalysisCut("lmeePrefilterKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); return cut; } - if (!nameStr.compare("ITSalonebAny_prefilter")) { + if (nameStr == "ITSalonebAny_prefilter") { cut->AddCut(GetAnalysisCut("lmeePrefilterKine")); cut->AddCut(GetAnalysisCut("electronStandardQualitybAnyITSOnly")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); return cut; } - if (!nameStr.compare("TPCalone_prefilter")) { + if (nameStr == "TPCalone_prefilter") { cut->AddCut(GetAnalysisCut("lmeePrefilterKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); return cut; } - if (!nameStr.compare("ITSTPC_prefilter")) { + if (nameStr == "ITSTPC_prefilter") { cut->AddCut(GetAnalysisCut("lmeePrefilterKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); @@ -1191,7 +1219,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } for (int iCut = 0; iCut < 10; iCut++) { // o2-linter: disable=magic-number (number of cuts) - if (!nameStr.compare(Form("jpsiEleSel%d_ionut", iCut))) { + if (nameStr == Form("jpsiEleSel%d_ionut", iCut)) { cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("trackQuality_ionut")); @@ -1199,7 +1227,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("jpsiEleSelTight%d_ionut", iCut))) { + if (nameStr == Form("jpsiEleSelTight%d_ionut", iCut)) { cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("trackQualityTight_ionut")); @@ -1210,11 +1238,11 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) // Magnus composite cuts ----------------------------------------------------------------------------------------------------------------- - AnalysisCompositeCut* magnus_PID111 = new AnalysisCompositeCut("magnus_PID111", ""); + auto* magnus_PID111 = new AnalysisCompositeCut("magnus_PID111", ""); magnus_PID111->AddCut(GetAnalysisCut("pidJpsi_magnus_ele1")); magnus_PID111->AddCut(GetAnalysisCut("pidJpsi_magnus_pion1")); magnus_PID111->AddCut(GetAnalysisCut("pidJpsi_magnus_prot1")); - if (!nameStr.compare("MagnussOptimization111")) { + if (nameStr == "MagnussOptimization111") { cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("trackQuality_ionut")); @@ -1222,11 +1250,11 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - AnalysisCompositeCut* magnus_PID211 = new AnalysisCompositeCut("magnus_PID211", ""); + auto* magnus_PID211 = new AnalysisCompositeCut("magnus_PID211", ""); magnus_PID211->AddCut(GetAnalysisCut("pidJpsi_magnus_ele2")); magnus_PID211->AddCut(GetAnalysisCut("pidJpsi_magnus_pion1")); magnus_PID211->AddCut(GetAnalysisCut("pidJpsi_magnus_prot1")); - if (!nameStr.compare("MagnussOptimization211")) { + if (nameStr == "MagnussOptimization211") { cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("trackQuality_ionut")); @@ -1234,11 +1262,11 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - AnalysisCompositeCut* magnus_PID311 = new AnalysisCompositeCut("magnus_PID311", ""); + auto* magnus_PID311 = new AnalysisCompositeCut("magnus_PID311", ""); magnus_PID311->AddCut(GetAnalysisCut("pidJpsi_magnus_ele3")); magnus_PID311->AddCut(GetAnalysisCut("pidJpsi_magnus_pion1")); magnus_PID311->AddCut(GetAnalysisCut("pidJpsi_magnus_prot1")); - if (!nameStr.compare("MagnussOptimization311")) { + if (nameStr == "MagnussOptimization311") { cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("trackQuality_ionut")); @@ -1246,11 +1274,11 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - AnalysisCompositeCut* magnus_PID121 = new AnalysisCompositeCut("magnus_PID121", ""); + auto* magnus_PID121 = new AnalysisCompositeCut("magnus_PID121", ""); magnus_PID121->AddCut(GetAnalysisCut("pidJpsi_magnus_ele1")); magnus_PID121->AddCut(GetAnalysisCut("pidJpsi_magnus_pion2")); magnus_PID121->AddCut(GetAnalysisCut("pidJpsi_magnus_prot1")); - if (!nameStr.compare("MagnussOptimization121")) { + if (nameStr == "MagnussOptimization121") { cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("trackQuality_ionut")); @@ -1258,11 +1286,11 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - AnalysisCompositeCut* magnus_PID112 = new AnalysisCompositeCut("magnus_PID112", ""); + auto* magnus_PID112 = new AnalysisCompositeCut("magnus_PID112", ""); magnus_PID112->AddCut(GetAnalysisCut("pidJpsi_magnus_ele1")); magnus_PID112->AddCut(GetAnalysisCut("pidJpsi_magnus_pion1")); magnus_PID112->AddCut(GetAnalysisCut("pidJpsi_magnus_prot2")); - if (!nameStr.compare("MagnussOptimization112")) { + if (nameStr == "MagnussOptimization112") { cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("trackQuality_ionut")); @@ -1270,11 +1298,11 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - AnalysisCompositeCut* magnus_PID122 = new AnalysisCompositeCut("magnus_PID122", ""); + auto* magnus_PID122 = new AnalysisCompositeCut("magnus_PID122", ""); magnus_PID122->AddCut(GetAnalysisCut("pidJpsi_magnus_ele1")); magnus_PID122->AddCut(GetAnalysisCut("pidJpsi_magnus_pion2")); magnus_PID122->AddCut(GetAnalysisCut("pidJpsi_magnus_prot2")); - if (!nameStr.compare("MagnussOptimization122")) { + if (nameStr == "MagnussOptimization122") { cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("trackQuality_ionut")); @@ -1282,11 +1310,11 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - AnalysisCompositeCut* magnus_PID222 = new AnalysisCompositeCut("magnus_PID222", ""); + auto* magnus_PID222 = new AnalysisCompositeCut("magnus_PID222", ""); magnus_PID222->AddCut(GetAnalysisCut("pidJpsi_magnus_ele2")); magnus_PID222->AddCut(GetAnalysisCut("pidJpsi_magnus_pion2")); magnus_PID222->AddCut(GetAnalysisCut("pidJpsi_magnus_prot2")); - if (!nameStr.compare("MagnussOptimization222")) { + if (nameStr == "MagnussOptimization222") { cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("trackQuality_ionut")); @@ -1294,11 +1322,11 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - AnalysisCompositeCut* magnus_PID212 = new AnalysisCompositeCut("magnus_PID212", ""); + auto* magnus_PID212 = new AnalysisCompositeCut("magnus_PID212", ""); magnus_PID212->AddCut(GetAnalysisCut("pidJpsi_magnus_ele2")); magnus_PID212->AddCut(GetAnalysisCut("pidJpsi_magnus_pion1")); magnus_PID212->AddCut(GetAnalysisCut("pidJpsi_magnus_prot2")); - if (!nameStr.compare("MagnussOptimization212")) { + if (nameStr == "MagnussOptimization212") { cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("trackQuality_ionut")); @@ -1306,11 +1334,11 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - AnalysisCompositeCut* magnus_PID221 = new AnalysisCompositeCut("magnus_PID221", ""); + auto* magnus_PID221 = new AnalysisCompositeCut("magnus_PID221", ""); magnus_PID221->AddCut(GetAnalysisCut("pidJpsi_magnus_ele2")); magnus_PID221->AddCut(GetAnalysisCut("pidJpsi_magnus_pion2")); magnus_PID221->AddCut(GetAnalysisCut("pidJpsi_magnus_prot1")); - if (!nameStr.compare("MagnussOptimization221")) { + if (nameStr == "MagnussOptimization221") { cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("trackQuality_ionut")); @@ -1318,11 +1346,11 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - AnalysisCompositeCut* magnus_PID321 = new AnalysisCompositeCut("magnus_PID321", ""); + auto* magnus_PID321 = new AnalysisCompositeCut("magnus_PID321", ""); magnus_PID321->AddCut(GetAnalysisCut("pidJpsi_magnus_ele3")); magnus_PID321->AddCut(GetAnalysisCut("pidJpsi_magnus_pion2")); magnus_PID321->AddCut(GetAnalysisCut("pidJpsi_magnus_prot1")); - if (!nameStr.compare("MagnussOptimization321")) { + if (nameStr == "MagnussOptimization321") { cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("trackQuality_ionut")); @@ -1330,11 +1358,11 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - AnalysisCompositeCut* magnus_PID312 = new AnalysisCompositeCut("magnus_PID312", ""); + auto* magnus_PID312 = new AnalysisCompositeCut("magnus_PID312", ""); magnus_PID312->AddCut(GetAnalysisCut("pidJpsi_magnus_ele3")); magnus_PID312->AddCut(GetAnalysisCut("pidJpsi_magnus_pion1")); magnus_PID312->AddCut(GetAnalysisCut("pidJpsi_magnus_prot2")); - if (!nameStr.compare("MagnussOptimization312")) { + if (nameStr == "MagnussOptimization312") { cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("trackQuality_ionut")); @@ -1342,11 +1370,11 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - AnalysisCompositeCut* magnus_PID322 = new AnalysisCompositeCut("magnus_PID322", ""); + auto* magnus_PID322 = new AnalysisCompositeCut("magnus_PID322", ""); magnus_PID322->AddCut(GetAnalysisCut("pidJpsi_magnus_ele1")); magnus_PID322->AddCut(GetAnalysisCut("pidJpsi_magnus_pion2")); magnus_PID322->AddCut(GetAnalysisCut("pidJpsi_magnus_prot2")); - if (!nameStr.compare("MagnussOptimization322")) { + if (nameStr == "MagnussOptimization322") { cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut")); cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); cut->AddCut(GetAnalysisCut("trackQuality_ionut")); @@ -1358,7 +1386,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) //--------------------------------------------------------------- // Cuts for the selection of legs from dalitz decay // - if (!nameStr.compare("DalitzCut1")) { + if (nameStr == "DalitzCut1") { cut->AddCut(GetAnalysisCut("dalitzStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); @@ -1366,7 +1394,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("DalitzCut2")) { + if (nameStr == "DalitzCut2") { cut->AddCut(GetAnalysisCut("dalitzStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); @@ -1374,7 +1402,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("DalitzCut2_Corr")) { + if (nameStr == "DalitzCut2_Corr") { cut->AddCut(GetAnalysisCut("dalitzStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); @@ -1382,7 +1410,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("DalitzCut3")) { + if (nameStr == "DalitzCut3") { cut->AddCut(GetAnalysisCut("dalitzStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); @@ -1390,7 +1418,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("DalitzCut3_Corr")) { + if (nameStr == "DalitzCut3_Corr") { cut->AddCut(GetAnalysisCut("dalitzStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); @@ -1398,7 +1426,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("DalitzCut1SPDfirst")) { + if (nameStr == "DalitzCut1SPDfirst") { cut->AddCut(GetAnalysisCut("dalitzStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); @@ -1407,7 +1435,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("DalitzCut1SPDfirst_Corr")) { + if (nameStr == "DalitzCut1SPDfirst_Corr") { cut->AddCut(GetAnalysisCut("dalitzStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); @@ -1416,7 +1444,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("DalitzCut2SPDfirst")) { + if (nameStr == "DalitzCut2SPDfirst") { cut->AddCut(GetAnalysisCut("dalitzStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); @@ -1425,7 +1453,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("DalitzCut2SPDfirst_Corr")) { + if (nameStr == "DalitzCut2SPDfirst_Corr") { cut->AddCut(GetAnalysisCut("dalitzStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); @@ -1434,7 +1462,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("DalitzCut3SPDfirst")) { + if (nameStr == "DalitzCut3SPDfirst") { cut->AddCut(GetAnalysisCut("dalitzStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); @@ -1443,7 +1471,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("DalitzCut3SPDfirst_Corr")) { + if (nameStr == "DalitzCut3SPDfirst_Corr") { cut->AddCut(GetAnalysisCut("dalitzStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); @@ -1452,38 +1480,38 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("Dalitz_WithTOF_SPDfirst")) { + if (nameStr == "Dalitz_WithTOF_SPDfirst") { cut->AddCut(GetAnalysisCut("dalitzStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); cut->AddCut(GetAnalysisCut("SPDfirst")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut("electronPIDPrKaPiRejLoose")); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut("electronPID_TOFnsigma")); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare("Dalitz_WithTOF_SPDfirst_Corr")) { + if (nameStr == "Dalitz_WithTOF_SPDfirst_Corr") { cut->AddCut(GetAnalysisCut("dalitzStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); cut->AddCut(GetAnalysisCut("SPDfirst")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut("electronPIDPrKaPiRejLoose_Corr")); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut("electronPID_TOFnsigma_Corr")); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); @@ -1491,13 +1519,13 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } for (int i = 1; i <= 8; i++) { // o2-linter: disable=magic-number (number of cuts) - if (!nameStr.compare(Form("dalitzSelected%d", i))) { + if (nameStr == Form("dalitzSelected%d", i)) { cut->AddCut(GetAnalysisCut(Form("dalitzLeg%d", i))); return cut; } } - if (!nameStr.compare("electronPrimaryTag0")) { + if (nameStr == "electronPrimaryTag0") { // with tight 3 sigma DCA cut for selecting primary electrons cut->AddCut(GetAnalysisCut("electronPID_TPCnsigma_loose")); // 3 sigma inclusion, 3sigma rejection cut->AddCut(GetAnalysisCut("electronPrimary_dca3sigma")); @@ -1505,7 +1533,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("electronPrimaryTag1")) { + if (nameStr == "electronPrimaryTag1") { // with 7 sigma DCA cut for selecting primary electrons cut->AddCut(GetAnalysisCut("electronPID_TPCnsigma_loose")); // 3 sigma inclusion, 3sigma rejection cut->AddCut(GetAnalysisCut("electronPrimary_dca7sigma")); @@ -1513,20 +1541,20 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("electronPrimaryProbe_TPC")) { + if (nameStr == "electronPrimaryProbe_TPC") { cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); cut->AddCut(GetAnalysisCut("lmeeStandardKine")); return cut; } - if (!nameStr.compare("electronPrimaryProbe_ITS")) { + if (nameStr == "electronPrimaryProbe_ITS") { cut->AddCut(GetAnalysisCut("electronStandardQualitybAnyITSOnly")); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCA")); cut->AddCut(GetAnalysisCut("lmeeStandardKine")); return cut; } - if (!nameStr.compare("electronPrimaryProbe_ITSTPC")) { + if (nameStr == "electronPrimaryProbe_ITSTPC") { cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualitybAnyITSOnly")); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCA")); @@ -1534,7 +1562,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiPIDworseRes")) { + if (nameStr == "jpsiPIDworseRes") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQuality")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); @@ -1542,7 +1570,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiPIDshift")) { + if (nameStr == "jpsiPIDshift") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQuality")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); @@ -1550,7 +1578,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiPID1shiftUp")) { + if (nameStr == "jpsiPID1shiftUp") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQuality")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); @@ -1558,54 +1586,82 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsiPID1shiftDown")) { + if (nameStr == "jpsiPID1shiftDown") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQuality")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); cut->AddCut(GetAnalysisCut("electronPID1shiftDown")); return cut; } + // ------------------------------------------------------------------------------------------------- + // + // Q vector contributor cut + // + if (nameStr == "selTPCCentral") { + auto* kineCut = new AnalysisCut("kineCut", "kine cut"); + kineCut->AddCut(VarManager::kEta, -0.8, 0.8); + kineCut->AddCut(VarManager::kPt, 0.15, 5); + + auto* qualityCuts = new AnalysisCut("qualityCuts", "quality cuts"); + qualityCuts->AddCut(VarManager::kTPCchi2, 0., 4.); + qualityCuts->AddCut(VarManager::kTPCnCRoverFindCls, 0.8, 1.); + qualityCuts->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); + qualityCuts->AddCut(VarManager::kITSchi2, 0., 36.); + + auto* dcaCuts = new AnalysisCut("dcaCuts", "DCA cuts"); + std::shared_ptr f1dcaxyHigh = std::make_shared("f1dcaxy", "[0]+[1]/pow(x,[2])", 0., 10.); + f1dcaxyHigh->SetParameters(0.0105, 0.035, 1.1); + std::shared_ptr f1dcaxyLow = std::make_shared("f1dcaxy_low", "[0]+[1]/pow(x,[2])", 0., 10.); + f1dcaxyLow->SetParameters(-0.0105, -0.035, 1.1); + dcaCuts->AddCut(VarManager::kTrackDCAxy, f1dcaxyLow, f1dcaxyHigh); + dcaCuts->AddCut(VarManager::kTrackDCAz, -2., 2.); + + cut->AddCut(kineCut); + cut->AddCut(qualityCuts); + cut->AddCut(dcaCuts); + } + // ------------------------------------------------------------------------------------------------- // // LMee cuts // List of cuts used for low mass dielectron analyses // // Skimming cuts: - if (!nameStr.compare("lmee_skimming")) { + if (nameStr == "lmee_skimming") { cut->AddCut(GetAnalysisCut("lmee_skimming_cuts")); return cut; } // LMee Run2 PID cuts - if (!nameStr.compare("lmeePID_TPChadrejTOFrec")) { + if (nameStr == "lmeePID_TPChadrejTOFrec") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("TightGlobalTrack")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); - AnalysisCompositeCut* cut_tpc_hadrej = new AnalysisCompositeCut("pid_TPChadrej", "pid_TPChadrej", kTRUE); + auto* cut_tpc_hadrej = new AnalysisCompositeCut("pid_TPChadrej", "pid_TPChadrej", kTRUE); cut_tpc_hadrej->AddCut(GetAnalysisCut("tpc_electron")); cut_tpc_hadrej->AddCut(GetAnalysisCut("tpc_pion_rejection")); cut_tpc_hadrej->AddCut(GetAnalysisCut("tpc_kaon_rejection")); cut_tpc_hadrej->AddCut(GetAnalysisCut("tpc_proton_rejection")); - AnalysisCompositeCut* cut_tof_rec = new AnalysisCompositeCut("pid_tof_rec", "pid_tof_rec", kTRUE); + auto* cut_tof_rec = new AnalysisCompositeCut("pid_tof_rec", "pid_tof_rec", kTRUE); cut_tof_rec->AddCut(GetAnalysisCut("tpc_electron")); cut_tof_rec->AddCut(GetAnalysisCut("tof_electron")); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("pid_TPChadrejTOFrec", "pid_TPChadrejTOFrec", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("pid_TPChadrejTOFrec", "pid_TPChadrejTOFrec", kFALSE); cut_pid_OR->AddCut(cut_tpc_hadrej); cut_pid_OR->AddCut(cut_tof_rec); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare("lmeePID_TPChadrej")) { + if (nameStr == "lmeePID_TPChadrej") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("TightGlobalTrack")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); - AnalysisCompositeCut* cut_tpc_hadrej = new AnalysisCompositeCut("pid_TPChadrej", "pid_TPChadrej", kTRUE); + auto* cut_tpc_hadrej = new AnalysisCompositeCut("pid_TPChadrej", "pid_TPChadrej", kTRUE); cut_tpc_hadrej->AddCut(GetAnalysisCut("tpc_electron")); cut_tpc_hadrej->AddCut(GetAnalysisCut("tpc_pion_rejection")); cut_tpc_hadrej->AddCut(GetAnalysisCut("tpc_kaon_rejection")); @@ -1614,30 +1670,30 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("lmee_eNSigmaRun2")) { + if (nameStr == "lmee_eNSigmaRun2") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("TightGlobalTrack")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut("electronPID_TPCnsigma")); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut("electronPID_TOFnsigma")); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare("lmeePID_TOFrec")) { + if (nameStr == "lmeePID_TOFrec") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("TightGlobalTrack")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); - AnalysisCompositeCut* cut_tof_rec = new AnalysisCompositeCut("pid_tof_rec", "pid_tof_rec", kTRUE); + auto* cut_tof_rec = new AnalysisCompositeCut("pid_tof_rec", "pid_tof_rec", kTRUE); cut_tof_rec->AddCut(GetAnalysisCut("tpc_electron")); cut_tof_rec->AddCut(GetAnalysisCut("tof_electron")); @@ -1645,28 +1701,28 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("lmee_GlobalTrackRun2")) { + if (nameStr == "lmee_GlobalTrackRun2") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("TightGlobalTrack")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); return cut; } - if (!nameStr.compare("lmee_GlobalTrackRun2_lowPt")) { + if (nameStr == "lmee_GlobalTrackRun2_lowPt") { cut->AddCut(GetAnalysisCut("lmeeLowBKine")); cut->AddCut(GetAnalysisCut("TightGlobalTrack")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); return cut; } - if (!nameStr.compare("lmee_TPCTrackRun2_lowPt")) { + if (nameStr == "lmee_TPCTrackRun2_lowPt") { cut->AddCut(GetAnalysisCut("lmeeLowBKine")); cut->AddCut(GetAnalysisCut("TightTPCTrack")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); return cut; } - if (!nameStr.compare("lmee_TPCTrackRun2")) { + if (nameStr == "lmee_TPCTrackRun2") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("TightTPCTrack")); cut->AddCut(GetAnalysisCut("standardPrimaryTrack")); @@ -1675,31 +1731,31 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) // LMee Run3 PID cuts - if (!nameStr.compare("lmeePID_TPChadrejTOFrecRun3")) { + if (nameStr == "lmeePID_TPChadrejTOFrecRun3") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_hadrej = new AnalysisCompositeCut("pid_TPChadrej", "pid_TPChadrej", kTRUE); + auto* cut_tpc_hadrej = new AnalysisCompositeCut("pid_TPChadrej", "pid_TPChadrej", kTRUE); cut_tpc_hadrej->AddCut(GetAnalysisCut("tpc_electron")); cut_tpc_hadrej->AddCut(GetAnalysisCut("tpc_pion_muon_band_rejection")); cut_tpc_hadrej->AddCut(GetAnalysisCut("tpc_pion_rejection_highp")); cut_tpc_hadrej->AddCut(GetAnalysisCut("tpc_kaon_rejection")); cut_tpc_hadrej->AddCut(GetAnalysisCut("tpc_proton_rejection")); - AnalysisCompositeCut* cut_tof_rec = new AnalysisCompositeCut("pid_tof_rec", "pid_tof_rec", kTRUE); + auto* cut_tof_rec = new AnalysisCompositeCut("pid_tof_rec", "pid_tof_rec", kTRUE); cut_tof_rec->AddCut(GetAnalysisCut("tpc_electron")); cut_tof_rec->AddCut(GetAnalysisCut("tof_electron_loose")); cut_tof_rec->AddCut(GetAnalysisCut("tpc_pion_rejection_highp")); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("pid_TPChadrejTOFrec", "pid_TPChadrejTOFrec", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("pid_TPChadrejTOFrec", "pid_TPChadrejTOFrec", kFALSE); cut_pid_OR->AddCut(cut_tpc_hadrej); cut_pid_OR->AddCut(cut_tof_rec); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare("lmee_Run3_TPCelectron")) { + if (nameStr == "lmee_Run3_TPCelectron") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); @@ -1707,7 +1763,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("lmee_Run3_TOFelectron")) { + if (nameStr == "lmee_Run3_TOFelectron") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); @@ -1715,7 +1771,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("lmee_Run3_posTrack_TPCelectron")) { + if (nameStr == "lmee_Run3_posTrack_TPCelectron") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); @@ -1724,7 +1780,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("lmee_Run3_posTrack_TOFelectron")) { + if (nameStr == "lmee_Run3_posTrack_TOFelectron") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); @@ -1733,7 +1789,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("lmee_Run3_negTrack_TPCelectron")) { + if (nameStr == "lmee_Run3_negTrack_TPCelectron") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); @@ -1742,7 +1798,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("lmee_Run3_negTrack_TOFelectron")) { + if (nameStr == "lmee_Run3_negTrack_TOFelectron") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); @@ -1766,21 +1822,21 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) // loop to define PID cuts with and without post calibration for (size_t icase = 0; icase < vecTypetrack.size(); icase++) { // Tracking cuts of Pb--Pb analysis - if (!nameStr.compare(Form("lmee%s_PbPb_selection", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee%s_PbPb_selection", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); return cut; } - if (!nameStr.compare(Form("lmee%s_PbPb_selection_pt04", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee%s_PbPb_selection_pt04", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine_pt04")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); return cut; } - if (!nameStr.compare(Form("lmee%s_TrackCuts_Resol", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee%s_TrackCuts_Resol", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("openEtaSel")); // No pt cut and wider eta cut to produce resolution maps cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); @@ -1788,7 +1844,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } // 4 cuts to separate pos & neg tracks in pos & neg eta range - if (!nameStr.compare(Form("lmee_posTrack_posEta_selection%s", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee_posTrack_posEta_selection%s", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); @@ -1796,7 +1852,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_negTrack_posEta_selection%s", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee_negTrack_posEta_selection%s", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); @@ -1804,7 +1860,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_posTrack_negEta_selection%s", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee_posTrack_negEta_selection%s", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); @@ -1812,7 +1868,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_negTrack_negEta_selection%s", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee_negTrack_negEta_selection%s", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); @@ -1821,7 +1877,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } // 2 cuts to separate pos & neg tracks - if (!nameStr.compare(Form("lmee_posTrack_selection%s", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee_posTrack_selection%s", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("etaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); @@ -1829,7 +1885,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_negTrack_selection%s", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee_negTrack_selection%s", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("etaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); @@ -1838,7 +1894,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } // 4 cuts to separate pos & neg tracks in pos & neg eta range low B field - if (!nameStr.compare(Form("lmee_lowB_posTrack_posEta_selection%s", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee_lowB_posTrack_posEta_selection%s", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); @@ -1846,7 +1902,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_lowB_negTrack_posEta_selection%s", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee_lowB_negTrack_posEta_selection%s", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); @@ -1854,7 +1910,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_lowB_posTrack_negEta_selection%s", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee_lowB_posTrack_negEta_selection%s", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); @@ -1862,7 +1918,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_lowB_negTrack_negEta_selection%s", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee_lowB_negTrack_negEta_selection%s", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); @@ -1871,7 +1927,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } // 2 cuts to separate pos & neg tracks in low B field - if (!nameStr.compare(Form("lmee_lowB_posTrack_selection%s", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee_lowB_posTrack_selection%s", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("etaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); @@ -1879,7 +1935,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_lowB_negTrack_selection%s", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmee_lowB_negTrack_selection%s", vecTypetrack.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("etaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); @@ -1902,12 +1958,12 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) // loop to define PID cuts with and without post calibration for (size_t icase = 0; icase < vecPIDcase.size(); icase++) { - if (!nameStr.compare(Form("lmee_onlyTPCPID%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_onlyTPCPID%s", vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut(Form("electronPIDOnly%s", vecPIDcase.at(icase).Data()))); return cut; } - if (!nameStr.compare(Form("ITSTPC_TPCPID%s_prefilter", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("ITSTPC_TPCPID%s_prefilter", vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeePrefilterKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); @@ -1916,45 +1972,45 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("ITS_ifTPC_TPCPID%s_prefilter", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("ITS_ifTPC_TPCPID%s_prefilter", vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeePrefilterKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_notpc = new AnalysisCompositeCut("NoTPC", "NoTPC", kTRUE); + auto* cut_notpc = new AnalysisCompositeCut("NoTPC", "NoTPC", kTRUE); cut_notpc->AddCut(GetAnalysisCut("noTPC")); - AnalysisCompositeCut* cut_tpcpid = new AnalysisCompositeCut("pid_TPC", "pid_TPC", kTRUE); + auto* cut_tpcpid = new AnalysisCompositeCut("pid_TPC", "pid_TPC", kTRUE); cut_tpcpid->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); cut_tpcpid->AddCut(GetAnalysisCut(Form("electronPIDOnly%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_OR = new AnalysisCompositeCut("OR", "OR", kFALSE); + auto* cut_OR = new AnalysisCompositeCut("OR", "OR", kFALSE); cut_OR->AddCut(cut_notpc); cut_OR->AddCut(cut_tpcpid); cut->AddCut(cut_OR); return cut; } - if (!nameStr.compare(Form("ITS_ifTPCStandard_TPCPID%s_prefilter", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("ITS_ifTPCStandard_TPCPID%s_prefilter", vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeePrefilterKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityITSOnly")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_notpcstandard = new AnalysisCompositeCut("NoTPCstandard", "NoTPCstandard", kTRUE); + auto* cut_notpcstandard = new AnalysisCompositeCut("NoTPCstandard", "NoTPCstandard", kTRUE); cut_notpcstandard->AddCut(GetAnalysisCut("NoelectronStandardQualityTPCOnly")); - AnalysisCompositeCut* cut_tpcpid = new AnalysisCompositeCut("pid_TPC", "pid_TPC", kTRUE); + auto* cut_tpcpid = new AnalysisCompositeCut("pid_TPC", "pid_TPC", kTRUE); cut_tpcpid->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); cut_tpcpid->AddCut(GetAnalysisCut(Form("electronPIDOnly%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_OR = new AnalysisCompositeCut("OR", "OR", kFALSE); + auto* cut_OR = new AnalysisCompositeCut("OR", "OR", kFALSE); cut_OR->AddCut(cut_notpcstandard); cut_OR->AddCut(cut_tpcpid); cut->AddCut(cut_OR); return cut; } - if (!nameStr.compare(Form("ITSTPCbAny_TPCPID%s_prefilter", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("ITSTPCbAny_TPCPID%s_prefilter", vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeePrefilterKine")); cut->AddCut(GetAnalysisCut("electronStandardQualitybAnyITSOnly")); cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); @@ -1963,38 +2019,38 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("ITSbAny_ifTPC_TPCPID%s_prefilter", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("ITSbAny_ifTPC_TPCPID%s_prefilter", vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeePrefilterKine")); cut->AddCut(GetAnalysisCut("electronStandardQualitybAnyITSOnly")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_notpc = new AnalysisCompositeCut("NoTPC", "NoTPC", kTRUE); + auto* cut_notpc = new AnalysisCompositeCut("NoTPC", "NoTPC", kTRUE); cut_notpc->AddCut(GetAnalysisCut("noTPC")); - AnalysisCompositeCut* cut_tpcpid = new AnalysisCompositeCut("pid_TPC", "pid_TPC", kTRUE); + auto* cut_tpcpid = new AnalysisCompositeCut("pid_TPC", "pid_TPC", kTRUE); cut_tpcpid->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); cut_tpcpid->AddCut(GetAnalysisCut(Form("electronPIDOnly%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_OR = new AnalysisCompositeCut("OR", "OR", kFALSE); + auto* cut_OR = new AnalysisCompositeCut("OR", "OR", kFALSE); cut_OR->AddCut(cut_notpc); cut_OR->AddCut(cut_tpcpid); cut->AddCut(cut_OR); return cut; } - if (!nameStr.compare(Form("ITSbAny_ifTPCStandard_TPCPID%s_prefilter", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("ITSbAny_ifTPCStandard_TPCPID%s_prefilter", vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeePrefilterKine")); cut->AddCut(GetAnalysisCut("electronStandardQualitybAnyITSOnly")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_notpcstandard = new AnalysisCompositeCut("NoTPCstandard", "NoTPCstandard", kTRUE); + auto* cut_notpcstandard = new AnalysisCompositeCut("NoTPCstandard", "NoTPCstandard", kTRUE); cut_notpcstandard->AddCut(GetAnalysisCut("NoelectronStandardQualityTPCOnly")); - AnalysisCompositeCut* cut_tpcpid = new AnalysisCompositeCut("pid_TPC", "pid_TPC", kTRUE); + auto* cut_tpcpid = new AnalysisCompositeCut("pid_TPC", "pid_TPC", kTRUE); cut_tpcpid->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); cut_tpcpid->AddCut(GetAnalysisCut(Form("electronPIDOnly%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_OR = new AnalysisCompositeCut("OR", "OR", kFALSE); + auto* cut_OR = new AnalysisCompositeCut("OR", "OR", kFALSE); cut_OR->AddCut(cut_notpcstandard); cut_OR->AddCut(cut_tpcpid); cut->AddCut(cut_OR); @@ -2002,18 +2058,18 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } for (unsigned int i = 0; i < 30; i++) { // o2-linter: disable=magic-number (number of cuts) - if (!nameStr.compare(Form("ElSelCutVar%s%i", vecPIDcase.at(icase).Data(), i))) { + if (nameStr == Form("ElSelCutVar%s%i", vecPIDcase.at(icase).Data(), i)) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeCutVarTrackCuts%i", i))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma_cutVar%s%i", vecPIDcase.at(icase).Data(), i))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma_cutVar%s%i", vecPIDcase.at(icase).Data(), i))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); @@ -2023,7 +2079,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) for (size_t jcase = 0; jcase < vecTypetrackWithPID.size(); jcase++) { // All previous cut with TightGlobalTrackRun3 - if (!nameStr.compare(Form("ITSTPC%s_TPCPIDalone%s_PbPb", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("ITSTPC%s_TPCPIDalone%s_PbPb", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); @@ -2031,97 +2087,97 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_loose", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_loose", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_loose", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_loose", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_strongHadRej", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_strongHadRej", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongHadRej", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongHadRej", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_strongNSigE_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_strongNSigE_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_TOFreq", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_TOFreq", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); @@ -2129,133 +2185,133 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_Resol", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_Resol", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("openEtaSel")); // No pt cut and wider eta cut to produce resolution maps cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_tightNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_tightNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_tightNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_tightNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_tightNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_tightNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine_pt04")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_tightNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_tightNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_strongNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_strongNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine_pt04")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_lowB_eNSigmaRun3%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_lowB_eNSigmaRun3%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeLowBKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); // to reject looper using DCAz - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_lowB_eNSigmaRun3%s_strongNSigE_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_lowB_eNSigmaRun3%s_strongNSigE_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeLowBKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); // to reject looper using DCAz - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TPCnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TOFnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_TOFreqRun3%s_strongNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_TOFreqRun3%s_strongNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine_pt04")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); @@ -2263,7 +2319,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee%s_TOFreqRun3%s_tightNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_TOFreqRun3%s_tightNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine_pt04")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); @@ -2272,152 +2328,152 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } // 8 cuts for QC - if (!nameStr.compare(Form("lmee%s_NSigmaRun3_posEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_NSigmaRun3_posEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("pt02Sel")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_NSigmaRun3_negEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_NSigmaRun3_negEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("pt02Sel")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_NSigmaRun3_posEta%s_strongNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_NSigmaRun3_posEta%s_strongNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("pt04Sel")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_NSigmaRun3_negEta%s_strongNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_NSigmaRun3_negEta%s_strongNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("pt04Sel")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_posNSigmaRun3_posEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_posNSigmaRun3_posEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_posNSigmaRun3_negEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_posNSigmaRun3_negEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_negNSigmaRun3_posEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_negNSigmaRun3_posEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_negNSigmaRun3_negEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_negNSigmaRun3_negEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); @@ -2425,7 +2481,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } // 6 cuts for QC - if (!nameStr.compare(Form("lmee%s_posTOFreqRun3_posEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_posTOFreqRun3_posEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); @@ -2434,7 +2490,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee%s_posTOFreqRun3_negEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_posTOFreqRun3_negEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); @@ -2443,7 +2499,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee%s_TOFreqRun3_posEta%s_strongNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_TOFreqRun3_posEta%s_strongNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("pt04Sel")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); @@ -2452,7 +2508,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee%s_TOFreqRun3_negEta%s_strongNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_TOFreqRun3_negEta%s_strongNSigEPbPb_rejBadTOF_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("pt04Sel")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); @@ -2461,7 +2517,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee%s_negTOFreqRun3_posEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_negTOFreqRun3_posEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); @@ -2470,7 +2526,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee%s_negTOFreqRun3_negEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_negTOFreqRun3_negEta%s_strongNSigEPbPb_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); @@ -2479,42 +2535,42 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_TPC_PID", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_TPC_PID", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); cut->AddCut(cut_tpc_nSigma); return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_TOF_PID", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_TOF_PID", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); cut->AddCut(cut_tof_nSigma); return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_strongNSigE_DCA05", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_strongNSigE_DCA05", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_DCA05")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); @@ -2522,76 +2578,76 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } // 4 cuts to separate pos & neg tracks in pos & neg eta range applying electron PID - if (!nameStr.compare(Form("lmee%s_posNSigmaRun3_posEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_posNSigmaRun3_posEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_negNSigmaRun3_posEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_negNSigmaRun3_posEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_posNSigmaRun3_negEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_posNSigmaRun3_negEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_negNSigmaRun3_negEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_negNSigmaRun3_negEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); @@ -2599,76 +2655,76 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } // 4 cuts to separate pos & neg tracks in pos & neg eta range applying electron PID for low B field - if (!nameStr.compare(Form("lmee%s_lowB_posNSigmaRun3_posEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_lowB_posNSigmaRun3_posEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_lowB_negNSigmaRun3_posEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_lowB_negNSigmaRun3_posEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_lowB_posNSigmaRun3_negEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_lowB_posNSigmaRun3_negEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_lowB_negNSigmaRun3_negEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_lowB_negNSigmaRun3_negEta%s_strongNSigE", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); @@ -2676,76 +2732,76 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } // 4 cuts to separate pos & neg tracks in pos & neg eta range applying electron PID for low B field with bad TOF rejection - if (!nameStr.compare(Form("lmee%s_lowB_posNSigmaRun3_posEta%s_strongNSigE_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_lowB_posNSigmaRun3_posEta%s_strongNSigE_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TPCnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TOFnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_lowB_negNSigmaRun3_posEta%s_strongNSigE_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_lowB_negNSigmaRun3_posEta%s_strongNSigE_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("posEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TPCnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TOFnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_lowB_posNSigmaRun3_negEta%s_strongNSigE_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_lowB_posNSigmaRun3_negEta%s_strongNSigE_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TPCnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TOFnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_lowB_negNSigmaRun3_negEta%s_strongNSigE_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_lowB_negNSigmaRun3_negEta%s_strongNSigE_rejBadTOF", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("negTrack")); cut->AddCut(GetAnalysisCut("negEtaSel")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TPCnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_lowB_TOFnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); @@ -2753,18 +2809,18 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } // some older cuts - if (!nameStr.compare(Form("lmee%s_pp502TeV_PID%s", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_pp502TeV_PID%s", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("lmee_pp_502TeV_TPC%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("lmee_pp_502TeV_TOF%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); @@ -2772,19 +2828,19 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } for (int i = 1; i <= 8; i++) { // o2-linter: disable=magic-number (number of cuts) - if (!nameStr.compare(Form("lmee%s_pp502TeV_PID%s_UsePrefilter%d", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data(), i))) { + if (nameStr == Form("lmee%s_pp502TeV_PID%s_UsePrefilter%d", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data(), i)) { cut->AddCut(GetAnalysisCut(Form("notDalitzLeg%d", i))); cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("lmee_pp_502TeV_TPC%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("lmee_pp_502TeV_TOF%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); @@ -2792,36 +2848,36 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } } - if (!nameStr.compare(Form("lmee%s_pp502TeV_lowB_PID%s", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_pp502TeV_lowB_PID%s", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeLowBKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); // DCAz to reject loopers - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("lmee_pp_502TeV_lowB_TPC%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("lmee_pp_502TeV_lowB_TOF%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_pt04", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine_pt04")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); @@ -2829,19 +2885,19 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } for (int i = 1; i <= 8; i++) { // o2-linter: disable=magic-number (number of cuts) - if (!nameStr.compare(Form("lmee%s_eNSigmaRun3%s_UsePrefilter%d", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data(), i))) { + if (nameStr == Form("lmee%s_eNSigmaRun3%s_UsePrefilter%d", vecTypetrackWithPID.at(jcase).Data(), vecPIDcase.at(icase).Data(), i)) { cut->AddCut(GetAnalysisCut(Form("notDalitzLeg%d", i))); cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrackWithPID.at(jcase).Data()))); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); @@ -2850,55 +2906,55 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } } - if (!nameStr.compare(Form("lmee_eNSigmaRun3%s_strongTPC", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_eNSigmaRun3%s_strongTPC", vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3_strongTPC")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TPCnsigma%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("electronPID_TOFnsigma%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee_skimmingtesta_PID%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_skimmingtesta_PID%s", vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("LooseGlobalTrackRun3")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("lmee_pp_502TeV_TPCloose%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut(Form("lmee_pp_502TeV_TOFloose%s", vecPIDcase.at(icase).Data()))); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); cut->AddCut(cut_pid_OR); return cut; } - if (!nameStr.compare(Form("lmee_skimmingtestb_PID%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_skimmingtestb_PID%s", vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("LooseGlobalTrackRun3")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut(Form("lmee_pp_502TeV_TPCloosenopkrej%s", vecPIDcase.at(icase).Data()))); cut->AddCut(cut_tpc_nSigma); return cut; } - if (!nameStr.compare(Form("lmee_skimmingtesta_TOF%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_skimmingtesta_TOF%s", vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("LooseGlobalTrackRun3")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); @@ -2906,7 +2962,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_skimmingtesta_TOF_pionrej%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_skimmingtesta_TOF_pionrej%s", vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("LooseGlobalTrackRun3")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); @@ -2914,7 +2970,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_skimmingtesta_TOF_pionrej_noDCA%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_skimmingtesta_TOF_pionrej_noDCA%s", vecPIDcase.at(icase).Data())) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("LooseGlobalTrackRun3")); cut->AddCut(GetAnalysisCut(Form("lmee_pp_502TeV_TOFloose_pionrej%s", vecPIDcase.at(icase).Data()))); @@ -2922,70 +2978,81 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) } } - if (!nameStr.compare("testCut_chic")) { + if (nameStr == "testCut_chic") { cut->AddCut(GetAnalysisCut("jpsiStandardKine5")); cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug")); cut->AddCut(GetAnalysisCut("electronPIDnsigma")); return cut; } - if (!nameStr.compare("lmee_GlobalTrackRun3")) { + if (nameStr == "lmee_GlobalTrackRun3") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); return cut; } - if (!nameStr.compare("lmee_GlobalTrackRun3_lowPt")) { + if (nameStr == "lmee_GlobalTrackRun3_lowPt") { cut->AddCut(GetAnalysisCut("lmeeLowBKine")); cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); return cut; } - if (!nameStr.compare("lmee_TPCTrackRun3_lowPt")) { + if (nameStr == "lmee_TPCTrackRun3_lowPt") { cut->AddCut(GetAnalysisCut("lmeeLowBKine")); cut->AddCut(GetAnalysisCut("TightTPCTrackRun3")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); return cut; } - if (!nameStr.compare("lmee_TPCTrackRun3")) { + if (nameStr == "lmee_TPCTrackRun3") { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("TightTPCTrackRun3")); cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); return cut; } - if (!nameStr.compare("trackCut_compareDQEMframework")) { // cut setting to check least common factor between reduced data sets of PWGEM and PWGDQ + if (nameStr == "trackCut_compareDQEMframework") { // cut setting to check least common factor between reduced data sets of PWGEM and PWGDQ cut->AddCut(GetAnalysisCut("lmeeStandardKine")); cut->AddCut(GetAnalysisCut("trackQuality_compareDQEMframework")); cut->AddCut(GetAnalysisCut("trackDCA1cm")); - AnalysisCompositeCut* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); + auto* cut_tpc_nSigma = new AnalysisCompositeCut("pid_TPCnSigma", "pid_TPCnSigma", kTRUE); cut_tpc_nSigma->AddCut(GetAnalysisCut("lmee_commonDQEM_PID_TPC")); - AnalysisCompositeCut* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); + auto* cut_tof_nSigma = new AnalysisCompositeCut("pid_TOFnSigma", "pid_TOFnSigma", kTRUE); cut_tof_nSigma->AddCut(GetAnalysisCut("lmee_commonDQEM_PID_TOF")); - AnalysisCompositeCut* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); + auto* cut_pid_OR = new AnalysisCompositeCut("e_NSigma", "e_NSigma", kFALSE); cut_pid_OR->AddCut(cut_tpc_nSigma); cut_pid_OR->AddCut(cut_tof_nSigma); return cut; } + if (nameStr == "jpsi_debug_TPCTOF3_rejBadTOF") { + cut->AddCut(GetAnalysisCut("jpsiStandardKine5")); + cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly3")); + cut->AddCut(GetAnalysisCut("SPDfirst")); + cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); + cut->AddCut(GetAnalysisCut("pidJpsi_TPCpion0")); + cut->AddCut(GetAnalysisCut("pidJpsi_beta")); + cut->AddCut(GetAnalysisCut("pidJpsi_noTOF_prot")); + return cut; + } + // ------------------------------------------------------------------------------------------------- // lmee pair cuts - if (!nameStr.compare("pairPhiV")) { - AnalysisCompositeCut* cut_pairPhiV = new AnalysisCompositeCut("cut_pairPhiV", "cut_pairPhiV", kTRUE); + if (nameStr == "pairPhiV") { + auto* cut_pairPhiV = new AnalysisCompositeCut("cut_pairPhiV", "cut_pairPhiV", kTRUE); cut_pairPhiV->AddCut(GetAnalysisCut("pairLowMass")); cut_pairPhiV->AddCut(GetAnalysisCut("pairPhiV")); cut->AddCut(cut_pairPhiV); return cut; } - if (!nameStr.compare("excludePairPhiV")) { - AnalysisCompositeCut* cut_pairlowPhiV = new AnalysisCompositeCut("cut_pairlowPhiV", "cut_pairlowPhiV", kFALSE); + if (nameStr == "excludePairPhiV") { + auto* cut_pairlowPhiV = new AnalysisCompositeCut("cut_pairlowPhiV", "cut_pairlowPhiV", kFALSE); cut_pairlowPhiV->AddCut(GetAnalysisCut("excludePairLowMass")); cut_pairlowPhiV->AddCut(GetAnalysisCut("excludePairPhiV")); cut->AddCut(cut_pairlowPhiV); @@ -2995,651 +3062,651 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) // ------------------------------------------------------------------------------------------------- // Muon cuts - if (!nameStr.compare("muonQualityCutsMatchingOnly")) { + if (nameStr == "muonQualityCutsMatchingOnly") { cut->AddCut(GetAnalysisCut("muonQualityCutsMatchingOnly")); return cut; } - if (!nameStr.compare("muonMinimalCuts")) { + if (nameStr == "muonMinimalCuts") { cut->AddCut(GetAnalysisCut("muonMinimalCuts")); return cut; } - if (!nameStr.compare("muonMinimalCuts10SigmaPDCA")) { + if (nameStr == "muonMinimalCuts10SigmaPDCA") { cut->AddCut(GetAnalysisCut("muonMinimalCuts10SigmaPDCA")); return cut; } - if (!nameStr.compare("muonQualityCuts")) { + if (nameStr == "muonQualityCuts") { cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("matchedQualityCuts")) { + if (nameStr == "matchedQualityCuts") { cut->AddCut(GetAnalysisCut("matchedQualityCuts")); return cut; } - if (!nameStr.compare("matchedQualityCutsMFTeta")) { + if (nameStr == "matchedQualityCutsMFTeta") { cut->AddCut(GetAnalysisCut("matchedQualityCutsMFTeta")); return cut; } - if (!nameStr.compare("muonQualityCuts5SigmaPDCA_Run3")) { + if (nameStr == "muonQualityCuts5SigmaPDCA_Run3") { cut->AddCut(GetAnalysisCut("muonQualityCuts5SigmaPDCA_Run3")); return cut; } - if (!nameStr.compare("muonLowPt5SigmaPDCA_Run3")) { + if (nameStr == "muonLowPt5SigmaPDCA_Run3") { cut->AddCut(GetAnalysisCut("muonLowPt")); cut->AddCut(GetAnalysisCut("muonQualityCuts5SigmaPDCA_Run3")); cut->AddCut(GetAnalysisCut("MCHMID")); return cut; } - if (!nameStr.compare("muonQualityCuts10SigmaPDCA_MCHMID")) { + if (nameStr == "muonQualityCuts10SigmaPDCA_MCHMID") { cut->AddCut(GetAnalysisCut("muonQualityCuts10SigmaPDCA")); cut->AddCut(GetAnalysisCut("MCHMID")); return cut; } - if (!nameStr.compare("muonLowPt10SigmaPDCA")) { + if (nameStr == "muonLowPt10SigmaPDCA") { cut->AddCut(GetAnalysisCut("muonLowPt")); cut->AddCut(GetAnalysisCut("muonQualityCuts10SigmaPDCA")); cut->AddCut(GetAnalysisCut("MCHMID")); return cut; } - if (!nameStr.compare("muonLowPt210SigmaPDCA")) { + if (nameStr == "muonLowPt210SigmaPDCA") { cut->AddCut(GetAnalysisCut("muonLowPt2")); cut->AddCut(GetAnalysisCut("muonQualityCuts10SigmaPDCA")); cut->AddCut(GetAnalysisCut("MCHMID")); return cut; } - if (!nameStr.compare("muonLowPt510SigmaPDCA")) { + if (nameStr == "muonLowPt510SigmaPDCA") { cut->AddCut(GetAnalysisCut("muonLowPt5")); cut->AddCut(GetAnalysisCut("muonQualityCuts10SigmaPDCA")); cut->AddCut(GetAnalysisCut("MCHMID")); return cut; } - if (!nameStr.compare("muonLowPt610SigmaPDCA")) { + if (nameStr == "muonLowPt610SigmaPDCA") { cut->AddCut(GetAnalysisCut("muonLowPt6")); cut->AddCut(GetAnalysisCut("muonQualityCuts10SigmaPDCA")); cut->AddCut(GetAnalysisCut("MCHMID")); return cut; } - if (!nameStr.compare("muonLowPt")) { + if (nameStr == "muonLowPt") { cut->AddCut(GetAnalysisCut("muonLowPt")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("muonLowPt2")) { + if (nameStr == "muonLowPt2") { cut->AddCut(GetAnalysisCut("muonLowPt2")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("muonLowPt3")) { + if (nameStr == "muonLowPt3") { cut->AddCut(GetAnalysisCut("muonLowPt3")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("muonLowPt4")) { + if (nameStr == "muonLowPt4") { cut->AddCut(GetAnalysisCut("muonLowPt4")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("muonLowPt5")) { + if (nameStr == "muonLowPt5") { cut->AddCut(GetAnalysisCut("muonLowPt5")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("muonLowPt6")) { + if (nameStr == "muonLowPt6") { cut->AddCut(GetAnalysisCut("muonLowPt6")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("muonLowPtMatchingOnly")) { + if (nameStr == "muonLowPtMatchingOnly") { cut->AddCut(GetAnalysisCut("muonLowPt")); cut->AddCut(GetAnalysisCut("muonQualityCutsMatchingOnly")); return cut; } - if (!nameStr.compare("muonLowPtMatchingOnly2")) { + if (nameStr == "muonLowPtMatchingOnly2") { cut->AddCut(GetAnalysisCut("muonLowPt2")); cut->AddCut(GetAnalysisCut("muonQualityCutsMatchingOnly")); return cut; } - if (!nameStr.compare("muonLowPtMatchingOnly3")) { + if (nameStr == "muonLowPtMatchingOnly3") { cut->AddCut(GetAnalysisCut("muonLowPt3")); cut->AddCut(GetAnalysisCut("muonQualityCutsMatchingOnly")); return cut; } - if (!nameStr.compare("muonLowPtMatchingOnly4")) { + if (nameStr == "muonLowPtMatchingOnly4") { cut->AddCut(GetAnalysisCut("muonLowPt4")); cut->AddCut(GetAnalysisCut("muonQualityCutsMatchingOnly")); return cut; } - if (!nameStr.compare("muonLowPtMatchingOnly5")) { + if (nameStr == "muonLowPtMatchingOnly5") { cut->AddCut(GetAnalysisCut("muonLowPt5")); cut->AddCut(GetAnalysisCut("muonQualityCutsMatchingOnly")); return cut; } - if (!nameStr.compare("muonLowPtMatchingOnly6")) { + if (nameStr == "muonLowPtMatchingOnly6") { cut->AddCut(GetAnalysisCut("muonLowPt6")); cut->AddCut(GetAnalysisCut("muonQualityCutsMatchingOnly")); return cut; } - if (!nameStr.compare("muonHighPt")) { + if (nameStr == "muonHighPt") { cut->AddCut(GetAnalysisCut("muonHighPt")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("muonHighPt2")) { + if (nameStr == "muonHighPt2") { cut->AddCut(GetAnalysisCut("muonHighPt2")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("muonHighPt3")) { + if (nameStr == "muonHighPt3") { cut->AddCut(GetAnalysisCut("muonHighPt3")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("muonHighPt4")) { + if (nameStr == "muonHighPt4") { cut->AddCut(GetAnalysisCut("muonHighPt4")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("muonHighPt5")) { + if (nameStr == "muonHighPt5") { cut->AddCut(GetAnalysisCut("muonHighPt5")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("muonHighPt6")) { + if (nameStr == "muonHighPt6") { cut->AddCut(GetAnalysisCut("muonHighPt6")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("muonHighPtMatchingOnly2")) { + if (nameStr == "muonHighPtMatchingOnly2") { cut->AddCut(GetAnalysisCut("muonHighPt2")); cut->AddCut(GetAnalysisCut("muonQualityCutsMatchingOnly")); return cut; } - if (!nameStr.compare("muonHighPtMatchingOnly3")) { + if (nameStr == "muonHighPtMatchingOnly3") { cut->AddCut(GetAnalysisCut("muonHighPt3")); cut->AddCut(GetAnalysisCut("muonQualityCutsMatchingOnly")); return cut; } - if (!nameStr.compare("muonTightQualityCutsForTests")) { + if (nameStr == "muonTightQualityCutsForTests") { cut->AddCut(GetAnalysisCut("muonTightQualityCutsForTests")); return cut; } - if (!nameStr.compare("mchTrack")) { + if (nameStr == "mchTrack") { cut->AddCut(GetAnalysisCut("mchTrack")); return cut; } - if (!nameStr.compare("matchedMchMid")) { + if (nameStr == "matchedMchMid") { cut->AddCut(GetAnalysisCut("matchedMchMid")); return cut; } - if (!nameStr.compare("matchedFwd")) { + if (nameStr == "matchedFwd") { cut->AddCut(GetAnalysisCut("matchedFwd")); return cut; } - if (!nameStr.compare("matchedGlobal")) { + if (nameStr == "matchedGlobal") { cut->AddCut(GetAnalysisCut("matchedGlobal")); return cut; } - if (!nameStr.compare("Chi2MCHMFTCut1")) { + if (nameStr == "Chi2MCHMFTCut1") { cut->AddCut(GetAnalysisCut("Chi2MCHMFTCut1")); return cut; } - if (!nameStr.compare("Chi2MCHMFTCut2")) { + if (nameStr == "Chi2MCHMFTCut2") { cut->AddCut(GetAnalysisCut("Chi2MCHMFTCut2")); return cut; } - if (!nameStr.compare("Chi2MCHMFTCut3")) { + if (nameStr == "Chi2MCHMFTCut3") { cut->AddCut(GetAnalysisCut("Chi2MCHMFTCut3")); return cut; } - if (!nameStr.compare("Chi2MCHMFTCut4")) { + if (nameStr == "Chi2MCHMFTCut4") { cut->AddCut(GetAnalysisCut("Chi2MCHMFTCut4")); return cut; } - if (!nameStr.compare("muonQualityCutsMUONStandalone")) { + if (nameStr == "muonQualityCutsMUONStandalone") { cut->AddCut(GetAnalysisCut("matchedMchMid")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } - if (!nameStr.compare("muonQualityCutsGlobal")) { + if (nameStr == "muonQualityCutsGlobal") { cut->AddCut(GetAnalysisCut("matchedGlobal")); cut->AddCut(GetAnalysisCut("muonQualityCuts")); return cut; } // ----------------------------------------------------------- // Pair cuts - if (!nameStr.compare("pairNoCut")) { + if (nameStr == "pairNoCut") { cut->AddCut(GetAnalysisCut("pairNoCut")); return cut; } - if (!nameStr.compare("pairMassLow1")) { + if (nameStr == "pairMassLow1") { cut->AddCut(GetAnalysisCut("pairMassLow1")); return cut; } - if (!nameStr.compare("pairMassLow2")) { + if (nameStr == "pairMassLow2") { cut->AddCut(GetAnalysisCut("pairMassLow2")); return cut; } - if (!nameStr.compare("pairPtLow3")) { + if (nameStr == "pairPtLow3") { cut->AddCut(GetAnalysisCut("pairPtLow3")); return cut; } - if (!nameStr.compare("pairPtLow4")) { + if (nameStr == "pairPtLow4") { cut->AddCut(GetAnalysisCut("pairPtLow4")); return cut; } - if (!nameStr.compare("pairPtLow5")) { + if (nameStr == "pairPtLow5") { cut->AddCut(GetAnalysisCut("pairPtLow5")); return cut; } - if (!nameStr.compare("pairMassLow3")) { + if (nameStr == "pairMassLow3") { cut->AddCut(GetAnalysisCut("pairMassLow3")); return cut; } - if (!nameStr.compare("pairMassLow4")) { + if (nameStr == "pairMassLow4") { cut->AddCut(GetAnalysisCut("pairMassLow4")); return cut; } - if (!nameStr.compare("pairMassLow5")) { + if (nameStr == "pairMassLow5") { cut->AddCut(GetAnalysisCut("pairMassLow5")); return cut; } - if (!nameStr.compare("pairMassLow6")) { + if (nameStr == "pairMassLow6") { cut->AddCut(GetAnalysisCut("pairMassLow6")); return cut; } - if (!nameStr.compare("pairMassLow7")) { + if (nameStr == "pairMassLow7") { cut->AddCut(GetAnalysisCut("pairMassLow7")); return cut; } - if (!nameStr.compare("pairMassLow8")) { + if (nameStr == "pairMassLow8") { cut->AddCut(GetAnalysisCut("pairMassLow8")); return cut; } - if (!nameStr.compare("pairMassLow9")) { + if (nameStr == "pairMassLow9") { cut->AddCut(GetAnalysisCut("pairMassLow9")); return cut; } - if (!nameStr.compare("pairMassLow10")) { + if (nameStr == "pairMassLow10") { cut->AddCut(GetAnalysisCut("pairMassLow10")); return cut; } - if (!nameStr.compare("pairMassLow11")) { + if (nameStr == "pairMassLow11") { cut->AddCut(GetAnalysisCut("pairMassLow11")); return cut; } - if (!nameStr.compare("pairMassLow12")) { + if (nameStr == "pairMassLow12") { cut->AddCut(GetAnalysisCut("pairMassLow12")); return cut; } - if (!nameStr.compare("pairMass1to2")) { + if (nameStr == "pairMass1to2") { cut->AddCut(GetAnalysisCut("pairMass1to2")); return cut; } - if (!nameStr.compare("pairMassIMR")) { + if (nameStr == "pairMassIMR") { cut->AddCut(GetAnalysisCut("pairMassIMR")); return cut; } - if (!nameStr.compare("pairMass1_5to2_7")) { + if (nameStr == "pairMass1_5to2_7") { cut->AddCut(GetAnalysisCut("pairMass1_5to2_7")); return cut; } - if (!nameStr.compare("pairMass1_3to3_5")) { + if (nameStr == "pairMass1_3to3_5") { cut->AddCut(GetAnalysisCut("pairMass1_3to3_5")); return cut; } - if (!nameStr.compare("pairMass1_3")) { + if (nameStr == "pairMass1_3") { cut->AddCut(GetAnalysisCut("pairMass1_3")); return cut; } - if (!nameStr.compare("pairMass1_5to3_5")) { + if (nameStr == "pairMass1_5to3_5") { cut->AddCut(GetAnalysisCut("pairMass1_5to3_5")); return cut; } - if (!nameStr.compare("pairDalitz1")) { + if (nameStr == "pairDalitz1") { cut->AddCut(GetAnalysisCut("pairDalitz1")); return cut; } - if (!nameStr.compare("pairDalitz1Strong")) { + if (nameStr == "pairDalitz1Strong") { cut->AddCut(GetAnalysisCut("pairDalitz1Strong")); return cut; } - if (!nameStr.compare("pairDalitz2")) { + if (nameStr == "pairDalitz2") { cut->AddCut(GetAnalysisCut("pairDalitz2")); return cut; } - if (!nameStr.compare("pairDalitz3")) { + if (nameStr == "pairDalitz3") { cut->AddCut(GetAnalysisCut("pairDalitz3")); return cut; } - if (!nameStr.compare("paira_prefilter1")) { + if (nameStr == "paira_prefilter1") { cut->AddCut(GetAnalysisCut("paira_prefilter1")); return cut; } - if (!nameStr.compare("paira_prefilter2")) { + if (nameStr == "paira_prefilter2") { cut->AddCut(GetAnalysisCut("paira_prefilter2")); return cut; } - if (!nameStr.compare("paira_prefilter3")) { + if (nameStr == "paira_prefilter3") { cut->AddCut(GetAnalysisCut("paira_prefilter3")); return cut; } - if (!nameStr.compare("paira_prefilter4")) { + if (nameStr == "paira_prefilter4") { cut->AddCut(GetAnalysisCut("paira_prefilter4")); return cut; } - if (!nameStr.compare("paira_prefilter5")) { + if (nameStr == "paira_prefilter5") { cut->AddCut(GetAnalysisCut("paira_prefilter5")); return cut; } - if (!nameStr.compare("paira_prefilter6")) { + if (nameStr == "paira_prefilter6") { cut->AddCut(GetAnalysisCut("paira_prefilter6")); return cut; } - if (!nameStr.compare("paira_prefilter7")) { + if (nameStr == "paira_prefilter7") { cut->AddCut(GetAnalysisCut("paira_prefilter7")); return cut; } - if (!nameStr.compare("pairb_prefilter1")) { + if (nameStr == "pairb_prefilter1") { cut->AddCut(GetAnalysisCut("pairb_prefilter1")); return cut; } - if (!nameStr.compare("pairb_prefilter2")) { + if (nameStr == "pairb_prefilter2") { cut->AddCut(GetAnalysisCut("pairb_prefilter2")); return cut; } - if (!nameStr.compare("pairb_prefilter3")) { + if (nameStr == "pairb_prefilter3") { cut->AddCut(GetAnalysisCut("pairb_prefilter3")); return cut; } - if (!nameStr.compare("pairb_prefilter4")) { + if (nameStr == "pairb_prefilter4") { cut->AddCut(GetAnalysisCut("pairb_prefilter4")); return cut; } - if (!nameStr.compare("pairb_prefilter5")) { + if (nameStr == "pairb_prefilter5") { cut->AddCut(GetAnalysisCut("pairb_prefilter5")); return cut; } - if (!nameStr.compare("pairb_prefilter6")) { + if (nameStr == "pairb_prefilter6") { cut->AddCut(GetAnalysisCut("pairb_prefilter6")); return cut; } - if (!nameStr.compare("pairb_prefilter7")) { + if (nameStr == "pairb_prefilter7") { cut->AddCut(GetAnalysisCut("pairb_prefilter7")); return cut; } - if (!nameStr.compare("pairc_prefilter1")) { + if (nameStr == "pairc_prefilter1") { cut->AddCut(GetAnalysisCut("pairc_prefilter1")); return cut; } - if (!nameStr.compare("pairc_prefilter2")) { + if (nameStr == "pairc_prefilter2") { cut->AddCut(GetAnalysisCut("pairc_prefilter2")); return cut; } - if (!nameStr.compare("pairc_prefilter3")) { + if (nameStr == "pairc_prefilter3") { cut->AddCut(GetAnalysisCut("pairc_prefilter3")); return cut; } - if (!nameStr.compare("pairc_prefilter4")) { + if (nameStr == "pairc_prefilter4") { cut->AddCut(GetAnalysisCut("pairc_prefilter4")); return cut; } - if (!nameStr.compare("pairc_prefilter5")) { + if (nameStr == "pairc_prefilter5") { cut->AddCut(GetAnalysisCut("pairc_prefilter5")); return cut; } - if (!nameStr.compare("pairc_prefilter6")) { + if (nameStr == "pairc_prefilter6") { cut->AddCut(GetAnalysisCut("pairc_prefilter6")); return cut; } - if (!nameStr.compare("pairc_prefilter7")) { + if (nameStr == "pairc_prefilter7") { cut->AddCut(GetAnalysisCut("pairc_prefilter7")); return cut; } - if (!nameStr.compare("paird_prefilter1")) { + if (nameStr == "paird_prefilter1") { cut->AddCut(GetAnalysisCut("paird_prefilter1")); return cut; } - if (!nameStr.compare("paire_prefilter1")) { + if (nameStr == "paire_prefilter1") { cut->AddCut(GetAnalysisCut("paire_prefilter1")); return cut; } - if (!nameStr.compare("pairf_prefilter1")) { + if (nameStr == "pairf_prefilter1") { cut->AddCut(GetAnalysisCut("pairf_prefilter1")); return cut; } - if (!nameStr.compare("pairg_prefilter1")) { + if (nameStr == "pairg_prefilter1") { cut->AddCut(GetAnalysisCut("pairg_prefilter1")); return cut; } - if (!nameStr.compare("pairh_prefilter1")) { + if (nameStr == "pairh_prefilter1") { cut->AddCut(GetAnalysisCut("pairh_prefilter1")); return cut; } - if (!nameStr.compare("pairi_prefilter1")) { + if (nameStr == "pairi_prefilter1") { cut->AddCut(GetAnalysisCut("pairi_prefilter1")); return cut; } - if (!nameStr.compare("pairJpsi")) { + if (nameStr == "pairJpsi") { cut->AddCut(GetAnalysisCut("pairJpsi")); return cut; } - if (!nameStr.compare("pairJpsi2")) { + if (nameStr == "pairJpsi2") { cut->AddCut(GetAnalysisCut("pairJpsi2")); return cut; } - if (!nameStr.compare("pairJpsi3")) { + if (nameStr == "pairJpsi3") { cut->AddCut(GetAnalysisCut("pairJpsi3")); return cut; } - if (!nameStr.compare("pairPsi2S")) { + if (nameStr == "pairPsi2S") { cut->AddCut(GetAnalysisCut("pairPsi2S")); return cut; } - if (!nameStr.compare("pairUpsilon")) { + if (nameStr == "pairUpsilon") { cut->AddCut(GetAnalysisCut("pairUpsilon")); return cut; } - if (!nameStr.compare("pairX3872Cut1")) { + if (nameStr == "pairX3872Cut1") { cut->AddCut(GetAnalysisCut("pairX3872")); return cut; } - if (!nameStr.compare("pairX3872Cut2")) { + if (nameStr == "pairX3872Cut2") { cut->AddCut(GetAnalysisCut("pairX3872_2")); return cut; } - if (!nameStr.compare("pairX3872Cut3")) { + if (nameStr == "pairX3872Cut3") { cut->AddCut(GetAnalysisCut("pairX3872_3")); return cut; } - if (!nameStr.compare("DipionPairCut1")) { + if (nameStr == "DipionPairCut1") { cut->AddCut(GetAnalysisCut("DipionMassCut1")); return cut; } - if (!nameStr.compare("DipionPairCut2")) { + if (nameStr == "DipionPairCut2") { cut->AddCut(GetAnalysisCut("DipionMassCut2")); return cut; } - if (!nameStr.compare("pairRapidityForward")) { + if (nameStr == "pairRapidityForward") { cut->AddCut(GetAnalysisCut("pairRapidityForward")); return cut; } - if (!nameStr.compare("pairJpsiLowPt1")) { + if (nameStr == "pairJpsiLowPt1") { cut->AddCut(GetAnalysisCut("pairJpsi")); cut->AddCut(GetAnalysisCut("pairPtLow1")); return cut; } - if (!nameStr.compare("pairJpsiLowPt2")) { + if (nameStr == "pairJpsiLowPt2") { cut->AddCut(GetAnalysisCut("pairJpsi")); cut->AddCut(GetAnalysisCut("pairPtLow2")); return cut; } - if (!nameStr.compare("pairCoherentRho0")) { + if (nameStr == "pairCoherentRho0") { cut->AddCut(GetAnalysisCut("pairPtLow3")); return cut; } - if (!nameStr.compare("pairD0")) { + if (nameStr == "pairD0") { cut->AddCut(GetAnalysisCut("pairD0")); return cut; } - if (!nameStr.compare("pairD0HighPt1")) { + if (nameStr == "pairD0HighPt1") { cut->AddCut(GetAnalysisCut("pairLxyzProjected3sigma")); cut->AddCut(GetAnalysisCut("pairPtLow5")); return cut; } - if (!nameStr.compare("pairD0HighPt2")) { + if (nameStr == "pairD0HighPt2") { cut->AddCut(GetAnalysisCut("pairTauxyzProjected1")); cut->AddCut(GetAnalysisCut("pairPtLow5")); return cut; } - if (!nameStr.compare("pairD0HighPt3")) { + if (nameStr == "pairD0HighPt3") { cut->AddCut(GetAnalysisCut("pairTauxyzProjected1sigma")); cut->AddCut(GetAnalysisCut("pairPtLow5")); return cut; } - if (!nameStr.compare("pairTauxyzProjected1")) { + if (nameStr == "pairTauxyzProjected1") { cut->AddCut(GetAnalysisCut("pairTauxyzProjected1")); return cut; } - if (!nameStr.compare("pairLxyProjected3sigmaLambdacCand")) { + if (nameStr == "pairLxyProjected3sigmaLambdacCand") { cut->AddCut(GetAnalysisCut("pairLxyProjected3sigmaLambdacCand")); return cut; } - if (!nameStr.compare("pairLxyProjected3sigmaDplusCand")) { + if (nameStr == "pairLxyProjected3sigmaDplusCand") { cut->AddCut(GetAnalysisCut("pairLxyProjected3sigmaDplusCand")); return cut; } - if (!nameStr.compare("pairCosPointingPos")) { + if (nameStr == "pairCosPointingPos") { cut->AddCut(GetAnalysisCut("pairCosPointingPos")); return cut; } - if (!nameStr.compare("pairCosPointingNeg90")) { + if (nameStr == "pairCosPointingNeg90") { cut->AddCut(GetAnalysisCut("pairCosPointingNeg90")); return cut; } - if (!nameStr.compare("pairCosPointingNeg85")) { + if (nameStr == "pairCosPointingNeg85") { cut->AddCut(GetAnalysisCut("pairCosPointingNeg85")); return cut; } - if (!nameStr.compare("pairTauxyzProjectedCosPointing1")) { + if (nameStr == "pairTauxyzProjectedCosPointing1") { cut->AddCut(GetAnalysisCut("pairCosPointingNeg")); cut->AddCut(GetAnalysisCut("pairTauxyzProjected1")); return cut; @@ -3650,122 +3717,122 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) // Below are a list of single electron single muon and in order or optimize the trigger // trigger selection cuts - if (!nameStr.compare("jpsiO2TriggerTestCuts_LooseNsigma")) { + if (nameStr == "jpsiO2TriggerTestCuts_LooseNsigma") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTriggerTest")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaOpen")); return cut; } - if (!nameStr.compare("jpsiO2TriggerTestCuts_LooseNsigma_corr")) { + if (nameStr == "jpsiO2TriggerTestCuts_LooseNsigma_corr") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTriggerTest")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug5")); return cut; } - if (!nameStr.compare("jpsiO2TriggerTestCuts_MediumNsigma")) { + if (nameStr == "jpsiO2TriggerTestCuts_MediumNsigma") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTriggerTest")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaOpen")); return cut; } - if (!nameStr.compare("jpsiO2TriggerTestCuts_MediumNsigma_corr")) { + if (nameStr == "jpsiO2TriggerTestCuts_MediumNsigma_corr") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTriggerTest")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug1")); return cut; } - if (!nameStr.compare("jpsiO2TriggerTestCuts_TightNsigma")) { + if (nameStr == "jpsiO2TriggerTestCuts_TightNsigma") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTriggerTest")); cut->AddCut(GetAnalysisCut("electronPIDnsigma")); return cut; } - if (!nameStr.compare("jpsiO2TriggerTestCuts_TightNsigma_corr")) { + if (nameStr == "jpsiO2TriggerTestCuts_TightNsigma_corr") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTriggerTest")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_debug2")); return cut; } - if (!nameStr.compare("jpsiO2TriggerTestCuts_TPCPID1")) { + if (nameStr == "jpsiO2TriggerTestCuts_TPCPID1") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTriggerTest")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_TriggerTest1")); return cut; } - if (!nameStr.compare("jpsiO2TriggerTestCuts_TPCPID2")) { + if (nameStr == "jpsiO2TriggerTestCuts_TPCPID2") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTriggerTest")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_TriggerTest2")); return cut; } - if (!nameStr.compare("jpsiO2TriggerTestCuts_TPCPID3")) { + if (nameStr == "jpsiO2TriggerTestCuts_TPCPID3") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTriggerTest")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_TriggerTest3")); return cut; } - if (!nameStr.compare("jpsiO2TriggerTestCuts_TPCPID4")) { + if (nameStr == "jpsiO2TriggerTestCuts_TPCPID4") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronStandardQualityTriggerTest")); cut->AddCut(GetAnalysisCut("jpsi_TPCPID_TriggerTest4")); return cut; } - if (!nameStr.compare("emu_electron_test")) { + if (nameStr == "emu_electron_test") { cut->AddCut(GetAnalysisCut("jpsiStandardKine")); cut->AddCut(GetAnalysisCut("electronTrackQuality_Maolin")); cut->AddCut(GetAnalysisCut("electronPIDnsigmaEMu")); return cut; } - if (!nameStr.compare("muonLooseTriggerTestCuts")) { + if (nameStr == "muonLooseTriggerTestCuts") { cut->AddCut(GetAnalysisCut("muonLooseTriggerTestCuts")); return cut; } - if (!nameStr.compare("muonLooseTriggerTestCuts_LowPt")) { + if (nameStr == "muonLooseTriggerTestCuts_LowPt") { cut->AddCut(GetAnalysisCut("muonLowPt")); cut->AddCut(GetAnalysisCut("muonLooseTriggerTestCuts")); return cut; } - if (!nameStr.compare("muonLooseTriggerTestCuts_HighPt2")) { + if (nameStr == "muonLooseTriggerTestCuts_HighPt2") { cut->AddCut(GetAnalysisCut("muonHighPt2")); cut->AddCut(GetAnalysisCut("muonLooseTriggerTestCuts")); return cut; } - if (!nameStr.compare("muonLooseTriggerTestCuts_HighPt3")) { + if (nameStr == "muonLooseTriggerTestCuts_HighPt3") { cut->AddCut(GetAnalysisCut("muonHighPt3")); cut->AddCut(GetAnalysisCut("muonLooseTriggerTestCuts")); return cut; } - if (!nameStr.compare("muonHighPtMatchingOnly2")) { + if (nameStr == "muonHighPtMatchingOnly2") { cut->AddCut(GetAnalysisCut("muonHighPt2")); cut->AddCut(GetAnalysisCut("muonQualityCutsMatchingOnly")); return cut; } - if (!nameStr.compare("muonHighPtMatchingOnly3")) { + if (nameStr == "muonHighPtMatchingOnly3") { cut->AddCut(GetAnalysisCut("muonHighPt3")); cut->AddCut(GetAnalysisCut("muonQualityCutsMatchingOnly")); return cut; } - if (!nameStr.compare("muonMatchingMFTMCHTriggerTestCuts")) { + if (nameStr == "muonMatchingMFTMCHTriggerTestCuts") { cut->AddCut(GetAnalysisCut("muonMatchingMFTMCHTriggerTestCuts")); return cut; } - if (!nameStr.compare("muonMatchingMFTMCHTriggerTestCuts_LowPt")) { + if (nameStr == "muonMatchingMFTMCHTriggerTestCuts_LowPt") { cut->AddCut(GetAnalysisCut("muonLowPt")); cut->AddCut(GetAnalysisCut("muonMatchingMFTMCHTriggerTestCuts")); return cut; @@ -3774,175 +3841,175 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) //--------------------------------------------------------------- // ALICE 3 studies composite cuts - if (!nameStr.compare("alice3StandardKine")) { + if (nameStr == "alice3StandardKine") { cut->AddCut(GetAnalysisCut("alice3StandardKine")); return cut; } - if (!nameStr.compare("alice3KineSkim")) { + if (nameStr == "alice3KineSkim") { cut->AddCut(GetAnalysisCut("alice3KineSkim")); return cut; } - if (!nameStr.compare("alice3TrackQuality")) { + if (nameStr == "alice3TrackQuality") { cut->AddCut(GetAnalysisCut("alice3TrackQuality")); return cut; } - if (!nameStr.compare("alice3TrackQualityTightDCA")) { + if (nameStr == "alice3TrackQualityTightDCA") { cut->AddCut(GetAnalysisCut("alice3TrackQuality")); return cut; } - if (!nameStr.compare("alice3StandardTrack")) { + if (nameStr == "alice3StandardTrack") { cut->AddCut(GetAnalysisCut("alice3StandardKine")); cut->AddCut(GetAnalysisCut("alice3TrackQuality")); return cut; } - if (!nameStr.compare("alice3StandardTrackTOFAcceptance")) { + if (nameStr == "alice3StandardTrackTOFAcceptance") { cut->AddCut(GetAnalysisCut("alice3KineTOFAcceptance")); cut->AddCut(GetAnalysisCut("alice3TrackQuality")); return cut; } - if (!nameStr.compare("alice3StandardTrackRICHAcceptance")) { + if (nameStr == "alice3StandardTrackRICHAcceptance") { cut->AddCut(GetAnalysisCut("alice3KineRICHAcceptance")); cut->AddCut(GetAnalysisCut("alice3TrackQuality")); return cut; } - if (!nameStr.compare("alice3TightDCATrack")) { + if (nameStr == "alice3TightDCATrack") { cut->AddCut(GetAnalysisCut("alice3StandardKine")); cut->AddCut(GetAnalysisCut("alice3TrackQualityTightDCA")); return cut; } - if (!nameStr.compare("alice3TightDCATrackTOFAcceptance")) { + if (nameStr == "alice3TightDCATrackTOFAcceptance") { cut->AddCut(GetAnalysisCut("alice3KineTOFAcceptance")); cut->AddCut(GetAnalysisCut("alice3TrackQualityTightDCA")); return cut; } - if (!nameStr.compare("alice3TightDCATrackRICHAcceptance")) { + if (nameStr == "alice3TightDCATrackRICHAcceptance") { cut->AddCut(GetAnalysisCut("alice3KineRICHAcceptance")); cut->AddCut(GetAnalysisCut("alice3TrackQualityTightDCA")); return cut; } - if (!nameStr.compare("alice3iTOFPIDEl")) { + if (nameStr == "alice3iTOFPIDEl") { cut->AddCut(GetAnalysisCut("alice3iTOFPIDEl")); return cut; } - if (!nameStr.compare("alice3iTOFPIDPi")) { + if (nameStr == "alice3iTOFPIDPi") { cut->AddCut(GetAnalysisCut("alice3iTOFPIDPi")); return cut; } - if (!nameStr.compare("alice3iTOFPIDKa")) { + if (nameStr == "alice3iTOFPIDKa") { cut->AddCut(GetAnalysisCut("alice3iTOFPIDKa")); return cut; } - if (!nameStr.compare("alice3iTOFPIDPr")) { + if (nameStr == "alice3iTOFPIDPr") { cut->AddCut(GetAnalysisCut("alice3iTOFPIDPr")); return cut; } - if (!nameStr.compare("alice3oTOFPIDEl")) { + if (nameStr == "alice3oTOFPIDEl") { cut->AddCut(GetAnalysisCut("alice3oTOFPIDEl")); return cut; } - if (!nameStr.compare("alice3oTOFPIDPi")) { + if (nameStr == "alice3oTOFPIDPi") { cut->AddCut(GetAnalysisCut("alice3oTOFPIDPi")); return cut; } - if (!nameStr.compare("alice3oTOFPIDKa")) { + if (nameStr == "alice3oTOFPIDKa") { cut->AddCut(GetAnalysisCut("alice3oTOFPIDKa")); return cut; } - if (!nameStr.compare("alice3oTOFPIDPr")) { + if (nameStr == "alice3oTOFPIDPr") { cut->AddCut(GetAnalysisCut("alice3oTOFPIDPr")); return cut; } - if (!nameStr.compare("alice3FullTOFPIDEl")) { + if (nameStr == "alice3FullTOFPIDEl") { cut->AddCut(GetAnalysisCut("alice3iTOFPIDEl")); cut->AddCut(GetAnalysisCut("alice3oTOFPIDEl")); return cut; } - if (!nameStr.compare("alice3FullTOFPIDPi")) { + if (nameStr == "alice3FullTOFPIDPi") { cut->AddCut(GetAnalysisCut("alice3iTOFPIDPi")); cut->AddCut(GetAnalysisCut("alice3oTOFPIDPi")); return cut; } - if (!nameStr.compare("alice3FullTOFPIDKa")) { + if (nameStr == "alice3FullTOFPIDKa") { cut->AddCut(GetAnalysisCut("alice3iTOFPIDKa")); cut->AddCut(GetAnalysisCut("alice3oTOFPIDKa")); return cut; } - if (!nameStr.compare("alice3FullTOFPIDPr")) { + if (nameStr == "alice3FullTOFPIDPr") { cut->AddCut(GetAnalysisCut("alice3iTOFPIDPr")); cut->AddCut(GetAnalysisCut("alice3oTOFPIDPr")); return cut; } - if (!nameStr.compare("alice3RICHPIDEl")) { + if (nameStr == "alice3RICHPIDEl") { cut->AddCut(GetAnalysisCut("alice3RICHPIDEl")); return cut; } - if (!nameStr.compare("alice3RICHPIDPi")) { + if (nameStr == "alice3RICHPIDPi") { cut->AddCut(GetAnalysisCut("alice3RICHPIDPi")); return cut; } - if (!nameStr.compare("alice3RICHPIDKa")) { + if (nameStr == "alice3RICHPIDKa") { cut->AddCut(GetAnalysisCut("alice3RICHPIDKa")); return cut; } - if (!nameStr.compare("alice3RICHPIDPr")) { + if (nameStr == "alice3RICHPIDPr") { cut->AddCut(GetAnalysisCut("alice3RICHPIDPr")); return cut; } - if (!nameStr.compare("alice3RICHTOFPIDEl")) { + if (nameStr == "alice3RICHTOFPIDEl") { cut->AddCut(GetAnalysisCut("alice3iTOFPIDEl")); cut->AddCut(GetAnalysisCut("alice3oTOFPIDEl")); cut->AddCut(GetAnalysisCut("alice3RICHPIDEl")); return cut; } - if (!nameStr.compare("alice3RICHTOFPIDPi")) { + if (nameStr == "alice3RICHTOFPIDPi") { cut->AddCut(GetAnalysisCut("alice3iTOFPIDPi")); cut->AddCut(GetAnalysisCut("alice3oTOFPIDPi")); cut->AddCut(GetAnalysisCut("alice3RICHPIDPi")); return cut; } - if (!nameStr.compare("alice3RICHTOFPIDKa")) { + if (nameStr == "alice3RICHTOFPIDKa") { cut->AddCut(GetAnalysisCut("alice3iTOFPIDKa")); cut->AddCut(GetAnalysisCut("alice3oTOFPIDKa")); cut->AddCut(GetAnalysisCut("alice3RICHPIDKa")); return cut; } - if (!nameStr.compare("alice3RICHTOFPIDPr")) { + if (nameStr == "alice3RICHTOFPIDPr") { cut->AddCut(GetAnalysisCut("alice3iTOFPIDPr")); cut->AddCut(GetAnalysisCut("alice3oTOFPIDPr")); cut->AddCut(GetAnalysisCut("alice3RICHPIDPr")); return cut; } - if (!nameStr.compare("alice3DielectronPID")) { + if (nameStr == "alice3DielectronPID") { cut->AddCut(GetAnalysisCut("alice3JpsiKine")); cut->AddCut(GetAnalysisCut("alice3TrackQuality")); cut->AddCut(GetAnalysisCut("alice3iTOFPIDEl")); @@ -3951,7 +4018,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("alice3DielectronPIDTOFOnly")) { + if (nameStr == "alice3DielectronPIDTOFOnly") { cut->AddCut(GetAnalysisCut("alice3JpsiKineTOFAcceptance")); cut->AddCut(GetAnalysisCut("alice3TrackQuality")); cut->AddCut(GetAnalysisCut("alice3iTOFPIDEl")); @@ -3959,7 +4026,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("alice3DielectronPIDRICHOnly")) { + if (nameStr == "alice3DielectronPIDRICHOnly") { cut->AddCut(GetAnalysisCut("alice3JpsiKineTOFAcceptance")); cut->AddCut(GetAnalysisCut("alice3TrackQuality")); cut->AddCut(GetAnalysisCut("alice3iTOFPIDEl")); @@ -3967,7 +4034,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("alice3DielectronPIDTOFOnly")) { + if (nameStr == "alice3DielectronPIDTOFOnly") { cut->AddCut(GetAnalysisCut("alice3JpsiKine")); cut->AddCut(GetAnalysisCut("alice3TrackQuality")); cut->AddCut(GetAnalysisCut("alice3iTOFPIDEl")); @@ -3975,7 +4042,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("alice3DielectronPIDTOFAcceptance")) { + if (nameStr == "alice3DielectronPIDTOFAcceptance") { cut->AddCut(GetAnalysisCut("alice3JpsiKineTOFAcceptance")); cut->AddCut(GetAnalysisCut("alice3TrackQuality")); cut->AddCut(GetAnalysisCut("alice3iTOFPIDEl")); @@ -3984,7 +4051,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("alice3DielectronPIDRICHAcceptance")) { + if (nameStr == "alice3DielectronPIDRICHAcceptance") { cut->AddCut(GetAnalysisCut("alice3JpsiKineRICHAcceptance")); cut->AddCut(GetAnalysisCut("alice3TrackQuality")); cut->AddCut(GetAnalysisCut("alice3iTOFPIDEl")); @@ -4003,50 +4070,50 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) // // define here cuts which are likely to be used often // - AnalysisCut* cut = new AnalysisCut(cutName, cutName); + auto* cut = new AnalysisCut(cutName, cutName); std::string nameStr = cutName; // --------------------------------------------------------------- // Event cuts - if (!nameStr.compare("noEventCut")) { + if (nameStr == "noEventCut") { return cut; } - if (!nameStr.compare("eventNoTFBorder")) { + if (nameStr == "eventNoTFBorder") { cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventIsTVXTriggered")) { + if (nameStr == "eventIsTVXTriggered") { cut->AddCut(VarManager::kIsTVXTriggered, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventStandard")) { + if (nameStr == "eventStandard") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsINT7, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventStandardNoINT7")) { + if (nameStr == "eventStandardNoINT7") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); return cut; } - if (!nameStr.compare("eventStandardtest")) { + if (nameStr == "eventStandardtest") { cut->AddCut(VarManager::kVtxZ, -30.0, 30.0); return cut; } - if (!nameStr.compare("eventSel8")) { // kIsSel8 = kIsTriggerTVX && kNoITSROFrameBorder && kNoTimeFrameBorder + if (nameStr == "eventSel8") { // kIsSel8 = kIsTriggerTVX && kNoITSROFrameBorder && kNoTimeFrameBorder cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventStandardSel8")) { // kIsSel8 = kIsTriggerTVX && kNoITSROFrameBorder && kNoTimeFrameBorder + if (nameStr == "eventStandardSel8") { // kIsSel8 = kIsTriggerTVX && kNoITSROFrameBorder && kNoTimeFrameBorder cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventStandardSel8WithITSROFRecomputedCut")) { + if (nameStr == "eventStandardSel8WithITSROFRecomputedCut") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4054,14 +4121,14 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventStandardSel8NoTFBorder")) { // Redundant w.r.t. eventStandardSel8, to be removed + if (nameStr == "eventStandardSel8NoTFBorder") { // Redundant w.r.t. eventStandardSel8, to be removed cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventStandardSel8NoTFBNoITSROFB")) { // Redundant w.r.t. eventStandardSel8, to be removed + if (nameStr == "eventStandardSel8NoTFBNoITSROFB") { // Redundant w.r.t. eventStandardSel8, to be removed cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4069,7 +4136,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventStandardSel8NoTFBNoITSROFBrecomp")) { + if (nameStr == "eventStandardSel8NoTFBNoITSROFBrecomp") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4077,33 +4144,33 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventSel8NoSameBunch")) { + if (nameStr == "eventSel8NoSameBunch") { cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoSameBunch, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventSel8TriggerZNAZNC")) { + if (nameStr == "eventSel8TriggerZNAZNC") { cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsTriggerZNAZNC, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventSel8TriggerZNAZNCNoPileUp")) { + if (nameStr == "eventSel8TriggerZNAZNCNoPileUp") { cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsTriggerZNAZNC, 0.5, 1.5); cut->AddCut(VarManager::kIsNoSameBunch, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventSel8NoSameBunchGoodZvtx")) { + if (nameStr == "eventSel8NoSameBunchGoodZvtx") { cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoSameBunch, 0.5, 1.5); cut->AddCut(VarManager::kIsGoodZvtxFT0vsPV, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventStandardSel8PbPbQuality")) { + if (nameStr == "eventStandardSel8PbPbQuality") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4113,7 +4180,16 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventStandardSel8PbPbQualityCent90")) { + if (nameStr == "eventStandardSel8NoPileup") { + cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); + cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); + cut->AddCut(VarManager::kIsNoSameBunch, 0.5, 1.5); + cut->AddCut(VarManager::kIsGoodZvtxFT0vsPV, 0.5, 1.5); + cut->AddCut(VarManager::kNoCollInTimeRangeStandard, 0.5, 1.5); + return cut; + } + + if (nameStr == "eventStandardSel8PbPbQualityCent90") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4124,7 +4200,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventStandardSel8PbPbQualityGoodITSLayersAll")) { // kIsSel8 = kIsTriggerTVX && kNoITSROFrameBorder && kNoTimeFrameBorder + if (nameStr == "eventStandardSel8PbPbQualityGoodITSLayersAll") { // kIsSel8 = kIsTriggerTVX && kNoITSROFrameBorder && kNoTimeFrameBorder cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4135,7 +4211,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventStandardSel8PbPbQualityTightTrackOccupancy")) { + if (nameStr == "eventStandardSel8PbPbQualityTightTrackOccupancy") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4147,7 +4223,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventStandardSel8PbPbQualityFirmTrackOccupancy")) { + if (nameStr == "eventStandardSel8PbPbQualityFirmTrackOccupancy") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4160,7 +4236,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventStandardSel8PbPbQualityLooseTrackOccupancy")) { + if (nameStr == "eventStandardSel8PbPbQualityLooseTrackOccupancy") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4173,7 +4249,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventStandardSel8PbPbQualityTightTrackOccupancyCollInTime")) { + if (nameStr == "eventStandardSel8PbPbQualityTightTrackOccupancyCollInTime") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4187,7 +4263,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventStandardSel8PbPbQualityTightTrackOccupancyCollInTime")) { + if (nameStr == "eventStandardSel8PbPbQualityTightTrackOccupancyCollInTime") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4216,7 +4292,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) 50000.}; for (size_t icase = 0; icase < vecOccupancies.size() - 1; icase++) { - if (!nameStr.compare(Form("eventStandardSel8PbPbQualityTrackOccupancySlice%lu", icase))) { + if (nameStr == Form("eventStandardSel8PbPbQualityTrackOccupancySlice%lu", icase)) { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4231,7 +4307,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) } for (size_t icase = 0; icase < vecOccupancies.size() - 1; icase++) { - if (!nameStr.compare(Form("eventStandardSel8PbPbQualityTrackOccupancySlice_0_%lu", icase))) { + if (nameStr == Form("eventStandardSel8PbPbQualityTrackOccupancySlice_0_%lu", icase)) { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4245,7 +4321,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) } } - if (!nameStr.compare("eventStandardSel8ppQuality")) { + if (nameStr == "eventStandardSel8ppQuality") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4257,7 +4333,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventStandardSel8ppQualityNoVtxZ")) { + if (nameStr == "eventStandardSel8ppQualityNoVtxZ") { cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); cut->AddCut(VarManager::kIsNoITSROFBorder, 0.5, 1.5); @@ -4268,7 +4344,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventStandardSel8multAnalysis")) { + if (nameStr == "eventStandardSel8multAnalysis") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); @@ -4278,7 +4354,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventStandardSel8VtxQuality1")) { // kIsSel8 = kIsTriggerTVX && kNoITSROFrameBorder && kNoTimeFrameBorder + if (nameStr == "eventStandardSel8VtxQuality1") { // kIsSel8 = kIsTriggerTVX && kNoITSROFrameBorder && kNoTimeFrameBorder cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); cut->AddCut(VarManager::kIsNoSameBunch, 0.5, 1.5); @@ -4287,7 +4363,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventStandardSel8PbPbMultCorr")) { + if (nameStr == "eventStandardSel8PbPbMultCorr") { std::shared_ptr fMultPVCutLow = std::make_shared("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x - 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); fMultPVCutLow->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); std::shared_ptr fMultPVCutHigh = std::make_shared("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x + 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); @@ -4306,165 +4382,165 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("eventDimuonStandard")) { + if (nameStr == "eventDimuonStandard") { cut->AddCut(VarManager::kIsMuonUnlikeLowPt7, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventMuonStandard")) { + if (nameStr == "eventMuonStandard") { cut->AddCut(VarManager::kIsMuonSingleLowPt7, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventTPCMultLow")) { + if (nameStr == "eventTPCMultLow") { cut->AddCut(VarManager::kMultTPC, 0, 50); return cut; } - if (!nameStr.compare("eventExclusivePair")) { + if (nameStr == "eventExclusivePair") { cut->AddCut(VarManager::kVtxNcontrib, 2, 2); return cut; } - if (!nameStr.compare("eventVtxNContrib")) { + if (nameStr == "eventVtxNContrib") { cut->AddCut(VarManager::kVtxNcontrib, 0, 10); return cut; } - if (!nameStr.compare("eventTPCMult3")) { + if (nameStr == "eventTPCMult3") { cut->AddCut(VarManager::kMultTPC, 3, 3); return cut; } - if (!nameStr.compare("int7vtxZ5")) { + if (nameStr == "int7vtxZ5") { cut->AddCut(VarManager::kVtxZ, -5.0, 5.0); cut->AddCut(VarManager::kIsINT7, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventDoubleGap")) { + if (nameStr == "eventDoubleGap") { cut->AddCut(VarManager::kIsDoubleGap, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventSingleGap")) { + if (nameStr == "eventSingleGap") { cut->AddCut(VarManager::kIsSingleGap, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventSingleGapA")) { + if (nameStr == "eventSingleGapA") { cut->AddCut(VarManager::kIsSingleGapA, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventSingleGapAZDC")) { + if (nameStr == "eventSingleGapAZDC") { cut->AddCut(VarManager::kIsSingleGapA, 0.5, 1.5); cut->AddCut(VarManager::kEnergyCommonZNA, -1000., 1.); cut->AddCut(VarManager::kEnergyCommonZNC, 1., 1000.); return cut; } - if (!nameStr.compare("eventSingleGapC")) { + if (nameStr == "eventSingleGapC") { cut->AddCut(VarManager::kIsSingleGapC, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventSingleGapCZDC")) { + if (nameStr == "eventSingleGapCZDC") { cut->AddCut(VarManager::kIsSingleGapC, 0.5, 1.5); cut->AddCut(VarManager::kEnergyCommonZNC, -1000., 1.); cut->AddCut(VarManager::kEnergyCommonZNA, 1., 1000.); return cut; } - if (!nameStr.compare("eventSingleGapACZDC")) { - AnalysisCompositeCut* cutA = new AnalysisCompositeCut("singleGapAZDC", "singleGapAZDC", kTRUE); + if (nameStr == "eventSingleGapACZDC") { + auto* cutA = new AnalysisCompositeCut("singleGapAZDC", "singleGapAZDC", kTRUE); cutA->AddCut(GetAnalysisCut("eventSingleGapAZDC")); - AnalysisCompositeCut* cutC = new AnalysisCompositeCut("singleGapCZDC", "singleGapCZDC", kTRUE); + auto* cutC = new AnalysisCompositeCut("singleGapCZDC", "singleGapCZDC", kTRUE); cutC->AddCut(GetAnalysisCut("eventSingleGapCZDC")); - AnalysisCompositeCut* cutAorC = new AnalysisCompositeCut("singleGapACZDC", "singleGapACZDC", kFALSE); + auto* cutAorC = new AnalysisCompositeCut("singleGapACZDC", "singleGapACZDC", kFALSE); cutAorC->AddCut(cutA); cutAorC->AddCut(cutC); return cutAorC; } - if (!nameStr.compare("eventUPCMode")) { + if (nameStr == "eventUPCMode") { cut->AddCut(VarManager::kIsITSUPCMode, 0.5, 1.5); return cut; } - if (!nameStr.compare("eventSingleGapACZDC_UPCMode")) { - AnalysisCompositeCut* cutA = new AnalysisCompositeCut("singleGapAZDC", "singleGapAZDC", kTRUE); + if (nameStr == "eventSingleGapACZDC_UPCMode") { + auto* cutA = new AnalysisCompositeCut("singleGapAZDC", "singleGapAZDC", kTRUE); cutA->AddCut(GetAnalysisCut("eventSingleGapAZDC")); cutA->AddCut(GetAnalysisCut("eventUPCMode")); - AnalysisCompositeCut* cutC = new AnalysisCompositeCut("singleGapCZDC", "singleGapCZDC", kTRUE); + auto* cutC = new AnalysisCompositeCut("singleGapCZDC", "singleGapCZDC", kTRUE); cutC->AddCut(GetAnalysisCut("eventSingleGapCZDC")); cutC->AddCut(GetAnalysisCut("eventUPCMode")); - AnalysisCompositeCut* cutAorC = new AnalysisCompositeCut("singleGapACZDC", "singleGapACZDC", kFALSE); + auto* cutAorC = new AnalysisCompositeCut("singleGapACZDC", "singleGapACZDC", kFALSE); cutAorC->AddCut(cutA); cutAorC->AddCut(cutC); return cutAorC; } - if (!nameStr.compare("eventXn0nTime")) { + if (nameStr == "eventXn0nTime") { cut->AddCut(VarManager::kTimeZNA, -2.0, 2.0); cut->AddCut(VarManager::kTimeZNC, -2.0, 2.0, true); return cut; } - if (!nameStr.compare("event0nXnTime")) { + if (nameStr == "event0nXnTime") { cut->AddCut(VarManager::kTimeZNA, -2.0, 2.0, true); cut->AddCut(VarManager::kTimeZNC, -2.0, 2.0); return cut; } - if (!nameStr.compare("event0n0nTime")) { + if (nameStr == "event0n0nTime") { cut->AddCut(VarManager::kTimeZNA, -2.0, 2.0, true); cut->AddCut(VarManager::kTimeZNC, -2.0, 2.0, true); return cut; } - if (!nameStr.compare("eventXnXnTime")) { + if (nameStr == "eventXnXnTime") { cut->AddCut(VarManager::kTimeZNA, -2.0, 2.0); cut->AddCut(VarManager::kTimeZNC, -2.0, 2.0); return cut; } // Event cuts based on centrality - if (!nameStr.compare("eventStandardNoINT7Cent090")) { + if (nameStr == "eventStandardNoINT7Cent090") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kCentFT0C, 0.0, 90.0); return cut; } - if (!nameStr.compare("eventStandardNoINT7Cent7090")) { + if (nameStr == "eventStandardNoINT7Cent7090") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kCentFT0C, 70.0, 90.0); return cut; } - if (!nameStr.compare("eventStandardNoINT7Cent5070")) { + if (nameStr == "eventStandardNoINT7Cent5070") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kCentFT0C, 50.0, 70.0); return cut; } - if (!nameStr.compare("eventStandardNoINT7Cent3050")) { + if (nameStr == "eventStandardNoINT7Cent3050") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kCentFT0C, 30.0, 50.0); return cut; } - if (!nameStr.compare("eventStandardNoINT7Cent1030")) { + if (nameStr == "eventStandardNoINT7Cent1030") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kCentFT0C, 10.0, 30.0); return cut; } - if (!nameStr.compare("eventStandardNoINT7Cent010")) { + if (nameStr == "eventStandardNoINT7Cent010") { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kCentFT0C, 0.0, 10.0); return cut; @@ -4472,174 +4548,180 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) // --------------------------------------------------- // Barrel track kine cuts - if (!nameStr.compare("negTrack")) { + if (nameStr == "negTrack") { cut->AddCut(VarManager::kCharge, -99., 0.); return cut; } - if (!nameStr.compare("posTrack")) { + if (nameStr == "posTrack") { cut->AddCut(VarManager::kCharge, 0., 99.); return cut; } - if (!nameStr.compare("posEtaSel")) { + if (nameStr == "posEtaSel") { cut->AddCut(VarManager::kEta, 0., 0.8); return cut; } - if (!nameStr.compare("negEtaSel")) { + if (nameStr == "negEtaSel") { cut->AddCut(VarManager::kEta, -0.8, 0.); return cut; } - if (!nameStr.compare("etaSel")) { + if (nameStr == "etaSel") { cut->AddCut(VarManager::kEta, -0.8, 0.8); return cut; } - if (!nameStr.compare("pt02Sel")) { + if (nameStr == "pt02Sel") { cut->AddCut(VarManager::kPt, 0.2, 20.0); return cut; } - if (!nameStr.compare("pt04Sel")) { + if (nameStr == "pt04Sel") { cut->AddCut(VarManager::kPt, 0.4, 20.0); return cut; } - if (!nameStr.compare("openEtaSel")) { + if (nameStr == "openEtaSel") { cut->AddCut(VarManager::kEta, -0.9, 0.9); return cut; } - if (!nameStr.compare("insideTPCsector")) { + if (nameStr == "insideTPCsector") { cut->AddCut(VarManager::kTrackIsInsideTPCModule, 0.5, 1.5); return cut; } - if (!nameStr.compare("rho0Kine")) { + if (nameStr == "rho0Kine") { cut->AddCut(VarManager::kPt, 0.1, 1000.0); cut->AddCut(VarManager::kEta, -1.1, 1.1); return cut; } - if (!nameStr.compare("pionQuality")) { + if (nameStr == "pionQuality") { cut->AddCut(VarManager::kTPCncls, 50.0, 1000.); return cut; } - if (!nameStr.compare("primaryVertexContributor")) { + if (nameStr == "primaryVertexContributor") { cut->AddCut(VarManager::kPVContributor, 0.5, 1.5); return cut; } - if (!nameStr.compare("jpsiStandardKine")) { + if (nameStr == "jpsiStandardKine") { cut->AddCut(VarManager::kPt, 1.0, 1000.0); cut->AddCut(VarManager::kEta, -0.9, 0.9); return cut; } - if (!nameStr.compare("jpsiStandardKine2")) { + if (nameStr == "jpsiStandardKine2") { cut->AddCut(VarManager::kPt, 0.9, 1000.0); cut->AddCut(VarManager::kEta, -0.9, 0.9); return cut; } - if (!nameStr.compare("jpsiStandardKine3")) { + if (nameStr == "jpsiStandardKine3") { cut->AddCut(VarManager::kP, 1.2, 1000.0); cut->AddCut(VarManager::kEta, -0.9, 0.9); return cut; } - if (!nameStr.compare("jpsiPIDcalibKine_posEta")) { + if (nameStr == "jpsiPIDcalibKine_posEta") { cut->AddCut(VarManager::kPin, 1.0, 1000.0); cut->AddCut(VarManager::kEta, 0.0, 0.9); return cut; } - if (!nameStr.compare("jpsiPIDcalibKine_negEta")) { + if (nameStr == "jpsiPIDcalibKine_negEta") { cut->AddCut(VarManager::kPin, 1.0, 1000.0); cut->AddCut(VarManager::kEta, -0.9, 0.0); return cut; } - if (!nameStr.compare("jpsiStandardKine4")) { + if (nameStr == "jpsiStandardKine4") { cut->AddCut(VarManager::kP, 1.5, 1000.0); cut->AddCut(VarManager::kEta, -0.9, 0.9); return cut; } - if (!nameStr.compare("jpsiKineSkimmed")) { + if (nameStr == "jpsiStandardKine5") { + cut->AddCut(VarManager::kP, 1.0, 1000.0); + cut->AddCut(VarManager::kEta, -0.9, 0.9); + return cut; + } + + if (nameStr == "jpsiKineSkimmed") { cut->AddCut(VarManager::kPt, 0.7, 1000.0); cut->AddCut(VarManager::kEta, -0.9, 0.9); return cut; } - if (!nameStr.compare("jpsiKineSkimmed")) { + if (nameStr == "jpsiKineSkimmed") { cut->AddCut(VarManager::kPt, 0.7, 1000.0); cut->AddCut(VarManager::kEta, -0.9, 0.9); return cut; } - if (!nameStr.compare("lmeePrefilterKine")) { + if (nameStr == "lmeePrefilterKine") { cut->AddCut(VarManager::kPt, 0., 20.0); cut->AddCut(VarManager::kEta, -1.2, 1.2); return cut; } - if (!nameStr.compare("lmeeStandardKine")) { + if (nameStr == "lmeeStandardKine") { cut->AddCut(VarManager::kPt, 0.2, 20.0); cut->AddCut(VarManager::kEta, -0.8, 0.8); return cut; } - if (!nameStr.compare("lmeeStandardKine_pt04")) { + if (nameStr == "lmeeStandardKine_pt04") { cut->AddCut(VarManager::kPt, 0.4, 20.0); cut->AddCut(VarManager::kEta, -0.8, 0.8); return cut; } - if (!nameStr.compare("lmeeLowBKine")) { + if (nameStr == "lmeeLowBKine") { cut->AddCut(VarManager::kPt, 0.075, 20.0); cut->AddCut(VarManager::kEta, -0.8, 0.8); return cut; } - if (!nameStr.compare("dalitzStandardKine")) { + if (nameStr == "dalitzStandardKine") { cut->AddCut(VarManager::kPt, 0.15, 1000.0); cut->AddCut(VarManager::kEta, -0.9, 0.9); return cut; } - if (!nameStr.compare("PIDStandardKine")) { + if (nameStr == "PIDStandardKine") { cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kPt, 1.0, 1000.0); return cut; } - if (!nameStr.compare("PIDStandardKine2")) { + if (nameStr == "PIDStandardKine2") { cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kPt, 0.1, 1000.0); return cut; } - if (!nameStr.compare("PIDStandardKine3")) { + if (nameStr == "PIDStandardKine3") { cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kPt, 0.5, 1000.0); return cut; } - if (!nameStr.compare("pTLow04")) { + if (nameStr == "pTLow04") { cut->AddCut(VarManager::kPt, 0.4, 1000.0); return cut; } - if (!nameStr.compare("pTLow03")) { + if (nameStr == "pTLow03") { cut->AddCut(VarManager::kPt, 0.3, 1000.0); return cut; } - if (!nameStr.compare("pTLow02")) { + if (nameStr == "pTLow02") { cut->AddCut(VarManager::kPt, 0.2, 1000.0); return cut; } @@ -4650,17 +4732,17 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) // --------------------------------------------------- // MC generated particle acceptance cuts - if (!nameStr.compare("rapidity08")) { + if (nameStr == "rapidity08") { cut->AddCut(VarManager::kMCY, -0.8, 0.8); return cut; } - if (!nameStr.compare("rapidity09")) { + if (nameStr == "rapidity09") { cut->AddCut(VarManager::kMCY, -0.9, 0.9); return cut; } - if (!nameStr.compare("acceptance_pp13600")) { + if (nameStr == "acceptance_pp13600") { cut->AddCut(VarManager::kMCY, -0.8, 0.8); cut->AddCut(VarManager::kMCPt1, 1.0, 1000.0); cut->AddCut(VarManager::kMCPt2, 1.0, 1000.0); @@ -4669,7 +4751,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("acceptance_pp5360")) { + if (nameStr == "acceptance_pp5360") { cut->AddCut(VarManager::kMCY, -0.9, 0.9); cut->AddCut(VarManager::kMCPt1, 1.0, 1000.0); cut->AddCut(VarManager::kMCPt2, 1.0, 1000.0); @@ -4678,7 +4760,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("acceptance_PbPb5360")) { + if (nameStr == "acceptance_PbPb5360") { cut->AddCut(VarManager::kMCY, -0.9, 0.9); cut->AddCut(VarManager::kMCP1, 1.0, 1000.0); cut->AddCut(VarManager::kMCP2, 1.0, 1000.0); @@ -4687,7 +4769,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("acceptance_PbPb5360_y08")) { + if (nameStr == "acceptance_PbPb5360_y08") { cut->AddCut(VarManager::kMCY, -0.8, 0.8); cut->AddCut(VarManager::kMCP1, 1.0, 1000.0); cut->AddCut(VarManager::kMCP2, 1.0, 1000.0); @@ -4701,7 +4783,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) // Run 2 only - if (!nameStr.compare("highPtHadron")) { + if (nameStr == "highPtHadron") { cut->AddCut(VarManager::kPt, 4.0, 1000.0); cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kIsITSrefit, 0.5, 1.5); @@ -4712,7 +4794,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("TightGlobalTrack")) { + if (nameStr == "TightGlobalTrack") { cut->AddCut(VarManager::kIsSPDfirst, 0.5, 1.5); cut->AddCut(VarManager::kIsITSrefit, 0.5, 1.5); cut->AddCut(VarManager::kIsTPCrefit, 0.5, 1.5); @@ -4724,7 +4806,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronStandardQuality")) { + if (nameStr == "electronStandardQuality") { cut->AddCut(VarManager::kIsSPDany, 0.5, 1.5); cut->AddCut(VarManager::kIsITSrefit, 0.5, 1.5); cut->AddCut(VarManager::kIsTPCrefit, 0.5, 1.5); @@ -4734,7 +4816,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronStandardQualityBenchmark")) { + if (nameStr == "electronStandardQualityBenchmark") { cut->AddCut(VarManager::kIsITSrefit, 0.5, 1.5); cut->AddCut(VarManager::kIsTPCrefit, 0.5, 1.5); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); @@ -4745,7 +4827,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) // Run 2 or run 3 - if (!nameStr.compare("jpsi_trackCut_debug")) { + if (nameStr == "jpsi_trackCut_debug") { cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 90., 159); @@ -4753,14 +4835,14 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsi_trackCut_noITSCuts_debug")) { + if (nameStr == "jpsi_trackCut_noITSCuts_debug") { cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 90., 159); return cut; } - if (!nameStr.compare("jpsi_trackCut_debug2")) { + if (nameStr == "jpsi_trackCut_debug2") { cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 90., 159); @@ -4771,7 +4853,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsi_trackCut_debug3")) { + if (nameStr == "jpsi_trackCut_debug3") { cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 90., 159); @@ -4785,7 +4867,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsi_trackCut_debug4")) { + if (nameStr == "jpsi_trackCut_debug4") { cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 90., 159); @@ -4796,7 +4878,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsi_trackCut_debug5")) { + if (nameStr == "jpsi_trackCut_debug5") { cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 70., 159); @@ -4804,7 +4886,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsi_trackCut_debug6")) { + if (nameStr == "jpsi_trackCut_debug6") { cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 120., 159); cut->AddCut(VarManager::kTPCnclsCR, 140., 159); @@ -4813,7 +4895,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("lmee_trackCut_debug")) { + if (nameStr == "lmee_trackCut_debug") { cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 80., 159); @@ -4821,7 +4903,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("lmee_skimming_cuts")) { + if (nameStr == "lmee_skimming_cuts") { cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kIsSPDfirst, 0.5, 1.5); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); @@ -4830,7 +4912,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("trackQuality_compareDQEMframework")) { // cut setting to check least common factor between reduced data sets of PWGEM and PWGDQ + if (nameStr == "trackQuality_compareDQEMframework") { // cut setting to check least common factor between reduced data sets of PWGEM and PWGDQ cut->AddCut(VarManager::kIsSPDfirst, 0.5, 1.5); cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); cut->AddCut(VarManager::kITSncls, 4.5, 7.5); @@ -4841,7 +4923,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if ((!nameStr.compare("TightGlobalTrackRun3")) || (!nameStr.compare("lmeeQCTrackCuts"))) { + if ((nameStr == "TightGlobalTrackRun3") || (nameStr == "lmeeQCTrackCuts")) { cut->AddCut(VarManager::kIsSPDfirst, 0.5, 1.5); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); @@ -4865,7 +4947,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) // loop to define PID cuts with and without post calibration for (size_t icase = 1; icase < vecTypetrack.size(); icase++) { - if (!nameStr.compare(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))) { + if (nameStr == Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data())) { if (icase == 1) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kIsSPDfirst, 0.5, 1.5); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); @@ -4922,7 +5004,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) } } - if (!nameStr.compare("LooseGlobalTrackRun3")) { + if (nameStr == "LooseGlobalTrackRun3") { cut->AddCut(VarManager::kIsSPDfirst, 0.5, 1.5); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kITSchi2, 0.0, 6.0); @@ -4931,7 +5013,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("TightGlobalTrackRun3_strongTPC")) { + if (nameStr == "TightGlobalTrackRun3_strongTPC") { cut->AddCut(VarManager::kIsSPDfirst, 0.5, 1.5); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); @@ -4941,40 +5023,40 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("TightTPCTrackRun3")) { + if (nameStr == "TightTPCTrackRun3") { cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCnclsCR, 80.0, 161.); return cut; } - if (!nameStr.compare("TightTPCTrack")) { + if (nameStr == "TightTPCTrack") { cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCnclsCR, 80.0, 161.); cut->AddCut(VarManager::kIsTPCrefit, 0.5, 1.5); return cut; } - if (!nameStr.compare("SPDfirst")) { + if (nameStr == "SPDfirst") { cut->AddCut(VarManager::kIsSPDfirst, 0.5, 1.5); return cut; } - if (!nameStr.compare("noTPC")) { + if (nameStr == "noTPC") { cut->AddCut(VarManager::kHasTPC, -0.5, 0.5); return cut; } - if (!nameStr.compare("SPDany")) { + if (nameStr == "SPDany") { cut->AddCut(VarManager::kIsSPDany, 0.5, 1.5); return cut; } - if (!nameStr.compare("ITSiball")) { + if (nameStr == "ITSiball") { cut->AddCut(VarManager::kIsITSibAll, 0.5, 1.5); return cut; } - if (!nameStr.compare("ITSibany")) { + if (nameStr == "ITSibany") { cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); return cut; } @@ -4987,7 +5069,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) std::vector cutVar_TPCnCls = {80., 100., 80., 90., 90., 80., 80., 80., 80., 90., 100., 100., 80., 80., 80., 80., 100., 90., 100., 90., 90., 100., 100., 80., 100., 90., 90., 100., 90., 90.}; for (unsigned int i = 0; i < cutVar_ITSchi2.size(); i++) { - if (!nameStr.compare(Form("lmeeCutVarTrackCuts%i", i))) { + if (nameStr == Form("lmeeCutVarTrackCuts%i", i)) { cut->AddCut(VarManager::kIsSPDfirst, 0.5, 1.5); cut->AddCut(VarManager::kITSchi2, 0.0, cutVar_ITSchi2.at(i)); cut->AddCut(VarManager::kTPCchi2, 0.0, cutVar_TPCchi2.at(i)); @@ -4998,66 +5080,72 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) } } - if (!nameStr.compare("electronStandardQualityForO2MCdebug")) { + if (nameStr == "electronStandardQualityForO2MCdebug") { cut->AddCut(VarManager::kIsSPDany, 0.5, 1.5); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 70, 161.); return cut; } - if (!nameStr.compare("electronStandardQualityForO2MCdebug2")) { + if (nameStr == "electronStandardQualityForO2MCdebug2") { cut->AddCut(VarManager::kIsSPDany, 0.5, 1.5); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 100.0, 161.); return cut; } - if (!nameStr.compare("electronStandardQualityForO2MCdebug3")) { + if (nameStr == "electronStandardQualityForO2MCdebug3") { cut->AddCut(VarManager::kITSncls, 0.5, 10); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 70, 161.); return cut; } - if (!nameStr.compare("electronStandardQualityForO2MCdebug4")) { + if (nameStr == "electronStandardQualityForO2MCdebug4") { cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 70, 161.); return cut; } - if (!nameStr.compare("electronStandardQualityITSOnly")) { + if (nameStr == "electronStandardQualityITSOnly") { cut->AddCut(VarManager::kIsSPDany, 0.5, 1.5); cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); cut->AddCut(VarManager::kITSncls, 3.5, 7.5); return cut; } - if (!nameStr.compare("electronStandardQualitybAnyITSOnly")) { + if (nameStr == "electronStandardQualitybAnyITSOnly") { cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); cut->AddCut(VarManager::kITSncls, 3.5, 7.5); return cut; } - if (!nameStr.compare("electronStandardQualityTPCOnly")) { + if (nameStr == "electronStandardQualityTPCOnly") { cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 70, 161.); return cut; } - if (!nameStr.compare("electronStandardQualityTPCOnly2")) { + if (nameStr == "electronStandardQualityTPCOnly2") { cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kTPCncls, 100, 161.); return cut; } - if (!nameStr.compare("NoelectronStandardQualityTPCOnly")) { + if (nameStr == "electronStandardQualityTPCOnly3") { + cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + cut->AddCut(VarManager::kTPCncls, 120, 161.); + return cut; + } + + if (nameStr == "NoelectronStandardQualityTPCOnly") { cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0, true, VarManager::kTPCncls, 70, 161.); return cut; } - if (!nameStr.compare("electronTrackQualitySkimmed")) { + if (nameStr == "electronTrackQualitySkimmed") { cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); cut->AddCut(VarManager::kTPCncls, 60, 161); @@ -5066,14 +5154,14 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronTrackQualitySkimmed2")) { + if (nameStr == "electronTrackQualitySkimmed2") { cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); cut->AddCut(VarManager::kTPCncls, 60, 161); return cut; } - if (!nameStr.compare("electronTrackQualitySkimmed3")) { + if (nameStr == "electronTrackQualitySkimmed3") { cut->AddCut(VarManager::kPt, 1.0, 1000.0); cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); @@ -5082,7 +5170,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronTrackQuality_Maolin")) { + if (nameStr == "electronTrackQuality_Maolin") { cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); cut->AddCut(VarManager::kITSchi2, 0.0, 15.0); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); @@ -5093,14 +5181,14 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("pionQualityCut1")) { + if (nameStr == "pionQualityCut1") { cut->AddCut(VarManager::kPt, 0.15, 1000.0); cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); cut->AddCut(VarManager::kTPCncls, 70, 161); return cut; } - if (!nameStr.compare("pionQualityCut2")) { + if (nameStr == "pionQualityCut2") { cut->AddCut(VarManager::kPt, 0.15, 1000.0); cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); @@ -5109,7 +5197,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("protonPVcut")) { + if (nameStr == "protonPVcut") { cut->AddCut(VarManager::kTrackDCAxy, -0.1, 0.1); cut->AddCut(VarManager::kTrackDCAz, -0.15, 0.15); cut->AddCut(VarManager::kPt, 0.4, 3); @@ -5120,31 +5208,31 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("pidbasic")) { + if (nameStr == "pidbasic") { cut->AddCut(VarManager::kEta, -0.9, 0.9); cut->AddCut(VarManager::kTPCncls, 60, 161.); return cut; } - if (!nameStr.compare("standardPrimaryTrack")) { + if (nameStr == "standardPrimaryTrack") { cut->AddCut(VarManager::kTrackDCAxy, -1.0, 1.0); cut->AddCut(VarManager::kTrackDCAz, -3.0, 3.0); return cut; } - if (!nameStr.compare("trackDCA1cm")) { // cut setting to check least common factor between reduced data sets of PWGEM and PWGDQ + if (nameStr == "trackDCA1cm") { // cut setting to check least common factor between reduced data sets of PWGEM and PWGDQ cut->AddCut(VarManager::kTrackDCAxy, -1.0, 1.0); cut->AddCut(VarManager::kTrackDCAz, -1.0, 1.0); return cut; } - if (!nameStr.compare("electronPrimary_dca3sigma") || !nameStr.compare("electronPrimary_dca7sigma")) { + if (nameStr == "electronPrimary_dca3sigma" || nameStr == "electronPrimary_dca7sigma") { std::shared_ptr fDCAxyresLow = std::make_shared("fDCAxyresLow", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); std::shared_ptr fDCAzresLow = std::make_shared("fDCAzresLow", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); std::shared_ptr fDCAxyresUp = std::make_shared("fDCAxyresUp", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); std::shared_ptr fDCAzresUp = std::make_shared("fDCAzresUp", "[0] + [1] * pow(x, -[2])", 0.1, 1000.); - if (!nameStr.compare("electronPrimary_dca3sigma")) { + if (nameStr == "electronPrimary_dca3sigma") { // DCAxy and DCAz 3 sigma cut. DCA resolution vs pt extracted from fits of Users/m/mfaggin/test/inputsTrackTuner/pp2024/pass1_minBias/vsPhi (used for the track tuner) // we add in addition a term for the misalignment of the mean of the distribution, which seems to be at most 20 mum for DCAxy and 10 mum for DCAz fDCAxyresLow->SetParameters(-3 * 8.7e-4 - 20e-4, -3 * 25.4e-4, 0.79); // res is 8.7 + 25.4/pt^0.79 mum @@ -5160,7 +5248,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronPrimary_dca7sigma")) { + if (nameStr == "electronPrimary_dca7sigma") { // DCAxy and DCAz 7 sigma cut fDCAxyresLow->SetParameters(-7 * 8.7e-4 - 20e-4, -7 * 25.4e-4, 0.79); fDCAzresLow->SetParameters(-7 * 9.4e-4 - 10e-4, -7 * 26.5e-4, 0.79); @@ -5176,13 +5264,13 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) } } - if (!nameStr.compare("dcaCut1_ionut")) { + if (nameStr == "dcaCut1_ionut") { cut->AddCut(VarManager::kTrackDCAxy, -0.5, 0.5); cut->AddCut(VarManager::kTrackDCAz, -0.5, 0.5); return cut; } - if (!nameStr.compare("trackQuality_ionut")) { + if (nameStr == "trackQuality_ionut") { cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); cut->AddCut(VarManager::kTPCncls, 70, 161); cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); @@ -5190,7 +5278,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("trackQualityTight_ionut")) { + if (nameStr == "trackQualityTight_ionut") { cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5); cut->AddCut(VarManager::kTPCncls, 100, 161); cut->AddCut(VarManager::kITSchi2, 0.0, 3.0); @@ -5199,13 +5287,13 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("kineJpsiEle_ionut")) { + if (nameStr == "kineJpsiEle_ionut") { cut->AddCut(VarManager::kP, 1.0, 15.0); cut->AddCut(VarManager::kEta, -0.9, 0.9); return cut; } - if (!nameStr.compare("pidJpsiEle0_ionut")) { + if (nameStr == "pidJpsiEle0_ionut") { cut->AddCut(VarManager::kTPCnSigmaEl, -2.0, 4.0, false, VarManager::kPin, 1.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0, false, VarManager::kPin, 4.0, 150.0); cut->AddCut(VarManager::kTPCnSigmaEl, 98.1, 98.11, false, VarManager::kPin, 0.0, 1.0); @@ -5213,7 +5301,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("pidJpsiEle1_ionut")) { + if (nameStr == "pidJpsiEle1_ionut") { cut->AddCut(VarManager::kTPCnSigmaEl, -1.5, 4.0, false, VarManager::kPin, 1.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0, false, VarManager::kPin, 4.0, 150.0); cut->AddCut(VarManager::kTPCnSigmaEl, 98.1, 98.11, false, VarManager::kPin, 0.0, 1.0); @@ -5221,129 +5309,144 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("pidJpsiEle2_ionut")) { + if (nameStr == "pidJpsiEle2_ionut") { cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true); return cut; } - if (!nameStr.compare("pidJpsiEle3_ionut")) { + if (nameStr == "pidJpsiEle3_ionut") { cut->AddCut(VarManager::kTPCnSigmaEl, -0.5, 4.0); cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true); return cut; } - if (!nameStr.compare("pidJpsiEle4_ionut")) { + if (nameStr == "pidJpsiEle4_ionut") { cut->AddCut(VarManager::kTPCnSigmaEl, 0.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true); return cut; } - if (!nameStr.compare("pidJpsiEle5_ionut")) { + if (nameStr == "pidJpsiEle5_ionut") { cut->AddCut(VarManager::kTPCnSigmaEl, 0.5, 4.0); cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true); return cut; } - if (!nameStr.compare("pidJpsiEle6_ionut")) { + if (nameStr == "pidJpsiEle6_ionut") { cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0); cut->AddCut(VarManager::kTOFnSigmaEl, -1.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true); return cut; } - if (!nameStr.compare("pidJpsiEle7_ionut")) { + if (nameStr == "pidJpsiEle7_ionut") { cut->AddCut(VarManager::kTOFnSigmaEl, -3.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0); return cut; } - if (!nameStr.compare("pidJpsiEle8_ionut")) { + if (nameStr == "pidJpsiEle8_ionut") { cut->AddCut(VarManager::kTOFnSigmaEl, -3.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaEl, -1.5, 4.0); return cut; } - if (!nameStr.compare("pidJpsiEle9_ionut")) { + if (nameStr == "pidJpsiEle9_ionut") { cut->AddCut(VarManager::kTOFnSigmaEl, -3.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaEl, -2.0, 4.0); return cut; } + if (nameStr == "pidJpsi_TPCpion0") { + cut->AddCut(VarManager::kTPCnSigmaPi, 4.0, 1000.0); + return cut; + } + + if (nameStr == "pidJpsi_noTOF_prot") { + cut->AddCut(VarManager::kTPCnSigmaPr, 3.5, 1000.0, false, VarManager::kHasTOF, -0.5, 0.5); + return cut; + } + + if (nameStr == "pidJpsi_beta") { + cut->AddCut(VarManager::kTOFbeta, 0.98, 1.02, false, VarManager::kHasTOF, 0.5, 1.5); + return cut; + } + // Magnus cuts ---------------------------------------------------------- - if (!nameStr.compare("pidJpsi_magnus_ele1")) { + if (nameStr == "pidJpsi_magnus_ele1") { cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 4.0); return cut; } - if (!nameStr.compare("pidJpsi_magnus_ele2")) { + if (nameStr == "pidJpsi_magnus_ele2") { cut->AddCut(VarManager::kTPCnSigmaEl, -2.0, 4.0); return cut; } - if (!nameStr.compare("pidJpsi_magnus_ele3")) { + if (nameStr == "pidJpsi_magnus_ele3") { cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0); return cut; } - if (!nameStr.compare("pidJpsi_magnus_prot1")) { + if (nameStr == "pidJpsi_magnus_prot1") { cut->AddCut(VarManager::kTPCnSigmaPr, 3.0, 1000.0); return cut; } - if (!nameStr.compare("pidJpsi_magnus_prot2")) { + if (nameStr == "pidJpsi_magnus_prot2") { cut->AddCut(VarManager::kTPCnSigmaPr, 3.5, 1000.0); return cut; } - if (!nameStr.compare("pidJpsi_magnus_pion1")) { + if (nameStr == "pidJpsi_magnus_pion1") { cut->AddCut(VarManager::kTPCnSigmaPi, 3.0, 1000.0); return cut; } - if (!nameStr.compare("pidJpsi_magnus_pion2")) { + if (nameStr == "pidJpsi_magnus_pion2") { cut->AddCut(VarManager::kTPCnSigmaPi, 3.5, 1000.0); return cut; } // ---------------------------------------------------------------------------------- - if (!nameStr.compare("standardPrimaryTrackDCAz")) { + if (nameStr == "standardPrimaryTrackDCAz") { cut->AddCut(VarManager::kTrackDCAxy, -3.0, 3.0); cut->AddCut(VarManager::kTrackDCAz, -1.0, 1.0); return cut; } - if (!nameStr.compare("standardPrimaryTrackDCA")) { + if (nameStr == "standardPrimaryTrackDCA") { cut->AddCut(VarManager::kTrackDCAxy, -0.1, 0.1); cut->AddCut(VarManager::kTrackDCAz, -0.15, 0.15); return cut; } - if (!nameStr.compare("PrimaryTrack_looseDCA")) { + if (nameStr == "PrimaryTrack_looseDCA") { cut->AddCut(VarManager::kTrackDCAxy, -3.0, 3.0); cut->AddCut(VarManager::kTrackDCAz, -3.0, 3.0); return cut; } - if (!nameStr.compare("tightPrimaryTrack")) { + if (nameStr == "tightPrimaryTrack") { cut->AddCut(VarManager::kTrackDCAsigXY, -3.0, 3.0); cut->AddCut(VarManager::kTrackDCAsigZ, -3.0, 3.0); return cut; } - if (!nameStr.compare("PrimaryTrack_DCA05")) { + if (nameStr == "PrimaryTrack_DCA05") { cut->AddCut(VarManager::kTrackDCAsigXY, -0.5, 0.5); cut->AddCut(VarManager::kTrackDCAsigZ, -0.5, 0.5); return cut; } - if (!nameStr.compare("PrimaryTrack_DCAz")) { + if (nameStr == "PrimaryTrack_DCAz") { cut->AddCut(VarManager::kTrackDCAz, -0.3, 0.3); return cut; } - if (!nameStr.compare("hasTOF")) { + if (nameStr == "hasTOF") { cut->AddCut(VarManager::kHasTOF, 0.5, 1.5); return cut; } - if (!nameStr.compare("noTOF")) { + if (nameStr == "noTOF") { cut->AddCut(VarManager::kHasTOF, -0.5, 0.5); return cut; } @@ -5352,33 +5455,33 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) // V0 and Dalitz legs selections for (int i = 1; i <= 8; i++) { // o2-linter: disable=magic-number (number of cuts) - if (!nameStr.compare(Form("dalitzLeg%d", i))) { + if (nameStr == Form("dalitzLeg%d", i)) { cut->AddCut(VarManager::kIsDalitzLeg + i - 1, 0.5, 1.5); return cut; } - if (!nameStr.compare(Form("notDalitzLeg%d", i))) { + if (nameStr == Form("notDalitzLeg%d", i)) { cut->AddCut(VarManager::kIsDalitzLeg + i - 1, -0.5, 0.5); return cut; } } - if (!nameStr.compare("pidcalib_ele")) { + if (nameStr == "pidcalib_ele") { cut->AddCut(VarManager::kIsLegFromGamma, 0.5, 1.5, false); return cut; } - if (!nameStr.compare("pidcalib_pion")) { + if (nameStr == "pidcalib_pion") { cut->AddCut(VarManager::kIsLegFromK0S, 0.5, 1.5, false); return cut; } - if (!nameStr.compare("pidcalib_proton")) { + if (nameStr == "pidcalib_proton") { cut->AddCut(VarManager::kIsProtonFromLambdaAndAntiLambda, 0.5, 1.5, false); return cut; } - if (!nameStr.compare("pidcalib_kaon")) { + if (nameStr == "pidcalib_kaon") { cut->AddCut(VarManager::kTOFnSigmaKa, -2.0, 2.0); cut->AddCut(VarManager::kTOFnSigmaPi, -2.0, 2.0, true); cut->AddCut(VarManager::kITSncls, 1.5, 7.5); @@ -5387,55 +5490,55 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) // ------------------------------------------------ // Barrel PID cuts - if (!nameStr.compare("jpsi_TPCPID_debug1")) { + if (nameStr == "jpsi_TPCPID_debug1") { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 2.5, 999); cut->AddCut(VarManager::kTPCnSigmaPr_Corr, 2.5, 999); return cut; } - if (!nameStr.compare("jpsi_TPCPID_debug2")) { + if (nameStr == "jpsi_TPCPID_debug2") { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 3.0, 999); cut->AddCut(VarManager::kTPCnSigmaPr_Corr, 3.0, 999); return cut; } - if (!nameStr.compare("jpsi_TPCPID_debug3")) { + if (nameStr == "jpsi_TPCPID_debug3") { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 3.5, 999); cut->AddCut(VarManager::kTPCnSigmaPr_Corr, 3.5, 999); return cut; } - if (!nameStr.compare("jpsi_TPCPID_debug4")) { + if (nameStr == "jpsi_TPCPID_debug4") { cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPi, 3.0, 999); cut->AddCut(VarManager::kTPCnSigmaPr, 3.0, 999); return cut; } - if (!nameStr.compare("jpsi_TPCPID_debug5")) { + if (nameStr == "jpsi_TPCPID_debug5") { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -4.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 2.5, 999); cut->AddCut(VarManager::kTPCnSigmaPr_Corr, 2.5, 999); return cut; } - if (!nameStr.compare("jpsi_TPCPID_debug5_noCorr")) { + if (nameStr == "jpsi_TPCPID_debug5_noCorr") { cut->AddCut(VarManager::kTPCnSigmaEl, -4.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaPi, 2.5, 999); cut->AddCut(VarManager::kTPCnSigmaPr, 2.5, 999); return cut; } - if (!nameStr.compare("electronPIDLooseSkimmed")) { + if (nameStr == "electronPIDLooseSkimmed") { cut->AddCut(VarManager::kTPCnSigmaEl, -4.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaPi, 2.5, 999); cut->AddCut(VarManager::kTPCnSigmaPr, 2.5, 999); return cut; } - if (!nameStr.compare("electronPIDLooseSkimmed2")) { + if (nameStr == "electronPIDLooseSkimmed2") { cut->AddCut(VarManager::kTPCnSigmaEl, -4.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaPi, 2.5, 999, false, VarManager::kPin, 0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPi, 1.5, 999, false, VarManager::kPin, 3.0, 999); @@ -5444,28 +5547,28 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronPIDLooseSkimmed3")) { + if (nameStr == "electronPIDLooseSkimmed3") { cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPi, 3.0, 999, false, VarManager::kPin, 0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr, 3.0, 999, false, VarManager::kPin, 0, 3.0); return cut; } - if (!nameStr.compare("jpsi_TPCPID_debug6")) { + if (nameStr == "jpsi_TPCPID_debug6") { cut->AddCut(VarManager::kTPCnSigmaEl, -2.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPi, 3.0, 999); cut->AddCut(VarManager::kTPCnSigmaPr, 3.0, 999); return cut; } - if (!nameStr.compare("jpsi_TPCPID_debug7")) { + if (nameStr == "jpsi_TPCPID_debug7") { cut->AddCut(VarManager::kTPCnSigmaEl, -2.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPi, 3.5, 999); cut->AddCut(VarManager::kTPCnSigmaPr, 3.5, 999); return cut; } - if (!nameStr.compare("jpsi_TPCPID_debug8")) { + if (nameStr == "jpsi_TPCPID_debug8") { cut->AddCut(VarManager::kTPCnSigmaEl, -2.0, 3.0, false, VarManager::kPin, 0.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0, false, VarManager::kPin, 3.0, 999.0); cut->AddCut(VarManager::kTPCnSigmaPi, 3.0, 999, false, VarManager::kPin, 0.0, 3.0); @@ -5474,95 +5577,95 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsi_TPCPID_debug9")) { + if (nameStr == "jpsi_TPCPID_debug9") { cut->AddCut(VarManager::kTPCnSigmaEl, -2.5, 4.0); cut->AddCut(VarManager::kTPCnSigmaPi, 1.0, 999, false, VarManager::kPin, 3.0, 999.0); cut->AddCut(VarManager::kTPCnSigmaPr, 2.0, 999); return cut; } - if (!nameStr.compare("jpsi_TPCPID_debug10")) { + if (nameStr == "jpsi_TPCPID_debug10") { cut->AddCut(VarManager::kTPCnSigmaEl, -1.5, 2.0); cut->AddCut(VarManager::kTPCnSigmaPi, 4.0, 999); cut->AddCut(VarManager::kTPCnSigmaPr, 3.5, 999); return cut; } - if (!nameStr.compare("pidCut_lowP_Corr")) { + if (nameStr == "pidCut_lowP_Corr") { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -3.0, 3.0, false, VarManager::kP, 0.0, 5.0); cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 3.0, 999, false, VarManager::kP, 0.0, 5.0); cut->AddCut(VarManager::kTPCnSigmaPr_Corr, 2.5, 999, false, VarManager::kP, 0.0, 5.0); return cut; } - if (!nameStr.compare("EleInclusion_highP_Corr")) { + if (nameStr == "EleInclusion_highP_Corr") { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -1.0, 4.0, false, VarManager::kP, 5.0, 999.0); return cut; } - if (!nameStr.compare("EleInclusion_highP2_Corr")) { + if (nameStr == "EleInclusion_highP2_Corr") { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -0.5, 4.0, false, VarManager::kP, 5.0, 999.0); return cut; } - if (!nameStr.compare("PionExclusion_highP_Corr")) { + if (nameStr == "PionExclusion_highP_Corr") { cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 2.0, 999, false, VarManager::kP, 5.0, 999.0); return cut; } - if (!nameStr.compare("pidCut_lowP")) { + if (nameStr == "pidCut_lowP") { cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0, false, VarManager::kP, 0.0, 5.0); cut->AddCut(VarManager::kTPCnSigmaPi, 3.0, 999, false, VarManager::kP, 0.0, 5.0); cut->AddCut(VarManager::kTPCnSigmaPr, 2.5, 999, false, VarManager::kP, 0.0, 5.0); return cut; } - if (!nameStr.compare("EleInclusion_highP")) { + if (nameStr == "EleInclusion_highP") { cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0, false, VarManager::kP, 5.0, 999.0); return cut; } - if (!nameStr.compare("EleInclusion_highP2")) { + if (nameStr == "EleInclusion_highP2") { cut->AddCut(VarManager::kTPCnSigmaEl, -0.5, 4.0, false, VarManager::kP, 5.0, 999.0); return cut; } - if (!nameStr.compare("PionExclusion_highP")) { + if (nameStr == "PionExclusion_highP") { cut->AddCut(VarManager::kTPCnSigmaPi, 2.0, 999, false, VarManager::kP, 5.0, 999.0); return cut; } - if (!nameStr.compare("lmee_TPCPID_debug1")) { + if (nameStr == "lmee_TPCPID_debug1") { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -5.0, 5.0); return cut; } - if (!nameStr.compare("electronPID1") || !nameStr.compare("electronPID1shiftUp") || !nameStr.compare("electronPID1shiftDown") || !nameStr.compare("electronPID2") || !nameStr.compare("electronPID3")) { + if (nameStr == "electronPID1" || nameStr == "electronPID1shiftUp" || nameStr == "electronPID1shiftDown" || nameStr == "electronPID2" || nameStr == "electronPID3") { std::shared_ptr cutLow1 = std::make_shared("cutLow1", "pol1", 0., 10.); - if (!nameStr.compare("electronPID1")) { + if (nameStr == "electronPID1") { cutLow1->SetParameters(130., -40.0); cut->AddCut(VarManager::kTPCsignal, 70., 100.); cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0, false, VarManager::kPin, 0.5, 3.0); return cut; } - if (!nameStr.compare("electronPID1shiftUp")) { + if (nameStr == "electronPID1shiftUp") { cut->AddCut(VarManager::kTPCsignal, 70. - 0.85, 100. - 0.85); cutLow1->SetParameters(130. - 0.85, -40.0); cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0 - 0.85, false, VarManager::kPin, 0.5, 3.0); return cut; } - if (!nameStr.compare("electronPID1shiftDown")) { + if (nameStr == "electronPID1shiftDown") { cut->AddCut(VarManager::kTPCsignal, 70.0 + 0.85, 100.0 + 0.85); cutLow1->SetParameters(130. + 0.85, -40.0); cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0 + 0.85, false, VarManager::kPin, 0.5, 3.0); return cut; } - if (!nameStr.compare("electronPID2")) { + if (nameStr == "electronPID2") { cutLow1->SetParameters(130., -40.0); cut->AddCut(VarManager::kTPCsignal, 73., 100.); cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0, false, VarManager::kPin, 0.5, 3.0); return cut; } - if (!nameStr.compare("electronPID3")) { + if (nameStr == "electronPID3") { cutLow1->SetParameters(130., -40.0); cut->AddCut(VarManager::kTPCsignal, 60., 110.); cut->AddCut(VarManager::kTPCsignal, cutLow1, 100.0, false, VarManager::kPin, 0.5, 3.0); @@ -5570,14 +5673,14 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) } } - if (!nameStr.compare("electronPIDnsigma")) { + if (nameStr == "electronPIDnsigma") { cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr, 3.0, 3000.0); cut->AddCut(VarManager::kTPCnSigmaPi, 3.0, 3000.0); return cut; } - if (!nameStr.compare("lmee_commonDQEM_PID_TPC")) { // cut setting to check least common factor between reduced data sets of PWGEM and PWGDQ + if (nameStr == "lmee_commonDQEM_PID_TPC") { // cut setting to check least common factor between reduced data sets of PWGEM and PWGDQ cut->AddCut(VarManager::kTPCnSigmaEl, -2.5, 3., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -1e12, 3.5, true, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaKa, -3., 3., true, VarManager::kPin, 0.0, 1e+10, false); @@ -5585,7 +5688,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("lmee_commonDQEM_PID_TOF")) { // cut setting to check least common factor between reduced data sets of PWGEM and PWGDQ + if (nameStr == "lmee_commonDQEM_PID_TOF") { // cut setting to check least common factor between reduced data sets of PWGEM and PWGDQ cut->AddCut(VarManager::kTPCnSigmaEl, -2.5, 3., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 3.5, true, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTOFnSigmaEl, -3., 3., false, VarManager::kPin, 0.3, 1e+10, false); @@ -5599,7 +5702,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) // loop to define TPC PID cuts with and without post calibration for (size_t icase = 0; icase < vecPIDcase.size(); icase++) { - if (!nameStr.compare(Form("electronPIDOnly%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPIDOnly%s", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0); } else if (icase == 1 || icase == 2) { // o2-linter: disable=magic-number (number of cuts) @@ -5608,7 +5711,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TPCnsigma%s_loose", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TPCnsigma%s_loose", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -3., 3., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 3.5, true, VarManager::kPin, 0.0, 1e+10, false); @@ -5628,7 +5731,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TPCnsigma%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TPCnsigma%s", vecPIDcase.at(icase).Data())) { if (icase == 0) { // previously known as electronPID_TPCnsigma_tight // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -3., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 3.5, true, VarManager::kPin, 0.0, 1e+10, false); @@ -5648,7 +5751,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TPCnsigma%s_strongHadRej", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TPCnsigma%s_strongHadRej", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -3., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -5668,7 +5771,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -2., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -5688,7 +5791,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_lowB_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_lowB_TPCnsigma%s_strongNSigE", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -2., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -5711,7 +5814,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_lowB_TPCnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_lowB_TPCnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -2., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -5736,7 +5839,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TPCnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TPCnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -2., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -5758,7 +5861,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TPCnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TPCnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -1., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -5780,7 +5883,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TPCnsigma%s_tightNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TPCnsigma%s_tightNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, 0., 3., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -5813,7 +5916,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) std::vector cutVar_TPCnSigmaPr_up = {2., 2., 3., 2., 3., 3., 3., 2., 4., 3., 3., 4., 4., 3., 4., 4., 3., 4., 2., 3., 4., 4., 3., 4., 3., 2., 3., 3., 2., 3}; for (unsigned int i = 0; i < cutVar_TPCnSigmaEl_low.size(); i++) { - if (!nameStr.compare(Form("electronPID_TPCnsigma_cutVar%s%i", vecPIDcase.at(icase).Data(), i))) { + if (nameStr == Form("electronPID_TPCnsigma_cutVar%s%i", vecPIDcase.at(icase).Data(), i)) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, cutVar_TPCnSigmaEl_low.at(i), cutVar_TPCnSigmaEl_up.at(i), false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, cutVar_TPCnSigmaPi_low.at(i), cutVar_TPCnSigmaPi_up.at(i), true, VarManager::kPin, 0.0, 1e+10, false); @@ -5834,7 +5937,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) } } - if (!nameStr.compare(Form("lmee_pp_502TeV_TPC%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_pp_502TeV_TPC%s", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -3., 3., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -99., 3.5, true, VarManager::kPin, 0.0, 1e+10, false); @@ -5854,7 +5957,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_pp_502TeV_lowB_TPC%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_pp_502TeV_lowB_TPC%s", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -3., 3., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3.5, 3.5, true, VarManager::kPin, 0.0, 1e+10, false); @@ -5877,7 +5980,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_pp_502TeV_TPCloosenopkrej%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_pp_502TeV_TPCloosenopkrej%s", vecPIDcase.at(icase).Data())) { if (icase == 0) { cut->AddCut(VarManager::kTPCnSigmaEl, -4., 4., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -99., 2.5, true, VarManager::kPin, 0.0, 1e+10, false); @@ -5888,7 +5991,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_pp_502TeV_TPCPbPbnopkrej%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_pp_502TeV_TPCPbPbnopkrej%s", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -1., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -5899,7 +6002,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_pp_502TeV_TPCloose%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_pp_502TeV_TPCloose%s", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -4., 4., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -99., 2.5, true, VarManager::kPin, 0.0, 1e+10, false); @@ -5920,21 +6023,21 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) } } - if (!nameStr.compare("electronPIDnsigmaOpen")) { + if (nameStr == "electronPIDnsigmaOpen") { cut->AddCut(VarManager::kTPCnSigmaEl, -4.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaPr, 2.0, 3000.0); cut->AddCut(VarManager::kTPCnSigmaPi, 2.0, 3000.0); return cut; } - if (!nameStr.compare("electronPIDnsigmaVeryVeryLoose")) { + if (nameStr == "electronPIDnsigmaVeryVeryLoose") { cut->AddCut(VarManager::kTPCnSigmaEl, -4.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaPr, 2.5, 3000.0); cut->AddCut(VarManager::kTPCnSigmaPi, 2.0, 3000.0); return cut; } - if (!nameStr.compare("electronPIDnsigmaVeryLoose")) { + if (nameStr == "electronPIDnsigmaVeryLoose") { cut->AddCut(VarManager::kTPCnSigmaEl, -4.0, 4.0); cut->AddCut(VarManager::kTPCnSigmaPr, 2.5, 3000.0); cut->AddCut(VarManager::kTPCnSigmaPi, 2.5, 3000.0); @@ -5942,41 +6045,41 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronPIDnsigmaLoose")) { + if (nameStr == "electronPIDnsigmaLoose") { cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr, 2.5, 3000.0); cut->AddCut(VarManager::kTPCnSigmaPi, 2.5, 3000.0); return cut; } - if (!nameStr.compare("electronPIDnsigmaMedium")) { + if (nameStr == "electronPIDnsigmaMedium") { cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr, 2.7, 3000.0); cut->AddCut(VarManager::kTPCnSigmaPi, 2.7, 3000.0); return cut; } - if (!nameStr.compare("electronPIDnsigmaMedium_withLargeTOFPID")) { + if (nameStr == "electronPIDnsigmaMedium_withLargeTOFPID") { cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr, 2.7, 3000.0); cut->AddCut(VarManager::kTPCnSigmaPi, 2.7, 3000.0); cut->AddCut(VarManager::kTOFnSigmaEl, -5.0, 5.0); return cut; } - if (!nameStr.compare("electronPIDnsigmaSkewed")) { + if (nameStr == "electronPIDnsigmaSkewed") { cut->AddCut(VarManager::kTPCnSigmaEl, -2.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr, 3.5, 3000.0); cut->AddCut(VarManager::kTPCnSigmaPi, 3.5, 3000.0); return cut; } - if (!nameStr.compare("electronPIDnsigmaSkewed_2")) { + if (nameStr == "electronPIDnsigmaSkewed_2") { cut->AddCut(VarManager::kTPCnSigmaEl, -0.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr, 3.5, 3000.0); cut->AddCut(VarManager::kTPCnSigmaPi, 3.5, 3000.0); return cut; } - if (!nameStr.compare("electronPIDPrKaPiRej")) { + if (nameStr == "electronPIDPrKaPiRej") { cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr, -3.0, 3.0, true); cut->AddCut(VarManager::kTPCnSigmaPi, -3.0, 3.0, true); @@ -5984,7 +6087,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronPIDPrKaPiRej_Corr")) { + if (nameStr == "electronPIDPrKaPiRej_Corr") { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr_Corr, -3.0, 3.0, true); cut->AddCut(VarManager::kTPCnSigmaPi_Corr, -3.0, 3.0, true); @@ -5992,7 +6095,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronPIDPrKaPiRejLoose")) { + if (nameStr == "electronPIDPrKaPiRejLoose") { cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr, -2.0, 2.0, true); cut->AddCut(VarManager::kTPCnSigmaPi, -3.0, 3.0, true, VarManager::kPin, 0.0, 1.0, false); @@ -6001,7 +6104,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronPIDPrKaPiRejLoose_Corr")) { + if (nameStr == "electronPIDPrKaPiRejLoose_Corr") { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr_Corr, -2.0, 2.0, true); cut->AddCut(VarManager::kTPCnSigmaPi_Corr, -3.0, 3.0, true, VarManager::kPin, 0.0, 1.0, false); @@ -6010,7 +6113,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("electronPIDnsigmaEMu")) { + if (nameStr == "electronPIDnsigmaEMu") { cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr, 3.5, 3000.0); cut->AddCut(VarManager::kTPCnSigmaPi, 3.5, 3000.0); @@ -6018,83 +6121,83 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("kaonPIDnsigma")) { + if (nameStr == "kaonPIDnsigma") { cut->AddCut(VarManager::kTPCnSigmaKa, -3.0, 3.0); return cut; } - if (!nameStr.compare("kaonRejNsigma")) { + if (nameStr == "kaonRejNsigma") { cut->AddCut(VarManager::kTPCnSigmaKa, -3.0, 3.0, true); return cut; } - if (!nameStr.compare("kaonPIDnsigma2")) { + if (nameStr == "kaonPIDnsigma2") { cut->AddCut(VarManager::kTPCnSigmaKa, -2.0, 2.0); return cut; } - if (!nameStr.compare("kaonPID_TPCnTOF")) { + if (nameStr == "kaonPID_TPCnTOF") { cut->AddCut(VarManager::kTPCnSigmaKa, -3.0, 3.0); cut->AddCut(VarManager::kTOFnSigmaKa, -3.0, 3.0); return cut; } - if (!nameStr.compare("kaonPIDnsigma700")) { + if (nameStr == "kaonPIDnsigma700") { cut->AddCut(VarManager::kTPCnSigmaKa, -3.0, 3.0); cut->AddCut(VarManager::kPin, 0.0, 0.7); return cut; } - if (!nameStr.compare("AssocKine")) { + if (nameStr == "AssocKine") { cut->AddCut(VarManager::kPt, 1.0, 1000.0); cut->AddCut(VarManager::kEta, -0.9, 0.9); return cut; } - if (!nameStr.compare("electronPIDworseRes")) { + if (nameStr == "electronPIDworseRes") { cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr, 3.0 * 0.8, 3000.0); // emulates a 20% degradation in PID resolution cut->AddCut(VarManager::kTPCnSigmaPi, 3.0 * 0.8, 3000.0); // proton and pion rejections are effectively relaxed by 20% return cut; } - if (!nameStr.compare("electronPIDshift")) { + if (nameStr == "electronPIDshift") { cut->AddCut(VarManager::kTPCnSigmaEl, -3.0, 3.0); cut->AddCut(VarManager::kTPCnSigmaPr, 3.0 - 0.2, 3000.0); cut->AddCut(VarManager::kTPCnSigmaPi, 3.0 - 0.2, 3000.0); return cut; } - if (!nameStr.compare("pionPIDnsigma")) { + if (nameStr == "pionPIDnsigma") { cut->AddCut(VarManager::kTPCnSigmaPi, -3.0, 3.0); return cut; } - if (!nameStr.compare("pionPID_TPCnTOF")) { + if (nameStr == "pionPID_TPCnTOF") { cut->AddCut(VarManager::kTPCnSigmaPi, -3.0, 3.0); cut->AddCut(VarManager::kTOFnSigmaPi, -3.0, 3.0); return cut; } - if (!nameStr.compare("protonPID_TPCnTOF")) { + if (nameStr == "protonPID_TPCnTOF") { cut->AddCut(VarManager::kTPCnSigmaPr, -3.0, 3.0); cut->AddCut(VarManager::kTOFnSigmaPr, -3.0, 3.0); return cut; } - if (!nameStr.compare("protonPID_TPCnTOF2")) { + if (nameStr == "protonPID_TPCnTOF2") { cut->AddCut(VarManager::kTPCnSigmaPr, -2.5, 2.5); return cut; } - if (!nameStr.compare("tpc_pion_rejection")) { + if (nameStr == "tpc_pion_rejection") { std::shared_ptr f1maxPi = std::make_shared("f1maxPi", "[0]+[1]*x", 0, 10); f1maxPi->SetParameters(85, -50); cut->AddCut(VarManager::kTPCsignal, 70, f1maxPi, true, VarManager::kPin, 0.0, 0.4, false); return cut; } - if (!nameStr.compare("tpc_pion_band_rejection")) { + if (nameStr == "tpc_pion_band_rejection") { std::shared_ptr f1minPi = std::make_shared("f1minPi", "[0]+[1]*log(x)", 0, 10); f1minPi->SetParameters(-115, -90); std::shared_ptr f1maxPi = std::make_shared("f1maxPi", "[0]+[1]*log(x)", 0, 10); @@ -6103,7 +6206,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("tpc_pion_muon_band_rejection")) { + if (nameStr == "tpc_pion_muon_band_rejection") { std::shared_ptr f1minPi = std::make_shared("f1minPi", "[0]+exp([1]*x+[2])", 0, 10); f1minPi->SetParameters(37, -18, 5.5); std::shared_ptr f1maxPi = std::make_shared("f1maxPi", "[0]+exp([1]*x+[2])", 0, 10); @@ -6112,14 +6215,14 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("tpc_pion_rejection_highp")) { + if (nameStr == "tpc_pion_rejection_highp") { std::shared_ptr f1minPi = std::make_shared("f1minPi", "[0]+[1]*x", 0, 10); f1minPi->SetParameters(65, 4.); cut->AddCut(VarManager::kTPCsignal, f1minPi, 110., false, VarManager::kPin, 0.0, 10, false); return cut; } - if (!nameStr.compare("tpc_kaon_rejection")) { + if (nameStr == "tpc_kaon_rejection") { std::shared_ptr f1minKa = std::make_shared("f1minKa", "[0]+exp([1]*x+[2])", 0, 10); f1minKa->SetParameters(37, -4, 5.6); std::shared_ptr f1maxKa = std::make_shared("f1maxKa", "[0]+exp([1]*x+[2])", 0, 10); @@ -6128,7 +6231,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("tpc_proton_rejection")) { + if (nameStr == "tpc_proton_rejection") { std::shared_ptr f1minPr = std::make_shared("f1minPr", "[0]+exp([1]*x+[2])", 0, 10); f1minPr->SetParameters(37, -2.6, 6.1); std::shared_ptr f1maxPr = std::make_shared("f1maxPr", "[0]+exp([1]*x+[2])", 0, 10); @@ -6137,34 +6240,34 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("tpc_electron")) { + if (nameStr == "tpc_electron") { cut->AddCut(VarManager::kTPCsignal, 60, 110, false, VarManager::kPin, 0.0, 1e+10, false); return cut; } - if (!nameStr.compare("tof_electron")) { + if (nameStr == "tof_electron") { cut->AddCut(VarManager::kTOFbeta, 0.99, 1.01, false, VarManager::kPin, 0.0, 1e+10, false); return cut; } - if (!nameStr.compare("tof_electron_sigma")) { + if (nameStr == "tof_electron_sigma") { cut->AddCut(VarManager::kTOFnSigmaEl, -2., 2., false, VarManager::kPin, 0.0, 1e+10, false); return cut; } - if (!nameStr.compare("tof_electron_sigma_2")) { + if (nameStr == "tof_electron_sigma_2") { cut->AddCut(VarManager::kTOFnSigmaEl, -3., 3.); return cut; } - if (!nameStr.compare("tof_electron_loose")) { + if (nameStr == "tof_electron_loose") { cut->AddCut(VarManager::kTOFbeta, 0.95, 1.05, false, VarManager::kPin, 0.0, 1e+10, false); return cut; } // loop to define TOF PID cuts with and without post calibration for (size_t icase = 0; icase < vecPIDcase.size(); icase++) { - if (!nameStr.compare(Form("electronPID_TOFnsigma%s_loose", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TOFnsigma%s_loose", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -3., 3., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 3.5, true, VarManager::kPin, 0.0, 1e+10, false); @@ -6177,7 +6280,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TOFnsigma%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TOFnsigma%s", vecPIDcase.at(icase).Data())) { if (icase == 0) { // previously known as electronPID_TOFnsigma_tight // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -3., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 3.5, true, VarManager::kPin, 0.0, 1e+10, false); @@ -6190,7 +6293,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TOFnsigma%s_strongHadRej", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TOFnsigma%s_strongHadRej", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -3., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -6203,7 +6306,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -2., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -6225,7 +6328,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) std::vector cutVar_TOFnSigmaEl_up = {4., 2., 4., 2., 4., 3., 2., 3., 3., 3., 4., 3., 2., 3., 4., 3., 3., 3., 4., 4., 2., 2., 2., 3., 3., 3., 2., 3., 2., 4}; for (unsigned int i = 0; i < cutVar_TOFnSigmaEl_low.size(); i++) { - if (!nameStr.compare(Form("electronPID_TOFnsigma_cutVar%s%i", vecPIDcase.at(icase).Data(), i))) { + if (nameStr == Form("electronPID_TOFnsigma_cutVar%s%i", vecPIDcase.at(icase).Data(), i)) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, cutVar_TPCnSigmaEl_low.at(i), cutVar_TPCnSigmaEl_up.at(i), false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, cutVar_TPCnSigmaPi_low.at(i), cutVar_TPCnSigmaPi_up.at(i), true, VarManager::kPin, 0.0, 1e+10, false); @@ -6239,7 +6342,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) } } - if (!nameStr.compare(Form("electronPID_TPC_TOFnsigma%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TPC_TOFnsigma%s", vecPIDcase.at(icase).Data())) { if (icase == 0) { // previously known as electronPID_TOFnsigma_tight // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -3., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 3.5, true, VarManager::kPin, 0.0, 1e+10, false); @@ -6256,7 +6359,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_lowB_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_lowB_TOFnsigma%s_strongNSigE", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -2., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.3, 1e+10, false); @@ -6271,7 +6374,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_lowB_TOFnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_lowB_TOFnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -2., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.3, 1e+10, false); @@ -6288,7 +6391,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TOFnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TOFnsigma%s_strongNSigE_rejBadTOF", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -2., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -6303,7 +6406,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TOFnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TOFnsigma%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -1., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -6318,7 +6421,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TOFnsigma%s_tightNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TOFnsigma%s_tightNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, 0., 3., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -6333,7 +6436,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TOFreq%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TOFreq%s_strongNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -1., 2., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -6346,7 +6449,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("electronPID_TOFreq%s_tightNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("electronPID_TOFreq%s_tightNSigEPbPb_rejBadTOF", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, 0., 3., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 4., true, VarManager::kPin, 0.0, 1e+10, false); @@ -6359,7 +6462,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_pp_502TeV_TOF%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_pp_502TeV_TOF%s", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -3., 3., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -99., 3.5, true, VarManager::kPin, 0.0, 1e+10, false); @@ -6372,7 +6475,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_pp_502TeV_lowB_TOF%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_pp_502TeV_lowB_TOF%s", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -3., 3., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -3., 3.5, true, VarManager::kPin, 0.0, 1e+10, false); @@ -6387,7 +6490,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_pp_502TeV_TOFloose%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_pp_502TeV_TOFloose%s", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -4., 4., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -99., 3., true, VarManager::kPin, 0.0, 4.0, false); @@ -6402,7 +6505,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare(Form("lmee_pp_502TeV_TOFloose_pionrej%s", vecPIDcase.at(icase).Data()))) { + if (nameStr == Form("lmee_pp_502TeV_TOFloose_pionrej%s", vecPIDcase.at(icase).Data())) { if (icase == 0) { // o2-linter: disable=magic-number (number of cuts) cut->AddCut(VarManager::kTPCnSigmaEl, -4., 4., false, VarManager::kPin, 0.0, 1e+10, false); cut->AddCut(VarManager::kTPCnSigmaPi, -99., 3.5, true, VarManager::kPin, 0.0, 2.0, false); @@ -6420,27 +6523,27 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) // ------------------------------------------------------------------------------------------------- // Muon cuts - if (!nameStr.compare("GlobalMuonTrack")) { + if (nameStr == "GlobalMuonTrack") { cut->AddCut(VarManager::kMuonTrackType, -0.5, 0.5); return cut; } - if (!nameStr.compare("MFTMCH")) { + if (nameStr == "MFTMCH") { cut->AddCut(VarManager::kMuonTrackType, 1.5, 2.5); return cut; } - if (!nameStr.compare("MCHMID")) { + if (nameStr == "MCHMID") { cut->AddCut(VarManager::kMuonTrackType, 2.5, 3.5); return cut; } - if (!nameStr.compare("MCHStandalone")) { + if (nameStr == "MCHStandalone") { cut->AddCut(VarManager::kMuonTrackType, 3.5, 4.5); return cut; } - if (!nameStr.compare("muonMinimalCuts")) { + if (nameStr == "muonMinimalCuts") { cut->AddCut(VarManager::kEta, -4.0, -2.5); cut->AddCut(VarManager::kMuonRAtAbsorberEnd, 17.6, 89.5); cut->AddCut(VarManager::kMuonPDca, 0.0, 594.0, false, VarManager::kMuonRAtAbsorberEnd, 17.6, 26.5); @@ -6448,7 +6551,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("muonMinimalCuts10SigmaPDCA")) { + if (nameStr == "muonMinimalCuts10SigmaPDCA") { cut->AddCut(VarManager::kEta, -4.0, -2.5); cut->AddCut(VarManager::kMuonRAtAbsorberEnd, 17.6, 89.5); cut->AddCut(VarManager::kMuonPDca, 0.0, 990.0, false, VarManager::kMuonRAtAbsorberEnd, 17.6, 26.5); @@ -6456,7 +6559,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("muonQualityCuts")) { + if (nameStr == "muonQualityCuts") { cut->AddCut(VarManager::kEta, -4.0, -2.5); cut->AddCut(VarManager::kMuonRAtAbsorberEnd, 17.6, 89.5); cut->AddCut(VarManager::kMuonPDca, 0.0, 594.0, false, VarManager::kMuonRAtAbsorberEnd, 17.6, 26.5); @@ -6466,7 +6569,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("muonQualityCuts5SigmaPDCA_Run3")) { + if (nameStr == "muonQualityCuts5SigmaPDCA_Run3") { cut->AddCut(VarManager::kEta, -4.0, -2.5); cut->AddCut(VarManager::kMuonRAtAbsorberEnd, 17.6, 89.5); cut->AddCut(VarManager::kMuonPDca, 0.0, 500.0, false, VarManager::kMuonRAtAbsorberEnd, 17.6, 26.5); @@ -6476,7 +6579,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("muonQualityCuts10SigmaPDCA")) { + if (nameStr == "muonQualityCuts10SigmaPDCA") { cut->AddCut(VarManager::kEta, -4.0, -2.5); cut->AddCut(VarManager::kMuonRAtAbsorberEnd, 17.6, 89.5); cut->AddCut(VarManager::kMuonPDca, 0.0, 990.0, false, VarManager::kMuonRAtAbsorberEnd, 17.6, 26.5); @@ -6486,7 +6589,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("matchedQualityCuts")) { + if (nameStr == "matchedQualityCuts") { cut->AddCut(VarManager::kEta, -4.0, -2.5); cut->AddCut(VarManager::kMuonRAtAbsorberEnd, 17.6, 89.5); cut->AddCut(VarManager::kMuonPDca, 0.0, 594.0, false, VarManager::kMuonRAtAbsorberEnd, 17.6, 26.5); @@ -6497,7 +6600,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("matchedQualityCutsMFTeta")) { + if (nameStr == "matchedQualityCutsMFTeta") { cut->AddCut(VarManager::kEta, -3.6, -2.5); cut->AddCut(VarManager::kMuonRAtAbsorberEnd, 17.6, 89.5); cut->AddCut(VarManager::kMuonPDca, 0.0, 594.0, false, VarManager::kMuonRAtAbsorberEnd, 17.6, 26.5); @@ -6508,74 +6611,74 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("muonQualityCutsMatchingOnly")) { + if (nameStr == "muonQualityCutsMatchingOnly") { cut->AddCut(VarManager::kEta, -4.0, -2.5); cut->AddCut(VarManager::kMuonChi2, 0.0, 1e6); cut->AddCut(VarManager::kMuonChi2MatchMCHMID, 0.0, 1e6); // matching MCH-MID return cut; } - if (!nameStr.compare("muonLowPt")) { + if (nameStr == "muonLowPt") { cut->AddCut(VarManager::kPt, 0.5, 1000.0); return cut; } - if (!nameStr.compare("muonLowPt2")) { + if (nameStr == "muonLowPt2") { cut->AddCut(VarManager::kPt, 0.7, 1000.0); return cut; } - if (!nameStr.compare("muonLowPt3")) { + if (nameStr == "muonLowPt3") { cut->AddCut(VarManager::kPt, 0.8, 1000.0); return cut; } - if (!nameStr.compare("muonLowPt4")) { + if (nameStr == "muonLowPt4") { cut->AddCut(VarManager::kPt, 0.9, 1000.0); return cut; } - if (!nameStr.compare("muonLowPt5")) { + if (nameStr == "muonLowPt5") { cut->AddCut(VarManager::kPt, 1.0, 1000.0); return cut; } - if (!nameStr.compare("muonLowPt6")) { + if (nameStr == "muonLowPt6") { cut->AddCut(VarManager::kPt, 2.0, 1000.0); return cut; } - if (!nameStr.compare("muonHighPt")) { + if (nameStr == "muonHighPt") { cut->AddCut(VarManager::kPt, 3.0, 1000.0); return cut; } - if (!nameStr.compare("muonHighPt2")) { + if (nameStr == "muonHighPt2") { cut->AddCut(VarManager::kPt, 4.0, 1000.0); return cut; } - if (!nameStr.compare("muonHighPt3")) { + if (nameStr == "muonHighPt3") { cut->AddCut(VarManager::kPt, 6.0, 1000.0); return cut; } - if (!nameStr.compare("muonHighPt4")) { + if (nameStr == "muonHighPt4") { cut->AddCut(VarManager::kPt, 8.0, 1000.0); return cut; } - if (!nameStr.compare("muonHighPt5")) { + if (nameStr == "muonHighPt5") { cut->AddCut(VarManager::kPt, 10.0, 1000.0); return cut; } - if (!nameStr.compare("muonHighPt6")) { + if (nameStr == "muonHighPt6") { cut->AddCut(VarManager::kPt, 20.0, 1000.0); return cut; } - if (!nameStr.compare("muonTightQualityCutsForTests")) { + if (nameStr == "muonTightQualityCutsForTests") { cut->AddCut(VarManager::kEta, -4.0, -2.5); cut->AddCut(VarManager::kMuonRAtAbsorberEnd, 20.0, 60.0); cut->AddCut(VarManager::kMuonPDca, 0.0, 594.0, false, VarManager::kMuonRAtAbsorberEnd, 17.6, 26.5); @@ -6584,49 +6687,49 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("mchTrack")) { + if (nameStr == "mchTrack") { cut->AddCut(VarManager::kMuonTrackType, 3.5, 4.5); return cut; } - if (!nameStr.compare("matchedMchMid")) { + if (nameStr == "matchedMchMid") { cut->AddCut(VarManager::kMuonTrackType, 2.5, 3.5); return cut; } - if (!nameStr.compare("matchedFwd")) { + if (nameStr == "matchedFwd") { cut->AddCut(VarManager::kMuonTrackType, 1.5, 2.5); return cut; } - if (!nameStr.compare("matchedGlobal")) { + if (nameStr == "matchedGlobal") { cut->AddCut(VarManager::kMuonTrackType, -0.5, 0.5); return cut; } - if (!nameStr.compare("Chi2MCHMFTCut1")) { + if (nameStr == "Chi2MCHMFTCut1") { cut->AddCut(VarManager::kMuonChi2MatchMCHMFT, 0, 30); return cut; } - if (!nameStr.compare("Chi2MCHMFTCut2")) { + if (nameStr == "Chi2MCHMFTCut2") { cut->AddCut(VarManager::kMuonChi2MatchMCHMFT, 0, 40); return cut; } - if (!nameStr.compare("Chi2MCHMFTCut3")) { + if (nameStr == "Chi2MCHMFTCut3") { cut->AddCut(VarManager::kMuonChi2MatchMCHMFT, 0, 50); return cut; } - if (!nameStr.compare("Chi2MCHMFTCut4")) { + if (nameStr == "Chi2MCHMFTCut4") { cut->AddCut(VarManager::kMuonChi2MatchMCHMFT, 0, 60); return cut; } // ----------------------------------------------------------------------------------------------- // Pair cuts - if (!nameStr.compare("pairDalitz1")) { + if (nameStr == "pairDalitz1") { cut->AddCut(VarManager::kMass, 0.0, 0.015, false, VarManager::kPt, 0., 1.); cut->AddCut(VarManager::kMass, 0.0, 0.035, false, VarManager::kPt, 0., 1., true); std::shared_ptr fcutHigh = std::make_shared("f1", "[0] - [0]/[1]*x", -1.5, 1.5); @@ -6637,318 +6740,318 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("pairDalitz1Strong")) { + if (nameStr == "pairDalitz1Strong") { cut->AddCut(VarManager::kMass, 0.0, 0.015, false, VarManager::kPt, 0., 1.); cut->AddCut(VarManager::kMass, 0.0, 0.035, false, VarManager::kPt, 0., 1., true); cut->AddCut(VarManager::kDeltaPhiPair, -1., 0.); return cut; } - if (!nameStr.compare("pairDalitz2")) { + if (nameStr == "pairDalitz2") { cut->AddCut(VarManager::kMass, 0.0, 0.015, false, VarManager::kPt, 0., 1.); cut->AddCut(VarManager::kMass, 0.0, 0.035, false, VarManager::kPt, 0., 1., true); return cut; } - if (!nameStr.compare("pairDalitz3")) { + if (nameStr == "pairDalitz3") { cut->AddCut(VarManager::kMass, 0.0, 0.15); return cut; } - if (!nameStr.compare("paira_prefilter1")) { + if (nameStr == "paira_prefilter1") { cut->AddCut(VarManager::kMass, 0.0, 0.06); return cut; } - if (!nameStr.compare("paira_prefilter2")) { + if (nameStr == "paira_prefilter2") { cut->AddCut(VarManager::kMass, 0.0, 0.06); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.025); return cut; } - if (!nameStr.compare("paira_prefilter3")) { + if (nameStr == "paira_prefilter3") { cut->AddCut(VarManager::kMass, 0.0, 0.06); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.05); return cut; } - if (!nameStr.compare("paira_prefilter4")) { + if (nameStr == "paira_prefilter4") { cut->AddCut(VarManager::kMass, 0.0, 0.06); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.075); return cut; } - if (!nameStr.compare("paira_prefilter5")) { + if (nameStr == "paira_prefilter5") { cut->AddCut(VarManager::kMass, 0.0, 0.06); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.1); return cut; } - if (!nameStr.compare("paira_prefilter6")) { + if (nameStr == "paira_prefilter6") { cut->AddCut(VarManager::kMass, 0.0, 0.06); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.125); return cut; } - if (!nameStr.compare("paira_prefilter7")) { + if (nameStr == "paira_prefilter7") { cut->AddCut(VarManager::kMass, 0.0, 0.06); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.15); return cut; } - if (!nameStr.compare("pairb_prefilter1")) { + if (nameStr == "pairb_prefilter1") { cut->AddCut(VarManager::kMass, 0.0, 0.05); return cut; } - if (!nameStr.compare("pairb_prefilter2")) { + if (nameStr == "pairb_prefilter2") { cut->AddCut(VarManager::kMass, 0.0, 0.05); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.025); return cut; } - if (!nameStr.compare("pairb_prefilter3")) { + if (nameStr == "pairb_prefilter3") { cut->AddCut(VarManager::kMass, 0.0, 0.05); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.05); return cut; } - if (!nameStr.compare("pairb_prefilter4")) { + if (nameStr == "pairb_prefilter4") { cut->AddCut(VarManager::kMass, 0.0, 0.05); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.075); return cut; } - if (!nameStr.compare("pairb_prefilter5")) { + if (nameStr == "pairb_prefilter5") { cut->AddCut(VarManager::kMass, 0.0, 0.05); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.1); return cut; } - if (!nameStr.compare("pairb_prefilter6")) { + if (nameStr == "pairb_prefilter6") { cut->AddCut(VarManager::kMass, 0.0, 0.05); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.125); return cut; } - if (!nameStr.compare("pairb_prefilter7")) { + if (nameStr == "pairb_prefilter7") { cut->AddCut(VarManager::kMass, 0.0, 0.05); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.15); return cut; } - if (!nameStr.compare("pairc_prefilter1")) { + if (nameStr == "pairc_prefilter1") { cut->AddCut(VarManager::kMass, 0.0, 0.04); return cut; } - if (!nameStr.compare("pairc_prefilter2")) { + if (nameStr == "pairc_prefilter2") { cut->AddCut(VarManager::kMass, 0.0, 0.04); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.025); return cut; } - if (!nameStr.compare("pairc_prefilter3")) { + if (nameStr == "pairc_prefilter3") { cut->AddCut(VarManager::kMass, 0.0, 0.04); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.05); return cut; } - if (!nameStr.compare("pairc_prefilter4")) { + if (nameStr == "pairc_prefilter4") { cut->AddCut(VarManager::kMass, 0.0, 0.04); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.075); return cut; } - if (!nameStr.compare("pairc_prefilter5")) { + if (nameStr == "pairc_prefilter5") { cut->AddCut(VarManager::kMass, 0.0, 0.04); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.1); return cut; } - if (!nameStr.compare("pairc_prefilter6")) { + if (nameStr == "pairc_prefilter6") { cut->AddCut(VarManager::kMass, 0.0, 0.04); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.125); return cut; } - if (!nameStr.compare("pairc_prefilter7")) { + if (nameStr == "pairc_prefilter7") { cut->AddCut(VarManager::kMass, 0.0, 0.04); cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.15); return cut; } - if (!nameStr.compare("paird_prefilter1")) { + if (nameStr == "paird_prefilter1") { cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.025); return cut; } - if (!nameStr.compare("paire_prefilter1")) { + if (nameStr == "paire_prefilter1") { cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.05); return cut; } - if (!nameStr.compare("pairf_prefilter1")) { + if (nameStr == "pairf_prefilter1") { cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.075); return cut; } - if (!nameStr.compare("pairg_prefilter1")) { + if (nameStr == "pairg_prefilter1") { cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.1); return cut; } - if (!nameStr.compare("pairh_prefilter1")) { + if (nameStr == "pairh_prefilter1") { cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.125); return cut; } - if (!nameStr.compare("pairi_prefilter1")) { + if (nameStr == "pairi_prefilter1") { cut->AddCut(VarManager::kOpeningAngle, 0.0, 0.15); return cut; } - if (!nameStr.compare("pairNoCut")) { + if (nameStr == "pairNoCut") { cut->AddCut(VarManager::kMass, 0.0, 1000.0); return cut; } - if (!nameStr.compare("DipionMassCut1")) { + if (nameStr == "DipionMassCut1") { cut->AddCut(VarManager::kMass, 0.5, 1.0); return cut; } - if (!nameStr.compare("DipionMassCut2")) { + if (nameStr == "DipionMassCut2") { cut->AddCut(VarManager::kMass, 0.0, 1.0); return cut; } - if (!nameStr.compare("pairMassLow1")) { + if (nameStr == "pairMassLow1") { cut->AddCut(VarManager::kMass, 1.0, 1000.0); return cut; } - if (!nameStr.compare("pairMassLow2")) { + if (nameStr == "pairMassLow2") { cut->AddCut(VarManager::kMass, 1.5, 1000.0); return cut; } - if (!nameStr.compare("pairMassLow3")) { + if (nameStr == "pairMassLow3") { cut->AddCut(VarManager::kMass, 1.6, 1000.0); return cut; } - if (!nameStr.compare("pairMassLow4")) { + if (nameStr == "pairMassLow4") { cut->AddCut(VarManager::kMass, 1.7, 1000.0); return cut; } - if (!nameStr.compare("pairMassLow5")) { + if (nameStr == "pairMassLow5") { cut->AddCut(VarManager::kMass, 1.8, 1000.0); return cut; } - if (!nameStr.compare("pairMassLow6")) { + if (nameStr == "pairMassLow6") { cut->AddCut(VarManager::kMass, 1.85, 1000.0); return cut; } - if (!nameStr.compare("pairMassLow7")) { + if (nameStr == "pairMassLow7") { cut->AddCut(VarManager::kMass, 1.9, 1000.0); return cut; } - if (!nameStr.compare("pairMassLow8")) { + if (nameStr == "pairMassLow8") { cut->AddCut(VarManager::kMass, 2.0, 1000.0); return cut; } - if (!nameStr.compare("pairMassLow9")) { + if (nameStr == "pairMassLow9") { cut->AddCut(VarManager::kMass, 2.2, 1000.0); return cut; } - if (!nameStr.compare("pairMassLow10")) { + if (nameStr == "pairMassLow10") { cut->AddCut(VarManager::kMass, 2.5, 1000.0); return cut; } - if (!nameStr.compare("pairMassLow11")) { + if (nameStr == "pairMassLow11") { cut->AddCut(VarManager::kMass, 3.0, 1000.0); return cut; } - if (!nameStr.compare("pairMassLow12")) { + if (nameStr == "pairMassLow12") { cut->AddCut(VarManager::kMass, 3.5, 1000.0); return cut; } - if (!nameStr.compare("pairMass1to2")) { + if (nameStr == "pairMass1to2") { cut->AddCut(VarManager::kMass, 1., 2.); return cut; } - if (!nameStr.compare("pairMassIMR")) { + if (nameStr == "pairMassIMR") { cut->AddCut(VarManager::kMass, 1.1, 2.7); return cut; } - if (!nameStr.compare("pairMass1_5to2_7")) { + if (nameStr == "pairMass1_5to2_7") { cut->AddCut(VarManager::kMass, 1.5, 2.7); return cut; } - if (!nameStr.compare("pairMass1_3to3_5")) { + if (nameStr == "pairMass1_3to3_5") { cut->AddCut(VarManager::kMass, 1.3, 3.5); return cut; } - if (!nameStr.compare("pairMass1_3")) { + if (nameStr == "pairMass1_3") { cut->AddCut(VarManager::kMass, 1.3, 1000.0); return cut; } - if (!nameStr.compare("pairMass1_5to3_5")) { + if (nameStr == "pairMass1_5to3_5") { cut->AddCut(VarManager::kMass, 1.5, 3.5); return cut; } - if (!nameStr.compare("pairD0")) { + if (nameStr == "pairD0") { cut->AddCut(VarManager::kMass, 1.814, 1.914); return cut; } - if (!nameStr.compare("pairJpsi")) { + if (nameStr == "pairJpsi") { cut->AddCut(VarManager::kMass, 2.8, 3.3); return cut; } - if (!nameStr.compare("pairJpsi2")) { + if (nameStr == "pairJpsi2") { cut->AddCut(VarManager::kMass, 2.72, 3.2); return cut; } - if (!nameStr.compare("pairJpsi3")) { + if (nameStr == "pairJpsi3") { cut->AddCut(VarManager::kMass, 2.92, 3.14); return cut; } - if (!nameStr.compare("pairPsi2S")) { + if (nameStr == "pairPsi2S") { cut->AddCut(VarManager::kMass, 3.4, 3.9); return cut; } - if (!nameStr.compare("pairUpsilon")) { + if (nameStr == "pairUpsilon") { cut->AddCut(VarManager::kMass, 8.0, 11.0); return cut; } - if (!nameStr.compare("pairX3872")) { + if (nameStr == "pairX3872") { cut->AddCut(VarManager::kQ, 0.0, 0.3); return cut; } - if (!nameStr.compare("pairX3872_2")) { + if (nameStr == "pairX3872_2") { cut->AddCut(VarManager::kQuadDefaultDileptonMass, 3.0, 5.0); cut->AddCut(VarManager::kQ, 0.0, 0.5); cut->AddCut(VarManager::kDeltaR, 0.0, 5.0); @@ -6956,7 +7059,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("pairX3872_3")) { + if (nameStr == "pairX3872_3") { cut->AddCut(VarManager::kQuadDefaultDileptonMass, 3.0, 5.0); cut->AddCut(VarManager::kQ, 0.0, 0.5); cut->AddCut(VarManager::kDeltaR, 0.0, 5.0); @@ -6964,104 +7067,104 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("pairPtLow1")) { + if (nameStr == "pairPtLow1") { cut->AddCut(VarManager::kPt, 2.0, 1000.0); return cut; } - if (!nameStr.compare("pairPtLow2")) { + if (nameStr == "pairPtLow2") { cut->AddCut(VarManager::kPt, 5.0, 1000.0); return cut; } - if (!nameStr.compare("pairPtLow3")) { + if (nameStr == "pairPtLow3") { cut->AddCut(VarManager::kPt, 0, 0.15); return cut; } - if (!nameStr.compare("pairPtLow4")) { + if (nameStr == "pairPtLow4") { cut->AddCut(VarManager::kPt, 0, 10.0); return cut; } - if (!nameStr.compare("pairPtLow5")) { + if (nameStr == "pairPtLow5") { cut->AddCut(VarManager::kPt, 0.8, 1000.0); return cut; } - if (!nameStr.compare("pairRapidityForward")) { + if (nameStr == "pairRapidityForward") { cut->AddCut(VarManager::kRap, 2.5, 4.0); return cut; } - if (!nameStr.compare("pairDCA")) { + if (nameStr == "pairDCA") { cut->AddCut(VarManager::kQuadDCAabsXY, .0, .50); return cut; } - if (!nameStr.compare("singleDCA")) { + if (nameStr == "singleDCA") { cut->AddCut(VarManager::kTrackDCAsigXY, 0.0, 5.); return cut; } - if (!nameStr.compare("pairPhiV")) { + if (nameStr == "pairPhiV") { cut->AddCut(VarManager::kPairPhiv, 2., 3.2); return cut; } - if (!nameStr.compare("excludePairPhiV")) { + if (nameStr == "excludePairPhiV") { cut->AddCut(VarManager::kPairPhiv, 2., 3.2, true); return cut; } - if (!nameStr.compare("pairLowMass")) { + if (nameStr == "pairLowMass") { cut->AddCut(VarManager::kMass, 0., 0.1); return cut; } - if (!nameStr.compare("excludePairLowMass")) { + if (nameStr == "excludePairLowMass") { cut->AddCut(VarManager::kMass, 0., 0.1, true); return cut; } - if (!nameStr.compare("pairLxyzProjected3sigma")) { + if (nameStr == "pairLxyzProjected3sigma") { cut->AddCut(VarManager::kVertexingLxyzProjected, 0.015, 10.); return cut; } - if (!nameStr.compare("pairTauxyzProjected1")) { + if (nameStr == "pairTauxyzProjected1") { cut->AddCut(VarManager::kVertexingTauxyzProjected, 0.0005, 10.); return cut; } - if (!nameStr.compare("pairTauxyzProjected1sigma")) { + if (nameStr == "pairTauxyzProjected1sigma") { cut->AddCut(VarManager::kVertexingTauxyzProjected, 0.003, 10.); return cut; } - if (!nameStr.compare("pairLxyProjected3sigmaLambdacCand")) { + if (nameStr == "pairLxyProjected3sigmaLambdacCand") { std::shared_ptr f1minLxyProjected = std::make_shared("f1minLxyProjected", "[0]+[1]*x", 0., 20.); f1minLxyProjected->SetParameters(0.0065, -0.00023); cut->AddCut(VarManager::kVertexingLxyProjected, f1minLxyProjected, 1., false, VarManager::kPt, 0., 20.); return cut; } - if (!nameStr.compare("pairLxyProjected3sigmaDplusCand")) { + if (nameStr == "pairLxyProjected3sigmaDplusCand") { cut->AddCut(VarManager::kVertexingLxyProjected, 0.009, 10.); return cut; } - if (!nameStr.compare("pairCosPointingPos")) { + if (nameStr == "pairCosPointingPos") { cut->AddCut(VarManager::kCosPointingAngle, 0.9, 1000.); return cut; } - if (!nameStr.compare("pairCosPointingNeg90")) { + if (nameStr == "pairCosPointingNeg90") { cut->AddCut(VarManager::kCosPointingAngle, -1000., -0.9); return cut; } - if (!nameStr.compare("pairCosPointingNeg85")) { + if (nameStr == "pairCosPointingNeg85") { cut->AddCut(VarManager::kCosPointingAngle, -1000., -0.85); return cut; } @@ -7071,7 +7174,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) // Below are a list of single electron single muon and pair selection in order or optimize the trigger // trigger selection cuts - if (!nameStr.compare("electronStandardQualityTriggerTest")) { + if (nameStr == "electronStandardQualityTriggerTest") { cut->AddCut(VarManager::kIsSPDany, 0.5, 1.5); cut->AddCut(VarManager::kIsITSrefit, 0.5, 1.5); cut->AddCut(VarManager::kIsTPCrefit, 0.5, 1.5); @@ -7081,7 +7184,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("muonLooseTriggerTestCuts")) { + if (nameStr == "muonLooseTriggerTestCuts") { cut->AddCut(VarManager::kEta, -4.5, -2.0); cut->AddCut(VarManager::kMuonRAtAbsorberEnd, 10, 100); cut->AddCut(VarManager::kMuonPDca, 0.0, 1500, false, VarManager::kMuonRAtAbsorberEnd, 10, 26.5); @@ -7091,7 +7194,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("muonMatchingMFTMCHTriggerTestCuts")) { + if (nameStr == "muonMatchingMFTMCHTriggerTestCuts") { cut->AddCut(VarManager::kEta, -4.5, -2.0); cut->AddCut(VarManager::kMuonRAtAbsorberEnd, 10, 100); cut->AddCut(VarManager::kMuonPDca, 0.0, 1500, false, VarManager::kMuonRAtAbsorberEnd, 10, 26.5); @@ -7102,7 +7205,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsi_TPCPID_TriggerTest1")) { + if (nameStr == "jpsi_TPCPID_TriggerTest1") { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -3.0, 4.0, false, VarManager::kPin, 0, 2.0); cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -2.0, 4.0, false, VarManager::kPin, 2.0, 9999.0); cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 3.0, 999, false, VarManager::kPin, 0, 2.0); @@ -7110,7 +7213,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsi_TPCPID_TriggerTest2")) { + if (nameStr == "jpsi_TPCPID_TriggerTest2") { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -3.0, 4.0, false, VarManager::kPin, 0, 2.0); cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -2.0, 4.0, false, VarManager::kPin, 2.0, 9999.0); cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 2.5, 999, false, VarManager::kPin, 0, 2.0); @@ -7118,7 +7221,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsi_TPCPID_TriggerTest3")) { + if (nameStr == "jpsi_TPCPID_TriggerTest3") { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -3.0, 4.0, false, VarManager::kPin, 0, 3.0); cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -2.0, 4.0, false, VarManager::kPin, 3.0, 9999.0); cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 3.0, 999, false, VarManager::kPin, 0, 2.0); @@ -7126,7 +7229,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("jpsi_TPCPID_TriggerTest4")) { + if (nameStr == "jpsi_TPCPID_TriggerTest4") { cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -3.0, 4.0, false, VarManager::kPin, 0, 3.0); cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -2.0, 4.0, false, VarManager::kPin, 3.0, 9999.0); cut->AddCut(VarManager::kTPCnSigmaPi_Corr, 2.5, 999, false, VarManager::kPin, 0, 2.0); @@ -7137,49 +7240,49 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) //--------------------------------------------------------------- // ALICE 3 Analysis Cuts - if (!nameStr.compare("alice3KineSkim")) { + if (nameStr == "alice3KineSkim") { cut->AddCut(VarManager::kPt, 0.05, 1000.0); cut->AddCut(VarManager::kEta, -4.0, 4.0); return cut; } - if (!nameStr.compare("alice3StandardKine")) { + if (nameStr == "alice3StandardKine") { cut->AddCut(VarManager::kPt, 0.1, 1000.0); cut->AddCut(VarManager::kEta, -2.5, 2.5); // Total tracker acceptance in v3b geomety return cut; } - if (!nameStr.compare("alice3KineTOFAcceptance")) { + if (nameStr == "alice3KineTOFAcceptance") { cut->AddCut(VarManager::kPt, 0.1, 1000.0); cut->AddCut(VarManager::kEta, -2.0, 2.0); // TOF acceptance in v3b geomety return cut; } - if (!nameStr.compare("alice3KineRICHAcceptance")) { + if (nameStr == "alice3KineRICHAcceptance") { cut->AddCut(VarManager::kPt, 0.1, 1000.0); cut->AddCut(VarManager::kEta, -0.8, 0.8); // RICH acceptance in v3b geomety return cut; } - if (!nameStr.compare("alice3JpsiKine")) { + if (nameStr == "alice3JpsiKine") { cut->AddCut(VarManager::kPt, 1.0, 1000.0); cut->AddCut(VarManager::kEta, -2.5, 2.5); // Total tracker acceptance in v3b geomety return cut; } - if (!nameStr.compare("alice3JpsiKineTOFAcceptance")) { + if (nameStr == "alice3JpsiKineTOFAcceptance") { cut->AddCut(VarManager::kPt, 1.0, 1000.0); cut->AddCut(VarManager::kEta, -2.0, 2.0); // TOF acceptance in v3b geomety return cut; } - if (!nameStr.compare("alice3JpsiKineRICHAcceptance")) { + if (nameStr == "alice3JpsiKineRICHAcceptance") { cut->AddCut(VarManager::kPt, 1.0, 1000.0); cut->AddCut(VarManager::kEta, -0.8, 0.8); // RICH acceptance in v3b geomety return cut; } - if (!nameStr.compare("alice3TrackQuality")) { + if (nameStr == "alice3TrackQuality") { cut->AddCut(VarManager::kIsReconstructed, 0.5, 1.5); cut->AddCut(VarManager::kNSiliconHits, 6.0, 12.0); cut->AddCut(VarManager::kTrackDCAxy, -3.0, 3.0); @@ -7187,7 +7290,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("alice3TrackQualityTightDCA")) { + if (nameStr == "alice3TrackQualityTightDCA") { cut->AddCut(VarManager::kIsReconstructed, 0.5, 1.5); cut->AddCut(VarManager::kNSiliconHits, 6.0, 12.0); cut->AddCut(VarManager::kTrackDCAxy, -1.0, 1.0); @@ -7195,90 +7298,90 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("alice3OTPIDEl")) { + if (nameStr == "alice3OTPIDEl") { cut->AddCut(VarManager::kOTnSigmaEl, -3.0, 3.0); return cut; } - if (!nameStr.compare("alice3OTPIDPi")) { + if (nameStr == "alice3OTPIDPi") { cut->AddCut(VarManager::kOTnSigmaPi, -3.0, 3.0); return cut; } - if (!nameStr.compare("alice3OTPIDKa")) { + if (nameStr == "alice3OTPIDKa") { cut->AddCut(VarManager::kOTnSigmaKa, -3.0, 3.0); return cut; } - if (!nameStr.compare("alice3OTPIDPr")) { + if (nameStr == "alice3OTPIDPr") { cut->AddCut(VarManager::kOTnSigmaPr, -3.0, 3.0); return cut; } - if (!nameStr.compare("alice3iTOFPIDEl")) { + if (nameStr == "alice3iTOFPIDEl") { cut->AddCut(VarManager::kInnerTOFnSigmaEl, -3.0, 3.0); return cut; } - if (!nameStr.compare("alice3iTOFPIDPi")) { + if (nameStr == "alice3iTOFPIDPi") { cut->AddCut(VarManager::kInnerTOFnSigmaPi, -3.0, 3.0); return cut; } - if (!nameStr.compare("alice3iTOFPIDKa")) { + if (nameStr == "alice3iTOFPIDKa") { cut->AddCut(VarManager::kInnerTOFnSigmaKa, -3.0, 3.0); return cut; } - if (!nameStr.compare("alice3iTOFPIDPr")) { + if (nameStr == "alice3iTOFPIDPr") { cut->AddCut(VarManager::kInnerTOFnSigmaPr, -3.0, 3.0); return cut; } - if (!nameStr.compare("alice3oTOFPIDEl")) { + if (nameStr == "alice3oTOFPIDEl") { cut->AddCut(VarManager::kOuterTOFnSigmaEl, -3.0, 3.0); return cut; } - if (!nameStr.compare("alice3oTOFPIDEl")) { + if (nameStr == "alice3oTOFPIDEl") { cut->AddCut(VarManager::kOuterTOFnSigmaEl, -3.0, 3.0); return cut; } - if (!nameStr.compare("alice3oTOFPIDPi")) { + if (nameStr == "alice3oTOFPIDPi") { cut->AddCut(VarManager::kOuterTOFnSigmaPi, -3.0, 3.0); return cut; } - if (!nameStr.compare("alice3oTOFPIDKa")) { + if (nameStr == "alice3oTOFPIDKa") { cut->AddCut(VarManager::kOuterTOFnSigmaKa, -3.0, 3.0); return cut; } - if (!nameStr.compare("alice3oTOFPIDPr")) { + if (nameStr == "alice3oTOFPIDPr") { cut->AddCut(VarManager::kOuterTOFnSigmaPr, -3.0, 3.0); return cut; } - if (!nameStr.compare("alice3RICHPIDEl")) { + if (nameStr == "alice3RICHPIDEl") { cut->AddCut(VarManager::kRICHnSigmaEl, -3.0, 3.0); cut->AddCut(VarManager::kHasRICHSigEl, 0.5, 1.5); return cut; } - if (!nameStr.compare("alice3RICHPIDPi")) { + if (nameStr == "alice3RICHPIDPi") { cut->AddCut(VarManager::kRICHnSigmaPi, -3.0, 3.0); cut->AddCut(VarManager::kHasRICHSigPi, 0.5, 1.5); return cut; } - if (!nameStr.compare("alice3RICHPIDKa")) { + if (nameStr == "alice3RICHPIDKa") { cut->AddCut(VarManager::kRICHnSigmaKa, -3.0, 3.0); cut->AddCut(VarManager::kHasRICHSigKa, 0.5, 1.5); return cut; } - if (!nameStr.compare("alice3RICHPIDPr")) { + if (nameStr == "alice3RICHPIDPr") { cut->AddCut(VarManager::kRICHnSigmaPr, -3.0, 3.0); cut->AddCut(VarManager::kHasRICHSigPr, 0.5, 1.5); return cut; @@ -7497,7 +7600,7 @@ AnalysisCut* o2::aod::dqcuts::ParseJSONAnalysisCut(T cut, const char* cutName) } // construct the AnalysisCut object and add the AddCuts - AnalysisCut* retCut = new AnalysisCut(cutName, cut->HasMember("library") ? cut->FindMember("title")->value.GetString() : ""); + auto* retCut = new AnalysisCut(cutName, cut->HasMember("library") ? cut->FindMember("title")->value.GetString() : ""); // loop over all the members for this cut and configure the AddCut objects for (rapidjson::Value::ConstMemberIterator it = cut->MemberBegin(); it != cut->MemberEnd(); it++) { @@ -7628,7 +7731,7 @@ AnalysisCompositeCut* o2::aod::dqcuts::ParseJSONAnalysisCompositeCut(T cut, cons return GetCompositeCut(cut->FindMember("library")->value.GetString()); } - AnalysisCompositeCut* retCut = new AnalysisCompositeCut(cutName, cut->HasMember("library") ? cut->FindMember("title")->value.GetString() : "", cut->FindMember("useAND")->value.GetBool()); + auto* retCut = new AnalysisCompositeCut(cutName, cut->HasMember("library") ? cut->FindMember("title")->value.GetString() : "", cut->FindMember("useAND")->value.GetBool()); // Loop to find AddCut objects for (rapidjson::Value::ConstMemberIterator it = cut->MemberBegin(); it != cut->MemberEnd(); it++) { @@ -7756,8 +7859,9 @@ o2::aod::dqmlcuts::BdtScoreConfig o2::aod::dqmlcuts::GetBdtScoreCutsAndConfigFro for (auto centMember = obj.MemberBegin(); centMember != obj.MemberEnd(); ++centMember) { TString centKey = centMember->name.GetString(); - if (!centKey.Contains("AddCentCut")) + if (!centKey.Contains("AddCentCut")) { continue; + } const auto& centCut = centMember->value; @@ -7771,8 +7875,9 @@ o2::aod::dqmlcuts::BdtScoreConfig o2::aod::dqmlcuts::GetBdtScoreCutsAndConfigFro for (auto ptMember = centCut.MemberBegin(); ptMember != centCut.MemberEnd(); ++ptMember) { TString ptKey = ptMember->name.GetString(); - if (!ptKey.Contains("AddPtCut")) + if (!ptKey.Contains("AddPtCut")) { continue; + } const auto& ptCut = ptMember->value; @@ -7790,8 +7895,9 @@ o2::aod::dqmlcuts::BdtScoreConfig o2::aod::dqmlcuts::GetBdtScoreCutsAndConfigFro for (auto mlMember = ptCut.MemberBegin(); mlMember != ptCut.MemberEnd(); ++mlMember) { TString mlKey = mlMember->name.GetString(); - if (!mlKey.Contains("AddMLCut")) + if (!mlKey.Contains("AddMLCut")) { continue; + } const auto& mlcut = mlMember->value; @@ -7822,8 +7928,9 @@ o2::aod::dqmlcuts::BdtScoreConfig o2::aod::dqmlcuts::GetBdtScoreCutsAndConfigFro std::string msg = ""; for (size_t i = 0; i < binCuts.size(); ++i) { msg += std::to_string(binCuts[i]); - if (i != binCuts.size() - 1) + if (i != binCuts.size() - 1) { msg += ", "; + } } msg += "] and direction: "; msg += (exclude ? "CutGreater" : "CutSmaller"); @@ -7838,6 +7945,7 @@ o2::aod::dqmlcuts::BdtScoreConfig o2::aod::dqmlcuts::GetBdtScoreCutsAndConfigFro } std::vector labelsClass; + labelsClass.reserve(cutsMl[0].size()); for (size_t j = 0; j < cutsMl[0].size(); ++j) { labelsClass.push_back(Form("score class %d", static_cast(j))); } diff --git a/PWGDQ/Core/HistogramManager.cxx b/PWGDQ/Core/HistogramManager.cxx index ae1c4be3022..ae062e371e3 100644 --- a/PWGDQ/Core/HistogramManager.cxx +++ b/PWGDQ/Core/HistogramManager.cxx @@ -43,8 +43,6 @@ using namespace std; #include #include -ClassImp(HistogramManager); - //_______________________________________________________________________________ HistogramManager::HistogramManager() : TNamed("", ""), fMainList(nullptr), diff --git a/PWGDQ/Core/HistogramManager.h b/PWGDQ/Core/HistogramManager.h index 94aa3ecec00..ec8781ea66a 100644 --- a/PWGDQ/Core/HistogramManager.h +++ b/PWGDQ/Core/HistogramManager.h @@ -115,8 +115,6 @@ class HistogramManager : public TNamed HistogramManager& operator=(const HistogramManager& c); HistogramManager(const HistogramManager& c); - - ClassDef(HistogramManager, 2) }; #endif // PWGDQ_CORE_HISTOGRAMMANAGER_H_ diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx index edfcf3d4985..a2a3dcc005a 100644 --- a/PWGDQ/Core/HistogramsLibrary.cxx +++ b/PWGDQ/Core/HistogramsLibrary.cxx @@ -55,7 +55,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "TF_NMuons", "Number of muons per TF", false, 1000, 0.0, 5000.0, VarManager::kTFNMuons); hm->AddHistogram(histClass, "TF_NMFTs", "Number of MFT tracks per TF", false, 1000, 0.0, 200000.0, VarManager::kTFNMFTs); } - if (!groupStr.CompareTo("event")) { + if (groupStr.CompareTo("event") == 0) { if (!subGroupStr.Contains("generator") && !subGroupStr.Contains("pairing")) { hm->AddHistogram(histClass, "VtxZ", "Vtx Z", false, 60, -15.0, 15.0, VarManager::kVtxZ); hm->AddHistogram(histClass, "VtxZ_Run", "Vtx Z", true, 1, -0.5, 0.5, VarManager::kRunNo, 60, -15.0, 15.0, VarManager::kVtxZ, 1, 0, 1, VarManager::kNothing, "", "", "", VarManager::kNothing, VarManager::kNothing, false, true); @@ -293,14 +293,14 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Psi2C_CentFT0C", "", false, 100, 0.0, 100.0, VarManager::kCentFT0C, 100, -2.0, 2.0, VarManager::kPsi2C); } if (subGroupStr.Contains("all-qvector")) { - int varZNA[3] = {VarManager::kQ1ZNAX, VarManager::kQ1ZNAY, VarManager::kCentFT0C}; - int varZNC[3] = {VarManager::kQ1ZNCX, VarManager::kQ1ZNCY, VarManager::kCentFT0C}; + std::array varZNA = {VarManager::kQ1ZNAX, VarManager::kQ1ZNAY, VarManager::kCentFT0C}; + std::array varZNC = {VarManager::kQ1ZNCX, VarManager::kQ1ZNCY, VarManager::kCentFT0C}; - int bins[3] = {500, 500, 18}; - double minBins[3] = {-10, -10, 0}; - double maxBins[3] = {10, 10, 90}; - hm->AddHistogram(histClass, "Q1ZNAX_Q1ZNAY_CentFT0C", "", 3, varZNA, bins, minBins, maxBins, 0, -1, kTRUE); - hm->AddHistogram(histClass, "Q1ZNCX_Q1ZNCY_CentFT0C", "", 3, varZNC, bins, minBins, maxBins, 0, -1, kTRUE); + std::array bins = {500, 500, 18}; + std::array minBins = {-10, -10, 0}; + std::array maxBins = {10, 10, 90}; + hm->AddHistogram(histClass, "Q1ZNAX_Q1ZNAY_CentFT0C", "", 3, varZNA.data(), bins.data(), minBins.data(), maxBins.data(), 0, -1, kTRUE); + hm->AddHistogram(histClass, "Q1ZNCX_Q1ZNCY_CentFT0C", "", 3, varZNC.data(), bins.data(), minBins.data(), maxBins.data(), 0, -1, kTRUE); hm->AddHistogram(histClass, "IntercalibZNA_CentFT0C", "", false, 18, 0.0, 90.0, VarManager::kCentFT0C, 500, -50.0, 50.0, VarManager::KIntercalibZNA); hm->AddHistogram(histClass, "IntercalibZNC_CentFT0C", "", false, 18, 0.0, 90.0, VarManager::kCentFT0C, 500, -50.0, 50.0, VarManager::KIntercalibZNC); @@ -628,7 +628,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h } } // end "event" - if (!groupStr.CompareTo("two-collisions")) { + if (groupStr.CompareTo("two-collisions") == 0) { hm->AddHistogram(histClass, "DeltaZ", "z_{1} - z_{2}", false, 400, -20., 20., VarManager::kTwoEvDeltaZ); hm->AddHistogram(histClass, "DeltaZ_Z1", "z_{1} - z_{2} vs z_{1}", false, 24, -12., 12., VarManager::kTwoEvPosZ1, 300, -15., 15., VarManager::kTwoEvDeltaZ); hm->AddHistogram(histClass, "DeltaR", "r_{1} - r_{2}", false, 200, -0.1, 0.1, VarManager::kTwoEvDeltaR); @@ -639,7 +639,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "NContrib1vs2", "n.contrib 1 vs 2", false, 100, 0.0, 100.0, VarManager::kTwoEvPVcontrib1, 100, 0.0, 100.0, VarManager::kTwoEvPVcontrib2); } - if (!groupStr.CompareTo("track")) { + if (groupStr.CompareTo("track") == 0) { hm->AddHistogram(histClass, "Pt", "p_{T} distribution", false, 2000, 0.0, 20.0, VarManager::kPt); hm->AddHistogram(histClass, "Eta", "#eta distribution", false, 500, -5.0, 5.0, VarManager::kEta); hm->AddHistogram(histClass, "Phi", "#varphi distribution", false, 500, -2. * o2::constants::math::PI, 2. * o2::constants::math::PI, VarManager::kPhi); @@ -744,32 +744,36 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h if (subGroupStr.Contains("tpcpid")) { if (subGroupStr.Contains("tpcpid_fine")) { // fine binning for pIN: steps in 10 MeV/c from 0 to 1 GeV/c and 100 MeV/c up to 10 GeV/c - double pIN_bins[281]; - for (int i = 0; i <= 200; i++) + std::array pIN_bins; + for (int i = 0; i <= 200; i++) { pIN_bins[i] = 0.01 * i; - for (int i = 1; i <= 80; i++) + } + for (int i = 1; i <= 80; i++) { pIN_bins[200 + i] = 2. + 0.1 * i; - int nbins_pIN = sizeof(pIN_bins) / sizeof(*pIN_bins) - 1; + } + int nbins_pIN = static_cast(pIN_bins.size()) - 1; - double TPCdEdx_bins[201]; - for (int i = 0; i <= 200; i++) + std::array TPCdEdx_bins; + for (int i = 0; i <= 200; i++) { TPCdEdx_bins[i] = i; - int nbins_TPCdEdx = sizeof(TPCdEdx_bins) / sizeof(*TPCdEdx_bins) - 1; + } + int nbins_TPCdEdx = static_cast(TPCdEdx_bins.size()) - 1; - double nSigma_bins[101]; - for (int i = 0; i <= 100; i++) + std::array nSigma_bins; + for (int i = 0; i <= 100; i++) { nSigma_bins[i] = -5. + 0.1 * i; - int nbins_nSigma = sizeof(nSigma_bins) / sizeof(*nSigma_bins) - 1; + } + int nbins_nSigma = static_cast(nSigma_bins.size()) - 1; - hm->AddHistogram(histClass, "TPCdedx_pIN", "TPC dE/dx vs pIN", false, nbins_pIN, pIN_bins, VarManager::kPin, nbins_TPCdEdx, TPCdEdx_bins, VarManager::kTPCsignal); - hm->AddHistogram(histClass, "TPCnSigEle_pIN", "TPC n-#sigma(e) vs pIN", false, nbins_pIN, pIN_bins, VarManager::kPin, nbins_nSigma, nSigma_bins, VarManager::kTPCnSigmaEl); - hm->AddHistogram(histClass, "TPCnSigPi_pIN", "TPC n-#sigma(#pi) vs pIN", false, nbins_pIN, pIN_bins, VarManager::kPin, nbins_nSigma, nSigma_bins, VarManager::kTPCnSigmaPi); - hm->AddHistogram(histClass, "TPCnSigKa_pIN", "TPC n-#sigma(K) vs pIN", false, nbins_pIN, pIN_bins, VarManager::kPin, nbins_nSigma, nSigma_bins, VarManager::kTPCnSigmaKa); - hm->AddHistogram(histClass, "TPCnSigPr_pIN", "TPC n-#sigma(p) vs pIN", false, nbins_pIN, pIN_bins, VarManager::kPin, nbins_nSigma, nSigma_bins, VarManager::kTPCnSigmaPr); + hm->AddHistogram(histClass, "TPCdedx_pIN", "TPC dE/dx vs pIN", false, nbins_pIN, pIN_bins.data(), VarManager::kPin, nbins_TPCdEdx, TPCdEdx_bins.data(), VarManager::kTPCsignal); + hm->AddHistogram(histClass, "TPCnSigEle_pIN", "TPC n-#sigma(e) vs pIN", false, nbins_pIN, pIN_bins.data(), VarManager::kPin, nbins_nSigma, nSigma_bins.data(), VarManager::kTPCnSigmaEl); + hm->AddHistogram(histClass, "TPCnSigPi_pIN", "TPC n-#sigma(#pi) vs pIN", false, nbins_pIN, pIN_bins.data(), VarManager::kPin, nbins_nSigma, nSigma_bins.data(), VarManager::kTPCnSigmaPi); + hm->AddHistogram(histClass, "TPCnSigKa_pIN", "TPC n-#sigma(K) vs pIN", false, nbins_pIN, pIN_bins.data(), VarManager::kPin, nbins_nSigma, nSigma_bins.data(), VarManager::kTPCnSigmaKa); + hm->AddHistogram(histClass, "TPCnSigPr_pIN", "TPC n-#sigma(p) vs pIN", false, nbins_pIN, pIN_bins.data(), VarManager::kPin, nbins_nSigma, nSigma_bins.data(), VarManager::kTPCnSigmaPr); if (subGroupStr.Contains("tpcpid_fine_corr")) { - hm->AddHistogram(histClass, "TPCnSigEl_Corr_pIN", "TPC n-#sigma(e) Corr. vs pIN", false, nbins_pIN, pIN_bins, VarManager::kPin, nbins_nSigma, nSigma_bins, VarManager::kTPCnSigmaEl_Corr); - hm->AddHistogram(histClass, "TPCnSigPi_Corr_pIN", "TPC n-#sigma(#pi) Corr. vs pIN", false, nbins_pIN, pIN_bins, VarManager::kPin, nbins_nSigma, nSigma_bins, VarManager::kTPCnSigmaPi_Corr); - hm->AddHistogram(histClass, "TPCnSigPr_Corr_pIN", "TPC n-#sigma(p) Corr. vs pIN", false, nbins_pIN, pIN_bins, VarManager::kPin, nbins_nSigma, nSigma_bins, VarManager::kTPCnSigmaPr_Corr); + hm->AddHistogram(histClass, "TPCnSigEl_Corr_pIN", "TPC n-#sigma(e) Corr. vs pIN", false, nbins_pIN, pIN_bins.data(), VarManager::kPin, nbins_nSigma, nSigma_bins.data(), VarManager::kTPCnSigmaEl_Corr); + hm->AddHistogram(histClass, "TPCnSigPi_Corr_pIN", "TPC n-#sigma(#pi) Corr. vs pIN", false, nbins_pIN, pIN_bins.data(), VarManager::kPin, nbins_nSigma, nSigma_bins.data(), VarManager::kTPCnSigmaPi_Corr); + hm->AddHistogram(histClass, "TPCnSigPr_Corr_pIN", "TPC n-#sigma(p) Corr. vs pIN", false, nbins_pIN, pIN_bins.data(), VarManager::kPin, nbins_nSigma, nSigma_bins.data(), VarManager::kTPCnSigmaPr_Corr); } } else { hm->AddHistogram(histClass, "TPCdedx_pIN", "TPC dE/dx vs pIN", false, 100, 0.0, 20.0, VarManager::kPin, 150, 0.0, 150., VarManager::kTPCsignal); @@ -818,86 +822,92 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h if (subGroupStr.Contains("postcalib")) { const int kNvarsPID = 4; const int kTPCnsigmaNbins = 70; - double tpcNsigmaBinLims[kTPCnsigmaNbins + 1]; - for (int i = 0; i <= kTPCnsigmaNbins; ++i) + std::array tpcNsigmaBinLims; + for (int i = 0; i <= kTPCnsigmaNbins; ++i) { tpcNsigmaBinLims[i] = -7.0 + 0.2 * i; + } const int kPinEleNbins = 20; - double pinEleBinLims[kPinEleNbins + 1] = {0.1, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 8.0, 10.0, 12.0, 16.0, 20.0}; + std::array pinEleBinLims = {0.1, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 8.0, 10.0, 12.0, 16.0, 20.0}; const int kEtaNbins = 9; - double etaBinLimsI[kEtaNbins + 1] = {-0.9, -0.7, -0.5, -0.3, -0.1, 0.1, 0.3, 0.5, 0.7, 0.9}; + std::array etaBinLimsI = {-0.9, -0.7, -0.5, -0.3, -0.1, 0.1, 0.3, 0.5, 0.7, 0.9}; const int kTPCnClusterbins = 16; - double tpcNclusterBinLims[kTPCnClusterbins + 1]; - for (int i = 0; i <= kTPCnClusterbins; ++i) + std::array tpcNclusterBinLims; + for (int i = 0; i <= kTPCnClusterbins; ++i) { tpcNclusterBinLims[i] = 10 * i; + } - TArrayD nSigBinLimits[kNvarsPID]; - nSigBinLimits[0] = TArrayD(kTPCnsigmaNbins + 1, tpcNsigmaBinLims); - nSigBinLimits[1] = TArrayD(kTPCnClusterbins + 1, tpcNclusterBinLims); - nSigBinLimits[2] = TArrayD(kPinEleNbins + 1, pinEleBinLims); - nSigBinLimits[3] = TArrayD(kEtaNbins + 1, etaBinLimsI); + std::array nSigBinLimits; + nSigBinLimits[0] = TArrayD(kTPCnsigmaNbins + 1, tpcNsigmaBinLims.data()); + nSigBinLimits[1] = TArrayD(kTPCnClusterbins + 1, tpcNclusterBinLims.data()); + nSigBinLimits[2] = TArrayD(kPinEleNbins + 1, pinEleBinLims.data()); + nSigBinLimits[3] = TArrayD(kEtaNbins + 1, etaBinLimsI.data()); const int kPinKaNbins = 15; - double pinKaBinLims[kPinKaNbins + 1] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 2.0, 3.0, 4.0, 5.0, 10.0}; + std::array pinKaBinLims = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 2.0, 3.0, 4.0, 5.0, 10.0}; - TArrayD nSigBinLimitsKa[kNvarsPID]; - nSigBinLimitsKa[0] = TArrayD(kTPCnsigmaNbins + 1, tpcNsigmaBinLims); - nSigBinLimitsKa[1] = TArrayD(kTPCnClusterbins + 1, tpcNclusterBinLims); - nSigBinLimitsKa[2] = TArrayD(kPinKaNbins + 1, pinKaBinLims); - nSigBinLimitsKa[3] = TArrayD(kEtaNbins + 1, etaBinLimsI); + std::array nSigBinLimitsKa; + nSigBinLimitsKa[0] = TArrayD(kTPCnsigmaNbins + 1, tpcNsigmaBinLims.data()); + nSigBinLimitsKa[1] = TArrayD(kTPCnClusterbins + 1, tpcNclusterBinLims.data()); + nSigBinLimitsKa[2] = TArrayD(kPinKaNbins + 1, pinKaBinLims.data()); + nSigBinLimitsKa[3] = TArrayD(kEtaNbins + 1, etaBinLimsI.data()); if (subGroupStr.Contains("electron")) { - int varsPIDnSigEle[kNvarsPID] = {VarManager::kTPCnSigmaEl, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; - int varsPIDnSigEle_Corr[kNvarsPID] = {VarManager::kTPCnSigmaEl_Corr, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; - hm->AddHistogram(histClass, "nSigmaTPCelectron", "TPC n_{#sigma}(e) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigEle, nSigBinLimits); - hm->AddHistogram(histClass, "nSigmaTPCelectron_Corr", "TPC n_{#sigma}^{Corr}(e) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigEle_Corr, nSigBinLimits); + std::array varsPIDnSigEle = {VarManager::kTPCnSigmaEl, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; + std::array varsPIDnSigEle_Corr = {VarManager::kTPCnSigmaEl_Corr, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; + hm->AddHistogram(histClass, "nSigmaTPCelectron", "TPC n_{#sigma}(e) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigEle.data(), nSigBinLimits.data()); + hm->AddHistogram(histClass, "nSigmaTPCelectron_Corr", "TPC n_{#sigma}^{Corr}(e) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigEle_Corr.data(), nSigBinLimits.data()); } if (subGroupStr.Contains("pion")) { - int varsPIDnSigPion[kNvarsPID] = {VarManager::kTPCnSigmaPi, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; - int varsPIDnSigPion_Corr[kNvarsPID] = {VarManager::kTPCnSigmaPi_Corr, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; - hm->AddHistogram(histClass, "nSigmaTPCpion", "TPC n_{#sigma}(pion) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigPion, nSigBinLimits); - hm->AddHistogram(histClass, "nSigmaTPCpion_Corr", "TPC n_{#sigma}^{Corr}(pion) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigPion_Corr, nSigBinLimits); + std::array varsPIDnSigPion = {VarManager::kTPCnSigmaPi, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; + std::array varsPIDnSigPion_Corr = {VarManager::kTPCnSigmaPi_Corr, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; + hm->AddHistogram(histClass, "nSigmaTPCpion", "TPC n_{#sigma}(pion) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigPion.data(), nSigBinLimits.data()); + hm->AddHistogram(histClass, "nSigmaTPCpion_Corr", "TPC n_{#sigma}^{Corr}(pion) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigPion_Corr.data(), nSigBinLimits.data()); } if (subGroupStr.Contains("kaon")) { - int varsPIDnSigKaon[kNvarsPID] = {VarManager::kTPCnSigmaKa, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; - int varsPIDnSigKaon_Corr[kNvarsPID] = {VarManager::kTPCnSigmaKa_Corr, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; - hm->AddHistogram(histClass, "nSigmaTPCkaon", "TPC n_{#sigma}(kaon) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigKaon, nSigBinLimitsKa); - hm->AddHistogram(histClass, "nSigmaTPCkaon_Corr", "TPC n_{#sigma}^{Corr}(kaon) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigKaon_Corr, nSigBinLimitsKa); + std::array varsPIDnSigKaon = {VarManager::kTPCnSigmaKa, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; + std::array varsPIDnSigKaon_Corr = {VarManager::kTPCnSigmaKa_Corr, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; + hm->AddHistogram(histClass, "nSigmaTPCkaon", "TPC n_{#sigma}(kaon) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigKaon.data(), nSigBinLimitsKa.data()); + hm->AddHistogram(histClass, "nSigmaTPCkaon_Corr", "TPC n_{#sigma}^{Corr}(kaon) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigKaon_Corr.data(), nSigBinLimitsKa.data()); } if (subGroupStr.Contains("proton")) { - int varsPIDnSigProton[kNvarsPID] = {VarManager::kTPCnSigmaPr, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; - int varsPIDnSigProton_Corr[kNvarsPID] = {VarManager::kTPCnSigmaPr_Corr, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; - hm->AddHistogram(histClass, "nSigmaTPCproton", "TPC n_{#sigma}(proton) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigProton, nSigBinLimits); - hm->AddHistogram(histClass, "nSigmaTPCproton_Corr", "TPC n_{#sigma}^{Corr}(proton) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigProton_Corr, nSigBinLimits); + std::array varsPIDnSigProton = {VarManager::kTPCnSigmaPr, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; + std::array varsPIDnSigProton_Corr = {VarManager::kTPCnSigmaPr_Corr, VarManager::kTPCncls, VarManager::kPin, VarManager::kEta}; + hm->AddHistogram(histClass, "nSigmaTPCproton", "TPC n_{#sigma}(proton) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigProton.data(), nSigBinLimits.data()); + hm->AddHistogram(histClass, "nSigmaTPCproton_Corr", "TPC n_{#sigma}^{Corr}(proton) Vs normNcluster Vs Pin Vs Eta", kNvarsPID, varsPIDnSigProton_Corr.data(), nSigBinLimits.data()); } } if (subGroupStr.Contains("tofpid")) { if (subGroupStr.Contains("tofpid_fine")) { // fine binning for pIN: steps in 10 MeV/c from 0 to 1 GeV/c and 100 MeV/c up to 10 GeV/c - double pIN_bins[281]; - for (int i = 0; i <= 200; i++) + std::array pIN_bins; + for (int i = 0; i <= 200; i++) { pIN_bins[i] = 0.01 * i; - for (int i = 1; i <= 80; i++) + } + for (int i = 1; i <= 80; i++) { pIN_bins[200 + i] = 2. + 0.1 * i; - int nbins_pIN = sizeof(pIN_bins) / sizeof(*pIN_bins) - 1; + } + int nbins_pIN = static_cast(pIN_bins.size()) - 1; - double TOFbeta_bins[241]; - for (int i = 0; i <= 240; i++) + std::array TOFbeta_bins; + for (int i = 0; i <= 240; i++) { TOFbeta_bins[i] = 0.005 * i; - int nbins_TOFbeta = sizeof(TOFbeta_bins) / sizeof(*TOFbeta_bins) - 1; + } + int nbins_TOFbeta = static_cast(TOFbeta_bins.size()) - 1; - double nSigma_bins[101]; - for (int i = 0; i <= 100; i++) + std::array nSigma_bins; + for (int i = 0; i <= 100; i++) { nSigma_bins[i] = -5. + 0.1 * i; - int nbins_nSigma = sizeof(nSigma_bins) / sizeof(*nSigma_bins) - 1; + } + int nbins_nSigma = static_cast(nSigma_bins.size()) - 1; - hm->AddHistogram(histClass, "TOFbeta_pIN", "TOF #beta vs pIN", false, nbins_pIN, pIN_bins, VarManager::kPin, nbins_TOFbeta, TOFbeta_bins, VarManager::kTOFbeta); - hm->AddHistogram(histClass, "TOFnSigEle_pIN", "TOF n-#sigma(e) vs pIN", false, nbins_pIN, pIN_bins, VarManager::kPin, nbins_nSigma, nSigma_bins, VarManager::kTOFnSigmaEl); - hm->AddHistogram(histClass, "TOFnSigPi_pIN", "TOF n-#sigma(#pi) vs pIN", false, nbins_pIN, pIN_bins, VarManager::kPin, nbins_nSigma, nSigma_bins, VarManager::kTOFnSigmaPi); - hm->AddHistogram(histClass, "TOFnSigKa_pIN", "TOF n-#sigma(K) vs pIN", false, nbins_pIN, pIN_bins, VarManager::kPin, nbins_nSigma, nSigma_bins, VarManager::kTOFnSigmaKa); - hm->AddHistogram(histClass, "TOFnSigPr_pIN", "TOF n-#sigma(p) vs pIN", false, nbins_pIN, pIN_bins, VarManager::kPin, nbins_nSigma, nSigma_bins, VarManager::kTOFnSigmaPr); + hm->AddHistogram(histClass, "TOFbeta_pIN", "TOF #beta vs pIN", false, nbins_pIN, pIN_bins.data(), VarManager::kPin, nbins_TOFbeta, TOFbeta_bins.data(), VarManager::kTOFbeta); + hm->AddHistogram(histClass, "TOFnSigEle_pIN", "TOF n-#sigma(e) vs pIN", false, nbins_pIN, pIN_bins.data(), VarManager::kPin, nbins_nSigma, nSigma_bins.data(), VarManager::kTOFnSigmaEl); + hm->AddHistogram(histClass, "TOFnSigPi_pIN", "TOF n-#sigma(#pi) vs pIN", false, nbins_pIN, pIN_bins.data(), VarManager::kPin, nbins_nSigma, nSigma_bins.data(), VarManager::kTOFnSigmaPi); + hm->AddHistogram(histClass, "TOFnSigKa_pIN", "TOF n-#sigma(K) vs pIN", false, nbins_pIN, pIN_bins.data(), VarManager::kPin, nbins_nSigma, nSigma_bins.data(), VarManager::kTOFnSigmaKa); + hm->AddHistogram(histClass, "TOFnSigPr_pIN", "TOF n-#sigma(p) vs pIN", false, nbins_pIN, pIN_bins.data(), VarManager::kPin, nbins_nSigma, nSigma_bins.data(), VarManager::kTOFnSigmaPr); } else { hm->AddHistogram(histClass, "TOFbeta_pIN", "TOF #beta vs pIN", false, 100, 0.0, 10.0, VarManager::kPin, 240, 0.0, 1.2, VarManager::kTOFbeta); hm->AddHistogram(histClass, "TOFnSigEle_pIN", "TOF n-#sigma(e) vs pIN", false, 100, 0.0, 10.0, VarManager::kPin, 100, -5.0, 5.0, VarManager::kTOFnSigmaEl); @@ -909,20 +919,25 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h if (subGroupStr.Contains("pidcorre")) { const int kNvarsPID = 3; const int kNbins_pIN = 169; - double pIN_bins[kNbins_pIN + 1]; - for (int i = 0; i <= 140; i++) + std::array pIN_bins; + for (int i = 0; i <= 140; i++) { pIN_bins[i] = 0.01 * i + 0.1; - for (int i = 1; i <= 15; i++) + } + for (int i = 1; i <= 15; i++) { pIN_bins[140 + i] = 1.5 + 0.1 * i; - for (int i = 1; i <= 14; i++) + } + for (int i = 1; i <= 14; i++) { pIN_bins[155 + i] = 3. + 0.5 * i; + } const int kNbins_pINmore = 135; - double pIN_binsmore[kNbins_pINmore + 1]; - for (int i = 0; i <= 120; i++) + std::array pIN_binsmore; + for (int i = 0; i <= 120; i++) { pIN_binsmore[i] = 0.01 * i + 0.3; - for (int i = 1; i <= 10; i++) + } + for (int i = 1; i <= 10; i++) { pIN_binsmore[120 + i] = 1.5 + 0.2 * i; + } pIN_binsmore[131] = 4.; pIN_binsmore[132] = 5.; pIN_binsmore[133] = 6.; @@ -930,55 +945,60 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h pIN_binsmore[135] = 10.; const int kNbins_nSigma = 100; - double nSigma_bins[kNbins_nSigma + 1]; - for (int i = 0; i <= kNbins_nSigma; i++) + std::array nSigma_bins; + for (int i = 0; i <= kNbins_nSigma; i++) { nSigma_bins[i] = -5. + 0.1 * i; + } const int kNbins_nSigmamore = 50; - double nSigma_binsmore[kNbins_nSigmamore + 1]; - for (int i = 0; i <= kNbins_nSigmamore; i++) + std::array nSigma_binsmore; + for (int i = 0; i <= kNbins_nSigmamore; i++) { nSigma_binsmore[i] = -5. + 0.2 * i; + } const int kNbins_nSigmagrob = 24; - double nSigma_binsgrob[kNbins_nSigmagrob + 1]; - for (int i = 0; i <= kNbins_nSigmagrob; i++) + std::array nSigma_binsgrob; + for (int i = 0; i <= kNbins_nSigmagrob; i++) { nSigma_binsgrob[i] = -6. + 0.5 * i; + } const int kNbins_TOFbeta = 120; - double TOFbeta_bins[kNbins_TOFbeta + 1]; - for (int i = 0; i <= kNbins_TOFbeta; i++) + std::array TOFbeta_bins; + for (int i = 0; i <= kNbins_TOFbeta; i++) { TOFbeta_bins[i] = 0.01 * i; + } const int kNbins_TPCdEdx = 140; - double TPCdEdx_bins[kNbins_TPCdEdx + 1]; - for (int i = 0; i <= kNbins_TPCdEdx; i++) + std::array TPCdEdx_bins; + for (int i = 0; i <= kNbins_TPCdEdx; i++) { TPCdEdx_bins[i] = i + 20; + } - TArrayD nSigmaBinLimits[kNvarsPID]; - nSigmaBinLimits[0] = TArrayD(kNbins_pIN + 1, pIN_bins); - nSigmaBinLimits[1] = TArrayD(kNbins_nSigma + 1, nSigma_bins); - nSigmaBinLimits[2] = TArrayD(kNbins_nSigma + 1, nSigma_bins); + std::array nSigmaBinLimits; + nSigmaBinLimits[0] = TArrayD(kNbins_pIN + 1, pIN_bins.data()); + nSigmaBinLimits[1] = TArrayD(kNbins_nSigma + 1, nSigma_bins.data()); + nSigmaBinLimits[2] = TArrayD(kNbins_nSigma + 1, nSigma_bins.data()); - TArrayD nSignalBinLimits[kNvarsPID]; - nSignalBinLimits[0] = TArrayD(kNbins_pIN + 1, pIN_bins); - nSignalBinLimits[1] = TArrayD(kNbins_TPCdEdx + 1, TPCdEdx_bins); - nSignalBinLimits[2] = TArrayD(kNbins_TOFbeta + 1, TOFbeta_bins); + std::array nSignalBinLimits; + nSignalBinLimits[0] = TArrayD(kNbins_pIN + 1, pIN_bins.data()); + nSignalBinLimits[1] = TArrayD(kNbins_TPCdEdx + 1, TPCdEdx_bins.data()); + nSignalBinLimits[2] = TArrayD(kNbins_TOFbeta + 1, TOFbeta_bins.data()); - int varsPIDnSignal[kNvarsPID] = {VarManager::kPin, VarManager::kTPCsignal, VarManager::kTOFbeta}; - hm->AddHistogram(histClass, "nSignalTPCTOF", "", kNvarsPID, varsPIDnSignal, nSignalBinLimits); + std::array varsPIDnSignal = {VarManager::kPin, VarManager::kTPCsignal, VarManager::kTOFbeta}; + hm->AddHistogram(histClass, "nSignalTPCTOF", "", kNvarsPID, varsPIDnSignal.data(), nSignalBinLimits.data()); if (subGroupStr.Contains("more")) { const int kNvarsPIDmore = 4; - TArrayD nSigmaBinLimitsmore[kNvarsPIDmore]; - nSigmaBinLimitsmore[0] = TArrayD(kNbins_pINmore + 1, pIN_binsmore); - nSigmaBinLimitsmore[1] = TArrayD(kNbins_nSigmamore + 1, nSigma_binsmore); - nSigmaBinLimitsmore[2] = TArrayD(kNbins_nSigmagrob + 1, nSigma_binsgrob); - nSigmaBinLimitsmore[3] = TArrayD(kNbins_nSigmamore + 1, nSigma_binsmore); - int varsPIDnSigmamore[kNvarsPIDmore] = {VarManager::kPin, VarManager::kTPCnSigmaEl, VarManager::kTPCnSigmaPi, VarManager::kTOFnSigmaEl}; - hm->AddHistogram(histClass, "nSigmaTPCTOF", "", kNvarsPIDmore, varsPIDnSigmamore, nSigmaBinLimitsmore); + std::array nSigmaBinLimitsmore; + nSigmaBinLimitsmore[0] = TArrayD(kNbins_pINmore + 1, pIN_binsmore.data()); + nSigmaBinLimitsmore[1] = TArrayD(kNbins_nSigmamore + 1, nSigma_binsmore.data()); + nSigmaBinLimitsmore[2] = TArrayD(kNbins_nSigmagrob + 1, nSigma_binsgrob.data()); + nSigmaBinLimitsmore[3] = TArrayD(kNbins_nSigmamore + 1, nSigma_binsmore.data()); + std::array varsPIDnSigmamore = {VarManager::kPin, VarManager::kTPCnSigmaEl, VarManager::kTPCnSigmaPi, VarManager::kTOFnSigmaEl}; + hm->AddHistogram(histClass, "nSigmaTPCTOF", "", kNvarsPIDmore, varsPIDnSigmamore.data(), nSigmaBinLimitsmore.data()); } else { - int varsPIDnSigma[kNvarsPID] = {VarManager::kPin, VarManager::kTPCnSigmaEl, VarManager::kTOFnSigmaEl}; - hm->AddHistogram(histClass, "nSigmaTPCTOF", "", kNvarsPID, varsPIDnSigma, nSigmaBinLimits); + std::array varsPIDnSigma = {VarManager::kPin, VarManager::kTPCnSigmaEl, VarManager::kTOFnSigmaEl}; + hm->AddHistogram(histClass, "nSigmaTPCTOF", "", kNvarsPID, varsPIDnSigma.data(), nSigmaBinLimits.data()); } } if (subGroupStr.Contains("runbyrun")) { @@ -1128,7 +1148,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "tpcNSigmaPi_tofNSigmaPi", "", false, 200, -10., 10., VarManager::kTPCnSigmaPi, 200, -10., 10., VarManager::kTOFnSigmaPi); } if (subGroupStr.Contains("singlemucumulant")) { - double PtBinEdges[67]; // 0-30GeV/c + std::array PtBinEdges; // 0-30GeV/c for (int i = 0; i < 67; i++) { if (i <= 39) { PtBinEdges[i] = i / 10.; @@ -1137,19 +1157,19 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h } } - double CentBinEdges[19]; // 0-90% + std::array CentBinEdges; // 0-90% for (int i = 0; i < 19; i++) { CentBinEdges[i] = i * 5; } - hm->AddHistogram(histClass, "Pt_centrFT0C_Corr2REFsingle", "", true, 66, PtBinEdges, VarManager::kPt, 18, CentBinEdges, VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR2REFbysinglemu, "", "", "", VarManager::kNothing, VarManager::kM11REFoverMpsingle); - hm->AddHistogram(histClass, "Pt_centrFT0C_Corr4REFsingle", "", true, 66, PtBinEdges, VarManager::kPt, 18, CentBinEdges, VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR4REFbysinglemu, "", "", "", VarManager::kNothing, VarManager::kM1111REFoverMpsingle); - hm->AddHistogram(histClass, "Pt_centrFT0C_Corr2POIsingle", "", true, 66, PtBinEdges, VarManager::kPt, 18, CentBinEdges, VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR2POIsingle, "", "", "", VarManager::kNothing, VarManager::kM01POIoverMpsingle); - hm->AddHistogram(histClass, "Pt_centrFT0C_Corr4POIsingle", "", true, 66, PtBinEdges, VarManager::kPt, 18, CentBinEdges, VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR4POIsingle, "", "", "", VarManager::kNothing, VarManager::kM0111POIoverMpsingle); + hm->AddHistogram(histClass, "Pt_centrFT0C_Corr2REFsingle", "", true, 66, PtBinEdges.data(), VarManager::kPt, 18, CentBinEdges.data(), VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR2REFbysinglemu, "", "", "", VarManager::kNothing, VarManager::kM11REFoverMpsingle); + hm->AddHistogram(histClass, "Pt_centrFT0C_Corr4REFsingle", "", true, 66, PtBinEdges.data(), VarManager::kPt, 18, CentBinEdges.data(), VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR4REFbysinglemu, "", "", "", VarManager::kNothing, VarManager::kM1111REFoverMpsingle); + hm->AddHistogram(histClass, "Pt_centrFT0C_Corr2POIsingle", "", true, 66, PtBinEdges.data(), VarManager::kPt, 18, CentBinEdges.data(), VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR2POIsingle, "", "", "", VarManager::kNothing, VarManager::kM01POIoverMpsingle); + hm->AddHistogram(histClass, "Pt_centrFT0C_Corr4POIsingle", "", true, 66, PtBinEdges.data(), VarManager::kPt, 18, CentBinEdges.data(), VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR4POIsingle, "", "", "", VarManager::kNothing, VarManager::kM0111POIoverMpsingle); } } - if (!groupStr.CompareTo("mctruth_triple")) { + if (groupStr.CompareTo("mctruth_triple") == 0) { hm->AddHistogram(histClass, "Eta_Pt", "", false, 100, -2.0, 2.0, VarManager::kPairEta, 200, 0.0, 30.0, VarManager::kPairPt); hm->AddHistogram(histClass, "Eta_Pt_lepton1", "", false, 100, -2.0, 2.0, VarManager::kEta1, 200, 0.0, 30.0, VarManager::kPt1); hm->AddHistogram(histClass, "Eta_Pt_lepton2", "", false, 100, -2.0, 2.0, VarManager::kEta2, 200, 0.0, 30.0, VarManager::kPt2); @@ -1169,7 +1189,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "DeltaMass_Jpsi", "", false, 1500, 3, 4.5, (VarManager::kDeltaMass_jpsi)); hm->AddHistogram(histClass, "Rapidity", "", false, 400, -5.0, 5.0, VarManager::kRap); } - if (!groupStr.CompareTo("mctruth_pair")) { + if (groupStr.CompareTo("mctruth_pair") == 0) { hm->AddHistogram(histClass, "Mass_Pt", "", false, 500, 0.0, 15.0, VarManager::kMCMass, 40, 0.0, 20.0, VarManager::kMCPt); hm->AddHistogram(histClass, "Pt", "", false, 200, 0.0, 20.0, VarManager::kMCPt); hm->AddHistogram(histClass, "Pt_Dilepton", "", false, 200, 0.0, 20.0, VarManager::kPairPtDau); @@ -1179,13 +1199,13 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Phi_Eta", "#phi vs #eta distribution", false, 200, -5.0, 5.0, VarManager::kMCEta, 200, -2. * o2::constants::math::PI, 2. * o2::constants::math::PI, VarManager::kMCPhi); if (subGroupStr.Contains("polarization")) { if (subGroupStr.Contains("pp")) { - int varspTHE[4] = {VarManager::kMCPt, VarManager::kMCCosThetaHE, VarManager::kMCPhiHE, VarManager::kMCPhiTildeHE}; - int varspTCS[4] = {VarManager::kMCPt, VarManager::kMCCosThetaCS, VarManager::kMCPhiCS, VarManager::kMCPhiTildeCS}; - int bins[4] = {20, 20, 20, 20}; - double xmin[4] = {0., -1., 0., 0.}; - double xmax[4] = {20., 1., 2. * o2::constants::math::PI, 2. * o2::constants::math::PI}; - hm->AddHistogram(histClass, "Pt_cosThetaHE_phiHE_phiTildeHE", "", 4, varspTHE, bins, xmin, xmax, 0, -1, kFALSE); - hm->AddHistogram(histClass, "Pt_cosThetaCS_phiCS_phiTildeCS", "", 4, varspTCS, bins, xmin, xmax, 0, -1, kFALSE); + std::array varspTHE = {VarManager::kMCPt, VarManager::kMCCosThetaHE, VarManager::kMCPhiHE, VarManager::kMCPhiTildeHE}; + std::array varspTCS = {VarManager::kMCPt, VarManager::kMCCosThetaCS, VarManager::kMCPhiCS, VarManager::kMCPhiTildeCS}; + std::array bins = {20, 20, 20, 20}; + std::array xmin = {0., -1., 0., 0.}; + std::array xmax = {20., 1., 2. * o2::constants::math::PI, 2. * o2::constants::math::PI}; + hm->AddHistogram(histClass, "Pt_cosThetaHE_phiHE_phiTildeHE", "", 4, varspTHE.data(), bins.data(), xmin.data(), xmax.data(), 0, -1, kFALSE); + hm->AddHistogram(histClass, "Pt_cosThetaCS_phiCS_phiTildeCS", "", 4, varspTCS.data(), bins.data(), xmin.data(), xmax.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("pbpb")) { hm->AddHistogram(histClass, "CosThetaStarRandom", "", false, 100, -1.0, 1.0, VarManager::kCosThetaStarRandom); @@ -1195,7 +1215,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h } } } - if (!groupStr.CompareTo("mctruth_quad")) { + if (groupStr.CompareTo("mctruth_quad") == 0) { hm->AddHistogram(histClass, "hMass_defaultDileptonMass", "", false, 1000, 3.0, 5.0, VarManager::kQuadDefaultDileptonMass); hm->AddHistogram(histClass, "hPt", "", false, 150, 0.0, 15.0, VarManager::kQuadPt); hm->AddHistogram(histClass, "hMass_defaultDileptonMass_Pt", "", false, 100, 3.0, 5.0, VarManager::kQuadDefaultDileptonMass, 150, 0.0, 15.0, VarManager::kQuadPt); @@ -1207,7 +1227,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "hMCPt_MCRap", "", false, 200, 0.0, 20.0, VarManager::kMCPt, 100, -2.0, 2.0, VarManager::kMCY); hm->AddHistogram(histClass, "hMCPhi", "", false, 100, -TMath::Pi(), TMath::Pi(), VarManager::kMCPhi); } - if (!groupStr.CompareTo("mctruth_track")) { + if (groupStr.CompareTo("mctruth_track") == 0) { hm->AddHistogram(histClass, "PtMC", "MC pT", false, 200, 0.0, 20.0, VarManager::kMCPt); hm->AddHistogram(histClass, "EtaMC", "MC #eta", false, 50, -5.0, 5.0, VarManager::kMCEta); hm->AddHistogram(histClass, "PhiMC", "MC #phi", false, 50, -6.3, 6.3, VarManager::kMCPhi); @@ -1221,7 +1241,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Weight", "", false, 50, 0.0, 5.0, VarManager::kMCParticleWeight); hm->AddHistogram(histClass, "MCImpPar_CentFT0CMC", "MC impact param vs MC Cent. FT0C", false, 20, 0.0, 20.0, VarManager::kMCEventImpParam, 100, 0.0, 100.0, VarManager::kMCEventCentrFT0C); } - if (!groupStr.CompareTo("mctruth_mult")) { + if (groupStr.CompareTo("mctruth_mult") == 0) { hm->AddHistogram(histClass, "PtMC_MultEta05", "MC pT vs mult |#eta| < 0.5", false, 200, 0.0, 20.0, VarManager::kMCPt, 150, 0.0, 150.0, VarManager::kMultMCNParticlesEta05); hm->AddHistogram(histClass, "PtMC_MultEta08", "MC pT vs mult |#eta| < 0.8", false, 200, 0.0, 20.0, VarManager::kMCPt, 150, 0.0, 150.0, VarManager::kMultMCNParticlesEta08); hm->AddHistogram(histClass, "PtMC_MultEta10", "MC pT vs mult |#eta| < 1.0", false, 200, 0.0, 20.0, VarManager::kMCPt, 150, 0.0, 150.0, VarManager::kMultMCNParticlesEta10); @@ -1230,26 +1250,26 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "EtaMC_MultEta10", "MC Eta vs mult |#eta| < 1.0", false, 40, -2.0, 2.0, VarManager::kMCEta, 150, 0.0, 150.0, VarManager::kMultMCNParticlesEta10); } - if (!groupStr.CompareTo("energy-correlator-gen")) { - double coschiBins[26]; + if (groupStr.CompareTo("energy-correlator-gen") == 0) { + std::array coschiBins; for (int i = 0; i < 26; i++) { coschiBins[i] = -1.0 + 2.0 * TMath::Power(0.04 * i, 2.0); } - hm->AddHistogram(histClass, "Coschi", "", false, 25, coschiBins, VarManager::kMCCosChi, 0, nullptr, -1, 0, nullptr, -1, "", "", "", -1, VarManager::kMCWeight); + hm->AddHistogram(histClass, "Coschi", "", false, 25, coschiBins.data(), VarManager::kMCCosChi, 0, nullptr, -1, 0, nullptr, -1, "", "", "", -1, VarManager::kMCWeight); } - if (!groupStr.CompareTo("polarization-pseudoproper-gen")) { - int varspTHE[3] = {VarManager::kMCPt, VarManager::kMCCosThetaHE, VarManager::kMCVertexingTauxyProjected}; - int varspTCS[3] = {VarManager::kMCPt, VarManager::kMCCosThetaCS, VarManager::kMCVertexingTauxyProjected}; - int varspTRM[3] = {VarManager::kMCPt, VarManager::kMCCosThetaRM, VarManager::kMCVertexingTauxyProjected}; - int bins[3] = {20, 20, 1000}; - double xmin[3] = {0., -1., -0.5}; - double xmax[3] = {20., 1., 0.5}; - hm->AddHistogram(histClass, "Pt_cosThetaHE_Tauxy", "", 3, varspTHE, bins, xmin, xmax, 0, -1, kFALSE); - hm->AddHistogram(histClass, "Pt_cosThetaCS_Tauxy", "", 3, varspTCS, bins, xmin, xmax, 0, -1, kFALSE); - hm->AddHistogram(histClass, "Pt_cosThetaRM_Tauxy", "", 3, varspTRM, bins, xmin, xmax, 0, -1, kFALSE); + if (groupStr.CompareTo("polarization-pseudoproper-gen") == 0) { + std::array varspTHE = {VarManager::kMCPt, VarManager::kMCCosThetaHE, VarManager::kMCVertexingTauxyProjected}; + std::array varspTCS = {VarManager::kMCPt, VarManager::kMCCosThetaCS, VarManager::kMCVertexingTauxyProjected}; + std::array varspTRM = {VarManager::kMCPt, VarManager::kMCCosThetaRM, VarManager::kMCVertexingTauxyProjected}; + std::array bins = {20, 20, 1000}; + std::array xmin = {0., -1., -0.5}; + std::array xmax = {20., 1., 0.5}; + hm->AddHistogram(histClass, "Pt_cosThetaHE_Tauxy", "", 3, varspTHE.data(), bins.data(), xmin.data(), xmax.data(), 0, -1, kFALSE); + hm->AddHistogram(histClass, "Pt_cosThetaCS_Tauxy", "", 3, varspTCS.data(), bins.data(), xmin.data(), xmax.data(), 0, -1, kFALSE); + hm->AddHistogram(histClass, "Pt_cosThetaRM_Tauxy", "", 3, varspTRM.data(), bins.data(), xmin.data(), xmax.data(), 0, -1, kFALSE); } - if (!groupStr.CompareTo("pair")) { + if (groupStr.CompareTo("pair") == 0) { if (subGroupStr.Contains("cepf")) { hm->AddHistogram(histClass, "Mass", "", false, 300, 0.0, 12.0, VarManager::kMass); hm->AddHistogram(histClass, "Mass_Pt", "", false, 300, 0.0, 12.0, VarManager::kMass, 10, 0.0, 20.0, VarManager::kPt); @@ -1269,45 +1289,45 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Mass_MultFDDC", "Mass vs MultFDDC", false, 200, 2.0, 5.0, VarManager::kMass, 1000, 0, 25000.0, VarManager::kMultFDDC); } if (subGroupStr.Contains("mass_mult_pv")) { - double multAnalysisBins[4] = {0.0, 4.0, 8.0, 1000.0}; + std::array multAnalysisBins = {0.0, 4.0, 8.0, 1000.0}; - double multAnalsisMassBins[201] = {0.0}; + std::array multAnalsisMassBins = {0.0}; for (int i = 0; i <= 200; i++) { multAnalsisMassBins[i] = 2.0 + i * 0.015; } - double multAnalysisPVBins[151] = {0.0}; + std::array multAnalysisPVBins = {0.0}; for (int i = 0; i <= 150; i++) { multAnalysisPVBins[i] = i * 1.0; } - double multAnalysisFV0ABins[1001] = {0.0}; + std::array multAnalysisFV0ABins = {0.0}; for (int i = 0; i <= 1000; i++) { multAnalysisFV0ABins[i] = i * 1.0; } - hm->AddHistogram(histClass, "Mass_VtxNcontribReal_Pt", "Mass vs VtxNcontribReal vs Pt", false, 200, multAnalsisMassBins, VarManager::kMass, 150, multAnalysisPVBins, VarManager::kVtxNcontribReal, 3, multAnalysisBins, VarManager::kPt); - hm->AddHistogram(histClass, "Mass_MultFV0A_Pt", "Mass vs MultFV0A vs Pt", false, 200, multAnalsisMassBins, VarManager::kMass, 1000, multAnalysisFV0ABins, VarManager::kMultFV0A, 3, multAnalysisBins, VarManager::kPt); - hm->AddHistogram(histClass, "Mass_MultFT0A_Pt", "Mass vs MultFT0A vs Pt", false, 200, multAnalsisMassBins, VarManager::kMass, 1000, multAnalysisFV0ABins, VarManager::kMultFT0A, 3, multAnalysisBins, VarManager::kPt); - hm->AddHistogram(histClass, "Mass_MultFT0C_Pt", "Mass vs MultFT0C vs Pt", false, 200, multAnalsisMassBins, VarManager::kMass, 1000, multAnalysisFV0ABins, VarManager::kMultFT0C, 3, multAnalysisBins, VarManager::kPt); + hm->AddHistogram(histClass, "Mass_VtxNcontribReal_Pt", "Mass vs VtxNcontribReal vs Pt", false, 200, multAnalsisMassBins.data(), VarManager::kMass, 150, multAnalysisPVBins.data(), VarManager::kVtxNcontribReal, 3, multAnalysisBins.data(), VarManager::kPt); + hm->AddHistogram(histClass, "Mass_MultFV0A_Pt", "Mass vs MultFV0A vs Pt", false, 200, multAnalsisMassBins.data(), VarManager::kMass, 1000, multAnalysisFV0ABins.data(), VarManager::kMultFV0A, 3, multAnalysisBins.data(), VarManager::kPt); + hm->AddHistogram(histClass, "Mass_MultFT0A_Pt", "Mass vs MultFT0A vs Pt", false, 200, multAnalsisMassBins.data(), VarManager::kMass, 1000, multAnalysisFV0ABins.data(), VarManager::kMultFT0A, 3, multAnalysisBins.data(), VarManager::kPt); + hm->AddHistogram(histClass, "Mass_MultFT0C_Pt", "Mass vs MultFT0C vs Pt", false, 200, multAnalsisMassBins.data(), VarManager::kMass, 1000, multAnalysisFV0ABins.data(), VarManager::kMultFT0C, 3, multAnalysisBins.data(), VarManager::kPt); } if (subGroupStr.Contains("barrel")) { hm->AddHistogram(histClass, "Mass", "", false, 500, 0.0, 5.0, VarManager::kMass); hm->AddHistogram(histClass, "Mass_HighRange", "", false, 375, 0.0, 15.0, VarManager::kMass); hm->AddHistogram(histClass, "Pt", "", false, 2000, 0.0, 20., VarManager::kPt); hm->AddHistogram(histClass, "Mass_Pt", "", false, 500, 0.0, 5.0, VarManager::kMass, 40, 0.0, 20.0, VarManager::kPt); - double massBins[76]; + std::array massBins; for (int i = 0; i < 76; i++) { massBins[i] = 1.5 + i * 0.04; } - double ptBins[70]; + std::array ptBins; for (int i = 0; i <= 50; i++) { ptBins[i] = i * 0.01; } for (int i = 1; i <= 19; i++) { ptBins[50 + i] = 0.5 + i * 0.5; } - hm->AddHistogram(histClass, "Mass_PtFine", "", false, 75, massBins, VarManager::kMass, 69, ptBins, VarManager::kPt); + hm->AddHistogram(histClass, "Mass_PtFine", "", false, 75, massBins.data(), VarManager::kMass, 69, ptBins.data(), VarManager::kPt); hm->AddHistogram(histClass, "Eta_Pt", "", false, 320, -2.0, 2.0, VarManager::kEta, 400, 0.0, 40.0, VarManager::kPt); hm->AddHistogram(histClass, "Y_Pt", "", false, 40, -2.0, 2.0, VarManager::kRap, 40, 0.0, 20.0, VarManager::kPt); hm->AddHistogram(histClass, "Mass_VtxZ", "", true, 30, -15.0, 15.0, VarManager::kVtxZ, 500, 0.0, 5.0, VarManager::kMass); @@ -1326,31 +1346,31 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "VtxZ_VtxNcontribReal", "VtxZ vs VtxNcontribReal", false, 240, -12.0, 12.0, VarManager::kVtxZ, 200, 0, 200.0, VarManager::kVtxNcontribReal); } if (subGroupStr.Contains("alice3barrel")) { - double pTBins[21] = { + std::array pTBins = { 0.1, 0.5, 1.0, 1.25, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.5, 8.0, 10.0, 12.0, 15.0, 20.0, 30.0, 40.0, 60.0, 80.0, 100.0}; - double massBins[501]; + std::array massBins; for (int i = 0; i < 501; i++) { massBins[i] = 0.01 * (i); } - hm->AddHistogram(histClass, "Mass_PtLong", "", false, 500, massBins, VarManager::kMass, 20, pTBins, VarManager::kPt); + hm->AddHistogram(histClass, "Mass_PtLong", "", false, 500, massBins.data(), VarManager::kMass, 20, pTBins.data(), VarManager::kPt); } if (subGroupStr.Contains("dielectron-polarization-he-pbpb")) { - int varsHEpbpb[5] = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaHE, VarManager::kPhiHE}; - int binspT[5] = {100, 30, 10, 10, 10}; - double xminpT[5] = {2., 0., 0, -1., 0.0}; - double xmaxpT[5] = {4.5, 3., 100, 1., 6.28}; - hm->AddHistogram(histClass, "Dielectron_Mass_Pt_Cent_cosThetaHE", "", 5, varsHEpbpb, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varsHEpbpb = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaHE, VarManager::kPhiHE}; + std::array binspT = {100, 30, 10, 10, 10}; + std::array xminpT = {2., 0., 0, -1., 0.0}; + std::array xmaxpT = {4.5, 3., 100, 1., 6.28}; + hm->AddHistogram(histClass, "Dielectron_Mass_Pt_Cent_cosThetaHE", "", 5, varsHEpbpb.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dielectron-polarization-cs-pbpb")) { - int varsCSpbpb[5] = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaCS, VarManager::kPhiCS}; - int binspT[5] = {100, 30, 10, 10, 10}; - double xminpT[5] = {2.0, 0., 0, -1., 0.0}; - double xmaxpT[5] = {4.5, 3., 100, 1., 6.28}; - hm->AddHistogram(histClass, "Dielectron_Mass_Pt_Cent_cosThetaCS", "", 5, varsCSpbpb, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varsCSpbpb = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaCS, VarManager::kPhiCS}; + std::array binspT = {100, 30, 10, 10, 10}; + std::array xminpT = {2.0, 0., 0, -1., 0.0}; + std::array xmaxpT = {4.5, 3., 100, 1., 6.28}; + hm->AddHistogram(histClass, "Dielectron_Mass_Pt_Cent_cosThetaCS", "", 5, varsCSpbpb.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("polarization")) { if (subGroupStr.Contains("helicity")) { @@ -1389,6 +1409,45 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "CosThetaStarMC", "", false, 100, -1.0, 1.0, VarManager::kMCCosThetaStar); } } + if (subGroupStr.Contains("flow-jpsi-ep")) { + std::array bins_A2 = {50, 20, 20, 9, 200}; + std::array minBins_A2 = {2.0, 0.0, -1., 0.0, -20.0}; + std::array maxBins_A2 = {4.0, 2.0, 1.0, 90.0, 20.0}; + std::array bins_DeltaPhi = {50, 20, 20, 9, 10}; + std::array minBins_DeltaPhi = {2.0, 0.0, -1., 0.0, 0}; + std::array maxBins_DeltaPhi = {4.0, 2.0, 1.0, 90.0, 3.14}; + TString labels[5] = {"kMass", "kPt", "kRapidity", "kCentFT0C", "kA2EP"}; + if (subGroupStr.Contains("tpc")) { + std::array varA2_TPC_PP = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kA2EP_PP_TPC}; + std::array varA2_TPC_RP = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kA2EP_RP_TPC}; + std::array varDeltaPhi_TPC_PP = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kDeltaPhiPP_TPC}; + std::array varDeltaPhi_TPC_RP = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kDeltaPhiRP_TPC}; + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_A2PP_TPC", "", 5, varA2_TPC_PP.data(), bins_A2.data(), minBins_A2.data(), maxBins_A2.data(), 0, -1, kTRUE); + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_A2RP_TPC", "", 5, varA2_TPC_RP.data(), bins_A2.data(), minBins_A2.data(), maxBins_A2.data(), 0, -1, kTRUE); + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_DeltaPhiPP_TPC", "", 5, varDeltaPhi_TPC_PP.data(), bins_DeltaPhi.data(), minBins_DeltaPhi.data(), maxBins_DeltaPhi.data(), 0, -1, kTRUE); + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_DeltaPhiRP_TPC", "", 5, varDeltaPhi_TPC_RP.data(), bins_DeltaPhi.data(), minBins_DeltaPhi.data(), maxBins_DeltaPhi.data(), 0, -1, kTRUE); + } + if (subGroupStr.Contains("ft0c")) { + std::array varA2_FT0C_PP = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kA2EP_PP_FT0C}; + std::array varA2_FT0C_RP = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kA2EP_RP_FT0C}; + std::array varDeltaPhi_FT0C_PP = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kDeltaPhiPP_FT0C}; + std::array varDeltaPhi_FT0C_RP = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kDeltaPhiRP_FT0C}; + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_A2PP_FT0C", "", 5, varA2_FT0C_PP.data(), bins_A2.data(), minBins_A2.data(), maxBins_A2.data(), 0, -1, kTRUE); + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_A2RP_FT0C", "", 5, varA2_FT0C_RP.data(), bins_A2.data(), minBins_A2.data(), maxBins_A2.data(), 0, -1, kTRUE); + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_DeltaPhiPP_FT0C", "", 5, varDeltaPhi_FT0C_PP.data(), bins_DeltaPhi.data(), minBins_DeltaPhi.data(), maxBins_DeltaPhi.data(), 0, -1, kTRUE); + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_DeltaPhiRP_FT0C", "", 5, varDeltaPhi_FT0C_RP.data(), bins_DeltaPhi.data(), minBins_DeltaPhi.data(), maxBins_DeltaPhi.data(), 0, -1, kTRUE); + } + if (subGroupStr.Contains("ft0a")) { + std::array varA2_FT0A_PP = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kA2EP_PP_FT0A}; + std::array varA2_FT0A_RP = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kA2EP_RP_FT0A}; + std::array varDeltaPhi_FT0A_PP = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kDeltaPhiPP_FT0A}; + std::array varDeltaPhi_FT0A_RP = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kDeltaPhiRP_FT0A}; + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_A2PP_FT0A", "", 5, varA2_FT0A_PP.data(), bins_A2.data(), minBins_A2.data(), maxBins_A2.data(), 0, -1, kTRUE); + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_A2RP_FT0A", "", 5, varA2_FT0A_RP.data(), bins_A2.data(), minBins_A2.data(), maxBins_A2.data(), 0, -1, kTRUE); + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_DeltaPhiPP_FT0A", "", 5, varDeltaPhi_FT0A_PP.data(), bins_DeltaPhi.data(), minBins_DeltaPhi.data(), maxBins_DeltaPhi.data(), 0, -1, kTRUE); + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_DeltaPhiRP_FT0A", "", 5, varDeltaPhi_FT0A_RP.data(), bins_DeltaPhi.data(), minBins_DeltaPhi.data(), maxBins_DeltaPhi.data(), 0, -1, kTRUE); + } + } if (subGroupStr.Contains("upsilon")) { hm->AddHistogram(histClass, "MassUpsilon_Pt", "", false, 500, 7.0, 12.0, VarManager::kMass, 400, 0.0, 40.0, VarManager::kPt); } @@ -1421,29 +1480,29 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "VtxingChi2PCA", "", false, 100, 0.0, 10.0, VarManager::kVertexingChi2PCA); } if (subGroupStr.Contains("tauxy-midy-pol-he")) { - int varspTHE[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaHE, VarManager::kVertexingTauxyProjectedPoleJPsiMass}; - int binspT[4] = {50, 10, 20, 1000}; - double xminpT[4] = {2., 0., -1., -0.5}; - double xmaxpT[4] = {4., 20., 1., 0.5}; - hm->AddHistogram(histClass, "Tauxy_Mass_Pt_CosthetaHE", "", 4, varspTHE, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varspTHE = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaHE, VarManager::kVertexingTauxyProjectedPoleJPsiMass}; + std::array binspT = {50, 10, 20, 1000}; + std::array xminpT = {2., 0., -1., -0.5}; + std::array xmaxpT = {4., 20., 1., 0.5}; + hm->AddHistogram(histClass, "Tauxy_Mass_Pt_CosthetaHE", "", 4, varspTHE.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("tauxy-midy-pol-rand")) { - int varspTRand[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaRM, VarManager::kVertexingTauxyProjectedPoleJPsiMass}; + std::array varspTRand = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaRM, VarManager::kVertexingTauxyProjectedPoleJPsiMass}; - int binspT[4] = {50, 10, 20, 1000}; - double xminpT[4] = {2., 0., -1., -0.5}; - double xmaxpT[4] = {4., 20., 1., 0.5}; - hm->AddHistogram(histClass, "Tauxy_Mass_Pt_CosthetaRand", "", 4, varspTRand, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array binspT = {50, 10, 20, 1000}; + std::array xminpT = {2., 0., -1., -0.5}; + std::array xmaxpT = {4., 20., 1., 0.5}; + hm->AddHistogram(histClass, "Tauxy_Mass_Pt_CosthetaRand", "", 4, varspTRand.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("tauxy-midy-pol-cs")) { - int varspTCS[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaCS, VarManager::kVertexingTauxyProjectedPoleJPsiMass}; + std::array varspTCS = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaCS, VarManager::kVertexingTauxyProjectedPoleJPsiMass}; - int binspT[4] = {50, 10, 20, 1000}; - double xminpT[4] = {2., 0., -1., -0.5}; - double xmaxpT[4] = {4., 20., 1., 0.5}; - hm->AddHistogram(histClass, "Tauxy_Mass_Pt_CosthetaCS", "", 4, varspTCS, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array binspT = {50, 10, 20, 1000}; + std::array xminpT = {2., 0., -1., -0.5}; + std::array xmaxpT = {4., 20., 1., 0.5}; + hm->AddHistogram(histClass, "Tauxy_Mass_Pt_CosthetaCS", "", 4, varspTCS.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("kalman-filter")) { @@ -1498,24 +1557,25 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h const int kNvarsPair = 4; const int kInvMassNbins = 3; - double InvMassBinLims[kInvMassNbins + 1] = {2.2, 2.6, 3.4, 3.6}; + std::array InvMassBinLims = {2.2, 2.6, 3.4, 3.6}; const int kPtNbins = 10; - double PtBinLims[kPtNbins + 1] = {1., 2., 3., 4., 5., 6., 7., 8., 9., 12., 20.}; + std::array PtBinLims = {1., 2., 3., 4., 5., 6., 7., 8., 9., 12., 20.}; const int kTauNBins = 500; - double TauBinLims[kTauNBins + 1]; - for (int i = 0; i <= kTauNBins; ++i) + std::array TauBinLims; + for (int i = 0; i <= kTauNBins; ++i) { TauBinLims[i] = -0.3 + (0.0015 * i); + } - TArrayD nCutsBinLimits[kNvarsPair]; - nCutsBinLimits[0] = TArrayD(kInvMassNbins + 1, InvMassBinLims); - nCutsBinLimits[1] = TArrayD(kPtNbins + 1, PtBinLims); - nCutsBinLimits[2] = TArrayD(kTauNBins + 1, TauBinLims); - nCutsBinLimits[3] = TArrayD(kTauNBins + 1, TauBinLims); + std::array nCutsBinLimits; + nCutsBinLimits[0] = TArrayD(kInvMassNbins + 1, InvMassBinLims.data()); + nCutsBinLimits[1] = TArrayD(kPtNbins + 1, PtBinLims.data()); + nCutsBinLimits[2] = TArrayD(kTauNBins + 1, TauBinLims.data()); + nCutsBinLimits[3] = TArrayD(kTauNBins + 1, TauBinLims.data()); - int varsPair[kNvarsPair] = {VarManager::kMass, VarManager::kPt, VarManager::kVertexingTauzProjected, VarManager::kVertexingTauxyProjected}; - hm->AddHistogram(histClass, "tau_MultiD", "Invariant mass vs. pT vs. eta vs. rapidity vs. Run2 tau", kNvarsPair, varsPair, nCutsBinLimits); + std::array varsPair = {VarManager::kMass, VarManager::kPt, VarManager::kVertexingTauzProjected, VarManager::kVertexingTauxyProjected}; + hm->AddHistogram(histClass, "tau_MultiD", "Invariant mass vs. pT vs. eta vs. rapidity vs. Run2 tau", kNvarsPair, varsPair.data(), nCutsBinLimits.data()); } if (subGroupStr.Contains("flow")) { @@ -1533,18 +1593,18 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Mass_EtaProbe", "mass vs probe eta", false, 750, 0.0, 15.0, VarManager::kMass, 120, 0.0, 30.0, VarManager::kEta2); // Warning: in the tag-and-probe task t2 is always the probe } if (subGroupStr.Contains("dimuon-multi-diff")) { - int varsKine[3] = {VarManager::kMass, VarManager::kPt, VarManager::kRap}; - int binsKine[3] = {250, 120, 60}; - double xminKine[3] = {0.0, 0.0, 2.5}; - double xmaxKine[3] = {5.0, 30.0, 4.0}; - hm->AddHistogram(histClass, "Mass_Pt_Rapidity", "", 3, varsKine, binsKine, xminKine, xmaxKine, 0, -1, kFALSE); + std::array varsKine = {VarManager::kMass, VarManager::kPt, VarManager::kRap}; + std::array binsKine = {250, 120, 60}; + std::array xminKine = {0.0, 0.0, 2.5}; + std::array xmaxKine = {5.0, 30.0, 4.0}; + hm->AddHistogram(histClass, "Mass_Pt_Rapidity", "", 3, varsKine.data(), binsKine.data(), xminKine.data(), xmaxKine.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-high-mass-multi-diff")) { - int varsKine[3] = {VarManager::kMass, VarManager::kPt, VarManager::kRap}; - int binsKine[3] = {250, 120, 60}; - double xminKine[3] = {7.0, 0.0, 2.5}; - double xmaxKine[3] = {12.0, 30.0, 4.0}; - hm->AddHistogram(histClass, "Mass_Pt_Rapidity", "", 3, varsKine, binsKine, xminKine, xmaxKine, 0, -1, kFALSE); + std::array varsKine = {VarManager::kMass, VarManager::kPt, VarManager::kRap}; + std::array binsKine = {250, 120, 60}; + std::array xminKine = {7.0, 0.0, 2.5}; + std::array xmaxKine = {12.0, 30.0, 4.0}; + hm->AddHistogram(histClass, "Mass_Pt_Rapidity", "", 3, varsKine.data(), binsKine.data(), xminKine.data(), xmaxKine.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-centr")) { hm->AddHistogram(histClass, "Mass_CentFT0C", "", false, 750, 0.0, 15.0, VarManager::kMass, 100, 0., 100., VarManager::kCentFT0C); @@ -1565,12 +1625,12 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "U2Q2_CentFT0C_ev2", "mass vs. centrality vs. U2Q2_event2", false, 125, 0.0, 5.0, VarManager::kMass, 9, 0.0, 90.0, VarManager::kCentFT0C, 100, -10.0, 10.0, VarManager::kU2Q2Ev2); } if (subGroupStr.Contains("metest")) { - double MassBinEdges[251]; // 0-5GeV/c2 + std::array MassBinEdges; // 0-5GeV/c2 for (int i = 0; i < 251; i++) { MassBinEdges[i] = i * 0.02; } - double PtBinEdges[49]; // 0-20GeV/c + std::array PtBinEdges; // 0-20GeV/c for (int i = 0; i < 49; i++) { if (i <= 9) { PtBinEdges[i] = i / 10.; @@ -1579,13 +1639,13 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h } } - double CentBinEdges[19]; // 0-90% + std::array CentBinEdges; // 0-90% for (int i = 0; i < 19; i++) { CentBinEdges[i] = i * 5; } - hm->AddHistogram(histClass, "Mass_Pt_CentFT0C_V2ME_SP", "Mass_Pt_CentFT0C_V2ME_SP", true, 250, MassBinEdges, VarManager::kMass, 48, PtBinEdges, VarManager::kPt, 18, CentBinEdges, VarManager::kCentFT0C, "", "", "", VarManager::kV2ME_SP, VarManager::kWV2ME_SP); - hm->AddHistogram(histClass, "Mass_Pt_CentFT0C_V2ME_EP", "Mass_Pt_CentFT0C_V2ME_EP", true, 250, MassBinEdges, VarManager::kMass, 48, PtBinEdges, VarManager::kPt, 18, CentBinEdges, VarManager::kCentFT0C, "", "", "", VarManager::kV2ME_EP, VarManager::kWV2ME_EP); + hm->AddHistogram(histClass, "Mass_Pt_CentFT0C_V2ME_SP", "Mass_Pt_CentFT0C_V2ME_SP", true, 250, MassBinEdges.data(), VarManager::kMass, 48, PtBinEdges.data(), VarManager::kPt, 18, CentBinEdges.data(), VarManager::kCentFT0C, "", "", "", VarManager::kV2ME_SP, VarManager::kWV2ME_SP); + hm->AddHistogram(histClass, "Mass_Pt_CentFT0C_V2ME_EP", "Mass_Pt_CentFT0C_V2ME_EP", true, 250, MassBinEdges.data(), VarManager::kMass, 48, PtBinEdges.data(), VarManager::kPt, 18, CentBinEdges.data(), VarManager::kCentFT0C, "", "", "", VarManager::kV2ME_EP, VarManager::kWV2ME_EP); } if (subGroupStr.Contains("cumulantme")) { hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_M11REFoverMpME", "", true, 250, 0.0, 5.0, VarManager::kMass, 60, 0.0, 30.0, VarManager::kPt, 9, 0.0, 90.0, VarManager::kCentFT0C, "", "", "", VarManager::kM11REFoverMpME); @@ -1600,12 +1660,12 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Mass_Pt_CentFT0C_V24ME", "Mass_Pt_CentFT0C_V24ME", true, 250, 0.0, 5.0, VarManager::kMass, 60, 0.0, 30.0, VarManager::kPt, 90, 0.0, 90.0, VarManager::kCentFT0C, "", "", "", VarManager::kV24ME, VarManager::kWV24ME); } if (subGroupStr.Contains("cumulantme1")) { - double MassBinEdges[251]; // 0-5GeV/c2 + std::array MassBinEdges; // 0-5GeV/c2 for (int i = 0; i < 251; i++) { MassBinEdges[i] = i * 0.02; } - double PtBinEdges[67]; // 0-30GeV/c + std::array PtBinEdges; // 0-30GeV/c for (int i = 0; i < 67; i++) { if (i <= 39) { PtBinEdges[i] = i / 10.; @@ -1614,12 +1674,12 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h } } - double CentBinEdges[19]; // 0-90% + std::array CentBinEdges; // 0-90% for (int i = 0; i < 19; i++) { CentBinEdges[i] = i * 5; } - hm->AddHistogram(histClass, "Mass_Pt_CentFT0C_V22ME", "Mass_Pt_CentFT0C_V22ME", true, 250, MassBinEdges, VarManager::kMass, 66, PtBinEdges, VarManager::kPt, 18, CentBinEdges, VarManager::kCentFT0C, "", "", "", VarManager::kV22ME, VarManager::kWV22ME); - hm->AddHistogram(histClass, "Mass_Pt_CentFT0C_V24ME", "Mass_Pt_CentFT0C_V24ME", true, 250, MassBinEdges, VarManager::kMass, 66, PtBinEdges, VarManager::kPt, 18, CentBinEdges, VarManager::kCentFT0C, "", "", "", VarManager::kV24ME, VarManager::kWV24ME); + hm->AddHistogram(histClass, "Mass_Pt_CentFT0C_V22ME", "Mass_Pt_CentFT0C_V22ME", true, 250, MassBinEdges.data(), VarManager::kMass, 66, PtBinEdges.data(), VarManager::kPt, 18, CentBinEdges.data(), VarManager::kCentFT0C, "", "", "", VarManager::kV22ME, VarManager::kWV22ME); + hm->AddHistogram(histClass, "Mass_Pt_CentFT0C_V24ME", "Mass_Pt_CentFT0C_V24ME", true, 250, MassBinEdges.data(), VarManager::kMass, 66, PtBinEdges.data(), VarManager::kPt, 18, CentBinEdges.data(), VarManager::kCentFT0C, "", "", "", VarManager::kV24ME, VarManager::kWV24ME); } if (subGroupStr.Contains("cumulantme2")) { hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_M11REFoverMpME", "", true, 250, 0.0, 5.0, VarManager::kMass, 60, 0.0, 30.0, VarManager::kPt, 9, 0.0, 90.0, VarManager::kCentFT0C, "", "", "", VarManager::kM11REFoverMpME); @@ -1632,162 +1692,162 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_Corr4POIME", "", true, 250, 0.0, 5.0, VarManager::kMass, 60, 0.0, 30.0, VarManager::kPt, 9, 0.0, 90.0, VarManager::kCentFT0C, "", "", "", VarManager::kCORR4POIME, VarManager::kM0111POIoverMpME); } if (subGroupStr.Contains("dimuon-polarization-he")) { - int varspTHE[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaHE, VarManager::kPhiHE}; - int binspT[4] = {100, 40, 20, 20}; - double xminpT[4] = {1., 0., -1., -3.14}; - double xmaxpT[4] = {5., 20., 1., +3.14}; - hm->AddHistogram(histClass, "Mass_Pt_cosThetaHE_phiHE", "", 4, varspTHE, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varspTHE = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaHE, VarManager::kPhiHE}; + std::array binspT = {100, 40, 20, 20}; + std::array xminpT = {1., 0., -1., -3.14}; + std::array xmaxpT = {5., 20., 1., +3.14}; + hm->AddHistogram(histClass, "Mass_Pt_cosThetaHE_phiHE", "", 4, varspTHE.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-polarization-cs")) { - int varspTCS[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaCS, VarManager::kPhiCS}; - int binspT[4] = {100, 40, 20, 20}; - double xminpT[4] = {1., 0., -1., -3.14}; - double xmaxpT[4] = {5., 20., 1., +3.14}; - hm->AddHistogram(histClass, "Mass_Pt_cosThetaCS_phiCS", "", 4, varspTCS, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varspTCS = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaCS, VarManager::kPhiCS}; + std::array binspT = {100, 40, 20, 20}; + std::array xminpT = {1., 0., -1., -3.14}; + std::array xmaxpT = {5., 20., 1., +3.14}; + hm->AddHistogram(histClass, "Mass_Pt_cosThetaCS_phiCS", "", 4, varspTCS.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-polarization-pp")) { - int varspTPP[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaPP, VarManager::kPhiPP}; - int binspT[4] = {100, 40, 20, 20}; - double xminpT[4] = {1., 0., -1., -3.14}; - double xmaxpT[4] = {5., 20., 1., +3.14}; - hm->AddHistogram(histClass, "Mass_Pt_cosThetaPP_phiPP", "", 4, varspTPP, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varspTPP = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaPP, VarManager::kPhiPP}; + std::array binspT = {100, 40, 20, 20}; + std::array xminpT = {1., 0., -1., -3.14}; + std::array xmaxpT = {5., 20., 1., +3.14}; + hm->AddHistogram(histClass, "Mass_Pt_cosThetaPP_phiPP", "", 4, varspTPP.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-polarization-lowmass-pp")) { - int varspTPP[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaPP, VarManager::kPhiPP}; - int varsrapPP[4] = {VarManager::kMass, VarManager::kRap, VarManager::kCosThetaPP, VarManager::kPhiPP}; - int binspT[4] = {100, 20, 20, 20}; - int binsy[4] = {100, 10, 20, 20}; - double xminpT[4] = {0.2, 0., -1., -3.14}; - double xmaxpT[4] = {1.5, 20., 1., +3.14}; - double xminy[4] = {0.2, 2.5, -1., -3.14}; - double xmaxy[4] = {1.5, 4.0, 1., +3.14}; - hm->AddHistogram(histClass, "Mass_Pt_cosThetaPP_phiPP", "", 4, varspTPP, binspT, xminpT, xmaxpT, 0, -1, kFALSE); - hm->AddHistogram(histClass, "Mass_y_cosThetaPP_phiPP", "", 4, varsrapPP, binsy, xminy, xmaxy, 0, -1, kFALSE); + std::array varspTPP = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaPP, VarManager::kPhiPP}; + std::array varsrapPP = {VarManager::kMass, VarManager::kRap, VarManager::kCosThetaPP, VarManager::kPhiPP}; + std::array binspT = {100, 20, 20, 20}; + std::array binsy = {100, 10, 20, 20}; + std::array xminpT = {0.2, 0., -1., -3.14}; + std::array xmaxpT = {1.5, 20., 1., +3.14}; + std::array xminy = {0.2, 2.5, -1., -3.14}; + std::array xmaxy = {1.5, 4.0, 1., +3.14}; + hm->AddHistogram(histClass, "Mass_Pt_cosThetaPP_phiPP", "", 4, varspTPP.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); + hm->AddHistogram(histClass, "Mass_y_cosThetaPP_phiPP", "", 4, varsrapPP.data(), binsy.data(), xminy.data(), xmaxy.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("upsilon-polarization-he")) { - int varspTHE[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaHE, VarManager::kPhiHE}; - int binspT[4] = {100, 20, 20, 20}; - double xminpT[4] = {1., 0., -1., 0.}; - double xmaxpT[4] = {15., 20., 1., 2. * o2::constants::math::PI}; - hm->AddHistogram(histClass, "Mass_Pt_cosThetaHE_phiHE", "", 4, varspTHE, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varspTHE = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaHE, VarManager::kPhiHE}; + std::array binspT = {100, 20, 20, 20}; + std::array xminpT = {1., 0., -1., 0.}; + std::array xmaxpT = {15., 20., 1., 2. * o2::constants::math::PI}; + hm->AddHistogram(histClass, "Mass_Pt_cosThetaHE_phiHE", "", 4, varspTHE.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("upsilon-polarization-cs")) { - int varspTCS[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaCS, VarManager::kPhiCS}; - int binspT[4] = {100, 20, 20, 20}; - double xminpT[4] = {1., 0., -1., 0.}; - double xmaxpT[4] = {15., 20., 1., 2. * o2::constants::math::PI}; - hm->AddHistogram(histClass, "Mass_Pt_cosThetaCS_phiCS", "", 4, varspTCS, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varspTCS = {VarManager::kMass, VarManager::kPt, VarManager::kCosThetaCS, VarManager::kPhiCS}; + std::array binspT = {100, 20, 20, 20}; + std::array xminpT = {1., 0., -1., 0.}; + std::array xmaxpT = {15., 20., 1., 2. * o2::constants::math::PI}; + hm->AddHistogram(histClass, "Mass_Pt_cosThetaCS_phiCS", "", 4, varspTCS.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-polarization-vp")) { - int varspTVP[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCosPhiVP, VarManager::kPhiVP}; - int varsrapVP[4] = {VarManager::kMass, VarManager::kRap, VarManager::kCosPhiVP, VarManager::kPhiVP}; - int binspT[4] = {100, 20, 24, 24}; - int binsy[4] = {100, 10, 24, 24}; - double xminpT[4] = {1., 0., -1., 0.}; - double xmaxpT[4] = {5., 20., 1., +3.14}; - double xminy[4] = {1., 2.5, -1., 0.}; - double xmaxy[4] = {5., 4.0, 1., +3.14}; - hm->AddHistogram(histClass, "Mass_Pt_phiVP", "", 4, varspTVP, binspT, xminpT, xmaxpT, 0, -1, kFALSE); - hm->AddHistogram(histClass, "Mass_y_phiVP", "", 4, varsrapVP, binsy, xminy, xmaxy, 0, -1, kFALSE); + std::array varspTVP = {VarManager::kMass, VarManager::kPt, VarManager::kCosPhiVP, VarManager::kPhiVP}; + std::array varsrapVP = {VarManager::kMass, VarManager::kRap, VarManager::kCosPhiVP, VarManager::kPhiVP}; + std::array binspT = {100, 20, 24, 24}; + std::array binsy = {100, 10, 24, 24}; + std::array xminpT = {1., 0., -1., 0.}; + std::array xmaxpT = {5., 20., 1., +3.14}; + std::array xminy = {1., 2.5, -1., 0.}; + std::array xmaxy = {5., 4.0, 1., +3.14}; + hm->AddHistogram(histClass, "Mass_Pt_phiVP", "", 4, varspTVP.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); + hm->AddHistogram(histClass, "Mass_y_phiVP", "", 4, varsrapVP.data(), binsy.data(), xminy.data(), xmaxy.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-rap")) { - int vars[4] = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kRap}; - int binspT[4] = {300, 200, 10, 6}; - double xminpT[4] = {2., 0., 0, 2.5}; - double xmaxpT[4] = {8., 20., 100, 4.0}; - hm->AddHistogram(histClass, "Mass_Pt_Cent_Rap", "", 4, vars, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array vars = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kRap}; + std::array binspT = {300, 200, 10, 6}; + std::array xminpT = {2., 0., 0, 2.5}; + std::array xmaxpT = {8., 20., 100, 4.0}; + hm->AddHistogram(histClass, "Mass_Pt_Cent_Rap", "", 4, vars.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-polarization-he-pbpb")) { - int varsHEpbpb[5] = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaHE, VarManager::kPhiHE}; - int binspT[5] = {150, 30, 10, 10, 10}; - double xminpT[5] = {2., 0., 0, -1., -3.14}; - double xmaxpT[5] = {5., 3., 100, 1., 3.14}; - hm->AddHistogram(histClass, "Mass_Pt_Cent_cosThetaHE", "", 5, varsHEpbpb, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varsHEpbpb = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaHE, VarManager::kPhiHE}; + std::array binspT = {150, 30, 10, 10, 10}; + std::array xminpT = {2., 0., 0, -1., -3.14}; + std::array xmaxpT = {5., 3., 100, 1., 3.14}; + hm->AddHistogram(histClass, "Mass_Pt_Cent_cosThetaHE", "", 5, varsHEpbpb.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-polarization-lowmass-he-pbpb")) { - int varsHEpbpb[5] = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaHE, VarManager::kPhiHE}; - int binspT[5] = {200, 30, 10, 10, 10}; - double xminpT[5] = {0.2, 0., 0, -1., -3.14}; - double xmaxpT[5] = {1.2, 3., 100, 1., 3.14}; - hm->AddHistogram(histClass, "Mass_Pt_Cent_cosThetaHE_lowmass", "", 5, varsHEpbpb, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varsHEpbpb = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaHE, VarManager::kPhiHE}; + std::array binspT = {200, 30, 10, 10, 10}; + std::array xminpT = {0.2, 0., 0, -1., -3.14}; + std::array xmaxpT = {1.2, 3., 100, 1., 3.14}; + hm->AddHistogram(histClass, "Mass_Pt_Cent_cosThetaHE_lowmass", "", 5, varsHEpbpb.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-polarization-cs-pbpb")) { - int varsCSpbpb[5] = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaCS, VarManager::kPhiCS}; - int binspT[5] = {150, 30, 10, 10, 10}; - double xminpT[5] = {2., 0., 0, -1., -3.14}; - double xmaxpT[5] = {5., 3., 100, 1., 3.14}; - hm->AddHistogram(histClass, "Mass_Pt_Cent_cosThetaCS", "", 5, varsCSpbpb, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varsCSpbpb = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaCS, VarManager::kPhiCS}; + std::array binspT = {150, 30, 10, 10, 10}; + std::array xminpT = {2., 0., 0, -1., -3.14}; + std::array xmaxpT = {5., 3., 100, 1., 3.14}; + hm->AddHistogram(histClass, "Mass_Pt_Cent_cosThetaCS", "", 5, varsCSpbpb.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-polarization-lowmass-cs-pbpb")) { - int varsCSpbpb[5] = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaCS, VarManager::kPhiCS}; - int binspT[5] = {200, 30, 10, 10, 10}; - double xminpT[5] = {0.2, 0., 0, -1., -3.14}; - double xmaxpT[5] = {1.2, 3., 100, 1., 3.14}; - hm->AddHistogram(histClass, "Mass_Pt_Cent_cosThetaCS_lowmass", "", 5, varsCSpbpb, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varsCSpbpb = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaCS, VarManager::kPhiCS}; + std::array binspT = {200, 30, 10, 10, 10}; + std::array xminpT = {0.2, 0., 0, -1., -3.14}; + std::array xmaxpT = {1.2, 3., 100, 1., 3.14}; + hm->AddHistogram(histClass, "Mass_Pt_Cent_cosThetaCS_lowmass", "", 5, varsCSpbpb.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-polarization-vp-pbpb")) { - int varsVPpbpb[5] = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosPhiVP, VarManager::kPhiVP}; - int binspT[5] = {150, 30, 10, 24, 24}; - double xminpT[5] = {2., 0., 0, -1., 0.}; - double xmaxpT[5] = {5., 3., 100, 1., 3.14}; - hm->AddHistogram(histClass, "Mass_Pt_Cent_phiVP", "", 5, varsVPpbpb, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varsVPpbpb = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosPhiVP, VarManager::kPhiVP}; + std::array binspT = {150, 30, 10, 24, 24}; + std::array xminpT = {2., 0., 0, -1., 0.}; + std::array xmaxpT = {5., 3., 100, 1., 3.14}; + hm->AddHistogram(histClass, "Mass_Pt_Cent_phiVP", "", 5, varsVPpbpb.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-polarization-lowmass-vp-pbpb")) { - int varsVPpbpb[5] = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosPhiVP, VarManager::kPhiVP}; - int binspT[5] = {200, 30, 10, 24, 24}; - double xminpT[5] = {0.2, 0., 0, -1., 0.}; - double xmaxpT[5] = {1.2, 3., 100, 1., 3.14}; - hm->AddHistogram(histClass, "Mass_Pt_Cent_phiVP_lowmass", "", 5, varsVPpbpb, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varsVPpbpb = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosPhiVP, VarManager::kPhiVP}; + std::array binspT = {200, 30, 10, 24, 24}; + std::array xminpT = {0.2, 0., 0, -1., 0.}; + std::array xmaxpT = {1.2, 3., 100, 1., 3.14}; + hm->AddHistogram(histClass, "Mass_Pt_Cent_phiVP_lowmass", "", 5, varsVPpbpb.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-rap-polarization-he-pbpb")) { - int varsHEpbpb[5] = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaHE, VarManager::kRap}; - int binspT[5] = {150, 30, 10, 10, 6}; - double xminpT[5] = {2., 0., 0, -1., 2.5}; - double xmaxpT[5] = {5., 3., 100, 1., 4.0}; - hm->AddHistogram(histClass, "Mass_Pt_Cent_cosThetaHE_Rap", "", 5, varsHEpbpb, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varsHEpbpb = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaHE, VarManager::kRap}; + std::array binspT = {150, 30, 10, 10, 6}; + std::array xminpT = {2., 0., 0, -1., 2.5}; + std::array xmaxpT = {5., 3., 100, 1., 4.0}; + hm->AddHistogram(histClass, "Mass_Pt_Cent_cosThetaHE_Rap", "", 5, varsHEpbpb.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-rap-polarization-cs-pbpb")) { - int varsCSpbpb[5] = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaCS, VarManager::kRap}; - int binspT[5] = {150, 30, 10, 10, 6}; - double xminpT[5] = {2., 0., 0, -1., 2.5}; - double xmaxpT[5] = {5., 3., 100, 1., 4.0}; - hm->AddHistogram(histClass, "Mass_Pt_Cent_cosThetaCS_Rap", "", 5, varsCSpbpb, binspT, xminpT, xmaxpT, 0, -1, kFALSE); + std::array varsCSpbpb = {VarManager::kMass, VarManager::kPt, VarManager::kCentFT0C, VarManager::kCosThetaCS, VarManager::kRap}; + std::array binspT = {150, 30, 10, 10, 6}; + std::array xminpT = {2., 0., 0, -1., 2.5}; + std::array xmaxpT = {5., 3., 100, 1., 4.0}; + hm->AddHistogram(histClass, "Mass_Pt_Cent_cosThetaCS_Rap", "", 5, varsCSpbpb.data(), binspT.data(), xminpT.data(), xmaxpT.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-midmult-polarization-he")) { - int varsITSTPCMulHE[4] = {VarManager::kMass, VarManager::kMultNTracksITSTPC, VarManager::kCosThetaHE, VarManager::kPhiHE}; - int varsITSMulHE[4] = {VarManager::kMass, VarManager::kMultNTracksHasITS, VarManager::kCosThetaHE, VarManager::kPhiHE}; - int binsMul[4] = {100, 20, 20, 20}; - double xminMul[4] = {1., 0., -1., -3.14}; - double xmaxMul[4] = {5., 120., 1., +3.14}; - hm->AddHistogram(histClass, "Mass_ITSTPCMult_cosThetaHE_phiHE", "", 4, varsITSTPCMulHE, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); - hm->AddHistogram(histClass, "Mass_ITSMult_cosThetaHE_phiHE", "", 4, varsITSMulHE, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); + std::array varsITSTPCMulHE = {VarManager::kMass, VarManager::kMultNTracksITSTPC, VarManager::kCosThetaHE, VarManager::kPhiHE}; + std::array varsITSMulHE = {VarManager::kMass, VarManager::kMultNTracksHasITS, VarManager::kCosThetaHE, VarManager::kPhiHE}; + std::array binsMul = {100, 20, 20, 20}; + std::array xminMul = {1., 0., -1., -3.14}; + std::array xmaxMul = {5., 120., 1., +3.14}; + hm->AddHistogram(histClass, "Mass_ITSTPCMult_cosThetaHE_phiHE", "", 4, varsITSTPCMulHE.data(), binsMul.data(), xminMul.data(), xmaxMul.data(), 0, -1, kFALSE); + hm->AddHistogram(histClass, "Mass_ITSMult_cosThetaHE_phiHE", "", 4, varsITSMulHE.data(), binsMul.data(), xminMul.data(), xmaxMul.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-midmult-polarization-cs")) { - int varsITSTPCMulCS[4] = {VarManager::kMass, VarManager::kMultNTracksITSTPC, VarManager::kCosThetaCS, VarManager::kPhiCS}; - int varsITSMulCS[4] = {VarManager::kMass, VarManager::kMultNTracksHasITS, VarManager::kCosThetaCS, VarManager::kPhiCS}; - int binsMul[4] = {100, 20, 20, 20}; - double xminMul[4] = {1., 0., -1., -3.14}; - double xmaxMul[4] = {5., 120., 1., +3.14}; - hm->AddHistogram(histClass, "Mass_ITSTPCMult_cosThetaCS_phiCS", "", 4, varsITSTPCMulCS, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); - hm->AddHistogram(histClass, "Mass_ITSMult_cosThetaCS_phiCS", "", 4, varsITSMulCS, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); + std::array varsITSTPCMulCS = {VarManager::kMass, VarManager::kMultNTracksITSTPC, VarManager::kCosThetaCS, VarManager::kPhiCS}; + std::array varsITSMulCS = {VarManager::kMass, VarManager::kMultNTracksHasITS, VarManager::kCosThetaCS, VarManager::kPhiCS}; + std::array binsMul = {100, 20, 20, 20}; + std::array xminMul = {1., 0., -1., -3.14}; + std::array xmaxMul = {5., 120., 1., +3.14}; + hm->AddHistogram(histClass, "Mass_ITSTPCMult_cosThetaCS_phiCS", "", 4, varsITSTPCMulCS.data(), binsMul.data(), xminMul.data(), xmaxMul.data(), 0, -1, kFALSE); + hm->AddHistogram(histClass, "Mass_ITSMult_cosThetaCS_phiCS", "", 4, varsITSMulCS.data(), binsMul.data(), xminMul.data(), xmaxMul.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-fwdmult-polarization-he")) { - int varsFT0AMulHE[4] = {VarManager::kMass, VarManager::kMultFT0A, VarManager::kCosThetaHE, VarManager::kPhiHE}; - int varsFV0AMulHE[4] = {VarManager::kMass, VarManager::kMultFV0A, VarManager::kCosThetaHE, VarManager::kPhiHE}; - int binsMul[4] = {100, 20, 20, 20}; - double xminMul[4] = {1., 0., -1., -3.14}; - double xmaxMul[4] = {5., 3000., 1., +3.14}; - hm->AddHistogram(histClass, "Mass_FT0AMult_cosThetaHE_phiHE", "", 4, varsFT0AMulHE, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); - hm->AddHistogram(histClass, "Mass_FV0AMult_cosThetaHE_phiHE", "", 4, varsFV0AMulHE, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); + std::array varsFT0AMulHE = {VarManager::kMass, VarManager::kMultFT0A, VarManager::kCosThetaHE, VarManager::kPhiHE}; + std::array varsFV0AMulHE = {VarManager::kMass, VarManager::kMultFV0A, VarManager::kCosThetaHE, VarManager::kPhiHE}; + std::array binsMul = {100, 20, 20, 20}; + std::array xminMul = {1., 0., -1., -3.14}; + std::array xmaxMul = {5., 3000., 1., +3.14}; + hm->AddHistogram(histClass, "Mass_FT0AMult_cosThetaHE_phiHE", "", 4, varsFT0AMulHE.data(), binsMul.data(), xminMul.data(), xmaxMul.data(), 0, -1, kFALSE); + hm->AddHistogram(histClass, "Mass_FV0AMult_cosThetaHE_phiHE", "", 4, varsFV0AMulHE.data(), binsMul.data(), xminMul.data(), xmaxMul.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("dimuon-fwdmult-polarization-cs")) { - int varsFT0AMulCS[4] = {VarManager::kMass, VarManager::kMultFT0A, VarManager::kCosThetaCS, VarManager::kPhiCS}; - int varsFV0AMulCS[4] = {VarManager::kMass, VarManager::kMultFV0A, VarManager::kCosThetaCS, VarManager::kPhiCS}; - int binsMul[4] = {100, 20, 20, 20}; - double xminMul[4] = {1., 0., -1., -3.14}; - double xmaxMul[4] = {5., 3000., 1., +3.14}; - hm->AddHistogram(histClass, "Mass_FT0AMult_cosThetaCS_phiCS", "", 4, varsFT0AMulCS, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); - hm->AddHistogram(histClass, "Mass_FV0AMult_cosThetaCS_phiCS", "", 4, varsFV0AMulCS, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); + std::array varsFT0AMulCS = {VarManager::kMass, VarManager::kMultFT0A, VarManager::kCosThetaCS, VarManager::kPhiCS}; + std::array varsFV0AMulCS = {VarManager::kMass, VarManager::kMultFV0A, VarManager::kCosThetaCS, VarManager::kPhiCS}; + std::array binsMul = {100, 20, 20, 20}; + std::array xminMul = {1., 0., -1., -3.14}; + std::array xmaxMul = {5., 3000., 1., +3.14}; + hm->AddHistogram(histClass, "Mass_FT0AMult_cosThetaCS_phiCS", "", 4, varsFT0AMulCS.data(), binsMul.data(), xminMul.data(), xmaxMul.data(), 0, -1, kFALSE); + hm->AddHistogram(histClass, "Mass_FV0AMult_cosThetaCS_phiCS", "", 4, varsFV0AMulCS.data(), binsMul.data(), xminMul.data(), xmaxMul.data(), 0, -1, kFALSE); } if (subGroupStr.Contains("vertexing-forward")) { hm->AddHistogram(histClass, "Lxyz", "", false, 100, 0.0, 10.0, VarManager::kVertexingLxyz); @@ -1819,40 +1879,40 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Mass_OpeningAngle", "", false, 250, 0.0, 5.0, VarManager::kMass, 800, 0, 0.8, VarManager::kOpeningAngle); } if (subGroupStr.Contains("flow-pos-neg-dimuon")) { - int varV2POS[6] = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kU2Q2POS, VarManager::kCos2DeltaPhiPOS}; - int varV2NEG[6] = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kU2Q2NEG, VarManager::kCos2DeltaPhiNEG}; + std::array varV2POS = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kU2Q2POS, VarManager::kCos2DeltaPhiPOS}; + std::array varV2NEG = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kU2Q2NEG, VarManager::kCos2DeltaPhiNEG}; - int bins[6] = {250, 60, 6, 18, 200, 40}; - double minBins[6] = {0.0, 0.0, 2.5, 0.0, -10.0, -2.0}; - double maxBins[6] = {5.0, 30.0, 4.0, 90.0, 10.0, 2.0}; - hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_V2POS", "", 6, varV2POS, bins, minBins, maxBins, 0, -1, kTRUE); - hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_V2NEG", "", 6, varV2NEG, bins, minBins, maxBins, 0, -1, kTRUE); + std::array bins = {250, 60, 6, 18, 200, 40}; + std::array minBins = {0.0, 0.0, 2.5, 0.0, -10.0, -2.0}; + std::array maxBins = {5.0, 30.0, 4.0, 90.0, 10.0, 2.0}; + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_V2POS", "", 6, varV2POS.data(), bins.data(), minBins.data(), maxBins.data(), 0, -1, kTRUE); + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_V2NEG", "", 6, varV2NEG.data(), bins.data(), minBins.data(), maxBins.data(), 0, -1, kTRUE); } if (subGroupStr.Contains("flow-dimuon-high-mass")) { - int varV2[6] = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kU2Q2, VarManager::kCos2DeltaPhi}; + std::array varV2 = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kU2Q2, VarManager::kCos2DeltaPhi}; - int bins[6] = {50, 30, 6, 18, 200, 40}; - double minBins[6] = {7.0, 0.0, 2.5, 0.0, -10.0, -2.0}; - double maxBins[6] = {12.0, 30.0, 4.0, 90.0, 10.0, 2.0}; - hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_V2", "", 6, varV2, bins, minBins, maxBins, 0, -1, kTRUE); + std::array bins = {50, 30, 6, 18, 200, 40}; + std::array minBins = {7.0, 0.0, 2.5, 0.0, -10.0, -2.0}; + std::array maxBins = {12.0, 30.0, 4.0, 90.0, 10.0, 2.0}; + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_V2", "", 6, varV2.data(), bins.data(), minBins.data(), maxBins.data(), 0, -1, kTRUE); } if (subGroupStr.Contains("flow-dimuon")) { - int varV2[6] = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kU2Q2, VarManager::kCos2DeltaPhi}; - // int varV3[6] = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kU3Q3, VarManager::kCos3DeltaPhi}; // removed temporarily + std::array varV2 = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kU2Q2, VarManager::kCos2DeltaPhi}; + // std::array varV3 = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kU3Q3, VarManager::kCos3DeltaPhi}; // removed temporarily - int bins[6] = {250, 60, 6, 18, 200, 40}; - double minBins[6] = {0.0, 0.0, 2.5, 0.0, -10.0, -2.0}; - double maxBins[6] = {5.0, 30.0, 4.0, 90.0, 10.0, 2.0}; - hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_V2", "", 6, varV2, bins, minBins, maxBins, 0, -1, kTRUE); - // hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_V3", "", 6, varV3, bins, minBins, maxBins, 0, -1, kTRUE); // removed temporarily + std::array bins = {250, 60, 6, 18, 200, 40}; + std::array minBins = {0.0, 0.0, 2.5, 0.0, -10.0, -2.0}; + std::array maxBins = {5.0, 30.0, 4.0, 90.0, 10.0, 2.0}; + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_V2", "", 6, varV2.data(), bins.data(), minBins.data(), maxBins.data(), 0, -1, kTRUE); + // hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_V3", "", 6, varV3.data(), bins.data(), minBins.data(), maxBins.data(), 0, -1, kTRUE); // removed temporarily } if (subGroupStr.Contains("flow-ccdb")) { - double MassBinEdges[251]; // 0-5GeV/c2 + std::array MassBinEdges; // 0-5GeV/c2 for (int i = 0; i < 251; i++) { MassBinEdges[i] = i * 0.02; } - double PtBinEdges[49]; // 0-20GeV/c + std::array PtBinEdges; // 0-20GeV/c for (int i = 0; i < 49; i++) { if (i <= 9) { PtBinEdges[i] = i / 10.; @@ -1861,19 +1921,19 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h } } - double CentBinEdges[19]; // 0-90% + std::array CentBinEdges; // 0-90% for (int i = 0; i < 19; i++) { CentBinEdges[i] = i * 5; } - hm->AddHistogram(histClass, "Mass_Pt_CentFT0C_V2SPwR", "Mass_Pt_CentFT0C_V2SPwR", true, 250, MassBinEdges, VarManager::kMass, 48, PtBinEdges, VarManager::kPt, 18, CentBinEdges, VarManager::kCentFT0C, "", "", "", VarManager::kV2SP, VarManager::kWV2SP); - hm->AddHistogram(histClass, "Mass_Pt_CentFT0C_V2EPwR", "Mass_Pt_CentFT0C_V2EPwR", true, 250, MassBinEdges, VarManager::kMass, 48, PtBinEdges, VarManager::kPt, 18, CentBinEdges, VarManager::kCentFT0C, "", "", "", VarManager::kV2EP, VarManager::kWV2EP); + hm->AddHistogram(histClass, "Mass_Pt_CentFT0C_V2SPwR", "Mass_Pt_CentFT0C_V2SPwR", true, 250, MassBinEdges.data(), VarManager::kMass, 48, PtBinEdges.data(), VarManager::kPt, 18, CentBinEdges.data(), VarManager::kCentFT0C, "", "", "", VarManager::kV2SP, VarManager::kWV2SP); + hm->AddHistogram(histClass, "Mass_Pt_CentFT0C_V2EPwR", "Mass_Pt_CentFT0C_V2EPwR", true, 250, MassBinEdges.data(), VarManager::kMass, 48, PtBinEdges.data(), VarManager::kPt, 18, CentBinEdges.data(), VarManager::kCentFT0C, "", "", "", VarManager::kV2EP, VarManager::kWV2EP); } if (subGroupStr.Contains("cumulant")) { - int var[4] = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C}; - int bins[4] = {250, 60, 6, 18}; - double minBins[4] = {0.0, 0.0, 2.5, 0.0}; - double maxBins[4] = {5.0, 30.0, 4.0, 90.0}; + std::array var = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C}; + std::array bins = {250, 60, 6, 18}; + std::array minBins = {0.0, 0.0, 2.5, 0.0}; + std::array maxBins = {5.0, 30.0, 4.0, 90.0}; hm->AddHistogram(histClass, "centrFT0C_M11REFoverMp_ev", "", true, 100, 0.0, 100.0, VarManager::kCentFT0C, 1000, 0.0, 1000000.0, VarManager::kM11REFoverMp); hm->AddHistogram(histClass, "centrFT0C_M1111REFoverMp_ev", "", true, 100, 0.0, 100.0, VarManager::kCentFT0C, 1000, 0.0, 100000000000000.0, VarManager::kM1111REFoverMp); hm->AddHistogram(histClass, "centrFT0C_M11M1111REFoverMp_ev", "", true, 100, 0.0, 100.0, VarManager::kCentFT0C, 1000, 0.0, 10000000000000000.0, VarManager::kM11M1111REFoverMp); @@ -1888,7 +1948,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_M01M0111overMp", "", true, 250, 0.0, 5.0, VarManager::kMass, 60, 0.0, 30.0, VarManager::kPt, 18, 0.0, 90.0, VarManager::kCentFT0C, "", "", "", VarManager::kM01M0111overMp); hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_M11M0111overMp", "", true, 250, 0.0, 5.0, VarManager::kMass, 60, 0.0, 30.0, VarManager::kPt, 18, 0.0, 90.0, VarManager::kCentFT0C, "", "", "", VarManager::kM11M0111overMp); hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_M11M01REFoverMp", "", true, 250, 0.0, 5.0, VarManager::kMass, 60, 0.0, 30.0, VarManager::kPt, 18, 0.0, 90.0, VarManager::kCentFT0C, "", "", "", VarManager::kM11M01overMp); - hm->AddHistogram(histClass, "Mass_Pt_Rapidity_CentFT0C", "", 4, var, bins, minBins, maxBins, 0, -1, kTRUE); + hm->AddHistogram(histClass, "Mass_Pt_Rapidity_CentFT0C", "", 4, var.data(), bins.data(), minBins.data(), maxBins.data(), 0, -1, kTRUE); hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_Corr2REF", "", true, 250, 0.0, 5.0, VarManager::kMass, 60, 0.0, 30.0, VarManager::kPt, 18, 0.0, 90.0, VarManager::kCentFT0C, "", "", "", VarManager::kCORR2REFbydimuons, VarManager::kM11REFoverMp); hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_Corr4REF", "", true, 250, 0.0, 5.0, VarManager::kMass, 60, 0.0, 30.0, VarManager::kPt, 18, 0.0, 90.0, VarManager::kCentFT0C, "", "", "", VarManager::kCORR4REFbydimuons, VarManager::kM1111REFoverMp); hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_Corr2POI", "", true, 250, 0.0, 5.0, VarManager::kMass, 60, 0.0, 30.0, VarManager::kPt, 18, 0.0, 90.0, VarManager::kCentFT0C, "", "", "", VarManager::kCORR2POI, VarManager::kM01POIoverMp); @@ -1899,11 +1959,11 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_Corr2REFCorr2POI", "", true, 250, 0.0, 5.0, VarManager::kMass, 60, 0.0, 30.0, VarManager::kPt, 18, 0.0, 90.0, VarManager::kCentFT0C, "", "", "", VarManager::kCORR2REFCORR2POI, VarManager::kM11M01overMp); } if (subGroupStr.Contains("cumulant1")) { - int var[4] = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C}; - int bins[4] = {250, 60, 6, 18}; - double minBins[4] = {0.0, 0.0, 2.5, 0.0}; - double maxBins[4] = {5.0, 30.0, 4.0, 90.0}; - hm->AddHistogram(histClass, "Mass_Pt_Rapidity_CentFT0C", "", 4, var, bins, minBins, maxBins, 0, -1, kTRUE); + std::array var = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C}; + std::array bins = {250, 60, 6, 18}; + std::array minBins = {0.0, 0.0, 2.5, 0.0}; + std::array maxBins = {5.0, 30.0, 4.0, 90.0}; + hm->AddHistogram(histClass, "Mass_Pt_Rapidity_CentFT0C", "", 4, var.data(), bins.data(), minBins.data(), maxBins.data(), 0, -1, kTRUE); hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_Corr2REF", "", true, 250, 0.0, 5.0, VarManager::kMass, 60, 0.0, 30.0, VarManager::kPt, 18, 0.0, 90.0, VarManager::kCentFT0C, "", "", "", VarManager::kCORR2REFbydimuons, VarManager::kM11REFoverMp); hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_Corr4REF", "", true, 250, 0.0, 5.0, VarManager::kMass, 60, 0.0, 30.0, VarManager::kPt, 18, 0.0, 90.0, VarManager::kCentFT0C, "", "", "", VarManager::kCORR4REFbydimuons, VarManager::kM1111REFoverMp); hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_Corr2POI", "", true, 250, 0.0, 5.0, VarManager::kMass, 60, 0.0, 30.0, VarManager::kPt, 18, 0.0, 90.0, VarManager::kCentFT0C, "", "", "", VarManager::kCORR2POI, VarManager::kM01POIoverMp); @@ -1922,11 +1982,11 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "centrFT0C_Corr2Corr4REF_ev", "", true, 100, 0.0, 100.0, VarManager::kCentFT0C, 250, -1.0, 1.0, VarManager::kCORR2CORR4REF, VarManager::kM11M1111REFoverMp); } if (subGroupStr.Contains("singlecumulant")) { - int var[4] = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C}; - int bins[4] = {250, 60, 6, 18}; - double minBins[4] = {0.0, 0.0, 2.5, 0.0}; - double maxBins[4] = {5.0, 30.0, 4.0, 90.0}; - hm->AddHistogram(histClass, "Mass_Pt_Rapidity_CentFT0C", "", 4, var, bins, minBins, maxBins, 0, -1, kTRUE); + std::array var = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C}; + std::array bins = {250, 60, 6, 18}; + std::array minBins = {0.0, 0.0, 2.5, 0.0}; + std::array maxBins = {5.0, 30.0, 4.0, 90.0}; + hm->AddHistogram(histClass, "Mass_Pt_Rapidity_CentFT0C", "", 4, var.data(), bins.data(), minBins.data(), maxBins.data(), 0, -1, kTRUE); hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_Corr2REFminus", "", true, 60, 0.0, 30.0, VarManager::kPt2, 18, 0.0, 90.0, VarManager::kCentFT0C, 0, 0.0, 1.0, VarManager::kCORR2REFbydimuons, "", "", "", VarManager::kNothing, VarManager::kM11REFoverMpminus); hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_Corr4REFminus", "", true, 60, 0.0, 30.0, VarManager::kPt2, 18, 0.0, 90.0, VarManager::kCentFT0C, 0, 0.0, 1.0, VarManager::kCORR4REFbydimuons, "", "", "", VarManager::kNothing, VarManager::kM1111REFoverMpminus); hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_Corr2REFplus", "", true, 60, 0.0, 30.0, VarManager::kPt1, 18, 0.0, 90.0, VarManager::kCentFT0C, 0, 0.0, 1.0, VarManager::kCORR2REFbydimuons, "", "", "", VarManager::kNothing, VarManager::kM11REFoverMpplus); @@ -1937,7 +1997,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_Corr4POIplus", "", true, 60, 0.0, 30.0, VarManager::kPt1, 18, 0.0, 90.0, VarManager::kCentFT0C, 0, 0.0, 1.0, VarManager::kCORR4POIplus, "", "", "", VarManager::kNothing, VarManager::kM0111POIoverMpplus); } if (subGroupStr.Contains("singlecumulant2")) { - double PtBinEdges[67]; // 0-30GeV/c + std::array PtBinEdges; // 0-30GeV/c for (int i = 0; i < 67; i++) { if (i <= 39) { PtBinEdges[i] = i / 10.; @@ -1945,28 +2005,28 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h PtBinEdges[i] = (i - 40) * 1. + 4.; } } - double CentBinEdges[19]; // 0-90% + std::array CentBinEdges; // 0-90% for (int i = 0; i < 19; i++) { CentBinEdges[i] = i * 5; } - hm->AddHistogram(histClass, "Pt_centrFT0C_Corr2REFminus", "", true, 66, PtBinEdges, VarManager::kPt2, 18, CentBinEdges, VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR2REFbydimuons, "", "", "", VarManager::kNothing, VarManager::kM11REFoverMpminus); - hm->AddHistogram(histClass, "Pt_centrFT0C_Corr4REFminus", "", true, 66, PtBinEdges, VarManager::kPt2, 18, CentBinEdges, VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR4REFbydimuons, "", "", "", VarManager::kNothing, VarManager::kM1111REFoverMpminus); - hm->AddHistogram(histClass, "Pt_centrFT0C_Corr2REFplus", "", true, 66, PtBinEdges, VarManager::kPt1, 18, CentBinEdges, VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR2REFbydimuons, "", "", "", VarManager::kNothing, VarManager::kM11REFoverMpplus); - hm->AddHistogram(histClass, "Pt_centrFT0C_Corr4REFplus", "", true, 66, PtBinEdges, VarManager::kPt1, 18, CentBinEdges, VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR4REFbydimuons, "", "", "", VarManager::kNothing, VarManager::kM1111REFoverMpplus); - hm->AddHistogram(histClass, "Pt_centrFT0C_Corr2POIminus", "", true, 66, PtBinEdges, VarManager::kPt2, 18, CentBinEdges, VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR2POIminus, "", "", "", VarManager::kNothing, VarManager::kM01POIoverMpminus); - hm->AddHistogram(histClass, "Pt_centrFT0C_Corr4POIminus", "", true, 66, PtBinEdges, VarManager::kPt2, 18, CentBinEdges, VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR4POIminus, "", "", "", VarManager::kNothing, VarManager::kM0111POIoverMpminus); - hm->AddHistogram(histClass, "Pt_centrFT0C_Corr2POIplus", "", true, 66, PtBinEdges, VarManager::kPt1, 18, CentBinEdges, VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR2POIplus, "", "", "", VarManager::kNothing, VarManager::kM01POIoverMpplus); - hm->AddHistogram(histClass, "Pt_centrFT0C_Corr4POIplus", "", true, 66, PtBinEdges, VarManager::kPt1, 18, CentBinEdges, VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR4POIplus, "", "", "", VarManager::kNothing, VarManager::kM0111POIoverMpplus); + hm->AddHistogram(histClass, "Pt_centrFT0C_Corr2REFminus", "", true, 66, PtBinEdges.data(), VarManager::kPt2, 18, CentBinEdges.data(), VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR2REFbydimuons, "", "", "", VarManager::kNothing, VarManager::kM11REFoverMpminus); + hm->AddHistogram(histClass, "Pt_centrFT0C_Corr4REFminus", "", true, 66, PtBinEdges.data(), VarManager::kPt2, 18, CentBinEdges.data(), VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR4REFbydimuons, "", "", "", VarManager::kNothing, VarManager::kM1111REFoverMpminus); + hm->AddHistogram(histClass, "Pt_centrFT0C_Corr2REFplus", "", true, 66, PtBinEdges.data(), VarManager::kPt1, 18, CentBinEdges.data(), VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR2REFbydimuons, "", "", "", VarManager::kNothing, VarManager::kM11REFoverMpplus); + hm->AddHistogram(histClass, "Pt_centrFT0C_Corr4REFplus", "", true, 66, PtBinEdges.data(), VarManager::kPt1, 18, CentBinEdges.data(), VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR4REFbydimuons, "", "", "", VarManager::kNothing, VarManager::kM1111REFoverMpplus); + hm->AddHistogram(histClass, "Pt_centrFT0C_Corr2POIminus", "", true, 66, PtBinEdges.data(), VarManager::kPt2, 18, CentBinEdges.data(), VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR2POIminus, "", "", "", VarManager::kNothing, VarManager::kM01POIoverMpminus); + hm->AddHistogram(histClass, "Pt_centrFT0C_Corr4POIminus", "", true, 66, PtBinEdges.data(), VarManager::kPt2, 18, CentBinEdges.data(), VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR4POIminus, "", "", "", VarManager::kNothing, VarManager::kM0111POIoverMpminus); + hm->AddHistogram(histClass, "Pt_centrFT0C_Corr2POIplus", "", true, 66, PtBinEdges.data(), VarManager::kPt1, 18, CentBinEdges.data(), VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR2POIplus, "", "", "", VarManager::kNothing, VarManager::kM01POIoverMpplus); + hm->AddHistogram(histClass, "Pt_centrFT0C_Corr4POIplus", "", true, 66, PtBinEdges.data(), VarManager::kPt1, 18, CentBinEdges.data(), VarManager::kCentFT0C, 0, nullptr, VarManager::kCORR4POIplus, "", "", "", VarManager::kNothing, VarManager::kM0111POIoverMpplus); } if (subGroupStr.Contains("res-flow-dimuon")) { - int varV2[6] = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kR2SP_AB, VarManager::kR2EP_AB}; - // int varV3[6] = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kR3SP, VarManager::kR3EP}; // removed temporarily + std::array varV2 = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kR2SP_AB, VarManager::kR2EP_AB}; + // std::array varV3 = {VarManager::kMass, VarManager::kPt, VarManager::kRap, VarManager::kCentFT0C, VarManager::kR3SP, VarManager::kR3EP}; // removed temporarily - int bins[6] = {125, 60, 6, 18, 200, 40}; - double minBins[6] = {0.0, 0.0, 2.5, 0.0, -10.0, -2.0}; - double maxBins[6] = {5.0, 30.0, 4.0, 90.0, 10.0, 2.0}; - hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_R2", "", 6, varV2, bins, minBins, maxBins, 0, -1, kTRUE); - // hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_R3", "", 6, varV3, bins, minBins, maxBins, 0, -1, kTRUE); // removed temporarily + std::array bins = {125, 60, 6, 18, 200, 40}; + std::array minBins = {0.0, 0.0, 2.5, 0.0, -10.0, -2.0}; + std::array maxBins = {5.0, 30.0, 4.0, 90.0, 10.0, 2.0}; + hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_R2", "", 6, varV2.data(), bins.data(), minBins.data(), maxBins.data(), 0, -1, kTRUE); + // hm->AddHistogram(histClass, "Mass_Pt_centrFT0C_R3", "", 6, varV3.data(), bins.data(), minBins.data(), maxBins.data(), 0, -1, kTRUE); // removed temporarily } if (subGroupStr.Contains("z-boson")) { hm->AddHistogram(histClass, "MassZboson", "", false, 240, 20.0, 140.0, VarManager::kMass); @@ -1998,11 +2058,11 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h // which FillPair populates for SE and FillPairME (patched in this PR) populates for ME. Stored as THnSparse so // running with many MC-matched hist classes (track cut x muon cut x signal x QA variant) does not blow the // 1 GB TBufferFile limit during the final ROOT serialization. - int varsEmu4D[4] = {VarManager::kDeltaPhiPair2, VarManager::kDeltaEtaPair2, VarManager::kPt1, VarManager::kPt2}; - int binsEmu4D[4] = {60, 35, 20, 20}; - double xminEmu4D[4] = {-o2::constants::math::PIHalf, 1.5, 0.0, 0.0}; - double xmaxEmu4D[4] = {1.5 * o2::constants::math::PI, 5.0, 20.0, 20.0}; - hm->AddHistogram(histClass, "DeltaPhiPair2_DeltaEtaPair2_PtE_PtMu", "", 4, varsEmu4D, binsEmu4D, xminEmu4D, xmaxEmu4D, nullptr, -1, kTRUE); + std::array varsEmu4D = {VarManager::kDeltaPhiPair2, VarManager::kDeltaEtaPair2, VarManager::kPt1, VarManager::kPt2}; + std::array binsEmu4D = {60, 35, 20, 20}; + std::array xminEmu4D = {-o2::constants::math::PIHalf, 1.5, 0.0, 0.0}; + std::array xmaxEmu4D = {1.5 * o2::constants::math::PI, 5.0, 20.0, 20.0}; + hm->AddHistogram(histClass, "DeltaPhiPair2_DeltaEtaPair2_PtE_PtMu", "", 4, varsEmu4D.data(), binsEmu4D.data(), xminEmu4D.data(), xmaxEmu4D.data(), nullptr, -1, kTRUE); } if (subGroupStr.Contains("dielectrons")) { if (subGroupStr.Contains("prefilter")) { @@ -2019,31 +2079,35 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h // every 10 MeV from 0 to 0.2 GeV/c2 // every 100 MeV from 0.2 to 1. GeV/c2 // every 500 GeV from 1 to 5 GeV/c2 - double mee_bins[37]; - for (int i = 0; i <= 20; i++) + std::array mee_bins; + for (int i = 0; i <= 20; i++) { mee_bins[i] = 0.01 * i; - for (int i = 1; i <= 8; i++) + } + for (int i = 1; i <= 8; i++) { mee_bins[20 + i] = 0.2 + 0.1 * i; - for (int i = 1; i <= 8; i++) + } + for (int i = 1; i <= 8; i++) { mee_bins[28 + i] = 1. + 0.5 * i; - int nbins_mee = sizeof(mee_bins) / sizeof(*mee_bins) - 1; + } + int nbins_mee = static_cast(mee_bins.size()) - 1; // binning for ptee at large scales: // every 0.2 GeV/c from 0 to 10 GeV/c - double ptee_bins[51]; - for (int i = 0; i <= 50; i++) + std::array ptee_bins; + for (int i = 0; i <= 50; i++) { ptee_bins[i] = 0.2 * i; - int nbins_ptee = sizeof(ptee_bins) / sizeof(*ptee_bins) - 1; + } + int nbins_ptee = static_cast(ptee_bins.size()) - 1; // binning for phiv: // steps of size pi/100 - double phiv_bins[101]; + std::array phiv_bins; for (int i = 0; i <= 100; i++) phiv_bins[i] = o2::constants::math::PI / 100. * i; - int nbins_phiv = sizeof(phiv_bins) / sizeof(*phiv_bins) - 1; + int nbins_phiv = static_cast(phiv_bins.size()) - 1; // 3D histo - hm->AddHistogram(histClass, "Mass_Pt_PhiV", "", false, nbins_mee, mee_bins, VarManager::kMass, nbins_ptee, ptee_bins, VarManager::kPt, nbins_phiv, phiv_bins, VarManager::kPairPhiv); + hm->AddHistogram(histClass, "Mass_Pt_PhiV", "", false, nbins_mee, mee_bins.data(), VarManager::kMass, nbins_ptee, ptee_bins.data(), VarManager::kPt, nbins_phiv, phiv_bins.data(), VarManager::kPairPhiv); } if (subGroupStr.Contains("meeptee")) { hm->AddHistogram(histClass, "Mass_Pt", "", false, 500, 0.0, 5.0, VarManager::kMass, 100, 0.0, 10.0, VarManager::kPt); @@ -2063,43 +2127,52 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h // every 50 MeV from 1.1 to 2.7 GeV/c2 // every 10 MeV from 2.7 to 3.2 GeV/c2 // every 50 MeV from 3.2 to 12 GeV/c2 - double mee_bins[369]; - for (int i = 0; i <= 110; i++) + std::array mee_bins; + for (int i = 0; i <= 110; i++) { mee_bins[i] = 0.01 * i; - for (int i = 1; i <= 32; i++) + } + for (int i = 1; i <= 32; i++) { mee_bins[110 + i] = 1.1 + 0.05 * i; - for (int i = 1; i <= 50; i++) + } + for (int i = 1; i <= 50; i++) { mee_bins[142 + i] = 2.7 + 0.01 * i; - for (int i = 1; i <= 176; i++) + } + for (int i = 1; i <= 176; i++) { mee_bins[192 + i] = 3.2 + 0.05 * i; - int nbins_mee = sizeof(mee_bins) / sizeof(*mee_bins) - 1; + } + int nbins_mee = static_cast(mee_bins.size()) - 1; // binning for ptee at large scales: // every 0.1 GeV/c from 0 to 10 GeV/c // every 0.5 GeV/c from 10 to 30 GeV/c - double ptee_bins[201]; - for (int i = 0; i <= 100; i++) + std::array ptee_bins; + for (int i = 0; i <= 100; i++) { ptee_bins[i] = 0.1 * i; - for (int i = 1; i <= 100; i++) + } + for (int i = 1; i <= 100; i++) { ptee_bins[100 + i] = 10 + 0.2 * i; - int nbins_ptee = sizeof(ptee_bins) / sizeof(*ptee_bins) - 1; + } + int nbins_ptee = static_cast(ptee_bins.size()) - 1; // binning for dca at large scales: // every 0.1 sigma from 0 to 5 sigma // every 0.5 sigma from 5 to 10 sigma // every 1.0 sigma from 10 to 40 sigma - double dca_bins[91]; - for (int i = 0; i <= 50; i++) + std::array dca_bins; + for (int i = 0; i <= 50; i++) { dca_bins[i] = 0.1 * i; - for (int i = 1; i <= 10; i++) + } + for (int i = 1; i <= 10; i++) { dca_bins[50 + i] = 5 + 0.5 * i; - for (int i = 1; i <= 30; i++) + } + for (int i = 1; i <= 30; i++) { dca_bins[60 + i] = 10 + 1 * i; - int nbins_dca = sizeof(dca_bins) / sizeof(*dca_bins) - 1; + } + int nbins_dca = static_cast(dca_bins.size()) - 1; - hm->AddHistogram(histClass, "Mass_QuadDCAsigXY", "", false, nbins_mee, mee_bins, VarManager::kMass, nbins_dca, dca_bins, VarManager::kQuadDCAsigXY); - hm->AddHistogram(histClass, "Mass_QuadDCAsigZ", "", false, nbins_mee, mee_bins, VarManager::kMass, nbins_dca, dca_bins, VarManager::kQuadDCAsigZ); - hm->AddHistogram(histClass, "Mass_Pt_QuadDCAsigXYZ", "", false, nbins_mee, mee_bins, VarManager::kMass, nbins_ptee, ptee_bins, VarManager::kPt, nbins_dca, dca_bins, VarManager::kQuadDCAsigXYZ); + hm->AddHistogram(histClass, "Mass_QuadDCAsigXY", "", false, nbins_mee, mee_bins.data(), VarManager::kMass, nbins_dca, dca_bins.data(), VarManager::kQuadDCAsigXY); + hm->AddHistogram(histClass, "Mass_QuadDCAsigZ", "", false, nbins_mee, mee_bins.data(), VarManager::kMass, nbins_dca, dca_bins.data(), VarManager::kQuadDCAsigZ); + hm->AddHistogram(histClass, "Mass_Pt_QuadDCAsigXYZ", "", false, nbins_mee, mee_bins.data(), VarManager::kMass, nbins_ptee, ptee_bins.data(), VarManager::kPt, nbins_dca, dca_bins.data(), VarManager::kQuadDCAsigXYZ); } } if (subGroupStr.Contains("opencharm")) { @@ -2131,7 +2204,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h } } - if (!groupStr.CompareTo("dilepton-track")) { + if (groupStr.CompareTo("dilepton-track") == 0) { if (subGroupStr.Contains("mixedevent")) { // for mixed event hm->AddHistogram(histClass, "Mass_Pt", "", false, 40, 0.0, 20.0, VarManager::kPairMass, 40, 0.0, 20.0, VarManager::kPairPt); hm->AddHistogram(histClass, "Mass", "", false, 750, 0.0, 30.0, VarManager::kPairMass); @@ -2178,26 +2251,27 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h const int kNvarsTripletCuts = 4; const int kInvMassNbins = 100; - double InvMassBinLims[kInvMassNbins + 1]; - for (int i = 0; i <= kInvMassNbins; ++i) + std::array InvMassBinLims; + for (int i = 0; i <= kInvMassNbins; ++i) { InvMassBinLims[i] = 4.0 + 0.02 * i; + } const int kPtNbins = 6; - double PtBinLims[kPtNbins + 1] = {0., 2., 4., 6., 8., 10., 20.}; + std::array PtBinLims = {0., 2., 4., 6., 8., 10., 20.}; const int kCosPointingAngleNbins = 5; - double CosPointingAngleBinLims[kCosPointingAngleNbins + 1] = {0., 0.86, 0.90, 0.94, 0.98, 1.0}; + std::array CosPointingAngleBinLims = {0., 0.86, 0.90, 0.94, 0.98, 1.0}; const int kTauNBins = 6; - double TauBinLims[kTauNBins + 1] = {0., 0.005, 0.01, 0.015, 0.02, 0.025, 0.3}; + std::array TauBinLims = {0., 0.005, 0.01, 0.015, 0.02, 0.025, 0.3}; - TArrayD nCutsBinLimits[kNvarsTripletCuts]; - nCutsBinLimits[0] = TArrayD(kInvMassNbins + 1, InvMassBinLims); - nCutsBinLimits[1] = TArrayD(kPtNbins + 1, PtBinLims); - nCutsBinLimits[2] = TArrayD(kCosPointingAngleNbins + 1, CosPointingAngleBinLims); - nCutsBinLimits[3] = TArrayD(kTauNBins + 1, TauBinLims); + std::array nCutsBinLimits; + nCutsBinLimits[0] = TArrayD(kInvMassNbins + 1, InvMassBinLims.data()); + nCutsBinLimits[1] = TArrayD(kPtNbins + 1, PtBinLims.data()); + nCutsBinLimits[2] = TArrayD(kCosPointingAngleNbins + 1, CosPointingAngleBinLims.data()); + nCutsBinLimits[3] = TArrayD(kTauNBins + 1, TauBinLims.data()); - int varsTripletCuts[kNvarsTripletCuts] = {VarManager::kPairMass, VarManager::kPairPt, VarManager::kCosPointingAngle, VarManager::kVertexingTauxyProjected}; - hm->AddHistogram(histClass, "multidimentional-vertexing", "Invariant mass vs. pT vs. cosine of pointing angle vs. tau", kNvarsTripletCuts, varsTripletCuts, nCutsBinLimits); + std::array varsTripletCuts = {VarManager::kPairMass, VarManager::kPairPt, VarManager::kCosPointingAngle, VarManager::kVertexingTauxyProjected}; + hm->AddHistogram(histClass, "multidimentional-vertexing", "Invariant mass vs. pT vs. cosine of pointing angle vs. tau", kNvarsTripletCuts, varsTripletCuts.data(), nCutsBinLimits.data()); } if (subGroupStr.Contains("correlation")) { hm->AddHistogram(histClass, "DeltaEta_DeltaPhi", "", false, 20, -2.0, 2.0, VarManager::kDeltaEta, 50, -8.0, 8.0, VarManager::kDeltaPhi); @@ -2205,30 +2279,32 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h } if (subGroupStr.Contains("dilepton-hadron-array-correlation")) { const int kInvMassBins = 500; - double InvMassBinLims[kInvMassBins + 1]; - for (int i = 0; i <= kInvMassBins; i++) + std::array InvMassBinLims; + for (int i = 0; i <= kInvMassBins; i++) { InvMassBinLims[i] = 0 + i * 0.01; + } const int kDelEtaBins = 20; - double DelEtaBinLims[kDelEtaBins + 1]; - for (int i = 0; i <= kDelEtaBins; i++) + std::array DelEtaBinLims; + for (int i = 0; i <= kDelEtaBins; i++) { DelEtaBinLims[i] = -2 + i * 0.2; + } const int kDelPhiBins = 26; - double DelPhiBinLims[] = {-1.69647, -1.44513, -1.19381, -0.94248, -0.69115, -0.43982, -0.18850, 0.06283, 0.31416, 0.56549, 0.81681, 1.06814, 1.31947, 1.57080, 1.82212, 2.07345, 2.32478, 2.57611, 2.82743, 3.07876, 3.33009, 3.58142, 3.83274, 4.08407, 4.33540, 4.58673, 4.83806}; + std::array DelPhiBinLims = {-1.69647, -1.44513, -1.19381, -0.94248, -0.69115, -0.43982, -0.18850, 0.06283, 0.31416, 0.56549, 0.81681, 1.06814, 1.31947, 1.57080, 1.82212, 2.07345, 2.32478, 2.57611, 2.82743, 3.07876, 3.33009, 3.58142, 3.83274, 4.08407, 4.33540, 4.58673, 4.83806}; const int kPtBins = 12; - double PtBinLims[kPtBins + 1] = {0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 7.5, 10, 20}; + std::array PtBinLims = {0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 7.5, 10, 20}; - TArrayD nJPsiHadCorr[4]; - nJPsiHadCorr[0] = TArrayD(kInvMassBins + 1, InvMassBinLims); - nJPsiHadCorr[1] = TArrayD(kDelEtaBins + 1, DelEtaBinLims); - nJPsiHadCorr[2] = TArrayD(kDelPhiBins + 1, DelPhiBinLims); - nJPsiHadCorr[3] = TArrayD(kPtBins + 1, PtBinLims); + std::array nJPsiHadCorr; + nJPsiHadCorr[0] = TArrayD(kInvMassBins + 1, InvMassBinLims.data()); + nJPsiHadCorr[1] = TArrayD(kDelEtaBins + 1, DelEtaBinLims.data()); + nJPsiHadCorr[2] = TArrayD(kDelPhiBins + 1, DelPhiBinLims.data()); + nJPsiHadCorr[3] = TArrayD(kPtBins + 1, PtBinLims.data()); - int varsJPsiHadCorr[4] = {VarManager::kPairMassDau, VarManager::kDeltaEta, VarManager::kDeltaPhi, VarManager::kPairPtDau}; - hm->AddHistogram(histClass, "InvMass_DelEta_DelPhi", "", 4, varsJPsiHadCorr, nJPsiHadCorr); // Without efficiency - // hm->AddHistogram(histClass, "InvMass_DelEta_DelPhi", "", 4, varsJPsiHadCorr, nJPsiHadCorr, nullptr, VarManager::kJpsiHadronEff); + std::array varsJPsiHadCorr = {VarManager::kPairMassDau, VarManager::kDeltaEta, VarManager::kDeltaPhi, VarManager::kPairPtDau}; + hm->AddHistogram(histClass, "InvMass_DelEta_DelPhi", "", 4, varsJPsiHadCorr.data(), nJPsiHadCorr.data()); // Without efficiency + // hm->AddHistogram(histClass, "InvMass_DelEta_DelPhi", "", 4, varsJPsiHadCorr.data(), nJPsiHadCorr.data(), nullptr, VarManager::kJpsiHadronEff); } if (subGroupStr.Contains("dilepton-hadron-femto")) { hm->AddHistogram(histClass, "DileptonHadronKstar_DileptonMass", "", false, 150, 0.0, 3.0, VarManager::kDileptonHadronKstar, 100, 1.5, 4.5, VarManager::kPairMassDau); @@ -2237,18 +2313,18 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Delta_Mass_DstarD0region", "", false, 50, 0.14, 0.16, VarManager::kDeltaMass); } if (subGroupStr.Contains("energy-correlator")) { - double coschiBins[26]; + std::array coschiBins; for (int i = 0; i < 26; i++) { coschiBins[i] = -1.0 + 2.0 * TMath::Power(0.04 * i, 2.0); } - hm->AddHistogram(histClass, "Coschi_unfolding", "", false, 25, coschiBins, VarManager::kMCCosChi_rec, 25, coschiBins, VarManager::kMCCosChi_gen); - hm->AddHistogram(histClass, "Coschi", "", false, 25, coschiBins, VarManager::kCosChi, 0, nullptr, -1, 0, nullptr, -1, "", "", "", -1, VarManager::kECWeight); + hm->AddHistogram(histClass, "Coschi_unfolding", "", false, 25, coschiBins.data(), VarManager::kMCCosChi_rec, 25, coschiBins.data(), VarManager::kMCCosChi_gen); + hm->AddHistogram(histClass, "Coschi", "", false, 25, coschiBins.data(), VarManager::kCosChi, 0, nullptr, -1, 0, nullptr, -1, "", "", "", -1, VarManager::kECWeight); hm->AddHistogram(histClass, "DeltaEta_DeltaPhi_weight", "", false, 20, -2.0, 2.0, VarManager::kDeltaEta, 50, -2.0, 6.0, VarManager::kDeltaPhi, 0, 0, 0, -1, "", "", "", -1, VarManager::kPtDau); } } - if (!groupStr.CompareTo("dilepton-charmhadron")) { + if (groupStr.CompareTo("dilepton-charmhadron") == 0) { if (subGroupStr.EqualTo("jpsitomumu")) { hm->AddHistogram(histClass, "hMassVsPtJPsi", "", false, 100, 0.f, 50.f, VarManager::kPt, 300, 2.f, 5.f, VarManager::kMass); hm->AddHistogram(histClass, "hRapVsPtJPsi", "", false, 100, 0.f, 50.f, VarManager::kPt, 50, -4.5f, -2.0f, VarManager::kRap); @@ -2277,7 +2353,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "hPhiVsPtVsBdtDmesonWithJPsi", "", false, 100, 0.f, 1.f, VarManager::kBdtCharmHadron, 100, 0.f, 50.f, VarManager::kPtCharmHadron, 180, 0., 2 * constants::math::PI, VarManager::kPhiCharmHadron); } } - if (!groupStr.CompareTo("dilepton-dihadron")) { + if (groupStr.CompareTo("dilepton-dihadron") == 0) { if (subGroupStr.Contains("xtojpsipipi") || subGroupStr.Contains("psi2stojpsipipi")) { hm->AddHistogram(histClass, "hMass_X3872", "", false, 1000, 3.0, 5.0, VarManager::kQuadMass); hm->AddHistogram(histClass, "hMass_defaultDileptonMass_X3872", "", false, 1000, 3.0, 5.0, VarManager::kQuadDefaultDileptonMass); @@ -2367,7 +2443,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "TauxyMC_Tauxy", "", false, 500, -0.01, 0.01, VarManager::kMCVertexingTauxy, 500, -0.01, 0.01, VarManager::kVertexingTauxy); hm->AddHistogram(histClass, "CosPointingAngleMC", "", false, 100, 0.0, 1.0, VarManager::kMCCosPointingAngle); } - if (!groupStr.CompareTo("dilepton-photon-mass")) { + if (groupStr.CompareTo("dilepton-photon-mass") == 0) { hm->AddHistogram(histClass, "Mass_Dilepton", "", false, 500, 0.0, 5.0, VarManager::kPairMassDau); hm->AddHistogram(histClass, "Mass_Photon", "", false, 500, 0.0, 0.1, VarManager::kMassDau); hm->AddHistogram(histClass, "Mass_Dilepton_Mass_Photon", "", false, 250, 0.0, 5.0, VarManager::kPairMassDau, 250, 0.0, 5.0, VarManager::kMassDau); @@ -2387,7 +2463,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Eta_Pt_lepton2", "", false, 100, -2.0, 2.0, VarManager::kEta2, 200, 0.0, 20.0, VarManager::kPt); } - if (!groupStr.CompareTo("photon")) { + if (groupStr.CompareTo("photon") == 0) { hm->AddHistogram(histClass, "Pt_Photon", "p_{T} distribution", false, 4500, 0.0, 4.5, VarManager::kPt); hm->AddHistogram(histClass, "Eta", "#eta distribution", false, 500, -5.0, 5.0, VarManager::kEta); hm->AddHistogram(histClass, "Eta_Pt", "", false, 100, -2.0, 2.0, VarManager::kEta, 200, 0.0, 20.0, VarManager::kPt); @@ -2398,7 +2474,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h } // specific group/subgroups for trigger - if (!groupStr.CompareTo("software-trigger")) { + if (groupStr.CompareTo("software-trigger") == 0) { if (subGroupStr.Contains("vtxpp")) { hm->AddHistogram(histClass, "VtxZ", "Vtx Z", false, 60, -15.0, 15.0, VarManager::kVtxZ); hm->AddHistogram(histClass, "VtxX", "Vtx X", false, 200, -0.1, 0.1, VarManager::kVtxX); diff --git a/PWGDQ/Core/MCProng.cxx b/PWGDQ/Core/MCProng.cxx index 1e50a10fce2..ee95463839d 100644 --- a/PWGDQ/Core/MCProng.cxx +++ b/PWGDQ/Core/MCProng.cxx @@ -22,8 +22,6 @@ #include #include -ClassImp(MCProng); - std::map MCProng::fgSourceNames = { {"kNothing", MCProng::kNothing}, {"kPhysicalPrimary", MCProng::kPhysicalPrimary}, diff --git a/PWGDQ/Core/MCProng.h b/PWGDQ/Core/MCProng.h index 4677a995bc7..7d795834855 100644 --- a/PWGDQ/Core/MCProng.h +++ b/PWGDQ/Core/MCProng.h @@ -114,7 +114,5 @@ class MCProng bool fCheckGenerationsInTime; std::vector fPDGInHistory; std::vector fExcludePDGInHistory; - - ClassDef(MCProng, 2); }; #endif // PWGDQ_CORE_MCPRONG_H_ diff --git a/PWGDQ/Core/MCSignal.cxx b/PWGDQ/Core/MCSignal.cxx index cb05a02b02c..20e510b0662 100644 --- a/PWGDQ/Core/MCSignal.cxx +++ b/PWGDQ/Core/MCSignal.cxx @@ -24,8 +24,6 @@ using std::cout; using std::endl; -ClassImp(MCSignal); - //________________________________________________________________________________________________ MCSignal::MCSignal() : TNamed("", ""), fProngs({}), diff --git a/PWGDQ/Core/MCSignalLibrary.cxx b/PWGDQ/Core/MCSignalLibrary.cxx index e41ed34ed03..19dcbbc8aa9 100644 --- a/PWGDQ/Core/MCSignalLibrary.cxx +++ b/PWGDQ/Core/MCSignalLibrary.cxx @@ -37,405 +37,405 @@ using namespace o2::constants::physics; MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) { std::string nameStr = name; - MCSignal* signal; + MCSignal* signal = nullptr; // 1-prong signals - if (!nameStr.compare("alicePrimary")) { + if (nameStr == "alicePrimary") { MCProng prong(1); // 1-generation prong prong.SetSourceBit(0, MCProng::kPhysicalPrimary); // set source to be ALICE primary particles signal = new MCSignal(1, name, "ALICE primaries"); // define a signal with one prong signal->AddProng(prong); // add the previously defined prong to the signal return signal; } - if (!nameStr.compare("electron")) { + if (nameStr == "electron") { MCProng prong(1, {11}, {true}, {false}, {0}, {0}, {false}); // define 1-generation prong using the full constructor signal = new MCSignal(name, "Inclusive electrons", {prong}, {-1}); // define the signal using the full constructor return signal; } - if (!nameStr.compare("electronPrimary")) { + if (nameStr == "electronPrimary") { MCProng prong(1, {11}, {true}, {false}, {0}, {0}, {false}); // define 1-generation prong using the full constructor prong.SetSourceBit(0, MCProng::kPhysicalPrimary); // set source to be ALICE primary particles signal = new MCSignal(name, "Primary electrons", {prong}, {-1}); // define the signal using the full constructor return signal; } - if (!nameStr.compare("pionPrimary")) { + if (nameStr == "pionPrimary") { MCProng prong(1, {211}, {true}, {false}, {0}, {0}, {false}); // define 1-generation prong using the full constructor prong.SetSourceBit(0, MCProng::kPhysicalPrimary); // set source to be ALICE primary particles signal = new MCSignal(name, "Primary pions", {prong}, {-1}); // define the signal using the full constructor return signal; } - if (!nameStr.compare("pionPrimaryFromHc")) { + if (nameStr == "pionPrimaryFromHc") { MCProng prong(2, {211, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary, false); signal = new MCSignal(name, "Primary pions from open charmed hadron decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("pionPrimaryFromHb")) { + if (nameStr == "pionPrimaryFromHb") { MCProng prong(2, {211, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary, false); signal = new MCSignal(name, "Primary pions from open beauty hadron decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("photon")) { + if (nameStr == "photon") { MCProng prong(1, {22}, {true}, {false}, {0}, {0}, {false}); // define 1-generation prong using the full constructor signal = new MCSignal(name, "Photon", {prong}, {-1}); // define the signal using the full constructor return signal; } - if (!nameStr.compare("muonPrimary")) { + if (nameStr == "muonPrimary") { MCProng prong(1, {13}, {true}, {false}, {0}, {0}, {false}); // define 1-generation prong using the full constructor prong.SetSourceBit(0, MCProng::kPhysicalPrimary); // set source to be ALICE primary particles signal = new MCSignal(name, "Primary Muons", {prong}, {-1}); // define the signal using the full constructor return signal; } - if (!nameStr.compare("kaonFromPhi")) { + if (nameStr == "kaonFromPhi") { MCProng prong(2, {321, 333}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); // define 2-generation prong using the full constructor signal = new MCSignal(name, "Kaons from phi-mesons", {prong}, {-1}); // define the signal using the full constructor return signal; } - if (!nameStr.compare("kaonPrimary")) { + if (nameStr == "kaonPrimary") { MCProng prong(1, {321}, {true}, {false}, {0}, {0}, {false}); // define 1-generation prong using the full constructor prong.SetSourceBit(0, MCProng::kPhysicalPrimary); // set source to be ALICE primary particles signal = new MCSignal(name, "Primary Kaons", {prong}, {-1}); // define the signal using the full constructor return signal; } - if (!nameStr.compare("Lambda0Baryon")) { + if (nameStr == "Lambda0Baryon") { MCProng prong(1, {3122}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Lambda0 Baryon", {prong}, {-1}); return signal; } - if (!nameStr.compare("SigmaPlusBaryon")) { + if (nameStr == "SigmaPlusBaryon") { MCProng prong(1, {3222}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "SigmaPlus Baryon", {prong}, {-1}); return signal; } - if (!nameStr.compare("proton")) { + if (nameStr == "proton") { MCProng prong(1, {2212}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "proton", {prong}, {-1}); return signal; } - if (!nameStr.compare("protonPrimary")) { + if (nameStr == "protonPrimary") { MCProng prong(1, {2212}, {true}, {false}, {0}, {0}, {false}); // define 1-generation prong using the full constructor prong.SetSourceBit(0, MCProng::kPhysicalPrimary); // set source to be ALICE primary particles signal = new MCSignal(name, "Primary Proton", {prong}, {-1}); // define the signal using the full constructor return signal; } - if (!nameStr.compare("protonFromTransport")) { + if (nameStr == "protonFromTransport") { MCProng prong(1, {2212}, {true}, {false}, {0}, {0}, {false}); prong.SetSourceBit(0, MCProng::kProducedInTransport); signal = new MCSignal(name, "ProtonFromTransport", {prong}, {-1}); return signal; } - if (!nameStr.compare("protonFromLambda0")) { + if (nameStr == "protonFromLambda0") { MCProng prong(2, {2212, 3122}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Proton from Lambda0 decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("protonFromSigmaPlus")) { + if (nameStr == "protonFromSigmaPlus") { MCProng prong(2, {2212, 3222}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Proton from Sigma+ decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("phiMeson")) { + if (nameStr == "phiMeson") { MCProng prong(1, {333}, {true}, {false}, {0}, {0}, {false}); // define 1-generation prong using the full constructor signal = new MCSignal(name, "phi meson", {prong}, {-1}); // define the signal using the full constructor return signal; } - if (!nameStr.compare("muon")) { + if (nameStr == "muon") { MCProng prong(1, {13}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Inclusive muons", {prong}, {-1}); return signal; } - if (!nameStr.compare("electronNOTfromTransport")) { + if (nameStr == "electronNOTfromTransport") { MCProng prong(1); prong.SetPDGcode(0, 11, true); prong.SetSourceBit(0, MCProng::kProducedInTransport, true); // exclude particles produces in transport signal = new MCSignal(name, "Electrons which are not produced during transport in detector", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromNonpromptJpsi")) { + if (nameStr == "eFromNonpromptJpsi") { MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {false}); signal = new MCSignal(name, "Electrons from non-prompt jpsi decays with beauty in decay chain", {prong}, {-1}); return signal; } - if (!nameStr.compare("ePrimaryFromPromptJpsi")) { + if (nameStr == "ePrimaryFromPromptJpsi") { MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from prompt jpsi decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("ePrimaryFromNonpromptJpsi")) { + if (nameStr == "ePrimaryFromNonpromptJpsi") { MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from non-prompt jpsi decays with beauty in decay chain", {prong}, {-1}); return signal; } - if (!nameStr.compare("Jpsi")) { + if (nameStr == "Jpsi") { MCProng prong(1, {443}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Inclusive jpsi", {prong}, {-1}); return signal; } - if (!nameStr.compare("Helium3")) { + if (nameStr == "Helium3") { MCProng prong(1, {1000020030}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Helium3", {prong}, {-1}); return signal; } - if (!nameStr.compare("Helium3Primary")) { + if (nameStr == "Helium3Primary") { MCProng prong(1, {1000020030}, {true}, {false}, {0}, {0}, {false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Helium3Primary", {prong}, {-1}); return signal; } - if (!nameStr.compare("Helium3FromTransport")) { + if (nameStr == "Helium3FromTransport") { MCProng prong(1, {1000020030}, {true}, {false}, {0}, {0}, {false}); prong.SetSourceBit(0, MCProng::kProducedInTransport); signal = new MCSignal(name, "Helium3FromTransport", {prong}, {-1}); return signal; } - if (!nameStr.compare("promptJpsi")) { + if (nameStr == "promptJpsi") { MCProng prong(1, {443}, {true}, {false}, {0}, {0}, {false}, false, {503}, {true}); signal = new MCSignal(name, "Prompt jpsi (not from beauty)", {prong}, {-1}); return signal; } - if (!nameStr.compare("nonPromptJpsi")) { + if (nameStr == "nonPromptJpsi") { MCProng prong(1, {443}, {true}, {false}, {0}, {0}, {false}, false, {503}, {false}); signal = new MCSignal(name, "Non-prompt jpsi (from beauty)", {prong}, {-1}); return signal; } - if (!nameStr.compare("nonPromptJpsiFromBeauty")) { + if (nameStr == "nonPromptJpsiFromBeauty") { MCProng prong(2, {503, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSignalInTime(true); signal = new MCSignal(name, "Non-prompt jpsi directly from beauty", {prong}, {-1}); return signal; } - if (!nameStr.compare("nonPromptJpsiNotDirectlyFromBeauty")) { + if (nameStr == "nonPromptJpsiNotDirectlyFromBeauty") { MCProng prong(2, {443, 503}, {true, true}, {false, true}, {0, 0}, {0, 0}, {false, false}, false, {503}, {false}); signal = new MCSignal(name, "Non-prompt jpsi from other but with beauty in decay chain", {prong}, {-1}); return signal; } - if (!nameStr.compare("AnythingDecayToJpsi")) { + if (nameStr == "AnythingDecayToJpsi") { MCProng prong(2, {MCProng::kPDGCodeNotAssigned, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSignalInTime(true); signal = new MCSignal(name, "Decay of anything into J/psi", {prong}, {-1}); return signal; } - if (!nameStr.compare("eeFromNonpromptPsi2S")) { + if (nameStr == "eeFromNonpromptPsi2S") { MCProng prong(2, {11, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {false}); signal = new MCSignal(name, "ee pairs from non-prompt psi2s decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eeFromPromptPsi2S")) { + if (nameStr == "eeFromPromptPsi2S") { MCProng prong(2, {11, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {true}); signal = new MCSignal(name, "ee pairs from prompt psi2s decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eFromNonpromptPsi2S")) { + if (nameStr == "eFromNonpromptPsi2S") { MCProng prong(2, {11, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {false}); signal = new MCSignal(name, "Electrons from beauty psi2s decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromPromptPsi2S")) { + if (nameStr == "eFromPromptPsi2S") { MCProng prong(2, {11, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {true}); signal = new MCSignal(name, "Electrons from prompt psi2s decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("Psi2S")) { + if (nameStr == "Psi2S") { MCProng prong(1, {100443}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Inclusive psi2s", {prong}, {-1}); return signal; } - if (!nameStr.compare("nonPromptPsi2S")) { + if (nameStr == "nonPromptPsi2S") { MCProng prong(1, {100443}, {true}, {false}, {0}, {0}, {false}, false, {503}, {false}); signal = new MCSignal(name, "Non-prompt psi2s", {prong}, {-1}); return signal; } - if (!nameStr.compare("promptPsi2S")) { + if (nameStr == "promptPsi2S") { MCProng prong(1, {100443}, {true}, {false}, {0}, {0}, {false}, false, {503}, {true}); signal = new MCSignal(name, "Prompt psi2s (not from beauty)", {prong}, {-1}); return signal; } - if (!nameStr.compare("Chic0")) { + if (nameStr == "Chic0") { MCProng prong(1, {10441}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Inclusive Chic0", {prong}, {-1}); return signal; } - if (!nameStr.compare("Chic1")) { + if (nameStr == "Chic1") { MCProng prong(1, {20443}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Inclusive Chic1", {prong}, {-1}); return signal; } - if (!nameStr.compare("Chic2")) { + if (nameStr == "Chic2") { MCProng prong(1, {445}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Inclusive Chic2", {prong}, {-1}); return signal; } - if (!nameStr.compare("Chic012")) { + if (nameStr == "Chic012") { MCProng prong(1, {904}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Inclusive Chic0, Chic1 and Chic2", {prong}, {-1}); return signal; } - if (!nameStr.compare("Upsilon1S")) { + if (nameStr == "Upsilon1S") { MCProng prong(1, {553}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Inclusive Upsilon1S", {prong}, {-1}); return signal; } - if (!nameStr.compare("Upsilon2S")) { + if (nameStr == "Upsilon2S") { MCProng prong(1, {100553}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Inclusive Upsilon2S", {prong}, {-1}); return signal; } - if (!nameStr.compare("Upsilon3S")) { + if (nameStr == "Upsilon3S") { MCProng prong(1, {200553}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Inclusive Upsilon3S", {prong}, {-1}); return signal; } - if (!nameStr.compare("allBeautyHadrons")) { + if (nameStr == "allBeautyHadrons") { MCProng prong(1, {503}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "All beauty hadrons", {prong}, {-1}); return signal; } - if (!nameStr.compare("allBeautyHadronsFS")) { + if (nameStr == "allBeautyHadronsFS") { MCProng prong(1, {503}, {true}, {false}, {0}, {0}, {false}); prong.SetSourceBit(0, MCProng::kHEPMCFinalState); signal = new MCSignal(name, "All beauty hadrons", {prong}, {-1}); return signal; } - if (!nameStr.compare("allOpenBeautyHadrons")) { + if (nameStr == "allOpenBeautyHadrons") { MCProng prong(1, {502}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "All open beauty hadrons", {prong}, {-1}); return signal; } - if (!nameStr.compare("allOpenBeautyHadronsFS")) { + if (nameStr == "allOpenBeautyHadronsFS") { MCProng prong(1, {502}, {true}, {false}, {0}, {0}, {false}); prong.SetSourceBit(0, MCProng::kHEPMCFinalState); signal = new MCSignal(name, "All open beauty hadrons", {prong}, {-1}); return signal; } - if (!nameStr.compare("Bc")) { + if (nameStr == "Bc") { MCProng prong(1, {541}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Bc", {prong}, {-1}); return signal; } - if (!nameStr.compare("mumuFromJpsiFromBc")) { + if (nameStr == "mumuFromJpsiFromBc") { MCProng prong(3, {13, 443, 541}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "Muon pair from jpsi from Bc decays", {prong, prong}, {1, 1}); return signal; } - if (!nameStr.compare("muFromBc")) { + if (nameStr == "muFromBc") { MCProng prong(2, {13, 541}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Muon from Bc decays", {prong}, {1}); return signal; } - if (!nameStr.compare("mumumuFromBc")) { + if (nameStr == "mumumuFromBc") { MCProng prongMuFromJpsi(3, {13, 443, 541}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongMuFromBc(2, {13, 541}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Trimuon from Bc decays", {prongMuFromJpsi, prongMuFromJpsi, prongMuFromBc}, {2, 2, 1}); return signal; } - if (!nameStr.compare("everythingFromBeauty")) { + if (nameStr == "everythingFromBeauty") { MCProng prong(2, {0, 503}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Everything from beauty", {prong}, {-1}); return signal; } - if (!nameStr.compare("everythingFromBeautyFS")) { + if (nameStr == "everythingFromBeautyFS") { MCProng prong(2, {0, 503}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(1, MCProng::kHEPMCFinalState); signal = new MCSignal(name, "Everything from beauty", {prong}, {-1}); return signal; } - if (!nameStr.compare("everythingFromEverythingFromBeauty")) { + if (nameStr == "everythingFromEverythingFromBeauty") { MCProng prong(3, {0, 0, 503}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "Everything from everything from beauty", {prong}, {-1}); return signal; } - if (!nameStr.compare("everythingFromEverythingFromBeautyFS")) { + if (nameStr == "everythingFromEverythingFromBeautyFS") { MCProng prong(3, {0, 0, 503}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); prong.SetSourceBit(2, MCProng::kHEPMCFinalState); signal = new MCSignal(name, "Everything from everything from beauty", {prong}, {-1}); return signal; } - if (!nameStr.compare("allCharmHadrons")) { + if (nameStr == "allCharmHadrons") { MCProng prong(1, {403}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "All charm hadrons", {prong}, {-1}); return signal; } - if (!nameStr.compare("allOpenCharmHadrons")) { + if (nameStr == "allOpenCharmHadrons") { MCProng prong(1, {402}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "All open charm hadrons", {prong}, {-1}); return signal; } - if (!nameStr.compare("allCharmFromBeauty")) { + if (nameStr == "allCharmFromBeauty") { MCProng prong(2, {403, 503}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "All charm hadrons from beauty", {prong}, {-1}); return signal; } - if (!nameStr.compare("allPromptCharm")) { + if (nameStr == "allPromptCharm") { MCProng prong(2, {403, 503}, {true, true}, {false, true}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "All prompt charm hadrons (not from beauty)", {prong}, {-1}); return signal; } - if (!nameStr.compare("Pi0DecayToe")) { + if (nameStr == "Pi0DecayToe") { MCProng prong(2, {111, 11}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Pi0 decays into an electron", {prong}, {-1}); return signal; } - if (!nameStr.compare("Pi0DecayTog")) { + if (nameStr == "Pi0DecayTog") { MCProng prong(2, {111, 22}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Pi0 decays into an gamma", {prong}, {1}); return signal; } - if (!nameStr.compare("Pi0DecayTogg")) { + if (nameStr == "Pi0DecayTogg") { MCProng prong(2, {111, 22}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Pi0 decays into an gamma, gamma", {prong, prong}, {1, 1}); return signal; } - if (!nameStr.compare("PromptPi0DecayToe")) { + if (nameStr == "PromptPi0DecayToe") { MCProng prong(2, {111, 11}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, true, {403, 503}, {true, true}); prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Pi0 decays into an electron", {prong}, {-1}); return signal; } - if (!nameStr.compare("Pi0")) { + if (nameStr == "Pi0") { MCProng prong(1, {111}, {true}, {false}, {0}, {0}, {false}); // prong.SetSourceBit(0, MCProng::kPhysicalPrimary, false); // set source to be ALICE primary particles signal = new MCSignal(name, "Pi0", {prong}, {-1}); return signal; } - if (!nameStr.compare("LMeeLFQ")) { + if (nameStr == "LMeeLFQ") { MCProng prong(1, {900}, {true}, {false}, {0}, {0}, {false}); // prong.SetSourceBit(0, MCProng::kPhysicalPrimary, false); // set source to be ALICE primary particles signal = new MCSignal(name, "light flavor mesons + quarkonia", {prong}, {-1}); // pi0,eta,eta',rho,omega,phi,jpsi,psi2s return signal; } - if (!nameStr.compare("LMeeLF")) { + if (nameStr == "LMeeLF") { MCProng prong(1, {901}, {true}, {false}, {0}, {0}, {false}); // prong.SetSourceBit(0, MCProng::kPhysicalPrimary, false); // set source to be ALICE primary particles signal = new MCSignal(name, "ligh flavor mesons", {prong}, {-1}); // pi0,eta,eta',rho,omega,phi return signal; } - if (!nameStr.compare("PromptJpsiDecayToe")) { + if (nameStr == "PromptJpsiDecayToe") { MCProng prong(2, {443, 11}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, true, {503}, {true}); prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Prompt jpsi (not from beauty) decay to electron", {prong}, {-1}); return signal; } - if (!nameStr.compare("electronFromDs")) { + if (nameStr == "electronFromDs") { MCProng prong(2, {11, 431}, {true, true}, {false, false}, {0, 0}, {0, 0}, {true, true}); signal = new MCSignal(name, "Electrons from Ds decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("dsMeson")) { + if (nameStr == "dsMeson") { MCProng prong(1, {431}, {true}, {false}, {0}, {0}, {true}); signal = new MCSignal(name, "Ds mesons", {prong}, {-1}); return signal; } - if (!nameStr.compare("electronFromPC")) { + if (nameStr == "electronFromPC") { MCProng prong(2, {11, 22}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "electron from a photon conversion", {prong}, {-1}); return signal; } - if (!nameStr.compare("PowhegDYMuon1")) { + if (nameStr == "PowhegDYMuon1") { MCProng prong(1, {13}, {true}, {false}, {0}, {0}, {false}); // selecting muons prong.SetSourceBit(0, MCProng::kIsPowhegDYMuon); // set source to be Muon from POWHEG signal = new MCSignal(name, "POWHEG Muon singles", {prong}, {-1}); // define a signal with 1-prong @@ -443,23 +443,23 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // 2-prong signals - if (!nameStr.compare("dielectron")) { + if (nameStr == "dielectron") { MCProng prong(1, {11}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Electron pair", {prong, prong}, {-1, -1}); return signal; } - if (!nameStr.compare("dimuon")) { + if (nameStr == "dimuon") { MCProng prong(1, {13}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Muon pair", {prong, prong}, {-1, -1}); return signal; } - if (!nameStr.compare("electronMuonPair")) { + if (nameStr == "electronMuonPair") { MCProng electron(1, {11}, {true}, {false}, {0}, {0}, {false}); MCProng muon(1, {13}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Electron-muon pair", {electron, muon}, {-1, -1}); return signal; } - if (!nameStr.compare("emuFromOpenHFhadron")) { + if (nameStr == "emuFromOpenHFhadron") { MCProng electron(2, {11, 902}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); electron.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng muon(2, {13, 902}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); @@ -467,7 +467,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) signal = new MCSignal(name, "e and mu each from an open charm or beauty hadron decay", {electron, muon}, {-1, -1}); return signal; } - if (!nameStr.compare("emuFromOpenCharmHadron")) { + if (nameStr == "emuFromOpenCharmHadron") { MCProng electron(2, {11, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); electron.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng muon(2, {13, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); @@ -475,7 +475,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) signal = new MCSignal(name, "e and mu each from an open charm hadron decay", {electron, muon}, {-1, -1}); return signal; } - if (!nameStr.compare("emuFromOpenBeautyHadron")) { + if (nameStr == "emuFromOpenBeautyHadron") { MCProng electron(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); electron.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng muon(2, {13, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); @@ -483,22 +483,22 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) signal = new MCSignal(name, "e and mu each from an open beauty hadron decay", {electron, muon}, {-1, -1}); return signal; } - if (!nameStr.compare("dielectronFromPC")) { + if (nameStr == "dielectronFromPC") { MCProng prong(2, {11, 22}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "dielectron from a photon conversion", {prong, prong}, {1, 1}); return signal; } - if (!nameStr.compare("dielectronFromAllPC")) { + if (nameStr == "dielectronFromAllPC") { MCProng prong(2, {11, 22}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "dielectron from a photon conversion", {prong, prong}, {-1, -1}); return signal; } - if (!nameStr.compare("dielectronPCPi0")) { + if (nameStr == "dielectronPCPi0") { MCProng prong(3, {11, 22, 111}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "dielectron from a photon conversion from a pi0", {prong, prong}, {1, 1}); return signal; } - if (!nameStr.compare("PowhegDYMuon2")) { + if (nameStr == "PowhegDYMuon2") { MCProng prong(1, {13}, {true}, {false}, {0}, {0}, {false}); // selecting muons prong.SetSourceBit(0, MCProng::kIsPowhegDYMuon); // set source to be Muon from POWHEG signal = new MCSignal(name, "POWHEG Muon pair", {prong, prong}, {-1, -1}); // define a signal with 2-prong @@ -507,376 +507,376 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) // LMEE single signals // electron signals with mother X: e from mother X - if (!nameStr.compare("eFromAnything")) { + if (nameStr == "eFromAnything") { MCProng prong(2, {11, MCProng::kPDGCodeNotAssigned}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electrons from any mother", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromPhoton")) { + if (nameStr == "eFromPhoton") { MCProng prong(2, {11, 22}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electrons from photon conversion", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromPi0")) { + if (nameStr == "eFromPi0") { MCProng prong(2, {11, 111}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electrons from pi0 decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("ePrimaryFromPromptPi0")) { + if (nameStr == "ePrimaryFromPromptPi0") { MCProng prong(2, {11, 111}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502, 402}, {true, true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from prompt pi0 decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromEta")) { + if (nameStr == "eFromEta") { MCProng prong(2, {11, 221}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electrons from eta decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromEtaPrime")) { + if (nameStr == "eFromEtaPrime") { MCProng prong(2, {11, 331}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electrons from eta' decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromRho")) { + if (nameStr == "eFromRho") { MCProng prong(2, {11, 113}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electrons from rho decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromOmega")) { + if (nameStr == "eFromOmega") { MCProng prong(2, {11, 223}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electrons from omega decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromPhi")) { + if (nameStr == "eFromPhi") { MCProng prong(2, {11, 333}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electrons from phi decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromJpsi")) { + if (nameStr == "eFromJpsi") { MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electrons from jpsi decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("anythingFromJpsi")) { + if (nameStr == "anythingFromJpsi") { MCProng prong(2, {MCProng::kPDGCodeNotAssigned, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Anything from jpsi decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromPromptJpsi")) { + if (nameStr == "eFromPromptJpsi") { MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {true}); signal = new MCSignal(name, "Electrons from jpsi decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromPsi2S")) { + if (nameStr == "eFromPsi2S") { MCProng prong(2, {11, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electrons from psi2s decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromLMeeLF")) { + if (nameStr == "eFromLMeeLF") { MCProng prong(2, {11, 901}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electrons from LF meson decays", {prong}, {-1}); // pi0,eta,eta',rho,omega,phi mesons return signal; } - if (!nameStr.compare("ePrimaryFromLMeeLF")) { + if (nameStr == "ePrimaryFromLMeeLF") { MCProng prong(2, {11, 901}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary, false); // set source to be ALICE primary particles signal = new MCSignal(name, "Electrons from LF meson decays", {prong}, {-1}); // pi0,eta,eta',rho,omega,phi mesons return signal; } - if (!nameStr.compare("eFromLMeeLFQ")) { + if (nameStr == "eFromLMeeLFQ") { MCProng prong(2, {11, 900}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSignalInTime(false); // set direction to check generation in time (true) or back in time (false) signal = new MCSignal(name, "Electrons from LF meson + quarkonia decays", {prong}, {-1}); // pi0,eta,eta',rho,omega,phi,jpsi,psi2s mesons return signal; } - if (!nameStr.compare("ePrimaryFromLMeeLFQ")) { + if (nameStr == "ePrimaryFromLMeeLFQ") { MCProng prong(2, {11, 900}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary, false); // set source to be ALICE primary particles prong.SetSignalInTime(false); // set direction to check generation in time (true) or back in time (false) signal = new MCSignal(name, "Electrons from LF meson + quarkonia decays", {prong}, {-1}); // pi0,eta,eta',rho,omega,phi,jpsi,psi2s mesons return signal; } - if (!nameStr.compare("eFromHc")) { + if (nameStr == "eFromHc") { MCProng prong(2, {11, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from open charmed hadron decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromAnyHc")) { + if (nameStr == "eFromAnyHc") { MCProng prong(1, {11}, {true}, {false}, {0}, {0}, {false}, false, {402}, {false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary, false); signal = new MCSignal(name, "Electrons from any open charm hadron decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromD0")) { + if (nameStr == "eFromD0") { MCProng prong(2, {11, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from D0 decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromChargedD")) { + if (nameStr == "eFromChargedD") { MCProng prong(2, {11, Pdg::kDPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from D+/- decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromDs")) { + if (nameStr == "eFromDs") { MCProng prong(2, {11, Pdg::kDS}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from Ds +/- decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromLambdaC")) { + if (nameStr == "eFromLambdaC") { MCProng prong(2, {11, Pdg::kLambdaCPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from Lambda_c decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromXiC0")) { + if (nameStr == "eFromXiC0") { MCProng prong(2, {11, Pdg::kXiC0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from Xi_c_0 decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromXiCPlus")) { + if (nameStr == "eFromXiCPlus") { MCProng prong(2, {11, Pdg::kXiCPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from Xi_c_+ decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromXiCPlusPlus")) { + if (nameStr == "eFromXiCPlusPlus") { MCProng prong(2, {11, Pdg::kXiCCPlusPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from Xi_c_++ decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromHb")) { + if (nameStr == "eFromHb") { MCProng prong(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from open beauty hadron decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromAnyHb")) { + if (nameStr == "eFromAnyHb") { MCProng prong(1, {11}, {true}, {false}, {0}, {0}, {false}, false, {502}, {false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary, false); signal = new MCSignal(name, "Electrons from any open beauty hadron decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromHbc")) { + if (nameStr == "eFromHbc") { MCProng prong(2, {11, 902}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from open charm or beauty hadron decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromMc")) { + if (nameStr == "eFromMc") { MCProng prong(2, {11, 401}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from open charmed meson decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromMb")) { + if (nameStr == "eFromMb") { MCProng prong(2, {11, 501}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from open beauty meson decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromBc")) { + if (nameStr == "eFromBc") { MCProng prong(2, {11, 4001}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from open charmed baryon decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromBb")) { + if (nameStr == "eFromBb") { MCProng prong(2, {11, 5001}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from open beauty baryon decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromPromptHc")) { + if (nameStr == "eFromPromptHc") { MCProng prong(2, {11, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from open charmed hadron decays without beauty in decay history", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromHbtoHc")) { + if (nameStr == "eFromHbtoHc") { MCProng prong(2, {11, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from open charmed hadron decays with b hadron in decay history", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromPromptLM")) { + if (nameStr == "eFromPromptLM") { MCProng prong(2, {11, 101}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502, 402}, {true, true}); signal = new MCSignal(name, "Electrons from light mesons without B/D in decay history", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromHbtoLM")) { + if (nameStr == "eFromHbtoLM") { MCProng prong(2, {11, 101}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {false}); signal = new MCSignal(name, "Electrons from light mesons with B hadron in decay history", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromHctoLM")) { + if (nameStr == "eFromHctoLM") { MCProng prong(2, {11, 101, 402}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false, {502}, {true}); signal = new MCSignal(name, "Electrons from light mesons from D hadron decays and no B in decay history", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromUpsilon1S")) { + if (nameStr == "eFromUpsilon1S") { MCProng prong(2, {11, 553}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electrons from Upsilon1S decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromUpsilon2S")) { + if (nameStr == "eFromUpsilon2S") { MCProng prong(2, {11, 100553}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electrons from Upsilon2S decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromUpsilon3S")) { + if (nameStr == "eFromUpsilon3S") { MCProng prong(2, {11, 200553}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electrons from Upsilon3S decays", {prong}, {-1}); return signal; } // muon signals with mother X: mu from mother X - if (!nameStr.compare("muFromJpsi")) { + if (nameStr == "muFromJpsi") { MCProng prong(2, {13, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "muons from jpsi decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("muFromPsi2S")) { + if (nameStr == "muFromPsi2S") { MCProng prong(2, {13, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "muons from psi2s decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("muFromHb")) { + if (nameStr == "muFromHb") { MCProng prong(2, {13, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "muons from b->mu", {prong}, {-1}); return signal; } - if (!nameStr.compare("muFromPromptHc")) { + if (nameStr == "muFromPromptHc") { MCProng prong(2, {13, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); signal = new MCSignal(name, "muons from c->mu, without beauty in decay history", {prong}, {-1}); return signal; } - if (!nameStr.compare("muFromHbtoHc")) { + if (nameStr == "muFromHbtoHc") { MCProng prong(3, {13, 402, 502}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "muons from b->c->mu", {prong}, {-1}); return signal; } - if (!nameStr.compare("secondaryMuon")) { + if (nameStr == "secondaryMuon") { MCProng prong(1, {13}, {true}, {false}, {0}, {0}, {false}); prong.SetSourceBit(0, MCProng::kProducedInTransport); signal = new MCSignal(name, "muons produced during transport in detector", {prong}, {-1}); return signal; } - if (!nameStr.compare("muFromPromptLM")) { + if (nameStr == "muFromPromptLM") { MCProng prong(2, {13, 101}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502, 402}, {true, true}); signal = new MCSignal(name, "muons from light mesons without B/D in decay history", {prong}, {-1}); return signal; } - if (!nameStr.compare("muFromHbtoLM")) { + if (nameStr == "muFromHbtoLM") { MCProng prong(2, {13, 101}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {false}); signal = new MCSignal(name, "muons from light mesons with B hadron in decay history", {prong}, {-1}); return signal; } - if (!nameStr.compare("muFromHctoLM")) { + if (nameStr == "muFromHctoLM") { MCProng prong(2, {13, 101, 402}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false, {502}, {true}); signal = new MCSignal(name, "muons from light mesons from D hadron decays and no B in decay history", {prong}, {-1}); return signal; } - if (!nameStr.compare("muFromUpsilon1S")) { + if (nameStr == "muFromUpsilon1S") { MCProng prong(2, {13, 553}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "muons from Upsilon1S decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("muFromUpsilon2S")) { + if (nameStr == "muFromUpsilon2S") { MCProng prong(2, {13, 100553}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "muons from Upsilon2S decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("muFromUpsilon3S")) { + if (nameStr == "muFromUpsilon3S") { MCProng prong(2, {13, 200553}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "muons from Upsilon3S decays", {prong}, {-1}); return signal; } // Decay signal: Mother to electron: X -> e - if (!nameStr.compare("AnythingToE")) { + if (nameStr == "AnythingToE") { MCProng prong(2, {MCProng::kPDGCodeNotAssigned, 11}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); // prong.SetSourceBit(0, MCProng::kPhysicalPrimary, false); // set source to be ALICE primary particles prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Decay of anything into e", {prong}, {-1}); // pi0,eta,eta',rho,omega,phi,jpsi,psi2s mesons return signal; } - if (!nameStr.compare("LFQdecayToE")) { + if (nameStr == "LFQdecayToE") { MCProng prong(2, {900, 11}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); // prong.SetSourceBit(0, MCProng::kPhysicalPrimary, false); // set source to be ALICE primary particles prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "LF meson + quarkonia decays into e", {prong}, {-1}); // pi0,eta,eta',rho,omega,phi,jpsi,psi2s mesons return signal; } - if (!nameStr.compare("HcToE")) { + if (nameStr == "HcToE") { MCProng prong(2, {402, 11}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Open charmed hadron decays into e", {prong}, {-1}); return signal; } - if (!nameStr.compare("HbToE")) { + if (nameStr == "HbToE") { MCProng prong(2, {502, 11}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Open beauty hadron decays into e", {prong}, {-1}); return signal; } - if (!nameStr.compare("McToE")) { + if (nameStr == "McToE") { MCProng prong(2, {401, 11}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Open charmed meson decays into e", {prong}, {-1}); return signal; } - if (!nameStr.compare("MbToE")) { + if (nameStr == "MbToE") { MCProng prong(2, {501, 11}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Open beauty meson decays into e", {prong}, {-1}); return signal; } - if (!nameStr.compare("BcToE")) { + if (nameStr == "BcToE") { MCProng prong(2, {4001, 11}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Open charmed baryon decays into e", {prong}, {-1}); return signal; } - if (!nameStr.compare("BbToE")) { + if (nameStr == "BbToE") { MCProng prong(2, {5001, 11}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Open beauty baryon decay into e", {prong}, {-1}); return signal; } - if (!nameStr.compare("PromptHcToE")) { + if (nameStr == "PromptHcToE") { MCProng prong(3, {502, 402, 11}, {true, true, true}, {true, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Open charmed hadron decays into e", {prong}, {-1}); return signal; } - if (!nameStr.compare("NonPromptHcToE")) { + if (nameStr == "NonPromptHcToE") { MCProng prong(3, {502, 402, 11}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "b hadron decays to open charmed hadron decays to e", {prong}, {-1}); return signal; } - if (!nameStr.compare("HFdecayToE")) { + if (nameStr == "HFdecayToE") { MCProng prong(2, {902, 11}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); // prong.SetSourceBit(0, MCProng::kPhysicalPrimary, false); // set source to be ALICE primary particles prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Open charm and beauty to electrons", {prong}, {-1}); return signal; } - if (!nameStr.compare("AnyHFdecayToE")) { + if (nameStr == "AnyHFdecayToE") { MCProng prong(1, {902}, {true}, {false}, {0}, {0}, {false}, true, {11}, {false}); // prong.SetSourceBit(0, MCProng::kPhysicalPrimary, false); // set source to be ALICE primary particles prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) signal = new MCSignal(name, "Open charm and beauty to electrons", {prong}, {-1}); return signal; } - // if (!nameStr.compare("LFQtoPC")) { + // if (nameStr == "LFQtoPC") { // MCProng prong(3, {900, 22, 11}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); // prong.SetSignalInTime(true); // set direction to check for daughters (true, in time) or for mothers (false, back in time) // signal = new MCSignal(name, "LF meson + quarkonia decays into photon conversion electron", {prong}, {-1}); @@ -885,166 +885,166 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) //_________________________________________________________________________________________________________________________ // LMEE pair signals for LF, same mother - if (!nameStr.compare("eeFromAnything")) { + if (nameStr == "eeFromAnything") { MCProng prong(2, {11, MCProng::kPDGCodeNotAssigned}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from any decay", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eeFromPi0")) { + if (nameStr == "eeFromPi0") { MCProng prong(2, {11, 111}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from pi0 decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eePrimaryFromPromptPi0")) { + if (nameStr == "eePrimaryFromPromptPi0") { MCProng prong(2, {11, 111}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502, 402}, {true, true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from prompt pi0 decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eeFromEta")) { + if (nameStr == "eeFromEta") { MCProng prong(2, {11, 221}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from eta decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eeFromEtaprime")) { + if (nameStr == "eeFromEtaprime") { MCProng prong(2, {11, 331}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from eta' decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eeFromRho")) { + if (nameStr == "eeFromRho") { MCProng prong(2, {11, 113}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from rho decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eeFromOmega")) { + if (nameStr == "eeFromOmega") { MCProng prong(2, {11, 223}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from omega decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eeFromPhi")) { + if (nameStr == "eeFromPhi") { MCProng prong(2, {11, 333}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from phi decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eeFromJpsi")) { + if (nameStr == "eeFromJpsi") { MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from j/psi decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eeFromJpsiExclusive")) { + if (nameStr == "eeFromJpsiExclusive") { MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from j/psi decays", {prong, prong}, {1, 1}); // signal at pair level signal->SetDecayChannelIsExclusive(2, true); return signal; } - if (!nameStr.compare("eeFromJpsiNotExclusive")) { + if (nameStr == "eeFromJpsiNotExclusive") { MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from j/psi decays", {prong, prong}, {1, 1}); // signal at pair level signal->SetDecayChannelIsNotExclusive(2, true); return signal; } - if (!nameStr.compare("eePrimaryFromPromptJPsi")) { + if (nameStr == "eePrimaryFromPromptJPsi") { MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from prompt j/psi decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eePrimaryFromNonPromptJPsi")) { + if (nameStr == "eePrimaryFromNonPromptJPsi") { MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from non-prompt j/psi decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("mumuFromPhi")) { + if (nameStr == "mumuFromPhi") { MCProng prong(2, {13, 333}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "mumu pairs from phi decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("mumuFromJpsi")) { + if (nameStr == "mumuFromJpsi") { MCProng prong(2, {13, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "mumu pairs from j/psi decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("mumuFromPromptJpsi")) { + if (nameStr == "mumuFromPromptJpsi") { MCProng prong(2, {13, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "mumu pairs from prompt j/psi decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("mumuFromNonPromptJpsi")) { + if (nameStr == "mumuFromNonPromptJpsi") { MCProng prong(2, {13, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "mumu pairs from non-prompt j/psi decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eeFromPsi2S")) { + if (nameStr == "eeFromPsi2S") { MCProng prong(2, {11, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from psi2s decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("mumuFromPsi2S")) { + if (nameStr == "mumuFromPsi2S") { MCProng prong(2, {13, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "mumu pairs from psi2s decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("mumuFromPromptPsi2S")) { + if (nameStr == "mumuFromPromptPsi2S") { MCProng prong(2, {13, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "mumu pairs from prompt psi2s decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("mumuFromNonPromptPsi2S")) { + if (nameStr == "mumuFromNonPromptPsi2S") { MCProng prong(2, {13, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "mumu pairs from non-prompt psi2s decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("mumuFromUpsilon1S")) { + if (nameStr == "mumuFromUpsilon1S") { MCProng prong(2, {13, 553}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "mumu pairs from upsilon1s decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("mumuFromUpsilon2S")) { + if (nameStr == "mumuFromUpsilon2S") { MCProng prong(2, {13, 100553}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "mumu pairs from upsilon2s decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("mumuFromUpsilon3S")) { + if (nameStr == "mumuFromUpsilon3S") { MCProng prong(2, {13, 200553}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "mumu pairs from upsilon3s decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eeFromLMeeLFQ")) { + if (nameStr == "eeFromLMeeLFQ") { MCProng prong(2, {11, 900}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from light flavor meson + quarkonia decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eeFromLMeeLF")) { + if (nameStr == "eeFromLMeeLF") { MCProng prong(2, {11, 901}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from light flavor meson decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eeFromLMeeNoHFLFQ")) { + if (nameStr == "eeFromLMeeNoHFLFQ") { MCProng prong(2, {11, 900}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502, 402}, {true, true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from light flavor meson + quarkonia decays not from open-HF decays", {prong, prong}, {1, 1}); // signal at pair level return signal; } - if (!nameStr.compare("eeFromLMeeNoHFLF")) { + if (nameStr == "eeFromLMeeNoHFLF") { MCProng prong(2, {11, 901}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502, 402}, {true, true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from light flavor meson decays not from open-HF decays", {prong, prong}, {1, 1}); // signal at pair level @@ -1053,7 +1053,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) // LMEE pair signals for HF // D0->e and D0->e - if (!nameStr.compare("eeFromD0")) { + if (nameStr == "eeFromD0") { MCProng prong(2, {kElectron, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from D0 decays, no beauty in history", {prong, prong}, {-1, -1}); @@ -1061,7 +1061,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // D0->e and D0->e - if (!nameStr.compare("eeFromPi0FromD0")) { + if (nameStr == "eeFromPi0FromD0") { MCProng prong(2, {kElectron, kPi0, Pdg::kD0}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from D0 to Pi0 decays, no beauty in history", {prong, prong}, {1, 1}); @@ -1069,7 +1069,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // D+/- -> e and D+/- -> e - if (!nameStr.compare("eeFromChargedD")) { + if (nameStr == "eeFromChargedD") { MCProng prong(2, {kElectron, Pdg::kDPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from D+/- decays, no beauty in history", {prong, prong}, {-1, -1}); @@ -1077,7 +1077,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // D0 -> e and D+/- -> e - if (!nameStr.compare("eeFromD0andChargedD")) { + if (nameStr == "eeFromD0andChargedD") { MCProng prongD0(2, {kElectron, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); MCProng prongDch(2, {kElectron, Pdg::kDPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prongD0.SetSourceBit(0, MCProng::kPhysicalPrimary); @@ -1087,7 +1087,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // D+/- -> e and D0 -> e - if (!nameStr.compare("eeFromD0andChargedDBis")) { + if (nameStr == "eeFromD0andChargedDBis") { MCProng prongD0(2, {kElectron, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); MCProng prongDch(2, {kElectron, Pdg::kDPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prongD0.SetSourceBit(0, MCProng::kPhysicalPrimary); @@ -1097,7 +1097,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // D_s->e and D_s->e - if (!nameStr.compare("eeFromDs")) { + if (nameStr == "eeFromDs") { MCProng prong(2, {kElectron, Pdg::kDS}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from Ds +/- decays, no beauty in history", {prong, prong}, {-1, -1}); @@ -1105,7 +1105,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // Lambda_c->e and Lambda_c->e - if (!nameStr.compare("eeFromLambdaC")) { + if (nameStr == "eeFromLambdaC") { MCProng prong(2, {kElectron, Pdg::kLambdaCPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from Lambda_c, no beauty in history", {prong, prong}, {-1, -1}); @@ -1113,7 +1113,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // Lambda_c->e and D0->e - if (!nameStr.compare("eeFromLambdaCandD0")) { + if (nameStr == "eeFromLambdaCandD0") { MCProng prongLc(2, {kElectron, Pdg::kLambdaCPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); MCProng prongD0(2, {kElectron, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prongLc.SetSourceBit(0, MCProng::kPhysicalPrimary); @@ -1123,7 +1123,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // D0->e and Lambda_c->e - if (!nameStr.compare("eeFromLambdaCandD0Bis")) { + if (nameStr == "eeFromLambdaCandD0Bis") { MCProng prongLc(2, {kElectron, Pdg::kLambdaCPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); MCProng prongD0(2, {kElectron, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prongLc.SetSourceBit(0, MCProng::kPhysicalPrimary); @@ -1133,7 +1133,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // Lambda_c->e and D+/- -> e - if (!nameStr.compare("eeFromLambdaCandChargedD")) { + if (nameStr == "eeFromLambdaCandChargedD") { MCProng prongLc(2, {kElectron, Pdg::kLambdaCPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); MCProng prongDch(2, {kElectron, Pdg::kDPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prongLc.SetSourceBit(0, MCProng::kPhysicalPrimary); @@ -1143,7 +1143,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // D+/- -> e and Lambda_c->e - if (!nameStr.compare("eeFromLambdaCandChargedDBis")) { + if (nameStr == "eeFromLambdaCandChargedDBis") { MCProng prongLc(2, {kElectron, Pdg::kLambdaCPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); MCProng prongDch(2, {kElectron, Pdg::kDPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prongLc.SetSourceBit(0, MCProng::kPhysicalPrimary); @@ -1153,7 +1153,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // Xic0 ->e and Xic0 ->e - if (!nameStr.compare("eeFromXiC0")) { + if (nameStr == "eeFromXiC0") { MCProng prong(2, {kElectron, Pdg::kXiC0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from Xi_c0, no beauty in history", {prong, prong}, {-1, -1}); @@ -1161,7 +1161,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // Xi_c+ ->e and Xi_c+ ->e - if (!nameStr.compare("eeFromXiCPlus")) { + if (nameStr == "eeFromXiCPlus") { MCProng prong(2, {kElectron, Pdg::kXiCPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from Xi_c+, no beauty in history", {prong, prong}, {-1, -1}); @@ -1169,7 +1169,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // Xi_c0 ->e and Xi_c+ ->e - if (!nameStr.compare("eeFromXiC0andXiCPlus")) { + if (nameStr == "eeFromXiC0andXiCPlus") { MCProng prongXiCPlus(2, {kElectron, Pdg::kXiCPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); MCProng prongXiC0(2, {kElectron, Pdg::kXiC0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prongXiCPlus.SetSourceBit(0, MCProng::kPhysicalPrimary); @@ -1179,7 +1179,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // Xi_c+ ->e and Xi_c0 ->e - if (!nameStr.compare("eeFromXiC0andXiCPlusBis")) { + if (nameStr == "eeFromXiC0andXiCPlusBis") { MCProng prongXiCPlus(2, {kElectron, Pdg::kXiCPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); MCProng prongXiC0(2, {kElectron, Pdg::kXiC0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prongXiCPlus.SetSourceBit(0, MCProng::kPhysicalPrimary); @@ -1189,7 +1189,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // Xi_cc++ ->e and Xi_cc++ ->e - if (!nameStr.compare("eeFromXiCPlusPlus")) { + if (nameStr == "eeFromXiCPlusPlus") { MCProng prong(2, {kElectron, Pdg::kXiCCPlusPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from Xi_cc++, no beauty in history", {prong, prong}, {-1, -1}); @@ -1197,7 +1197,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // c->e and c->e (no check) - if (!nameStr.compare("eeFromCCNoCheck")) { + if (nameStr == "eeFromCCNoCheck") { MCProng prong(2, {11, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from c->e and c->e without check", {prong, prong}, {-1, -1}); // signal at pair level @@ -1205,7 +1205,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // ee from HF in general - if (!nameStr.compare("eeFromHF")) { + if (nameStr == "eeFromHF") { MCProng prong(2, {11, 902}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from b,c->e and b,c->e without check", {prong, prong}, {-1, -1}); // signal at pair level @@ -1213,7 +1213,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // Any c in history but no b -> c -> e - if (!nameStr.compare("eeFromPromptCandPromptC")) { + if (nameStr == "eeFromPromptCandPromptC") { MCProng prong(2, {11, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); // check if mother pdg code is in history prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs with any charm but no beauty in decay chain", {prong, prong}, {-1, -1}); // signal at pair level @@ -1221,7 +1221,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // Any b to any c in history b -> c -> e - if (!nameStr.compare("eeFromAnyBtoCandAnyBtoC")) { + if (nameStr == "eeFromAnyBtoCandAnyBtoC") { MCProng prong(2, {11, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {false}); // check if mother pdg code is in history prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs with any beauty to charm in decay chain", {prong, prong}, {-1, -1}); // signal at pair level @@ -1229,7 +1229,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // b->c->e, b->c->e - if (!nameStr.compare("eeFromBtoCandBtoC")) { + if (nameStr == "eeFromBtoCandBtoC") { MCProng prong(3, {11, 402, 502}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false); // check if mother pdg code is in history prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs with any beauty to charm in decay chain", {prong, prong}, {-1, -1}); // signal at pair level @@ -1240,7 +1240,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) // Looking at such decays: B -> (e) D -> (e)e and bar{B} -> e // Signal allows combinations of ee from the same B meson // + the combination of e fom B and e from bar{B} - if (!nameStr.compare("eeFromBandAnyBtoC")) { + if (nameStr == "eeFromBandAnyBtoC") { MCProng prongB(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prongB.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng prongBtoC(2, {11, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {false}); // check if mother pdg code is in history @@ -1250,7 +1250,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // Any b->e and Any b->X->c->e - if (!nameStr.compare("eeFromBandAnyBtoCBis")) { + if (nameStr == "eeFromBandAnyBtoCBis") { MCProng prongB(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prongB.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng prongBtoC(2, {11, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {false}); // check if mother pdg code is in history @@ -1260,7 +1260,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // b->e and b->c->e - if (!nameStr.compare("eeFromBandBtoC")) { + if (nameStr == "eeFromBandBtoC") { MCProng prongB(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prongB.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng prongBtoC(3, {11, 402, 502}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false); // check if mother pdg code is in history @@ -1270,7 +1270,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // b->e and b->c->e - if (!nameStr.compare("eeFromBandBtoCBis")) { + if (nameStr == "eeFromBandBtoCBis") { MCProng prongB(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prongB.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng prongBtoC(3, {11, 402, 502}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false); // check if mother pdg code is in history @@ -1281,7 +1281,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) // b->e and b->c->e (same mother/grandmother) // require that the mother is the grandmother of the other electron - if (!nameStr.compare("eeFromBandBtoCsameGM")) { + if (nameStr == "eeFromBandBtoCsameGM") { MCProng prongB(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prongB.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng prongBtoC(3, {11, 402, 502}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false); // check if mother pdg code is in history @@ -1292,7 +1292,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) // b->e and b->c->e (same mother/grandmother) // require that the mother is the grandmother of the other electron - if (!nameStr.compare("eeFromBandBtoCsameGMBis")) { + if (nameStr == "eeFromBandBtoCsameGMBis") { MCProng prongB(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prongB.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng prongBtoC(3, {11, 402, 502}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false); // check if mother pdg code is in history @@ -1303,7 +1303,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) // b->e and b->c->e (different mother/grandmother) // require that the mother is not the grandmother of the other electron - if (!nameStr.compare("eeFromBandBtoCdiffGM")) { + if (nameStr == "eeFromBandBtoCdiffGM") { MCProng prongB(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prongB.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng prongBtoC(3, {11, 402, 502}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false); // check if mother pdg code is in history @@ -1314,7 +1314,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) // b->e and b->c->e (different mother/grandmother) // require that the mother is not the grandmother of the other electron - if (!nameStr.compare("eeFromBandBtoCdiffGMBis")) { + if (nameStr == "eeFromBandBtoCdiffGMBis") { MCProng prongB(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prongB.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng prongBtoC(3, {11, 402, 502}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false); // check if mother pdg code is in history @@ -1324,7 +1324,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // b->e and b->e - if (!nameStr.compare("eeFromBB")) { + if (nameStr == "eeFromBB") { MCProng prong(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from b->e and b->e", {prong, prong}, {-1, -1}); // signal at pair level @@ -1332,7 +1332,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // b->e and b->e (commonAncestors) - if (!nameStr.compare("eeFromSameB")) { + if (nameStr == "eeFromSameB") { MCProng prong(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "ee pairs from b->e and b->e", {prong, prong}, {1, 1}); // signal at pair level @@ -1340,7 +1340,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // b->e and c->e no check - if (!nameStr.compare("eeFromBandFromC")) { + if (nameStr == "eeFromBandFromC") { MCProng prongB(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prongB.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng prongC(2, {11, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); @@ -1350,7 +1350,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // b->e and c->e no check - if (!nameStr.compare("eeFromBandFromCBis")) { + if (nameStr == "eeFromBandFromCBis") { MCProng prongB(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prongB.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng prongC(2, {11, 402}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); @@ -1360,7 +1360,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // b->e and b->c->e (single b) - if (!nameStr.compare("eeFromSingleBandBtoC")) { + if (nameStr == "eeFromSingleBandBtoC") { MCProng prongB(2, {11, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prongB.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng prongBtoC(3, {11, 402, 502}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); @@ -1371,26 +1371,26 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) //_________________________________________________________________________________________________________________________ - if (!nameStr.compare("kaonFromBplus")) { + if (nameStr == "kaonFromBplus") { MCProng prong(2, {321, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaons from B+ decays", {prong}, {1}); return signal; } - if (!nameStr.compare("kaonFromBplusHistory")) { + if (nameStr == "kaonFromBplusHistory") { MCProng prong(1, {321}, {true}, {false}, {0}, {0}, {false}, false, {521}, {false}); signal = new MCSignal(name, "Kaons from B+ decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("kaonPrimaryFromBplusHistory")) { + if (nameStr == "kaonPrimaryFromBplusHistory") { MCProng prong(1, {321}, {true}, {false}, {0}, {0}, {false}, false, {521}, {false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Kaons from B+ decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("kaonPrimaryFromBplusFS")) { + if (nameStr == "kaonPrimaryFromBplusFS") { MCProng prong(2, {321, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); prong.SetSourceBit(1, MCProng::kHEPMCFinalState); @@ -1398,57 +1398,57 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) return signal; } - if (!nameStr.compare("kaonFromAnyBHistory")) { + if (nameStr == "kaonFromAnyBHistory") { MCProng prong(1, {321}, {true}, {false}, {0}, {0}, {false}, false, {503}, {false}); signal = new MCSignal(name, "Kaons from B+ decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("JpsiFromBplus")) { + if (nameStr == "JpsiFromBplus") { MCProng prong(2, {443, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Jpsi from B+ decays", {prong}, {1}); return signal; } - if (!nameStr.compare("eFromJpsiFromBplus")) { + if (nameStr == "eFromJpsiFromBplus") { MCProng prong(3, {11, 443, 521}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "Electrons from Jpsi from B+ decays", {prong}, {1}); return signal; } - if (!nameStr.compare("electronFromJpsiFromBplus")) { + if (nameStr == "electronFromJpsiFromBplus") { MCProng prong(3, {11, 443, 521}, {false, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "Electrons from Jpsi from B+ decays", {prong}, {1}); return signal; } - if (!nameStr.compare("positronFromJpsiFromBplus")) { + if (nameStr == "positronFromJpsiFromBplus") { MCProng prong(3, {-11, 443, 521}, {false, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "Positrons from Jpsi from B+ decays", {prong}, {1}); return signal; } - if (!nameStr.compare("eeFromJpsiFromBplus")) { + if (nameStr == "eeFromJpsiFromBplus") { MCProng prong(3, {11, 443, 521}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "Electron pair from Jpsi from B+ decays", {prong, prong}, {1, 1}); return signal; } - if (!nameStr.compare("eeKaonFromBplus")) { + if (nameStr == "eeKaonFromBplus") { MCProng pronge(3, {11, 443, 521}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongKaon(2, {321, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon and electron pair from B+", {pronge, pronge, prongKaon}, {2, 2, 1}); return signal; } - if (!nameStr.compare("eeFromJpsiKaonAny")) { + if (nameStr == "eeFromJpsiKaonAny") { MCProng pronge(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); MCProng prongKaon(1, {321}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Kaon and electron pair", {pronge, pronge, prongKaon}, {-1, -1, -1}); return signal; } - if (!nameStr.compare("eeKaonFromBplusExclusive")) { + if (nameStr == "eeKaonFromBplusExclusive") { MCProng pronge(3, {11, 443, 521}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongKaon(2, {321, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon and electron pair from B+", {pronge, pronge, prongKaon}, {2, 2, 1}); @@ -1456,7 +1456,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) return signal; } - if (!nameStr.compare("eeKaonFromBplusNotExclusive")) { + if (nameStr == "eeKaonFromBplusNotExclusive") { MCProng pronge(3, {11, 443, 521}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongKaon(2, {321, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon and electron pair from B+", {pronge, pronge, prongKaon}, {2, 2, 1}); @@ -1465,56 +1465,56 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) } // correlated background - if (!nameStr.compare("eePionFromBplus")) { + if (nameStr == "eePionFromBplus") { MCProng pronge(3, {11, 443, 521}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongPion(2, {211, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Pion and electron pair from B+", {pronge, pronge, prongPion}, {2, 2, 1}); return signal; } - if (!nameStr.compare("eeKaonFromBplusViaEverything")) { + if (nameStr == "eeKaonFromBplusViaEverything") { MCProng pronge(3, {11, 443, 521}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongKaon(3, {321, 0, 521}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "Kaon and electron pair from B+ via everything", {pronge, pronge, prongKaon}, {2, 2, 2}); return signal; } - if (!nameStr.compare("eeKaonFromB0")) { + if (nameStr == "eeKaonFromB0") { MCProng pronge(3, {11, 443, 511}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongKaon(2, {321, 511}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon and electron pair from B0", {pronge, pronge, prongKaon}, {2, 2, 1}); return signal; } - if (!nameStr.compare("eePionFromB0ViaEverything")) { // catching feed-down for B0 + if (nameStr == "eePionFromB0ViaEverything") { // catching feed-down for B0 MCProng pronge(3, {11, 443, 511}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongPion(3, {211, 0, 511}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "Pion and electron pair from B0", {pronge, pronge, prongPion}, {2, 2, 1}); return signal; } - if (!nameStr.compare("eeKaonFromOpenBeautyMesons")) { + if (nameStr == "eeKaonFromOpenBeautyMesons") { MCProng pronge(3, {11, 443, 501}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongKaon(2, {321, 501}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Excited kaon and electron pair from B0", {pronge, pronge, prongKaon}, {2, 2, 2}); return signal; } - if (!nameStr.compare("eeKaonFromOpenBeautyHadrons")) { + if (nameStr == "eeKaonFromOpenBeautyHadrons") { MCProng pronge(3, {11, 443, 502}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongKaon(2, {321, 502}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon and electron pair from open beauty hadrons", {pronge, pronge, prongKaon}, {2, 2, 1}); return signal; } - if (!nameStr.compare("eeKaonFromLambdaB")) { + if (nameStr == "eeKaonFromLambdaB") { MCProng pronge(3, {11, 443, 5122}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongKaon(2, {321, 5122}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon and electron pair from lambda B", {pronge, pronge, prongKaon}, {2, 2, 1}); return signal; } - if (!nameStr.compare("eeKaonPion0FromBplus")) { + if (nameStr == "eeKaonPion0FromBplus") { MCProng pronge(3, {11, 443, 521}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongKaon(2, {321, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); MCProng prongPion(2, {111, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); @@ -1522,7 +1522,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) return signal; } - if (!nameStr.compare("eeKaonEtaFromBplus")) { + if (nameStr == "eeKaonEtaFromBplus") { MCProng pronge(3, {11, 443, 521}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongKaon(2, {321, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); MCProng prongEta(2, {221, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); @@ -1530,7 +1530,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) return signal; } - if (!nameStr.compare("eeKaonOmegaFromBplus")) { + if (nameStr == "eeKaonOmegaFromBplus") { MCProng pronge(3, {11, 443, 521}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongKaon(2, {321, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); MCProng prongOmega(2, {223, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); @@ -1538,7 +1538,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) return signal; } - if (!nameStr.compare("eeKaonPionFromBplus")) { + if (nameStr == "eeKaonPionFromBplus") { MCProng pronge(3, {11, 443, 521}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongKaon(2, {321, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); MCProng prongPion(2, {211, 521}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); @@ -1546,35 +1546,35 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) return signal; } - if (!nameStr.compare("Bplus")) { + if (nameStr == "Bplus") { MCProng prong(1, {521}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "B+", {prong}, {-1}); return signal; } - if (!nameStr.compare("BplusFS")) { + if (nameStr == "BplusFS") { MCProng prong(1, {521}, {true}, {false}, {0}, {0}, {false}); prong.SetSourceBit(0, MCProng::kHEPMCFinalState); signal = new MCSignal(name, "B+", {prong}, {-1}); return signal; } - if (!nameStr.compare("beautyPairs")) { + if (nameStr == "beautyPairs") { MCProng prong(1, {503}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal("beautyPairs", "Beauty hadron pair", {prong, prong}, {-1, -1}); return signal; } - if (!nameStr.compare("everythingFromBeautyPairs")) { + if (nameStr == "everythingFromBeautyPairs") { MCProng prong(2, {0, 503}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal("everythingFromBeautyPairs", "Everything from beauty hadrons pair", {prong, prong}, {-1, -1}); return signal; } - if (!nameStr.compare("everythingFromEverythingFromBeautyPairsCM")) { + if (nameStr == "everythingFromEverythingFromBeautyPairsCM") { MCProng prong(3, {0, 0, 503}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal("everythingFromEverythingFromBeautyPairs", "Everything from everything from beauty hadrons pair with common grand-mother", {prong, prong}, {2, 2}); return signal; } - if (!nameStr.compare("everythingFromBeautyANDeverythingFromEverythingFromBeautyPairs")) { + if (nameStr == "everythingFromBeautyANDeverythingFromEverythingFromBeautyPairs") { MCProng prong1(3, {0, 0, 503}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prong2(2, {0, 503}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal("everythingFromBeautyANDeverythingFromEverythingFromBeautyPairs", "Everything beauty and everything from everything from beauty hadrons pair", {prong1, prong2}, {2, 1}); @@ -1583,136 +1583,136 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) //------------------------------------------------------------------------------------ - if (!nameStr.compare("D0")) { + if (nameStr == "D0") { MCProng prong(1, {Pdg::kD0}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "D0", {prong}, {-1}); return signal; } - if (!nameStr.compare("nonPromptD0")) { + if (nameStr == "nonPromptD0") { MCProng prong(2, {Pdg::kD0, 503}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Non-prompt D0", {prong}, {-1}); return signal; } - if (!nameStr.compare("D0FS")) { + if (nameStr == "D0FS") { MCProng prong(1, {Pdg::kD0}, {true}, {false}, {0}, {0}, {false}); prong.SetSourceBit(0, MCProng::kHEPMCFinalState); signal = new MCSignal(name, "D0", {prong}, {-1}); return signal; } - if (!nameStr.compare("KPiFromD0")) { + if (nameStr == "KPiFromD0") { MCProng prongKaon(2, {321, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); MCProng prongPion(2, {211, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon and pion pair from D0", {prongKaon, prongPion}, {1, 1}); return signal; } - if (!nameStr.compare("KPiFromD0Reflected")) { + if (nameStr == "KPiFromD0Reflected") { MCProng prongFalseKaon(2, {211, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); MCProng prongFalsePion(2, {321, Pdg::kD0}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon and pion pair from D0 with reflected mass assumption", {prongFalseKaon, prongFalsePion}, {1, 1}); return signal; } - if (!nameStr.compare("Dcharged")) { + if (nameStr == "Dcharged") { MCProng prong(1, {Pdg::kDPlus}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "D+/-", {prong}, {-1}); return signal; } - if (!nameStr.compare("Dplus")) { + if (nameStr == "Dplus") { MCProng prong(1, {Pdg::kDPlus}, {false}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "D+", {prong}, {-1}); return signal; } - if (!nameStr.compare("Dminus")) { + if (nameStr == "Dminus") { MCProng prong(1, {-Pdg::kDPlus}, {false}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "D+", {prong}, {-1}); return signal; } - if (!nameStr.compare("KPiPiFromDcharged")) { + if (nameStr == "KPiPiFromDcharged") { MCProng prongKaon(2, {321, Pdg::kDPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); MCProng prongPion(2, {211, Pdg::kDPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon pion pion triplet from D+/-", {prongKaon, prongPion, prongPion}, {1, 1, 1}); return signal; } - if (!nameStr.compare("KPiPiFromDplus")) { + if (nameStr == "KPiPiFromDplus") { MCProng prongKaon(2, {-321, Pdg::kDPlus}, {false, false}, {false, false}, {0, 0}, {0, 0}, {false, false}); MCProng prongPion(2, {211, Pdg::kDPlus}, {false, false}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon pion pion triplet from D+", {prongKaon, prongPion, prongPion}, {1, 1, 1}); return signal; } - if (!nameStr.compare("KPiPiFromDminus")) { + if (nameStr == "KPiPiFromDminus") { MCProng prongKaon(2, {321, -Pdg::kDPlus}, {false, false}, {false, false}, {0, 0}, {0, 0}, {false, false}); MCProng prongPion(2, {-211, -Pdg::kDPlus}, {false, false}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon pion pion triplet from D-", {prongKaon, prongPion, prongPion}, {1, 1, 1}); return signal; } - if (!nameStr.compare("Dstar")) { + if (nameStr == "Dstar") { MCProng prong(1, {Pdg::kDStar}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "D*", {prong}, {-1}); return signal; } - if (!nameStr.compare("DstarPlus")) { + if (nameStr == "DstarPlus") { MCProng prong(1, {Pdg::kDStar}, {false}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "D*+", {prong}, {-1}); return signal; } - if (!nameStr.compare("DstarMinus")) { + if (nameStr == "DstarMinus") { MCProng prong(1, {-Pdg::kDStar}, {false}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "D*-", {prong}, {-1}); return signal; } - if (!nameStr.compare("pionFromDstar")) { + if (nameStr == "pionFromDstar") { MCProng prong(2, {211, Pdg::kDStar}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Pions from D* decays", {prong}, {1}); return signal; } - if (!nameStr.compare("D0FromDstar")) { + if (nameStr == "D0FromDstar") { MCProng prong(2, {Pdg::kD0, Pdg::kDStar}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "D0 from D* decays", {prong}, {1}); return signal; } - if (!nameStr.compare("KFromD0FromDstar")) { + if (nameStr == "KFromD0FromDstar") { MCProng prong(3, {321, Pdg::kD0, Pdg::kDStar}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "Kaons from D0 from D* decays", {prong}, {1}); return signal; } - if (!nameStr.compare("PiFromD0FromDstar")) { + if (nameStr == "PiFromD0FromDstar") { MCProng prong(3, {211, Pdg::kD0, Pdg::kDStar}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "Pions from D0 from D* decays", {prong}, {1}); return signal; } - if (!nameStr.compare("KPiFromD0FromDstar")) { + if (nameStr == "KPiFromD0FromDstar") { MCProng prongKaon(3, {321, Pdg::kD0, Pdg::kDStar}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongPion(3, {321, Pdg::kD0, Pdg::kDStar}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "Kaon and pion pair from D0 from D* decay", {prongKaon, prongPion}, {1, 1}); return signal; } - if (!nameStr.compare("KPiPiFromD0FromDstar")) { + if (nameStr == "KPiPiFromD0FromDstar") { MCProng prongKaon(3, {321, Pdg::kD0, Pdg::kDStar}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongPionSecondary(3, {211, Pdg::kD0, Pdg::kDStar}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongPion(2, {211, Pdg::kDStar}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon pion pion triplet from D*", {prongKaon, prongPionSecondary, prongPion}, {2, 2, 1}); return signal; } - if (!nameStr.compare("KPiPiFromD0FromDstarPlus")) { + if (nameStr == "KPiPiFromD0FromDstarPlus") { MCProng prongKaon(3, {-321, Pdg::kD0, Pdg::kDStar}, {false, false, false}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongPionSecondary(3, {211, Pdg::kD0, Pdg::kDStar}, {false, false, false}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongPion(2, {211, Pdg::kDStar}, {false, false}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon pion pion triplet from D*+", {prongKaon, prongPionSecondary, prongPion}, {2, 2, 1}); return signal; } - if (!nameStr.compare("KPiPiFromD0FromDstarMinus")) { + if (nameStr == "KPiPiFromD0FromDstarMinus") { MCProng prongKaon(3, {321, Pdg::kD0, Pdg::kDStar}, {false, false, false}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongPionSecondary(3, {-211, Pdg::kD0, Pdg::kDStar}, {false, false, false}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongPion(2, {-211, Pdg::kDStar}, {false, false}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Kaon pion pion triplet from D*-", {prongKaon, prongPionSecondary, prongPion}, {2, 2, 1}); return signal; } - if (!nameStr.compare("KFromDplus")) { + if (nameStr == "KFromDplus") { MCProng prong(2, {321, Pdg::kDPlus}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {502}, {true}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Kaons from D+/- decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("LambdaC")) { + if (nameStr == "LambdaC") { MCProng prong(1, {Pdg::kLambdaCPlus}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Lambda_c", {prong}, {-1}); return signal; @@ -1720,110 +1720,110 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) //-------------------------------------------------------------------------------- - if (!nameStr.compare("JpsiFromChic0")) { + if (nameStr == "JpsiFromChic0") { MCProng prong(2, {443, 10441}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Jpsi from Chic0 decays", {prong}, {1}); return signal; } - if (!nameStr.compare("eFromJpsiFromChic0")) { + if (nameStr == "eFromJpsiFromChic0") { MCProng prong(3, {11, 443, 10441}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from Jpsi from Chic0 decays", {prong}, {1}); return signal; } - if (!nameStr.compare("eeFromJpsiFromChic0")) { + if (nameStr == "eeFromJpsiFromChic0") { MCProng prong(3, {11, 443, 10441}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electron pair from Jpsi from Chic0 decays", {prong, prong}, {2, 2}); return signal; } - if (!nameStr.compare("JpsiFromChic1")) { + if (nameStr == "JpsiFromChic1") { MCProng prong(2, {443, 20443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Jpsi from Chic1 decays", {prong}, {1}); return signal; } - if (!nameStr.compare("eFromJpsiFromChic1")) { + if (nameStr == "eFromJpsiFromChic1") { MCProng prong(3, {11, 443, 20443}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from Jpsi from Chic1 decays", {prong}, {2}); return signal; } - if (!nameStr.compare("eeFromJpsiFromChic1")) { + if (nameStr == "eeFromJpsiFromChic1") { MCProng prong(3, {11, 443, 20443}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electron pair from Jpsi from Chic1 decays", {prong, prong}, {2, 2}); return signal; } - if (!nameStr.compare("JpsiFromChic2")) { + if (nameStr == "JpsiFromChic2") { MCProng prong(2, {443, 445}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Jpsi from Chic2 decays", {prong}, {1}); return signal; } - if (!nameStr.compare("JpsiFromChic2")) { + if (nameStr == "JpsiFromChic2") { MCProng prong(2, {443, 904}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Jpsi from Chic0, Chic1 or Chic2 decays", {prong}, {1}); return signal; } - if (!nameStr.compare("eFromJpsiFromChic2")) { + if (nameStr == "eFromJpsiFromChic2") { MCProng prong(3, {11, 443, 445}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electrons from Jpsi from Chic2 decays", {prong}, {2}); return signal; } - if (!nameStr.compare("eeFromJpsiFromChic2")) { + if (nameStr == "eeFromJpsiFromChic2") { MCProng prong(3, {11, 443, 445}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electron pair from Jpsi from Chic2 decays", {prong, prong}, {2, 2}); return signal; } - if (!nameStr.compare("eeFromJpsiFromChic012")) { + if (nameStr == "eeFromJpsiFromChic012") { MCProng prong(3, {11, 443, 904}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Electron pair from Jpsi from Chic0, Chic1 or Chic2 decays", {prong, prong}, {2, 2}); return signal; } - if (!nameStr.compare("PhotonFromChic0")) { + if (nameStr == "PhotonFromChic0") { MCProng prong(2, {22, 10441}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Photon from Chic0 decays", {prong}, {1}); return signal; } - if (!nameStr.compare("PhotonFromChic1")) { + if (nameStr == "PhotonFromChic1") { MCProng prong(2, {22, 20443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Photon from Chic1 decays", {prong}, {1}); return signal; } - if (!nameStr.compare("PhotonFromChic2")) { + if (nameStr == "PhotonFromChic2") { MCProng prong(2, {22, 445}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Photon from Chic2 decays", {prong}, {1}); return signal; } - if (!nameStr.compare("PhotonFromChic012")) { + if (nameStr == "PhotonFromChic012") { MCProng prong(2, {22, 904}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Photon from Chic0, Chic1, and Chic2 decays", {prong}, {-1}); return signal; } - if (!nameStr.compare("PhotonFromPi0")) { + if (nameStr == "PhotonFromPi0") { MCProng prong(2, {22, 111}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); // prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Photon from Pi0 decays", {prong}, {1}); return signal; } - if (!nameStr.compare("PhotonPhotonFromPi0")) { + if (nameStr == "PhotonPhotonFromPi0") { MCProng prong(2, {22, 111}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); prong.SetSourceBit(0, MCProng::kPhysicalPrimary); signal = new MCSignal(name, "Photon Photon from Pi0 decays", {prong, prong}, {1, 1}); return signal; } - if (!nameStr.compare("eePhotonFromChic1")) { + if (nameStr == "eePhotonFromChic1") { MCProng pronge(3, {11, 443, 20443}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongPhoton(2, {22, 20443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); pronge.SetSourceBit(0, MCProng::kPhysicalPrimary); @@ -1832,7 +1832,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) return signal; } - if (!nameStr.compare("eePhotonFromChic2")) { + if (nameStr == "eePhotonFromChic2") { MCProng pronge(3, {11, 443, 445}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongPhoton(2, {22, 445}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); pronge.SetSourceBit(0, MCProng::kPhysicalPrimary); @@ -1841,7 +1841,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) return signal; } - if (!nameStr.compare("eePhotonFromChic12")) { + if (nameStr == "eePhotonFromChic12") { MCProng pronge(3, {11, 443, MCProng::kPDGCodeNotAssigned}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongPhoton(2, {22, MCProng::kPDGCodeNotAssigned}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); pronge.SetSourceBit(0, MCProng::kPhysicalPrimary); @@ -1850,7 +1850,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) return signal; } - if (!nameStr.compare("eePhotonFromPi0")) { + if (nameStr == "eePhotonFromPi0") { MCProng pronge(2, {11, 111}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); MCProng prongPhoton(2, {22, 111}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); pronge.SetSourceBit(0, MCProng::kPhysicalPrimary); @@ -1861,151 +1861,151 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) //-------------------------------------------------------------------------------- - if (!nameStr.compare("X3872")) { + if (nameStr == "X3872") { MCProng prong(1, {9920443}, {true}, {false}, {0}, {0}, {false}); signal = new MCSignal(name, "Inclusive X(3872)", {prong}, {-1}); return signal; } - if (!nameStr.compare("JpsiFromX3872")) { + if (nameStr == "JpsiFromX3872") { MCProng prong(1, {443}, {true}, {false}, {0}, {0}, {false}, false, {9920443}, {false}); signal = new MCSignal(name, "Jpsi from X3872", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromX3872")) { + if (nameStr == "eFromX3872") { MCProng prong(3, {11, 443, 9920443}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "Electron from Jpsi from X3872", {prong}, {1}); return signal; } - if (!nameStr.compare("PionFromX3872")) { + if (nameStr == "PionFromX3872") { MCProng prong(1, {211}, {true}, {false}, {0}, {0}, {false}, false, {9920443}, {false}); signal = new MCSignal(name, "Pion from Jpsi from X3872", {prong}, {-1}); return signal; } - if (!nameStr.compare("JpsiFromPsi2S")) { + if (nameStr == "JpsiFromPsi2S") { MCProng prong(1, {443}, {true}, {false}, {0}, {0}, {false}, false, {100443}, {false}); signal = new MCSignal(name, "Jpsi from Psi2S", {prong}, {-1}); return signal; } - if (!nameStr.compare("JpsiFromPromptPsi2S")) { + if (nameStr == "JpsiFromPromptPsi2S") { MCProng prong(2, {443, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {true}); signal = new MCSignal(name, "Jpsi from prompt Psi2S", {prong}, {-1}); return signal; } - if (!nameStr.compare("JpsiFromNonpromptPsi2S")) { + if (nameStr == "JpsiFromNonpromptPsi2S") { MCProng prong(2, {443, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {false}); signal = new MCSignal(name, "Jpsi from non-prompt Psi2S", {prong}, {-1}); return signal; } - if (!nameStr.compare("eFromJpsiFromPsi2S")) { + if (nameStr == "eFromJpsiFromPsi2S") { MCProng prong(3, {11, 443, 100443}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); signal = new MCSignal(name, "Electron from Jpsi from Psi2S", {prong}, {1}); return signal; } - if (!nameStr.compare("eFromJpsiFromPromptPsi2S")) { + if (nameStr == "eFromJpsiFromPromptPsi2S") { MCProng prong(3, {11, 443, 100443}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false, {503}, {true}); signal = new MCSignal(name, "Electron from Jpsi from prompt Psi2S", {prong}, {1}); return signal; } - if (!nameStr.compare("eFromJpsiFromNonpromptPsi2S")) { + if (nameStr == "eFromJpsiFromNonpromptPsi2S") { MCProng prong(3, {11, 443, 100443}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false, {503}, {false}); signal = new MCSignal(name, "Electron from Jpsi from non-prompt Psi2S", {prong}, {1}); return signal; } - if (!nameStr.compare("PionFromPsi2S")) { + if (nameStr == "PionFromPsi2S") { MCProng prong(1, {211}, {true}, {false}, {0}, {0}, {false}, false, {100443}, {false}); signal = new MCSignal(name, "Pion from Jpsi from Psi2S", {prong}, {-1}); return signal; } - if (!nameStr.compare("PionFromPromptPsi2S")) { + if (nameStr == "PionFromPromptPsi2S") { MCProng prong(2, {211, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {true}); signal = new MCSignal(name, "Pion from prompt Psi2S", {prong}, {-1}); return signal; } - if (!nameStr.compare("PionFromNonpromptPsi2S")) { + if (nameStr == "PionFromNonpromptPsi2S") { MCProng prong(2, {211, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {false}); signal = new MCSignal(name, "Pion from non-prompt Psi2S", {prong}, {-1}); return signal; } - if (!nameStr.compare("eeFromJpsiFromX3872")) { + if (nameStr == "eeFromJpsiFromX3872") { MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {9920443}, {false}); signal = new MCSignal(name, "Electron pair from Jpsi from X3872", {prong, prong}, {1, 1}); return signal; } - if (!nameStr.compare("JpsiPiPiFromX3872")) { + if (nameStr == "JpsiPiPiFromX3872") { MCProng prongJpsi(2, {443, 9920443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); MCProng prongPi(2, {211, 9920443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Jpsi and pion pair from X3872", {prongJpsi, prongPi, prongPi}, {1, 1, 1}); return signal; } - if (!nameStr.compare("eePiPiFromX3872")) { + if (nameStr == "eePiPiFromX3872") { MCProng pronge(3, {11, 443, 9920443}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongPi(2, {211, 9920443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electron pair and pion pair from X3872", {pronge, pronge, prongPi, prongPi}, {2, 2, 1, 1}); return signal; } - if (!nameStr.compare("eeFromJpsiFromPsi2S")) { + if (nameStr == "eeFromJpsiFromPsi2S") { MCProng prong(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {100443}, {false}); signal = new MCSignal(name, "Electron pair from Jpsi from Psi2S", {prong, prong}, {1, 1}); return signal; } - if (!nameStr.compare("eeFromJpsiFromPromptPsi2S")) { + if (nameStr == "eeFromJpsiFromPromptPsi2S") { MCProng prong(3, {11, 443, 100443}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false, {503}, {true}); signal = new MCSignal(name, "Electron pair from Jpsi from prompt Psi2S", {prong, prong}, {1, 1}); return signal; } - if (!nameStr.compare("eeFromJpsiFromNonpromptPsi2S")) { + if (nameStr == "eeFromJpsiFromNonpromptPsi2S") { MCProng prong(3, {11, 443, 100443}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false, {503}, {false}); signal = new MCSignal(name, "Electron pair from Jpsi from non-prompt Psi2S", {prong, prong}, {1, 1}); return signal; } - if (!nameStr.compare("JpsiPiPiFromPsi2S")) { + if (nameStr == "JpsiPiPiFromPsi2S") { MCProng prongJpsi(2, {443, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); MCProng prongPi(2, {211, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Jpsi and pion pair from Psi2S", {prongJpsi, prongPi, prongPi}, {1, 1, 1}); return signal; } - if (!nameStr.compare("eePiPiFromPsi2S")) { + if (nameStr == "eePiPiFromPsi2S") { MCProng pronge(3, {11, 443, 100443}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); MCProng prongPi(2, {211, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); signal = new MCSignal(name, "Electron pair and pion pair from Psi2S", {pronge, pronge, prongPi, prongPi}, {2, 2, 1, 1}); return signal; } - if (!nameStr.compare("eePiPiFromPromptPsi2S")) { + if (nameStr == "eePiPiFromPromptPsi2S") { MCProng pronge(3, {11, 443, 100443}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false, {503}, {true}); MCProng prongPi(2, {211, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {true}); signal = new MCSignal(name, "Electron pair and pion pair from prompt Psi2S", {pronge, pronge, prongPi, prongPi}, {2, 2, 1, 1}); return signal; } - if (!nameStr.compare("eePiPiFromNonpromptPsi2S")) { + if (nameStr == "eePiPiFromNonpromptPsi2S") { MCProng pronge(3, {11, 443, 100443}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}, false, {503}, {false}); MCProng prongPi(2, {211, 100443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {false}); signal = new MCSignal(name, "Electron pair and pion pair from non-prompt Psi2S", {pronge, pronge, prongPi, prongPi}, {2, 2, 1, 1}); return signal; } - if (!nameStr.compare("eeFromPromptJpsiAnyPrimary")) { + if (nameStr == "eeFromPromptJpsiAnyPrimary") { MCProng pronge(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}, false, {503}, {true}); pronge.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng prongPrimary(1); @@ -2014,7 +2014,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) return signal; } - if (!nameStr.compare("eeFromJpsiAnyPrimary")) { + if (nameStr == "eeFromJpsiAnyPrimary") { MCProng pronge(2, {11, 443}, {true, true}, {false, false}, {0, 0}, {0, 0}, {false, false}); pronge.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng prongPrimary(1); @@ -2023,7 +2023,7 @@ MCSignal* o2::aod::dqmcsignals::GetMCSignal(const char* name) return signal; } - if (!nameStr.compare("eeFromNonPromptJpsiAnyPrimary")) { + if (nameStr == "eeFromNonPromptJpsiAnyPrimary") { MCProng pronge(3, {11, 443, 503}, {true, true, true}, {false, false, false}, {0, 0, 0}, {0, 0, 0}, {false, false, false}); pronge.SetSourceBit(0, MCProng::kPhysicalPrimary); MCProng prongPrimary(1); @@ -2136,7 +2136,7 @@ std::vector o2::aod::dqmcsignals::GetMCSignalsFromJSON(const char* js } // Create the signal and add it to the output vector - MCSignal* mcSignal = new MCSignal(sigName, title, prongs, commonAncestors, excludeCommonAncestor); + auto* mcSignal = new MCSignal(sigName, title, prongs, commonAncestors, excludeCommonAncestor); LOG(debug) << "MCSignal defined, adding to the output vector"; mcSignal->PrintConfig(); signals.push_back(mcSignal); @@ -2422,8 +2422,8 @@ MCProng* o2::aod::dqmcsignals::ParseJSONMCProng(T prongJSON, const char* prongNa } // Calling the MCProng constructor - MCProng* prong = new MCProng(n, pdgs, checkBothCharges, excludePDG, sBitsVec, sBitsExcludeVec, useANDonSourceBitMap, - checkGenerationsInTime, checkIfPDGInHistory, excludePDGInHistory); + auto* prong = new MCProng(n, pdgs, checkBothCharges, excludePDG, sBitsVec, sBitsExcludeVec, useANDonSourceBitMap, + checkGenerationsInTime, checkIfPDGInHistory, excludePDGInHistory); // Print the configuration prong->Print(); return prong; diff --git a/PWGDQ/Core/MixingHandler.cxx b/PWGDQ/Core/MixingHandler.cxx index 5b769fed65d..962032ca864 100644 --- a/PWGDQ/Core/MixingHandler.cxx +++ b/PWGDQ/Core/MixingHandler.cxx @@ -13,18 +13,16 @@ #include "PWGDQ/Core/VarManager.h" -#include -#include #include #include -#include +#include +#include +#include #include using namespace std; -ClassImp(MixingHandler); - //_________________________________________________________________________ MixingHandler::MixingHandler() : TNamed(), fIsInitialized(false), diff --git a/PWGDQ/Core/MixingHandler.h b/PWGDQ/Core/MixingHandler.h index 2a396ab7d35..8a6f8597db8 100644 --- a/PWGDQ/Core/MixingHandler.h +++ b/PWGDQ/Core/MixingHandler.h @@ -19,12 +19,12 @@ #include "PWGDQ/Core/VarManager.h" -#include #include #include #include +#include #include #include #include @@ -39,8 +39,8 @@ class MixingHandler : public TNamed float eta; float phi; uint32_t filteringFlags; - // flip a bit to zero (needed when a track was already used in mixing for that bit for the required pool depth) - void FlipBit(int64_t mask) { filteringFlags ^= mask; } + // Clear a bit once the track was used in mixing for that bit for the required pool depth. + void ClearBit(uint32_t mask) { filteringFlags &= ~mask; } void Print() const { std::cout << "pt: " << pt << ", eta: " << eta << ", phi: " << phi << ", filteringFlags: " << filteringFlags << std::endl; @@ -56,7 +56,7 @@ class MixingHandler : public TNamed // bit map for active filtering bits of all the tracks uint32_t filteringMask = 0; // counters to keep track of how many times the event was used for mixing (for each track cut separately) - std::array counters = {0}; + std::array counters = {0}; // add a track to the event and update the filtering mask accordingly void AddTrack1(const MixingTrack& track) { @@ -68,32 +68,40 @@ class MixingHandler : public TNamed tracks2.push_back(track); filteringMask |= track.filteringFlags; } - // flip bits in the filtering mask - void FlipFilteringMask(int64_t mask) { filteringMask ^= mask; } + // Clear bits in the filtering mask. + void ClearFilteringMask(uint32_t mask) { filteringMask &= ~mask; } // 1) increment the counters for a given track cut bit mask and if the counters reached the pool depth, - // 2) flip the corresponding bit in the tracks filtering flags to exclude them from further mixing + // 2) clear the corresponding bit in the tracks filtering flags to exclude them from further mixing // 3) for each track, if there are no more active bits in the filtering mask, then remove the track from the event - void IncrementCounters(uint32_t mask, short poolDepth) + void IncrementCounters(uint32_t mask, int16_t poolDepth) { for (int i = 0; i < 32; i++) { - if (mask & (1ULL << i)) { + uint32_t bitMask = (static_cast(1) << i); + if (mask & bitMask) { counters[i]++; if (counters[i] >= poolDepth) { for (auto& track : tracks1) { - track.FlipBit(1ULL << i); - if (track.filteringFlags == 0) { - track = tracks1.back(); - tracks1.pop_back(); + track.ClearBit(bitMask); + } + for (auto track = tracks1.begin(); track != tracks1.end();) { + if (track->filteringFlags == 0) { + track = tracks1.erase(track); + } else { + ++track; } } + for (auto& track : tracks2) { - track.FlipBit(1ULL << i); - if (track.filteringFlags == 0) { - track = tracks2.back(); - tracks2.pop_back(); + track.ClearBit(bitMask); + } + for (auto track = tracks2.begin(); track != tracks2.end();) { + if (track->filteringFlags == 0) { + track = tracks2.erase(track); + } else { + ++track; } } - FlipFilteringMask(1ULL << i); + ClearFilteringMask(bitMask); } } } @@ -131,13 +139,17 @@ class MixingHandler : public TNamed // check which events in the pool are empty (i.e. no active tracks for mixing) and remove them from the pool void CleanPool() { - events.erase(std::remove_if(events.begin(), events.end(), - [](const MixingEvent& event) { return event.tracks1.empty() && event.tracks2.empty(); }), - events.end()); + for (auto event = events.begin(); event != events.end();) { + if (event->tracks1.empty() && event->tracks2.empty()) { + event = events.erase(event); + } else { + ++event; + } + } } // The function that performs the mixing is called outside this class, but the pool provides the events and tracks to be mixed and takes care of updating the events after mixing // (e.g. incrementing the counters and removing the tracks that reached the pool depth for a given cut) - void UpdatePool(const MixingEvent& event, short poolDepth) + void UpdatePool(const MixingEvent& event, int16_t poolDepth) { for (auto& event : events) { event.IncrementCounters(event.filteringMask, poolDepth); @@ -163,14 +175,14 @@ class MixingHandler : public TNamed // setters void AddMixingVariable(int var, std::vector binLims); - void SetPoolDepth(short depth) { fPoolDepth = depth; } + void SetPoolDepth(int16_t depth) { fPoolDepth = depth; } // getters // int GetNMixingVariables() const { return fVariables.size(); } // int GetMixingVariable(VarManager::Variables var); // returns the position in the internal varible list of the handler. Useful for checks, mostly // std::vector GetMixingVariableLimits(VarManager::Variables var); MixingPool& GetPool(int category) { return fPools[category]; } - short GetPoolDepth() const { return fPoolDepth; } + int16_t GetPoolDepth() const { return fPoolDepth; } void Init(); int FindEventCategory(float* values); @@ -187,10 +199,8 @@ class MixingHandler : public TNamed std::vector> fVariableLimits; std::map fVariables; // key: variable, value: position in the internal variable list of the handler (used to map the variables to the values passed to FindEventCategory) - short fPoolDepth; // number of events to be kept in each pool + int16_t fPoolDepth; // number of events to be kept in each pool std::map fPools; // key: category, value: pool of events corresponding to that category - - ClassDef(MixingHandler, 2); }; #endif // PWGDQ_CORE_MIXINGHANDLER_H_ diff --git a/PWGDQ/Core/MixingLibrary.cxx b/PWGDQ/Core/MixingLibrary.cxx index b152de7d27c..8bc00b6a53d 100644 --- a/PWGDQ/Core/MixingLibrary.cxx +++ b/PWGDQ/Core/MixingLibrary.cxx @@ -29,183 +29,183 @@ void o2::aod::dqmixing::SetUpMixing(MixingHandler* mh, const char* mixingVarible) { std::string nameStr = mixingVarible; - if (!nameStr.compare("Centrality1")) { + if (nameStr == "Centrality1") { std::vector fCentLimsHashing = {0.0f, 20.0f, 40.0f, 60.0f, 90.0f}; mh->AddMixingVariable(VarManager::kCentVZERO, fCentLimsHashing); } - if (!nameStr.compare("Centrality2")) { + if (nameStr == "Centrality2") { std::vector fCentLimsHashing = {0.0f, 10.0f, 20.0f, 40.0f, 60.0f, 90.0f}; mh->AddMixingVariable(VarManager::kCentVZERO, fCentLimsHashing); } - if (!nameStr.compare("Centrality3")) { + if (nameStr == "Centrality3") { std::vector fCentLimsHashing = {0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 70.0f, 90.0f}; mh->AddMixingVariable(VarManager::kCentVZERO, fCentLimsHashing); } - if (!nameStr.compare("Centrality4")) { + if (nameStr == "Centrality4") { std::vector fCentLimsHashing = {0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f}; mh->AddMixingVariable(VarManager::kCentVZERO, fCentLimsHashing); } - if (!nameStr.compare("Centrality5")) { + if (nameStr == "Centrality5") { std::vector fCentLimsHashing = {0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f}; mh->AddMixingVariable(VarManager::kCentVZERO, fCentLimsHashing); } - if (!nameStr.compare("Centrality6")) { + if (nameStr == "Centrality6") { std::vector fCentLimsHashing = {0.0f, 2.5f, 5.0f, 7.5f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f}; mh->AddMixingVariable(VarManager::kCentVZERO, fCentLimsHashing); } - if (!nameStr.compare("CentralityFT0C1")) { + if (nameStr == "CentralityFT0C1") { std::vector fCentFT0CLimsHashing = {0.0f, 20.0f, 40.0f, 60.0f, 90.0f}; mh->AddMixingVariable(VarManager::kCentFT0C, fCentFT0CLimsHashing); } - if (!nameStr.compare("CentralityFT0C2")) { + if (nameStr == "CentralityFT0C2") { std::vector fCentFT0CLimsHashing = {0.0f, 10.0f, 20.0f, 40.0f, 60.0f, 90.0f}; mh->AddMixingVariable(VarManager::kCentFT0C, fCentFT0CLimsHashing); } - if (!nameStr.compare("CentralityFT0C3")) { + if (nameStr == "CentralityFT0C3") { std::vector fCentFT0CLimsHashing = {0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 70.0f, 90.0f}; mh->AddMixingVariable(VarManager::kCentFT0C, fCentFT0CLimsHashing); } - if (!nameStr.compare("CentralityFT0C4")) { + if (nameStr == "CentralityFT0C4") { std::vector fCentFT0CLimsHashing = {0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f}; mh->AddMixingVariable(VarManager::kCentFT0C, fCentFT0CLimsHashing); } - if (!nameStr.compare("CentralityFT0C5")) { + if (nameStr == "CentralityFT0C5") { std::vector fCentFT0CLimsHashing = {0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f}; mh->AddMixingVariable(VarManager::kCentFT0C, fCentFT0CLimsHashing); } - if (!nameStr.compare("CentralityFT0C6")) { + if (nameStr == "CentralityFT0C6") { std::vector fCentFT0CLimsHashing = {0.0f, 2.5f, 5.0f, 7.5f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f}; mh->AddMixingVariable(VarManager::kCentFT0C, fCentFT0CLimsHashing); } - if (!nameStr.compare("Mult1")) { + if (nameStr == "Mult1") { std::vector fMultLimsHashing = {0.0f, 10.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 120.0f, 160.0f, 350.0f}; mh->AddMixingVariable(VarManager::kVtxNcontrib, fMultLimsHashing); } - if (!nameStr.compare("Mult2")) { + if (nameStr == "Mult2") { std::vector fMultLimsHashing = {0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 120.0f, 140.0f, 180.0f, 350.0f}; mh->AddMixingVariable(VarManager::kVtxNcontrib, fMultLimsHashing); } - if (!nameStr.compare("Mult3")) { + if (nameStr == "Mult3") { std::vector fMultLimsHashing = {0.0f, 5.0f, 10.0f, 15.0f, 20.0f, 25.0f, 30.0f, 35.0f, 40.0f, 45.0f, 50.0f, 55.0f, 60.0f, 65.0f, 70.0f, 75.0f, 80.0f, 85.0f, 90.0f, 100.0f, 120.0f, 140.0f, 165.0f, 200.0f, 350.0f}; mh->AddMixingVariable(VarManager::kVtxNcontrib, fMultLimsHashing); } - if (!nameStr.compare("Vtx1")) { + if (nameStr == "Vtx1") { std::vector fZLimsHashing = {-10.0f, 0.0f, 10.0f}; mh->AddMixingVariable(VarManager::kVtxZ, fZLimsHashing); } - if (!nameStr.compare("Vtx2")) { + if (nameStr == "Vtx2") { std::vector fZLimsHashing = {-10.0f, -5.0f, 0.0f, 5.0f, 10.0f}; mh->AddMixingVariable(VarManager::kVtxZ, fZLimsHashing); } - if (!nameStr.compare("Vtx3")) { + if (nameStr == "Vtx3") { std::vector fZLimsHashing = {-10.0f, -7.5f, -5.0f, -2.5f, 0.0f, 2.5f, 5.0f, 7.5f, 10.0f}; mh->AddMixingVariable(VarManager::kVtxZ, fZLimsHashing); } - if (!nameStr.compare("Vtx4")) { + if (nameStr == "Vtx4") { std::vector fZLimsHashing = {-10.0f, -8.0f, -6.0f, -4.0f, -2.0f, 0.0f, 2.0f, 4.0f, 6.0f, 8.0f, 10.0f}; mh->AddMixingVariable(VarManager::kVtxZ, fZLimsHashing); } - if (!nameStr.compare("Vtx5")) { + if (nameStr == "Vtx5") { std::vector fZLimsHashing = {-10.0f, -9.0f, -8.0f, -7.0f, -6.0f, -5.0f, -4.0f, -3.0f, -2.0f, -1.0f, 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f}; mh->AddMixingVariable(VarManager::kVtxZ, fZLimsHashing); } - if (!nameStr.compare("Occupancy1")) { + if (nameStr == "Occupancy1") { std::vector fOccLimsHashing = {0.0f, 500.0f, 1000.0f, 2000.0f, 3000.0f, 6000.0f, 50000.0f}; mh->AddMixingVariable(VarManager::kTrackOccupancyInTimeRange, fOccLimsHashing); } - if (!nameStr.compare("Occupancy2")) { + if (nameStr == "Occupancy2") { std::vector fOccLimsHashing = {0.0f, 250.0f, 500.0f, 750.0f, 1000.0f, 1500.0f, 2000.0f, 3000.0f, 6000.0f, 50000.0f}; mh->AddMixingVariable(VarManager::kTrackOccupancyInTimeRange, fOccLimsHashing); } - if (!nameStr.compare("Occupancy3")) { + if (nameStr == "Occupancy3") { std::vector fOccLimsHashing = {0.0f, 250.0f, 500.0f, 750.0f, 1000.0f, 1500.0f, 2000.0f, 3000.0f, 4500.0f, 6000.0f, 8000.0f, 10000.0f, 50000.0f}; mh->AddMixingVariable(VarManager::kTrackOccupancyInTimeRange, fOccLimsHashing); } - if (!nameStr.compare("Psi2A1")) { + if (nameStr == "Psi2A1") { std::vector fPsi2A = {-TMath::Pi() / 2., 0.0f, TMath::Pi() / 2.}; mh->AddMixingVariable(VarManager::kPsi2A, fPsi2A); } - if (!nameStr.compare("Psi2A2")) { + if (nameStr == "Psi2A2") { std::vector fPsi2A = {-TMath::Pi() / 2., -TMath::Pi() / 4., 0.0f, TMath::Pi() / 4., TMath::Pi() / 2.}; mh->AddMixingVariable(VarManager::kPsi2A, fPsi2A); } - if (!nameStr.compare("Psi2A3")) { + if (nameStr == "Psi2A3") { std::vector fPsi2A = {-4 * TMath::Pi() / 8., -3 * TMath::Pi() / 8., -2 * TMath::Pi() / 8., -TMath::Pi() / 8., 0.0f, TMath::Pi() / 8., 2 * TMath::Pi() / 8., 3 * TMath::Pi() / 8., 4 * TMath::Pi() / 8.}; mh->AddMixingVariable(VarManager::kPsi2A, fPsi2A); } - if (!nameStr.compare("Psi2A4")) { + if (nameStr == "Psi2A4") { std::vector fPsi2A = {-8 * TMath::Pi() / 16., -7 * TMath::Pi() / 16., -6 * TMath::Pi() / 16., -5 * TMath::Pi() / 16., -4 * TMath::Pi() / 16., -3 * TMath::Pi() / 16., -2 * TMath::Pi() / 16., -TMath::Pi() / 16., 0.0f, TMath::Pi() / 16., 2 * TMath::Pi() / 16., 3 * TMath::Pi() / 16., 4 * TMath::Pi() / 16., 5 * TMath::Pi() / 16., 6 * TMath::Pi() / 16., 7 * TMath::Pi() / 16., 8 * TMath::Pi() / 16.}; mh->AddMixingVariable(VarManager::kPsi2A, fPsi2A); } - if (!nameStr.compare("Psi2A5")) { + if (nameStr == "Psi2A5") { std::vector fPsi2A = {-12 * TMath::Pi() / 24., -11 * TMath::Pi() / 24., -10 * TMath::Pi() / 24., -9 * TMath::Pi() / 24., -8 * TMath::Pi() / 24., -7 * TMath::Pi() / 24., -6 * TMath::Pi() / 24., -5 * TMath::Pi() / 24., -4 * TMath::Pi() / 24., -3 * TMath::Pi() / 24., -2 * TMath::Pi() / 24., -TMath::Pi() / 24., 0.0f, TMath::Pi() / 24., 2 * TMath::Pi() / 24., 3 * TMath::Pi() / 24., 4 * TMath::Pi() / 24., 5 * TMath::Pi() / 24., 6 * TMath::Pi() / 24., 7 * TMath::Pi() / 24., 8 * TMath::Pi() / 24., 9 * TMath::Pi() / 24., 10 * TMath::Pi() / 24., 11 * TMath::Pi() / 24., 12 * TMath::Pi() / 24.}; mh->AddMixingVariable(VarManager::kPsi2A, fPsi2A); } - if (!nameStr.compare("Psi2B1")) { + if (nameStr == "Psi2B1") { std::vector fPsi2B = {-TMath::Pi() / 2., 0.0f, TMath::Pi() / 2.}; mh->AddMixingVariable(VarManager::kPsi2B, fPsi2B); } - if (!nameStr.compare("Psi2B2")) { + if (nameStr == "Psi2B2") { std::vector fPsi2B = {-TMath::Pi() / 2., -TMath::Pi() / 4., 0.0f, TMath::Pi() / 4., TMath::Pi() / 2.}; mh->AddMixingVariable(VarManager::kPsi2B, fPsi2B); } - if (!nameStr.compare("Psi2B3")) { + if (nameStr == "Psi2B3") { std::vector fPsi2B = {-4 * TMath::Pi() / 8., -3 * TMath::Pi() / 8., -2 * TMath::Pi() / 8., -TMath::Pi() / 8., 0.0f, TMath::Pi() / 8., 2 * TMath::Pi() / 8., 3 * TMath::Pi() / 8., 4 * TMath::Pi() / 8.}; mh->AddMixingVariable(VarManager::kPsi2B, fPsi2B); } - if (!nameStr.compare("Psi2B4")) { + if (nameStr == "Psi2B4") { std::vector fPsi2B = {-8 * TMath::Pi() / 16., -7 * TMath::Pi() / 16., -6 * TMath::Pi() / 16., -5 * TMath::Pi() / 16., -4 * TMath::Pi() / 16., -3 * TMath::Pi() / 16., -2 * TMath::Pi() / 16., -TMath::Pi() / 16., 0.0f, TMath::Pi() / 16., 2 * TMath::Pi() / 16., 3 * TMath::Pi() / 16., 4 * TMath::Pi() / 16., 5 * TMath::Pi() / 16., 6 * TMath::Pi() / 16., 7 * TMath::Pi() / 16., 8 * TMath::Pi() / 16.}; mh->AddMixingVariable(VarManager::kPsi2B, fPsi2B); } - if (!nameStr.compare("Psi2B5")) { + if (nameStr == "Psi2B5") { std::vector fPsi2B = {-12 * TMath::Pi() / 24., -11 * TMath::Pi() / 24., -10 * TMath::Pi() / 24., -9 * TMath::Pi() / 24., -8 * TMath::Pi() / 24., -7 * TMath::Pi() / 24., -6 * TMath::Pi() / 24., -5 * TMath::Pi() / 24., -4 * TMath::Pi() / 24., -3 * TMath::Pi() / 24., -2 * TMath::Pi() / 24., -TMath::Pi() / 24., 0.0f, TMath::Pi() / 24., 2 * TMath::Pi() / 24., 3 * TMath::Pi() / 24., 4 * TMath::Pi() / 24., 5 * TMath::Pi() / 24., 6 * TMath::Pi() / 24., 7 * TMath::Pi() / 24., 8 * TMath::Pi() / 24., 9 * TMath::Pi() / 24., 10 * TMath::Pi() / 24., 11 * TMath::Pi() / 24., 12 * TMath::Pi() / 24.}; mh->AddMixingVariable(VarManager::kPsi2B, fPsi2B); } - if (!nameStr.compare("Psi2C1")) { + if (nameStr == "Psi2C1") { std::vector fPsi2C = {-TMath::Pi() / 2., 0.0f, TMath::Pi() / 2.}; mh->AddMixingVariable(VarManager::kPsi2C, fPsi2C); } - if (!nameStr.compare("Psi2C2")) { + if (nameStr == "Psi2C2") { std::vector fPsi2C = {-TMath::Pi() / 2., -TMath::Pi() / 4., 0.0f, TMath::Pi() / 4., TMath::Pi() / 2.}; mh->AddMixingVariable(VarManager::kPsi2C, fPsi2C); } - if (!nameStr.compare("Psi2C3")) { + if (nameStr == "Psi2C3") { std::vector fPsi2C = {-4 * TMath::Pi() / 8., -3 * TMath::Pi() / 8., -2 * TMath::Pi() / 8., -TMath::Pi() / 8., 0.0f, TMath::Pi() / 8., 2 * TMath::Pi() / 8., 3 * TMath::Pi() / 8., 4 * TMath::Pi() / 8.}; mh->AddMixingVariable(VarManager::kPsi2C, fPsi2C); } - if (!nameStr.compare("Psi2C4")) { + if (nameStr == "Psi2C4") { std::vector fPsi2C = {-8 * TMath::Pi() / 16., -7 * TMath::Pi() / 16., -6 * TMath::Pi() / 16., -5 * TMath::Pi() / 16., -4 * TMath::Pi() / 16., -3 * TMath::Pi() / 16., -2 * TMath::Pi() / 16., -TMath::Pi() / 16., 0.0f, TMath::Pi() / 16., 2 * TMath::Pi() / 16., 3 * TMath::Pi() / 16., 4 * TMath::Pi() / 16., 5 * TMath::Pi() / 16., 6 * TMath::Pi() / 16., 7 * TMath::Pi() / 16., 8 * TMath::Pi() / 16.}; mh->AddMixingVariable(VarManager::kPsi2C, fPsi2C); } - if (!nameStr.compare("Psi2C5")) { + if (nameStr == "Psi2C5") { std::vector fPsi2C = {-12 * TMath::Pi() / 24., -11 * TMath::Pi() / 24., -10 * TMath::Pi() / 24., -9 * TMath::Pi() / 24., -8 * TMath::Pi() / 24., -7 * TMath::Pi() / 24., -6 * TMath::Pi() / 24., -5 * TMath::Pi() / 24., -4 * TMath::Pi() / 24., -3 * TMath::Pi() / 24., -2 * TMath::Pi() / 24., -TMath::Pi() / 24., 0.0f, TMath::Pi() / 24., 2 * TMath::Pi() / 24., 3 * TMath::Pi() / 24., 4 * TMath::Pi() / 24., 5 * TMath::Pi() / 24., 6 * TMath::Pi() / 24., 7 * TMath::Pi() / 24., 8 * TMath::Pi() / 24., 9 * TMath::Pi() / 24., 10 * TMath::Pi() / 24., 11 * TMath::Pi() / 24., 12 * TMath::Pi() / 24.}; mh->AddMixingVariable(VarManager::kPsi2C, fPsi2C); } - if (!nameStr.compare("MedianTimeA1")) { + if (nameStr == "MedianTimeA1") { std::vector fMTLimsHashing = {-100.0f, -40.0f, -20.0f, 20.0f, 40.0f, 100.0f}; mh->AddMixingVariable(VarManager::kNTPCmedianTimeLongA, fMTLimsHashing); } - if (!nameStr.compare("MedianTimeA2")) { + if (nameStr == "MedianTimeA2") { std::vector fMTLimsHashing = {-100.0f, -80.0f, -60.0f, -40.0f, -20.0f, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f}; mh->AddMixingVariable(VarManager::kNTPCmedianTimeLongA, fMTLimsHashing); } - if (!nameStr.compare("MedianTimeA3")) { + if (nameStr == "MedianTimeA3") { std::vector fMTLimsHashing = {-100.0f, -80.0f, -60.0f, -40.0f, -30.0f, -20.0f, -10.0f, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 60.0f, 80.0f, 100.0f}; mh->AddMixingVariable(VarManager::kNTPCmedianTimeLongA, fMTLimsHashing); } - if (!nameStr.compare("PileUpA1")) { + if (nameStr == "PileUpA1") { std::vector fPileUpLimsHashing = {0.0f, 1000.0f, 2000.0f, 6000.0f, 10000.0f, 20000.0f}; mh->AddMixingVariable(VarManager::kNTPCcontribLongA, fPileUpLimsHashing); } - if (!nameStr.compare("PileUpA2")) { + if (nameStr == "PileUpA2") { std::vector fPileUpLimsHashing = {0.0f, 1000.0f, 2000.0f, 4000.0f, 6000.0f, 8000.0f, 10000.0f, 20000.0f}; mh->AddMixingVariable(VarManager::kNTPCcontribLongA, fPileUpLimsHashing); } - if (!nameStr.compare("PileUpA3")) { + if (nameStr == "PileUpA3") { std::vector fPileUpLimsHashing = {0.0f, 1000.0f, 2000.0f, 3000.0f, 4000.0f, 5000.0f, 6000.0f, 8000.0f, 10000.0f, 20000.0f}; mh->AddMixingVariable(VarManager::kNTPCcontribLongA, fPileUpLimsHashing); } - if (!nameStr.compare("PileUpA4")) { + if (nameStr == "PileUpA4") { std::vector fPileUpLimsHashing = {0.0f, 500.0f, 1000.0f, 1500.0f, 2000.0f, 2500.0f, 3000.0f, 3500.0f, 4000.0f, 4500.0f, 5000.0f, 5500.0f, 6000.0f, 8000.0f, 10000.0f, 20000.0f}; mh->AddMixingVariable(VarManager::kNTPCcontribLongA, fPileUpLimsHashing); } diff --git a/PWGDQ/Core/MuonMatchingMlResponse.h b/PWGDQ/Core/MuonMatchingMlResponse.h index 4714036ef51..584cc10b3d6 100644 --- a/PWGDQ/Core/MuonMatchingMlResponse.h +++ b/PWGDQ/Core/MuonMatchingMlResponse.h @@ -146,6 +146,7 @@ enum class InputFeaturesMFTMuonMatch : uint8_t { c1PtTglMCH, c1Pt21Pt2MCH, // track residuals + sameSign, deltaX, deltaY, deltaPhi, @@ -154,7 +155,6 @@ enum class InputFeaturesMFTMuonMatch : uint8_t { deltaPt, deltaR, deltaDirection, - sameSign, pullX, pullY, pullPhi, @@ -163,6 +163,23 @@ enum class InputFeaturesMFTMuonMatch : uint8_t { pullPt, pullR, deltaPtRel, + // track residuals (absolute values) + absDeltaX, + absDeltaY, + absDeltaPhi, + absDeltaTgl, + absDeltaEta, + absDeltaPt, + absDeltaR, + absDeltaDirection, + absPullX, + absPullY, + absPullPhi, + absPullTgl, + absPullEta, + absPullPt, + absPullR, + absDeltaPtRel, // primary vertex parameters posX, posY, @@ -320,6 +337,7 @@ class MlResponseMFTMuonMatch : public MlResponse CHECK_AND_FILL_FEATURE(c1PtTglMCH, mchprop.getCovariances()(3, 4)); CHECK_AND_FILL_FEATURE(c1Pt21Pt2MCH, mchprop.getCovariances()(4, 4)); // Track residuals + CHECK_AND_FILL_FEATURE(sameSign, (mch.sign() == mft.sign()) ? 1 : 0); CHECK_AND_FILL_FEATURE(deltaX, mchprop.getX() - mftprop.getX()); CHECK_AND_FILL_FEATURE(deltaY, mchprop.getY() - mftprop.getY()); CHECK_AND_FILL_FEATURE(deltaPhi, mchprop.getPhi() - mftprop.getPhi()); @@ -329,7 +347,6 @@ class MlResponseMFTMuonMatch : public MlResponse CHECK_AND_FILL_FEATURE(deltaR, getDeltaR(mftprop, mchprop)); CHECK_AND_FILL_FEATURE(deltaDirection, getDeltaDirection(mftprop, mchprop)); CHECK_AND_FILL_FEATURE(deltaPtRel, (mchprop.getPt() - mftprop.getPt()) / (mchprop.getPt() + mftprop.getPt())); - CHECK_AND_FILL_FEATURE(sameSign, (mch.sign() == mft.sign()) ? 1 : 0); CHECK_AND_FILL_FEATURE(pullX, getPull(mftprop.getX(), mftprop.getCovariances()(0, 0), mchprop.getX(), mchprop.getCovariances()(0, 0))); CHECK_AND_FILL_FEATURE(pullY, getPull(mftprop.getY(), mftprop.getCovariances()(1, 1), mchprop.getY(), mchprop.getCovariances()(1, 1))); CHECK_AND_FILL_FEATURE(pullPhi, getPull(mftprop.getPhi(), mftprop.getCovariances()(2, 2), mchprop.getPhi(), mchprop.getCovariances()(2, 2))); @@ -337,6 +354,23 @@ class MlResponseMFTMuonMatch : public MlResponse /*dummy value*/ CHECK_AND_FILL_FEATURE(pullEta, 0); CHECK_AND_FILL_FEATURE(pullPt, getPullPt(mftprop, mchprop)); CHECK_AND_FILL_FEATURE(pullR, getPullR(mftprop, mchprop)); + // Track residuals (absolute values) + CHECK_AND_FILL_FEATURE(absDeltaX, std::fabs(mchprop.getX() - mftprop.getX())); + CHECK_AND_FILL_FEATURE(absDeltaY, std::fabs(mchprop.getY() - mftprop.getY())); + CHECK_AND_FILL_FEATURE(absDeltaPhi, std::fabs(mchprop.getPhi() - mftprop.getPhi())); + CHECK_AND_FILL_FEATURE(absDeltaTgl, std::fabs(mchprop.getTgl() - mftprop.getTgl())); + CHECK_AND_FILL_FEATURE(absDeltaEta, std::fabs(mchprop.getEta() - mftprop.getEta())); + CHECK_AND_FILL_FEATURE(absDeltaPt, std::fabs(mchprop.getPt() - mftprop.getPt())); + CHECK_AND_FILL_FEATURE(absDeltaR, std::fabs(getDeltaR(mftprop, mchprop))); + CHECK_AND_FILL_FEATURE(absDeltaDirection, std::fabs(getDeltaDirection(mftprop, mchprop))); + CHECK_AND_FILL_FEATURE(absDeltaPtRel, std::fabs((mchprop.getPt() - mftprop.getPt()) / (mchprop.getPt() + mftprop.getPt()))); + CHECK_AND_FILL_FEATURE(absPullX, std::fabs(getPull(mftprop.getX(), mftprop.getCovariances()(0, 0), mchprop.getX(), mchprop.getCovariances()(0, 0)))); + CHECK_AND_FILL_FEATURE(absPullY, std::fabs(getPull(mftprop.getY(), mftprop.getCovariances()(1, 1), mchprop.getY(), mchprop.getCovariances()(1, 1)))); + CHECK_AND_FILL_FEATURE(absPullPhi, std::fabs(getPull(mftprop.getPhi(), mftprop.getCovariances()(2, 2), mchprop.getPhi(), mchprop.getCovariances()(2, 2)))); + CHECK_AND_FILL_FEATURE(absPullTgl, std::fabs(getPull(mftprop.getTgl(), mftprop.getCovariances()(3, 3), mchprop.getTgl(), mchprop.getCovariances()(3, 3)))); + /*dummy value*/ CHECK_AND_FILL_FEATURE(absPullEta, 0); + CHECK_AND_FILL_FEATURE(absPullPt, std::fabs(getPullPt(mftprop, mchprop))); + CHECK_AND_FILL_FEATURE(absPullR, std::fabs(getPullR(mftprop, mchprop))); // primary vertex parameters CHECK_AND_FILL_FEATURE(posX, collision.posX()); CHECK_AND_FILL_FEATURE(posY, collision.posY()); @@ -469,6 +503,7 @@ class MlResponseMFTMuonMatch : public MlResponse FILL_MAP_MFTMUON_MATCH(c1PtTglMCH), FILL_MAP_MFTMUON_MATCH(c1Pt21Pt2MCH), // track residuals + FILL_MAP_MFTMUON_MATCH(sameSign), FILL_MAP_MFTMUON_MATCH(deltaX), FILL_MAP_MFTMUON_MATCH(deltaY), FILL_MAP_MFTMUON_MATCH(deltaPhi), @@ -477,7 +512,6 @@ class MlResponseMFTMuonMatch : public MlResponse FILL_MAP_MFTMUON_MATCH(deltaPt), FILL_MAP_MFTMUON_MATCH(deltaR), FILL_MAP_MFTMUON_MATCH(deltaDirection), - FILL_MAP_MFTMUON_MATCH(sameSign), FILL_MAP_MFTMUON_MATCH(pullX), FILL_MAP_MFTMUON_MATCH(pullY), FILL_MAP_MFTMUON_MATCH(pullPhi), @@ -486,6 +520,23 @@ class MlResponseMFTMuonMatch : public MlResponse FILL_MAP_MFTMUON_MATCH(pullPt), FILL_MAP_MFTMUON_MATCH(pullR), FILL_MAP_MFTMUON_MATCH(deltaPtRel), + // track residuals (absolute values) + FILL_MAP_MFTMUON_MATCH(absDeltaX), + FILL_MAP_MFTMUON_MATCH(absDeltaY), + FILL_MAP_MFTMUON_MATCH(absDeltaPhi), + FILL_MAP_MFTMUON_MATCH(absDeltaTgl), + FILL_MAP_MFTMUON_MATCH(absDeltaEta), + FILL_MAP_MFTMUON_MATCH(absDeltaPt), + FILL_MAP_MFTMUON_MATCH(absDeltaR), + FILL_MAP_MFTMUON_MATCH(absDeltaDirection), + FILL_MAP_MFTMUON_MATCH(absPullX), + FILL_MAP_MFTMUON_MATCH(absPullY), + FILL_MAP_MFTMUON_MATCH(absPullPhi), + FILL_MAP_MFTMUON_MATCH(absPullTgl), + FILL_MAP_MFTMUON_MATCH(absPullEta), + FILL_MAP_MFTMUON_MATCH(absPullPt), + FILL_MAP_MFTMUON_MATCH(absPullR), + FILL_MAP_MFTMUON_MATCH(absDeltaPtRel), // primary vertex parameters FILL_MAP_MFTMUON_MATCH(posX), FILL_MAP_MFTMUON_MATCH(posY), diff --git a/PWGDQ/Core/PWGDQCoreLinkDef.h b/PWGDQ/Core/PWGDQCoreLinkDef.h deleted file mode 100644 index 1f6a6f33685..00000000000 --- a/PWGDQ/Core/PWGDQCoreLinkDef.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#pragma link off all globals; -#pragma link off all classes; -#pragma link off all functions; - -#pragma link C++ class VarManager + ; -#pragma link C++ class HistogramManager + ; -#pragma link C++ class MixingHandler + ; -#pragma link C++ class AnalysisCut + ; -#pragma link C++ class AnalysisCompositeCut + ; -#pragma link C++ class MCProng + ; -#pragma link C++ class MCSignal + ; diff --git a/PWGDQ/Core/VarManager.cxx b/PWGDQ/Core/VarManager.cxx index 1faf6c8731e..0ae36125960 100644 --- a/PWGDQ/Core/VarManager.cxx +++ b/PWGDQ/Core/VarManager.cxx @@ -43,8 +43,6 @@ using namespace o2::constants::physics; -ClassImp(VarManager); - TString VarManager::fgVariableNames[VarManager::kNVars] = {""}; TString VarManager::fgVariableUnits[VarManager::kNVars] = {""}; std::map VarManager::fgVarNamesMap; @@ -916,6 +914,8 @@ void VarManager::SetDefaultVarNames() fgVariableUnits[kDCAzNPeaksTrimmed2] = ""; fgVariableNames[kDCAzNPeaksTrimmed3] = "Number of peaks in binned DCAz distribution (trimmed 3)"; fgVariableUnits[kDCAzNPeaksTrimmed3] = ""; + fgVariableNames[kInteractionRate] = "Interaction rate"; + fgVariableUnits[kInteractionRate] = "kHz"; fgVariableNames[kPt] = "p_{T}"; fgVariableUnits[kPt] = "GeV/c"; fgVariableNames[kPt1] = "p_{T1}"; @@ -2196,6 +2196,7 @@ void VarManager::SetDefaultVarNames() fgVarNamesMap["kTwoR2EP1"] = kTwoR2EP1; fgVarNamesMap["kTwoR2EP2"] = kTwoR2EP2; fgVarNamesMap["kNPairsPerEvent"] = kNPairsPerEvent; + fgVarNamesMap["kInteractionRate"] = kInteractionRate; fgVarNamesMap["kNEventWiseVariables"] = kNEventWiseVariables; fgVarNamesMap["kX"] = kX; fgVarNamesMap["kY"] = kY; @@ -2484,6 +2485,12 @@ void VarManager::SetDefaultVarNames() fgVarNamesMap["kDCATrackVtxProd"] = kDCATrackVtxProd; fgVarNamesMap["kV2SP"] = kV2SP; fgVarNamesMap["kV2EP"] = kV2EP; + fgVarNamesMap["kA2EP_PP_TPC"] = kA2EP_PP_TPC; + fgVarNamesMap["kA2EP_PP_FT0A"] = kA2EP_PP_FT0A; + fgVarNamesMap["kA2EP_PP_FT0C"] = kA2EP_PP_FT0C; + fgVarNamesMap["kA2EP_RP_TPC"] = kA2EP_RP_TPC; + fgVarNamesMap["kA2EP_RP_FT0A"] = kA2EP_RP_FT0A; + fgVarNamesMap["kA2EP_RP_FT0C"] = kA2EP_RP_FT0C; fgVarNamesMap["kWV2SP"] = kWV2SP; fgVarNamesMap["kWV2EP"] = kWV2EP; fgVarNamesMap["kU2Q2"] = kU2Q2; diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index f2b48e3d71f..7079269d946 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -70,7 +71,6 @@ #include #include -#include #include #include @@ -384,6 +384,9 @@ class VarManager : public TObject kMultA, // Multiplicity of the sub-event A kMultAPOS, // Multiplicity of the sub-event A kMultANEG, // Multiplicity of the sub-event A + kMultA1, + kMultA2, + kNnorm, kMultB, kMultC, kQ3X0A, // q-vector (e.g. from TPC) with x component (harmonic 3 and power 0), sub-event A @@ -495,6 +498,7 @@ class VarManager : public TObject kTwoR2EP1, // Event plane resolution of event2 for ME technique kTwoR2EP2, // Event plane resolution of event2 for ME technique kNPairsPerEvent, // number of pairs per event in same-event or mixed-event pairing + kInteractionRate, // Variables for event mixing with cumulant kV22m, @@ -805,6 +809,30 @@ class VarManager : public TObject kDeltaPhiPair2, kDeltaEtaPair2, kPsiPair, + kDeltaPhiRP_TPC, + kDeltaPhiRP_FT0A, + kDeltaPhiRP_FT0C, + kCos2DeltaPhiRP_TPC, + kCos2DeltaPhiRP_FT0A, + kCos2DeltaPhiRP_FT0C, + kDeltaPhiPP_TPC, + kDeltaPhiPP_FT0A, + kDeltaPhiPP_FT0C, + kCos2DeltaPhiPP_TPC, + kCos2DeltaPhiPP_FT0A, + kCos2DeltaPhiPP_FT0C, + kDeltaPhiRP_Random, + kDeltaPhiRP_MC, + kCos2DeltaPhiRP_Random, + kCos2DeltaPhiRP_MC, + kDeltaPhiPP_Random, + kDeltaPhiPP_MC, + kCos2DeltaPhiPP_Random, + kCos2DeltaPhiPP_MC, + kNullA2, + kInfA2, + kSel1, // if track1 is used in TPC Q vector calculation + kSel2, // if track2 is used in TPC Q vector calculation kDeltaPhiPair, kOpeningAngle, kQuadDCAabsXY, @@ -820,6 +848,12 @@ class VarManager : public TObject kDCATrackVtxProd, kV2SP, kV2EP, + kA2EP_RP_TPC, + kA2EP_RP_FT0A, + kA2EP_RP_FT0C, + kA2EP_PP_TPC, + kA2EP_PP_FT0A, + kA2EP_PP_FT0C, kWV2SP, kWV2EP, kU2Q2, @@ -1584,8 +1618,6 @@ class VarManager : public TObject VarManager& operator=(const VarManager& c); VarManager(const VarManager& c); - - ClassDef(VarManager, 6); }; template @@ -2388,6 +2420,101 @@ void VarManager::FillEvent(T const& event, float* values) values[kWR2EP_BC_Im] = std::isnan(R2EP_BC_Im) || std::isinf(R2EP_BC_Im) ? 0. : 1.0; } + if constexpr ((fillMap & CollisionQvectCentr) > 0) { + values[kQ1X0A] = -999; + values[kQ1Y0A] = -999; + values[kQ1X0B] = -999; + values[kQ1Y0B] = -999; + values[kQ1X0C] = -999; + values[kQ1Y0C] = -999; + values[kQ2X0A] = event.qvecTPCallRe() / event.nTrkTPCall(); + values[kQ2Y0A] = event.qvecTPCallIm() / event.nTrkTPCall(); + values[kQ2X0APOS] = event.qvecTPCposRe(); + values[kQ2Y0APOS] = event.qvecTPCposIm(); + values[kQ2X0ANEG] = event.qvecTPCnegRe(); + values[kQ2Y0ANEG] = event.qvecTPCnegIm(); + values[kQ2X0B] = event.qvecFT0ARe(); + values[kQ2Y0B] = event.qvecFT0AIm(); + values[kQ2X0C] = event.qvecFT0CRe(); + values[kQ2Y0C] = event.qvecFT0CIm(); + values[kMultA] = event.nTrkTPCall(); + values[kMultAPOS] = event.nTrkTPCpos(); + values[kMultANEG] = event.nTrkTPCneg(); + values[kMultB] = event.sumAmplFT0A(); + values[kMultC] = event.sumAmplFT0C(); + values[kQ3X0A] = -999; + values[kQ3Y0A] = -999; + values[kQ3X0B] = -999; + values[kQ3Y0B] = -999; + values[kQ3X0C] = -999; + values[kQ3Y0C] = -999; + values[kQ4X0A] = -999; + values[kQ4Y0A] = -999; + values[kQ4X0B] = -999; + values[kQ4Y0B] = -999; + values[kQ4X0C] = -999; + values[kQ4Y0C] = -999; + + EventPlaneHelper epHelper; + float Psi2A = epHelper.GetEventPlane(values[kQ2X0A], values[kQ2Y0A], 2); + float Psi2APOS = epHelper.GetEventPlane(values[kQ2X0APOS], values[kQ2Y0APOS], 2); + float Psi2ANEG = epHelper.GetEventPlane(values[kQ2X0ANEG], values[kQ2Y0ANEG], 2); + float Psi2B = epHelper.GetEventPlane(values[kQ2X0B], values[kQ2Y0B], 2); + float Psi2C = epHelper.GetEventPlane(values[kQ2X0C], values[kQ2Y0C], 2); + + values[kPsi2A] = Psi2A; + values[kPsi2APOS] = Psi2APOS; + values[kPsi2ANEG] = Psi2ANEG; + values[kPsi2B] = Psi2B; + values[kPsi2C] = Psi2C; + + float R2SP_AB = (values[kQ2X0A] * values[kQ2X0B] + values[kQ2Y0A] * values[kQ2Y0B]); + float R2SP_APOSB = (values[kQ2X0APOS] * values[kQ2X0B] + values[kQ2Y0APOS] * values[kQ2Y0B]); + float R2SP_ANEGB = (values[kQ2X0ANEG] * values[kQ2X0B] + values[kQ2Y0ANEG] * values[kQ2Y0B]); + float R2SP_AC = (values[kQ2X0A] * values[kQ2X0C] + values[kQ2Y0A] * values[kQ2Y0C]); + float R2SP_APOSC = (values[kQ2X0APOS] * values[kQ2X0C] + values[kQ2Y0APOS] * values[kQ2Y0C]); + float R2SP_ANEGC = (values[kQ2X0ANEG] * values[kQ2X0C] + values[kQ2Y0ANEG] * values[kQ2Y0C]); + float R2SP_BC = (values[kQ2X0B] * values[kQ2X0C] + values[kQ2Y0B] * values[kQ2Y0C]); + float R2SP_AB_Im = (values[kQ2Y0A] * values[kQ2X0B] - values[kQ2X0A] * values[kQ2Y0B]); + float R2SP_AC_Im = (values[kQ2Y0A] * values[kQ2X0C] - values[kQ2X0A] * values[kQ2Y0C]); + float R2SP_BC_Im = (values[kQ2Y0B] * values[kQ2X0C] - values[kQ2X0B] * values[kQ2Y0C]); + values[kR2SP_AB] = std::isnan(R2SP_AB) || std::isinf(R2SP_AB) ? 0. : R2SP_AB; + values[kR2SP_FT0CTPCPOS] = std::isnan(R2SP_APOSB) || std::isinf(R2SP_APOSB) ? 0. : R2SP_APOSB; + values[kR2SP_FT0CTPCNEG] = std::isnan(R2SP_ANEGB) || std::isinf(R2SP_ANEGB) ? 0. : R2SP_ANEGB; + values[kWR2SP_AB] = std::isnan(R2SP_AB) || std::isinf(R2SP_AB) ? 0. : 1.0; + values[kR2SP_AC] = std::isnan(R2SP_AC) || std::isinf(R2SP_AC) ? 0. : R2SP_AC; + values[kR2SP_FT0ATPCPOS] = std::isnan(R2SP_APOSC) || std::isinf(R2SP_APOSC) ? 0. : R2SP_APOSC; + values[kR2SP_FT0ATPCNEG] = std::isnan(R2SP_ANEGC) || std::isinf(R2SP_ANEGC) ? 0. : R2SP_ANEGC; + values[kWR2SP_AC] = std::isnan(R2SP_AC) || std::isinf(R2SP_AC) ? 0. : 1.0; + values[kR2SP_BC] = std::isnan(R2SP_BC) || std::isinf(R2SP_BC) ? 0. : R2SP_BC; + values[kWR2SP_BC] = std::isnan(R2SP_BC) || std::isinf(R2SP_BC) ? 0. : 1.0; + values[kR2SP_AB_Im] = std::isnan(R2SP_AB_Im) || std::isinf(R2SP_AB_Im) ? 0. : R2SP_AB_Im; + values[kWR2SP_AB_Im] = std::isnan(R2SP_AB_Im) || std::isinf(R2SP_AB_Im) ? 0. : 1.0; + values[kR2SP_AC_Im] = std::isnan(R2SP_AC_Im) || std::isinf(R2SP_AC_Im) ? 0. : R2SP_AC_Im; + values[kWR2SP_AC_Im] = std::isnan(R2SP_AC_Im) || std::isinf(R2SP_AC_Im) ? 0. : 1.0; + values[kR2SP_BC_Im] = std::isnan(R2SP_BC_Im) || std::isinf(R2SP_BC_Im) ? 0. : R2SP_BC_Im; + values[kWR2SP_BC_Im] = std::isnan(R2SP_BC_Im) || std::isinf(R2SP_BC_Im) ? 0. : 1.0; + + float R2EP_AB = std::isnan(Psi2A) || std::isinf(Psi2A) || std::isnan(Psi2B) || std::isinf(Psi2B) ? 0. : TMath::Cos(2 * (Psi2A - Psi2B)); + float R2EP_AC = std::isnan(Psi2A) || std::isinf(Psi2A) || std::isnan(Psi2C) || std::isinf(Psi2C) ? 0. : TMath::Cos(2 * (Psi2A - Psi2C)); + float R2EP_BC = std::isnan(Psi2B) || std::isinf(Psi2B) || std::isnan(Psi2C) || std::isinf(Psi2C) ? 0. : TMath::Cos(2 * (Psi2B - Psi2C)); + float R2EP_AB_Im = std::isnan(Psi2A) || std::isinf(Psi2A) || std::isnan(Psi2B) || std::isinf(Psi2B) ? 0. : TMath::Sin(2 * (Psi2A - Psi2B)); + float R2EP_AC_Im = std::isnan(Psi2A) || std::isinf(Psi2A) || std::isnan(Psi2C) || std::isinf(Psi2C) ? 0. : TMath::Sin(2 * (Psi2A - Psi2C)); + float R2EP_BC_Im = std::isnan(Psi2B) || std::isinf(Psi2B) || std::isnan(Psi2C) || std::isinf(Psi2C) ? 0. : TMath::Sin(2 * (Psi2B - Psi2C)); + values[kR2EP_AB] = std::isnan(R2EP_AB) || std::isinf(R2EP_AB) ? 0. : R2EP_AB; + values[kWR2EP_AB] = std::isnan(R2EP_AB) || std::isinf(R2EP_AB) ? 0. : 1.0; + values[kR2EP_AC] = std::isnan(R2EP_AC) || std::isinf(R2EP_AC) ? 0. : R2EP_AC; + values[kWR2EP_AC] = std::isnan(R2EP_AC) || std::isinf(R2EP_AC) ? 0. : 1.0; + values[kR2EP_BC] = std::isnan(R2EP_BC) || std::isinf(R2EP_BC) ? 0. : R2EP_BC; + values[kWR2EP_BC] = std::isnan(R2EP_BC) || std::isinf(R2EP_BC) ? 0. : 1.0; + values[kR2EP_AB_Im] = std::isnan(R2EP_AB_Im) || std::isinf(R2EP_AB_Im) ? 0. : R2EP_AB_Im; + values[kWR2EP_AB_Im] = std::isnan(R2EP_AB_Im) || std::isinf(R2EP_AB_Im) ? 0. : 1.0; + values[kR2EP_AC_Im] = std::isnan(R2EP_AC_Im) || std::isinf(R2EP_AC_Im) ? 0. : R2EP_AC_Im; + values[kWR2EP_AC_Im] = std::isnan(R2EP_AC_Im) || std::isinf(R2EP_AC_Im) ? 0. : 1.0; + values[kR2EP_BC_Im] = std::isnan(R2EP_BC_Im) || std::isinf(R2EP_BC_Im) ? 0. : R2EP_BC_Im; + values[kWR2EP_BC_Im] = std::isnan(R2EP_BC_Im) || std::isinf(R2EP_BC_Im) ? 0. : 1.0; + } + if constexpr ((fillMap & CollisionMC) > 0) { values[kMCEventGeneratorId] = event.generatorsID(); values[kMCEventSubGeneratorId] = event.getSubGeneratorId(); @@ -2983,6 +3110,9 @@ void VarManager::FillTrack(T const& track, float* values) values[kITSncls] += ((track.itsClusterMap() & (1 << i)) ? 1 : 0); } } + if (fgUsedVars[kTPCnCRoverFindCls]) { + values[kTPCnCRoverFindCls] = values[kTPCnclsCR] / values[kTPCncls]; + } values[kTrackDCAxy] = track.dcaXY(); values[kTrackDCAz] = track.dcaZ(); if constexpr ((fillMap & ReducedTrackBarrelCov) > 0) { @@ -4327,6 +4457,26 @@ void VarManager::FillPairMEAcrossTFs(T const& t1, T const& t2, float* values) values[kEta] = v12.Eta(); values[kPhi] = v12.Phi() > 0 ? v12.Phi() : v12.Phi() + 2. * M_PI; values[kRap] = -v12.Rapidity(); + + if (fgUsedVars[kCosThetaStarRandom] || fgUsedVars[kCosThetaStarFT0C]) { + ROOT::Math::Boost boostv12{v12.BoostToCM()}; + ROOT::Math::XYZVectorF v_CM{(boostv12(v1).Vect()).Unit()}; + + if (fgUsedVars[kCosThetaStarRandom]) { + // Randomize the event plane angle to check the unpolarized contribution + ROOT::Math::XYZVector zaxisRandom = ROOT::Math::XYZVector(TMath::Cos(values[kRandomPsi2]), TMath::Sin(values[kRandomPsi2]), 0).Unit(); + values[kCosThetaStarRandom] = v_CM.Dot(zaxisRandom); + values[kCos2ThetaStarRandom] = values[kCosThetaStarRandom] * values[kCosThetaStarRandom]; + } + + if (fgUsedVars[kCosThetaStarFT0C]) { + // event plane angle from FT0C + ROOT::Math::XYZVector zaxisFT0C = ROOT::Math::XYZVector(TMath::Cos(values[kPsi2C]), TMath::Sin(values[kPsi2C]), 0).Unit(); + values[kCosThetaStarFT0C] = v_CM.Dot(zaxisFT0C); + values[kAbsCosThetaStarFT0C] = std::abs(values[kCosThetaStarFT0C]); + values[kCos2ThetaStarFT0C] = values[kCosThetaStarFT0C] * values[kCosThetaStarFT0C]; + } + } } template @@ -4509,6 +4659,23 @@ void VarManager::FillPairMC(T1 const& t1, T2 const& t2, float* values) ROOT::Math::XYZVector zaxisTrue = ROOT::Math::XYZVector(TMath::Cos(values[kMCEventPlaneAngle]), TMath::Sin(values[kMCEventPlaneAngle]), 0).Unit(); values[kMCCosThetaStar] = v_CM.Dot(zaxisTrue); } + + if (fgUsedVars[kCos2DeltaPhiRP_Random] || fgUsedVars[kCos2DeltaPhiPP_Random] || fgUsedVars[kCos2DeltaPhiRP_MC] || fgUsedVars[kCos2DeltaPhiPP_MC]) { + ROOT::Math::Boost boostv12{v12.BoostToCM()}; + ROOT::Math::PtEtaPhiMVector v_daughter = boostv12(t1.pdgCode() > 0 ? v1 : v2); + + // reaction plane + float phi = v_daughter.Phi() > TMath::Pi() ? v_daughter.Phi() - 2. * TMath::Pi() : v_daughter.Phi(); + values[kDeltaPhiRP_Random] = phi - values[kRandomPsi2]; + values[kDeltaPhiRP_Random] = values[kDeltaPhiRP_Random] > TMath::Pi() ? 2. * TMath::Pi() - values[kDeltaPhiRP_Random] : values[kDeltaPhiRP_Random]; + values[kDeltaPhiRP_MC] = phi - values[kMCEventPlaneAngle]; + values[kDeltaPhiRP_MC] = values[kDeltaPhiRP_MC] > TMath::Pi() ? 2. * TMath::Pi() - values[kDeltaPhiRP_MC] : values[kDeltaPhiRP_MC]; + // fold delta phi into [-pi/2, pi/2] + values[kDeltaPhiRP_Random] = values[kDeltaPhiRP_Random] > TMath::Pi() / 2. ? TMath::Pi() - values[kDeltaPhiRP_Random] : values[kDeltaPhiRP_Random]; + values[kDeltaPhiRP_MC] = values[kDeltaPhiRP_MC] > TMath::Pi() / 2. ? TMath::Pi() - values[kDeltaPhiRP_MC] : values[kDeltaPhiRP_MC]; + values[kCos2DeltaPhiRP_Random] = TMath::Cos(2. * (phi - values[kRandomPsi2])); + values[kCos2DeltaPhiRP_MC] = TMath::Cos(2. * (phi - values[kMCEventPlaneAngle])); + } } template @@ -5945,6 +6112,116 @@ void VarManager::FillPairVn(T1 const& t1, T2 const& t2, float* values) values[kCos2ThetaStarFT0C] = values[kCosThetaStarFT0C] * values[kCosThetaStarFT0C]; } + // Coherent Jpsi A2 + bool useCoherentJpsiA2 = fgUsedVars[kA2EP_RP_TPC] || fgUsedVars[kA2EP_RP_FT0A] || fgUsedVars[kA2EP_RP_FT0C] || fgUsedVars[kA2EP_PP_TPC] || fgUsedVars[kA2EP_PP_FT0A] || fgUsedVars[kA2EP_PP_FT0C]; + if (useCoherentJpsiA2) { + // remove daughter from TPC Q-vector + // TODO: remove based on track cut in qVectorTable + float Q2X0A = values[kQ2X0A] * values[kMultA]; + float Q2Y0A = values[kQ2Y0A] * values[kMultA]; + float nNorm = values[kMultA]; + + // checkTrack(t1); + if (values[kSel1] > 0) { + float qx1 = t1.pt() * TMath::Cos(2. * t1.phi()); + float qy1 = t1.pt() * TMath::Sin(2. * t1.phi()); + Q2X0A = Q2X0A - qx1; + Q2Y0A = Q2Y0A - qy1; + nNorm = nNorm - 1.; + } + // checkTrack(t2); + if (values[kSel2] > 0) { + float qx2 = t2.pt() * TMath::Cos(2. * t2.phi()); + float qy2 = t2.pt() * TMath::Sin(2. * t2.phi()); + Q2X0A = Q2X0A - qx2; + Q2Y0A = Q2Y0A - qy2; + nNorm = nNorm - 1.; + } + values[kNnorm] = nNorm; + if (nNorm <= 0) { + values[kQ2X0A] = -999.; + values[kQ2Y0A] = -999.; + return; + } + + Q2X0A = nNorm > 0 ? Q2X0A / nNorm : NAN; + Q2Y0A = nNorm > 0 ? Q2Y0A / nNorm : NAN; + + float Psi2A = getEventPlane(2, Q2X0A, Q2Y0A); + values[kPsi2A] = Psi2A; + + // pT ~ 0.2, non-relativistic + // ROOT::Math::PtEtaPhiMVector v_daughter = t1.sign() > 0 ? v1 - v2 : v2 - v1; + // boost to Jpsi rest frame, then calculate the angle with respect to the event plane + ROOT::Math::Boost boostv12{v12.BoostToCM()}; + ROOT::Math::PtEtaPhiMVector v_daughter = boostv12(t1.sign() > 0 ? v1 : v2); + + // production plane + ROOT::Math::XYZVectorF zAxis_RF{(v12.Vect()).Unit()}; + ROOT::Math::XYZVectorF zAxis{fgBeamA.Vect().Unit()}; + ROOT::Math::XYZVectorF yAxis_RF = zAxis_RF.Cross(zAxis).Unit(); + ROOT::Math::XYZVectorF xAxis_RF = yAxis_RF.Cross(zAxis_RF).Unit(); + ROOT::Math::XYZVectorF daughterVec_RF{(v_daughter.Vect()).Unit()}; + ROOT::Math::XYZVectorF b_TPC_RF = ROOT::Math::XYZVectorF(std::cos(Psi2A), std::sin(Psi2A), 0.f); + ROOT::Math::XYZVectorF b_FT0A_RF = ROOT::Math::XYZVectorF(std::cos(Psi2B), std::sin(Psi2B), 0.f); + ROOT::Math::XYZVectorF b_FT0C_RF = ROOT::Math::XYZVectorF(std::cos(Psi2C), std::sin(Psi2C), 0.f); + float cosPhi = yAxis_RF.Dot(zAxis_RF.Cross(daughterVec_RF)); + float sinPhi = -1. * xAxis_RF.Dot(zAxis_RF.Cross(daughterVec_RF)); + float phi_PP = sinPhi > 0 ? TMath::ACos(cosPhi) : -1. * TMath::ACos(cosPhi); + float cosPsi2APP = b_TPC_RF.Dot(xAxis_RF.Cross(daughterVec_RF)); + float sinPsi2APP = b_TPC_RF.Dot(yAxis_RF.Cross(daughterVec_RF)); + float Psi2APP = sinPsi2APP > 0 ? TMath::ACos(cosPsi2APP) : -1. * TMath::ACos(cosPsi2APP); + float cosPsi2BPP = b_FT0A_RF.Dot(xAxis_RF.Cross(daughterVec_RF)); + float sinPsi2BPP = b_FT0A_RF.Dot(yAxis_RF.Cross(daughterVec_RF)); + float Psi2BPP = sinPsi2BPP > 0 ? TMath::ACos(cosPsi2BPP) : -1. * TMath::ACos(cosPsi2BPP); + float cosPsi2CPP = b_FT0C_RF.Dot(xAxis_RF.Cross(daughterVec_RF)); + float sinPsi2CPP = b_FT0C_RF.Dot(yAxis_RF.Cross(daughterVec_RF)); + float Psi2CPP = sinPsi2CPP > 0 ? TMath::ACos(cosPsi2CPP) : -1. * TMath::ACos(cosPsi2CPP); + values[kDeltaPhiPP_TPC] = phi_PP > Psi2APP ? phi_PP - Psi2APP : Psi2APP - phi_PP; + values[kDeltaPhiPP_TPC] = values[kDeltaPhiPP_TPC] > TMath::Pi() ? 2. * TMath::Pi() - values[kDeltaPhiPP_TPC] : values[kDeltaPhiPP_TPC]; + values[kDeltaPhiPP_FT0A] = phi_PP > Psi2BPP ? phi_PP - Psi2BPP : Psi2BPP - phi_PP; + values[kDeltaPhiPP_FT0A] = values[kDeltaPhiPP_FT0A] > TMath::Pi() ? 2. * TMath::Pi() - values[kDeltaPhiPP_FT0A] : values[kDeltaPhiPP_FT0A]; + values[kDeltaPhiPP_FT0C] = phi_PP > Psi2CPP ? phi_PP - Psi2CPP : Psi2CPP - phi_PP; + values[kDeltaPhiPP_FT0C] = values[kDeltaPhiPP_FT0C] > TMath::Pi() ? 2. * TMath::Pi() - values[kDeltaPhiPP_FT0C] : values[kDeltaPhiPP_FT0C]; + // fold delta phi to [0, pi/2] + values[kDeltaPhiPP_TPC] = values[kDeltaPhiPP_TPC] > TMath::Pi() / 2. ? TMath::Pi() - values[kDeltaPhiPP_TPC] : values[kDeltaPhiPP_TPC]; + values[kDeltaPhiPP_FT0A] = values[kDeltaPhiPP_FT0A] > TMath::Pi() / 2. ? TMath::Pi() - values[kDeltaPhiPP_FT0A] : values[kDeltaPhiPP_FT0A]; + values[kDeltaPhiPP_FT0C] = values[kDeltaPhiPP_FT0C] > TMath::Pi() / 2. ? TMath::Pi() - values[kDeltaPhiPP_FT0C] : values[kDeltaPhiPP_FT0C]; + values[kCos2DeltaPhiPP_TPC] = TMath::Cos(2. * (phi_PP - Psi2A)); + values[kCos2DeltaPhiPP_FT0A] = TMath::Cos(2. * (phi_PP - Psi2B)); + values[kCos2DeltaPhiPP_FT0C] = TMath::Cos(2. * (phi_PP - Psi2C)); + + float A2PP_TPC = values[kCos2DeltaPhiPP_TPC] / values[kR2EP]; + float A2PP_FT0A = values[kCos2DeltaPhiPP_FT0A] / values[kR2EP]; + float A2PP_FT0C = values[kCos2DeltaPhiPP_FT0C] / values[kR2EP]; + values[kA2EP_PP_TPC] = std::isnan(A2PP_TPC) || std::isinf(A2PP_TPC) ? -999. : A2PP_TPC; + values[kA2EP_PP_FT0A] = std::isnan(A2PP_FT0A) || std::isinf(A2PP_FT0A) ? -999. : A2PP_FT0A; + values[kA2EP_PP_FT0C] = std::isnan(A2PP_FT0C) || std::isinf(A2PP_FT0C) ? -999. : A2PP_FT0C; + + // reaction plane + float phi = v_daughter.Phi() > TMath::Pi() ? 2. * TMath::Pi() - v_daughter.Phi() : v_daughter.Phi(); + values[kDeltaPhiRP_TPC] = phi > Psi2A ? phi - Psi2A : Psi2A - phi; + values[kDeltaPhiRP_TPC] = values[kDeltaPhiRP_TPC] > TMath::Pi() ? 2. * TMath::Pi() - values[kDeltaPhiRP_TPC] : values[kDeltaPhiRP_TPC]; + values[kDeltaPhiRP_FT0A] = phi > Psi2B ? phi - Psi2B : Psi2B - phi; + values[kDeltaPhiRP_FT0A] = values[kDeltaPhiRP_FT0A] > TMath::Pi() ? 2. * TMath::Pi() - values[kDeltaPhiRP_FT0A] : values[kDeltaPhiRP_FT0A]; + values[kDeltaPhiRP_FT0C] = phi > Psi2C ? phi - Psi2C : Psi2C - phi; + values[kDeltaPhiRP_FT0C] = values[kDeltaPhiRP_FT0C] > TMath::Pi() ? 2. * TMath::Pi() - values[kDeltaPhiRP_FT0C] : values[kDeltaPhiRP_FT0C]; + // fold delta phi to [0, pi/2] + values[kDeltaPhiRP_TPC] = values[kDeltaPhiRP_TPC] > TMath::Pi() / 2. ? TMath::Pi() - values[kDeltaPhiRP_TPC] : values[kDeltaPhiRP_TPC]; + values[kDeltaPhiRP_FT0A] = values[kDeltaPhiRP_FT0A] > TMath::Pi() / 2. ? TMath::Pi() - values[kDeltaPhiRP_FT0A] : values[kDeltaPhiRP_FT0A]; + values[kDeltaPhiRP_FT0C] = values[kDeltaPhiRP_FT0C] > TMath::Pi() / 2. ? TMath::Pi() - values[kDeltaPhiRP_FT0C] : values[kDeltaPhiRP_FT0C]; + values[kCos2DeltaPhiRP_TPC] = TMath::Cos(2. * (phi - Psi2A)); + values[kCos2DeltaPhiRP_FT0A] = TMath::Cos(2. * (phi - Psi2B)); + values[kCos2DeltaPhiRP_FT0C] = TMath::Cos(2. * (phi - Psi2C)); + + float A2RP_TPC = values[kCos2DeltaPhiRP_TPC] / values[kR2EP]; + float A2RP_FT0A = values[kCos2DeltaPhiRP_FT0A] / values[kR2EP]; + float A2RP_FT0C = values[kCos2DeltaPhiRP_FT0C] / values[kR2EP]; + values[kA2EP_RP_TPC] = std::isnan(A2RP_TPC) || std::isinf(A2RP_TPC) ? -999. : A2RP_TPC; + values[kA2EP_RP_FT0A] = std::isnan(A2RP_FT0A) || std::isinf(A2RP_FT0A) ? -999. : A2RP_FT0A; + values[kA2EP_RP_FT0C] = std::isnan(A2RP_FT0C) || std::isinf(A2RP_FT0C) ? -999. : A2RP_FT0C; + } + // kV4, kC4POI, kC4REF etc. if constexpr ((fillMap & ReducedEventQvectorExtra) > 0) { std::complex Q21(values[kQ2X0A] * values[kS11A], values[kQ2Y0A] * values[kS11A]); @@ -6790,6 +7067,7 @@ float VarManager::LorentzTransformJpsihadroncosChi(TString Option, T1 const& v1, } return value; } + template void VarManager::FillFIT(T1 const& bc, T2 const& bcs, T3 const& ft0s, T4 const& fv0as, T5 const& fdds, float* values) { diff --git a/PWGDQ/DataModel/ReducedInfoTables.h b/PWGDQ/DataModel/ReducedInfoTables.h index be60adab101..781942d5fe7 100644 --- a/PWGDQ/DataModel/ReducedInfoTables.h +++ b/PWGDQ/DataModel/ReducedInfoTables.h @@ -826,6 +826,9 @@ DECLARE_SOA_COLUMN(PairDCAxyz, pairDCAxyz, float); DECLARE_SOA_COLUMN(PairDCAxy, pairDCAxy, float); //! Pair DCAxy to PV from KFParticle DECLARE_SOA_COLUMN(DeviationPairKF, deviationPairKF, float); //! Pair chi2 deviation to PV from KFParticle DECLARE_SOA_COLUMN(DeviationxyPairKF, deviationxyPairKF, float); //! Pair chi2 deviation to PV in XY from KFParticle +DECLARE_SOA_COLUMN(BdtBackground, bdtBackground, float); //! BDT output score for the background class +DECLARE_SOA_COLUMN(BdtPrompt, bdtPrompt, float); //! BDT output score for the prompt class +DECLARE_SOA_COLUMN(BdtNonprompt, bdtNonprompt, float); //! BDT output score for the nonprompt class // DECLARE_SOA_INDEX_COLUMN(ReducedMuon, reducedmuon2); //! DECLARE_SOA_COLUMN(CosThetaHE, costhetaHE, float); //! Cosine in the helicity frame DECLARE_SOA_COLUMN(PhiHE, phiHe, float); //! Phi in the helicity frame @@ -936,6 +939,12 @@ DECLARE_SOA_TABLE_STAGED(DielectronsAll, "RTDIELECTRONALL", //! reducedpair::Lz, reducedpair::Lxy); +DECLARE_SOA_TABLE_STAGED(DielectronsMls, "RTDIELECTRONML", //! + reducedpair::CentFT0C, + reducedpair::BdtBackground, + reducedpair::BdtPrompt, + reducedpair::BdtNonprompt); + DECLARE_SOA_TABLE(DimuonsAll, "AOD", "RTDIMUONALL", //! collision::PosX, collision::PosY, collision::PosZ, collision::NumContrib, evsel::Selection, reducedpair::EventSelection, @@ -1010,6 +1019,7 @@ using DimuonExtra = DimuonsExtra::iterator; using DileptonFlow = DileptonsFlow::iterator; using DileptonInfo = DileptonsInfo::iterator; using DielectronAll = DielectronsAll::iterator; +using DielectronMl = DielectronsMls::iterator; using DimuonAll = DimuonsAll::iterator; using DileptonMiniTree = DileptonsMiniTree::iterator; using DileptonMiniTreeGen = DileptonsMiniTreeGen::iterator; diff --git a/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx b/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx index ab35ad8b31f..620de63de2f 100644 --- a/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx +++ b/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -64,9 +65,9 @@ #include +#include #include #include -#include #include #include #include @@ -74,9 +75,6 @@ #include #include -using std::cout; -using std::endl; - using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -134,6 +132,14 @@ constexpr static uint32_t gkMuonRealignFillMapWithCov = VarManager::ObjTypes::Mu constexpr static uint32_t gkMFTFillMap = VarManager::ObjTypes::TrackMFT; constexpr static uint32_t gkMFTCovFillMap = VarManager::ObjTypes::TrackMFT | VarManager::ObjTypes::MFTCov; +namespace dqtablemakermc_helpers +{ +inline float* varValues() { return static_cast(VarManager::fgValues); } +inline TString* varNames() { return static_cast(VarManager::fgVariableNames); } +inline TString* varUnits() { return static_cast(VarManager::fgVariableUnits); } +} // namespace dqtablemakermc_helpers + +/* template void PrintBitMap(TMap map, int nbits) { @@ -141,6 +147,7 @@ void PrintBitMap(TMap map, int nbits) cout << ((map & (TMap(1) << i)) > 0 ? "1" : "0"); } } +*/ struct TableMakerMC { @@ -177,7 +184,7 @@ struct TableMakerMC { OutputObj fOutputList{"output"}; OutputObj fStatsList{"Statistics"}; //! skimming statistics - HistogramManager* fHistMan; + HistogramManager* fHistMan = nullptr; Configurable fIsRun2{"cfgIsRun2", false, "Whether we analyze Run-2 or Run-3 data"}; @@ -250,18 +257,18 @@ struct TableMakerMC { Configurable> fModelNames{"cfgModelNames", std::vector{"model.onnx"}, "ONNX file names for each pT bin (if not from CCDB full path)"}; } fConfigVariousOptions; - Service fCCDB; + Service fCCDB{}; o2::ccdb::CcdbApi fCCDBApi; o2::parameters::GRPObject* fGrpMagRun2 = nullptr; // for run 2, we access the GRPObject from GLO/GRP/GRP o2::parameters::GRPMagField* fGrpMag = nullptr; // for run 3, we access GRPMagField from GLO/Config/GRPMagField - AnalysisCompositeCut* fEventCut; //! Event selection cut + AnalysisCompositeCut* fEventCut = nullptr; //! Event selection cut std::vector fTrackCuts; //! Barrel track cuts std::vector fMuonCuts; //! Muon track cuts bool fDoDetailedQA = false; // Bool to set detailed QA true, if QA is set true - int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. + int fCurrentRun = -1; // needed to detect if the run changed and trigger update of calibrations etc. // list of MCsignal objects std::vector fMCSignals; @@ -280,7 +287,7 @@ struct TableMakerMC { o2::analysis::MlResponseMFTMuonMatch matchingMlResponse; std::vector binsPtMl; - std::array cutValues; + std::array cutValues{}; std::vector cutDirMl; // RCT flag checker @@ -334,7 +341,7 @@ struct TableMakerMC { fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(kTRUE); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqtablemakermc_helpers::varNames(), dqtablemakermc_helpers::varUnits()); // Only use detailed QA when QA is set true if (fConfigHistOutput.fConfigQA && fConfigHistOutput.fConfigDetailedQA) { @@ -360,7 +367,7 @@ struct TableMakerMC { } // Barrel track histograms after cuts; one directory per cut if (fConfigHistOutput.fConfigQA) { - for (auto& cut : fTrackCuts) { + for (const auto& cut : fTrackCuts) { histClasses += Form("TrackBarrel_%s;", cut->GetName()); } } @@ -373,7 +380,7 @@ struct TableMakerMC { } // Muon track histograms after cuts; one directory per cut if (fConfigHistOutput.fConfigQA) { - for (auto& muonCut : fMuonCuts) { + for (const auto& muonCut : fMuonCuts) { histClasses += Form("Muons_%s;", muonCut->GetName()); } } @@ -386,7 +393,7 @@ struct TableMakerMC { // loop over MC signals and add them to the signals array for (int isig = 0; isig < objArray->GetEntries(); ++isig) { MCSignal* sig = o2::aod::dqmcsignals::GetMCSignal(objArray->At(isig)->GetName()); - if (sig) { + if (sig != nullptr) { fMCSignals.push_back(sig); } } @@ -395,27 +402,27 @@ struct TableMakerMC { TString addMCSignalsStr = fConfigMCSignalsJSON.value; if (addMCSignalsStr != "") { std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); - for (auto& mcIt : addMCSignals) { - if (mcIt) { + for (const auto& mcIt : addMCSignals) { + if (mcIt != nullptr) { fMCSignals.push_back(mcIt); } } } - for (auto& mcIt : fMCSignals) { + for (const auto& mcIt : fMCSignals) { if (fConfigHistOutput.fConfigQA) { histClasses += Form("MCTruth_%s;", mcIt->GetName()); } if (fDoDetailedQA) { if (isBarrelEnabled) { // in case of detailed QA, setup histogram directories for each combination of reconstructed track cuts and MC signals - for (auto& cut : fTrackCuts) { + for (const auto& cut : fTrackCuts) { histClasses += Form("TrackBarrel_%s_%s;", cut->GetName(), mcIt->GetName()); } } if (isMuonEnabled) { // in case of detailed QA, setup histogram directories for each combination of reconstructed muon cuts and MC signals - for (auto& cut : fMuonCuts) { + for (const auto& cut : fMuonCuts) { histClasses += Form("Muons_%s_%s;", cut->GetName(), mcIt->GetName()); } } @@ -469,7 +476,7 @@ struct TableMakerMC { TString addEvCutsStr = fConfigCuts.fConfigEventCutsJSON.value; if (addEvCutsStr != "") { std::vector addEvCuts = dqcuts::GetCutsFromJSON(addEvCutsStr.Data()); - for (auto& cutIt : addEvCuts) { + for (const auto& cutIt : addEvCuts) { fEventCut->AddCut(cutIt); } } @@ -486,8 +493,8 @@ struct TableMakerMC { TString addTrackCutsStr = fConfigCuts.fConfigTrackCutsJSON.value; if (addTrackCutsStr != "") { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); - for (auto& t : addTrackCuts) { - fTrackCuts.push_back(reinterpret_cast(t)); + for (const auto& t : addTrackCuts) { + fTrackCuts.push_back(dynamic_cast(t)); } } @@ -503,8 +510,8 @@ struct TableMakerMC { TString addMuonCutsStr = fConfigCuts.fConfigMuonCutsJSON.value; if (addMuonCutsStr != "") { std::vector addMuonCuts = dqcuts::GetCutsFromJSON(addMuonCutsStr.Data()); - for (auto& t : addMuonCuts) { - fMuonCuts.push_back(reinterpret_cast(t)); + for (const auto& t : addMuonCuts) { + fMuonCuts.push_back(dynamic_cast(t)); } } @@ -525,11 +532,11 @@ struct TableMakerMC { VarManager::ResetValues(0, VarManager::kNVars); // Loop over MC collisions - for (auto& mcCollision : mcCollisions) { + for (const auto& mcCollision : mcCollisions) { // Get MC collision information into the VarManager VarManager::FillEvent(mcCollision); // Fill histograms - fHistMan->FillHistClass("Event_MCTruth", VarManager::fgValues); + fHistMan->FillHistClass("Event_MCTruth", dqtablemakermc_helpers::varValues()); // Create the skimmed table entry for this collision eventMC(mcCollision.generatorsID(), mcCollision.posX(), mcCollision.posY(), mcCollision.posZ(), mcCollision.t(), mcCollision.weight(), mcCollision.impactParameter(), mcCollision.bestCollisionCentFT0C(), @@ -549,14 +556,14 @@ struct TableMakerMC { fLabelsMapReversed.clear(); fMCFlags.clear(); - uint16_t mcflags = static_cast(0); // flags which will hold the decisions for each MC signal + auto mcflags = static_cast(0); // flags which will hold the decisions for each MC signal int trackCounter = 0; - for (auto& mctrack : mcTracks) { + for (const auto& mctrack : mcTracks) { // check all the requested MC signals and fill the decision bit map mcflags = 0; int i = 0; - for (auto& sig : fMCSignals) { + for (const auto& sig : fMCSignals) { bool checked = false; if constexpr (soa::is_soa_filtered_v) { auto mctrack_raw = mcTracks.rawIteratorAt(mctrack.globalIndex()); @@ -580,7 +587,7 @@ struct TableMakerMC { PrintBitMap(mcflags, 16); cout << endl; if (mctrack.has_mothers()) { - for (auto& m : mctrack.mothersIds()) { + for (const auto& m : mctrack.mothersIds()) { if (m < mcTracks.size()) { // protect against bad mother indices auto aMother = mcTracks.rawIteratorAt(m); cout << "<<<<<< mother idx / pdg: " << m << " / " << aMother.pdgCode() << endl; @@ -605,7 +612,7 @@ struct TableMakerMC { } // If this MC track was not already added to the map, add it now - if (fLabelsMap.find(mctrack.globalIndex()) == fLabelsMap.end()) { + if (!fLabelsMap.contains(mctrack.globalIndex())) { fLabelsMap[mctrack.globalIndex()] = trackCounter; fLabelsMapReversed[trackCounter] = mctrack.globalIndex(); fMCFlags[mctrack.globalIndex()] = mcflags; @@ -618,8 +625,8 @@ struct TableMakerMC { VarManager::FillEvent(mcCollision); int j = 0; for (auto signal = fMCSignals.begin(); signal != fMCSignals.end(); signal++, j++) { - if (mcflags & (static_cast(1) << j)) { - fHistMan->FillHistClass(Form("MCTruth_%s", (*signal)->GetName()), VarManager::fgValues); + if ((mcflags & (static_cast(1) << j)) != 0) { + fHistMan->FillHistClass(Form("MCTruth_%s", (*signal)->GetName()), dqtablemakermc_helpers::varValues()); } } } @@ -721,14 +728,14 @@ struct TableMakerMC { // Fill the stats event histogram with the event selection bits for (int i = 0; i < o2::aod::evsel::kNsel; i++) { if (collision.selection_bit(i)) { - (reinterpret_cast(fStatsList->At(0)))->Fill(1.0, static_cast(i)); + (dynamic_cast(fStatsList->At(0)))->Fill(1.0, static_cast(i)); } } - (reinterpret_cast(fStatsList->At(0)))->Fill(1.0, static_cast(o2::aod::evsel::kNsel)); + (dynamic_cast(fStatsList->At(0)))->Fill(1.0, static_cast(o2::aod::evsel::kNsel)); auto bc = collision.template bc_as(); // store the selection decisions - uint64_t tag = static_cast(0); + auto tag = static_cast(0); // store some more information in the tag // if the BC found by event selection does not coincide with the collision.bc(), toggle the first bit auto bcEvSel = collision.template foundBC_as(); @@ -749,32 +756,32 @@ struct TableMakerMC { VarManager::FillEvent(mcCollision); } if (fDoDetailedQA) { - fHistMan->FillHistClass("Event_BeforeCuts", VarManager::fgValues); + fHistMan->FillHistClass("Event_BeforeCuts", dqtablemakermc_helpers::varValues()); } // fill stats information, before selections for (int i = 0; i < o2::aod::evsel::kNsel; i++) { if (collision.selection_bit(i)) { - (reinterpret_cast(fStatsList->At(0)))->Fill(2.0, static_cast(i)); + (dynamic_cast(fStatsList->At(0)))->Fill(2.0, static_cast(i)); } } - (reinterpret_cast(fStatsList->At(0)))->Fill(2.0, static_cast(o2::aod::evsel::kNsel)); + (dynamic_cast(fStatsList->At(0)))->Fill(2.0, static_cast(o2::aod::evsel::kNsel)); // Apply the user specified event selection - if (!fEventCut->IsSelected(VarManager::fgValues) || (fConfigRCT.fConfigUseRCT.value && !(rctChecker(collision)))) { + if (!fEventCut->IsSelected(dqtablemakermc_helpers::varValues()) || (fConfigRCT.fConfigUseRCT.value && !(rctChecker(collision)))) { continue; } // fill stats information, after selections for (int i = 0; i < o2::aod::evsel::kNsel; i++) { if (collision.selection_bit(i)) { - (reinterpret_cast(fStatsList->At(0)))->Fill(3.0, static_cast(i)); + (dynamic_cast(fStatsList->At(0)))->Fill(3.0, static_cast(i)); } } - (reinterpret_cast(fStatsList->At(0)))->Fill(3.0, static_cast(o2::aod::evsel::kNsel)); + (dynamic_cast(fStatsList->At(0)))->Fill(3.0, static_cast(o2::aod::evsel::kNsel)); // Fill historams after event cuts - fHistMan->FillHistClass("Event_AfterCuts", VarManager::fgValues); + fHistMan->FillHistClass("Event_AfterCuts", dqtablemakermc_helpers::varValues()); // create the event tables event(tag, bc.runNumber(), collision.posX(), collision.posY(), collision.posZ(), collision.numContrib(), collision.collisionTime(), collision.collisionTimeRes()); @@ -836,9 +843,9 @@ struct TableMakerMC { // so in case of multiple associations, the variables depending on the collision association (e.g. DCA, secondary vertexing, etc) // have to be recomputed at analysis time for each association. - uint64_t trackFilteringTag = static_cast(0); - uint32_t trackTempFilterMap = static_cast(0); - uint16_t mcflags = static_cast(0); + uint64_t trackFilteringTag{0}; + uint32_t trackTempFilterMap{0}; + uint16_t mcflags{0}; int trackCounter = fLabelsMap.size(); // Loop over associations @@ -861,18 +868,18 @@ struct TableMakerMC { VarManager::FillTrackCollision(track, collision); } if (fDoDetailedQA) { - fHistMan->FillHistClass("TrackBarrel_BeforeCuts", VarManager::fgValues); + fHistMan->FillHistClass("TrackBarrel_BeforeCuts", dqtablemakermc_helpers::varValues()); } // apply track cuts and fill histograms int i = 0; for (auto cut = fTrackCuts.begin(); cut != fTrackCuts.end(); cut++, i++) { - if ((*cut)->IsSelected(VarManager::fgValues)) { + if ((*cut)->IsSelected(dqtablemakermc_helpers::varValues())) { trackTempFilterMap |= (static_cast(1) << i); if (fConfigHistOutput.fConfigQA) { - fHistMan->FillHistClass(Form("TrackBarrel_%s", (*cut)->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("TrackBarrel_%s", (*cut)->GetName()), dqtablemakermc_helpers::varValues()); } - (reinterpret_cast(fStatsList->At(1)))->Fill(static_cast(i)); + (dynamic_cast(fStatsList->At(1)))->Fill(static_cast(i)); } } if (!trackTempFilterMap) { @@ -891,7 +898,7 @@ struct TableMakerMC { trackFilteringTag |= static_cast(track.pidbit()); for (int iv0 = 0; iv0 < 5; iv0++) { if (track.pidbit() & (uint8_t(1) << iv0)) { - (reinterpret_cast(fStatsList->At(1)))->Fill(fTrackCuts.size() + static_cast(iv0)); + (dynamic_cast(fStatsList->At(1)))->Fill(fTrackCuts.size() + static_cast(iv0)); } } } // end if V0Bits @@ -939,24 +946,24 @@ struct TableMakerMC { VarManager::FillTrackMC(mcTracks, mctrack); mcflags = 0; - int i = 0; // runs over the MC signals + int isig = 0; // runs over the MC signals int j = 0; // runs over the track cuts // check all the specified signals and fill histograms for MC truth matched tracks - for (auto& sig : fMCSignals) { + for (const auto& sig : fMCSignals) { if (sig->CheckSignal(true, mctrack)) { - mcflags |= (static_cast(1) << i); + mcflags |= (static_cast(1) << isig); // If detailed QA is on, fill histograms for each MC signal and track cut combination if (fDoDetailedQA) { j = 0; - for (auto& cut : fTrackCuts) { + for (const auto& cut : fTrackCuts) { if (trackTempFilterMap & (uint8_t(1) << j)) { - fHistMan->FillHistClass(Form("TrackBarrel_%s_%s", cut->GetName(), sig->GetName()), VarManager::fgValues); // fill the reconstructed truth + fHistMan->FillHistClass(Form("TrackBarrel_%s_%s", cut->GetName(), sig->GetName()), dqtablemakermc_helpers::varValues()); // fill the reconstructed truth } j++; } } } - i++; + isig++; } // if the MC truth particle corresponding to this reconstructed track is not already written, @@ -979,7 +986,7 @@ struct TableMakerMC { { // Skim MFT tracks // So far no cuts are applied here - uint16_t mcflags = static_cast(0); + auto mcflags = static_cast(0); int trackCounter = fLabelsMap.size(); for (const auto& assoc : mftAssocs) { @@ -987,7 +994,7 @@ struct TableMakerMC { if (fConfigHistOutput.fConfigQA) { VarManager::FillTrack(track); - fHistMan->FillHistClass("MftTracks", VarManager::fgValues); + fHistMan->FillHistClass("MftTracks", dqtablemakermc_helpers::varValues()); } // write the MFT track global index in the map for skimming (to make sure we have it just once) @@ -1007,12 +1014,12 @@ struct TableMakerMC { mcflags = 0; int i = 0; // runs over the MC signals // check all the specified signals and fill histograms for MC truth matched tracks - for (auto& sig : fMCSignals) { + for (const auto& sig : fMCSignals) { if (sig->CheckSignal(true, mctrack)) { mcflags |= (static_cast(1) << i); // If detailed QA is on, fill histograms for each MC signal and track cut combination if (fDoDetailedQA) { - fHistMan->FillHistClass(Form("MFTTrack_%s", sig->GetName()), VarManager::fgValues); // fill the reconstructed truth + fHistMan->FillHistClass(Form("MFTTrack_%s", sig->GetName()), dqtablemakermc_helpers::varValues()); // fill the reconstructed truth } } i++; @@ -1050,7 +1057,7 @@ struct TableMakerMC { } } } - for (auto& pairCand : mCandidates) { + for (const auto& pairCand : mCandidates) { fBestMatch[pairCand.second.second] = true; } } @@ -1084,7 +1091,7 @@ struct TableMakerMC { } } } - for (auto& pairCand : mCandidates) { + for (const auto& pairCand : mCandidates) { fBestMatch[pairCand.second.second] = true; } } @@ -1096,10 +1103,10 @@ struct TableMakerMC { // Loop over the collision-track associations, recompute track properties depending on the collision assigned, and apply track cuts for selection // Muons are written only once, even if they constribute to more than one association, // which means that in the case of multiple associations, the track parameters are wrong and should be computed again at analysis time. - uint8_t trackFilteringTag = static_cast(0); - uint8_t trackTempFilterMap = static_cast(0); + auto trackFilteringTag = static_cast(0); + auto trackTempFilterMap = static_cast(0); fFwdTrackIndexMapReversed.clear(); - uint16_t mcflags = static_cast(0); + auto mcflags = static_cast(0); int trackCounter = fLabelsMap.size(); uint32_t offset = muonBasic.lastIndex(); @@ -1148,17 +1155,17 @@ struct TableMakerMC { } if (fDoDetailedQA) { - fHistMan->FillHistClass("Muons_BeforeCuts", VarManager::fgValues); + fHistMan->FillHistClass("Muons_BeforeCuts", dqtablemakermc_helpers::varValues()); } // check the cuts and fill histograms for each fulfilled cut int i = 0; for (auto cut = fMuonCuts.begin(); cut != fMuonCuts.end(); cut++, i++) { - if ((*cut)->IsSelected(VarManager::fgValues)) { + if ((*cut)->IsSelected(dqtablemakermc_helpers::varValues())) { trackTempFilterMap |= (uint8_t(1) << i); if (fConfigHistOutput.fConfigQA) { - fHistMan->FillHistClass(Form("Muons_%s", (*cut)->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("Muons_%s", (*cut)->GetName()), dqtablemakermc_helpers::varValues()); } - (reinterpret_cast(fStatsList->At(2)))->Fill(static_cast(i)); + (dynamic_cast(fStatsList->At(2)))->Fill(static_cast(i)); } } @@ -1186,23 +1193,23 @@ struct TableMakerMC { VarManager::FillTrackMC(mcTracks, mctrack); mcflags = 0; - int i = 0; // runs over the MC signals + int isig = 0; // runs over the MC signals int j = 0; // runs over the track cuts // check all the specified signals and fill histograms for MC truth matched tracks - for (auto& sig : fMCSignals) { + for (const auto& sig : fMCSignals) { if (sig->CheckSignal(true, mctrack)) { - mcflags |= (static_cast(1) << i); + mcflags |= (static_cast(1) << isig); if (fDoDetailedQA) { j = 0; - for (auto& cut : fMuonCuts) { + for (const auto& cut : fMuonCuts) { if (trackTempFilterMap & (uint8_t(1) << j)) { - fHistMan->FillHistClass(Form("Muons_%s_%s", cut->GetName(), sig->GetName()), VarManager::fgValues); // fill the reconstructed truth + fHistMan->FillHistClass(Form("Muons_%s_%s", cut->GetName(), sig->GetName()), dqtablemakermc_helpers::varValues()); // fill the reconstructed truth } j++; } } // end if do detailed QA } - i++; + isig++; } // end loop over MC signals // if the MC truth particle corresponding to this reconstructed muon is not already written, @@ -1305,7 +1312,7 @@ struct TableMakerMC { { // Check whether the run changed and update CCDB if it did if (bcs.size() > 0 && fCurrentRun != bcs.begin().runNumber()) { - if (fIsRun2 == true) { + if (fIsRun2) { fGrpMagRun2 = fCCDB->getForTimeStamp(fConfigCCDB.fGrpMagPathRun2, bcs.begin().timestamp()); if (fGrpMagRun2 != nullptr) { o2::base::Propagator::initFieldFromGRP(fGrpMagRun2); @@ -1350,7 +1357,7 @@ struct TableMakerMC { eventMClabels.reserve(collisions.size()); eventInfo.reserve(collisions.size()); skimCollisions(collisions, bcs); - if (fCollIndexMap.size() == 0) { + if (fCollIndexMap.empty()) { return; } @@ -1368,7 +1375,7 @@ struct TableMakerMC { trackBarrel.reserve(tracksBarrel.size()); trackBarrelCov.reserve(tracksBarrel.size()); trackBarrelPID.reserve(tracksBarrel.size()); - trackBarrelAssoc.reserve(tracksBarrel.size()); + trackBarrelAssoc.reserve(trackAssocs.size()); trackBarrelLabels.reserve(tracksBarrel.size()); } @@ -1378,7 +1385,7 @@ struct TableMakerMC { map_mfttrackcovs.clear(); mftTrack.reserve(mftTracks.size()); mftTrackExtra.reserve(mftTracks.size()); - mftAssoc.reserve(mftTracks.size()); + mftAssoc.reserve(mftAssocs.size()); mftLabels.reserve(mftTracks.size()); } @@ -1390,18 +1397,18 @@ struct TableMakerMC { muonBasic.reserve(muons.size()); muonExtra.reserve(muons.size()); muonCov.reserve(muons.size()); - muonAssoc.reserve(muons.size()); + muonAssoc.reserve(fwdTrackAssocs.size()); muonLabels.reserve(muons.size()); } if constexpr (static_cast(TMFTFillMap & VarManager::ObjTypes::MFTCov)) { - for (auto& mfttrackConv : mftCovs) { + for (const auto& mfttrackConv : mftCovs) { map_mfttrackcovs[mfttrackConv.matchMFTTrackId()] = mfttrackConv.globalIndex(); } } // loop over selected collisions and select the tracks and fwd tracks to be skimmed - if (fCollIndexMap.size() > 0) { + if (!fCollIndexMap.empty()) { for (auto const& [origIdx, skimIdx] : fCollIndexMap) { auto collision = collisions.rawIteratorAt(origIdx); // group the tracks and muons for this collision @@ -1445,14 +1452,14 @@ struct TableMakerMC { std::vector mothers; if (mctrack.has_mothers()) { - for (auto& m : mctrack.mothersIds()) { + for (const auto& m : mctrack.mothersIds()) { if (m < mcParticles.size()) { // protect against bad mother indices - if (fLabelsMap.find(m) != fLabelsMap.end()) { + if (fLabelsMap.contains(m)) { mothers.push_back(fLabelsMap.find(m)->second); } } else { - cout << "Mother label (" << m << ") exceeds the McParticles size (" << mcParticles.size() << ")" << endl; - cout << " Check the MC generator" << endl; + LOG(warn) << "Mother label (" << m << ") exceeds the McParticles size (" << mcParticles.size() << ")"; + LOG(warn) << "Check the MC generator"; } } } @@ -1464,17 +1471,17 @@ struct TableMakerMC { for (int d = mctrack.daughtersIds()[0]; d <= mctrack.daughtersIds()[1]; ++d) { // TODO: remove this check as soon as issues with MC production are fixed if (d < mcParticles.size()) { // protect against bad daughter indices - if (fLabelsMap.find(d) != fLabelsMap.end()) { + if (fLabelsMap.contains(d)) { daughters.push_back(fLabelsMap.find(d)->second); } } else { - cout << "Daughter label (" << d << ") exceeds the McParticles size (" << mcParticles.size() << ")" << endl; - cout << " Check the MC generator" << endl; + LOG(warn) << "Daughter label (" << d << ") exceeds the McParticles size (" << mcParticles.size() << ")"; + LOG(warn) << "Check the MC generator"; } } } - int daughterRange[2] = {-1, -1}; - if (daughters.size() > 0) { + std::array daughterRange{-1, -1}; + if (!daughters.empty()) { daughterRange[0] = daughters[0]; daughterRange[1] = daughters[daughters.size() - 1]; } @@ -1482,24 +1489,24 @@ struct TableMakerMC { // NOTE: Here we assume that MC collisions are not filtered, so there is no new vs old index map for translation auto mcCollision = mctrack.template mcCollision_as(); trackMC(mcCollision.globalIndex(), mctrack.pdgCode(), mctrack.statusCode(), mctrack.flags(), - mothers, daughterRange, + mothers, daughterRange.data(), mctrack.weight(), mctrack.pt(), mctrack.eta(), mctrack.phi(), mctrack.e(), mctrack.vx(), mctrack.vy(), mctrack.vz(), mctrack.vt(), mcflags); for (unsigned int isig = 0; isig < fMCSignals.size(); isig++) { if (mcflags & (static_cast(1) << isig)) { - (reinterpret_cast(fStatsList->At(3)))->Fill(static_cast(isig)); + (dynamic_cast(fStatsList->At(3)))->Fill(static_cast(isig)); } } if (mcflags == 0) { - (reinterpret_cast(fStatsList->At(3)))->Fill(static_cast(fMCSignals.size())); + (dynamic_cast(fStatsList->At(3)))->Fill(static_cast(fMCSignals.size())); } } // end loop over labels } - void DefineHistograms(TString histClasses) + void DefineHistograms(const TString& histClasses) { std::unique_ptr objArray(histClasses.Tokenize(";")); - for (Int_t iclass = 0; iclass < objArray->GetEntries(); ++iclass) { + for (int iclass = 0; iclass < objArray->GetEntries(); ++iclass) { TString classStr = objArray->At(iclass)->GetName(); if (fConfigHistOutput.fConfigQA) { fHistMan->AddHistClass(classStr.Data()); @@ -1545,21 +1552,21 @@ struct TableMakerMC { for (auto label = eventLabels.begin(); label != eventLabels.end(); label++, ib++) { histEvents->GetXaxis()->SetBinLabel(ib, (*label).Data()); } - for (int ib = 1; ib <= o2::aod::evsel::kNsel; ib++) { - histEvents->GetYaxis()->SetBinLabel(ib, o2::aod::evsel::selectionLabels[ib - 1]); + for (int iy = 1; iy <= o2::aod::evsel::kNsel; iy++) { + histEvents->GetYaxis()->SetBinLabel(iy, o2::aod::evsel::selectionLabels[iy - 1]); } histEvents->GetYaxis()->SetBinLabel(o2::aod::evsel::kNsel + 1, "Total"); fStatsList->Add(histEvents); // Track statistics: one bin for each track selection and 5 bins for V0 tags (gamma, K0s, Lambda, anti-Lambda, Omega) - TH1I* histTracks = new TH1I("TrackStats", "Track statistics", fTrackCuts.size() + 5.0, -0.5, fTrackCuts.size() - 0.5 + 5.0); + TH1I* histTracks = new TH1I("TrackStats", "Track statistics", fTrackCuts.size() + 5, -0.5, fTrackCuts.size() - 0.5 + 5.0); ib = 1; for (auto cut = fTrackCuts.begin(); cut != fTrackCuts.end(); cut++, ib++) { histTracks->GetXaxis()->SetBinLabel(ib, (*cut)->GetName()); } - const char* v0TagNames[5] = {"Photon conversion", "K^{0}_{s}", "#Lambda", "#bar{#Lambda}", "#Omega"}; - for (int ib = 0; ib < 5; ib++) { - histTracks->GetXaxis()->SetBinLabel(fTrackCuts.size() + 1 + ib, v0TagNames[ib]); + constexpr std::array v0TagNames = {"Photon conversion", "K^{0}_{s}", "#Lambda", "#bar{#Lambda}", "#Omega"}; + for (int iv0 = 0; iv0 < 5; iv0++) { + histTracks->GetXaxis()->SetBinLabel(fTrackCuts.size() + 1 + iv0, v0TagNames[iv0]); } fStatsList->Add(histTracks); TH1I* histMuons = new TH1I("MuonStats", "Muon statistics", fMuonCuts.size(), -0.5, fMuonCuts.size() - 0.5); @@ -1655,7 +1662,7 @@ struct TableMakerMC { { fullSkimming(collisions, bcs, nullptr, tracksMuon, mftTracks, nullptr, fwdTrackAssocs, mftAssocs, mcCollisions, mcParticles, nullptr); /*LOGP(info, "---------------------------"); - for (auto& mcCollision : mcCollisions) { + for (const auto& mcCollision : mcCollisions) { LOGP(info, "Gen. FT0C centrality = {}", mcCollision.bestCollisionCentFT0C()); //LOGP(info, "Gen. FT0C centrality = {}", mcCollision.posZ()); } @@ -1684,11 +1691,11 @@ struct TableMakerMC { void processOnlyBCs(soa::Join::iterator const& bc) { for (int i = 0; i < o2::aod::evsel::kNsel; i++) { - if (bc.alias_bit(i) > 0) { - (reinterpret_cast(fStatsList->At(0)))->Fill(0.0, static_cast(i)); + if (static_cast(bc.alias_bit(i)) > 0) { + (dynamic_cast(fStatsList->At(0)))->Fill(0.0, static_cast(i)); } } - (reinterpret_cast(fStatsList->At(0)))->Fill(0.0, static_cast(o2::aod::evsel::kNsel)); + (dynamic_cast(fStatsList->At(0)))->Fill(0.0, static_cast(o2::aod::evsel::kNsel)); } PROCESS_SWITCH(TableMakerMC, processPP, "Produce both barrel and muon skims, pp settings", false); diff --git a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx index 87010bdb21a..32749d294bf 100644 --- a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx +++ b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx @@ -92,8 +92,6 @@ using namespace o2::framework::expressions; using namespace o2::aod; using namespace o2::aod::rctsel; -Zorro zorro; - // Declaration of various Joins used in the different process functions // TODO: Since DCA depends on which collision the track is associated to, we should remove writing and subscribing to DCA tables, to optimize on CPU / memory using MyBarrelTracks = soa::Join(VarManager::fgValues); } +inline TString* varNames() { return static_cast(VarManager::fgVariableNames); } +inline TString* varUnits() { return static_cast(VarManager::fgVariableUnits); } +} // namespace dqtablemaker_helpers + struct TableMaker { - Produces event; - Produces eventExtended; - Produces eventVtxCov; - Produces eventInfo; - Produces zdc; - Produces fit; - Produces multPV; - Produces multAll; - Produces mergingTable; - Produces trackBarrelInfo; - Produces trackBasic; - Produces trackBarrel; - Produces trackBarrelCov; - Produces trackBarrelPID; - Produces trackBarrelAssoc; - Produces muonBasic; - Produces muonExtra; - Produces muonCov; - Produces muonInfo; - Produces muonAssoc; - Produces mftTrack; - Produces mftTrackExtra; - Produces mftAssoc; - - // Q-vector related tables, to be filled only if the user selects the corresponding option; since they are not needed for the skimming, we keep them in a separate group to avoid filling them when not needed struct : ProducesGroup { + Produces event; + Produces eventExtended; + Produces eventVtxCov; + Produces eventInfo; + Produces zdc; + Produces fit; + Produces multPV; + Produces multAll; + Produces mergingTable; + Produces trackBarrelInfo; + Produces trackBasic; + Produces trackBarrel; + Produces trackBarrelCov; + Produces trackBarrelPID; + Produces trackBarrelAssoc; + Produces muonBasic; + Produces muonExtra; + Produces muonCov; + Produces muonInfo; + Produces muonAssoc; + Produces mftTrack; + Produces mftTrackExtra; + Produces mftAssoc; + // Q-vector related tables, to be filled only if the user selects the corresponding option Produces eventQvectorCentr; Produces eventQvectorCentrExtra; - } qvecGroup; + } outTables; OutputObj fOutputList{"output"}; //! the histogram manager output list OutputObj fStatsList{"Statistics"}; //! skimming statistics - HistogramManager* fHistMan; + HistogramManager* fHistMan = nullptr; // Event and track AnalysisCut configurables struct : ConfigurableGroup { @@ -321,18 +325,18 @@ struct TableMaker { Configurable fExcludeShort{"cfgTPCExcludeShort", true, "Exclude short term from long term occupancy (micro-seconds)"}; } fConfigVariousOptions; - Service fCCDB; + Service fCCDB{}; o2::ccdb::CcdbApi fCCDBApi; o2::parameters::GRPObject* fGrpMagRun2 = nullptr; // for run 2, we access the GRPObject from GLO/GRP/GRP o2::parameters::GRPMagField* fGrpMag = nullptr; // for run 3, we access GRPMagField from GLO/Config/GRPMagField - AnalysisCompositeCut* fEventCut; //! Event selection cut + AnalysisCompositeCut* fEventCut = nullptr; //! Event selection cut std::vector fTrackCuts; //! Barrel track cuts std::vector fMuonCuts; //! Muon track cuts bool fDoDetailedQA = false; // Bool to set detailed QA true, if QA is set true - int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. + int fCurrentRun = -1; // needed to detect if the run changed and trigger update of calibrations etc. // maps used to store index info; NOTE: std::map are sorted in ascending order by default (needed for track to collision indices) std::map fCollIndexMap; // key: old collision index, value: skimmed collision index @@ -347,7 +351,7 @@ struct TableMaker { o2::analysis::MlResponseMFTMuonMatch matchingMlResponse; std::vector binsPtMl; - std::array cutValues; + std::array cutValues{}; std::vector cutDirMl; // RCT flag checker @@ -385,6 +389,7 @@ struct TableMaker { Partition tracksNegWithCov = (((aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor)) && (aod::track::tgl < static_cast(-0.05))); ctpRateFetcher mRateFetcher; + Zorro zorro; parameters::GRPLHCIFData* mLHCIFdata = nullptr; struct { @@ -455,7 +460,7 @@ struct TableMaker { // Initialize the histogram manager fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(kTRUE); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqtablemaker_helpers::varNames(), dqtablemaker_helpers::varUnits()); // Only use detailed QA when QA is set true if (fConfigHistOutput.fConfigQA && fConfigHistOutput.fConfigDetailedQA) { @@ -482,7 +487,7 @@ struct TableMaker { context.mOptions.get("processPbPbWithFilterBarrelOnly") || context.mOptions.get("processPPBarrelOnlyWithV0s") || context.mOptions.get("processPbPbBarrelOnlyNoTOF"); bool enableMuonHistos = (context.mOptions.get("processPP") || context.mOptions.get("processPPWithFilter") || context.mOptions.get("processPPWithFilterMuonOnly") || context.mOptions.get("processPPWithFilterMuonMFT") || context.mOptions.get("processPPMuonOnly") || context.mOptions.get("processPPRealignedMuonOnly") || context.mOptions.get("processPPMuonMFT") || context.mOptions.get("processPPMuonMFTWithMultsExtra") || - context.mOptions.get("processPbPb") || context.mOptions.get("processPbPbMuonOnly") || context.mOptions.get("processPbPbStreamMuonOnly") || context.mOptions.get("processPbPbRealignedMuonOnly") || context.mOptions.get("processPbPbMuonMFT")); + context.mOptions.get("processPbPb") || context.mOptions.get("processPbPbMuonOnly") || context.mOptions.get("processPbPbWithFilterMuonOnly") || context.mOptions.get("processPbPbStreamMuonOnly") || context.mOptions.get("processPbPbRealignedMuonOnly") || context.mOptions.get("processPbPbMuonMFT")); if (enableBarrelHistos) { // Barrel track histograms, before selections @@ -491,7 +496,7 @@ struct TableMaker { } if (fConfigHistOutput.fConfigQA) { // Barrel track histograms after selections; one histogram directory for each user specified selection - for (auto& cut : fTrackCuts) { + for (const auto& cut : fTrackCuts) { histClasses += Form("TrackBarrel_%s;", cut->GetName()); } } @@ -510,7 +515,7 @@ struct TableMaker { } if (fConfigHistOutput.fConfigQA) { // Muon tracks after selections; one directory per selection - for (auto& muonCut : fMuonCuts) { + for (const auto& muonCut : fMuonCuts) { histClasses += Form("Muons_%s;", muonCut->GetName()); } } @@ -556,7 +561,7 @@ struct TableMaker { TString addEvCutsStr = fConfigCuts.fConfigEventCutsJSON.value; if (addEvCutsStr != "") { std::vector addEvCuts = dqcuts::GetCutsFromJSON(addEvCutsStr.Data()); - for (auto& cutIt : addEvCuts) { + for (const auto& cutIt : addEvCuts) { fEventCut->AddCut(cutIt); } } @@ -573,8 +578,8 @@ struct TableMaker { TString addTrackCutsStr = fConfigCuts.fConfigTrackCutsJSON.value; if (addTrackCutsStr != "") { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); - for (auto& t : addTrackCuts) { - fTrackCuts.push_back(reinterpret_cast(t)); + for (const auto& t : addTrackCuts) { + fTrackCuts.push_back(dynamic_cast(t)); } } @@ -590,19 +595,19 @@ struct TableMaker { TString addMuonCutsStr = fConfigCuts.fConfigMuonCutsJSON.value; if (addMuonCutsStr != "") { std::vector addMuonCuts = dqcuts::GetCutsFromJSON(addMuonCutsStr.Data()); - for (auto& t : addMuonCuts) { - fMuonCuts.push_back(reinterpret_cast(t)); + for (const auto& t : addMuonCuts) { + fMuonCuts.push_back(dynamic_cast(t)); } } VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill } - void DefineHistograms(TString histClasses) + void DefineHistograms(const TString& histClasses) { // Create histograms via HistogramManager std::unique_ptr objArray(histClasses.Tokenize(";")); - for (Int_t iclass = 0; iclass < objArray->GetEntries(); ++iclass) { + for (int iclass = 0; iclass < objArray->GetEntries(); ++iclass) { TString classStr = objArray->At(iclass)->GetName(); if (fConfigHistOutput.fConfigQA) { fHistMan->AddHistClass(classStr.Data()); @@ -666,8 +671,8 @@ struct TableMaker { for (auto label = eventLabels.begin(); label != eventLabels.end(); label++, ib++) { histEvents->GetXaxis()->SetBinLabel(ib, (*label).Data()); } - for (int ib = 1; ib <= o2::aod::evsel::kNsel; ib++) { - histEvents->GetYaxis()->SetBinLabel(ib, o2::aod::evsel::selectionLabels[ib - 1]); + for (int iy = 1; iy <= o2::aod::evsel::kNsel; iy++) { + histEvents->GetYaxis()->SetBinLabel(iy, o2::aod::evsel::selectionLabels[iy - 1]); } histEvents->GetYaxis()->SetBinLabel(o2::aod::evsel::kNsel + 1, "Total"); fStatsList->AddAt(histEvents, kStatsEvent); @@ -681,13 +686,13 @@ struct TableMaker { fStatsList->AddAt(histBcs, kStatsBcs); // Track statistics: one bin for each track selection and 5 bins for V0 tags (gamma, K0s, Lambda, anti-Lambda, Omega) - TH1D* histTracks = new TH1D("TrackStats", "Track statistics", fTrackCuts.size() + 5.0, -0.5, fTrackCuts.size() - 0.5 + 5.0); + TH1D* histTracks = new TH1D("TrackStats", "Track statistics", fTrackCuts.size() + 5, -0.5, fTrackCuts.size() - 0.5 + 5.0); ib = 1; for (auto cut = fTrackCuts.begin(); cut != fTrackCuts.end(); cut++, ib++) { histTracks->GetXaxis()->SetBinLabel(ib, (*cut)->GetName()); } - const char* v0TagNames[5] = {"Photon conversion", "K^{0}_{s}", "#Lambda", "#bar{#Lambda}", "#Omega"}; - for (ib = 0; ib < 5; ib++) { + constexpr std::array v0TagNames{"Photon conversion", "K^{0}_{s}", "#Lambda", "#bar{#Lambda}", "#Omega"}; + for (ib = 0; ib < static_cast(v0TagNames.size()); ib++) { histTracks->GetXaxis()->SetBinLabel(fTrackCuts.size() + 1 + ib, v0TagNames[ib]); } fStatsList->AddAt(histTracks, kStatsTracks); @@ -712,7 +717,7 @@ struct TableMaker { } template - void computeOccupancyEstimators(TEvents const& collisions, Partition const& tracksPos, Partition const& tracksNeg, Preslice& preslice, TBCs const&) + void computeOccupancyEstimators(TEvents const& collisions, Partition const& tracksPosPart, Partition const& tracksNegPart, Preslice& presliceTracks, TBCs const&) { // clear the occupancy maps for this time frame @@ -751,7 +756,7 @@ struct TableMaker { oVtxZ[collision.globalIndex()] = collision.posZ(); // if more than one collision per bunch, add that collision to the list for that bunch - if (oBCreversed.find(bc) == oBCreversed.end()) { + if (!oBCreversed.contains(bc)) { std::vector evs = {collision.globalIndex()}; oBCreversed[bc] = evs; } else { @@ -760,8 +765,8 @@ struct TableMaker { } // make a slice for this collision and get the number of tracks - auto thisCollTrackPos = tracksPos.sliceBy(preslice, collision.globalIndex()); - auto thisCollTrackNeg = tracksNeg.sliceBy(preslice, collision.globalIndex()); + auto thisCollTrackPos = tracksPosPart.sliceBy(presliceTracks, collision.globalIndex()); + auto thisCollTrackNeg = tracksNegPart.sliceBy(presliceTracks, collision.globalIndex()); collMultPos[collision.globalIndex()] = thisCollTrackPos.size(); collMultNeg[collision.globalIndex()] = thisCollTrackNeg.size(); } @@ -795,7 +800,7 @@ struct TableMaker { // check if this collision is also within the short time range bool isShort = (thisBC >= pastShortBC && thisBC < futureShortBC); // loop over all collisions in this BC - for (auto& thisColl : colls) { + for (const auto& thisColl : colls) { // skip if this is the same collision if (thisColl == collision) { continue; @@ -841,8 +846,8 @@ struct TableMaker { // iterate over the time maps to obtain the median time fOccup.oMedianTimeLongA[collision] = 0.0; float sumMult = 0.0; - if (oTimeMapLongA.size() > 0) { - for (auto& [dt, mult] : oTimeMapLongA) { + if (!oTimeMapLongA.empty()) { + for (const auto& [dt, mult] : oTimeMapLongA) { sumMult += mult; if (sumMult > fOccup.oContribLongA[collision] / 2.0) { fOccup.oMedianTimeLongA[collision] = dt; @@ -852,8 +857,8 @@ struct TableMaker { } fOccup.oMedianTimeLongC[collision] = 0.0; sumMult = 0.0; - if (oTimeMapLongC.size() > 0) { - for (auto& [dt, mult] : oTimeMapLongC) { + if (!oTimeMapLongC.empty()) { + for (const auto& [dt, mult] : oTimeMapLongC) { sumMult += mult; if (sumMult > fOccup.oContribLongC[collision] / 2.0) { fOccup.oMedianTimeLongC[collision] = dt; @@ -863,8 +868,8 @@ struct TableMaker { } fOccup.oMedianTimeShortA[collision] = 0.0; sumMult = 0.0; - if (oTimeMapShortA.size() > 0) { - for (auto& [dt, mult] : oTimeMapShortA) { + if (!oTimeMapShortA.empty()) { + for (const auto& [dt, mult] : oTimeMapShortA) { sumMult += mult; if (sumMult > fOccup.oContribShortA[collision] / 2.0) { fOccup.oMedianTimeShortA[collision] = dt; @@ -874,8 +879,8 @@ struct TableMaker { } fOccup.oMedianTimeShortC[collision] = 0.0; sumMult = 0.0; - if (oTimeMapShortC.size() > 0) { - for (auto& [dt, mult] : oTimeMapShortC) { + if (!oTimeMapShortC.empty()) { + for (const auto& [dt, mult] : oTimeMapShortC) { sumMult += mult; if (sumMult > fOccup.oContribShortC[collision] / 2.0) { fOccup.oMedianTimeShortC[collision] = dt; @@ -893,12 +898,9 @@ struct TableMaker { auto bfilling = mLHCIFdata->getBunchFilling(); double nbc = bfilling.getFilledBCs().size(); - double tvxRate; - if (fConfigHistOutput.fConfigIrEstimator.value.empty()) { - tvxRate = mRateFetcher.fetch(fCCDB.service, timeStamp, bc.runNumber(), "T0VTX"); - } else { - tvxRate = mRateFetcher.fetch(fCCDB.service, timeStamp, bc.runNumber(), fConfigHistOutput.fConfigIrEstimator.value); - } + const double tvxRate = fConfigHistOutput.fConfigIrEstimator.value.empty() + ? mRateFetcher.fetch(fCCDB.service, timeStamp, bc.runNumber(), "T0VTX") + : mRateFetcher.fetch(fCCDB.service, timeStamp, bc.runNumber(), fConfigHistOutput.fConfigIrEstimator.value); double nTriggersPerFilledBC = tvxRate / nbc / o2::constants::lhc::LHCRevFreq; double mu = -std::log(1 - nTriggersPerFilledBC); @@ -906,7 +908,7 @@ struct TableMaker { } template - void computeCollMergingTag(TEvents const& collisions, TTracks const& tracks, Preslice& preslice) + void computeCollMergingTag(TEvents const& collisions, TTracks const& tracks, Preslice& presliceTracks) { // This function uses the standard track-collision association to compute quantities related to collision merging // clear the maps for this time frame @@ -939,7 +941,7 @@ struct TableMaker { for (const auto& collision : collisions) { // make a slice for this collision and compute the DCAz based event quantities - auto thisCollTracks = tracks.sliceBy(preslice, collision.globalIndex()); + auto thisCollTracks = tracks.sliceBy(presliceTracks, collision.globalIndex()); VarManager::FillEventTracks(thisCollTracks); // fill the VarManager arrays with the information of the tracks associated to this collision, needed for the cuts and histograms // add the computed variables to the maps with the collision index as key fCollMergingTag.bimodalityCoeffDCAz[collision.globalIndex()] = VarManager::fgValues[VarManager::kDCAzBimodalityCoefficient]; @@ -1012,22 +1014,22 @@ struct TableMaker { bool isTriggerZNA = bc.selection_bit(aod::evsel::kIsBBZNA); bool isTriggerZNC = bc.selection_bit(aod::evsel::kIsBBZNC); - (reinterpret_cast(fStatsList->At(kStatsBcs)))->Fill(0.0, muTVX); + (dynamic_cast(fStatsList->At(kStatsBcs)))->Fill(0.0, muTVX); if (isTvx) { - (reinterpret_cast(fStatsList->At(kStatsBcs)))->Fill(1.0, muTVX); + (dynamic_cast(fStatsList->At(kStatsBcs)))->Fill(1.0, muTVX); if (noBorder) { - (reinterpret_cast(fStatsList->At(kStatsBcs)))->Fill(2.0, muTVX); + (dynamic_cast(fStatsList->At(kStatsBcs)))->Fill(2.0, muTVX); if (isCentral) { - (reinterpret_cast(fStatsList->At(kStatsBcs)))->Fill(3.0, muTVX); + (dynamic_cast(fStatsList->At(kStatsBcs)))->Fill(3.0, muTVX); } if (isSemiCentral) { - (reinterpret_cast(fStatsList->At(kStatsBcs)))->Fill(4.0, muTVX); + (dynamic_cast(fStatsList->At(kStatsBcs)))->Fill(4.0, muTVX); } if (isCentral || isSemiCentral) { - (reinterpret_cast(fStatsList->At(kStatsBcs)))->Fill(5.0, muTVX); + (dynamic_cast(fStatsList->At(kStatsBcs)))->Fill(5.0, muTVX); } if (isTriggerZNA && isTriggerZNC) { - (reinterpret_cast(fStatsList->At(kStatsBcs)))->Fill(6.0, muTVX); + (dynamic_cast(fStatsList->At(kStatsBcs)))->Fill(6.0, muTVX); } } } @@ -1039,10 +1041,10 @@ struct TableMaker { for (int i = 0; i < o2::aod::evsel::kNsel; i++) { if (collision.selection_bit(i)) { - (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(1.0, static_cast(i)); + (dynamic_cast(fStatsList->At(kStatsEvent)))->Fill(1.0, static_cast(i)); } } - (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(1.0, static_cast(o2::aod::evsel::kNsel)); + (dynamic_cast(fStatsList->At(kStatsEvent)))->Fill(1.0, static_cast(o2::aod::evsel::kNsel)); // apply the event filter computed by filter-PP if constexpr ((TEventFillMap & VarManager::ObjTypes::EventFilter) > 0) { @@ -1118,28 +1120,28 @@ struct TableMaker { } if (fDoDetailedQA) { - fHistMan->FillHistClass("Event_BeforeCuts", VarManager::fgValues); + fHistMan->FillHistClass("Event_BeforeCuts", dqtablemaker_helpers::varValues()); } // fill stats information, before selections for (int i = 0; i < o2::aod::evsel::kNsel; i++) { if (collision.selection_bit(i)) { - (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(2.0, static_cast(i)); + (dynamic_cast(fStatsList->At(kStatsEvent)))->Fill(2.0, static_cast(i)); } } - (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(2.0, static_cast(o2::aod::evsel::kNsel)); + (dynamic_cast(fStatsList->At(kStatsEvent)))->Fill(2.0, static_cast(o2::aod::evsel::kNsel)); if (fConfigZorro.fConfigRunZorro) { zorro.setBaseCCDBPath(fConfigCCDB.fConfigCcdbPathZorro.value); zorro.setBCtolerance(fConfigZorro.fBcTolerance); zorro.initCCDB(fCCDB.service, fCurrentRun, bc.timestamp(), fConfigZorro.fConfigZorroTrigMask.value); - zorro.populateExternalHists(fCurrentRun, reinterpret_cast(fStatsList->At(kStatsZorroInfo)), reinterpret_cast(fStatsList->At(kStatsZorroSel))); + zorro.populateExternalHists(fCurrentRun, dynamic_cast(fStatsList->At(kStatsZorroInfo)), dynamic_cast(fStatsList->At(kStatsZorroSel))); - if (!fEventCut->IsSelected(VarManager::fgValues) || (fConfigRCT.fConfigUseRCT.value && !rctChecker(collision))) { + if (!fEventCut->IsSelected(dqtablemaker_helpers::varValues()) || (fConfigRCT.fConfigUseRCT.value && !rctChecker(collision))) { continue; } - bool zorroSel = zorro.isSelected(bc.globalBC(), fConfigZorro.fBcTolerance, reinterpret_cast(fStatsList->At(kStatsZorroSel))); + bool zorroSel = zorro.isSelected(bc.globalBC(), fConfigZorro.fBcTolerance, dynamic_cast(fStatsList->At(kStatsZorroSel))); if (zorroSel) { tag |= (static_cast(true) << 56); // the same bit is used for this zorro selections from ccdb } @@ -1147,7 +1149,7 @@ struct TableMaker { continue; } } else { - if (!fEventCut->IsSelected(VarManager::fgValues) || (fConfigRCT.fConfigUseRCT.value && !rctChecker(collision))) { + if (!fEventCut->IsSelected(dqtablemaker_helpers::varValues()) || (fConfigRCT.fConfigUseRCT.value && !rctChecker(collision))) { continue; } } @@ -1155,15 +1157,15 @@ struct TableMaker { // fill stats information, after selections for (int i = 0; i < o2::aod::evsel::kNsel; i++) { if (collision.selection_bit(i)) { - (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(3.0, static_cast(i)); + (dynamic_cast(fStatsList->At(kStatsEvent)))->Fill(3.0, static_cast(i)); } } - (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(3.0, static_cast(o2::aod::evsel::kNsel)); + (dynamic_cast(fStatsList->At(kStatsEvent)))->Fill(3.0, static_cast(o2::aod::evsel::kNsel)); - fHistMan->FillHistClass("Event_AfterCuts", VarManager::fgValues); + fHistMan->FillHistClass("Event_AfterCuts", dqtablemaker_helpers::varValues()); // create the event tables - event(tag, bc.runNumber(), collision.posX(), collision.posY(), collision.posZ(), collision.numContrib(), collision.collisionTime(), collision.collisionTimeRes()); + outTables.event(tag, bc.runNumber(), collision.posX(), collision.posY(), collision.posZ(), collision.numContrib(), collision.collisionTime(), collision.collisionTimeRes()); if constexpr ((TEventFillMap & VarManager::ObjTypes::CollisionMult) > 0) { multFV0C = collision.multFV0C(); multTPC = collision.multTPC(); @@ -1182,16 +1184,16 @@ struct TableMaker { centFT0A = collision.centFT0A(); centFT0M = collision.centFT0M(); } - eventExtended(bc.globalBC(), collision.alias_raw(), collision.selection_raw(), bc.timestamp(), VarManager::fgValues[VarManager::kCentVZERO], - multTPC, multFV0A, multFV0C, multFT0A, multFT0C, multFDDA, multFDDC, multZNA, multZNC, multTracklets, multTracksPV, centFT0C, centFT0A, centFT0M); - eventVtxCov(collision.covXX(), collision.covXY(), collision.covXZ(), collision.covYY(), collision.covYZ(), collision.covZZ(), collision.chi2()); - eventInfo(collision.globalIndex()); + outTables.eventExtended(bc.globalBC(), collision.alias_raw(), collision.selection_raw(), bc.timestamp(), VarManager::fgValues[VarManager::kCentVZERO], + multTPC, multFV0A, multFV0C, multFT0A, multFT0C, multFDDA, multFDDC, multZNA, multZNC, multTracklets, multTracksPV, centFT0C, centFT0A, centFT0M); + outTables.eventVtxCov(collision.covXX(), collision.covXY(), collision.covXZ(), collision.covYY(), collision.covYZ(), collision.covZZ(), collision.chi2()); + outTables.eventInfo(collision.globalIndex()); if constexpr ((TEventFillMap & VarManager::ObjTypes::CollisionQvectCentr) > 0) { if (fConfigQvector.fConfigQvectCalibAvailable) { - qvecGroup.eventQvectorCentr(collision.qvecFT0ARe(), collision.qvecFT0AIm(), collision.qvecFT0CRe(), collision.qvecFT0CIm(), collision.qvecFT0MRe(), collision.qvecFT0MIm(), collision.qvecFV0ARe(), collision.qvecFV0AIm(), collision.qvecTPCposRe(), collision.qvecTPCposIm(), collision.qvecTPCnegRe(), collision.qvecTPCnegIm(), + outTables.eventQvectorCentr(collision.qvecFT0ARe(), collision.qvecFT0AIm(), collision.qvecFT0CRe(), collision.qvecFT0CIm(), collision.qvecFT0MRe(), collision.qvecFT0MIm(), collision.qvecFV0ARe(), collision.qvecFV0AIm(), collision.qvecTPCposRe(), collision.qvecTPCposIm(), collision.qvecTPCnegRe(), collision.qvecTPCnegIm(), collision.sumAmplFT0A(), collision.sumAmplFT0C(), collision.sumAmplFT0M(), collision.sumAmplFV0A(), collision.nTrkTPCpos(), collision.nTrkTPCneg()); - qvecGroup.eventQvectorCentrExtra(collision.qvecTPCallRe(), collision.qvecTPCallIm(), collision.nTrkTPCall()); + outTables.eventQvectorCentrExtra(collision.qvecTPCallRe(), collision.qvecTPCallIm(), collision.nTrkTPCall()); } } if constexpr ((TEventFillMap & VarManager::ObjTypes::Zdc) > 0) { @@ -1200,70 +1202,70 @@ struct TableMaker { auto newbc = bcs.rawIteratorAt(collision.newBcIndex()); if (newbc.has_zdc()) { auto newbc_zdc = newbc.zdc(); - zdc(newbc_zdc.energyCommonZNA(), newbc_zdc.energyCommonZNC(), newbc_zdc.energyCommonZPA(), newbc_zdc.energyCommonZPC(), - newbc_zdc.timeZNA(), newbc_zdc.timeZNC(), newbc_zdc.timeZPA(), newbc_zdc.timeZPC()); + outTables.zdc(newbc_zdc.energyCommonZNA(), newbc_zdc.energyCommonZNC(), newbc_zdc.energyCommonZPA(), newbc_zdc.energyCommonZPC(), + newbc_zdc.timeZNA(), newbc_zdc.timeZNC(), newbc_zdc.timeZPA(), newbc_zdc.timeZPC()); } else { - zdc(-999.0, -999.0, -999.0, -999.0, -999.0, -999.0, -999.0, -999.0); + outTables.zdc(-999.0, -999.0, -999.0, -999.0, -999.0, -999.0, -999.0, -999.0); } } else if (bcEvSel.has_zdc()) { auto bc_zdc = bcEvSel.zdc(); - zdc(bc_zdc.energyCommonZNA(), bc_zdc.energyCommonZNC(), bc_zdc.energyCommonZPA(), bc_zdc.energyCommonZPC(), - bc_zdc.timeZNA(), bc_zdc.timeZNC(), bc_zdc.timeZPA(), bc_zdc.timeZPC()); + outTables.zdc(bc_zdc.energyCommonZNA(), bc_zdc.energyCommonZNC(), bc_zdc.energyCommonZPA(), bc_zdc.energyCommonZPC(), + bc_zdc.timeZNA(), bc_zdc.timeZNC(), bc_zdc.timeZPA(), bc_zdc.timeZPC()); } else { - zdc(-999.0, -999.0, -999.0, -999.0, -999.0, -999.0, -999.0, -999.0); + outTables.zdc(-999.0, -999.0, -999.0, -999.0, -999.0, -999.0, -999.0, -999.0); } } // Fill FIT table if requested if constexpr ((TEventFillMap & VarManager::ObjTypes::Fit) > 0) { - fit(VarManager::fgValues[VarManager::kAmplitudeFT0A], VarManager::fgValues[VarManager::kAmplitudeFT0C], - VarManager::fgValues[VarManager::kTimeFT0A], VarManager::fgValues[VarManager::kTimeFT0C], - static_cast(VarManager::fgValues[VarManager::kTriggerMaskFT0]), - static_cast(VarManager::fgValues[VarManager::kNFiredChannelsFT0A]), - static_cast(VarManager::fgValues[VarManager::kNFiredChannelsFT0C]), - VarManager::fgValues[VarManager::kAmplitudeFDDA], VarManager::fgValues[VarManager::kAmplitudeFDDC], - VarManager::fgValues[VarManager::kTimeFDDA], VarManager::fgValues[VarManager::kTimeFDDC], - static_cast(VarManager::fgValues[VarManager::kTriggerMaskFDD]), - VarManager::fgValues[VarManager::kAmplitudeFV0A], VarManager::fgValues[VarManager::kTimeFV0A], - static_cast(VarManager::fgValues[VarManager::kTriggerMaskFV0A]), - static_cast(VarManager::fgValues[VarManager::kNFiredChannelsFV0A]), - static_cast(VarManager::fgValues[VarManager::kBBFT0Apf]), - static_cast(VarManager::fgValues[VarManager::kBGFT0Apf]), - static_cast(VarManager::fgValues[VarManager::kBBFT0Cpf]), - static_cast(VarManager::fgValues[VarManager::kBGFT0Cpf]), - static_cast(VarManager::fgValues[VarManager::kBBFV0Apf]), - static_cast(VarManager::fgValues[VarManager::kBGFV0Apf]), - static_cast(VarManager::fgValues[VarManager::kBBFDDApf]), - static_cast(VarManager::fgValues[VarManager::kBGFDDApf]), - static_cast(VarManager::fgValues[VarManager::kBBFDDCpf]), - static_cast(VarManager::fgValues[VarManager::kBGFDDCpf])); + outTables.fit(VarManager::fgValues[VarManager::kAmplitudeFT0A], VarManager::fgValues[VarManager::kAmplitudeFT0C], + VarManager::fgValues[VarManager::kTimeFT0A], VarManager::fgValues[VarManager::kTimeFT0C], + static_cast(VarManager::fgValues[VarManager::kTriggerMaskFT0]), + static_cast(VarManager::fgValues[VarManager::kNFiredChannelsFT0A]), + static_cast(VarManager::fgValues[VarManager::kNFiredChannelsFT0C]), + VarManager::fgValues[VarManager::kAmplitudeFDDA], VarManager::fgValues[VarManager::kAmplitudeFDDC], + VarManager::fgValues[VarManager::kTimeFDDA], VarManager::fgValues[VarManager::kTimeFDDC], + static_cast(VarManager::fgValues[VarManager::kTriggerMaskFDD]), + VarManager::fgValues[VarManager::kAmplitudeFV0A], VarManager::fgValues[VarManager::kTimeFV0A], + static_cast(VarManager::fgValues[VarManager::kTriggerMaskFV0A]), + static_cast(VarManager::fgValues[VarManager::kNFiredChannelsFV0A]), + static_cast(VarManager::fgValues[VarManager::kBBFT0Apf]), + static_cast(VarManager::fgValues[VarManager::kBGFT0Apf]), + static_cast(VarManager::fgValues[VarManager::kBBFT0Cpf]), + static_cast(VarManager::fgValues[VarManager::kBGFT0Cpf]), + static_cast(VarManager::fgValues[VarManager::kBBFV0Apf]), + static_cast(VarManager::fgValues[VarManager::kBGFV0Apf]), + static_cast(VarManager::fgValues[VarManager::kBBFDDApf]), + static_cast(VarManager::fgValues[VarManager::kBGFDDApf]), + static_cast(VarManager::fgValues[VarManager::kBBFDDCpf]), + static_cast(VarManager::fgValues[VarManager::kBGFDDCpf])); } if constexpr ((TEventFillMap & VarManager::ObjTypes::CollisionMultExtra) > 0) { - multPV(collision.multNTracksHasITS(), collision.multNTracksHasTPC(), collision.multNTracksHasTOF(), collision.multNTracksHasTRD(), - collision.multNTracksITSOnly(), collision.multNTracksTPCOnly(), collision.multNTracksITSTPC(), - collision.multNTracksPVeta1(), collision.multNTracksPVetaHalf(), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange()); - - multAll(collision.multAllTracksTPCOnly(), collision.multAllTracksITSTPC(), - fOccup.oContribLongA[collision.globalIndex()], fOccup.oContribLongC[collision.globalIndex()], - fOccup.oMeanTimeLongA[collision.globalIndex()], fOccup.oMeanTimeLongC[collision.globalIndex()], - fOccup.oMedianTimeLongA[collision.globalIndex()], fOccup.oMedianTimeLongC[collision.globalIndex()], - fOccup.oContribShortA[collision.globalIndex()], fOccup.oContribShortC[collision.globalIndex()], - fOccup.oMeanTimeShortA[collision.globalIndex()], fOccup.oMeanTimeShortC[collision.globalIndex()], - fOccup.oMedianTimeShortA[collision.globalIndex()], fOccup.oMedianTimeShortC[collision.globalIndex()]); - } - mergingTable(fCollMergingTag.bimodalityCoeffDCAz[collision.globalIndex()], fCollMergingTag.bimodalityCoeffDCAzBinned[collision.globalIndex()], - fCollMergingTag.bimodalityCoeffDCAzBinnedTrimmed1[collision.globalIndex()], fCollMergingTag.bimodalityCoeffDCAzBinnedTrimmed2[collision.globalIndex()], fCollMergingTag.bimodalityCoeffDCAzBinnedTrimmed3[collision.globalIndex()], - fCollMergingTag.meanDCAz[collision.globalIndex()], fCollMergingTag.meanDCAzBinnedTrimmed1[collision.globalIndex()], fCollMergingTag.meanDCAzBinnedTrimmed2[collision.globalIndex()], fCollMergingTag.meanDCAzBinnedTrimmed3[collision.globalIndex()], - fCollMergingTag.rmsDCAz[collision.globalIndex()], fCollMergingTag.rmsDCAzBinnedTrimmed1[collision.globalIndex()], fCollMergingTag.rmsDCAzBinnedTrimmed2[collision.globalIndex()], fCollMergingTag.rmsDCAzBinnedTrimmed3[collision.globalIndex()], - fCollMergingTag.skewnessDCAz[collision.globalIndex()], fCollMergingTag.kurtosisDCAz[collision.globalIndex()], - fCollMergingTag.fraction100umDCAz[collision.globalIndex()], fCollMergingTag.fraction200umDCAz[collision.globalIndex()], - fCollMergingTag.fraction500umDCAz[collision.globalIndex()], fCollMergingTag.fraction1mmDCAz[collision.globalIndex()], - fCollMergingTag.fraction2mmDCAz[collision.globalIndex()], fCollMergingTag.fraction5mmDCAz[collision.globalIndex()], - fCollMergingTag.fraction10mmDCAz[collision.globalIndex()], - fCollMergingTag.nPeaksDCAz[collision.globalIndex()], fCollMergingTag.nPeaksDCAzTrimmed1[collision.globalIndex()], - fCollMergingTag.nPeaksDCAzTrimmed2[collision.globalIndex()], fCollMergingTag.nPeaksDCAzTrimmed3[collision.globalIndex()]); + outTables.multPV(collision.multNTracksHasITS(), collision.multNTracksHasTPC(), collision.multNTracksHasTOF(), collision.multNTracksHasTRD(), + collision.multNTracksITSOnly(), collision.multNTracksTPCOnly(), collision.multNTracksITSTPC(), + collision.multNTracksPVeta1(), collision.multNTracksPVetaHalf(), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange()); + + outTables.multAll(collision.multAllTracksTPCOnly(), collision.multAllTracksITSTPC(), + fOccup.oContribLongA[collision.globalIndex()], fOccup.oContribLongC[collision.globalIndex()], + fOccup.oMeanTimeLongA[collision.globalIndex()], fOccup.oMeanTimeLongC[collision.globalIndex()], + fOccup.oMedianTimeLongA[collision.globalIndex()], fOccup.oMedianTimeLongC[collision.globalIndex()], + fOccup.oContribShortA[collision.globalIndex()], fOccup.oContribShortC[collision.globalIndex()], + fOccup.oMeanTimeShortA[collision.globalIndex()], fOccup.oMeanTimeShortC[collision.globalIndex()], + fOccup.oMedianTimeShortA[collision.globalIndex()], fOccup.oMedianTimeShortC[collision.globalIndex()]); + } + outTables.mergingTable(fCollMergingTag.bimodalityCoeffDCAz[collision.globalIndex()], fCollMergingTag.bimodalityCoeffDCAzBinned[collision.globalIndex()], + fCollMergingTag.bimodalityCoeffDCAzBinnedTrimmed1[collision.globalIndex()], fCollMergingTag.bimodalityCoeffDCAzBinnedTrimmed2[collision.globalIndex()], fCollMergingTag.bimodalityCoeffDCAzBinnedTrimmed3[collision.globalIndex()], + fCollMergingTag.meanDCAz[collision.globalIndex()], fCollMergingTag.meanDCAzBinnedTrimmed1[collision.globalIndex()], fCollMergingTag.meanDCAzBinnedTrimmed2[collision.globalIndex()], fCollMergingTag.meanDCAzBinnedTrimmed3[collision.globalIndex()], + fCollMergingTag.rmsDCAz[collision.globalIndex()], fCollMergingTag.rmsDCAzBinnedTrimmed1[collision.globalIndex()], fCollMergingTag.rmsDCAzBinnedTrimmed2[collision.globalIndex()], fCollMergingTag.rmsDCAzBinnedTrimmed3[collision.globalIndex()], + fCollMergingTag.skewnessDCAz[collision.globalIndex()], fCollMergingTag.kurtosisDCAz[collision.globalIndex()], + fCollMergingTag.fraction100umDCAz[collision.globalIndex()], fCollMergingTag.fraction200umDCAz[collision.globalIndex()], + fCollMergingTag.fraction500umDCAz[collision.globalIndex()], fCollMergingTag.fraction1mmDCAz[collision.globalIndex()], + fCollMergingTag.fraction2mmDCAz[collision.globalIndex()], fCollMergingTag.fraction5mmDCAz[collision.globalIndex()], + fCollMergingTag.fraction10mmDCAz[collision.globalIndex()], + fCollMergingTag.nPeaksDCAz[collision.globalIndex()], fCollMergingTag.nPeaksDCAzTrimmed1[collision.globalIndex()], + fCollMergingTag.nPeaksDCAzTrimmed2[collision.globalIndex()], fCollMergingTag.nPeaksDCAzTrimmed3[collision.globalIndex()]); // - fCollIndexMap[collision.globalIndex()] = event.lastIndex(); + fCollIndexMap[collision.globalIndex()] = outTables.event.lastIndex(); } } @@ -1275,8 +1277,8 @@ struct TableMaker { // One can apply here cuts which depend on the association (e.g. DCA), which will discard (hopefully most) wrong associations. // Tracks are written only once, even if they constribute to more than one association - uint64_t trackFilteringTag = static_cast(0); - uint32_t trackTempFilterMap = static_cast(0); + auto trackFilteringTag = static_cast(0); + auto trackTempFilterMap = static_cast(0); // material correction for track propagation // TODO: Do we need a configurable to switch between different material correction options? @@ -1304,20 +1306,20 @@ struct TableMaker { } if (fDoDetailedQA) { - fHistMan->FillHistClass("TrackBarrel_BeforeCuts", VarManager::fgValues); + fHistMan->FillHistClass("TrackBarrel_BeforeCuts", dqtablemaker_helpers::varValues()); } // apply track cuts and fill stats histogram int i = 0; for (auto cut = fTrackCuts.begin(); cut != fTrackCuts.end(); cut++, i++) { - if ((*cut)->IsSelected(VarManager::fgValues)) { + if ((*cut)->IsSelected(dqtablemaker_helpers::varValues())) { trackTempFilterMap |= (static_cast(1) << i); // NOTE: the QA is filled here just for the first occurence of this track. // So if there are histograms of quantities which depend on the collision association, these will not be accurate if (fConfigHistOutput.fConfigQA && (fTrackIndexMap.find(track.globalIndex()) == fTrackIndexMap.end())) { - fHistMan->FillHistClass(Form("TrackBarrel_%s", (*cut)->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("TrackBarrel_%s", (*cut)->GetName()), dqtablemaker_helpers::varValues()); } - (reinterpret_cast(fStatsList->At(kStatsTracks)))->Fill(static_cast(i)); + (dynamic_cast(fStatsList->At(kStatsTracks)))->Fill(static_cast(i)); } } if (!trackTempFilterMap) { @@ -1327,7 +1329,7 @@ struct TableMaker { // If this track is already present in the index map, it means it was already skimmed, // so we just store the association and we skip the track if (fTrackIndexMap.find(track.globalIndex()) != fTrackIndexMap.end()) { - trackBarrelAssoc(fCollIndexMap[collision.globalIndex()], fTrackIndexMap[track.globalIndex()]); + outTables.trackBarrelAssoc(fCollIndexMap[collision.globalIndex()], fTrackIndexMap[track.globalIndex()]); continue; } @@ -1336,22 +1338,22 @@ struct TableMaker { trackFilteringTag |= static_cast(track.pidbit()); for (int iv0 = 0; iv0 < 5; iv0++) { if (track.pidbit() & (uint8_t(1) << iv0)) { - (reinterpret_cast(fStatsList->At(kStatsTracks)))->Fill(fTrackCuts.size() + static_cast(iv0)); + (dynamic_cast(fStatsList->At(kStatsTracks)))->Fill(fTrackCuts.size() + static_cast(iv0)); } } // TODO: this part should be removed since the calibration histogram can be filled as any other histogram if (fConfigPostCalibTPC.fConfigIsOnlyforMaps) { if (trackFilteringTag & (static_cast(1) << VarManager::kIsConversionLeg)) { // for electron - fHistMan->FillHistClass("TrackBarrel_PostCalibElectron", VarManager::fgValues); + fHistMan->FillHistClass("TrackBarrel_PostCalibElectron", dqtablemaker_helpers::varValues()); } if (trackFilteringTag & (static_cast(1) << VarManager::kIsK0sLeg)) { // for pion - fHistMan->FillHistClass("TrackBarrel_PostCalibPion", VarManager::fgValues); + fHistMan->FillHistClass("TrackBarrel_PostCalibPion", dqtablemaker_helpers::varValues()); } if ((static_cast(trackFilteringTag & (static_cast(1) << VarManager::kIsLambdaLeg)) * (track.sign()) > 0)) { // for proton from Lambda - fHistMan->FillHistClass("TrackBarrel_PostCalibProton", VarManager::fgValues); + fHistMan->FillHistClass("TrackBarrel_PostCalibProton", dqtablemaker_helpers::varValues()); } if ((static_cast(trackFilteringTag & (static_cast(1) << VarManager::kIsALambdaLeg)) * (track.sign()) < 0)) { // for proton from AntiLambda - fHistMan->FillHistClass("TrackBarrel_PostCalibProton", VarManager::fgValues); + fHistMan->FillHistClass("TrackBarrel_PostCalibProton", dqtablemaker_helpers::varValues()); } } if (fConfigPostCalibTPC.fConfigSaveElectronSample) { // only save electron sample @@ -1373,9 +1375,9 @@ struct TableMaker { // Calculating the percentage of orphan tracks i.e., tracks which have no collisions associated to it if (!track.has_collision()) { - (reinterpret_cast(fStatsList->At(kStatsOrphanTracks)))->Fill(static_cast(-1)); + (dynamic_cast(fStatsList->At(kStatsOrphanTracks)))->Fill(static_cast(-1)); } else { - (reinterpret_cast(fStatsList->At(kStatsOrphanTracks)))->Fill(0.9); + (dynamic_cast(fStatsList->At(kStatsOrphanTracks)))->Fill(0.9); } // NOTE: The collision ID written in the table is the one of the original collision assigned in the AO2D. @@ -1386,45 +1388,45 @@ struct TableMaker { // NOTE: trackBarrelInfo stores the index of the collision as in AO2D (for use in some cases where the analysis on skims is done // in workflows where the original AO2Ds are also present) - trackBarrelInfo(collision.globalIndex(), collision.posX(), collision.posY(), collision.posZ(), track.globalIndex()); - trackBasic(reducedEventIdx, trackFilteringTag, track.pt(), track.eta(), track.phi(), track.sign(), 0); - trackBarrel(track.x(), track.alpha(), track.y(), track.z(), track.snp(), track.tgl(), track.signed1Pt(), - track.tpcInnerParam(), track.flags(), track.itsClusterMap(), track.itsChi2NCl(), - track.tpcNClsFindable(), track.tpcNClsFindableMinusFound(), track.tpcNClsFindableMinusCrossedRows(), - track.tpcNClsShared(), track.tpcChi2NCl(), - track.trdChi2(), track.trdPattern(), track.tofChi2(), - track.length(), track.dcaXY(), track.dcaZ(), - track.trackTime(), track.trackTimeRes(), track.tofExpMom(), - track.detectorMap()); + outTables.trackBarrelInfo(collision.globalIndex(), collision.posX(), collision.posY(), collision.posZ(), track.globalIndex()); + outTables.trackBasic(reducedEventIdx, trackFilteringTag, track.pt(), track.eta(), track.phi(), track.sign(), 0); + outTables.trackBarrel(track.x(), track.alpha(), track.y(), track.z(), track.snp(), track.tgl(), track.signed1Pt(), + track.tpcInnerParam(), track.flags(), track.itsClusterMap(), track.itsChi2NCl(), + track.tpcNClsFindable(), track.tpcNClsFindableMinusFound(), track.tpcNClsFindableMinusCrossedRows(), + track.tpcNClsShared(), track.tpcChi2NCl(), + track.trdChi2(), track.trdPattern(), track.tofChi2(), + track.length(), track.dcaXY(), track.dcaZ(), + track.trackTime(), track.trackTimeRes(), track.tofExpMom(), + track.detectorMap()); if constexpr (static_cast(TTrackFillMap & VarManager::ObjTypes::TrackCov)) { - trackBarrelCov(track.cYY(), track.cZY(), track.cZZ(), track.cSnpY(), track.cSnpZ(), - track.cSnpSnp(), track.cTglY(), track.cTglZ(), track.cTglSnp(), track.cTglTgl(), - track.c1PtY(), track.c1PtZ(), track.c1PtSnp(), track.c1PtTgl(), track.c1Pt21Pt2()); + outTables.trackBarrelCov(track.cYY(), track.cZY(), track.cZZ(), track.cSnpY(), track.cSnpZ(), + track.cSnpSnp(), track.cTglY(), track.cTglZ(), track.cTglSnp(), track.cTglTgl(), + track.c1PtY(), track.c1PtZ(), track.c1PtSnp(), track.c1PtTgl(), track.c1Pt21Pt2()); } if constexpr (static_cast(TTrackFillMap & VarManager::ObjTypes::TrackPID)) { float nSigmaEl = (fConfigPostCalibTPC.fConfigComputeTPCpostCalib ? VarManager::fgValues[VarManager::kTPCnSigmaEl_Corr] : track.tpcNSigmaEl()); float nSigmaPi = (fConfigPostCalibTPC.fConfigComputeTPCpostCalib ? VarManager::fgValues[VarManager::kTPCnSigmaPi_Corr] : track.tpcNSigmaPi()); float nSigmaKa = ((fConfigPostCalibTPC.fConfigComputeTPCpostCalib && fConfigPostCalibTPC.fConfigComputeTPCpostCalibKaon) ? VarManager::fgValues[VarManager::kTPCnSigmaKa_Corr] : track.tpcNSigmaKa()); float nSigmaPr = (fConfigPostCalibTPC.fConfigComputeTPCpostCalib ? VarManager::fgValues[VarManager::kTPCnSigmaPr_Corr] : track.tpcNSigmaPr()); - trackBarrelPID(track.tpcSignal(), - nSigmaEl, track.tpcNSigmaMu(), nSigmaPi, nSigmaKa, nSigmaPr, - track.beta(), track.tofNSigmaEl(), track.tofNSigmaMu(), track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), - track.trdSignal()); + outTables.trackBarrelPID(track.tpcSignal(), + nSigmaEl, track.tpcNSigmaMu(), nSigmaPi, nSigmaKa, nSigmaPr, + track.beta(), track.tofNSigmaEl(), track.tofNSigmaMu(), track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), + track.trdSignal()); } else if constexpr (static_cast(TTrackFillMap & VarManager::ObjTypes::TrackTPCPID)) { float nSigmaEl = (fConfigPostCalibTPC.fConfigComputeTPCpostCalib ? VarManager::fgValues[VarManager::kTPCnSigmaEl_Corr] : track.tpcNSigmaEl()); float nSigmaPi = (fConfigPostCalibTPC.fConfigComputeTPCpostCalib ? VarManager::fgValues[VarManager::kTPCnSigmaPi_Corr] : track.tpcNSigmaPi()); float nSigmaKa = ((fConfigPostCalibTPC.fConfigComputeTPCpostCalib && fConfigPostCalibTPC.fConfigComputeTPCpostCalibKaon) ? VarManager::fgValues[VarManager::kTPCnSigmaKa_Corr] : track.tpcNSigmaKa()); float nSigmaPr = (fConfigPostCalibTPC.fConfigComputeTPCpostCalib ? VarManager::fgValues[VarManager::kTPCnSigmaPr_Corr] : track.tpcNSigmaPr()); - trackBarrelPID(track.tpcSignal(), - nSigmaEl, -999.0, nSigmaPi, nSigmaKa, nSigmaPr, - -999.0, -999.0, -999.0, -999.0, -999.0, -999.0, - -999.0); + outTables.trackBarrelPID(track.tpcSignal(), + nSigmaEl, -999.0, nSigmaPi, nSigmaKa, nSigmaPr, + -999.0, -999.0, -999.0, -999.0, -999.0, -999.0, + -999.0); } - fTrackIndexMap[track.globalIndex()] = trackBasic.lastIndex(); + fTrackIndexMap[track.globalIndex()] = outTables.trackBasic.lastIndex(); // write the skimmed collision - track association - trackBarrelAssoc(fCollIndexMap[collision.globalIndex()], fTrackIndexMap[track.globalIndex()]); + outTables.trackBarrelAssoc(fCollIndexMap[collision.globalIndex()], fTrackIndexMap[track.globalIndex()]); } // end loop over associations } // end skimTracks @@ -1439,19 +1441,19 @@ struct TableMaker { if (fConfigHistOutput.fConfigQA) { VarManager::FillTrack(track); - fHistMan->FillHistClass("MftTracks", VarManager::fgValues); + fHistMan->FillHistClass("MftTracks", dqtablemaker_helpers::varValues()); } // write the MFT track global index in the map for skimming (to make sure we have it just once) - if (fMftIndexMap.find(track.globalIndex()) == fMftIndexMap.end()) { + if (!fMftIndexMap.contains(track.globalIndex())) { uint32_t reducedEventIdx = fCollIndexMap[collision.globalIndex()]; - mftTrack(reducedEventIdx, static_cast(0), track.pt(), track.eta(), track.phi()); + outTables.mftTrack(reducedEventIdx, static_cast(0), track.pt(), track.eta(), track.phi()); // TODO: We are not writing the DCA at the moment, because this depend on the collision association - mftTrackExtra(track.mftClusterSizesAndTrackFlags(), track.sign(), 0.0, 0.0, track.nClusters()); + outTables.mftTrackExtra(track.mftClusterSizesAndTrackFlags(), track.sign(), 0.0, 0.0, track.nClusters()); - fMftIndexMap[track.globalIndex()] = mftTrack.lastIndex(); + fMftIndexMap[track.globalIndex()] = outTables.mftTrack.lastIndex(); } - mftAssoc(fCollIndexMap[collision.globalIndex()], fMftIndexMap[track.globalIndex()]); + outTables.mftAssoc(fCollIndexMap[collision.globalIndex()], fMftIndexMap[track.globalIndex()]); } } @@ -1472,7 +1474,7 @@ struct TableMaker { } } } - for (auto& pairCand : mCandidates) { + for (const auto& pairCand : mCandidates) { fBestMatch[pairCand.second.second] = true; } } @@ -1506,7 +1508,7 @@ struct TableMaker { } } } - for (auto& pairCand : mCandidates) { + for (const auto& pairCand : mCandidates) { fBestMatch[pairCand.second.second] = true; } } @@ -1521,11 +1523,11 @@ struct TableMaker { // TODO: Currently, the TMFTFillMap is not used in this function. Is it needed ? - uint8_t trackFilteringTag = static_cast(0); - uint8_t trackTempFilterMap = static_cast(0); + auto trackFilteringTag = static_cast(0); + auto trackTempFilterMap = static_cast(0); fFwdTrackIndexMapReversed.clear(); - uint32_t offset = muonBasic.lastIndex(); + uint32_t offset = outTables.muonBasic.lastIndex(); uint32_t counter = 0; for (const auto& assoc : muonAssocs) { // get the muon @@ -1574,20 +1576,20 @@ struct TableMaker { } if (fDoDetailedQA) { - fHistMan->FillHistClass("Muons_BeforeCuts", VarManager::fgValues); + fHistMan->FillHistClass("Muons_BeforeCuts", dqtablemaker_helpers::varValues()); } // check the cuts and filters int i = 0; for (auto cut = fMuonCuts.begin(); cut != fMuonCuts.end(); cut++, i++) { - if ((*cut)->IsSelected(VarManager::fgValues)) { + if ((*cut)->IsSelected(dqtablemaker_helpers::varValues())) { trackTempFilterMap |= (static_cast(1) << i); // NOTE: the QA is filled here just for the first occurence of this muon, which means the current association // will be skipped from histograms if this muon was already filled in the skimming map. // So if there are histograms of quantities which depend on the collision association, these histograms will not be completely accurate if (fConfigHistOutput.fConfigQA && (fFwdTrackIndexMap.find(muon.globalIndex()) == fFwdTrackIndexMap.end())) { - fHistMan->FillHistClass(Form("Muons_%s", (*cut)->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("Muons_%s", (*cut)->GetName()), dqtablemaker_helpers::varValues()); } - (reinterpret_cast(fStatsList->At(kStatsMuons)))->Fill(static_cast(i)); + (dynamic_cast(fStatsList->At(kStatsMuons)))->Fill(static_cast(i)); } } @@ -1613,7 +1615,7 @@ struct TableMaker { fFwdTrackFilterMap[muon.globalIndex()] |= trackFilteringTag; // make a bitwise OR with previous existing cuts } // write the association table - muonAssoc(fCollIndexMap[collision.globalIndex()], fFwdTrackIndexMap[muon.globalIndex()]); + outTables.muonAssoc(fCollIndexMap[collision.globalIndex()], fFwdTrackIndexMap[muon.globalIndex()]); } // end loop over assocs // Now we have the full index map of selected muons so we can proceed with writing the muon tables @@ -1664,19 +1666,19 @@ struct TableMaker { } else { VarManager::FillTrackCollision(muon, collision); } - muonBasic(reducedEventIdx, mchIdx, mftIdx, fFwdTrackFilterMap[muon.globalIndex()], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], muon.sign(), 0); - muonExtra(globalClusters, VarManager::fgValues[VarManager::kMuonPDca], VarManager::fgValues[VarManager::kMuonRAtAbsorberEnd], - VarManager::fgValues[VarManager::kMuonChi2], muon.chi2MatchMCHMID(), muon.chi2MatchMCHMFT(), - muon.matchScoreMCHMFT(), - muon.mchBitMap(), muon.midBitMap(), - muon.midBoards(), muon.trackType(), VarManager::fgValues[VarManager::kMuonDCAx], VarManager::fgValues[VarManager::kMuonDCAy], - muon.trackTime(), muon.trackTimeRes()); - muonInfo(muon.collisionId(), collision.posX(), collision.posY(), collision.posZ()); + outTables.muonBasic(reducedEventIdx, mchIdx, mftIdx, fFwdTrackFilterMap[muon.globalIndex()], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], muon.sign(), 0); + outTables.muonExtra(globalClusters, VarManager::fgValues[VarManager::kMuonPDca], VarManager::fgValues[VarManager::kMuonRAtAbsorberEnd], + VarManager::fgValues[VarManager::kMuonChi2], muon.chi2MatchMCHMID(), muon.chi2MatchMCHMFT(), + muon.matchScoreMCHMFT(), + muon.mchBitMap(), muon.midBitMap(), + muon.midBoards(), muon.trackType(), VarManager::fgValues[VarManager::kMuonDCAx], VarManager::fgValues[VarManager::kMuonDCAy], + muon.trackTime(), muon.trackTimeRes()); + outTables.muonInfo(muon.collisionId(), collision.posX(), collision.posY(), collision.posZ()); if constexpr (static_cast(TMuonFillMap & VarManager::ObjTypes::MuonCov) || static_cast(TMuonFillMap & VarManager::ObjTypes::MuonCovRealign)) { - muonCov(VarManager::fgValues[VarManager::kX], VarManager::fgValues[VarManager::kY], VarManager::fgValues[VarManager::kZ], VarManager::fgValues[VarManager::kPhi], VarManager::fgValues[VarManager::kTgl], muon.sign() / VarManager::fgValues[VarManager::kPt], - VarManager::fgValues[VarManager::kMuonCXX], VarManager::fgValues[VarManager::kMuonCXY], VarManager::fgValues[VarManager::kMuonCYY], VarManager::fgValues[VarManager::kMuonCPhiX], VarManager::fgValues[VarManager::kMuonCPhiY], VarManager::fgValues[VarManager::kMuonCPhiPhi], - VarManager::fgValues[VarManager::kMuonCTglX], VarManager::fgValues[VarManager::kMuonCTglY], VarManager::fgValues[VarManager::kMuonCTglPhi], VarManager::fgValues[VarManager::kMuonCTglTgl], VarManager::fgValues[VarManager::kMuonC1Pt2X], VarManager::fgValues[VarManager::kMuonC1Pt2Y], - VarManager::fgValues[VarManager::kMuonC1Pt2Phi], VarManager::fgValues[VarManager::kMuonC1Pt2Tgl], VarManager::fgValues[VarManager::kMuonC1Pt21Pt2]); + outTables.muonCov(VarManager::fgValues[VarManager::kX], VarManager::fgValues[VarManager::kY], VarManager::fgValues[VarManager::kZ], VarManager::fgValues[VarManager::kPhi], VarManager::fgValues[VarManager::kTgl], muon.sign() / VarManager::fgValues[VarManager::kPt], + VarManager::fgValues[VarManager::kMuonCXX], VarManager::fgValues[VarManager::kMuonCXY], VarManager::fgValues[VarManager::kMuonCYY], VarManager::fgValues[VarManager::kMuonCPhiX], VarManager::fgValues[VarManager::kMuonCPhiY], VarManager::fgValues[VarManager::kMuonCPhiPhi], + VarManager::fgValues[VarManager::kMuonCTglX], VarManager::fgValues[VarManager::kMuonCTglY], VarManager::fgValues[VarManager::kMuonCTglPhi], VarManager::fgValues[VarManager::kMuonCTglTgl], VarManager::fgValues[VarManager::kMuonC1Pt2X], VarManager::fgValues[VarManager::kMuonC1Pt2Y], + VarManager::fgValues[VarManager::kMuonC1Pt2Phi], VarManager::fgValues[VarManager::kMuonC1Pt2Tgl], VarManager::fgValues[VarManager::kMuonC1Pt21Pt2]); } } // end loop over selected muons } // end skimMuons @@ -1713,7 +1715,7 @@ struct TableMaker { } VarManager::SetCalibrationType(fConfigPostCalibTPC.fConfigTPCpostCalibType, fConfigPostCalibTPC.fConfigTPCuseInterpolatedCalib); } - if (fIsRun2 == true) { + if (fIsRun2) { fGrpMagRun2 = fCCDB->getForTimeStamp(fConfigCCDB.fConfigGrpMagPathRun2, bcs.begin().timestamp()); if (fGrpMagRun2 != nullptr) { o2::base::Propagator::initFieldFromGRP(fGrpMagRun2); @@ -1751,46 +1753,46 @@ struct TableMaker { } // end updating the CCDB quantities at change of run // skim collisions - event.reserve(collisions.size()); - eventExtended.reserve(collisions.size()); - eventVtxCov.reserve(collisions.size()); + outTables.event.reserve(collisions.size()); + outTables.eventExtended.reserve(collisions.size()); + outTables.eventVtxCov.reserve(collisions.size()); skimCollisions(collisions, bcs, zdcs, ft0s, fv0as, fdds); - if (fCollIndexMap.size() == 0) { + if (fCollIndexMap.empty()) { return; } if constexpr (static_cast(TTrackFillMap)) { fTrackIndexMap.clear(); - trackBarrelInfo.reserve(tracksBarrel.size()); - trackBasic.reserve(tracksBarrel.size()); - trackBarrel.reserve(tracksBarrel.size()); - trackBarrelCov.reserve(tracksBarrel.size()); - trackBarrelPID.reserve(tracksBarrel.size()); - trackBarrelAssoc.reserve(tracksBarrel.size()); + outTables.trackBarrelInfo.reserve(tracksBarrel.size()); + outTables.trackBasic.reserve(tracksBarrel.size()); + outTables.trackBarrel.reserve(tracksBarrel.size()); + outTables.trackBarrelCov.reserve(tracksBarrel.size()); + outTables.trackBarrelPID.reserve(tracksBarrel.size()); + outTables.trackBarrelAssoc.reserve(trackAssocs.size()); } if constexpr (static_cast(TMFTFillMap)) { fMftIndexMap.clear(); map_mfttrackcovs.clear(); - mftTrack.reserve(mftTracks.size()); - mftTrackExtra.reserve(mftTracks.size()); - mftAssoc.reserve(mftTracks.size()); + outTables.mftTrack.reserve(mftTracks.size()); + outTables.mftTrackExtra.reserve(mftTracks.size()); + outTables.mftAssoc.reserve(mftAssocs.size()); } if constexpr (static_cast(TMuonFillMap)) { fFwdTrackIndexMap.clear(); fFwdTrackFilterMap.clear(); fBestMatch.clear(); - muonBasic.reserve(muons.size()); - muonExtra.reserve(muons.size()); - muonInfo.reserve(muons.size()); - muonCov.reserve(muons.size()); - muonAssoc.reserve(muons.size()); + outTables.muonBasic.reserve(muons.size()); + outTables.muonExtra.reserve(muons.size()); + outTables.muonInfo.reserve(muons.size()); + outTables.muonCov.reserve(muons.size()); + outTables.muonAssoc.reserve(fwdTrackAssocs.size()); } if constexpr (static_cast(TMFTFillMap & VarManager::ObjTypes::MFTCov)) { - for (auto& mfttrackConv : mftCovs) { + for (const auto& mfttrackConv : mftCovs) { map_mfttrackcovs[mfttrackConv.matchMFTTrackId()] = mfttrackConv.globalIndex(); } } @@ -1834,8 +1836,8 @@ struct TableMaker { } // end loop over skimmed collisions // LOG(info) << "Skims in this TF: " << fCollIndexMap.size() << " collisions; " << trackBasic.lastIndex() << " barrel tracks; " - //<< muonBasic.lastIndex() << " muon tracks; " << mftTrack.lastIndex() << " MFT tracks; "; - // LOG(info) << " " << trackBarrelAssoc.lastIndex() << " barrel assocs; " << muonAssoc.lastIndex() << " muon assocs; " << mftAssoc.lastIndex() << " MFT assoc"; + //<< outTables.muonBasic.lastIndex() << " muon tracks; " << mftTrack.lastIndex() << " MFT tracks; "; + // LOG(info) << " " << trackBarrelAssoc.lastIndex() << " barrel assocs; " << outTables.muonAssoc.lastIndex() << " muon assocs; " << outTables.mftAssoc.lastIndex() << " MFT assoc"; } // produce the full DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), subscribe to the DQ event filter (filter-pp or filter-PbPb) @@ -1859,7 +1861,7 @@ struct TableMaker { } // produce the barrel-only DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), subscribe to the DQ event filter (filter-pp or filter-PbPb) - void processPPWithFilterBarrelOnly(MyEventsWithMultsAndFilter const& collisions, MyBCs const& bcs, aod::Zdcs& zdcs, + void processPPWithFilterBarrelOnly(MyEventsWithMultsAndFilter const& collisions, MyBCs const& bcs, aod::Zdcs const& zdcs, MyBarrelTracksWithCov const& tracksBarrel, TrackAssoc const& trackAssocs) { @@ -1882,7 +1884,7 @@ struct TableMaker { } // produce the barrel-only DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), meant to run on skimmed data - void processPPBarrelOnly(MyEventsWithMults const& collisions, MyBCs const& bcs, aod::Zdcs& zdcs, + void processPPBarrelOnly(MyEventsWithMults const& collisions, MyBCs const& bcs, aod::Zdcs const& zdcs, MyBarrelTracksWithCov const& tracksBarrel, TrackAssoc const& trackAssocs) { @@ -1932,7 +1934,7 @@ struct TableMaker { MyBarrelTracksWithCov const& tracksBarrel, MyMuonsWithCov const& muons, MFTTracks const& mftTracks, TrackAssoc const& trackAssocs, FwdTrackAssoc const& fwdTrackAssocs, - MFTTrackAssoc const& mftAssocs, aod::FT0s& ft0s, aod::FV0As& fv0as, aod::FDDs& fdds) + MFTTrackAssoc const& mftAssocs, aod::FT0s const& ft0s, aod::FV0As const& fv0as, aod::FDDs const& fdds) { fullSkimming(collisions, bcs, nullptr, tracksBarrel, muons, mftTracks, trackAssocs, fwdTrackAssocs, mftAssocs, nullptr, ft0s, fv0as, fdds); } @@ -1940,7 +1942,7 @@ struct TableMaker { // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter void processPbPbBarrelOnly(MyEventsWithCentAndMultsQvect const& collisions, MyBCs const& bcs, MyBarrelTracksWithCov const& tracksBarrel, - TrackAssoc const& trackAssocs, aod::FT0s& ft0s, aod::FV0As& fv0as, aod::FDDs& fdds) + TrackAssoc const& trackAssocs, aod::FT0s const& ft0s, aod::FV0As const& fv0as, aod::FDDs const& fdds) { computeOccupancyEstimators(collisions, tracksPosWithCov, tracksNegWithCov, presliceWithCov, bcs); computeCollMergingTag(collisions, tracksBarrel, presliceWithCov); @@ -1950,7 +1952,7 @@ struct TableMaker { // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no TOF void processPbPbBarrelOnlyNoTOF(MyEventsWithCentAndMultsQvect const& collisions, MyBCs const& bcs, MyBarrelTracksWithCovNoTOF const& tracksBarrel, - TrackAssoc const& trackAssocs, aod::FT0s& ft0s, aod::FV0As& fv0as, aod::FDDs& fdds) + TrackAssoc const& trackAssocs, aod::FT0s const& ft0s, aod::FV0As const& fv0as, aod::FDDs const& fdds) { computeOccupancyEstimators(collisions, tracksPosWithCovNoTOF, tracksNegWithCovNoTOF, presliceWithCovNoTOF, bcs); computeCollMergingTag(collisions, tracksBarrel, presliceWithCovNoTOF); @@ -1958,9 +1960,9 @@ struct TableMaker { } // produce the barrel-only DQ skimmed data model typically for UPC Pb-Pb (no centrality), subscribe to the DQ rapidity gap event filter (filter-PbPb) - void processPbPbWithFilterBarrelOnly(MyEventsWithMultsAndRapidityGapFilter const& collisions, MyBCs const& bcs, aod::Zdcs& zdcs, + void processPbPbWithFilterBarrelOnly(MyEventsWithMultsAndRapidityGapFilter const& collisions, MyBCs const& bcs, aod::Zdcs const& zdcs, MyBarrelTracksWithCov const& tracksBarrel, - TrackAssoc const& trackAssocs, aod::FT0s& ft0s, aod::FV0As& fv0as, aod::FDDs& fdds) + TrackAssoc const& trackAssocs, aod::FT0s const& ft0s, aod::FV0As const& fv0as, aod::FDDs const& fdds) { computeOccupancyEstimators(collisions, tracksPosWithCov, tracksNegWithCov, presliceWithCov, bcs); computeCollMergingTag(collisions, tracksBarrel, presliceWithCov); @@ -1970,7 +1972,7 @@ struct TableMaker { // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter void processPbPbBarrelOnlyWithV0Bits(MyEventsWithCentAndMultsQvect const& collisions, MyBCs const& bcs, MyBarrelTracksWithV0Bits const& tracksBarrel, - TrackAssoc const& trackAssocs, aod::FT0s& ft0s, aod::FV0As& fv0as, aod::FDDs& fdds) + TrackAssoc const& trackAssocs, aod::FT0s const& ft0s, aod::FV0As const& fv0as, aod::FDDs const& fdds) { computeOccupancyEstimators(collisions, tracksPos, tracksNeg, preslice, bcs); computeCollMergingTag(collisions, tracksBarrel, preslice); @@ -1980,7 +1982,7 @@ struct TableMaker { // produce the barrel only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter void processPbPbBarrelOnlyWithV0BitsNoTOF(MyEventsWithCentAndMultsQvect const& collisions, MyBCs const& bcs, MyBarrelTracksWithV0BitsNoTOF const& tracksBarrel, - TrackAssoc const& trackAssocs, aod::FT0s& ft0s, aod::FV0As& fv0as, aod::FDDs& fdds) + TrackAssoc const& trackAssocs, aod::FT0s const& ft0s, aod::FV0As const& fv0as, aod::FDDs const& fdds) { computeOccupancyEstimators(collisions, tracksPosNoTOF, tracksNegNoTOF, presliceNoTOF, bcs); computeCollMergingTag(collisions, tracksBarrel, presliceNoTOF); @@ -1989,15 +1991,22 @@ struct TableMaker { // produce the muon only DQ skimmed data model typically for Pb-Pb (with centrality), no subscribtion to the DQ event filter void processPbPbMuonOnly(MyEventsWithCentAndMults const& collisions, MyBCs const& bcs, - MyMuonsWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs, aod::FT0s& ft0s, aod::FV0As& fv0as, aod::FDDs& fdds) + MyMuonsWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs, aod::FT0s const& ft0s, aod::FV0As const& fv0as, aod::FDDs const& fdds) { fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, fwdTrackAssocs, nullptr, nullptr, ft0s, fv0as, fdds); } + // produce the muon-only DQ skimmed data model typically for UPC Pb-Pb (no centrality), subscribe to the DQ rapidity gap event filter (filter-PbPb) + void processPbPbWithFilterMuonOnly(MyEventsWithMultsAndRapidityGapFilter const& collisions, MyBCs const& bcs, aod::Zdcs const& zdcs, + MyMuonsWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs, aod::FT0s const& ft0s, aod::FV0As const& fv0as, aod::FDDs const& fdds) + { + fullSkimming(collisions, bcs, zdcs, nullptr, muons, nullptr, nullptr, fwdTrackAssocs, nullptr, nullptr, ft0s, fv0as, fdds); + } + // produce the muon only DQ skimmed data model typically for Pb-Pb (with centrality and flow), no subscribtion to the DQ event filter // no DCA table filled by the FwdTracExtension to optimize the memory consumption void processPbPbStreamMuonOnly(MyEventsWithCentAndMultsQvect const& collisions, MyBCs const& bcs, - MyMuonsNoDca const& muons, FwdTrackAssoc const& fwdTrackAssocs, aod::FT0s& ft0s, aod::FV0As& fv0as, aod::FDDs& fdds) + MyMuonsNoDca const& muons, FwdTrackAssoc const& fwdTrackAssocs, aod::FT0s const& ft0s, aod::FV0As const& fv0as, aod::FDDs const& fdds) { fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, fwdTrackAssocs, nullptr, nullptr, ft0s, fv0as, fdds); } @@ -2030,11 +2039,11 @@ struct TableMaker { void processOnlyBCs(soa::Join::iterator const& bc) { for (int i = 0; i < o2::aod::evsel::kNsel; i++) { - if (bc.selection_bit(i) > 0) { - (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(0.0, static_cast(i)); + if (static_cast(bc.selection_bit(i)) > 0) { + (dynamic_cast(fStatsList->At(kStatsEvent)))->Fill(0.0, static_cast(i)); } } - (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(0.0, static_cast(o2::aod::evsel::kNsel)); + (dynamic_cast(fStatsList->At(kStatsEvent)))->Fill(0.0, static_cast(o2::aod::evsel::kNsel)); } PROCESS_SWITCH(TableMaker, processPP, "Build full DQ skimmed data model for pp/p-Pb w/o event filtering (use Zorro)", false); @@ -2055,13 +2064,14 @@ struct TableMaker { PROCESS_SWITCH(TableMaker, processPbPbBarrelOnlyWithV0Bits, "Build barrel only DQ skimmed data model typically for Pb-Pb, w/ V0 bits, w/o event filtering", false); PROCESS_SWITCH(TableMaker, processPbPbBarrelOnlyWithV0BitsNoTOF, "Build barrel only DQ skimmed data model typically for Pb-Pb, w/ V0 bits, no TOF, w/o event filtering", false); PROCESS_SWITCH(TableMaker, processPbPbMuonOnly, "Build muon only DQ skimmed data model typically for Pb-Pb, w/o event filtering", false); + PROCESS_SWITCH(TableMaker, processPbPbWithFilterMuonOnly, "Build muon only DQ skimmed data model typically for UPC Pb-Pb, w/ event filtering", false); PROCESS_SWITCH(TableMaker, processPbPbStreamMuonOnly, "Build muon only DQ skimmed data model for Pb-Pb, with event properties and flow for streaming", false); PROCESS_SWITCH(TableMaker, processPbPbRealignedMuonOnly, "Build realigned muon only DQ skimmed data model typically for Pb-Pb, w/o event filtering", false); PROCESS_SWITCH(TableMaker, processPbPbMuonMFT, "Build muon + mft DQ skimmed data model typically for Pb-Pb, w/o event filtering", false); PROCESS_SWITCH(TableMaker, processOnlyBCs, "Analyze the BCs to store sampled lumi", false); }; -void DefineHistograms(HistogramManager* histMan, TString histClasses, Configurable configVar) +void DefineHistograms(HistogramManager* histMan, const TString& histClasses, const Configurable& configVar) { // // Define here the histograms for all the classes required in analysis. @@ -2069,7 +2079,7 @@ void DefineHistograms(HistogramManager* histMan, TString histClasses, Configurab // The histogram classes and their components histograms are defined below depending on the name of the histogram class // std::unique_ptr objArray(histClasses.Tokenize(";")); - for (Int_t iclass = 0; iclass < objArray->GetEntries(); ++iclass) { + for (int iclass = 0; iclass < objArray->GetEntries(); ++iclass) { TString classStr = objArray->At(iclass)->GetName(); histMan->AddHistClass(classStr.Data()); diff --git a/PWGDQ/Tasks/CMakeLists.txt b/PWGDQ/Tasks/CMakeLists.txt index 4bb0cf6d714..3295ffff241 100644 --- a/PWGDQ/Tasks/CMakeLists.txt +++ b/PWGDQ/Tasks/CMakeLists.txt @@ -15,7 +15,37 @@ o2physics_add_dpl_workflow(table-reader COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(table-reader-with-assoc - SOURCES tableReader_withAssoc.cxx + SOURCES tableReader_withAssoc_workflowSpec.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2Physics::PWGDQCore O2Physics::MLCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(table-reader-with-assoc-same-event-pairing-barrel-only + SOURCES tableReader_withAssoc_SameEventPairingBarrelOnly_workflowSpec.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2Physics::PWGDQCore O2Physics::MLCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(table-reader-with-assoc-same-event-pairing-muon-only + SOURCES tableReader_withAssoc_SameEventPairingMuonOnly_workflowSpec.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2Physics::PWGDQCore O2Physics::MLCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(table-reader-with-assoc-same-event-pairing + SOURCES tableReader_withAssoc_SameEventPairing_workflowSpec.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2Physics::PWGDQCore O2Physics::MLCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(table-reader-with-assoc-asymmetric-pairing + SOURCES tableReader_withAssoc_AsymmetricPairing_workflowSpec.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2Physics::PWGDQCore O2Physics::MLCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(table-reader-with-assoc-dilepton-track-pairing + SOURCES tableReader_withAssoc_DileptonTrackPairing_workflowSpec.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2Physics::PWGDQCore O2Physics::MLCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(table-reader-with-assoc-dilepton-track-track-pairing + SOURCES tableReader_withAssoc_DileptonTrackTrackPairing_workflowSpec.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2Physics::PWGDQCore O2Physics::MLCore COMPONENT_NAME Analysis) @@ -163,3 +193,8 @@ o2physics_add_dpl_workflow(muon-global-alignment SOURCES muonGlobalAlignment.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGDQCore O2::MCHGeometryTransformer COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(global-muon-matcher + SOURCES global-muon-matcher.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGDQCore O2::MCHGeometryTransformer + COMPONENT_NAME Analysis) diff --git a/PWGDQ/Tasks/DalitzSelection.cxx b/PWGDQ/Tasks/DalitzSelection.cxx index e44e1cac782..76b01e073bf 100644 --- a/PWGDQ/Tasks/DalitzSelection.cxx +++ b/PWGDQ/Tasks/DalitzSelection.cxx @@ -33,12 +33,14 @@ #include #include -#include #include #include #include #include +#include +#include #include +#include #include #include diff --git a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx index 4ea4e79e70e..42c42441774 100644 --- a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx +++ b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -47,6 +48,7 @@ #include #include #include +#include #include #include @@ -59,7 +61,6 @@ #include #include #include -#include #include #include #include @@ -67,10 +68,6 @@ #include #include -using std::cout; -using std::endl; -using std::string; - using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -272,16 +269,23 @@ constexpr static uint32_t gkMuonFillMap = VarManager::ObjTypes::ReducedMuon | Va constexpr static uint32_t gkMuonFillMapWithCov = VarManager::ObjTypes::ReducedMuon | VarManager::ObjTypes::ReducedMuonExtra | VarManager::ObjTypes::ReducedMuonCov; // constexpr static uint32_t gkMuonFillMapWithColl = VarManager::ObjTypes::ReducedMuon | VarManager::ObjTypes::ReducedMuonExtra | VarManager::ObjTypes::ReducedMuonCollInfo; +namespace dqefficiency_helpers +{ +inline float* varValues() { return static_cast(VarManager::fgValues); } +inline TString* varNames() { return static_cast(VarManager::fgVariableNames); } +inline TString* varUnits() { return static_cast(VarManager::fgVariableUnits); } +} // namespace dqefficiency_helpers + // Global function used to define needed histogram classes -void DefineHistograms(HistogramManager* histMan, TString histClasses, const char* histGroups); // defines histograms for all tasks +void DefineHistograms(HistogramManager* histMan, const TString& histClasses, const char* histGroups); // defines histograms for all tasks -template -void PrintBitMap(TMap map, int nbits) -{ - for (int i = 0; i < nbits; i++) { - cout << ((map & (TMap(1) << i)) > 0 ? "1" : "0"); - } -} +// template +// void PrintBitMap(TMap map, int nbits) +// { +// for (int i = 0; i < nbits; i++) { +// cout << ((map & (TMap(1) << i)) > 0 ? "1" : "0"); +// } +// } // Analysis task that produces event decisions and the Hash table used in event mixing struct AnalysisEventSelection { @@ -307,15 +311,15 @@ struct AnalysisEventSelection { HistogramManager* fHistMan = nullptr; MixingHandler* fMixHandler = nullptr; - AnalysisCompositeCut* fEventCut; + AnalysisCompositeCut* fEventCut = nullptr; - Service fCCDB; + Service fCCDB{}; o2::ccdb::CcdbApi fCCDBApi; std::map fSelMap; // key: reduced event global index, value: event selection decision std::map> fBCCollMap; // key: global BC, value: vector of reduced event global indices - std::map fMetadataRCT, fHeader; - int fCurrentRun; + std::map fMetadataRCT, fHeader; + int fCurrentRun = -1; void init(o2::framework::InitContext& context) { @@ -336,7 +340,7 @@ struct AnalysisEventSelection { TString eventCutJSONStr = fConfigEventCutsJSON.value; if (eventCutJSONStr != "") { std::vector jsonCuts = dqcuts::GetCutsFromJSON(eventCutJSONStr.Data()); - for (auto& cutIt : jsonCuts) { + for (auto const& cutIt : jsonCuts) { fEventCut->AddCut(cutIt); } } @@ -346,7 +350,7 @@ struct AnalysisEventSelection { if (fConfigQA) { fHistMan = new HistogramManager("analysisHistos", "", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(kTRUE); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqefficiency_helpers::varNames(), dqefficiency_helpers::varUnits()); DefineHistograms(fHistMan, "Event_BeforeCuts;Event_AfterCuts;", fConfigAddEventHistogram.value.data()); if (fConfigCheckSplitCollisions) { DefineHistograms(fHistMan, "OutOfBunchCorrelations;SameBunchCorrelations;", ""); @@ -388,7 +392,7 @@ struct AnalysisEventSelection { fSelMap.clear(); fBCCollMap.clear(); - for (auto& event : events) { + for (auto const& event : events) { // Reset the fValues array and fill event observables VarManager::ResetValues(0, VarManager::kNEventWiseVariables); VarManager::FillEvent(event); @@ -399,11 +403,11 @@ struct AnalysisEventSelection { bool decision = false; // if QA is requested fill histograms before event selections if (fConfigQA) { - fHistMan->FillHistClass("Event_BeforeCuts", VarManager::fgValues); // automatically fill all the histograms in the class Event + fHistMan->FillHistClass("Event_BeforeCuts", dqefficiency_helpers::varValues()); // automatically fill all the histograms in the class Event } - if (fEventCut->IsSelected(VarManager::fgValues)) { + if (fEventCut->IsSelected(dqefficiency_helpers::varValues())) { if (fConfigQA) { - fHistMan->FillHistClass("Event_AfterCuts", VarManager::fgValues); + fHistMan->FillHistClass("Event_AfterCuts", dqefficiency_helpers::varValues()); } decision = true; } @@ -416,17 +420,17 @@ struct AnalysisEventSelection { evIndices.push_back(event.globalIndex()); } if (fMixHandler != nullptr) { - int hh = fMixHandler->FindEventCategory(VarManager::fgValues); + int hh = fMixHandler->FindEventCategory(dqefficiency_helpers::varValues()); hash(hh); } } - for (auto& event : mcEvents) { + for (auto const& event : mcEvents) { // Reset the fValues array and fill event observables VarManager::ResetValues(0, VarManager::kNEventWiseVariables); VarManager::FillEvent(event); if (fConfigQA) { - fHistMan->FillHistClass("EventsMC", VarManager::fgValues); + fHistMan->FillHistClass("EventsMC", dqefficiency_helpers::varValues()); } } } @@ -455,7 +459,7 @@ struct AnalysisEventSelection { collisionSplittingMap[*ev1It] = true; collisionSplittingMap[*ev2It] = true; } - fHistMan->FillHistClass("SameBunchCorrelations", VarManager::fgValues); + fHistMan->FillHistClass("SameBunchCorrelations", dqefficiency_helpers::varValues()); } // end second event loop } // end first event loop } // end if BC1 events > 1 @@ -469,10 +473,10 @@ struct AnalysisEventSelection { auto const& bc2Events = bc2It->second; // loop over events in the first BC - for (auto ev1It : bc1Events) { + for (const auto& ev1It : bc1Events) { auto ev1 = events.rawIteratorAt(ev1It); // loop over events in the second BC - for (auto ev2It : bc2Events) { + for (const auto& ev2It : bc2Events) { auto ev2 = events.rawIteratorAt(ev2It); // compute 2-event quantities and mark the candidate split collisions VarManager::FillTwoEvents(ev1, ev2); @@ -480,15 +484,15 @@ struct AnalysisEventSelection { collisionSplittingMap[ev1It] = true; collisionSplittingMap[ev2It] = true; } - fHistMan->FillHistClass("OutOfBunchCorrelations", VarManager::fgValues); + fHistMan->FillHistClass("OutOfBunchCorrelations", dqefficiency_helpers::varValues()); } } } } // publish the table - uint32_t evSel = static_cast(0); - for (auto& event : events) { + auto evSel = static_cast(0); + for (auto const& event : events) { evSel = 0; if (fSelMap[event.globalIndex()]) { // event passed the user cuts evSel |= (static_cast(1) << 0); @@ -511,7 +515,7 @@ struct AnalysisEventSelection { } void processFillEvents(MyEvents const& events) // Used to forward the event table from tablemaker, typical use for now is jet analysis. { - for (auto& event : events) { + for (auto const& event : events) { JetEvents(event.tag_raw(), event.runNumber(), event.posX(), @@ -522,7 +526,7 @@ struct AnalysisEventSelection { event.collisionTimeRes()); } } - void processDummy(MyEvents&) + void processDummy(MyEvents const&) { // do nothing } @@ -554,15 +558,15 @@ struct AnalysisTrackSelection { Configurable fConfigMCSignals{"cfgTrackMCSignals", "", "Comma separated list of MC signals"}; Configurable fConfigMCSignalsJSON{"cfgTrackMCsignalsJSON", "", "Additional list of MC signals via JSON"}; - Service fCCDB; + Service fCCDB{}; - HistogramManager* fHistMan; + HistogramManager* fHistMan = nullptr; std::vector fTrackCuts; std::vector fMCSignals; // list of signals to be checked std::vector fHistNamesReco; std::vector fHistNamesMCMatched; - int fCurrentRun; // current run (needed to detect run changes for loading CCDB parameters) + int fCurrentRun = 0; // current run (needed to detect run changes for loading CCDB parameters) std::map> fNAssocsInBunch; // key: track global index, value: vector of global index for events associated in-bunch (events that have in-bunch pileup or splitting) std::map> fNAssocsOutOfBunch; // key: track global index, value: vector of global index for events associated out-of-bunch (events that have no in-bunch pileup) @@ -586,8 +590,8 @@ struct AnalysisTrackSelection { TString addTrackCutsStr = fConfigCutsJSON.value; if (addTrackCutsStr != "") { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); - for (auto& t : addTrackCuts) { - fTrackCuts.push_back(reinterpret_cast(t)); + for (auto const& t : addTrackCuts) { + fTrackCuts.push_back(static_cast(t)); } } VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill @@ -608,7 +612,7 @@ struct AnalysisTrackSelection { TString addMCSignalsStr = fConfigMCSignalsJSON.value; if (addMCSignalsStr != "") { std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); - for (auto& mcIt : addMCSignals) { + for (auto const& mcIt : addMCSignals) { if (mcIt->GetNProngs() != 1) { // NOTE: only 1 prong signals continue; } @@ -619,16 +623,16 @@ struct AnalysisTrackSelection { if (fConfigQA) { fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(kTRUE); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqefficiency_helpers::varNames(), dqefficiency_helpers::varUnits()); // Configure histogram classes for each track cut; // Add histogram classes for each track cut and for each requested MC signal (reconstructed tracks with MC truth) TString histClasses = "AssocsBarrel_BeforeCuts;"; - for (auto& cut : fTrackCuts) { + for (auto const& cut : fTrackCuts) { TString nameStr = Form("AssocsBarrel_%s", cut->GetName()); fHistNamesReco.push_back(nameStr); histClasses += Form("%s;", nameStr.Data()); - for (auto& sig : fMCSignals) { + for (auto const& sig : fMCSignals) { TString nameStr2 = Form("AssocsCorrectBarrel_%s_%s", cut->GetName(), sig->GetName()); fHistNamesMCMatched.push_back(nameStr2); histClasses += Form("%s;", nameStr2.Data()); @@ -673,7 +677,7 @@ struct AnalysisTrackSelection { VarManager::SetCalibrationObject(VarManager::kTPCProtonSigma, calibList->FindObject("sigma_map_proton")); } - o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp(grpmagPath, events.begin().timestamp()); + auto grpmag = fCCDB->getForTimeStamp(grpmagPath, events.begin().timestamp()); if (grpmag != nullptr) { VarManager::SetMagneticField(grpmag->getNominalL3Field()); } else { @@ -687,7 +691,7 @@ struct AnalysisTrackSelection { trackAmbiguities.reserve(tracks.size()); // Loop over associations - for (auto& assoc : assocs) { + for (auto const& assoc : assocs) { auto event = assoc.template reducedevent_as(); if (!event.isEventSelected_bit(0)) { trackSel(0); @@ -717,16 +721,16 @@ struct AnalysisTrackSelection { } if (fConfigQA) { - fHistMan->FillHistClass("AssocsBarrel_BeforeCuts", VarManager::fgValues); + fHistMan->FillHistClass("AssocsBarrel_BeforeCuts", dqefficiency_helpers::varValues()); } int iCut = 0; - uint32_t filterMap = static_cast(0); + auto filterMap = static_cast(0); for (auto cut = fTrackCuts.begin(); cut != fTrackCuts.end(); cut++, iCut++) { - if ((*cut)->IsSelected(VarManager::fgValues)) { + if ((*cut)->IsSelected(dqefficiency_helpers::varValues())) { filterMap |= (static_cast(1) << iCut); if (fConfigQA) { - fHistMan->FillHistClass(fHistNamesReco[iCut], VarManager::fgValues); + fHistMan->FillHistClass(fHistNamesReco[iCut], dqefficiency_helpers::varValues()); } } } // end loop over cuts @@ -744,9 +748,9 @@ struct AnalysisTrackSelection { for (unsigned int icut = 0; icut < fTrackCuts.size(); icut++) { if (filterMap & (static_cast(1) << icut)) { if (isCorrectAssoc) { - fHistMan->FillHistClass(fHistNamesMCMatched[icut * 2 * fMCSignals.size() + 2 * isig].Data(), VarManager::fgValues); + fHistMan->FillHistClass(fHistNamesMCMatched[icut * 2 * fMCSignals.size() + 2 * isig].Data(), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(fHistNamesMCMatched[icut * 2 * fMCSignals.size() + 2 * isig + 1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(fHistNamesMCMatched[icut * 2 * fMCSignals.size() + 2 * isig + 1].Data(), dqefficiency_helpers::varValues()); } } } // end loop over cuts @@ -761,9 +765,9 @@ struct AnalysisTrackSelection { for (unsigned int j = 0; j < fTrackCuts.size(); j++) { if (filterMap & (static_cast(1) << j)) { if (isCorrectAssoc) { - fHistMan->FillHistClass(fHistNamesMCMatched[j * fMCSignals.size() + 2 * i].Data(), VarManager::fgValues); + fHistMan->FillHistClass(fHistNamesMCMatched[j * fMCSignals.size() + 2 * i].Data(), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(fHistNamesMCMatched[j * fMCSignals.size() + 2 * i + 1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(fHistNamesMCMatched[j * fMCSignals.size() + 2 * i + 1].Data(), dqefficiency_helpers::varValues()); } } } // end loop over cuts @@ -799,7 +803,7 @@ struct AnalysisTrackSelection { // So one could QA these tracks separately if (fConfigPublishAmbiguity) { if (fConfigQA) { - for (auto& [trackIdx, evIndices] : fNAssocsInBunch) { + for (auto const& [trackIdx, evIndices] : fNAssocsInBunch) { if (evIndices.size() == 1) { continue; } @@ -807,10 +811,10 @@ struct AnalysisTrackSelection { VarManager::ResetValues(0, VarManager::kNBarrelTrackVariables); VarManager::FillTrack(track); VarManager::fgValues[VarManager::kBarrelNAssocsInBunch] = static_cast(evIndices.size()); - fHistMan->FillHistClass("TrackBarrel_AmbiguityInBunch", VarManager::fgValues); + fHistMan->FillHistClass("TrackBarrel_AmbiguityInBunch", dqefficiency_helpers::varValues()); } // end loop over in-bunch ambiguous tracks - for (auto& [trackIdx, evIndices] : fNAssocsOutOfBunch) { + for (auto const& [trackIdx, evIndices] : fNAssocsOutOfBunch) { if (evIndices.size() == 1) { continue; } @@ -818,12 +822,12 @@ struct AnalysisTrackSelection { VarManager::ResetValues(0, VarManager::kNBarrelTrackVariables); VarManager::FillTrack(track); VarManager::fgValues[VarManager::kBarrelNAssocsOutOfBunch] = static_cast(evIndices.size()); - fHistMan->FillHistClass("TrackBarrel_AmbiguityOutOfBunch", VarManager::fgValues); + fHistMan->FillHistClass("TrackBarrel_AmbiguityOutOfBunch", dqefficiency_helpers::varValues()); } // end loop over out-of-bunch ambiguous tracks } // publish the ambiguity table - for (auto& track : tracks) { + for (auto const& track : tracks) { int8_t nInBunch = 0; if (fNAssocsInBunch.find(track.globalIndex()) != fNAssocsInBunch.end()) { nInBunch = fNAssocsInBunch[track.globalIndex()].size(); @@ -845,7 +849,7 @@ struct AnalysisTrackSelection { { runTrackSelection(assocs, events, tracks, eventsMC, tracksMC); } - void processDummy(MyEvents&) + void processDummy(MyEvents const&) { // do nothing } @@ -877,15 +881,15 @@ struct AnalysisMuonSelection { Configurable fConfigMCSignals{"cfgMuonMCSignals", "", "Comma separated list of MC signals"}; Configurable fConfigMCSignalsJSON{"cfgMuonMCsignalsJSON", "", "Additional list of MC signals via JSON"}; - Service fCCDB; + Service fCCDB{}; - HistogramManager* fHistMan; + HistogramManager* fHistMan = nullptr; std::vector fMuonCuts; std::vector fHistNamesReco; std::vector fHistNamesMCMatched; std::vector fMCSignals; // list of signals to be checked - int fCurrentRun; // current run kept to detect run changes and trigger loading params from CCDB + int fCurrentRun = 0; // current run kept to detect run changes and trigger loading params from CCDB std::map> fNAssocsInBunch; // key: track global index, value: vector of global index for events associated in-bunch (events that have in-bunch pileup or splitting) std::map> fNAssocsOutOfBunch; // key: track global index, value: vector of global index for events associated out-of-bunch (events that have no in-bunch pileup) @@ -909,8 +913,8 @@ struct AnalysisMuonSelection { TString addCutsStr = fConfigCutsJSON.value; if (addCutsStr != "") { std::vector addCuts = dqcuts::GetCutsFromJSON(addCutsStr.Data()); - for (auto& t : addCuts) { - fMuonCuts.push_back(reinterpret_cast(t)); + for (auto const& t : addCuts) { + fMuonCuts.push_back(static_cast(t)); } } VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill @@ -931,7 +935,7 @@ struct AnalysisMuonSelection { TString addMCSignalsStr = fConfigMCSignalsJSON.value; if (addMCSignalsStr != "") { std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); - for (auto& mcIt : addMCSignals) { + for (auto const& mcIt : addMCSignals) { if (mcIt->GetNProngs() != 1) { // NOTE: only 1 prong signals continue; } @@ -942,16 +946,16 @@ struct AnalysisMuonSelection { if (fConfigQA) { fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(kTRUE); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqefficiency_helpers::varNames(), dqefficiency_helpers::varUnits()); // Configure histogram classes for each track cut; // Add histogram classes for each track cut and for each requested MC signal (reconstructed tracks with MC truth) TString histClasses = "AssocsMuon_BeforeCuts;"; - for (auto& cut : fMuonCuts) { + for (auto const& cut : fMuonCuts) { TString nameStr = Form("AssocsMuon_%s", cut->GetName()); fHistNamesReco.push_back(nameStr); histClasses += Form("%s;", nameStr.Data()); - for (auto& sig : fMCSignals) { + for (auto const& sig : fMCSignals) { TString nameStr2 = Form("AssocsCorrectMuon_%s_%s", cut->GetName(), sig->GetName()); fHistNamesMCMatched.push_back(nameStr2); histClasses += Form("%s;", nameStr2.Data()); @@ -983,7 +987,7 @@ struct AnalysisMuonSelection { void runMuonSelection(ReducedMuonsAssoc const& assocs, TEvents const& events, TMuons const& muons, ReducedMCEvents const& /*eventsMC*/, ReducedMCTracks const& muonsMC) { if (events.size() > 0 && fCurrentRun != events.begin().runNumber()) { - o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp(grpmagPath, events.begin().timestamp()); + auto grpmag = fCCDB->getForTimeStamp(grpmagPath, events.begin().timestamp()); if (grpmag != nullptr) { o2::base::Propagator::initFieldFromGRP(grpmag); VarManager::SetMagneticField(grpmag->getNominalL3Field()); @@ -999,7 +1003,7 @@ struct AnalysisMuonSelection { fNAssocsOutOfBunch.clear(); muonSel.reserve(assocs.size()); - for (auto& assoc : assocs) { + for (auto const& assoc : assocs) { auto event = assoc.template reducedevent_as(); if (!event.has_reducedMCevent() || !event.isEventSelected_bit(0)) { // condition on reducedMCevent to avoid rec. events with no generated event muonSel(0); @@ -1022,16 +1026,16 @@ struct AnalysisMuonSelection { } if (fConfigQA) { - fHistMan->FillHistClass("AssocsMuon_BeforeCuts", VarManager::fgValues); + fHistMan->FillHistClass("AssocsMuon_BeforeCuts", dqefficiency_helpers::varValues()); } int iCut = 0; - uint32_t filterMap = static_cast(0); + auto filterMap = static_cast(0); for (auto cut = fMuonCuts.begin(); cut != fMuonCuts.end(); cut++, iCut++) { - if ((*cut)->IsSelected(VarManager::fgValues)) { + if ((*cut)->IsSelected(dqefficiency_helpers::varValues())) { filterMap |= (static_cast(1) << iCut); if (fConfigQA) { - fHistMan->FillHistClass(fHistNamesReco[iCut].Data(), VarManager::fgValues); + fHistMan->FillHistClass(fHistNamesReco[iCut].Data(), dqefficiency_helpers::varValues()); } } } // end loop over cuts @@ -1049,7 +1053,7 @@ struct AnalysisMuonSelection { } // compute MC matching decisions - uint32_t mcDecision = static_cast(0); + auto mcDecision = static_cast(0); int isig = 0; for (auto sig = fMCSignals.begin(); sig != fMCSignals.end(); sig++, isig++) { if constexpr ((TMuonFillMap & VarManager::ObjTypes::ReducedMuon) > 0) { @@ -1069,9 +1073,9 @@ struct AnalysisMuonSelection { for (unsigned int j = 0; j < fMuonCuts.size(); j++) { if (filterMap & (static_cast(1) << j)) { if (isCorrectAssoc) { - fHistMan->FillHistClass(fHistNamesMCMatched[j * 2 * fMCSignals.size() + 2 * i].Data(), VarManager::fgValues); + fHistMan->FillHistClass(fHistNamesMCMatched[j * 2 * fMCSignals.size() + 2 * i].Data(), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(fHistNamesMCMatched[j * 2 * fMCSignals.size() + 2 * i + 1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(fHistNamesMCMatched[j * 2 * fMCSignals.size() + 2 * i + 1].Data(), dqefficiency_helpers::varValues()); } } } // end loop over cuts @@ -1103,7 +1107,7 @@ struct AnalysisMuonSelection { // TODO: some tracks can be associated to both collisions that have in bunch pileup and collisions from different bunches // So one could QA these tracks separately if (fConfigPublishAmbiguity) { - for (auto& [trackIdx, evIndices] : fNAssocsInBunch) { + for (auto const& [trackIdx, evIndices] : fNAssocsInBunch) { if (evIndices.size() == 1) { continue; } @@ -1111,10 +1115,10 @@ struct AnalysisMuonSelection { VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillTrack(track); VarManager::fgValues[VarManager::kMuonNAssocsInBunch] = static_cast(evIndices.size()); - fHistMan->FillHistClass("Muon_AmbiguityInBunch", VarManager::fgValues); + fHistMan->FillHistClass("Muon_AmbiguityInBunch", dqefficiency_helpers::varValues()); } // end loop over in-bunch ambiguous tracks - for (auto& [trackIdx, evIndices] : fNAssocsOutOfBunch) { + for (auto const& [trackIdx, evIndices] : fNAssocsOutOfBunch) { if (evIndices.size() == 1) { continue; } @@ -1122,11 +1126,11 @@ struct AnalysisMuonSelection { VarManager::ResetValues(0, VarManager::kNVars); VarManager::FillTrack(track); VarManager::fgValues[VarManager::kMuonNAssocsOutOfBunch] = static_cast(evIndices.size()); - fHistMan->FillHistClass("Muon_AmbiguityOutOfBunch", VarManager::fgValues); + fHistMan->FillHistClass("Muon_AmbiguityOutOfBunch", dqefficiency_helpers::varValues()); } // end loop over out-of-bunch ambiguous tracks // publish the ambiguity table - for (auto& track : muons) { + for (auto const& track : muons) { int8_t nInBunch = 0; if (fNAssocsInBunch.find(track.globalIndex()) != fNAssocsInBunch.end()) { nInBunch = fNAssocsInBunch[track.globalIndex()].size(); @@ -1149,7 +1153,7 @@ struct AnalysisMuonSelection { runMuonSelection(assocs, events, muons, eventsMC, tracksMC); } - void processDummy(MyEvents&) + void processDummy(MyEvents const&) { // do nothing } @@ -1175,9 +1179,9 @@ struct AnalysisPrefilterSelection { Configurable fPropTrack{"cfgPropTrack", false, "Propgate tracks to associated collision to recalculate DCA and momentum vector"}; std::map fPrefilterMap; - AnalysisCompositeCut* fPairCut; - uint32_t fPrefilterMask; - int fPrefilterCutBit; + AnalysisCompositeCut* fPairCut = nullptr; + uint32_t fPrefilterMask = 0; + int fPrefilterCutBit = -1; Preslice trackAssocsPerCollision = aod::reducedtrack_association::reducedeventId; @@ -1186,6 +1190,7 @@ struct AnalysisPrefilterSelection { if (context.mOptions.get("processDummy")) { return; } + VarManager::SetDefaultVarNames(); bool runPrefilter = true; // get the list of track cuts to be prefiltered @@ -1212,15 +1217,15 @@ struct AnalysisPrefilterSelection { if (runPrefilter) { // get the list of cuts that were computed in the barrel track-selection task and create a bit mask // to mark just the ones we want to apply a prefilter on - string trackCuts; - getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", trackCuts, false); + std::string trackCuts; + getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", trackCuts, false); TString allTrackCutsStr = trackCuts; - // check also the cuts added via JSON and add them to the string of cuts - getTaskOptionValue(context, "analysis-track-selection", "cfgBarrelTrackCutsJSON", trackCuts, false); + // check also the cuts added via JSON and add them to the std::string of cuts + getTaskOptionValue(context, "analysis-track-selection", "cfgBarrelTrackCutsJSON", trackCuts, false); TString addTrackCutsStr = trackCuts; if (addTrackCutsStr != "") { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); - for (auto& t : addTrackCuts) { + for (auto const& t : addTrackCuts) { allTrackCutsStr += Form(",%s", t->GetName()); } } @@ -1253,7 +1258,6 @@ struct AnalysisPrefilterSelection { } VarManager::SetUseVars(AnalysisCut::fgUsedVars); // provide the list of required variables so that VarManager knows what to fill - VarManager::SetDefaultVarNames(); VarManager::SetupTwoProngDCAFitter(5.0f, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, true); // TODO: get these parameters from Configurables VarManager::SetupTwoProngFwdDCAFitter(5.0f, true, 200.0f, 1.0e-3f, 0.9f, true); @@ -1266,7 +1270,7 @@ struct AnalysisPrefilterSelection { return; } - for (auto& [assoc1, assoc2] : o2::soa::combinations(assocs, assocs)) { + for (auto const& [assoc1, assoc2] : o2::soa::combinations(assocs, assocs)) { auto track1 = assoc1.template reducedtrack_as(); auto track2 = assoc2.template reducedtrack_as(); @@ -1282,7 +1286,7 @@ struct AnalysisPrefilterSelection { bool track1Loose = assoc1.isBarrelSelected_bit(fPrefilterCutBit); bool track2Loose = assoc2.isBarrelSelected_bit(fPrefilterCutBit); - if (!((track1Candidate > 0 && track2Loose) || (track2Candidate > 0 && track1Loose))) { + if ((track1Candidate == 0 || !track2Loose) && (track2Candidate == 0 || !track1Loose)) { continue; } @@ -1292,7 +1296,7 @@ struct AnalysisPrefilterSelection { VarManager::FillPairCollision(event, track1, track2); } // if the pair fullfils the criteria, add an entry into the prefilter map for the two tracks - if (fPairCut->IsSelected(VarManager::fgValues)) { + if (fPairCut->IsSelected(dqefficiency_helpers::varValues())) { if (fPrefilterMap.find(track1.globalIndex()) == fPrefilterMap.end() && track1Candidate > 0) { fPrefilterMap[track1.globalIndex()] = track1Candidate; } @@ -1308,7 +1312,7 @@ struct AnalysisPrefilterSelection { fPrefilterMap.clear(); - for (auto& event : events) { + for (auto const& event : events) { auto groupedAssocs = assocs.sliceBy(trackAssocsPerCollision, event.globalIndex()); if (groupedAssocs.size() > 1) { runPrefilter(event, groupedAssocs, tracks); @@ -1322,11 +1326,11 @@ struct AnalysisPrefilterSelection { prefilter(mymap); } } else { - for (auto& assoc : assocs) { + for (auto const& assoc : assocs) { // TODO: just use the index from the assoc (no need to cast the whole track) auto track = assoc.template reducedtrack_as(); mymap = -1; - if (fPrefilterMap.find(track.globalIndex()) != fPrefilterMap.end()) { + if (fPrefilterMap.contains(track.globalIndex())) { // NOTE: publish the bitwise negated bits (~), so there will be zeroes for cuts that failed the prefiltering and 1 everywhere else mymap = ~fPrefilterMap[track.globalIndex()]; prefilter(mymap); @@ -1337,7 +1341,7 @@ struct AnalysisPrefilterSelection { } } - void processDummy(MyEvents&) + void processDummy(MyEvents const&) { // do nothing } @@ -1368,7 +1372,7 @@ struct AnalysisSameEventPairing { Produces dileptonPolarList; o2::base::MatLayerCylSet* fLUT = nullptr; - int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. + int fCurrentRun = -1; // needed to detect if the run changed and trigger update of calibrations etc. OutputObj fOutputList{"output"}; @@ -1425,15 +1429,15 @@ struct AnalysisSameEventPairing { // Track related options Configurable fPropTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"}; - Service fCCDB; + Service fCCDB{}; // PDG database - Service pdgDB; + Service pdgDB{}; // Filter filterEventSelected = aod::dqanalysisflags::isEventSelected & uint32_t(1); Filter eventFilter = aod::dqanalysisflags::isEventSelected > static_cast(0); - HistogramManager* fHistMan; + HistogramManager* fHistMan = nullptr; // keep histogram class names in maps, so we don't have to buld their names in the pair loops std::map> fTrackHistNames; @@ -1451,17 +1455,17 @@ struct AnalysisSameEventPairing { std::vector fMCGenAccCuts; bool fUseMCGenAccCut = false; - uint32_t fTrackFilterMask; // mask for the track cuts required in this task to be applied on the barrel cuts produced upstream - uint32_t fMuonFilterMask; // mask for the muon cuts required in this task to be applied on the muon cuts produced upstream - int fNCutsBarrel; - int fNCutsMuon; - int fNPairCuts; + uint32_t fTrackFilterMask = 0; // mask for the track cuts required in this task to be applied on the barrel cuts produced upstream + uint32_t fMuonFilterMask = 0; // mask for the muon cuts required in this task to be applied on the muon cuts produced upstream + int fNCutsBarrel = 0; + int fNCutsMuon = 0; + int fNPairCuts = 0; bool fHasTwoProngGenMCsignals = false; - bool fEnableBarrelHistos; - bool fEnableMuonHistos; - bool fEnableBarrelMuonHistos; - bool fEnableBarrelMuonMixingHistos; + bool fEnableBarrelHistos = false; + bool fEnableMuonHistos = false; + bool fEnableBarrelMuonHistos = false; + bool fEnableBarrelMuonMixingHistos = false; Preslice> trackAssocsPerCollision = aod::reducedtrack_association::reducedeventId; Preslice> muonAssocsPerCollision = aod::reducedtrack_association::reducedeventId; @@ -1522,7 +1526,7 @@ struct AnalysisSameEventPairing { TString addMCSignalsStr = fConfigMC.recSignalsJSON.value; if (addMCSignalsStr != "") { std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); - for (auto& mcIt : addMCSignals) { + for (auto const& mcIt : addMCSignals) { if (mcIt->GetNProngs() != 2) { // NOTE: only 2 prong signals continue; } @@ -1545,7 +1549,7 @@ struct AnalysisSameEventPairing { TString addEmuMCSignalsStr = fConfigMC.emuRecSignalsJSON.value; if (addEmuMCSignalsStr != "") { std::vector addEmuMCSignals = dqmcsignals::GetMCSignalsFromJSON(addEmuMCSignalsStr.Data()); - for (auto& mcIt : addEmuMCSignals) { + for (auto const& mcIt : addEmuMCSignals) { if (mcIt->GetNProngs() != 2) { continue; } @@ -1554,15 +1558,15 @@ struct AnalysisSameEventPairing { } // get the barrel track selection cuts - string tempCuts; - getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", tempCuts, false); + std::string tempCuts; + getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", tempCuts, false); TString tempCutsStr = tempCuts; - // check also the cuts added via JSON and add them to the string of cuts - getTaskOptionValue(context, "analysis-track-selection", "cfgBarrelTrackCutsJSON", tempCuts, false); + // check also the cuts added via JSON and add them to the std::string of cuts + getTaskOptionValue(context, "analysis-track-selection", "cfgBarrelTrackCutsJSON", tempCuts, false); TString addTrackCutsStr = tempCuts; if (addTrackCutsStr != "") { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); - for (auto& t : addTrackCuts) { + for (auto const& t : addTrackCuts) { tempCutsStr += Form(",%s", t->GetName()); } } @@ -1594,7 +1598,7 @@ struct AnalysisSameEventPairing { names.push_back(Form("PairsBarrelSEPP_ambiguousOutOfBunch_%s", objArray->At(icut)->GetName())); names.push_back(Form("PairsBarrelSEMM_ambiguousOutOfBunch_%s", objArray->At(icut)->GetName())); } - for (auto& n : names) { + for (auto const& n : names) { histNames += Form("%s;", n.Data()); } fTrackHistNames[icut] = names; @@ -1602,9 +1606,9 @@ struct AnalysisSameEventPairing { // if there are pair cuts specified, assign hist directories for each barrel cut - pair cut combination // NOTE: This could possibly lead to large histogram outputs. It is strongly advised to use pair cuts only // if you know what you are doing. - TString cutNamesStr = fConfigCuts.pair.value; - if (!cutNamesStr.IsNull()) { // if pair cuts - std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); + TString pairCutNamesStr = fConfigCuts.pair.value; + if (!pairCutNamesStr.IsNull()) { // if pair cuts + std::unique_ptr objArrayPair(pairCutNamesStr.Tokenize(",")); fNPairCuts = objArrayPair->GetEntries(); for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { // loop over pair cuts names = { @@ -1635,7 +1639,7 @@ struct AnalysisSameEventPairing { names.push_back(Form("PairsBarrelSEPM_ambiguousOutOfBunchCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); names.push_back(Form("PairsBarrelSEPM_ambiguousOutOfBunchIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); } - for (auto& n : names) { + for (auto const& n : names) { histNames += Form("%s;", n.Data()); } fBarrelHistNamesMCmatched.try_emplace(icut * fRecMCSignals.size() + isig, names); @@ -1647,14 +1651,14 @@ struct AnalysisSameEventPairing { } // get the muon track selection cuts - getTaskOptionValue(context, "analysis-muon-selection", "cfgMuonCuts", tempCuts, false); + getTaskOptionValue(context, "analysis-muon-selection", "cfgMuonCuts", tempCuts, false); tempCutsStr = tempCuts; - // check also the cuts added via JSON and add them to the string of cuts - getTaskOptionValue(context, "analysis-muon-selection", "cfgMuonCutsJSON", tempCuts, false); + // check also the cuts added via JSON and add them to the std::string of cuts + getTaskOptionValue(context, "analysis-muon-selection", "cfgMuonCutsJSON", tempCuts, false); TString addMuonCutsStr = tempCuts; if (addMuonCutsStr != "") { std::vector addMuonCuts = dqcuts::GetCutsFromJSON(addMuonCutsStr.Data()); - for (auto& t : addMuonCuts) { + for (auto const& t : addMuonCuts) { tempCutsStr += Form(",%s", t->GetName()); } } @@ -1685,15 +1689,15 @@ struct AnalysisSameEventPairing { names.push_back(Form("PairsMuonSEPP_ambiguousOutOfBunch_%s", objArray->At(icut)->GetName())); names.push_back(Form("PairsMuonSEMM_ambiguousOutOfBunch_%s", objArray->At(icut)->GetName())); } - for (auto& n : names) { + for (auto const& n : names) { histNames += Form("%s;", n.Data()); } fMuonHistNames[icut] = names; // if there are specified pair cuts, assign hist dirs for each muon cut - pair cut combination - TString cutNamesStr = fConfigCuts.pair.value; - if (!cutNamesStr.IsNull()) { // if pair cuts - std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); + TString pairCutNamesStr = fConfigCuts.pair.value; + if (!pairCutNamesStr.IsNull()) { // if pair cuts + std::unique_ptr objArrayPair(pairCutNamesStr.Tokenize(",")); fNPairCuts = objArrayPair->GetEntries(); for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { // loop over pair cuts names = { @@ -1724,7 +1728,7 @@ struct AnalysisSameEventPairing { names.push_back(Form("PairsMuonSEPM_ambiguousOutOfBunchCorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); names.push_back(Form("PairsMuonSEPM_ambiguousOutOfBunchIncorrectAssoc_%s_%s", objArray->At(icut)->GetName(), sig->GetName())); } - for (auto& n : names) { + for (auto const& n : names) { histNames += Form("%s;", n.Data()); } fMuonHistNamesMCmatched.try_emplace(icut * fRecMCSignals.size() + isig, names); @@ -1738,27 +1742,27 @@ struct AnalysisSameEventPairing { // build the hist directories for e-mu pairs (track cut x muon cut [x pair cut]) and for the MC matched variants if (fEnableBarrelMuonHistos || fEnableBarrelMuonMixingHistos) { // re-fetch the barrel cut list from upstream (we lost it when the muon block reused tempCuts/tempCutsStr) - string tempBarrelCutsStr; - getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", tempBarrelCutsStr, false); + std::string tempBarrelCutsStr; + getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", tempBarrelCutsStr, false); TString barrelCutsAll = tempBarrelCutsStr; - getTaskOptionValue(context, "analysis-track-selection", "cfgBarrelTrackCutsJSON", tempBarrelCutsStr, false); + getTaskOptionValue(context, "analysis-track-selection", "cfgBarrelTrackCutsJSON", tempBarrelCutsStr, false); TString barrelCutsJSONStr = tempBarrelCutsStr; if (barrelCutsJSONStr != "") { std::vector addCuts = dqcuts::GetCutsFromJSON(barrelCutsJSONStr.Data()); - for (auto& t : addCuts) { + for (auto const& t : addCuts) { barrelCutsAll += Form(",%s", t->GetName()); } } std::unique_ptr objArrayBarrel(barrelCutsAll.Tokenize(",")); - string tempMuonCutsStr; - getTaskOptionValue(context, "analysis-muon-selection", "cfgMuonCuts", tempMuonCutsStr, false); + std::string tempMuonCutsStr; + getTaskOptionValue(context, "analysis-muon-selection", "cfgMuonCuts", tempMuonCutsStr, false); TString muonCutsAll = tempMuonCutsStr; - getTaskOptionValue(context, "analysis-muon-selection", "cfgMuonCutsJSON", tempMuonCutsStr, false); + getTaskOptionValue(context, "analysis-muon-selection", "cfgMuonCutsJSON", tempMuonCutsStr, false); TString muonCutsJSONStr = tempMuonCutsStr; if (muonCutsJSONStr != "") { std::vector addCuts = dqcuts::GetCutsFromJSON(muonCutsJSONStr.Data()); - for (auto& t : addCuts) { + for (auto const& t : addCuts) { muonCutsAll += Form(",%s", t->GetName()); } } @@ -1833,7 +1837,7 @@ struct AnalysisSameEventPairing { names.push_back(Form("PairsEleMuSEPM_ambiguousOutOfBunchCorrectAssoc_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); names.push_back(Form("PairsEleMuSEPM_ambiguousOutOfBunchIncorrectAssoc_%s_%s_%s", trackCutName.Data(), muonCutName.Data(), sig->GetName())); } - for (auto& n : names) { + for (auto const& n : names) { histNames += Form("%s;", n.Data()); } int index = iTrack * (fNCutsMuon * fEmuRecMCSignals.size()) + iMuon * fEmuRecMCSignals.size() + isig; @@ -1872,7 +1876,7 @@ struct AnalysisSameEventPairing { TString addMCSignalsGenStr = fConfigMC.genSignalsJSON.value; if (addMCSignalsGenStr != "") { std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsGenStr.Data()); - for (auto& mcIt : addMCSignals) { + for (auto const& mcIt : addMCSignals) { if (mcIt->GetNProngs() > 2) { // NOTE: only 2 prong signals continue; } @@ -1891,7 +1895,7 @@ struct AnalysisSameEventPairing { } if (isMCGen) { - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->GetNProngs() == 1) { histNames += Form("MCTruthGen_%s;", sig->GetName()); // TODO: Add these names to a std::vector to avoid using Form in the process function histNames += Form("MCTruthGenSel_%s;", sig->GetName()); @@ -1903,7 +1907,7 @@ struct AnalysisSameEventPairing { fHasTwoProngGenMCsignals = true; // for these pair level signals, also add histograms for each MCgenAcc cut if specified if (fUseMCGenAccCut) { - for (auto& cut : fMCGenAccCuts) { + for (auto const& cut : fMCGenAccCuts) { histNames += Form("MCTruthGenPairSel_%s_%s;", sig->GetName(), cut->GetName()); histNames += Form("MCTruthGenPseudoPolPairSel_%s_%s;", sig->GetName(), cut->GetName()); } @@ -1931,7 +1935,7 @@ struct AnalysisSameEventPairing { fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(kTRUE); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqefficiency_helpers::varNames(), dqefficiency_helpers::varUnits()); VarManager::SetCollisionSystem((TString)fConfigOptions.collisionSystem, fConfigOptions.centerMassEnergy); // set collision system and center of mass energy @@ -1944,7 +1948,7 @@ struct AnalysisSameEventPairing { void initParamsFromCCDB(uint64_t timestamp, bool withTwoProngFitter = true) { if (fConfigOptions.useRemoteField.value) { - o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp(fConfigCCDB.grpMagPath, timestamp); + auto grpmag = fCCDB->getForTimeStamp(fConfigCCDB.grpMagPath, timestamp); float magField = 0.0; if (grpmag != nullptr) { magField = grpmag->getNominalL3Field(); @@ -1977,7 +1981,7 @@ struct AnalysisSameEventPairing { // Template function to run same event pairing (barrel-barrel, muon-muon, barrel-muon) template - void runSameEventPairing(TEvents const& events, Preslice& preslice, TTrackAssocs const& assocs, TTracks const& /*tracks*/, ReducedMCEvents const& /*mcEvents*/, ReducedMCTracks const& /*mcTracks*/) + void runSameEventPairing(TEvents const& events, Preslice& preslice, TTrackAssocs const& assocs, TTracks const& /*tracks*/, ReducedMCEvents const& /*mcEvents*/, ReducedMCTracks const& mcTracks) { if (events.size() == 0) { LOG(warning) << "No events in this TF, going to the next one ..."; @@ -1999,16 +2003,17 @@ struct AnalysisSameEventPairing { ncuts = fNCutsMuon; } - uint32_t twoTrackFilter = static_cast(0); + auto twoTrackFilter = static_cast(0); int sign1 = 0; int sign2 = 0; - uint32_t mcDecision = static_cast(0); + auto mcDecision = static_cast(0); bool isCorrectAssoc_leg1 = false; bool isCorrectAssoc_leg2 = false; // estimate reserved size int64_t reserveSize = 0; - for (auto& event : events) { + int64_t reserveSizeGen = mcTracks.size(); + for (auto const& event : events) { if (event.isEventSelected_bit(0)) { auto groupedAssocs = assocs.sliceBy(preslice, event.globalIndex()); size_t nGood = 0; @@ -2038,7 +2043,7 @@ struct AnalysisSameEventPairing { dimuonAllList.reserve(reserveSize); } if (useMiniTree.fConfigMiniTree) { - dileptonMiniTreeGen.reserve(reserveSize); + dileptonMiniTreeGen.reserve(reserveSizeGen); dileptonMiniTreeRec.reserve(reserveSize); } if (fConfigOptions.polarTables.value) { @@ -2048,22 +2053,22 @@ struct AnalysisSameEventPairing { constexpr bool eventHasQvector = ((TEventFillMap & VarManager::ObjTypes::ReducedEventQvector) > 0); constexpr bool trackHasCov = ((TTrackFillMap & VarManager::ObjTypes::ReducedTrackBarrelCov) > 0); - for (auto& event : events) { + for (auto const& event : events) { if (!event.has_reducedMCevent() || !event.isEventSelected_bit(0)) { // condition on reducedMCevent to avoid rec. events with no generated event continue; } uint8_t evSel = event.isEventSelected_raw(); // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); - VarManager::FillEvent(event, VarManager::fgValues); - VarManager::FillEvent(event.reducedMCevent(), VarManager::fgValues); + VarManager::FillEvent(event, dqefficiency_helpers::varValues()); + VarManager::FillEvent(event.reducedMCevent(), dqefficiency_helpers::varValues()); auto groupedAssocs = assocs.sliceBy(preslice, event.globalIndex()); if (groupedAssocs.size() == 0) { continue; } - for (auto& [a1, a2] : o2::soa::combinations(groupedAssocs, groupedAssocs)) { + for (auto const& [a1, a2] : o2::soa::combinations(groupedAssocs, groupedAssocs)) { if constexpr (TPairType == VarManager::kDecayToEE) { twoTrackFilter = a1.isBarrelSelected_raw() & a2.isBarrelSelected_raw() & a1.isBarrelSelectedPrefilter_raw() & a2.isBarrelSelectedPrefilter_raw() & fTrackFilterMask; @@ -2115,7 +2120,7 @@ struct AnalysisSameEventPairing { if constexpr (eventHasQvector) { VarManager::FillPairVn(t1, t2); } - if (!fConfigMC.skimSignalOnly || (fConfigMC.skimSignalOnly && mcDecision > 0)) { + if (!fConfigMC.skimSignalOnly || mcDecision > 0) { dielectronList(event.globalIndex(), VarManager::fgValues[VarManager::kMass], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], t1.sign() + t2.sign(), twoTrackFilter, mcDecision); @@ -2158,10 +2163,12 @@ struct AnalysisSameEventPairing { } auto t1 = a1.template reducedmuon_as(); auto t2 = a2.template reducedmuon_as(); - if (t1.matchMCHTrackId() == t2.matchMCHTrackId() && t1.matchMCHTrackId() >= 0) + if (t1.matchMCHTrackId() == t2.matchMCHTrackId() && t1.matchMCHTrackId() >= 0) { continue; - if (t1.matchMFTTrackId() == t2.matchMFTTrackId() && t1.matchMFTTrackId() >= 0) + } + if (t1.matchMFTTrackId() == t2.matchMFTTrackId() && t1.matchMFTTrackId() >= 0) { continue; + } sign1 = t1.sign(); sign2 = t2.sign(); // store the ambiguity number of the two dilepton legs in the last 4 digits of the two-track filter @@ -2248,22 +2255,23 @@ struct AnalysisSameEventPairing { bool isAmbiInBunch = false; bool isAmbiOutOfBunch = false; bool isCorrect_pair = false; - if (isCorrectAssoc_leg1 && isCorrectAssoc_leg2) + if (isCorrectAssoc_leg1 && isCorrectAssoc_leg2) { isCorrect_pair = true; + } for (int icut = 0; icut < ncuts; icut++) { if (twoTrackFilter & (static_cast(1) << icut)) { isAmbiInBunch = (twoTrackFilter & (static_cast(1) << 28)) || (twoTrackFilter & (static_cast(1) << 29)); isAmbiOutOfBunch = (twoTrackFilter & (static_cast(1) << 30)) || (twoTrackFilter & (static_cast(1) << 31)); if (sign1 * sign2 < 0) { // +- pairs - fHistMan->FillHistClass(histNames[icut][0].Data(), VarManager::fgValues); // reconstructed, unmatched + fHistMan->FillHistClass(histNames[icut][0].Data(), dqefficiency_helpers::varValues()); // reconstructed, unmatched for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals if (mcDecision & (static_cast(1) << isig)) { PromptNonPromptSepTable(VarManager::fgValues[VarManager::kMass], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kRap], VarManager::fgValues[VarManager::kPhi], VarManager::fgValues[VarManager::kVertexingTauxyProjected], VarManager::fgValues[VarManager::kVertexingTauxyProjectedPoleJPsiMass], VarManager::fgValues[VarManager::kVertexingTauzProjected], VarManager::fgValues[VarManager::kVertexingTauxyProjectedPoleJPsiMassRecalculatePV], VarManager::fgValues[VarManager::kVtxX], VarManager::fgValues[VarManager::kVtxY], VarManager::fgValues[VarManager::kVtxZ], VarManager::fgValues[VarManager::kDCAxy1], VarManager::fgValues[VarManager::kDCAz1], VarManager::fgValues[VarManager::kITSclusterMap1], VarManager::fgValues[VarManager::kTPCnSigmaEl1], VarManager::fgValues[VarManager::kDCAxy2], VarManager::fgValues[VarManager::kDCAz2], VarManager::fgValues[VarManager::kITSclusterMap2], VarManager::fgValues[VarManager::kTPCnSigmaEl2], isAmbiInBunch, isAmbiOutOfBunch, isCorrect_pair, VarManager::fgValues[VarManager::kMultFT0A], VarManager::fgValues[VarManager::kMultFT0C], VarManager::fgValues[VarManager::kCentFT0M], VarManager::fgValues[VarManager::kVtxNcontribReal]); - fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][0].Data(), VarManager::fgValues); // matched signal + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][0].Data(), dqefficiency_helpers::varValues()); // matched signal if (useMiniTree.fConfigMiniTree) { if constexpr (TPairType == VarManager::kDecayToMuMu) { twoTrackFilter = a1.isMuonSelected_raw() & a2.isMuonSelected_raw() & fMuonFilterMask; @@ -2298,81 +2306,82 @@ struct AnalysisSameEventPairing { } if (fConfigQA) { if (isCorrectAssoc_leg1 && isCorrectAssoc_leg2) { // correct track-collision association - fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][3].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][3].Data(), dqefficiency_helpers::varValues()); } else { // incorrect track-collision association - fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][4].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][4].Data(), dqefficiency_helpers::varValues()); } if (isAmbiInBunch) { // ambiguous in bunch - fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][5].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][5].Data(), dqefficiency_helpers::varValues()); if (isCorrectAssoc_leg1 && isCorrectAssoc_leg2) { - fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][6].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][6].Data(), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][7].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][7].Data(), dqefficiency_helpers::varValues()); } } if (isAmbiOutOfBunch) { // ambiguous out of bunch - fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][8].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][8].Data(), dqefficiency_helpers::varValues()); if (isCorrectAssoc_leg1 && isCorrectAssoc_leg2) { - fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][9].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][9].Data(), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][10].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][10].Data(), dqefficiency_helpers::varValues()); } } } } if (fConfigQA) { if (isAmbiInBunch) { - fHistMan->FillHistClass(histNames[icut][3].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][3].Data(), dqefficiency_helpers::varValues()); } if (isAmbiOutOfBunch) { - fHistMan->FillHistClass(histNames[icut][3 + 3].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][3 + 3].Data(), dqefficiency_helpers::varValues()); } } } } else { if (sign1 > 0) { // ++ pairs - fHistMan->FillHistClass(histNames[icut][1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][1].Data(), dqefficiency_helpers::varValues()); for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals if (mcDecision & (static_cast(1) << isig)) { - fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][1].Data(), dqefficiency_helpers::varValues()); } } if (fConfigQA) { if (isAmbiInBunch) { - fHistMan->FillHistClass(histNames[icut][4].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][4].Data(), dqefficiency_helpers::varValues()); } if (isAmbiOutOfBunch) { - fHistMan->FillHistClass(histNames[icut][4 + 3].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][4 + 3].Data(), dqefficiency_helpers::varValues()); } } } else { // -- pairs - fHistMan->FillHistClass(histNames[icut][2].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][2].Data(), dqefficiency_helpers::varValues()); for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals if (mcDecision & (static_cast(1) << isig)) { - fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][2].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNamesMC[icut * fRecMCSignals.size() + isig][2].Data(), dqefficiency_helpers::varValues()); } } if (fConfigQA) { if (isAmbiInBunch) { - fHistMan->FillHistClass(histNames[icut][5].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][5].Data(), dqefficiency_helpers::varValues()); } if (isAmbiOutOfBunch) { - fHistMan->FillHistClass(histNames[icut][5 + 3].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][5 + 3].Data(), dqefficiency_helpers::varValues()); } } } } for (unsigned int iPairCut = 0; iPairCut < fPairCuts.size(); iPairCut++) { AnalysisCompositeCut cut = fPairCuts.at(iPairCut); - if (!(cut.IsSelected(VarManager::fgValues))) // apply pair cuts + if (!(cut.IsSelected(dqefficiency_helpers::varValues()))) { // apply pair cuts continue; + } if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(histNames[ncuts + icut * fPairCuts.size() + iPairCut][0].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[ncuts + icut * fPairCuts.size() + iPairCut][0].Data(), dqefficiency_helpers::varValues()); } else { if (sign1 > 0) { - fHistMan->FillHistClass(histNames[ncuts + icut * fPairCuts.size() + iPairCut][1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[ncuts + icut * fPairCuts.size() + iPairCut][1].Data(), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(histNames[ncuts + icut * fPairCuts.size() + iPairCut][2].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[ncuts + icut * fPairCuts.size() + iPairCut][2].Data(), dqefficiency_helpers::varValues()); } } } // end loop (pair cuts) @@ -2391,11 +2400,11 @@ struct AnalysisSameEventPairing { int isig = 0; // Loop over all MC single particles to fill generator level histograms, disregarding of whether they belong to selected reconstructed events or not - for (auto& mctrack : mcTracks) { - for (auto& sig : fGenMCSignals) { + for (auto const& mctrack : mcTracks) { + for (auto const& sig : fGenMCSignals) { if (sig->CheckSignal(true, mctrack)) { VarManager::FillTrackMC(mcTracks, mctrack); - fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), dqefficiency_helpers::varValues()); } } } @@ -2405,7 +2414,7 @@ struct AnalysisSameEventPairing { std::vector FinalStateMcParticleIndices; // Now loop over reconstructed events to select only MC particles belonging to the same MC collision as the reconstructed event - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } @@ -2418,18 +2427,18 @@ struct AnalysisSameEventPairing { auto groupedMCTracks = mcTracks.sliceBy(perReducedMcEvent, event.reducedMCeventId()); groupedMCTracks.bindInternalIndicesTo(&mcTracks); - for (auto& track : groupedMCTracks) { + for (auto const& track : groupedMCTracks) { auto track_raw = mcTracks.rawIteratorAt(track.globalIndex()); mcDecision = 0; isig = 0; - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->CheckSignal(true, track_raw)) { if (track.reducedMCeventId() != event.reducedMCeventId()) { // check that the mc track belongs to the same mc collision as the reconstructed event continue; } VarManager::FillTrackMC(mcTracks, track); mcDecision |= (static_cast(1) << isig); - fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), dqefficiency_helpers::varValues()); MCTruthTableEffi(VarManager::fgValues[VarManager::kMCPt], VarManager::fgValues[VarManager::kMCEta], VarManager::fgValues[VarManager::kMCY], VarManager::fgValues[VarManager::kMCPhi], VarManager::fgValues[VarManager::kMCVz], VarManager::fgValues[VarManager::kMCVtxZ], VarManager::fgValues[VarManager::kMultFT0A], VarManager::fgValues[VarManager::kMultFT0C], VarManager::fgValues[VarManager::kCentFT0M], VarManager::fgValues[VarManager::kVtxNcontribReal]); if (useMiniTree.fConfigMiniTree) { @@ -2439,7 +2448,7 @@ struct AnalysisSameEventPairing { } isig++; } - for (auto& sig : fFinalStateMCSignals) { + for (auto const& sig : fFinalStateMCSignals) { if (sig->CheckSignal(true, track_raw)) { FinalStateMcParticleIndices.push_back(track.globalIndex()); break; // if one of the final state signals is matched, no need to check the others @@ -2450,19 +2459,19 @@ struct AnalysisSameEventPairing { if (fHasTwoProngGenMCsignals) { // loop over combinations of the selected mc particles to fill generator level pair histograms - for (auto& t1 : FinalStateMcParticleIndices) { + for (auto const& t1 : FinalStateMcParticleIndices) { auto t1_raw = mcTracks.rawIteratorAt(t1); - for (auto& t2 : FinalStateMcParticleIndices) { + for (auto const& t2 : FinalStateMcParticleIndices) { if (t2 <= t1) { continue; // avoid double counting and self-pairing } - // for (auto& [t1, t2] : combinations(groupedMCTracks, groupedMCTracks)) { + // for (auto const& [t1, t2] : combinations(groupedMCTracks, groupedMCTracks)) { // cout << "Processing pair of mcTracks with globalIndices = " << t1.globalIndex() << ", " << t2.globalIndex() << endl; auto t2_raw = mcTracks.rawIteratorAt(t2); mcDecision = 0; isig = 0; - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->GetNProngs() != 2) { // NOTE: 2-prong signals required here continue; } @@ -2482,14 +2491,14 @@ struct AnalysisSameEventPairing { } } // cout << " Filled VarManager for the pair." << endl; - fHistMan->FillHistClass(Form("MCTruthGenPairSel_%s", sig->GetName()), VarManager::fgValues); - fHistMan->FillHistClass(Form("MCTruthGenPseudoPolPairSel_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGenPairSel_%s", sig->GetName()), dqefficiency_helpers::varValues()); + fHistMan->FillHistClass(Form("MCTruthGenPseudoPolPairSel_%s", sig->GetName()), dqefficiency_helpers::varValues()); // Fill also acceptance cut histograms if requested if (fUseMCGenAccCut) { - for (auto& cut : fMCGenAccCuts) { - if (cut->IsSelected(VarManager::fgValues)) { - fHistMan->FillHistClass(Form("MCTruthGenPairSel_%s_%s", sig->GetName(), cut->GetName()), VarManager::fgValues); - fHistMan->FillHistClass(Form("MCTruthGenPseudoPolPairSel_%s_%s", sig->GetName(), cut->GetName()), VarManager::fgValues); + for (auto const& cut : fMCGenAccCuts) { + if (cut->IsSelected(dqefficiency_helpers::varValues())) { + fHistMan->FillHistClass(Form("MCTruthGenPairSel_%s_%s", sig->GetName(), cut->GetName()), dqefficiency_helpers::varValues()); + fHistMan->FillHistClass(Form("MCTruthGenPseudoPolPairSel_%s_%s", sig->GetName(), cut->GetName()), dqefficiency_helpers::varValues()); } } } @@ -2523,7 +2532,7 @@ struct AnalysisSameEventPairing { const auto& histNames = fTrackMuonHistNames; const auto& histNamesMC = fTrackMuonHistNamesMCmatched; - int nPairCuts = (fPairCuts.size() > 0) ? static_cast(fPairCuts.size()) : 1; + int nPairCuts = !fPairCuts.empty() ? static_cast(fPairCuts.size()) : 1; uint32_t twoTrackFilter = 0; uint32_t mcDecision = 0; @@ -2535,14 +2544,14 @@ struct AnalysisSameEventPairing { constexpr bool eventHasQvector = ((TEventFillMap & VarManager::ObjTypes::ReducedEventQvector) > 0); constexpr bool eventHasQvectorCentr = ((TEventFillMap & VarManager::ObjTypes::CollisionQvect) > 0); - for (auto& event : events) { + for (auto const& event : events) { if (!event.has_reducedMCevent() || !event.isEventSelected_bit(0)) { continue; } VarManager::ResetValues(0, VarManager::kNVars); - VarManager::FillEvent(event, VarManager::fgValues); - VarManager::FillEvent(event.reducedMCevent(), VarManager::fgValues); + VarManager::FillEvent(event, dqefficiency_helpers::varValues()); + VarManager::FillEvent(event.reducedMCevent(), dqefficiency_helpers::varValues()); auto groupedAssocs1 = assocs1.sliceBy(preslice1, event.globalIndex()); if (groupedAssocs1.size() == 0) { @@ -2553,7 +2562,7 @@ struct AnalysisSameEventPairing { continue; } - for (auto& [a1, a2] : o2::soa::combinations(soa::CombinationsFullIndexPolicy(groupedAssocs1, groupedAssocs2))) { + for (auto const& [a1, a2] : o2::soa::combinations(soa::CombinationsFullIndexPolicy(groupedAssocs1, groupedAssocs2))) { if (!(a1.isBarrelSelected_raw() & a1.isBarrelSelectedPrefilter_raw() & fTrackFilterMask)) { continue; } @@ -2632,11 +2641,11 @@ struct AnalysisSameEventPairing { auto itHistBase = histNames.find(iTrack * fNCutsMuon + iMuon); if (itHistBase != histNames.end()) { if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(itHistBase->second[0].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHistBase->second[0].Data(), dqefficiency_helpers::varValues()); } else if (sign1 > 0) { - fHistMan->FillHistClass(itHistBase->second[1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHistBase->second[1].Data(), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(itHistBase->second[2].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHistBase->second[2].Data(), dqefficiency_helpers::varValues()); } } @@ -2644,7 +2653,7 @@ struct AnalysisSameEventPairing { for (int iPairCut = 0; iPairCut < nPairCuts; ++iPairCut) { if (!fPairCuts.empty()) { AnalysisCompositeCut cut = fPairCuts.at(iPairCut); - if (!cut.IsSelected(VarManager::fgValues)) { + if (!cut.IsSelected(dqefficiency_helpers::varValues())) { continue; } } @@ -2657,11 +2666,11 @@ struct AnalysisSameEventPairing { continue; } if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(itHist->second[0].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHist->second[0].Data(), dqefficiency_helpers::varValues()); } else if (sign1 > 0) { - fHistMan->FillHistClass(itHist->second[1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHist->second[1].Data(), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(itHist->second[2].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHist->second[2].Data(), dqefficiency_helpers::varValues()); } } @@ -2680,11 +2689,11 @@ struct AnalysisSameEventPairing { } const auto& mcNames = itHistMC->second; if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(mcNames[0].Data(), VarManager::fgValues); + fHistMan->FillHistClass(mcNames[0].Data(), dqefficiency_helpers::varValues()); } else if (sign1 > 0) { - fHistMan->FillHistClass(mcNames[1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(mcNames[1].Data(), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(mcNames[2].Data(), VarManager::fgValues); + fHistMan->FillHistClass(mcNames[2].Data(), dqefficiency_helpers::varValues()); } if (!fConfigQA || mcNames.size() < 11) { continue; @@ -2692,24 +2701,24 @@ struct AnalysisSameEventPairing { // QA fills (PM only, mirroring the dilepton MC layout: indices 3..10) if (sign1 * sign2 < 0) { if (isCorrectPair) { - fHistMan->FillHistClass(mcNames[3].Data(), VarManager::fgValues); + fHistMan->FillHistClass(mcNames[3].Data(), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(mcNames[4].Data(), VarManager::fgValues); + fHistMan->FillHistClass(mcNames[4].Data(), dqefficiency_helpers::varValues()); } if (isAmbiInBunch) { - fHistMan->FillHistClass(mcNames[5].Data(), VarManager::fgValues); + fHistMan->FillHistClass(mcNames[5].Data(), dqefficiency_helpers::varValues()); if (isCorrectPair) { - fHistMan->FillHistClass(mcNames[6].Data(), VarManager::fgValues); + fHistMan->FillHistClass(mcNames[6].Data(), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(mcNames[7].Data(), VarManager::fgValues); + fHistMan->FillHistClass(mcNames[7].Data(), dqefficiency_helpers::varValues()); } } if (isAmbiOutOfBunch) { - fHistMan->FillHistClass(mcNames[8].Data(), VarManager::fgValues); + fHistMan->FillHistClass(mcNames[8].Data(), dqefficiency_helpers::varValues()); if (isCorrectPair) { - fHistMan->FillHistClass(mcNames[9].Data(), VarManager::fgValues); + fHistMan->FillHistClass(mcNames[9].Data(), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(mcNames[10].Data(), VarManager::fgValues); + fHistMan->FillHistClass(mcNames[10].Data(), dqefficiency_helpers::varValues()); } } } @@ -2724,18 +2733,18 @@ struct AnalysisSameEventPairing { void runEmuMixedPairing(TAssoc1 const& assocs1, TAssoc2 const& assocs2, TTracks1 const& /*tracks1*/, TTracks2 const& /*tracks2*/) { const auto& histNames = fTrackMuonHistNames; - int nPairCuts = (fPairCuts.size() > 0) ? static_cast(fPairCuts.size()) : 1; + int nPairCuts = !fPairCuts.empty() ? static_cast(fPairCuts.size()) : 1; int sign1 = 0; int sign2 = 0; constexpr bool eventHasQvector = ((TEventFillMap & VarManager::ObjTypes::ReducedEventQvector) > 0); constexpr bool eventHasQvectorCentr = ((TEventFillMap & VarManager::ObjTypes::CollisionQvect) > 0); - for (auto& a1 : assocs1) { + for (auto const& a1 : assocs1) { if (!(a1.isBarrelSelected_raw() & a1.isBarrelSelectedPrefilter_raw() & fTrackFilterMask)) { continue; } - for (auto& a2 : assocs2) { + for (auto const& a2 : assocs2) { if (!(a2.isMuonSelected_raw() & fMuonFilterMask)) { continue; } @@ -2764,17 +2773,17 @@ struct AnalysisSameEventPairing { auto itHistBase = histNames.find(iTrack * fNCutsMuon + iMuon); if (itHistBase != histNames.end() && itHistBase->second.size() >= 6) { if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(itHistBase->second[3].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHistBase->second[3].Data(), dqefficiency_helpers::varValues()); } else if (sign1 > 0) { - fHistMan->FillHistClass(itHistBase->second[4].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHistBase->second[4].Data(), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(itHistBase->second[5].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHistBase->second[5].Data(), dqefficiency_helpers::varValues()); } } for (int iPairCut = 0; iPairCut < nPairCuts; ++iPairCut) { if (!fPairCuts.empty()) { AnalysisCompositeCut cut = fPairCuts.at(iPairCut); - if (!cut.IsSelected(VarManager::fgValues)) { + if (!cut.IsSelected(dqefficiency_helpers::varValues())) { continue; } } @@ -2787,11 +2796,11 @@ struct AnalysisSameEventPairing { continue; } if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(itHist->second[3].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHist->second[3].Data(), dqefficiency_helpers::varValues()); } else if (sign1 > 0) { - fHistMan->FillHistClass(itHist->second[4].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHist->second[4].Data(), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(itHist->second[5].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHist->second[5].Data(), dqefficiency_helpers::varValues()); } } } @@ -2807,9 +2816,9 @@ struct AnalysisSameEventPairing { events.bindExternalIndices(&assocs1); events.bindExternalIndices(&assocs2); int mixingDepth = fConfigMixingDepth.value; - for (auto& [event1, event2] : selfCombinations(hashBin, mixingDepth, -1, events, events)) { + for (auto const& [event1, event2] : selfCombinations(hashBin, mixingDepth, -1, events, events)) { VarManager::ResetValues(0, VarManager::kNVars); - VarManager::FillEvent(event1, VarManager::fgValues); + VarManager::FillEvent(event1, dqefficiency_helpers::varValues()); auto groupedAssocs1 = assocs1.sliceBy(preslice1, event1.globalIndex()); groupedAssocs1.bindExternalIndices(&events); @@ -2868,32 +2877,32 @@ struct AnalysisSameEventPairing { uint32_t mcDecision = 0; int isig = 0; - for (auto& mctrack : mcTracks) { + for (auto const& mctrack : mcTracks) { VarManager::FillTrackMC(mcTracks, mctrack); // NOTE: Signals are checked here mostly based on the skimmed MC stack, so depending on the requested signal, the stack could be incomplete. // NOTE: However, the working model is that the decisions on MC signals are precomputed during skimming and are stored in the mcReducedFlags member. // TODO: Use the mcReducedFlags to select signals - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->CheckSignal(true, mctrack)) { - fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), dqefficiency_helpers::varValues()); } } } // Fill Generated histograms taking into account selected collisions - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } if (!event.has_reducedMCevent()) { continue; } - VarManager::FillEvent(event, VarManager::fgValues); - VarManager::FillEvent(event.reducedMCevent(), VarManager::fgValues); + VarManager::FillEvent(event, dqefficiency_helpers::varValues()); + VarManager::FillEvent(event.reducedMCevent(), dqefficiency_helpers::varValues()); // auto groupedMCTracks = mcTracks.sliceBy(perReducedMcGenEvent, event.reducedMCeventId()); // groupedMCTracks.bindInternalIndicesTo(&mcTracks); - // for (auto& track : groupedMCTracks) { - for (auto& track : mcTracks) { + // for (auto const& track : groupedMCTracks) { + for (auto const& track : mcTracks) { if (track.reducedMCeventId() != event.reducedMCeventId()) { continue; } @@ -2902,10 +2911,10 @@ struct AnalysisSameEventPairing { // auto track_raw = groupedMCTracks.rawIteratorAt(track.globalIndex()); mcDecision = 0; isig = 0; - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->CheckSignal(true, track_raw)) { mcDecision |= (static_cast(1) << isig); - fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), dqefficiency_helpers::varValues()); MCTruthTableEffi(VarManager::fgValues[VarManager::kMCPt], VarManager::fgValues[VarManager::kMCEta], VarManager::fgValues[VarManager::kMCY], VarManager::fgValues[VarManager::kMCPhi], VarManager::fgValues[VarManager::kMCVz], VarManager::fgValues[VarManager::kMCVtxZ], VarManager::fgValues[VarManager::kMultFT0A], VarManager::fgValues[VarManager::kMultFT0C], VarManager::fgValues[VarManager::kCentFT0M], VarManager::fgValues[VarManager::kVtxNcontribReal]); if (useMiniTree.fConfigMiniTree) { @@ -2918,24 +2927,24 @@ struct AnalysisSameEventPairing { } } // end loop over reconstructed events if (fHasTwoProngGenMCsignals) { - for (auto& [t1, t2] : combinations(mcTracks, mcTracks)) { + for (auto const& [t1, t2] : combinations(mcTracks, mcTracks)) { auto t1_raw = mcTracks.rawIteratorAt(t1.globalIndex()); auto t2_raw = mcTracks.rawIteratorAt(t2.globalIndex()); if (t1_raw.reducedMCeventId() == t2_raw.reducedMCeventId()) { - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->GetNProngs() != 2) { // NOTE: 2-prong signals required here continue; } if (sig->CheckSignal(true, t1_raw, t2_raw)) { VarManager::FillPairMC(t1, t2); // NOTE: This feature will only work for muons - fHistMan->FillHistClass(Form("MCTruthGenPair_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGenPair_%s", sig->GetName()), dqefficiency_helpers::varValues()); } } } } } // Fill Generated PAIR histograms taking into account selected collisions - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } @@ -2944,7 +2953,7 @@ struct AnalysisSameEventPairing { } if (fHasTwoProngGenMCsignals) { - for (auto& [t1, t2] : combinations(mcTracks, mcTracks)) { + for (auto const& [t1, t2] : combinations(mcTracks, mcTracks)) { if (t1.reducedMCeventId() != event.reducedMCeventId()) { continue; } @@ -2956,14 +2965,14 @@ struct AnalysisSameEventPairing { if (t1_raw.reducedMCeventId() == t2_raw.reducedMCeventId()) { mcDecision = 0; isig = 0; - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->GetNProngs() != 2) { // NOTE: 2-prong signals required here continue; } if (sig->CheckSignal(true, t1_raw, t2_raw)) { mcDecision |= (static_cast(1) << isig); VarManager::FillPairMC(t1, t2); // NOTE: This feature will only work for muons - fHistMan->FillHistClass(Form("MCTruthGenPairSel_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGenPairSel_%s", sig->GetName()), dqefficiency_helpers::varValues()); if (useMiniTree.fConfigMiniTree) { // WARNING! To be checked dileptonMiniTreeGen(mcDecision, -999, t1.pt(), t1.eta(), t1.phi(), t2.pt(), t2.eta(), t2.phi()); @@ -2982,19 +2991,19 @@ struct AnalysisSameEventPairing { uint32_t mcDecision = 0; int isig = 0; - for (auto& mctrack : mcTracks) { + for (auto const& mctrack : mcTracks) { VarManager::FillTrackMC(mcTracks, mctrack); // NOTE: Signals are checked here mostly based on the skimmed MC stack, so depending on the requested signal, the stack could be incomplete. // NOTE: However, the working model is that the decisions on MC signals are precomputed during skimming and are stored in the mcReducedFlags member. // TODO: Use the mcReducedFlags to select signals - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->CheckSignal(true, mctrack)) { - fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), dqefficiency_helpers::varValues()); } } } // Fill Generated histograms taking into account selected collisions - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } @@ -3002,7 +3011,7 @@ struct AnalysisSameEventPairing { continue; } - for (auto& track : mcTracks) { + for (auto const& track : mcTracks) { if (track.reducedMCeventId() != event.reducedMCeventId()) { continue; } @@ -3010,10 +3019,10 @@ struct AnalysisSameEventPairing { auto track_raw = mcTracks.rawIteratorAt(track.globalIndex()); mcDecision = 0; isig = 0; - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->CheckSignal(true, track_raw)) { mcDecision |= (static_cast(1) << isig); - fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), dqefficiency_helpers::varValues()); MCTruthTableEffi(VarManager::fgValues[VarManager::kMCPt], VarManager::fgValues[VarManager::kMCEta], VarManager::fgValues[VarManager::kMCY], VarManager::fgValues[VarManager::kMCPhi], VarManager::fgValues[VarManager::kMCVz], VarManager::fgValues[VarManager::kMCVtxZ], VarManager::fgValues[VarManager::kMultFT0A], VarManager::fgValues[VarManager::kMultFT0C], VarManager::fgValues[VarManager::kCentFT0M], VarManager::fgValues[VarManager::kVtxNcontribReal]); if (useMiniTree.fConfigMiniTree) { @@ -3026,23 +3035,23 @@ struct AnalysisSameEventPairing { } } // end loop over reconstructed events if (fHasTwoProngGenMCsignals) { - for (auto& [t1, t2] : combinations(mcTracks, mcTracks)) { + for (auto const& [t1, t2] : combinations(mcTracks, mcTracks)) { auto t1_raw = mcTracks.rawIteratorAt(t1.globalIndex()); auto t2_raw = mcTracks.rawIteratorAt(t2.globalIndex()); if (t1_raw.reducedMCeventId() == t2_raw.reducedMCeventId()) { - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->GetNProngs() != 2) { // NOTE: 2-prong signals required here continue; } if (sig->CheckSignal(true, t1_raw, t2_raw)) { VarManager::FillPairMC(t1, t2); // NOTE: This feature will only work for muons - fHistMan->FillHistClass(Form("MCTruthGenPair_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGenPair_%s", sig->GetName()), dqefficiency_helpers::varValues()); } } } } } - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } @@ -3053,20 +3062,20 @@ struct AnalysisSameEventPairing { if (fHasTwoProngGenMCsignals) { auto groupedMCTracks = mcTracks.sliceBy(perReducedMcEvent, event.reducedMCeventId()); groupedMCTracks.bindInternalIndicesTo(&mcTracks); - for (auto& [t1, t2] : combinations(groupedMCTracks, groupedMCTracks)) { + for (auto const& [t1, t2] : combinations(groupedMCTracks, groupedMCTracks)) { auto t1_raw = groupedMCTracks.rawIteratorAt(t1.globalIndex()); auto t2_raw = groupedMCTracks.rawIteratorAt(t2.globalIndex()); if (t1_raw.reducedMCeventId() == t2_raw.reducedMCeventId()) { mcDecision = 0; isig = 0; - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->GetNProngs() != 2) { // NOTE: 2-prong signals required here continue; } if (sig->CheckSignal(true, t1_raw, t2_raw)) { mcDecision |= (static_cast(1) << isig); VarManager::FillPairMC(t1, t2); // NOTE: This feature will only work for muons - fHistMan->FillHistClass(Form("MCTruthGenPairSel_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGenPairSel_%s", sig->GetName()), dqefficiency_helpers::varValues()); if (useMiniTree.fConfigMiniTree) { // WARNING! To be checked dileptonMiniTreeGen(mcDecision, -999, t1.pt(), t1.eta(), t1.phi(), t2.pt(), t2.eta(), t2.phi()); @@ -3095,7 +3104,7 @@ struct AnalysisSameEventPairing { runEmuSameSideMixing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, muonAssocsPerCollision, muonAssocs, muons); } - void processDummy(MyEvents&) + void processDummy(MyEvents const&) { // do nothing } @@ -3118,7 +3127,7 @@ struct AnalysisAsymmetricPairing { Produces ditrackExtraList; o2::base::MatLayerCylSet* fLUT = nullptr; - int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. + int fCurrentRun = -1; // needed to detect if the run changed and trigger update of calibrations etc. // Output objects OutputObj fOutputList{"output"}; @@ -3155,32 +3164,32 @@ struct AnalysisAsymmetricPairing { Configurable fConfigMCRecSignalsJSON{"cfgMCRecSignalsJSON", "", "Additional list of MC signals (reconstructed) via JSON"}; Configurable fConfigMCGenSignalsJSON{"cfgMCGenSignalsJSON", "", "Comma separated list of MC signals (generated) via JSON"}; - Service fCCDB; + Service fCCDB{}; - HistogramManager* fHistMan; + HistogramManager* fHistMan = nullptr; std::vector fPairCuts; - int fNPairHistPrefixes; + int fNPairHistPrefixes = 0; std::vector fRecMCSignals; std::vector fGenMCSignals; // Filter masks to find legs in BarrelTrackCuts table - uint32_t fLegAFilterMask; - uint32_t fLegBFilterMask; - uint32_t fLegCFilterMask; + uint32_t fLegAFilterMask = 0; + uint32_t fLegBFilterMask = 0; + uint32_t fLegCFilterMask = 0; // Maps tracking which combination of leg cuts the track cuts participate in std::map fConstructedLegAFilterMasksMap; std::map fConstructedLegBFilterMasksMap; std::map fConstructedLegCFilterMasksMap; // Filter map for common track cuts - uint32_t fCommonTrackCutMask; + uint32_t fCommonTrackCutMask = 0; // Map tracking which common track cut the track cuts correspond to std::map fCommonTrackCutFilterMasks; - int fNLegCuts; + int fNLegCuts = 0; int fNPairCuts = 0; - int fNCommonTrackCuts; + int fNCommonTrackCuts = 0; // vectors for cut names and signal names, for easy access when calling FillHistogramList() std::vector fLegCutNames; std::vector fPairCutNames; @@ -3209,7 +3218,7 @@ struct AnalysisAsymmetricPairing { VarManager::SetDefaultVarNames(); fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(kTRUE); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqefficiency_helpers::varNames(), dqefficiency_helpers::varUnits()); // Get the leg cut filter masks fLegAFilterMask = fConfigLegAFilterMask.value; @@ -3228,8 +3237,8 @@ struct AnalysisAsymmetricPairing { TString addPairCutsStr = fConfigPairCutsJSON.value; if (addPairCutsStr != "") { std::vector addPairCuts = dqcuts::GetCutsFromJSON(addPairCutsStr.Data()); - for (auto& t : addPairCuts) { - fPairCuts.push_back(reinterpret_cast(t)); + for (auto const& t : addPairCuts) { + fPairCuts.push_back(static_cast(t)); cutNamesStr += Form(",%s", t->GetName()); } } @@ -3252,7 +3261,7 @@ struct AnalysisAsymmetricPairing { TString addMCSignalsStr = fConfigMCRecSignalsJSON.value; if (addMCSignalsStr != "") { std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); - for (auto& mcIt : addMCSignals) { + for (auto const& mcIt : addMCSignals) { if (mcIt->GetNProngs() != 2 && mcIt->GetNProngs() != 3) { LOG(fatal) << "Signal at reconstructed level requested (" << mcIt->GetName() << ") " << "does not have 2 or 3 prongs! Fix it"; } @@ -3267,21 +3276,21 @@ struct AnalysisAsymmetricPairing { } // Get the barrel track selection cuts - string tempCuts; - getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", tempCuts, false); + std::string tempCuts; + getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", tempCuts, false); TString tempCutsStr = tempCuts; - // check also the cuts added via JSON and add them to the string of cuts - getTaskOptionValue(context, "analysis-track-selection", "cfgBarrelTrackCutsJSON", tempCuts, false); + // check also the cuts added via JSON and add them to the std::string of cuts + getTaskOptionValue(context, "analysis-track-selection", "cfgBarrelTrackCutsJSON", tempCuts, false); TString addTrackCutsStr = tempCuts; if (addTrackCutsStr != "") { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); - for (auto& t : addTrackCuts) { + for (auto const& t : addTrackCuts) { tempCutsStr += Form(",%s", t->GetName()); } } std::unique_ptr objArray(tempCutsStr.Tokenize(",")); // Get the common leg cuts - int commonCutIdx; + int commonCutIdx = -1; TString commonNamesStr = fConfigCommonTrackCuts.value; if (!commonNamesStr.IsNull()) { // if common track cuts std::unique_ptr objArrayCommon(commonNamesStr.Tokenize(",")); @@ -3319,9 +3328,9 @@ struct AnalysisAsymmetricPairing { } fNLegCuts = objArrayLegs->GetEntries(); std::vector isThreeProng; - int legAIdx; - int legBIdx; - int legCIdx; + int legAIdx = -1; + int legBIdx = -1; + int legCIdx = -1; // Loop over leg defining cuts for (int icut = 0; icut < fNLegCuts; ++icut) { TString legsStr = objArrayLegs->At(icut)->GetName(); @@ -3376,9 +3385,9 @@ struct AnalysisAsymmetricPairing { DefineHistograms(fHistMan, Form("TripletsBarrelSE_%s_%s", legsStr.Data(), objArrayCommon->At(iCommonCut)->GetName()), fConfigHistogramSubgroups.value.data()); } - TString cutNamesStr = fConfigPairCuts.value; - if (!cutNamesStr.IsNull()) { // if pair cuts - std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); + TString pairCutNamesStr = fConfigPairCuts.value; + if (!pairCutNamesStr.IsNull()) { // if pair cuts + std::unique_ptr objArrayPair(pairCutNamesStr.Tokenize(",")); fNPairCuts = objArrayPair->GetEntries(); for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { // loop over pair cuts DefineHistograms(fHistMan, Form("TripletsBarrelSE_%s_%s", legsStr.Data(), objArrayPair->At(iPairCut)->GetName()), fConfigHistogramSubgroups.value.data()); @@ -3509,7 +3518,7 @@ struct AnalysisAsymmetricPairing { addMCSignalsStr = fConfigMCGenSignalsJSON.value; if (addMCSignalsStr != "") { std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); - for (auto& mcIt : addMCSignals) { + for (auto const& mcIt : addMCSignals) { if (mcIt->GetNProngs() == 1) { fGenMCSignals.push_back(mcIt); DefineHistograms(fHistMan, Form("MCTruthGen_%s;", mcIt->GetName()), fConfigHistogramSubgroups.value.data()); // TODO: Add these names to a std::vector to avoid using Form in the process function @@ -3551,7 +3560,7 @@ struct AnalysisAsymmetricPairing { void initParamsFromCCDB(uint64_t timestamp, bool isTriplets) { if (fConfigUseRemoteField.value) { - o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp(fConfigGRPMagPath, timestamp); + auto grpmag = fCCDB->getForTimeStamp(fConfigGRPMagPath, timestamp); float magField = 0.0; if (grpmag != nullptr) { magField = grpmag->getNominalL3Field(); @@ -3609,13 +3618,13 @@ struct AnalysisAsymmetricPairing { constexpr bool trackHasCov = ((TTrackFillMap & VarManager::ObjTypes::TrackCov) > 0 || (TTrackFillMap & VarManager::ObjTypes::ReducedTrackBarrelCov) > 0); - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); - VarManager::FillEvent(event, VarManager::fgValues); + VarManager::FillEvent(event, dqefficiency_helpers::varValues()); auto groupedLegAAssocs = legACandidateAssocs.sliceBy(preslice, event.globalIndex()); if (groupedLegAAssocs.size() == 0) { @@ -3626,7 +3635,7 @@ struct AnalysisAsymmetricPairing { continue; } - for (auto& [a1, a2] : combinations(soa::CombinationsFullIndexPolicy(groupedLegAAssocs, groupedLegBAssocs))) { + for (auto const& [a1, a2] : combinations(soa::CombinationsFullIndexPolicy(groupedLegAAssocs, groupedLegBAssocs))) { uint32_t twoTrackFilter = 0; uint32_t twoTrackCommonFilter = 0; @@ -3662,12 +3671,12 @@ struct AnalysisAsymmetricPairing { bool isReflected = false; std::pair trackIds(t1.globalIndex(), t2.globalIndex()); - if (fPairCount.find(trackIds) != fPairCount.end()) { + if (fPairCount.contains(trackIds)) { // Double counting is possible due to track-collision ambiguity. Skip pairs which were counted before fPairCount[trackIds] += 1; continue; } - if (fPairCount.find(std::pair(trackIds.second, trackIds.first)) != fPairCount.end()) { + if (fPairCount.contains(std::pair(trackIds.second, trackIds.first))) { isReflected = true; } fPairCount[trackIds] += 1; @@ -3683,13 +3692,13 @@ struct AnalysisAsymmetricPairing { } // run MC matching for this pair - int isig = 0; + int iSigMc = 0; mcDecision = 0; - for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { + for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, iSigMc++) { if (t1.has_reducedMCTrack() && t2.has_reducedMCTrack()) { VarManager::FillPairMC(t1.reducedMCTrack(), t2.reducedMCTrack()); if ((*sig)->CheckSignal(true, t1.reducedMCTrack(), t2.reducedMCTrack())) { - mcDecision |= static_cast(1) << isig; + mcDecision |= static_cast(1) << iSigMc; } } } // end loop over MC signals @@ -3705,49 +3714,49 @@ struct AnalysisAsymmetricPairing { if (twoTrackFilter & (static_cast(1) << icut)) { isAmbi = (twoTrackFilter & (static_cast(1) << 30)) || (twoTrackFilter & (static_cast(1) << 31)); if (sign1 * sign2 < 0) { // +- pairs - fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s", fLegCutNames[icut].Data()), VarManager::fgValues); // reconstructed, unmatched + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s", fLegCutNames[icut].Data()), dqefficiency_helpers::varValues()); // reconstructed, unmatched if (isAmbi && fConfigQA) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_ambiguous_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_ambiguous_%s", fLegCutNames[icut].Data()), dqefficiency_helpers::varValues()); } if (isReflected && fConfigReflectedHistograms.value) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_reflected_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_reflected_%s", fLegCutNames[icut].Data()), dqefficiency_helpers::varValues()); } } else if (fConfigSameSignHistograms.value) { if (sign1 > 0) { // ++ pairs - fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s", fLegCutNames[icut].Data()), dqefficiency_helpers::varValues()); if (isAmbi && fConfigQA) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_ambiguous_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_ambiguous_%s", fLegCutNames[icut].Data()), dqefficiency_helpers::varValues()); } if (isReflected && fConfigReflectedHistograms.value) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_reflected_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_reflected_%s", fLegCutNames[icut].Data()), dqefficiency_helpers::varValues()); } } else { // -- pairs - fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s", fLegCutNames[icut].Data()), dqefficiency_helpers::varValues()); if (isAmbi && fConfigQA) { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_ambiguous_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_ambiguous_%s", fLegCutNames[icut].Data()), dqefficiency_helpers::varValues()); } if (isReflected && fConfigReflectedHistograms) { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_reflected_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_reflected_%s", fLegCutNames[icut].Data()), dqefficiency_helpers::varValues()); } } } for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals if (mcDecision & (static_cast(1) << isig)) { if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); if (isReflected && fConfigReflectedHistograms.value) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_reflected_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_reflected_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); } } else if (fConfigSameSignHistograms.value) { if (sign1 > 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); if (isReflected && fConfigReflectedHistograms.value) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_reflected_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_reflected_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); } } else { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); if (isReflected && fConfigReflectedHistograms.value) { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_reflected_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_reflected_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); } } } @@ -3756,23 +3765,23 @@ struct AnalysisAsymmetricPairing { for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; iCommonCut++) { if (twoTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), dqefficiency_helpers::varValues()); } else if (fConfigSameSignHistograms.value) { if (sign1 > 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), dqefficiency_helpers::varValues()); } } for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals if (mcDecision & (static_cast(1) << isig)) { if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); } else if (fConfigSameSignHistograms.value) { if (sign1 > 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); } } } @@ -3781,28 +3790,29 @@ struct AnalysisAsymmetricPairing { } // end loop (common cuts) int iPairCut = 0; for (auto cut = fPairCuts.begin(); cut != fPairCuts.end(); cut++, iPairCut++) { - if (!((*cut)->IsSelected(VarManager::fgValues))) // apply pair cuts + if (!((*cut)->IsSelected(dqefficiency_helpers::varValues()))) { // apply pair cuts continue; + } pairFilter |= (static_cast(1) << iPairCut); // Histograms with pair cuts if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), dqefficiency_helpers::varValues()); } else if (fConfigSameSignHistograms.value) { if (sign1 > 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), dqefficiency_helpers::varValues()); } } for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals if (mcDecision & (static_cast(1) << isig)) { if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); } else if (fConfigSameSignHistograms.value) { if (sign1 > 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); } } } @@ -3811,23 +3821,23 @@ struct AnalysisAsymmetricPairing { for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { if (twoTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), dqefficiency_helpers::varValues()); } else if (fConfigSameSignHistograms.value) { if (sign1 > 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), dqefficiency_helpers::varValues()); } } for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals if (mcDecision & (static_cast(1) << isig)) { if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); } else if (fConfigSameSignHistograms.value) { if (sign1 > 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); } else { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); } } } @@ -3858,13 +3868,13 @@ struct AnalysisAsymmetricPairing { } } - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); - VarManager::FillEvent(event, VarManager::fgValues); + VarManager::FillEvent(event, dqefficiency_helpers::varValues()); auto groupedLegAAssocs = legACandidateAssocs.sliceBy(preslice, event.globalIndex()); if (groupedLegAAssocs.size() == 0) { @@ -3881,17 +3891,17 @@ struct AnalysisAsymmetricPairing { // Based on triplet type, make suitable combinations of the partitions if (tripletType == VarManager::kTripleCandidateToPKPi) { - for (auto& [a1, a2, a3] : combinations(soa::CombinationsFullIndexPolicy(groupedLegAAssocs, groupedLegBAssocs, groupedLegCAssocs))) { + for (auto const& [a1, a2, a3] : combinations(soa::CombinationsFullIndexPolicy(groupedLegAAssocs, groupedLegBAssocs, groupedLegCAssocs))) { readTriplet(a1, a2, a3, tracks, event, tripletType); } } else if (tripletType == VarManager::kTripleCandidateToKPiPi) { - for (auto& a1 : groupedLegAAssocs) { - for (auto& [a2, a3] : combinations(groupedLegBAssocs, groupedLegCAssocs)) { + for (auto const& a1 : groupedLegAAssocs) { + for (auto const& [a2, a3] : combinations(groupedLegBAssocs, groupedLegCAssocs)) { readTriplet(a1, a2, a3, tracks, event, tripletType); } } } else { - LOG(fatal) << "Given tripletType not recognized. Don't know how to make combinations!" << endl; + LOG(fatal) << "Given tripletType not recognized. Don't know how to make combinations!"; } } // end event loop } @@ -3965,17 +3975,17 @@ struct AnalysisAsymmetricPairing { } // run MC matching for this triplet - int isig = 0; + int iSigMc = 0; mcDecision = 0; - for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { + for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, iSigMc++) { if (t1.has_reducedMCTrack() && t2.has_reducedMCTrack() && t3.has_reducedMCTrack()) { if ((*sig)->CheckSignal(true, t1.reducedMCTrack(), t2.reducedMCTrack(), t3.reducedMCTrack())) { - mcDecision |= (static_cast(1) << isig); + mcDecision |= (static_cast(1) << iSigMc); } } } // end loop over MC signals - VarManager::FillTriple(t1, t2, t3, VarManager::fgValues, tripletType); + VarManager::FillTriple(t1, t2, t3, dqefficiency_helpers::varValues(), tripletType); if constexpr (TThreeProngFitter) { VarManager::FillTripletVertexing(event, t1, t2, t3, tripletType); } @@ -3985,43 +3995,44 @@ struct AnalysisAsymmetricPairing { for (int icut = 0; icut < fNLegCuts; icut++) { isAmbi = (threeTrackFilter & (static_cast(1) << 29)) || (threeTrackFilter & (static_cast(1) << 30)) || (threeTrackFilter & (static_cast(1) << 31)); if (threeTrackFilter & (static_cast(1) << icut)) { - fHistMan->FillHistClass(Form("TripletsBarrelSE_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s", fLegCutNames[icut].Data()), dqefficiency_helpers::varValues()); for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals if (mcDecision & (static_cast(1) << isig)) { - fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); // matched signal + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s", fLegCutNames[icut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); // matched signal } } // end loop (MC signals) if (fConfigQA && isAmbi) { - fHistMan->FillHistClass(Form("TripletsBarrelSE_ambiguous_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("TripletsBarrelSE_ambiguous_%s", fLegCutNames[icut].Data()), dqefficiency_helpers::varValues()); } for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; iCommonCut++) { if (threeTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { - fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), dqefficiency_helpers::varValues()); for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals if (mcDecision & (static_cast(1) << isig)) { - fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); // matched signal + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); // matched signal } } // end loop (MC signals) } } // end loop (common cuts) int iPairCut = 0; for (auto cut = fPairCuts.begin(); cut != fPairCuts.end(); cut++, iPairCut++) { - if (!((*cut)->IsSelected(VarManager::fgValues))) // apply pair cuts + if (!((*cut)->IsSelected(dqefficiency_helpers::varValues()))) { // apply pair cuts continue; + } // Histograms with pair cuts - fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), dqefficiency_helpers::varValues()); for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals if (mcDecision & (static_cast(1) << isig)) { - fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); // matched signal + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); // matched signal } } // end loop (MC signals) // Histograms with pair cuts and common track cuts for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { if (threeTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { - fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), dqefficiency_helpers::varValues()); for (unsigned int isig = 0; isig < fRecMCSignals.size(); isig++) { // loop over MC signals if (mcDecision & (static_cast(1) << isig)) { - fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), VarManager::fgValues); // matched signal + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fRecMCSignalNames[isig].Data()), dqefficiency_helpers::varValues()); // matched signal } } // end loop (MC signals) } @@ -4060,15 +4071,15 @@ struct AnalysisAsymmetricPairing { // loop over mc stack and fill histograms for pure MC truth signals // group all the MC tracks which belong to the MC event corresponding to the current reconstructed event // auto groupedMCTracks = tracksMC.sliceBy(aod::reducedtrackMC::reducedMCeventId, event.reducedMCevent().globalIndex()); - for (auto& mctrack : mcTracks) { + for (auto const& mctrack : mcTracks) { VarManager::FillTrackMC(mcTracks, mctrack); // NOTE: Signals are checked here mostly based on the skimmed MC stack, so depending on the requested signal, the stack could be incomplete. // NOTE: However, the working model is that the decisions on MC signals are precomputed during skimming and are stored in the mcReducedFlags member. // TODO: Use the mcReducedFlags to select signals - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->CheckSignal(true, mctrack)) { - fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), dqefficiency_helpers::varValues()); } } } @@ -4079,7 +4090,7 @@ struct AnalysisAsymmetricPairing { void processMCGenWithEventSelection(soa::Filtered const& events, ReducedMCEvents const& /*mcEvents*/, ReducedMCTracks const& mcTracks) { - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } @@ -4089,21 +4100,21 @@ struct AnalysisAsymmetricPairing { auto groupedMCTracks = mcTracks.sliceBy(perReducedMcEvent, event.reducedMCeventId()); groupedMCTracks.bindInternalIndicesTo(&mcTracks); - for (auto& track : groupedMCTracks) { + for (auto const& track : groupedMCTracks) { VarManager::FillTrackMC(mcTracks, track); auto track_raw = groupedMCTracks.rawIteratorAt(track.globalIndex()); - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->CheckSignal(true, track_raw)) { - fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), dqefficiency_helpers::varValues()); } } } } // end loop over reconstructed events } - void processDummy(MyEvents&) + void processDummy(MyEvents const&) { // do nothing } @@ -4159,13 +4170,13 @@ struct AnalysisDileptonTrack { Configurable fConfigUseCorrectlyAssociatedMC{"cfgUseCorrectlyAssociatedMC", true, "Use only correctly associated track to construct triplet"}; Configurable fConfigMixingDepth{"cfgMixingDepth", 5, "Event mixing pool depth"}; - int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. - int fNCuts; - int fNLegCuts; - int fNPairCuts; - int fNCommonTrackCuts; + int fCurrentRun = -1; // needed to detect if the run changed and trigger update of calibrations etc. + int fNCuts = 0; + int fNLegCuts = 0; + int fNPairCuts = 0; + int fNCommonTrackCuts = 0; std::map fCommonTrackCutMap; - uint32_t fTrackCutBitMap; // track cut bit mask to be used in the selection of tracks associated with dileptons + uint32_t fTrackCutBitMap = 0; // track cut bit mask to be used in the selection of tracks associated with dileptons // vector for single-lepton and track cut names for easy access when calling FillHistogramList() std::vector fTrackCutNames; std::vector fLegCutNames; @@ -4173,7 +4184,7 @@ struct AnalysisDileptonTrack { std::vector fPairCutNames; std::vector fCommonPairCutNames; - Service fCCDB; + Service fCCDB{}; // TODO: The filter expressions seem to always use the default value of configurables, not the values from the actual configuration file Filter eventFilter = aod::dqanalysisflags::isEventSelected > static_cast(0); @@ -4184,9 +4195,9 @@ struct AnalysisDileptonTrack { constexpr static uint32_t fgDileptonFillMap = VarManager::ObjTypes::ReducedTrack | VarManager::ObjTypes::Pair; // fill map // use two values array to avoid mixing up the quantities - float* fValuesDilepton; - float* fValuesHadron; - HistogramManager* fHistMan; + float* fValuesDilepton = nullptr; + float* fValuesHadron = nullptr; + HistogramManager* fHistMan = nullptr; std::vector fRecMCSignals; std::vector fGenMCSignals; @@ -4205,9 +4216,9 @@ struct AnalysisDileptonTrack { if (isDummy) { if (isBarrel || isMuon || isBarrelAsymmetric || isMCGen) { - LOG(fatal) << "Dummy function is enabled even if there are normal process functions running! Fix your config!" << endl; + LOG(fatal) << "Dummy function is enabled even if there are normal process functions running! Fix your config!"; } else { - LOG(info) << "Dummy function is enabled. Skipping the rest of the init function" << endl; + LOG(info) << "Dummy function is enabled. Skipping the rest of the init function"; return; } } @@ -4228,7 +4239,7 @@ struct AnalysisDileptonTrack { VarManager::SetDefaultVarNames(); fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(true); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqefficiency_helpers::varNames(), dqefficiency_helpers::varUnits()); TString sigNamesStr = fConfigMCRecSignals.value; std::unique_ptr objRecSigArray(sigNamesStr.Tokenize(",")); @@ -4250,7 +4261,7 @@ struct AnalysisDileptonTrack { TString addMCSignalsStr = fConfigMCRecSignalsJSON.value; if (addMCSignalsStr != "") { std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); - for (auto& mcIt : addMCSignals) { + for (auto const& mcIt : addMCSignals) { if (mcIt->GetNProngs() != 3) { LOG(fatal) << "Signal at reconstructed level requested (" << mcIt->GetName() << ") " << "does not have 3 prongs! Fix it"; } @@ -4275,7 +4286,7 @@ struct AnalysisDileptonTrack { addMCSignalsStr = fConfigMCGenSignalsJSON.value; if (addMCSignalsStr != "") { std::vector addMCSignals = dqmcsignals::GetMCSignalsFromJSON(addMCSignalsStr.Data()); - for (auto& mcIt : addMCSignals) { + for (auto const& mcIt : addMCSignals) { if (mcIt->GetNProngs() == 1) { fGenMCSignals.push_back(mcIt); } @@ -4288,11 +4299,11 @@ struct AnalysisDileptonTrack { // Get the list of single track and muon cuts computed in the dedicated tasks upstream // We need this to know the order in which they were computed, and also to make sure that in this task we do not ask // for cuts which were not computed (in which case this will trigger a fatal) - string cfgTrackSelection_TrackCuts; + std::string cfgTrackSelection_TrackCuts; if (isBarrel || isBarrelAsymmetric) { - getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", cfgTrackSelection_TrackCuts, false); + getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", cfgTrackSelection_TrackCuts, false); } else { - getTaskOptionValue(context, "analysis-muon-selection", "cfgMuonCuts", cfgTrackSelection_TrackCuts, false); + getTaskOptionValue(context, "analysis-muon-selection", "cfgMuonCuts", cfgTrackSelection_TrackCuts, false); } TObjArray* cfgTrackSelection_objArrayTrackCuts = nullptr; if (!cfgTrackSelection_TrackCuts.empty()) { @@ -4300,17 +4311,17 @@ struct AnalysisDileptonTrack { } // get also the list of cuts specified via the JSON parameters if (isBarrel || isBarrelAsymmetric) { - getTaskOptionValue(context, "analysis-track-selection", "cfgBarrelTrackCutsJSON", cfgTrackSelection_TrackCuts, false); + getTaskOptionValue(context, "analysis-track-selection", "cfgBarrelTrackCutsJSON", cfgTrackSelection_TrackCuts, false); } else { - getTaskOptionValue(context, "analysis-muon-selection", "cfgMuonCutsJSON", cfgTrackSelection_TrackCuts, false); + getTaskOptionValue(context, "analysis-muon-selection", "cfgMuonCutsJSON", cfgTrackSelection_TrackCuts, false); } if (!cfgTrackSelection_TrackCuts.empty()) { if (cfgTrackSelection_objArrayTrackCuts == nullptr) { cfgTrackSelection_objArrayTrackCuts = new TObjArray(); } std::vector addTrackCuts = dqcuts::GetCutsFromJSON(cfgTrackSelection_TrackCuts.data()); - for (auto& t : addTrackCuts) { - TObjString* tempObjStr = new TObjString(t->GetName()); + for (auto const& t : addTrackCuts) { + auto tempObjStr = new TObjString(t->GetName()); cfgTrackSelection_objArrayTrackCuts->Add(tempObjStr); } } @@ -4348,20 +4359,20 @@ struct AnalysisDileptonTrack { // NOTE: The track/muon cuts in analysis-same-event-pairing are used to select electrons/muons to build dielectrons/dimuons // NOTE: The cfgPairCuts in analysis-same-event-pairing are used to apply an additional selection on top of the already produced dileptons // but this is only used for histograms, not for the produced dilepton tables - string cfgPairing_TrackCuts; - string cfgPairing_PairCuts; - string cfgPairing_PairCutsJSON; - string cfgPairing_CommonTrackCuts; + std::string cfgPairing_TrackCuts; + std::string cfgPairing_PairCuts; + std::string cfgPairing_PairCutsJSON; + std::string cfgPairing_CommonTrackCuts; if (isBarrel) { - getTaskOptionValue(context, "analysis-same-event-pairing", "cfgTrackCuts", cfgPairing_TrackCuts, false); - getTaskOptionValue(context, "analysis-same-event-pairing", "cfgPairCuts", cfgPairing_PairCuts, false); + getTaskOptionValue(context, "analysis-same-event-pairing", "cfgTrackCuts", cfgPairing_TrackCuts, false); + getTaskOptionValue(context, "analysis-same-event-pairing", "cfgPairCuts", cfgPairing_PairCuts, false); } else if (isMuon) { - getTaskOptionValue(context, "analysis-same-event-pairing", "cfgMuonCuts", cfgPairing_TrackCuts, false); - getTaskOptionValue(context, "analysis-same-event-pairing", "cfgPairCuts", cfgPairing_PairCuts, false); + getTaskOptionValue(context, "analysis-same-event-pairing", "cfgMuonCuts", cfgPairing_TrackCuts, false); + getTaskOptionValue(context, "analysis-same-event-pairing", "cfgPairCuts", cfgPairing_PairCuts, false); } else if (isBarrelAsymmetric) { - getTaskOptionValue(context, "analysis-asymmetric-pairing", "cfgLegCuts", cfgPairing_TrackCuts, false); - getTaskOptionValue(context, "analysis-asymmetric-pairing", "cfgPairCuts", cfgPairing_PairCuts, false); - getTaskOptionValue(context, "analysis-asymmetric-pairing", "cfgCommonTrackCuts", cfgPairing_CommonTrackCuts, false); + getTaskOptionValue(context, "analysis-asymmetric-pairing", "cfgLegCuts", cfgPairing_TrackCuts, false); + getTaskOptionValue(context, "analysis-asymmetric-pairing", "cfgPairCuts", cfgPairing_PairCuts, false); + getTaskOptionValue(context, "analysis-asymmetric-pairing", "cfgCommonTrackCuts", cfgPairing_CommonTrackCuts, false); } if (cfgPairing_TrackCuts.empty()) { LOG(fatal) << "There are no dilepton cuts specified in the upstream in the same-event-pairing or asymmetric-pairing"; @@ -4384,11 +4395,11 @@ struct AnalysisDileptonTrack { // Get also the pair cuts specified via the JSON parameters if (isBarrelAsymmetric) { - getTaskOptionValue(context, "analysis-asymmetric-pairing", "cfgPairCutsJSON", cfgPairing_PairCutsJSON, false); + getTaskOptionValue(context, "analysis-asymmetric-pairing", "cfgPairCutsJSON", cfgPairing_PairCutsJSON, false); TString addPairCutsStr = cfgPairing_PairCutsJSON; if (addPairCutsStr != "") { std::vector addPairCuts = dqcuts::GetCutsFromJSON(addPairCutsStr.Data()); - for (auto& t : addPairCuts) { + for (auto const& t : addPairCuts) { cfgPairing_PairCuts += Form(",%s", t->GetName()); } } @@ -4423,7 +4434,7 @@ struct AnalysisDileptonTrack { pairLegCutName = fTrackCutNames[icut].Data(); } else { // For asymmetric pairs we access the leg cuts instead - pairLegCutName = static_cast(cfgPairing_objArrayTrackCuts->At(icut))->GetString(); + pairLegCutName = dynamic_cast(cfgPairing_objArrayTrackCuts->At(icut))->GetString(); } fLegCutNames.push_back(pairLegCutName); @@ -4433,12 +4444,12 @@ struct AnalysisDileptonTrack { for (int iCutTrack = 0; iCutTrack < fNCuts; iCutTrack++) { // here we check that this track cut is one of those required to associate with the dileptons - if (!(fTrackCutBitMap & (static_cast(1) << iCutTrack))) { + if ((fTrackCutBitMap & (static_cast(1) << iCutTrack)) == 0) { continue; } DefineHistograms(fHistMan, Form("DileptonTrack_%s_%s", pairLegCutName.Data(), fTrackCutNames[iCutTrack].Data()), fConfigHistogramSubgroups.value.data()); - for (auto& sig : fRecMCSignals) { + for (auto const& sig : fRecMCSignals) { DefineHistograms(fHistMan, Form("DileptonTrackMCMatched_%s_%s_%s", pairLegCutName.Data(), fTrackCutNames[iCutTrack].Data(), sig->GetName()), fConfigHistogramSubgroups.value.data()); } @@ -4447,7 +4458,7 @@ struct AnalysisDileptonTrack { for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { DefineHistograms(fHistMan, Form("DileptonsSelected_%s_%s", pairLegCutName.Data(), fCommonPairCutNames[iCommonCut].Data()), "barrel,vertexing"); DefineHistograms(fHistMan, Form("DileptonTrack_%s_%s_%s", pairLegCutName.Data(), fCommonPairCutNames[iCommonCut].Data(), fTrackCutNames[iCutTrack].Data()), fConfigHistogramSubgroups.value.data()); - for (auto& sig : fRecMCSignals) { + for (auto const& sig : fRecMCSignals) { DefineHistograms(fHistMan, Form("DileptonTrackMCMatched_%s_%s_%s_%s", pairLegCutName.Data(), fCommonPairCutNames[iCommonCut].Data(), fTrackCutNames[iCutTrack].Data(), sig->GetName()), fConfigHistogramSubgroups.value.data()); } } @@ -4458,7 +4469,7 @@ struct AnalysisDileptonTrack { for (int iPairCut = 0; iPairCut < fNPairCuts; ++iPairCut) { DefineHistograms(fHistMan, Form("DileptonsSelected_%s_%s", pairLegCutName.Data(), fPairCutNames[iPairCut].Data()), "barrel,vertexing"); DefineHistograms(fHistMan, Form("DileptonTrack_%s_%s_%s", pairLegCutName.Data(), fPairCutNames[iPairCut].Data(), fTrackCutNames[iCutTrack].Data()), fConfigHistogramSubgroups.value.data()); - for (auto& sig : fRecMCSignals) { + for (auto const& sig : fRecMCSignals) { DefineHistograms(fHistMan, Form("DileptonTrackMCMatched_%s_%s_%s_%s", pairLegCutName.Data(), fPairCutNames[iPairCut].Data(), fTrackCutNames[iCutTrack].Data(), sig->GetName()), fConfigHistogramSubgroups.value.data()); } @@ -4467,7 +4478,7 @@ struct AnalysisDileptonTrack { for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { DefineHistograms(fHistMan, Form("DileptonsSelected_%s_%s_%s", pairLegCutName.Data(), fCommonPairCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), "barrel,vertexing"); DefineHistograms(fHistMan, Form("DileptonTrack_%s_%s_%s_%s", pairLegCutName.Data(), fCommonPairCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fTrackCutNames[iCutTrack].Data()), fConfigHistogramSubgroups.value.data()); - for (auto& sig : fRecMCSignals) { + for (auto const& sig : fRecMCSignals) { DefineHistograms(fHistMan, Form("DileptonTrack_%s_%s_%s_%s_%s", pairLegCutName.Data(), fCommonPairCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data(), fTrackCutNames[iCutTrack].Data(), sig->GetName()), fConfigHistogramSubgroups.value.data()); } } @@ -4479,24 +4490,24 @@ struct AnalysisDileptonTrack { } // end if (isBarrel || isBarrelAsymmetric || isMuon) if (isMCGen) { - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { DefineHistograms(fHistMan, Form("MCTruthGen_%s", sig->GetName()), ""); DefineHistograms(fHistMan, Form("MCTruthGenSel_%s", sig->GetName()), ""); } - for (auto& sig : fRecMCSignals) { + for (auto const& sig : fRecMCSignals) { DefineHistograms(fHistMan, Form("MCTruthGenSelBR_%s", sig->GetName()), ""); DefineHistograms(fHistMan, Form("MCTruthGenSelBRAccepted_%s", sig->GetName()), ""); } } if (isMCGen_energycorrelators) { - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { DefineHistograms(fHistMan, Form("MCTruthEenergyCorrelators_%s", sig->GetName()), ""); } } if (isMCGen_energycorrelatorsME) { - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { DefineHistograms(fHistMan, Form("MCTruthEenergyCorrelatorsME_%s", sig->GetName()), ""); } } @@ -4513,7 +4524,7 @@ struct AnalysisDileptonTrack { void initParamsFromCCDB(uint64_t timestamp) { if (fConfigUseRemoteField.value) { - o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp(fConfigGRPmagPath.value, timestamp); + auto grpmag = fCCDB->getForTimeStamp(fConfigGRPmagPath.value, timestamp); float magField = 0.0; if (grpmag != nullptr) { magField = grpmag->getNominalL3Field(); @@ -4545,13 +4556,13 @@ struct AnalysisDileptonTrack { VarManager::FillEvent(event, fValuesDilepton); VarManager::FillEvent(event.reducedMCevent(), fValuesDilepton); - uint32_t mcDecision = static_cast(0); - size_t isig = 0; + auto mcDecision = static_cast(0); + size_t iSigMc = 0; bool isCorrectAssoc_lepton1 = false; bool isCorrectAssoc_lepton2 = false; bool isCorrectAssoc_assoc = false; - for (auto dilepton : dileptons) { + for (auto const& dilepton : dileptons) { // get full track info of tracks based on the index auto lepton1 = tracks.rawIteratorAt(dilepton.index0Id()); auto lepton2 = tracks.rawIteratorAt(dilepton.index1Id()); @@ -4566,8 +4577,9 @@ struct AnalysisDileptonTrack { } // dilepton rap cut float rap = dilepton.rap(); - if (fConfigUseMCRapcut && abs(rap) > fConfigDileptonRapCutAbs) + if (fConfigUseMCRapcut && std::abs(rap) > fConfigDileptonRapCutAbs) { continue; + } // Correct association if (fConfigUseCorrectlyAssociatedMC) { @@ -4608,7 +4620,7 @@ struct AnalysisDileptonTrack { } // loop over track associations - for (auto& assoc : assocs) { + for (auto const& assoc : assocs) { VarManager::ResetValues(0, VarManager::kNVars, fValuesHadron); VarManager::ResetValues(0, VarManager::kNVars, fValuesDilepton); @@ -4642,10 +4654,10 @@ struct AnalysisDileptonTrack { VarManager::FillDileptonTrackVertexing(event, lepton1, lepton2, track, fValuesHadron); mcDecision = 0; - isig = 0; - for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { + iSigMc = 0; + for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, iSigMc++) { if ((*sig)->CheckSignal(true, lepton1MC, lepton2MC, trackMC)) { - mcDecision |= (static_cast(1) << isig); + mcDecision |= (static_cast(1) << iSigMc); } } @@ -4706,10 +4718,10 @@ struct AnalysisDileptonTrack { auto trackMC = track.reducedMCTrack(); mcDecision = 0; - isig = 0; - for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { + iSigMc = 0; + for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, iSigMc++) { if ((*sig)->CheckSignal(true, lepton1MC, lepton2MC, trackMC)) { - mcDecision |= (static_cast(1) << isig); + mcDecision |= (static_cast(1) << iSigMc); } } } @@ -4733,10 +4745,10 @@ struct AnalysisDileptonTrack { } auto trackMC = track.reducedMCTrack(); mcDecision = 0; - isig = 0; - for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { + iSigMc = 0; + for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, iSigMc++) { if ((*sig)->CheckSignal(true, lepton1MC, lepton2MC, trackMC)) { - mcDecision |= (static_cast(1) << isig); + mcDecision |= (static_cast(1) << iSigMc); } } // Fill table for correlation analysis @@ -4823,7 +4835,7 @@ struct AnalysisDileptonTrack { initParamsFromCCDB(events.begin().timestamp()); fCurrentRun = events.begin().runNumber(); } // end: runNumber - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } @@ -4846,7 +4858,7 @@ struct AnalysisDileptonTrack { initParamsFromCCDB(events.begin().timestamp()); fCurrentRun = events.begin().runNumber(); } // end: runNumber - for (auto& event : events) { + for (auto const& event : events) { auto groupedBarrelAssocs = assocs.sliceBy(trackAssocsPerCollision, event.globalIndex()); auto groupedDitracks = ditracks.sliceBy(ditracksPerCollision, event.globalIndex()); runDileptonHadron(event, groupedBarrelAssocs, tracks, groupedDitracks, mcEvents, mcTracks); @@ -4869,7 +4881,7 @@ struct AnalysisDileptonTrack { initParamsFromCCDB(events.begin().timestamp()); fCurrentRun = events.begin().runNumber(); } // end: runNumber - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } @@ -4884,40 +4896,40 @@ struct AnalysisDileptonTrack { // loop over mc stack and fill histograms for pure MC truth signals // group all the MC tracks which belong to the MC event corresponding to the current reconstructed event // auto groupedMCTracks = tracksMC.sliceBy(aod::reducedtrackMC::reducedMCeventId, event.reducedMCevent().globalIndex()); - for (auto& mctrack : mcTracks) { - - if ((std::abs(mctrack.pdgCode()) > 400 && std::abs(mctrack.pdgCode()) < 599) || - (std::abs(mctrack.pdgCode()) > 4000 && std::abs(mctrack.pdgCode()) < 5999) || - mctrack.mcReducedFlags() > 0) { - /*cout << ">>>>>>>>>>>>>>>>>>>>>>> track idx / pdg / selections: " << mctrack.globalIndex() << " / " << mctrack.pdgCode() << " / "; - PrintBitMap(mctrack.mcReducedFlags(), 16); - cout << endl; - if (mctrack.has_mothers()) { - for (auto& m : mctrack.mothersIds()) { - if (m < mcTracks.size()) { // protect against bad mother indices - auto aMother = mcTracks.rawIteratorAt(m); - cout << "<<<<<< mother idx / pdg: " << m << " / " << aMother.pdgCode() << endl; - } - } - } - - if (mctrack.has_daughters()) { - for (int d = mctrack.daughtersIds()[0]; d <= mctrack.daughtersIds()[1]; ++d) { - if (d < mcTracks.size()) { // protect against bad daughter indices - auto aDaughter = mcTracks.rawIteratorAt(d); - cout << "<<<<<< daughter idx / pdg: " << d << " / " << aDaughter.pdgCode() << endl; - } - } - }*/ - } + for (auto const& mctrack : mcTracks) { + + // if ((std::abs(mctrack.pdgCode()) > 400 && std::abs(mctrack.pdgCode()) < 599) || + // (std::abs(mctrack.pdgCode()) > 4000 && std::abs(mctrack.pdgCode()) < 5999) || + // mctrack.mcReducedFlags() > 0) { + // /*cout << ">>>>>>>>>>>>>>>>>>>>>>> track idx / pdg / selections: " << mctrack.globalIndex() << " / " << mctrack.pdgCode() << " / "; + // PrintBitMap(mctrack.mcReducedFlags(), 16); + // cout << endl; + // if (mctrack.has_mothers()) { + // for (auto& m : mctrack.mothersIds()) { + // if (m < mcTracks.size()) { // protect against bad mother indices + // auto aMother = mcTracks.rawIteratorAt(m); + // cout << "<<<<<< mother idx / pdg: " << m << " / " << aMother.pdgCode() << endl; + // } + // } + // } + // + // if (mctrack.has_daughters()) { + // for (int d = mctrack.daughtersIds()[0]; d <= mctrack.daughtersIds()[1]; ++d) { + // if (d < mcTracks.size()) { // protect against bad daughter indices + // auto aDaughter = mcTracks.rawIteratorAt(d); + // cout << "<<<<<< daughter idx / pdg: " << d << " / " << aDaughter.pdgCode() << endl; + // } + // } + // }*/ + // } VarManager::FillTrackMC(mcTracks, mctrack); // NOTE: Signals are checked here mostly based on the skimmed MC stack, so depending on the requested signal, the stack could be incomplete. // NOTE: However, the working model is that the decisions on MC signals are precomputed during skimming and are stored in the mcReducedFlags member. // TODO: Use the mcReducedFlags to select signals - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->CheckSignal(true, mctrack)) { - fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGen_%s", sig->GetName()), dqefficiency_helpers::varValues()); } } } @@ -4928,7 +4940,7 @@ struct AnalysisDileptonTrack { void processMCGenWithEventSelection(soa::Filtered const& events, ReducedMCEvents const& /*mcEvents*/, ReducedMCTracks const& mcTracks) { - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } @@ -4938,45 +4950,48 @@ struct AnalysisDileptonTrack { auto groupedMCTracks = mcTracks.sliceBy(perReducedMcEvent, event.reducedMCeventId()); groupedMCTracks.bindInternalIndicesTo(&mcTracks); - for (auto& track : groupedMCTracks) { + for (auto const& track : groupedMCTracks) { VarManager::FillTrackMC(mcTracks, track); auto track_raw = groupedMCTracks.rawIteratorAt(track.globalIndex()); - for (auto& sig : fGenMCSignals) { + for (auto const& sig : fGenMCSignals) { if (sig->CheckSignal(true, track_raw)) { - fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGenSel_%s", sig->GetName()), dqefficiency_helpers::varValues()); } } } // make a list of all MC tracks in the MC collision corresponding to the current reconstructed event std::vector mcTrackIndices; - for (auto& t : groupedMCTracks) { + for (auto const& t : groupedMCTracks) { mcTrackIndices.push_back(t.globalIndex()); } // make a three nested for loop over all MC tracks in the vector - for (auto t1 : mcTrackIndices) { - auto track1 = mcTracks.rawIteratorAt(*(&t1)); - for (auto t2 : mcTrackIndices) { - if (t1 == t2) + for (const auto& t1 : mcTrackIndices) { + auto track1 = mcTracks.rawIteratorAt(t1); + for (const auto& t2 : mcTrackIndices) { + if (t1 == t2) { continue; + } // if (t2 < t1) continue; - auto track2 = mcTracks.rawIteratorAt(*(&t2)); - for (auto t3 : mcTrackIndices) { - if (t3 == t1) + auto track2 = mcTracks.rawIteratorAt(t2); + for (const auto& t3 : mcTrackIndices) { + if (t3 == t1) { continue; - if (t3 == t2) + } + if (t3 == t2) { continue; - auto track3 = mcTracks.rawIteratorAt(*(&t3)); + } + auto track3 = mcTracks.rawIteratorAt(t3); - for (auto& sig : fRecMCSignals) { + for (auto const& sig : fRecMCSignals) { if (sig->CheckSignal(true, track1, track2, track3)) { - VarManager::FillTripleMC(track1, track2, track3, VarManager::fgValues); // nb! hardcoded for jpsiK + VarManager::FillTripleMC(track1, track2, track3, dqefficiency_helpers::varValues()); // nb! hardcoded for jpsiK - fHistMan->FillHistClass(Form("MCTruthGenSelBR_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGenSelBR_%s", sig->GetName()), dqefficiency_helpers::varValues()); // apply kinematic cuts if (track1.pt() < fConfigMCGenDileptonLegPtMin.value || std::abs(track1.eta()) > fConfigMCGenDileptonLegEtaAbs.value) { @@ -4988,7 +5003,7 @@ struct AnalysisDileptonTrack { if (track3.pt() < fConfigMCGenHadronPtMin.value || std::abs(track3.eta()) > fConfigMCGenHadronEtaAbs.value) { continue; } - fHistMan->FillHistClass(Form("MCTruthGenSelBRAccepted_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthGenSelBRAccepted_%s", sig->GetName()), dqefficiency_helpers::varValues()); } } } @@ -5002,26 +5017,31 @@ struct AnalysisDileptonTrack { { auto groupedMCTracks = mcTracks.sliceBy(perReducedMcEvent, event.reducedMCeventId()); groupedMCTracks.bindInternalIndicesTo(&mcTracks); - for (auto& t1 : groupedMCTracks) { + for (auto const& t1 : groupedMCTracks) { auto t1_raw = mcTracks.rawIteratorAt(t1.globalIndex()); // apply kinematic cuts for signal - if ((t1_raw.pt() < fConfigDileptonLowpTCut || t1_raw.pt() > fConfigDileptonHighpTCut)) + if ((t1_raw.pt() < fConfigDileptonLowpTCut || t1_raw.pt() > fConfigDileptonHighpTCut)) { continue; - if (abs(t1_raw.y()) > fConfigDileptonRapCutAbs) + } + if (std::abs(t1_raw.y()) > fConfigDileptonRapCutAbs) { continue; + } // for the energy correlators - for (auto& t2 : groupedMCTracks) { + for (auto const& t2 : groupedMCTracks) { auto t2_raw = groupedMCTracks.rawIteratorAt(t2.globalIndex()); - if (TMath::Abs(t2_raw.pdgCode()) == 443 || TMath::Abs(t2_raw.pdgCode()) == 11 || TMath::Abs(t2_raw.pdgCode()) == 22) + if (std::abs(t2_raw.pdgCode()) == o2::constants::physics::Pdg::kJPsi || std::abs(t2_raw.pdgCode()) == PDG_t::kElectron || std::abs(t2_raw.pdgCode()) == PDG_t::kGamma) { continue; - if (t2_raw.pt() < fConfigMCGenHadronPtMin.value || std::abs(t2_raw.eta()) > fConfigMCGenHadronEtaAbs.value) + } + if (t2_raw.pt() < fConfigMCGenHadronPtMin.value || std::abs(t2_raw.eta()) > fConfigMCGenHadronEtaAbs.value) { continue; - if (t2_raw.getGenStatusCode() <= 0) + } + if (t2_raw.getGenStatusCode() <= 0) { continue; - VarManager::FillEnergyCorrelatorsMC(t1_raw, t2_raw, VarManager::fgValues); - for (auto& sig : fGenMCSignals) { + } + VarManager::FillEnergyCorrelatorsMC(t1_raw, t2_raw, dqefficiency_helpers::varValues()); + for (auto const& sig : fGenMCSignals) { if (sig->CheckSignal(true, t1_raw)) { - fHistMan->FillHistClass(Form("MCTruthEenergyCorrelators_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthEenergyCorrelators_%s", sig->GetName()), dqefficiency_helpers::varValues()); } } } @@ -5034,7 +5054,7 @@ struct AnalysisDileptonTrack { LOG(warning) << "No events in this TF, going to the next one ..."; return; } - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } @@ -5052,7 +5072,7 @@ struct AnalysisDileptonTrack { LOG(warning) << "No events in this TF, going to the next one ..."; return; } - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } @@ -5070,26 +5090,31 @@ struct AnalysisDileptonTrack { auto groupedMCTracks2 = mcTracks.sliceBy(perReducedMcEvent, event2.reducedMCeventId()); groupedMCTracks1.bindInternalIndicesTo(&mcTracks); groupedMCTracks2.bindInternalIndicesTo(&mcTracks); - for (auto& t1 : groupedMCTracks1) { + for (auto const& t1 : groupedMCTracks1) { auto t1_raw = mcTracks.rawIteratorAt(t1.globalIndex()); // apply kinematic cuts for signal - if ((t1_raw.pt() < fConfigDileptonLowpTCut || t1_raw.pt() > fConfigDileptonHighpTCut)) + if ((t1_raw.pt() < fConfigDileptonLowpTCut || t1_raw.pt() > fConfigDileptonHighpTCut)) { continue; - if (abs(t1_raw.y()) > fConfigDileptonRapCutAbs) + } + if (std::abs(t1_raw.y()) > fConfigDileptonRapCutAbs) { continue; + } // for the energy correlators - for (auto& t2 : groupedMCTracks2) { + for (auto const& t2 : groupedMCTracks2) { auto t2_raw = groupedMCTracks2.rawIteratorAt(t2.globalIndex()); - if (TMath::Abs(t2_raw.pdgCode()) == 443 || TMath::Abs(t2_raw.pdgCode()) == 11 || TMath::Abs(t2_raw.pdgCode()) == 22) + if (std::abs(t2_raw.pdgCode()) == o2::constants::physics::Pdg::kJPsi || std::abs(t2_raw.pdgCode()) == PDG_t::kElectron || std::abs(t2_raw.pdgCode()) == PDG_t::kGamma) { continue; - if (t2_raw.pt() < fConfigMCGenHadronPtMin.value || std::abs(t2_raw.eta()) > fConfigMCGenHadronEtaAbs.value) + } + if (t2_raw.pt() < fConfigMCGenHadronPtMin.value || std::abs(t2_raw.eta()) > fConfigMCGenHadronEtaAbs.value) { continue; - if (t2_raw.getGenStatusCode() <= 0) + } + if (t2_raw.getGenStatusCode() <= 0) { continue; - VarManager::FillEnergyCorrelatorsMC(t1_raw, t2_raw, VarManager::fgValues); - for (auto& sig : fGenMCSignals) { + } + VarManager::FillEnergyCorrelatorsMC(t1_raw, t2_raw, dqefficiency_helpers::varValues()); + for (auto const& sig : fGenMCSignals) { if (sig->CheckSignal(true, t1_raw)) { - fHistMan->FillHistClass(Form("MCTruthEenergyCorrelatorsME_%s", sig->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("MCTruthEenergyCorrelatorsME_%s", sig->GetName()), dqefficiency_helpers::varValues()); } } } @@ -5104,7 +5129,7 @@ struct AnalysisDileptonTrack { return; } // loop over two event comibnations - for (auto& [event1, event2] : selfCombinations(fHashBin, fConfigMixingDepth.value, -1, events, events)) { + for (auto const& [event1, event2] : selfCombinations(fHashBin, fConfigMixingDepth.value, -1, events, events)) { if (!event1.isEventSelected_bit(0) || !event2.isEventSelected_bit(0)) { continue; } @@ -5123,7 +5148,7 @@ struct AnalysisDileptonTrack { return; } // loop over two event comibnations - for (auto& [event1, event2] : selfCombinations(fHashBin, fConfigMixingDepth.value, -1, events, events)) { + for (auto const& [event1, event2] : selfCombinations(fHashBin, fConfigMixingDepth.value, -1, events, events)) { if (!event1.isEventSelected_bit(0) || !event2.isEventSelected_bit(0)) { continue; } @@ -5134,7 +5159,7 @@ struct AnalysisDileptonTrack { } } - void processDummy(MyEvents&) + void processDummy(MyEvents const&) { // do nothing } @@ -5163,7 +5188,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) adaptAnalysisTask(cfgc)}; } -void DefineHistograms(HistogramManager* histMan, TString histClasses, const char* histGroups) +void DefineHistograms(HistogramManager* histMan, const TString& histClasses, const char* histGroups) { // // Define here the histograms for all the classes required in analysis. diff --git a/PWGDQ/Tasks/dqEfficiency_withAssoc_direct.cxx b/PWGDQ/Tasks/dqEfficiency_withAssoc_direct.cxx index 5a437d6f091..bfb437c1ef6 100644 --- a/PWGDQ/Tasks/dqEfficiency_withAssoc_direct.cxx +++ b/PWGDQ/Tasks/dqEfficiency_withAssoc_direct.cxx @@ -1640,7 +1640,7 @@ struct AnalysisSameEventPairing { // Template function to run same event pairing (barrel-barrel, muon-muon, barrel-muon) template - void runSameEventPairing(TEvents const& events, BCsWithTimestamps const& bcs, Preslice>& preslice, soa::Join const& assocs, TTracks const& tracks, TEventsMC const& mcEvents, McParticles const& /*mcTracks*/) + void runSameEventPairing(TEvents const& events, BCsWithTimestamps const& bcs, Preslice>& preslice, soa::Join const& assocs, TTracks const& tracks, TEventsMC const& mcEvents, McParticles const& mcTracks) { cout << "AnalysisSameEventPairing::runSameEventPairing() called" << endl; if (events.size() == 0) { @@ -1672,6 +1672,7 @@ struct AnalysisSameEventPairing { // estimate reserved size int64_t reserveSize = 0; + int64_t reserveSizeGen = mcTracks.size(); for (auto& event : events) { if (event.isEventSelected_bit(0)) { auto groupedAssocs = assocs.sliceBy(preslice, event.globalIndex()); @@ -1700,7 +1701,7 @@ struct AnalysisSameEventPairing { dielectronAllList.reserve(reserveSize); } if (fConfigOptions.fConfigMiniTree) { - dileptonMiniTreeGen.reserve(reserveSize); + dileptonMiniTreeGen.reserve(reserveSizeGen); dileptonMiniTreeRec.reserve(reserveSize); } diff --git a/PWGDQ/Tasks/global-muon-matcher.cxx b/PWGDQ/Tasks/global-muon-matcher.cxx new file mode 100644 index 00000000000..c16f2917b6e --- /dev/null +++ b/PWGDQ/Tasks/global-muon-matcher.cxx @@ -0,0 +1,1686 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +/// \file global-muon-matcher.cxx +/// \brief Task for analysis MFT-MCH muon matching +/// \author Andrea Ferrero +/// +#include "PWGDQ/Core/MuonMatchingMlResponse.h" +#include "PWGDQ/Core/VarManager.h" + +#include "Common/Core/fwdtrackUtilities.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/FwdTrackReAlignTables.h" +#include "Tools/ML/MlResponse.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::aod; + +namespace o2::aod::globalmuonmatching +{ +DECLARE_SOA_COLUMN(MchTrackId, mchTrackId, int64_t); +DECLARE_SOA_COLUMN(MftTrackId, mftTrackId, int64_t); +DECLARE_SOA_COLUMN(MatchChi2, matchChi2, float); +DECLARE_SOA_COLUMN(MatchScore, matchScore, float); +DECLARE_SOA_COLUMN(MatchRanking, matchRanking, int32_t); +DECLARE_SOA_COLUMN(IsTagged, isTagged, bool); +} // namespace o2::aod::globalmuonmatching + +namespace o2::aod +{ +DECLARE_SOA_TABLE(GlobalMuonMatchCandidates, "AOD", "GMCAND", + o2::soa::Index<>, + globalmuonmatching::MchTrackId, + globalmuonmatching::MftTrackId, + globalmuonmatching::MatchChi2, globalmuonmatching::MatchScore, globalmuonmatching::MatchRanking, + globalmuonmatching::IsTagged); + +namespace globalmuonmatching +{ +DECLARE_SOA_ARRAY_INDEX_COLUMN(GlobalMuonMatchCandidate, globalMuonMatchCandidate); //! Array of GlobalMuonMatchCandidates indices +DECLARE_SOA_INDEX_COLUMN_FULL(FwdTrackRealign, fwdTrackRealign, int, FwdTracksReAlign, ""); //! Index of ambiguous FwdTracksReAlign entry +DECLARE_SOA_SLICE_INDEX_COLUMN_FULL(Bc, bc, int32_t, BCs, ""); //! BC index slice compatible with the track time window +} // namespace globalmuonmatching + +DECLARE_SOA_TABLE(FwdTrkMatchCands, "AOD", "FWDTRKMATCHCAND", //! Vectors of match-candidate indices stored per fwdtrack + globalmuonmatching::GlobalMuonMatchCandidateIds, o2::soa::Marker<3>); + +DECLARE_SOA_TABLE(AmbiguousFwdTracksReAlign, "AOD", "AMBIGFWDREALIGN", //! FwdTracksReAlign entries without a unique collision association + o2::soa::Index<>, globalmuonmatching::FwdTrackRealignId, globalmuonmatching::BcIdSlice); +} // namespace o2::aod + +using MyEvents = soa::Join; +using MyMuons = soa::Join; +using MyMFTs = aod::MFTTracks; +using MyMFTCovariances = aod::MFTTracksCov; + +using SMatrix55Sym = o2::track::SMatrix55Sym; +using SMatrix55Std = o2::track::SMatrix55Std; +using SMatrix5 = o2::track::SMatrix5; + +constexpr std::array NDetElemCh = {4, 4, 4, 4, 18, 18, 26, 26, 26, 26}; +constexpr std::array SNDetElemCh = {0, 4, 8, 12, 16, 34, 52, 78, 104, 130, 156}; + +struct GlobalMuonMatching { + + static constexpr int GlobalTrackTypeMax = 2; + static constexpr int MchMidTrackType = 3; + static constexpr int NMchChambers = 10; + static constexpr int MchDetElemNumberingBase = 100; + static constexpr int NMchDetElems = 156; + static constexpr int MinRemovableTrackClusters = 10; + static constexpr int ThetaAbsBoundaryDeg = 3; + static constexpr double SlopeResolutionZ = 535.; + static constexpr float MatchingPlaneDefaultZ = -77.5; + + struct MatchingCandidate { + int64_t muonTrackId{-1}; + int64_t mftTrackId{-1}; + double matchScore{-1}; + double matchChi2{-1}; + int matchRanking{-1}; + }; + + //// Variables for selecting tagged muons + struct : ConfigurableGroup { + Configurable cfgMuonTaggingNCrossedMftPlanesLow{"cfgMuonTaggingNCrossedMftPlanesLow", 5, ""}; + Configurable cfgMuonTaggingTrackChi2MchUp{"cfgMuonTaggingTrackChi2MchUp", 5.f, ""}; + Configurable cfgMuonTaggingPMchLow{"cfgMuonTaggingPMchLow", 0.0f, ""}; + Configurable cfgMuonTaggingPtMchLow{"cfgMuonTaggingPtMchLow", 0.7f, ""}; + Configurable cfgMuonTaggingEtaMchLow{"cfgMuonTaggingEtaMchLow", -3.6f, ""}; + Configurable cfgMuonTaggingEtaMchUp{"cfgMuonTaggingEtaMchUp", -2.5f, ""}; + Configurable cfgMuonTaggingRabsLow{"cfgMuonTaggingRabsLow", 17.6f, ""}; + Configurable cfgMuonTaggingRabsUp{"cfgMuonTaggingRabsUp", 89.5f, ""}; + Configurable cfgMuonTaggingPdcaUp{"cfgMuonTaggingPdcaUp", 4.f, ""}; + Configurable cfgMuonTaggingRadiusAtMftFrontLow{"cfgMuonTaggingRadiusAtMftFrontLow", 3.f, ""}; + Configurable cfgMuonTaggingRadiusAtMftFrontUp{"cfgMuonTaggingRadiusAtMftFrontUp", 9.f, ""}; + Configurable cfgMuonTaggingRadiusAtMftBackLow{"cfgMuonTaggingRadiusAtMftBackLow", 5.f, ""}; + Configurable cfgMuonTaggingRadiusAtMftBackUp{"cfgMuonTaggingRadiusAtMftBackUp", 12.f, ""}; + } configMuonTagging; + + //// Variables for MCH realignment + struct : ConfigurableGroup { + Configurable cfgEnableMCHRealign{"cfgEnableMCHRealign", true, "Enable re-alignment of MCH clusters and tracks"}; + Configurable cfgGeoRefPath{"cfgGeoRefPath", "GLO/Config/GeometryAligned", "Path of the reference geometry file"}; + Configurable cfgGeoNewPath{"cfgGeoNewPath", "GLO/Config/GeometryAligned", "Path of the new geometry file"}; + Configurable cfgCcdbNoLaterThanRef{"cfgCcdbNoLaterThanRef", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object of reference basis"}; + Configurable cfgCcdbNoLaterThanNew{"cfgCcdbNoLaterThanNew", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object of new basis"}; + Configurable cfgChamberResolutionX{"cfgChamberResolutionX", 0.04, "Chamber resolution along X configuration for refit"}; // 0.4cm pp, 0.2cm PbPb + Configurable cfgChamberResolutionY{"cfgChamberResolutionY", 0.04, "Chamber resolution along Y configuration for refit"}; // 0.4cm pp, 0.2cm PbPb + Configurable cfgSigmaCutImprove{"cfgSigmaCutImprove", 6., "Sigma cut for track improvement"}; // 6 for pp, 4 for PbPb + } configMchRealign; + + //// Variables for MFT alignment corrections + struct : ConfigurableGroup { + Configurable cfgEnableMftAlignmentCorrections{"cfgEnableMftAlignmentCorrections", true, "Enable alignment corrections for the MFT tracks"}; + // slope corrections + // Configurable cfgMFTAlignmentCorrXSlopeTop{"cfgMFTAlignmentCorrXSlopeTop", (-0.0006696 - 0.0005621) / 2.f, "MFT X slope correction - top half"}; + // Configurable cfgMFTAlignmentCorrXSlopeBottom{"cfgMFTAlignmentCorrXSlopeBottom", (0.00105 + 0.001007) / 2.f, "MFT X slope correction - bottom half"}; + // Configurable cfgMFTAlignmentCorrYSlopeTop{"cfgMFTAlignmentCorrYSlopeTop", (-0.002299 - 0.002442) / 2.f, "MFT Y slope correction - top half"}; + // Configurable cfgMFTAlignmentCorrYSlopeBottom{"cfgMFTAlignmentCorrYSlopeBottom", (-0.0005339 - 0.0006921) / 2.f, "MFT Y slope correction - bottom half"}; + Configurable cfgMFTAlignmentCorrXSlopeTop{"cfgMFTAlignmentCorrXSlopeTop", 0.f, "MFT X slope correction - top half"}; + Configurable cfgMFTAlignmentCorrXSlopeBottom{"cfgMFTAlignmentCorrXSlopeBottom", 0.f, "MFT X slope correction - bottom half"}; + Configurable cfgMFTAlignmentCorrYSlopeTop{"cfgMFTAlignmentCorrYSlopeTop", 0.f, "MFT Y slope correction - top half"}; + Configurable cfgMFTAlignmentCorrYSlopeBottom{"cfgMFTAlignmentCorrYSlopeBottom", 0.f, "MFT Y slope correction - bottom half"}; + // offset corrections + Configurable cfgMFTAlignmentCorrXOffsetTop{"cfgMFTAlignmentCorrXOffsetTop", 0.f, "MFT X offset correction - top half"}; + Configurable cfgMFTAlignmentCorrXOffsetBottom{"cfgMFTAlignmentCorrXOffsetBottom", 0.f, "MFT X offset correction - bottom half"}; + Configurable cfgMFTAlignmentCorrYOffsetTop{"cfgMFTAlignmentCorrYOffsetTop", 0.f, "MFT Y offset correction - top half"}; + Configurable cfgMFTAlignmentCorrYOffsetBottom{"cfgMFTAlignmentCorrYOffsetBottom", 0.f, "MFT Y offset correction - bottom half"}; + } configMftAlignmentCorrections; + + // Variables for CCDB objects access and retrieval + struct : ConfigurableGroup { + Configurable cfgCcdbUrl{"cfgCcdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable cfgCcdbNoLaterThan{"cfgCcdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + Configurable cfgGrpPath{"cfgGrpPath", "GLO/GRP/GRP", "Path of the grp file"}; + Configurable cfgGeoPath{"cfgGeoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + Configurable cfgGrpMagPath{"cfgGrpMagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + } configCcdb; + + // Matching strategy for the *custom* matches (production baseline is always computed). + // 0 = chi2 (runChi2Matching), 1 = ML (runMlMatching) + struct : ConfigurableGroup { + Configurable cfgCustomMatchingStrategy{"cfgCustomMatchingStrategy", 0, "0=chi2, 1=ML for custom matches"}; + Configurable cfgIncludeGlobalMuonsInFwdTracks{"cfgIncludeGlobalMuonsInFwdTracks", false, "Include MFT-MCH-MID global muons in GMMCANDTRK table"}; + Configurable cfgMaxCandidatesPerMchTrack{"cfgMaxCandidatesPerMchTrack", -1, "Maximum number of match candidates stored per MCH track (-1: no limit)"}; + Configurable cfgMatchAllTracks{"cfgMatchAllTracks", false, "If true the matching is performed considering all the MFT tracks for which the covariances are available; if false the matching is performed considering only the global forward tracks stored at production"}; + } configMatching; + + double mBzAtMftCenter{0}; + + using MatchingFunc = std::function(const o2::track::TrackParCovFwd& mchtrack, const o2::track::TrackParCovFwd& mfttrack)>; + std::map mMatchingFunctionMap; ///< MFT-MCH Matching function + + // Chi2 matching interface (single configurable method) + struct : ConfigurableGroup { + Configurable cfgChi2FunctionLabel{"cfgChi2FunctionLabel", std::string{"ProdAll"}, "Text label identifying the chi2 matching method"}; + Configurable cfgChi2FunctionName{"cfgChi2FunctionName", std::string{"prod"}, "Name of the chi2 matching function"}; + Configurable cfgChi2FunctionMatchingPlaneZ{"cfgChi2FunctionMatchingPlaneZ", static_cast(o2::mft::constants::mft::LayerZCoordinate()[9]), "Z position of the matching plane"}; + } configChi2MatchingOptions; + + // ML interface (single configurable model) + struct : ConfigurableGroup { + Configurable cfgMlModelLabel{"cfgMlModelLabel", std::string{""}, "Text label identifying this ML model"}; + Configurable cfgMlModelPathCcdb{"cfgMlModelPathCcdb", "Users/m/mcoquet/MLTest", "Path of model on CCDB"}; + Configurable cfgMlModelName{"cfgMlModelName", "model.onnx", "ONNX file name (if not from CCDB full path)"}; + Configurable> cfgMlInputFeatures{"cfgMlInputFeatures", std::vector{"chi2MCHMFT"}, "Names of ML model input features"}; + Configurable cfgMlModelMatchingPlaneZ{"cfgMlModelMatchingPlaneZ", static_cast(o2::mft::constants::mft::LayerZCoordinate()[9]), "Z position of the matching plane"}; + } configMlOptions; + + std::vector binsPtMl; + std::array cutValues{}; + std::vector cutDirMl; + bool hasActiveChi2Matching{false}; + std::string activeChi2FunctionName; + double activeChi2MatchingPlaneZ{0.}; + + bool hasActiveMlMatching{false}; + o2::analysis::MlResponseMFTMuonMatch activeMlResponse; + double activeMlMatchingPlaneZ{0.}; + + int mRunNumber{0}; // needed to detect if the run changed and trigger update of magnetic field + + Service ccdbManager{}; + o2::ccdb::CcdbApi fCCDBApi; + + // vector of all MFT-MCH(-MID) matching candidates associated to the same MCH(-MID) track, + // to be sorted in descending order with respect to the matching score + // the map key is the MCH(-MID) track global index + using MatchingCandidates = std::map>; + std::map> mMatchingCandidates; + + class TrackParExt : public o2::track::TrackParCovFwd + { + public: + TrackParExt() = default; + TrackParExt(const TrackParExt& t) = default; + explicit TrackParExt(o2::track::TrackParCovFwd const& t, int nc = -1, bool r = false) + : TrackParCovFwd(t), nClusters(nc), removable(r) {} + ~TrackParExt() = default; + + TrackParExt& operator=(const TrackParCovFwd& tpf) + { + o2::track::TrackParCovFwd::operator=(tpf); + return *this; + } + TrackParExt& operator=(const TrackParExt& tpe) + { + o2::track::TrackParCovFwd::operator=(tpe); + nClusters = tpe.getNClusters(); + removable = tpe.isRemovable(); + return *this; + } + + void setNClusters(int n) { nClusters = n; } + [[nodiscard]] int getNClusters() const { return nClusters; } + + void setRemovable() { removable = true; } + [[nodiscard]] bool isRemovable() const { return removable; } + + [[nodiscard]] o2::track::TrackParCovFwd asTrackParCovFwd() const { return *this; } + + private: + int nClusters{-1}; + bool removable{false}; + }; + + std::unordered_map mMchTrackPars; + std::unordered_map mMftTrackPars; + + std::unordered_map mftTrackCovs; + + Produces globalMuonMatchCandidates; + Produces fwdTrkMatchCands; + Produces gmCandidateFwdTracks; + Produces gmCandidateFwdTracksCov; + Produces gmAmbiguousFwdTracksReAlign; + + int32_t mGmmCandFwdTrackRowIndex{0}; + std::unordered_map> mAmbBcSliceByFwdTrackId; + bool mHasLastMchAmbiguousBcSlice{false}; + std::array mLastMchAmbiguousBcSlice{}; + + int32_t mMatchCandidateCounter{0}; + std::unordered_map> mMchTrackToCandidateIndices; + std::unordered_map> mMchTrackMatchingCandidates; + std::unordered_map mFwdTrackToGmmCandTrkIndex; + + mch::TrackFitter trackFitter; // Track fitter from MCH tracking library + mch::geo::TransformationCreator transformation; + std::map transformRef; // reference geometry w.r.t track data + std::map transformNew; // new geometry + double mImproveCutChi2{0.}; // Chi2 cut for track improvement. + TGeoManager* geoNew = nullptr; + TGeoManager* geoRef = nullptr; + globaltracking::MatchGlobalFwd mMatching; + + Preslice perMuon = aod::fwdtrkcl::fwdtrackId; + + template + o2::mch::TrackParam fwdToMch(const T& fwdtrack) + { + // Convert Forward Track parameters and covariances matrix to the + // MCH track format. + + // Parameter conversion + const double x2 = fwdtrack.getPhi(); + const double x3 = fwdtrack.getTanl(); + const double x4 = fwdtrack.getInvQPt(); + + const auto sinX2 = std::sin(x2); + const auto cosX2 = std::cos(x2); + + const double alpha1 = cosX2 / x3; + const double alpha3 = sinX2 / x3; + const double alpha4 = x4 / std::sqrt(x3 * x3 + sinX2 * sinX2); + + const auto kNorm = std::sqrt(x3 * x3 + sinX2 * sinX2); + const auto kNorm3 = kNorm * kNorm * kNorm; + + // Covariances matrix conversion + SMatrix55Std jacobian; + SMatrix55Sym covariances; + + covariances(0, 0) = fwdtrack.getCovariances()(0, 0); + covariances(0, 1) = fwdtrack.getCovariances()(0, 1); + covariances(0, 2) = fwdtrack.getCovariances()(0, 2); + covariances(0, 3) = fwdtrack.getCovariances()(0, 3); + covariances(0, 4) = fwdtrack.getCovariances()(0, 4); + + covariances(1, 1) = fwdtrack.getCovariances()(1, 1); + covariances(1, 2) = fwdtrack.getCovariances()(1, 2); + covariances(1, 3) = fwdtrack.getCovariances()(1, 3); + covariances(1, 4) = fwdtrack.getCovariances()(1, 4); + + covariances(2, 2) = fwdtrack.getCovariances()(2, 2); + covariances(2, 3) = fwdtrack.getCovariances()(2, 3); + covariances(2, 4) = fwdtrack.getCovariances()(2, 4); + + covariances(3, 3) = fwdtrack.getCovariances()(3, 3); + covariances(3, 4) = fwdtrack.getCovariances()(3, 4); + + covariances(4, 4) = fwdtrack.getCovariances()(4, 4); + + jacobian(0, 0) = 1; + + jacobian(1, 2) = -sinX2 / x3; + jacobian(1, 3) = -cosX2 / (x3 * x3); + + jacobian(2, 1) = 1; + + jacobian(3, 2) = cosX2 / x3; + jacobian(3, 3) = -sinX2 / (x3 * x3); + + jacobian(4, 2) = -x4 * sinX2 * cosX2 / kNorm3; + jacobian(4, 3) = -x3 * x4 / kNorm3; + jacobian(4, 4) = 1 / kNorm; + // jacobian*covariances*jacobian^T + covariances = ROOT::Math::Similarity(jacobian, covariances); + + std::array cov = {covariances(0, 0), covariances(1, 0), covariances(1, 1), covariances(2, 0), covariances(2, 1), covariances(2, 2), covariances(3, 0), covariances(3, 1), covariances(3, 2), covariances(3, 3), covariances(4, 0), covariances(4, 1), covariances(4, 2), covariances(4, 3), covariances(4, 4)}; + std::array param = {fwdtrack.getX(), alpha1, fwdtrack.getY(), alpha3, alpha4}; + + o2::mch::TrackParam convertedTrack(fwdtrack.getZ(), param.data(), cov.data()); + return {convertedTrack}; + } + + o2::track::TrackParCovFwd mchToFwd(const o2::mch::TrackParam& mchParam) + { + // Convert a MCH Track parameters and covariances matrix to the + // Forward track format. Must be called after propagation though the absorber + + o2::track::TrackParCovFwd convertedTrack; + + // Parameter conversion + const double alpha1 = mchParam.getNonBendingSlope(); + const double alpha3 = mchParam.getBendingSlope(); + const double alpha4 = mchParam.getInverseBendingMomentum(); + + const double x2 = std::atan2(-alpha3, -alpha1); + const double x3 = -1. / std::sqrt(alpha3 * alpha3 + alpha1 * alpha1); + const double x4 = alpha4 * -x3 * std::sqrt(1 + alpha3 * alpha3); + + const auto kNorm = alpha1 * alpha1 + alpha3 * alpha3; + const auto kNorm32 = kNorm * std::sqrt(kNorm); + const auto slopeLen = std::sqrt(alpha3 * alpha3 + 1); + + // Covariances matrix conversion + SMatrix55Std jacobian; + SMatrix55Sym covariances; + + covariances(0, 0) = mchParam.getCovariances()(0, 0); + covariances(0, 1) = mchParam.getCovariances()(0, 1); + covariances(0, 2) = mchParam.getCovariances()(0, 2); + covariances(0, 3) = mchParam.getCovariances()(0, 3); + covariances(0, 4) = mchParam.getCovariances()(0, 4); + + covariances(1, 1) = mchParam.getCovariances()(1, 1); + covariances(1, 2) = mchParam.getCovariances()(1, 2); + covariances(1, 3) = mchParam.getCovariances()(1, 3); + covariances(1, 4) = mchParam.getCovariances()(1, 4); + + covariances(2, 2) = mchParam.getCovariances()(2, 2); + covariances(2, 3) = mchParam.getCovariances()(2, 3); + covariances(2, 4) = mchParam.getCovariances()(2, 4); + + covariances(3, 3) = mchParam.getCovariances()(3, 3); + covariances(3, 4) = mchParam.getCovariances()(3, 4); + + covariances(4, 4) = mchParam.getCovariances()(4, 4); + + jacobian(0, 0) = 1; + + jacobian(1, 2) = 1; + + jacobian(2, 1) = -alpha3 / kNorm; + jacobian(2, 3) = alpha1 / kNorm; + + jacobian(3, 1) = alpha1 / kNorm32; + jacobian(3, 3) = alpha3 / kNorm32; + + jacobian(4, 1) = -alpha1 * alpha4 * slopeLen / kNorm32; + jacobian(4, 3) = alpha3 * alpha4 * (1 / (std::sqrt(kNorm) * slopeLen) - slopeLen / kNorm32); + jacobian(4, 4) = slopeLen / std::sqrt(kNorm); + + // jacobian*covariances*jacobian^T + covariances = ROOT::Math::Similarity(jacobian, covariances); + + // Set output + convertedTrack.setX(mchParam.getNonBendingCoor()); + convertedTrack.setY(mchParam.getBendingCoor()); + convertedTrack.setZ(mchParam.getZ()); + convertedTrack.setPhi(x2); + convertedTrack.setTanl(x3); + convertedTrack.setInvQPt(x4); + convertedTrack.setCharge(mchParam.getCharge()); + convertedTrack.setCovariances(covariances); + + return convertedTrack; + } + + int getDetElemId(int iDetElemNumber) + { + // make sure detector number is valid + if (iDetElemNumber < SNDetElemCh[0] || + iDetElemNumber >= SNDetElemCh[NMchChambers]) { + LOGF(fatal, "Invalid detector element number: %d", iDetElemNumber); + } + /// get det element number from ID + // get chamber and element number in chamber + int iCh = 0; + int iDet = 0; + for (int i = 1; i <= NMchChambers; i++) { + if (iDetElemNumber < SNDetElemCh[i]) { + iCh = i; + iDet = iDetElemNumber - SNDetElemCh[i - 1]; + break; + } + } + + // make sure detector index is valid + if (iCh <= 0 || iCh > NMchChambers || iDet >= NDetElemCh[iCh - 1]) { + LOGF(fatal, "Invalid detector element id: %d", MchDetElemNumberingBase * iCh + iDet); + } + + // add number of detectors up to this chamber + return MchDetElemNumberingBase * iCh + iDet; + } + + bool removeTrack(mch::Track& track) + { + // Refit track with re-aligned clusters + bool shouldRemoveTrack = false; + try { + trackFitter.fit(track, false); + } catch (std::exception const& e) { + shouldRemoveTrack = true; + return shouldRemoveTrack; + } + + auto itStartingParam = std::prev(track.rend()); + + while (true) { + + try { + trackFitter.fit(track, true, false, (itStartingParam == track.rbegin()) ? nullptr : &itStartingParam); + } catch (std::exception const&) { + shouldRemoveTrack = true; + break; + } + + double worstLocalChi2 = -1.0; + + track.tagRemovableClusters(0x1F, false); + + auto itWorstParam = track.end(); + + for (auto itParam = track.begin(); itParam != track.end(); ++itParam) { + if (itParam->getLocalChi2() > worstLocalChi2) { + worstLocalChi2 = itParam->getLocalChi2(); + itWorstParam = itParam; + } + } + + if (worstLocalChi2 < mImproveCutChi2) { + break; + } + + if (!itWorstParam->isRemovable()) { + shouldRemoveTrack = true; + track.removable(); + break; + } + + auto itNextParam = track.removeParamAtCluster(itWorstParam); + auto itNextToNextParam = (itNextParam == track.end()) ? itNextParam : std::next(itNextParam); + itStartingParam = track.rbegin(); + + if (track.getNClusters() < MinRemovableTrackClusters) { + shouldRemoveTrack = true; + break; + } + while (itNextToNextParam != track.end()) { + if (itNextToNextParam->getClusterPtr()->getChamberId() != itNextParam->getClusterPtr()->getChamberId()) { + itStartingParam = std::make_reverse_iterator(++itNextParam); + break; + } + ++itNextToNextParam; + } + } + + if (!shouldRemoveTrack) { + for (auto& param : track) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) + param.setParameters(param.getSmoothParameters()); + param.setCovariances(param.getSmoothCovariances()); + } + } + + return shouldRemoveTrack; + } + + template + void initCcdb(BC const& bc) + { + if (mRunNumber == bc.runNumber()) { + return; + } + + mRunNumber = bc.runNumber(); + std::map metadata; + auto soreor = o2::ccdb::BasicCCDBManager::getRunDuration(fCCDBApi, mRunNumber); + auto ts = soreor.first; + auto grpmag = fCCDBApi.retrieveFromTFileAny(configCcdb.cfgGrpMagPath, metadata, ts); + o2::base::Propagator::initFieldFromGRP(grpmag); + LOGF(info, "Set field for muons"); + VarManager::SetupMuonMagField(); + if (!o2::base::GeometryManager::isGeometryLoaded()) { + ccdbManager->get(configCcdb.cfgGeoPath); + } + mch::TrackExtrap::setField(); + mch::TrackExtrap::useExtrapV2(); + + // Load geometry information from CCDB/local + LOGF(info, "Loading reference aligned geometry from CCDB no later than %d", configMchRealign.cfgCcdbNoLaterThanRef.value); + ccdbManager->setCreatedNotAfter(configMchRealign.cfgCcdbNoLaterThanRef.value); // this timestamp has to be consistent with what has been used in reco + geoRef = ccdbManager->getForTimeStamp(configMchRealign.cfgGeoRefPath, bc.timestamp()); + ccdbManager->clearCache(configMchRealign.cfgGeoRefPath); + if (geoRef != nullptr) { + transformation = mch::geo::transformationFromTGeoManager(*geoRef); + } else { + LOGF(fatal, "Reference aligned geometry object is not available in CCDB at timestamp=%llu", bc.timestamp()); + } + for (int i = 0; i < NMchDetElems; i++) { + int iDEN = getDetElemId(i); + transformRef[iDEN] = transformation(iDEN); + } + + LOGF(info, "Loading new aligned geometry from CCDB no later than %d", configMchRealign.cfgCcdbNoLaterThanNew.value); + ccdbManager->setCreatedNotAfter(configMchRealign.cfgCcdbNoLaterThanNew.value); // make sure this timestamp can be resolved regarding the reference one + geoNew = ccdbManager->getForTimeStamp(configMchRealign.cfgGeoNewPath, bc.timestamp()); + ccdbManager->clearCache(configMchRealign.cfgGeoNewPath); + if (geoNew != nullptr) { + transformation = mch::geo::transformationFromTGeoManager(*geoNew); + } else { + LOGF(fatal, "New aligned geometry object is not available in CCDB at timestamp=%llu", bc.timestamp()); + } + for (int i = 0; i < NMchDetElems; i++) { + int iDEN = getDetElemId(i); + transformNew[iDEN] = transformation(iDEN); + } + + // Init magnetic field for MFT track extrapolation + auto* fieldB = dynamic_cast(TGeoGlobalMagField::Instance()->GetField()); + if (fieldB) { + std::array centerMft{0, 0, -61.4}; // Field at center of MFT + mBzAtMftCenter = fieldB->getBz(centerMft.data()); + // std::cout << "fieldB: " << (void*)fieldB << std::endl; + } + } + + void initMatchingFunctions() + { + using SVector2 = ROOT::Math::SVector; + using SVector4 = ROOT::Math::SVector; + using SVector5 = ROOT::Math::SVector; + + using SMatrix44 = ROOT::Math::SMatrix; + using SMatrix45 = ROOT::Math::SMatrix; + using SMatrix22 = ROOT::Math::SMatrix; + using SMatrix25 = ROOT::Math::SMatrix; + + // Define built-in matching functions + //________________________________________________________________________________ + mMatchingFunctionMap["matchALL"] = [](const o2::track::TrackParCovFwd& mchTrack, const o2::track::TrackParCovFwd& mftTrack) -> std::tuple { + // Match two tracks evaluating all parameters: X,Y, phi, tanl & q/pt + + SMatrix55Sym hK, vK; + SVector5 mK(mftTrack.getX(), mftTrack.getY(), mftTrack.getPhi(), + mftTrack.getTanl(), mftTrack.getInvQPt()), + rKKminus1; + const auto& globalMuonTrackParameters = mchTrack.getParameters(); + const auto& globalMuonTrackCovariances = mchTrack.getCovariances(); + vK(0, 0) = mftTrack.getCovariances()(0, 0); + vK(1, 1) = mftTrack.getCovariances()(1, 1); + vK(2, 2) = mftTrack.getCovariances()(2, 2); + vK(3, 3) = mftTrack.getCovariances()(3, 3); + vK(4, 4) = mftTrack.getCovariances()(4, 4); + hK(0, 0) = 1.0; + hK(1, 1) = 1.0; + hK(2, 2) = 1.0; + hK(3, 3) = 1.0; + hK(4, 4) = 1.0; + + // Covariance of residuals + SMatrix55Std invResCov = (vK + ROOT::Math::Similarity(hK, globalMuonTrackCovariances)); + invResCov.Invert(); + + // Update Parameters + rKKminus1 = mK - hK * globalMuonTrackParameters; // Residuals of prediction + + auto matchChi2Track = ROOT::Math::Similarity(rKKminus1, invResCov); + + // return chi2 and NDF + return {matchChi2Track, 5}; + }; + + //________________________________________________________________________________ + mMatchingFunctionMap["matchXYPhiTanl"] = [](const o2::track::TrackParCovFwd& mchTrack, const o2::track::TrackParCovFwd& mftTrack) -> std::tuple { + // Match two tracks evaluating positions & angles + + SMatrix45 hK; + SMatrix44 vK; + SVector4 mK(mftTrack.getX(), mftTrack.getY(), mftTrack.getPhi(), + mftTrack.getTanl()), + rKKminus1; + const auto& globalMuonTrackParameters = mchTrack.getParameters(); + const auto& globalMuonTrackCovariances = mchTrack.getCovariances(); + vK(0, 0) = mftTrack.getCovariances()(0, 0); + vK(1, 1) = mftTrack.getCovariances()(1, 1); + vK(2, 2) = mftTrack.getCovariances()(2, 2); + vK(3, 3) = mftTrack.getCovariances()(3, 3); + hK(0, 0) = 1.0; + hK(1, 1) = 1.0; + hK(2, 2) = 1.0; + hK(3, 3) = 1.0; + + // Covariance of residuals + SMatrix44 invResCov = (vK + ROOT::Math::Similarity(hK, globalMuonTrackCovariances)); + invResCov.Invert(); + + // Residuals of prediction + rKKminus1 = mK - hK * globalMuonTrackParameters; + + auto matchChi2Track = ROOT::Math::Similarity(rKKminus1, invResCov); + + // return chi2 and NDF + return {matchChi2Track, 4}; + }; + + //________________________________________________________________________________ + mMatchingFunctionMap["matchXY"] = [](const o2::track::TrackParCovFwd& mchTrack, const o2::track::TrackParCovFwd& mftTrack) -> std::tuple { + // Calculate Matching Chi2 - X and Y positions + + SMatrix25 hK; + SMatrix22 vK; + SVector2 mK(mftTrack.getX(), mftTrack.getY()), rKKminus1; + const auto& globalMuonTrackParameters = mchTrack.getParameters(); + const auto& globalMuonTrackCovariances = mchTrack.getCovariances(); + vK(0, 0) = mftTrack.getCovariances()(0, 0); + vK(1, 1) = mftTrack.getCovariances()(1, 1); + hK(0, 0) = 1.0; + hK(1, 1) = 1.0; + + // Covariance of residuals + SMatrix22 invResCov = (vK + ROOT::Math::Similarity(hK, globalMuonTrackCovariances)); + invResCov.Invert(); + + // Residuals of prediction + rKKminus1 = mK - hK * globalMuonTrackParameters; + auto matchChi2Track = ROOT::Math::Similarity(rKKminus1, invResCov); + + // return reduced chi2 + return {matchChi2Track, 2}; + }; + } + + void init(o2::framework::InitContext&) + { + // Load geometry + ccdbManager->setURL(configCcdb.cfgCcdbUrl); + ccdbManager->setCaching(true); + ccdbManager->setLocalObjectValidityChecking(); + fCCDBApi.init(configCcdb.cfgCcdbUrl); + mRunNumber = 0; + + // Configuration for track fitter + const auto& trackerParam = mch::TrackerParam::Instance(); + trackFitter.setBendingVertexDispersion(trackerParam.bendingVertexDispersion); + trackFitter.setChamberResolution(configMchRealign.cfgChamberResolutionX.value, configMchRealign.cfgChamberResolutionY.value); + trackFitter.smoothTracks(true); + trackFitter.useChamberResolution(); + mImproveCutChi2 = 2. * configMchRealign.cfgSigmaCutImprove.value * configMchRealign.cfgSigmaCutImprove.value; + + // Reset matching configuration, then populate only what we need. + hasActiveChi2Matching = false; + activeChi2FunctionName.clear(); + activeChi2MatchingPlaneZ = 0.; + + hasActiveMlMatching = false; + activeMlMatchingPlaneZ = 0.; + + if (configMatching.cfgCustomMatchingStrategy.value == 0) { + // Matching functions (custom chi2) + initMatchingFunctions(); + auto label = configChi2MatchingOptions.cfgChi2FunctionLabel.value; + auto funcName = configChi2MatchingOptions.cfgChi2FunctionName.value; + auto matchingPlaneZ = configChi2MatchingOptions.cfgChi2FunctionMatchingPlaneZ.value; + + if (!label.empty() && !funcName.empty()) { + hasActiveChi2Matching = true; + activeChi2FunctionName = funcName; + activeChi2MatchingPlaneZ = matchingPlaneZ; + } + } else { + // Matching ML models (custom ML) + // TODO : for now we use hard coded values since the current models use 1 pT bin + binsPtMl = {-1e-6, 1000.0}; + cutValues = {0.0}; + cutDirMl = {cuts_ml::CutNot}; + LabeledArray mycutsMl(cutValues.data(), 1, 1, std::vector{"pT bin 0"}, std::vector{"score"}); + + auto label = configMlOptions.cfgMlModelLabel.value; + auto modelPath = configMlOptions.cfgMlModelPathCcdb.value; + auto inputFeatures = configMlOptions.cfgMlInputFeatures.value; + auto modelName = configMlOptions.cfgMlModelName.value; + auto matchingPlaneZ = configMlOptions.cfgMlModelMatchingPlaneZ.value; + + if (!label.empty() && !modelPath.empty() && !inputFeatures.empty() && !modelName.empty()) { + activeMlResponse.configure(binsPtMl, mycutsMl, cutDirMl, 1); + activeMlResponse.setModelPathsCCDB(std::vector{modelName}, fCCDBApi, std::vector{modelPath}, configCcdb.cfgCcdbNoLaterThan.value); + activeMlResponse.cacheInputFeaturesIndices(inputFeatures); + activeMlResponse.init(); + + hasActiveMlMatching = true; + activeMlMatchingPlaneZ = matchingPlaneZ; + } + } + } + + template + bool pDcaCut(const T& mchTrack, const C& collision, double nSigmaPDCA) + { + static const double sigmaPDCA23 = 80.; + static const double sigmaPDCA310 = 54.; + static const double relPRes = 0.0004; + static const double slopeRes = 0.0005; + + constexpr double AbsorberEndZ = 505.; + constexpr double RadToDeg = 180. / o2::constants::math::PI; + double thetaAbs = std::atan(mchTrack.rAtAbsorberEnd() / AbsorberEndZ) * RadToDeg; + + // propagate muon track to vertex + auto mchTrackAtVertex = VarManager::PropagateMuon(mchTrack, collision, VarManager::kToVertex); + + // double pUncorr = mchTrack.p(); + double p = mchTrackAtVertex.getP(); + + double pDCA = mchTrack.pDca(); + double sigmaPDCA = (thetaAbs < ThetaAbsBoundaryDeg) ? sigmaPDCA23 : sigmaPDCA310; + double nrp = nSigmaPDCA * relPRes * p; + double pResEffect = sigmaPDCA / (1. - nrp / (1. + nrp)); + double slopeResEffect = SlopeResolutionZ * slopeRes * p; + double sigmaPDCAWithRes = std::sqrt(pResEffect * pResEffect + slopeResEffect * slopeResEffect); + return pDCA <= nSigmaPDCA * sigmaPDCAWithRes; + } + + template + bool isGoodMuon(const T& mchTrack, const C& collision, + double chi2Cut, + double pCut, + double pTCut, + std::array etaCut, + std::array rAbsCut, + double nSigmaPdcaCut) + { + // chi2 cut + if (mchTrack.chi2() > chi2Cut) { + return false; + } + + // momentum cut + if (mchTrack.p() < pCut) { + return false; // skip low-momentum tracks + } + + // transverse momentum cut + if (mchTrack.pt() < pTCut) { + return false; // skip low-momentum tracks + } + + // Eta cut + double eta = mchTrack.eta(); + if ((eta < etaCut[0] || eta > etaCut[1])) { + return false; + } + + // RAbs cut + double rAbs = mchTrack.rAtAbsorberEnd(); + if ((rAbs < rAbsCut[0] || rAbs > rAbsCut[1])) { + return false; + } + + // pDCA cut + return pDcaCut(mchTrack, collision, nSigmaPdcaCut); + } + + void storeFwdTrackCovariance(const SMatrix55Sym& cov) + { + const float sigX = std::sqrt(cov(0, 0)); + const float sigY = std::sqrt(cov(1, 1)); + const float sigPhi = std::sqrt(cov(2, 2)); + const float sigTgl = std::sqrt(cov(3, 3)); + const float sig1Pt = std::sqrt(cov(4, 4)); + const auto rhoXY = static_cast(128.f * cov(0, 1) / (sigX * sigY)); + const auto rhoPhiX = static_cast(128.f * cov(0, 2) / (sigPhi * sigX)); + const auto rhoPhiY = static_cast(128.f * cov(1, 2) / (sigPhi * sigY)); + const auto rhoTglX = static_cast(128.f * cov(0, 3) / (sigTgl * sigX)); + const auto rhoTglY = static_cast(128.f * cov(1, 3) / (sigTgl * sigY)); + const auto rhoTglPhi = static_cast(128.f * cov(2, 3) / (sigTgl * sigPhi)); + const auto rho1PtX = static_cast(128.f * cov(0, 4) / (sig1Pt * sigX)); + const auto rho1PtY = static_cast(128.f * cov(1, 4) / (sig1Pt * sigY)); + const auto rho1PtPhi = static_cast(128.f * cov(2, 4) / (sig1Pt * sigPhi)); + const auto rho1PtTgl = static_cast(128.f * cov(3, 4) / (sig1Pt * sigTgl)); + gmCandidateFwdTracksCov(sigX, sigY, sigPhi, sigTgl, sig1Pt, + rhoXY, rhoPhiY, rhoPhiX, rhoTglX, rhoTglY, rhoTglPhi, rho1PtX, rho1PtY, rho1PtPhi, rho1PtTgl); + } + + template + void fillBaseGmmCandFwdTrack(TMCH const& track, + TrackParExt const& trackPar, + int32_t gmmMchTrackId, + float chi2MatchMCHMFT, + float matchScoreMCHMFT) + { + const auto collisionId = track.collisionId(); + bool hasBcSlice = false; + std::array bcSlice{}; + if (collisionId < 0) { + const auto ambIt = mAmbBcSliceByFwdTrackId.find(track.globalIndex()); + if (ambIt != mAmbBcSliceByFwdTrackId.end()) { + bcSlice = ambIt->second; + hasBcSlice = true; + } + } + + gmCandidateFwdTracks( + collisionId, + track.trackType(), + trackPar.getX(), + trackPar.getY(), + trackPar.getZ(), + trackPar.getPhi(), + trackPar.getTgl(), + trackPar.getInvQPt(), + trackPar.getNClusters(), + track.pDca(), + track.rAtAbsorberEnd(), + trackPar.isRemovable(), + trackPar.getTrackChi2(), + track.chi2MatchMCHMID(), + chi2MatchMCHMFT, + matchScoreMCHMFT, + track.matchMFTTrackId(), + gmmMchTrackId, + track.mchBitMap(), + track.midBitMap(), + track.midBoards(), + track.trackTime(), + track.trackTimeRes()); + + storeFwdTrackCovariance(trackPar.getCovariances()); + if (hasBcSlice) { + gmAmbiguousFwdTracksReAlign(mGmmCandFwdTrackRowIndex, bcSlice.data()); + } + mGmmCandFwdTrackRowIndex += 1; + + mHasLastMchAmbiguousBcSlice = hasBcSlice; + if (hasBcSlice) { + mLastMchAmbiguousBcSlice = bcSlice; + } + } + + template + void fillCandidateFwdTrack(TMCH const& mchTrack, + TrackParExt const& mchPar, + int32_t gmmMchTrackId, + TMFT const& mftTrack, + TrackParExt const& mftPar, + const MatchingCandidate& candidate) + { + using o2::aod::fwdtrack::ForwardTrackTypeEnum; + using o2::aod::fwdtrackutils::propagationPoint; + + constexpr uint8_t CandidateTrackType = static_cast(ForwardTrackTypeEnum::GlobalForwardTrack); + + auto propmuonAtMft = fwdToMch(mchPar); + o2::mch::TrackExtrap::extrapToVertex(propmuonAtMft, + mftPar.getX(), + mftPar.getY(), + mftPar.getZ(), + mftPar.getSigma2X(), + mftPar.getSigma2Y()); + + const auto globalMuonRefit = o2::aod::fwdtrackutils::refitGlobalMuonCov(mchToFwd(propmuonAtMft), mftPar); + + const auto nClusters = static_cast(std::min(127, mchPar.getNClusters() + mftPar.getNClusters())); + + const float chi2 = static_cast(mchTrack.chi2()); + const int32_t collisionId = mchTrack.collisionId(); + bool hasBcSlice = false; + std::array bcSlice{}; + if (collisionId < 0) { + if (mHasLastMchAmbiguousBcSlice) { + bcSlice = mLastMchAmbiguousBcSlice; + hasBcSlice = true; + } else { + const auto ambIt = mAmbBcSliceByFwdTrackId.find(mchTrack.globalIndex()); + if (ambIt != mAmbBcSliceByFwdTrackId.end()) { + bcSlice = ambIt->second; + hasBcSlice = true; + } + } + } + + bool isRemovable = mchPar.isRemovable(); + + gmCandidateFwdTracks( + collisionId, + CandidateTrackType, + globalMuonRefit.getX(), + globalMuonRefit.getY(), + globalMuonRefit.getZ(), + globalMuonRefit.getPhi(), + globalMuonRefit.getTgl(), + globalMuonRefit.getInvQPt(), + nClusters, + mchTrack.pDca(), + mchTrack.rAtAbsorberEnd(), + isRemovable, + chi2, + mchTrack.chi2MatchMCHMID(), + static_cast(candidate.matchChi2), + static_cast(candidate.matchScore), + static_cast(mftTrack.globalIndex()), + gmmMchTrackId, + mchTrack.mchBitMap(), + mchTrack.midBitMap(), + mchTrack.midBoards(), + mchTrack.trackTime(), + mchTrack.trackTimeRes()); + + storeFwdTrackCovariance(globalMuonRefit.getCovariances()); + if (hasBcSlice) { + gmAmbiguousFwdTracksReAlign(mGmmCandFwdTrackRowIndex, bcSlice.data()); + } + mGmmCandFwdTrackRowIndex += 1; + } + + o2::track::TrackParCovFwd propagateToZMch(const o2::track::TrackParCovFwd& muon, const double z) + { + auto mchTrack = fwdToMch(muon); + + float absFront = -90.f; + float absBack = -505.f; + + if (muon.getZ() < absBack && z > absFront) { + // extrapolation through the absorber in the upstream direction + o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchTrack, z); + } else { + // all other cases + o2::mch::TrackExtrap::extrapToZCov(mchTrack, z); + } + + return mchToFwd(mchTrack); + } + + o2::track::TrackParCovFwd propagateToZMft(const o2::track::TrackParCovFwd& mftTrack, const double z) + { + o2::track::TrackParCovFwd trackExtrap{mftTrack}; + trackExtrap.propagateToZ(z, mBzAtMftCenter); + return trackExtrap; + } + + template + o2::track::TrackParCovFwd propagateToVertexMch(const TMCH& muon, + const C& collision) + { + auto mchTrack = fwdToMch(fwdtrackutils::getTrackParCovFwd(muon, muon)); + o2::mch::TrackExtrap::extrapToVertex(mchTrack, + collision.posX(), + collision.posY(), + collision.posZ(), + collision.covXX(), + collision.covYY()); + return mchToFwd(mchTrack); + } + + // tag muons based on the track quality and the track position at the front and back MFT planes + template + void getTaggedMuons(C const& collisions, + TMUON const& muonTracks, + std::vector& taggedMuons) + { + taggedMuons.clear(); + for (const auto& muonTrack : muonTracks) { + + // only consider MCH-MID matches + if (static_cast(muonTrack.trackType()) != MchMidTrackType) { + continue; + } + + // only select MCH-MID tracks associated to a collision + if (!muonTrack.has_collision()) { + continue; + } + + const auto& collision = collisions.rawIteratorAt(muonTrack.collisionId()); + + // select MCH tracks with strict quality cuts + if (!isGoodMuon(muonTrack, collision, + configMuonTagging.cfgMuonTaggingTrackChi2MchUp, + configMuonTagging.cfgMuonTaggingPMchLow, + configMuonTagging.cfgMuonTaggingPtMchLow, + {configMuonTagging.cfgMuonTaggingEtaMchLow, configMuonTagging.cfgMuonTaggingEtaMchUp}, + {configMuonTagging.cfgMuonTaggingRabsLow, configMuonTagging.cfgMuonTaggingRabsUp}, + configMuonTagging.cfgMuonTaggingPdcaUp)) { + continue; + } + + // propagate MCH track to the vertex + auto mchTrackAtVertex = propagateToVertexMch(muonTrack, collision); + + // propagate the track from the vertex to the first MFT plane + const auto& extrapToMFTfirst = propagateToZMch(mchTrackAtVertex, o2::mft::constants::mft::LayerZCoordinate()[0]); + double rFront = std::sqrt(extrapToMFTfirst.getX() * extrapToMFTfirst.getX() + extrapToMFTfirst.getY() * extrapToMFTfirst.getY()); + if (rFront < configMuonTagging.cfgMuonTaggingRadiusAtMftFrontLow.value || rFront > configMuonTagging.cfgMuonTaggingRadiusAtMftFrontUp.value) { + continue; + } + + // propagate the track from the vertex to the last MFT plane + const auto& extrapToMFTlast = propagateToZMch(mchTrackAtVertex, o2::mft::constants::mft::LayerZCoordinate()[9]); + double rBack = std::sqrt(extrapToMFTlast.getX() * extrapToMFTlast.getX() + extrapToMFTlast.getY() * extrapToMFTlast.getY()); + if (rBack < configMuonTagging.cfgMuonTaggingRadiusAtMftBackLow.value || rBack > configMuonTagging.cfgMuonTaggingRadiusAtMftBackUp.value) { + continue; + } + + int64_t muonTrackIndex = muonTrack.globalIndex(); + taggedMuons.emplace_back(muonTrackIndex); + } + } + + template + bool isMftMchTimeCompatible(EVT const& collisions, + BC const& bcs, + TMUON const& mchTrack, + TMFT const& mftTrack) + { + if (!mchTrack.has_collision() || !mftTrack.has_collision()) { + return false; + } + + const auto& collMch = collisions.rawIteratorAt(mchTrack.collisionId()); + const auto& bcMch = bcs.rawIteratorAt(collMch.bcId()); + const auto& collMft = collisions.rawIteratorAt(mftTrack.collisionId()); + const auto& bcMft = bcs.rawIteratorAt(collMft.bcId()); + + int64_t deltaBc = static_cast(bcMft.globalBC()) - static_cast(bcMch.globalBC()); + double deltaBcNS = o2::constants::lhc::LHCBunchSpacingNS * deltaBc; + double deltaTrackTime = mftTrack.trackTime() - mchTrack.trackTime() + deltaBcNS; + double trackTimeResTot = mftTrack.trackTimeRes() + mchTrack.trackTimeRes(); + + return std::fabs(deltaTrackTime) <= trackTimeResTot; + } + + template + void prepareMatchingCandidates(EVT const& collisions, + BC const& bcs, + TMUON const& muonTracks, + TMFT const& mftTracks, + MyMFTCovariances const& mftCovs) + { + mMftTrackPars.clear(); + mMchTrackPars.clear(); + mMatchingCandidates.clear(); + + LOGF(info, "Filling matching candidate tables"); + + for (const auto& muonTrack : muonTracks) { + if (static_cast(muonTrack.trackType()) <= GlobalTrackTypeMax) { + continue; + } + auto mchTrackIndex = muonTrack.globalIndex(); + + // initialize the MCH track parameters, which will be updated by the realignment if enabled + mMchTrackPars.try_emplace(mchTrackIndex, TrackParExt(fwdtrackutils::getTrackParCovFwd(muonTrack, muonTrack), muonTrack.nClusters())); + } + + for (const auto& mftTrack : mftTracks) { + auto mftTrackIndex = mftTrack.globalIndex(); + + // initialize the MFT track parameters, which will be updated by the alignment corrections if enabled + if (mftTrackCovs.contains(mftTrackIndex) && !mMftTrackPars.contains(mftTrackIndex)) { + auto const& mftTrackCov = mftCovs.rawIteratorAt(mftTrackCovs[mftTrackIndex]); + mMftTrackPars.emplace(mftTrackIndex, TrackParExt(fwdtrackutils::getTrackParCovFwd(mftTrack, mftTrackCov), mftTrack.nClusters())); + } + } + + // fill matching candidates table + if (!configMatching.cfgMatchAllTracks.value) { + // collect global MFT-MCH or MFT-MCH-MID tracks and associate them to the corresponding MCH(-MID) track + for (const auto& muonTrack : muonTracks) { + // skip MCH or MCH-MID tracks + if (static_cast(muonTrack.trackType()) > GlobalTrackTypeMax) { + continue; + } + + auto const& mchTrack = muonTrack.template matchMCHTrack_as(); + int64_t mchTrackIndex = mchTrack.globalIndex(); + auto const& mftTrack = muonTrack.template matchMFTTrack_as(); + int64_t mftTrackIndex = mftTrack.globalIndex(); + + if (!mftTrackCovs.contains(mftTrackIndex)) { + continue; + } + + mMatchingCandidates[mchTrackIndex].emplace_back(MatchingCandidate{ + .muonTrackId = muonTrack.globalIndex(), + .mftTrackId = mftTrackIndex, + .matchScore = muonTrack.matchScoreMCHMFT(), + .matchChi2 = muonTrack.chi2MatchMCHMFT()}); + } + } else { + // build matching candidates from all time-compatible MFT-MCH pairs + for (const auto& muonTrack : muonTracks) { + if (static_cast(muonTrack.trackType()) <= GlobalTrackTypeMax) { + continue; + } + auto mchTrackIndex = muonTrack.globalIndex(); + for (const auto& mftTrack : mftTracks) { + if (!isMftMchTimeCompatible(collisions, bcs, muonTrack, mftTrack)) { + continue; + } + if (!mftTrackCovs.contains(mftTrack.globalIndex())) { + continue; + } + + mMatchingCandidates[mchTrackIndex].emplace_back(MatchingCandidate{ + .mftTrackId = mftTrack.globalIndex()}); + } + } + } + + // sort the vectors of matching candidates in ascending order based on the matching chi2 value + auto compareMatchingChi2 = [](const MatchingCandidate& track1, const MatchingCandidate& track2) -> bool { + return (track1.matchChi2 < track2.matchChi2); + }; + + for (auto& [mchIndex, candidatesVector] : mMatchingCandidates) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) + std::sort(candidatesVector.begin(), candidatesVector.end(), compareMatchingChi2); + } + } + + template + o2::track::TrackParCovFwd transformMft(TMFT& mftTrack, TMFTCOV const& mftTrackCov) + { + auto track = fwdToMch(fwdtrackutils::getTrackParCovFwd(mftTrack, mftTrackCov)); + + double z = track.getZ(); + // double dZ = zMCH - z; + double x = track.getNonBendingCoor(); + double y = track.getBendingCoor(); + double xSlope = track.getNonBendingSlope(); + double ySlope = track.getBendingSlope(); + + double xSlopeCorrection = (y > 0) ? configMftAlignmentCorrections.cfgMFTAlignmentCorrXSlopeTop : configMftAlignmentCorrections.cfgMFTAlignmentCorrXSlopeBottom; + double xCorrection = xSlopeCorrection * z + + ((y > 0) ? configMftAlignmentCorrections.cfgMFTAlignmentCorrXOffsetTop : configMftAlignmentCorrections.cfgMFTAlignmentCorrXOffsetBottom); + double xNew = x + xCorrection; + double xSlopeNew = xSlope + xSlopeCorrection; + + track.setNonBendingCoor(xNew); + track.setNonBendingSlope(xSlopeNew); + + double ySlopeCorrection = (y > 0) ? configMftAlignmentCorrections.cfgMFTAlignmentCorrYSlopeTop : configMftAlignmentCorrections.cfgMFTAlignmentCorrYSlopeBottom; + double yCorrection = ySlopeCorrection * z + + ((y > 0) ? configMftAlignmentCorrections.cfgMFTAlignmentCorrYOffsetTop : configMftAlignmentCorrections.cfgMFTAlignmentCorrYOffsetBottom); + track.setBendingCoor(y + yCorrection); + track.setBendingSlope(ySlope + ySlopeCorrection); + + return mchToFwd(track); + } + + template + void runMftRealignment(TMFTs const& mftTracks, TMFTCOVs const& mftCovs) + { + for (const auto& mftTrack : mftTracks) { + auto mftTrackIndex = mftTrack.globalIndex(); + if (!mftTrackCovs.contains(mftTrackIndex)) { + continue; + } + + auto const& mftTrackCov = mftCovs.rawIteratorAt(mftTrackCovs[mftTrackIndex]); + mMftTrackPars[mftTrackIndex] = transformMft(mftTrack, mftTrackCov); + } + } + + template + void runMuonRealignment(TMuons const& muons, TMuonCls const& clusters) + { + // Loop over forward tracks + for (auto const& muon : muons) { + int mchIndex = muon.globalIndex(); + // skip global forward matches + if (muon.trackType() <= GlobalTrackTypeMax) { + continue; + } + + // continue; + + auto mchTrackParIt = mMchTrackPars.find(mchIndex); + if (mchTrackParIt == mMchTrackPars.end()) { + continue; + } + + auto clustersSliced = clusters.sliceBy(perMuon, muon.globalIndex()); // Slice clusters by muon id + mch::Track convertedTrack = mch::Track(); // Temporary variable to store re-aligned clusters + + int clIndex = -1; + // Get re-aligned clusters associated to current track + for (auto const& cluster : clustersSliced) { + clIndex += 1; + + auto* clusterMCH = new mch::Cluster(); + + math_utils::Point3D local; + math_utils::Point3D master; + master.SetXYZ(cluster.x(), cluster.y(), cluster.z()); + + // Transformation from reference geometry frame to new geometry frame + transformRef[cluster.deId()].MasterToLocal(master, local); + transformNew[cluster.deId()].LocalToMaster(local, master); + + clusterMCH->x = master.x(); + clusterMCH->y = master.y(); + clusterMCH->z = master.z(); + + const uint32_t clUid = mch::Cluster::buildUniqueId(static_cast(cluster.deId() / 100) - 1, cluster.deId(), clIndex); + clusterMCH->uid = clUid; + clusterMCH->ex = cluster.isGoodX() ? 0.2 : 10.0; + clusterMCH->ey = cluster.isGoodY() ? 0.2 : 10.0; + + // Add transformed cluster into temporary variable + convertedTrack.createParamAtCluster(*clusterMCH); + // LOGF(debug, "Track %d, cluster DE%d: x:%g y:%g z:%g", muon.globalIndex(), cluster.deId(), cluster.x(), cluster.y(), cluster.z()); + // LOGF(debug, "Track %d, re-aligned cluster DE%d: x:%g y:%g z:%g", muonRealignId, cluster.deId(), clusterMCH->getX(), clusterMCH->getY(), clusterMCH->getZ()); + } + + // Refit the re-aligned track + int removable = 0; + if (convertedTrack.getNClusters() != 0) { + removable = removeTrack(convertedTrack); + } else { + LOGF(fatal, "Muon track %d has no associated clusters.", muon.globalIndex()); + } + + // Get the re-aligned track parameter: track param at the first cluster + mch::TrackParam trackParam = mch::TrackParam(convertedTrack.first()); + + // Convert MCH track to FWD track and store new parameters after realignment + mchTrackParIt->second = mchToFwd(mch::TrackParam(convertedTrack.first())); + mchTrackParIt->second.setTrackChi2(trackParam.getTrackChi2() / convertedTrack.getNDF()); + mchTrackParIt->second.setNClusters(convertedTrack.getNClusters()); + if (removable) { + mchTrackParIt->second.setRemovable(); + } + } + } + + void runChi2Matching(const std::string& funcName, + float matchingPlaneZ, + const MatchingCandidates& matchingCandidates, + MatchingCandidates& newMatchingCandidates) + { + newMatchingCandidates.clear(); + + std::string funcNameEffective = funcName; + float matchingPlaneZEffective = matchingPlaneZ; + if (funcName == "prod") { + funcNameEffective = "matchALL"; + matchingPlaneZEffective = MatchingPlaneDefaultZ; + } + + if (!mMatchingFunctionMap.contains(funcNameEffective)) { + return; + } + auto matchingFunc = mMatchingFunctionMap.at(funcNameEffective); + + for (const auto& [mchIndex, candidatesVector] : matchingCandidates) { + + // get the tracks parameters, which have been updated by the realignment if enabled + const auto mchTrackParIt = mMchTrackPars.find(mchIndex); + if (mchTrackParIt == mMchTrackPars.end()) { + continue; + } + + for (const auto& candidate : candidatesVector) { + auto mftTrackParIt = mMftTrackPars.find(candidate.mftTrackId); + if (mftTrackParIt == mMftTrackPars.end()) { + continue; + } + + auto mftTrackProp = mftTrackParIt->second.asTrackParCovFwd(); + auto mchTrackProp = mchTrackParIt->second.asTrackParCovFwd(); + + if (matchingPlaneZEffective < 0.) { + mftTrackProp = propagateToZMft(mftTrackProp, matchingPlaneZ); + mchTrackProp = propagateToZMch(mchTrackProp, matchingPlaneZ); + } + + auto matchResult = matchingFunc(mchTrackProp, mftTrackProp); + float matchChi2 = std::get<0>(matchResult); + + newMatchingCandidates[mchIndex].emplace_back(MatchingCandidate{ + .muonTrackId = candidate.muonTrackId, + .mftTrackId = candidate.mftTrackId, + .matchScore = -1, + .matchChi2 = matchChi2}); + } + } + + auto compareMatchingChi2 = [](const MatchingCandidate& track1, const MatchingCandidate& track2) -> bool { + return (track1.matchChi2 < track2.matchChi2); + }; + + for (auto& [mchIndex, globalTracksVector] : newMatchingCandidates) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) + std::sort(globalTracksVector.begin(), globalTracksVector.end(), compareMatchingChi2); + + int ranking = 1; + for (auto& candidate : globalTracksVector) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) + candidate.matchRanking = ranking; + ranking += 1; + } + } + } + + template + void runMlMatching(C const& collisions, + TMUON const& muonTracks, + TMFT const& mftTracks, + o2::analysis::MlResponseMFTMuonMatch& mlResponse, + float matchingPlaneZ, + const MatchingCandidates& matchingCandidates, + MatchingCandidates& newMatchingCandidates) + { + newMatchingCandidates.clear(); + for (const auto& [mchIndex, candidatesVector] : matchingCandidates) { + auto const& mchTrack = muonTracks.rawIteratorAt(mchIndex); + if (!mchTrack.has_collision()) { + continue; + } + + auto collision = collisions.rawIteratorAt(mchTrack.collisionId()); + + // get the tracks parameters, which have been updated by the realignment if enabled + auto mchTrackParIt = mMchTrackPars.find(mchIndex); + if (mchTrackParIt == mMchTrackPars.end()) { + continue; + } + + for (const auto& candidate : candidatesVector) { + auto const& muonTrack = (candidate.muonTrackId >= 0) ? muonTracks.rawIteratorAt(candidate.muonTrackId) : mchTrack; + auto const& mftTrack = mftTracks.rawIteratorAt(candidate.mftTrackId); + auto mftTrackParIt = mMftTrackPars.find(candidate.mftTrackId); + if (mftTrackParIt == mMftTrackPars.end()) { + continue; + } + + auto mftTrackProp = mftTrackParIt->second.asTrackParCovFwd(); + auto mchTrackProp = mchTrackParIt->second.asTrackParCovFwd(); + + if (matchingPlaneZ < 0.) { + mftTrackProp = propagateToZMft(mftTrackProp, matchingPlaneZ); + mchTrackProp = propagateToZMch(mchTrackProp, matchingPlaneZ); + } + + std::vector output; + std::vector inputML = mlResponse.getInputFeatures(muonTrack, mftTrack, mchTrack, mftTrackProp, mchTrackProp, collision); + mlResponse.isSelectedMl(inputML, 0, output); + float matchScore = output[0]; + + newMatchingCandidates[mchIndex].emplace_back(MatchingCandidate{ + .muonTrackId = candidate.muonTrackId, + .mftTrackId = candidate.mftTrackId, + .matchScore = matchScore, + .matchChi2 = -1}); + } + } + + auto compareMatchingScore = [](const MatchingCandidate& track1, const MatchingCandidate& track2) -> bool { + return (track1.matchScore > track2.matchScore); + }; + + for (auto& [mchIndex, globalTracksVector] : newMatchingCandidates) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) + std::sort(globalTracksVector.begin(), globalTracksVector.end(), compareMatchingScore); + + int ranking = 1; + for (auto& candidate : globalTracksVector) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) + candidate.matchRanking = ranking; + ranking += 1; + } + } + } + + template + void processMatchingCandidates(C const& collisions, + TMUON const& muonTracks, + TMFT const& mftTracks, + CMFT const& mftCovs, + aod::FwdTrkCls const& clusters) + { + if (configMchRealign.cfgEnableMCHRealign.value) { + runMuonRealignment(muonTracks, clusters); + } + + if (configMftAlignmentCorrections.cfgEnableMftAlignmentCorrections) { + runMftRealignment(mftTracks, mftCovs); + } + + std::vector taggedMuons; + getTaggedMuons(collisions, muonTracks, taggedMuons); + + if (configMatching.cfgCustomMatchingStrategy.value == 0) { + if (hasActiveChi2Matching) { + MatchingCandidates newMatchingCandidates; + runChi2Matching(activeChi2FunctionName, activeChi2MatchingPlaneZ, mMatchingCandidates, newMatchingCandidates); + fillMatchingCandidates(newMatchingCandidates, taggedMuons); + } + } else { + if (hasActiveMlMatching) { + MatchingCandidates newMatchingCandidates; + runMlMatching(collisions, muonTracks, mftTracks, activeMlResponse, activeMlMatchingPlaneZ, mMatchingCandidates, newMatchingCandidates); + fillMatchingCandidates(newMatchingCandidates, taggedMuons); + } + } + } + + void fillMatchingCandidates(const MatchingCandidates& matchingCandidates, + const std::vector& taggedMuons) + { + for (const auto& [mchIndex, candidates] : matchingCandidates) { + if (candidates.empty()) { + continue; + } + + bool isTagged = std::find(taggedMuons.begin(), taggedMuons.end(), mchIndex) != taggedMuons.end(); + + std::vector storedCandidates; + int nStored = 0; + for (const auto& candidate : candidates) { + if (configMatching.cfgMaxCandidatesPerMchTrack.value >= 0 && nStored >= configMatching.cfgMaxCandidatesPerMchTrack.value) { + break; + } + + int32_t candidateIndex = mMatchCandidateCounter; + globalMuonMatchCandidates( + mchIndex, + candidate.mftTrackId, + static_cast(candidate.matchChi2), + static_cast(candidate.matchScore), + static_cast(candidate.matchRanking), + isTagged); + mMatchCandidateCounter += 1; + + mMchTrackToCandidateIndices[mchIndex].push_back(candidateIndex); + storedCandidates.push_back(candidate); + nStored += 1; + } + + if (!storedCandidates.empty()) { + mMchTrackMatchingCandidates[mchIndex] = std::move(storedCandidates); + } + } + } + + int32_t countStoredCandidatesForMchTrack(int64_t mchTrackIndex) const + { + const auto candidateIterator = mMchTrackMatchingCandidates.find(mchTrackIndex); + if (candidateIterator == mMchTrackMatchingCandidates.end()) { + return 0; + } + return static_cast(candidateIterator->second.size()); + } + + template + void fillGmmCandidateFwdTracks(TMUON const& muonTracks, + TMFT const& mftTracks, + aod::AmbiguousFwdTracks const& ambFwdTracks) + { + mFwdTrackToGmmCandTrkIndex.clear(); + mGmmCandFwdTrackRowIndex = 0; + mHasLastMchAmbiguousBcSlice = false; + mAmbBcSliceByFwdTrackId.clear(); + for (const auto& ambFwdTrack : ambFwdTracks) { + const auto bcIds = ambFwdTrack.bcIds(); + mAmbBcSliceByFwdTrackId[ambFwdTrack.fwdtrackId()] = {bcIds[0], bcIds[1]}; + } + + // First pass: assign GMMCANDTRK row indices for MCH/MCH-MID base entries so that + // MCHTrackId can be remapped consistently even when global muons appear first in FwdTracks. + int32_t nextGmmCandTrkIndex = 0; + for (const auto& track : muonTracks) { + const int trackType = static_cast(track.trackType()); + if (trackType > GlobalTrackTypeMax) { + mFwdTrackToGmmCandTrkIndex[track.globalIndex()] = nextGmmCandTrkIndex; + nextGmmCandTrkIndex += 1 + countStoredCandidatesForMchTrack(track.globalIndex()); + } else if (configMatching.cfgIncludeGlobalMuonsInFwdTracks.value) { + nextGmmCandTrkIndex += 1; + } + } + + // Second pass: fill GMMCANDTRK/GMMCANDTRKCOV in FwdTracks order. + for (const auto& track : muonTracks) { + const int trackType = static_cast(track.trackType()); + + if (trackType > GlobalTrackTypeMax) { + mHasLastMchAmbiguousBcSlice = false; + const int64_t mchTrackIndex = track.globalIndex(); + const int32_t gmmMchTrackId = mFwdTrackToGmmCandTrkIndex.at(mchTrackIndex); + + const auto candidateIterator = mMchTrackMatchingCandidates.find(mchTrackIndex); + auto mchTrackParIt = mMchTrackPars.find(mchTrackIndex); + if (mchTrackParIt == mMchTrackPars.end()) { + // fill muon tracks table with original parameters + const TrackParExt trackPar{fwdtrackutils::getTrackParCovFwd(track, track)}; + fillBaseGmmCandFwdTrack(track, trackPar, gmmMchTrackId, -1.f, -1.f); + } else { + // fill muon tracks table with realignment parameters + fillBaseGmmCandFwdTrack(track, mchTrackParIt->second, gmmMchTrackId, -1.f, -1.f); + } + + if (candidateIterator != mMchTrackMatchingCandidates.end()) { + for (const auto& candidate : candidateIterator->second) { + auto mftTrackParIt = mMftTrackPars.find(candidate.mftTrackId); + if (mftTrackParIt != mMftTrackPars.end()) { + const auto& mftTrack = mftTracks.rawIteratorAt(candidate.mftTrackId); + fillCandidateFwdTrack(track, mchTrackParIt->second, gmmMchTrackId, mftTrack, mftTrackParIt->second, candidate); + } + } + } + } + + if (configMatching.cfgIncludeGlobalMuonsInFwdTracks.value && trackType <= GlobalTrackTypeMax) { + int32_t gmmMchTrackId = -1; + const auto mchIterator = mFwdTrackToGmmCandTrkIndex.find(track.matchMCHTrackId()); + if (mchIterator != mFwdTrackToGmmCandTrkIndex.end()) { + gmmMchTrackId = mchIterator->second; + } + TrackParExt parExt(fwdtrackutils::getTrackParCovFwd(track, track)); + fillBaseGmmCandFwdTrack(track, + parExt, + gmmMchTrackId, + track.chi2MatchMCHMFT(), + track.matchScoreMCHMFT()); + } + } + } + + template + void fillFwdTrkMatchCands(TMUON const& muonTracks) + { + std::vector empty{}; + for (const auto& muonTrack : muonTracks) { + if (static_cast(muonTrack.trackType()) <= GlobalTrackTypeMax) { + fwdTrkMatchCands(empty); + continue; + } + + const int64_t mchTrackIndex = muonTrack.globalIndex(); + const auto matchIterator = mMchTrackToCandidateIndices.find(mchTrackIndex); + if (matchIterator == mMchTrackToCandidateIndices.end() || matchIterator->second.empty()) { + fwdTrkMatchCands(empty); + } else { + fwdTrkMatchCands(matchIterator->second); + } + } + } + + void processData(MyEvents const& collisions, + aod::BCsWithTimestamps const& bcs, + MyMuons const& muonTracks, + MyMFTs const& mftTracks, + MyMFTCovariances const& mftCovs, + aod::FwdTrkCls const& clusters, + aod::AmbiguousFwdTracks const& ambFwdTracks) + { + auto bc = bcs.begin(); + initCcdb(bc); + + LOGF(info, "Filling MFT cov"); + mftTrackCovs.clear(); + for (const auto& mftTrackCov : mftCovs) { + mftTrackCovs[mftTrackCov.matchMFTTrackId()] = mftTrackCov.globalIndex(); + } + + mMatchCandidateCounter = 0; + mMchTrackToCandidateIndices.clear(); + mMchTrackMatchingCandidates.clear(); + mFwdTrackToGmmCandTrkIndex.clear(); + + LOGF(info, "Preparing candidates"); + prepareMatchingCandidates(collisions, bcs, muonTracks, mftTracks, mftCovs); + + LOGF(info, "Processing candidates"); + processMatchingCandidates(collisions, muonTracks, mftTracks, mftCovs, clusters); + + LOGF(info, "Filling tables"); + // fill table with track/candidates index mapping + fillFwdTrkMatchCands(muonTracks); + // fill track tables + fillGmmCandidateFwdTracks(muonTracks, mftTracks, ambFwdTracks); + } + + PROCESS_SWITCH(GlobalMuonMatching, processData, "processData", true); +}; + +// Extends the fwdtracksrealign table with expression columns +struct GlobalMuonMatchingSpawner { + Spawns realignFwdTrksCov; + Spawns realignFwdTrks; + void init(InitContext const&) {} +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; +}; diff --git a/PWGDQ/Tasks/mchAlignRecord.cxx b/PWGDQ/Tasks/mchAlignRecord.cxx index 5f610a20c98..8cee87e4245 100644 --- a/PWGDQ/Tasks/mchAlignRecord.cxx +++ b/PWGDQ/Tasks/mchAlignRecord.cxx @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -45,7 +46,6 @@ #include #include -#include #include #include diff --git a/PWGDQ/Tasks/mftMchMatcher.cxx b/PWGDQ/Tasks/mftMchMatcher.cxx index d69afb2356c..165488fcf7c 100644 --- a/PWGDQ/Tasks/mftMchMatcher.cxx +++ b/PWGDQ/Tasks/mftMchMatcher.cxx @@ -240,6 +240,15 @@ struct mftMchMatcher { Configurable fzMatching{"cfgzMatching", -77.5f, "Plane for MFT-MCH matching"}; Configurable fSamplingFraction{"cfgSamplingFraction", 1.f, "Fraction of randomly selected events to be processed"}; + Configurable fSamplingFractionTrueLeadingMatches{"cfgSamplingFractionTrueLeadingMatches", 1.f, "Fraction of randomly selected leading true matches to be processed"}; + Configurable fSamplingFractionWrongLeadingMatches{"cfgSamplingFractionWrongLeadingMatches", 1.f, "Fraction of randomly selected leading wrong matches to be processed"}; + Configurable fSamplingFractionDecayLeadingMatches{"cfgSamplingFractionDecayLeadingMatches", 1.f, "Fraction of randomly selected leading decay matches to be processed"}; + Configurable fSamplingFractionFakeLeadingMatches{"cfgSamplingFractionFakeLeadingMatches", 1.f, "Fraction of randomly selected leading fake matches to be processed"}; + Configurable fSamplingFractionTrueNonLeadingMatches{"cfgSamplingFractionTrueNonLeadingMatches", 1.f, "Fraction of randomly selected non-leading true matches to be processed"}; + Configurable fSamplingFractionWrongNonLeadingMatches{"cfgSamplingFractionWrongNonLeadingMatches", 1.f, "Fraction of randomly selected non-leading wrong matches to be processed"}; + Configurable fSamplingFractionDecayNonLeadingMatches{"cfgSamplingFractionDecayNonLeadingMatches", 1.f, "Fraction of randomly selected non-leading decay matches to be processed"}; + Configurable fSamplingFractionFakeNonLeadingMatches{"cfgSamplingFractionFakeNonLeadingMatches", 1.f, "Fraction of randomly selected non-leading fake matches to be processed"}; + Configurable fSamplingBcOddness{"cfgSamplingBcOddness", -1, "Select only events with even (0) or odd (1) global BCs"}; //// Variables for ccdb Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; @@ -430,6 +439,17 @@ struct mftMchMatcher { hMatchType->GetXaxis()->SetBinLabel(7, "decay (non leading)"); hMatchType->GetXaxis()->SetBinLabel(8, "fake (non leading)"); hMatchType->GetXaxis()->SetBinLabel(9, "undefined"); + + auto hMatchTypeAccepted = std::get>(registry.add("matchTypeAccepted", "Match type (accepted)", {HistType::kTH1F, {matchTypeAxis}})); + hMatchTypeAccepted->GetXaxis()->SetBinLabel(1, "true (leading)"); + hMatchTypeAccepted->GetXaxis()->SetBinLabel(2, "wrong (leading)"); + hMatchTypeAccepted->GetXaxis()->SetBinLabel(3, "decay (leading)"); + hMatchTypeAccepted->GetXaxis()->SetBinLabel(4, "fake (leading)"); + hMatchTypeAccepted->GetXaxis()->SetBinLabel(5, "true (non leading)"); + hMatchTypeAccepted->GetXaxis()->SetBinLabel(6, "wrong (non leading)"); + hMatchTypeAccepted->GetXaxis()->SetBinLabel(7, "decay (non leading)"); + hMatchTypeAccepted->GetXaxis()->SetBinLabel(8, "fake (non leading)"); + hMatchTypeAccepted->GetXaxis()->SetBinLabel(9, "undefined"); } template @@ -603,8 +623,6 @@ struct mftMchMatcher { mftCovIndexes[mftTrackCov.matchMFTTrackId()] = mftTrackCov.globalIndex(); } - fwdMatchMLCandidates.reserve(muonTracks.size()); - for (auto muon : muonTracks) { // only consider global MFT-MCH-MID matches if (static_cast(muon.trackType()) != 0) { @@ -670,6 +688,50 @@ struct mftMchMatcher { registry.get(HIST("matchType"))->Fill(static_cast(matchType)); + // skipp odd/even BCs if requested + if (fSamplingBcOddness.value >= 0 && (static_cast((bc_coll.globalBC() % 2)) != fSamplingBcOddness.value)) { + continue; + } + + float matchTypeSamplingFraction = 1.0; + switch (matchType) { + case kMatchTypeTrueLeading: + matchTypeSamplingFraction = fSamplingFractionTrueLeadingMatches; + break; + case kMatchTypeTrueNonLeading: + matchTypeSamplingFraction = fSamplingFractionTrueNonLeadingMatches; + break; + case kMatchTypeWrongLeading: + matchTypeSamplingFraction = fSamplingFractionWrongLeadingMatches; + break; + case kMatchTypeWrongNonLeading: + matchTypeSamplingFraction = fSamplingFractionWrongNonLeadingMatches; + break; + case kMatchTypeDecayLeading: + matchTypeSamplingFraction = fSamplingFractionDecayLeadingMatches; + break; + case kMatchTypeDecayNonLeading: + matchTypeSamplingFraction = fSamplingFractionDecayNonLeadingMatches; + break; + case kMatchTypeFakeLeading: + matchTypeSamplingFraction = fSamplingFractionFakeLeadingMatches; + break; + case kMatchTypeFakeNonLeading: + matchTypeSamplingFraction = fSamplingFractionFakeNonLeadingMatches; + break; + default: + break; + } + + if (matchTypeSamplingFraction < 1.0) { + double rnd = mDistribution(mGenerator); + if (rnd > matchTypeSamplingFraction) { + continue; + } + } + + registry.get(HIST("matchTypeAccepted"))->Fill(static_cast(matchType)); + fwdMatchMLCandidates( muonprop.getX(), muonprop.getY(), diff --git a/PWGDQ/Tasks/muonGlobalAlignment.cxx b/PWGDQ/Tasks/muonGlobalAlignment.cxx index 1186ef99d08..bdd60ef5717 100644 --- a/PWGDQ/Tasks/muonGlobalAlignment.cxx +++ b/PWGDQ/Tasks/muonGlobalAlignment.cxx @@ -15,7 +15,6 @@ // #include "PWGDQ/Core/VarManager.h" -// #include "PWGDQ/DataModel/ReducedInfoTables.h" #include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/RCTSelectionFlags.h" @@ -37,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -63,7 +63,6 @@ #include #include -#include #include #include diff --git a/PWGDQ/Tasks/qaMatching.cxx b/PWGDQ/Tasks/qaMatching.cxx index e7de1e7f2b0..acd5924db7d 100644 --- a/PWGDQ/Tasks/qaMatching.cxx +++ b/PWGDQ/Tasks/qaMatching.cxx @@ -20,6 +20,7 @@ #include "Common/DataModel/Centrality.h" #include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/FwdTrackReAlignTables.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Tools/ML/MlResponse.h" @@ -73,6 +74,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +108,9 @@ DECLARE_SOA_COLUMN(IsTagged, isTagged, bool); DECLARE_SOA_COLUMN(XAtVtx, xAtVtx, float); DECLARE_SOA_COLUMN(YAtVtx, yAtVtx, float); DECLARE_SOA_COLUMN(ZAtVtx, zAtVtx, float); +DECLARE_SOA_COLUMN(FXAtPlaneZ2, fXAtPlaneZ2, float); +DECLARE_SOA_COLUMN(FYAtPlaneZ2, fYAtPlaneZ2, float); +DECLARE_SOA_COLUMN(FZAtPlaneZ2, fZAtPlaneZ2, float); DECLARE_SOA_COLUMN(PxAtVtx, pxAtVtx, float); DECLARE_SOA_COLUMN(PyAtVtx, pyAtVtx, float); DECLARE_SOA_COLUMN(PzAtVtx, pzAtVtx, float); @@ -144,6 +149,9 @@ DECLARE_SOA_TABLE(QaMatchingMCHTrack, "AOD", "QAMCHTRK", qamatching::XAtVtx, qamatching::YAtVtx, qamatching::ZAtVtx, + qamatching::FXAtPlaneZ2, + qamatching::FYAtPlaneZ2, + qamatching::FZAtPlaneZ2, qamatching::PxAtVtx, qamatching::PyAtVtx, qamatching::PzAtVtx); @@ -178,6 +186,7 @@ DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(Candidate, candidate, int32_t, o2::aod::QaM using MyEvents = soa::Join; using MyMuons = soa::Join; +using MyMuonsReAlign = soa::Join; using MyMuonsMC = soa::Join; using MyMFTs = aod::MFTTracks; using MyMFTCovariances = aod::MFTTracksCov; @@ -252,6 +261,7 @@ struct QaMatching { int64_t globalTrackId{-1}; int64_t muonTrackId{-1}; int64_t mftTrackId{-1}; + int trackType{-1}; o2::track::TrackParCovFwd mftTrackProp; o2::track::TrackParCovFwd mchTrackProp; double matchScore{-1}; @@ -260,12 +270,15 @@ struct QaMatching { double matchScoreProd{-1}; double matchChi2Prod{-1}; int matchRankingProd{-1}; - int mftMchMatchAttempts{0}; MuonMatchType matchType{kMatchTypeUndefined}; }; Configurable cfgIsMc{"cfgIsMc", true, "Wheter the processed data is from MC simulations"}; + //// Variables for selecting the collisions + Configurable cfgVtxZLow{"cfgVtxZLow", -10.0f, "Lower limit for the vertex z position"}; + Configurable cfgVtxZUp{"cfgVtxZUp", 10.0f, "Upper limit for the vertex z position"}; + //// Variables for selecting muon tracks Configurable cfgPMchLow{"cfgPMchLow", 0.0f, ""}; Configurable cfgPtMchLow{"cfgPtMchLow", 0.7f, ""}; @@ -459,6 +472,21 @@ struct QaMatching { // the map key is the MCH(-MID) track global index using MatchingCandidates = std::map>; + struct TrackTimeInfo { + // global BC number + int64_t bc{-1}; + // track time relative to the global BC + double time{-1}; + // time resolution + double timeRes{-1}; + }; + + struct MchTrackInfo : public TrackTimeInfo { + int64_t index{-1}; + // vector of MFT tracks that are time-compatible with this MCH track + std::vector compatMftTracks; + }; + struct CollisionInfo { int64_t index{0}; // internal index of this collision in the derived table @@ -470,8 +498,10 @@ struct QaMatching { int mftTracksMultiplicity{0}; // vector of MFT track indexes std::vector mftTracks; - // vector of MCH(-MID) track indexes - std::vector mchTracks; + // time information for MFT tracks + std::unordered_map mftTimeInfos; + // extra information for MCH(-MID) tracks + std::unordered_map mchTracks; // mapping between original and reduced MCH track indexes std::map reducedMchTrackIds; // matching candidates @@ -966,19 +996,38 @@ struct QaMatching { { AxisSpec chi2Axis = {1000, 0, 1000, "chi^{2}"}; AxisSpec chi2AxisSmall = {200, 0, 100, "chi^{2}"}; - AxisSpec pAxis = {1000, 0, 100, "p (GeV/c)"}; - AxisSpec pTAxis = {100, 0, 10, "p_{T} (GeV/c)"}; + AxisSpec pAxis = {50, 0, 100, "p (GeV/c)"}; + AxisSpec pTAxis = {50, 0, 10, "p_{T} (GeV/c)"}; AxisSpec etaAxis = {100, -4, -2, "#eta"}; - AxisSpec phiAxis = {90, -180, 180, "#phi (degrees)"}; + AxisSpec vzAxis = {20, -10, 10, "vertex_{z} (cm)"}; + AxisSpec rAxis = {60, 0, 15, "R_{track} (cm)"}; + AxisSpec mftNClusAxis = {6, 5, 11, "# of MFT clusters"}; + std::string histPath = cfgIsMc.value ? "matching/MC/" : "matching/"; AxisSpec trackPositionXAtMftAxis = {100, -15, 15, "MFT x (cm)"}; AxisSpec trackPositionYAtMftAxis = {100, -15, 15, "MFT y (cm)"}; - registry.add((histPath + "pairedMCHTracksAtMFT").c_str(), "Paired MCH tracks position at MFT end", {HistType::kTH2F, {trackPositionXAtMftAxis, trackPositionYAtMftAxis}}); - registry.add((histPath + "pairedMFTTracksAtMFT").c_str(), "Paired MFT tracks position at MFT end", {HistType::kTH2F, {trackPositionXAtMftAxis, trackPositionYAtMftAxis}}); - registry.add((histPath + "selectedMCHTracksAtMFT").c_str(), "Selected MCH tracks position at MFT end", {HistType::kTH2F, {trackPositionXAtMftAxis, trackPositionYAtMftAxis}}); - registry.add((histPath + "selectedMCHTracksAtMFTTrue").c_str(), "Selected MCH tracks position at MFT end - true", {HistType::kTH2F, {trackPositionXAtMftAxis, trackPositionYAtMftAxis}}); - registry.add((histPath + "selectedMCHTracksAtMFTFake").c_str(), "Selected MCH tracks position at MFT end - fake", {HistType::kTH2F, {trackPositionXAtMftAxis, trackPositionYAtMftAxis}}); + registry.add((histPath + "taggedMCHTracksAtMFT").c_str(), "Tagged MCH tracks position at MFT end", {HistType::kTH2F, {trackPositionXAtMftAxis, trackPositionYAtMftAxis}}); + if (cfgIsMc.value) { + registry.add((histPath + "pairedMCHTracksAtMFT").c_str(), "Paired MCH tracks position at MFT end", {HistType::kTH2F, {trackPositionXAtMftAxis, trackPositionYAtMftAxis}}); + registry.add((histPath + "pairedMFTTracksAtMFT").c_str(), "Paired MFT tracks position at MFT end", {HistType::kTH2F, {trackPositionXAtMftAxis, trackPositionYAtMftAxis}}); + registry.add((histPath + "taggedMCHTracksAtMFTTrue").c_str(), "Tagged MCH tracks position at MFT end - true", {HistType::kTH2F, {trackPositionXAtMftAxis, trackPositionYAtMftAxis}}); + registry.add((histPath + "taggedMCHTracksAtMFTFake").c_str(), "Tagged MCH tracks position at MFT end - fake", {HistType::kTH2F, {trackPositionXAtMftAxis, trackPositionYAtMftAxis}}); + } + + registry.add((histPath + "muonTracksVsMchKine").c_str(), "Muon tracks vs. MCH kine", {HistType::kTHnSparseF, {etaAxis, pTAxis, vzAxis}}); + registry.add((histPath + "muonTracksVsMchKineAtVertex").c_str(), "Muon tracks vs. MCH kine at vertex", {HistType::kTHnSparseF, {etaAxis, pTAxis, vzAxis}}); + + registry.add((histPath + "muonTracksRadiusAtMftFront").c_str(), "Muon tracks radius at MFT front", {HistType::kTHnSparseF, {rAxis, vzAxis, pAxis}}); + registry.add((histPath + "muonTracksRadiusAtMftBack").c_str(), "Muon tracks radius at MFT back", {HistType::kTHnSparseF, {rAxis, vzAxis, pAxis}}); + + if (cfgIsMc.value) { + registry.add((histPath + "muonTracksPairedVsMchKine").c_str(), "Paired muon tracks vs. MCH kine", {HistType::kTHnSparseF, {etaAxis, pTAxis, vzAxis, mftNClusAxis}}); + registry.add((histPath + "muonTracksPairedVsMchKineAtVertex").c_str(), "Paired muon tracks vs. MCH kine at vertex", {HistType::kTHnSparseF, {etaAxis, pTAxis, vzAxis, mftNClusAxis}}); + + registry.add((histPath + "muonTracksRadiusPairedAtMftFront").c_str(), "Paired muon tracks radius at MFT front", {HistType::kTHnSparseF, {rAxis, vzAxis, pAxis}}); + registry.add((histPath + "muonTracksRadiusPairedAtMftBack").c_str(), "Paired muon tracks radius at MFT back", {HistType::kTHnSparseF, {rAxis, vzAxis, pAxis}}); + } fChi2MatchingPlotter = std::make_unique(histPath + "Prod/", ®istryMatching, configQas.cfgCreatePdgMomHistograms, cfgMftTrackMultiplicityMax, cfgNCandidatesMax, cfgIsMc.value); int registryIndex = 0; @@ -996,7 +1045,7 @@ struct QaMatching { void createDimuonHistos() { - AxisSpec invMassAxis = {400, 1, 5, "M_{#mu^{+}#mu^{-}} (GeV/c^{2})"}; + AxisSpec invMassAxis = {500, 0, 5, "M_{#mu^{+}#mu^{-}} (GeV/c^{2})"}; AxisSpec invMassCorrelationAxis = {400, 0, 8, "M_{#mu^{+}#mu^{-}} (GeV/c^{2})"}; AxisSpec invMassAxisFull = {5000, 0, 100, "M_{#mu^{+}#mu^{-}} (GeV/c^{2})"}; int matchTypeCombMax = (static_cast(kMatchTypeTrueNonLeading) - 1) * 10 + static_cast(kMatchTypeTrueNonLeading) - 1; @@ -1022,6 +1071,16 @@ struct QaMatching { registryDimuon.add("dimuon/invariantMass_ScaledMftKine_GlobalMuonCuts_GoodMatches", "#mu^{+}#mu^{-} invariant mass (global muon cuts, rescaled MFT, good matches)", {HistType::kTH1F, {invMassAxis}}); // MFT-MCH-MID tracks with MFT acceptance cuts vs. muon tracks match type, good matches registryDimuon.add("dimuon/MC/invariantMass_ScaledMftKine_GlobalMuonCuts_GoodMatches_vs_match_type", "#mu^{+}#mu^{-} invariant mass vs. match tye (global muon cuts, rescaled MFT, good matches)", {HistType::kTH2F, {invMassAxis, matchTypeAxis}}); + + // global kinematics as stored in candidates + // MFT-MCH-MID tracks with MFT acceptance cuts + registryDimuon.add("dimuon/invariantMass_GlobalKine_GlobalMuonCuts", "#mu^{+}#mu^{-} invariant mass (global muon cuts, global kine)", {HistType::kTH1F, {invMassAxis}}); + // MCH-MID tracks with MFT acceptance cuts vs. muon tracks match type + registryDimuon.add("dimuon/MC/invariantMass_GlobalKine_GlobalMuonCuts_vs_match_type", "#mu^{+}#mu^{-} invariant mass vs. match tye (global muon cuts, global kine)", {HistType::kTH2F, {invMassAxis, matchTypeAxis}}); + // MFT-MCH-MID tracks with MFT acceptance cuts, good matches + registryDimuon.add("dimuon/invariantMass_GlobalKine_GlobalMuonCuts_GoodMatches", "#mu^{+}#mu^{-} invariant mass (global muon cuts, global kine, good matches)", {HistType::kTH1F, {invMassAxis}}); + // MFT-MCH-MID tracks with MFT acceptance cuts vs. muon tracks match type, good matches + registryDimuon.add("dimuon/MC/invariantMass_GlobalKine_GlobalMuonCuts_GoodMatches_vs_match_type", "#mu^{+}#mu^{-} invariant mass vs. match tye (global muon cuts, global kine, good matches)", {HistType::kTH2F, {invMassAxis, matchTypeAxis}}); } void initMatchingFunctions() @@ -1332,35 +1391,31 @@ struct QaMatching { return isGoodMft(mftTrack, cfgTrackChi2MftUp, cfgTrackNClustMftLow); } - template - bool isGoodGlobalMatching(const TMUON& muonTrack, - double matchingScore, + bool isGoodGlobalMatching(const MatchingCandidate& candidate, double matchingScoreCut) { - if (static_cast(muonTrack.trackType()) > GlobalTrackTypeMax) + if (static_cast(candidate.trackType) > GlobalTrackTypeMax) return false; // MFT-MCH matching score cut - if (matchingScore < matchingScoreCut) + if (candidate.matchScore < matchingScoreCut) return false; return true; } - template - bool isGoodGlobalMatching(const TMUON& muonTrack, double matchingScore) + bool isGoodGlobalMatching(const MatchingCandidate& candidate) { - return isGoodGlobalMatching(muonTrack, matchingScore, cfgMatchingChi2ScoreMftMchLow); + return isGoodGlobalMatching(candidate, cfgMatchingChi2ScoreMftMchLow); } - template - bool isTrueGlobalMatching(const TMUON& muonTrack, const std::vector>& matchablePairs) + bool isTrueGlobalMatching(const MatchingCandidate& candidate, const std::vector>& matchablePairs) { - if (static_cast(muonTrack.trackType()) > GlobalTrackTypeMax) + if (candidate.trackType > GlobalTrackTypeMax) return false; - int64_t mchTrackId = static_cast(muonTrack.matchMCHTrackId()); - int64_t mftTrackId = static_cast(muonTrack.matchMFTTrackId()); + int64_t mchTrackId = candidate.muonTrackId; + int64_t mftTrackId = candidate.mftTrackId; std::pair trackIndexes = std::make_pair(mchTrackId, mftTrackId); @@ -1739,9 +1794,7 @@ struct QaMatching { } } - template - int getTrueMatchIndex(TMUON const& muonTracks, - const std::vector& matchCandidatesVector, + int getTrueMatchIndex(const std::vector& matchCandidatesVector, const std::vector>& matchablePairs) { // find the index of the matching candidate that corresponds to the true match @@ -1749,9 +1802,7 @@ struct QaMatching { // index=0 means no candidate was found that corresponds to the true match int trueMatchIndex = 0; for (size_t i = 0; i < matchCandidatesVector.size(); i++) { - auto const& muonTrack = muonTracks.rawIteratorAt(matchCandidatesVector[i].globalTrackId); - - if (isTrueGlobalMatching(muonTrack, matchablePairs)) { + if (isTrueGlobalMatching(matchCandidatesVector[i], matchablePairs)) { trueMatchIndex = i + 1; break; } @@ -1795,20 +1846,20 @@ struct QaMatching { return isMuon(mchTrack, mftTrack); } - template - MuonMatchType getMatchType(const TMUON& muonTrack, - TMUONS const& /*muonTracks*/, + template + MuonMatchType getMatchType(const MatchingCandidate& candidate, + TMUONS const& muonTracks, TMFTS const& mftTracks, const std::vector>& matchablePairs, int ranking) { - if (static_cast(muonTrack.trackType()) > GlobalTrackTypeMax) + if (candidate.trackType > GlobalTrackTypeMax) return kMatchTypeUndefined; - auto const& mchTrack = muonTrack.template matchMCHTrack_as(); + auto const& mchTrack = muonTracks.rawIteratorAt(candidate.muonTrackId); - bool isPairable = isMatchableMch(mchTrack.globalIndex(), matchablePairs); - bool isTrueMatch = isTrueGlobalMatching(muonTrack, matchablePairs); + bool isPairable = isMatchableMch(candidate.muonTrackId, matchablePairs); + bool isTrueMatch = isTrueGlobalMatching(candidate, matchablePairs); int decayRanking = getDecayRanking(mchTrack, mftTracks); MuonMatchType result{kMatchTypeUndefined}; @@ -1886,10 +1937,11 @@ struct QaMatching { std::vector& globalMuonPairs) { // outer loop over muon tracks - for (const auto& mchIndex1 : collisionInfo.mchTracks) { - + for (const auto& mchTrack1 : collisionInfo.mchTracks) { + auto mchIndex1 = mchTrack1.first; // inner loop over muon tracks - for (const auto& mchIndex2 : collisionInfo.mchTracks) { + for (const auto& mchTrack2 : collisionInfo.mchTracks) { + auto mchIndex2 = mchTrack2.first; // avoid double-counting of muon pairs if (mchIndex2 <= mchIndex1) continue; @@ -1952,41 +2004,44 @@ struct QaMatching { return dimuon.M(); } - template - int getMftMchMatchAttempts(EVT const& collisions, - BC const& bcs, - TMUON const& mchTrack, - TMFTS const& mftTracks) + int getMftMchMatchAttempts(MchTrackInfo& mchTrackInfo, + const std::unordered_map& mftTracksInfos) { - if (!mchTrack.has_collision()) { - return 0; - } - const auto& collMch = collisions.rawIteratorAt(mchTrack.collisionId()); - const auto& bcMch = bcs.rawIteratorAt(collMch.bcId()); - + const auto& bcMch = mchTrackInfo.bc; int attempts{0}; - for (const auto& mftTrack : mftTracks) { - if (!mftTrack.has_collision()) { - continue; - } + for (const auto& [mftTrackIndex, mftTrackInfo] : mftTracksInfos) { + const auto& bcMft = mftTrackInfo.bc; - const auto& collMft = collisions.rawIteratorAt(mftTrack.collisionId()); - const auto& bcMft = bcs.rawIteratorAt(collMft.bcId()); - - int64_t deltaBc = static_cast(bcMft.globalBC()) - static_cast(bcMch.globalBC()); + int64_t deltaBc = bcMft - bcMch; double deltaBcNS = o2::constants::lhc::LHCBunchSpacingNS * deltaBc; - double deltaTrackTime = mftTrack.trackTime() - mchTrack.trackTime() + deltaBcNS; - double trackTimeResTot = mftTrack.trackTimeRes() + mchTrack.trackTimeRes(); + double deltaTrackTime = mftTrackInfo.time - mchTrackInfo.time + deltaBcNS; + double trackTimeResTot = mftTrackInfo.timeRes + mchTrackInfo.timeRes; if (std::fabs(deltaTrackTime) > trackTimeResTot) { continue; } attempts += 1; + mchTrackInfo.compatMftTracks.push_back(mftTrackIndex); } return attempts; } + template + void getMatchChi2AndScore(TMUON const& muonTrack, float& matchChi2, float& matchScore) + { + matchChi2 = muonTrack.chi2MatchMCHMFT() / MatchingDegreesOfFreedom; + matchScore = muonTrack.matchScoreMCHMFT(); + if (matchScore >= 0 && matchChi2 < 0) { + // match score from ML-based matching, we compute a chi2-like value from the score + float matchScoreInv = (matchScore > 0) ? 1.0 / matchScore : std::numeric_limits::max(); + matchChi2 = matchScoreInv - 1.f; + } else { + // we assume a standard chi2-based matching, and compute the score value from the chi2 + matchScore = chi2ToScore(muonTrack.chi2MatchMCHMFT(), MatchingDegreesOfFreedom, MatchingScoreChi2Max); + } + } + template void fillCollisions(EVT const& collisions, BC const& bcs, @@ -2011,6 +2066,35 @@ struct QaMatching { int64_t collisionIndex = collision.globalIndex(); auto bc = bcs.rawIteratorAt(collision.bcId()); + // remove vertices outside the allowed z range + if ((collision.posZ() < cfgVtxZLow.value) || (collision.posZ() > cfgVtxZUp.value)) { + continue; + } + + // fill collision information for MFT standalone tracks + for (const auto& mftTrack : mftTracks) { + if (!mftTrack.has_collision()) + continue; + + if (collisionIndex != mftTrack.collisionId()) { + continue; + } + + int64_t mftTrackIndex = mftTrack.globalIndex(); + + auto& collisionInfo = collisionInfos[collisionIndex]; + collisionInfo.index = collisionIndex; + collisionInfo.bc = bc.globalBC(); + collisionInfo.zVertex = collision.posZ(); + + collisionInfo.mftTracks.push_back(mftTrackIndex); + + auto& timeInfo = collisionInfo.mftTimeInfos[mftTrackIndex]; + timeInfo.bc = bc.globalBC(); + timeInfo.time = mftTrack.trackTime(); + timeInfo.timeRes = mftTrack.trackTimeRes(); + } + // fill collision information for global muon tracks (MFT-MCH-MID matches) for (const auto& muonTrack : muonTracks) { if (!muonTrack.has_collision()) @@ -2034,14 +2118,22 @@ struct QaMatching { if (static_cast(muonTrack.trackType()) > GlobalTrackTypeMax) { // standalone MCH or MCH-MID tracks int64_t mchTrackIndex = muonTrack.globalIndex(); - collisionInfo.mchTracks.push_back(mchTrackIndex); + auto& mchTrackInfo = collisionInfo.mchTracks[mchTrackIndex]; + mchTrackInfo.index = mchTrackIndex; + mchTrackInfo.bc = bc.globalBC(); + mchTrackInfo.time = muonTrack.trackTime(); + mchTrackInfo.timeRes = muonTrack.trackTimeRes(); + getMftMchMatchAttempts(mchTrackInfo, collisionInfo.mftTimeInfos); + collisionInfo.reducedMchTrackIds[mchTrackIndex] = reducedMchTrackId; reducedMchTrackId += 1; } else { // global muon tracks (MFT-MCH or MFT-MCH-MID) int64_t muonTrackIndex = muonTrack.globalIndex(); - double matchChi2 = muonTrack.chi2MatchMCHMFT() / MatchingDegreesOfFreedom; - double matchScore = chi2ToScore(muonTrack.chi2MatchMCHMFT(), MatchingDegreesOfFreedom, MatchingScoreChi2Max); + float matchChi2{-1}; + float matchScore{-1}; + getMatchChi2AndScore(muonTrack, matchChi2, matchScore); + auto const& mchTrack = muonTrack.template matchMCHTrack_as(); int64_t mchTrackIndex = mchTrack.globalIndex(); auto const& mftTrack = muonTrack.template matchMFTTrack_as(); @@ -2069,6 +2161,7 @@ struct QaMatching { muonTrackIndex, mchTrackIndex, mftTrackIndex, + static_cast(muonTrack.trackType()), mftTrackProp, mchTrackProp, matchScore, @@ -2077,7 +2170,6 @@ struct QaMatching { matchScore, matchChi2, -1, - 0, kMatchTypeUndefined}); } else { collisionInfo.matchingCandidates[mchTrackIndex].emplace_back(MatchingCandidate{ @@ -2085,6 +2177,7 @@ struct QaMatching { muonTrackIndex, mchTrackIndex, mftTrackIndex, + static_cast(muonTrack.trackType()), mftTrackProp, mchTrackProp, matchScore, @@ -2093,30 +2186,10 @@ struct QaMatching { matchScore, matchChi2, -1, - 0, kMatchTypeUndefined}); } } } - - // fill collision information for MFT standalone tracks - for (const auto& mftTrack : mftTracks) { - if (!mftTrack.has_collision()) - continue; - - if (collisionIndex != mftTrack.collisionId()) { - continue; - } - - int64_t mftTrackIndex = mftTrack.globalIndex(); - - auto& collisionInfo = collisionInfos[collisionIndex]; - collisionInfo.index = collisionIndex; - collisionInfo.bc = bc.globalBC(); - collisionInfo.zVertex = collision.posZ(); - - collisionInfo.mftTracks.push_back(mftTrackIndex); - } } // sort the vectors of matching candidates in ascending order based on the matching chi2 value @@ -2132,20 +2205,15 @@ struct QaMatching { for (auto& [mchIndex, globalTracksVector] : collisionInfo.matchingCandidates) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) std::sort(globalTracksVector.begin(), globalTracksVector.end(), compareMatchingChi2); - const auto& mchTrack = muonTracks.rawIteratorAt(mchIndex); - auto mftMchMatchAttempts = getMftMchMatchAttempts(collisions, bcs, mchTrack, mftTracks); int ranking = 1; for (auto& candidate : globalTracksVector) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) - const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); - candidate.matchRanking = ranking; candidate.matchRankingProd = ranking; if constexpr (isMC) { - candidate.matchType = getMatchType(muonTrack, muonTracks, mftTracks, collisionInfo.matchablePairs, ranking); + candidate.matchType = getMatchType(candidate, muonTracks, mftTracks, collisionInfo.matchablePairs, ranking); } else { candidate.matchType = kMatchTypeUndefined; } - candidate.mftMchMatchAttempts = mftMchMatchAttempts; ranking += 1; } } @@ -2217,13 +2285,11 @@ struct QaMatching { // loop over candidates for (const auto& candidate : globalTracksVector) { - auto const& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); - float matchScore = candidate.matchScore; float matchChi2 = candidate.matchChi2; - float matchChi2Prod = muonTrack.chi2MatchMCHMFT() / 5.f; - float matchScoreProd = chi2ToScore(muonTrack.chi2MatchMCHMFT(), 5, 50.f); + float matchChi2Prod = candidate.matchChi2Prod; + float matchScoreProd = candidate.matchScoreProd; std::get>(plotter->fMatchScoreVsProd)->Fill(matchScoreProd, matchScore); std::get>(plotter->fMatchChi2VsProd)->Fill(matchChi2Prod, matchChi2); @@ -2275,8 +2341,9 @@ struct QaMatching { // find the index of the matching candidate that corresponds to the true match // index=1 corresponds to the leading candidate // index=0 means no candidate was found that corresponds to the true match - int trueMatchIndex = getTrueMatchIndex(muonTracks, globalTracksVector, matchablePairs); - int trueMatchIndexProd = getTrueMatchIndex(muonTracks, matchingCandidatesProd.at(mchIndex), matchablePairs); + int trueMatchIndex = getTrueMatchIndex(globalTracksVector, matchablePairs); + const auto prodCandidatesIt = matchingCandidatesProd.find(mchIndex); + int trueMatchIndexProd = (prodCandidatesIt != matchingCandidatesProd.end()) ? getTrueMatchIndex(prodCandidatesIt->second, matchablePairs) : 0; float mcParticleDz = -1000; if (mchTrack.has_mcParticle()) { @@ -2284,7 +2351,10 @@ struct QaMatching { mcParticleDz = collision.posZ() - mchMcParticle.vz(); } - int matchAttempts = globalTracksVector[0].mftMchMatchAttempts; + int matchAttempts = 0; + if (const auto& mchTrackInfoIt = collisionInfo.mchTracks.find(mchIndex); mchTrackInfoIt != collisionInfo.mchTracks.end()) { + matchAttempts = mchTrackInfoIt->second.compatMftTracks.size(); + } std::get>(plotter->fMatchRanking->hist)->Fill(trueMatchIndex); std::get>(plotter->fMatchRanking->histVsP)->Fill(mchMom, trueMatchIndex); @@ -2462,18 +2532,16 @@ struct QaMatching { if (globalTracksVector.size() < 1) continue; - int trueMatchIndex = getTrueMatchIndex(muonTracks, globalTracksVector, matchablePairs); + int trueMatchIndex = getTrueMatchIndex(globalTracksVector, matchablePairs); // loop over candidates int candidateIndex = 1; for (const auto& candidate : globalTracksVector) { - auto const& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); - float matchScore = candidate.matchScore; float matchChi2 = candidate.matchChi2; - float matchChi2Prod = muonTrack.chi2MatchMCHMFT() / 5.f; - float matchScoreProd = chi2ToScore(muonTrack.chi2MatchMCHMFT(), 5, 50.f); + float matchChi2Prod = candidate.matchChi2Prod; + float matchScoreProd = candidate.matchScoreProd; std::get>(plotter->fMatchScoreVsProd)->Fill(matchScoreProd, matchScore); std::get>(plotter->fMatchChi2VsProd)->Fill(matchChi2Prod, matchChi2); @@ -2493,10 +2561,6 @@ struct QaMatching { if (globalTracksVector.size() < 1) continue; - // get the leading matching candidate - auto const& muonTrack = muonTracks.rawIteratorAt(globalTracksVector[0].globalTrackId); - double matchingScore = globalTracksVector[0].matchScore; - // get the standalone MCH and MFT tracks auto const& mchTrack = muonTracks.rawIteratorAt(mchIndex); @@ -2505,14 +2569,14 @@ struct QaMatching { continue; // skip candidates that do not pass the matching quality cuts - if (!isGoodGlobalMatching(muonTrack, matchingScore, matchingScoreCut)) + if (!isGoodGlobalMatching(globalTracksVector[0], matchingScoreCut)) continue; // check if the matching candidate is a true one - bool isTrueMatch = isTrueGlobalMatching(muonTrack, matchablePairs); + bool isTrueMatch = isTrueGlobalMatching(globalTracksVector[0], matchablePairs); // ---- MC ancestry ---- - auto motherParticles = getMotherParticles(muonTrack); + auto motherParticles = getMotherParticles(mchTrack); int motherPDG = 0; if (motherParticles.size() > 1) { motherPDG = motherParticles[1].first; @@ -2544,15 +2608,10 @@ struct QaMatching { if (matchingCandidates.count(matchableMchIndex) > 0) { const auto& globalTracksVector = matchingCandidates.at(static_cast(matchableMchIndex)); if (!globalTracksVector.empty()) { - // get the leading matching candidate - auto const& muonTrack = muonTracks.rawIteratorAt(globalTracksVector[0].globalTrackId); - double matchingScore = globalTracksVector[0].matchScore; - - // get the standalone MFT track - auto const& mftTrack = muonTrack.template matchMFTTrack_as(); - auto mftIndex = mftTrack.globalIndex(); + // get the standalone MFT track index + auto mftIndex = globalTracksVector[0].mftTrackId; - goodMatchFound = isGoodGlobalMatching(muonTrack, matchingScore, matchingScoreCut); + goodMatchFound = isGoodGlobalMatching(globalTracksVector[0], matchingScoreCut); isTrueMatch = (mftIndex == matchableMftIndex); } } @@ -2633,8 +2692,6 @@ struct QaMatching { auto const& muonTrack1 = muonTracks.rawIteratorAt(candidates1[0].globalTrackId); auto const& muonTrack2 = muonTracks.rawIteratorAt(candidates2[0].globalTrackId); - auto matchScore1 = candidates1[0].matchScore; - auto matchScore2 = candidates2[0].matchScore; auto const& mchTrack1 = muonTracks.rawIteratorAt(candidates1[0].muonTrackId); auto const& mchTrack2 = muonTracks.rawIteratorAt(candidates2[0].muonTrackId); auto const& mftTrack1 = mftTracks.rawIteratorAt(candidates1[0].mftTrackId); @@ -2660,29 +2717,34 @@ struct QaMatching { continue; } - bool goodGlobalMuonMatches = (isGoodGlobalMatching(muonTrack1, matchScore1) && isGoodGlobalMatching(muonTrack2, matchScore2)); + bool goodGlobalMuonMatches = (isGoodGlobalMatching(candidates1[0]) && isGoodGlobalMatching(candidates2[0])); double massMCH = getMuMuInvariantMass(propagateToVertexMch(mchTrack1, collision), propagateToVertexMch(mchTrack2, collision)); - double mass = getMuMuInvariantMass(propagateToVertexMft(mftTrack1, mchTrack1, collision), - propagateToVertexMft(mftTrack2, mchTrack2, collision)); + double massRescaledKine = getMuMuInvariantMass(propagateToVertexMft(mftTrack1, mchTrack1, collision), + propagateToVertexMft(mftTrack2, mchTrack2, collision)); + double massGlobalKine = getMuMuInvariantMass(propagateToVertexMft(muonTrack1, collision), + propagateToVertexMft(muonTrack2, collision)); registryDimuon.get(HIST("dimuon/invariantMass_MuonKine_GlobalMuonCuts"))->Fill(massMCH); - registryDimuon.get(HIST("dimuon/invariantMass_ScaledMftKine_GlobalMuonCuts"))->Fill(mass); + registryDimuon.get(HIST("dimuon/invariantMass_ScaledMftKine_GlobalMuonCuts"))->Fill(massRescaledKine); + registryDimuon.get(HIST("dimuon/invariantMass_GlobalKine_GlobalMuonCuts"))->Fill(massGlobalKine); registryDimuon.get(HIST("dimuon/MC/invariantMass_MuonKine_GlobalMuonCuts_vs_match_type"))->Fill(massMCH, matchType); - registryDimuon.get(HIST("dimuon/MC/invariantMass_ScaledMftKine_GlobalMuonCuts_vs_match_type"))->Fill(mass, matchType); + registryDimuon.get(HIST("dimuon/MC/invariantMass_ScaledMftKine_GlobalMuonCuts_vs_match_type"))->Fill(massRescaledKine, matchType); + registryDimuon.get(HIST("dimuon/MC/invariantMass_GlobalKine_GlobalMuonCuts_vs_match_type"))->Fill(massGlobalKine, matchType); if (goodGlobalMuonMatches) { registryDimuon.get(HIST("dimuon/invariantMass_MuonKine_GlobalMuonCuts_GoodMatches"))->Fill(massMCH); - registryDimuon.get(HIST("dimuon/invariantMass_ScaledMftKine_GlobalMuonCuts_GoodMatches"))->Fill(mass); + registryDimuon.get(HIST("dimuon/invariantMass_ScaledMftKine_GlobalMuonCuts_GoodMatches"))->Fill(massRescaledKine); + registryDimuon.get(HIST("dimuon/invariantMass_GlobalKine_GlobalMuonCuts_GoodMatches"))->Fill(massGlobalKine); registryDimuon.get(HIST("dimuon/MC/invariantMass_MuonKine_GlobalMuonCuts_GoodMatches_vs_match_type"))->Fill(massMCH, matchType); - registryDimuon.get(HIST("dimuon/MC/invariantMass_ScaledMftKine_GlobalMuonCuts_GoodMatches_vs_match_type"))->Fill(mass, matchType); + registryDimuon.get(HIST("dimuon/MC/invariantMass_ScaledMftKine_GlobalMuonCuts_GoodMatches_vs_match_type"))->Fill(massRescaledKine, matchType); + registryDimuon.get(HIST("dimuon/MC/invariantMass_GlobalKine_GlobalMuonCuts_GoodMatches_vs_match_type"))->Fill(massGlobalKine, matchType); } } } - template + template void runChi2Matching(C const& collisions, - BC const& bcs, TMUON const& muonTracks, TMFT const& mftTracks, CMFT const& mftCovs, @@ -2747,6 +2809,7 @@ struct QaMatching { candidate.globalTrackId, mchIndex, mftTrack.globalIndex(), + candidate.trackType, mftTrackProp, mchTrackProp, matchScore, @@ -2754,7 +2817,6 @@ struct QaMatching { -1, matchScoreProd, matchChi2Prod, - -1, kMatchTypeUndefined}); } else { newMatchingCandidates[mchIndex].emplace_back(MatchingCandidate{ @@ -2762,6 +2824,7 @@ struct QaMatching { candidate.globalTrackId, mchIndex, mftTrack.globalIndex(), + candidate.trackType, mftTrackProp, mchTrackProp, matchScore, @@ -2769,7 +2832,6 @@ struct QaMatching { -1, matchScoreProd, matchChi2Prod, - -1, kMatchTypeUndefined}); } } @@ -2783,27 +2845,21 @@ struct QaMatching { for (auto& [mchIndex, globalTracksVector] : newMatchingCandidates) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) std::sort(globalTracksVector.begin(), globalTracksVector.end(), compareMatchingChi2); - const auto& mchTrack = muonTracks.rawIteratorAt(mchIndex); - auto mftMchMatchAttempts = getMftMchMatchAttempts(collisions, bcs, mchTrack, mftTracks); int ranking = 1; for (auto& candidate : globalTracksVector) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) - const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); - candidate.matchRanking = ranking; if constexpr (isMC) { - candidate.matchType = getMatchType(muonTrack, muonTracks, mftTracks, matchablePairs, ranking); + candidate.matchType = getMatchType(candidate, muonTracks, mftTracks, matchablePairs, ranking); } else { candidate.matchType = kMatchTypeUndefined; } - candidate.mftMchMatchAttempts = mftMchMatchAttempts; ranking += 1; } } } - template + template void runChi2Matching(C const& collisions, - BC const& bcs, TMUON const& muonTracks, TMFT const& mftTracks, CMFT const& mftCovs, @@ -2832,12 +2888,11 @@ struct QaMatching { auto matchingPlaneZ = matchingPlanesZ[label]; auto extrapMethod = matchingExtrapMethod[label]; - runChi2Matching(collisions, bcs, muonTracks, mftTracks, mftCovs, funcName, matchingPlaneZ, extrapMethod, matchablePairs, matchingCandidates, newMatchingCandidates); + runChi2Matching(collisions, muonTracks, mftTracks, mftCovs, funcName, matchingPlaneZ, extrapMethod, matchablePairs, matchingCandidates, newMatchingCandidates); } - template + template void runMlMatching(C const& collisions, - BC const& bcs, TMUON const& muonTracks, TMFT const& mftTracks, CMFT const& mftCovs, @@ -2884,8 +2939,12 @@ struct QaMatching { std::vector inputML = mlResponse.getInputFeatures(muonTrack, mftTrack, mchTrack, mftTrackProp, mchTrackProp, collision); mlResponse.isSelectedMl(inputML, 0, output); float matchScore = output[0]; - float matchChi2Prod = muonTrack.chi2MatchMCHMFT() / MatchingDegreesOfFreedom; - float matchScoreProd = chi2ToScore(muonTrack.chi2MatchMCHMFT(), MatchingDegreesOfFreedom, MatchingScoreChi2Max); + float matchScoreInv = (matchScore > 0) ? 1.0 / matchScore : std::numeric_limits::max(); + float matchChi2 = matchScoreInv - 1.f; + + float matchChi2Prod{-1}; + float matchScoreProd{-1}; + getMatchChi2AndScore(muonTrack, matchChi2Prod, matchScoreProd); // check if a vector of global muon candidates is already available for the current MCH index // if not, initialize a new one and add the current global muon track @@ -2896,14 +2955,14 @@ struct QaMatching { candidate.globalTrackId, mchIndex, mftTrack.globalIndex(), + candidate.trackType, mftTrackProp, mchTrackProp, matchScore, - -1, + matchChi2, -1, matchScoreProd, matchChi2Prod, - -1, kMatchTypeUndefined}); } else { newMatchingCandidates[mchIndex].emplace_back(MatchingCandidate{ @@ -2911,14 +2970,14 @@ struct QaMatching { candidate.globalTrackId, mchIndex, mftTrack.globalIndex(), + candidate.trackType, mftTrackProp, mchTrackProp, matchScore, - -1, + matchChi2, -1, matchScoreProd, matchChi2Prod, - -1, kMatchTypeUndefined}); } } @@ -2932,28 +2991,22 @@ struct QaMatching { for (auto& [mchIndex, globalTracksVector] : newMatchingCandidates) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) std::sort(globalTracksVector.begin(), globalTracksVector.end(), compareMatchingScore); - const auto& mchTrack = muonTracks.rawIteratorAt(mchIndex); - auto mftMchMatchAttempts = getMftMchMatchAttempts(collisions, bcs, mchTrack, mftTracks); int ranking = 1; for (auto& candidate : globalTracksVector) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) - const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); - candidate.matchRanking = ranking; if constexpr (isMC) { - candidate.matchType = getMatchType(muonTrack, muonTracks, mftTracks, matchablePairs, ranking); + candidate.matchType = getMatchType(candidate, muonTracks, mftTracks, matchablePairs, ranking); } else { candidate.matchType = kMatchTypeUndefined; } - candidate.mftMchMatchAttempts = mftMchMatchAttempts; ranking += 1; } } } - template + template void processCollision(const CollisionInfo& collisionInfo, C const& collisions, - BC const& bcs, TMUON const& muonTracks, TMFT const& mftTracks, CMFT const& mftCovs) @@ -2965,11 +3018,67 @@ struct QaMatching { int debugCounter{0}; fillQaMatchingAodEventForCollision(collisionInfo, collision, collisionInfo.reducedEventId, debugCounter); - fillQaMatchingMchTracksForCollision(collisionInfo, collisions, collision, muonTracks, mftTracks, bcs, taggedMuons, collisionInfo.reducedEventId); + fillQaMatchingMchTracksForCollision(collisionInfo, collision, muonTracks, taggedMuons, collisionInfo.reducedEventId); registry.get(HIST("tracksMultiplicityMFT"))->Fill(collisionInfo.mftTracks.size()); registry.get(HIST("tracksMultiplicityMCH"))->Fill(collisionInfo.mchTracks.size()); + for (const auto& element : collisionInfo.mchTracks) { + auto mchIndex = element.first; + auto const& mchTrack = muonTracks.rawIteratorAt(mchIndex); + auto mchTrackAtVertex = VarManager::PropagateMuon(mchTrack, collision, VarManager::kToVertex); + + float mchEta = mchTrack.eta(); + float mchPt = mchTrack.pt(); + float mchP = mchTrack.p(); + float mchEtaAtVertex = mchTrackAtVertex.getEta(); + float mchPtAtVertex = mchTrackAtVertex.getPt(); + + float zMftFront = o2::mft::constants::mft::LayerZCoordinate()[0]; + float zMftBack = o2::mft::constants::mft::LayerZCoordinate()[9]; + auto mchTrackAtMftFront = propagateToZMch(mchTrackAtVertex, zMftFront); + auto mchTrackAtMftBack = propagateToZMch(mchTrackAtVertex, zMftBack); + + float rAtMftFront = std::hypot(mchTrackAtMftFront.getX(), mchTrackAtMftFront.getY()); + float rAtMftBack = std::hypot(mchTrackAtMftBack.getX(), mchTrackAtMftBack.getY()); + + if (isMC) { + registry.get(HIST("matching/MC/muonTracksVsMchKine"))->Fill(mchEta, mchPt, collision.posZ()); + registry.get(HIST("matching/MC/muonTracksVsMchKineAtVertex"))->Fill(mchEtaAtVertex, mchPtAtVertex, collision.posZ()); + registry.get(HIST("matching/MC/muonTracksRadiusAtMftFront"))->Fill(rAtMftFront, collision.posZ(), mchP); + registry.get(HIST("matching/MC/muonTracksRadiusAtMftBack"))->Fill(rAtMftBack, collision.posZ(), mchP); + } else { + registry.get(HIST("matching/muonTracksVsMchKine"))->Fill(mchEta, mchPt, collision.posZ()); + registry.get(HIST("matching/muonTracksVsMchKineAtVertex"))->Fill(mchEtaAtVertex, mchPtAtVertex, collision.posZ()); + registry.get(HIST("matching/muonTracksRadiusAtMftFront"))->Fill(rAtMftFront, collision.posZ(), mchP); + registry.get(HIST("matching/muonTracksRadiusAtMftBack"))->Fill(rAtMftBack, collision.posZ(), mchP); + } + + if (isMC) { + auto matchablePair = getMatchablePairForMch(mchIndex, collisionInfo.matchablePairs); + if (!matchablePair) { + continue; + } + auto const& mftTrack = mftTracks.rawIteratorAt(matchablePair.value().second); + registry.get(HIST("matching/MC/muonTracksPairedVsMchKine"))->Fill(mchEta, mchPt, collision.posZ(), mftTrack.nClusters()); + registry.get(HIST("matching/MC/muonTracksPairedVsMchKineAtVertex"))->Fill(mchEtaAtVertex, mchPtAtVertex, collision.posZ(), mftTrack.nClusters()); + + registry.get(HIST("matching/MC/muonTracksRadiusPairedAtMftFront"))->Fill(rAtMftFront, collision.posZ(), mchP); + registry.get(HIST("matching/MC/muonTracksRadiusPairedAtMftBack"))->Fill(rAtMftBack, collision.posZ(), mchP); + + if (mftTrackCovs.count(mftTrack.globalIndex()) < 1) { + continue; + } + auto const& mftTrackCov = mftCovs.rawIteratorAt(mftTrackCovs[mftTrack.globalIndex()]); + + // extrapolate the tracks to the matching plane + auto mftTrackAtMftBack = propagateToZMft(fwdToTrackPar(mftTrack, mftTrackCov), zMftBack); + + registry.get(HIST("matching/MC/pairedMCHTracksAtMFT"))->Fill(mchTrackAtMftBack.getX(), mchTrackAtMftBack.getY()); + registry.get(HIST("matching/MC/pairedMFTTracksAtMFT"))->Fill(mftTrackAtMftBack.getX(), mftTrackAtMftBack.getY()); + } + } + int matchingMethodCounter{0}; //------------------------------- @@ -2983,29 +3092,6 @@ struct QaMatching { //------------------------------- // Tagged muons - for (const auto& [mchIndex, mftIndex] : collisionInfo.matchablePairs) { - auto const& mchTrack = muonTracks.rawIteratorAt(mchIndex); - if (!mchTrack.has_collision()) - continue; - auto collision = collisions.rawIteratorAt(mchTrack.collisionId()); - - auto const& mftTrack = mftTracks.rawIteratorAt(mftIndex); - if (mftTrackCovs.count(mftTrack.globalIndex()) < 1) { - continue; - } - auto const& mftTrackCov = mftCovs.rawIteratorAt(mftTrackCovs[mftTrack.globalIndex()]); - - auto mchTrackAtVertex = VarManager::PropagateMuon(mchTrack, collision, VarManager::kToVertex); - - // extrapolate to the matching plane - auto z = o2::mft::constants::mft::LayerZCoordinate()[9]; - auto mchTrackProp = propagateToZMch(mchTrackAtVertex, z); - auto mftTrackProp = propagateToZMft(fwdToTrackPar(mftTrack, mftTrackCov), z); - - registry.get(HIST("matching/MC/pairedMCHTracksAtMFT"))->Fill(mchTrackProp.getX(), mchTrackProp.getY()); - registry.get(HIST("matching/MC/pairedMFTTracksAtMFT"))->Fill(mftTrackProp.getX(), mftTrackProp.getY()); - } - MatchingCandidates taggedMatchingCandidates; for (const auto& [mchIndex, globalTracksVector] : collisionInfo.matchingCandidates) { if (std::find(taggedMuons.begin(), taggedMuons.end(), mchIndex) != taggedMuons.end()) { @@ -3022,7 +3108,7 @@ struct QaMatching { // Custom chi2-based matching methods for (const auto& [label, func] : matchingChi2Functions) { MatchingCandidates matchingCandidates; - runChi2Matching(collisions, bcs, muonTracks, mftTracks, mftCovs, label, collisionInfo.matchablePairs, collisionInfo.matchingCandidates, matchingCandidates); + runChi2Matching(collisions, muonTracks, mftTracks, mftCovs, label, collisionInfo.matchablePairs, collisionInfo.matchingCandidates, matchingCandidates); auto* plotter = fMatchingPlotters.at(label).get(); double matchingScoreCut = matchingScoreCuts.at(label); @@ -3040,7 +3126,7 @@ struct QaMatching { // Custom ML-based matching methods for (const auto& [label, mlResponse] : matchingMlResponses) { MatchingCandidates matchingCandidates; - runMlMatching(collisions, bcs, muonTracks, mftTracks, mftCovs, label, collisionInfo.matchablePairs, collisionInfo.matchingCandidates, matchingCandidates); + runMlMatching(collisions, muonTracks, mftTracks, mftCovs, label, collisionInfo.matchablePairs, collisionInfo.matchingCandidates, matchingCandidates); auto* plotter = fMatchingPlotters.at(label).get(); double matchingScoreCut = matchingScoreCuts.at(label); @@ -3130,33 +3216,33 @@ struct QaMatching { } } - template + template void fillQaMatchingMchTracksForCollision(const CollisionInfo& collisionInfo, - TCOLLISIONS const& collisions, TCOLLISION const& collision, TMUON const& muonTracks, - TMFT const& mftTracks, - TBC const& bcs, const std::vector& taggedMuons, int32_t reducedEventId) { std::vector mchIds; - for (const auto& mchIndex : collisionInfo.mchTracks) { - if (std::find(mchIds.begin(), mchIds.end(), mchIndex) == mchIds.end()) { - mchIds.emplace_back(mchIndex); + for (const auto& mchTrack : collisionInfo.mchTracks) { + if (std::find(mchIds.begin(), mchIds.end(), mchTrack.first) == mchIds.end()) { + mchIds.emplace_back(mchTrack.first); } } - for (const auto& [mchIndex, candidates] : collisionInfo.matchingCandidates) { - (void)candidates; - if (std::find(mchIds.begin(), mchIds.end(), mchIndex) == mchIds.end()) { - mchIds.emplace_back(mchIndex); + for (const auto& candidate : collisionInfo.matchingCandidates) { + if (std::find(mchIds.begin(), mchIds.end(), candidate.first) == mchIds.end()) { + mchIds.emplace_back(candidate.first); } } for (const auto& mchIndex : mchIds) { auto const& mchTrack = muonTracks.rawIteratorAt(mchIndex); - int mftMchMatchAttempts = getMftMchMatchAttempts(collisions, bcs, mchTrack, mftTracks); + int mftMchMatchAttempts = 0; + if (const auto& mchTrackInfoIt = collisionInfo.mchTracks.find(mchIndex); mchTrackInfoIt != collisionInfo.mchTracks.end()) { + mftMchMatchAttempts = mchTrackInfoIt->second.compatMftTracks.size(); + } auto mchTrackAtVertex = VarManager::PropagateMuon(mchTrack, collision, VarManager::kToVertex); + auto mchTrackAtPlaneZ2 = propagateToZMch(mchTrackAtVertex, o2::mft::constants::mft::LayerZCoordinate()[9]); bool isTagged = false; if (std::find(taggedMuons.begin(), taggedMuons.end(), mchIndex) != taggedMuons.end()) { isTagged = true; @@ -3173,6 +3259,9 @@ struct QaMatching { static_cast(mchTrackAtVertex.getX()), static_cast(mchTrackAtVertex.getY()), static_cast(mchTrackAtVertex.getZ()), + static_cast(mchTrackAtPlaneZ2.getX()), + static_cast(mchTrackAtPlaneZ2.getY()), + static_cast(mchTrackAtPlaneZ2.getZ()), static_cast(mchTrackAtVertex.getPx()), static_cast(mchTrackAtVertex.getPy()), static_cast(mchTrackAtVertex.getPz())); @@ -3201,7 +3290,7 @@ struct QaMatching { fillCollisions(collisions, bcs, muonTracks, mftTracks, mftCovs, fCollisionInfos); for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) { - processCollision(collisionInfo, collisions, bcs, muonTracks, mftTracks, mftCovs); + processCollision(collisionInfo, collisions, muonTracks, mftTracks, mftCovs); } } @@ -3228,11 +3317,38 @@ struct QaMatching { fillCollisions(collisions, bcs, muonTracks, mftTracks, mftCovs, fCollisionInfos); for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) { - processCollision(collisionInfo, collisions, bcs, muonTracks, mftTracks, mftCovs); + processCollision(collisionInfo, collisions, muonTracks, mftTracks, mftCovs); } } PROCESS_SWITCH(QaMatching, processQA, "processQA", false); + + void processQAReAlign(MyEvents const& collisions, + aod::BCsWithTimestamps const& bcs, + MyMuonsReAlign const& muonTracks, + MyMFTs const& mftTracks, + MyMFTCovariances const& mftCovs) + { + auto bc = bcs.begin(); + initCcdb(bc); + + for (const auto& muon : muonTracks) { + registry.get(HIST("nTracksPerType"))->Fill(static_cast(muon.trackType())); + } + + mftTrackCovs.clear(); + for (const auto& mftTrackCov : mftCovs) { + mftTrackCovs[mftTrackCov.matchMFTTrackId()] = mftTrackCov.globalIndex(); + } + + fillCollisions(collisions, bcs, muonTracks, mftTracks, mftCovs, fCollisionInfos); + + for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) { + processCollision(collisionInfo, collisions, muonTracks, mftTracks, mftCovs); + } + } + + PROCESS_SWITCH(QaMatching, processQAReAlign, "processQAReAlign", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGDQ/Tasks/tableReader.cxx b/PWGDQ/Tasks/tableReader.cxx index 741ac75cc79..f8e00266743 100644 --- a/PWGDQ/Tasks/tableReader.cxx +++ b/PWGDQ/Tasks/tableReader.cxx @@ -350,6 +350,8 @@ struct AnalysisTrackSelection { int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. + int64_t reserveSize = 0; + void init(o2::framework::InitContext& context) { if (context.mOptions.get("processDummy")) { @@ -416,7 +418,8 @@ struct AnalysisTrackSelection { fCurrentRun = event.runNumber(); } - trackSel.reserve(tracks.size()); + reserveSize += tracks.size(); + trackSel.reserve(reserveSize); uint32_t filterMap = 0; bool prefilterSelected = false; int iCut = 0; @@ -477,6 +480,8 @@ struct AnalysisMuonSelection { Filter filterEventSelected = aod::dqanalysisflags::isEventSelected == 1; + int64_t reserveSize = 0; + void init(o2::framework::InitContext& context) { if (context.mOptions.get("processDummy")) { @@ -516,7 +521,8 @@ struct AnalysisMuonSelection { VarManager::ResetValues(0, VarManager::kNMuonTrackVariables); VarManager::FillEvent(event); - muonSel.reserve(muons.size()); + reserveSize += muons.size(); + muonSel.reserve(reserveSize); uint32_t filterMap = 0; int iCut = 0; @@ -1026,6 +1032,7 @@ struct AnalysisSameEventPairing { Produces dielectronInfoList; Produces dimuonExtraList; Produces dielectronAllList; + Produces dielectronMlList; Produces dimuonAllList; Produces dileptonFlowList; Produces dileptonInfoList; @@ -1102,6 +1109,8 @@ struct AnalysisSameEventPairing { std::vector> fTrackMuonHistNames; std::vector fPairCuts; + int64_t reserveSize = 0; + void init(o2::framework::InitContext& context) { if (context.mOptions.get("processDummy")) { @@ -1371,19 +1380,26 @@ struct AnalysisSameEventPairing { uint32_t twoTrackFilter = 0; uint32_t dileptonFilterMap = 0; uint32_t dileptonMcDecision = 0; // placeholder, copy of the dqEfficiency.cxx one - dielectronList.reserve(1); - dimuonList.reserve(1); - dielectronExtraList.reserve(1); - dielectronInfoList.reserve(1); - dimuonExtraList.reserve(1); - dileptonInfoList.reserve(1); - dileptonFlowList.reserve(1); + + if constexpr (TPairType != VarManager::kElectronMuon) { + // tracks1 = tracks2 + // since emu does not require any table in this task, reserveSize is updated for same particle only now + reserveSize += tracks1.size() * (tracks1.size() - 1) / 2; + } + dielectronList.reserve(reserveSize); + dimuonList.reserve(reserveSize); + dielectronExtraList.reserve(reserveSize); + dielectronInfoList.reserve(reserveSize); + dimuonExtraList.reserve(reserveSize); + dileptonInfoList.reserve(reserveSize); + dileptonFlowList.reserve(reserveSize); if (fConfigFlatTables.value) { - dielectronAllList.reserve(1); - dimuonAllList.reserve(1); + dielectronAllList.reserve(reserveSize); + dielectronMlList.reserve(reserveSize); + dimuonAllList.reserve(reserveSize); } if (useMiniTree.fConfigMiniTree) { - dileptonMiniTree.reserve(1); + dileptonMiniTree.reserve(reserveSize); } bool isSelectedBDT = false; @@ -1466,6 +1482,8 @@ struct AnalysisSameEventPairing { } } if constexpr ((TPairType == pairTypeEE) && (TTrackFillMap & VarManager::ObjTypes::ReducedTrackBarrelPID) > 0) { + isSelectedBDT = false; + fOutputMlPsi2ee.clear(); if (applyBDT) { std::vector dqInputFeatures = fDQMlResponse.getInputFeatures(t1, t2, VarManager::fgValues); @@ -1497,7 +1515,7 @@ struct AnalysisSameEventPairing { LOG(debug) << "Model index: " << modelIndex << ", pT: " << VarManager::fgValues[VarManager::kPt] << ", centrality (kCentFT0C): " << VarManager::fgValues[VarManager::kCentFT0C]; isSelectedBDT = fDQMlResponse.isSelectedMl(dqInputFeatures, modelIndex, fOutputMlPsi2ee); - VarManager::FillBdtScore(fOutputMlPsi2ee); // TODO: check if this is needed or not + VarManager::FillBdtScore(fOutputMlPsi2ee); } if (applyBDT && !isSelectedBDT) @@ -1512,6 +1530,10 @@ struct AnalysisSameEventPairing { VarManager::fgValues[VarManager::kKFMass], VarManager::fgValues[VarManager::kKFChi2OverNDFGeo], VarManager::fgValues[VarManager::kVertexingLxyz], VarManager::fgValues[VarManager::kVertexingLxyzOverErr], VarManager::fgValues[VarManager::kVertexingLxy], VarManager::fgValues[VarManager::kVertexingLxyOverErr], VarManager::fgValues[VarManager::kVertexingTauxy], VarManager::fgValues[VarManager::kVertexingTauxyErr], VarManager::fgValues[VarManager::kKFCosPA], VarManager::fgValues[VarManager::kKFJpsiDCAxyz], VarManager::fgValues[VarManager::kKFJpsiDCAxy], VarManager::fgValues[VarManager::kKFPairDeviationFromPV], VarManager::fgValues[VarManager::kKFPairDeviationxyFromPV], VarManager::fgValues[VarManager::kKFMassGeoTop], VarManager::fgValues[VarManager::kKFChi2OverNDFGeoTop], VarManager::fgValues[VarManager::kVertexingTauzProjected], VarManager::fgValues[VarManager::kVertexingTauxyProjected], VarManager::fgValues[VarManager::kVertexingLzProjected], VarManager::fgValues[VarManager::kVertexingLxyProjected]); + dielectronMlList(VarManager::fgValues[VarManager::kCentFT0C], + (applyBDT && fOutputMlPsi2ee.size() > 0) ? VarManager::fgValues[VarManager::kBdtBackground] : -999.f, + (applyBDT && fOutputMlPsi2ee.size() > 1) ? VarManager::fgValues[VarManager::kBdtPrompt] : -999.f, + (applyBDT && fOutputMlPsi2ee.size() > 2) ? VarManager::fgValues[VarManager::kBdtNonprompt] : -999.f); } } if constexpr (TPairType == pairTypeMuMu) { diff --git a/PWGDQ/Tasks/tableReader_withAssoc.cxx b/PWGDQ/Tasks/tableReader_withAssoc.cxx index 9e61737c6dc..eaaea676093 100644 --- a/PWGDQ/Tasks/tableReader_withAssoc.cxx +++ b/PWGDQ/Tasks/tableReader_withAssoc.cxx @@ -24,6 +24,7 @@ #include "PWGDQ/DataModel/ReducedInfoTables.h" #include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/ctpRateFetcher.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/TableHelper.h" @@ -65,7 +66,6 @@ #include #include #include -#include #include #include #include @@ -74,8 +74,6 @@ #include #include -using std::cout; -using std::endl; using std::string; using namespace o2; @@ -240,7 +238,7 @@ using MyEventsVtxCovZdcFitSelected = soa::Join; using MyEventsQvector = soa::Join; using MyEventsHashSelectedQvector = soa::Join; -using MyEventsQvectorCentr = soa::Join; +using MyEventsQvectorCentr = soa::Join; using MyEventsQvectorCentrSelected = soa::Join; using MyEventsHashSelectedQvectorCentr = soa::Join; @@ -249,7 +247,7 @@ using MyBarrelTracksWithAmbiguities = soa::Join; using MyBarrelTracksWithCovWithAmbiguities = soa::Join; using MyBarrelTracksWithCovWithAmbiguitiesWithColl = soa::Join; -using MyDielectronCandidates = soa::Join; +using MyDielectronCandidates = soa::Join; using MyDitrackCandidates = soa::Join; using MyDimuonCandidates = soa::Join; using MyMuonTracks = soa::Join; @@ -285,15 +283,25 @@ constexpr static int pairTypeEE = VarManager::kDecayToEE; constexpr static int pairTypeMuMu = VarManager::kDecayToMuMu; // constexpr static int pairTypeEMu = VarManager::kElectronMuon; +namespace dqtablereader_helpers +{ +inline float* varValues() { return static_cast(VarManager::fgValues); } +inline TString* varNames() { return static_cast(VarManager::fgVariableNames); } +inline TString* varUnits() { return static_cast(VarManager::fgVariableUnits); } +} // namespace dqtablereader_helpers + // Global function used to define needed histogram classes -void DefineHistograms(HistogramManager* histMan, TString histClasses, const char* histGroups); // defines histograms for all tasks +void DefineHistograms(HistogramManager* histMan, const TString& histClasses, const char* histGroups); // defines histograms for all tasks template void PrintBitMap(TMap map, int nbits) { + std::string bits; + bits.reserve(nbits); for (int i = 0; i < nbits; i++) { - cout << ((map & (TMap(1) << i)) > 0 ? "1" : "0"); + bits += ((map & (TMap(1) << i)) > 0 ? '1' : '0'); } + LOG(info) << bits; } // Analysis task that produces event decisions (analysis cut, in bunch pileup and split collision check) and the Hash table used in event mixing @@ -323,17 +331,20 @@ struct AnalysisEventSelection { Configurable fConfigRunZorro{"cfgRunZorro", false, "Enable event selection with zorro [WARNING: under debug, do not enable!]"}; Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + Configurable fConfigFetchInteractionRate{"cfgFetchInteractionRate", false, "Fetch event-wise interaction rate from the CCDB"}; + Configurable fConfigIRSource{"cfgIRSource", "ZNC hadronic", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; HistogramManager* fHistMan = nullptr; MixingHandler* fMixHandler = nullptr; - AnalysisCompositeCut* fEventCut; + AnalysisCompositeCut* fEventCut = nullptr; - Service fCCDB; + Service fCCDB{}; o2::ccdb::CcdbApi fCCDBApi; + ctpRateFetcher rateFetcher; std::map fSelMap; // key: reduced event global index, value: event selection decision std::map> fBCCollMap; // key: global BC, value: vector of reduced event global indices - int fCurrentRun; + int fCurrentRun = -1; void init(o2::framework::InitContext& context) { @@ -365,7 +376,7 @@ struct AnalysisEventSelection { TString eventCutJSONStr = fConfigEventCutsJSON.value; if (eventCutJSONStr != "") { std::vector jsonCuts = dqcuts::GetCutsFromJSON(eventCutJSONStr.Data()); - for (auto& cutIt : jsonCuts) { + for (auto const& cutIt : jsonCuts) { fEventCut->AddCut(cutIt); } } @@ -375,7 +386,7 @@ struct AnalysisEventSelection { if (fConfigQA) { fHistMan = new HistogramManager("analysisHistos", "", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(kTRUE); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqtablereader_helpers::varNames(), dqtablereader_helpers::varUnits()); DefineHistograms(fHistMan, "Event_BeforeCuts;Event_AfterCuts;", fConfigAddEventHistogram.value.data()); if (fConfigCheckSplitCollisions) { DefineHistograms(fHistMan, "SameBunchCorrelations;OutOfBunchCorrelations;", ""); @@ -421,7 +432,7 @@ struct AnalysisEventSelection { VarManager::SetSORandEOR(sor, eor); auto alppar = fCCDB->getForTimeStamp>("ITS/Config/AlpideParam", events.begin().timestamp()); - EventSelectionParams* par = fCCDB->getForTimeStamp("EventSelection/EventSelectionParams", events.begin().timestamp()); + auto par = fCCDB->getForTimeStamp("EventSelection/EventSelectionParams", events.begin().timestamp()); int itsROFrameStartBorderMargin = fConfigITSROFrameStartBorderMargin < 0 ? par->fITSROFrameStartBorderMargin : fConfigITSROFrameStartBorderMargin; int itsROFrameEndBorderMargin = fConfigITSROFrameEndBorderMargin < 0 ? par->fITSROFrameEndBorderMargin : fConfigITSROFrameEndBorderMargin; VarManager::SetITSROFBorderselection(alppar->roFrameBiasInBC, alppar->roFrameLengthInBC, itsROFrameStartBorderMargin, itsROFrameEndBorderMargin); @@ -431,29 +442,33 @@ struct AnalysisEventSelection { fSelMap.clear(); fBCCollMap.clear(); - for (auto& event : events) { + for (auto const& event : events) { // Reset the fValues array and fill event observables VarManager::ResetValues(0, VarManager::kNEventWiseVariables); VarManager::FillEvent(event); + // Get the instantaneous IR from the CCDB + if (fConfigFetchInteractionRate.value) { + VarManager::fgValues[VarManager::kInteractionRate] = rateFetcher.fetch(fCCDB.service, event.timestamp(), fCurrentRun, fConfigIRSource.value, true) / 1000.; // kHz + } bool decision = false; // Fill histograms in the class Event, before cuts if (fConfigQA) { - fHistMan->FillHistClass("Event_BeforeCuts", VarManager::fgValues); + fHistMan->FillHistClass("Event_BeforeCuts", dqtablereader_helpers::varValues()); } // Apply event cuts and fill histograms after selection - if (fEventCut->IsSelected(VarManager::fgValues)) { + if (fEventCut->IsSelected(dqtablereader_helpers::varValues())) { if (fConfigRunZorro) { if (event.tag_bit(56)) { // This is the bit used for the software trigger event selections [TO BE DONE: find a more clear way to use it] if (fConfigQA) { - fHistMan->FillHistClass("Event_AfterCuts", VarManager::fgValues); + fHistMan->FillHistClass("Event_AfterCuts", dqtablereader_helpers::varValues()); } decision = true; } } else { if (fConfigQA) { - fHistMan->FillHistClass("Event_AfterCuts", VarManager::fgValues); + fHistMan->FillHistClass("Event_AfterCuts", dqtablereader_helpers::varValues()); } decision = true; } @@ -473,7 +488,7 @@ struct AnalysisEventSelection { // create the mixing hash and publish it into the hash table if (fMixHandler != nullptr) { - int hh = fMixHandler->FindEventCategory(VarManager::fgValues); + int hh = fMixHandler->FindEventCategory(dqtablereader_helpers::varValues()); hash(hh); } } @@ -492,7 +507,7 @@ struct AnalysisEventSelection { // loop over the BC map, get the collision vectors and make in-bunch and out of bunch 2-event correlations for (auto bc1It = fBCCollMap.begin(); bc1It != fBCCollMap.end(); ++bc1It) { uint64_t bc1 = bc1It->first; - auto& bc1Events = bc1It->second; + auto const& bc1Events = bc1It->second; // same bunch event correlations, if more than 1 collisions in this bunch if (bc1Events.size() > 1) { @@ -507,7 +522,7 @@ struct AnalysisEventSelection { collisionSplittingMap[*ev2It] = true; } if (fConfigQA) { - fHistMan->FillHistClass("SameBunchCorrelations", VarManager::fgValues); + fHistMan->FillHistClass("SameBunchCorrelations", dqtablereader_helpers::varValues()); } } // end second event loop } // end first event loop @@ -519,13 +534,13 @@ struct AnalysisEventSelection { if ((bc2 > bc1 ? bc2 - bc1 : bc1 - bc2) > fConfigSplitCollisionsDeltaBC) { break; } - auto& bc2Events = bc2It->second; + auto const& bc2Events = bc2It->second; // loop over events in the first BC - for (auto ev1It : bc1Events) { + for (auto const& ev1It : bc1Events) { auto ev1 = events.rawIteratorAt(ev1It); // loop over events in the second BC - for (auto ev2It : bc2Events) { + for (auto const& ev2It : bc2Events) { auto ev2 = events.rawIteratorAt(ev2It); // compute 2-event quantities and mark the candidate split collisions VarManager::FillTwoEvents(ev1, ev2); @@ -534,7 +549,7 @@ struct AnalysisEventSelection { collisionSplittingMap[ev2It] = true; } if (fConfigQA) { - fHistMan->FillHistClass("OutOfBunchCorrelations", VarManager::fgValues); + fHistMan->FillHistClass("OutOfBunchCorrelations", dqtablereader_helpers::varValues()); } } } @@ -543,8 +558,8 @@ struct AnalysisEventSelection { } // publish the table - uint8_t evSel = static_cast(0); - for (auto& event : events) { + auto evSel = static_cast(0); + for (auto const& event : events) { evSel = 0; if (fSelMap[event.globalIndex()]) { // event passed the user cuts evSel |= (static_cast(1) << 0); @@ -602,7 +617,7 @@ struct AnalysisEventSelection { } void processFillEvents(MyEventsBasic const& events) // Used to forward the event table from tablemaker, typical use for now is jet analysis. { - for (auto& event : events) { + for (auto const& event : events) { JetEvents(event.tag_raw(), event.runNumber(), event.posX(), @@ -613,7 +628,7 @@ struct AnalysisEventSelection { event.collisionTimeRes()); } } - void processDummy(MyEventsBasic&) + void processDummy(MyEventsBasic const&) { // do nothing } @@ -655,13 +670,13 @@ struct AnalysisTrackSelection { // Track related options Configurable fPropTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"}; - Service fCCDB; + Service fCCDB{}; o2::ccdb::CcdbApi fCCDBApi; - HistogramManager* fHistMan; + HistogramManager* fHistMan = nullptr; std::vector fTrackCuts; - int fCurrentRun; // current run kept to detect run changes and trigger loading params from CCDB + int fCurrentRun = 0; // current run kept to detect run changes and trigger loading params from CCDB std::map> fNAssocsInBunch; // key: track global index, value: vector of global index for events associated in-bunch (events that have in-bunch pileup or splitting) std::map> fNAssocsOutOfBunch; // key: track global index, value: vector of global index for events associated out-of-bunch (events that have no in-bunch pileup) @@ -685,8 +700,8 @@ struct AnalysisTrackSelection { TString addTrackCutsStr = fConfigCutsJSON.value; if (addTrackCutsStr != "") { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); - for (auto& t : addTrackCuts) { - fTrackCuts.push_back(reinterpret_cast(t)); + for (auto const& t : addTrackCuts) { + fTrackCuts.push_back(static_cast(t)); } } @@ -695,11 +710,11 @@ struct AnalysisTrackSelection { if (fConfigQA) { fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(kTRUE); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqtablereader_helpers::varNames(), dqtablereader_helpers::varUnits()); // set one histogram directory for each defined track cut TString histDirNames = "TrackBarrel_BeforeCuts;"; - for (auto& cut : fTrackCuts) { + for (auto const& cut : fTrackCuts) { histDirNames += Form("TrackBarrel_%s;", cut->GetName()); } if (fConfigPublishAmbiguity) { @@ -742,7 +757,7 @@ struct AnalysisTrackSelection { VarManager::SetCalibrationType(fConfigTPCpostCalibType, fConfigTPCuseInterpolatedCalib); } - o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp(grpmagPath, events.begin().timestamp()); + auto grpmag = fCCDB->getForTimeStamp(grpmagPath, events.begin().timestamp()); if (grpmag != nullptr) { VarManager::SetMagneticField(grpmag->getNominalL3Field()); } else { @@ -760,10 +775,10 @@ struct AnalysisTrackSelection { trackSel.reserve(assocs.size()); trackAmbiguities.reserve(tracks.size()); - uint32_t filterMap = static_cast(0); + auto filterMap = static_cast(0); int iCut = 0; - for (auto& assoc : assocs) { + for (auto const& assoc : assocs) { // if the event from this association is not selected, reject also the association auto event = assoc.template reducedevent_as(); @@ -783,14 +798,14 @@ struct AnalysisTrackSelection { VarManager::FillTrackCollision(track, event); } if (fConfigQA) { - fHistMan->FillHistClass("TrackBarrel_BeforeCuts", VarManager::fgValues); + fHistMan->FillHistClass("TrackBarrel_BeforeCuts", dqtablereader_helpers::varValues()); } iCut = 0; for (auto cut = fTrackCuts.begin(); cut != fTrackCuts.end(); cut++, iCut++) { - if ((*cut)->IsSelected(VarManager::fgValues)) { + if ((*cut)->IsSelected(dqtablereader_helpers::varValues())) { filterMap |= (static_cast(1) << iCut); if (fConfigQA) { - fHistMan->FillHistClass(Form("TrackBarrel_%s", (*cut)->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("TrackBarrel_%s", (*cut)->GetName()), dqtablereader_helpers::varValues()); } } } // end loop over cuts @@ -824,7 +839,7 @@ struct AnalysisTrackSelection { if (fConfigPublishAmbiguity) { // QA the collision-track associations if (fConfigQA) { - for (auto& [trackIdx, evIndices] : fNAssocsInBunch) { + for (auto const& [trackIdx, evIndices] : fNAssocsInBunch) { if (evIndices.size() == 1) { continue; } @@ -833,10 +848,10 @@ struct AnalysisTrackSelection { VarManager::FillTrack(track); // Exceptionally, set the VarManager ambiguity number here, to be used in histograms VarManager::fgValues[VarManager::kBarrelNAssocsInBunch] = static_cast(evIndices.size()); - fHistMan->FillHistClass("TrackBarrel_AmbiguityInBunch", VarManager::fgValues); + fHistMan->FillHistClass("TrackBarrel_AmbiguityInBunch", dqtablereader_helpers::varValues()); } // end loop over in-bunch ambiguous tracks - for (auto& [trackIdx, evIndices] : fNAssocsOutOfBunch) { + for (auto const& [trackIdx, evIndices] : fNAssocsOutOfBunch) { if (evIndices.size() == 1) { continue; } @@ -845,12 +860,12 @@ struct AnalysisTrackSelection { VarManager::FillTrack(track); // Exceptionally, set the VarManager ambiguity number here VarManager::fgValues[VarManager::kBarrelNAssocsOutOfBunch] = static_cast(evIndices.size()); - fHistMan->FillHistClass("TrackBarrel_AmbiguityOutOfBunch", VarManager::fgValues); + fHistMan->FillHistClass("TrackBarrel_AmbiguityOutOfBunch", dqtablereader_helpers::varValues()); } // end loop over out-of-bunch ambiguous tracks } // publish the ambiguity table - for (auto& track : tracks) { + for (auto const& track : tracks) { int8_t nInBunch = 0; if (fNAssocsInBunch.find(track.globalIndex()) != fNAssocsInBunch.end()) { nInBunch = fNAssocsInBunch[track.globalIndex()].size(); @@ -877,7 +892,7 @@ struct AnalysisTrackSelection { { runTrackSelection(assocs, events, tracks); } - void processDummy(MyEventsBasic&) + void processDummy(MyEventsBasic const&) { // do nothing } @@ -907,12 +922,12 @@ struct AnalysisMuonSelection { Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigGeoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - Service fCCDB; + Service fCCDB{}; - HistogramManager* fHistMan; + HistogramManager* fHistMan = nullptr; std::vector fMuonCuts; - int fCurrentRun; // current run kept to detect run changes and trigger loading params from CCDB + int fCurrentRun = 0; // current run kept to detect run changes and trigger loading params from CCDB std::map> fNAssocsInBunch; // key: muon global index, value: vector of global index for events associated in-bunch (events that have in-bunch pileup or splitting) std::map> fNAssocsOutOfBunch; // key: muon global index, value: vector of global index for events associated out-of-bunch (events that have no in-bunch pileup) @@ -936,8 +951,8 @@ struct AnalysisMuonSelection { TString addCutsStr = fConfigCutsJSON.value; if (addCutsStr != "") { std::vector addCuts = dqcuts::GetCutsFromJSON(addCutsStr.Data()); - for (auto& t : addCuts) { - fMuonCuts.push_back(reinterpret_cast(t)); + for (auto const& t : addCuts) { + fMuonCuts.push_back(static_cast(t)); } } @@ -946,11 +961,11 @@ struct AnalysisMuonSelection { if (fConfigQA) { fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(kTRUE); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqtablereader_helpers::varNames(), dqtablereader_helpers::varUnits()); // set one histogram directory for each defined track cut TString histDirNames = "TrackMuon_BeforeCuts;"; - for (auto& cut : fMuonCuts) { + for (auto const& cut : fMuonCuts) { histDirNames += Form("TrackMuon_%s;", cut->GetName()); } if (fConfigPublishAmbiguity) { @@ -979,7 +994,7 @@ struct AnalysisMuonSelection { fNAssocsOutOfBunch.clear(); if (events.size() > 0 && fCurrentRun != events.begin().runNumber()) { - o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp(grpmagPath, events.begin().timestamp()); + auto grpmag = fCCDB->getForTimeStamp(grpmagPath, events.begin().timestamp()); if (grpmag != nullptr) { o2::base::Propagator::initFieldFromGRP(grpmag); VarManager::SetMagneticField(grpmag->getNominalL3Field()); @@ -991,10 +1006,10 @@ struct AnalysisMuonSelection { muonSel.reserve(assocs.size()); muonAmbiguities.reserve(muons.size()); - uint32_t filterMap = static_cast(0); + auto filterMap = static_cast(0); int iCut = 0; - for (auto& assoc : assocs) { + for (auto const& assoc : assocs) { auto event = assoc.template reducedevent_as(); if (!event.isEventSelected_bit(0)) { muonSel(0); @@ -1008,14 +1023,14 @@ struct AnalysisMuonSelection { filterMap = static_cast(0); VarManager::FillTrack(track); if (fConfigQA) { - fHistMan->FillHistClass("TrackMuon_BeforeCuts", VarManager::fgValues); + fHistMan->FillHistClass("TrackMuon_BeforeCuts", dqtablereader_helpers::varValues()); } iCut = 0; for (auto cut = fMuonCuts.begin(); cut != fMuonCuts.end(); cut++, iCut++) { - if ((*cut)->IsSelected(VarManager::fgValues)) { + if ((*cut)->IsSelected(dqtablereader_helpers::varValues())) { filterMap |= (static_cast(1) << iCut); if (fConfigQA) { - fHistMan->FillHistClass(Form("TrackMuon_%s", (*cut)->GetName()), VarManager::fgValues); + fHistMan->FillHistClass(Form("TrackMuon_%s", (*cut)->GetName()), dqtablereader_helpers::varValues()); } } } // end loop over cuts @@ -1046,7 +1061,7 @@ struct AnalysisMuonSelection { if (fConfigPublishAmbiguity) { // QA the collision-track associations if (fConfigQA) { - for (auto& [trackIdx, evIndices] : fNAssocsInBunch) { + for (auto const& [trackIdx, evIndices] : fNAssocsInBunch) { if (evIndices.size() == 1) { continue; } @@ -1054,10 +1069,10 @@ struct AnalysisMuonSelection { VarManager::ResetValues(0, VarManager::kNMuonTrackVariables); VarManager::FillTrack(track); VarManager::fgValues[VarManager::kMuonNAssocsInBunch] = static_cast(evIndices.size()); - fHistMan->FillHistClass("TrackMuon_AmbiguityInBunch", VarManager::fgValues); + fHistMan->FillHistClass("TrackMuon_AmbiguityInBunch", dqtablereader_helpers::varValues()); } // end loop over in-bunch ambiguous tracks - for (auto& [trackIdx, evIndices] : fNAssocsOutOfBunch) { + for (auto const& [trackIdx, evIndices] : fNAssocsOutOfBunch) { if (evIndices.size() == 1) { continue; } @@ -1065,12 +1080,12 @@ struct AnalysisMuonSelection { VarManager::ResetValues(0, VarManager::kNMuonTrackVariables); VarManager::FillTrack(track); VarManager::fgValues[VarManager::kMuonNAssocsOutOfBunch] = static_cast(evIndices.size()); - fHistMan->FillHistClass("TrackMuon_AmbiguityOutOfBunch", VarManager::fgValues); + fHistMan->FillHistClass("TrackMuon_AmbiguityOutOfBunch", dqtablereader_helpers::varValues()); } // end loop over out-of-bunch ambiguous tracks } // publish the ambiguity table - for (auto& track : muons) { + for (auto const& track : muons) { int8_t nInBunch = 0; if (fNAssocsInBunch.find(track.globalIndex()) != fNAssocsInBunch.end()) { nInBunch = fNAssocsInBunch[track.globalIndex()].size(); @@ -1088,7 +1103,7 @@ struct AnalysisMuonSelection { { runMuonSelection(assocs, events, muons); } - void processDummy(MyEventsBasic&) + void processDummy(MyEventsBasic const&) { // do nothing } @@ -1112,9 +1127,9 @@ struct AnalysisPrefilterSelection { // TODO: Add prefilter pair cut via JSON std::map fPrefilterMap; - AnalysisCompositeCut* fPairCut; - uint32_t fPrefilterMask; - int fPrefilterCutBit; + AnalysisCompositeCut* fPairCut = nullptr; + uint32_t fPrefilterMask = 0; + int fPrefilterCutBit = -1; Preslice trackAssocsPerCollision = aod::reducedtrack_association::reducedeventId; @@ -1158,7 +1173,7 @@ struct AnalysisPrefilterSelection { TString addTrackCutsStr = trackCuts; if (addTrackCutsStr != "") { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); - for (auto& t : addTrackCuts) { + for (auto const& t : addTrackCuts) { allTrackCutsStr += Form(",%s", t->GetName()); } } @@ -1202,7 +1217,7 @@ struct AnalysisPrefilterSelection { return; } - for (auto& [assoc1, assoc2] : o2::soa::combinations(assocs, assocs)) { + for (auto const& [assoc1, assoc2] : o2::soa::combinations(assocs, assocs)) { auto track1 = assoc1.template reducedtrack_as(); auto track2 = assoc2.template reducedtrack_as(); @@ -1219,14 +1234,14 @@ struct AnalysisPrefilterSelection { bool track2Loose = assoc2.isBarrelSelected_bit(fPrefilterCutBit); // Here we check if we should apply the prefilter for this pair - if (!((track1Candidate > 0 && track2Loose) || (track2Candidate > 0 && track1Loose))) { + if ((track1Candidate == 0 || !track2Loose) && (track2Candidate == 0 || !track1Loose)) { continue; } // compute pair quantities VarManager::FillPair(track1, track2); // if the pair fullfils the criteria, add an entry into the prefilter map for the two tracks - if (fPairCut->IsSelected(VarManager::fgValues)) { + if (fPairCut->IsSelected(dqtablereader_helpers::varValues())) { if (fPrefilterMap.find(track1.globalIndex()) == fPrefilterMap.end() && track1Candidate > 0) { fPrefilterMap[track1.globalIndex()] = track1Candidate; } @@ -1241,7 +1256,7 @@ struct AnalysisPrefilterSelection { { fPrefilterMap.clear(); - for (auto& event : events) { + for (auto const& event : events) { auto groupedAssocs = assocs.sliceBy(trackAssocsPerCollision, event.globalIndex()); if (groupedAssocs.size() > 1) { runPrefilter(groupedAssocs, tracks); @@ -1255,11 +1270,11 @@ struct AnalysisPrefilterSelection { prefilter(mymap); } } else { - for (auto& assoc : assocs) { + for (auto const& assoc : assocs) { // TODO: just use the index from the assoc (no need to cast the whole track) auto track = assoc.template reducedtrack_as(); mymap = -1; - if (fPrefilterMap.find(track.globalIndex()) != fPrefilterMap.end()) { + if (fPrefilterMap.contains(track.globalIndex())) { // NOTE: publish the bitwise negated bits (~), so there will be zeroes for cuts that failed the prefiltering and 1 everywhere else mymap = ~fPrefilterMap[track.globalIndex()]; prefilter(mymap); @@ -1270,7 +1285,7 @@ struct AnalysisPrefilterSelection { } } - void processDummy(MyEventsBasic&) + void processDummy(MyEventsBasic const&) { // do nothing } @@ -1293,15 +1308,19 @@ struct AnalysisSameEventPairing { Produces dielectronInfoList; Produces dimuonsExtraList; Produces dielectronAllList; + Produces dielectronMlList; Produces dimuonAllList; Produces dileptonFlowList; Produces dileptonInfoList; Produces PromptNonPromptSepTable; Produces dileptonPolarList; Produces dileptonEventInfoList; + Produces dileptonMiniTree; o2::base::MatLayerCylSet* fLUT = nullptr; - int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. + TH1D* ResoFlowSP = nullptr; + TH1D* ResoFlowEP = nullptr; + int fCurrentRun = -1; // needed to detect if the run changed and trigger update of calibrations etc. OutputObj fOutputList{"output"}; @@ -1309,6 +1328,7 @@ struct AnalysisSameEventPairing { Configurable track{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; Configurable muon{"cfgMuonCuts", "", "Comma separated list of muon cuts"}; Configurable pair{"cfgPairCuts", "", "Comma separated list of pair cuts"}; + Configurable qVector{"cfgQvectorTrackCut", "", "Track cut of Q-vector, enable this if you want to remove the auto-correlation in TPC"}; Configurable event{"cfgRemoveCollSplittingCandidates", false, "If true, remove collision splitting candidates as determined by the event selection task upstream"}; // TODO: Add pair cuts via JSON } fConfigCuts; @@ -1334,6 +1354,7 @@ struct AnalysisSameEventPairing { Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; Configurable GrpLhcIfPath{"grplhcif", "GLO/Config/GRPLHCIF", "Path on the CCDB for the GRPLHCIF object"}; Configurable efficiencyPath{"effHistPath", "Users/z/zhxiong/efficiency", "Path on the CCDB for the efficiency histograms"}; + Configurable flowPath{"flowPath", "Users/y/yiping/FlowResolution", "Path to the flow resolution object"}; } fConfigCCDB; struct : ConfigurableGroup { @@ -1352,6 +1373,7 @@ struct AnalysisSameEventPairing { Configurable useRemoteCollisionInfo{"cfgUseRemoteCollisionInfo", false, "Use remote collision information from CCDB"}; Configurable useEfficiencyWeighting{"cfgUseEfficiencyWeighting", false, "Apply efficiency weighting to the pairs from CCDB"}; Configurable efficiencyType{"cfgEfficiencyType", 0, "Type of efficiency to apply from CCDB: 0 no efficiency, 1 pt-cent-costhetastar"}; + Configurable useFlowReso{"cfgUseFlowReso", false, "Use remote flow information from CCDB"}; } fConfigOptions; struct : ConfigurableGroup { Configurable applyBDT{"applyBDT", false, "Flag to apply ML selections"}; @@ -1361,17 +1383,22 @@ struct AnalysisSameEventPairing { Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB"}; Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; } fConfigML; + struct : ConfigurableGroup { + Configurable fConfigMiniTree{"useMiniTree.cfgMiniTree", false, "Produce a single flat table with minimal information for analysis"}; + Configurable fConfigMiniTreeMinMass{"useMiniTree.cfgMiniTreeMinMass", 2, "Min. mass cut for minitree"}; + Configurable fConfigMiniTreeMaxMass{"useMiniTree.cfgMiniTreeMaxMass", 5, "Max. mass cut for minitree"}; + } useMiniTree; - Service fCCDB; + Service fCCDB{}; o2::ccdb::CcdbApi fCCDBApi; Filter filterEventSelected = aod::dqanalysisflags::isEventSelected > static_cast(0); - HistogramManager* fHistMan; + HistogramManager* fHistMan = nullptr; MixingHandler fMixingHandler; o2::analysis::DQMlResponse fDQMlResponse; - std::vector fOutputMlPsi2ee = {}; // TODO: check this is needed or not + std::vector fOutputMlPsi2ee; // TODO: check this is needed or not // keep histogram class names in maps, so we don't have to buld their names in the pair loops std::map> fTrackHistNames; @@ -1382,24 +1409,24 @@ struct AnalysisSameEventPairing { std::vector fMuonCuts; std::map, uint32_t> fAmbiguousPairs; - uint32_t fTrackFilterMask; // mask for the track cuts required in this task to be applied on the barrel cuts produced upstream - uint32_t fMuonFilterMask; // mask for the muon cuts required in this task to be applied on the muon cuts produced upstream - int fNCutsBarrel; - int fNCutsMuon; - int fNPairCuts; - int fNPairPerEvent; - - bool fEnableBarrelMixingHistos; - bool fEnableBarrelHistos; - bool fEnableMuonHistos; - bool fEnableMuonMixingHistos; - bool fEnableBarrelMuonHistos; - bool fEnableBarrelMuonMixingHistos; + uint32_t fTrackFilterMask = 0; // mask for the track cuts required in this task to be applied on the barrel cuts produced upstream + uint32_t fMuonFilterMask = 0; // mask for the muon cuts required in this task to be applied on the muon cuts produced upstream + uint32_t fQvectorFilterMask = 0; // mask for the track cuts applied in TPC Q-vector calculation, used to remove auto-correlation in flow analysis + int fNCutsBarrel = 0; + int fNCutsMuon = 0; + int fNPairCuts = 0; + int fNPairPerEvent = 0; + + bool fEnableBarrelMixingHistos = false; + bool fEnableBarrelHistos = false; + bool fEnableMuonHistos = false; + bool fEnableMuonMixingHistos = false; + bool fEnableBarrelMuonHistos = false; + bool fEnableBarrelMuonMixingHistos = false; NoBinningPolicy hashBin; Preslice> trackAssocsPerCollision = aod::reducedtrack_association::reducedeventId; - Preslice> trackEmuAssocsPerCollision = aod::reducedtrack_association::reducedeventId; Preslice> muonAssocsPerCollision = aod::reducedtrack_association::reducedeventId; void init(o2::framework::InitContext& context) @@ -1423,8 +1450,18 @@ struct AnalysisSameEventPairing { // Keep track of all the histogram class names to avoid composing strings in the pairing loop TString histNames = ""; std::vector names; + fTrackHistNames.clear(); + fMuonHistNames.clear(); + fTrackMuonHistNames.clear(); + fPairCuts.clear(); fTrackCuts.clear(); fMuonCuts.clear(); + fTrackFilterMask = 0; + fMuonFilterMask = 0; + fNCutsBarrel = 0; + fNCutsMuon = 0; + fNPairCuts = 0; + fNPairPerEvent = 0; // NOTE: Pair cuts are only applied on the histogram output. The produced pair tables do not have these cuts applied TString cutNamesStr = fConfigCuts.pair.value; @@ -1447,6 +1484,7 @@ struct AnalysisSameEventPairing { if (!muonCutsStr.IsNull()) { objArrayMuonCuts = muonCutsStr.Tokenize(","); } + TString qVectorCutStr = fConfigCuts.qVector.value; if (fConfigML.applyBDT) { // BDT cuts via JSON @@ -1505,7 +1543,7 @@ struct AnalysisSameEventPairing { TString addTrackCutsStr = tempCuts; if (addTrackCutsStr != "") { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); - for (auto& t : addTrackCuts) { + for (auto const& t : addTrackCuts) { tempCutsStr += Form(",%s", t->GetName()); } } @@ -1514,6 +1552,9 @@ struct AnalysisSameEventPairing { fNCutsBarrel = objArray->GetEntries(); for (int icut = 0; icut < objArray->GetEntries(); ++icut) { TString tempStr = objArray->At(icut)->GetName(); + if (tempStr.CompareTo(qVectorCutStr) == 0) { + fQvectorFilterMask |= (static_cast(1) << icut); + } fTrackCuts.push_back(tempStr); if (objArrayTrackCuts->FindObject(tempStr.Data()) != nullptr) { fTrackFilterMask |= (static_cast(1) << icut); @@ -1542,7 +1583,6 @@ struct AnalysisSameEventPairing { } fTrackHistNames[icut] = names; - TString cutNamesStr = fConfigCuts.pair.value; if (!cutNamesStr.IsNull()) { // if pair cuts std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); fNPairCuts = objArrayPair->GetEntries(); @@ -1568,7 +1608,7 @@ struct AnalysisSameEventPairing { TString addMuonCutsStr = tempCuts; if (addMuonCutsStr != "") { std::vector addMuonCuts = dqcuts::GetCutsFromJSON(addMuonCutsStr.Data()); - for (auto& t : addMuonCuts) { + for (auto const& t : addMuonCuts) { tempCutsStr += Form(",%s", t->GetName()); } } @@ -1625,7 +1665,6 @@ struct AnalysisSameEventPairing { } fMuonHistNames[icut] = names; - TString cutNamesStr = fConfigCuts.pair.value; if (!cutNamesStr.IsNull()) { // if pair cuts std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); fNPairCuts = objArrayPair->GetEntries(); @@ -1683,13 +1722,15 @@ struct AnalysisSameEventPairing { if (fEnableBarrelMuonHistos || fEnableBarrelMuonMixingHistos) { for (int iTrack = 0; iTrack < fNCutsBarrel; ++iTrack) { TString trackCutName = fTrackCuts[iTrack]; - if (objArrayTrackCuts->FindObject(trackCutName.Data()) == nullptr) + if (objArrayTrackCuts->FindObject(trackCutName.Data()) == nullptr) { continue; + } for (int iMuon = 0; iMuon < fNCutsMuon; ++iMuon) { TString muonCutName = fMuonCuts[iMuon]; - if (objArrayMuonCuts->FindObject(muonCutName.Data()) == nullptr) + if (objArrayMuonCuts->FindObject(muonCutName.Data()) == nullptr) { continue; + } names = { Form("PairsEleMuSEPM_%s_%s", trackCutName.Data(), muonCutName.Data()), @@ -1706,7 +1747,6 @@ struct AnalysisSameEventPairing { histNames += Form("%s;%s;%s;", names[3].Data(), names[4].Data(), names[5].Data()); } - TString cutNamesStr = fConfigCuts.pair.value; if (!cutNamesStr.IsNull()) { std::unique_ptr objArrayPair(cutNamesStr.Tokenize(",")); int nPairCuts = objArrayPair->GetEntries(); @@ -1733,7 +1773,7 @@ struct AnalysisSameEventPairing { if (fConfigQA) { fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(true); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqtablereader_helpers::varNames(), dqtablereader_helpers::varUnits()); VarManager::SetCollisionSystem((TString)fConfigOptions.collisionSystem, fConfigOptions.centerMassEnergy); // set collision system and center of mass energy DefineHistograms(fHistMan, histNames.Data(), fConfigAddSEPHistogram.value.data()); // define all histograms if (fEnableBarrelHistos) { @@ -1752,7 +1792,7 @@ struct AnalysisSameEventPairing { { if (fConfigOptions.useRemoteField.value) { - o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp(fConfigCCDB.grpMagPath, timestamp); + auto grpmag = fCCDB->getForTimeStamp(fConfigCCDB.grpMagPath, timestamp); float magField = 0.0; if (grpmag != nullptr) { magField = grpmag->getNominalL3Field(); @@ -1789,7 +1829,7 @@ struct AnalysisSameEventPairing { VarManager::SetSORandEOR(sor, eor); if (fConfigOptions.useRemoteCollisionInfo) { - o2::parameters::GRPLHCIFData* grpo = fCCDB->getForTimeStamp(fConfigCCDB.GrpLhcIfPath, timestamp); + auto grpo = fCCDB->getForTimeStamp(fConfigCCDB.GrpLhcIfPath, timestamp); VarManager::SetCollisionSystem(grpo); } @@ -1797,6 +1837,17 @@ struct AnalysisSameEventPairing { auto effList = fCCDB->getForTimeStamp(fConfigCCDB.efficiencyPath.value, timestamp); VarManager::SetEfficiencyObject(fConfigOptions.efficiencyType.value, effList->FindObject("efficiency")); } + + if (fConfigOptions.useFlowReso) { + TString PathFlow = fConfigCCDB.flowPath.value; + TString ccdbPathFlowSP = Form("%s/ScalarProduct", PathFlow.Data()); + TString ccdbPathFlowEP = Form("%s/EventPlane", PathFlow.Data()); + ResoFlowSP = fCCDB->getForTimeStamp(ccdbPathFlowSP.Data(), timestamp); + ResoFlowEP = fCCDB->getForTimeStamp(ccdbPathFlowEP.Data(), timestamp); + if (ResoFlowSP == nullptr || ResoFlowEP == nullptr) { + LOGF(fatal, "Flow resolution histograms not available in CCDB at timestamp=%llu", timestamp); + } + } } // Template function to run same event pairing (barrel-barrel, muon-muon, barrel-muon) @@ -1832,7 +1883,7 @@ struct AnalysisSameEventPairing { histNames = fTrackMuonHistNames; }*/ - uint32_t twoTrackFilter = static_cast(0); + auto twoTrackFilter = static_cast(0); uint32_t dileptonMcDecision = static_cast(0); // placeholder, copy of the dqEfficiency.cxx one int sign1 = 0; int sign2 = 0; @@ -1841,7 +1892,7 @@ struct AnalysisSameEventPairing { // only — pages are not faulted in until written. // estimate reserved size int64_t reserveSize = 0; - for (auto& event : events) { + for (auto const& event : events) { if (event.isEventSelected_bit(0)) { auto groupedAssocs = assocs.sliceBy(preslice, event.globalIndex()); size_t nGood = 0; @@ -1869,21 +1920,26 @@ struct AnalysisSameEventPairing { dileptonFlowList.reserve(reserveSize); if (fConfigOptions.flatTables.value) { dielectronAllList.reserve(reserveSize); + dielectronMlList.reserve(reserveSize); dimuonAllList.reserve(reserveSize); } if (fConfigOptions.polarTables.value) { dileptonPolarList.reserve(reserveSize); dileptonEventInfoList.reserve(reserveSize); } + if (useMiniTree.fConfigMiniTree) { + dileptonMiniTree.reserve(reserveSize); + } fAmbiguousPairs.clear(); constexpr bool eventHasQvector = ((TEventFillMap & VarManager::ObjTypes::ReducedEventQvector) > 0); constexpr bool eventHasQvectorCentr = ((TEventFillMap & VarManager::ObjTypes::CollisionQvect) > 0); constexpr bool trackHasCov = ((TTrackFillMap & VarManager::ObjTypes::TrackCov) > 0 || (TTrackFillMap & VarManager::ObjTypes::ReducedTrackBarrelCov) > 0); + // constexpr bool fillFlowReso = eventHasQvector || eventHasQvectorCentr; bool isSelectedBDT = false; fNPairPerEvent = 0; - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } @@ -1893,16 +1949,23 @@ struct AnalysisSameEventPairing { uint8_t evSel = event.isEventSelected_raw(); // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); - // VarManager::FillEvent(event, VarManager::fgValues); - VarManager::FillEvent(event, VarManager::fgValues); + // VarManager::FillEvent(event, dqtablereader_helpers::varValues()); + VarManager::FillEvent(event, dqtablereader_helpers::varValues()); auto groupedAssocs = assocs.sliceBy(preslice, event.globalIndex()); if (groupedAssocs.size() == 0) { continue; } + if (fConfigOptions.useFlowReso) { + if (ResoFlowSP == nullptr || ResoFlowEP == nullptr) { + LOGF(fatal, "Flow resolution histograms are not available, cannot fill flow variables!"); + } + VarManager::FillEventFlowResoFactor(ResoFlowSP, ResoFlowEP); + } + bool isFirst = true; - for (auto& [a1, a2] : o2::soa::combinations(groupedAssocs, groupedAssocs)) { + for (auto const& [a1, a2] : o2::soa::combinations(groupedAssocs, groupedAssocs)) { if constexpr (TPairType == VarManager::kDecayToEE) { twoTrackFilter = a1.isBarrelSelected_raw() & a2.isBarrelSelected_raw() & a1.isBarrelSelectedPrefilter_raw() & a2.isBarrelSelectedPrefilter_raw() & fTrackFilterMask; @@ -1930,6 +1993,20 @@ struct AnalysisSameEventPairing { } fNPairPerEvent++; + + // check if t1 or t2 is used in TPC Q vector calculation, so as to remove auto correlations in the flow analysis + VarManager::fgValues[VarManager::kSel1] = -9999.; + VarManager::fgValues[VarManager::kSel2] = -9999.; + if (t1.reducedeventId() == event.globalIndex()) { + if ((a1.isBarrelSelected_raw() & fQvectorFilterMask) > 0) { + VarManager::fgValues[VarManager::kSel1] = 1.; + } + } + if (t2.reducedeventId() == event.globalIndex()) { + if ((a2.isBarrelSelected_raw() & fQvectorFilterMask) > 0) { + VarManager::fgValues[VarManager::kSel2] = 1.; + } + } VarManager::FillPair(t1, t2); // compute quantities which depend on the associated collision, such as DCA if (fConfigOptions.propTrack) { @@ -1967,55 +2044,62 @@ struct AnalysisSameEventPairing { } if constexpr (trackHasCov && TTwoProngFitter) { dielectronsExtraList(t1.globalIndex(), t2.globalIndex(), VarManager::fgValues[VarManager::kVertexingTauzProjected], VarManager::fgValues[VarManager::kVertexingLzProjected], VarManager::fgValues[VarManager::kVertexingLxyProjected]); - if constexpr ((TTrackFillMap & VarManager::ObjTypes::ReducedTrackBarrelPID) > 0) { - if (fConfigML.applyBDT) { - std::vector dqInputFeatures = fDQMlResponse.getInputFeatures(t1, t2, VarManager::fgValues); - - if (dqInputFeatures.empty()) { - LOG(fatal) << "Input features for ML selection are empty! Please check your configuration."; - return; - } - - int modelIndex = -1; - const auto& binsCent = fDQMlResponse.getBinsCent(); - const auto& binsPt = fDQMlResponse.getBinsPt(); - const std::string& centType = fDQMlResponse.getCentType(); - - if ("kCentFT0C" == centType) { - modelIndex = o2::aod::dqmlcuts::getMlBinIndex(VarManager::fgValues[VarManager::kCentFT0C], VarManager::fgValues[VarManager::kPt], binsCent, binsPt); - } else if ("kCentFT0A" == centType) { - modelIndex = o2::aod::dqmlcuts::getMlBinIndex(VarManager::fgValues[VarManager::kCentFT0A], VarManager::fgValues[VarManager::kPt], binsCent, binsPt); - } else if ("kCentFT0M" == centType) { - modelIndex = o2::aod::dqmlcuts::getMlBinIndex(VarManager::fgValues[VarManager::kCentFT0M], VarManager::fgValues[VarManager::kPt], binsCent, binsPt); - } else { - LOG(fatal) << "Unknown centrality estimation type: " << centType; - return; - } - - if (modelIndex < 0) { - LOG(info) << "Ml index is negative! This means that the centrality/pt is not in the range of the model bins."; - continue; - } + } + if constexpr ((TTrackFillMap & VarManager::ObjTypes::ReducedTrackBarrelPID) > 0) { + isSelectedBDT = false; + fOutputMlPsi2ee.clear(); + if (fConfigML.applyBDT) { + std::vector dqInputFeatures = fDQMlResponse.getInputFeatures(t1, t2, dqtablereader_helpers::varValues()); + + if (dqInputFeatures.empty()) { + LOG(fatal) << "Input features for ML selection are empty! Please check your configuration."; + return; + } - LOG(debug) << "Model index: " << modelIndex << ", pT: " << VarManager::fgValues[VarManager::kPt] << ", centrality (kCentFT0C): " << VarManager::fgValues[VarManager::kCentFT0C]; - isSelectedBDT = fDQMlResponse.isSelectedMl(dqInputFeatures, modelIndex, fOutputMlPsi2ee); - VarManager::FillBdtScore(fOutputMlPsi2ee); // TODO: check if this is needed or not + int modelIndex = -1; + const auto& binsCent = fDQMlResponse.getBinsCent(); + const auto& binsPt = fDQMlResponse.getBinsPt(); + const std::string& centType = fDQMlResponse.getCentType(); + + if ("kCentFT0C" == centType) { + modelIndex = o2::aod::dqmlcuts::getMlBinIndex(VarManager::fgValues[VarManager::kCentFT0C], VarManager::fgValues[VarManager::kPt], binsCent, binsPt); + } else if ("kCentFT0A" == centType) { + modelIndex = o2::aod::dqmlcuts::getMlBinIndex(VarManager::fgValues[VarManager::kCentFT0A], VarManager::fgValues[VarManager::kPt], binsCent, binsPt); + } else if ("kCentFT0M" == centType) { + modelIndex = o2::aod::dqmlcuts::getMlBinIndex(VarManager::fgValues[VarManager::kCentFT0M], VarManager::fgValues[VarManager::kPt], binsCent, binsPt); + } else { + LOG(fatal) << "Unknown centrality estimation type: " << centType; + return; } - if (fConfigML.applyBDT && !isSelectedBDT) + if (modelIndex < 0) { + LOG(debug) << "Ml index is negative! This means that the centrality/pt is not in the range of the model bins."; continue; - - if (fConfigOptions.flatTables.value) { - dielectronAllList(VarManager::fgValues[VarManager::kMass], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], t1.sign() + t2.sign(), twoTrackFilter, dileptonMcDecision, - t1.pt(), t1.eta(), t1.phi(), t1.itsClusterMap(), t1.itsChi2NCl(), t1.tpcNClsCrossedRows(), t1.tpcNClsFound(), t1.tpcChi2NCl(), t1.dcaXY(), t1.dcaZ(), t1.tpcSignal(), t1.tpcNSigmaEl(), t1.tpcNSigmaPi(), t1.tpcNSigmaPr(), t1.beta(), t1.tofNSigmaEl(), t1.tofNSigmaPi(), t1.tofNSigmaPr(), - t2.pt(), t2.eta(), t2.phi(), t2.itsClusterMap(), t2.itsChi2NCl(), t2.tpcNClsCrossedRows(), t2.tpcNClsFound(), t2.tpcChi2NCl(), t2.dcaXY(), t2.dcaZ(), t2.tpcSignal(), t2.tpcNSigmaEl(), t2.tpcNSigmaPi(), t2.tpcNSigmaPr(), t2.beta(), t2.tofNSigmaEl(), t2.tofNSigmaPi(), t2.tofNSigmaPr(), - VarManager::fgValues[VarManager::kKFTrack0DCAxyz], VarManager::fgValues[VarManager::kKFTrack1DCAxyz], VarManager::fgValues[VarManager::kKFDCAxyzBetweenProngs], VarManager::fgValues[VarManager::kKFTrack0DCAxy], VarManager::fgValues[VarManager::kKFTrack1DCAxy], VarManager::fgValues[VarManager::kKFDCAxyBetweenProngs], - VarManager::fgValues[VarManager::kKFTrack0DeviationFromPV], VarManager::fgValues[VarManager::kKFTrack1DeviationFromPV], VarManager::fgValues[VarManager::kKFTrack0DeviationxyFromPV], VarManager::fgValues[VarManager::kKFTrack1DeviationxyFromPV], - VarManager::fgValues[VarManager::kKFMass], VarManager::fgValues[VarManager::kKFChi2OverNDFGeo], VarManager::fgValues[VarManager::kVertexingLxyz], VarManager::fgValues[VarManager::kVertexingLxyzOverErr], VarManager::fgValues[VarManager::kVertexingLxy], VarManager::fgValues[VarManager::kVertexingLxyOverErr], VarManager::fgValues[VarManager::kVertexingTauxy], VarManager::fgValues[VarManager::kVertexingTauxyErr], VarManager::fgValues[VarManager::kKFCosPA], VarManager::fgValues[VarManager::kKFJpsiDCAxyz], VarManager::fgValues[VarManager::kKFJpsiDCAxy], - VarManager::fgValues[VarManager::kKFPairDeviationFromPV], VarManager::fgValues[VarManager::kKFPairDeviationxyFromPV], - VarManager::fgValues[VarManager::kKFMassGeoTop], - VarManager::fgValues[VarManager::kKFChi2OverNDFGeoTop], VarManager::fgValues[VarManager::kVertexingTauzProjected], VarManager::fgValues[VarManager::kVertexingTauxyProjected], VarManager::fgValues[VarManager::kVertexingLzProjected], VarManager::fgValues[VarManager::kVertexingLxyProjected]); } + + LOG(debug) << "Model index: " << modelIndex << ", pT: " << VarManager::fgValues[VarManager::kPt] << ", centrality (kCentFT0C): " << VarManager::fgValues[VarManager::kCentFT0C]; + isSelectedBDT = fDQMlResponse.isSelectedMl(dqInputFeatures, modelIndex, fOutputMlPsi2ee); + VarManager::FillBdtScore(fOutputMlPsi2ee); + } + + if (fConfigML.applyBDT && !isSelectedBDT) { + continue; + } + + if (fConfigOptions.flatTables.value) { + dielectronAllList(VarManager::fgValues[VarManager::kMass], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], t1.sign() + t2.sign(), twoTrackFilter, dileptonMcDecision, + t1.pt(), t1.eta(), t1.phi(), t1.itsClusterMap(), t1.itsChi2NCl(), t1.tpcNClsCrossedRows(), t1.tpcNClsFound(), t1.tpcChi2NCl(), t1.dcaXY(), t1.dcaZ(), t1.tpcSignal(), t1.tpcNSigmaEl(), t1.tpcNSigmaPi(), t1.tpcNSigmaPr(), t1.beta(), t1.tofNSigmaEl(), t1.tofNSigmaPi(), t1.tofNSigmaPr(), + t2.pt(), t2.eta(), t2.phi(), t2.itsClusterMap(), t2.itsChi2NCl(), t2.tpcNClsCrossedRows(), t2.tpcNClsFound(), t2.tpcChi2NCl(), t2.dcaXY(), t2.dcaZ(), t2.tpcSignal(), t2.tpcNSigmaEl(), t2.tpcNSigmaPi(), t2.tpcNSigmaPr(), t2.beta(), t2.tofNSigmaEl(), t2.tofNSigmaPi(), t2.tofNSigmaPr(), + VarManager::fgValues[VarManager::kKFTrack0DCAxyz], VarManager::fgValues[VarManager::kKFTrack1DCAxyz], VarManager::fgValues[VarManager::kKFDCAxyzBetweenProngs], VarManager::fgValues[VarManager::kKFTrack0DCAxy], VarManager::fgValues[VarManager::kKFTrack1DCAxy], VarManager::fgValues[VarManager::kKFDCAxyBetweenProngs], + VarManager::fgValues[VarManager::kKFTrack0DeviationFromPV], VarManager::fgValues[VarManager::kKFTrack1DeviationFromPV], VarManager::fgValues[VarManager::kKFTrack0DeviationxyFromPV], VarManager::fgValues[VarManager::kKFTrack1DeviationxyFromPV], + VarManager::fgValues[VarManager::kKFMass], VarManager::fgValues[VarManager::kKFChi2OverNDFGeo], VarManager::fgValues[VarManager::kVertexingLxyz], VarManager::fgValues[VarManager::kVertexingLxyzOverErr], VarManager::fgValues[VarManager::kVertexingLxy], VarManager::fgValues[VarManager::kVertexingLxyOverErr], VarManager::fgValues[VarManager::kVertexingTauxy], VarManager::fgValues[VarManager::kVertexingTauxyErr], VarManager::fgValues[VarManager::kKFCosPA], VarManager::fgValues[VarManager::kKFJpsiDCAxyz], VarManager::fgValues[VarManager::kKFJpsiDCAxy], + VarManager::fgValues[VarManager::kKFPairDeviationFromPV], VarManager::fgValues[VarManager::kKFPairDeviationxyFromPV], + VarManager::fgValues[VarManager::kKFMassGeoTop], + VarManager::fgValues[VarManager::kKFChi2OverNDFGeoTop], VarManager::fgValues[VarManager::kVertexingTauzProjected], VarManager::fgValues[VarManager::kVertexingTauxyProjected], VarManager::fgValues[VarManager::kVertexingLzProjected], VarManager::fgValues[VarManager::kVertexingLxyProjected]); + dielectronMlList(VarManager::fgValues[VarManager::kCentFT0C], + (fConfigML.applyBDT && !fOutputMlPsi2ee.empty()) ? VarManager::fgValues[VarManager::kBdtBackground] : -999.f, + (fConfigML.applyBDT && fOutputMlPsi2ee.size() > 1) ? VarManager::fgValues[VarManager::kBdtPrompt] : -999.f, + (fConfigML.applyBDT && fOutputMlPsi2ee.size() > 2) ? VarManager::fgValues[VarManager::kBdtNonprompt] : -999.f); } } } @@ -2028,10 +2112,12 @@ struct AnalysisSameEventPairing { auto t1 = a1.template reducedmuon_as(); auto t2 = a2.template reducedmuon_as(); - if (t1.matchMCHTrackId() == t2.matchMCHTrackId() && t1.matchMCHTrackId() >= 0) + if (t1.matchMCHTrackId() == t2.matchMCHTrackId() && t1.matchMCHTrackId() >= 0) { continue; - if (t1.matchMFTTrackId() == t2.matchMFTTrackId() && t1.matchMFTTrackId() >= 0) + } + if (t1.matchMFTTrackId() == t2.matchMFTTrackId() && t1.matchMFTTrackId() >= 0) { continue; + } sign1 = t1.sign(); sign2 = t2.sign(); // store the ambiguity number of the two dilepton legs in the last 4 digits of the two-track filter @@ -2102,7 +2188,7 @@ struct AnalysisSameEventPairing { VarManager::fgValues[VarManager::kVertexingPz], VarManager::fgValues[VarManager::kVertexingSV]); } if constexpr ((TTrackFillMap & VarManager::ObjTypes::ReducedMuonCollInfo) > 0) { - if constexpr (eventHasQvector == true || eventHasQvectorCentr == true) { + if constexpr (eventHasQvector || eventHasQvectorCentr) { dileptonFlowList(t1.collisionId(), VarManager::fgValues[VarManager::kMass], VarManager::fgValues[VarManager::kCentFT0C], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], t1.sign() + t2.sign(), isFirst, VarManager::fgValues[VarManager::kU2Q2], VarManager::fgValues[VarManager::kR2SP_AB], VarManager::fgValues[VarManager::kR2SP_AC], VarManager::fgValues[VarManager::kR2SP_BC], @@ -2132,8 +2218,9 @@ struct AnalysisSameEventPairing { bool isLeg2Ambi = false; bool isAmbiExtra = false; - if (fConfigML.applyBDT && !isSelectedBDT) + if (fConfigML.applyBDT && !isSelectedBDT) { continue; + } for (int icut = 0; icut < ncuts; icut++) { if (twoTrackFilter & (static_cast(1) << icut)) { @@ -2145,7 +2232,7 @@ struct AnalysisSameEventPairing { if constexpr (TPairType == VarManager::kDecayToEE) { if (isLeg1Ambi && isLeg2Ambi) { std::pair iPair(a1.reducedtrackId(), a2.reducedtrackId()); - if (fAmbiguousPairs.find(iPair) != fAmbiguousPairs.end()) { + if (fAmbiguousPairs.contains(iPair)) { if (fAmbiguousPairs[iPair] & (static_cast(1) << icut)) { // if this pair is already stored with this cut isAmbiExtra = true; } else { @@ -2162,81 +2249,101 @@ struct AnalysisSameEventPairing { VarManager::fgValues[VarManager::kVtxX], VarManager::fgValues[VarManager::kVtxY], VarManager::fgValues[VarManager::kVtxZ], VarManager::fgValues[VarManager::kDCAxy1], VarManager::fgValues[VarManager::kDCAz1], VarManager::fgValues[VarManager::kITSclusterMap1], VarManager::fgValues[VarManager::kTPCnSigmaEl1], VarManager::fgValues[VarManager::kDCAxy2], VarManager::fgValues[VarManager::kDCAz2], VarManager::fgValues[VarManager::kITSclusterMap2], VarManager::fgValues[VarManager::kTPCnSigmaEl2], isAmbiInBunch, isAmbiOutOfBunch, VarManager::fgValues[VarManager::kMultFT0A], VarManager::fgValues[VarManager::kMultFT0C], VarManager::fgValues[VarManager::kCentFT0M], VarManager::fgValues[VarManager::kVtxNcontribReal]); if constexpr (TPairType == VarManager::kDecayToMuMu) { - fHistMan->FillHistClass(histNames[icut][0].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][0].Data(), dqtablereader_helpers::varValues()); + if (useMiniTree.fConfigMiniTree) { + auto t1 = a1.template reducedmuon_as(); + auto t2 = a2.template reducedmuon_as(); + + // By default (kPt1, kEta1, kPhi1) are for the positive charge + float dileptonMass = VarManager::fgValues[VarManager::kMass]; + if (dileptonMass > useMiniTree.fConfigMiniTreeMinMass && dileptonMass < useMiniTree.fConfigMiniTreeMaxMass) { + // In the miniTree the positive daughter is positioned as first + if (t1.sign() > 0) { + dileptonMiniTree(VarManager::fgValues[VarManager::kMass], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kRap], + VarManager::fgValues[VarManager::kCentFT0C], VarManager::fgValues[VarManager::kCos2DeltaPhi], + t1.pt(), t1.eta(), t1.phi(), t2.pt(), t2.eta(), t2.phi()); + } else { + dileptonMiniTree(VarManager::fgValues[VarManager::kMass], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kRap], + VarManager::fgValues[VarManager::kCentFT0C], VarManager::fgValues[VarManager::kCos2DeltaPhi], + t2.pt(), t2.eta(), t2.phi(), t1.pt(), t1.eta(), t1.phi()); + } + } + } if (fConfigAmbiguousMuonHistograms) { if (isAmbiInBunch) { - fHistMan->FillHistClass(histNames[icut][3 + histIdxOffset].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][3 + histIdxOffset].Data(), dqtablereader_helpers::varValues()); } if (isAmbiOutOfBunch) { - fHistMan->FillHistClass(histNames[icut][3 + histIdxOffset + 3].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][3 + histIdxOffset + 3].Data(), dqtablereader_helpers::varValues()); } if (isUnambiguous) { - fHistMan->FillHistClass(histNames[icut][3 + histIdxOffset + 6].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][3 + histIdxOffset + 6].Data(), dqtablereader_helpers::varValues()); } } } if constexpr (TPairType == VarManager::kDecayToEE) { - fHistMan->FillHistClass(histNames[icut][0].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][0].Data(), dqtablereader_helpers::varValues()); if (isAmbiExtra) { - fHistMan->FillHistClass(histNames[icut][3].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][3].Data(), dqtablereader_helpers::varValues()); } } } else { if (sign1 > 0) { if constexpr (TPairType == VarManager::kDecayToMuMu) { - fHistMan->FillHistClass(histNames[icut][1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][1].Data(), dqtablereader_helpers::varValues()); if (fConfigAmbiguousMuonHistograms) { if (isAmbiInBunch) { - fHistMan->FillHistClass(histNames[icut][4 + histIdxOffset].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][4 + histIdxOffset].Data(), dqtablereader_helpers::varValues()); } if (isAmbiOutOfBunch) { - fHistMan->FillHistClass(histNames[icut][4 + histIdxOffset + 3].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][4 + histIdxOffset + 3].Data(), dqtablereader_helpers::varValues()); } if (isUnambiguous) { - fHistMan->FillHistClass(histNames[icut][4 + histIdxOffset + 6].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][4 + histIdxOffset + 6].Data(), dqtablereader_helpers::varValues()); } } } if constexpr (TPairType == VarManager::kDecayToEE) { - fHistMan->FillHistClass(histNames[icut][1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][1].Data(), dqtablereader_helpers::varValues()); if (isAmbiExtra) { - fHistMan->FillHistClass(histNames[icut][4].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][4].Data(), dqtablereader_helpers::varValues()); } } } else { if constexpr (TPairType == VarManager::kDecayToMuMu) { - fHistMan->FillHistClass(histNames[icut][2].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][2].Data(), dqtablereader_helpers::varValues()); if (fConfigAmbiguousMuonHistograms) { if (isAmbiInBunch) { - fHistMan->FillHistClass(histNames[icut][5 + histIdxOffset].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][5 + histIdxOffset].Data(), dqtablereader_helpers::varValues()); } if (isAmbiOutOfBunch) { - fHistMan->FillHistClass(histNames[icut][5 + histIdxOffset + 3].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][5 + histIdxOffset + 3].Data(), dqtablereader_helpers::varValues()); } if (isUnambiguous) { - fHistMan->FillHistClass(histNames[icut][5 + histIdxOffset + 6].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][5 + histIdxOffset + 6].Data(), dqtablereader_helpers::varValues()); } } } if constexpr (TPairType == VarManager::kDecayToEE) { - fHistMan->FillHistClass(histNames[icut][2].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][2].Data(), dqtablereader_helpers::varValues()); if (isAmbiExtra) { - fHistMan->FillHistClass(histNames[icut][5].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][5].Data(), dqtablereader_helpers::varValues()); } } } } for (unsigned int iPairCut = 0; iPairCut < fPairCuts.size(); iPairCut++) { AnalysisCompositeCut cut = fPairCuts.at(iPairCut); - if (!(cut.IsSelected(VarManager::fgValues))) // apply pair cuts + if (!(cut.IsSelected(dqtablereader_helpers::varValues()))) { // apply pair cuts continue; + } if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(histNames[ncuts + icut * ncuts + iPairCut][0].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[ncuts + icut * ncuts + iPairCut][0].Data(), dqtablereader_helpers::varValues()); } else { if (sign1 > 0) { - fHistMan->FillHistClass(histNames[ncuts + icut * ncuts + iPairCut][1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[ncuts + icut * ncuts + iPairCut][1].Data(), dqtablereader_helpers::varValues()); } else { - fHistMan->FillHistClass(histNames[ncuts + icut * ncuts + iPairCut][2].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[ncuts + icut * ncuts + iPairCut][2].Data(), dqtablereader_helpers::varValues()); } } } // end loop (pair cuts) @@ -2280,7 +2387,7 @@ struct AnalysisSameEventPairing { if constexpr (TPairType == VarManager::kDecayToEE) { if (isLeg1Ambi && isLeg2Ambi) { std::pair iPair(a1.reducedtrackId(), a2.reducedtrackId()); - if (fAmbiguousPairs.find(iPair) != fAmbiguousPairs.end()) { + if (fAmbiguousPairs.contains(iPair)) { if (fAmbiguousPairs[iPair] & (static_cast(1) << icut)) { // if this pair is already stored with this cut isAmbiExtra = true; } else { @@ -2295,9 +2402,9 @@ struct AnalysisSameEventPairing { for (int i = 0; i < fConfigNRotations.value; i++) { VarManager::FillPairRotation(t1, t2); if constexpr (TPairType == VarManager::kDecayToEE) { - fHistMan->FillHistClass(Form("PairsBarrelTRPM_%s", fTrackCuts[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelTRPM_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues()); if (isAmbiExtra) { - fHistMan->FillHistClass(Form("PairsBarrelTRPM_ambiguousextra_%s", fTrackCuts[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelTRPM_ambiguousextra_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues()); } } } @@ -2310,7 +2417,7 @@ struct AnalysisSameEventPairing { } // end loop over pairs of track associations VarManager::fgValues[VarManager::kNPairsPerEvent] = fNPairPerEvent; if (fEnableBarrelHistos && fConfigQA) { - fHistMan->FillHistClass("PairingSEQA", VarManager::fgValues); + fHistMan->FillHistClass("PairingSEQA", dqtablereader_helpers::varValues()); } if (fConfigRunMixingAcrossTFs) { @@ -2318,7 +2425,7 @@ struct AnalysisSameEventPairing { // 1) create a MixingEvent and fill it with the relevant tracks MixingHandler::MixingEvent mixingEvent; uint32_t trackFilterForMixing = 0; - for (auto& assoc : groupedAssocs) { + for (auto const& assoc : groupedAssocs) { if constexpr (TPairType == VarManager::kDecayToEE) { trackFilterForMixing = assoc.isBarrelSelected_raw() & assoc.isBarrelSelectedPrefilter_raw() & fTrackFilterMask; if (!trackFilterForMixing) { @@ -2334,11 +2441,11 @@ struct AnalysisSameEventPairing { } } // 2) run the mixing with the events in the pool corresponding to this event - auto& pool = fMixingHandler.GetPool(fMixingHandler.FindEventCategory(VarManager::fgValues)); - for (auto& poolEvent : pool.GetEvents()) { - for (auto& t1 : mixingEvent.tracks1) { + auto& pool = fMixingHandler.GetPool(fMixingHandler.FindEventCategory(dqtablereader_helpers::varValues())); + for (auto const& poolEvent : pool.GetEvents()) { + for (auto const& t1 : mixingEvent.tracks1) { // run +- pairing - for (auto& t2 : poolEvent.tracks2) { + for (auto const& t2 : poolEvent.tracks2) { // check the two-track filter for the mixed pair uint32_t mixedTwoTrackFilter = t1.filteringFlags & t2.filteringFlags; if (!mixedTwoTrackFilter) { @@ -2347,12 +2454,12 @@ struct AnalysisSameEventPairing { VarManager::FillPairMEAcrossTFs(t1, t2); for (int icut = 0; icut < ncuts; icut++) { if (mixedTwoTrackFilter & (static_cast(1) << icut)) { - fHistMan->FillHistClass(Form("PairsBarrelMEPM_%s", fTrackCuts[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelMEPM_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues()); } } } // run ++ pairing - for (auto& t2 : poolEvent.tracks1) { + for (auto const& t2 : poolEvent.tracks1) { // check the two-track filter for the mixed pair uint32_t mixedTwoTrackFilter = t1.filteringFlags & t2.filteringFlags; if (!mixedTwoTrackFilter) { @@ -2361,14 +2468,14 @@ struct AnalysisSameEventPairing { VarManager::FillPairMEAcrossTFs(t1, t2); for (int icut = 0; icut < ncuts; icut++) { if (mixedTwoTrackFilter & (static_cast(1) << icut)) { - fHistMan->FillHistClass(Form("PairsBarrelMEPP_%s", fTrackCuts[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelMEPP_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues()); } } } } - for (auto& t1 : mixingEvent.tracks2) { + for (auto const& t1 : mixingEvent.tracks2) { // run -+ pairing - for (auto& t2 : poolEvent.tracks1) { + for (auto const& t2 : poolEvent.tracks1) { // check the two-track filter for the mixed pair uint32_t mixedTwoTrackFilter = t1.filteringFlags & t2.filteringFlags; if (!mixedTwoTrackFilter) { @@ -2377,12 +2484,12 @@ struct AnalysisSameEventPairing { VarManager::FillPairMEAcrossTFs(t1, t2); for (int icut = 0; icut < ncuts; icut++) { if (mixedTwoTrackFilter & (static_cast(1) << icut)) { - fHistMan->FillHistClass(Form("PairsBarrelMEPM_%s", fTrackCuts[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelMEPM_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues()); } } } // run -- pairing - for (auto& t2 : poolEvent.tracks2) { + for (auto const& t2 : poolEvent.tracks2) { // check the two-track filter for the mixed pair uint32_t mixedTwoTrackFilter = t1.filteringFlags & t2.filteringFlags; if (!mixedTwoTrackFilter) { @@ -2391,7 +2498,7 @@ struct AnalysisSameEventPairing { VarManager::FillPairMEAcrossTFs(t1, t2); for (int icut = 0; icut < ncuts; icut++) { if (mixedTwoTrackFilter & (static_cast(1) << icut)) { - fHistMan->FillHistClass(Form("PairsBarrelMEMM_%s", fTrackCuts[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelMEMM_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues()); } } } @@ -2410,9 +2517,9 @@ struct AnalysisSameEventPairing { std::map> histNames = fTrackHistNames; int pairSign = 0; int ncuts = 0; - uint32_t twoTrackFilter = static_cast(0); - for (auto& a1 : assocs1) { - for (auto& a2 : assocs2) { + auto twoTrackFilter = static_cast(0); + for (auto const& a1 : assocs1) { + for (auto const& a2 : assocs2) { if constexpr (TPairType == VarManager::kDecayToEE) { twoTrackFilter = a1.isBarrelSelected_raw() & a2.isBarrelSelected_raw() & a1.isBarrelSelectedPrefilter_raw() & a2.isBarrelSelectedPrefilter_raw() & fTrackFilterMask; if (!twoTrackFilter) { // the tracks must have at least one filter bit in common to continue @@ -2438,10 +2545,12 @@ struct AnalysisSameEventPairing { } auto t1 = a1.template reducedmuon_as(); auto t2 = a2.template reducedmuon_as(); - if (t1.matchMCHTrackId() == t2.matchMCHTrackId() && t1.matchMCHTrackId() >= 0) + if (t1.matchMCHTrackId() == t2.matchMCHTrackId() && t1.matchMCHTrackId() >= 0) { continue; - if (t1.matchMFTTrackId() == t2.matchMFTTrackId() && t1.matchMCHTrackId() >= 0) + } + if (t1.matchMFTTrackId() == t2.matchMFTTrackId() && t1.matchMCHTrackId() >= 0) { continue; + } VarManager::FillPairME(t1, t2); if constexpr ((TEventFillMap & VarManager::ObjTypes::ReducedEventQvector) > 0) { VarManager::FillPairVn(t1, t2); @@ -2512,58 +2621,58 @@ struct AnalysisSameEventPairing { isUnambiguous = !((twoTrackFilter & (static_cast(1) << 28)) || (twoTrackFilter & (static_cast(1) << 29)) || (twoTrackFilter & (static_cast(1) << 30)) || (twoTrackFilter & (static_cast(1) << 31))); if (pairSign == 0) { if constexpr (TPairType == VarManager::kDecayToMuMu) { - fHistMan->FillHistClass(histNames[icut][3].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][3].Data(), dqtablereader_helpers::varValues()); if (fConfigAmbiguousMuonHistograms) { if (isAmbiInBunch) { - fHistMan->FillHistClass(histNames[icut][15].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][15].Data(), dqtablereader_helpers::varValues()); } if (isAmbiOutOfBunch) { - fHistMan->FillHistClass(histNames[icut][18].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][18].Data(), dqtablereader_helpers::varValues()); } if (isUnambiguous) { - fHistMan->FillHistClass(histNames[icut][21].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][21].Data(), dqtablereader_helpers::varValues()); } } } if constexpr (TPairType == VarManager::kDecayToEE) { - fHistMan->FillHistClass(Form("PairsBarrelMEPM_%s", fTrackCuts[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelMEPM_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues()); } } else { if (pairSign > 0) { if constexpr (TPairType == VarManager::kDecayToMuMu) { - fHistMan->FillHistClass(histNames[icut][4].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][4].Data(), dqtablereader_helpers::varValues()); if (fConfigAmbiguousMuonHistograms) { if (isAmbiInBunch) { - fHistMan->FillHistClass(histNames[icut][16].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][16].Data(), dqtablereader_helpers::varValues()); } if (isAmbiOutOfBunch) { - fHistMan->FillHistClass(histNames[icut][19].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][19].Data(), dqtablereader_helpers::varValues()); } if (isUnambiguous) { - fHistMan->FillHistClass(histNames[icut][22].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][22].Data(), dqtablereader_helpers::varValues()); } } } if constexpr (TPairType == VarManager::kDecayToEE) { - fHistMan->FillHistClass(Form("PairsBarrelMEPP_%s", fTrackCuts[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelMEPP_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues()); } } else { if constexpr (TPairType == VarManager::kDecayToMuMu) { - fHistMan->FillHistClass(histNames[icut][5].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][5].Data(), dqtablereader_helpers::varValues()); if (fConfigAmbiguousMuonHistograms) { if (isAmbiInBunch) { - fHistMan->FillHistClass(histNames[icut][17].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][17].Data(), dqtablereader_helpers::varValues()); } if (isAmbiOutOfBunch) { - fHistMan->FillHistClass(histNames[icut][20].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][20].Data(), dqtablereader_helpers::varValues()); } if (isUnambiguous) { - fHistMan->FillHistClass(histNames[icut][23].Data(), VarManager::fgValues); + fHistMan->FillHistClass(histNames[icut][23].Data(), dqtablereader_helpers::varValues()); } } } if constexpr (TPairType == VarManager::kDecayToEE) { - fHistMan->FillHistClass(Form("PairsBarrelMEMM_%s", fTrackCuts[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelMEMM_%s", fTrackCuts[icut].Data()), dqtablereader_helpers::varValues()); } } } @@ -2576,12 +2685,18 @@ struct AnalysisSameEventPairing { template void runSameSideMixing(TEvents& events, TAssocs const& assocs, TTracks const& tracks, Preslice& preSlice) { + if (ResoFlowSP == nullptr || ResoFlowEP == nullptr) { + LOG(info) << "Flow resolution objects not set, flow will not be filled for mixed events"; + if (events.size() > 0) { + initParamsFromCCDB(events.begin().timestamp(), events.begin().runNumber(), false); + } + } events.bindExternalIndices(&assocs); int mixingDepth = fConfigMixingDepth.value; fAmbiguousPairs.clear(); - for (auto& [event1, event2] : selfCombinations(hashBin, mixingDepth, -1, events, events)) { + for (auto const& [event1, event2] : selfCombinations(hashBin, mixingDepth, -1, events, events)) { VarManager::ResetValues(0, VarManager::kNVars); - VarManager::FillEvent(event1, VarManager::fgValues); + VarManager::FillEvent(event1, dqtablereader_helpers::varValues()); auto assocs1 = assocs.sliceBy(preSlice, event1.globalIndex()); assocs1.bindExternalIndices(&events); @@ -2590,10 +2705,14 @@ struct AnalysisSameEventPairing { assocs2.bindExternalIndices(&events); fNPairPerEvent = 0; + VarManager::FillTwoMixEvents(event1, event2, assocs1, assocs2); + if (fConfigOptions.useFlowReso) { + VarManager::FillTwoMixEventsFlowResoFactor(ResoFlowSP, ResoFlowEP); + } runMixedPairing(assocs1, assocs2, tracks, tracks); VarManager::fgValues[VarManager::kNPairsPerEvent] = fNPairPerEvent; if (fEnableBarrelMixingHistos && fConfigQA) { - fHistMan->FillHistClass("PairingMEQA", VarManager::fgValues); + fHistMan->FillHistClass("PairingMEQA", dqtablereader_helpers::varValues()); } } // end event loop } @@ -2609,7 +2728,7 @@ struct AnalysisSameEventPairing { } const auto& histNames = fTrackMuonHistNames; - int nPairCuts = (fPairCuts.size() > 0) ? fPairCuts.size() : 1; + int nPairCuts = !fPairCuts.empty() ? static_cast(fPairCuts.size()) : 1; electronmuonList.reserve(assocs1.size()); @@ -2620,29 +2739,34 @@ struct AnalysisSameEventPairing { constexpr bool eventHasQvector = ((TEventFillMap & VarManager::ObjTypes::ReducedEventQvector) > 0); constexpr bool eventHasQvectorCentr = ((TEventFillMap & VarManager::ObjTypes::CollisionQvect) > 0); - for (auto& event : events) { - if (!event.isEventSelected_bit(0)) + for (auto const& event : events) { + if (!event.isEventSelected_bit(0)) { continue; - if (fConfigCuts.event && event.isEventSelected_bit(2)) + } + if (fConfigCuts.event && event.isEventSelected_bit(2)) { continue; + } VarManager::ResetValues(0, VarManager::kNVars); - VarManager::FillEvent(event, VarManager::fgValues); + VarManager::FillEvent(event, dqtablereader_helpers::varValues()); auto groupedAssocs1 = assocs1.sliceBy(preslice1, event.globalIndex()); - if (groupedAssocs1.size() == 0) + if (groupedAssocs1.size() == 0) { continue; + } auto groupedAssocs2 = assocs2.sliceBy(preslice2, event.globalIndex()); - if (groupedAssocs2.size() == 0) + if (groupedAssocs2.size() == 0) { continue; + } // Custom combination policy - for (auto& [a1, a2] : o2::soa::combinations(soa::CombinationsFullIndexPolicy(groupedAssocs1, groupedAssocs2))) { - if (!(a1.isBarrelSelected_raw() & fTrackFilterMask)) + for (auto const& [a1, a2] : o2::soa::combinations(soa::CombinationsFullIndexPolicy(groupedAssocs1, groupedAssocs2))) { + if (!(a1.isBarrelSelected_raw() & a1.isBarrelSelectedPrefilter_raw() & fTrackFilterMask)) { continue; - // if (!a1.isBarrelSelectedPrefilter_raw()) continue; - if (!(a2.isMuonSelected_raw() & fMuonFilterMask)) + } + if (!(a2.isMuonSelected_raw() & fMuonFilterMask)) { continue; + } auto t1 = a1.template reducedtrack_as(); auto t2 = a2.template reducedmuon_as(); @@ -2652,18 +2776,22 @@ struct AnalysisSameEventPairing { twoTrackFilter = 0; int minCuts = std::min(fNCutsBarrel, fNCutsMuon); for (int i = 0; i < minCuts; ++i) { - if ((a1.isBarrelSelected_raw() & (1u << i)) && (a2.isMuonSelected_raw() & (1u << i))) { + if ((a1.isBarrelSelected_raw() & a1.isBarrelSelectedPrefilter_raw() & (1u << i)) && (a2.isMuonSelected_raw() & (1u << i))) { twoTrackFilter |= (1u << i); } } - if (t1.barrelAmbiguityInBunch() > 1) + if (t1.barrelAmbiguityInBunch() > 1) { twoTrackFilter |= (1u << 28); - if (t1.barrelAmbiguityOutOfBunch() > 1) + } + if (t1.barrelAmbiguityOutOfBunch() > 1) { twoTrackFilter |= (1u << 30); - if (t2.muonAmbiguityInBunch() > 1) + } + if (t2.muonAmbiguityInBunch() > 1) { twoTrackFilter |= (1u << 29); - if (t2.muonAmbiguityOutOfBunch() > 1) + } + if (t2.muonAmbiguityOutOfBunch() > 1) { twoTrackFilter |= (1u << 31); + } VarManager::FillPair(t1, t2); if (fConfigOptions.propTrack) { @@ -2681,30 +2809,34 @@ struct AnalysisSameEventPairing { t1.sign() + t2.sign(), twoTrackFilter, 0); for (int iTrack = 0; iTrack < fNCutsBarrel; ++iTrack) { - if (!(a1.isBarrelSelected_raw() & (1u << iTrack))) + if (!(a1.isBarrelSelected_raw() & a1.isBarrelSelectedPrefilter_raw() & (1u << iTrack))) { continue; + } for (int iMuon = 0; iMuon < fNCutsMuon; ++iMuon) { - if (!(a2.isMuonSelected_raw() & (1u << iMuon))) + if (!(a2.isMuonSelected_raw() & (1u << iMuon))) { continue; + } for (unsigned int iPairCut = 0; iPairCut < (fPairCuts.empty() ? 1 : fPairCuts.size()); iPairCut++) { if (!fPairCuts.empty()) { AnalysisCompositeCut cut = fPairCuts.at(iPairCut); - if (!cut.IsSelected(VarManager::fgValues)) + if (!cut.IsSelected(dqtablereader_helpers::varValues())) { continue; + } } int index = iTrack * (fNCutsMuon * nPairCuts) + iMuon * nPairCuts + iPairCut; auto itHist = histNames.find(index); - if (itHist == histNames.end()) + if (itHist == histNames.end()) { continue; + } if (sign1 * sign2 < 0) { // Opposite Sign - fHistMan->FillHistClass(itHist->second[0].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHist->second[0].Data(), dqtablereader_helpers::varValues()); } else { // Like Sign if (sign1 > 0) { - fHistMan->FillHistClass(itHist->second[1].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHist->second[1].Data(), dqtablereader_helpers::varValues()); } else { - fHistMan->FillHistClass(itHist->second[2].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHist->second[2].Data(), dqtablereader_helpers::varValues()); } } } // end pair cut loop @@ -2721,15 +2853,15 @@ struct AnalysisSameEventPairing { const auto& histNames = fTrackMuonHistNames; int sign1 = 0; int sign2 = 0; - int nPairCuts = (fPairCuts.size() > 0) ? fPairCuts.size() : 1; + int nPairCuts = !fPairCuts.empty() ? static_cast(fPairCuts.size()) : 1; constexpr bool eventHasQvector = ((TEventFillMap & VarManager::ObjTypes::ReducedEventQvector) > 0); constexpr bool eventHasQvectorCentr = ((TEventFillMap & VarManager::ObjTypes::CollisionQvect) > 0); - for (auto& a1 : assocs1) { - if (!(a1.isBarrelSelected_raw() & fTrackFilterMask)) { + for (auto const& a1 : assocs1) { + if (!(a1.isBarrelSelected_raw() & a1.isBarrelSelectedPrefilter_raw() & fTrackFilterMask)) { continue; } - for (auto& a2 : assocs2) { + for (auto const& a2 : assocs2) { if (!(a2.isMuonSelected_raw() & fMuonFilterMask)) { continue; } @@ -2748,7 +2880,7 @@ struct AnalysisSameEventPairing { } for (int iTrack = 0; iTrack < fNCutsBarrel; ++iTrack) { - if (!(a1.isBarrelSelected_raw() & (1u << iTrack))) { + if (!(a1.isBarrelSelected_raw() & a1.isBarrelSelectedPrefilter_raw() & (1u << iTrack))) { continue; } for (int iMuon = 0; iMuon < fNCutsMuon; ++iMuon) { @@ -2758,7 +2890,7 @@ struct AnalysisSameEventPairing { for (int iPairCut = 0; iPairCut < nPairCuts; ++iPairCut) { if (!fPairCuts.empty()) { AnalysisCompositeCut cut = fPairCuts.at(iPairCut); - if (!cut.IsSelected(VarManager::fgValues)) { + if (!cut.IsSelected(dqtablereader_helpers::varValues())) { continue; } } @@ -2768,12 +2900,12 @@ struct AnalysisSameEventPairing { continue; } if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(itHist->second[3].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHist->second[3].Data(), dqtablereader_helpers::varValues()); } else { if (sign1 > 0) { - fHistMan->FillHistClass(itHist->second[4].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHist->second[4].Data(), dqtablereader_helpers::varValues()); } else { - fHistMan->FillHistClass(itHist->second[5].Data(), VarManager::fgValues); + fHistMan->FillHistClass(itHist->second[5].Data(), dqtablereader_helpers::varValues()); } } } // end pair cut loop @@ -2790,9 +2922,9 @@ struct AnalysisSameEventPairing { events.bindExternalIndices(&assocs1); events.bindExternalIndices(&assocs2); int mixingDepth = fConfigMixingDepth.value; - for (auto& [event1, event2] : selfCombinations(hashBin, mixingDepth, -1, events, events)) { + for (auto const& [event1, event2] : selfCombinations(hashBin, mixingDepth, -1, events, events)) { VarManager::ResetValues(0, VarManager::kNVars); - VarManager::FillEvent(event1, VarManager::fgValues); + VarManager::FillEvent(event1, dqtablereader_helpers::varValues()); auto groupedAssocs1 = assocs1.sliceBy(preslice1, event1.globalIndex()); groupedAssocs1.bindExternalIndices(&events); @@ -2887,13 +3019,13 @@ struct AnalysisSameEventPairing { } void processElectronMuonSkimmed(MyEventsVtxCovSelected const& events, - soa::Join const& barrelAssocs, MyBarrelTracksWithCovWithAmbiguities const& barrelTracks, + soa::Join const& barrelAssocs, MyBarrelTracksWithCovWithAmbiguities const& barrelTracks, soa::Join const& muonAssocs, MyMuonTracksWithCovWithAmbiguities const& muons) { - runEmuSameEventPairing(events, trackEmuAssocsPerCollision, barrelAssocs, barrelTracks, muonAssocsPerCollision, muonAssocs, muons); + runEmuSameEventPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, muonAssocsPerCollision, muonAssocs, muons); } - void processMixingAllSkimmed(soa::Filtered& events, + void processMixingAllSkimmed(soa::Filtered& events, // o2-linter: disable=const-ref-in-process soa::Join const& trackAssocs, MyBarrelTracksWithCov const& tracks, soa::Join const& muonAssocs, MyMuonTracksWithCovWithAmbiguities const& muons) { @@ -2901,44 +3033,44 @@ struct AnalysisSameEventPairing { runSameSideMixing(events, muonAssocs, muons, muonAssocsPerCollision); } - void processMixingBarrelSkimmed(soa::Filtered& events, + void processMixingBarrelSkimmed(soa::Filtered& events, // o2-linter: disable=const-ref-in-process soa::Join const& trackAssocs, aod::ReducedTracks const& tracks) { runSameSideMixing(events, trackAssocs, tracks, trackAssocsPerCollision); } - void processMixingBarrelSkimmedFlow(soa::Filtered& events, + void processMixingBarrelSkimmedFlow(soa::Filtered& events, // o2-linter: disable=const-ref-in-process soa::Join const& trackAssocs, aod::ReducedTracks const& tracks) { runSameSideMixing(events, trackAssocs, tracks, trackAssocsPerCollision); } - void processMixingBarrelWithQvectorCentrSkimmedNoCov(soa::Filtered& events, + void processMixingBarrelWithQvectorCentrSkimmedNoCov(soa::Filtered& events, // o2-linter: disable=const-ref-in-process soa::Join const& trackAssocs, MyBarrelTracksWithAmbiguities const& tracks) { runSameSideMixing(events, trackAssocs, tracks, trackAssocsPerCollision); } - void processMixingMuonSkimmed(soa::Filtered& events, + void processMixingMuonSkimmed(soa::Filtered& events, // o2-linter: disable=const-ref-in-process soa::Join const& muonAssocs, MyMuonTracksWithCovWithAmbiguities const& muons) { runSameSideMixing(events, muonAssocs, muons, muonAssocsPerCollision); } - void processMixingMuonSkimmedFlow(soa::Filtered& events, + void processMixingMuonSkimmedFlow(soa::Filtered& events, // o2-linter: disable=const-ref-in-process soa::Join const& muonAssocs, MyMuonTracksWithCovWithAmbiguities const& muons) { runSameSideMixing(events, muonAssocs, muons, muonAssocsPerCollision); } - void processMixingElectronMuonSkimmed(soa::Filtered& events, - soa::Join const& barrelAssocs, aod::ReducedTracks const& barrelTracks, + void processMixingElectronMuonSkimmed(soa::Filtered& events, // o2-linter: disable=const-ref-in-process + soa::Join const& barrelAssocs, aod::ReducedTracks const& barrelTracks, soa::Join const& muonAssocs, MyMuonTracksWithCovWithAmbiguities const& muons) { - runEmuSameSideMixing(events, trackEmuAssocsPerCollision, barrelAssocs, barrelTracks, muonAssocsPerCollision, muonAssocs, muons); + runEmuSameSideMixing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, muonAssocsPerCollision, muonAssocs, muons); } - void processDummy(MyEventsBasic&) + void processDummy(MyEventsBasic const&) { // do nothing } @@ -2972,7 +3104,7 @@ struct AnalysisAsymmetricPairing { Produces ditrackExtraList; o2::base::MatLayerCylSet* fLUT = nullptr; - int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. + int fCurrentRun = -1; // needed to detect if the run changed and trigger update of calibrations etc. // Output objects OutputObj fOutputList{"output"}; @@ -3003,30 +3135,33 @@ struct AnalysisAsymmetricPairing { Configurable fConfigUseAbsDCA{"cfgUseAbsDCA", false, "Use absolute DCA minimization instead of chi^2 minimization in secondary vertexing"}; Configurable fConfigPropToPCA{"cfgPropToPCA", false, "Propagate tracks to secondary vertex"}; Configurable fConfigLutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + Configurable fConfigFetchInteractionRate{"cfgFetchInteractionRate", false, "Fetch event-wise interaction rate from the CCDB"}; + Configurable fConfigIRSource{"cfgIRSource", "ZNC hadronic", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; - Service fCCDB; + Service fCCDB{}; + ctpRateFetcher rateFetcher; - HistogramManager* fHistMan; + HistogramManager* fHistMan = nullptr; std::vector fPairCuts; - int fNPairHistPrefixes; + int fNPairHistPrefixes = 0; // Filter masks to find legs in BarrelTrackCuts table - uint32_t fLegAFilterMask; - uint32_t fLegBFilterMask; - uint32_t fLegCFilterMask; + uint32_t fLegAFilterMask = 0; + uint32_t fLegBFilterMask = 0; + uint32_t fLegCFilterMask = 0; // Maps tracking which combination of leg cuts the track cuts participate in std::map fConstructedLegAFilterMasksMap; std::map fConstructedLegBFilterMasksMap; std::map fConstructedLegCFilterMasksMap; // Filter map for common track cuts - uint32_t fCommonTrackCutMask; + uint32_t fCommonTrackCutMask = 0; // Map tracking which common track cut the track cuts correspond to std::map fCommonTrackCutFilterMasks; - int fNLegCuts; - int fNPairCuts; - int fNCommonTrackCuts; + int fNLegCuts = 0; + int fNPairCuts = 0; + int fNCommonTrackCuts = 0; // vectors for cut names and signal names, for easy access when calling FillHistogramList() std::vector fLegCutNames; std::vector fPairCutNames; @@ -3051,7 +3186,7 @@ struct AnalysisAsymmetricPairing { VarManager::SetDefaultVarNames(); fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(kTRUE); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqtablereader_helpers::varNames(), dqtablereader_helpers::varUnits()); // Get the leg cut filter maps fLegAFilterMask = fConfigLegAFilterMask.value; @@ -3069,8 +3204,8 @@ struct AnalysisAsymmetricPairing { TString addPairCutsStr = fConfigPairCutsJSON.value; if (addPairCutsStr != "") { std::vector addPairCuts = dqcuts::GetCutsFromJSON(addPairCutsStr.Data()); - for (auto& t : addPairCuts) { - fPairCuts.push_back(reinterpret_cast(t)); + for (auto const& t : addPairCuts) { + fPairCuts.push_back(static_cast(t)); cutNamesStr += Form(",%s", t->GetName()); } } @@ -3088,13 +3223,13 @@ struct AnalysisAsymmetricPairing { TString addTrackCutsStr = tempCuts; if (addTrackCutsStr != "") { std::vector addTrackCuts = dqcuts::GetCutsFromJSON(addTrackCutsStr.Data()); - for (auto& t : addTrackCuts) { + for (auto const& t : addTrackCuts) { tempCutsStr += Form(",%s", t->GetName()); } } std::unique_ptr objArray(tempCutsStr.Tokenize(",")); // Get the common leg cuts - int commonCutIdx; + int commonCutIdx = -1; TString commonNamesStr = fConfigCommonTrackCuts.value; if (!commonNamesStr.IsNull()) { // if common track cuts std::unique_ptr objArrayCommon(commonNamesStr.Tokenize(",")); @@ -3132,9 +3267,9 @@ struct AnalysisAsymmetricPairing { } fNLegCuts = objArrayLegs->GetEntries(); std::vector isThreeProng; - int legAIdx; - int legBIdx; - int legCIdx; + int legAIdx = -1; + int legBIdx = -1; + int legCIdx = -1; // Loop over leg defining cuts for (int icut = 0; icut < fNLegCuts; ++icut) { TString legsStr = objArrayLegs->At(icut)->GetName(); @@ -3277,7 +3412,7 @@ struct AnalysisAsymmetricPairing { void initParamsFromCCDB(uint64_t timestamp, bool isTriplets) { if (fConfigUseRemoteField.value) { - o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp(fConfigGRPMagPath, timestamp); + auto grpmag = fCCDB->getForTimeStamp(fConfigGRPMagPath, timestamp); float magField = 0.0; if (grpmag != nullptr) { magField = grpmag->getNominalL3Field(); @@ -3334,7 +3469,7 @@ struct AnalysisAsymmetricPairing { constexpr bool trackHasCov = ((TTrackFillMap & VarManager::ObjTypes::TrackCov) > 0 || (TTrackFillMap & VarManager::ObjTypes::ReducedTrackBarrelCov) > 0); - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } @@ -3343,7 +3478,11 @@ struct AnalysisAsymmetricPairing { } // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); - VarManager::FillEvent(event, VarManager::fgValues); + VarManager::FillEvent(event, dqtablereader_helpers::varValues()); + // Get the instantaneous IR from the CCDB + if (fConfigFetchInteractionRate.value) { + VarManager::fgValues[VarManager::kInteractionRate] = rateFetcher.fetch(fCCDB.service, event.timestamp(), fCurrentRun, fConfigIRSource.value, true) / 1000.; // kHz + } auto groupedLegAAssocs = legACandidateAssocs.sliceBy(preslice, event.globalIndex()); if (groupedLegAAssocs.size() == 0) { @@ -3354,9 +3493,9 @@ struct AnalysisAsymmetricPairing { continue; } - for (auto& [a1, a2] : combinations(soa::CombinationsFullIndexPolicy(groupedLegAAssocs, groupedLegBAssocs))) { + for (auto const& [a1, a2] : combinations(soa::CombinationsFullIndexPolicy(groupedLegAAssocs, groupedLegBAssocs))) { - uint32_t twoTrackFilter = static_cast(0); + auto twoTrackFilter = static_cast(0); uint32_t twoTrackCommonFilter = static_cast(0); uint32_t pairFilter = static_cast(0); for (int icut = 0; icut < fNLegCuts; ++icut) { @@ -3388,12 +3527,12 @@ struct AnalysisAsymmetricPairing { bool isReflected = false; std::pair trackIds(t1.globalIndex(), t2.globalIndex()); - if (fPairCount.find(trackIds) != fPairCount.end()) { + if (fPairCount.contains(trackIds)) { // Double counting is possible due to track-collision ambiguity. Skip pairs which were counted before fPairCount[trackIds] += 1; continue; } - if (fPairCount.find(std::pair(trackIds.second, trackIds.first)) != fPairCount.end()) { + if (fPairCount.contains(std::pair(trackIds.second, trackIds.first))) { isReflected = true; } fPairCount[trackIds] += 1; @@ -3419,70 +3558,71 @@ struct AnalysisAsymmetricPairing { if (twoTrackFilter & (static_cast(1) << icut)) { isAmbi = (twoTrackFilter & (static_cast(1) << 30)) || (twoTrackFilter & (static_cast(1) << 31)); if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s", fLegCutNames[icut].Data()), VarManager::fgValues); // reconstructed, unmatched + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s", fLegCutNames[icut].Data()), dqtablereader_helpers::varValues()); // reconstructed, unmatched if (isAmbi && fConfigAmbiguousHistograms.value) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_ambiguous_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_ambiguous_%s", fLegCutNames[icut].Data()), dqtablereader_helpers::varValues()); } if (isReflected && fConfigReflectedHistograms.value) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_reflected_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_reflected_%s", fLegCutNames[icut].Data()), dqtablereader_helpers::varValues()); } } else if (fConfigSameSignHistograms.value) { if (sign1 > 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s", fLegCutNames[icut].Data()), dqtablereader_helpers::varValues()); if (isAmbi && fConfigAmbiguousHistograms.value) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_ambiguous_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_ambiguous_%s", fLegCutNames[icut].Data()), dqtablereader_helpers::varValues()); } if (isReflected && fConfigReflectedHistograms.value) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_reflected_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_reflected_%s", fLegCutNames[icut].Data()), dqtablereader_helpers::varValues()); } } else { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s", fLegCutNames[icut].Data()), dqtablereader_helpers::varValues()); if (isAmbi && fConfigAmbiguousHistograms.value) { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_ambiguous_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_ambiguous_%s", fLegCutNames[icut].Data()), dqtablereader_helpers::varValues()); } if (isReflected && fConfigReflectedHistograms) { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_reflected_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_reflected_%s", fLegCutNames[icut].Data()), dqtablereader_helpers::varValues()); } } } for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; iCommonCut++) { if (twoTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), dqtablereader_helpers::varValues()); } else if (fConfigSameSignHistograms.value) { if (sign1 > 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), dqtablereader_helpers::varValues()); } else { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), dqtablereader_helpers::varValues()); } } } } // end loop (common cuts) int iPairCut = 0; for (auto cut = fPairCuts.begin(); cut != fPairCuts.end(); cut++, iPairCut++) { - if (!((*cut)->IsSelected(VarManager::fgValues))) // apply pair cuts + if (!((*cut)->IsSelected(dqtablereader_helpers::varValues()))) { // apply pair cuts continue; + } pairFilter |= (static_cast(1) << iPairCut); // Histograms with pair cuts if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), dqtablereader_helpers::varValues()); } else if (fConfigSameSignHistograms.value) { if (sign1 > 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), dqtablereader_helpers::varValues()); } else { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), dqtablereader_helpers::varValues()); } } // Histograms with pair cuts and common track cuts for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { if (twoTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { if (sign1 * sign2 < 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), dqtablereader_helpers::varValues()); } else if (fConfigSameSignHistograms.value) { if (sign1 > 0) { - fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEPP_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), dqtablereader_helpers::varValues()); } else { - fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("PairsBarrelSEMM_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), dqtablereader_helpers::varValues()); } } } @@ -3511,7 +3651,7 @@ struct AnalysisAsymmetricPairing { } } - for (auto& event : events) { + for (auto const& event : events) { if (!event.isEventSelected_bit(0)) { continue; } @@ -3520,7 +3660,7 @@ struct AnalysisAsymmetricPairing { } // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); - VarManager::FillEvent(event, VarManager::fgValues); + VarManager::FillEvent(event, dqtablereader_helpers::varValues()); auto groupedLegAAssocs = legACandidateAssocs.sliceBy(preslice, event.globalIndex()); if (groupedLegAAssocs.size() == 0) { @@ -3537,17 +3677,17 @@ struct AnalysisAsymmetricPairing { // Based on triplet type, make suitable combinations of the partitions if (tripletType == VarManager::kTripleCandidateToPKPi) { - for (auto& [a1, a2, a3] : combinations(soa::CombinationsFullIndexPolicy(groupedLegAAssocs, groupedLegBAssocs, groupedLegCAssocs))) { + for (auto const& [a1, a2, a3] : combinations(soa::CombinationsFullIndexPolicy(groupedLegAAssocs, groupedLegBAssocs, groupedLegCAssocs))) { readTriplet(a1, a2, a3, tracks, event, tripletType); } } else if (tripletType == VarManager::kTripleCandidateToKPiPi) { - for (auto& a1 : groupedLegAAssocs) { - for (auto& [a2, a3] : combinations(groupedLegBAssocs, groupedLegCAssocs)) { + for (auto const& a1 : groupedLegAAssocs) { + for (auto const& [a2, a3] : combinations(groupedLegBAssocs, groupedLegCAssocs)) { readTriplet(a1, a2, a3, tracks, event, tripletType); } } } else { - LOG(fatal) << "Given tripletType not recognized. Don't know how to make combinations!" << endl; + LOG(fatal) << "Given tripletType not recognized. Don't know how to make combinations!"; } } // end event loop } @@ -3618,7 +3758,7 @@ struct AnalysisAsymmetricPairing { threeTrackFilter |= (static_cast(1) << 31); } - VarManager::FillTriple(t1, t2, t3, VarManager::fgValues, tripletType); + VarManager::FillTriple(t1, t2, t3, dqtablereader_helpers::varValues(), tripletType); if constexpr (TThreeProngFitter) { VarManager::FillTripletVertexing(event, t1, t2, t3, tripletType); } @@ -3626,25 +3766,26 @@ struct AnalysisAsymmetricPairing { // Fill histograms for (int icut = 0; icut < fNLegCuts; icut++) { if (threeTrackFilter & (static_cast(1) << icut)) { - fHistMan->FillHistClass(Form("TripletsBarrelSE_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s", fLegCutNames[icut].Data()), dqtablereader_helpers::varValues()); if (fConfigAmbiguousHistograms.value && ((threeTrackFilter & (static_cast(1) << 29)) || (threeTrackFilter & (static_cast(1) << 30)) || (threeTrackFilter & (static_cast(1) << 31)))) { - fHistMan->FillHistClass(Form("TripletsBarrelSE_ambiguous_%s", fLegCutNames[icut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("TripletsBarrelSE_ambiguous_%s", fLegCutNames[icut].Data()), dqtablereader_helpers::varValues()); } for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; iCommonCut++) { if (threeTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { - fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data()), dqtablereader_helpers::varValues()); } } // end loop (common cuts) int iPairCut = 0; for (auto cut = fPairCuts.begin(); cut != fPairCuts.end(); cut++, iPairCut++) { - if (!((*cut)->IsSelected(VarManager::fgValues))) // apply pair cuts + if (!((*cut)->IsSelected(dqtablereader_helpers::varValues()))) { // apply pair cuts continue; + } // Histograms with pair cuts - fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s", fLegCutNames[icut].Data(), fPairCutNames[iPairCut].Data()), dqtablereader_helpers::varValues()); // Histograms with pair cuts and common track cuts for (int iCommonCut = 0; iCommonCut < fNCommonTrackCuts; ++iCommonCut) { if (threeTrackCommonFilter & fCommonTrackCutFilterMasks[iCommonCut]) { - fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("TripletsBarrelSE_%s_%s_%s", fLegCutNames[icut].Data(), fCommonCutNames[iCommonCut].Data(), fPairCutNames[iPairCut].Data()), dqtablereader_helpers::varValues()); } } } // end loop (pair cuts) @@ -3687,7 +3828,7 @@ struct AnalysisAsymmetricPairing { runThreeProng(events, trackAssocsPerCollision, barrelAssocs, barrelTracks, VarManager::kTripleCandidateToPKPi); } - void processDummy(MyEventsBasic&) + void processDummy(MyEventsBasic const&) { // do nothing } @@ -3715,6 +3856,7 @@ struct AnalysisDileptonTrack { Configurable fConfigDileptonHighpTCut{"cfgDileptonHighpTCut", 1E5, "High pT cut for dileptons used in the triplet vertexing"}; Configurable fConfigDileptonRapCutAbs{"cfgDileptonRapCutAbs", 1.0, "Rap cut for dileptons used in the triplet vertexing"}; Configurable fConfigDileptonLxyCut{"cfgDileptonLxyCut", 0.0, "Lxy cut for dileptons used in the triplet vertexing"}; + Configurable fConfigDileptonTauxyCut{"cfgDileptonTauxyCut", -10000, "Tauxy cut for dileptons used to select the non-prompt Jpsi"}; Configurable fConfigUseKFVertexing{"cfgUseKFVertexing", false, "Use KF Particle for secondary vertex reconstruction (DCAFitter is used by default)"}; Configurable fConfigHistogramSubgroups{"cfgDileptonTrackHistogramsSubgroups", "invmass,vertexing", "Comma separated list of dilepton-track histogram subgroups"}; @@ -3738,13 +3880,13 @@ struct AnalysisDileptonTrack { Configurable fConfigApplyEfficiencyME{"cfgApplyEfficiencyME", false, "If true, apply efficiency correction for the energy correlator study"}; Configurable fConfigAccCCDBPath{"AccCCDBPath", "Users/y/yalin/pptest/test2", "Path of the efficiency corrections"}; - int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. - int fNCuts; // number of dilepton leg cuts - int fNLegCuts; - int fNPairCuts; // number of pair cuts - int fNCommonTrackCuts; + int fCurrentRun = -1; // needed to detect if the run changed and trigger update of calibrations etc. + int fNCuts = 0; // number of dilepton leg cuts + int fNLegCuts = 0; + int fNPairCuts = 0; // number of pair cuts + int fNCommonTrackCuts = 0; std::map fCommonTrackCutMap; - uint32_t fTrackCutBitMap; // track cut bit mask to be used in the selection of tracks associated with dileptons + uint32_t fTrackCutBitMap = 0; // track cut bit mask to be used in the selection of tracks associated with dileptons // vector for single-lepton and track cut names for easy access when calling FillHistogramList() std::vector fTrackCutNames; std::vector fLegCutNames; @@ -3752,30 +3894,30 @@ struct AnalysisDileptonTrack { std::vector fPairCutNames; std::vector fCommonPairCutNames; - Service fCCDB; + Service fCCDB{}; // TODO: The filter expressions seem to always use the default value of configurables, not the values from the actual configuration file Filter eventFilter = aod::dqanalysisflags::isEventSelected > static_cast(0); - Filter dileptonFilter = aod::reducedpair::pt > fConfigDileptonLowpTCut&& aod::reducedpair::pt fConfigDileptonLowMass&& aod::reducedpair::mass fConfigDileptonLxyCut; + Filter dileptonFilter = aod::reducedpair::pt > fConfigDileptonLowpTCut&& aod::reducedpair::pt fConfigDileptonLowMass&& aod::reducedpair::mass fConfigDileptonLxyCut&& aod::reducedpair::tauxy > fConfigDileptonTauxyCut; Filter filterBarrel = aod::dqanalysisflags::isBarrelSelected > static_cast(0); Filter filterMuon = aod::dqanalysisflags::isMuonSelected > static_cast(0); constexpr static uint32_t fgDileptonFillMap = VarManager::ObjTypes::ReducedTrack | VarManager::ObjTypes::Pair; // fill map // use two values array to avoid mixing up the quantities - float* fValuesDilepton; - float* fValuesHadron; - HistogramManager* fHistMan; + float* fValuesDilepton = nullptr; + float* fValuesHadron = nullptr; + HistogramManager* fHistMan = nullptr; NoBinningPolicy fHashBin; TF1* fMassBkg = nullptr; - TH2F* hAcceptance_rec; - TH2F* hAcceptance_gen; - TH2F* hEfficiency_dilepton; - TH2F* hEfficiency_hadron; - TH1F* hMasswindow; + TH2F* hAcceptance_rec = nullptr; + TH2F* hAcceptance_gen = nullptr; + TH2F* hEfficiency_dilepton = nullptr; + TH2F* hEfficiency_hadron = nullptr; + TH1F* hMasswindow = nullptr; void init(o2::framework::InitContext& context) { @@ -3800,7 +3942,7 @@ struct AnalysisDileptonTrack { VarManager::SetDefaultVarNames(); fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(true); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqtablereader_helpers::varNames(), dqtablereader_helpers::varUnits()); // For each track/muon selection used to produce dileptons, create a separate histogram directory using the // name of the track/muon cut. @@ -3830,8 +3972,8 @@ struct AnalysisDileptonTrack { cfgTrackSelection_objArrayTrackCuts = new TObjArray(); } std::vector addTrackCuts = dqcuts::GetCutsFromJSON(cfgTrackSelection_TrackCuts.data()); - for (auto& t : addTrackCuts) { - TObjString* tempObjStr = new TObjString(t->GetName()); + for (auto const& t : addTrackCuts) { + auto tempObjStr = new TObjString(t->GetName()); cfgTrackSelection_objArrayTrackCuts->Add(tempObjStr); } } @@ -3905,7 +4047,7 @@ struct AnalysisDileptonTrack { TString addPairCutsStr = cfgPairing_PairCutsJSON; if (addPairCutsStr != "") { std::vector addPairCuts = dqcuts::GetCutsFromJSON(addPairCutsStr.Data()); - for (auto& t : addPairCuts) { + for (auto const& t : addPairCuts) { cfgPairing_PairCuts += Form(",%s", t->GetName()); } } @@ -3938,7 +4080,7 @@ struct AnalysisDileptonTrack { pairLegCutName = fTrackCutNames[icut].Data(); } else { // For asymmetric pairs we access the leg cuts instead - pairLegCutName = static_cast(cfgPairing_objArrayTrackCuts->At(icut))->GetString(); + pairLegCutName = dynamic_cast(cfgPairing_objArrayTrackCuts->At(icut))->GetString(); } fLegCutNames.push_back(pairLegCutName); @@ -3948,7 +4090,7 @@ struct AnalysisDileptonTrack { for (int iCutTrack = 0; iCutTrack < fNCuts; iCutTrack++) { // here we check that this track cut is one of those required to associate with the dileptons - if (!(fTrackCutBitMap & (static_cast(1) << iCutTrack))) { + if ((fTrackCutBitMap & (static_cast(1) << iCutTrack)) == 0) { continue; } @@ -4013,7 +4155,7 @@ struct AnalysisDileptonTrack { void initParamsFromCCDB(uint64_t timestamp) { if (fConfigUseRemoteField.value) { - o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp(fConfigGRPmagPath.value, timestamp); + auto grpmag = fCCDB->getForTimeStamp(fConfigGRPmagPath.value, timestamp); float magField = 0.0; if (grpmag != nullptr) { magField = grpmag->getNominalL3Field(); @@ -4040,11 +4182,11 @@ struct AnalysisDileptonTrack { if (!listAccs) { LOG(fatal) << "Problem getting TList object with efficiencies!"; } - hEfficiency_dilepton = static_cast(listAccs->FindObject("hEfficiency_dilepton")); - hEfficiency_hadron = static_cast(listAccs->FindObject("hEfficiency_hadron")); - hAcceptance_rec = static_cast(listAccs->FindObject("hAcceptance_rec")); - hAcceptance_gen = static_cast(listAccs->FindObject("hAcceptance_gen")); - hMasswindow = static_cast(listAccs->FindObject("hMasswindow")); + hEfficiency_dilepton = dynamic_cast(listAccs->FindObject("hEfficiency_dilepton")); + hEfficiency_hadron = dynamic_cast(listAccs->FindObject("hEfficiency_hadron")); + hAcceptance_rec = dynamic_cast(listAccs->FindObject("hAcceptance_rec")); + hAcceptance_gen = dynamic_cast(listAccs->FindObject("hAcceptance_gen")); + hMasswindow = dynamic_cast(listAccs->FindObject("hMasswindow")); if (!hAcceptance_rec || !hAcceptance_gen || !hEfficiency_dilepton || !hEfficiency_hadron || !hMasswindow) { LOG(fatal) << "Problem getting histograms from the TList object with efficiencies!"; } @@ -4052,8 +4194,9 @@ struct AnalysisDileptonTrack { float GetSafeInterpolationWeight(TH2* hEff, float x, float y) { - if (!hEff) + if (!hEff) { return 1.0; + } float minX = hEff->GetXaxis()->GetBinCenter(1); float maxX = hEff->GetXaxis()->GetBinCenter(hEff->GetXaxis()->GetNbins()); @@ -4075,7 +4218,7 @@ struct AnalysisDileptonTrack { VarManager::FillEvent(event, fValuesHadron); VarManager::FillEvent(event, fValuesDilepton); - for (auto dilepton : dileptons) { + for (auto const& dilepton : dileptons) { // get full track info of tracks based on the index auto lepton1 = tracks.rawIteratorAt(dilepton.index0Id()); auto lepton2 = tracks.rawIteratorAt(dilepton.index1Id()); @@ -4085,8 +4228,9 @@ struct AnalysisDileptonTrack { } // dilepton rap cut float rap = dilepton.rap(); - if (fConfigUseRapcut && std::abs(rap) > fConfigDileptonRapCutAbs) + if (fConfigUseRapcut && std::abs(rap) > fConfigDileptonRapCutAbs) { continue; + } VarManager::FillTrack(dilepton, fValuesDilepton); @@ -4121,13 +4265,13 @@ struct AnalysisDileptonTrack { } // end loop over single lepton selections // loop over hadrons - for (auto& assoc : assocs) { + for (auto const& assoc : assocs) { uint32_t trackSelection = 0; if constexpr (TCandidateType == VarManager::kBtoJpsiEEK) { // check the cuts fulfilled by this candidate track; if none just continue trackSelection = (assoc.isBarrelSelected_raw() & fTrackCutBitMap); - if (!trackSelection) { + if (trackSelection == 0) { continue; } @@ -4176,7 +4320,7 @@ struct AnalysisDileptonTrack { } if constexpr (TCandidateType == VarManager::kDstarToD0KPiPi) { trackSelection = (assoc.isBarrelSelected_raw() & fTrackCutBitMap); - if (!trackSelection) { + if (trackSelection == 0) { continue; } auto track = assoc.template reducedtrack_as(); @@ -4192,7 +4336,7 @@ struct AnalysisDileptonTrack { } if constexpr (TCandidateType == VarManager::kBcToThreeMuons) { trackSelection = (assoc.isMuonSelected_raw() & fTrackCutBitMap); - if (!trackSelection) { + if (trackSelection == 0) { continue; } auto track = assoc.template reducedmuon_as(); @@ -4266,7 +4410,7 @@ struct AnalysisDileptonTrack { } fCurrentRun = events.begin().runNumber(); } // end: runNumber - for (auto& event : events) { + for (auto const& event : events) { auto groupedBarrelAssocs = assocs.sliceBy(trackAssocsPerCollision, event.globalIndex()); auto groupedDielectrons = dileptons.sliceBy(dielectronsPerCollision, event.globalIndex()); runDileptonHadron(event, groupedBarrelAssocs, tracks, groupedDielectrons); @@ -4285,7 +4429,7 @@ struct AnalysisDileptonTrack { initParamsFromCCDB(events.begin().timestamp()); fCurrentRun = events.begin().runNumber(); } // end: runNumber - for (auto& event : events) { + for (auto const& event : events) { auto groupedBarrelAssocs = assocs.sliceBy(trackAssocsPerCollision, event.globalIndex()); auto groupedDitracks = ditracks.sliceBy(ditracksPerCollision, event.globalIndex()); runDileptonHadron(event, groupedBarrelAssocs, tracks, groupedDitracks); @@ -4307,14 +4451,14 @@ struct AnalysisDileptonTrack { initParamsFromCCDB(events.begin().timestamp()); fCurrentRun = events.begin().runNumber(); } // end: runNumber - for (auto& event : events) { + for (auto const& event : events) { auto groupedMuonAssocs = assocs.sliceBy(muonAssocsPerCollision, event.globalIndex()); auto groupedDimuons = dileptons.sliceBy(dimuonsPerCollision, event.globalIndex()); runDileptonHadron(event, groupedMuonAssocs, tracks, groupedDimuons); } } - void processBarrelMixedEvent(soa::Filtered& events, + void processBarrelMixedEvent(soa::Filtered& events, // o2-linter: disable=const-ref-in-process soa::Filtered> const& assocs, MyBarrelTracksWithCov const& tracks, soa::Filtered const& dileptons) { @@ -4333,10 +4477,10 @@ struct AnalysisDileptonTrack { events.bindExternalIndices(&assocs); // loop over two event comibnations - for (auto& [event1, event2] : selfCombinations(fHashBin, fConfigMixingDepth.value, -1, events, events)) { + for (auto const& [event1, event2] : selfCombinations(fHashBin, fConfigMixingDepth.value, -1, events, events)) { // fill event quantities VarManager::ResetValues(0, VarManager::kNVars); - VarManager::FillEvent(event1, VarManager::fgValues); + VarManager::FillEvent(event1, dqtablereader_helpers::varValues()); // get the dilepton slice for event1 auto evDileptons = dileptons.sliceBy(dielectronsPerCollision, event1.globalIndex()); @@ -4347,11 +4491,11 @@ struct AnalysisDileptonTrack { evAssocs.bindExternalIndices(&events); // loop over associations - for (auto& assoc : evAssocs) { + for (auto const& assoc : evAssocs) { // check that this track fulfills at least one of the specified cuts uint32_t trackSelection = (assoc.isBarrelSelected_raw() & fTrackCutBitMap); - if (!trackSelection) { + if (trackSelection == 0) { continue; } @@ -4359,7 +4503,7 @@ struct AnalysisDileptonTrack { auto track = assoc.template reducedtrack_as(); // loop over dileptons - for (auto dilepton : evDileptons) { + for (auto const& dilepton : evDileptons) { // get full track info of tracks based on the index auto lepton1 = tracks.rawIteratorAt(dilepton.index0Id()); auto lepton2 = tracks.rawIteratorAt(dilepton.index1Id()); @@ -4369,11 +4513,12 @@ struct AnalysisDileptonTrack { } // dilepton rap cut float rap = dilepton.rap(); - if (fConfigUseRapcut && std::abs(rap) > fConfigDileptonRapCutAbs) + if (fConfigUseRapcut && std::abs(rap) > fConfigDileptonRapCutAbs) { continue; + } // compute dilepton - track quantities - VarManager::FillDileptonHadron(dilepton, track, VarManager::fgValues); + VarManager::FillDileptonHadron(dilepton, track, dqtablereader_helpers::varValues()); // for the energy correlator analysis float Effweight_rec = 1.0f; @@ -4394,7 +4539,7 @@ struct AnalysisDileptonTrack { } } std::vector fTransRange = fConfigTransRange; - VarManager::FillEnergyCorrelatorTriple(lepton1, lepton2, track, VarManager::fgValues, fTransRange[0], fTransRange[1], fConfigApplyMassEC, fMassBkg->GetRandom(), 1. / Effweight_rec); + VarManager::FillEnergyCorrelatorTriple(lepton1, lepton2, track, dqtablereader_helpers::varValues(), fTransRange[0], fTransRange[1], fConfigApplyMassEC, fMassBkg->GetRandom(), 1. / Effweight_rec); // loop over dilepton leg cuts and track cuts and fill histograms separately for each combination for (int icut = 0; icut < fNCuts; icut++) { @@ -4403,9 +4548,9 @@ struct AnalysisDileptonTrack { } for (uint32_t iTrackCut = 0; iTrackCut < fTrackCutNames.size(); iTrackCut++) { if (trackSelection & (static_cast(1) << iTrackCut)) { - fHistMan->FillHistClass(Form("DileptonTrackME_%s_%s", fTrackCutNames[icut].Data(), fTrackCutNames[iTrackCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("DileptonTrackME_%s_%s", fTrackCutNames[icut].Data(), fTrackCutNames[iTrackCut].Data()), dqtablereader_helpers::varValues()); if (fConfigEnergycorrelator) { - fHistMan->FillHistClass(Form("DileptonTrackECME_%s_%s", fTrackCutNames[icut].Data(), fTrackCutNames[iTrackCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("DileptonTrackECME_%s_%s", fTrackCutNames[icut].Data(), fTrackCutNames[iTrackCut].Data()), dqtablereader_helpers::varValues()); } } } @@ -4415,7 +4560,7 @@ struct AnalysisDileptonTrack { } // end event loop } - void processMuonMixedEvent(soa::Filtered& events, + void processMuonMixedEvent(soa::Filtered& events, // o2-linter: disable=const-ref-in-process soa::Filtered> const& assocs, MyMuonTracksWithCov const&, soa::Filtered const& dileptons) { @@ -4425,9 +4570,9 @@ struct AnalysisDileptonTrack { events.bindExternalIndices(&dileptons); events.bindExternalIndices(&assocs); - for (auto& [event1, event2] : selfCombinations(fHashBin, fConfigMixingDepth.value, -1, events, events)) { + for (auto const& [event1, event2] : selfCombinations(fHashBin, fConfigMixingDepth.value, -1, events, events)) { VarManager::ResetValues(0, VarManager::kNVars); - VarManager::FillEvent(event1, VarManager::fgValues); + VarManager::FillEvent(event1, dqtablereader_helpers::varValues()); auto evDileptons = dileptons.sliceBy(dimuonsPerCollision, event1.globalIndex()); evDileptons.bindExternalIndices(&events); @@ -4435,23 +4580,23 @@ struct AnalysisDileptonTrack { auto evAssocs = assocs.sliceBy(muonAssocsPerCollision, event2.globalIndex()); evAssocs.bindExternalIndices(&events); - for (auto& assoc : evAssocs) { + for (auto const& assoc : evAssocs) { uint32_t muonSelection = assoc.isMuonSelected_raw() & fTrackCutBitMap; - if (!muonSelection) { + if (muonSelection == 0) { continue; } auto track = assoc.template reducedmuon_as(); - for (auto dilepton : evDileptons) { - VarManager::FillDileptonHadron(dilepton, track, VarManager::fgValues); + for (auto const& dilepton : evDileptons) { + VarManager::FillDileptonHadron(dilepton, track, dqtablereader_helpers::varValues()); for (int icut = 0; icut < fNCuts; icut++) { if (!dilepton.filterMap_bit(icut)) { continue; } for (uint32_t iTrackCut = 0; iTrackCut < fTrackCutNames.size(); iTrackCut++) { if (muonSelection & (static_cast(1) << iTrackCut)) { - fHistMan->FillHistClass(Form("DileptonTrackME_%s_%s", fTrackCutNames[icut].Data(), fTrackCutNames[iTrackCut].Data()), VarManager::fgValues); + fHistMan->FillHistClass(Form("DileptonTrackME_%s_%s", fTrackCutNames[icut].Data(), fTrackCutNames[iTrackCut].Data()), dqtablereader_helpers::varValues()); } } } @@ -4460,7 +4605,7 @@ struct AnalysisDileptonTrack { } // end event loop } - void processDummy(MyEventsBasic&) + void processDummy(MyEventsBasic const&) { // do nothing } @@ -4491,7 +4636,7 @@ struct AnalysisDileptonTrackTrack { Produces DileptonTrackTrackTable; - int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. + int fCurrentRun = -1; // needed to detect if the run changed and trigger update of calibrations etc. // uint32_t fTrackCutBitMap; // track cut bit mask to be used in the selection of tracks associated with dileptons // cut name setting TString fTrackCutName1; @@ -4501,7 +4646,7 @@ struct AnalysisDileptonTrackTrack { std::vector fQuadrupletCutNames; std::vector fQuadrupletCuts; - Service fCCDB; + Service fCCDB{}; Filter eventFilter = aod::dqanalysisflags::isEventSelected > static_cast(0); Filter dileptonFilter = aod::reducedpair::sign == 0; @@ -4510,8 +4655,8 @@ struct AnalysisDileptonTrackTrack { constexpr static uint32_t fgDileptonFillMap = VarManager::ObjTypes::ReducedTrack | VarManager::ObjTypes::Pair; // fill map // use some values array to avoid mixing up the quantities - float* fValuesQuadruplet; - HistogramManager* fHistMan; + float* fValuesQuadruplet = nullptr; + HistogramManager* fHistMan = nullptr; void init(o2::framework::InitContext& context) { @@ -4527,7 +4672,7 @@ struct AnalysisDileptonTrackTrack { VarManager::SetDefaultVarNames(); fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(kTRUE); - fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + fHistMan->SetDefaultVarNames(dqtablereader_helpers::varNames(), dqtablereader_helpers::varUnits()); // define cuts fTrackCutName1 = fConfigTrackCut1.value; @@ -4569,7 +4714,7 @@ struct AnalysisDileptonTrackTrack { void initParamsFromCCDB(uint64_t timestamp) { if (fConfigUseRemoteField.value) { - o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp(fConfigGRPmagPath.value, timestamp); + auto grpmag = fCCDB->getForTimeStamp(fConfigGRPmagPath.value, timestamp); float magField = 0.0; if (grpmag != nullptr) { magField = grpmag->getNominalL3Field(); @@ -4604,7 +4749,7 @@ struct AnalysisDileptonTrackTrack { // int indexOffset = -999; // std::vector trackGlobalIndexes; - for (auto dilepton : dileptons) { + for (auto const& dilepton : dileptons) { // get full track info of tracks based on the index int indexLepton1 = dilepton.index0Id(); @@ -4619,13 +4764,14 @@ struct AnalysisDileptonTrackTrack { // LOGP(info, "is dilepton selected: {}", fDileptonCut.IsSelected(fValuesQuadruplet)); // apply the dilepton cut - if (!fDileptonCut.IsSelected(fValuesQuadruplet)) + if (!fDileptonCut.IsSelected(fValuesQuadruplet)) { continue; + } fHistMan->FillHistClass(Form("Pairs_%s", fDileptonCut.GetName()), fValuesQuadruplet); // loop over hadrons pairs - for (auto& [a1, a2] : o2::soa::combinations(assocs, assocs)) { + for (auto const& [a1, a2] : o2::soa::combinations(assocs, assocs)) { uint32_t trackSelection = 0; if (fIsSameTrackCut) { trackSelection = ((a1.isBarrelSelected_raw() & (static_cast(1) << 1)) || (a2.isBarrelSelected_raw() & (static_cast(1) << 1))); @@ -4633,7 +4779,7 @@ struct AnalysisDileptonTrackTrack { trackSelection = ((a1.isBarrelSelected_raw() & (static_cast(1) << 1)) && (a2.isBarrelSelected_raw() & (static_cast(1) << 2))); } // LOGP(info, "trackSelection: {}, a1: {}, a2: {}", trackSelection, a1.isBarrelSelected_raw(), a2.isBarrelSelected_raw()); - if (!trackSelection) { + if (trackSelection == 0) { continue; } @@ -4678,8 +4824,9 @@ struct AnalysisDileptonTrackTrack { } // loop over dilepton-track-track cuts // fill table - if (!CutDecision) + if (!CutDecision) { continue; + } DileptonTrackTrackTable(fValuesQuadruplet[VarManager::kQuadMass], fValuesQuadruplet[VarManager::kQuadPt], fValuesQuadruplet[VarManager::kQuadEta], fValuesQuadruplet[VarManager::kQuadPhi], fValuesQuadruplet[VarManager::kRap], fValuesQuadruplet[VarManager::kQ], fValuesQuadruplet[VarManager::kDeltaR1], fValuesQuadruplet[VarManager::kDeltaR2], fValuesQuadruplet[VarManager::kDeltaR], dilepton.mass(), dilepton.pt(), dilepton.eta(), dilepton.phi(), dilepton.sign(), @@ -4708,14 +4855,14 @@ struct AnalysisDileptonTrackTrack { initParamsFromCCDB(events.begin().timestamp()); fCurrentRun = events.begin().runNumber(); } // end: runNumber - for (auto& event : events) { + for (auto const& event : events) { auto groupedBarrelAssocs = assocs.sliceBy(trackAssocsPerCollision, event.globalIndex()); auto groupedDielectrons = dileptons.sliceBy(dielectronsPerCollision, event.globalIndex()); runDileptonTrackTrack(event, groupedBarrelAssocs, tracks, groupedDielectrons); } } - void processDummy(MyEventsBasic&) + void processDummy(MyEventsBasic const&) { // do nothing } @@ -4724,20 +4871,7 @@ struct AnalysisDileptonTrackTrack { PROCESS_SWITCH(AnalysisDileptonTrackTrack, processDummy, "Dummy function", true); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc)}; -} - -void DefineHistograms(HistogramManager* histMan, TString histClasses, const char* histGroups) +void DefineHistograms(HistogramManager* histMan, const TString& histClasses, const char* histGroups) { // // Define here the histograms for all the classes required in analysis. diff --git a/PWGDQ/Tasks/tableReader_withAssoc_AsymmetricPairing_workflowSpec.cxx b/PWGDQ/Tasks/tableReader_withAssoc_AsymmetricPairing_workflowSpec.cxx new file mode 100644 index 00000000000..4104a9882ec --- /dev/null +++ b/PWGDQ/Tasks/tableReader_withAssoc_AsymmetricPairing_workflowSpec.cxx @@ -0,0 +1,28 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no +// Configurable workflow for running several DQ or other PWG analyses + +#include "PWGDQ/Tasks/tableReader_withAssoc.cxx" + +#include +#include + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGDQ/Tasks/tableReader_withAssoc_DileptonTrackPairing_workflowSpec.cxx b/PWGDQ/Tasks/tableReader_withAssoc_DileptonTrackPairing_workflowSpec.cxx new file mode 100644 index 00000000000..5ebc720a889 --- /dev/null +++ b/PWGDQ/Tasks/tableReader_withAssoc_DileptonTrackPairing_workflowSpec.cxx @@ -0,0 +1,30 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no +// Configurable workflow for running several DQ or other PWG analyses + +#include "PWGDQ/Tasks/tableReader_withAssoc.cxx" + +#include +#include + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGDQ/Tasks/tableReader_withAssoc_DileptonTrackTrackPairing_workflowSpec.cxx b/PWGDQ/Tasks/tableReader_withAssoc_DileptonTrackTrackPairing_workflowSpec.cxx new file mode 100644 index 00000000000..33cc56c530a --- /dev/null +++ b/PWGDQ/Tasks/tableReader_withAssoc_DileptonTrackTrackPairing_workflowSpec.cxx @@ -0,0 +1,28 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no +// Configurable workflow for running several DQ or other PWG analyses + +#include "PWGDQ/Tasks/tableReader_withAssoc.cxx" + +#include +#include + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGEM/Dilepton/TableProducer/dimuonProducer.cxx b/PWGDQ/Tasks/tableReader_withAssoc_SameEventPairingBarrelOnly_workflowSpec.cxx similarity index 61% rename from PWGEM/Dilepton/TableProducer/dimuonProducer.cxx rename to PWGDQ/Tasks/tableReader_withAssoc_SameEventPairingBarrelOnly_workflowSpec.cxx index ed298d39c39..e66a829fc80 100644 --- a/PWGEM/Dilepton/TableProducer/dimuonProducer.cxx +++ b/PWGDQ/Tasks/tableReader_withAssoc_SameEventPairingBarrelOnly_workflowSpec.cxx @@ -9,20 +9,19 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -// ======================== -// -// This code is for dimuon analyses. -// Please write to: daiki.sekihata@cern.ch +// Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no +// Configurable workflow for running several DQ or other PWG analyses -#include "PWGEM/Dilepton/Core/DileptonProducer.h" -#include "PWGEM/Dilepton/Utils/PairUtilities.h" +#include "PWGDQ/Tasks/tableReader_withAssoc.cxx" #include #include -using namespace o2::framework; - WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{adaptAnalysisTask>(cfgc, TaskName{"dimuon-producer"})}; + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; } diff --git a/PWGEM/Dilepton/TableProducer/dielectronProducer.cxx b/PWGDQ/Tasks/tableReader_withAssoc_SameEventPairingMuonOnly_workflowSpec.cxx similarity index 61% rename from PWGEM/Dilepton/TableProducer/dielectronProducer.cxx rename to PWGDQ/Tasks/tableReader_withAssoc_SameEventPairingMuonOnly_workflowSpec.cxx index 945ac2853c9..aa3dbeb5700 100644 --- a/PWGEM/Dilepton/TableProducer/dielectronProducer.cxx +++ b/PWGDQ/Tasks/tableReader_withAssoc_SameEventPairingMuonOnly_workflowSpec.cxx @@ -9,20 +9,18 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -// ======================== -// -// This code is for dielectron analyses. -// Please write to: daiki.sekihata@cern.ch +// Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no +// Configurable workflow for running several DQ or other PWG analyses -#include "PWGEM/Dilepton/Core/DileptonProducer.h" -#include "PWGEM/Dilepton/Utils/PairUtilities.h" +#include "PWGDQ/Tasks/tableReader_withAssoc.cxx" #include #include -using namespace o2::framework; - WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{adaptAnalysisTask>(cfgc, TaskName{"dielectron-producer"})}; + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; } diff --git a/PWGDQ/Tasks/tableReader_withAssoc_SameEventPairing_workflowSpec.cxx b/PWGDQ/Tasks/tableReader_withAssoc_SameEventPairing_workflowSpec.cxx new file mode 100644 index 00000000000..02795bdc03b --- /dev/null +++ b/PWGDQ/Tasks/tableReader_withAssoc_SameEventPairing_workflowSpec.cxx @@ -0,0 +1,28 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no +// Configurable workflow for running several DQ or other PWG analyses + +#include "PWGDQ/Tasks/tableReader_withAssoc.cxx" + +#include +#include + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGDQ/Tasks/tableReader_withAssoc_direct.cxx b/PWGDQ/Tasks/tableReader_withAssoc_direct.cxx index 13e6b82c889..8a3d1ff07a7 100644 --- a/PWGDQ/Tasks/tableReader_withAssoc_direct.cxx +++ b/PWGDQ/Tasks/tableReader_withAssoc_direct.cxx @@ -27,11 +27,13 @@ #include "Common/Core/TableHelper.h" #include "Common/Core/Zorro.h" #include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/Qvectors.h" #include "Common/DataModel/TrackSelectionTables.h" #include @@ -52,6 +54,7 @@ #include #include +#include #include #include #include @@ -223,8 +226,11 @@ DECLARE_SOA_TABLE(BmesonCandidates, "AOD", "DQBMESONS", // Using definitions (data-only) using MyEvents = soa::Join; +using MyEventsQvectorCentr = soa::Join; using MyEventsSelected = soa::Join; +using MyEventsQvectorCentrSelected = soa::Join; using MyEventsHashSelected = soa::Join; +using MyEventsHashSelectedQvectorCentr = soa::Join; using MyBarrelTracksWithCov = soa::Join(events); } + void processDirectWithQvectorCentr(MyEventsQvectorCentr const& events, BCsWithTimestamps const& bcs) + { + runEventSelection(events, bcs); + publishSelections(events); + } + void processDummy(aod::Collisions&) {} PROCESS_SWITCH(AnalysisEventSelection, processDirect, "Run event selection on framework AO2Ds", false); + PROCESS_SWITCH(AnalysisEventSelection, processDirectWithQvectorCentr, "Run event selection on skimmed data with Q-vector and centrality", false); PROCESS_SWITCH(AnalysisEventSelection, processDummy, "Dummy function", true); }; @@ -857,7 +872,7 @@ struct AnalysisTrackSelection { void processWithCov(TrackAssoc const& assocs, BCsWithTimestamps const& bcs, MyEventsSelected const& events, MyBarrelTracksWithCov const& tracks) { - runTrackSelection(assocs, bcs, events, tracks); + runTrackSelection(assocs, bcs, events, tracks); } void processWithCovTOFService(TrackAssoc const& assocs, BCsWithTimestamps const& bcs, MyEventsSelected const& events, MyBarrelTracksWithCovNoTOF const& tracks) @@ -1275,6 +1290,8 @@ struct AnalysisSameEventPairing { Produces electronmuonList; o2::base::MatLayerCylSet* fLUT = nullptr; + TH1D* ResoFlowSP = nullptr; + TH1D* ResoFlowEP = nullptr; int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. OutputObj fOutputList{"output"}; @@ -1309,6 +1326,7 @@ struct AnalysisSameEventPairing { Configurable fConfigMiniTree{"cfgMiniTree", false, "Produce a single flat table with minimal information for analysis"}; Configurable fConfigMiniTreeMinMass{"cfgMiniTreeMinMass", 2, "Min. mass cut for minitree"}; Configurable fConfigMiniTreeMaxMass{"cfgMiniTreeMaxMass", 5, "Max. mass cut for minitree"}; + Configurable useFlowReso{"cfgUseFlowReso", false, "Use remote flow information from CCDB"}; } fConfigOptions; struct : ConfigurableGroup { @@ -1316,6 +1334,7 @@ struct AnalysisSameEventPairing { Configurable grpMagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + Configurable flowPath{"flowPath", "Users/y/yiping/FlowResolution", "Path to the flow resolution object"}; } fConfigCCDB; Service fCCDB; @@ -1358,7 +1377,7 @@ struct AnalysisSameEventPairing { } VarManager::SetDefaultVarNames(); - fEnableBarrelHistos = context.mOptions.get("processBarrelOnly"); + fEnableBarrelHistos = context.mOptions.get("processBarrelOnly") || context.mOptions.get("processBarrelOnlyWithQvectorCentr"); fEnableBarrelMuonHistos = context.mOptions.get("processElectronMuonDirect"); // Keep track of all the histogram class names to avoid composing strings in the pairing loop @@ -1563,6 +1582,17 @@ struct AnalysisSameEventPairing { VarManager::SetupTwoProngDCAFitter(fConfigOptions.magField.value, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fConfigOptions.useAbsDCA.value); // needed because take in varmanager Bz from fgFitterTwoProngBarrel for PhiV calculations } } + + if (fConfigOptions.useFlowReso) { + TString PathFlow = fConfigCCDB.flowPath.value; + TString ccdbPathFlowSP = Form("%s/ScalarProduct", PathFlow.Data()); + TString ccdbPathFlowEP = Form("%s/EventPlane", PathFlow.Data()); + ResoFlowSP = fCCDB->getForTimeStamp(ccdbPathFlowSP.Data(), timestamp); + ResoFlowEP = fCCDB->getForTimeStamp(ccdbPathFlowEP.Data(), timestamp); + if (ResoFlowSP == nullptr || ResoFlowEP == nullptr) { + LOGF(fatal, "Flow resolution histograms not available in CCDB at timestamp=%llu", timestamp); + } + } } template @@ -1662,8 +1692,9 @@ struct AnalysisSameEventPairing { dielectronAllList.reserve(reserveSize); } - constexpr bool eventHasQvector = ((TEventFillMap & VarManager::ObjTypes::CollisionQvect) > 0); + constexpr bool eventHasQvector = ((TEventFillMap & VarManager::ObjTypes::CollisionQvectCentr) > 0); constexpr bool trackHasCov = ((TTrackFillMap & VarManager::ObjTypes::TrackCov) > 0); + constexpr bool fillFlowReso = eventHasQvector; for (auto& event : events) { if (!event.isEventSelected_bit(0)) @@ -1680,6 +1711,13 @@ struct AnalysisSameEventPairing { if (groupedAssocs.size() == 0) continue; + if (fillFlowReso) { + if (ResoFlowSP == nullptr || ResoFlowEP == nullptr) { + LOGF(fatal, "Flow resolution histograms are not available, cannot fill flow variables!"); + } + VarManager::FillEventFlowResoFactor(ResoFlowSP, ResoFlowEP); + } + for (auto& [a1, a2] : o2::soa::combinations(groupedAssocs, groupedAssocs)) { if constexpr (TPairType == VarManager::kDecayToEE) { @@ -1755,7 +1793,7 @@ struct AnalysisSameEventPairing { } if constexpr (eventHasQvector) { - VarManager::FillPairVn(t1, t2); + VarManager::FillPairVn(t1, t2); } } // Fill normal histograms @@ -1947,10 +1985,18 @@ struct AnalysisSameEventPairing { muonAssocsPerCollision, muonAssocs, muons); } + void processBarrelOnlyWithQvectorCentr(MyEventsQvectorCentrSelected const& events, BCsWithTimestamps const& bcs, + soa::Join const& barrelAssocs, + MyBarrelTracksWithCovWithAmbiguities const& barrelTracks) + { + runSameEventPairing(events, bcs, trackAssocsPerCollision, barrelAssocs, barrelTracks); + } + void processDummy(MyEvents&) { /* do nothing */ } PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnly, "Run barrel only pairing", false); PROCESS_SWITCH(AnalysisSameEventPairing, processElectronMuonDirect, "Run electron-muon pairing on AO2D tracks/fwd-tracks", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnlyWithQvectorCentr, "Run barrel only pairing with Q-vector and centrality", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDummy, "Dummy function", true); }; diff --git a/PWGDQ/Tasks/tableReader_withAssoc_workflowSpec.cxx b/PWGDQ/Tasks/tableReader_withAssoc_workflowSpec.cxx new file mode 100644 index 00000000000..e458aff4e49 --- /dev/null +++ b/PWGDQ/Tasks/tableReader_withAssoc_workflowSpec.cxx @@ -0,0 +1,31 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no +// Configurable workflow for running several DQ or other PWG analyses + +#include "PWGDQ/Tasks/tableReader_withAssoc.cxx" + +#include +#include + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGEM/Dilepton/Core/DielectronCut.cxx b/PWGEM/Dilepton/Core/DielectronCut.cxx index e879828035a..65d952e38c0 100644 --- a/PWGEM/Dilepton/Core/DielectronCut.cxx +++ b/PWGEM/Dilepton/Core/DielectronCut.cxx @@ -17,6 +17,8 @@ #include +#include + #include #include diff --git a/PWGEM/Dilepton/Core/DielectronCut.h b/PWGEM/Dilepton/Core/DielectronCut.h index 22c1273d467..8e076108213 100644 --- a/PWGEM/Dilepton/Core/DielectronCut.h +++ b/PWGEM/Dilepton/Core/DielectronCut.h @@ -29,6 +29,8 @@ #include #include +#include + #include #include @@ -153,21 +155,21 @@ class DielectronCut : public TNamed } float deta = v1.Eta() - v2.Eta(); - float dphi = v1.Phi() - v2.Phi(); + float dphi = RecoDecay::constrainAngle(v1.Phi(), 0, 1U) - RecoDecay::constrainAngle(v2.Phi(), 0, 1U); dphi = RecoDecay::constrainAngle(dphi, -M_PI, 1U); // -pi - +pi if (mApplydEtadPhi && std::pow(deta / mMinDeltaEta, 2) + std::pow(dphi / mMinDeltaPhi, 2) < 1.f) { return false; } - float phiPosition1 = t1.phi() + std::asin(t1.sign() * -0.30282 * (mBz * 0.1) * mRefR / (2.f * t1.pt())); - float phiPosition2 = t2.phi() + std::asin(t2.sign() * -0.30282 * (mBz * 0.1) * mRefR / (2.f * t2.pt())); - phiPosition1 = RecoDecay::constrainAngle(phiPosition1, 0, 1U); // 0-2pi - phiPosition2 = RecoDecay::constrainAngle(phiPosition2, 0, 1U); // 0-2pi - float dphiPosition = phiPosition1 - phiPosition2; - dphiPosition = RecoDecay::constrainAngle(dphiPosition, -M_PI, 1U); // -pi - +pi - if (mApplydEtadPhiPosition && std::pow(deta / mMinDeltaEta, 2) + std::pow(dphiPosition / mMinDeltaPhi, 2) < 1.f) { - return false; - } + // float phiPosition1 = t1.phi() + std::asin(t1.sign() * -0.30282 * (mBz * 0.1) * mRefR / (2.f * t1.pt())); + // float phiPosition2 = t2.phi() + std::asin(t2.sign() * -0.30282 * (mBz * 0.1) * mRefR / (2.f * t2.pt())); + // phiPosition1 = RecoDecay::constrainAngle(phiPosition1, 0, 1U); // 0-2pi + // phiPosition2 = RecoDecay::constrainAngle(phiPosition2, 0, 1U); // 0-2pi + // float dphiPosition = phiPosition1 - phiPosition2; + // dphiPosition = RecoDecay::constrainAngle(dphiPosition, -M_PI, 1U); // -pi - +pi + // if (mApplydEtadPhiPosition && std::pow(deta / mMinDeltaEta, 2) + std::pow(dphiPosition / mMinDeltaPhi, 2) < 1.f) { + // return false; + // } return true; } diff --git a/PWGEM/Dilepton/Core/Dilepton.h b/PWGEM/Dilepton/Core/Dilepton.h index e68f5b6d478..90eb49e208d 100644 --- a/PWGEM/Dilepton/Core/Dilepton.h +++ b/PWGEM/Dilepton/Core/Dilepton.h @@ -20,6 +20,7 @@ #include "PWGEM/Dilepton/Core/DielectronCut.h" #include "PWGEM/Dilepton/Core/DimuonCut.h" #include "PWGEM/Dilepton/Core/EMEventCut.h" +#include "PWGEM/Dilepton/DataModel/EvSelFlags.h" #include "PWGEM/Dilepton/DataModel/dileptonTables.h" #include "PWGEM/Dilepton/Utils/EMFwdTrack.h" #include "PWGEM/Dilepton/Utils/EMTrack.h" @@ -94,11 +95,6 @@ using MyElectron = MyElectrons::iterator; using FilteredMyElectrons = o2::soa::Filtered; using FilteredMyElectron = FilteredMyElectrons::iterator; -using MyElectronsSCT = o2::soa::Join; -using MyElectronSCT = MyElectronsSCT::iterator; -using FilteredMyElectronsSCT = o2::soa::Filtered; -using FilteredMyElectronSCT = FilteredMyElectronsSCT::iterator; - using MyMuons = o2::soa::Join; using MyMuon = MyMuons::iterator; using FilteredMyMuons = o2::soa::Filtered; @@ -107,7 +103,7 @@ using FilteredMyMuon = FilteredMyMuons::iterator; using MyEMH_electron = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, o2::aod::pwgem::dilepton::utils::EMTrack>; using MyEMH_muon = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, o2::aod::pwgem::dilepton::utils::EMFwdTrack>; -template +template struct Dilepton { // Configurables @@ -140,7 +136,7 @@ struct Dilepton { o2::framework::ConfigurableAxis ConfMllBins{"ConfMllBins", {o2::framework::VARIABLE_WIDTH, 0.00, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00}, "mll bins for output histograms"}; o2::framework::ConfigurableAxis ConfPtllBins{"ConfPtllBins", {o2::framework::VARIABLE_WIDTH, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00, 6.00, 7.00, 8.00, 9.00, 10.00}, "pTll bins for output histograms"}; o2::framework::ConfigurableAxis ConfDCAllBins{"ConfDCAllBins", {o2::framework::VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0}, "DCAll bins for output histograms"}; - o2::framework::ConfigurableAxis ConfYllBins{"ConYllBins", {1, -1.f, 1.f}, "yll bins for output histograms"}; // pair rapidity + o2::framework::ConfigurableAxis ConfYllBins{"ConfYllBins", {1, -1.f, 1.f}, "yll bins for output histograms"}; // pair rapidity // o2::framework::ConfigurableAxis ConfMmumuBins{"ConfMmumuBins", {o2::framework::VARIABLE_WIDTH, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11,1.12,1.13,1.14,1.15,1.16,1.17,1.18,1.19, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00, 4.10, 4.20, 4.30, 4.40, 4.50, 4.60, 4.70, 4.80, 4.90, 5.00, 5.10, 5.20, 5.30, 5.40, 5.50, 5.60, 5.70, 5.80, 5.90, 6.00, 6.10, 6.20, 6.30, 6.40, 6.50, 6.60, 6.70, 6.80, 6.90, 7.00, 7.10, 7.20, 7.30, 7.40, 7.50, 7.60, 7.70, 7.80, 7.90, 8.00, 8.10, 8.20, 8.30, 8.40, 8.50, 8.60, 8.70, 8.80, 8.90, 9.00, 9.10, 9.20, 9.30, 9.40, 9.50, 9.60, 9.70, 9.80, 9.90, 10.00, 10.10, 10.20, 10.30, 10.40, 10.50, 10.60, 10.70, 10.80, 10.90, 11.00, 11.50, 12.00}, "mmumu bins for output histograms"}; // for dimuon. one can copy bins here to hyperloop page. @@ -205,7 +201,6 @@ struct Dilepton { o2::framework::Configurable cfg_min_phiv{"cfg_min_phiv", 0.0, "min phiv (constant)"}; o2::framework::Configurable cfg_max_phiv{"cfg_max_phiv", 3.2, "max phiv (constant)"}; o2::framework::Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut at PV"}; - o2::framework::Configurable cfg_apply_detadphiPosition{"cfg_apply_detadphiPosition", false, "flag to apply deta-dphi elliptic cut at ref. radius"}; o2::framework::Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 electrons (elliptic cut)"}; o2::framework::Configurable cfg_min_dphi{"cfg_min_dphi", 0.2, "min dphi between 2 electrons (elliptic cut)"}; o2::framework::Configurable cfg_min_opang{"cfg_min_opang", 0.0, "min opening angle"}; @@ -273,11 +268,6 @@ struct Dilepton { // o2::framework::Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; // o2::framework::Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; // o2::framework::Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; - - o2::framework::Configurable> binsMLSCT{"binsMLSCT", std::vector{0.1, 0.4, 0.6, 0.8, 1, 2, 4, 20.f}, "Bin limits for ML application"}; - o2::framework::Configurable> cutsMLSCTeT_prompt_hc{"cutsMLSCTeT_prompt_hc", std::vector{0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8}, "ML cuts per bin for prompt hc"}; - o2::framework::Configurable> cutsMLSCTeT_nonprompt_hc{"cutsMLSCTeT_nonprompt_hc", std::vector{0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8}, "ML cuts per bin for nonprompt hc"}; - o2::framework::Configurable> cutsMLSCTeT_hb{"cutsMLSCTeT_hb", std::vector{0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8}, "ML cuts per bin for hb"}; } dielectroncuts; DimuonCut fDimuonCut; @@ -317,6 +307,7 @@ struct Dilepton { o2::framework::Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1e+10, "max dca XY for single track in cm"}; o2::framework::Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; o2::framework::Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; + o2::framework::Configurable cfg_max_diff_chi2_mftmch{"cfg_max_diff_chi2_mftmch", -1.f, "max. diff chi2MatchingMCHMFT between the best and the 2nd best matched candidates"}; o2::framework::Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; o2::framework::Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; o2::framework::Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; @@ -620,7 +611,6 @@ struct Dilepton { if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kQC)) { fRegistry.add("Pair/same/uls/hs", "dilepton", o2::framework::HistType::kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y}, true); fRegistry.add("Pair/same/uls/hDeltaEtaDeltaPhi", "#Delta#eta-#Delta#varphi between 2 tracks;#Delta#varphi (rad.);#Delta#eta;", o2::framework::HistType::kTH2D, {{180, -M_PI, M_PI}, {400, -2, +2}}, true); - fRegistry.add("Pair/same/uls/hDeltaEtaDeltaPhiPos", Form("#Delta#eta-#Delta#varphi* between 2 tracks at r_{xy} = %3.2f m;#Delta#varphi* (rad.);#Delta#eta;", dielectroncuts.cfgRefR.value), o2::framework::HistType::kTH2D, {{180, -M_PI, M_PI}, {400, -2, +2}}, true); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.add("Pair/same/uls/hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", o2::framework::HistType::kTH2D, {{90, 0, M_PI}, {100, 0.0f, 1.0f}}, true); // phiv is only for dielectron @@ -770,14 +760,10 @@ struct Dilepton { fDielectronCut.SetPairDCARange(dielectroncuts.cfg_min_pair_dca3d, dielectroncuts.cfg_max_pair_dca3d); // in sigma fDielectronCut.SetMaxMeePhiVDep([&](float phiv) { return dielectroncuts.cfg_phiv_intercept + phiv * dielectroncuts.cfg_phiv_slope; }, dielectroncuts.cfg_min_phiv, dielectroncuts.cfg_max_phiv); fDielectronCut.ApplyPhiV(dielectroncuts.cfg_apply_phiv); - fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, dielectroncuts.cfg_apply_detadphiPosition, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); + fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, false, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); fDielectronCut.SetPairOpAng(dielectroncuts.cfg_min_opang, dielectroncuts.cfg_max_opang); // fDielectronCut.SetRequireDifferentSides(dielectroncuts.cfg_require_diff_sides); - if (dielectroncuts.cfg_apply_detadphi && dielectroncuts.cfg_apply_detadphiPosition) { - LOG(fatal) << "cfg_apply_detadphi and cfg_apply_detadphiPosition cannot be used simultaneously. Please select only one."; - } - // for track fDielectronCut.SetTrackPtRange(dielectroncuts.cfg_min_pt_track, dielectroncuts.cfg_max_pt_track); fDielectronCut.SetTrackEtaRange(dielectroncuts.cfg_min_eta_track, dielectroncuts.cfg_max_eta_track); @@ -845,6 +831,7 @@ struct Dilepton { fDimuonCut.SetChi2(0.f, dimuoncuts.cfg_max_chi2); fDimuonCut.SetChi2MFT(0.f, dimuoncuts.cfg_max_chi2mft); // fDimuonCut.SetMatchingChi2MCHMFT(0.f, dimuoncuts.cfg_max_matching_chi2_mftmch); + fDimuonCut.SetMaxDiffMatchingChi2MCHMFT(dimuoncuts.cfg_max_diff_chi2_mftmch); fDimuonCut.SetMaxMatchingChi2MCHMFTPtDep([&](float pt) { return (pt < dimuoncuts.cfg_border_pt_for_chi2mchmft ? dimuoncuts.cfg_max_matching_chi2_mftmch_lowPt : dimuoncuts.cfg_max_matching_chi2_mftmch_highPt); }); fDimuonCut.SetMatchingChi2MCHMID(0.f, dimuoncuts.cfg_max_matching_chi2_mchmid); fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); @@ -855,26 +842,6 @@ struct Dilepton { fDimuonCut.EnableTTCA(dimuoncuts.enableTTCA); } - template - bool foundHFSV(TTrack const& track) - { - int ptbin = lower_bound(dielectroncuts.binsMLSCT.value.begin(), dielectroncuts.binsMLSCT.value.end(), track.pt()) - dielectroncuts.binsMLSCT.value.begin() - 1; - if (ptbin < 0) { - ptbin = 0; - } else if (static_cast(dielectroncuts.binsMLSCT.value.size()) - 2 < ptbin) { - ptbin = static_cast(dielectroncuts.binsMLSCT.value.size()) - 2; - } - - for (int i = 0; i < static_cast(track.nSV()); i++) { - auto probaSCT = track.probaSCT(i); - // LOGF(info, "track.globalIndex() = %d, pt = %f, i = %d, probaSCT[0] = %f, probaSCT[1] = %f, probaSCT[2] = %f, probaSCT[3] = %f", track.globalIndex(), track.pt(), i, probaSCT[0], probaSCT[1], probaSCT[2], probaSCT[3]); - if (probaSCT[1] > dielectroncuts.cutsMLSCTeT_prompt_hc.value[ptbin] || probaSCT[2] > dielectroncuts.cutsMLSCTeT_nonprompt_hc.value[ptbin] || probaSCT[3] > dielectroncuts.cutsMLSCTeT_hb.value[ptbin]) { - return true; - } - } - return false; - } - template bool isGoodQvector(TQvectors const& qvectors) { @@ -927,11 +894,6 @@ struct Dilepton { return false; } } - if constexpr (withSCT) { - if (foundHFSV(t1) || foundHFSV(t2)) { - return false; - } - } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; @@ -1000,18 +962,12 @@ struct Dilepton { float dphi = t1.sign() * v1.Pt() > t2.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); dphi = RecoDecay::constrainAngle(dphi, -M_PI, 1U); // -pi - +pi - float phiPosition1 = RecoDecay::constrainAngle(t1.phi() + std::asin(t1.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * t1.pt())), 0, 1U); // 0-2pi - float phiPosition2 = RecoDecay::constrainAngle(t2.phi() + std::asin(t2.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * t2.pt())), 0, 1U); // 0-2pi - float dphiPosition = t1.sign() * v1.Pt() > t2.sign() * v2.Pt() ? phiPosition1 - phiPosition2 : phiPosition2 - phiPosition1; - dphiPosition = RecoDecay::constrainAngle(dphiPosition, -M_PI, 1U); // -pi - +pi - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), d_bz); float opAng = o2::aod::pwgem::dilepton::utils::pairutil::getOpeningAngle(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz()); if (t1.sign() * t2.sign() < 0) { // ULS fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hDeltaEtaDeltaPhi"), dphi, deta, weight); - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hDeltaEtaDeltaPhiPos"), dphiPosition, deta, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hMvsPhiV"), phiv, v12.M(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hMvsOpAng"), opAng, v12.M(), weight); @@ -1024,7 +980,6 @@ struct Dilepton { } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hDeltaEtaDeltaPhi"), dphi, deta, weight); - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hDeltaEtaDeltaPhiPos"), dphiPosition, deta, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hMvsPhiV"), phiv, v12.M(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hMvsOpAng"), opAng, v12.M(), weight); @@ -1037,7 +992,6 @@ struct Dilepton { } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hDeltaEtaDeltaPhi"), dphi, deta, weight); - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hDeltaEtaDeltaPhiPos"), dphiPosition, deta, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hMvsPhiV"), phiv, v12.M(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hMvsOpAng"), opAng, v12.M(), weight); @@ -1303,9 +1257,6 @@ struct Dilepton { o2::framework::expressions::Filter prefilter_derived_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter_derived.node() && dielectroncuts.cfg_prefilter_bits_derived.node() >= static_cast(1), ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULSAtRefR))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULSAtRefR))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) <= static_cast(0), true), o2::aod::emprimaryelectron::pfbderived >= static_cast(0)); @@ -1604,13 +1555,6 @@ struct Dilepton { return false; } } - - if constexpr (withSCT) { - if (foundHFSV(t1) || foundHFSV(t2)) { - return false; - } - } - } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { if (!cut.IsSelectedTrack(t1) || !cut.IsSelectedTrack(t2)) { return false; @@ -1618,13 +1562,6 @@ struct Dilepton { if (!map_best_match_globalmuon[t1.globalIndex()] || !map_best_match_globalmuon[t2.globalIndex()]) { return false; } - - // if (!o2::aod::pwgem::dilepton::utils::emtrackutil::isBestMatch(t1, cut, tracks)) { - // return false; - // } - // if (!o2::aod::pwgem::dilepton::utils::emtrackutil::isBestMatch(t2, cut, tracks)) { - // return false; - // } } if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { diff --git a/PWGEM/Dilepton/Core/DileptonHadronMPC.h b/PWGEM/Dilepton/Core/DileptonHadronMPC.h index df4a2d65f6d..f34ef5a1cca 100644 --- a/PWGEM/Dilepton/Core/DileptonHadronMPC.h +++ b/PWGEM/Dilepton/Core/DileptonHadronMPC.h @@ -188,7 +188,6 @@ struct DileptonHadronMPC { o2::framework::Configurable cfg_min_phiv{"cfg_min_phiv", 0.0, "min phiv (constant)"}; o2::framework::Configurable cfg_max_phiv{"cfg_max_phiv", 3.2, "max phiv (constant)"}; o2::framework::Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut at PV"}; - o2::framework::Configurable cfg_apply_detadphiposition{"cfg_apply_detadphiposition", false, "flag to apply deta-dphi elliptic cut at certain radius"}; o2::framework::Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 electrons (elliptic cut)"}; o2::framework::Configurable cfg_min_dphi{"cfg_min_dphi", 0.2, "min dphi between 2 electrons (elliptic cut)"}; @@ -631,7 +630,7 @@ struct DileptonHadronMPC { fDielectronCut.SetPairDCARange(dielectroncuts.cfg_min_pair_dca3d, dielectroncuts.cfg_max_pair_dca3d); // in sigma fDielectronCut.SetMaxMeePhiVDep([&](float phiv) { return dielectroncuts.cfg_phiv_intercept + phiv * dielectroncuts.cfg_phiv_slope; }, dielectroncuts.cfg_min_phiv, dielectroncuts.cfg_max_phiv); fDielectronCut.ApplyPhiV(dielectroncuts.cfg_apply_phiv); - fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, dielectroncuts.cfg_apply_detadphiposition, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); + fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, false, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); fDielectronCut.SetPairOpAng(0.f, 6.3); // fDielectronCut.SetRequireDifferentSides(false); @@ -985,9 +984,6 @@ struct DileptonHadronMPC { o2::framework::expressions::Filter prefilter_derived_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter_derived.node() && dielectroncuts.cfg_prefilter_bits_derived.node() >= static_cast(1), ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULSAtRefR))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULSAtRefR))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) <= static_cast(0), true), o2::aod::emprimaryelectron::pfbderived >= static_cast(0)); diff --git a/PWGEM/Dilepton/Core/DileptonMC.h b/PWGEM/Dilepton/Core/DileptonMC.h index c124e878faa..f7d399518ca 100644 --- a/PWGEM/Dilepton/Core/DileptonMC.h +++ b/PWGEM/Dilepton/Core/DileptonMC.h @@ -20,6 +20,7 @@ #include "PWGEM/Dilepton/Core/DielectronCut.h" #include "PWGEM/Dilepton/Core/DimuonCut.h" #include "PWGEM/Dilepton/Core/EMEventCut.h" +#include "PWGEM/Dilepton/DataModel/EvSelFlags.h" #include "PWGEM/Dilepton/DataModel/dileptonTables.h" #include "PWGEM/Dilepton/Utils/EMTrackUtilities.h" #include "PWGEM/Dilepton/Utils/EventHistograms.h" @@ -200,7 +201,6 @@ struct DileptonMC { o2::framework::Configurable cfg_min_phiv{"cfg_min_phiv", 0.0, "min phiv (constant)"}; o2::framework::Configurable cfg_max_phiv{"cfg_max_phiv", 3.2, "max phiv (constant)"}; o2::framework::Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut at PV"}; - o2::framework::Configurable cfg_apply_detadphiPosition{"cfg_apply_detadphiPosition", false, "flag to apply deta-dphi elliptic cut at ref. radius"}; o2::framework::Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 electrons (elliptic cut)"}; o2::framework::Configurable cfg_min_dphi{"cfg_min_dphi", 0.2, "min dphi between 2 electrons (elliptic cut)"}; o2::framework::Configurable cfg_min_opang{"cfg_min_opang", 0.0, "min opening angle"}; @@ -261,8 +261,8 @@ struct DileptonMC { // configuration for PID ML o2::framework::Configurable> onnxFileNames{"onnxFileNames", std::vector{"filename"}, "ONNX file names for each bin (if not from CCDB full path)"}; o2::framework::Configurable> onnxPathsCCDB{"onnxPathsCCDB", std::vector{"path"}, "Paths of models on CCDB"}; - o2::framework::Configurable> binsMl{"binsMl", std::vector{0.1, 0.15, 0.2, 0.25, 0.4, 0.8, 1.6, 2.0, 20.f}, "Bin limits for ML application"}; - o2::framework::Configurable> cutsMl{"cutsMl", std::vector{0.98, 0.98, 0.9, 0.9, 0.95, 0.95, 0.8, 0.8}, "ML cuts per bin"}; + o2::framework::Configurable> binsMLPID{"binsMLPID", std::vector{0.1, 0.15, 0.2, 0.25, 0.4, 0.8, 1.6, 2.0, 4.0, 20.f}, "Bin limits for ML application"}; + o2::framework::Configurable> cutsMLPID{"cutsMLPID", std::vector{0.97, 0.97, 0.97, 0.8, 0.95, 0.95, 0.8, 0.8, 0.8}, "ML cuts per bin"}; o2::framework::Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature"}, "Names of ML model input features"}; o2::framework::Configurable nameBinningFeature{"nameBinningFeature", "pt", "Names of ML model binning feature"}; o2::framework::Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; @@ -307,6 +307,7 @@ struct DileptonMC { o2::framework::Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1e+10, "max dca XY for single track in cm"}; o2::framework::Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; o2::framework::Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; + o2::framework::Configurable cfg_max_diff_chi2_mftmch{"cfg_max_diff_chi2_mftmch", -1.f, "max. diff chi2MatchingMCHMFT between the best and the 2nd best matched candidates"}; o2::framework::Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; o2::framework::Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; o2::framework::Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; @@ -439,9 +440,6 @@ struct DileptonMC { fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/NonPromptJPsi/"); fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/PromptPsi2S/"); fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/NonPromptPsi2S/"); - // fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/Upsilon1S/"); - // fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/Upsilon2S/"); - // fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/Upsilon3S/"); fRegistry.add("Generated/ccbar/c2l_c2l/uls/hs", "generated dilepton", o2::framework::HistType::kTHnSparseD, {axis_mass, axis_pt, axis_y, axis_dphi_ee, axis_deta_ee, axis_cos_theta_pol, axis_phi_pol, axis_quadmom, axis_aco, axis_asym_pt, axis_dphi_e_ee}, true); fRegistry.addClone("Generated/ccbar/c2l_c2l/uls/", "Generated/ccbar/c2l_c2l/lspp/"); @@ -738,14 +736,10 @@ struct DileptonMC { fDielectronCut.SetPairDCARange(dielectroncuts.cfg_min_pair_dca3d, dielectroncuts.cfg_max_pair_dca3d); // in sigma fDielectronCut.SetMaxMeePhiVDep([&](float phiv) { return dielectroncuts.cfg_phiv_intercept + phiv * dielectroncuts.cfg_phiv_slope; }, dielectroncuts.cfg_min_phiv, dielectroncuts.cfg_max_phiv); fDielectronCut.ApplyPhiV(dielectroncuts.cfg_apply_phiv); - fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, dielectroncuts.cfg_apply_detadphiPosition, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); + fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, false, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); fDielectronCut.SetPairOpAng(dielectroncuts.cfg_min_opang, dielectroncuts.cfg_max_opang); // fDielectronCut.SetRequireDifferentSides(dielectroncuts.cfg_require_diff_sides); - if (dielectroncuts.cfg_apply_detadphi && dielectroncuts.cfg_apply_detadphiPosition) { - LOG(fatal) << "cfg_apply_detadphi and cfg_apply_detadphiPosition cannot be used simultaneously. Please select only one."; - } - // for track fDielectronCut.SetTrackPtRange(dielectroncuts.cfg_min_pt_track, dielectroncuts.cfg_max_pt_track); fDielectronCut.SetTrackEtaRange(dielectroncuts.cfg_min_eta_track, +dielectroncuts.cfg_max_eta_track); @@ -779,14 +773,14 @@ struct DileptonMC { if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDileptonCut std::vector binsML{}; - binsML.reserve(dielectroncuts.binsMl.value.size()); - for (size_t i = 0; i < dielectroncuts.binsMl.value.size(); i++) { - binsML.emplace_back(dielectroncuts.binsMl.value[i]); + binsML.reserve(dielectroncuts.binsMLPID.value.size()); + for (size_t i = 0; i < dielectroncuts.binsMLPID.value.size(); i++) { + binsML.emplace_back(dielectroncuts.binsMLPID.value[i]); } std::vector thresholdsML{}; - thresholdsML.reserve(dielectroncuts.cutsMl.value.size()); - for (size_t i = 0; i < dielectroncuts.cutsMl.value.size(); i++) { - thresholdsML.emplace_back(dielectroncuts.cutsMl.value[i]); + thresholdsML.reserve(dielectroncuts.cutsMLPID.value.size()); + for (size_t i = 0; i < dielectroncuts.cutsMLPID.value.size(); i++) { + thresholdsML.emplace_back(dielectroncuts.cutsMLPID.value[i]); } fDielectronCut.SetMLThresholds(binsML, thresholdsML); } // end of PID ML @@ -813,6 +807,7 @@ struct DileptonMC { fDimuonCut.SetChi2(0.f, dimuoncuts.cfg_max_chi2); fDimuonCut.SetChi2MFT(0.f, dimuoncuts.cfg_max_chi2mft); // fDimuonCut.SetMatchingChi2MCHMFT(0.f, dimuoncuts.cfg_max_matching_chi2_mftmch); + fDimuonCut.SetMaxDiffMatchingChi2MCHMFT(dimuoncuts.cfg_max_diff_chi2_mftmch); fDimuonCut.SetMaxMatchingChi2MCHMFTPtDep([&](float pt) { return (pt < dimuoncuts.cfg_border_pt_for_chi2mchmft ? dimuoncuts.cfg_max_matching_chi2_mftmch_lowPt : dimuoncuts.cfg_max_matching_chi2_mftmch_highPt); }); fDimuonCut.SetMatchingChi2MCHMID(0.f, dimuoncuts.cfg_max_matching_chi2_mchmid); fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); @@ -2537,9 +2532,6 @@ struct DileptonMC { o2::framework::expressions::Filter prefilter_derived_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter_derived.node() && dielectroncuts.cfg_prefilter_bits_derived.node() >= static_cast(1), ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULSAtRefR))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULSAtRefR))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) <= static_cast(0), true), o2::aod::emprimaryelectron::pfbderived >= static_cast(0)); diff --git a/PWGEM/Dilepton/Core/DileptonProducer.h b/PWGEM/Dilepton/Core/DileptonProducer.h deleted file mode 100644 index 25e25fb3e3e..00000000000 --- a/PWGEM/Dilepton/Core/DileptonProducer.h +++ /dev/null @@ -1,782 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -// -// ======================== -// -// This code runs loop over leptons. -// Please write to: daiki.sekihata@cern.ch - -#ifndef PWGEM_DILEPTON_CORE_DILEPTONPRODUCER_H_ -#define PWGEM_DILEPTON_CORE_DILEPTONPRODUCER_H_ - -#include "PWGEM/Dilepton/Core/DielectronCut.h" -#include "PWGEM/Dilepton/Core/DimuonCut.h" -#include "PWGEM/Dilepton/Core/EMEventCut.h" -#include "PWGEM/Dilepton/DataModel/dileptonTables.h" -#include "PWGEM/Dilepton/Utils/EMTrackUtilities.h" -#include "PWGEM/Dilepton/Utils/PairUtilities.h" - -#include "Common/CCDB/RCTSelectionFlags.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/PIDResponseTPC.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using MyCollisions = o2::soa::Join; -using MyCollision = MyCollisions::iterator; - -using MyElectrons = o2::soa::Join; -using MyElectron = MyElectrons::iterator; -using FilteredMyElectrons = o2::soa::Filtered; -using FilteredMyElectron = FilteredMyElectrons::iterator; - -using MyMuons = o2::soa::Join; -using MyMuon = MyMuons::iterator; -using FilteredMyMuons = o2::soa::Filtered; -using FilteredMyMuon = FilteredMyMuons::iterator; - -template -struct DileptonProducer { - o2::framework::Produces eventTable; - o2::framework::Produces normTable; - o2::framework::Produces dileptonTable; - - // Configurables - o2::framework::Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - o2::framework::Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; - o2::framework::Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - o2::framework::Configurable skipGRPOquery{"skipGRPOquery", true, "skip grpo query"}; - o2::framework::Configurable d_bz_input{"d_bz_input", -999, "bz field in kG, -999 is automatic"}; - - o2::framework::Configurable cfgEP2Estimator_for_Mix{"cfgEP2Estimator_for_Mix", 3, "FT0M:0, FT0A:1, FT0C:2, BTot:3, BPos:4, BNeg:5"}; - o2::framework::Configurable cfgQvecEstimator{"cfgQvecEstimator", 0, "FT0M:0, FT0A:1, FT0C:2, BTot:3, BPos:4, BNeg:5"}; - o2::framework::Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; - o2::framework::Configurable cfgOccupancyEstimator{"cfgOccupancyEstimator", 0, "FT0C:0, Track:1"}; - o2::framework::Configurable cfgApplyWeightTTCA{"cfgApplyWeightTTCA", false, "flag to apply weighting by 1/N"}; - o2::framework::Configurable cfgDCAType{"cfgDCAType", 0, "type of DCA for output. 0:3D, 1:XY, 2:Z, else:3D"}; - o2::framework::Configurable cfgStoreULS{"cfgStoreULS", true, "flag to store ULS pairs"}; - o2::framework::Configurable cfgStoreLS{"cfgStoreLS", true, "flag to store LS pairs"}; - - EMEventCut fEMEventCut; - struct : o2::framework::ConfigurableGroup { - std::string prefix = "eventcut_group"; - o2::framework::Configurable cfgZvtxMin{"cfgZvtxMin", -10.f, "min. Zvtx"}; - o2::framework::Configurable cfgZvtxMax{"cfgZvtxMax", +10.f, "max. Zvtx"}; - o2::framework::Configurable cfgRequireSel8{"cfgRequireSel8", true, "require sel8 in event cut"}; - o2::framework::Configurable cfgRequireFT0AND{"cfgRequireFT0AND", true, "require FT0AND in event cut"}; - o2::framework::Configurable cfgRequireNoTFB{"cfgRequireNoTFB", false, "require No time frame border in event cut"}; - o2::framework::Configurable cfgRequireNoITSROFB{"cfgRequireNoITSROFB", false, "require no ITS readout frame border in event cut"}; - o2::framework::Configurable cfgRequireNoSameBunchPileup{"cfgRequireNoSameBunchPileup", false, "require no same bunch pileup in event cut"}; - o2::framework::Configurable cfgRequireVertexITSTPC{"cfgRequireVertexITSTPC", false, "require Vertex ITSTPC in event cut"}; // ITS-TPC matched track contributes PV. - o2::framework::Configurable cfgRequireVertexTOFmatched{"cfgRequireVertexTOFmatched", false, "require Vertex TOFmatched in event cut"}; // ITS-TPC-TOF matched track contributes PV. - o2::framework::Configurable cfgRequireGoodZvtxFT0vsPV{"cfgRequireGoodZvtxFT0vsPV", false, "require good Zvtx between FT0 vs. PV in event cut"}; - o2::framework::Configurable cfgTrackOccupancyMin{"cfgTrackOccupancyMin", -2, "min. occupancy"}; - o2::framework::Configurable cfgTrackOccupancyMax{"cfgTrackOccupancyMax", 1000000000, "max. occupancy"}; - o2::framework::Configurable cfgFT0COccupancyMin{"cfgFT0COccupancyMin", -2, "min. FT0C occupancy"}; - o2::framework::Configurable cfgFT0COccupancyMax{"cfgFT0COccupancyMax", 1000000000, "max. FT0C occupancy"}; - o2::framework::Configurable cfgRequireNoCollInTimeRangeStandard{"cfgRequireNoCollInTimeRangeStandard", false, "require no collision in time range standard"}; - o2::framework::Configurable cfgRequireNoCollInTimeRangeStrict{"cfgRequireNoCollInTimeRangeStrict", false, "require no collision in time range strict"}; - o2::framework::Configurable cfgRequireNoCollInITSROFStandard{"cfgRequireNoCollInITSROFStandard", false, "require no collision in time range standard"}; - o2::framework::Configurable cfgRequireNoCollInITSROFStrict{"cfgRequireNoCollInITSROFStrict", false, "require no collision in time range strict"}; - o2::framework::Configurable cfgRequireNoHighMultCollInPrevRof{"cfgRequireNoHighMultCollInPrevRof", false, "require no HM collision in previous ITS ROF"}; - o2::framework::Configurable cfgRequireGoodITSLayer3{"cfgRequireGoodITSLayer3", false, "number of inactive chips on ITS layer 3 are below threshold "}; - o2::framework::Configurable cfgRequireGoodITSLayer0123{"cfgRequireGoodITSLayer0123", false, "number of inactive chips on ITS layers 0-3 are below threshold "}; - o2::framework::Configurable cfgRequireGoodITSLayersAll{"cfgRequireGoodITSLayersAll", false, "number of inactive chips on all ITS layers are below threshold "}; - // for RCT - o2::framework::Configurable cfgRequireGoodRCT{"cfgRequireGoodRCT", false, "require good detector flag in run condtion table"}; - o2::framework::Configurable cfgRCTLabel{"cfgRCTLabel", "CBT_hadronPID", "select 1 [CBT, CBT_hadronPID, CBT_muon_glo] see O2Physics/Common/CCDB/RCTSelectionFlags.h"}; - o2::framework::Configurable cfgCheckZDC{"cfgCheckZDC", false, "set ZDC flag for PbPb"}; - o2::framework::Configurable cfgTreatLimitedAcceptanceAsBad{"cfgTreatLimitedAcceptanceAsBad", false, "reject all events where the detectors relevant for the specified Runlist are flagged as LimitedAcceptance"}; - - o2::framework::Configurable cfgCentMin{"cfgCentMin", -1, "min. centrality"}; - o2::framework::Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; - o2::framework::Configurable cfgNumContribMin{"cfgNumContribMin", 0, "min. numContrib"}; - o2::framework::Configurable cfgNumContribMax{"cfgNumContribMax", 65000, "max. numContrib"}; - } eventcuts; - - DielectronCut fDielectronCut; - struct : o2::framework::ConfigurableGroup { - std::string prefix = "dielectroncut_group"; - o2::framework::Configurable cfg_min_mass{"cfg_min_mass", 0.0, "min mass"}; - o2::framework::Configurable cfg_max_mass{"cfg_max_mass", 1e+10, "max mass"}; - o2::framework::Configurable cfg_min_pair_pt{"cfg_min_pair_pt", 0.0, "min pair pT"}; - o2::framework::Configurable cfg_max_pair_pt{"cfg_max_pair_pt", 1e+10, "max pair pT"}; - o2::framework::Configurable cfg_min_pair_y{"cfg_min_pair_y", -0.8, "min pair rapidity"}; - o2::framework::Configurable cfg_max_pair_y{"cfg_max_pair_y", +0.8, "max pair rapidity"}; - o2::framework::Configurable cfg_min_pair_dca3d{"cfg_min_pair_dca3d", 0.0, "min pair dca3d in sigma"}; - o2::framework::Configurable cfg_max_pair_dca3d{"cfg_max_pair_dca3d", 1e+10, "max pair dca3d in sigma"}; - o2::framework::Configurable cfg_apply_phiv{"cfg_apply_phiv", true, "flag to apply phiv cut"}; - o2::framework::Configurable cfg_phiv_slope{"cfg_phiv_slope", 0.0185, "slope for m vs. phiv"}; - o2::framework::Configurable cfg_phiv_intercept{"cfg_phiv_intercept", -0.0280, "intercept for m vs. phiv"}; - o2::framework::Configurable cfg_min_phiv{"cfg_min_phiv", 0.0, "min phiv (constant)"}; - o2::framework::Configurable cfg_max_phiv{"cfg_max_phiv", 3.2, "max phiv (constant)"}; - o2::framework::Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut at PV"}; - o2::framework::Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 electrons (elliptic cut)"}; - o2::framework::Configurable cfg_min_dphi{"cfg_min_dphi", 0.2, "min dphi between 2 electrons (elliptic cut)"}; - o2::framework::Configurable cfg_min_opang{"cfg_min_opang", 0.0, "min opening angle"}; - o2::framework::Configurable cfg_max_opang{"cfg_max_opang", 6.4, "max opening angle"}; - // o2::framework::Configurable cfg_require_diff_sides{"cfg_require_diff_sides", false, "flag to require 2 tracks are from different sides."}; - - o2::framework::Configurable cfg_apply_cuts_from_prefilter{"cfg_apply_cuts_from_prefilter", false, "flag to apply prefilter set when producing derived data"}; - o2::framework::Configurable cfg_prefilter_bits{"cfg_prefilter_bits", 0, "prefilter bits [kNone : 0, kElFromPC : 1, kElFromPi0_20MeV : 2, kElFromPi0_40MeV : 4, kElFromPi0_60MeV : 8, kElFromPi0_80MeV : 16, kElFromPi0_100MeV : 32, kElFromPi0_120MeV : 64, kElFromPi0_140MeV : 128] Please consider logical-OR among them."}; // see PairUtilities.h - - o2::framework::Configurable cfg_apply_cuts_from_prefilter_derived{"cfg_apply_cuts_from_prefilter_derived", false, "flag to apply pair cut same as prefilter set in derived data"}; - o2::framework::Configurable cfg_prefilter_bits_derived{"cfg_prefilter_bits_derived", 0, "prefilter bits [kNone : 0, kMee : 1, kPhiV : 2, kSplitOrMergedTrackLS : 4, kSplitOrMergedTrackULS : 8] Please consider logical-OR among them."}; // see PairUtilities.h - - o2::framework::Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.2, "min pT for single track"}; - o2::framework::Configurable cfg_max_pt_track{"cfg_max_pt_track", 1e+10, "max pT for single track"}; - o2::framework::Configurable cfg_min_eta_track{"cfg_min_eta_track", -0.8, "min eta for single track"}; - o2::framework::Configurable cfg_max_eta_track{"cfg_max_eta_track", +0.8, "max eta for single track"}; - o2::framework::Configurable cfg_min_phi_track{"cfg_min_phi_track", 0.f, "min phi for single track"}; - o2::framework::Configurable cfg_max_phi_track{"cfg_max_phi_track", 6.3, "max phi for single track"}; - o2::framework::Configurable cfg_mirror_phi_track{"cfg_mirror_phi_track", false, "mirror the phi cut around Pi, min and max Phi should be in 0-Pi"}; - o2::framework::Configurable cfg_reject_phi_track{"cfg_reject_phi_track", false, "reject the phi interval"}; - o2::framework::Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; - o2::framework::Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 5, "min ncluster its"}; - o2::framework::Configurable cfg_min_ncrossedrows{"cfg_min_ncrossedrows", 100, "min ncrossed rows"}; - o2::framework::Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; - o2::framework::Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; - o2::framework::Configurable cfg_max_chi2its{"cfg_max_chi2its", 5.0, "max chi2/NclsITS"}; - o2::framework::Configurable cfg_max_chi2tof{"cfg_max_chi2tof", 1e+10, "max chi2 TOF"}; - o2::framework::Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 0.2, "max dca XY for single track in cm"}; - o2::framework::Configurable cfg_max_dcaz{"cfg_max_dcaz", 0.2, "max dca Z for single track in cm"}; - o2::framework::Configurable cfg_require_itsib_any{"cfg_require_itsib_any", false, "flag to require ITS ib any hits"}; - o2::framework::Configurable cfg_require_itsib_1st{"cfg_require_itsib_1st", true, "flag to require ITS ib 1st hit"}; - o2::framework::Configurable cfg_min_its_cluster_size{"cfg_min_its_cluster_size", 0.f, "min ITS cluster size"}; - o2::framework::Configurable cfg_max_its_cluster_size{"cfg_max_its_cluster_size", 16.f, "max ITS cluster size"}; - // o2::framework::Configurable cfg_min_rel_diff_pin{"cfg_min_rel_diff_pin", -1e+10, "min rel. diff. between pin and ppv"}; - // o2::framework::Configurable cfg_max_rel_diff_pin{"cfg_max_rel_diff_pin", +1e+10, "max rel. diff. between pin and ppv"}; - o2::framework::Configurable cfgRefR{"cfgRefR", 0.50, "ref. radius (m) for calculating phi position"}; // 0.50 +/- 0.06 can be syst. unc. - o2::framework::Configurable cfg_min_phiposition_track{"cfg_min_phiposition_track", 0.f, "min phi position for single track at certain radius"}; - o2::framework::Configurable cfg_max_phiposition_track{"cfg_max_phiposition_track", 6.3, "max phi position for single track at certain radius"}; - - o2::framework::Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3, kTOFif : 4, kPIDML : 5, kTPChadrejORTOFreq_woTOFif : 6]"}; - o2::framework::Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; - o2::framework::Configurable cfg_max_TPCNsigmaEl{"cfg_max_TPCNsigmaEl", +3.0, "max. TPC n sigma for electron inclusion"}; - // o2::framework::Configurable cfg_min_TPCNsigmaMu{"cfg_min_TPCNsigmaMu", -0.0, "min. TPC n sigma for muon exclusion"}; - // o2::framework::Configurable cfg_max_TPCNsigmaMu{"cfg_max_TPCNsigmaMu", +0.0, "max. TPC n sigma for muon exclusion"}; - o2::framework::Configurable cfg_min_TPCNsigmaPi{"cfg_min_TPCNsigmaPi", -1e+10, "min. TPC n sigma for pion exclusion"}; - o2::framework::Configurable cfg_max_TPCNsigmaPi{"cfg_max_TPCNsigmaPi", +3.0, "max. TPC n sigma for pion exclusion"}; - o2::framework::Configurable cfg_min_TPCNsigmaKa{"cfg_min_TPCNsigmaKa", -3.0, "min. TPC n sigma for kaon exclusion"}; - o2::framework::Configurable cfg_max_TPCNsigmaKa{"cfg_max_TPCNsigmaKa", +3.0, "max. TPC n sigma for kaon exclusion"}; - o2::framework::Configurable cfg_min_TPCNsigmaPr{"cfg_min_TPCNsigmaPr", -3.0, "min. TPC n sigma for proton exclusion"}; - o2::framework::Configurable cfg_max_TPCNsigmaPr{"cfg_max_TPCNsigmaPr", +3.0, "max. TPC n sigma for proton exclusion"}; - o2::framework::Configurable cfg_min_TOFNsigmaEl{"cfg_min_TOFNsigmaEl", -3.0, "min. TOF n sigma for electron inclusion"}; - o2::framework::Configurable cfg_max_TOFNsigmaEl{"cfg_max_TOFNsigmaEl", +3.0, "max. TOF n sigma for electron inclusion"}; - o2::framework::Configurable cfg_min_pin_pirejTPC{"cfg_min_pin_pirejTPC", 0.f, "min. pin for pion rejection in TPC"}; - o2::framework::Configurable cfg_max_pin_pirejTPC{"cfg_max_pin_pirejTPC", 1e+10, "max. pin for pion rejection in TPC"}; - o2::framework::Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; - - // configuration for PID ML - o2::framework::Configurable> onnxFileNames{"onnxFileNames", std::vector{"filename"}, "ONNX file names for each bin (if not from CCDB full path)"}; - o2::framework::Configurable> onnxPathsCCDB{"onnxPathsCCDB", std::vector{"path"}, "Paths of models on CCDB"}; - o2::framework::Configurable> binsMl{"binsMl", std::vector{0.1, 0.15, 0.2, 0.25, 0.4, 0.8, 1.6, 2.0, 20.f}, "Bin limits for ML application"}; - o2::framework::Configurable> cutsMl{"cutsMl", std::vector{0.98, 0.98, 0.9, 0.9, 0.95, 0.95, 0.8, 0.8}, "ML cuts per bin"}; - o2::framework::Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature"}, "Names of ML model input features"}; - o2::framework::Configurable nameBinningFeature{"nameBinningFeature", "pt", "Names of ML model binning feature"}; - o2::framework::Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; - o2::framework::Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; - o2::framework::Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; - } dielectroncuts; - - DimuonCut fDimuonCut; - struct : o2::framework::ConfigurableGroup { - std::string prefix = "dimuoncut_group"; - o2::framework::Configurable cfg_min_mass{"cfg_min_mass", 0.0, "min mass"}; - o2::framework::Configurable cfg_max_mass{"cfg_max_mass", 1e+10, "max mass"}; - o2::framework::Configurable cfg_min_pair_pt{"cfg_min_pair_pt", 0.0, "min pair pt"}; - o2::framework::Configurable cfg_max_pair_pt{"cfg_max_pair_pt", 1e+10, "max pair pt"}; - o2::framework::Configurable cfg_min_pair_y{"cfg_min_pair_y", -4.0, "min pair rapidity"}; - o2::framework::Configurable cfg_max_pair_y{"cfg_max_pair_y", -2.5, "max pair rapidity"}; - o2::framework::Configurable cfg_min_pair_dcaxy{"cfg_min_pair_dcaxy", 0.0, "min pair dca3d in sigma"}; - o2::framework::Configurable cfg_max_pair_dcaxy{"cfg_max_pair_dcaxy", 1e+10, "max pair dca3d in sigma"}; - o2::framework::Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut"}; - o2::framework::Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 muons (elliptic cut)"}; - o2::framework::Configurable cfg_min_dphi{"cfg_min_dphi", 0.02, "min dphi between 2 muons (elliptic cut)"}; - - o2::framework::Configurable cfg_apply_cuts_from_prefilter_derived{"cfg_apply_cuts_from_prefilter_derived", false, "flag to apply prefilter set in derived data"}; - o2::framework::Configurable cfg_prefilter_bits_derived{"cfg_prefilter_bits_derived", 0, "prefilter bits [kNone : 0, kSplitOrMergedTrackLS : 4, kSplitOrMergedTrackULS : 8] Please consider logical-OR among them."}; // see PairUtilities.h - - o2::framework::Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; - o2::framework::Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.2, "min pT for single track"}; - o2::framework::Configurable cfg_max_pt_track{"cfg_max_pt_track", 1e+10, "max pT for single track"}; - o2::framework::Configurable cfg_min_eta_track{"cfg_min_eta_track", -4.0, "min eta for single track"}; - o2::framework::Configurable cfg_max_eta_track{"cfg_max_eta_track", -2.5, "max eta for single track"}; - o2::framework::Configurable cfg_min_phi_track{"cfg_min_phi_track", 0.f, "min phi for single track"}; - o2::framework::Configurable cfg_max_phi_track{"cfg_max_phi_track", 6.3, "max phi for single track"}; - o2::framework::Configurable cfg_min_ncluster_mft{"cfg_min_ncluster_mft", 5, "min ncluster MFT"}; - o2::framework::Configurable cfg_min_ncluster_mch{"cfg_min_ncluster_mch", 5, "min ncluster MCH"}; - o2::framework::Configurable cfg_max_chi2{"cfg_max_chi2", 1e+6, "max chi2/ndf"}; - o2::framework::Configurable cfg_max_chi2mft{"cfg_max_chi2mft", 1e+6, "max chi2/ndf"}; - // o2::framework::Configurable cfg_max_matching_chi2_mftmch{"cfg_max_matching_chi2_mftmch", 40, "max chi2 for MFT-MCH matching"}; - o2::framework::Configurable cfg_border_pt_for_chi2mchmft{"cfg_border_pt_for_chi2mchmft", 0, "border pt for different max chi2 for MFT-MCH matching"}; - o2::framework::Configurable cfg_max_matching_chi2_mftmch_lowPt{"cfg_max_matching_chi2_mftmch_lowPt", 8, "max chi2 for MFT-MCH matching for low pT"}; - o2::framework::Configurable cfg_max_matching_chi2_mftmch_highPt{"cfg_max_matching_chi2_mftmch_highPt", 40, "max chi2 for MFT-MCH matching for high pT"}; - o2::framework::Configurable cfg_max_matching_chi2_mchmid{"cfg_max_matching_chi2_mchmid", 1e+10, "max chi2 for MCH-MID matching"}; - o2::framework::Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1e+10, "max dca XY for single track in cm"}; - o2::framework::Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; - o2::framework::Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; - o2::framework::Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; - o2::framework::Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; - o2::framework::Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; - o2::framework::Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; - o2::framework::Configurable requireMFTHitMap{"requireMFTHitMap", false, "flag to apply MFT hit map"}; - o2::framework::Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; - } dimuoncuts; - - o2::aod::rctsel::RCTFlagsChecker rctChecker; - o2::framework::Service ccdb; - int mRunNumber; - float d_bz; - - o2::framework::HistogramRegistry fRegistry{"output", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject, false, false}; - - float leptonM1 = 0.f; - float leptonM2 = 0.f; - - void init(o2::framework::InitContext& /*context*/) - { - mRunNumber = 0; - d_bz = 0; - - ccdb->setURL(ccdburl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); - rctChecker.init(eventcuts.cfgRCTLabel.value, eventcuts.cfgCheckZDC.value, eventcuts.cfgTreatLimitedAcceptanceAsBad.value); - - DefineEMEventCut(); - if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - DefineDielectronCut(); - leptonM1 = o2::constants::physics::MassElectron; - leptonM2 = o2::constants::physics::MassElectron; - } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - DefineDimuonCut(); - leptonM1 = o2::constants::physics::MassMuon; - leptonM2 = o2::constants::physics::MassMuon; - } - } - - template - void initCCDB(TCollision const& collision) - { - if (mRunNumber == collision.runNumber()) { - return; - } - - // In case override, don't proceed, please - no CCDB access required - if (d_bz_input > -990) { - d_bz = d_bz_input; - o2::parameters::GRPMagField grpmag; - if (std::fabs(d_bz) > 1e-5) { - grpmag.setL3Current(30000.f / (d_bz / 5.0f)); - } - o2::base::Propagator::initFieldFromGRP(&grpmag); - mRunNumber = collision.runNumber(); - return; - } - - auto run3grp_timestamp = collision.timestamp(); - o2::parameters::GRPObject* grpo = 0x0; - o2::parameters::GRPMagField* grpmag = 0x0; - if (!skipGRPOquery) - grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); - if (grpo) { - o2::base::Propagator::initFieldFromGRP(grpo); - // Fetch magnetic field from ccdb for current collision - d_bz = grpo->getNominalL3Field(); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kG"; - } else { - grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); - if (!grpmag) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; - } - o2::base::Propagator::initFieldFromGRP(grpmag); - // Fetch magnetic field from ccdb for current collision - d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kG"; - } - mRunNumber = collision.runNumber(); - fDielectronCut.SetTrackPhiPositionRange(dielectroncuts.cfg_min_phiposition_track, dielectroncuts.cfg_max_phiposition_track, dielectroncuts.cfgRefR, d_bz, dielectroncuts.cfg_mirror_phi_track); - } - - ~DileptonProducer() {} - - void DefineEMEventCut() - { - fEMEventCut = EMEventCut("fEMEventCut", "fEMEventCut"); - fEMEventCut.SetRequireSel8(eventcuts.cfgRequireSel8); - fEMEventCut.SetRequireFT0AND(eventcuts.cfgRequireFT0AND); - fEMEventCut.SetZvtxRange(eventcuts.cfgZvtxMin, eventcuts.cfgZvtxMax); - fEMEventCut.SetRequireNoTFB(eventcuts.cfgRequireNoTFB); - fEMEventCut.SetRequireNoITSROFB(eventcuts.cfgRequireNoITSROFB); - fEMEventCut.SetRequireNoSameBunchPileup(eventcuts.cfgRequireNoSameBunchPileup); - fEMEventCut.SetRequireVertexITSTPC(eventcuts.cfgRequireVertexITSTPC); - fEMEventCut.SetRequireVertexTOFmatched(eventcuts.cfgRequireVertexTOFmatched); - fEMEventCut.SetRequireGoodZvtxFT0vsPV(eventcuts.cfgRequireGoodZvtxFT0vsPV); - fEMEventCut.SetRequireNoCollInTimeRangeStandard(eventcuts.cfgRequireNoCollInTimeRangeStandard); - fEMEventCut.SetRequireNoCollInTimeRangeStrict(eventcuts.cfgRequireNoCollInTimeRangeStrict); - fEMEventCut.SetRequireNoCollInITSROFStandard(eventcuts.cfgRequireNoCollInITSROFStandard); - fEMEventCut.SetRequireNoCollInITSROFStrict(eventcuts.cfgRequireNoCollInITSROFStrict); - fEMEventCut.SetRequireNoHighMultCollInPrevRof(eventcuts.cfgRequireNoHighMultCollInPrevRof); - fEMEventCut.SetRequireGoodITSLayer3(eventcuts.cfgRequireGoodITSLayer3); - fEMEventCut.SetRequireGoodITSLayer0123(eventcuts.cfgRequireGoodITSLayer0123); - fEMEventCut.SetRequireGoodITSLayersAll(eventcuts.cfgRequireGoodITSLayersAll); - } - - void DefineDielectronCut() - { - fDielectronCut = DielectronCut("fDielectronCut", "fDielectronCut"); - - // for pair - fDielectronCut.SetMeeRange(dielectroncuts.cfg_min_mass, dielectroncuts.cfg_max_mass); - fDielectronCut.SetPairPtRange(dielectroncuts.cfg_min_pair_pt, dielectroncuts.cfg_max_pair_pt); - fDielectronCut.SetPairYRange(dielectroncuts.cfg_min_pair_y, dielectroncuts.cfg_max_pair_y); - fDielectronCut.SetPairDCARange(dielectroncuts.cfg_min_pair_dca3d, dielectroncuts.cfg_max_pair_dca3d); // in sigma - fDielectronCut.SetMaxMeePhiVDep([&](float phiv) { return dielectroncuts.cfg_phiv_intercept + phiv * dielectroncuts.cfg_phiv_slope; }, dielectroncuts.cfg_min_phiv, dielectroncuts.cfg_max_phiv); - fDielectronCut.ApplyPhiV(dielectroncuts.cfg_apply_phiv); - fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, false, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); - fDielectronCut.SetPairOpAng(dielectroncuts.cfg_min_opang, dielectroncuts.cfg_max_opang); - // fDielectronCut.SetRequireDifferentSides(dielectroncuts.cfg_require_diff_sides); - - // for track - fDielectronCut.SetTrackPtRange(dielectroncuts.cfg_min_pt_track, dielectroncuts.cfg_max_pt_track); - fDielectronCut.SetTrackEtaRange(dielectroncuts.cfg_min_eta_track, dielectroncuts.cfg_max_eta_track); - fDielectronCut.SetTrackPhiRange(dielectroncuts.cfg_min_phi_track, dielectroncuts.cfg_max_phi_track, dielectroncuts.cfg_mirror_phi_track, dielectroncuts.cfg_reject_phi_track); - fDielectronCut.SetMinNClustersTPC(dielectroncuts.cfg_min_ncluster_tpc); - fDielectronCut.SetMinNCrossedRowsTPC(dielectroncuts.cfg_min_ncrossedrows); - fDielectronCut.SetMinNCrossedRowsOverFindableClustersTPC(0.8); - fDielectronCut.SetMaxFracSharedClustersTPC(dielectroncuts.cfg_max_frac_shared_clusters_tpc); - fDielectronCut.SetChi2PerClusterTPC(0.0, dielectroncuts.cfg_max_chi2tpc); - fDielectronCut.SetChi2PerClusterITS(0.0, dielectroncuts.cfg_max_chi2its); - fDielectronCut.SetNClustersITS(dielectroncuts.cfg_min_ncluster_its, 7); - fDielectronCut.SetMeanClusterSizeITS(dielectroncuts.cfg_min_its_cluster_size, dielectroncuts.cfg_max_its_cluster_size); - fDielectronCut.SetTrackMaxDcaXY(dielectroncuts.cfg_max_dcaxy); - fDielectronCut.SetTrackMaxDcaZ(dielectroncuts.cfg_max_dcaz); - fDielectronCut.RequireITSibAny(dielectroncuts.cfg_require_itsib_any); - fDielectronCut.RequireITSib1st(dielectroncuts.cfg_require_itsib_1st); - fDielectronCut.SetChi2TOF(0, dielectroncuts.cfg_max_chi2tof); - // fDielectronCut.SetRelDiffPin(dielectroncuts.cfg_min_rel_diff_pin, dielectroncuts.cfg_max_rel_diff_pin); - - // for eID - fDielectronCut.SetPIDScheme(dielectroncuts.cfg_pid_scheme); - fDielectronCut.SetTPCNsigmaElRange(dielectroncuts.cfg_min_TPCNsigmaEl, dielectroncuts.cfg_max_TPCNsigmaEl); - // fDielectronCut.SetTPCNsigmaMuRange(dielectroncuts.cfg_min_TPCNsigmaMu, dielectroncuts.cfg_max_TPCNsigmaMu); - fDielectronCut.SetTPCNsigmaPiRange(dielectroncuts.cfg_min_TPCNsigmaPi, dielectroncuts.cfg_max_TPCNsigmaPi); - fDielectronCut.SetTPCNsigmaKaRange(dielectroncuts.cfg_min_TPCNsigmaKa, dielectroncuts.cfg_max_TPCNsigmaKa); - fDielectronCut.SetTPCNsigmaPrRange(dielectroncuts.cfg_min_TPCNsigmaPr, dielectroncuts.cfg_max_TPCNsigmaPr); - fDielectronCut.SetTOFNsigmaElRange(dielectroncuts.cfg_min_TOFNsigmaEl, dielectroncuts.cfg_max_TOFNsigmaEl); - fDielectronCut.SetPinRangeForPionRejectionTPC(dielectroncuts.cfg_min_pin_pirejTPC, dielectroncuts.cfg_max_pin_pirejTPC); - - if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDileptonCut - std::vector binsML{}; - binsML.reserve(dielectroncuts.binsMl.value.size()); - for (size_t i = 0; i < dielectroncuts.binsMl.value.size(); i++) { - binsML.emplace_back(dielectroncuts.binsMl.value[i]); - } - std::vector thresholdsML{}; - thresholdsML.reserve(dielectroncuts.cutsMl.value.size()); - for (size_t i = 0; i < dielectroncuts.cutsMl.value.size(); i++) { - thresholdsML.emplace_back(dielectroncuts.cutsMl.value[i]); - } - fDielectronCut.SetMLThresholds(binsML, thresholdsML); - } // end of PID ML - } - - void DefineDimuonCut() - { - fDimuonCut = DimuonCut("fDimuonCut", "fDimuonCut"); - - // for pair - fDimuonCut.SetMassRange(dimuoncuts.cfg_min_mass, dimuoncuts.cfg_max_mass); - fDimuonCut.SetPairPtRange(dimuoncuts.cfg_min_pair_pt, dimuoncuts.cfg_max_pair_pt); - fDimuonCut.SetPairYRange(dimuoncuts.cfg_min_pair_y, dimuoncuts.cfg_max_pair_y); - fDimuonCut.SetPairDCAxyRange(dimuoncuts.cfg_min_pair_dcaxy, dimuoncuts.cfg_max_pair_dcaxy); - fDimuonCut.SetMindEtadPhi(dimuoncuts.cfg_apply_detadphi, dimuoncuts.cfg_min_deta, dimuoncuts.cfg_min_dphi); - - // for track - fDimuonCut.SetTrackType(dimuoncuts.cfg_track_type); - fDimuonCut.SetTrackPtRange(dimuoncuts.cfg_min_pt_track, dimuoncuts.cfg_max_pt_track); - fDimuonCut.SetTrackEtaRange(dimuoncuts.cfg_min_eta_track, dimuoncuts.cfg_max_eta_track); - fDimuonCut.SetTrackPhiRange(dimuoncuts.cfg_min_phi_track, dimuoncuts.cfg_max_phi_track); - fDimuonCut.SetNClustersMFT(dimuoncuts.cfg_min_ncluster_mft, 10); - fDimuonCut.SetNClustersMCHMID(dimuoncuts.cfg_min_ncluster_mch, 20); - fDimuonCut.SetChi2(0.f, dimuoncuts.cfg_max_chi2); - fDimuonCut.SetChi2MFT(0.f, dimuoncuts.cfg_max_chi2mft); - // fDimuonCut.SetMatchingChi2MCHMFT(0.f, dimuoncuts.cfg_max_matching_chi2_mftmch); - fDimuonCut.SetMaxMatchingChi2MCHMFTPtDep([&](float pt) { return (pt < dimuoncuts.cfg_border_pt_for_chi2mchmft ? dimuoncuts.cfg_max_matching_chi2_mftmch_lowPt : dimuoncuts.cfg_max_matching_chi2_mftmch_highPt); }); - fDimuonCut.SetMatchingChi2MCHMID(0.f, dimuoncuts.cfg_max_matching_chi2_mchmid); - fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); - fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); - fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); - fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons - fDimuonCut.SetMFTHitMap(dimuoncuts.requireMFTHitMap, dimuoncuts.requiredMFTDisks); - } - - template - bool fillPairInfo(TCollision const&, TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TAllTracks const&) - { - if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { - return false; - } - } else { // cut-based - if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { - return false; - } - } - } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { - return false; - } - if (!map_best_match_globalmuon[t1.globalIndex()] || !map_best_match_globalmuon[t2.globalIndex()]) { - return false; - } - - // if (!o2::aod::pwgem::dilepton::utils::emtrackutil::isBestMatch(t1, cut, tracks)) { - // return false; - // } - // if (!o2::aod::pwgem::dilepton::utils::emtrackutil::isBestMatch(t2, cut, tracks)) { - // return false; - // } - } - - if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - if (!cut.IsSelectedPair(t1, t2)) { - return false; - } - } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - if (!cut.IsSelectedPair(t1, t2)) { - return false; - } - } - - float weight = 1.f; - if (cfgApplyWeightTTCA) { - weight = map_weight[std::make_pair(t1.globalIndex(), t2.globalIndex())]; - } - - ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), leptonM1); - ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), leptonM2); - // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - - float dca1 = 999.f, dca2 = 999.f; - if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - dca1 = o2::aod::pwgem::dilepton::utils::emtrackutil::dca3DinSigma(t1); - dca2 = o2::aod::pwgem::dilepton::utils::emtrackutil::dca3DinSigma(t2); - if (cfgDCAType == 1) { - dca1 = o2::aod::pwgem::dilepton::utils::emtrackutil::dcaXYinSigma(t1); - dca2 = o2::aod::pwgem::dilepton::utils::emtrackutil::dcaXYinSigma(t2); - } else if (cfgDCAType == 2) { - dca1 = o2::aod::pwgem::dilepton::utils::emtrackutil::dcaZinSigma(t1); - dca2 = o2::aod::pwgem::dilepton::utils::emtrackutil::dcaZinSigma(t2); - } - } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - dca1 = o2::aod::pwgem::dilepton::utils::emtrackutil::fwdDcaXYinSigma(t1); - dca2 = o2::aod::pwgem::dilepton::utils::emtrackutil::fwdDcaXYinSigma(t2); - } - - // fill table here - dileptonTable(eventTable.lastIndex() + 1, // lastIndex starts from -1. - t1.pt(), t1.eta(), t1.phi(), t1.sign(), dca1, - t2.pt(), t2.eta(), t2.phi(), t2.sign(), dca2, - weight); - - return true; - } - - o2::framework::expressions::Filter collisionFilter_centrality = (eventcuts.cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < eventcuts.cfgCentMax) || (eventcuts.cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < eventcuts.cfgCentMax) || (eventcuts.cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < eventcuts.cfgCentMax); - o2::framework::expressions::Filter collisionFilter_numContrib = eventcuts.cfgNumContribMin <= o2::aod::collision::numContrib && o2::aod::collision::numContrib < eventcuts.cfgNumContribMax; - o2::framework::expressions::Filter collisionFilter_occupancy_track = eventcuts.cfgTrackOccupancyMin <= o2::aod::evsel::trackOccupancyInTimeRange && o2::aod::evsel::trackOccupancyInTimeRange < eventcuts.cfgTrackOccupancyMax; - o2::framework::expressions::Filter collisionFilter_occupancy_ft0c = eventcuts.cfgFT0COccupancyMin <= o2::aod::evsel::ft0cOccupancyInTimeRange && o2::aod::evsel::ft0cOccupancyInTimeRange < eventcuts.cfgFT0COccupancyMax; - using FilteredMyCollisions = o2::soa::Filtered; - - o2::framework::SliceCache cache; - o2::framework::Preslice perCollision_electron = o2::aod::emprimaryelectron::emeventId; - o2::framework::expressions::Filter trackFilter_electron = dielectroncuts.cfg_min_pt_track < o2::aod::track::pt && dielectroncuts.cfg_min_eta_track < o2::aod::track::eta && o2::aod::track::eta < dielectroncuts.cfg_max_eta_track && nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz; - o2::framework::expressions::Filter pidFilter_electron = dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl; - o2::framework::expressions::Filter ttcaFilter_electron = ifnode(dielectroncuts.enableTTCA.node(), o2::aod::emprimaryelectron::isAssociatedToMPC == true || o2::aod::emprimaryelectron::isAssociatedToMPC == false, o2::aod::emprimaryelectron::isAssociatedToMPC == true); - o2::framework::expressions::Filter prefilter_derived_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter_derived.node() && dielectroncuts.cfg_prefilter_bits_derived.node() >= static_cast(1), - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) <= static_cast(0), true), - o2::aod::emprimaryelectron::pfbderived >= static_cast(0)); - - o2::framework::expressions::Filter prefilter_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter.node() && dielectroncuts.cfg_prefilter_bits.node() >= static_cast(1), - ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPC))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPC))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_20MeV))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_20MeV))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_40MeV))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_40MeV))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_60MeV))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_60MeV))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_80MeV))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_80MeV))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_100MeV))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_100MeV))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_120MeV))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_120MeV))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_140MeV))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_140MeV))) <= static_cast(0), true), - o2::aod::emprimaryelectron::pfb >= static_cast(0)); - - o2::framework::Partition positive_electrons = o2::aod::emprimaryelectron::sign > int8_t(0); - o2::framework::Partition negative_electrons = o2::aod::emprimaryelectron::sign < int8_t(0); - - o2::framework::Preslice perCollision_muon = o2::aod::emprimarymuon::emeventId; - o2::framework::expressions::Filter trackFilter_muon = o2::aod::fwdtrack::trackType == dimuoncuts.cfg_track_type && dimuoncuts.cfg_min_pt_track < o2::aod::fwdtrack::pt && o2::aod::fwdtrack::pt < dimuoncuts.cfg_max_pt_track && dimuoncuts.cfg_min_eta_track < o2::aod::fwdtrack::eta && o2::aod::fwdtrack::eta < dimuoncuts.cfg_max_eta_track; - o2::framework::expressions::Filter ttcaFilter_muon = ifnode(dimuoncuts.enableTTCA.node(), o2::aod::emprimarymuon::isAssociatedToMPC == true || o2::aod::emprimarymuon::isAssociatedToMPC == false, o2::aod::emprimarymuon::isAssociatedToMPC == true); - o2::framework::expressions::Filter prefilter_derived_muon = ifnode(dimuoncuts.cfg_apply_cuts_from_prefilter_derived.node() && dimuoncuts.cfg_prefilter_bits_derived.node() >= static_cast(1), - ifnode((dimuoncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) > static_cast(0), (o2::aod::emprimarymuon::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) <= static_cast(0), true) && - ifnode((dimuoncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) > static_cast(0), (o2::aod::emprimarymuon::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) <= static_cast(0), true), - o2::aod::emprimarymuon::pfbderived >= static_cast(0)); - o2::framework::Partition positive_muons = o2::aod::emprimarymuon::sign > int8_t(0); - o2::framework::Partition negative_muons = o2::aod::emprimarymuon::sign < int8_t(0); - - template - void runPairing(TCollisions const& collisions, TLeptons const& posTracks, TLeptons const& negTracks, TPresilce const& perCollision, TCut const& cut, TAllTracks const& tracks) - { - for (const auto& collision : collisions) { - initCCDB(collision); - const float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; - // float centrality = centralities[cfgCentEstimator]; - if (centralities[cfgCentEstimator] < eventcuts.cfgCentMin || eventcuts.cfgCentMax < centralities[cfgCentEstimator]) { - continue; - } - - float eventplanes_2_for_mix[7] = {collision.ep2ft0m(), collision.ep2ft0a(), collision.ep2ft0c(), collision.ep2btot(), collision.ep2bpos(), collision.ep2bneg(), collision.ep2fv0a()}; - float ep2 = eventplanes_2_for_mix[cfgEP2Estimator_for_Mix]; - - if (!fEMEventCut.IsSelected(collision)) { - continue; - } - if (eventcuts.cfgRequireGoodRCT && !rctChecker.checkTable(collision)) { - continue; - } - - auto posTracks_per_coll = posTracks.sliceByCached(perCollision, collision.globalIndex(), cache); - auto negTracks_per_coll = negTracks.sliceByCached(perCollision, collision.globalIndex(), cache); - - int nuls = 0, nlspp = 0, nlsmm = 0; - - if (cfgStoreULS) { - for (const auto& [pos, neg] : combinations(o2::soa::CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS - bool is_pair_ok = fillPairInfo(collision, pos, neg, cut, tracks); - if (is_pair_ok) { - nuls++; - } - } - } - if (cfgStoreLS) { - for (const auto& [pos1, pos2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ - bool is_pair_ok = fillPairInfo(collision, pos1, pos2, cut, tracks); - if (is_pair_ok) { - nlspp++; - } - } - for (const auto& [neg1, neg2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- - bool is_pair_ok = fillPairInfo(collision, neg1, neg2, cut, tracks); - if (is_pair_ok) { - nlsmm++; - } - } - } - - if (nuls > 0 || nlspp > 0 || nlsmm > 0) { - eventTable(collision.runNumber(), collision.globalBC(), collision.timestamp(), collision.posZ(), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange(), centralities[cfgCentEstimator], ep2); - } - } // end of collision loop - } // end of DF - - template - bool isPairOK(TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TAllTracks const&) - { - if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { - if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { - return false; - } - } else { // cut-based - if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { - return false; - } - } - } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - if (!cut.IsSelectedTrack(t1) || !cut.IsSelectedTrack(t2)) { - return false; - } - if (!map_best_match_globalmuon[t1.globalIndex()] || !map_best_match_globalmuon[t2.globalIndex()]) { - return false; - } - - // if (!o2::aod::pwgem::dilepton::utils::emtrackutil::isBestMatch(t1, cut, tracks)) { - // return false; - // } - // if (!o2::aod::pwgem::dilepton::utils::emtrackutil::isBestMatch(t2, cut, tracks)) { - // return false; - // } - } - - if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - if (!cut.IsSelectedPair(t1, t2)) { - return false; - } - } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - if (!cut.IsSelectedPair(t1, t2)) { - return false; - } - } - return true; - } - - std::map, float> map_weight; // -> float - template - void fillPairWeightMap(TCollisions const& collisions, TLeptons const& posTracks, TLeptons const& negTracks, TPresilce const& perCollision, TCut const& cut, TAllTracks const& tracks) - { - std::vector> passed_pairIds; - passed_pairIds.reserve(posTracks.size() * negTracks.size()); - - for (const auto& collision : collisions) { - initCCDB(collision); - const float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; - if (centralities[cfgCentEstimator] < eventcuts.cfgCentMin || eventcuts.cfgCentMax < centralities[cfgCentEstimator]) { - continue; - } - - if (!fEMEventCut.IsSelected(collision)) { - continue; - } - if (eventcuts.cfgRequireGoodRCT && !rctChecker.checkTable(collision)) { - continue; - } - - auto posTracks_per_coll = posTracks.sliceByCached(perCollision, collision.globalIndex(), cache); - auto negTracks_per_coll = negTracks.sliceByCached(perCollision, collision.globalIndex(), cache); - - for (const auto& [pos, neg] : combinations(o2::soa::CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS - if (isPairOK(pos, neg, cut, tracks)) { - passed_pairIds.emplace_back(std::make_pair(pos.globalIndex(), neg.globalIndex())); - } - } - for (const auto& [pos1, pos2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ - if (isPairOK(pos1, pos2, cut, tracks)) { - passed_pairIds.emplace_back(std::make_pair(pos1.globalIndex(), pos2.globalIndex())); - } - } - for (const auto& [neg1, neg2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- - if (isPairOK(neg1, neg2, cut, tracks)) { - passed_pairIds.emplace_back(std::make_pair(neg1.globalIndex(), neg2.globalIndex())); - } - } - } // end of collision loop - - if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - for (const auto& pairId : passed_pairIds) { - auto t1 = tracks.rawIteratorAt(std::get<0>(pairId)); - auto t2 = tracks.rawIteratorAt(std::get<1>(pairId)); - // LOGF(info, "std::get<0>(pairId) = %d, std::get<1>(pairId) = %d, t1.globalIndex() = %d, t2.globalIndex() = %d", std::get<0>(pairId), std::get<1>(pairId), t1.globalIndex(), t2.globalIndex()); - - float n = 1.f; // include myself. - for (const auto& ambId1 : t1.ambiguousElectronsIds()) { - for (const auto& ambId2 : t2.ambiguousElectronsIds()) { - if (std::find(passed_pairIds.begin(), passed_pairIds.end(), std::make_pair(ambId1, ambId2)) != passed_pairIds.end()) { - n += 1.f; - } - } - } - map_weight[pairId] = 1.f / n; - } // end of passed_pairIds loop - } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - for (const auto& pairId : passed_pairIds) { - auto t1 = tracks.rawIteratorAt(std::get<0>(pairId)); - auto t2 = tracks.rawIteratorAt(std::get<1>(pairId)); - - float n = 1.f; // include myself. - for (const auto& ambId1 : t1.ambiguousMuonsIds()) { - for (const auto& ambId2 : t2.ambiguousMuonsIds()) { - if (std::find(passed_pairIds.begin(), passed_pairIds.end(), std::make_pair(ambId1, ambId2)) != passed_pairIds.end()) { - n += 1.f; - } - } - } - map_weight[pairId] = 1.f / n; - } // end of passed_pairIds loop - } - passed_pairIds.clear(); - passed_pairIds.shrink_to_fit(); - } - - std::unordered_map map_best_match_globalmuon; - - void processAnalysis(FilteredMyCollisions const& collisions, Types const&... args) - { - if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - auto electrons = std::get<0>(std::tie(args...)); - if (cfgApplyWeightTTCA) { - fillPairWeightMap(collisions, positive_electrons, negative_electrons, o2::aod::emprimaryelectron::emeventId, fDielectronCut, electrons); - } - runPairing(collisions, positive_electrons, negative_electrons, o2::aod::emprimaryelectron::emeventId, fDielectronCut, electrons); - } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - auto muons = std::get<0>(std::tie(args...)); - map_best_match_globalmuon = o2::aod::pwgem::dilepton::utils::emtrackutil::findBestMatchMap(muons, fDimuonCut); - if (cfgApplyWeightTTCA) { - fillPairWeightMap(collisions, positive_muons, negative_muons, o2::aod::emprimarymuon::emeventId, fDimuonCut, muons); - } - runPairing(collisions, positive_muons, negative_muons, o2::aod::emprimarymuon::emeventId, fDimuonCut, muons); - } - map_weight.clear(); - map_best_match_globalmuon.clear(); - } - PROCESS_SWITCH(DileptonProducer, processAnalysis, "run dilepton analysis", true); - - void processNorm(o2::aod::EMEventNormInfos const& collisions) - { - for (const auto& collision : collisions) { - if (collision.centFT0C() < eventcuts.cfgCentMin || eventcuts.cfgCentMax < collision.centFT0C()) { - continue; - } - - normTable(collision.selection_raw(), collision.rct_raw(), collision.posZint8(), collision.centFT0Muint8(), collision.centFT0Cuint8(), collision.centNTPVuint8() /*, collision.centNGlobaluint8()*/); - - } // end of collision loop - } - PROCESS_SWITCH(DileptonProducer, processNorm, "process normalization info", true); -}; - -#endif // PWGEM_DILEPTON_CORE_DILEPTONPRODUCER_H_ diff --git a/PWGEM/Dilepton/Core/DileptonSV.h b/PWGEM/Dilepton/Core/DileptonSV.h index 8296506a5a9..4a605e154bf 100644 --- a/PWGEM/Dilepton/Core/DileptonSV.h +++ b/PWGEM/Dilepton/Core/DileptonSV.h @@ -20,6 +20,7 @@ #include "PWGEM/Dilepton/Core/DielectronCut.h" #include "PWGEM/Dilepton/Core/DimuonCut.h" #include "PWGEM/Dilepton/Core/EMEventCut.h" +#include "PWGEM/Dilepton/DataModel/EvSelFlags.h" #include "PWGEM/Dilepton/DataModel/dileptonTables.h" #include "PWGEM/Dilepton/Utils/EMFwdTrack.h" #include "PWGEM/Dilepton/Utils/EMTrack.h" @@ -81,6 +82,7 @@ #include #include #include +#include #include #include #include @@ -126,17 +128,6 @@ struct DileptonSV { o2::framework::Configurable cfgQvecEstimator{"cfgQvecEstimator", 2, "FT0M:0, FT0A:1, FT0C:2, BTot:3, BPos:4, BNeg:5, FV0A:6"}; o2::framework::Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; - // for mixing - o2::framework::Configurable cfgOccupancyEstimator{"cfgOccupancyEstimator", 0, "FT0C:0, Track:1"}; - o2::framework::Configurable cfgEP2Estimator_for_Mix{"cfgEP2Estimator_for_Mix", 3, "FT0M:0, FT0A:1, FT0C:2, BTot:3, BPos:4, BNeg:5, FV0A:6"}; - o2::framework::Configurable cfgDoMix{"cfgDoMix", true, "flag for event mixing"}; - o2::framework::Configurable ndepth{"ndepth", 1000, "depth for event mixing"}; - o2::framework::Configurable ndiff_bc_mix{"ndiff_bc_mix", 594, "difference in global BC required in mixed events"}; - o2::framework::ConfigurableAxis ConfVtxBins{"ConfVtxBins", {o2::framework::VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; - o2::framework::ConfigurableAxis ConfCentBins{"ConfCentBins", {o2::framework::VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f, 999.f}, "Mixing bins - centrality"}; - o2::framework::ConfigurableAxis ConfEPBins{"ConfEPBins", {16, -M_PI / 2, +M_PI / 2}, "Mixing bins - event plane angle"}; - o2::framework::ConfigurableAxis ConfOccupancyBins{"ConfOccupancyBins", {o2::framework::VARIABLE_WIDTH, -1, 1e+10}, "Mixing bins - occupancy"}; - o2::framework::Configurable cfgApplyWeightTTCA{"cfgApplyWeightTTCA", false, "flag to apply weighting by 1/N"}; o2::framework::Configurable cfgPolarizationFrame{"cfgPolarizationFrame", 0, "frame of polarization. 0:CS, 1:HX, else:FATAL"}; @@ -144,8 +135,7 @@ struct DileptonSV { o2::framework::ConfigurableAxis ConfPtllBins{"ConfPtllBins", {o2::framework::VARIABLE_WIDTH, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00, 6.00, 7.00, 8.00, 9.00, 10.00}, "pTll bins for output histograms"}; o2::framework::ConfigurableAxis ConfDCAllBins{"ConfDCAllBins", {o2::framework::VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0}, "DCAll bins for output histograms"}; o2::framework::ConfigurableAxis ConfYllBins{"ConfYllBins", {1, -1.f, 1.f}, "yll bins for output histograms"}; // pair rapidity - o2::framework::ConfigurableAxis ConfLog10Chi2PCABins{"ConfLog10Chi2PCABins", {100, -10.f, 0.f}, "log10 of chi2PCA bins for output histograms"}; - o2::framework::ConfigurableAxis ConfDLBins{"ConfDLBins", {100, 0.f, 10.f}, "decay length bins for output histograms"}; + o2::framework::ConfigurableAxis ConfCPABins{"ConfCPABins", {o2::framework::VARIABLE_WIDTH, -1, -0.95, -0.9, -0.85, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.85, 0.9, 0.95, 1}, "cpa bins for output histograms"}; o2::framework::ConfigurableAxis ConfSPBins{"ConfSPBins", {200, -5, 5}, "SP bins for flow analysis"}; o2::framework::ConfigurableAxis ConfPolarizationCosThetaBins{"ConfPolarizationCosThetaBins", {20, -1.f, 1.f}, "cos(theta) bins for polarization analysis"}; @@ -154,14 +144,27 @@ struct DileptonSV { o2::framework::Configurable cfgNumBootstrapSamples{"cfgNumBootstrapSamples", 1, "Number of Bootstrap Samples"}; + struct : o2::framework::ConfigurableGroup { + std::string prefix = "mixingGroup"; + o2::framework::Configurable cfgOccupancyEstimator{"cfgOccupancyEstimator", 0, "FT0C:0, Track:1"}; + o2::framework::Configurable cfgEP2Estimator{"cfgEP2Estimator", 3, "FT0M:0, FT0A:1, FT0C:2, BTot:3, BPos:4, BNeg:5, FV0A:6"}; + o2::framework::Configurable cfgDoMix{"cfgDoMix", true, "flag for event mixing"}; + o2::framework::Configurable ndepth{"ndepth", 1000, "depth for event mixing"}; + o2::framework::Configurable ndiff_bc_mix{"ndiff_bc_mix", 594, "difference in global BC required in mixed events"}; + o2::framework::ConfigurableAxis ConfVtxBins{"ConfVtxBins", {20, -10.0f, 10.f}, "Mixing bins - z-vertex"}; + o2::framework::ConfigurableAxis ConfCentBins{"ConfCentBins", {o2::framework::VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f, 110.f}, "Mixing bins - centrality"}; + o2::framework::ConfigurableAxis ConfEPBins{"ConfEPBins", {1, -M_PI / 2, +M_PI / 2}, "Mixing bins - event plane angle"}; + o2::framework::ConfigurableAxis ConfOccupancyBins{"ConfOccupancyBins", {o2::framework::VARIABLE_WIDTH, -2, 1e+10}, "Mixing bins - occupancy"}; + } mixingGroup; + EMEventCut fEMEventCut; struct : o2::framework::ConfigurableGroup { std::string prefix = "eventcut_group"; o2::framework::Configurable cfgZvtxMin{"cfgZvtxMin", -10.f, "min. Zvtx"}; o2::framework::Configurable cfgZvtxMax{"cfgZvtxMax", +10.f, "max. Zvtx"}; - o2::framework::Configurable cfgRequireSel8{"cfgRequireSel8", true, "require sel8 in event cut"}; + o2::framework::Configurable cfgRequireSel8{"cfgRequireSel8", false, "require sel8 in event cut"}; o2::framework::Configurable cfgRequireFT0AND{"cfgRequireFT0AND", true, "require FT0AND in event cut"}; - o2::framework::Configurable cfgRequireNoTFB{"cfgRequireNoTFB", false, "require No time frame border in event cut"}; + o2::framework::Configurable cfgRequireNoTFB{"cfgRequireNoTFB", true, "require No time frame border in event cut"}; o2::framework::Configurable cfgRequireNoITSROFB{"cfgRequireNoITSROFB", false, "require no ITS readout frame border in event cut"}; o2::framework::Configurable cfgRequireNoSameBunchPileup{"cfgRequireNoSameBunchPileup", false, "require no same bunch pileup in event cut"}; o2::framework::Configurable cfgRequireVertexITSTPC{"cfgRequireVertexITSTPC", false, "require Vertex ITSTPC in event cut"}; // ITS-TPC matched track contributes PV. @@ -202,13 +205,12 @@ struct DileptonSV { o2::framework::Configurable cfg_max_pair_y{"cfg_max_pair_y", +0.8, "max pair rapidity"}; o2::framework::Configurable cfg_min_pair_dca3d{"cfg_min_pair_dca3d", 0.0, "min pair dca3d in sigma"}; o2::framework::Configurable cfg_max_pair_dca3d{"cfg_max_pair_dca3d", 1e+10, "max pair dca3d in sigma"}; - o2::framework::Configurable cfg_apply_phiv{"cfg_apply_phiv", true, "flag to apply phiv cut"}; + o2::framework::Configurable cfg_apply_phiv{"cfg_apply_phiv", false, "flag to apply phiv cut"}; o2::framework::Configurable cfg_phiv_slope{"cfg_phiv_slope", 0.0185, "slope for m vs. phiv"}; o2::framework::Configurable cfg_phiv_intercept{"cfg_phiv_intercept", -0.0280, "intercept for m vs. phiv"}; o2::framework::Configurable cfg_min_phiv{"cfg_min_phiv", 0.0, "min phiv (constant)"}; o2::framework::Configurable cfg_max_phiv{"cfg_max_phiv", 3.2, "max phiv (constant)"}; o2::framework::Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut at PV"}; - o2::framework::Configurable cfg_apply_detadphiPosition{"cfg_apply_detadphiPosition", false, "flag to apply deta-dphi elliptic cut at ref. radius"}; o2::framework::Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 electrons (elliptic cut)"}; o2::framework::Configurable cfg_min_dphi{"cfg_min_dphi", 0.2, "min dphi between 2 electrons (elliptic cut)"}; o2::framework::Configurable cfg_min_opang{"cfg_min_opang", 0.0, "min opening angle"}; @@ -221,7 +223,7 @@ struct DileptonSV { o2::framework::Configurable cfg_apply_cuts_from_prefilter_derived{"cfg_apply_cuts_from_prefilter_derived", false, "flag to apply prefilter set in derived data"}; o2::framework::Configurable cfg_prefilter_bits_derived{"cfg_prefilter_bits_derived", 0, "prefilter bits [kNone : 0, kMee : 1, kPhiV : 2, kSplitOrMergedTrackLS : 4, kSplitOrMergedTrackULS : 8] Please consider logical-OR among them."}; // see PairUtilities.h - o2::framework::Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.2, "min pT for single track"}; + o2::framework::Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.8, "min pT for single track"}; o2::framework::Configurable cfg_max_pt_track{"cfg_max_pt_track", 1e+10, "max pT for single track"}; o2::framework::Configurable cfg_min_eta_track{"cfg_min_eta_track", -0.8, "min eta for single track"}; o2::framework::Configurable cfg_max_eta_track{"cfg_max_eta_track", +0.8, "max eta for single track"}; @@ -270,8 +272,8 @@ struct DileptonSV { // configuration for PID ML // o2::framework::Configurable> onnxFileNames{"onnxFileNames", std::vector{"filename"}, "ONNX file names for each bin (if not from CCDB full path)"}; // o2::framework::Configurable> onnxPathsCCDB{"onnxPathsCCDB", std::vector{"path"}, "Paths of models on CCDB"}; - o2::framework::Configurable> binsMLPID{"binsMLPID", std::vector{0.1, 0.15, 0.2, 0.25, 0.4, 0.8, 1.6, 2.0, 20.f}, "Bin limits for ML application"}; - o2::framework::Configurable> cutsMLPID{"cutsMLPID", std::vector{0.97, 0.97, 0.97, 0.8, 0.95, 0.95, 0.8, 0.8}, "ML cuts per bin"}; + o2::framework::Configurable> binsMLPID{"binsMLPID", std::vector{0.1, 0.15, 0.2, 0.25, 0.4, 0.8, 1.6, 2.0, 4.0, 20.f}, "Bin limits for ML application"}; + o2::framework::Configurable> cutsMLPID{"cutsMLPID", std::vector{0.97, 0.97, 0.97, 0.8, 0.95, 0.95, 0.8, 0.8, 0.8}, "ML cuts per bin"}; // o2::framework::Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature"}, "Names of ML model input features"}; // o2::framework::Configurable nameBinningFeature{"nameBinningFeature", "pt", "Names of ML model binning feature"}; // o2::framework::Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; @@ -303,7 +305,7 @@ struct DileptonSV { o2::framework::Configurable cfg_prefilter_bits_derived{"cfg_prefilter_bits_derived", 0, "prefilter bits [kNone : 0, kSplitOrMergedTrackLS : 4, kSplitOrMergedTrackULS : 8] Please consider logical-OR among them."}; // see PairUtilities.h o2::framework::Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; - o2::framework::Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.2, "min pT for single track"}; + o2::framework::Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.8, "min pT for single track"}; o2::framework::Configurable cfg_max_pt_track{"cfg_max_pt_track", 1e+10, "max pT for single track"}; o2::framework::Configurable cfg_min_eta_track{"cfg_min_eta_track", -4.0, "min eta for single track"}; o2::framework::Configurable cfg_max_eta_track{"cfg_max_eta_track", -2.5, "max eta for single track"}; @@ -369,7 +371,6 @@ struct DileptonSV { o2::vertexing::FwdDCAFitterN<2> mFwdDCAFitter; o2::aod::rctsel::RCTFlagsChecker rctChecker; - // o2::ccdb::CcdbApi ccdbApi; o2::framework::Service ccdb; int mRunNumber{0}; float d_bz{0}; @@ -410,77 +411,77 @@ struct DileptonSV { ccdb->setFatalWhenNull(false); rctChecker.init(eventcuts.cfgRCTLabel.value, eventcuts.cfgCheckZDC.value, eventcuts.cfgTreatLimitedAcceptanceAsBad.value); - if (ConfVtxBins.value[0] == o2::framework::VARIABLE_WIDTH) { - zvtx_bin_edges = std::vector(ConfVtxBins.value.begin(), ConfVtxBins.value.end()); + if (mixingGroup.ConfVtxBins.value[0] == o2::framework::VARIABLE_WIDTH) { + zvtx_bin_edges = std::vector(mixingGroup.ConfVtxBins.value.begin(), mixingGroup.ConfVtxBins.value.end()); zvtx_bin_edges.erase(zvtx_bin_edges.begin()); - for (const auto& edge : zvtx_bin_edges) { - LOGF(info, "o2::framework::VARIABLE_WIDTH: zvtx_bin_edges = %f", edge); - } + // for (const auto& edge : zvtx_bin_edges) { + // LOGF(info, "o2::framework::VARIABLE_WIDTH: zvtx_bin_edges = %f", edge); + // } } else { - int nbins = static_cast(ConfVtxBins.value[0]); - float xmin = static_cast(ConfVtxBins.value[1]); - float xmax = static_cast(ConfVtxBins.value[2]); + int nbins = static_cast(mixingGroup.ConfVtxBins.value[0]); + float xmin = static_cast(mixingGroup.ConfVtxBins.value[1]); + float xmax = static_cast(mixingGroup.ConfVtxBins.value[2]); zvtx_bin_edges.resize(nbins + 1); for (int i = 0; i < nbins + 1; i++) { zvtx_bin_edges[i] = (xmax - xmin) / (nbins)*i + xmin; - LOGF(info, "FIXED_WIDTH: zvtx_bin_edges[%d] = %f", i, zvtx_bin_edges[i]); + // LOGF(info, "FIXED_WIDTH: zvtx_bin_edges[%d] = %f", i, zvtx_bin_edges[i]); } } - if (ConfCentBins.value[0] == o2::framework::VARIABLE_WIDTH) { - cent_bin_edges = std::vector(ConfCentBins.value.begin(), ConfCentBins.value.end()); + if (mixingGroup.ConfCentBins.value[0] == o2::framework::VARIABLE_WIDTH) { + cent_bin_edges = std::vector(mixingGroup.ConfCentBins.value.begin(), mixingGroup.ConfCentBins.value.end()); cent_bin_edges.erase(cent_bin_edges.begin()); - for (const auto& edge : cent_bin_edges) { - LOGF(info, "o2::framework::VARIABLE_WIDTH: cent_bin_edges = %f", edge); - } + // for (const auto& edge : cent_bin_edges) { + // LOGF(info, "o2::framework::VARIABLE_WIDTH: cent_bin_edges = %f", edge); + // } } else { - int nbins = static_cast(ConfCentBins.value[0]); - float xmin = static_cast(ConfCentBins.value[1]); - float xmax = static_cast(ConfCentBins.value[2]); + int nbins = static_cast(mixingGroup.ConfCentBins.value[0]); + float xmin = static_cast(mixingGroup.ConfCentBins.value[1]); + float xmax = static_cast(mixingGroup.ConfCentBins.value[2]); cent_bin_edges.resize(nbins + 1); for (int i = 0; i < nbins + 1; i++) { cent_bin_edges[i] = (xmax - xmin) / (nbins)*i + xmin; - LOGF(info, "FIXED_WIDTH: cent_bin_edges[%d] = %f", i, cent_bin_edges[i]); + // LOGF(info, "FIXED_WIDTH: cent_bin_edges[%d] = %f", i, cent_bin_edges[i]); } } - if (ConfEPBins.value[0] == o2::framework::VARIABLE_WIDTH) { - ep_bin_edges = std::vector(ConfEPBins.value.begin(), ConfEPBins.value.end()); + if (mixingGroup.ConfEPBins.value[0] == o2::framework::VARIABLE_WIDTH) { + ep_bin_edges = std::vector(mixingGroup.ConfEPBins.value.begin(), mixingGroup.ConfEPBins.value.end()); ep_bin_edges.erase(ep_bin_edges.begin()); - for (const auto& edge : ep_bin_edges) { - LOGF(info, "o2::framework::VARIABLE_WIDTH: ep_bin_edges = %f", edge); - } + // for (const auto& edge : ep_bin_edges) { + // LOGF(info, "o2::framework::VARIABLE_WIDTH: ep_bin_edges = %f", edge); + // } } else { - int nbins = static_cast(ConfEPBins.value[0]); - float xmin = static_cast(ConfEPBins.value[1]); - float xmax = static_cast(ConfEPBins.value[2]); + int nbins = static_cast(mixingGroup.ConfEPBins.value[0]); + float xmin = static_cast(mixingGroup.ConfEPBins.value[1]); + float xmax = static_cast(mixingGroup.ConfEPBins.value[2]); ep_bin_edges.resize(nbins + 1); for (int i = 0; i < nbins + 1; i++) { ep_bin_edges[i] = (xmax - xmin) / (nbins)*i + xmin; - LOGF(info, "FIXED_WIDTH: ep_bin_edges[%d] = %f", i, ep_bin_edges[i]); + // LOGF(info, "FIXED_WIDTH: ep_bin_edges[%d] = %f", i, ep_bin_edges[i]); } } - LOGF(info, "cfgOccupancyEstimator = %d", cfgOccupancyEstimator.value); - if (ConfOccupancyBins.value[0] == o2::framework::VARIABLE_WIDTH) { - occ_bin_edges = std::vector(ConfOccupancyBins.value.begin(), ConfOccupancyBins.value.end()); + // LOGF(info, "mixingGroup.cfgOccupancyEstimator = %d", mixingGroup.cfgOccupancyEstimator.value); + if (mixingGroup.ConfOccupancyBins.value[0] == o2::framework::VARIABLE_WIDTH) { + occ_bin_edges = std::vector(mixingGroup.ConfOccupancyBins.value.begin(), mixingGroup.ConfOccupancyBins.value.end()); occ_bin_edges.erase(occ_bin_edges.begin()); - for (const auto& edge : occ_bin_edges) { - LOGF(info, "o2::framework::VARIABLE_WIDTH: occ_bin_edges = %f", edge); - } + // for (const auto& edge : occ_bin_edges) { + // LOGF(info, "o2::framework::VARIABLE_WIDTH: occ_bin_edges = %f", edge); + // } } else { - int nbins = static_cast(ConfOccupancyBins.value[0]); - float xmin = static_cast(ConfOccupancyBins.value[1]); - float xmax = static_cast(ConfOccupancyBins.value[2]); + int nbins = static_cast(mixingGroup.ConfOccupancyBins.value[0]); + float xmin = static_cast(mixingGroup.ConfOccupancyBins.value[1]); + float xmax = static_cast(mixingGroup.ConfOccupancyBins.value[2]); occ_bin_edges.resize(nbins + 1); for (int i = 0; i < nbins + 1; i++) { occ_bin_edges[i] = (xmax - xmin) / (nbins)*i + xmin; - LOGF(info, "FIXED_WIDTH: occ_bin_edges[%d] = %f", i, occ_bin_edges[i]); + // LOGF(info, "FIXED_WIDTH: occ_bin_edges[%d] = %f", i, occ_bin_edges[i]); } } - emh_pos = new TEMH(ndepth); - emh_neg = new TEMH(ndepth); + emh_pos = new TEMH(mixingGroup.ndepth); + emh_neg = new TEMH(mixingGroup.ndepth); DefineEMEventCut(); addhistograms(); @@ -494,7 +495,12 @@ struct DileptonSV { leptonM2 = o2::constants::physics::MassMuon; } - fRegistry.add("Pair/mix/hDiffBC", "diff. global BC in mixed event;|BC_{current} - BC_{mixed}|", o2::framework::HistType::kTH1D, {{10001, -0.5, 10000.5}}, true); + fRegistry.add("Event/hDiffBC", "diff. global BC in mixed event;|BC_{current} - BC_{mixed}|", o2::framework::HistType::kTH1D, {{10001, -0.5, 10000.5}}, false); + const o2::framework::AxisSpec axis_mix_zvtx{mixingGroup.ConfVtxBins, "Z_{vtx} (cm)"}; + const o2::framework::AxisSpec axis_mix_cent{mixingGroup.ConfCentBins, "centrality (%)"}; + const o2::framework::AxisSpec axis_mix_ep2{mixingGroup.ConfEPBins, "event plane of 2nd harmonics (rad.)"}; + const o2::framework::AxisSpec axis_mix_occ{mixingGroup.ConfOccupancyBins, "occupancy"}; + fRegistry.add("Event/hsMixCounter", "mixed event counter", o2::framework::HistType::kTHnSparseD, {axis_mix_zvtx, axis_mix_cent, axis_mix_ep2, axis_mix_occ}, false); if (doprocessTriggerAnalysis) { LOGF(info, "Trigger analysis is enabled. Desired trigger name = %s", zorroGroup.cfg_swt_name.value.data()); @@ -648,13 +654,11 @@ struct DileptonSV { const o2::framework::AxisSpec axis_pt{ConfPtllBins, pair_pt_axis_title}; const o2::framework::AxisSpec axis_dca{ConfDCAllBins, pair_dca_axis_title}; const o2::framework::AxisSpec axis_y{ConfYllBins, pair_y_axis_title}; - const o2::framework::AxisSpec axis_chi2PCA{ConfLog10Chi2PCABins, "log_{10}(#chi^{2}_{PCA})"}; - const o2::framework::AxisSpec axis_dl{ConfDLBins, "decay length (#sigma)"}; + const o2::framework::AxisSpec axis_cpa{ConfCPABins, "cos(#theta_{p})"}; if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kQC)) { - fRegistry.add("Pair/same/uls/hs", "dilepton", o2::framework::HistType::kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_chi2PCA, axis_dl}, true); - fRegistry.add("Pair/same/uls/hDeltaEtaDeltaPhi", "#Delta#eta-#Delta#varphi between 2 tracks;#Delta#varphi (rad.);#Delta#eta;", o2::framework::HistType::kTH2D, {{180, -M_PI, M_PI}, {400, -2, +2}}, true); - fRegistry.add("Pair/same/uls/hDeltaEtaDeltaPhiPos", Form("#Delta#eta-#Delta#varphi* between 2 tracks at r_{xy} = %3.2f m;#Delta#varphi* (rad.);#Delta#eta;", dielectroncuts.cfgRefR.value), o2::framework::HistType::kTH2D, {{180, -M_PI, M_PI}, {400, -2, +2}}, true); + fRegistry.add("Pair/same/uls/hs", "dilepton", o2::framework::HistType::kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_cpa}, true); + fRegistry.add("Pair/same/uls/hDeltaEtaDeltaPhi", "#Delta#eta-#Delta#varphi between 2 tracks;#Delta#varphi (rad.);#Delta#eta;", o2::framework::HistType::kTH2D, {{360, -M_PI, M_PI}, {400, -2, +2}}, true); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.add("Pair/same/uls/hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", o2::framework::HistType::kTH2D, {{90, 0, M_PI}, {100, 0.0f, 1.0f}}, true); // phiv is only for dielectron @@ -709,7 +713,7 @@ struct DileptonSV { const o2::framework::AxisSpec axis_cos_theta{ConfPolarizationCosThetaBins, Form("cos(#theta^{%s})", frameName.data())}; const o2::framework::AxisSpec axis_phi{ConfPolarizationPhiBins, Form("#varphi^{%s} (rad.)", frameName.data())}; const o2::framework::AxisSpec axis_quadmom{ConfPolarizationQuadMomBins, Form("#frac{3 cos^{2}(#theta^{%s}) -1}{2}", frameName.data())}; - fRegistry.add("Pair/same/uls/hs", "dilepton", o2::framework::HistType::kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_cos_theta, axis_phi, axis_quadmom}, true); + fRegistry.add("Pair/same/uls/hs", "dilepton", o2::framework::HistType::kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_cos_theta, axis_phi, axis_quadmom, axis_cpa}, true); fRegistry.addClone("Pair/same/uls/", "Pair/same/lspp/"); fRegistry.addClone("Pair/same/uls/", "Pair/same/lsmm/"); @@ -760,8 +764,8 @@ struct DileptonSV { } else { o2::aod::pwgem::dilepton::utils::eventhistogram::addEventHistograms<-1>(&fRegistry); } - fRegistry.add("Event/before/hEP2_CentFT0C_forMix", Form("2nd harmonics event plane for mix;centrality FT0C (%%);#Psi_{2}^{%s} (rad.)", qvec_det_names[cfgEP2Estimator_for_Mix].data()), o2::framework::HistType::kTH2F, {{110, 0, 110}, {180, -M_PI_2, +M_PI_2}}, false); - fRegistry.add("Event/after/hEP2_CentFT0C_forMix", Form("2nd harmonics event plane for mix;centrality FT0C (%%);#Psi_{2}^{%s} (rad.)", qvec_det_names[cfgEP2Estimator_for_Mix].data()), o2::framework::HistType::kTH2F, {{110, 0, 110}, {180, -M_PI_2, +M_PI_2}}, false); + fRegistry.add("Event/before/hEP2_CentFT0C_forMix", Form("2nd harmonics event plane for mix;centrality FT0C (%%);#Psi_{2}^{%s} (rad.)", qvec_det_names[mixingGroup.cfgEP2Estimator].data()), o2::framework::HistType::kTH2F, {{110, 0, 110}, {180, -M_PI_2, +M_PI_2}}, false); + fRegistry.add("Event/after/hEP2_CentFT0C_forMix", Form("2nd harmonics event plane for mix;centrality FT0C (%%);#Psi_{2}^{%s} (rad.)", qvec_det_names[mixingGroup.cfgEP2Estimator].data()), o2::framework::HistType::kTH2F, {{110, 0, 110}, {180, -M_PI_2, +M_PI_2}}, false); } void DefineEMEventCut() @@ -797,14 +801,10 @@ struct DileptonSV { fDielectronCut.SetPairDCARange(dielectroncuts.cfg_min_pair_dca3d, dielectroncuts.cfg_max_pair_dca3d); // in sigma fDielectronCut.SetMaxMeePhiVDep([&](float phiv) { return dielectroncuts.cfg_phiv_intercept + phiv * dielectroncuts.cfg_phiv_slope; }, dielectroncuts.cfg_min_phiv, dielectroncuts.cfg_max_phiv); fDielectronCut.ApplyPhiV(dielectroncuts.cfg_apply_phiv); - fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, dielectroncuts.cfg_apply_detadphiPosition, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); + fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, false, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); fDielectronCut.SetPairOpAng(dielectroncuts.cfg_min_opang, dielectroncuts.cfg_max_opang); // fDielectronCut.SetRequireDifferentSides(dielectroncuts.cfg_require_diff_sides); - if (dielectroncuts.cfg_apply_detadphi && dielectroncuts.cfg_apply_detadphiPosition) { - LOG(fatal) << "cfg_apply_detadphi and cfg_apply_detadphiPosition cannot be used simultaneously. Please select only one."; - } - // for track fDielectronCut.SetTrackPtRange(dielectroncuts.cfg_min_pt_track, dielectroncuts.cfg_max_pt_track); fDielectronCut.SetTrackEtaRange(dielectroncuts.cfg_min_eta_track, dielectroncuts.cfg_max_eta_track); @@ -991,7 +991,7 @@ struct DileptonSV { trackParCov0.getPxPyPzGlo(pvec0); trackParCov1.getPxPyPzGlo(pvec1); std::array momDilepton = {pvec0[0] + pvec1[0], pvec0[1] + pvec1[1], pvec0[2] + pvec1[2]}; - candidate.cpa = RecoDecay::cpa(pvertex, secondaryVertex, momDilepton); + candidate.cpa = std::clamp(RecoDecay::cpa(pvertex, secondaryVertex, momDilepton), -1.0, std::nextafter(1.0, 0.0)); candidate.lxy = std::sqrt(std::pow(secondaryVertex[0] - collision.posX(), 2) + std::pow(secondaryVertex[1] - collision.posY(), 2)); candidate.lz = secondaryVertex[2] - collision.posZ(); @@ -1038,7 +1038,7 @@ struct DileptonSV { auto trackParCov0 = mFwdDCAFitter.getTrack(0); auto trackParCov1 = mFwdDCAFitter.getTrack(1); std::array momDilepton = {static_cast(trackParCov0.getPx() + trackParCov1.getPx()), static_cast(trackParCov0.getPy() + trackParCov1.getPy()), static_cast(trackParCov0.getPz() + trackParCov1.getPz())}; - candidate.cpa = RecoDecay::cpa(pvertex, secondaryVertex, momDilepton); + candidate.cpa = std::clamp(RecoDecay::cpa(pvertex, secondaryVertex, momDilepton), -1.0, std::nextafter(1.0, 0.0)); candidate.lxy = std::sqrt(std::pow(secondaryVertex[0] - collision.posX(), 2) + std::pow(secondaryVertex[1] - collision.posY(), 2)); candidate.lz = secondaryVertex[2] - collision.posZ(); @@ -1110,29 +1110,15 @@ struct DileptonSV { candidate.phi2 = t2.phi(); } - // if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - // auto trackParCov1 = getTrackParCov(t1); - // auto trackParCov2 = getTrackParCov(t2); - // if(!findSV(collision, trackParCov1, trackParCov2, candidate)){ - // return false; - // } - // } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - // auto trackParCov1 = o2::aod::fwdtrackutils::getTrackParCovFwd(t1, t1); - // auto trackParCov2 = o2::aod::fwdtrackutils::getTrackParCovFwd(t2, t2); - // if(!findSVFwd(collision, trackParCov1, trackParCov2, candidate)){ - // return false; - // } - // } - - // if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - // if (!cut.IsSelectedPair(t1, t2)) { - // return false; - // } - // } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { - // if (!cut.IsSelectedPair(t1, t2)) { - // return false; - // } - // } + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (!cut.IsSelectedPair(t1, t2)) { + return false; + } + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + if (!cut.IsSelectedPair(t1, t2)) { + return false; + } + } float weight = 1.f; if constexpr (ev_id == 0) { @@ -1165,32 +1151,23 @@ struct DileptonSV { float dphi = t1.sign() * v1.Pt() > t2.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); dphi = RecoDecay::constrainAngle(dphi, -M_PI, 1U); // -pi - +pi - float phiPosition1 = RecoDecay::constrainAngle(t1.phi() + std::asin(t1.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * t1.pt())), 0, 1U); // 0-2pi - float phiPosition2 = RecoDecay::constrainAngle(t2.phi() + std::asin(t2.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * t2.pt())), 0, 1U); // 0-2pi - float dphiPosition = t1.sign() * v1.Pt() > t2.sign() * v2.Pt() ? phiPosition1 - phiPosition2 : phiPosition2 - phiPosition1; - dphiPosition = RecoDecay::constrainAngle(dphiPosition, -M_PI, 1U); // -pi - +pi - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), d_bz); - // float opAng = o2::aod::pwgem::dilepton::utils::pairutil::getOpeningAngle(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz()); if (t1.sign() * t2.sign() < 0) { // ULS - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), std::log10(candidate.chi2PCA), candidate.lxyz / candidate.lxyzErr, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), candidate.cpa, weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hDeltaEtaDeltaPhi"), dphi, deta, weight); - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hDeltaEtaDeltaPhiPos"), dphiPosition, deta, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hMvsPhiV"), phiv, v12.M(), weight); } } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), std::log10(candidate.chi2PCA), candidate.lxyz / candidate.lxyzErr, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), candidate.cpa, weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hDeltaEtaDeltaPhi"), dphi, deta, weight); - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hDeltaEtaDeltaPhiPos"), dphiPosition, deta, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hMvsPhiV"), phiv, v12.M(), weight); } } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), std::log10(candidate.chi2PCA), candidate.lxyz / candidate.lxyzErr, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), candidate.cpa, weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hDeltaEtaDeltaPhi"), dphi, deta, weight); - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hDeltaEtaDeltaPhiPos"), dphiPosition, deta, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hMvsPhiV"), phiv, v12.M(), weight); } @@ -1238,8 +1215,6 @@ struct DileptonSV { }; if constexpr (ev_id == 0) { - // LOGF(info, "collision.centFT0C() = %f, collision.trackOccupancyInTimeRange() = %d, getSPresolution = %f", collision.centFT0C(), collision.trackOccupancyInTimeRange(), getSPresolution(collision.centFT0C(), collision.trackOccupancyInTimeRange())); - float sp = RecoDecay::dotProd(std::array{static_cast(std::cos(nmod * v12.Phi())), static_cast(std::sin(nmod * v12.Phi()))}, qvectors[nmod][cfgQvecEstimator]) / getSPresolution(collision.centFT0C(), collision.trackOccupancyInTimeRange()); if (t1.sign() * t2.sign() < 0) { // ULS fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), sp, weight); @@ -1273,11 +1248,11 @@ struct DileptonSV { float quadmom = (3.f * std::pow(cos_thetaPol, 2) - 1.f) / 2.f; if (t1.sign() * t2.sign() < 0) { // ULS - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), cos_thetaPol, phiPol, quadmom, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), cos_thetaPol, phiPol, quadmom, candidate.cpa, weight); } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), cos_thetaPol, phiPol, quadmom, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), cos_thetaPol, phiPol, quadmom, candidate.cpa, weight); } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- - fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), cos_thetaPol, phiPol, quadmom, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), cos_thetaPol, phiPol, quadmom, candidate.cpa, weight); } } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kHFll)) { float dphi = v1.Phi() - v2.Phi(); @@ -1374,7 +1349,7 @@ struct DileptonSV { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { if (std::find(used_trackIds_per_col.begin(), used_trackIds_per_col.end(), t1.globalIndex()) == used_trackIds_per_col.end()) { used_trackIds_per_col.emplace_back(t1.globalIndex()); - if (cfgDoMix) { + if (mixingGroup.cfgDoMix) { if (t1.sign() > 0) { emh_pos->AddTrackToEventPool(key_df_collision, o2::aod::pwgem::dilepton::utils::EMTrack(candidate.pt1, candidate.eta1, candidate.phi1, leptonM1, t1.sign(), t1.dcaXY(), t1.dcaZ(), t1.cYY(), t1.cZY(), t1.cZZ())); // emh_pos->AddTrackToEventPool(key_df_collision, o2::aod::pwgem::dilepton::utils::EMTrackWithCov(t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.dcaXY(), t1.dcaZ(), t1.cYY(), t1.cZY(), t1.cZZ(), @@ -1394,7 +1369,7 @@ struct DileptonSV { } if (std::find(used_trackIds_per_col.begin(), used_trackIds_per_col.end(), t2.globalIndex()) == used_trackIds_per_col.end()) { used_trackIds_per_col.emplace_back(t2.globalIndex()); - if (cfgDoMix) { + if (mixingGroup.cfgDoMix) { if (t2.sign() > 0) { emh_pos->AddTrackToEventPool(key_df_collision, o2::aod::pwgem::dilepton::utils::EMTrack(candidate.pt2, candidate.eta2, candidate.phi2, leptonM2, t2.sign(), t2.dcaXY(), t2.dcaZ(), t2.cYY(), t2.cZY(), t2.cZZ())); // emh_pos->AddTrackToEventPool(key_df_collision, o2::aod::pwgem::dilepton::utils::EMTrackWithCov(t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.dcaXY(), t2.dcaZ(), t2.cYY(), t2.cZY(), t2.cZZ(), @@ -1415,7 +1390,7 @@ struct DileptonSV { } else if (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { if (std::find(used_trackIds_per_col.begin(), used_trackIds_per_col.end(), t1.globalIndex()) == used_trackIds_per_col.end()) { used_trackIds_per_col.emplace_back(t1.globalIndex()); - if (cfgDoMix) { + if (mixingGroup.cfgDoMix) { if (t1.sign() > 0) { emh_pos->AddTrackToEventPool(key_df_collision, o2::aod::pwgem::dilepton::utils::EMFwdTrack(candidate.pt1, candidate.eta1, candidate.phi1, leptonM1, t1.sign(), t1.fwdDcaX(), t1.fwdDcaY(), t1.cXX(), t1.cXY(), t1.cYY())); // emh_pos->AddTrackToEventPool(key_df_collision, o2::aod::pwgem::dilepton::utils::EMFwdTrackWithCov(t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.fwdDcaX(), t1.fwdDcaY(), t1.cXX(), t1.cXY(), t1.cYY(), @@ -1436,7 +1411,7 @@ struct DileptonSV { } if (std::find(used_trackIds_per_col.begin(), used_trackIds_per_col.end(), t2.globalIndex()) == used_trackIds_per_col.end()) { used_trackIds_per_col.emplace_back(t2.globalIndex()); - if (cfgDoMix) { + if (mixingGroup.cfgDoMix) { if (t2.sign() > 0) { emh_pos->AddTrackToEventPool(key_df_collision, o2::aod::pwgem::dilepton::utils::EMFwdTrack(candidate.pt2, candidate.eta2, candidate.phi2, leptonM2, t2.sign(), t2.fwdDcaX(), t2.fwdDcaY(), t2.cXX(), t2.cXY(), t2.cYY())); // emh_pos->AddTrackToEventPool(key_df_collision, o2::aod::pwgem::dilepton::utils::EMFwdTrackWithCov(t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.fwdDcaX(), t2.fwdDcaY(), t2.cXX(), t2.cXY(), t2.cYY(), @@ -1473,9 +1448,6 @@ struct DileptonSV { o2::framework::expressions::Filter prefilter_derived_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter_derived.node() && dielectroncuts.cfg_prefilter_bits_derived.node() >= static_cast(1), ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULSAtRefR))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULSAtRefR))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) <= static_cast(0), true), o2::aod::emprimaryelectron::pfbderived >= static_cast(0)); @@ -1535,7 +1507,7 @@ struct DileptonSV { std::array q2bneg = {collision.q2xbneg(), collision.q2ybneg()}; std::array q2fv0a = {collision.q2xfv0a(), collision.q2yfv0a()}; const float eventplanes_2_for_mix[7] = {collision.ep2ft0m(), collision.ep2ft0a(), collision.ep2ft0c(), collision.ep2btot(), collision.ep2bpos(), collision.ep2bneg(), collision.ep2fv0a()}; - float ep2 = eventplanes_2_for_mix[cfgEP2Estimator_for_Mix]; + float ep2 = eventplanes_2_for_mix[mixingGroup.cfgEP2Estimator]; std::vector>> qvectors = { {{999.f, 999.f}, {999.f, 999.f}, {999.f, 999.f}, {999.f, 999.f}, {999.f, 999.f}, {999.f, 999.f}, {999.f, 999.f}}, // 0th harmonics @@ -1639,7 +1611,7 @@ struct DileptonSV { used_trackIds_per_col.clear(); used_trackIds_per_col.shrink_to_fit(); - if (!cfgDoMix || !(nuls > 0 || nlspp > 0 || nlsmm > 0)) { + if (!mixingGroup.cfgDoMix || !(nuls > 0 || nlspp > 0 || nlsmm > 0)) { continue; } @@ -1665,15 +1637,8 @@ struct DileptonSV { epbin = static_cast(ep_bin_edges.size()) - 2; } - int occbin = -1; - if (cfgOccupancyEstimator == 0) { - occbin = lower_bound(occ_bin_edges.begin(), occ_bin_edges.end(), collision.ft0cOccupancyInTimeRange()) - occ_bin_edges.begin() - 1; - } else if (cfgOccupancyEstimator == 1) { - occbin = lower_bound(occ_bin_edges.begin(), occ_bin_edges.end(), collision.trackOccupancyInTimeRange()) - occ_bin_edges.begin() - 1; - } else { - occbin = lower_bound(occ_bin_edges.begin(), occ_bin_edges.end(), collision.ft0cOccupancyInTimeRange()) - occ_bin_edges.begin() - 1; - } - + float occupancy = std::array{collision.ft0cOccupancyInTimeRange(), static_cast(collision.trackOccupancyInTimeRange())}[mixingGroup.cfgOccupancyEstimator]; + int occbin = lower_bound(occ_bin_edges.begin(), occ_bin_edges.end(), occupancy) - occ_bin_edges.begin() - 1; if (occbin < 0) { occbin = 0; } else if (static_cast(occ_bin_edges.size()) - 2 < occbin) { @@ -1702,10 +1667,11 @@ struct DileptonSV { auto globalBC_mix = map_mixed_eventId_to_globalBC[mix_dfId_collisionId]; uint64_t diffBC = std::max(collision.globalBC(), globalBC_mix) - std::min(collision.globalBC(), globalBC_mix); - fRegistry.fill(HIST("Pair/mix/hDiffBC"), diffBC); - if (diffBC < ndiff_bc_mix) { + fRegistry.fill(HIST("Event/hDiffBC"), diffBC); + if (diffBC < mixingGroup.ndiff_bc_mix) { continue; } + fRegistry.fill(HIST("Event/hsMixCounter"), collision.posZ(), centrality, ep2, occupancy); auto posTracks_from_event_pool = emh_pos->GetTracksPerCollision(mix_dfId_collisionId); auto negTracks_from_event_pool = emh_neg->GetTracksPerCollision(mix_dfId_collisionId); diff --git a/PWGEM/Dilepton/Core/DileptonSVMC.h b/PWGEM/Dilepton/Core/DileptonSVMC.h new file mode 100644 index 00000000000..d5e8743e507 --- /dev/null +++ b/PWGEM/Dilepton/Core/DileptonSVMC.h @@ -0,0 +1,2905 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// ======================== +// +// This code runs loop over leptons in MC +// Please write to: daiki.sekihata@cern.ch + +#ifndef PWGEM_DILEPTON_CORE_DILEPTONSVMC_H_ +#define PWGEM_DILEPTON_CORE_DILEPTONSVMC_H_ + +#include "PWGEM/Dilepton/Core/DielectronCut.h" +#include "PWGEM/Dilepton/Core/DimuonCut.h" +#include "PWGEM/Dilepton/Core/EMEventCut.h" +#include "PWGEM/Dilepton/DataModel/EvSelFlags.h" +#include "PWGEM/Dilepton/DataModel/dileptonTables.h" +#include "PWGEM/Dilepton/Utils/EMTrackUtilities.h" +#include "PWGEM/Dilepton/Utils/EventHistograms.h" +#include "PWGEM/Dilepton/Utils/MCUtilities.h" +#include "PWGEM/Dilepton/Utils/PairUtilities.h" + +#include "Common/CCDB/RCTSelectionFlags.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/fwdtrackUtilities.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using MyCollisions = o2::soa::Join; +using MyCollision = MyCollisions::iterator; + +using MyMCCollisions = o2::soa::Join; +using MyMCCollision = MyMCCollisions::iterator; + +using MyMCElectrons = o2::soa::Join; +using MyMCElectron = MyMCElectrons::iterator; +using FilteredMyMCElectrons = o2::soa::Filtered; +using FilteredMyMCElectron = FilteredMyMCElectrons::iterator; + +using MyMCMuons = o2::soa::Join; +using MyMCMuon = MyMCMuons::iterator; +using FilteredMyMCMuons = o2::soa::Filtered; +using FilteredMyMCMuon = FilteredMyMCMuons::iterator; + +using MySmearedElectrons = o2::soa::Join; +using MySmearedElectron = MySmearedElectrons::iterator; + +using MySmearedMuons = o2::soa::Join; +using MySmearedMuon = MySmearedMuons::iterator; + +// template +template +struct DileptonSVMC { + + // Configurables + o2::framework::Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + o2::framework::Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; + o2::framework::Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + + o2::framework::Configurable cfgEventGeneratorType{"cfgEventGeneratorType", -1, "if positive, select event generator type. i.e. gap or signal"}; + o2::framework::Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; + o2::framework::Configurable cfgApplyWeightTTCA{"cfgApplyWeightTTCA", false, "flag to apply weighting by 1/N"}; + o2::framework::Configurable cfgFillUnfolding{"cfgFillUnfolding", false, "flag to fill histograms for unfolding"}; + o2::framework::Configurable cfgRequireTrueAssociation{"cfgRequireTrueAssociation", false, "flag to require true mc collision association"}; + o2::framework::Configurable cfgFillSeparateCharmHadronPairs{"cfgFillSeparateCharmHadronPairs", false, "flag to fill different ccbar pairs separately"}; + + o2::framework::ConfigurableAxis ConfMllBins{"ConfMllBins", {o2::framework::VARIABLE_WIDTH, 0.00, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00}, "mll bins for output histograms"}; + o2::framework::ConfigurableAxis ConfPtllBins{"ConfPtllBins", {o2::framework::VARIABLE_WIDTH, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00, 6.00, 7.00, 8.00, 9.00, 10.00}, "pTll bins for output histograms"}; + o2::framework::ConfigurableAxis ConfDCAllBins{"ConfDCAllBins", {o2::framework::VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0}, "DCAll bins for output histograms"}; + + o2::framework::ConfigurableAxis ConfDPtBins{"ConfDPtBins", {220, -1.0, +10.0}, "dpt bins for output histograms"}; + o2::framework::ConfigurableAxis ConfDCAllNarrowBins{"ConfDCAllNarrowBins", {200, 0.0, 10.0}, "narrow DCAll bins for output histograms"}; + o2::framework::ConfigurableAxis ConfTrackDCA{"ConfTrackDCA", {o2::framework::VARIABLE_WIDTH, -10, -9, -8, -7, -6, -5, -4.5, -4, -3.5, -3, -2.5, -2, -1.9, -1.8, -1.7, -1.6, -1.5, -1.4, -1.3, -1.2, -1.1, -1, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.5, 3, 3.5, 4, 4.5, 5, 6, 7, 8, 9, 10}, "DCA binning for single tacks"}; + + o2::framework::ConfigurableAxis ConfYllBins{"ConfYllBins", {1, -1.f, +1.f}, "yll bins for output histograms"}; + o2::framework::ConfigurableAxis ConfCPABins{"ConfCPABins", {o2::framework::VARIABLE_WIDTH, -1, -0.95, -0.9, -0.85, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.85, 0.9, 0.95, 1}, "cpa bins for output histograms"}; + + // o2::framework::ConfigurableAxis ConfMmumuBins{"ConfMmumuBins", {o2::framework::VARIABLE_WIDTH, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11,1.12,1.13,1.14,1.15,1.16,1.17,1.18,1.19, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00, 4.10, 4.20, 4.30, 4.40, 4.50, 4.60, 4.70, 4.80, 4.90, 5.00, 5.10, 5.20, 5.30, 5.40, 5.50, 5.60, 5.70, 5.80, 5.90, 6.00, 6.10, 6.20, 6.30, 6.40, 6.50, 6.60, 6.70, 6.80, 6.90, 7.00, 7.10, 7.20, 7.30, 7.40, 7.50, 7.60, 7.70, 7.80, 7.90, 8.00, 8.10, 8.20, 8.30, 8.40, 8.50, 8.60, 8.70, 8.80, 8.90, 9.00, 9.10, 9.20, 9.30, 9.40, 9.50, 9.60, 9.70, 9.80, 9.90, 10.00, 10.10, 10.20, 10.30, 10.40, 10.50, 10.60, 10.70, 10.80, 10.90, 11.00, 11.50, 12.00}, "mmumu bins for output histograms"}; // for dimuon. one can copy bins here to hyperloop page. + + o2::framework::Configurable cfg_nbin_dphi_ee{"cfg_nbin_dphi_ee", 1, "number of bins for dphi_ee"}; // 36 + o2::framework::Configurable cfg_nbin_deta_ee{"cfg_nbin_deta_ee", 1, "number of bins for deta_ee"}; // 40 + // o2::framework::Configurable cfg_nbin_cos_theta_cs{"cfg_nbin_cos_theta_cs", 1, "number of bins for cos theta cs"}; // 10 + // o2::framework::Configurable cfg_nbin_phi_cs{"cfg_nbin_phi_cs", 1, "number of bins for phi cs"}; // 10 + o2::framework::Configurable cfg_nbin_aco{"cfg_nbin_aco", 1, "number of bins for acoplanarity"}; // 10 + o2::framework::Configurable cfg_nbin_asym_pt{"cfg_nbin_asym_pt", 1, "number of bins for pt asymmetry"}; // 10 + o2::framework::Configurable cfg_nbin_dphi_e_ee{"cfg_nbin_dphi_e_ee", 1, "number of bins for dphi_ee_e"}; // 18 + o2::framework::ConfigurableAxis ConfPolarizationCosThetaBins{"ConfPolarizationCosThetaBins", {1, -1.f, 1.f}, "cos(theta) bins for polarization analysis"}; + o2::framework::ConfigurableAxis ConfPolarizationPhiBins{"ConfPolarizationPhiBins", {1, -M_PI, M_PI}, "phi bins for polarization analysis"}; + o2::framework::Configurable cfgPolarizationFrame{"cfgPolarizationFrame", 0, "frame of polarization. 0:CS, 1:HX, else:FATAL"}; + o2::framework::ConfigurableAxis ConfPolarizationQuadMomBins{"ConfPolarizationQuadMomBins", {1, -0.5, 1}, "quadrupole moment bins for polarization analysis"}; // quardrupole moment <(3 x cos^2(theta) -1)/2> + + EMEventCut fEMEventCut; + struct : o2::framework::ConfigurableGroup { + std::string prefix = "eventcut_group"; + o2::framework::Configurable cfgZvtxMin{"cfgZvtxMin", -10.f, "min. Zvtx"}; + o2::framework::Configurable cfgZvtxMax{"cfgZvtxMax", +10.f, "max. Zvtx"}; + o2::framework::Configurable cfgRequireSel8{"cfgRequireSel8", false, "require sel8 in event cut"}; + o2::framework::Configurable cfgRequireFT0AND{"cfgRequireFT0AND", true, "require FT0AND in event cut"}; + o2::framework::Configurable cfgRequireNoTFB{"cfgRequireNoTFB", false, "require No time frame border in event cut"}; + o2::framework::Configurable cfgRequireNoITSROFB{"cfgRequireNoITSROFB", false, "require no ITS readout frame border in event cut"}; + o2::framework::Configurable cfgRequireNoSameBunchPileup{"cfgRequireNoSameBunchPileup", false, "require no same bunch pileup in event cut"}; + o2::framework::Configurable cfgRequireVertexITSTPC{"cfgRequireVertexITSTPC", false, "require Vertex ITSTPC in event cut"}; // ITS-TPC matched track contributes PV. + o2::framework::Configurable cfgRequireVertexTOFmatched{"cfgRequireVertexTOFmatched", false, "require Vertex TOFmatched in event cut"}; // ITS-TPC-TOF matched track contributes PV. + o2::framework::Configurable cfgRequireGoodZvtxFT0vsPV{"cfgRequireGoodZvtxFT0vsPV", false, "require good Zvtx between FT0 vs. PV in event cut"}; + o2::framework::Configurable cfgTrackOccupancyMin{"cfgTrackOccupancyMin", -2, "min. occupancy"}; + o2::framework::Configurable cfgTrackOccupancyMax{"cfgTrackOccupancyMax", 1000000000, "max. occupancy"}; + o2::framework::Configurable cfgFT0COccupancyMin{"cfgFT0COccupancyMin", -2, "min. FT0C occupancy"}; + o2::framework::Configurable cfgFT0COccupancyMax{"cfgFT0COccupancyMax", 1000000000, "max. FT0C occupancy"}; + o2::framework::Configurable cfgRequireNoCollInTimeRangeStandard{"cfgRequireNoCollInTimeRangeStandard", false, "require no collision in time range standard"}; + o2::framework::Configurable cfgRequireNoCollInTimeRangeStrict{"cfgRequireNoCollInTimeRangeStrict", false, "require no collision in time range strict"}; + o2::framework::Configurable cfgRequireNoCollInITSROFStandard{"cfgRequireNoCollInITSROFStandard", false, "require no collision in time range standard"}; + o2::framework::Configurable cfgRequireNoCollInITSROFStrict{"cfgRequireNoCollInITSROFStrict", false, "require no collision in time range strict"}; + o2::framework::Configurable cfgRequireNoHighMultCollInPrevRof{"cfgRequireNoHighMultCollInPrevRof", false, "require no HM collision in previous ITS ROF"}; + o2::framework::Configurable cfgRequireGoodITSLayer3{"cfgRequireGoodITSLayer3", false, "number of inactive chips on ITS layer 3 are below threshold "}; + o2::framework::Configurable cfgRequireGoodITSLayer0123{"cfgRequireGoodITSLayer0123", false, "number of inactive chips on ITS layers 0-3 are below threshold "}; + o2::framework::Configurable cfgRequireGoodITSLayersAll{"cfgRequireGoodITSLayersAll", false, "number of inactive chips on all ITS layers are below threshold "}; + + // for RCT + o2::framework::Configurable cfgRequireGoodRCT{"cfgRequireGoodRCT", false, "require good detector flag in run condtion table"}; + o2::framework::Configurable cfgRCTLabel{"cfgRCTLabel", "CBT_hadronPID", "select 1 [CBT, CBT_hadronPID, CBT_muon_glo] see O2Physics/Common/CCDB/RCTSelectionFlags.h"}; + o2::framework::Configurable cfgCheckZDC{"cfgCheckZDC", false, "set ZDC flag for PbPb"}; + o2::framework::Configurable cfgTreatLimitedAcceptanceAsBad{"cfgTreatLimitedAcceptanceAsBad", false, "reject all events where the detectors relevant for the specified Runlist are flagged as LimitedAcceptance"}; + + o2::framework::Configurable cfgCentMin{"cfgCentMin", -1, "min. centrality"}; + o2::framework::Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; + o2::framework::Configurable cfgNumContribMin{"cfgNumContribMin", 0, "min. numContrib"}; + o2::framework::Configurable cfgNumContribMax{"cfgNumContribMax", 65000, "max. numContrib"}; + } eventcuts; + + DielectronCut fDielectronCut; + struct : o2::framework::ConfigurableGroup { + std::string prefix = "dielectroncut_group"; + o2::framework::Configurable cfg_min_mass{"cfg_min_mass", 0.0, "min mass"}; + o2::framework::Configurable cfg_max_mass{"cfg_max_mass", 1e+10, "max mass"}; + o2::framework::Configurable cfg_min_pair_pt{"cfg_min_pair_pt", 0.0, "min pair pT"}; + o2::framework::Configurable cfg_max_pair_pt{"cfg_max_pair_pt", 1e+10, "max pair pT"}; + o2::framework::Configurable cfg_min_pair_y{"cfg_min_pair_y", -0.8, "min pair rapidity"}; + o2::framework::Configurable cfg_max_pair_y{"cfg_max_pair_y", +0.8, "max pair rapidity"}; + o2::framework::Configurable cfg_min_pair_dca3d{"cfg_min_pair_dca3d", 0.0, "min pair dca3d in sigma"}; + o2::framework::Configurable cfg_max_pair_dca3d{"cfg_max_pair_dca3d", 1e+10, "max pair dca3d in sigma"}; + o2::framework::Configurable cfg_apply_phiv{"cfg_apply_phiv", false, "flag to apply phiv cut"}; + o2::framework::Configurable cfg_phiv_slope{"cfg_phiv_slope", 0.0185, "slope for m vs. phiv"}; + o2::framework::Configurable cfg_phiv_intercept{"cfg_phiv_intercept", -0.0280, "intercept for m vs. phiv"}; + o2::framework::Configurable cfg_min_phiv{"cfg_min_phiv", 0.0, "min phiv (constant)"}; + o2::framework::Configurable cfg_max_phiv{"cfg_max_phiv", 3.2, "max phiv (constant)"}; + o2::framework::Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut at PV"}; + o2::framework::Configurable cfg_min_deta{"cfg_min_deta", 0.04, "min deta between 2 electrons (elliptic cut)"}; + o2::framework::Configurable cfg_min_dphi{"cfg_min_dphi", 0.12, "min dphi between 2 electrons (elliptic cut)"}; + o2::framework::Configurable cfg_min_opang{"cfg_min_opang", 0.0, "min opening angle"}; + o2::framework::Configurable cfg_max_opang{"cfg_max_opang", 6.4, "max opening angle"}; + // o2::framework::Configurable cfg_require_diff_sides{"cfg_require_diff_sides", false, "flag to require 2 tracks are from different sides."}; + + o2::framework::Configurable cfg_apply_cuts_from_prefilter{"cfg_apply_cuts_from_prefilter", false, "flag to apply prefilter set when producing derived data"}; + o2::framework::Configurable cfg_prefilter_bits{"cfg_prefilter_bits", 0, "prefilter bits [kNone : 0, kElFromPC : 1, kElFromPi0_20MeV : 2, kElFromPi0_40MeV : 4, kElFromPi0_60MeV : 8, kElFromPi0_80MeV : 16, kElFromPi0_100MeV : 32, kElFromPi0_120MeV : 64, kElFromPi0_140MeV : 128] Please consider logical-OR among them."}; // see PairUtilities.h + + o2::framework::Configurable cfg_apply_cuts_from_prefilter_derived{"cfg_apply_cuts_from_prefilter_derived", false, "flag to apply phiv cut inherited from prefilter"}; + o2::framework::Configurable cfg_prefilter_bits_derived{"cfg_prefilter_bits_derived", 0, "prefilter bits [kNone : 0, kMee : 1, kPhiV : 2, kSplitOrMergedTrackLS : 4, kSplitOrMergedTrackULS : 8] Please consider logical-OR among them."}; // see PairUtilities.h + + o2::framework::Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.8, "min pT for single track"}; + o2::framework::Configurable cfg_max_pt_track{"cfg_max_pt_track", 1e+10, "max pT for single track"}; + o2::framework::Configurable cfg_min_eta_track{"cfg_min_eta_track", -0.8, "min eta for single track"}; + o2::framework::Configurable cfg_max_eta_track{"cfg_max_eta_track", +0.8, "max eta for single track"}; + o2::framework::Configurable cfg_min_phi_track{"cfg_min_phi_track", 0.f, "min phi for single track"}; + o2::framework::Configurable cfg_max_phi_track{"cfg_max_phi_track", 6.3, "max phi for single track"}; + o2::framework::Configurable cfg_mirror_phi_track{"cfg_mirror_phi_track", false, "mirror the phi cut around Pi, min and max Phi should be in 0-Pi"}; + o2::framework::Configurable cfg_reject_phi_track{"cfg_reject_phi_track", false, "reject the phi interval"}; + o2::framework::Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; + o2::framework::Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 5, "min ncluster its"}; + o2::framework::Configurable cfg_min_ncrossedrows{"cfg_min_ncrossedrows", 100, "min ncrossed rows"}; + o2::framework::Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; + o2::framework::Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; + o2::framework::Configurable cfg_max_chi2its{"cfg_max_chi2its", 5.0, "max chi2/NclsITS"}; + o2::framework::Configurable cfg_max_chi2tof{"cfg_max_chi2tof", 1e+10, "max chi2 TOF"}; + o2::framework::Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1.0, "max dca XY for single track in cm"}; + o2::framework::Configurable cfg_max_dcaz{"cfg_max_dcaz", 1.0, "max dca Z for single track in cm"}; + o2::framework::Configurable cfg_max_dca_sigma{"cfg_max_dca_sigma", 1e+10, "max dca for single track in sigma"}; + o2::framework::Configurable cfg_require_itsib_any{"cfg_require_itsib_any", false, "flag to require ITS ib any hits"}; + o2::framework::Configurable cfg_require_itsib_1st{"cfg_require_itsib_1st", true, "flag to require ITS ib 1st hit"}; + o2::framework::Configurable cfg_min_its_cluster_size{"cfg_min_its_cluster_size", 0.f, "min ITS cluster size"}; + o2::framework::Configurable cfg_max_its_cluster_size{"cfg_max_its_cluster_size", 16.f, "max ITS cluster size"}; + // o2::framework::Configurable cfg_min_rel_diff_pin{"cfg_min_rel_diff_pin", -1e+10, "min rel. diff. between pin and ppv"}; + // o2::framework::Configurable cfg_max_rel_diff_pin{"cfg_max_rel_diff_pin", +1e+10, "max rel. diff. between pin and ppv"}; + o2::framework::Configurable cfgRefR{"cfgRefR", 0.50, "ref. radius (m) for calculating phi position"}; // 0.50 +/- 0.06 can be syst. unc. + o2::framework::Configurable cfg_min_phiposition_track{"cfg_min_phiposition_track", 0.f, "min phi position for single track at certain radius"}; + o2::framework::Configurable cfg_max_phiposition_track{"cfg_max_phiposition_track", 6.3, "max phi position for single track at certain radius"}; + o2::framework::Configurable cfgDCAType{"cfgDCAType", 0, "type of DCA for output. 0:3D, 1:XY, 2:Z, else:3D"}; + + o2::framework::Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3, kTOFif = 4, kPIDML = 5]"}; + o2::framework::Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; + o2::framework::Configurable cfg_max_TPCNsigmaEl{"cfg_max_TPCNsigmaEl", +3.0, "max. TPC n sigma for electron inclusion"}; + // o2::framework::Configurable cfg_min_TPCNsigmaMu{"cfg_min_TPCNsigmaMu", -0.0, "min. TPC n sigma for muon exclusion"}; + // o2::framework::Configurable cfg_max_TPCNsigmaMu{"cfg_max_TPCNsigmaMu", +0.0, "max. TPC n sigma for muon exclusion"}; + o2::framework::Configurable cfg_min_TPCNsigmaPi{"cfg_min_TPCNsigmaPi", -1e+10, "min. TPC n sigma for pion exclusion"}; + o2::framework::Configurable cfg_max_TPCNsigmaPi{"cfg_max_TPCNsigmaPi", +3.0, "max. TPC n sigma for pion exclusion"}; + o2::framework::Configurable cfg_min_TPCNsigmaKa{"cfg_min_TPCNsigmaKa", -3.0, "min. TPC n sigma for kaon exclusion"}; + o2::framework::Configurable cfg_max_TPCNsigmaKa{"cfg_max_TPCNsigmaKa", +3.0, "max. TPC n sigma for kaon exclusion"}; + o2::framework::Configurable cfg_min_TPCNsigmaPr{"cfg_min_TPCNsigmaPr", -3.0, "min. TPC n sigma for proton exclusion"}; + o2::framework::Configurable cfg_max_TPCNsigmaPr{"cfg_max_TPCNsigmaPr", +3.0, "max. TPC n sigma for proton exclusion"}; + o2::framework::Configurable cfg_min_TOFNsigmaEl{"cfg_min_TOFNsigmaEl", -3.0, "min. TOF n sigma for electron inclusion"}; + o2::framework::Configurable cfg_max_TOFNsigmaEl{"cfg_max_TOFNsigmaEl", +3.0, "max. TOF n sigma for electron inclusion"}; + o2::framework::Configurable cfg_min_pin_pirejTPC{"cfg_min_pin_pirejTPC", 0.f, "min. pin for pion rejection in TPC"}; + o2::framework::Configurable cfg_max_pin_pirejTPC{"cfg_max_pin_pirejTPC", 1e+10, "max. pin for pion rejection in TPC"}; + o2::framework::Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; + + // configuration for PID ML + o2::framework::Configurable> onnxFileNames{"onnxFileNames", std::vector{"filename"}, "ONNX file names for each bin (if not from CCDB full path)"}; + o2::framework::Configurable> onnxPathsCCDB{"onnxPathsCCDB", std::vector{"path"}, "Paths of models on CCDB"}; + o2::framework::Configurable> binsMLPID{"binsMLPID", std::vector{0.1, 0.15, 0.2, 0.25, 0.4, 0.8, 1.6, 2.0, 4.0, 20.f}, "Bin limits for ML application"}; + o2::framework::Configurable> cutsMLPID{"cutsMLPID", std::vector{0.97, 0.97, 0.97, 0.8, 0.95, 0.95, 0.8, 0.8, 0.8}, "ML cuts per bin"}; + o2::framework::Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature"}, "Names of ML model input features"}; + o2::framework::Configurable nameBinningFeature{"nameBinningFeature", "pt", "Names of ML model binning feature"}; + o2::framework::Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; + o2::framework::Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; + o2::framework::Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; + } dielectroncuts; + + DimuonCut fDimuonCut; + struct : o2::framework::ConfigurableGroup { + std::string prefix = "dimuoncut_group"; + o2::framework::Configurable cfg_min_mass{"cfg_min_mass", 0.0, "min mass"}; + o2::framework::Configurable cfg_max_mass{"cfg_max_mass", 1e+10, "max mass"}; + o2::framework::Configurable cfg_min_pair_pt{"cfg_min_pair_pt", 0.0, "min pair pt"}; + o2::framework::Configurable cfg_max_pair_pt{"cfg_max_pair_pt", 1e+10, "max pair pt"}; + o2::framework::Configurable cfg_min_pair_y{"cfg_min_pair_y", -4.0, "min pair rapidity"}; + o2::framework::Configurable cfg_max_pair_y{"cfg_max_pair_y", -2.5, "max pair rapidity"}; + o2::framework::Configurable cfg_min_pair_dcaxy{"cfg_min_pair_dcaxy", 0.0, "min pair dca3d in sigma"}; + o2::framework::Configurable cfg_max_pair_dcaxy{"cfg_max_pair_dcaxy", 1e+10, "max pair dca3d in sigma"}; + o2::framework::Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut"}; + o2::framework::Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 muons (elliptic cut)"}; + o2::framework::Configurable cfg_min_dphi{"cfg_min_dphi", 0.02, "min dphi between 2 muons (elliptic cut)"}; + + o2::framework::Configurable cfg_apply_cuts_from_prefilter_derived{"cfg_apply_cuts_from_prefilter_derived", false, "flag to apply prefilter set in derived data"}; + o2::framework::Configurable cfg_prefilter_bits_derived{"cfg_prefilter_bits_derived", 0, "prefilter bits [kNone : 0, kSplitOrMergedTrackLS : 4, kSplitOrMergedTrackULS : 8] Please consider logical-OR among them."}; // see PairUtilities.h + + o2::framework::Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; + o2::framework::Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.8, "min pT for single track"}; + o2::framework::Configurable cfg_max_pt_track{"cfg_max_pt_track", 1e+10, "max pT for single track"}; + o2::framework::Configurable cfg_min_eta_track{"cfg_min_eta_track", -4.0, "min eta for single track"}; + o2::framework::Configurable cfg_max_eta_track{"cfg_max_eta_track", -2.5, "max eta for single track"}; + o2::framework::Configurable cfg_min_phi_track{"cfg_min_phi_track", 0.f, "max phi for single track"}; + o2::framework::Configurable cfg_max_phi_track{"cfg_max_phi_track", 6.3, "max phi for single track"}; + o2::framework::Configurable cfg_min_ncluster_mft{"cfg_min_ncluster_mft", 5, "min ncluster MFT"}; + o2::framework::Configurable cfg_min_ncluster_mch{"cfg_min_ncluster_mch", 5, "min ncluster MCH"}; + o2::framework::Configurable cfg_max_chi2{"cfg_max_chi2", 1e+6, "max chi2/ndf"}; + o2::framework::Configurable cfg_max_chi2mft{"cfg_max_chi2mft", 1e+6, "max chi2/ndf"}; + // o2::framework::Configurable cfg_max_matching_chi2_mftmch{"cfg_max_matching_chi2_mftmch", 40, "max chi2 for MFT-MCH matching"}; + o2::framework::Configurable cfg_border_pt_for_chi2mchmft{"cfg_border_pt_for_chi2mchmft", 0, "border pt for different max chi2 for MFT-MCH matching"}; + o2::framework::Configurable cfg_max_matching_chi2_mftmch_lowPt{"cfg_max_matching_chi2_mftmch_lowPt", 8, "max chi2 for MFT-MCH matching for low pT"}; + o2::framework::Configurable cfg_max_matching_chi2_mftmch_highPt{"cfg_max_matching_chi2_mftmch_highPt", 40, "max chi2 for MFT-MCH matching for high pT"}; + o2::framework::Configurable cfg_max_matching_chi2_mchmid{"cfg_max_matching_chi2_mchmid", 1e+10, "max chi2 for MCH-MID matching"}; + o2::framework::Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1e+10, "max dca XY for single track in cm"}; + o2::framework::Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; + o2::framework::Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; + o2::framework::Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; + o2::framework::Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; + o2::framework::Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; + o2::framework::Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + o2::framework::Configurable requireMFTHitMap{"requireMFTHitMap", false, "flag to apply MFT hit map"}; + o2::framework::Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; + o2::framework::Configurable acceptOnlyCorrectMatch{"acceptOnlyCorrectMatch", false, "flag to accept only correct match between MFT and MCH-MID"}; // this is only for MC study, as we don't know correct match in data. + o2::framework::Configurable acceptOnlyWrongMatch{"acceptOnlyWrongMatch", false, "flag to accept only wrong match between MFT and MCH-MID"}; // this is only for MC study, as we don't know correct match in data. + o2::framework::Configurable acceptOnlyXORMatching{"acceptOnlyXORMatching", false, "flag to accept only correct-wrong XOR pairs between MFT and MCH-MID"}; // this is only for MC study, as we don't know correct match in data. + } dimuoncuts; + + struct : o2::framework::ConfigurableGroup { + std::string prefix = "dfGroup"; + o2::framework::Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; + o2::framework::Configurable useWeightedFinalPCA{"useWeightedFinalPCA", false, "Recalculate vertex position using track covariances, effective only if useAbsDCA is true"}; + o2::framework::Configurable maxR{"maxR", 10.f, "reject PCA's above this radius"}; + o2::framework::Configurable maxDZIni{"maxDZIni", 4.f, "reject (if > 0) PCA candidate if tracks DZ exceeds threshold"}; + o2::framework::Configurable minParamChange{"minParamChange", 1e-3, "stop iterations if largest change of any X is smaller than this"}; + o2::framework::Configurable minRelChi2Change{"minRelChi2Change", 0.9, "stop iterations is chi2/chi2old > this"}; + o2::framework::Configurable propagateToPCA{"propagateToPCA", true, "create tracks version propagated to PCA"}; + o2::framework::Configurable maxLog10Chi2PCA{"maxLog10Chi2PCA", 0, "max. log10(chi2PCA) for dilepton pair"}; + } dfGroup; // for DCAFitterN + + struct : o2::framework::ConfigurableGroup { + std::string prefix = "fdfGroup"; + o2::framework::Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; + o2::framework::Configurable useWeightedFinalPCA{"useWeightedFinalPCA", false, "Recalculate vertex position using track covariances, effective only if useAbsDCA is true"}; + o2::framework::Configurable maxR{"maxR", 10.f, "reject PCA's above this radius"}; + o2::framework::Configurable maxDXIni{"maxDXIni", 4.f, "reject (if > 0) PCA candidate if tracks DZ exceeds threshold"}; + o2::framework::Configurable minParamChange{"minParamChange", 1e-3, "stop iterations if largest change of any X is smaller than this"}; + o2::framework::Configurable minRelChi2Change{"minRelChi2Change", 0.9, "stop iterations is chi2/chi2old > this"}; + o2::framework::Configurable propagateToPCA{"propagateToPCA", true, "create tracks version propagated to PCA"}; + o2::framework::Configurable maxLog10Chi2PCA{"maxLog10Chi2PCA", 0, "max. log10(chi2PCA) for dilepton pair"}; + } fdfGroup; // for FwdDCAFitterN + + o2::vertexing::DCAFitterN<2> mDCAFitter; + o2::vertexing::FwdDCAFitterN<2> mFwdDCAFitter; + + o2::aod::rctsel::RCTFlagsChecker rctChecker; + o2::framework::Service ccdb; + // o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; + int mRunNumber{0}; + float d_bz{0}; + + struct : o2::framework::ConfigurableGroup { + std::string prefix = "mctrackcut_group"; + o2::framework::Configurable min_mcPt{"min_mcPt", 0.1, "min. MC pT for generated single lepton"}; + o2::framework::Configurable max_mcPt{"max_mcPt", 1e+10, "max. MC pT for generated single lepton"}; + o2::framework::Configurable min_mcEta{"min_mcEta", -0.8, "max. MC eta for generated single lepton"}; + o2::framework::Configurable max_mcEta{"max_mcEta", +0.8, "max. MC eta for generated single lepton"}; + } mctrackcuts; + + o2::framework::HistogramRegistry fRegistry{"output", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject, false, false}; + static constexpr std::string_view event_cut_types[2] = {"before/", "after/"}; + static constexpr std::string_view pair_sign_types[3] = {"uls/", "lspp/", "lsmm/"}; + static constexpr std::string_view dilepton_source_types[20] = { + "sm/Photon/", // 0 + "sm/PromptPi0/", // 1 + "sm/NonPromptPi0/", // 2 + "sm/Eta/", // 3 + "sm/EtaPrime/", // 4 + "sm/Rho/", // 5 + "sm/Omega/", // 6 + "sm/Phi/", // 7 + "sm/PromptJPsi/", // 8 + "sm/NonPromptJPsi/", // 9 + "sm/PromptPsi2S/", // 10 + "sm/NonPromptPsi2S/", // 11 + "sm/Upsilon1S/", // 12 + "sm/Upsilon2S/", // 13 + "sm/Upsilon3S/", // 14 + "ccbar/c2l_c2l/", // 15 + "bbbar/b2l_b2l/", // 16 + "bbbar/b2c2l_b2c2l/", // 17 + "bbbar/b2c2l_b2l_sameb/", // 18 + "bbbar/b2c2l_b2l_diffb/" // 19 + }; // unordered_map is better, but cannot be constexpr. + static constexpr std::string_view unfolding_dilepton_source_types[3] = {"sm/", "ccbar/", "bbbar/"}; + + ~DileptonSVMC() {} + + void addhistograms() + { + // event info + o2::aod::pwgem::dilepton::utils::eventhistogram::addEventHistograms(&fRegistry); + fRegistry.add("MCEvent/before/hZvtx", "mc vertex z; Z_{vtx} (cm)", o2::framework::HistType::kTH1F, {{100, -50, +50}}, false); + fRegistry.add("MCEvent/before/hZvtx_rec", "rec. mc vertex z; Z_{vtx} (cm)", o2::framework::HistType::kTH1F, {{100, -50, +50}}, false); + fRegistry.addClone("MCEvent/before/", "MCEvent/after/"); + + std::string mass_axis_title = "m_{ll} (GeV/c^{2})"; + std::string pair_pt_axis_title = "p_{T,ll} (GeV/c)"; + std::string pair_y_axis_title = "y_{ll}"; + std::string pair_dca_axis_title = "DCA_{ll} (#sigma)"; + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + mass_axis_title = "m_{ee} (GeV/c^{2})"; + pair_pt_axis_title = "p_{T,ee} (GeV/c)"; + pair_y_axis_title = "y_{ee}"; + pair_dca_axis_title = "DCA_{ee}^{3D} (#sigma)"; + if (dielectroncuts.cfgDCAType == 1) { + pair_dca_axis_title = "DCA_{ee}^{XY} (#sigma)"; + } else if (dielectroncuts.cfgDCAType == 2) { + pair_dca_axis_title = "DCA_{ee}^{Z} (#sigma)"; + } + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + mass_axis_title = "m_{#mu#mu} (GeV/c^{2})"; + pair_pt_axis_title = "p_{T,#mu#mu} (GeV/c)"; + pair_y_axis_title = "y_{#mu#mu}"; + pair_dca_axis_title = "DCA_{#mu#mu}^{XY} (#sigma)"; + } + + // pair info + const o2::framework::AxisSpec axis_mass{ConfMllBins, mass_axis_title}; + const o2::framework::AxisSpec axis_pt{ConfPtllBins, pair_pt_axis_title}; + const o2::framework::AxisSpec axis_y{ConfYllBins, pair_y_axis_title}; + const o2::framework::AxisSpec axis_dca{ConfDCAllBins, pair_dca_axis_title}; + const o2::framework::AxisSpec axis_pt_meson{ConfPtllBins, "p_{T}^{VM} (GeV/c)"}; // for omega, phi meson pT spectra + const o2::framework::AxisSpec axis_y_meson{ConfYllBins, "y^{VM}"}; // for omega, phi meson pT spectra + const o2::framework::AxisSpec axis_cpa{ConfCPABins, "cos(#theta_{p})"}; + + const o2::framework::AxisSpec axis_dca_narrow{ConfDCAllNarrowBins, pair_dca_axis_title}; + const o2::framework::AxisSpec axis_dpt{ConfDPtBins, "#Delta p_{T,1}^{gen-rec} + #Delta p_{T,2}^{gen-rec} (GeV/c)"}; + const o2::framework::AxisSpec axis_dca_track1{ConfTrackDCA, "DCA_{e,1}^{Z} (#sigma)"}; + const o2::framework::AxisSpec axis_dca_track2{ConfTrackDCA, "DCA_{e,2}^{Z} (#sigma)"}; + + std::string frameName = "CS"; + if (cfgPolarizationFrame == 0) { + frameName = "CS"; + } else if (cfgPolarizationFrame == 1) { + frameName = "HX"; + } else { + LOG(fatal) << "set 0 or 1 to cfgPolarizationFrame!"; + } + + const o2::framework::AxisSpec axis_dphi_ee{cfg_nbin_dphi_ee, -M_PI / 2., 3. / 2. * M_PI, "#Delta#varphi = #varphi_{l1} - #varphi_{l2} (rad.)"}; // for kHFll + const o2::framework::AxisSpec axis_deta_ee{cfg_nbin_deta_ee, -2., 2., "#Delta#eta = #eta_{l1} - #eta_{l2}"}; // for kHFll + const o2::framework::AxisSpec axis_cos_theta_pol{ConfPolarizationCosThetaBins, Form("cos(#theta^{%s})", frameName.data())}; // for kPolarization, kUPC + const o2::framework::AxisSpec axis_phi_pol{ConfPolarizationPhiBins, Form("#varphi^{%s} (rad.)", frameName.data())}; // for kPolarization + const o2::framework::AxisSpec axis_quadmom{ConfPolarizationQuadMomBins, Form("#frac{3 cos^{2}(#theta^{%s}) -1}{2}", frameName.data())}; // for kPolarization + const o2::framework::AxisSpec axis_aco{cfg_nbin_aco, 0, 1.f, "#alpha = 1 - #frac{|#varphi_{l^{+}} - #varphi_{l^{-}}|}{#pi}"}; // for kUPC + const o2::framework::AxisSpec axis_asym_pt{cfg_nbin_asym_pt, 0, 1.f, "A = #frac{|p_{T,l^{+}} - p_{T,l^{-}}|}{|p_{T,l^{+}} + p_{T,l^{-}}|}"}; // for kUPC + const o2::framework::AxisSpec axis_dphi_e_ee{cfg_nbin_dphi_e_ee, 0, M_PI, "#Delta#varphi = #varphi_{l} - #varphi_{ll} (rad.)"}; // for kUPC + + // generated info + fRegistry.add("Generated/sm/PromptPi0/uls/hs", "gen. dilepton", o2::framework::HistType::kTHnSparseD, {axis_mass, axis_pt, axis_y, axis_dphi_ee, axis_deta_ee, axis_cos_theta_pol, axis_phi_pol, axis_quadmom, axis_aco, axis_asym_pt, axis_dphi_e_ee}, true); + fRegistry.addClone("Generated/sm/PromptPi0/uls/", "Generated/sm/PromptPi0/lspp/"); + fRegistry.addClone("Generated/sm/PromptPi0/uls/", "Generated/sm/PromptPi0/lsmm/"); + + fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/NonPromptPi0/"); + fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/Eta/"); + fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/EtaPrime/"); + fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/Rho/"); + fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/Omega/"); + fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/Omega2ll/"); + fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/Phi/"); + fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/Phi2ll/"); + fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/PromptJPsi/"); + fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/NonPromptJPsi/"); + fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/PromptPsi2S/"); + fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/NonPromptPsi2S/"); + // fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/Upsilon1S/"); + // fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/Upsilon2S/"); + // fRegistry.addClone("Generated/sm/PromptPi0/", "Generated/sm/Upsilon3S/"); + + fRegistry.add("Generated/ccbar/c2l_c2l/uls/hs", "generated dilepton", o2::framework::HistType::kTHnSparseD, {axis_mass, axis_pt, axis_y, axis_dphi_ee, axis_deta_ee, axis_cos_theta_pol, axis_phi_pol, axis_quadmom, axis_aco, axis_asym_pt, axis_dphi_e_ee}, true); + fRegistry.addClone("Generated/ccbar/c2l_c2l/uls/", "Generated/ccbar/c2l_c2l/lspp/"); + fRegistry.addClone("Generated/ccbar/c2l_c2l/uls/", "Generated/ccbar/c2l_c2l/lsmm/"); + + fRegistry.addClone("Generated/ccbar/c2l_c2l/", "Generated/bbbar/b2l_b2l/"); + fRegistry.addClone("Generated/ccbar/c2l_c2l/", "Generated/bbbar/b2c2l_b2c2l/"); + fRegistry.addClone("Generated/ccbar/c2l_c2l/", "Generated/bbbar/b2c2l_b2l_sameb/"); + fRegistry.addClone("Generated/ccbar/c2l_c2l/", "Generated/bbbar/b2c2l_b2l_diffb/"); // LS + + // for charmed hadrons // create 28 combinations + static constexpr std::string_view charmed_mesons[] = {"Dplus", "D0", "Dsplus"}; // 411, 421, 431 + static constexpr std::string_view anti_charmed_mesons[] = {"Dminus", "D0bar", "Dsminus"}; + const int nm = sizeof(charmed_mesons) / sizeof(charmed_mesons[0]); + static constexpr std::string_view charmed_baryons[] = {"Lcplus", "Xicplus", "Xic0", "Omegac0"}; // 4122, 4232, 4132, 4332 + static constexpr std::string_view anti_charmed_baryons[] = {"Lcminus", "Xicminus", "Xic0bar", "Omegac0bar"}; + const int nb = sizeof(charmed_baryons) / sizeof(charmed_baryons[0]); + static constexpr std::string_view sum_charmed_mesons[] = {"Dpm", "D0", "Dspm"}; + static constexpr std::string_view sum_charmed_baryons[] = {"Lcpm", "Xicpm", "Xic0", "Omegac0"}; + + if (cfgFillSeparateCharmHadronPairs) { + for (int im = 0; im < nm; im++) { + fRegistry.addClone("Generated/ccbar/c2l_c2l/", Form("Generated/ccbar/%s_%s/", charmed_mesons[im].data(), anti_charmed_mesons[im].data())); + } + for (int ib = 0; ib < nb; ib++) { + fRegistry.addClone("Generated/ccbar/c2l_c2l/", Form("Generated/ccbar/%s_%s/", charmed_baryons[ib].data(), anti_charmed_baryons[ib].data())); + } + for (int im1 = 0; im1 < nm - 1; im1++) { + for (int im2 = im1 + 1; im2 < nm; im2++) { + fRegistry.addClone("Generated/ccbar/c2l_c2l/", Form("Generated/ccbar/%s_%s/", sum_charmed_mesons[im1].data(), sum_charmed_mesons[im2].data())); + } + } + for (int ib1 = 0; ib1 < nb - 1; ib1++) { + for (int ib2 = ib1 + 1; ib2 < nb; ib2++) { + fRegistry.addClone("Generated/ccbar/c2l_c2l/", Form("Generated/ccbar/%s_%s/", sum_charmed_baryons[ib1].data(), sum_charmed_baryons[ib2].data())); + } + } + for (int im = 0; im < nm; im++) { + for (int ib = 0; ib < nb; ib++) { + fRegistry.addClone("Generated/ccbar/c2l_c2l/", Form("Generated/ccbar/%s_%s/", sum_charmed_mesons[im].data(), sum_charmed_baryons[ib].data())); + } + } + } + + // evaluate acceptance for polarization + fRegistry.add("Generated/VM/All/Phi/hs", "gen. VM #rightarrow ll", o2::framework::HistType::kTHnSparseD, {axis_mass, axis_pt, axis_y, axis_cos_theta_pol, axis_phi_pol, axis_quadmom}, true); + fRegistry.addClone("Generated/VM/All/Phi/", "Generated/VM/All/Rho/"); + fRegistry.addClone("Generated/VM/All/Phi/", "Generated/VM/All/Omega/"); + fRegistry.addClone("Generated/VM/All/Phi/", "Generated/VM/All/PromptJPsi/"); + fRegistry.addClone("Generated/VM/All/Phi/", "Generated/VM/All/NonPromptJPsi/"); + fRegistry.addClone("Generated/VM/All/", "Generated/VM/Acc/"); + + // reconstructed pair info + fRegistry.add("Pair/sm/Photon/uls/hs", "rec. dilepton", o2::framework::HistType::kTHnSparseD, {axis_mass, axis_pt, axis_y, axis_dphi_ee, axis_deta_ee, axis_cos_theta_pol, axis_phi_pol, axis_quadmom, axis_aco, axis_asym_pt, axis_dphi_e_ee, axis_dca, axis_cpa}, true); + + fRegistry.addClone("Pair/sm/Photon/uls/", "Pair/sm/Photon/lspp/"); + fRegistry.addClone("Pair/sm/Photon/uls/", "Pair/sm/Photon/lsmm/"); + fRegistry.addClone("Pair/sm/Photon/", "Pair/sm/PromptPi0/"); + fRegistry.addClone("Pair/sm/Photon/", "Pair/sm/NonPromptPi0/"); + fRegistry.addClone("Pair/sm/Photon/", "Pair/sm/Eta/"); + fRegistry.addClone("Pair/sm/Photon/", "Pair/sm/EtaPrime/"); + fRegistry.addClone("Pair/sm/Photon/", "Pair/sm/Rho/"); + fRegistry.addClone("Pair/sm/Photon/", "Pair/sm/Omega/"); + fRegistry.addClone("Pair/sm/Photon/", "Pair/sm/Omega2ll/"); + fRegistry.addClone("Pair/sm/Photon/", "Pair/sm/Phi/"); + fRegistry.addClone("Pair/sm/Photon/", "Pair/sm/Phi2ll/"); + fRegistry.addClone("Pair/sm/Photon/", "Pair/sm/PromptJPsi/"); + fRegistry.addClone("Pair/sm/Photon/", "Pair/sm/NonPromptJPsi/"); + fRegistry.addClone("Pair/sm/Photon/", "Pair/sm/PromptPsi2S/"); + fRegistry.addClone("Pair/sm/Photon/", "Pair/sm/NonPromptPsi2S/"); + + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + fRegistry.add("Pair/sm/Photon/uls/hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi (rad.);m_{ee} (GeV/c^{2})", o2::framework::HistType::kTH2F, {{90, 0, M_PI}, {100, 0.0f, 1.0f}}, true); + fRegistry.add("Pair/sm/Photon/uls/hMvsRxy", "m_{ee} vs. r_{xy};r_{xy}^{true} (cm);m_{ee} (GeV/c^{2})", o2::framework::HistType::kTH2F, {{100, 0, 100}, {100, 0.0f, 1.0f}}, true); + for (const auto& strSign : pair_sign_types) { + fRegistry.add(std::format("Pair/sm/PromptPi0/{0}hMvsPhiV", strSign), "m_{ee} vs. #varphi_{V};#varphi (rad.);m_{ee} (GeV/c^{2})", o2::framework::HistType::kTH2F, {{90, 0, M_PI}, {100, 0.0f, 1.0f}}, true); + fRegistry.add(std::format("Pair/sm/NonPromptPi0/{0}hMvsPhiV", strSign), "m_{ee} vs. #varphi_{V};#varphi (rad.);m_{ee} (GeV/c^{2})", o2::framework::HistType::kTH2F, {{90, 0, M_PI}, {100, 0.0f, 1.0f}}, true); + } + } + + fRegistry.add("Pair/ccbar/c2l_c2l/uls/hs", "rec. dilepton", o2::framework::HistType::kTHnSparseD, {axis_mass, axis_pt, axis_y, axis_dphi_ee, axis_deta_ee, axis_cos_theta_pol, axis_phi_pol, axis_quadmom, axis_aco, axis_asym_pt, axis_dphi_e_ee, axis_dca, axis_cpa}, true); + fRegistry.addClone("Pair/ccbar/c2l_c2l/uls/", "Pair/ccbar/c2l_c2l/lspp/"); + fRegistry.addClone("Pair/ccbar/c2l_c2l/uls/", "Pair/ccbar/c2l_c2l/lsmm/"); + + fRegistry.addClone("Pair/ccbar/c2l_c2l/", "Pair/bbbar/b2l_b2l/"); + fRegistry.addClone("Pair/ccbar/c2l_c2l/", "Pair/bbbar/b2c2l_b2c2l/"); + fRegistry.addClone("Pair/ccbar/c2l_c2l/", "Pair/bbbar/b2c2l_b2l_sameb/"); + fRegistry.addClone("Pair/ccbar/c2l_c2l/", "Pair/bbbar/b2c2l_b2l_diffb/"); // LS + + if (cfgFillSeparateCharmHadronPairs) { + for (int im = 0; im < nm; im++) { + fRegistry.addClone("Pair/ccbar/c2l_c2l/", Form("Pair/ccbar/%s_%s/", charmed_mesons[im].data(), anti_charmed_mesons[im].data())); + } + for (int ib = 0; ib < nb; ib++) { + fRegistry.addClone("Pair/ccbar/c2l_c2l/", Form("Pair/ccbar/%s_%s/", charmed_baryons[ib].data(), anti_charmed_baryons[ib].data())); + } + for (int im1 = 0; im1 < nm - 1; im1++) { + for (int im2 = im1 + 1; im2 < nm; im2++) { + fRegistry.addClone("Pair/ccbar/c2l_c2l/", Form("Pair/ccbar/%s_%s/", sum_charmed_mesons[im1].data(), sum_charmed_mesons[im2].data())); + } + } + for (int ib1 = 0; ib1 < nb - 1; ib1++) { + for (int ib2 = ib1 + 1; ib2 < nb; ib2++) { + fRegistry.addClone("Pair/ccbar/c2l_c2l/", Form("Pair/ccbar/%s_%s/", sum_charmed_baryons[ib1].data(), sum_charmed_baryons[ib2].data())); + } + } + for (int im = 0; im < nm; im++) { + for (int ib = 0; ib < nb; ib++) { + fRegistry.addClone("Pair/ccbar/c2l_c2l/", Form("Pair/ccbar/%s_%s/", sum_charmed_mesons[im].data(), sum_charmed_baryons[ib].data())); + } + } + } + + // for correlated bkg due to mis-identified hadrons, and true combinatorial bkg + fRegistry.add("Pair/corr_bkg_lh/uls/hs", "rec. bkg", o2::framework::HistType::kTHnSparseD, {axis_mass, axis_pt, axis_y, axis_dphi_ee, axis_deta_ee, axis_cos_theta_pol, axis_phi_pol, axis_quadmom, axis_aco, axis_asym_pt, axis_dphi_e_ee, axis_dca, axis_cpa}, true); + fRegistry.addClone("Pair/corr_bkg_lh/uls/", "Pair/corr_bkg_lh/lspp/"); + fRegistry.addClone("Pair/corr_bkg_lh/uls/", "Pair/corr_bkg_lh/lsmm/"); + fRegistry.addClone("Pair/corr_bkg_lh/", "Pair/corr_bkg_hh/"); + fRegistry.addClone("Pair/corr_bkg_lh/", "Pair/comb_bkg/"); + + if (doprocessGen_VM) { + fRegistry.add("Generated/VM/Omega/hPtY", "pT vs. y of #omega", o2::framework::HistType::kTH2D, {axis_y_meson, axis_pt_meson}, true); // for pT spectrum + fRegistry.add("Generated/VM/Phi/hPtY", "pT vs. y of #phi", o2::framework::HistType::kTH2D, {axis_y_meson, axis_pt_meson}, true); // for pT spectrum + } + + if (cfgFillUnfolding) { + // for 2D unfolding + const o2::framework::AxisSpec axis_mass_gen{ConfMllBins, "m_{ll}^{gen} (GeV/c^{2})"}; + const o2::framework::AxisSpec axis_pt_gen{ConfPtllBins, "p_{T,ll}^{gen} (GeV/c)"}; + const o2::framework::AxisSpec axis_mass_rec{ConfMllBins, "m_{ll}^{rec} (GeV/c^{2})"}; + const o2::framework::AxisSpec axis_pt_rec{ConfPtllBins, "p_{T,ll}^{rec} (GeV/c)"}; + fRegistry.add("Unfold/sm/uls/hsRM", "response matrix", o2::framework::HistType::kTHnSparseD, {axis_mass_gen, axis_pt_gen, axis_mass_rec, axis_pt_rec}, true); + fRegistry.add("Unfold/sm/uls/hMiss", "missing dilepton", o2::framework::HistType::kTH2D, {axis_mass_gen, axis_pt_gen}, true); // e.g. true eta is in acceptance, but reconstructed eta is out of acceptance. + fRegistry.add("Unfold/sm/uls/hFake", "fake dilepton", o2::framework::HistType::kTH2D, {axis_mass_rec, axis_pt_rec}, true); // e.g. true eta is out of acceptance, but reconstructed eta is in acceptance. + fRegistry.addClone("Unfold/sm/uls/", "Unfold/sm/lspp/"); + fRegistry.addClone("Unfold/sm/uls/", "Unfold/sm/lsmm/"); + fRegistry.addClone("Unfold/sm/", "Unfold/ccbar/"); + fRegistry.addClone("Unfold/sm/", "Unfold/bbbar/"); + } + } + + float beamM1 = o2::constants::physics::MassProton; // mass of beam + float beamM2 = o2::constants::physics::MassProton; // mass of beam + float beamE1 = 0.f; // beam energy + float beamE2 = 0.f; // beam energy + float beamP1 = 0.f; // beam momentum + float beamP2 = 0.f; // beam momentum + + float leptonM1 = 0.f; + float leptonM2 = 0.f; + int pdg_lepton = 0; + void init(o2::framework::InitContext&) + { + if (doprocessAnalysis && doprocessAnalysis_Smeared) { + LOGF(fatal, "Cannot enable doprocessAnalysis and doprocessAnalysis_Smeared at the same time. Please choose one."); + } + + mRunNumber = 0; + d_bz = 0; + + ccdb->setURL(ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + rctChecker.init(eventcuts.cfgRCTLabel.value, eventcuts.cfgCheckZDC.value, eventcuts.cfgTreatLimitedAcceptanceAsBad.value); + + DefineEMEventCut(); + addhistograms(); + + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + DefineDielectronCut(); + leptonM1 = o2::constants::physics::MassElectron; + leptonM2 = o2::constants::physics::MassElectron; + pdg_lepton = 11; + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + DefineDimuonCut(); + leptonM1 = o2::constants::physics::MassMuon; + leptonM2 = o2::constants::physics::MassMuon; + pdg_lepton = 13; + } + if (doprocessNorm) { + fRegistry.addClone("Event/before/hCollisionCounter", "Event/norm/hCollisionCounter"); + } + if (doprocessBC) { + auto hTVXCounter = fRegistry.add("BC/hTVXCounter", "TVX counter", o2::framework::HistType::kTH1D, {{6, -0.5f, 5.5f}}); + hTVXCounter->GetXaxis()->SetBinLabel(1, "TVX"); + hTVXCounter->GetXaxis()->SetBinLabel(2, "TVX && NoTFB"); + hTVXCounter->GetXaxis()->SetBinLabel(3, "TVX && NoITSROFB"); + hTVXCounter->GetXaxis()->SetBinLabel(4, "TVX && GoodRCT"); + hTVXCounter->GetXaxis()->SetBinLabel(5, "TVX && NoTFB && NoITSROFB"); + hTVXCounter->GetXaxis()->SetBinLabel(6, "TVX && NoTFB && NoITSROFB && GoodRCT"); + } + + mDCAFitter.setPropagateToPCA(dfGroup.propagateToPCA); + mDCAFitter.setMaxR(dfGroup.maxR); + mDCAFitter.setMaxDZIni(dfGroup.maxDZIni); + mDCAFitter.setMinParamChange(dfGroup.minParamChange); + mDCAFitter.setMinRelChi2Change(dfGroup.minRelChi2Change); + mDCAFitter.setUseAbsDCA(dfGroup.useAbsDCA); + mDCAFitter.setWeightedFinalPCA(dfGroup.useWeightedFinalPCA); + + mFwdDCAFitter.setPropagateToPCA(fdfGroup.propagateToPCA); + mFwdDCAFitter.setMaxR(fdfGroup.maxR); + mFwdDCAFitter.setMaxDXIni(fdfGroup.maxDXIni); + mFwdDCAFitter.setMinParamChange(fdfGroup.minParamChange); + mFwdDCAFitter.setMinRelChi2Change(fdfGroup.minRelChi2Change); + mFwdDCAFitter.setUseAbsDCA(fdfGroup.useAbsDCA); + } + + template + void initCCDB(TCollision const& collision) + { + if (mRunNumber == collision.runNumber()) { + return; + } + + auto run3grp_timestamp = collision.timestamp(); + o2::parameters::GRPObject* grpo = 0x0; + o2::parameters::GRPMagField* grpmag = 0x0; + if (grpo) { + o2::base::Propagator::initFieldFromGRP(grpo); + // Fetch magnetic field from ccdb for current collision + d_bz = grpo->getNominalL3Field(); + LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kG"; + } else { + grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); + if (!grpmag) { + LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; + } + o2::base::Propagator::initFieldFromGRP(grpmag); + // Fetch magnetic field from ccdb for current collision + d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); + LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kG"; + } + mRunNumber = collision.runNumber(); + fDielectronCut.SetTrackPhiPositionRange(dielectroncuts.cfg_min_phiposition_track, dielectroncuts.cfg_max_phiposition_track, dielectroncuts.cfgRefR, d_bz, dielectroncuts.cfg_mirror_phi_track); + + mDCAFitter.setBz(d_bz); + mFwdDCAFitter.setBz(d_bz); + + auto grplhcif = ccdb->getForTimeStamp("GLO/Config/GRPLHCIF", collision.timestamp()); + int beamZ1 = grplhcif->getBeamZ(o2::constants::lhc::BeamC); + int beamZ2 = grplhcif->getBeamZ(o2::constants::lhc::BeamA); + int beamA1 = grplhcif->getBeamA(o2::constants::lhc::BeamC); + int beamA2 = grplhcif->getBeamA(o2::constants::lhc::BeamA); + beamE1 = grplhcif->getBeamEnergyPerNucleonInGeV(o2::constants::lhc::BeamC); + beamE2 = grplhcif->getBeamEnergyPerNucleonInGeV(o2::constants::lhc::BeamA); + beamM1 = o2::constants::physics::MassProton * beamA1; + beamM2 = o2::constants::physics::MassProton * beamA2; + beamP1 = std::sqrt(std::pow(beamE1, 2) - std::pow(beamM1, 2)); + beamP2 = std::sqrt(std::pow(beamE2, 2) - std::pow(beamM2, 2)); + LOGF(info, "beamZ1 = %d, beamZ2 = %d, beamA1 = %d, beamA2 = %d, beamE1 = %f (GeV), beamE2 = %f (GeV), beamM1 = %f (GeV), beamM2 = %f (GeV), beamP1 = %f (GeV), beamP2 = %f (GeV)", beamZ1, beamZ2, beamA1, beamA2, beamE1, beamE2, beamM1, beamM2, beamP1, beamP2); + } + + void DefineEMEventCut() + { + fEMEventCut = EMEventCut("fEMEventCut", "fEMEventCut"); + fEMEventCut.SetRequireSel8(eventcuts.cfgRequireSel8); + fEMEventCut.SetRequireFT0AND(eventcuts.cfgRequireFT0AND); + fEMEventCut.SetZvtxRange(eventcuts.cfgZvtxMin, eventcuts.cfgZvtxMax); + fEMEventCut.SetRequireNoTFB(eventcuts.cfgRequireNoTFB); + fEMEventCut.SetRequireNoITSROFB(eventcuts.cfgRequireNoITSROFB); + fEMEventCut.SetRequireNoSameBunchPileup(eventcuts.cfgRequireNoSameBunchPileup); + fEMEventCut.SetRequireVertexITSTPC(eventcuts.cfgRequireVertexITSTPC); + fEMEventCut.SetRequireVertexTOFmatched(eventcuts.cfgRequireVertexTOFmatched); + fEMEventCut.SetRequireGoodZvtxFT0vsPV(eventcuts.cfgRequireGoodZvtxFT0vsPV); + fEMEventCut.SetRequireNoCollInTimeRangeStandard(eventcuts.cfgRequireNoCollInTimeRangeStandard); + fEMEventCut.SetRequireNoCollInTimeRangeStrict(eventcuts.cfgRequireNoCollInTimeRangeStrict); + fEMEventCut.SetRequireNoCollInITSROFStandard(eventcuts.cfgRequireNoCollInITSROFStandard); + fEMEventCut.SetRequireNoCollInITSROFStrict(eventcuts.cfgRequireNoCollInITSROFStrict); + fEMEventCut.SetRequireNoHighMultCollInPrevRof(eventcuts.cfgRequireNoHighMultCollInPrevRof); + fEMEventCut.SetRequireGoodITSLayer3(eventcuts.cfgRequireGoodITSLayer3); + fEMEventCut.SetRequireGoodITSLayer0123(eventcuts.cfgRequireGoodITSLayer0123); + fEMEventCut.SetRequireGoodITSLayersAll(eventcuts.cfgRequireGoodITSLayersAll); + } + + void DefineDielectronCut() + { + fDielectronCut = DielectronCut("fDielectronCut", "fDielectronCut"); + + // for pair + fDielectronCut.SetMeeRange(dielectroncuts.cfg_min_mass, dielectroncuts.cfg_max_mass); + fDielectronCut.SetPairPtRange(dielectroncuts.cfg_min_pair_pt, dielectroncuts.cfg_max_pair_pt); + fDielectronCut.SetPairYRange(dielectroncuts.cfg_min_pair_y, dielectroncuts.cfg_max_pair_y); + fDielectronCut.SetPairDCARange(dielectroncuts.cfg_min_pair_dca3d, dielectroncuts.cfg_max_pair_dca3d); // in sigma + fDielectronCut.SetMaxMeePhiVDep([&](float phiv) { return dielectroncuts.cfg_phiv_intercept + phiv * dielectroncuts.cfg_phiv_slope; }, dielectroncuts.cfg_min_phiv, dielectroncuts.cfg_max_phiv); + fDielectronCut.ApplyPhiV(dielectroncuts.cfg_apply_phiv); + fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, false, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); + fDielectronCut.SetPairOpAng(dielectroncuts.cfg_min_opang, dielectroncuts.cfg_max_opang); + // fDielectronCut.SetRequireDifferentSides(dielectroncuts.cfg_require_diff_sides); + + // for track + fDielectronCut.SetTrackPtRange(dielectroncuts.cfg_min_pt_track, dielectroncuts.cfg_max_pt_track); + fDielectronCut.SetTrackEtaRange(dielectroncuts.cfg_min_eta_track, +dielectroncuts.cfg_max_eta_track); + fDielectronCut.SetTrackPhiRange(dielectroncuts.cfg_min_phi_track, dielectroncuts.cfg_max_phi_track, dielectroncuts.cfg_mirror_phi_track, dielectroncuts.cfg_reject_phi_track); + fDielectronCut.SetMinNClustersTPC(dielectroncuts.cfg_min_ncluster_tpc); + fDielectronCut.SetMinNCrossedRowsTPC(dielectroncuts.cfg_min_ncrossedrows); + fDielectronCut.SetMinNCrossedRowsOverFindableClustersTPC(0.8); + fDielectronCut.SetMaxFracSharedClustersTPC(dielectroncuts.cfg_max_frac_shared_clusters_tpc); + fDielectronCut.SetChi2PerClusterTPC(0.0, dielectroncuts.cfg_max_chi2tpc); + fDielectronCut.SetChi2PerClusterITS(0.0, dielectroncuts.cfg_max_chi2its); + fDielectronCut.SetNClustersITS(dielectroncuts.cfg_min_ncluster_its, 7); + fDielectronCut.SetMeanClusterSizeITS(dielectroncuts.cfg_min_its_cluster_size, dielectroncuts.cfg_max_its_cluster_size); + fDielectronCut.SetTrackMaxDcaSigma(dielectroncuts.cfg_max_dca_sigma, dielectroncuts.cfgDCAType); + fDielectronCut.SetTrackMaxDcaXY(dielectroncuts.cfg_max_dcaxy); + fDielectronCut.SetTrackMaxDcaZ(dielectroncuts.cfg_max_dcaz); + fDielectronCut.RequireITSibAny(dielectroncuts.cfg_require_itsib_any); + fDielectronCut.RequireITSib1st(dielectroncuts.cfg_require_itsib_1st); + fDielectronCut.SetChi2TOF(0.0, dielectroncuts.cfg_max_chi2tof); + // fDielectronCut.SetRelDiffPin(dielectroncuts.cfg_min_rel_diff_pin, dielectroncuts.cfg_max_rel_diff_pin); + fDielectronCut.EnableTTCA(dielectroncuts.enableTTCA); + + // for eID + fDielectronCut.SetPIDScheme(dielectroncuts.cfg_pid_scheme); + fDielectronCut.SetTPCNsigmaElRange(dielectroncuts.cfg_min_TPCNsigmaEl, dielectroncuts.cfg_max_TPCNsigmaEl); + // fDielectronCut.SetTPCNsigmaMuRange(dielectroncuts.cfg_min_TPCNsigmaMu, dielectroncuts.cfg_max_TPCNsigmaMu); + fDielectronCut.SetTPCNsigmaPiRange(dielectroncuts.cfg_min_TPCNsigmaPi, dielectroncuts.cfg_max_TPCNsigmaPi); + fDielectronCut.SetTPCNsigmaKaRange(dielectroncuts.cfg_min_TPCNsigmaKa, dielectroncuts.cfg_max_TPCNsigmaKa); + fDielectronCut.SetTPCNsigmaPrRange(dielectroncuts.cfg_min_TPCNsigmaPr, dielectroncuts.cfg_max_TPCNsigmaPr); + fDielectronCut.SetTOFNsigmaElRange(dielectroncuts.cfg_min_TOFNsigmaEl, dielectroncuts.cfg_max_TOFNsigmaEl); + fDielectronCut.SetPinRangeForPionRejectionTPC(dielectroncuts.cfg_min_pin_pirejTPC, dielectroncuts.cfg_max_pin_pirejTPC); + + if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDileptonCut + std::vector binsML{}; + binsML.reserve(dielectroncuts.binsMLPID.value.size()); + for (size_t i = 0; i < dielectroncuts.binsMLPID.value.size(); i++) { + binsML.emplace_back(dielectroncuts.binsMLPID.value[i]); + } + std::vector thresholdsML{}; + thresholdsML.reserve(dielectroncuts.cutsMLPID.value.size()); + for (size_t i = 0; i < dielectroncuts.cutsMLPID.value.size(); i++) { + thresholdsML.emplace_back(dielectroncuts.cutsMLPID.value[i]); + } + fDielectronCut.SetMLThresholds(binsML, thresholdsML); + } // end of PID ML + } + + void DefineDimuonCut() + { + fDimuonCut = DimuonCut("fDimuonCut", "fDimuonCut"); + + // for pair + fDimuonCut.SetMassRange(dimuoncuts.cfg_min_mass, dimuoncuts.cfg_max_mass); + fDimuonCut.SetPairPtRange(dimuoncuts.cfg_min_pair_pt, dimuoncuts.cfg_max_pair_pt); + fDimuonCut.SetPairYRange(dimuoncuts.cfg_min_pair_y, dimuoncuts.cfg_max_pair_y); + fDimuonCut.SetPairDCAxyRange(dimuoncuts.cfg_min_pair_dcaxy, dimuoncuts.cfg_max_pair_dcaxy); // DCAxy in cm + fDimuonCut.SetMindEtadPhi(dimuoncuts.cfg_apply_detadphi, dimuoncuts.cfg_min_deta, dimuoncuts.cfg_min_dphi); + + // for track + fDimuonCut.SetTrackType(dimuoncuts.cfg_track_type); + fDimuonCut.SetTrackPtRange(dimuoncuts.cfg_min_pt_track, dimuoncuts.cfg_max_pt_track); + fDimuonCut.SetTrackEtaRange(dimuoncuts.cfg_min_eta_track, dimuoncuts.cfg_max_eta_track); + fDimuonCut.SetTrackPhiRange(dimuoncuts.cfg_min_phi_track, dimuoncuts.cfg_max_phi_track); + fDimuonCut.SetNClustersMFT(dimuoncuts.cfg_min_ncluster_mft, 10); + fDimuonCut.SetNClustersMCHMID(dimuoncuts.cfg_min_ncluster_mch, 20); + fDimuonCut.SetChi2(0.f, dimuoncuts.cfg_max_chi2); + fDimuonCut.SetChi2MFT(0.f, dimuoncuts.cfg_max_chi2mft); + // fDimuonCut.SetMatchingChi2MCHMFT(0.f, dimuoncuts.cfg_max_matching_chi2_mftmch); + fDimuonCut.SetMaxMatchingChi2MCHMFTPtDep([&](float pt) { return (pt < dimuoncuts.cfg_border_pt_for_chi2mchmft ? dimuoncuts.cfg_max_matching_chi2_mftmch_lowPt : dimuoncuts.cfg_max_matching_chi2_mftmch_highPt); }); + fDimuonCut.SetMatchingChi2MCHMID(0.f, dimuoncuts.cfg_max_matching_chi2_mchmid); + fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); + fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); + fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); + fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons + fDimuonCut.SetMFTHitMap(dimuoncuts.requireMFTHitMap, dimuoncuts.requiredMFTDisks); + fDimuonCut.EnableTTCA(dimuoncuts.enableTTCA); + } + + template + int FindSMULS(TTrack const& t1mc, TTrack const& t2mc, TMCParticles const& mcparticles) + { + int arr[] = { + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, pdg_lepton, 22, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, pdg_lepton, 111, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, pdg_lepton, 221, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, pdg_lepton, 331, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, pdg_lepton, 113, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, pdg_lepton, 223, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, pdg_lepton, 333, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, pdg_lepton, 443, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, pdg_lepton, 100443, mcparticles) + // o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, pdg_lepton, 553, mcparticles), + // o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, pdg_lepton, 100553, mcparticles), + // o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, pdg_lepton, 200553, mcparticles) + }; + int size = sizeof(arr) / sizeof(*arr); + int max = *std::max_element(arr, arr + size); + return max; + } + + template + int FindSMLSPP(TTrack const& t1mc, TTrack const& t2mc, TMCParticles const& mcparticles) + { + int arr[] = { + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, -pdg_lepton, 111, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, -pdg_lepton, 221, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, -pdg_lepton, 331, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, -pdg_lepton, 113, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, -pdg_lepton, 223, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, -pdg_lepton, -pdg_lepton, 333, mcparticles)}; + int size = sizeof(arr) / sizeof(*arr); + int max = *std::max_element(arr, arr + size); + return max; + } + + template + int FindSMLSMM(TTrack const& t1mc, TTrack const& t2mc, TMCParticles const& mcparticles) + { + int arr[] = { + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, pdg_lepton, pdg_lepton, 111, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, pdg_lepton, pdg_lepton, 221, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, pdg_lepton, pdg_lepton, 331, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, pdg_lepton, pdg_lepton, 113, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, pdg_lepton, pdg_lepton, 223, mcparticles), + o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(t1mc, t2mc, pdg_lepton, pdg_lepton, 333, mcparticles)}; + int size = sizeof(arr) / sizeof(*arr); + int max = *std::max_element(arr, arr + size); + return max; + } + + template + bool isInAcceptance(T const& lepton) + { + float pt = 0.f, eta = 0.f; + if constexpr (isSmeared) { + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + pt = lepton.ptSmeared(); + eta = lepton.etaSmeared(); + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + if (dimuoncuts.cfg_track_type == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack)) { + pt = lepton.ptSmeared_sa_muon(); + eta = lepton.etaSmeared_sa_muon(); + } else if (dimuoncuts.cfg_track_type == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack)) { + pt = lepton.ptSmeared_gl_muon(); + eta = lepton.etaSmeared_gl_muon(); + } else { + pt = lepton.pt(); + eta = lepton.eta(); + } + } + } else { + pt = lepton.pt(); + eta = lepton.eta(); + } + + return isInAcceptance(pt, eta); + + // if ((mctrackcuts.min_mcPt < pt && pt < mctrackcuts.max_mcPt) && (mctrackcuts.min_mcEta < eta && eta < mctrackcuts.max_mcEta)) { + // return true; + // } else { + // return false; + // } + } + + bool isInAcceptance(const float pt, const float eta) + { + if ((mctrackcuts.min_mcPt < pt && pt < mctrackcuts.max_mcPt) && (mctrackcuts.min_mcEta < eta && eta < mctrackcuts.max_mcEta)) { + return true; + } else { + return false; + } + } + + struct dileptonSV { + float pt1{999}; + float eta1{999}; + float phi1{999}; + + float pt2{999}; + float eta2{999}; + float phi2{999}; + + // float mass{999}; + // float pt{999}; + // float rapidity{999}; + + float chi2PCA{999}; + float cpa{999}; + float lxy{999}; + float lz{999}; + float lxyz{999}; + float lxyErr{999}; + float lzErr{999}; + float lxyzErr{999}; + }; + + template + bool findSV(TCollision const& collision, TTrackParCov const& t1, TTrackParCov const& t2, dileptonSV& candidate) + { + try { + if (mDCAFitter.process(t1, t2) == 0) { + return false; + } + } catch (const std::runtime_error& error) { + LOG(info) << "Run time error found: " << error.what() << ". DCAFitterN cannot work, skipping the candidate."; + return false; + } + candidate.chi2PCA = mDCAFitter.getChi2AtPCACandidate(); + if (dfGroup.maxLog10Chi2PCA < std::log10(candidate.chi2PCA)) { + return false; + } + + mDCAFitter.propagateTracksToVertex(); + const auto& secondaryVertex = mDCAFitter.getPCACandidate(); + auto trackParCov0 = mDCAFitter.getTrack(0); + auto trackParCov1 = mDCAFitter.getTrack(1); + + // get track momenta + std::array pvertex = {collision.posX(), collision.posY(), collision.posZ()}; + std::array pvec0{}; + std::array pvec1{}; + trackParCov0.getPxPyPzGlo(pvec0); + trackParCov1.getPxPyPzGlo(pvec1); + std::array momDilepton = {pvec0[0] + pvec1[0], pvec0[1] + pvec1[1], pvec0[2] + pvec1[2]}; + candidate.cpa = std::clamp(RecoDecay::cpa(pvertex, secondaryVertex, momDilepton), -1.0, std::nextafter(1.0, 0.0)); + + candidate.lxy = std::sqrt(std::pow(secondaryVertex[0] - collision.posX(), 2) + std::pow(secondaryVertex[1] - collision.posY(), 2)); + candidate.lz = secondaryVertex[2] - collision.posZ(); + candidate.lxyz = std::sqrt(std::pow(candidate.lxy, 2) + std::pow(candidate.lz, 2)); + + auto primaryVertex = getPrimaryVertex(collision); + std::array covVtx = mDCAFitter.calcPCACovMatrixFlat(); + double phi{0}, theta{0}; + getPointDirection(std::array{primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}, secondaryVertex, phi, theta); + candidate.lxyErr = std::sqrt(getRotatedCovMatrixXX(primaryVertex.getCov(), phi, 0.) + getRotatedCovMatrixXX(covVtx, phi, 0.)); + candidate.lzErr = std::sqrt(getRotatedCovMatrixXX(primaryVertex.getCov(), 0, theta) + getRotatedCovMatrixXX(covVtx, 0, theta)); + candidate.lxyzErr = std::sqrt(getRotatedCovMatrixXX(primaryVertex.getCov(), phi, theta) + getRotatedCovMatrixXX(covVtx, phi, theta)); + + candidate.pt1 = trackParCov0.getPt(); + candidate.eta1 = trackParCov0.getEta(); + candidate.phi1 = RecoDecay::constrainAngle(trackParCov0.getPhi(), 0, 1U); // 0-2pi + + candidate.pt2 = trackParCov1.getPt(); + candidate.eta2 = trackParCov1.getEta(); + candidate.phi2 = RecoDecay::constrainAngle(trackParCov1.getPhi(), 0, 1U); // 0-2pi + + return true; + } + + template + bool findSVFwd(TCollision const& collision, TTrackParCov const& t1, TTrackParCov const& t2, dileptonSV& candidate) + { + try { + if (mFwdDCAFitter.process(t1, t2) == 0) { + return false; + } + } catch (const std::runtime_error& error) { + LOG(info) << "Run time error found: " << error.what() << ". FwdDCAFitterN cannot work, skipping the candidate."; + return false; + } + mFwdDCAFitter.FwdpropagateTracksToVertex(); + + std::array pvertex = {collision.posX(), collision.posY(), collision.posZ()}; + const auto& secondaryVertex = mFwdDCAFitter.getPCACandidate(); + candidate.chi2PCA = mFwdDCAFitter.getChi2AtPCACandidate(); + if (fdfGroup.maxLog10Chi2PCA < std::log10(candidate.chi2PCA)) { + return false; + } + auto trackParCov0 = mFwdDCAFitter.getTrack(0); + auto trackParCov1 = mFwdDCAFitter.getTrack(1); + std::array momDilepton = {static_cast(trackParCov0.getPx() + trackParCov1.getPx()), static_cast(trackParCov0.getPy() + trackParCov1.getPy()), static_cast(trackParCov0.getPz() + trackParCov1.getPz())}; + candidate.cpa = std::clamp(RecoDecay::cpa(pvertex, secondaryVertex, momDilepton), -1.0, std::nextafter(1.0, 0.0)); + + candidate.lxy = std::sqrt(std::pow(secondaryVertex[0] - collision.posX(), 2) + std::pow(secondaryVertex[1] - collision.posY(), 2)); + candidate.lz = secondaryVertex[2] - collision.posZ(); + candidate.lxyz = std::sqrt(std::pow(candidate.lxy, 2) + std::pow(candidate.lz, 2)); + + auto primaryVertex = getPrimaryVertex(collision); + std::array covVtx = mFwdDCAFitter.calcPCACovMatrixFlat(); + double phi{0}, theta{0}; + getPointDirection(std::array{primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ()}, secondaryVertex, phi, theta); + candidate.lxyErr = std::sqrt(getRotatedCovMatrixXX(primaryVertex.getCov(), phi, 0.) + getRotatedCovMatrixXX(covVtx, phi, 0.)); + candidate.lzErr = std::sqrt(getRotatedCovMatrixXX(primaryVertex.getCov(), 0, theta) + getRotatedCovMatrixXX(covVtx, 0, theta)); + candidate.lxyzErr = std::sqrt(getRotatedCovMatrixXX(primaryVertex.getCov(), phi, theta) + getRotatedCovMatrixXX(covVtx, phi, theta)); + + candidate.pt1 = trackParCov0.getPt(); + candidate.eta1 = trackParCov0.getEta(); + candidate.phi1 = RecoDecay::constrainAngle(trackParCov0.getPhi(), 0, 1U); // 0-2pi + + candidate.pt2 = trackParCov1.getPt(); + candidate.eta2 = trackParCov1.getEta(); + candidate.phi2 = RecoDecay::constrainAngle(trackParCov1.getPhi(), 0, 1U); // 0-2pi + + return true; + } + + template + void fillGenHistograms(const int sign1, const int sign2, const int pdgMotherC1, const int pdgMotherC2, const float mass, const float pt, const float rapidity, const float dphi, const float deta, const float cos_thetaPol, const float phiPol, const float quadmom, const float aco, const float asym, const float dphi_e_ee, const float weight) + { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/") + HIST(dilepton_source_types[sourceId]) + HIST("uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/") + HIST(dilepton_source_types[sourceId]) + HIST("lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/") + HIST(dilepton_source_types[sourceId]) + HIST("lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + + if (dilepton_source_types[sourceId].find("ccbar") != std::string_view::npos && cfgFillSeparateCharmHadronPairs) { + if (std::abs(pdgMotherC1) == 411 && std::abs(pdgMotherC2) == 411) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Dplus_Dminus/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Dplus_Dminus/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Dplus_Dminus/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if (std::abs(pdgMotherC1) == 421 && std::abs(pdgMotherC2) == 421) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/D0_D0bar/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/D0_D0bar/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/D0_D0bar/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if (std::abs(pdgMotherC1) == 431 && std::abs(pdgMotherC2) == 431) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Dsplus_Dsminus/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Dsplus_Dsminus/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Dsplus_Dsminus/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 411 && std::abs(pdgMotherC2) == 421) || (std::abs(pdgMotherC2) == 411 && std::abs(pdgMotherC1) == 421)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Dpm_D0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Dpm_D0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Dpm_D0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 411 && std::abs(pdgMotherC2) == 431) || (std::abs(pdgMotherC2) == 411 && std::abs(pdgMotherC1) == 431)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Dpm_Dspm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Dpm_Dspm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Dpm_Dspm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 421 && std::abs(pdgMotherC2) == 431) || (std::abs(pdgMotherC2) == 421 && std::abs(pdgMotherC1) == 431)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/D0_Dspm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/D0_Dspm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/D0_Dspm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if (std::abs(pdgMotherC1) == 4122 && std::abs(pdgMotherC2) == 4122) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Lcplus_Lcminus/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Lcplus_Lcminus/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Lcplus_Lcminus/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if (std::abs(pdgMotherC1) == 4232 && std::abs(pdgMotherC2) == 4232) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Xicplus_Xicminus/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Xicplus_Xicminus/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Xicplus_Xicminus/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if (std::abs(pdgMotherC1) == 4132 && std::abs(pdgMotherC2) == 4132) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Xic0_Xic0bar/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Xic0_Xic0bar/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Xic0_Xic0bar/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if (std::abs(pdgMotherC1) == 4332 && std::abs(pdgMotherC2) == 4332) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Omegac0_Omegac0bar/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Omegac0_Omegac0bar/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Omegac0_Omegac0bar/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 4122 && std::abs(pdgMotherC2) == 4232) || (std::abs(pdgMotherC2) == 4122 && std::abs(pdgMotherC1) == 4232)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Lcpm_Xicpm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Lcpm_Xicpm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Lcpm_Xicpm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 4122 && std::abs(pdgMotherC2) == 4132) || (std::abs(pdgMotherC2) == 4122 && std::abs(pdgMotherC1) == 4132)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Lcpm_Xic0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Lcpm_Xic0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Lcpm_Xic0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 4122 && std::abs(pdgMotherC2) == 4332) || (std::abs(pdgMotherC2) == 4122 && std::abs(pdgMotherC1) == 4332)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Lcpm_Omegac0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Lcpm_Omegac0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Lcpm_Omegac0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 4232 && std::abs(pdgMotherC2) == 4132) || (std::abs(pdgMotherC2) == 4232 && std::abs(pdgMotherC1) == 4132)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Xicpm_Xic0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Xicpm_Xic0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Xicpm_Xic0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 4232 && std::abs(pdgMotherC2) == 4332) || (std::abs(pdgMotherC2) == 4232 && std::abs(pdgMotherC1) == 4332)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Xicpm_Omegac0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Xicpm_Omegac0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Xicpm_Omegac0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 4132 && std::abs(pdgMotherC2) == 4332) || (std::abs(pdgMotherC2) == 4132 && std::abs(pdgMotherC1) == 4332)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Xic0_Omegac0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Xic0_Omegac0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Xic0_Omegac0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 411 && std::abs(pdgMotherC2) == 4122) || (std::abs(pdgMotherC2) == 411 && std::abs(pdgMotherC1) == 4122)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Dpm_Lcpm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Dpm_Lcpm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Dpm_Lcpm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 411 && std::abs(pdgMotherC2) == 4232) || (std::abs(pdgMotherC2) == 411 && std::abs(pdgMotherC1) == 4232)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Dpm_Xicpm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Dpm_Xicpm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Dpm_Xicpm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 411 && std::abs(pdgMotherC2) == 4132) || (std::abs(pdgMotherC2) == 411 && std::abs(pdgMotherC1) == 4132)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Dpm_Xic0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Dpm_Xic0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Dpm_Xic0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 411 && std::abs(pdgMotherC2) == 4332) || (std::abs(pdgMotherC2) == 411 && std::abs(pdgMotherC1) == 4332)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Dpm_Omegac0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Dpm_Omegac0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Dpm_Omegac0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 421 && std::abs(pdgMotherC2) == 4122) || (std::abs(pdgMotherC2) == 421 && std::abs(pdgMotherC1) == 4122)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/D0_Lcpm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/D0_Lcpm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/D0_Lcpm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 421 && std::abs(pdgMotherC2) == 4232) || (std::abs(pdgMotherC2) == 421 && std::abs(pdgMotherC1) == 4232)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/D0_Xicpm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/D0_Xicpm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/D0_Xicpm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 421 && std::abs(pdgMotherC2) == 4132) || (std::abs(pdgMotherC2) == 421 && std::abs(pdgMotherC1) == 4132)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/D0_Xic0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/D0_Xic0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/D0_Xic0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 421 && std::abs(pdgMotherC2) == 4332) || (std::abs(pdgMotherC2) == 421 && std::abs(pdgMotherC1) == 4332)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/D0_Omegac0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/D0_Omegac0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/D0_Omegac0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 431 && std::abs(pdgMotherC2) == 4122) || (std::abs(pdgMotherC2) == 431 && std::abs(pdgMotherC1) == 4122)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Dspm_Lcpm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Dspm_Lcpm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Dspm_Lcpm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 431 && std::abs(pdgMotherC2) == 4232) || (std::abs(pdgMotherC2) == 431 && std::abs(pdgMotherC1) == 4232)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Dspm_Xicpm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Dspm_Xicpm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Dspm_Xicpm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 431 && std::abs(pdgMotherC2) == 4132) || (std::abs(pdgMotherC2) == 431 && std::abs(pdgMotherC1) == 4132)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Dspm_Xic0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Dspm_Xic0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Dspm_Xic0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } else if ((std::abs(pdgMotherC1) == 431 && std::abs(pdgMotherC2) == 4332) || (std::abs(pdgMotherC2) == 431 && std::abs(pdgMotherC1) == 4332)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Generated/ccbar/Dspm_Omegac0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Generated/ccbar/Dspm_Omegac0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Generated/ccbar/Dspm_Omegac0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, weight); + } + } + } + } + + template + void fillRecHistograms(const int sign1, const int sign2, const int pdgMotherC1, const int pdgMotherC2, const float mass, const float pt, const float rapidity, const float dphi, const float deta, const float cos_thetaPol, const float phiPol, const float quadmom, const float aco, const float asym, const float dphi_e_ee, const float pair_dca, const float cpa, const float weight) + { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/") + HIST(dilepton_source_types[sourceId]) + HIST("uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/") + HIST(dilepton_source_types[sourceId]) + HIST("lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/") + HIST(dilepton_source_types[sourceId]) + HIST("lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + + if (dilepton_source_types[sourceId].find("ccbar") != std::string_view::npos && cfgFillSeparateCharmHadronPairs) { + if (std::abs(pdgMotherC1) == 411 && std::abs(pdgMotherC2) == 411) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Dplus_Dminus/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Dplus_Dminus/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Dplus_Dminus/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if (std::abs(pdgMotherC1) == 421 && std::abs(pdgMotherC2) == 421) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/D0_D0bar/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/D0_D0bar/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/D0_D0bar/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if (std::abs(pdgMotherC1) == 431 && std::abs(pdgMotherC2) == 431) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Dsplus_Dsminus/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Dsplus_Dsminus/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Dsplus_Dsminus/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 411 && std::abs(pdgMotherC2) == 421) || (std::abs(pdgMotherC2) == 411 && std::abs(pdgMotherC1) == 421)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Dpm_D0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Dpm_D0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Dpm_D0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 411 && std::abs(pdgMotherC2) == 431) || (std::abs(pdgMotherC2) == 411 && std::abs(pdgMotherC1) == 431)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Dpm_Dspm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Dpm_Dspm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Dpm_Dspm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 421 && std::abs(pdgMotherC2) == 431) || (std::abs(pdgMotherC2) == 421 && std::abs(pdgMotherC1) == 431)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/D0_Dspm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/D0_Dspm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/D0_Dspm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if (std::abs(pdgMotherC1) == 4122 && std::abs(pdgMotherC2) == 4122) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Lcplus_Lcminus/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Lcplus_Lcminus/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Lcplus_Lcminus/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if (std::abs(pdgMotherC1) == 4232 && std::abs(pdgMotherC2) == 4232) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Xicplus_Xicminus/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Xicplus_Xicminus/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Xicplus_Xicminus/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if (std::abs(pdgMotherC1) == 4132 && std::abs(pdgMotherC2) == 4132) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Xic0_Xic0bar/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Xic0_Xic0bar/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Xic0_Xic0bar/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if (std::abs(pdgMotherC1) == 4332 && std::abs(pdgMotherC2) == 4332) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Omegac0_Omegac0bar/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Omegac0_Omegac0bar/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Omegac0_Omegac0bar/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 4122 && std::abs(pdgMotherC2) == 4232) || (std::abs(pdgMotherC2) == 4122 && std::abs(pdgMotherC1) == 4232)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Lcpm_Xicpm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Lcpm_Xicpm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Lcpm_Xicpm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 4122 && std::abs(pdgMotherC2) == 4132) || (std::abs(pdgMotherC2) == 4122 && std::abs(pdgMotherC1) == 4132)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Lcpm_Xic0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Lcpm_Xic0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Lcpm_Xic0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 4122 && std::abs(pdgMotherC2) == 4332) || (std::abs(pdgMotherC2) == 4122 && std::abs(pdgMotherC1) == 4332)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Lcpm_Omegac0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Lcpm_Omegac0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Lcpm_Omegac0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 4232 && std::abs(pdgMotherC2) == 4132) || (std::abs(pdgMotherC2) == 4232 && std::abs(pdgMotherC1) == 4132)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Xicpm_Xic0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Xicpm_Xic0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Xicpm_Xic0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 4232 && std::abs(pdgMotherC2) == 4332) || (std::abs(pdgMotherC2) == 4232 && std::abs(pdgMotherC1) == 4332)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Xicpm_Omegac0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Xicpm_Omegac0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Xicpm_Omegac0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 4132 && std::abs(pdgMotherC2) == 4332) || (std::abs(pdgMotherC2) == 4132 && std::abs(pdgMotherC1) == 4332)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Xic0_Omegac0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Xic0_Omegac0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Xic0_Omegac0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 411 && std::abs(pdgMotherC2) == 4122) || (std::abs(pdgMotherC2) == 411 && std::abs(pdgMotherC1) == 4122)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Dpm_Lcpm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Dpm_Lcpm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Dpm_Lcpm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 411 && std::abs(pdgMotherC2) == 4232) || (std::abs(pdgMotherC2) == 411 && std::abs(pdgMotherC1) == 4232)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Dpm_Xicpm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Dpm_Xicpm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Dpm_Xicpm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 411 && std::abs(pdgMotherC2) == 4132) || (std::abs(pdgMotherC2) == 411 && std::abs(pdgMotherC1) == 4132)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Dpm_Xic0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Dpm_Xic0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Dpm_Xic0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 411 && std::abs(pdgMotherC2) == 4332) || (std::abs(pdgMotherC2) == 411 && std::abs(pdgMotherC1) == 4332)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Dpm_Omegac0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Dpm_Omegac0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Dpm_Omegac0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 421 && std::abs(pdgMotherC2) == 4122) || (std::abs(pdgMotherC2) == 421 && std::abs(pdgMotherC1) == 4122)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/D0_Lcpm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/D0_Lcpm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/D0_Lcpm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 421 && std::abs(pdgMotherC2) == 4232) || (std::abs(pdgMotherC2) == 421 && std::abs(pdgMotherC1) == 4232)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/D0_Xicpm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/D0_Xicpm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/D0_Xicpm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 421 && std::abs(pdgMotherC2) == 4132) || (std::abs(pdgMotherC2) == 421 && std::abs(pdgMotherC1) == 4132)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/D0_Xic0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/D0_Xic0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/D0_Xic0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 421 && std::abs(pdgMotherC2) == 4332) || (std::abs(pdgMotherC2) == 421 && std::abs(pdgMotherC1) == 4332)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/D0_Omegac0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/D0_Omegac0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/D0_Omegac0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 431 && std::abs(pdgMotherC2) == 4122) || (std::abs(pdgMotherC2) == 431 && std::abs(pdgMotherC1) == 4122)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Dspm_Lcpm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Dspm_Lcpm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Dspm_Lcpm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 431 && std::abs(pdgMotherC2) == 4232) || (std::abs(pdgMotherC2) == 431 && std::abs(pdgMotherC1) == 4232)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Dspm_Xicpm/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Dspm_Xicpm/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Dspm_Xicpm/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 431 && std::abs(pdgMotherC2) == 4132) || (std::abs(pdgMotherC2) == 431 && std::abs(pdgMotherC1) == 4132)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Dspm_Xic0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Dspm_Xic0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Dspm_Xic0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } else if ((std::abs(pdgMotherC1) == 431 && std::abs(pdgMotherC2) == 4332) || (std::abs(pdgMotherC2) == 431 && std::abs(pdgMotherC1) == 4332)) { + if (sign1 * sign2 < 0) { // ULS + fRegistry.fill(HIST("Pair/ccbar/Dspm_Omegac0/uls/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 > 0 && sign2 > 0) { // LS++ + fRegistry.fill(HIST("Pair/ccbar/Dspm_Omegac0/lspp/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } else if (sign1 < 0 && sign2 < 0) { // LS-- + fRegistry.fill(HIST("Pair/ccbar/Dspm_Omegac0/lsmm/hs"), mass, pt, rapidity, dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, dphi_e_ee, pair_dca, cpa, weight); + } + } + } + } + + template + bool fillTruePairInfo(TCollision const& collision, TMCCollisions const&, TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TAllTracks const&, TMCParticles const& mcparticles) + { + auto t1mc = mcparticles.iteratorAt(t1.emmcparticleId()); + auto t2mc = mcparticles.iteratorAt(t2.emmcparticleId()); + bool is_pair_from_same_mcevent = (t1mc.emmceventId() == t2mc.emmceventId()); + + auto mccollision1 = t1mc.template emmcevent_as(); + auto mccollision2 = t2mc.template emmcevent_as(); + if (cfgEventGeneratorType >= 0 && mccollision1.getSubGeneratorId() != cfgEventGeneratorType) { + return false; + } + if (cfgEventGeneratorType >= 0 && mccollision2.getSubGeneratorId() != cfgEventGeneratorType) { + return false; + } + if (!isInAcceptance(t1mc) || !isInAcceptance(t2mc)) { + return false; + } + + dileptonSV candidate; + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { + return false; + } + } else { // cut-based + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { + return false; + } + } + + auto trackParCov1 = getTrackParCov(t1); + auto trackParCov2 = getTrackParCov(t2); + if (!findSV(collision, trackParCov1, trackParCov2, candidate)) { + return false; + } + + if (!cut.IsSelectedPair(t1, t2)) { + return false; + } + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { + return false; + } + if (!map_best_match_globalmuon[t1.globalIndex()] || !map_best_match_globalmuon[t2.globalIndex()]) { + return false; + } + + bool isCorrectMatch1 = t1.emmcparticleId() == t1.emmftmcparticleId(); + bool isCorrectMatch2 = t2.emmcparticleId() == t2.emmftmcparticleId(); + + if (dimuoncuts.acceptOnlyCorrectMatch) { + if (t1.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && !isCorrectMatch1) { + return false; + } + if (t2.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && !isCorrectMatch2) { + return false; + } + } + if (dimuoncuts.acceptOnlyWrongMatch) { + if (t1.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && isCorrectMatch1) { + return false; + } + if (t2.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && isCorrectMatch2) { + return false; + } + } + if (dimuoncuts.acceptOnlyXORMatching) { // this is dummy comment. + if (t1.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && t2.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack)) { + if (!(isCorrectMatch1 ^ isCorrectMatch2)) { + return false; + } + } + } + + auto trackParCov1 = o2::aod::fwdtrackutils::getTrackParCovFwd(t1, t1); + auto trackParCov2 = o2::aod::fwdtrackutils::getTrackParCovFwd(t2, t2); + if (!findSVFwd(collision, trackParCov1, trackParCov2, candidate)) { + return false; + } + + if (!cut.IsSelectedPair(t1, t2)) { + return false; + } + } + + float pt1 = 0.f, eta1 = 0.f, phi1 = 0.f, pt2 = 0.f, eta2 = 0.f, phi2 = 0.f; + if constexpr (isSmeared) { + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + pt1 = t1mc.ptSmeared(); + eta1 = t1mc.etaSmeared(); + phi1 = t1mc.phiSmeared(); + pt2 = t2mc.ptSmeared(); + eta2 = t2mc.etaSmeared(); + phi2 = t2mc.phiSmeared(); + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + if (dimuoncuts.cfg_track_type == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack)) { + pt1 = t1mc.ptSmeared_sa_muon(); + eta1 = t1mc.etaSmeared_sa_muon(); + phi1 = t1mc.phiSmeared_sa_muon(); + pt2 = t2mc.ptSmeared_sa_muon(); + eta2 = t2mc.etaSmeared_sa_muon(); + phi2 = t2mc.phiSmeared_sa_muon(); + } else if (dimuoncuts.cfg_track_type == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack)) { + pt1 = t1mc.ptSmeared_gl_muon(); + eta1 = t1mc.etaSmeared_gl_muon(); + phi1 = t1mc.phiSmeared_gl_muon(); + pt2 = t2mc.ptSmeared_gl_muon(); + eta2 = t2mc.etaSmeared_gl_muon(); + phi2 = t2mc.phiSmeared_gl_muon(); + } else { + pt1 = t1mc.pt(); + eta1 = t1mc.eta(); + phi1 = t1mc.phi(); + pt2 = t2mc.pt(); + eta2 = t2mc.eta(); + phi2 = t2mc.phi(); + } + } + } else { + pt1 = t1mc.pt(); + eta1 = t1mc.eta(); + phi1 = t1mc.phi(); + pt2 = t2mc.pt(); + eta2 = t2mc.eta(); + phi2 = t2mc.phi(); + } + + ROOT::Math::PtEtaPhiMVector v1mc(pt1, eta1, phi1, leptonM1); + ROOT::Math::PtEtaPhiMVector v2mc(pt2, eta2, phi2, leptonM2); + ROOT::Math::PtEtaPhiMVector v12mc = v1mc + v2mc; + + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (v12mc.Rapidity() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < v12mc.Rapidity()) { + return false; + } + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + if (v12mc.Rapidity() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < v12mc.Rapidity()) { + return false; + } + } + + float weight = 1.f; + if (cfgApplyWeightTTCA) { + weight = map_weight[std::make_pair(t1.globalIndex(), t2.globalIndex())]; + } + // LOGF(info, "t1.sign() = %d, t2.sign() = %d, map_weight[std::make_pair(%d, %d)] = %f", t1.sign(), t2.sign(), t1.globalIndex(), t2.globalIndex(), weight); + + // ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), leptonM1); + // ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), leptonM2); + ROOT::Math::PtEtaPhiMVector v1(candidate.pt1, candidate.eta1, candidate.phi1, leptonM1); + ROOT::Math::PtEtaPhiMVector v2(candidate.pt2, candidate.eta2, candidate.phi2, leptonM2); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + + float pair_dca = 999.f; + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + pair_dca = o2::aod::pwgem::dilepton::utils::pairutil::pairDCAQuadSum(o2::aod::pwgem::dilepton::utils::emtrackutil::dca3DinSigma(t1), o2::aod::pwgem::dilepton::utils::emtrackutil::dca3DinSigma(t2)); + if (dielectroncuts.cfgDCAType == 1) { + pair_dca = o2::aod::pwgem::dilepton::utils::pairutil::pairDCAQuadSum(o2::aod::pwgem::dilepton::utils::emtrackutil::dcaXYinSigma(t1), o2::aod::pwgem::dilepton::utils::emtrackutil::dcaXYinSigma(t2)); + } else if (dielectroncuts.cfgDCAType == 2) { + pair_dca = o2::aod::pwgem::dilepton::utils::pairutil::pairDCAQuadSum(o2::aod::pwgem::dilepton::utils::emtrackutil::dcaZinSigma(t1), o2::aod::pwgem::dilepton::utils::emtrackutil::dcaZinSigma(t2)); + } + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + pair_dca = o2::aod::pwgem::dilepton::utils::pairutil::pairDCAQuadSum(o2::aod::pwgem::dilepton::utils::emtrackutil::fwdDcaXYinSigma(t1), o2::aod::pwgem::dilepton::utils::emtrackutil::fwdDcaXYinSigma(t2)); + } + float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), d_bz); + + float deta = v1.Eta() - v2.Eta(); + float dphi = v1.Phi() - v2.Phi(); + o2::math_utils::bringToPMPi(dphi); + + float aco = 1.f - std::fabs(dphi) / M_PI; + float asym = std::fabs(v1.Pt() - v2.Pt()) / (v1.Pt() + v2.Pt()); + float dphi_e_ee = v1.Phi() - v12.Phi(); + o2::math_utils::bringToPMPi(dphi_e_ee); + dphi = RecoDecay::constrainAngle(dphi, -o2::constants::math::PIHalf, 1); // shift dphi in [-pi/2, +3pi/2] rad. + + std::array arrP1 = {t1.px(), t1.py(), t1.pz(), leptonM1}; + std::array arrP2 = {t2.px(), t2.py(), t2.pz(), leptonM2}; + float cos_thetaPol = 999, phiPol = 999.f; + if (cfgPolarizationFrame == 0) { + o2::aod::pwgem::dilepton::utils::pairutil::getAngleCS(arrP1, arrP2, beamE1, beamE2, beamP1, beamP2, t1.sign(), cos_thetaPol, phiPol); + } else if (cfgPolarizationFrame == 1) { + o2::aod::pwgem::dilepton::utils::pairutil::getAngleHX(arrP1, arrP2, beamE1, beamE2, beamP1, beamP2, t1.sign(), cos_thetaPol, phiPol); + } + o2::math_utils::bringToPMPi(phiPol); + float quadmom = (3.f * std::pow(cos_thetaPol, 2) - 1.f) / 2.f; + + if ((o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2ProngsWithoutPDG(t1mc, t2mc) > 0 || o2::aod::pwgem::dilepton::utils::mcutil::IsHF(t1mc, t2mc, mcparticles) > 0) && is_pair_from_same_mcevent) { // for bkg study + if (std::abs(t1mc.pdgCode()) != pdg_lepton || std::abs(t2mc.pdgCode()) != pdg_lepton) { // hh or lh correlated bkg + if (std::abs(t1mc.pdgCode()) != pdg_lepton && std::abs(t2mc.pdgCode()) != pdg_lepton) { // hh correlated bkg + if (t1.sign() * t2.sign() < 0) { // ULS + fRegistry.fill(HIST("Pair/corr_bkg_hh/uls/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); + } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ + fRegistry.fill(HIST("Pair/corr_bkg_hh/lspp/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); + } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- + fRegistry.fill(HIST("Pair/corr_bkg_hh/lsmm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); + } + } else { // lh correlated bkg + if (t1.sign() * t2.sign() < 0) { // ULS + fRegistry.fill(HIST("Pair/corr_bkg_lh/uls/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); + } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ + fRegistry.fill(HIST("Pair/corr_bkg_lh/lspp/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); + } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- + fRegistry.fill(HIST("Pair/corr_bkg_lh/lsmm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); + } + } + } + } else { // true combinatorial bkg + if (t1.sign() * t2.sign() < 0) { // ULS + fRegistry.fill(HIST("Pair/comb_bkg/uls/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); + } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ + fRegistry.fill(HIST("Pair/comb_bkg/lspp/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); + } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- + fRegistry.fill(HIST("Pair/comb_bkg/lsmm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); + } + } + + if (std::abs(t1mc.pdgCode()) != pdg_lepton || std::abs(t2mc.pdgCode()) != pdg_lepton) { + return false; + } + + if (!is_pair_from_same_mcevent) { + return false; + } + if (cfgRequireTrueAssociation && (t1mc.emmceventId() != collision.emmceventId() || t2mc.emmceventId() != collision.emmceventId())) { + return false; + } + int mother_id = std::max({FindSMULS(t1mc, t2mc, mcparticles), FindSMULS(t2mc, t1mc, mcparticles), FindSMLSPP(t1mc, t2mc, mcparticles), FindSMLSMM(t1mc, t2mc, mcparticles)}); + int hfee_type = o2::aod::pwgem::dilepton::utils::mcutil::IsHF(t1mc, t2mc, mcparticles); + if (mother_id < 0 && hfee_type < 0) { + return false; + } + + if (mother_id > -1) { + auto mcmother = mcparticles.iteratorAt(mother_id); + if (mcmother.isPhysicalPrimary() || mcmother.producedByGenerator()) { + if ((t1mc.isPhysicalPrimary() || t1mc.producedByGenerator()) && (t2mc.isPhysicalPrimary() || t2mc.producedByGenerator())) { + switch (std::abs(mcmother.pdgCode())) { + case 111: + if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromCharm(mcmother, mcparticles) < 0 && o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mcmother, mcparticles) < 0) { // prompt pi0 + fillRecHistograms<1>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // prompt pi0 + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (t1.sign() * t2.sign() < 0) { // ULS + fRegistry.fill(HIST("Pair/sm/PromptPi0/uls/hMvsPhiV"), phiv, v12.M()); + } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ + fRegistry.fill(HIST("Pair/sm/PromptPi0/lspp/hMvsPhiV"), phiv, v12.M()); + } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- + fRegistry.fill(HIST("Pair/sm/PromptPi0/lsmm/hMvsPhiV"), phiv, v12.M()); + } + } + } else { // non-prompt pi0 + fillRecHistograms<2>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // non-prompt pi0 + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (t1.sign() * t2.sign() < 0) { // ULS + fRegistry.fill(HIST("Pair/sm/NonPromptPi0/uls/hMvsPhiV"), phiv, v12.M()); + } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ + fRegistry.fill(HIST("Pair/sm/NonPromptPi0/lspp/hMvsPhiV"), phiv, v12.M()); + } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- + fRegistry.fill(HIST("Pair/sm/NonPromptPi0/lsmm/hMvsPhiV"), phiv, v12.M()); + } + } + } + break; + case 221: + fillRecHistograms<3>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // eta + break; + case 331: + fillRecHistograms<4>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // eta' + break; + case 113: + fillRecHistograms<5>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // rho + break; + case 223: + fillRecHistograms<6>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // omega + if (mcmother.daughtersIds().size() == 2) { + if (t1.sign() * t2.sign() < 0) { // ULS + fRegistry.fill(HIST("Pair/sm/Omega2ll/uls/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // omeag->ee + } + } + break; + case 333: + fillRecHistograms<7>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // phi + if (mcmother.daughtersIds().size() == 2) { + if (t1.sign() * t2.sign() < 0) { // ULS + fRegistry.fill(HIST("Pair/sm/Phi2ll/uls/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // phi->ee + } + } + break; + case 443: + if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mcmother, mcparticles) > 0) { + fillRecHistograms<9>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // non-prompt J/psi + } else { + fillRecHistograms<8>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // prompt J/psi + } + break; + case 100443: + if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mcmother, mcparticles) > 0) { + fillRecHistograms<11>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // non-prompt psi2S + } else { + fillRecHistograms<10>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // prompt psi2S + } + break; + default: + break; + } + } else if (!(t1mc.isPhysicalPrimary() || t1mc.producedByGenerator()) && !(t2mc.isPhysicalPrimary() || t2mc.producedByGenerator())) { + switch (std::abs(mcmother.pdgCode())) { + case 22: + fillRecHistograms<0>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // photon conversion + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + fRegistry.fill(HIST("Pair/sm/Photon/uls/hMvsPhiV"), phiv, v12.M()); + float rxy_gen = std::sqrt(std::pow(t1mc.vx(), 2) + std::pow(t1mc.vy(), 2)); + fRegistry.fill(HIST("Pair/sm/Photon/uls/hMvsRxy"), rxy_gen, v12.M()); + } + break; + default: + break; + } + } // end of primary/secondary selection + } // end of primary selection for same mother + } else if (hfee_type > -1) { + if ((t1mc.isPhysicalPrimary() || t1mc.producedByGenerator()) && (t2mc.isPhysicalPrimary() || t2mc.producedByGenerator())) { + auto mp1 = mcparticles.iteratorAt(t1mc.mothersIds()[0]); + auto mp2 = mcparticles.iteratorAt(t2mc.mothersIds()[0]); + switch (hfee_type) { + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kCe_Ce): + fillRecHistograms<15>(t1.sign(), t2.sign(), mp1.pdgCode(), mp2.pdgCode(), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // c2l_c2l + break; + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kBe_Be): + fillRecHistograms<16>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // b2l_b2l + break; + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kBCe_BCe): + fillRecHistograms<17>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // b2c2l_b2c2l + break; + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kBCe_Be_SameB): + fillRecHistograms<18>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // b2c2l_b2l_sameb + break; + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kBCe_Be_DiffB): + fillRecHistograms<19>(t1.sign(), t2.sign(), 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), pair_dca, candidate.cpa, weight); // b2c2l_b2l_diffb + break; + default: + break; + } + } + } // end of HF evaluation + return true; + } + + template + bool fillGenPairInfo(TMCParticle const& t1, TMCParticle const& t2, TMCParticles const& mcparticles) + { + if (!t1.isPhysicalPrimary() && !t1.producedByGenerator()) { + return false; + } + if (!t2.isPhysicalPrimary() && !t2.producedByGenerator()) { + return false; + } + + int mother_id = std::max({FindSMULS(t1, t2, mcparticles), FindSMULS(t2, t1, mcparticles), FindSMLSPP(t1, t2, mcparticles), FindSMLSMM(t1, t2, mcparticles)}); + int hfee_type = o2::aod::pwgem::dilepton::utils::mcutil::IsHF(t1, t2, mcparticles); + if (mother_id < 0 && hfee_type < 0) { + return false; + } + + float pt1 = 0.f, eta1 = 0.f, phi1 = 0.f, pt2 = 0.f, eta2 = 0.f, phi2 = 0.f; + if constexpr (isSmeared) { + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + pt1 = t1.ptSmeared(); + eta1 = t1.etaSmeared(); + phi1 = t1.phiSmeared(); + pt2 = t2.ptSmeared(); + eta2 = t2.etaSmeared(); + phi2 = t2.phiSmeared(); + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + if (dimuoncuts.cfg_track_type == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack)) { + pt1 = t1.ptSmeared_sa_muon(); + eta1 = t1.etaSmeared_sa_muon(); + phi1 = t1.phiSmeared_sa_muon(); + pt2 = t2.ptSmeared_sa_muon(); + eta2 = t2.etaSmeared_sa_muon(); + phi2 = t2.phiSmeared_sa_muon(); + } else if (dimuoncuts.cfg_track_type == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack)) { + pt1 = t1.ptSmeared_gl_muon(); + eta1 = t1.etaSmeared_gl_muon(); + phi1 = t1.phiSmeared_gl_muon(); + pt2 = t2.ptSmeared_gl_muon(); + eta2 = t2.etaSmeared_gl_muon(); + phi2 = t2.phiSmeared_gl_muon(); + } else { + pt1 = t1.pt(); + eta1 = t1.eta(); + phi1 = t1.phi(); + pt2 = t2.pt(); + eta2 = t2.eta(); + phi2 = t2.phi(); + } + } + } else { + pt1 = t1.pt(); + eta1 = t1.eta(); + phi1 = t1.phi(); + pt2 = t2.pt(); + eta2 = t2.eta(); + phi2 = t2.phi(); + } + + ROOT::Math::PtEtaPhiMVector v1(pt1, eta1, phi1, leptonM1); + ROOT::Math::PtEtaPhiMVector v2(pt2, eta2, phi2, leptonM2); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + + float deta = v1.Eta() - v2.Eta(); + float dphi = v1.Phi() - v2.Phi(); + o2::math_utils::bringToPMPi(dphi); + + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (v12.Rapidity() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < v12.Rapidity()) { + return false; + } + // if (dielectroncuts.cfg_apply_detadphi && std::pow(deta / dielectroncuts.cfg_min_deta, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi, 2) < 1.f) { + // continue; + // } + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + if (v12.Rapidity() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < v12.Rapidity()) { + return false; + } + // if (dimuoncuts.cfg_apply_detadphi && std::pow(deta / dimuoncuts.cfg_min_deta, 2) + std::pow(dphi / dimuoncuts.cfg_min_dphi, 2) < 1.f) { + // continue; + // } + } + + int sign1 = -t1.pdgCode() / pdg_lepton; + int sign2 = -t2.pdgCode() / pdg_lepton; + + float aco = 1.f - std::fabs(dphi) / M_PI; + float asym = std::fabs(v1.Pt() - v2.Pt()) / (v1.Pt() + v2.Pt()); + float dphi_e_ee = v1.Phi() - v12.Phi(); + o2::math_utils::bringToPMPi(dphi_e_ee); + dphi = RecoDecay::constrainAngle(dphi, -o2::constants::math::PIHalf, 1); // shift dphi in [-pi/2, +3pi/2] rad. after deta-dphi cut. + + std::array arrP1 = {static_cast(v1.Px()), static_cast(v1.Py()), static_cast(v1.Pz()), leptonM1}; + std::array arrP2 = {static_cast(v2.Px()), static_cast(v2.Py()), static_cast(v2.Pz()), leptonM2}; + float cos_thetaPol = 999, phiPol = 999.f; + if (cfgPolarizationFrame == 0) { + o2::aod::pwgem::dilepton::utils::pairutil::getAngleCS(arrP1, arrP2, beamE1, beamE2, beamP1, beamP2, -t1.pdgCode() / pdg_lepton, cos_thetaPol, phiPol); + } else if (cfgPolarizationFrame == 1) { + o2::aod::pwgem::dilepton::utils::pairutil::getAngleHX(arrP1, arrP2, beamE1, beamE2, beamP1, beamP2, -t1.pdgCode() / pdg_lepton, cos_thetaPol, phiPol); + } + o2::math_utils::bringToPMPi(phiPol); + float quadmom = (3.f * std::pow(cos_thetaPol, 2) - 1.f) / 2.f; + + if (!isInAcceptance(t1) || !isInAcceptance(t2)) { + return false; + } + + float weight = 1.f; + if (mother_id > -1) { + auto mcmother = mcparticles.iteratorAt(mother_id); + if (mcmother.isPhysicalPrimary() || mcmother.producedByGenerator()) { + switch (std::abs(mcmother.pdgCode())) { + case 111: + if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromCharm(mcmother, mcparticles) < 0 && o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mcmother, mcparticles) < 0) { // prompt pi0 + fillGenHistograms<1>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // prompt pi0 + } else { // non-prompt pi0 + fillGenHistograms<2>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // non-prompt pi0 + } + break; + case 221: + fillGenHistograms<3>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // eta + break; + case 331: + fillGenHistograms<4>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // eta' + break; + case 113: + fillGenHistograms<5>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // rho + break; + case 223: + fillGenHistograms<6>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // omega + if (mcmother.daughtersIds().size() == 2) { + fRegistry.fill(HIST("Generated/sm/Omega2ll/uls/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // omega->ee + } + break; + case 333: + fillGenHistograms<7>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // phi + if (mcmother.daughtersIds().size() == 2) { + fRegistry.fill(HIST("Generated/sm/Phi2ll/uls/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee)); // phi->ee + } + break; + case 443: + if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mcmother, mcparticles) > 0) { + fillGenHistograms<9>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // non-prompt J/psi + } else { + fillGenHistograms<8>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // prompt J/psi + } + break; + case 100443: + if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mcmother, mcparticles) > 0) { + fillGenHistograms<11>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // non-prompt psi2S + } else { + fillGenHistograms<10>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // prompt psi2S + } + break; + default: + break; + } + } + } else if (hfee_type > -1) { + auto mp1 = mcparticles.iteratorAt(t1.mothersIds()[0]); + auto mp2 = mcparticles.iteratorAt(t2.mothersIds()[0]); + switch (hfee_type) { + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kCe_Ce): + fillGenHistograms<15>(sign1, sign2, mp1.pdgCode(), mp2.pdgCode(), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // c2l_c2l + break; + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kBe_Be): + fillGenHistograms<16>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // b2l_b2l + break; + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kBCe_BCe): + fillGenHistograms<17>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // b2c2l_b2c2l + break; + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kBCe_Be_SameB): + fillGenHistograms<18>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // b2c2l_b2l_sameb + break; + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kBCe_Be_DiffB): + fillGenHistograms<19>(sign1, sign2, 0, 0, v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, cos_thetaPol, phiPol, quadmom, aco, asym, std::fabs(dphi_e_ee), weight); // b2c2l_b2l_diffb + break; + default: + break; + } + } // end of HF evaluation + return false; + } + + template + bool fillGenParticleAcc(TMCParticle const& mcParticle, TMCParticles const& mcParticles) + { + if (!mcParticle.isPhysicalPrimary() && !mcParticle.producedByGenerator()) { + return false; + } + if (mcParticle.daughtersIds().size() < 2) { + return false; + } + + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (mcParticle.y() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < mcParticle.y()) { + return false; + } + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + if (mcParticle.y() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < mcParticle.y()) { + return false; + } + } + + int pdg = mcParticle.pdgCode(); + if (std::abs(pdg) == 113 && mcParticle.daughtersIds().size() != 2) { // reject dalitz decay + return false; + } + if (std::abs(pdg) == 223 && mcParticle.daughtersIds().size() != 2) { // reject dalitz decay + return false; + } + if (std::abs(pdg) == 333 && mcParticle.daughtersIds().size() != 2) { // reject dalitz decay + return false; + } + // accept radiative decay of charmonia (ee + multiple gamma). + + // float pt1 = 0.f, eta1 = 0.f, phi1 = 0.f, sign1 = 0.f; + // float pt2 = 0.f, eta2 = 0.f, phi2 = 0.f, sign2 = 0.f; + std::vector> vDau; + vDau.reserve(mcParticle.daughtersIds().size()); + for (const auto& daughterId : mcParticle.daughtersIds()) { + auto dau = mcParticles.rawIteratorAt(daughterId); + if (std::abs(dau.pdgCode()) == pdg_lepton) { + vDau.emplace_back(std::array{dau.pt(), dau.eta(), dau.phi(), dau.pdgCode() > 0 ? -1.f : +1.f}); + } + } + if (vDau.size() != 2 || vDau[0][3] * vDau[1][3] > 0.f) { // decay objects must be ULS 2 leptons. + vDau.clear(); + vDau.shrink_to_fit(); + return false; + } + + // LOGF(info, "mcParticle.globalIndex() = %d, mcParticle.pdgCode() = %d, mcParticle.daughtersIds().size() = %d", mcParticle.globalIndex(), mcParticle.pdgCode(), mcParticle.daughtersIds().size()); + + ROOT::Math::PtEtaPhiMVector v1(vDau[0][0], vDau[0][1], vDau[0][2], leptonM1); + ROOT::Math::PtEtaPhiMVector v2(vDau[1][0], vDau[1][1], vDau[1][2], leptonM2); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + + std::array arrP1 = {static_cast(v1.Px()), static_cast(v1.Py()), static_cast(v1.Pz()), leptonM1}; + std::array arrP2 = {static_cast(v2.Px()), static_cast(v2.Py()), static_cast(v2.Pz()), leptonM2}; + float cos_thetaPol = 999, phiPol = 999.f; + if (cfgPolarizationFrame == 0) { + o2::aod::pwgem::dilepton::utils::pairutil::getAngleCS(arrP1, arrP2, beamE1, beamE2, beamP1, beamP2, vDau[0][3] > 0 ? 1 : -1, cos_thetaPol, phiPol); + } else if (cfgPolarizationFrame == 1) { + o2::aod::pwgem::dilepton::utils::pairutil::getAngleHX(arrP1, arrP2, beamE1, beamE2, beamP1, beamP2, vDau[0][3] > 0 ? 1 : -1, cos_thetaPol, phiPol); + } + o2::math_utils::bringToPMPi(phiPol); + float quadmom = (3.f * std::pow(cos_thetaPol, 2) - 1.f) / 2.f; + + float weight = 1.f; + switch (std::abs(mcParticle.pdgCode())) { + case 113: + fRegistry.fill(HIST("Generated/VM/All/Rho/hs"), v12.M(), mcParticle.pt(), mcParticle.y(), cos_thetaPol, phiPol, quadmom, weight); + if (isInAcceptance(v1.Pt(), v1.Eta()) && isInAcceptance(v2.Pt(), v2.Eta())) { + fRegistry.fill(HIST("Generated/VM/Acc/Rho/hs"), v12.M(), mcParticle.pt(), mcParticle.y(), cos_thetaPol, phiPol, quadmom, weight); + } + break; + case 223: + fRegistry.fill(HIST("Generated/VM/All/Omega/hs"), v12.M(), mcParticle.pt(), mcParticle.y(), cos_thetaPol, phiPol, quadmom, weight); + if (isInAcceptance(v1.Pt(), v1.Eta()) && isInAcceptance(v2.Pt(), v2.Eta())) { + fRegistry.fill(HIST("Generated/VM/Acc/Omega/hs"), v12.M(), mcParticle.pt(), mcParticle.y(), cos_thetaPol, phiPol, quadmom, weight); + } + break; + case 333: + fRegistry.fill(HIST("Generated/VM/All/Phi/hs"), v12.M(), mcParticle.pt(), mcParticle.y(), cos_thetaPol, phiPol, quadmom, weight); + if (isInAcceptance(v1.Pt(), v1.Eta()) && isInAcceptance(v2.Pt(), v2.Eta())) { + fRegistry.fill(HIST("Generated/VM/Acc/Phi/hs"), v12.M(), mcParticle.pt(), mcParticle.y(), cos_thetaPol, phiPol, quadmom, weight); + } + break; + case 443: + if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mcParticle, mcParticles) > 0) { + fRegistry.fill(HIST("Generated/VM/All/NonPromptJPsi/hs"), v12.M(), mcParticle.pt(), mcParticle.y(), cos_thetaPol, phiPol, quadmom, weight); + if (isInAcceptance(v1.Pt(), v1.Eta()) && isInAcceptance(v2.Pt(), v2.Eta())) { + fRegistry.fill(HIST("Generated/VM/Acc/NonPromptJPsi/hs"), v12.M(), mcParticle.pt(), mcParticle.y(), cos_thetaPol, phiPol, quadmom, weight); + } + } else { + fRegistry.fill(HIST("Generated/VM/All/PromptJPsi/hs"), v12.M(), mcParticle.pt(), mcParticle.y(), cos_thetaPol, phiPol, quadmom, weight); + if (isInAcceptance(v1.Pt(), v1.Eta()) && isInAcceptance(v2.Pt(), v2.Eta())) { + fRegistry.fill(HIST("Generated/VM/Acc/PromptJPsi/hs"), v12.M(), mcParticle.pt(), mcParticle.y(), cos_thetaPol, phiPol, quadmom, weight); + } + } + break; + default: + break; + } + + vDau.clear(); + vDau.shrink_to_fit(); + return false; + } + + template + void runTruePairing(TCollisions const& collisions, TMCLeptons const& posTracks, TMCLeptons const& negTracks, TPreslice const& perCollision, TCut const& cut, TAllTracks const& tracks, TMCCollisions const& mccollisions, TMCParticles const& mcparticles) + { + for (const auto& collision : collisions) { + initCCDB(collision); + float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; + if (centralities[cfgCentEstimator] < eventcuts.cfgCentMin || eventcuts.cfgCentMax < centralities[cfgCentEstimator]) { + continue; + } + + o2::aod::pwgem::dilepton::utils::eventhistogram::fillEventInfo<0, -1>(&fRegistry, collision); + if (!fEMEventCut.IsSelected(collision)) { + continue; + } + if (eventcuts.cfgRequireGoodRCT && !rctChecker.checkTable(collision)) { + continue; + } + o2::aod::pwgem::dilepton::utils::eventhistogram::fillEventInfo<1, -1>(&fRegistry, collision); + fRegistry.fill(HIST("Event/before/hCollisionCounter"), o2::aod::pwgem::dilepton::utils::eventhistogram::nbin_ev); // accepted + fRegistry.fill(HIST("Event/after/hCollisionCounter"), o2::aod::pwgem::dilepton::utils::eventhistogram::nbin_ev); // accepted + + auto posTracks_per_coll = posTracks.sliceByCached(perCollision, collision.globalIndex(), cache); + auto negTracks_per_coll = negTracks.sliceByCached(perCollision, collision.globalIndex(), cache); + // LOGF(info, "centrality = %f , posTracks_per_coll.size() = %d, negTracks_per_coll.size() = %d", centralities[cfgCentEstimator], posTracks_per_coll.size(), negTracks_per_coll.size()); + + for (const auto& [pos, neg] : combinations(o2::soa::CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS + fillTruePairInfo(collision, mccollisions, pos, neg, cut, tracks, mcparticles); + } // end of ULS pair loop + + for (const auto& [pos1, pos2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ + fillTruePairInfo(collision, mccollisions, pos1, pos2, cut, tracks, mcparticles); + } // end of LS++ pair loop + + for (const auto& [neg1, neg2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- + fillTruePairInfo(collision, mccollisions, neg1, neg2, cut, tracks, mcparticles); + } // end of LS-- pair loop + + } // end of collision loop + } + + template + void runGenInfo(TCollisions const& collisions, TMCCollisions const& mccollisions, TMCLeptons const& posTracksMC, TMCLeptons const& negTracksMC, TMCParticles const& mcparticles) + { + for (const auto& mccollision : mccollisions) { + if (cfgEventGeneratorType >= 0 && mccollision.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } + fRegistry.fill(HIST("MCEvent/before/hZvtx"), mccollision.posZ()); + if (mccollision.mpemeventId() < 0) { + continue; + } + auto collision = collisions.rawIteratorAt(mccollision.mpemeventId()); + + float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; + if (centralities[cfgCentEstimator] < eventcuts.cfgCentMin || eventcuts.cfgCentMax < centralities[cfgCentEstimator]) { + continue; + } + fRegistry.fill(HIST("MCEvent/before/hZvtx_rec"), mccollision.posZ()); + if (!fEMEventCut.IsSelected(collision)) { + continue; + } + if (eventcuts.cfgRequireGoodRCT && !rctChecker.checkTable(collision)) { + continue; + } + if (!(eventcuts.cfgTrackOccupancyMin <= collision.trackOccupancyInTimeRange() && collision.trackOccupancyInTimeRange() < eventcuts.cfgTrackOccupancyMax)) { + continue; + } + if (!(eventcuts.cfgFT0COccupancyMin <= collision.ft0cOccupancyInTimeRange() && collision.ft0cOccupancyInTimeRange() < eventcuts.cfgFT0COccupancyMax)) { + continue; + } + fRegistry.fill(HIST("MCEvent/after/hZvtx"), mccollision.posZ()); + + auto posTracks_per_coll = posTracksMC.sliceByCachedUnsorted(o2::aod::emmcparticle::emmceventId, mccollision.globalIndex(), cache); + auto negTracks_per_coll = negTracksMC.sliceByCachedUnsorted(o2::aod::emmcparticle::emmceventId, mccollision.globalIndex(), cache); + + for (const auto& [t1, t2] : combinations(o2::soa::CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS + fillGenPairInfo(t1, t2, mcparticles); + } // end of true ULS pair loop + + for (const auto& [t1, t2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ + fillGenPairInfo(t1, t2, mcparticles); + } // end of true LS++ pair loop + + for (const auto& [t1, t2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- + fillGenPairInfo(t1, t2, mcparticles); + } // end of true LS-- pair loop + + // acceptance for polarization of vector mesons + auto mcParticles_per_coll = mcparticles.sliceBy(perMcCollision, mccollision.globalIndex()); + for (const auto& mcParticle : mcParticles_per_coll) { + if (!mcParticle.isPhysicalPrimary() && !mcParticle.producedByGenerator()) { + continue; + } + int pdg = std::abs(mcParticle.pdgCode()); + if (pdg == 113 || pdg == 223 || pdg == 333 || pdg == 443) { // select only VMs + fillGenParticleAcc(mcParticle, mcparticles); // VMs that decay into dilepton are stored in derived data. This is sufficient for polarization. + } + } // end of mc particle loop + } // end of collision loop + } + + template + bool isPairOK(TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TAllTracks const&) + { + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { + return false; + } + } else { // cut-based + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { + return false; + } + } + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { + return false; + } + if (!map_best_match_globalmuon[t1.globalIndex()] || !map_best_match_globalmuon[t2.globalIndex()]) { + return false; + } + // if (!o2::aod::pwgem::dilepton::utils::emtrackutil::isBestMatch(t1, cut, tracks)) { + // return false; + // } + // if (!o2::aod::pwgem::dilepton::utils::emtrackutil::isBestMatch(t2, cut, tracks)) { + // return false; + // } + } + + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (!cut.template IsSelectedPair(t1, t2)) { + return false; + } + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + if (!cut.template IsSelectedPair(t1, t2)) { + return false; + } + } + return true; + } + + std::map, float> map_weight; // -> float + template + void fillPairWeightMap(TCollisions const& collisions, TTracks1 const& posTracks, TTracks2 const& negTracks, TPresilce const& perCollision, TCut const& cut, TAllTracks const& tracks, TMCCollisions const&, TMCParticles const& mcparticles) + { + std::vector> passed_pairIds; + passed_pairIds.reserve(posTracks.size() * negTracks.size()); + + for (const auto& collision : collisions) { + initCCDB(collision); + const float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; + if (centralities[cfgCentEstimator] < eventcuts.cfgCentMin || eventcuts.cfgCentMax < centralities[cfgCentEstimator]) { + continue; + } + + if (!fEMEventCut.IsSelected(collision)) { + continue; + } + if (eventcuts.cfgRequireGoodRCT && !rctChecker.checkTable(collision)) { + continue; + } + + // auto mccollision = collision.template emmcevent_as(); + // if (cfgEventGeneratorType >= 0 && mccollision.getSubGeneratorId() != cfgEventGeneratorType) { + // continue; + // } + + auto posTracks_per_coll = posTracks.sliceByCached(perCollision, collision.globalIndex(), cache); + auto negTracks_per_coll = negTracks.sliceByCached(perCollision, collision.globalIndex(), cache); + + for (const auto& [pos, neg] : combinations(o2::soa::CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS + auto mcpos = mcparticles.iteratorAt(pos.emmcparticleId()); + auto mccollision_from_pos = mcpos.template emmcevent_as(); + if (cfgEventGeneratorType >= 0 && mccollision_from_pos.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } + auto mcneg = mcparticles.iteratorAt(neg.emmcparticleId()); + auto mccollision_from_neg = mcneg.template emmcevent_as(); + if (cfgEventGeneratorType >= 0 && mccollision_from_neg.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } + if (cfgRequireTrueAssociation && (mcpos.emmceventId() != collision.emmceventId() || mcneg.emmceventId() != collision.emmceventId())) { + continue; + } + + if (isPairOK(pos, neg, cut, tracks)) { + passed_pairIds.emplace_back(std::make_pair(pos.globalIndex(), neg.globalIndex())); + } + } + for (const auto& [pos1, pos2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ + auto mcpos1 = mcparticles.iteratorAt(pos1.emmcparticleId()); + auto mccollision_from_pos1 = mcpos1.template emmcevent_as(); + if (cfgEventGeneratorType >= 0 && mccollision_from_pos1.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } + auto mcpos2 = mcparticles.iteratorAt(pos2.emmcparticleId()); + auto mccollision_from_pos2 = mcpos2.template emmcevent_as(); + if (cfgEventGeneratorType >= 0 && mccollision_from_pos2.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } + if (cfgRequireTrueAssociation && (mcpos1.emmceventId() != collision.emmceventId() || mcpos2.emmceventId() != collision.emmceventId())) { + continue; + } + + if (isPairOK(pos1, pos2, cut, tracks)) { + passed_pairIds.emplace_back(std::make_pair(pos1.globalIndex(), pos2.globalIndex())); + } + } + for (const auto& [neg1, neg2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- + auto mcneg1 = mcparticles.iteratorAt(neg1.emmcparticleId()); + auto mccollision_from_neg1 = mcneg1.template emmcevent_as(); + if (cfgEventGeneratorType >= 0 && mccollision_from_neg1.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } + auto mcneg2 = mcparticles.iteratorAt(neg2.emmcparticleId()); + auto mccollision_from_neg2 = mcneg2.template emmcevent_as(); + if (cfgEventGeneratorType >= 0 && mccollision_from_neg2.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } + if (cfgRequireTrueAssociation && (mcneg1.emmceventId() != collision.emmceventId() || mcneg2.emmceventId() != collision.emmceventId())) { + continue; + } + if (isPairOK(neg1, neg2, cut, tracks)) { + passed_pairIds.emplace_back(std::make_pair(neg1.globalIndex(), neg2.globalIndex())); + } + } + } // end of collision loop + + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + for (const auto& pairId : passed_pairIds) { + auto t1 = tracks.rawIteratorAt(std::get<0>(pairId)); + auto t2 = tracks.rawIteratorAt(std::get<1>(pairId)); + // LOGF(info, "std::get<0>(pairId) = %d, std::get<1>(pairId) = %d, t1.globalIndex() = %d, t2.globalIndex() = %d", std::get<0>(pairId), std::get<1>(pairId), t1.globalIndex(), t2.globalIndex()); + + float n = 1.f; // include myself. + for (const auto& ambId1 : t1.ambiguousElectronsIds()) { + for (const auto& ambId2 : t2.ambiguousElectronsIds()) { + if (std::find(passed_pairIds.begin(), passed_pairIds.end(), std::make_pair(ambId1, ambId2)) != passed_pairIds.end()) { + n += 1.f; + } + } + } + map_weight[pairId] = 1.f / n; + } // end of passed_pairIds loop + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + for (const auto& pairId : passed_pairIds) { + auto t1 = tracks.rawIteratorAt(std::get<0>(pairId)); + auto t2 = tracks.rawIteratorAt(std::get<1>(pairId)); + + float n = 1.f; // include myself. + for (const auto& ambId1 : t1.ambiguousMuonsIds()) { + for (const auto& ambId2 : t2.ambiguousMuonsIds()) { + if (std::find(passed_pairIds.begin(), passed_pairIds.end(), std::make_pair(ambId1, ambId2)) != passed_pairIds.end()) { + n += 1.f; + } + } + } + map_weight[pairId] = 1.f / n; + } // end of passed_pairIds loop + } + passed_pairIds.clear(); + passed_pairIds.shrink_to_fit(); + } + + template + bool isPairInAcc(TTrack const& t1, TTrack const& t2) + { + ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), leptonM1); + ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), leptonM2); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if ((t1.pt() < dielectroncuts.cfg_min_pt_track || dielectroncuts.cfg_max_pt_track < t1.pt()) || (t2.pt() < dielectroncuts.cfg_min_pt_track || dielectroncuts.cfg_max_pt_track < t2.pt())) { + return false; + } + if ((t1.eta() < dielectroncuts.cfg_min_eta_track || dielectroncuts.cfg_max_eta_track < t1.eta()) || (t2.eta() < dielectroncuts.cfg_min_eta_track || dielectroncuts.cfg_max_eta_track < t2.eta())) { + return false; + } + if (v12.Rapidity() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < v12.Rapidity()) { + return false; + } + return true; + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + if ((t1.pt() < dimuoncuts.cfg_min_pt_track || dimuoncuts.cfg_max_pt_track < t1.pt()) || (t2.pt() < dimuoncuts.cfg_min_pt_track || dimuoncuts.cfg_max_pt_track < t2.pt())) { + return false; + } + if ((t1.eta() < dimuoncuts.cfg_min_eta_track || dimuoncuts.cfg_max_eta_track < t1.eta()) || (t2.eta() < dimuoncuts.cfg_min_eta_track || dimuoncuts.cfg_max_eta_track < t2.eta())) { + return false; + } + if (v12.Rapidity() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < v12.Rapidity()) { + return false; + } + return true; + } else { + return false; + } + return true; + } + + template + void fillHistogramsUnfolding(TTrack const& t1, TTrack const& t2, TMCParticles const& mcparticles) + { + auto t1mc = mcparticles.iteratorAt(t1.emmcparticleId()); + auto t2mc = mcparticles.iteratorAt(t2.emmcparticleId()); + + ROOT::Math::PtEtaPhiMVector v1rec(t1.pt(), t1.eta(), t1.phi(), leptonM1); + ROOT::Math::PtEtaPhiMVector v2rec(t2.pt(), t2.eta(), t2.phi(), leptonM2); + ROOT::Math::PtEtaPhiMVector v12rec = v1rec + v2rec; + + ROOT::Math::PtEtaPhiMVector v1mc(t1mc.pt(), t1mc.eta(), t1mc.phi(), leptonM1); + ROOT::Math::PtEtaPhiMVector v2mc(t2mc.pt(), t2mc.eta(), t2mc.phi(), leptonM2); + ROOT::Math::PtEtaPhiMVector v12mc = v1mc + v2mc; + + float weight = 1.f; + if (cfgApplyWeightTTCA) { + weight = map_weight[std::make_pair(t1.globalIndex(), t2.globalIndex())]; + } + + if (isPairInAcc(t1, t2) && isPairInAcc(t1mc, t2mc)) { // both rec and mc info are in acceptance. + if (t1.sign() * t2.sign() < 0) { // ULS + fRegistry.fill(HIST("Unfold/") + HIST(unfolding_dilepton_source_types[sourceId]) + HIST("uls/hsRM"), v12mc.M(), v12mc.Pt(), v12rec.M(), v12rec.Pt(), weight); + } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ + fRegistry.fill(HIST("Unfold/") + HIST(unfolding_dilepton_source_types[sourceId]) + HIST("lspp/hsRM"), v12mc.M(), v12mc.Pt(), v12rec.M(), v12rec.Pt(), weight); + } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- + fRegistry.fill(HIST("Unfold/") + HIST(unfolding_dilepton_source_types[sourceId]) + HIST("lsmm/hsRM"), v12mc.M(), v12mc.Pt(), v12rec.M(), v12rec.Pt(), weight); + } + } else if (!isPairInAcc(t1, t2) && isPairInAcc(t1mc, t2mc)) { + if (t1.sign() * t2.sign() < 0) { // ULS + fRegistry.fill(HIST("Unfold/") + HIST(unfolding_dilepton_source_types[sourceId]) + HIST("uls/hMiss"), v12mc.M(), v12mc.Pt(), weight); + } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ + fRegistry.fill(HIST("Unfold/") + HIST(unfolding_dilepton_source_types[sourceId]) + HIST("lspp/hMiss"), v12mc.M(), v12mc.Pt(), weight); + } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- + fRegistry.fill(HIST("Unfold/") + HIST(unfolding_dilepton_source_types[sourceId]) + HIST("lsmm/hMiss"), v12mc.M(), v12mc.Pt(), weight); + } + } else if (isPairInAcc(t1, t2) && !isPairInAcc(t1mc, t2mc)) { + if (t1.sign() * t2.sign() < 0) { // ULS + fRegistry.fill(HIST("Unfold/") + HIST(unfolding_dilepton_source_types[sourceId]) + HIST("uls/hFake"), v12rec.M(), v12rec.Pt(), weight); + } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ + fRegistry.fill(HIST("Unfold/") + HIST(unfolding_dilepton_source_types[sourceId]) + HIST("lspp/hFake"), v12rec.M(), v12rec.Pt(), weight); + } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- + fRegistry.fill(HIST("Unfold/") + HIST(unfolding_dilepton_source_types[sourceId]) + HIST("lsmm/hFake"), v12rec.M(), v12rec.Pt(), weight); + } + } + } + + template + bool fillPairUnfolding(TTrack const& t1, TTrack const& t2, TTracks const& tracks, TCut const& cut, TMCCollisions const&, TMCParticles const& mcparticles) + { + auto t1mc = mcparticles.iteratorAt(t1.emmcparticleId()); + auto mccollision_from_t1 = t1mc.template emmcevent_as(); + if (cfgEventGeneratorType >= 0 && mccollision_from_t1.getSubGeneratorId() != cfgEventGeneratorType) { + return false; + } + + auto t2mc = mcparticles.iteratorAt(t2.emmcparticleId()); + auto mccollision_from_t2 = t2mc.template emmcevent_as(); + if (cfgEventGeneratorType >= 0 && mccollision_from_t2.getSubGeneratorId() != cfgEventGeneratorType) { + return false; + } + + if ((std::abs(t1mc.pdgCode()) != pdg_lepton || std::abs(t2mc.pdgCode()) != pdg_lepton) || (t1mc.emmceventId() != t2mc.emmceventId())) { + return false; + } + if (t1mc.pdgCode() * t2mc.pdgCode() > 0) { // ULS + return false; + } + if (!((t1mc.isPhysicalPrimary() || t1mc.producedByGenerator()) && (t2mc.isPhysicalPrimary() || t2mc.producedByGenerator()))) { + return false; + } + int mother_id = std::max({FindSMULS(t1mc, t2mc, mcparticles), FindSMULS(t2mc, t1mc, mcparticles), FindSMLSPP(t1mc, t2mc, mcparticles), FindSMLSMM(t1mc, t2mc, mcparticles)}); + int hfee_type = o2::aod::pwgem::dilepton::utils::mcutil::IsHF(t1mc, t2mc, mcparticles); + if (mother_id < 0 && hfee_type < 0) { + return false; + } + + if (!isPairOK(t1, t2, cut, tracks)) { // without acceptance + return false; + } + + // ROOT::Math::PtEtaPhiMVector v1rec(t1.pt(), t1.eta(), t1.phi(), leptonM1); + // ROOT::Math::PtEtaPhiMVector v2rec(t2.pt(), t2.eta(), t2.phi(), leptonM2); + // ROOT::Math::PtEtaPhiMVector v12rec = v1rec + v2rec; + + // ROOT::Math::PtEtaPhiMVector v1mc(t1mc.pt(), t1mc.eta(), t1mc.phi(), leptonM1); + // ROOT::Math::PtEtaPhiMVector v2mc(t2mc.pt(), t2mc.eta(), t2mc.phi(), leptonM2); + // ROOT::Math::PtEtaPhiMVector v12mc = v1mc + v2mc; + + if (mother_id > -1) { + auto mcmother = mcparticles.iteratorAt(mother_id); + if (!(mcmother.isPhysicalPrimary() || mcmother.producedByGenerator())) { + return false; + } + switch (std::abs(mcmother.pdgCode())) { + case 111: + case 221: + case 331: + case 113: + case 223: + case 333: + case 443: + case 100443: + fillHistogramsUnfolding<0>(t1, t2, mcparticles); + break; + default: + break; + } + } else if (hfee_type > -1) { + switch (hfee_type) { + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kCe_Ce): + fillHistogramsUnfolding<1>(t1, t2, mcparticles); + break; + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kBe_Be): + fillHistogramsUnfolding<2>(t1, t2, mcparticles); + break; + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kBCe_BCe): + fillHistogramsUnfolding<2>(t1, t2, mcparticles); + break; + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kBCe_Be_SameB): + fillHistogramsUnfolding<2>(t1, t2, mcparticles); + break; + case static_cast(o2::aod::pwgem::dilepton::utils::mcutil::EM_HFeeType::kBCe_Be_DiffB): + fillHistogramsUnfolding<2>(t1, t2, mcparticles); + break; + default: + break; + } + } + return true; + } + + template + void fillUnfolding(TCollisions const& collisions, TTracks1 const& posTracks, TTracks2 const& negTracks, TPresilce const& perCollision, TCut const& cut, TAllTracks const& tracks, TMCCollisions const& mcCollisions, TMCParticles const& mcparticles) + { + for (const auto& collision : collisions) { + initCCDB(collision); + float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; + if (centralities[cfgCentEstimator] < eventcuts.cfgCentMin || eventcuts.cfgCentMax < centralities[cfgCentEstimator]) { + continue; + } + + if (!fEMEventCut.IsSelected(collision)) { + continue; + } + if (eventcuts.cfgRequireGoodRCT && !rctChecker.checkTable(collision)) { + continue; + } + + auto posTracks_per_coll = posTracks.sliceByCached(perCollision, collision.globalIndex(), cache); // reconstructed pos tracks + auto negTracks_per_coll = negTracks.sliceByCached(perCollision, collision.globalIndex(), cache); // reconstructed neg tracks + + for (const auto& [pos, neg] : combinations(o2::soa::CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS + fillPairUnfolding(pos, neg, tracks, cut, mcCollisions, mcparticles); + } // end of ULS pairing + for (const auto& [pos1, pos2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ + fillPairUnfolding(pos1, pos2, tracks, cut, mcCollisions, mcparticles); + } // end of LS++ pairing + for (const auto& [neg1, neg2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- + fillPairUnfolding(neg1, neg2, tracks, cut, mcCollisions, mcparticles); + } // end of LS-- pairing + } // end of collision loop + } + + std::unordered_map map_best_match_globalmuon; + + o2::framework::SliceCache cache; + o2::framework::Preslice perCollision_electron = o2::aod::emprimaryelectron::emeventId; + o2::framework::expressions::Filter trackFilter_electron = nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz && o2::aod::track::itsChi2NCl < dielectroncuts.cfg_max_chi2its && o2::aod::track::tpcChi2NCl < dielectroncuts.cfg_max_chi2tpc; + o2::framework::expressions::Filter pidFilter_electron = dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl; + o2::framework::expressions::Filter ttcaFilter_electron = ifnode(dielectroncuts.enableTTCA.node(), true, o2::aod::emprimaryelectron::isAssociatedToMPC == true); + o2::framework::expressions::Filter prefilter_derived_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter_derived.node() && dielectroncuts.cfg_prefilter_bits_derived.node() >= static_cast(1), + ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) <= static_cast(0), true) && + ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) <= static_cast(0), true) && + ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) <= static_cast(0), true) && + ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) <= static_cast(0), true), + o2::aod::emprimaryelectron::pfbderived >= static_cast(0)); + + o2::framework::expressions::Filter prefilter_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter.node() && dielectroncuts.cfg_prefilter_bits.node() >= static_cast(1), + ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPC))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPC))) <= static_cast(0), true) && + ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_20MeV))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_20MeV))) <= static_cast(0), true) && + ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_40MeV))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_40MeV))) <= static_cast(0), true) && + ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_60MeV))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_60MeV))) <= static_cast(0), true) && + ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_80MeV))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_80MeV))) <= static_cast(0), true) && + ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_100MeV))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_100MeV))) <= static_cast(0), true) && + ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_120MeV))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_120MeV))) <= static_cast(0), true) && + ifnode((dielectroncuts.cfg_prefilter_bits.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_140MeV))) > static_cast(0), (o2::aod::emprimaryelectron::pfb & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_140MeV))) <= static_cast(0), true), + o2::aod::emprimaryelectron::pfb >= static_cast(0)); + + o2::framework::Preslice perCollision_muon = o2::aod::emprimarymuon::emeventId; + o2::framework::expressions::Filter trackFilter_muon = o2::aod::fwdtrack::trackType == dimuoncuts.cfg_track_type; + o2::framework::expressions::Filter ttcaFilter_muon = ifnode(dimuoncuts.enableTTCA.node(), true, o2::aod::emprimarymuon::isAssociatedToMPC == true); + o2::framework::expressions::Filter prefilter_derived_muon = ifnode(dimuoncuts.cfg_apply_cuts_from_prefilter_derived.node() && dimuoncuts.cfg_prefilter_bits_derived.node() >= static_cast(1), + ifnode((dimuoncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) > static_cast(0), (o2::aod::emprimarymuon::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) <= static_cast(0), true) && + ifnode((dimuoncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) > static_cast(0), (o2::aod::emprimarymuon::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) <= static_cast(0), true), + o2::aod::emprimarymuon::pfbderived >= static_cast(0)); + + o2::framework::expressions::Filter collisionFilter_centrality = (eventcuts.cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < eventcuts.cfgCentMax) || (eventcuts.cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < eventcuts.cfgCentMax) || (eventcuts.cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < eventcuts.cfgCentMax); + o2::framework::expressions::Filter collisionFilter_numContrib = eventcuts.cfgNumContribMin <= o2::aod::collision::numContrib && o2::aod::collision::numContrib < eventcuts.cfgNumContribMax; + o2::framework::expressions::Filter collisionFilter_occupancy_track = eventcuts.cfgTrackOccupancyMin <= o2::aod::evsel::trackOccupancyInTimeRange && o2::aod::evsel::trackOccupancyInTimeRange < eventcuts.cfgTrackOccupancyMax; + o2::framework::expressions::Filter collisionFilter_occupancy_ft0c = eventcuts.cfgFT0COccupancyMin <= o2::aod::evsel::ft0cOccupancyInTimeRange && o2::aod::evsel::ft0cOccupancyInTimeRange < eventcuts.cfgFT0COccupancyMax; + using FilteredMyCollisions = o2::soa::Filtered; + + o2::framework::Partition positive_electrons = o2::aod::emprimaryelectron::sign > int8_t(0); // reconstructed tracks + o2::framework::Partition negative_electrons = o2::aod::emprimaryelectron::sign < int8_t(0); // reconstructed tracks + o2::framework::Partition positive_muons = o2::aod::emprimarymuon::sign > int8_t(0); // reconstructed tracks + o2::framework::Partition negative_muons = o2::aod::emprimarymuon::sign < int8_t(0); // reconstructed tracks + + o2::framework::Partition positive_electronsMC = o2::aod::mcparticle::pdgCode == -11; // e+ + o2::framework::Partition negative_electronsMC = o2::aod::mcparticle::pdgCode == 11; // e- + o2::framework::Partition positive_muonsMC = o2::aod::mcparticle::pdgCode == -13; // mu+ + o2::framework::Partition negative_muonsMC = o2::aod::mcparticle::pdgCode == 13; // mu- + o2::framework::PresliceUnsorted perMcCollision = o2::aod::emmcparticle::emmceventId; + o2::framework::PresliceUnsorted perMcCollision_vm = o2::aod::emmcgenvectormeson::emmceventId; + // o2::framework::PresliceUnsorted recColperMcCollision = o2::aod::emmceventlabel::emmceventId; + + void processAnalysis(FilteredMyCollisions const& collisions, MyMCCollisions const& mccollisions, o2::aod::EMMCParticles const& mcparticles, TLeptons const& leptons) + { + // LOGF(info, "collisions.size() = %d, mccollisions.size() = %d, mcparticles.size() = %d", collisions.size(), mccollisions.size(), mcparticles.size()); + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (cfgApplyWeightTTCA) { + fillPairWeightMap(collisions, positive_electrons, negative_electrons, o2::aod::emprimaryelectron::emeventId, fDielectronCut, leptons, mccollisions, mcparticles); + } + runTruePairing(collisions, positive_electrons, negative_electrons, o2::aod::emprimaryelectron::emeventId, fDielectronCut, leptons, mccollisions, mcparticles); + runGenInfo(collisions, mccollisions, positive_electronsMC, negative_electronsMC, mcparticles); + if (cfgFillUnfolding) { + fillUnfolding(collisions, positive_electrons, negative_electrons, o2::aod::emprimaryelectron::emeventId, fDielectronCut, leptons, mccollisions, mcparticles); + } + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + map_best_match_globalmuon = o2::aod::pwgem::dilepton::utils::emtrackutil::findBestMatchMap(leptons, fDimuonCut); + if (cfgApplyWeightTTCA) { + fillPairWeightMap(collisions, positive_muons, negative_muons, o2::aod::emprimarymuon::emeventId, fDimuonCut, leptons, mccollisions, mcparticles); + } + runTruePairing(collisions, positive_muons, negative_muons, o2::aod::emprimarymuon::emeventId, fDimuonCut, leptons, mccollisions, mcparticles); + runGenInfo(collisions, mccollisions, positive_muonsMC, negative_muonsMC, mcparticles); + if (cfgFillUnfolding) { + fillUnfolding(collisions, positive_muons, negative_muons, o2::aod::emprimarymuon::emeventId, fDimuonCut, leptons, mccollisions, mcparticles); + } + } + map_weight.clear(); + map_best_match_globalmuon.clear(); + } + PROCESS_SWITCH(DileptonSVMC, processAnalysis, "run dilepton mc analysis", true); + + o2::framework::Partition positive_electronsMC_smeared = o2::aod::mcparticle::pdgCode == -11; // e+ + o2::framework::Partition negative_electronsMC_smeared = o2::aod::mcparticle::pdgCode == 11; // e- + o2::framework::Partition positive_muonsMC_smeared = o2::aod::mcparticle::pdgCode == -13; // mu+ + o2::framework::Partition negative_muonsMC_smeared = o2::aod::mcparticle::pdgCode == 13; // mu- + + void processAnalysis_Smeared(FilteredMyCollisions const& collisions, MyMCCollisions const& mccollisions, TLeptons const& leptons, TSmeardMCParitlces const& mcparticles_smeared) + { + // LOGF(info, "collisions.size() = %d, mccollisions.size() = %d, mcparticles.size() = %d", collisions.size(), mccollisions.size(), mcparticles.size()); + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (cfgApplyWeightTTCA) { + fillPairWeightMap(collisions, positive_electrons, negative_electrons, o2::aod::emprimaryelectron::emeventId, fDielectronCut, leptons, mccollisions, mcparticles_smeared); + } + runTruePairing(collisions, positive_electrons, negative_electrons, o2::aod::emprimaryelectron::emeventId, fDielectronCut, leptons, mccollisions, mcparticles_smeared); + runGenInfo(collisions, mccollisions, positive_electronsMC_smeared, negative_electronsMC_smeared, mcparticles_smeared); + if (cfgFillUnfolding) { + fillUnfolding(collisions, positive_electrons, negative_electrons, o2::aod::emprimaryelectron::emeventId, fDielectronCut, leptons, mccollisions, mcparticles_smeared); + } + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + map_best_match_globalmuon = o2::aod::pwgem::dilepton::utils::emtrackutil::findBestMatchMap(leptons, fDimuonCut); + if (cfgApplyWeightTTCA) { + fillPairWeightMap(collisions, positive_muons, negative_muons, o2::aod::emprimarymuon::emeventId, fDimuonCut, leptons, mccollisions, mcparticles_smeared); + } + runTruePairing(collisions, positive_muons, negative_muons, o2::aod::emprimarymuon::emeventId, fDimuonCut, leptons, mccollisions, mcparticles_smeared); + runGenInfo(collisions, mccollisions, positive_muonsMC_smeared, negative_muonsMC_smeared, mcparticles_smeared); + if (cfgFillUnfolding) { + fillUnfolding(collisions, positive_muons, negative_muons, o2::aod::emprimarymuon::emeventId, fDimuonCut, leptons, mccollisions, mcparticles_smeared); + } + } + map_weight.clear(); + map_best_match_globalmuon.clear(); + } + PROCESS_SWITCH(DileptonSVMC, processAnalysis_Smeared, "run dilepton mc analysis with smearing", false); + + void processGen_VM(FilteredMyCollisions const& collisions, MyMCCollisions const&, o2::aod::EMMCGenVectorMesons const& mcparticles) + { + // for oemga, phi efficiency + for (const auto& collision : collisions) { + float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; + if (centralities[cfgCentEstimator] < eventcuts.cfgCentMin || eventcuts.cfgCentMax < centralities[cfgCentEstimator]) { + continue; + } + + if (!fEMEventCut.IsSelected(collision)) { + continue; + } + if (eventcuts.cfgRequireGoodRCT && !rctChecker.checkTable(collision)) { + continue; + } + auto mccollision = collision.template emmcevent_as(); + if (cfgEventGeneratorType >= 0 && mccollision.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } + auto mctracks_per_coll = mcparticles.sliceBy(perMcCollision_vm, mccollision.globalIndex()); + + for (const auto& mctrack : mctracks_per_coll) { + if (!(mctrack.isPhysicalPrimary() || mctrack.producedByGenerator())) { + continue; + } + + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (mctrack.y() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < mctrack.y()) { + continue; + } + } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { + if (mctrack.y() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < mctrack.y()) { + continue; + } + } + + switch (std::abs(mctrack.pdgCode())) { + case 223: + fRegistry.fill(HIST("Generated/VM/Omega/hPtY"), mctrack.y(), mctrack.pt(), 1.f / mctrack.dsf()); + break; + case 333: + fRegistry.fill(HIST("Generated/VM/Phi/hPtY"), mctrack.y(), mctrack.pt(), 1.f / mctrack.dsf()); + break; + default: + break; + } + + } // end of mctracks per mccollision + } // end of collision loop + } + PROCESS_SWITCH(DileptonSVMC, processGen_VM, "process generated info for vector mesons", false); + + void processNorm(o2::aod::EMEventNormInfos const& collisions) + { + for (const auto& collision : collisions) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 1.0); + if (collision.selection_bit(o2::aod::emevsel::kIsTriggerTVX)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 2.0); + } + if (collision.selection_bit(o2::aod::emevsel::kNoTimeFrameBorder)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 3.0); + } + if (collision.selection_bit(o2::aod::emevsel::kNoITSROFrameBorder)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 4.0); + } + if (collision.selection_bit(o2::aod::emevsel::kNoSameBunchPileup)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 5.0); + } + if (collision.selection_bit(o2::aod::emevsel::kIsGoodZvtxFT0vsPV)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 6.0); + } + if (collision.selection_bit(o2::aod::emevsel::kIsVertexITSTPC)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 7.0); + } + if (collision.selection_bit(o2::aod::emevsel::kIsVertexTRDmatched)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 8.0); + } + if (collision.selection_bit(o2::aod::emevsel::kIsVertexTOFmatched)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 9.0); + } + if (collision.sel8()) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 10.0); + } + if (std::fabs(collision.posZ()) < 10.0) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 11.0); + } + if (collision.selection_bit(o2::aod::emevsel::kNoCollInTimeRangeStandard)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 12.0); + } + if (collision.selection_bit(o2::aod::emevsel::kNoCollInTimeRangeStrict)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 13.0); + } + if (collision.selection_bit(o2::aod::emevsel::kNoCollInRofStandard)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 14.0); + } + if (collision.selection_bit(o2::aod::emevsel::kNoCollInRofStrict)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 15.0); + } + if (collision.selection_bit(o2::aod::emevsel::kNoHighMultCollInPrevRof)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 16.0); + } + if (collision.selection_bit(o2::aod::emevsel::kIsGoodITSLayer3)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 17.0); + } + if (collision.selection_bit(o2::aod::emevsel::kIsGoodITSLayer0123)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 18.0); + } + if (collision.selection_bit(o2::aod::emevsel::kIsGoodITSLayersAll)) { + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 19.0); + } + if (!fEMEventCut.IsSelected(collision)) { + continue; + } + if (eventcuts.cfgRequireGoodRCT && !rctChecker.checkTable(collision)) { + continue; + } + fRegistry.fill(HIST("Event/norm/hCollisionCounter"), o2::aod::pwgem::dilepton::utils::eventhistogram::nbin_ev); // accepted + } // end of collision loop + } + PROCESS_SWITCH(DileptonSVMC, processNorm, "process normalization info", false); + + void processBC(o2::aod::EMBCs const& bcs) + { + for (const auto& bc : bcs) { + if (bc.selection_bit(o2::aod::emevsel::kIsTriggerTVX)) { + fRegistry.fill(HIST("BC/hTVXCounter"), 0.f); + + if (bc.selection_bit(o2::aod::emevsel::kNoTimeFrameBorder)) { + fRegistry.fill(HIST("BC/hTVXCounter"), 1.f); + } + if (bc.selection_bit(o2::aod::emevsel::kNoITSROFrameBorder)) { + fRegistry.fill(HIST("BC/hTVXCounter"), 2.f); + } + if (rctChecker(bc)) { + fRegistry.fill(HIST("BC/hTVXCounter"), 3.f); + } + if (bc.selection_bit(o2::aod::emevsel::kNoTimeFrameBorder) && bc.selection_bit(o2::aod::emevsel::kNoITSROFrameBorder)) { + fRegistry.fill(HIST("BC/hTVXCounter"), 4.f); + } + if (bc.selection_bit(o2::aod::emevsel::kNoTimeFrameBorder) && bc.selection_bit(o2::aod::emevsel::kNoITSROFrameBorder) && rctChecker(bc)) { + fRegistry.fill(HIST("BC/hTVXCounter"), 5.f); + } + } + } + } + PROCESS_SWITCH(DileptonSVMC, processBC, "process BC counter", false); + + void processDummy(FilteredMyCollisions const&) {} + PROCESS_SWITCH(DileptonSVMC, processDummy, "Dummy function", false); +}; + +#endif // PWGEM_DILEPTON_CORE_DILEPTONSVMC_H_ diff --git a/PWGEM/Dilepton/Core/DimuonCut.cxx b/PWGEM/Dilepton/Core/DimuonCut.cxx index f3a67d06d4a..36f768b124f 100644 --- a/PWGEM/Dilepton/Core/DimuonCut.cxx +++ b/PWGEM/Dilepton/Core/DimuonCut.cxx @@ -101,6 +101,11 @@ void DimuonCut::SetMaxMatchingChi2MCHMFTPtDep(std::function PtDepC mMaxMatchingChi2MCHMFTPtDep = PtDepCut; LOG(info) << "Dimuon Cut, set matching chi2 MFT-MCH range: " << mMaxMatchingChi2MCHMFTPtDep(0.5); } +void DimuonCut::SetMaxDiffMatchingChi2MCHMFT(float diff) +{ + mMaxDiffMatchingChi2MCHMFT = diff; + LOG(info) << "Dimuon Cut, set max diff. matching chi2 MFT-MCH: " << mMaxDiffMatchingChi2MCHMFT; +} void DimuonCut::SetMatchingChi2MCHMID(float min, float max) { mMinMatchingChi2MCHMID = min; diff --git a/PWGEM/Dilepton/Core/DimuonCut.h b/PWGEM/Dilepton/Core/DimuonCut.h index 9975380f168..7f31744dc93 100644 --- a/PWGEM/Dilepton/Core/DimuonCut.h +++ b/PWGEM/Dilepton/Core/DimuonCut.h @@ -65,6 +65,7 @@ class DimuonCut : public TNamed kPDCA, kMFTHitMap, kDPtDEtaDPhiwrtMCHMID, + kDiffMatchingChi2MCHMFT, kTTCA, kNCuts }; @@ -177,6 +178,9 @@ class DimuonCut : public TNamed if (track.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && !IsSelectedTrack(track, DimuonCuts::kDPtDEtaDPhiwrtMCHMID)) { return false; } + if (track.trackType() == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) && !IsSelectedTrack(track, DimuonCuts::kDiffMatchingChi2MCHMFT)) { + return false; + } return true; } @@ -241,6 +245,9 @@ class DimuonCut : public TNamed case DimuonCuts::kDPtDEtaDPhiwrtMCHMID: return std::fabs(track.ptMatchedMCHMID() - track.pt()) / track.pt() < mMaxReldPtwrtMCHMID && std::sqrt(std::pow((track.etaMatchedMCHMID() - track.eta()) / mMaxdEtawrtMCHMID, 2) + std::pow((track.phiMatchedMCHMID() - track.phi()) / mMaxdPhiwrtMCHMID, 2)) < 1.f; + case DimuonCuts::kDiffMatchingChi2MCHMFT: + return track.diffChi2MatchingMCHMFT() > mMaxDiffMatchingChi2MCHMFT; + default: return false; } @@ -269,6 +276,7 @@ class DimuonCut : public TNamed void SetMFTHitMap(bool flag, std::vector hitMap); void SetMaxdPtdEtadPhiwrtMCHMID(float reldPtMax, float dEtaMax, float dPhiMax); // this is relevant for global muons void SetMaxMatchingChi2MCHMFTPtDep(std::function PtDepCut); + void SetMaxDiffMatchingChi2MCHMFT(float diff); void EnableTTCA(bool flag); private: @@ -301,6 +309,7 @@ class DimuonCut : public TNamed float mMinRabs{17.6}, mMaxRabs{89.5}; float mMinDcaXY{0.0f}, mMaxDcaXY{1e10f}; float mMaxReldPtwrtMCHMID{1e10f}, mMaxdEtawrtMCHMID{1e10f}, mMaxdPhiwrtMCHMID{1e10f}; + float mMaxDiffMatchingChi2MCHMFT{-1.f}; bool mApplyMFTHitMap{false}; std::vector mRequiredMFTDisks{}; diff --git a/PWGEM/Dilepton/Core/EMEventCut.h b/PWGEM/Dilepton/Core/EMEventCut.h index b0450f5b575..d9671356e24 100644 --- a/PWGEM/Dilepton/Core/EMEventCut.h +++ b/PWGEM/Dilepton/Core/EMEventCut.h @@ -16,7 +16,7 @@ #ifndef PWGEM_DILEPTON_CORE_EMEVENTCUT_H_ #define PWGEM_DILEPTON_CORE_EMEVENTCUT_H_ -#include "PWGEM/Dilepton/DataModel/dileptonTables.h" +#include "PWGEM/Dilepton/DataModel/EvSelFlags.h" #include diff --git a/PWGEM/Dilepton/Core/SingleTrackQC.h b/PWGEM/Dilepton/Core/SingleTrackQC.h index 0af7cc07bf1..414b43d3c02 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQC.h @@ -20,6 +20,7 @@ #include "PWGEM/Dilepton/Core/DielectronCut.h" #include "PWGEM/Dilepton/Core/DimuonCut.h" #include "PWGEM/Dilepton/Core/EMEventCut.h" +#include "PWGEM/Dilepton/DataModel/EvSelFlags.h" #include "PWGEM/Dilepton/DataModel/dileptonTables.h" #include "PWGEM/Dilepton/Utils/EMTrackUtilities.h" #include "PWGEM/Dilepton/Utils/EventHistograms.h" @@ -54,6 +55,8 @@ #include #include +#include + #include #include #include @@ -191,15 +194,15 @@ struct SingleTrackQC { o2::framework::Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; // configuration for PID ML - o2::framework::Configurable> onnxFileNames{"onnxFileNames", std::vector{"filename"}, "ONNX file names for each bin (if not from CCDB full path)"}; - o2::framework::Configurable> onnxPathsCCDB{"onnxPathsCCDB", std::vector{"path"}, "Paths of models on CCDB"}; - o2::framework::Configurable> binsMl{"binsMl", std::vector{0.1, 0.15, 0.2, 0.25, 0.4, 0.8, 1.6, 2.0, 20.f}, "Bin limits for ML application"}; - o2::framework::Configurable> cutsMl{"cutsMl", std::vector{0.98, 0.98, 0.9, 0.9, 0.95, 0.95, 0.8, 0.8}, "ML cuts per bin"}; - o2::framework::Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature"}, "Names of ML model input features"}; - o2::framework::Configurable nameBinningFeature{"nameBinningFeature", "pt", "Names of ML model binning feature"}; - o2::framework::Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; - o2::framework::Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; - o2::framework::Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; + // o2::framework::Configurable> onnxFileNames{"onnxFileNames", std::vector{"filename"}, "ONNX file names for each bin (if not from CCDB full path)"}; + // o2::framework::Configurable> onnxPathsCCDB{"onnxPathsCCDB", std::vector{"path"}, "Paths of models on CCDB"}; + o2::framework::Configurable> binsMLPID{"binsMLPID", std::vector{0.1, 0.15, 0.2, 0.25, 0.4, 0.8, 1.6, 2.0, 4.0, 20.f}, "Bin limits for ML application"}; + o2::framework::Configurable> cutsMLPID{"cutsMLPID", std::vector{0.97, 0.97, 0.97, 0.8, 0.95, 0.95, 0.8, 0.8, 0.8}, "ML cuts per bin"}; + // o2::framework::Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature"}, "Names of ML model input features"}; + // o2::framework::Configurable nameBinningFeature{"nameBinningFeature", "pt", "Names of ML model binning feature"}; + // o2::framework::Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; + // o2::framework::Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; + // o2::framework::Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; } dielectroncuts; DimuonCut fDimuonCut; @@ -229,6 +232,7 @@ struct SingleTrackQC { o2::framework::Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1e+10, "max dca XY for single track in cm"}; o2::framework::Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; o2::framework::Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; + o2::framework::Configurable cfg_max_diff_chi2_mftmch{"cfg_max_diff_chi2_mftmch", -1.f, "max. diff chi2MatchingMCHMFT between the best and the 2nd best matched candidates"}; o2::framework::Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; o2::framework::Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; o2::framework::Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; @@ -276,7 +280,6 @@ struct SingleTrackQC { // track info fRegistry.add("Track/positive/hs", "rec. single electron", o2::framework::HistType::kTHnSparseD, {axis_pt, axis_eta, axis_phi, axis_dca3D, axis_dcaXY, axis_dcaZ}, true); - fRegistry.add("Track/positive/hPhiPosition", Form("phi position at r_{xy} = %3.2f m", dielectroncuts.cfgRefR.value), o2::framework::HistType::kTH1F, {axis_phiposition}, false); fRegistry.add("Track/positive/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", o2::framework::HistType::kTH1F, {{4000, -20, 20}}, false); fRegistry.add("Track/positive/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", o2::framework::HistType::kTH2F, {{200, -1.0f, 1.0f}, {200, -1.f, 1.f}}, false); fRegistry.add("Track/positive/hDCAxyzSigma", "DCA xy vs. z;DCA_{xy} (#sigma);DCA_{z} (#sigma)", o2::framework::HistType::kTH2F, {{400, -20.0f, 20.0f}, {400, -20.0f, 20.0f}}, false); @@ -291,7 +294,7 @@ struct SingleTrackQC { fRegistry.add("Track/positive/hTPCNcls2Nf", "TPC Ncls/Nfindable;TPC N_{cls}/N_{cls}^{findable}", o2::framework::HistType::kTH1F, {{200, 0, 2}}, false); fRegistry.add("Track/positive/hTPCNclsShared", "TPC Ncls shared/Ncls;p_{T} (GeV/c);N_{cls}^{shared}/N_{cls} in TPC", o2::framework::HistType::kTH2F, {{1000, 0, 10}, {100, 0, 1}}, false); fRegistry.add("Track/positive/hNclsITS", "number of ITS clusters;ITS N_{cls}", o2::framework::HistType::kTH1F, {{8, -0.5, 7.5}}, false); - fRegistry.add("Track/positive/hChi2ITS", "chi2/number of ITS clusters;ITS #chi^{2}/N_{cls}", o2::framework::HistType::kTH1F, {{100, 0, 10}}, false); + fRegistry.add("Track/positive/hChi2ITS", "chi2/number of ITS clusters;ITS #chi^{2}/N_{cls}", o2::framework::HistType::kTH1F, {{400, 0, 40}}, false); fRegistry.add("Track/positive/hITSClusterMap", "ITS cluster map", o2::framework::HistType::kTH1F, {{128, -0.5, 127.5}}, false); fRegistry.add("Track/positive/hChi2TOF", "TOF Chi2;p_{pv} (GeV/c);TOF #chi^{2}", o2::framework::HistType::kTH2F, {{1000, 0, 10}, {100, 0, 10}}, false); @@ -309,7 +312,7 @@ struct SingleTrackQC { // fRegistry.add("Track/positive/hTOFNsigmaKa", "TOF n sigma ka;p_{pv} (GeV/c);n #sigma_{K}^{TOF}", o2::framework::HistType::kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); // fRegistry.add("Track/positive/hTOFNsigmaPr", "TOF n sigma pr;p_{pv} (GeV/c);n #sigma_{p}^{TOF}", o2::framework::HistType::kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/positive/hPIDForTracking", "PID for trackng", o2::framework::HistType::kTH1F, {{9, -0.5, 8.5}}, false); // see numbering in O2/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h + fRegistry.add("Track/positive/hPIDForTracking", "PID for tracking", o2::framework::HistType::kTH1F, {{9, -0.5, 8.5}}, false); // see numbering in O2/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h fRegistry.add("Track/positive/hProbElBDT", "probability to be e from BDT;p_{in} (GeV/c);BDT score;", o2::framework::HistType::kTH2F, {{1000, 0, 10}, {100, 0, 1}}, false); fRegistry.add("Track/positive/hMeanClusterSizeITS", "mean cluster size ITS;p_{pv} (GeV/c); on ITS #times cos(#lambda);", o2::framework::HistType::kTH2F, {{1000, 0.f, 10.f}, {150, 0, 15}}, false); fRegistry.add("Track/positive/hMeanClusterSizeITSib", "mean cluster size ITS inner barrel;p_{pv} (GeV/c); on ITS #times cos(#lambda);", o2::framework::HistType::kTH2F, {{1000, 0.f, 10.f}, {150, 0, 15}}, false); @@ -509,14 +512,14 @@ struct SingleTrackQC { if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDileptonCut std::vector binsML{}; - binsML.reserve(dielectroncuts.binsMl.value.size()); - for (size_t i = 0; i < dielectroncuts.binsMl.value.size(); i++) { - binsML.emplace_back(dielectroncuts.binsMl.value[i]); + binsML.reserve(dielectroncuts.binsMLPID.value.size()); + for (size_t i = 0; i < dielectroncuts.binsMLPID.value.size(); i++) { + binsML.emplace_back(dielectroncuts.binsMLPID.value[i]); } std::vector thresholdsML{}; - thresholdsML.reserve(dielectroncuts.cutsMl.value.size()); - for (size_t i = 0; i < dielectroncuts.cutsMl.value.size(); i++) { - thresholdsML.emplace_back(dielectroncuts.cutsMl.value[i]); + thresholdsML.reserve(dielectroncuts.cutsMLPID.value.size()); + for (size_t i = 0; i < dielectroncuts.cutsMLPID.value.size(); i++) { + thresholdsML.emplace_back(dielectroncuts.cutsMLPID.value[i]); } fDielectronCut.SetMLThresholds(binsML, thresholdsML); } // end of PID ML @@ -536,6 +539,7 @@ struct SingleTrackQC { fDimuonCut.SetChi2(0.f, dimuoncuts.cfg_max_chi2); fDimuonCut.SetChi2MFT(0.f, dimuoncuts.cfg_max_chi2mft); // fDimuonCut.SetMatchingChi2MCHMFT(0.f, dimuoncuts.cfg_max_matching_chi2_mftmch); + fDimuonCut.SetMaxDiffMatchingChi2MCHMFT(dimuoncuts.cfg_max_diff_chi2_mftmch); fDimuonCut.SetMaxMatchingChi2MCHMFTPtDep([&](float pt) { return (pt < dimuoncuts.cfg_border_pt_for_chi2mchmft ? dimuoncuts.cfg_max_matching_chi2_mftmch_lowPt : dimuoncuts.cfg_max_matching_chi2_mftmch_highPt); }); fDimuonCut.SetMatchingChi2MCHMID(0.f, dimuoncuts.cfg_max_matching_chi2_mchmid); fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); @@ -557,12 +561,9 @@ struct SingleTrackQC { float dca3D = o2::aod::pwgem::dilepton::utils::emtrackutil::dca3DinSigma(track); float dcaXY = o2::aod::pwgem::dilepton::utils::emtrackutil::dcaXYinSigma(track); float dcaZ = o2::aod::pwgem::dilepton::utils::emtrackutil::dcaZinSigma(track); - float phiPosition = track.phi() + std::asin(-0.30282 * track.sign() * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * track.pt())); - o2::math_utils::bringTo02Pi(phiPosition); if (track.sign() > 0) { fRegistry.fill(HIST("Track/positive/hs"), track.pt(), track.eta(), track.phi(), dca3D, dcaXY, dcaZ, weight); - fRegistry.fill(HIST("Track/positive/hPhiPosition"), phiPosition); fRegistry.fill(HIST("Track/positive/hQoverPt"), track.sign() / track.pt()); fRegistry.fill(HIST("Track/positive/hDCAxyz"), track.dcaXY(), track.dcaZ()); fRegistry.fill(HIST("Track/positive/hDCAxyzSigma"), dcaXY, dcaZ); @@ -602,7 +603,6 @@ struct SingleTrackQC { // fRegistry.fill(HIST("Track/positive/hTOFNsigmaPr"), track.p(), track.tofNSigmaPr()); } else { fRegistry.fill(HIST("Track/negative/hs"), track.pt(), track.eta(), track.phi(), dca3D, dcaXY, dcaZ, weight); - fRegistry.fill(HIST("Track/negative/hPhiPosition"), phiPosition); fRegistry.fill(HIST("Track/negative/hQoverPt"), track.sign() / track.pt()); fRegistry.fill(HIST("Track/negative/hDCAxyz"), track.dcaXY(), track.dcaZ()); fRegistry.fill(HIST("Track/negative/hDCAxyzSigma"), dcaXY, dcaZ); @@ -884,9 +884,6 @@ struct SingleTrackQC { o2::framework::expressions::Filter prefilter_derived_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter_derived.node() && dielectroncuts.cfg_prefilter_bits_derived.node() >= static_cast(1), ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULSAtRefR))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULSAtRefR))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) <= static_cast(0), true), o2::aod::emprimaryelectron::pfbderived >= static_cast(0)); diff --git a/PWGEM/Dilepton/Core/SingleTrackQCMC.h b/PWGEM/Dilepton/Core/SingleTrackQCMC.h index d22a4422260..c439bfc0492 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQCMC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQCMC.h @@ -20,6 +20,7 @@ #include "PWGEM/Dilepton/Core/DielectronCut.h" #include "PWGEM/Dilepton/Core/DimuonCut.h" #include "PWGEM/Dilepton/Core/EMEventCut.h" +#include "PWGEM/Dilepton/DataModel/EvSelFlags.h" #include "PWGEM/Dilepton/DataModel/dileptonTables.h" #include "PWGEM/Dilepton/Utils/EMTrackUtilities.h" #include "PWGEM/Dilepton/Utils/EventHistograms.h" @@ -52,7 +53,8 @@ #include #include -#include + +#include #include #include @@ -199,17 +201,19 @@ struct SingleTrackQCMC { o2::framework::Configurable cfg_max_pin_pirejTPC{"cfg_max_pin_pirejTPC", 1e+10, "max. pin for pion rejection in TPC"}; o2::framework::Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; o2::framework::Configurable includeITSsa{"includeITSsa", false, "Flag to include ITSsa tracks only for MC. switch ON only if needed."}; + o2::framework::Configurable acceptOnlyCorrectMatch{"acceptOnlyCorrectMatch", false, "flag to accept only correct match between ITS and TPC"}; // this is only for MC study, as we don't know correct match in data. + o2::framework::Configurable acceptOnlyWrongMatch{"acceptOnlyWrongMatch", false, "flag to accept only wrong match between ITS and TPC"}; // this is only for MC study, as we don't know correct match in data. // configuration for PID ML - o2::framework::Configurable> onnxFileNames{"onnxFileNames", std::vector{"filename"}, "ONNX file names for each bin (if not from CCDB full path)"}; - o2::framework::Configurable> onnxPathsCCDB{"onnxPathsCCDB", std::vector{"path"}, "Paths of models on CCDB"}; - o2::framework::Configurable> binsMl{"binsMl", std::vector{0.1, 0.15, 0.2, 0.25, 0.4, 0.8, 1.6, 2.0, 20.f}, "Bin limits for ML application"}; - o2::framework::Configurable> cutsMl{"cutsMl", std::vector{0.98, 0.98, 0.9, 0.9, 0.95, 0.95, 0.8, 0.8}, "ML cuts per bin"}; - o2::framework::Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature"}, "Names of ML model input features"}; - o2::framework::Configurable nameBinningFeature{"nameBinningFeature", "pt", "Names of ML model binning feature"}; - o2::framework::Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; - o2::framework::Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; - o2::framework::Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; + // o2::framework::Configurable> onnxFileNames{"onnxFileNames", std::vector{"filename"}, "ONNX file names for each bin (if not from CCDB full path)"}; + // o2::framework::Configurable> onnxPathsCCDB{"onnxPathsCCDB", std::vector{"path"}, "Paths of models on CCDB"}; + o2::framework::Configurable> binsMLPID{"binsMLPID", std::vector{0.1, 0.15, 0.2, 0.25, 0.4, 0.8, 1.6, 2.0, 4.0, 20.f}, "Bin limits for ML application"}; + o2::framework::Configurable> cutsMLPID{"cutsMLPID", std::vector{0.97, 0.97, 0.97, 0.8, 0.95, 0.95, 0.8, 0.8, 0.8}, "ML cuts per bin"}; + // o2::framework::Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature"}, "Names of ML model input features"}; + // o2::framework::Configurable nameBinningFeature{"nameBinningFeature", "pt", "Names of ML model binning feature"}; + // o2::framework::Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; + // o2::framework::Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; + // o2::framework::Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; } dielectroncuts; DimuonCut fDimuonCut; @@ -238,6 +242,7 @@ struct SingleTrackQCMC { o2::framework::Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1e+10, "max dca XY for single track in cm"}; o2::framework::Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; o2::framework::Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; + o2::framework::Configurable cfg_max_diff_chi2_mftmch{"cfg_max_diff_chi2_mftmch", -1.f, "max. diff chi2MatchingMCHMFT between the best and the 2nd best matched candidates"}; o2::framework::Configurable enableTTCA{"enableTTCA", true, "Flag to enable or disable TTCA"}; o2::framework::Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; o2::framework::Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; @@ -299,7 +304,6 @@ struct SingleTrackQCMC { fRegistry.add("Track/PromptLF/positive/hsGenRec", "rec. single electron", o2::framework::HistType::kTHnSparseD, {axis_pt, axis_eta, axis_phi, axis_dca3D, axis_dcaXY, axis_dcaZ, axis_charge_gen}, true); } if (cfgFillQA) { - fRegistry.add("Track/PromptLF/positive/hPhiPosition", Form("phi position at r_{xy} = %3.2f m", dielectroncuts.cfgRefR.value), o2::framework::HistType::kTH1F, {axis_phiposition}, false); fRegistry.add("Track/PromptLF/positive/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", o2::framework::HistType::kTH1F, {{4000, -20, 20}}, false); fRegistry.add("Track/PromptLF/positive/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", o2::framework::HistType::kTH2F, {{200, -1.0f, 1.0f}, {200, -1.f, 1.f}}, false); fRegistry.add("Track/PromptLF/positive/hDCAxyzSigma", "DCA xy vs. z;DCA_{xy} (#sigma);DCA_{z} (#sigma)", o2::framework::HistType::kTH2F, {{400, -20.0f, 20.0f}, {400, -20.0f, 20.0f}}, false); @@ -313,11 +317,11 @@ struct SingleTrackQCMC { fRegistry.add("Track/PromptLF/positive/hTPCNcls2Nf", "TPC Ncls/Nfindable;TPC N_{cls}/N_{cls}^{findable}", o2::framework::HistType::kTH1F, {{200, 0, 2}}, false); fRegistry.add("Track/PromptLF/positive/hTPCNclsShared", "TPC Ncls shared/Ncls;p_{T} (GeV/c);N_{cls}^{shared}/N_{cls} in TPC", o2::framework::HistType::kTH2F, {{1000, 0, 10}, {100, 0, 1}}, false); fRegistry.add("Track/PromptLF/positive/hNclsITS", "number of ITS clusters;ITS N_{cls}", o2::framework::HistType::kTH1F, {{8, -0.5, 7.5}}, false); - fRegistry.add("Track/PromptLF/positive/hChi2ITS", "chi2/number of ITS clusters;ITS #chi^{2}/N_{cls}", o2::framework::HistType::kTH1F, {{100, 0, 10}}, false); + fRegistry.add("Track/PromptLF/positive/hChi2ITS", "chi2/number of ITS clusters;ITS #chi^{2}/N_{cls}", o2::framework::HistType::kTH1F, {{400, 0, 40}}, false); fRegistry.add("Track/PromptLF/positive/hDeltaPin", "p_{in} vs. p_{pv};p_{in} (GeV/c);(p_{pv} - p_{in})/p_{in}", o2::framework::HistType::kTH2F, {{1000, 0, 10}, {200, -1, +1}}, false); fRegistry.add("Track/PromptLF/positive/hChi2TOF", "TOF Chi2;p_{pv} (GeV/c);TOF #chi^{2}", o2::framework::HistType::kTH2F, {{1000, 0, 10}, {100, 0, 10}}, false); fRegistry.add("Track/PromptLF/positive/hITSClusterMap", "ITS cluster map", o2::framework::HistType::kTH1F, {{128, -0.5, 127.5}}, false); - fRegistry.add("Track/PromptLF/positive/hPIDForTracking", "PID for trackng", o2::framework::HistType::kTH1F, {{9, -0.5, 8.5}}, false); // see numbering in O2/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h + fRegistry.add("Track/PromptLF/positive/hPIDForTracking", "PID for tracking", o2::framework::HistType::kTH1F, {{9, -0.5, 8.5}}, false); // see numbering in O2/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h fRegistry.add("Track/PromptLF/positive/hPtGen_DeltaPtOverPtGen", "electron p_{T} resolution;p_{T}^{gen} (GeV/c);(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", o2::framework::HistType::kTH2F, {{200, 0, 10}, {200, -1.0f, 1.0f}}, true); fRegistry.add("Track/PromptLF/positive/hPtGen_DeltaEta", "electron #eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}", o2::framework::HistType::kTH2F, {{200, 0, 10}, {100, -0.05f, 0.05f}}, true); fRegistry.add("Track/PromptLF/positive/hPtGen_DeltaPhi", "electron #varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)", o2::framework::HistType::kTH2F, {{200, 0, 10}, {100, -0.05f, 0.05f}}, true); @@ -557,14 +561,14 @@ struct SingleTrackQCMC { if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { // please call this at the end of DefineDileptonCut std::vector binsML{}; - binsML.reserve(dielectroncuts.binsMl.value.size()); - for (size_t i = 0; i < dielectroncuts.binsMl.value.size(); i++) { - binsML.emplace_back(dielectroncuts.binsMl.value[i]); + binsML.reserve(dielectroncuts.binsMLPID.value.size()); + for (size_t i = 0; i < dielectroncuts.binsMLPID.value.size(); i++) { + binsML.emplace_back(dielectroncuts.binsMLPID.value[i]); } std::vector thresholdsML{}; - thresholdsML.reserve(dielectroncuts.cutsMl.value.size()); - for (size_t i = 0; i < dielectroncuts.cutsMl.value.size(); i++) { - thresholdsML.emplace_back(dielectroncuts.cutsMl.value[i]); + thresholdsML.reserve(dielectroncuts.cutsMLPID.value.size()); + for (size_t i = 0; i < dielectroncuts.cutsMLPID.value.size(); i++) { + thresholdsML.emplace_back(dielectroncuts.cutsMLPID.value[i]); } fDielectronCut.SetMLThresholds(binsML, thresholdsML); } // end of PID ML @@ -584,6 +588,7 @@ struct SingleTrackQCMC { fDimuonCut.SetChi2(0.f, dimuoncuts.cfg_max_chi2); fDimuonCut.SetChi2MFT(0.f, dimuoncuts.cfg_max_chi2mft); // fDimuonCut.SetMatchingChi2MCHMFT(0.f, dimuoncuts.cfg_max_matching_chi2_mftmch); + fDimuonCut.SetMaxDiffMatchingChi2MCHMFT(dimuoncuts.cfg_max_diff_chi2_mftmch); fDimuonCut.SetMaxMatchingChi2MCHMFTPtDep([&](float pt) { return (pt < dimuoncuts.cfg_border_pt_for_chi2mchmft ? dimuoncuts.cfg_max_matching_chi2_mftmch_lowPt : dimuoncuts.cfg_max_matching_chi2_mftmch_highPt); }); fDimuonCut.SetMatchingChi2MCHMID(0.f, dimuoncuts.cfg_max_matching_chi2_mchmid); fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); @@ -643,8 +648,6 @@ struct SingleTrackQCMC { float dca3D = o2::aod::pwgem::dilepton::utils::emtrackutil::dca3DinSigma(track); float dcaXY = o2::aod::pwgem::dilepton::utils::emtrackutil::dcaXYinSigma(track); float dcaZ = o2::aod::pwgem::dilepton::utils::emtrackutil::dcaZinSigma(track); - float phiPosition = track.phi() + std::asin(-0.30282 * track.sign() * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * track.pt())); - o2::math_utils::bringTo02Pi(phiPosition); float weight = 1.f; if (cfgApplyWeightTTCA) { @@ -662,7 +665,6 @@ struct SingleTrackQCMC { fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hsGenRec"), mctrack.pt(), mctrack.eta(), mctrack.phi(), dca3D, dcaXY, dcaZ, -mctrack.pdgCode() / pdg_lepton, weight); } if (cfgFillQA) { - fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hPhiPosition"), phiPosition); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hQoverPt"), track.sign() / track.pt()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hDCAxyz"), track.dcaXY(), track.dcaZ()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("positive/hDCAxyzSigma"), dcaXY, dcaZ); @@ -709,7 +711,6 @@ struct SingleTrackQCMC { fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hsGenRec"), mctrack.pt(), mctrack.eta(), mctrack.phi(), dca3D, dcaXY, dcaZ, -mctrack.pdgCode() / pdg_lepton, weight); } if (cfgFillQA) { - fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hPhiPosition"), phiPosition); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hQoverPt"), track.sign() / track.pt()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hDCAxyz"), track.dcaXY(), track.dcaZ()); fRegistry.fill(HIST("Track/") + HIST(lepton_source_types[lepton_source_id]) + HIST("negative/hDCAxyzSigma"), dcaXY, dcaZ); @@ -890,6 +891,12 @@ struct SingleTrackQCMC { continue; } } + if (dielectroncuts.acceptOnlyCorrectMatch && o2::aod::pwgem::dilepton::utils::mcutil::hasFakeMatchITSTPC(track)) { + continue; + } + if (dielectroncuts.acceptOnlyWrongMatch && !o2::aod::pwgem::dilepton::utils::mcutil::hasFakeMatchITSTPC(track)) { + continue; + } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { if (!cut.template IsSelectedTrack(track)) { continue; @@ -1157,9 +1164,6 @@ struct SingleTrackQCMC { o2::framework::expressions::Filter prefilter_derived_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter_derived.node() && dielectroncuts.cfg_prefilter_bits_derived.node() >= static_cast(1), ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULSAtRefR))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULSAtRefR))) <= static_cast(0), true) && - ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS))) <= static_cast(0), true) && ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS))) <= static_cast(0), true), o2::aod::emprimaryelectron::pfbderived >= static_cast(0)); diff --git a/PWGEM/Dilepton/DataModel/EvSelFlags.h b/PWGEM/Dilepton/DataModel/EvSelFlags.h new file mode 100644 index 00000000000..0b05ff288eb --- /dev/null +++ b/PWGEM/Dilepton/DataModel/EvSelFlags.h @@ -0,0 +1,40 @@ +// Copyright 2019-2026 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef PWGEM_DILEPTON_CORE_EVSELFLAGS_H +#define PWGEM_DILEPTON_CORE_EVSELFLAGS_H + +namespace o2::aod::emevsel +{ +// Event selection criteria. See O2Physics/Common/CCDB/EventSelectionParams.h +enum EventSelectionFlags { + kIsTriggerTVX = 0, // FT0 vertex (acceptable FT0C-FT0A time difference) at trigger level + kNoITSROFrameBorder, // bunch crossing is far from ITS RO Frame border + kNoTimeFrameBorder, // bunch crossing is far from Time Frame borders + kNoSameBunchPileup, // reject collisions in case of pileup with another collision in the same foundBC + kIsGoodZvtxFT0vsPV, // small difference between z-vertex from PV and from FT0 + kIsVertexITSTPC, // at least one ITS-TPC track (reject vertices built from ITS-only tracks) + kIsVertexTOFmatched, // at least one of vertex contributors is matched to TOF + kIsVertexTRDmatched, // at least one of vertex contributors is matched to TRD + kNoCollInTimeRangeNarrow, // no other collisions in specified time range (narrower than Strict) + kNoCollInTimeRangeStrict, // no other collisions in specified time range + kNoCollInTimeRangeStandard, // no other collisions in specified time range with per-collision multiplicity above threshold + kNoCollInRofStrict, // no other collisions in this Readout Frame + kNoCollInRofStandard, // no other collisions in this Readout Frame with per-collision multiplicity above threshold + kNoHighMultCollInPrevRof, // veto an event if FT0C amplitude in previous ITS ROF is above threshold + kIsGoodITSLayer3, // number of inactive chips on ITS layer 3 is below maximum allowed value + kIsGoodITSLayer0123, // numbers of inactive chips on ITS layers 0-3 are below maximum allowed values + kIsGoodITSLayersAll, // numbers of inactive chips on all ITS layers are below maximum allowed values + kNsel // counter +}; +} // namespace o2::aod::emevsel + +#endif // PWGEM_DILEPTON_CORE_EVSELFLAGS_H diff --git a/PWGEM/Dilepton/DataModel/dileptonTables.h b/PWGEM/Dilepton/DataModel/dileptonTables.h index 425b4e0cb97..0d11e1ea166 100644 --- a/PWGEM/Dilepton/DataModel/dileptonTables.h +++ b/PWGEM/Dilepton/DataModel/dileptonTables.h @@ -9,6 +9,8 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include "EvSelFlags.h" + #include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" @@ -36,58 +38,8 @@ namespace o2::aod { -// namespace pwgem::dilepton::swt -// { -// enum class swtAliases : int { // software trigger aliases for EM -// kHighTrackMult = 0, -// kHighFt0cFv0Mult, -// kSingleE, -// kLMeeIMR, -// kLMeeHMR, -// kDiElectron, -// kSingleMuLow, -// kSingleMuHigh, -// kDiMuon, -// kNaliases -// }; -// -// const std::unordered_map aliasLabels = { -// {"fHighTrackMult", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kHighTrackMult)}, -// {"fHighFt0cFv0Mult", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kHighFt0cFv0Mult)}, -// {"fSingleE", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kSingleE)}, -// {"fLMeeIMR", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kLMeeIMR)}, -// {"fLMeeHMR", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kLMeeHMR)}, -// {"fDiElectron", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kDiElectron)}, -// {"fSingleMuLow", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kSingleMuLow)}, -// {"fSingleMuHigh", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kSingleMuHigh)}, -// {"fDiMuon", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kDiMuon)}, -// }; -// } // namespace pwgem::dilepton::swt - namespace emevsel { -// Event selection criteria. See O2Physics/Common/CCDB/EventSelectionParams.h -enum EventSelectionFlags { - kIsTriggerTVX = 0, // FT0 vertex (acceptable FT0C-FT0A time difference) at trigger level - kNoITSROFrameBorder, // bunch crossing is far from ITS RO Frame border - kNoTimeFrameBorder, // bunch crossing is far from Time Frame borders - kNoSameBunchPileup, // reject collisions in case of pileup with another collision in the same foundBC - kIsGoodZvtxFT0vsPV, // small difference between z-vertex from PV and from FT0 - kIsVertexITSTPC, // at least one ITS-TPC track (reject vertices built from ITS-only tracks) - kIsVertexTOFmatched, // at least one of vertex contributors is matched to TOF - kIsVertexTRDmatched, // at least one of vertex contributors is matched to TRD - kNoCollInTimeRangeNarrow, // no other collisions in specified time range (narrower than Strict) - kNoCollInTimeRangeStrict, // no other collisions in specified time range - kNoCollInTimeRangeStandard, // no other collisions in specified time range with per-collision multiplicity above threshold - kNoCollInRofStrict, // no other collisions in this Readout Frame - kNoCollInRofStandard, // no other collisions in this Readout Frame with per-collision multiplicity above threshold - kNoHighMultCollInPrevRof, // veto an event if FT0C amplitude in previous ITS ROF is above threshold - kIsGoodITSLayer3, // number of inactive chips on ITS layer 3 is below maximum allowed value - kIsGoodITSLayer0123, // numbers of inactive chips on ITS layers 0-3 are below maximum allowed values - kIsGoodITSLayersAll, // numbers of inactive chips on all ITS layers are below maximum allowed values - kNsel // counter -}; - DECLARE_SOA_BITMAP_COLUMN(Selection, selection, 32); //! Bitmask of selection flags DECLARE_SOA_DYNAMIC_COLUMN(Sel8, sel8, [](uint32_t selection_bit) -> bool { return (selection_bit & BIT(o2::aod::emevsel::kIsTriggerTVX)) && (selection_bit & BIT(o2::aod::emevsel::kNoTimeFrameBorder)) && (selection_bit & BIT(o2::aod::emevsel::kNoITSROFrameBorder)); }); @@ -149,7 +101,6 @@ uint32_t reduceSelectionBit(TBC const& bc) } return bitMap; } - } // namespace emevsel namespace emevent @@ -165,49 +116,54 @@ DECLARE_SOA_BITMAP_COLUMN(IsAnalyzedToI, isAnalyzedToI, 16); DECLARE_SOA_COLUMN(NeeULS, neeuls, int); DECLARE_SOA_COLUMN(NeeLSpp, neelspp, int); DECLARE_SOA_COLUMN(NeeLSmm, neelsmm, int); -DECLARE_SOA_COLUMN(Bz, bz, float); //! kG -DECLARE_SOA_COLUMN(Q2xFT0M, q2xft0m, float); //! Qx for 2nd harmonics in FT0M -DECLARE_SOA_COLUMN(Q2yFT0M, q2yft0m, float); //! Qy for 2nd harmonics in FT0M -DECLARE_SOA_COLUMN(Q2xFT0A, q2xft0a, float); //! Qx for 2nd harmonics in FT0A (i.e. positive eta) -DECLARE_SOA_COLUMN(Q2yFT0A, q2yft0a, float); //! Qy for 2nd harmonics in FT0A (i.e. positive eta) -DECLARE_SOA_COLUMN(Q2xFT0C, q2xft0c, float); //! Qx for 2nd harmonics in FT0C (i.e. negative eta) -DECLARE_SOA_COLUMN(Q2yFT0C, q2yft0c, float); //! Qy for 2nd harmonics in FT0C (i.e. negative eta) -DECLARE_SOA_COLUMN(Q2xFV0A, q2xfv0a, float); //! Qx for 2nd harmonics in FV0A (i.e. positive eta) -DECLARE_SOA_COLUMN(Q2yFV0A, q2yfv0a, float); //! Qy for 2nd harmonics in FV0A (i.e. positive eta) -DECLARE_SOA_COLUMN(Q2xBPos, q2xbpos, float); //! Qx for 2nd harmonics in Barrel positive eta region -DECLARE_SOA_COLUMN(Q2yBPos, q2ybpos, float); //! Qy for 2nd harmonics in Barrel positive eta region -DECLARE_SOA_COLUMN(Q2xBNeg, q2xbneg, float); //! Qx for 2nd harmonics in Barrel negative eta region -DECLARE_SOA_COLUMN(Q2yBNeg, q2ybneg, float); //! Qy for 2nd harmonics in Barrel negative eta region -DECLARE_SOA_COLUMN(Q2xBTot, q2xbtot, float); //! Qx for 2nd harmonics in Barrel full eta region -DECLARE_SOA_COLUMN(Q2yBTot, q2ybtot, float); //! Qy for 2nd harmonics in Barrel full eta region -DECLARE_SOA_COLUMN(Q3xFT0M, q3xft0m, float); //! Qx for 3rd harmonics in FT0M -DECLARE_SOA_COLUMN(Q3yFT0M, q3yft0m, float); //! Qy for 3rd harmonics in FT0M -DECLARE_SOA_COLUMN(Q3xFT0A, q3xft0a, float); //! Qx for 3rd harmonics in FT0A (i.e. positive eta) -DECLARE_SOA_COLUMN(Q3yFT0A, q3yft0a, float); //! Qy for 3rd harmonics in FT0A (i.e. positive eta) -DECLARE_SOA_COLUMN(Q3xFT0C, q3xft0c, float); //! Qx for 3rd harmonics in FT0C (i.e. negative eta) -DECLARE_SOA_COLUMN(Q3yFT0C, q3yft0c, float); //! Qy for 3rd harmonics in FT0C (i.e. negative eta) -DECLARE_SOA_COLUMN(Q3xFV0A, q3xfv0a, float); //! Qx for 3rd harmonics in FV0A (i.e. positive eta) -DECLARE_SOA_COLUMN(Q3yFV0A, q3yfv0a, float); //! Qy for 3rd harmonics in FV0A (i.e. positive eta) -DECLARE_SOA_COLUMN(Q3xBPos, q3xbpos, float); //! Qx for 3rd harmonics in Barrel positive eta region -DECLARE_SOA_COLUMN(Q3yBPos, q3ybpos, float); //! Qy for 3rd harmonics in Barrel positive eta region -DECLARE_SOA_COLUMN(Q3xBNeg, q3xbneg, float); //! Qx for 3rd harmonics in Barrel negative eta region -DECLARE_SOA_COLUMN(Q3yBNeg, q3ybneg, float); //! Qy for 3rd harmonics in Barrel negative eta region -DECLARE_SOA_COLUMN(Q3xBTot, q3xbtot, float); //! Qx for 3rd harmonics in Barrel full eta region -DECLARE_SOA_COLUMN(Q3yBTot, q3ybtot, float); //! Qy for 3rd harmonics in Barrel full eta region -DECLARE_SOA_COLUMN(Q4xFT0M, q4xft0m, float); //! Qx for 4th harmonics in FT0M -DECLARE_SOA_COLUMN(Q4yFT0M, q4yft0m, float); //! Qy for 4th harmonics in FT0M -DECLARE_SOA_COLUMN(Q4xFT0A, q4xft0a, float); //! Qx for 4th harmonics in FT0A (i.e. positive eta) -DECLARE_SOA_COLUMN(Q4yFT0A, q4yft0a, float); //! Qy for 4th harmonics in FT0A (i.e. positive eta) -DECLARE_SOA_COLUMN(Q4xFT0C, q4xft0c, float); //! Qx for 4th harmonics in FT0C (i.e. negative eta) -DECLARE_SOA_COLUMN(Q4yFT0C, q4yft0c, float); //! Qy for 4th harmonics in FT0C (i.e. negative eta) -DECLARE_SOA_COLUMN(Q4xFV0A, q4xfv0a, float); //! Qx for 4th harmonics in FV0A (i.e. positive eta) -DECLARE_SOA_COLUMN(Q4yFV0A, q4yfv0a, float); //! Qy for 4th harmonics in FV0A (i.e. positive eta) -DECLARE_SOA_COLUMN(Q4xBPos, q4xbpos, float); //! Qx for 4th harmonics in Barrel positive eta region -DECLARE_SOA_COLUMN(Q4yBPos, q4ybpos, float); //! Qy for 4th harmonics in Barrel positive eta region -DECLARE_SOA_COLUMN(Q4xBNeg, q4xbneg, float); //! Qx for 4th harmonics in Barrel negative eta region -DECLARE_SOA_COLUMN(Q4yBNeg, q4ybneg, float); //! Qy for 4th harmonics in Barrel negative eta region -DECLARE_SOA_COLUMN(Q4xBTot, q4xbtot, float); //! Qx for 4th harmonics in Barrel full eta region -DECLARE_SOA_COLUMN(Q4yBTot, q4ybtot, float); //! Qy for 4th harmonics in Barrel full eta region +DECLARE_SOA_COLUMN(Bz, bz, float); //! kG +DECLARE_SOA_COLUMN(Q2xFT0M, q2xft0m, float); //! Qx for 2nd harmonics in FT0M +DECLARE_SOA_COLUMN(Q2yFT0M, q2yft0m, float); //! Qy for 2nd harmonics in FT0M +DECLARE_SOA_COLUMN(Q2xFT0A, q2xft0a, float); //! Qx for 2nd harmonics in FT0A (i.e. positive eta) +DECLARE_SOA_COLUMN(Q2yFT0A, q2yft0a, float); //! Qy for 2nd harmonics in FT0A (i.e. positive eta) +DECLARE_SOA_COLUMN(Q2xFT0C, q2xft0c, float); //! Qx for 2nd harmonics in FT0C (i.e. negative eta) +DECLARE_SOA_COLUMN(Q2yFT0C, q2yft0c, float); //! Qy for 2nd harmonics in FT0C (i.e. negative eta) +DECLARE_SOA_COLUMN(Q2xFV0A, q2xfv0a, float); //! Qx for 2nd harmonics in FV0A (i.e. positive eta) +DECLARE_SOA_COLUMN(Q2yFV0A, q2yfv0a, float); //! Qy for 2nd harmonics in FV0A (i.e. positive eta) +DECLARE_SOA_COLUMN(Q2xBPos, q2xbpos, float); //! Qx for 2nd harmonics in Barrel positive eta region +DECLARE_SOA_COLUMN(Q2yBPos, q2ybpos, float); //! Qy for 2nd harmonics in Barrel positive eta region +DECLARE_SOA_COLUMN(Q2xBNeg, q2xbneg, float); //! Qx for 2nd harmonics in Barrel negative eta region +DECLARE_SOA_COLUMN(Q2yBNeg, q2ybneg, float); //! Qy for 2nd harmonics in Barrel negative eta region +DECLARE_SOA_COLUMN(Q2xBTot, q2xbtot, float); //! Qx for 2nd harmonics in Barrel full eta region +DECLARE_SOA_COLUMN(Q2yBTot, q2ybtot, float); //! Qy for 2nd harmonics in Barrel full eta region +DECLARE_SOA_COLUMN(Q3xFT0M, q3xft0m, float); //! Qx for 3rd harmonics in FT0M +DECLARE_SOA_COLUMN(Q3yFT0M, q3yft0m, float); //! Qy for 3rd harmonics in FT0M +DECLARE_SOA_COLUMN(Q3xFT0A, q3xft0a, float); //! Qx for 3rd harmonics in FT0A (i.e. positive eta) +DECLARE_SOA_COLUMN(Q3yFT0A, q3yft0a, float); //! Qy for 3rd harmonics in FT0A (i.e. positive eta) +DECLARE_SOA_COLUMN(Q3xFT0C, q3xft0c, float); //! Qx for 3rd harmonics in FT0C (i.e. negative eta) +DECLARE_SOA_COLUMN(Q3yFT0C, q3yft0c, float); //! Qy for 3rd harmonics in FT0C (i.e. negative eta) +DECLARE_SOA_COLUMN(Q3xFV0A, q3xfv0a, float); //! Qx for 3rd harmonics in FV0A (i.e. positive eta) +DECLARE_SOA_COLUMN(Q3yFV0A, q3yfv0a, float); //! Qy for 3rd harmonics in FV0A (i.e. positive eta) +DECLARE_SOA_COLUMN(Q3xBPos, q3xbpos, float); //! Qx for 3rd harmonics in Barrel positive eta region +DECLARE_SOA_COLUMN(Q3yBPos, q3ybpos, float); //! Qy for 3rd harmonics in Barrel positive eta region +DECLARE_SOA_COLUMN(Q3xBNeg, q3xbneg, float); //! Qx for 3rd harmonics in Barrel negative eta region +DECLARE_SOA_COLUMN(Q3yBNeg, q3ybneg, float); //! Qy for 3rd harmonics in Barrel negative eta region +DECLARE_SOA_COLUMN(Q3xBTot, q3xbtot, float); //! Qx for 3rd harmonics in Barrel full eta region +DECLARE_SOA_COLUMN(Q3yBTot, q3ybtot, float); //! Qy for 3rd harmonics in Barrel full eta region +DECLARE_SOA_COLUMN(Q4xFT0M, q4xft0m, float); //! Qx for 4th harmonics in FT0M +DECLARE_SOA_COLUMN(Q4yFT0M, q4yft0m, float); //! Qy for 4th harmonics in FT0M +DECLARE_SOA_COLUMN(Q4xFT0A, q4xft0a, float); //! Qx for 4th harmonics in FT0A (i.e. positive eta) +DECLARE_SOA_COLUMN(Q4yFT0A, q4yft0a, float); //! Qy for 4th harmonics in FT0A (i.e. positive eta) +DECLARE_SOA_COLUMN(Q4xFT0C, q4xft0c, float); //! Qx for 4th harmonics in FT0C (i.e. negative eta) +DECLARE_SOA_COLUMN(Q4yFT0C, q4yft0c, float); //! Qy for 4th harmonics in FT0C (i.e. negative eta) +DECLARE_SOA_COLUMN(Q4xFV0A, q4xfv0a, float); //! Qx for 4th harmonics in FV0A (i.e. positive eta) +DECLARE_SOA_COLUMN(Q4yFV0A, q4yfv0a, float); //! Qy for 4th harmonics in FV0A (i.e. positive eta) +DECLARE_SOA_COLUMN(Q4xBPos, q4xbpos, float); //! Qx for 4th harmonics in Barrel positive eta region +DECLARE_SOA_COLUMN(Q4yBPos, q4ybpos, float); //! Qy for 4th harmonics in Barrel positive eta region +DECLARE_SOA_COLUMN(Q4xBNeg, q4xbneg, float); //! Qx for 4th harmonics in Barrel negative eta region +DECLARE_SOA_COLUMN(Q4yBNeg, q4ybneg, float); //! Qy for 4th harmonics in Barrel negative eta region +DECLARE_SOA_COLUMN(Q4xBTot, q4xbtot, float); //! Qx for 4th harmonics in Barrel full eta region +DECLARE_SOA_COLUMN(Q4yBTot, q4ybtot, float); //! Qy for 4th harmonics in Barrel full eta region +DECLARE_SOA_COLUMN(QxZDCA, qxZDCA, float); //! Qx in ZDCA (i.e. positive eta) +DECLARE_SOA_COLUMN(QyZDCA, qyZDCA, float); //! Qy in ZDCA (i.e. positive eta) +DECLARE_SOA_COLUMN(QxZDCC, qxZDCC, float); //! Qx in ZDCC (i.e. negative eta) +DECLARE_SOA_COLUMN(QyZDCC, qyZDCC, float); //! Qy in ZDCC (i.e. negative eta) + DECLARE_SOA_COLUMN(SpherocityPtWeighted, spherocity_ptweighted, float); //! transverse spherocity DECLARE_SOA_COLUMN(SpherocityPtUnWeighted, spherocity_ptunweighted, float); //! transverse spherocity DECLARE_SOA_COLUMN(NtrackSpherocity, ntspherocity, int); @@ -263,28 +219,6 @@ DECLARE_SOA_DYNAMIC_COLUMN(CentNTPV, centNTPV, [](uint8_t centuint8) -> float { DECLARE_SOA_DYNAMIC_COLUMN(CentNGlobal, centNGlobal, [](uint8_t centuint8) -> float { return centuint8 < 100 ? std::nextafter(centuint8 * 0.01f, std::numeric_limits::infinity()) : std::nextafter(centuint8 - 110.f, std::numeric_limits::infinity()); }); //! centrality is multiplied by 100 in createEMEventDilepton.cxx } // namespace emeventnorm -// namespace emcent -// { -// DECLARE_SOA_COLUMN(CentFT0Muint8, centFT0Muint8, uint8_t); //! this is only to reduce data size -// DECLARE_SOA_COLUMN(CentFT0Auint8, centFT0Auint8, uint8_t); //! this is only to reduce data size -// DECLARE_SOA_COLUMN(CentFT0Cuint8, centFT0Cuint8, uint8_t); //! this is only to reduce data size -// DECLARE_SOA_COLUMN(CentNTPVuint8, centNTPVuint8, uint8_t); //! this is only to reduce data size -// DECLARE_SOA_COLUMN(CentNGlobaluint8, centNGlobaluint8, uint8_t); //! this is only to reduce data size -// -// DECLARE_SOA_EXPRESSION_COLUMN(CentFT0A, centFT0A, float, 1.f * centFT0Auint8); // this must be inverse of calculation in createEMEventDilepton.cxx -// DECLARE_SOA_EXPRESSION_COLUMN(CentFT0M, centFT0M, float, 1.f * centFT0Muint8); // this must be inverse of calculation in createEMEventDilepton.cxx -// DECLARE_SOA_EXPRESSION_COLUMN(CentFT0C, centFT0C, float, 1.f * centFT0Cuint8); // this must be inverse of calculation in createEMEventDilepton.cxx -// DECLARE_SOA_EXPRESSION_COLUMN(CentNTPV, centNTPV, float, 1.f * centNTPVuint8); // this must be inverse of calculation in createEMEventDilepton.cxx -// DECLARE_SOA_EXPRESSION_COLUMN(CentNGlobal, centNGlobal, float, 1.f * centNGlobaluint8); // this must be inverse of calculation in createEMEventDilepton.cxx -// -// // DECLARE_SOA_EXPRESSION_COLUMN(CentFT0A, centFT0A, float, (centFT0Auint8 < 100) ? std::nextafter((1.f * centFT0Auint8) / 100.f, std::numeric_limits::infinity()) : std::nextafter((1.f * centFT0Auint8) - 110.f, std::numeric_limits::infinity())); // this must be inverse of calculation in createEMEventDilepton.cxx -// // DECLARE_SOA_EXPRESSION_COLUMN(CentFT0M, centFT0M, float, (centFT0Muint8 < 100) ? std::nextafter((1.f * centFT0Muint8) / 100.f, std::numeric_limits::infinity()) : std::nextafter((1.f * centFT0Muint8) - 110.f, std::numeric_limits::infinity())); // this must be inverse of calculation in createEMEventDilepton.cxx -// // DECLARE_SOA_EXPRESSION_COLUMN(CentFT0C, centFT0C, float, (centFT0Cuint8 < 100) ? std::nextafter((1.f * centFT0Cuint8) / 100.f, std::numeric_limits::infinity()) : std::nextafter((1.f * centFT0Cuint8) - 110.f, std::numeric_limits::infinity())); // this must be inverse of calculation in createEMEventDilepton.cxx -// // DECLARE_SOA_EXPRESSION_COLUMN(CentNTPV, centNTPV, float, (centNTPVuint8 < 100) ? std::nextafter((1.f * centNTPVuint8) / 100.f, std::numeric_limits::infinity()) : std::nextafter((1.f * centNTPVuint8) - 110.f, std::numeric_limits::infinity())); // this must be inverse of calculation in createEMEventDilepton.cxx -// // DECLARE_SOA_EXPRESSION_COLUMN(CentNGlobal, centNGlobal, float, (centNGlobaluint8 < 100) ? std::nextafter((1.f * centNGlobaluint8) / 100.f, std::numeric_limits::infinity()) : std::nextafter((1.f * centNGlobaluint8) - 110.f, std::numeric_limits::infinity())); // this must be inverse of calculation in createEMEventDilepton.cxx -// -// } // namespace emcent - DECLARE_SOA_TABLE(EMBCs_000, "AOD", "EMBC", //! bc information for normalization o2::soa::Index<>, evsel::Selection, evsel::Rct); @@ -356,18 +290,6 @@ DECLARE_SOA_TABLE_VERSIONED(EMEventsCent_001, "AOD", "EMEVENTCENT", 1, //! event using EMEventsCent = EMEventsCent_001; using EMEventCent = EMEventsCent::iterator; -// DECLARE_SOA_TABLE_VERSIONED(EMEventsCentBase_001, "AOD", "EMEVENTCENT", 1, //! event centrality table stored in AO2D -// emcent::CentFT0Muint8, emcent::CentFT0Auint8, emcent::CentFT0Cuint8, emcent::CentNTPVuint8, emcent::CentNGlobaluint8); -// -// using EMEventsCentBase = EMEventsCentBase_001; -// using EMEventCentBase = EMEventsCentBase::iterator; -// -// // Extended table with expression columns that can be used for o2::framework::expressions::Filter. -// DECLARE_SOA_EXTENDED_TABLE_USER(EMEventsCent, EMEventsCentBase, "EMCENTEXT", -// emcent::CentFT0M, emcent::CentFT0A, emcent::CentFT0C, emcent::CentNTPV, emcent::CentNGlobal); -// -// using EMEventCent = EMEventsCent::iterator; - DECLARE_SOA_TABLE_VERSIONED(EMEventsQvec_000, "AOD", "EMEVENTQVEC", 0, //! event q vector table, joinable to EMEvents emevent::Q2xFT0M, emevent::Q2yFT0M, emevent::Q2xFT0A, emevent::Q2yFT0A, emevent::Q2xFT0C, emevent::Q2yFT0C, emevent::Q2xBPos, emevent::Q2yBPos, emevent::Q2xBNeg, emevent::Q2yBNeg, emevent::Q2xBTot, emevent::Q2yBTot, @@ -447,6 +369,11 @@ DECLARE_SOA_TABLE_VERSIONED(EMEventsQvec3_000, "AOD", "EMEVENTQVEC3", 0, //! M using EMEventsQvec3 = EMEventsQvec3_000; using EMEventQvec3 = EMEventsQvec3::iterator; +DECLARE_SOA_TABLE_VERSIONED(EMEventsZDC_000, "AOD", "EMEVENTZDC", 0, //! ZDC Qvector information + emevent::QxZDCA, emevent::QyZDCA, emevent::QxZDCC, emevent::QyZDCC); +using EMEventsZDC = EMEventsZDC_000; +using EMEventZDC = EMEventsZDC::iterator; + DECLARE_SOA_TABLE(EMSWTriggerBits, "AOD", "EMSWTBIT", emevent::SWTAlias, o2::soa::Marker<1>); //! joinable to EMEvents using EMSWTriggerBit = EMSWTriggerBits::iterator; @@ -1042,22 +969,23 @@ DECLARE_SOA_COLUMN(MCHTrackId, mchtrackId, int); DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN(GlobalMuonsWithSameMCHMID, globalMuonsWithSameMCHMID); //! self indices to global muons that have the same MCHTrackId DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN(GlobalMuonsWithSameMFT, globalMuonsWithSameMFT); //! self indices to global muons that have the same MFTTrackId DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN(AmbiguousMuons, ambiguousMuons); -DECLARE_SOA_COLUMN(CXXatDCA, cXXatDCA, float); //! DCAx resolution squared at DCA -DECLARE_SOA_COLUMN(CYYatDCA, cYYatDCA, float); //! DCAy resolution squared at DCA -DECLARE_SOA_COLUMN(CXYatDCA, cXYatDCA, float); //! correlation term of DCAx,y resolution at DCA -DECLARE_SOA_COLUMN(PtMatchedMCHMID, ptMatchedMCHMID, float); //! pt of MCH-MID track in MFT-MCH-MID track at PV -DECLARE_SOA_COLUMN(EtaMatchedMCHMID, etaMatchedMCHMID, float); //! eta of MCH-MID track in MFT-MCH-MID track at PV -DECLARE_SOA_COLUMN(PhiMatchedMCHMID, phiMatchedMCHMID, float); //! phi of MCH-MID track in MFT-MCH-MID track at PV -DECLARE_SOA_COLUMN(EtaMatchedMCHMIDatMP, etaMatchedMCHMIDatMP, float); //! eta of MCH-MID track in MFT-MCH-MID track at matching plane -DECLARE_SOA_COLUMN(PhiMatchedMCHMIDatMP, phiMatchedMCHMIDatMP, float); //! phi of MCH-MID track in MFT-MCH-MID track at matching plane -DECLARE_SOA_COLUMN(EtaMatchedMFTatMP, etaMatchedMFTatMP, float); //! eta of MFT track in MFT-MCH-MID track at matching plane -DECLARE_SOA_COLUMN(PhiMatchedMFTatMP, phiMatchedMFTatMP, float); //! phi of MFT track in MFT-MCH-MID track at matching plane -DECLARE_SOA_COLUMN(IsAssociatedToMPC, isAssociatedToMPC, bool); //! is associated to most probable collision -DECLARE_SOA_COLUMN(IsAmbiguous, isAmbiguous, bool); //! is ambiguous -DECLARE_SOA_COLUMN(IsCorrectMatchMFTMCH, isCorrectMatchMFTMCH, bool); //! is correct match between MFT and MCH, only for MC -DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! -DECLARE_SOA_COLUMN(Chi2MFT, chi2MFT, float); //! chi2 of MFT standalone track -DECLARE_SOA_COLUMN(PrefilterBitDerived, pfbderived, uint16_t); //! +DECLARE_SOA_COLUMN(CXXatDCA, cXXatDCA, float); //! DCAx resolution squared at DCA +DECLARE_SOA_COLUMN(CYYatDCA, cYYatDCA, float); //! DCAy resolution squared at DCA +DECLARE_SOA_COLUMN(CXYatDCA, cXYatDCA, float); //! correlation term of DCAx,y resolution at DCA +DECLARE_SOA_COLUMN(PtMatchedMCHMID, ptMatchedMCHMID, float); //! pt of MCH-MID track in MFT-MCH-MID track at PV +DECLARE_SOA_COLUMN(EtaMatchedMCHMID, etaMatchedMCHMID, float); //! eta of MCH-MID track in MFT-MCH-MID track at PV +DECLARE_SOA_COLUMN(PhiMatchedMCHMID, phiMatchedMCHMID, float); //! phi of MCH-MID track in MFT-MCH-MID track at PV +DECLARE_SOA_COLUMN(EtaMatchedMCHMIDatMP, etaMatchedMCHMIDatMP, float); //! eta of MCH-MID track in MFT-MCH-MID track at matching plane +DECLARE_SOA_COLUMN(PhiMatchedMCHMIDatMP, phiMatchedMCHMIDatMP, float); //! phi of MCH-MID track in MFT-MCH-MID track at matching plane +DECLARE_SOA_COLUMN(EtaMatchedMFTatMP, etaMatchedMFTatMP, float); //! eta of MFT track in MFT-MCH-MID track at matching plane +DECLARE_SOA_COLUMN(PhiMatchedMFTatMP, phiMatchedMFTatMP, float); //! phi of MFT track in MFT-MCH-MID track at matching plane +DECLARE_SOA_COLUMN(IsAssociatedToMPC, isAssociatedToMPC, bool); //! is associated to most probable collision +DECLARE_SOA_COLUMN(IsAmbiguous, isAmbiguous, bool); //! is ambiguous +DECLARE_SOA_COLUMN(IsCorrectMatchMFTMCH, isCorrectMatchMFTMCH, bool); //! is correct match between MFT and MCH, only for MC +DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! +DECLARE_SOA_COLUMN(Chi2MFT, chi2MFT, float); //! chi2 of MFT standalone track +DECLARE_SOA_COLUMN(DiffChi2MatchMCHMFT, diffChi2MatchingMCHMFT, float); //! difference of matching chi2 between the best and the 2nd-best matched candidates +DECLARE_SOA_COLUMN(PrefilterBitDerived, pfbderived, uint16_t); //! DECLARE_SOA_DYNAMIC_COLUMN(Tgl, tgl, [](float eta) -> float { return std::tan(o2::constants::math::PIHalf - 2 * std::atan(std::exp(-eta))); }); DECLARE_SOA_DYNAMIC_COLUMN(Signed1Pt, signed1Pt, [](float pt, int8_t sign) -> float { return sign * 1. / pt; }); DECLARE_SOA_DYNAMIC_COLUMN(P, p, [](float pt, float eta) -> float { return pt * std::cosh(eta); }); @@ -1156,7 +1084,30 @@ DECLARE_SOA_TABLE_VERSIONED(EMPrimaryMuons_002, "AOD", "EMPRIMARYMU", 2, //! emprimarymuon::Py, emprimarymuon::Pz); -using EMPrimaryMuons = EMPrimaryMuons_002; +DECLARE_SOA_TABLE_VERSIONED(EMPrimaryMuons_003, "AOD", "EMPRIMARYMU", 3, //! + o2::soa::Index<>, emprimarymuon::CollisionId, + emprimarymuon::FwdTrackId, emprimarymuon::MFTTrackId, emprimarymuon::MCHTrackId, fwdtrack::TrackType, + fwdtrack::Pt, fwdtrack::Eta, fwdtrack::Phi, emprimarymuon::Sign, + fwdtrack::FwdDcaX, fwdtrack::FwdDcaY, o2::aod::fwdtrack::CXX, o2::aod::fwdtrack::CYY, o2::aod::fwdtrack::CXY, + emprimarymuon::PtMatchedMCHMID, emprimarymuon::EtaMatchedMCHMID, emprimarymuon::PhiMatchedMCHMID, + + fwdtrack::NClusters, fwdtrack::PDca, fwdtrack::RAtAbsorberEnd, + fwdtrack::Chi2, fwdtrack::Chi2MatchMCHMID, fwdtrack::Chi2MatchMCHMFT, emprimarymuon::DiffChi2MatchMCHMFT, + fwdtrack::MCHBitMap, fwdtrack::MIDBitMap, fwdtrack::MIDBoards, + fwdtrack::MFTClusterSizesAndTrackFlags, emprimarymuon::Chi2MFT, emprimarymuon::IsAssociatedToMPC, emprimarymuon::IsAmbiguous, + + // dynamic column + emprimarymuon::Signed1Pt, + emprimarymuon::Tgl, + emprimarymuon::NClustersMFT, + fwdtrack::IsCA, + emprimarymuon::MFTClusterMap, + emprimarymuon::P, + emprimarymuon::Px, + emprimarymuon::Py, + emprimarymuon::Pz); + +using EMPrimaryMuons = EMPrimaryMuons_003; // iterators using EMPrimaryMuon = EMPrimaryMuons::iterator; @@ -1282,48 +1233,6 @@ DECLARE_SOA_TABLE_VERSIONED(EMDileptons_000, "AOD", "EMDILEPTON", 0, emdilepton::Weight); using EMDileptons = EMDileptons_000; using EMDilepton = EMDileptons::iterator; - -// Dummy data for MC -namespace emdummydata -{ -DECLARE_SOA_COLUMN(A, a, float); -DECLARE_SOA_COLUMN(B, b, float); -DECLARE_SOA_COLUMN(C, c, float); -DECLARE_SOA_COLUMN(D, d, float); -DECLARE_SOA_COLUMN(E, e, float); -DECLARE_SOA_COLUMN(F, f, float); -DECLARE_SOA_COLUMN(G, g, float); -DECLARE_SOA_COLUMN(H, h, float); -DECLARE_SOA_COLUMN(I, i, float); -DECLARE_SOA_COLUMN(J, j, float); -DECLARE_SOA_COLUMN(K, k, float); -DECLARE_SOA_COLUMN(L, l, float); -DECLARE_SOA_COLUMN(M, m, float); -DECLARE_SOA_COLUMN(N, n, float); -DECLARE_SOA_COLUMN(O, o, float); -DECLARE_SOA_COLUMN(P, p, float); -DECLARE_SOA_COLUMN(Q, q, float); -DECLARE_SOA_COLUMN(R, r, float); -DECLARE_SOA_COLUMN(S, s, float); -DECLARE_SOA_COLUMN(T, t, float); -DECLARE_SOA_COLUMN(U, u, float); -DECLARE_SOA_COLUMN(V, v, float); -DECLARE_SOA_COLUMN(W, w, float); -DECLARE_SOA_COLUMN(X, x, float); -DECLARE_SOA_COLUMN(Y, y, float); -DECLARE_SOA_COLUMN(Z, z, float); -} // namespace emdummydata -DECLARE_SOA_TABLE(EMDummyDatas, "AOD", "EMDUMMYDATA", - o2::soa::Index<>, - emdummydata::A, emdummydata::B, emdummydata::C, emdummydata::D, emdummydata::E, - emdummydata::F, emdummydata::G, emdummydata::H, emdummydata::I, emdummydata::J, - emdummydata::K, emdummydata::L, emdummydata::M, emdummydata::N, emdummydata::O, - emdummydata::P, emdummydata::Q, emdummydata::R, emdummydata::S, emdummydata::T, - emdummydata::U, emdummydata::V, emdummydata::W, emdummydata::X, emdummydata::Y, - emdummydata::Z); - -// iterators -using EMDummyData = EMDummyDatas::iterator; } // namespace o2::aod #endif // PWGEM_DILEPTON_DATAMODEL_DILEPTONTABLES_H_ diff --git a/PWGEM/Dilepton/DataModel/lmeeMLTables.h b/PWGEM/Dilepton/DataModel/lmeeMLTables.h index b8f745d730c..3fc0d0aa90b 100644 --- a/PWGEM/Dilepton/DataModel/lmeeMLTables.h +++ b/PWGEM/Dilepton/DataModel/lmeeMLTables.h @@ -346,25 +346,41 @@ using EMMLLCascPair = EMMLLCascPairs::iterator; namespace emmldilepton { -DECLARE_SOA_INDEX_COLUMN(EMMLEvent, emmlevent); //! index to event table -DECLARE_SOA_COLUMN(Signed1Pt1, signed1Pt1, float); //! q/pt of lepton1 at PV -DECLARE_SOA_COLUMN(Eta1, eta1, float); //! eta of lepton1 at PV -DECLARE_SOA_COLUMN(ImpParXY1, impParXY1, float); //! impact parameter for lepton1 in XY plane -DECLARE_SOA_COLUMN(ImpParZ1, impParZ1, float); //! impact parameter for lepton1 in Z plane -DECLARE_SOA_COLUMN(ImpParCYY1, impParCYY1, float); //! sigma of impact parameter for lepton1 in XY -DECLARE_SOA_COLUMN(ImpParCZY1, impParCZY1, float); //! sigma of impact parameter for lepton1, correlaion term -DECLARE_SOA_COLUMN(ImpParCZZ1, impParCZZ1, float); //! sigma of impact parameter for lepton1 in Z +DECLARE_SOA_INDEX_COLUMN(EMMLEvent, emmlevent); //! index to event table +DECLARE_SOA_COLUMN(Signed1Pt1, signed1Pt1, float); //! q/pt of lepton1 at PV +DECLARE_SOA_COLUMN(Eta1, eta1, float); //! eta of lepton1 at PV +DECLARE_SOA_COLUMN(ImpParXY1, impParXY1, float); //! impact parameter for lepton1 in XY plane +DECLARE_SOA_COLUMN(ImpParZ1, impParZ1, float); //! impact parameter for lepton1 in Z plane +DECLARE_SOA_COLUMN(ImpParCYY1, impParCYY1, float); //! sigma of impact parameter for lepton1 in XY +DECLARE_SOA_COLUMN(ImpParCZY1, impParCZY1, float); //! sigma of impact parameter for lepton1, correlaion term +DECLARE_SOA_COLUMN(ImpParCZZ1, impParCZZ1, float); //! sigma of impact parameter for lepton1 in Z + +DECLARE_SOA_COLUMN(UnbiasedImpParXY1, unbiasedImpParXY1, float); //! impact parameter for lepton1 in XY plane +DECLARE_SOA_COLUMN(UnbiasedImpParZ1, unbiasedImpParZ1, float); //! impact parameter for lepton1 in Z plane +DECLARE_SOA_COLUMN(UnbiasedImpParCYY1, unbiasedImpParCYY1, float); //! sigma of impact parameter for lepton1 in XY +DECLARE_SOA_COLUMN(UnbiasedImpParCZY1, unbiasedImpParCZY1, float); //! sigma of impact parameter for lepton1, correlaion term +DECLARE_SOA_COLUMN(UnbiasedImpParCZZ1, unbiasedImpParCZZ1, float); //! sigma of impact parameter for lepton1 in Z + DECLARE_SOA_COLUMN(IsCorrectCollision1, isCorrectCollision1, bool); //! lepton1 is associated to correct collision. +DECLARE_SOA_COLUMN(IsReassociated1, isReassociated1, bool); //! lepton1 is reassociated. DECLARE_SOA_COLUMN(PdgCodeMother1, pdgCodeMother1, int); //! pdg code of mother of lepton1 -DECLARE_SOA_COLUMN(Signed1Pt2, signed1Pt2, float); //! q/pt of lepton2 at PV -DECLARE_SOA_COLUMN(Eta2, eta2, float); //! eta of lepton1 at PV -DECLARE_SOA_COLUMN(ImpParXY2, impParXY2, float); //! impact parameter for lepton2 in XY plane -DECLARE_SOA_COLUMN(ImpParZ2, impParZ2, float); //! impact parameter for lepton2 in Z plane -DECLARE_SOA_COLUMN(ImpParCYY2, impParCYY2, float); //! sigma of impact parameter for lepton2 in XY -DECLARE_SOA_COLUMN(ImpParCZY2, impParCZY2, float); //! sigma of impact parameter for lepton2, correlaion term -DECLARE_SOA_COLUMN(ImpParCZZ2, impParCZZ2, float); //! sigma of impact parameter for lepton2 in Z +DECLARE_SOA_COLUMN(Signed1Pt2, signed1Pt2, float); //! q/pt of lepton2 at PV +DECLARE_SOA_COLUMN(Eta2, eta2, float); //! eta of lepton1 at PV +DECLARE_SOA_COLUMN(ImpParXY2, impParXY2, float); //! impact parameter for lepton2 in XY plane +DECLARE_SOA_COLUMN(ImpParZ2, impParZ2, float); //! impact parameter for lepton2 in Z plane +DECLARE_SOA_COLUMN(ImpParCYY2, impParCYY2, float); //! sigma of impact parameter for lepton2 in XY +DECLARE_SOA_COLUMN(ImpParCZY2, impParCZY2, float); //! sigma of impact parameter for lepton2, correlaion term +DECLARE_SOA_COLUMN(ImpParCZZ2, impParCZZ2, float); //! sigma of impact parameter for lepton2 in Z + +DECLARE_SOA_COLUMN(UnbiasedImpParXY2, unbiasedImpParXY2, float); //! impact parameter for lepton2 in XY plane +DECLARE_SOA_COLUMN(UnbiasedImpParZ2, unbiasedImpParZ2, float); //! impact parameter for lepton2 in Z plane +DECLARE_SOA_COLUMN(UnbiasedImpParCYY2, unbiasedImpParCYY2, float); //! sigma of impact parameter for lepton2 in XY +DECLARE_SOA_COLUMN(UnbiasedImpParCZY2, unbiasedImpParCZY2, float); //! sigma of impact parameter for lepton2, correlaion term +DECLARE_SOA_COLUMN(UnbiasedImpParCZZ2, unbiasedImpParCZZ2, float); //! sigma of impact parameter for lepton2 in Z + DECLARE_SOA_COLUMN(IsCorrectCollision2, isCorrectCollision2, bool); //! lepton is associated to correct collision. +DECLARE_SOA_COLUMN(IsReassociated2, isReassociated2, bool); //! lepton2 is reassociated. DECLARE_SOA_COLUMN(PdgCodeMother2, pdgCodeMother2, int); //! pdg code of mother of lepton1 DECLARE_SOA_COLUMN(Mass, mass, float); //! invariant mass of dilepton @@ -388,8 +404,9 @@ DECLARE_SOA_COLUMN(PdgCodeCommonMother, pdgCodeCommonMother, int); //! pdg code DECLARE_SOA_TABLE(EMMLDielectronsAtSV, "AOD", "EMMLEESV", //! emmldilepton::EMMLEventId, - emmldilepton::Signed1Pt1, emmldilepton::Eta1, emmldilepton::ImpParXY1, emmldilepton::ImpParZ1, emmldilepton::ImpParCYY1, emmldilepton::ImpParCZY1, emmldilepton::ImpParCZZ1, emmldilepton::IsCorrectCollision1, emmldilepton::PdgCodeMother1, - emmldilepton::Signed1Pt2, emmldilepton::Eta2, emmldilepton::ImpParXY2, emmldilepton::ImpParZ2, emmldilepton::ImpParCYY2, emmldilepton::ImpParCZY2, emmldilepton::ImpParCZZ2, emmldilepton::IsCorrectCollision2, emmldilepton::PdgCodeMother2, + emmldilepton::Signed1Pt1, emmldilepton::Eta1, emmldilepton::ImpParXY1, emmldilepton::ImpParZ1, emmldilepton::ImpParCYY1, emmldilepton::ImpParCZY1, emmldilepton::ImpParCZZ1, emmldilepton::IsCorrectCollision1, emmldilepton::IsReassociated1, emmldilepton::PdgCodeMother1, + emmldilepton::Signed1Pt2, emmldilepton::Eta2, emmldilepton::ImpParXY2, emmldilepton::ImpParZ2, emmldilepton::ImpParCYY2, emmldilepton::ImpParCZY2, emmldilepton::ImpParCZZ2, emmldilepton::IsCorrectCollision2, emmldilepton::IsReassociated2, emmldilepton::PdgCodeMother2, + emmldilepton::Mass, emmldilepton::Pt, emmldilepton::Rapidity, emmldilepton::Chi2PCA, emmldilepton::CPA, emmldilepton::CPAXY, emmldilepton::CPARZ, diff --git a/PWGEM/Dilepton/TableProducer/CMakeLists.txt b/PWGEM/Dilepton/TableProducer/CMakeLists.txt index 2a2cbf861c5..5d2889041ae 100644 --- a/PWGEM/Dilepton/TableProducer/CMakeLists.txt +++ b/PWGEM/Dilepton/TableProducer/CMakeLists.txt @@ -86,16 +86,6 @@ o2physics_add_dpl_workflow(filter-eoi PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(dielectron-producer - SOURCES dielectronProducer.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::PWGEMDileptonCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(dimuon-producer - SOURCES dimuonProducer.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::PWGEMDileptonCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(qvector-dummy-otf SOURCES qVectorDummyOTF.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore @@ -111,6 +101,11 @@ o2physics_add_dpl_workflow(qvector3-dummy-otf PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(prefilter-dielectron + SOURCES prefilterDielectron.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGEMDileptonCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(prefilter-dimuon SOURCES prefilterDimuon.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGEMDileptonCore diff --git a/PWGEM/Dilepton/TableProducer/Converters/CMakeLists.txt b/PWGEM/Dilepton/TableProducer/Converters/CMakeLists.txt index d3b100b2a31..5ac1908c3ff 100644 --- a/PWGEM/Dilepton/TableProducer/Converters/CMakeLists.txt +++ b/PWGEM/Dilepton/TableProducer/Converters/CMakeLists.txt @@ -70,6 +70,11 @@ o2physics_add_dpl_workflow(muon-converter2 PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(muon-converter3 + SOURCES muonConverter3.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(muon-selfid-converter1 SOURCES muonSelfIdConverter1.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore diff --git a/PWGEM/Dilepton/TableProducer/Converters/muonConverter3.cxx b/PWGEM/Dilepton/TableProducer/Converters/muonConverter3.cxx new file mode 100644 index 00000000000..b6e45334276 --- /dev/null +++ b/PWGEM/Dilepton/TableProducer/Converters/muonConverter3.cxx @@ -0,0 +1,52 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// ======================== +// +// This code produces muon table 003 from 002. +// Please write to: daiki.sekihata@cern.ch + +#include "PWGEM/Dilepton/DataModel/dileptonTables.h" + +#include +#include +#include + +using namespace o2; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct muonConverter3 { + Produces muon_003; + + void process(aod::EMPrimaryMuons_002 const& muons) + { + for (const auto& muon : muons) { + muon_003( + muon.collisionId(), + muon.fwdtrackId(), muon.mfttrackId(), muon.mchtrackId(), muon.trackType(), + muon.pt(), muon.eta(), muon.phi(), muon.sign(), + muon.fwdDcaX(), muon.fwdDcaY(), muon.cXX(), muon.cYY(), muon.cXY(), + muon.ptMatchedMCHMID(), muon.etaMatchedMCHMID(), muon.phiMatchedMCHMID(), + muon.nClusters(), muon.pDca(), muon.rAtAbsorberEnd(), + muon.chi2(), muon.chi2MatchMCHMID(), muon.chi2MatchMCHMFT(), 9999.f, + muon.mchBitMap(), muon.midBitMap(), muon.midBoards(), + muon.mftClusterSizesAndTrackFlags(), muon.chi2MFT(), muon.isAssociatedToMPC(), muon.isAmbiguous()); + } // end of muon loop + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"muon-converter3"})}; +} diff --git a/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx b/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx index 2e95f21f5c2..7ba4bf6d750 100644 --- a/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx +++ b/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx @@ -59,7 +59,6 @@ struct AssociateMCInfoDilepton { Produces emprimaryelectronmclabels; Produces emprimarymuonmclabels; Produces emmftmclabels; - Produces emdummydata; Configurable n_dummy_loop{"n_dummy_loop", 0, "for loop runs over n times"}; Configurable down_scaling_omega{"down_scaling_omega", 1.0, "down scaling factor to store omega"}; @@ -686,25 +685,11 @@ struct AssociateMCInfoDilepton { skimmingMC(collisions, bcs, mccollisions, mcTracks, o2tracks, o2fwdtracks, o2mfttracks, nullptr, nullptr, emprimaryelectrons, emprimarymuons); } - void processGenDummy(MyCollisionsMC const&) - { - for (int i = 0; i < n_dummy_loop; i++) { - emdummydata( - 0.f, 0.f, 0.f, 0.f, 0.f, - 0.f, 0.f, 0.f, 0.f, 0.f, - 0.f, 0.f, 0.f, 0.f, 0.f, - 0.f, 0.f, 0.f, 0.f, 0.f, - 0.f, 0.f, 0.f, 0.f, 0.f, - 0.f); - } - } - void processDummy(MyCollisionsMC const&) {} PROCESS_SWITCH(AssociateMCInfoDilepton, processMC_Electron, "create em mc event table for Electron", false); PROCESS_SWITCH(AssociateMCInfoDilepton, processMC_FwdMuon, "create em mc event table for Forward Muon", false); PROCESS_SWITCH(AssociateMCInfoDilepton, processMC_Electron_FwdMuon, "create em mc event table for Electron, FwdMuon", false); - PROCESS_SWITCH(AssociateMCInfoDilepton, processGenDummy, "produce dummy data", false); PROCESS_SWITCH(AssociateMCInfoDilepton, processDummy, "processDummy", true); }; diff --git a/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx b/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx index 7af181385b6..4e8d7d22d6c 100644 --- a/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx +++ b/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx @@ -14,6 +14,7 @@ /// \author Daiki Sekihata, daiki.sekihata@cern.ch #include "PWGEM/Dilepton/DataModel/dileptonTables.h" +#include "PWGLF/DataModel/SPCalibrationTables.h" // for ZDC information #include "Common/CCDB/EventSelectionParams.h" #include "Common/DataModel/Centrality.h" @@ -51,6 +52,7 @@ using MyQvectors = soa::Join; using MyCollisions_Cent = soa::Join; using MyCollisions_Cent_Qvec = soa::Join; +using MyCollisions_Cent_ZDC = soa::Join; using MyCollisionsWithSWT = soa::Join; using MyCollisionsWithSWT_Cent = soa::Join; @@ -70,12 +72,14 @@ struct CreateEMEventDilepton { // Produces event_qvec; Produces event_qvec2; Produces event_qvec3; + Produces event_zdc; Produces event_norm_info; enum class EMEventType : int { kEvent = 0, kEvent_Cent = 1, kEvent_Cent_Qvec = 2, + kEvent_Cent_ZDC = 3, }; // // CCDB options @@ -137,7 +141,7 @@ struct CreateEMEventDilepton { } if constexpr (eventtype == EMEventType::kEvent) { event_norm_info(o2::aod::emevsel::reduceSelectionBit(collision), collision.rct_raw(), posZint8, static_cast(105.f + 110.f), static_cast(105.f + 110.f), static_cast(105.f + 110.f) /*, static_cast(105.f + 110.f)*/); - } else if constexpr (eventtype == EMEventType::kEvent_Cent || eventtype == EMEventType::kEvent_Cent_Qvec) { + } else if constexpr (eventtype == EMEventType::kEvent_Cent || eventtype == EMEventType::kEvent_Cent_Qvec || eventtype == EMEventType::kEvent_Cent_ZDC) { uint8_t centFT0Muint8 = collision.centFT0M() < 1.f ? static_cast(collision.centFT0M() * 100.f) : static_cast(collision.centFT0M() + 110.f); uint8_t centFT0Cuint8 = collision.centFT0C() < 1.f ? static_cast(collision.centFT0C() * 100.f) : static_cast(collision.centFT0C() + 110.f); uint8_t centNTPVuint8 = collision.centNTPV() < 1.f ? static_cast(collision.centNTPV() * 100.f) : static_cast(collision.centNTPV() + 110.f); @@ -191,9 +195,6 @@ struct CreateEMEventDilepton { event_cent(collision.centFT0M(), collision.centFT0A(), collision.centFT0C(), collision.centNTPV() /*, collision.centNGlobal()*/); event_qvec2(999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f); event_qvec3(999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f); - // event_qvec( - // 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, - // 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f); } else if constexpr (eventtype == EMEventType::kEvent_Cent_Qvec) { registry.fill(HIST("hCentFT0M"), collision.centFT0M()); registry.fill(HIST("hCentFT0A"), collision.centFT0A()); @@ -214,14 +215,21 @@ struct CreateEMEventDilepton { q2xft0m = collision.qvecFT0MReVec()[0], q2xft0a = collision.qvecFT0AReVec()[0], q2xft0c = collision.qvecFT0CReVec()[0], q2xfv0a = collision.qvecFV0AReVec()[0], q2xbpos = collision.qvecBPosReVec()[0], q2xbneg = collision.qvecBNegReVec()[0], q2xbtot = collision.qvecBTotReVec()[0]; q2yft0m = collision.qvecFT0MImVec()[0], q2yft0a = collision.qvecFT0AImVec()[0], q2yft0c = collision.qvecFT0CImVec()[0], q2yfv0a = collision.qvecFV0AImVec()[0], q2ybpos = collision.qvecBPosImVec()[0], q2ybneg = collision.qvecBNegImVec()[0], q2ybtot = collision.qvecBTotImVec()[0]; } - // event_qvec(q2xft0m, q2yft0m, q2xft0a, q2yft0a, q2xft0c, q2yft0c, q2xfv0a, q2yfv0a, q2xbpos, q2ybpos, q2xbneg, q2ybneg, q2xbtot, q2ybtot, - // q3xft0m, q3yft0m, q3xft0a, q3yft0a, q3xft0c, q3yft0c, q3xfv0a, q3yfv0a, q3xbpos, q3ybpos, q3xbneg, q3ybneg, q3xbtot, q3ybtot); event_qvec2(q2xft0m, q2yft0m, q2xft0a, q2yft0a, q2xft0c, q2yft0c, q2xfv0a, q2yfv0a, q2xbpos, q2ybpos, q2xbneg, q2ybneg, q2xbtot, q2ybtot); event_qvec3(q3xft0m, q3yft0m, q3xft0a, q3yft0a, q3xft0c, q3yft0c, q3xfv0a, q3yfv0a, q3xbpos, q3ybpos, q3xbneg, q3ybneg, q3xbtot, q3ybtot); + } else if constexpr (eventtype == EMEventType::kEvent_Cent_ZDC) { + registry.fill(HIST("hCentFT0M"), collision.centFT0M()); + registry.fill(HIST("hCentFT0A"), collision.centFT0A()); + registry.fill(HIST("hCentFT0C"), collision.centFT0C()); + registry.fill(HIST("hCentNTPV"), collision.centNTPV()); + registry.fill(HIST("hCentNGlobal"), collision.centFT0M()); + + event_cent(collision.centFT0M(), collision.centFT0A(), collision.centFT0C(), collision.centNTPV() /*, collision.centNGlobal()*/); + event_qvec2(999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f); + event_qvec3(999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f); + event_zdc(collision.qxZDCA(), collision.qyZDCA(), collision.qxZDCC(), collision.qyZDCC()); } else { event_cent(105.f, 105.f, 105.f, 105.f); - // event_qvec( 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, - // 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f); event_qvec2(999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f); event_qvec3(999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f); } @@ -248,6 +256,12 @@ struct CreateEMEventDilepton { } PROCESS_SWITCH(CreateEMEventDilepton, processEvent_Cent_Qvec, "process event info", false); + void processEvent_Cent_ZDC(MyCollisions_Cent_ZDC const& collisions, MyBCs const& bcs) + { + skimEvent(collisions, bcs); + } + PROCESS_SWITCH(CreateEMEventDilepton, processEvent_Cent_ZDC, "process event info with ZDC", false); + //---------- for data with swt ---------- void processEvent_SWT(MyCollisionsWithSWT const& collisions, MyBCs const& bcs) @@ -312,6 +326,7 @@ struct AssociateDileptonToEMEvent { // LOGF(info, "collision.collisionId() = %d , nl = %d", collision.collisionId(), nl); for (int il = 0; il < nl; il++) { eventIds(collision.globalIndex()); + mCounter++; } // end of photon loop } // end of collision loop } @@ -319,6 +334,8 @@ struct AssociateDileptonToEMEvent { // This struct is for both data and MC. // Note that reconstructed collisions without mc collisions are already rejected in CreateEMEventDilepton in MC. + int mCounter{0}; + void processElectron(aod::EMEvents const& collisions, aod::EMPrimaryElectrons const& tracks) { fillEventId(collisions, tracks, prmeleventid, perCollision_el); @@ -326,7 +343,11 @@ struct AssociateDileptonToEMEvent { void processFwdMuon(aod::EMEvents const& collisions, aod::EMPrimaryMuons const& tracks) { + mCounter = 0; fillEventId(collisions, tracks, prmmueventid, perCollision_mu); + if (mCounter != tracks.size()) { + LOGF(fatal, "different table size is detected. mCounter = %d, muons.size() = %d", mCounter, tracks.size()); // this should never happen. + } } void processChargedTrack(aod::EMEvents const& collisions, soa::Join const& tracks) diff --git a/PWGEM/Dilepton/TableProducer/eventSelection.cxx b/PWGEM/Dilepton/TableProducer/eventSelection.cxx index 7c857fd6743..5b423d1d054 100644 --- a/PWGEM/Dilepton/TableProducer/eventSelection.cxx +++ b/PWGEM/Dilepton/TableProducer/eventSelection.cxx @@ -60,7 +60,6 @@ struct EMEventSelection { Configurable cfgZvtxMin{"cfgZvtxMin", -1e+10, "min. Zvtx"}; Configurable cfgZvtxMax{"cfgZvtxMax", 1e+10, "max. Zvtx"}; - Configurable cfgRequireSel8{"cfgRequireSel8", false, "require sel8 in event cut"}; Configurable cfgRequireFT0AND{"cfgRequireFT0AND", false, "require FT0AND in event cut"}; Configurable cfgRequireNoTFB{"cfgRequireNoTFB", false, "require No time frame border in event cut"}; Configurable cfgRequireNoITSROFB{"cfgRequireNoITSROFB", false, "require no ITS readout frame border in event cut"}; diff --git a/PWGEM/Dilepton/Tasks/prefilterDielectron.cxx b/PWGEM/Dilepton/TableProducer/prefilterDielectron.cxx similarity index 76% rename from PWGEM/Dilepton/Tasks/prefilterDielectron.cxx rename to PWGEM/Dilepton/TableProducer/prefilterDielectron.cxx index 77bfb3e6980..8460b0caf5c 100644 --- a/PWGEM/Dilepton/Tasks/prefilterDielectron.cxx +++ b/PWGEM/Dilepton/TableProducer/prefilterDielectron.cxx @@ -19,11 +19,11 @@ #include "PWGEM/Dilepton/DataModel/dileptonTables.h" #include "PWGEM/Dilepton/Utils/PairUtilities.h" +#include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include -#include #include #include #include @@ -40,11 +40,12 @@ #include #include #include -#include #include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) #include +#include + #include #include #include @@ -67,7 +68,6 @@ struct prefilterDielectron { using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; - // using MyTracks = soa::Join; using MyTracks = soa::Join; using MyTrack = MyTracks::iterator; @@ -77,8 +77,6 @@ struct prefilterDielectron { Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable skipGRPOquery{"skipGRPOquery", true, "skip grpo query"}; - Configurable d_bz_input{"d_bz_input", -999, "bz field in kG, -999 is automatic"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; Configurable cfgCentMin{"cfgCentMin", -1, "min. centrality"}; @@ -91,7 +89,7 @@ struct prefilterDielectron { Configurable cfgZvtxMax{"cfgZvtxMax", +10.f, "max. Zvtx"}; Configurable cfgRequireSel8{"cfgRequireSel8", false, "require sel8 in event cut"}; Configurable cfgRequireFT0AND{"cfgRequireFT0AND", true, "require FT0AND in event cut"}; - Configurable cfgRequireNoTFB{"cfgRequireNoTFB", false, "require No time frame border in event cut"}; + Configurable cfgRequireNoTFB{"cfgRequireNoTFB", true, "require No time frame border in event cut"}; Configurable cfgRequireNoITSROFB{"cfgRequireNoITSROFB", false, "require no ITS readout frame border in event cut"}; Configurable cfgRequireNoSameBunchPileup{"cfgRequireNoSameBunchPileup", false, "require no same bunch pileup in event cut"}; Configurable cfgRequireGoodZvtxFT0vsPV{"cfgRequireGoodZvtxFT0vsPV", false, "require good Zvtx between FT0 vs. PV in event cut"}; @@ -111,22 +109,19 @@ struct prefilterDielectron { // for phiv prefilter Configurable cfg_apply_phiv{"cfg_apply_phiv", false, "flag to apply phiv cut for ULS"}; // region to be rejected - Configurable cfg_apply_phiv_ls{"cfg_apply_phiv_ls", false, "flag to apply phiv cut for LS"}; // region to be rejected Configurable cfg_phiv_slope{"cfg_phiv_slope", 0.0185, "slope for m vs. phiv"}; // region to be rejected Configurable cfg_phiv_intercept{"cfg_phiv_intercept", -0.0280, "intercept for m vs. phiv"}; // region to be rejected Configurable cfg_min_phiv{"cfg_min_phiv", -1.f, "min phiv"}; // region to be rejected Configurable cfg_max_phiv{"cfg_max_phiv", 3.2, "max phiv"}; // region to be rejected // for deta-dphi prefilter - Configurable cfg_apply_detadphi_uls{"cfg_apply_detadphi_uls", false, "flag to apply deta-dphi elliptic cut in ULS"}; // region to be rejected - Configurable cfg_apply_detadphi_ls{"cfg_apply_detadphi_ls", false, "flag to apply deta-dphi elliptic cut in LS"}; // region to be rejected - Configurable cfg_apply_detadphiPosition_uls{"cfg_apply_detadphiPosition_uls", false, "flag to apply deta-dphiPosition elliptic cut in ULS"}; // region to be rejected - Configurable cfg_apply_detadphiPosition_ls{"cfg_apply_detadphiPosition_ls", false, "flag to apply deta-dphiPosition elliptic cut in LS"}; // region to be rejected - Configurable cfg_min_deta_ls{"cfg_min_deta_ls", 0.04, "deta between 2 electrons (elliptic cut)"}; // region to be rejected - Configurable cfg_min_dphi_ls{"cfg_min_dphi_ls", 0.2, "dphi between 2 electrons (elliptic cut)"}; // region to be rejected - Configurable cfg_min_deta_uls{"cfg_min_deta_uls", 0.04, "deta between 2 electrons (elliptic cut)"}; // region to be rejected - Configurable cfg_min_dphi_uls{"cfg_min_dphi_uls", 0.2, "dphi between 2 electrons (elliptic cut)"}; // region to be rejected - Configurable cfgRefR{"cfgRefR", 0.5, "reference R (in m) for extrapolation"}; // https://cds.cern.ch/record/1419204 + Configurable cfg_apply_detadphi_uls{"cfg_apply_detadphi_uls", false, "flag to apply deta-dphi elliptic cut in ULS"}; // region to be rejected + Configurable cfg_apply_detadphi_ls{"cfg_apply_detadphi_ls", false, "flag to apply deta-dphi elliptic cut in LS"}; // region to be rejected + Configurable cfg_min_deta_ls{"cfg_min_deta_ls", 0.04, "deta between 2 electrons (elliptic cut)"}; // region to be rejected + Configurable cfg_min_dphi_ls{"cfg_min_dphi_ls", 0.2, "dphi between 2 electrons (elliptic cut)"}; // region to be rejected + Configurable cfg_min_deta_uls{"cfg_min_deta_uls", 0.04, "deta between 2 electrons (elliptic cut)"}; // region to be rejected + Configurable cfg_min_dphi_uls{"cfg_min_dphi_uls", 0.2, "dphi between 2 electrons (elliptic cut)"}; // region to be rejected + Configurable cfgRefR{"cfgRefR", 0.5, "reference R (in m) for extrapolation"}; // https://cds.cern.ch/record/1419204 Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.15, "min pT for single track"}; Configurable cfg_max_pt_track{"cfg_max_pt_track", 1e+10, "max pT for single track"}; @@ -143,12 +138,14 @@ struct prefilterDielectron { Configurable cfg_max_chi2tof{"cfg_max_chi2tof", 1e+10, "max chi2 TOF"}; Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1.f, "max dca XY for single track in cm"}; Configurable cfg_max_dcaz{"cfg_max_dcaz", 1.f, "max dca Z for single track in cm"}; + o2::framework::Configurable cfg_max_dca_sigma{"cfg_max_dca_sigma", 1e+10, "max dca for single track in sigma"}; Configurable cfg_require_itsib_any{"cfg_require_itsib_any", true, "flag to require ITS ib any hits"}; Configurable cfg_require_itsib_1st{"cfg_require_itsib_1st", false, "flag to require ITS ib 1st hit"}; Configurable cfg_min_its_cluster_size{"cfg_min_its_cluster_size", 0.f, "min ITS cluster size"}; Configurable cfg_max_its_cluster_size{"cfg_max_its_cluster_size", 16.f, "max ITS cluster size"}; // Configurable cfg_min_rel_diff_pin{"cfg_min_rel_diff_pin", -1e+10, "min rel. diff. between pin and ppv"}; // Configurable cfg_max_rel_diff_pin{"cfg_max_rel_diff_pin", +1e+10, "max rel. diff. between pin and ppv"}; + o2::framework::Configurable cfgDCAType{"cfgDCAType", 0, "type of DCA for output. 0:3D, 1:XY, 2:Z, else:3D"}; Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3, kTOFif : 4, kPIDML : 5, kTPChadrejORTOFreq_woTOFif : 6]"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; @@ -179,10 +176,9 @@ struct prefilterDielectron { // Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; } dielectroncuts; - o2::ccdb::CcdbApi ccdbApi; Service ccdb; - int mRunNumber; - float d_bz; + int mRunNumber{0}; + float d_bz{0}; o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; @@ -200,13 +196,6 @@ struct prefilterDielectron { ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); - - if (dielectroncuts.cfg_apply_detadphi_uls && dielectroncuts.cfg_apply_detadphiPosition_uls) { - LOG(fatal) << "cfg_apply_detadphi_uls and cfg_apply_detadphiPosition_uls cannot be used simultaneously. Please select only one."; - } - if (dielectroncuts.cfg_apply_detadphi_ls && dielectroncuts.cfg_apply_detadphiPosition_ls) { - LOG(fatal) << "cfg_apply_detadphi_ls and cfg_apply_detadphiPosition_ls cannot be used simultaneously. Please select only one."; - } } template @@ -216,23 +205,9 @@ struct prefilterDielectron { return; } - // In case override, don't proceed, please - no CCDB access required - if (d_bz_input > -990) { - d_bz = d_bz_input; - o2::parameters::GRPMagField grpmag; - if (fabs(d_bz) > 1e-5) { - grpmag.setL3Current(30000.f / (d_bz / 5.0f)); - } - o2::base::Propagator::initFieldFromGRP(&grpmag); - mRunNumber = collision.runNumber(); - return; - } - auto run3grp_timestamp = collision.timestamp(); o2::parameters::GRPObject* grpo = 0x0; o2::parameters::GRPMagField* grpmag = 0x0; - if (!skipGRPOquery) - grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); if (grpo) { o2::base::Propagator::initFieldFromGRP(grpo); // Fetch magnetic field from ccdb for current collision @@ -263,7 +238,6 @@ struct prefilterDielectron { fRegistry.add("Pair/before/uls/hMvsPt", "m_{ee} vs. p_{T,ee}", kTH2D, {axis_mass, axis_pair_pt}, true); fRegistry.add("Pair/before/uls/hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", kTH2D, {axis_phiv, {200, 0, 1}}, true); fRegistry.add("Pair/before/uls/hDeltaEtaDeltaPhi", "#Delta#eta-#Delta#varphi between 2 tracks;#Delta#varphi (rad.);#Delta#eta;", kTH2D, {{180, -M_PI, M_PI}, {400, -2, +2}}, true); - fRegistry.add("Pair/before/uls/hDeltaEtaDeltaPhiPos", Form("#Delta#eta-#Delta#varphi* between 2 tracks at r_{xy} = %3.2f m;#Delta#varphi* (rad.);#Delta#eta;", dielectroncuts.cfgRefR.value), kTH2D, {{180, -M_PI, M_PI}, {400, -2, +2}}, true); fRegistry.addClone("Pair/before/uls/", "Pair/before/lspp/"); fRegistry.addClone("Pair/before/uls/", "Pair/before/lsmm/"); fRegistry.addClone("Pair/before/", "Pair/after/"); @@ -306,6 +280,7 @@ struct prefilterDielectron { fDielectronCut.SetChi2PerClusterITS(0.0, dielectroncuts.cfg_max_chi2its); fDielectronCut.SetNClustersITS(dielectroncuts.cfg_min_ncluster_its, 7); fDielectronCut.SetMeanClusterSizeITS(dielectroncuts.cfg_min_its_cluster_size, dielectroncuts.cfg_max_its_cluster_size); + fDielectronCut.SetTrackMaxDcaSigma(dielectroncuts.cfg_max_dca_sigma, dielectroncuts.cfgDCAType); fDielectronCut.SetTrackMaxDcaXY(dielectroncuts.cfg_max_dcaxy); fDielectronCut.SetTrackMaxDcaZ(dielectroncuts.cfg_max_dcaz); fDielectronCut.RequireITSibAny(dielectroncuts.cfg_require_itsib_any); @@ -394,15 +369,9 @@ struct prefilterDielectron { float dphi = pos.sign() * v1.Pt() > ele.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); dphi = RecoDecay::constrainAngle(dphi, -M_PI, 1U); // -pi - +pi - float phiPosition1 = RecoDecay::constrainAngle(pos.phi() + std::asin(pos.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * pos.pt())), 0, 1U); // 0-2pi - float phiPosition2 = RecoDecay::constrainAngle(ele.phi() + std::asin(ele.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * ele.pt())), 0, 1U); // 0-2pi - float dphiPosition = pos.sign() * v1.Pt() > ele.sign() * v2.Pt() ? phiPosition1 - phiPosition2 : phiPosition2 - phiPosition1; - dphiPosition = RecoDecay::constrainAngle(dphiPosition, -M_PI, 1U); // -pi - +pi - fRegistry.fill(HIST("Pair/before/uls/hMvsPhiV"), phiv, v12.M()); fRegistry.fill(HIST("Pair/before/uls/hMvsPt"), v12.M(), v12.Pt()); fRegistry.fill(HIST("Pair/before/uls/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST("Pair/before/uls/hDeltaEtaDeltaPhiPos"), dphiPosition, deta); if (dielectroncuts.cfg_min_mass < v12.M() && v12.M() < dielectroncuts.cfg_max_mass) { map_pfb[pos.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee); @@ -419,10 +388,6 @@ struct prefilterDielectron { map_pfb[ele.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS); } - if (dielectroncuts.cfg_apply_detadphiPosition_uls && std::pow(deta / dielectroncuts.cfg_min_deta_uls, 2) + std::pow(dphiPosition / dielectroncuts.cfg_min_dphi_uls, 2) < 1.f) { - map_pfb[pos.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULSAtRefR); - map_pfb[ele.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULSAtRefR); - } } // end of ULS pairing for (const auto& [pos1, pos2] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ @@ -439,31 +404,15 @@ struct prefilterDielectron { float dphi = pos1.sign() * v1.Pt() > pos2.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); dphi = RecoDecay::constrainAngle(dphi, -M_PI, 1U); // -pi - +pi - float phiPosition1 = RecoDecay::constrainAngle(pos1.phi() + std::asin(pos1.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * pos1.pt())), 0, 1U); // 0-2pi - float phiPosition2 = RecoDecay::constrainAngle(pos2.phi() + std::asin(pos2.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * pos2.pt())), 0, 1U); // 0-2pi - float dphiPosition = pos1.sign() * v1.Pt() > pos2.sign() * v2.Pt() ? phiPosition1 - phiPosition2 : phiPosition2 - phiPosition1; - dphiPosition = RecoDecay::constrainAngle(dphiPosition, -M_PI, 1U); // -pi - +pi - fRegistry.fill(HIST("Pair/before/lspp/hMvsPt"), v12.M(), v12.Pt()); fRegistry.fill(HIST("Pair/before/lspp/hMvsPhiV"), phiv, v12.M()); fRegistry.fill(HIST("Pair/before/lspp/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST("Pair/before/lspp/hDeltaEtaDeltaPhiPos"), dphiPosition, deta); - - if (dielectroncuts.cfg_apply_phiv_ls && ((v12.M() < dielectroncuts.cfg_phiv_slope * phiv + dielectroncuts.cfg_phiv_intercept) && (dielectroncuts.cfg_min_phiv < phiv && phiv < dielectroncuts.cfg_max_phiv))) { - map_pfb[pos1.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS); - map_pfb[pos2.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS); - } if (dielectroncuts.cfg_apply_detadphi_ls && std::pow(deta / dielectroncuts.cfg_min_deta_ls, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi_ls, 2) < 1.f) { map_pfb[pos1.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); map_pfb[pos2.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); } - if (dielectroncuts.cfg_apply_detadphiPosition_ls && std::pow(deta / dielectroncuts.cfg_min_deta_uls, 2) + std::pow(dphiPosition / dielectroncuts.cfg_min_dphi_uls, 2) < 1.f) { - map_pfb[pos1.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR); - map_pfb[pos2.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR); - } - } // end of LS++ pairing for (const auto& [ele1, ele2] : combinations(CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- @@ -480,30 +429,15 @@ struct prefilterDielectron { float dphi = ele1.sign() * v1.Pt() > ele2.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); dphi = RecoDecay::constrainAngle(dphi, -M_PI, 1U); // -pi - +pi - float phiPosition1 = RecoDecay::constrainAngle(ele1.phi() + std::asin(ele1.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * ele1.pt())), 0, 1U); // 0-2pi - float phiPosition2 = RecoDecay::constrainAngle(ele2.phi() + std::asin(ele2.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * ele2.pt())), 0, 1U); // 0-2pi - float dphiPosition = ele1.sign() * v1.Pt() > ele2.sign() * v2.Pt() ? phiPosition1 - phiPosition2 : phiPosition2 - phiPosition1; - dphiPosition = RecoDecay::constrainAngle(dphiPosition, -M_PI, 1U); // -pi - +pi - fRegistry.fill(HIST("Pair/before/lsmm/hMvsPt"), v12.M(), v12.Pt()); fRegistry.fill(HIST("Pair/before/lsmm/hMvsPhiV"), phiv, v12.M()); fRegistry.fill(HIST("Pair/before/lsmm/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST("Pair/before/lsmm/hDeltaEtaDeltaPhiPos"), dphiPosition, deta); - - if (dielectroncuts.cfg_apply_phiv_ls && ((v12.M() < dielectroncuts.cfg_phiv_slope * phiv + dielectroncuts.cfg_phiv_intercept) && (dielectroncuts.cfg_min_phiv < phiv && phiv < dielectroncuts.cfg_max_phiv))) { - map_pfb[ele1.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS); - map_pfb[ele2.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiVLS); - } if (dielectroncuts.cfg_apply_detadphi_ls && std::pow(deta / dielectroncuts.cfg_min_deta_ls, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi_ls, 2) < 1.f) { map_pfb[ele1.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); map_pfb[ele2.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); } - if (dielectroncuts.cfg_apply_detadphiPosition_ls && std::pow(deta / dielectroncuts.cfg_min_deta_uls, 2) + std::pow(dphiPosition / dielectroncuts.cfg_min_dphi_uls, 2) < 1.f) { - map_pfb[ele1.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR); - map_pfb[ele2.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLSAtRefR); - } } // end of LS-- pairing } // end of collision loop @@ -542,15 +476,9 @@ struct prefilterDielectron { float dphi = pos.sign() * v1.Pt() > ele.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); dphi = RecoDecay::constrainAngle(dphi, -M_PI, 1U); // -pi - +pi - float phiPosition1 = RecoDecay::constrainAngle(pos.phi() + std::asin(pos.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * pos.pt())), 0, 1U); // 0-2pi - float phiPosition2 = RecoDecay::constrainAngle(ele.phi() + std::asin(ele.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * ele.pt())), 0, 1U); // 0-2pi - float dphiPosition = pos.sign() * v1.Pt() > ele.sign() * v2.Pt() ? phiPosition1 - phiPosition2 : phiPosition2 - phiPosition1; - dphiPosition = RecoDecay::constrainAngle(dphiPosition, -M_PI, 1U); // -pi - +pi - fRegistry.fill(HIST("Pair/after/uls/hMvsPhiV"), phiv, v12.M()); fRegistry.fill(HIST("Pair/after/uls/hMvsPt"), v12.M(), v12.Pt()); fRegistry.fill(HIST("Pair/after/uls/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST("Pair/after/uls/hDeltaEtaDeltaPhiPos"), dphiPosition, deta); } for (const auto& [pos1, pos2] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ @@ -569,15 +497,9 @@ struct prefilterDielectron { float dphi = pos1.sign() * v1.Pt() > pos2.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); dphi = RecoDecay::constrainAngle(dphi, -M_PI, 1U); // -pi - +pi - float phiPosition1 = RecoDecay::constrainAngle(pos1.phi() + std::asin(pos1.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * pos1.pt())), 0, 1U); // 0-2pi - float phiPosition2 = RecoDecay::constrainAngle(pos2.phi() + std::asin(pos2.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * pos2.pt())), 0, 1U); // 0-2pi - float dphiPosition = pos1.sign() * v1.Pt() > pos2.sign() * v2.Pt() ? phiPosition1 - phiPosition2 : phiPosition2 - phiPosition1; - dphiPosition = RecoDecay::constrainAngle(dphiPosition, -M_PI, 1U); // -pi - +pi - fRegistry.fill(HIST("Pair/after/lspp/hMvsPt"), v12.M(), v12.Pt()); fRegistry.fill(HIST("Pair/after/lspp/hMvsPhiV"), phiv, v12.M()); fRegistry.fill(HIST("Pair/after/lspp/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST("Pair/after/lspp/hDeltaEtaDeltaPhiPos"), dphiPosition, deta); } for (const auto& [ele1, ele2] : combinations(CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- @@ -596,15 +518,9 @@ struct prefilterDielectron { float dphi = ele1.sign() * v1.Pt() > ele2.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); dphi = RecoDecay::constrainAngle(dphi, -M_PI, 1U); // -pi - +pi - float phiPosition1 = RecoDecay::constrainAngle(ele1.phi() + std::asin(ele1.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * ele1.pt())), 0, 1U); // 0-2pi - float phiPosition2 = RecoDecay::constrainAngle(ele2.phi() + std::asin(ele2.sign() * -0.30282 * (d_bz * 0.1) * dielectroncuts.cfgRefR / (2.f * ele2.pt())), 0, 1U); // 0-2pi - float dphiPosition = ele1.sign() * v1.Pt() > ele2.sign() * v2.Pt() ? phiPosition1 - phiPosition2 : phiPosition2 - phiPosition1; - dphiPosition = RecoDecay::constrainAngle(dphiPosition, -M_PI, 1U); // -pi - +pi - fRegistry.fill(HIST("Pair/after/lsmm/hMvsPt"), v12.M(), v12.Pt()); fRegistry.fill(HIST("Pair/after/lsmm/hMvsPhiV"), phiv, v12.M()); fRegistry.fill(HIST("Pair/after/lsmm/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST("Pair/after/lsmm/hDeltaEtaDeltaPhiPos"), dphiPosition, deta); } } // end of collision loop diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronSV.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronSV.cxx index 3402faa2e42..d5d1f21543d 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronSV.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronSV.cxx @@ -14,7 +14,6 @@ #include "PWGEM/Dilepton/DataModel/dileptonTables.h" #include "PWGEM/Dilepton/Utils/ElectronModule.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" #include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" @@ -22,9 +21,6 @@ #include "Common/DataModel/PIDResponseTPC.h" #include -#include -#include -#include #include #include #include @@ -39,31 +35,26 @@ #include #include -#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) - #include -#include #include #include #include struct skimmerPrimaryElectronSV { - - // using MyBCs = o2::soa::Join; - using MyBCs = o2::soa::Join; + using MyBCs = o2::soa::Join; using MyCollisions = o2::soa::Join; using MyCollisionsWithSWT = o2::soa::Join; - using MyTracks = o2::soa::Join; using MyTrack = MyTracks::iterator; using MyTracksMC = o2::soa::Join; using MyTrackMC = MyTracksMC::iterator; - using MyV0s = o2::soa::Join; - using MyCascades = o2::soa::Join; + // using MyV0s = o2::soa::Join; + // using MyCascades = o2::soa::Join; struct : o2::framework::ConfigurableGroup { o2::framework::Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; @@ -73,19 +64,18 @@ struct skimmerPrimaryElectronSV { o2::framework::Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; } ccdbConfig; - o2::framework::Configurable doSCTwithTracks{"doSCTwithTracks", true, "flag to tag electrons with tracks"}; - o2::framework::Configurable doSCTwithV0s{"doSCTwithV0s", false, "flag to tag electrons with v0s"}; - o2::framework::Configurable doSCTwithCascades{"doSCTwithCascades", false, "flag to tag electrons with cascades"}; + o2::framework::Configurable doSCTwithTracks{"doSCTwithTracks", false, "flag to tag electrons with tracks"}; + // o2::framework::Configurable doSCTwithV0s{"doSCTwithV0s", false, "flag to tag electrons with v0s"}; + // o2::framework::Configurable doSCTwithCascades{"doSCTwithCascades", false, "flag to tag electrons with cascades"}; o2::framework::Service ccdb; - o2::ccdb::CcdbApi ccdbApi; o2::framework::Service mTOFResponse; o2::framework::SliceCache cache; - o2::framework::Preslice perCol_track = o2::aod::track::collisionId; + o2::framework::Preslice perCol_track = o2::aod::track::collisionId; o2::framework::Preslice trackIndicesPerCollision = o2::aod::track_association::collisionId; - o2::framework::Preslice perCol_v0 = o2::aod::v0data::collisionId; - o2::framework::Preslice perCol_casc = o2::aod::cascdata::collisionId; + // o2::framework::Preslice perCol_v0 = o2::aod::v0data::collisionId; + // o2::framework::Preslice perCol_casc = o2::aod::cascdata::collisionId; void init(o2::framework::InitContext& initContext) { @@ -97,18 +87,14 @@ struct skimmerPrimaryElectronSV { ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); - // ccdbApi.init(ccdbConfig.ccdburl); - // mTOFResponse->initSetup(ccdb, initContext); LOGF(info, "initializing electronModule"); - electronModule.init(cfgEelectronCut, cfgEelectronPFCut, cfgHadronCut, cfgV0Cut, cfgCascadeCut, cfgDFeT, cfgDFeV0, cfgDFeC, initContext, ccdb, mTOFResponse, ccdbConfig.ccdburl.value); - // electronModule.setTOFResponse(mTOFResponse); + electronModule.init(cfgEelectronCut, cfgEelectronPFCut, cfgHadronCut, /*cfgV0Cut, cfgCascadeCut,*/ cfgDFeT, /*cfgDFeV0, cfgDFeC,*/ initContext, ccdb, mTOFResponse, ccdbConfig.ccdburl.value); electronModule.addHistograms(mRegistry); - // electronModule.doPFB(doPF.value); electronModule.doSCTwithTracks(doSCTwithTracks.value); - electronModule.doSCTwithV0s(doSCTwithV0s.value); - electronModule.doSCTwithCascades(doSCTwithCascades.value); + // electronModule.doSCTwithV0s(doSCTwithV0s.value); + // electronModule.doSCTwithCascades(doSCTwithCascades.value); } o2::pwgem::dilepton::utils::ElectronModule electronModule; @@ -116,11 +102,11 @@ struct skimmerPrimaryElectronSV { o2::pwgem::dilepton::utils::electronCut cfgEelectronCut; o2::pwgem::dilepton::utils::electronPFCut cfgEelectronPFCut; o2::pwgem::dilepton::utils::hadronCut cfgHadronCut; - o2::pwgem::dilepton::utils::v0Cut cfgV0Cut; - o2::pwgem::dilepton::utils::cascadeCut cfgCascadeCut; + // o2::pwgem::dilepton::utils::v0Cut cfgV0Cut; + // o2::pwgem::dilepton::utils::cascadeCut cfgCascadeCut; o2::pwgem::dilepton::utils::cfgDFeT cfgDFeT; - o2::pwgem::dilepton::utils::cfgDFeV0 cfgDFeV0; - o2::pwgem::dilepton::utils::cfgDFeC cfgDFeC; + // o2::pwgem::dilepton::utils::cfgDFeV0 cfgDFeV0; + // o2::pwgem::dilepton::utils::cfgDFeC cfgDFeC; o2::framework::HistogramRegistry mRegistry{"output", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject, false, false}; // ---------- for data ---------- @@ -174,78 +160,78 @@ struct skimmerPrimaryElectronSV { mRunNumber = bc.runNumber(); } - //! type of V0. 0: built solely for cascades (does not pass standard V0 cut), 1: standard 2, 3: photon-like with TPC-only use. Regular analysis should always use type 1. - o2::framework::expressions::Filter v0Filter = o2::aod::v0data::v0Type == uint8_t(1) && o2::aod::v0data::v0cosPA > cfgV0Cut.cfg_min_cospa&& o2::aod::v0data::dcaV0daughters cfgV0Cut.cfg_min_dcaxy&& nabs(o2::aod::v0data::dcanegtopv) > cfgV0Cut.cfg_min_dcaxy; - using filteredMyV0s = o2::soa::Filtered; + // //! type of V0. 0: built solely for cascades (does not pass standard V0 cut), 1: standard 2, 3: photon-like with TPC-only use. Regular analysis should always use type 1. + // o2::framework::expressions::Filter v0Filter = o2::aod::v0data::v0Type == uint8_t(1) && o2::aod::v0data::v0cosPA > cfgV0Cut.cfg_min_cospa&& o2::aod::v0data::dcaV0daughters cfgV0Cut.cfg_min_dcaxy&& nabs(o2::aod::v0data::dcanegtopv) > cfgV0Cut.cfg_min_dcaxy; + // using filteredMyV0s = o2::soa::Filtered; - o2::framework::expressions::Filter cascadeFilter = nabs(o2::aod::cascdata::dcanegtopv) > cfgCascadeCut.cfg_min_dcaxy_v0leg&& nabs(o2::aod::cascdata::dcanegtopv) > cfgCascadeCut.cfg_min_dcaxy_v0leg&& nabs(o2::aod::cascdata::dcabachtopv) > cfgCascadeCut.cfg_min_dcaxy_bachelor&& o2::aod::cascdata::dcacascdaughters < cfgCascadeCut.cfg_max_dcadau&& o2::aod::cascdata::dcaV0daughters < cfgCascadeCut.cfg_max_dcadau_v0; - using filteredMyCascades = o2::soa::Filtered; + // o2::framework::expressions::Filter cascadeFilter = nabs(o2::aod::cascdata::dcanegtopv) > cfgCascadeCut.cfg_min_dcaxy_v0leg&& nabs(o2::aod::cascdata::dcanegtopv) > cfgCascadeCut.cfg_min_dcaxy_v0leg&& nabs(o2::aod::cascdata::dcabachtopv) > cfgCascadeCut.cfg_min_dcaxy_bachelor&& o2::aod::cascdata::dcacascdaughters < cfgCascadeCut.cfg_max_dcadau&& o2::aod::cascdata::dcaV0daughters < cfgCascadeCut.cfg_max_dcadau_v0; + // using filteredMyCascades = o2::soa::Filtered; - void processRec_SA(MyCollisions const& collisions, MyBCs const& bcs, MyTracks const& tracks, filteredMyV0s const& v0s, filteredMyCascades const& cascades) + void processRec_SA(MyCollisions const& collisions, MyBCs const& bcs, MyTracks const& tracks /*, filteredMyV0s const& v0s, filteredMyCascades const& cascades*/) { if (bcs.size() == 0) { return; } auto bc = bcs.begin(); initCCDB(bc); - electronModule.processWithoutTTCA(bcs, collisions, tracks, v0s, cascades, nullptr, products, mRegistry); + electronModule.processWithoutTTCA(bcs, collisions, tracks, /*v0s, cascades,*/ nullptr, products, mRegistry); } PROCESS_SWITCH(skimmerPrimaryElectronSV, processRec_SA, "process reconstructed info only", true); // standalone - void processRec_TTCA(MyCollisions const& collisions, MyBCs const& bcs, MyTracks const& tracks, o2::aod::TrackAssoc const& trackIndices, filteredMyV0s const& v0s, filteredMyCascades const& cascades) + void processRec_TTCA(MyCollisions const& collisions, MyBCs const& bcs, MyTracks const& tracks, o2::aod::TrackAssoc const& trackIndices /*, filteredMyV0s const& v0s, filteredMyCascades const& cascades*/) { if (bcs.size() == 0) { return; } auto bc = bcs.begin(); initCCDB(bc); - electronModule.processWithTTCA(bcs, collisions, tracks, v0s, cascades, trackIndices, nullptr, products, mRegistry, cache, perCol_track, trackIndicesPerCollision, perCol_v0, perCol_casc); + electronModule.processWithTTCA(bcs, collisions, tracks, /*v0s, cascades,*/ trackIndices, nullptr, products, mRegistry, cache, perCol_track, trackIndicesPerCollision /*, perCol_v0, perCol_casc*/); } PROCESS_SWITCH(skimmerPrimaryElectronSV, processRec_TTCA, "process reconstructed info only", false); // with TTCA - void processRec_SA_SWT(MyCollisionsWithSWT const& collisions, MyBCs const& bcs, MyTracks const& tracks, filteredMyV0s const& v0s, filteredMyCascades const& cascades) + void processRec_SA_SWT(MyCollisionsWithSWT const& collisions, MyBCs const& bcs, MyTracks const& tracks /*, filteredMyV0s const& v0s, filteredMyCascades const& cascades*/) { if (bcs.size() == 0) { return; } auto bc = bcs.begin(); initCCDB(bc); - electronModule.processWithoutTTCA(bcs, collisions, tracks, v0s, cascades, nullptr, products, mRegistry); + electronModule.processWithoutTTCA(bcs, collisions, tracks, /*v0s, cascades,*/ nullptr, products, mRegistry); } PROCESS_SWITCH(skimmerPrimaryElectronSV, processRec_SA_SWT, "process reconstructed info only", false); // standalone with swt - void processRec_TTCA_SWT(MyCollisionsWithSWT const& collisions, MyBCs const& bcs, MyTracks const& tracks, o2::aod::TrackAssoc const& trackIndices, filteredMyV0s const& v0s, filteredMyCascades const& cascades) + void processRec_TTCA_SWT(MyCollisionsWithSWT const& collisions, MyBCs const& bcs, MyTracks const& tracks, o2::aod::TrackAssoc const& trackIndices /*, filteredMyV0s const& v0s, filteredMyCascades const& cascades*/) { if (bcs.size() == 0) { return; } auto bc = bcs.begin(); initCCDB(bc); - electronModule.processWithTTCA(bcs, collisions, tracks, v0s, cascades, trackIndices, nullptr, products, mRegistry, cache, perCol_track, trackIndicesPerCollision, perCol_v0, perCol_casc); + electronModule.processWithTTCA(bcs, collisions, tracks, /*v0s, cascades,*/ trackIndices, nullptr, products, mRegistry, cache, perCol_track, trackIndicesPerCollision /*, perCol_v0, perCol_casc*/); } PROCESS_SWITCH(skimmerPrimaryElectronSV, processRec_TTCA_SWT, "process reconstructed info only", false); // with TTCA with swt // ---------- for MC ---------- - void processMC_SA(o2::soa::Join const& collisions, MyBCs const& bcs, MyTracksMC const& tracks, filteredMyV0s const& v0s, filteredMyCascades const& cascades, o2::aod::McParticles const& mcParticles) + void processMC_SA(o2::soa::Join const& collisions, MyBCs const& bcs, MyTracksMC const& tracks, /*filteredMyV0s const& v0s, filteredMyCascades const& cascades,*/ o2::aod::McParticles const& mcParticles) { if (bcs.size() == 0) { return; } auto bc = bcs.begin(); initCCDB(bc); - electronModule.processWithoutTTCA(bcs, collisions, tracks, v0s, cascades, mcParticles, products, mRegistry); + electronModule.processWithoutTTCA(bcs, collisions, tracks, /*v0s, cascades,*/ mcParticles, products, mRegistry); } PROCESS_SWITCH(skimmerPrimaryElectronSV, processMC_SA, "process reconstructed and MC info ", false); // without TTCA in MC - void processMC_TTCA(o2::soa::Join const& collisions, MyBCs const& bcs, MyTracksMC const& tracks, o2::aod::TrackAssoc const& trackIndices, filteredMyV0s const& v0s, filteredMyCascades const& cascades, o2::aod::McParticles const& mcParticles) + void processMC_TTCA(o2::soa::Join const& collisions, MyBCs const& bcs, MyTracksMC const& tracks, o2::aod::TrackAssoc const& trackIndices, /*filteredMyV0s const& v0s, filteredMyCascades const& cascades,*/ o2::aod::McParticles const& mcParticles) { if (bcs.size() == 0) { return; } auto bc = bcs.begin(); initCCDB(bc); - electronModule.processWithTTCA(bcs, collisions, tracks, v0s, cascades, trackIndices, mcParticles, products, mRegistry, cache, perCol_track, trackIndicesPerCollision, perCol_v0, perCol_casc); + electronModule.processWithTTCA(bcs, collisions, tracks, /*v0s, cascades,*/ trackIndices, mcParticles, products, mRegistry, cache, perCol_track, trackIndicesPerCollision /*, perCol_v0, perCol_casc*/); } PROCESS_SWITCH(skimmerPrimaryElectronSV, processMC_TTCA, "process reconstructed info only", false); // with TTCA in MC }; diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx index 674902c2746..e1dde9ce73f 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx @@ -43,6 +43,7 @@ #include #include +#include #include #include #include @@ -105,8 +106,9 @@ struct skimmerPrimaryMuon { Configurable minNmuon{"minNmuon", 0, "min number of muon candidates per collision"}; Configurable maxDEta{"maxDEta", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; Configurable maxDPhi{"maxDPhi", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; - Configurable cfgApplyPreselectionInBestMatch{"cfgApplyPreselectionInBestMatch", false, "flag to apply preselection in find best match function"}; - Configurable cfgRequireSameSign{"cfgRequireSameSign", false, "flag to require same sign between MFT and MCH-MID"}; + // Configurable cfgApplyPreselectionInBestMatch{"cfgApplyPreselectionInBestMatch", false, "flag to apply preselection in find best match function"}; + Configurable cfgKeepOnlySAmuons{"cfgKeepOnlySAmuons", false, "flag to store only MCH-MID tracks"}; + Configurable cfgKeepOnlyGLmuons{"cfgKeepOnlyGLmuons", false, "flag to store only MFT-MCH-MID tracks"}; // for z shift for propagation Configurable cfgApplyZShiftFromCCDB{"cfgApplyZShiftFromCCDB", false, "flag to apply z shift"}; @@ -124,6 +126,10 @@ struct skimmerPrimaryMuon { void init(InitContext&) { + if (cfgKeepOnlySAmuons && cfgKeepOnlyGLmuons) { + LOGF(fatal, "cfgKeepOnlySAmuons and cfgKeepOnlyGLmuons cannot be true simultaneously. Please disable both or choose one."); + } + ccdb->setURL(ccdburl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); @@ -344,10 +350,6 @@ struct skimmerPrimaryMuon { return false; } - if (cfgRequireSameSign && (mfttrack.sign() != mchtrack.sign())) { - return false; - } - xMFT = mfttrack.x(); yMFT = mfttrack.y(); @@ -478,7 +480,7 @@ struct skimmerPrimaryMuon { emprimarymuons(collision.globalIndex(), fwdtrack.globalIndex(), fwdtrack.matchMFTTrackId(), fwdtrack.matchMCHTrackId(), fwdtrack.trackType(), pt, eta, phi, fwdtrack.sign(), dcaX, dcaY, cXX, cYY, cXY, ptMatchedMCHMID, etaMatchedMCHMID, phiMatchedMCHMID, // etaMatchedMCHMIDatMP, phiMatchedMCHMIDatMP, etaMatchedMFTatMP, phiMatchedMFTatMP, - fwdtrack.nClusters(), pDCA, rAtAbsorberEnd, fwdtrack.chi2(), fwdtrack.chi2MatchMCHMID(), fwdtrack.chi2MatchMCHMFT(), + fwdtrack.nClusters(), pDCA, rAtAbsorberEnd, fwdtrack.chi2(), fwdtrack.chi2MatchMCHMID(), fwdtrack.chi2MatchMCHMFT(), map_diff_chi2MatchMCHMFT[fwdtrack.globalIndex()], fwdtrack.mchBitMap(), fwdtrack.midBitMap(), fwdtrack.midBoards(), mftClusterSizesAndTrackFlags, chi2mft, isAssociatedToMPC, isAmbiguous); const auto& fwdcov = propmuonAtPV.getCovariances(); // covatiance matrix at PV @@ -563,10 +565,11 @@ struct skimmerPrimaryMuon { } std::unordered_map map_mfttrackcovs; - std::vector> vec_min_chi2MatchMCHMFT; // std::pair -> chi2MatchMCHMFT; + std::vector> vec_min_chi2MatchMCHMFT; + std::unordered_map map_diff_chi2MatchMCHMFT; // map fwdtrack.globalIndex -> diff chi2 template - void findBestMatchPerMCHMID(TCollision const& collision, TFwdTrack const& fwdtrack, TFwdTracks const& fwdtracks, TMFTTracks const&) + void findBestMatchPerMCHMID(TCollision const&, TFwdTrack const& fwdtrack, TFwdTracks const& fwdtracks, TMFTTracks const&) { if (fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { return; @@ -581,73 +584,89 @@ struct skimmerPrimaryMuon { // LOGF(info, "stanadalone: muon.globalIndex() = %d, muon.chi2MatchMCHMFT() = %f", muon.globalIndex(), muon.chi2MatchMCHMFT()); // LOGF(info, "muons_per_MCHMID.size() = %d", muons_per_MCHMID.size()); - o2::dataformats::GlobalFwdTrack propmuonAtPV_Matched = propagateMuon(fwdtrack, fwdtrack, collision, propagationPoint::kToVertex, matchingZ, mBz, mZShift); - float etaMatchedMCHMID = propmuonAtPV_Matched.getEta(); - float phiMatchedMCHMID = propmuonAtPV_Matched.getPhi(); - o2::math_utils::bringTo02Pi(phiMatchedMCHMID); + // o2::dataformats::GlobalFwdTrack propmuonAtPV_Matched = propagateMuon(fwdtrack, fwdtrack, collision, propagationPoint::kToVertex, matchingZ, mBz, mZShift); + // float etaMatchedMCHMID = propmuonAtPV_Matched.getEta(); + // float phiMatchedMCHMID = propmuonAtPV_Matched.getPhi(); + // o2::math_utils::bringTo02Pi(phiMatchedMCHMID); - o2::dataformats::GlobalFwdTrack propmuonAtDCA_Matched = propagateMuon(fwdtrack, fwdtrack, collision, propagationPoint::kToDCA, matchingZ, mBz, mZShift); - float dcaX_Matched = propmuonAtDCA_Matched.getX() - collision.posX(); - float dcaY_Matched = propmuonAtDCA_Matched.getY() - collision.posY(); - float dcaXY_Matched = std::sqrt(dcaX_Matched * dcaX_Matched + dcaY_Matched * dcaY_Matched); - float pDCA = fwdtrack.p() * dcaXY_Matched; + // o2::dataformats::GlobalFwdTrack propmuonAtDCA_Matched = propagateMuon(fwdtrack, fwdtrack, collision, propagationPoint::kToDCA, matchingZ, mBz, mZShift); + // float dcaX_Matched = propmuonAtDCA_Matched.getX() - collision.posX(); + // float dcaY_Matched = propmuonAtDCA_Matched.getY() - collision.posY(); + // float dcaXY_Matched = std::sqrt(dcaX_Matched * dcaX_Matched + dcaY_Matched * dcaY_Matched); + // float pDCA = fwdtrack.p() * dcaXY_Matched; float min_chi2MatchMCHMFT = 1e+10; - std::tuple tupleIds_at_min_chi2mftmch; + std::tuple tupleId_at_min_chi2mftmch; + std::vector vec_chi2tmp; + vec_chi2tmp.reserve(muons_per_MCHMID.size()); + for (const auto& muon_tmp : muons_per_MCHMID) { if (muon_tmp.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) { auto tupleId = std::make_tuple(muon_tmp.globalIndex(), muon_tmp.matchMCHTrackId(), muon_tmp.matchMFTTrackId()); - auto mchtrack = muon_tmp.template matchMCHTrack_as(); // MCH-MID - auto mfttrack = muon_tmp.template matchMFTTrack_as(); // MFTsa + // auto mchtrack = muon_tmp.template matchMCHTrack_as(); // MCH-MID + // auto mfttrack = muon_tmp.template matchMFTTrack_as(); // MFTsa - if (muon_tmp.chi2() < 0.f || muon_tmp.chi2MatchMCHMFT() < 0.f || muon_tmp.chi2MatchMCHMID() < 0.f || mfttrack.chi2() < 0.f) { // reject negative chi2, i.e. wrong. - // LOGF(info, "reject: muon_tmp.globalIndex() = %d, muon_tmp.chi2MatchMCHMFT() = %f, muon_tmp.chi2MatchMCHMID() = %f, muon_tmp.chi2() = %f, mfttrack.chi2() = %f", muon_tmp.globalIndex(), muon_tmp.chi2MatchMCHMFT(), muon_tmp.chi2MatchMCHMID(), muon_tmp.chi2(), mfttrack.chi2()); + if (muon_tmp.chi2MatchMCHMFT() < 0.f) { // reject negative chi2, i.e. wrong. continue; } - o2::dataformats::GlobalFwdTrack propmuonAtPV = propagateMuon(muon_tmp, muon_tmp, collision, propagationPoint::kToVertex, matchingZ, mBz, mZShift); - float pt = propmuonAtPV.getPt(); - float eta = propmuonAtPV.getEta(); - float phi = propmuonAtPV.getPhi(); - o2::math_utils::bringTo02Pi(phi); - - if (refitGlobalMuon) { - pt = propmuonAtPV_Matched.getP() * std::sin(2.f * std::atan(std::exp(-eta))); - } + // if (muon_tmp.chi2() < 0.f || muon_tmp.chi2MatchMCHMFT() < 0.f || muon_tmp.chi2MatchMCHMID() < 0.f || mfttrack.chi2() < 0.f) { // reject negative chi2, i.e. wrong. + // continue; + // } - float deta = etaMatchedMCHMID - eta; - float dphi = phiMatchedMCHMID - phi; - o2::math_utils::bringToPMPi(dphi); - int ndf = 2 * (mchtrack.nClusters() + mfttrack.nClusters()) - 5; + // o2::dataformats::GlobalFwdTrack propmuonAtPV = propagateMuon(muon_tmp, muon_tmp, collision, propagationPoint::kToVertex, matchingZ, mBz, mZShift); + // float pt = propmuonAtPV.getPt(); + // float eta = propmuonAtPV.getEta(); + // float phi = propmuonAtPV.getPhi(); + // o2::math_utils::bringTo02Pi(phi); - float dcaX = propmuonAtPV.getX() - collision.posX(); - float dcaY = propmuonAtPV.getY() - collision.posY(); - float dcaXY = std::sqrt(dcaX * dcaX + dcaY * dcaY); + // if (refitGlobalMuon) { + // pt = propmuonAtPV_Matched.getP() * std::sin(2.f * std::atan(std::exp(-eta))); + // } - if (cfgApplyPreselectionInBestMatch) { - if (!isSelected(pt, eta, muon_tmp.rAtAbsorberEnd(), pDCA, muon_tmp.chi2() / ndf, muon_tmp.trackType(), dcaXY)) { - continue; - } - if (std::sqrt(std::pow(deta / maxDEta, 2) + std::pow(dphi / maxDPhi, 2)) > 1.f) { - continue; - } - if (muon_tmp.chi2MatchMCHMFT() > maxMatchingChi2MCHMFT) { - continue; - } - if (cfgRequireSameSign && (mfttrack.sign() != mchtrack.sign())) { - continue; - } - } + // float deta = etaMatchedMCHMID - eta; + // float dphi = phiMatchedMCHMID - phi; + // o2::math_utils::bringToPMPi(dphi); + // int ndf = 2 * (mchtrack.nClusters() + mfttrack.nClusters()) - 5; + + // float dcaX = propmuonAtPV.getX() - collision.posX(); + // float dcaY = propmuonAtPV.getY() - collision.posY(); + // float dcaXY = std::sqrt(dcaX * dcaX + dcaY * dcaY); + + // if (cfgApplyPreselectionInBestMatch) { + // if (!isSelected(pt, eta, muon_tmp.rAtAbsorberEnd(), pDCA, muon_tmp.chi2() / ndf, muon_tmp.trackType(), dcaXY)) { + // continue; + // } + // if (std::sqrt(std::pow(deta / maxDEta, 2) + std::pow(dphi / maxDPhi, 2)) > 1.f) { + // continue; + // } + // if (muon_tmp.chi2MatchMCHMFT() > maxMatchingChi2MCHMFT) { + // continue; + // } + // } + vec_chi2tmp.emplace_back(muon_tmp.chi2MatchMCHMFT()); if (0.f < muon_tmp.chi2MatchMCHMFT() && muon_tmp.chi2MatchMCHMFT() < min_chi2MatchMCHMFT) { min_chi2MatchMCHMFT = muon_tmp.chi2MatchMCHMFT(); - tupleIds_at_min_chi2mftmch = tupleId; + tupleId_at_min_chi2mftmch = tupleId; } } } - vec_min_chi2MatchMCHMFT.emplace_back(tupleIds_at_min_chi2mftmch); + vec_min_chi2MatchMCHMFT.emplace_back(tupleId_at_min_chi2mftmch); + + float diff_chi2 = 1e+10; + std::nth_element(vec_chi2tmp.begin(), vec_chi2tmp.begin() + 1, vec_chi2tmp.end()); // sort only 0, 1. + if (vec_chi2tmp.size() >= 2) { + diff_chi2 = vec_chi2tmp[1] - vec_chi2tmp[0]; + } else { + diff_chi2 = 1e+10; + } + map_diff_chi2MatchMCHMFT[std::get<0>(tupleId_at_min_chi2mftmch)] = diff_chi2; + + vec_chi2tmp.clear(); + vec_chi2tmp.shrink_to_fit(); - // LOGF(info, "min: muon_tmp.globalIndex() = %d, muon_tmp.matchMCHTrackId() = %d, muon_tmp.matchMFTTrackId() = %d, muon_tmp.chi2MatchMCHMFT() = %f", std::get<0>(tupleIds_at_min), std::get<1>(tupleIds_at_min), std::get<2>(tupleIds_at_min), min_chi2MatchMCHMFT); + // LOGF(info, "min: muon_tmp.globalIndex() = %d, muon_tmp.matchMCHTrackId() = %d, muon_tmp.matchMFTTrackId() = %d, muon_tmp.chi2MatchMCHMFT() = %f", std::get<0>(tupleId_at_min), std::get<1>(tupleId_at_min), std::get<2>(tupleId_at_min), min_chi2MatchMCHMFT); } SliceCache cache; @@ -685,9 +704,16 @@ struct skimmerPrimaryMuon { continue; } - // if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { - // continue; - // } + if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + continue; + } + + if (cfgKeepOnlyGLmuons && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) { + continue; + } + if (cfgKeepOnlySAmuons && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { + continue; + } if (!fillFwdTrackTable(collision, fwdtrack, nullptr, false)) { continue; @@ -731,6 +757,7 @@ struct skimmerPrimaryMuon { map_mfttrackcovs.clear(); vec_min_chi2MatchMCHMFT.clear(); vec_min_chi2MatchMCHMFT.shrink_to_fit(); + map_diff_chi2MatchMCHMFT.clear(); } PROCESS_SWITCH(skimmerPrimaryMuon, processRec_SA, "process reconstructed info", false); @@ -771,9 +798,16 @@ struct skimmerPrimaryMuon { continue; } - // if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { - // continue; - // } + if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + continue; + } + + if (cfgKeepOnlyGLmuons && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) { + continue; + } + if (cfgKeepOnlySAmuons && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { + continue; + } if (!fillFwdTrackTable(collision, fwdtrack, nullptr, mapAmb[fwdtrack.globalIndex()])) { continue; @@ -818,6 +852,7 @@ struct skimmerPrimaryMuon { map_mfttrackcovs.clear(); vec_min_chi2MatchMCHMFT.clear(); vec_min_chi2MatchMCHMFT.shrink_to_fit(); + map_diff_chi2MatchMCHMFT.clear(); } PROCESS_SWITCH(skimmerPrimaryMuon, processRec_TTCA, "process reconstructed info", false); @@ -860,9 +895,9 @@ struct skimmerPrimaryMuon { // continue; // } - // // if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { - // // continue; - // // } + // if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + // continue; + // } // if (!fillFwdTrackTable(collision, fwdtrack, mftCovs, mapAmb[fwdtrack.globalIndex()])) { // continue; @@ -907,6 +942,7 @@ struct skimmerPrimaryMuon { // map_mfttrackcovs.clear(); // vec_min_chi2MatchMCHMFT.clear(); // vec_min_chi2MatchMCHMFT.shrink_to_fit(); + // map_diff_chi2MatchMCHMFT.clear(); // } // PROCESS_SWITCH(skimmerPrimaryMuon, processRec_TTCA_withMFTCov, "process reconstructed info", false); @@ -939,9 +975,16 @@ struct skimmerPrimaryMuon { if (fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { continue; } - // if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { - // continue; - // } + if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + continue; + } + + if (cfgKeepOnlyGLmuons && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) { + continue; + } + if (cfgKeepOnlySAmuons && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { + continue; + } if (!fillFwdTrackTable(collision, fwdtrack, nullptr, false)) { continue; @@ -985,6 +1028,7 @@ struct skimmerPrimaryMuon { map_mfttrackcovs.clear(); vec_min_chi2MatchMCHMFT.clear(); vec_min_chi2MatchMCHMFT.shrink_to_fit(); + map_diff_chi2MatchMCHMFT.clear(); } PROCESS_SWITCH(skimmerPrimaryMuon, processRec_SA_SWT, "process reconstructed info only with standalone", false); @@ -1024,9 +1068,16 @@ struct skimmerPrimaryMuon { if (fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { continue; } - // if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { - // continue; - // } + if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + continue; + } + + if (cfgKeepOnlyGLmuons && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) { + continue; + } + if (cfgKeepOnlySAmuons && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { + continue; + } if (!fillFwdTrackTable(collision, fwdtrack, nullptr, mapAmb[fwdtrack.globalIndex()])) { continue; @@ -1071,6 +1122,7 @@ struct skimmerPrimaryMuon { map_mfttrackcovs.clear(); vec_min_chi2MatchMCHMFT.clear(); vec_min_chi2MatchMCHMFT.shrink_to_fit(); + map_diff_chi2MatchMCHMFT.clear(); } PROCESS_SWITCH(skimmerPrimaryMuon, processRec_TTCA_SWT, "process reconstructed info", false); @@ -1113,9 +1165,9 @@ struct skimmerPrimaryMuon { // if (fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { // continue; // } - // // if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { - // // continue; - // // } + // if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + // continue; + // } // if (!fillFwdTrackTable(collision, fwdtrack, mftCovs, mapAmb[fwdtrack.globalIndex()])) { // continue; @@ -1160,6 +1212,7 @@ struct skimmerPrimaryMuon { // map_mfttrackcovs.clear(); // vec_min_chi2MatchMCHMFT.clear(); // vec_min_chi2MatchMCHMFT.shrink_to_fit(); + // map_diff_chi2MatchMCHMFT.clear(); // } // PROCESS_SWITCH(skimmerPrimaryMuon, processRec_TTCA_SWT_withMFTCov, "process reconstructed info", false); @@ -1193,9 +1246,16 @@ struct skimmerPrimaryMuon { if (fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { continue; } - // if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { - // continue; - // } + if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + continue; + } + + if (cfgKeepOnlyGLmuons && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) { + continue; + } + if (cfgKeepOnlySAmuons && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { + continue; + } if (!fillFwdTrackTable(collision, fwdtrack, nullptr, false)) { continue; @@ -1239,6 +1299,7 @@ struct skimmerPrimaryMuon { map_mfttrackcovs.clear(); vec_min_chi2MatchMCHMFT.clear(); vec_min_chi2MatchMCHMFT.shrink_to_fit(); + map_diff_chi2MatchMCHMFT.clear(); } PROCESS_SWITCH(skimmerPrimaryMuon, processMC_SA, "process reconstructed and MC info", false); @@ -1281,9 +1342,16 @@ struct skimmerPrimaryMuon { if (fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { continue; } - // if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { - // continue; - // } + if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + continue; + } + + if (cfgKeepOnlyGLmuons && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) { + continue; + } + if (cfgKeepOnlySAmuons && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { + continue; + } if (!fillFwdTrackTable(collision, fwdtrack, nullptr, mapAmb[fwdtrack.globalIndex()])) { continue; @@ -1328,6 +1396,7 @@ struct skimmerPrimaryMuon { map_mfttrackcovs.clear(); vec_min_chi2MatchMCHMFT.clear(); vec_min_chi2MatchMCHMFT.shrink_to_fit(); + map_diff_chi2MatchMCHMFT.clear(); } PROCESS_SWITCH(skimmerPrimaryMuon, processMC_TTCA, "process reconstructed and MC info", false); @@ -1373,9 +1442,9 @@ struct skimmerPrimaryMuon { // if (fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { // continue; // } - // // if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { - // // continue; - // // } + // if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + // continue; + // } // if (!fillFwdTrackTable(collision, fwdtrack, mftCovs, mapAmb[fwdtrack.globalIndex()])) { // continue; @@ -1420,6 +1489,7 @@ struct skimmerPrimaryMuon { // map_mfttrackcovs.clear(); // vec_min_chi2MatchMCHMFT.clear(); // vec_min_chi2MatchMCHMFT.shrink_to_fit(); + // map_diff_chi2MatchMCHMFT.clear(); // } // PROCESS_SWITCH(skimmerPrimaryMuon, processMC_TTCA_withMFTCov, "process reconstructed and MC with MFTCov info", false); diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuonQC.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuonQC.cxx index d5f410eafaa..4086fb20e78 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuonQC.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuonQC.cxx @@ -475,7 +475,7 @@ struct skimmerPrimaryMuonQC { { emprimarymuons(collision.globalIndex(), fwdtrack.globalIndex(), fwdtrack.matchMFTTrackId(), fwdtrack.matchMCHTrackId(), fwdtrack.trackType(), muon.pt, muon.eta, muon.phi, fwdtrack.sign(), muon.dcaX, muon.dcaY, muon.cXX, muon.cYY, muon.cXY, muon.ptMatchedMCHMID, muon.etaMatchedMCHMID, muon.phiMatchedMCHMID, - fwdtrack.nClusters(), muon.pDCA, muon.rAtAbsorberEnd, fwdtrack.chi2(), fwdtrack.chi2MatchMCHMID(), fwdtrack.chi2MatchMCHMFT(), + fwdtrack.nClusters(), muon.pDCA, muon.rAtAbsorberEnd, fwdtrack.chi2(), fwdtrack.chi2MatchMCHMID(), fwdtrack.chi2MatchMCHMFT(), 9999.f, fwdtrack.mchBitMap(), fwdtrack.midBitMap(), fwdtrack.midBoards(), muon.mftClusterSizesAndTrackFlags, muon.chi2mft, true, false); // if (fillQAHistograms) { diff --git a/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx b/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx index 3df99ab199d..fc0314ea15f 100644 --- a/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx +++ b/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -53,8 +54,6 @@ #include -#include - #include #include #include diff --git a/PWGEM/Dilepton/Tasks/CMakeLists.txt b/PWGEM/Dilepton/Tasks/CMakeLists.txt index 5a1547c8a65..cb6b75c685c 100644 --- a/PWGEM/Dilepton/Tasks/CMakeLists.txt +++ b/PWGEM/Dilepton/Tasks/CMakeLists.txt @@ -55,6 +55,11 @@ o2physics_add_dpl_workflow(table-reader-barrel PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase O2Physics::PWGDQCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(create-ttp + SOURCES createTTP.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(event-qc SOURCES eventQC.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::EventFilteringUtils @@ -95,9 +100,9 @@ o2physics_add_dpl_workflow(dielectron-sv PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2::DCAFitter O2Physics::AnalysisCore O2Physics::PWGEMDileptonCore O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(dielectron-sct - SOURCES dielectronSCT.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::PWGEMDileptonCore O2Physics::EventFilteringUtils +o2physics_add_dpl_workflow(dielectron-sv-mc + SOURCES dielectronSVMC.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2::DCAFitter O2Physics::AnalysisCore O2Physics::PWGEMDileptonCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(dimuon @@ -110,8 +115,8 @@ o2physics_add_dpl_workflow(dimuon-mc PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::PWGEMDileptonCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(prefilter-dielectron - SOURCES prefilterDielectron.cxx +o2physics_add_dpl_workflow(dimuon-v1 + SOURCES dimuonV1.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGEMDileptonCore COMPONENT_NAME Analysis) @@ -152,7 +157,7 @@ o2physics_add_dpl_workflow(mc-particle-predictions-otf o2physics_add_dpl_workflow(study-dcafitter SOURCES studyDCAFitter.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::DCAFitter O2Physics::AnalysisCore + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsVertexing O2::DCAFitter O2Physics::AnalysisCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(evaluate-acceptance @@ -160,11 +165,6 @@ o2physics_add_dpl_workflow(evaluate-acceptance PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(dilepton-polarization - SOURCES dileptonPolarization.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(check-mc-template SOURCES checkMCTemplate.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::GlobalTracking diff --git a/PWGEM/Dilepton/Tasks/checkMCPairTemplate.cxx b/PWGEM/Dilepton/Tasks/checkMCPairTemplate.cxx index c3821acbf85..0e2d7b2968d 100644 --- a/PWGEM/Dilepton/Tasks/checkMCPairTemplate.cxx +++ b/PWGEM/Dilepton/Tasks/checkMCPairTemplate.cxx @@ -17,6 +17,7 @@ #include "PWGEM/Dilepton/Core/DielectronCut.h" #include "PWGEM/Dilepton/Core/DimuonCut.h" #include "PWGEM/Dilepton/Core/EMEventCut.h" +#include "PWGEM/Dilepton/DataModel/EvSelFlags.h" #include "PWGEM/Dilepton/DataModel/dileptonTables.h" #include "PWGEM/Dilepton/Utils/EMTrackUtilities.h" #include "PWGEM/Dilepton/Utils/EventHistograms.h" diff --git a/PWGEM/Dilepton/Tasks/createTTP.cxx b/PWGEM/Dilepton/Tasks/createTTP.cxx new file mode 100644 index 00000000000..7bef5555eba --- /dev/null +++ b/PWGEM/Dilepton/Tasks/createTTP.cxx @@ -0,0 +1,858 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// ======================== +// +// This code creates parameters used in track tuner. +// Please write to: daiki.sekihata@cern.ch + +#include "PWGEM/Dilepton/Utils/MCUtilities.h" +#include "PWGEM/Dilepton/Utils/PairUtilities.h" + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/RCTSelectionFlags.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/Zorro.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace o2; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct createTTP { + // Configurables + Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + Configurable cfgEventGeneratorType{"cfgEventGeneratorType", -1, "if positive, select event generator type. i.e. gap or signal"}; + + ConfigurableAxis ConfPtBins{"ConfPtBins", {VARIABLE_WIDTH, 0.00, 0.10, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.5, 6.0, 7.5, 7.0, 7.5, 8.0, 9.0, 10.0, 15, 20}, "pT bins for output histograms"}; + Configurable cfgNbinsEta{"cfgNbinsEta", 20, "number of eta bins for output histograms"}; + Configurable cfgNbinsPhi{"cfgNbinsPhi", 36, "number of phi bins for output histograms"}; + ConfigurableAxis ConfDCABins{"ConfDCABins", {2000, -1000, +1000}, "DCA bins for output histograms"}; + ConfigurableAxis ConfDCASigmaBins{"ConfDCASigmaBins", {200, -10, +10}, "DCA in sigma bins for output histograms"}; + + o2::framework::ConfigurableAxis ConfMllBins{"ConfMllBins", {400, 0, 4}, "mll bins for output histograms"}; + o2::framework::ConfigurableAxis ConfPtllBins{"ConfPtllBins", {o2::framework::VARIABLE_WIDTH, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00, 6.00, 7.00, 8.00, 9.00, 10.00}, "pTll bins for output histograms"}; + + struct : ConfigurableGroup { + std::string prefix = "eventCut"; + Configurable cfgZvtxMin{"cfgZvtxMin", -10, "min. Zvtx"}; + Configurable cfgZvtxMax{"cfgZvtxMax", +10, "max. Zvtx"}; + Configurable cfgRequireFT0AND{"cfgRequireFT0AND", true, "require FT0AND in event cut"}; + Configurable cfgRequireNoTFB{"cfgRequireNoTFB", true, "require No time frame border in event cut"}; + Configurable cfgRequireNoITSROFB{"cfgRequireNoITSROFB", false, "require no ITS readout frame border in event cut"}; + Configurable cfgRequireVertexITSTPC{"cfgRequireVertexITSTPC", false, "require Vertex ITSTPC in event cut"}; // ITS-TPC matched track contributes PV. + Configurable cfgRequireVertexTOFmatched{"cfgRequireVertexTOFmatched", false, "require Vertex TOFmatched in event cut"}; // ITS-TPC-TOF matched track contributes PV. + Configurable cfgRequireNoSameBunchPileup{"cfgRequireNoSameBunchPileup", false, "require no same bunch pileup in event cut"}; + Configurable cfgRequireGoodZvtxFT0vsPV{"cfgRequireGoodZvtxFT0vsPV", false, "require good Zvtx between FT0 vs. PV in event cut"}; + Configurable cfgTrackOccupancyMin{"cfgTrackOccupancyMin", -2, "min. track occupancy"}; + Configurable cfgTrackOccupancyMax{"cfgTrackOccupancyMax", 1000000000, "max. track occupancy"}; + Configurable cfgFT0COccupancyMin{"cfgFT0COccupancyMin", -2, "min. FT0C occupancy"}; + Configurable cfgFT0COccupancyMax{"cfgFT0COccupancyMax", 1000000000, "max. FT0C occupancy"}; + + Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; + Configurable cfgCentMin{"cfgCentMin", -1.f, "min. centrality"}; + Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; + Configurable cfgNumContribMin{"cfgNumContribMin", 0, "min. numContrib"}; + Configurable cfgNumContribMax{"cfgNumContribMax", 65000, "max. numContrib"}; + + // for RCT + Configurable cfgRequireGoodRCT{"cfgRequireGoodRCT", true, "require good detector flag in run condtion table"}; + Configurable cfgRCTLabel{"cfgRCTLabel", "CBT_hadronPID", "select 1 [CBT, CBT_hadronPID, CBT_muon_glo] see O2Physics/Common/CCDB/RCTSelectionFlags.h"}; + Configurable cfgCheckZDC{"cfgCheckZDC", false, "set ZDC flag for PbPb"}; + Configurable cfgTreatLimitedAcceptanceAsBad{"cfgTreatLimitedAcceptanceAsBad", false, "reject all events where the detectors relevant for the specified Runlist are flagged as LimitedAcceptance"}; + } eventCut; + + struct : ConfigurableGroup { + std::string prefix = "tagCut"; + Configurable min_pt_track{"min_pt_track", 0.4, "min pT for single track"}; + Configurable max_pt_track{"max_pt_track", 1e+10, "max pT for single track"}; + Configurable min_eta_track{"min_eta_track", -0.8, "min eta for single track"}; + Configurable max_eta_track{"max_eta_track", +0.8, "max eta for single track"}; + Configurable min_ncluster_tpc{"min_ncluster_tpc", 0, "min ncluster tpc"}; + Configurable min_ncrossedrows_tpc{"min_ncrossedrows_tpc", 120, "min. crossed rows"}; + Configurable min_ncluster_its{"min_ncluster_its", 5, "min ncluster its"}; + Configurable min_ncluster_itsib{"min_ncluster_itsib", 3, "min ncluster itsib"}; + Configurable min_tpc_cr_findable_ratio{"min_tpc_cr_findable_ratio", 0.8, "min. TPC Ncr/Nf ratio"}; + Configurable max_frac_shared_clusters_tpc{"max_frac_shared_clusters_tpc", 0.7, "max fraction of shared clusters in TPC"}; + Configurable max_chi2tpc{"max_chi2tpc", 2.5, "max. chi2/NclsTPC"}; + Configurable max_chi2its{"max_chi2its", 36.0, "max. chi2/NclsITS"}; + Configurable max_dcaxy{"max_dcaxy", 0.2, "max DCAxy in cm"}; + Configurable max_dcaz{"max_dcaz", 0.2, "max DCAz in cm"}; + Configurable max_dca_in_sigma{"max_dca_in_sigma", 1e+10, "max dca in sigma for a single track"}; + + Configurable min_TPCNsigmaEl{"min_TPCNsigmaEl", -2, "min. TPC n sigma for electron inclusion"}; + Configurable max_TPCNsigmaEl{"max_TPCNsigmaEl", +3, "max. TPC n sigma for electron inclusion"}; + Configurable min_TPCNsigmaPi{"min_TPCNsigmaPi", -1e+10, "min n sigma pi in TPC for exclusion"}; + Configurable max_TPCNsigmaPi{"max_TPCNsigmaPi", +3, "max n sigma pi in TPC for exclusion"}; + Configurable min_TPCNsigmaKa{"min_TPCNsigmaKa", -3, "min n sigma ka in TPC for exclusion"}; + Configurable max_TPCNsigmaKa{"max_TPCNsigmaKa", +3, "max n sigma ka in TPC for exclusion"}; + Configurable min_TPCNsigmaPr{"min_TPCNsigmaPr", -3, "min n sigma pr in TPC for exclusion"}; + Configurable max_TPCNsigmaPr{"max_TPCNsigmaPr", +3, "max n sigma pr in TPC for exclusion"}; + Configurable min_TOFNsigmaEl{"min_TOFNsigmaEl", -3, "min. TOF n sigma for electron inclusion"}; + Configurable max_TOFNsigmaEl{"max_TOFNsigmaEl", +3, "max. TOF n sigma for electron inclusion"}; + } tagCut; + + struct : ConfigurableGroup { + std::string prefix = "probeCut"; + Configurable min_pt_track{"min_pt_track", 0.05, "min pT for single track"}; + Configurable max_pt_track{"max_pt_track", 1e+10, "max pT for single track"}; + Configurable min_eta_track{"min_eta_track", -0.8, "min eta for single track"}; + Configurable max_eta_track{"max_eta_track", +0.8, "max eta for single track"}; + Configurable min_ncrossedrows_tpc{"min_ncrossedrows_tpc", 80, "min ncrossed rows"}; + Configurable min_ncluster_tpc{"min_ncluster_tpc", 0, "min ncluster tpc"}; + Configurable min_ncluster_its{"min_ncluster_its", 5, "min ncluster its"}; + Configurable min_ncluster_itsib{"min_ncluster_itsib", 1, "min ncluster itsib"}; + Configurable min_cr2findable_ratio_tpc{"min_cr2findable_ratio_tpc", 0.8, "min. TPC Ncr/Nf ratio"}; + Configurable max_frac_shared_clusters_tpc{"max_frac_shared_clusters_tpc", 0.7f, "max fraction of shared clusters in TPC"}; + Configurable max_chi2tpc{"max_chi2tpc", 4.0, "max chi2/NclsTPC"}; + Configurable max_chi2its{"max_chi2its", 36.0, "max chi2/NclsITS"}; + Configurable max_dcaxy{"max_dcaxy", 1, "max dca XY for single track in cm"}; + Configurable max_dcaz{"max_dcaz", 1, "max dca Z for single track in cm"}; + + Configurable min_TPCNsigmaEl{"min_TPCNsigmaEl", -2, "min n sigma e in TPC"}; + Configurable max_TPCNsigmaEl{"max_TPCNsigmaEl", +3, "max n sigma e in TPC"}; + Configurable min_TOFNsigmaEl{"min_TOFNsigmaEl", -3, "min n sigma e in TOF"}; + Configurable max_TOFNsigmaEl{"max_TOFNsigmaEl", +3, "max n sigma e in TOF"}; + } probeCut; + + struct : ConfigurableGroup { + std::string prefix = "pairCut"; + Configurable minMee{"minMee", 0.00, "min mee of pi0 -> ee"}; + Configurable maxMee{"maxMee", 0.01, "max mee of pi0 -> ee"}; + Configurable minPhiV{"minPhiV", 0.f, "min phiv of pi0 -> ee"}; + Configurable maxPhiV{"maxPhiV", M_PI / 2, "max phiv of pi0 -> ee"}; + } pairCut; + + struct : ConfigurableGroup { + std::string prefix = "pfGroup"; + Configurable maxMee{"maxMee", 0.06, "max mee of pi0 -> ee for prefilter to improve S/B for peak extraction of VMs"}; + } pfGroup; + + o2::aod::rctsel::RCTFlagsChecker rctChecker; + + int mRunNumber{0}; + float d_bz{0}; + Service ccdb; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + o2::dataformats::VertexBase mVtx; + o2::base::MatLayerCylSet* lut = nullptr; + + HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; + + void init(InitContext&) + { + mRunNumber = 0; + d_bz = 0; + ccdb->setURL(ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + rctChecker.init(eventCut.cfgRCTLabel.value, eventCut.cfgCheckZDC.value, eventCut.cfgTreatLimitedAcceptanceAsBad.value); + + addhistograms(); + } + + ~createTTP() {} + + template + void initCCDB(TBC const& bc) + { + if (mRunNumber == bc.runNumber()) { + return; + } + + // load matLUT for this timestamp + if (!lut) { + LOG(info) << "Loading material look-up table for timestamp: " << bc.timestamp(); + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->getForTimeStamp(lutPath, bc.timestamp())); + } else { + LOG(info) << "Material look-up table already in place. Not reloading."; + } + + auto run3grp_timestamp = bc.timestamp(); + o2::parameters::GRPObject* grpo = 0x0; + o2::parameters::GRPMagField* grpmag = 0x0; + if (grpo) { + o2::base::Propagator::initFieldFromGRP(grpo); + o2::base::Propagator::Instance()->setMatLUT(lut); + // Fetch magnetic field from ccdb for current collision + d_bz = grpo->getNominalL3Field(); + LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; + } else { + grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); + if (!grpmag) { + LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; + } + o2::base::Propagator::initFieldFromGRP(grpmag); + o2::base::Propagator::Instance()->setMatLUT(lut); + // Fetch magnetic field from ccdb for current collision + d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); + LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; + } + + mRunNumber = bc.runNumber(); + } + + void addhistograms() + { + // event info + auto hCollisionCounter = fRegistry.add("Event/hCollisionCounter", "collision counter;;Number of events", kTH1D, {{2, -0.5, 1.5}}, false); + hCollisionCounter->GetXaxis()->SetBinLabel(1, "all"); + hCollisionCounter->GetXaxis()->SetBinLabel(2, "accepted"); + + const AxisSpec axis_pt{ConfPtBins, "p_{T} (GeV/c)"}; + const AxisSpec axis_eta{cfgNbinsEta, -1, +1, "#eta"}; + const AxisSpec axis_phi{cfgNbinsPhi, 0.0, 2 * M_PI, "#varphi (rad.)"}; + const AxisSpec axis_sign{3, -1.5, +1.5, "sign"}; + const AxisSpec axis_mass{ConfMllBins, "m_{ee} (GeV/c^{2})"}; + const AxisSpec axis_ptee{ConfPtllBins, "p_{T,ee} (GeV/c)"}; + + const AxisSpec axis_mean_dcaXY{ConfDCABins, "DCA_{xy} (#mum)"}; + const AxisSpec axis_mean_dcaZ{ConfDCABins, "DCA_{z} (#mum)"}; + const AxisSpec axis_pull_dcaXY{ConfDCASigmaBins, "DCA_{xy}/#sigma_{xy}^{DCA}"}; + const AxisSpec axis_pull_dcaZ{ConfDCASigmaBins, "DCA_{z}/#sigma_{z}^{DCA}"}; + + fRegistry.add("Track/hs", "probe electron", kTHnSparseD, {axis_pt, axis_eta, axis_phi, axis_sign, axis_mean_dcaXY, axis_mean_dcaZ, axis_pull_dcaXY, axis_pull_dcaZ}, false); + fRegistry.add("Track/hTPCNsigmaEl", "TPC n sigma el;p_{in} (GeV/c);n #sigma_{e}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5.f, +5.f}}, false); + fRegistry.add("Pair/uls/hMvsPt", "dielectron", kTH2D, {axis_mass, axis_ptee}, false); + fRegistry.addClone("Pair/uls/", "Pair/lspp/"); + fRegistry.addClone("Pair/uls/", "Pair/lsmm/"); + fRegistry.add("TAP/hMvsPhiV", "m_{ee} vs. #varphi_{V} ULS;#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", kTH2F, {{90, 0.f, M_PI}, {100, 0, 0.1}}); + + if (doprocessMC) { + fRegistry.add("Pair/hMvsPt_omega", "#omega->ee", kTH2D, {axis_mass, axis_ptee}, false); + fRegistry.add("Pair/hMvsPt_phi", "#phi->ee", kTH2D, {axis_mass, axis_ptee}, false); + fRegistry.add("Pair/hMvsPt_jpsi", "J/#psi->ee", kTH2D, {axis_mass, axis_ptee}, false); + } + } + + template + bool isTag(TTrack const& track, const float pt, const float eta, const float dcaXY, const float dcaZ, const float cYY, const float cZZ, const float cZY) + { + if (!track.hasITS() || !track.hasTPC()) { + return false; + } + + if (pt < tagCut.min_pt_track || tagCut.max_pt_track < pt) { + return false; + } + + if (eta < tagCut.min_eta_track || tagCut.max_eta_track < eta) { + return false; + } + + if (std::fabs(dcaXY) > tagCut.max_dcaxy || std::fabs(dcaZ) > tagCut.max_dcaz) { + return false; + } + + if (dca3DinSigmaOTF(dcaXY, dcaZ, cYY, cZZ, cZY) > tagCut.max_dca_in_sigma) { + return false; + } + + if (track.itsChi2NCl() < 0.f || tagCut.max_chi2its < track.itsChi2NCl()) { + return false; + } + if (track.itsNCls() < tagCut.min_ncluster_its) { + return false; + } + if (track.itsNClsInnerBarrel() < tagCut.min_ncluster_itsib) { + return false; + } + + if (track.tpcChi2NCl() < 0.f || tagCut.max_chi2tpc < track.tpcChi2NCl()) { + return false; + } + + if (track.tpcNClsFound() < tagCut.min_ncluster_tpc) { + return false; + } + + if (track.tpcNClsCrossedRows() < tagCut.min_ncrossedrows_tpc) { + return false; + } + + if (track.tpcCrossedRowsOverFindableCls() < tagCut.min_tpc_cr_findable_ratio) { + return false; + } + + if (track.tpcFractionSharedCls() > tagCut.max_frac_shared_clusters_tpc) { + return false; + } + + return true; + } + + template + bool isProbe(TTrack const& track, const float pt, const float eta, const float dcaXY, const float dcaZ) + { + if (!track.hasITS() || !track.hasTPC()) { + return false; + } + + if (pt < probeCut.min_pt_track || probeCut.max_pt_track < pt) { + return false; + } + + if (eta < probeCut.min_eta_track || probeCut.max_eta_track < eta) { + return false; + } + + if (std::fabs(dcaXY) > probeCut.max_dcaxy) { + return false; + } + + if (std::fabs(dcaZ) > probeCut.max_dcaz) { + return false; + } + + if (track.itsChi2NCl() > probeCut.max_chi2its) { + return false; + } + + if (track.itsNCls() < probeCut.min_ncluster_its) { + return false; + } + + if (track.itsNClsInnerBarrel() < probeCut.min_ncluster_itsib) { + return false; + } + + if (track.tpcChi2NCl() > probeCut.max_chi2tpc) { + return false; + } + + if (track.tpcNClsFound() < probeCut.min_ncluster_tpc) { + return false; + } + + if (track.tpcNClsCrossedRows() < probeCut.min_ncrossedrows_tpc) { + return false; + } + + if (track.tpcCrossedRowsOverFindableCls() < probeCut.min_cr2findable_ratio_tpc) { + return false; + } + + if (track.tpcFractionSharedCls() > probeCut.max_frac_shared_clusters_tpc) { + return false; + } + + return true; + } + + template + bool isTagElectron(TTrack const& track) + { + bool is_OK_El_TPC = tagCut.min_TPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < tagCut.max_TPCNsigmaEl; + bool is_OK_El_TOFreq = tagCut.min_TOFNsigmaEl < track.tofNSigmaEl() && track.tofNSigmaEl() < tagCut.max_TOFNsigmaEl; + + bool is_OK_Pi_TPC = !(tagCut.min_TPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < tagCut.max_TPCNsigmaPi); + bool is_OK_Ka_TPC = !(tagCut.min_TPCNsigmaKa < track.tpcNSigmaKa() && track.tpcNSigmaKa() < tagCut.max_TPCNsigmaKa); + bool is_OK_Pr_TPC = !(tagCut.min_TPCNsigmaPr < track.tpcNSigmaPr() && track.tpcNSigmaPr() < tagCut.max_TPCNsigmaPr); + bool is_OK_El_TOFif = track.hasTOF() ? tagCut.min_TOFNsigmaEl < track.tofNSigmaEl() && track.tofNSigmaEl() < tagCut.max_TOFNsigmaEl : true; + + bool isTOFreq = is_OK_El_TPC && is_OK_Pi_TPC && is_OK_El_TOFreq; + bool isTPC_had_rej = is_OK_El_TPC && is_OK_Pi_TPC && is_OK_Ka_TPC && is_OK_Pr_TPC && is_OK_El_TOFif; + + return isTOFreq || isTPC_had_rej; + } + + template + bool isProbeElectron(TTrack const& track) + { + bool is_El_TPC = probeCut.min_TPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < probeCut.max_TPCNsigmaEl; + bool is_El_TOF = track.hasTOF() ? probeCut.min_TOFNsigmaEl < track.tofNSigmaEl() && track.tofNSigmaEl() < probeCut.max_TOFNsigmaEl : true; + return is_El_TPC && is_El_TOF; + } + + template + bool isSelectedCollision(TCollision const& collision) + { + if (collision.posZ() < eventCut.cfgZvtxMin || eventCut.cfgZvtxMax < collision.posZ()) { + return false; + } + + if (eventCut.cfgRequireFT0AND && !collision.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { + return false; + } + + if (eventCut.cfgRequireNoTFB && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + return false; + } + + if (eventCut.cfgRequireNoITSROFB && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + return false; + } + + if (eventCut.cfgRequireVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + return false; + } + + if (eventCut.cfgRequireVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { + return false; + } + + if (eventCut.cfgRequireNoSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + return false; + } + + if (eventCut.cfgRequireGoodZvtxFT0vsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + + if (!(eventCut.cfgTrackOccupancyMin <= collision.trackOccupancyInTimeRange() && collision.trackOccupancyInTimeRange() < eventCut.cfgTrackOccupancyMax)) { + return false; + } + + if (!(eventCut.cfgFT0COccupancyMin <= collision.ft0cOccupancyInTimeRange() && collision.ft0cOccupancyInTimeRange() < eventCut.cfgFT0COccupancyMax)) { + return false; + } + + if (eventCut.cfgRequireGoodRCT && !rctChecker.checkTable(collision)) { + return false; + } + + return true; + } + + float dca3DinSigmaOTF(const float dcaXY, const float dcaZ, const float cYY, const float cZZ, const float cZY) + { + float det = cYY * cZZ - cZY * cZY; // determinant + if (det < 0) { + return 999.f; + } else { + return std::sqrt(std::fabs((dcaXY * dcaXY * cZZ + dcaZ * dcaZ * cYY - 2. * dcaXY * dcaZ * cZY) / det / 2.)); // dca 3d in sigma + } + } + + struct lepton { + float pt{0}; + float eta{0}; + float phi{0}; + int8_t sign{0}; + float tpcInnerParam{0}; + float tpcNSigmaEl{999}; + + float dcaXY{999}; + float dcaZ{999}; + float dcaXYinSigma{999}; + float dcaZinSigma{999}; + + bool passTrackTag{false}; + bool passTrackProbe{false}; + bool passPIDTag{false}; + bool passPIDProbe{false}; + int globalIndex{-1}; + int mcParticleId{-1}; + }; + + using MyBCs = soa::Join; + using MyCollisions = soa::Join; + using MyTracks = soa::Join; + + Filter collisionFilter_zvtx = eventCut.cfgZvtxMin < o2::aod::collision::posZ && o2::aod::collision::posZ < eventCut.cfgZvtxMax; + Filter collisionFilter_centrality = (eventCut.cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < eventCut.cfgCentMax) || (eventCut.cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < eventCut.cfgCentMax) || (eventCut.cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < eventCut.cfgCentMax); + Filter collisionFilter_numContrib = eventCut.cfgNumContribMin <= o2::aod::collision::numContrib && o2::aod::collision::numContrib < eventCut.cfgNumContribMax; + Filter collisionFilter_track_occupancy = eventCut.cfgTrackOccupancyMin <= o2::aod::evsel::trackOccupancyInTimeRange && o2::aod::evsel::trackOccupancyInTimeRange < eventCut.cfgTrackOccupancyMax; + Filter collisionFilter_ft0c_occupancy = eventCut.cfgFT0COccupancyMin <= o2::aod::evsel::ft0cOccupancyInTimeRange && o2::aod::evsel::ft0cOccupancyInTimeRange < eventCut.cfgFT0COccupancyMax; + + using FilteredMyCollisions = soa::Filtered; + using FilteredMyCollision = FilteredMyCollisions::iterator; + + Filter trackFilter_itstpc = ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC) == true; + Filter trackFilter_tpcpid = probeCut.min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < probeCut.max_TPCNsigmaEl; + using FilteredMyTracks = soa::Filtered; + + SliceCache cache; + Preslice perCol = o2::aod::track::collisionId; + // Partition posTracks = o2::aod::track::signed1Pt > 0.f; + // Partition negTracks = o2::aod::track::signed1Pt < 0.f; + + template + void runTAP(TBCs const&, TCollisions const& collisions, TTracks const& tracks) + { + for (const auto& collision : collisions) { + auto bc = collision.template bc_as(); + initCCDB(bc); + + float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; + if (centralities[eventCut.cfgCentEstimator] < eventCut.cfgCentMin || eventCut.cfgCentMax < centralities[eventCut.cfgCentEstimator]) { + continue; + } + + fRegistry.fill(HIST("Event/hCollisionCounter"), 0); + if (!isSelectedCollision(collision)) { + continue; + } + fRegistry.fill(HIST("Event/hCollisionCounter"), 1); + + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + + // auto posTracks_per_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + // auto negTracks_per_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + // // LOGF(info, "posTracks_per_coll.size() = %d, negTracks_per_coll.size() = %d", posTracks_per_coll.size(), negTracks_per_coll.size()); + // if (posTracks_per_coll.size() + negTracks_per_coll.size() < 2) { + // continue; + // } + + auto tracks_per_coll = tracks.sliceBy(perCol, collision.globalIndex()); + if (tracks_per_coll.size() < 2) { // at least 2 tracks are necessary to make a pair. + continue; + } + + o2::dataformats::DCA mDcaInfoCov; + std::vector posLeptons; + std::vector negLeptons; + posLeptons.reserve(tracks_per_coll.size()); + negLeptons.reserve(tracks_per_coll.size()); + + for (const auto& track : tracks_per_coll) { + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(o2::track::PID::Electron); + bool isPropOK = o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); + if (!isPropOK) { + continue; + } + + lepton tmp; + tmp.pt = trackParCov.getPt(); + tmp.eta = trackParCov.getEta(); + tmp.phi = RecoDecay::constrainAngle(trackParCov.getPhi(), 0, 1U); + tmp.sign = track.sign(); + tmp.tpcInnerParam = track.tpcInnerParam(); + tmp.tpcNSigmaEl = track.tpcNSigmaEl(); + tmp.dcaXY = mDcaInfoCov.getY() * 1e+4; // in um + tmp.dcaZ = mDcaInfoCov.getZ() * 1e+4; // in um + tmp.dcaXYinSigma = mDcaInfoCov.getY() / std::sqrt(trackParCov.getSigmaY2()); + tmp.dcaZinSigma = mDcaInfoCov.getZ() / std::sqrt(trackParCov.getSigmaZ2()); + tmp.passTrackTag = isTag(track, trackParCov.getPt(), trackParCov.getEta(), mDcaInfoCov.getY(), mDcaInfoCov.getZ(), trackParCov.getSigmaY2(), trackParCov.getSigmaZ2(), trackParCov.getSigmaZY()); + tmp.passTrackProbe = isProbe(track, trackParCov.getPt(), trackParCov.getEta(), mDcaInfoCov.getY(), mDcaInfoCov.getZ()); + tmp.passPIDTag = isTagElectron(track); + tmp.passPIDProbe = isProbeElectron(track); + tmp.globalIndex = track.globalIndex(); + tmp.mcParticleId = -1; + + if (tmp.passTrackTag || tmp.passTrackProbe) { + if (track.sign() > 0) { + posLeptons.emplace_back(tmp); + } else { + negLeptons.emplace_back(tmp); + } + } + } // end of track loop + + auto tagPositrons = std::views::filter(posLeptons, [](lepton t) { return t.passTrackTag == true && t.passPIDTag == true; }); + auto tagElectrons = std::views::filter(negLeptons, [](lepton t) { return t.passTrackTag == true && t.passPIDTag == true; }); + auto probePositrons = std::views::filter(posLeptons, [](lepton t) { return t.passTrackProbe == true && t.passPIDProbe == true; }); + auto probeElectrons = std::views::filter(negLeptons, [](lepton t) { return t.passTrackProbe == true && t.passPIDProbe == true; }); + + for (const auto& tag : tagPositrons) { + for (const auto& probe : probeElectrons) { + ROOT::Math::PtEtaPhiMVector v1(tag.pt, tag.eta, RecoDecay::constrainAngle(tag.phi, 0, 1U), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(probe.pt, probe.eta, RecoDecay::constrainAngle(probe.phi, 0, 1U), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + float mee = v12.M(); + float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(v1.Px(), v1.Py(), v1.Pz(), v2.Px(), v2.Py(), v2.Pz(), tag.sign, probe.sign, d_bz); + fRegistry.fill(HIST("TAP/hMvsPhiV"), phiv, mee); + + if ((pairCut.minMee < mee && mee < pairCut.maxMee) && (pairCut.minPhiV < phiv && phiv < pairCut.maxPhiV)) { + fRegistry.fill(HIST("Track/hs"), probe.pt, probe.eta, RecoDecay::constrainAngle(probe.phi, 0, 1U), probe.sign, probe.dcaXY, probe.dcaZ, probe.dcaXYinSigma, probe.dcaZinSigma); + fRegistry.fill(HIST("Track/hTPCNsigmaEl"), probe.tpcInnerParam, probe.tpcNSigmaEl); + } + } // end of electron loop + } // end of positron loop + + for (const auto& tag : tagElectrons) { + for (const auto& probe : probePositrons) { + ROOT::Math::PtEtaPhiMVector v1(tag.pt, tag.eta, RecoDecay::constrainAngle(tag.phi, 0, 1U), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(probe.pt, probe.eta, RecoDecay::constrainAngle(probe.phi, 0, 1U), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + float mee = v12.M(); + float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(v1.Px(), v1.Py(), v1.Pz(), v2.Px(), v2.Py(), v2.Pz(), tag.sign, probe.sign, d_bz); + fRegistry.fill(HIST("TAP/hMvsPhiV"), phiv, mee); + + if ((pairCut.minMee < mee && mee < pairCut.maxMee) && (pairCut.minPhiV < phiv && phiv < pairCut.maxPhiV)) { + fRegistry.fill(HIST("Track/hs"), probe.pt, probe.eta, RecoDecay::constrainAngle(probe.phi, 0, 1U), probe.sign, probe.dcaXY, probe.dcaZ, probe.dcaXYinSigma, probe.dcaZinSigma); + fRegistry.fill(HIST("Track/hTPCNsigmaEl"), probe.tpcInnerParam, probe.tpcNSigmaEl); + } + } // end of positron loop + } // end of electron loop + + auto probePositronsVM = std::views::filter(posLeptons, [](lepton t) { return t.passTrackProbe == true && t.passPIDTag == true; }); + auto probeElectronsVM = std::views::filter(negLeptons, [](lepton t) { return t.passTrackProbe == true && t.passPIDTag == true; }); + + // for VM peak analyses + std::vector trackIdsFromPi0; + trackIdsFromPi0.reserve(posLeptons.size() + negLeptons.size()); + + for (const auto& t1 : probePositronsVM) { + for (const auto& t2 : probeElectronsVM) { + ROOT::Math::PtEtaPhiMVector v1(t1.pt, t1.eta, t1.phi, o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(t2.pt, t2.eta, t2.phi, o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + if (v12.M() < pfGroup.maxMee) { + trackIdsFromPi0.emplace_back(t1.globalIndex); + trackIdsFromPi0.emplace_back(t2.globalIndex); + } + } // end of electron loop + } // end of positron loop + + for (const auto& t1 : probePositronsVM) { + for (const auto& t2 : probeElectronsVM) { + if (std::find(trackIdsFromPi0.begin(), trackIdsFromPi0.end(), t1.globalIndex) != trackIdsFromPi0.end()) { + continue; + } + if (std::find(trackIdsFromPi0.begin(), trackIdsFromPi0.end(), t2.globalIndex) != trackIdsFromPi0.end()) { + continue; + } + ROOT::Math::PtEtaPhiMVector v1(t1.pt, t1.eta, t1.phi, o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(t2.pt, t2.eta, t2.phi, o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + fRegistry.fill(HIST("Pair/uls/hMvsPt"), v12.M(), v12.Pt()); + } // end of electron loop + } // end of positron loop + + size_t nposVM = static_cast(std::ranges::distance(probePositronsVM)); + size_t neleVM = static_cast(std::ranges::distance(probeElectronsVM)); + + for (size_t i = 0; i < nposVM; i++) { + auto t1 = posLeptons[i]; + for (size_t j = i + 1; j < nposVM; j++) { + auto t2 = posLeptons[j]; + if (std::find(trackIdsFromPi0.begin(), trackIdsFromPi0.end(), t1.globalIndex) != trackIdsFromPi0.end()) { + continue; + } + if (std::find(trackIdsFromPi0.begin(), trackIdsFromPi0.end(), t2.globalIndex) != trackIdsFromPi0.end()) { + continue; + } + ROOT::Math::PtEtaPhiMVector v1(t1.pt, t1.eta, t1.phi, o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(t2.pt, t2.eta, t2.phi, o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + fRegistry.fill(HIST("Pair/lspp/hMvsPt"), v12.M(), v12.Pt()); + } // end of positron loop + } // end of positron loop + + for (size_t i = 0; i < neleVM; i++) { + auto t1 = negLeptons[i]; + for (size_t j = i + 1; j < neleVM; j++) { + auto t2 = negLeptons[j]; + if (std::find(trackIdsFromPi0.begin(), trackIdsFromPi0.end(), t1.globalIndex) != trackIdsFromPi0.end()) { + continue; + } + if (std::find(trackIdsFromPi0.begin(), trackIdsFromPi0.end(), t2.globalIndex) != trackIdsFromPi0.end()) { + continue; + } + ROOT::Math::PtEtaPhiMVector v1(t1.pt, t1.eta, t1.phi, o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(t2.pt, t2.eta, t2.phi, o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + fRegistry.fill(HIST("Pair/lsmm/hMvsPt"), v12.M(), v12.Pt()); + } // end of electron loop + } // end of electron loop + + posLeptons.clear(); + posLeptons.shrink_to_fit(); + negLeptons.clear(); + negLeptons.shrink_to_fit(); + trackIdsFromPi0.clear(); + trackIdsFromPi0.shrink_to_fit(); + + } // end of collision loop + } // end of runTAP + + void processData(MyBCs const& bcs, FilteredMyCollisions const& collisions, FilteredMyTracks const& tracks) + { + runTAP(bcs, collisions, tracks); + } + PROCESS_SWITCH(createTTP, processData, "process data", true); + + using MyCollisionsMC = soa::Join; + using MyTracksMC = soa::Join; + + using FilteredMyCollisionsMC = soa::Filtered; + using FilteredMyTracksMC = soa::Filtered; + + void processMC(MyBCs const&, FilteredMyCollisionsMC const& collisions, FilteredMyTracksMC const& tracks, aod::McCollisions const&, aod::McParticles const& mcParticles) + { + for (const auto& collision : collisions) { + if (!collision.has_mcCollision()) { + continue; + } + + auto bc = collision.template bc_as(); + initCCDB(bc); + + float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; + if (centralities[eventCut.cfgCentEstimator] < eventCut.cfgCentMin || eventCut.cfgCentMax < centralities[eventCut.cfgCentEstimator]) { + continue; + } + + fRegistry.fill(HIST("Event/hCollisionCounter"), 0); + if (!isSelectedCollision(collision)) { + continue; + } + fRegistry.fill(HIST("Event/hCollisionCounter"), 1); + + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + + auto tracks_per_coll = tracks.sliceBy(perCol, collision.globalIndex()); + std::vector posLeptons; + std::vector negLeptons; + posLeptons.reserve(tracks_per_coll.size()); + negLeptons.reserve(tracks_per_coll.size()); + + o2::dataformats::DCA mDcaInfoCov; + for (const auto& track : tracks_per_coll) { + if (!track.has_mcParticle()) { + continue; + } + auto mcParticle = track.template mcParticle_as(); + auto mcCollision = mcParticle.template mcCollision_as(); + if (std::abs(mcParticle.pdgCode()) != 11) { + continue; + } + if (!(mcParticle.isPhysicalPrimary() || mcParticle.producedByGenerator())) { + continue; + } + if (!mcParticle.has_mothers()) { + continue; + } + + if (cfgEventGeneratorType >= 0 && mcCollision.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } + + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(o2::track::PID::Electron); + bool isPropOK = o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); + if (!isPropOK) { + continue; + } + if (!isProbe(track, trackParCov.getPt(), trackParCov.getEta(), mDcaInfoCov.getY(), mDcaInfoCov.getZ())) { // PID cut is not necessary, because this is true electron. + continue; + } + + fRegistry.fill(HIST("Track/hs"), trackParCov.getPt(), trackParCov.getEta(), RecoDecay::constrainAngle(trackParCov.getPhi(), 0, 1U), track.sign(), mDcaInfoCov.getY() * 1e+4, mDcaInfoCov.getZ() * 1e+4, mDcaInfoCov.getY() / std::sqrt(trackParCov.getSigmaY2()), mDcaInfoCov.getZ() / std::sqrt(trackParCov.getSigmaZ2())); + + lepton tmp; + tmp.pt = trackParCov.getPt(); + tmp.eta = trackParCov.getEta(); + tmp.phi = RecoDecay::constrainAngle(trackParCov.getPhi(), 0, 1U); + tmp.globalIndex = track.globalIndex(); + tmp.mcParticleId = mcParticle.globalIndex(); + + if (track.sign() > 0) { + posLeptons.emplace_back(tmp); + } else { + negLeptons.emplace_back(tmp); + } + } // end of track loop + + for (const auto& pos : posLeptons) { + for (const auto& neg : negLeptons) { + ROOT::Math::PtEtaPhiMVector v1(pos.pt, pos.eta, pos.phi, o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(neg.pt, neg.eta, neg.phi, o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + + auto posmc = mcParticles.rawIteratorAt(pos.mcParticleId); + auto negmc = mcParticles.rawIteratorAt(neg.mcParticleId); + + int omegaId = o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 223, mcParticles); + int phiId = o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 333, mcParticles); + int jpsiId = o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 443, mcParticles); + if (omegaId > 0) { + auto mcMother = mcParticles.rawIteratorAt(omegaId); + int ndau = mcMother.daughtersIds()[1] - mcMother.daughtersIds()[0] + 1; + if (ndau == 2) { + fRegistry.fill(HIST("Pair/hMvsPt_omega"), v12.M(), v12.Pt()); + } + } else if (phiId > 0) { + auto mcMother = mcParticles.rawIteratorAt(phiId); + int ndau = mcMother.daughtersIds()[1] - mcMother.daughtersIds()[0] + 1; + if (ndau == 2) { + fRegistry.fill(HIST("Pair/hMvsPt_phi"), v12.M(), v12.Pt()); + } + } else if (jpsiId > 0) { + auto mcMother = mcParticles.rawIteratorAt(jpsiId); + int ndau = mcMother.daughtersIds()[1] - mcMother.daughtersIds()[0] + 1; + if (ndau == 2) { + fRegistry.fill(HIST("Pair/hMvsPt_jpsi"), v12.M(), v12.Pt()); + } + } + } // end of electron loop + } // end of positron loop + + posLeptons.clear(); + posLeptons.shrink_to_fit(); + negLeptons.clear(); + negLeptons.shrink_to_fit(); + + } // end of collision loop + } + PROCESS_SWITCH(createTTP, processMC, "process MC", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"create-ttp"})}; +} diff --git a/PWGEM/Dilepton/Tasks/dielectron.cxx b/PWGEM/Dilepton/Tasks/dielectron.cxx index 27f5d13802e..042831bff30 100644 --- a/PWGEM/Dilepton/Tasks/dielectron.cxx +++ b/PWGEM/Dilepton/Tasks/dielectron.cxx @@ -25,5 +25,5 @@ using namespace o2::framework; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask>(cfgc, TaskName{"dielectron"})}; + adaptAnalysisTask>(cfgc, TaskName{"dielectron"})}; } diff --git a/PWGEM/Dilepton/Tasks/dielectronSCT.cxx b/PWGEM/Dilepton/Tasks/dielectronSVMC.cxx similarity index 74% rename from PWGEM/Dilepton/Tasks/dielectronSCT.cxx rename to PWGEM/Dilepton/Tasks/dielectronSVMC.cxx index 646069802b5..7bcd0ab497d 100644 --- a/PWGEM/Dilepton/Tasks/dielectronSCT.cxx +++ b/PWGEM/Dilepton/Tasks/dielectronSVMC.cxx @@ -11,10 +11,10 @@ // // ======================== // -// This code is for dielectron analyses. +// This code runs loop over electron table and make pairs. // Please write to: daiki.sekihata@cern.ch -#include "PWGEM/Dilepton/Core/Dilepton.h" +#include "PWGEM/Dilepton/Core/DileptonSVMC.h" #include "PWGEM/Dilepton/Utils/PairUtilities.h" #include @@ -25,5 +25,5 @@ using namespace o2::framework; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask>(cfgc, TaskName{"dielectron-sct"})}; + adaptAnalysisTask>(cfgc, TaskName{"dielectron-sv-mc"})}; } diff --git a/PWGEM/Dilepton/Tasks/dileptonPolarization.cxx b/PWGEM/Dilepton/Tasks/dileptonPolarization.cxx deleted file mode 100644 index df4f9c14fda..00000000000 --- a/PWGEM/Dilepton/Tasks/dileptonPolarization.cxx +++ /dev/null @@ -1,650 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -// -// ======================== -// -// This code runs loop over leptons. -// Please write to: daiki.sekihata@cern.ch - -#include "PWGEM/Dilepton/DataModel/dileptonTables.h" -#include "PWGEM/Dilepton/Utils/EMTrack.h" -#include "PWGEM/Dilepton/Utils/PairUtilities.h" - -#include "Common/Core/RecoDecay.h" -#include "Common/DataModel/EventSelection.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace o2; -using namespace o2::aod; -using namespace o2::framework; -using namespace o2::framework::expressions; -using namespace o2::soa; -using namespace o2::aod::pwgem::dilepton::utils; -using namespace o2::aod::pwgem::dilepton::utils::pairutil; - -struct DileptonPolarization { - // Configurables - Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - - Configurable cfgPairType{"cfgPairType", 0, "0:dielectron, 1:dimuon"}; - Configurable cfgOccupancyEstimator{"cfgOccupancyEstimator", 0, "FT0C:0, Track:1"}; - Configurable cfgDoMix{"cfgDoMix", true, "flag for event mixing"}; - // Configurable ndepth{"ndepth", 10000, "depth for event mixing"}; - Configurable ndiff_bc_mix{"ndiff_bc_mix", 594, "difference in global BC required in mixed events"}; - ConfigurableAxis ConfVtxBins{"ConfVtxBins", {10, -10.0f, 10.f}, "Mixing bins - z-vertex"}; - ConfigurableAxis ConfCentBins{"ConfCentBins", {VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f, 999.f}, "Mixing bins - centrality"}; - ConfigurableAxis ConfEPBins{"ConfEPBins", {1, -M_PI / 2, +M_PI / 2}, "Mixing bins - event plane angle"}; - ConfigurableAxis ConfOccupancyBins{"ConfOccupancyBins", {VARIABLE_WIDTH, -1, 1e+10}, "Mixing bins - occupancy"}; - Configurable cfgPolarizationFrame{"cfgPolarizationFrame", 0, "frame of polarization. 0:CS, 1:HX, else:FATAL"}; - Configurable cfgUseAbs{"cfgUseAbs", false, "flag to use absolute value for cos_theta and phi"}; // this is to increase statistics per bin. - Configurable cfgDoULS{"cfgDoULS", true, "flag to perform ULS pairing"}; - Configurable cfgDoLS{"cfgDoLS", true, "flag to perform LS pairing"}; - - ConfigurableAxis ConfMllBins{"ConfMllBins", {VARIABLE_WIDTH, 0.00, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.00, 8.10, 8.20, 8.30, 8.40, 8.50, 8.60, 8.70, 8.80, 8.90, 9.00, 9.10, 9.20, 9.30, 9.40, 9.50, 9.60, 9.70, 9.80, 9.90, 10.00, 10.10, 10.20, 10.30, 10.40, 10.50, 10.60, 10.70, 10.80, 10.90, 11.00, 11.1, 11.2, 11.3, 11.4, 11.50, 11.6, 11.7, 11.8, 11.9, 12.0}, "mll bins for output histograms"}; - ConfigurableAxis ConfPtllBins{"ConfPtllBins", {VARIABLE_WIDTH, 0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00, 6.00, 7.00, 8.00, 9.00, 10.00}, "pTll bins for output histograms"}; - ConfigurableAxis ConfDCAllBins{"ConfDCAllBins", {VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0}, "DCAll bins for output histograms"}; - ConfigurableAxis ConfYllBins{"ConYllBins", {1, -1.f, 1.f}, "yll bins for output histograms"}; // pair rapidity - - ConfigurableAxis ConfPolarizationCosThetaBins{"ConfPolarizationCosThetaBins", {20, -1.f, 1.f}, "cos(theta) bins for polarization analysis"}; - ConfigurableAxis ConfPolarizationPhiBins{"ConfPolarizationPhiBins", {1, -M_PI, M_PI}, "phi bins for polarization analysis"}; - ConfigurableAxis ConfPolarizationQuadMomBins{"ConfPolarizationQuadMomBins", {15, -0.5, 1}, "quadrupole moment bins for polarization analysis"}; // quardrupole moment <(3 x cos^2(theta) -1)/2> - - struct : ConfigurableGroup { - std::string prefix = "eventcut_group"; - Configurable cfgZvtxMin{"cfgZvtxMin", -10.f, "min. Zvtx"}; - Configurable cfgZvtxMax{"cfgZvtxMax", +10.f, "max. Zvtx"}; - // Configurable cfgRequireSel8{"cfgRequireSel8", true, "require sel8 in event cut"}; - // Configurable cfgRequireFT0AND{"cfgRequireFT0AND", true, "require FT0AND in event cut"}; - // Configurable cfgRequireNoTFB{"cfgRequireNoTFB", false, "require No time frame border in event cut"}; - // Configurable cfgRequireNoITSROFB{"cfgRequireNoITSROFB", false, "require no ITS readout frame border in event cut"}; - // Configurable cfgRequireNoSameBunchPileup{"cfgRequireNoSameBunchPileup", false, "require no same bunch pileup in event cut"}; - // Configurable cfgRequireVertexITSTPC{"cfgRequireVertexITSTPC", false, "require Vertex ITSTPC in event cut"}; // ITS-TPC matched track contributes PV. - // Configurable cfgRequireVertexTOFmatched{"cfgRequireVertexTOFmatched", false, "require Vertex TOFmatched in event cut"}; // ITS-TPC-TOF matched track contributes PV. - // Configurable cfgRequireGoodZvtxFT0vsPV{"cfgRequireGoodZvtxFT0vsPV", false, "require good Zvtx between FT0 vs. PV in event cut"}; - Configurable cfgCentMin{"cfgCentMin", -1, "min. centrality"}; - Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; - Configurable cfgTrackOccupancyMin{"cfgTrackOccupancyMin", -2, "min. occupancy"}; - Configurable cfgTrackOccupancyMax{"cfgTrackOccupancyMax", 1000000000, "max. occupancy"}; - Configurable cfgFT0COccupancyMin{"cfgFT0COccupancyMin", -2, "min. FT0C occupancy"}; - Configurable cfgFT0COccupancyMax{"cfgFT0COccupancyMax", 1000000000, "max. FT0C occupancy"}; - } eventcuts; - - struct : ConfigurableGroup { - std::string prefix = "dileptoncut_group"; - Configurable cfg_min_pair_mass{"cfg_min_pair_mass", 0.0, "min pair mass"}; - Configurable cfg_max_pair_mass{"cfg_max_pair_mass", 1e+10, "max pair mass"}; - Configurable cfg_min_pair_pt{"cfg_min_pair_pt", 0.0, "min pair pT"}; - Configurable cfg_max_pair_pt{"cfg_max_pair_pt", 1e+10, "max pair pT"}; - Configurable cfg_min_pair_y{"cfg_min_pair_y", -0.9, "min pair rapidity"}; - Configurable cfg_max_pair_y{"cfg_max_pair_y", +0.9, "max pair rapidity"}; - - Configurable cfg_min_track_pt{"cfg_min_track_pt", 0.2, "min pT for single track"}; - Configurable cfg_max_track_pt{"cfg_max_track_pt", 1e+10, "max pT for single track"}; - Configurable cfg_min_track_eta{"cfg_min_track_eta", -0.9, "min eta for single track"}; - Configurable cfg_max_track_eta{"cfg_max_track_eta", +0.9, "max eta for single track"}; - } dileptoncuts; - - struct : ConfigurableGroup { - std::string prefix = "accBins"; - Configurable cfgDM{"cfgDM", 0.01, "dm for lorentz boost"}; - Configurable cfgDPt{"cfgDPt", 0.1, "dpT for lorentz boost"}; - Configurable cfgDEta{"cfgDEta", 0.1, "deta for lorentz boost"}; - Configurable cfgDPhi{"cfgDPhi", 0.087, "dphi (rad.) for lorentz boost"}; - } accBins; - - Service ccdb; - int mRunNumber; - // float d_bz; - - HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; - static constexpr std::string_view event_pair_types[2] = {"same/", "mix/"}; - static constexpr std::string_view pair_sign_types[3] = {"uls/", "lspp/", "lsmm/"}; - - std::mt19937 engine; - std::vector zvtx_bin_edges; - std::vector cent_bin_edges; - std::vector ep_bin_edges; - std::vector occ_bin_edges; - - float leptonM1 = 0.f; - float leptonM2 = 0.f; - - float beamM1 = o2::constants::physics::MassProton; // mass of beam - float beamM2 = o2::constants::physics::MassProton; // mass of beam - float beamE1 = 0.f; // beam energy - float beamE2 = 0.f; // beam energy - float beamP1 = 0.f; // beam momentum - float beamP2 = 0.f; // beam momentum - - void init(InitContext& /*context*/) - { - mRunNumber = 0; - // d_bz = 0; - - ccdb->setURL(ccdburl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); - - if (cfgPairType.value == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron)) { - leptonM1 = o2::constants::physics::MassElectron; - leptonM2 = o2::constants::physics::MassElectron; - } else if (cfgPairType.value == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon)) { - leptonM1 = o2::constants::physics::MassMuon; - leptonM2 = o2::constants::physics::MassMuon; - } else { - LOG(fatal) << "Please select either dielectron or dimuon"; - } - - if (ConfVtxBins.value[0] == VARIABLE_WIDTH) { - zvtx_bin_edges = std::vector(ConfVtxBins.value.begin(), ConfVtxBins.value.end()); - zvtx_bin_edges.erase(zvtx_bin_edges.begin()); - for (const auto& edge : zvtx_bin_edges) { - LOGF(info, "VARIABLE_WIDTH: zvtx_bin_edges = %f", edge); - } - } else { - int nbins = static_cast(ConfVtxBins.value[0]); - float xmin = static_cast(ConfVtxBins.value[1]); - float xmax = static_cast(ConfVtxBins.value[2]); - zvtx_bin_edges.resize(nbins + 1); - for (int i = 0; i < nbins + 1; i++) { - zvtx_bin_edges[i] = (xmax - xmin) / (nbins)*i + xmin; - LOGF(info, "FIXED_WIDTH: zvtx_bin_edges[%d] = %f", i, zvtx_bin_edges[i]); - } - } - - if (ConfCentBins.value[0] == VARIABLE_WIDTH) { - cent_bin_edges = std::vector(ConfCentBins.value.begin(), ConfCentBins.value.end()); - cent_bin_edges.erase(cent_bin_edges.begin()); - for (const auto& edge : cent_bin_edges) { - LOGF(info, "VARIABLE_WIDTH: cent_bin_edges = %f", edge); - } - } else { - int nbins = static_cast(ConfCentBins.value[0]); - float xmin = static_cast(ConfCentBins.value[1]); - float xmax = static_cast(ConfCentBins.value[2]); - cent_bin_edges.resize(nbins + 1); - for (int i = 0; i < nbins + 1; i++) { - cent_bin_edges[i] = (xmax - xmin) / (nbins)*i + xmin; - LOGF(info, "FIXED_WIDTH: cent_bin_edges[%d] = %f", i, cent_bin_edges[i]); - } - } - - if (ConfEPBins.value[0] == VARIABLE_WIDTH) { - ep_bin_edges = std::vector(ConfEPBins.value.begin(), ConfEPBins.value.end()); - ep_bin_edges.erase(ep_bin_edges.begin()); - for (const auto& edge : ep_bin_edges) { - LOGF(info, "VARIABLE_WIDTH: ep_bin_edges = %f", edge); - } - } else { - int nbins = static_cast(ConfEPBins.value[0]); - float xmin = static_cast(ConfEPBins.value[1]); - float xmax = static_cast(ConfEPBins.value[2]); - ep_bin_edges.resize(nbins + 1); - for (int i = 0; i < nbins + 1; i++) { - ep_bin_edges[i] = (xmax - xmin) / (nbins)*i + xmin; - LOGF(info, "FIXED_WIDTH: ep_bin_edges[%d] = %f", i, ep_bin_edges[i]); - } - } - - LOGF(info, "cfgOccupancyEstimator = %d", cfgOccupancyEstimator.value); - if (ConfOccupancyBins.value[0] == VARIABLE_WIDTH) { - occ_bin_edges = std::vector(ConfOccupancyBins.value.begin(), ConfOccupancyBins.value.end()); - occ_bin_edges.erase(occ_bin_edges.begin()); - for (const auto& edge : occ_bin_edges) { - LOGF(info, "VARIABLE_WIDTH: occ_bin_edges = %f", edge); - } - } else { - int nbins = static_cast(ConfOccupancyBins.value[0]); - float xmin = static_cast(ConfOccupancyBins.value[1]); - float xmax = static_cast(ConfOccupancyBins.value[2]); - occ_bin_edges.resize(nbins + 1); - for (int i = 0; i < nbins + 1; i++) { - occ_bin_edges[i] = (xmax - xmin) / (nbins)*i + xmin; - LOGF(info, "FIXED_WIDTH: occ_bin_edges[%d] = %f", i, occ_bin_edges[i]); - } - } - - std::random_device seed_gen; - engine = std::mt19937(seed_gen()); - - addhistograms(); - - fRegistry.add("Pair/mix/hDiffBC", "diff. global BC in mixed event;|BC_{current} - BC_{mixed}|", kTH1D, {{10001, -0.5, 10000.5}}, true); - } - - template - void initCCDB(TCollision const& collision) - { - if (mRunNumber == collision.runNumber()) { - return; - } - - // // In case override, don't proceed, please - no CCDB access required - // if (d_bz_input > -990) { - // d_bz = d_bz_input; - // o2::parameters::GRPMagField grpmag; - // if (std::fabs(d_bz) > 1e-5) { - // grpmag.setL3Current(30000.f / (d_bz / 5.0f)); - // } - // o2::base::Propagator::initFieldFromGRP(&grpmag); - // mRunNumber = collision.runNumber(); - // return; - // } - - // auto run3grp_timestamp = collision.timestamp(); - // o2::parameters::GRPObject* grpo = 0x0; - // o2::parameters::GRPMagField* grpmag = 0x0; - // if (!skipGRPOquery) - // grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); - // if (grpo) { - // o2::base::Propagator::initFieldFromGRP(grpo); - // // Fetch magnetic field from ccdb for current collision - // d_bz = grpo->getNominalL3Field(); - // LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kG"; - // } else { - // grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); - // if (!grpmag) { - // LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; - // } - // o2::base::Propagator::initFieldFromGRP(grpmag); - // // Fetch magnetic field from ccdb for current collision - // d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); - // LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kG"; - // } - - auto grplhcif = ccdb->getForTimeStamp("GLO/Config/GRPLHCIF", collision.timestamp()); - int beamZ1 = grplhcif->getBeamZ(o2::constants::lhc::BeamC); - int beamZ2 = grplhcif->getBeamZ(o2::constants::lhc::BeamA); - int beamA1 = grplhcif->getBeamA(o2::constants::lhc::BeamC); - int beamA2 = grplhcif->getBeamA(o2::constants::lhc::BeamA); - beamE1 = grplhcif->getBeamEnergyPerNucleonInGeV(o2::constants::lhc::BeamC); - beamE2 = grplhcif->getBeamEnergyPerNucleonInGeV(o2::constants::lhc::BeamA); - beamM1 = o2::constants::physics::MassProton * beamA1; - beamM2 = o2::constants::physics::MassProton * beamA2; - beamP1 = std::sqrt(std::pow(beamE1, 2) - std::pow(beamM1, 2)); - beamP2 = std::sqrt(std::pow(beamE2, 2) - std::pow(beamM2, 2)); - LOGF(info, "beamZ1 = %d, beamZ2 = %d, beamA1 = %d, beamA2 = %d, beamE1 = %f (GeV), beamE2 = %f (GeV), beamM1 = %f (GeV), beamM2 = %f (GeV), beamP1 = %f (GeV), beamP2 = %f (GeV)", beamZ1, beamZ2, beamA1, beamA2, beamE1, beamE2, beamM1, beamM2, beamP1, beamP2); - - mRunNumber = collision.runNumber(); - } - - ~DileptonPolarization() {} - - void addhistograms() - { - auto hCollisionCounter = fRegistry.add("Event/before/hCollisionCounter", "collision counter;;Number of events", kTH1D, {{9, 0.5, 9 + 0.5}}, false); - hCollisionCounter->GetXaxis()->SetBinLabel(1, "all"); - hCollisionCounter->GetXaxis()->SetBinLabel(2, "FT0AND"); - hCollisionCounter->GetXaxis()->SetBinLabel(3, "No TF border"); - hCollisionCounter->GetXaxis()->SetBinLabel(4, "No ITS ROF border"); - hCollisionCounter->GetXaxis()->SetBinLabel(5, "No Same Bunch Pileup"); - hCollisionCounter->GetXaxis()->SetBinLabel(6, "Is Good Zvtx FT0vsPV"); - hCollisionCounter->GetXaxis()->SetBinLabel(7, "sel8"); - hCollisionCounter->GetXaxis()->SetBinLabel(8, "|Z_{vtx}| < 10 cm"); - hCollisionCounter->GetXaxis()->SetBinLabel(9, "accepted"); - - fRegistry.add("Event/before/hZvtx", "vertex z; Z_{vtx} (cm)", kTH1D, {{100, -50, +50}}, false); - fRegistry.add("Event/before/hCentFT0C", "hCentFT0C;centrality FT0C (%)", kTH1D, {{110, 0, 110}}, false); - fRegistry.add("Event/before/hCorrOccupancy", "occupancy correlation;FT0C occupancy;track occupancy", kTH2D, {{200, 0, 200000}, {200, 0, 20000}}, false); - fRegistry.add("Event/before/hEP2_CentFT0C_forMix", "2nd harmonics event plane for mix;centrality FT0C (%);#Psi_{2} (rad.)", kTH2F, {{110, 0, 110}, {180, -M_PI_2, +M_PI_2}}, false); - fRegistry.addClone("Event/before/", "Event/after/"); - - std::string mass_axis_title = "m_{ll} (GeV/c^{2})"; - std::string pair_pt_axis_title = "p_{T,ll} (GeV/c)"; - std::string pair_dca_axis_title = "DCA_{ll} (#sigma)"; - std::string pair_y_axis_title = "y_{ll}"; - - if (cfgPairType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron)) { - mass_axis_title = "m_{ee} (GeV/c^{2})"; - pair_pt_axis_title = "p_{T,ee} (GeV/c)"; - pair_dca_axis_title = "DCA_{ee} (#sigma)"; - pair_y_axis_title = "y_{ee}"; - } else if (cfgPairType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon)) { - mass_axis_title = "m_{#mu#mu} (GeV/c^{2})"; - pair_pt_axis_title = "p_{T,#mu#mu} (GeV/c)"; - pair_dca_axis_title = "DCA_{#mu#mu} (#sigma)"; - pair_y_axis_title = "y_{#mu#mu}"; - } - - // pair info - const AxisSpec axis_mass{ConfMllBins, mass_axis_title}; - const AxisSpec axis_pt{ConfPtllBins, pair_pt_axis_title}; - const AxisSpec axis_dca{ConfDCAllBins, pair_dca_axis_title}; - const AxisSpec axis_y{ConfYllBins, pair_y_axis_title}; - - std::string frameName = "CS"; - if (cfgPolarizationFrame == 0) { - frameName = "CS"; - } else if (cfgPolarizationFrame == 1) { - frameName = "HX"; - } else { - LOG(fatal) << "set 0 or 1 to cfgPolarizationFrame!"; - } - - const AxisSpec axis_cos_theta{ConfPolarizationCosThetaBins, Form("cos(#theta^{%s})", frameName.data())}; - const AxisSpec axis_phi{ConfPolarizationPhiBins, Form("#varphi^{%s} (rad.)", frameName.data())}; - const AxisSpec axis_quadmom{ConfPolarizationQuadMomBins, Form("#frac{3 cos^{2}(#theta^{%s}) -1}{2}", frameName.data())}; - fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_cos_theta, axis_phi, axis_quadmom}, true); - - fRegistry.addClone("Pair/same/uls/", "Pair/same/lspp/"); - fRegistry.addClone("Pair/same/uls/", "Pair/same/lsmm/"); - fRegistry.addClone("Pair/same/", "Pair/mix/"); - fRegistry.add("Pair/same/uls/hEta", "#eta_{ll}", kTH1D, {{2000, -10, 10}}, true); - // fRegistry.add("Pair/mix/uls/hBeta", "#beta for Lorentz boost;#beta^{same};(#beta^{mix} - #beta^{same})/#beta^{same}", kTH2D, {{100, 0, 1}, {400, -0.2, 0.2}}, true); - } - - template - bool fillPairInfo(TCollision const& collision, TDilepton const& dilepton, TMixingBin const& mixingBin) - { - float weight = 1.f; - ROOT::Math::PtEtaPhiMVector v1(dilepton.pt1(), dilepton.eta1(), dilepton.phi1(), leptonM1); - ROOT::Math::PtEtaPhiMVector v2(dilepton.pt2(), dilepton.eta2(), dilepton.phi2(), leptonM2); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - - if (v12.M() < dileptoncuts.cfg_min_pair_mass || dileptoncuts.cfg_max_pair_mass < v12.M()) { - return false; - } - - if (v12.Pt() < dileptoncuts.cfg_min_pair_pt || dileptoncuts.cfg_max_pair_pt < v12.Pt()) { - return false; - } - - if (v12.Rapidity() < dileptoncuts.cfg_min_pair_y || dileptoncuts.cfg_max_pair_y < v12.Rapidity()) { - return false; - } - - float pair_dca = pairDCAQuadSum(dilepton.dca1(), dilepton.dca2()); - float cos_thetaPol = 999, phiPol = 999.f; - auto arrM = std::array{static_cast(v12.Px()), static_cast(v12.Py()), static_cast(v12.Pz()), static_cast(v12.M())}; - auto random_sign = std::pow(-1, engine() % 2); // -1^0 = +1 or -1^1 = -1; - auto arrD = dilepton.sign1() * dilepton.sign2() < 0 ? (dilepton.sign1() > 0 ? std::array{static_cast(v1.Px()), static_cast(v1.Py()), static_cast(v1.Pz()), leptonM1} : std::array{static_cast(v2.Px()), static_cast(v2.Py()), static_cast(v2.Pz()), leptonM2}) : (random_sign > 0 ? std::array{static_cast(v1.Px()), static_cast(v1.Py()), static_cast(v1.Pz()), leptonM1} : std::array{static_cast(v2.Px()), static_cast(v2.Py()), static_cast(v2.Pz()), leptonM2}); - if (cfgPolarizationFrame == 0) { - o2::aod::pwgem::dilepton::utils::pairutil::getAngleCS(arrM, arrD, beamE1, beamE2, beamP1, beamP2, cos_thetaPol, phiPol); - } else if (cfgPolarizationFrame == 1) { - o2::aod::pwgem::dilepton::utils::pairutil::getAngleHX(arrM, arrD, beamE1, beamE2, beamP1, beamP2, cos_thetaPol, phiPol); - } - o2::math_utils::bringToPMPi(phiPol); - float quadmom = (3.f * std::pow(cos_thetaPol, 2) - 1.f) / 2.f; - - if (cfgUseAbs) { - cos_thetaPol = std::fabs(cos_thetaPol); - phiPol = std::fabs(phiPol); - } - - if (dilepton.sign1() * dilepton.sign2() < 0) { // ULS - fRegistry.fill(HIST("Pair/same/uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), cos_thetaPol, phiPol, quadmom, weight); - fRegistry.fill(HIST("Pair/same/uls/hEta"), v12.Eta(), weight); - } else if (dilepton.sign1() > 0 && dilepton.sign2() > 0) { // LS++ - fRegistry.fill(HIST("Pair/same/lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), cos_thetaPol, phiPol, quadmom, weight); - fRegistry.fill(HIST("Pair/same/lspp/hEta"), v12.Eta(), weight); - } else if (dilepton.sign1() < 0 && dilepton.sign2() < 0) { // LS-- - fRegistry.fill(HIST("Pair/same/lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), cos_thetaPol, phiPol, quadmom, weight); - fRegistry.fill(HIST("Pair/same/lsmm/hEta"), v12.Eta(), weight); - } - - float phi12_tmp = v12.Phi(); - o2::math_utils::bringTo02Pi(phi12_tmp); - EMPair empair = EMPair(v12.Pt(), v12.Eta(), phi12_tmp, v12.M(), 0); - empair.setPositiveLegPxPyPzM(arrD[0], arrD[1], arrD[2], leptonM1); - // empair.setNegativeLegPtEtaPhiM(t2.pt(), t2.eta(), t2.phi(), leptonM2); - empair.setPairDCA(pair_dca); - auto pair_tmp = std::make_pair(collision.globalIndex(), empair); - if (dilepton.sign1() * dilepton.sign2() < 0) { // ULS - mapMixingULS[mixingBin].emplace_back(pair_tmp); - } else if (dilepton.sign1() > 0 && dilepton.sign2() > 0) { // LS++ - mapMixingLSPP[mixingBin].emplace_back(pair_tmp); - } else if (dilepton.sign1() < 0 && dilepton.sign2() < 0) { // LS-- - mapMixingLSMM[mixingBin].emplace_back(pair_tmp); - } - return true; - } - - template - void fillMixedPairInfo(TPairs const& pairs) - { - float weight = 1.f; - - for (const auto& pair1 : pairs) { - auto globalBC1 = map_mixed_eventId_to_globalBC[std::get<0>(pair1)]; - auto empair1 = std::get<1>(pair1); - auto v_pos = empair1.getPositiveLeg(); // pt, eta, phi, M - auto arrD = std::array{static_cast(v_pos.Px()), static_cast(v_pos.Py()), static_cast(v_pos.Pz()), leptonM1}; - - auto pairs_in_same_ptetaphim_bin = std::views::filter(pairs, [&](std::pair t) { return std::get<0>(t) != std::get<0>(pair1) && std::fabs(std::get<1>(t).mass() - empair1.mass()) < accBins.cfgDM && std::fabs(std::get<1>(t).pt() - empair1.pt()) < accBins.cfgDPt && std::fabs(std::get<1>(t).eta() - empair1.eta()) < accBins.cfgDEta && std::fabs(RecoDecay::constrainAngle(std::get<1>(t).phi() - empair1.phi(), -o2::constants::math::PI, 1U)) < accBins.cfgDPhi; }); - - for (const auto& pair2 : pairs_in_same_ptetaphim_bin) { - auto globalBC2 = map_mixed_eventId_to_globalBC[std::get<0>(pair2)]; - uint64_t diffBC = std::max(globalBC1, globalBC2) - std::min(globalBC1, globalBC2); - fRegistry.fill(HIST("Pair/mix/hDiffBC"), diffBC); - if (diffBC < ndiff_bc_mix) { - continue; - } - - auto empair2 = std::get<1>(pair2); - auto arrM = std::array{static_cast(empair2.px()), static_cast(empair2.py()), static_cast(empair2.pz()), static_cast(empair2.mass())}; - - float cos_thetaPol = 999.f, phiPol = 999.f; - if (cfgPolarizationFrame == 0) { - o2::aod::pwgem::dilepton::utils::pairutil::getAngleCS(arrM, arrD, beamE1, beamE2, beamP1, beamP2, cos_thetaPol, phiPol); - } else if (cfgPolarizationFrame == 1) { - o2::aod::pwgem::dilepton::utils::pairutil::getAngleHX(arrM, arrD, beamE1, beamE2, beamP1, beamP2, cos_thetaPol, phiPol); - } - o2::math_utils::bringToPMPi(phiPol); - float quadmom = (3.f * std::pow(cos_thetaPol, 2) - 1.f) / 2.f; - if (cfgUseAbs) { - cos_thetaPol = std::fabs(cos_thetaPol); - phiPol = std::fabs(phiPol); - } - fRegistry.fill(HIST("Pair/mix/") + HIST(pair_sign_types[signType]) + HIST("hs"), empair1.mass(), empair1.pt(), empair1.getPairDCA(), empair1.rapidity(), cos_thetaPol, phiPol, quadmom, weight); - // fRegistry.fill(HIST("Pair/mix/") + HIST(pair_sign_types[signType]) + HIST("hBeta"), empair1.p() / empair1.e(), (empair2.p() / empair2.e() - empair1.p() / empair1.e()) / (empair1.p() / empair1.e())); - - } // end of pair2 loop - } // end of pair1 loop - } - - Filter collisionFilter_centrality = eventcuts.cfgCentMin < o2::aod::emthinevent::centrality && o2::aod::emthinevent::centrality < eventcuts.cfgCentMax; - Filter collisionFilter_occupancy_track = eventcuts.cfgTrackOccupancyMin <= o2::aod::evsel::trackOccupancyInTimeRange && o2::aod::evsel::trackOccupancyInTimeRange < eventcuts.cfgTrackOccupancyMax; - Filter collisionFilter_occupancy_ft0c = eventcuts.cfgFT0COccupancyMin <= o2::aod::evsel::ft0cOccupancyInTimeRange && o2::aod::evsel::ft0cOccupancyInTimeRange < eventcuts.cfgFT0COccupancyMax; - using filteredCollisions = soa::Filtered; - - Filter dileptonFilter_track1 = (dileptoncuts.cfg_min_track_pt < o2::aod::emdilepton::pt1 && o2::aod::emdilepton::pt1 < dileptoncuts.cfg_max_track_pt) && (dileptoncuts.cfg_min_track_eta < o2::aod::emdilepton::eta1 && o2::aod::emdilepton::eta1 < dileptoncuts.cfg_max_track_eta); - Filter dileptonFilter_track2 = (dileptoncuts.cfg_min_track_pt < o2::aod::emdilepton::pt2 && o2::aod::emdilepton::pt2 < dileptoncuts.cfg_max_track_pt) && (dileptoncuts.cfg_min_track_eta < o2::aod::emdilepton::eta2 && o2::aod::emdilepton::eta2 < dileptoncuts.cfg_max_track_eta); - using filteredDileptons = soa::Filtered; - - SliceCache cache; - Preslice perCollision = aod::emdilepton::emthineventId; - Partition dileptonsULS = (o2::aod::emdilepton::sign1 > static_cast(0) && o2::aod::emdilepton::sign2 < static_cast(0)) || (o2::aod::emdilepton::sign1 < static_cast(0) && o2::aod::emdilepton::sign2 > static_cast(0)); - Partition dileptonsLSPP = o2::aod::emdilepton::sign1 > static_cast(0) && o2::aod::emdilepton::sign2 > static_cast(0); - Partition dileptonsLSMM = o2::aod::emdilepton::sign1 < static_cast(0) && o2::aod::emdilepton::sign2 < static_cast(0); - - std::map, std::vector>> mapMixingULS; // -> vector of for ULS pairs - std::map, std::vector>> mapMixingLSPP; // -> vector of for LSPP pairs - std::map, std::vector>> mapMixingLSMM; // -> vector of for LSMM pairs - - std::unordered_map map_mixed_eventId_to_globalBC; - - template - void runPairing(TCollisions const& collisions, TDileptons const&) - { - for (const auto& collision : collisions) { - initCCDB(collision); - float centrality = collision.centrality(); - if (centrality < eventcuts.cfgCentMin || eventcuts.cfgCentMax < centrality) { - continue; - } - - float ep2 = collision.ep2(); - fRegistry.fill(HIST("Event/after/hZvtx"), collision.posZ()); - fRegistry.fill(HIST("Event/after/hCollisionCounter"), 9); - fRegistry.fill(HIST("Event/after/hCorrOccupancy"), collision.ft0cOccupancyInTimeRange(), collision.trackOccupancyInTimeRange()); - fRegistry.fill(HIST("Event/after/hEP2_CentFT0C_forMix"), centrality, ep2); - - // event mixing - int zbin = lower_bound(zvtx_bin_edges.begin(), zvtx_bin_edges.end(), collision.posZ()) - zvtx_bin_edges.begin() - 1; - if (zbin < 0) { - zbin = 0; - } else if (static_cast(zvtx_bin_edges.size()) - 2 < zbin) { - zbin = static_cast(zvtx_bin_edges.size()) - 2; - } - - int centbin = lower_bound(cent_bin_edges.begin(), cent_bin_edges.end(), centrality) - cent_bin_edges.begin() - 1; - if (centbin < 0) { - centbin = 0; - } else if (static_cast(cent_bin_edges.size()) - 2 < centbin) { - centbin = static_cast(cent_bin_edges.size()) - 2; - } - - int epbin = lower_bound(ep_bin_edges.begin(), ep_bin_edges.end(), ep2) - ep_bin_edges.begin() - 1; - if (epbin < 0) { - epbin = 0; - } else if (static_cast(ep_bin_edges.size()) - 2 < epbin) { - epbin = static_cast(ep_bin_edges.size()) - 2; - } - - int occbin = -1; - if (cfgOccupancyEstimator == 0) { - occbin = lower_bound(occ_bin_edges.begin(), occ_bin_edges.end(), collision.ft0cOccupancyInTimeRange()) - occ_bin_edges.begin() - 1; - } else if (cfgOccupancyEstimator == 1) { - occbin = lower_bound(occ_bin_edges.begin(), occ_bin_edges.end(), collision.trackOccupancyInTimeRange()) - occ_bin_edges.begin() - 1; - } else { - occbin = lower_bound(occ_bin_edges.begin(), occ_bin_edges.end(), collision.ft0cOccupancyInTimeRange()) - occ_bin_edges.begin() - 1; - } - - if (occbin < 0) { - occbin = 0; - } else if (static_cast(occ_bin_edges.size()) - 2 < occbin) { - occbin = static_cast(occ_bin_edges.size()) - 2; - } - - auto mixingBin = std::make_tuple(zbin, centbin, epbin, occbin); - - auto dileptons_uls_per_coll = dileptonsULS->sliceByCached(aod::emdilepton::emthineventId, collision.globalIndex(), cache); - auto dileptons_lspp_per_coll = dileptonsLSPP->sliceByCached(aod::emdilepton::emthineventId, collision.globalIndex(), cache); - auto dileptons_lsmm_per_coll = dileptonsLSMM->sliceByCached(aod::emdilepton::emthineventId, collision.globalIndex(), cache); - // LOGF(info, "collision.globalIndex() = %d, dileptons_uls_per_coll.size() = %d, dileptons_lspp_per_coll.size() = %d, dileptons_lsmm_per_coll.size() = %d", collision.globalIndex(), dileptons_uls_per_coll.size(), dileptons_lspp_per_coll.size(), dileptons_lsmm_per_coll.size()); - - int nuls = 0, nlspp = 0, nlsmm = 0; - if (cfgDoULS) { - for (const auto& dilepton : dileptons_uls_per_coll) { // ULS - bool is_pair_ok = fillPairInfo(collision, dilepton, mixingBin); - if (is_pair_ok) { - nuls++; - } - } - } - - if (cfgDoLS) { - for (const auto& dilepton : dileptons_lspp_per_coll) { // LS++ - bool is_pair_ok = fillPairInfo(collision, dilepton, mixingBin); - if (is_pair_ok) { - nlspp++; - } - } - for (const auto& dilepton : dileptons_lsmm_per_coll) { // LS-- - bool is_pair_ok = fillPairInfo(collision, dilepton, mixingBin); - if (is_pair_ok) { - nlsmm++; - } - } - } - - if (!cfgDoMix || !(nuls > 0 || nlspp > 0 || nlsmm > 0)) { - continue; - } - - if (nuls > 0 || nlspp > 0 || nlsmm > 0) { - map_mixed_eventId_to_globalBC[collision.globalIndex()] = collision.globalBC(); - } // end of if pair exist - - } // end of collision loop - - for (int iz = 0; iz < static_cast(zvtx_bin_edges.size()) - 1; iz++) { - for (int icent = 0; icent < static_cast(cent_bin_edges.size()) - 1; icent++) { - for (int iep = 0; iep < static_cast(ep_bin_edges.size()) - 1; iep++) { - for (int iocc = 0; iocc < static_cast(occ_bin_edges.size()) - 1; iocc++) { - auto key_bin = std::make_tuple(iz, icent, iep, iocc); - - auto pairsULS = mapMixingULS[key_bin]; - auto pairsLSPP = mapMixingLSPP[key_bin]; - auto pairsLSMM = mapMixingLSMM[key_bin]; - LOGF(info, "iz = %d, icent = %d, iep = %d, iocc = %d, pairsULS.size() = %d, pairsLSPP.size() = %d, pairsLSMM.size() = %d", iz, icent, iep, iocc, pairsULS.size(), pairsLSPP.size(), pairsLSMM.size()); - - if (cfgDoULS) { - fillMixedPairInfo<0>(pairsULS); - } - if (cfgDoLS) { - fillMixedPairInfo<1>(pairsLSPP); - fillMixedPairInfo<2>(pairsLSMM); - } - - } // end of iocc loop - } // end of iep loop - } // end of icent loop - } // end of iz loop - - mapMixingULS.clear(); - mapMixingLSPP.clear(); - mapMixingLSMM.clear(); - map_mixed_eventId_to_globalBC.clear(); - } // end of DF - - void processAnalysis(filteredCollisions const& collisions, filteredDileptons const& dileptons) - { - runPairing(collisions, dileptons); - } - PROCESS_SWITCH(DileptonPolarization, processAnalysis, "run dilepton analysis", true); - - void processDummy(aod::EMThinEvents const&) {} - PROCESS_SWITCH(DileptonPolarization, processDummy, "Dummy function", false); -}; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"dilepton-polarization"})}; -} diff --git a/PWGEM/Dilepton/Tasks/dimuon.cxx b/PWGEM/Dilepton/Tasks/dimuon.cxx index a964f00a1c8..be0a7d8386b 100644 --- a/PWGEM/Dilepton/Tasks/dimuon.cxx +++ b/PWGEM/Dilepton/Tasks/dimuon.cxx @@ -25,5 +25,5 @@ using namespace o2::framework; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask>(cfgc, TaskName{"dimuon"})}; + adaptAnalysisTask>(cfgc, TaskName{"dimuon"})}; } diff --git a/PWGEM/Dilepton/Tasks/dimuonV1.cxx b/PWGEM/Dilepton/Tasks/dimuonV1.cxx new file mode 100644 index 00000000000..0fb52b31034 --- /dev/null +++ b/PWGEM/Dilepton/Tasks/dimuonV1.cxx @@ -0,0 +1,523 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// ======================== +// +// This code runs loop over leptons. +// Please write to: daiki.sekihata@cern.ch + +#include "PWGEM/Dilepton/Core/DimuonCut.h" +#include "PWGEM/Dilepton/Core/EMEventCut.h" +#include "PWGEM/Dilepton/DataModel/dileptonTables.h" +#include "PWGEM/Dilepton/Utils/EventHistograms.h" + +#include "Common/CCDB/RCTSelectionFlags.h" +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct dimuonV1 { + + // // Configurables + o2::framework::Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; + // o2::framework::Configurable cfgOccupancyEstimator{"cfgOccupancyEstimator", 0, "FT0C:0, Track:1"}; + // o2::framework::Configurable cfgDoMix{"cfgDoMix", false, "flag for event mixing"}; + // o2::framework::Configurable ndepth{"ndepth", 1000, "depth for event mixing"}; + // o2::framework::Configurable ndiff_bc_mix{"ndiff_bc_mix", 594, "difference in global BC required in mixed events"}; + // o2::framework::ConfigurableAxis ConfVtxBins{"ConfVtxBins", {o2::framework::VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; + // o2::framework::ConfigurableAxis ConfCentBins{"ConfCentBins", {o2::framework::VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f, 999.f}, "Mixing bins - centrality"}; + // o2::framework::ConfigurableAxis ConfEPBins{"ConfEPBins", {16, -M_PI / 2, +M_PI / 2}, "Mixing bins - event plane angle"}; + // o2::framework::ConfigurableAxis ConfOccupancyBins{"ConfOccupancyBins", {o2::framework::VARIABLE_WIDTH, -1, 1e+10}, "Mixing bins - occupancy"}; + + o2::framework::Configurable cfgApplyWeightTTCA{"cfgApplyWeightTTCA", false, "flag to apply weighting by 1/N"}; + + o2::framework::ConfigurableAxis ConfMllBins{"ConfMllBins", {o2::framework::VARIABLE_WIDTH, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20, 1.3, 1.4, 1.5, 2.00, 2.01, 2.02, 2.03, 2.04, 2.05, 2.06, 2.07, 2.08, 2.09, 2.1, 2.11, 2.12, 2.13, 2.14, 2.15, 2.16, 2.17, 2.18, 2.19, 2.2, 2.21, 2.22, 2.23, 2.24, 2.25, 2.26, 2.27, 2.28, 2.29, 2.3, 2.31, 2.32, 2.33, 2.34, 2.35, 2.36, 2.37, 2.38, 2.39, 2.4, 2.41, 2.42, 2.43, 2.44, 2.45, 2.46, 2.47, 2.48, 2.49, 2.5, 2.51, 2.52, 2.53, 2.54, 2.55, 2.56, 2.57, 2.58, 2.59, 2.6, 2.61, 2.62, 2.63, 2.64, 2.65, 2.66, 2.67, 2.68, 2.69, 2.7, 2.71, 2.72, 2.73, 2.74, 2.75, 2.76, 2.77, 2.78, 2.79, 2.8, 2.81, 2.82, 2.83, 2.84, 2.85, 2.86, 2.87, 2.88, 2.89, 2.9, 2.91, 2.92, 2.93, 2.94, 2.95, 2.96, 2.97, 2.98, 2.99, 3., 3.01, 3.02, 3.03, 3.04, 3.05, 3.06, 3.07, 3.08, 3.09, 3.1, 3.11, 3.12, 3.13, 3.14, 3.15, 3.16, 3.17, 3.18, 3.19, 3.2, 3.21, 3.22, 3.23, 3.24, 3.25, 3.26, 3.27, 3.28, 3.29, 3.3, 3.31, 3.32, 3.33, 3.34, 3.35, 3.36, 3.37, 3.38, 3.39, 3.4, 3.41, 3.42, 3.43, 3.44, 3.45, 3.46, 3.47, 3.48, 3.49, 3.5, 3.51, 3.52, 3.53, 3.54, 3.55, 3.56, 3.57, 3.58, 3.59, 3.6, 3.61, 3.62, 3.63, 3.64, 3.65, 3.66, 3.67, 3.68, 3.69, 3.7, 3.71, 3.72, 3.73, 3.74, 3.75, 3.76, 3.77, 3.78, 3.79, 3.8, 3.81, 3.82, 3.83, 3.84, 3.85, 3.86, 3.87, 3.88, 3.89, 3.9, 3.91, 3.92, 3.93, 3.94, 3.95, 3.96, 3.97, 3.98, 3.99, 4.0, 6.00, 6.10, 6.20, 6.30, 6.40, 6.50, 6.60, 6.70, 6.80, 6.90, 7.00, 7.10, 7.20, 7.30, 7.40, 7.50, 7.60, 7.70, 7.80, 7.90, 8.00, 8.10, 8.20, 8.30, 8.40, 8.50, 8.60, 8.70, 8.80, 8.90, 9.00, 9.10, 9.20, 9.30, 9.40, 9.50, 9.60, 9.70, 9.80, 9.90, 10.00, 10.10, 10.20, 10.30, 10.40, 10.50, 10.60, 10.70, 10.80, 10.90, 11.00, 11.1, 11.2, 11.3, 11.4, 11.5, 11.6, 11.7, 11.8, 11.9, 12.0}, "mmumu bins for output histograms"}; + + o2::framework::ConfigurableAxis ConfPtllBins{"ConfPtllBins", {10, 0, 10}, "pTll bins for output histograms"}; + o2::framework::ConfigurableAxis ConfYllBins{"ConfYllBins", {3, -4.0, -2.5}, "yll bins for output histograms"}; + o2::framework::ConfigurableAxis ConfUQBins{"ConfUQBins", {400, -1, 1}, "uQ bins for output histograms"}; + o2::framework::Configurable cfgNrotation{"cfgNrotation", 1, "number of rotation bkg"}; + o2::framework::Configurable cfgRandomSeed{"cfgRandomSeed", 1, "randam seed for rotation bkg"}; + o2::framework::Configurable cfgRotationMin{"cfgRotationMin", -M_PI / 4, "min. rotation angle for rotation bkg"}; + o2::framework::Configurable cfgRotationMax{"cfgRotationMax", +M_PI / 4, "max. rotation angle for rotation bkg"}; + + EMEventCut fEMEventCut; + struct : o2::framework::ConfigurableGroup { + std::string prefix = "eventcut_group"; + o2::framework::Configurable cfgZvtxMin{"cfgZvtxMin", -10.f, "min. Zvtx"}; + o2::framework::Configurable cfgZvtxMax{"cfgZvtxMax", +10.f, "max. Zvtx"}; + o2::framework::Configurable cfgRequireSel8{"cfgRequireSel8", false, "require sel8 in event cut"}; + o2::framework::Configurable cfgRequireFT0AND{"cfgRequireFT0AND", true, "require FT0AND in event cut"}; + o2::framework::Configurable cfgRequireNoTFB{"cfgRequireNoTFB", true, "require No time frame border in event cut"}; + o2::framework::Configurable cfgRequireNoITSROFB{"cfgRequireNoITSROFB", true, "require no ITS readout frame border in event cut"}; + o2::framework::Configurable cfgRequireNoSameBunchPileup{"cfgRequireNoSameBunchPileup", true, "require no same bunch pileup in event cut"}; + o2::framework::Configurable cfgRequireVertexITSTPC{"cfgRequireVertexITSTPC", false, "require Vertex ITSTPC in event cut"}; // ITS-TPC matched track contributes PV. + o2::framework::Configurable cfgRequireVertexTOFmatched{"cfgRequireVertexTOFmatched", false, "require Vertex TOFmatched in event cut"}; // ITS-TPC-TOF matched track contributes PV. + o2::framework::Configurable cfgRequireGoodZvtxFT0vsPV{"cfgRequireGoodZvtxFT0vsPV", true, "require good Zvtx between FT0 vs. PV in event cut"}; + o2::framework::Configurable cfgTrackOccupancyMin{"cfgTrackOccupancyMin", -2, "min. occupancy"}; + o2::framework::Configurable cfgTrackOccupancyMax{"cfgTrackOccupancyMax", 1000000000, "max. occupancy"}; + o2::framework::Configurable cfgFT0COccupancyMin{"cfgFT0COccupancyMin", -2, "min. FT0C occupancy"}; + o2::framework::Configurable cfgFT0COccupancyMax{"cfgFT0COccupancyMax", 1000000000, "max. FT0C occupancy"}; + + // o2::framework::Configurable cfgRequireNoCollInTimeRangeStandard{"cfgRequireNoCollInTimeRangeStandard", false, "require no collision in time range standard"}; + // o2::framework::Configurable cfgRequireNoCollInTimeRangeStrict{"cfgRequireNoCollInTimeRangeStrict", false, "require no collision in time range strict"}; + // o2::framework::Configurable cfgRequireNoCollInITSROFStandard{"cfgRequireNoCollInITSROFStandard", false, "require no collision in time range standard"}; + // o2::framework::Configurable cfgRequireNoCollInITSROFStrict{"cfgRequireNoCollInITSROFStrict", false, "require no collision in time range strict"}; + // o2::framework::Configurable cfgRequireNoHighMultCollInPrevRof{"cfgRequireNoHighMultCollInPrevRof", false, "require no HM collision in previous ITS ROF"}; + // o2::framework::Configurable cfgRequireGoodITSLayer3{"cfgRequireGoodITSLayer3", false, "number of inactive chips on ITS layer 3 are below threshold "}; + // o2::framework::Configurable cfgRequireGoodITSLayer0123{"cfgRequireGoodITSLayer0123", false, "number of inactive chips on ITS layers 0-3 are below threshold "}; + // o2::framework::Configurable cfgRequireGoodITSLayersAll{"cfgRequireGoodITSLayersAll", false, "number of inactive chips on all ITS layers are below threshold "}; + // for RCT + o2::framework::Configurable cfgRequireGoodRCT{"cfgRequireGoodRCT", true, "require good detector flag in run condtion table"}; + o2::framework::Configurable cfgRCTLabel{"cfgRCTLabel", "CBT_muon", "select 1 [CBT, CBT_hadronPID, CBT_muon_glo] see O2Physics/Common/CCDB/RCTSelectionFlags.h"}; + o2::framework::Configurable cfgCheckZDC{"cfgCheckZDC", true, "set ZDC flag for PbPb"}; + o2::framework::Configurable cfgTreatLimitedAcceptanceAsBad{"cfgTreatLimitedAcceptanceAsBad", false, "reject all events where the detectors relevant for the specified Runlist are flagged as LimitedAcceptance"}; + + o2::framework::Configurable cfgCentMin{"cfgCentMin", -1, "min. centrality"}; + o2::framework::Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; + o2::framework::Configurable cfgNumContribMin{"cfgNumContribMin", 0, "min. numContrib"}; + o2::framework::Configurable cfgNumContribMax{"cfgNumContribMax", 65000, "max. numContrib"}; + } eventcuts; + + DimuonCut fDimuonCut; + struct : o2::framework::ConfigurableGroup { + std::string prefix = "dimuoncut_group"; + o2::framework::Configurable cfg_min_mass{"cfg_min_mass", 0.0, "min mass"}; + o2::framework::Configurable cfg_max_mass{"cfg_max_mass", 1e+10, "max mass"}; + o2::framework::Configurable cfg_min_pair_pt{"cfg_min_pair_pt", 0.0, "min pair pt"}; + o2::framework::Configurable cfg_max_pair_pt{"cfg_max_pair_pt", 1e+10, "max pair pt"}; + o2::framework::Configurable cfg_min_pair_y{"cfg_min_pair_y", -4.0, "min pair rapidity"}; + o2::framework::Configurable cfg_max_pair_y{"cfg_max_pair_y", -2.5, "max pair rapidity"}; + o2::framework::Configurable cfg_min_pair_dcaxy{"cfg_min_pair_dcaxy", 0.0, "min pair dca3d in sigma"}; + o2::framework::Configurable cfg_max_pair_dcaxy{"cfg_max_pair_dcaxy", 1e+10, "max pair dca3d in sigma"}; + o2::framework::Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut"}; + o2::framework::Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 muons (elliptic cut)"}; + o2::framework::Configurable cfg_min_dphi{"cfg_min_dphi", 0.02, "min dphi between 2 muons (elliptic cut)"}; + + // o2::framework::Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; + o2::framework::Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.8, "min pT for single track"}; + o2::framework::Configurable cfg_max_pt_track{"cfg_max_pt_track", 1e+10, "max pT for single track"}; + o2::framework::Configurable cfg_min_eta_track{"cfg_min_eta_track", -4.0, "min eta for single track"}; + o2::framework::Configurable cfg_max_eta_track{"cfg_max_eta_track", -2.5, "max eta for single track"}; + o2::framework::Configurable cfg_min_phi_track{"cfg_min_phi_track", 0.f, "min phi for single track"}; + o2::framework::Configurable cfg_max_phi_track{"cfg_max_phi_track", 6.3, "max phi for single track"}; + o2::framework::Configurable cfg_min_ncluster_mft{"cfg_min_ncluster_mft", 5, "min ncluster MFT"}; + o2::framework::Configurable cfg_min_ncluster_mch{"cfg_min_ncluster_mch", 5, "min ncluster MCH"}; + o2::framework::Configurable cfg_max_chi2{"cfg_max_chi2", 1e+6, "max chi2/ndf"}; + o2::framework::Configurable cfg_max_chi2mft{"cfg_max_chi2mft", 1e+6, "max chi2/ndf"}; + o2::framework::Configurable cfg_border_pt_for_chi2mchmft{"cfg_border_pt_for_chi2mchmft", 0, "border pt for different max chi2 for MFT-MCH matching"}; + o2::framework::Configurable cfg_max_matching_chi2_mftmch_lowPt{"cfg_max_matching_chi2_mftmch_lowPt", 8, "max chi2 for MFT-MCH matching for low pT"}; + o2::framework::Configurable cfg_max_matching_chi2_mftmch_highPt{"cfg_max_matching_chi2_mftmch_highPt", 40, "max chi2 for MFT-MCH matching for high pT"}; + o2::framework::Configurable cfg_max_matching_chi2_mchmid{"cfg_max_matching_chi2_mchmid", 1e+10, "max chi2 for MCH-MID matching"}; + o2::framework::Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1e+10, "max dca XY for single track in cm"}; + o2::framework::Configurable cfg_min_rabs{"cfg_min_rabs", 17.6, "min Radius at the absorber end"}; + o2::framework::Configurable cfg_max_rabs{"cfg_max_rabs", 89.5, "max Radius at the absorber end"}; + o2::framework::Configurable cfg_max_diff_chi2_mftmch{"cfg_max_diff_chi2_mftmch", -1.f, "max. diff chi2MatchingMCHMFT between the best and the 2nd best matched candidates"}; + o2::framework::Configurable enableTTCA{"enableTTCA", false, "Flag to enable or disable TTCA"}; + o2::framework::Configurable cfg_max_relDPt_wrt_matchedMCHMID{"cfg_max_relDPt_wrt_matchedMCHMID", 1e+10f, "max. relative dpt between MFT-MCH-MID and MCH-MID"}; + o2::framework::Configurable cfg_max_DEta_wrt_matchedMCHMID{"cfg_max_DEta_wrt_matchedMCHMID", 1e+10f, "max. deta between MFT-MCH-MID and MCH-MID"}; + o2::framework::Configurable cfg_max_DPhi_wrt_matchedMCHMID{"cfg_max_DPhi_wrt_matchedMCHMID", 1e+10f, "max. dphi between MFT-MCH-MID and MCH-MID"}; + o2::framework::Configurable requireMFTHitMap{"requireMFTHitMap", false, "flag to apply MFT hit map"}; + o2::framework::Configurable> requiredMFTDisks{"requiredMFTDisks", std::vector{0}, "hit map on MFT disks [0,1,2,3,4]. logical-OR of each double-sided disk"}; + } dimuoncuts; + + o2::aod::rctsel::RCTFlagsChecker rctChecker; + int mRunNumber{0}; + std::mt19937 engine; + std::uniform_real_distribution distDPhi; + + o2::framework::HistogramRegistry fRegistry{"output", {}, o2::framework::OutputObjHandlingPolicy::AnalysisObject, false, false}; + static constexpr std::string_view event_pair_types[2] = {"same/", "mix/"}; + + void init(o2::framework::InitContext& /*context*/) + { + mRunNumber = 0; + + // std::random_device seed_gen; + engine = std::mt19937(cfgRandomSeed); + distDPhi = std::uniform_real_distribution(cfgRotationMin, cfgRotationMax); + + rctChecker.init(eventcuts.cfgRCTLabel.value, eventcuts.cfgCheckZDC.value, eventcuts.cfgTreatLimitedAcceptanceAsBad.value); + + // emh_pos = new MyEMH_muon(ndepth); + // emh_neg = new MyEMH_muon(ndepth); + + addhistograms(); + DefineEMEventCut(); + DefineDimuonCut(); + } + + template + void initCCDB(TCollision const& collision) + { + if (mRunNumber == collision.runNumber()) { + return; + } + mRunNumber = collision.runNumber(); + } + + ~dimuonV1() + { + // delete emh_pos; + // emh_pos = 0x0; + // delete emh_neg; + // emh_neg = 0x0; + } + + void addhistograms() + { + // event info + o2::aod::pwgem::dilepton::utils::eventhistogram::addEventHistograms<-1>(&fRegistry); + + fRegistry.add("Event/before/ZDC/hQxt", "Q_{x}^{t} vs. centrality;centrality FT0C (%);Q_{x}^{t}", o2::framework::HistType::kTH2D, {{110, 0, 110}, {200, -1, +1}}, false); + fRegistry.add("Event/before/ZDC/hQyt", "Q_{y}^{t} vs. centrality;centrality FT0C (%);Q_{y}^{t}", o2::framework::HistType::kTH2D, {{110, 0, 110}, {200, -1, +1}}, false); + fRegistry.add("Event/before/ZDC/hQxp", "Q_{x}^{p} vs. centrality;centrality FT0C (%);Q_{x}^{p}", o2::framework::HistType::kTH2D, {{110, 0, 110}, {200, -1, +1}}, false); + fRegistry.add("Event/before/ZDC/hQyp", "Q_{y}^{p} vs. centrality;centrality FT0C (%);Q_{y}^{p}", o2::framework::HistType::kTH2D, {{110, 0, 110}, {200, -1, +1}}, false); + + fRegistry.add("Event/before/ZDC/hQxtQxp", "Q_{x}^{t} #upoint Q_{x}^{p} vs. centrality;centrality FT0C (%);Q_{x}^{t} #upoint Q_{x}^{p}", o2::framework::HistType::kTH2D, {{110, 0, 110}, {1000, -1, +1}}, false); + fRegistry.add("Event/before/ZDC/hQytQyp", "Q_{y}^{t} #upoint Q_{y}^{p} vs. centrality;centrality FT0C (%);Q_{y}^{t} #upoint Q_{y}^{p}", o2::framework::HistType::kTH2D, {{110, 0, 110}, {1000, -1, +1}}, false); + fRegistry.add("Event/before/ZDC/hQxtQyp", "Q_{x}^{t} #upoint Q_{y}^{p} vs. centrality;centrality FT0C (%);Q_{x}^{t} #upoint Q_{y}^{p}", o2::framework::HistType::kTH2D, {{110, 0, 110}, {1000, -1, +1}}, false); + fRegistry.add("Event/before/ZDC/hQytQxp", "Q_{y}^{t} #upoint Q_{x}^{p} vs. centrality;centrality FT0C (%);Q_{y}^{t} #upoint Q_{x}^{p}", o2::framework::HistType::kTH2D, {{110, 0, 110}, {1000, -1, +1}}, false); + fRegistry.addClone("Event/before/ZDC/", "Event/after/ZDC/"); + + // pair info + const o2::framework::AxisSpec axis_mass{ConfMllBins, "m_{#mu#mu} (GeV/c^{2})"}; + const o2::framework::AxisSpec axis_pt{ConfPtllBins, "p_{T,#mu#mu} (GeV/c)"}; + const o2::framework::AxisSpec axis_y{ConfYllBins, "y_{#mu#mu}"}; + const o2::framework::AxisSpec axis_uxQxt{ConfUQBins, "u_{x}Q_{x}^{t}"}; + const o2::framework::AxisSpec axis_uxQxp{ConfUQBins, "u_{x}Q_{x}^{p}"}; + const o2::framework::AxisSpec axis_uyQyt{ConfUQBins, "u_{y}Q_{y}^{t}"}; + const o2::framework::AxisSpec axis_uyQyp{ConfUQBins, "u_{y}Q_{y}^{p}"}; + + fRegistry.add("Pair/same/uls/hs", "dilepton", o2::framework::HistType::kTHnSparseD, {axis_mass, axis_pt, axis_y, axis_uxQxt, axis_uxQxp, axis_uyQyt, axis_uyQyp}, true); + fRegistry.add("Pair/same/uls/hsRotBkg", "dilepton", o2::framework::HistType::kTHnSparseD, {axis_mass, axis_pt, axis_y}, true); + + // fRegistry.addClone("Pair/same/uls/", "Pair/same/lspp/"); + // fRegistry.addClone("Pair/same/uls/", "Pair/same/lsmm/"); + // fRegistry.addClone("Pair/same/", "Pair/mix/"); + } + + void DefineEMEventCut() + { + fEMEventCut = EMEventCut("fEMEventCut", "fEMEventCut"); + fEMEventCut.SetRequireSel8(eventcuts.cfgRequireSel8); + fEMEventCut.SetRequireFT0AND(eventcuts.cfgRequireFT0AND); + fEMEventCut.SetZvtxRange(eventcuts.cfgZvtxMin, eventcuts.cfgZvtxMax); + fEMEventCut.SetRequireNoTFB(eventcuts.cfgRequireNoTFB); + fEMEventCut.SetRequireNoITSROFB(eventcuts.cfgRequireNoITSROFB); + fEMEventCut.SetRequireNoSameBunchPileup(eventcuts.cfgRequireNoSameBunchPileup); + fEMEventCut.SetRequireVertexITSTPC(eventcuts.cfgRequireVertexITSTPC); + fEMEventCut.SetRequireVertexTOFmatched(eventcuts.cfgRequireVertexTOFmatched); + fEMEventCut.SetRequireGoodZvtxFT0vsPV(eventcuts.cfgRequireGoodZvtxFT0vsPV); + // fEMEventCut.SetRequireNoCollInTimeRangeStandard(eventcuts.cfgRequireNoCollInTimeRangeStandard); + // fEMEventCut.SetRequireNoCollInTimeRangeStrict(eventcuts.cfgRequireNoCollInTimeRangeStrict); + // fEMEventCut.SetRequireNoCollInITSROFStandard(eventcuts.cfgRequireNoCollInITSROFStandard); + // fEMEventCut.SetRequireNoCollInITSROFStrict(eventcuts.cfgRequireNoCollInITSROFStrict); + // fEMEventCut.SetRequireNoHighMultCollInPrevRof(eventcuts.cfgRequireNoHighMultCollInPrevRof); + // fEMEventCut.SetRequireGoodITSLayer3(eventcuts.cfgRequireGoodITSLayer3); + // fEMEventCut.SetRequireGoodITSLayer0123(eventcuts.cfgRequireGoodITSLayer0123); + // fEMEventCut.SetRequireGoodITSLayersAll(eventcuts.cfgRequireGoodITSLayersAll); + } + + void DefineDimuonCut() + { + fDimuonCut = DimuonCut("fDimuonCut", "fDimuonCut"); + + // for pair + fDimuonCut.SetMassRange(dimuoncuts.cfg_min_mass, dimuoncuts.cfg_max_mass); + fDimuonCut.SetPairPtRange(dimuoncuts.cfg_min_pair_pt, dimuoncuts.cfg_max_pair_pt); + fDimuonCut.SetPairYRange(dimuoncuts.cfg_min_pair_y, dimuoncuts.cfg_max_pair_y); + fDimuonCut.SetPairDCAxyRange(dimuoncuts.cfg_min_pair_dcaxy, dimuoncuts.cfg_max_pair_dcaxy); + fDimuonCut.SetMindEtadPhi(dimuoncuts.cfg_apply_detadphi, dimuoncuts.cfg_min_deta, dimuoncuts.cfg_min_dphi); + + // for track + // fDimuonCut.SetTrackType(dimuoncuts.cfg_track_type); + fDimuonCut.SetTrackType(3); + fDimuonCut.SetTrackPtRange(dimuoncuts.cfg_min_pt_track, dimuoncuts.cfg_max_pt_track); + fDimuonCut.SetTrackEtaRange(dimuoncuts.cfg_min_eta_track, dimuoncuts.cfg_max_eta_track); + fDimuonCut.SetTrackPhiRange(dimuoncuts.cfg_min_phi_track, dimuoncuts.cfg_max_phi_track); + fDimuonCut.SetNClustersMFT(dimuoncuts.cfg_min_ncluster_mft, 10); + fDimuonCut.SetNClustersMCHMID(dimuoncuts.cfg_min_ncluster_mch, 20); + fDimuonCut.SetChi2(0.f, dimuoncuts.cfg_max_chi2); + fDimuonCut.SetChi2MFT(0.f, dimuoncuts.cfg_max_chi2mft); + fDimuonCut.SetMaxDiffMatchingChi2MCHMFT(dimuoncuts.cfg_max_diff_chi2_mftmch); + fDimuonCut.SetMaxMatchingChi2MCHMFTPtDep([&](float pt) { return (pt < dimuoncuts.cfg_border_pt_for_chi2mchmft ? dimuoncuts.cfg_max_matching_chi2_mftmch_lowPt : dimuoncuts.cfg_max_matching_chi2_mftmch_highPt); }); + fDimuonCut.SetMatchingChi2MCHMID(0.f, dimuoncuts.cfg_max_matching_chi2_mchmid); + fDimuonCut.SetDCAxy(0.f, dimuoncuts.cfg_max_dcaxy); + fDimuonCut.SetRabs(dimuoncuts.cfg_min_rabs, dimuoncuts.cfg_max_rabs); + fDimuonCut.SetMaxPDCARabsDep([&](float rabs) { return (rabs < 26.5 ? 594.f : 324.f); }); + fDimuonCut.SetMaxdPtdEtadPhiwrtMCHMID(dimuoncuts.cfg_max_relDPt_wrt_matchedMCHMID, dimuoncuts.cfg_max_DEta_wrt_matchedMCHMID, dimuoncuts.cfg_max_DPhi_wrt_matchedMCHMID); // this is relevant for global muons + fDimuonCut.SetMFTHitMap(dimuoncuts.requireMFTHitMap, dimuoncuts.requiredMFTDisks); + fDimuonCut.EnableTTCA(dimuoncuts.enableTTCA); + } + + template + bool fillPairInfo(TCollision const& collision, TTrack1 const& t1, TTrack2 const& t2, TCut const& cut) + { + if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { + return false; + } + + if (!cut.IsSelectedPair(t1, t2)) { + return false; + } + + float weight = 1.f; + if constexpr (ev_id == 0) { + if (cfgApplyWeightTTCA) { + weight = map_weight[std::make_pair(t1.globalIndex(), t2.globalIndex())]; + } + } + + ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), RecoDecay::constrainAngle(t1.phi(), 0, 1U), o2::constants::physics::MassMuon); + ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), RecoDecay::constrainAngle(t2.phi(), 0, 1U), o2::constants::physics::MassMuon); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + float phi = RecoDecay::constrainAngle(v12.Phi(), 0, 1U); + + // TODO : implement correction for NUA + float uxQxt = std::cos(1.f * phi) * collision.qxZDCC(); + float uxQxp = std::cos(1.f * phi) * collision.qxZDCA(); + float uyQyt = std::sin(1.f * phi) * collision.qyZDCC(); + float uyQyp = std::sin(1.f * phi) * collision.qyZDCA(); + + if (t1.sign() * t2.sign() < 0) { // ULS + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), v12.Rapidity(), uxQxt, uxQxp, uyQyt, uyQyp, weight); + + for (int i = 0; i < cfgNrotation; i++) { + float dphi = distDPhi(engine); + ROOT::Math::PtEtaPhiMVector v2rot(t2.pt(), t2.eta(), RecoDecay::constrainAngle(t2.phi() + M_PI + dphi, 0, 1U), o2::constants::physics::MassMuon); + ROOT::Math::PtEtaPhiMVector v12bkg = v1 + v2rot; + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hsRotBkg"), v12bkg.M(), v12bkg.Pt(), v12bkg.Rapidity(), weight * 1.f / static_cast(cfgNrotation)); + } + + // } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ + // fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), v12.Rapidity(), uxQxt, uxQxp, uyQyt, uyQyp, weight); + // } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- + // fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), v12.Rapidity(), uxQxt, uxQxp, uyQyt, uyQyp, weight); + } + return true; + } + + template + void runPairing(TCollisions const& collisions, TLeptons const& posTracks, TLeptons const& negTracks, TPresilce const& perCollision, TCut const& cut) + { + for (const auto& collision : collisions) { + initCCDB(collision); + + float centrality = std::array{collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}[cfgCentEstimator]; + if (centrality < eventcuts.cfgCentMin || eventcuts.cfgCentMax < centrality) { + continue; + } + o2::aod::pwgem::dilepton::utils::eventhistogram::fillEventInfo<0, -1>(&fRegistry, collision); + + float QxtQxp = collision.qxZDCA() * collision.qxZDCC(); + float QytQyp = collision.qyZDCA() * collision.qyZDCC(); + float QytQxp = collision.qxZDCA() * collision.qyZDCC(); + float QxtQyp = collision.qxZDCC() * collision.qyZDCA(); + + fRegistry.fill(HIST("Event/before/ZDC/hQxt"), centrality, collision.qxZDCC()); + fRegistry.fill(HIST("Event/before/ZDC/hQyt"), centrality, collision.qyZDCC()); + fRegistry.fill(HIST("Event/before/ZDC/hQxp"), centrality, collision.qxZDCA()); + fRegistry.fill(HIST("Event/before/ZDC/hQyp"), centrality, collision.qyZDCA()); + + fRegistry.fill(HIST("Event/before/ZDC/hQxtQxp"), centrality, QxtQxp); + fRegistry.fill(HIST("Event/before/ZDC/hQytQyp"), centrality, QytQyp); + fRegistry.fill(HIST("Event/before/ZDC/hQxtQyp"), centrality, QxtQyp); + fRegistry.fill(HIST("Event/before/ZDC/hQytQxp"), centrality, QytQxp); + + if (!fEMEventCut.IsSelected(collision)) { + continue; + } + if (eventcuts.cfgRequireGoodRCT && !rctChecker.checkTable(collision)) { + continue; + } + + o2::aod::pwgem::dilepton::utils::eventhistogram::fillEventInfo<1, -1>(&fRegistry, collision); + + fRegistry.fill(HIST("Event/before/hCollisionCounter"), o2::aod::pwgem::dilepton::utils::eventhistogram::nbin_ev); // accepted + fRegistry.fill(HIST("Event/after/hCollisionCounter"), o2::aod::pwgem::dilepton::utils::eventhistogram::nbin_ev); // accepted + + fRegistry.fill(HIST("Event/after/ZDC/hQxt"), centrality, collision.qxZDCC()); + fRegistry.fill(HIST("Event/after/ZDC/hQyt"), centrality, collision.qyZDCC()); + fRegistry.fill(HIST("Event/after/ZDC/hQxp"), centrality, collision.qxZDCA()); + fRegistry.fill(HIST("Event/after/ZDC/hQyp"), centrality, collision.qyZDCA()); + + fRegistry.fill(HIST("Event/after/ZDC/hQxtQxp"), centrality, QxtQxp); + fRegistry.fill(HIST("Event/after/ZDC/hQytQyp"), centrality, QytQyp); + fRegistry.fill(HIST("Event/after/ZDC/hQxtQyp"), centrality, QxtQyp); + fRegistry.fill(HIST("Event/after/ZDC/hQytQxp"), centrality, QytQxp); + + auto posTracks_per_coll = posTracks.sliceByCached(perCollision, collision.globalIndex(), cache); + auto negTracks_per_coll = negTracks.sliceByCached(perCollision, collision.globalIndex(), cache); + + for (const auto& [pos, neg] : combinations(o2::soa::CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS + fillPairInfo<0>(collision, pos, neg, cut); + } + + // for (const auto& [pos1, pos2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ + // fillPairInfo<0>(collision, pos1, pos2, cut); + // } + // for (const auto& [neg1, neg2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- + // fillPairInfo<0>(collision, neg1, neg2, cut); + // } + + } // end of collision loop + } // end of DF + + template + bool isPairOK(TTrack1 const& t1, TTrack2 const& t2, TCut const& cut) + { + if (!cut.IsSelectedTrack(t1) || !cut.IsSelectedTrack(t2)) { + return false; + } + + if (!cut.IsSelectedPair(t1, t2)) { + return false; + } + return true; + } + + std::map, float> map_weight; // -> float + template + void fillPairWeightMap(TCollisions const& collisions, TLeptons const& posTracks, TLeptons const& negTracks, TPresilce const& perCollision, TCut const& cut, TAllTracks const& tracks) + { + std::vector> passed_pairIds; + passed_pairIds.reserve(posTracks.size() * negTracks.size()); + + for (const auto& collision : collisions) { + initCCDB(collision); + float centrality = std::array{collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}[cfgCentEstimator]; + if (centrality < eventcuts.cfgCentMin || eventcuts.cfgCentMax < centrality) { + continue; + } + + if (!fEMEventCut.IsSelected(collision)) { + continue; + } + if (eventcuts.cfgRequireGoodRCT && !rctChecker.checkTable(collision)) { + continue; + } + + auto posTracks_per_coll = posTracks.sliceByCached(perCollision, collision.globalIndex(), cache); + auto negTracks_per_coll = negTracks.sliceByCached(perCollision, collision.globalIndex(), cache); + + for (const auto& [pos, neg] : combinations(o2::soa::CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS + if (isPairOK(pos, neg, cut)) { + passed_pairIds.emplace_back(std::make_pair(pos.globalIndex(), neg.globalIndex())); + } + } + for (const auto& [pos1, pos2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ + if (isPairOK(pos1, pos2, cut)) { + passed_pairIds.emplace_back(std::make_pair(pos1.globalIndex(), pos2.globalIndex())); + } + } + for (const auto& [neg1, neg2] : combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- + if (isPairOK(neg1, neg2, cut)) { + passed_pairIds.emplace_back(std::make_pair(neg1.globalIndex(), neg2.globalIndex())); + } + } + } // end of collision loop + + for (const auto& pairId : passed_pairIds) { + auto t1 = tracks.rawIteratorAt(std::get<0>(pairId)); + auto t2 = tracks.rawIteratorAt(std::get<1>(pairId)); + + float n = 1.f; // include myself. + for (const auto& ambId1 : t1.ambiguousMuonsIds()) { + for (const auto& ambId2 : t2.ambiguousMuonsIds()) { + if (std::find(passed_pairIds.begin(), passed_pairIds.end(), std::make_pair(ambId1, ambId2)) != passed_pairIds.end()) { + n += 1.f; + } + } + } + map_weight[pairId] = 1.f / n; + } // end of passed_pairIds loop + passed_pairIds.clear(); + passed_pairIds.shrink_to_fit(); + } + + using MyCollisions = o2::soa::Join; + using MyCollision = MyCollisions::iterator; + + using MyMuons = o2::soa::Join; + using MyMuon = MyMuons::iterator; + + // using MyEMH_muon = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, o2::aod::pwgem::dilepton::utils::EMFwdTrack>; + + o2::framework::expressions::Filter collisionFilter_centrality = (eventcuts.cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < eventcuts.cfgCentMax) || (eventcuts.cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < eventcuts.cfgCentMax) || (eventcuts.cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < eventcuts.cfgCentMax); + o2::framework::expressions::Filter collisionFilter_numContrib = eventcuts.cfgNumContribMin <= o2::aod::collision::numContrib && o2::aod::collision::numContrib < eventcuts.cfgNumContribMax; + o2::framework::expressions::Filter collisionFilter_occupancy_track = eventcuts.cfgTrackOccupancyMin <= o2::aod::evsel::trackOccupancyInTimeRange && o2::aod::evsel::trackOccupancyInTimeRange < eventcuts.cfgTrackOccupancyMax; + o2::framework::expressions::Filter collisionFilter_occupancy_ft0c = eventcuts.cfgFT0COccupancyMin <= o2::aod::evsel::ft0cOccupancyInTimeRange && o2::aod::evsel::ft0cOccupancyInTimeRange < eventcuts.cfgFT0COccupancyMax; + using FilteredMyCollisions = o2::soa::Filtered; + using FilteredMyCollision = FilteredMyCollisions::iterator; + + o2::framework::SliceCache cache; + o2::framework::Preslice perCollision_muon = o2::aod::emprimarymuon::emeventId; + + o2::framework::expressions::Filter trackFilter_muon = o2::aod::fwdtrack::trackType == static_cast(o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) && dimuoncuts.cfg_min_pt_track < o2::aod::fwdtrack::pt && o2::aod::fwdtrack::pt < dimuoncuts.cfg_max_pt_track && dimuoncuts.cfg_min_eta_track < o2::aod::fwdtrack::eta && o2::aod::fwdtrack::eta < dimuoncuts.cfg_max_eta_track; + o2::framework::expressions::Filter ttcaFilter_muon = ifnode(dimuoncuts.enableTTCA.node(), true, o2::aod::emprimarymuon::isAssociatedToMPC == true); + using FilteredMyMuons = o2::soa::Filtered; + using FilteredMyMuon = FilteredMyMuons::iterator; + + o2::framework::Partition positive_muons = o2::aod::emprimarymuon::sign > int8_t(0); + o2::framework::Partition negative_muons = o2::aod::emprimarymuon::sign < int8_t(0); + + // MyEMH_muon* emh_pos = nullptr; + // MyEMH_muon* emh_neg = nullptr; + + void processAnalysis(FilteredMyCollisions const& collisions, FilteredMyMuons const& muons) + { + if (cfgApplyWeightTTCA) { + fillPairWeightMap(collisions, positive_muons, negative_muons, o2::aod::emprimarymuon::emeventId, fDimuonCut, muons); + } + runPairing(collisions, positive_muons, negative_muons, o2::aod::emprimarymuon::emeventId, fDimuonCut); + } + PROCESS_SWITCH(dimuonV1, processAnalysis, "run dimuon v1 analysis", true); + + void processDummy(MyCollisions const&) {} + PROCESS_SWITCH(dimuonV1, processDummy, "Dummy function", false); +}; +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +{ + return o2::framework::WorkflowSpec{adaptAnalysisTask(cfgc, o2::framework::TaskName{"dimuon-v1"})}; +} diff --git a/PWGEM/Dilepton/Tasks/studyDCAFitter.cxx b/PWGEM/Dilepton/Tasks/studyDCAFitter.cxx index c2da23e382e..0383fe3868c 100644 --- a/PWGEM/Dilepton/Tasks/studyDCAFitter.cxx +++ b/PWGEM/Dilepton/Tasks/studyDCAFitter.cxx @@ -24,17 +24,17 @@ #include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/PIDResponseTOF.h" -#include "Common/DataModel/PIDResponseTPC.h" #include #include +#include #include -// #include #include #include #include #include +#include // for PV refit +#include #include #include #include @@ -45,6 +45,8 @@ #include #include #include +#include +#include // for PV refit #include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) #include @@ -52,13 +54,14 @@ #include #include +#include #include #include #include -#include -#include #include +#include + using namespace o2; using namespace o2::soa; using namespace o2::framework; @@ -70,6 +73,7 @@ using namespace o2::aod::pwgem::dilepton::utils::pairutil; struct studyDCAFitter { using MyCollisions = soa::Join; using MyTracks = soa::Join; + using MyTrack = MyTracks::iterator; using MyBCs = soa::Join; Produces eventTable; @@ -110,7 +114,6 @@ struct studyDCAFitter { struct : ConfigurableGroup { std::string prefix = "eventCut"; - Configurable cfgEventGeneratorType{"cfgEventGeneratorType", -1, "if positive, select event generator type. i.e. gap or signal"}; Configurable cfgRejectEventGenerator{"cfgRejectEventGenerator", 999, "reject event generator. e.g. reject tracks from gap events"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; Configurable cfgCentMin{"cfgCentMin", -1.f, "min. centrality"}; @@ -234,9 +237,28 @@ struct studyDCAFitter { fRegistry.add("Event/hCentFT0CvsMultNTracksPV", "hCentFT0CvsMultNTracksPV;centrality FT0C (%);N_{track} to PV", kTH2F, {{110, 0, 110}, {600, 0, 6000}}, false); fRegistry.add("Event/hMultFT0CvsMultNTracksPV", "hMultFT0CvsMultNTracksPV;mult. FT0C;N_{track} to PV", kTH2F, {{60, 0, 60000}, {600, 0, 6000}}, false); + // fRegistry.add("Event/refitPV/remove/hNContrib", "hNContrib;before;after", kTH2F, {{1001, -0.5, 1000.5}, {1001, -0.5, 1000.5}}, false); + // fRegistry.add("Event/refitPV/remove/hChi2", "hChi2;before;after", kTH2F, {{100, 0, 1000}, {100, 0, 1000}}, false); + // fRegistry.add("Event/refitPV/remove/hDeltaXvsNContrib", "hDeltaXvsNContrib;numContrib after;X_{after} - X_{before} (cm)", kTH2F, {{1001, -0.5, 1000.5}, {200, -0.01, 0.01}}, false); + // fRegistry.add("Event/refitPV/remove/hDeltaYvsNContrib", "hDeltaYvsNContrib;numContrib after;Y_{after} - Y_{before} (cm)", kTH2F, {{1001, -0.5, 1000.5}, {200, -0.01, 0.01}}, false); + // fRegistry.add("Event/refitPV/remove/hDeltaZvsNContrib", "hDeltaZvsNContrib;numContrib after;Z_{after} - Z_{before} (cm)", kTH2F, {{1001, -0.5, 1000.5}, {200, -0.01, 0.01}}, false); + // fRegistry.addClone("Event/refitPV/remove/", "Event/refitPV/add/"); + const o2::framework::AxisSpec axis_mass{ConfMllBins, "m_{ll} (GeV/c^{2})"}; const o2::framework::AxisSpec axis_pt{ConfPtllBins, "p_{T,ee} (GeV/c)"}; const o2::framework::AxisSpec axis_dca{ConfDCAllBins, "DCA_{ee}^{3D} (#sigma)"}; + // const o2::framework::AxisSpec axis_dca_remove1track{ConfDCAllBins, "DCA_{ee}^{3D, remove 1 track} (#sigma)"}; + // const o2::framework::AxisSpec axis_dca_remove2track{ConfDCAllBins, "DCA_{ee}^{3D, remove 2 tracks} (#sigma)"}; + + // for single tracks + fRegistry.add("Track/Zboson/hs", "hs;p_{T,e} (GeV/c);#eta_{e};#varphi_{e} (rad);DCA_{e}^{3D} (#sigma);", kTHnSparseF, {{100, 0, 10}, {20, -1, +1}, {36, 0, 2 * M_PI}, {100, 0, 10}}, false); + // fRegistry.add("Track/Zboson/hChi2PV", "log_{10}(#chi^{2}_{IP})", kTH1F, {{400, -200, 200}}, false); + // fRegistry.add("Track/Zboson/hDiffDCAinSigma3D", "diff DCA 3D(#sigma)", kTH1F, {{200, -10, 10}}, false); + fRegistry.addClone("Track/Zboson/", "Track/PromptJpsi/"); + fRegistry.addClone("Track/Zboson/", "Track/NonPromptJpsi/"); + fRegistry.addClone("Track/Zboson/", "Track/c2e/"); + fRegistry.addClone("Track/Zboson/", "Track/b2e/"); + fRegistry.addClone("Track/Zboson/", "Track/b2c2e/"); // for pairs fRegistry.add("Pair/PV/Zboson/uls/hs", "hs;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c);DCA_{ee}^{3D} (#sigma);", kTHnSparseF, {axis_mass, axis_pt, axis_dca}, false); @@ -250,7 +272,7 @@ struct studyDCAFitter { fRegistry.addClone("Pair/PV/Zboson/", "Pair/PV/b2c2e_b2e_sameb/"); fRegistry.addClone("Pair/PV/Zboson/", "Pair/PV/b2c2e_b2e_diffb/"); - fRegistry.add("Pair/SV/Zboson/uls/hs", "hs;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c);DCA_{ee}^{3D} (#sigma);", kTHnSparseF, {axis_mass, axis_pt}, false); + fRegistry.add("Pair/SV/Zboson/uls/hs", "hs;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c);DCA_{ee}^{3D} (#sigma);", kTHnSparseF, {axis_mass, axis_pt, axis_dca, {200, -1, 1}}, false); fRegistry.add("Pair/SV/Zboson/uls/hCosPA", "cosPA;cosPA;", kTH1F, {{200, -1, 1}}, false); fRegistry.add("Pair/SV/Zboson/uls/hChi2PCA", "chi2 at PCA;log_{10}(#chi^{2}_{PCA});", kTH1F, {{1000, -10, 0}}, false); fRegistry.addClone("Pair/SV/Zboson/uls/", "Pair/SV/Zboson/lspp/"); @@ -361,6 +383,51 @@ struct studyDCAFitter { fRegistry.fill(HIST("Event/hMultFT0CvsMultNTracksPV"), collision.multFT0C(), collision.multNTracksPV()); } + template + void fillElectronHistograms(TCollision const&, TTrack const& track, TMCParticles const& mcParticles /*, TRefittedPV const& refittedPV, TRefittedPV const& refittedPVwoMod*/) + { + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); + float dcaXY = mDcaInfoCov.getY(); + float dcaZ = mDcaInfoCov.getZ(); + float dca3DinSigma = dca3DinSigmaOTF(dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZ2(), trackParCov.getSigmaZY()); + + float pt = trackParCov.getPt(); + float eta = trackParCov.getEta(); + float phi = RecoDecay::constrainAngle(trackParCov.getPhi(), 0, 1U); + + // mDcaInfoCov.set(999, 999, 999, 999, 999); + // o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); + // dcaXY = mDcaInfoCov.getY(); + // dcaZ = mDcaInfoCov.getZ(); + // float dca3DinSigma_unbiased = dca3DinSigmaOTF(dcaXY, dcaZ, mDcaInfoCov.getSigmaY2(), mDcaInfoCov.getSigmaZ2(), mDcaInfoCov.getSigmaYZ()); + // float diff = dca3DinSigma_unbiased - dca3DinSigma_biased; + // float diffChi2PV = refittedPVwoMod.getChi2() - refittedPV.getChi2(); + + auto mcParticle = track.template mcParticle_as(); // electron + auto mcMother = mcParticle.template mothers_as()[0]; + + if (isFromGammaZ(mcParticle, mcParticles) > -1) { + fRegistry.fill(HIST("Track/Zboson/hs"), pt, eta, phi, dca3DinSigma); + } else if (std::abs(mcMother.pdgCode()) == 443) { + if (IsFromCharm(mcMother, mcParticles) < 0 && IsFromBeauty(mcMother, mcParticles) < 0) { // prompt + fRegistry.fill(HIST("Track/PromptJpsi/hs"), pt, eta, phi, dca3DinSigma); + } else { // nonprompt + fRegistry.fill(HIST("Track/NonPromptJpsi/hs"), pt, eta, phi, dca3DinSigma); + } + } else if (isCharmMeson(mcMother) || isCharmBaryon(mcMother)) { + if (IsFromBeauty(mcMother, mcParticles) < 0) { // prompt + fRegistry.fill(HIST("Track/c2e/hs"), pt, eta, phi, dca3DinSigma); + } else { // nonprompt + fRegistry.fill(HIST("Track/b2c2e/hs"), pt, eta, phi, dca3DinSigma); + } + } else if (isBeautyMeson(mcMother) || isBeautyBaryon(mcMother)) { + fRegistry.fill(HIST("Track/b2e/hs"), pt, eta, phi, dca3DinSigma); + } + } + float dca3DinSigmaOTF(const float dcaXY, const float dcaZ, const float cYY, const float cZZ, const float cZY) { float det = cYY * cZZ - cZY * cZY; // determinant @@ -375,7 +442,7 @@ struct studyDCAFitter { int FindCommonMother(TTrack const& posmc, TTrack const& negmc, TMCParticles const& mcparticles) { int arr[] = { - FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 23, mcparticles), // Z/gamma* + isPairFromGammaZ(posmc, negmc, mcparticles), FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 111, mcparticles), FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 221, mcparticles), FindCommonMotherFrom2Prongs(posmc, negmc, -11, 11, 331, mcparticles), @@ -510,13 +577,180 @@ struct studyDCAFitter { } // end of HFee } + template + o2::dataformats::VertexBase refitPV(TCollision const& collision, std::vector const& vecPvContributorTrackParCov, std::vector const& vecPvContributorGlobalId, std::vector const& tracksToRemove) + { + std::vector vecPvRefitContributorUsed(vecPvContributorGlobalId.size(), true); + + // build the VertexBase to initialize the vertexer + o2::dataformats::VertexBase primVtx; + primVtx.setX(collision.posX()); + primVtx.setY(collision.posY()); + primVtx.setZ(collision.posZ()); + primVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + + o2::vertexing::PVertexer vertexer; + o2::conf::ConfigurableParam::updateFromString("pvertexer.useMeanVertexConstraint=false"); // remove diamond constraint + o2::conf::ConfigurableParam::updateFromString("pvertexer.tukey=100."); + vertexer.init(); + const bool pvRefitDoable = vertexer.prepareVertexRefit(vecPvContributorTrackParCov, primVtx); + if (!pvRefitDoable) { + LOG(info) << "Not enough tracks accepted for the refit"; // this should not happen by definition, because nPV>=2 is required in the reconstruction. I analyze the reconstructed collisions in AO2D. + return primVtx; + } + + for (const auto& trackToRemove : tracksToRemove) { + const auto trackIterator = std::find(vecPvContributorGlobalId.begin(), vecPvContributorGlobalId.end(), trackToRemove.globalIndex()); // track global index + if (trackIterator != vecPvContributorGlobalId.end()) { + const int entry = std::distance(vecPvContributorGlobalId.begin(), trackIterator); // this track contributed to this collision: let's do the refit without it + vecPvRefitContributorUsed[entry] = false; // remove the track from the PV refitting + } + } + + const auto primVtxRefitted = vertexer.refitVertex(vecPvRefitContributorUsed, primVtx); // vertex refit + // LOG(info) << "refit for track with global index " << static_cast(trackToRemove.globalIndex()) << " " << primVtxRefitted.asString(); + // LOG(info) << "refitVertex: collision.globalIndex() = " << collision.globalIndex() << " , " << primVtxRefitted.asString(); + if (primVtxRefitted.getChi2() < 0) { + // LOG(info) << "---> (when removing tracks) Refitted vertex has bad chi2 = " << primVtxRefitted.getChi2(); + return primVtx; + } + + fRegistry.fill(HIST("Event/refitPV/remove/hNContrib"), collision.numContrib(), primVtxRefitted.getNContributors()); + fRegistry.fill(HIST("Event/refitPV/remove/hChi2"), collision.chi2(), primVtxRefitted.getChi2()); + fRegistry.fill(HIST("Event/refitPV/remove/hDeltaXvsNContrib"), primVtxRefitted.getNContributors(), primVtxRefitted.getX() - primVtx.getX()); + fRegistry.fill(HIST("Event/refitPV/remove/hDeltaYvsNContrib"), primVtxRefitted.getNContributors(), primVtxRefitted.getY() - primVtx.getY()); + fRegistry.fill(HIST("Event/refitPV/remove/hDeltaZvsNContrib"), primVtxRefitted.getNContributors(), primVtxRefitted.getZ() - primVtx.getZ()); + + o2::dataformats::VertexBase primVtxBaseRecalc; + primVtxBaseRecalc.setX(primVtxRefitted.getX()); + primVtxBaseRecalc.setY(primVtxRefitted.getY()); + primVtxBaseRecalc.setZ(primVtxRefitted.getZ()); + primVtxBaseRecalc.setCov(primVtxRefitted.getSigmaX2(), primVtxRefitted.getSigmaXY(), primVtxRefitted.getSigmaY2(), primVtxRefitted.getSigmaXZ(), primVtxRefitted.getSigmaYZ(), primVtxRefitted.getSigmaZ2()); + + vecPvRefitContributorUsed.clear(); + vecPvRefitContributorUsed.shrink_to_fit(); + return primVtxRefitted; + // return primVtxBaseRecalc; + } + + template + // o2::dataformats::VertexBase refitPVFullByRemovingTracks(TCollision const& collision, std::vector const& vecPvContributorTrackParCov, std::vector const& vecPvContributorGlobalId, std::vector const& tracksToRemove) + o2::vertexing::PVertex refitPVFullByRemovingTracks(TCollision const& collision, std::vector const& vecPvContributorTrackParCov, std::vector const& vecPvContributorGlobalId, std::vector const& tracksToRemove) + { + std::vector vecPvRefitContributorUsed(vecPvContributorGlobalId.size(), true); + + // build the VertexBase to initialize the vertexer + o2::dataformats::VertexBase primVtx; + primVtx.setX(collision.posX()); + primVtx.setY(collision.posY()); + primVtx.setZ(collision.posZ()); + primVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + + o2::vertexing::PVertexer vertexer; + o2::conf::ConfigurableParam::updateFromString("pvertexer.useMeanVertexConstraint=false"); // remove diamond constraint + o2::conf::ConfigurableParam::updateFromString("pvertexer.tukey=100."); + vertexer.init(); + const bool pvRefitDoable = vertexer.prepareVertexRefit(vecPvContributorTrackParCov, primVtx); + if (!pvRefitDoable) { + LOG(info) << "Not enough tracks accepted for the refit"; // this should not happen by definition, because nPV>=2 is required in the reconstruction. I analyze the reconstructed collisions in AO2D. + // return primVtx; + } + + for (const auto& trackToRemove : tracksToRemove) { + const auto trackIterator = std::find(vecPvContributorGlobalId.begin(), vecPvContributorGlobalId.end(), trackToRemove.globalIndex()); // track global index + if (trackIterator != vecPvContributorGlobalId.end()) { + const int entry = std::distance(vecPvContributorGlobalId.begin(), trackIterator); // this track contributed to this collision: let's do the refit without it + vecPvRefitContributorUsed[entry] = false; // remove the track from the PV refitting + } + } + + const auto primVtxRefitted = vertexer.refitVertexFull(vecPvRefitContributorUsed, primVtx); // vertex refit + // LOG(info) << "refit for track with global index " << static_cast(trackToRemove.globalIndex()) << " " << primVtxRefitted.asString(); + // LOG(info) << "refitVertexFull: collision.globalIndex() = " << collision.globalIndex() << " , " << primVtxRefitted.asString(); + if (primVtxRefitted.getChi2() < 0) { + // LOG(info) << "---> (when removing tracks) Refitted vertex has bad chi2 = " << primVtxRefitted.getChi2(); + return primVtxRefitted; + } + + fRegistry.fill(HIST("Event/refitPV/remove/hNContrib"), collision.numContrib(), primVtxRefitted.getNContributors()); + fRegistry.fill(HIST("Event/refitPV/remove/hChi2"), collision.chi2(), primVtxRefitted.getChi2()); + fRegistry.fill(HIST("Event/refitPV/remove/hDeltaXvsNContrib"), primVtxRefitted.getNContributors(), primVtxRefitted.getX() - primVtx.getX()); + fRegistry.fill(HIST("Event/refitPV/remove/hDeltaYvsNContrib"), primVtxRefitted.getNContributors(), primVtxRefitted.getY() - primVtx.getY()); + fRegistry.fill(HIST("Event/refitPV/remove/hDeltaZvsNContrib"), primVtxRefitted.getNContributors(), primVtxRefitted.getZ() - primVtx.getZ()); + + o2::dataformats::VertexBase primVtxBaseRecalc; + primVtxBaseRecalc.setX(primVtxRefitted.getX()); + primVtxBaseRecalc.setY(primVtxRefitted.getY()); + primVtxBaseRecalc.setZ(primVtxRefitted.getZ()); + primVtxBaseRecalc.setCov(primVtxRefitted.getSigmaX2(), primVtxRefitted.getSigmaXY(), primVtxRefitted.getSigmaY2(), primVtxRefitted.getSigmaXZ(), primVtxRefitted.getSigmaYZ(), primVtxRefitted.getSigmaZ2()); + + vecPvRefitContributorUsed.clear(); + vecPvRefitContributorUsed.shrink_to_fit(); + return primVtxRefitted; + // return primVtxBaseRecalc; + } + + template + o2::dataformats::VertexBase refitPVFullByAddingTracks(TCollision const& collision, std::vector vecPvContributorTrackParCov, std::vector vecPvContributorGlobalId, std::vector const& tracksToAdd) + { + // build the VertexBase to initialize the vertexer + o2::dataformats::VertexBase primVtx; + primVtx.setX(collision.posX()); + primVtx.setY(collision.posY()); + primVtx.setZ(collision.posZ()); + primVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + + for (const auto& trackToAdd : tracksToAdd) { + if (!trackToAdd.isPVContributor() && trackToAdd.collisionId() == collision.globalIndex()) { // this track belongs to this collision, but not a PV contributor + vecPvContributorTrackParCov.emplace_back(getTrackParCov(trackToAdd)); + vecPvContributorGlobalId.emplace_back(trackToAdd.globalIndex()); + } + } + std::vector vecPvRefitContributorUsed(vecPvContributorGlobalId.size(), true); + + o2::vertexing::PVertexer vertexer; + o2::conf::ConfigurableParam::updateFromString("pvertexer.useMeanVertexConstraint=false"); // remove diamond constraint + o2::conf::ConfigurableParam::updateFromString("pvertexer.tukey=100."); + vertexer.init(); + const bool pvRefitDoable = vertexer.prepareVertexRefit(vecPvContributorTrackParCov, primVtx); + if (!pvRefitDoable) { + LOG(info) << "Not enough tracks accepted for the refit"; // this should not happen by definition, because nPV>=2 is required in the reconstruction. I analyze the reconstructed collisions in AO2D. + return primVtx; + } + + const auto primVtxRefitted = vertexer.refitVertexFull(vecPvRefitContributorUsed, primVtx); // vertex refit + // LOG(info) << "refit for track with global index " << static_cast(trackToAdd.globalIndex()) << " " << primVtxRefitted.asString(); + // LOG(info) << "refitVertexFull + adding a track: collision.globalIndex() = " << collision.globalIndex() << " , " << primVtxRefitted.asString(); + + if (primVtxRefitted.getChi2() < 0) { + // LOG(info) << "---> (when adding tracks) Refitted vertex has bad chi2 = " << primVtxRefitted.getChi2(); + return primVtx; + } + + fRegistry.fill(HIST("Event/refitPV/add/hNContrib"), collision.numContrib(), primVtxRefitted.getNContributors()); + fRegistry.fill(HIST("Event/refitPV/add/hChi2"), collision.chi2(), primVtxRefitted.getChi2()); + fRegistry.fill(HIST("Event/refitPV/add/hDeltaXvsNContrib"), primVtxRefitted.getNContributors(), primVtxRefitted.getX() - primVtx.getX()); + fRegistry.fill(HIST("Event/refitPV/add/hDeltaYvsNContrib"), primVtxRefitted.getNContributors(), primVtxRefitted.getY() - primVtx.getY()); + fRegistry.fill(HIST("Event/refitPV/add/hDeltaZvsNContrib"), primVtxRefitted.getNContributors(), primVtxRefitted.getZ() - primVtx.getZ()); + + o2::dataformats::VertexBase primVtxBaseRecalc; + primVtxBaseRecalc.setX(primVtxRefitted.getX()); + primVtxBaseRecalc.setY(primVtxRefitted.getY()); + primVtxBaseRecalc.setZ(primVtxRefitted.getZ()); + primVtxBaseRecalc.setCov(primVtxRefitted.getSigmaX2(), primVtxRefitted.getSigmaXY(), primVtxRefitted.getSigmaY2(), primVtxRefitted.getSigmaXZ(), primVtxRefitted.getSigmaYZ(), primVtxRefitted.getSigmaZ2()); + + vecPvRefitContributorUsed.clear(); + vecPvRefitContributorUsed.shrink_to_fit(); + return primVtxRefitted; + // return primVtxBaseRecalc; + } + template - void runSVFinder(TCollision const& collision, TTrack const& t1, TTrack const& t2, TMCParticles const& mcParticles) + void runSVFinder(TCollision const& collision, TTrack const& t1, TTrack const& t2, TMCParticles const& mcParticles /*, std::vector const& vecPvContributorTrackParCov, std::vector const& vecPvContributorGlobalId*/) { auto trackParCov1 = getTrackParCov(t1); trackParCov1.setPID(o2::track::PID::Electron); mDcaInfoCov.set(999, 999, 999, 999, 999); - trackParCov1.setPID(o2::track::PID::Electron); o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov1, 2.f, matCorr, &mDcaInfoCov); float dcaXY1 = mDcaInfoCov.getY(); float dcaZ1 = mDcaInfoCov.getZ(); @@ -525,11 +759,11 @@ struct studyDCAFitter { float CZZ1 = trackParCov1.getSigmaZ2(); float signed1Pt1 = trackParCov1.getQ2Pt(); // at PV float eta1 = trackParCov1.getEta(); // at PV + float dca3DinSigma1 = dca3DinSigmaOTF(dcaXY1, dcaZ1, trackParCov1.getSigmaY2(), trackParCov1.getSigmaZ2(), trackParCov1.getSigmaZY()); auto trackParCov2 = getTrackParCov(t2); trackParCov2.setPID(o2::track::PID::Electron); mDcaInfoCov.set(999, 999, 999, 999, 999); - trackParCov2.setPID(o2::track::PID::Electron); o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov2, 2.f, matCorr, &mDcaInfoCov); float dcaXY2 = mDcaInfoCov.getY(); float dcaZ2 = mDcaInfoCov.getZ(); @@ -538,6 +772,26 @@ struct studyDCAFitter { float CZZ2 = trackParCov2.getSigmaZ2(); float signed1Pt2 = trackParCov2.getQ2Pt(); // at PV float eta2 = trackParCov2.getEta(); // at PV + float dca3DinSigma2 = dca3DinSigmaOTF(dcaXY2, dcaZ2, trackParCov2.getSigmaY2(), trackParCov2.getSigmaZ2(), trackParCov2.getSigmaZY()); + float pairDCA = pairDCAQuadSum(dca3DinSigma1, dca3DinSigma2); + + // auto refittedPV_remove_t1 = refitPVFullByRemovingTracks(collision, vecPvContributorTrackParCov, vecPvContributorGlobalId, std::vector{t1}); + // mDcaInfoCov.set(999, 999, 999, 999, 999); + // o2::base::Propagator::Instance()->propagateToDCABxByBz(refittedPV_remove_t1, trackParCov1, 2.f, matCorr, &mDcaInfoCov); + // float dca3DinSigma1_remove_1track = dca3DinSigmaOTF(mDcaInfoCov.getY(), mDcaInfoCov.getZ(), trackParCov1.getSigmaY2(), trackParCov1.getSigmaZ2(), trackParCov1.getSigmaZY()); + // auto refittedPV_remove_t2 = refitPVFullByRemovingTracks(collision, vecPvContributorTrackParCov, vecPvContributorGlobalId, std::vector{t2}); + // mDcaInfoCov.set(999, 999, 999, 999, 999); + // o2::base::Propagator::Instance()->propagateToDCABxByBz(refittedPV_remove_t2, trackParCov2, 2.f, matCorr, &mDcaInfoCov); + // float dca3DinSigma2_remove_1track = dca3DinSigmaOTF(mDcaInfoCov.getY(), mDcaInfoCov.getZ(), trackParCov2.getSigmaY2(), trackParCov2.getSigmaZ2(), trackParCov2.getSigmaZY()); + // float pairDCA_remove_1track = pairDCAQuadSum(dca3DinSigma1_remove_1track, dca3DinSigma2_remove_1track); + + // auto refittedPV_remove_t12 = refitPVFullByRemovingTracks(collision, vecPvContributorTrackParCov, vecPvContributorGlobalId, std::vector{t1, t2}); + // mDcaInfoCov.set(999, 999, 999, 999, 999); + // o2::base::Propagator::Instance()->propagateToDCABxByBz(refittedPV_remove_t12, trackParCov1, 2.f, matCorr, &mDcaInfoCov); + // float dca3DinSigma1_remove_2track = dca3DinSigmaOTF(mDcaInfoCov.getY(), mDcaInfoCov.getZ(), trackParCov1.getSigmaY2(), trackParCov1.getSigmaZ2(), trackParCov1.getSigmaZY()); + // o2::base::Propagator::Instance()->propagateToDCABxByBz(refittedPV_remove_t12, trackParCov2, 2.f, matCorr, &mDcaInfoCov); + // float dca3DinSigma2_remove_2track = dca3DinSigmaOTF(mDcaInfoCov.getY(), mDcaInfoCov.getZ(), trackParCov2.getSigmaY2(), trackParCov2.getSigmaZ2(), trackParCov2.getSigmaZY()); + // float pairDCA_remove_2track = pairDCAQuadSum(dca3DinSigma1_remove_2track, dca3DinSigma2_remove_2track); std::array pVtx = {collision.posX(), collision.posY(), collision.posZ()}; std::array svpos = {0.}; // secondary vertex position @@ -595,6 +849,8 @@ struct studyDCAFitter { auto t2mc = t2.template mcParticle_as(); // true lepton bool isCorrectCollision1 = t1mc.mcCollisionId() == collision.mcCollisionId(); bool isCorrectCollision2 = t2mc.mcCollisionId() == collision.mcCollisionId(); + bool isReassociated1 = !(t1.collisionId() == collision.globalIndex()); + bool isReassociated2 = !(t2.collisionId() == collision.globalIndex()); int pdgCodeMother1 = 0; int pdgCodeMother2 = 0; @@ -612,15 +868,15 @@ struct studyDCAFitter { keepSignal = true; dileptonType = 1; if constexpr (signType == 0) { // ULS - fRegistry.fill(HIST("Pair/SV/Zboson/uls/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/Zboson/uls/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/Zboson/uls/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/Zboson/uls/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 1) { // LS++ - fRegistry.fill(HIST("Pair/SV/Zboson/lspp/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/Zboson/lspp/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/Zboson/lspp/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/Zboson/lspp/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 2) { // LS-- - fRegistry.fill(HIST("Pair/SV/Zboson/lsmm/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/Zboson/lsmm/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/Zboson/lsmm/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/Zboson/lsmm/hChi2PCA"), std::log10(chi2PCA)); } @@ -630,30 +886,30 @@ struct studyDCAFitter { if (IsFromCharm(cmp, mcParticles) < 0 && IsFromBeauty(cmp, mcParticles) < 0) { // prompt dileptonType = 1; if constexpr (signType == 0) { // ULS - fRegistry.fill(HIST("Pair/SV/PromptJpsi/uls/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/PromptJpsi/uls/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/PromptJpsi/uls/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/PromptJpsi/uls/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 1) { // LS++ - fRegistry.fill(HIST("Pair/SV/PromptJpsi/lspp/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/PromptJpsi/lspp/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/PromptJpsi/lspp/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/PromptJpsi/lspp/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 2) { // LS-- - fRegistry.fill(HIST("Pair/SV/PromptJpsi/lsmm/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/PromptJpsi/lsmm/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/PromptJpsi/lsmm/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/PromptJpsi/lsmm/hChi2PCA"), std::log10(chi2PCA)); } } else { // nonprompt dileptonType = 2; if constexpr (signType == 0) { // ULS - fRegistry.fill(HIST("Pair/SV/NonPromptJpsi/uls/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/NonPromptJpsi/uls/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/NonPromptJpsi/uls/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/NonPromptJpsi/uls/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 1) { // LS++ - fRegistry.fill(HIST("Pair/SV/NonPromptJpsi/lspp/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/NonPromptJpsi/lspp/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/NonPromptJpsi/lspp/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/NonPromptJpsi/lspp/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 2) { // LS-- - fRegistry.fill(HIST("Pair/SV/NonPromptJpsi/lsmm/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/NonPromptJpsi/lsmm/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/NonPromptJpsi/lsmm/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/NonPromptJpsi/lsmm/hChi2PCA"), std::log10(chi2PCA)); } @@ -673,15 +929,15 @@ struct studyDCAFitter { case static_cast(EM_HFeeType::kCe_Ce): dileptonType = 3; if constexpr (signType == 0) { // ULS - fRegistry.fill(HIST("Pair/SV/c2e_c2e/uls/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/c2e_c2e/uls/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/c2e_c2e/uls/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/c2e_c2e/uls/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 1) { // LS++ - fRegistry.fill(HIST("Pair/SV/c2e_c2e/lspp/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/c2e_c2e/lspp/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/c2e_c2e/lspp/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/c2e_c2e/lspp/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 2) { // LS-- - fRegistry.fill(HIST("Pair/SV/c2e_c2e/lsmm/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/c2e_c2e/lsmm/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/c2e_c2e/lsmm/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/c2e_c2e/lsmm/hChi2PCA"), std::log10(chi2PCA)); } @@ -689,15 +945,15 @@ struct studyDCAFitter { case static_cast(EM_HFeeType::kBe_Be): dileptonType = 4; if constexpr (signType == 0) { // ULS - fRegistry.fill(HIST("Pair/SV/b2e_b2e/uls/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/b2e_b2e/uls/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/b2e_b2e/uls/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/b2e_b2e/uls/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 1) { // LS++ - fRegistry.fill(HIST("Pair/SV/b2e_b2e/lspp/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/b2e_b2e/lspp/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/b2e_b2e/lspp/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/b2e_b2e/lspp/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 2) { // LS-- - fRegistry.fill(HIST("Pair/SV/b2e_b2e/lsmm/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/b2e_b2e/lsmm/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/b2e_b2e/lsmm/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/b2e_b2e/lsmm/hChi2PCA"), std::log10(chi2PCA)); } @@ -705,15 +961,15 @@ struct studyDCAFitter { case static_cast(EM_HFeeType::kBCe_BCe): dileptonType = 5; if constexpr (signType == 0) { // ULS - fRegistry.fill(HIST("Pair/SV/b2c2e_b2c2e/uls/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/b2c2e_b2c2e/uls/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2c2e/uls/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2c2e/uls/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 1) { // LS++ - fRegistry.fill(HIST("Pair/SV/b2c2e_b2c2e/lspp/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/b2c2e_b2c2e/lspp/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2c2e/lspp/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2c2e/lspp/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 2) { // LS-- - fRegistry.fill(HIST("Pair/SV/b2c2e_b2c2e/lsmm/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/b2c2e_b2c2e/lsmm/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2c2e/lsmm/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2c2e/lsmm/hChi2PCA"), std::log10(chi2PCA)); } @@ -721,15 +977,15 @@ struct studyDCAFitter { case static_cast(EM_HFeeType::kBCe_Be_SameB): dileptonType = 6; if constexpr (signType == 0) { // ULS - fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_sameb/uls/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_sameb/uls/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_sameb/uls/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_sameb/uls/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 1) { // LS++ - fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_sameb/lspp/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_sameb/lspp/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_sameb/lspp/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_sameb/lspp/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 2) { // LS-- - fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_sameb/lsmm/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_sameb/lsmm/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_sameb/lsmm/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_sameb/lsmm/hChi2PCA"), std::log10(chi2PCA)); } @@ -737,15 +993,15 @@ struct studyDCAFitter { case static_cast(EM_HFeeType::kBCe_Be_DiffB): dileptonType = 7; if constexpr (signType == 0) { // ULS - fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_diffb/uls/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_diffb/uls/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_diffb/uls/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_diffb/uls/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 1) { // LS+diff - fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_diffb/lspp/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_diffb/lspp/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_diffb/lspp/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_diffb/lspp/hChi2PCA"), std::log10(chi2PCA)); } else if constexpr (signType == 2) { // LS-diff - fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_diffb/lsmm/hs"), meeAtSV, pteeAtSV); + fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_diffb/lsmm/hs"), meeAtSV, pteeAtSV, pairDCA, cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_diffb/lsmm/hCosPA"), cpa); fRegistry.fill(HIST("Pair/SV/b2c2e_b2e_diffb/lsmm/hChi2PCA"), std::log10(chi2PCA)); } @@ -768,8 +1024,8 @@ struct studyDCAFitter { } dileptonTable(eventTable.lastIndex() + 1, - signed1Pt1, eta1, dcaXY1, dcaZ1, CYY1, CZY1, CZZ1, isCorrectCollision1, pdgCodeMother1, - signed1Pt2, eta2, dcaXY2, dcaZ2, CYY2, CZY2, CZZ2, isCorrectCollision2, pdgCodeMother2, + signed1Pt1, eta1, dcaXY1, dcaZ1, CYY1, CZY1, CZZ1, isCorrectCollision1, isReassociated1, pdgCodeMother1, + signed1Pt2, eta2, dcaXY2, dcaZ2, CYY2, CZY2, CZZ2, isCorrectCollision2, isReassociated2, pdgCodeMother2, meeAtSV, pteeAtSV, yeeAtSV, chi2PCA, cpa, cpaXY, cpaRZ, @@ -783,6 +1039,15 @@ struct studyDCAFitter { void run(TBCs const&, TCollisions const& collisions, TTracks const& tracks, TTrackAssoc const& trackIndices, TMCCollisions const&, TMCParticles const& mcParticles) { for (const auto& collision : collisions) { + if (!collision.has_mcCollision()) { + continue; + } + + auto mcCollision_from_collision = collision.template mcCollision_as(); + if (mcCollision_from_collision.getSubGeneratorId() == eventCut.cfgRejectEventGenerator) { + continue; + } + auto bc = collision.template bc_as(); initCCDB(bc); fRegistry.fill(HIST("Event/hCollisionCounter"), 0); @@ -799,6 +1064,8 @@ struct studyDCAFitter { fillEventHistograms(collision); auto trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, collision.globalIndex()); + std::vector electronIds; + std::vector positronIds; electronIds.reserve(trackIdsThisCollision.size()); positronIds.reserve(trackIdsThisCollision.size()); mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); @@ -815,23 +1082,24 @@ struct studyDCAFitter { } auto mctrack = track.template mcParticle_as(); auto mcCollision = mctrack.template mcCollision_as(); - if (eventCut.cfgEventGeneratorType >= 0 && mcCollision.getSubGeneratorId() != eventCut.cfgEventGeneratorType) { + if (mcCollision.getSubGeneratorId() == eventCut.cfgRejectEventGenerator) { continue; } + if (!mctrack.has_mothers()) { continue; } if (std::abs(mctrack.pdgCode()) != 11) { continue; } + if (!(mctrack.isPhysicalPrimary() || mctrack.producedByGenerator())) { + continue; + } auto mcMother = mctrack.template mothers_first_as(); if (std::abs(mcMother.pdgCode()) > 1e+9) { continue; } - if (!(mctrack.isPhysicalPrimary() || mctrack.producedByGenerator())) { - continue; - } mDcaInfoCov.set(999, 999, 999, 999, 999); auto trackParCov = getTrackParCov(track); @@ -849,6 +1117,38 @@ struct studyDCAFitter { } } // end of track loop for electron selection + // auto pvContributors_per_collision = pvContributors->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + // std::vector vecPvContributorTrackParCov; + // std::vector vecPvContributorGlobalId; + // vecPvContributorTrackParCov.reserve(pvContributors_per_collision.size()); + // vecPvContributorGlobalId.reserve(pvContributors_per_collision.size()); + + // for (const auto& track : pvContributors_per_collision) { + // vecPvContributorGlobalId.push_back(track.globalIndex()); + // vecPvContributorTrackParCov.push_back(getTrackParCov(track)); + // } + + // auto refittedPVFull_wo_modification = refitPVFullByRemovingTracks(collision, vecPvContributorTrackParCov, vecPvContributorGlobalId, std::vector{}); + // for (const auto& posId : positronIds) { + // auto pos = tracks.rawIteratorAt(posId); + // refitPVFullByAddingTracks(collision, vecPvContributorTrackParCov, vecPvContributorGlobalId, std::vector{pos}); + // } + // for (const auto& eleId : electronIds) { + // auto ele = tracks.rawIteratorAt(eleId); + // refitPVFullByAddingTracks(collision, vecPvContributorTrackParCov, vecPvContributorGlobalId, std::vector{ele}); + // } + + for (const auto& posId : positronIds) { + auto pos = tracks.rawIteratorAt(posId); + // auto refittedPV = refitPVFullByRemovingTracks(collision, vecPvContributorTrackParCov, vecPvContributorGlobalId, std::vector{pos}); + fillElectronHistograms(collision, pos, mcParticles); + } + for (const auto& eleId : electronIds) { + auto ele = tracks.rawIteratorAt(eleId); + // auto refittedPV = refitPVFullByRemovingTracks(collision, vecPvContributorTrackParCov, vecPvContributorGlobalId, std::vector{ele}); + fillElectronHistograms(collision, ele, mcParticles); + } + for (const auto& posId : positronIds) { auto pos = tracks.rawIteratorAt(posId); for (const auto& eleId : electronIds) { @@ -885,6 +1185,12 @@ struct studyDCAFitter { positronIds.clear(); positronIds.shrink_to_fit(); + // vecPvContributorGlobalId.clear(); + // vecPvContributorTrackParCov.clear(); + + // vecPvContributorGlobalId.shrink_to_fit(); + // vecPvContributorTrackParCov.shrink_to_fit(); + } // end of collision loop } @@ -895,13 +1201,12 @@ struct studyDCAFitter { Filter collisionFilter_centrality = (eventCut.cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < eventCut.cfgCentMax) || (eventCut.cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < eventCut.cfgCentMax) || (eventCut.cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < eventCut.cfgCentMax); using FilteredMyCollisions = soa::Filtered; + // Partition pvContributors = ((o2::aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor)); + Preslice trackIndicesPerCollision = aod::track_association::collisionId; // Partition posTracks = o2::aod::track::signed1Pt > 0.f; // Partition negTracks = o2::aod::track::signed1Pt < 0.f; - std::vector electronIds; - std::vector positronIds; - void processMC(FilteredMyCollisions const& collisions, MyBCs const& bcs, MyTracks const& tracks, aod::TrackAssoc const& trackIndices, aod::McCollisions const& mcCollisions, aod::McParticles const& mcParticles) { run(bcs, collisions, tracks, trackIndices, mcCollisions, mcParticles); diff --git a/PWGEM/Dilepton/Tasks/taggingHFE.cxx b/PWGEM/Dilepton/Tasks/taggingHFE.cxx index ed7f717c397..7ba582fa714 100644 --- a/PWGEM/Dilepton/Tasks/taggingHFE.cxx +++ b/PWGEM/Dilepton/Tasks/taggingHFE.cxx @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -54,8 +55,6 @@ #include #include -#include - #include #include #include @@ -1730,7 +1729,7 @@ struct taggingHFE { continue; } - auto eKpair = o2::aod::pwgem::dilepton::utils::makePairLeptonTrack(fitter_eK, collision, pos, kaon, o2::track::PID::Electron, kaon.pidForTracking()); + auto eKpair = o2::aod::pwgem::dilepton::utils::makePairLeptonTrack(fitter_eK, collision, pos, kaon, o2::track::PID::Electron, kaon.pidForTracking(), o2::constants::physics::MassElectron); if (!eKpair.isOK) { continue; } @@ -1790,7 +1789,7 @@ struct taggingHFE { continue; } - auto eKpair = o2::aod::pwgem::dilepton::utils::makePairLeptonTrack(fitter_eK, collision, pos, kaon, o2::track::PID::Electron, kaon.pidForTracking()); + auto eKpair = o2::aod::pwgem::dilepton::utils::makePairLeptonTrack(fitter_eK, collision, pos, kaon, o2::track::PID::Electron, kaon.pidForTracking(), o2::constants::physics::MassElectron); if (!eKpair.isOK) { continue; } @@ -1857,7 +1856,7 @@ struct taggingHFE { o2::dataformats::DCA impactParameterV0; o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackV0, 2.f, matCorr, &impactParameterV0); // trackV0 is TrackParCov object - auto eV0pair = o2::aod::pwgem::dilepton::utils::makePairLeptonV0(fitter_eV0, collision, pos, v0, o2::track::PID::Electron, o2::track::PID::K0); + auto eV0pair = o2::aod::pwgem::dilepton::utils::makePairLeptonV0(fitter_eV0, collision, pos, v0, o2::track::PID::Electron, o2::track::PID::K0, o2::constants::physics::MassElectron); if (!eV0pair.isOK) { continue; @@ -1934,7 +1933,7 @@ struct taggingHFE { o2::dataformats::DCA impactParameterV0; o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackV0, 2.f, matCorr, &impactParameterV0); // trackV0 is TrackParCov object - auto eV0pair = o2::aod::pwgem::dilepton::utils::makePairLeptonV0(fitter_eV0, collision, pos, v0, o2::track::PID::Electron, o2::track::PID::Lambda); + auto eV0pair = o2::aod::pwgem::dilepton::utils::makePairLeptonV0(fitter_eV0, collision, pos, v0, o2::track::PID::Electron, o2::track::PID::Lambda, o2::constants::physics::MassElectron); if (!eV0pair.isOK) { continue; @@ -1994,7 +1993,7 @@ struct taggingHFE { o2::dataformats::DCA impactParameterCasc; o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackCasc, 2.f, matCorr, &impactParameterCasc); // trackCasc is TrackParCov object - auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(fitter_eCascade, collision, pos, cascade, o2::track::PID::Electron, o2::track::PID::XiMinus); + auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(fitter_eCascade, collision, pos, cascade, o2::track::PID::Electron, o2::track::PID::XiMinus, o2::constants::physics::MassElectron); if (!eCpair.isOK) { continue; @@ -2060,7 +2059,7 @@ struct taggingHFE { o2::dataformats::DCA impactParameterCasc; o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackCasc, 2.f, matCorr, &impactParameterCasc); // trackCasc is TrackParCov object - auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(fitter_eCascade, collision, pos, cascade, o2::track::PID::Electron, o2::track::PID::OmegaMinus); + auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(fitter_eCascade, collision, pos, cascade, o2::track::PID::Electron, o2::track::PID::OmegaMinus, o2::constants::physics::MassElectron); if (!eCpair.isOK) { continue; @@ -2154,7 +2153,7 @@ struct taggingHFE { continue; } - auto eKpair = o2::aod::pwgem::dilepton::utils::makePairLeptonTrack(fitter_eK, collision, ele, kaon, o2::track::PID::Electron, kaon.pidForTracking()); + auto eKpair = o2::aod::pwgem::dilepton::utils::makePairLeptonTrack(fitter_eK, collision, ele, kaon, o2::track::PID::Electron, kaon.pidForTracking(), o2::constants::physics::MassElectron); if (!eKpair.isOK) { continue; } @@ -2215,7 +2214,7 @@ struct taggingHFE { continue; } - auto eKpair = o2::aod::pwgem::dilepton::utils::makePairLeptonTrack(fitter_eK, collision, ele, kaon, o2::track::PID::Electron, kaon.pidForTracking()); + auto eKpair = o2::aod::pwgem::dilepton::utils::makePairLeptonTrack(fitter_eK, collision, ele, kaon, o2::track::PID::Electron, kaon.pidForTracking(), o2::constants::physics::MassElectron); if (!eKpair.isOK) { continue; } @@ -2282,7 +2281,7 @@ struct taggingHFE { o2::dataformats::DCA impactParameterV0; o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackV0, 2.f, matCorr, &impactParameterV0); // trackV0 is TrackParCov object - auto eV0pair = o2::aod::pwgem::dilepton::utils::makePairLeptonV0(fitter_eV0, collision, ele, v0, o2::track::PID::Electron, o2::track::PID::K0); + auto eV0pair = o2::aod::pwgem::dilepton::utils::makePairLeptonV0(fitter_eV0, collision, ele, v0, o2::track::PID::Electron, o2::track::PID::K0, o2::constants::physics::MassElectron); if (!eV0pair.isOK) { continue; @@ -2358,7 +2357,7 @@ struct taggingHFE { o2::dataformats::DCA impactParameterV0; o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackV0, 2.f, matCorr, &impactParameterV0); // trackV0 is TrackParCov object - auto eV0pair = o2::aod::pwgem::dilepton::utils::makePairLeptonV0(fitter_eV0, collision, ele, v0, o2::track::PID::Electron, o2::track::PID::Lambda); + auto eV0pair = o2::aod::pwgem::dilepton::utils::makePairLeptonV0(fitter_eV0, collision, ele, v0, o2::track::PID::Electron, o2::track::PID::Lambda, o2::constants::physics::MassElectron); if (!eV0pair.isOK) { continue; @@ -2418,7 +2417,7 @@ struct taggingHFE { o2::dataformats::DCA impactParameterCasc; o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackCasc, 2.f, matCorr, &impactParameterCasc); // trackCasc is TrackParCov object - auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(fitter_eCascade, collision, ele, cascade, o2::track::PID::Electron, o2::track::PID::XiMinus); + auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(fitter_eCascade, collision, ele, cascade, o2::track::PID::Electron, o2::track::PID::XiMinus, o2::constants::physics::MassElectron); if (!eCpair.isOK) { continue; @@ -2484,7 +2483,7 @@ struct taggingHFE { o2::dataformats::DCA impactParameterCasc; o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackCasc, 2.f, matCorr, &impactParameterCasc); // trackCasc is TrackParCov object - auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(fitter_eCascade, collision, ele, cascade, o2::track::PID::Electron, o2::track::PID::OmegaMinus); + auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(fitter_eCascade, collision, ele, cascade, o2::track::PID::Electron, o2::track::PID::OmegaMinus, o2::constants::physics::MassElectron); if (!eCpair.isOK) { continue; diff --git a/PWGEM/Dilepton/Utils/ElectronModule.h b/PWGEM/Dilepton/Utils/ElectronModule.h index a1a259163a9..fddcd6fe56c 100644 --- a/PWGEM/Dilepton/Utils/ElectronModule.h +++ b/PWGEM/Dilepton/Utils/ElectronModule.h @@ -95,7 +95,7 @@ struct electronCut : o2::framework::ConfigurableGroup { o2::framework::Configurable minchi2tpc{"minchi2tpc", 0.0, "min. chi2/NclsTPC"}; o2::framework::Configurable minchi2its{"minchi2its", 0.0, "min. chi2/NclsITS"}; o2::framework::Configurable maxchi2tpc{"maxchi2tpc", 5.0, "max. chi2/NclsTPC"}; - o2::framework::Configurable maxchi2its{"maxchi2its", 6.0, "max. chi2/NclsITS"}; + o2::framework::Configurable maxchi2its{"maxchi2its", 36.0, "max. chi2/NclsITS"}; o2::framework::Configurable minpt{"minpt", 0.05, "min pt"}; o2::framework::Configurable maxeta{"maxeta", 0.9, "max eta"}; o2::framework::Configurable dca_xy_max{"dca_xy_max", 1.0, "max DCAxy in cm"}; @@ -112,12 +112,16 @@ struct electronCut : o2::framework::ConfigurableGroup { o2::framework::Configurable requireTOF{"requireTOF", false, "require TOF hit"}; o2::framework::Configurable min_pin_for_pion_rejection{"min_pin_for_pion_rejection", 0.0, "pion rejection is applied above this pin"}; // this is used only in TOFreq o2::framework::Configurable max_pin_for_pion_rejection{"max_pin_for_pion_rejection", 0.5, "pion rejection is applied below this pin"}; - o2::framework::Configurable max_frac_shared_clusters_tpc{"max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; + o2::framework::Configurable max_frac_shared_clusters_tpc{"max_frac_shared_clusters_tpc", 0.7f, "max fraction of shared clusters in TPC"}; o2::framework::Configurable maxMeanITSClusterSize{"maxMeanITSClusterSize", 16, "max x cos(lambda)"}; o2::framework::Configurable storeOnlyTrueElectronMC{"storeOnlyTrueElectronMC", false, "Flag to store only true electron in MC"}; o2::framework::Configurable minNelectron{"minNelectron", 0, "min number of electron candidates per collision"}; o2::framework::Configurable includeITSsa{"includeITSsa", false, "Flag to include ITSsa tracks only for MC. switch ON only if needed."}; o2::framework::Configurable useTOFNSigmaDeltaBC{"useTOFNSigmaDeltaBC", false, "Flag to shift delta BC for TOF n sigma (only with TTCA)"}; + o2::framework::Configurable useElectronHypothesis{"useElectronHypothesis", true, "force to use trackParCov.setPID(o2::track::PID::Electron)"}; + + o2::framework::Configurable dcaType{"dcaType", 0, "type of DCA cut. 0:3D, 1:XY, 2:Z, else:3D"}; + o2::framework::Configurable max_dca_in_sigma{"max_dca_in_sigma", 1e+10, "max dca in sigma for a single track"}; // configuration for PID ML o2::framework::Configurable usePIDML{"usePIDML", false, "Flag to use PID ML"}; @@ -148,7 +152,7 @@ struct electronPFCut : o2::framework::ConfigurableGroup { o2::framework::Configurable dca_z_max{"dca_z_max", 1.0, "max DCAz in cm"}; o2::framework::Configurable minTPCNsigmaEl{"minTPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; o2::framework::Configurable maxTPCNsigmaEl{"maxTPCNsigmaEl", 3.0, "max. TPC n sigma for electron inclusion"}; - o2::framework::Configurable maxTOFNsigmaEl{"maxTOFNsigmaEl", 1e+10, "max. TOF n sigma for electron inclusion"}; + o2::framework::Configurable maxTOFNsigmaEl{"maxTOFNsigmaEl", 3.0, "max. TOF n sigma for electron inclusion"}; o2::framework::Configurable maxTPCNsigmaPi{"maxTPCNsigmaPi", 0.0, "max. TPC n sigma for pion exclusion"}; o2::framework::Configurable minTPCNsigmaPi{"minTPCNsigmaPi", 0.0, "min. TPC n sigma for pion exclusion"}; // set to -2 for lowB, -1e+10 for nominalB o2::framework::Configurable maxTPCNsigmaKa{"maxTPCNsigmaKa", 0.0, "max. TPC n sigma for kaon exclusion"}; @@ -189,83 +193,68 @@ struct hadronCut : o2::framework::ConfigurableGroup { o2::framework::Configurable cfg_max_dcaz{"cfg_max_dcaz", 1.0, "max dca Z for single track in cm"}; o2::framework::Configurable cfg_min_TPCNsigmaPi{"cfg_min_TPCNsigmaPi", -3, "min n sigma pi in TPC"}; o2::framework::Configurable cfg_max_TPCNsigmaPi{"cfg_max_TPCNsigmaPi", +3, "max n sigma pi in TPC"}; - // o2::framework::Configurable cfg_min_TOFNsigmaPi{"cfg_min_TOFNsigmaPi", -3, "min n sigma pi in TOF"}; - // o2::framework::Configurable cfg_max_TOFNsigmaPi{"cfg_max_TOFNsigmaPi", +3, "max n sigma pi in TOF"}; o2::framework::Configurable cfg_min_TPCNsigmaKa{"cfg_min_TPCNsigmaKa", -3, "min n sigma ka in TPC"}; o2::framework::Configurable cfg_max_TPCNsigmaKa{"cfg_max_TPCNsigmaKa", +3, "max n sigma ka in TPC"}; - // o2::framework::Configurable cfg_min_TOFNsigmaKa{"cfg_min_TOFNsigmaKa", -3, "min n sigma ka in TOF"}; - // o2::framework::Configurable cfg_max_TOFNsigmaKa{"cfg_max_TOFNsigmaKa", +3, "max n sigma ka in TOF"}; - // o2::framework::Configurable cfg_min_TPCNsigmaPr{"cfg_min_TPCNsigmaPr", -3, "min n sigma pr in TPC"}; - // o2::framework::Configurable cfg_max_TPCNsigmaPr{"cfg_max_TPCNsigmaPr", +3, "max n sigma pr in TPC"}; - // // o2::framework::Configurable cfg_min_TOFNsigmaPr{"cfg_min_TOFNsigmaPr", -3, "min n sigma pr in TOF"}; - // // o2::framework::Configurable cfg_max_TOFNsigmaPr{"cfg_max_TOFNsigmaPr", +3, "max n sigma pr in TOF"}; o2::framework::Configurable requirePiKa{"requirePiKa", true, "require hadron to be pion or kaon"}; // protons are not involved in semileptonic decays of HF hadrons. }; -struct v0Cut : o2::framework::ConfigurableGroup { - std::string prefix = "v0Cut"; - o2::framework::Configurable cfg_min_mass_k0s{"cfg_min_mass_k0s", 0.48, "min mass for K0S"}; - o2::framework::Configurable cfg_max_mass_k0s{"cfg_max_mass_k0s", 0.51, "max mass for K0S"}; - o2::framework::Configurable cfg_min_mass_k0s_veto{"cfg_min_mass_k0s_veto", 0.48, "min mass for K0S veto for Lambda"}; - o2::framework::Configurable cfg_max_mass_k0s_veto{"cfg_max_mass_k0s_veto", 0.51, "max mass for K0S veto for Lambda"}; - o2::framework::Configurable cfg_min_mass_lambda{"cfg_min_mass_lambda", 1.11, "min mass for Lambda"}; - o2::framework::Configurable cfg_max_mass_lambda{"cfg_max_mass_lambda", 1.12, "max mass for Lambda"}; - o2::framework::Configurable cfg_min_mass_lambda_veto{"cfg_min_mass_lambda_veto", 1.11, "min mass for Lambda veto for K0S"}; - o2::framework::Configurable cfg_max_mass_lambda_veto{"cfg_max_mass_lambda_veto", 1.12, "max mass for Lambda veto for K0S"}; - o2::framework::Configurable cfg_min_cospa{"cfg_min_cospa", 0.95, "min cospa for v0"}; - o2::framework::Configurable cfg_max_dca2legs{"cfg_max_dca2legs", 0.1, "max distance between 2 legs for v0"}; - o2::framework::Configurable cfg_min_radius{"cfg_min_radius", 0.1, "min rxy for v"}; - o2::framework::Configurable cfg_min_cr2findable_ratio_tpc{"cfg_min_cr2findable_ratio_tpc", 0.f, "min. TPC Ncr/Nf ratio"}; - o2::framework::Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; - o2::framework::Configurable cfg_min_ncrossedrows_tpc{"cfg_min_ncrossedrows_tpc", 70, "min ncrossed rows"}; - o2::framework::Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; - o2::framework::Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; - o2::framework::Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; - o2::framework::Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 2, "min ncluster its"}; - o2::framework::Configurable cfg_min_ncluster_itsib{"cfg_min_ncluster_itsib", 0, "min ncluster itsib"}; - o2::framework::Configurable cfg_min_dcaxy{"cfg_min_dcaxy", 0.1, "min dca XY for v0 legs in cm"}; - - o2::framework::Configurable cfg_max_alpha_veto{"cfg_max_alpha_veto", 0.95, "max alpha for photon conversion rejection"}; - o2::framework::Configurable cfg_max_qt_veto{"cfg_max_qt_veto", 0.01, "max qT for photon conversion rejection"}; - - // for both v0 and cascade - o2::framework::Configurable cfg_min_TPCNsigmaPi{"cfg_min_TPCNsigmaPi", -3, "min n sigma pi in TPC"}; - o2::framework::Configurable cfg_max_TPCNsigmaPi{"cfg_max_TPCNsigmaPi", +3, "max n sigma pi in TPC"}; - o2::framework::Configurable cfg_min_TPCNsigmaKa{"cfg_min_TPCNsigmaKa", -3, "min n sigma ka in TPC"}; - o2::framework::Configurable cfg_max_TPCNsigmaKa{"cfg_max_TPCNsigmaKa", +3, "max n sigma ka in TPC"}; - o2::framework::Configurable cfg_min_TPCNsigmaPr{"cfg_min_TPCNsigmaPr", -3, "min n sigma pr in TPC"}; - o2::framework::Configurable cfg_max_TPCNsigmaPr{"cfg_max_TPCNsigmaPr", +3, "max n sigma pr in TPC"}; - // o2::framework::Configurable cfg_min_TOFNsigmaPi{"cfg_min_TOFNsigmaPi", -3, "min n sigma pi in TOF"}; - // o2::framework::Configurable cfg_max_TOFNsigmaPi{"cfg_max_TOFNsigmaPi", +3, "max n sigma pi in TOF"}; - // o2::framework::Configurable cfg_min_TOFNsigmaKa{"cfg_min_TOFNsigmaKa", -3, "min n sigma ka in TOF"}; - // o2::framework::Configurable cfg_max_TOFNsigmaKa{"cfg_max_TOFNsigmaKa", +3, "max n sigma ka in TOF"}; - // o2::framework::Configurable cfg_min_TOFNsigmaPr{"cfg_min_TOFNsigmaPr", -3, "min n sigma pr in TOF"}; - // o2::framework::Configurable cfg_max_TOFNsigmaPr{"cfg_max_TOFNsigmaPr", +3, "max n sigma pr in TOF"}; - // o2::framework::Configurable applyTOFif{"applyTOFif", false, "apply TOFif for hadron identification"}; -}; - -struct cascadeCut : o2::framework::ConfigurableGroup { - std::string prefix = "cascadeCut"; - o2::framework::Configurable cfg_min_mass_lambda{"cfg_min_mass_lambda", 1.11, "min mass for lambda in cascade"}; - o2::framework::Configurable cfg_max_mass_lambda{"cfg_max_mass_lambda", 1.12, "max mass for lambda in cascade"}; - o2::framework::Configurable cfg_min_mass_Xi{"cfg_min_mass_Xi", 1.314, "min mass for Xi"}; - o2::framework::Configurable cfg_max_mass_Xi{"cfg_max_mass_Xi", 1.328, "max mass for Xi"}; - o2::framework::Configurable cfg_min_mass_Xi_veto{"cfg_min_mass_Xi_veto", 1.31, "min mass for Xi veto"}; - o2::framework::Configurable cfg_max_mass_Xi_veto{"cfg_max_mass_Xi_veto", 1.33, "max mass for Xi veto"}; - o2::framework::Configurable cfg_min_mass_Omega{"cfg_min_mass_Omega", 1.668, "min mass for Omega"}; - o2::framework::Configurable cfg_max_mass_Omega{"cfg_max_mass_Omega", 1.678, "max mass for Omega"}; - o2::framework::Configurable cfg_min_mass_Omega_veto{"cfg_min_mass_Omega_veto", 1.665, "min mass for Omega veto"}; - o2::framework::Configurable cfg_max_mass_Omega_veto{"cfg_max_mass_Omega_veto", 1.680, "max mass for Omega veto"}; - o2::framework::Configurable cfg_min_cospa_v0{"cfg_min_cospa_v0", 0.95, "minimum V0 CosPA in cascade"}; - o2::framework::Configurable cfg_max_dcadau_v0{"cfg_max_dcadau_v0", 0.1, "max distance between V0 Daughters in cascade"}; - o2::framework::Configurable cfg_min_cospa{"cfg_min_cospa", 0.95, "minimum cascade CosPA"}; - o2::framework::Configurable cfg_max_dcadau{"cfg_max_dcadau", 0.1, "max distance between bachelor and V0"}; - o2::framework::Configurable cfg_min_rxy_v0{"cfg_min_rxy_v0", 0.1, "minimum V0 rxy in cascade"}; - o2::framework::Configurable cfg_min_rxy{"cfg_min_rxy", 0.1, "minimum V0 rxy in cascade"}; - o2::framework::Configurable cfg_min_dcaxy_v0leg{"cfg_min_dcaxy_v0leg", 0.1, "min dca XY for v0 legs in cm"}; - o2::framework::Configurable cfg_min_dcaxy_bachelor{"cfg_min_dcaxy_bachelor", 0.05, "min dca XY for bachelor in cm"}; - o2::framework::Configurable cfg_min_dcaxy_v0{"cfg_min_dcaxy_v0", 0.0, "min dca XY for V0 in cm"}; -}; +// struct v0Cut : o2::framework::ConfigurableGroup { +// std::string prefix = "v0Cut"; +// o2::framework::Configurable cfg_min_mass_k0s{"cfg_min_mass_k0s", 0.48, "min mass for K0S"}; +// o2::framework::Configurable cfg_max_mass_k0s{"cfg_max_mass_k0s", 0.51, "max mass for K0S"}; +// o2::framework::Configurable cfg_min_mass_k0s_veto{"cfg_min_mass_k0s_veto", 0.48, "min mass for K0S veto for Lambda"}; +// o2::framework::Configurable cfg_max_mass_k0s_veto{"cfg_max_mass_k0s_veto", 0.51, "max mass for K0S veto for Lambda"}; +// o2::framework::Configurable cfg_min_mass_lambda{"cfg_min_mass_lambda", 1.11, "min mass for Lambda"}; +// o2::framework::Configurable cfg_max_mass_lambda{"cfg_max_mass_lambda", 1.12, "max mass for Lambda"}; +// o2::framework::Configurable cfg_min_mass_lambda_veto{"cfg_min_mass_lambda_veto", 1.11, "min mass for Lambda veto for K0S"}; +// o2::framework::Configurable cfg_max_mass_lambda_veto{"cfg_max_mass_lambda_veto", 1.12, "max mass for Lambda veto for K0S"}; +// o2::framework::Configurable cfg_min_cospa{"cfg_min_cospa", 0.95, "min cospa for v0"}; +// o2::framework::Configurable cfg_max_dca2legs{"cfg_max_dca2legs", 0.1, "max distance between 2 legs for v0"}; +// o2::framework::Configurable cfg_min_radius{"cfg_min_radius", 0.1, "min rxy for v"}; +// o2::framework::Configurable cfg_min_cr2findable_ratio_tpc{"cfg_min_cr2findable_ratio_tpc", 0.f, "min. TPC Ncr/Nf ratio"}; +// o2::framework::Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; +// o2::framework::Configurable cfg_min_ncrossedrows_tpc{"cfg_min_ncrossedrows_tpc", 70, "min ncrossed rows"}; +// o2::framework::Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; +// o2::framework::Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; +// o2::framework::Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; +// o2::framework::Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 2, "min ncluster its"}; +// o2::framework::Configurable cfg_min_ncluster_itsib{"cfg_min_ncluster_itsib", 0, "min ncluster itsib"}; +// o2::framework::Configurable cfg_min_dcaxy{"cfg_min_dcaxy", 0.1, "min dca XY for v0 legs in cm"}; +// +// o2::framework::Configurable cfg_max_alpha_veto{"cfg_max_alpha_veto", 0.95, "max alpha for photon conversion rejection"}; +// o2::framework::Configurable cfg_max_qt_veto{"cfg_max_qt_veto", 0.01, "max qT for photon conversion rejection"}; +// +// // for both v0 and cascade +// o2::framework::Configurable cfg_min_TPCNsigmaPi{"cfg_min_TPCNsigmaPi", -3, "min n sigma pi in TPC"}; +// o2::framework::Configurable cfg_max_TPCNsigmaPi{"cfg_max_TPCNsigmaPi", +3, "max n sigma pi in TPC"}; +// o2::framework::Configurable cfg_min_TPCNsigmaKa{"cfg_min_TPCNsigmaKa", -3, "min n sigma ka in TPC"}; +// o2::framework::Configurable cfg_max_TPCNsigmaKa{"cfg_max_TPCNsigmaKa", +3, "max n sigma ka in TPC"}; +// o2::framework::Configurable cfg_min_TPCNsigmaPr{"cfg_min_TPCNsigmaPr", -3, "min n sigma pr in TPC"}; +// o2::framework::Configurable cfg_max_TPCNsigmaPr{"cfg_max_TPCNsigmaPr", +3, "max n sigma pr in TPC"}; +// }; +// +// struct cascadeCut : o2::framework::ConfigurableGroup { +// std::string prefix = "cascadeCut"; +// o2::framework::Configurable cfg_min_mass_lambda{"cfg_min_mass_lambda", 1.11, "min mass for lambda in cascade"}; +// o2::framework::Configurable cfg_max_mass_lambda{"cfg_max_mass_lambda", 1.12, "max mass for lambda in cascade"}; +// o2::framework::Configurable cfg_min_mass_Xi{"cfg_min_mass_Xi", 1.314, "min mass for Xi"}; +// o2::framework::Configurable cfg_max_mass_Xi{"cfg_max_mass_Xi", 1.328, "max mass for Xi"}; +// o2::framework::Configurable cfg_min_mass_Xi_veto{"cfg_min_mass_Xi_veto", 1.31, "min mass for Xi veto"}; +// o2::framework::Configurable cfg_max_mass_Xi_veto{"cfg_max_mass_Xi_veto", 1.33, "max mass for Xi veto"}; +// o2::framework::Configurable cfg_min_mass_Omega{"cfg_min_mass_Omega", 1.668, "min mass for Omega"}; +// o2::framework::Configurable cfg_max_mass_Omega{"cfg_max_mass_Omega", 1.678, "max mass for Omega"}; +// o2::framework::Configurable cfg_min_mass_Omega_veto{"cfg_min_mass_Omega_veto", 1.665, "min mass for Omega veto"}; +// o2::framework::Configurable cfg_max_mass_Omega_veto{"cfg_max_mass_Omega_veto", 1.680, "max mass for Omega veto"}; +// o2::framework::Configurable cfg_min_cospa_v0{"cfg_min_cospa_v0", 0.95, "minimum V0 CosPA in cascade"}; +// o2::framework::Configurable cfg_max_dcadau_v0{"cfg_max_dcadau_v0", 0.1, "max distance between V0 Daughters in cascade"}; +// o2::framework::Configurable cfg_min_cospa{"cfg_min_cospa", 0.95, "minimum cascade CosPA"}; +// o2::framework::Configurable cfg_max_dcadau{"cfg_max_dcadau", 0.1, "max distance between bachelor and V0"}; +// o2::framework::Configurable cfg_min_rxy_v0{"cfg_min_rxy_v0", 0.1, "minimum V0 rxy in cascade"}; +// o2::framework::Configurable cfg_min_rxy{"cfg_min_rxy", 0.1, "minimum V0 rxy in cascade"}; +// o2::framework::Configurable cfg_min_dcaxy_v0leg{"cfg_min_dcaxy_v0leg", 0.1, "min dca XY for v0 legs in cm"}; +// o2::framework::Configurable cfg_min_dcaxy_bachelor{"cfg_min_dcaxy_bachelor", 0.05, "min dca XY for bachelor in cm"}; +// o2::framework::Configurable cfg_min_dcaxy_v0{"cfg_min_dcaxy_v0", 0.0, "min dca XY for V0 in cm"}; +// }; struct cfgDFeT : o2::framework::ConfigurableGroup { std::string prefix = "cfgDFeT"; @@ -285,41 +274,41 @@ struct cfgDFeT : o2::framework::ConfigurableGroup { o2::framework::Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; }; -struct cfgDFeV0 : o2::framework::ConfigurableGroup { - std::string prefix = "cfgDFeV0"; - o2::framework::Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; - o2::framework::Configurable useWeightedFinalPCA{"useWeightedFinalPCA", false, "Recalculate vertex position using track covariances, effective only if useAbsDCA is true"}; - o2::framework::Configurable maxChi2PCA{"maxChi2PCA", 1.0, "max chi2 at PCA"}; - o2::framework::Configurable maxMassLH{"maxMassLH", 5.5, "max massLH in GeV/c2"}; // set hb mass. SVs whose mass is above this mass cannot be HF hadrons. - // configuration for PID ML - o2::framework::Configurable useML{"useML", false, "Flag to use PID ML"}; - o2::framework::Configurable> onnxFileNames{"onnxFileNames", std::vector{"filename"}, "ONNX file names for each bin (if not from CCDB full path)"}; - o2::framework::Configurable> onnxPathsCCDB{"onnxPathsCCDB", std::vector{"path"}, "Paths of models on CCDB"}; - o2::framework::Configurable> binsMl{"binsMl", std::vector{0.1, 0.4, 0.8, 1.0, 2.0, 4, 20}, "Bin limits for ML application"}; - // o2::framework::Configurable> cutsMl{"cutsMl", std::vector{0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9}, "ML cuts per bin"}; - o2::framework::Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"ptH", "impPar3DHinSigma", "massLH", "logChi2PCA", "cpa", "cpaXY", "decayLength3DinSigma"}, "Names of ML model input features"}; - o2::framework::Configurable nameBinningFeature{"nameBinningFeature", "ptL", "Names of ML model binning feature"}; - o2::framework::Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; - o2::framework::Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; -}; - -struct cfgDFeC : o2::framework::ConfigurableGroup { - std::string prefix = "cfgDFeC"; - o2::framework::Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; - o2::framework::Configurable useWeightedFinalPCA{"useWeightedFinalPCA", false, "Recalculate vertex position using track covariances, effective only if useAbsDCA is true"}; - o2::framework::Configurable maxChi2PCA{"maxChi2PCA", 1.0, "max chi2 at PCA"}; - o2::framework::Configurable maxMassLH{"maxMassLH", 5.5, "max massLH in GeV/c2"}; // set hb mass. SVs whose mass is above this mass cannot be HF hadrons. - // configuration for PID ML - o2::framework::Configurable useML{"useML", false, "Flag to use PID ML"}; - o2::framework::Configurable> onnxFileNames{"onnxFileNames", std::vector{"filename"}, "ONNX file names for each bin (if not from CCDB full path)"}; - o2::framework::Configurable> onnxPathsCCDB{"onnxPathsCCDB", std::vector{"path"}, "Paths of models on CCDB"}; - o2::framework::Configurable> binsMl{"binsMl", std::vector{0.1, 0.4, 0.8, 1.0, 2.0, 4, 20}, "Bin limits for ML application"}; - // o2::framework::Configurable> cutsMl{"cutsMl", std::vector{0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9}, "ML cuts per bin"}; - o2::framework::Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"ptH", "impPar3DHinSigma", "massLH", "logChi2PCA", "cpa", "cpaXY", "decayLength3DinSigma"}, "Names of ML model input features"}; - o2::framework::Configurable nameBinningFeature{"nameBinningFeature", "ptL", "Names of ML model binning feature"}; - o2::framework::Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; - o2::framework::Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; -}; +// struct cfgDFeV0 : o2::framework::ConfigurableGroup { +// std::string prefix = "cfgDFeV0"; +// o2::framework::Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; +// o2::framework::Configurable useWeightedFinalPCA{"useWeightedFinalPCA", false, "Recalculate vertex position using track covariances, effective only if useAbsDCA is true"}; +// o2::framework::Configurable maxChi2PCA{"maxChi2PCA", 1.0, "max chi2 at PCA"}; +// o2::framework::Configurable maxMassLH{"maxMassLH", 5.5, "max massLH in GeV/c2"}; // set hb mass. SVs whose mass is above this mass cannot be HF hadrons. +// // configuration for PID ML +// o2::framework::Configurable useML{"useML", false, "Flag to use PID ML"}; +// o2::framework::Configurable> onnxFileNames{"onnxFileNames", std::vector{"filename"}, "ONNX file names for each bin (if not from CCDB full path)"}; +// o2::framework::Configurable> onnxPathsCCDB{"onnxPathsCCDB", std::vector{"path"}, "Paths of models on CCDB"}; +// o2::framework::Configurable> binsMl{"binsMl", std::vector{0.1, 0.4, 0.8, 1.0, 2.0, 4, 20}, "Bin limits for ML application"}; +// // o2::framework::Configurable> cutsMl{"cutsMl", std::vector{0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9}, "ML cuts per bin"}; +// o2::framework::Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"ptH", "impPar3DHinSigma", "massLH", "logChi2PCA", "cpa", "cpaXY", "decayLength3DinSigma"}, "Names of ML model input features"}; +// o2::framework::Configurable nameBinningFeature{"nameBinningFeature", "ptL", "Names of ML model binning feature"}; +// o2::framework::Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; +// o2::framework::Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; +// }; +// +// struct cfgDFeC : o2::framework::ConfigurableGroup { +// std::string prefix = "cfgDFeC"; +// o2::framework::Configurable useAbsDCA{"useAbsDCA", true, "Minimise abs. distance rather than chi2"}; +// o2::framework::Configurable useWeightedFinalPCA{"useWeightedFinalPCA", false, "Recalculate vertex position using track covariances, effective only if useAbsDCA is true"}; +// o2::framework::Configurable maxChi2PCA{"maxChi2PCA", 1.0, "max chi2 at PCA"}; +// o2::framework::Configurable maxMassLH{"maxMassLH", 5.5, "max massLH in GeV/c2"}; // set hb mass. SVs whose mass is above this mass cannot be HF hadrons. +// // configuration for PID ML +// o2::framework::Configurable useML{"useML", false, "Flag to use PID ML"}; +// o2::framework::Configurable> onnxFileNames{"onnxFileNames", std::vector{"filename"}, "ONNX file names for each bin (if not from CCDB full path)"}; +// o2::framework::Configurable> onnxPathsCCDB{"onnxPathsCCDB", std::vector{"path"}, "Paths of models on CCDB"}; +// o2::framework::Configurable> binsMl{"binsMl", std::vector{0.1, 0.4, 0.8, 1.0, 2.0, 4, 20}, "Bin limits for ML application"}; +// // o2::framework::Configurable> cutsMl{"cutsMl", std::vector{0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9}, "ML cuts per bin"}; +// o2::framework::Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"ptH", "impPar3DHinSigma", "massLH", "logChi2PCA", "cpa", "cpaXY", "decayLength3DinSigma"}, "Names of ML model input features"}; +// o2::framework::Configurable nameBinningFeature{"nameBinningFeature", "ptL", "Names of ML model binning feature"}; +// o2::framework::Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; +// o2::framework::Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; +// }; class ElectronModule { @@ -339,8 +328,8 @@ class ElectronModule // float phi{1e+10}; // }; - template - void init(TElectronCut const& eCut, TElectronPFCut const& ePFCut, THadronCut const& hCut, TV0Cut const& v0Cut, TCascadeCut const& cascadeCut, TDFConfigET const& cfgET, TDFConfigEV0 const& cfgEV0, TDFConfigEC const& cfgEC, TInitContext& initContext, TCCDB& ccdb, TTOFResponse const& tofResponse, std::string const& ccdburl) + template + void init(TElectronCut const& eCut, TElectronPFCut const& ePFCut, THadronCut const& hCut, /*TV0Cut const& v0Cut, TCascadeCut const& cascadeCut,*/ TDFConfigET const& cfgET, /*TDFConfigEV0 const& cfgEV0, TDFConfigEC const& cfgEC,*/ TInitContext& initContext, TCCDB& ccdb, TTOFResponse const& tofResponse, std::string const& ccdburl) { mRunNumber = 0; d_bz = 0; @@ -351,15 +340,14 @@ class ElectronModule fElectronCut = eCut; fElectronPFCut = ePFCut; fHadronCut = hCut; - fV0Cut = v0Cut; - fCascadeCut = cascadeCut; + // fV0Cut = v0Cut; + // fCascadeCut = cascadeCut; fConfigDFeT = cfgET; - fConfigDFeV0 = cfgEV0; - fConfigDFeC = cfgEC; + // fConfigDFeV0 = cfgEV0; + // fConfigDFeC = cfgEC; LOGF(info, "intializing TOFResponse"); mTOFResponse = tofResponse; - // mTOFResponse->initSetup(&ccdb->instance(), initContext); mTOFResponse->initSetup(ccdb, initContext); dfeT.setPropagateToPCA(true); @@ -372,25 +360,25 @@ class ElectronModule dfeT.setWeightedFinalPCA(fConfigDFeT.useWeightedFinalPCA); dfeT.setMatCorrType(matCorr); - dfeV0.setPropagateToPCA(true); - dfeV0.setMaxR(200.f); - dfeV0.setMinParamChange(1e-3); - dfeV0.setMinRelChi2Change(0.9); - dfeV0.setMaxDZIni(1e9); - dfeV0.setMaxChi2(1e9); - dfeV0.setUseAbsDCA(fConfigDFeV0.useAbsDCA); - dfeV0.setWeightedFinalPCA(fConfigDFeV0.useWeightedFinalPCA); - dfeV0.setMatCorrType(matCorr); - - dfeC.setPropagateToPCA(true); - dfeC.setMaxR(200.f); - dfeC.setMinParamChange(1e-3); - dfeC.setMinRelChi2Change(0.9); - dfeC.setMaxDZIni(1e9); - dfeC.setMaxChi2(1e9); - dfeC.setUseAbsDCA(fConfigDFeC.useAbsDCA); - dfeC.setWeightedFinalPCA(fConfigDFeC.useWeightedFinalPCA); - dfeC.setMatCorrType(matCorr); + // dfeV0.setPropagateToPCA(true); + // dfeV0.setMaxR(200.f); + // dfeV0.setMinParamChange(1e-3); + // dfeV0.setMinRelChi2Change(0.9); + // dfeV0.setMaxDZIni(1e9); + // dfeV0.setMaxChi2(1e9); + // dfeV0.setUseAbsDCA(fConfigDFeV0.useAbsDCA); + // dfeV0.setWeightedFinalPCA(fConfigDFeV0.useWeightedFinalPCA); + // dfeV0.setMatCorrType(matCorr); + + // dfeC.setPropagateToPCA(true); + // dfeC.setMaxR(200.f); + // dfeC.setMinParamChange(1e-3); + // dfeC.setMinRelChi2Change(0.9); + // dfeC.setMaxDZIni(1e9); + // dfeC.setMaxChi2(1e9); + // dfeC.setUseAbsDCA(fConfigDFeC.useAbsDCA); + // dfeC.setWeightedFinalPCA(fConfigDFeC.useWeightedFinalPCA); + // dfeC.setMatCorrType(matCorr); } template @@ -403,6 +391,10 @@ class ElectronModule d_bz = o2::base::Propagator::Instance()->getNominalBz(); LOG(info) << "Configuring for timestamp " << bc.timestamp() << " with magnetic field of " << d_bz << " kG"; + dfeT.setBz(d_bz); + // dfeV0.setBz(d_bz); + // dfeC.setBz(d_bz); + // initialize MLResponse if (fElectronCut.usePIDML) { LOGF(info, "loading ONNX for ML PID"); @@ -456,58 +448,58 @@ class ElectronModule mlResponseSCTeT.init(fConfigDFeT.enableOptimizations); } // end of ML SCTeT - if (fConfigDFeV0.useML) { - LOGF(info, "loading ONNX for SCT eV0"); - static constexpr int nClassesMl = 4; - const std::vector cutDirMl = {o2::cuts_ml::CutNot, o2::cuts_ml::CutNot, o2::cuts_ml::CutNot, o2::cuts_ml::CutNot}; - const std::vector labelsClasses = {"background", "prompthc", "nonprompthc", "hb"}; - const uint32_t nBinsMl = fConfigDFeV0.binsMl.value.size() - 1; - const std::vector labelsBins(nBinsMl, "bin"); - double cutsMlArr[nBinsMl][nClassesMl]; - for (uint32_t i = 0; i < nBinsMl; i++) { - cutsMlArr[i][0] = 0.0; - cutsMlArr[i][1] = 0.0; - cutsMlArr[i][2] = 0.0; - cutsMlArr[i][3] = 0.0; - } - o2::framework::LabeledArray cutsMltmp = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; + // if (fConfigDFeV0.useML) { + // LOGF(info, "loading ONNX for SCT eV0"); + // static constexpr int nClassesMl = 4; + // const std::vector cutDirMl = {o2::cuts_ml::CutNot, o2::cuts_ml::CutNot, o2::cuts_ml::CutNot, o2::cuts_ml::CutNot}; + // const std::vector labelsClasses = {"background", "prompthc", "nonprompthc", "hb"}; + // const uint32_t nBinsMl = fConfigDFeV0.binsMl.value.size() - 1; + // const std::vector labelsBins(nBinsMl, "bin"); + // double cutsMlArr[nBinsMl][nClassesMl]; + // for (uint32_t i = 0; i < nBinsMl; i++) { + // cutsMlArr[i][0] = 0.0; + // cutsMlArr[i][1] = 0.0; + // cutsMlArr[i][2] = 0.0; + // cutsMlArr[i][3] = 0.0; + // } + // o2::framework::LabeledArray cutsMltmp = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; - mlResponseSCTeV0.configure(fConfigDFeV0.binsMl.value, cutsMltmp, cutDirMl, nClassesMl); - if (fConfigDFeV0.loadModelsFromCCDB) { - mlResponseSCTeV0.setModelPathsCCDB(fConfigDFeV0.onnxFileNames, ccdbApi, fConfigDFeV0.onnxPathsCCDB, bc.timestamp()); - } else { - mlResponseSCTeV0.setModelPathsLocal(fConfigDFeV0.onnxFileNames); - } - mlResponseSCTeV0.cacheInputFeaturesIndices(fConfigDFeV0.namesInputFeatures); - mlResponseSCTeV0.cacheBinningIndex(fConfigDFeV0.nameBinningFeature); - mlResponseSCTeV0.init(fConfigDFeV0.enableOptimizations); - } // end of ML SCTeV0 - - if (fConfigDFeC.useML) { - LOGF(info, "loading ONNX for SCT eC"); - static constexpr int nClassesMl = 3; - const std::vector cutDirMl = {o2::cuts_ml::CutNot, o2::cuts_ml::CutNot, o2::cuts_ml::CutNot}; - const std::vector labelsClasses = {"background", "prompthc", "nonprompthc"}; - const uint32_t nBinsMl = fConfigDFeC.binsMl.value.size() - 1; - const std::vector labelsBins(nBinsMl, "bin"); - double cutsMlArr[nBinsMl][nClassesMl]; - for (uint32_t i = 0; i < nBinsMl; i++) { - cutsMlArr[i][0] = 0.0; - cutsMlArr[i][1] = 0.0; - cutsMlArr[i][2] = 0.0; - } - o2::framework::LabeledArray cutsMltmp = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; + // mlResponseSCTeV0.configure(fConfigDFeV0.binsMl.value, cutsMltmp, cutDirMl, nClassesMl); + // if (fConfigDFeV0.loadModelsFromCCDB) { + // mlResponseSCTeV0.setModelPathsCCDB(fConfigDFeV0.onnxFileNames, ccdbApi, fConfigDFeV0.onnxPathsCCDB, bc.timestamp()); + // } else { + // mlResponseSCTeV0.setModelPathsLocal(fConfigDFeV0.onnxFileNames); + // } + // mlResponseSCTeV0.cacheInputFeaturesIndices(fConfigDFeV0.namesInputFeatures); + // mlResponseSCTeV0.cacheBinningIndex(fConfigDFeV0.nameBinningFeature); + // mlResponseSCTeV0.init(fConfigDFeV0.enableOptimizations); + // } // end of ML SCTeV0 + + // if (fConfigDFeC.useML) { + // LOGF(info, "loading ONNX for SCT eC"); + // static constexpr int nClassesMl = 3; + // const std::vector cutDirMl = {o2::cuts_ml::CutNot, o2::cuts_ml::CutNot, o2::cuts_ml::CutNot}; + // const std::vector labelsClasses = {"background", "prompthc", "nonprompthc"}; + // const uint32_t nBinsMl = fConfigDFeC.binsMl.value.size() - 1; + // const std::vector labelsBins(nBinsMl, "bin"); + // double cutsMlArr[nBinsMl][nClassesMl]; + // for (uint32_t i = 0; i < nBinsMl; i++) { + // cutsMlArr[i][0] = 0.0; + // cutsMlArr[i][1] = 0.0; + // cutsMlArr[i][2] = 0.0; + // } + // o2::framework::LabeledArray cutsMltmp = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; - mlResponseSCTeC.configure(fConfigDFeC.binsMl.value, cutsMltmp, cutDirMl, nClassesMl); - if (fConfigDFeC.loadModelsFromCCDB) { - mlResponseSCTeC.setModelPathsCCDB(fConfigDFeC.onnxFileNames, ccdbApi, fConfigDFeC.onnxPathsCCDB, bc.timestamp()); - } else { - mlResponseSCTeC.setModelPathsLocal(fConfigDFeC.onnxFileNames); - } - mlResponseSCTeC.cacheInputFeaturesIndices(fConfigDFeC.namesInputFeatures); - mlResponseSCTeC.cacheBinningIndex(fConfigDFeC.nameBinningFeature); - mlResponseSCTeC.init(fConfigDFeC.enableOptimizations); - } // end of ML SCTeC + // mlResponseSCTeC.configure(fConfigDFeC.binsMl.value, cutsMltmp, cutDirMl, nClassesMl); + // if (fConfigDFeC.loadModelsFromCCDB) { + // mlResponseSCTeC.setModelPathsCCDB(fConfigDFeC.onnxFileNames, ccdbApi, fConfigDFeC.onnxPathsCCDB, bc.timestamp()); + // } else { + // mlResponseSCTeC.setModelPathsLocal(fConfigDFeC.onnxFileNames); + // } + // mlResponseSCTeC.cacheInputFeaturesIndices(fConfigDFeC.namesInputFeatures); + // mlResponseSCTeC.cacheBinningIndex(fConfigDFeC.nameBinningFeature); + // mlResponseSCTeC.init(fConfigDFeC.enableOptimizations); + // } // end of ML SCTeC mRunNumber = bc.runNumber(); mTOFResponse->processSetup(bc); @@ -521,6 +513,7 @@ class ElectronModule registry.add("Track/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", o2::framework::HistType::kTH2F, {{180, 0, 2 * M_PI}, {20, -1.0f, 1.0f}}, false); registry.add("Track/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", o2::framework::HistType::kTH2F, {{200, -1.0f, 1.0f}, {200, -1.0f, 1.0f}}, false); registry.add("Track/hDCAxyzSigma", "DCA xy vs. z;DCA_{xy} (#sigma);DCA_{z} (#sigma)", o2::framework::HistType::kTH2F, {{200, -10.0f, 10.0f}, {200, -10.0f, 10.0f}}, false); + registry.add("Track/hDCA3dSigma", "DCA 3d;DCA_{3D} (#sigma);", o2::framework::HistType::kTH1F, {{100, 0.0f, 10.0f}}, false); registry.add("Track/hDCAxyRes_Pt", "DCA_{xy} resolution vs. pT;p_{T} (GeV/c);DCA_{xy} resolution (#mum)", o2::framework::HistType::kTH2F, {{1000, 0, 10}, {500, 0., 500}}, false); registry.add("Track/hDCAzRes_Pt", "DCA_{z} resolution vs. pT;p_{T} (GeV/c);DCA_{z} resolution (#mum)", o2::framework::HistType::kTH2F, {{1000, 0, 10}, {500, 0., 500}}, false); registry.add("Track/hNclsTPC", "number of TPC clusters", o2::framework::HistType::kTH1F, {{161, -0.5, 160.5}}, false); @@ -531,7 +524,7 @@ class ElectronModule registry.add("Track/hTPCNcls2Nf", "TPC Ncls/Nfindable", o2::framework::HistType::kTH1F, {{200, 0, 2}}, false); registry.add("Track/hTPCNclsShared", "TPC Ncls shared/Ncls;p_{T} (GeV/c);N_{cls}^{shared}/N_{cls} in TPC", o2::framework::HistType::kTH2F, {{1000, 0, 10}, {100, 0, 1}}, false); registry.add("Track/hNclsITS", "number of ITS clusters", o2::framework::HistType::kTH1F, {{8, -0.5, 7.5}}, false); - registry.add("Track/hChi2ITS", "chi2/number of ITS clusters", o2::framework::HistType::kTH1F, {{100, 0, 10}}, false); + registry.add("Track/hChi2ITS", "chi2/number of ITS clusters", o2::framework::HistType::kTH1F, {{72, 0, 36}}, false); registry.add("Track/hITSClusterMap", "ITS cluster map", o2::framework::HistType::kTH1F, {{128, -0.5, 127.5}}, false); registry.add("Track/hTPCdEdx", "TPC dE/dx;p_{in} (GeV/c);TPC dE/dx (a.u.)", o2::framework::HistType::kTH2F, {{1000, 0, 10}, {200, 0, 200}}, false); registry.add("Track/hTPCdEdxMC", "TPC dE/dx;p_{in} (GeV/c);TPC dE/dx (a.u.)", o2::framework::HistType::kTH2F, {{1000, 0, 10}, {200, 0, 200}}, false); @@ -704,7 +697,7 @@ class ElectronModule o2::dataformats::DCA mDcaInfoCov; mDcaInfoCov.set(999, 999, 999, 999, 999); auto trackParCov = getTrackParCov(track); - trackParCov.setPID(o2::track::PID::Electron); + trackParCov.setPID(fElectronCut.useElectronHypothesis ? o2::track::PID::Electron : track.pidForTracking()); bool isPropOK = o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); if (!isPropOK) { return; @@ -806,7 +799,7 @@ class ElectronModule o2::dataformats::DCA mDcaInfoCov; mDcaInfoCov.set(999, 999, 999, 999, 999); auto trackParCov = getTrackParCov(track); - trackParCov.setPID(o2::track::PID::Electron); + trackParCov.setPID(fElectronCut.useElectronHypothesis ? o2::track::PID::Electron : track.pidForTracking()); bool isPropOK = o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); if (!isPropOK) { return false; @@ -818,6 +811,10 @@ class ElectronModule return false; } + if ((std::array{dca3DinSigmaOTF(dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZ2(), trackParCov.getSigmaZY()), dcaXY / std::sqrt(trackParCov.getSigmaY2()), dcaZ / std::sqrt(trackParCov.getSigmaZ2())}[fElectronCut.dcaType]) > fElectronCut.max_dca_in_sigma) { + return false; + } + if (trackParCov.getPt() < fElectronCut.minpt || std::fabs(trackParCov.getEta()) > fElectronCut.maxeta) { return false; } @@ -884,7 +881,7 @@ class ElectronModule o2::dataformats::DCA mDcaInfoCov; mDcaInfoCov.set(999, 999, 999, 999, 999); auto trackParCov = getTrackParCov(track); - trackParCov.setPID(o2::track::PID::Electron); + trackParCov.setPID(fElectronCut.useElectronHypothesis ? o2::track::PID::Electron : track.pidForTracking()); bool isPropOK = o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); if (!isPropOK) { return false; @@ -1128,6 +1125,7 @@ class ElectronModule registry.fill(HIST("Track/hEtaPhi"), phi, eta); registry.fill(HIST("Track/hDCAxyz"), dcaXY, dcaZ); registry.fill(HIST("Track/hDCAxyzSigma"), dcaXY / std::sqrt(trackParCov.getSigmaY2()), dcaZ / std::sqrt(trackParCov.getSigmaZ2())); + registry.fill(HIST("Track/hDCA3dSigma"), dca3DinSigmaOTF(dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZ2(), trackParCov.getSigmaZY())); registry.fill(HIST("Track/hDCAxyRes_Pt"), pt, std::sqrt(trackParCov.getSigmaY2()) * 1e+4); // convert cm to um registry.fill(HIST("Track/hDCAzRes_Pt"), pt, std::sqrt(trackParCov.getSigmaZ2()) * 1e+4); // convert cm to um registry.fill(HIST("Track/hNclsITS"), track.itsNCls()); @@ -1166,191 +1164,191 @@ class ElectronModule return is_pi_included_TPC || is_ka_included_TPC; } - template - bool isSelectedV0Leg(TTrack const& track) - { - if constexpr (isMC) { - if (!track.has_mcParticle()) { - return false; - } - } - - if (!track.hasITS() || !track.hasTPC()) { - return false; - } - - if (track.itsChi2NCl() > fV0Cut.cfg_max_chi2its) { - return false; - } - - if (track.itsNCls() < fV0Cut.cfg_min_ncluster_its) { - return false; - } - - if (track.itsNClsInnerBarrel() < fV0Cut.cfg_min_ncluster_itsib) { - return false; - } - - if (track.tpcChi2NCl() > fV0Cut.cfg_max_chi2tpc) { - return false; - } - - if (track.tpcNClsFound() < fV0Cut.cfg_min_ncluster_tpc) { - return false; - } - - if (track.tpcNClsCrossedRows() < fV0Cut.cfg_min_ncrossedrows_tpc) { - return false; - } - - if (track.tpcCrossedRowsOverFindableCls() < fV0Cut.cfg_min_cr2findable_ratio_tpc) { - return false; - } - - if (track.tpcFractionSharedCls() > fV0Cut.cfg_max_frac_shared_clusters_tpc) { - return false; - } - - return true; - } - - template - bool isPion(TTrack const& track) - { - return fV0Cut.cfg_min_TPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < fV0Cut.cfg_max_TPCNsigmaPi; - } - - template - bool isKaon(TTrack const& track) - { - return fV0Cut.cfg_min_TPCNsigmaKa < track.tpcNSigmaKa() && track.tpcNSigmaKa() < fV0Cut.cfg_max_TPCNsigmaKa; - } - - template - bool isProton(TTrack const& track) - { - return fV0Cut.cfg_min_TPCNsigmaPr < track.tpcNSigmaPr() && track.tpcNSigmaPr() < fV0Cut.cfg_max_TPCNsigmaPr; - } - - template - bool isK0S(TV0 const& v0) - { - return (fV0Cut.cfg_min_mass_k0s < v0.mK0Short() && v0.mK0Short() < fV0Cut.cfg_max_mass_k0s) && (v0.mLambda() < fV0Cut.cfg_min_mass_lambda_veto || fV0Cut.cfg_max_mass_lambda_veto < v0.mLambda()) && (v0.mAntiLambda() < fV0Cut.cfg_min_mass_lambda_veto || fV0Cut.cfg_max_mass_lambda_veto < v0.mAntiLambda()); - } - - template - bool isLambda(TV0 const& v0) - { - return (fV0Cut.cfg_min_mass_lambda < v0.mLambda() && v0.mLambda() < fV0Cut.cfg_max_mass_lambda) && (v0.mK0Short() < fV0Cut.cfg_min_mass_k0s_veto || fV0Cut.cfg_max_mass_k0s_veto < v0.mK0Short()); - } - - template - bool isAntiLambda(TV0 const& v0) - { - return (fV0Cut.cfg_min_mass_lambda < v0.mAntiLambda() && v0.mAntiLambda() < fV0Cut.cfg_max_mass_lambda) && (v0.mK0Short() < fV0Cut.cfg_min_mass_k0s_veto || fV0Cut.cfg_max_mass_k0s_veto < v0.mK0Short()); - } - - template - bool isXi(TCascade const& cascade) - { - return (fCascadeCut.cfg_min_mass_Xi < cascade.mXi() && cascade.mXi() < fCascadeCut.cfg_max_mass_Xi) && (cascade.mOmega() < fCascadeCut.cfg_min_mass_Omega_veto || fCascadeCut.cfg_max_mass_Omega_veto < cascade.mOmega()); - } - - template - bool isOmega(TCascade const& cascade) - { - return (fCascadeCut.cfg_min_mass_Omega < cascade.mOmega() && cascade.mOmega() < fCascadeCut.cfg_max_mass_Omega) && (cascade.mXi() < fCascadeCut.cfg_min_mass_Xi_veto || fCascadeCut.cfg_max_mass_Xi_veto < cascade.mXi()); - } - - template - void fillV0Histograms(TCollision const&, TV0 const& v0, THistoregistry& registry) - { - auto pos = v0.template posTrack_as(); - auto neg = v0.template negTrack_as(); - registry.fill(HIST("SCT/V0/hPt"), v0.pt()); - registry.fill(HIST("SCT/V0/hAP"), v0.alpha(), v0.qtarm()); - registry.fill(HIST("SCT/V0/hCosPA"), v0.v0cosPA()); - registry.fill(HIST("SCT/V0/hLxy"), v0.v0radius()); - registry.fill(HIST("SCT/V0/hDCA2Legs"), v0.dcaV0daughters()); - - if (isPion(pos) && isPion(neg)) { - if ((v0.mLambda() < fV0Cut.cfg_min_mass_lambda_veto || fV0Cut.cfg_max_mass_lambda_veto < v0.mLambda()) && (v0.mAntiLambda() < fV0Cut.cfg_min_mass_lambda_veto || fV0Cut.cfg_max_mass_lambda_veto < v0.mAntiLambda())) { - registry.fill(HIST("SCT/V0/hMassK0S"), v0.mK0Short()); - registry.fill(HIST("SCT/V0/hYPhi_K0S"), v0.phi(), v0.yK0Short()); - } - registry.fill(HIST("SCT/V0/hMassGamma_misid"), v0.mGamma()); - registry.fill(HIST("SCT/V0/hMassLambda_misid"), v0.mLambda()); - registry.fill(HIST("SCT/V0/hMassAntiLambda_misid"), v0.mAntiLambda()); - } - - if (isProton(pos) && isPion(neg)) { - if (v0.mK0Short() < fV0Cut.cfg_min_mass_k0s_veto || fV0Cut.cfg_max_mass_k0s_veto < v0.mK0Short()) { - registry.fill(HIST("SCT/V0/hMassLambda"), v0.mLambda()); - registry.fill(HIST("SCT/V0/hYPhi_Lambda"), v0.phi(), v0.yLambda()); - } - registry.fill(HIST("SCT/V0/hMassGamma_misid"), v0.mGamma()); - registry.fill(HIST("SCT/V0/hMassK0S_misid"), v0.mK0Short()); - } - - if (isProton(neg) && isPion(pos)) { - if (v0.mK0Short() < fV0Cut.cfg_min_mass_k0s_veto || fV0Cut.cfg_max_mass_k0s_veto < v0.mK0Short()) { - registry.fill(HIST("SCT/V0/hMassAntiLambda"), v0.mAntiLambda()); - registry.fill(HIST("SCT/V0/hYPhi_Lambda"), v0.phi(), v0.yLambda()); - } - registry.fill(HIST("SCT/V0/hMassGamma_misid"), v0.mGamma()); - registry.fill(HIST("SCT/V0/hMassK0S_misid"), v0.mK0Short()); - } - } - - template - void fillCascadeHistograms(TCollision const& collision, TCascade const& cascade, THistoregistry& registry) - { - auto pos = cascade.template posTrack_as(); - auto neg = cascade.template negTrack_as(); - auto bachelor = cascade.template bachelor_as(); - - registry.fill(HIST("SCT/Cascade/hPt"), cascade.pt()); - registry.fill(HIST("SCT/Cascade/hMassLambda"), cascade.mLambda()); - registry.fill(HIST("SCT/Cascade/hCosPA"), cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ())); - registry.fill(HIST("SCT/Cascade/hDCA2Legs"), cascade.dcacascdaughters()); - registry.fill(HIST("SCT/Cascade/hV0CosPA"), cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); - registry.fill(HIST("SCT/Cascade/hV0DCA2Legs"), cascade.dcaV0daughters()); - - if (cascade.sign() < 0) { // Xi- or Omega- - if (isPion(bachelor) && isProton(pos) && isPion(neg)) { - if (cascade.mOmega() < fCascadeCut.cfg_min_mass_Omega_veto || fCascadeCut.cfg_max_mass_Omega_veto < cascade.mOmega()) { - registry.fill(HIST("SCT/Cascade/hMassXi"), cascade.mXi()); - registry.fill(HIST("SCT/Cascade/hYPhi_Xi"), cascade.phi(), cascade.yXi()); - } - registry.fill(HIST("SCT/Cascade/hMassOmega_misid"), cascade.mOmega()); - } - if (isKaon(bachelor) && isProton(pos) && isPion(neg)) { - if (cascade.mXi() < fCascadeCut.cfg_min_mass_Xi_veto || fCascadeCut.cfg_max_mass_Xi_veto < cascade.mXi()) { - registry.fill(HIST("SCT/Cascade/hMassOmega"), cascade.mOmega()); - registry.fill(HIST("SCT/Cascade/hYPhi_Omega"), cascade.phi(), cascade.yOmega()); - } - registry.fill(HIST("SCT/Cascade/hMassXi_misid"), cascade.mXi()); - } - } else { // Xi+ or Omega+ - if (isPion(bachelor) && isProton(neg) && isPion(pos)) { - if (cascade.mOmega() < fCascadeCut.cfg_min_mass_Omega_veto || fCascadeCut.cfg_max_mass_Omega_veto < cascade.mOmega()) { - registry.fill(HIST("SCT/Cascade/hMassXi"), cascade.mXi()); - registry.fill(HIST("SCT/Cascade/hYPhi_Xi"), cascade.phi(), cascade.yXi()); - } - registry.fill(HIST("SCT/Cascade/hMassOmega_misid"), cascade.mOmega()); - } - if (isKaon(bachelor) && isProton(neg) && isPion(pos)) { - if (cascade.mXi() < fCascadeCut.cfg_min_mass_Xi_veto || fCascadeCut.cfg_max_mass_Xi_veto < cascade.mXi()) { - registry.fill(HIST("SCT/Cascade/hMassOmega"), cascade.mOmega()); - registry.fill(HIST("SCT/Cascade/hYPhi_Omega"), cascade.phi(), cascade.yOmega()); - } - registry.fill(HIST("SCT/Cascade/hMassXi_misid"), cascade.mXi()); - } - } - } - - template - void processWithTTCA(TBCs const& bcs, TCollisions const& collisions, TTracks const& tracks, TV0s const& v0s, TCascades const& cascades, TTrackAssoc const& trackIndices, TMCParticles const&, TProducts& products, THistoregistry& registry, TSliceCache& cache, TPresliceTrack const& perColTrack, TPresliceTrackAssoc const& trackIndicesPerCollision, TPresliceV0 const& perColV0, TPresliceCascade const& perColCasc) + // template + // bool isSelectedV0Leg(TTrack const& track) + // { + // if constexpr (isMC) { + // if (!track.has_mcParticle()) { + // return false; + // } + // } + + // if (!track.hasITS() || !track.hasTPC()) { + // return false; + // } + + // if (track.itsChi2NCl() > fV0Cut.cfg_max_chi2its) { + // return false; + // } + + // if (track.itsNCls() < fV0Cut.cfg_min_ncluster_its) { + // return false; + // } + + // if (track.itsNClsInnerBarrel() < fV0Cut.cfg_min_ncluster_itsib) { + // return false; + // } + + // if (track.tpcChi2NCl() > fV0Cut.cfg_max_chi2tpc) { + // return false; + // } + + // if (track.tpcNClsFound() < fV0Cut.cfg_min_ncluster_tpc) { + // return false; + // } + + // if (track.tpcNClsCrossedRows() < fV0Cut.cfg_min_ncrossedrows_tpc) { + // return false; + // } + + // if (track.tpcCrossedRowsOverFindableCls() < fV0Cut.cfg_min_cr2findable_ratio_tpc) { + // return false; + // } + + // if (track.tpcFractionSharedCls() > fV0Cut.cfg_max_frac_shared_clusters_tpc) { + // return false; + // } + + // return true; + // } + + // template + // bool isPion(TTrack const& track) + // { + // return fV0Cut.cfg_min_TPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < fV0Cut.cfg_max_TPCNsigmaPi; + // } + + // template + // bool isKaon(TTrack const& track) + // { + // return fV0Cut.cfg_min_TPCNsigmaKa < track.tpcNSigmaKa() && track.tpcNSigmaKa() < fV0Cut.cfg_max_TPCNsigmaKa; + // } + + // template + // bool isProton(TTrack const& track) + // { + // return fV0Cut.cfg_min_TPCNsigmaPr < track.tpcNSigmaPr() && track.tpcNSigmaPr() < fV0Cut.cfg_max_TPCNsigmaPr; + // } + + // template + // bool isK0S(TV0 const& v0) + // { + // return (fV0Cut.cfg_min_mass_k0s < v0.mK0Short() && v0.mK0Short() < fV0Cut.cfg_max_mass_k0s) && (v0.mLambda() < fV0Cut.cfg_min_mass_lambda_veto || fV0Cut.cfg_max_mass_lambda_veto < v0.mLambda()) && (v0.mAntiLambda() < fV0Cut.cfg_min_mass_lambda_veto || fV0Cut.cfg_max_mass_lambda_veto < v0.mAntiLambda()); + // } + + // template + // bool isLambda(TV0 const& v0) + // { + // return (fV0Cut.cfg_min_mass_lambda < v0.mLambda() && v0.mLambda() < fV0Cut.cfg_max_mass_lambda) && (v0.mK0Short() < fV0Cut.cfg_min_mass_k0s_veto || fV0Cut.cfg_max_mass_k0s_veto < v0.mK0Short()); + // } + + // template + // bool isAntiLambda(TV0 const& v0) + // { + // return (fV0Cut.cfg_min_mass_lambda < v0.mAntiLambda() && v0.mAntiLambda() < fV0Cut.cfg_max_mass_lambda) && (v0.mK0Short() < fV0Cut.cfg_min_mass_k0s_veto || fV0Cut.cfg_max_mass_k0s_veto < v0.mK0Short()); + // } + + // template + // bool isXi(TCascade const& cascade) + // { + // return (fCascadeCut.cfg_min_mass_Xi < cascade.mXi() && cascade.mXi() < fCascadeCut.cfg_max_mass_Xi) && (cascade.mOmega() < fCascadeCut.cfg_min_mass_Omega_veto || fCascadeCut.cfg_max_mass_Omega_veto < cascade.mOmega()); + // } + + // template + // bool isOmega(TCascade const& cascade) + // { + // return (fCascadeCut.cfg_min_mass_Omega < cascade.mOmega() && cascade.mOmega() < fCascadeCut.cfg_max_mass_Omega) && (cascade.mXi() < fCascadeCut.cfg_min_mass_Xi_veto || fCascadeCut.cfg_max_mass_Xi_veto < cascade.mXi()); + // } + + // template + // void fillV0Histograms(TCollision const&, TV0 const& v0, THistoregistry& registry) + // { + // auto pos = v0.template posTrack_as(); + // auto neg = v0.template negTrack_as(); + // registry.fill(HIST("SCT/V0/hPt"), v0.pt()); + // registry.fill(HIST("SCT/V0/hAP"), v0.alpha(), v0.qtarm()); + // registry.fill(HIST("SCT/V0/hCosPA"), v0.v0cosPA()); + // registry.fill(HIST("SCT/V0/hLxy"), v0.v0radius()); + // registry.fill(HIST("SCT/V0/hDCA2Legs"), v0.dcaV0daughters()); + + // if (isPion(pos) && isPion(neg)) { + // if ((v0.mLambda() < fV0Cut.cfg_min_mass_lambda_veto || fV0Cut.cfg_max_mass_lambda_veto < v0.mLambda()) && (v0.mAntiLambda() < fV0Cut.cfg_min_mass_lambda_veto || fV0Cut.cfg_max_mass_lambda_veto < v0.mAntiLambda())) { + // registry.fill(HIST("SCT/V0/hMassK0S"), v0.mK0Short()); + // registry.fill(HIST("SCT/V0/hYPhi_K0S"), v0.phi(), v0.yK0Short()); + // } + // registry.fill(HIST("SCT/V0/hMassGamma_misid"), v0.mGamma()); + // registry.fill(HIST("SCT/V0/hMassLambda_misid"), v0.mLambda()); + // registry.fill(HIST("SCT/V0/hMassAntiLambda_misid"), v0.mAntiLambda()); + // } + + // if (isProton(pos) && isPion(neg)) { + // if (v0.mK0Short() < fV0Cut.cfg_min_mass_k0s_veto || fV0Cut.cfg_max_mass_k0s_veto < v0.mK0Short()) { + // registry.fill(HIST("SCT/V0/hMassLambda"), v0.mLambda()); + // registry.fill(HIST("SCT/V0/hYPhi_Lambda"), v0.phi(), v0.yLambda()); + // } + // registry.fill(HIST("SCT/V0/hMassGamma_misid"), v0.mGamma()); + // registry.fill(HIST("SCT/V0/hMassK0S_misid"), v0.mK0Short()); + // } + + // if (isProton(neg) && isPion(pos)) { + // if (v0.mK0Short() < fV0Cut.cfg_min_mass_k0s_veto || fV0Cut.cfg_max_mass_k0s_veto < v0.mK0Short()) { + // registry.fill(HIST("SCT/V0/hMassAntiLambda"), v0.mAntiLambda()); + // registry.fill(HIST("SCT/V0/hYPhi_Lambda"), v0.phi(), v0.yLambda()); + // } + // registry.fill(HIST("SCT/V0/hMassGamma_misid"), v0.mGamma()); + // registry.fill(HIST("SCT/V0/hMassK0S_misid"), v0.mK0Short()); + // } + // } + + // template + // void fillCascadeHistograms(TCollision const& collision, TCascade const& cascade, THistoregistry& registry) + // { + // auto pos = cascade.template posTrack_as(); + // auto neg = cascade.template negTrack_as(); + // auto bachelor = cascade.template bachelor_as(); + + // registry.fill(HIST("SCT/Cascade/hPt"), cascade.pt()); + // registry.fill(HIST("SCT/Cascade/hMassLambda"), cascade.mLambda()); + // registry.fill(HIST("SCT/Cascade/hCosPA"), cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + // registry.fill(HIST("SCT/Cascade/hDCA2Legs"), cascade.dcacascdaughters()); + // registry.fill(HIST("SCT/Cascade/hV0CosPA"), cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); + // registry.fill(HIST("SCT/Cascade/hV0DCA2Legs"), cascade.dcaV0daughters()); + + // if (cascade.sign() < 0) { // Xi- or Omega- + // if (isPion(bachelor) && isProton(pos) && isPion(neg)) { + // if (cascade.mOmega() < fCascadeCut.cfg_min_mass_Omega_veto || fCascadeCut.cfg_max_mass_Omega_veto < cascade.mOmega()) { + // registry.fill(HIST("SCT/Cascade/hMassXi"), cascade.mXi()); + // registry.fill(HIST("SCT/Cascade/hYPhi_Xi"), cascade.phi(), cascade.yXi()); + // } + // registry.fill(HIST("SCT/Cascade/hMassOmega_misid"), cascade.mOmega()); + // } + // if (isKaon(bachelor) && isProton(pos) && isPion(neg)) { + // if (cascade.mXi() < fCascadeCut.cfg_min_mass_Xi_veto || fCascadeCut.cfg_max_mass_Xi_veto < cascade.mXi()) { + // registry.fill(HIST("SCT/Cascade/hMassOmega"), cascade.mOmega()); + // registry.fill(HIST("SCT/Cascade/hYPhi_Omega"), cascade.phi(), cascade.yOmega()); + // } + // registry.fill(HIST("SCT/Cascade/hMassXi_misid"), cascade.mXi()); + // } + // } else { // Xi+ or Omega+ + // if (isPion(bachelor) && isProton(neg) && isPion(pos)) { + // if (cascade.mOmega() < fCascadeCut.cfg_min_mass_Omega_veto || fCascadeCut.cfg_max_mass_Omega_veto < cascade.mOmega()) { + // registry.fill(HIST("SCT/Cascade/hMassXi"), cascade.mXi()); + // registry.fill(HIST("SCT/Cascade/hYPhi_Xi"), cascade.phi(), cascade.yXi()); + // } + // registry.fill(HIST("SCT/Cascade/hMassOmega_misid"), cascade.mOmega()); + // } + // if (isKaon(bachelor) && isProton(neg) && isPion(pos)) { + // if (cascade.mXi() < fCascadeCut.cfg_min_mass_Xi_veto || fCascadeCut.cfg_max_mass_Xi_veto < cascade.mXi()) { + // registry.fill(HIST("SCT/Cascade/hMassOmega"), cascade.mOmega()); + // registry.fill(HIST("SCT/Cascade/hYPhi_Omega"), cascade.phi(), cascade.yOmega()); + // } + // registry.fill(HIST("SCT/Cascade/hMassXi_misid"), cascade.mXi()); + // } + // } + // } + + template + void processWithTTCA(TBCs const& bcs, TCollisions const& collisions, TTracks const& tracks, /*TV0s const& v0s, TCascades const& cascades,*/ TTrackAssoc const& trackIndices, TMCParticles const&, TProducts& products, THistoregistry& registry, TSliceCache& cache, TPresliceTrack const& perColTrack, TPresliceTrackAssoc const& trackIndicesPerCollision /*, TPresliceV0 const& perColV0, TPresliceCascade const& perColCasc*/) { if (bcs.size() == 0) { return; @@ -1415,161 +1413,160 @@ class ElectronModule } std::vector hadronIds; - std::vector k0sIds; - std::vector lambdaIds; - std::vector antilambdaIds; - std::vector xiMinusIds; - std::vector xiPlusIds; - std::vector omegaMinusIds; - std::vector omegaPlusIds; + // std::vector k0sIds; + // std::vector lambdaIds; + // std::vector antilambdaIds; + // std::vector xiMinusIds; + // std::vector xiPlusIds; + // std::vector omegaMinusIds; + // std::vector omegaPlusIds; if (fDoSCTwithTracks) { hadronIds.reserve(trackIdsThisCollision.size()); - } - - if (fDoSCTwithV0s) { - auto v0s_per_collision = v0s.sliceBy(perColV0, collision.globalIndex()); - k0sIds.reserve(v0s_per_collision.size()); - lambdaIds.reserve(v0s_per_collision.size()); - antilambdaIds.reserve(v0s_per_collision.size()); - - for (const auto& v0 : v0s_per_collision) { - auto pos = v0.template posTrack_as(); - auto neg = v0.template negTrack_as(); - - if (pos.sign() * neg.sign() > 0) { - continue; - } - if (!isSelectedV0Leg(pos) || !isSelectedV0Leg(neg)) { - continue; - } - - if (v0.dcaV0daughters() > fV0Cut.cfg_max_dca2legs) { - continue; - } - - if (v0.v0radius() < fV0Cut.cfg_min_radius) { - continue; - } - - if (v0.v0cosPA() < fV0Cut.cfg_min_cospa) { - continue; - } - - if (std::sqrt(std::pow(v0.alpha() / fV0Cut.cfg_max_alpha_veto, 2) + std::pow(v0.qtarm() / fV0Cut.cfg_max_qt_veto, 2)) < 1.f) { // photon conversion rejection at small qT - continue; - } - - fillV0Histograms(collision, v0, registry); - - if (isK0S(v0) && isPion(pos) && isPion(neg)) { - k0sIds.emplace_back(v0.globalIndex()); - } - - if (isLambda(v0) && isProton(pos) && isPion(neg)) { - lambdaIds.emplace_back(v0.globalIndex()); - } else if (isAntiLambda(v0) && isProton(neg) && isPion(pos)) { - antilambdaIds.emplace_back(v0.globalIndex()); - } - - } // end of v0 loop - } - - if (fDoSCTwithCascades) { - auto cascades_per_collision = cascades.sliceBy(perColCasc, collision.globalIndex()); - xiMinusIds.reserve(cascades_per_collision.size()); - xiPlusIds.reserve(cascades_per_collision.size()); - omegaMinusIds.reserve(cascades_per_collision.size()); - omegaPlusIds.reserve(cascades_per_collision.size()); - - for (const auto& cascade : cascades_per_collision) { - auto pos = cascade.template posTrack_as(); - auto neg = cascade.template negTrack_as(); - auto bachelor = cascade.template bachelor_as(); - if (pos.sign() * neg.sign() > 0) { - continue; - } - if (cascade.mLambda() < fCascadeCut.cfg_min_mass_lambda || fCascadeCut.cfg_max_mass_lambda < cascade.mLambda()) { - continue; - } - - if (!isSelectedV0Leg(pos) || !isSelectedV0Leg(neg) || !isSelectedV0Leg(bachelor)) { - continue; - } - - if (cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ()) < fCascadeCut.cfg_min_cospa) { - continue; - } - if (cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < fCascadeCut.cfg_min_cospa_v0) { - continue; - } - - if (cascade.cascradius() > cascade.v0radius()) { - continue; - } - - if (cascade.dcaV0daughters() > fCascadeCut.cfg_max_dcadau_v0) { - continue; - } - if (cascade.v0radius() < fCascadeCut.cfg_min_rxy_v0) { - continue; - } - if (cascade.cascradius() < fCascadeCut.cfg_min_rxy) { - continue; - } - - if (cascade.dcacascdaughters() > fCascadeCut.cfg_max_dcadau) { - continue; - } - - if (std::fabs(cascade.dcav0topv(collision.posX(), collision.posY(), collision.posZ())) < fCascadeCut.cfg_min_dcaxy_v0) { + for (const auto& trackId : trackIdsThisCollision) { + auto track = trackId.template track_as(); + auto trackParCov = getTrackParCov(track); + o2::dataformats::DCA mDcaInfoCov; + mDcaInfoCov.set(999, 999, 999, 999, 999); + trackParCov.setPID(track.pidForTracking()); + bool isPropOK = o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); + if (!isPropOK) { continue; } - - fillCascadeHistograms(collision, cascade, registry); - - if (cascade.sign() < 0) { // Xi- or Omega- - if (isXi(cascade) && isPion(bachelor) && isProton(pos) && isPion(neg)) { - xiMinusIds.emplace_back(cascade.globalIndex()); - } - if (isOmega(cascade) && isKaon(bachelor) && isProton(pos) && isPion(neg)) { - omegaMinusIds.emplace_back(cascade.globalIndex()); - } - } else { // Xi+ or Omega+ - if (isXi(cascade) && isPion(bachelor) && isProton(neg) && isPion(pos)) { - xiPlusIds.emplace_back(cascade.globalIndex()); - } - if (isOmega(cascade) && isKaon(bachelor) && isProton(neg) && isPion(pos)) { - omegaPlusIds.emplace_back(cascade.globalIndex()); + float dcaXY = mDcaInfoCov.getY(); + float dcaZ = mDcaInfoCov.getZ(); + if (isSelectedHadron(collision, track, trackParCov, dcaXY, dcaZ)) { + float tpcSignal = track.tpcSignal(); + if constexpr (isMC) { + tpcSignal = track.mcTunedTPCSignal(); } + registry.fill(HIST("SCT/Track/hs"), trackParCov.getPt(), trackParCov.getEta(), RecoDecay::constrainAngle(trackParCov.getPhi(), 0, 1U)); + registry.fill(HIST("SCT/Track/hDCA"), dcaXY, dcaZ); + registry.fill(HIST("SCT/Track/hTPCdEdx"), track.tpcInnerParam(), tpcSignal); + registry.fill(HIST("SCT/Track/hTOFbeta"), trackParCov.getP(), fMapTOFBetaReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())]); + hadronIds.emplace_back(track.globalIndex()); } - } // end of cascade loop + } // end of track loop } - for (const auto& trackId : trackIdsThisCollision) { - auto track = trackId.template track_as(); - auto trackParCov = getTrackParCov(track); - o2::dataformats::DCA mDcaInfoCov; - mDcaInfoCov.set(999, 999, 999, 999, 999); - trackParCov.setPID(track.pidForTracking()); - bool isPropOK = o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); - if (!isPropOK) { - continue; - } - float dcaXY = mDcaInfoCov.getY(); - float dcaZ = mDcaInfoCov.getZ(); - if (isSelectedHadron(collision, track, trackParCov, dcaXY, dcaZ)) { - float tpcSignal = track.tpcSignal(); - if constexpr (isMC) { - tpcSignal = track.mcTunedTPCSignal(); - } - registry.fill(HIST("SCT/Track/hs"), trackParCov.getPt(), trackParCov.getEta(), RecoDecay::constrainAngle(trackParCov.getPhi(), 0, 1U)); - registry.fill(HIST("SCT/Track/hDCA"), dcaXY, dcaZ); - registry.fill(HIST("SCT/Track/hTPCdEdx"), track.tpcInnerParam(), tpcSignal); - registry.fill(HIST("SCT/Track/hTOFbeta"), trackParCov.getP(), fMapTOFBetaReassociated[std::make_pair(collision.globalIndex(), track.globalIndex())]); - hadronIds.emplace_back(track.globalIndex()); - } - } // end of track loop + // if (fDoSCTwithV0s) { + // auto v0s_per_collision = v0s.sliceBy(perColV0, collision.globalIndex()); + // k0sIds.reserve(v0s_per_collision.size()); + // lambdaIds.reserve(v0s_per_collision.size()); + // antilambdaIds.reserve(v0s_per_collision.size()); + + // for (const auto& v0 : v0s_per_collision) { + // auto pos = v0.template posTrack_as(); + // auto neg = v0.template negTrack_as(); + + // if (pos.sign() * neg.sign() > 0) { + // continue; + // } + // if (!isSelectedV0Leg(pos) || !isSelectedV0Leg(neg)) { + // continue; + // } + + // if (v0.dcaV0daughters() > fV0Cut.cfg_max_dca2legs) { + // continue; + // } + + // if (v0.v0radius() < fV0Cut.cfg_min_radius) { + // continue; + // } + + // if (v0.v0cosPA() < fV0Cut.cfg_min_cospa) { + // continue; + // } + + // if (std::sqrt(std::pow(v0.alpha() / fV0Cut.cfg_max_alpha_veto, 2) + std::pow(v0.qtarm() / fV0Cut.cfg_max_qt_veto, 2)) < 1.f) { // photon conversion rejection at small qT + // continue; + // } + + // fillV0Histograms(collision, v0, registry); + + // if (isK0S(v0) && isPion(pos) && isPion(neg)) { + // k0sIds.emplace_back(v0.globalIndex()); + // } + + // if (isLambda(v0) && isProton(pos) && isPion(neg)) { + // lambdaIds.emplace_back(v0.globalIndex()); + // } else if (isAntiLambda(v0) && isProton(neg) && isPion(pos)) { + // antilambdaIds.emplace_back(v0.globalIndex()); + // } + + // } // end of v0 loop + // } + + // if (fDoSCTwithCascades) { + // auto cascades_per_collision = cascades.sliceBy(perColCasc, collision.globalIndex()); + // xiMinusIds.reserve(cascades_per_collision.size()); + // xiPlusIds.reserve(cascades_per_collision.size()); + // omegaMinusIds.reserve(cascades_per_collision.size()); + // omegaPlusIds.reserve(cascades_per_collision.size()); + + // for (const auto& cascade : cascades_per_collision) { + // auto pos = cascade.template posTrack_as(); + // auto neg = cascade.template negTrack_as(); + // auto bachelor = cascade.template bachelor_as(); + // if (pos.sign() * neg.sign() > 0) { + // continue; + // } + // if (cascade.mLambda() < fCascadeCut.cfg_min_mass_lambda || fCascadeCut.cfg_max_mass_lambda < cascade.mLambda()) { + // continue; + // } + + // if (!isSelectedV0Leg(pos) || !isSelectedV0Leg(neg) || !isSelectedV0Leg(bachelor)) { + // continue; + // } + + // if (cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ()) < fCascadeCut.cfg_min_cospa) { + // continue; + // } + // if (cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < fCascadeCut.cfg_min_cospa_v0) { + // continue; + // } + + // if (cascade.cascradius() > cascade.v0radius()) { + // continue; + // } + + // if (cascade.dcaV0daughters() > fCascadeCut.cfg_max_dcadau_v0) { + // continue; + // } + // if (cascade.v0radius() < fCascadeCut.cfg_min_rxy_v0) { + // continue; + // } + // if (cascade.cascradius() < fCascadeCut.cfg_min_rxy) { + // continue; + // } + + // if (cascade.dcacascdaughters() > fCascadeCut.cfg_max_dcadau) { + // continue; + // } + + // if (std::fabs(cascade.dcav0topv(collision.posX(), collision.posY(), collision.posZ())) < fCascadeCut.cfg_min_dcaxy_v0) { + // continue; + // } + + // fillCascadeHistograms(collision, cascade, registry); + + // if (cascade.sign() < 0) { // Xi- or Omega- + // if (isXi(cascade) && isPion(bachelor) && isProton(pos) && isPion(neg)) { + // xiMinusIds.emplace_back(cascade.globalIndex()); + // } + // if (isOmega(cascade) && isKaon(bachelor) && isProton(pos) && isPion(neg)) { + // omegaMinusIds.emplace_back(cascade.globalIndex()); + // } + // } else { // Xi+ or Omega+ + // if (isXi(cascade) && isPion(bachelor) && isProton(neg) && isPion(pos)) { + // xiPlusIds.emplace_back(cascade.globalIndex()); + // } + // if (isOmega(cascade) && isKaon(bachelor) && isProton(neg) && isPion(pos)) { + // omegaPlusIds.emplace_back(cascade.globalIndex()); + // } + // } + // } // end of cascade loop + // } auto range_electrons = multiMapTracksPerCollision.equal_range(collision.globalIndex()); for (auto it = range_electrons.first; it != range_electrons.second; it++) { @@ -1577,7 +1574,7 @@ class ElectronModule o2::dataformats::DCA mDcaInfoCov; mDcaInfoCov.set(999, 999, 999, 999, 999); auto trackParCov = getTrackParCov(electron); - trackParCov.setPID(o2::track::PID::Electron); + trackParCov.setPID(fElectronCut.useElectronHypothesis ? o2::track::PID::Electron : electron.pidForTracking()); bool isPropOK = o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); if (!isPropOK) { continue; @@ -1599,7 +1596,7 @@ class ElectronModule } auto trackParCov2 = getTrackParCov(looseElectron); - trackParCov2.setPID(o2::track::PID::Electron); + trackParCov2.setPID(fElectronCut.useElectronHypothesis ? o2::track::PID::Electron : looseElectron.pidForTracking()); bool isPropOK = o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov2, 2.f, matCorr, &mDcaInfoCov); if (!isPropOK) { continue; @@ -1639,11 +1636,11 @@ class ElectronModule std::vector bdtScoreHb; std::vector hadronType; - bdtScoreBkg.reserve(hadronIds.size() + k0sIds.size() + lambdaIds.size() + antilambdaIds.size()); - bdtScorePromptHc.reserve(hadronIds.size() + k0sIds.size() + lambdaIds.size() + antilambdaIds.size()); - bdtScoreNonpromptHc.reserve(hadronIds.size() + k0sIds.size() + lambdaIds.size() + antilambdaIds.size()); - bdtScoreHb.reserve(hadronIds.size() + k0sIds.size() + lambdaIds.size() + antilambdaIds.size()); - hadronType.reserve(hadronIds.size() + k0sIds.size() + lambdaIds.size() + antilambdaIds.size()); + bdtScoreBkg.reserve(hadronIds.size() /*+ k0sIds.size() + lambdaIds.size() + antilambdaIds.size()*/); + bdtScorePromptHc.reserve(hadronIds.size() /*+ k0sIds.size() + lambdaIds.size() + antilambdaIds.size()*/); + bdtScoreNonpromptHc.reserve(hadronIds.size() /*+ k0sIds.size() + lambdaIds.size() + antilambdaIds.size()*/); + bdtScoreHb.reserve(hadronIds.size() /*+ k0sIds.size() + lambdaIds.size() + antilambdaIds.size()*/); + hadronType.reserve(hadronIds.size() /*+ k0sIds.size() + lambdaIds.size() + antilambdaIds.size()*/); // eTrack pair for (const auto& hadronId : hadronIds) { @@ -1658,7 +1655,7 @@ class ElectronModule hadronParCov.setPID(hadron.pidForTracking()); o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, hadronParCov, 2.f, matCorr, &mDcaInfoCov); - auto eTpair = o2::aod::pwgem::dilepton::utils::makePairLeptonTrack(dfeT, collision, electron, hadron, o2::track::PID::Electron, hadron.pidForTracking()); + auto eTpair = o2::aod::pwgem::dilepton::utils::makePairLeptonTrack(dfeT, collision, electron, hadron, fElectronCut.useElectronHypothesis ? o2::track::PID::Electron : electron.pidForTracking(), hadron.pidForTracking(), o2::constants::physics::MassElectron); registry.fill(HIST("SCT/eT/hDecayLength"), eTpair.lxy, eTpair.lz); registry.fill(HIST("SCT/eT/hCosPA"), eTpair.cospa); registry.fill(HIST("SCT/eT/hDCA2legs"), eTpair.dca2legs); @@ -1690,361 +1687,361 @@ class ElectronModule } } // end of charged track loop - // eK0S pair - for (const auto& k0sId : k0sIds) { - auto v0 = v0s.rawIteratorAt(k0sId); - if (v0.posTrackId() == electron.globalIndex() || v0.negTrackId() == electron.globalIndex()) { - continue; - } - const std::array vertexV0 = {v0.x(), v0.y(), v0.z()}; - const std::array momV0 = {v0.px(), v0.py(), v0.pz()}; - std::array covV0 = {0.}; - constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component - for (int i = 0; i < 6; i++) { - covV0[MomInd[i]] = v0.momentumCovMat()[i]; - covV0[i] = v0.positionCovMat()[i]; - } - auto v0ParCov = o2::track::TrackParCov(vertexV0, momV0, covV0, 0, true); - v0ParCov.setAbsCharge(0); - v0ParCov.setPID(o2::track::PID::K0); - o2::dataformats::DCA impactParameterV0; - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, v0ParCov, 2.f, matCorr, &impactParameterV0); // v0ParCov is TrackParCov object - - auto eV0pair = o2::aod::pwgem::dilepton::utils::makePairLeptonV0(dfeV0, collision, electron, v0, o2::track::PID::Electron, o2::track::PID::K0); - registry.fill(HIST("SCT/eV0/hDecayLength"), eV0pair.lxy, eV0pair.lz); - registry.fill(HIST("SCT/eV0/hCosPA"), eV0pair.cospa); - registry.fill(HIST("SCT/eV0/hDCA2legs"), eV0pair.dca2legs); - registry.fill(HIST("SCT/eV0/hMass"), eV0pair.mass); - if (eV0pair.isOK && fConfigDFeV0.useML && eV0pair.chi2PCA < fConfigDFeV0.maxChi2PCA && eV0pair.mass < fConfigDFeV0.maxMassLH) { - o2::analysis::pwgem::dilepton::sct::candidate candidate; - fillCandidate(candidate, eV0pair, v0ParCov, impactParameterV0); - candidate.ptL = trackParCov.getPt(); - candidate.massH = o2::constants::physics::MassK0Short; - - auto inputFeatures = mlResponseSCTeV0.getInputFeatures(candidate); - float binningFeature = mlResponseSCTeV0.getBinningFeature(candidate); - - int pbin = lower_bound(fConfigDFeV0.binsMl.value.begin(), fConfigDFeV0.binsMl.value.end(), binningFeature) - fConfigDFeV0.binsMl.value.begin() - 1; - if (pbin < 0) { - pbin = 0; - } else if (static_cast(fConfigDFeV0.binsMl.value.size()) - 2 < pbin) { - pbin = static_cast(fConfigDFeV0.binsMl.value.size()) - 2; - } - - auto vecProb = mlResponseSCTeV0.getModelOutput(inputFeatures, pbin); - bdtScoreBkg.emplace_back(static_cast(vecProb[0] * 255.f)); - bdtScorePromptHc.emplace_back(static_cast(vecProb[1] * 255.f)); - bdtScoreNonpromptHc.emplace_back(static_cast(vecProb[2] * 255.f)); - bdtScoreHb.emplace_back(static_cast(vecProb[3] * 255.f)); - hadronType.emplace_back(1); - } - } // end of k0s loop + // // eK0S pair + // for (const auto& k0sId : k0sIds) { + // auto v0 = v0s.rawIteratorAt(k0sId); + // if (v0.posTrackId() == electron.globalIndex() || v0.negTrackId() == electron.globalIndex()) { + // continue; + // } + // const std::array vertexV0 = {v0.x(), v0.y(), v0.z()}; + // const std::array momV0 = {v0.px(), v0.py(), v0.pz()}; + // std::array covV0 = {0.}; + // constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component + // for (int i = 0; i < 6; i++) { + // covV0[MomInd[i]] = v0.momentumCovMat()[i]; + // covV0[i] = v0.positionCovMat()[i]; + // } + // auto v0ParCov = o2::track::TrackParCov(vertexV0, momV0, covV0, 0, true); + // v0ParCov.setAbsCharge(0); + // v0ParCov.setPID(o2::track::PID::K0); + // o2::dataformats::DCA impactParameterV0; + // o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, v0ParCov, 2.f, matCorr, &impactParameterV0); // v0ParCov is TrackParCov object + + // auto eV0pair = o2::aod::pwgem::dilepton::utils::makePairLeptonV0(dfeV0, collision, electron, v0, fElectronCut.useElectronHypothesis ? o2::track::PID::Electron : electron.pidForTracking(), o2::track::PID::K0, o2::constants::physics::MassElectron); + // registry.fill(HIST("SCT/eV0/hDecayLength"), eV0pair.lxy, eV0pair.lz); + // registry.fill(HIST("SCT/eV0/hCosPA"), eV0pair.cospa); + // registry.fill(HIST("SCT/eV0/hDCA2legs"), eV0pair.dca2legs); + // registry.fill(HIST("SCT/eV0/hMass"), eV0pair.mass); + // if (eV0pair.isOK && fConfigDFeV0.useML && eV0pair.chi2PCA < fConfigDFeV0.maxChi2PCA && eV0pair.mass < fConfigDFeV0.maxMassLH) { + // o2::analysis::pwgem::dilepton::sct::candidate candidate; + // fillCandidate(candidate, eV0pair, v0ParCov, impactParameterV0); + // candidate.ptL = trackParCov.getPt(); + // candidate.massH = o2::constants::physics::MassK0Short; + + // auto inputFeatures = mlResponseSCTeV0.getInputFeatures(candidate); + // float binningFeature = mlResponseSCTeV0.getBinningFeature(candidate); + + // int pbin = lower_bound(fConfigDFeV0.binsMl.value.begin(), fConfigDFeV0.binsMl.value.end(), binningFeature) - fConfigDFeV0.binsMl.value.begin() - 1; + // if (pbin < 0) { + // pbin = 0; + // } else if (static_cast(fConfigDFeV0.binsMl.value.size()) - 2 < pbin) { + // pbin = static_cast(fConfigDFeV0.binsMl.value.size()) - 2; + // } + + // auto vecProb = mlResponseSCTeV0.getModelOutput(inputFeatures, pbin); + // bdtScoreBkg.emplace_back(static_cast(vecProb[0] * 255.f)); + // bdtScorePromptHc.emplace_back(static_cast(vecProb[1] * 255.f)); + // bdtScoreNonpromptHc.emplace_back(static_cast(vecProb[2] * 255.f)); + // bdtScoreHb.emplace_back(static_cast(vecProb[3] * 255.f)); + // hadronType.emplace_back(1); + // } + // } // end of k0s loop if (electron.sign() > 0) { // positron // eL pair // sign is restricted in baryon decay: Lc+ -> e+ nu_e Lambda - for (const auto& lambdaId : lambdaIds) { - auto v0 = v0s.rawIteratorAt(lambdaId); - if (v0.posTrackId() == electron.globalIndex() || v0.negTrackId() == electron.globalIndex()) { - continue; - } - const std::array vertexV0 = {v0.x(), v0.y(), v0.z()}; - const std::array momV0 = {v0.px(), v0.py(), v0.pz()}; - std::array covV0 = {0.}; - constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component - for (int i = 0; i < 6; i++) { - covV0[MomInd[i]] = v0.momentumCovMat()[i]; - covV0[i] = v0.positionCovMat()[i]; - } - auto v0ParCov = o2::track::TrackParCov(vertexV0, momV0, covV0, 0, true); - v0ParCov.setAbsCharge(0); - v0ParCov.setPID(o2::track::PID::Lambda); - o2::dataformats::DCA impactParameterV0; - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, v0ParCov, 2.f, matCorr, &impactParameterV0); // v0ParCov is TrackParCov object - - auto eV0pair = o2::aod::pwgem::dilepton::utils::makePairLeptonV0(dfeV0, collision, electron, v0, o2::track::PID::Electron, o2::track::PID::Lambda); - registry.fill(HIST("SCT/eV0/hDecayLength"), eV0pair.lxy, eV0pair.lz); - registry.fill(HIST("SCT/eV0/hCosPA"), eV0pair.cospa); - registry.fill(HIST("SCT/eV0/hDCA2legs"), eV0pair.dca2legs); - registry.fill(HIST("SCT/eV0/hMass"), eV0pair.mass); - if (eV0pair.isOK && fConfigDFeV0.useML && eV0pair.chi2PCA < fConfigDFeV0.maxChi2PCA && eV0pair.mass < fConfigDFeV0.maxMassLH) { - o2::analysis::pwgem::dilepton::sct::candidate candidate; - fillCandidate(candidate, eV0pair, v0ParCov, impactParameterV0); - candidate.ptL = trackParCov.getPt(); - candidate.massH = o2::constants::physics::MassLambda; - - auto inputFeatures = mlResponseSCTeV0.getInputFeatures(candidate); - float binningFeature = mlResponseSCTeV0.getBinningFeature(candidate); - - int pbin = lower_bound(fConfigDFeV0.binsMl.value.begin(), fConfigDFeV0.binsMl.value.end(), binningFeature) - fConfigDFeV0.binsMl.value.begin() - 1; - if (pbin < 0) { - pbin = 0; - } else if (static_cast(fConfigDFeV0.binsMl.value.size()) - 2 < pbin) { - pbin = static_cast(fConfigDFeV0.binsMl.value.size()) - 2; - } - - auto vecProb = mlResponseSCTeV0.getModelOutput(inputFeatures, pbin); - bdtScoreBkg.emplace_back(static_cast(vecProb[0] * 255.f)); - bdtScorePromptHc.emplace_back(static_cast(vecProb[1] * 255.f)); - bdtScoreNonpromptHc.emplace_back(static_cast(vecProb[2] * 255.f)); - bdtScoreHb.emplace_back(static_cast(vecProb[3] * 255.f)); - hadronType.emplace_back(2); - } - } // end of lambda loop + // for (const auto& lambdaId : lambdaIds) { + // auto v0 = v0s.rawIteratorAt(lambdaId); + // if (v0.posTrackId() == electron.globalIndex() || v0.negTrackId() == electron.globalIndex()) { + // continue; + // } + // const std::array vertexV0 = {v0.x(), v0.y(), v0.z()}; + // const std::array momV0 = {v0.px(), v0.py(), v0.pz()}; + // std::array covV0 = {0.}; + // constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component + // for (int i = 0; i < 6; i++) { + // covV0[MomInd[i]] = v0.momentumCovMat()[i]; + // covV0[i] = v0.positionCovMat()[i]; + // } + // auto v0ParCov = o2::track::TrackParCov(vertexV0, momV0, covV0, 0, true); + // v0ParCov.setAbsCharge(0); + // v0ParCov.setPID(o2::track::PID::Lambda); + // o2::dataformats::DCA impactParameterV0; + // o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, v0ParCov, 2.f, matCorr, &impactParameterV0); // v0ParCov is TrackParCov object + + // auto eV0pair = o2::aod::pwgem::dilepton::utils::makePairLeptonV0(dfeV0, collision, electron, v0, fElectronCut.useElectronHypothesis ? o2::track::PID::Electron : electron.pidForTracking(), o2::track::PID::Lambda, o2::constants::physics::MassElectron); + // registry.fill(HIST("SCT/eV0/hDecayLength"), eV0pair.lxy, eV0pair.lz); + // registry.fill(HIST("SCT/eV0/hCosPA"), eV0pair.cospa); + // registry.fill(HIST("SCT/eV0/hDCA2legs"), eV0pair.dca2legs); + // registry.fill(HIST("SCT/eV0/hMass"), eV0pair.mass); + // if (eV0pair.isOK && fConfigDFeV0.useML && eV0pair.chi2PCA < fConfigDFeV0.maxChi2PCA && eV0pair.mass < fConfigDFeV0.maxMassLH) { + // o2::analysis::pwgem::dilepton::sct::candidate candidate; + // fillCandidate(candidate, eV0pair, v0ParCov, impactParameterV0); + // candidate.ptL = trackParCov.getPt(); + // candidate.massH = o2::constants::physics::MassLambda; + + // auto inputFeatures = mlResponseSCTeV0.getInputFeatures(candidate); + // float binningFeature = mlResponseSCTeV0.getBinningFeature(candidate); + + // int pbin = lower_bound(fConfigDFeV0.binsMl.value.begin(), fConfigDFeV0.binsMl.value.end(), binningFeature) - fConfigDFeV0.binsMl.value.begin() - 1; + // if (pbin < 0) { + // pbin = 0; + // } else if (static_cast(fConfigDFeV0.binsMl.value.size()) - 2 < pbin) { + // pbin = static_cast(fConfigDFeV0.binsMl.value.size()) - 2; + // } + + // auto vecProb = mlResponseSCTeV0.getModelOutput(inputFeatures, pbin); + // bdtScoreBkg.emplace_back(static_cast(vecProb[0] * 255.f)); + // bdtScorePromptHc.emplace_back(static_cast(vecProb[1] * 255.f)); + // bdtScoreNonpromptHc.emplace_back(static_cast(vecProb[2] * 255.f)); + // bdtScoreHb.emplace_back(static_cast(vecProb[3] * 255.f)); + // hadronType.emplace_back(2); + // } + // } // end of lambda loop // eXi pair // sign is restricted in baryon decay: Xic0 -> e+ nu_e Xi- - for (const auto& xiId : xiMinusIds) { - auto cascade = cascades.rawIteratorAt(xiId); - if (cascade.posTrackId() == electron.globalIndex() || cascade.negTrackId() == electron.globalIndex() || cascade.bachelorId() == electron.globalIndex()) { - continue; - } - - const std::array vertexCasc = {cascade.x(), cascade.y(), cascade.z()}; - const std::array momCasc = {cascade.px(), cascade.py(), cascade.pz()}; - std::array covCasc = {0.}; - constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component - for (int i = 0; i < 6; i++) { - covCasc[MomInd[i]] = cascade.momentumCovMat()[i]; - covCasc[i] = cascade.positionCovMat()[i]; - } - auto cascadeParCov = o2::track::TrackParCov(vertexCasc, momCasc, covCasc, cascade.sign(), true); - cascadeParCov.setAbsCharge(1); - cascadeParCov.setPID(o2::track::PID::XiMinus); - o2::dataformats::DCA impactParameterCasc; - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, cascadeParCov, 2.f, matCorr, &impactParameterCasc); // cascadeParCov is TrackParCov object - - auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(dfeC, collision, electron, cascade, o2::track::PID::Electron, o2::track::PID::XiMinus); - registry.fill(HIST("SCT/eC/hDecayLength"), eCpair.lxy, eCpair.lz); - registry.fill(HIST("SCT/eC/hCosPA"), eCpair.cospa); - registry.fill(HIST("SCT/eC/hDCA2legs"), eCpair.dca2legs); - registry.fill(HIST("SCT/eC/hMass"), eCpair.mass); - if (eCpair.isOK && fConfigDFeC.useML && eCpair.chi2PCA < fConfigDFeC.maxChi2PCA && eCpair.mass < fConfigDFeC.maxMassLH) { - o2::analysis::pwgem::dilepton::sct::candidate candidate; - fillCandidate(candidate, eCpair, cascadeParCov, impactParameterCasc); - candidate.ptL = trackParCov.getPt(); - candidate.massH = o2::constants::physics::MassXiMinus; - - auto inputFeatures = mlResponseSCTeC.getInputFeatures(candidate); - float binningFeature = mlResponseSCTeC.getBinningFeature(candidate); - - int pbin = lower_bound(fConfigDFeC.binsMl.value.begin(), fConfigDFeC.binsMl.value.end(), binningFeature) - fConfigDFeC.binsMl.value.begin() - 1; - if (pbin < 0) { - pbin = 0; - } else if (static_cast(fConfigDFeC.binsMl.value.size()) - 2 < pbin) { - pbin = static_cast(fConfigDFeC.binsMl.value.size()) - 2; - } - - auto vecProb = mlResponseSCTeC.getModelOutput(inputFeatures, pbin); - bdtScoreBkg.emplace_back(static_cast(vecProb[0] * 255.f)); - bdtScorePromptHc.emplace_back(static_cast(vecProb[1] * 255.f)); - bdtScoreNonpromptHc.emplace_back(static_cast(vecProb[2] * 255.f)); - bdtScoreHb.emplace_back(static_cast(0)); - hadronType.emplace_back(4); - } - } // end of Xi- loop - - // eOmega pair // sign is restricted in baryon decay: Omegac0 -> e+ nu_e Omega- - for (const auto& omegaId : omegaMinusIds) { - auto cascade = cascades.rawIteratorAt(omegaId); - if (cascade.posTrackId() == electron.globalIndex() || cascade.negTrackId() == electron.globalIndex() || cascade.bachelorId() == electron.globalIndex()) { - continue; - } - - const std::array vertexCasc = {cascade.x(), cascade.y(), cascade.z()}; - const std::array momCasc = {cascade.px(), cascade.py(), cascade.pz()}; - std::array covCasc = {0.}; - constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component - for (int i = 0; i < 6; i++) { - covCasc[MomInd[i]] = cascade.momentumCovMat()[i]; - covCasc[i] = cascade.positionCovMat()[i]; - } - auto cascadeParCov = o2::track::TrackParCov(vertexCasc, momCasc, covCasc, cascade.sign(), true); - cascadeParCov.setAbsCharge(1); - cascadeParCov.setPID(o2::track::PID::OmegaMinus); - o2::dataformats::DCA impactParameterCasc; - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, cascadeParCov, 2.f, matCorr, &impactParameterCasc); // cascadeParCov is TrackParCov object - - auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(dfeC, collision, electron, cascade, o2::track::PID::Electron, o2::track::PID::OmegaMinus); - registry.fill(HIST("SCT/eC/hDecayLength"), eCpair.lxy, eCpair.lz); - registry.fill(HIST("SCT/eC/hCosPA"), eCpair.cospa); - registry.fill(HIST("SCT/eC/hDCA2legs"), eCpair.dca2legs); - registry.fill(HIST("SCT/eC/hMass"), eCpair.mass); - if (eCpair.isOK && fConfigDFeC.useML && eCpair.chi2PCA < fConfigDFeC.maxChi2PCA && eCpair.mass < fConfigDFeC.maxMassLH) { - o2::analysis::pwgem::dilepton::sct::candidate candidate; - fillCandidate(candidate, eCpair, cascadeParCov, impactParameterCasc); - candidate.ptL = trackParCov.getPt(); - candidate.massH = o2::constants::physics::MassOmegaMinus; - - auto inputFeatures = mlResponseSCTeC.getInputFeatures(candidate); - float binningFeature = mlResponseSCTeC.getBinningFeature(candidate); - - int pbin = lower_bound(fConfigDFeC.binsMl.value.begin(), fConfigDFeC.binsMl.value.end(), binningFeature) - fConfigDFeC.binsMl.value.begin() - 1; - if (pbin < 0) { - pbin = 0; - } else if (static_cast(fConfigDFeC.binsMl.value.size()) - 2 < pbin) { - pbin = static_cast(fConfigDFeC.binsMl.value.size()) - 2; - } - - auto vecProb = mlResponseSCTeC.getModelOutput(inputFeatures, pbin); - bdtScoreBkg.emplace_back(static_cast(vecProb[0] * 255.f)); - bdtScorePromptHc.emplace_back(static_cast(vecProb[1] * 255.f)); - bdtScoreNonpromptHc.emplace_back(static_cast(vecProb[2] * 255.f)); - bdtScoreHb.emplace_back(static_cast(0)); - hadronType.emplace_back(6); - } - } // end of Omega- loop + // for (const auto& xiId : xiMinusIds) { + // auto cascade = cascades.rawIteratorAt(xiId); + // if (cascade.posTrackId() == electron.globalIndex() || cascade.negTrackId() == electron.globalIndex() || cascade.bachelorId() == electron.globalIndex()) { + // continue; + // } + + // const std::array vertexCasc = {cascade.x(), cascade.y(), cascade.z()}; + // const std::array momCasc = {cascade.px(), cascade.py(), cascade.pz()}; + // std::array covCasc = {0.}; + // constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component + // for (int i = 0; i < 6; i++) { + // covCasc[MomInd[i]] = cascade.momentumCovMat()[i]; + // covCasc[i] = cascade.positionCovMat()[i]; + // } + // auto cascadeParCov = o2::track::TrackParCov(vertexCasc, momCasc, covCasc, cascade.sign(), true); + // cascadeParCov.setAbsCharge(1); + // cascadeParCov.setPID(o2::track::PID::XiMinus); + // o2::dataformats::DCA impactParameterCasc; + // o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, cascadeParCov, 2.f, matCorr, &impactParameterCasc); // cascadeParCov is TrackParCov object + + // auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(dfeC, collision, electron, cascade, fElectronCut.useElectronHypothesis ? o2::track::PID::Electron : electron.pidForTracking(), o2::track::PID::XiMinus, o2::constants::physics::MassElectron); + // registry.fill(HIST("SCT/eC/hDecayLength"), eCpair.lxy, eCpair.lz); + // registry.fill(HIST("SCT/eC/hCosPA"), eCpair.cospa); + // registry.fill(HIST("SCT/eC/hDCA2legs"), eCpair.dca2legs); + // registry.fill(HIST("SCT/eC/hMass"), eCpair.mass); + // if (eCpair.isOK && fConfigDFeC.useML && eCpair.chi2PCA < fConfigDFeC.maxChi2PCA && eCpair.mass < fConfigDFeC.maxMassLH) { + // o2::analysis::pwgem::dilepton::sct::candidate candidate; + // fillCandidate(candidate, eCpair, cascadeParCov, impactParameterCasc); + // candidate.ptL = trackParCov.getPt(); + // candidate.massH = o2::constants::physics::MassXiMinus; + + // auto inputFeatures = mlResponseSCTeC.getInputFeatures(candidate); + // float binningFeature = mlResponseSCTeC.getBinningFeature(candidate); + + // int pbin = lower_bound(fConfigDFeC.binsMl.value.begin(), fConfigDFeC.binsMl.value.end(), binningFeature) - fConfigDFeC.binsMl.value.begin() - 1; + // if (pbin < 0) { + // pbin = 0; + // } else if (static_cast(fConfigDFeC.binsMl.value.size()) - 2 < pbin) { + // pbin = static_cast(fConfigDFeC.binsMl.value.size()) - 2; + // } + + // auto vecProb = mlResponseSCTeC.getModelOutput(inputFeatures, pbin); + // bdtScoreBkg.emplace_back(static_cast(vecProb[0] * 255.f)); + // bdtScorePromptHc.emplace_back(static_cast(vecProb[1] * 255.f)); + // bdtScoreNonpromptHc.emplace_back(static_cast(vecProb[2] * 255.f)); + // bdtScoreHb.emplace_back(static_cast(0)); + // hadronType.emplace_back(4); + // } + // } // end of Xi- loop + + // // eOmega pair // sign is restricted in baryon decay: Omegac0 -> e+ nu_e Omega- + // for (const auto& omegaId : omegaMinusIds) { + // auto cascade = cascades.rawIteratorAt(omegaId); + // if (cascade.posTrackId() == electron.globalIndex() || cascade.negTrackId() == electron.globalIndex() || cascade.bachelorId() == electron.globalIndex()) { + // continue; + // } + + // const std::array vertexCasc = {cascade.x(), cascade.y(), cascade.z()}; + // const std::array momCasc = {cascade.px(), cascade.py(), cascade.pz()}; + // std::array covCasc = {0.}; + // constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component + // for (int i = 0; i < 6; i++) { + // covCasc[MomInd[i]] = cascade.momentumCovMat()[i]; + // covCasc[i] = cascade.positionCovMat()[i]; + // } + // auto cascadeParCov = o2::track::TrackParCov(vertexCasc, momCasc, covCasc, cascade.sign(), true); + // cascadeParCov.setAbsCharge(1); + // cascadeParCov.setPID(o2::track::PID::OmegaMinus); + // o2::dataformats::DCA impactParameterCasc; + // o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, cascadeParCov, 2.f, matCorr, &impactParameterCasc); // cascadeParCov is TrackParCov object + + // auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(dfeC, collision, electron, cascade, fElectronCut.useElectronHypothesis ? o2::track::PID::Electron : electron.pidForTracking(), o2::track::PID::OmegaMinus, o2::constants::physics::MassElectron); + // registry.fill(HIST("SCT/eC/hDecayLength"), eCpair.lxy, eCpair.lz); + // registry.fill(HIST("SCT/eC/hCosPA"), eCpair.cospa); + // registry.fill(HIST("SCT/eC/hDCA2legs"), eCpair.dca2legs); + // registry.fill(HIST("SCT/eC/hMass"), eCpair.mass); + // if (eCpair.isOK && fConfigDFeC.useML && eCpair.chi2PCA < fConfigDFeC.maxChi2PCA && eCpair.mass < fConfigDFeC.maxMassLH) { + // o2::analysis::pwgem::dilepton::sct::candidate candidate; + // fillCandidate(candidate, eCpair, cascadeParCov, impactParameterCasc); + // candidate.ptL = trackParCov.getPt(); + // candidate.massH = o2::constants::physics::MassOmegaMinus; + + // auto inputFeatures = mlResponseSCTeC.getInputFeatures(candidate); + // float binningFeature = mlResponseSCTeC.getBinningFeature(candidate); + + // int pbin = lower_bound(fConfigDFeC.binsMl.value.begin(), fConfigDFeC.binsMl.value.end(), binningFeature) - fConfigDFeC.binsMl.value.begin() - 1; + // if (pbin < 0) { + // pbin = 0; + // } else if (static_cast(fConfigDFeC.binsMl.value.size()) - 2 < pbin) { + // pbin = static_cast(fConfigDFeC.binsMl.value.size()) - 2; + // } + + // auto vecProb = mlResponseSCTeC.getModelOutput(inputFeatures, pbin); + // bdtScoreBkg.emplace_back(static_cast(vecProb[0] * 255.f)); + // bdtScorePromptHc.emplace_back(static_cast(vecProb[1] * 255.f)); + // bdtScoreNonpromptHc.emplace_back(static_cast(vecProb[2] * 255.f)); + // bdtScoreHb.emplace_back(static_cast(0)); + // hadronType.emplace_back(6); + // } + // } // end of Omega- loop } else { // electron // eL pair // sign is restricted in baryon decay: Lc- -> e- anti_nu_e antiLambda - for (const auto& antilambdaId : antilambdaIds) { - auto v0 = v0s.rawIteratorAt(antilambdaId); - if (v0.posTrackId() == electron.globalIndex() || v0.negTrackId() == electron.globalIndex()) { - continue; - } - const std::array vertexV0 = {v0.x(), v0.y(), v0.z()}; - const std::array momV0 = {v0.px(), v0.py(), v0.pz()}; - std::array covV0 = {0.}; - constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component - for (int i = 0; i < 6; i++) { - covV0[MomInd[i]] = v0.momentumCovMat()[i]; - covV0[i] = v0.positionCovMat()[i]; - } - auto v0ParCov = o2::track::TrackParCov(vertexV0, momV0, covV0, 0, true); - v0ParCov.setAbsCharge(0); - v0ParCov.setPID(o2::track::PID::Lambda); - o2::dataformats::DCA impactParameterV0; - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, v0ParCov, 2.f, matCorr, &impactParameterV0); // v0ParCov is TrackParCov object - - auto eV0pair = o2::aod::pwgem::dilepton::utils::makePairLeptonV0(dfeV0, collision, electron, v0, o2::track::PID::Electron, o2::track::PID::Lambda); - registry.fill(HIST("SCT/eV0/hDecayLength"), eV0pair.lxy, eV0pair.lz); - registry.fill(HIST("SCT/eV0/hCosPA"), eV0pair.cospa); - registry.fill(HIST("SCT/eV0/hDCA2legs"), eV0pair.dca2legs); - registry.fill(HIST("SCT/eV0/hMass"), eV0pair.mass); - if (eV0pair.isOK && fConfigDFeV0.useML && eV0pair.chi2PCA < fConfigDFeV0.maxChi2PCA && eV0pair.mass < fConfigDFeV0.maxMassLH) { - o2::analysis::pwgem::dilepton::sct::candidate candidate; - fillCandidate(candidate, eV0pair, v0ParCov, impactParameterV0); - candidate.ptL = trackParCov.getPt(); - candidate.massH = o2::constants::physics::MassLambda; - - auto inputFeatures = mlResponseSCTeV0.getInputFeatures(candidate); - float binningFeature = mlResponseSCTeV0.getBinningFeature(candidate); - - int pbin = lower_bound(fConfigDFeV0.binsMl.value.begin(), fConfigDFeV0.binsMl.value.end(), binningFeature) - fConfigDFeV0.binsMl.value.begin() - 1; - if (pbin < 0) { - pbin = 0; - } else if (static_cast(fConfigDFeV0.binsMl.value.size()) - 2 < pbin) { - pbin = static_cast(fConfigDFeV0.binsMl.value.size()) - 2; - } - - auto vecProb = mlResponseSCTeV0.getModelOutput(inputFeatures, pbin); - bdtScoreBkg.emplace_back(static_cast(vecProb[0] * 255.f)); - bdtScorePromptHc.emplace_back(static_cast(vecProb[1] * 255.f)); - bdtScoreNonpromptHc.emplace_back(static_cast(vecProb[2] * 255.f)); - bdtScoreHb.emplace_back(static_cast(vecProb[3] * 255.f)); - hadronType.emplace_back(3); - } - } // end of antilambda loop - - // eXi pair // sign is restricted in baryon decay: Xic0bar -> e- anti_nu_e Xi+ - for (const auto& xiId : xiPlusIds) { - auto cascade = cascades.rawIteratorAt(xiId); - if (cascade.posTrackId() == electron.globalIndex() || cascade.negTrackId() == electron.globalIndex() || cascade.bachelorId() == electron.globalIndex()) { - continue; - } - - const std::array vertexCasc = {cascade.x(), cascade.y(), cascade.z()}; - const std::array momCasc = {cascade.px(), cascade.py(), cascade.pz()}; - std::array covCasc = {0.}; - constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component - for (int i = 0; i < 6; i++) { - covCasc[MomInd[i]] = cascade.momentumCovMat()[i]; - covCasc[i] = cascade.positionCovMat()[i]; - } - auto cascadeParCov = o2::track::TrackParCov(vertexCasc, momCasc, covCasc, cascade.sign(), true); - cascadeParCov.setAbsCharge(1); - cascadeParCov.setPID(o2::track::PID::XiMinus); - o2::dataformats::DCA impactParameterCasc; - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, cascadeParCov, 2.f, matCorr, &impactParameterCasc); // cascadeParCov is TrackParCov object - - auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(dfeC, collision, electron, cascade, o2::track::PID::Electron, o2::track::PID::XiMinus); - registry.fill(HIST("SCT/eC/hDecayLength"), eCpair.lxy, eCpair.lz); - registry.fill(HIST("SCT/eC/hCosPA"), eCpair.cospa); - registry.fill(HIST("SCT/eC/hDCA2legs"), eCpair.dca2legs); - registry.fill(HIST("SCT/eC/hMass"), eCpair.mass); - if (eCpair.isOK && fConfigDFeC.useML && eCpair.chi2PCA < fConfigDFeC.maxChi2PCA && eCpair.mass < fConfigDFeC.maxMassLH) { - o2::analysis::pwgem::dilepton::sct::candidate candidate; - fillCandidate(candidate, eCpair, cascadeParCov, impactParameterCasc); - candidate.ptL = trackParCov.getPt(); - candidate.massH = o2::constants::physics::MassXiMinus; - - auto inputFeatures = mlResponseSCTeC.getInputFeatures(candidate); - float binningFeature = mlResponseSCTeC.getBinningFeature(candidate); - - int pbin = lower_bound(fConfigDFeC.binsMl.value.begin(), fConfigDFeC.binsMl.value.end(), binningFeature) - fConfigDFeC.binsMl.value.begin() - 1; - if (pbin < 0) { - pbin = 0; - } else if (static_cast(fConfigDFeC.binsMl.value.size()) - 2 < pbin) { - pbin = static_cast(fConfigDFeC.binsMl.value.size()) - 2; - } - - auto vecProb = mlResponseSCTeC.getModelOutput(inputFeatures, pbin); - bdtScoreBkg.emplace_back(static_cast(vecProb[0] * 255.f)); - bdtScorePromptHc.emplace_back(static_cast(vecProb[1] * 255.f)); - bdtScoreNonpromptHc.emplace_back(static_cast(vecProb[2] * 255.f)); - bdtScoreHb.emplace_back(static_cast(0)); - hadronType.emplace_back(5); - } - } // end of Xi- loop - - // eOmega pair // sign is restricted in baryon decay: Omegac0bar -> e- anti_nu_e Omega+ - for (const auto& omegaId : omegaPlusIds) { - auto cascade = cascades.rawIteratorAt(omegaId); - if (cascade.posTrackId() == electron.globalIndex() || cascade.negTrackId() == electron.globalIndex() || cascade.bachelorId() == electron.globalIndex()) { - continue; - } - - const std::array vertexCasc = {cascade.x(), cascade.y(), cascade.z()}; - const std::array momCasc = {cascade.px(), cascade.py(), cascade.pz()}; - std::array covCasc = {0.}; - constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component - for (int i = 0; i < 6; i++) { - covCasc[MomInd[i]] = cascade.momentumCovMat()[i]; - covCasc[i] = cascade.positionCovMat()[i]; - } - auto cascadeParCov = o2::track::TrackParCov(vertexCasc, momCasc, covCasc, cascade.sign(), true); - cascadeParCov.setAbsCharge(1); - cascadeParCov.setPID(o2::track::PID::OmegaMinus); - o2::dataformats::DCA impactParameterCasc; - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, cascadeParCov, 2.f, matCorr, &impactParameterCasc); // cascadeParCov is TrackParCov object - - auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(dfeC, collision, electron, cascade, o2::track::PID::Electron, o2::track::PID::OmegaMinus); - registry.fill(HIST("SCT/eC/hDecayLength"), eCpair.lxy, eCpair.lz); - registry.fill(HIST("SCT/eC/hCosPA"), eCpair.cospa); - registry.fill(HIST("SCT/eC/hDCA2legs"), eCpair.dca2legs); - registry.fill(HIST("SCT/eC/hMass"), eCpair.mass); - if (eCpair.isOK && fConfigDFeC.useML && eCpair.chi2PCA < fConfigDFeC.maxChi2PCA && eCpair.mass < fConfigDFeC.maxMassLH) { - o2::analysis::pwgem::dilepton::sct::candidate candidate; - fillCandidate(candidate, eCpair, cascadeParCov, impactParameterCasc); - candidate.ptL = trackParCov.getPt(); - candidate.massH = o2::constants::physics::MassOmegaMinus; - - auto inputFeatures = mlResponseSCTeC.getInputFeatures(candidate); - float binningFeature = mlResponseSCTeC.getBinningFeature(candidate); - - int pbin = lower_bound(fConfigDFeC.binsMl.value.begin(), fConfigDFeC.binsMl.value.end(), binningFeature) - fConfigDFeC.binsMl.value.begin() - 1; - if (pbin < 0) { - pbin = 0; - } else if (static_cast(fConfigDFeC.binsMl.value.size()) - 2 < pbin) { - pbin = static_cast(fConfigDFeC.binsMl.value.size()) - 2; - } - - auto vecProb = mlResponseSCTeC.getModelOutput(inputFeatures, pbin); - bdtScoreBkg.emplace_back(static_cast(vecProb[0] * 255.f)); - bdtScorePromptHc.emplace_back(static_cast(vecProb[1] * 255.f)); - bdtScoreNonpromptHc.emplace_back(static_cast(vecProb[2] * 255.f)); - bdtScoreHb.emplace_back(static_cast(0)); - hadronType.emplace_back(7); - } - } // end of Omega- loop + // for (const auto& antilambdaId : antilambdaIds) { + // auto v0 = v0s.rawIteratorAt(antilambdaId); + // if (v0.posTrackId() == electron.globalIndex() || v0.negTrackId() == electron.globalIndex()) { + // continue; + // } + // const std::array vertexV0 = {v0.x(), v0.y(), v0.z()}; + // const std::array momV0 = {v0.px(), v0.py(), v0.pz()}; + // std::array covV0 = {0.}; + // constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component + // for (int i = 0; i < 6; i++) { + // covV0[MomInd[i]] = v0.momentumCovMat()[i]; + // covV0[i] = v0.positionCovMat()[i]; + // } + // auto v0ParCov = o2::track::TrackParCov(vertexV0, momV0, covV0, 0, true); + // v0ParCov.setAbsCharge(0); + // v0ParCov.setPID(o2::track::PID::Lambda); + // o2::dataformats::DCA impactParameterV0; + // o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, v0ParCov, 2.f, matCorr, &impactParameterV0); // v0ParCov is TrackParCov object + + // auto eV0pair = o2::aod::pwgem::dilepton::utils::makePairLeptonV0(dfeV0, collision, electron, v0, fElectronCut.useElectronHypothesis ? o2::track::PID::Electron : electron.pidForTracking(), o2::track::PID::Lambda, o2::constants::physics::MassElectron); + // registry.fill(HIST("SCT/eV0/hDecayLength"), eV0pair.lxy, eV0pair.lz); + // registry.fill(HIST("SCT/eV0/hCosPA"), eV0pair.cospa); + // registry.fill(HIST("SCT/eV0/hDCA2legs"), eV0pair.dca2legs); + // registry.fill(HIST("SCT/eV0/hMass"), eV0pair.mass); + // if (eV0pair.isOK && fConfigDFeV0.useML && eV0pair.chi2PCA < fConfigDFeV0.maxChi2PCA && eV0pair.mass < fConfigDFeV0.maxMassLH) { + // o2::analysis::pwgem::dilepton::sct::candidate candidate; + // fillCandidate(candidate, eV0pair, v0ParCov, impactParameterV0); + // candidate.ptL = trackParCov.getPt(); + // candidate.massH = o2::constants::physics::MassLambda; + + // auto inputFeatures = mlResponseSCTeV0.getInputFeatures(candidate); + // float binningFeature = mlResponseSCTeV0.getBinningFeature(candidate); + + // int pbin = lower_bound(fConfigDFeV0.binsMl.value.begin(), fConfigDFeV0.binsMl.value.end(), binningFeature) - fConfigDFeV0.binsMl.value.begin() - 1; + // if (pbin < 0) { + // pbin = 0; + // } else if (static_cast(fConfigDFeV0.binsMl.value.size()) - 2 < pbin) { + // pbin = static_cast(fConfigDFeV0.binsMl.value.size()) - 2; + // } + + // auto vecProb = mlResponseSCTeV0.getModelOutput(inputFeatures, pbin); + // bdtScoreBkg.emplace_back(static_cast(vecProb[0] * 255.f)); + // bdtScorePromptHc.emplace_back(static_cast(vecProb[1] * 255.f)); + // bdtScoreNonpromptHc.emplace_back(static_cast(vecProb[2] * 255.f)); + // bdtScoreHb.emplace_back(static_cast(vecProb[3] * 255.f)); + // hadronType.emplace_back(3); + // } + // } // end of antilambda loop + + // // eXi pair // sign is restricted in baryon decay: Xic0bar -> e- anti_nu_e Xi+ + // for (const auto& xiId : xiPlusIds) { + // auto cascade = cascades.rawIteratorAt(xiId); + // if (cascade.posTrackId() == electron.globalIndex() || cascade.negTrackId() == electron.globalIndex() || cascade.bachelorId() == electron.globalIndex()) { + // continue; + // } + + // const std::array vertexCasc = {cascade.x(), cascade.y(), cascade.z()}; + // const std::array momCasc = {cascade.px(), cascade.py(), cascade.pz()}; + // std::array covCasc = {0.}; + // constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component + // for (int i = 0; i < 6; i++) { + // covCasc[MomInd[i]] = cascade.momentumCovMat()[i]; + // covCasc[i] = cascade.positionCovMat()[i]; + // } + // auto cascadeParCov = o2::track::TrackParCov(vertexCasc, momCasc, covCasc, cascade.sign(), true); + // cascadeParCov.setAbsCharge(1); + // cascadeParCov.setPID(o2::track::PID::XiMinus); + // o2::dataformats::DCA impactParameterCasc; + // o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, cascadeParCov, 2.f, matCorr, &impactParameterCasc); // cascadeParCov is TrackParCov object + + // auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(dfeC, collision, electron, cascade, fElectronCut.useElectronHypothesis ? o2::track::PID::Electron : electron.pidForTracking(), o2::track::PID::XiMinus, o2::constants::physics::MassElectron); + // registry.fill(HIST("SCT/eC/hDecayLength"), eCpair.lxy, eCpair.lz); + // registry.fill(HIST("SCT/eC/hCosPA"), eCpair.cospa); + // registry.fill(HIST("SCT/eC/hDCA2legs"), eCpair.dca2legs); + // registry.fill(HIST("SCT/eC/hMass"), eCpair.mass); + // if (eCpair.isOK && fConfigDFeC.useML && eCpair.chi2PCA < fConfigDFeC.maxChi2PCA && eCpair.mass < fConfigDFeC.maxMassLH) { + // o2::analysis::pwgem::dilepton::sct::candidate candidate; + // fillCandidate(candidate, eCpair, cascadeParCov, impactParameterCasc); + // candidate.ptL = trackParCov.getPt(); + // candidate.massH = o2::constants::physics::MassXiMinus; + + // auto inputFeatures = mlResponseSCTeC.getInputFeatures(candidate); + // float binningFeature = mlResponseSCTeC.getBinningFeature(candidate); + + // int pbin = lower_bound(fConfigDFeC.binsMl.value.begin(), fConfigDFeC.binsMl.value.end(), binningFeature) - fConfigDFeC.binsMl.value.begin() - 1; + // if (pbin < 0) { + // pbin = 0; + // } else if (static_cast(fConfigDFeC.binsMl.value.size()) - 2 < pbin) { + // pbin = static_cast(fConfigDFeC.binsMl.value.size()) - 2; + // } + + // auto vecProb = mlResponseSCTeC.getModelOutput(inputFeatures, pbin); + // bdtScoreBkg.emplace_back(static_cast(vecProb[0] * 255.f)); + // bdtScorePromptHc.emplace_back(static_cast(vecProb[1] * 255.f)); + // bdtScoreNonpromptHc.emplace_back(static_cast(vecProb[2] * 255.f)); + // bdtScoreHb.emplace_back(static_cast(0)); + // hadronType.emplace_back(5); + // } + // } // end of Xi- loop + + // // eOmega pair // sign is restricted in baryon decay: Omegac0bar -> e- anti_nu_e Omega+ + // for (const auto& omegaId : omegaPlusIds) { + // auto cascade = cascades.rawIteratorAt(omegaId); + // if (cascade.posTrackId() == electron.globalIndex() || cascade.negTrackId() == electron.globalIndex() || cascade.bachelorId() == electron.globalIndex()) { + // continue; + // } + + // const std::array vertexCasc = {cascade.x(), cascade.y(), cascade.z()}; + // const std::array momCasc = {cascade.px(), cascade.py(), cascade.pz()}; + // std::array covCasc = {0.}; + // constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component + // for (int i = 0; i < 6; i++) { + // covCasc[MomInd[i]] = cascade.momentumCovMat()[i]; + // covCasc[i] = cascade.positionCovMat()[i]; + // } + // auto cascadeParCov = o2::track::TrackParCov(vertexCasc, momCasc, covCasc, cascade.sign(), true); + // cascadeParCov.setAbsCharge(1); + // cascadeParCov.setPID(o2::track::PID::OmegaMinus); + // o2::dataformats::DCA impactParameterCasc; + // o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, cascadeParCov, 2.f, matCorr, &impactParameterCasc); // cascadeParCov is TrackParCov object + + // auto eCpair = o2::aod::pwgem::dilepton::utils::makePairLeptonCascade(dfeC, collision, electron, cascade, fElectronCut.useElectronHypothesis ? o2::track::PID::Electron : electron.pidForTracking(), o2::track::PID::OmegaMinus, o2::constants::physics::MassElectron); + // registry.fill(HIST("SCT/eC/hDecayLength"), eCpair.lxy, eCpair.lz); + // registry.fill(HIST("SCT/eC/hCosPA"), eCpair.cospa); + // registry.fill(HIST("SCT/eC/hDCA2legs"), eCpair.dca2legs); + // registry.fill(HIST("SCT/eC/hMass"), eCpair.mass); + // if (eCpair.isOK && fConfigDFeC.useML && eCpair.chi2PCA < fConfigDFeC.maxChi2PCA && eCpair.mass < fConfigDFeC.maxMassLH) { + // o2::analysis::pwgem::dilepton::sct::candidate candidate; + // fillCandidate(candidate, eCpair, cascadeParCov, impactParameterCasc); + // candidate.ptL = trackParCov.getPt(); + // candidate.massH = o2::constants::physics::MassOmegaMinus; + + // auto inputFeatures = mlResponseSCTeC.getInputFeatures(candidate); + // float binningFeature = mlResponseSCTeC.getBinningFeature(candidate); + + // int pbin = lower_bound(fConfigDFeC.binsMl.value.begin(), fConfigDFeC.binsMl.value.end(), binningFeature) - fConfigDFeC.binsMl.value.begin() - 1; + // if (pbin < 0) { + // pbin = 0; + // } else if (static_cast(fConfigDFeC.binsMl.value.size()) - 2 < pbin) { + // pbin = static_cast(fConfigDFeC.binsMl.value.size()) - 2; + // } + + // auto vecProb = mlResponseSCTeC.getModelOutput(inputFeatures, pbin); + // bdtScoreBkg.emplace_back(static_cast(vecProb[0] * 255.f)); + // bdtScorePromptHc.emplace_back(static_cast(vecProb[1] * 255.f)); + // bdtScoreNonpromptHc.emplace_back(static_cast(vecProb[2] * 255.f)); + // bdtScoreHb.emplace_back(static_cast(0)); + // hadronType.emplace_back(7); + // } + // } // end of Omega- loop } products.sctTable(/*bdtScoreBkg,*/ bdtScorePromptHc, bdtScoreNonpromptHc, bdtScoreHb, hadronType); @@ -2064,23 +2061,23 @@ class ElectronModule hadronIds.clear(); hadronIds.shrink_to_fit(); - k0sIds.clear(); - k0sIds.shrink_to_fit(); + // k0sIds.clear(); + // k0sIds.shrink_to_fit(); - lambdaIds.clear(); - lambdaIds.shrink_to_fit(); - antilambdaIds.clear(); - antilambdaIds.shrink_to_fit(); + // lambdaIds.clear(); + // lambdaIds.shrink_to_fit(); + // antilambdaIds.clear(); + // antilambdaIds.shrink_to_fit(); - xiMinusIds.clear(); - xiMinusIds.shrink_to_fit(); - xiPlusIds.clear(); - xiPlusIds.shrink_to_fit(); + // xiMinusIds.clear(); + // xiMinusIds.shrink_to_fit(); + // xiPlusIds.clear(); + // xiPlusIds.shrink_to_fit(); - omegaMinusIds.clear(); - omegaMinusIds.shrink_to_fit(); - omegaPlusIds.clear(); - omegaPlusIds.shrink_to_fit(); + // omegaMinusIds.clear(); + // omegaMinusIds.shrink_to_fit(); + // omegaPlusIds.clear(); + // omegaPlusIds.shrink_to_fit(); looseElectronIds.clear(); looseElectronIds.shrink_to_fit(); @@ -2092,8 +2089,8 @@ class ElectronModule clear(); } - template - void processWithoutTTCA(TBCs const&, TCollisions const&, TTracks const&, TV0s const&, TCascades const&, TMCParticles const&, TProducts&, THistoregistry&) + template + void processWithoutTTCA(TBCs const&, TCollisions const&, TTracks const&, /*TV0s const&, TCascades const&,*/ TMCParticles const&, TProducts&, THistoregistry&) { LOGF(info, "processWithoutTTCA is not supported. Bye."); @@ -2137,8 +2134,8 @@ class ElectronModule } void doSCTwithTracks(const bool flag) { fDoSCTwithTracks = flag; } - void doSCTwithV0s(const bool flag) { fDoSCTwithV0s = flag; } - void doSCTwithCascades(const bool flag) { fDoSCTwithCascades = flag; } + // void doSCTwithV0s(const bool flag) { fDoSCTwithV0s = flag; } + // void doSCTwithCascades(const bool flag) { fDoSCTwithCascades = flag; } float dca3DinSigmaOTF(const float dcaXY, const float dcaZ, const float cYY, const float cZZ, const float cZY) { @@ -2186,18 +2183,18 @@ class ElectronModule electronCut fElectronCut; electronPFCut fElectronPFCut; hadronCut fHadronCut; - v0Cut fV0Cut; - cascadeCut fCascadeCut; + // v0Cut fV0Cut; + // cascadeCut fCascadeCut; cfgDFeT fConfigDFeT; - cfgDFeV0 fConfigDFeV0; - cfgDFeC fConfigDFeC; + // cfgDFeV0 fConfigDFeV0; + // cfgDFeC fConfigDFeC; std::map, float> fMapProbaEl; // map pair(collisionId, trackId) -> probaEl std::map, float> fMapTOFNsigmaElReassociated; // map pair(collisionId, trackId) -> tof n sigma el // std::map, float> fMapTOFNsigmaPiReassociated; // map pair(collisionId, trackId) -> tof n sigma pi // std::map, float> fMapTOFNsigmaKaReassociated; // map pair(collisionId, trackId) -> tof n sigma ka // std::map, float> fMapTOFNsigmaPrReassociated; // map pair(collisionId, trackId) -> tof n sigma pr - std::map, float> fMapTOFBetaReassociated; // map pair(collisionId, trackId) -> tof beta + std::map, float> fMapTOFBetaReassociated; // map pair(collisionId, trackId) -> tof beta int mRunNumber{0}; float d_bz{0}; @@ -2206,16 +2203,16 @@ class ElectronModule o2::framework::Service mTOFResponse; o2::analysis::MlResponsePID mlResponsePID; o2::analysis::MlResponseSCT mlResponseSCTeT; - o2::analysis::MlResponseSCT mlResponseSCTeV0; - o2::analysis::MlResponseSCT mlResponseSCTeC; + // o2::analysis::MlResponseSCT mlResponseSCTeV0; + // o2::analysis::MlResponseSCT mlResponseSCTeC; bool fDoSCTwithTracks{false}; - bool fDoSCTwithV0s{false}; - bool fDoSCTwithCascades{false}; + // bool fDoSCTwithV0s{false}; + // bool fDoSCTwithCascades{false}; const std::vector max_mee_vec{0.02, 0.04, 0.06, 0.08, 0.10, 0.12, 0.14}; o2::vertexing::DCAFitterN<2> dfeT; - o2::vertexing::DCAFitterN<2> dfeV0; - o2::vertexing::DCAFitterN<2> dfeC; + // o2::vertexing::DCAFitterN<2> dfeV0; + // o2::vertexing::DCAFitterN<2> dfeC; o2::ccdb::CcdbApi ccdbApi; }; // end ElectronModule diff --git a/PWGEM/Dilepton/Utils/EventHistograms.h b/PWGEM/Dilepton/Utils/EventHistograms.h index da8d3734794..cafc4a8d756 100644 --- a/PWGEM/Dilepton/Utils/EventHistograms.h +++ b/PWGEM/Dilepton/Utils/EventHistograms.h @@ -15,6 +15,7 @@ #ifndef PWGEM_DILEPTON_UTILS_EVENTHISTOGRAMS_H_ #define PWGEM_DILEPTON_UTILS_EVENTHISTOGRAMS_H_ +#include "PWGEM/Dilepton/DataModel/EvSelFlags.h" #include "PWGEM/Dilepton/DataModel/dileptonTables.h" #include "Common/Core/RecoDecay.h" diff --git a/PWGEM/Dilepton/Utils/MCUtilities.h b/PWGEM/Dilepton/Utils/MCUtilities.h index b7c00447a35..51753c2da09 100644 --- a/PWGEM/Dilepton/Utils/MCUtilities.h +++ b/PWGEM/Dilepton/Utils/MCUtilities.h @@ -39,7 +39,7 @@ enum class EM_HFeeType : int { //_______________________________________________________________________ template -int hasFakeMatchITSTPC(TTrack const& track) +bool hasFakeMatchITSTPC(TTrack const& track) { // track and mctracklabel have to be joined. // bit 13 -- ITS/TPC labels are not equal @@ -52,7 +52,7 @@ int hasFakeMatchITSTPC(TTrack const& track) } //_______________________________________________________________________ template -int hasFakeMatchITSTPCTOF(TTrack const&) +bool hasFakeMatchITSTPCTOF(TTrack const&) { // track and mctracklabel have to be joined. return false; @@ -64,7 +64,7 @@ int hasFakeMatchITSTPCTOF(TTrack const&) } //_______________________________________________________________________ template -int hasFakeMatchMFTMCH(TTrack const& track) +bool hasFakeMatchMFTMCH(TTrack const& track) { // fwdtrack and mcfwdtracklabel have to be joined. if ((track.mcMask() & 1 << 7)) { @@ -74,6 +74,41 @@ int hasFakeMatchMFTMCH(TTrack const& track) } } //_______________________________________________________________________ +template +int isFromGammaZ(T const& track, TMCParticles const& mcParticles) +{ + if (!track.has_mothers()) { + return -999; + } + + int motherId = track.mothersIds()[0]; + while (motherId > -1) { + auto mp = mcParticles.rawIteratorAt(motherId); + if (std::abs(mp.pdgCode()) == 23) { + return mp.globalIndex(); + } + + if (mp.has_mothers()) { + motherId = mp.mothersIds()[0]; + } else { + motherId = -999; + } + } + return -999; +} +//_______________________________________________________________________ +template +int isPairFromGammaZ(T const& t1, T const& t2, TMCParticles const& mcParticles) +{ + int id1 = isFromGammaZ(t1, mcParticles); + int id2 = isFromGammaZ(t2, mcParticles); + if ((id1 > -1 && id2 > -1) && (id1 == id2)) { + return id1; + } else { + return -999; + } +} +//_______________________________________________________________________ template bool isCharmonia(T const& track) { diff --git a/PWGEM/Dilepton/Utils/MlResponseO2Track.h b/PWGEM/Dilepton/Utils/MlResponseO2Track.h index 0b1bdbbe2be..80824c3ff87 100644 --- a/PWGEM/Dilepton/Utils/MlResponseO2Track.h +++ b/PWGEM/Dilepton/Utils/MlResponseO2Track.h @@ -58,10 +58,10 @@ int nsize = 0; \ int ncls = 0; \ for (int il = v1; il < v2; il++) { \ - nsize += track.itsClsSizeInLayer(il); \ - if (nsize > 0) { \ + if (track.itsClsSizeInLayer(il) > 0) { \ ncls++; \ } \ + nsize += track.itsClsSizeInLayer(il); \ } \ inputFeature = static_cast(nsize) / static_cast(ncls); \ break; \ @@ -73,10 +73,10 @@ int nsize = 0; \ int ncls = 0; \ for (int il = v1; il < v2; il++) { \ - nsize += track.itsClsSizeInLayer(il); \ - if (nsize > 0) { \ + if (track.itsClsSizeInLayer(il) > 0) { \ ncls++; \ } \ + nsize += track.itsClsSizeInLayer(il); \ } \ inputFeature = static_cast(nsize) / static_cast(ncls) * std::cos(std::atan(trackParCov.getTgl())); \ break; \ @@ -107,16 +107,6 @@ break; \ } -// Check if the index of mCachedIndices (index associated to a FEATURE) -// matches the entry in EnumInputFeatures associated to this FEATURE -// if so, the inputFeatures vector is filled with the FEATURE's value -// by calling the corresponding GETTER1 from track and multiplying with cos(atan(GETTER2)) -#define CHECK_AND_FILL_O2_TRACK_COS(FEATURE, GETTER1, GETTER2) \ - case static_cast(InputFeaturesO2Track::FEATURE): { \ - inputFeature = track.GETTER1() * std::cos(std::atan(track.GETTER2())); \ - break; \ - } - // Check if the index of mCachedIndices (index associated to a FEATURE) // matches the entry in EnumInputFeatures associated to this FEATURE // if so, the inputFeatures vector is filled with the FEATURE's value @@ -343,7 +333,6 @@ class MlResponseO2Track : public MlResponse #undef CHECK_AND_FILL_O2_TRACK_MEAN_ITSCLUSTER_SIZE #undef CHECK_AND_FILL_O2_TRACK_MEAN_ITSCLUSTER_SIZE_COS #undef CHECK_AND_FILL_O2_TRACK_SQRT -#undef CHECK_AND_FILL_O2_TRACK_COS #undef CHECK_AND_FILL_O2_TRACK_TPCTOF #undef CHECK_AND_FILL_O2_TRACK_RELDIFF #undef CHECK_AND_FILL_DIELECTRON_COLLISION diff --git a/PWGEM/Dilepton/Utils/PairUtilities.h b/PWGEM/Dilepton/Utils/PairUtilities.h index 48813c84722..57992d65447 100644 --- a/PWGEM/Dilepton/Utils/PairUtilities.h +++ b/PWGEM/Dilepton/Utils/PairUtilities.h @@ -71,13 +71,10 @@ enum class DileptonPrefilterBit : int { }; enum class DileptonPrefilterBitDerived : int { - kMee = 0, // reject tracks from pi0 dalitz decays at very low mass - kPhiV = 1, // reject tracks from photon conversions - kSplitOrMergedTrackLS = 2, // reject split or marged tracks in LS pairs based on momentum deta-dphi at PV - kSplitOrMergedTrackULS = 3, // reject split or marged tracks in ULS pairs based on momentum deta-dphi at PV - kSplitOrMergedTrackLSAtRefR = 4, // reject split or marged tracks in LS pairs based on deta-dphi position at ref. radius - kSplitOrMergedTrackULSAtRefR = 5, // reject split or marged tracks in ULS pairs based on deta-dphi position at ref. radius - kPhiVLS = 6, // reject suspicious tracks. e.g. duplicated tracks or wrongly matched ITS-TPC tracks. Check mee vs. phiv. + kMee = 0, // reject tracks from pi0 dalitz decays at very low mass + kPhiV = 1, // reject tracks from photon conversions + kSplitOrMergedTrackLS = 2, // reject split or marged tracks in LS pairs based on momentum deta-dphi at PV + kSplitOrMergedTrackULS = 3, // reject split or marged tracks in ULS pairs based on momentum deta-dphi at PV }; using SMatrix55 = ROOT::Math::SMatrix>; diff --git a/PWGEM/Dilepton/Utils/SemiCharmTag.h b/PWGEM/Dilepton/Utils/SemiCharmTag.h index c38df4337af..f2ca9343986 100644 --- a/PWGEM/Dilepton/Utils/SemiCharmTag.h +++ b/PWGEM/Dilepton/Utils/SemiCharmTag.h @@ -21,15 +21,16 @@ #include #include -#include #include -#include +#include #include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) #include #include +#include + namespace o2::aod::pwgem::dilepton::utils { @@ -73,7 +74,7 @@ struct LHPair { // struct to store electron-hadron pair information }; template -LHPair makePairLeptonTrack(TFitter& fitter, TCollision const& collision, TLepton const& lepton, TTrack const& track, o2::track::PID::ID leptonId, o2::track::PID::ID strHadId) +LHPair makePairLeptonTrack(TFitter& fitter, TCollision const& collision, TLepton const& lepton, TTrack const& track, const o2::track::PID::ID leptonId, const o2::track::PID::ID strHadId, const float massLepton) { LHPair pair; auto leptonParCov = getTrackParCov(lepton); @@ -159,17 +160,7 @@ LHPair makePairLeptonTrack(TFitter& fitter, TCollision const& collision, TLepton // LOGF(info, "fitter.getBz() = %f, dcaLH.getY() = %f, dcaLH.getZ() = %f", fitter.getBz(), dcaLH.getY(), dcaLH.getZ()); - ROOT::Math::PxPyPzMVector v1(pvec0[0], pvec0[1], pvec0[2], o2::constants::physics::MassElectron); - if (leptonId == o2::track::PID::Electron) { - v1.SetM(o2::constants::physics::MassElectron); - } else if (leptonId == o2::track::PID::Muon) { - v1.SetM(o2::constants::physics::MassMuon); - } else { - LOGF(info, "leptonId supports only Electron or Muon."); - pair.isOK = false; - return pair; - } - + ROOT::Math::PxPyPzMVector v1(pvec0[0], pvec0[1], pvec0[2], massLepton); ROOT::Math::PxPyPzMVector v2(pvec1[0], pvec1[1], pvec1[2], o2::constants::physics::MassKaonCharged); ROOT::Math::PxPyPzMVector v12 = v1 + v2; pair.mass = v12.M(); @@ -182,7 +173,7 @@ LHPair makePairLeptonTrack(TFitter& fitter, TCollision const& collision, TLepton } template -LHPair makePairLeptonV0(TFitter& fitter, TCollision const& collision, TLepton const& lepton, TV0 const& v0, o2::track::PID::ID leptonId, o2::track::PID::ID strHadId) +LHPair makePairLeptonV0(TFitter& fitter, TCollision const& collision, TLepton const& lepton, TV0 const& v0, o2::track::PID::ID leptonId, o2::track::PID::ID strHadId, const float massLepton) { LHPair pair; auto leptonParCov = getTrackParCov(lepton); @@ -276,17 +267,7 @@ LHPair makePairLeptonV0(TFitter& fitter, TCollision const& collision, TLepton co // pair.impParCZY = dcaLH.getSigmaYZ(); // pair.impParCZZ = dcaLH.getSigmaZ2(); - ROOT::Math::PxPyPzMVector v1(pvec0[0], pvec0[1], pvec0[2], o2::constants::physics::MassElectron); - if (leptonId == o2::track::PID::Electron) { - v1.SetM(o2::constants::physics::MassElectron); - } else if (leptonId == o2::track::PID::Muon) { - v1.SetM(o2::constants::physics::MassMuon); - } else { - LOGF(info, "leptonId supports only Electron or Muon."); - pair.isOK = false; - return pair; - } - + ROOT::Math::PxPyPzMVector v1(pvec0[0], pvec0[1], pvec0[2], massLepton); ROOT::Math::PxPyPzMVector v2(pvec1[0], pvec1[1], pvec1[2], o2::constants::physics::MassLambda); if (strHadId == o2::track::PID::Lambda) { v2.SetM(o2::constants::physics::MassLambda); @@ -310,7 +291,7 @@ LHPair makePairLeptonV0(TFitter& fitter, TCollision const& collision, TLepton co } template -LHPair makePairLeptonCascade(TFitter& fitter, TCollision const& collision, TLepton const& lepton, TCascade const& cascade, o2::track::PID::ID leptonId, o2::track::PID::ID strHadId) +LHPair makePairLeptonCascade(TFitter& fitter, TCollision const& collision, TLepton const& lepton, TCascade const& cascade, o2::track::PID::ID leptonId, o2::track::PID::ID strHadId, const float massLepton) { LHPair pair; auto leptonParCov = getTrackParCov(lepton); @@ -408,17 +389,7 @@ LHPair makePairLeptonCascade(TFitter& fitter, TCollision const& collision, TLept // pair.impParCZY = dcaLH.getSigmaYZ(); // pair.impParCZZ = dcaLH.getSigmaZ2(); - ROOT::Math::PxPyPzMVector v1(pvec0[0], pvec0[1], pvec0[2], o2::constants::physics::MassElectron); - if (leptonId == o2::track::PID::Electron) { - v1.SetM(o2::constants::physics::MassElectron); - } else if (leptonId == o2::track::PID::Muon) { - v1.SetM(o2::constants::physics::MassMuon); - } else { - LOGF(info, "leptonId supports only Electron or Muon."); - pair.isOK = false; - return pair; - } - + ROOT::Math::PxPyPzMVector v1(pvec0[0], pvec0[1], pvec0[2], massLepton); ROOT::Math::PxPyPzMVector v2(pvec1[0], pvec1[1], pvec1[2], o2::constants::physics::MassXiMinus); if (strHadId == o2::track::PID::XiMinus) { v2.SetM(o2::constants::physics::MassXiMinus); diff --git a/PWGEM/PhotonMeson/Core/CMakeLists.txt b/PWGEM/PhotonMeson/Core/CMakeLists.txt index 1eb9558356d..0150236c53e 100644 --- a/PWGEM/PhotonMeson/Core/CMakeLists.txt +++ b/PWGEM/PhotonMeson/Core/CMakeLists.txt @@ -21,16 +21,3 @@ o2physics_add_library(PWGEMPhotonMesonCore EMBitFlags.cxx EMNonLin.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::MLCore O2Physics::PWGEMDileptonCore KFParticle::KFParticle) - -o2physics_target_root_dictionary(PWGEMPhotonMesonCore - HEADERS V0PhotonCut.h - DalitzEECut.h - PHOSPhotonCut.h - EMCPhotonCut.h - PairCut.h - EMPhotonEventCut.h - CutsLibrary.h - HistogramsLibrary.h - EMBitFlags.h - EMNonLin.h - LINKDEF PWGEMPhotonMesonCoreLinkDef.h) diff --git a/PWGEM/PhotonMeson/Core/DalitzEECut.h b/PWGEM/PhotonMeson/Core/DalitzEECut.h index 293a52424c0..5366b94f36e 100644 --- a/PWGEM/PhotonMeson/Core/DalitzEECut.h +++ b/PWGEM/PhotonMeson/Core/DalitzEECut.h @@ -24,21 +24,19 @@ #include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) #include -#include - -#include #include #include #include #include +#include #include -class DalitzEECut : public TNamed +class DalitzEECut { public: DalitzEECut() = default; - DalitzEECut(const char* name, const char* title) : TNamed(name, title) {} + DalitzEECut(const char* name, const char* title) : name(name), title(title) {} enum class DalitzEECuts : int { // pair cut @@ -71,6 +69,9 @@ class DalitzEECut : public TNamed kTPConly = 1, }; + const std::string getName() const { return name; } + const std::string getTitle() const { return title; } + template bool IsSelected(TTrack1 const& t1, TTrack2 const& t2, float bz) const { @@ -311,6 +312,8 @@ class DalitzEECut : public TNamed bool IsPhotonConversionSelected() const { return mSelectPC; } private: + std::string name; + std::string title; static const std::pair> its_ib_any_Requirement; static const std::pair> its_ib_1st_Requirement; // pair cuts @@ -353,8 +356,6 @@ class DalitzEECut : public TNamed float mMinTPCNsigmaEl{-1e+10}, mMaxTPCNsigmaEl{+1e+10}; float mMinTPCNsigmaPi{0}, mMaxTPCNsigmaPi{0}; float mMinTOFNsigmaEl{-1e+10}, mMaxTOFNsigmaEl{+1e+10}; - - ClassDef(DalitzEECut, 2); }; #endif // PWGEM_PHOTONMESON_CORE_DALITZEECUT_H_ diff --git a/PWGEM/PhotonMeson/Core/EMCPhotonCut.h b/PWGEM/PhotonMeson/Core/EMCPhotonCut.h index bba559ed8cb..30045d96faf 100644 --- a/PWGEM/PhotonMeson/Core/EMCPhotonCut.h +++ b/PWGEM/PhotonMeson/Core/EMCPhotonCut.h @@ -25,12 +25,9 @@ #include #include -#include #include -#include - #include #include #include @@ -108,11 +105,11 @@ struct TrackMatchingParams { float c{-2.5f}; }; -class EMCPhotonCut : public TNamed +class EMCPhotonCut { public: EMCPhotonCut() = default; - EMCPhotonCut(const char* name, const char* title) : TNamed(name, title) {} + EMCPhotonCut(const char* name, const char* title) : name(name), title(title) {} enum class EMCPhotonCuts : std::uint8_t { // cluster cut @@ -133,6 +130,9 @@ class EMCPhotonCut : public TNamed kSecondary, }; + const std::string getName() const { return name; } + const std::string getTitle() const { return title; } + static const char* mCutNames[static_cast(EMCPhotonCuts::kNCuts)]; static constexpr auto getClusterId(o2::soa::is_iterator auto const& t) @@ -701,6 +701,8 @@ class EMCPhotonCut : public TNamed void print() const; private: + std::string name; + std::string title; // EMCal cluster cuts int mDefinition{10}; ///< clusterizer definition float mMinE{0.7f}; ///< minimum energy @@ -723,8 +725,6 @@ class EMCPhotonCut : public TNamed TrackMatchingParams mTrackMatchingPhiParams = {-1.f, 0.f, 0.f}; TrackMatchingParams mSecTrackMatchingEtaParams = {-1.f, 0.f, 0.f}; TrackMatchingParams mSecTrackMatchingPhiParams = {-1.f, 0.f, 0.f}; - - ClassDef(EMCPhotonCut, 3); }; #endif // PWGEM_PHOTONMESON_CORE_EMCPHOTONCUT_H_ diff --git a/PWGEM/PhotonMeson/Core/EMPhotonEventCut.h b/PWGEM/PhotonMeson/Core/EMPhotonEventCut.h index 5b14aa8d2ef..1056de45a76 100644 --- a/PWGEM/PhotonMeson/Core/EMPhotonEventCut.h +++ b/PWGEM/PhotonMeson/Core/EMPhotonEventCut.h @@ -19,15 +19,13 @@ #include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/TriggerAliases.h" -#include +#include -#include - -class EMPhotonEventCut : public TNamed +class EMPhotonEventCut { public: EMPhotonEventCut() = default; - EMPhotonEventCut(const char* name, const char* title) : TNamed(name, title) {} + EMPhotonEventCut(const char* name, const char* title) : name(name), title(title) {} enum class EMPhotonEventCuts : int { kSel8 = 0, @@ -52,6 +50,9 @@ class EMPhotonEventCut : public TNamed kNCuts }; + const std::string getName() const { return name; } + const std::string getTitle() const { return title; } + template bool IsSelected(T const& collision) const { @@ -203,6 +204,8 @@ class EMPhotonEventCut : public TNamed void SetRequireEMCHardwareTriggered(bool flag); private: + std::string name; + std::string title; bool mRequireSel8{false}; bool mRequireFT0AND{true}; float mMinZvtx{-10.f}, mMaxZvtx{+10.f}; @@ -222,8 +225,6 @@ class EMPhotonEventCut : public TNamed bool mRequireGoodITSLayersAll{false}; bool mRequireEMCReadoutInMB{false}; bool mRequireEMCHardwareTriggered{false}; - - ClassDef(EMPhotonEventCut, 1); }; #endif // PWGEM_PHOTONMESON_CORE_EMPHOTONEVENTCUT_H_ diff --git a/PWGEM/PhotonMeson/Core/PHOSPhotonCut.h b/PWGEM/PhotonMeson/Core/PHOSPhotonCut.h index ea7fd3440ab..32f1b59d133 100644 --- a/PWGEM/PhotonMeson/Core/PHOSPhotonCut.h +++ b/PWGEM/PhotonMeson/Core/PHOSPhotonCut.h @@ -18,15 +18,13 @@ #include -#include +#include -#include - -class PHOSPhotonCut : public TNamed +class PHOSPhotonCut { public: PHOSPhotonCut() = default; - PHOSPhotonCut(const char* name, const char* title) : TNamed(name, title) {} + PHOSPhotonCut(const char* name, const char* title) : name(name), title(title) {} enum class PHOSPhotonCuts : int { kEnergy = 0, @@ -35,6 +33,9 @@ class PHOSPhotonCut : public TNamed kNCuts }; + const std::string getName() const { return name; } + const std::string getTitle() const { return title; } + static const char* mCutNames[static_cast(PHOSPhotonCuts::kNCuts)]; // Temporary function to check if track passes selection criteria. To be replaced by framework filters. @@ -96,9 +97,9 @@ class PHOSPhotonCut : public TNamed void print() const; private: + std::string name; + std::string title; float mMinEnergy{0.1f}, mMaxEnergy{1e+10f}; - - ClassDef(PHOSPhotonCut, 2); }; #endif // PWGEM_PHOTONMESON_CORE_PHOSPHOTONCUT_H_ diff --git a/PWGEM/PhotonMeson/Core/PWGEMPhotonMesonCoreLinkDef.h b/PWGEM/PhotonMeson/Core/PWGEMPhotonMesonCoreLinkDef.h deleted file mode 100644 index 2a1a0ff7226..00000000000 --- a/PWGEM/PhotonMeson/Core/PWGEMPhotonMesonCoreLinkDef.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#ifndef PWGEM_PHOTONMESON_CORE_PWGEMPHOTONMESONCORELINKDEF_H_ -#define PWGEM_PHOTONMESON_CORE_PWGEMPHOTONMESONCORELINKDEF_H_ - -#pragma link off all globals; -#pragma link off all classes; -#pragma link off all functions; - -#pragma link C++ class V0PhotonCut + ; -#pragma link C++ class DalitzEECut + ; -#pragma link C++ class PHOSPhotonCut + ; -#pragma link C++ class EMCPhotonCut + ; -#pragma link C++ class EMPhotonEventCut + ; -#pragma link C++ class PairCut + ; -#pragma link C++ class EMBitFlags + ; - -#endif // PWGEM_PHOTONMESON_CORE_PWGEMPHOTONMESONCORELINKDEF_H_ diff --git a/PWGEM/PhotonMeson/Core/PairCut.h b/PWGEM/PhotonMeson/Core/PairCut.h index f30f7dae7a9..63dfddf2bd4 100644 --- a/PWGEM/PhotonMeson/Core/PairCut.h +++ b/PWGEM/PhotonMeson/Core/PairCut.h @@ -16,15 +16,13 @@ #ifndef PWGEM_PHOTONMESON_CORE_PAIRCUT_H_ #define PWGEM_PHOTONMESON_CORE_PAIRCUT_H_ -#include +#include -#include - -class PairCut : public TNamed +class PairCut { public: PairCut() = default; - PairCut(const char* name, const char* title) : TNamed(name, title) {} + PairCut(const char* name, const char* title) : name(name), title(title) {} enum class PairCuts : int { // v0 cut @@ -32,6 +30,9 @@ class PairCut : public TNamed kNCuts }; + const std::string getName() const { return name; } + const std::string getTitle() const { return title; } + static const char* mCutNames[static_cast(PairCuts::kNCuts)]; template @@ -66,9 +67,9 @@ class PairCut : public TNamed void print() const; private: + std::string name; + std::string title; float mMinAsym{-1e+10}, mMaxAsym{1e+10}; - - ClassDef(PairCut, 1); }; #endif // PWGEM_PHOTONMESON_CORE_PAIRCUT_H_ diff --git a/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h b/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h index f022be669ef..2a84548f9bc 100644 --- a/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h +++ b/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h @@ -978,6 +978,25 @@ struct Pi0EtaToGammaGamma { if (std::fabs(v12.Rapidity()) > maxY) { continue; } + // as photon has mass= 0 e = p + float alphaMeson = std::fabs(g1.p() - g2.p()) / (g1.p() + g2.p()); + float alphaCut = 999.f; + switch (static_cast(cfgAlphaMesonCut.value)) { + case AlphaMesonCutOption::Off: + break; + case AlphaMesonCutOption::SpecificValue: + alphaCut = cfgAlphaMeson; + break; + case AlphaMesonCutOption::PTDependent: { + alphaCut = cfgAlphaMesonA * std::tanh(cfgAlphaMesonB * v12.pt()); + break; + } + default: + LOGF(error, "Invalid option for alpha meson cut. No alpha cut will be applied."); + } + if (alphaMeson > alphaCut) { + continue; + } fRegistry.fill(HIST("Pair/mix/hs"), v12.M(), v12.Pt(), weight); } diff --git a/PWGEM/PhotonMeson/Core/V0PhotonCut.h b/PWGEM/PhotonMeson/Core/V0PhotonCut.h index 741f72f8df9..407c77ae8c5 100644 --- a/PWGEM/PhotonMeson/Core/V0PhotonCut.h +++ b/PWGEM/PhotonMeson/Core/V0PhotonCut.h @@ -34,8 +34,6 @@ #include -#include - #include #include #include @@ -168,7 +166,7 @@ class V0PhotonCut : public TNamed { public: V0PhotonCut() = default; - V0PhotonCut(const char* name, const char* title) : TNamed(name, title) {} + V0PhotonCut(const char* name, const char* title) : name(name), title(title) {} ~V0PhotonCut() override { delete mEmMlResponse; }; enum class V0PhotonCuts : int { @@ -216,6 +214,9 @@ class V0PhotonCut : public TNamed kRadAndAngle = 2 }; + const std::string getName() const { return name; } + const std::string getTitle() const { return title; } + /// \brief add histograms to registry /// \param fRegistry pointer to histogram registry void addQAHistograms(o2::framework::HistogramRegistry* fRegistry = nullptr) const @@ -1155,6 +1156,8 @@ class V0PhotonCut : public TNamed void setDoQA(bool flag = false); private: + std::string name; + std::string title; static const std::pair> its_ib_Requirement; static const std::pair> its_ob_Requirement; static const std::pair> its_ob_Requirement_ITSTPC; @@ -1238,8 +1241,6 @@ class V0PhotonCut : public TNamed bool mDoQA{false}; ///< flag to decide if QA should be done or not mutable uint nAccV0PerColl{0}; ///< running number of accepted v0 photons per collision used for QA mutable int currentCollID{-1}; ///< running collision ID of v0 photon used for QA - - ClassDef(V0PhotonCut, 5); }; #endif // PWGEM_PHOTONMESON_CORE_V0PHOTONCUT_H_ diff --git a/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx b/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx index 463bc9045a8..83fa58c4b84 100644 --- a/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx @@ -44,7 +44,7 @@ #include #include -#include +#include #include #include #include @@ -120,12 +120,8 @@ struct MaterialBudgetMC { { for (const auto& tagcut : tagcuts) { for (const auto& probecut : probecuts) { - std::string cutname1 = tagcut.GetName(); - std::string cutname2 = probecut.GetName(); - - // if (cutname1 == cutname2) { - // continue; - // } + std::string cutname1 = tagcut.getName(); + std::string cutname2 = probecut.getName(); THashList* list_pair_subsys = reinterpret_cast(list_pair->FindObject(pairname.data())); std::string photon_cut_name = cutname1 + "_" + cutname2; @@ -133,7 +129,7 @@ struct MaterialBudgetMC { THashList* list_pair_subsys_photoncut = reinterpret_cast(list_pair_subsys->FindObject(photon_cut_name.data())); for (const auto& cut3 : cuts3) { - std::string pair_cut_name = cut3.GetName(); + std::string pair_cut_name = cut3.getName(); o2::aod::pwgem::photon::histogram::AddHistClass(list_pair_subsys_photoncut, pair_cut_name.data()); THashList* list_pair_subsys_paircut = reinterpret_cast(list_pair_subsys_photoncut->FindObject(pair_cut_name.data())); o2::aod::pwgem::photon::histogram::DefineHistograms(list_pair_subsys_paircut, "material_budget_study", "Pair"); @@ -160,8 +156,8 @@ struct MaterialBudgetMC { // for V0s for (const auto& cut : fProbeCuts) { - const char* cutname = cut.GetName(); - THashList* list_v0_cut = o2::aod::pwgem::photon::histogram::AddHistClass(list_v0, cutname); + std::string cutname = cut.getName(); + THashList* list_v0_cut = o2::aod::pwgem::photon::histogram::AddHistClass(list_v0, cutname.c_str()); o2::aod::pwgem::photon::histogram::DefineHistograms(list_v0_cut, "material_budget_study", "V0"); } @@ -189,42 +185,51 @@ struct MaterialBudgetMC { void DefineTagCuts() { - TString cutNamesStr = fConfigTagCuts.value; - if (!cutNamesStr.IsNull()) { - std::unique_ptr objArray(cutNamesStr.Tokenize(",")); - for (int icut = 0; icut < objArray->GetEntries(); ++icut) { - const char* cutname = objArray->At(icut)->GetName(); - LOGF(info, "add cut : %s", cutname); - fTagCuts.push_back(*pcmcuts::GetCut(cutname)); - } + if (fConfigTagCuts.value.empty()) { + return; + } + + std::string_view namesView(fConfigTagCuts.value); + + for (auto name : namesView | std::views::split(',')) { + std::string cutString(name.begin(), name.end()); + const char* cutname = cutString.c_str(); + LOGF(info, "add tag cut : %s", cutname); + fTagCuts.push_back(*pcmcuts::GetCut(cutname)); } LOGF(info, "Number of Tag PCM cuts = %d", fTagCuts.size()); } void DefineProbeCuts() { - TString cutNamesStr = fConfigProbeCuts.value; - if (!cutNamesStr.IsNull()) { - std::unique_ptr objArray(cutNamesStr.Tokenize(",")); - for (int icut = 0; icut < objArray->GetEntries(); ++icut) { - const char* cutname = objArray->At(icut)->GetName(); - LOGF(info, "add cut : %s", cutname); - fProbeCuts.push_back(*pcmcuts::GetCut(cutname)); - } + if (fConfigProbeCuts.value.empty()) { + return; + } + + std::string_view namesView(fConfigProbeCuts.value); + + for (auto name : namesView | std::views::split(',')) { + std::string cutString(name.begin(), name.end()); + const char* cutname = cutString.c_str(); + LOGF(info, "add probe cut : %s", cutname); + fProbeCuts.push_back(*pcmcuts::GetCut(cutname)); } LOGF(info, "Number of Probe PCM cuts = %d", fProbeCuts.size()); } void DefinePairCuts() { - TString cutNamesStr = fConfigPairCuts.value; - if (!cutNamesStr.IsNull()) { - std::unique_ptr objArray(cutNamesStr.Tokenize(",")); - for (int icut = 0; icut < objArray->GetEntries(); ++icut) { - const char* cutname = objArray->At(icut)->GetName(); - LOGF(info, "add cut : %s", cutname); - fPairCuts.push_back(*paircuts::GetCut(cutname)); - } + if (fConfigPairCuts.value.empty()) { + return; + } + + std::string_view namesView(fConfigPairCuts.value); + + for (auto name : namesView | std::views::split(',')) { + std::string cutString(name.begin(), name.end()); + const char* cutname = cutString.c_str(); + LOGF(info, "add pair cut : %s", cutname); + fPairCuts.push_back(*paircuts::GetCut(cutname)); } LOGF(info, "Number of Pair cuts = %d", fPairCuts.size()); } @@ -288,7 +293,7 @@ struct MaterialBudgetMC { value[1] = photon.v0radius(); value[2] = RecoDecay::constrainAngle(phi_cp); value[3] = eta_cp; - reinterpret_cast(list_v0->FindObject(cut.GetName())->FindObject("hs_conv_point"))->Fill(value); + reinterpret_cast(list_v0->FindObject(cut.getName().c_str())->FindObject("hs_conv_point"))->Fill(value); } // end of photon loop } // end of cut loop @@ -381,7 +386,7 @@ struct MaterialBudgetMC { value[3] = g2.v0radius(); value[4] = RecoDecay::constrainAngle(phi_cp2); value[5] = eta_cp2; - reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.GetName(), probecut.GetName()))->FindObject(paircut.GetName())->FindObject("hs_conv_point_same"))->Fill(value); + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.getName().c_str(), probecut.getName().c_str()))->FindObject(paircut.getName().c_str())->FindObject("hs_conv_point_same"))->Fill(value); } // end of pair cut loop } // end of g2 loop } // end of g1 loop diff --git a/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGammaMCPCMPCMML.cxx b/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGammaMCPCMPCMML.cxx index c5b06741e75..1f2f76d6499 100644 --- a/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGammaMCPCMPCMML.cxx +++ b/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGammaMCPCMPCMML.cxx @@ -26,7 +26,7 @@ using namespace o2::aod; using namespace o2::framework; using namespace o2::aod::pwgem::photonmeson::photonpair; -using MyV0Photons = o2::soa::Filtered>; +using MyV0Photons = o2::soa::Filtered>; using MyMCV0Legs = soa::Join; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGEM/PhotonMeson/Tasks/SinglePhoton.cxx b/PWGEM/PhotonMeson/Tasks/SinglePhoton.cxx index 62d2e47a234..04b7dbb7a26 100644 --- a/PWGEM/PhotonMeson/Tasks/SinglePhoton.cxx +++ b/PWGEM/PhotonMeson/Tasks/SinglePhoton.cxx @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #include #include @@ -108,12 +108,6 @@ struct SinglePhoton { if (context.mOptions.get("processPCM")) { fDetNames.push_back("PCM"); } - // if (context.mOptions.get("processPHOS")) { - // fDetNames.push_back("PHOS"); - // } - // if (context.mOptions.get("processEMC")) { - // fDetNames.push_back("EMC"); - // } DefinePCMCuts(); DefinePHOSCuts(); @@ -130,7 +124,7 @@ struct SinglePhoton { void add_histograms(THashList* list_photon, const std::string detname, TCuts1 const& cuts1) { for (auto& cut1 : cuts1) { - std::string cutname1 = cut1.GetName(); + std::string cutname1 = cut1.getName(); THashList* list_photon_subsys = reinterpret_cast(list_photon->FindObject(detname.data())); o2::aod::pwgem::photon::histogram::AddHistClass(list_photon_subsys, cutname1.data()); @@ -188,55 +182,64 @@ struct SinglePhoton { void DefinePCMCuts() { - TString cutNamesStr = fConfigPCMCuts.value; - if (!cutNamesStr.IsNull()) { - std::unique_ptr objArray(cutNamesStr.Tokenize(",")); - for (int icut = 0; icut < objArray->GetEntries(); ++icut) { - const char* cutname = objArray->At(icut)->GetName(); - LOGF(info, "add cut : %s", cutname); - fPCMCuts.push_back(*pcmcuts::GetCut(cutname)); - } + if (fConfigPCMCuts.value.empty()) { + return; + } + + std::string_view namesView(fConfigPCMCuts.value); + + for (auto name : namesView | std::views::split(',')) { + std::string cutString(name.begin(), name.end()); + const char* cutname = cutString.c_str(); + LOGF(info, "add PCM cut : %s", cutname); + fPCMCuts.push_back(*pcmcuts::GetCut(cutname)); } LOGF(info, "Number of PCM cuts = %d", fPCMCuts.size()); } void DefinePHOSCuts() { - TString cutNamesStr = fConfigPHOSCuts.value; - if (!cutNamesStr.IsNull()) { - std::unique_ptr objArray(cutNamesStr.Tokenize(",")); - for (int icut = 0; icut < objArray->GetEntries(); ++icut) { - const char* cutname = objArray->At(icut)->GetName(); - LOGF(info, "add cut : %s", cutname); - fPHOSCuts.push_back(*phoscuts::GetCut(cutname)); - } + if (fConfigPHOSCuts.value.empty()) { + return; + } + + std::string_view namesView(fConfigPHOSCuts.value); + + for (auto name : namesView | std::views::split(',')) { + std::string cutString(name.begin(), name.end()); + const char* cutname = cutString.c_str(); + LOGF(info, "add PHOS cut : %s", cutname); + fPHOSCuts.push_back(*phoscuts::GetCut(cutname)); } LOGF(info, "Number of PHOS cuts = %d", fPHOSCuts.size()); } void DefineEMCCuts() { - TString cutNamesStr = fConfigEMCCuts.value; - if (!cutNamesStr.IsNull()) { - std::unique_ptr objArray(cutNamesStr.Tokenize(",")); - for (int icut = 0; icut < objArray->GetEntries(); ++icut) { - const char* cutname = objArray->At(icut)->GetName(); - LOGF(info, "add cut : %s", cutname); - if (std::strcmp(cutname, "custom") == 0) { - EMCPhotonCut* custom_cut = new EMCPhotonCut(cutname, cutname); - custom_cut->SetMinE(EMC_minE); - custom_cut->SetMinNCell(EMC_minNCell); - custom_cut->SetM02Range(EMC_minM02, EMC_maxM02); - custom_cut->SetTimeRange(EMC_minTime, EMC_maxTime); - - custom_cut->SetTrackMatchingEtaParams(EMC_TM_Eta->at(0), EMC_TM_Eta->at(1), EMC_TM_Eta->at(2)); - custom_cut->SetTrackMatchingPhiParams(EMC_TM_Phi->at(0), EMC_TM_Phi->at(1), EMC_TM_Phi->at(2)); - - custom_cut->SetMinEoverP(EMC_Eoverp); - custom_cut->SetUseExoticCut(EMC_UseExoticCut); - fEMCCuts.push_back(*custom_cut); - } else { - fEMCCuts.push_back(*emccuts::GetCut(cutname)); - } + if (fConfigEMCCuts.value.empty()) { + return; + } + + std::string_view namesView(fConfigEMCCuts.value); + + for (auto name : namesView | std::views::split(',')) { + std::string cutString(name.begin(), name.end()); + const char* cutname = cutString.c_str(); + LOGF(info, "add EMC cut : %s", cutname); + if (std::strcmp(cutname, "custom") == 0) { + EMCPhotonCut* custom_cut = new EMCPhotonCut(cutname, cutname); + custom_cut->SetMinE(EMC_minE); + custom_cut->SetMinNCell(EMC_minNCell); + custom_cut->SetM02Range(EMC_minM02, EMC_maxM02); + custom_cut->SetTimeRange(EMC_minTime, EMC_maxTime); + + custom_cut->SetTrackMatchingEtaParams(EMC_TM_Eta->at(0), EMC_TM_Eta->at(1), EMC_TM_Eta->at(2)); + custom_cut->SetTrackMatchingPhiParams(EMC_TM_Phi->at(0), EMC_TM_Phi->at(1), EMC_TM_Phi->at(2)); + + custom_cut->SetMinEoverP(EMC_Eoverp); + custom_cut->SetUseExoticCut(EMC_UseExoticCut); + fEMCCuts.push_back(*custom_cut); + } else { + fEMCCuts.push_back(*emccuts::GetCut(cutname)); } } LOGF(info, "Number of EMCal cuts = %d", fEMCCuts.size()); @@ -306,7 +309,7 @@ struct SinglePhoton { auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); for (auto& cut : cuts1) { - THashList* list_photon_det_cut = static_cast(list_photon_det->FindObject(cut.GetName())); + THashList* list_photon_det_cut = static_cast(list_photon_det->FindObject(cut.getName().c_str())); for (auto& photon : photons1_coll) { if (!IsSelected(photon, cut)) { continue; diff --git a/PWGEM/PhotonMeson/Tasks/SinglePhotonMC.cxx b/PWGEM/PhotonMeson/Tasks/SinglePhotonMC.cxx index e8e083dca28..b3ed44f54c2 100644 --- a/PWGEM/PhotonMeson/Tasks/SinglePhotonMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/SinglePhotonMC.cxx @@ -39,7 +39,7 @@ #include #include -#include +#include #include #include #include @@ -77,20 +77,6 @@ struct SinglePhotonMC { Configurable margin_z_mc{"margin_z_mc", 7.0, "margin for z cut in cm for MC"}; Configurable fConfigPCMCuts{"cfgPCMCuts", "analysis,qc,nocut", "Comma separated list of V0 photon cuts"}; - // Configurable fConfigPHOSCuts{"cfgPHOSCuts", "test02,test03", "Comma separated list of PHOS photon cuts"}; - // Configurable fConfigEMCCuts{"fConfigEMCCuts", "custom,standard,nocut", "Comma separated list of EMCal photon cuts"}; - - //// Configurable for EMCal cuts - // Configurable EMC_minTime{"EMC_minTime", -20., "Minimum cluster time for EMCal time cut"}; - // Configurable EMC_maxTime{"EMC_maxTime", +25., "Maximum cluster time for EMCal time cut"}; - // Configurable EMC_minM02{"EMC_minM02", 0.1, "Minimum M02 for EMCal M02 cut"}; - // Configurable EMC_maxM02{"EMC_maxM02", 0.7, "Maximum M02 for EMCal M02 cut"}; - // Configurable EMC_minE{"EMC_minE", 0.7, "Minimum cluster energy for EMCal energy cut"}; - // Configurable EMC_minNCell{"EMC_minNCell", 1, "Minimum number of cells per cluster for EMCal NCell cut"}; - // Configurable> EMC_TM_Eta{"EMC_TM_Eta", {0.01f, 4.07f, -2.5f}, "|eta| <= [0]+(pT+[1])^[2] for EMCal track matching"}; - // Configurable> EMC_TM_Phi{"EMC_TM_Phi", {0.015f, 3.65f, -2.f}, "|phi| <= [0]+(pT+[1])^[2] for EMCal track matching"}; - // Configurable EMC_Eoverp{"EMC_Eoverp", 1.75, "Minimum cluster energy over track momentum for EMCal track matching"}; - // Configurable EMC_UseExoticCut{"EMC_UseExoticCut", true, "FLag to use the EMCal exotic cluster cut"}; Configurable fConfigEMEventCut{"cfgEMEventCut", "minbias", "em event cut"}; // only 1 event cut per wagon EMPhotonEventCut fEMEventCut; @@ -111,16 +97,8 @@ struct SinglePhotonMC { if (context.mOptions.get("processPCM")) { fDetNames.push_back("PCM"); } - // if (context.mOptions.get("processPHOS")) { - // fDetNames.push_back("PHOS"); - // } - // if (context.mOptions.get("processEMC")) { - // fDetNames.push_back("EMC"); - // } DefinePCMCuts(); - // DefinePHOSCuts(); - // DefineEMCCuts(); addhistograms(); TString ev_cut_name = fConfigEMEventCut.value; fEMEventCut = *eventcuts::GetCut(ev_cut_name.Data()); @@ -175,77 +153,27 @@ struct SinglePhotonMC { if (detname == "PCM") { add_photon_histograms(list_photon, detname, fPCMCuts); } - // if (detname == "PHOS") { - // add_photon_histograms(list_photon, detname, fPHOSCuts); - // } - // if (detname == "EMC") { - // add_photon_histograms(list_photon, detname, fEMCCuts); - // } - } // end of detector name loop } void DefinePCMCuts() { - TString cutNamesStr = fConfigPCMCuts.value; - if (!cutNamesStr.IsNull()) { - std::unique_ptr objArray(cutNamesStr.Tokenize(",")); - for (int icut = 0; icut < objArray->GetEntries(); ++icut) { - const char* cutname = objArray->At(icut)->GetName(); - LOGF(info, "add cut : %s", cutname); - fPCMCuts.push_back(*pcmcuts::GetCut(cutname)); - } + if (fConfigPCMCuts.value.empty()) { + return; + } + + std::string_view namesView(fConfigPCMCuts.value); + + for (auto name : namesView | std::views::split(',')) { + std::string cutString(name.begin(), name.end()); + const char* cutname = cutString.c_str(); + LOGF(info, "add tag cut : %s", cutname); + fPCMCuts.push_back(*pcmcuts::GetCut(cutname)); } LOGF(info, "Number of PCM cuts = %d", fPCMCuts.size()); } - // void DefinePHOSCuts() - // { - // TString cutNamesStr = fConfigPHOSCuts.value; - // if (!cutNamesStr.IsNull()) { - // std::unique_ptr objArray(cutNamesStr.Tokenize(",")); - // for (int icut = 0; icut < objArray->GetEntries(); ++icut) { - // const char* cutname = objArray->At(icut)->GetName(); - // LOGF(info, "add cut : %s", cutname); - // fPHOSCuts.push_back(*phoscuts::GetCut(cutname)); - // } - // } - // LOGF(info, "Number of PHOS cuts = %d", fPHOSCuts.size()); - // } - // - // void DefineEMCCuts() - // { - // - // TString cutNamesStr = fConfigEMCCuts.value; - // if (!cutNamesStr.IsNull()) { - // std::unique_ptr objArray(cutNamesStr.Tokenize(",")); - // for (int icut = 0; icut < objArray->GetEntries(); ++icut) { - // const char* cutname = objArray->At(icut)->GetName(); - // LOGF(info, "add cut : %s", cutname); - // if (std::strcmp(cutname, "custom") == 0) { - // EMCPhotonCut* custom_cut = new EMCPhotonCut(cutname, cutname); - // custom_cut->SetMinE(EMC_minE); - // custom_cut->SetMinNCell(EMC_minNCell); - // custom_cut->SetM02Range(EMC_minM02, EMC_maxM02); - // custom_cut->SetTimeRange(EMC_minTime, EMC_maxTime); - // - // custom_cut->SetTrackMatchingEtaParams(EMC_TM_Eta->at(0), EMC_TM_Eta->at(1), EMC_TM_Eta->at(2)); - // custom_cut->SetTrackMatchingPhiParams(EMC_TM_Phi->at(0), EMC_TM_Phi->at(1), EMC_TM_Phi->at(2)); - // - // custom_cut->SetMinEoverP(EMC_Eoverp); - // custom_cut->SetUseExoticCut(EMC_UseExoticCut); - // fEMCCuts.push_back(*custom_cut); - // } else { - // fEMCCuts.push_back(*emccuts::GetCut(cutname)); - // } - // } - // } - // LOGF(info, "Number of EMCal cuts = %d", fEMCCuts.size()); - // } - Preslice perCollision = aod::v0photonkf::pmeventId; - // Preslice perCollision_phos = aod::skimmedcluster::collisionId; - // Preslice perCollision_emc = aod::skimmedcluster::collisionId; template bool IsSelected(TG1 const& g1, TCut1 const& cut1) @@ -293,7 +221,7 @@ struct SinglePhotonMC { auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); for (auto& cut : cuts1) { - THashList* list_photon_det_cut = static_cast(list_photon_det->FindObject(cut.GetName())); + THashList* list_photon_det_cut = static_cast(list_photon_det->FindObject(cut.getName().c_str())); for (auto& photon : photons1_coll) { if (!IsSelected(photon, cut)) { continue; diff --git a/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx b/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx index 818eb101285..b99d863cf06 100644 --- a/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx +++ b/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx @@ -133,14 +133,14 @@ struct TagAndProbe { template void add_pair_histograms(THashList* list_pair, const std::string pairname, TTagCut const& tagcut, TProbeCuts const& probecuts, TPairCuts const& paircuts) { - std::string cutname1 = tagcut.GetName(); + std::string cutname1 = tagcut.getName(); for (auto& cut2 : probecuts) { - std::string cutname2 = cut2.GetName(); + std::string cutname2 = cut2.getName(); std::string photon_cut_name = cutname1 + "_" + cutname2; THashList* list_pair_subsys_photoncut = o2::aod::pwgem::photon::histogram::AddHistClass(list_pair, photon_cut_name.data()); for (auto& cut3 : paircuts) { - std::string pair_cut_name = cut3.GetName(); + std::string pair_cut_name = cut3.getName(); o2::aod::pwgem::photon::histogram::AddHistClass(list_pair_subsys_photoncut, pair_cut_name.data()); THashList* list_pair_subsys_paircut = reinterpret_cast(list_pair_subsys_photoncut->FindObject(pair_cut_name.data())); o2::aod::pwgem::photon::histogram::DefineHistograms(list_pair_subsys_paircut, "tag_and_probe", pairname.data()); @@ -315,7 +315,7 @@ struct TagAndProbe { if (abs(v12.Rapidity()) > maxY) { continue; } - reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.GetName(), probecut.GetName()))->FindObject(paircut.GetName())->FindObject("hMggPt_Probe_Same"))->Fill(v12.M(), v2.Pt()); + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.getName().c_str(), probecut.getName().c_str()))->FindObject(paircut.getName().c_str())->FindObject("hMggPt_Probe_Same"))->Fill(v12.M(), v2.Pt()); if constexpr (pairtype == PairType::kPCMPCM) { if (!probecut.template IsSelected(g2)) { @@ -331,7 +331,7 @@ struct TagAndProbe { } } - reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.GetName(), probecut.GetName()))->FindObject(paircut.GetName())->FindObject("hMggPt_PassingProbe_Same"))->Fill(v12.M(), v2.Pt()); + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.getName().c_str(), probecut.getName().c_str()))->FindObject(paircut.getName().c_str())->FindObject("hMggPt_PassingProbe_Same"))->Fill(v12.M(), v2.Pt()); if constexpr (pairtype == PairType::kEMCEMC) { RotationBackground(v12, v1, v2, photons2_coll, g1.globalIndex(), g2.globalIndex(), probecut, paircut); @@ -406,7 +406,7 @@ struct TagAndProbe { if (abs(v12.Rapidity()) > maxY) { continue; } - reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.GetName(), probecut.GetName()))->FindObject(paircut.GetName())->FindObject("hMggPt_Probe_Mixed"))->Fill(v12.M(), v2.Pt()); + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.getName().c_str(), probecut.getName().c_str()))->FindObject(paircut.getName().c_str())->FindObject("hMggPt_Probe_Mixed"))->Fill(v12.M(), v2.Pt()); if constexpr (pairtype == PairType::kPCMPCM) { if (!probecut.template IsSelected(g2)) { @@ -422,7 +422,7 @@ struct TagAndProbe { } } - reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.GetName(), probecut.GetName()))->FindObject(paircut.GetName())->FindObject("hMggPt_PassingProbe_Mixed"))->Fill(v12.M(), v2.Pt()); + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.getName().c_str(), probecut.getName().c_str()))->FindObject(paircut.getName().c_str())->FindObject("hMggPt_PassingProbe_Mixed"))->Fill(v12.M(), v2.Pt()); } // end of probe cut loop } // end of pair cut loop @@ -484,10 +484,10 @@ struct TagAndProbe { // LOG(info) << "openingAngle2_2 = " << openingAngle2_2; if (openingAngle1 > minOpenAngle) { - reinterpret_cast(fMainList->FindObject("Pair")->FindObject("EMCEMC")->FindObject(Form("%s_%s", cut.GetName(), cut.GetName()))->FindObject(paircut.GetName())->FindObject("hMggPt_Same_RotatedBkg"))->Fill(mother1.M(), mother1.Pt()); + reinterpret_cast(fMainList->FindObject("Pair")->FindObject("EMCEMC")->FindObject(Form("%s_%s", cut.getName().c_str(), cut.getName().c_str()))->FindObject(paircut.getName().c_str())->FindObject("hMggPt_Same_RotatedBkg"))->Fill(mother1.M(), mother1.Pt()); } if (openingAngle2 > minOpenAngle) { - reinterpret_cast(fMainList->FindObject("Pair")->FindObject("EMCEMC")->FindObject(Form("%s_%s", cut.GetName(), cut.GetName()))->FindObject(paircut.GetName())->FindObject("hMggPt_Same_RotatedBkg"))->Fill(mother2.M(), mother2.Pt()); + reinterpret_cast(fMainList->FindObject("Pair")->FindObject("EMCEMC")->FindObject(Form("%s_%s", cut.getName().c_str(), cut.getName().c_str()))->FindObject(paircut.getName().c_str())->FindObject("hMggPt_Same_RotatedBkg"))->Fill(mother2.M(), mother2.Pt()); } } } diff --git a/PWGEM/PhotonMeson/Tasks/emcalQC.cxx b/PWGEM/PhotonMeson/Tasks/emcalQC.cxx index 39af167b327..39317e7e5bc 100644 --- a/PWGEM/PhotonMeson/Tasks/emcalQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/emcalQC.cxx @@ -97,6 +97,11 @@ struct EmcalQC { Configurable emcUseSecondaryTM{"emcUseSecondaryTM", false, "flag to use EMCal secondary track matching cut or not"}; } emccuts; + struct : ConfigurableGroup { + std::string prefix = "axis_group"; + ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {100, 0., 20.}, "pT axis for photon candidates"}; + } axisGroup; + void defineEMEventCut() { fEMEventCut = EMPhotonEventCut("fEMEventCut", "fEMEventCut"); @@ -146,6 +151,10 @@ struct EmcalQC { defineEMCCut(); defineEMEventCut(); + const AxisSpec thnAxisPt{axisGroup.thnConfigAxisPt, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec thAxisdEta{200, -0.06, 0.06, "#Delta#eta"}; + const AxisSpec thAxisdPhi{200, -0.06, 0.06, "#Delta#varphi (rad)"}; + o2::aod::pwgem::photonmeson::utils::eventhistogram::addEventHistograms(&fRegistry); auto hEMCCollisionCounter = fRegistry.add("Event/hEMCCollisionCounter", "Number of collisions after event cuts", HistType::kTH1D, {{7, 0.5, 7.5}}, false); hEMCCollisionCounter->GetXaxis()->SetBinLabel(1, "all"); @@ -156,6 +165,13 @@ struct EmcalQC { hEMCCollisionCounter->GetXaxis()->SetBinLabel(6, "+unique"); // TVX with z < 10cm and Sel8 and good z xertex and unique (only collision in the BC) hEMCCollisionCounter->GetXaxis()->SetBinLabel(7, "+EMC readout"); // TVX with z < 10cm and Sel8 and good z xertex and unique (only collision in the BC) and kTVXinEMC o2::aod::pwgem::photonmeson::utils::clusterhistogram::addClusterHistograms(&fRegistry, cfgDo2DQA); + + if (doprocessQCTM) { + fRegistry.add("Cluster/hDeltaEtaPhiAllPrimTracks", "#Delta#eta #Delta#varphi distribution of all matched prim. tracks", HistType::kTH3D, {thAxisdEta, thAxisdPhi, thnAxisPt}, false); + fRegistry.add("Cluster/hDeltaEtaPhiClosestPrimTracks", "#Delta#eta #Delta#varphi distribution of the Closest matched prim. track", HistType::kTH3D, {thAxisdEta, thAxisdPhi, thnAxisPt}, false); + fRegistry.add("Cluster/hDeltaEtaPhiAllSecTracks", "#Delta#eta #Delta#varphi distribution of all matched sec. tracks", HistType::kTH3D, {thAxisdEta, thAxisdPhi, thnAxisPt}, false); + fRegistry.add("Cluster/hDeltaEtaPhiClosestSecTracks", "#Delta#eta #Delta#varphi distribution of the Closest matched sec. track", HistType::kTH3D, {thAxisdEta, thAxisdPhi, thnAxisPt}, false); + } } bool isEventGood(MyCollision const& collision) @@ -189,7 +205,7 @@ struct EmcalQC { if (!fEMEventCut.IsSelected(collision)) { return false; } - if (!(eventcuts.cfgOccupancyMin <= collision.trackOccupancyInTimeRange() && collision.trackOccupancyInTimeRange() < eventcuts.cfgOccupancyMax)) { + if (!(eventcuts.cfgOccupancyMin <= collision.trackOccupancyInTimeRange()) || !(collision.trackOccupancyInTimeRange() < eventcuts.cfgOccupancyMax)) { return false; } @@ -216,11 +232,11 @@ struct EmcalQC { // Define two boleans to see, whether the cluster "survives" the EMC cluster cuts to later check, whether the cuts in this task align with the ones in EMCPhotonCut.h: bool survivesIsSelectedEMCalCuts = true; // Survives "manual" cuts listed in this task - bool survivesIsSelectedCuts = false; + bool survivesIsSelectedCuts = true; survivesIsSelectedCuts = fEMCCut.IsSelected(cluster); for (int icut = 0; icut < static_cast(EMCPhotonCut::EMCPhotonCuts::kNCuts); icut++) { // Loop through different cut observables - EMCPhotonCut::EMCPhotonCuts specificcut = static_cast(icut); + auto specificcut = static_cast(icut); if (!fEMCCut.IsSelectedEMCal(specificcut, cluster)) { // Check whether cluster passes this cluster requirement, if not, fill why in the next row fRegistry.fill(HIST("Cluster/hClusterQualityCuts"), icut + 1, cluster.e(), collision.weight()); survivesIsSelectedEMCalCuts = false; @@ -240,12 +256,10 @@ struct EmcalQC { } } fRegistry.fill(HIST("Cluster/after/hNgamma"), ngAfter, collision.weight()); - - return; } template - void doClusterQA(MyCollision const& collision, TClusters const& clusters, TMatchedTracks const& primTracks, TMatchedSecondaries const& secTracks) + void doClusterQAWithTM(MyCollision const& collision, TClusters const& clusters, TMatchedTracks const& primTracks, TMatchedSecondaries const& secTracks) { fRegistry.fill(HIST("Cluster/before/hNgamma"), clusters.size(), collision.weight()); int ngAfter = 0; @@ -263,11 +277,11 @@ struct EmcalQC { // Define two boleans to see, whether the cluster "survives" the EMC cluster cuts to later check, whether the cuts in this task align with the ones in EMCPhotonCut.h: bool survivesIsSelectedEMCalCuts = true; // Survives "manual" cuts listed in this task - bool survivesIsSelectedCuts = false; + bool survivesIsSelectedCuts = true; survivesIsSelectedCuts = fEMCCut.IsSelected(cluster, primTracksPerCluster, secTracksPerCluster); for (int icut = 0; icut < static_cast(EMCPhotonCut::EMCPhotonCuts::kNCuts); icut++) { // Loop through different cut observables - EMCPhotonCut::EMCPhotonCuts specificcut = static_cast(icut); + auto specificcut = static_cast(icut); if (specificcut == EMCPhotonCut::EMCPhotonCuts::kTM || specificcut == EMCPhotonCut::EMCPhotonCuts::kSecondaryTM) { // will do track matching cuts extra later or never depending on chosen process function continue; @@ -277,6 +291,20 @@ struct EmcalQC { survivesIsSelectedEMCalCuts = false; } } + if (primTracksPerCluster.size() > 0) { + const auto closestPrimTrack = primTracksPerCluster.begin(); + fRegistry.fill(HIST("Cluster/hDeltaEtaPhiClosestPrimTracks"), closestPrimTrack.deltaEta(), closestPrimTrack.deltaPhi(), cluster.pt()); + } + for (const auto& matchedPrimTrack : primTracksPerCluster) { + fRegistry.fill(HIST("Cluster/hDeltaEtaPhiAllPrimTracks"), matchedPrimTrack.deltaEta(), matchedPrimTrack.deltaPhi(), cluster.pt()); + } + if (secTracksPerCluster.size() > 0) { + const auto closestSecTrack = secTracksPerCluster.begin(); + fRegistry.fill(HIST("Cluster/hDeltaEtaPhiClosestSecTracks"), closestSecTrack.deltaEta(), closestSecTrack.deltaPhi(), cluster.pt()); + } + for (const auto& matchedSecTrack : secTracksPerCluster) { + fRegistry.fill(HIST("Cluster/hDeltaEtaPhiAllSecTracks"), matchedSecTrack.deltaEta(), matchedSecTrack.deltaPhi(), cluster.pt()); + } if (!fEMCCut.IsSelectedEMCal(EMCPhotonCut::EMCPhotonCuts::kTM, cluster, primTracksPerCluster)) { // Check whether cluster passes this cluster requirement, if not, fill why in the next row fRegistry.fill(HIST("Cluster/hClusterQualityCuts"), static_cast(EMCPhotonCut::EMCPhotonCuts::kTM) + 1, cluster.e(), collision.weight()); @@ -300,8 +328,6 @@ struct EmcalQC { } } fRegistry.fill(HIST("Cluster/after/hNgamma"), ngAfter, collision.weight()); - - return; } void processQC(MyCollisions const& collisions, EMCalPhotons const& clusters) @@ -327,7 +353,7 @@ struct EmcalQC { } auto clustersPerColl = clusters.sliceBy(perCollisionEMC, collision.collisionId()); - doClusterQA(collision, clustersPerColl, matchedPrims, matchedSeconds); + doClusterQAWithTM(collision, clustersPerColl, matchedPrims, matchedSeconds); } // end of collision loop } // end of process @@ -339,7 +365,7 @@ struct EmcalQC { PROCESS_SWITCH(EmcalQC, processDummy, "Dummy function", true); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +WorkflowSpec defineDataProcessing(ConfigContext const& context) { - return WorkflowSpec{adaptAnalysisTask(cfgc)}; + return WorkflowSpec{adaptAnalysisTask(context)}; } diff --git a/PWGEM/PhotonMeson/Tasks/phosQC.cxx b/PWGEM/PhotonMeson/Tasks/phosQC.cxx index 56c7adb50b6..7dbc1684f9a 100644 --- a/PWGEM/PhotonMeson/Tasks/phosQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/phosQC.cxx @@ -30,10 +30,9 @@ #include #include -#include #include -#include +#include #include #include #include @@ -72,28 +71,31 @@ struct phosQC { THashList* list_cluster = reinterpret_cast(fMainList->FindObject("Cluster")); for (const auto& cut : fPHOSCuts) { - const char* cutname = cut.GetName(); - o2::aod::pwgem::photon::histogram::AddHistClass(list_cluster, cutname); + std::string cutname = cut.getName(); + o2::aod::pwgem::photon::histogram::AddHistClass(list_cluster, cutname.c_str()); } // for Clusters for (auto& cut : fPHOSCuts) { - std::string_view cutname = cut.GetName(); - THashList* list = reinterpret_cast(fMainList->FindObject("Cluster")->FindObject(cutname.data())); + std::string cutname = cut.getName(); + THashList* list = reinterpret_cast(fMainList->FindObject("Cluster")->FindObject(cutname.c_str())); o2::aod::pwgem::photon::histogram::DefineHistograms(list, "Cluster", "PHOS"); } } void DefineCuts() { - TString cutNamesStr = fConfigPHOSCuts.value; - if (!cutNamesStr.IsNull()) { - std::unique_ptr objArray(cutNamesStr.Tokenize(",")); - for (int icut = 0; icut < objArray->GetEntries(); ++icut) { - const char* cutname = objArray->At(icut)->GetName(); - LOGF(info, "add cut : %s", cutname); - fPHOSCuts.push_back(*phoscuts::GetCut(cutname)); - } + if (fConfigPHOSCuts.value.empty()) { + return; + } + + std::string_view namesView(fConfigPHOSCuts.value); + + for (auto name : namesView | std::views::split(',')) { + std::string cutString(name.begin(), name.end()); + const char* cutname = cutString.c_str(); + LOGF(info, "add PHOS cut : %s", cutname); + fPHOSCuts.push_back(*phoscuts::GetCut(cutname)); } LOGF(info, "Number of PHOS cuts = %d", fPHOSCuts.size()); } @@ -140,7 +142,7 @@ struct phosQC { auto clusters_per_coll = clusters.sliceBy(perCollision, collision.collisionId()); for (const auto& cut : fPHOSCuts) { - THashList* list_cluster_cut = static_cast(list_cluster->FindObject(cut.GetName())); + THashList* list_cluster_cut = static_cast(list_cluster->FindObject(cut.getName().c_str())); int ng = 0; for (auto& cluster : clusters_per_coll) { @@ -149,7 +151,7 @@ struct phosQC { ng++; } } // end of v0 loop - reinterpret_cast(fMainList->FindObject("Cluster")->FindObject(cut.GetName())->FindObject("hNgamma"))->Fill(ng); + reinterpret_cast(fMainList->FindObject("Cluster")->FindObject(cut.getName().c_str())->FindObject("hNgamma"))->Fill(ng); } // end of cut loop } // end of collision loop } // end of process diff --git a/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx b/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx index 863773c045b..aa3745d9503 100644 --- a/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx @@ -76,19 +76,19 @@ using namespace o2::aod::pwgem::photon; enum QvecEstimator { FT0M = 0, FT0A = 1, - FT0C, - TPCPos, - TPCNeg, - TPCTot, - FV0A + FT0C = 2, + TPCPos = 3, + TPCNeg = 4, + TPCTot = 5, + FV0A = 6 }; enum CentralityEstimator { None = 0, CFT0A = 1, - CFT0C, - CFT0M, - NCentralityEstimators + CFT0C = 2, + CFT0M = 3, + NCentralityEstimators = 4 }; enum Harmonics { @@ -121,7 +121,6 @@ struct TaskPi0FlowEMC { Configurable cfgEMCalMapLevelBackground{"cfgEMCalMapLevelBackground", 4, "Different levels of correction for the background, the smaller number includes the level of the higher number (4: none, 3: only inside EMCal, 2: remove edges, 1: exclude bad channels)"}; Configurable cfgEMCalMapLevelSameEvent{"cfgEMCalMapLevelSameEvent", 4, "Different levels of correction for the same event, the smaller number includes the level of the higher number (4: none, 3: only inside EMCal, 2: remove edges, 1: exclude bad channels)"}; Configurable cfgDistanceToEdge{"cfgDistanceToEdge", 1, "Distance to edge in cells required for rotated cluster to be accepted"}; - Configurable cfgDoM02{"cfgDoM02", false, "Flag to enable flow vs M02 for single photons"}; Configurable cfgDoPlaneQA{"cfgDoPlaneQA", false, "Flag to enable QA plots comparing in and out of plane"}; Configurable cfgMaxQVector{"cfgMaxQVector", 20.f, "Maximum allowed absolute QVector value."}; @@ -234,21 +233,21 @@ struct TaskPi0FlowEMC { std::string prefix = "rotationConfig"; Configurable cfgDoRotation{"cfgDoRotation", false, "Flag to enable rotation background method."}; Configurable cfgDownsampling{"cfgDownsampling", 1, "Calculate rotation background only for every collision."}; - Configurable cfgRotAngle{"cfgRotAngle", std::move(const_cast(o2::constants::math::PIHalf)), "Angle used for the rotation method."}; + Configurable cfgRotAngle{"cfgRotAngle", static_cast(o2::constants::math::PIHalf), "Angle used for the rotation method."}; Configurable cfgUseWeights{"cfgUseWeights", false, "Flag to enable weights for rotation background method."}; } rotationConfig; struct : ConfigurableGroup { std::string prefix = "correctionConfig"; Configurable cfgSpresoPath{"cfgSpresoPath", "Users/m/mhemmer/EM/Flow/Resolution", "Path to SP resolution file"}; - Configurable cfgApplySPresolution{"cfgApplySPresolution", 0, "Apply resolution correction"}; - Configurable doEMCalCalib{"doEMCalCalib", 0, "Produce output for EMCal calibration"}; + Configurable cfgApplySPresolution{"cfgApplySPresolution", false, "Apply resolution correction"}; + Configurable doEMCalCalib{"doEMCalCalib", false, "Produce output for EMCal calibration"}; Configurable cfgEnableNonLin{"cfgEnableNonLin", false, "flag to turn extra non linear energy calibration on/off"}; } correctionConfig; SliceCache cache; EventPlaneHelper epHelper; - o2::framework::Service ccdb; + o2::framework::Service ccdb{}; int runNow = 0; int runBefore = -1; @@ -270,8 +269,8 @@ struct TaskPi0FlowEMC { HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; - o2::emcal::Geometry* emcalGeom; - o2::emcal::BadChannelMap* mBadChannels; + o2::emcal::Geometry* emcalGeom = nullptr; + o2::emcal::BadChannelMap* mBadChannels = nullptr; TH1D* h1SPResolution = nullptr; // Constants for eta and phi ranges for the look up table static constexpr double EtaMin = -0.75, etaMax = 0.75; @@ -280,7 +279,7 @@ struct TaskPi0FlowEMC { static constexpr double PhiMin = 1.35, phiMax = 5.75; static constexpr int NBinsPhi = 440; // (440 bins = 0.01 step size covering most regions) - std::array lookupTable1D; + std::array lookupTable1D{}; float epsilon = 1.e-8; // static constexpr @@ -408,18 +407,21 @@ struct TaskPi0FlowEMC { const AxisSpec thnAxisMixingCent{mixingConfig.cfgCentBins, "Centrality (%)"}; const AxisSpec thnAxisMixingEP{mixingConfig.cfgEPBins, Form("cos(%d#varphi)", harmonic.value)}; - registry.add("hSparsePi0Flow", " vs m_{inv} vs p_T vs cent for same event", HistType::kTProfile3D, {thnAxisInvMass, thnAxisPt, thnAxisCent}); - registry.add("hSparsePi0", "m_{inv} vs p_T vs cent for same event", HistType::kTH3D, {thnAxisInvMass, thnAxisPt, thnAxisCent}); + if (!doprocessM02) { + registry.add("hSparsePi0Flow", " vs m_{inv} vs p_T vs cent for same event", HistType::kTProfile3D, {thnAxisInvMass, thnAxisPt, thnAxisCent}); + registry.add("hSparsePi0", "m_{inv} vs p_T vs cent for same event", HistType::kTH3D, {thnAxisInvMass, thnAxisPt, thnAxisCent}); - registry.add("hSparseBkgMixFlow", " vs m_{inv} vs p_T vs cent for mixed event", HistType::kTProfile3D, {thnAxisInvMass, thnAxisPt, thnAxisCent}); - registry.add("hSparseBkgMix", "m_{inv} vs p_T vs cent for mixed event", HistType::kTH3D, {thnAxisInvMass, thnAxisPt, thnAxisCent}); + registry.add("hSparseBkgMixFlow", " vs m_{inv} vs p_T vs cent for mixed event", HistType::kTProfile3D, {thnAxisInvMass, thnAxisPt, thnAxisCent}); + registry.add("hSparseBkgMix", "m_{inv} vs p_T vs cent for mixed event", HistType::kTH3D, {thnAxisInvMass, thnAxisPt, thnAxisCent}); + + registry.add("h3DMixingCount", "THn Event Mixing QA", HistType::kTH3D, {thnAxisMixingVtx, thnAxisMixingCent, thnAxisMixingEP}); + } if (rotationConfig.cfgDoRotation.value) { registry.add("hSparseBkgRotFlow", " vs m_{inv} vs p_T vs cent for rotation background", HistType::kTProfile3D, {thnAxisInvMass, thnAxisPt, thnAxisCent}); registry.add("hSparseBkgRot", "m_{inv} vs p_T vs cent for rotation background", HistType::kTH3D, {thnAxisInvMass, thnAxisPt, thnAxisCent}); } - registry.add("h3DMixingCount", "THn Event Mixing QA", HistType::kTH3D, {thnAxisMixingVtx, thnAxisMixingCent, thnAxisMixingEP}); if (cfgDoPlaneQA.value) { registry.add("hSparsePi0FlowPlane", "THn for SP", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisCent, thnAxisCosDeltaPhi}); } @@ -464,9 +466,9 @@ struct TaskPi0FlowEMC { registry.add("hSparseCalibBack", "THn for Calib background", HistType::kTHnSparseF, {thnAxisInvMass, thAxisEnergyCalib, thnAxisCent}); } - if (cfgDoM02.value) { - registry.add("p3DM02Flow", " vs M_{02} vs p_T vs cent", HistType::kTProfile3D, {thnAxisM02, thnAxisPt, thnAxisCent}); - registry.add("h3DSparsePi0", "M_{02} vs p_T vs cent", HistType::kTH3D, {thnAxisM02, thnAxisPt, thnAxisCent}); + if (doprocessM02) { + registry.add("hSparsePhotonFlow", " vs M_{02} vs p_T vs cent", HistType::kTProfile3D, {thnAxisM02, thnAxisPt, thnAxisCent}); + registry.add("hSparsePhoton", "M_{02} vs p_T vs cent", HistType::kTH3D, {thnAxisM02, thnAxisPt, thnAxisCent}); } ccdb->setURL(ccdbUrl); @@ -504,8 +506,8 @@ struct TaskPi0FlowEMC { template void fillThn(const float mass, const float pt, const float cent, const float sp) { - static constexpr std::string_view FlowHistTypes[3] = {"hSparsePi0Flow", "hSparseBkgRotFlow", "hSparseBkgMixFlow"}; - static constexpr std::string_view HistTypes[3] = {"hSparsePi0", "hSparseBkgRot", "hSparseBkgMix"}; + static constexpr std::array FlowHistTypes = {"hSparsePi0Flow", "hSparseBkgRotFlow", "hSparseBkgMixFlow"}; + static constexpr std::array HistTypes = {"hSparsePi0", "hSparseBkgRot", "hSparseBkgMix"}; registry.fill(HIST(FlowHistTypes[histType]), mass, pt, cent, sp); registry.fill(HIST(HistTypes[histType]), mass, pt, cent); } @@ -666,9 +668,8 @@ struct TaskPi0FlowEMC { int iRowLast = 24; if (emcalGeom->GetSMType(iSupMod) == o2::emcal::EMCALSMType::EMCAL_HALF) { iRowLast /= 2; // 2/3 sm case - } else if (emcalGeom->GetSMType(iSupMod) == o2::emcal::EMCALSMType::EMCAL_THIRD) { - iRowLast /= 3; // 1/3 sm case - } else if (emcalGeom->GetSMType(iSupMod) == o2::emcal::EMCALSMType::DCAL_EXT) { + } else if ((emcalGeom->GetSMType(iSupMod) == o2::emcal::EMCALSMType::EMCAL_THIRD) || + (emcalGeom->GetSMType(iSupMod) == o2::emcal::EMCALSMType::DCAL_EXT)) { iRowLast /= 3; // 1/3 sm case } @@ -802,7 +803,7 @@ struct TaskPi0FlowEMC { if (mesonConfig.enableTanThetadPhi.value) { float dTheta = photon1.Theta() - photon3.Theta(); float dPhi = photon1.Phi() - photon3.Phi(); - if (mesonConfig.enableTanThetadPhi.value && mesonConfig.minTanThetadPhi <= std::fabs(getAngleDegree(std::atan(dTheta / dPhi)))) { + if (mesonConfig.minTanThetadPhi <= std::fabs(getAngleDegree(std::atan(dTheta / dPhi)))) { continue; } } @@ -824,7 +825,7 @@ struct TaskPi0FlowEMC { if (mesonConfig.enableTanThetadPhi.value) { float dTheta = photon2.Theta() - photon3.Theta(); float dPhi = photon2.Phi() - photon3.Phi(); - if (mesonConfig.enableTanThetadPhi.value && mesonConfig.minTanThetadPhi <= std::fabs(getAngleDegree(std::atan(dTheta / dPhi)))) { + if (mesonConfig.minTanThetadPhi <= std::fabs(getAngleDegree(std::atan(dTheta / dPhi)))) { continue; } } @@ -834,7 +835,6 @@ struct TaskPi0FlowEMC { } // end of loop over third photon } } - return; } /// \brief Calculate background using rotation background method @@ -909,7 +909,7 @@ struct TaskPi0FlowEMC { if (mesonConfig.enableTanThetadPhi.value) { float dTheta = photonPCM.Theta() - photon3.Theta(); float dPhi = photonPCM.Phi() - photon3.Phi(); - if (mesonConfig.enableTanThetadPhi.value && mesonConfig.minTanThetadPhi <= std::fabs(getAngleDegree(std::atan(dTheta / dPhi)))) { + if (mesonConfig.minTanThetadPhi <= std::fabs(getAngleDegree(std::atan(dTheta / dPhi)))) { continue; } } @@ -941,7 +941,7 @@ struct TaskPi0FlowEMC { if (mesonConfig.enableTanThetadPhi.value) { float dTheta = photonEMC.Theta() - photon3.Theta(); float dPhi = photonEMC.Phi() - photon3.Phi(); - if (mesonConfig.enableTanThetadPhi.value && mesonConfig.minTanThetadPhi <= std::fabs(getAngleDegree(std::atan(dTheta / dPhi)))) { + if (mesonConfig.minTanThetadPhi <= std::fabs(getAngleDegree(std::atan(dTheta / dPhi)))) { continue; } } @@ -950,7 +950,6 @@ struct TaskPi0FlowEMC { } } // end of loop over PCM photons } // if(iCellIDphotonEMC > -1) - return; } /// Compute the scalar product @@ -981,7 +980,6 @@ struct TaskPi0FlowEMC { } fillThn(massCand, ptCand, cent, scalprodCand); - return; } /// \brief check if standard event cuts + FT0 occupancy + centrality + QVec good is @@ -1103,7 +1101,7 @@ struct TaskPi0FlowEMC { if (!(fEMCCut.IsSelected(photon))) { continue; } - if (cfgDistanceToEdge.value && (checkEtaPhi1D(photon.eta(), RecoDecay::constrainAngle(photon.phi())) >= cfgEMCalMapLevelSameEvent.value)) { + if (cfgDistanceToEdge.value > 0 && (checkEtaPhi1D(photon.eta(), RecoDecay::constrainAngle(photon.phi())) >= cfgEMCalMapLevelSameEvent.value)) { continue; } registry.fill(HIST("clusterQA/hEClusterAfter"), photon.corrE()); // accepted after cuts @@ -1143,7 +1141,7 @@ struct TaskPi0FlowEMC { // general event selection continue; } - if (!(eventcuts.cfgFT0COccupancyMin <= c1.ft0cOccupancyInTimeRange() && c1.ft0cOccupancyInTimeRange() < eventcuts.cfgFT0COccupancyMax) || !(eventcuts.cfgFT0COccupancyMin <= c2.ft0cOccupancyInTimeRange() && c2.ft0cOccupancyInTimeRange() < eventcuts.cfgFT0COccupancyMax)) { + if (!(eventcuts.cfgFT0COccupancyMin <= c1.ft0cOccupancyInTimeRange()) || !(c1.ft0cOccupancyInTimeRange() < eventcuts.cfgFT0COccupancyMax) || !(eventcuts.cfgFT0COccupancyMin <= c2.ft0cOccupancyInTimeRange()) || !(c2.ft0cOccupancyInTimeRange() < eventcuts.cfgFT0COccupancyMax)) { // occupancy selection continue; } @@ -1166,7 +1164,7 @@ struct TaskPi0FlowEMC { continue; } // Cut edge clusters away, similar to rotation method to ensure same acceptance is used - if (cfgDistanceToEdge.value) { + if (cfgDistanceToEdge.value > 0) { if (checkEtaPhi1D(g1.eta(), RecoDecay::constrainAngle(g1.phi())) >= cfgEMCalMapLevelBackground.value) { continue; } @@ -1257,7 +1255,7 @@ struct TaskPi0FlowEMC { } // Cut edge clusters away, similar to rotation method to ensure same acceptance is used - if (cfgDistanceToEdge.value) { + if (cfgDistanceToEdge.value > 0) { if (checkEtaPhi1D(g1.eta(), RecoDecay::constrainAngle(g1.phi())) >= cfgEMCalMapLevelSameEvent.value) { continue; } @@ -1333,7 +1331,7 @@ struct TaskPi0FlowEMC { // general event selection continue; } - if (!(eventcuts.cfgFT0COccupancyMin <= c1.ft0cOccupancyInTimeRange() && c1.ft0cOccupancyInTimeRange() < eventcuts.cfgFT0COccupancyMax) || !(eventcuts.cfgFT0COccupancyMin <= c2.ft0cOccupancyInTimeRange() && c2.ft0cOccupancyInTimeRange() < eventcuts.cfgFT0COccupancyMax)) { + if (!(eventcuts.cfgFT0COccupancyMin <= c1.ft0cOccupancyInTimeRange()) || !(c1.ft0cOccupancyInTimeRange() < eventcuts.cfgFT0COccupancyMax) || !(eventcuts.cfgFT0COccupancyMin <= c2.ft0cOccupancyInTimeRange()) || !(c2.ft0cOccupancyInTimeRange() < eventcuts.cfgFT0COccupancyMax)) { // occupancy selection continue; } @@ -1356,7 +1354,7 @@ struct TaskPi0FlowEMC { continue; } // Cut edge clusters away, similar to rotation method to ensure same acceptance is used - if (cfgDistanceToEdge.value) { + if (cfgDistanceToEdge.value > 0) { if (checkEtaPhi1D(g1.eta(), RecoDecay::constrainAngle(g1.phi())) >= cfgEMCalMapLevelBackground.value) { continue; } @@ -1409,22 +1407,8 @@ struct TaskPi0FlowEMC { fEMCCut.AreSelectedRunning(emcFlags, clusters, matchedPrims, matchedSeconds); for (const auto& collision : collisions) { - o2::aod::pwgem::photonmeson::utils::eventhistogram::fillEventInfo<0>(®istry, collision); - if (!(fEMEventCut.IsSelected(collision))) { - // general event selection - continue; - } - if (!(eventcuts.cfgFT0COccupancyMin <= collision.ft0cOccupancyInTimeRange() && collision.ft0cOccupancyInTimeRange() < eventcuts.cfgFT0COccupancyMax)) { - // occupancy selection - continue; - } float cent = getCentrality(collision); - if (cent < eventcuts.cfgMinCent || cent > eventcuts.cfgMaxCent) { - // event selection - continue; - } - if (!isQvecGood(getAllQvec(collision))) { - // selection based on QVector + if (!isFullEventSelected(collision, true)) { continue; } runNow = collision.runNumber(); @@ -1432,25 +1416,22 @@ struct TaskPi0FlowEMC { initCCDB(collision); runBefore = runNow; } - o2::aod::pwgem::photonmeson::utils::eventhistogram::fillEventInfo<1>(®istry, collision); - registry.fill(HIST("Event/before/hCollisionCounter"), 12.0); // accepted - registry.fill(HIST("Event/after/hCollisionCounter"), 12.0); // accepted auto photonsPerCollision = clusters.sliceBy(perCollisionEMC, collision.globalIndex()); for (const auto& photon : photonsPerCollision) { if (emccuts.cfgEnableQA.value) { - registry.fill(HIST("clusterQA/hEClusterBefore"), photon.e()); // before cuts + registry.fill(HIST("clusterQA/hEClusterBefore"), photon.corrE()); // before cuts registry.fill(HIST("clusterQA/hClusterEtaPhiBefore"), photon.phi(), photon.eta()); // before cuts } if (!(emcFlags.test(photon.globalIndex()))) { continue; } - if (cfgDistanceToEdge.value && (checkEtaPhi1D(photon.eta(), RecoDecay::constrainAngle(photon.phi())) >= cfgEMCalMapLevelSameEvent.value)) { + if (cfgDistanceToEdge.value > 0 && (checkEtaPhi1D(photon.eta(), RecoDecay::constrainAngle(photon.phi())) >= cfgEMCalMapLevelSameEvent.value)) { continue; } if (emccuts.cfgEnableQA.value) { - registry.fill(HIST("clusterQA/hEClusterAfter"), photon.e()); // accepted after cuts + registry.fill(HIST("clusterQA/hEClusterAfter"), photon.corrE()); // accepted after cuts registry.fill(HIST("clusterQA/hClusterEtaPhiAfter"), photon.phi(), photon.eta()); // after cuts } @@ -1465,11 +1446,8 @@ struct TaskPi0FlowEMC { if (correctionConfig.cfgApplySPresolution.value) { scalprodCand = scalprodCand / h1SPResolution->GetBinContent(h1SPResolution->FindBin(cent + epsilon)); } - if (cfgDoM02.value) { - registry.fill(HIST("p3DM02Flow"), photon.m02(), photon.pt(), cent, scalprodCand); - registry.fill(HIST("h3DSparsePi0"), photon.m02(), photon.pt(), cent); - } - continue; + registry.fill(HIST("hSparsePhotonFlow"), photon.m02(), photon.corrPt(), cent, scalprodCand); + registry.fill(HIST("hSparsePhoton"), photon.m02(), photon.corrPt(), cent); } // end of loop over single cluster } // end of loop over collisions } // processM02 @@ -1554,7 +1532,7 @@ struct TaskPi0FlowEMC { // general event selection continue; } - if (!(eventcuts.cfgFT0COccupancyMin <= c1.ft0cOccupancyInTimeRange() && c1.ft0cOccupancyInTimeRange() < eventcuts.cfgFT0COccupancyMax) || !(eventcuts.cfgFT0COccupancyMin <= c2.ft0cOccupancyInTimeRange() && c2.ft0cOccupancyInTimeRange() < eventcuts.cfgFT0COccupancyMax)) { + if (!(eventcuts.cfgFT0COccupancyMin <= c1.ft0cOccupancyInTimeRange()) || !(c1.ft0cOccupancyInTimeRange() < eventcuts.cfgFT0COccupancyMax) || !(eventcuts.cfgFT0COccupancyMin <= c2.ft0cOccupancyInTimeRange()) || !(c2.ft0cOccupancyInTimeRange() < eventcuts.cfgFT0COccupancyMax)) { // occupancy selection continue; } @@ -1604,7 +1582,7 @@ struct TaskPi0FlowEMC { }; // End struct TaskPi0FlowEMC -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +WorkflowSpec defineDataProcessing(ConfigContext const& context) { - return WorkflowSpec{adaptAnalysisTask(cfgc)}; + return WorkflowSpec{adaptAnalysisTask(context)}; } diff --git a/PWGEM/Tasks/phosNbar.cxx b/PWGEM/Tasks/phosNbar.cxx index 56447345bc0..6cf0d3d082b 100644 --- a/PWGEM/Tasks/phosNbar.cxx +++ b/PWGEM/Tasks/phosNbar.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -40,8 +41,6 @@ #include -#include - #include #include #include diff --git a/PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h b/PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h new file mode 100644 index 00000000000..ddf7bacc33d --- /dev/null +++ b/PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h @@ -0,0 +1,208 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file CandidateReconstructionTables.h +/// \brief Definitions of tables produced by candidate reconstruction workflows +/// +/// \author Gian Michele Innocenti , CERN +/// \author Vít Kučera , CERN + +#ifndef PWGHF_ALICE3_DATAMODEL_CANDIDATERECONSTRUCTIONTABLES_H_ +#define PWGHF_ALICE3_DATAMODEL_CANDIDATERECONSTRUCTIONTABLES_H_ + +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/TrackIndexSkimmingTables.h" + +#include +#include +#include + +namespace o2::aod +{ +// specific chic candidate properties +namespace hf_cand_chic +{ +DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, HfCand2Prong, "_0"); // Jpsi index +// DECLARE_SOA_INDEX_COLUMN_FULL(Prong1, prong1, int, ECALs, "_1"); +DECLARE_SOA_COLUMN(JpsiToMuMuMass, jpsiToMuMuMass, float); // Jpsi mass +} // namespace hf_cand_chic + +// declare dedicated chi_c candidate table +DECLARE_SOA_TABLE(HfCandChicBase, "AOD", "HFCANDCHICBASE", + // general columns + HFCAND_COLUMNS, + // 2-prong specific columns + hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, + hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1, + hf_cand::ImpactParameter0, hf_cand::ImpactParameter1, + hf_cand::ErrorImpactParameter0, hf_cand::ErrorImpactParameter1, + hf_cand_chic::Prong0Id, /*hf_cand_chic::Prong1Id,*/ + hf_track_index::HFflag, hf_cand_chic::JpsiToMuMuMass, + /* dynamic columns */ + hf_cand_2prong::M, + hf_cand_2prong::M2, + /* prong 2 */ + // hf_cand::PtProng1, + // hf_cand::Pt2Prong1, + // hf_cand::PVectorProng1, + /* dynamic columns that use candidate momentum components */ + hf_cand::Pt, + hf_cand::Pt2, + hf_cand::P, + hf_cand::P2, + hf_cand::PVector, + hf_cand::Cpa, + hf_cand::CpaXY, + hf_cand::Ct, + hf_cand::ImpactParameterXY, + hf_cand_2prong::MaxNormalisedDeltaIP, + hf_cand::Eta, + hf_cand::Phi, + hf_cand::Y, + hf_cand::E, + hf_cand::E2); + +// extended table with expression columns that can be used as arguments of dynamic columns +DECLARE_SOA_EXTENDED_TABLE_USER(HfCandChicExt, HfCandChicBase, "HFCANDCHICEXT", + hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz); + +using HfCandChic = HfCandChicExt; + +// table with results of reconstruction level MC matching +DECLARE_SOA_TABLE(HfCandChicMcRec, "AOD", "HFCANDCHICMCREC", //! + hf_cand_mc_flag::FlagMcMatchRec, + hf_cand_mc_flag::OriginMcRec, + hf_cand_mc_flag::FlagMcDecayChanRec); + +// table with results of generator level MC matching +DECLARE_SOA_TABLE(HfCandChicMcGen, "AOD", "HFCANDCHICMCGEN", //! + hf_cand_mc_flag::FlagMcMatchGen, + hf_cand_mc_flag::OriginMcGen, + hf_cand_mc_flag::FlagMcDecayChanGen); + +namespace hf_cand_x +{ +DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, HfCand2Prong, "_0"); // Jpsi index +} // namespace hf_cand_x + +// declare dedicated X candidate table +DECLARE_SOA_TABLE(HfCandXBase, "AOD", "HFCANDXBASE", + // general columns + HFCAND_COLUMNS, + // 3-prong specific columns + hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, + hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1, + hf_cand::PxProng2, hf_cand::PyProng2, hf_cand::PzProng2, + hf_cand::ImpactParameter0, hf_cand::ImpactParameter1, hf_cand::ImpactParameter2, + hf_cand::ErrorImpactParameter0, hf_cand::ErrorImpactParameter1, hf_cand::ErrorImpactParameter2, + hf_cand_x::Prong0Id, hf_track_index::Prong1Id, hf_track_index::Prong2Id, // note the difference between Jpsi and pion indices + hf_track_index::HFflag, + /* dynamic columns */ + hf_cand_3prong::M, + hf_cand_3prong::M2, + /* prong 2 */ + hf_cand::PtProng2, + hf_cand::Pt2Prong2, + hf_cand::PVectorProng2, + /* dynamic columns that use candidate momentum components */ + hf_cand::Pt, + hf_cand::Pt2, + hf_cand::P, + hf_cand::P2, + hf_cand::PVector, + hf_cand::Cpa, + hf_cand::CpaXY, + hf_cand::Ct, + hf_cand::ImpactParameterXY, + hf_cand_3prong::MaxNormalisedDeltaIP, + hf_cand::Eta, + hf_cand::Phi, + hf_cand::Y, + hf_cand::E, + hf_cand::E2); + +// extended table with expression columns that can be used as arguments of dynamic columns +DECLARE_SOA_EXTENDED_TABLE_USER(HfCandXExt, HfCandXBase, "HFCANDXEXT", + hf_cand_3prong::Px, hf_cand_3prong::Py, hf_cand_3prong::Pz); + +using HfCandX = HfCandXExt; + +// table with results of reconstruction level MC matching +DECLARE_SOA_TABLE(HfCandXMcRec, "AOD", "HFCANDXMCREC", //! + hf_cand_mc_flag::FlagMcMatchRec, + hf_cand_mc_flag::OriginMcRec, + hf_cand_mc_flag::FlagMcDecayChanRec); + +// table with results of generator level MC matching +DECLARE_SOA_TABLE(HfCandXMcGen, "AOD", "HFCANDXMCGEN", //! + hf_cand_mc_flag::FlagMcMatchGen, + hf_cand_mc_flag::OriginMcGen, + hf_cand_mc_flag::FlagMcDecayChanGen); + +// specific Xicc candidate properties +namespace hf_cand_xicc +{ +DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, HfCand3Prong, "_0"); // Xic index +} // namespace hf_cand_xicc + +// declare dedicated Xicc candidate table +DECLARE_SOA_TABLE(HfCandXiccBase, "AOD", "HFCANDXICCBASE", + // general columns + HFCAND_COLUMNS, + // 2-prong specific columns + hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, + hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1, + hf_cand::ImpactParameter0, hf_cand::ImpactParameter1, + hf_cand::ErrorImpactParameter0, hf_cand::ErrorImpactParameter1, + hf_cand_xicc::Prong0Id, hf_track_index::Prong1Id, + hf_track_index::HFflag, + /* dynamic columns */ + hf_cand_2prong::M, + hf_cand_2prong::M2, + hf_cand_2prong::ImpactParameterProduct, + /* dynamic columns that use candidate momentum components */ + hf_cand::Pt, + hf_cand::Pt2, + hf_cand::P, + hf_cand::P2, + hf_cand::PVector, + hf_cand::Cpa, + hf_cand::CpaXY, + hf_cand::Ct, + hf_cand::ImpactParameterXY, + hf_cand_2prong::MaxNormalisedDeltaIP, + hf_cand::Eta, + hf_cand::Phi, + hf_cand::Y, + hf_cand::E, + hf_cand::E2); + +// extended table with expression columns that can be used as arguments of dynamic columns +DECLARE_SOA_EXTENDED_TABLE_USER(HfCandXiccExt, HfCandXiccBase, "HFCANDXICCEXT", + hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz); + +using HfCandXicc = HfCandXiccExt; + +// table with results of reconstruction level MC matching +DECLARE_SOA_TABLE(HfCandXiccMcRec, "AOD", "HFCANDXICCMCREC", //! + hf_cand_mc_flag::FlagMcMatchRec, + hf_cand_mc_flag::OriginMcRec, + hf_cand_mc_flag::DebugMcRec); + +// table with results of generator level MC matching +DECLARE_SOA_TABLE(HfCandXiccMcGen, "AOD", "HFCANDXICCMCGEN", //! + hf_cand_mc_flag::FlagMcMatchGen, + hf_cand_mc_flag::OriginMcGen); + +} // namespace o2::aod + +#endif // PWGHF_ALICE3_DATAMODEL_CANDIDATERECONSTRUCTIONTABLES_H_ diff --git a/PWGHF/ALICE3/DataModel/CandidateSelectionTables.h b/PWGHF/ALICE3/DataModel/CandidateSelectionTables.h new file mode 100644 index 00000000000..f2d45eb55ad --- /dev/null +++ b/PWGHF/ALICE3/DataModel/CandidateSelectionTables.h @@ -0,0 +1,166 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file CandidateSelectionTables.h +/// \brief Definitions of tables produced by candidate selectors +/// +/// \author Nima Zardoshti , CERN + +#ifndef PWGHF_ALICE3_DATAMODEL_CANDIDATESELECTIONTABLES_H_ +#define PWGHF_ALICE3_DATAMODEL_CANDIDATESELECTIONTABLES_H_ + +#include + +namespace o2::aod +{ +namespace hf_sel_candidate_d0_parametrized_pid +{ +DECLARE_SOA_COLUMN(IsSelD0NoPid, isSelD0NoPid, int); //! +DECLARE_SOA_COLUMN(IsSelD0PerfectPid, isSelD0PerfectPid, int); //! +DECLARE_SOA_COLUMN(IsSelD0, isSelD0, int); //! +DECLARE_SOA_COLUMN(IsSelD0barNoPid, isSelD0barNoPid, int); //! +DECLARE_SOA_COLUMN(IsSelD0barPerfectPid, isSelD0barPerfectPid, int); //! +DECLARE_SOA_COLUMN(IsSelD0bar, isSelD0bar, int); //! +} // namespace hf_sel_candidate_d0_parametrized_pid + +DECLARE_SOA_TABLE(HfSelD0ParametrizedPid, "AOD", "HFSELD0P", //! + hf_sel_candidate_d0_parametrized_pid::IsSelD0NoPid, + hf_sel_candidate_d0_parametrized_pid::IsSelD0PerfectPid, + hf_sel_candidate_d0_parametrized_pid::IsSelD0, + hf_sel_candidate_d0_parametrized_pid::IsSelD0barNoPid, + hf_sel_candidate_d0_parametrized_pid::IsSelD0barPerfectPid, + hf_sel_candidate_d0_parametrized_pid::IsSelD0bar); + +namespace hf_sel_candidate_d0_alice3_barrel +{ +DECLARE_SOA_COLUMN(IsSelHfFlag, isSelHfFlag, int); //! +DECLARE_SOA_COLUMN(IsSelD0NoPid, isSelD0NoPid, int); //! +DECLARE_SOA_COLUMN(IsSelD0PerfectPid, isSelD0PerfectPid, int); //! +DECLARE_SOA_COLUMN(IsSelD0TofPid, isSelD0TofPid, int); //! +DECLARE_SOA_COLUMN(IsSelD0RichPid, isSelD0RichPid, int); //! +DECLARE_SOA_COLUMN(IsSelD0TofPlusRichPid, isSelD0TofPlusRichPid, int); //! +DECLARE_SOA_COLUMN(IsSelD0barTofPlusRichPid, isSelD0barTofPlusRichPid, int); //! +} // namespace hf_sel_candidate_d0_alice3_barrel + +DECLARE_SOA_TABLE(HfSelD0Alice3Barrel, "AOD", "HFSELD0A3B", //! + hf_sel_candidate_d0_alice3_barrel::IsSelHfFlag, + hf_sel_candidate_d0_alice3_barrel::IsSelD0NoPid, + hf_sel_candidate_d0_alice3_barrel::IsSelD0PerfectPid, + hf_sel_candidate_d0_alice3_barrel::IsSelD0TofPid, + hf_sel_candidate_d0_alice3_barrel::IsSelD0RichPid, + hf_sel_candidate_d0_alice3_barrel::IsSelD0TofPlusRichPid, + hf_sel_candidate_d0_alice3_barrel::IsSelD0barTofPlusRichPid); + +namespace hf_sel_candidate_d0_alice3_forward +{ +DECLARE_SOA_COLUMN(IsSelHfFlag, isSelHfFlag, int); //! +DECLARE_SOA_COLUMN(IsSelD0FNoPid, isSelD0FNoPid, int); //! +DECLARE_SOA_COLUMN(IsSelD0FRichPid, isSelD0FRichPid, int); //! +} // namespace hf_sel_candidate_d0_alice3_forward + +DECLARE_SOA_TABLE(HfSelD0Alice3Forward, "AOD", "HFSELD0A3F", //! + hf_sel_candidate_d0_alice3_forward::IsSelHfFlag, + hf_sel_candidate_d0_alice3_forward::IsSelD0FNoPid, + hf_sel_candidate_d0_alice3_forward::IsSelD0FRichPid); + +namespace hf_sel_candidate_lc_alice3 +{ +DECLARE_SOA_COLUMN(IsSelLcToPKPiNoPid, isSelLcToPKPiNoPid, int); //! +DECLARE_SOA_COLUMN(IsSelLcToPKPiPerfectPid, isSelLcToPKPiPerfectPid, int); //! +DECLARE_SOA_COLUMN(IsSelLcToPKPiTofPid, isSelLcToPKPiTofPid, int); //! +DECLARE_SOA_COLUMN(IsSelLcToPKPiTofPlusRichPid, isSelLcToPKPiTofPlusRichPid, int); //! +DECLARE_SOA_COLUMN(IsSelLcToPiKPNoPid, isSelLcToPiKPNoPid, int); //! +DECLARE_SOA_COLUMN(IsSelLcToPiKPPerfectPid, isSelLcToPiKPPerfectPid, int); //! +DECLARE_SOA_COLUMN(IsSelLcToPiKPTofPid, isSelLcToPiKPTofPid, int); //! +DECLARE_SOA_COLUMN(IsSelLcToPiKPTofPlusRichPid, isSelLcToPiKPTofPlusRichPid, int); //! +} // namespace hf_sel_candidate_lc_alice3 + +DECLARE_SOA_TABLE(HfSelLcAlice3, "AOD", "HFSELLCA3B", //! + hf_sel_candidate_lc_alice3::IsSelLcToPKPiNoPid, + hf_sel_candidate_lc_alice3::IsSelLcToPKPiPerfectPid, + hf_sel_candidate_lc_alice3::IsSelLcToPKPiTofPid, + hf_sel_candidate_lc_alice3::IsSelLcToPKPiTofPlusRichPid, + hf_sel_candidate_lc_alice3::IsSelLcToPiKPNoPid, + hf_sel_candidate_lc_alice3::IsSelLcToPiKPPerfectPid, + hf_sel_candidate_lc_alice3::IsSelLcToPiKPTofPid, + hf_sel_candidate_lc_alice3::IsSelLcToPiKPTofPlusRichPid); + +namespace hf_sel_candidate_lc_parametrized_pid +{ +DECLARE_SOA_COLUMN(IsSelLcToPKPiNoPid, isSelLcToPKPiNoPid, int); //! +DECLARE_SOA_COLUMN(IsSelLcToPKPiPerfectPid, isSelLcToPKPiPerfectPid, int); //! +DECLARE_SOA_COLUMN(IsSelLcToPKPi, isSelLcToPKPi, int); //! +DECLARE_SOA_COLUMN(IsSelLcToPiKPNoPid, isSelLcToPiKPNoPid, int); //! +DECLARE_SOA_COLUMN(IsSelLcToPiKPPerfectPid, isSelLcToPiKPPerfectPid, int); //! +DECLARE_SOA_COLUMN(IsSelLcToPiKP, isSelLcToPiKP, int); //! +} // namespace hf_sel_candidate_lc_parametrized_pid + +DECLARE_SOA_TABLE(HfSelLcParametrizedPid, "AOD", "HFSELLCP", //! + hf_sel_candidate_lc_parametrized_pid::IsSelLcToPKPiNoPid, + hf_sel_candidate_lc_parametrized_pid::IsSelLcToPKPiPerfectPid, + hf_sel_candidate_lc_parametrized_pid::IsSelLcToPKPi, + hf_sel_candidate_lc_parametrized_pid::IsSelLcToPiKPNoPid, + hf_sel_candidate_lc_parametrized_pid::IsSelLcToPiKPPerfectPid, + hf_sel_candidate_lc_parametrized_pid::IsSelLcToPiKP); + +namespace hf_sel_candidate_jpsi +{ +DECLARE_SOA_COLUMN(IsSelJpsiToEE, isSelJpsiToEE, int); //! +DECLARE_SOA_COLUMN(IsSelJpsiToMuMu, isSelJpsiToMuMu, int); //! +DECLARE_SOA_COLUMN(IsSelJpsiToEETopol, isSelJpsiToEETopol, int); //! +DECLARE_SOA_COLUMN(IsSelJpsiToEETpc, isSelJpsiToEETpc, int); //! +DECLARE_SOA_COLUMN(IsSelJpsiToEETof, isSelJpsiToEETof, int); //! +DECLARE_SOA_COLUMN(IsSelJpsiToEERich, isSelJpsiToEERich, int); //! +DECLARE_SOA_COLUMN(IsSelJpsiToEETofRich, isSelJpsiToEETofRich, int); //! +DECLARE_SOA_COLUMN(IsSelJpsiToMuMuTopol, isSelJpsiToMuMuTopol, int); //! +DECLARE_SOA_COLUMN(IsSelJpsiToMuMuMid, isSelJpsiToMuMuMid, int); //! +} // namespace hf_sel_candidate_jpsi + +DECLARE_SOA_TABLE(HfSelJpsi, "AOD", "HFSELJPSI", //! + hf_sel_candidate_jpsi::IsSelJpsiToEE, + hf_sel_candidate_jpsi::IsSelJpsiToMuMu, + hf_sel_candidate_jpsi::IsSelJpsiToEETopol, + hf_sel_candidate_jpsi::IsSelJpsiToEETpc, + hf_sel_candidate_jpsi::IsSelJpsiToEETof, + hf_sel_candidate_jpsi::IsSelJpsiToEERich, + hf_sel_candidate_jpsi::IsSelJpsiToEETofRich, + hf_sel_candidate_jpsi::IsSelJpsiToMuMuTopol, + hf_sel_candidate_jpsi::IsSelJpsiToMuMuMid); + +namespace hf_sel_candidate_x +{ +DECLARE_SOA_COLUMN(IsSelXToJpsiToEEPiPi, isSelXToJpsiToEEPiPi, int); //! +DECLARE_SOA_COLUMN(IsSelXToJpsiToMuMuPiPi, isSelXToJpsiToMuMuPiPi, int); //! +} // namespace hf_sel_candidate_x + +DECLARE_SOA_TABLE(HfSelXToJpsiPiPi, "AOD", "HFSELX", //! + hf_sel_candidate_x::IsSelXToJpsiToEEPiPi, hf_sel_candidate_x::IsSelXToJpsiToMuMuPiPi); + +namespace hf_sel_candidate_chic +{ +DECLARE_SOA_COLUMN(IsSelChicToJpsiToEEGamma, isSelChicToJpsiToEEGamma, int); //! +DECLARE_SOA_COLUMN(IsSelChicToJpsiToMuMuGamma, isSelChicToJpsiToMuMuGamma, int); //! +} // namespace hf_sel_candidate_chic + +DECLARE_SOA_TABLE(HfSelChicToJpsiGamma, "AOD", "HFSELCHIC", //! + hf_sel_candidate_chic::IsSelChicToJpsiToEEGamma, hf_sel_candidate_chic::IsSelChicToJpsiToMuMuGamma); + +namespace hf_sel_candidate_xicc +{ +DECLARE_SOA_COLUMN(IsSelXiccToPKPiPi, isSelXiccToPKPiPi, int); //! +} // namespace hf_sel_candidate_xicc + +DECLARE_SOA_TABLE(HfSelXiccToPKPiPi, "AOD", "HFSELXICC", //! + hf_sel_candidate_xicc::IsSelXiccToPKPiPi); + +} // namespace o2::aod + +#endif // PWGHF_ALICE3_DATAMODEL_CANDIDATESELECTIONTABLES_H_ diff --git a/PWGHF/ALICE3/TableProducer/candidateCreatorChic.cxx b/PWGHF/ALICE3/TableProducer/candidateCreatorChic.cxx index b03c9bf6952..ee9d90c178f 100644 --- a/PWGHF/ALICE3/TableProducer/candidateCreatorChic.cxx +++ b/PWGHF/ALICE3/TableProducer/candidateCreatorChic.cxx @@ -15,11 +15,13 @@ /// /// \author Alessandro De Falco , Cagliari University +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "ALICE3/DataModel/ECAL.h" #include "Common/Core/trackUtilities.h" #include diff --git a/PWGHF/ALICE3/TableProducer/candidateCreatorX.cxx b/PWGHF/ALICE3/TableProducer/candidateCreatorX.cxx index f0dfb8d761c..daf0e2fe7b2 100644 --- a/PWGHF/ALICE3/TableProducer/candidateCreatorX.cxx +++ b/PWGHF/ALICE3/TableProducer/candidateCreatorX.cxx @@ -16,6 +16,8 @@ /// \author Rik Spijkers , Utrecht University /// \author Luca Micheletti , INFN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/TableProducer/candidateCreatorXicc.cxx b/PWGHF/ALICE3/TableProducer/candidateCreatorXicc.cxx index a605acdc7fc..2d30f704d67 100644 --- a/PWGHF/ALICE3/TableProducer/candidateCreatorXicc.cxx +++ b/PWGHF/ALICE3/TableProducer/candidateCreatorXicc.cxx @@ -18,6 +18,8 @@ /// \author Mattia Faggin , University and INFN PADOVA #include "PWGHF/ALICE3/Core/DecayChannelsLegacy.h" +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" diff --git a/PWGHF/ALICE3/TableProducer/candidateSelectorChicToJpsiGamma.cxx b/PWGHF/ALICE3/TableProducer/candidateSelectorChicToJpsiGamma.cxx index 0c4b37e21c4..2096b646f17 100644 --- a/PWGHF/ALICE3/TableProducer/candidateSelectorChicToJpsiGamma.cxx +++ b/PWGHF/ALICE3/TableProducer/candidateSelectorChicToJpsiGamma.cxx @@ -15,6 +15,8 @@ /// /// \author Alessandro De Falco , Università/INFN Cagliari +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" diff --git a/PWGHF/ALICE3/TableProducer/candidateSelectorD0Alice3Barrel.cxx b/PWGHF/ALICE3/TableProducer/candidateSelectorD0Alice3Barrel.cxx index 5fb93e341f5..6a49ab90852 100644 --- a/PWGHF/ALICE3/TableProducer/candidateSelectorD0Alice3Barrel.cxx +++ b/PWGHF/ALICE3/TableProducer/candidateSelectorD0Alice3Barrel.cxx @@ -15,6 +15,8 @@ /// \author Nima Zardoshti , CERN /// \author Vít Kučera , CERN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/TableProducer/candidateSelectorD0Alice3Forward.cxx b/PWGHF/ALICE3/TableProducer/candidateSelectorD0Alice3Forward.cxx index ab2e05c16e8..e9f2645ce0d 100644 --- a/PWGHF/ALICE3/TableProducer/candidateSelectorD0Alice3Forward.cxx +++ b/PWGHF/ALICE3/TableProducer/candidateSelectorD0Alice3Forward.cxx @@ -15,6 +15,8 @@ /// \author Nima Zardoshti , CERN /// \author Vít Kučera , CERN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/TableProducer/candidateSelectorD0ParametrizedPid.cxx b/PWGHF/ALICE3/TableProducer/candidateSelectorD0ParametrizedPid.cxx index 474d0eda059..31216646ba3 100644 --- a/PWGHF/ALICE3/TableProducer/candidateSelectorD0ParametrizedPid.cxx +++ b/PWGHF/ALICE3/TableProducer/candidateSelectorD0ParametrizedPid.cxx @@ -15,6 +15,8 @@ /// \author Nima Zardoshti , CERN /// \author Vít Kučera , CERN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/TableProducer/candidateSelectorJpsi.cxx b/PWGHF/ALICE3/TableProducer/candidateSelectorJpsi.cxx index 40f8aee3e01..9b2db0530af 100644 --- a/PWGHF/ALICE3/TableProducer/candidateSelectorJpsi.cxx +++ b/PWGHF/ALICE3/TableProducer/candidateSelectorJpsi.cxx @@ -16,6 +16,8 @@ /// \author Nima Zardoshti , CERN /// \author Vít Kučera , CERN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/TableProducer/candidateSelectorLcAlice3.cxx b/PWGHF/ALICE3/TableProducer/candidateSelectorLcAlice3.cxx index 1844f315f28..904daf44b45 100644 --- a/PWGHF/ALICE3/TableProducer/candidateSelectorLcAlice3.cxx +++ b/PWGHF/ALICE3/TableProducer/candidateSelectorLcAlice3.cxx @@ -16,6 +16,8 @@ /// \author Nima Zardoshti , CERN /// \author Vít Kučera , CERN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/TableProducer/candidateSelectorLcParametrizedPid.cxx b/PWGHF/ALICE3/TableProducer/candidateSelectorLcParametrizedPid.cxx index 5fbde221894..c494536e169 100644 --- a/PWGHF/ALICE3/TableProducer/candidateSelectorLcParametrizedPid.cxx +++ b/PWGHF/ALICE3/TableProducer/candidateSelectorLcParametrizedPid.cxx @@ -16,6 +16,8 @@ /// \author Nima Zardoshti , CERN /// \author Vít Kučera , CERN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/TableProducer/candidateSelectorXToJpsiPiPi.cxx b/PWGHF/ALICE3/TableProducer/candidateSelectorXToJpsiPiPi.cxx index 69ef001ab57..d24b5d80bde 100644 --- a/PWGHF/ALICE3/TableProducer/candidateSelectorXToJpsiPiPi.cxx +++ b/PWGHF/ALICE3/TableProducer/candidateSelectorXToJpsiPiPi.cxx @@ -16,6 +16,8 @@ /// \author Rik Spijkers , Utrecht University /// \author Luca Micheletti , INFN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" diff --git a/PWGHF/ALICE3/TableProducer/candidateSelectorXiccToPKPiPi.cxx b/PWGHF/ALICE3/TableProducer/candidateSelectorXiccToPKPiPi.cxx index 12a5bc3477f..0754aa27539 100644 --- a/PWGHF/ALICE3/TableProducer/candidateSelectorXiccToPKPiPi.cxx +++ b/PWGHF/ALICE3/TableProducer/candidateSelectorXiccToPKPiPi.cxx @@ -15,6 +15,8 @@ /// \author Gian Michele Innocenti , CERN #include "PWGHF/ALICE3/Core/DecayChannelsLegacy.h" +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/AliasTables.h" diff --git a/PWGHF/ALICE3/TableProducer/treeCreatorChicToJpsiGamma.cxx b/PWGHF/ALICE3/TableProducer/treeCreatorChicToJpsiGamma.cxx index 589d889fdcb..a7d6dca0f42 100644 --- a/PWGHF/ALICE3/TableProducer/treeCreatorChicToJpsiGamma.cxx +++ b/PWGHF/ALICE3/TableProducer/treeCreatorChicToJpsiGamma.cxx @@ -18,6 +18,8 @@ /// \author Alessandro De Falco , Università/INFN Cagliari /// \author Luca Micheletti , INFN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/TableProducer/treeCreatorXToJpsiPiPi.cxx b/PWGHF/ALICE3/TableProducer/treeCreatorXToJpsiPiPi.cxx index 2a9c9c49faf..a92171bb28c 100644 --- a/PWGHF/ALICE3/TableProducer/treeCreatorXToJpsiPiPi.cxx +++ b/PWGHF/ALICE3/TableProducer/treeCreatorXToJpsiPiPi.cxx @@ -17,6 +17,8 @@ /// /// \author Luca Micheletti , INFN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/TableProducer/treeCreatorXiccToPKPiPi.cxx b/PWGHF/ALICE3/TableProducer/treeCreatorXiccToPKPiPi.cxx index 305ec024513..582967fffe4 100644 --- a/PWGHF/ALICE3/TableProducer/treeCreatorXiccToPKPiPi.cxx +++ b/PWGHF/ALICE3/TableProducer/treeCreatorXiccToPKPiPi.cxx @@ -18,6 +18,8 @@ /// \author Jinjoo Seo , Inha University #include "PWGHF/ALICE3/Core/DecayChannelsLegacy.h" +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/Tasks/taskChic.cxx b/PWGHF/ALICE3/Tasks/taskChic.cxx index f6ed3fbabe0..84e749c0dc8 100644 --- a/PWGHF/ALICE3/Tasks/taskChic.cxx +++ b/PWGHF/ALICE3/Tasks/taskChic.cxx @@ -15,6 +15,8 @@ /// \author Gian Michele Innocenti , CERN /// \author Alessandro De Falco , Cagliari University +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" diff --git a/PWGHF/ALICE3/Tasks/taskD0Alice3Barrel.cxx b/PWGHF/ALICE3/Tasks/taskD0Alice3Barrel.cxx index a6a79fa2e23..1aa6989dec6 100644 --- a/PWGHF/ALICE3/Tasks/taskD0Alice3Barrel.cxx +++ b/PWGHF/ALICE3/Tasks/taskD0Alice3Barrel.cxx @@ -15,6 +15,8 @@ /// \author Gian Michele Innocenti , CERN /// \author Vít Kučera , CERN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/Tasks/taskD0Alice3Forward.cxx b/PWGHF/ALICE3/Tasks/taskD0Alice3Forward.cxx index ac528208830..8064b70756f 100644 --- a/PWGHF/ALICE3/Tasks/taskD0Alice3Forward.cxx +++ b/PWGHF/ALICE3/Tasks/taskD0Alice3Forward.cxx @@ -15,6 +15,8 @@ /// \author Gian Michele Innocenti , CERN /// \author Vít Kučera , CERN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/Tasks/taskD0ParametrizedPid.cxx b/PWGHF/ALICE3/Tasks/taskD0ParametrizedPid.cxx index 23d160348d8..5132bfc55e2 100644 --- a/PWGHF/ALICE3/Tasks/taskD0ParametrizedPid.cxx +++ b/PWGHF/ALICE3/Tasks/taskD0ParametrizedPid.cxx @@ -15,6 +15,8 @@ /// \author Gian Michele Innocenti , CERN /// \author Vít Kučera , CERN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/Tasks/taskJpsi.cxx b/PWGHF/ALICE3/Tasks/taskJpsi.cxx index 9390751b7ee..ea5c2abf616 100644 --- a/PWGHF/ALICE3/Tasks/taskJpsi.cxx +++ b/PWGHF/ALICE3/Tasks/taskJpsi.cxx @@ -16,6 +16,8 @@ /// \author Vít Kučera , CERN /// \author Biao Zhang , CCNU +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/Tasks/taskLcAlice3.cxx b/PWGHF/ALICE3/Tasks/taskLcAlice3.cxx index 703ba304092..c39455ca5d8 100644 --- a/PWGHF/ALICE3/Tasks/taskLcAlice3.cxx +++ b/PWGHF/ALICE3/Tasks/taskLcAlice3.cxx @@ -15,6 +15,8 @@ /// \author Gian Michele Innocenti , CERN /// \author Vít Kučera , CERN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/Tasks/taskLcParametrizedPid.cxx b/PWGHF/ALICE3/Tasks/taskLcParametrizedPid.cxx index ff8e2aad4a4..21e97ad4355 100644 --- a/PWGHF/ALICE3/Tasks/taskLcParametrizedPid.cxx +++ b/PWGHF/ALICE3/Tasks/taskLcParametrizedPid.cxx @@ -15,6 +15,8 @@ /// \author Gian Michele Innocenti , CERN /// \author Vít Kučera , CERN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" diff --git a/PWGHF/ALICE3/Tasks/taskX.cxx b/PWGHF/ALICE3/Tasks/taskX.cxx index 2391634f8ce..3cde2020102 100644 --- a/PWGHF/ALICE3/Tasks/taskX.cxx +++ b/PWGHF/ALICE3/Tasks/taskX.cxx @@ -16,6 +16,8 @@ /// \author Rik Spijkers , Utrecht University /// \author Luca Micheletti , INFN +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" diff --git a/PWGHF/ALICE3/Tasks/taskXicc.cxx b/PWGHF/ALICE3/Tasks/taskXicc.cxx index f75ca850c81..3a00bc928bd 100644 --- a/PWGHF/ALICE3/Tasks/taskXicc.cxx +++ b/PWGHF/ALICE3/Tasks/taskXicc.cxx @@ -17,6 +17,8 @@ /// \author Jinjoo Seo , Inha University #include "PWGHF/ALICE3/Core/DecayChannelsLegacy.h" +#include "PWGHF/ALICE3/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/AliasTables.h" diff --git a/PWGHF/Core/DecayChannels.h b/PWGHF/Core/DecayChannels.h index 929079b9b9f..7e685493a1f 100644 --- a/PWGHF/Core/DecayChannels.h +++ b/PWGHF/Core/DecayChannels.h @@ -92,8 +92,10 @@ enum DecayChannelMain : HfDecayChannel { XicToPKPi = 21, // p K− π+ XicToPKK = 22, // p K− K+ XicToSPiPi = 23, // Σ+ π− π+ + // cd+ + CDeuteronToDeKPi = 24, // de K− π+ // - NChannelsMain = XicToSPiPi // last channel + NChannelsMain = CDeuteronToDeKPi // last channel }; /// @brief 3-prong candidates: resonant channels enum DecayChannelResonant : HfDecayChannel { @@ -131,8 +133,11 @@ enum DecayChannelResonant : HfDecayChannel { // Ξc+ XicToPKstar0 = 27, // p anti-K*0(892) XicToPPhi = 28, // p φ - // - NChannelsResonant = XicToPPhi // last channel + // cd+ + CDeuteronToDeKstar0 = 30, + CDeuteronToNeDeltaplusK = 31, + CDeuteronToNeL1520Pi = 32, + NChannelsResonant = CDeuteronToNeL1520Pi // last channel }; } // namespace hf_cand_3prong diff --git a/PWGHF/Core/HfHelper.h b/PWGHF/Core/HfHelper.h index de1b537b3bf..e91bfa85ca8 100644 --- a/PWGHF/Core/HfHelper.h +++ b/PWGHF/Core/HfHelper.h @@ -660,6 +660,38 @@ struct HfHelper { return candidate.m(std::array{o2::constants::physics::MassD0, o2::constants::physics::MassPiPlus, o2::constants::physics::MassPiPlus}); } + template + static auto invMassB0ToJpsiK0Star(const T& candidate, const bool useJpsiPdgMass, const bool useK0StarPdgMass, bool k0StarToKPi = true) + { + auto const pVecMuPos = candidate.pVectorProng0(); + auto const pVecMuNeg = candidate.pVectorProng1(); + auto const pVecLfTrack0 = candidate.pVectorProng2(); + auto const pVecLfTrack1 = candidate.pVectorProng3(); + if (useJpsiPdgMass && useK0StarPdgMass) { + return RecoDecay::m(std::array{RecoDecay::pVec(pVecMuPos, pVecMuNeg), RecoDecay::pVec(pVecLfTrack0, pVecLfTrack1)}, + std::array{o2::constants::physics::MassJPsi, o2::constants::physics::MassK0Star892}); + } + if (useJpsiPdgMass && !useK0StarPdgMass) { + if (k0StarToKPi) { + return RecoDecay::m(std::array{RecoDecay::pVec(pVecMuPos, pVecMuNeg), pVecLfTrack0, pVecLfTrack1}, + std::array{o2::constants::physics::MassJPsi, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); + } + return RecoDecay::m(std::array{RecoDecay::pVec(pVecMuPos, pVecMuNeg), pVecLfTrack0, pVecLfTrack1}, + std::array{o2::constants::physics::MassJPsi, o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus}); + } + if (!useJpsiPdgMass && useK0StarPdgMass) { + return RecoDecay::m(std::array{pVecMuPos, pVecMuNeg, RecoDecay::pVec(pVecLfTrack0, pVecLfTrack1)}, + std::array{o2::constants::physics::MassMuon, o2::constants::physics::MassMuon, o2::constants::physics::MassK0Star892}); + } + // Do not use PDG mass for either J/psi or K*0 + if (k0StarToKPi) { + return RecoDecay::m(std::array{pVecMuPos, pVecMuNeg, pVecLfTrack0, pVecLfTrack1}, + std::array{o2::constants::physics::MassMuon, o2::constants::physics::MassMuon, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); + } + return RecoDecay::m(std::array{pVecMuPos, pVecMuNeg, pVecLfTrack0, pVecLfTrack1}, + std::array{o2::constants::physics::MassMuon, o2::constants::physics::MassMuon, o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus}); + } + template static auto cosThetaStarB0(const T& candidate) { @@ -697,22 +729,22 @@ struct HfHelper { { auto const pVecMuPos = candidate.pVectorProng0(); auto const pVecMuNeg = candidate.pVectorProng1(); - auto const pVecKaPos = candidate.pVectorProng2(); - auto const pVecKaNeg = candidate.pVectorProng3(); + auto const pVecKa0 = candidate.pVectorProng2(); + auto const pVecKa1 = candidate.pVectorProng3(); if (useJpsiPdgMass && usePhiPdgMass) { - return RecoDecay::m(std::array{RecoDecay::pVec(pVecMuPos, pVecMuNeg), RecoDecay::pVec(pVecKaPos, pVecKaNeg)}, + return RecoDecay::m(std::array{RecoDecay::pVec(pVecMuPos, pVecMuNeg), RecoDecay::pVec(pVecKa0, pVecKa1)}, std::array{o2::constants::physics::MassJPsi, o2::constants::physics::MassPhi}); } if (useJpsiPdgMass && !usePhiPdgMass) { - return RecoDecay::m(std::array{RecoDecay::pVec(pVecMuPos, pVecMuNeg), pVecKaPos, pVecKaNeg}, + return RecoDecay::m(std::array{RecoDecay::pVec(pVecMuPos, pVecMuNeg), pVecKa0, pVecKa1}, std::array{o2::constants::physics::MassJPsi, o2::constants::physics::MassKPlus, o2::constants::physics::MassKPlus}); } if (!useJpsiPdgMass && usePhiPdgMass) { - return RecoDecay::m(std::array{pVecMuPos, pVecMuNeg, RecoDecay::pVec(pVecKaPos, pVecKaNeg)}, + return RecoDecay::m(std::array{pVecMuPos, pVecMuNeg, RecoDecay::pVec(pVecKa0, pVecKa1)}, std::array{o2::constants::physics::MassMuon, o2::constants::physics::MassMuon, o2::constants::physics::MassPhi}); } // Do not use PDG mass for either J/psi or phi - return RecoDecay::m(std::array{pVecMuPos, pVecMuNeg, pVecKaPos, pVecKaNeg}, + return RecoDecay::m(std::array{pVecMuPos, pVecMuNeg, pVecKa0, pVecKa1}, std::array{o2::constants::physics::MassMuon, o2::constants::physics::MassMuon, o2::constants::physics::MassKPlus, o2::constants::physics::MassKPlus}); } @@ -912,6 +944,122 @@ struct HfHelper { return true; } + // Apply topological cuts as defined in SelectorCuts.h + /// \param candB0 B0 candidate + /// \param cuts B0 candidate selection per pT bin + /// \param binsPt pT bin limits + /// \param useJpsiPdgMass Use PDG mass for J/psi when calculating B0 candidate mass + /// \param useK0StarPdgMass Use PDG mass for K*0 when calculating B0 candidate mass + /// \return true if candidate passes all selections + template + static bool selectionB0ToJpsiK0StarTopol(const T1& candB0, const T2& cuts, const T3& binsPt, const bool useJpsiPdgMass, const bool useK0StarPdgMass, const bool k0StarToKPi = true) + { + auto ptCandB0 = candB0.pt(); + auto mCandB0 = invMassB0ToJpsiK0Star(candB0, useJpsiPdgMass, useK0StarPdgMass, k0StarToKPi); + auto const pVecMu0 = candB0.pVectorProng0(); + auto const pVecMu1 = candB0.pVectorProng1(); + auto const pVecLfDau0 = candB0.pVectorProng2(); + auto const pVecLfDau1 = candB0.pVectorProng3(); + // K*0 invariant mass for the chosen daughter-mass hypothesis: K*0 → K+ π- or K*0bar → π+ K- + auto mCandK0Star = k0StarToKPi + ? RecoDecay::m(std::array{pVecLfDau0, pVecLfDau1}, std::array{o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}) + : RecoDecay::m(std::array{pVecLfDau0, pVecLfDau1}, std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus}); + auto ptJpsi = RecoDecay::pt(pVecMu0, pVecMu1); + auto ptK0Star = RecoDecay::pt(pVecLfDau0, pVecLfDau1); + auto candJpsi = candB0.jpsi(); + float pseudoPropDecLen = candB0.decayLengthXY() * mCandB0 / ptCandB0; + + int binPt = o2::analysis::findBin(binsPt, ptCandB0); + if (binPt == -1) { + return false; + } + + // B0 mass cut + if (std::abs(mCandB0 - o2::constants::physics::MassB0) > cuts->get(binPt, "m")) { + return false; + } + + // K*0 pt + if (ptK0Star < cuts->get(binPt, "pT K*0")) { + return false; + } + + // J/Psi pt + if (ptJpsi < cuts->get(binPt, "pT J/Psi")) { + return false; + } + + // K*0 mass + if (std::abs(mCandK0Star - o2::constants::physics::MassK0Star892) > cuts->get(binPt, "DeltaM K*0")) { + return false; + } + + // J/Psi mass + if (std::abs(candJpsi.m() - o2::constants::physics::MassJPsi) > cuts->get(binPt, "DeltaM J/Psi")) { + return false; + } + + // d0(J/Psi)xd0(K*0) + if (candB0.impactParameterProduct() > cuts->get(binPt, "B Imp. Par. Product")) { + return false; + } + + // B0 Decay length + if (candB0.decayLength() < cuts->get(binPt, "B decLen")) { + return false; + } + + // B0 Decay length XY + if (candB0.decayLengthXY() < cuts->get(binPt, "B decLenXY")) { + return false; + } + + // B0 CPA cut + if (candB0.cpa() < cuts->get(binPt, "CPA")) { + return false; + } + + // B0 CPAXY cut + if (candB0.cpaXY() < cuts->get(binPt, "CPAXY")) { + return false; + } + + // d0 of K*0 daughters + if (std::abs(candB0.impactParameter2()) < cuts->get(binPt, "d0 K*0 daughters") || + std::abs(candB0.impactParameter3()) < cuts->get(binPt, "d0 K*0 daughters")) { + return false; + } + + // d0 of J/Psi + if (std::abs(candB0.impactParameter0()) < cuts->get(binPt, "d0 J/Psi daughters") || + std::abs(candB0.impactParameter1()) < cuts->get(binPt, "d0 J/Psi daughters")) { + return false; + } + + // B pseudoproper decay length + if (pseudoPropDecLen < cuts->get(binPt, "B pseudoprop. decLen")) { + return false; + } + + return true; + } + + /// Apply PID selection + /// \param pidTrack PID status of track (prong of B0 candidate) + /// \param acceptPIDNotApplicable switch to accept Status::NotApplicable + /// \return true if prong of B0 candidate passes all selections + static bool selectionB0ToJpsiK0StarPid(const int pidTrack, const bool acceptPIDNotApplicable) + { + if (!acceptPIDNotApplicable && pidTrack != TrackSelectorPID::Accepted) { + return false; + } + if (acceptPIDNotApplicable && pidTrack == TrackSelectorPID::Rejected) { + return false; + } + + return true; + } + /// Apply PID selection /// \param pidTrackPi PID status of trackPi (prong1 of B+ candidate) /// \param acceptPIDNotApplicable switch to accept Status::NotApplicable @@ -932,7 +1080,7 @@ struct HfHelper { /// \param candBp B+ candidate /// \param cuts B+ candidate selection per pT bin /// \param binsPt pT bin limits - /// \param useJpsiPdgMass Use PDG mass for J/psi when calculating Bs candidate mass + /// \param useJpsiPdgMass Use PDG mass for J/psi when calculating B+ candidate mass /// \return true if candidate passes all selections template static bool selectionBplusToJpsiKTopol(const T1& candBp, const T2& cuts, const T3& binsPt, const bool useJpsiPdgMass) @@ -998,12 +1146,13 @@ struct HfHelper { } // d0 of K - if (std::abs(candBp.impactParameter1()) < cuts->get(binPt, "d0 K")) { + if (std::abs(candBp.impactParameter2()) < cuts->get(binPt, "d0 K")) { return false; } - // d0 of J/Psi - if (std::abs(candBp.impactParameter0()) < cuts->get(binPt, "d0 J/Psi")) { + // d0 of J/Psi daughters + if (std::abs(candBp.impactParameter0()) < cuts->get(binPt, "d0 J/Psi daughters") || + std::abs(candBp.impactParameter1()) < cuts->get(binPt, "d0 J/Psi daughters")) { return false; } @@ -1135,8 +1284,7 @@ struct HfHelper { auto const pVecKa1 = candBs.pVectorProng3(); auto mCandPhi = RecoDecay::m(std::array{pVecKa0, pVecKa1}, std::array{o2::constants::physics::MassKPlus, o2::constants::physics::MassKPlus}); auto ptJpsi = RecoDecay::pt(pVecMu0, pVecMu1); - auto ptKa0 = RecoDecay::pt(pVecKa0); - auto ptKa1 = RecoDecay::pt(pVecKa1); + auto ptPhi = RecoDecay::pt(pVecKa0, pVecKa1); auto candJpsi = candBs.jpsi(); float pseudoPropDecLen = candBs.decayLengthXY() * mCandBs / ptCandBs; @@ -1146,13 +1294,12 @@ struct HfHelper { } // Bs mass cut - if (std::abs(mCandBs - o2::constants::physics::MassBPlus) > cuts->get(binPt, "m")) { + if (std::abs(mCandBs - o2::constants::physics::MassBS) > cuts->get(binPt, "m")) { return false; } - // kaon pt - if (ptKa0 < cuts->get(binPt, "pT K") && - ptKa1 < cuts->get(binPt, "pT K")) { + // phi pt + if (ptPhi < cuts->get(binPt, "pT phi")) { return false; } @@ -1197,12 +1344,14 @@ struct HfHelper { } // d0 of phi - if (std::abs(candBs.impactParameter1()) < cuts->get(binPt, "d0 phi")) { + if ((std::abs(candBs.impactParameter2()) < cuts->get(binPt, "d0 phi daughters")) || + (std::abs(candBs.impactParameter3()) < cuts->get(binPt, "d0 phi daughters"))) { return false; } // d0 of J/Psi - if (std::abs(candBs.impactParameter0()) < cuts->get(binPt, "d0 J/Psi")) { + if (std::abs(candBs.impactParameter0()) < cuts->get(binPt, "d0 J/Psi daughters") || + std::abs(candBs.impactParameter1()) < cuts->get(binPt, "d0 J/Psi daughters")) { return false; } @@ -1215,15 +1364,15 @@ struct HfHelper { } /// Apply PID selection - /// \param pidTrackKa PID status of trackKa (prong1 of B+ candidate) + /// \param pidTrack PID status of track (prong of Bs candidate) /// \param acceptPIDNotApplicable switch to accept Status::NotApplicable - /// \return true if prong1 of B+ candidate passes all selections - static bool selectionBsToJpsiPhiPid(const int pidTrackKa, const bool acceptPIDNotApplicable) + /// \return true if prong1 of Bs candidate passes all selections + static bool selectionBsToJpsiPhiPid(const int pidTrack, const bool acceptPIDNotApplicable) { - if (!acceptPIDNotApplicable && pidTrackKa != TrackSelectorPID::Accepted) { + if (!acceptPIDNotApplicable && pidTrack != TrackSelectorPID::Accepted) { return false; } - if (acceptPIDNotApplicable && pidTrackKa == TrackSelectorPID::Rejected) { + if (acceptPIDNotApplicable && pidTrack == TrackSelectorPID::Rejected) { return false; } diff --git a/PWGHF/Core/HfMlResponseB0ToJpsiK0StarReduced.h b/PWGHF/Core/HfMlResponseB0ToJpsiK0StarReduced.h new file mode 100644 index 00000000000..b8b8f9ed8f7 --- /dev/null +++ b/PWGHF/Core/HfMlResponseB0ToJpsiK0StarReduced.h @@ -0,0 +1,223 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file HfMlResponseB0ToJpsiK0StarReduced.h +/// \brief Class to compute the ML response for B0 → J/Psi K*0 analysis selections in the reduced format +/// \author Fabrizio Chinu , Università degli Studi and INFN Torino + +#ifndef PWGHF_CORE_HFMLRESPONSEB0TOJPSIK0STARREDUCED_H_ +#define PWGHF_CORE_HFMLRESPONSEB0TOJPSIK0STARREDUCED_H_ + +#include "PWGHF/Core/HfMlResponse.h" +#include "PWGHF/D2H/Utils/utilsRedDataFormat.h" + +#include "Tools/ML/MlResponse.h" + +#include + +#include +#include + +// Fill the map of available input features +// the key is the feature's name (std::string) +// the value is the corresponding value in EnumInputFeatures +#define FILL_MAP_B0(FEATURE) \ + { \ + #FEATURE, static_cast(InputFeaturesB0ToJpsiK0StarReduced::FEATURE)} + +// Check if the index of mCachedIndices (index associated to a FEATURE) +// matches the entry in EnumInputFeatures associated to this FEATURE +// if so, the inputFeatures vector is filled with the FEATURE's value +// by calling the corresponding GETTER from OBJECT +#define CHECK_AND_FILL_VEC_B0_FULL(OBJECT, FEATURE, GETTER) \ + case static_cast(InputFeaturesB0ToJpsiK0StarReduced::FEATURE): { \ + inputFeatures.emplace_back(OBJECT.GETTER()); \ + break; \ + } + +// Check if the index of mCachedIndices (index associated to a FEATURE) +// matches the entry in EnumInputFeatures associated to this FEATURE +// if so, the inputFeatures vector is filled with the FEATURE's value +// by calling the GETTER function taking OBJECT in argument +#define CHECK_AND_FILL_VEC_B0_FUNC(OBJECT, FEATURE, GETTER) \ + case static_cast(InputFeaturesB0ToJpsiK0StarReduced::FEATURE): { \ + inputFeatures.emplace_back(GETTER(OBJECT)); \ + break; \ + } + +// Specific case of CHECK_AND_FILL_VEC_B0_FULL(OBJECT, FEATURE, GETTER) +// where OBJECT is named candidate and FEATURE = GETTER +#define CHECK_AND_FILL_VEC_B0(GETTER) \ + case static_cast(InputFeaturesB0ToJpsiK0StarReduced::GETTER): { \ + inputFeatures.emplace_back(candidate.GETTER()); \ + break; \ + } + +// Specific case of CHECK_AND_FILL_VEC_B0_FULL(OBJECT, FEATURE, GETTER) +// where OBJECT is named candidate and FEATURE = GETTER and mass hypotheses are needed +#define CHECK_AND_FILL_VEC_B0_WITH_MASS_HYPO(GETTER) \ + case static_cast(InputFeaturesB0ToJpsiK0StarReduced::GETTER): { \ + std::array massesKPi{ \ + o2::constants::physics::MassMuon, \ + o2::constants::physics::MassMuon, \ + o2::constants::physics::MassKPlus, \ + o2::constants::physics::MassPiPlus}; \ + std::array massesPiK{ \ + o2::constants::physics::MassMuon, \ + o2::constants::physics::MassMuon, \ + o2::constants::physics::MassPiPlus, \ + o2::constants::physics::MassKPlus}; \ + if (caseK0StarToKPi) { \ + inputFeatures.emplace_back(candidate.GETTER(massesKPi)); \ + } else { \ + inputFeatures.emplace_back(candidate.GETTER(massesPiK)); \ + } \ + break; \ + } + +namespace o2::analysis +{ + +enum class InputFeaturesB0ToJpsiK0StarReduced : uint8_t { + ptProng0 = 0, + ptProng1, + impactParameter0, + impactParameter1, + impactParameter2, + impactParameter3, + impactParameterProduct, + impactParameterProductJpsi, + impactParameterProductK0Star, + chi2PCA, + decayLength, + decayLengthXY, + decayLengthNormalised, + decayLengthXYNormalised, + cpa, + cpaXY, + maxNormalisedDeltaIP, + ctXY, + tpcNSigmaKa0, + tofNSigmaKa0, + tpcTofNSigmaKa0, + tpcNSigmaKa1, + tofNSigmaKa1, + tpcTofNSigmaKa1 +}; + +template +class HfMlResponseB0ToJpsiK0StarReduced : public HfMlResponse +{ + public: + /// Default constructor + HfMlResponseB0ToJpsiK0StarReduced() = default; + /// Default destructor + virtual ~HfMlResponseB0ToJpsiK0StarReduced() = default; + + /// Method to get the input features vector needed for ML inference + /// \param candidate is the B0 candidate + /// \param prong1 is the candidate's prong1 + /// \param prong2 is the candidate's prong2 + /// \param caseK0StarToKPi whether we have K*0 → K+ Pi- or K*0bar → K- Pi+ + /// \return inputFeatures vector + template + std::vector getInputFeatures(T1 const& candidate, + T2 const& prong1, + T3 const& prong2, + bool const caseK0StarToKPi) + { + std::vector inputFeatures; + + for (const auto& idx : MlResponse::mCachedIndices) { + switch (idx) { + CHECK_AND_FILL_VEC_B0(ptProng0); + CHECK_AND_FILL_VEC_B0(ptProng1); + CHECK_AND_FILL_VEC_B0(impactParameter0); + CHECK_AND_FILL_VEC_B0(impactParameter1); + CHECK_AND_FILL_VEC_B0(impactParameter2); + CHECK_AND_FILL_VEC_B0(impactParameter3); + CHECK_AND_FILL_VEC_B0(impactParameterProduct); + CHECK_AND_FILL_VEC_B0(impactParameterProductJpsi); + CHECK_AND_FILL_VEC_B0(impactParameterProductK0Star); + CHECK_AND_FILL_VEC_B0(chi2PCA); + CHECK_AND_FILL_VEC_B0(decayLength); + CHECK_AND_FILL_VEC_B0(decayLengthXY); + CHECK_AND_FILL_VEC_B0(decayLengthNormalised); + CHECK_AND_FILL_VEC_B0(decayLengthXYNormalised); + CHECK_AND_FILL_VEC_B0(cpa); + CHECK_AND_FILL_VEC_B0(cpaXY); + CHECK_AND_FILL_VEC_B0(maxNormalisedDeltaIP); + CHECK_AND_FILL_VEC_B0_WITH_MASS_HYPO(ctXY); + // TPC PID variable + CHECK_AND_FILL_VEC_B0_FULL(prong1, tpcNSigmaKa0, tpcNSigmaKa); + // TOF PID variable + CHECK_AND_FILL_VEC_B0_FULL(prong1, tofNSigmaKa0, tofNSigmaKa); + // Combined PID variables + CHECK_AND_FILL_VEC_B0_FUNC(prong1, tpcTofNSigmaKa0, o2::pid_tpc_tof_utils::getTpcTofNSigmaKa1); + // TPC PID variable + CHECK_AND_FILL_VEC_B0_FULL(prong2, tpcNSigmaKa1, tpcNSigmaKa); + // TOF PID variable + CHECK_AND_FILL_VEC_B0_FULL(prong2, tofNSigmaKa1, tofNSigmaKa); + // Combined PID variables + CHECK_AND_FILL_VEC_B0_FUNC(prong2, tpcTofNSigmaKa1, o2::pid_tpc_tof_utils::getTpcTofNSigmaKa1); + } + } + + return inputFeatures; + } + + protected: + /// Method to fill the map of available input features + void setAvailableInputFeatures() + { + MlResponse::mAvailableInputFeatures = { + FILL_MAP_B0(ptProng0), + FILL_MAP_B0(ptProng1), + FILL_MAP_B0(impactParameter0), + FILL_MAP_B0(impactParameter1), + FILL_MAP_B0(impactParameter2), + FILL_MAP_B0(impactParameter3), + FILL_MAP_B0(impactParameterProduct), + FILL_MAP_B0(impactParameterProductJpsi), + FILL_MAP_B0(impactParameterProductK0Star), + FILL_MAP_B0(chi2PCA), + FILL_MAP_B0(decayLength), + FILL_MAP_B0(decayLengthXY), + FILL_MAP_B0(decayLengthNormalised), + FILL_MAP_B0(decayLengthXYNormalised), + FILL_MAP_B0(cpa), + FILL_MAP_B0(cpaXY), + FILL_MAP_B0(maxNormalisedDeltaIP), + FILL_MAP_B0(ctXY), + // TPC PID variable + FILL_MAP_B0(tpcNSigmaKa0), + // TOF PID variable + FILL_MAP_B0(tofNSigmaKa0), + // Combined PID variable + FILL_MAP_B0(tpcTofNSigmaKa0), + // TPC PID variable + FILL_MAP_B0(tpcNSigmaKa1), + // TOF PID variable + FILL_MAP_B0(tofNSigmaKa1), + // Combined PID variable + FILL_MAP_B0(tpcTofNSigmaKa1)}; + } +}; + +} // namespace o2::analysis + +#undef FILL_MAP_B0 +#undef CHECK_AND_FILL_VEC_B0_FULL +#undef CHECK_AND_FILL_VEC_B0_FUNC +#undef CHECK_AND_FILL_VEC_B0 +#undef CHECK_AND_FILL_VEC_B0_WITH_MASS_HYPO + +#endif // PWGHF_CORE_HFMLRESPONSEB0TOJPSIK0STARREDUCED_H_ diff --git a/PWGHF/Core/HfMlResponseBsToJpsiPhiReduced.h b/PWGHF/Core/HfMlResponseBsToJpsiPhiReduced.h index ee9fb5956c7..8c094c9b305 100644 --- a/PWGHF/Core/HfMlResponseBsToJpsiPhiReduced.h +++ b/PWGHF/Core/HfMlResponseBsToJpsiPhiReduced.h @@ -29,10 +29,9 @@ // Fill the map of available input features // the key is the feature's name (std::string) // the value is the corresponding value in EnumInputFeatures -#define FILL_MAP_BS(FEATURE) \ - { \ - #FEATURE, static_cast(InputFeaturesBsToJpsiPhiReduced::FEATURE) \ - } +#define FILL_MAP_BS(FEATURE) \ + { \ + #FEATURE, static_cast(InputFeaturesBsToJpsiPhiReduced::FEATURE)} // Check if the index of mCachedIndices (index associated to a FEATURE) // matches the entry in EnumInputFeatures associated to this FEATURE @@ -112,6 +111,7 @@ class HfMlResponseBsToJpsiPhiReduced : public HfMlResponse /// Method to get the input features vector needed for ML inference /// \param candidate is the Bs candidate /// \param prong1 is the candidate's prong1 + /// \param prong2 is the candidate's prong2 /// \return inputFeatures vector template std::vector getInputFeatures(T1 const& candidate, diff --git a/PWGHF/Core/HfMlResponseOmegacToOmegaPi.h b/PWGHF/Core/HfMlResponseOmegacToOmegaPi.h index d3afc762d83..13e4731f491 100644 --- a/PWGHF/Core/HfMlResponseOmegacToOmegaPi.h +++ b/PWGHF/Core/HfMlResponseOmegacToOmegaPi.h @@ -74,6 +74,7 @@ enum class InputFeaturesOmegacToOmegaPi : uint8_t { dcaCascDau, cosPaCascToOmegac, decayLenXYCasc, + decayLenXYOmegac, ldlOmegac, chi2NdfTopoCascToOmegac, chi2NdfTopoCascToPv, @@ -120,6 +121,7 @@ class HfMlResponseOmegacToOmegaPi : public HfMlResponse CHECK_AND_FILL_VEC_OMEGAC0(dcaCascDau); CHECK_AND_FILL_VEC_OMEGAC0(cosPaCascToOmegac); CHECK_AND_FILL_VEC_OMEGAC0(decayLenXYCasc); + CHECK_AND_FILL_VEC_OMEGAC0(decayLenXYOmegac); CHECK_AND_FILL_VEC_OMEGAC0_FULL(candidate, ldlOmegac, omegacldl); CHECK_AND_FILL_VEC_OMEGAC0_FULL(candidate, chi2NdfTopoCascToOmegac, chi2TopoCascToOmegac); CHECK_AND_FILL_VEC_OMEGAC0_FULL(candidate, chi2NdfTopoCascToPv, chi2TopoCascToPv); @@ -156,6 +158,7 @@ class HfMlResponseOmegacToOmegaPi : public HfMlResponse FILL_MAP_OMEGAC0(dcaCascDau), FILL_MAP_OMEGAC0(cosPaCascToOmegac), FILL_MAP_OMEGAC0(decayLenXYCasc), + FILL_MAP_OMEGAC0(decayLenXYOmegac), FILL_MAP_OMEGAC0(ldlOmegac), FILL_MAP_OMEGAC0(chi2NdfTopoCascToOmegac), FILL_MAP_OMEGAC0(chi2NdfTopoCascToPv), diff --git a/PWGHF/Core/SelectorCuts.h b/PWGHF/Core/SelectorCuts.h index f48f1158109..37dd3c656c7 100644 --- a/PWGHF/Core/SelectorCuts.h +++ b/PWGHF/Core/SelectorCuts.h @@ -1146,6 +1146,61 @@ static const std::vector labelsPt = { // column labels static const std::vector labelsCutVar = {"m", "CPA", "Chi2PCA", "d0 D", "d0 Pi", "pT D", "pT Pi", "B0 decLen", "B0 decLenXY", "Imp. Par. Product", "DeltaMD", "Cos ThetaStar"}; } // namespace hf_cuts_b0_to_d_pi +namespace hf_cuts_b0_to_jpsi_k0star +{ +static constexpr int NBinsPt = 12; +static constexpr int NCutVars = 13; +// default values for the pT bin edges (can be used to configure histogram axis) +// offset by 1 from the bin numbers in cuts array +constexpr double BinsPt[NBinsPt + 1] = { + 0, + 0.5, + 1.0, + 2.0, + 3.0, + 4.0, + 5.0, + 7.0, + 10.0, + 13.0, + 16.0, + 20.0, + 24.0}; + +const auto vecBinsPt = std::vector{BinsPt, BinsPt + NBinsPt + 1}; + +// default values for the cuts +// DeltaM CPA CPAXY d0JpsiDau d0K*0Dau pTJpsi pTK*0 BDecayLength BDecayLengthXY BIPProd DeltaMJpsi DeltaMK*0 PseudopropDL +constexpr double Cuts[NBinsPt][NCutVars] = {{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.15, 0.}, /* 0 < pt < 0.5 */ + {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.15, 0.}, /* 0.5 < pt < 1 */ + {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.15, 0.}, /* 1 < pt < 2 */ + {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.15, 0.}, /* 2 < pt < 3 */ + {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.15, 0.}, /* 3 < pt < 4 */ + {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.15, 0.}, /* 4 < pt < 5 */ + {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.15, 0.}, /* 5 < pt < 7 */ + {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.15, 0.}, /* 7 < pt < 10 */ + {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.15, 0.}, /* 10 < pt < 13 */ + {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.15, 0.}, /* 13 < pt < 16 */ + {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.15, 0.}, /* 16 < pt < 20 */ + {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.15, 0.}}; /* 20 < pt < 24 */ +// row labels +static const std::vector labelsPt = { + "pT bin 0", + "pT bin 1", + "pT bin 2", + "pT bin 3", + "pT bin 4", + "pT bin 5", + "pT bin 6", + "pT bin 7", + "pT bin 8", + "pT bin 9", + "pT bin 10", + "pT bin 11"}; + +// column labels +static const std::vector labelsCutVar = {"m", "CPA", "CPAXY", "d0 J/Psi daughters", "d0 K*0 daughters", "pT J/Psi", "pT K*0", "B decLen", "B decLenXY", "B Imp. Par. Product", "DeltaM J/Psi", "DeltaM K*0", "B pseudoprop. decLen"}; +} // namespace hf_cuts_b0_to_jpsi_k0star namespace hf_cuts_bs_to_ds_pi { @@ -1222,7 +1277,7 @@ constexpr double BinsPt[NBinsPt + 1] = { const auto vecBinsPt = std::vector{BinsPt, BinsPt + NBinsPt + 1}; // default values for the cuts -// DeltaM CPA d0Jpsi d0K pTJpsi pTK BDecayLength BDecayLengthXY BIPProd DeltaMJpsi JpsiIPProd +// DeltaM CPA CPAXY d0Jpsi d0K pTJpsi pTK BDecayLength BDecayLengthXY BIPProd DeltaMJpsi DeltaMPhi PseudopropDL constexpr double Cuts[NBinsPt][NCutVars] = {{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}, /* 0 < pt < 0.5 */ {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}, /* 0.5 < pt < 1 */ {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.02, 0.}, /* 1 < pt < 2 */ @@ -1251,7 +1306,7 @@ static const std::vector labelsPt = { "pT bin 11"}; // column labels -static const std::vector labelsCutVar = {"m", "CPA", "CPAXY", "d0 J/Psi", "d0 phi", "pT J/Psi", "pT K", "B decLen", "B decLenXY", "B Imp. Par. Product", "DeltaM J/Psi", "DeltaM phi", "B pseudoprop. decLen"}; +static const std::vector labelsCutVar = {"m", "CPA", "CPAXY", "d0 J/Psi daughters", "d0 phi daughters", "pT J/Psi", "pT phi", "B decLen", "B decLenXY", "B Imp. Par. Product", "DeltaM J/Psi", "DeltaM phi", "B pseudoprop. decLen"}; } // namespace hf_cuts_bs_to_jpsi_phi namespace hf_cuts_bplus_to_d0_pi @@ -1334,7 +1389,7 @@ constexpr double BinsPt[NBinsPt + 1] = { const auto vecBinsPt = std::vector{BinsPt, BinsPt + NBinsPt + 1}; // default values for the cuts -// DeltaM CPA d0Jpsi d0K pTJpsi pTK BDecayLength BDecayLengthXY BIPProd DeltaMJpsi JpsiIPProd +// DeltaM CPA d0Jpsi d0K pTJpsi pTK BDecayLength BDecayLengthXY BIPProd DeltaMJpsi PseudopropDL constexpr double Cuts[NBinsPt][NCutVars] = {{1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.}, /* 0 < pt < 0.5 */ {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.}, /* 0.5 < pt < 1 */ {1., 0.8, 0.8, 0.01, 0.01, 1.0, 0.15, 0.05, 0.05, 0., 0.1, 0.}, /* 1 < pt < 2 */ @@ -1363,7 +1418,7 @@ static const std::vector labelsPt = { "pT bin 11"}; // column labels -static const std::vector labelsCutVar = {"m", "CPA", "CPAXY", "d0 J/Psi", "d0 K", "pT J/Psi", "pT K", "B decLen", "B decLenXY", "B Imp. Par. Product", "DeltaM J/Psi", "B pseudoprop. decLen"}; +static const std::vector labelsCutVar = {"m", "CPA", "CPAXY", "d0 J/Psi daughters", "d0 K", "pT J/Psi", "pT K", "B decLen", "B decLenXY", "B Imp. Par. Product", "DeltaM J/Psi", "B pseudoprop. decLen"}; } // namespace hf_cuts_bplus_to_jpsi_k namespace hf_cuts_lb_to_lc_pi diff --git a/PWGHF/D2H/DataModel/ReducedDataModel.h b/PWGHF/D2H/DataModel/ReducedDataModel.h index 9499fc76a31..7ddb58baad4 100644 --- a/PWGHF/D2H/DataModel/ReducedDataModel.h +++ b/PWGHF/D2H/DataModel/ReducedDataModel.h @@ -327,8 +327,9 @@ DECLARE_SOA_TABLE(HfRedBach0Bases, "AOD", "HFREDBACH0BASE", //! Table with track hf_track_pid_reduced::TPCTOFNSigmaPr, aod::track::Px, aod::track::Py, - aod::track::Pz, - aod::track::PVector); + aod::track::Pz, + aod::track::PVector, + aod::track::Sign); DECLARE_SOA_TABLE(HfRedBach0Cov, "AOD", "HFREDBACH0COV", //! Table with track covariance information for reduced workflow soa::Index<>, @@ -359,8 +360,9 @@ DECLARE_SOA_TABLE(HfRedBach1Bases, "AOD", "HFREDBACH1BASE", //! Table with track hf_track_pid_reduced::TPCTOFNSigmaPr, aod::track::Px, aod::track::Py, - aod::track::Pz, - aod::track::PVector); + aod::track::Pz, + aod::track::PVector, + aod::track::Sign); DECLARE_SOA_TABLE(HfRedBach1Cov, "AOD", "HFREDBACH1COV", //! Table with track covariance information for reduced workflow soa::Index<>, @@ -755,8 +757,8 @@ DECLARE_SOA_INDEX_COLUMN_FULL(ProngD0, prongD0, int, HfRed2Prongs, "_0"); DECLARE_SOA_INDEX_COLUMN_FULL(ProngBachPi, prongBachPi, int, HfRedTrackBases, "_1"); //! ProngBachPi index DECLARE_SOA_INDEX_COLUMN_FULL(ProngSoftPi, prongSoftPi, int, HfRedSoftPiBases, "_2"); //! ProngSoftPi index DECLARE_SOA_INDEX_COLUMN_FULL(Jpsi, jpsi, int, HfRedJpsis, "_0"); //! J/Psi index -DECLARE_SOA_INDEX_COLUMN_FULL(Prong0K0Star, prong0K0Star, int, HfRedBach0Bases, "_0"); //! J/Psi index -DECLARE_SOA_INDEX_COLUMN_FULL(Prong1K0Star, prong1K0Star, int, HfRedBach1Bases, "_0"); //! J/Psi index +DECLARE_SOA_INDEX_COLUMN_FULL(Prong0K0Star, prong0K0Star, int, HfRedBach0Bases, "_0"); //! K*0 index +DECLARE_SOA_INDEX_COLUMN_FULL(Prong1K0Star, prong1K0Star, int, HfRedBach1Bases, "_0"); //! K*0 index DECLARE_SOA_COLUMN(Prong0MlScoreBkg, prong0MlScoreBkg, float); //! Bkg ML score of the D daughter DECLARE_SOA_COLUMN(Prong0MlScorePrompt, prong0MlScorePrompt, float); //! Prompt ML score of the D daughter DECLARE_SOA_COLUMN(Prong0MlScoreNonprompt, prong0MlScoreNonprompt, float); //! Nonprompt ML score of the D daughter @@ -768,6 +770,9 @@ DECLARE_SOA_TABLE(HfRedB0Prongs, "AOD", "HFREDB0PRONG", //! Table with B0 daught DECLARE_SOA_TABLE(HfRedB0ProngDStars, "AOD", "HFREDB0PRONGDST", //! Table with B0 daughter indices hf_cand_b0_reduced::ProngD0Id, hf_cand_b0_reduced::ProngBachPiId, hf_cand_b0_reduced::ProngSoftPiId); +DECLARE_SOA_TABLE(HfRedB02JpsiDaus, "AOD", "HFREDB02JPSIDAU", + hf_cand_b0_reduced::JpsiId, hf_cand_b0_reduced::Prong0K0StarId, hf_cand_b0_reduced::Prong1K0StarId); + DECLARE_SOA_TABLE(HfRedB0DpMls, "AOD", "HFREDB0DPML", //! Table with ML scores for the D+ daughter hf_cand_b0_reduced::Prong0MlScoreBkg, hf_cand_b0_reduced::Prong0MlScorePrompt, @@ -776,6 +781,7 @@ DECLARE_SOA_TABLE(HfRedB0DpMls, "AOD", "HFREDB0DPML", //! Table with ML scores f using HfRedCandB0 = soa::Join; using HfRedCandB0DStar = soa::Join; +using HfRedCandB0ToJpsiK0Star = soa::Join; namespace hf_cand_bplus_reduced { diff --git a/PWGHF/D2H/TableProducer/CMakeLists.txt b/PWGHF/D2H/TableProducer/CMakeLists.txt index 674bbeeb25c..5a725c4623b 100644 --- a/PWGHF/D2H/TableProducer/CMakeLists.txt +++ b/PWGHF/D2H/TableProducer/CMakeLists.txt @@ -106,3 +106,10 @@ o2physics_add_dpl_workflow(converter-reduced-3-prongs-ml SOURCES converterReducedHadronDausPid.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +# Tree creator + +o2physics_add_dpl_workflow(tree-creator-dstar-spin-align-mixing + SOURCES treeCreatorDstarSpinAlignMixing.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGHF/D2H/TableProducer/candidateCreatorBToJpsiReduced.cxx b/PWGHF/D2H/TableProducer/candidateCreatorBToJpsiReduced.cxx index b42d84c54fc..8209d8696bb 100644 --- a/PWGHF/D2H/TableProducer/candidateCreatorBToJpsiReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateCreatorBToJpsiReduced.cxx @@ -63,6 +63,8 @@ enum DecayChannel : uint8_t { struct HfCandidateCreatorBToJpsiReduced { Produces rowCandidateBpBase; // table defined in CandidateReconstructionTables.h Produces rowCandidateBpProngs; // table defined in ReducedDataModel.h + Produces rowCandidateB0Base; // table defined in CandidateReconstructionTables.h + Produces rowCandidateB0Prongs; // table defined in ReducedDataModel.h Produces rowCandidateBsBase; // table defined in CandidateReconstructionTables.h Produces rowCandidateBsProngs; // table defined in ReducedDataModel.h @@ -78,8 +80,8 @@ struct HfCandidateCreatorBToJpsiReduced { // selection Configurable invMassWindowJpsiHadTolerance{"invMassWindowJpsiHadTolerance", 0.01, "invariant-mass window tolerance for J/Psi K pair preselections (GeV/c2)"}; - float myInvMassWindowJpsiK{1.}, myInvMassWindowJpsiPhi{1.}; // variable that will store the value of invMassWindowJpsiK (defined in dataCreatorJpsiKReduced.cxx) - double massBplus{0.}, massBs{0.}; + float myInvMassWindowJpsiK{1.}, myInvMassWindowJpsiK0Star{1.}, myInvMassWindowJpsiPhi{1.}; // variable that will store the value of invMassWindowJpsiK (defined in dataCreatorJpsiKReduced.cxx) + double massBplus{o2::constants::physics::MassBPlus}, massB0{o2::constants::physics::MassB0}, massBs{o2::constants::physics::MassBS}; double bz{0.}; o2::vertexing::DCAFitterN<2> df2; // fitter for B vertex (2-prong vertex fitter) o2::vertexing::DCAFitterN<3> df3; // fitter for B vertex (3-prong vertex fitter) @@ -97,10 +99,6 @@ struct HfCandidateCreatorBToJpsiReduced { void init(InitContext const&) { - // invariant-mass window cut - massBplus = o2::constants::physics::MassBPlus; - massBs = o2::constants::physics::MassBS; - // Initialize fitters df2.setPropagateToPCA(propagateToPCA); df2.setMaxR(maxR); @@ -132,6 +130,8 @@ struct HfCandidateCreatorBToJpsiReduced { // histograms registry.add("hMassJpsi", "J/Psi mass;#it{M}_{#mu#mu} (GeV/#it{c}^{2});Counts", {HistType::kTH1F, {{600, 2.5, 3.7, "#it{p}_{T} (GeV/#it{c})"}}}); registry.add("hMassBplusToJpsiK", "2-prong candidates;inv. mass (B^{+} #rightarrow #overline{D^{0}}#pi^{#plus} #rightarrow #pi^{#minus}K^{#plus}#pi^{#plus}) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 3., 8.}}}); + registry.add("hMassB0ToJpsiK0Star", "2-prong candidates;inv. mass (B^{0} #rightarrow J/ψ K^{*0}) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 4., 6.}}}); + registry.add("hMassBsToJpsiPhi", "2-prong candidates;inv. mass (B^{0}_{s} #rightarrow J/ψ #phi) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 4., 6.}}}); registry.add("hCovPVXX", "2-prong candidates;XX element of cov. matrix of prim. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, 0., 1.e-4}}}); registry.add("hCovSVXX", "2-prong candidates;XX element of cov. matrix of sec. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, 0., 0.2}}}); registry.add("hEvents", "Events;;entries", HistType::kTH1F, {{1, 0.5, 1.5}}); @@ -272,8 +272,91 @@ struct HfCandidateCreatorBToJpsiReduced { std::sqrt(dcaDauPos.getSigmaY2()), std::sqrt(dcaDauNeg.getSigmaY2()), std::sqrt(dcaKaon.getSigmaY2())); rowCandidateBpProngs(candJpsi.globalIndex(), trackLf0.globalIndex()); + } else if constexpr (DecChannel == DecayChannel::B0ToJpsiK0Star) { + for (const auto& trackLf1 : tracksLfDau1ThisCollision) { + if (trackLf0.sign() == trackLf1.sign()) { + continue; // require opposite-sign tracks for K*0 reconstruction + } + // this track is among daughters + if (trackLf1.trackId() == candJpsi.prongPosId() || trackLf1.trackId() == candJpsi.prongNegId()) { + continue; + } + auto trackParCovLf1 = getTrackParCov(trackLf1); + std::array pVecTrackLf1 = trackLf1.pVector(); + + // --------------------------------- + // reconstruct the 4-prong B0 vertex + hCandidatesB->Fill(SVFitting::BeforeFit); + try { + if (df4.process(trackPosParCov, trackNegParCov, trackParCovLf0, trackParCovLf1) == 0) { + continue; + } + } catch (const std::runtime_error& error) { + LOG(info) << "Run time error found: " << error.what() << ". DCAFitterN cannot work, skipping the candidate."; + hCandidatesB->Fill(SVFitting::Fail); + continue; + } + hCandidatesB->Fill(SVFitting::FitOk); + // passed B0 reconstruction + + // calculate relevant properties + const auto& secondaryVertexB0 = df4.getPCACandidate(); + auto chi2PCA = df4.getChi2AtPCACandidate(); + auto covMatrixPCA = df4.calcPCACovMatrixFlat(); + registry.fill(HIST("hCovSVXX"), covMatrixPCA[0]); + registry.fill(HIST("hCovPVXX"), covMatrixPV[0]); + + // get JPsi daughters and K tracks (propagated to the B0 vertex if propagateToPCA==true) + // track.getPxPyPzGlo(pVec) modifies pVec of track + df4.getTrack(0).getPxPyPzGlo(pVecDauPos); // momentum of Jpsi at the B0 vertex + df4.getTrack(1).getPxPyPzGlo(pVecDauNeg); // momentum of Jpsi at the B0 vertex + df4.getTrack(2).getPxPyPzGlo(pVecTrackLf0); // momentum of K at the B0 vertex + df4.getTrack(3).getPxPyPzGlo(pVecTrackLf1); // momentum of K at the B0 vertex + + // compute invariant mass square and apply selection + auto invMass2JpsiPiK = RecoDecay::m2(std::array{pVecDauPos, pVecDauNeg, pVecTrackLf0, pVecTrackLf1}, std::array{o2::constants::physics::MassMuon, o2::constants::physics::MassMuon, o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus}); + auto invMass2JpsiKPi = RecoDecay::m2(std::array{pVecDauPos, pVecDauNeg, pVecTrackLf0, pVecTrackLf1}, std::array{o2::constants::physics::MassMuon, o2::constants::physics::MassMuon, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); + bool isK0StarPiK = invMass2JpsiPiK > invMass2JpsiHadMin && invMass2JpsiPiK < invMass2JpsiHadMax; + bool isK0StarKPi = invMass2JpsiKPi > invMass2JpsiHadMin && invMass2JpsiKPi < invMass2JpsiHadMax; + + if (!isK0StarPiK && !isK0StarKPi) { + continue; + } + registry.fill(HIST("hMassB0ToJpsiK0Star"), isK0StarPiK ? std::sqrt(invMass2JpsiPiK) : std::sqrt(invMass2JpsiKPi)); + + // compute impact parameters of Jpsi and K*0 daughters + o2::dataformats::DCA dcaDauPos, dcaDauNeg, dcaTrackLf0, dcaTrackLf1; + trackPosParCov.propagateToDCA(primaryVertex, bz, &dcaDauPos); + trackNegParCov.propagateToDCA(primaryVertex, bz, &dcaDauNeg); + trackParCovLf0.propagateToDCA(primaryVertex, bz, &dcaTrackLf0); + trackParCovLf1.propagateToDCA(primaryVertex, bz, &dcaTrackLf1); + + // get uncertainty of the decay length + double phi{}, theta{}; + // getPointDirection modifies phi and theta + getPointDirection(std::array{collision.posX(), collision.posY(), collision.posZ()}, secondaryVertexB0, phi, theta); + auto errorDecayLength = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, theta) + getRotatedCovMatrixXX(covMatrixPCA, phi, theta)); + auto errorDecayLengthXY = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, 0.) + getRotatedCovMatrixXX(covMatrixPCA, phi, 0.)); + + // fill the candidate table for the B0 here: + rowCandidateB0Base(collision.globalIndex(), + collision.posX(), collision.posY(), collision.posZ(), + secondaryVertexB0[0], secondaryVertexB0[1], secondaryVertexB0[2], + errorDecayLength, errorDecayLengthXY, + chi2PCA, + pVecDauPos[0], pVecDauPos[1], pVecDauPos[2], + pVecDauNeg[0], pVecDauNeg[1], pVecDauNeg[2], + pVecTrackLf0[0], pVecTrackLf0[1], pVecTrackLf0[2], + pVecTrackLf1[0], pVecTrackLf1[1], pVecTrackLf1[2], + dcaDauPos.getY(), dcaDauNeg.getY(), dcaTrackLf0.getY(), dcaTrackLf1.getY(), + std::sqrt(dcaDauPos.getSigmaY2()), std::sqrt(dcaDauNeg.getSigmaY2()), std::sqrt(dcaTrackLf0.getSigmaY2()), std::sqrt(dcaTrackLf1.getSigmaY2())); + rowCandidateB0Prongs(candJpsi.globalIndex(), trackLf0.globalIndex(), trackLf1.globalIndex()); + } } else if constexpr (DecChannel == DecayChannel::BsToJpsiPhi) { for (const auto& trackLf1 : tracksLfDau1ThisCollision) { + if (trackLf0.sign() == trackLf1.sign()) { + continue; // require opposite-sign tracks for phi reconstruction + } // this track is among daughters if (trackLf1.trackId() == candJpsi.prongPosId() || trackLf1.trackId() == candJpsi.prongNegId()) { continue; @@ -305,17 +388,17 @@ struct HfCandidateCreatorBToJpsiReduced { // get JPsi daughters and K tracks (propagated to the Bs vertex if propagateToPCA==true) // track.getPxPyPzGlo(pVec) modifies pVec of track - df4.getTrack(0).getPxPyPzGlo(pVecDauPos); // momentum of Jpsi at the B+ vertex - df4.getTrack(1).getPxPyPzGlo(pVecDauNeg); // momentum of Jpsi at the B+ vertex - df4.getTrack(2).getPxPyPzGlo(pVecTrackLf0); // momentum of K at the B+ vertex - df4.getTrack(3).getPxPyPzGlo(pVecTrackLf1); // momentum of K at the B+ vertex + df4.getTrack(0).getPxPyPzGlo(pVecDauPos); // momentum of Jpsi at the Bs vertex + df4.getTrack(1).getPxPyPzGlo(pVecDauNeg); // momentum of Jpsi at the Bs vertex + df4.getTrack(2).getPxPyPzGlo(pVecTrackLf0); // momentum of K at the Bs vertex + df4.getTrack(3).getPxPyPzGlo(pVecTrackLf1); // momentum of K at the Bs vertex // compute invariant mass square and apply selection auto invMass2JpsiPhi = RecoDecay::m2(std::array{pVecDauPos, pVecDauNeg, pVecTrackLf0, pVecTrackLf1}, std::array{o2::constants::physics::MassMuon, o2::constants::physics::MassMuon, o2::constants::physics::MassKPlus, o2::constants::physics::MassKPlus}); if ((invMass2JpsiPhi < invMass2JpsiHadMin) || (invMass2JpsiPhi > invMass2JpsiHadMax)) { continue; } - registry.fill(HIST("hMassBplusToJpsiK"), std::sqrt(invMass2JpsiPhi)); + registry.fill(HIST("hMassBsToJpsiPhi"), std::sqrt(invMass2JpsiPhi)); // compute impact parameters of Jpsi and K o2::dataformats::DCA dcaDauPos, dcaDauNeg, dcaTrackLf0, dcaTrackLf1; @@ -378,6 +461,36 @@ struct HfCandidateCreatorBToJpsiReduced { } // processDataBplus PROCESS_SWITCH(HfCandidateCreatorBToJpsiReduced, processDataBplus, "Process data for B+", true); + void processDataB0(HfRedCollisionsWithExtras const& collisions, + soa::Join const& candsJpsi, + soa::Join const& tracksLfDau0, + soa::Join const& tracksLfDau1, + aod::HfOrigColCounts const& collisionsCounter, + aod::HfCfgB0ToJpsis const& configs) + { + // Jpsi K*0 invariant-mass window cut + for (const auto& config : configs) { + myInvMassWindowJpsiK0Star = config.myInvMassWindowJpsiK0Star(); + } + // invMassWindowJpsiHadTolerance is used to apply a slightly tighter cut than in JpsiK pair preselection + // to avoid accepting JpsiK pairs that were not formed in JpsiK pair creator + double const invMass2JpsiKMin = (massB0 - myInvMassWindowJpsiK0Star + invMassWindowJpsiHadTolerance) * (massB0 - myInvMassWindowJpsiK0Star + invMassWindowJpsiHadTolerance); + double const invMass2JpsiKMax = (massB0 + myInvMassWindowJpsiK0Star - invMassWindowJpsiHadTolerance) * (massB0 + myInvMassWindowJpsiK0Star - invMassWindowJpsiHadTolerance); + + for (const auto& collisionCounter : collisionsCounter) { + registry.fill(HIST("hEvents"), 1, collisionCounter.originalCollisionCount()); + } + + for (const auto& collision : collisions) { + auto thisCollId = collision.globalIndex(); + auto candsJpsiThisColl = candsJpsi.sliceBy(candsJpsiPerCollision, thisCollId); + auto tracksLf0ThisCollision = tracksLfDau0.sliceBy(tracksLf0PerCollision, thisCollId); + auto tracksLf1ThisCollision = tracksLfDau1.sliceBy(tracksLf1PerCollision, thisCollId); + runCandidateCreation(collision, candsJpsiThisColl, tracksLf0ThisCollision, tracksLf1ThisCollision, invMass2JpsiKMin, invMass2JpsiKMax); + } + } // processDataB0 + PROCESS_SWITCH(HfCandidateCreatorBToJpsiReduced, processDataB0, "Process data for B0", false); + void processDataBs(HfRedCollisionsWithExtras const& collisions, soa::Join const& candsJpsi, soa::Join const& tracksLfDau0, @@ -385,7 +498,7 @@ struct HfCandidateCreatorBToJpsiReduced { aod::HfOrigColCounts const& collisionsCounter, aod::HfCfgBsToJpsis const& configs) { - // Jpsi K invariant-mass window cut + // Jpsi phi invariant-mass window cut for (const auto& config : configs) { myInvMassWindowJpsiPhi = config.myInvMassWindowJpsiPhi(); } @@ -412,8 +525,10 @@ struct HfCandidateCreatorBToJpsiReduced { /// Extends the table base with expression columns and performs MC matching. struct HfCandidateCreatorBToJpsiReducedExpressions { Spawns rowCandidateBPlus; + Spawns rowCandidateB0; Spawns rowCandidateBs; Produces rowBplusMcRec; + Produces rowB0McRec; Produces rowBsMcRec; /// Fill candidate information at MC reconstruction level @@ -436,6 +551,18 @@ struct HfCandidateCreatorBToJpsiReducedExpressions { if (!filledMcInfo) { // protection to get same size tables in case something went wrong: we created a candidate that was not preselected in the Jpsi-K creator rowBplusMcRec(0, -1, -1, -1, -1.f); } + } else if constexpr (DecChannel == DecayChannel::B0ToJpsiK0Star) { + for (const auto& rowJpsiHadMcRec : rowsJpsiHadMcRec) { + if ((rowJpsiHadMcRec.jpsiId() != candB.jpsiId()) || (rowJpsiHadMcRec.prong0K0StarId() != candB.prong0K0StarId()) || (rowJpsiHadMcRec.prong1K0StarId() != candB.prong1K0StarId())) { + continue; + } + rowB0McRec(rowJpsiHadMcRec.flagMcMatchRec(), rowJpsiHadMcRec.flagMcDecayChanRec(), rowJpsiHadMcRec.flagWrongCollision(), rowJpsiHadMcRec.debugMcRec(), rowJpsiHadMcRec.ptMother()); + filledMcInfo = true; + break; + } + if (!filledMcInfo) { // protection to get same size tables in case something went wrong: we created a candidate that was not preselected in the Jpsi-K creator + rowB0McRec(0, -1, -1, -1, -1.f); + } } else if constexpr (DecChannel == DecayChannel::BsToJpsiPhi) { for (const auto& rowJpsiHadMcRec : rowsJpsiHadMcRec) { if ((rowJpsiHadMcRec.jpsiId() != candB.jpsiId()) || (rowJpsiHadMcRec.prong0PhiId() != candB.prong0PhiId()) || (rowJpsiHadMcRec.prong1PhiId() != candB.prong1PhiId())) { @@ -456,13 +583,19 @@ struct HfCandidateCreatorBToJpsiReducedExpressions { { fillMcRec(rowsJpsiKMcRec, candsBplus); } - PROCESS_SWITCH(HfCandidateCreatorBToJpsiReducedExpressions, processMcBPlus, "Process MC", false); + PROCESS_SWITCH(HfCandidateCreatorBToJpsiReducedExpressions, processMcBPlus, "Process MC for B+", false); + + void processMcB0(HfMcRecRedJPK0ss const& rowsJpsiK0StarMcRec, HfRedB02JpsiDaus const& b0) + { + fillMcRec(rowsJpsiK0StarMcRec, b0); + } + PROCESS_SWITCH(HfCandidateCreatorBToJpsiReducedExpressions, processMcB0, "Process MC for B0", false); void processMcBs(HfMcRecRedJPPhis const& rowsJpsiPhiMcRec, HfRedBs2JpsiDaus const& bs) { fillMcRec(rowsJpsiPhiMcRec, bs); } - PROCESS_SWITCH(HfCandidateCreatorBToJpsiReducedExpressions, processMcBs, "Process MC", false); + PROCESS_SWITCH(HfCandidateCreatorBToJpsiReducedExpressions, processMcBs, "Process MC for Bs", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx index 5eb2e3f0ad4..7e7fde636f9 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx @@ -153,10 +153,10 @@ struct HfDataCreatorJpsiHadReduced { Configurable ptTrackMin{"ptTrackMin", 0.5, "minimum bachelor track pT threshold (GeV/c)"}; Configurable absEtaTrackMax{"absEtaTrackMax", 0.8, "maximum bachelor track absolute eta threshold"}; Configurable> binsPtTrack{"binsPtTrack", std::vector{hf_cuts_single_track::vecBinsPtTrack}, "track pT bin limits for bachelor track DCA XY pT-dependent cut"}; - Configurable> cutsTrackDCA{"cutsTrackDCA", {hf_cuts_single_track::CutsTrack[0], hf_cuts_single_track::NBinsPtTrack, hf_cuts_single_track::NCutVarsTrack, hf_cuts_single_track::labelsPtTrack, hf_cuts_single_track::labelsCutVarTrack}, "Single-track selections per pT bin for bachelor track"}; + Configurable> cutsTrackDCA{"cutsTrackDCA", {&hf_cuts_single_track::CutsTrack[0][0], hf_cuts_single_track::NBinsPtTrack, hf_cuts_single_track::NCutVarsTrack, hf_cuts_single_track::labelsPtTrack, hf_cuts_single_track::labelsCutVarTrack}, "Single-track selections per pT bin for bachelor track"}; // topological/kinematic cuts Configurable> binsPt{"binsPt", std::vector{hf_cuts_jpsi_to_mu_mu::vecBinsPt}, "J/Psi pT bin limits"}; - Configurable> cuts{"cuts", {hf_cuts_jpsi_to_mu_mu::Cuts[0], hf_cuts_jpsi_to_mu_mu::NBinsPt, hf_cuts_jpsi_to_mu_mu::NCutVars, hf_cuts_jpsi_to_mu_mu::labelsPt, hf_cuts_jpsi_to_mu_mu::labelsCutVar}, "J/Psi candidate selection per pT bin"}; + Configurable> cuts{"cuts", {&hf_cuts_jpsi_to_mu_mu::Cuts[0][0], hf_cuts_jpsi_to_mu_mu::NBinsPt, hf_cuts_jpsi_to_mu_mu::NCutVars, hf_cuts_jpsi_to_mu_mu::labelsPt, hf_cuts_jpsi_to_mu_mu::labelsCutVar}, "J/Psi candidate selection per pT bin"}; Configurable invMassWindowJpsiHad{"invMassWindowJpsiHad", 0.3, "invariant-mass window for Jpsi-Had pair preselections (GeV/c2)"}; Configurable deltaMPhiMax{"deltaMPhiMax", 0.02, "invariant-mass window for phi preselections (GeV/c2) (only for Bs->J/PsiPhi)"}; Configurable deltaMK0StarMax{"deltaMK0StarMax", 0.15, "invariant-mass window for K*0 preselections (GeV/c2) (only for B0->J/PsiK0*)"}; @@ -206,14 +206,14 @@ struct HfDataCreatorJpsiHadReduced { selectorElectron.setRangePtTpc(selectionsPid.ptPidTpcMin, selectionsPid.ptPidTpcMax); selectorElectron.setRangeNSigmaTpc(selectionsPid.nSigmaTpcElMinForVeto, selectionsPid.nSigmaTpcElMaxForVeto); - std::array doProcess = {doprocessJpsiKData, doprocessJpsiKMc, doprocessJpsiK0StarData, doprocessJpsiK0StarMc, doprocessJpsiPhiData, doprocessJpsiPhiMc}; + std::array doProcess = {doprocessJpsiKData, doprocessJpsiKMc, doprocessJpsiK0StarData, doprocessJpsiK0StarMc, doprocessJpsiPhiData, doprocessJpsiPhiMc}; if (std::accumulate(doProcess.begin(), doProcess.end(), 0) != 1) { LOGP(fatal, "One and only one process function can be enabled at a time, please fix your configuration!"); } // Set up the histogram registry constexpr int NumBinsSelections = 2 + aod::SelectionStep::RecoPID; - std::string labels[NumBinsSelections]; + std::array labels; labels[0] = "No selection"; labels[1 + aod::SelectionStep::RecoSkims] = "Skims selection"; labels[1 + aod::SelectionStep::RecoTopol] = "Skims & Topological selections"; @@ -225,19 +225,19 @@ struct HfDataCreatorJpsiHadReduced { } constexpr int NumBinsEvents = NEvent; - std::string labelsEvents[NumBinsEvents]; + std::array labelsEvents; labelsEvents[Event::Processed] = "processed"; labelsEvents[Event::NoCharmHadPiSelected] = "without CharmHad-Pi pairs"; labelsEvents[Event::CharmHadPiSelected] = "with CharmHad-Pi pairs"; static const AxisSpec axisEvents = {NumBinsEvents, 0.5, NumBinsEvents + 0.5, ""}; - registry.add("hEvents", "Events;;entries", HistType::kTH1F, {axisEvents}); + registry.add("hEvents", "Events;;entries", HistType::kTH1D, {axisEvents}); for (int iBin = 0; iBin < NumBinsEvents; iBin++) { registry.get(HIST("hEvents"))->GetXaxis()->SetBinLabel(iBin + 1, labelsEvents[iBin].data()); } - registry.add("hMassJpsi", "J/Psi mass;#it{M}_{#mu#mu} (GeV/#it{c}^{2});Counts", {HistType::kTH1F, {{600, 2.8, 3.4, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hPtJpsi", "J/Psi #it{p}_{T};#it{p}_{T} (GeV/#it{c});Counts", {HistType::kTH1F, {{(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("hCpaJpsi", "J/Psi cos#theta_{p};J/Psi cos#theta_{p};Counts", {HistType::kTH1F, {{200, -1., 1, "J/Psi cos#theta_{p}"}}}); + registry.add("hMassJpsi", "J/Psi mass;#it{M}_{#mu#mu} (GeV/#it{c}^{2});Counts", {HistType::kTH1D, {{600, 2.8, 3.4, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hPtJpsi", "J/Psi #it{p}_{T};#it{p}_{T} (GeV/#it{c});Counts", {HistType::kTH1D, {{(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("hCpaJpsi", "J/Psi cos#theta_{p};J/Psi cos#theta_{p};Counts", {HistType::kTH1D, {{200, -1., 1, "J/Psi cos#theta_{p}"}}}); std::shared_ptr hFitCandidatesJpsi = registry.add("hFitCandidatesJpsi", "Jpsi candidate counter", {HistType::kTH1D, {axisCands}}); std::shared_ptr hFitCandidatesBPlus = registry.add("hFitCandidatesBPlus", "hFitCandidatesBPlus candidate counter", {HistType::kTH1D, {axisCands}}); std::shared_ptr hFitCandidatesB0 = registry.add("hFitCandidatesB0", "hFitCandidatesB0 candidate counter", {HistType::kTH1D, {axisCands}}); @@ -247,18 +247,18 @@ struct HfDataCreatorJpsiHadReduced { setLabelHistoCands(hFitCandidatesB0); setLabelHistoCands(hFitCandidatesBS); if (doprocessJpsiKData || doprocessJpsiKMc) { - registry.add("hPtKaon", "Kaon #it{p}_{T};#it{p}_{T} (GeV/#it{c});Counts", {HistType::kTH1F, {{100, 0., 10.}}}); - registry.add("hMassJpsiKaon", "J/Psi Kaon mass;#it{M}_{J/#PsiK} (GeV/#it{c}^{2});Counts", {HistType::kTH1F, {{800, 4.9, 5.7}}}); + registry.add("hPtKaon", "Kaon #it{p}_{T};#it{p}_{T} (GeV/#it{c});Counts", {HistType::kTH1D, {{100, 0., 10.}}}); + registry.add("hMassJpsiKaon", "J/Psi Kaon mass;#it{M}_{J/#PsiK} (GeV/#it{c}^{2});Counts", {HistType::kTH1D, {{800, 4.9, 5.7}}}); } else if (doprocessJpsiK0StarData || doprocessJpsiK0StarMc) { - registry.add("hPtK0Star", "K*0 #it{p}_{T};#it{p}_{T} (GeV/#it{c});Counts", {HistType::kTH1F, {{100, 0., 10.}}}); - registry.add("hMassK0Star", "K*0 mass;#it{M}_{#piK} (GeV/#it{c}^{2});Counts", {HistType::kTH1F, {{200, 0.9, 1.2}}}); - registry.add("hMassJpsiK0Star", "J/Psi K*0 mass;#it{M}_{J/#PsiK*0} (GeV/#it{c}^{2});Counts", {HistType::kTH1F, {{800, 4.9, 5.7}}}); + registry.add("hPtK0Star", "K*0 #it{p}_{T};#it{p}_{T} (GeV/#it{c});Counts", {HistType::kTH1D, {{100, 0., 10.}}}); + registry.add("hMassK0Star", "K*0 mass;#it{M}_{#piK} (GeV/#it{c}^{2});Counts", {HistType::kTH1D, {{400, 0.6, 1.2}}}); + registry.add("hMassJpsiK0Star", "J/Psi K*0 mass;#it{M}_{J/#PsiK*0} (GeV/#it{c}^{2});Counts", {HistType::kTH1D, {{800, 4.9, 5.7}}}); std::shared_ptr hFitCandidatesK0Star = registry.add("hFitCandidatesK0Star", "K*0 candidate counter", {HistType::kTH1D, {axisCands}}); setLabelHistoCands(hFitCandidatesK0Star); } else if (doprocessJpsiPhiData || doprocessJpsiPhiMc) { - registry.add("hPtPhi", "Phi #it{p}_{T};#it{p}_{T} (GeV/#it{c});Counts", {HistType::kTH1F, {{100, 0., 10.}}}); - registry.add("hMassPhi", "Phi mass;#it{M}_{KK} (GeV/#it{c}^{2});Counts", {HistType::kTH1F, {{200, 0.9, 1.2}}}); - registry.add("hMassJpsiPhi", "J/Psi Phi mass;#it{M}_{J/#Psi#phi} (GeV/#it{c}^{2});Counts", {HistType::kTH1F, {{800, 4.9, 5.7}}}); + registry.add("hPtPhi", "Phi #it{p}_{T};#it{p}_{T} (GeV/#it{c});Counts", {HistType::kTH1D, {{100, 0., 10.}}}); + registry.add("hMassPhi", "Phi mass;#it{M}_{KK} (GeV/#it{c}^{2});Counts", {HistType::kTH1D, {{400, 0.9, 1.2}}}); + registry.add("hMassJpsiPhi", "J/Psi Phi mass;#it{M}_{J/#Psi#phi} (GeV/#it{c}^{2});Counts", {HistType::kTH1D, {{800, 4.9, 5.7}}}); std::shared_ptr hFitCandidatesPhi = registry.add("hFitCandidatesPhi", "Phi candidate counter", {HistType::kTH1D, {axisCands}}); setLabelHistoCands(hFitCandidatesPhi); } @@ -299,6 +299,9 @@ struct HfDataCreatorJpsiHadReduced { if (doprocessJpsiKData || doprocessJpsiKMc) { invMass2JpsiHadMin = (MassBPlus - invMassWindowJpsiHad) * (MassBPlus - invMassWindowJpsiHad); invMass2JpsiHadMax = (MassBPlus + invMassWindowJpsiHad) * (MassBPlus + invMassWindowJpsiHad); + } else if (doprocessJpsiK0StarData || doprocessJpsiK0StarMc) { + invMass2JpsiHadMin = (MassB0 - invMassWindowJpsiHad) * (MassB0 - invMassWindowJpsiHad); + invMass2JpsiHadMax = (MassB0 + invMassWindowJpsiHad) * (MassB0 + invMassWindowJpsiHad); } else if (doprocessJpsiPhiData || doprocessJpsiPhiMc) { invMass2JpsiHadMin = (MassBS - invMassWindowJpsiHad) * (MassBS - invMassWindowJpsiHad); invMass2JpsiHadMax = (MassBS + invMassWindowJpsiHad) * (MassBS + invMassWindowJpsiHad); @@ -416,10 +419,7 @@ struct HfDataCreatorJpsiHadReduced { pidElectron = selectorElectron.statusTpc(track, track.tpcNSigmaEl()); - if (pidElectron == TrackSelectorPID::Accepted) { - return false; - } - return true; + return pidElectron != TrackSelectorPID::Accepted; } /// B meson preselections @@ -892,7 +892,7 @@ struct HfDataCreatorJpsiHadReduced { // fill Kaon tracks table // if information on track already stored, go to next track - if (!selectedTracksBach.count(trackBach.globalIndex())) { + if (!selectedTracksBach.contains(trackBach.globalIndex())) { hfTrackLfDau0(trackBach.globalIndex(), indexHfReducedCollision, trackParCovBach.getX(), trackParCovBach.getAlpha(), trackParCovBach.getY(), trackParCovBach.getZ(), trackParCovBach.getSnp(), @@ -994,52 +994,57 @@ struct HfDataCreatorJpsiHadReduced { } registry.fill(HIST("hMassJpsiK0Star"), std::sqrt(invMass2JpsiHad)); - // fill daughter tracks table + // fill daughter tracks table (positive daughter as Dau0, negative daughter as Dau1) + const auto& posDauTrack = trackBach.sign() > 0 ? trackBach : trackBach2; + const auto& negDauTrack = trackBach.sign() > 0 ? trackBach2 : trackBach; + const auto& posDauTrackParCov = trackBach.sign() > 0 ? trackParCovBach : trackBach2ParCov; + const auto& negDauTrackParCov = trackBach.sign() > 0 ? trackBach2ParCov : trackParCovBach; + // if information on track already stored, go to next track - if (!selectedTracksBach.count(trackBach.globalIndex())) { - hfTrackLfDau0(trackBach.globalIndex(), indexHfReducedCollision, - trackParCovBach.getX(), trackParCovBach.getAlpha(), - trackParCovBach.getY(), trackParCovBach.getZ(), trackParCovBach.getSnp(), - trackParCovBach.getTgl(), trackParCovBach.getQ2Pt(), - trackBach.itsNCls(), trackBach.tpcNClsCrossedRows(), trackBach.tpcChi2NCl(), trackBach.itsChi2NCl(), - trackBach.hasTPC(), trackBach.hasTOF(), - trackBach.tpcNSigmaPi(), trackBach.tofNSigmaPi(), - trackBach.tpcNSigmaKa(), trackBach.tofNSigmaKa(), - trackBach.tpcNSigmaPr(), trackBach.tofNSigmaPr()); - hfTrackCovLfDau0(trackParCovBach.getSigmaY2(), trackParCovBach.getSigmaZY(), trackParCovBach.getSigmaZ2(), - trackParCovBach.getSigmaSnpY(), trackParCovBach.getSigmaSnpZ(), - trackParCovBach.getSigmaSnp2(), trackParCovBach.getSigmaTglY(), trackParCovBach.getSigmaTglZ(), - trackParCovBach.getSigmaTglSnp(), trackParCovBach.getSigmaTgl2(), - trackParCovBach.getSigma1PtY(), trackParCovBach.getSigma1PtZ(), trackParCovBach.getSigma1PtSnp(), - trackParCovBach.getSigma1PtTgl(), trackParCovBach.getSigma1Pt2()); + if (!selectedTracksBach.contains(posDauTrack.globalIndex())) { + hfTrackLfDau0(posDauTrack.globalIndex(), indexHfReducedCollision, + posDauTrackParCov.getX(), posDauTrackParCov.getAlpha(), + posDauTrackParCov.getY(), posDauTrackParCov.getZ(), posDauTrackParCov.getSnp(), + posDauTrackParCov.getTgl(), posDauTrackParCov.getQ2Pt(), + posDauTrack.itsNCls(), posDauTrack.tpcNClsCrossedRows(), posDauTrack.tpcChi2NCl(), posDauTrack.itsChi2NCl(), + posDauTrack.hasTPC(), posDauTrack.hasTOF(), + posDauTrack.tpcNSigmaPi(), posDauTrack.tofNSigmaPi(), + posDauTrack.tpcNSigmaKa(), posDauTrack.tofNSigmaKa(), + posDauTrack.tpcNSigmaPr(), posDauTrack.tofNSigmaPr()); + hfTrackCovLfDau0(posDauTrackParCov.getSigmaY2(), posDauTrackParCov.getSigmaZY(), posDauTrackParCov.getSigmaZ2(), + posDauTrackParCov.getSigmaSnpY(), posDauTrackParCov.getSigmaSnpZ(), + posDauTrackParCov.getSigmaSnp2(), posDauTrackParCov.getSigmaTglY(), posDauTrackParCov.getSigmaTglZ(), + posDauTrackParCov.getSigmaTglSnp(), posDauTrackParCov.getSigmaTgl2(), + posDauTrackParCov.getSigma1PtY(), posDauTrackParCov.getSigma1PtZ(), posDauTrackParCov.getSigma1PtSnp(), + posDauTrackParCov.getSigma1PtTgl(), posDauTrackParCov.getSigma1Pt2()); // add trackBach.globalIndex() to a list // to keep memory of the pions filled in the table and avoid refilling them if they are paired to another Jpsi candidate // and keep track of their index in hfTrackLfDau0 for McRec purposes - selectedTracksBach[trackBach.globalIndex()] = hfTrackLfDau0.lastIndex(); + selectedTracksBach[posDauTrack.globalIndex()] = hfTrackLfDau0.lastIndex(); } // fill daughter tracks table // if information on track already stored, go to next track - if (!selectedTracksBach2.count(trackBach2.globalIndex())) { - hfTrackLfDau1(trackBach2.globalIndex(), indexHfReducedCollision, - trackBach2ParCov.getX(), trackBach2ParCov.getAlpha(), - trackBach2ParCov.getY(), trackBach2ParCov.getZ(), trackBach2ParCov.getSnp(), - trackBach2ParCov.getTgl(), trackBach2ParCov.getQ2Pt(), - trackBach2.itsNCls(), trackBach2.tpcNClsCrossedRows(), trackBach2.tpcChi2NCl(), trackBach2.itsChi2NCl(), - trackBach2.hasTPC(), trackBach2.hasTOF(), - trackBach2.tpcNSigmaPi(), trackBach2.tofNSigmaPi(), - trackBach2.tpcNSigmaKa(), trackBach2.tofNSigmaKa(), - trackBach2.tpcNSigmaPr(), trackBach2.tofNSigmaPr()); - hfTrackCovLfDau1(trackBach2ParCov.getSigmaY2(), trackBach2ParCov.getSigmaZY(), trackBach2ParCov.getSigmaZ2(), - trackBach2ParCov.getSigmaSnpY(), trackBach2ParCov.getSigmaSnpZ(), - trackBach2ParCov.getSigmaSnp2(), trackBach2ParCov.getSigmaTglY(), trackBach2ParCov.getSigmaTglZ(), - trackBach2ParCov.getSigmaTglSnp(), trackBach2ParCov.getSigmaTgl2(), - trackBach2ParCov.getSigma1PtY(), trackBach2ParCov.getSigma1PtZ(), trackBach2ParCov.getSigma1PtSnp(), - trackBach2ParCov.getSigma1PtTgl(), trackBach2ParCov.getSigma1Pt2()); - // add trackBach2.globalIndex() to a list + if (!selectedTracksBach2.contains(negDauTrack.globalIndex())) { + hfTrackLfDau1(negDauTrack.globalIndex(), indexHfReducedCollision, + negDauTrackParCov.getX(), negDauTrackParCov.getAlpha(), + negDauTrackParCov.getY(), negDauTrackParCov.getZ(), negDauTrackParCov.getSnp(), + negDauTrackParCov.getTgl(), negDauTrackParCov.getQ2Pt(), + negDauTrack.itsNCls(), negDauTrack.tpcNClsCrossedRows(), negDauTrack.tpcChi2NCl(), negDauTrack.itsChi2NCl(), + negDauTrack.hasTPC(), negDauTrack.hasTOF(), + negDauTrack.tpcNSigmaPi(), negDauTrack.tofNSigmaPi(), + negDauTrack.tpcNSigmaKa(), negDauTrack.tofNSigmaKa(), + negDauTrack.tpcNSigmaPr(), negDauTrack.tofNSigmaPr()); + hfTrackCovLfDau1(negDauTrackParCov.getSigmaY2(), negDauTrackParCov.getSigmaZY(), negDauTrackParCov.getSigmaZ2(), + negDauTrackParCov.getSigmaSnpY(), negDauTrackParCov.getSigmaSnpZ(), + negDauTrackParCov.getSigmaSnp2(), negDauTrackParCov.getSigmaTglY(), negDauTrackParCov.getSigmaTglZ(), + negDauTrackParCov.getSigmaTglSnp(), negDauTrackParCov.getSigmaTgl2(), + negDauTrackParCov.getSigma1PtY(), negDauTrackParCov.getSigma1PtZ(), negDauTrackParCov.getSigma1PtSnp(), + negDauTrackParCov.getSigma1PtTgl(), negDauTrackParCov.getSigma1Pt2()); + // add negDauTrack.globalIndex() to a list // to keep memory of the pions filled in the table and avoid refilling them if they are paired to another Jpsi candidate // and keep track of their index in hfTrackLfDau1 for McRec purposes - selectedTracksBach2[trackBach2.globalIndex()] = hfTrackLfDau1.lastIndex(); + selectedTracksBach2[negDauTrack.globalIndex()] = hfTrackLfDau1.lastIndex(); } if constexpr (DoMc) { @@ -1048,8 +1053,8 @@ struct HfDataCreatorJpsiHadReduced { for (const auto& track : jPsiDauTracks) { beautyHadDauTracks.push_back(track); } - beautyHadDauTracks.push_back(trackBach); - beautyHadDauTracks.push_back(trackBach2); + beautyHadDauTracks.push_back(posDauTrack); + beautyHadDauTracks.push_back(negDauTrack); fillMcRecoInfo(collision, particlesMc, beautyHadDauTracks, indexHfCandJpsi, std::array, 2>{selectedTracksBach, selectedTracksBach2}, indexCollisionMaxNumContrib); } fillHfCandJpsi = true; @@ -1121,52 +1126,57 @@ struct HfDataCreatorJpsiHadReduced { } registry.fill(HIST("hMassJpsiPhi"), std::sqrt(invMass2JpsiHad)); - // fill daughter tracks table + // fill daughter tracks table (positive daughter as Dau0, negative daughter as Dau1) + const auto& posDauTrack = trackBach.sign() > 0 ? trackBach : trackBach2; + const auto& negDauTrack = trackBach.sign() > 0 ? trackBach2 : trackBach; + const auto& posDauTrackParCov = trackBach.sign() > 0 ? trackParCovBach : trackBach2ParCov; + const auto& negDauTrackParCov = trackBach.sign() > 0 ? trackBach2ParCov : trackParCovBach; + // if information on track already stored, go to next track - if (!selectedTracksBach.count(trackBach.globalIndex())) { - hfTrackLfDau0(trackBach.globalIndex(), indexHfReducedCollision, - trackParCovBach.getX(), trackParCovBach.getAlpha(), - trackParCovBach.getY(), trackParCovBach.getZ(), trackParCovBach.getSnp(), - trackParCovBach.getTgl(), trackParCovBach.getQ2Pt(), - trackBach.itsNCls(), trackBach.tpcNClsCrossedRows(), trackBach.tpcChi2NCl(), trackBach.itsChi2NCl(), - trackBach.hasTPC(), trackBach.hasTOF(), - trackBach.tpcNSigmaPi(), trackBach.tofNSigmaPi(), - trackBach.tpcNSigmaKa(), trackBach.tofNSigmaKa(), - trackBach.tpcNSigmaPr(), trackBach.tofNSigmaPr()); - hfTrackCovLfDau0(trackParCovBach.getSigmaY2(), trackParCovBach.getSigmaZY(), trackParCovBach.getSigmaZ2(), - trackParCovBach.getSigmaSnpY(), trackParCovBach.getSigmaSnpZ(), - trackParCovBach.getSigmaSnp2(), trackParCovBach.getSigmaTglY(), trackParCovBach.getSigmaTglZ(), - trackParCovBach.getSigmaTglSnp(), trackParCovBach.getSigmaTgl2(), - trackParCovBach.getSigma1PtY(), trackParCovBach.getSigma1PtZ(), trackParCovBach.getSigma1PtSnp(), - trackParCovBach.getSigma1PtTgl(), trackParCovBach.getSigma1Pt2()); - // add trackBach.globalIndex() to a list + if (!selectedTracksBach.contains(posDauTrack.globalIndex())) { + hfTrackLfDau0(posDauTrack.globalIndex(), indexHfReducedCollision, + posDauTrackParCov.getX(), posDauTrackParCov.getAlpha(), + posDauTrackParCov.getY(), posDauTrackParCov.getZ(), posDauTrackParCov.getSnp(), + posDauTrackParCov.getTgl(), posDauTrackParCov.getQ2Pt(), + posDauTrack.itsNCls(), posDauTrack.tpcNClsCrossedRows(), posDauTrack.tpcChi2NCl(), posDauTrack.itsChi2NCl(), + posDauTrack.hasTPC(), posDauTrack.hasTOF(), + posDauTrack.tpcNSigmaPi(), posDauTrack.tofNSigmaPi(), + posDauTrack.tpcNSigmaKa(), posDauTrack.tofNSigmaKa(), + posDauTrack.tpcNSigmaPr(), posDauTrack.tofNSigmaPr()); + hfTrackCovLfDau0(posDauTrackParCov.getSigmaY2(), posDauTrackParCov.getSigmaZY(), posDauTrackParCov.getSigmaZ2(), + posDauTrackParCov.getSigmaSnpY(), posDauTrackParCov.getSigmaSnpZ(), + posDauTrackParCov.getSigmaSnp2(), posDauTrackParCov.getSigmaTglY(), posDauTrackParCov.getSigmaTglZ(), + posDauTrackParCov.getSigmaTglSnp(), posDauTrackParCov.getSigmaTgl2(), + posDauTrackParCov.getSigma1PtY(), posDauTrackParCov.getSigma1PtZ(), posDauTrackParCov.getSigma1PtSnp(), + posDauTrackParCov.getSigma1PtTgl(), posDauTrackParCov.getSigma1Pt2()); + // add posDauTrack.globalIndex() to a list // to keep memory of the pions filled in the table and avoid refilling them if they are paired to another Jpsi candidate // and keep track of their index in hfTrackLfDau0 for McRec purposes - selectedTracksBach[trackBach.globalIndex()] = hfTrackLfDau0.lastIndex(); + selectedTracksBach[posDauTrack.globalIndex()] = hfTrackLfDau0.lastIndex(); } // fill daughter tracks table // if information on track already stored, go to next track - if (!selectedTracksBach2.count(trackBach2.globalIndex())) { - hfTrackLfDau1(trackBach2.globalIndex(), indexHfReducedCollision, - trackBach2ParCov.getX(), trackBach2ParCov.getAlpha(), - trackBach2ParCov.getY(), trackBach2ParCov.getZ(), trackBach2ParCov.getSnp(), - trackBach2ParCov.getTgl(), trackBach2ParCov.getQ2Pt(), - trackBach2.itsNCls(), trackBach2.tpcNClsCrossedRows(), trackBach2.tpcChi2NCl(), trackBach2.itsChi2NCl(), - trackBach2.hasTPC(), trackBach2.hasTOF(), - trackBach2.tpcNSigmaPi(), trackBach2.tofNSigmaPi(), - trackBach2.tpcNSigmaKa(), trackBach2.tofNSigmaKa(), - trackBach2.tpcNSigmaPr(), trackBach2.tofNSigmaPr()); - hfTrackCovLfDau1(trackBach2ParCov.getSigmaY2(), trackBach2ParCov.getSigmaZY(), trackBach2ParCov.getSigmaZ2(), - trackBach2ParCov.getSigmaSnpY(), trackBach2ParCov.getSigmaSnpZ(), - trackBach2ParCov.getSigmaSnp2(), trackBach2ParCov.getSigmaTglY(), trackBach2ParCov.getSigmaTglZ(), - trackBach2ParCov.getSigmaTglSnp(), trackBach2ParCov.getSigmaTgl2(), - trackBach2ParCov.getSigma1PtY(), trackBach2ParCov.getSigma1PtZ(), trackBach2ParCov.getSigma1PtSnp(), - trackBach2ParCov.getSigma1PtTgl(), trackBach2ParCov.getSigma1Pt2()); - // add trackBach2.globalIndex() to a list + if (!selectedTracksBach2.contains(negDauTrack.globalIndex())) { + hfTrackLfDau1(negDauTrack.globalIndex(), indexHfReducedCollision, + negDauTrackParCov.getX(), negDauTrackParCov.getAlpha(), + negDauTrackParCov.getY(), negDauTrackParCov.getZ(), negDauTrackParCov.getSnp(), + negDauTrackParCov.getTgl(), negDauTrackParCov.getQ2Pt(), + negDauTrack.itsNCls(), negDauTrack.tpcNClsCrossedRows(), negDauTrack.tpcChi2NCl(), negDauTrack.itsChi2NCl(), + negDauTrack.hasTPC(), negDauTrack.hasTOF(), + negDauTrack.tpcNSigmaPi(), negDauTrack.tofNSigmaPi(), + negDauTrack.tpcNSigmaKa(), negDauTrack.tofNSigmaKa(), + negDauTrack.tpcNSigmaPr(), negDauTrack.tofNSigmaPr()); + hfTrackCovLfDau1(negDauTrackParCov.getSigmaY2(), negDauTrackParCov.getSigmaZY(), negDauTrackParCov.getSigmaZ2(), + negDauTrackParCov.getSigmaSnpY(), negDauTrackParCov.getSigmaSnpZ(), + negDauTrackParCov.getSigmaSnp2(), negDauTrackParCov.getSigmaTglY(), negDauTrackParCov.getSigmaTglZ(), + negDauTrackParCov.getSigmaTglSnp(), negDauTrackParCov.getSigmaTgl2(), + negDauTrackParCov.getSigma1PtY(), negDauTrackParCov.getSigma1PtZ(), negDauTrackParCov.getSigma1PtSnp(), + negDauTrackParCov.getSigma1PtTgl(), negDauTrackParCov.getSigma1Pt2()); + // add negDauTrack.globalIndex() to a list // to keep memory of the pions filled in the table and avoid refilling them if they are paired to another Jpsi candidate // and keep track of their index in hfTrackLfDau1 for McRec purposes - selectedTracksBach2[trackBach2.globalIndex()] = hfTrackLfDau1.lastIndex(); + selectedTracksBach2[negDauTrack.globalIndex()] = hfTrackLfDau1.lastIndex(); } if constexpr (DoMc) { @@ -1175,8 +1185,8 @@ struct HfDataCreatorJpsiHadReduced { for (const auto& track : jPsiDauTracks) { beautyHadDauTracks.push_back(track); } - beautyHadDauTracks.push_back(trackBach); - beautyHadDauTracks.push_back(trackBach2); + beautyHadDauTracks.push_back(posDauTrack); + beautyHadDauTracks.push_back(negDauTrack); fillMcRecoInfo(collision, particlesMc, beautyHadDauTracks, indexHfCandJpsi, std::array, 2>{selectedTracksBach, selectedTracksBach2}, indexCollisionMaxNumContrib); } fillHfCandJpsi = true; diff --git a/PWGHF/D2H/TableProducer/treeCreatorDstarSpinAlignMixing.cxx b/PWGHF/D2H/TableProducer/treeCreatorDstarSpinAlignMixing.cxx new file mode 100644 index 00000000000..e89d601aa3b --- /dev/null +++ b/PWGHF/D2H/TableProducer/treeCreatorDstarSpinAlignMixing.cxx @@ -0,0 +1,236 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file treeCreatorDstarSpinAlignMixing.cxx +/// \brief Writer of D*+ → D0 ( → π+ K-) π+ candidates in the form of flat tables to be stored in TTrees. +/// Intended for Mix-candidate analysis in spin alignment measurement. +/// Serving as a correction for detector acceptance and reconstruction efficiency. +/// +/// \author Mingze li , CCNU/UniTo + +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/D2H/Utils/utilsFlow.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Qvectors.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::hf_centrality; +using namespace o2::hf_occupancy; +using namespace o2::analysis::hf_flow_utils; + +namespace o2::aod +{ +namespace mixing_dstar +{ +DECLARE_SOA_INDEX_COLUMN(Collision, collision); +// D0 related variables +DECLARE_SOA_COLUMN(MD0, mD0, float); +// DECLARE_SOA_COLUMN(PtD0, ptD0, float); +// DECLARE_SOA_COLUMN(PD0, pD0, float); +// DECLARE_SOA_COLUMN(EtaD0, etaD0, float); +// DECLARE_SOA_COLUMN(PhiD0, phiD0, float); +// DECLARE_SOA_COLUMN(YD0, yD0, float); +// soft pion related variables +DECLARE_SOA_COLUMN(PtSoftPi, ptSoftPi, float); +// DECLARE_SOA_COLUMN(PSoftPi, pSoftPi, float); +DECLARE_SOA_COLUMN(EtaSoftPi, etaSoftPi, float); +DECLARE_SOA_COLUMN(PhiSoftPi, phiSoftPi, float); +// DECLARE_SOA_COLUMN(YSoftPi, ySoftPi, float); +// Dstar related variables +DECLARE_SOA_COLUMN(M, m, float); +DECLARE_SOA_COLUMN(Pt, pt, float); +// DECLARE_SOA_COLUMN(P, p, float); +DECLARE_SOA_COLUMN(Eta, eta, float); +DECLARE_SOA_COLUMN(Phi, phi, float); +DECLARE_SOA_COLUMN(Y, y, float); +DECLARE_SOA_COLUMN(MlProbDstarToD0PiBkg, mlProbDstarToD0PiBkg, float); +DECLARE_SOA_COLUMN(MlProbDstarToD0PiPrompt, mlProbDstarToD0PiPrompt, float); +DECLARE_SOA_COLUMN(MlProbDstarToD0PiNonPrompt, mlProbDstarToD0PiNonPrompt, float); +// Events +DECLARE_SOA_COLUMN(ZVtx, zVtx, float); +DECLARE_SOA_COLUMN(Centrality, centrality, float); +DECLARE_SOA_COLUMN(NPvContrib, nPvContrib, uint16_t); +DECLARE_SOA_COLUMN(Occupancy, occupancy, int); +DECLARE_SOA_COLUMN(XQVec, xQVec, float); +DECLARE_SOA_COLUMN(YQVec, yQVec, float); +DECLARE_SOA_COLUMN(GIndexCol, gIndexCol, int); +DECLARE_SOA_COLUMN(TimeStamp, timeStamp, int64_t); +// Tracks +DECLARE_SOA_COLUMN(MinAbsEtaTrack, minAbsEtaTrack, float); +DECLARE_SOA_COLUMN(MinNumItsCls, minNumItsCls, uint8_t); +DECLARE_SOA_COLUMN(MinNumTpcCls, minNumTpcCls, uint8_t); +} // namespace mixing_dstar + +DECLARE_SOA_TABLE(HfCandDstMix, "AOD", "HFCANDDSTMIX", + mixing_dstar::MD0, + mixing_dstar::PtSoftPi, + mixing_dstar::EtaSoftPi, + mixing_dstar::PhiSoftPi, + mixing_dstar::M, + mixing_dstar::Pt, + mixing_dstar::Eta, + mixing_dstar::Phi, + mixing_dstar::Y, + mixing_dstar::MlProbDstarToD0PiBkg, + mixing_dstar::MlProbDstarToD0PiPrompt, + mixing_dstar::MlProbDstarToD0PiNonPrompt, + mixing_dstar::ZVtx, + mixing_dstar::Centrality, + mixing_dstar::NPvContrib, + mixing_dstar::Occupancy, + mixing_dstar::XQVec, + mixing_dstar::YQVec, + mixing_dstar::MinAbsEtaTrack, + mixing_dstar::MinNumItsCls, + mixing_dstar::MinNumTpcCls, + mixing_dstar::GIndexCol, + mixing_dstar::TimeStamp); +} // namespace o2::aod + +/// Writes the full information in an output TTree +struct HfTreeCreatorDstarSpinAlignMixing { + Produces rowCandidateMix; + + Configurable qVecDetector{"qVecDetector", 2, "Detector for Q vector estimation (FV0A: 0, FT0M: 1, FT0C: 2)"}; + Configurable centEstimator{"centEstimator", 2, "Centrality estimator ((None: 0, FT0C: 2, FT0M: 3))"}; + Configurable occEstimator{"occEstimator", 2, "If enabled, replace number of PV contributors with occupancy estimation (0: don't use, 1: ITS, 2: FT0C)"}; + + using CollsWithQVecs = soa::Join; + using TracksWithExtra = soa::Join; + using CandDstarWSelFlag = soa::Join; + using FilteredCandDstarWSelFlagAndMl = soa::Filtered>; + + Filter filterSelectDstarCandidates = aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == true; + + Preslice dstarWithMlPerCollision = aod::hf_cand::collisionId; + + void init(InitContext const&) + { + } + + /// prongTracks is the vector of daughter tracks + /// etaMin is the minimum eta + /// nItsClsMin is the minumum number of clusters in ITS + /// nTpcClsMin is the minumum number of clusters in TPC + template + void getTrackingInfos(std::vector const& prongTracks, float& etaMin, int& nItsClsMin, int& nTpcClsMin) + { + etaMin = 10.f; + nItsClsMin = 10; + nTpcClsMin = 1000; + + for (const auto& track : prongTracks) { + if (std::abs(track.eta()) < etaMin) { + etaMin = std::abs(track.eta()); + } + if (track.itsNCls() < nItsClsMin) { + nItsClsMin = track.itsNCls(); + } + if (track.tpcNClsCrossedRows() < nTpcClsMin) { + nTpcClsMin = track.tpcNClsCrossedRows(); + } + } + } + + template + void fillCandidateTable(CollType const& collision, const T& candidate, Trk const& /*tracks*/, BcType const& /*bcs*/) + { + const auto bc = collision.template bc_as(); + const int64_t timeStamp = bc.timestamp(); + + float massD0{-1.f}; + float massDStar{-1.f}; + float etaSoftPi{-1.f}; + float phiSoftPi{-1.f}; + if (candidate.signSoftPi() > 0) { + massD0 = candidate.invMassD0(); + massDStar = candidate.invMassDstar(); + } else { + massD0 = candidate.invMassD0Bar(); + massDStar = candidate.invMassAntiDstar(); + } + etaSoftPi = RecoDecay::eta(std::array{candidate.pxSoftPi(), candidate.pySoftPi(), candidate.pzSoftPi()}); + phiSoftPi = RecoDecay::phi(std::array{candidate.pxSoftPi(), candidate.pySoftPi(), candidate.pzSoftPi()}); + + float absEtaTrackMin{-1.f}; + int numItsClsMin{-1}, numTpcClsMin{-1}; + + auto trackProng0 = candidate.template prong0_as(); + auto trackProng1 = candidate.template prong1_as(); + auto trackProng2 = candidate.template prongPi_as(); + getTrackingInfos(std::vector{trackProng0, trackProng1, trackProng2}, absEtaTrackMin, numItsClsMin, numTpcClsMin); + std::array const Qvector = getQvec(collision, qVecDetector.value); + + rowCandidateMix( + massD0, + candidate.ptSoftPi(), + etaSoftPi, + phiSoftPi, + massDStar, + candidate.pt(), + candidate.eta(), + candidate.phi(), + candidate.y(constants::physics::MassDStar), + candidate.mlProbDstarToD0Pi()[0], + candidate.mlProbDstarToD0Pi()[1], + candidate.mlProbDstarToD0Pi()[2], + collision.posZ(), + getCentralityColl(collision, centEstimator), + collision.numContrib(), + getOccupancyColl(collision, occEstimator), + Qvector[0], + Qvector[1], + absEtaTrackMin, + numItsClsMin, + numTpcClsMin, + collision.globalIndex(), + timeStamp); + } + + void processData(CollsWithQVecs const& collisions, + FilteredCandDstarWSelFlagAndMl const& dstarCandidates, + TracksWithExtra const& tracks, + aod::BCsWithTimestamps const& bcWithTimeStamps) + { + for (const auto& collision : collisions) { + auto thisCollId = collision.globalIndex(); + auto groupedDstarCandidates = dstarCandidates.sliceBy(dstarWithMlPerCollision, thisCollId); + for (const auto& dstarCandidate : groupedDstarCandidates) { + fillCandidateTable(collision, dstarCandidate, tracks, bcWithTimeStamps); + } + } + } + PROCESS_SWITCH(HfTreeCreatorDstarSpinAlignMixing, processData, "Process data", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/D2H/Tasks/CMakeLists.txt b/PWGHF/D2H/Tasks/CMakeLists.txt index a4e036cd80c..19a61637c19 100644 --- a/PWGHF/D2H/Tasks/CMakeLists.txt +++ b/PWGHF/D2H/Tasks/CMakeLists.txt @@ -19,6 +19,11 @@ o2physics_add_dpl_workflow(task-b0-reduced PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(task-b0-to-jpsi-k0-star-reduced + SOURCES taskB0ToJpsiK0StarReduced.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(task-bplus SOURCES taskBplus.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/D2H/Tasks/taskB0ToJpsiK0StarReduced.cxx b/PWGHF/D2H/Tasks/taskB0ToJpsiK0StarReduced.cxx new file mode 100644 index 00000000000..1aa8c73979b --- /dev/null +++ b/PWGHF/D2H/Tasks/taskB0ToJpsiK0StarReduced.cxx @@ -0,0 +1,726 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file taskB0ToJpsiK0StarReduced.cxx +/// \brief B0 → Jpsi K*0 → (µ+ µ-) (K+pi-) analysis task +/// +/// \author Fabrizio Chinu , Università degli Studi and INFN Torino +/// \author Fabrizio Grosa , CERN + +#include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/HfMlResponseB0ToJpsiK0StarReduced.h" +#include "PWGHF/Core/SelectorCuts.h" +#include "PWGHF/D2H/DataModel/ReducedDataModel.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsPid.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelectorPID.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::aod; +using namespace o2::analysis; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::aod::pid_tpc_tof_utils; + +namespace o2::aod +{ +namespace hf_cand_b0tojpsik0star_lite +{ +DECLARE_SOA_COLUMN(PtJpsi, ptJpsi, float); //! Transverse momentum of Jpsi daughter candidate (GeV/c) +DECLARE_SOA_COLUMN(PtBach0, ptBach0, float); //! Transverse momentum of bachelor kaon(<- K*0) (GeV/c) +DECLARE_SOA_COLUMN(PtBach1, ptBach1, float); //! Transverse momentum of bachelor kaon(<- K*0) (GeV/c) +DECLARE_SOA_COLUMN(ItsNClsJpsiDauPos, itsNClsJpsiDauPos, int); //! Number of clusters in ITS +DECLARE_SOA_COLUMN(TpcNClsCrossedRowsJpsiDauPos, tpcNClsCrossedRowsJpsiDauPos, int); //! Number of TPC crossed rows +DECLARE_SOA_COLUMN(ItsChi2NClJpsiDauPos, itsChi2NClJpsiDauPos, float); //! ITS chi2 / Number of clusters +DECLARE_SOA_COLUMN(TpcChi2NClJpsiDauPos, tpcChi2NClJpsiDauPos, float); //! TPC chi2 / Number of clusters +DECLARE_SOA_COLUMN(AbsEtaJpsiDauPos, absEtaJpsiDauPos, float); //! |eta| +DECLARE_SOA_COLUMN(ItsNClsJpsiDauNeg, itsNClsJpsiDauNeg, int); //! Number of clusters in ITS +DECLARE_SOA_COLUMN(TpcNClsCrossedRowsJpsiDauNeg, tpcNClsCrossedRowsJpsiDauNeg, int); //! Number of TPC crossed rows +DECLARE_SOA_COLUMN(ItsChi2NClJpsiDauNeg, itsChi2NClJpsiDauNeg, float); //! ITS chi2 / Number of clusters +DECLARE_SOA_COLUMN(TpcChi2NClJpsiDauNeg, tpcChi2NClJpsiDauNeg, float); //! TPC chi2 / Number of clusters +DECLARE_SOA_COLUMN(AbsEtaJpsiDauNeg, absEtaJpsiDauNeg, float); //! |eta| +DECLARE_SOA_COLUMN(ItsNClsLfTrack0, itsNClsLfTrack0, int); //! Number of clusters in ITS +DECLARE_SOA_COLUMN(TpcNClsCrossedRowsLfTrack0, tpcNClsCrossedRowsLfTrack0, int); //! Number of TPC crossed rows +DECLARE_SOA_COLUMN(ItsChi2NClLfTrack0, itsChi2NClLfTrack0, float); //! ITS chi2 / Number of clusters +DECLARE_SOA_COLUMN(TpcChi2NClLfTrack0, tpcChi2NClLfTrack0, float); //! TPC chi2 / Number of clusters +DECLARE_SOA_COLUMN(AbsEtaLfTrack0, absEtaLfTrack0, float); //! |eta| +DECLARE_SOA_COLUMN(ItsNClsLfTrack1, itsNClsLfTrack1, int); //! Number of clusters in ITS +DECLARE_SOA_COLUMN(TpcNClsCrossedRowsLfTrack1, tpcNClsCrossedRowsLfTrack1, int); //! Number of TPC crossed rows +DECLARE_SOA_COLUMN(ItsChi2NClLfTrack1, itsChi2NClLfTrack1, float); //! ITS chi2 / Number of clusters +DECLARE_SOA_COLUMN(TpcChi2NClLfTrack1, tpcChi2NClLfTrack1, float); //! TPC chi2 / Number of clusters +DECLARE_SOA_COLUMN(AbsEtaLfTrack1, absEtaLfTrack1, float); //! |eta| +DECLARE_SOA_COLUMN(MJpsi, mJpsi, float); //! Invariant mass of Jpsi daughter candidates (GeV/c) +DECLARE_SOA_COLUMN(MK0Star, mK0Star, float); //! Invariant mass of K*0 daughter candidates (GeV/c) +DECLARE_SOA_COLUMN(M, m, float); //! Invariant mass of candidate (GeV/c2) +DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(PtGen, ptGen, float); //! Transverse momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(P, p, float); //! Momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(Y, y, float); //! Rapidity of candidate +DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity of candidate +DECLARE_SOA_COLUMN(Phi, phi, float); //! Azimuth angle of candidate +DECLARE_SOA_COLUMN(E, e, float); //! Energy of candidate (GeV) +DECLARE_SOA_COLUMN(NSigTpcKaBachelor0, nSigTpcKaBachelor0, float); //! TPC Nsigma separation for bachelor 0 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTofKaBachelor0, nSigTofKaBachelor0, float); //! TOF Nsigma separation for bachelor 0 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofKaBachelor0, nSigTpcTofKaBachelor0, float); //! Combined TPC and TOF Nsigma separation for bachelor 0 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcKaBachelor1, nSigTpcKaBachelor1, float); //! TPC Nsigma separation for bachelor 1 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTofKaBachelor1, nSigTofKaBachelor1, float); //! TOF Nsigma separation for bachelor 1 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofKaBachelor1, nSigTpcTofKaBachelor1, float); //! Combined TPC and TOF Nsigma separation for bachelor 1 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcPiBachelor0, nSigTpcPiBachelor0, float); //! TPC Nsigma separation for bachelor 0 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTofPiBachelor0, nSigTofPiBachelor0, float); //! TOF Nsigma separation for bachelor 0 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofPiBachelor0, nSigTpcTofPiBachelor0, float); //! Combined TPC and TOF Nsigma separation for bachelor 0 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcPiBachelor1, nSigTpcPiBachelor1, float); //! TPC Nsigma separation for bachelor 1 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTofPiBachelor1, nSigTofPiBachelor1, float); //! TOF Nsigma separation for bachelor 1 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofPiBachelor1, nSigTpcTofPiBachelor1, float); //! Combined TPC and TOF Nsigma separation for bachelor 1 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcMuJpsiDauPos, nSigTpcMuJpsiDauPos, float); //! TPC Nsigma separation for Jpsi DauPos with muon mass hypothesis +DECLARE_SOA_COLUMN(NSigTofMuJpsiDauPos, nSigTofMuJpsiDauPos, float); //! TOF Nsigma separation for Jpsi DauPos with muon mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofMuJpsiDauPos, nSigTpcTofMuJpsiDauPos, float); //! Combined TPC and TOF Nsigma separation for Jpsi prong0 with muon mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcMuJpsiDauNeg, nSigTpcMuJpsiDauNeg, float); //! TPC Nsigma separation for Jpsi DauNeg with muon mass hypothesis +DECLARE_SOA_COLUMN(NSigTofMuJpsiDauNeg, nSigTofMuJpsiDauNeg, float); //! TOF Nsigma separation for Jpsi DauNeg with muon mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofMuJpsiDauNeg, nSigTpcTofMuJpsiDauNeg, float); //! Combined TPC and TOF Nsigma separation for Jpsi prong1 with muon mass hypothesis +DECLARE_SOA_COLUMN(DecayLength, decayLength, float); //! Decay length of candidate (cm) +DECLARE_SOA_COLUMN(DecayLengthXY, decayLengthXY, float); //! Transverse decay length of candidate (cm) +DECLARE_SOA_COLUMN(DecayLengthNormalised, decayLengthNormalised, float); //! Normalised decay length of candidate +DECLARE_SOA_COLUMN(DecayLengthXYNormalised, decayLengthXYNormalised, float); //! Normalised transverse decay length of candidate +DECLARE_SOA_COLUMN(CtXY, ctXY, float); //! Pseudo-proper decay length of candidate +DECLARE_SOA_COLUMN(ImpactParameterProduct, impactParameterProduct, float); //! Impact parameter product of B daughters +DECLARE_SOA_COLUMN(ImpactParameterProductJpsi, impactParameterProductJpsi, float); //! Impact parameter product of Jpsi daughters +DECLARE_SOA_COLUMN(ImpactParameterProductK0Star, impactParameterProductK0Star, float); //! Impact parameter product of K*0 daughters +DECLARE_SOA_COLUMN(ImpactParameterJpsiDauPos, impactParameterJpsiDauPos, float); //! Impact parameter of Jpsi daughter candidate +DECLARE_SOA_COLUMN(ImpactParameterJpsiDauNeg, impactParameterJpsiDauNeg, float); //! Impact parameter of Jpsi daughter candidate +DECLARE_SOA_COLUMN(ImpactParameterLfTrack0, impactParameterLfTrack0, float); //! Impact parameter of K*0 daughter candidate +DECLARE_SOA_COLUMN(ImpactParameterLfTrack1, impactParameterLfTrack1, float); //! Impact parameter of K*0 daughter candidate +DECLARE_SOA_COLUMN(Cpa, cpa, float); //! Cosine pointing angle of candidate +DECLARE_SOA_COLUMN(CpaXY, cpaXY, float); //! Cosine pointing angle of candidate in transverse plane +DECLARE_SOA_COLUMN(CpaJpsi, cpaJpsi, float); //! Cosine pointing angle of Jpsi daughter candidate +DECLARE_SOA_COLUMN(CpaXYJpsi, cpaXYJpsi, float); //! Cosine pointing angle in transverse plane of Jpsi daughter candidate +DECLARE_SOA_COLUMN(MaxNormalisedDeltaIP, maxNormalisedDeltaIP, float); //! Maximum normalized difference between measured and expected impact parameter of candidate prongs +DECLARE_SOA_COLUMN(MlScoreSig, mlScoreSig, float); //! ML score for signal class +DECLARE_SOA_COLUMN(IsSelB0KPi, isSelB0KPi, int8_t); //! Selection-step bitmask passed under the KPi K*0 mass hypothesis (see SelectionStep) +DECLARE_SOA_COLUMN(IsSelB0PiK, isSelB0PiK, int8_t); //! Selection-step bitmask passed under the PiK K*0 mass hypothesis (see SelectionStep) +DECLARE_SOA_COLUMN(FlagWrongCollision, flagWrongCollision, int8_t); //! Flag for association with wrong collision +} // namespace hf_cand_b0tojpsik0star_lite + +DECLARE_SOA_TABLE(HfRedCandB0Lites, "AOD", "HFREDCANDB0LITE", //! Table with some B0 properties + hf_cand_b0tojpsik0star_lite::M, + hf_cand_b0tojpsik0star_lite::Pt, + hf_cand_b0tojpsik0star_lite::Eta, + hf_cand_b0tojpsik0star_lite::Phi, + hf_cand_b0tojpsik0star_lite::Y, + hf_cand_b0tojpsik0star_lite::Cpa, + hf_cand_b0tojpsik0star_lite::CpaXY, + hf_cand::Chi2PCA, + hf_cand_b0tojpsik0star_lite::DecayLength, + hf_cand_b0tojpsik0star_lite::DecayLengthXY, + hf_cand_b0tojpsik0star_lite::DecayLengthNormalised, + hf_cand_b0tojpsik0star_lite::DecayLengthXYNormalised, + hf_cand_b0tojpsik0star_lite::CtXY, + hf_cand_b0tojpsik0star_lite::ImpactParameterProduct, + hf_cand_b0tojpsik0star_lite::ImpactParameterProductJpsi, + hf_cand_b0tojpsik0star_lite::ImpactParameterProductK0Star, + hf_cand_b0tojpsik0star_lite::MaxNormalisedDeltaIP, + hf_cand_b0tojpsik0star_lite::MlScoreSig, + hf_cand_b0tojpsik0star_lite::IsSelB0KPi, + hf_cand_b0tojpsik0star_lite::IsSelB0PiK, + // Jpsi meson features + hf_cand_b0tojpsik0star_lite::MJpsi, + hf_cand_b0tojpsik0star_lite::PtJpsi, + hf_cand_b0tojpsik0star_lite::MK0Star, + hf_cand_b0tojpsik0star_lite::ImpactParameterJpsiDauPos, + hf_cand_b0tojpsik0star_lite::ImpactParameterJpsiDauNeg, + hf_cand_b0tojpsik0star_lite::ImpactParameterLfTrack0, + hf_cand_b0tojpsik0star_lite::ImpactParameterLfTrack1, + // Jpsi daughter features + hf_cand_b0tojpsik0star_lite::ItsNClsJpsiDauPos, + hf_cand_b0tojpsik0star_lite::TpcNClsCrossedRowsJpsiDauPos, + hf_cand_b0tojpsik0star_lite::ItsChi2NClJpsiDauPos, + hf_cand_b0tojpsik0star_lite::TpcChi2NClJpsiDauPos, + hf_cand_b0tojpsik0star_lite::AbsEtaJpsiDauPos, + hf_cand_b0tojpsik0star_lite::ItsNClsJpsiDauNeg, + hf_cand_b0tojpsik0star_lite::TpcNClsCrossedRowsJpsiDauNeg, + hf_cand_b0tojpsik0star_lite::ItsChi2NClJpsiDauNeg, + hf_cand_b0tojpsik0star_lite::TpcChi2NClJpsiDauNeg, + hf_cand_b0tojpsik0star_lite::AbsEtaJpsiDauNeg, + // K0* features + hf_cand_b0tojpsik0star_lite::PtBach0, + hf_cand_b0tojpsik0star_lite::ItsNClsLfTrack0, + hf_cand_b0tojpsik0star_lite::TpcNClsCrossedRowsLfTrack0, + hf_cand_b0tojpsik0star_lite::ItsChi2NClLfTrack0, + hf_cand_b0tojpsik0star_lite::TpcChi2NClLfTrack0, + hf_cand_b0tojpsik0star_lite::AbsEtaLfTrack0, + hf_cand_b0tojpsik0star_lite::NSigTpcKaBachelor0, + hf_cand_b0tojpsik0star_lite::NSigTofKaBachelor0, + hf_cand_b0tojpsik0star_lite::NSigTpcTofKaBachelor0, + hf_cand_b0tojpsik0star_lite::NSigTpcPiBachelor0, + hf_cand_b0tojpsik0star_lite::NSigTofPiBachelor0, + hf_cand_b0tojpsik0star_lite::NSigTpcTofPiBachelor0, + hf_cand_b0tojpsik0star_lite::PtBach1, + hf_cand_b0tojpsik0star_lite::ItsNClsLfTrack1, + hf_cand_b0tojpsik0star_lite::TpcNClsCrossedRowsLfTrack1, + hf_cand_b0tojpsik0star_lite::ItsChi2NClLfTrack1, + hf_cand_b0tojpsik0star_lite::TpcChi2NClLfTrack1, + hf_cand_b0tojpsik0star_lite::AbsEtaLfTrack1, + hf_cand_b0tojpsik0star_lite::NSigTpcKaBachelor1, + hf_cand_b0tojpsik0star_lite::NSigTofKaBachelor1, + hf_cand_b0tojpsik0star_lite::NSigTpcTofKaBachelor1, + hf_cand_b0tojpsik0star_lite::NSigTpcPiBachelor1, + hf_cand_b0tojpsik0star_lite::NSigTofPiBachelor1, + hf_cand_b0tojpsik0star_lite::NSigTpcTofPiBachelor1, + // MC truth + hf_cand_mc_flag::FlagMcMatchRec, + hf_cand_mc_flag::FlagMcDecayChanRec, + hf_cand_mc_flag::OriginMcRec, + hf_cand_b0tojpsik0star_lite::FlagWrongCollision, + hf_cand_b0tojpsik0star_lite::PtGen); + +} // namespace o2::aod + +// string definitions, used for histogram axis labels +const TString stringPt = "#it{p}_{T} (GeV/#it{c})"; +const TString stringPtJpsi = "#it{p}_{T}(Jpsi) (GeV/#it{c});"; +const TString b0CandTitle = "B^{0} candidates;"; +const TString entries = "entries"; +const TString b0CandMatch = "B^{0} candidates (matched);"; +const TString b0CandUnmatch = "B^{0} candidates (unmatched);"; +const TString mcParticleMatched = "MC particles (matched);"; + +/// B0 analysis task +struct HfTaskB0ToJpsiK0StarReduced { + Produces hfRedCandB0Lite; + // Produces hfRedB0McCheck; + + Configurable selectionFlagB0{"selectionFlagB0", 1, "Selection Flag for B0"}; + Configurable yCandGenMax{"yCandGenMax", 0.5, "max. gen particle rapidity"}; + Configurable yCandRecoMax{"yCandRecoMax", 0.8, "max. cand. rapidity"}; + Configurable etaTrackMax{"etaTrackMax", 0.8, "max. track pseudo-rapidity"}; + Configurable ptTrackMin{"ptTrackMin", 0.1, "min. track transverse momentum"}; + Configurable fillBackground{"fillBackground", false, "Flag to enable filling of background histograms/sparses/tree (only MC)"}; + Configurable downSampleBkgFactor{"downSampleBkgFactor", 1., "Fraction of background candidates to keep for ML trainings"}; + Configurable ptMaxForDownSample{"ptMaxForDownSample", 10., "Maximum pt for the application of the downsampling factor"}; + Configurable useJpsiPdgMass{"useJpsiPdgMass", true, "Whether to use J/Psi PDG mass for B+ candidate mass evaluation or to use the invariant mass of the two prongs"}; + Configurable useK0StarPdgMass{"useK0StarPdgMass", true, "Whether to use K*0 PDG mass for B+ candidate mass evaluation or to use the invariant mass of the two prongs"}; + // topological cuts + Configurable> binsPt{"binsPt", std::vector{hf_cuts_b0_to_jpsi_k0star::vecBinsPt}, "pT bin limits"}; + Configurable> cuts{"cuts", {hf_cuts_b0_to_jpsi_k0star::Cuts[0], hf_cuts_b0_to_jpsi_k0star::NBinsPt, hf_cuts_b0_to_jpsi_k0star::NCutVars, hf_cuts_b0_to_jpsi_k0star::labelsPt, hf_cuts_b0_to_jpsi_k0star::labelsCutVar}, "B0 candidate selection per pT bin"}; + // Enable PID + Configurable kaonPidMethod{"kaonPidMethod", PidMethod::TpcOrTof, "PID selection method for the bachelor kaon (PidMethod::NoPid: none, PidMethod::TpcOrTof: TPC or TOF, PidMethod::TpcAndTof: TPC and TOF)"}; + Configurable pionPidMethod{"pionPidMethod", PidMethod::TpcOrTof, "PID selection method for the bachelor pion (PidMethod::NoPid: none, PidMethod::TpcOrTof: TPC or TOF, PidMethod::TpcAndTof: TPC and TOF)"}; + Configurable acceptPIDNotApplicable{"acceptPIDNotApplicable", true, "Switch to accept Status::NotApplicable [(NotApplicable for one detector) and (NotApplicable or Conditional for the other)] in PID selection"}; + // TPC PID + Configurable ptPidTpcMin{"ptPidTpcMin", 0.15, "Lower bound of track pT for TPC PID"}; + Configurable ptPidTpcMax{"ptPidTpcMax", 20., "Upper bound of track pT for TPC PID"}; + Configurable nSigmaTpcMax{"nSigmaTpcMax", 5., "Nsigma cut on TPC only"}; + Configurable nSigmaTpcCombinedMax{"nSigmaTpcCombinedMax", 5., "Nsigma cut on TPC combined with TOF"}; + // TOF PID + Configurable ptPidTofMin{"ptPidTofMin", 0.15, "Lower bound of track pT for TOF PID"}; + Configurable ptPidTofMax{"ptPidTofMax", 20., "Upper bound of track pT for TOF PID"}; + Configurable nSigmaTofMax{"nSigmaTofMax", 5., "Nsigma cut on TOF only"}; + Configurable nSigmaTofCombinedMax{"nSigmaTofCombinedMax", 5., "Nsigma cut on TOF combined with TPC"}; + // B0 ML inference + Configurable> binsPtB0Ml{"binsPtB0Ml", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; + Configurable> cutDirB0Ml{"cutDirB0Ml", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; + Configurable> cutsB0Ml{"cutsB0Ml", {hf_cuts_ml::Cuts[0], hf_cuts_ml::NBinsPt, hf_cuts_ml::NCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "ML selections per pT bin"}; + Configurable nClassesB0Ml{"nClassesB0Ml", static_cast(hf_cuts_ml::NCutScores), "Number of classes in ML model"}; + Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature1", "feature2"}, "Names of ML model input features"}; + // CCDB configuration + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"path_ccdb/BDT_BS/"}, "Paths of models on CCDB"}; + Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_BSToJpsiPhi.onnx"}, "ONNX file names for each pT bin (if not from CCDB full path)"}; + Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB"}; + Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; + + TrackSelectorKa selectorKaon; + TrackSelectorPi selectorPion; + o2::analysis::HfMlResponseB0ToJpsiK0StarReduced hfMlResponse; + o2::ccdb::CcdbApi ccdbApi; + + using TracksKaon = soa::Join; + std::vector outputMl; + + // Filter filterSelectCandidates = (aod::hf_sel_candidate_bplus::isSelBsToJpsiPi >= selectionFlagBs); + + HistogramRegistry registry{"registry"}; + + void init(InitContext&) + { + std::array processFuncData{doprocessData, doprocessDataWithB0Ml}; + if ((std::accumulate(processFuncData.begin(), processFuncData.end(), 0)) > 1) { + LOGP(fatal, "Only one process function for data can be enabled at a time."); + } + std::array processFuncMc{doprocessMc, doprocessMcWithB0Ml}; + if ((std::accumulate(processFuncMc.begin(), processFuncMc.end(), 0)) > 1) { + LOGP(fatal, "Only one process function for MC can be enabled at a time."); + } + + if (kaonPidMethod < 0 || kaonPidMethod >= PidMethod::NPidMethods || pionPidMethod < 0 || pionPidMethod >= PidMethod::NPidMethods) { + LOGP(fatal, "Invalid PID option in configurable, please set 0 (no PID), 1 (TPC or TOF), or 2 (TPC and TOF)"); + } + + if (kaonPidMethod != PidMethod::NoPid) { + selectorKaon.setRangePtTpc(ptPidTpcMin, ptPidTpcMax); + selectorKaon.setRangeNSigmaTpc(-nSigmaTpcMax, nSigmaTpcMax); + selectorKaon.setRangeNSigmaTpcCondTof(-nSigmaTpcCombinedMax, nSigmaTpcCombinedMax); + selectorKaon.setRangePtTof(ptPidTofMin, ptPidTofMax); + selectorKaon.setRangeNSigmaTof(-nSigmaTofMax, nSigmaTofMax); + selectorKaon.setRangeNSigmaTofCondTpc(-nSigmaTofCombinedMax, nSigmaTofCombinedMax); + } + + if (pionPidMethod != PidMethod::NoPid) { + selectorPion.setRangePtTpc(ptPidTpcMin, ptPidTpcMax); + selectorPion.setRangeNSigmaTpc(-nSigmaTpcMax, nSigmaTpcMax); + selectorPion.setRangeNSigmaTpcCondTof(-nSigmaTpcCombinedMax, nSigmaTpcCombinedMax); + selectorPion.setRangePtTof(ptPidTofMin, ptPidTofMax); + selectorPion.setRangeNSigmaTof(-nSigmaTofMax, nSigmaTofMax); + selectorPion.setRangeNSigmaTofCondTpc(-nSigmaTofCombinedMax, nSigmaTofCombinedMax); + } + + const AxisSpec axisMassB0{150, 4.5, 6.0}; + const AxisSpec axisMassJpsi{600, 2.8f, 3.4f}; + const AxisSpec axisMassK0Star{200, 0.9f, 1.1f}; + const AxisSpec axisPtProng{100, 0., 10.}; + const AxisSpec axisImpactPar{200, -0.05, 0.05}; + const AxisSpec axisPtJpsi{100, 0., 50.}; + const AxisSpec axisRapidity{100, -2., 2.}; + const AxisSpec axisPtB{(std::vector)binsPt, "#it{p}_{T}^{B^{0}} (GeV/#it{c})"}; + const AxisSpec axisPtK0Star{100, 0.f, 10.f}; + + registry.add("hMass", b0CandTitle + "inv. mass J/#Psi K*^{0} (GeV/#it{c}^{2});" + stringPt, {HistType::kTH2F, {axisMassB0, axisPtB}}); + registry.add("hMassJpsi", b0CandTitle + "inv. mass #mu^{+}#mu^{#minus} (GeV/#it{c}^{2});" + stringPt, {HistType::kTH2F, {axisMassJpsi, axisPtJpsi}}); + registry.add("hMassK0Star", b0CandTitle + "inv. mass K^{+}#pi^{#minus} (GeV/#it{c}^{2});" + stringPt, {HistType::kTH2F, {axisMassK0Star, axisPtK0Star}}); + + // histograms processMC + if (doprocessMc || doprocessMcWithB0Ml) { + registry.add("hPtJpsiGen", mcParticleMatched + "J/#Psi #it{p}_{T}^{gen} (GeV/#it{c}); B^{0} " + stringPt, {HistType::kTH2F, {axisPtProng, axisPtB}}); + registry.add("hPtK0StarGen", mcParticleMatched + "K*^{0} #it{p}_{T}^{gen} (GeV/#it{c}); B^{0} " + stringPt, {HistType::kTH2F, {axisPtK0Star, axisPtB}}); + registry.add("hYGenWithProngsInAcceptance", mcParticleMatched + "B^{0} #it{p}_{T}^{gen} (GeV/#it{c}); B^{0} #it{y}", {HistType::kTH2F, {axisPtProng, axisRapidity}}); + registry.add("hMassRecSig", b0CandMatch + "inv. mass J/#Psi K*^{0} (GeV/#it{c}^{2}); B^{0} " + stringPt, {HistType::kTH2F, {axisMassB0, axisPtB}}); + registry.add("hMassJpsiRecSig", b0CandMatch + "inv. mass #mu^{+}#mu^{#minus} (GeV/#it{c}^{2}); J/#Psi " + stringPt, {HistType::kTH2F, {axisMassJpsi, axisPtJpsi}}); + registry.add("hMassK0StarRecSig", b0CandMatch + "inv. mass K^{+}#pi^{#minus} (GeV/#it{c}^{2}); K*^{0} " + stringPt, {HistType::kTH2F, {axisMassK0Star, axisPtK0Star}}); + registry.add("hMassRecBg", b0CandUnmatch + "inv. mass J/#Psi K*^{0} (GeV/#it{c}^{2}); B^{0} " + stringPt, {HistType::kTH2F, {axisMassB0, axisPtB}}); + registry.add("hMassJpsiRecBg", b0CandUnmatch + "inv. mass #mu^{+}#mu^{#minus} (GeV/#it{c}^{2}); J/#Psi " + stringPt, {HistType::kTH2F, {axisMassJpsi, axisPtJpsi}}); + registry.add("hMassK0StarRecBg", b0CandUnmatch + "inv. mass K^{+}#pi^{#minus} (GeV/#it{c}^{2}); K*^{0} " + stringPt, {HistType::kTH2F, {axisMassK0Star, axisPtK0Star}}); + } + + if (doprocessDataWithB0Ml || doprocessMcWithB0Ml) { + hfMlResponse.configure(binsPtB0Ml, cutsB0Ml, cutDirB0Ml, nClassesB0Ml); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdbUrl); + hfMlResponse.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + } else { + hfMlResponse.setModelPathsLocal(onnxFileNames); + } + hfMlResponse.cacheInputFeaturesIndices(namesInputFeatures); + hfMlResponse.init(); + } + } + + /// Selection of B0 daughter in geometrical acceptance + /// \param etaProng is the pseudorapidity of B0 prong + /// \param ptProng is the pT of B0 prong + /// \return true if prong is in geometrical acceptance + template + bool isProngInAcceptance(const T& etaProng, const T& ptProng) + { + return std::abs(etaProng) <= etaTrackMax && ptProng >= ptTrackMin; + } + + /// Calculate pseudorapidity from track tan(lambda) + /// \param tgl is the track tangent of the dip angle + /// \return pseudorapidity + float absEta(float tgl) + { + return std::abs(std::log(std::tan(o2::constants::math::PIQuarter - 0.5f * std::atan(tgl)))); + } + + /// Fill candidate information at reconstruction level + /// \param doMc is the flag to enable the filling with MC information + /// \param withB0Ml is the flag to enable the filling with ML scores for the B0 candidate + /// \param candidate is the B0 candidate + /// \param candidatesJpsi is the table with Jpsi candidates + template + void fillCand(Cand const& candidate, + aod::HfRedJpsis const& /*candidatesJpsi*/, + aod::HfRedBach0Tracks const&, + aod::HfRedBach1Tracks const&) + { + auto ptCandB0 = candidate.pt(); + auto invMassB0KPi = HfHelper::invMassB0ToJpsiK0Star(candidate, useJpsiPdgMass, useK0StarPdgMass, true); + auto invMassB0PiK = HfHelper::invMassB0ToJpsiK0Star(candidate, useJpsiPdgMass, useK0StarPdgMass, false); + auto candJpsi = candidate.template jpsi_as(); + auto candLfDau0 = candidate.template prong0K0Star_as(); + auto candLfDau1 = candidate.template prong1K0Star_as(); + auto const pVecMu0 = candidate.pVectorProng0(); + auto const pVecMu1 = candidate.pVectorProng1(); + auto const pVecLfDau0 = candidate.pVectorProng2(); + auto const pVecLfDau1 = candidate.pVectorProng3(); + auto ptJpsi = RecoDecay::pt(pVecMu0, pVecMu1); + auto ptK0Star = RecoDecay::pt(pVecLfDau0, pVecLfDau1); + auto invMassJpsi = RecoDecay::m(std::array{pVecMu0, pVecMu1}, std::array{o2::constants::physics::MassMuonPlus, o2::constants::physics::MassMuonMinus}); + auto invMassK0StarKPi = RecoDecay::m(std::array{pVecLfDau0, pVecLfDau1}, std::array{o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); + auto invMassK0StarPiK = RecoDecay::m(std::array{pVecLfDau0, pVecLfDau1}, std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus}); + + int8_t flagMcMatchRec{0}, flagMcDecayChanRec{0}, flagWrongCollision{0}; + bool isSignal = false; + if constexpr (DoMc) { + flagMcMatchRec = candidate.flagMcMatchRec(); + flagMcDecayChanRec = candidate.flagMcDecayChanRec(); + flagWrongCollision = candidate.flagWrongCollision(); + isSignal = std::abs(flagMcMatchRec) == o2::hf_decay::hf_cand_beauty::B0ToJpsiPiK && + flagMcDecayChanRec == o2::hf_decay::hf_cand_beauty::B0ToJpsiKstar0; + } + + int8_t statusB0KPi{0}; + int8_t statusB0PiK{0}; + SETBIT(statusB0KPi, SelectionStep::RecoSkims); + SETBIT(statusB0PiK, SelectionStep::RecoSkims); + + // topological selection for the two K*0 mass hypotheses + bool selKPi = HfHelper::selectionB0ToJpsiK0StarTopol(candidate, cuts, binsPt, useJpsiPdgMass, useK0StarPdgMass, true); + bool selPiK = HfHelper::selectionB0ToJpsiK0StarTopol(candidate, cuts, binsPt, useJpsiPdgMass, useK0StarPdgMass, false); + + if (!selKPi && !selPiK && selectionFlagB0 >= BIT(SelectionStep::RecoTopol) * 2 - 1) { + return; + } + if (selKPi) { + SETBIT(statusB0KPi, SelectionStep::RecoTopol); + } + if (selPiK) { + SETBIT(statusB0PiK, SelectionStep::RecoTopol); + } + + // track-level PID selection + // KPi: LfTrack0 as K and LfTrack1 as π ; PiK: LfTrack0 as π and LfTrack1 as K + if (kaonPidMethod != PidMethod::NoPid || pionPidMethod != PidMethod::NoPid) { + int pidKa0{TrackSelectorPID::Status::NotApplicable}; + int pidKa1{TrackSelectorPID::Status::NotApplicable}; + int pidPi0{TrackSelectorPID::Status::NotApplicable}; + int pidPi1{TrackSelectorPID::Status::NotApplicable}; + if (kaonPidMethod == PidMethod::TpcOrTof) { + pidKa0 = selectorKaon.statusTpcOrTof(candLfDau0); + pidKa1 = selectorKaon.statusTpcOrTof(candLfDau1); + } else if (kaonPidMethod == PidMethod::TpcAndTof) { + pidKa0 = selectorKaon.statusTpcAndTof(candLfDau0); + pidKa1 = selectorKaon.statusTpcAndTof(candLfDau1); + } + if (pionPidMethod == PidMethod::TpcOrTof) { + pidPi0 = selectorPion.statusTpcOrTof(candLfDau0); + pidPi1 = selectorPion.statusTpcOrTof(candLfDau1); + } else if (pionPidMethod == PidMethod::TpcAndTof) { + pidPi0 = selectorPion.statusTpcAndTof(candLfDau0); + pidPi1 = selectorPion.statusTpcAndTof(candLfDau1); + } + bool const pidKPi = HfHelper::selectionB0ToJpsiK0StarPid(pidKa0, acceptPIDNotApplicable.value) && + HfHelper::selectionB0ToJpsiK0StarPid(pidPi1, acceptPIDNotApplicable.value); + bool const pidPiK = HfHelper::selectionB0ToJpsiK0StarPid(pidPi0, acceptPIDNotApplicable.value) && + HfHelper::selectionB0ToJpsiK0StarPid(pidKa1, acceptPIDNotApplicable.value); + selKPi = selKPi && pidKPi; + selPiK = selPiK && pidPiK; + if (!selKPi && !selPiK && selectionFlagB0 >= BIT(SelectionStep::RecoPID) * 2 - 1) { + return; + } + if (selKPi) { + SETBIT(statusB0KPi, SelectionStep::RecoPID); + } + if (selPiK) { + SETBIT(statusB0PiK, SelectionStep::RecoPID); + } + } + + // ML selection, evaluated for each hypothesis that survived topological + PID selection + float mlScoreSigKPi = -1; + float mlScoreSigPiK = -1; + if constexpr (WithB0Ml) { + if (selKPi) { + std::vector inputFeaturesKPi = hfMlResponse.getInputFeatures(candidate, candLfDau0, candLfDau1, true); + outputMl.clear(); + selKPi = hfMlResponse.isSelectedMl(inputFeaturesKPi, ptCandB0, outputMl); + if (selKPi) { + mlScoreSigKPi = outputMl[1]; + SETBIT(statusB0KPi, SelectionStep::RecoMl); + } + } + if (selPiK) { + std::vector inputFeaturesPiK = hfMlResponse.getInputFeatures(candidate, candLfDau0, candLfDau1, false); + outputMl.clear(); + selPiK = hfMlResponse.isSelectedMl(inputFeaturesPiK, ptCandB0, outputMl); + if (selPiK) { + mlScoreSigPiK = outputMl[1]; + SETBIT(statusB0PiK, SelectionStep::RecoMl); + } + } + if (!selKPi && !selPiK && selectionFlagB0 >= BIT(SelectionStep::RecoMl) * 2 - 1) { + return; + } + } + + registry.fill(HIST("hMassJpsi"), invMassJpsi, ptJpsi); + if constexpr (DoMc) { + if (isSignal) { + registry.fill(HIST("hMassJpsiRecSig"), invMassJpsi, ptJpsi); + } else if (fillBackground) { + registry.fill(HIST("hMassJpsiRecBg"), invMassJpsi, ptJpsi); + } + } + if (selKPi) { + registry.fill(HIST("hMass"), invMassB0KPi, ptCandB0); + registry.fill(HIST("hMassK0Star"), invMassK0StarKPi, ptK0Star); + } + if (selPiK) { + registry.fill(HIST("hMass"), invMassB0PiK, ptCandB0); + registry.fill(HIST("hMassK0Star"), invMassK0StarPiK, ptK0Star); + } + if constexpr (DoMc) { + if (isSignal) { + if (selKPi) { + registry.fill(HIST("hMassRecSig"), invMassB0KPi, ptCandB0); + registry.fill(HIST("hMassK0StarRecSig"), invMassK0StarKPi, ptK0Star); + } + if (selPiK) { + registry.fill(HIST("hMassRecSig"), invMassB0PiK, ptCandB0); + registry.fill(HIST("hMassK0StarRecSig"), invMassK0StarPiK, ptK0Star); + } + } else if (fillBackground) { + if (selKPi) { + registry.fill(HIST("hMassRecBg"), invMassB0KPi, ptCandB0); + registry.fill(HIST("hMassK0StarRecBg"), invMassK0StarKPi, ptK0Star); + } + if (selPiK) { + registry.fill(HIST("hMassRecBg"), invMassB0PiK, ptCandB0); + registry.fill(HIST("hMassK0StarRecBg"), invMassK0StarPiK, ptK0Star); + } + } + } + + // downsampling for ML trainings + float const pseudoRndm = ptJpsi * 1000. - static_cast(ptJpsi * 1000); + if (ptCandB0 < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { + return; + } + + float ptMother = -1.; + if constexpr (DoMc) { + ptMother = candidate.ptMother(); + } + + auto fillTable = [&](bool isSelKPi) { + auto ctXY = isSelKPi ? candidate.ctXY(std::array{o2::constants::physics::MassMuon, o2::constants::physics::MassMuon, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}) + : candidate.ctXY(std::array{o2::constants::physics::MassMuon, o2::constants::physics::MassMuon, o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus}); + auto mlScoreSig = isSelKPi ? mlScoreSigKPi : mlScoreSigPiK; + auto invMassB0 = isSelKPi ? invMassB0KPi : invMassB0PiK; + auto invMassK0Star = isSelKPi ? invMassK0StarKPi : invMassK0StarPiK; + hfRedCandB0Lite( + // B0 - meson features + invMassB0, + ptCandB0, + candidate.eta(), + candidate.phi(), + HfHelper::yB0(candidate), + candidate.cpa(), + candidate.cpaXY(), + candidate.chi2PCA(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + ctXY, + candidate.impactParameterProduct(), + candidate.impactParameterProductJpsi(), + candidate.impactParameterProductK0Star(), + candidate.maxNormalisedDeltaIP(), + mlScoreSig, + isSelKPi ? statusB0KPi : -1, + isSelKPi ? -1 : statusB0PiK, + // J/Psi features + invMassJpsi, + ptJpsi, + invMassK0Star, + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameter2(), + candidate.impactParameter3(), + candJpsi.itsNClsDauPos(), + candJpsi.tpcNClsCrossedRowsDauPos(), + candJpsi.itsChi2NClDauPos(), + candJpsi.tpcChi2NClDauPos(), + absEta(candJpsi.tglDauPos()), + candJpsi.itsNClsDauNeg(), + candJpsi.tpcNClsCrossedRowsDauNeg(), + candJpsi.itsChi2NClDauNeg(), + candJpsi.tpcChi2NClDauNeg(), + absEta(candJpsi.tglDauNeg()), + // K*0 daughter features + candLfDau0.pt(), + candLfDau0.itsNCls(), + candLfDau0.tpcNClsCrossedRows(), + candLfDau0.itsChi2NCl(), + candLfDau0.tpcChi2NCl(), + absEta(candLfDau0.tgl()), + candLfDau0.tpcNSigmaKa(), + candLfDau0.tofNSigmaKa(), + candLfDau0.tpcTofNSigmaKa(), + candLfDau0.tpcNSigmaPi(), + candLfDau0.tofNSigmaPi(), + candLfDau0.tpcTofNSigmaPi(), + candLfDau1.pt(), + candLfDau1.itsNCls(), + candLfDau1.tpcNClsCrossedRows(), + candLfDau1.itsChi2NCl(), + candLfDau1.tpcChi2NCl(), + absEta(candLfDau1.tgl()), + candLfDau1.tpcNSigmaKa(), + candLfDau1.tofNSigmaKa(), + candLfDau1.tpcTofNSigmaKa(), + candLfDau1.tpcNSigmaPi(), + candLfDau1.tofNSigmaPi(), + candLfDau1.tpcTofNSigmaPi(), + // MC truth + flagMcMatchRec, + flagMcDecayChanRec, + isSignal, + flagWrongCollision, + ptMother); + }; + + if (statusB0KPi >= selectionFlagB0) { + fillTable(true); + } + if (statusB0PiK >= selectionFlagB0) { + fillTable(false); + } + } + + /// Fill particle histograms (gen MC truth) + void fillCandMcGen(aod::HfMcGenRedB0s::iterator const& particle) + { + auto ptParticle = particle.ptTrack(); + auto yParticle = particle.yTrack(); + if (yCandGenMax >= 0. && std::abs(yParticle) > yCandGenMax) { + return; + } + std::array ptProngs = {particle.ptProng0(), particle.ptProng1()}; + std::array etaProngs = {particle.etaProng0(), particle.etaProng1()}; + bool const prongsInAcc = isProngInAcceptance(etaProngs[0], ptProngs[0]) && isProngInAcceptance(etaProngs[1], ptProngs[1]); + + registry.fill(HIST("hPtJpsiGen"), ptProngs[0], ptParticle); + registry.fill(HIST("hPtK0StarGen"), ptProngs[1], ptParticle); + + // generated B0 with daughters in geometrical acceptance + if (prongsInAcc) { + registry.fill(HIST("hYGenWithProngsInAcceptance"), ptParticle, yParticle); + } + } + + // Process functions + void processData(aod::HfRedCandB0ToJpsiK0Star const& candidates, + aod::HfRedJpsis const& candidatesJpsi, + aod::HfRedBach0Tracks const& kaon0Tracks, + aod::HfRedBach1Tracks const& kaon1Tracks) + { + for (const auto& candidate : candidates) { + if (yCandRecoMax >= 0. && std::abs(HfHelper::yB0(candidate)) > yCandRecoMax) { + continue; + } + fillCand(candidate, candidatesJpsi, kaon0Tracks, kaon1Tracks); + } // candidate loop + } // processData + PROCESS_SWITCH(HfTaskB0ToJpsiK0StarReduced, processData, "Process data without ML for B0", true); + + void processDataWithB0Ml(aod::HfRedCandB0ToJpsiK0Star const& candidates, + aod::HfRedJpsis const& candidatesJpsi, + aod::HfRedBach0Tracks const& kaon0Tracks, + aod::HfRedBach1Tracks const& kaon1Tracks) + { + for (const auto& candidate : candidates) { + if (yCandRecoMax >= 0. && std::abs(HfHelper::yB0(candidate)) > yCandRecoMax) { + continue; + } + fillCand(candidate, candidatesJpsi, kaon0Tracks, kaon1Tracks); + } // candidate loop + } // processDataWithB0Ml + PROCESS_SWITCH(HfTaskB0ToJpsiK0StarReduced, processDataWithB0Ml, "Process data with ML for B0", false); + + void processMc(soa::Join const& candidates, + aod::HfMcGenRedB0s const& mcParticles, + aod::HfRedJpsis const& candidatesJpsi, + aod::HfRedBach0Tracks const& kaon0Tracks, + aod::HfRedBach1Tracks const& kaon1Tracks) + { + // MC rec + for (const auto& candidate : candidates) { + if (yCandRecoMax >= 0. && std::abs(HfHelper::yB0(candidate)) > yCandRecoMax) { + continue; + } + fillCand(candidate, candidatesJpsi, kaon0Tracks, kaon1Tracks); + } // rec + + // MC gen. level + for (const auto& particle : mcParticles) { + fillCandMcGen(particle); + } // gen + } // processMc + PROCESS_SWITCH(HfTaskB0ToJpsiK0StarReduced, processMc, "Process MC without ML for B0", false); + + void processMcWithB0Ml(soa::Join const& candidates, + aod::HfMcGenRedB0s const& mcParticles, + aod::HfRedJpsis const& candidatesJpsi, + aod::HfRedBach0Tracks const& kaon0Tracks, + aod::HfRedBach1Tracks const& kaon1Tracks) + { + // MC rec + for (const auto& candidate : candidates) { + if (yCandRecoMax >= 0. && std::abs(HfHelper::yB0(candidate)) > yCandRecoMax) { + continue; + } + fillCand(candidate, candidatesJpsi, kaon0Tracks, kaon1Tracks); + } // rec + + // MC gen. level + for (const auto& particle : mcParticles) { + fillCandMcGen(particle); + } // gen + } // processMcWithB0Ml + PROCESS_SWITCH(HfTaskB0ToJpsiK0StarReduced, processMcWithB0Ml, "Process MC with ML for B0", false); + +}; // struct + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/D2H/Tasks/taskBplusToJpsiKReduced.cxx b/PWGHF/D2H/Tasks/taskBplusToJpsiKReduced.cxx index 134dc6b529b..4e207739d3e 100644 --- a/PWGHF/D2H/Tasks/taskBplusToJpsiKReduced.cxx +++ b/PWGHF/D2H/Tasks/taskBplusToJpsiKReduced.cxx @@ -24,6 +24,7 @@ #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/Utils/utilsPid.h" +#include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelectorPID.h" #include diff --git a/PWGHF/D2H/Tasks/taskBsToJpsiPhiReduced.cxx b/PWGHF/D2H/Tasks/taskBsToJpsiPhiReduced.cxx index 039bc79b980..c33292fb43e 100644 --- a/PWGHF/D2H/Tasks/taskBsToJpsiPhiReduced.cxx +++ b/PWGHF/D2H/Tasks/taskBsToJpsiPhiReduced.cxx @@ -169,7 +169,7 @@ DECLARE_SOA_TABLE(HfRedCandBsLites, "AOD", "HFREDCANDBSLITE", //! Table with som hf_cand_bstojpsiphi_lite::ItsChi2NClJpsiDauNeg, hf_cand_bstojpsiphi_lite::TpcChi2NClJpsiDauNeg, hf_cand_bstojpsiphi_lite::AbsEtaJpsiDauNeg, - // kaon features + // phi features hf_cand_bstojpsiphi_lite::PtBach0, hf_cand_bstojpsiphi_lite::ItsNClsLfTrack0, hf_cand_bstojpsiphi_lite::TpcNClsCrossedRowsLfTrack0, @@ -213,10 +213,10 @@ DECLARE_SOA_TABLE(HfRedCandBsLites, "AOD", "HFREDCANDBSLITE", //! Table with som // string definitions, used for histogram axis labels const TString stringPt = "#it{p}_{T} (GeV/#it{c})"; const TString stringPtJpsi = "#it{p}_{T}(Jpsi) (GeV/#it{c});"; -const TString bSCandTitle = "B_{s}^{0} candidates;"; +const TString bsCandTitle = "B_{s}^{0} candidates;"; const TString entries = "entries"; -const TString bSCandMatch = "B_{s}^{0} candidates (matched);"; -const TString bSCandUnmatch = "B_{s}^{0} candidates (unmatched);"; +const TString bsCandMatch = "B_{s}^{0} candidates (matched);"; +const TString bsCandUnmatch = "B_{s}^{0} candidates (unmatched);"; const TString mcParticleMatched = "MC particles (matched);"; /// Bs analysis task @@ -306,12 +306,11 @@ struct HfTaskBsToJpsiPhiReduced { const AxisSpec axisPtJpsi{100, 0., 50.}; const AxisSpec axisRapidity{100, -2., 2.}; const AxisSpec axisPtB{(std::vector)binsPt, "#it{p}_{T}^{B_{s}^{0}} (GeV/#it{c})"}; - const AxisSpec axisPtKa{100, 0.f, 10.f}; const AxisSpec axisPtPhi{100, 0.f, 10.f}; - registry.add("hMass", bSCandTitle + "inv. mass J/#Psi K^{+} (GeV/#it{c}^{2});" + stringPt, {HistType::kTH2F, {axisMassBs, axisPtB}}); - registry.add("hMassJpsi", bSCandTitle + "inv. mass #mu^{+}#mu^{#minus} (GeV/#it{c}^{2});" + stringPt, {HistType::kTH2F, {axisMassJpsi, axisPtJpsi}}); - registry.add("hMassPhi", bSCandTitle + "inv. mass K^{+}K^{#minus} (GeV/#it{c}^{2});" + stringPt, {HistType::kTH2F, {axisMassPhi, axisPtPhi}}); + registry.add("hMass", bsCandTitle + "inv. mass J/#Psi K^{+} (GeV/#it{c}^{2});" + stringPt, {HistType::kTH2F, {axisMassBs, axisPtB}}); + registry.add("hMassJpsi", bsCandTitle + "inv. mass #mu^{+}#mu^{#minus} (GeV/#it{c}^{2});" + stringPt, {HistType::kTH2F, {axisMassJpsi, axisPtJpsi}}); + registry.add("hMassPhi", bsCandTitle + "inv. mass K^{+}K^{#minus} (GeV/#it{c}^{2});" + stringPt, {HistType::kTH2F, {axisMassPhi, axisPtPhi}}); // histograms processMC if (doprocessMc || doprocessMcWithBsMl) { @@ -319,12 +318,12 @@ struct HfTaskBsToJpsiPhiReduced { registry.add("hPtPhiGen", mcParticleMatched + "#phi #it{p}_{T}^{gen} (GeV/#it{c}); B_{s}^{0} " + stringPt, {HistType::kTH2F, {axisPtProng, axisPtB}}); registry.add("hPtKGen", mcParticleMatched + "Kaon #it{p}_{T}^{gen} (GeV/#it{c}); B_{s}^{0} " + stringPt, {HistType::kTH2F, {axisPtProng, axisPtB}}); registry.add("hYGenWithProngsInAcceptance", mcParticleMatched + "B_{s}^{0} #it{p}_{T}^{gen} (GeV/#it{c}); B_{s}^{0} #it{y}", {HistType::kTH2F, {axisPtProng, axisRapidity}}); - registry.add("hMassRecSig", bSCandMatch + "inv. mass J/#Psi K^{+} (GeV/#it{c}^{2}); B_{s}^{0} " + stringPt, {HistType::kTH2F, {axisMassBs, axisPtB}}); - registry.add("hMassJpsiRecSig", bSCandMatch + "inv. mass #mu^{+}#mu^{#minus} (GeV/#it{c}^{2}); J/#Psi " + stringPt, {HistType::kTH2F, {axisMassJpsi, axisPtJpsi}}); - registry.add("hMassPhiRecSig", bSCandMatch + "inv. mass K^{+}K^{#minus} (GeV/#it{c}^{2}); #phi " + stringPt, {HistType::kTH2F, {axisMassPhi, axisPtPhi}}); - registry.add("hMassRecBg", bSCandUnmatch + "inv. mass J/#Psi K^{+} (GeV/#it{c}^{2}); B_{s}^{0} " + stringPt, {HistType::kTH2F, {axisMassBs, axisPtB}}); - registry.add("hMassJpsiRecBg", bSCandUnmatch + "inv. mass #mu^{+}#mu^{#minus} (GeV/#it{c}^{2}); J/#Psi " + stringPt, {HistType::kTH2F, {axisMassJpsi, axisPtJpsi}}); - registry.add("hMassPhiRecBg", bSCandMatch + "inv. mass K^{+}K^{#minus} (GeV/#it{c}^{2}); #phi " + stringPt, {HistType::kTH2F, {axisMassPhi, axisPtPhi}}); + registry.add("hMassRecSig", bsCandMatch + "inv. mass J/#Psi K^{+} (GeV/#it{c}^{2}); B_{s}^{0} " + stringPt, {HistType::kTH2F, {axisMassBs, axisPtB}}); + registry.add("hMassJpsiRecSig", bsCandMatch + "inv. mass #mu^{+}#mu^{#minus} (GeV/#it{c}^{2}); J/#Psi " + stringPt, {HistType::kTH2F, {axisMassJpsi, axisPtJpsi}}); + registry.add("hMassPhiRecSig", bsCandMatch + "inv. mass K^{+}K^{#minus} (GeV/#it{c}^{2}); #phi " + stringPt, {HistType::kTH2F, {axisMassPhi, axisPtPhi}}); + registry.add("hMassRecBg", bsCandUnmatch + "inv. mass J/#Psi K^{+} (GeV/#it{c}^{2}); B_{s}^{0} " + stringPt, {HistType::kTH2F, {axisMassBs, axisPtB}}); + registry.add("hMassJpsiRecBg", bsCandUnmatch + "inv. mass #mu^{+}#mu^{#minus} (GeV/#it{c}^{2}); J/#Psi " + stringPt, {HistType::kTH2F, {axisMassJpsi, axisPtJpsi}}); + registry.add("hMassPhiRecBg", bsCandUnmatch + "inv. mass K^{+}K^{#minus} (GeV/#it{c}^{2}); #phi " + stringPt, {HistType::kTH2F, {axisMassPhi, axisPtPhi}}); } if (doprocessDataWithBsMl || doprocessMcWithBsMl) { @@ -390,7 +389,7 @@ struct HfTaskBsToJpsiPhiReduced { flagMcMatchRec = candidate.flagMcMatchRec(); flagMcDecayChanRec = candidate.flagMcDecayChanRec(); flagWrongCollision = candidate.flagWrongCollision(); - isSignal = flagMcMatchRec == o2::hf_decay::hf_cand_beauty::BsToJpsiKK && + isSignal = std::abs(flagMcMatchRec) == o2::hf_decay::hf_cand_beauty::BsToJpsiKK && flagMcDecayChanRec == o2::hf_decay::hf_cand_beauty::BsToJpsiPhi; } diff --git a/PWGHF/D2H/Tasks/taskCd.cxx b/PWGHF/D2H/Tasks/taskCd.cxx index c1e3a743f19..4c71e62d6ee 100644 --- a/PWGHF/D2H/Tasks/taskCd.cxx +++ b/PWGHF/D2H/Tasks/taskCd.cxx @@ -14,12 +14,14 @@ /// \author Biao Zhang , Heidelberg Universiity #include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Core/DecayChannels.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/DataModel/TrackIndexSkimmingTables.h" +#include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponseITS.h" @@ -27,6 +29,7 @@ #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" +#include #include #include #include @@ -40,6 +43,7 @@ #include #include +#include #include @@ -48,6 +52,7 @@ #include #include #include +#include #include // std::vector using namespace o2; @@ -63,52 +68,61 @@ namespace o2::aod namespace full { // Candidate kinematics -DECLARE_SOA_COLUMN(MassCd, massCd, float); //! Invariant mass of cd candidate (GeV/c^2) -DECLARE_SOA_COLUMN(MassLc, massLc, float); //! Invariant mass of lc candidate (GeV/c^2) -DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) -DECLARE_SOA_COLUMN(Eta, eta, float); //! eta of candidate (GeV/c) -DECLARE_SOA_COLUMN(Phi, phi, float); //! phi of candidate (GeV/c) -DECLARE_SOA_COLUMN(PtProng0, ptProng0, float); //! Transverse momentum of prong 0 (GeV/c) -DECLARE_SOA_COLUMN(PxProng0, pxProng0, float); //! Px of prong 0 (GeV/c) -DECLARE_SOA_COLUMN(PyProng0, pyProng0, float); //! Py of prong 0 (GeV/c) -DECLARE_SOA_COLUMN(PzProng0, pzProng0, float); //! Pz of prong 0 (GeV/c) -DECLARE_SOA_COLUMN(PtProng1, ptProng1, float); //! Transverse momentum of prong 1 (GeV/c) -DECLARE_SOA_COLUMN(PxProng1, pxProng1, float); //! Px of prong 1 (GeV/c) -DECLARE_SOA_COLUMN(PyProng1, pyProng1, float); //! Py of prong 1 (GeV/c) -DECLARE_SOA_COLUMN(PzProng1, pzProng1, float); //! Pz of prong 1 (GeV/c) -DECLARE_SOA_COLUMN(PtProng2, ptProng2, float); //! Transverse momentum of prong 2 (GeV/c) -DECLARE_SOA_COLUMN(PxProng2, pxProng2, float); //! Px of prong 2 (GeV/c) -DECLARE_SOA_COLUMN(PyProng2, pyProng2, float); //! Py of prong 2 (GeV/c) -DECLARE_SOA_COLUMN(PzProng2, pzProng2, float); //! Pz of prong 2 (GeV/c) -DECLARE_SOA_COLUMN(ImpactParameter0, impactParameter0, float); //! Impact parameter (DCA to PV) of prong 0 (cm) -DECLARE_SOA_COLUMN(ImpactParameter1, impactParameter1, float); //! Impact parameter (DCA to PV) of prong 1 (cm) -DECLARE_SOA_COLUMN(ImpactParameter2, impactParameter2, float); //! Impact parameter (DCA to PV) of prong 2 (cm) -DECLARE_SOA_COLUMN(DecayLength, decayLength, float); //! Decay length (3D) of candidate (cm) -DECLARE_SOA_COLUMN(DecayLengthXY, decayLengthXY, float); //! Decay length in transverse plane (cm) -DECLARE_SOA_COLUMN(Cpa, cpa, float); //! Cosine of pointing angle (3D) -DECLARE_SOA_COLUMN(CpaXY, cpaXY, float); //! Cosine of pointing angle in XY plane -DECLARE_SOA_COLUMN(Chi2PCA, chi2PCA, float); //! chi2PCA -DECLARE_SOA_COLUMN(NSigmaTpcDe, nSigmaTpcDe, float); //! TPC nσ for deuteron hypothesis -DECLARE_SOA_COLUMN(NSigmaTpcPr, nSigmaTpcPr, float); //! TPC nσ for proton hypothesis -DECLARE_SOA_COLUMN(NSigmaTpcKa, nSigmaTpcKa, float); //! TPC nσ for kaon hypothesis -DECLARE_SOA_COLUMN(NSigmaTpcPi, nSigmaTpcPi, float); //! TPC nσ for pion hypothesis -DECLARE_SOA_COLUMN(NSigmaItsDe, nSigmaItsDe, float); //! ITS nσ for deuteron hypothesis -DECLARE_SOA_COLUMN(NSigmaTofDe, nSigmaTofDe, float); //! TOF nσ for deuteron hypothesis -DECLARE_SOA_COLUMN(NSigmaTofKa, nSigmaTofKa, float); //! TOF nσ for kaon hypothesis -DECLARE_SOA_COLUMN(NSigmaTofPi, nSigmaTofPi, float); //! TOF nσ for pion hypothesis -DECLARE_SOA_COLUMN(NItsClusters, nItsClusters, float); //! Number of ITS clusters used in the track fit -DECLARE_SOA_COLUMN(NItsNClusterSize, nItsNClusterSize, float); //! Number of ITS clusters size used in the track fit -DECLARE_SOA_COLUMN(NTpcClusters, nTpcClusters, float); //! Number of TPC clusters used in the track fit -DECLARE_SOA_COLUMN(NTpcSignalsDe, nTpcSignalsDe, float); //! Number of TPC signas for deuteron -DECLARE_SOA_COLUMN(NTpcSignalsPi, nTpcSignalsPi, float); //! Number of TPC signas for pion -DECLARE_SOA_COLUMN(NTpcSignalsKa, nTpcSignalsKa, float); //! Number of TPC signas for kaon -DECLARE_SOA_COLUMN(NItsSignalsDe, nItsSignalsDe, float); //! Number of ITS signas -DECLARE_SOA_COLUMN(CandidateSelFlag, candidateSelFlag, int8_t); //! Candidates falg -DECLARE_SOA_COLUMN(CandidateSign, candidateSign, int8_t); //! Candidates sign -DECLARE_SOA_COLUMN(Cent, cent, float); //! Centrality -DECLARE_SOA_COLUMN(VtxZ, vtxZ, float); //! Vertex Z -DECLARE_SOA_COLUMN(GIndexCol, gIndexCol, int); //! Global index for the collisionAdd commentMore actions -DECLARE_SOA_COLUMN(TimeStamp, timeStamp, int64_t); //! Timestamp for the collision +DECLARE_SOA_COLUMN(MassCd, massCd, float); //! Invariant mass of cd candidate (GeV/c^2) +DECLARE_SOA_COLUMN(MassLc, massLc, float); //! Invariant mass of lc candidate (GeV/c^2) +DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(Eta, eta, float); //! eta of candidate (GeV/c) +DECLARE_SOA_COLUMN(Phi, phi, float); //! phi of candidate (GeV/c) +DECLARE_SOA_COLUMN(Y, y, float); //! rapidity of generated particle +DECLARE_SOA_COLUMN(PtProng0, ptProng0, float); //! Transverse momentum of prong 0 (GeV/c) +DECLARE_SOA_COLUMN(PxProng0, pxProng0, float); //! Px of prong 0 (GeV/c) +DECLARE_SOA_COLUMN(PyProng0, pyProng0, float); //! Py of prong 0 (GeV/c) +DECLARE_SOA_COLUMN(PzProng0, pzProng0, float); //! Pz of prong 0 (GeV/c) +DECLARE_SOA_COLUMN(PtProng1, ptProng1, float); //! Transverse momentum of prong 1 (GeV/c) +DECLARE_SOA_COLUMN(PxProng1, pxProng1, float); //! Px of prong 1 (GeV/c) +DECLARE_SOA_COLUMN(PyProng1, pyProng1, float); //! Py of prong 1 (GeV/c) +DECLARE_SOA_COLUMN(PzProng1, pzProng1, float); //! Pz of prong 1 (GeV/c) +DECLARE_SOA_COLUMN(PtProng2, ptProng2, float); //! Transverse momentum of prong 2 (GeV/c) +DECLARE_SOA_COLUMN(PxProng2, pxProng2, float); //! Px of prong 2 (GeV/c) +DECLARE_SOA_COLUMN(PyProng2, pyProng2, float); //! Py of prong 2 (GeV/c) +DECLARE_SOA_COLUMN(PzProng2, pzProng2, float); //! Pz of prong 2 (GeV/c) +DECLARE_SOA_COLUMN(ImpactParameter0, impactParameter0, float); //! Impact parameter (DCA to PV) of prong 0 (cm) +DECLARE_SOA_COLUMN(ImpactParameter1, impactParameter1, float); //! Impact parameter (DCA to PV) of prong 1 (cm) +DECLARE_SOA_COLUMN(ImpactParameter2, impactParameter2, float); //! Impact parameter (DCA to PV) of prong 2 (cm) +DECLARE_SOA_COLUMN(DecayLength, decayLength, float); //! Decay length (3D) of candidate (cm) +DECLARE_SOA_COLUMN(DecayLengthXY, decayLengthXY, float); //! Decay length in transverse plane (cm) +DECLARE_SOA_COLUMN(Cpa, cpa, float); //! Cosine of pointing angle (3D) +DECLARE_SOA_COLUMN(CpaXY, cpaXY, float); //! Cosine of pointing angle in XY plane +DECLARE_SOA_COLUMN(Chi2PCA, chi2PCA, float); //! chi2PCA +DECLARE_SOA_COLUMN(NSigmaTpcDe, nSigmaTpcDe, float); //! TPC nσ for deuteron hypothesis +DECLARE_SOA_COLUMN(NSigmaTpcPr, nSigmaTpcPr, float); //! TPC nσ for proton hypothesis +DECLARE_SOA_COLUMN(NSigmaTpcKa, nSigmaTpcKa, float); //! TPC nσ for kaon hypothesis +DECLARE_SOA_COLUMN(NSigmaTpcPi, nSigmaTpcPi, float); //! TPC nσ for pion hypothesis +DECLARE_SOA_COLUMN(NSigmaItsDe, nSigmaItsDe, float); //! ITS nσ for deuteron hypothesis +DECLARE_SOA_COLUMN(NSigmaTofDe, nSigmaTofDe, float); //! TOF nσ for deuteron hypothesis +DECLARE_SOA_COLUMN(NSigmaTofKa, nSigmaTofKa, float); //! TOF nσ for kaon hypothesis +DECLARE_SOA_COLUMN(NSigmaTofPi, nSigmaTofPi, float); //! TOF nσ for pion hypothesis +DECLARE_SOA_COLUMN(NItsClusters, nItsClusters, float); //! Number of ITS clusters used in the track fit +DECLARE_SOA_COLUMN(NItsNClusterSize, nItsNClusterSize, float); //! Number of ITS clusters size used in the track fit +DECLARE_SOA_COLUMN(NTpcClusters, nTpcClusters, float); //! Number of TPC clusters used in the track fit +DECLARE_SOA_COLUMN(NTpcSignalsDe, nTpcSignalsDe, float); //! Number of TPC signas for deuteron +DECLARE_SOA_COLUMN(NTpcSignalsPi, nTpcSignalsPi, float); //! Number of TPC signas for pion +DECLARE_SOA_COLUMN(NTpcSignalsKa, nTpcSignalsKa, float); //! Number of TPC signas for kaon +DECLARE_SOA_COLUMN(NItsSignalsDe, nItsSignalsDe, float); //! Number of ITS signas +DECLARE_SOA_COLUMN(CandidateSelFlag, candidateSelFlag, int8_t); //! Candidates falg +DECLARE_SOA_COLUMN(CandidateSign, candidateSign, int8_t); //! Candidates sign +DECLARE_SOA_COLUMN(FlagMc, flagMc, int8_t); //! MC matching flag +DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int8_t); //! MC origin for reconstructed candidates +DECLARE_SOA_COLUMN(FlagMcDecayChanRec, flagMcDecayChanRec, int8_t); //! Resonant MC decay channel for reconstructed candidates +DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int8_t); //! MC origin for generated particles +DECLARE_SOA_COLUMN(FlagMcDecayChanGen, flagMcDecayChanGen, int8_t); //! Resonant MC decay channel for generated candidates +DECLARE_SOA_COLUMN(CtGen, ctGen, float); //! Generated ct computed wrt to c-deuteron production vertex, which can be either PV (prompt) or B-hadron decay vertex (non-prompt) +DECLARE_SOA_COLUMN(CtRec, ctRec, float); //! Reconstructed ct computed wrt to PV +DECLARE_SOA_COLUMN(Cent, cent, float); //! Centrality +DECLARE_SOA_COLUMN(VtxZ, vtxZ, float); //! Vertex Z +DECLARE_SOA_COLUMN(GIndexCol, gIndexCol, int); //! Global index for the collision +DECLARE_SOA_COLUMN(McCollisionId, mcCollisionId, int); //! Global index for the MC collision +DECLARE_SOA_COLUMN(TimeStamp, timeStamp, int64_t); //! Timestamp for the collision } // namespace full // Lite table @@ -131,8 +145,13 @@ DECLARE_SOA_TABLE(HfCandCdLite, "AOD", "HFCANDCDLITE", full::NSigmaTpcPr, full::NSigmaItsDe, full::NSigmaTofDe, + full::CtRec, full::CandidateSelFlag, full::CandidateSign, + full::FlagMc, + full::OriginMcRec, + full::FlagMcDecayChanRec, + full::CtGen, full::Cent); // full table for local Rotation & Event Mixing @@ -160,20 +179,41 @@ DECLARE_SOA_TABLE(HfCandCdFull, "AOD", "HFCANDCDFULL", full::NSigmaTofPi, full::NSigmaTpcKa, full::NSigmaTofKa, + full::CtRec, full::CandidateSelFlag, full::CandidateSign, + full::FlagMc, + full::OriginMcRec, + full::FlagMcDecayChanRec, + full::CtGen, full::Cent, full::VtxZ, full::GIndexCol, full::TimeStamp); + +DECLARE_SOA_TABLE(HfCandCdGen, "AOD", "HFCANDCDGEN", + full::Pt, + full::Eta, + full::Phi, + full::Y, + full::FlagMc, + full::OriginMcGen, + full::FlagMcDecayChanGen, + full::CtGen, + full::Cent, + full::VtxZ, + full::McCollisionId); } // namespace o2::aod struct HfTaskCd { Produces rowCandCdLite; Produces rowCandCdFull; + Produces rowCandCdGen; Configurable selectionFlagCd{"selectionFlagCd", 1, "Selection Flag for Cd"}; + Configurable yCandGenMax{"yCandGenMax", 0.5, "max. gen particle rapidity"}; + Configurable yCandRecoMax{"yCandRecoMax", 0.8, "max. cand. rapidity"}; Configurable> binsPt{"binsPt", std::vector{hf_cuts_cd_to_de_k_pi::vecBinsPt}, "pT bin limits"}; Configurable fillTHn{"fillTHn", false, "fill THn"}; Configurable fillCandLiteTree{"fillCandLiteTree", false, "Flag to fill candiates lite tree"}; @@ -186,14 +226,21 @@ struct HfTaskCd { SliceCache cache; using CollisionsWEvSel = soa::Join; + using CollisionsMc = soa::Join; using CollisionsWithEvSelFT0C = soa::Join; + using CollisionsMcWithEvSelFT0C = soa::Join; using CollisionsWithEvSelFT0M = soa::Join; + using CollisionsMcWithEvSelFT0M = soa::Join; using CdCandidates = soa::Filtered>; + using CdCandidatesMc = soa::Filtered>; + using McParticles3ProngMatched = soa::Join; using HFTracks = soa::Join; + using HFTracksMc = soa::Join; Filter filterSelectCandidates = aod::hf_sel_candidate_cd::isSelCdToDeKPi >= selectionFlagCd || aod::hf_sel_candidate_cd::isSelCdToPiKDe >= selectionFlagCd; Preslice candCdPerCollision = aod::hf_cand::collisionId; + PresliceUnsorted colPerMcCollision = aod::mcparticle::mcCollisionId; ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {72, 0, 36}, ""}; ConfigurableAxis thnConfigAxisMass{"thnConfigAxisMass", {400, 2.4, 4.4}, ""}; @@ -202,45 +249,103 @@ struct HfTaskCd { ConfigurableAxis thnConfigAxisDecLength{"thnConfigAxisDecLength", {10, 0, 0.05}, ""}; ConfigurableAxis thnConfigAxisCPA{"thnConfigAxisCPA", {20, 0.8, 1}, ""}; ConfigurableAxis thnConfigAxisCentrality{"thnConfigAxisCentrality", {100, 0, 100}, ""}; + ConfigurableAxis thnAxisRapidity{"thnAxisRapidity", {20, -1, 1}, "Cand. rapidity bins"}; + ConfigurableAxis thnConfigAxisGenPtB{"thnConfigAxisGenPtB", {1000, 0, 100}, "Gen Pt B"}; + ConfigurableAxis thnConfigAxisNumPvContr{"thnConfigAxisNumPvContr", {200, -0.5, 199.5}, "Number of PV contributors"}; + ConfigurableAxis thnConfigAxisCt{"thnConfigAxisCt", {500, 0., 5000.}, ""}; + + constexpr static std::string_view SignalFolders[] = {"signal", "prompt", "nonprompt"}; + constexpr static std::string_view SignalSuffixes[] = {"", "Prompt", "NonPrompt"}; + const float cmToMum = 1.e4; + + enum SignalClasses : int { + Signal = 0, + Prompt, + NonPrompt + }; HistogramRegistry registry{ "registry", {/// mass candidate - {"Data/hMass", "3-prong candidates;inv. mass (de K #pi) (GeV/#it{c}^{2})", {HistType::kTH1F, {{400, 2.4, 4.4}}}}, + {"Data/hMass", "3-prong candidates;inv. mass (de K #pi) (GeV/#it{c}^{2})", {HistType::kTH1D, {{400, 2.4, 4.4}}}}, /// pT - {"Data/hPt", "3-prong candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}}, - {"Data/hPtProng0", "3-prong candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}}, - {"Data/hPtProng1", "3-prong candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}}, - {"Data/hPtProng2", "3-prong candidates;prong 2 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}}, + {"Data/hPt", "3-prong candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{360, 0., 36.}}}}, + {"Data/hPtProng0", "3-prong candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{360, 0., 36.}}}}, + {"Data/hPtProng1", "3-prong candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{360, 0., 36.}}}}, + {"Data/hPtProng2", "3-prong candidates;prong 2 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {{360, 0., 36.}}}}, /// DCAxy to prim. vertex prongs - {"Data/hd0Prong0", "3-prong candidates;prong 0 DCAxy to prim. vertex (cm);entries", {HistType::kTH1F, {{600, -0.4, 0.4}}}}, - {"Data/hd0Prong1", "3-prong candidates;prong 1 DCAxy to prim. vertex (cm);entries", {HistType::kTH1F, {{600, -0.4, 0.4}}}}, - {"Data/hd0Prong2", "3-prong candidates;prong 2 DCAxy to prim. vertex (cm);entries", {HistType::kTH1F, {{600, -0.4, 0.4}}}}, + {"Data/hd0Prong0", "3-prong candidates;prong 0 DCAxy to prim. vertex (cm);entries", {HistType::kTH1D, {{600, -0.4, 0.4}}}}, + {"Data/hd0Prong1", "3-prong candidates;prong 1 DCAxy to prim. vertex (cm);entries", {HistType::kTH1D, {{600, -0.4, 0.4}}}}, + {"Data/hd0Prong2", "3-prong candidates;prong 2 DCAxy to prim. vertex (cm);entries", {HistType::kTH1D, {{600, -0.4, 0.4}}}}, /// decay length candidate - {"Data/hDecLength", "3-prong candidates;decay length (cm);entries", {HistType::kTH1F, {{400, 0., 1.}}}}, + {"Data/hDecLength", "3-prong candidates;decay length (cm);entries", {HistType::kTH1D, {{400, 0., 1.}}}}, /// decay length xy candidate - {"Data/hDecLengthxy", "3-prong candidates;decay length xy (cm);entries", {HistType::kTH1F, {{400, 0., 1.}}}}, + {"Data/hDecLengthxy", "3-prong candidates;decay length xy (cm);entries", {HistType::kTH1D, {{400, 0., 1.}}}}, /// cosine of pointing angle - {"Data/hCPA", "3-prong candidates;cosine of pointing angle;entries", {HistType::kTH1F, {{110, -1.1, 1.1}}}}, + {"Data/hCPA", "3-prong candidates;cosine of pointing angle;entries", {HistType::kTH1D, {{110, -1.1, 1.1}}}}, /// cosine of pointing angle xy - {"Data/hCPAxy", "3-prong candidates;cosine of pointing angle xy;entries", {HistType::kTH1F, {{110, -1.1, 1.1}}}}, + {"Data/hCPAxy", "3-prong candidates;cosine of pointing angle xy;entries", {HistType::kTH1D, {{110, -1.1, 1.1}}}}, /// Chi 2 PCA to sec. vertex - {"Data/hDca2", "3-prong candidates;prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH1F, {{400, 0., 20.}}}}, + {"Data/hDca2", "3-prong candidates;prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH1D, {{400, 0., 20.}}}}, /// eta - {"Data/hEta", "3-prong candidates;#it{#eta};entries", {HistType::kTH1F, {{100, -2., 2.}}}}, + {"Data/hEta", "3-prong candidates;#it{#eta};entries", {HistType::kTH1D, {{100, -2., 2.}}}}, /// phi - {"Data/hPhi", "3-prong candidates;#it{#Phi};entries", {HistType::kTH1F, {{100, 0., 6.3}}}}}}; + {"Data/hPhi", "3-prong candidates;#it{#Phi};entries", {HistType::kTH1D, {{100, 0., 6.3}}}}}}; HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; void init(InitContext&) { - std::array doprocess{doprocessDataStd, doprocessDataStdWithFT0C, doprocessDataStdWithFT0M}; + std::array doprocess{doprocessDataStd, doprocessDataStdWithFT0C, doprocessDataStdWithFT0M, doprocessMcStd, doprocessMcStdWithFT0C, doprocessMcStdWithFT0M}; if ((std::accumulate(doprocess.begin(), doprocess.end(), 0)) != 1) { LOGP(fatal, "no or more than one process function enabled! Please check your configuration!"); } + const bool isData = doprocessDataStd || doprocessDataStdWithFT0C || doprocessDataStdWithFT0M; + + auto addHistogramsRec = [&](const std::string& histoName, const std::string& xAxisTitle, const std::string& yAxisTitle, const HistogramConfigSpec& configSpec) { + if (!isData) { + registry.add(("MC/reconstructed/signal/" + histoName + "RecSig").c_str(), ("3-prong candidates (matched);" + xAxisTitle + ";" + yAxisTitle).c_str(), configSpec); + registry.add(("MC/reconstructed/prompt/" + histoName + "RecSigPrompt").c_str(), ("3-prong candidates (matched, prompt);" + xAxisTitle + ";" + yAxisTitle).c_str(), configSpec); + registry.add(("MC/reconstructed/nonprompt/" + histoName + "RecSigNonPrompt").c_str(), ("3-prong candidates (matched, non-prompt);" + xAxisTitle + ";" + yAxisTitle).c_str(), configSpec); + } + }; + + auto addHistogramsGen = [&](const std::string& histoName, const std::string& xAxisTitle, const std::string& yAxisTitle, const HistogramConfigSpec& configSpec) { + if (!isData) { + registry.add(("MC/generated/signal/" + histoName + "Gen").c_str(), ("MC particles (matched);" + xAxisTitle + ";" + yAxisTitle).c_str(), configSpec); + registry.add(("MC/generated/prompt/" + histoName + "GenPrompt").c_str(), ("MC particles (matched, prompt);" + xAxisTitle + ";" + yAxisTitle).c_str(), configSpec); + registry.add(("MC/generated/nonprompt/" + histoName + "GenNonPrompt").c_str(), ("MC particles (matched, non-prompt);" + xAxisTitle + ";" + yAxisTitle).c_str(), configSpec); + } + }; + + addHistogramsRec("hMass", "inv. mass (de K #pi) (GeV/#it{c}^{2})", "", {HistType::kTH1D, {{400, 2.4, 4.4}}}); + addHistogramsRec("hPt", "#it{p}_{T}^{rec.} (GeV/#it{c})", "entries", {HistType::kTH1D, {{360, 0., 36.}}}); + addHistogramsGen("hPt", "#it{p}_{T}^{gen.} (GeV/#it{c})", "entries", {HistType::kTH1D, {{360, 0., 36.}}}); + if (!isData) { + registry.add("MC/generated/signal/hPtGenSig", "3-prong candidates (matched);#it{p}_{T}^{gen.} (GeV/#it{c});entries", {HistType::kTH1D, {{360, 0., 36.}}}); + } + addHistogramsRec("hPtProng0", "prong 0 #it{p}_{T} (GeV/#it{c})", "entries", {HistType::kTH1D, {{360, 0., 36.}}}); + addHistogramsRec("hPtProng1", "prong 1 #it{p}_{T} (GeV/#it{c})", "entries", {HistType::kTH1D, {{360, 0., 36.}}}); + addHistogramsRec("hPtProng2", "prong 2 #it{p}_{T} (GeV/#it{c})", "entries", {HistType::kTH1D, {{360, 0., 36.}}}); + addHistogramsRec("hd0Prong0", "prong 0 DCAxy to prim. vertex (cm)", "entries", {HistType::kTH1D, {{600, -0.4, 0.4}}}); + addHistogramsRec("hd0Prong1", "prong 1 DCAxy to prim. vertex (cm)", "entries", {HistType::kTH1D, {{600, -0.4, 0.4}}}); + addHistogramsRec("hd0Prong2", "prong 2 DCAxy to prim. vertex (cm)", "entries", {HistType::kTH1D, {{600, -0.4, 0.4}}}); + addHistogramsRec("hDecLength", "decay length (cm)", "entries", {HistType::kTH1D, {{400, 0., 1.}}}); + addHistogramsRec("hDecLengthxy", "decay length xy (cm)", "entries", {HistType::kTH1D, {{400, 0., 1.}}}); + addHistogramsRec("hCPA", "cosine of pointing angle", "entries", {HistType::kTH1D, {{110, -1.1, 1.1}}}); + addHistogramsRec("hCPAxy", "cosine of pointing angle xy", "entries", {HistType::kTH1D, {{110, -1.1, 1.1}}}); + addHistogramsRec("hDca2", "prong Chi2PCA to sec. vertex (cm)", "entries", {HistType::kTH1D, {{400, 0., 20.}}}); + addHistogramsRec("hEta", "#it{#eta}", "entries", {HistType::kTH1D, {{100, -2., 2.}}}); + addHistogramsGen("hEta", "#it{#eta}", "entries", {HistType::kTH1D, {{100, -2., 2.}}}); + addHistogramsGen("hY", "#it{y}", "entries", {HistType::kTH1D, {{100, -2., 2.}}}); + addHistogramsRec("hPhi", "#it{#Phi}", "entries", {HistType::kTH1D, {{100, 0., 6.3}}}); + addHistogramsGen("hPhi", "#it{#Phi}", "entries", {HistType::kTH1D, {{100, 0., 6.3}}}); + /// mass candidate - registry.add("Data/hMassVsPtVsNPvContributors", "3-prong candidates;inv. mass (de K #pi) (GeV/#it{c}^{2}); p_{T}; Number of PV contributors", {HistType::kTH3F, {{400, 2.4, 4.4}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}, {500, 0., 5000.}}}); + if (isData) { + registry.add("Data/hMassVsPtVsNPvContributors", "3-prong candidates;inv. mass (de K #pi) (GeV/#it{c}^{2}); p_{T}; Number of PV contributors", {HistType::kTH3F, {{400, 2.4, 4.4}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}, {500, 0., 5000.}}}); + } + addHistogramsRec("hMassVsPt", "inv. mass (de K #pi) (GeV/#it{c}^{2})", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{400, 2.4, 4.4}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); registry.add("Data/hMassVsPt", "3-prong candidates;inv. mass (de K #pi) (GeV/#it{c}^{2}); p_{T}", {HistType::kTH2F, {{400, 2.4, 4.4}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); /// DCAxy to prim. vertex prongs registry.add("Data/hd0VsPtProng0", "3-prong candidates;prong 0 DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {{600, -0.4, 0.4}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); @@ -258,8 +363,11 @@ struct HfTaskCd { registry.add("Data/hDca2VsPt", "3-prong candidates;prong Chi2PCA to sec. vertex (cm);entries", {HistType::kTH2F, {{400, 0., 20.}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); /// eta registry.add("Data/hEtaVsPt", "3-prong candidates;candidate #it{#eta};entries", {HistType::kTH2F, {{100, -2., 2.}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + addHistogramsGen("hEtaVsPt", "#it{#eta}", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, -2., 2.}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + addHistogramsGen("hYVsPt", "#it{y}", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, -2., 2.}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); /// phi registry.add("Data/hPhiVsPt", "3-prong candidates;candidate #it{#Phi};entries", {HistType::kTH2F, {{100, 0., 6.3}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + addHistogramsGen("hPhiVsPt", "#it{#Phi}", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, 0., 6.3}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); /// selection status registry.add("hSelectionStatus", "3-prong candidates;selection status;entries", {HistType::kTH2F, {{5, -0.5, 4.5}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); /// impact parameter error @@ -278,6 +386,16 @@ struct HfTaskCd { registry.add("Data/hNsigmaTOFPiVsP", "Pion;#it{p} (GeV/#it{c});n#sigma^{TOF}_{pi};", {HistType::kTH2F, {{200, -10.f, 10.f}, {200, -6.f, 6.f}}}); registry.add("Data/hNsigmaTPCKaVsP", "Kaon;#it{p} (GeV/#it{c}); n#sigma^{TPC}_{Kaon}", {HistType::kTH2F, {{200, -10.f, 10.f}, {200, -6.f, 6.f}}}); registry.add("Data/hNsigmaTOFKaVsP", "Kaon;#it{p} (GeV/#it{c}); n#sigma^{TOF}_{Kaon}", {HistType::kTH2F, {{200, -10.f, 10.f}, {200, -6.f, 6.f}}}); + addHistogramsRec("hd0VsPtProng0", "prong 0 DCAxy to prim. vertex (cm)", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{600, -0.4, 0.4}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + addHistogramsRec("hd0VsPtProng1", "prong 1 DCAxy to prim. vertex (cm)", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{600, -0.4, 0.4}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + addHistogramsRec("hd0VsPtProng2", "prong 2 DCAxy to prim. vertex (cm)", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{600, -0.4, 0.4}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + addHistogramsRec("hDecLengthVsPt", "decay length (cm)", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{400, 0., 1.}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + addHistogramsRec("hDecLengthxyVsPt", "decay length xy (cm)", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{400, 0., 1.}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + addHistogramsRec("hCPAVsPt", "cosine of pointing angle", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{110, -1.1, 1.1}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + addHistogramsRec("hCPAxyVsPt", "cosine of pointing angle xy", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{110, -1.1, 1.1}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + addHistogramsRec("hDca2VsPt", "prong Chi2PCA to sec. vertex (cm)", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{400, 0., 20.}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + addHistogramsRec("hEtaVsPt", "candidate #it{#eta}", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, -2., 2.}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + addHistogramsRec("hPhiVsPt", "candidate #it{#Phi}", "#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, 0., 6.3}, {binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); if (fillTHn) { const AxisSpec thnAxisMass{thnConfigAxisMass, "inv. mass (de K #pi) (GeV/#it{c}^{2})"}; const AxisSpec thnAxisPt{thnConfigAxisPt, "#it{p}_{T}(C_{d}^{+}) (GeV/#it{c})"}; @@ -288,9 +406,17 @@ struct HfTaskCd { const AxisSpec thnAxisDecLength{thnConfigAxisDecLength, "decay length (cm)"}; const AxisSpec thnAxisCPA{thnConfigAxisCPA, "cosine of pointing angle"}; const AxisSpec thnAxisCentrality{thnConfigAxisCentrality, "centrality (FT0C)"}; + const AxisSpec thnAxisY{thnAxisRapidity, "rapidity"}; + const AxisSpec thnAxisPtB{thnConfigAxisGenPtB, "#it{p}_{T}^{B} (GeV/#it{c})"}; + const AxisSpec thnAxisCt{thnConfigAxisCt, "#it{ct} (#mum)"}; + const AxisSpec thnAxisTracklets{thnConfigAxisNumPvContr, "Number of PV contributors"}; std::vector axesStd{thnAxisMass, thnAxisPt, thnAxisPtProng0, thnAxisPtProng1, thnAxisPtProng2, thnAxisChi2PCA, thnAxisDecLength, thnAxisCPA, thnAxisCentrality}; - registry.add("hnCdVars", "THn for Reconstructed Cd candidates for data", HistType::kTHnSparseF, axesStd); + std::vector axesGen{thnAxisPt, thnAxisCentrality, thnAxisY, thnAxisTracklets, thnAxisCt, thnAxisPtB}; + registry.add("hnCdVars", isData ? "THn for Reconstructed Cd candidates for data" : "THn for Reconstructed Cd candidates for MC", HistType::kTHnSparseF, axesStd); + if (!isData) { + registry.add("hnCdVarsGen", "THn for Generated Cd", HistType::kTHnSparseF, axesGen); + } } } @@ -312,6 +438,300 @@ struct HfTaskCd { return (static_cast(sumClusterSizes) / numLayers) * cosLamnda; }; + /// Helper function for filling MC reconstructed histograms for prompt, nonprompt and common signal + template + void fillHistogramsRecSig(CandidateType const& candidate) + { + const auto& mcParticleProng0 = candidate.template prong0_as().template mcParticle_as(); + const auto pdgCodeProng0 = std::abs(mcParticleProng0.pdgCode()); + if ((candidate.isSelCdToDeKPi() >= selectionFlagCd) && pdgCodeProng0 == o2::constants::physics::Pdg::kDeuteron) { + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hMassRecSig") + HIST(SignalSuffixes[SignalType]), HfHelper::invMassCdToDeKPi(candidate)); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hMassVsPtRecSig") + HIST(SignalSuffixes[SignalType]), HfHelper::invMassCdToDeKPi(candidate), candidate.pt()); + } + if ((candidate.isSelCdToPiKDe() >= selectionFlagCd) && pdgCodeProng0 == kPiPlus) { + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hMassRecSig") + HIST(SignalSuffixes[SignalType]), HfHelper::invMassCdToPiKDe(candidate)); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hMassVsPtRecSig") + HIST(SignalSuffixes[SignalType]), HfHelper::invMassCdToPiKDe(candidate), candidate.pt()); + } + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hPtRecSig") + HIST(SignalSuffixes[SignalType]), candidate.pt()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hPtProng0RecSig") + HIST(SignalSuffixes[SignalType]), candidate.ptProng0()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hPtProng1RecSig") + HIST(SignalSuffixes[SignalType]), candidate.ptProng1()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hPtProng2RecSig") + HIST(SignalSuffixes[SignalType]), candidate.ptProng2()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hd0Prong0RecSig") + HIST(SignalSuffixes[SignalType]), candidate.impactParameter0()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hd0Prong1RecSig") + HIST(SignalSuffixes[SignalType]), candidate.impactParameter1()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hd0Prong2RecSig") + HIST(SignalSuffixes[SignalType]), candidate.impactParameter2()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hd0VsPtProng0RecSig") + HIST(SignalSuffixes[SignalType]), candidate.impactParameter0(), candidate.pt()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hd0VsPtProng1RecSig") + HIST(SignalSuffixes[SignalType]), candidate.impactParameter1(), candidate.pt()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hd0VsPtProng2RecSig") + HIST(SignalSuffixes[SignalType]), candidate.impactParameter2(), candidate.pt()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hDecLengthRecSig") + HIST(SignalSuffixes[SignalType]), candidate.decayLength()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hDecLengthVsPtRecSig") + HIST(SignalSuffixes[SignalType]), candidate.decayLength(), candidate.pt()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hDecLengthxyRecSig") + HIST(SignalSuffixes[SignalType]), candidate.decayLengthXY()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hDecLengthxyVsPtRecSig") + HIST(SignalSuffixes[SignalType]), candidate.decayLengthXY(), candidate.pt()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hCPARecSig") + HIST(SignalSuffixes[SignalType]), candidate.cpa()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hCPAVsPtRecSig") + HIST(SignalSuffixes[SignalType]), candidate.cpa(), candidate.pt()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hCPAxyRecSig") + HIST(SignalSuffixes[SignalType]), candidate.cpaXY()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hCPAxyVsPtRecSig") + HIST(SignalSuffixes[SignalType]), candidate.cpaXY(), candidate.pt()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hDca2RecSig") + HIST(SignalSuffixes[SignalType]), candidate.chi2PCA()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hDca2VsPtRecSig") + HIST(SignalSuffixes[SignalType]), candidate.chi2PCA(), candidate.pt()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hEtaRecSig") + HIST(SignalSuffixes[SignalType]), candidate.eta()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hEtaVsPtRecSig") + HIST(SignalSuffixes[SignalType]), candidate.eta(), candidate.pt()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hPhiRecSig") + HIST(SignalSuffixes[SignalType]), candidate.phi()); + registry.fill(HIST("MC/reconstructed/") + HIST(SignalFolders[SignalType]) + HIST("/hPhiVsPtRecSig") + HIST(SignalSuffixes[SignalType]), candidate.phi(), candidate.pt()); + } + + template + void fillHistosMcRec(CollType const& collision, CandCdMcRec const& candidates, CandCdMcGen const& mcParticles, TrackWithItsType const& tracksWithItsPid, BcType const& /*bcs*/) + { + const auto thisCollId = collision.globalIndex(); + const auto& groupedCdCandidates = candidates.sliceBy(candCdPerCollision, thisCollId); + const auto bc = collision.template bc_as(); + const int64_t timeStamp = bc.timestamp(); + + for (const auto& candidate : groupedCdCandidates) { + if (candidate.flagMcMatchRec() == 0) { // we skip combinatorial background + continue; + } + if (!TESTBIT(candidate.hfflag(), aod::hf_cand_3prong::DecayType::CdToDeKPi)) { + continue; + } + const auto yCd = RecoDecay::y(candidate.pVector(), o2::constants::physics::MassCDeuteron); + if (yCandRecoMax >= 0. && std::abs(yCd) > yCandRecoMax) { + continue; + } + + float ctGen{-1.f}, ptGen{-1.f}; + int pdgCodeProng0{0}; + if (std::abs(candidate.flagMcMatchRec()) == hf_decay::hf_cand_3prong::DecayChannelMain::CDeuteronToDeKPi) { + const auto& mcParticleProng0 = candidate.template prong0_as().template mcParticle_as(); + pdgCodeProng0 = std::abs(mcParticleProng0.pdgCode()); + const auto indexMother = RecoDecay::getMother(mcParticles, mcParticleProng0, o2::constants::physics::Pdg::kCDeuteron, true); + const auto particleMother = mcParticles.rawIteratorAt(indexMother); + ctGen = RecoDecay::ct(std::array{particleMother.px(), particleMother.py(), particleMother.pz()}, RecoDecay::distance(std::array{particleMother.vx(), particleMother.vy(), particleMother.vz()}, std::array{mcParticleProng0.vx(), mcParticleProng0.vy(), mcParticleProng0.vz()}), o2::constants::physics::MassCDeuteron) * cmToMum; + ptGen = particleMother.pt(); + } + + if (fillCandLiteTree || fillCandFullTree) { + float invMassCd = 0.f; + float invMassLc = 0.f; + int candFlag = -999; + int candSign = -999; + + float nSigmaTpcDe = 0.f, nSigmaTpcKa = 0.f, nSigmaTpcPi = 0.f, nSigmaTpcPr = 0.f; + float nSigmaItsDe = 0.f; + float nSigmaTofDe = 0.f, nSigmaTofKa = 0.f, nSigmaTofPi = 0.f; + + float dcaDeuteron = 0.f, dcaKaon = 0.f, dcaPion = 0.f; + + const bool selDeKPi = (candidate.isSelCdToDeKPi() >= selectionFlagCd); + const bool selPiKDe = (candidate.isSelCdToPiKDe() >= selectionFlagCd); + + auto prong1 = candidate.template prong1_as(); + + auto prong0Its = tracksWithItsPid.iteratorAt(candidate.prong0Id() - tracksWithItsPid.offset()); + auto prong2Its = tracksWithItsPid.iteratorAt(candidate.prong2Id() - tracksWithItsPid.offset()); + + candSign = static_cast(-prong1.sign()); + nSigmaTpcKa = candidate.nSigTpcKa1(); + nSigmaTofKa = candidate.nSigTofKa1(); + + if (selDeKPi) { + invMassCd = HfHelper::invMassCdToDeKPi(candidate); + invMassLc = HfHelper::invMassLcToPKPi(candidate); + candFlag = 1; + nSigmaTpcDe = candidate.nSigTpcDe0(); + nSigmaTpcPr = candidate.nSigTpcPr0(); + nSigmaTofDe = candidate.nSigTofDe0(); + nSigmaTpcPi = candidate.nSigTpcPi2(); + nSigmaTofPi = candidate.nSigTofPi2(); + nSigmaItsDe = prong0Its.itsNSigmaDe(); + dcaDeuteron = candidate.impactParameter0(); + dcaKaon = candidate.impactParameter1(); + dcaPion = candidate.impactParameter2(); + } else if (selPiKDe) { + invMassCd = HfHelper::invMassCdToPiKDe(candidate); + invMassLc = HfHelper::invMassLcToPiKP(candidate); + candFlag = -1; + nSigmaTpcDe = candidate.nSigTpcDe2(); + nSigmaTpcPr = candidate.nSigTpcPr2(); + nSigmaTofDe = candidate.nSigTofDe2(); + nSigmaTpcPi = candidate.nSigTpcPi0(); + nSigmaTofPi = candidate.nSigTofPi0(); + nSigmaItsDe = prong2Its.itsNSigmaDe(); + dcaDeuteron = candidate.impactParameter2(); + dcaKaon = candidate.impactParameter1(); + dcaPion = candidate.impactParameter0(); + } + + if (cfgUseTofPidForDeuteron && std::abs(nSigmaTofDe) > cfgMaxDeuteronTofPidPreselection) { + continue; + } + if (std::abs(dcaDeuteron) < cfgMinDeuteronDcaPreselection) { + continue; + } + if (cfgCutOnDeuteronDcaOrdering && (std::abs(dcaDeuteron) > std::abs(dcaKaon) || std::abs(dcaDeuteron) > std::abs(dcaPion))) { + continue; + } + + if (fillCandLiteTree) { + rowCandCdLite( + invMassCd, + invMassLc, + candidate.pt(), + candidate.eta(), + candidate.phi(), + candidate.ptProng0(), + candidate.ptProng1(), + candidate.ptProng2(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameter2(), + candidate.decayLength(), + candidate.cpa(), + candidate.chi2PCA(), + nSigmaTpcDe, + nSigmaTpcPr, + nSigmaItsDe, + nSigmaTofDe, + candidate.ct(o2::constants::physics::MassCDeuteron) * cmToMum, + candFlag, + candSign, + candidate.flagMcMatchRec(), + candidate.originMcRec(), + candidate.flagMcDecayChanRec(), + ctGen, + o2::hf_centrality::getCentralityColl(collision)); + } + + if (fillCandFullTree) { + rowCandCdFull( + candidate.pxProng0(), + candidate.pyProng0(), + candidate.pzProng0(), + candidate.pxProng1(), + candidate.pyProng1(), + candidate.pzProng1(), + candidate.pxProng2(), + candidate.pyProng2(), + candidate.pzProng2(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameter2(), + candidate.decayLength(), + candidate.cpa(), + candidate.chi2PCA(), + nSigmaTpcDe, + nSigmaTpcPr, + nSigmaItsDe, + nSigmaTofDe, + nSigmaTpcPi, + nSigmaTofPi, + nSigmaTpcKa, + nSigmaTofKa, + candidate.ct(o2::constants::physics::MassCDeuteron) * cmToMum, + candFlag, + candSign, + candidate.flagMcMatchRec(), + candidate.originMcRec(), + candidate.flagMcDecayChanRec(), + ctGen, + o2::hf_centrality::getCentralityColl(collision), + collision.posZ(), + collision.globalIndex(), + timeStamp); + } + } + + if (std::abs(candidate.flagMcMatchRec()) != hf_decay::hf_cand_3prong::DecayChannelMain::CDeuteronToDeKPi) { + continue; + } + + registry.fill(HIST("MC/generated/signal/hPtGenSig"), ptGen); + + fillHistogramsRecSig(candidate); + if (candidate.originMcRec() == RecoDecay::OriginType::Prompt) { + fillHistogramsRecSig(candidate); + } else if (candidate.originMcRec() == RecoDecay::OriginType::NonPrompt) { + fillHistogramsRecSig(candidate); + } + + if (fillTHn) { + const float cent = o2::hf_centrality::getCentralityColl(collision); + auto fillTHnRecSig = [&](bool isDeKPi) { + const auto massCd = isDeKPi ? HfHelper::invMassCdToDeKPi(candidate) : HfHelper::invMassCdToPiKDe(candidate); + std::vector valuesToFill{massCd, candidate.pt(), candidate.ptProng0(), candidate.ptProng1(), candidate.ptProng2(), candidate.chi2PCA(), candidate.decayLength(), candidate.cpa(), cent}; + registry.get(HIST("hnCdVars"))->Fill(valuesToFill.data()); + }; + if ((candidate.isSelCdToDeKPi() >= selectionFlagCd) && pdgCodeProng0 == o2::constants::physics::Pdg::kDeuteron) { + fillTHnRecSig(true); + } + if ((candidate.isSelCdToPiKDe() >= selectionFlagCd) && pdgCodeProng0 == kPiPlus) { + fillTHnRecSig(false); + } + } + } + } + + template + void fillHistogramsGen(ParticleType const& particle, float yGen) + { + registry.fill(HIST("MC/generated/") + HIST(SignalFolders[SignalType]) + HIST("/hPtGen") + HIST(SignalSuffixes[SignalType]), particle.pt()); + registry.fill(HIST("MC/generated/") + HIST(SignalFolders[SignalType]) + HIST("/hEtaGen") + HIST(SignalSuffixes[SignalType]), particle.eta()); + registry.fill(HIST("MC/generated/") + HIST(SignalFolders[SignalType]) + HIST("/hYGen") + HIST(SignalSuffixes[SignalType]), yGen); + registry.fill(HIST("MC/generated/") + HIST(SignalFolders[SignalType]) + HIST("/hPhiGen") + HIST(SignalSuffixes[SignalType]), particle.phi()); + registry.fill(HIST("MC/generated/") + HIST(SignalFolders[SignalType]) + HIST("/hEtaVsPtGen") + HIST(SignalSuffixes[SignalType]), particle.eta(), particle.pt()); + registry.fill(HIST("MC/generated/") + HIST(SignalFolders[SignalType]) + HIST("/hYVsPtGen") + HIST(SignalSuffixes[SignalType]), yGen, particle.pt()); + registry.fill(HIST("MC/generated/") + HIST(SignalFolders[SignalType]) + HIST("/hPhiVsPtGen") + HIST(SignalSuffixes[SignalType]), particle.phi(), particle.pt()); + } + + template + void fillHistosMcGen(CandCdMcGen const& mcParticles, Coll const& recoCollisions) + { + for (const auto& particle : mcParticles) { + if (std::abs(particle.flagMcMatchGen()) != hf_decay::hf_cand_3prong::DecayChannelMain::CDeuteronToDeKPi) { + continue; + } + const auto yGen = RecoDecay::y(particle.pVector(), o2::constants::physics::MassCDeuteron); + if (yCandGenMax >= 0. && std::abs(yGen) > yCandGenMax) { + continue; + } + const auto& recoCollsPerMcColl = recoCollisions.sliceBy(colPerMcCollision, particle.mcCollision().globalIndex()); + unsigned int numPvContributors = 0; + float vtxZ = -999.f; + for (const auto& recCol : recoCollsPerMcColl) { + numPvContributors = recCol.numContrib() > numPvContributors ? recCol.numContrib() : numPvContributors; + vtxZ = recCol.posZ(); + } + const float cent = o2::hf_centrality::getCentralityGenColl(recoCollsPerMcColl); + const float ptGenB = particle.originMcGen() == RecoDecay::OriginType::Prompt ? -1.f : mcParticles.rawIteratorAt(particle.idxBhadMotherPart()).pt(); + const auto firstDau = particle.template daughters_as().begin(); + const float ctGen = RecoDecay::ct(std::array{particle.px(), particle.py(), particle.pz()}, RecoDecay::distance(std::array{particle.vx(), particle.vy(), particle.vz()}, std::array{firstDau.vx(), firstDau.vy(), firstDau.vz()}), o2::constants::physics::MassCDeuteron) * cmToMum; + + fillHistogramsGen(particle, yGen); + if (particle.originMcGen() == RecoDecay::OriginType::Prompt) { + fillHistogramsGen(particle, yGen); + } else if (particle.originMcGen() == RecoDecay::OriginType::NonPrompt) { + fillHistogramsGen(particle, yGen); + } + + if (fillTHn) { + std::vector valuesToFill{particle.pt(), cent, yGen, static_cast(numPvContributors), ctGen, ptGenB}; + registry.get(HIST("hnCdVarsGen"))->Fill(valuesToFill.data()); + } + + rowCandCdGen( + particle.pt(), + particle.eta(), + particle.phi(), + yGen, + particle.flagMcMatchGen(), + particle.originMcGen(), + particle.flagMcDecayChanGen(), + ctGen, + cent, + vtxZ, + particle.mcCollision().globalIndex()); + } + } + /// Fill histograms for real data template void fillHistosData(CollType const& collision, CandType const& candidates, TrackType const& /*tracks*/, TrackWithItsType const& tracksWithItsPid, BcType const& /*bcs*/) @@ -525,8 +945,13 @@ struct HfTaskCd { nSigmaTpcPr, nSigmaItsDe, nSigmaTofDe, + candidate.ct(o2::constants::physics::MassCDeuteron), candFlag, candSign, + 0, + 0, + -1, + -1.f, cent); } @@ -556,8 +981,13 @@ struct HfTaskCd { nSigmaTofPi, nSigmaTpcKa, nSigmaTofKa, + candidate.ct(o2::constants::physics::MassCDeuteron), candFlag, candSign, + 0, + 0, + -1, + -1.f, cent, collision.posZ(), collision.globalIndex(), @@ -580,6 +1010,19 @@ struct HfTaskCd { } } + template + void runAnalysisPerCollisionMc(CollType const& collisions, + CandType const& candidates, + CandCdMcGen const& mcParticles, + TrackWithItsType const& tracksWithItsPid, + BcType const& bcs) + { + for (const auto& collision : collisions) { + fillHistosMcRec(collision, candidates, mcParticles, tracksWithItsPid, bcs); + } + fillHistosMcGen(mcParticles, collisions); + } + void processDataStd(CollisionsWEvSel const& collisions, CdCandidates const& selectedCdCandidates, HFTracks const& tracks, @@ -612,6 +1055,42 @@ struct HfTaskCd { runAnalysisPerCollisionData(collisions, selectedCdCandidates, tracks, tracksWithItsPid, bcWithTimeStamps); } PROCESS_SWITCH(HfTaskCd, processDataStdWithFT0M, "Process real data with the standard method and with FT0M centrality", false); + + void processMcStd(CollisionsMc const& collisions, + CdCandidatesMc const& selectedCdCandidatesMc, + McParticles3ProngMatched const& mcParticles, + aod::McCollisions const&, + HFTracksMc const& tracks, + aod::BCsWithTimestamps const& bcWithTimeStamps) + { + auto tracksWithItsPid = soa::Attach(tracks); + runAnalysisPerCollisionMc(collisions, selectedCdCandidatesMc, mcParticles, tracksWithItsPid, bcWithTimeStamps); + } + PROCESS_SWITCH(HfTaskCd, processMcStd, "Process MC with the standard method", false); + + void processMcStdWithFT0C(CollisionsMcWithEvSelFT0C const& collisions, + CdCandidatesMc const& selectedCdCandidatesMc, + McParticles3ProngMatched const& mcParticles, + aod::McCollisions const&, + HFTracksMc const& tracks, + aod::BCsWithTimestamps const& bcWithTimeStamps) + { + auto tracksWithItsPid = soa::Attach(tracks); + runAnalysisPerCollisionMc(collisions, selectedCdCandidatesMc, mcParticles, tracksWithItsPid, bcWithTimeStamps); + } + PROCESS_SWITCH(HfTaskCd, processMcStdWithFT0C, "Process MC with the standard method with FT0C centrality", false); + + void processMcStdWithFT0M(CollisionsMcWithEvSelFT0M const& collisions, + CdCandidatesMc const& selectedCdCandidatesMc, + McParticles3ProngMatched const& mcParticles, + aod::McCollisions const&, + HFTracksMc const& tracks, + aod::BCsWithTimestamps const& bcWithTimeStamps) + { + auto tracksWithItsPid = soa::Attach(tracks); + runAnalysisPerCollisionMc(collisions, selectedCdCandidatesMc, mcParticles, tracksWithItsPid, bcWithTimeStamps); + } + PROCESS_SWITCH(HfTaskCd, processMcStdWithFT0M, "Process MC with the standard method with FT0M centrality", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/D2H/Tasks/taskDeuteronFromLb.cxx b/PWGHF/D2H/Tasks/taskDeuteronFromLb.cxx index 1dc6f54dbe4..db0af2da598 100644 --- a/PWGHF/D2H/Tasks/taskDeuteronFromLb.cxx +++ b/PWGHF/D2H/Tasks/taskDeuteronFromLb.cxx @@ -25,6 +25,7 @@ #include "Common/DataModel/TrackSelectionTables.h" #include +#include #include #include #include @@ -36,8 +37,6 @@ #include #include #include -#include -#include #include @@ -75,7 +74,8 @@ struct HfTaskDeuteronFromLb { Configurable cfgDCAmax{"cfgDCAmax", 1000.0f, "Maximum DCA for deuteron PID"}; Configurable rapidityCut{"rapidityCut", 0.5f, "Rapidity cut"}; // PDG codes - Configurable pdgCodeMother{"pdgCodeMother", -5122, "PDG code of the mother particle (default: anti-Lambda_b)"}; + Configurable pdgCodeBeautyMeson{"pdgCodeBeautyMeson", -521, "PDG code of the beauty meson mother particle (default: B-)"}; + Configurable pdgCodeBeautyBaryon{"pdgCodeBeautyBaryon", -5122, "PDG code of the beauty baryon mother particle (default: anti-Lambda_b)"}; Configurable pdgCodeDaughter{"pdgCodeDaughter", -1000010020, "PDG code of the daughter particle (default: anti-deuteron)"}; int mRunNumber = 0; @@ -91,7 +91,7 @@ struct HfTaskDeuteronFromLb { Preslice trackIndicesPerCollision = o2::aod::track_association::collisionId; - ConfigurableAxis ptAxis{"ptAxis", {100, 0., 10.f}, "p_{T} GeV/c"}; + ConfigurableAxis ptAxis{"ptAxis", {100, 0.f, 10.f}, "p_{T} GeV/c"}; ConfigurableAxis nSigmaAxis{"nSigmaAxis", {200, -10.f, 10.f}, "nSigma"}; ConfigurableAxis dcaXyAxis{"dcaXyAxis", {1000, -0.2f, 0.2f}, "DCA xy (cm)"}; ConfigurableAxis dcaZAxis{"dcaZAxis", {1000, -0.2f, 0.2f}, "DCA z (cm)"}; @@ -102,6 +102,23 @@ struct HfTaskDeuteronFromLb { OutputObj zorroSummary{"zorroSummary"}; OutputObj hProcessedEvents{TH1D("hProcessedEvents", "Event filtered;; Number of events", 4, 0., 4.)}; + bool isSelectedBeautyHadron(int pdgCode) + { + return pdgCode == pdgCodeBeautyMeson || pdgCode == pdgCodeBeautyBaryon; + } + + double getBeautyHadronMass(int pdgCode) + { + if (pdgCode == pdgCodeBeautyMeson) { + return o2::constants::physics::MassBPlus; + } + + if (pdgCode == pdgCodeBeautyBaryon) { + return o2::constants::physics::MassLambdaB0; + } + return -1.; + } + void init(framework::InitContext&) { ccdb->setURL("http://alice-ccdb.cern.ch"); @@ -113,11 +130,6 @@ struct HfTaskDeuteronFromLb { zorroSummary.setObject(zorro.getZorroSummary()); } - QAHistos.add("MC/ptGeneratedLb", "ptGeneratedLb", HistType::kTH1F, {ptAxis}); - QAHistos.add("MC/ptAntiDeuteronPrimary", "ptAntiDeuteronPrimaryReco", HistType::kTH1F, {ptAxis}); - QAHistos.add("MC/ptAntiDeuteronFromLb", "ptAntiDeuteronFromLbReco", HistType::kTH1F, {ptAxis}); - QAHistos.add("MC/hDCAxy-Primary", "DCAxy-Primary", {HistType::kTH1D, {{400, -0.2f, 0.2f, "DCA xy (cm)"}}}); - QAHistos.add("MC/hDCAxy-FromLb", "DCAxy-FromLb", {HistType::kTH1D, {{400, -0.2f, 0.2f, "DCA xy (cm)"}}}); QAHistos.add("Data/hDCAxyVsPt", "DCAxy #bar{d} vs p_{T}", {HistType::kTH2D, {ptAxis, dcaXyAxis}}); QAHistos.add("Data/hDCAzVsPt", "DCAz #bar{d} vs p_{T}", {HistType::kTH2D, {ptAxis, dcaZAxis}}); QAHistos.add("Data/hnSigmaTPCVsPt", "n#sigma TPC vs p_{T} for #bar{d} hypothesis; p_{T} (GeV/c); n#sigma TPC", {HistType::kTH2D, {ptAxis, nSigmaAxis}}); @@ -125,6 +137,31 @@ struct HfTaskDeuteronFromLb { QAHistos.add("Data/ptAntiDeuteron", "ptAntiDeuteron", {HistType::kTH1F, {ptAxis}}); QAHistos.add("Data/etaAntideuteron", "etaAntideuteron", {HistType::kTH1F, {{100, -1.0f, 1.0f, "eta #bar{d}"}}}); QAHistos.add("Data/hVtxZ", "Z-Vertex distribution after selection;Z (cm)", HistType::kTH1F, {{100, -50, 50}}); + // MC generated-level histograms + QAHistos.add("MCGen/ptGeneratedBminus", "p_{T} generated B^{-};p_{T} (GeV/c);Counts", HistType::kTH1F, {ptAxis}); + QAHistos.add("MCGen/ptGeneratedAntiLambdaB", "p_{T} generated #bar{#Lambda}_{b};p_{T} (GeV/c);Counts", HistType::kTH1F, {ptAxis}); + + QAHistos.add("MCGen/ptAntiDeuteronPrimary", "p_{T} #bar{d} primary gen;p_{T} (GeV/c);Counts", HistType::kTH1F, {ptAxis}); + QAHistos.add("MCGen/ptAntiDeuteronFromBeautyHadron", "p_{T} #bar{d} from beauty gen hadrons;p_{T} (GeV/c);Counts", HistType::kTH1F, {ptAxis}); + + QAHistos.add("MCGen/hMotherPdgCode", "PDG code of mother, gen level;PDG code;Counts", HistType::kTH1I, {{12000, -6000, 6000}}); + QAHistos.add("MCGen/ctauBminus", "ctau of B^{-}, gen level;ctau (#mu m);Counts", HistType::kTH1F, {{25, 0., 2000.f}}); + QAHistos.add("MCGen/ctauAntiLambdaB", "ctau of #bar{#Lambda}_{b}, gen level;ctau (#mu m);Counts", HistType::kTH1F, {{25, 0., 2000.f}}); + // MC reco/MC-anchored histograms + QAHistos.add("MCReco/ptAntiDeuteronFromBminus", + "p_{T} #bar{d} from B^{-} reco/MC anchored;p_{T} (GeV/c);Counts", + HistType::kTH1F, {ptAxis}); + + QAHistos.add("MCReco/ptAntiDeuteronFromAntiLambdaB", + "p_{T} #bar{d} from #bar{#Lambda}_{b} reco/MC anchored;p_{T} (GeV/c);Counts", + HistType::kTH1F, {ptAxis}); + QAHistos.add("MCGen/ptAntiDeuteronFromBminus", "p_{T} #bar{d} from B^{-} gen;p_{T} (GeV/c);Counts", HistType::kTH1F, {ptAxis}); + QAHistos.add("MCGen/ptAntiDeuteronFromAntiLambdaB", "p_{T} #bar{d} from #bar{#Lambda}_{b} gen;p_{T} (GeV/c);Counts", HistType::kTH1F, {ptAxis}); + QAHistos.add("MCReco/hDCAxy-Primary", "DCAxy primary reco/MC anchored;DCA xy (cm);Counts", {HistType::kTH1D, {{400, -0.2f, 0.2f, "DCA xy (cm)"}}}); + QAHistos.add("MCReco/hDCAxy-FromBeautyHadron", "DCAxy from beauty reco/MC anchored;DCA xy (cm);Counts", {HistType::kTH1D, {{400, -0.2f, 0.2f, "DCA xy (cm)"}}}); + QAHistos.add("MCReco/hMotherPdgCode", "PDG code of mother, reco/MC anchored;PDG code;Counts", HistType::kTH1I, {{12000, -6000, 6000}}); + QAHistos.add("MCReco/ctauBminus", "ctau of B^{-}, reco/MC anchored;ctau (#mu m);Counts", HistType::kTH1F, {{25, 0., 2000.f}}); + QAHistos.add("MCReco/ctauAntiLambdaB", "ctau of #bar{#Lambda}_{b}, reco/MC anchored;ctau (#mu m);Counts", HistType::kTH1F, {{25, 0., 2000.f}}); hProcessedEvents->GetXaxis()->SetBinLabel(1, "Events processed"); hProcessedEvents->GetXaxis()->SetBinLabel(2, "ZORRO"); @@ -248,9 +285,9 @@ struct HfTaskDeuteronFromLb { } } } - PROCESS_SWITCH(HfTaskDeuteronFromLb, processData, "processData", true); + PROCESS_SWITCH(HfTaskDeuteronFromLb, processData, "processData", false); - void processMC(MCCollisionCandidates::iterator const&, MCTrackCandidates const& tracks, o2::aod::McParticles const&) + void processMC(MCCollisionCandidates::iterator const& collision, MCTrackCandidates const& tracks, o2::aod::McParticles const&) { for (const auto& track : tracks) { if (!passedSingleTrackSelection(track)) { @@ -267,21 +304,42 @@ struct HfTaskDeuteronFromLb { continue; } if (mcParticle.isPhysicalPrimary()) { - bool isFromLb = false; + int motherPdg = 0; if (separateAntideuterons) { for (const auto& mom : mcParticle.mothers_as()) { - if (mom.pdgCode() == pdgCodeMother) { - isFromLb = true; + QAHistos.fill(HIST("MCReco/hMotherPdgCode"), mom.pdgCode()); + if (mom.pdgCode() == pdgCodeBeautyMeson || mom.pdgCode() == pdgCodeBeautyBaryon) { + motherPdg = mom.pdgCode(); + double dx = mcParticle.vx() - collision.posX(); + double dy = mcParticle.vy() - collision.posY(); + double dz = mcParticle.vz() - collision.posZ(); + + double flightDistance = std::sqrt(dx * dx + dy * dy + dz * dz); + double massBeauty = getBeautyHadronMass(mom.pdgCode()); + + if (massBeauty > 0.) { + double ctauBeauty = flightDistance / mom.p() * massBeauty; + ctauBeauty *= 1.e4; + + if (motherPdg == pdgCodeBeautyMeson) { + QAHistos.fill(HIST("MCReco/ctauBminus"), ctauBeauty); + } else if (motherPdg == pdgCodeBeautyBaryon) { + QAHistos.fill(HIST("MCReco/ctauAntiLambdaB"), ctauBeauty); + } + } break; } } } - if (isFromLb) { - QAHistos.fill(HIST("MC/hDCAxy-FromLb"), track.dcaXY()); - QAHistos.fill(HIST("MC/ptAntiDeuteronFromLb"), track.pt()); + if (motherPdg == pdgCodeBeautyMeson) { + QAHistos.fill(HIST("MCReco/hDCAxy-FromBeautyHadron"), track.dcaXY()); + QAHistos.fill(HIST("MCReco/ptAntiDeuteronFromBminus"), track.pt()); + } else if (motherPdg == pdgCodeBeautyBaryon) { + QAHistos.fill(HIST("MCReco/hDCAxy-FromBeautyHadron"), track.dcaXY()); + QAHistos.fill(HIST("MCReco/ptAntiDeuteronFromAntiLambdaB"), track.pt()); } else { - QAHistos.fill(HIST("MC/hDCAxy-Primary"), track.dcaXY()); - QAHistos.fill(HIST("MC/ptAntiDeuteronPrimary"), track.pt()); + QAHistos.fill(HIST("MCReco/hDCAxy-Primary"), track.dcaXY()); + QAHistos.fill(HIST("MCReco/ptAntiDeuteronPrimary"), track.pt()); } } } @@ -289,39 +347,83 @@ struct HfTaskDeuteronFromLb { } PROCESS_SWITCH(HfTaskDeuteronFromLb, processMC, "processMC", false); - void processGen(o2::aod::McCollision const&, o2::aod::McParticles const& mcParticles) + void processGen(o2::aod::McCollision const& collision, o2::aod::McParticles const& mcParticles) { hProcessedEvents->Fill(0.5); + for (const auto& mcParticle : mcParticles) { - if (mcParticle.pdgCode() == pdgCodeMother) { + + // Beauty hadron mother + if (isSelectedBeautyHadron(mcParticle.pdgCode())) { if (std::abs(mcParticle.y()) <= rapidityCut) { - QAHistos.fill(HIST("MC/ptGeneratedLb"), mcParticle.pt()); + if (mcParticle.pdgCode() == pdgCodeBeautyMeson) { + QAHistos.fill(HIST("MCGen/ptGeneratedBminus"), mcParticle.pt()); + } else if (mcParticle.pdgCode() == pdgCodeBeautyBaryon) { + QAHistos.fill(HIST("MCGen/ptGeneratedAntiLambdaB"), mcParticle.pt()); + } + } + + if (mcParticle.has_daughters()) { + + for (const auto& daughter : mcParticle.daughters_as()) { + + double dx = daughter.vx() - collision.posX(); + double dy = daughter.vy() - collision.posY(); + double dz = daughter.vz() - collision.posZ(); + + double flightDistance = std::sqrt(dx * dx + dy * dy + dz * dz); + double massBeauty = getBeautyHadronMass(mcParticle.pdgCode()); + if (massBeauty > 0.) { + double ctauBeauty = flightDistance / mcParticle.p() * massBeauty; + ctauBeauty *= 1.e4; // cm -> micrometers + + if (mcParticle.pdgCode() == pdgCodeBeautyMeson) { + QAHistos.fill(HIST("MCGen/ctauBminus"), ctauBeauty); + } else if (mcParticle.pdgCode() == pdgCodeBeautyBaryon) { + QAHistos.fill(HIST("MCGen/ctauAntiLambdaB"), ctauBeauty); + } + } + break; + } } } if (mcParticle.pdgCode() == pdgCodeDaughter) { - if (std::abs(mcParticle.y()) > rapidityCut) + + if (std::abs(mcParticle.y()) > rapidityCut) { continue; + } - bool isFromLb = false; + int motherPdg = 0; if (mcParticle.has_mothers()) { for (const auto& mom : mcParticle.mothers_as()) { - if (mom.pdgCode() == pdgCodeMother) { - isFromLb = true; + + QAHistos.fill(HIST("MCGen/hMotherPdgCode"), mom.pdgCode()); + + if (mom.pdgCode() == pdgCodeBeautyMeson) { + motherPdg = mom.pdgCode(); + break; + } + + if (mom.pdgCode() == pdgCodeBeautyBaryon) { + motherPdg = mom.pdgCode(); break; } } } - if (isFromLb) { - QAHistos.fill(HIST("MC/ptAntiDeuteronFromLb"), mcParticle.pt()); + if (motherPdg == pdgCodeBeautyMeson) { + QAHistos.fill(HIST("MCGen/ptAntiDeuteronFromBminus"), mcParticle.pt()); + } else if (motherPdg == pdgCodeBeautyBaryon) { + QAHistos.fill(HIST("MCGen/ptAntiDeuteronFromAntiLambdaB"), mcParticle.pt()); } else if (mcParticle.isPhysicalPrimary()) { - QAHistos.fill(HIST("MC/ptAntiDeuteronPrimary"), mcParticle.pt()); + QAHistos.fill(HIST("MCGen/ptAntiDeuteronPrimary"), mcParticle.pt()); } } } } - PROCESS_SWITCH(HfTaskDeuteronFromLb, processGen, "processGen", false); + + PROCESS_SWITCH(HfTaskDeuteronFromLb, processGen, "processGen", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx index c2166cca266..38443379315 100644 --- a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx +++ b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx @@ -91,7 +91,14 @@ DECLARE_SOA_TABLE(HfCandFlowInfos, "AOD", "HFCANDFLOWINFO", full::MlScore1, full::ScalarProd, full::Cent); -DECLARE_SOA_TABLE(HfRedQVecEsEs, "AOD", "HFREDQVECESE", full::RedQVec); +DECLARE_SOA_TABLE(HfCandFlowEses, "AOD", "HFCANDFLOWESE", + full::M, + full::Pt, + full::MlScore0, + full::MlScore1, + full::ScalarProd, + full::Cent, + full::RedQVec); } // namespace o2::aod enum DecayChannel { DplusToPiKPi = 0, @@ -115,7 +122,7 @@ enum RunMode { struct HfTaskFlowCharmHadrons { Produces rowCandMassPtMl; Produces rowCandMassPtMlSpCent; - Produces rowRedQVecEsE; + Produces rowCandFlowEsE; Configurable harmonic{"harmonic", 2, "harmonic number"}; Configurable qVecDetector{"qVecDetector", 3, "Detector for Q vector estimation (FV0A: 0, FT0M: 1, FT0A: 2, FT0C: 3, TPC Pos: 4, TPC Neg: 5, TPC Tot: 6)"}; @@ -299,23 +306,23 @@ struct HfTaskFlowCharmHadrons { } if (doprocessResolutionSP || doprocessResolutionSPEsE) { // enable resolution histograms only for resolution process - registry.add("spReso/hSpResoFT0cFT0a", "hSpResoFT0cFT0a; centrality; Q_{FT0c} #bullet Q_{FT0a}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFT0cFV0a", "hSpResoFT0cFV0a; centrality; Q_{FT0c} #bullet Q_{FV0a}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFT0cTPCpos", "hSpResoFT0cTPCpos; centrality; Q_{FT0c} #bullet Q_{TPCpos}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFT0cTPCneg", "hSpResoFT0cTPCneg; centrality; Q_{FT0c} #bullet Q_{TPCneg}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFT0cTPCtot", "hSpResoFT0cTPCtot; centrality; Q_{FT0c} #bullet Q_{TPCtot}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFT0aFV0a", "hSpResoFT0aFV0a; centrality; Q_{FT0a} #bullet Q_{FV0a}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFT0aTPCpos", "hSpResoFT0aTPCpos; centrality; Q_{FT0a} #bullet Q_{TPCpos}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFT0aTPCneg", "hSpResoFT0aTPCneg; centrality; Q_{FT0a} #bullet Q_{TPCneg}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFT0aTPCtot", "hSpResoFT0aTPCtot; centrality; Q_{FT0m} #bullet Q_{TPCtot}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFT0mFV0a", "hSpResoFT0mFV0a; centrality; Q_{FT0m} #bullet Q_{FV0a}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFT0mTPCpos", "hSpResoFT0mTPCpos; centrality; Q_{FT0m} #bullet Q_{TPCpos}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFT0mTPCneg", "hSpResoFT0mTPCneg; centrality; Q_{FT0m} #bullet Q_{TPCneg}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFT0mTPCtot", "hSpResoFT0mTPCtot; centrality; Q_{FV0a} #bullet Q_{TPCtot}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFV0aTPCpos", "hSpResoFV0aTPCpos; centrality; Q_{FV0a} #bullet Q_{TPCpos}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFV0aTPCneg", "hSpResoFV0aTPCneg; centrality; Q_{FV0a} #bullet Q_{TPCneg}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoFV0aTPCtot", "hSpResoFV0aTPCtot; centrality; Q_{FV0a} #bullet Q_{TPCtot}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); - registry.add("spReso/hSpResoTPCposTPCneg", "hSpResoTPCposTPCneg; centrality; Q_{TPCpos} #bullet Q_{TPCneg}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); + registry.add("spReso/hSpResoFT0cFT0a", "hSpResoFT0cFT0a; centrality; Q_{FT0c} #bullet Q_{FT0a}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFT0cFV0a", "hSpResoFT0cFV0a; centrality; Q_{FT0c} #bullet Q_{FV0a}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFT0cTPCpos", "hSpResoFT0cTPCpos; centrality; Q_{FT0c} #bullet Q_{TPCpos}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFT0cTPCneg", "hSpResoFT0cTPCneg; centrality; Q_{FT0c} #bullet Q_{TPCneg}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFT0cTPCtot", "hSpResoFT0cTPCtot; centrality; Q_{FT0c} #bullet Q_{TPCtot}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFT0aFV0a", "hSpResoFT0aFV0a; centrality; Q_{FT0a} #bullet Q_{FV0a}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFT0aTPCpos", "hSpResoFT0aTPCpos; centrality; Q_{FT0a} #bullet Q_{TPCpos}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFT0aTPCneg", "hSpResoFT0aTPCneg; centrality; Q_{FT0a} #bullet Q_{TPCneg}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFT0aTPCtot", "hSpResoFT0aTPCtot; centrality; Q_{FT0m} #bullet Q_{TPCtot}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFT0mFV0a", "hSpResoFT0mFV0a; centrality; Q_{FT0m} #bullet Q_{FV0a}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFT0mTPCpos", "hSpResoFT0mTPCpos; centrality; Q_{FT0m} #bullet Q_{TPCpos}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFT0mTPCneg", "hSpResoFT0mTPCneg; centrality; Q_{FT0m} #bullet Q_{TPCneg}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFT0mTPCtot", "hSpResoFT0mTPCtot; centrality; Q_{FV0a} #bullet Q_{TPCtot}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFV0aTPCpos", "hSpResoFV0aTPCpos; centrality; Q_{FV0a} #bullet Q_{TPCpos}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFV0aTPCneg", "hSpResoFV0aTPCneg; centrality; Q_{FV0a} #bullet Q_{TPCneg}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoFV0aTPCtot", "hSpResoFV0aTPCtot; centrality; Q_{FV0a} #bullet Q_{TPCtot}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); + registry.add("spReso/hSpResoTPCposTPCneg", "hSpResoTPCposTPCneg; centrality; Q_{TPCpos} #bullet Q_{TPCneg}; |q_{2}|", {HistType::kTH3F, {thnAxisCent, thnAxisScalarProd, thnAxisRedQVec}}); if (doprocessResolutionSPEsE) { registry.add("redQVecs/hSparseRedQVecs", "hSpResoRedQVec; centrality; Q_{red} #bullet Q_{TPCtot}", {HistType::kTHnSparseF, {thnAxisCent, thnAxisRedQVec, thnAxisRedQVec, thnAxisRedQVec, thnAxisRedQVec}}); @@ -812,7 +819,7 @@ struct HfTaskFlowCharmHadrons { } } if (storeRedQVec) { - rowRedQVecEsE(redQVec); + rowCandFlowEsE(massCand, ptCand, outputMl[0], outputMl[1], scalprodCand, cent, redQVec); } if (fillSparse) { fillThn(massCand, ptCand, etaCand, signCand, cent, cosNPhi, sinNPhi, @@ -1037,23 +1044,30 @@ struct HfTaskFlowCharmHadrons { return; } - registry.fill(HIST("spReso/hSpResoFT0cFT0a"), centrality, xQVecFT0c * xQVecFT0a + yQVecFT0c * yQVecFT0a); - registry.fill(HIST("spReso/hSpResoFT0cFV0a"), centrality, xQVecFT0c * xQVecFV0a + yQVecFT0c * yQVecFV0a); - registry.fill(HIST("spReso/hSpResoFT0cTPCpos"), centrality, xQVecFT0c * xQVecTPCPos + yQVecFT0c * yQVecTPCPos); - registry.fill(HIST("spReso/hSpResoFT0cTPCneg"), centrality, xQVecFT0c * xQVecTPCNeg + yQVecFT0c * yQVecTPCNeg); - registry.fill(HIST("spReso/hSpResoFT0cTPCtot"), centrality, xQVecFT0c * xQVecTPCAll + yQVecFT0c * yQVecTPCAll); - registry.fill(HIST("spReso/hSpResoFT0aFV0a"), centrality, xQVecFT0a * xQVecFV0a + yQVecFT0a * yQVecFV0a); - registry.fill(HIST("spReso/hSpResoFT0aTPCpos"), centrality, xQVecFT0a * xQVecTPCPos + yQVecFT0a * yQVecTPCPos); - registry.fill(HIST("spReso/hSpResoFT0aTPCneg"), centrality, xQVecFT0a * xQVecTPCNeg + yQVecFT0a * yQVecTPCNeg); - registry.fill(HIST("spReso/hSpResoFT0aTPCtot"), centrality, xQVecFT0a * xQVecTPCAll + yQVecFT0a * yQVecTPCAll); - registry.fill(HIST("spReso/hSpResoFT0mFV0a"), centrality, xQVecFT0m * xQVecFV0a + yQVecFT0m * yQVecFV0a); - registry.fill(HIST("spReso/hSpResoFT0mTPCpos"), centrality, xQVecFT0m * xQVecTPCPos + yQVecFT0m * yQVecTPCPos); - registry.fill(HIST("spReso/hSpResoFT0mTPCneg"), centrality, xQVecFT0m * xQVecTPCNeg + yQVecFT0m * yQVecTPCNeg); - registry.fill(HIST("spReso/hSpResoFT0mTPCtot"), centrality, xQVecFT0m * xQVecTPCAll + yQVecFT0m * yQVecTPCAll); - registry.fill(HIST("spReso/hSpResoFV0aTPCpos"), centrality, xQVecFV0a * xQVecTPCPos + yQVecFV0a * yQVecTPCPos); - registry.fill(HIST("spReso/hSpResoFV0aTPCneg"), centrality, xQVecFV0a * xQVecTPCNeg + yQVecFV0a * yQVecTPCNeg); - registry.fill(HIST("spReso/hSpResoFV0aTPCtot"), centrality, xQVecFV0a * xQVecTPCAll + yQVecFV0a * yQVecTPCAll); - registry.fill(HIST("spReso/hSpResoTPCposTPCneg"), centrality, xQVecTPCPos * xQVecTPCNeg + yQVecTPCPos * yQVecTPCNeg); + float redQVec{-999.f}; + std::array qVecRedComps{-999.f, -999.f, -999.f}; + if constexpr (HasRedQVecs) { + qVecRedComps = getEseQvec(collision, qVecRedDetector.value); + } + redQVec = std::hypot(qVecRedComps[0], qVecRedComps[1]); + + registry.fill(HIST("spReso/hSpResoFT0cFT0a"), centrality, xQVecFT0c * xQVecFT0a + yQVecFT0c * yQVecFT0a, redQVec); + registry.fill(HIST("spReso/hSpResoFT0cFV0a"), centrality, xQVecFT0c * xQVecFV0a + yQVecFT0c * yQVecFV0a, redQVec); + registry.fill(HIST("spReso/hSpResoFT0cTPCpos"), centrality, xQVecFT0c * xQVecTPCPos + yQVecFT0c * yQVecTPCPos, redQVec); + registry.fill(HIST("spReso/hSpResoFT0cTPCneg"), centrality, xQVecFT0c * xQVecTPCNeg + yQVecFT0c * yQVecTPCNeg, redQVec); + registry.fill(HIST("spReso/hSpResoFT0cTPCtot"), centrality, xQVecFT0c * xQVecTPCAll + yQVecFT0c * yQVecTPCAll, redQVec); + registry.fill(HIST("spReso/hSpResoFT0aFV0a"), centrality, xQVecFT0a * xQVecFV0a + yQVecFT0a * yQVecFV0a, redQVec); + registry.fill(HIST("spReso/hSpResoFT0aTPCpos"), centrality, xQVecFT0a * xQVecTPCPos + yQVecFT0a * yQVecTPCPos, redQVec); + registry.fill(HIST("spReso/hSpResoFT0aTPCneg"), centrality, xQVecFT0a * xQVecTPCNeg + yQVecFT0a * yQVecTPCNeg, redQVec); + registry.fill(HIST("spReso/hSpResoFT0aTPCtot"), centrality, xQVecFT0a * xQVecTPCAll + yQVecFT0a * yQVecTPCAll, redQVec); + registry.fill(HIST("spReso/hSpResoFT0mFV0a"), centrality, xQVecFT0m * xQVecFV0a + yQVecFT0m * yQVecFV0a, redQVec); + registry.fill(HIST("spReso/hSpResoFT0mTPCpos"), centrality, xQVecFT0m * xQVecTPCPos + yQVecFT0m * yQVecTPCPos, redQVec); + registry.fill(HIST("spReso/hSpResoFT0mTPCneg"), centrality, xQVecFT0m * xQVecTPCNeg + yQVecFT0m * yQVecTPCNeg, redQVec); + registry.fill(HIST("spReso/hSpResoFT0mTPCtot"), centrality, xQVecFT0m * xQVecTPCAll + yQVecFT0m * yQVecTPCAll, redQVec); + registry.fill(HIST("spReso/hSpResoFV0aTPCpos"), centrality, xQVecFV0a * xQVecTPCPos + yQVecFV0a * yQVecTPCPos, redQVec); + registry.fill(HIST("spReso/hSpResoFV0aTPCneg"), centrality, xQVecFV0a * xQVecTPCNeg + yQVecFV0a * yQVecTPCNeg, redQVec); + registry.fill(HIST("spReso/hSpResoFV0aTPCtot"), centrality, xQVecFV0a * xQVecTPCAll + yQVecFV0a * yQVecTPCAll, redQVec); + registry.fill(HIST("spReso/hSpResoTPCposTPCneg"), centrality, xQVecTPCPos * xQVecTPCNeg + yQVecTPCPos * yQVecTPCNeg, redQVec); if constexpr (HasRedQVecs) { registry.fill(HIST("redQVecs/hRedQVecFT0C"), centrality, std::hypot(collision.eseQvecFT0CRe(), collision.eseQvecFT0CIm())); diff --git a/PWGHF/D2H/Tasks/taskSigmac.cxx b/PWGHF/D2H/Tasks/taskSigmac.cxx index 1cb94c20c5c..69e370f3fd1 100644 --- a/PWGHF/D2H/Tasks/taskSigmac.cxx +++ b/PWGHF/D2H/Tasks/taskSigmac.cxx @@ -45,6 +45,7 @@ #include #include #include +#include #include using namespace o2; diff --git a/PWGHF/DataModel/CandidateReconstructionTables.h b/PWGHF/DataModel/CandidateReconstructionTables.h index 04f0cdde0cd..b4d60f34123 100644 --- a/PWGHF/DataModel/CandidateReconstructionTables.h +++ b/PWGHF/DataModel/CandidateReconstructionTables.h @@ -23,7 +23,6 @@ // #include "PWGLF/DataModel/LFStrangenessTables.h" -// #include "ALICE3/DataModel/ECAL.h" #include "Common/Core/RecoDecay.h" #include @@ -927,120 +926,6 @@ enum ConstructMethod { DcaFitter = 0, KfParticle }; } // namespace hf_cand_casc_lf -namespace hf_cand_x -{ -DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, HfCand2Prong, "_0"); // Jpsi index -} // namespace hf_cand_x - -// declare dedicated X candidate table -DECLARE_SOA_TABLE(HfCandXBase, "AOD", "HFCANDXBASE", - // general columns - HFCAND_COLUMNS, - // 3-prong specific columns - hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, - hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1, - hf_cand::PxProng2, hf_cand::PyProng2, hf_cand::PzProng2, - hf_cand::ImpactParameter0, hf_cand::ImpactParameter1, hf_cand::ImpactParameter2, - hf_cand::ErrorImpactParameter0, hf_cand::ErrorImpactParameter1, hf_cand::ErrorImpactParameter2, - hf_cand_x::Prong0Id, hf_track_index::Prong1Id, hf_track_index::Prong2Id, // note the difference between Jpsi and pion indices - hf_track_index::HFflag, - /* dynamic columns */ - hf_cand_3prong::M, - hf_cand_3prong::M2, - /* prong 2 */ - hf_cand::PtProng2, - hf_cand::Pt2Prong2, - hf_cand::PVectorProng2, - /* dynamic columns that use candidate momentum components */ - hf_cand::Pt, - hf_cand::Pt2, - hf_cand::P, - hf_cand::P2, - hf_cand::PVector, - hf_cand::Cpa, - hf_cand::CpaXY, - hf_cand::Ct, - hf_cand::ImpactParameterXY, - hf_cand_3prong::MaxNormalisedDeltaIP, - hf_cand::Eta, - hf_cand::Phi, - hf_cand::Y, - hf_cand::E, - hf_cand::E2); - -// extended table with expression columns that can be used as arguments of dynamic columns -DECLARE_SOA_EXTENDED_TABLE_USER(HfCandXExt, HfCandXBase, "HFCANDXEXT", - hf_cand_3prong::Px, hf_cand_3prong::Py, hf_cand_3prong::Pz); - -using HfCandX = HfCandXExt; - -// table with results of reconstruction level MC matching -DECLARE_SOA_TABLE(HfCandXMcRec, "AOD", "HFCANDXMCREC", //! - hf_cand_mc_flag::FlagMcMatchRec, - hf_cand_mc_flag::OriginMcRec, - hf_cand_mc_flag::FlagMcDecayChanRec); - -// table with results of generator level MC matching -DECLARE_SOA_TABLE(HfCandXMcGen, "AOD", "HFCANDXMCGEN", //! - hf_cand_mc_flag::FlagMcMatchGen, - hf_cand_mc_flag::OriginMcGen, - hf_cand_mc_flag::FlagMcDecayChanGen); - -// specific Xicc candidate properties -namespace hf_cand_xicc -{ -DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, HfCand3Prong, "_0"); // Xic index -} // namespace hf_cand_xicc - -// declare dedicated Xicc candidate table -DECLARE_SOA_TABLE(HfCandXiccBase, "AOD", "HFCANDXICCBASE", - // general columns - HFCAND_COLUMNS, - // 2-prong specific columns - hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, - hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1, - hf_cand::ImpactParameter0, hf_cand::ImpactParameter1, - hf_cand::ErrorImpactParameter0, hf_cand::ErrorImpactParameter1, - hf_cand_xicc::Prong0Id, hf_track_index::Prong1Id, - hf_track_index::HFflag, - /* dynamic columns */ - hf_cand_2prong::M, - hf_cand_2prong::M2, - hf_cand_2prong::ImpactParameterProduct, - /* dynamic columns that use candidate momentum components */ - hf_cand::Pt, - hf_cand::Pt2, - hf_cand::P, - hf_cand::P2, - hf_cand::PVector, - hf_cand::Cpa, - hf_cand::CpaXY, - hf_cand::Ct, - hf_cand::ImpactParameterXY, - hf_cand_2prong::MaxNormalisedDeltaIP, - hf_cand::Eta, - hf_cand::Phi, - hf_cand::Y, - hf_cand::E, - hf_cand::E2); - -// extended table with expression columns that can be used as arguments of dynamic columns -DECLARE_SOA_EXTENDED_TABLE_USER(HfCandXiccExt, HfCandXiccBase, "HFCANDXICCEXT", - hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz); - -using HfCandXicc = HfCandXiccExt; - -// table with results of reconstruction level MC matching -DECLARE_SOA_TABLE(HfCandXiccMcRec, "AOD", "HFCANDXICCMCREC", //! - hf_cand_mc_flag::FlagMcMatchRec, - hf_cand_mc_flag::OriginMcRec, - hf_cand_mc_flag::DebugMcRec); - -// table with results of generator level MC matching -DECLARE_SOA_TABLE(HfCandXiccMcGen, "AOD", "HFCANDXICCMCGEN", //! - hf_cand_mc_flag::FlagMcMatchGen, - hf_cand_mc_flag::OriginMcGen); - // specific Omegac and Xic to Xi Pi candidate properties namespace hf_cand_xic0_omegac0 { @@ -1731,67 +1616,6 @@ DECLARE_SOA_TABLE(HfCandXicResid, "AOD", "HFCANDXICRESID", hf_cand_xic_to_xi_pi_pi::YSvPull, hf_cand_xic_to_xi_pi_pi::ZSvPull); -// specific chic candidate properties -// namespace hf_cand_chic -// { -// DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, HfCand2Prong, "_0"); // Jpsi index -// DECLARE_SOA_INDEX_COLUMN_FULL(Prong1, prong1, int, ECALs, "_1"); -// DECLARE_SOA_COLUMN(JpsiToMuMuMass, jpsiToMuMuMass, float); // Jpsi mass -// } // namespace hf_cand_chic - -// // declare dedicated chi_c candidate table -// DECLARE_SOA_TABLE(HfCandChicBase, "AOD", "HFCANDCHICBASE", -// // general columns -// HFCAND_COLUMNS, -// // 2-prong specific columns -// hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, -// hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1, -// hf_cand::ImpactParameter0, hf_cand::ImpactParameter1, -// hf_cand::ErrorImpactParameter0, hf_cand::ErrorImpactParameter1, -// hf_cand_chic::Prong0Id, hf_cand_chic::Prong1Id, -// hf_track_index::HFflag, hf_cand_chic::JpsiToMuMuMass, -// /* dynamic columns */ -// hf_cand_2prong::M, -// hf_cand_2prong::M2, -// /* prong 2 */ -// // hf_cand::PtProng1, -// // hf_cand::Pt2Prong1, -// // hf_cand::PVectorProng1, -// /* dynamic columns that use candidate momentum components */ -// hf_cand::Pt, -// hf_cand::Pt2, -// hf_cand::P, -// hf_cand::P2, -// hf_cand::PVector, -// hf_cand::Cpa, -// hf_cand::CpaXY, -// hf_cand::Ct, -// hf_cand::ImpactParameterXY, -// hf_cand_2prong::MaxNormalisedDeltaIP, -// hf_cand::Eta, -// hf_cand::Phi, -// hf_cand::Y, -// hf_cand::E, -// hf_cand::E2); - -// // extended table with expression columns that can be used as arguments of dynamic columns -// DECLARE_SOA_EXTENDED_TABLE_USER(HfCandChicExt, HfCandChicBase, "HFCANDCHICEXT", -// hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz); - -// using HfCandChic = HfCandChicExt; - -// // table with results of reconstruction level MC matching -// DECLARE_SOA_TABLE(HfCandChicMcRec, "AOD", "HFCANDCHICMCREC", //! -// hf_cand_mc_flag::FlagMcMatchRec, -// hf_cand_mc_flag::OriginMcRec, -// hf_cand_mc_flag::FlagMcDecayChanRec); - -// // table with results of generator level MC matching -// DECLARE_SOA_TABLE(HfCandChicMcGen, "AOD", "HFCANDCHICMCGEN", //! -// hf_cand_mc_flag::FlagMcMatchGen, -// hf_cand_mc_flag::OriginMcGen, -// hf_cand_mc_flag::FlagMcDecayChanGen); - // specific Lb candidate properties namespace hf_cand_lb { @@ -1867,9 +1691,9 @@ DECLARE_SOA_DYNAMIC_COLUMN(ImpactParameterProduct, impactParameterProduct, // Im float impParK0Star = RecoDecay::impParXY(std::array{xVtxP, yVtxP, zVtxP}, std::array{xVtxS, yVtxS, zVtxS}, RecoDecay::pVec(std::array{pxLfTrack0, pyLfTrack0, pzLfTrack0}, std::array{pxLfTrack1, pyLfTrack1, pzLfTrack1})); return impParJpsi * impParK0Star; }); -DECLARE_SOA_DYNAMIC_COLUMN(ImpactParameterProductJpsi, impactParameterProductJpsi, // J/Psi impact parameter for Bs -> J/Psi phi +DECLARE_SOA_DYNAMIC_COLUMN(ImpactParameterProductJpsi, impactParameterProductJpsi, // J/Psi impact parameter product for B0 -> J/Psi K*0 [](float dcaDauPos, float dcaDauNeg) -> float { return dcaDauPos * dcaDauNeg; }); -DECLARE_SOA_DYNAMIC_COLUMN(ImpactParameterProductK0Star, impactParameterProductK0Star, // K*0 impact parameter for B0 -> J/Psi K*0 +DECLARE_SOA_DYNAMIC_COLUMN(ImpactParameterProductK0Star, impactParameterProductK0Star, // K*0 impact parameter product for B0 -> J/Psi K*0 [](float dcaLfTrack0, float dcaLfTrack1) -> float { return dcaLfTrack0 * dcaLfTrack1; }); enum DecayTypeMc : uint8_t { B0ToDplusPiToPiKPiPi = 0, diff --git a/PWGHF/DataModel/CandidateSelectionTables.h b/PWGHF/DataModel/CandidateSelectionTables.h index a359794da92..0e06ab6797c 100644 --- a/PWGHF/DataModel/CandidateSelectionTables.h +++ b/PWGHF/DataModel/CandidateSelectionTables.h @@ -56,56 +56,6 @@ DECLARE_SOA_TABLE(HfMlD0, "AOD", "HFMLD0", //! hf_sel_candidate_d0::MlProbD0, hf_sel_candidate_d0::MlProbD0bar); -namespace hf_sel_candidate_d0_parametrized_pid -{ -DECLARE_SOA_COLUMN(IsSelD0NoPid, isSelD0NoPid, int); //! -DECLARE_SOA_COLUMN(IsSelD0PerfectPid, isSelD0PerfectPid, int); //! -DECLARE_SOA_COLUMN(IsSelD0, isSelD0, int); //! -DECLARE_SOA_COLUMN(IsSelD0barNoPid, isSelD0barNoPid, int); //! -DECLARE_SOA_COLUMN(IsSelD0barPerfectPid, isSelD0barPerfectPid, int); //! -DECLARE_SOA_COLUMN(IsSelD0bar, isSelD0bar, int); //! -} // namespace hf_sel_candidate_d0_parametrized_pid - -DECLARE_SOA_TABLE(HfSelD0ParametrizedPid, "AOD", "HFSELD0P", //! - hf_sel_candidate_d0_parametrized_pid::IsSelD0NoPid, - hf_sel_candidate_d0_parametrized_pid::IsSelD0PerfectPid, - hf_sel_candidate_d0_parametrized_pid::IsSelD0, - hf_sel_candidate_d0_parametrized_pid::IsSelD0barNoPid, - hf_sel_candidate_d0_parametrized_pid::IsSelD0barPerfectPid, - hf_sel_candidate_d0_parametrized_pid::IsSelD0bar); - -namespace hf_sel_candidate_d0_alice3_barrel -{ -DECLARE_SOA_COLUMN(IsSelHfFlag, isSelHfFlag, int); //! -DECLARE_SOA_COLUMN(IsSelD0NoPid, isSelD0NoPid, int); //! -DECLARE_SOA_COLUMN(IsSelD0PerfectPid, isSelD0PerfectPid, int); //! -DECLARE_SOA_COLUMN(IsSelD0TofPid, isSelD0TofPid, int); //! -DECLARE_SOA_COLUMN(IsSelD0RichPid, isSelD0RichPid, int); //! -DECLARE_SOA_COLUMN(IsSelD0TofPlusRichPid, isSelD0TofPlusRichPid, int); //! -DECLARE_SOA_COLUMN(IsSelD0barTofPlusRichPid, isSelD0barTofPlusRichPid, int); //! -} // namespace hf_sel_candidate_d0_alice3_barrel - -DECLARE_SOA_TABLE(HfSelD0Alice3Barrel, "AOD", "HFSELD0A3B", //! - hf_sel_candidate_d0_alice3_barrel::IsSelHfFlag, - hf_sel_candidate_d0_alice3_barrel::IsSelD0NoPid, - hf_sel_candidate_d0_alice3_barrel::IsSelD0PerfectPid, - hf_sel_candidate_d0_alice3_barrel::IsSelD0TofPid, - hf_sel_candidate_d0_alice3_barrel::IsSelD0RichPid, - hf_sel_candidate_d0_alice3_barrel::IsSelD0TofPlusRichPid, - hf_sel_candidate_d0_alice3_barrel::IsSelD0barTofPlusRichPid); - -namespace hf_sel_candidate_d0_alice3_forward -{ -DECLARE_SOA_COLUMN(IsSelHfFlag, isSelHfFlag, int); //! -DECLARE_SOA_COLUMN(IsSelD0FNoPid, isSelD0FNoPid, int); //! -DECLARE_SOA_COLUMN(IsSelD0FRichPid, isSelD0FRichPid, int); //! -} // namespace hf_sel_candidate_d0_alice3_forward - -DECLARE_SOA_TABLE(HfSelD0Alice3Forward, "AOD", "HFSELD0A3F", //! - hf_sel_candidate_d0_alice3_forward::IsSelHfFlag, - hf_sel_candidate_d0_alice3_forward::IsSelD0FNoPid, - hf_sel_candidate_d0_alice3_forward::IsSelD0FRichPid); - namespace hf_sel_candidate_dplus { DECLARE_SOA_COLUMN(IsSelDplusToPiKPi, isSelDplusToPiKPi, int); //! @@ -188,70 +138,6 @@ DECLARE_SOA_COLUMN(IsSelChToPiKHe, isSelChToPiKHe, int); //! DECLARE_SOA_TABLE(HfSelCh, "AOD", "HFSELCH", //! hf_sel_candidate_ch::IsSelChToHeKPi, hf_sel_candidate_ch::IsSelChToPiKHe); -namespace hf_sel_candidate_lc_alice3 -{ -DECLARE_SOA_COLUMN(IsSelLcToPKPiNoPid, isSelLcToPKPiNoPid, int); //! -DECLARE_SOA_COLUMN(IsSelLcToPKPiPerfectPid, isSelLcToPKPiPerfectPid, int); //! -DECLARE_SOA_COLUMN(IsSelLcToPKPiTofPid, isSelLcToPKPiTofPid, int); //! -DECLARE_SOA_COLUMN(IsSelLcToPKPiTofPlusRichPid, isSelLcToPKPiTofPlusRichPid, int); //! -DECLARE_SOA_COLUMN(IsSelLcToPiKPNoPid, isSelLcToPiKPNoPid, int); //! -DECLARE_SOA_COLUMN(IsSelLcToPiKPPerfectPid, isSelLcToPiKPPerfectPid, int); //! -DECLARE_SOA_COLUMN(IsSelLcToPiKPTofPid, isSelLcToPiKPTofPid, int); //! -DECLARE_SOA_COLUMN(IsSelLcToPiKPTofPlusRichPid, isSelLcToPiKPTofPlusRichPid, int); //! -} // namespace hf_sel_candidate_lc_alice3 - -DECLARE_SOA_TABLE(HfSelLcAlice3, "AOD", "HFSELLCA3B", //! - hf_sel_candidate_lc_alice3::IsSelLcToPKPiNoPid, - hf_sel_candidate_lc_alice3::IsSelLcToPKPiPerfectPid, - hf_sel_candidate_lc_alice3::IsSelLcToPKPiTofPid, - hf_sel_candidate_lc_alice3::IsSelLcToPKPiTofPlusRichPid, - hf_sel_candidate_lc_alice3::IsSelLcToPiKPNoPid, - hf_sel_candidate_lc_alice3::IsSelLcToPiKPPerfectPid, - hf_sel_candidate_lc_alice3::IsSelLcToPiKPTofPid, - hf_sel_candidate_lc_alice3::IsSelLcToPiKPTofPlusRichPid); - -namespace hf_sel_candidate_lc_parametrized_pid -{ -DECLARE_SOA_COLUMN(IsSelLcToPKPiNoPid, isSelLcToPKPiNoPid, int); //! -DECLARE_SOA_COLUMN(IsSelLcToPKPiPerfectPid, isSelLcToPKPiPerfectPid, int); //! -DECLARE_SOA_COLUMN(IsSelLcToPKPi, isSelLcToPKPi, int); //! -DECLARE_SOA_COLUMN(IsSelLcToPiKPNoPid, isSelLcToPiKPNoPid, int); //! -DECLARE_SOA_COLUMN(IsSelLcToPiKPPerfectPid, isSelLcToPiKPPerfectPid, int); //! -DECLARE_SOA_COLUMN(IsSelLcToPiKP, isSelLcToPiKP, int); //! -} // namespace hf_sel_candidate_lc_parametrized_pid - -DECLARE_SOA_TABLE(HfSelLcParametrizedPid, "AOD", "HFSELLCP", //! - hf_sel_candidate_lc_parametrized_pid::IsSelLcToPKPiNoPid, - hf_sel_candidate_lc_parametrized_pid::IsSelLcToPKPiPerfectPid, - hf_sel_candidate_lc_parametrized_pid::IsSelLcToPKPi, - hf_sel_candidate_lc_parametrized_pid::IsSelLcToPiKPNoPid, - hf_sel_candidate_lc_parametrized_pid::IsSelLcToPiKPPerfectPid, - hf_sel_candidate_lc_parametrized_pid::IsSelLcToPiKP); - -namespace hf_sel_candidate_jpsi -{ -DECLARE_SOA_COLUMN(IsSelJpsiToEE, isSelJpsiToEE, int); //! -DECLARE_SOA_COLUMN(IsSelJpsiToMuMu, isSelJpsiToMuMu, int); //! -DECLARE_SOA_COLUMN(IsSelJpsiToEETopol, isSelJpsiToEETopol, int); //! -DECLARE_SOA_COLUMN(IsSelJpsiToEETpc, isSelJpsiToEETpc, int); //! -DECLARE_SOA_COLUMN(IsSelJpsiToEETof, isSelJpsiToEETof, int); //! -DECLARE_SOA_COLUMN(IsSelJpsiToEERich, isSelJpsiToEERich, int); //! -DECLARE_SOA_COLUMN(IsSelJpsiToEETofRich, isSelJpsiToEETofRich, int); //! -DECLARE_SOA_COLUMN(IsSelJpsiToMuMuTopol, isSelJpsiToMuMuTopol, int); //! -DECLARE_SOA_COLUMN(IsSelJpsiToMuMuMid, isSelJpsiToMuMuMid, int); //! -} // namespace hf_sel_candidate_jpsi - -DECLARE_SOA_TABLE(HfSelJpsi, "AOD", "HFSELJPSI", //! - hf_sel_candidate_jpsi::IsSelJpsiToEE, - hf_sel_candidate_jpsi::IsSelJpsiToMuMu, - hf_sel_candidate_jpsi::IsSelJpsiToEETopol, - hf_sel_candidate_jpsi::IsSelJpsiToEETpc, - hf_sel_candidate_jpsi::IsSelJpsiToEETof, - hf_sel_candidate_jpsi::IsSelJpsiToEERich, - hf_sel_candidate_jpsi::IsSelJpsiToEETofRich, - hf_sel_candidate_jpsi::IsSelJpsiToMuMuTopol, - hf_sel_candidate_jpsi::IsSelJpsiToMuMuMid); - namespace hf_sel_candidate_lc_to_k0s_p { DECLARE_SOA_COLUMN(IsSelLcToK0sP, isSelLcToK0sP, int); @@ -315,24 +201,6 @@ DECLARE_SOA_TABLE(HfSelLbToLcPi, "AOD", "HFSELLB", //! DECLARE_SOA_TABLE(HfMlLbToLcPi, "AOD", "HFMLLB", //! hf_sel_candidate_lb::MlProbLbToLcPi); -namespace hf_sel_candidate_x -{ -DECLARE_SOA_COLUMN(IsSelXToJpsiToEEPiPi, isSelXToJpsiToEEPiPi, int); //! -DECLARE_SOA_COLUMN(IsSelXToJpsiToMuMuPiPi, isSelXToJpsiToMuMuPiPi, int); //! -} // namespace hf_sel_candidate_x - -DECLARE_SOA_TABLE(HfSelXToJpsiPiPi, "AOD", "HFSELX", //! - hf_sel_candidate_x::IsSelXToJpsiToEEPiPi, hf_sel_candidate_x::IsSelXToJpsiToMuMuPiPi); - -namespace hf_sel_candidate_chic -{ -DECLARE_SOA_COLUMN(IsSelChicToJpsiToEEGamma, isSelChicToJpsiToEEGamma, int); //! -DECLARE_SOA_COLUMN(IsSelChicToJpsiToMuMuGamma, isSelChicToJpsiToMuMuGamma, int); //! -} // namespace hf_sel_candidate_chic - -DECLARE_SOA_TABLE(HfSelChicToJpsiGamma, "AOD", "HFSELCHIC", //! - hf_sel_candidate_chic::IsSelChicToJpsiToEEGamma, hf_sel_candidate_chic::IsSelChicToJpsiToMuMuGamma); - namespace hf_sel_candidate_xic { // XicPlus to P K Pi @@ -363,14 +231,6 @@ DECLARE_SOA_TABLE(HfSelXicToXiPiPi, "AOD", "HFSELXICTOXI2PI", //! DECLARE_SOA_TABLE(HfMlXicToXiPiPi, "AOD", "HFMLXICTOXI2PI", //! hf_sel_candidate_xic::MlProbXicToXiPiPi); -namespace hf_sel_candidate_xicc -{ -DECLARE_SOA_COLUMN(IsSelXiccToPKPiPi, isSelXiccToPKPiPi, int); //! -} // namespace hf_sel_candidate_xicc - -DECLARE_SOA_TABLE(HfSelXiccToPKPiPi, "AOD", "HFSELXICC", //! - hf_sel_candidate_xicc::IsSelXiccToPKPiPi); - namespace hf_sel_toxipi { DECLARE_SOA_COLUMN(StatusPidLambda, statusPidLambda, bool); diff --git a/PWGHF/HFC/DataModel/CorrelationTables.h b/PWGHF/HFC/DataModel/CorrelationTables.h index 02ffed0b9c4..fcf63df4c2a 100644 --- a/PWGHF/HFC/DataModel/CorrelationTables.h +++ b/PWGHF/HFC/DataModel/CorrelationTables.h @@ -316,6 +316,7 @@ DECLARE_SOA_TABLE(CandCharge, "AOD", "CANDCHARGE", // definition of columns and tables for Ds-Hadron correlation pairs namespace hf_correlation_ds_hadron { +DECLARE_SOA_COLUMN(Centrality, centrality, float); //! Centrality of Collision DECLARE_SOA_COLUMN(DeltaPhi, deltaPhi, float); //! DeltaPhi between Ds and Hadrons DECLARE_SOA_COLUMN(DeltaEta, deltaEta, float); //! DeltaEta between Ds and Hadrons DECLARE_SOA_COLUMN(SignedPtD, signedPtD, float); //! Transverse momentum of Ds @@ -341,7 +342,8 @@ DECLARE_SOA_TABLE(DsHadronPair, "AOD", "DSHPAIR", //! Ds-Hadrons pairs Informati aod::hf_correlation_ds_hadron::SignedPtD, aod::hf_correlation_ds_hadron::SignedPtHadron, aod::hf_correlation_ds_hadron::PoolBin, - aod::hf_correlation_ds_hadron::NumPvContrib); + aod::hf_correlation_ds_hadron::NumPvContrib, + aod::hf_correlation_ds_hadron::Centrality); DECLARE_SOA_TABLE(DsHadronRecoInfo, "AOD", "DSHRECOINFO", //! Ds-Hadrons pairs Reconstructed Information aod::hf_correlation_ds_hadron::MD, @@ -362,7 +364,8 @@ DECLARE_SOA_TABLE(DsCandRecoInfo, "AOD", "DSCANDRECOINFO", //! Ds candidates Rec aod::hf_correlation_ds_hadron::SignedPtD, aod::hf_correlation_ds_hadron::MlScorePrompt, aod::hf_correlation_ds_hadron::MlScoreBkg, - aod::hf_correlation_ds_hadron::NumPvContrib); + aod::hf_correlation_ds_hadron::NumPvContrib, + aod::hf_correlation_ds_hadron::Centrality); DECLARE_SOA_TABLE(DsCandGenInfo, "AOD", "DSCANDGENOINFO", //! Ds candidates Generated Information aod::hf_correlation_ds_hadron::IsPrompt); diff --git a/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h b/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h index fb74da7a260..e7c69695f32 100644 --- a/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h +++ b/PWGHF/HFC/DataModel/DerivedDataCorrelationTables.h @@ -32,6 +32,7 @@ DECLARE_SOA_COLUMN(PosZ, posZ, float); //! Primary vertex z posi DECLARE_SOA_TABLE(HfcRedCollisions, "AOD", "HFCREDCOLLISION", //! Table with collision info soa::Index<>, aod::hf_collisions_reduced::Multiplicity, + aod::hf_collisions_reduced::Centrality, aod::hf_collisions_reduced::NumPvContrib, aod::hf_collisions_reduced::PosZ); diff --git a/PWGHF/HFC/TableProducer/correlatorD0D0barBarrelFullPid.cxx b/PWGHF/HFC/TableProducer/correlatorD0D0barBarrelFullPid.cxx index a7efa82e7bd..ff4bdbba50e 100644 --- a/PWGHF/HFC/TableProducer/correlatorD0D0barBarrelFullPid.cxx +++ b/PWGHF/HFC/TableProducer/correlatorD0D0barBarrelFullPid.cxx @@ -14,12 +14,12 @@ /// /// \author Fabio Colamaria , INFN Bari +#include "PWGHF/ALICE3/DataModel/CandidateSelectionTables.h" #include "PWGHF/Core/DecayChannels.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/DataModel/TrackIndexSkimmingTables.h" #include "PWGHF/HFC/DataModel/CorrelationTables.h" #include "PWGHF/Utils/utilsAnalysis.h" diff --git a/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx index e5c3c8d57e0..334e473114c 100644 --- a/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDplusHadrons.cxx @@ -576,7 +576,7 @@ struct HfCorrelatorDplusHadrons { assocTrackSelInfo(indexHfcReducedCollision, track.tpcNClsCrossedRows(), track.itsClusterMap(), track.itsNCls(), track.dcaXY(), track.dcaZ()); } - collReduced(collision.multFT0M(), collision.numContrib(), collision.posZ()); + collReduced(collision.multFT0M(), 0.f, collision.numContrib(), collision.posZ()); } } PROCESS_SWITCH(HfCorrelatorDplusHadrons, processDerivedDataDplus, "Process derived data D+", false); diff --git a/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx index e9461ab0b94..eabedd61556 100644 --- a/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDsHadrons.cxx @@ -28,6 +28,7 @@ #include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" @@ -216,7 +217,7 @@ struct HfCorrelatorDsHadrons { SliceCache cache; - using SelCollisionsWithDs = soa::Filtered>; // collisionFilter applied + using SelCollisionsWithDs = soa::Filtered>; // collisionFilter applied // using SelCollisionsWithDsWithMc = soa::Filtered>; // collisionFilter applied using SelCollisionsMc = soa::Join; using CandDsData = soa::Filtered>; // flagDsFilter applied @@ -468,13 +469,13 @@ struct HfCorrelatorDsHadrons { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbDsToKKPi()[classMl->at(iclass)]; } - entryDsCandRecoInfo(HfHelper::invMassDsToKKPi(candidate), candidate.pt() * chargeDs, outputMl[0], outputMl[2], collision.numContrib()); + entryDsCandRecoInfo(HfHelper::invMassDsToKKPi(candidate), candidate.pt() * chargeDs, outputMl[0], outputMl[2], collision.numContrib(), collision.centFT0M()); } else if (candidate.isSelDsToPiKK() >= selectionFlagDs) { fillHistoPiKK(candidate, efficiencyWeightD); for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl->at(iclass)]; } - entryDsCandRecoInfo(HfHelper::invMassDsToPiKK(candidate), candidate.pt() * chargeDs, outputMl[0], outputMl[2], collision.numContrib()); + entryDsCandRecoInfo(HfHelper::invMassDsToPiKK(candidate), candidate.pt() * chargeDs, outputMl[0], outputMl[2], collision.numContrib(), collision.centFT0M()); } if (candidate.isSelDsToKKPi() >= selectionFlagDs && candidate.isSelDsToPiKK() >= selectionFlagDs) { registry.fill(HIST("hCountSelectionStatusDsToKKPiAndToPiKK"), 0.); @@ -498,7 +499,8 @@ struct HfCorrelatorDsHadrons { candidate.pt() * chargeDs, track.pt() * track.sign(), poolBin, - collision.numContrib()); + collision.numContrib(), + collision.centFT0M()); entryDsHadronRecoInfo(HfHelper::invMassDsToKKPi(candidate), false, false); // entryDsHadronGenInfo(false, false, 0); entryDsHadronMlInfo(outputMl[0], outputMl[2]); @@ -509,7 +511,8 @@ struct HfCorrelatorDsHadrons { candidate.pt() * chargeDs, track.pt() * track.sign(), poolBin, - collision.numContrib()); + collision.numContrib(), + collision.centFT0M()); entryDsHadronRecoInfo(HfHelper::invMassDsToPiKK(candidate), false, false); // entryDsHadronGenInfo(false, false, 0); entryDsHadronMlInfo(outputMl[0], outputMl[2]); @@ -569,7 +572,7 @@ struct HfCorrelatorDsHadrons { registry.fill(HIST("hMassDsMcRecSig"), HfHelper::invMassDsToKKPi(candidate), candidate.pt(), efficiencyWeightD); registry.fill(HIST("hMassDsVsPtMcRec"), HfHelper::invMassDsToKKPi(candidate), candidate.pt(), efficiencyWeightD); registry.fill(HIST("hSelectionStatusDsToKKPiMcRec"), candidate.isSelDsToKKPi()); - entryDsCandRecoInfo(HfHelper::invMassDsToKKPi(candidate), candidate.pt() * chargeDs, outputMl[0], outputMl[2], collision.numContrib()); + entryDsCandRecoInfo(HfHelper::invMassDsToKKPi(candidate), candidate.pt() * chargeDs, outputMl[0], outputMl[2], collision.numContrib(), collision.centFT0M()); entryDsCandGenInfo(isDsPrompt); } else if (candidate.isSelDsToPiKK() >= selectionFlagDs) { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { @@ -579,7 +582,7 @@ struct HfCorrelatorDsHadrons { registry.fill(HIST("hMassDsMcRecSig"), HfHelper::invMassDsToPiKK(candidate), candidate.pt(), efficiencyWeightD); registry.fill(HIST("hMassDsVsPtMcRec"), HfHelper::invMassDsToPiKK(candidate), candidate.pt(), efficiencyWeightD); registry.fill(HIST("hSelectionStatusDsToPiKKMcRec"), candidate.isSelDsToPiKK()); - entryDsCandRecoInfo(HfHelper::invMassDsToPiKK(candidate), candidate.pt() * chargeDs, outputMl[0], outputMl[2], collision.numContrib()); + entryDsCandRecoInfo(HfHelper::invMassDsToPiKK(candidate), candidate.pt() * chargeDs, outputMl[0], outputMl[2], collision.numContrib(), collision.centFT0M()); entryDsCandGenInfo(isDsPrompt); } } else { @@ -653,7 +656,8 @@ struct HfCorrelatorDsHadrons { candidate.pt() * chargeDs, track.pt() * track.sign(), poolBin, - collision.numContrib()); + collision.numContrib(), + collision.centFT0M()); entryDsHadronRecoInfo(HfHelper::invMassDsToKKPi(candidate), isDsSignal, isDecayChan); entryDsHadronMlInfo(outputMl[0], outputMl[2]); isPhysicalPrimary = mcParticle.isPhysicalPrimary(); @@ -675,7 +679,8 @@ struct HfCorrelatorDsHadrons { candidate.pt() * chargeDs, track.pt() * track.sign(), poolBin, - collision.numContrib()); + collision.numContrib(), + collision.centFT0M()); entryDsHadronRecoInfo(HfHelper::invMassDsToPiKK(candidate), isDsSignal, isDecayChan); entryDsHadronMlInfo(outputMl[0], outputMl[2]); isPhysicalPrimary = mcParticle.isPhysicalPrimary(); @@ -819,7 +824,8 @@ struct HfCorrelatorDsHadrons { particle.pt() * chargeDs, particleAssoc.pt() * chargeParticle, poolBin, - 0); + 0, + 0.f); // no multiplicity and centrality info at gen level entryDsHadronRecoInfo(MassDS, true, isDecayChan); entryDsHadronGenInfo(isDsPrompt, particleAssoc.isPhysicalPrimary(), trackOrigin); } // end loop generated particles @@ -902,7 +908,7 @@ struct HfCorrelatorDsHadrons { } } - collReduced(collision.multFT0M(), collision.numContrib(), collision.posZ()); + collReduced(collision.multFT0M(), collision.centFT0M(), collision.numContrib(), collision.posZ()); } } PROCESS_SWITCH(HfCorrelatorDsHadrons, processDerivedDataDs, "Process derived data Ds", false); @@ -952,7 +958,8 @@ struct HfCorrelatorDsHadrons { cand.pt() * chargeDs, pAssoc.pt() * pAssoc.sign(), poolBin, - c1.numContrib()); + c1.numContrib(), + c1.centFT0M()); entryDsHadronRecoInfo(HfHelper::invMassDsToKKPi(cand), false, false); // entryDsHadronGenInfo(false, false, 0); for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { @@ -967,7 +974,8 @@ struct HfCorrelatorDsHadrons { cand.pt() * chargeDs, pAssoc.pt() * pAssoc.sign(), poolBin, - c1.numContrib()); + c1.numContrib(), + c1.centFT0M()); entryDsHadronRecoInfo(HfHelper::invMassDsToPiKK(cand), false, false); // entryDsHadronGenInfo(false, false, 0); for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { @@ -1044,7 +1052,8 @@ struct HfCorrelatorDsHadrons { candidate.pt() * chargeDs, pAssoc.pt() * pAssoc.sign(), poolBin, - c1.numContrib()); + c1.numContrib(), + c1.centFT0M()); entryDsHadronRecoInfo(HfHelper::invMassDsToKKPi(candidate), isDsSignal, isDecayChan); entryDsHadronGenInfo(isDsPrompt, isPhysicalPrimary, trackOrigin); for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { @@ -1058,7 +1067,8 @@ struct HfCorrelatorDsHadrons { candidate.pt() * chargeDs, pAssoc.pt() * pAssoc.sign(), poolBin, - c1.numContrib()); + c1.numContrib(), + c1.centFT0M()); entryDsHadronRecoInfo(HfHelper::invMassDsToPiKK(candidate), isDsSignal, isDecayChan); entryDsHadronGenInfo(isDsPrompt, isPhysicalPrimary, trackOrigin); for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { @@ -1128,7 +1138,8 @@ struct HfCorrelatorDsHadrons { candidate.pt() * chargeDs, particleAssoc.pt() * chargeParticle, poolBin, - 0); + 0, + 0.f); // no multiplicity and centrality info at gen level entryDsHadronRecoInfo(MassDS, true, true); entryDsHadronGenInfo(isDsPrompt, particleAssoc.isPhysicalPrimary(), trackOrigin); } diff --git a/PWGHF/HFC/TableProducer/correlatorDsHadronsReduced.cxx b/PWGHF/HFC/TableProducer/correlatorDsHadronsReduced.cxx index 4da399567b5..4365220fa88 100644 --- a/PWGHF/HFC/TableProducer/correlatorDsHadronsReduced.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDsHadronsReduced.cxx @@ -126,7 +126,7 @@ struct HfCorrelatorDsHadronsReduced { registry.fill(HIST("hDsPoolBin"), poolBin); registry.fill(HIST("hPhiVsPtCand"), RecoDecay::constrainAngle(candidate.phiCand(), -PIHalf), candidate.ptCand()); registry.fill(HIST("hEtaVsPtCand"), candidate.etaCand(), candidate.ptCand()); - entryDsCandRecoInfo(candidate.invMass(), candidate.ptCand(), candidate.bdtScorePrompt(), candidate.bdtScoreBkg(), collision.numPvContrib()); + entryDsCandRecoInfo(candidate.invMass(), candidate.ptCand(), candidate.bdtScorePrompt(), candidate.bdtScoreBkg(), collision.numPvContrib(), collision.centrality()); for (const auto& track : tracksThisColl) { // Removing Ds daughters by checking track indices if ((candidate.prong0Id() == track.originTrackId()) || (candidate.prong1Id() == track.originTrackId()) || (candidate.prong2Id() == track.originTrackId())) { @@ -141,7 +141,8 @@ struct HfCorrelatorDsHadronsReduced { candidate.ptCand(), track.ptAssocTrack(), poolBin, - collision.numPvContrib()); + collision.numPvContrib(), + collision.centrality()); entryDsHadronRecoInfo(candidate.invMass(), false, false); entryDsHadronMlInfo(candidate.bdtScorePrompt(), candidate.bdtScoreBkg()); entryTrackRecoInfo(track.dcaXY(), track.dcaZ(), track.nTpcCrossedRows()); @@ -204,7 +205,8 @@ struct HfCorrelatorDsHadronsReduced { cand.ptCand(), pAssoc.ptAssocTrack(), poolBin, - c1.numPvContrib()); + c1.numPvContrib(), + c1.centrality()); entryDsHadronRecoInfo(cand.invMass(), false, false); // entryDsHadronGenInfo(false, false, 0); } diff --git a/PWGHF/HFC/TableProducer/correlatorLcScHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorLcScHadrons.cxx index 6e148bc6c9e..0b1f7bf87ba 100644 --- a/PWGHF/HFC/TableProducer/correlatorLcScHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorLcScHadrons.cxx @@ -98,16 +98,9 @@ struct HfCorrelatorLcScHadronsSelection { Configurable ptCandMin{"ptCandMin", 1., "min. cand. pT"}; struct : ConfigurableGroup { - Configurable cfgV0radiusMin{"cfgV0radiusMin", 1.2, "minimum decay radius"}; - Configurable cfgDCAPosToPVMin{"cfgDCAPosToPVMin", 0.05, "minimum DCA to PV for positive track"}; - Configurable cfgDCANegToPVMin{"cfgDCANegToPVMin", 0.2, "minimum DCA to PV for negative track"}; - Configurable cfgV0CosPA{"cfgV0CosPA", 0.995, "minimum v0 cosine"}; - Configurable cfgDCAV0Dau{"cfgDCAV0Dau", 1.0, "maximum DCA between daughters"}; - Configurable cfgV0PtMin{"cfgV0PtMin", 0, "minimum pT for lambda"}; - Configurable cfgV0LifeTime{"cfgV0LifeTime", 30., "maximum lambda lifetime"}; - Configurable cfgPV{"cfgPV", 10., "maximum z-vertex"}; Configurable cfgMaxOccupancy{"cfgMaxOccupancy", 999999, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; Configurable cfgMinOccupancy{"cfgMinOccupancy", 0, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; + Configurable cfgPV{"cfgPV", 10., "maximum z-vertex"}; } cfgV0; SliceCache cache; @@ -121,7 +114,7 @@ struct HfCorrelatorLcScHadronsSelection { // filter on selection of Lc and decay channel Lc->PKPi Filter lcFilter = ((o2::aod::hf_track_index::hfflag & static_cast(1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) != static_cast(0)) && (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagLc || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagLc); - template + template void selectionCollision(CollType const& collision, CandType const& candidates) { bool isSelColl = true; @@ -150,6 +143,19 @@ struct HfCorrelatorLcScHadronsSelection { isCandFound = false; continue; } + if constexpr (IsMc) { + auto const mcFlag = std::abs(candidate.flagMcMatchRec()); + + // Cast enums to int to safely compare against the absolute integer flag + bool isSc0 = (mcFlag == static_cast(o2::hf_decay::hf_cand_sigmac::DecayChannelMain::Sc0ToPKPiPi)); + bool isScPlusPlus = (mcFlag == static_cast(o2::hf_decay::hf_cand_sigmac::DecayChannelMain::ScplusplusToPKPiPi)); + bool isLc = (mcFlag == static_cast(o2::hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi)); + + if (!(isSc0 || isScPlusPlus || isLc)) { + isCandFound = false; + continue; + } + } isCandFound = true; break; } @@ -188,37 +194,6 @@ struct HfCorrelatorLcScHadronsSelection { candSel(isCandFound); } - template - bool selectionV0(TCollision const& collision, V0 const& candidate) - { - if (candidate.v0radius() < cfgV0.cfgV0radiusMin) { - return false; - } - if (std::abs(candidate.dcapostopv()) < cfgV0.cfgDCAPosToPVMin) { - return false; - } - if (std::abs(candidate.dcanegtopv()) < cfgV0.cfgDCANegToPVMin) { - return false; - } - if (candidate.v0cosPA() < cfgV0.cfgV0CosPA) { - return false; - } - if (std::abs(candidate.dcaV0daughters()) > cfgV0.cfgDCAV0Dau) { - return false; - } - if (candidate.pt() < cfgV0.cfgV0PtMin) { - return false; - } - if (std::abs(candidate.yLambda()) > yCandMax) { - return false; - } - if (candidate.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda > cfgV0.cfgV0LifeTime) { - return false; - } - - return true; - } - template bool eventSelV0(TCollision collision) { @@ -260,12 +235,7 @@ struct HfCorrelatorLcScHadronsSelection { candSel(isCandFound); return; } - for (const auto& v0 : V0s) { - if (selectionV0(collision, v0)) { - isCandFound = true; - break; - } - } + isCandFound = true; candSel(isCandFound); } PROCESS_SWITCH(HfCorrelatorLcScHadronsSelection, processV0Selection, "Process V0 Collision Selection for Data", true); @@ -273,28 +243,28 @@ struct HfCorrelatorLcScHadronsSelection { void processLcSelection(SelCollisions::iterator const& collision, CandsLcDataFiltered const& candidates) { - selectionCollision(collision, candidates); + selectionCollision(collision, candidates); } PROCESS_SWITCH(HfCorrelatorLcScHadronsSelection, processLcSelection, "Process Lc Collision Selection for Data and Mc", true); void processScSelection(SelCollisions::iterator const& collision, aod::HfCandSc const& candidates) { - selectionCollision(collision, candidates); + selectionCollision(collision, candidates); } PROCESS_SWITCH(HfCorrelatorLcScHadronsSelection, processScSelection, "Process Sc Collision Selection for Data and Mc", false); void processLcSelectionMcRec(SelCollisions::iterator const& collision, CandsLcMcRecFiltered const& candidates) { - selectionCollision(collision, candidates); + selectionCollision(collision, candidates); } PROCESS_SWITCH(HfCorrelatorLcScHadronsSelection, processLcSelectionMcRec, "Process Lc Selection McRec", false); void processScSelectionMcRec(SelCollisions::iterator const& collision, CandsScMcRec const& candidates) { - selectionCollision(collision, candidates); + selectionCollision(collision, candidates); } PROCESS_SWITCH(HfCorrelatorLcScHadronsSelection, processScSelectionMcRec, "Process Sc Selection McRec", false); @@ -376,17 +346,27 @@ struct HfCorrelatorLcScHadrons { } cfgCharmCand; struct : ConfigurableGroup { - Configurable cfgDaughPrPtMax{"cfgDaughPrPtMax", 5., "max. pT Daughter Proton"}; - Configurable cfgDaughPrPtMin{"cfgDaughPrPtMin", 0.3, "min. pT Daughter Proton"}; - Configurable cfgDaughPiPtMax{"cfgDaughPiPtMax", 10., "max. pT Daughter Pion"}; - Configurable cfgDaughPiPtMin{"cfgDaughPiPtMin", 0.3, "min. pT Daughter Pion"}; - Configurable cfgDaughPIDCutsTPCPr{"cfgDaughPIDCutsTPCPr", 2.5, "max. TPCnSigma Proton"}; - Configurable cfgDaughPIDCutsTPCPi{"cfgDaughPIDCutsTPCPi", 2.5, "max. TPCnSigma Pion"}; - Configurable cfgDaughPIDCutsTOFPi{"cfgDaughPIDCutsTOFPi", 2.5, "max. TOFnSigma Pion"}; - Configurable cfgDaughPIDCutsTOFPr{"cfgDaughPIDCutsTOFPr", 2.5, "max. TOFnSigma Pion"}; + Configurable cfgV0DaughPrPtMax{"cfgV0DaughPrPtMax", 5., "max. pT Daughter Proton"}; + Configurable cfgV0DaughPrPtMin{"cfgV0DaughPrPtMin", 0.3, "min. pT Daughter Proton"}; + Configurable cfgV0DaughPiPtMax{"cfgV0DaughPiPtMax", 10., "max. pT Daughter Pion"}; + Configurable cfgV0DaughPiPtMin{"cfgV0DaughPiPtMin", 0.3, "min. pT Daughter Pion"}; + Configurable cfgV0DaughPIDCutsTPCPr{"cfgV0DaughPIDCutsTPCPr", 2.5, "max. TPCnSigma Proton"}; + Configurable cfgV0DaughPIDCutsTPCPi{"cfgV0DaughPIDCutsTPCPi", 2.5, "max. TPCnSigma Pion"}; + Configurable cfgV0DaughPIDCutsTOFPi{"cfgV0DaughPIDCutsTOFPi", 2.5, "max. TOFnSigma Pion"}; + Configurable cfgV0DaughPIDCutsTOFPr{"cfgV0DaughPIDCutsTOFPr", 2.5, "max. TOFnSigma Pion"}; Configurable cfgHypMassWindow{"cfgHypMassWindow", 0.1, "single lambda mass selection"}; Configurable cfgIsCorrCollMatchV0{"cfgIsCorrCollMatchV0", true, "check if daughter and mother collision are same"}; Configurable cfgCalDataDrivenEffPr{"cfgCalDataDrivenEffPr", false, "calculate data driven efficiency of proton using Lambda"}; + Configurable cfgV0radiusMin{"cfgV0radiusMin", 1.2, "minimum decay radius"}; + Configurable cfgDCAPosToPVMin{"cfgDCAPosToPVMin", 0.05, "minimum DCA to PV for positive track"}; + Configurable cfgDCANegToPVMin{"cfgDCANegToPVMin", 0.2, "minimum DCA to PV for negative track"}; + Configurable cfgV0CosPA{"cfgV0CosPA", 0.995, "minimum v0 cosine"}; + Configurable cfgDCAV0Dau{"cfgDCAV0Dau", 1.0, "maximum DCA between daughters"}; + Configurable cfgV0PtMin{"cfgV0PtMin", 0, "minimum pT for lambda"}; + Configurable cfgV0LifeTime{"cfgV0LifeTime", 30., "maximum lambda lifetime"}; + Configurable cfgMaxOccupancy{"cfgMaxOccupancy", 999999, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; + Configurable cfgMinOccupancy{"cfgMinOccupancy", 0, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; + Configurable cfgPV{"cfgPV", 10., "maximum z-vertex"}; Configurable calEffV0{"calEffV0", false, "calculate lambda0 efficiency"}; } cfgV0; @@ -551,6 +531,7 @@ struct HfCorrelatorLcScHadrons { registry.add("hV0LambdaReflMcRec", "McRec V0 Lambda reflected candidates;inv. mass (p #pi) (GeV/#it{c}^{2});GeV/#it{c};GeV/#it{c}", {HistType::kTH3F, {{axisMassV0}, {axisPtV0}, {axisPtHadron}}}); registry.add("hV0LambdaPiKRejMcRec", "McRec V0 Lambda candidates with #pi K rejection;inv. mass (p #pi) (GeV/#it{c}^{2});GeV/#it{c};GeV/#it{c}", {HistType::kTH3F, {{axisMassV0}, {axisPtV0}, {axisPtHadron}}}); registry.add("hV0LambdaReflPiKRejMcRec", "McRec V0 Lambda reflected candidates with #pi K rejection;inv. mass (p #pi) (GeV/#it{c}^{2});GeV/#it{c};GeV/#it{c}", {HistType::kTH3F, {{axisMassV0}, {axisPtV0}, {axisPtHadron}}}); + registry.add("hV0PtPrimLambdaMcGen", "Mcgen V0 Lambda candidates;GeV/#it{c}", {HistType::kTH1F, {{axisPtV0}}}); corrBinning = {{binsZVtx, binsMultiplicity}, true}; } @@ -582,6 +563,37 @@ struct HfCorrelatorLcScHadrons { return y; } + template + bool selectionV0(TCollision const& collision, V0 const& candidate) + { + if (candidate.v0radius() < cfgV0.cfgV0radiusMin) { + return false; + } + if (std::abs(candidate.dcapostopv()) < cfgV0.cfgDCAPosToPVMin) { + return false; + } + if (std::abs(candidate.dcanegtopv()) < cfgV0.cfgDCANegToPVMin) { + return false; + } + if (candidate.v0cosPA() < cfgV0.cfgV0CosPA) { + return false; + } + if (std::abs(candidate.dcaV0daughters()) > cfgV0.cfgDCAV0Dau) { + return false; + } + if (candidate.pt() < cfgV0.cfgV0PtMin) { + return false; + } + if (std::abs(candidate.yLambda()) > cfgCharmCand.yCandMax) { + return false; + } + if (candidate.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda > cfgV0.cfgV0LifeTime) { + return false; + } + + return true; + } + template bool isSelectedV0Daughter(Tracktype const& track, V0Type v0, int pid) { @@ -594,7 +606,7 @@ struct HfCorrelatorLcScHadrons { if (std::abs(pid) == kProton) { bool passTOF = false; - if (track.pt() > cfgV0.cfgDaughPrPtMax || track.pt() < cfgV0.cfgDaughPrPtMin) { + if (track.pt() > cfgV0.cfgV0DaughPrPtMax || track.pt() < cfgV0.cfgV0DaughPrPtMin) { return false; } if (track.hasTOF()) { @@ -602,14 +614,14 @@ struct HfCorrelatorLcScHadrons { // pid > 0: Proton from Lambda (LaPr) // pid < 0: Antiproton from Anti-Lambda (ALaPr) double strangeTOF = (pid > 0) ? v0.tofNSigmaLaPr() : v0.tofNSigmaALaPr(); - passTOF = std::abs(strangeTOF) > cfgV0.cfgDaughPIDCutsTOFPr; + passTOF = std::abs(strangeTOF) > cfgV0.cfgV0DaughPIDCutsTOFPr; } else { // if strange TOF is unavailable - passTOF = std::abs(track.tofNSigmaPr()) > cfgV0.cfgDaughPIDCutsTOFPr; + passTOF = std::abs(track.tofNSigmaPr()) > cfgV0.cfgV0DaughPIDCutsTOFPr; } } - if ((std::abs(track.tpcNSigmaPr()) > cfgV0.cfgDaughPIDCutsTPCPr) || passTOF) { + if ((std::abs(track.tpcNSigmaPr()) > cfgV0.cfgV0DaughPIDCutsTPCPr) || passTOF) { return false; } } @@ -620,7 +632,7 @@ struct HfCorrelatorLcScHadrons { if (std::abs(pid) == kPiPlus) { bool passTOF = false; - if (track.pt() > cfgV0.cfgDaughPiPtMax || track.pt() < cfgV0.cfgDaughPiPtMin) { + if (track.pt() > cfgV0.cfgV0DaughPiPtMax || track.pt() < cfgV0.cfgV0DaughPiPtMin) { return false; } @@ -630,14 +642,14 @@ struct HfCorrelatorLcScHadrons { // We evaluate both applicable hypotheses based on charge sign and pick the best match. double tofLa = (pid > 0) ? v0.tofNSigmaALaPi() : v0.tofNSigmaLaPi(); - passTOF = tofLa > cfgV0.cfgDaughPIDCutsTOFPi; + passTOF = tofLa > cfgV0.cfgV0DaughPIDCutsTOFPi; } else { // Fallback to standard track TOF - passTOF = std::abs(track.tofNSigmaPi()) > cfgV0.cfgDaughPIDCutsTOFPi; + passTOF = std::abs(track.tofNSigmaPi()) > cfgV0.cfgV0DaughPIDCutsTOFPi; } } - if ((std::abs(track.tpcNSigmaPi()) > cfgV0.cfgDaughPIDCutsTPCPi) || passTOF) { + if ((std::abs(track.tpcNSigmaPi()) > cfgV0.cfgV0DaughPIDCutsTPCPi) || passTOF) { return false; } } @@ -815,6 +827,10 @@ struct HfCorrelatorLcScHadrons { const int v0Lambda = 1; const int v0AntiLambda = -1; + if (!selectionV0(collision, v0)) { + continue; + } + auto posTrackV0 = v0.template posTrack_as(); auto negTrackV0 = v0.template negTrack_as(); @@ -920,13 +936,17 @@ struct HfCorrelatorLcScHadrons { // ======================================== // Efficiency calculation block // ======================================== - template - void fillEffV0(V0 const& v0s, + template + void fillEffV0(CollType const& col, + V0 const& v0s, TrackType const&, - aod::McParticles const& mcParticles) + PartType const& mcParticles) { + int countV0 = 1; // Data-driven efficiency calculation for protons using Lambda for (const auto& v0 : v0s) { + bool passV0Sel = selectionV0(col, v0); + auto const& trackV0Pos = v0.template posTrack_as(); auto const& trackV0Neg = v0.template negTrack_as(); if (cfgV0.cfgIsCorrCollMatchV0 && ((v0.collisionId() != trackV0Pos.collisionId()) || (v0.collisionId() != trackV0Neg.collisionId()))) { @@ -934,7 +954,7 @@ struct HfCorrelatorLcScHadrons { } // Process Lambda (proton + pion) - if (std::abs(o2::constants::physics::MassLambda - v0.mLambda()) < cfgV0.cfgHypMassWindow) { + if (passV0Sel && std::abs(o2::constants::physics::MassLambda - v0.mLambda()) < cfgV0.cfgHypMassWindow) { entryHadron(v0.mLambda(), trackV0Pos.eta(), trackV0Pos.pt() * trackV0Pos.sign(), 0, 0, v0.pt()); entryTrkPID(trackV0Pos.tpcNSigmaPr(), trackV0Pos.tpcNSigmaKa(), trackV0Pos.tpcNSigmaPi(), trackV0Pos.tofNSigmaPr(), trackV0Pos.tofNSigmaKa(), trackV0Pos.tofNSigmaPi()); @@ -958,7 +978,7 @@ struct HfCorrelatorLcScHadrons { } } - if (std::abs(o2::constants::physics::MassLambda - v0.mAntiLambda()) < cfgV0.cfgHypMassWindow) { + if (passV0Sel && std::abs(o2::constants::physics::MassLambda - v0.mAntiLambda()) < cfgV0.cfgHypMassWindow) { entryHadron(v0.mAntiLambda(), trackV0Neg.eta(), trackV0Neg.pt() * trackV0Neg.sign(), 0, 0, v0.pt()); entryTrkPID(trackV0Neg.tpcNSigmaPr(), trackV0Neg.tpcNSigmaKa(), trackV0Neg.tpcNSigmaPi(), trackV0Neg.tofNSigmaPr(), trackV0Neg.tofNSigmaKa(), trackV0Neg.tofNSigmaPi()); @@ -991,81 +1011,88 @@ struct HfCorrelatorLcScHadrons { auto const& partV0Pos = trackV0Pos.mcParticle(); auto const& partV0Neg = trackV0Neg.mcParticle(); - if (v0Mc.pdgCode() == kLambda0) { - registry.fill(HIST("hV0LambdaMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); - registry.fill(HIST("hV0LambdaReflMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); - if (cfgV0.calEffV0 && v0Mc.isPhysicalPrimary() && v0Mc.producedByGenerator()) { - registry.fill(HIST("hV0PrimLambdaMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); - registry.fill(HIST("hV0PrimLambdaReflMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); - } + if (passV0Sel && v0Mc.pdgCode() == kLambda0) { + if (isSelectedV0Daughter(trackV0Pos, v0, kProton) && isSelectedV0Daughter(trackV0Neg, v0, kPiMinus)) { + registry.fill(HIST("hV0LambdaMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); + registry.fill(HIST("hV0LambdaReflMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); + if (cfgV0.calEffV0 && v0Mc.isPhysicalPrimary() && v0Mc.producedByGenerator()) { + registry.fill(HIST("hV0PrimLambdaMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); + registry.fill(HIST("hV0PrimLambdaReflMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); + } - if (passPIDSelection(trackV0Pos, cfgCharmCand.trkPIDspecies, cfgCharmCand.pidTPCMax, cfgCharmCand.pidTOFMax, cfgCharmCand.tofPIDThreshold, cfgCharmCand.forceTOF)) { - registry.fill(HIST("hV0LambdaPiKRejMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); - registry.fill(HIST("hV0LambdaReflPiKRejMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); + if (passPIDSelection(trackV0Pos, cfgCharmCand.trkPIDspecies, cfgCharmCand.pidTPCMax, cfgCharmCand.pidTOFMax, cfgCharmCand.tofPIDThreshold, cfgCharmCand.forceTOF)) { + registry.fill(HIST("hV0LambdaPiKRejMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); + registry.fill(HIST("hV0LambdaReflPiKRejMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); + } } } - if (v0Mc.pdgCode() == kLambda0Bar) { - registry.fill(HIST("hV0LambdaMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); - registry.fill(HIST("hV0LambdaReflMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); - - if (cfgV0.calEffV0 && v0Mc.isPhysicalPrimary() && v0Mc.producedByGenerator()) { - registry.fill(HIST("hV0PrimLambdaMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); - registry.fill(HIST("hV0PrimLambdaReflMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); - } - if (passPIDSelection(trackV0Neg, cfgCharmCand.trkPIDspecies, cfgCharmCand.pidTPCMax, cfgCharmCand.pidTOFMax, cfgCharmCand.tofPIDThreshold, cfgCharmCand.forceTOF)) { - registry.fill(HIST("hV0LambdaPiKRejMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); - registry.fill(HIST("hV0LambdaReflPiKRejMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); + if (passV0Sel && v0Mc.pdgCode() == kLambda0Bar) { + if (isSelectedV0Daughter(trackV0Neg, v0, kProtonBar) && isSelectedV0Daughter(trackV0Pos, v0, kPiPlus)) { + registry.fill(HIST("hV0LambdaMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); + registry.fill(HIST("hV0LambdaReflMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); + + if (cfgV0.calEffV0 && v0Mc.isPhysicalPrimary() && v0Mc.producedByGenerator()) { + registry.fill(HIST("hV0PrimLambdaMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); + registry.fill(HIST("hV0PrimLambdaReflMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); + } + if (passPIDSelection(trackV0Neg, cfgCharmCand.trkPIDspecies, cfgCharmCand.pidTPCMax, cfgCharmCand.pidTOFMax, cfgCharmCand.tofPIDThreshold, cfgCharmCand.forceTOF)) { + registry.fill(HIST("hV0LambdaPiKRejMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); + registry.fill(HIST("hV0LambdaReflPiKRejMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); + } } } - } - } + if (cfgV0.calEffV0 && countV0 == 1) { + auto genPart = mcParticles.sliceBy(perTrueCollision, v0Mc.mcCollisionId()); - if constexpr (IsMc) { - if (cfgV0.calEffV0) { + for (const auto& particle : genPart) { - for (const auto& particle : mcParticles) { - - if (std::abs(particle.pdgCode()) != kLambda0) { - continue; - } - - if (std::abs(particle.y()) > cfgCharmCand.yCandMax) { - continue; - } - if (!particle.isPhysicalPrimary() || !particle.producedByGenerator()) { - continue; - } - - auto daughterParts = particle.daughters_as(); - const int8_t nDaughtersV0 = 2; + if (std::abs(particle.pdgCode()) != kLambda0) { + continue; + } - if (daughterParts.size() != nDaughtersV0) { - continue; - } + if (std::abs(particle.y()) > cfgCharmCand.yCandMax) { + continue; + } + if (!particle.isPhysicalPrimary() || !particle.producedByGenerator()) { + continue; + } - for (const auto& currentDaughter : daughterParts) { + auto daughterParts = particle.template daughters_as(); + const int8_t nDaughtersV0 = 2; - if (std::abs(currentDaughter.eta()) > cfgCharmCand.etaTrackMax) { + if (daughterParts.size() != nDaughtersV0) { continue; } - if (std::abs(currentDaughter.pdgCode()) == kProton) { + int8_t countPassedDaughter = 0; + for (const auto& currentDaughter : daughterParts) { - if (currentDaughter.pt() > cfgV0.cfgDaughPrPtMax || currentDaughter.pt() < cfgV0.cfgDaughPrPtMin) { + if (std::abs(currentDaughter.eta()) > cfgCharmCand.etaTrackMax) { continue; } - } else if (std::abs(currentDaughter.pdgCode()) == kPiPlus) { - if (currentDaughter.pt() > cfgV0.cfgDaughPiPtMax || currentDaughter.pt() < cfgV0.cfgDaughPiPtMin) { + if (std::abs(currentDaughter.pdgCode()) == kProton) { + + if (currentDaughter.pt() > cfgV0.cfgV0DaughPrPtMax || currentDaughter.pt() < cfgV0.cfgV0DaughPrPtMin) { + continue; + } + + } else if (std::abs(currentDaughter.pdgCode()) == kPiPlus) { + if (currentDaughter.pt() > cfgV0.cfgV0DaughPiPtMax || currentDaughter.pt() < cfgV0.cfgV0DaughPiPtMin) { + continue; + } + + } else { continue; } - - } else { - continue; + countPassedDaughter++; + } + if (countPassedDaughter == nDaughtersV0) { + registry.fill(HIST("hV0PtPrimLambdaMcGen"), particle.pt()); } } - registry.fill(HIST("hV0PtPrimLambdaMcGen"), particle.pt()); } + countV0++; } } } @@ -1866,12 +1893,12 @@ struct HfCorrelatorLcScHadrons { } PROCESS_SWITCH(HfCorrelatorLcScHadrons, processMcLambdaV0, "Mc process for v0 lambda with Lc", false); - void processLambda0EffCal(SelCollisions::iterator const&, + void processLambda0EffCal(SelCollisions::iterator const& collision, TracksWithMc const& tracks, soa::Join const& v0s, aod::McParticles const& mcParticles) { - fillEffV0(v0s, tracks, mcParticles); + fillEffV0(collision, v0s, tracks, mcParticles); } PROCESS_SWITCH(HfCorrelatorLcScHadrons, processLambda0EffCal, "Mc process for lambda0", false); }; diff --git a/PWGHF/HFC/TableProducer/correlatorXicHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorXicHadrons.cxx index ba25f043366..4cb726052ea 100644 --- a/PWGHF/HFC/TableProducer/correlatorXicHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorXicHadrons.cxx @@ -13,14 +13,10 @@ /// \brief Xic-Hadrons correlator task - data-like, Mc-Reco and Mc-Gen analyses /// \author Ravindra Singh -#include "PWGHF/Core/DecayChannels.h" #include "PWGHF/Core/DecayChannelsLegacy.h" -#include "PWGHF/Core/HfHelper.h" -#include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" -#include "PWGHF/DataModel/TrackIndexSkimmingTables.h" #include "PWGHF/HFC/DataModel/CorrelationTables.h" #include "PWGHF/HFC/Utils/utilsCorrelations.h" #include "PWGHF/Utils/utilsAnalysis.h" @@ -48,17 +44,19 @@ #include #include #include -#include #include #include #include #include +#include + #include #include #include #include +#include #include using namespace o2; @@ -128,13 +126,6 @@ struct HfCorrelatorXicHadronsSelection { Configurable ptCandMin{"ptCandMin", 1., "min. cand. pT"}; struct : ConfigurableGroup { - Configurable cfgV0radiusMin{"cfgV0radiusMin", 1.2, "minimum decay radius"}; - Configurable cfgDCAPosToPVMin{"cfgDCAPosToPVMin", 0.05, "minimum DCA to PV for positive track"}; - Configurable cfgDCANegToPVMin{"cfgDCANegToPVMin", 0.2, "minimum DCA to PV for negative track"}; - Configurable cfgV0CosPA{"cfgV0CosPA", 0.995, "minimum v0 cosine"}; - Configurable cfgDCAV0Dau{"cfgDCAV0Dau", 1.0, "maximum DCA between daughters"}; - Configurable cfgV0PtMin{"cfgV0PtMin", 0, "minimum pT for lambda"}; - Configurable cfgV0LifeTime{"cfgV0LifeTime", 30., "maximum lambda lifetime"}; Configurable cfgPV{"cfgPV", 10., "maximum z-vertex"}; Configurable cfgMaxOccupancy{"cfgMaxOccupancy", 999999, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; Configurable cfgMinOccupancy{"cfgMinOccupancy", 0, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; @@ -158,17 +149,20 @@ struct HfCorrelatorXicHadronsSelection { Filter xicPlusFilter = aod::hf_sel_candidate_xic::isSelXicToXiPiPi >= selectionFlagXic; Filter xic0Filter = aod::hf_sel_toxipi::resultSelections == true; - template + template void selectionCollision(CollType const& collision, CandType const& candidates) { + bool isSelColl = true; bool isCandFound = false; bool isSel8 = true; bool isNosameBunchPileUp = true; - double yCand = -999.; - double massCand = -999.; - double ptCand = -999; + if (doSelXicCollision) { for (const auto& candidate : candidates) { + double massCand = -999.; + double ptCand = -999.; + double yCand = -999.; + // For both XicPlus and Xic0 if constexpr (IsXicPlus) { massCand = o2::constants::physics::MassXiCPlus; @@ -180,23 +174,38 @@ struct HfCorrelatorXicHadronsSelection { yCand = candidate.kfRapXic(); } + // Kinematic cuts if (std::abs(yCand) > yCandMax || ptCand < ptCandMin) { isCandFound = false; continue; } + + if constexpr (IsMc) { + auto const mcFlag = std::abs(candidate.flagMcMatchRec()); + + bool isSignal = (mcFlag == static_cast(o2::aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiPiPi)) || (mcFlag == static_cast(BIT(aod::hf_cand_xic0_omegac0::DecayType::XiczeroToXiPi))); + + if (!isSignal) { + isCandFound = false; + continue; + } + } + // If it passed both Kinematic and MC checks isCandFound = true; break; } } + + // Collision-level cuts if (useSel8) { isSel8 = collision.sel8(); } if (selNoSameBunchPileUpColl) { isNosameBunchPileUp = static_cast(collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)); } - if (isCandFound && isSel8 && isNosameBunchPileUp) { - candSel(true); - } + + isSelColl = isCandFound && isSel8 && isNosameBunchPileUp; + candSel(isSelColl); } template @@ -221,37 +230,6 @@ struct HfCorrelatorXicHadronsSelection { candSel(isCandFound); } - template - bool selectionV0(TCollision const& collision, V0 const& candidate) - { - if (candidate.v0radius() < cfgV0.cfgV0radiusMin) { - return false; - } - if (std::abs(candidate.dcapostopv()) < cfgV0.cfgDCAPosToPVMin) { - return false; - } - if (std::abs(candidate.dcanegtopv()) < cfgV0.cfgDCANegToPVMin) { - return false; - } - if (candidate.v0cosPA() < cfgV0.cfgV0CosPA) { - return false; - } - if (std::abs(candidate.dcaV0daughters()) > cfgV0.cfgDCAV0Dau) { - return false; - } - if (candidate.pt() < cfgV0.cfgV0PtMin) { - return false; - } - if (std::abs(candidate.yLambda()) > yCandMax) { - return false; - } - if (candidate.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda > cfgV0.cfgV0LifeTime) { - return false; - } - - return true; - } - template bool eventSelV0(TCollision const& col) { @@ -292,12 +270,7 @@ struct HfCorrelatorXicHadronsSelection { candSel(isCandFound); return; } - for (const auto& v0 : V0s) { - if (selectionV0(collision, v0)) { - isCandFound = true; - break; - } - } + isCandFound = true; candSel(isCandFound); } PROCESS_SWITCH(HfCorrelatorXicHadronsSelection, processV0Selection, "Process V0 Collision Selection for Data", false); @@ -305,28 +278,28 @@ struct HfCorrelatorXicHadronsSelection { void processXicPlusSelection(SelCollisions::iterator const& collision, CandsXicPlusDataFiltered const& candidates) { - selectionCollision(collision, candidates); + selectionCollision(collision, candidates); } PROCESS_SWITCH(HfCorrelatorXicHadronsSelection, processXicPlusSelection, "Process XicPlus Collision Selection for Data", true); void processXic0Selection(SelCollisions::iterator const& collision, CandsXic0DataFiltered const& candidates) { - selectionCollision(collision, candidates); + selectionCollision(collision, candidates); } PROCESS_SWITCH(HfCorrelatorXicHadronsSelection, processXic0Selection, "Process Xic0 Collision Selection for Data", false); void processXicPlusSelectionMcRec(SelCollisions::iterator const& collision, CandsXicPlusMcRecFiltered const& candidates) { - selectionCollision(collision, candidates); + selectionCollision(collision, candidates); } PROCESS_SWITCH(HfCorrelatorXicHadronsSelection, processXicPlusSelectionMcRec, "Process XicPlus Selection McRec", false); void processXic0SelectionMcRec(SelCollisions::iterator const& collision, CandsXic0McRecFiltered const& candidates) { - selectionCollision(collision, candidates); + selectionCollision(collision, candidates); } PROCESS_SWITCH(HfCorrelatorXicHadronsSelection, processXic0SelectionMcRec, "Process Xic0 Selection McRec", false); @@ -404,17 +377,27 @@ struct HfCorrelatorXicHadrons { } cfgXicCand; struct : ConfigurableGroup { - Configurable cfgDaughPrPtMax{"cfgDaughPrPtMax", 5.f, "max. pT daughter proton"}; - Configurable cfgDaughPrPtMin{"cfgDaughPrPtMin", 0.3f, "min. pT daughter proton"}; - Configurable cfgDaughPiPtMax{"cfgDaughPiPtMax", 10.f, "max. pT daughter pion"}; - Configurable cfgDaughPiPtMin{"cfgDaughPiPtMin", 0.3f, "min. pT daughter pion"}; - Configurable cfgDaughPIDCutsTPCPr{"cfgDaughPIDCutsTPCPr", 2.5f, "max. TPC nSigma proton"}; - Configurable cfgDaughPIDCutsTPCPi{"cfgDaughPIDCutsTPCPi", 2.5f, "max. TPC nSigma pion"}; - Configurable cfgDaughPIDCutsTOFPi{"cfgDaughPIDCutsTOFPi", 2.5f, "max. TOF nSigma pion"}; - Configurable cfgDaughPIDCutsTOFPr{"cfgDaughPIDCutsTOFPr", 2.5f, "max. TOF nSigma pion"}; - Configurable cfgHypMassWindow{"cfgHypMassWindow", 0.1f, "single lambda mass selection"}; + Configurable cfgDaughPrPtMax{"cfgDaughPrPtMax", 5., "max. pT Daughter Proton"}; + Configurable cfgDaughPrPtMin{"cfgDaughPrPtMin", 0.3, "min. pT Daughter Proton"}; + Configurable cfgDaughPiPtMax{"cfgDaughPiPtMax", 10., "max. pT Daughter Pion"}; + Configurable cfgDaughPiPtMin{"cfgDaughPiPtMin", 0.3, "min. pT Daughter Pion"}; + Configurable cfgDaughPIDCutsTPCPr{"cfgDaughPIDCutsTPCPr", 2.5, "max. TPCnSigma Proton"}; + Configurable cfgDaughPIDCutsTPCPi{"cfgDaughPIDCutsTPCPi", 2.5, "max. TPCnSigma Pion"}; + Configurable cfgDaughPIDCutsTOFPi{"cfgDaughPIDCutsTOFPi", 2.5, "max. TOFnSigma Pion"}; + Configurable cfgDaughPIDCutsTOFPr{"cfgDaughPIDCutsTOFPr", 2.5, "max. TOFnSigma Pion"}; + Configurable cfgHypMassWindow{"cfgHypMassWindow", 0.1, "single lambda mass selection"}; Configurable cfgIsCorrCollMatchV0{"cfgIsCorrCollMatchV0", true, "check if daughter and mother collision are same"}; Configurable cfgCalDataDrivenEffPr{"cfgCalDataDrivenEffPr", false, "calculate data driven efficiency of proton using Lambda"}; + Configurable cfgV0radiusMin{"cfgV0radiusMin", 1.2, "minimum decay radius"}; + Configurable cfgDCAPosToPVMin{"cfgDCAPosToPVMin", 0.05, "minimum DCA to PV for positive track"}; + Configurable cfgDCANegToPVMin{"cfgDCANegToPVMin", 0.2, "minimum DCA to PV for negative track"}; + Configurable cfgV0CosPA{"cfgV0CosPA", 0.995, "minimum v0 cosine"}; + Configurable cfgDCAV0Dau{"cfgDCAV0Dau", 1.0, "maximum DCA between daughters"}; + Configurable cfgV0PtMin{"cfgV0PtMin", 0, "minimum pT for lambda"}; + Configurable cfgV0LifeTime{"cfgV0LifeTime", 30., "maximum lambda lifetime"}; + Configurable cfgMaxOccupancy{"cfgMaxOccupancy", 999999, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; + Configurable cfgMinOccupancy{"cfgMinOccupancy", 0, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; + Configurable cfgPV{"cfgPV", 10., "maximum z-vertex"}; Configurable calEffV0{"calEffV0", false, "calculate lambda0 efficiency"}; } cfgV0; @@ -632,6 +615,37 @@ struct HfCorrelatorXicHadrons { } } + template + bool selectionV0(TCollision const& collision, V0 const& candidate) + { + if (candidate.v0radius() < cfgV0.cfgV0radiusMin) { + return false; + } + if (std::abs(candidate.dcapostopv()) < cfgV0.cfgDCAPosToPVMin) { + return false; + } + if (std::abs(candidate.dcanegtopv()) < cfgV0.cfgDCANegToPVMin) { + return false; + } + if (candidate.v0cosPA() < cfgV0.cfgV0CosPA) { + return false; + } + if (std::abs(candidate.dcaV0daughters()) > cfgV0.cfgDCAV0Dau) { + return false; + } + if (candidate.pt() < cfgV0.cfgV0PtMin) { + return false; + } + if (std::abs(candidate.yLambda()) > cfgXicCand.yCandMax) { + return false; + } + if (candidate.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda > cfgV0.cfgV0LifeTime) { + return false; + } + + return true; + } + template bool isSelectedV0Daughter(Tracktype const& track, V0Type v0, int pid) { @@ -698,13 +712,17 @@ struct HfCorrelatorXicHadrons { // ======================================== // Efficiency calculation block // ======================================== - template - void fillEffV0(V0 const& v0s, + template + void fillEffV0(CollType const& col, + V0 const& v0s, TrackType const&, - aod::McParticles const& mcParticles) + PartType const& mcParticles) { + int countV0 = 1; // Data-driven efficiency calculation for protons using Lambda for (const auto& v0 : v0s) { + bool passV0Sel = selectionV0(col, v0); + auto const& trackV0Pos = v0.template posTrack_as(); auto const& trackV0Neg = v0.template negTrack_as(); if (cfgV0.cfgIsCorrCollMatchV0 && ((v0.collisionId() != trackV0Pos.collisionId()) || (v0.collisionId() != trackV0Neg.collisionId()))) { @@ -712,7 +730,7 @@ struct HfCorrelatorXicHadrons { } // Process Lambda (proton + pion) - if (std::abs(o2::constants::physics::MassLambda - v0.mLambda()) < cfgV0.cfgHypMassWindow) { + if (passV0Sel && std::abs(o2::constants::physics::MassLambda - v0.mLambda()) < cfgV0.cfgHypMassWindow) { entryHadron(v0.mLambda(), trackV0Pos.eta(), trackV0Pos.pt() * trackV0Pos.sign(), 0, 0, v0.pt()); entryTrkPID(trackV0Pos.tpcNSigmaPr(), trackV0Pos.tpcNSigmaKa(), trackV0Pos.tpcNSigmaPi(), trackV0Pos.tofNSigmaPr(), trackV0Pos.tofNSigmaKa(), trackV0Pos.tofNSigmaPi()); @@ -736,7 +754,7 @@ struct HfCorrelatorXicHadrons { } } - if (std::abs(o2::constants::physics::MassLambda - v0.mAntiLambda()) < cfgV0.cfgHypMassWindow) { + if (passV0Sel && std::abs(o2::constants::physics::MassLambda - v0.mAntiLambda()) < cfgV0.cfgHypMassWindow) { entryHadron(v0.mAntiLambda(), trackV0Neg.eta(), trackV0Neg.pt() * trackV0Neg.sign(), 0, 0, v0.pt()); entryTrkPID(trackV0Neg.tpcNSigmaPr(), trackV0Neg.tpcNSigmaKa(), trackV0Neg.tpcNSigmaPi(), trackV0Neg.tofNSigmaPr(), trackV0Neg.tofNSigmaKa(), trackV0Neg.tofNSigmaPi()); @@ -769,81 +787,88 @@ struct HfCorrelatorXicHadrons { auto const& partV0Pos = trackV0Pos.mcParticle(); auto const& partV0Neg = trackV0Neg.mcParticle(); - if (v0Mc.pdgCode() == kLambda0) { - registry.fill(HIST("hV0LambdaMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); - registry.fill(HIST("hV0LambdaReflMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); - if (cfgV0.calEffV0 && v0Mc.isPhysicalPrimary() && v0Mc.producedByGenerator()) { - registry.fill(HIST("hV0PrimLambdaMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); - registry.fill(HIST("hV0PrimLambdaReflMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); - } + if (passV0Sel && v0Mc.pdgCode() == kLambda0) { + if (isSelectedV0Daughter(trackV0Pos, v0, kProton) && isSelectedV0Daughter(trackV0Neg, v0, kPiMinus)) { + registry.fill(HIST("hV0LambdaMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); + registry.fill(HIST("hV0LambdaReflMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); + if (cfgV0.calEffV0 && v0Mc.isPhysicalPrimary() && v0Mc.producedByGenerator()) { + registry.fill(HIST("hV0PrimLambdaMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); + registry.fill(HIST("hV0PrimLambdaReflMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); + } - if (passPIDSelection(trackV0Pos, cfgXicCand.trkPIDspecies, cfgXicCand.pidTPCMax, cfgXicCand.pidTOFMax, cfgXicCand.tofPIDThreshold, cfgXicCand.forceTOF)) { - registry.fill(HIST("hV0LambdaPiKRejMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); - registry.fill(HIST("hV0LambdaReflPiKRejMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); + if (passPIDSelection(trackV0Pos, cfgXicCand.trkPIDspecies, cfgXicCand.pidTPCMax, cfgXicCand.pidTOFMax, cfgXicCand.tofPIDThreshold, cfgXicCand.forceTOF)) { + registry.fill(HIST("hV0LambdaPiKRejMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); + registry.fill(HIST("hV0LambdaReflPiKRejMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); + } } } - if (v0Mc.pdgCode() == kLambda0Bar) { - registry.fill(HIST("hV0LambdaMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); - registry.fill(HIST("hV0LambdaReflMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); + if (passV0Sel && v0Mc.pdgCode() == kLambda0Bar) { + if (isSelectedV0Daughter(trackV0Neg, v0, kProtonBar) && isSelectedV0Daughter(trackV0Pos, v0, kPiPlus)) { + registry.fill(HIST("hV0LambdaMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); + registry.fill(HIST("hV0LambdaReflMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); - if (cfgV0.calEffV0 && v0Mc.isPhysicalPrimary() && v0Mc.producedByGenerator()) { - registry.fill(HIST("hV0PrimLambdaMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); - registry.fill(HIST("hV0PrimLambdaReflMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); - } - if (passPIDSelection(trackV0Neg, cfgXicCand.trkPIDspecies, cfgXicCand.pidTPCMax, cfgXicCand.pidTOFMax, cfgXicCand.tofPIDThreshold, cfgXicCand.forceTOF)) { - registry.fill(HIST("hV0LambdaPiKRejMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); - registry.fill(HIST("hV0LambdaReflPiKRejMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); + if (cfgV0.calEffV0 && v0Mc.isPhysicalPrimary() && v0Mc.producedByGenerator()) { + registry.fill(HIST("hV0PrimLambdaMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); + registry.fill(HIST("hV0PrimLambdaReflMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); + } + if (passPIDSelection(trackV0Neg, cfgXicCand.trkPIDspecies, cfgXicCand.pidTPCMax, cfgXicCand.pidTOFMax, cfgXicCand.tofPIDThreshold, cfgXicCand.forceTOF)) { + registry.fill(HIST("hV0LambdaPiKRejMcRec"), v0.mAntiLambda(), v0.pt(), partV0Neg.pt()); + registry.fill(HIST("hV0LambdaReflPiKRejMcRec"), v0.mLambda(), v0.pt(), partV0Pos.pt()); + } } } - } - } - - if constexpr (IsMc) { - if (cfgV0.calEffV0) { + if (cfgV0.calEffV0 && countV0 == 1) { + auto genPart = mcParticles.sliceBy(perTrueCollision, v0Mc.mcCollisionId()); - for (const auto& particle : mcParticles) { - - if (std::abs(particle.pdgCode()) != kLambda0) { - continue; - } - - if (std::abs(particle.y()) > cfgXicCand.yCandMax) { - continue; - } - if (!particle.isPhysicalPrimary() || !particle.producedByGenerator()) { - continue; - } + for (const auto& particle : genPart) { - auto daughterParts = particle.daughters_as(); - const int8_t nDaughtersV0 = 2; + if (std::abs(particle.pdgCode()) != kLambda0) { + continue; + } - if (daughterParts.size() != nDaughtersV0) { - continue; - } + if (std::abs(particle.y()) > cfgXicCand.yCandMax) { + continue; + } + if (!particle.isPhysicalPrimary() || !particle.producedByGenerator()) { + continue; + } - for (const auto& currentDaughter : daughterParts) { + auto daughterParts = particle.template daughters_as(); + const int8_t nDaughtersV0 = 2; - if (std::abs(currentDaughter.eta()) > cfgXicCand.etaTrackMax) { + if (daughterParts.size() != nDaughtersV0) { continue; } - if (std::abs(currentDaughter.pdgCode()) == kProton) { + int8_t countPassedDaughter = 0; + for (const auto& currentDaughter : daughterParts) { - if (currentDaughter.pt() > cfgV0.cfgDaughPrPtMax || currentDaughter.pt() < cfgV0.cfgDaughPrPtMin) { + if (std::abs(currentDaughter.eta()) > cfgXicCand.etaTrackMax) { continue; } - } else if (std::abs(currentDaughter.pdgCode()) == kPiPlus) { - if (currentDaughter.pt() > cfgV0.cfgDaughPiPtMax || currentDaughter.pt() < cfgV0.cfgDaughPiPtMin) { + if (std::abs(currentDaughter.pdgCode()) == kProton) { + + if (currentDaughter.pt() > cfgV0.cfgDaughPrPtMax || currentDaughter.pt() < cfgV0.cfgDaughPrPtMin) { + continue; + } + + } else if (std::abs(currentDaughter.pdgCode()) == kPiPlus) { + if (currentDaughter.pt() > cfgV0.cfgDaughPiPtMax || currentDaughter.pt() < cfgV0.cfgDaughPiPtMin) { + continue; + } + + } else { continue; } - - } else { - continue; + countPassedDaughter++; + } + if (countPassedDaughter == nDaughtersV0) { + registry.fill(HIST("hV0PtPrimLambdaMcGen"), particle.pt()); } } - registry.fill(HIST("hV0PtPrimLambdaMcGen"), particle.pt()); } + countV0++; } } } @@ -996,6 +1021,9 @@ struct HfCorrelatorXicHadrons { // Correlate Xic with all Lambda V0 in the same event for (const auto& v0 : v0s) { + if (!selectionV0(collision, v0)) { + continue; + } auto const& trackV0Pos = v0.template posTrack_as(); auto const& trackV0Neg = v0.template negTrack_as(); @@ -1696,12 +1724,12 @@ struct HfCorrelatorXicHadrons { PROCESS_SWITCH(HfCorrelatorXicHadrons, processMcRecXic0V0, "Mc process for v0 lambda with Xic0", false); /// MC Reco processing: Xic0 with V0 Lambda - void processV0McRec(SelCollisions::iterator const&, + void processV0McRec(SelCollisions::iterator const& collision, TracksWithMc const& tracks, soa::Join const& v0s, aod::McParticles const& mcParticles) { - fillEffV0(v0s, tracks, mcParticles); + fillEffV0(collision, v0s, tracks, mcParticles); } PROCESS_SWITCH(HfCorrelatorXicHadrons, processV0McRec, "Mc process for v0 lambda", false); diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx index fcfd59ea839..d128f50fafb 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsTrackFemtoDream.cxx @@ -21,10 +21,12 @@ #include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Core/DecayChannels.h" +#include "PWGHF/Core/DecayChannelsLegacy.h" #include "PWGHF/Core/HfMlResponseD0ToKPi.h" #include "PWGHF/Core/HfMlResponseDplusToPiKPi.h" #include "PWGHF/Core/HfMlResponseDstarToD0Pi.h" #include "PWGHF/Core/HfMlResponseLcToPKPi.h" +#include "PWGHF/Core/HfMlResponseXicToXiPiPi.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/AliasTables.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" @@ -32,6 +34,7 @@ #include "PWGHF/Utils/utilsBfieldCCDB.h" #include "PWGHF/Utils/utilsEvSelHf.h" +#include "Common/Core/RecoDecay.h" #include "Common/Core/ZorroSummary.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" @@ -98,7 +101,8 @@ enum MlMode : uint8_t { enum DecayChannel { DplusToPiKPi = 0, LcToPKPi, D0ToPiK, - DstarToD0Pi + DstarToD0Pi, + XicToXiPiPi }; enum class D0CandFlag : uint8_t { @@ -109,35 +113,38 @@ enum class D0CandFlag : uint8_t { struct HfProducerCharmHadronsTrackFemtoDream { - Produces outputCollision; - Produces rowMasks; - Produces rowCandCharm3Prong; - Produces rowCandCharm2Prong; - Produces rowCandCharmDstar; - Produces rowCandMcCharmHad; - Produces rowCandCharmHadGen; - Produces outputPartsIndex; - Produces outputPartsTime; - Produces outputMcCollision; - Produces outputCollsMcLabels; - Produces outputParts; - Produces outputPartsMc; - Produces outputDebugParts; - Produces outputPartsMcLabels; - Produces outputDebugPartsMc; - Produces outputPartsExtMcLabels; - - Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable ccdbPathLut{"ccdbPathLut", "GLO/Param/MatLUT", "Path for LUT parametrization"}; - Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "Path of the grp file (Run 2)"}; - Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; - - Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTLc"}, "Paths of models on CCDB"}; - Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_LcToPKPi.onnx"}, "ONNX file names for each pT bin (if not from CCDB full path)"}; - Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB"}; - Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; - - // Configurable isForceGRP{"isForceGRP", false, "Set true if the magnetic field configuration is not available in the usual CCDB directory (e.g. for Run 2 converted data or unanchorad Monte Carlo)"}; + struct : ProducesGroup { + Produces outputCollision; + Produces rowMasks; + Produces rowCandCharm3Prong; + Produces rowCandCharm3ProngXic; + Produces rowCandCharm3ProngXicQa; + Produces rowCandCharm2Prong; + Produces rowCandCharmDstar; + Produces rowCandMcCharmHad; + Produces rowCandCharmHadGen; + Produces outputPartsIndex; + Produces outputPartsTime; + Produces outputMcCollision; + Produces outputCollsMcLabels; + Produces outputParts; + Produces outputPartsMc; + Produces outputDebugParts; + Produces outputPartsMcLabels; + Produces outputDebugPartsMc; + Produces outputPartsExtMcLabels; + } tables; + + struct : ConfigurableGroup { + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbPathLut{"ccdbPathLut", "GLO/Param/MatLUT", "Path for LUT parametrization"}; + Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "Path of the grp file (Run 2)"}; + Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; + Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTLc"}, "Paths of models on CCDB"}; + Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_LcToPKPi.onnx"}, "ONNX file names for each pT bin (if not from CCDB full path)"}; + Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB"}; + Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; + } ccdbCfg; // ------------------------- // Kaon PID cut parameters @@ -157,37 +164,41 @@ struct HfProducerCharmHadronsTrackFemtoDream { Configurable nSigmaCombPiMax{"nSigmaCombPiMax", 6.f, "Kaon PID Method2: for p > pTrackTightMin require |nSigmaCombPi| < this"}; } kaonPidSel; - Configurable isDebug{"isDebug", true, "Enable Debug tables"}; - Configurable isRun3{"isRun3", true, "Running on Run3 or pilot"}; - - /// Charm hadron table - Configurable selectionFlagHadron{"selectionFlagHadron", 1, "Selection Flag for Charm Hadron: 1 for Lc, 7 for Dplus (Topologic and PID cuts)"}; - Configurable useCent{"useCent", false, "Enable centrality for Charm Hadron"}; - - Configurable trkPDGCode{"trkPDGCode", 2212, "PDG code of the selected track for Monte Carlo truth"}; - Configurable> trkCharge{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kSign, "trk"), std::vector{-1, 1}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kSign, "Track selection: ")}; - Configurable> trkDCAxyMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAxyMax, "trk"), std::vector{0.1f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAxyMax, "Track selection: ")}; - Configurable> trkDCAzMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAzMax, "trk"), std::vector{0.2f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAzMax, "Track selection: ")}; - Configurable> trkEta{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kEtaMax, "trk"), std::vector{0.8f, 0.7f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kEtaMax, "Track selection: ")}; - Configurable> trkPIDspecies{"trkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"}; - Configurable> trkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kPIDnSigmaMax, "trk"), std::vector{3.5f, 3.f, 2.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kPIDnSigmaMax, "Track selection: ")}; - Configurable trkPIDnSigmaOffsetTPC{"trkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"}; - Configurable trkPIDnSigmaOffsetTOF{"trkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; - Configurable> trkPtmax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMax, "trk"), std::vector{5.4f, 5.6f, 5.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMax, "Track selection: ")}; - Configurable> trkPtmin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMin, "trk"), std::vector{0.5f, 0.4f, 0.6f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMin, "Track selection: ")}; - Configurable> trkTPCcRowsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCcRowsMin, "trk"), std::vector{70.f, 60.f, 80.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCcRowsMin, "Track selection: ")}; - Configurable> trkTPCfCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCfClsMin, "trk"), std::vector{0.7f, 0.83f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCfClsMin, "Track selection: ")}; - Configurable> trkTPCnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCnClsMin, "trk"), std::vector{80.f, 70.f, 60.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCnClsMin, "Track selection: ")}; - Configurable> trkTPCsCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCsClsMax, "trk"), std::vector{0.1f, 160.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCsClsMax, "Track selection: ")}; - Configurable> trkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsIbMin, "trk"), std::vector{-1.f, 1.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsIbMin, "Track selection: ")}; - Configurable> trkITSnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsMin, "trk"), std::vector{-1.f, 2.f, 4.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsMin, "Track selection: ")}; - // ML inference - Configurable applyMlMode{"applyMlMode", 1, "None: 0, BDT model from candidate selector: 1, New BDT model on Top of candidate selector: 2"}; - Configurable> binsPtMl{"binsPtMl", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; - Configurable> cutDirMl{"cutDirMl", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; - Configurable> cutsMl{"cutsMl", {hf_cuts_ml::Cuts[0], hf_cuts_ml::NBinsPt, hf_cuts_ml::NCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "ML selections per pT bin"}; - Configurable nClassesMl{"nClassesMl", static_cast(hf_cuts_ml::NCutScores), "Number of classes in ML model"}; - Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature1", "feature2"}, "Names of ML model input features"}; + struct : ConfigurableGroup { + Configurable isDebug{"isDebug", true, "Enable Debug tables"}; + Configurable isRun3{"isRun3", true, "Running on Run3 or pilot"}; + Configurable selectionFlagHadron{"selectionFlagHadron", 1, "Selection flag for charm hadrons; applied to D0, Dplus, Lc and Xic selector decisions"}; + Configurable useCent{"useCent", false, "Enable centrality for Charm Hadron"}; + } generalCfg; + + struct : ConfigurableGroup { + Configurable trkPDGCode{"trkPDGCode", 2212, "PDG code of the selected track for Monte Carlo truth"}; + Configurable> trkCharge{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kSign, "trk"), std::vector{-1, 1}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kSign, "Track selection: ")}; + Configurable> trkDCAxyMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAxyMax, "trk"), std::vector{0.1f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAxyMax, "Track selection: ")}; + Configurable> trkDCAzMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAzMax, "trk"), std::vector{0.2f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAzMax, "Track selection: ")}; + Configurable> trkEta{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kEtaMax, "trk"), std::vector{0.8f, 0.7f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kEtaMax, "Track selection: ")}; + Configurable> trkPIDspecies{"trkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"}; + Configurable> trkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kPIDnSigmaMax, "trk"), std::vector{3.5f, 3.f, 2.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kPIDnSigmaMax, "Track selection: ")}; + Configurable trkPIDnSigmaOffsetTPC{"trkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"}; + Configurable trkPIDnSigmaOffsetTOF{"trkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; + Configurable> trkPtmax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMax, "trk"), std::vector{5.4f, 5.6f, 5.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMax, "Track selection: ")}; + Configurable> trkPtmin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kpTMin, "trk"), std::vector{0.5f, 0.4f, 0.6f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kpTMin, "Track selection: ")}; + Configurable> trkTPCcRowsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCcRowsMin, "trk"), std::vector{70.f, 60.f, 80.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCcRowsMin, "Track selection: ")}; + Configurable> trkTPCfCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCfClsMin, "trk"), std::vector{0.7f, 0.83f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCfClsMin, "Track selection: ")}; + Configurable> trkTPCnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCnClsMin, "trk"), std::vector{80.f, 70.f, 60.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCnClsMin, "Track selection: ")}; + Configurable> trkTPCsCls{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kTPCsClsMax, "trk"), std::vector{0.1f, 160.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kTPCsClsMax, "Track selection: ")}; + Configurable> trkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsIbMin, "trk"), std::vector{-1.f, 1.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsIbMin, "Track selection: ")}; + Configurable> trkITSnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsMin, "trk"), std::vector{-1.f, 2.f, 4.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsMin, "Track selection: ")}; + } trackCfg; + + struct : ConfigurableGroup { + Configurable applyMlMode{"applyMlMode", 1, "None: 0, BDT model from candidate selector: 1, New BDT model on Top of candidate selector: 2"}; + Configurable> binsPtMl{"binsPtMl", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; + Configurable> cutDirMl{"cutDirMl", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; + Configurable> cutsMl{"cutsMl", {hf_cuts_ml::Cuts[0], hf_cuts_ml::NBinsPt, hf_cuts_ml::NCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "ML selections per pT bin"}; + Configurable nClassesMl{"nClassesMl", static_cast(hf_cuts_ml::NCutScores), "Number of classes in ML model"}; + Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature1", "feature2"}, "Names of ML model input features"}; + } mlCfg; FemtoDreamTrackSelection trackCuts; @@ -195,6 +206,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { o2::analysis::HfMlResponseDplusToPiKPi hfMlResponseDplus; o2::analysis::HfMlResponseD0ToKPi hfMlResponseD0; o2::analysis::HfMlResponseDstarToD0Pi hfMlResponseDstar; + o2::analysis::HfMlResponseXicToXiPiPi hfMlResponseXic; std::vector outputMlD0; std::vector outputMlD0bar; @@ -202,11 +214,11 @@ struct HfProducerCharmHadronsTrackFemtoDream { std::vector outputMlDplus; std::vector outputMlPKPi; std::vector outputMlPiKP; + std::vector outputMlXic; o2::ccdb::CcdbApi ccdbApi; o2::hf_evsel::HfEventSelection hfEvSel; Service ccdb{}; /// Accessing the CCDB o2::base::MatLayerCylSet* lut{}; - // if (doPvRefit){ lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut));} //! may be it useful, will check later float magField{}; int runNumber{}; @@ -218,6 +230,10 @@ struct HfProducerCharmHadronsTrackFemtoDream { using CandidateDplusMc = soa::Join; using CandidateLc = soa::Join; using CandidateLcMc = soa::Join; + using CandidateXic = soa::Join; + using CandidateXicMc = soa::Join; + using CandidateXicKf = soa::Join; + using CandidateXicKfMc = soa::Join; using FemtoFullCollision = soa::Join::iterator; using FemtoFullCollisionMc = soa::Join::iterator; @@ -231,11 +247,13 @@ struct HfProducerCharmHadronsTrackFemtoDream { using Generated3ProngMc = soa::Join; using Generated2ProngMc = soa::Join; using GeneratedDstarMc = soa::Join; + using GeneratedXicMc = soa::Join; - Filter filterSelectCandidateD0 = (aod::hf_sel_candidate_d0::isSelD0 >= selectionFlagHadron || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlagHadron); + Filter filterSelectCandidateD0 = (aod::hf_sel_candidate_d0::isSelD0 >= generalCfg.selectionFlagHadron || aod::hf_sel_candidate_d0::isSelD0bar >= generalCfg.selectionFlagHadron); Filter filterSelectCandidateDstar = aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == true; - Filter filterSelectCandidateDplus = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagHadron; - Filter filterSelectCandidateLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagHadron || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagHadron); + Filter filterSelectCandidateDplus = aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= generalCfg.selectionFlagHadron; + Filter filterSelectCandidateLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= generalCfg.selectionFlagHadron || aod::hf_sel_candidate_lc::isSelLcToPiKP >= generalCfg.selectionFlagHadron); + Filter filterSelectCandidateXic = aod::hf_sel_candidate_xic::isSelXicToXiPiPi >= generalCfg.selectionFlagHadron; HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry trackRegistry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -243,8 +261,12 @@ struct HfProducerCharmHadronsTrackFemtoDream { void init(InitContext&) { - std::array processes = {doprocessDataDplusToPiKPi, doprocessMcDplusToPiKPi, doprocessDataDplusToPiKPiWithML, doprocessMcDplusToPiKPiWithML, doprocessMcDplusToPiKPiGen, - doprocessDataLcToPKPi, doprocessMcLcToPKPi, doprocessDataLcToPKPiWithML, doprocessMcLcToPKPiWithML, doprocessMcLcToPKPiGen, doprocessDataD0ToPiK, doprocessMcD0ToPiK, doprocessDataD0ToPiKWithML, doprocessMcD0ToPiKWithML, doprocessMcD0ToPiKGen, doprocessDataDstarToD0Pi, doprocessMcDstarToD0Pi, doprocessDataDstarToD0PiWithML, doprocessMcDstarToD0PiWithML, doprocessMcDstarToD0PiGen}; + std::array processes = {doprocessDataDplusToPiKPi, doprocessMcDplusToPiKPi, doprocessDataDplusToPiKPiWithML, doprocessMcDplusToPiKPiWithML, doprocessMcDplusToPiKPiGen, + doprocessDataLcToPKPi, doprocessMcLcToPKPi, doprocessDataLcToPKPiWithML, doprocessMcLcToPKPiWithML, doprocessMcLcToPKPiGen, + doprocessDataD0ToPiK, doprocessMcD0ToPiK, doprocessDataD0ToPiKWithML, doprocessMcD0ToPiKWithML, doprocessMcD0ToPiKGen, + doprocessDataDstarToD0Pi, doprocessMcDstarToD0Pi, doprocessDataDstarToD0PiWithML, doprocessMcDstarToD0PiWithML, doprocessMcDstarToD0PiGen, + doprocessDataXicToXiPiPi, doprocessDataXicToXiPiPiKf, doprocessDataXicToXiPiPiWithML, doprocessDataXicToXiPiPiWithMLKf, + doprocessMcXicToXiPiPi, doprocessMcXicToXiPiPiKf, doprocessMcXicToXiPiPiWithML, doprocessMcXicToXiPiPiWithMLKf, doprocessMcXicToXiPiPiGen}; if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { LOGP(fatal, "One and only one process function must be enabled at a time."); } @@ -253,8 +275,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { trackRegistry.add("AnalysisQA/CutCounter", "; Bit; Counter", kTH1F, {{cutBits + 1, -0.5, cutBits + 0.5}}); // event QA histograms - constexpr int kEventTypes = PairSelected + 1; - std::string labels[kEventTypes]; + constexpr int EventTypes = PairSelected + 1; + std::string labels[EventTypes]; labels[Event::All] = "All events"; labels[Event::RejEveSel] = "rejected by event selection"; labels[Event::RejNoTracksAndCharm] = "rejected by no tracks and charm"; @@ -262,33 +284,33 @@ struct HfProducerCharmHadronsTrackFemtoDream { labels[Event::CharmSelected] = "with charm hadrons "; labels[Event::PairSelected] = "with pairs"; - static const AxisSpec axisEvents = {kEventTypes, 0.5, kEventTypes + 0.5, ""}; + static const AxisSpec axisEvents = {EventTypes, 0.5, EventTypes + 0.5, ""}; qaRegistry.add("hEventQA", "Events;;entries", HistType::kTH1F, {axisEvents}); - for (int iBin = 0; iBin < kEventTypes; iBin++) { + for (int iBin = 0; iBin < EventTypes; iBin++) { qaRegistry.get(HIST("hEventQA"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); } - trackCuts.setSelection(trkCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); - trackCuts.setSelection(trkPtmin, femtoDreamTrackSelection::kpTMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkPtmax, femtoDreamTrackSelection::kpTMax, femtoDreamSelection::kUpperLimit); - trackCuts.setSelection(trkEta, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(trkTPCnclsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkTPCfCls, femtoDreamTrackSelection::kTPCfClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkTPCcRowsMin, femtoDreamTrackSelection::kTPCcRowsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkTPCsCls, femtoDreamTrackSelection::kTPCsClsMax, femtoDreamSelection::kUpperLimit); - trackCuts.setSelection(trkITSnclsMin, femtoDreamTrackSelection::kITSnClsMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkITSnclsIbMin, femtoDreamTrackSelection::kITSnClsIbMin, femtoDreamSelection::kLowerLimit); - trackCuts.setSelection(trkDCAxyMax, femtoDreamTrackSelection::kDCAxyMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(trkDCAzMax, femtoDreamTrackSelection::kDCAzMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setSelection(trkPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); - trackCuts.setPIDSpecies(trkPIDspecies); - trackCuts.setnSigmaPIDOffset(trkPIDnSigmaOffsetTPC, trkPIDnSigmaOffsetTOF); + trackCuts.setSelection(trackCfg.trkCharge, femtoDreamTrackSelection::kSign, femtoDreamSelection::kEqual); + trackCuts.setSelection(trackCfg.trkPtmin, femtoDreamTrackSelection::kpTMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkPtmax, femtoDreamTrackSelection::kpTMax, femtoDreamSelection::kUpperLimit); + trackCuts.setSelection(trackCfg.trkEta, femtoDreamTrackSelection::kEtaMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setSelection(trackCfg.trkTPCnclsMin, femtoDreamTrackSelection::kTPCnClsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkTPCfCls, femtoDreamTrackSelection::kTPCfClsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkTPCcRowsMin, femtoDreamTrackSelection::kTPCcRowsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkTPCsCls, femtoDreamTrackSelection::kTPCsClsMax, femtoDreamSelection::kUpperLimit); + trackCuts.setSelection(trackCfg.trkITSnclsMin, femtoDreamTrackSelection::kITSnClsMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkITSnclsIbMin, femtoDreamTrackSelection::kITSnClsIbMin, femtoDreamSelection::kLowerLimit); + trackCuts.setSelection(trackCfg.trkDCAxyMax, femtoDreamTrackSelection::kDCAxyMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setSelection(trackCfg.trkDCAzMax, femtoDreamTrackSelection::kDCAzMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setSelection(trackCfg.trkPIDnSigmaMax, femtoDreamTrackSelection::kPIDnSigmaMax, femtoDreamSelection::kAbsUpperLimit); + trackCuts.setPIDSpecies(trackCfg.trkPIDspecies); + trackCuts.setnSigmaPIDOffset(trackCfg.trkPIDnSigmaOffsetTPC, trackCfg.trkPIDnSigmaOffsetTOF); trackCuts.init(&qaRegistry, &trackRegistry); runNumber = 0; magField = 0.0; /// Initializing CCDB - ccdb->setURL(ccdbUrl); + ccdb->setURL(ccdbCfg.ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); @@ -301,25 +323,27 @@ struct HfProducerCharmHadronsTrackFemtoDream { bool useDplusMl = doprocessDataDplusToPiKPiWithML || doprocessMcDplusToPiKPiWithML; bool useD0Ml = doprocessDataD0ToPiKWithML || doprocessMcD0ToPiKWithML; bool useDstarMl = doprocessDataDstarToD0PiWithML || doprocessMcDstarToD0PiWithML; + bool useXicMl = doprocessDataXicToXiPiPiWithML || doprocessMcXicToXiPiPiWithML || doprocessDataXicToXiPiPiWithMLKf || doprocessMcXicToXiPiPiWithMLKf; - if (applyMlMode == FillMlFromNewBDT) { + if (mlCfg.applyMlMode == FillMlFromNewBDT) { auto setupFeatures = [&](auto& hfResponse, bool useMlFlag) { if (!useMlFlag) { return; } - hfResponse.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); - hfResponse.cacheInputFeaturesIndices(namesInputFeatures); + hfResponse.configure(mlCfg.binsPtMl, mlCfg.cutsMl, mlCfg.cutDirMl, mlCfg.nClassesMl); + hfResponse.cacheInputFeaturesIndices(mlCfg.namesInputFeatures); }; setupFeatures(hfMlResponseLc, useLcMl); setupFeatures(hfMlResponseDplus, useDplusMl); setupFeatures(hfMlResponseD0, useD0Ml); setupFeatures(hfMlResponseDstar, useDstarMl); + setupFeatures(hfMlResponseXic, useXicMl); - const bool useAnyMl = useLcMl || useDplusMl || useD0Ml || useDstarMl; - if (loadModelsFromCCDB && useAnyMl) { - ccdbApi.init(ccdbUrl); + const bool useAnyMl = useLcMl || useDplusMl || useD0Ml || useDstarMl || useXicMl; + if (ccdbCfg.loadModelsFromCCDB && useAnyMl) { + ccdbApi.init(ccdbCfg.ccdbUrl); } auto initModel = [&](auto& hfResponse, bool useMlFlag) { @@ -327,10 +351,10 @@ struct HfProducerCharmHadronsTrackFemtoDream { return; } - if (loadModelsFromCCDB) { - hfResponse.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + if (ccdbCfg.loadModelsFromCCDB) { + hfResponse.setModelPathsCCDB(ccdbCfg.onnxFileNames, ccdbApi, ccdbCfg.modelPathsCCDB, ccdbCfg.timestampCCDB); } else { - hfResponse.setModelPathsLocal(onnxFileNames); + hfResponse.setModelPathsLocal(ccdbCfg.onnxFileNames); } hfResponse.init(); }; @@ -339,6 +363,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { initModel(hfMlResponseDplus, useDplusMl); initModel(hfMlResponseD0, useD0Ml); initModel(hfMlResponseDstar, useDstarMl); + initModel(hfMlResponseXic, useXicMl); } } @@ -403,41 +428,41 @@ struct HfProducerCharmHadronsTrackFemtoDream { /// Function to retrieve the nominal magnetic field in kG (0.1T) and convert it directly to T void getMagneticFieldTesla(const aod::BCsWithTimestamps::iterator& bc) { - initCCDB(bc, runNumber, ccdb, !isRun3 ? ccdbPathGrp : ccdbPathGrpMag, lut, !isRun3); + initCCDB(bc, runNumber, ccdb, !generalCfg.isRun3 ? ccdbCfg.ccdbPathGrp : ccdbCfg.ccdbPathGrpMag, lut, !generalCfg.isRun3); } template void fillDebugParticle(ParticleType const& particle) { - outputDebugParts(particle.sign(), - (uint8_t)particle.tpcNClsFound(), - particle.tpcNClsFindable(), - (uint8_t)particle.tpcNClsCrossedRows(), - particle.tpcNClsShared(), - particle.tpcInnerParam(), - particle.itsNCls(), - particle.itsNClsInnerBarrel(), - particle.dcaXY(), - particle.dcaZ(), - particle.tpcSignal(), - -999., - particle.tpcNSigmaPi(), - particle.tpcNSigmaKa(), - particle.tpcNSigmaPr(), - particle.tpcNSigmaDe(), - -999., - -999., - -999., - particle.tofNSigmaPi(), - particle.tofNSigmaKa(), - particle.tofNSigmaPr(), - particle.tofNSigmaDe(), - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999., -999., - -999., -999., -999.); + tables.outputDebugParts(particle.sign(), + (uint8_t)particle.tpcNClsFound(), + particle.tpcNClsFindable(), + (uint8_t)particle.tpcNClsCrossedRows(), + particle.tpcNClsShared(), + particle.tpcInnerParam(), + particle.itsNCls(), + particle.itsNClsInnerBarrel(), + particle.dcaXY(), + particle.dcaZ(), + particle.tpcSignal(), + -999., + particle.tpcNSigmaPi(), + particle.tpcNSigmaKa(), + particle.tpcNSigmaPr(), + particle.tpcNSigmaDe(), + -999., + -999., + -999., + particle.tofNSigmaPi(), + particle.tofNSigmaKa(), + particle.tofNSigmaPr(), + particle.tofNSigmaDe(), + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999., -999., + -999., -999., -999.); } template @@ -454,7 +479,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { auto motherparticlesMc = particleMc.template mothers_as(); // check pdg code // if this fails, the particle is a fake - if (std::abs(pdgCode) == std::abs(trkPDGCode.value)) { + if (std::abs(pdgCode) == std::abs(trackCfg.trkPDGCode.value)) { // check first if particle is from pile up // check if the collision associated with the particle is the same as the analyzed collision by checking their Ids if ((col.has_mcCollision() && (particleMc.mcCollisionId() != col.mcCollisionId())) || !col.has_mcCollision()) { @@ -470,7 +495,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { // get direct mother auto motherparticleMc = motherparticlesMc.front(); pdgCodeMother = motherparticleMc.pdgCode(); - particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode(), pdgCode); // check if particle is material // particle is from inelastic hadronic interaction -> getProcess() == 23 // particle is generated during transport -> getGenStatusCode() == -1 @@ -485,16 +510,16 @@ struct HfProducerCharmHadronsTrackFemtoDream { particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kFake; } - outputPartsMc(particleOrigin, pdgCode, particleMc.pt(), particleMc.eta(), particleMc.phi()); - outputPartsMcLabels(outputPartsMc.lastIndex()); - if (isDebug) { - outputPartsExtMcLabels(outputPartsMc.lastIndex()); - outputDebugPartsMc(pdgCodeMother); + tables.outputPartsMc(particleOrigin, pdgCode, particleMc.pt(), particleMc.eta(), particleMc.phi()); + tables.outputPartsMcLabels(tables.outputPartsMc.lastIndex()); + if (generalCfg.isDebug) { + tables.outputPartsExtMcLabels(tables.outputPartsMc.lastIndex()); + tables.outputDebugPartsMc(pdgCodeMother); } } else { - outputPartsMcLabels(-1); - if (isDebug) { - outputPartsExtMcLabels(-1); + tables.outputPartsMcLabels(-1); + if (generalCfg.isDebug) { + tables.outputPartsExtMcLabels(-1); } } } @@ -504,10 +529,10 @@ struct HfProducerCharmHadronsTrackFemtoDream { { if (col.has_mcCollision()) { // auto genMCcol = col.template mcCollision_as(); - // outputMcCollision(genMCcol.multMCNParticlesEta08()); - outputCollsMcLabels(outputMcCollision.lastIndex()); + // tables.outputMcCollision(genMCcol.multMCNParticlesEta08()); + tables.outputCollsMcLabels(tables.outputMcCollision.lastIndex()); } else { - outputCollsMcLabels(-1); + tables.outputCollsMcLabels(-1); } } @@ -532,35 +557,35 @@ struct HfProducerCharmHadronsTrackFemtoDream { auto bc = col.template bc_as(); int64_t timeStamp = bc.timestamp(); // track global index - outputPartsIndex(track.globalIndex()); - outputPartsTime(timeStamp); + tables.outputPartsIndex(track.globalIndex()); + tables.outputPartsTime(timeStamp); // now the table is filled - if (trkPDGCode == kKPlus) { + if (trackCfg.trkPDGCode == kKPlus) { const auto pidTrackPassBit = static_cast(isTrackKaonPidSelected(track)); - outputParts(outputCollision.lastIndex(), - track.pt(), - track.eta(), - track.phi(), - aod::femtodreamparticle::ParticleType::kTrack, - cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), - pidTrackPassBit, - track.dcaXY(), childIDs, 0, 0); + tables.outputParts(tables.outputCollision.lastIndex(), + track.pt(), + track.eta(), + track.phi(), + aod::femtodreamparticle::ParticleType::kTrack, + cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), + pidTrackPassBit, + track.dcaXY(), childIDs, 0, 0); } else { - outputParts(outputCollision.lastIndex(), - track.pt(), - track.eta(), - track.phi(), - aod::femtodreamparticle::ParticleType::kTrack, - cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), - cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kPID), - track.dcaXY(), childIDs, 0, 0); + tables.outputParts(tables.outputCollision.lastIndex(), + track.pt(), + track.eta(), + track.phi(), + aod::femtodreamparticle::ParticleType::kTrack, + cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kCuts), + cutContainer.at(femtoDreamTrackSelection::TrackContainerPosition::kPID), + track.dcaXY(), childIDs, 0, 0); } fIsTrackFilled = true; // tmpIDtrack.push_back(track.globalIndex()); - if (isDebug.value) { + if (generalCfg.isDebug.value) { fillDebugParticle(track); } @@ -579,8 +604,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { const auto spher = 2.; // dummy value for the moment float mult = 0; int multNtr = 0; - if (isRun3) { - if (useCent) { + if (generalCfg.isRun3) { + if (generalCfg.useCent) { mult = col.centFT0M(); } else { mult = 0; @@ -608,19 +633,11 @@ struct HfProducerCharmHadronsTrackFemtoDream { return; } - outputCollision(vtxZ, mult, multNtr, spher, magField); + tables.outputCollision(vtxZ, mult, multNtr, spher, magField); if constexpr (IsMc) { fillMcCollision(col); } - // Filling candidate properties - if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi) { - rowCandCharm3Prong.reserve(sizeCand); - } else if constexpr (Channel == DecayChannel::D0ToPiK) { - rowCandCharm2Prong.reserve(sizeCand); - } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { - rowCandCharmDstar.reserve(sizeCand); - } bool isTrackFilled = false; bool isSelectedMlLcToPKPi = true; bool isSelectedMlLcToPiKP = true; @@ -629,6 +646,14 @@ struct HfProducerCharmHadronsTrackFemtoDream { bool isSelectedMlD0barToKPi = true; bool isSelectedMlDstarToD0Pi = true; + if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi) { + tables.rowCandCharm3Prong.reserve(tables.rowCandCharm3Prong.lastIndex() + sizeCand * 2 + 1); + } else if constexpr (Channel == DecayChannel::D0ToPiK) { + tables.rowCandCharm2Prong.reserve(tables.rowCandCharm2Prong.lastIndex() + sizeCand * 2 + 1); + } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { + tables.rowCandCharmDstar.reserve(tables.rowCandCharmDstar.lastIndex() + sizeCand + 1); + } + for (const auto& candidate : candidates) { outputMlD0 = {-1.0f, -1.0f, -1.0f}; outputMlD0bar = {-1.0f, -1.0f, -1.0f}; @@ -650,8 +675,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { if (functionSelection >= 1) { if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi) { auto trackPos2 = candidate.template prong2_as(); - rowCandCharm3Prong( - outputCollision.lastIndex(), + tables.rowCandCharm3Prong( + tables.outputCollision.lastIndex(), timeStamp, trackPos1.sign() + trackNeg.sign() + trackPos2.sign(), trackPos1.globalIndex(), @@ -682,8 +707,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { } else { LOG(error) << "Unexpected candFlag = " << candFlag; } - rowCandCharm2Prong( - outputCollision.lastIndex(), + tables.rowCandCharm2Prong( + tables.outputCollision.lastIndex(), timeStamp, signD0, trackPos1.globalIndex(), @@ -700,8 +725,8 @@ struct HfProducerCharmHadronsTrackFemtoDream { bdtScoreFd); } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { auto trackPos2 = candidate.template prongPi_as(); - rowCandCharmDstar( - outputCollision.lastIndex(), + tables.rowCandCharmDstar( + tables.outputCollision.lastIndex(), timeStamp, candidate.template prongPi_as().sign(), trackPos1.globalIndex(), @@ -723,7 +748,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } if constexpr (IsMc) { - rowCandMcCharmHad( + tables.rowCandMcCharmHad( candidate.flagMcMatchRec(), candidate.originMcRec()); } @@ -734,13 +759,13 @@ struct HfProducerCharmHadronsTrackFemtoDream { if constexpr (UseCharmMl) { /// fill with ML information /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (applyMlMode == FillMlFromSelector) { + if (mlCfg.applyMlMode == FillMlFromSelector) { if (candidate.mlProbDplusToPiKPi().size() > 0) { outputMlDplus.at(0) = candidate.mlProbDplusToPiKPi()[0]; /// bkg score outputMlDplus.at(1) = candidate.mlProbDplusToPiKPi()[1]; /// prompt score outputMlDplus.at(2) = candidate.mlProbDplusToPiKPi()[2]; /// non-prompt score } - } else if (applyMlMode == FillMlFromNewBDT) { + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { isSelectedMlDplusToPiKPi = false; if (candidate.mlProbDplusToPiKPi().size() > 0) { std::vector inputFeaturesDplusToPiKPi = hfMlResponseDplus.getInputFeatures(candidate); @@ -759,7 +784,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { if constexpr (UseCharmMl) { /// fill with ML information /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (applyMlMode == FillMlFromSelector) { + if (mlCfg.applyMlMode == FillMlFromSelector) { if (candidate.mlProbLcToPKPi().size() > 0) { outputMlPKPi.at(0) = candidate.mlProbLcToPKPi()[0]; /// bkg score outputMlPKPi.at(1) = candidate.mlProbLcToPKPi()[1]; /// prompt score @@ -770,7 +795,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { outputMlPiKP.at(1) = candidate.mlProbLcToPiKP()[1]; /// prompt score outputMlPiKP.at(2) = candidate.mlProbLcToPiKP()[2]; /// non-prompt score } - } else if (applyMlMode == FillMlFromNewBDT) { + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { isSelectedMlLcToPKPi = false; isSelectedMlLcToPiKP = false; if (candidate.mlProbLcToPKPi().size() > 0) { @@ -795,7 +820,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { /// fill with ML information /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (applyMlMode == FillMlFromSelector) { + if (mlCfg.applyMlMode == FillMlFromSelector) { if (candidate.mlProbD0().size() > 0) { outputMlD0.at(0) = candidate.mlProbD0()[0]; /// bkg score outputMlD0.at(1) = candidate.mlProbD0()[1]; /// prompt score @@ -807,7 +832,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { outputMlD0bar.at(2) = candidate.mlProbD0bar()[2]; /// non-prompt score } - } else if (applyMlMode == FillMlFromNewBDT) { + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { isSelectedMlD0ToPiK = false; isSelectedMlD0barToKPi = false; @@ -837,13 +862,13 @@ struct HfProducerCharmHadronsTrackFemtoDream { if constexpr (UseCharmMl) { /// fill with ML information /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (applyMlMode == FillMlFromSelector) { + if (mlCfg.applyMlMode == FillMlFromSelector) { if (candidate.mlProbDstarToD0Pi().size() > 0) { outputMlDstar.at(0) = candidate.mlProbDstarToD0Pi()[0]; /// bkg score outputMlDstar.at(1) = candidate.mlProbDstarToD0Pi()[1]; /// prompt score outputMlDstar.at(2) = candidate.mlProbDstarToD0Pi()[2]; /// non-prompt score } - } else if (applyMlMode == FillMlFromNewBDT) { + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { isSelectedMlDstarToD0Pi = false; if (candidate.mlProbDstarToD0Pi().size() > 0) { std::vector inputFeaturesDstarToD0Pi = hfMlResponseDstar.getInputFeatures(candidate, false); @@ -877,9 +902,153 @@ struct HfProducerCharmHadronsTrackFemtoDream { qaRegistry.fill(HIST("hEventQA"), 1 + Event::PairSelected); } - rowMasks(bitTrack, - bitCand, - 0); + tables.rowMasks(bitTrack, + bitCand, + 0); + } + + template + void fillXicHadronTable(CollisionType const& col, TrackType const& tracks, CandType const& candidates, DaughterTrackType const&) + { + const auto vtxZ = col.posZ(); + const auto sizeCand = candidates.size(); + const auto spher = 2.f; + float mult = 0; + int multNtr = 0; + if (generalCfg.isRun3) { + mult = generalCfg.useCent ? col.centFT0M() : 0.f; + multNtr = col.multNTracksPV(); + } else { + mult = 1.f; + multNtr = col.multTracklets(); + } + + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(col, mult, ccdb, qaRegistry); + qaRegistry.fill(HIST("hEventQA"), 1 + Event::All); + hfEvSel.fillHistograms(col, rejectionMask, mult); + if (rejectionMask != 0) { + qaRegistry.fill(HIST("hEventQA"), 1 + Event::RejEveSel); + return; + } + + if (isNoSelectedTracks(col, tracks, trackCuts) && sizeCand <= 0) { + qaRegistry.fill(HIST("hEventQA"), 1 + Event::RejNoTracksAndCharm); + return; + } + + tables.outputCollision(vtxZ, mult, multNtr, spher, magField); + if constexpr (IsMc) { + fillMcCollision(col); + } + + tables.rowCandCharm3ProngXic.reserve(tables.rowCandCharm3ProngXic.lastIndex() + sizeCand + 1); + tables.rowCandCharm3ProngXicQa.reserve(tables.rowCandCharm3ProngXicQa.lastIndex() + sizeCand + 1); + + bool isTrackFilled = false; + int nSelectedXic = 0; + + for (const auto& candidate : candidates) { + if (candidate.isSelXicToXiPiPi() < generalCfg.selectionFlagHadron) { + continue; + } + + outputMlXic = {-1.f, -1.f, -1.f}; + bool isSelectedMlXicToXiPiPi = true; + if constexpr (UseCharmMl) { + if (mlCfg.applyMlMode == FillMlFromSelector) { + if (candidate.mlProbXicToXiPiPi().size() > 0) { + outputMlXic.at(0) = candidate.mlProbXicToXiPiPi()[0]; + outputMlXic.at(1) = candidate.mlProbXicToXiPiPi()[1]; + outputMlXic.at(2) = candidate.mlProbXicToXiPiPi()[2]; + } + } else if (mlCfg.applyMlMode == FillMlFromNewBDT) { + isSelectedMlXicToXiPiPi = false; + if (candidate.mlProbXicToXiPiPi().size() > 0) { + std::vector inputFeaturesXicToXiPiPi = hfMlResponseXic.getInputFeatures(candidate); + isSelectedMlXicToXiPiPi = hfMlResponseXic.isSelectedMl(inputFeaturesXicToXiPiPi, candidate.pt(), outputMlXic); + } + if (!isSelectedMlXicToXiPiPi) { + continue; + } + } else { + LOGF(fatal, "Please check your ML configuration."); + } + } + + auto bc = col.template bc_as(); + int64_t timeStamp = bc.timestamp(); + const auto eta0 = static_cast(RecoDecay::eta(std::array{candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()})); + const auto eta1 = static_cast(RecoDecay::eta(std::array{candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()})); + const auto eta2 = static_cast(RecoDecay::eta(std::array{candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()})); + const auto phi0 = static_cast(RecoDecay::phi(candidate.pxProng0(), candidate.pyProng0())); + const auto phi1 = static_cast(RecoDecay::phi(candidate.pxProng1(), candidate.pyProng1())); + const auto phi2 = static_cast(RecoDecay::phi(candidate.pxProng2(), candidate.pyProng2())); + const auto cascBachelorTrack = candidate.template bachelor_as(); + const auto cascPosTrack = candidate.template posTrack_as(); + const auto cascNegTrack = candidate.template negTrack_as(); + + tables.rowCandCharm3ProngXic( + tables.outputCollision.lastIndex(), + timeStamp, + candidate.sign(), + candidate.cascadeId(), + candidate.pi0Id(), + candidate.pi1Id(), + candidate.bachelorId(), + candidate.posTrackId(), + candidate.negTrackId(), + candidate.ptProng0(), + candidate.ptProng1(), + candidate.ptProng2(), + eta0, + eta1, + eta2, + phi0, + phi1, + phi2, + 1 << 0, + outputMlXic.at(0), + outputMlXic.at(1), + outputMlXic.at(2)); + + tables.rowCandCharm3ProngXicQa( + cascBachelorTrack.pt(), + cascBachelorTrack.phi(), + cascBachelorTrack.eta(), + cascPosTrack.pt(), + cascPosTrack.phi(), + cascPosTrack.eta(), + cascNegTrack.pt(), + cascNegTrack.phi(), + cascNegTrack.eta()); + + ++nSelectedXic; + if constexpr (IsMc) { + tables.rowCandMcCharmHad( + candidate.flagMcMatchRec(), + candidate.originMcRec()); + } + } + + isTrackFilled = fillTracksForCharmHadron(col, tracks); + + aod::femtodreamcollision::BitMaskType bitTrack = 0; + if (isTrackFilled) { + bitTrack |= 1 << 0; + qaRegistry.fill(HIST("hEventQA"), 1 + Event::TrackSelected); + } + + aod::femtodreamcollision::BitMaskType bitCand = 0; + if (nSelectedXic > 0) { + bitCand |= 1 << 0; + qaRegistry.fill(HIST("hEventQA"), 1 + Event::CharmSelected); + } + + if (isTrackFilled && nSelectedXic > 0) { + qaRegistry.fill(HIST("hEventQA"), 1 + Event::PairSelected); + } + + tables.rowMasks(bitTrack, bitCand, 0); } // check if there is no selected track @@ -902,11 +1071,11 @@ struct HfProducerCharmHadronsTrackFemtoDream { void fillCharmHadMcGen(ParticleType particles) { // Filling particle properties - rowCandCharmHadGen.reserve(particles.size()); + tables.rowCandCharmHadGen.reserve(particles.size() + 1); if constexpr (Channel == DecayChannel::DplusToPiKPi) { for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { - rowCandCharmHadGen( + tables.rowCandCharmHadGen( particle.mcCollisionId(), particle.flagMcMatchGen(), particle.originMcGen()); @@ -915,7 +1084,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } else if constexpr (Channel == DecayChannel::LcToPKPi) { for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { - rowCandCharmHadGen( + tables.rowCandCharmHadGen( particle.mcCollisionId(), particle.flagMcMatchGen(), particle.originMcGen()); @@ -924,7 +1093,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } else if constexpr (Channel == DecayChannel::D0ToPiK) { for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { - rowCandCharmHadGen( + tables.rowCandCharmHadGen( particle.mcCollisionId(), particle.flagMcMatchGen(), particle.originMcGen()); @@ -933,7 +1102,7 @@ struct HfProducerCharmHadronsTrackFemtoDream { } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi) { - rowCandCharmHadGen( + tables.rowCandCharmHadGen( particle.mcCollisionId(), particle.flagMcMatchGen(), particle.originMcGen()); @@ -942,6 +1111,21 @@ struct HfProducerCharmHadronsTrackFemtoDream { } } + void fillXicMcGen(GeneratedXicMc const& particles) + { + tables.rowCandCharmHadGen.reserve(particles.size() + 1); + for (const auto& particle : particles) { + const int absFlag = std::abs(static_cast(particle.flagMcMatchGen())); + if (absFlag == (1 << o2::aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiPiPi) || + absFlag == (1 << o2::aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiResPiToXiPiPi)) { + tables.rowCandCharmHadGen( + particle.mcCollisionId(), + particle.flagMcMatchGen(), + particle.originMcGen()); + } + } + } + /// D0ToPiK void processDataD0ToPiK(FemtoFullCollision const& col, aod::BCsWithTimestamps const&, @@ -1166,6 +1350,105 @@ struct HfProducerCharmHadronsTrackFemtoDream { fillCharmHadMcGen(particles); } PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcLcToPKPiGen, "Provide Mc Generated lctopkpi", false); + + /// XicToXiPiPi + void processDataXicToXiPiPi(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + aod::FullTracks const& daughterTracks, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPi, "Data for XicToXiPiPi femto (DCAFitter; no HFCANDXICKF)", false); + + void processDataXicToXiPiPiKf(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + aod::FullTracks const& daughterTracks, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPiKf, "Data for XicToXiPiPi femto (KFParticle; requires HFCANDXICKF)", false); + + void processDataXicToXiPiPiWithML(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + aod::FullTracks const& daughterTracks, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPiWithML, "Data for XicToXiPiPi femto with ML (DCAFitter)", false); + + void processDataXicToXiPiPiWithMLKf(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + aod::FullTracks const& daughterTracks, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processDataXicToXiPiPiWithMLKf, "Data for XicToXiPiPi femto with ML (KFParticle)", false); + + void processMcXicToXiPiPi(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::FullTracks const& daughterTracks, + aod::McParticles const&, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPi, "MC for XicToXiPiPi (DCAFitter)", false); + + void processMcXicToXiPiPiKf(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::FullTracks const& daughterTracks, + aod::McParticles const&, + soa::Filtered const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiKf, "MC for XicToXiPiPi (KFParticle)", false); + + void processMcXicToXiPiPiWithML(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::FullTracks const& daughterTracks, + aod::McParticles const&, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiWithML, "MC for XicToXiPiPi with ML (DCAFitter)", false); + + void processMcXicToXiPiPiWithMLKf(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::FullTracks const& daughterTracks, + aod::McParticles const&, + soa::Filtered> const& candidates) + { + getMagneticFieldTesla(col.bc_as()); + fillXicHadronTable(col, tracks, candidates, daughterTracks); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiWithMLKf, "MC for XicToXiPiPi with ML (KFParticle)", false); + + void processMcXicToXiPiPiGen(GeneratedXicMc const& particles) + { + fillXicMcGen(particles); + } + PROCESS_SWITCH(HfProducerCharmHadronsTrackFemtoDream, processMcXicToXiPiPiGen, "MC generated XicToXiPiPi", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/HFC/TableProducer/producerCharmHadronsV0FemtoDream.cxx b/PWGHF/HFC/TableProducer/producerCharmHadronsV0FemtoDream.cxx index ebc38e73682..c490ea599ba 100644 --- a/PWGHF/HFC/TableProducer/producerCharmHadronsV0FemtoDream.cxx +++ b/PWGHF/HFC/TableProducer/producerCharmHadronsV0FemtoDream.cxx @@ -506,6 +506,10 @@ struct HfProducerCharmHadronsV0FemtoDream { constexpr int GenFromTransport = -1; // -1 if a particle produced during transport // get list of mothers, but it could be empty (for example in case of injected light nuclei) auto motherparticlesMc = particleMc.template mothers_as(); + float ptPos{-1.f}, ptNeg{-1.f}; + float etaPos{-1.f}, etaNeg{-1.f}; + float phiPos{-1.f}, phiNeg{-1.f}; + int pdgCodePos{0}, pdgCodeNeg{0}; // check pdg code // if this fails, the particle is a fake if (std::abs(pdgCode) == std::abs(v0PDGCode.value)) { @@ -524,7 +528,7 @@ struct HfProducerCharmHadronsV0FemtoDream { // get direct mother auto motherparticleMc = motherparticlesMc.front(); pdgCodeMother = motherparticleMc.pdgCode(); - particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode()); + particleOrigin = checkDaughterType(fdparttype, motherparticleMc.pdgCode(), pdgCode); // check if particle is material // particle is from inelastic hadronic interaction -> getProcess() == 23 // particle is generated during transport -> getGenStatusCode() == -1 @@ -534,11 +538,39 @@ struct HfProducerCharmHadronsV0FemtoDream { } else { particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kElse; } + for (auto const& dauMc : particleMc.template daughters_as()) { + if (dauMc.pdgCode() > 0) { + ptPos = dauMc.pt(); + etaPos = dauMc.eta(); + phiPos = dauMc.phi(); + pdgCodePos = dauMc.pdgCode(); + } else { + ptNeg = dauMc.pt(); + etaNeg = dauMc.eta(); + phiNeg = dauMc.phi(); + pdgCodeNeg = dauMc.pdgCode(); + } + } // if pdg code is wrong, particle is fake } else { particleOrigin = aod::femtodreamMCparticle::ParticleOriginMCTruth::kFake; } + // positive daughter + outputPartsMc(particleOrigin, pdgCodePos, ptPos, etaPos, phiPos); + outputPartsMcLabels(outputPartsMc.lastIndex()); + if (isDebug) { + outputPartsExtMcLabels(outputPartsMc.lastIndex()); + outputDebugPartsMc(pdgCode); + } + // negative daughter + outputPartsMc(particleOrigin, pdgCodeNeg, ptNeg, etaNeg, phiNeg); + outputPartsMcLabels(outputPartsMc.lastIndex()); + if (isDebug) { + outputPartsExtMcLabels(outputPartsMc.lastIndex()); + outputDebugPartsMc(pdgCode); + } + // V0 outputPartsMc(particleOrigin, pdgCode, particleMc.pt(), particleMc.eta(), particleMc.phi()); outputPartsMcLabels(outputPartsMc.lastIndex()); if (isDebug) { @@ -546,9 +578,26 @@ struct HfProducerCharmHadronsV0FemtoDream { outputDebugPartsMc(pdgCodeMother); } } else { + // positive daughter + outputPartsMc(aod::femtodreamMCparticle::ParticleOriginMCTruth::kFake, 0, -1.f, -1.f, -1.f); + outputPartsMcLabels(-1); + if (isDebug) { + outputPartsExtMcLabels(-1); + outputDebugPartsMc(0); + } + // negative daughter + outputPartsMc(aod::femtodreamMCparticle::ParticleOriginMCTruth::kFake, 0, -1.f, -1.f, -1.f); outputPartsMcLabels(-1); if (isDebug) { outputPartsExtMcLabels(-1); + outputDebugPartsMc(0); + } + // V0 + outputPartsMc(aod::femtodreamMCparticle::ParticleOriginMCTruth::kFake, 0, -1.f, -1.f, -1.f); + outputPartsMcLabels(-1); + if (isDebug) { + outputPartsExtMcLabels(-1); + outputDebugPartsMc(0); } } } @@ -722,19 +771,19 @@ struct HfProducerCharmHadronsV0FemtoDream { return; } + if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi) { + rowCandCharm3Prong.reserve(rowCandCharm3Prong.lastIndex() + sizeCand * 2 + 1); + } else if constexpr (Channel == DecayChannel::D0ToPiK) { + rowCandCharm2Prong.reserve(rowCandCharm2Prong.lastIndex() + sizeCand * 2 + 1); + } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { + rowCandCharmDstar.reserve(rowCandCharmDstar.lastIndex() + sizeCand + 1); + } + outputCollision(vtxZ, mult, multNtr, spher, magField); if constexpr (IsMc) { fillMcCollision(col); } - // Filling candidate properties - if constexpr (Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::LcToPKPi) { - rowCandCharm3Prong.reserve(sizeCand); - } else if constexpr (Channel == DecayChannel::D0ToPiK) { - rowCandCharm2Prong.reserve(sizeCand); - } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { - rowCandCharmDstar.reserve(sizeCand); - } bool isV0Filled = false; bool isSelectedMlLcToPKPi = true; bool isSelectedMlLcToPiKP = true; @@ -1132,7 +1181,7 @@ struct HfProducerCharmHadronsV0FemtoDream { void fillCharmHadMcGen(ParticleType particles) { // Filling particle properties - rowCandCharmHadGen.reserve(particles.size()); + rowCandCharmHadGen.reserve(particles.size() + 1); if constexpr (Channel == DecayChannel::DplusToPiKPi) { for (const auto& particle : particles) { if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx index a0b6b1aed76..e7f10007cfa 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsTrackFemtoDream.cxx @@ -86,7 +86,8 @@ struct HfTaskCharmHadronsTrackFemtoDream { enum DecayChannel { DplusToPiKPi = 0, LcToPKPi, D0ToPiK, - DstarToD0Pi + DstarToD0Pi, + XicToXiPiPi }; constexpr static int OriginRecPrompt = 1; @@ -107,14 +108,14 @@ struct HfTaskCharmHadronsTrackFemtoDream { struct : ConfigurableGroup { Configurable charmHadBkgBDTmax{"charmHadBkgBDTmax", 1., "Maximum background bdt score for Charm Hadron (particle 2)"}; Configurable charmHadCandSel{"charmHadCandSel", 1, "candidate selection for charm hadron"}; - Configurable charmHadMcSel{"charmHadMcSel", DecayChannelMain::LcToPKPi, "charm hadron selection for mc, DplusToPiKPi = 1, LcToPKPi = 17"}; + Configurable charmHadMcSel{"charmHadMcSel", DecayChannelMain::LcToPKPi, "MC matching flag for the selected charm hadron decay channel"}; Configurable charmHadFdBDTmin{"charmHadFdBDTmin", 0., "Minimum feed-down bdt score Charm Hadron (particle 2)"}; Configurable charmHadFdBDTmax{"charmHadFdBDTmax", 1., "Maximum feed-down bdt score Charm Hadron (particle 2)"}; Configurable charmHadMaxInvMass{"charmHadMaxInvMass", 2.45, "Maximum invariant mass of Charm Hadron (particle 2)"}; Configurable charmHadMinInvMass{"charmHadMinInvMass", 2.15, "Minimum invariant mass of Charm Hadron (particle 2)"}; Configurable charmHadMinPt{"charmHadMinPt", 0., "Minimum pT of Charm Hadron (particle 2)"}; Configurable charmHadMaxPt{"charmHadMaxPt", 999., "Maximum pT of Charm Hadron (particle 2)"}; - Configurable charmHadPDGCode{"charmHadPDGCode", 4122, "PDG code of particle 2 Charm Hadron"}; + Configurable charmHadPDGCode{"charmHadPDGCode", Pdg::kLambdaCPlus, "PDG code of particle 2 Charm Hadron"}; Configurable charmHadPromptBDTmin{"charmHadPromptBDTmin", 0., "Minimum prompt bdt score Charm Hadron (particle 2)"}; Configurable charmHadPromptBDTmax{"charmHadPromptBDTmax", 1., "Maximum prompt bdt score Charm Hadron (particle 2)"}; } charmSel; @@ -150,7 +151,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { /// Particle 1 (track) struct : ConfigurableGroup { Configurable cutBitTrack1{"cutBitTrack1", 8188, "Particle 1 (Track) - Selection bit from cutCulator"}; - Configurable pdgCodeTrack1{"pdgCodeTrack1", 2212, "PDG code of Particle 1 (Track)"}; + Configurable pdgCodeTrack1{"pdgCodeTrack1", kProton, "PDG code of Particle 1 (Track)"}; Configurable pidThresTrack1{"pidThresTrack1", 0.75, "Momentum threshold for PID selection for particle 1 (Track)"}; Configurable tpcBitTrack1{"tpcBitTrack1", 4, "PID TPC bit from cutCulator for particle 1 (Track)"}; Configurable tpcTofBitTrack1{"tpcTofBitTrack1", 2, "PID TPCTOF bit from cutCulator for particle 1 (Track)"}; @@ -164,6 +165,9 @@ struct HfTaskCharmHadronsTrackFemtoDream { using FilteredCharmCand3Prongs = soa::Filtered; using FilteredCharmCand3Prong = FilteredCharmCand3Prongs::iterator; + using FilteredCharmCand3ProngsXic = soa::Filtered; + using FilteredCharmCand3ProngXic = FilteredCharmCand3ProngsXic::iterator; + using FilteredCharmCand2Prongs = soa::Filtered; using FilteredCharmCand2Prong = FilteredCharmCand2Prongs::iterator; @@ -173,6 +177,9 @@ struct HfTaskCharmHadronsTrackFemtoDream { using FilteredCharmMcCand3Prongs = soa::Filtered>; using FilteredCharmMcCand3Prong = FilteredCharmMcCand3Prongs::iterator; + using FilteredCharmMcCand3ProngsXic = soa::Filtered>; + using FilteredCharmMcCand3ProngXic = FilteredCharmMcCand3ProngsXic::iterator; + using FilteredCharmMcCand2Prongs = soa::Filtered>; using FilteredCharmMcCand2Prong = FilteredCharmMcCand2Prongs::iterator; @@ -200,10 +207,13 @@ struct HfTaskCharmHadronsTrackFemtoDream { Filter trackPtFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt < trackSel.ptTrack1Max, true); Filter trackPtFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt > trackSel.ptTrack1Min, true); - Preslice perCol = aod::femtodreamparticle::fdCollisionId; - Preslice perHf3ProngByCol = aod::femtodreamparticle::fdCollisionId; - Preslice perHf2ProngByCol = aod::femtodreamparticle::fdCollisionId; - Preslice perHfDstarByCol = aod::femtodreamparticle::fdCollisionId; + struct : PresliceGroup { + Preslice perCol = aod::femtodreamparticle::fdCollisionId; + Preslice perHf3ProngByCol = aod::femtodreamparticle::fdCollisionId; + Preslice perHf3ProngXicByCol = aod::femtodreamparticle::fdCollisionId; + Preslice perHf2ProngByCol = aod::femtodreamparticle::fdCollisionId; + Preslice perHfDstarByCol = aod::femtodreamparticle::fdCollisionId; + } preslices; /// Partition for particle 1 Partition partitionTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && (ncheckbit(aod::femtodreamparticle::cut, trackSel.cutBitTrack1)) && ifnode(aod::femtodreamparticle::pt * coshEta(aod::femtodreamparticle::eta) <= trackSel.pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, trackSel.tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, trackSel.tpcTofBitTrack1)); @@ -217,10 +227,12 @@ struct HfTaskCharmHadronsTrackFemtoDream { /// Partition for particle 2 Partition partitionCharmHadron3Prong = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; + Partition partitionCharmHadron3ProngXic = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; Partition partitionCharmHadron2Prong = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; Partition partitionCharmHadronDstar = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; Partition partitionMcCharmHadron3Prong = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; + Partition partitionMcCharmHadron3ProngXic = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; Partition partitionMcCharmHadron2Prong = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; Partition partitionMcCharmHadronDstar = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; @@ -282,21 +294,23 @@ struct HfTaskCharmHadronsTrackFemtoDream { HistogramRegistry registryMixQa{"registryMixQa"}; HistogramRegistry registryCharmHadronQa{"registryCharmHadronQa"}; - float massOne = o2::analysis::femtoDream::getMass(trackSel.pdgCodeTrack1); - float massTwo = o2::analysis::femtoDream::getMass(charmSel.charmHadPDGCode); - int8_t partSign = 0; + float massOne = 0.f; + float massTwo = 0.f; int64_t processType = 0; void init(InitContext& /*context*/) { - std::array processes = {doprocessDataLcTrk, doprocessDataDplusTrk, doprocessDataD0Trk, doprocessDataDstarTrk, doprocessMcLcTrk, doprocessMcDplusTrk, doprocessMcD0Trk, doprocessMcDstarTrk}; + std::array processes = {doprocessDataLcTrk, doprocessDataDplusTrk, doprocessDataD0Trk, doprocessDataDstarTrk, doprocessDataXicTrk, doprocessMcLcTrk, doprocessMcDplusTrk, doprocessMcD0Trk, doprocessMcDstarTrk, doprocessMcXicTrk}; if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { LOGP(fatal, "One and only one process function must be enabled at a time."); } - bool process3Prong = doprocessDataLcTrk || doprocessDataDplusTrk || doprocessMcLcTrk || doprocessMcDplusTrk; + bool process3Prong = doprocessDataLcTrk || doprocessDataDplusTrk || doprocessDataXicTrk || doprocessMcLcTrk || doprocessMcDplusTrk || doprocessMcXicTrk; bool process2Prong = doprocessDataD0Trk || doprocessMcD0Trk; bool processDstar = doprocessDataDstarTrk || doprocessMcDstarTrk; + massOne = o2::analysis::femtoDream::getMass(trackSel.pdgCodeTrack1.value); + massTwo = o2::analysis::femtoDream::getMass(charmSel.charmHadPDGCode.value); + // setup columnpolicy for binning colBinningMult = {{mixingBinVztx, mixingBinMult}, true}; colBinningMultPercentile = {{mixingBinVztx, mixingBinMultPercentile}, true}; @@ -312,7 +326,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { highkstarCut, smearingByOrigin, binInvMass); - sameEventCont.setPDGCodes(trackSel.pdgCodeTrack1, charmSel.charmHadPDGCode); + sameEventCont.setPDGCodes(trackSel.pdgCodeTrack1.value, charmSel.charmHadPDGCode.value); mixedEventCont.init(®istry, binkstar, binpTTrack, binkT, binmT, mixingBinMult, mixingBinMultPercentile, bin4Dkstar, bin4DmT, bin4DMult, bin4DmultPercentile, @@ -320,7 +334,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { highkstarCut, smearingByOrigin, binInvMass); - mixedEventCont.setPDGCodes(trackSel.pdgCodeTrack1, charmSel.charmHadPDGCode); + mixedEventCont.setPDGCodes(trackSel.pdgCodeTrack1.value, charmSel.charmHadPDGCode.value); registryMixQa.add("MixingQA/hSECollisionBins", "; bin; Entries", kTH1F, {{120, -0.5, 119.5}}); registryMixQa.add("MixingQA/hSECollisionPool", "; Vz (cm); Mul", kTH2F, {{100, -10, 10}, {200, 0, 200}}); registryMixQa.add("MixingQA/hMECollisionBins", "; bin; Entries", kTH1F, {{120, -0.5, 119.5}}); @@ -349,7 +363,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { } /// Compute the charm hadron candidates mass with the daughter masses - /// assumes the candidate is either a D+ or Λc+ or D0 or Dstar + /// assumes the candidate is either a D+ or Λc+ or D0 or Dstar or Ξc+ template float getCharmHadronMass(const Candidate& cand, bool ReturnDaughMass = false) { @@ -387,6 +401,9 @@ struct HfTaskCharmHadronsTrackFemtoDream { } else { return mDstar - mD0; } + } else if constexpr (Channel == DecayChannel::XicToXiPiPi) { + invMass = cand.m(std::array{MassXiMinus, MassPiPlus, MassPiPlus}); + return invMass; } // Add more channels as needed return 0.f; @@ -433,7 +450,15 @@ struct HfTaskCharmHadronsTrackFemtoDream { return static_cast(RecoDecay::m(pVecCharmTrk, massCharmTrk)); } - // 3-prong:Λc → p K π, D+ → π K π + track + // Ξc⁺ → Ξ π π + track + if constexpr (Channel == DecayChannel::XicToXiPiPi) { + auto pVecProng2 = RecoDecayPtEtaPhi::pVector(cand.prong2Pt(), cand.prong2Eta(), cand.prong2Phi()); + const auto pVecCharmTrk = std::array{pVecProng0, pVecProng1, pVecProng2, pVecTrack}; + const std::array massCharmTrk{MassXiMinus, MassPiPlus, MassPiPlus, trackMassHyp}; + return static_cast(RecoDecay::m(pVecCharmTrk, massCharmTrk)); + } + + // 3-prong: Λc → p K π, D+ → π K π, D* → D0π + track if constexpr (Channel == DecayChannel::LcToPKPi || Channel == DecayChannel::DplusToPiKPi || Channel == DecayChannel::DstarToD0Pi) { auto pVecProng2 = RecoDecayPtEtaPhi::pVector(cand.prong2Pt(), cand.prong2Eta(), cand.prong2Phi()); const auto pVecCharmTrk = std::array{pVecProng0, pVecProng1, pVecProng2, pVecTrack}; @@ -502,6 +527,19 @@ struct HfTaskCharmHadronsTrackFemtoDream { } } + if constexpr (Channel == DecayChannel::XicToXiPiPi) { + if (p1.trackId() == p2.prong1Id() || p1.trackId() == p2.prong2Id() || + p1.trackId() == p2.cascBachelorTrackId() || + p1.trackId() == p2.cascPosTrackId() || p1.trackId() == p2.cascNegTrackId()) { + continue; + } + if (pairQASetting.useCPR.value) { + if (pairCloseRejectionSE3Prong.isClosePair(p1, p2, parts, col.magField())) { + continue; + } + } + } + if constexpr (Channel == DecayChannel::DstarToD0Pi) { if (p1.trackId() == p2.prong0Id() || p1.trackId() == p2.prong1Id() || p1.trackId() == p2.prong2Id()) { continue; @@ -533,7 +571,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { float deltaInvMassPair = getCharmHadronTrackMass(p2, p1, trackSel.pdgCodeTrack1.value) - invMass; - // proton track charge + // associated track charge float chargeTrack = 0.; if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) { chargeTrack = PositiveCharge; @@ -632,6 +670,14 @@ struct HfTaskCharmHadronsTrackFemtoDream { } } + if constexpr (Channel == DecayChannel::XicToXiPiPi) { + if (pairQASetting.useCPR.value) { + if (pairCloseRejectionME3Prong.isClosePair(p1, p2, parts, collision1.magField())) { + continue; + } + } + } + if constexpr (Channel == DecayChannel::DstarToD0Pi) { if (pairQASetting.useCPR.value) { @@ -662,7 +708,7 @@ struct HfTaskCharmHadronsTrackFemtoDream { float deltaInvMassPair = getCharmHadronTrackMass(p2, p1, trackSel.pdgCodeTrack1.value) - invMass; - // proton track charge + // associated track charge float chargeTrack = 0.; if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) { chargeTrack = PositiveCharge; @@ -740,6 +786,21 @@ struct HfTaskCharmHadronsTrackFemtoDream { part.bdtBkg(), part.bdtPrompt(), part.bdtFD()); + } else if constexpr (Channel == DecayChannel::XicToXiPiPi) { + rowFemtoResultCharm3Prong( + col.globalIndex(), + timeStamp, + invMass, + part.pt(), + part.eta(), + part.phi(), + part.cascId(), + part.prong1Id(), + part.prong2Id(), + part.charge(), + part.bdtBkg(), + part.bdtPrompt(), + part.bdtFD()); } else if constexpr (Channel == DecayChannel::D0ToPiK) { rowFemtoResultCharm2Prong( col.globalIndex(), @@ -837,8 +898,10 @@ struct HfTaskCharmHadronsTrackFemtoDream { void processDataLcTrk(FilteredCollisions const& cols, FilteredFDParticles const& parts, - FilteredCharmCand3Prongs const&) + FilteredCharmCand3Prongs const& candidates) { + rowFemtoResultCharm3Prong.reserve(2 * candidates.size() + 1); + rowFemtoResultTrk.reserve(parts.size() + 1); for (const auto& col : cols) { eventHisto.fillQA(col); auto* partitionTrk1Selected = &partitionTrk1; @@ -876,8 +939,10 @@ struct HfTaskCharmHadronsTrackFemtoDream { void processDataDplusTrk(FilteredCollisions const& cols, FilteredFDParticles const& parts, - FilteredCharmCand3Prongs const&) + FilteredCharmCand3Prongs const& candidates) { + rowFemtoResultCharm3Prong.reserve(candidates.size() + 1); + rowFemtoResultTrk.reserve(parts.size() + 1); for (const auto& col : cols) { eventHisto.fillQA(col); auto* partitionTrk1Selected = &partitionTrk1; @@ -916,8 +981,10 @@ struct HfTaskCharmHadronsTrackFemtoDream { void processDataD0Trk(FilteredCollisions const& cols, FilteredFDParticles const& parts, - FilteredCharmCand2Prongs const&) + FilteredCharmCand2Prongs const& candidates) { + rowFemtoResultCharm2Prong.reserve(candidates.size() * 2 + 1); + rowFemtoResultTrk.reserve(parts.size() + 1); for (const auto& col : cols) { eventHisto.fillQA(col); auto* partitionTrk1Selected = &partitionTrk1; @@ -955,8 +1022,10 @@ struct HfTaskCharmHadronsTrackFemtoDream { void processDataDstarTrk(FilteredCollisions const& cols, FilteredFDParticles const& parts, - FilteredCharmCandDstars const&) + FilteredCharmCandDstars const& candidates) { + rowFemtoResultCharmDstar.reserve(candidates.size() + 1); + rowFemtoResultTrk.reserve(parts.size() + 1); for (const auto& col : cols) { eventHisto.fillQA(col); auto* partitionTrk1Selected = &partitionTrk1; @@ -992,6 +1061,49 @@ struct HfTaskCharmHadronsTrackFemtoDream { } PROCESS_SWITCH(HfTaskCharmHadronsTrackFemtoDream, processDataDstarTrk, "Enable processing DstarToD0Pi and Tracks correlation", false); + void processDataXicTrk(FilteredCollisions const& cols, + FilteredFDParticles const& parts, + FilteredCharmCand3ProngsXic const&) + { + for (const auto& col : cols) { + eventHisto.fillQA(col); + auto* partitionTrk1Selected = &partitionTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionTrk1Ka; + } + auto sliceTrk1 = partitionTrk1Selected->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto sliceCharmHad = partitionCharmHadron3ProngXic->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if (fillTableWithCharm.value && sliceCharmHad.size() == 0) { + continue; + } else { + fillTables(col, sliceTrk1, sliceCharmHad); + } + if (sliceCharmHad.size() > 0 && sliceTrk1.size() > 0) { + doSameEvent(sliceCharmHad, sliceTrk1, parts, col); + } + } + if (mixSetting.doMixEvent) { + auto* partitionTrk1Selected = &partitionTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionTrk1Ka; + } + switch (mixSetting.mixingBinPolicy) { + case femtodreamcollision::kMult: + doMixedEvent(cols, partitionCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent(cols, partitionCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent(cols, partitionCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + PROCESS_SWITCH(HfTaskCharmHadronsTrackFemtoDream, processDataXicTrk, "Enable processing XicToXiPiPi and Tracks correlation", false); + void processMcLcTrk(FilteredMcColisions const& cols, FilteredFDMcParts const& parts, o2::aod::FDMCParticles const&, @@ -1131,6 +1243,47 @@ struct HfTaskCharmHadronsTrackFemtoDream { } } PROCESS_SWITCH(HfTaskCharmHadronsTrackFemtoDream, processMcDstarTrk, "Enable processing DstarToD0Pi and Tracks correlation for Monte Carlo", false); + + void processMcXicTrk(FilteredMcColisions const& cols, + FilteredFDMcParts const& parts, + o2::aod::FDMCParticles const&, + o2::aod::FDExtMCParticles const&, + FilteredCharmMcCand3ProngsXic const&) + { + for (const auto& col : cols) { + eventHisto.fillQA(col); + auto* partitionTrk1Selected = &partitionMcTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionMcTrk1Ka; + } + auto sliceMcTrk1 = partitionTrk1Selected->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto sliceMcCharmHad = partitionMcCharmHadron3ProngXic->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if ((col.bitmaskTrackOne() & bitMask) != bitMask || (col.bitmaskTrackTwo() & bitMask) != bitMask) { + continue; + } + doSameEvent(sliceMcCharmHad, sliceMcTrk1, parts, col); + } + if (mixSetting.doMixEvent) { + auto* partitionTrk1Selected = &partitionMcTrk1; + if (trackSel.pdgCodeTrack1.value == kKPlus) { + partitionTrk1Selected = &partitionMcTrk1Ka; + } + switch (mixSetting.mixingBinPolicy) { + case femtodreamcollision::kMult: + doMixedEvent(cols, partitionMcCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent(cols, partitionMcCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent(cols, partitionMcCharmHadron3ProngXic, *partitionTrk1Selected, parts, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + } + PROCESS_SWITCH(HfTaskCharmHadronsTrackFemtoDream, processMcXicTrk, "Enable processing XicToXiPiPi and Tracks correlation for Monte Carlo", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsV0FemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsV0FemtoDream.cxx index 9c320059605..30adbcdd49a 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsV0FemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsV0FemtoDream.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file taskCharmHadronsTrackFemtoDream.cxx +/// \file taskCharmHadronsV0FemtoDream.cxx /// \brief Tasks that reads the V0 and CharmHadrons tables used for the pairing and builds pairs /// \author Biao Zhang, Heidelberg University, biao.zhang@cern.ch @@ -174,11 +174,11 @@ struct HfTaskCharmHadronsV0FemtoDream { using FilteredCollisions = soa::Filtered>; using FilteredCollision = FilteredCollisions::iterator; - using FilteredMcColisions = soa::Filtered>; - using FilteredMcColision = FilteredMcColisions::iterator; + using FilteredMcCollisions = soa::Filtered>; + using FilteredMcColision = FilteredMcCollisions::iterator; - using FilteredFDMcParts = soa::Filtered>; - using FilteredFDMcPart = FilteredFDMcParts::iterator; + using FDMcV0Particles = soa::Join; + using FDMcV0Particle = FDMcV0Particles::iterator; using FDV0Particles = soa::Join; using FDV0Particle = FDV0Particles::iterator; @@ -189,11 +189,12 @@ struct HfTaskCharmHadronsV0FemtoDream { Filter hfMcSelFilter = (nabs(aod::fdhf::flagMc) == charmSel.charmHadMcSel); Preslice perCol = aod::femtodreamparticle::fdCollisionId; + Preslice perColMc = aod::femtodreamparticle::fdCollisionId; Preslice perHf3ProngByCol = aod::femtodreamparticle::fdCollisionId; Preslice perHf2ProngByCol = aod::femtodreamparticle::fdCollisionId; Preslice perHfDstarByCol = aod::femtodreamparticle::fdCollisionId; - /// Partition for particle Lambda + /// Partitions for particle Lambda Partition partitionLambda = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0)) && ((aod::femtodreamparticle::cut & v0Sel.cutBit) == v0Sel.cutBit) && (aod::femtodreamparticle::pt > v0Sel.ptV0Min) && @@ -205,7 +206,18 @@ struct HfTaskCharmHadronsV0FemtoDream { (aod::femtodreamparticle::mAntiLambda > v0Sel.invMassAntiV0Min) && (aod::femtodreamparticle::mAntiLambda < v0Sel.invMassAntiV0Max); - /// Partition for particle K0Short + Partition partitionMcLambda = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0)) && + ((aod::femtodreamparticle::cut & v0Sel.cutBit) == v0Sel.cutBit) && + (aod::femtodreamparticle::pt > v0Sel.ptV0Min) && + (aod::femtodreamparticle::pt < v0Sel.ptV0Max) && + (aod::femtodreamparticle::eta > v0Sel.etaV0Min) && + (aod::femtodreamparticle::eta < v0Sel.etaV0Max) && + (aod::femtodreamparticle::mLambda > v0Sel.invMassV0Min) && + (aod::femtodreamparticle::mLambda < v0Sel.invMassV0Max) && + (aod::femtodreamparticle::mAntiLambda > v0Sel.invMassAntiV0Min) && + (aod::femtodreamparticle::mAntiLambda < v0Sel.invMassAntiV0Max); + + /// Partitions for particle K0Short Partition partitionK0Short = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0K0Short)) && ((aod::femtodreamparticle::cut & v0Sel.cutBit) == v0Sel.cutBit) && (aod::femtodreamparticle::pt > v0Sel.ptV0Min) && @@ -217,6 +229,17 @@ struct HfTaskCharmHadronsV0FemtoDream { (aod::femtodreamparticle::mAntiLambda > v0Sel.invMassAntiV0Min) && (aod::femtodreamparticle::mAntiLambda < v0Sel.invMassAntiV0Max); + Partition partitionMcK0Short = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0K0Short)) && + ((aod::femtodreamparticle::cut & v0Sel.cutBit) == v0Sel.cutBit) && + (aod::femtodreamparticle::pt > v0Sel.ptV0Min) && + (aod::femtodreamparticle::pt < v0Sel.ptV0Max) && + (aod::femtodreamparticle::eta > v0Sel.etaV0Min) && + (aod::femtodreamparticle::eta < v0Sel.etaV0Max) && + (aod::femtodreamparticle::mLambda > v0Sel.invMassV0Min) && + (aod::femtodreamparticle::mLambda < v0Sel.invMassV0Max) && + (aod::femtodreamparticle::mAntiLambda > v0Sel.invMassAntiV0Min) && + (aod::femtodreamparticle::mAntiLambda < v0Sel.invMassAntiV0Max); + /// Partition for particle 2 Partition partitionCharmHadron3Prong = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; Partition partitionCharmHadron2Prong = aod::fdhf::bdtBkg < charmSel.charmHadBkgBDTmax && aod::fdhf::bdtFD < charmSel.charmHadFdBDTmax && aod::fdhf::bdtFD > charmSel.charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmSel.charmHadPromptBDTmin; @@ -298,11 +321,11 @@ struct HfTaskCharmHadronsV0FemtoDream { void init(InitContext& /*context*/) { - std::array processes = {doprocessDataLcV0, doprocessDataDplusV0, doprocessDataD0V0, doprocessDataDstarV0}; + std::array processes = {doprocessDataLcV0, doprocessDataDplusV0, doprocessDataD0V0, doprocessDataDstarV0, doprocessMcDplusV0}; if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { LOGP(fatal, "One and only one process function must be enabled at a time."); } - bool process3Prong = doprocessDataLcV0 || doprocessDataDplusV0; + bool process3Prong = doprocessDataLcV0 || doprocessDataDplusV0 || doprocessMcDplusV0; bool process2Prong = doprocessDataD0V0; bool processDstar = doprocessDataDstarV0; @@ -381,10 +404,9 @@ struct HfTaskCharmHadronsV0FemtoDream { if (cand.candidateSelFlag() == 1) { invMass = cand.m(std::array{MassPiPlus, MassKPlus}); return invMass; - } else { - invMass = cand.m(std::array{MassKPlus, MassPiPlus}); - return invMass; } + invMass = cand.m(std::array{MassKPlus, MassPiPlus}); + return invMass; } else if constexpr (Channel == DecayChannel::DstarToD0Pi) { // D* → D0π (PDG: 413) float mDstar = 0.f; float mD0 = 0.f; @@ -397,9 +419,8 @@ struct HfTaskCharmHadronsV0FemtoDream { } if (ReturnDaughMass) { return mD0; - } else { - return mDstar - mD0; } + return mDstar - mD0; } // Add more channels as needed return 0.f; @@ -502,7 +523,7 @@ struct HfTaskCharmHadronsV0FemtoDream { } template - void doMixedEvent(CollisionType const& cols, PartitionType1& charms, PartitionType2& v0s, FDParticles const& /*femtoParts*/, BinningType policy) + void doMixedEvent(CollisionType const& cols, PartitionType1& charms, PartitionType2& v0s, FDParticles const& /*femtoParts*/, BinningType const& policy) { processType = 2; // for mixed event // Mixed events that contain the pair of interest @@ -717,9 +738,9 @@ struct HfTaskCharmHadronsV0FemtoDream { } } - template - void runMixing(FilteredCollisions const& cols, - FDV0Particles const& parts, + template + void runMixing(Cols const& cols, + V0Part const& parts, CharmPart& charmPart) { if (!mixSetting.doMixEvent) { @@ -728,13 +749,25 @@ struct HfTaskCharmHadronsV0FemtoDream { auto run = [&](auto& v0Part) { switch (mixSetting.mixingBinPolicy) { case femtodreamcollision::kMult: - doMixedEvent(cols, charmPart, v0Part, parts, colBinningMult); + if constexpr (IsMc) { + doMixedEvent(cols, charmPart, v0Part, parts, colBinningMult); + } else { + doMixedEvent(cols, charmPart, v0Part, parts, colBinningMult); + } break; case femtodreamcollision::kMultPercentile: - doMixedEvent(cols, charmPart, v0Part, parts, colBinningMultPercentile); + if constexpr (IsMc) { + doMixedEvent(cols, charmPart, v0Part, parts, colBinningMultPercentile); + } else { + doMixedEvent(cols, charmPart, v0Part, parts, colBinningMultPercentile); + } break; case femtodreamcollision::kMultMultPercentile: - doMixedEvent(cols, charmPart, v0Part, parts, colBinningMultMultPercentile); + if constexpr (IsMc) { + doMixedEvent(cols, charmPart, v0Part, parts, colBinningMultMultPercentile); + } else { + doMixedEvent(cols, charmPart, v0Part, parts, colBinningMultMultPercentile); + } break; default: LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; @@ -742,9 +775,17 @@ struct HfTaskCharmHadronsV0FemtoDream { }; if (v0Sel.pdgCodeV0 == kLambda0) { - run(partitionLambda); + if constexpr (IsMc) { + run(partitionMcLambda); + } else { + run(partitionLambda); + } } else if (v0Sel.pdgCodeV0 == kK0Short) { - run(partitionK0Short); + if constexpr (IsMc) { + run(partitionMcK0Short); + } else { + run(partitionK0Short); + } } else { LOG(fatal) << "Unsupported V0 PDG: " << v0Sel.pdgCodeV0 << " (allowed: 3122, 310) for mixed-events"; } @@ -752,8 +793,11 @@ struct HfTaskCharmHadronsV0FemtoDream { void processDataLcV0(FilteredCollisions const& cols, FDV0Particles const& parts, - FilteredCharmCand3Prongs const&) + FilteredCharmCand3Prongs const& candidates) { + + rowFemtoResultCharm3Prong.reserve(candidates.size() + 1); + for (const auto& col : cols) { eventHisto.fillQA(col); auto sliceCharmHad = partitionCharmHadron3Prong->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); @@ -778,14 +822,16 @@ struct HfTaskCharmHadronsV0FemtoDream { LOG(fatal) << "Unsupported V0 PDG: " << v0Sel.pdgCodeV0 << " (allowed: 3122, 310) for same events"; } } - runMixing(cols, parts, partitionCharmHadron3Prong); + runMixing(cols, parts, partitionCharmHadron3Prong); } PROCESS_SWITCH(HfTaskCharmHadronsV0FemtoDream, processDataLcV0, "Enable processing LcToPKPi and V0 correlation", false); void processDataDplusV0(FilteredCollisions const& cols, FDV0Particles const& parts, - FilteredCharmCand3Prongs const&) + FilteredCharmCand3Prongs const& candidates) { + rowFemtoResultCharm3Prong.reserve(candidates.size() + 1); + for (const auto& col : cols) { eventHisto.fillQA(col); auto sliceCharmHad = partitionCharmHadron3Prong->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); @@ -810,14 +856,16 @@ struct HfTaskCharmHadronsV0FemtoDream { LOG(fatal) << "Unsupported V0 PDG: " << v0Sel.pdgCodeV0 << " (allowed: 3122, 310)"; } } - runMixing(cols, parts, partitionCharmHadron3Prong); + runMixing(cols, parts, partitionCharmHadron3Prong); } PROCESS_SWITCH(HfTaskCharmHadronsV0FemtoDream, processDataDplusV0, "Enable processing DplusToPiKPi and V0 correlation", false); void processDataD0V0(FilteredCollisions const& cols, FDV0Particles const& parts, - FilteredCharmCand2Prongs const&) + FilteredCharmCand2Prongs const& candidates) { + rowFemtoResultCharm2Prong.reserve(candidates.size() + 1); + for (const auto& col : cols) { eventHisto.fillQA(col); auto sliceCharmHad = partitionCharmHadron2Prong->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); @@ -842,14 +890,17 @@ struct HfTaskCharmHadronsV0FemtoDream { LOG(fatal) << "Unsupported V0 PDG: " << v0Sel.pdgCodeV0 << " (allowed: 3122, 310)"; } } - runMixing(cols, parts, partitionCharmHadron2Prong); + runMixing(cols, parts, partitionCharmHadron2Prong); } PROCESS_SWITCH(HfTaskCharmHadronsV0FemtoDream, processDataD0V0, "Enable processing D0ToPiK and V0 correlation", false); void processDataDstarV0(FilteredCollisions const& cols, FDV0Particles const& parts, - FilteredCharmCandDstars const&) + FilteredCharmCandDstars const& candidates) { + + rowFemtoResultCharmDstar.reserve(candidates.size() + 1); + for (const auto& col : cols) { eventHisto.fillQA(col); auto sliceCharmHad = partitionCharmHadronDstar->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); @@ -874,9 +925,43 @@ struct HfTaskCharmHadronsV0FemtoDream { LOG(fatal) << "Unsupported V0 PDG: " << v0Sel.pdgCodeV0 << " (allowed: 3122, 310)"; } } - runMixing(cols, parts, partitionCharmHadronDstar); + runMixing(cols, parts, partitionCharmHadronDstar); } PROCESS_SWITCH(HfTaskCharmHadronsV0FemtoDream, processDataDstarV0, "Enable processing DstarToD0Pi and V0 correlation", false); + + void processMcDplusV0(FilteredMcCollisions const& cols, + FDMcV0Particles const& parts, + o2::aod::FDMCParticles const&, + o2::aod::FDExtMCParticles const&, + FilteredCharmMcCand3Prongs const&) + { + for (const auto& col : cols) { + eventHisto.fillQA(col); + auto sliceMcCharmHad = partitionMcCharmHadron3Prong->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if (fillTableWithCharm.value && sliceMcCharmHad.size() == 0) { + continue; + } + if (v0Sel.pdgCodeV0 == kLambda0) { + auto sliceMcV0 = partitionMcLambda->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + fillTables(col, sliceMcV0, sliceMcCharmHad, parts); + if (sliceMcCharmHad.size() > 0 && sliceMcV0.size() > 0) { + doSameEvent(sliceMcCharmHad, sliceMcV0, parts, col); + } + + } else if (v0Sel.pdgCodeV0 == kK0Short) { + auto sliceMcV0 = partitionMcK0Short->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + fillTables(col, sliceMcV0, sliceMcCharmHad, parts); + + if (sliceMcCharmHad.size() > 0 && sliceMcV0.size() > 0) { + doSameEvent(sliceMcCharmHad, sliceMcV0, parts, col); + } + } else { + LOG(fatal) << "Unsupported V0 PDG: " << v0Sel.pdgCodeV0 << " (allowed: 3122, 310)"; + } + } + runMixing(cols, parts, partitionMcCharmHadron3Prong); + } + PROCESS_SWITCH(HfTaskCharmHadronsV0FemtoDream, processMcDplusV0, "Enable processing DplusToPiKPi and V0 correlation for Monte Carlo", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx b/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx index 622c5a7a037..61c87645ba4 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationDsHadrons.cxx @@ -128,6 +128,7 @@ struct HfTaskCorrelationDsHadrons { Configurable> pidTOFMax{"pidTOFMax", std::vector{3., 0., 0.}, "maximum nSigma TOF"}; Configurable> binsPtD{"binsPtD", std::vector{o2::analysis::hf_cuts_ds_to_k_k_pi::vecBinsPt}, "pT bin limits for candidate mass plots and efficiency"}; Configurable> binsPtHadron{"binsPtHadron", std::vector{0.3, 2., 4., 8., 12., 50.}, "pT bin limits for assoc particle efficiency"}; + Configurable> binsCentrality{"binsCentrality", std::vector{0., 10., 30., 100.}, "Centrality bin limits"}; Configurable> mlOutputPromptMin{"mlOutputPromptMin", {0.5, 0.5, 0.5, 0.5}, "Machine learning scores for prompt"}; Configurable> mlOutputPromptMax{"mlOutputPromptMax", {1.0, 1.0, 1.0, 1.0}, "Machine learning scores for prompt"}; Configurable> mlOutputBkg{"mlOutputBkg", {0.5, 0.5, 0.5, 0.5}, "Machine learning scores for bkg"}; @@ -176,7 +177,7 @@ struct HfTaskCorrelationDsHadrons { Preslice perCollisionCandMc = o2::aod::mcparticle::mcCollisionId; Preslice perCollision = o2::aod::track::collisionId; Preslice perCollisionMc = o2::aod::mcparticle::mcCollisionId; - PresliceUnsorted> collPerCollMc = o2::aod::mccollisionlabel::mcCollisionId; + PresliceUnsorted> collPerCollMc = o2::aod::mccollisionlabel::mcCollisionId; ConfigurableAxis binsMassD{"binsMassD", {200, 1.7, 2.25}, "inv. mass (K^{#pm}K^{-}#pi^{+}) (GeV/#it{c}^{2})"}; ConfigurableAxis binsBdtScore{"binsBdtScore", {100, 0., 1.}, "Bdt output scores"}; @@ -196,6 +197,7 @@ struct HfTaskCorrelationDsHadrons { AxisSpec axisEta = {binsEta, "#it{#eta}"}; AxisSpec axisDetlaPhi = {binsPhi, "#it{#varphi}^{Hadron}-#it{#varphi}^{D} (rad)"}; AxisSpec axisPtD = {(std::vector)binsPtD, "#it{p}_{T}^{D} (GeV/#it{c})"}; + AxisSpec axisCentrality = {(std::vector)binsCentrality, "centrality FT0M (%)"}; AxisSpec axisPtHadron = {(std::vector)binsPtHadron, "#it{p}_{T}^{Hadron} (GeV/#it{c})"}; AxisSpec axisPoolBin = {binsPoolBin, "poolBin"}; AxisSpec const axisBdtScore = {binsBdtScore, "Bdt score"}; @@ -207,7 +209,7 @@ struct HfTaskCorrelationDsHadrons { // Histograms for data analysis registry.add("hBdtScorePrompt", "Ds BDT prompt score", {HistType::kTH1F, {axisBdtScore}}); registry.add("hBdtScoreBkg", "Ds BDT bkg score", {HistType::kTH1F, {axisBdtScore}}); - registry.add("hMassDsVsPt", "Ds candidates massVsPt", {HistType::kTH2F, {{axisMassD}, {axisPtD}}}); + registry.add("hMassDsVsPt", "Ds candidates massVsPt", {HistType::kTH3F, {{axisMassD}, {axisPtD}, {axisCentrality}}}); if (doLSpair) { registry.add("hCorrel2DVsPtSignalRegionLS", "Ds-h correlations signal region - LS pairs", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}}}); registry.add("hCorrel2DVsPtSidebandLeftLS", "Ds-h correlations sideband left region - LS pairs", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}}}); @@ -229,13 +231,13 @@ struct HfTaskCorrelationDsHadrons { if (fillHistoData) { registry.add("hDeltaEtaPtIntSignalRegion", "Ds-h deltaEta signal region", {HistType::kTH1F, {axisDetlaEta}}); registry.add("hDeltaPhiPtIntSignalRegion", "Ds-h deltaPhi signal region", {HistType::kTH1F, {axisDetlaPhi}}); - registry.add("hCorrel2DVsPtSignalRegion", "Ds-h correlations signal region", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}}}); + registry.add("hCorrel2DVsPtSignalRegion", "Ds-h correlations signal region", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}, {axisCentrality}}}); registry.add("hDeltaEtaPtIntSidebandLeft", "Ds-h deltaEta sideband left region", {HistType::kTH1F, {axisDetlaEta}}); registry.add("hDeltaPhiPtIntSidebandLeft", "Ds-h deltaPhi sideband left region", {HistType::kTH1F, {axisDetlaPhi}}); registry.add("hDeltaEtaPtIntSidebandRight", "Ds-h deltaEta sideband right region", {HistType::kTH1F, {axisDetlaEta}}); registry.add("hDeltaPhiPtIntSidebandRight", "Ds-h deltaPhi sideband right region", {HistType::kTH1F, {axisDetlaPhi}}); - registry.add("hCorrel2DVsPtSidebandLeft", "Ds-h correlations sideband left region", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}}}); - registry.add("hCorrel2DVsPtSidebandRight", "Ds-h correlations sideband right region", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}}}); + registry.add("hCorrel2DVsPtSidebandLeft", "Ds-h correlations sideband left region", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}, {axisCentrality}}}); + registry.add("hCorrel2DVsPtSidebandRight", "Ds-h correlations sideband right region", {HistType::kTHnSparseD, {{axisDetlaPhi}, {axisDetlaEta}, {axisPtD}, {axisPtHadron}, {axisPoolBin}, {axisCentrality}}}); registry.get(HIST("hCorrel2DVsPtSignalRegion"))->Sumw2(); registry.get(HIST("hCorrel2DVsPtSidebandLeft"))->Sumw2(); @@ -304,22 +306,22 @@ struct HfTaskCorrelationDsHadrons { registry.add("hPtCandMcGenDaughterInAcc", "Ds,Hadron particles non prompt - MC Gen", {HistType::kTH1F, {axisPtD}}); if (useHighDimHistoForEff) { - registry.add("hPtCandMcRecPrompt", "Ds prompt candidates", {HistType::kTH2F, {{axisPtD}, {axisNumPvContr}}}); - registry.add("hPtCandMcRecNonPrompt", "Ds non prompt candidates pt", {HistType::kTH2F, {{axisPtD}, {axisNumPvContr}}}); - registry.add("hPtCandMcGenPrompt", "Ds,Hadron particles prompt - MC Gen", {HistType::kTH2F, {{axisPtD}, {axisNumPvContr}}}); - registry.add("hPtCandMcGenNonPrompt", "Ds,Hadron particles non prompt - MC Gen", {HistType::kTH2F, {{axisPtD}, {axisNumPvContr}}}); + registry.add("hPtCandMcRecPrompt", "Ds prompt candidates", {HistType::kTH2F, {{axisPtD}, {axisCentrality}}}); + registry.add("hPtCandMcRecNonPrompt", "Ds non prompt candidates pt", {HistType::kTH2F, {{axisPtD}, {axisCentrality}}}); + registry.add("hPtCandMcGenPrompt", "Ds,Hadron particles prompt - MC Gen", {HistType::kTH2F, {{axisPtD}, {axisCentrality}}}); + registry.add("hPtCandMcGenNonPrompt", "Ds,Hadron particles non prompt - MC Gen", {HistType::kTH2F, {{axisPtD}, {axisCentrality}}}); registry.add("hPtParticleAssocSpecieMcRec", "Associated Particle - MC Rec", {HistType::kTHnSparseF, {axisPtHadron}}); - registry.add("hPtPrmPionMcRec", "Primary pions - MC Rec", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisNumPvContr}}}); - registry.add("hPtPrmKaonMcRec", "Primary kaons - MC Rec", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisNumPvContr}}}); - registry.add("hPtPrmProtonMcRec", "Primary protons - MC Rec", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisNumPvContr}}}); - registry.add("hPtPrmElectronMcRec", "Primary electrons - MC Rec", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisNumPvContr}}}); - registry.add("hPtPrmMuonMcRec", "Primary muons - MC Rec", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisNumPvContr}}}); - registry.add("hPtParticleAssocMcGen", "Associated Particle - MC Gen", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisNumPvContr}}}); - registry.add("hPtPrmPionMcGen", "Primary pions - MC Gen", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisNumPvContr}}}); - registry.add("hPtPrmKaonMcGen", "Primary kaons - MC Gen", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisNumPvContr}}}); - registry.add("hPtPrmProtonMcGen", "Primary protons - MC Gen", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisNumPvContr}}}); - registry.add("hPtPrmElectronMcGen", "Primary electrons - MC Gen", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisNumPvContr}}}); - registry.add("hPtPrmMuonMcGen", "Primary muons - MC Gen", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisNumPvContr}}}); + registry.add("hPtPrmPionMcRec", "Primary pions - MC Rec", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisCentrality}}}); + registry.add("hPtPrmKaonMcRec", "Primary kaons - MC Rec", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisCentrality}}}); + registry.add("hPtPrmProtonMcRec", "Primary protons - MC Rec", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisCentrality}}}); + registry.add("hPtPrmElectronMcRec", "Primary electrons - MC Rec", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisCentrality}}}); + registry.add("hPtPrmMuonMcRec", "Primary muons - MC Rec", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisCentrality}}}); + registry.add("hPtParticleAssocMcGen", "Associated Particle - MC Gen", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisCentrality}}}); + registry.add("hPtPrmPionMcGen", "Primary pions - MC Gen", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisCentrality}}}); + registry.add("hPtPrmKaonMcGen", "Primary kaons - MC Gen", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisCentrality}}}); + registry.add("hPtPrmProtonMcGen", "Primary protons - MC Gen", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisCentrality}}}); + registry.add("hPtPrmElectronMcGen", "Primary electrons - MC Gen", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisCentrality}}}); + registry.add("hPtPrmMuonMcGen", "Primary muons - MC Gen", {HistType::kTHnSparseF, {{axisPtHadron}, {axisEta}, {axisPosZ}, {axisCentrality}}}); } else { registry.add("hPtCandMcRecPrompt", "Ds prompt candidates pt", {HistType::kTH1F, {axisPtD}}); registry.add("hPtCandMcRecNonPrompt", "Ds non prompt candidates pt", {HistType::kTH1F, {axisPtD}}); @@ -487,6 +489,7 @@ struct HfTaskCorrelationDsHadrons { aod::DsCandRecoInfo const& candidates) { for (const auto& candidate : candidates) { + float const centrality = candidate.centrality(); float const massD = candidate.mD(); float const ptD = candidate.signedPtD(); float const bdtScorePrompt = candidate.mlScorePrompt(); @@ -505,13 +508,14 @@ struct HfTaskCorrelationDsHadrons { efficiencyWeightD = getEfficiencyWeight(std::abs(ptD)); } - registry.fill(HIST("hMassDsVsPt"), massD, std::abs(ptD), efficiencyWeightD); + registry.fill(HIST("hMassDsVsPt"), massD, std::abs(ptD), centrality, efficiencyWeightD); registry.fill(HIST("hBdtScorePrompt"), bdtScorePrompt); registry.fill(HIST("hBdtScoreBkg"), bdtScoreBkg); } for (const auto& pairEntry : pairEntries) { // define variables for widely used quantities + float const centrality = pairEntry.centrality(); float deltaPhi = pairEntry.deltaPhi(); float const deltaEta = pairEntry.deltaEta(); float const ptD = pairEntry.signedPtD(); @@ -549,7 +553,7 @@ struct HfTaskCorrelationDsHadrons { } else if (doULSpair && !haveSameSign) { // unlike-sign pairs registry.fill(HIST("hCorrel2DVsPtSignalRegionULS"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin, efficiencyWeight); } else if (fillHistoData) { // default case - registry.fill(HIST("hCorrel2DVsPtSignalRegion"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin, efficiencyWeight); + registry.fill(HIST("hCorrel2DVsPtSignalRegion"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin, centrality, efficiencyWeight); registry.fill(HIST("hDeltaEtaPtIntSignalRegion"), deltaEta, efficiencyWeight); registry.fill(HIST("hDeltaPhiPtIntSignalRegion"), deltaPhi, efficiencyWeight); } @@ -561,7 +565,7 @@ struct HfTaskCorrelationDsHadrons { } else if (doULSpair && !haveSameSign) { // unlike-sign pairs registry.fill(HIST("hCorrel2DVsPtSidebandLeftULS"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin, efficiencyWeight); } else if (fillHistoData) { // default case - registry.fill(HIST("hCorrel2DVsPtSidebandLeft"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin, efficiencyWeight); + registry.fill(HIST("hCorrel2DVsPtSidebandLeft"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin, centrality, efficiencyWeight); registry.fill(HIST("hDeltaEtaPtIntSidebandLeft"), deltaEta, efficiencyWeight); registry.fill(HIST("hDeltaPhiPtIntSidebandLeft"), deltaPhi, efficiencyWeight); } @@ -573,7 +577,7 @@ struct HfTaskCorrelationDsHadrons { } else if (doULSpair && !haveSameSign) { // unlike-sign pairs registry.fill(HIST("hCorrel2DVsPtSidebandRightULS"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin, efficiencyWeight); } else if (fillHistoData) { // default case - registry.fill(HIST("hCorrel2DVsPtSidebandRight"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin, efficiencyWeight); + registry.fill(HIST("hCorrel2DVsPtSidebandRight"), deltaPhi, deltaEta, std::abs(ptD), std::abs(ptHadron), poolBin, centrality, efficiencyWeight); registry.fill(HIST("hDeltaEtaPtIntSidebandRight"), deltaEta, efficiencyWeight); registry.fill(HIST("hDeltaPhiPtIntSidebandRight"), deltaPhi, efficiencyWeight); } @@ -948,7 +952,7 @@ struct HfTaskCorrelationDsHadrons { PROCESS_SWITCH(HfTaskCorrelationDsHadrons, processMcRecME, "Process MC Reco ME", false); /// Ds-Hadron correlation - for calculating candidate reconstruction efficiency using MC reco-level analysis - void processMcCandEfficiency(soa::Join const& collisions, + void processMcCandEfficiency(soa::Join const& collisions, soa::Join const& mcCollisions, CandDsMcGen const& mcParticles, CandDsMcReco const& candidates, @@ -967,6 +971,8 @@ struct HfTaskCorrelationDsHadrons { continue; } + const float centralityMc = getCentralityGenColl(groupedCollisions, centEstimator); + /// loop over reconstructed collisions for (const auto& collision : groupedCollisions) { @@ -980,6 +986,11 @@ struct HfTaskCorrelationDsHadrons { if (selNoSameBunchPileUpColl && !(collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup))) { continue; } + const float centralityRec = getCentralityColl(collision, centEstimator); + if (centralityRec < centralityMin || centralityRec > centralityMax) { + continue; + } + if (!collision.has_mcCollision()) { registry.fill(HIST("hFakeCollision"), 0.); continue; @@ -996,14 +1007,14 @@ struct HfTaskCorrelationDsHadrons { if (std::abs(yDs) <= yCandGenMax) { if (mcParticle.originMcGen() == RecoDecay::OriginType::Prompt) { if (useHighDimHistoForEff) { - registry.fill(HIST("hPtCandMcGenPrompt"), mcParticle.pt(), collision.numContrib()); + registry.fill(HIST("hPtCandMcGenPrompt"), mcParticle.pt(), centralityMc); } else { registry.fill(HIST("hPtCandMcGenPrompt"), mcParticle.pt()); } } if (mcParticle.originMcGen() == RecoDecay::OriginType::NonPrompt) { if (useHighDimHistoForEff) { - registry.fill(HIST("hPtCandMcGenNonPrompt"), mcParticle.pt(), collision.numContrib()); + registry.fill(HIST("hPtCandMcGenNonPrompt"), mcParticle.pt(), centralityMc); } else { registry.fill(HIST("hPtCandMcGenNonPrompt"), mcParticle.pt()); } @@ -1049,14 +1060,14 @@ struct HfTaskCorrelationDsHadrons { if (std::abs(HfHelper::yDs(candidate)) <= yCandMax) { if (candidate.originMcRec() == RecoDecay::OriginType::Prompt) { if (useHighDimHistoForEff) { - registry.fill(HIST("hPtCandMcRecPrompt"), candidate.pt(), collision.numContrib()); + registry.fill(HIST("hPtCandMcRecPrompt"), candidate.pt(), centralityRec); } else { registry.fill(HIST("hPtCandMcRecPrompt"), candidate.pt()); } } if (candidate.originMcRec() == RecoDecay::OriginType::NonPrompt) { if (useHighDimHistoForEff) { - registry.fill(HIST("hPtCandMcRecNonPrompt"), candidate.pt(), collision.numContrib()); + registry.fill(HIST("hPtCandMcRecNonPrompt"), candidate.pt(), centralityRec); } else { registry.fill(HIST("hPtCandMcRecNonPrompt"), candidate.pt()); } @@ -1162,6 +1173,8 @@ struct HfTaskCorrelationDsHadrons { continue; } + const float centralityMc = getCentralityGenColl(groupedCollisions, centEstimator); + /// loop over reconstructed collisions for (const auto& collision : groupedCollisions) { @@ -1175,8 +1188,8 @@ struct HfTaskCorrelationDsHadrons { if (selNoSameBunchPileUpColl && !(collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup))) { continue; } - int centrality = getCentrality(collision); - if (centrality < centralityMin || centrality > centralityMax) { + const float centralityRec = getCentralityColl(collision, centEstimator); + if (centralityRec < centralityMin || centralityRec > centralityMax) { continue; } if (!collision.has_mcCollision()) { @@ -1192,17 +1205,17 @@ struct HfTaskCorrelationDsHadrons { if (mcParticle.pt() > ptTrackMin && mcParticle.pt() < ptTrackMax) { if (std::abs(mcParticle.eta()) < etaTrackMax) { if (useHighDimHistoForEff) { - registry.fill(HIST("hPtParticleAssocMcGen"), mcParticle.pt(), mcParticle.eta(), collision.posZ(), collision.numContrib()); + registry.fill(HIST("hPtParticleAssocMcGen"), mcParticle.pt(), mcParticle.eta(), collision.posZ(), centralityMc); if (std::abs(mcParticle.pdgCode()) == kPiPlus) { - registry.fill(HIST("hPtPrmPionMcGen"), mcParticle.pt(), mcParticle.eta(), collision.posZ(), collision.numContrib()); + registry.fill(HIST("hPtPrmPionMcGen"), mcParticle.pt(), mcParticle.eta(), collision.posZ(), centralityMc); } else if (std::abs(mcParticle.pdgCode()) == kKPlus) { - registry.fill(HIST("hPtPrmKaonMcGen"), mcParticle.pt(), mcParticle.eta(), collision.posZ(), collision.numContrib()); + registry.fill(HIST("hPtPrmKaonMcGen"), mcParticle.pt(), mcParticle.eta(), collision.posZ(), centralityMc); } else if (std::abs(mcParticle.pdgCode()) == kProton) { - registry.fill(HIST("hPtPrmProtonMcGen"), mcParticle.pt(), mcParticle.eta(), collision.posZ(), collision.numContrib()); + registry.fill(HIST("hPtPrmProtonMcGen"), mcParticle.pt(), mcParticle.eta(), collision.posZ(), centralityMc); } else if (std::abs(mcParticle.pdgCode()) == kElectron) { - registry.fill(HIST("hPtPrmElectronMcGen"), mcParticle.pt(), mcParticle.eta(), collision.posZ(), collision.numContrib()); + registry.fill(HIST("hPtPrmElectronMcGen"), mcParticle.pt(), mcParticle.eta(), collision.posZ(), centralityMc); } else if (std::abs(mcParticle.pdgCode()) == kMuonMinus) { - registry.fill(HIST("hPtPrmMuonMcGen"), mcParticle.pt(), mcParticle.eta(), collision.posZ(), collision.numContrib()); + registry.fill(HIST("hPtPrmMuonMcGen"), mcParticle.pt(), mcParticle.eta(), collision.posZ(), centralityMc); } } else { registry.fill(HIST("hPtParticleAssocMcGen"), mcParticle.pt()); @@ -1251,15 +1264,15 @@ struct HfTaskCorrelationDsHadrons { if (useHighDimHistoForEff) { registry.fill(HIST("hPtParticleAssocSpecieMcRec"), track.pt()); if (std::abs(mcParticle.pdgCode()) == kPiPlus) { - registry.fill(HIST("hPtPrmPionMcRec"), track.pt(), track.eta(), collision.posZ(), collision.numContrib()); + registry.fill(HIST("hPtPrmPionMcRec"), track.pt(), track.eta(), collision.posZ(), centralityRec); } else if (std::abs(mcParticle.pdgCode()) == kKPlus) { - registry.fill(HIST("hPtPrmKaonMcRec"), track.pt(), track.eta(), collision.posZ(), collision.numContrib()); + registry.fill(HIST("hPtPrmKaonMcRec"), track.pt(), track.eta(), collision.posZ(), centralityRec); } else if (std::abs(mcParticle.pdgCode()) == kProton) { - registry.fill(HIST("hPtPrmProtonMcRec"), track.pt(), track.eta(), collision.posZ(), collision.numContrib()); + registry.fill(HIST("hPtPrmProtonMcRec"), track.pt(), track.eta(), collision.posZ(), centralityRec); } else if (std::abs(mcParticle.pdgCode()) == kElectron) { - registry.fill(HIST("hPtPrmElectronMcRec"), track.pt(), track.eta(), collision.posZ(), collision.numContrib()); + registry.fill(HIST("hPtPrmElectronMcRec"), track.pt(), track.eta(), collision.posZ(), centralityRec); } else if (std::abs(mcParticle.pdgCode()) == kMuonMinus) { - registry.fill(HIST("hPtPrmMuonMcRec"), track.pt(), track.eta(), collision.posZ(), collision.numContrib()); + registry.fill(HIST("hPtPrmMuonMcRec"), track.pt(), track.eta(), collision.posZ(), centralityRec); } } else { registry.fill(HIST("hPtParticleAssocSpecieMcRec"), track.pt()); diff --git a/PWGHF/HFC/Tasks/taskFlow.cxx b/PWGHF/HFC/Tasks/taskFlow.cxx index 467410d7151..6756a4e2334 100644 --- a/PWGHF/HFC/Tasks/taskFlow.cxx +++ b/PWGHF/HFC/Tasks/taskFlow.cxx @@ -22,12 +22,12 @@ #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/DataModel/TrackIndexSkimmingTables.h" -#include "PWGHF/Utils/utilsPid.h" #include "PWGMM/Mult/DataModel/bestCollisionTable.h" #include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/RCTSelectionFlags.h" #include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -57,12 +56,11 @@ #include #include -#include +#include #include #include -#include #include #include #include @@ -225,6 +223,7 @@ struct HfTaskFlow { Configurable nSamples{"nSamples", 10, "number of different samples for correlations"}; Configurable nameCorrelationContainer{"nameCorrelationContainer", "", "Add the possibility to the rename the correlation container as configurable"}; Configurable useEfficiencyCorrection{"useEfficiencyCorrection", false, "Choose to use or not use efficiency correction, if not used, weight is set to 1"}; + Configurable useOnlyPrimaryInMc{"useOnlyPrimaryInMc", false, "Choose to use or not use only primaries for McGen"}; } configTask; // configurables for collisions @@ -318,13 +317,13 @@ struct HfTaskFlow { Service pdg{}; Service ccdb{}; std::vector* offsetFT0{}; - std::vector* offsetFV0{}; + // std::vector* offsetFV0{}; o2::ccdb::CcdbApi ccdbApi; o2::ft0::Geometry ft0Det; - o2::fv0::Geometry* fv0Det{}; + // o2::fv0::Geometry* fv0Det{}; std::vector cstFT0RelGain{}; RCTFlagsChecker rctChecker; - RCTFlagsChecker correlationAnalysisRctChecker{kFT0Bad, kITSBad, kTPCBadTracking, kTPCBadPID, kMFTBad}; + RCTFlagsChecker correlationAnalysisRctChecker{kFT0Bad, kITSBad, kTPCBadTracking, kTPCBadPID, kMFTBad, kITSLimAccMCRepr, kMFTLimAccMCRepr, kTPCLimAccMCRepr}; TH3D* mEfficiencyTpc = nullptr; TH3D* mEfficiencyMft = nullptr; @@ -349,6 +348,8 @@ struct HfTaskFlow { // ========================= using SmallGroupMcCollisions = soa::SmallGroups>; + using FilteredMcCollisionsWMult = soa::Filtered>; + using FilteredMcParticles = soa::Filtered; // ========================= // Filters & partitions : DATA @@ -383,11 +384,19 @@ struct HfTaskFlow { Filter mftTrackEtaFilter = ((aod::fwdtrack::eta < configMft.etaMftTrackMaxFilter) && (aod::fwdtrack::eta > configMft.etaMftTrackMinFilter)); - // Filters below will be used for uncertainties Filter mftTrackCollisionIdFilter = (aod::fwdtrack::bestCollisionId >= 0); // Filter mftTrackDcaXYFilter = (nabs(aod::fwdtrack::bestDCAXY) < configMft.mftMaxDCAxy); // Filter mftTrackDcaZFilter = (nabs(aod::fwdtrack::bestDCAZ) < configMft.mftMaxDCAz); + // ========================= + // Filters & partitions : MC + // ========================= + + Filter mcParticleFilter = (((aod::mcparticle::eta > configTask.etaMcParticlesTriggerMin) && (aod::mcparticle::eta < configTask.etaMcParticlesTriggerMax)) || ((aod::mcparticle::eta > configTask.etaMcParticlesAssocMin) && (aod::mcparticle::eta < configTask.etaMcParticlesAssocMax)) || (nabs(aod::mcparticle::eta) < configCentral.etaCentralTrackMax)) && (aod::mcparticle::pt > configTask.ptMcParticlesTriggerMin) && (aod::mcparticle::pt < configTask.ptMcParticlesTriggerMax); + + // Filter for MCcollisions + Filter mcCollisionFilter = nabs(aod::mccollision::posZ) < configCollision.zVertexMax; + // ========================= // Preslice : DATA // ========================= @@ -396,7 +405,7 @@ struct HfTaskFlow { Preslice perColLcs = aod::track::collisionId; Preslice perColMftTracks = o2::aod::fwdtrack::collisionId; Preslice perColTracks = aod::track::collisionId; - Preslice perMcColMcParticles = aod::mcparticle::mcCollisionId; + // Preslice perMcColMcParticles = aod::mcparticle::mcCollisionId; PresliceUnsorted> perColReassociated2dTracks = o2::aod::fwdtrack::collisionId; PresliceUnsorted> perColReassociated3dTracks = o2::aod::fwdtrack::collisionId; @@ -524,12 +533,12 @@ struct HfTaskFlow { ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); LOGF(info, "Getting alignment offsets from the CCDB..."); offsetFT0 = ccdb->getForTimeStamp>("FT0/Calib/Align", configCcdb.noLaterThan.value); - offsetFV0 = ccdb->getForTimeStamp>("FV0/Calib/Align", configCcdb.noLaterThan.value); + // offsetFV0 = ccdb->getForTimeStamp>("FV0/Calib/Align", configCcdb.noLaterThan.value); LOGF(info, "Offset for FT0A: x = %.3f y = %.3f z = %.3f\n", (*offsetFT0)[0].getX(), (*offsetFT0)[0].getY(), (*offsetFT0)[0].getZ()); LOGF(info, "Offset for FT0C: x = %.3f y = %.3f z = %.3f\n", (*offsetFT0)[1].getX(), (*offsetFT0)[1].getY(), (*offsetFT0)[1].getZ()); - LOGF(info, "Offset for FV0-left: x = %.3f y = %.3f z = %.3f\n", (*offsetFV0)[0].getX(), (*offsetFV0)[0].getY(), (*offsetFV0)[0].getZ()); - LOGF(info, "Offset for FV0-right: x = %.3f y = %.3f z = %.3f\n", (*offsetFV0)[1].getX(), (*offsetFV0)[1].getY(), (*offsetFV0)[1].getZ()); - fv0Det = o2::fv0::Geometry::instance(o2::fv0::Geometry::eUninitialized); + // LOGF(info, "Offset for FV0-left: x = %.3f y = %.3f z = %.3f\n", (*offsetFV0)[0].getX(), (*offsetFV0)[0].getY(), (*offsetFV0)[0].getZ()); + // LOGF(info, "Offset for FV0-right: x = %.3f y = %.3f z = %.3f\n", (*offsetFV0)[1].getX(), (*offsetFV0)[1].getY(), (*offsetFV0)[1].getZ()); + // fv0Det = o2::fv0::Geometry::instance(o2::fv0::Geometry::eUninitialized); // ========================= // Event histograms @@ -648,7 +657,10 @@ struct HfTaskFlow { addHistograms(); addMftHistograms(); registry.add("Data/hEfficiencyTrigger", "", {HistType::kTH3D, {{configAxis.axisPtTrigger}, {configAxis.axisEtaTrigger}, {configAxis.axisVertex}}}); - registry.add("Data/hEfficiencyAssociated", "", {HistType::kTH3D, {{configAxis.axisPtTrigger}, {configAxis.axisEtaTrigger}, {configAxis.axisVertex}}}); + registry.add("Data/hEfficiencyAssociated", "", {HistType::kTH3D, {{configAxis.axisPtAssoc}, {configAxis.axisEtaAssociated}, {configAxis.axisVertex}}}); + + registry.add("Data/hMultiplicity_uncorrected", "", {HistType::kTH1D, {configAxis.axisMultiplicity}}); + registry.add("Data/hMultiplicity_corrected", "", {HistType::kTH1D, {configAxis.axisMultiplicity}}); if (!configTask.doEtaDependentFlow && !configTask.doVariationContainers) { registry.add("Trig_hist_TPC_MFT", "", {HistType::kTHnSparseF, {{configAxis.axisSamples, configAxis.axisVertex, configAxis.axisPtTrigger}}}); @@ -852,7 +864,7 @@ struct HfTaskFlow { sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); } else if (configTask.doEtaDependentFlow) { - registry.add("Trig_hist_FT0A_FT0C ", "", {HistType::kTHnSparseF, {{configAxis.axisSamples, configAxis.axisVertex, configAxis.axisEtaTrigger}}}); + registry.add("Trig_hist_FT0A_FT0C", "", {HistType::kTHnSparseF, {{configAxis.axisSamples, configAxis.axisVertex, configAxis.axisEtaTrigger}}}); sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxisEta, effAxis, {})); mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxisEta, effAxis, {})); } else { @@ -869,7 +881,7 @@ struct HfTaskFlow { if (doprocessSameMcGen) { registry.add("MC/hEfficiencyTrigger", "", {HistType::kTH3D, {{configAxis.axisPtTrigger}, {configAxis.axisEtaTrigger}, {configAxis.axisVertex}}}); - registry.add("MC/hEfficiencyAssociated", "", {HistType::kTH3D, {{configAxis.axisPtTrigger}, {configAxis.axisEtaTrigger}, {configAxis.axisVertex}}}); + registry.add("MC/hEfficiencyAssociated", "", {HistType::kTH3D, {{configAxis.axisPtTrigger}, {configAxis.axisEtaAssociated}, {configAxis.axisVertex}}}); if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::TpcTpc)) { addHistograms(); @@ -881,6 +893,8 @@ struct HfTaskFlow { addHistograms(); } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::TpcFt0a)) { addHistograms(); + } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::MftFt0a)) { + addHistograms(); } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::TpcFt0c)) { addHistograms(); } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::Ft0aFt0c)) { @@ -902,27 +916,6 @@ struct HfTaskFlow { } } - // ========================= - // Initialization of histograms and CorrelationContainers for McGen cases - // ========================= - - // if (doprocessSameMcGen) { - - // if (!configTask.doEtaDependentFlow && !configTask.doVariationContainers) { - // registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{configAxis.axisSamples, configAxis.axisVertex, configAxis.axisPtTrigger}}}); - // sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, {})); - // mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, {})); - // } else if (configTask.doEtaDependentFlow){ - // registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{configAxis.axisSamples, configAxis.axisVertex, configAxis.axisEtaTrigger}}}); - // sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxisEta, effAxis, {})); - // mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxisEta, effAxis, {})); - // } else { - // registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{configAxis.axisSamples, configAxis.axisVertex, configAxis.axisPtTrigger}}}); - // sameEvent.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxisVariations, effAxis, {})); - // mixedEvent.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxisVariations, effAxis, {})); - // } - // } - } // End of init() function // ========================= @@ -1191,10 +1184,10 @@ struct HfTaskFlow { float efficiencyTpc = 1.; if (mEfficiencyTpc) { - int etaBin = mEfficiencyTpc->GetXaxis()->FindBin(eta); - int ptBin = mEfficiencyTpc->FindBin(pt); + int ptBin = mEfficiencyTpc->GetXaxis()->FindBin(pt); + int etaBin = mEfficiencyTpc->GetYaxis()->FindBin(eta); int vertexBin = mEfficiencyTpc->GetZaxis()->FindBin(vertex); - efficiencyTpc = mEfficiencyTpc->GetBinContent(etaBin, ptBin, vertexBin); + efficiencyTpc = mEfficiencyTpc->GetBinContent(ptBin, etaBin, vertexBin); } if (efficiencyTpc == 0) { @@ -1211,10 +1204,10 @@ struct HfTaskFlow { float efficiencyMft = 1.; if (mEfficiencyMft) { - int etaBin = mEfficiencyMft->GetXaxis()->FindBin(eta); - int ptBin = mEfficiencyMft->FindBin(pt); + int ptBin = mEfficiencyMft->GetXaxis()->FindBin(pt); + int etaBin = mEfficiencyMft->GetYaxis()->FindBin(eta); int vertexBin = mEfficiencyMft->GetZaxis()->FindBin(vertex); - efficiencyMft = mEfficiencyMft->GetBinContent(etaBin, ptBin, vertexBin); + efficiencyMft = mEfficiencyMft->GetBinContent(ptBin, etaBin, vertexBin); } if (efficiencyMft == 0) { @@ -1237,9 +1230,6 @@ struct HfTaskFlow { trackCounter += 1; } - // if (!getEfficiencyCorrection_Nch(weight_Nch, track.pt())) { - // continue; - // } auto efficiencyNch = 1.0f; if (configTask.useEfficiencyCorrection) { @@ -1262,24 +1252,6 @@ struct HfTaskFlow { return trackCounter; } - // bool getEfficiencyCorrectionNch(float& weightNch, float pt) - // { - // float efficiencyNch = 1.; - - // if (mEfficiencyNch) { - // int ptBin = mEfficiencyNch->FindBin(pt); - // efficiencyNch = mEfficiencyNch->GetBinContent(ptBin); - // } - - // if (efficiencyNch == 0 ) { - // return false; - // } - - // weightNch = 1. / efficiencyNch; - - // return true; - // } - // ========================= // Cuts with functions // ========================= @@ -2401,8 +2373,8 @@ struct HfTaskFlow { TTracksTrig const& tracks1, TTracksAssoc const& tracks2, float multiplicity, float posZ, bool sameEvent) { - auto triggerWeight = 1; - auto associatedWeight = 1; + auto triggerWeight = 1.0f; + auto associatedWeight = 1.0f; auto loopCounter = 0; // To avoid filling associated tracks QA many times, I fill it only for the first trigger track of the collision int sampleIndex = gRandom->Uniform(0, configTask.nSamples); bool fillQaPlots = false; @@ -2426,7 +2398,7 @@ struct HfTaskFlow { if (track1.pt() < configTask.ptMcParticlesTriggerMin || track1.pt() > configTask.ptMcParticlesTriggerMax) { continue; } - if (step >= CorrelationContainer::kCFStepTrackedOnlyPrim && !track1.isPhysicalPrimary()) { + if (configTask.useOnlyPrimaryInMc && !track1.isPhysicalPrimary()) { continue; } @@ -2452,6 +2424,8 @@ struct HfTaskFlow { fillTriggerQa(multiplicity, track1.eta(), track1.phi(), track1.pt()); } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::TpcFt0a)) { fillTriggerQa(multiplicity, track1.eta(), track1.phi(), track1.pt()); + } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::MftFt0a)) { + fillTriggerQa(multiplicity, track1.eta(), track1.phi(), track1.pt()); } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::TpcFt0c)) { fillTriggerQa(multiplicity, track1.eta(), track1.phi(), track1.pt()); } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::Ft0aFt0c)) { @@ -2470,7 +2444,7 @@ struct HfTaskFlow { if (track2.pt() < configTask.ptMcParticlesAssocMin || track2.pt() > configTask.ptMcParticlesAssocMax) { continue; } - if (step >= CorrelationContainer::kCFStepTrackedOnlyPrim && !track2.isPhysicalPrimary()) { + if (configTask.useOnlyPrimaryInMc && !track2.isPhysicalPrimary()) { continue; } @@ -2492,19 +2466,21 @@ struct HfTaskFlow { if (sameEvent && fillQaPlots && (loopCounter == 1)) { registry.fill(HIST("MC/hEfficiencyAssociated"), track2.pt(), track2.eta(), posZ); if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::TpcTpc)) { - fillAssociatedQa(track2.eta(), track2.phi(), track2.pt()); + fillAssociatedQa(multiplicity, track2.eta(), track2.phi()); } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::TpcMft)) { - fillAssociatedQa(track2.eta(), track2.phi(), track2.pt()); + fillAssociatedQa(multiplicity, track2.eta(), track2.phi()); } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::TpcFv0a)) { - fillAssociatedQa(track2.eta(), track2.phi(), track2.pt()); + fillAssociatedQa(multiplicity, track2.eta(), track2.phi()); } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::MftFv0a)) { - fillAssociatedQa(track2.eta(), track2.phi(), track2.pt()); + fillAssociatedQa(multiplicity, track2.eta(), track2.phi()); } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::TpcFt0a)) { - fillAssociatedQa(track2.eta(), track2.phi(), track2.pt()); + fillAssociatedQa(multiplicity, track2.eta(), track2.phi()); + } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::MftFt0a)) { + fillAssociatedQa(multiplicity, track2.eta(), track2.phi()); } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::TpcFt0c)) { - fillAssociatedQa(track2.eta(), track2.phi(), track2.pt()); + fillAssociatedQa(multiplicity, track2.eta(), track2.phi()); } else if (configTask.chooseCorrelationCase.value == static_cast(CorrelationCase::Ft0aFt0c)) { - fillAssociatedQa(track2.eta(), track2.phi(), track2.pt()); + fillAssociatedQa(multiplicity, track2.eta(), track2.phi()); } } // end of fill QA } // end of loop over track2 @@ -2658,9 +2634,10 @@ struct HfTaskFlow { auto bc = collision1.template bc_as(); loadEfficiencyCorrection(bc.timestamp()); + auto tracksForMultiplicity = tracksTpc.sliceByCached(o2::aod::track::collisionId, collision1.globalIndex(), cache); auto multiplicity = 0; if (configCollision.useMultiplicityFromTracks) { - multiplicity = tracksTpc.size(); + multiplicity = tracksForMultiplicity.size(); } else { multiplicity = getMultiplicityEstimator(collision1, false); } @@ -2685,8 +2662,8 @@ struct HfTaskFlow { } // end of for loop } - template - void mixCollisionsFIT(TCollisions const& collisions, CorrelationContainer::CFStep step, + template + void mixCollisionsFIT(TCollisions const& collisions, CorrelationContainer::CFStep step, TTracksTpc const& tracksTpc, TTracksTrig const& tracks1, TTracksAssoc const& tracks2, TPreslice const& preslice, OutputObj& corrContainer, int fitType, aod::BCsWithTimestamps const&) { @@ -2721,36 +2698,39 @@ struct HfTaskFlow { auto bc = collision1.template bc_as(); loadEfficiencyCorrection(bc.timestamp()); - if constexpr (std::is_same_v) { // IF ASSOCIATED PARTICLE FROM FV0A - if (collision1.has_foundFV0() && collision2.has_foundFV0()) { + // if constexpr (std::is_same_v) { // IF ASSOCIATED PARTICLE FROM FV0A + // if (collision1.has_foundFV0() && collision2.has_foundFV0()) { - auto slicedTriggerTracks = tracks1.sliceBy(preslice, collision1.globalIndex()); - const auto& fv0 = collision2.foundFV0(); + // auto slicedTriggerTracks = tracks1.sliceBy(preslice, collision1.globalIndex()); + // auto tracksForMultiplicity = tracksTpc.sliceByCached(o2::aod::track::collisionId, collision1.globalIndex(), cache); + // const auto& fv0 = collision2.foundFV0(); - auto multiplicity = 0; - if (configCollision.useMultiplicityFromTracks) { - multiplicity = tracks1.size(); - } else { - multiplicity = getMultiplicityEstimator(collision1, false); - } + // auto multiplicity = 0; + // if (configCollision.useMultiplicityFromTracks) { + // multiplicity = tracksForMultiplicity.size(); + // } else { + // multiplicity = getMultiplicityEstimator(collision1, false); + // } - if (multiplicity < configCollision.minMultiplicity || multiplicity >= configCollision.maxMultiplicity) { - return; - } + // if (multiplicity < configCollision.minMultiplicity || multiplicity >= configCollision.maxMultiplicity) { + // return; + // } - corrContainer->fillEvent(multiplicity, step); - fillCorrelationsFIT(corrContainer, step, slicedTriggerTracks, fv0, tracks2, multiplicity, collision1.posZ(), false, fitType); - } - } // end of if condition for FV0s + // corrContainer->fillEvent(multiplicity, step); + // fillCorrelationsFIT(corrContainer, step, slicedTriggerTracks, fv0, tracks2, multiplicity, collision1.posZ(), false, fitType); + // } + // } // end of if condition for FV0s if constexpr (std::is_same_v) { if (collision1.has_foundFT0() && collision2.has_foundFT0()) { auto slicedTriggerTracks = tracks1.sliceBy(preslice, collision1.globalIndex()); + auto tracksForMultiplicity = tracksTpc.sliceByCached(o2::aod::track::collisionId, collision1.globalIndex(), cache); const auto& ft0 = collision2.foundFT0(); + auto multiplicity = 0; if (configCollision.useMultiplicityFromTracks) { - multiplicity = tracks1.size(); + multiplicity = tracksForMultiplicity.size(); } else { multiplicity = getMultiplicityEstimator(collision1, false); } @@ -2806,13 +2786,13 @@ struct HfTaskFlow { auto bc = collision1.template bc_as(); loadEfficiencyCorrection(bc.timestamp()); + auto tracksForMultiplicity = tracksTpc.sliceByCached(o2::aod::track::collisionId, collision1.globalIndex(), cache); auto multiplicity = 0; if (configCollision.useMultiplicityFromTracks) { - multiplicity = tracksTpc.size(); + multiplicity = tracksForMultiplicity.size(); } else { multiplicity = getMultiplicityEstimator(collision1, false); } - if (multiplicity < configCollision.minMultiplicity || multiplicity >= configCollision.maxMultiplicity) { return; } @@ -3037,6 +3017,12 @@ struct HfTaskFlow { multiplicity = getMultiplicityEstimator(collision, true); } + registry.fill(HIST("Data/hMultiplicity_uncorrected"), multiplicity); + if (configCollision.useMultiplicityFromTracksCorrected) { + multiplicity = getCorrectedMultiplicity(tracks); + registry.fill(HIST("Data/hMultiplicity_corrected"), multiplicity); + } + if (multiplicity < configCollision.minMultiplicity || multiplicity >= configCollision.maxMultiplicity) { return; } @@ -3826,14 +3812,10 @@ struct HfTaskFlow { // MONTE-CARLO // =================================================================================================================================================================================================================================================================== - void processSameMcGen(soa::Join::iterator const& mcCollision, - aod::McParticles const& mcParticles, + void processSameMcGen(FilteredMcCollisionsWMult::iterator const& mcCollision, + FilteredMcParticles const& mcParticles, SmallGroupMcCollisions const& collisions) { - if (!(std::abs(mcCollision.posZ()) <= configCollision.zVertexMax)) { - return; - } - auto multiplicity = 0; if (configCollision.useMultiplicityFromTracks) { for (const auto& track : mcParticles) { @@ -3849,15 +3831,12 @@ struct HfTaskFlow { return; } - sameEvent->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepAll); - fillCorrelationsMonteCarlo(sameEvent, CorrelationContainer::CFStep::kCFStepAll, mcParticles, mcParticles, multiplicity, mcCollision.posZ(), true); - if (collisions.size() == 0) { return; } - sameEvent->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepTrackedOnlyPrim); - fillCorrelationsMonteCarlo(sameEvent, CorrelationContainer::CFStep::kCFStepTrackedOnlyPrim, mcParticles, mcParticles, multiplicity, mcCollision.posZ(), true); + sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepAll); + fillCorrelationsMonteCarlo(sameEvent, CorrelationContainer::CFStep::kCFStepAll, mcParticles, mcParticles, multiplicity, mcCollision.posZ(), true); } PROCESS_SWITCH(HfTaskFlow, processSameMcGen, "MC Gen : Process same-event correlations", false); @@ -4066,9 +4045,9 @@ struct HfTaskFlow { aod::BCsWithTimestamps const& bcs) { if (!configTask.doEtaDependentFlow && !configTask.doVariationContainers) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, ft0s, perColTracks, mixedEvent, isFT0A, bcs); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, tracks, ft0s, perColTracks, mixedEvent, isFT0A, bcs); } else { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, ft0s, perColTracks, mixedEventTpcFt0a, isFT0A, bcs); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, tracks, ft0s, perColTracks, mixedEventTpcFt0a, isFT0A, bcs); } } PROCESS_SWITCH(HfTaskFlow, processMixedTpcFt0aChCh, "DATA : Process mixed-event correlations for TPC-FT0-A h-h case", false); @@ -4079,10 +4058,11 @@ struct HfTaskFlow { void processMixedTpcFt0aD0Ch(FilteredCollisionsWSelMult const& collisions, HfCandidatesSelD0 const& candidates, + FilteredTracksWDcaSel const& tracks, aod::FT0s const& ft0s, aod::BCsWithTimestamps const& bcs) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, candidates, ft0s, perColD0s, mixedEventHf, isFT0A, bcs); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, candidates, ft0s, perColD0s, mixedEventHf, isFT0A, bcs); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcFt0aD0Ch, "DATA : Process mixed-event correlations for TPC-FT0-A D0-h case", false); @@ -4092,10 +4072,11 @@ struct HfTaskFlow { void processMixedTpcFt0aLcCh(FilteredCollisionsWSelMult const& collisions, HfCandidatesSelLc const& candidates, + FilteredTracksWDcaSel const& tracks, aod::FT0s const& ft0s, aod::BCsWithTimestamps const& bcs) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, candidates, ft0s, perColLcs, mixedEventHf, isFT0A, bcs); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, candidates, ft0s, perColLcs, mixedEventHf, isFT0A, bcs); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcFt0aLcCh, "DATA : Process mixed-event correlations for TPC-FT0-A Lc-h case", false); @@ -4105,13 +4086,14 @@ struct HfTaskFlow { void processMixedMftFt0aChCh(FilteredCollisionsWSelMult const& collisions, FilteredMftTracks const& mftTracks, + FilteredTracksWDcaSel const& tracks, aod::FT0s const& ft0s, aod::BCsWithTimestamps const& bcs) { if (!configTask.doEtaDependentFlow && !configTask.doVariationContainers) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, mftTracks, ft0s, perColMftTracks, mixedEvent, isFT0A, bcs); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, mftTracks, ft0s, perColMftTracks, mixedEvent, isFT0A, bcs); } else { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, mftTracks, ft0s, perColMftTracks, mixedEventMftFt0a, isFT0A, bcs); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, mftTracks, ft0s, perColMftTracks, mixedEventMftFt0a, isFT0A, bcs); } } PROCESS_SWITCH(HfTaskFlow, processMixedMftFt0aChCh, "DATA : Process mixed-event correlations for MFT-FT0-A h-h case", false); @@ -4170,7 +4152,7 @@ struct HfTaskFlow { aod::FT0s const& ft0s, aod::BCsWithTimestamps const& bcs) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, ft0s, perColTracks, mixedEvent, isFT0C, bcs); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, tracks, ft0s, perColTracks, mixedEvent, isFT0C, bcs); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcFt0cChCh, "DATA : Process mixed-event correlations for TPC-FT0C h-h case", false); @@ -4180,10 +4162,11 @@ struct HfTaskFlow { void processMixedTpcFt0cD0Ch(FilteredCollisionsWSelMult const& collisions, HfCandidatesSelD0 const& candidates, + FilteredTracksWDcaSel const& tracks, aod::FT0s const& ft0s, aod::BCsWithTimestamps const& bcs) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, candidates, ft0s, perColD0s, mixedEventHf, isFT0C, bcs); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, candidates, ft0s, perColD0s, mixedEventHf, isFT0C, bcs); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcFt0cD0Ch, "DATA : Process mixed-event correlations for TPC-FT0C D0-h case", false); @@ -4193,10 +4176,11 @@ struct HfTaskFlow { void processMixedTpcFt0cLcCh(FilteredCollisionsWSelMult const& collisions, HfCandidatesSelLc const& candidates, + FilteredTracksWDcaSel const& tracks, aod::FT0s const& ft0s, aod::BCsWithTimestamps const& bcs) { - mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, candidates, ft0s, perColLcs, mixedEventHf, isFT0C, bcs); + mixCollisionsFIT(collisions, CorrelationContainer::kCFStepReconstructed, tracks, candidates, ft0s, perColLcs, mixedEventHf, isFT0C, bcs); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcFt0cLcCh, "DATA : Process mixed-event correlations for TPC-FT0C Lc-h case", false); @@ -4217,15 +4201,10 @@ struct HfTaskFlow { // MONTE-CARLO // =================================================================================================================================================================================================================================================================== - void processMixedMcGen(soa::Join const& mcCollisions, - aod::McParticles const& mcParticles, + void processMixedMcGen(FilteredMcCollisionsWMult const& mcCollisions, + FilteredMcParticles const& mcParticles, SmallGroupMcCollisions const& collisions) { - // auto getTracksSize = [&mcParticles, this](aod::McCollisions::iterator const& mcCollision) { - // auto associatedTracks = mcParticles.sliceByCached(o2::aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), this->cache); - // auto multiplicity = associatedTracks.size(); - // return multiplicity; - // }; auto getTracksSize = [&mcParticles, this](soa::Join::iterator const& mcCollision) { auto associatedTracks = mcParticles.sliceByCached(o2::aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), this->cache); @@ -4245,10 +4224,12 @@ struct HfTaskFlow { using MixedBinning = FlexibleBinningPolicy, aod::mccollision::PosZ, decltype(getTracksSize)>; MixedBinning const binningOnVtxAndMult{{getTracksSize}, {configAxis.binsMixingVertex, configAxis.binsMixingMultiplicity}, true}; - for (auto const& [collision1, collision2] : soa::selfCombinations(binningOnVtxAndMult, configTask.nMixedEvents, -1, mcCollisions, mcCollisions)) { + auto tracksTuple = std::make_tuple(mcParticles, mcParticles); + + Pair pairs{binningOnVtxAndMult, configTask.nMixedEvents, -1, mcCollisions, tracksTuple, &cache}; // -1 is the number of the bin to skip - auto tracks1 = mcParticles.sliceBy(perMcColMcParticles, collision1.globalIndex()); - auto tracks2 = mcParticles.sliceBy(perMcColMcParticles, collision2.globalIndex()); + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, tracks1, collision2, tracks2] = *it; auto multiplicityCollision1 = 0; auto multiplicityCollision2 = 0; @@ -4276,17 +4257,17 @@ struct HfTaskFlow { continue; } - auto groupedCollisions = collisions.sliceBy(collisionPerMcCollision, collision1.globalIndex()); - - mixedEvent->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepAll); - fillCorrelationsMonteCarlo(mixedEvent, CorrelationContainer::CFStep::kCFStepAll, mcParticles, mcParticles, multiplicityCollision1, collision1.posZ(), false); - - if (groupedCollisions.size() == 0) { + auto groupedCollisions1 = collisions.sliceBy(collisionPerMcCollision, collision1.globalIndex()); + auto groupedCollisions2 = collisions.sliceBy(collisionPerMcCollision, collision2.globalIndex()); + if (groupedCollisions1.size() == 0) { + return; + } + if (groupedCollisions2.size() == 0) { return; } - mixedEvent->fillEvent(mcParticles.size(), CorrelationContainer::kCFStepTrackedOnlyPrim); - fillCorrelationsMonteCarlo(mixedEvent, CorrelationContainer::CFStep::kCFStepTrackedOnlyPrim, mcParticles, mcParticles, multiplicityCollision1, collision1.posZ(), false); + mixedEvent->fillEvent(multiplicityCollision1, CorrelationContainer::kCFStepAll); + fillCorrelationsMonteCarlo(mixedEvent, CorrelationContainer::CFStep::kCFStepAll, tracks1, tracks2, multiplicityCollision1, collision1.posZ(), false); } } PROCESS_SWITCH(HfTaskFlow, processMixedMcGen, "MC Gen : Process mixed-event correlations", false); diff --git a/PWGHF/TableProducer/candidateCreator3Prong.cxx b/PWGHF/TableProducer/candidateCreator3Prong.cxx index b7542c5bbe3..e83396da8ab 100644 --- a/PWGHF/TableProducer/candidateCreator3Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator3Prong.cxx @@ -853,7 +853,7 @@ struct HfCandidateCreator3Prong { ///////////////////////////////////////////// /// @brief process function using DCA fitter w/ PV refit and w/ centrality selection on UPC - void processPvRefitWithDCAFitterNUpc(soa::Join const& collisions, + void processPvRefitWithDCAFitterNUpc(soa::Join const& collisions, FilteredPvRefitHf3Prongs const& rowsTrackIndexProng3, TracksWCovExtraPidPiKaPrLightNuclei const& tracks, aod::BcFullInfos const& bcWithTimeStamps, @@ -867,7 +867,7 @@ struct HfCandidateCreator3Prong { PROCESS_SWITCH(HfCandidateCreator3Prong, processPvRefitWithDCAFitterNUpc, "Run candidate creator using DCA fitter with PV refit and w/ centrality selection on UPC", false); /// @brief process function using DCA fitter w/o PV refit and w/ centrality selection on UPC - void processNoPvRefitWithDCAFitterNUpc(soa::Join const& collisions, + void processNoPvRefitWithDCAFitterNUpc(soa::Join const& collisions, FilteredHf3Prongs const& rowsTrackIndexProng3, TracksWCovExtraPidPiKaPrLightNuclei const& tracks, aod::BcFullInfos const& bcWithTimeStamps, @@ -881,7 +881,7 @@ struct HfCandidateCreator3Prong { PROCESS_SWITCH(HfCandidateCreator3Prong, processNoPvRefitWithDCAFitterNUpc, "Run candidate creator using DCA fitter without PV refit and w/ centrality selection on UPC", false); /// @brief process function using KFParticle package w/ PV refit and w/ centrality selection on UPC - void processPvRefitWithKFParticleUpc(soa::Join const& collisions, + void processPvRefitWithKFParticleUpc(soa::Join const& collisions, FilteredPvRefitHf3Prongs const& rowsTrackIndexProng3, TracksWCovExtraPidPiKaPrLightNuclei const& tracks, aod::BcFullInfos const& bcWithTimeStamps, @@ -895,7 +895,7 @@ struct HfCandidateCreator3Prong { PROCESS_SWITCH(HfCandidateCreator3Prong, processPvRefitWithKFParticleUpc, "Run candidate creator using KFParticle package with PV refit and w/ centrality selection on UPC", false); /// @brief process function using KFParticle package w/o PV refit and w/ centrality selection on UPC - void processNoPvRefitWithKFParticleUpc(soa::Join const& collisions, + void processNoPvRefitWithKFParticleUpc(soa::Join const& collisions, FilteredHf3Prongs const& rowsTrackIndexProng3, TracksWCovExtraPidPiKaPrLightNuclei const& tracks, aod::BcFullInfos const& bcWithTimeStamps, @@ -1327,6 +1327,26 @@ struct HfCandidateCreator3ProngExpressions { } } } + + // cd± → de± K∓ π± + if (flagChannelMain == 0) { + auto arrPdgDaughtersCDeuteronToDeKPi{std::array{+Pdg::kDeuteron, -kKPlus, +kPiPlus}}; + if (matchKinkedDecayTopology && matchInteractionsWithMaterial) { + indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kCDeuteron, arrPdgDaughtersCDeuteronToDeKPi, true, &sign, 1, &nKinkedTracks, &nInteractionsWithMaterial); + } else if (matchKinkedDecayTopology && !matchInteractionsWithMaterial) { + indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kCDeuteron, arrPdgDaughtersCDeuteronToDeKPi, true, &sign, 1, &nKinkedTracks); + } else if (!matchKinkedDecayTopology && matchInteractionsWithMaterial) { + indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kCDeuteron, arrPdgDaughtersCDeuteronToDeKPi, true, &sign, 1, nullptr, &nInteractionsWithMaterial); + } else { + indexRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kCDeuteron, arrPdgDaughtersCDeuteronToDeKPi, true, &sign, 1); + } + if (indexRec > -1) { + flagChannelMain = static_cast(sign * DecayChannelMain::CDeuteronToDeKPi); + auto particle = mcParticles.rawIteratorAt(indexRec); + // particular treatment for c-deuteron resonant decay channels, as resonances are not stored in the stack + flagChannelResonant = hf_decay::getResonantDecayCDeuteron(particle); + } + } } // Check whether the particle is non-prompt (from a b quark). @@ -1338,6 +1358,9 @@ struct HfCandidateCreator3ProngExpressions { auto bHadMother = mcParticles.rawIteratorAt(idxBhadMothers[0]); rowMcMatchRec(flagChannelMain, origin, swapping, flagChannelResonant, bHadMother.pt(), bHadMother.pdgCode(), nKinkedTracks, nInteractionsWithMaterial); } else { + if (std::abs(flagChannelMain) == DecayChannelMain::CDeuteronToDeKPi) { + origin = RecoDecay::OriginType::Prompt; + } rowMcMatchRec(flagChannelMain, origin, swapping, flagChannelResonant, -1.f, 0, nKinkedTracks, nInteractionsWithMaterial); } } diff --git a/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx b/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx index a618360598f..5ec7bbced6b 100644 --- a/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx @@ -111,12 +111,21 @@ struct HfCandidateCreatorXicToXiPiPi { Configurable constrainXicPlusToPv{"constrainXicPlusToPv", false, "Constrain XicPlus to PV"}; Configurable kfConstructMethod{"kfConstructMethod", 2, "Construct method of XicPlus: 0 fast mathematics without constraint of fixed daughter particle masses, 2 daughter particle masses stay fixed in construction process"}; Configurable rejDiffCollTrack{"rejDiffCollTrack", true, "Reject tracks coming from different collisions (effective only for KFParticle w/o derived data)"}; + // configurables for software trigger selections + struct : ConfigurableGroup { + std::string prefix = "softtrig"; + Configurable applySoftwareTrigSelections{"applySoftwareTrigSelections", false, "Enable application of software trigger selections"}; + Configurable minDecayLength{"minDecayLength", 0.015, "Minimum decay length (computed with DCAFitter)"}; + Configurable minCosPA{"minCosPA", 0.9, "Minimum coine of pointing angle (computed with DCAFitter)"}; + Configurable maxChi2Pca{"maxChi2Pca", 3., "Maximum chi2 PCA (computed with DCAFitter)"}; + } softTrigCuts; Service ccdb{}; o2::base::MatLayerCylSet* lut{}; o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; o2::vertexing::DCAFitterN<3> df; + o2::vertexing::DCAFitterN<2> df2Prong; HfEventSelection hfEvSel; @@ -196,6 +205,66 @@ struct HfCandidateCreatorXicToXiPiPi { df.setMinRelChi2Change(minRelChi2Change); df.setUseAbsDCA(useAbsDCA); df.setWeightedFinalPCA(useWeightedFinalPCA); + + if (softTrigCuts.applySoftwareTrigSelections) { + float maxRadSoftTrig = 200.; + float maxDZIniSoftTrig = 1.e9; + float maxDXYIniSoftTrig = 4.; + float minParamChangeSoftTrig = 1.e-3; + float maxChi2SoftTrig = 0.9; + float minRelChi2ChangeSoftTrig = 0.9; + df2Prong.setPropagateToPCA(true); + df2Prong.setMaxR(maxRadSoftTrig); + df2Prong.setMaxDZIni(maxDZIniSoftTrig); + df2Prong.setMaxDXYIni(maxDXYIniSoftTrig); + df2Prong.setMinParamChange(minParamChangeSoftTrig); + df2Prong.setMinRelChi2Change(minRelChi2ChangeSoftTrig); + df2Prong.setMaxChi2(maxChi2SoftTrig); + df2Prong.setUseAbsDCA(false); + df2Prong.setWeightedFinalPCA(false); + } + } + + /// Method that reapplies the selections applied in the software trigger + /// \param pVecCascade is the cascade momentum vector + /// \param trackParBachelor is the array with two bachelor track parametrisations + /// \param collision is the collision containing the candidate + template + bool isSelectedXicSoftwareTriggers(std::array const& pVecCascade, std::array const& trackParBachelor, Coll const& collision) + { + int nCand{0}; + try { + nCand = df2Prong.process(trackParBachelor[0], trackParBachelor[1]); + } catch (...) { + LOG(error) << "Exception caught in DCA fitter process call for bachelor + bachelor in software trigger selection function!"; + return false; + } + if (nCand == 0) { + return false; + } + + const auto& vtx = df2Prong.getPCACandidate(); + if (df2Prong.getChi2AtPCACandidate() > softTrigCuts.maxChi2Pca) { + return false; + } + + std::array pVecBachFirst{}, pVecBachSecond{}; + const auto& trackBachFirstProp = df2Prong.getTrack(0); + const auto& trackBachSecondProp = df2Prong.getTrack(1); + trackBachFirstProp.getPxPyPzGlo(pVecBachFirst); + trackBachSecondProp.getPxPyPzGlo(pVecBachSecond); + auto momXiBachBach = RecoDecay::pVec(pVecCascade, pVecBachFirst, pVecBachSecond); + + std::array primVtx = {collision.posX(), collision.posY(), collision.posZ()}; + if (RecoDecay::cpa(primVtx, std::array{vtx[0], vtx[1], vtx[2]}, momXiBachBach) < softTrigCuts.minCosPA) { + return false; + } + + if (RecoDecay::distance(primVtx, vtx) < softTrigCuts.minDecayLength) { + return false; + } + + return true; } template @@ -282,6 +351,13 @@ struct HfCandidateCreatorXicToXiPiPi { auto trackParCovCharmBachelor0 = getTrackParCov(trackCharmBachelor0); auto trackParCovCharmBachelor1 = getTrackParCov(trackCharmBachelor1); + // if enabled, apply selections of software trigger + if (softTrigCuts.applySoftwareTrigSelections) { + if (!isSelectedXicSoftwareTriggers(pVecCasc, std::array{trackParCovCharmBachelor0, trackParCovCharmBachelor1}, collision)) { + continue; + } + } + // reconstruct the 3-prong secondary vertex try { if (df.process(trackCasc, trackParCovCharmBachelor0, trackParCovCharmBachelor1) == 0) { @@ -459,9 +535,20 @@ struct HfCandidateCreatorXicToXiPiPi { continue; } auto casc = cascAodElement.kfCascData_as(); + auto trackCharmBachelor0 = rowTrackIndexXicPlus.prong0_as(); auto trackCharmBachelor1 = rowTrackIndexXicPlus.prong1_as(); + // if enabled, apply selections of software trigger + if (softTrigCuts.applySoftwareTrigSelections) { + auto trackParCovCharmBachelor0 = getTrackParCov(trackCharmBachelor0); + auto trackParCovCharmBachelor1 = getTrackParCov(trackCharmBachelor1); + std::array const pVecCasc = {casc.px(), casc.py(), casc.pz()}; + if (!isSelectedXicSoftwareTriggers(pVecCasc, std::array{trackParCovCharmBachelor0, trackParCovCharmBachelor1}, collision)) { + continue; + } + } + //-------------------preselect cascade candidates-------------------------------------- if (doCascadePreselection) { if (std::abs(casc.dcaXYCascToPV()) > dcaXYToPVCascadeMax) { diff --git a/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPi.cxx b/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPi.cxx index 87856e1554a..59a17142176 100644 --- a/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorOmegac0ToOmegaPi.cxx @@ -763,6 +763,8 @@ struct HfCandidateSelectorToOmegaPi { isSelectedMlOmegac = hfMlResponse.isSelectedMl(inputFeaturesOmegaC, ptCand, outputMlOmegac); if (isSelectedMlOmegac) { registry.fill(HIST("hBDTScoreTest1"), outputMlOmegac[0]); + } else { + resultSelections = false; } hfMlSelToOmegaPi(outputMlOmegac); } diff --git a/PWGHF/TableProducer/derivedDataCreatorB0ToDPi.cxx b/PWGHF/TableProducer/derivedDataCreatorB0ToDPi.cxx index bb52685c14e..fba8b5ef210 100644 --- a/PWGHF/TableProducer/derivedDataCreatorB0ToDPi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorB0ToDPi.cxx @@ -94,6 +94,7 @@ struct HfDerivedDataCreatorB0ToDPi { SliceCache cache; static constexpr double Mass{o2::constants::physics::MassB0}; + static constexpr int NHypothesesCand{1}; // Number of possible selection hypotheses per candidate. using CollisionsWCentMult = soa::Join; using CollisionsWMcCentMult = soa::Join; @@ -139,6 +140,7 @@ struct HfDerivedDataCreatorB0ToDPi { void fillTablesCandidate(const T& candidate, const U& prongCharm, const V& prongBachelor, int candFlag, double invMass, double ct, double y, int8_t flagMc, int8_t origin, float mlScore, const std::vector& mlScoresCharm) { + LOGF(debug, "Filling candidate at derived index %d", rowsCommon.rowCandidateBase.lastIndex() + 1); rowsCommon.fillTablesCandidate(candidate, invMass, y); if (fillCandidatePar) { rowCandidatePar( @@ -249,20 +251,32 @@ struct HfDerivedDataCreatorB0ToDPi { rowsCommon.matchedCollisions.clear(); } } - auto sizeTableColl = collisions.size(); - rowsCommon.reserveTablesColl(sizeTableColl); + // const auto sizeTableColl = collisions.size(); + // rowsCommon.reserveTablesColl(sizeTableColl); + const auto sizeTableCand = candidates.size() * NHypothesesCand; + rowsCommon.reserveTablesCandidates(sizeTableCand); + reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); + reserveTable(rowCandidateParDplus, fillCandidateParDplus, sizeTableCand); + reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); + reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); + reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); + reserveTable(rowCandidateMlDplus, fillCandidateMlDplus, sizeTableCand); + reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); + if constexpr (IsMc) { + reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); + } for (const auto& collision : collisions) { - auto thisCollId = collision.globalIndex(); - auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME - auto sizeTableCand = candidatesThisColl.size(); - LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCand); + const auto thisCollId = collision.globalIndex(); + const auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME + const auto sizeTableCandThisColl = candidatesThisColl.size(); + LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCandThisColl); // Skip collisions without HF candidates (and without HF particles in matched MC collisions if saving indices of reconstructed collisions matched to MC collisions) bool mcCollisionHasMcParticles{false}; if constexpr (IsMc) { mcCollisionHasMcParticles = confDerData.fillMcRCollId && collision.has_mcCollision() && rowsCommon.hasMcParticles[collision.mcCollisionId()]; LOGF(debug, "Rec. collision %d has MC collision %d with MC particles? %s", thisCollId, collision.mcCollisionId(), mcCollisionHasMcParticles ? "yes" : "no"); } - if (sizeTableCand == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { + if (sizeTableCandThisColl == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { LOGF(debug, "Skipping rec. collision %d", thisCollId); continue; } @@ -270,17 +284,6 @@ struct HfDerivedDataCreatorB0ToDPi { rowsCommon.fillTablesCollision(collision); // Fill candidate properties - rowsCommon.reserveTablesCandidates(sizeTableCand); - reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); - reserveTable(rowCandidateParDplus, fillCandidateParDplus, sizeTableCand); - reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); - reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); - reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); - reserveTable(rowCandidateMlDplus, fillCandidateMlDplus, sizeTableCand); - reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); - if constexpr (IsMc) { - reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); - } int8_t flagMcRec = 0, origin = 0; for (const auto& candidate : candidatesThisColl) { if constexpr (IsMl) { diff --git a/PWGHF/TableProducer/derivedDataCreatorBplusToD0Pi.cxx b/PWGHF/TableProducer/derivedDataCreatorBplusToD0Pi.cxx index 5baaec8dafa..e337ec4649f 100644 --- a/PWGHF/TableProducer/derivedDataCreatorBplusToD0Pi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorBplusToD0Pi.cxx @@ -97,6 +97,7 @@ struct HfDerivedDataCreatorBplusToD0Pi { SliceCache cache; static constexpr double Mass{o2::constants::physics::MassBPlus}; + static constexpr int NHypothesesCand{1}; // Number of possible selection hypotheses per candidate. using CollisionsWCentMult = soa::Join; using CollisionsWMcCentMult = soa::Join; @@ -142,6 +143,7 @@ struct HfDerivedDataCreatorBplusToD0Pi { void fillTablesCandidate(const T& candidate, const U& prongCharm, const V& prongBachelor, int candFlag, double invMass, double ct, double y, int8_t flagMc, int8_t origin, float mlScore, const std::vector& mlScoresCharm) { + LOGF(debug, "Filling candidate at derived index %d", rowsCommon.rowCandidateBase.lastIndex() + 1); rowsCommon.fillTablesCandidate(candidate, invMass, y); if (fillCandidatePar) { rowCandidatePar( @@ -284,20 +286,33 @@ struct HfDerivedDataCreatorBplusToD0Pi { rowsCommon.matchedCollisions.clear(); } } - auto sizeTableColl = collisions.size(); - rowsCommon.reserveTablesColl(sizeTableColl); + // const auto sizeTableColl = collisions.size(); + // rowsCommon.reserveTablesColl(sizeTableColl); + const auto sizeTableCand = candidates.size() * NHypothesesCand; + rowsCommon.reserveTablesCandidates(sizeTableCand); + reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); + reserveTable(rowCandidateParD0, fillCandidateParD0, sizeTableCand); + reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); + reserveTable(rowCandidateParD0E, fillCandidateParD0E, sizeTableCand); + reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); + reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); + reserveTable(rowCandidateMlD0, fillCandidateMlD0, sizeTableCand); + reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); + if constexpr (IsMc) { + reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); + } for (const auto& collision : collisions) { - auto thisCollId = collision.globalIndex(); - auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME - auto sizeTableCand = candidatesThisColl.size(); - LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCand); + const auto thisCollId = collision.globalIndex(); + const auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME + const auto sizeTableCandThisColl = candidatesThisColl.size(); + LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCandThisColl); // Skip collisions without HF candidates (and without HF particles in matched MC collisions if saving indices of reconstructed collisions matched to MC collisions) bool mcCollisionHasMcParticles{false}; if constexpr (IsMc) { mcCollisionHasMcParticles = confDerData.fillMcRCollId && collision.has_mcCollision() && rowsCommon.hasMcParticles[collision.mcCollisionId()]; LOGF(debug, "Rec. collision %d has MC collision %d with MC particles? %s", thisCollId, collision.mcCollisionId(), mcCollisionHasMcParticles ? "yes" : "no"); } - if (sizeTableCand == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { + if (sizeTableCandThisColl == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { LOGF(debug, "Skipping rec. collision %d", thisCollId); continue; } @@ -305,18 +320,6 @@ struct HfDerivedDataCreatorBplusToD0Pi { rowsCommon.fillTablesCollision(collision); // Fill candidate properties - rowsCommon.reserveTablesCandidates(sizeTableCand); - reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); - reserveTable(rowCandidateParD0, fillCandidateParD0, sizeTableCand); - reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); - reserveTable(rowCandidateParD0E, fillCandidateParD0E, sizeTableCand); - reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); - reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); - reserveTable(rowCandidateMlD0, fillCandidateMlD0, sizeTableCand); - reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); - if constexpr (IsMc) { - reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); - } int8_t flagMcRec = 0, origin = 0; for (const auto& candidate : candidatesThisColl) { if constexpr (IsMl) { diff --git a/PWGHF/TableProducer/derivedDataCreatorD0ToKPi.cxx b/PWGHF/TableProducer/derivedDataCreatorD0ToKPi.cxx index 9041d4d7c2e..603316670a1 100644 --- a/PWGHF/TableProducer/derivedDataCreatorD0ToKPi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorD0ToKPi.cxx @@ -89,6 +89,7 @@ struct HfDerivedDataCreatorD0ToKPi { SliceCache cache; static constexpr double Mass{o2::constants::physics::MassD0}; + static constexpr int NHypothesesCand{2}; // Number of possible selection hypotheses per candidate. using CollisionsWCentMult = soa::Join; using CollisionsWMcCentMult = soa::Join; @@ -150,6 +151,7 @@ struct HfDerivedDataCreatorD0ToKPi { void fillTablesCandidate(const T& candidate, int candFlag, double invMass, double cosThetaStar, double topoChi2, double ct, double y, int8_t flagMc, int8_t origin, const std::vector& mlScores) { + LOGF(debug, "Filling candidate at derived index %d", rowsCommon.rowCandidateBase.lastIndex() + 1); rowsCommon.fillTablesCandidate(candidate, invMass, y); if (fillCandidatePar) { std::array, 2>, 2> sigmas{}; // PID nSigma [Expected][Hypothesis][TPC/TOF/TPC+TOF] @@ -248,20 +250,30 @@ struct HfDerivedDataCreatorD0ToKPi { rowsCommon.matchedCollisions.clear(); } } - auto sizeTableColl = collisions.size(); - rowsCommon.reserveTablesColl(sizeTableColl); + // const auto sizeTableColl = collisions.size(); + // rowsCommon.reserveTablesColl(sizeTableColl); + const auto sizeTableCand = candidates.size() * NHypothesesCand; + rowsCommon.reserveTablesCandidates(sizeTableCand); + reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); + reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); + reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); + reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); + reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); + if constexpr (IsMc) { + reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); + } for (const auto& collision : collisions) { - auto thisCollId = collision.globalIndex(); - auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME - auto sizeTableCand = candidatesThisColl.size(); - LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCand); + const auto thisCollId = collision.globalIndex(); + const auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME + const auto sizeTableCandThisColl = candidatesThisColl.size(); + LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCandThisColl); // Skip collisions without HF candidates (and without HF particles in matched MC collisions if saving indices of reconstructed collisions matched to MC collisions) bool mcCollisionHasMcParticles{false}; if constexpr (IsMc) { mcCollisionHasMcParticles = confDerData.fillMcRCollId && collision.has_mcCollision() && rowsCommon.hasMcParticles[collision.mcCollisionId()]; LOGF(debug, "Rec. collision %d has MC collision %d with MC particles? %s", thisCollId, collision.mcCollisionId(), mcCollisionHasMcParticles ? "yes" : "no"); } - if (sizeTableCand == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { + if (sizeTableCandThisColl == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { LOGF(debug, "Skipping rec. collision %d", thisCollId); continue; } @@ -269,15 +281,6 @@ struct HfDerivedDataCreatorD0ToKPi { rowsCommon.fillTablesCollision(collision); // Fill candidate properties - rowsCommon.reserveTablesCandidates(sizeTableCand); - reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); - reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); - reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); - reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); - reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); - if constexpr (IsMc) { - reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); - } int8_t flagMcRec = 0, origin = 0; for (const auto& candidate : candidatesThisColl) { if constexpr (IsMc) { diff --git a/PWGHF/TableProducer/derivedDataCreatorDplusToPiKPi.cxx b/PWGHF/TableProducer/derivedDataCreatorDplusToPiKPi.cxx index ddc56bfaebc..74da79ae04c 100644 --- a/PWGHF/TableProducer/derivedDataCreatorDplusToPiKPi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorDplusToPiKPi.cxx @@ -90,6 +90,7 @@ struct HfDerivedDataCreatorDplusToPiKPi { SliceCache cache; static constexpr double Mass{o2::constants::physics::MassDPlus}; + static constexpr int NHypothesesCand{1}; // Number of possible selection hypotheses per candidate. using CollisionsWCentMult = soa::Join; using CollisionsWMcCentMult = soa::Join; @@ -134,6 +135,7 @@ struct HfDerivedDataCreatorDplusToPiKPi { void fillTablesCandidate(const T& candidate, int candFlag, double invMass, double ct, double y, int8_t flagMc, int8_t origin, int8_t swapping, int8_t flagDecayChan, const std::vector& mlScores) { + LOGF(debug, "Filling candidate at derived index %d", rowsCommon.rowCandidateBase.lastIndex() + 1); rowsCommon.fillTablesCandidate(candidate, invMass, y); if (fillCandidatePar) { rowCandidatePar( @@ -246,20 +248,30 @@ struct HfDerivedDataCreatorDplusToPiKPi { rowsCommon.matchedCollisions.clear(); } } - auto sizeTableColl = collisions.size(); - rowsCommon.reserveTablesColl(sizeTableColl); + // const auto sizeTableColl = collisions.size(); + // rowsCommon.reserveTablesColl(sizeTableColl); + const auto sizeTableCand = candidates.size() * NHypothesesCand; + rowsCommon.reserveTablesCandidates(sizeTableCand); + reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); + reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); + reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); + reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); + reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); + if constexpr (IsMc) { + reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); + } for (const auto& collision : collisions) { - auto thisCollId = collision.globalIndex(); - auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME - auto sizeTableCand = candidatesThisColl.size(); - LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCand); + const auto thisCollId = collision.globalIndex(); + const auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME + const auto sizeTableCandThisColl = candidatesThisColl.size(); + LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCandThisColl); // Skip collisions without HF candidates (and without HF particles in matched MC collisions if saving indices of reconstructed collisions matched to MC collisions) bool mcCollisionHasMcParticles{false}; if constexpr (IsMc) { mcCollisionHasMcParticles = confDerData.fillMcRCollId && collision.has_mcCollision() && rowsCommon.hasMcParticles[collision.mcCollisionId()]; LOGF(debug, "Rec. collision %d has MC collision %d with MC particles? %s", thisCollId, collision.mcCollisionId(), mcCollisionHasMcParticles ? "yes" : "no"); } - if (sizeTableCand == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { + if (sizeTableCandThisColl == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { LOGF(debug, "Skipping rec. collision %d", thisCollId); continue; } @@ -267,15 +279,6 @@ struct HfDerivedDataCreatorDplusToPiKPi { rowsCommon.fillTablesCollision(collision); // Fill candidate properties - rowsCommon.reserveTablesCandidates(sizeTableCand); - reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); - reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); - reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); - reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); - reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); - if constexpr (IsMc) { - reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); - } int8_t flagMcRec = 0, origin = 0, swapping = 0, flagDecayChanRec = 0; for (const auto& candidate : candidatesThisColl) { if constexpr (IsMl) { diff --git a/PWGHF/TableProducer/derivedDataCreatorDsToKKPi.cxx b/PWGHF/TableProducer/derivedDataCreatorDsToKKPi.cxx index 587b967af0b..165dcadd758 100644 --- a/PWGHF/TableProducer/derivedDataCreatorDsToKKPi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorDsToKKPi.cxx @@ -88,6 +88,7 @@ struct HfDerivedDataCreatorDsToKKPi { SliceCache cache; static constexpr double Mass{o2::constants::physics::MassDS}; + static constexpr int NHypothesesCand{1}; // Number of possible selection hypotheses per candidate. using CollisionsWCentMult = soa::Join; using CollisionsWMcCentMult = soa::Join; @@ -132,6 +133,7 @@ struct HfDerivedDataCreatorDsToKKPi { void fillTablesCandidate(const T& candidate, int candFlag, double invMass, double ct, double y, int8_t flagMc, int8_t origin, int8_t swapping, int8_t flagDecayChan, const std::vector& mlScores) { + LOGF(debug, "Filling candidate at derived index %d", rowsCommon.rowCandidateBase.lastIndex() + 1); rowsCommon.fillTablesCandidate(candidate, invMass, y); if (fillCandidatePar) { rowCandidatePar( @@ -229,20 +231,30 @@ struct HfDerivedDataCreatorDsToKKPi { rowsCommon.matchedCollisions.clear(); } } - auto sizeTableColl = collisions.size(); - rowsCommon.reserveTablesColl(sizeTableColl); + // const auto sizeTableColl = collisions.size(); + // rowsCommon.reserveTablesColl(sizeTableColl); + const auto sizeTableCand = candidates.size() * NHypothesesCand; + rowsCommon.reserveTablesCandidates(sizeTableCand); + reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); + reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); + reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); + reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); + reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); + if constexpr (IsMc) { + reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); + } for (const auto& collision : collisions) { - auto thisCollId = collision.globalIndex(); - auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME - auto sizeTableCand = candidatesThisColl.size(); - LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCand); + const auto thisCollId = collision.globalIndex(); + const auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME + const auto sizeTableCandThisColl = candidatesThisColl.size(); + LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCandThisColl); // Skip collisions without HF candidates (and without HF particles in matched MC collisions if saving indices of reconstructed collisions matched to MC collisions) bool mcCollisionHasMcParticles{false}; if constexpr (IsMc) { mcCollisionHasMcParticles = confDerData.fillMcRCollId && collision.has_mcCollision() && rowsCommon.hasMcParticles[collision.mcCollisionId()]; LOGF(debug, "Rec. collision %d has MC collision %d with MC particles? %s", thisCollId, collision.mcCollisionId(), mcCollisionHasMcParticles ? "yes" : "no"); } - if (sizeTableCand == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { + if (sizeTableCandThisColl == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { LOGF(debug, "Skipping rec. collision %d", thisCollId); continue; } @@ -250,15 +262,6 @@ struct HfDerivedDataCreatorDsToKKPi { rowsCommon.fillTablesCollision(collision); // Fill candidate properties - rowsCommon.reserveTablesCandidates(sizeTableCand); - reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); - reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); - reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); - reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); - reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); - if constexpr (IsMc) { - reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); - } int8_t flagMcRec = 0, origin = 0, swapping = 0, flagDecayChanRec = 0; for (const auto& candidate : candidatesThisColl) { if constexpr (IsMl) { diff --git a/PWGHF/TableProducer/derivedDataCreatorDstarToD0Pi.cxx b/PWGHF/TableProducer/derivedDataCreatorDstarToD0Pi.cxx index a04dc0cf033..d2812782bde 100644 --- a/PWGHF/TableProducer/derivedDataCreatorDstarToD0Pi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorDstarToD0Pi.cxx @@ -86,6 +86,7 @@ struct HfDerivedDataCreatorDstarToD0Pi { SliceCache cache; static constexpr double Mass{o2::constants::physics::MassDStar}; + static constexpr int NHypothesesCand{1}; // Number of possible selection hypotheses per candidate. using CollisionsWCentMult = soa::Join; using CollisionsWMcCentMult = soa::Join; @@ -130,6 +131,7 @@ struct HfDerivedDataCreatorDstarToD0Pi { void fillTablesCandidate(const T& candidate, const U& prong0, const U& prong1, const U& prongSoftPi, int candFlag, double invMass, double invMassD0, double y, int8_t flagMc, int8_t flagMcD0, int8_t origin, int8_t nTracksDecayed, double ptBhad, int pdgBhad, const std::vector& mlScores) { + LOGF(debug, "Filling candidate at derived index %d", rowsCommon.rowCandidateBase.lastIndex() + 1); rowsCommon.fillTablesCandidate(candidate, invMass, y); if (fillCandidatePar) { rowCandidatePar( @@ -217,20 +219,30 @@ struct HfDerivedDataCreatorDstarToD0Pi { rowsCommon.matchedCollisions.clear(); } } - auto sizeTableColl = collisions.size(); - rowsCommon.reserveTablesColl(sizeTableColl); + // const auto sizeTableColl = collisions.size(); + // rowsCommon.reserveTablesColl(sizeTableColl); + const auto sizeTableCand = candidates.size() * NHypothesesCand; + rowsCommon.reserveTablesCandidates(sizeTableCand); + reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); + reserveTable(rowCandidateParD0, fillCandidateParD0, sizeTableCand); + reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); + reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); + reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); + if constexpr (IsMc) { + reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); + } for (const auto& collision : collisions) { - auto thisCollId = collision.globalIndex(); - auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME - auto sizeTableCand = candidatesThisColl.size(); - LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCand); + const auto thisCollId = collision.globalIndex(); + const auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME + const auto sizeTableCandThisColl = candidatesThisColl.size(); + LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCandThisColl); // Skip collisions without HF candidates (and without HF particles in matched MC collisions if saving indices of reconstructed collisions matched to MC collisions) bool mcCollisionHasMcParticles{false}; if constexpr (IsMc) { mcCollisionHasMcParticles = confDerData.fillMcRCollId && collision.has_mcCollision() && rowsCommon.hasMcParticles[collision.mcCollisionId()]; LOGF(debug, "Rec. collision %d has MC collision %d with MC particles? %s", thisCollId, collision.mcCollisionId(), mcCollisionHasMcParticles ? "yes" : "no"); } - if (sizeTableCand == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { + if (sizeTableCandThisColl == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { LOGF(debug, "Skipping rec. collision %d", thisCollId); continue; } @@ -238,15 +250,6 @@ struct HfDerivedDataCreatorDstarToD0Pi { rowsCommon.fillTablesCollision(collision); // Fill candidate properties - rowsCommon.reserveTablesCandidates(sizeTableCand); - reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); - reserveTable(rowCandidateParD0, fillCandidateParD0, sizeTableCand); - reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); - reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); - reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); - if constexpr (IsMc) { - reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); - } int8_t flagMcRec = 0, flagMcRecD0 = 0, origin = 0, nTracksDecayed = 0; double ptBhadMotherPart = 0; int pdgBhadMotherPart = 0; diff --git a/PWGHF/TableProducer/derivedDataCreatorLcToK0sP.cxx b/PWGHF/TableProducer/derivedDataCreatorLcToK0sP.cxx index 371b9ab9c4c..3f6a0b77fdb 100644 --- a/PWGHF/TableProducer/derivedDataCreatorLcToK0sP.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorLcToK0sP.cxx @@ -88,6 +88,7 @@ struct HfDerivedDataCreatorLcToK0sP { SliceCache cache; static constexpr double Mass{o2::constants::physics::MassLambdaCPlus}; + static constexpr int NHypothesesCand{1}; // Number of possible selection hypotheses per candidate. using CollisionsWCentMult = soa::Join; using CollisionsWMcCentMult = soa::Join; @@ -132,6 +133,7 @@ struct HfDerivedDataCreatorLcToK0sP { void fillTablesCandidate(const T& candidate, const U& bach, int candFlag, double invMass, double ct, double ctV0, double y, int8_t flagMc, int8_t origin, const std::vector& mlScores) { + LOGF(debug, "Filling candidate at derived index %d", rowsCommon.rowCandidateBase.lastIndex() + 1); rowsCommon.fillTablesCandidate(candidate, invMass, y); if (fillCandidatePar) { rowCandidatePar( @@ -220,20 +222,30 @@ struct HfDerivedDataCreatorLcToK0sP { rowsCommon.matchedCollisions.clear(); } } - auto sizeTableColl = collisions.size(); - rowsCommon.reserveTablesColl(sizeTableColl); + // const auto sizeTableColl = collisions.size(); + // rowsCommon.reserveTablesColl(sizeTableColl); + const auto sizeTableCand = candidates.size() * NHypothesesCand; + rowsCommon.reserveTablesCandidates(sizeTableCand); + reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); + reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); + reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); + reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); + reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); + if constexpr (IsMc) { + reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); + } for (const auto& collision : collisions) { - auto thisCollId = collision.globalIndex(); - auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME - auto sizeTableCand = candidatesThisColl.size(); - LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCand); + const auto thisCollId = collision.globalIndex(); + const auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME + const auto sizeTableCandThisColl = candidatesThisColl.size(); + LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCandThisColl); // Skip collisions without HF candidates (and without HF particles in matched MC collisions if saving indices of reconstructed collisions matched to MC collisions) bool mcCollisionHasMcParticles{false}; if constexpr (IsMc) { mcCollisionHasMcParticles = confDerData.fillMcRCollId && collision.has_mcCollision() && rowsCommon.hasMcParticles[collision.mcCollisionId()]; LOGF(debug, "Rec. collision %d has MC collision %d with MC particles? %s", thisCollId, collision.mcCollisionId(), mcCollisionHasMcParticles ? "yes" : "no"); } - if (sizeTableCand == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { + if (sizeTableCandThisColl == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { LOGF(debug, "Skipping rec. collision %d", thisCollId); continue; } @@ -241,15 +253,6 @@ struct HfDerivedDataCreatorLcToK0sP { rowsCommon.fillTablesCollision(collision); // Fill candidate properties - rowsCommon.reserveTablesCandidates(sizeTableCand); - reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); - reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); - reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); - reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); - reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); - if constexpr (IsMc) { - reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); - } int8_t flagMcRec = 0, origin = 0; for (const auto& candidate : candidatesThisColl) { if constexpr (IsMc) { diff --git a/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx b/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx index efecd6f6713..7b37995e3a3 100644 --- a/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx @@ -88,6 +88,7 @@ struct HfDerivedDataCreatorLcToPKPi { SliceCache cache; static constexpr double Mass{o2::constants::physics::MassLambdaCPlus}; + static constexpr int NHypothesesCand{2}; // Number of possible selection hypotheses per candidate. using CollisionsWCentMult = soa::Join; using CollisionsWMcCentMult = soa::Join; @@ -132,6 +133,7 @@ struct HfDerivedDataCreatorLcToPKPi { void fillTablesCandidate(const T& candidate, int candFlag, double invMass, double ct, double y, int8_t flagMc, int8_t origin, int8_t swapping, const std::vector& mlScores) { + LOGF(debug, "Filling candidate at derived index %d", rowsCommon.rowCandidateBase.lastIndex() + 1); rowsCommon.fillTablesCandidate(candidate, invMass, y); if (fillCandidatePar) { rowCandidatePar( @@ -228,20 +230,30 @@ struct HfDerivedDataCreatorLcToPKPi { rowsCommon.matchedCollisions.clear(); } } - auto sizeTableColl = collisions.size(); - rowsCommon.reserveTablesColl(sizeTableColl); + // const auto sizeTableColl = collisions.size(); + // rowsCommon.reserveTablesColl(sizeTableColl); + const auto sizeTableCand = candidates.size() * NHypothesesCand; + rowsCommon.reserveTablesCandidates(sizeTableCand); + reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); + reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); + reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); + reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); + reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); + if constexpr (IsMc) { + reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); + } for (const auto& collision : collisions) { - auto thisCollId = collision.globalIndex(); - auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME - auto sizeTableCand = candidatesThisColl.size(); - LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCand); + const auto thisCollId = collision.globalIndex(); + const auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME + const auto sizeTableCandThisColl = candidatesThisColl.size(); + LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCandThisColl); // Skip collisions without HF candidates (and without HF particles in matched MC collisions if saving indices of reconstructed collisions matched to MC collisions) bool mcCollisionHasMcParticles{false}; if constexpr (IsMc) { mcCollisionHasMcParticles = confDerData.fillMcRCollId && collision.has_mcCollision() && rowsCommon.hasMcParticles[collision.mcCollisionId()]; LOGF(debug, "Rec. collision %d has MC collision %d with MC particles? %s", thisCollId, collision.mcCollisionId(), mcCollisionHasMcParticles ? "yes" : "no"); } - if (sizeTableCand == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { + if (sizeTableCandThisColl == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { LOGF(debug, "Skipping rec. collision %d", thisCollId); continue; } @@ -249,15 +261,6 @@ struct HfDerivedDataCreatorLcToPKPi { rowsCommon.fillTablesCollision(collision); // Fill candidate properties - rowsCommon.reserveTablesCandidates(sizeTableCand); - reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); - reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); - reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); - reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); - reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); - if constexpr (IsMc) { - reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); - } int8_t flagMcRec = 0, origin = 0, swapping = 0; for (const auto& candidate : candidatesThisColl) { if constexpr (IsMc) { diff --git a/PWGHF/TableProducer/derivedDataCreatorXicToXiPiPi.cxx b/PWGHF/TableProducer/derivedDataCreatorXicToXiPiPi.cxx index 9e0529b97d6..fdce0301529 100644 --- a/PWGHF/TableProducer/derivedDataCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorXicToXiPiPi.cxx @@ -89,6 +89,7 @@ struct HfDerivedDataCreatorXicToXiPiPi { SliceCache cache; static constexpr double Mass{o2::constants::physics::MassXiCPlus}; + static constexpr int NHypothesesCand{1}; // Number of possible selection hypotheses per candidate. using CollisionsWCentMult = soa::Join; using CollisionsWMcCentMult = soa::Join; @@ -134,6 +135,7 @@ struct HfDerivedDataCreatorXicToXiPiPi { void fillTablesCandidate(const T& candidate, int candFlag, double invMass, double ct, double y, int8_t flagMc, int8_t origin, const std::vector& mlScores) { + LOGF(debug, "Filling candidate at derived index %d", rowsCommon.rowCandidateBase.lastIndex() + 1); rowsCommon.fillTablesCandidate(candidate, invMass, y); if (fillCandidatePar) { rowCandidatePar( @@ -228,20 +230,30 @@ struct HfDerivedDataCreatorXicToXiPiPi { rowsCommon.matchedCollisions.clear(); } } - auto sizeTableColl = collisions.size(); - rowsCommon.reserveTablesColl(sizeTableColl); + // const auto sizeTableColl = collisions.size(); + // rowsCommon.reserveTablesColl(sizeTableColl); + const auto sizeTableCand = candidates.size() * NHypothesesCand; + rowsCommon.reserveTablesCandidates(sizeTableCand); + reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); + reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); + reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); + reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); + reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); + if constexpr (IsMc) { + reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); + } for (const auto& collision : collisions) { - auto thisCollId = collision.globalIndex(); - auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME - auto sizeTableCand = candidatesThisColl.size(); - LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCand); + const auto thisCollId = collision.globalIndex(); + const auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME + const auto sizeTableCandThisColl = candidatesThisColl.size(); + LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCandThisColl); // Skip collisions without HF candidates (and without HF particles in matched MC collisions if saving indices of reconstructed collisions matched to MC collisions) bool mcCollisionHasMcParticles{false}; if constexpr (IsMc) { mcCollisionHasMcParticles = confDerData.fillMcRCollId && collision.has_mcCollision() && rowsCommon.hasMcParticles[collision.mcCollisionId()]; LOGF(debug, "Rec. collision %d has MC collision %d with MC particles? %s", thisCollId, collision.mcCollisionId(), mcCollisionHasMcParticles ? "yes" : "no"); } - if (sizeTableCand == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { + if (sizeTableCandThisColl == 0 && (!confDerData.fillMcRCollId || !mcCollisionHasMcParticles)) { LOGF(debug, "Skipping rec. collision %d", thisCollId); continue; } @@ -249,15 +261,6 @@ struct HfDerivedDataCreatorXicToXiPiPi { rowsCommon.fillTablesCollision(collision); // Fill candidate properties - rowsCommon.reserveTablesCandidates(sizeTableCand); - reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); - reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); - reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); - reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); - reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); - if constexpr (IsMc) { - reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); - } int8_t flagMcRec = 0, origin = 0; for (const auto& candidate : candidatesThisColl) { if constexpr (IsMl) { diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index f3e3054e4b5..50a4e70c80f 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -83,6 +83,7 @@ #include #include // std::distance #include +#include #include // std::string #include // std::forward #include // std::vector @@ -1693,6 +1694,9 @@ struct HfTrackIndexSkimCreator { const std::vector ptBinsMl{0., 1.e10}; const std::vector cutDirMl{o2::cuts_ml::CutDirection::CutGreater, o2::cuts_ml::CutDirection::CutSmaller, o2::cuts_ml::CutDirection::CutSmaller}; const std::array, kN3ProngDecaysUsedMlForHfFilters> thresholdMlScore3Prongs{config.thresholdMlScoreDplusToPiKPi, config.thresholdMlScoreLcToPiKP, config.thresholdMlScoreDsToPiKK, config.thresholdMlScoreXicToPiKP}; + const std::vector inputFeatures2Prongs = {"ptProng0", "dcaXyProng0", "dcaZProng0", "ptProng1", "dcaXyProng1", "dcaZProng1"}; + const std::vector inputFeatures3Prongs = {"ptProng0", "dcaXyProng0", "dcaZProng0", "ptProng1", "dcaXyProng1", "dcaZProng1", "ptProng2", "dcaXyProng2", "dcaZProng2"}; + const std::vector inputFeatures3ProngsWithPid = {"ptProng0", "dcaXyProng0", "dcaZProng0", "ptProng1", "dcaXyProng1", "dcaZProng1", "ptProng2", "dcaXyProng2", "dcaZProng2", "tpcNSigmaPrProng0", "tpcNSigmaPrProng2", "tpcNSigmaPiProng0", "tpcNSigmaPiProng2", "tpcNSigmaKaProng1"}; // initialise 2-prong ML response hfMlResponse2Prongs.configure(ptBinsMl, config.thresholdMlScoreD0ToKPi, cutDirMl, 3); @@ -1702,6 +1706,7 @@ struct HfTrackIndexSkimCreator { } else { hfMlResponse2Prongs.setModelPathsLocal(onnxFileNames2Prongs); } + hfMlResponse2Prongs.cacheInputFeaturesIndices(inputFeatures2Prongs); hfMlResponse2Prongs.init(); // initialise 3-prong ML responses @@ -1717,6 +1722,11 @@ struct HfTrackIndexSkimCreator { } else { hfMlResponse3Prongs[iDecay3P].setModelPathsLocal(onnxFileNames3Prongs[iDecay3P]); } + if ((doprocess2And3ProngsWithPvRefitWithPidForHfFiltersBdt || doprocess2And3ProngsNoPvRefitWithPidForHfFiltersBdt) && iDecay3P == aod::hf_cand_3prong::DecayType::LcToPKPi) { + hfMlResponse3Prongs[iDecay3P].cacheInputFeaturesIndices(inputFeatures3ProngsWithPid); + } else { + hfMlResponse3Prongs[iDecay3P].cacheInputFeaturesIndices(inputFeatures3Prongs); + } hfMlResponse3Prongs[iDecay3P].init(); } } @@ -2391,6 +2401,9 @@ struct HfTrackIndexSkimCreator { // first loop over positive tracks const auto groupedTrackIndicesPos1 = positiveFor2And3Prongs->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + const auto groupedTrackIndicesNeg1 = negativeFor2And3Prongs->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + std::optionalsliceByCached(aod::track::collisionId, 0, cache))> groupedTrackIndicesSoftPionsPos; + std::optionalsliceByCached(aod::track::collisionId, 0, cache))> groupedTrackIndicesSoftPionsNeg; int lastFilledD0 = -1; // index to be filled in table for D* mesons for (auto trackIndexPos1 = groupedTrackIndicesPos1.begin(); trackIndexPos1 != groupedTrackIndicesPos1.end(); ++trackIndexPos1) { const auto trackPos1 = trackIndexPos1.template track_as(); @@ -2409,7 +2422,6 @@ struct HfTrackIndexSkimCreator { } // first loop over negative tracks - const auto groupedTrackIndicesNeg1 = negativeFor2And3Prongs->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); for (auto trackIndexNeg1 = groupedTrackIndicesNeg1.begin(); trackIndexNeg1 != groupedTrackIndicesNeg1.end(); ++trackIndexNeg1) { const auto trackNeg1 = trackIndexNeg1.template track_as(); @@ -3189,8 +3201,10 @@ struct HfTrackIndexSkimCreator { // if D* enabled and pt of the D0 is larger than the minimum of the D* one within 20% (D* and D0 momenta are very similar, always within 20% according to PYTHIA8) // second loop over positive tracks if (TESTBIT(whichHypo2Prong[kN2ProngDecays], 0) && (!config.applyKaonPidIn3Prongs || TESTBIT(trackIndexNeg1.isIdentifiedPid(), ChannelKaonPid))) { // only for D0 candidates; moreover if kaon PID enabled, apply to the negative track - auto groupedTrackIndicesSoftPionsPos = positiveSoftPions->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - for (auto trackIndexPos2 = groupedTrackIndicesSoftPionsPos.begin(); trackIndexPos2 != groupedTrackIndicesSoftPionsPos.end(); ++trackIndexPos2) { + if (!groupedTrackIndicesSoftPionsPos) { + groupedTrackIndicesSoftPionsPos.emplace(positiveSoftPions->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache)); + } + for (auto trackIndexPos2 = groupedTrackIndicesSoftPionsPos->begin(); trackIndexPos2 != groupedTrackIndicesSoftPionsPos->end(); ++trackIndexPos2) { if (trackIndexPos2 == trackIndexPos1) { continue; } @@ -3226,8 +3240,10 @@ struct HfTrackIndexSkimCreator { // second loop over negative tracks if (TESTBIT(whichHypo2Prong[kN2ProngDecays], 1) && (!config.applyKaonPidIn3Prongs || TESTBIT(trackIndexPos1.isIdentifiedPid(), ChannelKaonPid))) { // only for D0bar candidates; moreover if kaon PID enabled, apply to the positive track - auto groupedTrackIndicesSoftPionsNeg = negativeSoftPions->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - for (auto trackIndexNeg2 = groupedTrackIndicesSoftPionsNeg.begin(); trackIndexNeg2 != groupedTrackIndicesSoftPionsNeg.end(); ++trackIndexNeg2) { + if (!groupedTrackIndicesSoftPionsNeg) { + groupedTrackIndicesSoftPionsNeg.emplace(negativeSoftPions->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache)); + } + for (auto trackIndexNeg2 = groupedTrackIndicesSoftPionsNeg->begin(); trackIndexNeg2 != groupedTrackIndicesSoftPionsNeg->end(); ++trackIndexNeg2) { if (trackIndexNeg1 == trackIndexNeg2) { continue; } @@ -3453,7 +3469,7 @@ struct HfTrackIndexSkimCreatorCascades { void processCascades(SelectedCollisions const& collisions, soa::Join const& v0s, FilteredTrackAssocSel const& trackIndices, - aod::TracksWCovDcaExtra const&, + aod::TracksWCovDca const&, aod::BCsWithTimestamps const&) { // set the magnetic field from CCDB @@ -3472,7 +3488,7 @@ struct HfTrackIndexSkimCreatorCascades { // fist we loop over the bachelor candidate for (const auto& bachIdx : groupedBachTrackIndices) { - const auto bach = bachIdx.track_as(); + const auto bach = bachIdx.track_as(); std::array pVecBach{bach.pVector()}; auto trackBach = getTrackParCov(bach); if (thisCollId != bach.collisionId()) { // this is not the "default" collision for this track, we have to re-propagate it @@ -3484,8 +3500,8 @@ struct HfTrackIndexSkimCreatorCascades { // now we loop over the V0s for (const auto& v0 : groupedV0s) { // selections on the V0 daughters - const auto& trackV0DaughPos = v0.posTrack_as(); // only used for indices and track cuts (TPC clusters, TPC refit) - const auto& trackV0DaughNeg = v0.negTrack_as(); // only used for indices and track cuts (TPC clusters, TPC refit) + const auto& trackV0DaughPos = v0.posTrack_as(); // only the global index is read here; track-quality cuts are applied upstream in tag-sel-tracks + const auto& trackV0DaughNeg = v0.negTrack_as(); // only the global index is read here; track-quality cuts are applied upstream in tag-sel-tracks // check not to take the same track twice (as bachelor and V0 daughter) if (trackV0DaughPos.globalIndex() == bach.globalIndex() || trackV0DaughNeg.globalIndex() == bach.globalIndex()) { diff --git a/PWGHF/TableProducer/treeCreatorD0ToKPi.cxx b/PWGHF/TableProducer/treeCreatorD0ToKPi.cxx index 36316355fad..9b8a49abc58 100644 --- a/PWGHF/TableProducer/treeCreatorD0ToKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorD0ToKPi.cxx @@ -423,12 +423,14 @@ struct HfTreeCreatorD0ToKPi { // Filling candidate properties if (fillCandidateLiteTable) { - rowCandidateLite.reserve(candidates.size()); + // Account for candidates passing both D0 and D0bar + // selection, which will be stored twice in the lite table + rowCandidateLite.reserve(candidates.size() * 2); } else { - rowCandidateFull.reserve(candidates.size()); + rowCandidateFull.reserve(candidates.size() * 2); } if constexpr (ApplyMl) { - rowCandidateMl.reserve(candidates.size()); + rowCandidateMl.reserve(candidates.size() * 2); } for (const auto& candidate : candidates) { if (downSampleBkgFactor < 1.) { @@ -511,12 +513,12 @@ struct HfTreeCreatorD0ToKPi { // Filling candidate properties if (fillCandidateLiteTable) { - rowCandidateLite.reserve(candidates.size()); + rowCandidateLite.reserve(candidates.size() * 2); } else { - rowCandidateFull.reserve(candidates.size()); + rowCandidateFull.reserve(candidates.size() * 2); } if constexpr (ApplyMl) { - rowCandidateMl.reserve(candidates.size()); + rowCandidateMl.reserve(candidates.size() * 2); } for (const auto& candidate : candidates) { if constexpr (OnlyBkg) { diff --git a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx index 8a952cbea49..62d03a71615 100644 --- a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx +++ b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx @@ -366,6 +366,9 @@ struct HfTreeCreatorOmegacSt { { mapMcPartToGenTable.clear(); for (const auto& mcParticle : mcParticles) { + origin = 0; + idxBhadMothers.clear(); + decayChannel = -1; const bool isOmegaC = std::abs(mcParticle.pdgCode()) == constants::physics::Pdg::kOmegaC0; const bool isXiC = std::abs(mcParticle.pdgCode()) == constants::physics::Pdg::kXiC0; if (!isOmegaC && !isXiC) { @@ -397,7 +400,6 @@ struct HfTreeCreatorOmegacSt { continue; } - int decayChannel = -1; const int pdgCasc = std::abs(mcParticles.iteratorAt(idxCascDaughter).pdgCode()); if (isOmegaC) { @@ -716,6 +718,11 @@ struct HfTreeCreatorOmegacSt { //--- do the MC Rec match if (mcParticles) { + isMatched = false; + origin = 0; + idxBhadMothers.clear(); + indexRecCharmBaryon = -1; + indexRec = -1; auto arrayDaughters = std::array{ trackId.template track_as(), // bachelor <- charm baryon casc.bachelor_as(), // bachelor <- cascade diff --git a/PWGHF/TableProducer/treeCreatorToXiPiQa.cxx b/PWGHF/TableProducer/treeCreatorToXiPiQa.cxx index 9fb1a50a305..a4c8f7e16db 100644 --- a/PWGHF/TableProducer/treeCreatorToXiPiQa.cxx +++ b/PWGHF/TableProducer/treeCreatorToXiPiQa.cxx @@ -36,6 +36,8 @@ #include #include +#include + #include using namespace o2; @@ -219,9 +221,10 @@ DECLARE_SOA_COLUMN(MassV0Chi2OverNdf, massV0Chi2OverNdf, float); DECLARE_SOA_COLUMN(MassCascChi2OverNdf, massCascChi2OverNdf, float); // MC DECLARE_SOA_COLUMN(ParticlePdg, particlePdg, int); +DECLARE_SOA_COLUMN(PtGenB, ptGenB, float); DECLARE_SOA_COLUMN(NContribMax, nContribMax, int); DECLARE_SOA_COLUMN(NRecoColl, nRecoColl, int); -DECLARE_SOA_COLUMN(PtGenB, ptGenB, float); +DECLARE_SOA_COLUMN(IsXic0WithRecoCollSel8, isXic0WithRecoCollSel8, bool); } // namespace full DECLARE_SOA_TABLE(HfToXiPiEvs, "AOD", "HFTOXIPIEV", @@ -322,9 +325,11 @@ DECLARE_SOA_TABLE(HfCandToXiPiGen, "AOD", "HFCANDTOXIPIGEN", full::FlagMcMatchRec, full::OriginRec, full::ParticlePdg, + full::PtGenB, full::NContribMax, full::NRecoColl, - full::PtGenB) + full::IsXic0WithRecoCollSel8); + } // namespace o2::aod /// Writes the full information in an output TTree @@ -660,10 +665,14 @@ struct HfTreeCreatorToXiPiQa { auto yGen = particle.rapidityCharmBaryonGen(); int nContribMax = 0; + bool recoCollPassedSel8 = false; auto mcCollision = particle.template mcCollision_as(); const auto& recoCollsPerMcColl = collisions.sliceBy(colPerMcCollision, mcCollision.globalIndex()); for (const auto& recoCol : recoCollsPerMcColl) { nContribMax = recoCol.numContrib() > nContribMax ? recoCol.numContrib() : nContribMax; + if (recoCol.sel8()) { + recoCollPassedSel8 = true; + } } float ptGenBhad = (particle.originMcGen() == RecoDecay::OriginType::NonPrompt) ? mcParticles.rawIteratorAt(particle.idxBhadMotherPart()).pt() : -999.f; @@ -676,9 +685,10 @@ struct HfTreeCreatorToXiPiQa { particle.flagMcMatchGen(), particle.originMcGen(), particle.pdgCode(), + ptGenBhad, nContribMax, recoCollsPerMcColl.size(), - ptGenBhad); + recoCollPassedSel8); } } diff --git a/PWGHF/Utils/utilsDerivedData.h b/PWGHF/Utils/utilsDerivedData.h index 8b2b4fd431a..f2b63291665 100644 --- a/PWGHF/Utils/utilsDerivedData.h +++ b/PWGHF/Utils/utilsDerivedData.h @@ -230,16 +230,18 @@ struct HfProducesDerivedData : o2::framework::ProducesGroup { const TMass massParticle) { // Fill MC collision properties - const auto sizeTableMcColl = mcCollisions.size(); - reserveTablesMcColl(sizeTableMcColl); + // const auto sizeTableMcColl = mcCollisions.size(); + // reserveTablesMcColl(sizeTableMcColl); + const auto sizeTablePart = mcParticles.size(); + reserveTablesParticles(sizeTablePart); for (const auto& mcCollision : mcCollisions) { const auto thisMcCollId = mcCollision.globalIndex(); const auto particlesThisMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, thisMcCollId); - const auto sizeTablePart = particlesThisMcColl.size(); - LOGF(debug, "MC collision %d has %d MC particles", thisMcCollId, sizeTablePart); + const auto sizeTablePartThisColl = particlesThisMcColl.size(); + LOGF(debug, "MC collision %d has %d MC particles", thisMcCollId, sizeTablePartThisColl); // Skip MC collisions without HF particles (and without HF candidates in matched reconstructed collisions if saving indices of reconstructed collisions matched to MC collisions) LOGF(debug, "MC collision %d has %d saved derived rec. collisions", thisMcCollId, matchedCollisions[thisMcCollId].size()); - if (sizeTablePart == 0 && (!conf->fillMcRCollId.value || matchedCollisions[thisMcCollId].empty())) { + if (sizeTablePartThisColl == 0 && (!conf->fillMcRCollId.value || matchedCollisions[thisMcCollId].empty())) { LOGF(debug, "Skipping MC collision %d", thisMcCollId); continue; } @@ -247,7 +249,6 @@ struct HfProducesDerivedData : o2::framework::ProducesGroup { fillTablesMcCollision(mcCollision); // Fill MC particle properties - reserveTablesParticles(sizeTablePart); for (const auto& particle : particlesThisMcColl) { fillTablesParticle(particle, massParticle); } diff --git a/PWGHF/Utils/utilsMcGen.h b/PWGHF/Utils/utilsMcGen.h index 18734c1e96a..87697009a3c 100644 --- a/PWGHF/Utils/utilsMcGen.h +++ b/PWGHF/Utils/utilsMcGen.h @@ -202,7 +202,7 @@ void fillMcMatchGen3Prong(TMcParticles const& mcParticles, if (std::abs(pdgMother) == Pdg::kDStar) { std::vector arrResoDaughIndexDStar = {}; RecoDecay::getDaughters(particle, &arrResoDaughIndexDStar, std::array{0}, DepthResoMax); - for (const int iDaug : arrResoDaughIndexDStar) { + for (const int iDaug : arrResoDaughIndexDStar) { // o2-linter: disable=const-ref-in-for-loop (not necessary for int type) auto daughDstar = mcParticles.rawIteratorAt(iDaug); if (std::abs(daughDstar.pdgCode()) == Pdg::kD0 || std::abs(daughDstar.pdgCode()) == Pdg::kDPlus) { RecoDecay::getDaughters(daughDstar, &arrResoDaughIndex, std::array{0}, DepthResoMax); @@ -301,6 +301,14 @@ void fillMcMatchGen3Prong(TMcParticles const& mcParticles, flagChannelMain = sign * DecayChannelMain::XicToPKPi; } } + + // cd± → de± K∓ π± + if (flagChannelMain == 0) { + if (RecoDecay::isMatchedMCGen(mcParticles, particle, Pdg::kCDeuteron, std::array{+Pdg::kDeuteron, -kKPlus, +kPiPlus}, true, &sign, 1)) { + flagChannelMain = sign * DecayChannelMain::CDeuteronToDeKPi; + flagChannelResonant = o2::hf_decay::getResonantDecayCDeuteron(particle); + } + } } // Check whether the particle is non-prompt (from a b quark). diff --git a/PWGHF/Utils/utilsMcMatching.h b/PWGHF/Utils/utilsMcMatching.h index 097c13a901e..d4989053dd7 100644 --- a/PWGHF/Utils/utilsMcMatching.h +++ b/PWGHF/Utils/utilsMcMatching.h @@ -154,6 +154,16 @@ static const std::unordered_map> {DecayChannelResonant::XicToPPhi, {+PDG_t::kProton, +o2::constants::physics::Pdg::kPhi}}, }; +// cd+ + +static const std::unordered_map> daughtersCDeuteronMain{ + {DecayChannelMain::CDeuteronToDeKPi, {+o2::constants::physics::Pdg::kDeuteron, +PDG_t::kKMinus, +PDG_t::kPiPlus}}}; + +/// resonances in c-deuteron decay are not stored in the particle stack for c-deuteron, but tagged with specific status codes +static constexpr std::array statusCodeCDeuteronToDeKstar0{-85, -95}; +static constexpr std::array statusCodeCDeuteronToNeDeltaplusK{-86, -96}; +static constexpr std::array statusCodeCDeuteronToNeL1520Pi{-87, -97}; + /// Returns a map of the possible final states for a specific 3-prong particle specie /// \param pdgMother PDG code of the mother particle /// \return a map of final states with their corresponding PDG codes @@ -170,6 +180,8 @@ inline std::unordered_map> getDecayChan return daughtersLcMain; case o2::constants::physics::Pdg::kXiCPlus: return daughtersXicMain; + case o2::constants::physics::Pdg::kCDeuteron: + return daughtersCDeuteronMain; default: LOG(fatal) << "Unknown PDG code for 3-prong final states: " << pdgMother; return {}; @@ -317,6 +329,27 @@ inline void flipPdgSign(const int pdgMother, const int pdgToFlip, std::array +inline int getResonantDecayCDeuteron(Part const& particle) +{ + auto statusCode = particle.getGenStatusCode(); + if (statusCode == o2::hf_decay::hf_cand_3prong::statusCodeCDeuteronToDeKstar0[0] || statusCode == o2::hf_decay::hf_cand_3prong::statusCodeCDeuteronToDeKstar0[1]) { + return o2::hf_decay::hf_cand_3prong::DecayChannelResonant::CDeuteronToDeKstar0; + } + if (statusCode == o2::hf_decay::hf_cand_3prong::statusCodeCDeuteronToNeDeltaplusK[0] || statusCode == o2::hf_decay::hf_cand_3prong::statusCodeCDeuteronToNeDeltaplusK[1]) { + return o2::hf_decay::hf_cand_3prong::DecayChannelResonant::CDeuteronToNeDeltaplusK; + } + if (statusCode == o2::hf_decay::hf_cand_3prong::statusCodeCDeuteronToNeL1520Pi[0] || statusCode == o2::hf_decay::hf_cand_3prong::statusCodeCDeuteronToNeL1520Pi[1]) { + return o2::hf_decay::hf_cand_3prong::DecayChannelResonant::CDeuteronToNeL1520Pi; + } + return 0; +} } // namespace o2::hf_decay #endif // PWGHF_UTILS_UTILSMCMATCHING_H_ diff --git a/PWGJE/Core/CMakeLists.txt b/PWGJE/Core/CMakeLists.txt index b6ccafb2be2..a7713c9900d 100644 --- a/PWGJE/Core/CMakeLists.txt +++ b/PWGJE/Core/CMakeLists.txt @@ -23,7 +23,6 @@ o2physics_target_root_dictionary(PWGJECore FastJetUtilities.h JetTaggingUtilities.h JetBkgSubUtils.h - JetDerivedDataUtilities.h emcalCrossTalkEmulation.h utilsTrackMatchingEMC.h LINKDEF PWGJECoreLinkDef.h) diff --git a/PWGJE/TableProducer/CMakeLists.txt b/PWGJE/TableProducer/CMakeLists.txt index 3e7510f56b9..1c24d632022 100644 --- a/PWGJE/TableProducer/CMakeLists.txt +++ b/PWGJE/TableProducer/CMakeLists.txt @@ -110,3 +110,8 @@ o2physics_add_dpl_workflow(slim-tables-producer SOURCES slimTablesProducer.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(diff-wake-tree-producer + SOURCES diffWakeTreeProducer.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGJE/TableProducer/diffWakeTreeProducer.cxx b/PWGJE/TableProducer/diffWakeTreeProducer.cxx new file mode 100644 index 00000000000..bad79ec1889 --- /dev/null +++ b/PWGJE/TableProducer/diffWakeTreeProducer.cxx @@ -0,0 +1,292 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file diffWakeTreeProducer.cxx +/// \brief This task writes a collision and track table which are further used in a diffusion wake analysis +/// \authors Nicola Wilson and Nicolas Wirth + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/Core/EventPlaneHelper.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/Qvectors.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// Event selection: Only events that contain track above some threshold +// ------------------------------------------------------------------------------------------- +// TRACK DATA +// ------------------------------------------------------------------------------------------- +// BEFORE COMPRESSION AFTER COMPRESSION +// Name Data Type Size(b) Name Data Type Size(b) +// ColID int32_t 4 [same] +// Charge short 2 [same] +// Px, Py, Pz float 3x4 P unsigned long 8 +// DEdx float 4 DEdx unsigned short 2 +// DCAXY float 4 DCAXY short 2 +// DCAZ float 4 DCAZ short 2 +// Length float 4 Length unsigned short 2 + +// OVERALL COMPRESSION 34b->22b + +// ------------------------------------------------------------------------------------------- +// EVENT DATA +// ------------------------------------------------------------------------------------------- +// GI int64_t 8 [same] +// RN int 4 [same] +// Cent float 4 [same] +// Mult int 4 [same] +// VertexX float 4 [same] +// VertexY float 4 [same] +// VertexZ float 4 [same] +// Psi2 float 4 Psi2 short 2 +// Psi3 float 4 Psi3 short 2 + +// OVERALL COMPRESSION 40b->36b +//-------------------------------------------------------- +namespace o2::aod +{ +namespace testcol +{ +// Event properties +DECLARE_SOA_COLUMN(Rn, rn, int32_t); // run number +DECLARE_SOA_COLUMN(Cent, cent, float); // FT0C centrality +DECLARE_SOA_COLUMN(Mult, mult, int32_t); // TPC multiplicity +DECLARE_SOA_COLUMN(Occu, occu, int32_t); // Occupancy ITS +DECLARE_SOA_COLUMN(Occuft0, occuft0, float); // Occupancy FT0C amplitudes +DECLARE_SOA_COLUMN(VertexX, vertexX, float); +DECLARE_SOA_COLUMN(VertexY, vertexY, float); +DECLARE_SOA_COLUMN(VertexZ, vertexZ, float); +DECLARE_SOA_COLUMN(Psi2, psi2, int16_t); +DECLARE_SOA_COLUMN(Psi3, psi3, int16_t); +} // namespace testcol + +DECLARE_SOA_TABLE(TableCols, "AOD", "TABLECOL", + o2::soa::Index<>, + testcol::Rn, + testcol::Cent, + testcol::Mult, + testcol::Occu, + testcol::Occuft0, + testcol::VertexX, + testcol::VertexY, + testcol::VertexZ, + testcol::Psi2, + testcol::Psi3); +using TableCol = TableCols::iterator; + +namespace testtrack +{ + +// Track properties +DECLARE_SOA_INDEX_COLUMN(TableCol, tableCol); +DECLARE_SOA_COLUMN(Charge, charge, int16_t); +DECLARE_SOA_COLUMN(P, p, uint64_t); +DECLARE_SOA_COLUMN(Dedx, dedx, uint16_t); +DECLARE_SOA_COLUMN(Dcaxy, dcaxy, int16_t); +DECLARE_SOA_COLUMN(Dcaz, dcaz, int16_t); +} // namespace testtrack + +DECLARE_SOA_TABLE(TableTrack, "AOD", "TABLETRACK", + testtrack::TableColId, + testtrack::Charge, + testtrack::P, + testtrack::Dedx, + testtrack::Dcaxy, + testtrack::Dcaz); +} // namespace o2::aod +//-------------------------------------------------------- +using namespace o2; +using namespace o2::framework; + +struct DiffWakeTreeProducer { + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + Configurable nBinsPt{"nBinsPt", 100, "N bins in pT histo"}; + Configurable ptThresh{"ptThresh", 20.0, "pT threshold"}; + Configurable centMax{"centMax", 10, "centrality"}; + Configurable zVertCut{"zVertCut", 10.0, "z_vertex cut"}; + Configurable etaCut{"etaCut", 0.9, "eta cut"}; + + Produces testcol; + Produces testtrack; + + EventPlaneHelper helperEP; + + void init(InitContext const&) + { + const AxisSpec axisEta{30, -1.5, +1.5, "#eta"}; + const AxisSpec axispT{nBinsPt, 0, 250, "p_{T}"}; + + histos.add("etaHistogram", "etaHistogram", kTH1F, {axisEta}); + histos.add("pTHistogram", "pTHistogram", kTH1F, {axispT}); + } + + using Bcs = aod::BCs; + void process(soa::Join::iterator const& col, + soa::Join const& tracks, + Bcs const&) + { + const float maxMomentum = 173.0; // max for px, py, pz + const float minMomentum = 0.1; // min for pT + + // Event selection corresponds to sel8FullPbPb + if (!col.sel8()) { + return; + } + if (col.centFT0C() > centMax) { + return; // Centrality 0 - 10 % + } + if (std::abs(col.posZ()) > zVertCut) { + return; // z position < 10 cm + } + if (!col.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + return; + } + if (!col.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return; + } + //------ Get Run number --------------------- + auto bc = col.bc_as(); + int run = bc.runNumber(); + //------------ EP --------------------------- + double ep2 = 0.0; + double ep3 = 0.0; + ep2 = helperEP.GetEventPlane(col.qvecFT0CRe(), col.qvecFT0CIm(), 2); + ep3 = helperEP.GetEventPlane(col.qvecFT0CRe(), col.qvecFT0CIm(), 3); + + //------- Only events with track above some thresh ---------- + + bool eventHighpT = false; + for (const auto& track : tracks) { + + if (!track.isGlobalTrackWoPtEta()) { + continue; + } + if (track.pt() < minMomentum) { + continue; + } + if (std::abs(track.eta()) > etaCut) { + continue; + } + if (track.pt() > ptThresh) { + eventHighpT = true; + break; + } + } + if (!eventHighpT) { + return; + } + //------------------------------------------------------------ + // Translate values to less memory consuming values + auto substituteEp2 = static_cast(ep2 * 1000); + auto substituteEp3 = static_cast(ep3 * 1000); + + testcol(run, + col.centFT0C(), + col.multTPC(), + col.trackOccupancyInTimeRange(), + col.ft0cOccupancyInTimeRange(), + col.posX(), + col.posY(), + col.posZ(), + substituteEp2, + substituteEp3); + + for (const auto& track : tracks) { + + // Track cut + if (!track.isGlobalTrackWoPtEta()) { + continue; // General track cuts, but pT and eta cut are set manually + } + if (track.pt() < minMomentum) { + continue; + } + if (std::abs(track.eta()) > etaCut) { + continue; + } + + if (std::abs(track.px()) > maxMomentum || std::abs(track.py()) > maxMomentum || std::abs(track.pz()) > maxMomentum) { + continue; // to avoid overflow in Substitute_p + } + + histos.fill(HIST("etaHistogram"), track.eta()); + histos.fill(HIST("pTHistogram"), track.pt()); + + //------------ Translate values to less memory consuming values -------------------- + // Px, Py, Pz + uint64_t substituteP = 0; + uint8_t uppermostBit = 20; + uint8_t lowermostBit = 0; + uint64_t bitmask20Bits = 0b11111111111111111111; + + int64_t particlePx = (track.px() * 6000); + if (particlePx < 0) { + substituteP |= static_cast(1) << uppermostBit; + particlePx = (-1) * particlePx; + } + substituteP |= (particlePx & bitmask20Bits) << lowermostBit; + + uppermostBit = 41; + lowermostBit = 21; + int64_t particlePy = (track.py() * 6000); + if (particlePy < 0) { + substituteP |= static_cast(1) << uppermostBit; + particlePy = (-1) * particlePy; + } + substituteP |= (particlePy & bitmask20Bits) << lowermostBit; + + uppermostBit = 62; + lowermostBit = 42; + int64_t particlePz = (track.pz() * 6000); + if (particlePz < 0) { + substituteP |= static_cast(1) << uppermostBit; + particlePz = (-1) * particlePz; + } + substituteP |= (particlePz & bitmask20Bits) << lowermostBit; + + // dEdx + auto substituteDEDX = static_cast(track.tpcSignal() * 10); + + // DCA + auto substituteDCAXY = static_cast(track.dcaXY() * 100); + auto substituteDCAZ = static_cast(track.dcaZ() * 100); + + //--------------- Fill track table ------------------ + testtrack(testcol.lastIndex(), + track.sign(), + substituteP, + substituteDEDX, + substituteDCAXY, + substituteDCAZ); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGJE/TableProducer/emcalCorrectionTask.cxx b/PWGJE/TableProducer/emcalCorrectionTask.cxx index 6add2b66a89..75831ad1393 100644 --- a/PWGJE/TableProducer/emcalCorrectionTask.cxx +++ b/PWGJE/TableProducer/emcalCorrectionTask.cxx @@ -53,10 +53,11 @@ #include #include #include +#include #include -#include +#include #include #include @@ -199,7 +200,12 @@ struct EmcalCorrectionTask { int runNumber{0}; static constexpr float TrackNotOnEMCal = -900.f; - static constexpr int kMaxMatchesPerCluster = 20; // Maximum number of tracks to match per cluster + static constexpr int MaxMatchesPerCluster = 20; // Maximum number of tracks to match per cluster + + static constexpr uint MaxClusterPerDFPerClusterizer = 200'000; // memory footprint: 13 MB per clusterizer + static constexpr uint MaxAmbClusterPerDFPerClusterizer = 300'000; // memory footprint: 19.5 MB per clusterizer + static constexpr uint MaxCellsPerClusterPerDFPerClusterizer = 300'000; // memory footprint: 4.8 MB per clusterizer + static constexpr uint MaxCellsPerAmbClusterPerDFPerClusterizer = 450'000; // memory footprint: 7.2 MB per clusterizer // cluster size size_t nCluster = 0; @@ -414,6 +420,10 @@ struct EmcalCorrectionTask { void processFull(BcEvSels const& bcs, CollEventSels const& collisions, MyGlobTracks const& tracks, FilteredCells const& cells) { LOG(debug) << "Starting process full."; + clusters.reserve(MaxClusterPerDFPerClusterizer * mClusterizers.size()); + clustersAmbiguous.reserve(MaxAmbClusterPerDFPerClusterizer * mClusterizers.size()); + clustercells.reserve(MaxCellsPerClusterPerDFPerClusterizer * mClusterizers.size()); + clustercellsambiguous.reserve(MaxCellsPerAmbClusterPerDFPerClusterizer * mClusterizers.size()); int previousCollisionId = 0; // Collision ID of the last unique BC. Needed to skip unordered collisions to ensure ordered collisionIds in the cluster table int nBCsProcessed = 0; @@ -570,6 +580,11 @@ struct EmcalCorrectionTask { { LOG(debug) << "Starting process full."; + clusters.reserve(MaxClusterPerDFPerClusterizer * mClusterizers.size()); + clustersAmbiguous.reserve(MaxAmbClusterPerDFPerClusterizer * mClusterizers.size()); + clustercells.reserve(MaxCellsPerClusterPerDFPerClusterizer * mClusterizers.size()); + clustercellsambiguous.reserve(MaxCellsPerAmbClusterPerDFPerClusterizer * mClusterizers.size()); + int previousCollisionId = 0; // Collision ID of the last unique BC. Needed to skip unordered collisions to ensure ordered collisionIds in the cluster table int nBCsProcessed = 0; int nCellsProcessed = 0; @@ -730,6 +745,13 @@ struct EmcalCorrectionTask { { LOG(debug) << "Starting processMCFull."; + clusters.reserve(MaxClusterPerDFPerClusterizer * mClusterizers.size()); + mcclusters.reserve(MaxClusterPerDFPerClusterizer * mClusterizers.size()); + clustersAmbiguous.reserve(MaxAmbClusterPerDFPerClusterizer * mClusterizers.size()); + mcclustersAmbiguous.reserve(MaxAmbClusterPerDFPerClusterizer * mClusterizers.size()); + clustercells.reserve(MaxCellsPerClusterPerDFPerClusterizer * mClusterizers.size()); + clustercellsambiguous.reserve(MaxCellsPerAmbClusterPerDFPerClusterizer * mClusterizers.size()); + int previousCollisionId = 0; // Collision ID of the last unique BC. Needed to skip unordered collisions to ensure ordered collisionIds in the cluster table int nBCsProcessed = 0; int nCellsProcessed = 0; @@ -918,6 +940,13 @@ struct EmcalCorrectionTask { { LOG(debug) << "Starting processMCWithSecondaries."; + clusters.reserve(MaxClusterPerDFPerClusterizer * mClusterizers.size()); + mcclusters.reserve(MaxClusterPerDFPerClusterizer * mClusterizers.size()); + clustersAmbiguous.reserve(MaxAmbClusterPerDFPerClusterizer * mClusterizers.size()); + mcclustersAmbiguous.reserve(MaxAmbClusterPerDFPerClusterizer * mClusterizers.size()); + clustercells.reserve(MaxCellsPerClusterPerDFPerClusterizer * mClusterizers.size()); + clustercellsambiguous.reserve(MaxCellsPerAmbClusterPerDFPerClusterizer * mClusterizers.size()); + int previousCollisionId = 0; // Collision ID of the last unique BC. Needed to skip unordered collisions to ensure ordered collisionIds in the cluster table int nBCsProcessed = 0; int nCellsProcessed = 0; @@ -1107,6 +1136,12 @@ struct EmcalCorrectionTask { void processStandalone(BcEvSels const& bcs, aod::Collisions const& collisions, FilteredCells const& cells) { LOG(debug) << "Starting process standalone."; + + clusters.reserve(MaxClusterPerDFPerClusterizer * mClusterizers.size()); + clustersAmbiguous.reserve(MaxAmbClusterPerDFPerClusterizer * mClusterizers.size()); + clustercells.reserve(MaxCellsPerClusterPerDFPerClusterizer * mClusterizers.size()); + clustercellsambiguous.reserve(MaxCellsPerAmbClusterPerDFPerClusterizer * mClusterizers.size()); + int previousCollisionId = 0; // Collision ID of the last unique BC. Needed to skip unordered collisions to ensure ordered collisionIds in the cluster table int nBCsProcessed = 0; int nCellsProcessed = 0; @@ -1270,16 +1305,6 @@ struct EmcalCorrectionTask { template void fillClusterTable(Collision const& col, math_utils::Point3D const& vertexPos, size_t iClusterizer, const gsl::span cellIndicesBC, MatchResult* indexMapPair = nullptr, const std::vector* trackGlobalIndex = nullptr, MatchResult* indexMapPairSecondaries = nullptr, const std::vector* secondariesGlobalIndex = nullptr) { - // average number of cells per cluster, only used the reseve a reasonable amount for the clustercells table - // const size_t nAvgNcells = 3; - // we found a collision, put the clusters into the none ambiguous table - clusters.reserve(nCluster + mAnalysisClusters.size()); - if (!mClusterLabels.empty()) { - mcclusters.reserve(nCluster + mClusterLabels.size()); - } - // Since reserve triggers a fatal when its too small, it is not save for cells to use it unless we use a really large buffer... - // clustercells.reserve(mAnalysisClusters.size() * nAvgNcells); - // get the clusterType once const auto clusterType = static_cast(mClusterDefinitions[iClusterizer]); @@ -1368,14 +1393,7 @@ struct EmcalCorrectionTask { template void fillAmbigousClusterTable(BC const& bc, size_t iClusterizer, const gsl::span cellIndicesBC, bool hasCollision) { - // average number of cells per cluster, only used the reseve a reasonable amount for the clustercells table - // const size_t nAvgNcells = 3; int cellindex = -1; - clustersAmbiguous.reserve(mAnalysisClusters.size() + nClusterAmb); - if (mClusterLabels.size() > 0) { - mcclustersAmbiguous.reserve(mClusterLabels.size() + nClusterAmb); - } - // clustercellsambiguous.reserve(mAnalysisClusters.size() * nAvgNcells); unsigned int iCluster = 0; float energy = 0.f; for (const auto& cluster : mAnalysisClusters) { @@ -1433,7 +1451,7 @@ struct EmcalCorrectionTask { trackGlobalIndex.reserve(nTracksInCol); fillTrackInfo(groupedTracks, trackPhi, trackEta, trackGlobalIndex); - indexMapPair = matchTracksToCluster(mClusterPhi, mClusterEta, trackPhi, trackEta, maxMatchingDistance, kMaxMatchesPerCluster); + indexMapPair = matchTracksToCluster(mClusterPhi, mClusterEta, trackPhi, trackEta, maxMatchingDistance, MaxMatchesPerCluster); } template @@ -1469,7 +1487,7 @@ struct EmcalCorrectionTask { trackEta.emplace_back(trackEtaEmcal); trackGlobalIndex.emplace_back(track.globalIndex()); } - indexMapPair = matchTracksToCluster(mClusterPhi, mClusterEta, trackPhi, trackEta, maxMatchingDistance, kMaxMatchesPerCluster); + indexMapPair = matchTracksToCluster(mClusterPhi, mClusterEta, trackPhi, trackEta, maxMatchingDistance, MaxMatchesPerCluster); } template diff --git a/PWGJE/TableProducer/secondaryVertexReconstruction.cxx b/PWGJE/TableProducer/secondaryVertexReconstruction.cxx index d722cb4d743..363538c081b 100644 --- a/PWGJE/TableProducer/secondaryVertexReconstruction.cxx +++ b/PWGJE/TableProducer/secondaryVertexReconstruction.cxx @@ -37,12 +37,11 @@ #include #include #include +#include #include #include #include -#include - #include #include #include diff --git a/PWGJE/Tasks/CMakeLists.txt b/PWGJE/Tasks/CMakeLists.txt index e87a75535d2..3fa812e1308 100644 --- a/PWGJE/Tasks/CMakeLists.txt +++ b/PWGJE/Tasks/CMakeLists.txt @@ -440,4 +440,8 @@ if(FastJet_FOUND) SOURCES bjetCentMult.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-hadrons-pid + SOURCES jetHadronsPid.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::PWGJECore FastJet::FastJet FastJet::Contrib O2Physics::EventFilteringUtils + COMPONENT_NAME Analysis) endif() diff --git a/PWGJE/Tasks/chargedJetHadron.cxx b/PWGJE/Tasks/chargedJetHadron.cxx index 16a3e75e5d3..99c60a4cd06 100644 --- a/PWGJE/Tasks/chargedJetHadron.cxx +++ b/PWGJE/Tasks/chargedJetHadron.cxx @@ -55,7 +55,8 @@ struct ChargedJetHadron { Configurable vertexZCut{"vertexZCut", 10.0f, "Accepted z-vertex range"}; Configurable centralityMin{"centralityMin", 0.0, "minimum centrality"}; Configurable centralityMax{"centralityMax", 100.0, "maximum centrality"}; - Configurable triggerHadronPtMin{"triggerHadronPtMin", 20.0, "minimum trigger hadron pT for h-jet control"}; + Configurable triggerHadronPtMin{"triggerHadronPtMin", 15.0, "minimum trigger hadron pT for hjet"}; + Configurable subleadingHadronPtMin{"subleadingHadronPtMin", 10.0, "minimum recoil/subleading trigger hadron pT for di-hadron"}; Configurable leadingjetptMin{"leadingjetptMin", 20.0, "minimum leadingjetpt"}; Configurable subleadingjetptMin{"subleadingjetptMin", 10.0, "minimum subleadingjetpt"}; Configurable dijetDphiCut{"dijetDphiCut", 0.5, "minimum dijetDphiCut"}; @@ -81,9 +82,9 @@ struct ChargedJetHadron { Configurable acceptSplitCollisions{"acceptSplitCollisions", 0, "0: only look at mcCollisions that are not split; 1: accept split mcCollisions, 2: accept split mcCollisions but only look at the first reco collision associated with it"}; Configurable skipMBGapEvents{"skipMBGapEvents", false, "flag to choose to reject min. bias gap events; jet-level rejection can also be applied at the jet finder level for jets only, here rejection is applied for collision and track process functions for the first time, and on jets in case it was set to false at the jet finder level"}; Configurable checkLeadConstituentPtForMcpJets{"checkLeadConstituentPtForMcpJets", false, "flag to choose whether particle level jets should have their lead track pt above leadingConstituentPtMin to be accepted; off by default, as leadingConstituentPtMin cut is only applied on MCD jets for the Pb-Pb analysis using pp MC anchored to Pb-Pb for the response matrix"}; - Configurable doDijetEta{"doDijetEta", true, "0: dijet-hadron Eta axis, 1: dijet-hadron DEta axis"}; + Configurable doDijetEta{"doDijetEta", true, "1: dijet-hadron eta axis, 0: dijet-hadron delta-eta axis"}; Configurable doEventWeighted{"doEventWeighted", false, "0: weight is 1 for MB Sample, 1: weight from Jet-Jet Sample"}; - Configurable cfgCentEstimator{"cfgCentEstimator", 0, "0:FT0C; 1:FT0A; 2:FT0M"}; + Configurable cfgCentEstimator{"cfgCentEstimator", 0, "0:FT0C; 1:FT0A; 2:FT0M; -1:FT0CVariant1"}; Configurable numberEventsMixed{"numberEventsMixed", 5, "number of events mixed in ME process"}; ConfigurableAxis binsZVtx{"binsZVtx", {VARIABLE_WIDTH, -10.0f, -2.5f, 2.5f, 10.0f}, "Mixing bins - z-vertex"}; ConfigurableAxis binsMultiplicity{"binsMultiplicity", {VARIABLE_WIDTH, 0, 100., 300., 600., 1000., 2000., 5000., 8000.}, "Mixing bins - multiplicity"}; @@ -112,17 +113,6 @@ struct ChargedJetHadron { using CorrChargedMCDJets = soa::Join; using CorrChargedMCPJets = soa::Join; - /* - using BinningTypePP = ColumnBinningPolicy; - using BinningTypeMCPP = ColumnBinningPolicy; - using BinningType = ColumnBinningPolicy; - using BinningTypeMC = ColumnBinningPolicy; - BinningTypePP corrBinning{{binsZVtx, binsMultiplicity}, true}; - BinningTypeMCPP corrBinningMC{{binsZVtx, binsMultiplicityMc}, true}; - BinningType corrBinning{{binsZVtx, binsMultiplicity}, true}; - BinningTypeMC corrBinningMC{{binsZVtx, binsMultiplicityMc}, true}; - */ - using BinningTypePP = ColumnBinningPolicy; using BinningType = ColumnBinningPolicy; using BinningTypeMC = ColumnBinningPolicy; @@ -147,6 +137,8 @@ struct ChargedJetHadron { if (cfgCentEstimator == 0) { eventCuts = (aod::jcollision::centFT0C >= centralityMin && aod::jcollision::centFT0C <= centralityMax); + } else if (cfgCentEstimator == -1) { + eventCuts = (aod::jcollision::centFT0CVariant1 >= centralityMin && aod::jcollision::centFT0CVariant1 <= centralityMax); } else if (cfgCentEstimator == 1) { eventCuts = (aod::jcollision::centFT0A >= centralityMin && aod::jcollision::centFT0A <= centralityMax); } else { @@ -159,16 +151,16 @@ struct ChargedJetHadron { AxisSpec phiAxis = {65, -0.2, 6.3, "#varphi"}; AxisSpec jetPtAxis = {200, 0., 200., "#it{p}_{T} (GeV/#it{c})"}; AxisSpec jetPtAxisRhoAreaSub = {280, -80., 200., "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec jetmultetaAxis = {4, -0.5, 0.5, "#Delta#eta"}; + AxisSpec jetmultetaAxis = {4, -0.5, 0.5, "#eta_{jet1}#eta_{jet2}"}; + AxisSpec hadronmultetaAxis = {4, -1.0, 1.0, "#eta_{trig1}#eta_{trig2}"}; AxisSpec detaAxis = {32, -1.6, 1.6, "#Delta#eta"}; AxisSpec dphiAxis = {70, -1.7, 5.3, "#Delta#varphi"}; AxisSpec drAxis = {30, 0.0, 1.5, "#Delta#it{R}"}; - AxisSpec axisBdtScore = {100, 0., 1., "Bdt score"}; if (doprocessCollisionsQCData || doprocessCollisionsQCMCD) { if (doprocessCollisionsQCMCD && doEventWeighted) { - registry.add("h_jet_phat", "jet #hat{p};#hat{p} (GeV/#it{c});entries", {HistType::kTH1F, {{1000, 0, 1000}}}); - registry.add("h_jet_phat_weighted", "jet #hat{p};#hat{p} (GeV/#it{c});entries", {HistType::kTH1F, {{1000, 0, 1000}}}); + registry.add("h_coll_phat", "collision #hat{p};#hat{p} (GeV/#it{c});entries", {HistType::kTH1F, {{1000, 0, 1000}}}); + registry.add("h_coll_phat_weighted", "collision #hat{p};#hat{p} (GeV/#it{c});entries", {HistType::kTH1F, {{1000, 0, 1000}}}); } registry.add("h_collisions", "event status;event status; entries", {HistType::kTH1F, {{7, 0.0, 7.0}}}); registry.add("h_collisions_weighted", "event status;event status;entries", {HistType::kTH1F, {{7, 0.0, 7.0}}}); @@ -177,8 +169,8 @@ struct ChargedJetHadron { registry.add("h_collisions_zvertex", "position of collision; #it{Z} (cm)", {HistType::kTH1F, {{300, -15.0, 15.0}}}); registry.add("h_collisions_multFT0", " multiplicity using multFT0; entries", {HistType::kTH1F, {{500, 0, 100000}}}); registry.add("h2_track_eta_track_phi", "track #eta vs. track #phi; #eta; #phi; counts", {HistType::kTH2F, {etaAxis, phiAxis}}); - registry.add("h2_track_eta_pt", "track #eta vs. track #it{p}_{T}; #eta; #it{p}_{T,track} (GeV/#it{c}; counts", {HistType::kTH2F, {etaAxis, trackPtAxis}}); - registry.add("h2_track_phi_pt", "track #phi vs. track #it{p}_{T}; #phi; #it{p}_{T,track} (GeV/#it{c}; counts", {HistType::kTH2F, {phiAxis, trackPtAxis}}); + registry.add("h2_track_eta_pt", "track #eta vs. track #it{p}_{T}; #eta; #it{p}_{T,track} (GeV/#it{c}); counts", {HistType::kTH2F, {etaAxis, trackPtAxis}}); + registry.add("h2_track_phi_pt", "track #phi vs. track #it{p}_{T}; #phi; #it{p}_{T,track} (GeV/#it{c}); counts", {HistType::kTH2F, {phiAxis, trackPtAxis}}); } if (doprocessSpectraAreaSubData || doprocessSpectraAreaSubMCD) { @@ -200,7 +192,7 @@ struct ChargedJetHadron { if (doprocessJetHadron || doprocessMixJetHadron || doprocessJetHadronMCD || doprocessMixJetHadronMCD) { registry.add("h_trigjet_corrpt", "trigger jet pT;#it{p}_{T,jet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); registry.add("thn_jeth_correlations", "jet-h correlations; jetpT; trackpT; jeth#Delta#eta; jeth#Delta#varphi; jeth#Delta#it{R}", HistType::kTHnSparseF, {jetPtAxis, trackPtAxis, detaAxis, dphiAxis, drAxis}); - registry.add("h_jeth_event_stats", "Same event statistics; Event pair type; counts", {HistType::kTH1F, {{7, 0., 7.}}}); + registry.add("h_jeth_event_stats", "Same event statistics; Event pair type; counts", {HistType::kTH1F, {{7, 0.5, 7.5}}}); registry.get(HIST("h_jeth_event_stats"))->GetXaxis()->SetBinLabel(1, "Total jets"); registry.get(HIST("h_jeth_event_stats"))->GetXaxis()->SetBinLabel(2, "Total jets with pTHat cut"); registry.get(HIST("h_jeth_event_stats"))->GetXaxis()->SetBinLabel(3, "Total jets with cuts"); @@ -208,7 +200,7 @@ struct ChargedJetHadron { registry.get(HIST("h_jeth_event_stats"))->GetXaxis()->SetBinLabel(5, "Total j-h pairs with accepted"); registry.add("h_mixtrigjet_corrpt", "trigger jet pT;#it{p}_{T,jet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); registry.add("thn_mixjeth_correlations", "ME: jet-h correlations; jetpT; trackpT; jeth#Delta#eta; jeth#Delta#varphi; jeth#Delta#it{R}", HistType::kTHnSparseF, {jetPtAxis, trackPtAxis, detaAxis, dphiAxis, drAxis}); - registry.add("h_mixjeth_event_stats", "Mixed event statistics; Event pair type; counts", {HistType::kTH1F, {{7, 0., 7.}}}); + registry.add("h_mixjeth_event_stats", "Mixed event statistics; Event pair type; counts", {HistType::kTH1F, {{7, 0.5, 7.5}}}); registry.get(HIST("h_mixjeth_event_stats"))->GetXaxis()->SetBinLabel(1, "Total mixed events"); registry.get(HIST("h_mixjeth_event_stats"))->GetXaxis()->SetBinLabel(2, "Total jets"); registry.get(HIST("h_mixjeth_event_stats"))->GetXaxis()->SetBinLabel(3, "Total jets with cuts"); @@ -216,21 +208,6 @@ struct ChargedJetHadron { registry.get(HIST("h_mixjeth_event_stats"))->GetXaxis()->SetBinLabel(5, "Total j-h pairs with accepted"); } - if (doprocessHFJetCorrelation) { - registry.add("h_d0jet_pt", "D0 jet pT;#it{p}_{T,jet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxis}}); - registry.add("h_d0jet_corrpt", "D0 jet pT;#it{p}_{T,jet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); - registry.add("h_d0jet_eta", "D0 jet eta;#eta; counts", {HistType::kTH1F, {etaAxis}}); - registry.add("h_d0jet_phi", "D0 jet phi;#phi; counts", {HistType::kTH1F, {phiAxis}}); - registry.add("h_d0_pt", ";p_{T,D^{0}};dN/dp_{T,D^{0}}", {HistType::kTH1F, {{200, 0., 10.}}}); - registry.add("h_d0_mass", ";m_{D^{0}} (GeV/c^{2});dN/dm_{D^{0}}", {HistType::kTH1F, {{1000, 0., 10.}}}); - registry.add("h_d0_eta", ";#eta_{D^{0}} (GeV/c^{2});dN/d#eta_{D^{0}}", {HistType::kTH1F, {{200, -5., 5.}}}); - registry.add("h_d0_phi", ";#varphi_{D^{0}} (GeV/c^{2});dN/d#varphi_{D^{0}}", {HistType::kTH1F, {{200, -10., 10.}}}); - registry.add("h_d0_bdtScorePrompt", "D0 BDT prompt score", {HistType::kTH1F, {axisBdtScore}}); - registry.add("h_d0_bdtScoreBkg", "D0 BDT bkg score", {HistType::kTH1F, {axisBdtScore}}); - registry.add("h_d0bar_bdtScorePrompt", "D0bar BDT prompt score", {HistType::kTH1F, {axisBdtScore}}); - registry.add("h_d0bar_bdtScoreBkg", "D0bar BDT bkg score", {HistType::kTH1F, {axisBdtScore}}); - registry.add("h2_d0jet_detadphi", "D^{0}-jets deta vs dphi; #Delta#eta; #Delta#phi", {HistType::kTH2F, {detaAxis, dphiAxis}}); - } //========leading jet-hadron correlations====================== if (doprocessLeadingJetHadron || doprocessLeadingJetHadronMCD) { registry.add("h_centrality", "centrality distributions; centrality; counts", {HistType::kTH1F, {centralityAxis}}); @@ -238,13 +215,13 @@ struct ChargedJetHadron { registry.add("h_leadjet_pt", "leading jet pT;#it{p}_{T,leadingjet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxis}}); registry.add("h_leadjet_corrpt", "leading jet corrpT;#it{p}_{T,leadingjet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); registry.add("h_subleadjet_pt", "subleading jet pT;#it{p}_{T,subleadingjet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxis}}); - registry.add("h_subleadjet_corrpt", "subleading jet corrpT;#it{p}_{T,leadingjet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); + registry.add("h_subleadjet_corrpt", "subleading jet corrpT;#it{p}_{T,subleadingjet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); registry.add("h_leadjet_eta", "leading jet eta;#eta; counts", {HistType::kTH1F, {etaAxis}}); registry.add("h_leadjet_phi", "leading jet phi;#phi; counts", {HistType::kTH1F, {phiAxis}}); registry.add("h_subleadjet_eta", "subleading jet eta;#eta; counts", {HistType::kTH1F, {etaAxis}}); registry.add("h_subleadjet_phi", "subleading jet phi;#phi; counts", {HistType::kTH1F, {phiAxis}}); - registry.add("h2_leadjet_corrpt_constituent_pt", "leading jet;#it{p}_{T,jet}^{corr};#it{p}_{T}^{const}", {HistType::kTH2F, {jetPtAxis, trackPtAxis}}); - registry.add("h2_subleadjet_corrpt_constituent_pt", "subleading jet;#it{p}_{T,jet}^{corr};#it{p}_{T}^{const}", {HistType::kTH2F, {jetPtAxis, trackPtAxis}}); + registry.add("h_leadjet_constituent_pt", "leading jet constituent;#it{p}_{T}^{const}", {HistType::kTH1F, {trackPtAxis}}); + registry.add("h_subleadjet_constituent_pt", "subleading jet constituent;#it{p}_{T}^{const}", {HistType::kTH1F, {trackPtAxis}}); registry.add("h_leadjet_leadingconstituent_pt", "leading jet leading constituent;#it{p}_{T}^{leading const} (GeV/#it{c});counts", {HistType::kTH1F, {trackPtAxis}}); registry.add("h_subleadjet_leadingconstituent_pt", "subleading jet leading constituent;#it{p}_{T}^{leading const} (GeV/#it{c});counts", {HistType::kTH1F, {trackPtAxis}}); registry.add("h2_dijet_detanoflip_dphi", "dijet #Delta#eta no flip vs #Delta#varphi; #Delta#eta_{noflip}; #Delta#varphi; counts", {HistType::kTH2F, {detaAxis, {63, 0, 6.3}}}); @@ -254,8 +231,8 @@ struct ChargedJetHadron { registry.add("h_jeth_deta", "jeth #Delta#eta; #Delta#eta; counts", {HistType::kTH1F, {detaAxis}}); registry.add("h_jeth_dphi", "jeth #Delta#varphi; #Delta#varphi; counts", {HistType::kTH1F, {dphiAxis}}); if (doDijetEta) { - registry.add("h2_dijet_TimeEtaThan0_pt", "dijet #eta_{jet1}#eta_{jet1} > 0", {HistType::kTH2F, {jetPtAxis, jetPtAxis}}); - registry.add("h2_dijet_TimeEtaLess0_pt", "dijet #eta_{jet1}#eta_{jet1} < 0", {HistType::kTH2F, {jetPtAxis, jetPtAxis}}); + registry.add("h2_dijet_TimeEtaThan0_pt", "dijet #eta_{jet1}#eta_{jet2} > 0", {HistType::kTH2F, {jetPtAxis, jetPtAxis}}); + registry.add("h2_dijet_TimeEtaLess0_pt", "dijet #eta_{jet1}#eta_{jet2} < 0", {HistType::kTH2F, {jetPtAxis, jetPtAxis}}); registry.add("h2_jeth_heta_dphi", "jeth heta vs dphi; hadron #eta; #Delta#phi", {HistType::kTH2F, {etaAxis, dphiAxis}}); registry.add("thn_ljeth_correlations", "leading jet-h correlations; leadingjetpT; subleadingjetpT; trackpT; timedijeteta; track #eta; jeth#Delta#varphi", HistType::kTHnSparseF, {jetPtAxis, jetPtAxis, {8, 0., 8.}, jetmultetaAxis, etaAxis, dphiAxis}); } else { @@ -265,6 +242,7 @@ struct ChargedJetHadron { registry.add("thn_ljeth_correlations", "leading jet-h correlations; leadingjetpT; subleadingjetpT; trackpT; #Delta#eta_{jet1,2}; jeth#Delta#eta; jeth#Delta#varphi", HistType::kTHnSparseF, {jetPtAxis, jetPtAxis, {8, 0., 8.}, {16, 0, 1.6}, detaAxis, dphiAxis}); } } + //=============hjet-hadron correlations====================== if (doprocessHadronJetHadron || doprocessHadronJetHadronMCD) { registry.add("h_hjet_trigtrack_pt", "trigger hadron pT;#it{p}_{T,trig} (GeV/#it{c}); counts", {HistType::kTH1F, {trackPtAxis}}); registry.add("h_hjet_trigtrack_eta", "trigger hadron #eta;#eta_{trig}; counts", {HistType::kTH1F, {etaAxis}}); @@ -273,13 +251,29 @@ struct ChargedJetHadron { registry.add("h_hjet_recoiljet_eta", "recoil jet #eta;#eta_{recoil jet}; counts", {HistType::kTH1F, {etaAxis}}); registry.add("h_hjet_recoiljet_phi", "recoil jet #varphi;#varphi_{recoil jet}; counts", {HistType::kTH1F, {phiAxis}}); registry.add("h_hjet_dphi", "hjet #Delta#varphi; #Delta#varphi_{hjet}; counts", {HistType::kTH1F, {{63, 0., 6.3}}}); - registry.add("h2_recojet_corrpt_constituent_pt", "recoil jet;#it{p}_{T,jet}^{corr};#it{p}_{T}^{const}", {HistType::kTH2F, {jetPtAxis, trackPtAxis}}); - registry.add("h2_hjet_TimeEtaThan0_pt", "h-jet #eta_{trig}#eta_{recoil jet} > 0;#it{p}_{T,trig};#it{p}_{T,recoil jet}^{corr}", {HistType::kTH2F, {trackPtAxis, jetPtAxis}}); - registry.add("h2_hjet_TimeEtaLess0_pt", "h-jet #eta_{trig}#eta_{recoil jet} < 0;#it{p}_{T,trig};#it{p}_{T,recoil jet}^{corr}", {HistType::kTH2F, {trackPtAxis, jetPtAxis}}); + registry.add("h_recojet_constituent_pt", "recoil jet constituent;#it{p}_{T}^{const}", {HistType::kTH1F, {trackPtAxis}}); + registry.add("h2_hjet_TimeEtaThan0_pt", "hjet #eta_{trig1}#eta_{jet2} > 0;#it{p}_{T,trig};#it{p}_{T,recoil jet}^{corr}", {HistType::kTH2F, {trackPtAxis, jetPtAxis}}); + registry.add("h2_hjet_TimeEtaLess0_pt", "hjet #eta_{trig1}#eta_{jet2} < 0;#it{p}_{T,trig};#it{p}_{T,recoil jet}^{corr}", {HistType::kTH2F, {trackPtAxis, jetPtAxis}}); registry.add("h2_hjet_heta_dphi", "hjet heta vs dphi; hadron #eta; #Delta#phi", {HistType::kTH2F, {etaAxis, dphiAxis}}); - registry.add("thn_hjeth_correlations", "h-jet-h correlations; triggerHadronpT; recoilJetpT; trackpT; timehjeteta; track #eta; hh#Delta#varphi", HistType::kTHnSparseF, {trackPtAxis, jetPtAxis, {8, 0., 8.}, jetmultetaAxis, etaAxis, dphiAxis}); + registry.add("thn_hjeth_correlations", "hjet-h correlations; triggerHadronpT; recoilJetpT; trackpT; timehjeteta; track #eta; hh#Delta#varphi", HistType::kTHnSparseF, {trackPtAxis, jetPtAxis, {8, 0., 8.}, hadronmultetaAxis, etaAxis, dphiAxis}); + } + + //========dihadron-hadron correlations========== + if (doprocessDiHadron || doprocessDiHadronMCD) { + registry.add("h_dihadron_leadtrack_pt", "leading trigger hadron pT;#it{p}_{T,trig1} (GeV/#it{c}); counts", {HistType::kTH1F, {trackPtAxis}}); + registry.add("h_dihadron_leadtrack_eta", "leading trigger hadron #eta;#eta_{trig1}; counts", {HistType::kTH1F, {etaAxis}}); + registry.add("h_dihadron_leadtrack_phi", "leading trigger hadron #varphi;#varphi_{trig1}; counts", {HistType::kTH1F, {phiAxis}}); + registry.add("h_dihadron_subleadtrack_pt", "recoil trigger hadron pT;#it{p}_{T,trig2} (GeV/#it{c}); counts", {HistType::kTH1F, {trackPtAxis}}); + registry.add("h_dihadron_subleadtrack_eta", "recoil trigger hadron #eta;#eta_{trig2}; counts", {HistType::kTH1F, {etaAxis}}); + registry.add("h_dihadron_subleadtrack_phi", "recoil trigger hadron #varphi;#varphi_{trig2}; counts", {HistType::kTH1F, {phiAxis}}); + registry.add("h_dihadron_dphi", "di-hadron #Delta#varphi;|#Delta#varphi_{trig1,trig2}|; counts", {HistType::kTH1F, {{63, 0., 6.3}}}); + registry.add("h2_dihadron_TimeEtaThan0_pt", "di-hadron #eta_{trig1}#eta_{trig2} > 0;#it{p}_{T,trig1};#it{p}_{T,trig2}", {HistType::kTH2F, {trackPtAxis, trackPtAxis}}); + registry.add("h2_dihadron_TimeEtaLess0_pt", "di-hadron #eta_{trig1}#eta_{trig2} < 0;#it{p}_{T,trig1};#it{p}_{T,trig2}", {HistType::kTH2F, {trackPtAxis, trackPtAxis}}); + registry.add("h2_dihadron_heta_dphi", "di-hadron associated-hadron #eta vs #Delta#varphi;hadron #eta;#Delta#varphi", {HistType::kTH2F, {etaAxis, dphiAxis}}); + registry.add("thn_dihadron_correlations", "di-hadron correlations;leadingHadronpT;recoilHadronpT;associatedHadronpT;#eta_{trig1}#eta_{trig2};associated hadron #eta;h-h #Delta#varphi", HistType::kTHnSparseF, {trackPtAxis, trackPtAxis, {8, 0., 8.}, hadronmultetaAxis, etaAxis, dphiAxis}); } + //======MC===================== if (doprocessCollisionsQCMCP) { registry.add("h_mcColl_counts", " number of mc events; event status; entries", {HistType::kTH1F, {{9, 0., 9.}}}); registry.get(HIST("h_mcColl_counts"))->GetXaxis()->SetBinLabel(1, "allMcColl"); @@ -289,23 +283,23 @@ struct ChargedJetHadron { registry.get(HIST("h_mcColl_counts"))->GetXaxis()->SetBinLabel(5, "recoEvtSel"); registry.get(HIST("h_mcColl_counts"))->GetXaxis()->SetBinLabel(6, "occupancyCut"); registry.get(HIST("h_mcColl_counts"))->GetXaxis()->SetBinLabel(7, "centralityCut"); + registry.get(HIST("h_mcColl_counts"))->GetXaxis()->SetBinLabel(8, "accepted"); registry.add("h_mcpColl_zvertex", "position of collision ;#it{Z} (cm)", {HistType::kTH1F, {{300, -15.0, 15.0}}}); registry.add("h_mcpColl_centrality", "mcp collision centrality; centrality; counts", {HistType::kTH1F, {centralityAxis}}); registry.add("h_mcpColl_multFT0", " mcp multiplicity global tracks; entries", {HistType::kTH1F, {{500, 0, 100000}}}); registry.add("h2_particle_eta_phi", "particle #eta vs. particle #phi; #eta; #phi; counts", {HistType::kTH2F, {etaAxis, phiAxis}}); - registry.add("h2_particle_eta_pt", "particle #eta vs. particle #it{p}_{T}; #eta; #it{p}_{T,particle} (GeV/#it{c}; counts", {HistType::kTH2F, {etaAxis, trackPtAxis}}); - registry.add("h2_particle_phi_pt", "particle #phi vs. particle #it{p}_{T}; #phi; #it{p}_{T,particle} (GeV/#it{c}; counts", {HistType::kTH2F, {phiAxis, trackPtAxis}}); + registry.add("h2_particle_eta_pt", "particle #eta vs. particle #it{p}_{T}; #eta; #it{p}_{T,particle} (GeV/#it{c}); counts", {HistType::kTH2F, {etaAxis, trackPtAxis}}); + registry.add("h2_particle_phi_pt", "particle #phi vs. particle #it{p}_{T}; #phi; #it{p}_{T,particle} (GeV/#it{c}); counts", {HistType::kTH2F, {phiAxis, trackPtAxis}}); } if (doprocessSpectraAreaSubMCP) { if (doEventWeighted) { - registry.add("h_mcColl_counts_weight", " number of weighted mc events; event status; entries", {HistType::kTH1F, {{7, 0., 7.}}}); + registry.add("h_mcColl_counts_weight", " number of weighted mc events; event status; entries", {HistType::kTH1F, {{7, 0.5, 7.5}}}); registry.get(HIST("h_mcColl_counts_weight"))->GetXaxis()->SetBinLabel(1, "McColl"); registry.get(HIST("h_mcColl_counts_weight"))->GetXaxis()->SetBinLabel(2, "xsectGen"); registry.get(HIST("h_mcColl_counts_weight"))->GetXaxis()->SetBinLabel(3, "event weight"); } registry.add("h_mcColl_rho", "mc collision rho;#rho (GeV/#it{c}); counts", {HistType::kTH1F, {{500, 0.0, 500.0}}}); - registry.add("h_inclusivejet_corrpt_part", "part inclusive jet pT;#it{p}_{T,jet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); registry.add("h_jet_pt_part", "part jet pT;#it{p}_{T,jet}^{part} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxis}}); registry.add("h_jet_eta_part", "part jet #eta;#eta^{part}; counts", {HistType::kTH1F, {etaAxis}}); registry.add("h_jet_phi_part", "part jet #varphi;#phi^{part}; counts", {HistType::kTH1F, {phiAxis}}); @@ -325,7 +319,7 @@ struct ChargedJetHadron { registry.add("h_trigjet_corrpt_part", "trigger jet pT;#it{p}_{T,jet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); registry.add("thn_jeth_correlations_part", "MCP: jet-h correlations; jetpT; trackpT; jeth#Delta#eta; jeth#Delta#varphi; jeth#Delta#it{R}", HistType::kTHnSparseF, {jetPtAxis, trackPtAxis, detaAxis, dphiAxis, drAxis}); - registry.add("h_jeth_event_stats_part", "MCP: same event statistics; Event pair type; counts", {HistType::kTH1F, {{7, 0., 7.}}}); + registry.add("h_jeth_event_stats_part", "MCP: same event statistics; Event pair type; counts", {HistType::kTH1F, {{7, 0.5, 7.5}}}); registry.get(HIST("h_jeth_event_stats_part"))->GetXaxis()->SetBinLabel(1, "Total jets"); registry.get(HIST("h_jeth_event_stats_part"))->GetXaxis()->SetBinLabel(2, "Total jets with pTHat cut"); registry.get(HIST("h_jeth_event_stats_part"))->GetXaxis()->SetBinLabel(3, "Total jets with cuts"); @@ -334,7 +328,7 @@ struct ChargedJetHadron { registry.add("h_mixtrigjet_corrpt_part", "trigger jet pT;#it{p}_{T,jet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); registry.add("thn_mixjeth_correlations_part", "mcpME: jet-h correlations; jetpT; trackpT; jeth#Delta#eta; jeth#Delta#varphi; jeth#Delta#it{R}", HistType::kTHnSparseF, {jetPtAxis, trackPtAxis, detaAxis, dphiAxis, drAxis}); - registry.add("h_mixjeth_event_stats_part", "MCP: mixed event statistics; Event pair type; counts", {HistType::kTH1F, {{7, 0., 7.}}}); + registry.add("h_mixjeth_event_stats_part", "MCP: mixed event statistics; Event pair type; counts", {HistType::kTH1F, {{7, 0.5, 7.5}}}); registry.get(HIST("h_mixjeth_event_stats_part"))->GetXaxis()->SetBinLabel(1, "Total mixed events"); registry.get(HIST("h_mixjeth_event_stats_part"))->GetXaxis()->SetBinLabel(2, "Total jets"); registry.get(HIST("h_mixjeth_event_stats_part"))->GetXaxis()->SetBinLabel(3, "Total jets with cuts"); @@ -344,6 +338,7 @@ struct ChargedJetHadron { if (doprocessLeadingJetHadronMCP) { //.........SE leading jet correlations............... + registry.add("h_inclusivejet_corrpt_part", "part inclusive jet pT;#it{p}_{T,jet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); registry.add("h_leadjet_pt_part", "MCP: leading jet pT;#it{p}_{T,leadingjet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxis}}); registry.add("h_leadjet_corrpt_part", "MCP: leading jet corrpT;#it{p}_{T,leadingjet} (GeV/#it{c}); counts", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); registry.add("h_leadjet_eta_part", "MCP: leading jet eta;#eta; counts", {HistType::kTH1F, {etaAxis}}); @@ -354,13 +349,13 @@ struct ChargedJetHadron { registry.add("h_subleadjet_phi_part", "MCP: subleading jet phi;#phi; counts", {HistType::kTH1F, {phiAxis}}); registry.add("h2_dijet_detanoflip_dphi_part", "MCP: dijet #Delta#eta no flip vs #Delta#varphi; #Delta#eta_{noflip}; #Delta#varphi; counts", {HistType::kTH2F, {detaAxis, {63, 0, 6.3}}}); registry.add("h2_dijet_Asymmetry_part", "MCP: dijet Asymmetry; #it{p}_{T,subleadingjet} (GeV/#it{c}); #it{X}_{J}; counts", {HistType::kTH2F, {jetPtAxisRhoAreaSub, {40, 0, 1.0}}}); - registry.add("h3_dijet_deta_pt_part", "MCP: dijet #Delta#eta flip vs #it{p}_{T,jet1-jet2}; #Delta#eta_{flip}; #Delta#varphi; counts", {HistType::kTH3F, {{16, 0, 1.6}, jetPtAxis, jetPtAxis}}); + registry.add("h3_dijet_deta_pt_part", "MCP: dijet #Delta#eta flip vs #it{p}_{T,jet1-jet2}; #Delta#eta_{flip}; #it{p}_{T,jet1}^{corr}; #it{p}_{T,jet2}^{corr};", {HistType::kTH3F, {{16, 0, 1.6}, jetPtAxis, jetPtAxis}}); registry.add("h_jeth_detatot_part", "MCP: jeth tot #Delta#eta; #Delta#eta; counts", {HistType::kTH1F, {detaAxis}}); registry.add("h_jeth_deta_part", "MCP: jeth #Delta#eta; #Delta#eta; counts", {HistType::kTH1F, {detaAxis}}); registry.add("h_jeth_dphi_part", "MCP: jeth #Delta#varphi; #Delta#varphi; counts", {HistType::kTH1F, {dphiAxis}}); if (doDijetEta) { - registry.add("h2_dijet_TimeEtaThan0_pt_part", "dijet #eta_{jet1}#eta_{jet1} > 0", {HistType::kTH2F, {jetPtAxis, jetPtAxis}}); - registry.add("h2_dijet_TimeEtaLess0_pt_part", "dijet #eta_{jet1}#eta_{jet1} < 0", {HistType::kTH2F, {jetPtAxis, jetPtAxis}}); + registry.add("h2_dijet_TimeEtaThan0_pt_part", "dijet #eta_{jet1}#eta_{jet2} > 0", {HistType::kTH2F, {jetPtAxis, jetPtAxis}}); + registry.add("h2_dijet_TimeEtaLess0_pt_part", "dijet #eta_{jet1}#eta_{jet2} < 0", {HistType::kTH2F, {jetPtAxis, jetPtAxis}}); registry.add("h2_jeth_heta_dphi_part", "MCP: jeth heta vs dphi; hadron #eta; #Delta#phi", {HistType::kTH2F, {etaAxis, dphiAxis}}); registry.add("thn_ljeth_correlations_part", "MCP: leading jet-h correlations; leadingjetpT; subleadingjetpT; trackpT; timedijeteta; track #eta; jeth#Delta#varphi", HistType::kTHnSparseF, {jetPtAxis, jetPtAxis, {8, 0., 8.}, jetmultetaAxis, etaAxis, dphiAxis}); } else { @@ -383,6 +378,8 @@ struct ChargedJetHadron { { if (cfgCentEstimator.value == 0) return coll.centFT0C(); + if (cfgCentEstimator.value == -1) + return coll.centFT0CVariant1(); if (cfgCentEstimator.value == 1) return coll.centFT0A(); return coll.centFT0M(); @@ -393,6 +390,8 @@ struct ChargedJetHadron { { if (cfgCentEstimator.value == 0) return coll.multFT0C(); + if (cfgCentEstimator.value == -1) + return coll.multFT0C(); if (cfgCentEstimator.value == 1) return coll.multFT0A(); return coll.multFT0C() + coll.multFT0A(); @@ -495,15 +494,8 @@ struct ChargedJetHadron { } // ========================================================== template - void fillTrackHistograms(TTracks const& track, float weight = 1.0, float pTHat = 999.0) + void fillTrackHistograms(TTracks const& track, float weight = 1.0) { - // float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); - if (track.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) - return; - if (doEventWeighted) { - registry.fill(HIST("h_jet_phat"), pTHat); - registry.fill(HIST("h_jet_phat_weighted"), pTHat, weight); - } registry.fill(HIST("h2_track_eta_track_phi"), track.eta(), track.phi(), weight); registry.fill(HIST("h2_track_eta_pt"), track.eta(), track.pt(), weight); registry.fill(HIST("h2_track_phi_pt"), track.phi(), track.pt(), weight); @@ -512,7 +504,7 @@ struct ChargedJetHadron { template void fillJetHistograms(TJets const& jet, float weight = 1.0, float pTHat = 999.0) { - if (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) + if (doEventWeighted && (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin)) return; if (jet.r() == round(selectedJetsRadius * 100.0f)) { registry.fill(HIST("h_jet_pt"), jet.pt(), weight); @@ -529,7 +521,7 @@ struct ChargedJetHadron { template void fillJetAreaSubHistograms(TJets const& jet, float rho, float weight = 1.0, float pTHat = 999.0) { - if (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) + if (doEventWeighted && (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin)) return; double jetcorrpt = jet.pt() - (rho * jet.area()); if (jet.r() == round(selectedJetsRadius * 100.0f)) { @@ -547,19 +539,17 @@ struct ChargedJetHadron { } template - void fillParticleHistograms(const TParticles& particle, float weight = 1.0, float pTHat = 999.0) + void fillParticleHistograms(const TParticles& particle, float weight = 1.0) { - if (particle.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) - return; registry.fill(HIST("h2_particle_eta_phi"), particle.eta(), particle.phi(), weight); registry.fill(HIST("h2_particle_eta_pt"), particle.eta(), particle.pt(), weight); registry.fill(HIST("h2_particle_phi_pt"), particle.phi(), particle.pt(), weight); } template - void fillMCPHistograms(TJets const& jet, float weight = 1.0, float pTHat = 999.0) + void fillMCPJetHistograms(TJets const& jet, float weight = 1.0, float pTHat = 999.0) { - if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) + if (doEventWeighted && (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin)) return; if (jet.r() == round(selectedJetsRadius * 100.0f)) { registry.fill(HIST("h_jet_pt_part"), jet.pt(), weight); @@ -574,9 +564,9 @@ struct ChargedJetHadron { } template - void fillMCPAreaSubHistograms(TJets const& jet, float rho = 0.0, float weight = 1.0, float pTHat = 999.0) + void fillMCPJetAreaSubHistograms(TJets const& jet, float rho = 0.0, float weight = 1.0, float pTHat = 999.0) { - if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) + if (doEventWeighted && (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin)) return; double jetcorrpt = jet.pt() - (rho * jet.area()); if (jet.r() == round(selectedJetsRadius * 100.0f)) { @@ -606,20 +596,20 @@ struct ChargedJetHadron { } if (!isAcceptedJet(jet)) continue; - registry.fill(HIST("h_jeth_event_stats"), 1); - if (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) + registry.fill(HIST("h_jeth_event_stats"), 1, weight); + if (doEventWeighted && (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin)) continue; - registry.fill(HIST("h_jeth_event_stats"), 2); + registry.fill(HIST("h_jeth_event_stats"), 2, weight); double ptCorr = jet.pt() - jet.area() * collision.rho(); if (ptCorr < subleadingjetptMin) continue; - registry.fill(HIST("h_trigjet_corrpt"), ptCorr); - registry.fill(HIST("h_jeth_event_stats"), 3); + registry.fill(HIST("h_trigjet_corrpt"), ptCorr, weight); + registry.fill(HIST("h_jeth_event_stats"), 3, weight); for (auto const& track : tracks) { - registry.fill(HIST("h_jeth_event_stats"), 4); + registry.fill(HIST("h_jeth_event_stats"), 4, weight); if (!jetderiveddatautilities::selectTrack(track, trackSelection)) continue; - registry.fill(HIST("h_jeth_event_stats"), 5); + registry.fill(HIST("h_jeth_event_stats"), 5, weight); double deta = track.eta() - jet.eta(); double dphi = track.phi() - jet.phi(); dphi = RecoDecay::constrainAngle(dphi, -PIHalf); @@ -631,16 +621,16 @@ struct ChargedJetHadron { //.......mixed events................................. template - void fillMixJetHadronHistograms(const TCollisions& collisions, const TJets& jets, const TTracks& tracks, float weight = 1.0) + void fillMixJetHadronHistograms(const TCollisions& collisions, const TJets& jets, const TTracks& tracks) { using TracksTable = std::decay_t; auto tracksTuple = std::make_tuple(jets, tracks); Pair pairData{corrBinning, numberEventsMixed, -1, collisions, tracksTuple, &cache}; //// -1 is the number of the bin to skip for (const auto& [c1, jets1, c2, tracks2] : pairData) { - weight = doEventWeighted ? c1.weight() : 1.f; - const float pTHat = 10.f / std::pow(weight, 1.f / pTHatExponent); - registry.fill(HIST("h_mixjeth_event_stats"), 1); + const float weight = doEventWeighted ? c1.weight() : 1.f; + const float pTHat = doEventWeighted ? 10.f / std::pow(weight, 1.f / pTHatExponent) : 999.f; + registry.fill(HIST("h_mixjeth_event_stats"), 1, weight); if (!isGoodCollision(c1) || !isGoodCollision(c2)) continue; for (auto const& jet : jets1) { @@ -649,19 +639,19 @@ struct ChargedJetHadron { } if (!isAcceptedJet(jet)) continue; // for pp Reason: Trying to dereference index with a wrong type in tracks_as for base target "JTracks" - if (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) + if (doEventWeighted && (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin)) continue; - registry.fill(HIST("h_mixjeth_event_stats"), 2); + registry.fill(HIST("h_mixjeth_event_stats"), 2, weight); double ptCorr = jet.pt() - jet.area() * c1.rho(); if (ptCorr < subleadingjetptMin) continue; - registry.fill(HIST("h_mixtrigjet_corrpt"), ptCorr); - registry.fill(HIST("h_mixjeth_event_stats"), 3); + registry.fill(HIST("h_mixtrigjet_corrpt"), ptCorr, weight); + registry.fill(HIST("h_mixjeth_event_stats"), 3, weight); for (auto const& track : tracks2) { - registry.fill(HIST("h_mixjeth_event_stats"), 4); + registry.fill(HIST("h_mixjeth_event_stats"), 4, weight); if (!jetderiveddatautilities::selectTrack(track, trackSelection)) continue; - registry.fill(HIST("h_mixjeth_event_stats"), 5); + registry.fill(HIST("h_mixjeth_event_stats"), 5, weight); double deta = track.eta() - jet.eta(); double dphi = track.phi() - jet.phi(); dphi = RecoDecay::constrainAngle(dphi, -PIHalf); @@ -684,16 +674,17 @@ struct ChargedJetHadron { if (!isAcceptedJet(jet, true)) { continue; } - if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) - return; - registry.fill(HIST("h_jeth_event_stats_part"), 2); + registry.fill(HIST("h_jeth_event_stats_part"), 1, weight); + if (doEventWeighted && (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin)) + continue; + registry.fill(HIST("h_jeth_event_stats_part"), 2, weight); double ptCorr = jet.pt() - jet.area() * mccollision.rho(); if (ptCorr < subleadingjetptMin) continue; - registry.fill(HIST("h_trigjet_corrpt_part"), ptCorr); - registry.fill(HIST("h_jeth_event_stats_part"), 3); + registry.fill(HIST("h_trigjet_corrpt_part"), ptCorr, weight); + registry.fill(HIST("h_jeth_event_stats_part"), 3, weight); for (auto const& particle : particles) { - registry.fill(HIST("h_jeth_event_stats_part"), 4); + registry.fill(HIST("h_jeth_event_stats_part"), 4, weight); double deta = particle.eta() - jet.eta(); double dphi = particle.phi() - jet.phi(); dphi = RecoDecay::constrainAngle(dphi, -PIHalf); @@ -704,16 +695,16 @@ struct ChargedJetHadron { } //......mixed events...................... template - void fillMCPMixJetHadronHistograms(const TmcCollisions& mccollisions, const TCollisions& collisions, const TJets& jets, const TParticles& particles, float weight = 1.0) + void fillMCPMixJetHadronHistograms(const TmcCollisions& mccollisions, const TCollisions& collisions, const TJets& jets, const TParticles& particles) { using ParticlesTable = std::decay_t; auto particlesTuple = std::make_tuple(jets, particles); Pair pairMCData{corrBinningMC, numberEventsMixed, -1, mccollisions, particlesTuple, &cache}; for (const auto& [c1, jets1, c2, particles2] : pairMCData) { - weight = doEventWeighted ? c1.weight() : 1.f; - const float pTHat = 10.f / std::pow(weight, 1.f / pTHatExponent); - registry.fill(HIST("h_mixjeth_event_stats_part"), 1); + const float weight = doEventWeighted ? c1.weight() : 1.f; + const float pTHat = doEventWeighted ? 10.f / std::pow(weight, 1.f / pTHatExponent) : 999.f; + registry.fill(HIST("h_mixjeth_event_stats_part"), 1, weight); if (!applyMCCollisionCuts(c1, collisions) || !applyMCCollisionCuts(c2, collisions)) continue; @@ -722,18 +713,18 @@ struct ChargedJetHadron { continue; if (!isAcceptedJet(jet, true)) continue; - if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) - return; - registry.fill(HIST("h_mixjeth_event_stats_part"), 2); + if (doEventWeighted && (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin)) + continue; + registry.fill(HIST("h_mixjeth_event_stats_part"), 2, weight); double ptCorr = jet.pt() - jet.area() * c1.rho(); if (ptCorr < subleadingjetptMin) continue; - registry.fill(HIST("h_mixtrigjet_corrpt_part"), ptCorr); - registry.fill(HIST("h_mixjeth_event_stats_part"), 3); + registry.fill(HIST("h_mixtrigjet_corrpt_part"), ptCorr, weight); + registry.fill(HIST("h_mixjeth_event_stats_part"), 3, weight); for (auto const& particle : particles2) { - registry.fill(HIST("h_mixjeth_event_stats_part"), 4); + registry.fill(HIST("h_mixjeth_event_stats_part"), 4, weight); double deta = particle.eta() - jet.eta(); double dphi = particle.phi() - jet.phi(); dphi = RecoDecay::constrainAngle(dphi, -PIHalf); @@ -751,7 +742,7 @@ struct ChargedJetHadron { void fillLeadingJetHadronHistograms(const TCollision& collision, const TJets& jets, const TTracks& tracks, float weight = 1.0, float pTHat = 999.0) { using TracksTable = std::decay_t; - registry.fill(HIST("h_centrality"), getCentrality(collision)); + registry.fill(HIST("h_centrality"), getCentrality(collision), weight); typename TJets::iterator leadingJet; typename TJets::iterator subleadingJet; bool hasLeading = false; @@ -767,7 +758,7 @@ struct ChargedJetHadron { continue; if (!isAcceptedJet(jet)) continue; - if (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) + if (doEventWeighted && (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin)) continue; double ptCorr = jet.pt() - jet.area() * collision.rho(); registry.fill(HIST("h_inclusivejet_corrpt"), ptCorr, weight); @@ -800,7 +791,7 @@ struct ChargedJetHadron { double etaJet2Raw = subleadingJet.eta(); double multEta1Eta2 = etaJet1Raw * etaJet2Raw; double deltaEtaJetsNoflip = etaJet1Raw - etaJet2Raw; - double inverse = (etaJet1Raw > 0) ? 1.0 : -1.0; // Dr.Yang suggestion + double inverse = (etaJet1Raw > 0) ? 1.0 : -1.0; // eta-side convention double flip = (etaJet1Raw > etaJet2Raw) ? 1.0 : -1.0; double etajet1 = flip * etaJet1Raw; // leading jet eta after flip double etajet2 = flip * etaJet2Raw; // subleading jet eta after flip @@ -825,12 +816,12 @@ struct ChargedJetHadron { registry.fill(HIST("h2_dijet_TimeEtaLess0_pt"), ptLeadingCorr, ptSubleadingCorr, weight); for (const auto& constituent : leadingJet.template tracks_as()) { - registry.fill(HIST("h2_leadjet_corrpt_constituent_pt"), ptLeadingCorr, constituent.pt(), weight); + registry.fill(HIST("h_leadjet_constituent_pt"), constituent.pt(), weight); if (constituent.pt() > leadingJetLeadingConstPt) leadingJetLeadingConstPt = constituent.pt(); } for (const auto& constituent : subleadingJet.template tracks_as()) { - registry.fill(HIST("h2_subleadjet_corrpt_constituent_pt"), ptSubleadingCorr, constituent.pt(), weight); + registry.fill(HIST("h_subleadjet_constituent_pt"), constituent.pt(), weight); if (constituent.pt() > subleadingJetLeadingConstPt) subleadingJetLeadingConstPt = constituent.pt(); } @@ -841,7 +832,7 @@ struct ChargedJetHadron { if (!jetderiveddatautilities::selectTrack(track, trackSelection)) continue; double hpt = track.pt(); - double heta = inverse * (track.eta()); // Dr.Yang + double heta = inverse * (track.eta()); // eta-side convention double detatot = track.eta() - etaJet1Raw; double deta = flip * (track.eta() - etaJet1Raw); // always relative to leadingJet (after flip) double dphi = track.phi() - leadingJet.phi(); @@ -854,7 +845,7 @@ struct ChargedJetHadron { // registry.fill(HIST("thn_ljeth_correlations"), ptLeadingCorr, ptSubleadingCorr, multEta1Eta2, deltaEtaJetsNoflip, weight); if (doDijetEta) { registry.fill(HIST("thn_ljeth_correlations"), ptLeadingCorr, ptSubleadingCorr, hpt, multEta1Eta2, heta, dphi, weight); - if (hpt >= assoHadronPtMin && hpt < assoHadronPtMax && multEta1Eta2 > 0) + if (hpt >= assoHadronPtMin && hpt < assoHadronPtMax && multEta1Eta2 < 0) registry.fill(HIST("h2_jeth_heta_dphi"), heta, dphi, weight); } else { registry.fill(HIST("thn_ljeth_correlations"), ptLeadingCorr, ptSubleadingCorr, hpt, deltaEtaJets, deta, dphi, weight); @@ -888,8 +879,8 @@ struct ChargedJetHadron { continue; if (!isAcceptedJet(jet, true)) continue; - if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) - return; + if (doEventWeighted && (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin)) + continue; double ptCorr = jet.pt() - jet.area() * mccollision.rho(); registry.fill(HIST("h_inclusivejet_corrpt_part"), ptCorr, weight); @@ -918,7 +909,7 @@ struct ChargedJetHadron { double etaJet2Raw = subleadingJet.eta(); double multEta1Eta2 = etaJet1Raw * etaJet2Raw; double deltaEtaJetsNoflip = etaJet1Raw - etaJet2Raw; - double inverse = (etaJet1Raw > 0) ? 1.0 : -1.0; // Dr.Yang suggestion + double inverse = (etaJet1Raw > 0) ? 1.0 : -1.0; // eta-side convention double flip = (etaJet1Raw > etaJet2Raw) ? 1.0 : -1.0; double etajet1 = flip * etaJet1Raw; // leading jet eta after flip double etajet2 = flip * etaJet2Raw; // subleading jet eta after flip @@ -944,7 +935,7 @@ struct ChargedJetHadron { for (auto const& particle : particles) { double hpt = particle.pt(); - double heta = inverse * particle.eta(); // Dr.Yang + double heta = inverse * particle.eta(); // eta-side convention double detatot = particle.eta() - etaJet1Raw; double deta = flip * (particle.eta() - etaJet1Raw); // always relative to leadingJet (after flip) double dphi = particle.phi() - leadingJet.phi(); @@ -956,7 +947,7 @@ struct ChargedJetHadron { registry.fill(HIST("h_jeth_dphi_part"), dphi, weight); if (doDijetEta) { registry.fill(HIST("thn_ljeth_correlations_part"), ptLeadingCorr, ptSubleadingCorr, hpt, multEta1Eta2, heta, dphi, weight); - if (hpt >= assoHadronPtMin && hpt < assoHadronPtMax && multEta1Eta2 > 0) + if (hpt >= assoHadronPtMin && hpt < assoHadronPtMax && multEta1Eta2 < 0) registry.fill(HIST("h2_jeth_heta_dphi_part"), heta, dphi, weight); } else { registry.fill(HIST("thn_ljeth_correlations_part"), ptLeadingCorr, ptSubleadingCorr, hpt, deltaEtaJets, deta, dphi, weight); @@ -974,14 +965,11 @@ struct ChargedJetHadron { // ========================================================== //..........hadron-triggered recoil-jet - hadron correlations. - //..........suggestion test: replace Jet1 by trigger track. // ========================================================== template - void fillHadronJetHadronHistograms(const TCollision& collision, const TJets& jets, const TTracks& tracks, float weight = 1.0) + void fillHadronJetHadronHistograms(const TCollision& collision, const TJets& jets, const TTracks& tracks, float weight = 1.0, float pTHat = 999.0) { - float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); using TracksTable = std::decay_t; - // ----- Step 1: find leading trigger track, not leading jet ----- typename TTracks::iterator triggerTrack; bool hasTriggerTrack = false; @@ -1007,21 +995,18 @@ struct ChargedJetHadron { typename TJets::iterator recoilJet; bool hasRecoilJet = false; double ptRecoilCorr = -999.0; - for (auto it = jets.begin(); it != jets.end(); ++it) { const auto& jet = *it; if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) continue; if (!isAcceptedJet(jet)) continue; - if (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) + if (doEventWeighted && (jet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin)) continue; - double dphiHJ = phiTrig - jet.phi(); dphiHJ = RecoDecay::constrainAngle(dphiHJ, -PIHalf); if (std::abs(dphiHJ) < dijetDphiCut * PI) continue; - registry.fill(HIST("h_hjet_dphi"), dphiHJ, weight); double ptCorr = jet.pt() - jet.area() * collision.rho(); if (ptCorr > ptRecoilCorr) { recoilJet = it; @@ -1038,16 +1023,18 @@ struct ChargedJetHadron { double phiRecoil = recoilJet.phi(); double multEtaHJet = etaTrigRaw * etaRecoilRaw; double inverse = (etaTrigRaw > 0) ? 1.0 : -1.0; + double deltaPhiHJet = phiTrig - phiRecoil; + deltaPhiHJet = RecoDecay::constrainAngle(deltaPhiHJet, -PIHalf); registry.fill(HIST("h_hjet_trigtrack_pt"), ptTrig, weight); registry.fill(HIST("h_hjet_trigtrack_eta"), etaTrigRaw, weight); registry.fill(HIST("h_hjet_trigtrack_phi"), phiTrig, weight); registry.fill(HIST("h_hjet_recoiljet_corrpt"), ptRecoilCorr, weight); registry.fill(HIST("h_hjet_recoiljet_eta"), etaRecoilRaw, weight); registry.fill(HIST("h_hjet_recoiljet_phi"), phiRecoil, weight); + registry.fill(HIST("h_hjet_dphi"), deltaPhiHJet, weight); for (const auto& constituent : recoilJet.template tracks_as()) { - registry.fill(HIST("h2_recojet_corrpt_constituent_pt"), ptRecoilCorr, constituent.pt(), weight); + registry.fill(HIST("h_recojet_constituent_pt"), constituent.pt(), weight); } - if (multEtaHJet > 0) registry.fill(HIST("h2_hjet_TimeEtaThan0_pt"), ptTrig, ptRecoilCorr, weight); else if (multEtaHJet < 0) @@ -1066,14 +1053,105 @@ struct ChargedJetHadron { double heta = inverse * track.eta(); double dphi = track.phi() - phiTrig; dphi = RecoDecay::constrainAngle(dphi, -PIHalf); - if (hpt >= assoHadronPtMin && hpt < assoHadronPtMax && multEtaHJet > 0) + if (hpt >= assoHadronPtMin && hpt < assoHadronPtMax && multEtaHJet < 0) registry.fill(HIST("h2_hjet_heta_dphi"), heta, dphi, weight); registry.fill(HIST("thn_hjeth_correlations"), ptTrig, ptRecoilCorr, hpt, multEtaHJet, heta, dphi, weight); } } // ========================================================== - //.............process staring............................... + //.............di-hadron - hadron correlations............... + // ========================================================== + template + void fillDiHadronHistograms(const TCollision&, const TTracks& tracks, float weight = 1.0, float pTHat = 999.0) + { + if (doEventWeighted && (pTHat < pTHatAbsoluteMin)) + return; + // ----- Step 1: find the leading trigger hadron ----- + typename TTracks::iterator leadingHadron; + typename TTracks::iterator subleadingHadron; + double deltaPhiTriggers = 0.0; + bool hasLeadingHadron = false; + bool hasSubleadingHadron = false; + double ptLeadingHadron = -1.0; + double ptSubleadingHadron = -1.0; + + for (auto it = tracks.begin(); it != tracks.end(); ++it) { + const auto& track = *it; + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) + continue; + if (track.pt() < triggerHadronPtMin) + continue; + if (track.pt() > ptLeadingHadron) { + leadingHadron = it; + ptLeadingHadron = track.pt(); + hasLeadingHadron = true; + } + } + if (!hasLeadingHadron) + return; + const double etaLeadingRaw = leadingHadron.eta(); + const double phiLeading = leadingHadron.phi(); + + // ----- Step 2: find the highest-pT away-side recoil hadron ----- + for (auto it = tracks.begin(); it != tracks.end(); ++it) { + const auto& track = *it; + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) + continue; + if (track.globalIndex() == leadingHadron.globalIndex()) + continue; + if (track.pt() < subleadingHadronPtMin) + continue; + double dphi = phiLeading - track.phi(); + dphi = RecoDecay::constrainAngle(dphi, -PIHalf); + if (std::abs(dphi) < dijetDphiCut * PI) + continue; + if (track.pt() > ptSubleadingHadron) { + subleadingHadron = it; + ptSubleadingHadron = track.pt(); + deltaPhiTriggers = dphi; + hasSubleadingHadron = true; + } + } + if (!hasSubleadingHadron) + return; + const double etaSubleadingRaw = subleadingHadron.eta(); + const double phiSubleading = subleadingHadron.phi(); + const double multEtaHadron = etaLeadingRaw * etaSubleadingRaw; + const double inverse = (etaLeadingRaw > 0.0) ? 1.0 : -1.0; + + registry.fill(HIST("h_dihadron_leadtrack_pt"), ptLeadingHadron, weight); + registry.fill(HIST("h_dihadron_leadtrack_eta"), etaLeadingRaw, weight); + registry.fill(HIST("h_dihadron_leadtrack_phi"), phiLeading, weight); + registry.fill(HIST("h_dihadron_subleadtrack_pt"), ptSubleadingHadron, weight); + registry.fill(HIST("h_dihadron_subleadtrack_eta"), etaSubleadingRaw, weight); + registry.fill(HIST("h_dihadron_subleadtrack_phi"), phiSubleading, weight); + registry.fill(HIST("h_dihadron_dphi"), std::abs(deltaPhiTriggers), weight); + if (multEtaHadron > 0.0) + registry.fill(HIST("h2_dihadron_TimeEtaThan0_pt"), ptLeadingHadron, ptSubleadingHadron, weight); + else if (multEtaHadron < 0.0) + registry.fill(HIST("h2_dihadron_TimeEtaLess0_pt"), ptLeadingHadron, ptSubleadingHadron, weight); + + // ----- Step 3: associated hadrons relative to the leading-hadron axis ----- + for (auto const& track : tracks) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) + continue; + if (track.globalIndex() == leadingHadron.globalIndex() || track.globalIndex() == subleadingHadron.globalIndex()) + continue; + const double hpt = track.pt(); + if (hpt > assoHadronPtMaxCut) + continue; + const double heta = inverse * track.eta(); + double dphi = track.phi() - phiLeading; + dphi = RecoDecay::constrainAngle(dphi, -PIHalf); + if (hpt >= assoHadronPtMin && hpt < assoHadronPtMax && multEtaHadron < 0.0) + registry.fill(HIST("h2_dihadron_heta_dphi"), heta, dphi, weight); + registry.fill(HIST("thn_dihadron_correlations"), ptLeadingHadron, ptSubleadingHadron, hpt, multEtaHadron, heta, dphi, weight); + } + } + + // ========================================================== + //.............process starting............................... // ========================================================== void processCollisionsQCData(aod::JetCollision const& collision, FilterJetTracks const& tracks) @@ -1128,7 +1206,7 @@ struct ChargedJetHadron { return; fillLeadingJetHadronHistograms(collision, jets, tracks); } - PROCESS_SWITCH(ChargedJetHadron, processLeadingJetHadron, "same event subleading jet-h for Data", false); + PROCESS_SWITCH(ChargedJetHadron, processLeadingJetHadron, "same event leading jet-h for Data", false); void processHadronJetHadron(FilterCollision const& collision, CorrChargedJets const& jets, @@ -1138,7 +1216,16 @@ struct ChargedJetHadron { return; fillHadronJetHadronHistograms(collision, jets, tracks); } - PROCESS_SWITCH(ChargedJetHadron, processHadronJetHadron, "same event h-jet-hadron correlations for Data", false); + PROCESS_SWITCH(ChargedJetHadron, processHadronJetHadron, "same event hjet-hadron correlations for Data", false); + + void processDiHadron(FilterCollision const& collision, + FilterJetTracks const& tracks) + { + if (!isGoodCollision(collision)) + return; + fillDiHadronHistograms(collision, tracks); + } + PROCESS_SWITCH(ChargedJetHadron, processDiHadron, "same event di-hadron correlations for Data", false); void processJetHadron(FilterCollision const& collision, CorrChargedJets const& jets, @@ -1160,37 +1247,6 @@ struct ChargedJetHadron { } PROCESS_SWITCH(ChargedJetHadron, processMixJetHadron, "mixed event jet-h for Data", false); - //...HF jet correlations.................... - void processHFJetCorrelation(FilterCollision const& collision, - CorrChargedJets const& jets, - aod::CandidatesD0Data const& candidates) - { - if (!isGoodCollision(collision)) - return; - for (const auto& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { - continue; - } - registry.fill(HIST("h_d0jet_pt"), jet.pt()); - registry.fill(HIST("h_d0jet_corrpt"), jet.pt() - collision.rho() * jet.area()); - registry.fill(HIST("h_d0jet_eta"), jet.eta()); - registry.fill(HIST("h_d0jet_phi"), jet.phi()); - } - for (const auto& candidate : candidates) { - registry.fill(HIST("h_d0_mass"), candidate.m()); - registry.fill(HIST("h_d0_pt"), candidate.pt()); - registry.fill(HIST("h_d0_eta"), candidate.eta()); - registry.fill(HIST("h_d0_phi"), candidate.phi()); - for (const auto& jet : jets) { - double deltaeta = candidate.eta() - jet.eta(); - double deltaphi = candidate.phi() - jet.phi(); - deltaphi = RecoDecay::constrainAngle(deltaphi, -PIHalf); - registry.fill(HIST("h2_d0jet_detadphi"), deltaeta, deltaphi); - } - } - } - PROCESS_SWITCH(ChargedJetHadron, processHFJetCorrelation, "D0-jet for Data", false); - //........MCD.................................................. void processCollisionsQCMCD(soa::Join::iterator const& collision, FilterJetTracks const& tracks) @@ -1216,11 +1272,17 @@ struct ChargedJetHadron { registry.fill(HIST("h_collisions_weighted"), 3.5, eventWeight); registry.fill(HIST("h2_centrality_occupancy"), getCentrality(collision), collision.trackOccupancyInTimeRange(), eventWeight); registry.fill(HIST("h_collisions_zvertex"), collision.posZ(), eventWeight); + registry.fill(HIST("h_collisions_multFT0"), getMultiplicity(collision), eventWeight); + const float pTHat = doEventWeighted ? collision.mcCollision().ptHard() : 999.f; + if (doEventWeighted) { + registry.fill(HIST("h_coll_phat"), pTHat); + registry.fill(HIST("h_coll_phat_weighted"), pTHat, eventWeight); + } for (auto const& track : tracks) { if (!jetderiveddatautilities::selectTrack(track, trackSelection)) continue; - fillTrackHistograms(track, eventWeight, collision.mcCollision().ptHard()); + fillTrackHistograms(track, eventWeight); } } PROCESS_SWITCH(ChargedJetHadron, processCollisionsQCMCD, "QC of collisions and tracks for MCD", false); @@ -1230,6 +1292,7 @@ struct ChargedJetHadron { aod::JetTracks const&) { const float eventWeight = doEventWeighted ? collision.weight() : 1.f; + const float pTHat = doEventWeighted ? collision.mcCollision().ptHard() : 999.f; if (!isGoodCollision(collision)) return; for (auto const& jet : jets) { @@ -1239,8 +1302,8 @@ struct ChargedJetHadron { if (!isAcceptedJet(jet)) { continue; } - fillJetHistograms(jet, eventWeight, collision.mcCollision().ptHard()); - fillJetAreaSubHistograms(jet, collision.rho(), eventWeight, collision.mcCollision().ptHard()); + fillJetHistograms(jet, eventWeight, pTHat); + fillJetAreaSubHistograms(jet, collision.rho(), eventWeight, pTHat); } } PROCESS_SWITCH(ChargedJetHadron, processSpectraAreaSubMCD, "jet spectra with rho-area subtraction for MCD", false); @@ -1250,36 +1313,49 @@ struct ChargedJetHadron { FilterJetTracks const& tracks) { const float eventWeight = doEventWeighted ? collision.weight() : 1.f; - if (!isGoodCollision(collision)) { + const float pTHat = doEventWeighted ? collision.mcCollision().ptHard() : 999.f; + if (!isGoodCollision(collision)) return; - } - fillLeadingJetHadronHistograms(collision, jets, tracks, eventWeight, collision.mcCollision().ptHard()); + fillLeadingJetHadronHistograms(collision, jets, tracks, eventWeight, pTHat); } PROCESS_SWITCH(ChargedJetHadron, processLeadingJetHadronMCD, "same event leading jet-hadron correlations for MCD", false); - void processHadronJetHadronMCD(FilterCollision const& collision, + void processHadronJetHadronMCD(FilterMcdCollision const& collision, CorrChargedMCDJets const& jets, FilterJetTracks const& tracks) { const float eventWeight = doEventWeighted ? collision.weight() : 1.f; + const float pTHat = doEventWeighted ? collision.mcCollision().ptHard() : 999.f; + if (!isGoodCollision(collision)) + return; + fillHadronJetHadronHistograms(collision, jets, tracks, eventWeight, pTHat); + } + PROCESS_SWITCH(ChargedJetHadron, processHadronJetHadronMCD, "same event hjet-hadron correlations for MCD", false); + + void processDiHadronMCD(FilterMcdCollision const& collision, + FilterJetTracks const& tracks) + { + const float eventWeight = doEventWeighted ? collision.weight() : 1.f; + const float pTHat = doEventWeighted ? collision.mcCollision().ptHard() : 999.f; if (!isGoodCollision(collision)) return; - fillHadronJetHadronHistograms(collision, jets, tracks, eventWeight); + fillDiHadronHistograms(collision, tracks, eventWeight, pTHat); } - PROCESS_SWITCH(ChargedJetHadron, processHadronJetHadronMCD, "same event h-jet-hadron correlations for MCD", false); + PROCESS_SWITCH(ChargedJetHadron, processDiHadronMCD, "same event di-hadron correlations for MCD", false); void processJetHadronMCD(FilterMcdCollision const& collision, CorrChargedMCDJets const& jets, FilterJetTracks const& tracks) { const float eventWeight = doEventWeighted ? collision.weight() : 1.f; + const float pTHat = doEventWeighted ? collision.mcCollision().ptHard() : 999.f; if (!isGoodCollision(collision)) return; - fillJetHadronHistograms(collision, jets, tracks, eventWeight, collision.mcCollision().ptHard()); + fillJetHadronHistograms(collision, jets, tracks, eventWeight, pTHat); } PROCESS_SWITCH(ChargedJetHadron, processJetHadronMCD, "same event jet-hadron correlations for MCD", false); - void processMixJetHadronMCD(FilterCollisions const& collisions, + void processMixJetHadronMCD(FilterMcdCollisions const& collisions, CorrChargedMCDJets const& jets, FilterJetTracks const& tracks) { @@ -1316,7 +1392,7 @@ struct ChargedJetHadron { registry.fill(HIST("h_mcpColl_centrality"), mccollision.centFT0M(), eventWeight); registry.fill(HIST("h_mcpColl_multFT0"), getMultiplicity(mccollision), eventWeight); for (auto const& particle : particles) { - fillParticleHistograms(particle, eventWeight, mccollision.ptHard()); + fillParticleHistograms(particle, eventWeight); } } PROCESS_SWITCH(ChargedJetHadron, processCollisionsQCMCP, "QC of collisions and particles for MCP", false); @@ -1328,13 +1404,14 @@ struct ChargedJetHadron { { bool mcLevelIsParticleLevel = true; const float eventWeight = doEventWeighted ? mccollision.weight() : 1.f; + const float pTHat = doEventWeighted ? mccollision.ptHard() : 999.f; if (!applyMCCollisionCuts(mccollision, collisions)) return; registry.fill(HIST("h_mcColl_rho"), mccollision.rho(), eventWeight); if (doEventWeighted) { - registry.fill(HIST("h_mcColl_counts_weight"), 1.5); - registry.fill(HIST("h_mcColl_counts_weight"), 2.5, mccollision.xsectGen()); - registry.fill(HIST("h_mcColl_counts_weight"), 3.5, eventWeight); + registry.fill(HIST("h_mcColl_counts_weight"), 1); + registry.fill(HIST("h_mcColl_counts_weight"), 2, mccollision.xsectGen()); + registry.fill(HIST("h_mcColl_counts_weight"), 3, eventWeight); } for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -1343,8 +1420,8 @@ struct ChargedJetHadron { if (!isAcceptedJet(jet, mcLevelIsParticleLevel)) { continue; } - fillMCPHistograms(jet, eventWeight, mccollision.ptHard()); - fillMCPAreaSubHistograms(jet, mccollision.rho(), eventWeight, mccollision.ptHard()); + fillMCPJetHistograms(jet, eventWeight, pTHat); + fillMCPJetAreaSubHistograms(jet, mccollision.rho(), eventWeight, pTHat); } } PROCESS_SWITCH(ChargedJetHadron, processSpectraAreaSubMCP, "jet spectra without and with UE subtraction of area-based for MCP", false); @@ -1355,10 +1432,11 @@ struct ChargedJetHadron { soa::Filtered const& particles) { const float eventWeight = doEventWeighted ? mccollision.weight() : 1.f; + const float pTHat = doEventWeighted ? mccollision.ptHard() : 999.f; if (!applyMCCollisionCuts(mccollision, collisions)) return; - fillMCPLeadingJetHadronHistograms(mccollision, jets, particles, eventWeight, mccollision.ptHard()); + fillMCPLeadingJetHadronHistograms(mccollision, jets, particles, eventWeight, pTHat); } PROCESS_SWITCH(ChargedJetHadron, processLeadingJetHadronMCP, "same event leading jet-hadron for MCP", false); @@ -1368,10 +1446,11 @@ struct ChargedJetHadron { soa::Filtered const& particles) { const float eventWeight = doEventWeighted ? mccollision.weight() : 1.f; + const float pTHat = doEventWeighted ? mccollision.ptHard() : 999.f; if (!applyMCCollisionCuts(mccollision, collisions)) return; - fillMCPJetHadronHistograms(mccollision, jets, particles, eventWeight, mccollision.ptHard()); + fillMCPJetHadronHistograms(mccollision, jets, particles, eventWeight, pTHat); } PROCESS_SWITCH(ChargedJetHadron, processJetHadronMCP, "same event jet-hadron for MCP", false); diff --git a/PWGJE/Tasks/jetChargedV2.cxx b/PWGJE/Tasks/jetChargedV2.cxx index 602e896bc18..e52154196e6 100644 --- a/PWGJE/Tasks/jetChargedV2.cxx +++ b/PWGJE/Tasks/jetChargedV2.cxx @@ -103,9 +103,11 @@ struct JetChargedV2 { //=====================< evt pln >=====================// Configurable> cfgnMods{"cfgnMods", {2}, "Modulation of interest"}; Configurable cfgnTotalSystem{"cfgnTotalSystem", 7, "total qvector number"}; - Configurable cfgDetName{"cfgDetName", "FT0M", "The name of detector to be analyzed"}; + Configurable cfgDetName{"cfgDetName", "FT0C", "The name of detector to be analyzed"}; + Configurable cfgDetCheckName{"cfgDetCheckName", "FT0M", "The name of detector to be analyzed"}; Configurable cfgRefAName{"cfgRefAName", "TPCpos", "The name of detector for reference A"}; Configurable cfgRefBName{"cfgRefBName", "TPCneg", "The name of detector for reference B"}; + Configurable detCheck{"detCheck", 4, "total qvector number"}; ConfigurableAxis cfgAxisQvecF{"cfgAxisQvecF", {300, -1, 1}, ""}; ConfigurableAxis cfgAxisQvec{"cfgAxisQvec", {100, -3, 3}, ""}; @@ -118,6 +120,7 @@ struct JetChargedV2 { int detId; int refAId; int refBId; + int detIdCheck; //=====================< jetSpectraConfig to this analysis >=====================// Configurable acceptSplitCollisions{"acceptSplitCollisions", 0, "0: only look at mcCollisions that are not split; 1: accept split mcCollisions, 2: accept split mcCollisions but only look at the first reco collision associated with it"}; @@ -182,11 +185,13 @@ struct JetChargedV2 { void init(o2::framework::InitContext&) { detId = getDetId(cfgDetName); + detIdCheck = getDetId(cfgDetCheckName); refAId = getDetId(cfgRefAName); refBId = getDetId(cfgRefBName); - if (detId == refAId || detId == refBId || refAId == refBId) { + if (detId == refAId || detId == refBId || refAId == refBId || detId == detIdCheck) { LOGF(info, "Wrong detector configuration \n The FT0C will be used to get Q-Vector \n The TPCpos and TPCneg will be used as reference systems"); detId = 0; + detIdCheck = 0; refAId = 4; refBId = 5; } @@ -307,12 +312,18 @@ struct JetChargedV2 { histosQA.add(Form("histEvtPlTwistV%d", cfgnMods->at(i)), "", {HistType::kTH2F, {axisEvtPl, axisCent}}); histosQA.add(Form("histEvtPlFinalV%d", cfgnMods->at(i)), "", {HistType::kTH2F, {axisEvtPl, axisCent}}); + histosQA.add(Form("h_ep2_FT0CV%d", cfgnMods->at(i)), "", {HistType::kTH2F, {axisEvtPl, axisCent}}); + histosQA.add(Form("h_ep2_FT0MV%d", cfgnMods->at(i)), "", {HistType::kTH2F, {axisEvtPl, axisCent}}); + histosQA.add(Form("histEvtPlRes_SigRefAV%d", cfgnMods->at(i)), "", {HistType::kTH2F, {axisEvtPl, axisCent}}); histosQA.add(Form("histEvtPlRes_SigRefBV%d", cfgnMods->at(i)), "", {HistType::kTH2F, {axisEvtPl, axisCent}}); histosQA.add(Form("histEvtPlRes_RefARefBV%d", cfgnMods->at(i)), "", {HistType::kTH2F, {axisEvtPl, axisCent}}); } histosQA.add("histCent", "Centrality TrkProcess", HistType::kTH1F, {axisCent}); + histosQA.add("h2_ep2_FT0C_FT0M", "event_plane_FT0C_FT0M; FT0C; FT0M; cent", {HistType::kTH3F, {{100, -o2::constants::math::PIHalf, o2::constants::math::PIHalf}, {100, -o2::constants::math::PIHalf, o2::constants::math::PIHalf}, {100, 0.0, 100.0}}}); + histosQA.add("h2_ep2_FT0C_FT0M_bumpRegion", "event_plane_FT0C_FT0M_bumpRegion; FT0C; FT0M; cent", {HistType::kTH3F, {{100, -o2::constants::math::PIHalf, o2::constants::math::PIHalf}, {100, -o2::constants::math::PIHalf, o2::constants::math::PIHalf}, {100, 0.0, 100.0}}}); + //< fit quality >// registry.add("h_PvalueCDF_CombinFit", "cDF #chi^{2}; entries", {HistType::kTH1F, {{50, 0, 1}}}); registry.add("h2_PvalueCDFCent_CombinFit", "p-value cDF vs centrality; centrality; p-value", {HistType::kTH2F, {{100, 0, 100}, {40, 0, 1}}}); @@ -330,15 +341,39 @@ struct JetChargedV2 { registry.add("h_fitparaPsi2_evtnum", "fitparameter #Psi_{2} vs evtnum ; #eventnumber", {HistType::kTH1F, {{1000, 0.0, 1000}}}); registry.add("h_fitparaPsi3_evtnum", "fitparameter #Psi_{3} vs evtnum ; #eventnumber", {HistType::kTH1F, {{1000, 0.0, 1000}}}); registry.add("h_evtnum_centrlity", "eventNumber vs centrality ; #eventNumber", {HistType::kTH1F, {{1000, 0.0, 1000}}}); - registry.add("h_badfit_counter", "bad fit para[1] count; #eventNumber", {HistType::kTH1F, {{5, 0.0, 5}}}); registry.add("h2_phi_rholocal", "#varphi vs #rho(#varphi); #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); - registry.add("h2_phi_rholocal_absDelta", "#varphi vs #rho(#varphi), absDelta; #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); - - registry.add("h2_rholocal_cent", "#varphi vs #rho(#varphi); #cent; #rho(#varphi) ", {HistType::kTH2F, {{100, 0., 100}, {210, -10.0, 200.0}}}); + registry.add("h2_phi_rholocal_absDelta", "#varphi vs #rho(#varphi)absDelta, absDelta; #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); + registry.add("h2_centrality_pT", "centrality vs p_{T}; p_{T}; centrality ", {HistType::kTH2F, {{210, -10.0, 200.0}, {100, 0., 100}}}); + + registry.add("h2_rholocal_cent", "#centrality vs #rho(#varphi); #centrality; #rho(#varphi) ", {HistType::kTH2F, {{100, 0., 100}, {210, -10.0, 200.0}}}); + registry.add("h2_averagerho_cent", "#centrality vs #rho; #centrality; #rho ", {HistType::kTH2F, {{100, 0., 100}, {210, -10.0, 200.0}}}); + + registry.add("h2_rholocal_pt", "#varphi vs #it{p}_{T}; #it{p}_{T}; #rho(#varphi) ", {HistType::kTH2F, {{100, 0., 100}, {210, -10.0, 200.0}}}); + registry.add("h2_rholocal_raw_pt", "#varphi vs #it{p}_{T}; #it{p}_{T} - #rhoArea; #rho(#varphi) ", {HistType::kTH2F, {{100, 0., 100}, {210, -10.0, 200.0}}}); + registry.add("h2_rholocal_pt_inplane", "#varphi vs #it{p}_{T}; #it{p}_{T}; #rho(#varphi) ", {HistType::kTH2F, {{100, 0., 100}, {210, -10.0, 200.0}}}); + registry.add("h2_rholocal_pt_outplane", "#varphi vs #it{p}_{T}; #it{p}_{T}; #rho(#varphi) ", {HistType::kTH2F, {{100, 0., 100}, {210, -10.0, 200.0}}}); + + registry.add("h2_phi_averagerho_absDelta", "#varphi vs #rho(0)absDelta, absDelta; #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); + registry.add("h2_averagerho_pt", "#varphi vs #it{p}_{T}; #it{p}_{T}; <#rho> ", {HistType::kTH2F, {{100, 0., 100}, {210, -10.0, 200.0}}}); + registry.add("h2_averagerho_raw_pt", "#varphi vs #it{p}_{T}; #it{p}_{T} - <#rho>Area; <#rho> ", {HistType::kTH2F, {{100, 0., 100}, {210, -10.0, 200.0}}}); + registry.add("h2_averagerho_pt_inplane", "#varphi vs #it{p}_{T}; #it{p}_{T}; <#rho> ", {HistType::kTH2F, {{100, 0., 100}, {210, -10.0, 200.0}}}); + registry.add("h2_averagerho_pt_outplane", "#varphi vs #it{p}_{T}; #it{p}_{T}; <#rho> ", {HistType::kTH2F, {{100, 0., 100}, {210, -10.0, 200.0}}}); + + registry.add("h2_phi_rholocal_absDelta_low", "#varphi vs #rho(#varphi)absDeltaLow, absDelta; #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); + registry.add("h2_phi_rholocal_absDelta_medium", "#varphi vs #rho(#varphi)absDeltaMediun, absDelta; #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); + registry.add("h2_phi_rholocal_absDelta_high", "#varphi vs #rho(#varphi)absDeltahigh, absDelta; #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); + + registry.add("h2_phi_rholocal_absDelta_low_inplane", "#varphi vs #rho(#varphi)absDeltaLow inplane, absDelta; #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); + registry.add("h2_phi_rholocal_absDelta_medium_inplane", "#varphi vs #rho(#varphi)absDeltaMediun inplane, absDelta; #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); + registry.add("h2_phi_rholocal_absDelta_high_inplane", "#varphi vs #rho(#varphi)absDeltahigh inplane, absDelta; #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); + + registry.add("h2_phi_rholocal_absDelta_low_outplane", "#varphi vs #rho(#varphi)absDeltaLow outplane, absDelta; #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); + registry.add("h2_phi_rholocal_absDelta_medium_outplane", "#varphi vs #rho(#varphi)absDeltaMediun outplane, absDelta; #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); + registry.add("h2_phi_rholocal_absDelta_high_outplane", "#varphi vs #rho(#varphi)absDeltahigh outplane, absDelta; #varphi - #Psi_{EP,2}; #rho(#varphi) ", {HistType::kTH2F, {{40, 0., o2::constants::math::TwoPI}, {210, -10.0, 200.0}}}); //< \sigma p_T at local rho test plot | end > - registry.add("h_jet_pt_rhoareasubtracted", "jet pT rhoareasubtracted;#it{p}_{T,jet} (GeV/#it{c}); entries", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); + registry.add("h_jet_pt_inclusive_v2", "jet pT rhoareasubtracted;#it{p}_{T,jet} (GeV/#it{c}); entries", {HistType::kTH1F, {jetPtAxisRhoAreaSub}}); registry.add("leadJetPt", "leadJet Pt ", {HistType::kTH1F, {{200, 0., 200.0}}}); registry.add("leadJetPhi", "leadJet constituent #phi ", {HistType::kTH1F, {{80, -1.0, 7.}}}); @@ -889,9 +924,7 @@ struct JetChargedV2 { temppara[2] = fFitModulationV2v3P->GetParameter(2); temppara[3] = fFitModulationV2v3P->GetParameter(3); temppara[4] = fFitModulationV2v3P->GetParameter(4); - if (temppara[0] == 0) { - registry.fill(HIST("h_badfit_counter"), 1); - } + registry.fill(HIST("h_mcp_fitparaRho_evtnum"), evtnum, temppara[0]); registry.fill(HIST("h_mcp_fitparaPsi2_evtnum"), evtnum, temppara[2]); registry.fill(HIST("h_mcp_fitparaPsi3_evtnum"), evtnum, temppara[4]); @@ -1239,6 +1272,7 @@ struct JetChargedV2 { for (uint i = 0; i < cfgnMods->size(); i++) { int nmode = cfgnMods->at(i); int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); + int detIndFT0M = (detIdCheck + 2) * 4 + cfgnTotalSystem * 4 * (nmode - 2); int refAInd = refAId * 4 + cfgnTotalSystem * 4 * (nmode - 2); int refBInd = refBId * 4 + cfgnTotalSystem * 4 * (nmode - 2); @@ -1254,6 +1288,11 @@ struct JetChargedV2 { histosQA.fill(HIST("histEvtPlTwistV2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2], nmode), collision.cent()); histosQA.fill(HIST("histEvtPlFinalV2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), collision.cent()); + // mark + histosQA.fill(HIST("h_ep2_FT0CV2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), collision.cent()); + histosQA.fill(HIST("h_ep2_FT0MV2"), helperEP.GetEventPlane(collision.qvecRe()[detIndFT0M + 3], collision.qvecIm()[detIndFT0M + 3], nmode), collision.cent()); + histosQA.fill(HIST("h2_ep2_FT0C_FT0M"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[detIndFT0M + 3], collision.qvecIm()[detIndFT0M + 3], nmode), collision.cent()); + histosQA.fill(HIST("histEvtPlRes_SigRefAV2"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], nmode), nmode), collision.cent()); histosQA.fill(HIST("histEvtPlRes_SigRefBV2"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode), collision.cent()); histosQA.fill(HIST("histEvtPlRes_RefARefBV2"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode), collision.cent()); @@ -1274,79 +1313,6 @@ struct JetChargedV2 { histosQA.fill(HIST("histEvtPlRes_RefARefBV3"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode), collision.cent()); } } - - float centrality = -1.0; - switch (centralityMode) { - case 1: - centrality = collision.centFT0M(); - break; - case 2: - centrality = collision.centFT0A(); - break; - default: - centrality = collision.centFT0C(); - break; - } - int evtPlnAngleA = 7; - int evtPlnAngleB = 3; - int evtPlnAngleC = 5; - for (uint i = 0; i < cfgnMods->size(); i++) { - int nmode = cfgnMods->at(i); - int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); - - if (nmode == cfgNmodA) { - double phiMinusPsi2; - if (collision.qvecAmp()[detId] < collQvecAmpDetId) { - continue; - } - float ep2 = helperEP.GetEventPlane(collision.qvecRe()[detInd], collision.qvecIm()[detInd], nmode); - for (auto const& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { - continue; - } - if (!isAcceptedJet(jet)) { - continue; - } - if (jet.r() != round(selectedJetsRadius * 100.0f)) { - continue; - } - registry.fill(HIST("h_jet_pt_rhoareasubtracted"), jet.pt() - (collision.rho() * jet.area()), 1.0); - - // phiMinusPsi2 = jet.phi() - ep2; - phiMinusPsi2 = RecoDecay::constrainAngle(jet.phi() - ep2, -o2::constants::math::PI); - float absDelta = std::abs(phiMinusPsi2); - if ((absDelta < o2::constants::math::PIQuarter) || (absDelta >= evtPlnAngleA * o2::constants::math::PIQuarter) || (absDelta >= evtPlnAngleB * o2::constants::math::PIQuarter && absDelta < evtPlnAngleC * o2::constants::math::PIQuarter)) { - registry.fill(HIST("h_jet_pt_in_plane_v2"), jet.pt() - (collision.rho() * jet.area()), 1.0); - registry.fill(HIST("h2_centrality_jet_pt_in_plane_v2"), centrality, jet.pt() - (collision.rho() * jet.area()), 1.0); - } else { - registry.fill(HIST("h_jet_pt_out_of_plane_v2"), jet.pt() - (collision.rho() * jet.area()), 1.0); - registry.fill(HIST("h2_centrality_jet_pt_out_of_plane_v2"), centrality, jet.pt() - (collision.rho() * jet.area()), 1.0); - } - } - } else if (nmode == cfgNmodB) { - double phiMinusPsi3; - float ep3 = helperEP.GetEventPlane(collision.qvecRe()[detInd], collision.qvecIm()[detInd], nmode); - for (auto const& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { - continue; - } - if (!isAcceptedJet(jet)) { - continue; - } - if (jet.r() != round(selectedJetsRadius * 100.0f)) { - continue; - } - // phiMinusPsi3 = jet.phi() - ep3; - phiMinusPsi3 = RecoDecay::constrainAngle(jet.phi() - ep3, -o2::constants::math::PI); - float absDelta3 = std::abs(phiMinusPsi3); - if ((absDelta3 < o2::constants::math::PIQuarter) || (absDelta3 >= evtPlnAngleA * o2::constants::math::PIQuarter) || (absDelta3 >= evtPlnAngleB * o2::constants::math::PIQuarter && absDelta3 < evtPlnAngleC * o2::constants::math::PIQuarter)) { - registry.fill(HIST("h_jet_pt_in_plane_v3"), jet.pt() - (collision.rho() * jet.area()), 1.0); - } else { - registry.fill(HIST("h_jet_pt_out_of_plane_v3"), jet.pt() - (collision.rho() * jet.area()), 1.0); - } - } - } - } } PROCESS_SWITCH(JetChargedV2, processInOutJetV2, "Jet V2 in and out of plane", false); @@ -1408,80 +1374,6 @@ struct JetChargedV2 { histosQA.fill(HIST("histEvtPlRes_RefARefBV3"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode), collision.cent()); } } - - float centrality = -1.0; - switch (centralityMode) { - case 1: - centrality = collision.centFT0M(); - break; - case 2: - centrality = collision.centFT0A(); - break; - default: - centrality = collision.centFT0C(); - break; - } - int evtPlnAngleA = 7; - int evtPlnAngleB = 3; - int evtPlnAngleC = 5; - for (uint i = 0; i < cfgnMods->size(); i++) { - int nmode = cfgnMods->at(i); - int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); - - if (nmode == cfgNmodA) { - double phiMinusPsi2; - if (collision.qvecAmp()[detId] < collQvecAmpDetId) { - continue; - } - float ep2 = helperEP.GetEventPlane(collision.qvecRe()[detInd], collision.qvecIm()[detInd], nmode); - for (auto const& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { - continue; - } - if (!isAcceptedJet(jet)) { - continue; - } - if (jet.r() != round(selectedJetsRadius * 100.0f)) { - continue; - } - registry.fill(HIST("h_jet_pt_rhoareasubtracted"), jet.pt() - (collision.rho() * jet.area()), 1.0); - - // phiMinusPsi2 = jet.phi() - ep2; - phiMinusPsi2 = RecoDecay::constrainAngle(jet.phi() - ep2, -o2::constants::math::PI); - float absDelta = std::abs(phiMinusPsi2); - if ((absDelta < o2::constants::math::PIQuarter) || (absDelta >= evtPlnAngleA * o2::constants::math::PIQuarter) || (absDelta >= evtPlnAngleB * o2::constants::math::PIQuarter && absDelta < evtPlnAngleC * o2::constants::math::PIQuarter)) { - registry.fill(HIST("h_jet_pt_in_plane_v2"), jet.pt() - (collision.rho() * jet.area()), 1.0); - registry.fill(HIST("h2_centrality_jet_pt_in_plane_v2"), centrality, jet.pt() - (collision.rho() * jet.area()), 1.0); - } else { - registry.fill(HIST("h_jet_pt_out_of_plane_v2"), jet.pt() - (collision.rho() * jet.area()), 1.0); - registry.fill(HIST("h2_centrality_jet_pt_out_of_plane_v2"), centrality, jet.pt() - (collision.rho() * jet.area()), 1.0); - } - } - } else if (nmode == cfgNmodB) { - double phiMinusPsi3; - float ep3 = helperEP.GetEventPlane(collision.qvecRe()[detInd], collision.qvecIm()[detInd], nmode); - for (auto const& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { - continue; - } - if (!isAcceptedJet(jet)) { - continue; - } - if (jet.r() != round(selectedJetsRadius * 100.0f)) { - continue; - } - // phiMinusPsi3 = jet.phi() - ep3; - phiMinusPsi3 = RecoDecay::constrainAngle(jet.phi() - ep3, -o2::constants::math::PI); - float absDelta3 = std::abs(phiMinusPsi3); - - if ((absDelta3 < o2::constants::math::PIQuarter) || (absDelta3 >= evtPlnAngleA * o2::constants::math::PIQuarter) || (absDelta3 >= evtPlnAngleB * o2::constants::math::PIQuarter && absDelta3 < evtPlnAngleC * o2::constants::math::PIQuarter)) { - registry.fill(HIST("h_jet_pt_in_plane_v3"), jet.pt() - (collision.rho() * jet.area()), 1.0); - } else { - registry.fill(HIST("h_jet_pt_out_of_plane_v3"), jet.pt() - (collision.rho() * jet.area()), 1.0); - } - } - } - } } PROCESS_SWITCH(JetChargedV2, processInOutJetV2MCD, "Jet V2 in and out of plane MCD", false); @@ -1539,6 +1431,7 @@ struct JetChargedV2 { for (uint i = 0; i < cfgnMods->size(); i++) { int nmode = cfgnMods->at(i); int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); + if (nmode == cfgNmodA) { if (collision.qvecAmp()[detId] > collQvecAmpDetId) { ep2 = helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode); @@ -1551,7 +1444,7 @@ struct JetChargedV2 { } const char* fitFunctionV2v3 = "[0] * (1. + 2. * ([1] * std::cos(2. * (x - [2])) + [3] * std::cos(3. * (x - [4]))))"; - fFitModulationV2v3 = new TF1("fit_kV3", fitFunctionV2v3, 0, o2::constants::math::TwoPI); + fFitModulationV2v3 = new TF1("fit_kV3", fitFunctionV2v3, -1, o2::constants::math::TwoPI + 1); //=========================< set parameter >=========================// fFitModulationV2v3->SetParameter(0, 1.); fFitModulationV2v3->SetParameter(1, 0.01); @@ -1589,10 +1482,6 @@ struct JetChargedV2 { registry.fill(HIST("h_v3obs_centrality"), centrality, temppara[3]); registry.fill(HIST("h_evtnum_centrlity"), evtnum, centrality); - if (temppara[0] == 0) { - registry.fill(HIST("h_badfit_counter"), 1); - } - int nDF = 1; int numOfFreePara = 2; nDF = static_cast(fFitModulationV2v3->GetXaxis()->GetNbins()) - numOfFreePara; @@ -1638,7 +1527,11 @@ struct JetChargedV2 { for (uint i = 0; i < cfgnMods->size(); i++) { int nmode = cfgnMods->at(i); int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); + int detIndFT0M = 4 * detCheck + cfgnTotalSystem * 4 * (nmode - 2); + int bumpLow = 75; + int bumpUp = 125; + bool hasBumpJet = false; for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { continue; @@ -1649,10 +1542,50 @@ struct JetChargedV2 { if (jet.r() != round(selectedJetsRadius * 100.0f)) { continue; } + if (jet.pt() > bumpLow && jet.pt() < bumpUp) { + hasBumpJet = true; + } + } + if (hasBumpJet && nmode == cfgNmodA) { + if (collision.qvecAmp()[detId] >= collQvecAmpDetId) { + histosQA.fill(HIST("h2_ep2_FT0C_FT0M_bumpRegion"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[detIndFT0M + 3], collision.qvecIm()[detIndFT0M + 3], nmode), collision.cent()); + } + } - double integralValue = fFitModulationV2v3->Integral(jet.phi() - selectedJetsRadius, jet.phi() + selectedJetsRadius); + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + if (!isAcceptedJet(jet)) { + continue; + } + if (jet.r() != round(selectedJetsRadius * 100.0f)) { + continue; + } + double twoPi = o2::constants::math::TwoPI; + double phi = std::fmod(jet.phi(), twoPi); + if (phi < 0) { + phi += twoPi; + } + + double low = phi - selectedJetsRadius; + double high = phi + selectedJetsRadius; + double integralValue = 0.0; + if (low < 0) { + integralValue += fFitModulationV2v3->Integral(low + twoPi, twoPi); + integralValue += fFitModulationV2v3->Integral(0, high); + } else if (high > twoPi) { + integralValue += fFitModulationV2v3->Integral(low, twoPi); + integralValue += fFitModulationV2v3->Integral(0, high - twoPi); + } else { + integralValue += fFitModulationV2v3->Integral(low, high); + } + if (integralValue < 0) { + integralValue = 0; + } + + // double integralValue = fFitModulationV2v3->Integral(phi - selectedJetsRadius, phi + selectedJetsRadius); double rholocal = collision.rho() / (2 * selectedJetsRadius * temppara[0]) * integralValue; - registry.fill(HIST("h2_rholocal_cent"), centrality, rholocal, 1.0); if (nmode == cfgNmodA) { double phiMinusPsi2; @@ -1662,15 +1595,64 @@ struct JetChargedV2 { // phiMinusPsi2 = jet.phi() - ep2; phiMinusPsi2 = RecoDecay::constrainAngle(jet.phi() - ep2, -o2::constants::math::PI); float absDelta = std::abs(phiMinusPsi2); + registry.fill(HIST("h2_rholocal_cent"), centrality, rholocal, 1.0); + registry.fill(HIST("h2_averagerho_cent"), centrality, collision.rho(), 1.0); + registry.fill(HIST("h2_centrality_pT"), jet.pt(), centrality, 1.0); + registry.fill(HIST("h2_phi_rholocal"), jet.phi() - ep2, rholocal, 1.0); registry.fill(HIST("h2_phi_rholocal_absDelta"), absDelta, rholocal, 1.0); + registry.fill(HIST("h2_phi_averagerho_absDelta"), absDelta, collision.rho(), 1.0); + + registry.fill(HIST("h2_rholocal_pt"), jet.pt(), rholocal, 1.0); + registry.fill(HIST("h2_rholocal_raw_pt"), jet.pt() - rholocal * jet.area(), rholocal, 1.0); + registry.fill(HIST("h2_averagerho_pt"), jet.pt(), collision.rho(), 1.0); + registry.fill(HIST("h2_averagerho_raw_pt"), jet.pt() - collision.rho() * jet.area(), collision.rho(), 1.0); + + int lowPtCut = 20; + int mediumPtCut = 40; + int highPtCut = 70; + int highPtCutEnd = 100; + + if (jet.pt() >= lowPtCut && jet.pt() < mediumPtCut) { + registry.fill(HIST("h2_phi_rholocal_absDelta_low"), absDelta, rholocal, 1.0); + } else if (jet.pt() >= mediumPtCut && jet.pt() < highPtCut) { + registry.fill(HIST("h2_phi_rholocal_absDelta_medium"), absDelta, rholocal, 1.0); + } else if (jet.pt() >= highPtCut && jet.pt() < highPtCutEnd) { + registry.fill(HIST("h2_phi_rholocal_absDelta_high"), absDelta, rholocal, 1.0); + } + registry.fill(HIST("h_jet_pt_inclusive_v2"), jet.pt() - (collision.rho() * jet.area()), 1.0); registry.fill(HIST("h_jet_pt_inclusive_v2_rho"), jet.pt() - (rholocal * jet.area()), 1.0); + + if (jet.pt() > bumpLow && jet.pt() < bumpUp) { + histosQA.fill(HIST("h2_ep2_FT0C_FT0M_bumpRegion"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[detIndFT0M + 3], collision.qvecIm()[detIndFT0M + 3], nmode), collision.cent()); + } + if ((absDelta < o2::constants::math::PIQuarter) || (absDelta >= evtPlnAngleA * o2::constants::math::PIQuarter) || (absDelta >= evtPlnAngleB * o2::constants::math::PIQuarter && absDelta < evtPlnAngleC * o2::constants::math::PIQuarter)) { + registry.fill(HIST("h_jet_pt_in_plane_v2"), jet.pt() - (collision.rho() * jet.area()), 1.0); + registry.fill(HIST("h2_centrality_jet_pt_in_plane_v2"), centrality, jet.pt() - (collision.rho() * jet.area()), 1.0); + registry.fill(HIST("h_jet_pt_in_plane_v2_rho"), jet.pt() - (rholocal * jet.area()), 1.0); registry.fill(HIST("h2_centrality_jet_pt_in_plane_v2_rho"), centrality, jet.pt() - (rholocal * jet.area()), 1.0); + + registry.fill(HIST("h2_phi_rholocal_absDelta_low_inplane"), absDelta, rholocal, 1.0); + registry.fill(HIST("h2_phi_rholocal_absDelta_medium_inplane"), absDelta, rholocal, 1.0); + registry.fill(HIST("h2_phi_rholocal_absDelta_high_inplane"), absDelta, rholocal, 1.0); + + registry.fill(HIST("h2_averagerho_pt_inplane"), jet.pt(), collision.rho(), 1.0); + registry.fill(HIST("h2_rholocal_pt_inplane"), jet.pt(), rholocal, 1.0); } else { + registry.fill(HIST("h_jet_pt_out_of_plane_v2"), jet.pt() - (collision.rho() * jet.area()), 1.0); + registry.fill(HIST("h2_centrality_jet_pt_out_of_plane_v2"), centrality, jet.pt() - (collision.rho() * jet.area()), 1.0); + registry.fill(HIST("h_jet_pt_out_of_plane_v2_rho"), jet.pt() - (rholocal * jet.area()), 1.0); registry.fill(HIST("h2_centrality_jet_pt_out_of_plane_v2_rho"), centrality, jet.pt() - (rholocal * jet.area()), 1.0); + + registry.fill(HIST("h2_phi_rholocal_absDelta_low_outplane"), absDelta, rholocal, 1.0); + registry.fill(HIST("h2_phi_rholocal_absDelta_medium_outplane"), absDelta, rholocal, 1.0); + registry.fill(HIST("h2_phi_rholocal_absDelta_high_outplane"), absDelta, rholocal, 1.0); + + registry.fill(HIST("h2_averagerho_pt_outplane"), jet.pt(), collision.rho(), 1.0); + registry.fill(HIST("h2_rholocal_pt_outplane"), jet.pt(), rholocal, 1.0); } } else if (nmode == cfgNmodB) { double phiMinusPsi3; @@ -1683,8 +1665,10 @@ struct JetChargedV2 { float absDelta3 = std::abs(phiMinusPsi3); if ((absDelta3 < o2::constants::math::PIQuarter) || (absDelta3 >= evtPlnAngleA * o2::constants::math::PIQuarter) || (absDelta3 >= evtPlnAngleB * o2::constants::math::PIQuarter && absDelta3 < evtPlnAngleC * o2::constants::math::PIQuarter)) { + registry.fill(HIST("h_jet_pt_in_plane_v3"), jet.pt() - (collision.rho() * jet.area()), 1.0); registry.fill(HIST("h_jet_pt_in_plane_v3_rho"), jet.pt() - (rholocal * jet.area()), 1.0); } else { + registry.fill(HIST("h_jet_pt_out_of_plane_v3"), jet.pt() - (collision.rho() * jet.area()), 1.0); registry.fill(HIST("h_jet_pt_out_of_plane_v3_rho"), jet.pt() - (rholocal * jet.area()), 1.0); } } @@ -1933,10 +1917,6 @@ struct JetChargedV2 { registry.fill(HIST("h_v3obs_centrality"), centrality, temppara[3]); registry.fill(HIST("h_evtnum_centrlity"), evtnum, centrality); - if (temppara[0] == 0) { - registry.fill(HIST("h_badfit_counter"), 1); - } - int nDF = 1; int numOfFreePara = 2; nDF = static_cast(fFitModulationV2v3->GetXaxis()->GetNbins()) - numOfFreePara; diff --git a/PWGJE/Tasks/jetCorrelationD0.cxx b/PWGJE/Tasks/jetCorrelationD0.cxx index 0196aec6d5b..1196c7b52a4 100644 --- a/PWGJE/Tasks/jetCorrelationD0.cxx +++ b/PWGJE/Tasks/jetCorrelationD0.cxx @@ -21,7 +21,6 @@ #include "Common/Core/RecoDecay.h" #include -#include #include #include #include @@ -32,6 +31,9 @@ #include #include +#include + +#include #include #include #include @@ -84,7 +86,9 @@ DECLARE_SOA_COLUMN(D0MD, d0MD, float); DECLARE_SOA_COLUMN(D0PtD, d0PtD, float); DECLARE_SOA_COLUMN(D0EtaD, d0EtaD, float); DECLARE_SOA_COLUMN(D0PhiD, d0PhiD, float); -DECLARE_SOA_COLUMN(D0Reflection, d0Reflection, int); +DECLARE_SOA_COLUMN(D0MatchedFrom, d0MatchedFrom, int); +DECLARE_SOA_COLUMN(D0SelectedAs, d0SelectedAs, int); +DECLARE_SOA_COLUMN(D0DecayChannel, d0DecayChannel, int8_t); } // namespace d0Info DECLARE_SOA_TABLE(D0Tables, "AOD", "D0TABLE", @@ -99,6 +103,21 @@ DECLARE_SOA_TABLE(D0Tables, "AOD", "D0TABLE", d0Info::D0Phi, d0Info::D0Y); +DECLARE_SOA_TABLE(D0McDTables, "AOD", "D0MCDTABLE", + o2::soa::Index<>, + collisionInfo::McCollisionTableId, + d0Info::D0PromptBDT, + d0Info::D0NonPromptBDT, + d0Info::D0BkgBDT, + d0Info::D0M, + d0Info::D0Pt, + d0Info::D0Eta, + d0Info::D0Phi, + d0Info::D0Y, + d0Info::D0MatchedFrom, + d0Info::D0SelectedAs, + d0Info::D0DecayChannel); + DECLARE_SOA_TABLE(D0McPTables, "AOD", "D0MCPTABLE", o2::soa::Index<>, collisionInfo::McCollisionTableId, @@ -106,12 +125,14 @@ DECLARE_SOA_TABLE(D0McPTables, "AOD", "D0MCPTABLE", d0Info::D0Pt, d0Info::D0Eta, d0Info::D0Phi, - d0Info::D0Y); + d0Info::D0Y, + d0Info::D0DecayChannel); namespace jetInfo { // D0 tables DECLARE_SOA_INDEX_COLUMN(D0Table, d0Table); +DECLARE_SOA_INDEX_COLUMN(D0McDTable, d0McDTable); DECLARE_SOA_INDEX_COLUMN(D0McPTable, d0McPTable); // Jet DECLARE_SOA_COLUMN(JetPt, jetPt, float); @@ -134,6 +155,15 @@ DECLARE_SOA_TABLE_STAGED(JetTables, "JETTABLE", jetInfo::JetPhi, jetInfo::D0JetDeltaPhi); +DECLARE_SOA_TABLE_STAGED(JetMcDTables, "JETMCDTABLE", + o2::soa::Index<>, + collisionInfo::CollisionTableId, + jetInfo::D0McDTableId, + jetInfo::JetPt, + jetInfo::JetEta, + jetInfo::JetPhi, + jetInfo::D0JetDeltaPhi); + DECLARE_SOA_TABLE_STAGED(JetMcPTables, "JETMCPTABLE", o2::soa::Index<>, collisionInfo::McCollisionTableId, @@ -160,11 +190,13 @@ DECLARE_SOA_TABLE_STAGED(JetMatchedTables, "JETMATCHEDTABLE", struct JetCorrelationD0 { // Define new table Produces tableCollision; - Produces tableMatchedCollision; Produces tableMcCollision; + Produces tableMatchedCollision; Produces tableD0; + Produces tableD0McDetector; Produces tableD0McParticle; Produces tableJet; + Produces tableJetMcDetector; Produces tableJetMcParticle; Produces tableJetMatched; @@ -318,15 +350,37 @@ struct JetCorrelationD0 { } const auto scores = d0Candidate.mlScores(); fillD0Histograms(d0Candidate, scores); - tableD0(tableCollision.lastIndex(), // might want to add some more detector level D0 quantities like prompt or non prompt info - scores[2], - scores[1], - scores[0], - d0Candidate.m(), - d0Candidate.pt(), - d0Candidate.eta(), - d0Candidate.phi(), - d0Candidate.y()); + + // flagMcMatchRec() = sign * DecayChannelMain + // |value| identifies the decay channel (D0ToPiK=1, ..., D0ToKK=5), sign identifies D0(+)/D0bar(-), 0 = no match. + int8_t d0DecayChannel = d0Candidate.flagMcMatchRec(); + + int matchedFrom = 0; + int selectedAs = 0; + + if (d0DecayChannel > 0) { // matched to a D0 on truth level (any channel) + matchedFrom = 1; + } else if (d0DecayChannel < 0) { // matched to a D0bar on truth level (any channel) + matchedFrom = -1; + } + if (d0Candidate.candidateSelFlag() & BIT(0)) { // CandidateSelFlag == BIT(0) -> selected as D0 + selectedAs = 1; + } else if (d0Candidate.candidateSelFlag() & BIT(1)) { // CandidateSelFlag == BIT(1) -> selected as D0bar + selectedAs = -1; + } + + tableD0McDetector(tableCollision.lastIndex(), // might want to add some more detector level D0 quantities like prompt or non prompt info + scores[2], + scores[1], + scores[0], + d0Candidate.m(), + d0Candidate.pt(), + d0Candidate.eta(), + d0Candidate.phi(), + d0Candidate.y(), + matchedFrom, + selectedAs, + d0DecayChannel); for (const auto& jet : jets) { if (jet.pt() < jetPtCutMin) { continue; @@ -336,12 +390,12 @@ struct JetCorrelationD0 { continue; } fillJetHistograms(jet, dPhi); - tableJet(tableCollision.lastIndex(), - tableD0.lastIndex(), - jet.pt(), - jet.eta(), - jet.phi(), - dPhi); + tableJetMcDetector(tableCollision.lastIndex(), + tableD0McDetector.lastIndex(), + jet.pt(), + jet.eta(), + jet.phi(), + dPhi); } } } @@ -364,7 +418,8 @@ struct JetCorrelationD0 { d0McPCandidate.pt(), d0McPCandidate.eta(), d0McPCandidate.phi(), - d0McPCandidate.y()); + d0McPCandidate.y(), + d0McPCandidate.flagMcMatchGen()); for (const auto& jet : jets) { if (jet.pt() < jetMcPtCutMin) { @@ -417,9 +472,6 @@ struct JetCorrelationD0 { if (McDJet.has_matchedJetGeo()) { // geometric matching for (auto const& McPJet : McDJet.template matchedJetGeo_as()) { float dPhiP = RecoDecay::constrainAngle(McPJet.phi() - d0Particle.phi(), -o2::constants::math::PI); - // if (std::abs(dPhiP - o2::constants::math::PI) > (o2::constants::math::PI / 2)) { - // continue; - // } tableJetMatched(tableMatchedCollision.lastIndex(), McDJet.pt(), McDJet.eta(), diff --git a/PWGJE/Tasks/jetCrossSectionEfficiency.cxx b/PWGJE/Tasks/jetCrossSectionEfficiency.cxx index c768e25fa2f..a3be1282987 100644 --- a/PWGJE/Tasks/jetCrossSectionEfficiency.cxx +++ b/PWGJE/Tasks/jetCrossSectionEfficiency.cxx @@ -19,6 +19,7 @@ #include "PWGJE/Core/JetDerivedDataUtilities.h" #include "PWGJE/Core/JetFindingUtilities.h" #include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" #include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/RCTSelectionFlags.h" @@ -32,6 +33,9 @@ #include #include +#include +#include + #include #include #include diff --git a/PWGJE/Tasks/jetDsSpecSubs.cxx b/PWGJE/Tasks/jetDsSpecSubs.cxx index 8568ab64bea..ab36cbeb43f 100644 --- a/PWGJE/Tasks/jetDsSpecSubs.cxx +++ b/PWGJE/Tasks/jetDsSpecSubs.cxx @@ -413,7 +413,7 @@ struct JetDsSpecSubs { // MC collisions passing z_cut selection registry.fill(HIST("McEffCol"), getValFromBin(BinMCColCntr::ZCut)); - // Detector level + // Reconstructed collisions associated to this mccollision const auto collisionsPerMCCollision = collisions.sliceBy(collisionsPerMCCollisionPreslice, mccollision.globalIndex()); for (const auto& collision : collisionsPerMCCollision) { diff --git a/PWGJE/Tasks/jetHadronsPid.cxx b/PWGJE/Tasks/jetHadronsPid.cxx new file mode 100644 index 00000000000..b172a70e5cf --- /dev/null +++ b/PWGJE/Tasks/jetHadronsPid.cxx @@ -0,0 +1,662 @@ +// Copyright 2019-2026 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file jetHadronsPid.cxx +/// \brief Analysis of hadrons in jets +/// \author Leonard Lorenc, WUT Warsaw, leonard.lorenc@cern.ch +/// \author Aleksandra Mulewicz, WUT Warsaw, aleksandra.mulewicz@cern.ch +/// \author Hubert Zalewski, WUT Warsaw, hubert.zalewski@cern.ch +/// \author Janik Małgorzata malgorzata.janik@cern.ch +/// \author Daniela Ruggiano daniela.ruggiano@cern.ch + +#include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" +#include "PWGJE/DataModel/JetSubtraction.h" + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponseITS.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::aod; +using namespace o2::constants::physics; +using namespace o2::constants::math; +using namespace o2::framework::expressions; + +using StandardEvents = soa::Join; + +using JetEvents = soa::Join; + +using HadronTracks = soa::Join; + +using HadronTracksMC = soa::Join; + +struct JetHadronsPid { + + HistogramRegistry registryData{"registryData", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + Configurable eventSelections{"eventSelections", "sel8,vtxITSTPC,noITSROF,noTF,noPileup,goodZvtx", "choose event selection"}; + std::vector eventSelectionBits; + + Configurable isppRefAnalysis{"isppRefAnalysis", true, "Is ppRef analysis"}; + Configurable cfgEtaJetMax{"cfgEtaJetMax", 0.5, "max jet eta"}; + + Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "Reject events near the ITS ROF border"}; + Configurable rejectTFBorder{"rejectTFBorder", true, "Reject events near the TF border"}; + Configurable requireVtxITSTPC{"requireVtxITSTPC", true, "Require at least one ITS-TPC matched track"}; + Configurable rejectSameBunchPileup{"rejectSameBunchPileup", true, "Reject events with same-bunch pileup collisions"}; + Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", true, "Require consistent FT0 vs PV z-vertex"}; + Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "Require at least one vertex track matched to TOF"}; + + Configurable minJetPt{"minJetPt", 4.0, "Minimum pt of the jet after bkg subtraction"}; + Configurable maxJetPt{"maxJetPt", 1e+06, "Maximum pt of the jet after bkg subtraction"}; + Configurable rJet{"rJet", 0.4, "Jet resolution parameter R"}; + Configurable zVtx{"zVtx", 10.0, "Maximum zVertex"}; + Configurable applyAreaCut{"applyAreaCut", false, "apply area cut"}; + Configurable minNormalizedJetArea{"minNormalizedJetArea", 0.6, "Minimum normalized area cut to reject fake jets"}; + Configurable deltaEtaEdge{"deltaEtaEdge", 0.05, "eta gap from the edge"}; + + Configurable requirePvContributor{"requirePvContributor", false, "require that the track is a PV contributor"}; + Configurable minItsNclusters{"minItsNclusters", 5, "minimum number of ITS clusters"}; + Configurable minTpcNcrossedRows{"minTpcNcrossedRows", 70, "minimum number of TPC crossed pad rows"}; + Configurable minChiSquareTpc{"minChiSquareTpc", 0.0, "minimum TPC chi^2/Ncls"}; + Configurable maxChiSquareTpc{"maxChiSquareTpc", 4.0, "maximum TPC chi^2/Ncls"}; + Configurable maxChiSquareIts{"maxChiSquareIts", 36.0, "maximum ITS chi^2/Ncls"}; + Configurable minPt{"minPt", 0.3, "minimum pt of the tracks"}; + Configurable maxPt{"maxPt", 4.0, "maximum pt of the tracks for PID analysis"}; + Configurable minEta{"minEta", -0.8, "minimum eta"}; + Configurable maxEta{"maxEta", +0.8, "maximum eta"}; + Configurable maxDcaxy{"maxDcaxy", 0.2, "Maximum DCAxy"}; + Configurable maxDcaz{"maxDcaz", 0.1, "Maximum DCAz"}; + Configurable maxNSigmaPid{"maxNSigmaPid", 3.0, "Maximum nSigma for TPC and TOF PID"}; + + Configurable setMCDefaultItsParams{"setMCDefaultItsParams", true, "set MC default parameters"}; + + o2::aod::ITSResponse itsResponse; + + Preslice tracksPerCollision = aod::track::collisionId; + + void init(InitContext const&) + { + if (setMCDefaultItsParams) { + itsResponse.setMCDefaultParameters(); + } + + eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(static_cast(eventSelections)); + + registryData.add("n_events", "Event counter", HistType::kTH1F, {{1, 0.5, 1.5, "N_{events}"}}); + registryData.add("n_events_raw", "All events", HistType::kTH1F, {{1, 0.5, 1.5, ""}}); + + registryData.add("jet_pt", "Jet pT ", HistType::kTH1F, {{100, 0.0, 20.0, "#it{p}_{T}^{raw} (GeV/#it{c})"}}); + registryData.add("jet_pt_subtracted", "Jet pT subtracted", HistType::kTH1F, {{200, 0.0, 10.0, "#it{p}_{T}^{sub} (GeV/#it{c})"}}); + registryData.add("jet_pt_raw_vs_sub", "Raw vs sub jet pT", HistType::kTH2F, {{200, 0, 200}, {200, 0, 200}}); + registryData.add("jet_eta", "Jet eta", HistType::kTH1F, {{100, -1.0, 1.0, "#eta_{jet}"}}); + registryData.add("jet_phi", "Jet phi", HistType::kTH1F, {{100, 0.0, TwoPI, "#phi_{jet}"}}); + registryData.add("jet_area", "Jet area", HistType::kTH1F, {{100, 0.0, 1.5, "Area"}}); + registryData.add("jet_n_constituents", "Jet multiplicity", HistType::kTH1I, {{100, 0, 30, "N_{constituents}"}}); + + registryData.add("pion_pure_tpc", "TPC Pion PID", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TPC}"}}); + registryData.add("pion_pure_tof", "TOF Pion PID", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TOF}"}}); + registryData.add("pion_pure_pt", "Pion pT", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("pion_pure_eta", "Pion Eta", HistType::kTH1F, {{100, -1.0, 1.0, "#eta"}}); + registryData.add("pion_pure_dcaz", "Pion DCAz", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{z} (cm)"}}); + registryData.add("pion_pure_dcaxy", "Pion DCAxy", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{xy} (cm)"}}); + + registryData.add("kaon_pure_tpc", "TPC Kaon PID", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TPC}"}}); + registryData.add("kaon_pure_tof", "TOF Kaon PID", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TOF}"}}); + registryData.add("kaon_pure_pt", "Kaon pT", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("kaon_pure_eta", "Kaon Eta", HistType::kTH1F, {{100, -1.0, 1.0, "#eta"}}); + registryData.add("kaon_pure_dcaz", "Kaon DCAz", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{z} (cm)"}}); + registryData.add("kaon_pure_dcaxy", "Kaon DCAxy", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{xy} (cm)"}}); + + registryData.add("proton_pure_tpc", "TPC Proton PID", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TPC}"}}); + registryData.add("proton_pure_tof", "TOF Proton PID", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TOF}"}}); + registryData.add("proton_pure_pt", "Proton pT", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("proton_pure_eta", "Proton Eta", HistType::kTH1F, {{100, -1.0, 1.0, "#eta"}}); + registryData.add("proton_pure_dcaz", "Proton DCAz", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{z} (cm)"}}); + registryData.add("proton_pure_dcaxy", "Proton DCAxy", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{xy} (cm)"}}); + + registryData.add("z_vtx", "Z-Vertex Distribution", HistType::kTH1F, {{200, -20.0, 20.0, "Z-Vertex (cm)"}}); + + registryData.add("pion_jet_tpc", "TPC Pion PID in Jets", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TPC}"}}); + registryData.add("pion_jet_tof", "TOF Pion PID in Jets", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TOF}"}}); + registryData.add("kaon_jet_tpc", "TPC Kaon PID in Jets", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TPC}"}}); + registryData.add("kaon_jet_tof", "TOF Kaon PID in Jets", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TOF}"}}); + registryData.add("proton_jet_tpc", "TPC Proton PID in Jets", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TPC}"}}); + registryData.add("proton_jet_tof", "TOF Proton PID in Jets", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TOF}"}}); + + registryData.add("pion_jet_pt", "Pion pT in Jets", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("pion_jet_eta", "Pion Eta in Jets", HistType::kTH1F, {{100, -1.0, 1.0, "#eta"}}); + registryData.add("pion_jet_dcaxy", "Pion DCAxy in Jets", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{xy} (cm)"}}); + registryData.add("pion_jet_dcaz", "Pion DCAz in Jets", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{z} (cm)"}}); + + registryData.add("kaon_jet_pt", "Kaon pT in Jets", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("kaon_jet_eta", "Kaon Eta in Jets", HistType::kTH1F, {{100, -1.0, 1.0, "#eta"}}); + registryData.add("kaon_jet_dcaxy", "Kaon DCAxy in Jets", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{xy} (cm)"}}); + registryData.add("kaon_jet_dcaz", "Kaon DCAz in Jets", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{z} (cm)"}}); + + registryData.add("proton_jet_pt", "Proton pT in Jets", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("proton_jet_eta", "Proton Eta in Jets", HistType::kTH1F, {{100, -1.0, 1.0, "#eta"}}); + registryData.add("proton_jet_dcaxy", "Proton DCAxy in Jets", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{xy} (cm)"}}); + registryData.add("proton_jet_dcaz", "Proton DCAz in Jets", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{z} (cm)"}}); + + registryData.add("pion_ue_tpc", "TPC Pion PID in UE", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TPC}"}}); + registryData.add("pion_ue_tof", "TOF Pion PID in UE", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TOF}"}}); + registryData.add("kaon_ue_tpc", "TPC Kaon PID in UE", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TPC}"}}); + registryData.add("kaon_ue_tof", "TOF Kaon PID in UE", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TOF}"}}); + registryData.add("proton_ue_tpc", "TPC Proton PID in UE", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TPC}"}}); + registryData.add("proton_ue_tof", "TOF Proton PID in UE", HistType::kTH2F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}, {200, -3.0, 3.0, "n#sigma_{TOF}"}}); + + registryData.add("pion_ue_pt", "Pion pT in UE", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("pion_ue_eta", "Pion Eta in UE", HistType::kTH1F, {{100, -1.0, 1.0, "#eta"}}); + registryData.add("pion_ue_dcaxy", "Pion DCAxy in UE", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{xy} (cm)"}}); + registryData.add("pion_ue_dcaz", "Pion DCAz in UE", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{z} (cm)"}}); + + registryData.add("kaon_ue_pt", "Kaon pT in UE", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("kaon_ue_eta", "Kaon Eta in UE", HistType::kTH1F, {{100, -1.0, 1.0, "#eta"}}); + registryData.add("kaon_ue_dcaxy", "Kaon DCAxy in UE", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{xy} (cm)"}}); + registryData.add("kaon_ue_dcaz", "Kaon DCAz in UE", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{z} (cm)"}}); + + registryData.add("proton_ue_pt", "Proton pT in UE", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("proton_ue_eta", "Proton Eta in UE", HistType::kTH1F, {{100, -1.0, 1.0, "#eta"}}); + registryData.add("proton_ue_dcaxy", "Proton DCAxy in UE", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{xy} (cm)"}}); + registryData.add("proton_ue_dcaz", "Proton DCAz in UE", HistType::kTH1F, {{100, -0.1, 0.1, "DCA_{z} (cm)"}}); + + registryData.add("tracks_n_in_ue", "Number of tracks in UE", HistType::kTH1I, {{100, 0, 100, "N_{tracks}"}}); + + registryData.add("rec_pion_all", "All Tracks PID'd as Pions", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("mc_rec_pion_pt", "True Primary Pions (Reconstructed)", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("mc_sec_pion_pt", "Secondary Pions (Reconstructed)", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("contamination_matrix_pion", "Pion PID Contamination", HistType::kTH2F, {{4000, -0.5, 3999.5, "Absolute PDG Code"}, {120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + + registryData.add("rec_kaon_all", "All Tracks PID'd as Kaons", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("mc_rec_kaon_pt", "True Primary Kaons (Reconstructed)", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("mc_sec_kaon_pt", "Secondary Kaons (Reconstructed)", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("contamination_matrix_kaon", "Kaon PID Contamination", HistType::kTH2F, {{4000, -0.5, 3999.5, "Absolute PDG Code"}, {120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + + registryData.add("rec_proton_all", "All Tracks PID'd as Protons", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("mc_rec_proton_pt", "True Primary Protons (Reconstructed)", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("mc_sec_proton_pt", "Secondary Protons (Reconstructed)", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("contamination_matrix_proton", "Proton PID Contamination", HistType::kTH2F, {{4000, -0.5, 3999.5, "Absolute PDG Code"}, {120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + + registryData.add("mc_gen_pion_pt", "Generated Primary Pions (Truth)", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("mc_gen_kaon_pt", "Generated Primary Kaons (Truth)", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + registryData.add("mc_gen_proton_pt", "Generated Primary Protons (Truth)", HistType::kTH1F, {{120, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}}); + } + + void getPerpendicularDirections(const TVector3& p, TVector3& u1, TVector3& u2) + { + double const treshold = 1e-9; + if (p.Mag2() < treshold) { + u1.SetXYZ(0, 0, 0); + u2.SetXYZ(0, 0, 0); + return; + } + u1 = p.Orthogonal(); + u2 = p.Cross(u1); + } + + template + bool hasITSLayerHit(const TrackIts& track, int layer) + { + return TESTBIT(track.itsClusterMap(), layer - 1); + } + + template + bool passedTrackSelection(const TrackType& track) + { + if (requirePvContributor && !(track.isPVContributor())) + return false; + if (!track.hasITS() || !track.hasTPC()) + return false; + if ((!hasITSLayerHit(track, 1)) && (!hasITSLayerHit(track, 2)) && (!hasITSLayerHit(track, 3))) + return false; + if (track.itsNCls() < minItsNclusters) + return false; + if (track.tpcNClsCrossedRows() < minTpcNcrossedRows) + return false; + if (track.tpcChi2NCl() < minChiSquareTpc || track.tpcChi2NCl() > maxChiSquareTpc) + return false; + if (track.itsChi2NCl() > maxChiSquareIts) + return false; + if (track.eta() < minEta || track.eta() > maxEta) + return false; + if (track.pt() < minPt || track.pt() > maxPt) + return false; + if (std::abs(track.dcaXY()) > maxDcaxy || std::abs(track.dcaZ()) > maxDcaz) + return false; + return true; + } + + void processPureTracks(StandardEvents::iterator const& collision, HadronTracks const& globalTracks) + { + if (!collision.sel8() || std::abs(collision.posZ()) > zVtx) + return; + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) + return; + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) + return; + if (requireVtxITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) + return; + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + return; + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + return; + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) + return; + + for (auto const& track : globalTracks) { + if (!passedTrackSelection(track)) + continue; + + double pt = track.pt(); + double eta = track.eta(); + double dcaxy = track.dcaXY(); + double dcaz = track.dcaZ(); + + bool passTpcPi = (std::abs(track.tpcNSigmaPi()) <= maxNSigmaPid); + bool passTpcKa = (std::abs(track.tpcNSigmaKa()) <= maxNSigmaPid); + bool passTpcPr = (std::abs(track.tpcNSigmaPr()) <= maxNSigmaPid); + + bool passTofPi = track.hasTOF() && (std::abs(track.tofNSigmaPi()) <= maxNSigmaPid); + bool passTofKa = track.hasTOF() && (std::abs(track.tofNSigmaKa()) <= maxNSigmaPid); + bool passTofPr = track.hasTOF() && (std::abs(track.tofNSigmaPr()) <= maxNSigmaPid); + + const double ptThreshold = 0.8; + + if (passTpcPi) { + registryData.fill(HIST("pion_pure_tpc"), pt, track.tpcNSigmaPi()); + if (passTofPi) + registryData.fill(HIST("pion_pure_tof"), pt, track.tofNSigmaPi()); + if (pt < ptThreshold || passTofPi) { + registryData.fill(HIST("pion_pure_pt"), pt); + registryData.fill(HIST("pion_pure_eta"), eta); + registryData.fill(HIST("pion_pure_dcaxy"), dcaxy); + registryData.fill(HIST("pion_pure_dcaz"), dcaz); + } + } + + if (passTpcKa) { + registryData.fill(HIST("kaon_pure_tpc"), pt, track.tpcNSigmaKa()); + if (passTofKa) + registryData.fill(HIST("kaon_pure_tof"), pt, track.tofNSigmaKa()); + if (pt < ptThreshold || passTofKa) { + registryData.fill(HIST("kaon_pure_pt"), pt); + registryData.fill(HIST("kaon_pure_eta"), eta); + registryData.fill(HIST("kaon_pure_dcaxy"), dcaxy); + registryData.fill(HIST("kaon_pure_dcaz"), dcaz); + } + } + + if (passTpcPr) { + registryData.fill(HIST("proton_pure_tpc"), pt, track.tpcNSigmaPr()); + if (passTofPr) + registryData.fill(HIST("proton_pure_tof"), pt, track.tofNSigmaPr()); + if (pt < ptThreshold || passTofPr) { + registryData.fill(HIST("proton_pure_pt"), pt); + registryData.fill(HIST("proton_pure_eta"), eta); + registryData.fill(HIST("proton_pure_dcaxy"), dcaxy); + registryData.fill(HIST("proton_pure_dcaz"), dcaz); + } + } + } + } + PROCESS_SWITCH(JetHadronsPid, processPureTracks, "Pure Tracks Analysis", true); + + void processJets(JetEvents::iterator const& collision, + soa::Join const& jets, + soa::Join const&, + HadronTracks const& globalTracks) + { + registryData.fill(HIST("n_events_raw"), 1); + + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { + return; + } + + float zVertex = collision.posZ(); + if (std::abs(zVertex) > zVtx) + return; + + registryData.fill(HIST("n_events"), 1); + registryData.fill(HIST("z_vtx"), zVertex); + + double centralRho = collision.rho(); + + auto collTracks = globalTracks.sliceBy(tracksPerCollision, collision.collisionId()); + + for (auto const& jet : jets) { + + if (!isppRefAnalysis && ((std::abs(jet.eta()) + rJet) > (maxEta - deltaEtaEdge))) + continue; + if (isppRefAnalysis && std::abs(jet.eta()) > cfgEtaJetMax) + continue; + + double ptSub = jet.pt() - (centralRho * jet.area()); + if (ptSub < 0) + ptSub = 0.0; + + registryData.fill(HIST("jet_pt_subtracted"), ptSub); + registryData.fill(HIST("jet_pt_raw_vs_sub"), jet.pt(), ptSub); + + if (isppRefAnalysis && (jet.pt() < minJetPt || jet.pt() > maxJetPt)) + continue; + if (!isppRefAnalysis && (ptSub < minJetPt || ptSub > maxJetPt)) + continue; + + double normalizedJetArea = jet.area() / (PI * rJet * rJet); + if (applyAreaCut && normalizedJetArea < minNormalizedJetArea) + continue; + + registryData.fill(HIST("jet_eta"), jet.eta()); + registryData.fill(HIST("jet_phi"), jet.phi()); + registryData.fill(HIST("jet_area"), jet.area()); + registryData.fill(HIST("jet_pt"), jet.pt()); + + const double magnitudeThreshold = 1e-9; + TVector3 jetAxis(jet.px(), jet.py(), jet.pz()); + TVector3 ueAxis1(0, 0, 0), ueAxis2(0, 0, 0); + getPerpendicularDirections(jetAxis, ueAxis1, ueAxis2); + + if (ueAxis1.Mag() < magnitudeThreshold || ueAxis2.Mag() < magnitudeThreshold) + continue; + + int constituentCount = 0; + std::set tracksInJetsSet; + + for (auto const& jtrack : jet.tracks_as>()) { + constituentCount++; + + auto track = jtrack.track_as(); + tracksInJetsSet.insert(track.index()); + + if (!passedTrackSelection(track)) + continue; + + double pt = track.pt(); + double eta = track.eta(); + double dcaxy = track.dcaXY(); + double dcaz = track.dcaZ(); + + bool passTpcPi = (std::abs(track.tpcNSigmaPi()) <= maxNSigmaPid); + bool passTpcKa = (std::abs(track.tpcNSigmaKa()) <= maxNSigmaPid); + bool passTpcPr = (std::abs(track.tpcNSigmaPr()) <= maxNSigmaPid); + + bool passTofPi = track.hasTOF() && (std::abs(track.tofNSigmaPi()) <= maxNSigmaPid); + bool passTofKa = track.hasTOF() && (std::abs(track.tofNSigmaKa()) <= maxNSigmaPid); + bool passTofPr = track.hasTOF() && (std::abs(track.tofNSigmaPr()) <= maxNSigmaPid); + + const double ptThreshold = 0.8; + + if (passTpcPi) { + registryData.fill(HIST("pion_jet_tpc"), pt, track.tpcNSigmaPi()); + if (passTofPi) + registryData.fill(HIST("pion_jet_tof"), pt, track.tofNSigmaPi()); + if (pt < ptThreshold || passTofPi) { + registryData.fill(HIST("pion_jet_pt"), pt); + registryData.fill(HIST("pion_jet_eta"), eta); + registryData.fill(HIST("pion_jet_dcaxy"), dcaxy); + registryData.fill(HIST("pion_jet_dcaz"), dcaz); + } + } + + if (passTpcKa) { + registryData.fill(HIST("kaon_jet_tpc"), pt, track.tpcNSigmaKa()); + if (passTofKa) + registryData.fill(HIST("kaon_jet_tof"), pt, track.tofNSigmaKa()); + if (pt < ptThreshold || passTofKa) { + registryData.fill(HIST("kaon_jet_pt"), pt); + registryData.fill(HIST("kaon_jet_eta"), eta); + registryData.fill(HIST("kaon_jet_dcaxy"), dcaxy); + registryData.fill(HIST("kaon_jet_dcaz"), dcaz); + } + } + + if (passTpcPr) { + registryData.fill(HIST("proton_jet_tpc"), pt, track.tpcNSigmaPr()); + if (passTofPr) + registryData.fill(HIST("proton_jet_tof"), pt, track.tofNSigmaPr()); + if (pt < ptThreshold || passTofPr) { + registryData.fill(HIST("proton_jet_pt"), pt); + registryData.fill(HIST("proton_jet_eta"), eta); + registryData.fill(HIST("proton_jet_dcaxy"), dcaxy); + registryData.fill(HIST("proton_jet_dcaz"), dcaz); + } + } + } + registryData.fill(HIST("jet_n_constituents"), constituentCount); + + int nTracksOut = 0; + + for (auto const& track : collTracks) { + + if (tracksInJetsSet.find(track.index()) == tracksInJetsSet.end()) { + if (passedTrackSelection(track)) + nTracksOut++; + } + + if (!passedTrackSelection(track)) + continue; + + double deltaEtaUe1 = track.eta() - ueAxis1.Eta(); + double deltaPhiUe1 = RecoDecay::constrainAngle(track.phi() - ueAxis1.Phi(), -PI); + double deltaRUe1 = std::sqrt(deltaEtaUe1 * deltaEtaUe1 + deltaPhiUe1 * deltaPhiUe1); + + double deltaEtaUe2 = track.eta() - ueAxis2.Eta(); + double deltaPhiUe2 = RecoDecay::constrainAngle(track.phi() - ueAxis2.Phi(), -PI); + double deltaRUe2 = std::sqrt(deltaEtaUe2 * deltaEtaUe2 + deltaPhiUe2 * deltaPhiUe2); + + if (deltaRUe1 > rJet && deltaRUe2 > rJet) + continue; + + double pt = track.pt(); + double eta = track.eta(); + double dcaxy = track.dcaXY(); + double dcaz = track.dcaZ(); + + bool passTpcPi = (std::abs(track.tpcNSigmaPi()) <= maxNSigmaPid); + bool passTpcKa = (std::abs(track.tpcNSigmaKa()) <= maxNSigmaPid); + bool passTpcPr = (std::abs(track.tpcNSigmaPr()) <= maxNSigmaPid); + + bool passTofPi = track.hasTOF() && (std::abs(track.tofNSigmaPi()) <= maxNSigmaPid); + bool passTofKa = track.hasTOF() && (std::abs(track.tofNSigmaKa()) <= maxNSigmaPid); + bool passTofPr = track.hasTOF() && (std::abs(track.tofNSigmaPr()) <= maxNSigmaPid); + + const double ptThreshold = 0.8; + + if (passTpcPi) { + registryData.fill(HIST("pion_ue_tpc"), pt, track.tpcNSigmaPi()); + if (passTofPi) + registryData.fill(HIST("pion_ue_tof"), pt, track.tofNSigmaPi()); + if (pt < ptThreshold || passTofPi) { + registryData.fill(HIST("pion_ue_pt"), pt); + registryData.fill(HIST("pion_ue_eta"), eta); + registryData.fill(HIST("pion_ue_dcaxy"), dcaxy); + registryData.fill(HIST("pion_ue_dcaz"), dcaz); + } + } + + if (passTpcKa) { + registryData.fill(HIST("kaon_ue_tpc"), pt, track.tpcNSigmaKa()); + if (passTofKa) + registryData.fill(HIST("kaon_ue_tof"), pt, track.tofNSigmaKa()); + if (pt < ptThreshold || passTofKa) { + registryData.fill(HIST("kaon_ue_pt"), pt); + registryData.fill(HIST("kaon_ue_eta"), eta); + registryData.fill(HIST("kaon_ue_dcaxy"), dcaxy); + registryData.fill(HIST("kaon_ue_dcaz"), dcaz); + } + } + + if (passTpcPr) { + registryData.fill(HIST("proton_ue_tpc"), pt, track.tpcNSigmaPr()); + if (passTofPr) + registryData.fill(HIST("proton_ue_tof"), pt, track.tofNSigmaPr()); + if (pt < ptThreshold || passTofPr) { + registryData.fill(HIST("proton_ue_pt"), pt); + registryData.fill(HIST("proton_ue_eta"), eta); + registryData.fill(HIST("proton_ue_dcaxy"), dcaxy); + registryData.fill(HIST("proton_ue_dcaz"), dcaz); + } + } + } + registryData.fill(HIST("tracks_n_in_ue"), nTracksOut); + } + } + PROCESS_SWITCH(JetHadronsPid, processJets, "Jets Analysis", true); + + void processMC(StandardEvents::iterator const& collision, HadronTracksMC const& tracks, aod::McParticles const&) + { + if (!collision.sel8() || std::abs(collision.posZ()) > zVtx) + return; + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) + return; + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) + return; + if (requireVtxITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) + return; + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + return; + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + return; + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) + return; + + const double ptThreshold = 0.8; + + for (auto const& track : tracks) { + + if (!passedTrackSelection(track)) + continue; + + double pt = track.pt(); + + bool passTpcPi = (std::abs(track.tpcNSigmaPi()) <= maxNSigmaPid); + bool passTofPi = track.hasTOF() && (std::abs(track.tofNSigmaPi()) <= maxNSigmaPid); + + bool passTpcKa = (std::abs(track.tpcNSigmaKa()) <= maxNSigmaPid); + bool passTofKa = track.hasTOF() && (std::abs(track.tofNSigmaKa()) <= maxNSigmaPid); + + bool passTpcPr = (std::abs(track.tpcNSigmaPr()) <= maxNSigmaPid); + bool passTofPr = track.hasTOF() && (std::abs(track.tofNSigmaPr()) <= maxNSigmaPid); + + if (!track.has_mcParticle()) + continue; + auto const& trueParticle = track.mcParticle(); + + int pdg = std::abs(trueParticle.pdgCode()); + bool isPrimary = trueParticle.isPhysicalPrimary(); + + if (passTpcPi && (pt < ptThreshold || passTofPi)) { + registryData.fill(HIST("rec_pion_all"), pt); + registryData.fill(HIST("contamination_matrix_pion"), pdg, pt); + if (isPrimary) { + if (pdg == PDG_t::kPiPlus) + registryData.fill(HIST("mc_rec_pion_pt"), pt); + } else { + registryData.fill(HIST("mc_sec_pion_pt"), pt); + } + } + + if (passTpcKa && (pt < ptThreshold || passTofKa)) { + registryData.fill(HIST("rec_kaon_all"), pt); + registryData.fill(HIST("contamination_matrix_kaon"), pdg, pt); + if (isPrimary) { + if (pdg == PDG_t::kKPlus) + registryData.fill(HIST("mc_rec_kaon_pt"), pt); + } else { + registryData.fill(HIST("mc_sec_kaon_pt"), pt); + } + } + + if (passTpcPr && (pt < ptThreshold || passTofPr)) { + registryData.fill(HIST("rec_proton_all"), pt); + registryData.fill(HIST("contamination_matrix_proton"), pdg, pt); + if (isPrimary) { + if (pdg == PDG_t::kProton) + registryData.fill(HIST("mc_rec_proton_pt"), pt); + } else { + registryData.fill(HIST("mc_sec_proton_pt"), pt); + } + } + } + } + PROCESS_SWITCH(JetHadronsPid, processMC, "Run on Monte Carlo", false); + + void processMCTruth(aod::McCollisions::iterator const& mcCollision, aod::McParticles const& mcParticles) + { + if (std::abs(mcCollision.posZ()) > zVtx) + return; + + for (auto const& mcpart : mcParticles) { + + if (!mcpart.isPhysicalPrimary()) + continue; + + if (mcpart.eta() < minEta || mcpart.eta() > maxEta) + continue; + if (mcpart.pt() < minPt || mcpart.pt() > maxPt) + continue; + + int pdg = std::abs(mcpart.pdgCode()); + double pt = mcpart.pt(); + + if (pdg == PDG_t::kPiPlus) { + registryData.fill(HIST("mc_gen_pion_pt"), pt); + } else if (pdg == PDG_t::kKPlus) { + registryData.fill(HIST("mc_gen_kaon_pt"), pt); + } else if (pdg == PDG_t::kProton) { + registryData.fill(HIST("mc_gen_proton_pt"), pt); + } + } + } + PROCESS_SWITCH(JetHadronsPid, processMCTruth, "Run on Monte Carlo (Pure Truth)", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGJE/Tasks/jetSpectraChargedGen.cxx b/PWGJE/Tasks/jetSpectraChargedGen.cxx index 210b2144a33..ec8e1896e40 100644 --- a/PWGJE/Tasks/jetSpectraChargedGen.cxx +++ b/PWGJE/Tasks/jetSpectraChargedGen.cxx @@ -19,6 +19,7 @@ #include "PWGJE/Core/JetFindingUtilities.h" #include "PWGJE/Core/JetUtilities.h" #include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" #include "PWGJE/DataModel/JetSubtraction.h" #include @@ -28,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/PWGJE/Tasks/jetSpectraEseTask.cxx b/PWGJE/Tasks/jetSpectraEseTask.cxx index 20e3f34589b..0272ebec174 100644 --- a/PWGJE/Tasks/jetSpectraEseTask.cxx +++ b/PWGJE/Tasks/jetSpectraEseTask.cxx @@ -23,10 +23,12 @@ #include "Common/Core/RecoDecay.h" #include "Common/DataModel/EseTable.h" #include "Common/DataModel/Qvectors.h" +#include "Common/DataModel/TrackSelectionTables.h" #include #include #include +#include #include #include #include @@ -52,13 +54,13 @@ #include #include +#include #include #include #include #include #include #include -#include #include using namespace o2; @@ -100,11 +102,8 @@ struct JetSpectraEseTask { Configurable cfgChi2PrTPCcls{"cfgChi2PrTPCcls", 2.5, "cut for chi2 per TPC cluster for tracks"}; Configurable cfgChi2PrITScls{"cfgChi2PrITScls", 36, "cut for chi2 per ITS cluster for tracks"}; - Configurable trackPtMinRhoPhi{"trackPtMinRhoPhi", 0.2, "minimum pT acceptance for tracks used in rho(phi) calculation"}; - Configurable trackPtMaxRhoPhi{"trackPtMaxRhoPhi", 5.0, "maximum pT acceptance for tracks used in rho(phi) calculation"}; - - Configurable jetEtaMin{"jetEtaMin", -0.7, "minimum jet pseudorapidity"}; - Configurable jetEtaMax{"jetEtaMax", 0.7, "maximum jet pseudorapidity"}; + Configurable> trackPtRhoPhi{"trackPtRhoPhi", {0.2, 5.0}, "pT range for tracks used in rho(phi) calculation"}; + Configurable> cfgJetEta{"cfgJetEta", {-0.7, 0.7}, "jet eta range for analysis"}; Configurable eventSelections{"eventSelections", "sel8FullPbPb", "choose event selection"}; Configurable trackSelections{"trackSelections", "globalTracks", "set track selections"}; @@ -117,6 +116,7 @@ struct JetSpectraEseTask { Configurable cfgnTotalSystem{"cfgnTotalSystem", 7, "total qvector number // look in Qvector table for this number"}; Configurable cfgnCorrLevel{"cfgnCorrLevel", 3, "QVector step: 0 = no corr, 1 = rect, 2 = twist, 3 = full"}; + Configurable cfgnredCorrLevel{"cfgnredCorrLevel", 2, "For the correlation of the reduced q vector, QVector step: 0 = no corr, 1 = rect, 2 = twist, 3 = full"}; Configurable cfgEPRefA{"cfgEPRefA", "FT0A", "EP reference A"}; Configurable cfgEPRefB{"cfgEPRefB", "TPCpos", "EP reference B"}; @@ -234,7 +234,8 @@ struct JetSpectraEseTask { static constexpr EventPlaneFiller PsiFillerEse = {true, false}; static constexpr EventPlaneFiller PsiFillerFalse = {false, false}; TRandom3* fRndm = new TRandom3(0); - static constexpr int NumSubSmpl = 10; + static constexpr int NumSubSmpl = 5; + static constexpr int NumSavedRhoFitEvents = 5; std::array, NumSubSmpl> hSameSub; void applySystematicPreset() @@ -359,6 +360,10 @@ struct JetSpectraEseTask { registry.get(HIST("trackQA/hRhoTrackCounter"))->GetXaxis()->SetBinLabel(3, "Tracks for rho(phi)"); registry.add("trackQA/hPhiPtsum", "jet sumpt;sum p_{T};entries", {HistType::kTH1F, {{40, 0., o2::constants::math::TwoPI}}}); + for (int i = 0; i < NumSavedRhoFitEvents; ++i) { + const auto eventName = fmt::format("rhoPhiFitEvents/event_{}", i); + registry.add(eventName, "event;#varphi;#Sigma #it{p}_{T} (GeV/#it{c})", HistType::kTH1F, {{1, 0., o2::constants::math::TwoPI}}); + } registry.add("eventQA/hfitPar0", "", {HistType::kTH2F, {{centAxis}, {fitAxis0}}}); registry.add("eventQA/hfitPar1", "", {HistType::kTH2F, {{centAxis}, {fitAxis13}}}); registry.add("eventQA/hfitPar2", "", {HistType::kTH2F, {{centAxis}, {fitAxis24}}}); @@ -447,20 +452,41 @@ struct JetSpectraEseTask { if (doprocessESEEPData) { LOGF(info, "JetSpectraEseTask::init() - Event Plane Process"); registry.add("eventQA/hPsi2FT0C", ";Centrality; #Psi_{2}", {HistType::kTH2F, {{centAxis}, {150, -2.5, 2.5}}}); - registry.addClone("eventQA/hPsi2FT0C", "hPsi2FT0A"); - registry.addClone("eventQA/hPsi2FT0C", "hPsi2FV0A"); - registry.addClone("eventQA/hPsi2FT0C", "hPsi2TPCpos"); - registry.addClone("eventQA/hPsi2FT0C", "hPsi2TPCneg"); - registry.add("eventQA/hCosPsi2AmC", ";Centrality;cos(2(#Psi_{2}^{A}-#Psi_{2}^{B}));#it{q}_{2}", {HistType::kTH3F, {{centAxis}, {cosAxis}, {eseAxis}}}); - registry.addClone("eventQA/hCosPsi2AmC", "hCosPsi2AmB"); - registry.addClone("eventQA/hCosPsi2AmC", "hCosPsi2BmC"); + registry.addClone("eventQA/hPsi2FT0C", "eventQA/hPsi2FT0A"); + registry.addClone("eventQA/hPsi2FT0C", "eventQA/hPsi2FV0A"); + registry.addClone("eventQA/hPsi2FT0C", "eventQA/hPsi2TPCpos"); + registry.addClone("eventQA/hPsi2FT0C", "eventQA/hPsi2TPCneg"); + + registry.addClone("eventQA/hPsi2FT0C", "eventQA/hPsi3FT0C"); + registry.addClone("eventQA/hPsi2FT0C", "eventQA/hPsi3FT0A"); + + registry.addClone("eventQA/hPsi2FT0C", "eventQA/hPsi4FT0C"); + registry.addClone("eventQA/hPsi2FT0C", "eventQA/hPsi4FT0A"); + registry.addClone("eventQA/hPsi2FT0C", "eventQA/hPsi4FV0A"); + registry.addClone("eventQA/hPsi2FT0C", "eventQA/hPsi4TPCpos"); + registry.addClone("eventQA/hPsi2FT0C", "eventQA/hPsi4TPCneg"); + + registry.add("eventQA/hCos2Psi2AmC", ";Centrality;cos(2(#Psi_{2}^{A}-#Psi_{2}^{B}));#it{q}_{2}", {HistType::kTH3F, {{centAxis}, {cosAxis}, {eseAxis}}}); + registry.addClone("eventQA/hCos2Psi2AmC", "eventQA/hCos2Psi2AmB"); + registry.addClone("eventQA/hCos2Psi2AmC", "eventQA/hCos2Psi2BmC"); + + registry.addClone("eventQA/hCos2Psi2AmC", "eventQA/hCos4Psi2AmC"); + registry.addClone("eventQA/hCos2Psi2AmC", "eventQA/hCos4Psi2AmB"); + registry.addClone("eventQA/hCos2Psi2AmC", "eventQA/hCos4Psi2BmC"); + + registry.addClone("eventQA/hCos2Psi2AmC", "eventQA/hCos4Psi4AmC"); + registry.addClone("eventQA/hCos2Psi2AmC", "eventQA/hCos4Psi4AmB"); + registry.addClone("eventQA/hCos2Psi2AmC", "eventQA/hCos4Psi4BmC"); + registry.add("eventQA/hQvecUncorV2", ";Centrality;Q_x;Q_y", {HistType::kTH3F, {{centAxis}, {qvecAxis}, {qvecAxis}}}); - registry.addClone("eventQA/hQvecUncorV2", "hQvecRectrV2"); - registry.addClone("eventQA/hQvecUncorV2", "hQvecTwistV2"); - registry.addClone("eventQA/hQvecUncorV2", "hQvecFinalV2"); - registry.addClone("eventQA/hPsi2FT0C", "hEPUncorV2"); - registry.addClone("eventQA/hPsi2FT0C", "hEPRectrV2"); - registry.addClone("eventQA/hPsi2FT0C", "hEPTwistV2"); + registry.addClone("eventQA/hQvecUncorV2", "eventQA/hQvecRectrV2"); + registry.addClone("eventQA/hQvecUncorV2", "eventQA/hQvecTwistV2"); + registry.addClone("eventQA/hQvecUncorV2", "eventQA/hQvecFinalV2"); + registry.addClone("eventQA/hPsi2FT0C", "eventQA/hEPUncorV2"); + registry.addClone("eventQA/hPsi2FT0C", "eventQA/hEPRectrV2"); + registry.addClone("eventQA/hPsi2FT0C", "eventQA/hEPTwistV2"); + + registry.add("eventQA/h3Centq2FT0Cq2FT0A", ";Centrality;#it{q}_{2}^{FT0C};#it{q}_{2}^{FT0A}", {HistType::kTH3F, {{centAxis}, {250, 0, 35}, {250, 0, 35}}}); } if (doprocessESEBackground) { LOGF(info, "JetSpectraEseTask::init() - Background Process"); @@ -469,6 +495,9 @@ struct JetSpectraEseTask { registry.add("hCentRhoRandomConewoLeadingJet", "; centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho} (GeV/c);", {HistType::kTHnSparseF, {{centAxis}, {800, -400.0, 400.0}, {dPhiAxis}, {eseAxis}}}); registry.add("hCentRhoRandomConeRndTrackDirwoOneLeadingJet", "; centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho} (GeV/c);", {HistType::kTHnSparseF, {{centAxis}, {800, -400.0, 400.0}, {dPhiAxis}, {eseAxis}}}); registry.add("hCentRhoRandomConeRndTrackDirwoTwoLeadingJet", "; centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho} (GeV/c);", {HistType::kTHnSparseF, {{centAxis}, {800, -400.0, 400.0}, {dPhiAxis}, {eseAxis}}}); + + registry.add("h3CentdeltapTRndmConePhi_localrhovsphi", "centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho}; #Delta#varphi_{jet}", {HistType::kTH3F, {{100, 0.0, 100.0}, {400, -200.0, 200.0}, {dPhiAxis}}}); + registry.add("h3CentdeltapTRndmConePhi_rhovsphi", "centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho}; #Delta#varphi_{jet}", {HistType::kTH3F, {{100, 0.0, 100.0}, {400, -200.0, 200.0}, {dPhiAxis}}}); } if (doprocessMCParticleLevel) { LOGF(info, "JetSpectraEseTask::init() - MC Particle level"); @@ -657,9 +686,10 @@ struct JetSpectraEseTask { auto corrL = [&](const auto& j) { return j.pt() - evalRho(rhoFit.get(), jetR, j.phi(), collision.rho()) * j.area(); }; for (const auto& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) + if (!jetfindingutilities::isInEtaAcceptance(jet, cfgJetEta->at(0), cfgJetEta->at(1), trackEtaMin, trackEtaMax)) continue; - if (!isAcceptedJet(jet)) { + // if (!isAcceptedJet(jet)) { + if (!isAcceptedJet>(jet)) { continue; } auto vCorr = corr(collision, jet); @@ -791,9 +821,9 @@ struct JetSpectraEseTask { auto corrL = [&](const auto& j) { return j.pt() - evalRho(rhoFit.get(), jetR, j.phi(), c1.rho()) * j.area(); }; for (const auto& jet : jets1) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) + if (!jetfindingutilities::isInEtaAcceptance(jet, cfgJetEta->at(0), cfgJetEta->at(1), trackEtaMin, trackEtaMax)) continue; - if (!isAcceptedJet(jet)) { + if (!isAcceptedJet>(jet)) { continue; } auto vCorr = corr(c1, jet); @@ -878,6 +908,7 @@ struct JetSpectraEseTask { return; [[maybe_unused]] const auto psi{procEP(collision)}; + detCorrelation(collision); } PROCESS_SWITCH(JetSpectraEseTask, processESEEPData, "process ese collisions for filling EP and EPR", false); @@ -921,7 +952,7 @@ struct JetSpectraEseTask { registry.fill(HIST("hTrackPhi"), collision.centFT0M(), track.phi(), occupancy); } for (const auto& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) + if (!jetfindingutilities::isInEtaAcceptance(jet, cfgJetEta->at(0), cfgJetEta->at(1), trackEtaMin, trackEtaMax)) continue; if (!isAcceptedJet(jet)) { continue; @@ -1185,69 +1216,113 @@ struct JetSpectraEseTask { } PROCESS_SWITCH(JetSpectraEseTask, processMCRecoTrack, "jet MC process: Reconstructed track", false); + float redqn(const std::vector& vec) + { + float redq = -999.0f; + if (vec[2] > LowFT0Cut) { + redq = std::sqrt(vec[0] * vec[0] + vec[1] * vec[1]) * std::sqrt(vec[2]); + } + return redq; + } + template + void detCorrelation(Col const& col) + { + + auto qC = qVecNoESE(col, 2, cfgnredCorrLevel); + auto qA = qVecNoESE(col, 2, cfgnredCorrLevel); + + auto redFT0C = redqn(qC); + auto redFT0A = redqn(qA); + + registry.fill(HIST("eventQA/h3Centq2FT0Cq2FT0A"), col.centFT0M(), redFT0C, redFT0A); + } + static constexpr float InvalidValue = 999.; - // template template EventPlane procEP(EPCol const& vec) { - constexpr std::array AmpCut{LowFT0Cut, 0.0}; - auto computeEP = [&AmpCut](const std::vector& vec, auto det, float n) { return vec[2] > AmpCut[det] ? (1.0 / n) * std::atan2(vec[1], vec[0]) : InvalidValue; }; - std::map epMap; - std::map ep3Map; - auto vec1{qVecNoESE(vec)}; - epMap["FT0A"] = computeEP(vec1, 0, 2.0); - ep3Map["FT0A"] = computeEP(vec1, 0, 3.0); + auto computeEP = [](const std::vector& qVec, float minAmp, float harmonic) { + return qVec[2] > minAmp ? std::atan2(qVec[1], qVec[0]) / harmonic : InvalidValue; + }; + + std::map epMap{ + {"FT0A", computeEP(qVecNoESE(vec, 2, cfgnCorrLevel), LowFT0Cut, 2.0f)}, + {"FT0C", computeEP(qVecNoESE(vec, 2, cfgnCorrLevel), LowFT0Cut, 2.0f)}, + {"FV0A", computeEP(qVecNoESE(vec, 2, cfgnCorrLevel), LowFT0Cut, 2.0f)}, + {"TPCpos", computeEP(qVecNoESE(vec, 2, cfgnCorrLevel), 0.0f, 2.0f)}, + {"TPCneg", computeEP(qVecNoESE(vec, 2, cfgnCorrLevel), 0.0f, 2.0f)}}; + std::map ep3Map{ + {"FT0A", computeEP(qVecNoESE(vec, 3, cfgnCorrLevel), LowFT0Cut, 3.0f)}, + {"FT0C", computeEP(qVecNoESE(vec, 3, cfgnCorrLevel), LowFT0Cut, 3.0f)}}; + std::map ep4Map{ + {"FT0A", computeEP(qVecNoESE(vec, 4, cfgnCorrLevel), LowFT0Cut, 4.0f)}, + {"FT0C", computeEP(qVecNoESE(vec, 4, cfgnCorrLevel), LowFT0Cut, 4.0f)}, + {"FV0A", computeEP(qVecNoESE(vec, 4, cfgnCorrLevel), LowFT0Cut, 4.0f)}, + {"TPCpos", computeEP(qVecNoESE(vec, 4, cfgnCorrLevel), 0.0f, 4.0f)}, + {"TPCneg", computeEP(qVecNoESE(vec, 4, cfgnCorrLevel), 0.0f, 4.0f)}}; + if constexpr (P.psi) { - auto vec2{qVecNoESE(vec)}; - epMap["FT0C"] = computeEP(vec2, 0, 2.0); - ep3Map["FT0C"] = computeEP(vec2, 0, 3.0); - epMap["FV0A"] = computeEP(qVecNoESE(vec), 0, 2.0); - epMap["TPCpos"] = computeEP(qVecNoESE(vec), 1, 2.0); - epMap["TPCneg"] = computeEP(qVecNoESE(vec), 1, 2.0); - if constexpr (P.hist) - fillEP(/*std::make_index_sequence<5>{},*/ vec, epMap); - auto cosPsi = [](float psiX, float psiY) { return (static_cast(psiX) == InvalidValue || static_cast(psiY) == InvalidValue) ? InvalidValue : std::cos(2.0 * (psiX - psiY)); }; - std::array epCorrContainer{}; - epCorrContainer[0] = cosPsi(epMap.at(cfgEPRefA), epMap.at(cfgEPRefC)); - epCorrContainer[1] = cosPsi(epMap.at(cfgEPRefA), epMap.at(cfgEPRefB)); - epCorrContainer[2] = cosPsi(epMap.at(cfgEPRefB), epMap.at(cfgEPRefC)); - if constexpr (P.hist) - fillEPCos(/*std::make_index_sequence<3>{},*/ vec, epCorrContainer); - } - EventPlane localPlane; - localPlane.psi2 = epMap.at(cfgEPRefA); - localPlane.psi3 = ep3Map.at(cfgEPRefA); - return localPlane; - // return epMap.at(cfgEPRefA); + if constexpr (P.hist) { + fillEP(vec, epMap, ep3Map, ep4Map); + } + + auto cosPsi = [](float psiX, float psiY, const float harmonic = 2.0f) { + return psiX == InvalidValue || psiY == InvalidValue ? InvalidValue : std::cos(harmonic * (psiX - psiY)); + }; + const std::array epCorrContainer22{ + cosPsi(epMap.at(cfgEPRefA), epMap.at(cfgEPRefC)), + cosPsi(epMap.at(cfgEPRefA), epMap.at(cfgEPRefB)), + cosPsi(epMap.at(cfgEPRefB), epMap.at(cfgEPRefC))}; + const std::array epCorrContainer24{ + cosPsi(epMap.at(cfgEPRefA), epMap.at(cfgEPRefC), 4.0f), + cosPsi(epMap.at(cfgEPRefA), epMap.at(cfgEPRefB), 4.0f), + cosPsi(epMap.at(cfgEPRefB), epMap.at(cfgEPRefC), 4.0f)}; + const std::array epCorrContainer44{ + cosPsi(ep4Map.at(cfgEPRefA), ep4Map.at(cfgEPRefC), 4.0f), + cosPsi(ep4Map.at(cfgEPRefA), ep4Map.at(cfgEPRefB), 4.0f), + cosPsi(ep4Map.at(cfgEPRefB), ep4Map.at(cfgEPRefC), 4.0f)}; + + if constexpr (P.hist) { + fillEPCos(vec, epCorrContainer22, epCorrContainer24, epCorrContainer44); + } + } + return {epMap.at(cfgEPRefA), ep3Map.at(cfgEPRefA)}; } - template - void fillEPCos(/*const std::index_sequence&,*/ const collision& col, const std::array& Corr) + template + void fillEPCos(const collision& col, const std::array& Corr22, const std::array& Corr42, const std::array& Corr44) { - // static constexpr std::string CosList[] = {"hCosPsi2AmC", "hCosPsi2AmB", "hCosPsi2BmC"}; - // (registry.fill(HIST(CosList[Idx]), col.centrality(), Corr[Idx], col.qPERCFT0C()[0]), ...); - registry.fill(HIST("eventQA/hCosPsi2AmC"), col.centFT0M(), Corr[0], col.qPERCFT0C()[0]); - registry.fill(HIST("eventQA/hCosPsi2AmB"), col.centFT0M(), Corr[1], col.qPERCFT0C()[0]); - registry.fill(HIST("eventQA/hCosPsi2BmC"), col.centFT0M(), Corr[2], col.qPERCFT0C()[0]); + registry.fill(HIST("eventQA/hCos2Psi2AmC"), col.centFT0M(), Corr22[0], col.qPERCFT0C()[0]); + registry.fill(HIST("eventQA/hCos2Psi2AmB"), col.centFT0M(), Corr22[1], col.qPERCFT0C()[0]); + registry.fill(HIST("eventQA/hCos2Psi2BmC"), col.centFT0M(), Corr22[2], col.qPERCFT0C()[0]); + + registry.fill(HIST("eventQA/hCos4Psi2AmC"), col.centFT0M(), Corr42[0], col.qPERCFT0C()[0]); + registry.fill(HIST("eventQA/hCos4Psi2AmB"), col.centFT0M(), Corr42[1], col.qPERCFT0C()[0]); + registry.fill(HIST("eventQA/hCos4Psi2BmC"), col.centFT0M(), Corr42[2], col.qPERCFT0C()[0]); + + registry.fill(HIST("eventQA/hCos4Psi4AmC"), col.centFT0M(), Corr44[0], col.qPERCFT0C()[0]); + registry.fill(HIST("eventQA/hCos4Psi4AmB"), col.centFT0M(), Corr44[1], col.qPERCFT0C()[0]); + registry.fill(HIST("eventQA/hCos4Psi4BmC"), col.centFT0M(), Corr44[2], col.qPERCFT0C()[0]); } - template - void fillEP(/*const std::index_sequence&,*/ const collision& col, const std::map& epMap) + template + void fillEP(const collision& col, const std::map& epMap, const std::map& ep3Map, const std::map& ep4Map) { - // static constexpr std::string_view EpList[] = {"hPsi2FT0A", "hPsi2FV0A", "hPsi2FT0C", "hPsi2TPCpos", "hPsi2TPCneg"}; - // (registry.fill(HIST(EpList[Idx]), col.centrality(), epMap.at(std::string(RemovePrefix(EpList[Idx])))), ...); registry.fill(HIST("eventQA/hPsi2FT0A"), col.centFT0M(), epMap.at("FT0A")); registry.fill(HIST("eventQA/hPsi2FV0A"), col.centFT0M(), epMap.at("FV0A")); registry.fill(HIST("eventQA/hPsi2FT0C"), col.centFT0M(), epMap.at("FT0C")); registry.fill(HIST("eventQA/hPsi2TPCpos"), col.centFT0M(), epMap.at("TPCpos")); registry.fill(HIST("eventQA/hPsi2TPCneg"), col.centFT0M(), epMap.at("TPCneg")); - } - constexpr std::string_view RemovePrefix(std::string_view str) - { - constexpr std::string_view Prefix{"hPsi2"}; - return str.substr(Prefix.size()); - } + registry.fill(HIST("eventQA/hPsi3FT0A"), col.centFT0M(), ep3Map.at("FT0A")); + registry.fill(HIST("eventQA/hPsi3FT0C"), col.centFT0M(), ep3Map.at("FT0C")); + + registry.fill(HIST("eventQA/hPsi4FT0A"), col.centFT0M(), ep4Map.at("FT0A")); + registry.fill(HIST("eventQA/hPsi4FT0C"), col.centFT0M(), ep4Map.at("FT0C")); + registry.fill(HIST("eventQA/hPsi4FV0A"), col.centFT0M(), ep4Map.at("FV0A")); + registry.fill(HIST("eventQA/hPsi4TPCpos"), col.centFT0M(), ep4Map.at("TPCpos")); + registry.fill(HIST("eventQA/hPsi4TPCneg"), col.centFT0M(), ep4Map.at("TPCneg")); + } constexpr int detIDN(const DetID id) { switch (id) { @@ -1269,14 +1344,14 @@ struct JetSpectraEseTask { return -1; } + const int secondHarmonic{2}; template - std::vector qVecNoESE(Col collision) + std::vector qVecNoESE(Col collision, int nmode = 2, int corrLevel = 3) { - // const int nmode{2}; int detId{detIDN(id)}; - int detInd{detId * 4 /*+ cfgnTotalSystem * 4 * (nmode - 2)*/}; + int detInd{detId * 4 + cfgnTotalSystem * 4 * (nmode - 2)}; if constexpr (fill) { - if (collision.qvecAmp()[detInd] > LowFT0Cut) { + if (collision.qvecAmp()[detInd] > LowFT0Cut && nmode == secondHarmonic) { registry.fill(HIST("eventQA/hQvecUncorV2"), collision.centFT0M(), collision.qvecRe()[detInd], collision.qvecIm()[detInd]); registry.fill(HIST("eventQA/hQvecRectrV2"), collision.centFT0M(), collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1]); registry.fill(HIST("eventQA/hQvecTwistV2"), collision.centFT0M(), collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2]); @@ -1287,8 +1362,8 @@ struct JetSpectraEseTask { } } std::vector qVec{}; - qVec.push_back(collision.qvecRe()[detInd + cfgnCorrLevel]); - qVec.push_back(collision.qvecIm()[detInd + cfgnCorrLevel]); + qVec.push_back(collision.qvecRe()[detInd + corrLevel]); + qVec.push_back(collision.qvecIm()[detInd + corrLevel]); qVec.push_back(collision.qvecAmp()[detId]); return qVec; } @@ -1312,6 +1387,24 @@ struct JetSpectraEseTask { return true; } + std::shared_ptr getRhoPhiFitEvent(int eventIndex) + { + switch (eventIndex) { + case 0: + return registry.get(HIST("rhoPhiFitEvents/event_0")); + case 1: + return registry.get(HIST("rhoPhiFitEvents/event_1")); + case 2: + return registry.get(HIST("rhoPhiFitEvents/event_2")); + case 3: + return registry.get(HIST("rhoPhiFitEvents/event_3")); + case 4: + return registry.get(HIST("rhoPhiFitEvents/event_4")); + default: + return nullptr; + } + } + template std::unique_ptr fitRho(const Col& col, const EventPlane& ep, TTracks const& tracks, Jets const& jets) { @@ -1331,7 +1424,7 @@ struct JetSpectraEseTask { for (const auto& track : tracks) { if constexpr (fillHist) registry.fill(HIST("trackQA/hRhoTrackCounter"), 0.5); - if (jetderiveddatautilities::selectTrack(track, trackSelection) && (std::fabs(track.eta() - leadingJetEta) > jetR) && track.pt() >= trackPtMinRhoPhi && track.pt() <= trackPtMaxRhoPhi) { + if (jetderiveddatautilities::selectTrack(track, trackSelection) && (std::fabs(track.eta() - leadingJetEta) > jetR) && track.pt() >= trackPtRhoPhi->at(0) && track.pt() <= trackPtRhoPhi->at(1)) { nTrk++; if constexpr (fillHist) registry.fill(HIST("trackQA/hRhoTrackCounter"), 1.5); @@ -1343,7 +1436,7 @@ struct JetSpectraEseTask { auto hPhiPt = std::unique_ptr(new TH1F("h_ptsum_sumpt_fit", "h_ptsum_sumpt fit use", TMath::CeilNint(std::sqrt(nTrk)), 0., o2::constants::math::TwoPI)); for (const auto& track : tracks) { - if (jetderiveddatautilities::selectTrack(track, trackSelection) && (std::fabs(track.eta() - leadingJetEta) > jetR) && track.pt() >= trackPtMinRhoPhi && track.pt() <= trackPtMaxRhoPhi) { + if (jetderiveddatautilities::selectTrack(track, trackSelection) && (std::fabs(track.eta() - leadingJetEta) > jetR) && track.pt() >= trackPtRhoPhi->at(0) && track.pt() <= trackPtRhoPhi->at(1)) { hPhiPt->Fill(track.phi(), track.pt()); if constexpr (fillHist) { registry.fill(HIST("trackQA/hRhoTrackCounter"), 2.5); @@ -1360,7 +1453,7 @@ struct JetSpectraEseTask { modulationFit->FixParameter(2, (ep.psi2 < 0) ? RecoDecay::constrainAngle(ep.psi2) : ep.psi2); modulationFit->FixParameter(4, (ep.psi3 < 0) ? RecoDecay::constrainAngle(ep.psi3) : ep.psi3); - hPhiPt->Fit(modulationFit.get(), "Q", "", 0, o2::constants::math::TwoPI); + hPhiPt->Fit(modulationFit.get(), "QN", "", 0, o2::constants::math::TwoPI); if constexpr (fillHist) { registry.fill(HIST("eventQA/hfitPar0"), col.centFT0M(), modulationFit->GetParameter(0)); @@ -1391,6 +1484,56 @@ struct JetSpectraEseTask { if constexpr (fillHist) { registry.fill(HIST("eventQA/hPValueCentCDF"), col.centFT0M(), cDF); registry.fill(HIST("eventQA/hCentChi2Ndf"), col.centFT0M(), chi2 / (static_cast(nDF))); + + static int numSavedRhoFitEvents{0}; + if (numSavedRhoFitEvents < NumSavedRhoFitEvents) { + auto savedEvent = getRhoPhiFitEvent(numSavedRhoFitEvents); + savedEvent->SetBins(hPhiPt->GetNbinsX(), 0., o2::constants::math::TwoPI); + for (int bin = 0; bin <= hPhiPt->GetNbinsX() + 1; ++bin) { + savedEvent->SetBinContent(bin, hPhiPt->GetBinContent(bin)); + savedEvent->SetBinError(bin, hPhiPt->GetBinError(bin)); + } + savedEvent->SetEntries(hPhiPt->GetEntries()); + + const double rho0 = modulationFit->GetParameter(0); + const double v2 = modulationFit->GetParameter(1); + const double psi2 = modulationFit->GetParameter(2); + const double v3 = modulationFit->GetParameter(3); + const double psi3 = modulationFit->GetParameter(4); + + auto rho0Function = std::make_unique("rho_0", "pol0", 0., o2::constants::math::TwoPI, TF1::EAddToList::kNo); + rho0Function->SetParameter(0, rho0); + rho0Function->SetParError(0, modulationFit->GetParError(0)); + rho0Function->SetParName(0, "rho_0"); + rho0Function->SetLineStyle(2); + + auto rhoPhiFunction = std::unique_ptr(static_cast(modulationFit->Clone("rho_phi"))); + rhoPhiFunction->SetParNames("rho_0", "v_2", "Psi_2", "v_3", "Psi_3"); + rhoPhiFunction->SetLineWidth(2); + rhoPhiFunction->ResetBit(TF1::kNotDraw); + + auto rhoV2Function = std::make_unique("rho_v2", "[0] * (1. + 2. * [1] * std::cos(2. * (x - [2])))", 0., o2::constants::math::TwoPI, TF1::EAddToList::kNo); + rhoV2Function->SetParameters(rho0, v2, psi2); + rhoV2Function->SetParError(0, modulationFit->GetParError(0)); + rhoV2Function->SetParError(1, modulationFit->GetParError(1)); + rhoV2Function->SetParError(2, modulationFit->GetParError(2)); + rhoV2Function->SetParNames("rho_0", "v_2", "Psi_2"); + rhoV2Function->SetLineStyle(7); + + auto rhoV3Function = std::make_unique("rho_v3", "[0] * (1. + 2. * [1] * std::cos(3. * (x - [2])))", 0., o2::constants::math::TwoPI, TF1::EAddToList::kNo); + rhoV3Function->SetParameters(rho0, v3, psi3); + rhoV3Function->SetParError(0, modulationFit->GetParError(0)); + rhoV3Function->SetParError(1, modulationFit->GetParError(3)); + rhoV3Function->SetParError(2, modulationFit->GetParError(4)); + rhoV3Function->SetParNames("rho_0", "v_3", "Psi_3"); + rhoV3Function->SetLineStyle(9); + + savedEvent->GetListOfFunctions()->Add(rho0Function.release()); + savedEvent->GetListOfFunctions()->Add(rhoPhiFunction.release()); + savedEvent->GetListOfFunctions()->Add(rhoV2Function.release()); + savedEvent->GetListOfFunctions()->Add(rhoV3Function.release()); + ++numSavedRhoFitEvents; + } } return modulationFit; @@ -1436,17 +1579,17 @@ struct JetSpectraEseTask { } registry.fill(HIST("hCentRhoRandomCone"), collision.centFT0M(), randomConePt - o2::constants::math::PI * randomConeR * randomConeR * collision.rho()); - randomConePt = 0; + float randomConePtRandomTrackDir = 0; for (auto const& track : tracks) { if (jetderiveddatautilities::selectTrack(track, trackSelection)) { float dPhi = RecoDecay::constrainAngle(randomNumber.Uniform(0.0, o2::constants::math::TwoPI) - randomConePhi, -o2::constants::math::PI); float dEta = randomNumber.Uniform(trackEtaMin, trackEtaMax) - randomConeEta; if (std::sqrt(dEta * dEta + dPhi * dPhi) < randomConeR) { - randomConePt += track.pt(); + randomConePtRandomTrackDir += track.pt(); } } } - registry.fill(HIST("hCentRhoRandomConeRandomTrackDir"), collision.centFT0M(), randomConePt - o2::constants::math::PI * randomConeR * randomConeR * collision.rho()); + registry.fill(HIST("hCentRhoRandomConeRandomTrackDir"), collision.centFT0M(), randomConePtRandomTrackDir - o2::constants::math::PI * randomConeR * randomConeR * collision.rho()); if (jets.size() > 0) { float dPhiLeadingJet = RecoDecay::constrainAngle(jets.iteratorAt(0).phi() - randomConePhi, -o2::constants::math::PI); @@ -1502,6 +1645,8 @@ struct JetSpectraEseTask { } } } + registry.fill(HIST("h3CentdeltapTRndmConePhi_rhovsphi"), collision.centFT0M(), randomConePt - o2::constants::math::PI * randomConeR * randomConeR * collision.rho(), dPhiRC); + registry.fill(HIST("h3CentdeltapTRndmConePhi_localrhovsphi"), collision.centFT0M(), randomConePt - o2::constants::math::PI * randomConeR * randomConeR * rho, dPhiRC); registry.fill(HIST("hCentRhoRandomConeRndTrackDirwoOneLeadingJet"), collision.centFT0M(), randomConePtWithoutOneLeadJet - o2::constants::math::PI * randomConeR * randomConeR * rho, dPhiRC, qPerc[0]); registry.fill(HIST("hCentRhoRandomConeRndTrackDirwoTwoLeadingJet"), collision.centFT0M(), randomConePtWithoutTwoLeadJet - o2::constants::math::PI * randomConeR * randomConeR * rho, dPhiRC, qPerc[0]); } @@ -1526,7 +1671,7 @@ struct JetSpectraEseTask { { float weight = 1.0; for (const auto& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + if (!jetfindingutilities::isInEtaAcceptance(jet, cfgJetEta->at(0), cfgJetEta->at(1), trackEtaMin, trackEtaMax)) { continue; } if (!isAcceptedJet(jet)) { @@ -1549,7 +1694,7 @@ struct JetSpectraEseTask { bool mcLevelIsParticleLevel = true; float weight = 1.0; for (const auto& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + if (!jetfindingutilities::isInEtaAcceptance(jet, cfgJetEta->at(0), cfgJetEta->at(1), trackEtaMin, trackEtaMax)) { continue; } if (!isAcceptedJet(jet, mcLevelIsParticleLevel)) { @@ -1571,7 +1716,7 @@ struct JetSpectraEseTask { { float weight = 1.0; for (const auto& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + if (!jetfindingutilities::isInEtaAcceptance(jet, cfgJetEta->at(0), cfgJetEta->at(1), trackEtaMin, trackEtaMax)) { continue; } if (!isAcceptedJet(jet)) { @@ -1620,9 +1765,9 @@ struct JetSpectraEseTask { float leadJetEta = -999; bool hasLeadingJet = false; for (const auto& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) + if (!jetfindingutilities::isInEtaAcceptance(jet, cfgJetEta->at(0), cfgJetEta->at(1), trackEtaMin, trackEtaMax)) continue; - if (!isAcceptedJet(jet)) { + if (!isAcceptedJet>(jet)) { continue; } auto jetPtBkg = jet.pt() - (collision.rho() * jet.area()); diff --git a/PWGJE/Tasks/nucleiInJets.cxx b/PWGJE/Tasks/nucleiInJets.cxx index f6a419992b8..ab6554a4bb0 100644 --- a/PWGJE/Tasks/nucleiInJets.cxx +++ b/PWGJE/Tasks/nucleiInJets.cxx @@ -17,6 +17,7 @@ #include "PWGJE/DataModel/JetSubtraction.h" // #include "PWGLF/DataModel/LFParticleIdentification.h" +#include "PWGLF/DataModel/mcCentrality.h" #include "PWGLF/Utils/inelGt.h" #include "Common/Core/RecoDecay.h" @@ -163,6 +164,8 @@ struct nucleiInJets { Configurable useTOFVeto{"useTOFVeto", false, "true: use TOF veto, false: no TOF veto"}; Configurable isRequireHitsInITSLayers{"isRequireHitsInITSLayers", true, "true: at least one hit in the its inner layes"}; Configurable useMcC{"useMcC", true, "use mcC"}; + Configurable usebkgSubractionMC{"usebkgSubractionMC", true, "use rho-area background subtraction for detector-level matched MC jets"}; + Configurable cfgjetPtBkgSubMinMC{"cfgjetPtBkgSubMinMC", 10.0f, "minimum detector-level matched MC jet pT after optional background subtraction"}; Configurable useRapidityCutForPID{"useRapidityCutForPID", false, "true: use rapidity cut for PID, false: no rapidity cut for PID"}; Configurable addpik{"addpik", true, "add pion and kaon hist"}; @@ -188,6 +191,7 @@ struct nucleiInJets { // using EventTable = soa::Join; using EventTable = aod::JetCollisions; using EventTableMC = soa::Join; + using JetMcCollisionWithCent = soa::Join::iterator; using JetCollWithLabel = o2::soa::Join::iterator; using TrackCandidates = soa::Join(HIST("hNEvents"))->GetXaxis()->SetBinLabel(1, "All"); jetHist.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(2, "Skimmed"); jetHist.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(3, "|Vz|<10"); - jetHist.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(4, "Sel8+|Vz|<10"); - jetHist.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(5, "nJets>0"); + jetHist.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(4, "Sel8"); + jetHist.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(5, "noSameBunchPileup"); + jetHist.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(6, "isGoodZvtxFT0vsPV"); + jetHist.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(7, "OccupancySel"); + jetHist.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(8, "nJets>0"); jetHist.add("hNEventsInc", "hNEventsInc", {HistType::kTH1D, {{6, 0.f, 6.f}}}); jetHist.get(HIST("hNEventsInc"))->GetXaxis()->SetBinLabel(1, "All"); @@ -424,9 +431,13 @@ struct nucleiInJets { jetHist.add("tracks/antiKaon/h2TofNsigmaantiKaonVsPt_jet", "h2TofNsigmaantiKaonVsPt_jet; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH2F, {{100, -5, 5}, {50, 0., 5.}}); } jetHist.add("tracks/proton/h2TofNsigmaProtonVsPt_jet", "h2TofNsigmaProtonVsPt_jet; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH2F, {{100, -5, 5}, {50, 0., 5.}}); + jetHist.add("tracks/proton/h3TofNsigmaProtonVsPtVsJetPtBkgSub_jet", "h3TofNsigmaProtonVsPtVsJetPtBkgSub_jet; TofNsigma; #it{p}_{T} (GeV); jet #it{p}_{T} (Bkg Sub) (GeV)", HistType::kTH3F, {{100, -5, 5}, {50, 0., 5.}, {PtJetAxis}}); jetHist.add("tracks/antiProton/h2TofNsigmaantiProtonVsPt_jet", "h2TofNsigmaantiProtonVsPt_jet; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH2F, {{100, -5, 5}, {50, 0., 5.}}); + jetHist.add("tracks/antiProton/h3TofNsigmaantiProtonVsPtVsJetPtBkgSub_jet", "h3TofNsigmaantiProtonVsPtVsJetPtBkgSub_jet; TofNsigma; #it{p}_{T} (GeV); jet #it{p}_{T} (Bkg Sub) (GeV)", HistType::kTH3F, {{100, -5, 5}, {50, 0., 5.}, {PtJetAxis}}); jetHist.add("tracks/deuteron/h2TofNsigmaDeuteronVsPt_jet", "h2TofNsigmaDeuteronVsPt_jet; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH2F, {{100, -5, 5}, {50, 0., 5.}}); + jetHist.add("tracks/deuteron/h3TofNsigmaDeuteronVsPtVsJetPtBkgSub_jet", "h3TofNsigmaDeuteronVsPtVsJetPtBkgSub_jet; TofNsigma; #it{p}_{T} (GeV); jet #it{p}_{T} (Bkg Sub) (GeV)", HistType::kTH3F, {{100, -5, 5}, {50, 0., 5.}, {PtJetAxis}}); jetHist.add("tracks/antiDeuteron/h2TofNsigmaantiDeuteronVsPt_jet", "h2TofNsigmaantiDeuteronVsPt_jet; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH2F, {{100, -5, 5}, {50, 0., 5.}}); + jetHist.add("tracks/antiDeuteron/h3TofNsigmaantiDeuteronVsPtVsJetPtBkgSub_jet", "h3TofNsigmaantiDeuteronVsPtVsJetPtBkgSub_jet; TofNsigma; #it{p}_{T} (GeV); jet #it{p}_{T} (Bkg Sub) (GeV)", HistType::kTH3F, {{100, -5, 5}, {50, 0., 5.}, {PtJetAxis}}); jetHist.add("tracks/triton/h2TofNsigmaTritonVsPt_jet", "h2TofNsigmaTritonVsPt_jet; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH2F, {{100, -5, 5}, {50, 0., 5.}}); jetHist.add("tracks/antiTriton/h2TofNsigmaantiTritonVsPt_jet", "h2TofNsigmaantiTritonVsPt_jet; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH2F, {{100, -5, 5}, {50, 0., 5.}}); jetHist.add("tracks/helium/h2TofNsigmaHeliumVsPt_jet", "h2TofNsigmaHeliumVsPt_jet; TofNsigma; #it{p}_{T}/z (GeV)", HistType::kTH2F, {{100, -5, 5}, {50, 0., 5.}}); @@ -591,13 +602,16 @@ struct nucleiInJets { // Event and signal loss analysis histograms (inclusive) jetHist.add("eventLoss/hEventStatistics", "Event Statistics for Loss Analysis", kTH1F, {{10, 0.f, 10.f}}); jetHist.get(HIST("eventLoss/hEventStatistics"))->GetXaxis()->SetBinLabel(1, "All Generated"); - jetHist.get(HIST("eventLoss/hEventStatistics"))->GetXaxis()->SetBinLabel(2, "Gen |Vz|<10"); + jetHist.get(HIST("eventLoss/hEventStatistics"))->GetXaxis()->SetBinLabel(2, "Gen |Vz| cut"); jetHist.get(HIST("eventLoss/hEventStatistics"))->GetXaxis()->SetBinLabel(3, "Gen True INEL>0"); jetHist.get(HIST("eventLoss/hEventStatistics"))->GetXaxis()->SetBinLabel(4, "Has Reco Coll"); jetHist.get(HIST("eventLoss/hEventStatistics"))->GetXaxis()->SetBinLabel(5, "Pass Sel8"); - jetHist.get(HIST("eventLoss/hEventStatistics"))->GetXaxis()->SetBinLabel(6, "Pass |Vz|<10"); - jetHist.get(HIST("eventLoss/hEventStatistics"))->GetXaxis()->SetBinLabel(7, "Pass rec INEL>0"); - jetHist.get(HIST("eventLoss/hEventStatistics"))->GetXaxis()->SetBinLabel(8, "EvSelPassedRecINELgt0"); + jetHist.get(HIST("eventLoss/hEventStatistics"))->GetXaxis()->SetBinLabel(6, "Pass reco |Vz| cut"); + jetHist.get(HIST("eventLoss/hEventStatistics"))->GetXaxis()->SetBinLabel(7, "Pass extra event sel"); + jetHist.get(HIST("eventLoss/hEventStatistics"))->GetXaxis()->SetBinLabel(8, "Reco selected"); + jetHist.get(HIST("eventLoss/hEventStatistics"))->GetXaxis()->SetBinLabel(9, "Reco selected + true INEL>0"); + jetHist.add("eventLoss/hRecoCollPerMCCollVsCent", "Reco collisions per MC collision;N_{reco coll};Centrality", HistType::kTH2F, {{10, -0.5f, 9.5f}, {100, 0.f, 100.f}}); + jetHist.add("eventLoss/hSelectedRecoCollPerMCCollVsCent", "Selected reco collisions per MC collision;N_{selected reco coll};Centrality", HistType::kTH2F, {{10, -0.5f, 9.5f}, {100, 0.f, 100.f}}); // Signal loss histograms (only the ones that are actually used) jetHist.add("eventLoss/signalLoss/h3GenParticlesPtVsEtaVsCent_INELgt0", "Generated Particles p_{T} vs #eta vs Centrality", HistType::kTH3F, {{PtAxis}, {100, -1.5f, 1.5f}, {100, 0, 100}}); @@ -724,6 +738,10 @@ struct nucleiInJets { jetHist.add("eff/recmatched/perpCone/pt/PtParticleTypeTPCTOFVeto", "Pt (p) vs particletype", HistType::kTH2D, {{PtAxis}, {14, -7, 7}}); jetHist.add("eff/recmatched/gen/pt/PtParticleType", "Pt (p) vs jetflag vs particletype", HistType::kTH3D, {{PtAxis}, {2, 0, 2}, {14, -7, 7}}); jetHist.add("eff/recmatched/gen/perpCone/pt/PtParticleType", "Pt (p) vs particletype", HistType::kTH2D, {{PtAxis}, {14, -7, 7}}); + jetHist.add("eff/recmatched/mcC/gen/pt/PtParticleType", "Pt (gen, mcC) vs jetflag vs particletype", HistType::kTH3D, {{PtAxis}, {2, 0, 2}, {14, -7, 7}}); + jetHist.add("eff/recmatched/mcCSpectra/gen/pt/PtParticleType", "Pt (gen, mcCSpectra) vs jetflag vs particletype", HistType::kTH3D, {{PtAxis}, {2, 0, 2}, {14, -7, 7}}); + jetHist.add("eff/recmatched/mcC/gen/perpCone/pt/PtParticleType", "Pt (gen, mcC, perp cone) vs particletype", HistType::kTH2D, {{PtAxis}, {14, -7, 7}}); + jetHist.add("eff/recmatched/mcCSpectra/gen/perpCone/pt/PtParticleType", "Pt (gen, mcCSpectra, perp cone) vs particletype", HistType::kTH2D, {{PtAxis}, {14, -7, 7}}); // gen matched jetHist.add("genmatched/hRecMatchedJetPt", "matched jet pT (Rec level);#it{p}_{T,jet part} (GeV/#it{c}); #it{p}_{T,jet part} - #it{p}_{T,jet det}", HistType::kTH2F, {{100, 0., 100.}, {400, -20., 20.}}); jetHist.add("genmatched/hRecMatchedVsGenJetPt", "matched jet pT (Rec level);#it{p}_{T,jet det}; #it{p}_{T,jet part} (GeV/#it{c})", HistType::kTH2F, {{100, 0., 100.}, {100, 0., 100.}}); @@ -1012,6 +1030,8 @@ struct nucleiInJets { jetHist.fill(HIST("tracks/proton/h3TOFmass2ProtonVsPtVsJetPtBkgSub_jet"), massTOF * massTOF - MassProton * MassProton, trk.pt(), jetPtBkgSub); jetHist.fill(HIST("tracks/deuteron/h3TOFmassDeuteronVsPtVsJetPtBkgSub_jet"), massTOF, trk.pt(), jetPtBkgSub); jetHist.fill(HIST("tracks/deuteron/h3TOFmass2DeuteronVsPtVsJetPtBkgSub_jet"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt(), jetPtBkgSub); + jetHist.fill(HIST("tracks/proton/h3TofNsigmaProtonVsPtVsJetPtBkgSub_jet"), trk.tofNSigmaPr(), trk.pt(), jetPtBkgSub); + jetHist.fill(HIST("tracks/deuteron/h3TofNsigmaDeuteronVsPtVsJetPtBkgSub_jet"), trk.tofNSigmaDe(), trk.pt(), jetPtBkgSub); jetHist.fill(HIST("tracks/triton/h3TOFmassTritonVsPtVsJetPtBkgSub_jet"), massTOF, trk.pt(), jetPtBkgSub); jetHist.fill(HIST("tracks/triton/h3TOFmass2TritonVsPtVsJetPtBkgSub_jet"), massTOF * massTOF - MassTriton * MassTriton, trk.pt(), jetPtBkgSub); jetHist.fill(HIST("tracks/helium/h3TOFmassHeliumVsPtVsJetPtBkgSub_jet"), massTOF, trk.pt() / 2.0, jetPtBkgSub); @@ -1030,6 +1050,7 @@ struct nucleiInJets { if (backgroundRho > 0) { jetHist.fill(HIST("tracks/proton/h3TOFmassProtonVsPtVsJetPtBkgSub_jet"), massTOF, trk.pt(), jetPtBkgSub); jetHist.fill(HIST("tracks/proton/h3TOFmass2ProtonVsPtVsJetPtBkgSub_jet"), massTOF * massTOF - MassProton * MassProton, trk.pt(), jetPtBkgSub); + jetHist.fill(HIST("tracks/proton/h3TofNsigmaProtonVsPtVsJetPtBkgSub_jet"), trk.tofNSigmaPr(), trk.pt(), jetPtBkgSub); } jetHist.fill(HIST("tracks/proton/h2TofNsigmaProtonVsPt_jet"), trk.tofNSigmaPr(), trk.pt()); jetHist.fill(HIST("tracks/proton/h3TpcNsigmaTofNsigmaProtonVsPt_jet"), trk.tpcNSigmaPr(), trk.tofNSigmaPr(), trk.pt()); @@ -1040,6 +1061,7 @@ struct nucleiInJets { if (backgroundRho > 0) { jetHist.fill(HIST("tracks/deuteron/h3TOFmassDeuteronVsPtVsJetPtBkgSub_jet"), massTOF, trk.pt(), jetPtBkgSub); jetHist.fill(HIST("tracks/deuteron/h3TOFmass2DeuteronVsPtVsJetPtBkgSub_jet"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt(), jetPtBkgSub); + jetHist.fill(HIST("tracks/deuteron/h3TofNsigmaDeuteronVsPtVsJetPtBkgSub_jet"), trk.tofNSigmaDe(), trk.pt(), jetPtBkgSub); } jetHist.fill(HIST("tracks/deuteron/h2TofNsigmaDeuteronVsPt_jet"), trk.tofNSigmaDe(), trk.pt()); jetHist.fill(HIST("tracks/deuteron/h3TpcNsigmaTofNsigmaDeuteronVsPt_jet"), trk.tpcNSigmaDe(), trk.tofNSigmaDe(), trk.pt()); @@ -1202,6 +1224,8 @@ struct nucleiInJets { jetHist.fill(HIST("tracks/antiProton/h3TOFmass2antiProtonVsPtVsJetPtBkgSub_jet"), massTOF * massTOF - MassProton * MassProton, trk.pt(), jetPtBkgSub); jetHist.fill(HIST("tracks/antiDeuteron/h3TOFmassantiDeuteronVsPtVsJetPtBkgSub_jet"), massTOF, trk.pt(), jetPtBkgSub); jetHist.fill(HIST("tracks/antiDeuteron/h3TOFmass2antiDeuteronVsPtVsJetPtBkgSub_jet"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt(), jetPtBkgSub); + jetHist.fill(HIST("tracks/antiProton/h3TofNsigmaantiProtonVsPtVsJetPtBkgSub_jet"), trk.tofNSigmaPr(), trk.pt(), jetPtBkgSub); + jetHist.fill(HIST("tracks/antiDeuteron/h3TofNsigmaantiDeuteronVsPtVsJetPtBkgSub_jet"), trk.tofNSigmaDe(), trk.pt(), jetPtBkgSub); jetHist.fill(HIST("tracks/antiTriton/h3TOFmassantiTritonVsPtVsJetPtBkgSub_jet"), massTOF, trk.pt(), jetPtBkgSub); jetHist.fill(HIST("tracks/antiTriton/h3TOFmass2antiTritonVsPtVsJetPtBkgSub_jet"), massTOF * massTOF - MassTriton * MassTriton, trk.pt(), jetPtBkgSub); jetHist.fill(HIST("tracks/antiHelium/h3TOFmassantiHeliumVsPtVsJetPtBkgSub_jet"), massTOF, trk.pt() / 2.0, jetPtBkgSub); @@ -1214,6 +1238,7 @@ struct nucleiInJets { if (backgroundRho > 0) { jetHist.fill(HIST("tracks/antiProton/h3TOFmassantiProtonVsPtVsJetPtBkgSub_jet"), massTOF, trk.pt(), jetPtBkgSub); jetHist.fill(HIST("tracks/antiProton/h3TOFmass2antiProtonVsPtVsJetPtBkgSub_jet"), massTOF * massTOF - MassProton * MassProton, trk.pt(), jetPtBkgSub); + jetHist.fill(HIST("tracks/antiProton/h3TofNsigmaantiProtonVsPtVsJetPtBkgSub_jet"), trk.tofNSigmaPr(), trk.pt(), jetPtBkgSub); } jetHist.fill(HIST("tracks/antiProton/h2TofNsigmaantiProtonVsPt_jet"), trk.tofNSigmaPr(), trk.pt()); jetHist.fill(HIST("tracks/antiProton/h3TpcNsigmaTofNsigmaantiProtonVsPt_jet"), trk.tpcNSigmaPr(), trk.tofNSigmaPr(), trk.pt()); @@ -1221,6 +1246,11 @@ struct nucleiInJets { if (std::abs(trk.tpcNSigmaDe()) < cfgnTPCPIDDe) { jetHist.fill(HIST("tracks/antiDeuteron/h3TOFmassantiDeuteronVsPtVsJetPt_jet"), massTOF, trk.pt(), jetPt); jetHist.fill(HIST("tracks/antiDeuteron/h3TOFmass2antiDeuteronVsPtVsJetPt_jet"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt(), jetPt); + if (backgroundRho > 0) { + jetHist.fill(HIST("tracks/antiDeuteron/h3TOFmassantiDeuteronVsPtVsJetPtBkgSub_jet"), massTOF, trk.pt(), jetPtBkgSub); + jetHist.fill(HIST("tracks/antiDeuteron/h3TOFmass2antiDeuteronVsPtVsJetPtBkgSub_jet"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt(), jetPtBkgSub); + jetHist.fill(HIST("tracks/antiDeuteron/h3TofNsigmaantiDeuteronVsPtVsJetPtBkgSub_jet"), trk.tofNSigmaDe(), trk.pt(), jetPtBkgSub); + } jetHist.fill(HIST("tracks/antiDeuteron/h2TofNsigmaantiDeuteronVsPt_jet"), trk.tofNSigmaDe(), trk.pt()); jetHist.fill(HIST("tracks/antiDeuteron/h3TpcNsigmaTofNsigmaantiDeuteronVsPt_jet"), trk.tpcNSigmaDe(), trk.tofNSigmaDe(), trk.pt()); } @@ -1609,8 +1639,8 @@ struct nucleiInJets { { auto bc = collision.bc_as(); initCCDB(bc); + jetHist.fill(HIST("hNEvents"), 0.5); if (applySkim) { - jetHist.fill(HIST("hNEvents"), 0.5); bool zorroSelected = zorro.isSelected(bc.globalBC()); if (!zorroSelected) { return; @@ -1623,6 +1653,15 @@ struct nucleiInJets { if (!jetderiveddatautilities::selectCollision(collision, jetderiveddatautilities::initialiseEventSelectionBits("sel8"))) return; jetHist.fill(HIST("hNEvents"), 3.5); + if (selNoSameBunchPileup && !jetderiveddatautilities::selectCollision(collision, jetderiveddatautilities::initialiseEventSelectionBits("NoSameBunchPileup"))) + return; + jetHist.fill(HIST("hNEvents"), 4.5); + if (selIsGoodZvtxFT0vsPV && !jetderiveddatautilities::selectCollision(collision, jetderiveddatautilities::initialiseEventSelectionBits("IsGoodZvtxFT0vsPV"))) + return; + jetHist.fill(HIST("hNEvents"), 5.5); + if (useOccupancy && !isOccupancyAccepted(collision)) + return; + jetHist.fill(HIST("hNEvents"), 6.5); int nJets = 0; std::vector leadingJetWithPtEtaPhi(3); float leadingJetPt = -1.0f; @@ -1655,7 +1694,7 @@ struct nucleiInJets { jetHist.fill(HIST("vertexZ"), collision.posZ()); if (nJets > 0) { jetHist.fill(HIST("jet/vertexZ"), collision.posZ()); - jetHist.fill(HIST("hNEvents"), 4.5); + jetHist.fill(HIST("hNEvents"), 7.5); } else { jetHist.fill(HIST("jetOut/vertexZ"), collision.posZ()); } @@ -1673,8 +1712,8 @@ struct nucleiInJets { { auto bc = collision.bc_as(); initCCDB(bc); + jetHist.fill(HIST("hNEvents"), 0.5); if (applySkim) { - jetHist.fill(HIST("hNEvents"), 0.5); bool zorroSelected = zorro.isSelected(bc.globalBC()); if (!zorroSelected) { return; @@ -1688,6 +1727,15 @@ struct nucleiInJets { if (!jetderiveddatautilities::selectCollision(collision, jetderiveddatautilities::initialiseEventSelectionBits("sel8"))) return; jetHist.fill(HIST("hNEvents"), 3.5); + if (selNoSameBunchPileup && !jetderiveddatautilities::selectCollision(collision, jetderiveddatautilities::initialiseEventSelectionBits("NoSameBunchPileup"))) + return; + jetHist.fill(HIST("hNEvents"), 4.5); + if (selIsGoodZvtxFT0vsPV && !jetderiveddatautilities::selectCollision(collision, jetderiveddatautilities::initialiseEventSelectionBits("IsGoodZvtxFT0vsPV"))) + return; + jetHist.fill(HIST("hNEvents"), 5.5); + if (useOccupancy && !isOccupancyAccepted(collision)) + return; + jetHist.fill(HIST("hNEvents"), 6.5); int nJets = 0; std::vector leadingJetWithPtEtaPhi(3); float leadingJetPt = -1.0f; @@ -1720,7 +1768,7 @@ struct nucleiInJets { jetHist.fill(HIST("vertexZ"), collision.posZ()); if (nJets > 0) { jetHist.fill(HIST("jet/vertexZ"), collision.posZ()); - jetHist.fill(HIST("hNEvents"), 4.5); + jetHist.fill(HIST("hNEvents"), 7.5); } else { jetHist.fill(HIST("jetOut/vertexZ"), collision.posZ()); } @@ -2172,6 +2220,14 @@ struct nucleiInJets { jetHist.fill(HIST("recmatched/vertexZ"), collision.posZ()); + // Event-wise random splitting for closure test: decide once per event + bool useDataLikeHist = (randUniform.Uniform(0, 1) < 0.5); + const float backgroundRho = collision.rho(); + const float jetArea = M_PI * cfgjetR * cfgjetR; + if (usebkgSubractionMC) { + jetHist.fill(HIST("jet/h1BkgRho"), backgroundRho); + } + std::vector mcdJetPt{}; std::vector mcdJetPhi{}; std::vector mcdJetEta{}; @@ -2191,21 +2247,25 @@ struct nucleiInJets { if (!mcpjet.has_matchedJetGeo()) continue; - mcdJetPt.push_back(mcdjet.pt()); + const float mcdJetPtForResponse = usebkgSubractionMC ? mcdjet.pt() - backgroundRho * jetArea : mcdjet.pt(); + if (mcdJetPtForResponse < cfgjetPtBkgSubMinMC) { + continue; + } + mcdJetPt.push_back(mcdJetPtForResponse); mcdJetPhi.push_back(mcdjet.phi()); mcdJetEta.push_back(mcdjet.eta()); mcpJetPt.push_back(mcpjet.pt()); mcpJetPhi.push_back(mcpjet.phi()); mcpJetEta.push_back(mcpjet.eta()); - jetHist.fill(HIST("recmatched/hRecMatchedJetPt"), mcpjet.pt(), mcpjet.pt() - mcdjet.pt()); + jetHist.fill(HIST("recmatched/hRecMatchedJetPt"), mcpjet.pt(), mcpjet.pt() - mcdJetPtForResponse); jetHist.fill(HIST("recmatched/hRecMatchedJetPhi"), mcpjet.phi(), mcpjet.phi() - mcdjet.phi()); jetHist.fill(HIST("recmatched/hRecMatchedJetEta"), mcpjet.eta(), mcpjet.eta() - mcdjet.eta()); - jetHist.fill(HIST("recmatched/hRecMatchedVsGenJetPtVsEta"), mcdjet.pt(), mcdjet.eta()); - jetHist.fill(HIST("recmatched/hRecJetPt"), mcdjet.pt()); + jetHist.fill(HIST("recmatched/hRecMatchedVsGenJetPtVsEta"), mcdJetPtForResponse, mcdjet.eta()); + jetHist.fill(HIST("recmatched/hRecJetPt"), mcdJetPtForResponse); jetHist.fill(HIST("recmatched/hGenJetPt"), mcpjet.pt()); - jetHist.fill(HIST("recmatched/h2ResponseMatrix"), mcdjet.pt(), mcpjet.pt()); + jetHist.fill(HIST("recmatched/h2ResponseMatrix"), mcdJetPtForResponse, mcpjet.pt()); } // mcpJet } // mcdJet @@ -2219,7 +2279,7 @@ struct nucleiInJets { LOGP(fatal, "Error: Index {} is out of range for vectors!", indexJet); } if (useMcC) { - if (randUniform.Uniform(0, 1) < 0.5) + if (useDataLikeHist) jetHist.fill(HIST("recmatched/h2ResponseMatrixLeadingJet"), mcdJetPt.at(indexJet), mcpJetPt.at(indexJet)); else jetHist.fill(HIST("recmatched/mcC/h2ResponseMatrixLeadingJet"), mcdJetPt.at(indexJet), mcpJetPt.at(indexJet)); @@ -2287,7 +2347,7 @@ struct nucleiInJets { bool isTpcPassed(true); // why is this always true? jetHist.fill(HIST("eff/recmatched/pt/PtParticleType"), mcTrack.pt(), jetFlag, mapPDGToValue(mcTrack.pdgCode())); if (useMcC) { - if (randUniform.Uniform(0, 1) < 0.5) + if (useDataLikeHist) jetHist.fill(HIST("eff/recmatched/mcC/pt/PtParticleType"), track.pt(), mcTrack.pt(), mapPDGToValue(mcTrack.pdgCode())); else jetHist.fill(HIST("eff/recmatched/mcCSpectra/pt/PtParticleType"), track.pt(), mcTrack.pt(), mapPDGToValue(mcTrack.pdgCode())); @@ -2306,7 +2366,7 @@ struct nucleiInJets { if (jetFlagPerpCone) { jetHist.fill(HIST("eff/recmatched/perpCone/pt/PtParticleType"), mcTrack.pt(), mapPDGToValue(mcTrack.pdgCode())); if (useMcC) { - if (randUniform.Uniform(0, 1) < 0.5) + if (useDataLikeHist) jetHist.fill(HIST("eff/recmatched/perpCone/mcC/pt/PtParticleType"), track.pt(), mcTrack.pt(), mapPDGToValue(mcTrack.pdgCode())); else jetHist.fill(HIST("eff/recmatched/perpCone/mcCSpectra/pt/PtParticleType"), track.pt(), mcTrack.pt(), mapPDGToValue(mcTrack.pdgCode())); @@ -2363,8 +2423,22 @@ struct nucleiInJets { if (mapPDGToValue(mcParticle.pdgCode()) != 0) { jetHist.fill(HIST("eff/recmatched/gen/pt/PtParticleType"), mcParticle.pt(), jetFlagMC, mapPDGToValue(mcParticle.pdgCode())); + if (useMcC) { + if (useDataLikeHist) { + jetHist.fill(HIST("eff/recmatched/mcC/gen/pt/PtParticleType"), mcParticle.pt(), jetFlagMC, mapPDGToValue(mcParticle.pdgCode())); + } else { + jetHist.fill(HIST("eff/recmatched/mcCSpectra/gen/pt/PtParticleType"), mcParticle.pt(), jetFlagMC, mapPDGToValue(mcParticle.pdgCode())); + } + } if (jetFlagPerpConeMC) { jetHist.fill(HIST("eff/recmatched/gen/perpCone/pt/PtParticleType"), mcParticle.pt(), mapPDGToValue(mcParticle.pdgCode())); + if (useMcC) { + if (useDataLikeHist) { + jetHist.fill(HIST("eff/recmatched/mcC/gen/perpCone/pt/PtParticleType"), mcParticle.pt(), mapPDGToValue(mcParticle.pdgCode())); + } else { + jetHist.fill(HIST("eff/recmatched/mcCSpectra/gen/perpCone/pt/PtParticleType"), mcParticle.pt(), mapPDGToValue(mcParticle.pdgCode())); + } + } } } } // mcParticle @@ -2391,6 +2465,9 @@ struct nucleiInJets { return; jetHist.fill(HIST("genmatched/vertexZ"), collision.posZ()); + // Event-wise random splitting for closure test: decide once per event + bool useDataLikeHist = (randUniform.Uniform(0, 1) < 0.5); + std::vector mcpJetPt{}; std::vector mcpJetPhi{}; std::vector mcpJetEta{}; @@ -2441,7 +2518,7 @@ struct nucleiInJets { jetHist.fill(HIST("genmatched/hRecMatchedJetEta"), leadingMCPJet.eta(), leadingMCPJet.eta() - mcdjet.eta()); if (useMcC) { - if (randUniform.Uniform(0, 1) < 0.5) { + if (useDataLikeHist) { jetHist.fill(HIST("genmatched/hRecMatchedVsGenJetPt"), mcdjet.pt(), leadingMCPJet.pt()); } else { jetHist.fill(HIST("genmatched/mcC/hRecMatchedVsGenJetPt"), mcdjet.pt(), leadingMCPJet.pt()); @@ -2660,76 +2737,95 @@ struct nucleiInJets { } // Process function for event and signal loss analysis (inclusive) - void processEventSignalLoss(aod::JetMcCollision const& mcCollision, + void processEventSignalLoss(JetMcCollisionWithCent const& mcCollision, soa::SmallGroups> const& recoColls, aod::JetParticles const& mcParticles, TrackCandidates const&) { - - // Fill generated event statistics jetHist.fill(HIST("eventLoss/hEventStatistics"), 0.5); // All Generated - // Check if we have a reconstructed collision - bool hasRecoColl = false; - bool passSel8 = false; - bool passVz = false; - bool passINELgt0 = false; - bool isSel8 = false; - - float centrality = -999; + auto mcParticles_perColl = mcParticles.sliceBy(perMCCol, mcCollision.globalIndex()); + float centrality = -999.f; switch (centralityType) { - case 0: // FT0M + case 0: centrality = mcCollision.centFT0M(); break; - case 1: // FT0C - centrality = mcCollision.multFT0C(); + case 1: + centrality = mcCollision.centFT0C(); break; - case 2: // V0A - centrality = mcCollision.multFV0A(); + case 2: + centrality = mcCollision.centFV0A(); break; default: - centrality = -999; + centrality = mcCollision.centFT0M(); + break; } + const bool passGenVz = std::abs(mcCollision.posZ()) < cfgMaxZVertex; + const bool mcINELgt0 = o2::pwglf::isINELgt0mc(mcParticles_perColl, pdgDB); - // Check INEL>0 at MC level using PWGLF functionality - bool mcINELgt0 = o2::pwglf::isINELgt0mc(mcParticles, pdgDB); - if (mcCollision.posZ() < 10) { - jetHist.fill(HIST("eventLoss/hEventStatistics"), 1.5); - if (mcINELgt0) { - jetHist.fill(HIST("eventLoss/hEventStatistics"), 2.5); - } + if (!passGenVz) { + return; + } + jetHist.fill(HIST("eventLoss/hEventStatistics"), 1.5); // Gen |Vz| cut + + if (!mcINELgt0) { + return; } + jetHist.fill(HIST("eventLoss/hEventStatistics"), 2.5); // Gen True INEL>0 + int nRecoColls = 0; + int nSelectedRecoColls = 0; + bool hasRecoColl = false; + bool passSel8 = false; + bool passRecoVz = false; + bool passExtraEventSel = false; + bool hasSelectedRecoColl = false; for (const auto& recoColl : recoColls) { + ++nRecoColls; hasRecoColl = true; - if (jetderiveddatautilities::selectCollision(recoColl, jetderiveddatautilities::initialiseEventSelectionBits("sel8"))) - isSel8 = true; - jetHist.fill(HIST("eventLoss/hEventStatistics"), 3.5); // Has Reco Coll + const bool isSel8 = jetderiveddatautilities::selectCollision(recoColl, jetderiveddatautilities::initialiseEventSelectionBits("sel8")); + const bool isRecoVz = std::abs(recoColl.posZ()) < cfgMaxZVertex; + const bool isNoSameBunchPileup = !selNoSameBunchPileup || jetderiveddatautilities::selectCollision(recoColl, jetderiveddatautilities::initialiseEventSelectionBits("NoSameBunchPileup")); + const bool isGoodZvtxFT0vsPV = !selIsGoodZvtxFT0vsPV || jetderiveddatautilities::selectCollision(recoColl, jetderiveddatautilities::initialiseEventSelectionBits("IsGoodZvtxFT0vsPV")); + const bool isOccupancy = !useOccupancy || isOccupancyAccepted(recoColl); + const bool isExtraEventSel = isNoSameBunchPileup && isGoodZvtxFT0vsPV && isOccupancy; if (isSel8) { passSel8 = true; - jetHist.fill(HIST("eventLoss/hEventStatistics"), 4.5); // Pass Sel8 } - - if (std::abs(recoColl.posZ()) < 10.0) { - passVz = true; - jetHist.fill(HIST("eventLoss/hEventStatistics"), 5.5); // Pass |Vz|<10 + if (isRecoVz) { + passRecoVz = true; } - - if (mcINELgt0) { - passINELgt0 = true; - jetHist.fill(HIST("eventLoss/hEventStatistics"), 6.5); // Pass rec INEL>0 + if (isExtraEventSel) { + passExtraEventSel = true; } - break; // Only first reco collision + if (isSel8 && isRecoVz && isExtraEventSel) { + ++nSelectedRecoColls; + hasSelectedRecoColl = true; + } } - // Final selection (all cuts passed) - if (hasRecoColl && passSel8 && passVz && passINELgt0) { - jetHist.fill(HIST("eventLoss/hEventStatistics"), 7.5); // Final Selection + jetHist.fill(HIST("eventLoss/hRecoCollPerMCCollVsCent"), nRecoColls, centrality); + jetHist.fill(HIST("eventLoss/hSelectedRecoCollPerMCCollVsCent"), nSelectedRecoColls, centrality); + + if (hasRecoColl) { + jetHist.fill(HIST("eventLoss/hEventStatistics"), 3.5); // Has Reco Coll + } + if (passSel8) { + jetHist.fill(HIST("eventLoss/hEventStatistics"), 4.5); // Pass Sel8 + } + if (passRecoVz) { + jetHist.fill(HIST("eventLoss/hEventStatistics"), 5.5); // Pass reco |Vz| cut + } + if (passExtraEventSel) { + jetHist.fill(HIST("eventLoss/hEventStatistics"), 6.5); // Pass extra event sel + } + if (hasSelectedRecoColl) { + jetHist.fill(HIST("eventLoss/hEventStatistics"), 7.5); // Reco selected + jetHist.fill(HIST("eventLoss/hEventStatistics"), 8.5); // Reco selected + true INEL>0 } - auto mcParticles_perColl = mcParticles.sliceBy(perMCCol, mcCollision.globalIndex()); for (const auto& mcParticle : mcParticles_perColl) { if (!mcParticle.isPhysicalPrimary()) continue; @@ -2737,19 +2833,17 @@ struct nucleiInJets { // Apply kinematic cuts similar to track selection if (std::fabs(mcParticle.eta()) > cfgtrkMaxEta) continue; + if (std::fabs(mcParticle.y()) > cfgtrkMaxRap) + continue; int particleType = mapPDGToValue(mcParticle.pdgCode()); if (particleType == 0) continue; // Only interested particles - // Fill INEL>0 specific histograms - if (mcINELgt0) { - jetHist.fill(HIST("eventLoss/signalLoss/h3GenParticlesPtVsEtaVsCent_TrueINELgt0"), mcParticle.pt(), mcParticle.eta(), centrality); - jetHist.fill(HIST("eventLoss/signalLoss/h3GenParticleTypeVsPtVsCent_TrueINELgt0"), mcParticle.pt(), particleType, centrality); - } + jetHist.fill(HIST("eventLoss/signalLoss/h3GenParticlesPtVsEtaVsCent_TrueINELgt0"), mcParticle.pt(), mcParticle.eta(), centrality); + jetHist.fill(HIST("eventLoss/signalLoss/h3GenParticleTypeVsPtVsCent_TrueINELgt0"), mcParticle.pt(), particleType, centrality); - // Fill generated particle histograms (rec events) - if (hasRecoColl && passSel8 && passVz && passINELgt0) { + if (hasSelectedRecoColl) { jetHist.fill(HIST("eventLoss/signalLoss/h3GenParticlesPtVsEtaVsCent_INELgt0"), mcParticle.pt(), mcParticle.eta(), centrality); jetHist.fill(HIST("eventLoss/signalLoss/h3GenParticleTypeVsPtVsCent_INELgt0"), mcParticle.pt(), particleType, centrality); } diff --git a/PWGJE/Tasks/recoilJets.cxx b/PWGJE/Tasks/recoilJets.cxx index 53ea5d93c80..d81ec304d59 100644 --- a/PWGJE/Tasks/recoilJets.cxx +++ b/PWGJE/Tasks/recoilJets.cxx @@ -21,7 +21,6 @@ #include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" -#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -355,7 +354,7 @@ struct RecoilJets { auto tmpHistPointer = spectra.add(Form("hScaled%s_Ntrig", eaAxis.label), Form("Scaled %s vs Total number of selected triggers per class", eaAxis.label), - kTH2F, {{eaAxis.axis, eaAxis.axisName}, {2, 0.0, 2.}}); + kTH2F, {{eaAxis.axis, eaAxis.axisName}, {2, 0.0, 2.}}, hist.sumw2); tmpHistPointer->GetYaxis()->SetBinLabel(1, "TT_{Ref}"); tmpHistPointer->GetYaxis()->SetBinLabel(2, "TT_{Sig}"); @@ -411,6 +410,19 @@ struct RecoilJets { Form("Events w. TT_{Sig}: scaled %s & #rho", eaAxis.label), kTH2F, {{eaAxis.axis, eaAxis.axisName}, rho}, hist.sumw2); + // Rectricted phi range for TT selection + spectra.add(Form("hScaled%s_Ntrig_RestrictedPhi", eaAxis.label), + Form("Scaled %s vs Total number of selected triggers per class #in #varphi (%.2f, %.2f)", eaAxis.label, phiMin, phiMax), + kTH2F, {{eaAxis.axis, eaAxis.axisName}, {2, 0.0, 2.}}, hist.sumw2); + + spectra.add(Form("hScaled%s_Recoil_JetPt_Corr_TTRef_RestrictedPhi", eaAxis.label), + Form("Events w. TT_{Ref}: scaled %s & #it{p}_{T} of recoil jets", eaAxis.label), + kTH2F, {{eaAxis.axis, eaAxis.axisName}, jetPTcorr}, hist.sumw2); + + spectra.add(Form("hScaled%s_Recoil_JetPt_Corr_TTSig_RestrictedPhi", eaAxis.label), + Form("Events w. TT_{Sig}: scaled %s & #it{p}_{T} of recoil jets", eaAxis.label), + kTH2F, {{eaAxis.axis, eaAxis.axisName}, jetPTcorr}, hist.sumw2); + spectra.add(Form("hScaled%s_DPhi_JetPt_Corr_TTRef_RestrictedPhi", eaAxis.label), Form("Events w. TT_{Ref} #in #varphi (%.2f, %.2f): scaled %s & #Delta#varphi & #it{p}_{T, jet}^{ch}", phiMin, phiMax, eaAxis.label), kTH3F, {{eaAxis.axis, eaAxis.axisName}, deltaPhiAngle, jetPTcorr}, hist.sumw2); @@ -580,6 +592,18 @@ struct RecoilJets { kTH2F, {{eaAxis.axis, eaAxis.axisName}, rho}, hist.sumw2); // Rectricted phi range for TT selection + spectra.add(Form("hScaled%s_Ntrig_RestrictedPhi_Part", eaAxis.label), + Form("Scaled %s vs Total number of selected triggers per class #in #varphi (%.2f, %.2f)", eaAxis.label, phiMin, phiMax), + kTH2F, {{eaAxis.axis, eaAxis.axisName}, {2, 0.0, 2.}}, hist.sumw2); + + spectra.add(Form("hScaled%s_Recoil_JetPt_Corr_TTRef_RestrictedPhi_Part", eaAxis.label), + Form("Events w. TT_{Ref}: scaled %s & #it{p}_{T} of recoil jets", eaAxis.label), + kTH2F, {{eaAxis.axis, eaAxis.axisName}, jetPTcorr}, hist.sumw2); + + spectra.add(Form("hScaled%s_Recoil_JetPt_Corr_TTSig_RestrictedPhi_Part", eaAxis.label), + Form("Events w. TT_{Sig}: scaled %s & #it{p}_{T} of recoil jets", eaAxis.label), + kTH2F, {{eaAxis.axis, eaAxis.axisName}, jetPTcorr}, hist.sumw2); + spectra.add(Form("hScaled%s_DPhi_JetPt_Corr_TTRef_RestrictedPhi_Part", eaAxis.label), Form("MC events w. TT_{Ref} #in #varphi (%.2f, %.2f): scaled %s & #Delta#varphi & #it{p}_{T, jet}^{ch}", phiMin, phiMax, eaAxis.label), kTH3F, {{eaAxis.axis, eaAxis.axisName}, deltaPhiAngle, jetPTcorr}, hist.sumw2); @@ -1103,8 +1127,8 @@ struct RecoilJets { Form("Bkgd fluctuations RC with #it{R} = %.1f avoid lead, sublead jet in vic. %.1f vs. EA", bkgd.randomConeR.value, bkgd.minDeltaRToJet.value), kTH2F, {{eaAxis.axis}, {400, -40., 60., "#delta#it{p}_{T} (GeV/#it{c})"}}, hist.sumw2); - spectra.add(Form("hScaled%s_deltaPtRandomConeInEventTTSig", eaAxis.label), - Form("Bkgd fluctuations RC with #it{R} = %.1f in events with TT{%.0f, %.0f} in vic. %.1f vs. EA", bkgd.randomConeR.value, ptTTsigMin, ptTTsigMax, bkgd.minDeltaRToJet.value), + spectra.add(Form("hScaled%s_deltaPtPerpConeTTSig", eaAxis.label), + Form("Bkgd fluctuations PC with #it{R} = %.1f in events with TT{%.0f, %.0f} vs. EA", bkgd.randomConeR.value, ptTTsigMin, ptTTsigMax), kTH2F, {{eaAxis.axis}, {400, -40., 60., "#delta#it{p}_{T} (GeV/#it{c})"}}, hist.sumw2); } } @@ -1128,7 +1152,7 @@ struct RecoilJets { Form("Bkgd fluctuations RC with #it{R} = %.1f avoid lead, sublead jet in vic. %.1f vs. EA", bkgd.randomConeR.value, bkgd.minDeltaRToJet.value), kTH2F, {{eaAxis.axis}, {400, -40., 60., "#delta#it{p}_{T} (GeV/#it{c})"}}, hist.sumw2); - spectra.add(Form("hScaled%s_deltaPtRandomConeInEventTTSig_PartLevel", eaAxis.label), + spectra.add(Form("hScaled%s_deltaPtPerpConeTTSig_PartLevel", eaAxis.label), Form("Bkgd fluctuations RC with #it{R} = %.1f in events with TT{%.0f, %.0f} in vic. %.1f vs. EA", bkgd.randomConeR.value, ptTTsigMin, ptTTsigMax, bkgd.minDeltaRToJet.value), kTH2F, {{eaAxis.axis}, {400, -40., 60., "#delta#it{p}_{T} (GeV/#it{c})"}}, hist.sumw2); } @@ -1327,11 +1351,19 @@ struct RecoilJets { phiTT = getPhiTT(vPhiOfTT); + const auto phiMin = tt.phiRestr->at(0); + const auto phiMax = tt.phiRestr->at(1); + if (bSigEv) { // EA spectra.fill(HIST("hScaledFT0C_Ntrig"), scaledFT0C, addCountToTTSig, weight); spectra.fill(HIST("hScaledFT0M_Ntrig"), scaledFT0M, addCountToTTSig, weight); + if (phiTT > phiMin && phiTT < phiMax) { + spectra.fill(HIST("hScaledFT0C_Ntrig_RestrictedPhi"), scaledFT0C, addCountToTTSig, weight); + spectra.fill(HIST("hScaledFT0M_Ntrig_RestrictedPhi"), scaledFT0M, addCountToTTSig, weight); + } + spectra.fill(HIST("hScaledFT0C_TTSig_per_event"), scaledFT0C, nTT, weight); spectra.fill(HIST("hScaledFT0M_TTSig_per_event"), scaledFT0M, nTT, weight); @@ -1362,6 +1394,11 @@ struct RecoilJets { spectra.fill(HIST("hScaledFT0C_Ntrig"), scaledFT0C, addCountToTTRef, weight); spectra.fill(HIST("hScaledFT0M_Ntrig"), scaledFT0M, addCountToTTRef, weight); + if (phiTT > phiMin && phiTT < phiMax) { + spectra.fill(HIST("hScaledFT0C_Ntrig_RestrictedPhi"), scaledFT0C, addCountToTTRef, weight); + spectra.fill(HIST("hScaledFT0M_Ntrig_RestrictedPhi"), scaledFT0M, addCountToTTRef, weight); + } + spectra.fill(HIST("hScaledFT0C_TTRef_per_event"), scaledFT0C, nTT, weight); spectra.fill(HIST("hScaledFT0M_TTRef_per_event"), scaledFT0M, nTT, weight); @@ -1441,6 +1478,11 @@ struct RecoilJets { spectra.fill(HIST("hCentFT0C_Recoil_JetPt_Corr_TTSig"), centFT0C, jetPtCorr, weight); spectra.fill(HIST("hCentFT0M_Recoil_JetPt_Corr_TTSig"), centFT0M, jetPtCorr, weight); spectra.fill(HIST("hCentFT0CVar1_Recoil_JetPt_Corr_TTSig"), centFT0CVar1, jetPtCorr, weight); + + if (phiTT > phiMin && phiTT < phiMax) { + spectra.fill(HIST("hScaledFT0C_Recoil_JetPt_Corr_TTSig_RestrictedPhi"), scaledFT0C, jetPtCorr, weight); + spectra.fill(HIST("hScaledFT0M_Recoil_JetPt_Corr_TTSig_RestrictedPhi"), scaledFT0M, jetPtCorr, weight); + } } } else { @@ -1476,6 +1518,11 @@ struct RecoilJets { spectra.fill(HIST("hCentFT0C_Recoil_JetPt_Corr_TTRef"), centFT0C, jetPtCorr, weight); spectra.fill(HIST("hCentFT0M_Recoil_JetPt_Corr_TTRef"), centFT0M, jetPtCorr, weight); spectra.fill(HIST("hCentFT0CVar1_Recoil_JetPt_Corr_TTRef"), centFT0CVar1, jetPtCorr, weight); + + if (phiTT > phiMin && phiTT < phiMax) { + spectra.fill(HIST("hScaledFT0C_Recoil_JetPt_Corr_TTRef_RestrictedPhi"), scaledFT0C, jetPtCorr, weight); + spectra.fill(HIST("hScaledFT0M_Recoil_JetPt_Corr_TTRef_RestrictedPhi"), scaledFT0M, jetPtCorr, weight); + } } } } @@ -1566,12 +1613,20 @@ struct RecoilJets { phiTT = getPhiTT(vPhiOfTT); + const auto phiMin = tt.phiRestr->at(0); + const auto phiMax = tt.phiRestr->at(1); + if (bSigEv) { // EA spectra.fill(HIST("hScaledFT0C_Ntrig_Part"), scaledFT0C, addCountToTTSig, weight); spectra.fill(HIST("hScaledFT0M_Ntrig_Part"), scaledFT0M, addCountToTTSig, weight); + if (phiTT > phiMin && phiTT < phiMax) { + spectra.fill(HIST("hScaledFT0C_Ntrig_RestrictedPhi_Part"), scaledFT0C, addCountToTTSig, weight); + spectra.fill(HIST("hScaledFT0M_Ntrig_RestrictedPhi_Part"), scaledFT0M, addCountToTTSig, weight); + } + spectra.fill(HIST("hScaledFT0C_TTSig_per_event_Part"), scaledFT0C, nTT, weight); spectra.fill(HIST("hScaledFT0M_TTSig_per_event_Part"), scaledFT0M, nTT, weight); @@ -1599,6 +1654,11 @@ struct RecoilJets { spectra.fill(HIST("hScaledFT0C_Ntrig_Part"), scaledFT0C, addCountToTTRef, weight); spectra.fill(HIST("hScaledFT0M_Ntrig_Part"), scaledFT0M, addCountToTTRef, weight); + if (phiTT > phiMin && phiTT < phiMax) { + spectra.fill(HIST("hScaledFT0C_Ntrig_RestrictedPhi_Part"), scaledFT0C, addCountToTTRef, weight); + spectra.fill(HIST("hScaledFT0M_Ntrig_RestrictedPhi_Part"), scaledFT0M, addCountToTTRef, weight); + } + spectra.fill(HIST("hScaledFT0C_TTRef_per_event_Part"), scaledFT0C, nTT, weight); spectra.fill(HIST("hScaledFT0M_TTRef_per_event_Part"), scaledFT0M, nTT, weight); @@ -1669,6 +1729,11 @@ struct RecoilJets { spectra.fill(HIST("hCentFT0A_Recoil_JetPt_Corr_TTSig_Part"), centFT0A, jetPtCorr, weight); spectra.fill(HIST("hCentFT0C_Recoil_JetPt_Corr_TTSig_Part"), centFT0C, jetPtCorr, weight); spectra.fill(HIST("hCentFT0M_Recoil_JetPt_Corr_TTSig_Part"), centFT0M, jetPtCorr, weight); + + if (phiTT > phiMin && phiTT < phiMax) { + spectra.fill(HIST("hScaledFT0C_Recoil_JetPt_Corr_TTSig_RestrictedPhi_Part"), scaledFT0C, jetPtCorr, weight); + spectra.fill(HIST("hScaledFT0M_Recoil_JetPt_Corr_TTSig_RestrictedPhi_Part"), scaledFT0M, jetPtCorr, weight); + } } } else { @@ -1702,6 +1767,11 @@ struct RecoilJets { spectra.fill(HIST("hCentFT0A_Recoil_JetPt_Corr_TTRef_Part"), centFT0A, jetPtCorr, weight); spectra.fill(HIST("hCentFT0C_Recoil_JetPt_Corr_TTRef_Part"), centFT0C, jetPtCorr, weight); spectra.fill(HIST("hCentFT0M_Recoil_JetPt_Corr_TTRef_Part"), centFT0M, jetPtCorr, weight); + + if (phiTT > phiMin && phiTT < phiMax) { + spectra.fill(HIST("hScaledFT0C_Recoil_JetPt_Corr_TTRef_RestrictedPhi_Part"), scaledFT0C, jetPtCorr, weight); + spectra.fill(HIST("hScaledFT0M_Recoil_JetPt_Corr_TTRef_RestrictedPhi_Part"), scaledFT0M, jetPtCorr, weight); + } } } } @@ -2409,6 +2479,7 @@ struct RecoilJets { uint64_t index = 0; for (const auto& track : tracks) { + ++index; if (skipTrack(track)) continue; @@ -2424,9 +2495,8 @@ struct RecoilJets { const auto ptTTsigMin = tt.sigPtRange->at(0); const auto ptTTsigMax = tt.sigPtRange->at(1); if (track.pt() > ptTTsigMin && track.pt() < ptTTsigMax) { - vCandForTT.emplace_back(index); + vCandForTT.emplace_back(index - 1); } - ++index; } spectra.fill(HIST("hScaledFT0C_deltaPtRandomCone"), scaledFT0C, randomConePt - areaRC * rho, weight); spectra.fill(HIST("hScaledFT0M_deltaPtRandomCone"), scaledFT0M, randomConePt - areaRC * rho, weight); @@ -2519,19 +2589,6 @@ struct RecoilJets { float dEtaSubleadJet = std::pow(subleadJetEta - randomConeEta, 2); float dPhiSubleadJet = std::pow(RecoDecay::constrainAngle(subleadJetPhi - randomConePhi, -constants::math::PI), 2); - // Try to add events with TTsig - bool keepEventWithTT = false; - if (vCandForTT.size() > 0) // at least 1 TT - { - auto randIndexTrack = randGen->Integer(vCandForTT.size()); - auto objTT = tracks.iteratorAt(vCandForTT[randIndexTrack]); - - // Skip events where TT is not a part of leading or subleading jets (mutlijet event, difficult to place RC and avoid hard jets) - if (isTrackInJet(jets.iteratorAt(0), objTT) || isTrackInJet(jets.iteratorAt(1), objTT)) { - keepEventWithTT = true; - } - } - //---------------------------------------------------------- bool isTherePlaceForRC = false; for (int attempt = 0; attempt < maxAttempts; ++attempt) { @@ -2566,11 +2623,37 @@ struct RecoilJets { } spectra.fill(HIST("hScaledFT0C_deltaPtRandomConeAvoidLeadAndSubleadJet"), scaledFT0C, randomConePt - areaRC * rho, weight); spectra.fill(HIST("hScaledFT0M_deltaPtRandomConeAvoidLeadAndSubleadJet"), scaledFT0M, randomConePt - areaRC * rho, weight); + } + } - if (keepEventWithTT) { - spectra.fill(HIST("hScaledFT0C_deltaPtRandomConeInEventTTSig"), scaledFT0C, randomConePt - areaRC * rho, weight); - spectra.fill(HIST("hScaledFT0M_deltaPtRandomConeInEventTTSig"), scaledFT0M, randomConePt - areaRC * rho, weight); + //---------------------------------------------------------- + // Place cone perpendicular to TTSig candidate + if (vCandForTT.size() > 0) // at least 1 TT + { + auto randIndexTrack = randGen->Integer(vCandForTT.size()); + auto objTT = tracks.iteratorAt(vCandForTT[randIndexTrack]); + + float perpTTConeEta = objTT.eta(); + float perpTTConePhi = RecoDecay::constrainAngle(objTT.phi() + constants::math::PIHalf, 0.0f); + + // Keep the full cone inside the track acceptance + if (std::abs(perpTTConeEta) < (trk.etaCut - bkgd.randomConeR)) { + float perpTTConePt = 0.0; + for (const auto& track : tracks) { + if (skipTrack(track)) + continue; + + float dEta = std::pow(perpTTConeEta - track.eta(), 2); + float dPhi = std::pow(RecoDecay::constrainAngle(perpTTConePhi - track.phi(), -constants::math::PI), 2); + + if ((dEta + dPhi) < radiusRC2) // inside TT perpendicular cone + { + perpTTConePt += track.pt(); + } } + + spectra.fill(HIST("hScaledFT0C_deltaPtPerpConeTTSig"), scaledFT0C, perpTTConePt - areaRC * rho, weight); + spectra.fill(HIST("hScaledFT0M_deltaPtPerpConeTTSig"), scaledFT0M, perpTTConePt - areaRC * rho, weight); } } } @@ -2760,8 +2843,8 @@ struct RecoilJets { spectra.fill(HIST("hScaledFT0M_deltaPtRandomConeAvoidLeadAndSubleadJet_PartLevel"), scaledFT0M, randomConePt - areaRC * rho, weight); if (keepEventWithTT) { - spectra.fill(HIST("hScaledFT0C_deltaPtRandomConeInEventTTSig_PartLevel"), scaledFT0C, randomConePt - areaRC * rho, weight); - spectra.fill(HIST("hScaledFT0M_deltaPtRandomConeInEventTTSig_PartLevel"), scaledFT0M, randomConePt - areaRC * rho, weight); + spectra.fill(HIST("hScaledFT0C_deltaPtPerpConeTTSig_PartLevel"), scaledFT0C, randomConePt - areaRC * rho, weight); + spectra.fill(HIST("hScaledFT0M_deltaPtPerpConeTTSig_PartLevel"), scaledFT0M, randomConePt - areaRC * rho, weight); } } } diff --git a/PWGLF/DataModel/LFLambda1405Table.h b/PWGLF/DataModel/LFLambda1405Table.h index 31721f634e3..103065146c6 100644 --- a/PWGLF/DataModel/LFLambda1405Table.h +++ b/PWGLF/DataModel/LFLambda1405Table.h @@ -48,9 +48,12 @@ DECLARE_SOA_COLUMN(DCAKinkDauToPV, dcaKinkDauToPV, float); //! DCA of the kink DECLARE_SOA_COLUMN(NSigmaTPCPiDau, nSigmaTPCPiDau, float); //! Number of sigmas for the lambda1405 pion daughter in TPC DECLARE_SOA_COLUMN(NSigmaTOFPiDau, nSigmaTOFPiDau, float); //! Number of sigmas for the lambda1405 pion daughter in TOF +// Event properties +DECLARE_SOA_COLUMN(Centrality, centrality, float); //! Centrality of the candidate +DECLARE_SOA_COLUMN(Occupancy, occupancy, float); //! Occupancy of the candidate + // Flow columns DECLARE_SOA_COLUMN(ScalarProd, scalarProd, float); //! Scalar product of the candidate -DECLARE_SOA_COLUMN(Centrality, centrality, float); //! Centrality of the candidate // MC Columns DECLARE_SOA_COLUMN(PtMC, ptMC, float); //! pT of the candidate in MC @@ -70,12 +73,14 @@ DECLARE_SOA_TABLE(Lambda1405Cands, "AOD", "LAMBDA1405", lambda1405::NSigmaTPCPiKink, lambda1405::NSigmaTOFPiKink, lambda1405::NSigmaTPCPrKink, lambda1405::NSigmaTOFPrKink, lambda1405::DCAKinkDauToPV, - lambda1405::NSigmaTPCPiDau, lambda1405::NSigmaTOFPiDau); + lambda1405::NSigmaTPCPiDau, lambda1405::NSigmaTOFPiDau, + lambda1405::Centrality, lambda1405::Occupancy); DECLARE_SOA_TABLE(Lambda1405Flow, "AOD", "LAMBDA1405FLOW", o2::soa::Index<>, - lambda1405::Pt, - lambda1405::Mass, lambda1405::SigmaMinusMass, lambda1405::SigmaPlusMass, + lambda1405::Pt, lambda1405::Mass, + lambda1405::PtSigma, + lambda1405::SigmaMinusMass, lambda1405::SigmaPlusMass, lambda1405::AlphaAPSigma, lambda1405::QtAPSigma, lambda1405::NSigmaTPCPiKink, lambda1405::NSigmaTOFPiKink, lambda1405::NSigmaTPCPrKink, lambda1405::NSigmaTOFPrKink, @@ -94,7 +99,8 @@ DECLARE_SOA_TABLE(Lambda1405CandsMC, "AOD", "MCLAMBDA1405", lambda1405::NSigmaTPCPrKink, lambda1405::NSigmaTOFPrKink, lambda1405::DCAKinkDauToPV, lambda1405::NSigmaTPCPiDau, lambda1405::NSigmaTOFPiDau, - lambda1405::PtMC, lambda1405::MassMC, lambda1405::SigmaPdgCode, lambda1405::KinkDauPdgCode); + lambda1405::PtMC, lambda1405::MassMC, lambda1405::SigmaPdgCode, lambda1405::KinkDauPdgCode, + lambda1405::Centrality, lambda1405::Occupancy); } // namespace o2::aod diff --git a/PWGLF/DataModel/LFNonPromptCascadeTables.h b/PWGLF/DataModel/LFNonPromptCascadeTables.h index 0ea616d8853..9b503213edf 100644 --- a/PWGLF/DataModel/LFNonPromptCascadeTables.h +++ b/PWGLF/DataModel/LFNonPromptCascadeTables.h @@ -464,7 +464,8 @@ DECLARE_SOA_TABLE(NPCollisionTable, "AOD", "NPCollisionTABLE", NPCascadeTable::MultNTracksGlobal, NPCascadeTable::MultNTracksNP, NPCascadeTable::CentFT0M, - NPCascadeTable::MultFT0M); + NPCascadeTable::MultFT0M, + NPCascadeTable::NoSameBunchPileup); DECLARE_SOA_INDEX_COLUMN_FULL(NPCollision, npCollision, int32_t, NPCollisionTable, ""); DECLARE_SOA_TABLE(NPRecoChargedCand, "AOD", "NPRecoChargedCand", NPCollisionId, diff --git a/PWGLF/DataModel/LFPhiFlowTables.h b/PWGLF/DataModel/LFPhiFlowTables.h new file mode 100644 index 00000000000..139d0ee763c --- /dev/null +++ b/PWGLF/DataModel/LFPhiFlowTables.h @@ -0,0 +1,70 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file LFPhiFlowTables.h +/// \brief DataModel for Phi flow +/// +/// \author Prottay Das + +#ifndef PWGLF_DATAMODEL_LFPHIFLOWTABLES_H_ +#define PWGLF_DATAMODEL_LFPHIFLOWTABLES_H_ + +#include +#include + +#include +#include + +namespace o2::aod +{ +namespace kaonevent +{ +DECLARE_SOA_COLUMN(Cent, cent, float); +DECLARE_SOA_COLUMN(Posz, posz, float); +DECLARE_SOA_COLUMN(QxA, qxA, float); +DECLARE_SOA_COLUMN(QxC, qxC, float); +DECLARE_SOA_COLUMN(QyA, qyA, float); +DECLARE_SOA_COLUMN(QyC, qyC, float); +} // namespace kaonevent +DECLARE_SOA_TABLE(KaonEvents, "AOD", "KAONEVENT", + o2::soa::Index<>, + kaonevent::Cent, + kaonevent::Posz, + kaonevent::QxA, + kaonevent::QxC, + kaonevent::QyA, + kaonevent::QyC) +using KaonEvent = KaonEvents::iterator; + +namespace kaonpair +{ +DECLARE_SOA_INDEX_COLUMN(KaonEvent, kaonevent); +DECLARE_SOA_COLUMN(Px, px, float); //! Bachelor Kaon Px +DECLARE_SOA_COLUMN(Py, py, float); //! Bachelor Kaon Py +DECLARE_SOA_COLUMN(Pz, pz, float); //! Bachelor Kaon Pz +DECLARE_SOA_COLUMN(Charge, charge, int8_t); //! Charge +DECLARE_SOA_COLUMN(KaonIndex, kaonIndex, int64_t); //! Daughter Kaon index1 +DECLARE_SOA_COLUMN(KaonPidMask, kaonPidMask, uint16_t); //! bitmask for PID selections +} // namespace kaonpair + +DECLARE_SOA_TABLE(KaonTracks, "AOD", "KAONTRACK", + o2::soa::Index<>, + kaonpair::KaonEventId, + kaonpair::Px, + kaonpair::Py, + kaonpair::Pz, + kaonpair::Charge, + kaonpair::KaonIndex, + kaonpair::KaonPidMask); + +using KaonTrack = KaonTracks::iterator; +} // namespace o2::aod +#endif // PWGLF_DATAMODEL_LFPHIFLOWTABLES_H_ diff --git a/PWGLF/DataModel/LFSigmaTables.h b/PWGLF/DataModel/LFSigmaTables.h index 69ff56bcc5f..9f2bf428352 100644 --- a/PWGLF/DataModel/LFSigmaTables.h +++ b/PWGLF/DataModel/LFSigmaTables.h @@ -790,6 +790,8 @@ DECLARE_SOA_COLUMN(PhotonMCPz, photonmcpz, float); DECLARE_SOA_COLUMN(IsPhotonPrimary, isPhotonPrimary, bool); DECLARE_SOA_COLUMN(PhotonPDGCode, photonPDGCode, int); DECLARE_SOA_COLUMN(PhotonPDGCodeMother, photonPDGCodeMother, int); +DECLARE_SOA_COLUMN(PhotonPDGCodeGrandMother, photonPDGCodeGrandMother, int); +DECLARE_SOA_COLUMN(PhotonGlobalIndexGrandMother, photonGlobalIndexGrandMother, int); DECLARE_SOA_COLUMN(PhotonIsCorrectlyAssoc, photonIsCorrectlyAssoc, bool); DECLARE_SOA_COLUMN(KShortMCPx, kshortmcpx, float); @@ -798,6 +800,8 @@ DECLARE_SOA_COLUMN(KShortMCPz, kshortmcpz, float); DECLARE_SOA_COLUMN(IsKShortPrimary, isKShortPrimary, bool); DECLARE_SOA_COLUMN(KShortPDGCode, kshortPDGCode, int); DECLARE_SOA_COLUMN(KShortPDGCodeMother, kshortPDGCodeMother, int); +DECLARE_SOA_COLUMN(KShortPDGCodeGrandMother, kshortPDGCodeGrandMother, int); +DECLARE_SOA_COLUMN(KShortGlobalIndexGrandMother, kshortGlobalIndexGrandMother, int); DECLARE_SOA_COLUMN(KShortIsCorrectlyAssoc, kshortIsCorrectlyAssoc, bool); DECLARE_SOA_DYNAMIC_COLUMN(IsKStar, isKStar, //! IsSigma0 @@ -903,10 +907,10 @@ DECLARE_SOA_TABLE(KStarMCCores, "AOD", "KSTARMCCORES", kstarMCCore::MCradius, kstarMCCore::PDGCode, kstarMCCore::PDGCodeMother, kstarMCCore::MCprocess, kstarMCCore::IsProducedByGenerator, kstarMCCore::PhotonMCPx, kstarMCCore::PhotonMCPy, kstarMCCore::PhotonMCPz, - kstarMCCore::IsPhotonPrimary, kstarMCCore::PhotonPDGCode, kstarMCCore::PhotonPDGCodeMother, kstarMCCore::PhotonIsCorrectlyAssoc, + kstarMCCore::IsPhotonPrimary, kstarMCCore::PhotonPDGCode, kstarMCCore::PhotonPDGCodeMother, kstarMCCore::PhotonPDGCodeGrandMother, kstarMCCore::PhotonGlobalIndexGrandMother, kstarMCCore::PhotonIsCorrectlyAssoc, kstarMCCore::KShortMCPx, kstarMCCore::KShortMCPy, kstarMCCore::KShortMCPz, - kstarMCCore::IsKShortPrimary, kstarMCCore::KShortPDGCode, kstarMCCore::KShortPDGCodeMother, kstarMCCore::KShortIsCorrectlyAssoc, + kstarMCCore::IsKShortPrimary, kstarMCCore::KShortPDGCode, kstarMCCore::KShortPDGCodeMother, kstarMCCore::KShortPDGCodeGrandMother, kstarMCCore::KShortGlobalIndexGrandMother, kstarMCCore::KShortIsCorrectlyAssoc, // Dynamic columns kstarMCCore::IsKStar, diff --git a/PWGLF/DataModel/LFSlimNucleiTables.h b/PWGLF/DataModel/LFSlimNucleiTables.h index 974acc072d2..2b64efe2b00 100644 --- a/PWGLF/DataModel/LFSlimNucleiTables.h +++ b/PWGLF/DataModel/LFSlimNucleiTables.h @@ -56,8 +56,11 @@ DECLARE_SOA_COLUMN(AbsoDecL, absoDecL, float); DECLARE_SOA_COLUMN(McProcess, mcProcess, uint64_t); DECLARE_SOA_COLUMN(gEventMask, genEventMask, uint8_t); -DECLARE_SOA_COLUMN(NsigmaTpc, nsigmaTpc, uint8_t); -DECLARE_SOA_COLUMN(NsigmaTof, nsigmaTof, uint8_t); +DECLARE_SOA_COLUMN(NsigmaTpc, nsigmaTpc, float); +DECLARE_SOA_COLUMN(NsigmaTof, nsigmaTof, float); + +DECLARE_SOA_COLUMN(Vx, vx, float); +DECLARE_SOA_COLUMN(Vy, vy, float); } // namespace NucleiTableNS @@ -139,6 +142,12 @@ DECLARE_SOA_TABLE(NucleiTableFlow, "AOD", "NUCLEITABLEFLOW", NucleiFlowTableNS::QTPCl, NucleiFlowTableNS::QTPCr); +DECLARE_SOA_TABLE(NucleiTableCent, "AOD", "NUCLEITABLECENT", + NucleiFlowTableNS::CentFV0A, + NucleiFlowTableNS::CentFT0M, + NucleiFlowTableNS::CentFT0A, + NucleiFlowTableNS::CentFT0C); + DECLARE_SOA_TABLE(NucleiTableMC, "AOD", "NUCLEITABLEMC", NucleiTableNS::Pt, NucleiTableNS::Eta, @@ -245,6 +254,10 @@ DECLARE_SOA_TABLE(NucleiTableMCExtension, "AOD", "NUCTABLEMCSEL", DECLARE_SOA_TABLE(NucleiTableExt, "AOD", "NUCLEITABLEEXT", NucleiTableNS::NsigmaTpc, NucleiTableNS::NsigmaTof); +// Extended table for studies on nuclei from material +DECLARE_SOA_TABLE(NucleiTableMat, "AOD", "NUCLEITABLEMAT", + NucleiTableNS::Vx, + NucleiTableNS::Vy); } // namespace o2::aod diff --git a/PWGLF/DataModel/ReducedDoublePhiTables.h b/PWGLF/DataModel/ReducedDoublePhiTables.h index 61175fccfc8..ec0d969e0f3 100644 --- a/PWGLF/DataModel/ReducedDoublePhiTables.h +++ b/PWGLF/DataModel/ReducedDoublePhiTables.h @@ -27,6 +27,7 @@ namespace redphievent { DECLARE_SOA_COLUMN(NumPos, numPos, int); //! Number of positive Kaon DECLARE_SOA_COLUMN(NumNeg, numNeg, int); //! Number of negative Kaon +DECLARE_SOA_COLUMN(Centrality, centrality, float); //! Number of negative Kaon } // namespace redphievent DECLARE_SOA_TABLE(RedPhiEvents, "AOD", "REDPHIEVENT", o2::soa::Index<>, @@ -36,7 +37,8 @@ DECLARE_SOA_TABLE(RedPhiEvents, "AOD", "REDPHIEVENT", collision::PosZ, collision::NumContrib, redphievent::NumPos, - redphievent::NumNeg); + redphievent::NumNeg, + redphievent::Centrality); using RedPhiEvent = RedPhiEvents::iterator; namespace phitrack diff --git a/PWGLF/DataModel/ZDCCalTables.h b/PWGLF/DataModel/ZDCCalTables.h index 0d11fe4b1ca..30851802438 100644 --- a/PWGLF/DataModel/ZDCCalTables.h +++ b/PWGLF/DataModel/ZDCCalTables.h @@ -38,6 +38,7 @@ DECLARE_SOA_COLUMN(QyA, qyA, float); DECLARE_SOA_COLUMN(QyC, qyC, float); } // namespace zdccaltable DECLARE_SOA_TABLE(ZDCCalTables, "AOD", "ZDCCALTABLE", + o2::soa::Index<>, zdccaltable::TriggerEventZDC, zdccaltable::TriggerEventRunNo, zdccaltable::Cent, @@ -102,5 +103,29 @@ DECLARE_SOA_TABLE(ZDCTimeTables, "AOD", "ZDCTIME", zdctimetable::TimeMin); using ZDCTimeTable = ZDCTimeTables::iterator; + +// charged-track linked table comes here + +namespace zdcchargedtrack +{ +DECLARE_SOA_INDEX_COLUMN(ZDCCalTable, zdcCalTable); + +DECLARE_SOA_COLUMN(Px, px, float); +DECLARE_SOA_COLUMN(Py, py, float); +DECLARE_SOA_COLUMN(Pz, pz, float); +DECLARE_SOA_COLUMN(Sign, sign, int8_t); +} // namespace zdcchargedtrack + +DECLARE_SOA_TABLE(ZDCChargedTracks, + "AOD", + "ZDCCHTRK", + zdcchargedtrack::ZDCCalTableId, + zdcchargedtrack::Px, + zdcchargedtrack::Py, + zdcchargedtrack::Pz, + zdcchargedtrack::Sign); + +using ZDCChargedTrack = ZDCChargedTracks::iterator; + } // namespace o2::aod #endif // PWGLF_DATAMODEL_ZDCCALTABLES_H_ diff --git a/PWGLF/TableProducer/Common/kinkBuilder.cxx b/PWGLF/TableProducer/Common/kinkBuilder.cxx index 4ae1e77b7c0..623efeeeb2f 100644 --- a/PWGLF/TableProducer/Common/kinkBuilder.cxx +++ b/PWGLF/TableProducer/Common/kinkBuilder.cxx @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -96,7 +97,10 @@ std::shared_ptr hDCAMothToPV; std::shared_ptr hDCADaugToPV; std::shared_ptr hMothDecRad2; std::shared_ptr hGenCandidates; -std::shared_ptr hRecCandidates; +std::shared_ptr hGenDecayRadius; +std::shared_ptr hRecCandidatesRecoPt; +std::shared_ptr hRecCandidatesGenPt; +std::shared_ptr hRecCandidatesDeltaPt; std::array, NMatchedDecays> hGenPtKinkAngle; std::array, NMatchedDecays> hRecPtKinkAngle; } // namespace @@ -362,21 +366,27 @@ struct kinkBuilder { if (doprocessMc || doprocessMcWCent) { if (skipBkgCands) { - hRecCandidates = qaRegistry.add("hRecCandidates", "hRecCandidates;Counts;", {HistType::kTH2F, {{NMatchedDecays, -0.5, static_cast(NMatchedDecays) - 0.5}, absPtAxis}}); - hRecCandidates->GetXaxis()->SetBinLabel(1, "#Sigma^{-} #rightarrow n#pi^{-}"); - hRecCandidates->GetXaxis()->SetBinLabel(2, "#Sigma^{+} #rightarrow n#pi^{+}"); - hRecCandidates->GetXaxis()->SetBinLabel(3, "#Sigma^{+} #rightarrow p#pi^{0}"); + hRecCandidatesRecoPt = qaRegistry.add("hRecCandidatesRecoPt", "hRecCandidates;Counts;Reco #it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{NMatchedDecays, -0.5, static_cast(NMatchedDecays) - 0.5}, absPtAxis}}); + hRecCandidatesRecoPt->GetXaxis()->SetBinLabel(1, "#Sigma^{-} #rightarrow n#pi^{-}"); + hRecCandidatesRecoPt->GetXaxis()->SetBinLabel(2, "#Sigma^{+} #rightarrow n#pi^{+}"); + hRecCandidatesRecoPt->GetXaxis()->SetBinLabel(3, "#Sigma^{+} #rightarrow p#pi^{0}"); + hRecCandidatesGenPt = qaRegistry.add("hRecCandidatesGenPt", "hRecCandidatesGenPt;Counts;Gen #it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{NMatchedDecays, -0.5, static_cast(NMatchedDecays) - 0.5}, absPtAxis}}); + hRecCandidatesGenPt->GetXaxis()->SetBinLabel(1, "#Sigma^{-} #rightarrow n#pi^{-}"); + hRecCandidatesGenPt->GetXaxis()->SetBinLabel(2, "#Sigma^{+} #rightarrow n#pi^{+}"); + hRecCandidatesGenPt->GetXaxis()->SetBinLabel(3, "#Sigma^{+} #rightarrow p#pi^{0}"); + hRecCandidatesDeltaPt = qaRegistry.add("hRecCandidatesDeltaPt", "hRecCandidatesDeltaPt;Counts;#Delta p_{T} (GeV/c)", {HistType::kTH2F, {{400, -0.5, 0.5}, absPtAxis}}); } - hGenCandidates = qaRegistry.add("hGenCandidates", "hGenCandidates;Counts;", {HistType::kTH2F, {{NMatchedDecays, -0.5, static_cast(NMatchedDecays) - 0.5}, absPtAxis}}); + hGenDecayRadius = qaRegistry.add("hGenDecayRadius", "hGenDecayRadius;Radius (cm); #it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{300, 0, 30}, absPtAxis}}); + hGenCandidates = qaRegistry.add("hGenCandidates", "hGenCandidates;Counts;Gen #it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{NMatchedDecays, -0.5, static_cast(NMatchedDecays) - 0.5}, absPtAxis}}); hGenCandidates->GetXaxis()->SetBinLabel(1, "#Sigma^{-} #rightarrow n#pi^{-}"); hGenCandidates->GetXaxis()->SetBinLabel(2, "#Sigma^{+} #rightarrow n#pi^{+}"); hGenCandidates->GetXaxis()->SetBinLabel(3, "#Sigma^{+} #rightarrow p#pi^{0}"); - hRecPtKinkAngle[SigmaMinusToPiMinusNeutron] = qaRegistry.add("hRecPtKinkAngleSigmaMinusToPiMinusNeutron", "Rec Pt vs KinkAngle #Sigma^{-} #rightarrow #pi^{-}n;Counts;", {HistType::kTH2F, {absPtAxis, kinkAngleAxis}}); - hRecPtKinkAngle[SigmaPlusToPiPlusNeutron] = qaRegistry.add("hRecPtKinkAngleSigmaPlusToPiPlusNeutron", "Rec Pt vs KinkAngle #Sigma^{+} #rightarrow #pi^{+}n;Counts;", {HistType::kTH2F, {absPtAxis, kinkAngleAxis}}); - hRecPtKinkAngle[SigmaPlusToProtonPi0] = qaRegistry.add("hRecPtKinkAngleSigmaPlusToProtonPi0", "Rec Pt vs KinkAngle #Sigma^{+} #rightarrow p#pi^{0};Counts;", {HistType::kTH2F, {absPtAxis, kinkAngleAxis}}); - hGenPtKinkAngle[SigmaMinusToPiMinusNeutron] = qaRegistry.add("hGenPtKinkAngleSigmaMinusToPiMinusNeutron", "Gen Pt vs KinkAngle #Sigma^{-} #rightarrow #pi^{-}n;Counts;", {HistType::kTH2F, {absPtAxis, kinkAngleAxis}}); - hGenPtKinkAngle[SigmaPlusToPiPlusNeutron] = qaRegistry.add("hGenPtKinkAngleSigmaPlusToPiPlusNeutron", "Gen Pt vs KinkAngle #Sigma^{+} #rightarrow #pi^{+}n;Counts;", {HistType::kTH2F, {absPtAxis, kinkAngleAxis}}); - hGenPtKinkAngle[SigmaPlusToProtonPi0] = qaRegistry.add("hGenPtKinkAngleSigmaPlusToProtonPi0", "Gen Pt vs KinkAngle #Sigma^{+} #rightarrow p#pi^{0};Counts;", {HistType::kTH2F, {absPtAxis, kinkAngleAxis}}); + hRecPtKinkAngle[SigmaMinusToPiMinusNeutron] = qaRegistry.add("hRecPtKinkAngleSigmaMinusToPi", "Rec Pt vs KinkAngle #Sigma^{-} #rightarrow #pi^{-}n;Counts;", {HistType::kTH2F, {absPtAxis, kinkAngleAxis}}); + hRecPtKinkAngle[SigmaPlusToPiPlusNeutron] = qaRegistry.add("hRecPtKinkAngleSigmaPlusToPi", "Rec Pt vs KinkAngle #Sigma^{+} #rightarrow #pi^{+}n;Counts;", {HistType::kTH2F, {absPtAxis, kinkAngleAxis}}); + hRecPtKinkAngle[SigmaPlusToProtonPi0] = qaRegistry.add("hRecPtKinkAngleSigmaPlusToPr", "Rec Pt vs KinkAngle #Sigma^{+} #rightarrow p#pi^{0};Counts;", {HistType::kTH2F, {absPtAxis, kinkAngleAxis}}); + hGenPtKinkAngle[SigmaMinusToPiMinusNeutron] = qaRegistry.add("hGenPtKinkAngleSigmaMinusToPi", "Gen Pt vs KinkAngle #Sigma^{-} #rightarrow #pi^{-}n;Counts;", {HistType::kTH2F, {absPtAxis, kinkAngleAxis}}); + hGenPtKinkAngle[SigmaPlusToPiPlusNeutron] = qaRegistry.add("hGenPtKinkAngleSigmaPlusToPi", "Gen Pt vs KinkAngle #Sigma^{+} #rightarrow #pi^{+}n;Counts;", {HistType::kTH2F, {absPtAxis, kinkAngleAxis}}); + hGenPtKinkAngle[SigmaPlusToProtonPi0] = qaRegistry.add("hGenPtKinkAngleSigmaPlusToPr", "Gen Pt vs KinkAngle #Sigma^{+} #rightarrow p#pi^{0};Counts;", {HistType::kTH2F, {absPtAxis, kinkAngleAxis}}); } } @@ -402,12 +412,14 @@ struct kinkBuilder { return false; hSelMotherQA->Fill(4.f, isPositive); - h2ItsClsMothBeforeSel->Fill(candidate.itsNCls(), candidate.itsNClsInnerBarrel()); - if (candidate.itsNCls() >= nItsTotalLayers - 1) + int itsTotCls = static_cast(candidate.itsNCls()); + int itsIBCls = static_cast(candidate.itsNClsInnerBarrel()); + h2ItsClsMothBeforeSel->Fill(itsTotCls, itsIBCls); + if (itsTotCls >= nItsTotalLayers - 1) return false; hSelMotherQA->Fill(5.f, isPositive); - if (candidate.itsNClsInnerBarrel() != nItsInnerBarrelLayers) + if (itsIBCls != nItsInnerBarrelLayers) return false; hSelMotherQA->Fill(6.f, isPositive); @@ -440,8 +452,10 @@ struct kinkBuilder { return false; hSelDaugQA->Fill(3.f, isPositive); - h2ItsClsDaugBeforeSel->Fill(candidate.itsNCls(), candidate.itsNClsInnerBarrel()); - if (candidate.itsNClsInnerBarrel() != 0) + int itsTotCls = static_cast(candidate.itsNCls()); + int itsIBCls = static_cast(candidate.itsNClsInnerBarrel()); + h2ItsClsDaugBeforeSel->Fill(itsTotCls, itsIBCls); + if (itsIBCls != 0) return false; hSelDaugQA->Fill(4.f, isPositive); @@ -649,7 +663,7 @@ struct kinkBuilder { LOG(info) << "Task initialized for run " << mRunNumber << " with magnetic field " << mBz << " kZG"; } - template + template void buildSvPool(const TColls& collisions, const TTracks& tracks, const TAmbiTracks& ambiguousTracks, const aod::BCs& bcs) { svCreator.clearPools(); @@ -660,8 +674,36 @@ struct kinkBuilder { continue; } - bool isDaug = selectDaugTrack(track); - bool isMoth = selectMothTrack(track); + bool canBeMoth = true; + bool canBeDaug = true; + + if constexpr (KeepOnlyKinks) { + if (!track.has_mcParticle()) { + LOG(debug) << "Track has no MC particle"; + continue; + } + auto genPart = track.template mcParticle_as(); + + canBeMoth = std::find( + mothMatchPdgCodes.begin(), + mothMatchPdgCodes.end(), + std::abs(genPart.pdgCode())) != mothMatchPdgCodes.end(); + + canBeDaug = false; + for (const auto& mother : genPart.template mothers_as()) { + if (std::find( + mothMatchPdgCodes.begin(), + mothMatchPdgCodes.end(), + std::abs(mother.pdgCode())) != mothMatchPdgCodes.end()) { + canBeDaug = true; + break; + } + } + } + + bool isMoth = canBeMoth && selectMothTrack(track); + bool isDaug = canBeDaug && selectDaugTrack(track); + if (!isDaug && !isMoth) { continue; } @@ -675,7 +717,7 @@ struct kinkBuilder { { kinkCandidates.clear(); - buildSvPool(collisions, tracks, ambiTracks, bcs); + buildSvPool(collisions, tracks, ambiTracks, bcs); auto& kinkPool = svCreator.getSVCandPool(collisions, !unlikeSignBkg); bool isAccepted = false; for (const auto& svCand : kinkPool) { @@ -762,7 +804,12 @@ struct kinkBuilder { { kinkCandidates.clear(); - buildSvPool(mcRecoCollisions, tracksMc, ambiTracksMc, bcs); + if (skipBkgCands) { + buildSvPool(mcRecoCollisions, tracksMc, ambiTracksMc, bcs); + } else { + buildSvPool(mcRecoCollisions, tracksMc, ambiTracksMc, bcs); + } + auto& kinkPool = svCreator.getSVCandPool(mcRecoCollisions, !unlikeSignBkg); for (const auto& svCand : kinkPool) { // Perform matching of the kink candidate @@ -787,7 +834,9 @@ struct kinkBuilder { if (decayChannel < 0) { continue; // Skip candidates that do not match the decay channels of interest } - hRecCandidates->Fill(decayChannel, trackMoth.pt()); // Decay channel match bin + hRecCandidatesRecoPt->Fill(decayChannel, trackMoth.pt()); // Decay channel match bin + hRecCandidatesGenPt->Fill(decayChannel, genMothPart.pt()); // Decay channel match bin + hRecCandidatesDeltaPt->Fill((trackMoth.pt() - genMothPart.pt()) / genMothPart.pt(), genMothPart.pt()); // Decay channel match bin } bool isAccepted = false; buildKinkCand(svCand, tracksMc, isAccepted, mcRecoCollisions); @@ -831,6 +880,7 @@ struct kinkBuilder { auto daughI = mcParticles.rawIteratorAt(arrDaughIdxs[iProng]); if (std::abs(daughI.pdgCode()) == PDG_t::kPiPlus || std::abs(daughI.pdgCode()) == PDG_t::kProton) { hGenPtKinkAngle[decayChannel]->Fill(mcPart.pt(), std::abs(mcPart.phi() - daughI.phi()) * radToDeg); + hGenDecayRadius->Fill(std::hypot(daughI.vx(), daughI.vy()), mcPart.pt()); } } } diff --git a/PWGLF/TableProducer/Common/spvector.cxx b/PWGLF/TableProducer/Common/spvector.cxx index d3bd49d3cf4..c6873010efa 100644 --- a/PWGLF/TableProducer/Common/spvector.cxx +++ b/PWGLF/TableProducer/Common/spvector.cxx @@ -20,11 +20,8 @@ #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/PIDResponseTPC.h" -#include "Common/DataModel/TrackSelectionTables.h" #include -#include #include #include #include @@ -37,6 +34,7 @@ #include #include +#include #include #include #include @@ -62,8 +60,6 @@ using namespace o2::framework::expressions; using namespace o2::constants::physics; using namespace o2::aod::rctsel; -using BCsRun3 = soa::Join; - struct spvector { Produces spcalibrationtable; @@ -76,7 +72,6 @@ struct spvector { // Enable access to the CCDB for the offset and correction constants and save them in dedicated variables. Service ccdb; - o2::ccdb::CcdbApi ccdbApi; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; @@ -120,6 +115,7 @@ struct spvector { Configurable hfinebinTime{"hfinebinTime", 120, "higher bin value in Time fine histograms"}; } configbins; + Configurable useoldrecentering{"useoldrecentering", true, "flag to perform old vs new recentering"}; Configurable useShift{"useShift", false, "shift histograms"}; Configurable ispolarization{"ispolarization", false, "Flag to check polarization"}; Configurable followpub{"followpub", true, "flag to use alphaZDC"}; @@ -127,10 +123,13 @@ struct spvector { Configurable useCallibvertex{"useCallibvertex", false, "use calibration for vxy"}; Configurable coarse1{"coarse1", false, "RE1"}; Configurable fine1{"fine1", false, "REfine1"}; + Configurable finetime1{"finetime1", false, "REfinetime1"}; Configurable coarse2{"coarse2", false, "RE2"}; Configurable fine2{"fine2", false, "REfine2"}; + Configurable finetime2{"finetime2", false, "REfinetime2"}; Configurable coarse3{"coarse3", false, "RE3"}; Configurable fine3{"fine3", false, "REfine3"}; + Configurable finetime3{"finetime3", false, "REfinetime3"}; Configurable coarse4{"coarse4", false, "RE4"}; Configurable fine4{"fine4", false, "REfine4"}; Configurable coarse5{"coarse5", false, "RE5"}; @@ -139,6 +138,7 @@ struct spvector { Configurable fine6{"fine6", false, "REfine6"}; Configurable useRecentereSp{"useRecentereSp", false, "use Recentering with Sparse or THn"}; Configurable useRecenterefineSp{"useRecenterefineSp", false, "use fine Recentering with THn"}; + Configurable useTimeRecentering{"useTimeRecentering", false, "Use residual time recentering"}; Configurable ConfGainPath{"ConfGainPath", "Users/p/prottay/My/Object/NewPbPbpass4_10092024/gaincallib", "Path to gain calibration"}; Configurable ConfGainPathvxy{"ConfGainPathvxy", "Users/p/prottay/My/Object/swapcoords/PbPbpass4_20112024/recentervert", "Path to gain calibration for vxy"}; Configurable ConfRecentereSp{"ConfRecentereSp", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn Path for recentere"}; @@ -173,28 +173,60 @@ struct spvector { Configurable ConfRecenterevzSp6{"ConfRecenterevzSp6", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn Path for vz recentere6"}; Configurable ConfShiftC{"ConfShiftC", "Users/p/prottay/My/Object/Testinglocaltree/shiftcallib2", "Path to shift C"}; Configurable ConfShiftA{"ConfShiftA", "Users/p/prottay/My/Object/Testinglocaltree/shiftcallib2", "Path to shift A"}; + Configurable confRecentereTimeSp1{"confRecentereTimeSp1", "Users/p/prottay/My/Object/GCwithoutcfactorgoodVztimedep/From676541/TestDDlocal/2024PbPbpass3_23062026/recenterlast2", "Path to time recentering map 1"}; + Configurable confRecentereTimeSp2{"confRecentereTimeSp2", "Users/p/prottay/My/Object/GCwithoutcfactorgoodVztimedep/From676541/TestDDlocal/2024PbPbpass3_23062026/recenterlast2", "Path to time recentering map 2"}; + Configurable confRecentereTimeSp3{"confRecentereTimeSp3", "Users/p/prottay/My/Object/GCwithoutcfactorgoodVztimedep/From676541/TestDDlocal/2024PbPbpass3_23062026/recenterlast3", "Path to time recentering map 3"}; - // Event selection cuts - Alex - /* - TF1* fMultPVCutLow = nullptr; - TF1* fMultPVCutHigh = nullptr; - TF1* fMultCutLow = nullptr; - TF1* fMultCutHigh = nullptr; - TF1* fMultMultPVCut = nullptr; - */ - /* - template - bool eventSelected(TCollision collision, const double& centrality) - { - auto multNTracksPV = collision.multNTracksPV(); - if (multNTracksPV < fMultPVCutLow->Eval(centrality)) - return 0; - if (multNTracksPV > fMultPVCutHigh->Eval(centrality)) - return 0; - - return 1; - } - */ + struct : ConfigurableGroup { + // Five recentering stages. Each stage is applied in the strict order: + // cent -> (cent,Vx) -> (cent,Vy) -> (cent,Vz). + Configurable finecent1{"finecent1", false, "Apply fine centrality recentering, stage 1"}; + Configurable finecent2{"finecent2", false, "Apply fine centrality recentering, stage 2"}; + Configurable finecent3{"finecent3", false, "Apply fine centrality recentering, stage 3"}; + Configurable finecent4{"finecent4", false, "Apply fine centrality recentering, stage 4"}; + Configurable finecent5{"finecent5", false, "Apply fine centrality recentering, stage 5"}; + + Configurable finecentvx1{"finecentvx1", false, "Apply fine (cent,Vx) recentering, stage 1"}; + Configurable finecentvx2{"finecentvx2", false, "Apply fine (cent,Vx) recentering, stage 2"}; + Configurable finecentvx3{"finecentvx3", false, "Apply fine (cent,Vx) recentering, stage 3"}; + Configurable finecentvx4{"finecentvx4", false, "Apply fine (cent,Vx) recentering, stage 4"}; + Configurable finecentvx5{"finecentvx5", false, "Apply fine (cent,Vx) recentering, stage 5"}; + + Configurable finecentvy1{"finecentvy1", false, "Apply fine (cent,Vy) recentering, stage 1"}; + Configurable finecentvy2{"finecentvy2", false, "Apply fine (cent,Vy) recentering, stage 2"}; + Configurable finecentvy3{"finecentvy3", false, "Apply fine (cent,Vy) recentering, stage 3"}; + Configurable finecentvy4{"finecentvy4", false, "Apply fine (cent,Vy) recentering, stage 4"}; + Configurable finecentvy5{"finecentvy5", false, "Apply fine (cent,Vy) recentering, stage 5"}; + + Configurable finecentvz1{"finecentvz1", false, "Apply fine (cent,Vz) recentering, stage 1"}; + Configurable finecentvz2{"finecentvz2", false, "Apply fine (cent,Vz) recentering, stage 2"}; + Configurable finecentvz3{"finecentvz3", false, "Apply fine (cent,Vz) recentering, stage 3"}; + Configurable finecentvz4{"finecentvz4", false, "Apply fine (cent,Vz) recentering, stage 4"}; + Configurable finecentvz5{"finecentvz5", false, "Apply fine (cent,Vz) recentering, stage 5"}; + Configurable useRecenterefinecentSp{"useRecenterefinecentSp", false, "use finecent Recentering with THn"}; + Configurable useRecenterefinecentvxvyvzSp{"useRecenterefinecentvxvyvzSp", false, "use finecentvxvyvz Recentering with THn"}; + + Configurable confRecentereCentSp{"confRecentereCentSp", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for cent recentering"}; + Configurable confRecentereCentSp2{"confRecentereCentSp2", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for cent recentering 2"}; + Configurable confRecentereCentSp3{"confRecentereCentSp3", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for cent recentering 3"}; + Configurable confRecentereCentSp4{"confRecentereCentSp4", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for cent recentering 4"}; + Configurable confRecentereCentSp5{"confRecentereCentSp5", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for cent recentering 5"}; + Configurable confRecentereCentVxSp{"confRecentereCentVxSp", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvx recentering"}; + Configurable confRecentereCentVySp{"confRecentereCentVySp", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvy recentering"}; + Configurable confRecentereCentVzSp{"confRecentereCentVzSp", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvz recentering"}; + Configurable confRecentereCentVxSp2{"confRecentereCentVxSp2", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvx2 recentering"}; + Configurable confRecentereCentVySp2{"confRecentereCentVySp2", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvy2 recentering"}; + Configurable confRecentereCentVzSp2{"confRecentereCentVzSp2", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvz2 recentering"}; + Configurable confRecentereCentVxSp3{"confRecentereCentVxSp3", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvx3 recentering"}; + Configurable confRecentereCentVySp3{"confRecentereCentVySp3", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvy3 recentering"}; + Configurable confRecentereCentVzSp3{"confRecentereCentVzSp3", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvz3 recentering"}; + Configurable confRecentereCentVxSp4{"confRecentereCentVxSp4", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvx4 recentering"}; + Configurable confRecentereCentVySp4{"confRecentereCentVySp4", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvy4 recentering"}; + Configurable confRecentereCentVzSp4{"confRecentereCentVzSp4", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvz4 recentering"}; + Configurable confRecentereCentVxSp5{"confRecentereCentVxSp5", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvx5 recentering"}; + Configurable confRecentereCentVySp5{"confRecentereCentVySp5", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvy5 recentering"}; + Configurable confRecentereCentVzSp5{"confRecentereCentVzSp5", "Users/p/prottay/My/Object/Testingwithsparse/NewPbPbpass4_17092024/recenter", "Sparse or THn path for centvz5 recentering"}; + } confignewpro; struct : ConfigurableGroup { Configurable requireRCTFlagChecker{"requireRCTFlagChecker", true, "Check event quality in run condition table"}; @@ -265,6 +297,102 @@ struct spvector { histos.add("htimeQyZDCA", "htimeQyZDCA", kTH2F, {{timefineAxis}, {qxZDCAxis}}); histos.add("htimeQxZDCC", "htimeQxZDCC", kTH2F, {{timefineAxis}, {qxZDCAxis}}); histos.add("htimeQyZDCC", "htimeQyZDCC", kTH2F, {{timefineAxis}, {qxZDCAxis}}); + + histos.add("pQxZDCAvsCentVzAfter", + " after recentering;" + "centrality (%);V_{z} (cm);", + kTProfile2D, + {centfineAxis, vzfineAxis}); + + histos.add("pQyZDCAvsCentVzAfter", + " after recentering;" + "centrality (%);V_{z} (cm);", + kTProfile2D, + {centfineAxis, vzfineAxis}); + + histos.add("pQxZDCCvsCentVzAfter", + " after recentering;" + "centrality (%);V_{z} (cm);", + kTProfile2D, + {centfineAxis, vzfineAxis}); + + histos.add("pQyZDCCvsCentVzAfter", + " after recentering;" + "centrality (%);V_{z} (cm);", + kTProfile2D, + {centfineAxis, vzfineAxis}); + + histos.add("pQxZDCAvsCentVyAfter", + " after recentering;" + "centrality (%);V_{y} (cm);", + kTProfile2D, + {centfineAxis, vyfineAxis}); + + histos.add("pQyZDCAvsCentVyAfter", + " after recentering;" + "centrality (%);V_{y} (cm);", + kTProfile2D, + {centfineAxis, vyfineAxis}); + + histos.add("pQxZDCCvsCentVyAfter", + " after recentering;" + "centrality (%);V_{y} (cm);", + kTProfile2D, + {centfineAxis, vyfineAxis}); + + histos.add("pQyZDCCvsCentVyAfter", + " after recentering;" + "centrality (%);V_{y} (cm);", + kTProfile2D, + {centfineAxis, vyfineAxis}); + + histos.add("pQxZDCAvsCentVxAfter", + " after recentering;" + "centrality (%);V_{x} (cm);", + kTProfile2D, + {centfineAxis, vxfineAxis}); + + histos.add("pQyZDCAvsCentVxAfter", + " after recentering;" + "centrality (%);V_{x} (cm);", + kTProfile2D, + {centfineAxis, vxfineAxis}); + + histos.add("pQxZDCCvsCentVxAfter", + " after recentering;" + "centrality (%);V_{x} (cm);", + kTProfile2D, + {centfineAxis, vxfineAxis}); + + histos.add("pQyZDCCvsCentVxAfter", + " after recentering;" + "centrality (%);V_{x} (cm);", + kTProfile2D, + {centfineAxis, vxfineAxis}); + + histos.add("pQxZDCAvsVyVxAfter", + " after recentering;" + "V_{y};V_{x} (cm);", + kTProfile2D, + {vyfineAxis, vxfineAxis}); + + histos.add("pQyZDCAvsVyVxAfter", + " after recentering;" + "V_{y};V_{x} (cm);", + kTProfile2D, + {vyfineAxis, vxfineAxis}); + + histos.add("pQxZDCCvsVyVxAfter", + " after recentering;" + "V_{y};V_{x} (cm);", + kTProfile2D, + {vyfineAxis, vxfineAxis}); + + histos.add("pQyZDCCvsVyVxAfter", + " after recentering;" + "V_{y};V_{x} (cm);", + kTProfile2D, + {vyfineAxis, vxfineAxis}); } histos.add("PsiZDCC", "PsiZDCC", kTH2F, {centfineAxis, phiAxis}); @@ -276,22 +404,12 @@ struct spvector { histos.add("hpCosPsiAPsiC", "hpCosPsiAPsiC", kTProfile, {centfineAxis}); histos.add("hpSinPsiAPsiC", "hpSinPsiAPsiC", kTProfile, {centfineAxis}); histos.add("AvgVxy", "AvgVxy", kTProfile, {VxyAxis}); + histos.add("hpQxZDCAvstime", "hpQxZDCAvstime", kTProfile, {{timefineAxis}}); + histos.add("hpQxZDCCvstime", "hpQxZDCCvstime", kTProfile, {{timefineAxis}}); + histos.add("hpQyZDCAvstime", "hpQyZDCAvstime", kTProfile, {{timefineAxis}}); + histos.add("hpQyZDCCvstime", "hpQyZDCCvstime", kTProfile, {{timefineAxis}}); - // Event selection cut additional - Alex - /* - fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.5*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); - fMultPVCutLow->SetParameters(2834.66, -87.0127, 0.915126, -0.00330136, 332.513, -12.3476, 0.251663, -0.00272819, 1.12242e-05); - fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 2.5*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); - fMultPVCutHigh->SetParameters(2834.66, -87.0127, 0.915126, -0.00330136, 332.513, -12.3476, 0.251663, -0.00272819, 1.12242e-05); - fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.5*([4]+[5]*x)", 0, 100); - fMultCutLow->SetParameters(1893.94, -53.86, 0.502913, -0.0015122, 109.625, -1.19253); - fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 3.*([4]+[5]*x)", 0, 100); - fMultCutHigh->SetParameters(1893.94, -53.86, 0.502913, -0.0015122, 109.625, -1.19253); - fMultMultPVCut = new TF1("fMultMultPVCut", "[0]+[1]*x+[2]*x*x", 0, 5000); - fMultMultPVCut->SetParameters(-0.1, 0.785, -4.7e-05); - */ ccdb->setURL(cfgCcdbParam.cfgURL); - ccdbApi.init("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); @@ -299,17 +417,139 @@ struct spvector { int currentRunNumber = -999; int lastRunNumber = -999; - TH2D* gainprofile; - TProfile* gainprofilevxy; + TH2D* gainprofile = nullptr; + TProfile* gainprofilevxy = nullptr; std::array hrecentereSpA; // Array of 6 histograms std::array hrecenterecentSpA; // Array of 5 histograms std::array hrecenterevxSpA; // Array of 5 histograms std::array hrecenterevySpA; // Array of 5 histograms std::array hrecenterevzSpA; // Array of 5 histograms - TProfile3D* shiftprofileA; - TProfile3D* shiftprofileC; + TProfile3D* shiftprofileA = nullptr; + TProfile3D* shiftprofileC = nullptr; + TH2F* hrecentereTimeSp1 = nullptr; + TH2F* hrecentereTimeSp2 = nullptr; + TH2F* hrecentereTimeSp3 = nullptr; + // One payload for each of the five iterations. + std::array hrecenterecentvxSpA{}; + std::array hrecenterecentvySpA{}; + std::array hrecenterecentvzSpA{}; + + bool CorrectfineCent(TH2F* hrecenterecentSp, + auto centrality, + auto& qxZDCA, + auto& qyZDCA, + auto& qxZDCC, + auto& qyZDCC) + { + if (!hrecenterecentSp) { + return false; + } + + const double meanxAcent = hrecenterecentSp->GetBinContent( + hrecenterecentSp->FindBin(centrality + 0.00001, 0.5)); + const double meanyAcent = hrecenterecentSp->GetBinContent( + hrecenterecentSp->FindBin(centrality + 0.00001, 1.5)); + const double meanxCcent = hrecenterecentSp->GetBinContent( + hrecenterecentSp->FindBin(centrality + 0.00001, 2.5)); + const double meanyCcent = hrecenterecentSp->GetBinContent( + hrecenterecentSp->FindBin(centrality + 0.00001, 3.5)); + + qxZDCA -= meanxAcent; + qyZDCA -= meanyAcent; + qxZDCC -= meanxCcent; + qyZDCC -= meanyCcent; + + return true; + } + + bool CorrectfineCentVx(TH3F* hrecenterecentvxSp, + auto centrality, + auto vx, + auto& qxZDCA, + auto& qyZDCA, + auto& qxZDCC, + auto& qyZDCC) + { + if (!hrecenterecentvxSp) { + return false; + } + + const double meanxAcentvx = hrecenterecentvxSp->GetBinContent( + hrecenterecentvxSp->FindBin(centrality + 0.00001, vx + 0.00001, 0.5)); + const double meanyAcentvx = hrecenterecentvxSp->GetBinContent( + hrecenterecentvxSp->FindBin(centrality + 0.00001, vx + 0.00001, 1.5)); + const double meanxCcentvx = hrecenterecentvxSp->GetBinContent( + hrecenterecentvxSp->FindBin(centrality + 0.00001, vx + 0.00001, 2.5)); + const double meanyCcentvx = hrecenterecentvxSp->GetBinContent( + hrecenterecentvxSp->FindBin(centrality + 0.00001, vx + 0.00001, 3.5)); + + qxZDCA -= meanxAcentvx; + qyZDCA -= meanyAcentvx; + qxZDCC -= meanxCcentvx; + qyZDCC -= meanyCcentvx; + + return true; + } + + bool CorrectfineCentVy(TH3F* hrecenterecentvySp, + auto centrality, + auto vy, + auto& qxZDCA, + auto& qyZDCA, + auto& qxZDCC, + auto& qyZDCC) + { + if (!hrecenterecentvySp) { + return false; + } + + const double meanxAcentvy = hrecenterecentvySp->GetBinContent( + hrecenterecentvySp->FindBin(centrality + 0.00001, vy + 0.00001, 0.5)); + const double meanyAcentvy = hrecenterecentvySp->GetBinContent( + hrecenterecentvySp->FindBin(centrality + 0.00001, vy + 0.00001, 1.5)); + const double meanxCcentvy = hrecenterecentvySp->GetBinContent( + hrecenterecentvySp->FindBin(centrality + 0.00001, vy + 0.00001, 2.5)); + const double meanyCcentvy = hrecenterecentvySp->GetBinContent( + hrecenterecentvySp->FindBin(centrality + 0.00001, vy + 0.00001, 3.5)); + + qxZDCA -= meanxAcentvy; + qyZDCA -= meanyAcentvy; + qxZDCC -= meanxCcentvy; + qyZDCC -= meanyCcentvy; + + return true; + } - Bool_t Correctcoarse(const THnF* hrecentereSp, auto centrality, auto vx, auto vy, auto vz, auto& qxZDCA, auto& qyZDCA, auto& qxZDCC, auto& qyZDCC) + bool CorrectfineCentVz(TH3F* hrecenterecentvzSp, + auto centrality, + auto vz, + auto& qxZDCA, + auto& qyZDCA, + auto& qxZDCC, + auto& qyZDCC) + { + if (!hrecenterecentvzSp) { + return false; + } + + const double meanxAcentvz = hrecenterecentvzSp->GetBinContent( + hrecenterecentvzSp->FindBin(centrality + 0.00001, vz + 0.00001, 0.5)); + const double meanyAcentvz = hrecenterecentvzSp->GetBinContent( + hrecenterecentvzSp->FindBin(centrality + 0.00001, vz + 0.00001, 1.5)); + const double meanxCcentvz = hrecenterecentvzSp->GetBinContent( + hrecenterecentvzSp->FindBin(centrality + 0.00001, vz + 0.00001, 2.5)); + const double meanyCcentvz = hrecenterecentvzSp->GetBinContent( + hrecenterecentvzSp->FindBin(centrality + 0.00001, vz + 0.00001, 3.5)); + + qxZDCA -= meanxAcentvz; + qyZDCA -= meanyAcentvz; + qxZDCC -= meanxCcentvz; + qyZDCC -= meanyCcentvz; + + return true; + } + + bool Correctcoarse(const THnF* hrecentereSp, auto centrality, auto vx, auto vy, auto vz, auto& qxZDCA, auto& qyZDCA, auto& qxZDCC, auto& qyZDCC) { int binCoords[5]; @@ -353,7 +593,7 @@ struct spvector { return kTRUE; } - Bool_t Correctfine(TH2F* hrecenterecentSp, TH2F* hrecenterevxSp, TH2F* hrecenterevySp, TH2F* hrecenterevzSp, auto centrality, auto vx, auto vy, auto vz, auto& qxZDCA, auto& qyZDCA, auto& qxZDCC, auto& qyZDCC) + bool Correctfine(TH2F* hrecenterecentSp, TH2F* hrecenterevxSp, TH2F* hrecenterevySp, TH2F* hrecenterevzSp, auto centrality, auto vx, auto vy, auto vz, auto& qxZDCA, auto& qyZDCA, auto& qxZDCC, auto& qyZDCC) { if (!hrecenterecentSp || !hrecenterevxSp || !hrecenterevySp || !hrecenterevzSp) { @@ -389,19 +629,36 @@ struct spvector { return kTRUE; } + bool Correcttime(TH2F* hrecentereTimeSp, + auto timeMin, + auto& qxZDCA, + auto& qyZDCA, + auto& qxZDCC, + auto& qyZDCC) + { + if (!hrecentereTimeSp) { + return false; + } + + double meanxA = hrecentereTimeSp->GetBinContent(hrecentereTimeSp->FindBin(timeMin + 1.e-7, 0.5)); + double meanyA = hrecentereTimeSp->GetBinContent(hrecentereTimeSp->FindBin(timeMin + 1.e-7, 1.5)); + double meanxC = hrecentereTimeSp->GetBinContent(hrecentereTimeSp->FindBin(timeMin + 1.e-7, 2.5)); + double meanyC = hrecentereTimeSp->GetBinContent(hrecentereTimeSp->FindBin(timeMin + 1.e-7, 3.5)); + + qxZDCA -= meanxA; + qyZDCA -= meanyA; + qxZDCC -= meanxC; + qyZDCC -= meanyC; + + return true; + } + + using BCsRun3 = soa::Join; using MyCollisions = soa::Join; - using AllTrackCandidates = soa::Join; Preslice zdcPerCollision = aod::collision::bcId; - void process(MyCollisions::iterator const& collision, aod::FT0s const& /*ft0s*/, aod::FV0As const& /*fv0s*/, BCsRun3 const& bcs, aod::Zdcs const&, AllTrackCandidates const& tracks) + void process(MyCollisions::iterator const& collision, aod::FT0s const& /*ft0s*/, aod::FV0As const& /*fv0s*/, BCsRun3 const& bcs, aod::Zdcs const&) { - - if (usemem) { - for (const auto& track : tracks) { - histos.fill(HIST("htpcnsigmapi"), track.tpcNSigmaPi()); - } - } - histos.fill(HIST("hEvtSelInfo"), 0.5); auto centrality = collision.centFT0C(); bool triggerevent = false; @@ -440,10 +697,11 @@ struct spvector { // Store first timestamp of run to calculate relative time static std::unordered_map runStartTime; if (runStartTime.find(currentRunNumber) == runStartTime.end()) { - runStartTime[currentRunNumber] = timestampzdc; + // runStartTime[currentRunNumber] = timestampzdc; + runStartTime.try_emplace(currentRunNumber, timestampzdc); } - double timeInMinutes = (timestampzdc - runStartTime[currentRunNumber]) / 60000.0; // ms -> minutes + double timeMin = (timestampzdc - runStartTime[currentRunNumber]) / 60000.0; // ms -> minutes auto zdc = bc.zdc(); auto zncEnergy = zdc.energySectorZNC(); @@ -599,116 +857,361 @@ struct spvector { vy = vy - gainprofilevxy->GetBinContent(2); } - Bool_t res = 0; - Bool_t resfine = 0; - Int_t check = 1; + bool res = false; + bool resfine = false; + int check = 1; - if (coarse1) { - if (useRecentereSp && (currentRunNumber != lastRunNumber)) { - hrecentereSpA[0] = ccdb->getForTimeStamp(ConfRecentereSp.value, bc.timestamp()); + if (useoldrecentering) { + if (coarse1) { + if (useRecentereSp && (currentRunNumber != lastRunNumber)) { + hrecentereSpA[0] = ccdb->getForTimeStamp(ConfRecentereSp.value, bc.timestamp()); + } + res = Correctcoarse(hrecentereSpA[0], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); } - res = Correctcoarse(hrecentereSpA[0], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); - } - if (fine1) { + if (fine1) { - if (useRecenterefineSp && (currentRunNumber != lastRunNumber)) { - hrecenterecentSpA[0] = ccdb->getForTimeStamp(ConfRecenterecentSp.value, bc.timestamp()); - hrecenterevxSpA[0] = ccdb->getForTimeStamp(ConfRecenterevxSp.value, bc.timestamp()); - hrecenterevySpA[0] = ccdb->getForTimeStamp(ConfRecenterevySp.value, bc.timestamp()); - hrecenterevzSpA[0] = ccdb->getForTimeStamp(ConfRecenterevzSp.value, bc.timestamp()); + if (useRecenterefineSp && (currentRunNumber != lastRunNumber)) { + hrecenterecentSpA[0] = ccdb->getForTimeStamp(ConfRecenterecentSp.value, bc.timestamp()); + hrecenterevxSpA[0] = ccdb->getForTimeStamp(ConfRecenterevxSp.value, bc.timestamp()); + hrecenterevySpA[0] = ccdb->getForTimeStamp(ConfRecenterevySp.value, bc.timestamp()); + hrecenterevzSpA[0] = ccdb->getForTimeStamp(ConfRecenterevzSp.value, bc.timestamp()); + } + resfine = Correctfine(hrecenterecentSpA[0], hrecenterevxSpA[0], hrecenterevySpA[0], hrecenterevzSpA[0], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); } - resfine = Correctfine(hrecenterecentSpA[0], hrecenterevxSpA[0], hrecenterevySpA[0], hrecenterevzSpA[0], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); - } - if (coarse2) { - if (useRecentereSp && (currentRunNumber != lastRunNumber)) { - hrecentereSpA[1] = ccdb->getForTimeStamp(ConfRecentereSp2.value, bc.timestamp()); + if (finetime1 && (currentRunNumber != lastRunNumber)) { + hrecentereTimeSp1 = ccdb->getForTimeStamp(confRecentereTimeSp1.value, bc.timestamp()); + } + bool restime = false; + if (useTimeRecentering) { + restime = Correcttime(hrecentereTimeSp1, timeMin, qxZDCA, qyZDCA, qxZDCC, qyZDCC); } - res = Correctcoarse(hrecentereSpA[1], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); - } - if (fine2) { - if (useRecenterefineSp && (currentRunNumber != lastRunNumber)) { - hrecenterecentSpA[1] = ccdb->getForTimeStamp(ConfRecenterecentSp2.value, bc.timestamp()); - hrecenterevxSpA[1] = ccdb->getForTimeStamp(ConfRecenterevxSp2.value, bc.timestamp()); - hrecenterevySpA[1] = ccdb->getForTimeStamp(ConfRecenterevySp2.value, bc.timestamp()); - hrecenterevzSpA[1] = ccdb->getForTimeStamp(ConfRecenterevzSp2.value, bc.timestamp()); + if (coarse2) { + if (useRecentereSp && (currentRunNumber != lastRunNumber)) { + hrecentereSpA[1] = ccdb->getForTimeStamp(ConfRecentereSp2.value, bc.timestamp()); + } + res = Correctcoarse(hrecentereSpA[1], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); } - resfine = Correctfine(hrecenterecentSpA[1], hrecenterevxSpA[1], hrecenterevySpA[1], hrecenterevzSpA[1], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); - } - if (coarse3) { - if (useRecentereSp && (currentRunNumber != lastRunNumber)) { - hrecentereSpA[2] = ccdb->getForTimeStamp(ConfRecentereSp3.value, bc.timestamp()); + if (fine2) { + if (useRecenterefineSp && (currentRunNumber != lastRunNumber)) { + hrecenterecentSpA[1] = ccdb->getForTimeStamp(ConfRecenterecentSp2.value, bc.timestamp()); + hrecenterevxSpA[1] = ccdb->getForTimeStamp(ConfRecenterevxSp2.value, bc.timestamp()); + hrecenterevySpA[1] = ccdb->getForTimeStamp(ConfRecenterevySp2.value, bc.timestamp()); + hrecenterevzSpA[1] = ccdb->getForTimeStamp(ConfRecenterevzSp2.value, bc.timestamp()); + } + resfine = Correctfine(hrecenterecentSpA[1], hrecenterevxSpA[1], hrecenterevySpA[1], hrecenterevzSpA[1], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); } - res = Correctcoarse(hrecentereSpA[2], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); - } - if (fine3) { - if (useRecenterefineSp && (currentRunNumber != lastRunNumber)) { - hrecenterecentSpA[2] = ccdb->getForTimeStamp(ConfRecenterecentSp3.value, bc.timestamp()); - hrecenterevxSpA[2] = ccdb->getForTimeStamp(ConfRecenterevxSp3.value, bc.timestamp()); - hrecenterevySpA[2] = ccdb->getForTimeStamp(ConfRecenterevySp3.value, bc.timestamp()); - hrecenterevzSpA[2] = ccdb->getForTimeStamp(ConfRecenterevzSp3.value, bc.timestamp()); + if (finetime2 && (currentRunNumber != lastRunNumber)) { + hrecentereTimeSp2 = ccdb->getForTimeStamp(confRecentereTimeSp2.value, bc.timestamp()); + } + if (useTimeRecentering) { + restime = Correcttime(hrecentereTimeSp2, timeMin, qxZDCA, qyZDCA, qxZDCC, qyZDCC); } - resfine = Correctfine(hrecenterecentSpA[2], hrecenterevxSpA[2], hrecenterevySpA[2], hrecenterevzSpA[2], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); - } - if (coarse4) { - if (useRecentereSp && (currentRunNumber != lastRunNumber)) { - hrecentereSpA[3] = ccdb->getForTimeStamp(ConfRecentereSp4.value, bc.timestamp()); + if (coarse3) { + if (useRecentereSp && (currentRunNumber != lastRunNumber)) { + hrecentereSpA[2] = ccdb->getForTimeStamp(ConfRecentereSp3.value, bc.timestamp()); + } + res = Correctcoarse(hrecentereSpA[2], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); } - res = Correctcoarse(hrecentereSpA[3], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); - } - if (fine4) { - if (useRecenterefineSp && (currentRunNumber != lastRunNumber)) { - hrecenterecentSpA[3] = ccdb->getForTimeStamp(ConfRecenterecentSp4.value, bc.timestamp()); - hrecenterevxSpA[3] = ccdb->getForTimeStamp(ConfRecenterevxSp4.value, bc.timestamp()); - hrecenterevySpA[3] = ccdb->getForTimeStamp(ConfRecenterevySp4.value, bc.timestamp()); - hrecenterevzSpA[3] = ccdb->getForTimeStamp(ConfRecenterevzSp4.value, bc.timestamp()); + if (fine3) { + if (useRecenterefineSp && (currentRunNumber != lastRunNumber)) { + hrecenterecentSpA[2] = ccdb->getForTimeStamp(ConfRecenterecentSp3.value, bc.timestamp()); + hrecenterevxSpA[2] = ccdb->getForTimeStamp(ConfRecenterevxSp3.value, bc.timestamp()); + hrecenterevySpA[2] = ccdb->getForTimeStamp(ConfRecenterevySp3.value, bc.timestamp()); + hrecenterevzSpA[2] = ccdb->getForTimeStamp(ConfRecenterevzSp3.value, bc.timestamp()); + } + resfine = Correctfine(hrecenterecentSpA[2], hrecenterevxSpA[2], hrecenterevySpA[2], hrecenterevzSpA[2], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); } - resfine = Correctfine(hrecenterecentSpA[3], hrecenterevxSpA[3], hrecenterevySpA[3], hrecenterevzSpA[3], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); - } - if (coarse5) { - if (useRecentereSp && (currentRunNumber != lastRunNumber)) { - hrecentereSpA[4] = ccdb->getForTimeStamp(ConfRecentereSp5.value, bc.timestamp()); + if (finetime3 && (currentRunNumber != lastRunNumber)) { + hrecentereTimeSp3 = ccdb->getForTimeStamp(confRecentereTimeSp3.value, bc.timestamp()); + } + if (useTimeRecentering) { + restime = Correcttime(hrecentereTimeSp3, timeMin, qxZDCA, qyZDCA, qxZDCC, qyZDCC); } - res = Correctcoarse(hrecentereSpA[4], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); - } - if (fine5) { - if (useRecenterefineSp && (currentRunNumber != lastRunNumber)) { - hrecenterecentSpA[4] = ccdb->getForTimeStamp(ConfRecenterecentSp5.value, bc.timestamp()); - hrecenterevxSpA[4] = ccdb->getForTimeStamp(ConfRecenterevxSp5.value, bc.timestamp()); - hrecenterevySpA[4] = ccdb->getForTimeStamp(ConfRecenterevySp5.value, bc.timestamp()); - hrecenterevzSpA[4] = ccdb->getForTimeStamp(ConfRecenterevzSp5.value, bc.timestamp()); + if (coarse4) { + if (useRecentereSp && (currentRunNumber != lastRunNumber)) { + hrecentereSpA[3] = ccdb->getForTimeStamp(ConfRecentereSp4.value, bc.timestamp()); + } + res = Correctcoarse(hrecentereSpA[3], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); } - resfine = Correctfine(hrecenterecentSpA[4], hrecenterevxSpA[4], hrecenterevySpA[4], hrecenterevzSpA[4], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); - } - if (coarse6) { - if (useRecentereSp && (currentRunNumber != lastRunNumber)) { - hrecentereSpA[5] = ccdb->getForTimeStamp(ConfRecentereSp6.value, bc.timestamp()); + if (fine4) { + if (useRecenterefineSp && (currentRunNumber != lastRunNumber)) { + hrecenterecentSpA[3] = ccdb->getForTimeStamp(ConfRecenterecentSp4.value, bc.timestamp()); + hrecenterevxSpA[3] = ccdb->getForTimeStamp(ConfRecenterevxSp4.value, bc.timestamp()); + hrecenterevySpA[3] = ccdb->getForTimeStamp(ConfRecenterevySp4.value, bc.timestamp()); + hrecenterevzSpA[3] = ccdb->getForTimeStamp(ConfRecenterevzSp4.value, bc.timestamp()); + } + resfine = Correctfine(hrecenterecentSpA[3], hrecenterevxSpA[3], hrecenterevySpA[3], hrecenterevzSpA[3], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); } - res = Correctcoarse(hrecentereSpA[5], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); - } - if (fine6) { - if (useRecenterefineSp && (currentRunNumber != lastRunNumber)) { - hrecenterecentSpA[5] = ccdb->getForTimeStamp(ConfRecenterecentSp6.value, bc.timestamp()); - hrecenterevxSpA[5] = ccdb->getForTimeStamp(ConfRecenterevxSp6.value, bc.timestamp()); - hrecenterevySpA[5] = ccdb->getForTimeStamp(ConfRecenterevySp6.value, bc.timestamp()); - hrecenterevzSpA[5] = ccdb->getForTimeStamp(ConfRecenterevzSp6.value, bc.timestamp()); + if (coarse5) { + if (useRecentereSp && (currentRunNumber != lastRunNumber)) { + hrecentereSpA[4] = ccdb->getForTimeStamp(ConfRecentereSp5.value, bc.timestamp()); + } + res = Correctcoarse(hrecentereSpA[4], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); } - resfine = Correctfine(hrecenterecentSpA[5], hrecenterevxSpA[5], hrecenterevySpA[5], hrecenterevzSpA[5], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); - } - if (res == 0 && resfine == 0 && check == 0) { - LOG(info) << "Histograms are null"; + if (fine5) { + if (useRecenterefineSp && (currentRunNumber != lastRunNumber)) { + hrecenterecentSpA[4] = ccdb->getForTimeStamp(ConfRecenterecentSp5.value, bc.timestamp()); + hrecenterevxSpA[4] = ccdb->getForTimeStamp(ConfRecenterevxSp5.value, bc.timestamp()); + hrecenterevySpA[4] = ccdb->getForTimeStamp(ConfRecenterevySp5.value, bc.timestamp()); + hrecenterevzSpA[4] = ccdb->getForTimeStamp(ConfRecenterevzSp5.value, bc.timestamp()); + } + resfine = Correctfine(hrecenterecentSpA[4], hrecenterevxSpA[4], hrecenterevySpA[4], hrecenterevzSpA[4], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); + } + + if (coarse6) { + if (useRecentereSp && (currentRunNumber != lastRunNumber)) { + hrecentereSpA[5] = ccdb->getForTimeStamp(ConfRecentereSp6.value, bc.timestamp()); + } + res = Correctcoarse(hrecentereSpA[5], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); + } + + if (fine6) { + if (useRecenterefineSp && (currentRunNumber != lastRunNumber)) { + hrecenterecentSpA[5] = ccdb->getForTimeStamp(ConfRecenterecentSp6.value, bc.timestamp()); + hrecenterevxSpA[5] = ccdb->getForTimeStamp(ConfRecenterevxSp6.value, bc.timestamp()); + hrecenterevySpA[5] = ccdb->getForTimeStamp(ConfRecenterevySp6.value, bc.timestamp()); + hrecenterevzSpA[5] = ccdb->getForTimeStamp(ConfRecenterevzSp6.value, bc.timestamp()); + } + resfine = Correctfine(hrecenterecentSpA[5], hrecenterevxSpA[5], hrecenterevySpA[5], hrecenterevzSpA[5], centrality, vx, vy, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC); + } + + if (res == 0 && resfine == 0 && check == 0) { + LOG(info) << "Histograms are null"; + } + + if (useTimeRecentering && restime == 0 && check == 0) { + LOG(info) << "Histograms are null"; + } + } else { + + // Each stage must preserve this order: + // centrality -> (centrality,Vx) -> (centrality,Vy) -> (centrality,Vz). + // Keeping the switches separate allows the residual maps to be made + // in the same order in separate calibration passes. + + // -------------------- Stage 1 -------------------- + if (confignewpro.finecent1) { + if (confignewpro.useRecenterefinecentSp && + (currentRunNumber != lastRunNumber || !hrecenterecentSpA[0])) { + hrecenterecentSpA[0] = ccdb->getForTimeStamp(confignewpro.confRecentereCentSp.value, bc.timestamp()); + } + if (!CorrectfineCent(hrecenterecentSpA[0], centrality, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine centrality recentering, stage 1"); + } + } + + if (confignewpro.finecentvx1) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvxSpA[0])) { + hrecenterecentvxSpA[0] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVxSp.value, bc.timestamp()); + } + if (!CorrectfineCentVx(hrecenterecentvxSpA[0], centrality, vx, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vx) recentering, stage 1"); + } + } + + if (confignewpro.finecentvy1) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvySpA[0])) { + hrecenterecentvySpA[0] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVySp.value, bc.timestamp()); + } + if (!CorrectfineCentVy(hrecenterecentvySpA[0], centrality, vy, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vy) recentering, stage 1"); + } + } + + if (confignewpro.finecentvz1) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvzSpA[0])) { + hrecenterecentvzSpA[0] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVzSp.value, bc.timestamp()); + } + if (!CorrectfineCentVz(hrecenterecentvzSpA[0], centrality, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vz) recentering, stage 1"); + } + } + + // -------------------- Stage 2 -------------------- + if (confignewpro.finecent2) { + if (confignewpro.useRecenterefinecentSp && + (currentRunNumber != lastRunNumber || !hrecenterecentSpA[1])) { + hrecenterecentSpA[1] = ccdb->getForTimeStamp(confignewpro.confRecentereCentSp2.value, bc.timestamp()); + } + if (!CorrectfineCent(hrecenterecentSpA[1], centrality, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine centrality recentering, stage 2"); + } + } + + if (confignewpro.finecentvx2) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvxSpA[1])) { + hrecenterecentvxSpA[1] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVxSp2.value, bc.timestamp()); + } + if (!CorrectfineCentVx(hrecenterecentvxSpA[1], centrality, vx, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vx) recentering, stage 2"); + } + } + + if (confignewpro.finecentvy2) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvySpA[1])) { + hrecenterecentvySpA[1] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVySp2.value, bc.timestamp()); + } + if (!CorrectfineCentVy(hrecenterecentvySpA[1], centrality, vy, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vy) recentering, stage 2"); + } + } + + if (confignewpro.finecentvz2) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvzSpA[1])) { + hrecenterecentvzSpA[1] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVzSp2.value, bc.timestamp()); + } + if (!CorrectfineCentVz(hrecenterecentvzSpA[1], centrality, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vz) recentering, stage 2"); + } + } + + // -------------------- Stage 3 -------------------- + if (confignewpro.finecent3) { + if (confignewpro.useRecenterefinecentSp && + (currentRunNumber != lastRunNumber || !hrecenterecentSpA[2])) { + hrecenterecentSpA[2] = ccdb->getForTimeStamp(confignewpro.confRecentereCentSp3.value, bc.timestamp()); + } + if (!CorrectfineCent(hrecenterecentSpA[2], centrality, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine centrality recentering, stage 3"); + } + } + + if (confignewpro.finecentvx3) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvxSpA[2])) { + hrecenterecentvxSpA[2] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVxSp3.value, bc.timestamp()); + } + if (!CorrectfineCentVx(hrecenterecentvxSpA[2], centrality, vx, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vx) recentering, stage 3"); + } + } + + if (confignewpro.finecentvy3) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvySpA[2])) { + hrecenterecentvySpA[2] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVySp3.value, bc.timestamp()); + } + if (!CorrectfineCentVy(hrecenterecentvySpA[2], centrality, vy, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vy) recentering, stage 3"); + } + } + + if (confignewpro.finecentvz3) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvzSpA[2])) { + hrecenterecentvzSpA[2] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVzSp3.value, bc.timestamp()); + } + if (!CorrectfineCentVz(hrecenterecentvzSpA[2], centrality, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vz) recentering, stage 3"); + } + } + + // -------------------- Stage 4 -------------------- + if (confignewpro.finecent4) { + if (confignewpro.useRecenterefinecentSp && + (currentRunNumber != lastRunNumber || !hrecenterecentSpA[3])) { + hrecenterecentSpA[3] = ccdb->getForTimeStamp(confignewpro.confRecentereCentSp4.value, bc.timestamp()); + } + if (!CorrectfineCent(hrecenterecentSpA[3], centrality, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine centrality recentering, stage 4"); + } + } + + if (confignewpro.finecentvx4) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvxSpA[3])) { + hrecenterecentvxSpA[3] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVxSp4.value, bc.timestamp()); + } + if (!CorrectfineCentVx(hrecenterecentvxSpA[3], centrality, vx, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vx) recentering, stage 4"); + } + } + + if (confignewpro.finecentvy4) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvySpA[3])) { + hrecenterecentvySpA[3] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVySp4.value, bc.timestamp()); + } + if (!CorrectfineCentVy(hrecenterecentvySpA[3], centrality, vy, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vy) recentering, stage 4"); + } + } + + if (confignewpro.finecentvz4) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvzSpA[3])) { + hrecenterecentvzSpA[3] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVzSp4.value, bc.timestamp()); + } + if (!CorrectfineCentVz(hrecenterecentvzSpA[3], centrality, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vz) recentering, stage 4"); + } + } + + // -------------------- Stage 5 -------------------- + if (confignewpro.finecent5) { + if (confignewpro.useRecenterefinecentSp && + (currentRunNumber != lastRunNumber || !hrecenterecentSpA[4])) { + hrecenterecentSpA[4] = ccdb->getForTimeStamp(confignewpro.confRecentereCentSp5.value, bc.timestamp()); + } + if (!CorrectfineCent(hrecenterecentSpA[4], centrality, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine centrality recentering, stage 5"); + } + } + + if (confignewpro.finecentvx5) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvxSpA[4])) { + hrecenterecentvxSpA[4] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVxSp5.value, bc.timestamp()); + } + if (!CorrectfineCentVx(hrecenterecentvxSpA[4], centrality, vx, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vx) recentering, stage 5"); + } + } + + if (confignewpro.finecentvy5) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvySpA[4])) { + hrecenterecentvySpA[4] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVySp5.value, bc.timestamp()); + } + if (!CorrectfineCentVy(hrecenterecentvySpA[4], centrality, vy, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vy) recentering, stage 5"); + } + } + + if (confignewpro.finecentvz5) { + if (confignewpro.useRecenterefinecentvxvyvzSp && + (currentRunNumber != lastRunNumber || !hrecenterecentvzSpA[4])) { + hrecenterecentvzSpA[4] = ccdb->getForTimeStamp(confignewpro.confRecentereCentVzSp5.value, bc.timestamp()); + } + if (!CorrectfineCentVz(hrecenterecentvzSpA[4], centrality, vz, qxZDCA, qyZDCA, qxZDCC, qyZDCC)) { + LOGF(fatal, "Cannot apply fine (cent,Vz) recentering, stage 5"); + } + } } + + histos.fill(HIST("hpQxZDCAvstime"), timeMin, qxZDCA); + histos.fill(HIST("hpQxZDCCvstime"), timeMin, qxZDCC); + histos.fill(HIST("hpQyZDCAvstime"), timeMin, qyZDCA); + histos.fill(HIST("hpQyZDCCvstime"), timeMin, qyZDCC); + psiZDCC = 1.0 * TMath::ATan2(qyZDCC, qxZDCC); psiZDCA = 1.0 * TMath::ATan2(qyZDCA, qxZDCA); @@ -772,10 +1275,53 @@ struct spvector { histos.fill(HIST("hvzQxZDCC"), vz, qxZDCC); histos.fill(HIST("hvzQyZDCC"), vz, qyZDCC); - histos.fill(HIST("htimeQxZDCA"), timeInMinutes, qxZDCA); - histos.fill(HIST("htimeQyZDCA"), timeInMinutes, qyZDCA); - histos.fill(HIST("htimeQxZDCC"), timeInMinutes, qxZDCC); - histos.fill(HIST("htimeQyZDCC"), timeInMinutes, qyZDCC); + histos.fill(HIST("pQxZDCAvsCentVzAfter"), + centrality, vz, qxZDCA); + + histos.fill(HIST("pQyZDCAvsCentVzAfter"), + centrality, vz, qyZDCA); + + histos.fill(HIST("pQxZDCCvsCentVzAfter"), + centrality, vz, qxZDCC); + + histos.fill(HIST("pQyZDCCvsCentVzAfter"), + centrality, vz, qyZDCC); + + histos.fill(HIST("pQxZDCAvsCentVyAfter"), + centrality, vy, qxZDCA); + + histos.fill(HIST("pQyZDCAvsCentVyAfter"), + centrality, vy, qyZDCA); + + histos.fill(HIST("pQxZDCCvsCentVyAfter"), + centrality, vy, qxZDCC); + + histos.fill(HIST("pQyZDCCvsCentVyAfter"), + centrality, vy, qyZDCC); + + histos.fill(HIST("pQxZDCAvsCentVxAfter"), + centrality, vx, qxZDCA); + + histos.fill(HIST("pQyZDCAvsCentVxAfter"), + centrality, vx, qyZDCA); + + histos.fill(HIST("pQxZDCCvsCentVxAfter"), + centrality, vx, qxZDCC); + + histos.fill(HIST("pQyZDCCvsCentVxAfter"), + centrality, vx, qyZDCC); + + histos.fill(HIST("pQxZDCAvsVyVxAfter"), + vy, vx, qxZDCA); + + histos.fill(HIST("pQyZDCAvsVyVxAfter"), + vy, vx, qyZDCA); + + histos.fill(HIST("pQxZDCCvsVyVxAfter"), + vy, vx, qxZDCC); + + histos.fill(HIST("pQyZDCCvsVyVxAfter"), + vy, vx, qyZDCC); } histos.fill(HIST("hpCosPsiAPsiC"), centrality, (TMath::Cos(psiZDCA - psiZDCC))); diff --git a/PWGLF/TableProducer/Common/zdcvector.cxx b/PWGLF/TableProducer/Common/zdcvector.cxx index b6b5407156f..c32e81cdc7f 100644 --- a/PWGLF/TableProducer/Common/zdcvector.cxx +++ b/PWGLF/TableProducer/Common/zdcvector.cxx @@ -62,6 +62,7 @@ struct zdcvector { Produces zdccaltable; Produces zdcenergytable; Produces zdctimetable; + Produces zdcchargedtracks; // Configurables. struct : ConfigurableGroup { @@ -80,6 +81,12 @@ struct zdcvector { Configurable usemem{"usemem", true, "usemem"}; Configurable usecfactor{"usecfactor", false, "use c factor"}; + Configurable cfgTrackPtMin{"cfgTrackPtMin", 0.2f, "Minimum charged-track pT"}; + Configurable cfgTrackPtMax{"cfgTrackPtMax", 10.0f, "Maximum charged-track pT"}; + Configurable cfgTrackEtaMax{"cfgTrackEtaMax", 0.8f, "Maximum absolute eta"}; + Configurable cfgUseGlobalTracks{"cfgUseGlobalTracks", true, "Use global tracks"}; + Configurable storeChargedTracks{"storeChargedTracks", true, "Store selected charged tracks in a linked extra table"}; + struct : ConfigurableGroup { Configurable vzFineNbins{"vzFineNbins", 20, "Number of bins in Vz fine histograms"}; Configurable lfinebinVz{"lfinebinVz", -10.0, "lower bin value in Vz fine histograms"}; @@ -143,13 +150,35 @@ struct zdcvector { ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); } + template + bool selectionTrack(const T& candidate) + { + if (!(candidate.isGlobalTrack() && + candidate.isPVContributor() && + candidate.itsNCls() > 3 && + candidate.tpcNClsFound() > 50.0 && + candidate.itsNClsInnerBarrel() >= 1)) { + return false; + } + + if (std::abs(candidate.dcaXY()) >= 0.1) { + return false; + } + + if (std::abs(candidate.dcaZ()) >= 0.1) { + return false; + } + + return true; + } + int currentRunNumber = -999; int lastRunNumber = -999; TH2D* gainprofile = nullptr; TProfile* gainprofilevxy = nullptr; // int lastRunNumberTimeRec = -999; - // for time since start of run + // for time since start of run // int runForStartTime = -999; // uint64_t runStartTime = 0; @@ -217,7 +246,7 @@ struct zdcvector { float qxA, float qxC, float qyA, - float qyC) { + float qyC) -> int32_t { zdccaltable(trigger, currentRunNumber, centrality, @@ -229,7 +258,7 @@ struct zdcvector { qyA, qyC); - auto zdcCalIndex = zdccaltable.lastIndex(); + const auto zdcCalIndex = static_cast(zdccaltable.lastIndex()); if (storeZdcEnergy) { zdcenergytable(zdcCalIndex, @@ -244,11 +273,14 @@ struct zdcvector { znc2, znc3); } + if (storeZdcTime) { zdctimetable(zdcCalIndex, timestampzdc, timeInMinutes); } + + return zdcCalIndex; }; if (!bc.has_zdc()) { @@ -439,11 +471,42 @@ struct zdcvector { lastRunNumber = currentRunNumber; } // zdccaltable(triggerevent, currentRunNumber, centrality, vx, vy, vz, qxZDCA, qxZDCC, qyZDCA, qyZDCC); - fillTables(triggerevent, - qxZDCA, - qxZDCC, - qyZDCA, - qyZDCC); + const auto zdcCalIndex = fillTables(triggerevent, + qxZDCA, + qxZDCC, + qyZDCA, + qyZDCC); + + // Do not write tracks for events rejected by your ZDC/event selection + if (!triggerevent || !storeChargedTracks) { + return; + } + + // In this process signature, "tracks" are the tracks associated with + // the current collision. + for (const auto& track : tracks) { + if (!selectionTrack(track)) { + continue; + } + + if (track.pt() < cfgTrackPtMin || track.pt() > cfgTrackPtMax) { + continue; + } + + if (track.sign() == 0) { + continue; + } + + if (std::abs(track.eta()) > cfgTrackEtaMax) { + continue; + } + + zdcchargedtracks(zdcCalIndex, + track.px(), + track.py(), + track.pz(), + static_cast(track.sign())); + } } }; diff --git a/PWGLF/TableProducer/Nuspex/coalescenceTreeProducer.cxx b/PWGLF/TableProducer/Nuspex/coalescenceTreeProducer.cxx index f196e0ed8ff..4985cecbd8f 100644 --- a/PWGLF/TableProducer/Nuspex/coalescenceTreeProducer.cxx +++ b/PWGLF/TableProducer/Nuspex/coalescenceTreeProducer.cxx @@ -27,6 +27,8 @@ /// /// \author Alberto Calivà +#include "PWGLF/DataModel/mcCentrality.h" + #include #include #include @@ -36,7 +38,6 @@ #include #include #include -#include #include #include @@ -49,8 +50,9 @@ #include #include +#include + #include -#include #include #include @@ -65,6 +67,8 @@ using namespace o2::constants::math; constexpr double massHypertriton = 2.99116; +using GenCollisionsMc = soa::Join; + // Lightweight particle container struct ReducedParticle { int64_t idPart = 0; @@ -85,6 +89,8 @@ struct CoalescenceTreeProducer { // Configurable analysis parameters Configurable zVtxMax{"zVtxMax", 10.f, "Maximum |z vertex| in cm"}; + Configurable multMin{"multMin", 0.f, "Lower edge of the multiplicity/centrality interval (%)"}; + Configurable multMax{"multMax", 90.f, "Upper edge of the multiplicity/centrality interval (%)"}; Configurable etaMax{"etaMax", 1.5f, "Maximum |eta| for generated particles"}; Configurable pRhoMax{"pRhoMax", 0.5f, "Maximum Jacobi p_rho in GeV/c"}; Configurable pLambdaMax{"pLambdaMax", 0.5f, "Maximum Jacobi p_lambda in GeV/c"}; @@ -112,8 +118,17 @@ struct CoalescenceTreeProducer { registry.add("eventCounter", "event Counter", HistType::kTH1F, {{5, 0, 5, "counter"}}); registry.get(HIST("eventCounter"))->GetXaxis()->SetBinLabel(1, "Before z-vertex cut"); registry.get(HIST("eventCounter"))->GetXaxis()->SetBinLabel(2, "After z-vertex cut"); - registry.get(HIST("eventCounter"))->GetXaxis()->SetBinLabel(3, "After non-empty constituent lists"); - registry.get(HIST("eventCounter"))->GetXaxis()->SetBinLabel(4, "After non-empty candidate lists"); + registry.get(HIST("eventCounter"))->GetXaxis()->SetBinLabel(3, "After multiplicity selection"); + registry.get(HIST("eventCounter"))->GetXaxis()->SetBinLabel(4, "After non-empty constituent lists"); + registry.get(HIST("eventCounter"))->GetXaxis()->SetBinLabel(5, "After non-empty candidate lists"); + + // Multiplicity distribution + registry.add("multDistribution", "multiplicity distribution", HistType::kTH1F, {{200, 0, 100, "Multiplicity (%)"}}); + + // pt distributions of constituents (to be used for re-weighting) + registry.add("ptProtons", "ptProtons", HistType::kTH1F, {{200, 0, 10, "p_{T} (GeV/c)"}}); + registry.add("ptNeutrons", "ptNeutrons", HistType::kTH1F, {{200, 0, 10, "p_{T} (GeV/c)"}}); + registry.add("ptLambdas", "ptLambdas", HistType::kTH1F, {{200, 0, 10, "p_{T} (GeV/c)"}}); // Output tree for bound-state candidates treeBoundState.setObject(new TTree("BoundStateTree", "Tree for coalescence")); @@ -231,7 +246,7 @@ struct CoalescenceTreeProducer { Preslice mcParticlesPerMcCollision = o2::aod::mcparticle::mcCollisionId; // Process Hypertriton - void processHypertriton(aod::McCollisions const& collisions, aod::McParticles const& mcParticles) + void processHypertriton(GenCollisionsMc const& collisions, aod::McParticles const& mcParticles) { // Loop over MC collisions for (const auto& collision : collisions) { @@ -246,7 +261,16 @@ struct CoalescenceTreeProducer { // Event counter after z-vertex cut registry.fill(HIST("eventCounter"), 1.5); - // To be implemented: maybe add INEL>0 selection + // Multiplicity Distribution + const float multiplicityPerc = collision.centFT0M(); + registry.fill(HIST("multDistribution"), multiplicityPerc); + + // Multiplicity selection + if (multiplicityPerc < multMin || multiplicityPerc > multMax) + continue; + + // Event counter multiplicity selection + registry.fill(HIST("eventCounter"), 2.5); // Get particles in this MC collision const auto mcParticlesThisMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, collision.globalIndex()); @@ -284,6 +308,21 @@ struct CoalescenceTreeProducer { if (std::abs(particle.pdgCode()) == PDG_t::kLambda0) { lambdas.push_back({particle.globalIndex(), particle.pdgCode(), particle.vx(), particle.vy(), particle.vz(), particle.vt(), particle.px(), particle.py(), particle.pz()}); } + + // Rapidity selection + if (std::abs(particle.y()) > yMax) + continue; + + // Pt distributions of constituents + if (std::abs(particle.pdgCode()) == PDG_t::kProton) { + registry.fill(HIST("ptProtons"), particle.pt()); + } + if (std::abs(particle.pdgCode()) == PDG_t::kNeutron) { + registry.fill(HIST("ptNeutrons"), particle.pt()); + } + if (std::abs(particle.pdgCode()) == PDG_t::kLambda0) { + registry.fill(HIST("ptLambdas"), particle.pt()); + } } // end of loop over MC particles // Reject events that do not contain at least one proton, one neutron, and one lambda @@ -291,7 +330,7 @@ struct CoalescenceTreeProducer { continue; // Event counter: events containing all three constituent species - registry.fill(HIST("eventCounter"), 2.5); + registry.fill(HIST("eventCounter"), 3.5); // Count matter and antimatter candidates in the event Long64_t nCandidatesMatter(0); @@ -321,7 +360,7 @@ struct CoalescenceTreeProducer { continue; // Event counter: number of events with at least one candidate - registry.fill(HIST("eventCounter"), 3.5); + registry.fill(HIST("eventCounter"), 4.5); // Store number of candidates per event nMatterCandidatesPerEvent = nCandidatesMatter; diff --git a/PWGLF/TableProducer/Nuspex/deuteronInTriggeredEvents.cxx b/PWGLF/TableProducer/Nuspex/deuteronInTriggeredEvents.cxx index 412fbb44adc..e7bacabd29a 100644 --- a/PWGLF/TableProducer/Nuspex/deuteronInTriggeredEvents.cxx +++ b/PWGLF/TableProducer/Nuspex/deuteronInTriggeredEvents.cxx @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -81,7 +82,6 @@ #include #include -#include #include #include diff --git a/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx b/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx index 9bfaca1bef1..c363d84e3f3 100644 --- a/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx +++ b/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx @@ -259,6 +259,7 @@ struct EbyeMaker { Configurable kINT7Intervals{"kINT7Intervals", false, "toggle kINT7 trigger selection in the 10-30% and 50-90% centrality intervals (2018 Pb-Pb)"}; Configurable kUsePileUpCut{"kUsePileUpCut", false, "toggle strong correlation cuts (Run 2)"}; Configurable kUseEstimatorsCorrelationCut{"kUseEstimatorsCorrelationCut", false, "toggle cut on the correlation between centrality estimators (2018 Pb-Pb)"}; + Configurable kUsePID{"kUsePID", true, "use PID information in the analysis"}; Configurable kCentCutMax{"kCentCutMax", 100, "maximum accepted centrality"}; @@ -838,7 +839,8 @@ struct EbyeMaker { } if (mcLab.has_mcParticle()) { auto mcTrack = mcLab.template mcParticle_as(); - if (std::abs(mcTrack.pdgCode()) != kPartPdg[iP]) + auto pdgCode = mcTrack.pdgCode(); + if ((std::abs(pdgCode) != kPartPdg[iP] && kUsePID) || ((std::abs(pdgCode) == PDG_t::kPiPlus || std::abs(pdgCode) == PDG_t::kElectron || std::abs(pdgCode) == PDG_t::kMuonMinus || std::abs(pdgCode) == PDG_t::kKPlus || std::abs(pdgCode) == PDG_t::kProton) && !kUsePID)) continue; if ((((mcTrack.flags() & 0x8) || (mcTrack.flags() & 0x2)) && (doprocessMcRun2 || doprocessMiniMcRun2)) || ((mcTrack.flags() & 0x1) && !doprocessMiniMcRun2)) continue; @@ -847,7 +849,7 @@ struct EbyeMaker { continue; if (mcTrack.isPhysicalPrimary()) candidateTrack.pdgcodemoth = PartTypes::kPhysPrim; - else if (mcTrack.has_mothers() && iP == 0) + else if (mcTrack.has_mothers() && iP == 0 && kUsePID) candidateTrack.pdgcodemoth = getPartTypeMother(mcTrack); auto genPt = std::hypot(mcTrack.px(), mcTrack.py()); @@ -906,8 +908,9 @@ struct EbyeMaker { continue; auto pdgCode = mcPart.pdgCode(); auto genPt = std::hypot(mcPart.px(), mcPart.py()); + int ch = 0; if ((std::abs(pdgCode) == PDG_t::kPiPlus || std::abs(pdgCode) == PDG_t::kElectron || std::abs(pdgCode) == PDG_t::kMuonMinus || std::abs(pdgCode) == PDG_t::kKPlus || std::abs(pdgCode) == PDG_t::kProton) && mcPart.isPhysicalPrimary() && genPt > ptMin[0] && genPt < ptMax[0]) { - int ch = (pdgCode == PDG_t::kPiPlus || pdgCode == -PDG_t::kElectron || pdgCode == -PDG_t::kMuonMinus || pdgCode == PDG_t::kKPlus || pdgCode == PDG_t::kProton) ? 1 : -1; + ch = (pdgCode == PDG_t::kPiPlus || pdgCode == -PDG_t::kElectron || pdgCode == -PDG_t::kMuonMinus || pdgCode == PDG_t::kKPlus || pdgCode == PDG_t::kProton) ? 1 : -1; if ((ch < 0 && countOnlyLSTrk == TracksCharge::kNegative) || (ch > 0 && countOnlyLSTrk == TracksCharge::kPositive) || (countOnlyLSTrk == TracksCharge::kAll)) nChPartGen++; } @@ -935,9 +938,9 @@ struct EbyeMaker { LOGF(debug, "not found!"); candidateV0s.emplace_back(candV0); } - } else if (std::abs(pdgCode) == kPartPdg[0] || std::abs(pdgCode) == kPartPdg[1]) { + } else if (((std::abs(pdgCode) == kPartPdg[0] || std::abs(pdgCode) == kPartPdg[1]) && kUsePID) || (std::abs(ch) == 1 && !kUsePID)) { int iP = 1; - if (std::abs(pdgCode) == kPartPdg[0]) { + if ((std::abs(pdgCode) == kPartPdg[0] && kUsePID) || !kUsePID) { iP = 0; } if ((!mcPart.isPhysicalPrimary() && !doprocessMiniMcRun2)) @@ -949,7 +952,7 @@ struct EbyeMaker { candTrack.pdgcode = pdgCode; if (mcPart.isPhysicalPrimary()) candTrack.pdgcodemoth = PartTypes::kPhysPrim; - else if (mcPart.has_mothers() && iP == 0) + else if (mcPart.has_mothers() && iP == 0 && kUsePID) candTrack.pdgcodemoth = getPartTypeMother(mcPart); auto it = find_if(candidateTracks[iP].begin(), candidateTracks[iP].end(), [&](CandidateTrack trk) { return trk.mcIndex == mcPart.globalIndex(); }); diff --git a/PWGLF/TableProducer/Nuspex/he3LambdaAnalysis.cxx b/PWGLF/TableProducer/Nuspex/he3LambdaAnalysis.cxx index 9b75803f9fd..01411e4e566 100644 --- a/PWGLF/TableProducer/Nuspex/he3LambdaAnalysis.cxx +++ b/PWGLF/TableProducer/Nuspex/he3LambdaAnalysis.cxx @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -42,8 +43,6 @@ #include #include -#include - #include #include #include diff --git a/PWGLF/TableProducer/Nuspex/lfTreeCreatorNuclei.cxx b/PWGLF/TableProducer/Nuspex/lfTreeCreatorNuclei.cxx index 238ab1a0afb..438f082f070 100644 --- a/PWGLF/TableProducer/Nuspex/lfTreeCreatorNuclei.cxx +++ b/PWGLF/TableProducer/Nuspex/lfTreeCreatorNuclei.cxx @@ -19,7 +19,6 @@ #include "PWGLF/DataModel/LFNucleiTables.h" #include "PWGLF/DataModel/LFParticleIdentification.h" -#include "PWGLF/Utils/inelGt.h" #include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/TrackSelection.h" diff --git a/PWGLF/TableProducer/Nuspex/nucleiAntineutronCex.cxx b/PWGLF/TableProducer/Nuspex/nucleiAntineutronCex.cxx index d239368e3df..f732a5f8cc9 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiAntineutronCex.cxx +++ b/PWGLF/TableProducer/Nuspex/nucleiAntineutronCex.cxx @@ -518,7 +518,7 @@ struct NucleiAntineutronCex { if (motherPz != 0) histos.fill(HIST("cexn_pairmc_pz"), cexPairMcPz / motherPz); if (motherP != 0 && pion0) - histos.fill(HIST("cexPairMcP_pi0"), cexPairMcP / motherP); + histos.fill(HIST("cexn_pairmc_p_pi0"), cexPairMcP / motherP); } // BG mother if (motherPdg != -kNeutron) { diff --git a/PWGLF/TableProducer/Nuspex/nucleiFlowTree.cxx b/PWGLF/TableProducer/Nuspex/nucleiFlowTree.cxx index a17eefdcf21..0e11dd983e8 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiFlowTree.cxx +++ b/PWGLF/TableProducer/Nuspex/nucleiFlowTree.cxx @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,6 @@ #include #include -#include #include #include diff --git a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx index e4d3987f8da..5358f18b079 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx +++ b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -72,7 +73,6 @@ #include -#include #include #include @@ -297,6 +297,7 @@ struct nucleiSpectra { }; Produces nucleiTable; + Produces nucleiTableCent; Produces nucleiPairTable; Produces nucleiTableMC; Produces nucleiTableMCExtension; @@ -841,6 +842,16 @@ struct nucleiSpectra { std::hypot(collision.qvecBTotIm(), collision.qvecBTotRe()), std::hypot(collision.qvecBNegIm(), collision.qvecBNegRe()), std::hypot(collision.qvecBPosIm(), collision.qvecBPosRe())}); + } else if constexpr (requires { + collision.centFT0C(); + }) { + nuclei::candidates_flow.emplace_back(NucleusCandidateFlow{ + collision.centFV0A(), + collision.centFT0M(), + collision.centFT0A(), + collision.centFT0C(), + 0.f, 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, 0.f}); } if (fillTree) { if (flag & kTriton) { @@ -860,9 +871,10 @@ struct nucleiSpectra { nuclei::hGloTOFtracks[1]->Fill(nGloTracks[1], nTOFTracks[1]); } - void processData(soa::Join::iterator const& collision, TrackCandidates const& tracks, aod::BCsWithTimestamps const&) + void processData(CollWithCent const& collision, TrackCandidates const& tracks, aod::BCsWithTimestamps const&) { nuclei::candidates.clear(); + nuclei::candidates_flow.clear(); if (!eventSelectionWithHisto(collision)) { return; } @@ -870,8 +882,10 @@ struct nucleiSpectra { fillDataInfo(collision, tracks); for (size_t i1{0}; i1 < nuclei::candidates.size(); ++i1) { auto& c1 = nuclei::candidates[i1]; + auto& c1Cent = nuclei::candidates_flow[i1]; if (c1.fillTree) { nucleiTable(c1.pt, c1.eta, c1.phi, c1.tpcInnerParam, c1.beta, c1.zVertex, c1.nContrib, c1.DCAxy, c1.DCAz, c1.TPCsignal, c1.ITSchi2, c1.TPCchi2, c1.TOFchi2, c1.flags, c1.TPCfindableCls, c1.TPCcrossedRows, c1.ITSclsMap, c1.TPCnCls, c1.TPCnClsShared, c1.clusterSizesITS); + nucleiTableCent(c1Cent.centFV0A, c1Cent.centFT0M, c1Cent.centFT0A, c1Cent.centFT0C); if (cfgFillPairTree) { for (size_t i2{i1 + 1}; i2 < nuclei::candidates.size(); ++i2) { auto& c2 = nuclei::candidates[i2]; diff --git a/PWGLF/TableProducer/QC/flowQC.cxx b/PWGLF/TableProducer/QC/flowQC.cxx index 8210ac95666..6c9606bdef2 100644 --- a/PWGLF/TableProducer/QC/flowQC.cxx +++ b/PWGLF/TableProducer/QC/flowQC.cxx @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -48,8 +49,6 @@ #include -#include - #include #include #include diff --git a/PWGLF/TableProducer/QC/nucleiQC.cxx b/PWGLF/TableProducer/QC/nucleiQC.cxx index bef7cb9f4f5..c22c5cdf81a 100644 --- a/PWGLF/TableProducer/QC/nucleiQC.cxx +++ b/PWGLF/TableProducer/QC/nucleiQC.cxx @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -51,9 +52,6 @@ #include -#include - -#include #include #include #include @@ -99,6 +97,7 @@ struct nucleiQC { Configurable cfgFillTable{"cfgFillTable", true, "Fill output tree"}; Configurable cfgDoCheckPdgCode{"cfgDoCheckPdgCode", true, "Should you only select tracks associated to a mc particle with the correct PDG code?"}; + Configurable cfgSkipNonReconstructedCollisions{"cfgSkipNonReconstructedCollisions", true, "Should you skip collisions for which no particle is reconstructed?"}; Configurable cfgFillOnlyPhysicalPrimaries{"cfgFillOnlyPhysicalPrimaries", true, "Should you only select physical primary particles?"}; Configurable> cfgSpeciesToProcess{"cfgSpeciesToProcess", {nuclei::speciesToProcessDefault[0], nuclei::Species::kNspecies, 1, nuclei::names, {"processNucleus"}}, "Nuclei to process"}; Configurable> cfgEventSelections{"cfgEventSelections", {nuclei::EvSelDefault[0], 8, 1, nuclei::eventSelectionLabels, nuclei::eventSelectionTitle}, "Event selections"}; @@ -161,6 +160,7 @@ struct nucleiQC { std::array mFillSpecies{false}; Produces mNucleiTableRed; Produces mNucleiTableExt; + Produces mNucleiTableMat; std::vector mNucleiCandidates; std::vector mFilledMcParticleIds; @@ -208,6 +208,7 @@ struct nucleiQC { nuclei::createHistogramRegistryNucleus(mHistograms); mHistograms.add(fmt::format("{}/hTrackQuality", nuclei::cNames[kSpeciesRt]).c_str(), (fmt::format("{} track quality;", nuclei::cNames[kSpeciesRt]) + std::string("#it{p}_{T} / #it{Z} (GeV/#it{c}); Selection step; Counts")).c_str(), o2::framework::HistType::kTH2D, {{400, -10.0f, 10.0f}, {trackQuality::kNtrackQuality, -0.5f, static_cast(trackQuality::kNtrackQuality) - 0.5f}}); + mHistograms.add(fmt::format("{}/h2Productionvertex", nuclei::cNames[kSpeciesRt]).c_str(), (fmt::format("{} production vertex;", nuclei::cNames[kSpeciesRt]) + std::string("#it{x} (cm); #it{y} (cm); Counts")).c_str(), o2::framework::HistType::kTH2D, {{400, -100.0f, 100.0f}, {400, -100.0f, 100.0f}}); for (size_t iSel = 0; iSel < trackQuality::kNtrackQuality; iSel++) { mHistograms.get(HIST(nuclei::cNames[kSpeciesRt]) + HIST("/hTrackQuality"))->GetYaxis()->SetBinLabel(iSel + 1, trackQualityLabels[iSel].c_str()); } @@ -351,7 +352,7 @@ struct nucleiQC { return true; } - template + template void fillNucleusFlagsPdgsMc(const Tparticle& particle, nuclei::SlimCandidate& candidate) { candidate.pdgCode = particle.pdgCode(); @@ -382,6 +383,9 @@ struct nucleiQC { candidate.flags |= nuclei::QcFlags::kQcIsSecondaryFromWeakDecay; } else { candidate.flags |= nuclei::QcFlags::kQcIsSecondaryFromMaterial; + mHistograms.fill(HIST(nuclei::cNames[iSpecies]) + HIST("/h2Productionvertex"), particle.vx(), particle.vy()); + candidate.vx = particle.vx(); + candidate.vy = particle.vy(); } } @@ -442,7 +446,9 @@ struct nucleiQC { .centrality = nuclei::getCentrality(collision, cfgCentralityEstimator, mHistFailCentrality), .mcProcess = TMCProcess::kPNoProcess, .nsigmaTpc = mPidManagers[iSpecies].getNSigmaTPC(track), - .nsigmaTof = mPidManagers[iSpecies].getNSigmaTOF(track)}; + .nsigmaTof = mPidManagers[iSpecies].getNSigmaTOF(track), + .vx = -999.f, + .vy = -999.f}; fillNucleusFlagsPdgs(collision, track, candidate); @@ -450,7 +456,12 @@ struct nucleiQC { if (track.has_mcParticle()) { const auto& particle = track.mcParticle(); - fillNucleusFlagsPdgsMc(particle, candidate); + static_for<0, nuclei::kNspecies - 1>([&](auto iSpeciesCtV) { + constexpr int kSpeciesCt = decltype(iSpeciesCtV)::value; + if (std::abs(particle.pdgCode()) == nuclei::pdgCodes[kSpeciesCt]) { + fillNucleusFlagsPdgsMc(particle, candidate); + } + }); fillNucleusGeneratedVariables(particle, candidate); } } @@ -526,6 +537,9 @@ struct nucleiQC { mNucleiTableExt( candidate.nsigmaTpc, candidate.nsigmaTof); + mNucleiTableMat( + candidate.vx, + candidate.vy); } void processMc(const Collisions& collisions, const TrackCandidatesMC& tracks, const aod::BCsWithTimestamps&, const aod::McParticles& mcParticles, const aod::McCollisions& /*mcCollisions*/) @@ -625,6 +639,9 @@ struct nucleiQC { if (!mFillSpecies[iSpecies]) continue; + if (cfgSkipNonReconstructedCollisions && reconstructedCollisions.count(particle.mcCollisionId()) == 0) + continue; + if (reconstructedMcParticles.count(mcIndex) > 0) continue; @@ -643,7 +660,12 @@ struct nucleiQC { const auto& centralityIt = mcCollisionIdToCentrality.find(particle.mcCollisionId()); candidate.centrality = centralityIt != mcCollisionIdToCentrality.end() ? centralityIt->second : -1.f; fillCollisionFlag(particle, candidate, reconstructedCollisions); - fillNucleusFlagsPdgsMc(particle, candidate); + static_for<0, nuclei::kNspecies - 1>([&](auto iSpeciesCtV) { + constexpr int kSpeciesCt = decltype(iSpeciesCtV)::value; + if (std::abs(particle.pdgCode()) == nuclei::pdgCodes[kSpeciesCt]) { + fillNucleusFlagsPdgsMc(particle, candidate); + } + }); fillNucleusGeneratedVariables(particle, candidate); writeCandidate(candidate); diff --git a/PWGLF/TableProducer/Resonances/CMakeLists.txt b/PWGLF/TableProducer/Resonances/CMakeLists.txt index a3e59673293..05e51ad1511 100644 --- a/PWGLF/TableProducer/Resonances/CMakeLists.txt +++ b/PWGLF/TableProducer/Resonances/CMakeLists.txt @@ -55,6 +55,11 @@ o2physics_add_dpl_workflow(cksspinalignment PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(phiflow + SOURCES phiflow.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(resonance-tree-creator SOURCES resonanceTreeCreator.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGLF/TableProducer/Resonances/doublephitable.cxx b/PWGLF/TableProducer/Resonances/doublephitable.cxx index b682d8cbb40..0c116305cac 100644 --- a/PWGLF/TableProducer/Resonances/doublephitable.cxx +++ b/PWGLF/TableProducer/Resonances/doublephitable.cxx @@ -17,6 +17,7 @@ #include "PWGLF/DataModel/ReducedDoublePhiTables.h" #include "Common/CCDB/EventSelectionParams.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseITS.h" @@ -83,7 +84,7 @@ struct doublephitable { Filter DCAcutFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz); Filter PIDcutFilter = nabs(aod::pidtpc::tpcNSigmaKa) < nsigmaCutTPC; - using EventCandidates = soa::Filtered>; + using EventCandidates = soa::Filtered>; using TrackCandidates = soa::Filtered>; SliceCache cache; @@ -165,7 +166,7 @@ struct doublephitable { int Npostrack = 0; int Nnegtrack = 0; - + float centrality = collision.centFT0M(); if (collision.sel8() && collision.selection_bit(aod::evsel::kNoTimeFrameBorder) && collision.selection_bit(aod::evsel::kNoITSROFrameBorder) && collision.selection_bit(aod::evsel::kNoSameBunchPileup) && collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { auto posThisColl = posTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto negThisColl = negTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -258,7 +259,7 @@ struct doublephitable { if (keepEventDoublePhi && numberPhi > 1 && Npostrack > 1 && Nnegtrack > 1 && (phiresonance.size() == phiresonanced1.size()) && (phiresonance.size() == phiresonanced2.size())) { qaRegistry.fill(HIST("hEventstat"), 1.5); /////////// Fill collision table/////////////// - redPhiEvents(bc.globalBC(), currentRunNumber, bc.timestamp(), collision.posZ(), collision.numContrib(), Npostrack, Nnegtrack); + redPhiEvents(bc.globalBC(), currentRunNumber, bc.timestamp(), collision.posZ(), collision.numContrib(), Npostrack, Nnegtrack, centrality); auto indexEvent = redPhiEvents.lastIndex(); //// Fill track table for Phi////////////////// for (auto if1 = phiresonance.begin(); if1 != phiresonance.end(); ++if1) { diff --git a/PWGLF/TableProducer/Resonances/phiflow.cxx b/PWGLF/TableProducer/Resonances/phiflow.cxx new file mode 100644 index 00000000000..0fba563e264 --- /dev/null +++ b/PWGLF/TableProducer/Resonances/phiflow.cxx @@ -0,0 +1,567 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file phiflow.cxx +/// \brief Table producer for Phi FLow +/// +/// \author prottay.das@cern.ch + +#include "PWGLF/DataModel/LFPhiFlowTables.h" +#include "PWGLF/DataModel/SPCalibrationTables.h" + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/RCTSelectionFlags.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponseITS.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) + +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::aod::rctsel; + +struct phiflow { + + Produces kaonEvent; + Produces kaonTrack; + + struct : ConfigurableGroup { + Configurable requireRCTFlagChecker{"requireRCTFlagChecker", true, "Check event quality in run condition table"}; + Configurable cfgEvtRCTFlagCheckerLabel{"cfgEvtRCTFlagCheckerLabel", "CBT_hadronPID", "Evt sel: RCT flag checker label"}; + Configurable cfgEvtRCTFlagCheckerZDCCheck{"cfgEvtRCTFlagCheckerZDCCheck", false, "Evt sel: RCT flag checker ZDC check"}; + Configurable cfgEvtRCTFlagCheckerLimitAcceptAsBad{"cfgEvtRCTFlagCheckerLimitAcceptAsBad", true, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; + } rctCut; + + Configurable useNoCollInTimeRangeStandard{"useNoCollInTimeRangeStandard", false, "Apply kNoCollInTimeRangeStandard selection bit"}; + Configurable useGoodITSLayersAll{"useGoodITSLayersAll", true, "Apply kIsGoodITSLayersAll selection bit"}; + Configurable cfgCutOccupancy{"cfgCutOccupancy", 2000, "Occupancy cut"}; + + // events + Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; + Configurable cfgCutCentralityMax{"cfgCutCentralityMax", 80.0f, "Accepted maximum Centrality"}; + Configurable cfgCutCentralityMin{"cfgCutCentralityMin", 0.0f, "Accepted minimum Centrality"}; + + // Configs for track filtering + Configurable cfgCutCharge{"cfgCutCharge", 0.0, "Charge cut on daughter"}; + Configurable cfgCutPt{"cfgCutPt", 0.2, "Pt cut on daughter track"}; + Configurable cfgCutEta{"cfgCutEta", 0.8, "Eta cut on daughter track"}; + Configurable cfgCutDCAxy{"cfgCutDCAxy", 0.2, "DCAxy cut on daughter track"}; + Configurable cfgCutDCAz{"cfgCutDCAz", 0.2, "DCAz cut on daughter track"}; + Configurable nsigmaCutTPC{"nsigmaCutTPC", 3.0, "Maximum nsigma cut TPC for filtered kaon track"}; + + // Configs for kaon + struct : ConfigurableGroup { + Configurable itsPIDSelection{"itsPIDSelection", true, "PID ITS"}; + Configurable lowITSPIDNsigma{"lowITSPIDNsigma", -3.0, "lower cut on PID nsigma for ITS"}; + Configurable highITSPIDNsigma{"highITSPIDNsigma", 3.0, "higher cut on PID nsigma for ITS"}; + Configurable itsclusterKaMeson{"itsclusterKaMeson", 5, "Minimum number of ITS cluster for kaon meson track"}; + Configurable tpcCrossedRowsKaMeson{"tpcCrossedRowsKaMeson", 80, "Minimum number of TPC Crossed Rows for kaon meson track"}; + Configurable cutDCAxyKaMeson{"cutDCAxyKaMeson", 0.1, "Maximum DCAxy for kaon meson track"}; + Configurable cutDCAzKaMeson{"cutDCAzKaMeson", 0.1, "Maximum DCAz for kaon meson track"}; + Configurable cutEtaKaMeson{"cutEtaKaMeson", 0.8, "Maximum eta for kaon meson track"}; + Configurable cutPTKaMeson{"cutPTKaMeson", 0.8, "Minimum pt for kaon meson track"}; + Configurable usePID{"usePID", true, "Flag for using PID selection for kaon meson track"}; + Configurable nsigmaCutTPCKaMeson{"nsigmaCutTPCKaMeson", 3.0, "Maximum nsigma cut TPC for kaon meson track"}; + Configurable nsigmaCutTOFKaMeson{"nsigmaCutTOFKaMeson", 3.0, "Maximum nsigma cut TOF for kaon meson track"}; + Configurable cutTOFBetaKaMeson{"cutTOFBetaKaMeson", 0.5f, "Maximum beta cut for kaon meson track"}; + Configurable pSwitchPID{"pSwitchPID", 0.5f, "pT switch for pT-dependent kaon PID"}; + Configurable pSwitchAsymPID{"pSwitchAsymPID", 0.7f, "Momentum switch for asymmetric kaon PID"}; + Configurable applyTOFAsymPID{"applyTOFAsymPID", true, "Apply TOF requirement in PID7"}; + } grpKaon; + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + RCTFlagsChecker rctChecker; + void init(o2::framework::InitContext&) + { + rctChecker.init(rctCut.cfgEvtRCTFlagCheckerLabel, rctCut.cfgEvtRCTFlagCheckerZDCCheck, rctCut.cfgEvtRCTFlagCheckerLimitAcceptAsBad); + + histos.add("hCent", "hCent", kTH1F, {{8, 0, 80.0}}); + histos.add("hEvtSelInfo", "hEvtSelInfo", kTH1F, {{5, 0, 5.0}}); + histos.add("hTrkSelInfo", "hTrkSelInfo", kTH1F, {{10, 0, 10.0}}); + } + + template + bool selectionTrack(const T& candidate) + { + return candidate.isGlobalTrack() && + candidate.isPVContributor() && + candidate.itsNCls() >= grpKaon.itsclusterKaMeson && + candidate.tpcNClsCrossedRows() > grpKaon.tpcCrossedRowsKaMeson && + std::abs(candidate.dcaXY()) <= grpKaon.cutDCAxyKaMeson && + std::abs(candidate.dcaZ()) <= grpKaon.cutDCAzKaMeson && + std::abs(candidate.eta()) <= grpKaon.cutEtaKaMeson && + candidate.pt() >= grpKaon.cutPTKaMeson; + } + + enum KaonPidBits : uint8_t { + kPID1 = 1u << 0, // TOF-availability-dependent rectangular PID + kPID2 = 1u << 1, // TOF-availability-dependent circular PID + kPID3 = 1u << 2, // pT-dependent circular PID + kPID4 = 1u << 3, // pT-dependent rectangular PID, phi-v2-like + kPID5 = 1u << 4, // TOF-only PID + kPID6 = 1u << 5, // Momentum-dependent asymmetric TOF PID + kPID7 = 1u << 6 // Optional-TOF asymmetric PID + }; + + template + bool selectionPID(const T& candidate) + { + const float nTPC = candidate.tpcNSigmaKa(); + + // No TOF hit: TPC-only PID at all pT. + if (!candidate.hasTOF()) { + return std::abs(nTPC) < grpKaon.nsigmaCutTPCKaMeson; + } + + // TOF hit: require beta, TPC PID, and TOF PID. + if (candidate.beta() <= grpKaon.cutTOFBetaKaMeson) { + return false; + } + + return std::abs(nTPC) < grpKaon.nsigmaCutTPCKaMeson && + std::abs(candidate.tofNSigmaKa()) < grpKaon.nsigmaCutTOFKaMeson; + } + + template + bool selectionPID2(const T& candidate) + { + const float nTPC = candidate.tpcNSigmaKa(); + + // No TOF hit: TPC-only PID at all pT. + if (!candidate.hasTOF()) { + return std::abs(nTPC) < grpKaon.nsigmaCutTPCKaMeson; + } + + if (candidate.beta() <= grpKaon.cutTOFBetaKaMeson) { + return false; + } + + const float nTOF = candidate.tofNSigmaKa(); + const float nCombined = std::sqrt(nTPC * nTPC + nTOF * nTOF); + + return nCombined < grpKaon.nsigmaCutTOFKaMeson; + } + + template + bool selectionPID3(const T& candidate) + { + const float pt = candidate.pt(); + const float nTPC = candidate.tpcNSigmaKa(); + + // Low pT: TPC-only. TOF is ignored even if present. + if (pt < grpKaon.pSwitchPID) { + return std::abs(nTPC) < grpKaon.nsigmaCutTPCKaMeson; + } + + // High pT: TOF is mandatory. + if (!candidate.hasTOF()) { + return false; + } + + if (candidate.beta() <= grpKaon.cutTOFBetaKaMeson) { + return false; + } + + const float nTOF = candidate.tofNSigmaKa(); + const float nCombined = std::sqrt(nTPC * nTPC + nTOF * nTOF); + + return nCombined < grpKaon.nsigmaCutTOFKaMeson; + } + + template + bool selectionPID4(const T& candidate) + { + const float pt = candidate.pt(); + const float nTPC = candidate.tpcNSigmaKa(); + + // Low pT: TPC-only. TOF is ignored even if present. + if (pt < grpKaon.pSwitchPID) { + return std::abs(nTPC) < grpKaon.nsigmaCutTPCKaMeson; + } + + // High pT: TOF is mandatory. + if (!candidate.hasTOF()) { + return false; + } + + if (candidate.beta() <= grpKaon.cutTOFBetaKaMeson) { + return false; + } + + const float nTOF = candidate.tofNSigmaKa(); + + return std::abs(nTPC) < grpKaon.nsigmaCutTPCKaMeson && + std::abs(nTOF) < grpKaon.nsigmaCutTOFKaMeson; + } + + template + bool selectionPID5(const T& candidate) + { + // This matches the TOF-only selection from the other task. + if (!candidate.hasTOF()) { + return false; + } + + if (candidate.beta() <= grpKaon.cutTOFBetaKaMeson) { + return false; + } + + return std::abs(candidate.tofNSigmaKa()) < + grpKaon.nsigmaCutTOFKaMeson; + } + + template + bool selectionPID6(const T& candidate) + { + const float p = candidate.p(); + const float nTPC = candidate.tpcNSigmaKa(); + + // This follows selectionPIDpTdependent2 from the other task. + // Note: it uses total momentum p, not transverse momentum pT. + if (p < grpKaon.pSwitchAsymPID) { + return std::abs(nTPC) < grpKaon.nsigmaCutTPCKaMeson; + } + + if (!candidate.hasTOF()) { + return false; + } + + if (std::abs(nTPC) >= grpKaon.nsigmaCutTPCKaMeson) { + return false; + } + + if (candidate.beta() <= grpKaon.cutTOFBetaKaMeson) { + return false; + } + + const float nTOF = candidate.tofNSigmaKa(); + + if (p < 1.6f) { + return nTOF > -5.0f && nTOF < 10.0f; + } + + if (p < 2.0f) { + return nTOF > -3.0f && nTOF < 10.0f; + } + + if (p < 2.5f) { + return nTOF > -3.0f && nTOF < 6.0f; + } + + if (p < 4.0f) { + return nTOF > -2.5f && nTOF < 4.0f; + } + + if (p < 5.0f) { + return nTOF > -4.0f && nTOF < 3.0f; + } + + if (p < 6.0f) { + return nTOF > -4.0f && nTOF < 2.5f; + } + + return nTOF > -3.0f && nTOF < 3.0f; + } + + template + bool selectionPID7(const T& candidate) + { + const float p = candidate.p(); + const float nTPC = candidate.tpcNSigmaKa(); + + // This follows selectionPID22 from the other task. + // If TOF is disabled, use only the TPC kaon selection. + if (!grpKaon.applyTOFAsymPID) { + return std::abs(nTPC) < grpKaon.nsigmaCutTPCKaMeson; + } + + // No TOF hit: allow TPC-only PID at all momenta. + if (!candidate.hasTOF()) { + return std::abs(nTPC) < grpKaon.nsigmaCutTPCKaMeson; + } + + // For tracks with TOF, asymmetric TOF selection starts above p = 0.5. + if (p <= 0.5f) { + return false; + } + + if (std::abs(nTPC) >= grpKaon.nsigmaCutTPCKaMeson) { + return false; + } + + if (candidate.beta() <= grpKaon.cutTOFBetaKaMeson) { + return false; + } + + const float nTOF = candidate.tofNSigmaKa(); + + if (p < 1.6f) { + return nTOF > -5.0f && nTOF < 10.0f; + } + + if (p < 2.0f) { + return nTOF > -3.0f && nTOF < 10.0f; + } + + if (p < 2.5f) { + return nTOF > -3.0f && nTOF < 6.0f; + } + + if (p < 4.0f) { + return nTOF > -2.5f && nTOF < 4.0f; + } + + if (p < 5.0f) { + return nTOF > -4.0f && nTOF < 3.0f; + } + + if (p < 6.0f) { + return nTOF > -4.0f && nTOF < 2.5f; + } + + return nTOF > -3.0f && nTOF < 3.0f; + } + + template + uint8_t kaonPidMask(const T& track) + { + uint8_t mask = 0; + + if (selectionPID(track)) { + mask |= kPID1; + } + + if (selectionPID2(track)) { + mask |= kPID2; + } + + if (selectionPID3(track)) { + mask |= kPID3; + } + + if (selectionPID4(track)) { + mask |= kPID4; + } + + if (selectionPID5(track)) { + mask |= kPID5; + } + + if (selectionPID6(track)) { + mask |= kPID6; + } + + if (selectionPID7(track)) { + mask |= kPID7; + } + + return mask; + } + + struct StoredKaon { + float px; + float py; + float pz; + int8_t charge; + int64_t trackId; + uint8_t pidMask; + }; + + Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; + Filter centralityFilter = (aod::cent::centFT0C < cfgCutCentralityMax && aod::cent::centFT0C > cfgCutCentralityMin); + Filter acceptanceFilter = (nabs(aod::track::eta) < cfgCutEta && (aod::track::pt) > cfgCutPt); + Filter DCAcutFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + Filter PIDcutFilter = nabs(aod::pidtpc::tpcNSigmaKa) < nsigmaCutTPC; + + using EventCandidates = soa::Filtered>; + using AllTrackCandidates = soa::Filtered>; + SliceCache cache; + Partition posTracks = aod::track::signed1Pt > cfgCutCharge; + Partition negTracks = aod::track::signed1Pt < cfgCutCharge; + + void processData(EventCandidates::iterator const& collision, + AllTrackCandidates const& /*tracks*/) + { + o2::aod::ITSResponse itsResponse; + + const auto centrality = collision.centFT0C(); + const auto vz = collision.posZ(); + const int occupancy = collision.trackOccupancyInTimeRange(); + + histos.fill(HIST("hEvtSelInfo"), 0.5); + + if (!collision.triggereventsp()) { + return; + } + + histos.fill(HIST("hEvtSelInfo"), 1.5); + + if ((rctCut.requireRCTFlagChecker && !rctChecker(collision)) || + !collision.selection_bit(aod::evsel::kNoSameBunchPileup) || + !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || + (useNoCollInTimeRangeStandard && + !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) || + !collision.sel8() || + (useGoodITSLayersAll && + !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) || + occupancy >= cfgCutOccupancy) { + return; + } + + histos.fill(HIST("hEvtSelInfo"), 2.5); + + histos.fill(HIST("hCent"), centrality); + + std::vector selectedKaons; + + // Same slicing pattern that worked in your old producer. + auto posThisColl = posTracks->sliceByCached( + aod::track::collisionId, + collision.globalIndex(), + cache); + + auto negThisColl = negTracks->sliceByCached( + aod::track::collisionId, + collision.globalIndex(), + cache); + + // ---------------- Positive kaons ---------------- + for (const auto& track1 : posThisColl) { + histos.fill(HIST("hTrkSelInfo"), 0.5); + + if (!selectionTrack(track1)) { + continue; + } + + histos.fill(HIST("hTrkSelInfo"), 1.5); + + const float nSigmaITS1 = + itsResponse.nSigmaITS(track1); + + if (grpKaon.itsPIDSelection && track1.p() < 1.0 && + (nSigmaITS1 <= grpKaon.lowITSPIDNsigma || + nSigmaITS1 >= grpKaon.highITSPIDNsigma)) { + continue; + } + + histos.fill(HIST("hTrkSelInfo"), 2.5); + + const uint8_t mask1 = kaonPidMask(track1); + + if (grpKaon.usePID && mask1 == 0) { + continue; + } + + histos.fill(HIST("hTrkSelInfo"), 3.5); + + selectedKaons.push_back({track1.px(), + track1.py(), + track1.pz(), + +1, + track1.globalIndex(), + mask1}); + } + + // ---------------- Negative kaons ---------------- + for (const auto& track2 : negThisColl) { + histos.fill(HIST("hTrkSelInfo"), 4.5); + + if (!selectionTrack(track2)) { + continue; + } + + histos.fill(HIST("hTrkSelInfo"), 5.5); + + const float nSigmaITS2 = + itsResponse.nSigmaITS(track2); + + if (grpKaon.itsPIDSelection && track2.p() < 1.0 && + (nSigmaITS2 <= grpKaon.lowITSPIDNsigma || + nSigmaITS2 >= grpKaon.highITSPIDNsigma)) { + continue; + } + + histos.fill(HIST("hTrkSelInfo"), 6.5); + + const uint8_t mask2 = kaonPidMask(track2); + + if (grpKaon.usePID && mask2 == 0) { + continue; + } + + histos.fill(HIST("hTrkSelInfo"), 7.5); + + selectedKaons.push_back({track2.px(), + track2.py(), + track2.pz(), + -1, + track2.globalIndex(), + mask2}); + } + + // No selected K+ or K- in this collision: + // not writing a reduced event row. + histos.fill(HIST("hEvtSelInfo"), 3.5); + /* + if (selectedKaons.empty()) { + return; + } + */ + histos.fill(HIST("hEvtSelInfo"), 4.5); + + kaonEvent(centrality, + vz, + collision.qxZDCA(), + collision.qxZDCC(), + collision.qyZDCA(), + collision.qyZDCC()); + + const int64_t indexEvent = kaonEvent.lastIndex(); + + // One table row per selected kaon. + for (const auto& kaon : selectedKaons) { + kaonTrack(indexEvent, + kaon.px, + kaon.py, + kaon.pz, + kaon.charge, + kaon.trackId, + kaon.pidMask); + } + } + PROCESS_SWITCH(phiflow, processData, "Process data", true); +}; +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/TableProducer/Strangeness/Converters/stradautrackstofpidconverter3.cxx b/PWGLF/TableProducer/Strangeness/Converters/stradautrackstofpidconverter3.cxx index d2956ef6d9a..0a5a09ba7c7 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/stradautrackstofpidconverter3.cxx +++ b/PWGLF/TableProducer/Strangeness/Converters/stradautrackstofpidconverter3.cxx @@ -19,6 +19,7 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" #include +#include #include #include diff --git a/PWGLF/TableProducer/Strangeness/Converters/straevselextrasconverter.cxx b/PWGLF/TableProducer/Strangeness/Converters/straevselextrasconverter.cxx index d182e385506..2ae89c97d84 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/straevselextrasconverter.cxx +++ b/PWGLF/TableProducer/Strangeness/Converters/straevselextrasconverter.cxx @@ -20,10 +20,11 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" -#include -#include #include +#include #include +#include +#include #include using namespace o2; diff --git a/PWGLF/TableProducer/Strangeness/Converters/straevselextrasconverter2.cxx b/PWGLF/TableProducer/Strangeness/Converters/straevselextrasconverter2.cxx index 0d06b2cd1df..b24fdae1a5a 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/straevselextrasconverter2.cxx +++ b/PWGLF/TableProducer/Strangeness/Converters/straevselextrasconverter2.cxx @@ -11,11 +11,9 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/AggregatedRunInfo.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter6.cxx b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter6.cxx index 148d892eda5..5b8c29ad1b3 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter6.cxx +++ b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter6.cxx @@ -11,11 +11,10 @@ #include "PWGLF/DataModel/LFStrangenessTables.h" -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/AggregatedRunInfo.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGLF/TableProducer/Strangeness/cascqaanalysis.cxx b/PWGLF/TableProducer/Strangeness/cascqaanalysis.cxx index c71d74f9d9e..58aac18208a 100644 --- a/PWGLF/TableProducer/Strangeness/cascqaanalysis.cxx +++ b/PWGLF/TableProducer/Strangeness/cascqaanalysis.cxx @@ -44,14 +44,11 @@ #include #include -#include -#include #include #include #include #include -#include #include #include #include @@ -85,12 +82,6 @@ struct Cascqaanalysis { kNEventTypeBins }; - static constexpr std::array, kNEventTypeBins> EventTypeBinLabels{{ - {kINEL, "INEL"}, - {kINELgt0, "INEL>0"}, - {kINELgt1, "INEL>1"}, - }}; - // Axes ConfigurableAxis ptAxis{"ptAxis", {200, 0.0f, 10.0f}, "#it{p}_{T} (GeV/#it{c})"}; ConfigurableAxis rapidityAxis{"rapidityAxis", {200, -2.0f, 2.0f}, "y"}; @@ -112,6 +103,7 @@ struct Cascqaanalysis { // Event selection criteria Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; + Configurable cutzvertexGen{"cutzvertexGen", -1.0f, "Accepted generated z-vertex range (cm); negative disables the cut"}; Configurable isVertexITSTPC{"isVertexITSTPC", 0, "Select collisions with at least one ITS-TPC track"}; Configurable isNoSameBunchPileup{"isNoSameBunchPileup", 0, "Same found-by-T0 bunch crossing rejection"}; Configurable isGoodZvtxFT0vsPV{"isGoodZvtxFT0vsPV", 0, "z of PV by tracks and z of PV from FT0 A-C time difference cut"}; @@ -213,14 +205,6 @@ struct Cascqaanalysis { o2::constants::physics::MassOmegaMinus * decayLength * invMomentum}; } - template - static void setEventTypeAxisLabels(TAxisType* axis) - { - for (const auto& [bin, label] : EventTypeBinLabels) { - axis->SetBinLabel(static_cast(bin) + 1, label); - } - } - void init(InitContext const&) { TString hCandidateCounterLabels[4] = {"All candidates", "passed topo cuts", "has associated MC particle", "associated with Xi(Omega)"}; @@ -255,17 +239,9 @@ struct Cascqaanalysis { registry.add("hNchFT0MGenEvType", "hNchFT0MGenEvType", {HistType::kTH2D, {nChargedFT0MGenAxis, eventTypeAxis}}); registry.add("hNchFV0AGenEvType", "hNchFV0AGenEvType", {HistType::kTH2D, {nChargedFV0AGenAxis, eventTypeAxis}}); registry.add("hCentFT0M_genMC", "hCentFT0M_genMC", {HistType::kTH2D, {centFT0MAxis, eventTypeAxis}}); - setEventTypeAxisLabels(registry.get(HIST("hEventTypeRecVsGen"))->GetXaxis()); - setEventTypeAxisLabels(registry.get(HIST("hEventTypeRecVsGen"))->GetYaxis()); - setEventTypeAxisLabels(registry.get(HIST("hNchFT0MNAssocMCCollisions"))->GetZaxis()); - setEventTypeAxisLabels(registry.get(HIST("hNchFT0MNAssocMCCollisionsSameType"))->GetZaxis()); - setEventTypeAxisLabels(registry.get(HIST("hNchFT0MGenEvType"))->GetYaxis()); - setEventTypeAxisLabels(registry.get(HIST("hNchFV0AGenEvType"))->GetYaxis()); - setEventTypeAxisLabels(registry.get(HIST("hCentFT0M_genMC"))->GetYaxis()); } registry.add("hCentFT0M_rec", "hCentFT0M_rec", {HistType::kTH2D, {centFT0MAxis, eventTypeAxis}}); - setEventTypeAxisLabels(registry.get(HIST("hCentFT0M_rec"))->GetYaxis()); if (candidateQA) { registry.add("hNcandidates", "hNcandidates", {HistType::kTH3D, {nCandidates, centFT0MAxis, {2, -0.5f, 1.5f}}}); @@ -279,9 +255,6 @@ struct Cascqaanalysis { registry.add("hNchFT0Mglobal", "hNchFT0Mglobal", {HistType::kTH3D, {nChargedFT0MGenAxis, multNTracksAxis, eventTypeAxis}}); registry.add("hNchFT0MPVContr", "hNchFT0MPVContr", {HistType::kTH3D, {nChargedFT0MGenAxis, multNTracksAxis, eventTypeAxis}}); registry.add("hNchFV0APVContr", "hNchFV0APVContr", {HistType::kTH3D, {nChargedFV0AGenAxis, multNTracksAxis, eventTypeAxis}}); - setEventTypeAxisLabels(registry.get(HIST("hNchFT0Mglobal"))->GetZaxis()); - setEventTypeAxisLabels(registry.get(HIST("hNchFT0MPVContr"))->GetZaxis()); - setEventTypeAxisLabels(registry.get(HIST("hNchFV0APVContr"))->GetZaxis()); } registry.add("hFT0MpvContr", "hFT0MpvContr", {HistType::kTH3D, {centFT0MAxis, multNTracksAxis, eventTypeAxis}}); registry.add("hFV0ApvContr", "hFV0ApvContr", {HistType::kTH3D, {centFV0AAxis, multNTracksAxis, eventTypeAxis}}); @@ -289,11 +262,6 @@ struct Cascqaanalysis { registry.add("hFV0AFT0M", "hFV0AFT0M", {HistType::kTH3D, {centFV0AAxis, centFT0MAxis, eventTypeAxis}}); registry.add("hFT0MFV0Asignal", "hFT0MFV0Asignal", {HistType::kTH2D, {signalFT0MAxis, signalFV0AAxis}}); registry.add("hFT0MsignalPVContr", "hFT0MsignalPVContr", {HistType::kTH3D, {signalFT0MAxis, multNTracksAxis, eventTypeAxis}}); - setEventTypeAxisLabels(registry.get(HIST("hFT0MpvContr"))->GetZaxis()); - setEventTypeAxisLabels(registry.get(HIST("hFV0ApvContr"))->GetZaxis()); - setEventTypeAxisLabels(registry.get(HIST("hFT0Mglobal"))->GetZaxis()); - setEventTypeAxisLabels(registry.get(HIST("hFV0AFT0M"))->GetZaxis()); - setEventTypeAxisLabels(registry.get(HIST("hFT0MsignalPVContr"))->GetZaxis()); } rctChecker.init(cfgEvtRCTFlagCheckerLabel, cfgEvtRCTFlagCheckerZDCCheck, cfgEvtRCTFlagCheckerLimitAcceptAsBad, requireRCTFlagChecker || applyRCTOnGen); @@ -464,7 +432,7 @@ struct Cascqaanalysis { registry.fill(HIST("hNEvents"), 8.5); } - // Z vertex selection + // z-vertex selection if (std::fabs(collision.posZ()) > cutzvertex) { return false; } @@ -711,8 +679,8 @@ struct Cascqaanalysis { // All generated collisions registry.fill(HIST("hNEventsMC"), 0.5); - // Generated with accepted z vertex - if (std::fabs(mcCollision.posZ()) > cutzvertex) { + // Generated z-vertex selection + if (cutzvertexGen >= 0.f && std::fabs(mcCollision.posZ()) > cutzvertexGen) { return; } registry.fill(HIST("hNEventsMC"), 1.5); diff --git a/PWGLF/TableProducer/Strangeness/hStrangeCorrelationFilter.cxx b/PWGLF/TableProducer/Strangeness/hStrangeCorrelationFilter.cxx index c58c707f72a..ecd50c6dd54 100644 --- a/PWGLF/TableProducer/Strangeness/hStrangeCorrelationFilter.cxx +++ b/PWGLF/TableProducer/Strangeness/hStrangeCorrelationFilter.cxx @@ -123,6 +123,8 @@ struct HStrangeCorrelationFilter { Configurable assocRequireITS{"assocRequireITS", true, "require ITS signal in assoc tracks"}; Configurable triggerMaxTPCSharedClusters{"triggerMaxTPCSharedClusters", 200, "maximum number of shared TPC clusters (inclusive)"}; Configurable triggerRequireL0{"triggerRequireL0", false, "require ITS L0 cluster for trigger"}; + Configurable requireClusterInITS{"requireClusterInITS", false, "require cluster in ITS for V0 and cascade daughter tracks"}; + Configurable minITSClustersForDaughterTracks{"minITSClustersForDaughterTracks", 1, "Minimum number of ITS clusters for V0 daughter tracks"}; // Associated pion identification Configurable pionMinBayesProb{"pionMinBayesProb", 0.95, "minimal Bayesian probability for pion ID"}; @@ -143,6 +145,7 @@ struct HStrangeCorrelationFilter { Configurable dcaPostopv{"dcaPostopv", 0.06, "DCA Pos To PV"}; Configurable dcaBaryonToPV{"dcaBaryonToPV", 0.2, "DCA of baryon daughter track To PV"}; Configurable dcaMesonToPV{"dcaMesonToPV", 0.05, "DCA of meson daughter track To PV"}; + Configurable dcaDaugToPVForK0s{"dcaDaugToPVForK0s", 0, "DCA of K0s daughter tracks To PV"}; Configurable v0RadiusMin{"v0RadiusMin", 0.5, "v0radius"}; Configurable v0RadiusMax{"v0RadiusMax", 200, "v0radius"}; @@ -764,9 +767,12 @@ struct HStrangeCorrelationFilter { continue; if (posdau.tpcNClsCrossedRows() < trackSelections.minTPCNCrossedRows) continue; + if (trackSelections.requireClusterInITS && (posdau.itsNCls() < trackSelections.minITSClustersForDaughterTracks || negdau.itsNCls() < trackSelections.minITSClustersForDaughterTracks)) + continue; + float dcaDauCutForK0s = v0Selection.dcaDaugToPVForK0s == 0 ? v0Selection.dcaMesonToPV : v0Selection.dcaDaugToPVForK0s; bool isGoodK0Short = (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < v0Selection.lifetimecutK0S && - std::abs(v0.dcapostopv()) > v0Selection.dcaMesonToPV && std::abs(v0.dcanegtopv()) > v0Selection.dcaMesonToPV && + std::abs(v0.dcapostopv()) > dcaDauCutForK0s && std::abs(v0.dcanegtopv()) > dcaDauCutForK0s && v0.qtarm() * v0Selection.armPodCut > std::abs(v0.alpha())); bool isGoodLambda = (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < v0Selection.lifetimecutLambda && std::abs(v0.dcapostopv()) > v0Selection.dcaBaryonToPV && std::abs(v0.dcanegtopv()) > v0Selection.dcaMesonToPV); @@ -890,9 +896,12 @@ struct HStrangeCorrelationFilter { continue; if (posdau.tpcNClsCrossedRows() < trackSelections.minTPCNCrossedRows) continue; + if (trackSelections.requireClusterInITS && (posdau.itsNCls() < trackSelections.minITSClustersForDaughterTracks || negdau.itsNCls() < trackSelections.minITSClustersForDaughterTracks)) + continue; + float dcaDauCutForK0s = v0Selection.dcaDaugToPVForK0s == 0 ? v0Selection.dcaMesonToPV : v0Selection.dcaDaugToPVForK0s; bool isGoodK0Short = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < v0Selection.lifetimecutK0S && - std::abs(v0.dcapostopv()) > v0Selection.dcaMesonToPV && std::abs(v0.dcanegtopv()) > v0Selection.dcaMesonToPV && + std::abs(v0.dcapostopv()) > dcaDauCutForK0s && std::abs(v0.dcanegtopv()) > dcaDauCutForK0s && v0.qtarm() * v0Selection.armPodCut > std::abs(v0.alpha()); bool isGoodLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < v0Selection.lifetimecutLambda && std::abs(v0.dcapostopv()) > v0Selection.dcaBaryonToPV && std::abs(v0.dcanegtopv()) > v0Selection.dcaMesonToPV; @@ -1035,6 +1044,8 @@ struct HStrangeCorrelationFilter { continue; if (!doPPAnalysis && !cascadeSelectedPbPb(casc, collision.posX(), collision.posY(), collision.posZ())) continue; + if (trackSelections.requireClusterInITS && (posTrackCast.itsNCls() < trackSelections.minITSClustersForDaughterTracks || negTrackCast.itsNCls() < trackSelections.minITSClustersForDaughterTracks || bachTrackCast.itsNCls() < trackSelections.minITSClustersForDaughterTracks)) + continue; bool isGoodNegCascadePbPb = std::abs(casc.dcabachtopv()) > cascSelection.dcaBachToPV && std::abs(casc.dcapostopv()) > cascSelection.cascDcaBaryonToPV && std::abs(casc.dcanegtopv()) > cascSelection.cascDcaMesonToPV; @@ -1192,6 +1203,8 @@ struct HStrangeCorrelationFilter { continue; if (!doPPAnalysis && !cascadeSelectedPbPb(casc, collision.posX(), collision.posY(), collision.posZ())) continue; + if (trackSelections.requireClusterInITS && (posTrackCast.itsNCls() < trackSelections.minITSClustersForDaughterTracks || negTrackCast.itsNCls() < trackSelections.minITSClustersForDaughterTracks || bachTrackCast.itsNCls() < trackSelections.minITSClustersForDaughterTracks)) + continue; bool isGoodNegCascadePbPb = (std::abs(casc.dcabachtopv()) > cascSelection.dcaBachToPV && std::abs(casc.dcapostopv()) > cascSelection.cascDcaBaryonToPV && std::abs(casc.dcanegtopv()) > cascSelection.cascDcaMesonToPV); bool isGoodPosCascadePbPb = (std::abs(casc.dcabachtopv()) > cascSelection.dcaBachToPV && std::abs(casc.dcapostopv()) > cascSelection.cascDcaMesonToPV && diff --git a/PWGLF/TableProducer/Strangeness/sigma0builder.cxx b/PWGLF/TableProducer/Strangeness/sigma0builder.cxx index 86bf8e6172d..6a363942d5f 100644 --- a/PWGLF/TableProducer/Strangeness/sigma0builder.cxx +++ b/PWGLF/TableProducer/Strangeness/sigma0builder.cxx @@ -9,16 +9,11 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -// This is a task that employs the standard V0 tables and attempts to combine -// two V0s into a Sigma0 -> Lambda + gamma candidate. -// *+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* -// Sigma0 builder task -// *+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* -// -// Comments, questions, complaints, suggestions? -// Please write to: -// gianni.shigeru.setoue.liveraro@cern.ch -// + +/// \file sigma0builder.cxx +/// \brief This is a task that employs the standard V0 tables and attempts to combine two V0s into a Sigma0 -> Lambda + gamma candidate. +/// \author Gianni Shigeru Setoue Liveraro +/// \author Oussama Benchikhi #include "PWGEM/PhotonMeson/Utils/MCUtilities.h" #include "PWGJE/DataModel/EMCALClusters.h" @@ -285,6 +280,7 @@ struct sigma0builder { Configurable KShortRejectPosITSafterburner{"KShortRejectPosITSafterburner", false, "reject positive track formed out of afterburner ITS tracks"}; Configurable KShortRejectNegITSafterburner{"KShortRejectNegITSafterburner", false, "reject negative track formed out of afterburner ITS tracks"}; Configurable KShortArmenterosCoefficient{"KShortArmenterosCoefficient", 0.2, "Armenteros-Podolanski coefficient to reject lambdas"}; + Configurable KShortMaxTPCNSigmas{"KShortMaxTPCNSigmas", 1e+9, "Max |TPC NSigma| (pion hypothesis) for K0S daughters"}; } kshortSelections; // KStar criteria: @@ -310,46 +306,48 @@ struct sigma0builder { Configurable mc_rapidityMax{"mc_rapidityMax", 0.5, "Max generated particle rapidity"}; } genSelections; - // Axis - // base properties - ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for analysis"}; - ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 110.0f}, "Centrality"}; - ConfigurableAxis axisNch{"axisNch", {300, 0.0f, 3000.0f}, "N_{ch}"}; - - // Invariant Mass - ConfigurableAxis axisSigmaMass{"axisSigmaMass", {500, 1.10f, 1.30f}, "M_{#Sigma^{0}} (GeV/c^{2})"}; - ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.101f, 1.131f}, "M_{#Lambda} (GeV/c^{2})"}; - ConfigurableAxis axisPhotonMass{"axisPhotonMass", {200, 0.0f, 0.3f}, "M_{#Gamma}"}; - ConfigurableAxis axisK0SMass{"axisK0SMass", {200, 0.4f, 0.6f}, "M_{K^{0}}"}; - ConfigurableAxis axisKStarMass{"axisKStarMass", {500, 0.6f, 1.6f}, "M_{K^{*}} (GeV/c^{2})"}; - - // AP plot axes - ConfigurableAxis axisAPAlpha{"axisAPAlpha", {220, -1.1f, 1.1f}, "V0 AP alpha"}; - ConfigurableAxis axisAPQt{"axisAPQt", {220, 0.0f, 0.5f}, "V0 AP alpha"}; - - // topological variable QA axes - ConfigurableAxis axisTPCrows{"axisTPCrows", {160, 0.0f, 160.0f}, "N TPC rows"}; - ConfigurableAxis axisNCls{"axisNCls", {8, -0.5, 7.5}, "NCls"}; - ConfigurableAxis axisTPCNSigma{"axisTPCNSigma", {40, -10, 10}, "TPC NSigma"}; - ConfigurableAxis axisDCAtoPV{"axisDCAtoPV", {500, 0.0f, 50.0f}, "DCA (cm)"}; - ConfigurableAxis axisXY{"axisXY", {120, -120.0f, 120.0f}, "XY axis"}; - ConfigurableAxis axisZ{"axisZ", {120, -120.0f, 120.0f}, "V0 Z position (cm)"}; - ConfigurableAxis axisDCAdau{"axisDCAdau", {50, 0.0f, 5.0f}, "DCA (cm)"}; - ConfigurableAxis axisCosPA{"axisCosPA", {200, 0.5f, 1.0f}, "Cosine of pointing angle"}; - ConfigurableAxis axisRadius{"axisRadius", {240, 0.0f, 120.0f}, "V0 radius (cm)"}; - ConfigurableAxis axisPhi{"axisPhi", {200, 0, 2 * o2::constants::math::PI}, "Phi for photons"}; - ConfigurableAxis axisPA{"axisPA", {100, 0.0f, 1}, "Pointing angle"}; - ConfigurableAxis axisRapidity{"axisRapidity", {100, -2.0f, 2.0f}, "Rapidity"}; - ConfigurableAxis axisCandSel{"axisCandSel", {15, 0.5f, +15.5f}, "Candidate Selection"}; - ConfigurableAxis axisIRBinning{"axisIRBinning", {151, -10, 1500}, "Binning for the interaction rate (kHz)"}; - ConfigurableAxis axisLifetime{"axisLifetime", {200, 0, 50}, "Lifetime"}; - - // EMCal-specifc - ConfigurableAxis axisClrDefinition{"axisClrDefinition", {51, -0.5, 50.5}, "Cluster Definition"}; - ConfigurableAxis axisClrNCells{"axisClrNCells", {25, 0.0, 25}, "N cells per cluster"}; - ConfigurableAxis axisClrEnergy{"axisClrEnergy", {400, 0.0, 10}, "Energy per cluster"}; - ConfigurableAxis axisClrTime{"axisClrTime", {300, -30.0, 30.0}, "cluster time (ns)"}; - ConfigurableAxis axisClrShape{"axisClrShape", {100, 0.0, 1.0}, "cluster shape"}; + struct : ConfigurableGroup { + // base properties + std::string prefix = "axisConfig"; // JSON group name + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for analysis"}; + ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 110.0f}, "Centrality"}; + ConfigurableAxis axisNch{"axisNch", {300, 0.0f, 3000.0f}, "N_{ch}"}; + + // Invariant Mass + ConfigurableAxis axisSigmaMass{"axisSigmaMass", {500, 1.10f, 1.30f}, "M_{#Sigma^{0}} (GeV/c^{2})"}; + ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.101f, 1.131f}, "M_{#Lambda} (GeV/c^{2})"}; + ConfigurableAxis axisPhotonMass{"axisPhotonMass", {200, 0.0f, 0.3f}, "M_{#Gamma}"}; + ConfigurableAxis axisK0SMass{"axisK0SMass", {200, 0.4f, 0.6f}, "M_{K^{0}}"}; + ConfigurableAxis axisKStarMass{"axisKStarMass", {500, 0.6f, 1.6f}, "M_{K^{*}} (GeV/c^{2})"}; + + // AP plot axes + ConfigurableAxis axisAPAlpha{"axisAPAlpha", {220, -1.1f, 1.1f}, "V0 AP alpha"}; + ConfigurableAxis axisAPQt{"axisAPQt", {220, 0.0f, 0.5f}, "V0 AP alpha"}; + + // topological variable QA axes + ConfigurableAxis axisTPCrows{"axisTPCrows", {160, 0.0f, 160.0f}, "N TPC rows"}; + ConfigurableAxis axisNCls{"axisNCls", {8, -0.5, 7.5}, "NCls"}; + ConfigurableAxis axisTPCNSigma{"axisTPCNSigma", {40, -10, 10}, "TPC NSigma"}; + ConfigurableAxis axisDCAtoPV{"axisDCAtoPV", {500, 0.0f, 50.0f}, "DCA (cm)"}; + ConfigurableAxis axisXY{"axisXY", {120, -120.0f, 120.0f}, "XY axis"}; + ConfigurableAxis axisZ{"axisZ", {120, -120.0f, 120.0f}, "V0 Z position (cm)"}; + ConfigurableAxis axisDCAdau{"axisDCAdau", {50, 0.0f, 5.0f}, "DCA (cm)"}; + ConfigurableAxis axisCosPA{"axisCosPA", {200, 0.5f, 1.0f}, "Cosine of pointing angle"}; + ConfigurableAxis axisRadius{"axisRadius", {240, 0.0f, 120.0f}, "V0 radius (cm)"}; + ConfigurableAxis axisPhi{"axisPhi", {200, 0, 2 * o2::constants::math::PI}, "Phi for photons"}; + ConfigurableAxis axisPA{"axisPA", {100, 0.0f, 1}, "Pointing angle"}; + ConfigurableAxis axisRapidity{"axisRapidity", {100, -2.0f, 2.0f}, "Rapidity"}; + ConfigurableAxis axisCandSel{"axisCandSel", {15, 0.5f, +15.5f}, "Candidate Selection"}; + ConfigurableAxis axisIRBinning{"axisIRBinning", {151, -10, 1500}, "Binning for the interaction rate (kHz)"}; + ConfigurableAxis axisLifetime{"axisLifetime", {200, 0, 50}, "Lifetime"}; + + // EMCal-specifc + ConfigurableAxis axisClrDefinition{"axisClrDefinition", {51, -0.5, 50.5}, "Cluster Definition"}; + ConfigurableAxis axisClrNCells{"axisClrNCells", {25, 0.0, 25}, "N cells per cluster"}; + ConfigurableAxis axisClrEnergy{"axisClrEnergy", {400, 0.0, 10}, "Energy per cluster"}; + ConfigurableAxis axisClrTime{"axisClrTime", {300, -30.0, 30.0}, "cluster time (ns)"}; + ConfigurableAxis axisClrShape{"axisClrShape", {100, 0.0, 1.0}, "cluster shape"}; + } axisConfig; void init(InitContext const&) { @@ -371,7 +369,7 @@ struct sigma0builder { ccdb->setCaching(true); ccdb->setFatalWhenNull(false); - histos.add("hEventCentrality", "hEventCentrality", kTH1D, {axisCentrality}); + histos.add("hEventCentrality", "hEventCentrality", kTH1D, {axisConfig.axisCentrality}); if (eventSelections.fUseEventSelection) { histos.add("hEventSelection", "hEventSelection", kTH1D, {{21, -0.5f, +20.5f}}); @@ -403,8 +401,8 @@ struct sigma0builder { if (fGetIR) { histos.add("GeneralQA/hRunNumberNegativeIR", "", kTH1D, {{1, 0., 1.}}); - histos.add("GeneralQA/hInteractionRate", "hInteractionRate", kTH1D, {axisIRBinning}); - histos.add("GeneralQA/hCentralityVsInteractionRate", "hCentralityVsInteractionRate", kTH2D, {axisCentrality, axisIRBinning}); + histos.add("GeneralQA/hInteractionRate", "hInteractionRate", kTH1D, {axisConfig.axisIRBinning}); + histos.add("GeneralQA/hCentralityVsInteractionRate", "hCentralityVsInteractionRate", kTH2D, {axisConfig.axisCentrality, axisConfig.axisIRBinning}); } } @@ -418,51 +416,51 @@ struct sigma0builder { continue; } - histos.add(histodir + "/hpT", "hpT", kTH1D, {axisPt}); + histos.add(histodir + "/hpT", "hpT", kTH1D, {axisConfig.axisPt}); histos.add(histodir + "/hV0Type", "hV0Type", kTH1D, {{8, 0.5f, 8.5f}}); - histos.add(histodir + "/hNegEta", "hNegEta", kTH1D, {axisRapidity}); - histos.add(histodir + "/hPosEta", "hPosEta", kTH1D, {axisRapidity}); - histos.add(histodir + "/hDCANegToPV", "hDCANegToPV", kTH1D, {axisDCAtoPV}); - histos.add(histodir + "/hDCAPosToPV", "hDCAPosToPV", kTH1D, {axisDCAtoPV}); - histos.add(histodir + "/hDCADau", "hnDCADau", kTH1D, {axisDCAdau}); - histos.add(histodir + "/hRadius", "hnRadius", kTH1D, {axisRadius}); - histos.add(histodir + "/hZ", "hZ", kTH1D, {axisZ}); - histos.add(histodir + "/hCosPA", "hCosPA", kTH1D, {axisCosPA}); - histos.add(histodir + "/hPhi", "hPhi", kTH1D, {axisPhi}); - histos.add(histodir + "/hPosTPCCR", "hPosTPCCR", kTH1D, {axisTPCrows}); - histos.add(histodir + "/hNegTPCCR", "hNegTPCCR", kTH1D, {axisTPCrows}); - histos.add(histodir + "/hPosITSNCls", "hPosITSNCls", kTH1D, {axisNCls}); - histos.add(histodir + "/hNegITSNCls", "hNegITSNCls", kTH1D, {axisNCls}); - histos.add(histodir + "/hPosTPCNSigmaEl", "hPosTPCNSigmaEl", kTH1D, {axisTPCNSigma}); - histos.add(histodir + "/hNegTPCNSigmaEl", "hNegTPCNSigmaEl", kTH1D, {axisTPCNSigma}); - histos.add(histodir + "/hPosTPCNSigmaPi", "hPosTPCNSigmaPi", kTH1D, {axisTPCNSigma}); - histos.add(histodir + "/hNegTPCNSigmaPi", "hNegTPCNSigmaPi", kTH1D, {axisTPCNSigma}); - histos.add(histodir + "/hPosTPCNSigmaPr", "hPosTPCNSigmaPr", kTH1D, {axisTPCNSigma}); - histos.add(histodir + "/hNegTPCNSigmaPr", "hNegTPCNSigmaPr", kTH1D, {axisTPCNSigma}); - histos.add(histodir + "/h2dArmenteros", "h2dArmenteros", kTH2D, {axisAPAlpha, axisAPQt}); - - histos.add(histodir + "/hPhotonY", "hPhotonY", kTH1D, {axisRapidity}); - histos.add(histodir + "/hPhotonMass", "hPhotonMass", kTH1D, {axisPhotonMass}); - histos.add(histodir + "/h2dMassPhotonVsK0S", "h2dMassPhotonVsK0S", kTH2D, {axisPhotonMass, axisK0SMass}); - histos.add(histodir + "/h2dMassPhotonVsLambda", "h2dMassPhotonVsLambda", kTH2D, {axisPhotonMass, axisLambdaMass}); - histos.add(histodir + "/hLambdaLifeTime", "hLambdaLifeTime", kTH1D, {axisLifetime}); - histos.add(histodir + "/hLambdaY", "hLambdaY", kTH1D, {axisRapidity}); - histos.add(histodir + "/hLambdaMass", "hLambdaMass", kTH1D, {axisLambdaMass}); - histos.add(histodir + "/hALambdaMass", "hALambdaMass", kTH1D, {axisLambdaMass}); - histos.add(histodir + "/h2dMassLambdaVsK0S", "h2dMassLambdaVsK0S", kTH2D, {axisLambdaMass, axisK0SMass}); - histos.add(histodir + "/h2dMassLambdaVsGamma", "h2dMassLambdaVsGamma", kTH2D, {axisLambdaMass, axisPhotonMass}); - histos.add(histodir + "/hKShortLifeTime", "hKShortLifeTime", kTH1D, {axisLifetime}); - histos.add(histodir + "/hKShortY", "hKShortY", kTH1D, {axisRapidity}); - histos.add(histodir + "/hKShortMass", "hKShortMass", kTH1D, {axisK0SMass}); - histos.add(histodir + "/h2dMassK0SvsLambda", "h2dMassK0SvsLambda", kTH2D, {axisK0SMass, axisLambdaMass}); - histos.add(histodir + "/h2dMassK0SVsGamma", "h2dMassK0SVsGamma", kTH2D, {axisK0SMass, axisPhotonMass}); + histos.add(histodir + "/hNegEta", "hNegEta", kTH1D, {axisConfig.axisRapidity}); + histos.add(histodir + "/hPosEta", "hPosEta", kTH1D, {axisConfig.axisRapidity}); + histos.add(histodir + "/hDCANegToPV", "hDCANegToPV", kTH1D, {axisConfig.axisDCAtoPV}); + histos.add(histodir + "/hDCAPosToPV", "hDCAPosToPV", kTH1D, {axisConfig.axisDCAtoPV}); + histos.add(histodir + "/hDCADau", "hnDCADau", kTH1D, {axisConfig.axisDCAdau}); + histos.add(histodir + "/hRadius", "hnRadius", kTH1D, {axisConfig.axisRadius}); + histos.add(histodir + "/hZ", "hZ", kTH1D, {axisConfig.axisZ}); + histos.add(histodir + "/hCosPA", "hCosPA", kTH1D, {axisConfig.axisCosPA}); + histos.add(histodir + "/hPhi", "hPhi", kTH1D, {axisConfig.axisPhi}); + histos.add(histodir + "/hPosTPCCR", "hPosTPCCR", kTH1D, {axisConfig.axisTPCrows}); + histos.add(histodir + "/hNegTPCCR", "hNegTPCCR", kTH1D, {axisConfig.axisTPCrows}); + histos.add(histodir + "/hPosITSNCls", "hPosITSNCls", kTH1D, {axisConfig.axisNCls}); + histos.add(histodir + "/hNegITSNCls", "hNegITSNCls", kTH1D, {axisConfig.axisNCls}); + histos.add(histodir + "/hPosTPCNSigmaEl", "hPosTPCNSigmaEl", kTH1D, {axisConfig.axisTPCNSigma}); + histos.add(histodir + "/hNegTPCNSigmaEl", "hNegTPCNSigmaEl", kTH1D, {axisConfig.axisTPCNSigma}); + histos.add(histodir + "/hPosTPCNSigmaPi", "hPosTPCNSigmaPi", kTH1D, {axisConfig.axisTPCNSigma}); + histos.add(histodir + "/hNegTPCNSigmaPi", "hNegTPCNSigmaPi", kTH1D, {axisConfig.axisTPCNSigma}); + histos.add(histodir + "/hPosTPCNSigmaPr", "hPosTPCNSigmaPr", kTH1D, {axisConfig.axisTPCNSigma}); + histos.add(histodir + "/hNegTPCNSigmaPr", "hNegTPCNSigmaPr", kTH1D, {axisConfig.axisTPCNSigma}); + histos.add(histodir + "/h2dArmenteros", "h2dArmenteros", kTH2D, {axisConfig.axisAPAlpha, axisConfig.axisAPQt}); + + histos.add(histodir + "/hPhotonY", "hPhotonY", kTH1D, {axisConfig.axisRapidity}); + histos.add(histodir + "/hPhotonMass", "hPhotonMass", kTH1D, {axisConfig.axisPhotonMass}); + histos.add(histodir + "/h2dMassPhotonVsK0S", "h2dMassPhotonVsK0S", kTH2D, {axisConfig.axisPhotonMass, axisConfig.axisK0SMass}); + histos.add(histodir + "/h2dMassPhotonVsLambda", "h2dMassPhotonVsLambda", kTH2D, {axisConfig.axisPhotonMass, axisConfig.axisLambdaMass}); + histos.add(histodir + "/hLambdaLifeTime", "hLambdaLifeTime", kTH1D, {axisConfig.axisLifetime}); + histos.add(histodir + "/hLambdaY", "hLambdaY", kTH1D, {axisConfig.axisRapidity}); + histos.add(histodir + "/hLambdaMass", "hLambdaMass", kTH1D, {axisConfig.axisLambdaMass}); + histos.add(histodir + "/hALambdaMass", "hALambdaMass", kTH1D, {axisConfig.axisLambdaMass}); + histos.add(histodir + "/h2dMassLambdaVsK0S", "h2dMassLambdaVsK0S", kTH2D, {axisConfig.axisLambdaMass, axisConfig.axisK0SMass}); + histos.add(histodir + "/h2dMassLambdaVsGamma", "h2dMassLambdaVsGamma", kTH2D, {axisConfig.axisLambdaMass, axisConfig.axisPhotonMass}); + histos.add(histodir + "/hKShortLifeTime", "hKShortLifeTime", kTH1D, {axisConfig.axisLifetime}); + histos.add(histodir + "/hKShortY", "hKShortY", kTH1D, {axisConfig.axisRapidity}); + histos.add(histodir + "/hKShortMass", "hKShortMass", kTH1D, {axisConfig.axisK0SMass}); + histos.add(histodir + "/h2dMassK0SvsLambda", "h2dMassK0SvsLambda", kTH2D, {axisConfig.axisK0SMass, axisConfig.axisLambdaMass}); + histos.add(histodir + "/h2dMassK0SVsGamma", "h2dMassK0SVsGamma", kTH2D, {axisConfig.axisK0SMass, axisConfig.axisPhotonMass}); if (histodir != "V0BeforeSel" && fFillV03DPositionHistos) // We dont want this for all reco v0s! - histos.add(histodir + "/h3dV0XYZ", "h3dV0XYZ", kTH3D, {axisXY, axisXY, axisZ}); + histos.add(histodir + "/h3dV0XYZ", "h3dV0XYZ", kTH3D, {axisConfig.axisXY, axisConfig.axisXY, axisConfig.axisZ}); } if (fUsePCMPhoton || doprocessPCMVsEMCalQA) { - histos.add("PhotonSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisCandSel}); + histos.add("PhotonSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisConfig.axisCandSel}); histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(1, "No Sel"); histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(2, "Mass"); histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(3, "Y"); @@ -474,11 +472,12 @@ struct sigma0builder { histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(9, "Z"); histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(10, "CosPA"); histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(11, "Phi"); - histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(12, "TPCCR"); - histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(13, "TPC NSigma"); + histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(12, "Armenteros"); + histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(13, "TPCCR"); + histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(14, "TPC NSigma"); if (doprocessPCMVsEMCalQA) { - histos.add("EMCalPhotonSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisCandSel}); + histos.add("EMCalPhotonSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisConfig.axisCandSel}); histos.get(HIST("EMCalPhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(1, "No Sel"); histos.get(HIST("EMCalPhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(2, "Definition"); histos.get(HIST("EMCalPhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(3, "MinCell"); @@ -491,16 +490,16 @@ struct sigma0builder { } else { for (const auto& histodir : DirList2) { - histos.add(histodir + "/hDefinition", "hDefinition", kTH1D, {axisClrDefinition}); - histos.add(histodir + "/h2dNCells", "h2dNCells", kTH2D, {axisPt, axisClrNCells}); - histos.add(histodir + "/h2dEnergy", "h2dEnergy", kTH2D, {axisPt, axisClrEnergy}); - histos.add(histodir + "/h2dEtaVsPhi", "h2dEtaVsPhi", kTH2D, {axisRapidity, axisPhi}); - histos.add(histodir + "/h2dTime", "h2dTime", kTH2D, {axisPt, axisClrTime}); + histos.add(histodir + "/hDefinition", "hDefinition", kTH1D, {axisConfig.axisClrDefinition}); + histos.add(histodir + "/h2dNCells", "h2dNCells", kTH2D, {axisConfig.axisPt, axisConfig.axisClrNCells}); + histos.add(histodir + "/h2dEnergy", "h2dEnergy", kTH2D, {axisConfig.axisPt, axisConfig.axisClrEnergy}); + histos.add(histodir + "/h2dEtaVsPhi", "h2dEtaVsPhi", kTH2D, {axisConfig.axisRapidity, axisConfig.axisPhi}); + histos.add(histodir + "/h2dTime", "h2dTime", kTH2D, {axisConfig.axisPt, axisConfig.axisClrTime}); histos.add(histodir + "/hExotic", "hExotic", kTH1D, {{2, -0.5f, 1.5f}}); - histos.add(histodir + "/h2dShape", "h2dShape", kTH2D, {axisPt, axisClrShape}); + histos.add(histodir + "/h2dShape", "h2dShape", kTH2D, {axisConfig.axisPt, axisConfig.axisClrShape}); } - histos.add("EMCalPhotonSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisCandSel}); + histos.add("EMCalPhotonSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisConfig.axisCandSel}); histos.get(HIST("EMCalPhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(1, "No Sel"); histos.get(HIST("EMCalPhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(2, "Definition"); histos.get(HIST("EMCalPhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(3, "MinCell"); @@ -511,7 +510,7 @@ struct sigma0builder { histos.get(HIST("EMCalPhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(8, "Shape"); } - histos.add("LambdaSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisCandSel}); + histos.add("LambdaSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisConfig.axisCandSel}); histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(1, "No Sel"); histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(2, "Mass"); histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(3, "Y"); @@ -527,7 +526,7 @@ struct sigma0builder { histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(13, "ITSNCls"); histos.get(HIST("LambdaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(14, "Lifetime"); - histos.add("KShortSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisCandSel}); + histos.add("KShortSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisConfig.axisCandSel}); histos.get(HIST("KShortSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(1, "No Sel"); histos.get(HIST("KShortSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(2, "Mass"); histos.get(HIST("KShortSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(3, "Y"); @@ -542,40 +541,42 @@ struct sigma0builder { histos.get(HIST("KShortSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(12, "TPCCR"); histos.get(HIST("KShortSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(13, "ITSNCls"); histos.get(HIST("KShortSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(14, "Lifetime"); + histos.get(HIST("KShortSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(15, "TPC NSigma"); if (doprocessRealData || doprocessRealDataWithTOF || doprocessRealDataWithEMCal || doprocessMonteCarlo || doprocessMonteCarloWithTOF || doprocessMonteCarloWithEMCal) { histos.add("SigmaSel/hSigma0DauDeltaIndex", "hSigma0DauDeltaIndex", kTH1F, {{100, -49.5f, 50.5f}}); - histos.add("SigmaSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisCandSel}); + histos.add("SigmaSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisConfig.axisCandSel}); histos.get(HIST("SigmaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(1, "No Sel"); histos.get(HIST("SigmaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(2, "Sigma Mass Window"); histos.get(HIST("SigmaSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(3, "Sigma Y Window"); - histos.add("SigmaSel/hSigmaMassBeforeSel", "hSigmaMassBeforeSel", kTH1F, {axisSigmaMass}); - histos.add("SigmaSel/hSigmaMassSelected", "hSigmaMassSelected", kTH1F, {axisSigmaMass}); + histos.add("SigmaSel/hSigmaMassBeforeSel", "hSigmaMassBeforeSel", kTH1F, {axisConfig.axisSigmaMass}); + histos.add("SigmaSel/hSigmaMassSelected", "hSigmaMassSelected", kTH1F, {axisConfig.axisSigmaMass}); - histos.add("KStarSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisCandSel}); + histos.add("KStarSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisConfig.axisCandSel}); histos.get(HIST("KStarSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(1, "No Sel"); histos.get(HIST("KStarSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(2, "KStar Mass Window"); histos.get(HIST("KStarSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(3, "KStar Y Window"); - histos.add("KStarSel/hKStarMassSelected", "hKStarMassSelected", kTH1F, {axisKStarMass}); + histos.add("KStarSel/hKStarMassSelected", "hKStarMassSelected", kTH1F, {axisConfig.axisKStarMass}); } if (doAssocStudy && (doprocessMonteCarlo || doprocessMonteCarloWithTOF)) { - histos.add("V0AssoQA/h2dIRVsPt_TrueGamma", "h2dIRVsPt_TrueGamma", kTH2F, {axisIRBinning, axisPt}); - histos.add("V0AssoQA/h3dPAVsIRVsPt_TrueGamma", "h3dPAVsIRVsPt_TrueGamma", kTH3F, {axisPA, axisIRBinning, axisPt}); - histos.add("V0AssoQA/h2dIRVsPt_TrueGamma_BadCollAssig", "h2dIRVsPt_TrueGamma_BadCollAssig", kTH2F, {axisIRBinning, axisPt}); - histos.add("V0AssoQA/h3dPAVsIRVsPt_TrueGamma_BadCollAssig", "h3dPAVsIRVsPt_TrueGamma_BadCollAssig", kTH3F, {axisPA, axisIRBinning, axisPt}); + histos.add("V0AssoQA/h2dIRVsPt_TrueGamma", "h2dIRVsPt_TrueGamma", kTH2F, {axisConfig.axisIRBinning, axisConfig.axisPt}); + histos.add("V0AssoQA/h3dPAVsIRVsPt_TrueGamma", "h3dPAVsIRVsPt_TrueGamma", kTH3F, {axisConfig.axisPA, axisConfig.axisIRBinning, axisConfig.axisPt}); + histos.add("V0AssoQA/h2dIRVsPt_TrueGamma_BadCollAssig", "h2dIRVsPt_TrueGamma_BadCollAssig", kTH2F, {axisConfig.axisIRBinning, axisConfig.axisPt}); + histos.add("V0AssoQA/h3dPAVsIRVsPt_TrueGamma_BadCollAssig", "h3dPAVsIRVsPt_TrueGamma_BadCollAssig", kTH3F, {axisConfig.axisPA, axisConfig.axisIRBinning, axisConfig.axisPt}); - histos.add("V0AssoQA/h2dIRVsPt_TrueLambda", "h2dIRVsPt_TrueLambda", kTH2F, {axisIRBinning, axisPt}); - histos.add("V0AssoQA/h3dPAVsIRVsPt_TrueLambda", "h3dPAVsIRVsPt_TrueLambda", kTH3F, {axisPA, axisIRBinning, axisPt}); - histos.add("V0AssoQA/h2dIRVsPt_TrueLambda_BadCollAssig", "h2dIRVsPt_TrueLambda_BadCollAssig", kTH2F, {axisIRBinning, axisPt}); - histos.add("V0AssoQA/h3dPAVsIRVsPt_TrueLambda_BadCollAssig", "h3dPAVsIRVsPt_TrueLambda_BadCollAssig", kTH3F, {axisPA, axisIRBinning, axisPt}); + histos.add("V0AssoQA/h2dIRVsPt_TrueLambda", "h2dIRVsPt_TrueLambda", kTH2F, {axisConfig.axisIRBinning, axisConfig.axisPt}); + histos.add("V0AssoQA/h3dPAVsIRVsPt_TrueLambda", "h3dPAVsIRVsPt_TrueLambda", kTH3F, {axisConfig.axisPA, axisConfig.axisIRBinning, axisConfig.axisPt}); + histos.add("V0AssoQA/h2dIRVsPt_TrueLambda_BadCollAssig", "h2dIRVsPt_TrueLambda_BadCollAssig", kTH2F, {axisConfig.axisIRBinning, axisConfig.axisPt}); + histos.add("V0AssoQA/h3dPAVsIRVsPt_TrueLambda_BadCollAssig", "h3dPAVsIRVsPt_TrueLambda_BadCollAssig", kTH3F, {axisConfig.axisPA, axisConfig.axisIRBinning, axisConfig.axisPt}); } // MC if (doprocessMonteCarlo || doprocessMonteCarloWithTOF || doprocessMonteCarloWithEMCal) { histos.add("MCQA/h2dPhotonNMothersVsPDG", "h2dPhotonNMothersVsPDG", kTHnSparseD, {{10, -0.5f, +9.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("MCQA/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); histos.add("MCQA/h2dPhotonNMothersVsMCProcess", "h2dPhotonNMothersVsMCProcess", kTH2D, {{10, -0.5f, +9.5f}, {50, -0.5f, 49.5f}}); histos.add("MCQA/hPhotonMotherSize", "hPhotonMotherSize", kTH1D, {{10, -0.5f, +9.5f}}); histos.add("MCQA/hPhotonMCProcess", "hPhotonMCProcess", kTH1D, {{50, -0.5f, 49.5f}}); @@ -603,33 +604,33 @@ struct sigma0builder { } if (doprocessPCMVsEMCalQA) { - histos.add("PhotonMCQA/hPCMPhotonMCpT", "hPCMPhotonMCpT", kTH1D, {axisPt}); - histos.add("PhotonMCQA/h2dPCMPhotonMCpTResolution", "h2dPCMPhotonMCpTResolution", kTH2D, {axisPt, {100, -2.0f, 2.0f}}); - histos.add("PhotonMCQA/hPCMSigma0PhotonMCpT", "hPCMSigma0PhotonMCpT", kTH1D, {axisPt}); - histos.add("PhotonMCQA/h2dPCMSigma0PhotonMCpTResolution", "h2dPCMSigma0PhotonMCpTResolution", kTH2D, {axisPt, {100, -2.0f, 2.0f}}); + histos.add("PhotonMCQA/hPCMPhotonMCpT", "hPCMPhotonMCpT", kTH1D, {axisConfig.axisPt}); + histos.add("PhotonMCQA/h2dPCMPhotonMCpTResolution", "h2dPCMPhotonMCpTResolution", kTH2D, {axisConfig.axisPt, {100, -2.0f, 2.0f}}); + histos.add("PhotonMCQA/hPCMSigma0PhotonMCpT", "hPCMSigma0PhotonMCpT", kTH1D, {axisConfig.axisPt}); + histos.add("PhotonMCQA/h2dPCMSigma0PhotonMCpTResolution", "h2dPCMSigma0PhotonMCpTResolution", kTH2D, {axisConfig.axisPt, {100, -2.0f, 2.0f}}); - histos.add("PhotonMCQA/hEMCalPhotonMCpT", "hEMCalPhotonMCpT", kTH1D, {axisPt}); - histos.add("PhotonMCQA/h2dEMCalPhotonMCpTResolution", "h2dEMCalPhotonMCpTResolution", kTH2D, {axisPt, {100, -2.0f, 2.0f}}); - histos.add("PhotonMCQA/h2dEMCalPhotonMCEnergyResolution", "h2dEMCalPhotonMCEnergyResolution", kTH2D, {axisClrEnergy, {100, -2.0f, 2.0f}}); - histos.add("PhotonMCQA/h2dEMCalPhotonMCEtaResolution", "h2dEMCalPhotonMCEtaResolution", kTH2D, {axisRapidity, {100, -2.0f, 2.0f}}); - histos.add("PhotonMCQA/h2dEMCalPhotonMCPhiResolution", "h2dEMCalPhotonMCPhiResolution", kTH2D, {axisPhi, {100, -2.0f, 2.0f}}); - histos.add("PhotonMCQA/h2dEMCalPhotonMCFractionEnergy", "h2dEMCalPhotonMCFractionEnergy", kTH2D, {axisPt, {100, -1.0f, 1.0f}}); + histos.add("PhotonMCQA/hEMCalPhotonMCpT", "hEMCalPhotonMCpT", kTH1D, {axisConfig.axisPt}); + histos.add("PhotonMCQA/h2dEMCalPhotonMCpTResolution", "h2dEMCalPhotonMCpTResolution", kTH2D, {axisConfig.axisPt, {100, -2.0f, 2.0f}}); + histos.add("PhotonMCQA/h2dEMCalPhotonMCEnergyResolution", "h2dEMCalPhotonMCEnergyResolution", kTH2D, {axisConfig.axisClrEnergy, {100, -2.0f, 2.0f}}); + histos.add("PhotonMCQA/h2dEMCalPhotonMCEtaResolution", "h2dEMCalPhotonMCEtaResolution", kTH2D, {axisConfig.axisRapidity, {100, -2.0f, 2.0f}}); + histos.add("PhotonMCQA/h2dEMCalPhotonMCPhiResolution", "h2dEMCalPhotonMCPhiResolution", kTH2D, {axisConfig.axisPhi, {100, -2.0f, 2.0f}}); + histos.add("PhotonMCQA/h2dEMCalPhotonMCFractionEnergy", "h2dEMCalPhotonMCFractionEnergy", kTH2D, {axisConfig.axisPt, {100, -1.0f, 1.0f}}); - histos.add("PhotonMCQA/hEMCalSigma0PhotonMCpT", "hEMCalSigma0PhotonMCpT", kTH1D, {axisPt}); - histos.add("PhotonMCQA/h2dEMCalSigma0PhotonMCpTResolution", "h2dEMCalSigma0PhotonMCpTResolution", kTH2D, {axisPt, {100, -2.0f, 2.0f}}); - histos.add("PhotonMCQA/h2dEMCalSigma0PhotonMCEnergyResolution", "h2dEMCalSigma0PhotonMCEnergyResolution", kTH2D, {axisClrEnergy, {100, -2.0f, 2.0f}}); - histos.add("PhotonMCQA/h2dEMCalSigma0PhotonMCEtaResolution", "h2dEMCalSigma0PhotonMCEtaResolution", kTH2D, {axisRapidity, {100, -2.0f, 2.0f}}); - histos.add("PhotonMCQA/h2dEMCalSigma0PhotonMCPhiResolution", "h2dEMCalSigma0PhotonMCPhiResolution", kTH2D, {axisPhi, {100, -2.0f, 2.0f}}); - histos.add("PhotonMCQA/h2dEMCalSigma0PhotonMCFractionEnergy", "h2dEMCalSigma0PhotonMCFractionEnergy", kTH2D, {axisPt, {100, -1.0f, 1.0f}}); + histos.add("PhotonMCQA/hEMCalSigma0PhotonMCpT", "hEMCalSigma0PhotonMCpT", kTH1D, {axisConfig.axisPt}); + histos.add("PhotonMCQA/h2dEMCalSigma0PhotonMCpTResolution", "h2dEMCalSigma0PhotonMCpTResolution", kTH2D, {axisConfig.axisPt, {100, -2.0f, 2.0f}}); + histos.add("PhotonMCQA/h2dEMCalSigma0PhotonMCEnergyResolution", "h2dEMCalSigma0PhotonMCEnergyResolution", kTH2D, {axisConfig.axisClrEnergy, {100, -2.0f, 2.0f}}); + histos.add("PhotonMCQA/h2dEMCalSigma0PhotonMCEtaResolution", "h2dEMCalSigma0PhotonMCEtaResolution", kTH2D, {axisConfig.axisRapidity, {100, -2.0f, 2.0f}}); + histos.add("PhotonMCQA/h2dEMCalSigma0PhotonMCPhiResolution", "h2dEMCalSigma0PhotonMCPhiResolution", kTH2D, {axisConfig.axisPhi, {100, -2.0f, 2.0f}}); + histos.add("PhotonMCQA/h2dEMCalSigma0PhotonMCFractionEnergy", "h2dEMCalSigma0PhotonMCFractionEnergy", kTH2D, {axisConfig.axisPt, {100, -1.0f, 1.0f}}); - histos.add("PhotonMCQA/hGenPhoton", "hGenPhoton", kTH1D, {axisPt}); - histos.add("PhotonMCQA/hGenSigma0Photon", "hGenSigma0Photon", kTH1D, {axisPt}); + histos.add("PhotonMCQA/hGenPhoton", "hGenPhoton", kTH1D, {axisConfig.axisPt}); + histos.add("PhotonMCQA/hGenSigma0Photon", "hGenSigma0Photon", kTH1D, {axisConfig.axisPt}); } if (doprocessGeneratedRun3 && genSelections.doQA) { // Pi0s - histos.add("GenQA/hGenPi0", "hGenPi0", kTH1D, {axisPt}); + histos.add("GenQA/hGenPi0", "hGenPi0", kTH1D, {axisConfig.axisPt}); auto hPrimaryPi0s = histos.add("GenQA/hPrimaryPi0s", "hPrimaryPi0s", kTH1D, {{2, -0.5f, 1.5f}}); hPrimaryPi0s->GetXaxis()->SetBinLabel(1, "All Pi0s"); @@ -646,16 +647,16 @@ struct sigma0builder { // ______________________________________________________ // Sigma0s - histos.add("GenQA/hGenSigma0", "hGenSigma0", kTH1D, {axisPt}); - histos.add("GenQA/hGenAntiSigma0", "hGenAntiSigma0", kTH1D, {axisPt}); + histos.add("GenQA/hGenSigma0", "hGenSigma0", kTH1D, {axisConfig.axisPt}); + histos.add("GenQA/hGenAntiSigma0", "hGenAntiSigma0", kTH1D, {axisConfig.axisPt}); - histos.add("GenQA/h3dGenSigma0_pTMap", "h3dGenSigma0_pTMap", kTH3D, {axisPt, axisPt, axisPt}); - histos.add("GenQA/h3dGenASigma0_pTMap", "h3dGenASigma0_pTMap", kTH3D, {axisPt, axisPt, axisPt}); + histos.add("GenQA/h3dGenSigma0_pTMap", "h3dGenSigma0_pTMap", kTH3D, {axisConfig.axisPt, axisConfig.axisPt, axisConfig.axisPt}); + histos.add("GenQA/h3dGenASigma0_pTMap", "h3dGenASigma0_pTMap", kTH3D, {axisConfig.axisPt, axisConfig.axisPt, axisConfig.axisPt}); - histos.add("GenQA/h2dGenSigma0xy_Generator", "hGenSigma0xy_Generator", kTH2D, {axisXY, axisXY}); - histos.add("GenQA/h2dGenSigma0xy_Transport", "hGenSigma0xy_Transport", kTH2D, {axisXY, axisXY}); - histos.add("GenQA/hGenSigma0Radius_Generator", "hGenSigma0Radius_Generator", kTH1D, {axisRadius}); - histos.add("GenQA/hGenSigma0Radius_Transport", "hGenSigma0Radius_Transport", kTH1D, {axisRadius}); + histos.add("GenQA/h2dGenSigma0xy_Generator", "hGenSigma0xy_Generator", kTH2D, {axisConfig.axisXY, axisConfig.axisXY}); + histos.add("GenQA/h2dGenSigma0xy_Transport", "hGenSigma0xy_Transport", kTH2D, {axisConfig.axisXY, axisConfig.axisXY}); + histos.add("GenQA/hGenSigma0Radius_Generator", "hGenSigma0Radius_Generator", kTH1D, {axisConfig.axisRadius}); + histos.add("GenQA/hGenSigma0Radius_Transport", "hGenSigma0Radius_Transport", kTH1D, {axisConfig.axisRadius}); histos.add("GenQA/h2dSigma0MCSourceVsPDGMother", "h2dSigma0MCSourceVsPDGMother", kTHnSparseD, {{2, -0.5f, 1.5f}, {10001, -5000.5f, +5000.5f}}); histos.add("GenQA/h2dSigma0NDaughtersVsPDG", "h2dSigma0NDaughtersVsPDG", kTHnSparseD, {{10, -0.5f, +9.5f}, {10001, -5000.5f, +5000.5f}}); @@ -681,12 +682,12 @@ struct sigma0builder { // ______________________________________________________ // KStar - histos.add("GenQA/hGenKStar", "hGenKStar", kTH1D, {axisPt}); + histos.add("GenQA/hGenKStar", "hGenKStar", kTH1D, {axisConfig.axisPt}); - histos.add("GenQA/h2dGenKStarxy_Generator", "hGenKStarxy_Generator", kTH2D, {axisXY, axisXY}); - histos.add("GenQA/h2dGenKStarxy_Transport", "hGenKStarxy_Transport", kTH2D, {axisXY, axisXY}); - histos.add("GenQA/hGenKStarRadius_Generator", "hGenKStarRadius_Generator", kTH1D, {axisRadius}); - histos.add("GenQA/hGenKStarRadius_Transport", "hGenKStarRadius_Transport", kTH1D, {axisRadius}); + histos.add("GenQA/h2dGenKStarxy_Generator", "hGenKStarxy_Generator", kTH2D, {axisConfig.axisXY, axisConfig.axisXY}); + histos.add("GenQA/h2dGenKStarxy_Transport", "hGenKStarxy_Transport", kTH2D, {axisConfig.axisXY, axisConfig.axisXY}); + histos.add("GenQA/hGenKStarRadius_Generator", "hGenKStarRadius_Generator", kTH1D, {axisConfig.axisRadius}); + histos.add("GenQA/hGenKStarRadius_Transport", "hGenKStarRadius_Transport", kTH1D, {axisConfig.axisRadius}); histos.add("GenQA/h2dKStarMCSourceVsPDGMother", "h2dKStarMCSourceVsPDGMother", kTHnSparseD, {{2, -0.5f, 1.5f}, {10001, -5000.5f, +5000.5f}}); histos.add("GenQA/h2dKStarNDaughtersVsPDG", "h2dKStarNDaughtersVsPDG", kTHnSparseD, {{10, -0.5f, +9.5f}, {10001, -5000.5f, +5000.5f}}); @@ -712,72 +713,72 @@ struct sigma0builder { if (doprocessV0QA || doprocessV0MCQA) { // Event selection: - histos.add("V0QA/hEventCentrality", "hEventCentrality", kTH1D, {axisCentrality}); + histos.add("V0QA/hEventCentrality", "hEventCentrality", kTH1D, {axisConfig.axisCentrality}); // Photon part: - histos.add("V0QA/h3dPhotonMass", "h3dPhotonMass", kTH3D, {axisCentrality, axisPt, axisPhotonMass}); - histos.add("V0QA/h3dYPhotonMass", "h3dYPhotonMass", kTH3D, {axisRapidity, axisPt, axisPhotonMass}); - histos.add("V0QA/h3dYPhotonRadius", "h3dYPhotonRadius", kTH3D, {axisRapidity, axisPt, axisRadius}); + histos.add("V0QA/h3dPhotonMass", "h3dPhotonMass", kTH3D, {axisConfig.axisCentrality, axisConfig.axisPt, axisConfig.axisPhotonMass}); + histos.add("V0QA/h3dYPhotonMass", "h3dYPhotonMass", kTH3D, {axisConfig.axisRapidity, axisConfig.axisPt, axisConfig.axisPhotonMass}); + histos.add("V0QA/h3dYPhotonRadius", "h3dYPhotonRadius", kTH3D, {axisConfig.axisRapidity, axisConfig.axisPt, axisConfig.axisRadius}); - histos.add("V0QA/h3dTruePhotonMass", "h3dTruePhotonMass", kTH3D, {axisCentrality, axisPt, axisPhotonMass}); - histos.add("V0QA/h2dTrueSigma0PhotonMass", "h2dTrueSigma0PhotonMass", kTH2D, {axisPt, axisPhotonMass}); - histos.add("V0QA/h2dTrueKStarPhotonMass", "h2dTrueKStarPhotonMass", kTH2D, {axisPt, axisPhotonMass}); + histos.add("V0QA/h3dTruePhotonMass", "h3dTruePhotonMass", kTH3D, {axisConfig.axisCentrality, axisConfig.axisPt, axisConfig.axisPhotonMass}); + histos.add("V0QA/h2dTrueSigma0PhotonMass", "h2dTrueSigma0PhotonMass", kTH2D, {axisConfig.axisPt, axisConfig.axisPhotonMass}); + histos.add("V0QA/h2dTrueKStarPhotonMass", "h2dTrueKStarPhotonMass", kTH2D, {axisConfig.axisPt, axisConfig.axisPhotonMass}); // Lambda part: - histos.add("V0QA/h3dLambdaMass", "h3dLambdaMass", kTH3D, {axisCentrality, axisPt, axisLambdaMass}); - histos.add("V0QA/h3dTrueLambdaMass", "h3dTrueLambdaMass", kTH3D, {axisCentrality, axisPt, axisLambdaMass}); - histos.add("V0QA/h3dYLambdaMass", "h3dYLambdaMass", kTH3D, {axisRapidity, axisPt, axisLambdaMass}); - histos.add("V0QA/h3dYRLambdaMass", "h3dYRLambdaMass", kTH3D, {axisRapidity, axisRadius, axisLambdaMass}); + histos.add("V0QA/h3dLambdaMass", "h3dLambdaMass", kTH3D, {axisConfig.axisCentrality, axisConfig.axisPt, axisConfig.axisLambdaMass}); + histos.add("V0QA/h3dTrueLambdaMass", "h3dTrueLambdaMass", kTH3D, {axisConfig.axisCentrality, axisConfig.axisPt, axisConfig.axisLambdaMass}); + histos.add("V0QA/h3dYLambdaMass", "h3dYLambdaMass", kTH3D, {axisConfig.axisRapidity, axisConfig.axisPt, axisConfig.axisLambdaMass}); + histos.add("V0QA/h3dYRLambdaMass", "h3dYRLambdaMass", kTH3D, {axisConfig.axisRapidity, axisConfig.axisRadius, axisConfig.axisLambdaMass}); - histos.add("V0QA/h2dTrueSigma0LambdaMass", "h2dTrueSigma0LambdaMass", kTH2D, {axisPt, axisLambdaMass}); + histos.add("V0QA/h2dTrueSigma0LambdaMass", "h2dTrueSigma0LambdaMass", kTH2D, {axisConfig.axisPt, axisConfig.axisLambdaMass}); // AntiLambda part: - histos.add("V0QA/h3dALambdaMass", "h3dALambdaMass", kTH3D, {axisCentrality, axisPt, axisLambdaMass}); - histos.add("V0QA/h3dTrueALambdaMass", "h3dTrueALambdaMass", kTH3D, {axisCentrality, axisPt, axisLambdaMass}); - histos.add("V0QA/h3dYALambdaMass", "h3dYALambdaMass", kTH3D, {axisRapidity, axisPt, axisLambdaMass}); - histos.add("V0QA/h3dYRALambdaMass", "h3dYRALambdaMass", kTH3D, {axisRapidity, axisRadius, axisLambdaMass}); + histos.add("V0QA/h3dALambdaMass", "h3dALambdaMass", kTH3D, {axisConfig.axisCentrality, axisConfig.axisPt, axisConfig.axisLambdaMass}); + histos.add("V0QA/h3dTrueALambdaMass", "h3dTrueALambdaMass", kTH3D, {axisConfig.axisCentrality, axisConfig.axisPt, axisConfig.axisLambdaMass}); + histos.add("V0QA/h3dYALambdaMass", "h3dYALambdaMass", kTH3D, {axisConfig.axisRapidity, axisConfig.axisPt, axisConfig.axisLambdaMass}); + histos.add("V0QA/h3dYRALambdaMass", "h3dYRALambdaMass", kTH3D, {axisConfig.axisRapidity, axisConfig.axisRadius, axisConfig.axisLambdaMass}); - histos.add("V0QA/h2dTrueASigma0ALambdaMass", "h2dTrueASigma0ALambdaMass", kTH2D, {axisPt, axisLambdaMass}); + histos.add("V0QA/h2dTrueASigma0ALambdaMass", "h2dTrueASigma0ALambdaMass", kTH2D, {axisConfig.axisPt, axisConfig.axisLambdaMass}); // KShort part: - histos.add("V0QA/h3dKShortMass", "h3dKShortMass", kTH3D, {axisCentrality, axisPt, axisK0SMass}); - histos.add("V0QA/h3dTrueKShortMass", "h3dTrueKShortMass", kTH3D, {axisCentrality, axisPt, axisK0SMass}); - histos.add("V0QA/h3dYKShortMass", "h3dYKShortMass", kTH3D, {axisRapidity, axisPt, axisK0SMass}); - histos.add("V0QA/h3dYRKShortMass", "h3dYRKShortMass", kTH3D, {axisRapidity, axisRadius, axisK0SMass}); - histos.add("V0QA/h2dTrueKStarKShortMass", "h2dTrueKStarKShortMass", kTH2D, {axisPt, axisK0SMass}); + histos.add("V0QA/h3dKShortMass", "h3dKShortMass", kTH3D, {axisConfig.axisCentrality, axisConfig.axisPt, axisConfig.axisK0SMass}); + histos.add("V0QA/h3dTrueKShortMass", "h3dTrueKShortMass", kTH3D, {axisConfig.axisCentrality, axisConfig.axisPt, axisConfig.axisK0SMass}); + histos.add("V0QA/h3dYKShortMass", "h3dYKShortMass", kTH3D, {axisConfig.axisRapidity, axisConfig.axisPt, axisConfig.axisK0SMass}); + histos.add("V0QA/h3dYRKShortMass", "h3dYRKShortMass", kTH3D, {axisConfig.axisRapidity, axisConfig.axisRadius, axisConfig.axisK0SMass}); + histos.add("V0QA/h2dTrueKStarKShortMass", "h2dTrueKStarKShortMass", kTH2D, {axisConfig.axisPt, axisConfig.axisK0SMass}); } if (doprocessV0Generated) { - histos.add("V0QA/hGenEvents", "hGenEvents", kTH2D, {{axisNch}, {2, -0.5f, +1.5f}}); + histos.add("V0QA/hGenEvents", "hGenEvents", kTH2D, {{axisConfig.axisNch}, {2, -0.5f, +1.5f}}); histos.get(HIST("V0QA/hGenEvents"))->GetYaxis()->SetBinLabel(1, "All gen. events"); histos.get(HIST("V0QA/hGenEvents"))->GetYaxis()->SetBinLabel(2, "Gen. with at least 1 rec. events"); histos.add("V0QA/hGenEventCentrality", "hGenEventCentrality", kTH1D, {{101, 0.0f, 101.0f}}); - histos.add("V0QA/hCentralityVsNcoll_beforeEvSel", "hCentralityVsNcoll_beforeEvSel", kTH2D, {axisCentrality, {50, -0.5f, 49.5f}}); - histos.add("V0QA/hCentralityVsNcoll_afterEvSel", "hCentralityVsNcoll_afterEvSel", kTH2D, {axisCentrality, {50, -0.5f, 49.5f}}); + histos.add("V0QA/hCentralityVsNcoll_beforeEvSel", "hCentralityVsNcoll_beforeEvSel", kTH2D, {axisConfig.axisCentrality, {50, -0.5f, 49.5f}}); + histos.add("V0QA/hCentralityVsNcoll_afterEvSel", "hCentralityVsNcoll_afterEvSel", kTH2D, {axisConfig.axisCentrality, {50, -0.5f, 49.5f}}); - histos.add("V0QA/hCentralityVsMultMC", "hCentralityVsMultMC", kTH2D, {{101, 0.0f, 101.0f}, axisNch}); + histos.add("V0QA/hCentralityVsMultMC", "hCentralityVsMultMC", kTH2D, {{101, 0.0f, 101.0f}, axisConfig.axisNch}); histos.add("V0QA/hEventPVzMC", "hEventPVzMC", kTH1D, {{100, -20.0f, +20.0f}}); histos.add("V0QA/hCentralityVsPVzMC", "hCentralityVsPVzMC", kTH2D, {{101, 0.0f, 101.0f}, {100, -20.0f, +20.0f}}); - histos.add("V0QA/h2dGenPhoton", "h2dGenPhoton", kTH2D, {axisCentrality, axisPt}); - histos.add("V0QA/h2dGenLambda", "h2dGenLambda", kTH2D, {axisCentrality, axisPt}); - histos.add("V0QA/h2dGenAntiLambda", "h2dGenAntiLambda", kTH2D, {axisCentrality, axisPt}); + histos.add("V0QA/h2dGenPhoton", "h2dGenPhoton", kTH2D, {axisConfig.axisCentrality, axisConfig.axisPt}); + histos.add("V0QA/h2dGenLambda", "h2dGenLambda", kTH2D, {axisConfig.axisCentrality, axisConfig.axisPt}); + histos.add("V0QA/h2dGenAntiLambda", "h2dGenAntiLambda", kTH2D, {axisConfig.axisCentrality, axisConfig.axisPt}); - histos.add("V0QA/h2dGenPhotonVsMultMC_RecoedEvt", "h2dGenPhotonVsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); - histos.add("V0QA/h2dGenLambdaVsMultMC_RecoedEvt", "h2dGenLambdaVsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); - histos.add("V0QA/h2dGenAntiLambdaVsMultMC_RecoedEvt", "h2dGenAntiLambdaVsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); + histos.add("V0QA/h2dGenPhotonVsMultMC_RecoedEvt", "h2dGenPhotonVsMultMC_RecoedEvt", kTH2D, {axisConfig.axisNch, axisConfig.axisPt}); + histos.add("V0QA/h2dGenLambdaVsMultMC_RecoedEvt", "h2dGenLambdaVsMultMC_RecoedEvt", kTH2D, {axisConfig.axisNch, axisConfig.axisPt}); + histos.add("V0QA/h2dGenAntiLambdaVsMultMC_RecoedEvt", "h2dGenAntiLambdaVsMultMC_RecoedEvt", kTH2D, {axisConfig.axisNch, axisConfig.axisPt}); - histos.add("V0QA/h2dGenPhotonVsMultMC", "h2dGenPhotonVsMultMC", kTH2D, {axisNch, axisPt}); - histos.add("V0QA/h2dGenLambdaVsMultMC", "h2dGenLambdaVsMultMC", kTH2D, {axisNch, axisPt}); - histos.add("V0QA/h2dGenAntiLambdaVsMultMC", "h2dGenAntiLambdaVsMultMC", kTH2D, {axisNch, axisPt}); + histos.add("V0QA/h2dGenPhotonVsMultMC", "h2dGenPhotonVsMultMC", kTH2D, {axisConfig.axisNch, axisConfig.axisPt}); + histos.add("V0QA/h2dGenLambdaVsMultMC", "h2dGenLambdaVsMultMC", kTH2D, {axisConfig.axisNch, axisConfig.axisPt}); + histos.add("V0QA/h2dGenAntiLambdaVsMultMC", "h2dGenAntiLambdaVsMultMC", kTH2D, {axisConfig.axisNch, axisConfig.axisPt}); - histos.add("V0QA/h2dGenKShort", "h2dGenKShort", kTH2D, {axisCentrality, axisPt}); + histos.add("V0QA/h2dGenKShort", "h2dGenKShort", kTH2D, {axisConfig.axisCentrality, axisConfig.axisPt}); - histos.add("V0QA/h2dGenKShortVsMultMC_RecoedEvt", "h2dGenKShortVsMultMC_RecoedEvt", kTH2D, {axisNch, axisPt}); + histos.add("V0QA/h2dGenKShortVsMultMC_RecoedEvt", "h2dGenKShortVsMultMC_RecoedEvt", kTH2D, {axisConfig.axisNch, axisConfig.axisPt}); - histos.add("V0QA/h2dGenKShortVsMultMC", "h2dGenKShortVsMultMC", kTH2D, {axisNch, axisPt}); + histos.add("V0QA/h2dGenKShortVsMultMC", "h2dGenKShortVsMultMC", kTH2D, {axisConfig.axisNch, axisConfig.axisPt}); } // inspect histogram sizes, please @@ -810,6 +811,10 @@ struct sigma0builder { int V02PDGCode = 0; int V01PDGCodeMother = 0; int V02PDGCodeMother = 0; + int V01PDGCodeGrandMother = 0; + int V02PDGCodeGrandMother = 0; + int V01GlobalIndexGrandMother = 0; + int V02GlobalIndexGrandMother = 0; int V0PairPDGCode = 0; int V0PairPDGCodeMother = 0; int V0PairMCProcess = -1; @@ -955,6 +960,46 @@ struct sigma0builder { auto const& MCMother_v01 = MCMothersList_v01.front(); // First mother auto const& MCMother_v02 = MCMothersList_v02.front(); // First mother + // Add the grandmothers + auto const& GrandMothersList_v01 = MCMother_v01.template mothers_as(); + if (!GrandMothersList_v01.empty()) { + MCinfo.V01PDGCodeGrandMother = GrandMothersList_v01.front().pdgCode(); + MCinfo.V01GlobalIndexGrandMother = GrandMothersList_v01.front().globalIndex(); + } + + auto const& GrandMothersList_v02 = MCMother_v02.template mothers_as(); + if (!GrandMothersList_v02.empty()) { + MCinfo.V02PDGCodeGrandMother = GrandMothersList_v02.front().pdgCode(); + MCinfo.V02GlobalIndexGrandMother = GrandMothersList_v02.front().globalIndex(); + } + + // check grandmothers and fill histograms + int kShortMotherCode = 0; + int photonMotherCode = 0; + if ((std::abs(MCParticle_v01.pdgCode()) == PDG_t::kGamma) && (std::abs(MCParticle_v02.pdgCode()) == PDG_t::kK0Short) && (!fIsKStar)) { + + kShortMotherCode = MCMother_v02.pdgCode(); + + // If the KShort mother is a (anti)Kaon, use the grandmother instead + if (std::abs(kShortMotherCode) == PDG_t::kK0) { + auto const& kShortGrandMothers = MCMother_v02.template mothers_as(); + if (!kShortGrandMothers.empty()) { + kShortMotherCode = kShortGrandMothers.front().pdgCode(); + } + } + + photonMotherCode = MCMother_v01.pdgCode(); + // If the photon mother is a pi0, climb to grandmother + if (std::abs(photonMotherCode) == PDG_t::kPi0) { + auto const& photonGrandMothers = MCMother_v01.template mothers_as(); + if (!photonGrandMothers.empty()) { + photonMotherCode = photonGrandMothers.front().pdgCode(); + } + } + + histos.fill(HIST("MCQA/h2dTrueDaughtersMatrix"), kShortMotherCode, photonMotherCode); + } + if (MCMother_v01.globalIndex() == MCMother_v02.globalIndex()) { // Is it the same mother? MCinfo.fV0PairProducedByGenerator = MCMother_v01.producedByGenerator(); @@ -1329,13 +1374,11 @@ struct sigma0builder { if (eventSelections.maxIR >= 0 && interactionRate > eventSelections.maxIR) { return false; } - if (fillHists) + if (fillHists) { histos.fill(HIST("hEventSelection"), 19 /* Above max IR */); - - // Fill centrality histogram after event selection - if (fillHists) + // Fill centrality histogram after event selection histos.fill(HIST("hEventCentrality"), centrality); - + } return true; } @@ -1466,7 +1509,7 @@ struct sigma0builder { else if (std::abs(v0MC.pdgCode()) == PDG_t::kLambda0) ymc = v0MC.rapidityMC(1); else if (v0MC.pdgCode() == PDG_t::kK0Short) - ymc = v0MC.rapidityMC(2); // what is the 2 here? + ymc = v0MC.rapidityMC(0); // 0 = K0 mass hypothesis (1/2 = Lambda); see LFStrangenessTables.h:829 if ((ymc < genSelections.mc_rapidityMin) || (ymc > genSelections.mc_rapidityMax)) continue; @@ -2202,6 +2245,11 @@ struct sigma0builder { return false; histos.fill(HIST("KShortSel/hSelectionStatistics"), 14.); + if (((TMath::Abs(posTrackKShort.tpcNSigmaPi()) > kshortSelections.KShortMaxTPCNSigmas) || + (TMath::Abs(negTrackKShort.tpcNSigmaPi()) > kshortSelections.KShortMaxTPCNSigmas))) + return false; + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 15.); } return true; } @@ -2555,9 +2603,9 @@ struct sigma0builder { kstarmccores(kstarMCInfo.V0PairMCRadius, kstarMCInfo.V0PairPDGCode, kstarMCInfo.V0PairPDGCodeMother, kstarMCInfo.V0PairMCProcess, kstarMCInfo.fV0PairProducedByGenerator, kstarMCInfo.V01MCpx, kstarMCInfo.V01MCpy, kstarMCInfo.V01MCpz, - kstarMCInfo.fIsV01Primary, kstarMCInfo.V01PDGCode, kstarMCInfo.V01PDGCodeMother, kstarMCInfo.fIsV01CorrectlyAssign, + kstarMCInfo.fIsV01Primary, kstarMCInfo.V01PDGCode, kstarMCInfo.V01PDGCodeMother, kstarMCInfo.V01PDGCodeGrandMother, kstarMCInfo.V01GlobalIndexGrandMother, kstarMCInfo.fIsV01CorrectlyAssign, kstarMCInfo.V02MCpx, kstarMCInfo.V02MCpy, kstarMCInfo.V02MCpz, - kstarMCInfo.fIsV02Primary, kstarMCInfo.V02PDGCode, kstarMCInfo.V02PDGCodeMother, kstarMCInfo.fIsV02CorrectlyAssign); + kstarMCInfo.fIsV02Primary, kstarMCInfo.V02PDGCode, kstarMCInfo.V02PDGCodeMother, kstarMCInfo.V02PDGCodeGrandMother, kstarMCInfo.V02GlobalIndexGrandMother, kstarMCInfo.fIsV02CorrectlyAssign); } // KStar -> stracollisions link @@ -2759,9 +2807,9 @@ struct sigma0builder { } } - //_______________________________________________ - // KStar loop if constexpr (!soa::is_table) { // Don't use EMCal clusters here + //_______________________________________________ + // KStar loop if (fillKStarTables) { auto gamma1 = fullV0s.rawIteratorAt(bestGammasArray[i]); for (size_t j = 0; j < bestKShortsArray.size(); ++j) { @@ -2772,11 +2820,9 @@ struct sigma0builder { continue; } } - } - //_______________________________________________ - // pi0 loop - if constexpr (!soa::is_table) { // Don't use EMCal clusters here + //_______________________________________________ + // pi0 loop if (fillPi0Tables) { auto gamma1 = fullV0s.rawIteratorAt(bestGammasArray[i]); for (size_t j = i + 1; j < bestGammasArray.size(); ++j) { diff --git a/PWGLF/TableProducer/Strangeness/sigmaminustask.cxx b/PWGLF/TableProducer/Strangeness/sigmaminustask.cxx index 828ef0240cd..cd4c6f690c3 100644 --- a/PWGLF/TableProducer/Strangeness/sigmaminustask.cxx +++ b/PWGLF/TableProducer/Strangeness/sigmaminustask.cxx @@ -35,20 +35,20 @@ #include #include #include +#include #include #include #include #include -#include - #include #include #include #include #include #include +#include #include #include #include diff --git a/PWGLF/TableProducer/Strangeness/strangenesstofpid.cxx b/PWGLF/TableProducer/Strangeness/strangenesstofpid.cxx index 2ef71417749..e34227a8b70 100644 --- a/PWGLF/TableProducer/Strangeness/strangenesstofpid.cxx +++ b/PWGLF/TableProducer/Strangeness/strangenesstofpid.cxx @@ -49,7 +49,10 @@ #include #include #include +#include #include +#include +#include #include #include @@ -58,14 +61,11 @@ #include #include -#include - #include #include #include #include -#include -#include +#include #include #include #include @@ -1705,7 +1705,7 @@ struct strangenesstofpid { collisionEventTime[collision.globalIndex()] /= static_cast(collisionNtracks[collision.globalIndex()]); collisionEventTimeErr[collision.globalIndex()] /= static_cast(collisionNtracks[collision.globalIndex()]); } else { - collisionEventTime[collision.globalIndex()] = -1e+6; // undefined + collisionEventTime[collision.globalIndex()] = -1e+6; // undefined collisionEventTimeErr[collision.globalIndex()] = -1e+6; // undefined } histos.fill(HIST("hCollisionTimes"), collisionEventTime[collision.globalIndex()]); diff --git a/PWGLF/TableProducer/Strangeness/v0qaanalysis.cxx b/PWGLF/TableProducer/Strangeness/v0qaanalysis.cxx index 771b2ab4a18..269bb4a5098 100644 --- a/PWGLF/TableProducer/Strangeness/v0qaanalysis.cxx +++ b/PWGLF/TableProducer/Strangeness/v0qaanalysis.cxx @@ -20,6 +20,7 @@ #include "PWGLF/Utils/inelGt.h" #include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/RCTSelectionFlags.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -43,12 +44,14 @@ #include +#include #include #include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::aod::rctsel; void customize(std::vector& workflowOptions) { @@ -61,6 +64,7 @@ void customize(std::vector& workflowOptions) using DauTracks = soa::Join; using DauTracksMC = soa::Join; using V0Collisions = soa::Join; +using BCsWithBcSels = soa::Join; struct LfV0qaanalysis { @@ -106,10 +110,12 @@ struct LfV0qaanalysis { registry.add("hCentFT0M_GenRecoColl_MC_INELgt0", "hCentFT0M_GenRecoColl_MC_INELgt0", {HistType::kTH1F, {{1000, 0.f, 100.f}}}); registry.add("hCentFT0M_GenColl_MC", "hCentFT0M_GenColl_MC", {HistType::kTH1F, {{1000, 0.f, 100.f}}}); registry.add("hCentFT0M_GenColl_MC_INELgt0", "hCentFT0M_GenColl_MC_INELgt0", {HistType::kTH1F, {{1000, 0.f, 100.f}}}); - registry.add("hNEventsMCGen", "hNEventsMCGen", {HistType::kTH1D, {{4, 0.f, 4.f}}}); + registry.add("hNEventsMCGen", "hNEventsMCGen", {HistType::kTH1D, {{5, 0.f, 5.f}}}); registry.get(HIST("hNEventsMCGen"))->GetXaxis()->SetBinLabel(1, "all"); registry.get(HIST("hNEventsMCGen"))->GetXaxis()->SetBinLabel(2, "zvertex_true"); - registry.get(HIST("hNEventsMCGen"))->GetXaxis()->SetBinLabel(3, "INELgt0_true"); + registry.get(HIST("hNEventsMCGen"))->GetXaxis()->SetBinLabel(3, "BC TF/ITS ROF border"); + registry.get(HIST("hNEventsMCGen"))->GetXaxis()->SetBinLabel(4, "RCTFlagsChecker"); + registry.get(HIST("hNEventsMCGen"))->GetXaxis()->SetBinLabel(5, "INELgt0_true"); registry.add("hNEventsMCGenReco", "hNEventsMCGenReco", {HistType::kTH1D, {{2, 0.f, 2.f}}}); registry.get(HIST("hNEventsMCGenReco"))->GetXaxis()->SetBinLabel(1, "INEL"); registry.get(HIST("hNEventsMCGenReco"))->GetXaxis()->SetBinLabel(2, "INELgt0"); @@ -153,6 +159,7 @@ struct LfV0qaanalysis { registry.add("Generated_MCGenColl_INELgt0_Lambda", "Generated_MCGenColl_INELgt0_Lambda", {HistType::kTH2F, {{250, 0.f, 25.f}, {1000, 0.f, 100.f}}}); registry.add("Generated_MCGenColl_INELgt0_AntiLambda", "Generated_MCGenColl_INELgt0_AntiLambda", {HistType::kTH2F, {{250, 0.f, 25.f}, {1000, 0.f, 100.f}}}); } + rctChecker.init(cfgEvtRCTFlagCheckerLabel, cfgEvtRCTFlagCheckerZDCCheck, cfgEvtRCTFlagCheckerLimitAcceptAsBad, applyRCTOnGen); registry.print(); } @@ -164,11 +171,18 @@ struct LfV0qaanalysis { Configurable isTriggerTVX{"isTriggerTVX", 1, "Is Trigger TVX"}; Configurable isNoTimeFrameBorder{"isNoTimeFrameBorder", 1, "Is No Time Frame Border"}; Configurable isNoITSROFrameBorder{"isNoITSROFrameBorder", 1, "Is No ITS Readout Frame Border"}; + Configurable applyBcBorderCutsOnGen{"applyBcBorderCutsOnGen", false, "Apply enabled BC-level TF and ITS ROF border cuts on generated-level MC collisions"}; + Configurable applyRCTOnGen{"applyRCTOnGen", false, "Apply enabled BC-level RCT run-condition selection on generated-level MC collisions"}; Configurable isVertexTOFmatched{"isVertexTOFmatched", 0, "Is Vertex TOF matched"}; Configurable isNoSameBunchPileup{"isNoSameBunchPileup", 0, "isNoSameBunchPileup"}; + Configurable cfgEvtRCTFlagCheckerLabel{"cfgEvtRCTFlagCheckerLabel", "CBT_hadronPID", "Evt sel: RCT flag checker label"}; + Configurable cfgEvtRCTFlagCheckerZDCCheck{"cfgEvtRCTFlagCheckerZDCCheck", false, "Evt sel: RCT flag checker ZDC check"}; + Configurable cfgEvtRCTFlagCheckerLimitAcceptAsBad{"cfgEvtRCTFlagCheckerLimitAcceptAsBad", false, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; Configurable v0TypeSelection{"v0TypeSelection", 1, "select on a certain V0 type (leave negative if no selection desired)"}; Configurable NotITSAfterburner{"NotITSAfterburner", 0, "NotITSAfterburner"}; + RCTFlagsChecker rctChecker; + // V0 selection criteria Configurable v0cospa{"v0cospa", 0.97, "V0 CosPA"}; Configurable dcav0dau{"dcav0dau", 10, "DCA V0 Daughters"}; @@ -214,6 +228,27 @@ struct LfV0qaanalysis { return true; } + template + bool acceptGeneratedEventBcBorderCuts(TBC const& bc) + { + if (!applyBcBorderCutsOnGen) { + return true; + } + if (isNoTimeFrameBorder && !bc.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + return false; + } + if (isNoITSROFrameBorder && !bc.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + return false; + } + return true; + } + + template + bool acceptGeneratedEventRCT(TBC const& bc) + { + return !applyRCTOnGen || rctChecker(bc); + } + Filter preFilterV0 = nabs(aod::v0data::dcapostopv) > dcapostopv&& nabs(aod::v0data::dcanegtopv) > dcanegtopv&& aod::v0data::dcaV0daughters < dcav0dau; @@ -230,7 +265,7 @@ struct LfV0qaanalysis { registry.fill(HIST("hCentFT0M"), collision.centFT0M()); registry.fill(HIST("hCentNGlobals"), collision.centNGlobal()); - for (auto& v0 : V0s) { // loop over V0s + for (const auto& v0 : V0s) { // loop over V0s if (v0.v0Type() != v0TypeSelection) { continue; @@ -323,7 +358,7 @@ struct LfV0qaanalysis { } auto v0sThisCollision = V0s.sliceBy(perCol, collision.globalIndex()); - for (auto& v0 : v0sThisCollision) { // loop over V0s + for (const auto& v0 : v0sThisCollision) { // loop over V0s if (!v0.has_mcParticle()) { continue; @@ -371,8 +406,8 @@ struct LfV0qaanalysis { lPDG = v0mcparticle.pdgCode(); isprimary = v0mcparticle.isPhysicalPrimary(); } - for (auto& mcparticleDaughter0 : v0mcparticle.daughters_as()) { - for (auto& mcparticleDaughter1 : v0mcparticle.daughters_as()) { + for (const auto& mcparticleDaughter0 : v0mcparticle.daughters_as()) { + for (const auto& mcparticleDaughter1 : v0mcparticle.daughters_as()) { if (mcparticleDaughter0.pdgCode() == 211 && mcparticleDaughter1.pdgCode() == -211) { isDauK0Short = true; } @@ -389,7 +424,7 @@ struct LfV0qaanalysis { float pdgMother = 0.; if (std::abs(v0mcparticle.pdgCode()) == 3122 && v0mcparticle.has_mothers()) { - for (auto& mcparticleMother0 : v0mcparticle.mothers_as()) { + for (const auto& mcparticleMother0 : v0mcparticle.mothers_as()) { if (std::abs(mcparticleMother0.pdgCode()) == 3312 || std::abs(mcparticleMother0.pdgCode()) == 3322) { ptMotherMC = mcparticleMother0.pt(); pdgMother = mcparticleMother0.pdgCode(); @@ -435,7 +470,7 @@ struct LfV0qaanalysis { // Generated particles const auto particlesInCollision = mcParticles.sliceByCached(aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), cache1); - for (auto& mcParticle : particlesInCollision) { + for (const auto& mcParticle : particlesInCollision) { if (!mcParticle.isPhysicalPrimary()) { continue; } @@ -469,7 +504,8 @@ struct LfV0qaanalysis { void processMCGen(soa::Join::iterator const& mcCollision, aod::McParticles const& mcParticles, - soa::SmallGroups> const& collisions) + soa::SmallGroups> const& collisions, + BCsWithBcSels const&) { //==================================== //===== Event Loss Denominator ======= @@ -481,13 +517,22 @@ struct LfV0qaanalysis { return; } registry.fill(HIST("hNEventsMCGen"), 1.5); + const auto bc = mcCollision.bc_as(); + if (!acceptGeneratedEventBcBorderCuts(bc)) { + return; + } + registry.fill(HIST("hNEventsMCGen"), 2.5); + if (!acceptGeneratedEventRCT(bc)) { + return; + } + registry.fill(HIST("hNEventsMCGen"), 3.5); registry.fill(HIST("hCentFT0M_GenColl_MC"), mcCollision.centFT0M()); bool isINELgt0true = false; if (pwglf::isINELgtNmc(mcParticles, 0, pdgDB)) { isINELgt0true = true; - registry.fill(HIST("hNEventsMCGen"), 2.5); + registry.fill(HIST("hNEventsMCGen"), 4.5); registry.fill(HIST("hCentFT0M_GenColl_MC_INELgt0"), mcCollision.centFT0M()); } @@ -495,7 +540,7 @@ struct LfV0qaanalysis { //===== Signal Loss Denominator ======= //===================================== - for (auto& mcParticle : mcParticles) { + for (const auto& mcParticle : mcParticles) { if (!mcParticle.isPhysicalPrimary()) { continue; @@ -526,7 +571,7 @@ struct LfV0qaanalysis { int recoCollIndex_INEL = 0; int recoCollIndex_INELgt0 = 0; - for (auto& collision : collisions) { // loop on reconstructed collisions + for (const auto& collision : collisions) { // loop on reconstructed collisions //===================================== //====== Event Split Numerator ======== @@ -553,7 +598,7 @@ struct LfV0qaanalysis { //======== Sgn Split Numerator ======== //===================================== - for (auto& mcParticle : mcParticles) { + for (const auto& mcParticle : mcParticles) { if (!mcParticle.isPhysicalPrimary()) { continue; @@ -605,7 +650,7 @@ struct LfV0qaanalysis { //===== Signal Loss Numerator ========= //===================================== - for (auto& mcParticle : mcParticles) { + for (const auto& mcParticle : mcParticles) { if (!mcParticle.isPhysicalPrimary()) { continue; @@ -682,7 +727,7 @@ struct LfMyV0s { void process(aod::MyV0Candidates const& myv0s) { - for (auto& candidate : myv0s) { + for (const auto& candidate : myv0s) { registry.fill(HIST("hMassLambda"), candidate.masslambda()); registry.fill(HIST("hPt"), candidate.v0pt()); diff --git a/PWGLF/Tasks/GlobalEventProperties/PseudorapidityDensityMFT.cxx b/PWGLF/Tasks/GlobalEventProperties/PseudorapidityDensityMFT.cxx index ed76d333570..27e11cebe8b 100644 --- a/PWGLF/Tasks/GlobalEventProperties/PseudorapidityDensityMFT.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/PseudorapidityDensityMFT.cxx @@ -400,7 +400,8 @@ struct PseudorapidityDensityMFT { Configurable useTriggerTVX{"useTriggerTVX", true, "Require kIsTriggerTVX in processGenReco"}; Configurable useNoTimeFrameBorderCut{"useNoTimeFrameBorderCut", true, "Require kNoTimeFrameBorder in processGenReco"}; Configurable useNoITSROFrameBorderCut{"useNoITSROFrameBorderCut", true, "Require kNoITSROFrameBorder in processGenReco"}; - + AxisSpec multAxisRecoMFT = {multBinning, "N_{ch}^{reco,MFT}"}; + AxisSpec multAxisGenMFT = {multBinning, "N_{ch}^{gen,MFT}"}; HistogramRegistry registry{ "registry", { @@ -630,6 +631,22 @@ struct PseudorapidityDensityMFT { registry.add({"Purity/reco/PNchMFT_afterCuts", ";N_{trk}^{MFT} (selected);events", {HistType::kTH1F, {multAxis}}}); + // MC P(Nch) objects for MFT multiplicity unfolding/correction. + // Generator multiplicity: primary charged particles in the MFT acceptance, + // with generated INEL>0 defined from the central estimator. + // Reco multiplicity: selected reassociated MFT tracks for matched accepted reco events. + registry.add({"PNchMC/gen_inelgt0", + ";N_{ch}^{gen,MFT};events", + {HistType::kTH1F, {multAxisGenMFT}}}); + + registry.add({"PNchMC/reco_sel8_inelgt0", + ";N_{ch}^{reco,MFT};events", + {HistType::kTH1F, {multAxisRecoMFT}}}); + + registry.add({"PNchMC/responseMatrix", + ";N_{ch}^{reco,MFT};N_{ch}^{gen,MFT};events", + {HistType::kTH2F, {multAxisRecoMFT, multAxisGenMFT}}}); + registry.add({"Purity/DCAyVsDCAx_Right", ";DCA_{x} (cm);DCA_{y} (cm)", {HistType::kTH2F, {dcaXAxis, dcaYAxis}}}); @@ -1214,6 +1231,27 @@ struct PseudorapidityDensityMFT { " ; N_{Trk}^{nonamb}", {HistType::kTH1F, {{701, -0.5, 700.5}}}}); // + // Event-level P(Nch) distributions for reassociated MFT tracks. + // Fill once per collision after counting selected reassociated MFT tracks. + registry.add({"PNch/MFT_sel8", + ";N_{ch}^{MFT};events", + {HistType::kTH1F, {multAxis}}}); + registry.add({"PNch/MFT_sel8_inelgt0", + ";N_{ch}^{MFT};events", + {HistType::kTH1F, {multAxis}}}); + registry.add({"PNch/MFT_sel8_inelfwdgt0", + ";N_{ch}^{MFT};events", + {HistType::kTH1F, {multAxis}}}); + registry.add({"PNch/MFT_sel8_inelgt0_nonamb", + ";N_{ch}^{MFT, nonamb};events", + {HistType::kTH1F, {multAxis}}}); + registry.add({"PNch/MFT_sel8_inelgt0_amb", + ";N_{ch}^{MFT, amb};events", + {HistType::kTH1F, {multAxis}}}); + registry.add({"PNch/MFTZvtx_sel8_inelgt0", + ";N_{ch}^{MFT};#it{z}_{vtx} (cm);events", + {HistType::kTH2F, {multAxis, zAxis}}}); + registry.add({"Tracks/Control/amb/AmbTracksPhiEta", "; #varphi; #eta; tracks", {HistType::kTH2F, {phiAxis, etaBinning}}}); // @@ -1542,6 +1580,10 @@ struct PseudorapidityDensityMFT { std::unordered_set eventsInelMFT; std::unordered_set eventsInel; + int64_t nMFTSelected{0}; + int64_t nMFTSelectedAmb{0}; + int64_t nMFTSelectedNonAmb{0}; + const auto fillDataCut = [&](DataCutBin bin) { registry.fill(HIST("EventSelectionData"), static_cast(bin)); }; @@ -1655,6 +1697,13 @@ struct PseudorapidityDensityMFT { if (failTrackCuts) { continue; } + ++nMFTSelected; + if (retrack.ambDegree() > SingleCompatibleCollision) { + ++nMFTSelectedAmb; + } else if (retrack.ambDegree() == SingleCompatibleCollision) { + ++nMFTSelectedNonAmb; + } + registry.fill(HIST("Tracks/Control/TrackAmbDegree"), retrack.ambDegree()); registry.fill(HIST("Tracks/Control/DCAXY"), retrack.bestDCAXY()); @@ -1771,6 +1820,17 @@ struct PseudorapidityDensityMFT { registry.fill(HIST("Tracks/Control/nonamb/nTrkNonAmb"), j); registry.fill(HIST("Tracks/Control/woOrp/nTrk"), k); registry.fill(HIST("hNumCollisions_Inel"), 1, eventsInel.size()); + + registry.fill(HIST("PNch/MFT_sel8"), nMFTSelected); + if (midtracks.size() > 0) { + registry.fill(HIST("PNch/MFT_sel8_inelgt0"), nMFTSelected); + registry.fill(HIST("PNch/MFTZvtx_sel8_inelgt0"), nMFTSelected, z); + registry.fill(HIST("PNch/MFT_sel8_inelgt0_nonamb"), nMFTSelectedNonAmb); + registry.fill(HIST("PNch/MFT_sel8_inelgt0_amb"), nMFTSelectedAmb); + if (nMFTSelected > 0) { + registry.fill(HIST("PNch/MFT_sel8_inelfwdgt0"), nMFTSelected); + } + } } void processMultReassoc(CollwEv::iterator const& collision, @@ -2413,6 +2473,7 @@ struct PseudorapidityDensityMFT { bool onlyVzGt0 = false; // EtaZvtxGen_gt0t bool atLeastOneSel8Vz = false; // EtaZvtxGen bool atLeastOneSel8VzGt0 = false; // EtaZvtxGen_gt0 + bool hasRecoCollisionForPNch{false}; const auto fillGenRecoCut = [&](GenRecoCutBin bin) { registry.fill(HIST("EventsRecoCuts_GenReco"), static_cast(bin)); @@ -2567,6 +2628,7 @@ struct PseudorapidityDensityMFT { acceptedRecoCols.insert(recoCol); recoCollisionIds.insert(recoCol); trueMCCollisionIds.insert(mcCol); + hasRecoCollisionForPNch = true; if (mcCol >= 0) { recoToMc[recoCol] = mcCol; @@ -2603,7 +2665,9 @@ struct PseudorapidityDensityMFT { int64_t woOrpCount = 0; bool filledRight = false; bool filledWrong = false; - int nMftSelectedAfterCuts = 0; + int64_t nMftSelectedAfterCuts{0}; + int64_t nRecoMFTSelectedForPNch{0}; + int64_t nGenPrimaryChargedMFT{0}; std::unordered_set uniqueBestRecoCols; if (tracks.size() > 0) { @@ -2689,6 +2753,11 @@ struct PseudorapidityDensityMFT { failDCAzCut = useDCAzCut && (std::abs(dcaZCut) > maxDCAz); // std::cout <<" dcaZReco " <= cfgVzCut1) && (mcCollision.posZ() <= cfgVzCut2)) { + if (nChargedCentral > 0) { + + registry.fill(HIST("PNchMC/gen_inelgt0"), + nGenPrimaryChargedMFT); + + if (hasRecoCollisionForPNch) { + registry.fill(HIST("PNchMC/reco_sel8_inelgt0"), + nRecoMFTSelectedForPNch); + + registry.fill(HIST("PNchMC/responseMatrix"), + nRecoMFTSelectedForPNch, + nGenPrimaryChargedMFT); + } } } } diff --git a/PWGLF/Tasks/GlobalEventProperties/flattenictyPikp.cxx b/PWGLF/Tasks/GlobalEventProperties/flattenictyPikp.cxx index 10a72a46eaf..5bfd8ff0712 100644 --- a/PWGLF/Tasks/GlobalEventProperties/flattenictyPikp.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/flattenictyPikp.cxx @@ -63,12 +63,12 @@ #include +#include + #include #include -#include #include #include -#include #include #include #include @@ -94,7 +94,7 @@ static constexpr float Cone = 1.0f; static constexpr int CmaxRingsFV0 = 5; static constexpr int CnCellsFV0 = 48; static constexpr int CinnerFV0 = 32; -static constexpr float Cfv0IndexPhi[5] = {0., 8., 16., 24., 32.}; +const std::array cFV0IndexPhi{0, 8, 16, 24, 32}; static constexpr float CmaxEtaFV0 = 5.1; static constexpr float CminEtaFV0 = 2.2; static constexpr float CdEtaFV0 = (CmaxEtaFV0 - CminEtaFV0) / CmaxRingsFV0; @@ -102,30 +102,34 @@ auto static constexpr CminAccFT0A = 3.5f; auto static constexpr CmaxAccFT0A = 4.9f; auto static constexpr CminAccFT0C = -3.3f; auto static constexpr CmaxAccFT0C = -2.1f; + // PID names static constexpr int CprocessIdWeak = 4; static constexpr int Ncharges = 2; static constexpr o2::track::PID::ID Npart = 5; static constexpr o2::track::PID::ID NpartChrg = Npart * Ncharges; -static constexpr int PDGs[] = {11, 13, 211, 321, 2212}; -static constexpr int PidSgn[NpartChrg] = {11, 13, 211, 321, 2212, -11, -13, -211, -321, -2212}; -static constexpr const char* Pid[Npart] = {"el", "mu", "pi", "ka", "pr"}; -static constexpr const char* PidChrg[NpartChrg] = {"e^{-}", "#mu^{-}", "#pi^{+}", "K^{+}", "p", "e^{+}", "#mu^{+}", "#pi^{-}", "K^{-}", "#bar{p}"}; -static constexpr std::string_view CspeciesAll[Npart] = {"El", "Mu", "Pi", "Ka", "Pr"}; +const std::array pDGs{11, 13, 211, 321, 2212}; +const std::array pIdSgn{11, 13, 211, 321, 2212, -11, -13, -211, -321, -2212}; +const std::array pID{"el", "mu", "pi", "ka", "pr"}; +const std::array pIdChrg{"e^{-}", "#mu^{-}", "#pi^{+}", "K^{+}", "p", "e^{+}", "#mu^{+}", "#pi^{-}", "K^{-}", "#bar{p}"}; +static constexpr std::array CspeciesAll{"El", "Mu", "Pi", "Ka", "Pr"}; + // histogram naming -static constexpr std::string_view PidDir[] = {"el/", "pi/", "pr/"}; -static constexpr std::string_view V0Dir[] = {"Ga/", "K0s/", "La/", "ALa/"}; -static constexpr std::string_view Ccharge[] = {"all/", "pos/", "neg/"}; +static constexpr std::array PidDir{"el/", "pi/", "pr/"}; +static constexpr std::array V0Dir{"Ga/", "K0s/", "La/", "ALa/"}; +static constexpr std::array Ccharge{"all/", "pos/", "neg/"}; static constexpr std::string_view Cprefix = "Tracks/"; static constexpr std::string_view CprefixCleanTof = "Tracks/CleanTof/"; static constexpr std::string_view CprefixCleanV0 = "Tracks/CleanV0/"; static constexpr std::string_view CprefixV0qa = "Tracks/V0qa/"; -static constexpr std::string_view Cstatus[] = {"preSel/", "postSel/"}; -static constexpr std::string_view CstatCalib[] = {"preCalib/", "postCalib/"}; +static constexpr std::array Cstatus{"preSel/", "postSel/"}; +static constexpr std::array CstatCalib{"preCalib/", "postCalib/"}; static constexpr std::string_view CdEdxMcRecPrim = "/hdEdxMcRecPrim"; static constexpr std::string_view CdEdxMcRecPrimF = "Tracks/{}/hdEdxMcRecPrim"; static constexpr std::string_view CdEdxMcRecPrimSel = "/hdEdxMcRecPrimSel"; static constexpr std::string_view CdEdxMcRecPrimSelF = "Tracks/{}/hdEdxMcRecPrimSel"; +static constexpr std::string_view CEtaVsPtVsPMcRecPrimSel = "/hEtaVsPtVsPMcRecPrimSel"; +static constexpr std::string_view CEtaVsPtVsPMcRecPrimSelF = "Tracks/{}/hEtaVsPtVsPMcRecPrimSel"; static constexpr std::string_view CpTvsDCAxy = "/hPtVsDCAxy"; static constexpr std::string_view CpTvsDCAxyF = "Tracks/{}/hPtVsDCAxy"; static constexpr std::string_view CpTvsDCAxyAll = "/hPtVsDCAxyAll"; @@ -219,31 +223,6 @@ struct MultE { static constexpr int CmultTPC = 2; }; -std::array rhoLatticeFV0{0}; -std::array fv0AmplitudeWoCalib{0}; -std::array, NpartChrg> hPtGenRecEvt{}; -std::array, NpartChrg> hPtGenPrimRecEvt{}; -std::array, NpartChrg> hPtGenRecEvtGtZero{}; -std::array, NpartChrg> hPtGenPrimRecEvtGtZero{}; -std::array, NpartChrg> hPtEffRec{}; -std::array, NpartChrg> hPtEffGen{}; -std::array, NpartChrg> hPtEffRecGoodCollPrim{}; -std::array, NpartChrg> hPtEffRecGoodCollWeak{}; -std::array, NpartChrg> hPtEffRecGoodCollMat{}; -std::array, NpartChrg> hPtEffGenPrim{}; -std::array, NpartChrg> hPtEffGenWeak{}; -std::array, NpartChrg> hPtEffGenMat{}; -std::array, NpartChrg> hPtEffGenPrimEvtSelGen{}; -std::array, NpartChrg> hPtEffGenWeakEvtSelGen{}; -std::array, NpartChrg> hPtEffGenMatEvtSelGen{}; - -std::array, NpartChrg> hDCAxyRecBadCollPrim{}; -std::array, NpartChrg> hDCAxyRecBadCollWeak{}; -std::array, NpartChrg> hDCAxyRecBadCollMat{}; -std::array, NpartChrg> hPtVsDCAxyRecGoodCollPrim{}; -std::array, NpartChrg> hPtVsDCAxyRecGoodCollWeak{}; -std::array, NpartChrg> hPtVsDCAxyRecGoodCollMat{}; - struct FlattenictyPikp { HistogramRegistry registryData{"registryData", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; @@ -251,11 +230,11 @@ struct FlattenictyPikp { HistogramRegistry registryQC{"registryQC", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; OutputObj listEfficiency{"Efficiency"}; - Service pdg; + Service pdg{}; - std::vector fv0AmplCorr{}; + std::vector fv0AmplCorr; TProfile2D* zVtxMap = nullptr; - float magField; + float magField{0.}; int runNumber{-1}; o2::parameters::GRPMagField* grpmag = nullptr; @@ -263,7 +242,7 @@ struct FlattenictyPikp { Configurable applyCalibGain{"applyCalibGain", false, "equalize detector amplitudes"}; Configurable applyCalibVtx{"applyCalibVtx", false, "equalize Amp vs vtx"}; Configurable applyCalibDeDx{"applyCalibDeDx", false, "calibration of dedx signal"}; - Configurable applyCalibDeDxFromCCDB{"applyCalibDeDxFromCCDB", false, "use CCDB-based calibration of dedx signal"}; + Configurable applyCalibDeDxFromCCDB{"applyCalibDeDxFromCCDB", true, "use CCDB-based calibration of dedx signal"}; Configurable cfgFillTrackQaHist{"cfgFillTrackQaHist", false, "fill track QA histograms"}; Configurable cfgFillNclVsPhiCutQaHist{"cfgFillNclVsPhiCutQaHist", false, "fill TPC cluster vs geometrical cut QA histograms"}; Configurable cfgFilldEdxCalibHist{"cfgFilldEdxCalibHist", false, "fill dEdx calibration histograms"}; @@ -288,8 +267,7 @@ struct FlattenictyPikp { Configurable cfgGainEqCcdbPath{"cfgGainEqCcdbPath", "Users/g/gbencedi/flattenicity/GainEq", "CCDB path for gain equalization constants"}; Configurable cfgVtxEqCcdbPath{"cfgVtxEqCcdbPath", "Users/g/gbencedi/flattenicity/ZvtxEq", "CCDB path for z-vertex equalization constants"}; Configurable cfgDeDxCalibCcdbPath{"cfgDeDxCalibCcdbPath", "Users/g/gbencedi/flattenicity/dEdxCalib", "CCDB path for dEdx calibration"}; - Configurable cfgUseCcdbForRun{"cfgUseCcdbForRun", true, "Get ccdb object based on run number instead of timestamp"}; - Configurable cfgStoreThnSparse{"cfgStoreThnSparse", false, "Store histograms as THnSparse"}; + Configurable cfgStoreThnSparse{"cfgStoreThnSparse", true, "Store histograms as THnSparse"}; struct : ConfigurableGroup { Configurable cfgCustomTVX{"cfgCustomTVX", false, "Ask for custom TVX instead of sel8"}; @@ -370,7 +348,7 @@ struct FlattenictyPikp { // standad parameters for V0 selection Configurable cfgV0etamin{"cfgV0etamin", -0.8f, "min eta of V0s"}; Configurable cfgV0etamax{"cfgV0etamax", +0.8f, "max eta of V0s"}; - Configurable cfgminNCrossedRowsTPC{"cfgminNCrossedRowsTPC", 70.f, "Additional cut on the minimum number of crossed rows in the TPC"}; + Configurable cfgminNCrossedRowsTPC{"cfgminNCrossedRowsTPC", 70, "Additional cut on the minimum number of crossed rows in the TPC"}; Configurable cfgApplyV0sNclFound{"cfgApplyV0sNclFound", false, "Apply cut on TPC Found clusters"}; Configurable cfgV0NclTPCMin{"cfgV0NclTPCMin", 135.0f, "Minimum of number of TPC found clusters"}; Configurable cfgApplyV0sNclPID{"cfgApplyV0sNclPID", true, "Apply cut on TPC PID clusters"}; @@ -406,7 +384,7 @@ struct FlattenictyPikp { Configurable cfgdEdxPlateauSel{"cfgdEdxPlateauSel", 50, "dEdx selection sensitivity for electrons"}; } v0SelOpt; - Service ccdb; + Service ccdb{}; struct : ConfigurableGroup { Configurable cfgMagField{"cfgMagField", 99999, "Configurable magnetic field;default CCDB will be queried"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; @@ -445,7 +423,7 @@ struct FlattenictyPikp { Configurable requireITS{"requireITS", true, "Additional cut on the ITS requirement"}; Configurable requireTPC{"requireTPC", true, "Additional cut on the TPC requirement"}; Configurable requireGoldenChi2{"requireGoldenChi2", true, "Additional cut on the GoldenChi2"}; - Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 70.f, "Additional cut on the minimum number of crossed rows in the TPC"}; + Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 70, "Additional cut on the minimum number of crossed rows in the TPC"}; Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; Configurable maxChi2PerClusterTPC{"maxChi2PerClusterTPC", 4.f, "Additional cut on the maximum value of the chi2 per cluster in the TPC"}; Configurable maxChi2PerClusterITS{"maxChi2PerClusterITS", 36.f, "Additional cut on the maximum value of the chi2 per cluster in the ITS"}; @@ -461,6 +439,28 @@ struct FlattenictyPikp { std::vector> fEDeDxVsEta; std::vector> vecParamsPLA; + std::array, NpartChrg> hPtGenRecEvt{}; + std::array, NpartChrg> hPtGenPrimRecEvt{}; + std::array, NpartChrg> hPtGenRecEvtGtZero{}; + std::array, NpartChrg> hPtGenPrimRecEvtGtZero{}; + std::array, NpartChrg> hPtEffRec{}; + std::array, NpartChrg> hPtEffGen{}; + std::array, NpartChrg> hPtEffRecGoodCollPrim{}; + std::array, NpartChrg> hPtEffRecGoodCollWeak{}; + std::array, NpartChrg> hPtEffRecGoodCollMat{}; + std::array, NpartChrg> hPtEffGenPrim{}; + std::array, NpartChrg> hPtEffGenWeak{}; + std::array, NpartChrg> hPtEffGenMat{}; + std::array, NpartChrg> hPtEffGenPrimEvtSelGen{}; + std::array, NpartChrg> hPtEffGenWeakEvtSelGen{}; + std::array, NpartChrg> hPtEffGenMatEvtSelGen{}; + std::array, NpartChrg> hDCAxyRecBadCollPrim{}; + std::array, NpartChrg> hDCAxyRecBadCollWeak{}; + std::array, NpartChrg> hDCAxyRecBadCollMat{}; + std::array, NpartChrg> hPtVsDCAxyRecGoodCollPrim{}; + std::array, NpartChrg> hPtVsDCAxyRecGoodCollWeak{}; + std::array, NpartChrg> hPtVsDCAxyRecGoodCollMat{}; + using MyCollisions = soa::Join; using Colls = soa::Join; using CollsGen = soa::Join; @@ -496,9 +496,6 @@ struct FlattenictyPikp { targetVec.emplace_back(vecParamsMIPposEtaN); targetVec.emplace_back(vecParamsMIPnegEtaN); targetVec.emplace_back(vecParamsMIPallEtaN); - if (!vecParamsMIP.size()) { - LOG(info) << "size of " << name << "is zero."; - } } else { targetVec.emplace_back(vecParamsPLAposEtaP); targetVec.emplace_back(vecParamsPLAnegEtaP); @@ -506,9 +503,9 @@ struct FlattenictyPikp { targetVec.emplace_back(vecParamsPLAposEtaN); targetVec.emplace_back(vecParamsPLAnegEtaN); targetVec.emplace_back(vecParamsPLAallEtaN); - if (!vecParamsPLA.size()) { - LOG(info) << "size of " << name << "is zero."; - } + } + if (vecParamsMIP.empty() || vecParamsPLA.empty()) { + LOG(info) << "size of " << name << "is zero."; } }; addVec(vecParamsMIP, "vecParamsMIP", true); @@ -702,7 +699,7 @@ struct FlattenictyPikp { } if (cfgFillDCAxyHist) { for (int i = 0; i < Npart; i++) { - registryData.add({fmt::format(CpTvsDCAxyF.data(), CspeciesAll[i]).c_str(), "; mult; flat; #it{p} (GeV/#it{c}); DCA_{xy} (cm)", {kTHnSparseF, {multAxis, flatAxis, ptAxis, dcaXYAxis}}}); + registryData.add({fmt::format(CpTvsDCAxyF.data(), CspeciesAll[i].data()).c_str(), "; mult; flat; #it{p} (GeV/#it{c}); DCA_{xy} (cm)", {kTHnSparseF, {multAxis, flatAxis, ptAxis, dcaXYAxis}}}); } } } @@ -780,11 +777,11 @@ struct FlattenictyPikp { registryMC.add("Events/hCentVsFlatRecINELgt0wRecEvtSel", "Gen evt w/ Nrec > 0 + Evt sel; mult; flat", {kTH2F, {multAxis, flatAxis}}); for (int i = 0; i < Npart; ++i) { // Signal loss - registryMC.add({fmt::format(CpTgenPrimSgnF.data(), CspeciesAll[i]).c_str(), "Gen evt w/o Evt sel; Gen Nch (|#eta|<0.8); flat; #it{p}_{T} (GeV/#it{c})", {kTHnSparseF, {nChAxis, flatAxis, ptAxis}}}); - registryMC.add({fmt::format(CpTrecCollPrimSgnF.data(), CspeciesAll[i]).c_str(), "Gen Nch w/ Nrec > 0; Gen Nch (|#eta|<0.8); flat; #it{p}_{T} (GeV/#it{c})", {kTHnSparseF, {nChAxis, flatAxis, ptAxis}}}); + registryMC.add({fmt::format(CpTgenPrimSgnF.data(), CspeciesAll[i].data()).c_str(), "Gen evt w/o Evt sel; Gen Nch (|#eta|<0.8); flat; #it{p}_{T} (GeV/#it{c})", {kTHnSparseF, {nChAxis, flatAxis, ptAxis}}}); + registryMC.add({fmt::format(CpTrecCollPrimSgnF.data(), CspeciesAll[i].data()).c_str(), "Gen Nch w/ Nrec > 0; Gen Nch (|#eta|<0.8); flat; #it{p}_{T} (GeV/#it{c})", {kTHnSparseF, {nChAxis, flatAxis, ptAxis}}}); // Closure test - registryMC.add({fmt::format(CpTmcClosureGenPrimF.data(), CspeciesAll[i]).c_str(), "Gen evt w/o Evt sel; Gen Nch (|#eta|<0.8); flat; #it{p}_{T} (GeV/#it{c})", {kTHnSparseF, {nChAxis, flatAxis, ptAxis}}}); - registryMC.add({fmt::format(CpTmcClosureRecF.data(), CspeciesAll[i]).c_str(), "Gen Nch w/ Nrec > 0 + Evt. sel; Gen Nch (|#eta|<0.8); flat; #it{p}_{T} (GeV/#it{c})", {kTHnSparseF, {nChAxis, flatAxis, ptAxis}}}); + registryMC.add({fmt::format(CpTmcClosureGenPrimF.data(), CspeciesAll[i].data()).c_str(), "Gen evt w/o Evt sel; Gen Nch (|#eta|<0.8); flat; #it{p}_{T} (GeV/#it{c})", {kTHnSparseF, {nChAxis, flatAxis, ptAxis}}}); + registryMC.add({fmt::format(CpTmcClosureRecF.data(), CspeciesAll[i].data()).c_str(), "Gen Nch w/ Nrec > 0 + Evt. sel; Gen Nch (|#eta|<0.8); flat; #it{p}_{T} (GeV/#it{c})", {kTHnSparseF, {nChAxis, flatAxis, ptAxis}}}); } if (cfgFillNclVsPhiCutQaHist) { registryMC.add("Tracks/postSel/hPtPhi", "; #it{p}_{T} (GeV/#it{c}); fmod(#varphi,#pi/9)", {kTH2F, {ptAxis, phiAxisMod}}); @@ -798,7 +795,7 @@ struct FlattenictyPikp { registryMC.addClone("Tracks/postSel/", "Tracks/preSel/"); for (int i = 0; i < NpartChrg; i++) { - const std::string strID = Form("/%s/%s", (i < Npart) ? "pos" : "neg", Pid[i % Npart]); + const std::string strID = Form("/%s/%s", (i < Npart) ? "pos" : "neg", pID[i % Npart]); hPtGenRecEvt[i] = registryMC.add("Tracks/hPtGenRecEvt" + strID, "Gen evt w/ Nrec > 0; mult; flat; #it{p}_{T} (GeV/#it{c})", kTHnSparseF, {multAxis, flatAxis, ptAxis}); hPtGenPrimRecEvt[i] = registryMC.add("Tracks/hPtGenPrimRecEvt" + strID, "Gen evt w/ Nrec > 0 (primary); mult; flat; #it{p}_{T} (GeV/#it{c})", kTHnSparseF, {multAxis, flatAxis, ptAxis}); hPtGenRecEvtGtZero[i] = registryMC.add("Tracks/hPtGenRecEvtGtZero" + strID, "Gen evt w/ Nrec > 0; mult; flat; #it{p}_{T} (GeV/#it{c})", kTHnSparseF, {multAxis, flatAxis, ptAxis}); @@ -821,14 +818,15 @@ struct FlattenictyPikp { } for (int i = 0; i < Npart; i++) { - registryMC.add({fmt::format(CpTeffGenPrimRecEvtF.data(), CspeciesAll[i]).c_str(), "Gen evt w/ Nrec > 0; mult; flat; #it{p}_{T} (GeV/#it{c})", {kTHnSparseF, {multAxis, flatAxis, ptAxis}}}); - registryMC.add({fmt::format(CpTeffPrimRecEvtF.data(), CspeciesAll[i]).c_str(), "Gen evt w/ Nrec > 0 + Evt sel; mult; flat; #it{p}_{T} (GeV/#it{c})", {kTHnSparseF, {multAxis, flatAxis, ptAxis}}}); - registryMC.add({fmt::format(CpTvsDCAxyAllF.data(), CspeciesAll[i]).c_str(), "; mult; flat; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", {kTHnSparseF, {multAxis, flatAxis, ptAxis, dcaXYAxis}}}); - registryMC.add({fmt::format(CpTvsDCAxyPrimAllF.data(), CspeciesAll[i]).c_str(), "; mult; flat; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", {kTHnSparseF, {multAxis, flatAxis, ptAxis, dcaXYAxis}}}); - registryMC.add({fmt::format(CpTvsDCAxyWeakAllF.data(), CspeciesAll[i]).c_str(), "; mult; flat; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", {kTHnSparseF, {multAxis, flatAxis, ptAxis, dcaXYAxis}}}); - registryMC.add({fmt::format(CpTvsDCAxyMatAllF.data(), CspeciesAll[i]).c_str(), "; mult; flat; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", {kTHnSparseF, {multAxis, flatAxis, ptAxis, dcaXYAxis}}}); - registryMC.add({fmt::format(CdEdxMcRecPrimF.data(), CspeciesAll[i]).c_str(), "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {kTHnSparseF, {etaAxis, multAxis, flatAxis, pAxis, dEdxAxis}}}); - registryMC.add({fmt::format(CdEdxMcRecPrimSelF.data(), CspeciesAll[i]).c_str(), "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {kTHnSparseF, {etaAxis, multAxis, flatAxis, pAxis, dEdxAxis}}}); + registryMC.add({fmt::format(CpTeffGenPrimRecEvtF.data(), CspeciesAll[i].data()).c_str(), "Gen evt w/ Nrec > 0; mult; flat; #it{p}_{T} (GeV/#it{c})", {kTHnSparseF, {multAxis, flatAxis, ptAxis}}}); + registryMC.add({fmt::format(CpTeffPrimRecEvtF.data(), CspeciesAll[i].data()).c_str(), "Gen evt w/ Nrec > 0 + Evt sel; mult; flat; #it{p}_{T} (GeV/#it{c})", {kTHnSparseF, {multAxis, flatAxis, ptAxis}}}); + registryMC.add({fmt::format(CpTvsDCAxyAllF.data(), CspeciesAll[i].data()).c_str(), "; mult; flat; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", {kTHnSparseF, {multAxis, flatAxis, ptAxis, dcaXYAxis}}}); + registryMC.add({fmt::format(CpTvsDCAxyPrimAllF.data(), CspeciesAll[i].data()).c_str(), "; mult; flat; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", {kTHnSparseF, {multAxis, flatAxis, ptAxis, dcaXYAxis}}}); + registryMC.add({fmt::format(CpTvsDCAxyWeakAllF.data(), CspeciesAll[i].data()).c_str(), "; mult; flat; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", {kTHnSparseF, {multAxis, flatAxis, ptAxis, dcaXYAxis}}}); + registryMC.add({fmt::format(CpTvsDCAxyMatAllF.data(), CspeciesAll[i].data()).c_str(), "; mult; flat; #it{p}_{T} (GeV/#it{c}); DCA_{xy} (cm)", {kTHnSparseF, {multAxis, flatAxis, ptAxis, dcaXYAxis}}}); + registryMC.add({fmt::format(CdEdxMcRecPrimF.data(), CspeciesAll[i].data()).c_str(), "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {kTHnSparseF, {etaAxis, multAxis, flatAxis, pAxis, dEdxAxis}}}); + registryMC.add({fmt::format(CdEdxMcRecPrimSelF.data(), CspeciesAll[i].data()).c_str(), "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {kTHnSparseF, {etaAxis, multAxis, flatAxis, pAxis, dEdxAxis}}}); + registryMC.add({fmt::format(CEtaVsPtVsPMcRecPrimSelF.data(), CspeciesAll[i].data()).c_str(), "; #eta; #it{p}_{T} (GeV/#it{c}); #it{p} (GeV/#it{c})", {kTHnSparseF, {etaAxis, ptAxis, pAxis}}}); } // Hash list for efficiency @@ -851,11 +849,10 @@ struct FlattenictyPikp { { fv0AmplCorr.clear(); fv0AmplCorr = {}; - std::string fullPathCalibGain; - std::string fullPathCalibVtx; - std::string fullPathCalibDeDxMip; - std::string fullPathCalibDeDxPlateau; - auto timestamp = bc.timestamp(); + // std::string fullPathCalibGain{}; + // std::string fullPathCalibVtx{}; + // std::string fullPathCalibDeDxMip{}; + // std::string fullPathCalibDeDxPlateau{}; auto runnumber = bc.runNumber(); if (trkSelOpt.cfgRejectTrkAtTPCSector || v0SelOpt.cfgRejectV0sAtTPCSector) { @@ -867,9 +864,9 @@ struct FlattenictyPikp { LOG(info) << "Retrieved GRP for run " << runnumber << " with magnetic field of " << magField << " kZG"; } if (applyCalibGain) { - fullPathCalibGain = cfgGainEqCcdbPath; + std::string fullPathCalibGain = cfgGainEqCcdbPath; fullPathCalibGain += "/FV0"; - const auto* objfv0Gain = getForTsOrRun>(fullPathCalibGain, timestamp, runnumber); + const auto* objfv0Gain = ccdb->getForRun>(fullPathCalibGain, runnumber); if (!objfv0Gain) { for (auto i{0u}; i < CnCellsFV0; i++) { fv0AmplCorr.push_back(1.); @@ -880,49 +877,53 @@ struct FlattenictyPikp { } } if (applyCalibVtx) { - fullPathCalibVtx = cfgVtxEqCcdbPath; + std::string fullPathCalibVtx = cfgVtxEqCcdbPath; fullPathCalibVtx += "/FV0"; - zVtxMap = getForTsOrRun(fullPathCalibVtx, timestamp, runnumber); + zVtxMap = ccdb->getForRun(fullPathCalibVtx, runnumber); } if (applyCalibDeDxFromCCDB) { - fullPathCalibDeDxMip = cfgDeDxCalibCcdbPath; - fullPathCalibDeDxMip += "/MIP"; - fullPathCalibDeDxPlateau = cfgDeDxCalibCcdbPath; - fullPathCalibDeDxPlateau += "/Plateau"; + std::string fullPathCalibDeDxMip = cfgDeDxCalibCcdbPath; if (!fullPathCalibDeDxMip.empty()) { - dedxcalib.lCalibObjects = getForTsOrRun(fullPathCalibDeDxMip, timestamp, runnumber); - if (dedxcalib.lCalibObjects) { - LOG(info) << "CCDB objects loaded successfully"; - dedxcalib.hMIPcalibPos = static_cast(dedxcalib.lCalibObjects->FindObject("hMIPcalibPos")); - dedxcalib.hMIPcalibNeg = static_cast(dedxcalib.lCalibObjects->FindObject("hMIPcalibNeg")); - dedxcalib.hMIPcalibAll = static_cast(dedxcalib.lCalibObjects->FindObject("hMIPcalibAll")); - dedxcalib.lCalibLoaded = true; - if (!dedxcalib.hMIPcalibPos || !dedxcalib.hMIPcalibNeg || !dedxcalib.hMIPcalibAll) { - LOGF(error, "Problem loading CCDB objects! Please check"); - dedxcalib.lCalibLoaded = false; - } - } else { - LOGF(fatal, "Could not load hMIPcalib from %s", fullPathCalibDeDxMip.c_str()); - dedxcalib.lCalibLoaded = false; - } + fullPathCalibDeDxMip += "/MIP"; } + std::string fullPathCalibDeDxPlateau = cfgDeDxCalibCcdbPath; if (!fullPathCalibDeDxPlateau.empty()) { - dedxcalib.lCalibObjects = getForTsOrRun(fullPathCalibDeDxPlateau, timestamp, runnumber); - if (dedxcalib.lCalibObjects) { - LOG(info) << "CCDB objects loaded successfully"; - dedxcalib.hPlateauCalibPos = static_cast(dedxcalib.lCalibObjects->FindObject("hPlateauCalibPos")); - dedxcalib.hPlateauCalibNeg = static_cast(dedxcalib.lCalibObjects->FindObject("hPlateauCalibNeg")); - dedxcalib.hPlateauCalibAll = static_cast(dedxcalib.lCalibObjects->FindObject("hPlateauCalibAll")); - dedxcalib.lCalibLoaded = true; - if (!dedxcalib.hPlateauCalibPos || !dedxcalib.hPlateauCalibNeg || !dedxcalib.hPlateauCalibAll) { - LOGF(error, "Problem loading CCDB objects! Please check"); - dedxcalib.lCalibLoaded = false; - } - } else { - LOGF(fatal, "Could not load hPlateauCalib from %s", fullPathCalibDeDxPlateau.c_str()); + fullPathCalibDeDxPlateau += "/Plateau"; + } + // if (!fullPathCalibDeDxMip.empty()) { + dedxcalib.lCalibObjects = ccdb->getForRun(fullPathCalibDeDxMip, runnumber); + if (dedxcalib.lCalibObjects) { + LOG(info) << "CCDB objects loaded successfully"; + dedxcalib.hMIPcalibPos = dynamic_cast(dedxcalib.lCalibObjects->FindObject("hMIPcalibPos")); + dedxcalib.hMIPcalibNeg = dynamic_cast(dedxcalib.lCalibObjects->FindObject("hMIPcalibNeg")); + dedxcalib.hMIPcalibAll = dynamic_cast(dedxcalib.lCalibObjects->FindObject("hMIPcalibAll")); + dedxcalib.lCalibLoaded = true; + if (!dedxcalib.hMIPcalibPos || !dedxcalib.hMIPcalibNeg || !dedxcalib.hMIPcalibAll) { + LOGF(error, "Problem loading CCDB objects! Please check"); + dedxcalib.lCalibLoaded = false; + } + } else { + LOGF(fatal, "Could not load hMIPcalib from %s", fullPathCalibDeDxMip.c_str()); + dedxcalib.lCalibLoaded = false; + } + // } + // if (!fullPathCalibDeDxPlateau.empty()) { + dedxcalib.lCalibObjects = ccdb->getForRun(fullPathCalibDeDxPlateau, runnumber); + if (dedxcalib.lCalibObjects) { + LOG(info) << "CCDB objects loaded successfully"; + dedxcalib.hPlateauCalibPos = dynamic_cast(dedxcalib.lCalibObjects->FindObject("hPlateauCalibPos")); + dedxcalib.hPlateauCalibNeg = dynamic_cast(dedxcalib.lCalibObjects->FindObject("hPlateauCalibNeg")); + dedxcalib.hPlateauCalibAll = dynamic_cast(dedxcalib.lCalibObjects->FindObject("hPlateauCalibAll")); + dedxcalib.lCalibLoaded = true; + if (!dedxcalib.hPlateauCalibPos || !dedxcalib.hPlateauCalibNeg || !dedxcalib.hPlateauCalibAll) { + LOGF(error, "Problem loading CCDB objects! Please check"); + dedxcalib.lCalibLoaded = false; } + } else { + LOGF(fatal, "Could not load hPlateauCalib from %s", fullPathCalibDeDxPlateau.c_str()); } + // } } } @@ -942,9 +943,9 @@ struct FlattenictyPikp { bool isPID(const P& mcParticle) { static_assert(pidSgn == CnullInt || pidSgn == ConeInt); - static_assert(id > CnullInt || id < Npart); + static_assert(id > CnullInt && id < Npart); constexpr int Cidx = id + pidSgn * Npart; - return mcParticle.pdgCode() == PidSgn[Cidx]; + return mcParticle.pdgCode() == pIdSgn[Cidx]; } template @@ -1160,31 +1161,32 @@ struct FlattenictyPikp { if (selectTypeV0s(collision, v0, posTrack, negTrack) == kGa) { // Gamma selection fillV0QA(v0, posTrack); fillV0QA(v0, negTrack); + // float dEdxPosGa{-1.}, dEdxNegGa{-1.}; if (applyCalibDeDx) { if (cfgFillChrgTypeV0s) { if (applyCalibDeDxFromCCDB) { - const float dEdxPosGa = dedxcalib.hMIPcalibPos->GetBinContent(dedxcalib.hMIPcalibPos->FindBin(posTrack.eta())); - const float dEdxNegGa = dedxcalib.hMIPcalibNeg->GetBinContent(dedxcalib.hMIPcalibNeg->FindBin(negTrack.eta())); + float dEdxPosGa = dedxcalib.hMIPcalibPos->GetBinContent(dedxcalib.hMIPcalibPos->FindBin(posTrack.eta())); + float dEdxNegGa = dedxcalib.hMIPcalibNeg->GetBinContent(dedxcalib.hMIPcalibNeg->FindBin(negTrack.eta())); if (std::abs(dEdxPos - dEdxPosGa) >= v0SelOpt.cfgdEdxPlateauSel || std::abs(dEdxNeg - dEdxNegGa) >= v0SelOpt.cfgdEdxPlateauSel) { continue; } } else { - const float dEdxPosGa = getCalibration(fEDeDxVsEta, posTrack); - const float dEdxNegGa = getCalibration(fEDeDxVsEta, negTrack); + float dEdxPosGa = getCalibration(fEDeDxVsEta, posTrack); + float dEdxNegGa = getCalibration(fEDeDxVsEta, negTrack); if (std::abs(dEdxPos - dEdxPosGa) >= v0SelOpt.cfgdEdxPlateauSel || std::abs(dEdxNeg - dEdxNegGa) >= v0SelOpt.cfgdEdxPlateauSel) { continue; } } } else { if (applyCalibDeDxFromCCDB) { - const float dEdxPosGa = dedxcalib.hPlateauCalibAll->GetBinContent(dedxcalib.hPlateauCalibAll->FindBin(posTrack.eta())); - const float dEdxNegGa = dedxcalib.hPlateauCalibAll->GetBinContent(dedxcalib.hPlateauCalibAll->FindBin(negTrack.eta())); + float dEdxPosGa = dedxcalib.hPlateauCalibAll->GetBinContent(dedxcalib.hPlateauCalibAll->FindBin(posTrack.eta())); + float dEdxNegGa = dedxcalib.hPlateauCalibAll->GetBinContent(dedxcalib.hPlateauCalibAll->FindBin(negTrack.eta())); if (std::abs(dEdxPos - dEdxPosGa) >= v0SelOpt.cfgdEdxPlateauSel || std::abs(dEdxNeg - dEdxNegGa) >= v0SelOpt.cfgdEdxPlateauSel) { continue; } } else { - const float dEdxPosGa = getCalibration(fEDeDxVsEta, posTrack); - const float dEdxNegGa = getCalibration(fEDeDxVsEta, negTrack); + float dEdxPosGa = getCalibration(fEDeDxVsEta, posTrack); + float dEdxNegGa = getCalibration(fEDeDxVsEta, negTrack); if (std::abs(dEdxPos - dEdxPosGa) >= v0SelOpt.cfgdEdxPlateauSel || std::abs(dEdxNeg - dEdxNegGa) >= v0SelOpt.cfgdEdxPlateauSel) { continue; } @@ -1360,9 +1362,6 @@ struct FlattenictyPikp { return false; } registryMC.fill(HIST("Events/hNchTVX"), nChrgMc, 1.5); - if (nChrgMc == CnullInt) { - return false; - } return true; } @@ -1391,15 +1390,17 @@ struct FlattenictyPikp { return nTrk; } - void phiMod(float& phimodn, const int& mag, const int& charge) + void phiMod(float& phimodn, const float& mag, const int& charge) { - if (mag < Cnull) // for negative polarity field + if (mag < Cnull) { // for negative polarity field phimodn = o2::constants::math::TwoPI - phimodn; - if (charge < Cnull) // for negative charge + } + if (charge < Cnull) { // for negative charge phimodn = o2::constants::math::TwoPI - phimodn; - if (phimodn < Cnull) + } + if (phimodn < Cnull) { LOGF(warning, "phi < Cnull: %g", phimodn); - + } phimodn += o2::constants::math::PI / 18.0f; // to center gap in the middle phimodn = std::fmod(phimodn, o2::constants::math::PI / 9.0f); } @@ -1474,34 +1475,28 @@ struct FlattenictyPikp { template int selectTypeV0s(C const& collision, T1 const& v0, T2 const& postrk, T2 const& negtrk) { - const float dMassK0s = std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short); - const float dMassL = std::abs(v0.mLambda() - o2::constants::physics::MassLambda0); - const float dMassAL = std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0); - const float dMassG = std::abs(v0.mGamma() - o2::constants::physics::MassGamma); - bool isMassG = false; bool isMassK0s = false; bool isMassL = false; bool isMassAL = false; - if (dMassK0s > v0SelOpt.cfgdmassK && dMassL > v0SelOpt.cfgdmassL && dMassAL > v0SelOpt.cfgdmassL && dMassG < v0SelOpt.cfgdmassG) { + if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) > v0SelOpt.cfgdmassK && std::abs(v0.mLambda() - o2::constants::physics::MassLambda0) > v0SelOpt.cfgdmassL && std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) > v0SelOpt.cfgdmassL && std::abs(v0.mGamma() - o2::constants::physics::MassGamma) < v0SelOpt.cfgdmassG) { isMassG = true; } - if (dMassK0s < v0SelOpt.cfgdmassK && dMassL > v0SelOpt.cfgdmassL && dMassAL > v0SelOpt.cfgdmassL && dMassG > v0SelOpt.cfgdmassG) { + if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) < v0SelOpt.cfgdmassK && std::abs(v0.mLambda() - o2::constants::physics::MassLambda0) > v0SelOpt.cfgdmassL && std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) > v0SelOpt.cfgdmassL && std::abs(v0.mGamma() - o2::constants::physics::MassGamma) > v0SelOpt.cfgdmassG) { isMassK0s = true; } - if (dMassK0s > v0SelOpt.cfgdmassK && dMassL < v0SelOpt.cfgdmassL && dMassG > v0SelOpt.cfgdmassG) { + if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) > v0SelOpt.cfgdmassK && std::abs(v0.mLambda() - o2::constants::physics::MassLambda0) < v0SelOpt.cfgdmassL && std::abs(v0.mGamma() - o2::constants::physics::MassGamma) > v0SelOpt.cfgdmassG) { isMassL = true; } - if (dMassK0s > v0SelOpt.cfgdmassK && dMassAL < v0SelOpt.cfgdmassL && dMassG > v0SelOpt.cfgdmassG) { + if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) > v0SelOpt.cfgdmassK && std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) < v0SelOpt.cfgdmassL && std::abs(v0.mGamma() - o2::constants::physics::MassGamma) > v0SelOpt.cfgdmassG) { isMassAL = true; } // Gamma selection - const float yGamma = RecoDecay::y(std::array{v0.px(), v0.py(), v0.pz()}, o2::constants::physics::MassGamma); if (isMassG) { - if (std::abs(yGamma) < v0SelOpt.cfgV0Ymax) { // rapidity cut - if (std::abs(v0.alpha()) < v0SelOpt.cfgArmPodGammasalpha && v0.qtarm() < v0SelOpt.cfgArmPodGammasqT) { // + if (std::abs(RecoDecay::y(std::array{v0.px(), v0.py(), v0.pz()}, o2::constants::physics::MassGamma)) < v0SelOpt.cfgV0Ymax) { // rapidity cut + if (std::abs(v0.alpha()) < v0SelOpt.cfgArmPodGammasalpha && v0.qtarm() < v0SelOpt.cfgArmPodGammasqT) { // if (postrk.hasTPC() && std::abs(postrk.tpcNSigmaEl()) < v0SelOpt.cfgNsigmaElTPC) { if (postrk.hasTOF() && std::abs(postrk.tofNSigmaEl()) < v0SelOpt.cfgNsigmaElTOF) { return kGa; @@ -1808,93 +1803,93 @@ struct FlattenictyPikp { { int iRing = -1; - if (i_ch >= Cfv0IndexPhi[0] && i_ch < Cfv0IndexPhi[1]) { - if (i_ch < Cfv0IndexPhi[0] + 4) { + if (i_ch >= cFV0IndexPhi[0] && i_ch < cFV0IndexPhi[1]) { + if (i_ch < cFV0IndexPhi[0] + 4) { iRing = i_ch; } else { - if (i_ch == Cfv0IndexPhi[1] - 1) { + if (i_ch == cFV0IndexPhi[1] - 1) { iRing = i_ch - 3; // 4; - } else if (i_ch == Cfv0IndexPhi[1] - 2) { + } else if (i_ch == cFV0IndexPhi[1] - 2) { iRing = i_ch - 1; // 5; - } else if (i_ch == Cfv0IndexPhi[1] - 3) { + } else if (i_ch == cFV0IndexPhi[1] - 3) { iRing = i_ch + 1; // 6; - } else if (i_ch == Cfv0IndexPhi[1] - 4) { + } else if (i_ch == cFV0IndexPhi[1] - 4) { iRing = i_ch + 3; // 7; } } - } else if (i_ch >= Cfv0IndexPhi[1] && i_ch < Cfv0IndexPhi[2]) { - if (i_ch < Cfv0IndexPhi[2] - 4) { + } else if (i_ch >= cFV0IndexPhi[1] && i_ch < cFV0IndexPhi[2]) { + if (i_ch < cFV0IndexPhi[2] - 4) { iRing = i_ch; } else { - if (i_ch == Cfv0IndexPhi[2] - 1) { + if (i_ch == cFV0IndexPhi[2] - 1) { iRing = i_ch - 3; // 12; - } else if (i_ch == Cfv0IndexPhi[2] - 2) { + } else if (i_ch == cFV0IndexPhi[2] - 2) { iRing = i_ch - 1; // 13; - } else if (i_ch == Cfv0IndexPhi[2] - 3) { + } else if (i_ch == cFV0IndexPhi[2] - 3) { iRing = i_ch + 1; // 14; - } else if (i_ch == Cfv0IndexPhi[2] - 4) { + } else if (i_ch == cFV0IndexPhi[2] - 4) { iRing = i_ch + 3; // 15; } } - } else if (i_ch >= Cfv0IndexPhi[2] && i_ch < Cfv0IndexPhi[3]) { - if (i_ch < Cfv0IndexPhi[3] - 4) { + } else if (i_ch >= cFV0IndexPhi[2] && i_ch < cFV0IndexPhi[3]) { + if (i_ch < cFV0IndexPhi[3] - 4) { iRing = i_ch; } else { - if (i_ch == Cfv0IndexPhi[3] - 1) { + if (i_ch == cFV0IndexPhi[3] - 1) { iRing = i_ch - 3; // 20; - } else if (i_ch == Cfv0IndexPhi[3] - 2) { + } else if (i_ch == cFV0IndexPhi[3] - 2) { iRing = i_ch - 1; // 21; - } else if (i_ch == Cfv0IndexPhi[3] - 3) { + } else if (i_ch == cFV0IndexPhi[3] - 3) { iRing = i_ch + 1; // 22; - } else if (i_ch == Cfv0IndexPhi[3] - 4) { + } else if (i_ch == cFV0IndexPhi[3] - 4) { iRing = i_ch + 3; // 23; } } - } else if (i_ch >= Cfv0IndexPhi[3] && i_ch < Cfv0IndexPhi[4]) { - if (i_ch < Cfv0IndexPhi[3] + 4) { + } else if (i_ch >= cFV0IndexPhi[3] && i_ch < cFV0IndexPhi[4]) { + if (i_ch < cFV0IndexPhi[3] + 4) { iRing = i_ch; } else { - if (i_ch == Cfv0IndexPhi[4] - 5) { + if (i_ch == cFV0IndexPhi[4] - 5) { iRing = i_ch - 3; // 28; - } else if (i_ch == Cfv0IndexPhi[4] - 6) { + } else if (i_ch == cFV0IndexPhi[4] - 6) { iRing = i_ch - 1; // 29; - } else if (i_ch == Cfv0IndexPhi[4] - 7) { + } else if (i_ch == cFV0IndexPhi[4] - 7) { iRing = i_ch + 1; // 30; - } else if (i_ch == Cfv0IndexPhi[4] - 8) { + } else if (i_ch == cFV0IndexPhi[4] - 8) { iRing = i_ch + 3; // 31; } } - } else if (i_ch == Cfv0IndexPhi[4]) { - iRing = Cfv0IndexPhi[4]; - } else if (i_ch == Cfv0IndexPhi[4] + 8) { + } else if (i_ch == cFV0IndexPhi[4]) { + iRing = cFV0IndexPhi[4]; + } else if (i_ch == cFV0IndexPhi[4] + 8) { iRing = i_ch - 7; // 33; - } else if (i_ch == Cfv0IndexPhi[4] + 1) { + } else if (i_ch == cFV0IndexPhi[4] + 1) { iRing = i_ch + 1; // 34; - } else if (i_ch == Cfv0IndexPhi[4] + 9) { + } else if (i_ch == cFV0IndexPhi[4] + 9) { iRing = i_ch - 6; // 35; - } else if (i_ch == Cfv0IndexPhi[4] + 2) { + } else if (i_ch == cFV0IndexPhi[4] + 2) { iRing = i_ch + 2; // 36; - } else if (i_ch == Cfv0IndexPhi[4] + 10) { + } else if (i_ch == cFV0IndexPhi[4] + 10) { iRing = i_ch - 5; // 37; - } else if (i_ch == Cfv0IndexPhi[4] + 3) { + } else if (i_ch == cFV0IndexPhi[4] + 3) { iRing = i_ch + 3; // 38; - } else if (i_ch == Cfv0IndexPhi[4] + 11) { + } else if (i_ch == cFV0IndexPhi[4] + 11) { iRing = i_ch - 4; // 39; - } else if (i_ch == Cfv0IndexPhi[4] + 15) { + } else if (i_ch == cFV0IndexPhi[4] + 15) { iRing = i_ch - 7; // 40; - } else if (i_ch == Cfv0IndexPhi[4] + 7) { + } else if (i_ch == cFV0IndexPhi[4] + 7) { iRing = i_ch + 2; // 41; - } else if (i_ch == Cfv0IndexPhi[4] + 14) { + } else if (i_ch == cFV0IndexPhi[4] + 14) { iRing = i_ch - 4; // 42; - } else if (i_ch == Cfv0IndexPhi[4] + 6) { + } else if (i_ch == cFV0IndexPhi[4] + 6) { iRing = i_ch + 5; // 43; - } else if (i_ch == Cfv0IndexPhi[4] + 13) { + } else if (i_ch == cFV0IndexPhi[4] + 13) { iRing = i_ch - 1; // 44; - } else if (i_ch == Cfv0IndexPhi[4] + 5) { + } else if (i_ch == cFV0IndexPhi[4] + 5) { iRing = i_ch + 8; // 45; - } else if (i_ch == Cfv0IndexPhi[4] + 12) { + } else if (i_ch == cFV0IndexPhi[4] + 12) { iRing = i_ch + 2; // 46; - } else if (i_ch == Cfv0IndexPhi[4] + 4) { + } else if (i_ch == cFV0IndexPhi[4] + 4) { iRing = i_ch + 11; // 47; } return iRing; @@ -1973,13 +1968,12 @@ struct FlattenictyPikp { template float fillFlat(C const& collision) { - rhoLatticeFV0.fill(0); - fv0AmplitudeWoCalib.fill(0); + float oneMinusFlat{9999}; if (collision.has_foundFV0()) { auto fv0 = collision.foundFV0(); - std::bitset<8> fV0Triggers = fv0.triggerMask(); - bool isOkFV0OrA = fV0Triggers[o2::fit::Triggers::bitA]; - if (isOkFV0OrA) { + if (TESTBIT(fv0.triggerMask(), o2::fit::Triggers::bitA)) { + std::array rhoLatticeFV0{0.}; + std::array fv0AmplitudeWoCalib{0.}; for (std::size_t ich = 0; ich < fv0.channel().size(); ich++) { float amplCh = fv0.amplitude()[ich]; int chv0 = fv0.channel()[ich]; @@ -2018,13 +2012,10 @@ struct FlattenictyPikp { } } float flattenicityFV0 = calcFlatenicity(rhoLatticeFV0); - return 1. - flattenicityFV0; - } else { - return 9999; + oneMinusFlat = 1. - flattenicityFV0; } - } else { - return 9999; } + return oneMinusFlat; } template @@ -2108,8 +2099,8 @@ struct FlattenictyPikp { float maxPhi = 0; float dPhi = 0; - float etaMinFV0bins[CmaxRingsFV0] = {0.0}; - float etaMaxFV0bins[CmaxRingsFV0] = {0.0}; + std::array etaMinFV0bins{0.}; + std::array etaMaxFV0bins{0.}; for (int i = 0; i < CmaxRingsFV0; ++i) { etaMaxFV0bins[i] = CmaxEtaFV0 - i * CdEtaFV0; if (i < CmaxRingsFV0 - 1) { @@ -2119,7 +2110,7 @@ struct FlattenictyPikp { } } - rhoLatticeFV0.fill(0); + std::array rhoLatticeFV0{0.}; std::vector vNch; float nChFV0{0}; for (const auto& mcPart : mcparts) { @@ -2175,8 +2166,8 @@ struct FlattenictyPikp { { AxisSpec ptAxis{binOpt.axisPt, "#it{p}_{T} (GeV/#it{c})"}; constexpr int ChistIdx = id + pidSgn * Npart; - auto idx = static_cast(id); - const std::string strID = Form("/%s/%s", (pidSgn == CnullInt && id < Npart) ? "pos" : "neg", Pid[idx]); + auto idx = id; + const std::string strID = Form("/%s/%s", (pidSgn == CnullInt && id < Npart) ? "pos" : "neg", pID[idx]); hPtEffRec[ChistIdx] = registryMC.add("Tracks/hPtEffRec" + strID, " ; #it{p}_{T} (GeV/#it{c})", kTH1F, {ptAxis}); hPtEffGen[ChistIdx] = registryMC.add("Tracks/hPtEffGen" + strID, " ; #it{p}_{T} (GeV/#it{c})", kTH1F, {ptAxis}); } @@ -2185,14 +2176,14 @@ struct FlattenictyPikp { void initEfficiency() { static_assert(pidSgn == CnullInt || pidSgn == ConeInt); - static_assert(id > CnullInt || id < Npart); + static_assert(id > CnullInt && id < Npart); constexpr int Cidx = id + pidSgn * Npart; - const TString partName = PidChrg[Cidx]; - THashList* lhash = new THashList(); + const TString partName = pIdChrg[Cidx]; + auto lhash = new THashList(); lhash->SetName(partName); listEfficiency->Add(lhash); - auto bookEff = [&](const TString eName, auto h) { + auto bookEff = [&](const TString& eName, const auto& h) { const TAxis* axis = h->GetXaxis(); TString eTitle = h->GetTitle(); eTitle.ReplaceAll("Numerator", "").Strip(TString::kBoth); @@ -2209,15 +2200,15 @@ struct FlattenictyPikp { { static_assert(pidSgn == CnullInt || pidSgn == ConeInt); constexpr int ChistIdx = id + pidSgn * Npart; - const char* partName = PidChrg[ChistIdx]; - THashList* lhash = static_cast(listEfficiency->FindObject(partName)); + const char* partName = pIdChrg[ChistIdx]; + auto lhash = dynamic_cast(listEfficiency->FindObject(partName)); if (!lhash) { LOG(warning) << "No efficiency object found for particle " << partName; return; } - auto fillEff = [&](const TString eName, auto num, auto den) { - TEfficiency* eff = static_cast(lhash->FindObject(eName)); + auto fillEff = [&](const TString& eName, const auto& num, const auto& den) { + auto eff = dynamic_cast(lhash->FindObject(eName)); if (!eff) { LOG(warning) << "Cannot find TEfficiency " << eName; return; @@ -2426,7 +2417,7 @@ struct FlattenictyPikp { }); static_for<0, 4>([&](auto i) { constexpr int Cidx = i.value; - if (std::fabs(particle.pdgCode()) == PDGs[Cidx]) { + if (std::fabs(particle.pdgCode()) == pDGs[Cidx]) { registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTrecCollPrimSgn), multMC, flatMC, particle.pt()); // Sgn loss num registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTeffGenPrimRecEvt), multRecGt1, flatRec, particle.pt()); // Tracking eff. den } @@ -2485,30 +2476,31 @@ struct FlattenictyPikp { }); static_for<0, 4>([&](auto i) { constexpr int Cidx = i.value; - if (std::sqrt(std::pow(std::fabs(o2::aod::pidutils::tpcNSigma(track)), 2) + std::pow(std::fabs(o2::aod::pidutils::tofNSigma(track)), 2) < trkSelOpt.cfgDcaNsigmaCombinedMax)) { - if (std::fabs(particle.pdgCode()) == PDGs[Cidx]) { - if (!particle.isPhysicalPrimary()) { - if (particle.getProcess() == CprocessIdWeak) { - registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTvsDCAxyWeakAll), multRecGt1, flatRec, track.pt(), track.dcaXY()); - } else { - registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTvsDCAxyMatAll), multRecGt1, flatRec, track.pt(), track.dcaXY()); - } + if (std::fabs(particle.pdgCode()) == pDGs[Cidx]) { + if (!particle.isPhysicalPrimary()) { + if (particle.getProcess() == CprocessIdWeak) { + registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTvsDCAxyWeakAll), multRecGt1, flatRec, track.pt(), track.dcaXY()); } else { - registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTvsDCAxyPrimAll), multRecGt1, flatRec, track.pt(), track.dcaXY()); - registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CdEdxMcRecPrim), track.eta(), multRecGt1, flatRec, track.p(), track.tpcSignal()); + registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTvsDCAxyMatAll), multRecGt1, flatRec, track.pt(), track.dcaXY()); } - registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTvsDCAxyAll), multRecGt1, flatRec, track.pt(), track.dcaXY()); + } else { + registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTvsDCAxyPrimAll), multRecGt1, flatRec, track.pt(), track.dcaXY()); + registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CdEdxMcRecPrim), track.eta(), multRecGt1, flatRec, track.p(), track.tpcSignal()); } + registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTvsDCAxyAll), multRecGt1, flatRec, track.pt(), track.dcaXY()); } }); if (isDCAxyCut(track)) { static_for<0, 4>([&](auto i) { constexpr int Cidx = i.value; - if (std::fabs(particle.pdgCode()) == PDGs[Cidx]) { - if (particle.isPhysicalPrimary()) { - registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CdEdxMcRecPrimSel), track.eta(), multRecGt1, flatRec, track.p(), track.tpcSignal()); - registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTeffPrimRecEvt), multRecGt1, flatRec, track.pt()); // Tracking eff. num - registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTmcClosureRec), multMC, flatMC, track.pt()); // closure + if (std::sqrt(std::pow(std::fabs(o2::aod::pidutils::tpcNSigma(track)), 2) + std::pow(std::fabs(o2::aod::pidutils::tofNSigma(track)), 2) < trkSelOpt.cfgDcaNsigmaCombinedMax)) { + if (std::fabs(particle.pdgCode()) == pDGs[Cidx]) { + if (particle.isPhysicalPrimary()) { + registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CdEdxMcRecPrimSel), track.eta(), multRecGt1, flatRec, track.p(), track.tpcSignal()); + registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CEtaVsPtVsPMcRecPrimSel), track.eta(), track.pt(), track.p()); + registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTeffPrimRecEvt), multRecGt1, flatRec, track.pt()); // Tracking eff. num + registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTmcClosureRec), multMC, flatMC, track.pt()); // closure + } } } }); @@ -2581,7 +2573,7 @@ struct FlattenictyPikp { constexpr int Cidx = i.value; // LOG(debug) << "fillMCGen for pidSgn '" << pidSgn << "' and id '" << static_cast(id) << " with index " << ChistIdx; if (particle.isPhysicalPrimary()) { - if (std::fabs(particle.pdgCode()) == PDGs[Cidx]) { + if (std::fabs(particle.pdgCode()) == pDGs[Cidx]) { registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTgenPrimSgn), multMC, flatMC, particle.pt()); // Sgn loss den registryMC.fill(HIST(Cprefix) + HIST(CspeciesAll[Cidx]) + HIST(CpTmcClosureGenPrim), multMC, flatMC, particle.pt()); // closure } @@ -2590,16 +2582,6 @@ struct FlattenictyPikp { } } PROCESS_SWITCH(FlattenictyPikp, processMC, "process MC", false); - - template - ObjType* getForTsOrRun(std::string const& fullPath, int64_t timestamp, int runNumber) - { - if (cfgUseCcdbForRun) { - return ccdb->getForRun(fullPath, runNumber); - } else { - return ccdb->getForTimeStamp(fullPath, timestamp); - } - } }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx b/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx index c19f5858129..ec8c9ae7471 100644 --- a/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx @@ -1008,7 +1008,7 @@ struct HeavyionMultiplicity { } // collision loop } - void processBcData(soa::Join::iterator const& multbc) + void processBcData(soa::Join::iterator const& multbc) { histos.fill(HIST("BcHist"), 1); // all BCs if (selectCollidingBCs && !multbc.multCollidingBC()) diff --git a/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx b/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx index 0f93e91320f..217eefacd0b 100644 --- a/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/ptmultCorr.cxx @@ -16,19 +16,17 @@ /// \since October 01, 2025 #include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/RCTSelectionFlags.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/McCollisionExtra.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include #include #include #include #include #include -#include #include #include #include @@ -37,11 +35,9 @@ #include #include -#include #include #include -#include #include #include #include @@ -54,12 +50,13 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::aod::track; using namespace o2::aod::evsel; +using namespace o2::aod::rctsel; using ColDataTablePbPb = soa::Join; using ColDataTablepp = soa::Join; using ColMCRecTablePbPb = soa::SmallGroups>; using ColMCRecTablepp = soa::SmallGroups>; -using ColMCTrueTable = soa::Join; +using ColMCTrueTable = soa::Join; using TrackDataTable = soa::Join; using TrackMCRecTable = soa::Join; using TrackMCTrueTable = aod::McParticles; @@ -121,20 +118,18 @@ AxisSpec axisPhi{{0, o2::constants::math::PIQuarter, o2::constants::math::PIHalf AxisSpec axisPhi2{629, 0, o2::constants::math::TwoPI, "#phi"}; AxisSpec axisCent{100, 0, 100, "#Cent"}; AxisSpec axisDeltaPt{50, -1.0, +1.0, "#Delta(pT)"}; -AxisSpec axisDCAxy{100, -3.0, 3.0, "DCA_{xy} (cm)", "DCAxyAxis"}; // range ±3 cm for TPC-only case +AxisSpec axisDCAxy{600, -3.0, 3.0, "DCA_{xy} (cm)", "DCAxyAxis"}; // range ±3 cm for TPC-only case AxisSpec axisGenPtVary = {kGenpTend - 1, +kGenpTbegin + 0.5, +kGenpTend - 0.5, "", "GenpTVaryAxis"}; // axisGenTrkType auto-expands: kGenTrkTypeend is now 8, giving 6 bins (kGenAll … kGenAllCharged) AxisSpec axisGenTrkType = {kGenTrkTypeend - 1, +kGenTrkTypebegin + 0.5, +kGenTrkTypeend - 0.5, "", "GenTrackTypeAxis"}; AxisSpec axisRecTrkType = {kRecTrkTypeend - 1, +kRecTrkTypebegin + 0.5, +kRecTrkTypeend - 0.5, "", "RecTrackTypeAxis"}; AxisSpec axisTrackType = {kTrackTypeend - 1, +kTrackTypebegin + 0.5, +kTrackTypeend - 0.5, "", "TrackTypeAxis"}; auto static constexpr KminCharge = 3.f; -auto static constexpr KminPtCut = 0.1f; struct PtmultCorr { HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; Service pdg; - Service ccdb; Preslice perCollision = aod::track::collisionId; Configurable etaRange{"etaRange", 0.8f, "Eta range to consider"}; Configurable vtxRange{"vtxRange", 10.0f, "Vertex Z range to consider"}; @@ -146,64 +141,49 @@ struct PtmultCorr { Configurable extraphicut3{"extraphicut3", 0.03f, "Extra Phi cut 3"}; Configurable extraphicut4{"extraphicut4", 6.253f, "Extra Phi cut 4"}; - // Track quality cuts (matching piKpRAA analysis) - Configurable cfgMinNClusITS{"cfgMinNClusITS", 7, "Minimum ITS clusters"}; Configurable cfgMinNCrossedRows{"cfgMinNCrossedRows", 70, "Minimum TPC crossed rows"}; - Configurable cfgMinNcls{"cfgMinNcls", 130, "Minimum TPC clusters (applied only if cfgApplyNclSel is true)"}; - Configurable cfgApplyNclSel{"cfgApplyNclSel", true, "Enable minimum TPC cluster selection"}; Configurable cfgUseNclsPID{"cfgUseNclsPID", false, "Use NclsPID instead of NclsFound for the Ncls cut"}; Configurable cfgMinChi2ClsTPC{"cfgMinChi2ClsTPC", 0.5f, "Minimum TPC chi2/cls"}; Configurable cfgMaxChi2ClsTPC{"cfgMaxChi2ClsTPC", 4.0f, "Maximum TPC chi2/cls"}; Configurable cfgMaxChi2ClsITS{"cfgMaxChi2ClsITS", 36.0f, "Maximum ITS chi2/cls"}; - Configurable cfgNSigmaDCAxy{"cfgNSigmaDCAxy", 1.0f, "nSigma scaling for DCAxy cut"}; - Configurable cfgNSigmaDCAz{"cfgNSigmaDCAz", 1.0f, "nSigma scaling for DCAz cut"}; - - // CCDB paths for pT-dependent DCA cuts - Configurable pathDCAxy{"pathDCAxy", "", "CCDB path for DCAxy parametrisation (leave empty to skip)"}; - Configurable pathDCAz{"pathDCAz", "", "CCDB path for DCAz parametrisation (leave empty to skip)"}; - Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable CCDB timestamp"}; + Configurable cfgDCAz{"cfgDCAz", 0.04, "DCAz cut in cm"}; ConfigurableAxis ptHistBin{"ptHistBin", {200, 0., 20.}, ""}; ConfigurableAxis centralityBinning{"centralityBinning", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, ""}; ConfigurableAxis binsImpactPar{"binsImpactPar", {VARIABLE_WIDTH, 0.0, 3.00065, 4.28798, 6.14552, 7.6196, 8.90942, 10.0897, 11.2002, 12.2709, 13.3167, 14.4173, 23.2518}, "Binning of the impact parameter axis"}; - // DCA cache (loaded from CCDB) - struct ConfigDCA { - TH1F* hDCAxy = nullptr; - TH1F* hDCAz = nullptr; - bool loaded = false; - } cfgDCA; - - Configurable isApplySameBunchPileup{"isApplySameBunchPileup", false, "Enable SameBunchPileup cut"}; - Configurable isApplyGoodZvtxFT0vsPV{"isApplyGoodZvtxFT0vsPV", false, "Enable GoodZvtxFT0vsPV cut"}; - Configurable isApplyExtraPhiCut{"isApplyExtraPhiCut", false, "Enable extra phi cut"}; - Configurable isApplyNoCollInTimeRangeStandard{"isApplyNoCollInTimeRangeStandard", true, "Enable NoCollInTimeRangeStandard cut"}; - Configurable isApplyNoCollInRofStandard{"isApplyNoCollInRofStandard", false, "Enable NoCollInRofStandard cut"}; - Configurable isApplyNoHighMultCollInPrevRof{"isApplyNoHighMultCollInPrevRof", false, "Enable NoHighMultCollInPrevRof cut"}; - Configurable isApplyFT0CbasedOccupancy{"isApplyFT0CbasedOccupancy", false, "Enable FT0CbasedOccupancy cut"}; - Configurable isApplyInelgt0{"isApplyInelgt0", false, "Enable INEL > 0 condition"}; - Configurable isApplyOccuCut{"isApplyOccuCut", false, "Enable occupancy selection"}; - - // Secondary estimation related configurables - Configurable isApplyDCACuts{"isApplyDCACuts", false, "Enable DCA cuts (set to false for secondary estimation)"}; - Configurable isApplyITSCuts{"isApplyITSCuts", false, "Enable ITS cuts (set to false for secondary estimation)"}; - Configurable isApplyChi2Cuts{"isApplyChi2Cuts", false, "Enable χ² cuts (set to false for secondary estimation)"}; + Configurable isSameBunchPileup{"isSameBunchPileup", false, "Enable SameBunchPileup cut"}; + Configurable isGoodZvtxFT0vsPV{"isGoodZvtxFT0vsPV", false, "Enable GoodZvtxFT0vsPV cut"}; + Configurable applyExtraPhiCut{"applyExtraPhiCut", false, "Enable extra phi cut"}; + Configurable isNoCollInTimeRangeStandard{"isNoCollInTimeRangeStandard", false, "Enable NoCollInTimeRangeStandard cut"}; + Configurable isNoCollInTimeRangeStrict{"isNoCollInTimeRangeStrict", false, "use isNoCollInTimeRangeStrict?"}; + + Configurable selHasBC{"selHasBC", true, "Require has_foundBC"}; + Configurable selHasFT0{"selHasFT0", true, "Require has_foundFT0"}; + + Configurable isNoCollInRofStandard{"isNoCollInRofStandard", false, "Enable NoCollInRofStandard cut"}; + Configurable isNoCollInRofStrict{"isNoCollInRofStrict", false, "use isNoCollInRofStrict?"}; + + Configurable isNoHighMultCollInPrevRof{"isNoHighMultCollInPrevRof", false, "use isNoHighMultCollInPrevRof?"}; + Configurable isNoCollInTimeRangeNarrow{"isNoCollInTimeRangeNarrow", false, "use isNoCollInTimeRangeNarrow?"}; + + Configurable applyFT0CbasedOccupancy{"applyFT0CbasedOccupancy", false, "Enable FT0CbasedOccupancy cut"}; + Configurable applyInelgt0{"applyInelgt0", true, "Enable INEL > 0 condition"}; + Configurable applyOccuCut{"applyOccuCut", true, "Enable occupancy selection"}; + + Configurable rctLabel{"rctLabel", "CBT_hadronPID", "RCT selection flag"}; + Configurable rctCheckZDC{"rctCheckZDC", false, "Check ZDC in RCT"}; + Configurable rctTreatLimitedAcceptanceAsBad{"rctTreatLimitedAcceptanceAsBad", false, "Treat limited acceptance as bad"}; + Configurable requireGoodRct{"requireGoodRct", true, "Apply RCT selection"}; + + // RCT checker instance + RCTFlagsChecker rctChecker; void init(InitContext const&) { - // Load DCA parametrisations from CCDB (matching piKpRAA) - if (!pathDCAxy.value.empty()) { - cfgDCA.hDCAxy = ccdb->getForTimeStamp(pathDCAxy, ccdbNoLaterThan); - if (cfgDCA.hDCAxy == nullptr) - LOGF(fatal, "Could not load DCAxy histogram from %s", pathDCAxy.value.c_str()); - } - if (!pathDCAz.value.empty()) { - cfgDCA.hDCAz = ccdb->getForTimeStamp(pathDCAz, ccdbNoLaterThan); - if (cfgDCA.hDCAz == nullptr) - LOGF(fatal, "Could not load DCAz histogram from %s", pathDCAz.value.c_str()); - } - if (cfgDCA.hDCAxy && cfgDCA.hDCAz) - cfgDCA.loaded = true; + if (requireGoodRct) { + rctChecker.init(rctLabel.value, rctCheckZDC.value, rctTreatLimitedAcceptanceAsBad.value); + } AxisSpec centAxis = {centralityBinning, "Centrality", "CentralityAxis"}; AxisSpec axisPt = {ptHistBin, "pT", "pTAxis"}; AxisSpec impactParAxis = {binsImpactPar, "Impact Parameter"}; @@ -211,7 +191,6 @@ struct PtmultCorr { histos.add("EventHist", "EventHist", kTH1D, {axisEvent}, false); histos.add("VtxZHist", "VtxZHist", kTH1D, {axisVtxZ}, false); histos.add("CentPercentileHist", "CentPercentileHist", kTH1D, {axisCent}, false); - histos.add("CentPercentileMCRecHist", "CentPercentileMCRecHist", kTH1D, {axisCent}, false); histos.add("PhiVsEtaHistNoCut", "PhiVsEtaHistNoCut", kTH2D, {axisPhi2, axisEta}, false); histos.add("PhiVsEtaHistWithCut", "PhiVsEtaHistWithCut", kTH2D, {axisPhi2, axisEta}, false); @@ -265,20 +244,60 @@ struct PtmultCorr { histos.add("hImpactParameterGen", "Impact parameter of generated MC events", kTH1F, {impactParAxis}); histos.add("hImpactParameterRec", "Impact parameter of selected MC events", kTH1F, {impactParAxis}); histos.add("hImpactParvsCentrRec", "Impact parameter of selected MC events vs centrality", kTH2F, {axisCent, impactParAxis}); + + // CO map: centrality vs generated Nch (for N_rec_at_least_once events) + histos.add("hNchVsCent_WithRecoEvt", "hNchVsCent_WithRecoEvt", + kTH2F, {axisCent, {500, 0, 500, "Gen N_{ch} |#eta|<0.8"}}); + + // Event loss denominator: Nch distribution of all generated events + histos.add("hNchMC_AllGen", "hNchMC_AllGen", + kTH1F, {{500, 0, 500, "Gen N_{ch} |#eta|<0.8"}}); + + // Event loss numerator: Nch distribution of N_rec_at_least_once events + histos.add("hNchMC_WithRecoEvt", "hNchMC_WithRecoEvt", + kTH1F, {{500, 0, 500, "Gen N_{ch} |#eta|<0.8"}}); + + // Event splitting: centrality distributions + histos.add("hCent_WRecoEvtWSelCri", "N_rec_at_least_once (with sel)", kTH1F, {axisCent}); + histos.add("hCent_AllRecoEvt", "N_rec (with sel)", kTH1F, {axisCent}); + + // Signal loss: pT vs Nch (2D), for all gen events and N_rec_at_least_once + histos.add("hPtVsNchMC_AllGen", "hPtVsNchMC_AllGen", + kTH2F, {{axisPt}, {500, 0, 500, "Gen N_{ch} |#eta|<0.8"}}); + histos.add("hPtVsNchMC_WithRecoEvt", "hPtVsNchMC_WithRecoEvt", + kTH2F, {{axisPt}, {500, 0, 500, "Gen N_{ch} |#eta|<0.8"}}); } + if (doprocessEvtLossSigLossMCpp) { + histos.add("hNch_AllRecoEvt", + "All reco collisions passing partial cuts (event split denom pp)", + kTH1F, {{500, 0, 500, "N_{ch} |#eta|<0.8"}}); + histos.add("hNch_WRecoEvtWSelCri", + "Best reco collision passing full selection (event split num pp)", + kTH1F, {{500, 0, 500, "N_{ch} |#eta|<0.8"}}); + } + if (doprocessDatapp || doprocessDataPbPb) { + histos.add("RCTSel", "All=1 | RCT passed=2", kTH1F, {{2, 0.5, 2.5}}); + auto hrct = histos.get(HIST("RCTSel")); + hrct->GetXaxis()->SetBinLabel(1, "All"); + hrct->GetXaxis()->SetBinLabel(2, "RCT passed"); + } auto hstat = histos.get(HIST("EventHist")); auto* x = hstat->GetXaxis(); x->SetBinLabel(1, "All events"); - x->SetBinLabel(2, "sel8"); - x->SetBinLabel(3, "kNoSameBunchPileup"); // reject collisions in case of pileup with another collision in the same foundBC - x->SetBinLabel(4, "kIsGoodZvtxFT0vsPV"); // small difference between z-vertex from PV and from FT0 - x->SetBinLabel(5, "ApplyNoCollInTimeRangeStandard"); - x->SetBinLabel(6, "ApplyNoCollInRofStandard"); - x->SetBinLabel(7, "ApplyNoHighMultCollInPrevRof"); - x->SetBinLabel(8, "INEL > 0"); - x->SetBinLabel(9, "|vz|<10"); - x->SetBinLabel(10, "Occupancy<500"); + x->SetBinLabel(2, "has_foundBC"); + x->SetBinLabel(3, "has_foundFT0"); + x->SetBinLabel(4, "kIsTriggerTVX"); + x->SetBinLabel(5, "kNoITSROFrameBorder"); + x->SetBinLabel(6, "kNoTimeFrameBorder"); + x->SetBinLabel(7, "|vz|SetBinLabel(8, "kIsGoodZvtxFT0vsPV"); + x->SetBinLabel(9, "kNoSameBunchPileup"); + x->SetBinLabel(10, "kNoCollInTimeRangeStrict"); + x->SetBinLabel(11, "kNoCollInRofStrict"); + x->SetBinLabel(12, "kNoHighMultCollInPrevRof"); + x->SetBinLabel(13, "INEL>0"); + x->SetBinLabel(14, "Occupancy"); } template @@ -286,51 +305,74 @@ struct PtmultCorr { { histos.fill(HIST("EventHist"), 1); - if (!col.sel8()) { + if (selHasBC && !col.has_foundBC()) return false; - } - histos.fill(HIST("EventHist"), 2); - - if (isApplySameBunchPileup && !col.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + if (selHasFT0 && !col.has_foundFT0()) return false; - } - histos.fill(HIST("EventHist"), 3); - if (isApplyGoodZvtxFT0vsPV && !col.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + // TVX trigger (replaces sel8 as primary trigger requirement) + if (!col.selection_bit(o2::aod::evsel::kIsTriggerTVX)) return false; - } histos.fill(HIST("EventHist"), 4); - if (isApplyNoCollInTimeRangeStandard && !col.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + // ITS ROF border + if (!col.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) return false; - } histos.fill(HIST("EventHist"), 5); - if (isApplyNoCollInRofStandard && !col.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + // Time frame border + if (!col.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) return false; - } histos.fill(HIST("EventHist"), 6); - if (isApplyNoHighMultCollInPrevRof && !col.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + // vtxZ + if (std::abs(col.posZ()) > vtxRange) return false; - } histos.fill(HIST("EventHist"), 7); - if (isApplyInelgt0 && !col.isInelGt0()) { + // Good ZvtxFT0vsPV + if (isGoodZvtxFT0vsPV && + !col.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) return false; - } histos.fill(HIST("EventHist"), 8); - if (std::abs(col.posZ()) >= vtxRange) { + // No same bunch pileup + if (isSameBunchPileup && + !col.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) return false; - } histos.fill(HIST("EventHist"), 9); - auto occu = isApplyFT0CbasedOccupancy ? col.ft0cOccupancyInTimeRange() : col.trackOccupancyInTimeRange(); - if (isApplyOccuCut && occu > occuRange) { + // Time range isolation — Strict (replaces Standard) + if (isNoCollInTimeRangeStrict && + !col.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) return false; - } histos.fill(HIST("EventHist"), 10); + + // ROF isolation — Strict (replaces Standard) + if (isNoCollInRofStrict && + !col.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) + return false; + histos.fill(HIST("EventHist"), 11); + + // No high mult collision in previous ROF + if (isNoHighMultCollInPrevRof && + !col.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) + return false; + histos.fill(HIST("EventHist"), 12); + + // INEL > 0 + if (applyInelgt0 && !col.isInelGt0()) + return false; + histos.fill(HIST("EventHist"), 13); + + // Occupancy + auto occu = applyFT0CbasedOccupancy + ? col.ft0cOccupancyInTimeRange() + : col.trackOccupancyInTimeRange(); + if (applyOccuCut && occu > occuRange) + return false; + histos.fill(HIST("EventHist"), 14); + return true; } @@ -347,61 +389,33 @@ struct PtmultCorr { return false; } - if (track.hasTPC()) { - // ---- Global (ITS+TPC) tracks: + // ITS inner-barrel hit: must fire layer 0 or layer 1 + if (!(track.itsClusterMap() & 0x01) && !(track.itsClusterMap() & 0x02)) { + return false; + } - // ITS cuts: can be disabled for secondary estimation - if (isApplyITSCuts) { - // ITS inner-barrel hit: must fire layer 0 or layer 1 - if (!(track.itsClusterMap() & 0x01) && !(track.itsClusterMap() & 0x02)) { - return false; - } - if (track.itsNCls() < cfgMinNClusITS) { - return false; - } - // ITS chi2 cut (also part of ITS cuts) - if (track.itsChi2NCl() > cfgMaxChi2ClsITS) { - return false; - } - } + // ITS chi2 cut (also part of ITS cuts) + if (track.itsChi2NCl() > cfgMaxChi2ClsITS) { + return false; + } + + if (track.hasTPC()) { - // TPC quality cuts (always applied) if (track.tpcNClsCrossedRows() < cfgMinNCrossedRows) { return false; } - // optional minimum TPC clusters (found or PID, matching piKpRAA applyNclSel) - if (cfgApplyNclSel) { - const int16_t ncl = cfgUseNclsPID ? track.tpcNClsPID() : track.tpcNClsFound(); - if (ncl < cfgMinNcls) { - return false; - } - } - // --- χ² cuts (can be disabled for secondary estimation) --- - if (isApplyChi2Cuts) { - if (track.tpcChi2NCl() < cfgMinChi2ClsTPC || track.tpcChi2NCl() > cfgMaxChi2ClsTPC) { - return false; - } - } - - // pT-dependent DCA cuts (can be disabled for secondary estimation) - if (isApplyDCACuts && cfgDCA.loaded) { - const float pt = track.pt(); - const double dcaXYcut = cfgNSigmaDCAxy * (cfgDCA.hDCAxy->GetBinContent(1) + - cfgDCA.hDCAxy->GetBinContent(2) / - std::pow(std::abs(pt), cfgDCA.hDCAxy->GetBinContent(3))); - const double dcaZcut = cfgNSigmaDCAz * (cfgDCA.hDCAz->GetBinContent(1) + - cfgDCA.hDCAz->GetBinContent(2) / - std::pow(std::abs(pt), cfgDCA.hDCAz->GetBinContent(3))); - if (std::abs(track.dcaZ()) > dcaZcut || std::abs(track.dcaXY()) > dcaXYcut) { - return false; - } + if (track.tpcChi2NCl() < cfgMinChi2ClsTPC || track.tpcChi2NCl() > cfgMaxChi2ClsTPC) { + return false; } } + if (std::abs(track.dcaZ()) > cfgDCAz) + return false; + // --- optional phi cut (applied to all track types) --- histos.fill(HIST("PhiVsEtaHistNoCut"), track.phi(), track.eta()); - if (isApplyExtraPhiCut && ((track.phi() > extraphicut1 && track.phi() < extraphicut2) || track.phi() <= extraphicut3 || track.phi() >= extraphicut4)) { + if (applyExtraPhiCut && ((track.phi() > extraphicut1 && track.phi() < extraphicut2) || track.phi() <= extraphicut3 || track.phi() >= extraphicut4)) { return false; } histos.fill(HIST("PhiVsEtaHistWithCut"), track.phi(), track.eta()); @@ -417,7 +431,7 @@ struct PtmultCorr { if (!track.isPhysicalPrimary()) { return false; } - if (!track.producedByGenerator()) { + if (track.pt() < cfgPtCutMin || track.pt() > cfgPtCutMax) { return false; } auto pdgTrack = pdg->GetParticle(track.pdgCode()); @@ -430,7 +444,7 @@ struct PtmultCorr { if (std::abs(track.eta()) >= etaRange) { return false; } - if (isApplyExtraPhiCut && ((track.phi() > extraphicut1 && track.phi() < extraphicut2) || track.phi() <= extraphicut3 || track.phi() >= extraphicut4)) { + if (applyExtraPhiCut && ((track.phi() > extraphicut1 && track.phi() < extraphicut2) || track.phi() <= extraphicut3 || track.phi() >= extraphicut4)) { return false; } return true; @@ -445,7 +459,7 @@ struct PtmultCorr { template bool isGenChargedTrackSelected(CheckGenTrack const& track) { - if (!track.producedByGenerator()) { + if (track.pt() < cfgPtCutMin || track.pt() > cfgPtCutMax) { return false; } auto pdgTrack = pdg->GetParticle(track.pdgCode()); @@ -458,7 +472,7 @@ struct PtmultCorr { if (std::abs(track.eta()) >= etaRange) { return false; } - if (isApplyExtraPhiCut && ((track.phi() > extraphicut1 && track.phi() < extraphicut2) || track.phi() <= extraphicut3 || track.phi() >= extraphicut4)) { + if (applyExtraPhiCut && ((track.phi() > extraphicut1 && track.phi() < extraphicut2) || track.phi() <= extraphicut3 || track.phi() >= extraphicut4)) { return false; } return true; @@ -466,6 +480,12 @@ struct PtmultCorr { void processDataPbPb(ColDataTablePbPb::iterator const& cols, TrackDataTable const& tracks) { + if (requireGoodRct) { + histos.fill(HIST("RCTSel"), 1); // all events + if (!rctChecker(cols)) + return; + histos.fill(HIST("RCTSel"), 2); // passed RCT + } if (!isEventSelected(cols)) { return; } @@ -488,6 +508,12 @@ struct PtmultCorr { void processDatapp(ColDataTablepp::iterator const& cols, TrackDataTable const& tracks) { + if (requireGoodRct) { + histos.fill(HIST("RCTSel"), 1); // all events + if (!rctChecker(cols)) + return; + histos.fill(HIST("RCTSel"), 2); // passed RCT + } if (!isEventSelected(cols)) { return; } @@ -508,15 +534,25 @@ struct PtmultCorr { void processMCeffPbPb(ColMCTrueTable::iterator const& mcCollision, ColMCRecTablePbPb const& RecCols, TrackMCTrueTable const& GenParticles, TrackMCRecTable const& RecTracks) { - auto gencent = -999; + float gencent = -999.f; bool atLeastOne = false; + int bestCollisionIndex = -1; + int biggestNContribs = -1; for (const auto& RecCol : RecCols) { + if (biggestNContribs < RecCol.numContrib()) { + biggestNContribs = RecCol.numContrib(); + bestCollisionIndex = RecCol.globalIndex(); + } + } + for (const auto& RecCol : RecCols) { + if (!isEventSelected(RecCol)) { continue; } - if (RecCol.globalIndex() != mcCollision.bestCollisionIndex()) { + + if (RecCol.globalIndex() != bestCollisionIndex) continue; - } + atLeastOne = true; gencent = RecCol.centFT0C(); } @@ -556,7 +592,7 @@ struct PtmultCorr { histos.fill(HIST("hPbPbGenMCdndpt"), mcCollision.posZ(), gencent, particle.pt(), particle.phi()); if (atLeastOne) { histos.fill(HIST("hPbPbGenMCAssoRecdndpt"), mcCollision.posZ(), gencent, particle.pt(), particle.phi(), static_cast(kGenAll), kNoGenpTVar); - if (particle.pt() < KminPtCut) { + if (particle.pt() < cfgPtCutMin) { histos.fill(HIST("hPbPbGenMCAssoRecdndpt"), mcCollision.posZ(), gencent, particle.pt(), particle.phi(), static_cast(kGenAll), kGenpTup, -10.0 * particle.pt() + 2); histos.fill(HIST("hPbPbGenMCAssoRecdndpt"), mcCollision.posZ(), gencent, particle.pt(), particle.phi(), static_cast(kGenAll), kGenpTdown, 5.0 * particle.pt() + 0.5); } else { @@ -583,12 +619,14 @@ struct PtmultCorr { } // track (mcgen) loop for (const auto& RecCol : RecCols) { + if (!isEventSelected(RecCol)) { continue; } - if (RecCol.globalIndex() != mcCollision.bestCollisionIndex()) { + + if (RecCol.globalIndex() != bestCollisionIndex) continue; - } + histos.fill(HIST("hPbPbRecMCvtxz"), RecCol.posZ()); histos.fill(HIST("hPbPbRecMCcent"), RecCol.centFT0C()); histos.fill(HIST("hPbPbRecMCvtxzcent"), RecCol.posZ(), RecCol.centFT0C()); @@ -652,13 +690,23 @@ struct PtmultCorr { void processMCeffpp(ColMCTrueTable::iterator const& mcCollision, ColMCRecTablepp const& RecCols, TrackMCTrueTable const& GenParticles, TrackMCRecTable const& RecTracks) { bool atLeastOne = false; + int bestCollisionIndex = -1; + int biggestNContribs = -1; for (const auto& RecCol : RecCols) { + if (biggestNContribs < RecCol.numContrib()) { + biggestNContribs = RecCol.numContrib(); + bestCollisionIndex = RecCol.globalIndex(); + } + } + for (const auto& RecCol : RecCols) { + if (!isEventSelected(RecCol)) { continue; } - if (RecCol.globalIndex() != mcCollision.bestCollisionIndex()) { + + if (RecCol.globalIndex() != bestCollisionIndex) continue; - } + atLeastOne = true; } histos.fill(HIST("hppGenMCvtxz"), mcCollision.posZ()); @@ -695,7 +743,7 @@ struct PtmultCorr { histos.fill(HIST("hppGenMCdndpt"), mcCollision.posZ(), particle.pt(), particle.phi()); if (atLeastOne) { histos.fill(HIST("hppGenMCAssoRecdndpt"), mcCollision.posZ(), particle.pt(), particle.phi(), static_cast(kGenAll), kNoGenpTVar); - if (particle.pt() < KminPtCut) { + if (particle.pt() < cfgPtCutMin) { histos.fill(HIST("hppGenMCAssoRecdndpt"), mcCollision.posZ(), particle.pt(), particle.phi(), static_cast(kGenAll), kGenpTup, -10.0 * particle.pt() + 2); histos.fill(HIST("hppGenMCAssoRecdndpt"), mcCollision.posZ(), particle.pt(), particle.phi(), static_cast(kGenAll), kGenpTdown, 5.0 * particle.pt() + 0.5); } else { @@ -722,12 +770,14 @@ struct PtmultCorr { } // track (mcgen) loop for (const auto& RecCol : RecCols) { + if (!isEventSelected(RecCol)) { continue; } - if (RecCol.globalIndex() != mcCollision.bestCollisionIndex()) { + + if (RecCol.globalIndex() != bestCollisionIndex) continue; - } + histos.fill(HIST("hppRecMCvtxz"), RecCol.posZ()); auto recTracksPart = RecTracks.sliceBy(perCollision, RecCol.globalIndex()); std::vector mclabels; @@ -784,37 +834,87 @@ struct PtmultCorr { } // collision loop } - void processEvtLossSigLossMCpp(ColMCTrueTable::iterator const& mcCollision, ColMCRecTablepp const& RecCols, TrackMCTrueTable const& GenParticles) + void processEvtLossSigLossMCpp(ColMCTrueTable::iterator const& /*mcCollision*/, ColMCRecTablepp const& RecCols, TrackMCTrueTable const& GenParticles) { - if (isApplyInelgt0 && !mcCollision.isInelGt0()) { - return; + + // ── Count generated Nch in |eta| < etaRange for event loss ────────────── + int nChMC = 0; + for (const auto& particle : GenParticles) { + if (!particle.isPhysicalPrimary()) + continue; + auto pdgParticle = pdg->GetParticle(particle.pdgCode()); + if (!pdgParticle) + continue; + if (std::abs(pdgParticle->Charge()) < KminCharge) + continue; + if (std::abs(particle.eta()) < etaRange) + nChMC++; } - if (std::abs(mcCollision.posZ()) >= vtxRange) { - return; + + for (const auto& RecCol : RecCols) { + if (!RecCol.has_foundBC()) + continue; + if (!RecCol.has_foundFT0()) + continue; + if (!RecCol.selection_bit(o2::aod::evsel::kIsTriggerTVX)) + continue; + if (!RecCol.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) + continue; + if (!RecCol.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) + continue; + if (std::fabs(RecCol.posZ()) > vtxRange) + continue; + if (isGoodZvtxFT0vsPV && + !RecCol.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + continue; + if (isSameBunchPileup && + !RecCol.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + continue; + + histos.fill(HIST("hNch_AllRecoEvt"), nChMC); // denominator for event splitting } + + // ── Find best collision, apply full selection ──────────────────────────── + // isEventSelected() first, bestCollisionIndex filter second + // matches processMCeffpp cut order bool atLeastOne = false; + int bestCollisionIndex = -1; + int biggestNContribs = -1; for (const auto& RecCol : RecCols) { - if (!isEventSelected(RecCol)) { - continue; + if (biggestNContribs < RecCol.numContrib()) { + biggestNContribs = RecCol.numContrib(); + bestCollisionIndex = RecCol.globalIndex(); } - if (RecCol.globalIndex() != mcCollision.bestCollisionIndex()) { + } + for (const auto& RecCol : RecCols) { + if (!isEventSelected(RecCol)) + continue; + + if (RecCol.globalIndex() != bestCollisionIndex) continue; - } atLeastOne = true; + histos.fill(HIST("hNch_WRecoEvtWSelCri"), nChMC); // numerator for event splitting } - // All generated events + + // ── Event loss histograms ──────────────────────────────────────────────── histos.fill(HIST("MCEventHist"), 1); + histos.fill(HIST("hNchMC_AllGen"), nChMC); // denominator for event loss + if (atLeastOne) { histos.fill(HIST("MCEventHist"), 2); + histos.fill(HIST("hNchMC_WithRecoEvt"), nChMC); // numerator for event loss } + + // ── Signal loss particle loop ──────────────────────────────────────────── for (const auto& particle : GenParticles) { - if (!isGenTrackSelected(particle)) { + if (!isGenTrackSelected(particle)) continue; - } - // All generated particles + + histos.fill(HIST("hPtVsNchMC_AllGen"), particle.pt(), nChMC); // denominator: all generated events histos.fill(HIST("hgenptBeforeEvtSel"), particle.pt()); + if (atLeastOne) { - // All generated particles with at least one reconstructed collision (signal loss estimation) + histos.fill(HIST("hPtVsNchMC_WithRecoEvt"), particle.pt(), nChMC); // numerator: ≥1 reco collision passing selection histos.fill(HIST("hgenptAfterEvtSel"), particle.pt()); } } @@ -822,40 +922,92 @@ struct PtmultCorr { void processEvtLossSigLossMCPbPb(ColMCTrueTable::iterator const& mcCollision, ColMCRecTablePbPb const& RecCols, TrackMCTrueTable const& GenParticles) { - if (isApplyInelgt0 && !mcCollision.isInelGt0()) { - return; + // ── Count generated Nch in |eta| < etaRange for event loss ────────────── + int nChMC = 0; + for (const auto& particle : GenParticles) { + if (!particle.isPhysicalPrimary()) + continue; + auto pdgParticle = pdg->GetParticle(particle.pdgCode()); + if (!pdgParticle) + continue; + if (std::abs(pdgParticle->Charge()) < KminCharge) + continue; + if (std::abs(particle.eta()) < etaRange) + nChMC++; } - if (std::abs(mcCollision.posZ()) >= vtxRange) { - return; + + // ── Event splitting denominator ────────────────────────────────────────── + + for (const auto& RecCol : RecCols) { + if (!RecCol.has_foundBC()) + continue; + if (!RecCol.has_foundFT0()) + continue; + if (!RecCol.selection_bit(o2::aod::evsel::kIsTriggerTVX)) + continue; + if (!RecCol.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) + continue; + if (!RecCol.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) + continue; + if (std::fabs(RecCol.posZ()) > vtxRange) + continue; + if (isGoodZvtxFT0vsPV && + !RecCol.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + continue; + if (isSameBunchPileup && + !RecCol.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + continue; + + histos.fill(HIST("hCent_AllRecoEvt"), RecCol.centFT0C()); // denominator for event splitting } + + // ── Find best collision, apply full selection ──────────────────────────── + // isEventSelected() first, bestCollisionIndex filter second + // matches processMCeffPbPb cut order bool atLeastOne = false; - auto centrality = -999.; + int bestCollisionIndex = -1; + int biggestNContribs = -1; for (const auto& RecCol : RecCols) { - if (!isEventSelected(RecCol)) { - continue; + if (biggestNContribs < RecCol.numContrib()) { + biggestNContribs = RecCol.numContrib(); + bestCollisionIndex = RecCol.globalIndex(); } - if (RecCol.globalIndex() != mcCollision.bestCollisionIndex()) { + } + auto centrality = -999.f; + for (const auto& RecCol : RecCols) { + if (!isEventSelected(RecCol)) + continue; + + if (RecCol.globalIndex() != bestCollisionIndex) continue; - } - centrality = RecCol.centFT0C(); atLeastOne = true; + centrality = RecCol.centFT0C(); + histos.fill(HIST("hCent_WRecoEvtWSelCri"), RecCol.centFT0C()); // numerator for event splitting } - // All generated events + + // ── Event loss histograms ──────────────────────────────────────────────── histos.fill(HIST("MCEventHist"), 1); histos.fill(HIST("hImpactParameterGen"), mcCollision.impactParameter()); + histos.fill(HIST("hNchMC_AllGen"), nChMC); // denominator for event loss + if (atLeastOne) { histos.fill(HIST("MCEventHist"), 2); histos.fill(HIST("hImpactParameterRec"), mcCollision.impactParameter()); histos.fill(HIST("hImpactParvsCentrRec"), centrality, mcCollision.impactParameter()); + histos.fill(HIST("hNchMC_WithRecoEvt"), nChMC); // numerator for event loss + histos.fill(HIST("hNchVsCent_WithRecoEvt"), centrality, nChMC); // CO map } + + // ── Signal loss particle loop ──────────────────────────────────────────── for (const auto& particle : GenParticles) { - if (!isGenTrackSelected(particle)) { + if (!isGenTrackSelected(particle)) continue; - } - // All generated particles + + histos.fill(HIST("hPtVsNchMC_AllGen"), particle.pt(), nChMC); // denominator: all generated events histos.fill(HIST("hgenptBeforeEvtSelPbPb"), particle.pt(), mcCollision.impactParameter()); + if (atLeastOne) { - // All generated particles with at least one reconstructed collision (signal loss estimation) + histos.fill(HIST("hPtVsNchMC_WithRecoEvt"), particle.pt(), nChMC); // numerator: ≥1 reco collision passing selection histos.fill(HIST("hgenptAfterEvtSelPbPb"), particle.pt(), mcCollision.impactParameter()); } } diff --git a/PWGLF/Tasks/Nuspex/antinucleiInJets.cxx b/PWGLF/Tasks/Nuspex/antinucleiInJets.cxx index 8b863f01b08..f2b28bd38bb 100644 --- a/PWGLF/Tasks/Nuspex/antinucleiInJets.cxx +++ b/PWGLF/Tasks/Nuspex/antinucleiInJets.cxx @@ -392,6 +392,10 @@ struct AntinucleiInJets { registryMC.add("antiproton_gen_ue", "antiproton_gen_ue", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); registryMC.add("antiproton_gen_full", "antiproton_gen_full", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + // Generated spectra of antideuterons + registryMC.add("antideuteron_gen_jet", "antideuteron_gen_jet", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_gen_ue", "antideuteron_gen_ue", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + // Generated spectra of antiprotons for closure test registryMC.add("antiproton_gen_jet_data", "antiproton_gen_jet_data", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); registryMC.add("antiproton_gen_ue_data", "antiproton_gen_ue_data", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); @@ -425,6 +429,12 @@ struct AntinucleiInJets { registryMC.add("antiproton_rec_tpc_full", "antiproton_rec_tpc_full", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); registryMC.add("antiproton_rec_tof_full", "antiproton_rec_tof_full", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + // Reconstructed spectra of antideuterons + registryMC.add("antideuteron_rec_tpc_jet", "antideuteron_rec_tpc_jet", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_rec_tof_jet", "antideuteron_rec_tof_jet", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_rec_tpc_ue", "antideuteron_rec_tpc_ue", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_rec_tof_ue", "antideuteron_rec_tof_ue", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + // Reconstructed spectra of antiprotons for closure test registryMC.add("antiproton_rec_tpc_jet_data", "antiproton_rec_tpc_jet_data", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); registryMC.add("antiproton_rec_tof_jet_data", "antiproton_rec_tof_jet_data", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); @@ -464,8 +474,8 @@ struct AntinucleiInJets { // Generated spectra of (anti)deuterons registryMC.add("deuteron_gen_jet", "deuteron_gen_jet", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); registryMC.add("deuteron_gen_ue", "deuteron_gen_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antideuteron_gen_jet", "antideuteron_gen_jet", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antideuteron_gen_ue", "antideuteron_gen_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuterons_gen_jet", "antideuterons_gen_jet", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuterons_gen_ue", "antideuterons_gen_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); // Generated spectra of (anti)helium3 registryMC.add("helium3_gen_jet", "helium3_gen_jet", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); @@ -484,10 +494,10 @@ struct AntinucleiInJets { registryMC.add("deuteron_rec_tof_jet", "deuteron_rec_tof_jet", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); registryMC.add("deuteron_rec_tpc_ue", "deuteron_rec_tpc_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); registryMC.add("deuteron_rec_tof_ue", "deuteron_rec_tof_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antideuteron_rec_tpc_jet", "antideuteron_rec_tpc_jet", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antideuteron_rec_tof_jet", "antideuteron_rec_tof_jet", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antideuteron_rec_tpc_ue", "antideuteron_rec_tpc_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antideuteron_rec_tof_ue", "antideuteron_rec_tof_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuterons_rec_tpc_jet", "antideuterons_rec_tpc_jet", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuterons_rec_tof_jet", "antideuterons_rec_tof_jet", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuterons_rec_tpc_ue", "antideuterons_rec_tpc_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuterons_rec_tof_ue", "antideuterons_rec_tof_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); // Reconstructed spectra of (anti)helium3 registryMC.add("helium3_rec_tpc_jet", "helium3_rec_tpc_jet", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); @@ -735,9 +745,9 @@ struct AntinucleiInJets { // Check if particle is a physical primary or a decay product of a heavy-flavor hadron bool isPhysicalPrimaryOrFromHF(aod::McParticle const& particle, aod::McParticles const& mcParticles) { - // Keep only pi, K, p, e, mu + // Keep only pi, K, p, d, e, mu int pdg = std::abs(particle.pdgCode()); - if (!(pdg == PDG_t::kPiPlus || pdg == PDG_t::kKPlus || pdg == PDG_t::kProton || pdg == PDG_t::kElectron || pdg == PDG_t::kMuonMinus)) + if (!(pdg == PDG_t::kPiPlus || pdg == PDG_t::kKPlus || pdg == PDG_t::kProton || pdg == o2::constants::physics::Pdg::kDeuteron || pdg == PDG_t::kElectron || pdg == PDG_t::kMuonMinus)) return false; // Constants for identifying heavy-flavor (charm and bottom) content from PDG codes @@ -1750,8 +1760,8 @@ struct AntinucleiInJets { registryMC.fill(HIST("deuteron_gen_ue"), particle.pt()); break; case -o2::constants::physics::Pdg::kDeuteron: - registryMC.fill(HIST("antideuteron_gen_jet"), particle.pt()); - registryMC.fill(HIST("antideuteron_gen_ue"), particle.pt()); + registryMC.fill(HIST("antideuterons_gen_jet"), particle.pt()); + registryMC.fill(HIST("antideuterons_gen_ue"), particle.pt()); break; case o2::constants::physics::Pdg::kHelium3: registryMC.fill(HIST("helium3_gen_jet"), particle.pt()); @@ -1982,12 +1992,12 @@ struct AntinucleiInJets { // Fill histograms of antideuterons if (track.sign() < 0 && particle.pdgCode() == -o2::constants::physics::Pdg::kDeuteron && passedItsPidDeut) { if (nsigmaTPCDe > minNsigmaTpc && nsigmaTPCDe < maxNsigmaTpc) { - registryMC.fill(HIST("antideuteron_rec_tpc_jet"), track.pt()); - registryMC.fill(HIST("antideuteron_rec_tpc_ue"), track.pt()); + registryMC.fill(HIST("antideuterons_rec_tpc_jet"), track.pt()); + registryMC.fill(HIST("antideuterons_rec_tpc_ue"), track.pt()); if (track.hasTOF() && nsigmaTOFDe > minNsigmaTof && nsigmaTOFDe < maxNsigmaTof) { - registryMC.fill(HIST("antideuteron_rec_tof_jet"), track.pt()); - registryMC.fill(HIST("antideuteron_rec_tof_ue"), track.pt()); + registryMC.fill(HIST("antideuterons_rec_tof_jet"), track.pt()); + registryMC.fill(HIST("antideuterons_rec_tof_ue"), track.pt()); } } } @@ -2030,6 +2040,7 @@ struct AntinucleiInJets { // Define per-event particle containers std::vector fjParticles; std::vector protonMomentum; + std::vector deuteronMomentum; // Event counter int eventCounter = 0; @@ -2047,6 +2058,7 @@ struct AntinucleiInJets { // Clear containers at the start of the event loop fjParticles.clear(); protonMomentum.clear(); + deuteronMomentum.clear(); // Event counter: before event selection registryMC.fill(HIST("genEvents"), 0.5); @@ -2084,6 +2096,12 @@ struct AntinucleiInJets { registryMC.fill(HIST("antiproton_gen_full"), particle.pt()); } + // Store 3-momentum vectors of antideuterons for further analysis + if (particle.pdgCode() == -o2::constants::physics::Pdg::kDeuteron) { + TVector3 pVec(particle.px(), particle.py(), particle.pz()); + deuteronMomentum.emplace_back(pVec); + } + // 4-momentum representation of a particle double energy = std::sqrt(particle.p() * particle.p() + MassPionCharged * MassPionCharged); fastjet::PseudoJet fourMomentum(particle.px(), particle.py(), particle.pz(), energy); @@ -2133,34 +2151,45 @@ struct AntinucleiInJets { // Analyze jet constituents std::vector jetConstituents = jet.constituents(); for (const auto& particle : jetConstituents) { - if (particle.user_index() != PDG_t::kProtonBar) - continue; + // Particle selection based on PDG + bool isAntip = particle.user_index() == PDG_t::kProtonBar; + bool isAntid = particle.user_index() == -o2::constants::physics::Pdg::kDeuteron; + + // Pseudorapidity selection if (particle.eta() < minEta || particle.eta() > maxEta) continue; - // Fill normalization histogram - registryMC.fill(HIST("antiproton_deltay_deltaphi_jet"), particle.eta() - jet.eta(), getDeltaPhi(particle.phi(), jet.phi())); + // Fill antiproton spectra + if (isAntip) { + // Fill normalization histogram + registryMC.fill(HIST("antiproton_deltay_deltaphi_jet"), particle.eta() - jet.eta(), getDeltaPhi(particle.phi(), jet.phi())); - // Calculate weight - double weightJet(1.0); - if (applyReweighting && particle.pt() < antiprotonsInsideJets->GetXaxis()->GetXmax()) { - int ipt = antiprotonsInsideJets->FindBin(particle.pt()); - weightJet = antiprotonsInsideJets->GetBinContent(ipt); - } + // Calculate weight + double weightJet(1.0); + if (applyReweighting && particle.pt() < antiprotonsInsideJets->GetXaxis()->GetXmax()) { + int ipt = antiprotonsInsideJets->FindBin(particle.pt()); + weightJet = antiprotonsInsideJets->GetBinContent(ipt); + } - // Fill histogram for generated antiprotons - registryMC.fill(HIST("antiproton_gen_jet"), particle.pt(), weightJet); + // Fill histogram for generated antiprotons + registryMC.fill(HIST("antiproton_gen_jet"), particle.pt(), weightJet); - // Fill histograms for generated antiprotons for closure test - if (isPseudoData) { - registryMC.fill(HIST("antiproton_gen_jet_data"), particle.pt()); - } else { - registryMC.fill(HIST("antiproton_gen_jet_mc"), particle.pt()); - } + // Fill histograms for generated antiprotons for closure test + if (isPseudoData) { + registryMC.fill(HIST("antiproton_gen_jet_data"), particle.pt()); + } else { + registryMC.fill(HIST("antiproton_gen_jet_mc"), particle.pt()); + } - // Fill 2d (pt,eta) distribution of antiprotons - registryMC.fill(HIST("antiproton_eta_pt_jet"), particle.pt(), particle.eta(), weightJet); + // Fill 2d (pt,eta) distribution of antiprotons + registryMC.fill(HIST("antiproton_eta_pt_jet"), particle.pt(), particle.eta(), weightJet); + } // end if antip + + // Fill antideuteron spectra + if (isAntid) { + registryMC.fill(HIST("antideuteron_gen_jet"), particle.pt()); + } } // Set up two perpendicular cone axes for underlying event estimation @@ -2171,7 +2200,7 @@ struct AntinucleiInJets { continue; } - // Loop over MC particles to analyze underlying event region + // Loop over antiprotons to analyze underlying event region for (const auto& protonVec : protonMomentum) { // Compute distance of particle from both perpendicular cone axes @@ -2210,6 +2239,25 @@ struct AntinucleiInJets { // Fill 2d (pt,eta) distribution of antiprotons registryMC.fill(HIST("antiproton_eta_pt_ue"), protonVec.Pt(), protonVec.Eta(), weightUe); } + + // Loop over antideuterons to analyze underlying event region + for (const auto& deuteronVec : deuteronMomentum) { + + // Compute distance of particle from both perpendicular cone axes + double deltaEtaUe1 = deuteronVec.Eta() - ueAxis1.Eta(); + double deltaPhiUe1 = getDeltaPhi(deuteronVec.Phi(), ueAxis1.Phi()); + double deltaRUe1 = std::sqrt(deltaEtaUe1 * deltaEtaUe1 + deltaPhiUe1 * deltaPhiUe1); + double deltaEtaUe2 = deuteronVec.Eta() - ueAxis2.Eta(); + double deltaPhiUe2 = getDeltaPhi(deuteronVec.Phi(), ueAxis2.Phi()); + double deltaRUe2 = std::sqrt(deltaEtaUe2 * deltaEtaUe2 + deltaPhiUe2 * deltaPhiUe2); + + // Reject tracks that lie outside the maxConeRadius from both UE axes + if (deltaRUe1 > rJet && deltaRUe2 > rJet) + continue; + + // Fill histogram for antideuterons in the UE + registryMC.fill(HIST("antideuteron_gen_ue"), deuteronVec.Pt()); + } } if (isAtLeastOneJetSelected) { registryMC.fill(HIST("genEvents"), 3.5); @@ -2235,6 +2283,7 @@ struct AntinucleiInJets { // Define per-event containers std::vector fjParticles; std::vector antiprotonTrackIndex; + std::vector antideuteronTrackIndex; // Jet and area definitions fastjet::JetDefinition jetDef(fastjet::antikt_algorithm, rJet); @@ -2255,6 +2304,7 @@ struct AntinucleiInJets { // Clear containers at the start of the event loop fjParticles.clear(); antiprotonTrackIndex.clear(); + antideuteronTrackIndex.clear(); // Event counter: before event selection registryMC.fill(HIST("recEvents"), 0.5); @@ -2331,6 +2381,11 @@ struct AntinucleiInJets { } } + // Store track index for antideuteron tracks + if (passedTrackSelection(track) && track.sign() < 0 && mcparticle.pdgCode() == -o2::constants::physics::Pdg::kDeuteron) { + antideuteronTrackIndex.emplace_back(id); + } + // Apply track selection for jet reconstruction if (!passedTrackSelectionForJetReconstruction(track)) continue; @@ -2408,6 +2463,8 @@ struct AntinucleiInJets { // Define variables double nsigmaTPCPr = track.tpcNSigmaPr(); double nsigmaTOFPr = track.tofNSigmaPr(); + double nsigmaTPCDe = track.tpcNSigmaDe(); + double nsigmaTOFDe = track.tofNSigmaDe(); double pt = track.pt(); double dcaxy = track.dcaXY(); double dcaz = track.dcaZ(); @@ -2417,71 +2474,94 @@ struct AntinucleiInJets { registryMC.fill(HIST("antiproton_nsigma_tof_jet_mc"), pt, nsigmaTOFPr); } - // Antiproton selection based on the PDG - if (mcparticle.pdgCode() != PDG_t::kProtonBar) - continue; + // Particle selection based on PDG + bool isAntip = mcparticle.pdgCode() == PDG_t::kProtonBar; + bool isAntid = mcparticle.pdgCode() == -o2::constants::physics::Pdg::kDeuteron; - // Fill DCA templates - if (std::fabs(dcaz) < maxDcaz) { - if (mcparticle.isPhysicalPrimary()) { - registryMC.fill(HIST("antiproton_prim_dca_jet"), pt, dcaxy); - } else { - registryMC.fill(HIST("antiproton_all_dca_jet"), pt, dcaxy); + // Fill spectra for antiprotons + if (isAntip) { + // Fill DCA templates + if (std::fabs(dcaz) < maxDcaz) { + if (mcparticle.isPhysicalPrimary()) { + registryMC.fill(HIST("antiproton_prim_dca_jet"), pt, dcaxy); + } else { + registryMC.fill(HIST("antiproton_all_dca_jet"), pt, dcaxy); + } } - } - - // Apply DCA selections - if (std::fabs(dcaxy) > maxDcaxy || std::fabs(dcaz) > maxDcaz) - continue; - - // nsigmaITS for antiprotons - double nSigmaITSprot = static_cast(itsResponse.nSigmaITS(track)); - // Particle identification using the ITS cluster size - bool passedItsPidProt(true); - if (applyItsPid && pt < ptMaxItsPidProt && (nSigmaITSprot < nSigmaItsMin || nSigmaITSprot > nSigmaItsMax)) { - passedItsPidProt = false; - } + // Apply DCA selections + if (std::fabs(dcaxy) > maxDcaxy || std::fabs(dcaz) > maxDcaz) + continue; - // Fill inclusive antiproton spectrum - registryMC.fill(HIST("antiproton_incl_jet"), pt); + // nsigmaITS for antiprotons + double nSigmaITSprot = static_cast(itsResponse.nSigmaITS(track)); - // Select physical primary antiprotons - if (!mcparticle.isPhysicalPrimary()) - continue; + // Particle identification using the ITS cluster size + bool passedItsPidProt(true); + if (applyItsPid && pt < ptMaxItsPidProt && (nSigmaITSprot < nSigmaItsMin || nSigmaITSprot > nSigmaItsMax)) { + passedItsPidProt = false; + } - // Fill antiproton spectrum for physical primaries - registryMC.fill(HIST("antiproton_prim_jet"), pt); + // Fill inclusive antiproton spectrum + registryMC.fill(HIST("antiproton_incl_jet"), pt); - // Calculate weight - double weightJet(1.0); - if (applyReweighting && mcparticle.pt() < antiprotonsInsideJets->GetXaxis()->GetXmax()) { - int ipt = antiprotonsInsideJets->FindBin(mcparticle.pt()); - weightJet = antiprotonsInsideJets->GetBinContent(ipt); - } + // Select physical primary antiprotons + if (!mcparticle.isPhysicalPrimary()) + continue; - // Fill histograms (TPC and TOF) only for selected candidates - if (passedItsPidProt && nsigmaTPCPr > minNsigmaTpc && nsigmaTPCPr < maxNsigmaTpc) { - registryMC.fill(HIST("antiproton_rec_tpc_jet"), pt, weightJet); + // Fill antiproton spectrum for physical primaries + registryMC.fill(HIST("antiproton_prim_jet"), pt); - // Fill histograms for reconstructed antiprotons for closure test - if (isPseudoData) { - registryMC.fill(HIST("antiproton_rec_tpc_jet_data"), pt); - } else { - registryMC.fill(HIST("antiproton_rec_tpc_jet_mc"), pt); + // Calculate weight + double weightJet(1.0); + if (applyReweighting && mcparticle.pt() < antiprotonsInsideJets->GetXaxis()->GetXmax()) { + int ipt = antiprotonsInsideJets->FindBin(mcparticle.pt()); + weightJet = antiprotonsInsideJets->GetBinContent(ipt); } - if (track.hasTOF() && nsigmaTOFPr > minNsigmaTof && nsigmaTOFPr < maxNsigmaTof) { - registryMC.fill(HIST("antiproton_rec_tof_jet"), pt, weightJet); + // Fill histograms (TPC and TOF) only for selected candidates + if (passedItsPidProt && nsigmaTPCPr > minNsigmaTpc && nsigmaTPCPr < maxNsigmaTpc) { + registryMC.fill(HIST("antiproton_rec_tpc_jet"), pt, weightJet); // Fill histograms for reconstructed antiprotons for closure test if (isPseudoData) { - registryMC.fill(HIST("antiproton_rec_tof_jet_data"), pt); + registryMC.fill(HIST("antiproton_rec_tpc_jet_data"), pt); } else { - registryMC.fill(HIST("antiproton_rec_tof_jet_mc"), pt); + registryMC.fill(HIST("antiproton_rec_tpc_jet_mc"), pt); + } + + if (track.hasTOF() && nsigmaTOFPr > minNsigmaTof && nsigmaTOFPr < maxNsigmaTof) { + registryMC.fill(HIST("antiproton_rec_tof_jet"), pt, weightJet); + + // Fill histograms for reconstructed antiprotons for closure test + if (isPseudoData) { + registryMC.fill(HIST("antiproton_rec_tof_jet_data"), pt); + } else { + registryMC.fill(HIST("antiproton_rec_tof_jet_mc"), pt); + } } } - } + } // end of isAntip + + // Fill antideuteron spectra + if (isAntid) { + // Apply DCA selections + if (std::fabs(dcaxy) > maxDcaxy || std::fabs(dcaz) > maxDcaz) + continue; + + // Select physical primary antiprotons + if (!mcparticle.isPhysicalPrimary()) + continue; + + // Fill histograms (TPC and TOF) only for selected candidates + if (nsigmaTPCDe > minNsigmaTpc && nsigmaTPCDe < maxNsigmaTpc) { + registryMC.fill(HIST("antideuteron_rec_tpc_jet"), pt); + + if (track.hasTOF() && nsigmaTOFDe > minNsigmaTof && nsigmaTOFDe < maxNsigmaTof) { + registryMC.fill(HIST("antideuteron_rec_tof_jet"), pt); + } + } + } // end of isAntid } // Loop over tracks in the underlying event @@ -2574,6 +2654,54 @@ struct AntinucleiInJets { } } } + + // Loop over tracks in the underlying event + for (auto const& index : antideuteronTrackIndex) { + + // retrieve track associated to index + auto const& track = mcTracksThisMcColl.iteratorAt(index); + + // Get corresponding MC particle + if (!track.has_mcParticle()) + continue; + const auto mcparticle = track.mcParticle(); + + // Define variables + double nsigmaTPCDe = track.tpcNSigmaDe(); + double nsigmaTOFDe = track.tofNSigmaDe(); + double pt = track.pt(); + double dcaxy = track.dcaXY(); + double dcaz = track.dcaZ(); + + // Apply DCA selection + if (std::fabs(dcaxy) > maxDcaxy || std::fabs(dcaz) > maxDcaz) + continue; + + // Calculate the angular distance between the track and underlying event axes in eta-phi space + double deltaEtaUe1 = track.eta() - ueAxis1.Eta(); + double deltaPhiUe1 = getDeltaPhi(track.phi(), ueAxis1.Phi()); + double deltaRUe1 = std::sqrt(deltaEtaUe1 * deltaEtaUe1 + deltaPhiUe1 * deltaPhiUe1); + double deltaEtaUe2 = track.eta() - ueAxis2.Eta(); + double deltaPhiUe2 = getDeltaPhi(track.phi(), ueAxis2.Phi()); + double deltaRUe2 = std::sqrt(deltaEtaUe2 * deltaEtaUe2 + deltaPhiUe2 * deltaPhiUe2); + + // Reject tracks that lie outside the maxConeRadius from both UE axes + if (deltaRUe1 > rJet && deltaRUe2 > rJet) + continue; + + // Select physical primary antiprotons + if (!mcparticle.isPhysicalPrimary()) + continue; + + // Fill histograms (TPC and TOF) only for selected candidates + if (nsigmaTPCDe > minNsigmaTpc && nsigmaTPCDe < maxNsigmaTpc) { + registryMC.fill(HIST("antideuteron_rec_tpc_ue"), pt); + + if (track.hasTOF() && nsigmaTOFDe > minNsigmaTof && nsigmaTOFDe < maxNsigmaTof) { + registryMC.fill(HIST("antideuteron_rec_tof_ue"), pt); + } + } + } } if (isAtLeastOneJetSelected) { registryMC.fill(HIST("recEvents"), 9.5); diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx index 3181a09495d..2186703599f 100644 --- a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -43,13 +43,14 @@ #include #include +#include #include #include #include #include #include -#include +#include #include using namespace o2; @@ -59,39 +60,37 @@ using namespace constants::physics; using PIDTracks = soa::Join< aod::Tracks, aod::TracksExtra, aod::TrackSelectionExtension, aod::TracksDCA, aod::TrackSelection, - aod::pidTOFFullPi, aod::pidTOFFullPr, aod::pidTOFFullEl, aod::pidTOFbeta, aod::pidTPCPi, aod::pidTPCPr, aod::pidTPCEl>; + aod::pidTOFFullPi, aod::pidTOFFullPr, aod::pidTOFFullEl, aod::pidTOFbeta, aod::pidTPCPi, aod::pidTPCPr, aod::pidTPCEl, aod::pidTOFFlags>; using SelectedCollisions = soa::Join; using BCsRun3 = soa::Join; -static constexpr int NCentHists{10}; -std::array, NCentHists> hDedxVsMomentumVsCentPos{}; -std::array, NCentHists> hDedxVsMomentumVsCentNeg{}; -std::array, NCentHists + 1> hDedxVspTMomentumVsCent{}; -std::array, NCentHists + 1> hMomentumVsEtaPos{}; -std::array, NCentHists + 1> hMomentumVsEtaNeg{}; -std::array, NCentHists + 1> hpTVsEtaPos{}; -std::array, NCentHists + 1> hpTVsEtaNeg{}; - struct DedxPidAnalysis { // dE/dx for all charged particles - HistogramRegistry registryDeDx{ - "registryDeDx", - {}, - OutputObjHandlingPolicy::AnalysisObject, - true, - true}; + HistogramRegistry registryDeDx{"registryDeDx", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; // Constant values static constexpr int EtaIntervals = 8; static constexpr int ParticlesType = 4; static constexpr int CentralityClasses = 10; - float pionMin = 0.35; - float pionMax = 0.45; - float elTofCut = 0.1; - float pionTofCut = 1.0; - float pTcut = 2.0; + std::array, CentralityClasses> hDedxVsMomentumVsCentPos{}; + std::array, CentralityClasses> hDedxVsMomentumVsCentNeg{}; + std::array, ParticlesType> hDedxvsMomentumPos{}; + std::array, ParticlesType> hDedxvsMomentumNeg{}; + std::array, CentralityClasses + 1> hDedxVspTMomentumVsCent{}; + std::array, CentralityClasses + 1> hMomentumVsEtaPos{}; + std::array, CentralityClasses + 1> hMomentumVsEtaNeg{}; + std::array, CentralityClasses + 1> hpTVsEtaPos{}; + std::array, CentralityClasses + 1> hpTVsEtaNeg{}; + std::array, EtaIntervals> hNclFoundTPCPosBefore; + std::array, EtaIntervals> hNclFoundTPCNegBefore; + std::array, EtaIntervals> hNclFoundTPCPosAfter; + std::array, EtaIntervals> hNclFoundTPCNegAfter; + std::array, EtaIntervals> hNclPIDTPCPosBefore; + std::array, EtaIntervals> hNclPIDTPCNegBefore; + std::array, EtaIntervals> hNclPIDTPCPosAfter; + std::array, EtaIntervals> hNclPIDTPCNegAfter; bool fillHist = false; @@ -116,6 +115,12 @@ struct DedxPidAnalysis { }; + enum V0SigmaMode { + V0NoSigmaCut = 0, + V0SigmaOnly = 1, + V0TOFAndSigma = 2 + }; + enum NINELSelectionMode : int { NoSelINEL = 1, SelINELgt0 = 2, @@ -203,9 +208,17 @@ struct DedxPidAnalysis { Configurable nSigmaDCAxy{"nSigmaDCAxy", 3.0, "nSigma DCAxy selection"}; Configurable dcaXYp0{"dcaXYp0", 0.0105f, "DCAxy formula: p0 + p1/pt^p2"}; Configurable dcaXYp1{"dcaXYp1", 0.0350f, "DCAxy p1 parameter"}; - Configurable dcaXYp2{"dcaXYp2", 1.1f, "DCA_xy p2 parameter"}; + Configurable dcaXYp2{"dcaXYp2", 1.1f, "DCAxy p2 parameter"}; + Configurable dcaZp0{"dcaZp0", 0.0105f, "DCAz formula: p0 + p1/pt^p2"}; + Configurable dcaZp1{"dcaZp1", 0.0350f, "DCAz p1 parameter"}; + Configurable dcaZp2{"dcaZp2", 1.1f, "DCAz p2 parameter"}; Configurable nSigmaDCAz{"nSigmaDCAz", 3.0, "nSigma DCAz selection"}; - Configurable maxDCAz{"maxDCAz", 0.1f, "maxDCAz"}; + // Configurable maxDCAz{"maxDCAz", 0.1f, "maxDCAz"}; + Configurable pionMin{"pionMin", 0.35f, "pionMin"}; + Configurable pionMax{"pionMax", 0.45f, "pionMax"}; + Configurable elTofCut{"elTofCut", 0.1f, "elTofCut"}; + Configurable pionTofCut{"pionTofCut", 1.0f, "pionTofCut"}; + Configurable pTcut{"pTcut", 2.f, "pTcut"}; // v0 cuts Configurable v0cospaMin{"v0cospaMin", 0.999f, "Minimum V0 CosPA"}; Configurable minimumV0Radius{"minimumV0Radius", 1.2f, @@ -224,7 +237,9 @@ struct DedxPidAnalysis { Configurable v0ProperLifetimeCutK0s{"v0ProperLifetimeCutK0s", 20.f, "V0 proper lifetime cut for K0s"}; Configurable v0ProperLifetimeCutLambda{"v0ProperLifetimeCutLambda", 30.f, "V0 proper lifetime cut for Lambda"}; Configurable nsigmaMax{"nsigmaMax", 3.0f, "Maximum nsigma cut"}; + Configurable nsigmaMaxTOF{"nsigmaMaxTOF", 3.0f, "Maximum nsigma cut for TOF"}; Configurable tpcMomentumCut{"tpcMomentumCut", 0.6f, "Momentum threshold above which TOF is required"}; + Configurable v0SigmaMode{"v0SigmaMode", 0, "0: no cut, 1: sigma only, 2: TOF + sigma above tpcMomentumCut"}; Configurable invMassCutK0s{"invMassCutK0s", 0.015f, "invariant Mass Cut for K0s"}; Configurable invMassCutLambda{"invMassCutLambda", 0.015f, "invariant Mass Cut for Lambda"}; Configurable invMassCutGamma{"invMassCutGamma", 0.015f, "invariant Mass Cut for Gamma"}; @@ -245,40 +260,21 @@ struct DedxPidAnalysis { Configurable highParam1{"highParam1", 0.16685, "First parameter for high phi cut"}; Configurable highParam2{"highParam2", 0.00981942, "Second parameter for high phi cut"}; Configurable armPodCut{"armPodCut", 5.0f, "pT * (cut) > |alpha|"}; - // Histograms names - static constexpr std::string_view DedxvsMomentumPos[ParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; - static constexpr std::string_view DedxvsMomentumNeg[ParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; - static constexpr std::string_view DedxvsMomentumvsCentPos[CentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Pos", "dEdx_vs_Momentum_Cent1_5_Pos", "dEdx_vs_Momentum_Cent5_10_Pos", "dEdx_vs_Momentum_Cent10_15_Pos", "dEdx_vs_Momentum_Cent15_20_Pos", "dEdx_vs_Momentum_Cent20_30_Pos", "dEdx_vs_Momentum_Cent30_40_Pos", "dEdx_vs_Momentum_Cent40_50_Pos", "dEdx_vs_Momentum_Cent50_70_Pos", "dEdx_vs_Momentum_Cent70_100_Pos"}; - static constexpr std::string_view DedxvsMomentumvsCentNeg[CentralityClasses] = {"dEdx_vs_Momentum_Cent0_1_Neg", "dEdx_vs_Momentum_Cent1_5_Neg", "dEdx_vs_Momentum_Cent5_10_Neg", "dEdx_vs_Momentum_Cent10_15_Neg", "dEdx_vs_Momentum_Cent15_20_Neg", "dEdx_vs_Momentum_Cent20_30_Neg", "dEdx_vs_Momentum_Cent30_40_Neg", "dEdx_vs_Momentum_Cent40_50_Neg", "dEdx_vs_Momentum_Cent50_70_Neg", "dEdx_vs_Momentum_Cent70_100_Neg"}; - static constexpr std::string_view DedxvspTMomentumvsCent[CentralityClasses + 1] = {"dEdx_vs_pTMomentum_Cent0_1", "dEdx_vs_pTMomentum_Cent1_5", "dEdx_vs_pTMomentum_Cent5_10", "dEdx_vs_pTMomentum_Cent10_15", "dEdx_vs_pTMomentum_Cent15_20", "dEdx_vs_pTMomentum_Cent20_30", "dEdx_vs_pTMomentum_Cent30_40", "dEdx_vs_pTMomentum_Cent40_50", "dEdx_vs_pTMomentum_Cent50_70", "dEdx_vs_pTMomentum_Cent70_100", "dEdx_vs_pTMomentum_all_Pos"}; - // Fine binning - static constexpr std::string_view CentpPos[CentralityClasses + 1] = {"p_vs_eta_Cent0_1_Pos", "p_vs_eta_Cent1_5_Pos", "p_vs_eta_Cent5_10_Pos", "p_vs_eta_Cent10_15_Pos", "p_vs_eta_Cent15_20_Pos", "p_vs_eta_Cent20_30_Pos", "p_vs_eta_Cent30_40_Pos", "p_vs_eta_Cent40_50_Pos", "p_vs_eta_Cent50_70_Pos", "p_vs_eta_Cent70_100_Pos", "p_vs_eta_MB_Pos"}; - static constexpr std::string_view CentpNeg[CentralityClasses + 1] = {"p_vs_eta_Cent0_1_Neg", "p_vs_eta_Cent1_5_Neg", "p_vs_eta_Cent5_10_Neg", "p_vs_eta_Cent10_15_Neg", "p_vs_eta_Cent15_20_Neg", "p_vs_eta_Cent20_30_Neg", "p_vs_eta_Cent30_40_Neg", "p_vs_eta_Cent40_50_Neg", "p_vs_eta_Cent50_70_Neg", "p_vs_eta_Cent70_100_Neg", "p_vs_eta_MB_Neg"}; - static constexpr std::string_view CentpTPos[CentralityClasses + 1] = {"pT_vs_eta_Cent0_1_Pos", "pT_vs_eta_Cent1_5_Pos", "pT_vs_eta_Cent5_10_Pos", "pT_vs_eta_Cent10_15_Pos", "pT_vs_eta_Cent15_20_Pos", "pT_vs_eta_Cent20_30_Pos", "pT_vs_eta_Cent30_40_Pos", "pT_vs_eta_Cent40_50_Pos", "pT_vs_eta_Cent50_70_Pos", "pT_vs_eta_Cent70_100_Pos", "pT_vs_eta_MB_Pos"}; - static constexpr std::string_view CentpTNeg[CentralityClasses + 1] = {"pT_vs_eta_Cent0_1_Neg", "pT_vs_eta_Cent1_5_Neg", "pT_vs_eta_Cent5_10_Neg", "pT_vs_eta_Cent10_15_Neg", "pT_vs_eta_Cent15_20_Neg", "pT_vs_eta_Cent20_30_Neg", "pT_vs_eta_Cent30_40_Neg", "pT_vs_eta_Cent40_50_Neg", "pT_vs_eta_Cent50_70_Neg", "pT_vs_eta_Cent70_100_Neg", "pT_vs_eta_MB_Neg"}; - // Ncl TPC - static constexpr std::string_view NclTPCDedxMomentumNegBefore[EtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; - static constexpr std::string_view NclTPCDedxMomentumPosBefore[EtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; - static constexpr std::string_view NclTPCDedxMomentumNegAfter[EtaIntervals] = {"Ncl_TFoundPC_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_8_After"}; - static constexpr std::string_view NclTPCDedxMomentumPosAfter[EtaIntervals] = {"Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_8_After"}; - // Ncl PID TPC - static constexpr std::string_view NclPIDTPCDedxMomentumNegBefore[EtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_8_Before"}; - static constexpr std::string_view NclPIDTPCDedxMomentumPosBefore[EtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_8_Before"}; - static constexpr std::string_view NclPIDTPCDedxMomentumNegAfter[EtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_8_After"}; - static constexpr std::string_view NclPIDTPCDedxMomentumPosAfter[EtaIntervals] = {"Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_8_After"}; - static constexpr double EtaCut[EtaIntervals + 1] = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}; - static constexpr double CentClasses[CentralityClasses + 1] = {0.0, 1.0, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 70.0, 100.0}; + + static constexpr std::array EtaCut = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}; + static constexpr std::array CentClasses = {0.0, 1.0, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 70.0, 100.0}; Configurable> calibrationFactorNeg{"calibrationFactorNeg", {50.4011, 50.4764, 50.186, 49.2955, 48.8222, 49.4273, 49.9292, 50.0556}, "negative calibration factors"}; Configurable> calibrationFactorPos{"calibrationFactorPos", {50.5157, 50.6359, 50.3198, 49.3345, 48.9197, 49.4931, 50.0188, 50.1406}, "positive calibration factors"}; ConfigurableAxis binP{"binP", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, ""}; - ConfigurableAxis centBins{"centBins", {100, 0, 100}, "Binning for centralidad"}; - ConfigurableAxis dedxBins{"dedxBins", {100, 0, 100}, "Binning for dedx"}; - ConfigurableAxis pFineBins{"pFineBins", {1995, 0.1, 40}, "Binning for momentum"}; + ConfigurableAxis centBins{"centBins", {100, 0, 100}, "Binning for centralidad plots"}; + ConfigurableAxis dedxBins{"dedxBins", {100, 0, 100}, "Binning for dedx plots"}; + ConfigurableAxis pFineBins{"pFineBins", {1995, 0.1, 40}, "Binning for momentum plots"}; + ConfigurableAxis dcaBins{"dcaBins", {500, -0.5, 0.5}, "Binning for DCA plots"}; // phi cut fits TF1* fphiCutHigh = nullptr; TF1* fphiCutLow = nullptr; - Service ccdb; + Service ccdb{}; TrackSelection myTrackSelection() { @@ -287,7 +283,7 @@ struct DedxPidAnalysis { selectedTracks.SetEtaRange(etaMin, etaMax); selectedTracks.SetRequireITSRefit(true); selectedTracks.SetRequireTPCRefit(true); - selectedTracks.SetMinNCrossedRowsTPC(minNCrossedRowsTPC); + selectedTracks.SetMinNCrossedRowsTPC(static_cast(minNCrossedRowsTPC.value)); selectedTracks.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC); selectedTracks.SetMaxChi2PerClusterTPC(maxChi2TPC); selectedTracks.SetRequireHitsInITSLayers(1, {0, 1, 2}); @@ -331,6 +327,13 @@ struct DedxPidAnalysis { } else if (v0SelectionMode == V0TPCTOF) { LOGF(info, "V0 seleccion using TOF + TPC"); } + if (v0SigmaMode == V0NoSigmaCut) { + LOGF(info, "V0 sigma mode: no cut"); + } else if (v0SigmaMode == V0SigmaOnly) { + LOGF(info, "V0 sigma mode: sigma only"); + } else if (v0SigmaMode == V0TOFAndSigma) { + LOGF(info, "V0 sigma mode: TOF + sigma above tpcMomentumCut"); + } if (calibrationMode) { LOGF(info, "Calibration mode activated"); } else { @@ -369,6 +372,7 @@ struct DedxPidAnalysis { AxisSpec centAxis{centBins, "Undefined multiplicity estimator"}; AxisSpec pFineAxis{pFineBins, "#it{p} (GeV/c)"}; AxisSpec pTFineAxis{pFineBins, "#it{p}_{T} (GeV/c)"}; + AxisSpec dcaAxis{dcaBins, ""}; switch (multiplicityEstimator) { case MultSelectionMode::NoMultiplicity: // No multiplicity LOGF(info, "No multiplicity estimator applied"); @@ -426,6 +430,11 @@ struct DedxPidAnalysis { LOGF(info, "=== Phi Cut Parameters ==="); LOGF(info, "Low cut: %.6f/x² + pi/18 - %.6f", lowParam1.value, lowParam2.value); LOGF(info, "High cut: %.6f/x + pi/18 + %.6f", highParam1.value, highParam2.value); + const std::array centNames = { + "Cent0_1", "Cent1_5", "Cent5_10", "Cent10_15", "Cent15_20", + "Cent20_30", "Cent30_40", "Cent40_50", "Cent50_70", "Cent70_100", "MB"}; + const std::array v0Names = { + "all", "Pi_v0", "Pr_v0", "El_v0"}; if (calibrationMode) { // MIP for pions @@ -478,6 +487,14 @@ struct DedxPidAnalysis { "hdEdx_vs_eta_vs_p_Pos_calibrated_TOF", "dE/dx", HistType::kTH3F, {{etaAxis}, {dedxAxis}, {pAxis}}); + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Neg_calibrated_TOF2", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Pos_calibrated_TOF2", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + // pt vs p registryDeDx.add( "heta_vs_pt_vs_p_all_Neg", "eta_vs_pT_vs_p", HistType::kTH3F, @@ -488,23 +505,26 @@ struct DedxPidAnalysis { // De/Dx for ch and v0 particles for (int i = 0; i < ParticlesType; ++i) { - registryDeDx.add(DedxvsMomentumPos[i].data(), "dE/dx", HistType::kTH3F, - {{pAxisTrack}, {dedxAxis}, {etaAxis}}); - registryDeDx.add(DedxvsMomentumNeg[i].data(), "dE/dx", HistType::kTH3F, - {{pAxisTrack}, {dedxAxis}, {etaAxis}}); + const auto& part = v0Names[i]; + hDedxvsMomentumPos[i] = registryDeDx.add(Form("dEdx_vs_Momentum_%s_Pos", part.c_str()), + "dE/dx vs Momentum Positive", kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); + hDedxvsMomentumNeg[i] = registryDeDx.add(Form("dEdx_vs_Momentum_%s_Neg", part.c_str()), + "dE/dx vs Momentum Negative", kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); } for (int i = 0; i < CentralityClasses; ++i) { - hDedxVsMomentumVsCentPos[i] = registryDeDx.add(DedxvsMomentumvsCentPos[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); - hDedxVsMomentumVsCentNeg[i] = registryDeDx.add(DedxvsMomentumvsCentNeg[i].data(), "dE/dx", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); + const auto& cent = centNames[i]; + hDedxVsMomentumVsCentPos[i] = registryDeDx.add(Form("dEdx_vs_Momentum_%s_Pos", cent.c_str()), "dE/dx vs Momentum Positive", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); + hDedxVsMomentumVsCentNeg[i] = registryDeDx.add(Form("dEdx_vs_Momentum_%s_Neg", cent.c_str()), "dE/dx vs Momentum Negative", HistType::kTH3F, {{pAxisTrack}, {dedxAxis}, {etaAxis}}); } for (int i = 0; i < CentralityClasses + 1; ++i) { - hDedxVspTMomentumVsCent[i] = registryDeDx.add(DedxvspTMomentumvsCent[i].data(), "dE/dx", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); - hMomentumVsEtaPos[i] = registryDeDx.add(CentpPos[i].data(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); - hMomentumVsEtaNeg[i] = registryDeDx.add(CentpNeg[i].data(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); - hpTVsEtaPos[i] = registryDeDx.add(CentpTPos[i].data(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); - hpTVsEtaNeg[i] = registryDeDx.add(CentpTNeg[i].data(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); + const auto& cent = centNames[i]; + hDedxVspTMomentumVsCent[i] = registryDeDx.add(Form("dEdx_vs_pT_%s", cent.c_str()), "dE/dx vs pT", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); + hMomentumVsEtaPos[i] = registryDeDx.add(Form("p_vs_eta_%s_Pos", cent.c_str()), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); + hMomentumVsEtaNeg[i] = registryDeDx.add(Form("p_vs_eta_%s_Neg", cent.c_str()), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); + hpTVsEtaPos[i] = registryDeDx.add(Form("pT_vs_eta_%s_Pos", cent.c_str()), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); + hpTVsEtaNeg[i] = registryDeDx.add(Form("pT_vs_eta_%s_Neg", cent.c_str()), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); } // Invariant Mass @@ -571,33 +591,41 @@ struct DedxPidAnalysis { "hp_vs_phi_NclPID_TPC_Before", "phi cut vs p", HistType::kTH3F, {{pAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl, PID}"}}); } - // Ncl vs de/dx TPC + // Ncl vs de/dx TPC (found) if (nClTPCFoundCut) { for (int i = 0; i < EtaIntervals; ++i) { - registryDeDx.add(NclTPCDedxMomentumPosBefore[i].data(), "Ncl found TPC vs dE/dx vs Momentum Positive before", HistType::kTH3F, - {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(NclTPCDedxMomentumNegBefore[i].data(), "Ncl found TPC vs dE/dx vs Momentum Negative before", HistType::kTH3F, - {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); - - registryDeDx.add(NclTPCDedxMomentumPosAfter[i].data(), "Ncl found TPC vs dE/dx vs Momentum Positive after", HistType::kTH3F, - {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(NclTPCDedxMomentumNegAfter[i].data(), "Ncl found TPC vs dE/dx vs Momentum Negative after", HistType::kTH3F, - {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); + hNclFoundTPCPosBefore[i] = registryDeDx.add(Form("Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_%d_Before", i + 1), + "Ncl found TPC vs dE/dx vs Momentum Positive before", HistType::kTH3F, + {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); + hNclFoundTPCNegBefore[i] = registryDeDx.add(Form("Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_%d_Before", i + 1), + "Ncl found TPC vs dE/dx vs Momentum Negative before", HistType::kTH3F, + {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); + + hNclFoundTPCPosAfter[i] = registryDeDx.add(Form("Ncl_FoundTPC_vs_dEdx_vs_Momentum_Pos_%d_After", i + 1), + "Ncl found TPC vs dE/dx vs Momentum Positive after", HistType::kTH3F, + {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); + hNclFoundTPCNegAfter[i] = registryDeDx.add(Form("Ncl_FoundTPC_vs_dEdx_vs_Momentum_Neg_%d_After", i + 1), + "Ncl found TPC vs dE/dx vs Momentum Negative after", HistType::kTH3F, + {{100, 0, 160, "N_{cl, found}^{TPC}"}, {dedxAxis}, {pAxis}}); } } - // Ncl vs de/dx ITS + // Ncl vs de/dx PID TPC if (nClTPCPIDCut) { for (int i = 0; i < EtaIntervals; ++i) { - registryDeDx.add(NclPIDTPCDedxMomentumPosBefore[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Positive before", HistType::kTH3F, - {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(NclPIDTPCDedxMomentumNegBefore[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Negative before", HistType::kTH3F, - {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); - - registryDeDx.add(NclPIDTPCDedxMomentumPosAfter[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Positive after", HistType::kTH3F, - {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); - registryDeDx.add(NclPIDTPCDedxMomentumNegAfter[i].data(), "Ncl PID TPC vs dE/dx vs Momentum Negative after", HistType::kTH3F, - {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); + hNclPIDTPCPosBefore[i] = registryDeDx.add(Form("Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_%d_Before", i + 1), + "Ncl PID TPC vs dE/dx vs Momentum Positive before", HistType::kTH3F, + {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); + hNclPIDTPCNegBefore[i] = registryDeDx.add(Form("Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_%d_Before", i + 1), + "Ncl PID TPC vs dE/dx vs Momentum Negative before", HistType::kTH3F, + {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); + + hNclPIDTPCPosAfter[i] = registryDeDx.add(Form("Ncl_PIDTPC_vs_dEdx_vs_Momentum_Pos_%d_After", i + 1), + "Ncl PID TPC vs dE/dx vs Momentum Positive after", HistType::kTH3F, + {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); + hNclPIDTPCNegAfter[i] = registryDeDx.add(Form("Ncl_PIDTPC_vs_dEdx_vs_Momentum_Neg_%d_After", i + 1), + "Ncl PID TPC vs dE/dx vs Momentum Negative after", HistType::kTH3F, + {{100, 0, 160, "N_{cl, PID}^{TPC}"}, {dedxAxis}, {pAxis}}); } } // eta @@ -718,14 +746,18 @@ struct DedxPidAnalysis { registryDeDx.add("hTPCPIDAfter", "N clusters TPC PID After", HistType::kTH1F, {{200, 0, 200, "N_{cl,PID, After}"}}); // DCA cut + registryDeDx.add("hDCAxyVsPt_beforeAnyCut", "DCAxy vs pT before any tkr cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", + HistType::kTH2F, {{ptAxis}, {dcaAxis}}); + registryDeDx.add("hDCAzVsPt_beforeAnyCut", "DCAz vs pT before any tkr cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", + HistType::kTH2F, {{ptAxis}, {dcaAxis}}); registryDeDx.add("hDCAxyVsPt_before", "DCAxy vs pT before cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", - HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); + HistType::kTH2F, {{ptAxis}, {dcaAxis}}); registryDeDx.add("hDCAzVsPt_before", "DCAz vs pT before cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", - HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); + HistType::kTH2F, {{ptAxis}, {dcaAxis}}); registryDeDx.add("hDCAxyVsPt_after", "DCAxy vs pT after cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", - HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); + HistType::kTH2F, {{ptAxis}, {dcaAxis}}); registryDeDx.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", - HistType::kTH2F, {{ptAxis}, {200, -0.5, 0.5}}); + HistType::kTH2F, {{ptAxis}, {dcaAxis}}); // Event Counter registryDeDx.add("evsel", "events selected", HistType::kTH1F, {{6, 0.5, 6.5, ""}}); @@ -816,7 +848,7 @@ struct DedxPidAnalysis { template bool passesDCAzCut(const T1& track) const { - const float maxiDcaZ = nSigmaDCAz.value * (maxDCAz.value) / 3.0; + const float maxiDcaZ = nSigmaDCAz.value * (dcaZp0.value + dcaZp1.value / std::pow(track.pt(), dcaZp2.value)) / 3.0; return std::abs(track.dcaZ()) < maxiDcaZ; } // Momentum @@ -872,16 +904,24 @@ struct DedxPidAnalysis { sigman = std::hypot(ntrack.tpcNSigmaPi(), ntrack.tofNSigmaPi()); } - if (ptrack.tpcInnerParam() > tpcMomentumCut) { - if (!ptrack.hasTOF()) - return false; + if (v0SigmaMode == V0TOFAndSigma) { + // TOF + sigma + if (ptrack.tpcInnerParam() > tpcMomentumCut) { + if (!ptrack.hasTOF()) + return false; + if (std::abs(sigmap) > nsigmaMax) + return false; + } + if (ntrack.tpcInnerParam() > tpcMomentumCut) { + if (!ntrack.hasTOF()) + return false; + if (std::abs(sigman) > nsigmaMax) + return false; + } + } else if (v0SigmaMode == V0SigmaOnly) { + // sigma only if (std::abs(sigmap) > nsigmaMax) return false; - } - - if (ntrack.tpcInnerParam() > tpcMomentumCut) { - if (!ntrack.hasTOF()) - return false; if (std::abs(sigman) > nsigmaMax) return false; } @@ -953,16 +993,24 @@ struct DedxPidAnalysis { sigman = std::hypot(ntrack.tpcNSigmaPi(), ntrack.tofNSigmaPi()); } - if (ptrack.tpcInnerParam() > tpcMomentumCut) { - if (!ptrack.hasTOF()) - return false; + if (v0SigmaMode == V0TOFAndSigma) { + // TOF + sigma + if (ptrack.tpcInnerParam() > tpcMomentumCut) { + if (!ptrack.hasTOF()) + return false; + if (std::abs(sigmap) > nsigmaMax) + return false; + } + if (ntrack.tpcInnerParam() > tpcMomentumCut) { + if (!ntrack.hasTOF()) + return false; + if (std::abs(sigman) > nsigmaMax) + return false; + } + } else if (v0SigmaMode == V0SigmaOnly) { + // sigma only if (std::abs(sigmap) > nsigmaMax) return false; - } - - if (ntrack.tpcInnerParam() > tpcMomentumCut) { - if (!ntrack.hasTOF()) - return false; if (std::abs(sigman) > nsigmaMax) return false; } @@ -1027,15 +1075,24 @@ struct DedxPidAnalysis { sigmap = std::hypot(ptrack.tpcNSigmaPi(), ptrack.tofNSigmaPi()); sigman = std::hypot(ntrack.tpcNSigmaPr(), ntrack.tofNSigmaPr()); } - if (ptrack.tpcInnerParam() > tpcMomentumCut) { - if (!ptrack.hasTOF()) - return false; - if (std::abs(sigmap) > nsigmaMax) - return false; - } - if (ntrack.tpcInnerParam() > tpcMomentumCut) { - if (!ntrack.hasTOF()) + if (v0SigmaMode == V0TOFAndSigma) { + // TOF + sigma + if (ptrack.tpcInnerParam() > tpcMomentumCut) { + if (!ptrack.hasTOF()) + return false; + if (std::abs(sigmap) > nsigmaMax) + return false; + } + if (ntrack.tpcInnerParam() > tpcMomentumCut) { + if (!ntrack.hasTOF()) + return false; + if (std::abs(sigman) > nsigmaMax) + return false; + } + } else if (v0SigmaMode == V0SigmaOnly) { + // sigma only + if (std::abs(sigmap) > nsigmaMax) return false; if (std::abs(sigman) > nsigmaMax) return false; @@ -1104,19 +1161,28 @@ struct DedxPidAnalysis { sigman = std::hypot(ntrack.tpcNSigmaEl(), ntrack.tofNSigmaEl()); } - if (ptrack.tpcInnerParam() > tpcMomentumCut) { - if (!ptrack.hasTOF()) - return false; + if (v0SigmaMode == V0TOFAndSigma) { + // TOF + sigma + if (ptrack.tpcInnerParam() > tpcMomentumCut) { + if (!ptrack.hasTOF()) + return false; + if (std::abs(sigmap) > nsigmaMax) + return false; + } + if (ntrack.tpcInnerParam() > tpcMomentumCut) { + if (!ntrack.hasTOF()) + return false; + if (std::abs(sigman) > nsigmaMax) + return false; + } + } else if (v0SigmaMode == V0SigmaOnly) { + // sigma only if (std::abs(sigmap) > nsigmaMax) return false; - } - - if (ntrack.tpcInnerParam() > tpcMomentumCut) { - if (!ntrack.hasTOF()) - return false; if (std::abs(sigman) > nsigmaMax) return false; } + const float gammaMass = 2 * MassElectron; // GeV/c^2 if (fillHist) @@ -1156,7 +1222,7 @@ struct DedxPidAnalysis { } // Phi cut template - bool passedPhiCutPri(const T& trk, float magField, const TF1& fphiCutLow, const TF1& fphiCutHigh) + bool passedPhiCutPri(const T& trk, float magField) { float p = trk.p(); float pt = trk.pt(); @@ -1183,7 +1249,7 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("hp_vs_phi_NclPID_TPC_Before"), p, phi, nTPCPIDCl); // cut phi - if (phi < fphiCutHigh.Eval(pt) && phi > fphiCutLow.Eval(pt)) + if (phi < fphiCutHigh->Eval(pt) && phi > fphiCutLow->Eval(pt)) return false; // reject track registryDeDx.fill(HIST("hpt_vs_phi_NclFound_TPC_After"), pt, phi, nTPCCl); @@ -1202,107 +1268,29 @@ struct DedxPidAnalysis { float sigP = trk.sign() * getMomentum(trk); auto nTPCCl = trk.tpcNClsFound(); - if (eta >= EtaCut[0] && eta < EtaCut[1]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[0]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[1] && eta < EtaCut[2]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[1]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[2] && eta < EtaCut[3]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[2]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[3] && eta < EtaCut[4]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[3]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[4] && eta < EtaCut[5]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[4]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[5] && eta < EtaCut[6]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[5]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[6] && eta < EtaCut[7]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[6]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[7] && eta < EtaCut[8]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegBefore[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosBefore[7]), nTPCCl, trk.tpcSignal(), sigP); + int etaIndex = -1; + for (int i = 0; i < EtaIntervals; ++i) { + if (eta >= EtaCut[i] && eta < EtaCut[i + 1]) { + etaIndex = i; + break; } } + if (etaIndex == -1) + return false; + + if (sigP < 0) { + hNclFoundTPCNegBefore[etaIndex]->Fill(nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + hNclFoundTPCPosBefore[etaIndex]->Fill(nTPCCl, trk.tpcSignal(), sigP); + } if (nTPCCl < minTPCnClsFound) return false; - if (eta >= EtaCut[0] && eta < EtaCut[1]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[0]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[1] && eta < EtaCut[2]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[1]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[2] && eta < EtaCut[3]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[2]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[3] && eta < EtaCut[4]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[3]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[4] && eta < EtaCut[5]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[4]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[5] && eta < EtaCut[6]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[5]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[6] && eta < EtaCut[7]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[6]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[7] && eta < EtaCut[8]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclTPCDedxMomentumNegAfter[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclTPCDedxMomentumPosAfter[7]), nTPCCl, trk.tpcSignal(), sigP); - } + if (sigP < 0) { + hNclFoundTPCNegAfter[etaIndex]->Fill(nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + hNclFoundTPCPosAfter[etaIndex]->Fill(nTPCCl, trk.tpcSignal(), sigP); } return true; @@ -1316,107 +1304,29 @@ struct DedxPidAnalysis { float sigP = trk.sign() * getMomentum(trk); auto nTPCCl = trk.tpcNClsPID(); - if (eta >= EtaCut[0] && eta < EtaCut[1]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[0]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[1] && eta < EtaCut[2]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[1]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[2] && eta < EtaCut[3]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[2]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[3] && eta < EtaCut[4]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[3]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[4] && eta < EtaCut[5]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[4]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[5] && eta < EtaCut[6]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[5]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[6] && eta < EtaCut[7]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[6]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[7] && eta < EtaCut[8]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegBefore[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosBefore[7]), nTPCCl, trk.tpcSignal(), sigP); + int etaIndex = -1; + for (int i = 0; i < EtaIntervals; ++i) { + if (eta >= EtaCut[i] && eta < EtaCut[i + 1]) { + etaIndex = i; + break; } } + if (etaIndex == -1) + return false; + + if (sigP < 0) { + hNclPIDTPCNegBefore[etaIndex]->Fill(nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + hNclPIDTPCPosBefore[etaIndex]->Fill(nTPCCl, trk.tpcSignal(), sigP); + } if (nTPCCl < minTPCnClsPID) return false; - if (eta >= EtaCut[0] && eta < EtaCut[1]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[0]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[1] && eta < EtaCut[2]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[1]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[2] && eta < EtaCut[3]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[2]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[3] && eta < EtaCut[4]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[3]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[4] && eta < EtaCut[5]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[4]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[5] && eta < EtaCut[6]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[5]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[6] && eta < EtaCut[7]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[6]), nTPCCl, trk.tpcSignal(), sigP); - } - } else if (eta >= EtaCut[7] && eta < EtaCut[8]) { - if (sigP < 0) { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumNegAfter[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); - } else { - registryDeDx.fill(HIST(NclPIDTPCDedxMomentumPosAfter[7]), nTPCCl, trk.tpcSignal(), sigP); - } + if (sigP < 0) { + hNclPIDTPCNegAfter[etaIndex]->Fill(nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + hNclPIDTPCPosAfter[etaIndex]->Fill(nTPCCl, trk.tpcSignal(), sigP); } return true; @@ -1424,7 +1334,7 @@ struct DedxPidAnalysis { // Phi cut Secondaries template - bool passedPhiCutSecondaries(const T& trk, float magField, const TF1& fphiCutLow, const TF1& fphiCutHigh) + bool passedPhiCutSecondaries(const T& trk, float magField) { float pt = trk.pt(); float phi = trk.phi(); @@ -1442,36 +1352,24 @@ struct DedxPidAnalysis { phi += o2::constants::math::PI / 18.0f; phi = std::fmod(phi, o2::constants::math::PI / 9.0f); - // cut phi - if (phi < fphiCutHigh.Eval(pt) && phi > fphiCutLow.Eval(pt)) - return false; // reject track - - return true; + // cut phi, reject track if inside the gap + return (phi >= fphiCutHigh->Eval(pt)) || (phi <= fphiCutLow->Eval(pt)); } // NclCutTPC template bool passedNClTPCFoundCutSecondaries(const T& trk) { - auto nTPCCl = trk.tpcNClsFound(); - - if (nTPCCl < minTPCnClsFound) - return false; - - return true; + return trk.tpcNClsFound() >= minTPCnClsFound; } // NclCutPIDTPC secondary template bool passedNClTPCPIDCutSecondaries(const T& trk) { - auto nTPCCl = trk.tpcNClsPID(); - - if (nTPCCl < minTPCnClsPID) - return false; - - return true; + return trk.tpcNClsPID() >= minTPCnClsPID; } + // Get Multiplicity template float getMultiplicity(const T& collision) @@ -1574,6 +1472,10 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("hTPCClustersBefore"), trk.tpcNClsFound()); registryDeDx.fill(HIST("hTPCPIDBefore"), trk.tpcNClsPID()); + // Before DCA any tkr cuts + registryDeDx.fill(HIST("hDCAxyVsPt_beforeAnyCut"), trk.pt(), trk.dcaXY()); + registryDeDx.fill(HIST("hDCAzVsPt_beforeAnyCut"), trk.pt(), trk.dcaZ()); + // track Selection wo DCA if (!mySelectionPrim.IsSelected(trk)) continue; @@ -1598,7 +1500,7 @@ struct DedxPidAnalysis { // phi and Ncl cut if (phiVarCut) { - if (!passedPhiCutPri(trk, magField, *fphiCutLow, *fphiCutHigh)) + if (!passedPhiCutPri(trk, magField)) continue; registryDeDx.fill(HIST("trackselAll"), TrkPriCutLabel::PhiVarCutPri); } @@ -1700,6 +1602,24 @@ struct DedxPidAnalysis { } } + // pions from TOF w nsigma + if (!calibrationMode) { + if (trk.hasTOF() && trk.goodTOFMatch()) { + const double sigmaPi = std::hypot(trk.tpcNSigmaPi(), trk.tofNSigmaPi()); + if (std::abs(sigmaPi) < nsigmaMaxTOF) { + for (int i = 0; i < EtaIntervals; ++i) { + if (trk.eta() >= EtaCut[i] && trk.eta() < EtaCut[i + 1]) { + if (signedP < 0) { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_calibrated_TOF2"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), std::abs(signedP)); + } else { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Pos_calibrated_TOF2"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorPos->at(i), signedP); + } + } + } + } + } + } + registryDeDx.fill(HIST("hdEdx_vs_phi"), trk.phi(), trk.tpcSignal()); if (!calibrationMode) { @@ -1716,7 +1636,7 @@ struct DedxPidAnalysis { for (int i = 0; i < EtaIntervals; ++i) { if (trk.eta() >= EtaCut[i] && trk.eta() < EtaCut[i + 1]) { if (signedP > 0) { - registryDeDx.fill(HIST(DedxvsMomentumPos[0]), signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); + hDedxvsMomentumPos[0]->Fill(signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); registryDeDx.fill(HIST("heta_vs_pt_vs_p_all_Pos"), trk.eta(), trk.pt(), trk.p()); hDedxVsMomentumVsCentPos[centIndex]->Fill(signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); hDedxVspTMomentumVsCent[centIndex]->Fill(signedpT, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); @@ -1726,7 +1646,7 @@ struct DedxPidAnalysis { hpTVsEtaPos[centIndex]->Fill(trk.eta(), signedpT); hpTVsEtaPos[10]->Fill(trk.eta(), signedpT); } else { - registryDeDx.fill(HIST(DedxvsMomentumNeg[0]), std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); + hDedxvsMomentumNeg[0]->Fill(std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); registryDeDx.fill(HIST("heta_vs_pt_vs_p_all_Neg"), trk.eta(), trk.pt(), trk.p()); hDedxVsMomentumVsCentNeg[centIndex]->Fill(std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); hDedxVspTMomentumVsCent[centIndex]->Fill(std::abs(signedpT), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); @@ -1764,10 +1684,10 @@ struct DedxPidAnalysis { // registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel::TPCRefit); // phi and Ncl cut if (phiVarCut) { - if (!passedPhiCutSecondaries(posTrack, magField, *fphiCutLow, *fphiCutHigh)) + if (!passedPhiCutSecondaries(posTrack, magField)) continue; - if (!passedPhiCutSecondaries(negTrack, magField, *fphiCutLow, *fphiCutHigh)) + if (!passedPhiCutSecondaries(negTrack, magField)) continue; registryDeDx.fill(HIST("trackselSec"), TrkSecCutLabel ::PhiVarCutSec); @@ -1841,10 +1761,10 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("hArmenterosK0s"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(DedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + hDedxvsMomentumNeg[1]->Fill(std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); } if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(DedxvsMomentumPos[1]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + hDedxvsMomentumPos[1]->Fill(signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); } } } @@ -1859,10 +1779,10 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("hArmenterosLambda"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(DedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + hDedxvsMomentumNeg[1]->Fill(std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); } if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(DedxvsMomentumPos[2]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + hDedxvsMomentumPos[2]->Fill(signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); } } } @@ -1877,10 +1797,10 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("hArmenterosAntiLambda"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(DedxvsMomentumNeg[2]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + hDedxvsMomentumNeg[2]->Fill(std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); } if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(DedxvsMomentumPos[1]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + hDedxvsMomentumPos[1]->Fill(signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); } } } @@ -1895,10 +1815,10 @@ struct DedxPidAnalysis { registryDeDx.fill(HIST("hArmenterosGamma"), v0.alpha(), v0.qtarm()); for (int i = 0; i < EtaIntervals; ++i) { if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(DedxvsMomentumNeg[3]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + hDedxvsMomentumNeg[3]->Fill(std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); } if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { - registryDeDx.fill(HIST(DedxvsMomentumPos[3]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + hDedxvsMomentumPos[3]->Fill(signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); } } } diff --git a/PWGLF/Tasks/Nuspex/hadronnucleicorrelation.cxx b/PWGLF/Tasks/Nuspex/hadronnucleicorrelation.cxx index 59e36311135..32edfd80aa6 100644 --- a/PWGLF/Tasks/Nuspex/hadronnucleicorrelation.cxx +++ b/PWGLF/Tasks/Nuspex/hadronnucleicorrelation.cxx @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,12 @@ enum Modes { kPPbar }; +enum Origin { + kPrimary = 0, + kWeakDecay, + kMaterial +}; + struct HadronNucleiCorrelation { static constexpr int betahasTOFthr = -100; @@ -77,13 +84,14 @@ struct HadronNucleiCorrelation { Configurable mode{"mode", 0, "0: antid-antip, 1: d-p, 2: antid-p, 3: d-antip, 4: antip-p, 5: antip-antip, 6: p-p, 7: p-antip"}; - Configurable dorapidity{"dorapidity", false, "do rapidity dependent analysis"}; + Configurable doRapidity{"doRapidity", false, "do rapidity dependent analysis"}; Configurable doQA{"doQA", true, "save QA histograms"}; Configurable doMCQA{"doMCQA", false, "save MC QA histograms"}; Configurable isMC{"isMC", false, "is MC"}; Configurable isMCGen{"isMCGen", false, "is isMCGen"}; Configurable isPrim{"isPrim", true, "is isPrim"}; Configurable doCorrection{"doCorrection", false, "do efficiency correction"}; + Configurable doQuadraticPID{"doQuadraticPID", false, "do PID with sum in quadrature of TOF and TPC"}; Configurable fCorrectionPath{"fCorrectionPath", "", "Correction path to file"}; Configurable fCorrectionHisto{"fCorrectionHisto", "", "Correction histogram"}; @@ -91,19 +99,20 @@ struct HadronNucleiCorrelation { // Event selection Configurable cutzVertex{"cutzVertex", 10.0, "|vertexZ| value limit"}; + Configurable removeSameBunchPileup{"removeSameBunchPileup", false, "remove Same Bunch Pileup"}; // Track selection Configurable doClosePairRejection{"doClosePairRejection", false, "doClosePairRejection"}; - Configurable par0{"par0", 0.004, "par 0"}; - Configurable par1{"par1", 0.013, "par 1"}; + Configurable dcaPar0{"dcaPar0", 0.004, "par 0"}; + Configurable dcaPar1{"dcaPar1", 0.013, "par 1"}; Configurable doDCAZ{"doDCAZ", true, "do DCA z cut"}; - Configurable min_TPC_nClusters{"min_TPC_nClusters", 80, "minimum number of found TPC clusters"}; - Configurable min_TPC_nCrossedRowsOverFindableCls{"min_TPC_nCrossedRowsOverFindableCls", 0.8, "n TPC Crossed Rows Over Findable Cls"}; - Configurable max_chi2_TPC{"max_chi2_TPC", 4.0f, "maximum TPC chi^2/Ncls"}; - Configurable max_chi2_ITS{"max_chi2_ITS", 36.0f, "maximum ITS chi^2/Ncls"}; + Configurable minTPCnClusters{"minTPCnClusters", 80, "minimum number of found TPC clusters"}; + Configurable minTPCnCrossedRowsOverFindableCls{"minTPCnCrossedRowsOverFindableCls", 0.8, "n TPC Crossed Rows Over Findable Cls"}; + Configurable maxchi2TPC{"maxchi2TPC", 4.0f, "maximum TPC chi^2/Ncls"}; + Configurable maxchi2ITS{"maxchi2ITS", 36.0f, "maximum ITS chi^2/Ncls"}; Configurable etaCut{"etaCut", 0.8f, "eta cut"}; - Configurable max_DCAxy{"max_DCAxy", 0.14f, "Maximum DCAxy"}; - Configurable max_DCAz{"max_DCAz", 0.1f, "Maximum DCAz"}; + Configurable maxDCAxy{"maxDCAxy", 0.14f, "Maximum DCAxy"}; + Configurable maxDCAz{"maxDCAz", 0.1f, "Maximum DCAz"}; Configurable nsigmaTPC{"nsigmaTPC", 3.0f, "cut nsigma TPC"}; Configurable nsigmaElPr{"nsigmaElPr", 1.0f, "cut nsigma TPC El for protons"}; Configurable nsigmaElDe{"nsigmaElDe", 3.0f, "cut nsigma TPC El for protons"}; @@ -111,17 +120,18 @@ struct HadronNucleiCorrelation { Configurable nsigmaITSPr{"nsigmaITSPr", -2.0f, "cut nsigma ITS Pr"}; Configurable nsigmaITSDe{"nsigmaITSDe", -2.0f, "cut nsigma ITS De"}; Configurable doITSPID{"doITSPID", true, "do ITS PID"}; - Configurable pTthrpr_TOF{"pTthrpr_TOF", 0.8f, "threshold pT proton to use TOF"}; - Configurable pTthrpr_TPCEl{"pTthrpr_TPCEl", 1.0f, "threshold pT proton to use TPC El rejection"}; - Configurable pTthrde_TOF{"pTthrde_TOF", 1.0f, "threshold pT deuteron to use TOF"}; - Configurable pTthrde_TPCEl{"pTthrde_TPCEl", 1.0f, "threshold pT deuteron to use TPC El rejection"}; + Configurable pTthrprTOF{"pTthrprTOF", 0.8f, "threshold pT proton to use TOF"}; + Configurable pTthrprTPCEl{"pTthrprTPCEl", 1.0f, "threshold pT proton to use TPC El rejection"}; + Configurable pTthrdeTOF{"pTthrdeTOF", 1.0f, "threshold pT deuteron to use TOF"}; + Configurable pTthrdeTPCEl{"pTthrdeTPCEl", 1.0f, "threshold pT deuteron to use TPC El rejection"}; Configurable rejectionEl{"rejectionEl", true, "use TPC El rejection"}; - Configurable max_tpcSharedCls{"max_tpcSharedCls", 0.4, "maximum fraction of TPC shared clasters"}; - Configurable min_itsNCls{"min_itsNCls", 0, "minimum allowed number of ITS clasters"}; + Configurable maxtpcSharedCls{"maxtpcSharedCls", 0.4, "maximum fraction of TPC shared clasters"}; + Configurable minitsNCls{"minitsNCls", 0, "minimum allowed number of ITS clasters"}; Configurable maxmixcollsGen{"maxmixcollsGen", 100, "maxmixcollsGen"}; Configurable radiusTPC{"radiusTPC", 1.2, "TPC radius to calculate phi_star for"}; Configurable dEta{"dEta", 0.01, "minimum allowed difference in eta between two tracks in a pair"}; Configurable dPhi{"dPhi", 0.01, "minimum allowed difference in phi_star between two tracks in a pair"}; + Configurable yRap{"yRap", 0.5, "rapidity"}; // Mixing parameters ConfigurableAxis confMultBins{"confMultBins", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 50.0f, 100.0f, 99999.f}, "Mixing bins - multiplicity"}; @@ -131,10 +141,11 @@ struct HadronNucleiCorrelation { // pT/A bins Configurable> pTBins{"pTBins", {0.6f, 1.0f, 1.2f, 2.f}, "p_{T} bins"}; - ConfigurableAxis AxisNSigma{"AxisNSigma", {35, -7.f, 7.f}, "n#sigma"}; - ConfigurableAxis DeltaPhiAxis = {"DeltaPhiAxis", {46, -1 * o2::constants::math::PIHalf, 3 * o2::constants::math::PIHalf}, "#Delta#phi (rad)"}; + ConfigurableAxis axisNSigma{"axisNSigma", {35, -7.f, 7.f}, "n#sigma"}; + ConfigurableAxis deltaPhiAxis = {"deltaPhiAxis", {46, -1 * o2::constants::math::PIHalf, 3 * o2::constants::math::PIHalf}, "#Delta#phi (rad)"}; using FilteredCollisions = soa::Filtered; + using FilteredCollisionsExtra = soa::Filtered>; using SimCollisions = soa::Filtered; using SimParticles = aod::McParticles; using FilteredTracks = soa::Filtered>; // new tables (v3) @@ -230,26 +241,26 @@ struct HadronNucleiCorrelation { if (!isMC) { for (int i = 0; i < nBinspT; i++) { - if (dorapidity) { + if (doRapidity) { - auto htempSE_AntiDeAntiPr = registry.add(Form("hEtaPhi_%s_SE_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("Raw #Delta y #Delta#phi (%.1f(Form("hEtaPhi_%s_ME_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("Raw #Delta y #Delta#phi (%.1f(Form("hEtaPhi_%s_SE_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("Raw #Delta y #Delta#phi (%.1f(Form("hEtaPhi_%s_ME_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("Raw #Delta y #Delta#phi (%.1f(Form("hCorrEtaPhi_%s_SE_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("#Delta y #Delta#phi (%.1f(Form("hCorrEtaPhi_%s_ME_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("#Delta y #Delta#phi (%.1f(Form("hCorrEtaPhi_%s_SE_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("#Delta y #Delta#phi (%.1f(Form("hCorrEtaPhi_%s_ME_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("#Delta y #Delta#phi (%.1f(Form("hEtaPhi_%s_SE_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("Raw #Delta#eta#Delta#phi (%.1f(Form("hEtaPhi_%s_ME_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("Raw #Delta#eta#Delta#phi (%.1f(Form("hEtaPhi_%s_SE_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("Raw #Delta#eta#Delta#phi (%.1f(Form("hEtaPhi_%s_ME_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("Raw #Delta#eta#Delta#phi (%.1f(Form("hCorrEtaPhi_%s_SE_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("#Delta#eta#Delta#phi (%.1f(Form("hCorrEtaPhi_%s_ME_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("#Delta#eta#Delta#phi (%.1f(Form("hCorrEtaPhi_%s_SE_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("#Delta#eta#Delta#phi (%.1f(Form("hCorrEtaPhi_%s_ME_pt%02.0f%02.0f", name.Data(), pTBins.value.at(i) * 10, pTBins.value.at(i + 1) * 10), Form("#Delta#eta#Delta#phi (%.1f= min_TPC_nClusters && - o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedTpcChi2NCl) <= max_chi2_TPC && - o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedTpcCrossedRowsOverFindableCls) >= min_TPC_nCrossedRowsOverFindableCls && - o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedItsChi2NCl) <= max_chi2_ITS && - nabs(o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedDcaXY)) <= max_DCAxy && - nabs(o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedDcaXY)) <= max_DCAz && + Filter trackFilter = o2::aod::singletrackselector::tpcNClsFound >= minTPCnClusters && + o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedTpcChi2NCl) <= maxchi2TPC && + o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedTpcCrossedRowsOverFindableCls) >= minTPCnCrossedRowsOverFindableCls && + o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedItsChi2NCl) <= maxchi2ITS && + nabs(o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedDcaXY)) <= maxDCAxy && + nabs(o2::aod::singletrackselector::unPack(o2::aod::singletrackselector::storedDcaXY)) <= maxDCAz && nabs(o2::aod::singletrackselector::eta) <= etaCut; Filter simvertexFilter = nabs(o2::aod::mccollision::posZ) <= cutzVertex; @@ -427,14 +442,33 @@ struct HadronNucleiCorrelation { bool IsProton(Type const& track, int sign) { bool isProton = false; + bool isTPCPID = std::abs(track.tpcNSigmaPr()) < nsigmaTPC; bool isTOFPID = std::abs(track.tofNSigmaPr()) < nsigmaTOF; - bool isTPCElRejection = rejectionEl && track.beta() < betahasTOFthr && track.pt() < pTthrpr_TPCEl && track.tpcNSigmaEl() >= nsigmaElPr; + bool isTPCElRejection = rejectionEl && track.beta() < betahasTOFthr && track.pt() < pTthrprTPCEl && track.tpcNSigmaEl() >= nsigmaElPr; bool isITSPID = track.itsNSigmaPr() > nsigmaITSPr; - if (isTPCPID) { - if (track.pt() < pTthrpr_TOF) { - if (!doITSPID || isITSPID) { + bool isQuadraticPID = TMath::Sqrt(track.tpcNSigmaPr() * track.tpcNSigmaPr() + track.tofNSigmaPr() * track.tofNSigmaPr()) < nsigmaTPC; + + if (!doQuadraticPID) { + if (isTPCPID) { + if (track.pt() < pTthrprTOF) { + if (!doITSPID || isITSPID) { + if (sign > 0) { + if (track.sign() > 0) { + isProton = true; + } else if (track.sign() < 0) { + isProton = false; + } + } else if (sign < 0) { + if (track.sign() > 0) { + isProton = false; + } else if (track.sign() < 0) { + isProton = true; + } + } + } + } else if (isTPCElRejection) { if (sign > 0) { if (track.sign() > 0) { isProton = true; @@ -448,22 +482,42 @@ struct HadronNucleiCorrelation { isProton = true; } } - } - } else if (isTPCElRejection) { - if (sign > 0) { - if (track.sign() > 0) { - isProton = true; - } else if (track.sign() < 0) { - isProton = false; + } else if (isTOFPID) { + if (sign > 0) { + if (track.sign() > 0) { + isProton = true; + } else if (track.sign() < 0) { + isProton = false; + } + } else if (sign < 0) { + if (track.sign() > 0) { + isProton = false; + } else if (track.sign() < 0) { + isProton = true; + } } - } else if (sign < 0) { - if (track.sign() > 0) { - isProton = false; - } else if (track.sign() < 0) { - isProton = true; + } + } + } else { + if (track.pt() < pTthrprTOF) { + if (isTPCPID) { + if (!doITSPID || isITSPID) { + if (sign > 0) { + if (track.sign() > 0) { + isProton = true; + } else if (track.sign() < 0) { + isProton = false; + } + } else if (sign < 0) { + if (track.sign() > 0) { + isProton = false; + } else if (track.sign() < 0) { + isProton = true; + } + } } } - } else if (isTOFPID) { + } else if (isQuadraticPID) { if (sign > 0) { if (track.sign() > 0) { isProton = true; @@ -488,12 +542,30 @@ struct HadronNucleiCorrelation { bool isDeuteron = false; bool isTPCPID = std::abs(track.tpcNSigmaDe()) < nsigmaTPC; bool isTOFPID = std::abs(track.tofNSigmaDe()) < nsigmaTOF; - bool isTPCElRejection = rejectionEl && track.beta() < betahasTOFthr && track.pt() < pTthrde_TPCEl && track.tpcNSigmaEl() >= nsigmaElDe; + bool isTPCElRejection = rejectionEl && track.beta() < betahasTOFthr && track.pt() < pTthrdeTPCEl && track.tpcNSigmaEl() >= nsigmaElDe; bool isITSPID = track.itsNSigmaDe() > nsigmaITSDe; - if (isTPCPID) { - if (track.pt() < pTthrde_TOF) { - if (!doITSPID || isITSPID) { + bool isQuadraticPID = TMath::Sqrt(track.tpcNSigmaDe() * track.tpcNSigmaDe() + track.tofNSigmaDe() * track.tofNSigmaDe()) < nsigmaTPC; + + if (!doQuadraticPID) { + if (isTPCPID) { + if (track.pt() < pTthrdeTOF) { + if (!doITSPID || isITSPID) { + if (sign > 0) { + if (track.sign() > 0) { + isDeuteron = true; + } else if (track.sign() < 0) { + isDeuteron = false; + } + } else if (sign < 0) { + if (track.sign() > 0) { + isDeuteron = false; + } else if (track.sign() < 0) { + isDeuteron = true; + } + } + } + } else if (isTPCElRejection) { if (sign > 0) { if (track.sign() > 0) { isDeuteron = true; @@ -507,22 +579,42 @@ struct HadronNucleiCorrelation { isDeuteron = true; } } - } - } else if (isTPCElRejection) { - if (sign > 0) { - if (track.sign() > 0) { - isDeuteron = true; - } else if (track.sign() < 0) { - isDeuteron = false; + } else if (isTOFPID) { + if (sign > 0) { + if (track.sign() > 0) { + isDeuteron = true; + } else if (track.sign() < 0) { + isDeuteron = false; + } + } else if (sign < 0) { + if (track.sign() > 0) { + isDeuteron = false; + } else if (track.sign() < 0) { + isDeuteron = true; + } } - } else if (sign < 0) { - if (track.sign() > 0) { - isDeuteron = false; - } else if (track.sign() < 0) { - isDeuteron = true; + } + } + } else { + if (track.pt() < pTthrprTOF) { + if (isTPCPID) { + if (!doITSPID || isITSPID) { + if (sign > 0) { + if (track.sign() > 0) { + isDeuteron = true; + } else if (track.sign() < 0) { + isDeuteron = false; + } + } else if (sign < 0) { + if (track.sign() > 0) { + isDeuteron = false; + } else if (track.sign() < 0) { + isDeuteron = true; + } + } } } - } else if (isTOFPID) { + } else if (isQuadraticPID) { if (sign > 0) { if (track.sign() > 0) { isDeuteron = true; @@ -546,10 +638,10 @@ struct HadronNucleiCorrelation { { bool passcut = true; // pt-dependent selection - if (std::abs(track.dcaXY()) > (par0 + par1 / track.pt())) + if (std::abs(track.dcaXY()) > (dcaPar0 + dcaPar1 / track.pt())) passcut = false; - if (doDCAZ && std::abs(track.dcaZ()) > (par0 + par1 / track.pt())) + if (doDCAZ && std::abs(track.dcaZ()) > (dcaPar0 + dcaPar1 / track.pt())) passcut = false; return passcut; @@ -582,35 +674,35 @@ struct HadronNucleiCorrelation { if (doCorrection) { // Apply corrections switch (mode) { - case 0: + case kDbarPbar: corr0 = hEffpTEta_antideuteron->Interpolate(part0.pt(), part0.eta()); corr1 = hEffpTEta_antiproton->Interpolate(part1.pt(), part1.eta()); break; - case 1: + case kDP: corr0 = hEffpTEta_deuteron->Interpolate(part0.pt(), part0.eta()); corr1 = hEffpTEta_proton->Interpolate(part1.pt(), part1.eta()); break; - case 2: + case kDbarP: corr0 = hEffpTEta_antideuteron->Interpolate(part0.pt(), part0.eta()); corr1 = hEffpTEta_proton->Interpolate(part1.pt(), part1.eta()); break; - case 3: + case kDPbar: corr0 = hEffpTEta_deuteron->Interpolate(part0.pt(), part0.eta()); corr1 = hEffpTEta_antiproton->Interpolate(part1.pt(), part1.eta()); break; - case 4: + case kPbarP: corr0 = hEffpTEta_antiproton->Interpolate(part0.pt(), part0.eta()); corr1 = hEffpTEta_proton->Interpolate(part1.pt(), part1.eta()); break; - case 5: + case kPbarPbar: corr0 = hEffpTEta_antiproton->Interpolate(part0.pt(), part0.eta()); corr1 = hEffpTEta_antiproton->Interpolate(part1.pt(), part1.eta()); break; - case 6: + case kPP: corr0 = hEffpTEta_proton->Interpolate(part0.pt(), part0.eta()); corr1 = hEffpTEta_proton->Interpolate(part1.pt(), part1.eta()); break; - case 7: + case kPPbar: corr0 = hEffpTEta_proton->Interpolate(part0.pt(), part0.eta()); corr1 = hEffpTEta_antiproton->Interpolate(part1.pt(), part1.eta()); break; @@ -721,9 +813,10 @@ struct HadronNucleiCorrelation { registry.fill(HIST("hMult"), collision.mult()); for (const auto& track : tracks) { - if (track.tpcFractionSharedCls() > max_tpcSharedCls) + + if (track.tpcFractionSharedCls() > maxtpcSharedCls) continue; - if (track.itsNCls() < min_itsNCls) + if (track.itsNCls() < minitsNCls) continue; if (IsProton(track, +1)) @@ -755,6 +848,8 @@ struct HadronNucleiCorrelation { QA.fill(HIST("QA/hnSigmaTOFVsPt_De"), track.pt() * track.sign(), track.tofNSigmaDe()); QA.fill(HIST("QA/hnSigmaITSVsPt_Pr"), track.pt() * track.sign(), track.itsNSigmaPr()); QA.fill(HIST("QA/hnSigmaITSVsPt_De"), track.pt() * track.sign(), track.itsNSigmaDe()); + QA.fill(HIST("QA/h2dTPCTOF_AntiPr"), track.tpcNSigmaPr(), track.tofNSigmaPr()); + QA.fill(HIST("QA/h2dTPCTOF_Pr"), track.tpcNSigmaPr(), track.tofNSigmaPr()); if (IsProton(track, -1)) { QA.fill(HIST("QA/hEtaAntiPr"), track.eta()); @@ -762,6 +857,7 @@ struct HadronNucleiCorrelation { QA.fill(HIST("QA/hnSigmaTOFVsPt_Pr_AfterSel"), track.pt() * track.sign(), track.tofNSigmaPr()); QA.fill(HIST("QA/hnSigmaTPCVsPt_Pr_AfterSel"), track.pt() * track.sign(), track.tpcNSigmaPr()); QA.fill(HIST("QA/hnSigmaITSVsPt_Pr_AfterSel"), track.pt() * track.sign(), track.itsNSigmaPr()); + QA.fill(HIST("QA/h2dTPCTOF_AntiPr_AfterSel"), track.tpcNSigmaPr(), track.tofNSigmaPr()); } if (IsProton(track, +1)) { QA.fill(HIST("QA/hEtaPr"), track.eta()); @@ -769,6 +865,7 @@ struct HadronNucleiCorrelation { QA.fill(HIST("QA/hnSigmaTOFVsPt_Pr_AfterSel"), track.pt() * track.sign(), track.tofNSigmaPr()); QA.fill(HIST("QA/hnSigmaTPCVsPt_Pr_AfterSel"), track.pt() * track.sign(), track.tpcNSigmaPr()); QA.fill(HIST("QA/hnSigmaITSVsPt_Pr_AfterSel"), track.pt() * track.sign(), track.itsNSigmaPr()); + QA.fill(HIST("QA/h2dTPCTOF_Pr_AfterSel"), track.tpcNSigmaPr(), track.tofNSigmaPr()); } if (IsDeuteron(track, -1)) { QA.fill(HIST("QA/hEtaAntiDe"), track.eta()); @@ -794,13 +891,13 @@ struct HadronNucleiCorrelation { for (const auto& [part0, part1] : combinations(CombinationsStrictlyUpperIndexPolicy(tracks, tracks))) { - if (part0.tpcFractionSharedCls() > max_tpcSharedCls) + if (part0.tpcFractionSharedCls() > maxtpcSharedCls) continue; - if (part0.itsNCls() < min_itsNCls) + if (part0.itsNCls() < minitsNCls) continue; - if (part1.tpcFractionSharedCls() > max_tpcSharedCls) + if (part1.tpcFractionSharedCls() > maxtpcSharedCls) continue; - if (part1.itsNCls() < min_itsNCls) + if (part1.itsNCls() < minitsNCls) continue; if (!applyDCAcut(part0)) @@ -836,13 +933,13 @@ struct HadronNucleiCorrelation { for (const auto& [part0, part1] : combinations(CombinationsFullIndexPolicy(tracks, tracks))) { - if (part0.tpcFractionSharedCls() > max_tpcSharedCls) + if (part0.tpcFractionSharedCls() > maxtpcSharedCls) continue; - if (part0.itsNCls() < min_itsNCls) + if (part0.itsNCls() < minitsNCls) continue; - if (part1.tpcFractionSharedCls() > max_tpcSharedCls) + if (part1.tpcFractionSharedCls() > maxtpcSharedCls) continue; - if (part1.itsNCls() < min_itsNCls) + if (part1.itsNCls() < minitsNCls) continue; if (!applyDCAcut(part0)) @@ -900,6 +997,206 @@ struct HadronNucleiCorrelation { } PROCESS_SWITCH(HadronNucleiCorrelation, processSameEvent, "processSameEvent", true); + void processSameEventEvSel(FilteredCollisionsExtra::iterator const& collision, FilteredTracks const& tracks) + { + + registry.fill(HIST("hNEvents"), 0.5); + registry.fill(HIST("hMult"), collision.mult()); + + for (const auto& track : tracks) { + + if (removeSameBunchPileup && !track.template singleCollSel_as().isNoSameBunchPileup()) + continue; + + if (track.tpcFractionSharedCls() > maxtpcSharedCls) + continue; + if (track.itsNCls() < minitsNCls) + continue; + + if (IsProton(track, +1)) + registry.fill(HIST("hPrDCAxy"), track.dcaXY(), track.pt()); + if (IsProton(track, -1)) + registry.fill(HIST("hAntiPrDCAxy"), track.dcaXY(), track.pt()); + if (IsDeuteron(track, +1)) + registry.fill(HIST("hDeDCAxy"), track.dcaXY(), track.pt()); + if (IsDeuteron(track, -1)) + registry.fill(HIST("hAntiDeDCAxy"), track.dcaXY(), track.pt()); + + if (!applyDCAcut(track)) + continue; + + if (doQA) { + QA.fill(HIST("QA/hTPCnClusters"), track.tpcNClsFound()); + QA.fill(HIST("QA/hTPCSharedClusters"), track.tpcFractionSharedCls()); + QA.fill(HIST("QA/hTPCchi2"), track.tpcChi2NCl()); + QA.fill(HIST("QA/hTPCcrossedRowsOverFindableCls"), track.tpcCrossedRowsOverFindableCls()); + QA.fill(HIST("QA/hITSchi2"), track.itsChi2NCl()); + QA.fill(HIST("QA/hDCAxy"), track.dcaXY(), track.pt()); + QA.fill(HIST("QA/hDCAz"), track.dcaZ(), track.pt()); + QA.fill(HIST("QA/TPCChi2VsPZ"), track.tpcInnerParam() / track.sign(), track.tpcChi2NCl()); + QA.fill(HIST("QA/hVtxZ_trk"), collision.posZ()); + QA.fill(HIST("QA/hnSigmaTPCVsPt_El"), track.pt() * track.sign(), track.tpcNSigmaEl()); + QA.fill(HIST("QA/hnSigmaTPCVsPt_Pr"), track.pt() * track.sign(), track.tpcNSigmaPr()); + QA.fill(HIST("QA/hnSigmaTPCVsPt_De"), track.pt() * track.sign(), track.tpcNSigmaDe()); + QA.fill(HIST("QA/hnSigmaTOFVsPt_Pr"), track.pt() * track.sign(), track.tofNSigmaPr()); + QA.fill(HIST("QA/hnSigmaTOFVsPt_De"), track.pt() * track.sign(), track.tofNSigmaDe()); + QA.fill(HIST("QA/hnSigmaITSVsPt_Pr"), track.pt() * track.sign(), track.itsNSigmaPr()); + QA.fill(HIST("QA/hnSigmaITSVsPt_De"), track.pt() * track.sign(), track.itsNSigmaDe()); + QA.fill(HIST("QA/h2dTPCTOF_AntiPr"), track.tpcNSigmaPr(), track.tofNSigmaPr()); + QA.fill(HIST("QA/h2dTPCTOF_Pr"), track.tpcNSigmaPr(), track.tofNSigmaPr()); + + if (IsProton(track, -1)) { + QA.fill(HIST("QA/hEtaAntiPr"), track.eta()); + QA.fill(HIST("QA/hPhiAntiPr"), track.phi()); + QA.fill(HIST("QA/hnSigmaTOFVsPt_Pr_AfterSel"), track.pt() * track.sign(), track.tofNSigmaPr()); + QA.fill(HIST("QA/hnSigmaTPCVsPt_Pr_AfterSel"), track.pt() * track.sign(), track.tpcNSigmaPr()); + QA.fill(HIST("QA/hnSigmaITSVsPt_Pr_AfterSel"), track.pt() * track.sign(), track.itsNSigmaPr()); + QA.fill(HIST("QA/h2dTPCTOF_AntiPr_AfterSel"), track.tpcNSigmaPr(), track.tofNSigmaPr()); + } + if (IsProton(track, +1)) { + QA.fill(HIST("QA/hEtaPr"), track.eta()); + QA.fill(HIST("QA/hPhiPr"), track.phi()); + QA.fill(HIST("QA/hnSigmaTOFVsPt_Pr_AfterSel"), track.pt() * track.sign(), track.tofNSigmaPr()); + QA.fill(HIST("QA/hnSigmaTPCVsPt_Pr_AfterSel"), track.pt() * track.sign(), track.tpcNSigmaPr()); + QA.fill(HIST("QA/hnSigmaITSVsPt_Pr_AfterSel"), track.pt() * track.sign(), track.itsNSigmaPr()); + QA.fill(HIST("QA/h2dTPCTOF_Pr_AfterSel"), track.tpcNSigmaPr(), track.tofNSigmaPr()); + } + if (IsDeuteron(track, -1)) { + QA.fill(HIST("QA/hEtaAntiDe"), track.eta()); + QA.fill(HIST("QA/hPhiAntiDe"), track.phi()); + QA.fill(HIST("QA/hnSigmaTOFVsPt_De_AfterSel"), track.pt() * track.sign(), track.tofNSigmaDe()); + QA.fill(HIST("QA/hnSigmaTPCVsPt_De_AfterSel"), track.pt() * track.sign(), track.tpcNSigmaDe()); + QA.fill(HIST("QA/hnSigmaITSVsPt_De_AfterSel"), track.pt() * track.sign(), track.itsNSigmaDe()); + } + if (IsDeuteron(track, +1)) { + QA.fill(HIST("QA/hEtaDe"), track.eta()); + QA.fill(HIST("QA/hPhiDe"), track.phi()); + QA.fill(HIST("QA/hnSigmaTOFVsPt_De_AfterSel"), track.pt() * track.sign(), track.tofNSigmaDe()); + QA.fill(HIST("QA/hnSigmaTPCVsPt_De_AfterSel"), track.pt() * track.sign(), track.tpcNSigmaDe()); + QA.fill(HIST("QA/hnSigmaITSVsPt_De_AfterSel"), track.pt() * track.sign(), track.itsNSigmaDe()); + } + } + } + + Pair->SetMagField1(collision.magField()); + Pair->SetMagField2(collision.magField()); + + if (mode == kPbarPbar || mode == kPP) { // Identical particle combinations + + for (const auto& [part0, part1] : combinations(CombinationsStrictlyUpperIndexPolicy(tracks, tracks))) { + + if (removeSameBunchPileup && !part0.template singleCollSel_as().isNoSameBunchPileup()) + continue; + + if (part0.tpcFractionSharedCls() > maxtpcSharedCls) + continue; + if (part0.itsNCls() < minitsNCls) + continue; + if (part1.tpcFractionSharedCls() > maxtpcSharedCls) + continue; + if (part1.itsNCls() < minitsNCls) + continue; + + if (!applyDCAcut(part0)) + continue; + if (!applyDCAcut(part1)) + continue; + + // remove tracks outside pt bins + if (part0.pt() < pTBins.value.at(0) || part0.pt() >= pTBins.value.at(nBinspT)) + continue; + if (part1.pt() < pTBins.value.at(0) || part1.pt() >= pTBins.value.at(nBinspT)) + continue; + + // mode 6 + if (mode == kPP) { + if (!IsProton(part0, +1)) + continue; + if (!IsProton(part1, +1)) + continue; + } + // mode 5 + if (mode == kPbarPbar) { + if (!IsProton(part0, -1)) + continue; + if (!IsProton(part1, -1)) + continue; + } + + fillHistograms(part0, part1, false, true); + } + + } else { + + for (const auto& [part0, part1] : combinations(CombinationsFullIndexPolicy(tracks, tracks))) { + + if (removeSameBunchPileup && !part0.template singleCollSel_as().isNoSameBunchPileup()) + continue; + + if (part0.tpcFractionSharedCls() > maxtpcSharedCls) + continue; + if (part0.itsNCls() < minitsNCls) + continue; + if (part1.tpcFractionSharedCls() > maxtpcSharedCls) + continue; + if (part1.itsNCls() < minitsNCls) + continue; + + if (!applyDCAcut(part0)) + continue; + if (!applyDCAcut(part1)) + continue; + + // remove tracks outside pt bins + if (part0.pt() < pTBins.value.at(0) || part0.pt() >= pTBins.value.at(nBinspT)) + continue; + if (part1.pt() < pTBins.value.at(0) || part1.pt() >= pTBins.value.at(nBinspT)) + continue; + + // modes 0,1,2,3,4,7 + if (mode == kDbarPbar) { + if (!IsDeuteron(part0, -1)) + continue; + if (!IsProton(part1, -1)) + continue; + } + if (mode == kDP) { + if (!IsDeuteron(part0, +1)) + continue; + if (!IsProton(part1, +1)) + continue; + } + if (mode == kDbarP) { + if (!IsDeuteron(part0, -1)) + continue; + if (!IsProton(part1, +1)) + continue; + } + if (mode == kDPbar) { + if (!IsDeuteron(part0, +1)) + continue; + if (!IsProton(part1, -1)) + continue; + } + if (mode == kPbarP) { + if (!IsProton(part0, -1)) + continue; + if (!IsProton(part1, +1)) + continue; + } + if (mode == kPPbar) { + if (!IsProton(part0, +1)) + continue; + if (!IsProton(part1, -1)) + continue; + } + + fillHistograms(part0, part1, false, false); + } + } + } + PROCESS_SWITCH(HadronNucleiCorrelation, processSameEventEvSel, "processSameEventEvSel", false); + void processMixedEvent(FilteredCollisions const& collisions, FilteredTracks const& tracks) { @@ -913,7 +1210,9 @@ struct HadronNucleiCorrelation { const auto& magFieldTesla1 = collision1.magField(); const auto& magFieldTesla2 = collision2.magField(); - if (std::abs(magFieldTesla1 - magFieldTesla2) > 1e-4) { + const float limit = 1e-4; + + if (std::abs(magFieldTesla1 - magFieldTesla2) > limit) { continue; } @@ -922,13 +1221,13 @@ struct HadronNucleiCorrelation { for (const auto& [part0, part1] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { - if (part0.tpcFractionSharedCls() > max_tpcSharedCls) + if (part0.tpcFractionSharedCls() > maxtpcSharedCls) continue; - if (part0.itsNCls() < min_itsNCls) + if (part0.itsNCls() < minitsNCls) continue; - if (part1.tpcFractionSharedCls() > max_tpcSharedCls) + if (part1.tpcFractionSharedCls() > maxtpcSharedCls) continue; - if (part1.itsNCls() < min_itsNCls) + if (part1.itsNCls() < minitsNCls) continue; if (!applyDCAcut(part0)) @@ -1002,51 +1301,160 @@ struct HadronNucleiCorrelation { } PROCESS_SWITCH(HadronNucleiCorrelation, processMixedEvent, "processMixedEvent", true); + void processMixedEventEvSel(FilteredCollisionsExtra const& collisions, FilteredTracks const& tracks) + { + + for (const auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, collisions, collisions)) { + + // LOGF(info, "Mixed event collisions: (%d, %d) zvtx (%.1f, %.1f) mult (%d, %d)", collision1.globalIndex(), collision2.globalIndex(), collision1.posZ(), collision2.posZ(), collision1.mult(), collision2.mult()); + + auto groupPartsOne = tracks.sliceByCached(o2::aod::singletrackselector::singleCollSelId, collision1.globalIndex(), cache); + auto groupPartsTwo = tracks.sliceByCached(o2::aod::singletrackselector::singleCollSelId, collision2.globalIndex(), cache); + + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + + const float limit = 1e-4; + + if (std::abs(magFieldTesla1 - magFieldTesla2) > limit) { + continue; + } + + Pair->SetMagField1(magFieldTesla1); + Pair->SetMagField2(magFieldTesla2); + + for (const auto& [part0, part1] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + + if (removeSameBunchPileup && !part0.template singleCollSel_as().isNoSameBunchPileup()) + continue; + if (removeSameBunchPileup && !part1.template singleCollSel_as().isNoSameBunchPileup()) + continue; + + if (part0.tpcFractionSharedCls() > maxtpcSharedCls) + continue; + if (part0.itsNCls() < minitsNCls) + continue; + if (part1.tpcFractionSharedCls() > maxtpcSharedCls) + continue; + if (part1.itsNCls() < minitsNCls) + continue; + + if (!applyDCAcut(part0)) + continue; + if (!applyDCAcut(part1)) + continue; + + // remove tracks outside pt bins + if (part0.pt() < pTBins.value.at(0) || part0.pt() >= pTBins.value.at(nBinspT)) + continue; + if (part1.pt() < pTBins.value.at(0) || part1.pt() >= pTBins.value.at(nBinspT)) + continue; + + //{"mode", 0, "0: antid-antip, 1: d-p, 2: antid-p, 3: d-antip, 4: antip-p, 5: antip-antip, 6: p-p, 7: p-antip"}; + if (mode == kDbarPbar) { + if (!IsDeuteron(part0, -1)) + continue; + if (!IsProton(part1, -1)) + continue; + } + if (mode == kDP) { + if (!IsDeuteron(part0, +1)) + continue; + if (!IsProton(part1, +1)) + continue; + } + if (mode == kDbarP) { + if (!IsDeuteron(part0, -1)) + continue; + if (!IsProton(part1, +1)) + continue; + } + if (mode == kDPbar) { + if (!IsDeuteron(part0, +1)) + continue; + if (!IsProton(part1, -1)) + continue; + } + if (mode == kPbarP) { + if (!IsProton(part0, -1)) + continue; + if (!IsProton(part1, +1)) + continue; + } + if (mode == kPbarPbar) { + if (!IsProton(part0, -1)) + continue; + if (!IsProton(part1, -1)) + continue; + } + if (mode == kPP) { + if (!IsProton(part0, +1)) + continue; + if (!IsProton(part1, +1)) + continue; + } + if (mode == kPPbar) { + if (!IsProton(part0, +1)) + continue; + if (!IsProton(part1, -1)) + continue; + } + + bool isIdentical = false; + if (mode == kPbarPbar || mode == kPP) + isIdentical = true; + + fillHistograms(part0, part1, true, isIdentical); + } + } + } + PROCESS_SWITCH(HadronNucleiCorrelation, processMixedEventEvSel, "processMixedEventEvSel", false); + void processMC(FilteredCollisions const&, FilteredTracksMC const& tracks) { for (const auto& track : tracks) { if (std::abs(track.template singleCollSel_as().posZ()) > cutzVertex) continue; - if (track.tpcFractionSharedCls() > max_tpcSharedCls) + if (track.tpcFractionSharedCls() > maxtpcSharedCls) continue; - if (track.itsNCls() < min_itsNCls) + if (track.itsNCls() < minitsNCls) continue; if (IsProton(track, +1) && track.pdgCode() == PDG_t::kProton) { registry.fill(HIST("hPrDCAxy"), track.dcaXY(), track.pt()); - if (track.origin() == 0) + if (track.origin() == kPrimary) registry.fill(HIST("hPrimPrDCAxy"), track.dcaXY(), track.pt()); - if (track.origin() == 1) + if (track.origin() == kWeakDecay) registry.fill(HIST("hSecWeakPrDCAxy"), track.dcaXY(), track.pt()); - if (track.origin() == 2) + if (track.origin() == kMaterial) registry.fill(HIST("hSecMatPrDCAxy"), track.dcaXY(), track.pt()); } if (IsProton(track, -1) && track.pdgCode() == -PDG_t::kProton) { registry.fill(HIST("hAntiPrDCAxy"), track.dcaXY(), track.pt()); - if (track.origin() == 0) + if (track.origin() == kPrimary) registry.fill(HIST("hPrimAntiPrDCAxy"), track.dcaXY(), track.pt()); - if (track.origin() == 1) + if (track.origin() == kWeakDecay) registry.fill(HIST("hSecWeakAntiPrDCAxy"), track.dcaXY(), track.pt()); - if (track.origin() == 2) + if (track.origin() == kMaterial) registry.fill(HIST("hSecMatAntiPrDCAxy"), track.dcaXY(), track.pt()); } if (IsDeuteron(track, +1) && track.pdgCode() == o2::constants::physics::Pdg::kDeuteron) { registry.fill(HIST("hDeDCAxy"), track.dcaXY(), track.pt()); - if (track.origin() == 0) + if (track.origin() == kPrimary) registry.fill(HIST("hPrimDeDCAxy"), track.dcaXY(), track.pt()); - if (track.origin() == 1) + if (track.origin() == kWeakDecay) registry.fill(HIST("hSecWeakDeDCAxy"), track.dcaXY(), track.pt()); - if (track.origin() == 2) + if (track.origin() == kMaterial) registry.fill(HIST("hSecMatDeDCAxy"), track.dcaXY(), track.pt()); } if (IsDeuteron(track, -1) && track.pdgCode() == -o2::constants::physics::Pdg::kDeuteron) { registry.fill(HIST("hAntiDeDCAxy"), track.dcaXY(), track.pt()); - if (track.origin() == 0) + if (track.origin() == kPrimary) registry.fill(HIST("hPrimAntiDeDCAxy"), track.dcaXY(), track.pt()); - if (track.origin() == 1) + if (track.origin() == kWeakDecay) registry.fill(HIST("hSecWeakAntiDeDCAxy"), track.dcaXY(), track.pt()); - if (track.origin() == 2) + if (track.origin() == kMaterial) registry.fill(HIST("hSecMatAntiDeDCAxy"), track.dcaXY(), track.pt()); } @@ -1080,13 +1488,13 @@ struct HadronNucleiCorrelation { if (isPr) { registry.fill(HIST("hPrimSec_EtaPhiPt_Proton"), track.eta(), track.phi(), track.pt() * +1); - if (track.origin() == 1 || track.origin() == 2) { // secondaries + if (track.origin() == kWeakDecay || track.origin() == kMaterial) { // secondaries registry.fill(HIST("hSec_EtaPhiPt_Proton"), track.eta(), track.phi(), track.pt() * +1); } } if (isAntiPr) { registry.fill(HIST("hPrimSec_EtaPhiPt_Proton"), track.eta(), track.phi(), track.pt() * -1); - if (track.origin() == 1 || track.origin() == 2) { + if (track.origin() == kWeakDecay || track.origin() == kMaterial) { registry.fill(HIST("hSec_EtaPhiPt_Proton"), track.eta(), track.phi(), track.pt() * -1); } } @@ -1392,10 +1800,10 @@ struct HadronNucleiCorrelation { registry.fill(HIST("Generated/hQADeuterons"), 1.5); } - if (particle.pdgCode() == o2::constants::physics::Pdg::kDeuteron && std::abs(particle.y()) < 0.5) { + if (particle.pdgCode() == o2::constants::physics::Pdg::kDeuteron && std::abs(particle.y()) < yRap) { registry.fill(HIST("Generated/hDeuteronsVsPt"), particle.pt()); } - if (particle.pdgCode() == -o2::constants::physics::Pdg::kDeuteron && std::abs(particle.y()) < 0.5) { + if (particle.pdgCode() == -o2::constants::physics::Pdg::kDeuteron && std::abs(particle.y()) < yRap) { registry.fill(HIST("Generated/hAntiDeuteronsVsPt"), particle.pt()); } diff --git a/PWGLF/Tasks/Nuspex/lfNucleiBATask.cxx b/PWGLF/Tasks/Nuspex/lfNucleiBATask.cxx index 02b47ebdb03..56182078996 100644 --- a/PWGLF/Tasks/Nuspex/lfNucleiBATask.cxx +++ b/PWGLF/Tasks/Nuspex/lfNucleiBATask.cxx @@ -54,6 +54,7 @@ #include #include +#include #include #include #include @@ -68,8 +69,8 @@ using namespace o2::framework; using namespace o2::framework::expressions; struct lfNucleiBATask { - Service ccdb; - Service pdgDB; + Service ccdb{}; + Service pdgDB{}; Zorro zorro; OutputObj zorroSummary{"zorroSummary"}; @@ -108,6 +109,8 @@ struct lfNucleiBATask { Configurable useTVXtrigger{"useTVXtrigger", false, "Use TVX for Event Selection (default w/ Sel8)"}; Configurable removeTFBorder{"removeTFBorder", false, "Remove TimeFrame border (default w/ Sel8)"}; Configurable removeITSROFBorder{"removeITSROFBorder", false, "Remove ITS Read-Out Frame border (default w/ Sel8)"}; + Configurable useINELgt0cut{"useINELgt0cut", false, "Apply INEL>0 Event Selection in processData o processMC"}; + Configurable useINELgt1cut{"useINELgt1cut", false, "Apply INEL>1 Event Selection in processData o processMC"}; Configurable enableGenVzCut{"enableGenVzCut", true, "Apply cut in z-Vertex in the processGen function"}; } evselOptions; @@ -122,9 +125,9 @@ struct lfNucleiBATask { // Set the quality cuts for tracks struct : ConfigurableGroup { Configurable rejectFakeTracks{"rejectFakeTracks", false, "Flag to reject ITS-TPC fake tracks (for MC)"}; - Configurable cfgCutITSClusters{"cfgCutITSClusters", -1.f, "Minimum number of ITS clusters"}; - Configurable cfgCutTPCXRows{"cfgCutTPCXRows", -1.f, "Minimum number of crossed TPC rows"}; - Configurable cfgCutTPCClusters{"cfgCutTPCClusters", -1.f, "Minimum number of found TPC clusters"}; + Configurable cfgCutITSClusters{"cfgCutITSClusters", 3.f, "Minimum number of ITS clusters; set to -1 to disable"}; + Configurable cfgCutTPCXRows{"cfgCutTPCXRows", 70.f, "Minimum number of crossed TPC rows"}; + Configurable cfgCutTPCClusters{"cfgCutTPCClusters", 120.f, "Minimum number of found TPC clusters"}; Configurable cfgCutTPCCROFnd{"cfgCutTPCCROFnd", 0.8, "Minimum ratio of crossed TPC clusters over findable"}; Configurable> tpcChi2NclCuts{"tpcChi2NclCuts", {0.5, 4}, "Range of accepted of Chi2/TPC clusters"}; Configurable> itsChi2NclCuts{"itsChi2NclCuts", {0.f, 36}, "Range of accepted of Chi2/ITS clusters"}; @@ -133,10 +136,10 @@ struct lfNucleiBATask { // Set the kinematic and PID cuts for tracks struct : ConfigurableGroup { - Configurable cfgMomentumCut{"cfgMomentumCut", 0.3f, "Value of the p selection for spectra (default 0.3)"}; + Configurable cfgMomentumCut{"cfgMomentumCut", 0.42f, "Value of the p selection for spectra (default 0.3)"}; Configurable cfgEtaCut{"cfgEtaCut", 0.8f, "Value of the eta selection for spectra (default 0.8)"}; - Configurable cfgRapidityCutLow{"cfgRapidityCutLow", -1.0f, "Value of the low rapidity selection for spectra (default -1.0)"}; - Configurable cfgRapidityCutHigh{"cfgRapidityCutHigh", 1.0f, "Value of the high rapidity selection for spectra (default 1.0)"}; + Configurable cfgRapidityCutLow{"cfgRapidityCutLow", -0.5f, "Value of the low rapidity selection for spectra (default -1.0)"}; + Configurable cfgRapidityCutHigh{"cfgRapidityCutHigh", 0.5f, "Value of the high rapidity selection for spectra (default 1.0)"}; } kinemOptions; Configurable isPVContributorCut{"isPVContributorCut", false, "Flag to enable isPVContributor cut."}; @@ -144,17 +147,17 @@ struct lfNucleiBATask { struct : ConfigurableGroup { Configurable nsigmaTPCPr{"nsigmaTPCPr", 3.f, "Value of the Nsigma TPC cut for protons"}; - Configurable nsigmaTPCDe{"nsigmaTPCDe", 3.f, "Value of the Nsigma TPC cut for deuterons"}; - Configurable nsigmaTPCTr{"nsigmaTPCTr", 3.f, "Value of the Nsigma TPC cut for tritons"}; - Configurable nsigmaTPCHe{"nsigmaTPCHe", 3.f, "Value of the Nsigma TPC cut for helium-3"}; - Configurable nsigmaTPCAl{"nsigmaTPCAl", 3.f, "Value of the Nsigma TPC cut for alpha"}; + Configurable nsigmaTPCDe{"nsigmaTPCDe", 4.f, "Value of the Nsigma TPC cut for deuterons"}; + Configurable nsigmaTPCTr{"nsigmaTPCTr", 4.f, "Value of the Nsigma TPC cut for tritons"}; + Configurable nsigmaTPCHe{"nsigmaTPCHe", 5.f, "Value of the Nsigma TPC cut for helium-3"}; + Configurable nsigmaTPCAl{"nsigmaTPCAl", 5.f, "Value of the Nsigma TPC cut for alpha"}; } nsigmaTPCvar; struct : ConfigurableGroup { Configurable useITSDeCut{"useITSDeCut", false, "Select Deuteron if compatible with deuteron hypothesis (via SigmaITS)"}; - Configurable useITSHeCut{"useITSHeCut", false, "Select Helium if compatible with helium hypothesis (via SigmaITS)"}; - Configurable nsigmaITSDe{"nsigmaITSDe", -1.f, "Value of the Nsigma ITS cut for deuteron ( > nSigmaITSHe)"}; - Configurable nsigmaITSHe{"nsigmaITSHe", -1.f, "Value of the Nsigma ITS cut for helium-3 ( > nSigmaITSHe)"}; + Configurable useITSHeCut{"useITSHeCut", true, "Select Helium if compatible with helium hypothesis (via SigmaITS)"}; + Configurable nsigmaITSDe{"nsigmaITSDe", -3.f, "Value of the Nsigma ITS cut for deuteron ( > nSigmaITSHe)"}; + Configurable nsigmaITSHe{"nsigmaITSHe", -5.f, "Value of the Nsigma ITS cut for helium-3 ( > nSigmaITSHe)"}; Configurable showAverageClusterSize{"showAverageClusterSize", false, "Show average cluster size"}; } nsigmaITSvar; @@ -170,14 +173,14 @@ struct lfNucleiBATask { ConfigurableAxis binsdEdx{"binsdEdx", {600, 0.f, 3000.f}, ""}; ConfigurableAxis binsBeta{"binsBeta", {120, 0.0, 1.2}, ""}; ConfigurableAxis binsDCA{"binsDCA", {400, -1.f, 1.f}, ""}; - ConfigurableAxis binsSigmaITS{"binsSigmaITS", {200, -20, 20}, ""}; - ConfigurableAxis binsSigmaTPC{"binsSigmaTPC", {1000, -100, 100}, ""}; - ConfigurableAxis binsSigmaTOF{"binsSigmaTOF", {1000, -100, 100}, ""}; - ConfigurableAxis binsMassPr{"binsMassPr", {100, -1., 1.f}, ""}; - ConfigurableAxis binsMassDe{"binsMassDe", {180, -1.8, 1.8f}, ""}; - ConfigurableAxis binsMassTr{"binsMassTr", {250, -2.5, 2.5f}, ""}; - ConfigurableAxis binsMassHe{"binsMassHe", {300, -3., 3.f}, ""}; - ConfigurableAxis avClsBins{"avClsBins", {200, 0, 20}, "Binning in average cluster size"}; + ConfigurableAxis binsSigmaITS{"binsSigmaITS", {150, -15, 5}, ""}; + ConfigurableAxis binsSigmaTPC{"binsSigmaTPC", {290, -17, 12}, ""}; + ConfigurableAxis binsSigmaTOF{"binsSigmaTOF", {300, -15, 15}, ""}; + ConfigurableAxis binsMassPr{"binsMassPr", {400, -2., 2.f}, ""}; + ConfigurableAxis binsMassDe{"binsMassDe", {360, -1.8, 1.8f}, ""}; + ConfigurableAxis binsMassTr{"binsMassTr", {500, -2.5, 2.5f}, ""}; + ConfigurableAxis binsMassHe{"binsMassHe", {1000, -5., 5.f}, ""}; + ConfigurableAxis avClsBins{"avClsBins", {90, 0, 18}, "Binning in average cluster size"}; // Enable custom cuts/debug functions struct : ConfigurableGroup { @@ -186,15 +189,15 @@ struct lfNucleiBATask { Configurable enableEvTimeSplitting{"enableEvTimeSplitting", false, "Flag to enable histograms splitting depending on the Event Time used"}; } filterOptions; - Configurable enableCustomDCACut{"enableCustomDCACut", false, "Flag to enable DCA custom cuts - unflag to use standard isGlobalCut DCA cut"}; + Configurable enableCustomDCACut{"enableCustomDCACut", true, "Flag to enable DCA custom cuts - unflag to use standard isGlobalCut DCA cut"}; struct : ConfigurableGroup { Configurable cfgCustomDCA{"cfgCustomDCA", 0, "Select to use: pT independent DCAxy and DCAz CustomCut (0), pT dependent DCAxy and DCAz cut (1), pt dependent DCAxy, DCAz CustomCut (2) DCAxy CustomCut, pT dependent DCAz (3) or a circular DCAxy,z cut (4) for tracks. Need 'enableCustomDCACut' to be enabled."}; - Configurable cfgCustomDCAxy{"cfgCustomDCAxy", 0.05f, "Value of the DCAxy selection for spectra (default 0.05 cm)"}; + Configurable cfgCustomDCAxy{"cfgCustomDCAxy", 0.12f, "Value of the DCAxy selection for spectra (default 0.12 cm)"}; Configurable cfgCustomDCAz{"cfgCustomDCAz", 0.5f, "Value of the DCAz selection for spectra (default 0.5 cm)"}; } dcaConfOptions; - Configurable> parDCAxycuts{"parDCAxycuts", {0.004f, 0.013f, 1, 1}, "Parameters for Pt dependent DCAxy cut (if enabled): |DCAxy| < [3] * ([O] + [1]/Pt^[2])."}; - Configurable> parDCAzcuts{"parDCAzcuts", {0.004f, 0.013f, 1, 1}, "Parameters for Pt dependent DCAz cut (if enabled): |DCAz| < [3] * ([O] + [1]/Pt^[2])."}; + Configurable> parDCAxycuts{"parDCAxycuts", {0.004f, 0.013f, 1, 3}, "Parameters for Pt dependent DCAxy cut (if enabled): |DCAxy| < [3] * ([O] + [1]/Pt^[2])."}; + Configurable> parDCAzcuts{"parDCAzcuts", {0.004f, 0.013f, 1, 3}, "Parameters for Pt dependent DCAz cut (if enabled): |DCAz| < [3] * ([O] + [1]/Pt^[2])."}; // Enable output histograms struct : ConfigurableGroup { @@ -238,7 +241,7 @@ struct lfNucleiBATask { Configurable> parShiftPtAntiHe{"parShiftPtAntiHe", {0.0f, 0.1f, 0.1f, 0.1f, 0.1f}, "Parameters for anti-helium3-Pt shift (if enabled)."}; Configurable enablePtShiftPID{"enablePtShiftPID", true, "Flag to enable wrong PID in tracking pT correction shift"}; - Configurable> parShiftPtPID{"parShiftPtPID", {0.0f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f}, "Parameters for helium3-Pt wrong pid shift (if enabled)."}; + Configurable> parShiftPtPID{"parShiftPtPID", {0.000048972, 12.2439, -0.493803, -9.06264, 3.4022, -0.17518, -0.087316}, "Parameters for helium3-Pt wrong pid shift (if enabled)."}; // o2-linter: disable=pdg/explicit-mass (there are not masses but calibration values) Configurable cfgPtShiftPID{"cfgPtShiftPID", 1.25f, "Default upper limit for PID pt-shift correction"}; Configurable enableCentrality{"enableCentrality", true, "Flag to enable centrality 3D histos)"}; @@ -246,7 +249,7 @@ struct lfNucleiBATask { // ITS to TPC - Fake hit loop static constexpr int IntFakeLoop = 10; // Fixed O2Linter error // TPC low/high momentum range - static constexpr float CfgTpcClasses[] = {0.5f, 0.1f}; + static constexpr std::array CfgTpcClasses = {0.5f, 1.5f}; static constexpr float CfgKaonCut = 5.f; // PDG codes and masses used in this analysis @@ -257,7 +260,7 @@ struct lfNucleiBATask { static constexpr int PDGTriton = o2::constants::physics::Pdg::kTriton; static constexpr int PDGHelium = o2::constants::physics::Pdg::kHelium3; static constexpr int PDGAlpha = o2::constants::physics::Pdg::kAlpha; - static constexpr int PDGHyperTriton = o2::constants::physics::Pdg::kHyperTriton; + // static constexpr int PDGHyperTriton = o2::constants::physics::Pdg::kHyperTriton; // not used static constexpr float MassProtonVal = o2::constants::physics::MassProton; static constexpr float MassDeuteronVal = o2::constants::physics::MassDeuteron; static constexpr float MassTritonVal = o2::constants::physics::MassTriton; @@ -265,35 +268,13 @@ struct lfNucleiBATask { static constexpr float MassAlphaVal = o2::constants::physics::MassAlpha; // PDG of Mothers - static constexpr int PdgMotherList[] = { - PDG_t::kPiPlus, - PDG_t::kKPlus, - PDG_t::kK0Short, - PDG_t::kNeutron, - PDG_t::kProton, - PDG_t::kLambda0, - o2::constants::physics::Pdg::kDeuteron, - o2::constants::physics::Pdg::kHelium3, - o2::constants::physics::Pdg::kTriton, - o2::constants::physics::Pdg::kHyperTriton, - o2::constants::physics::Pdg::kAlpha}; - - static constexpr int NumMotherList = sizeof(PdgMotherList) / sizeof(PdgMotherList[0]); - - static constexpr const char* kMotherNames[NumMotherList] = { - "#pi^{+}", - "K^{+}", - "K^{0}_{S}", - "n", - "p", - "#Lambda", - "d", - "He3", - "t", - "^{3}_{#Lambda}H", - "He4"}; - - static constexpr int kMaxNumMom = 2; // X: 0..4, overflow=5 + static constexpr std::array PdgMotherList = {PDG_t::kPiPlus, PDG_t::kKPlus, PDG_t::kK0Short, PDG_t::kNeutron, PDG_t::kProton, PDG_t::kLambda0, o2::constants::physics::Pdg::kDeuteron, o2::constants::physics::Pdg::kHelium3, o2::constants::physics::Pdg::kTriton, o2::constants::physics::Pdg::kHyperTriton, o2::constants::physics::Pdg::kAlpha}; + + static constexpr int NumMotherList = PdgMotherList.size(); + + static constexpr std::array MotherNames = {"#pi^{+}", "K^{+}", "K^{0}_{S}", "n", "p", "#Lambda", "d", "He3", "t", "^{3}_{#Lambda}H", "He4"}; + + static constexpr int MaxNumMom = 2; // X: 0..4, overflow=5 template float averageClusterSizeTrk(const TrackType& track) @@ -317,6 +298,30 @@ struct lfNucleiBATask { } } + template + float getPFromPt(const TrackType& track, const float pt) + { + return pt * std::cosh(track.eta()); + } + + template + float getPzFromPt(const TrackType& track, const float pt) + { + return pt * std::sinh(track.eta()); + } + + template + float getRapidityFromPtMass(const TrackType& track, const float pt, const float mass) + { + const float pz = getPzFromPt(track, pt); + const float p = getPFromPt(track, pt); + const float e = std::sqrt(p * p + mass * mass); + if (e <= std::abs(pz)) { + return -999.f; + } + return 0.5f * std::log((e + pz) / (e - pz)); + } + void init(o2::framework::InitContext& context) { if (initITSPID) { @@ -348,9 +353,13 @@ struct lfNucleiBATask { const AxisSpec avClsAxis{avClsBins, ""}; const AxisSpec avClsEffAxis{avClsBins, " / cosh(#eta)"}; - if (((doprocessData == true) || (doprocessDataLfPid == true)) && ((doprocessMCReco == true) || (doprocessMCRecoLfPid == true) || (doprocessMCGen == true))) { + if (((doprocessData) || (doprocessDataLfPid)) && ((doprocessMCReco) || (doprocessMCRecoLfPid) || (doprocessMCGen))) { LOG(fatal) << "Can't enable processData and processMCReco in the same time, pick one!"; } + if (enablePtShiftHe && enablePtShiftPID) { + LOG(fatal) << "Invalid configuration: enablePtShiftHe and enablePtShiftPID cannot be enabled at the same time." + << "They define alternative pT-shift corrections for (anti)helium. Pick one!"; + } if (doprocessEvSgLossMC) { evLossHistos.add("evLoss/hEvent", "Event loss histograms; ; counts", HistType::kTH1F, {{4, 0., 4.}}); evLossHistos.get(HIST("evLoss/hEvent"))->GetXaxis()->SetBinLabel(1, "All Gen."); @@ -358,24 +367,29 @@ struct lfNucleiBATask { evLossHistos.get(HIST("evLoss/hEvent"))->GetXaxis()->SetBinLabel(3, "MC Sel8 (TVX + NoTFB) (reco.)"); evLossHistos.get(HIST("evLoss/hEvent"))->GetXaxis()->SetBinLabel(4, "Sel8 (reco.)"); - evLossHistos.add("evLoss/pt/hDeuteronTriggeredTVX", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - evLossHistos.add("evLoss/pt/hDeuteronTriggeredSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - evLossHistos.add("evLoss/pt/hDeuteronTriggeredMCSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - evLossHistos.add("evLoss/pt/hDeuteronGen", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - evLossHistos.add("evLoss/pt/hAntiDeuteronTriggeredTVX", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - evLossHistos.add("evLoss/pt/hAntiDeuteronTriggeredMCSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - evLossHistos.add("evLoss/pt/hAntiDeuteronTriggeredSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - evLossHistos.add("evLoss/pt/hAntiDeuteronGen", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - - evLossHistos.add("evLoss/pt/hHeliumTriggeredTVX", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - evLossHistos.add("evLoss/pt/hHeliumTriggeredSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - evLossHistos.add("evLoss/pt/hHeliumTriggeredMCSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - evLossHistos.add("evLoss/pt/hHeliumGen", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - evLossHistos.add("evLoss/pt/hAntiHeliumTriggeredTVX", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - evLossHistos.add("evLoss/pt/hAntiHeliumTriggeredSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - evLossHistos.add("evLoss/pt/hAntiHeliumTriggeredMCSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); - evLossHistos.add("evLoss/pt/hAntiHeliumGen", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + if (enableDe) { + evLossHistos.add("evLoss/pt/hDeuteronTriggeredTVX", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + evLossHistos.add("evLoss/pt/hDeuteronTriggeredSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + evLossHistos.add("evLoss/pt/hDeuteronTriggeredMCSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + evLossHistos.add("evLoss/pt/hDeuteronGen", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + evLossHistos.add("evLoss/pt/hAntiDeuteronTriggeredTVX", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + evLossHistos.add("evLoss/pt/hAntiDeuteronTriggeredMCSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + evLossHistos.add("evLoss/pt/hAntiDeuteronTriggeredSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + evLossHistos.add("evLoss/pt/hAntiDeuteronGen", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + } + + if (enableHe) { + evLossHistos.add("evLoss/pt/hHeliumTriggeredTVX", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + evLossHistos.add("evLoss/pt/hHeliumTriggeredSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + evLossHistos.add("evLoss/pt/hHeliumTriggeredMCSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + evLossHistos.add("evLoss/pt/hHeliumGen", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + evLossHistos.add("evLoss/pt/hAntiHeliumTriggeredTVX", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + evLossHistos.add("evLoss/pt/hAntiHeliumTriggeredSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + evLossHistos.add("evLoss/pt/hAntiHeliumTriggeredMCSel8", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + evLossHistos.add("evLoss/pt/hAntiHeliumGen", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{100, 0., 5.}}); + } } + if (doprocessMCRecoLfPidEv) { spectraGen.add("LfEv/pT_nocut", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{ptHeAxis}}); spectraGen.add("LfEv/pT_TVXtrigger", "Track #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{ptHeAxis}}); @@ -514,10 +528,11 @@ struct lfNucleiBATask { if (enableCentrality) { histos.add("event/eventSelection", "eventSelection", HistType::kTH2D, {{11, -0.5, 10.5}, {binsPercentile, "Centrality FT0M"}}); auto h2d = histos.get(HIST("event/eventSelection")); - if (skimmingOptions.applySkimming) + if (skimmingOptions.applySkimming) { h2d->GetXaxis()->SetBinLabel(1, "Skimmed events"); - else + } else { h2d->GetXaxis()->SetBinLabel(1, "Total"); + } h2d->GetXaxis()->SetBinLabel(2, "TVX trigger cut"); h2d->GetXaxis()->SetBinLabel(3, "TF border cut"); @@ -526,16 +541,17 @@ struct lfNucleiBATask { h2d->GetXaxis()->SetBinLabel(6, "Sel8 cut"); h2d->GetXaxis()->SetBinLabel(7, "Z-vert Cut"); h2d->GetXaxis()->SetBinLabel(8, "Multiplicity cut"); - h2d->GetXaxis()->SetBinLabel(9, "INEL"); + h2d->GetXaxis()->SetBinLabel(9, "MB"); h2d->GetXaxis()->SetBinLabel(10, "INEL > 0"); h2d->GetXaxis()->SetBinLabel(11, "INEL > 1"); } else { histos.add("event/eventSelection", "eventSelection", HistType::kTH1D, {{11, -0.5, 10.5}}); auto h1d = histos.get(HIST("event/eventSelection")); - if (skimmingOptions.applySkimming) + if (skimmingOptions.applySkimming) { h1d->GetXaxis()->SetBinLabel(1, "Skimmed events"); - else + } else { h1d->GetXaxis()->SetBinLabel(1, "Total"); + } h1d->GetXaxis()->SetBinLabel(2, "TVX trigger cut"); h1d->GetXaxis()->SetBinLabel(3, "TF border cut"); @@ -544,7 +560,7 @@ struct lfNucleiBATask { h1d->GetXaxis()->SetBinLabel(6, "Sel8 cut"); h1d->GetXaxis()->SetBinLabel(7, "Z-vert Cut"); h1d->GetXaxis()->SetBinLabel(8, "Multiplicity cut"); - h1d->GetXaxis()->SetBinLabel(9, "INEL"); + h1d->GetXaxis()->SetBinLabel(9, "MB"); h1d->GetXaxis()->SetBinLabel(10, "INEL > 0"); h1d->GetXaxis()->SetBinLabel(11, "INEL > 1"); } @@ -797,6 +813,10 @@ struct lfNucleiBATask { histos.add("tracks/deuteron/h2DeuteronYvsPt", "#it{y} vs #it{p}_{T} (d)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); histos.add("tracks/deuteron/h2antiDeuteronYvsPt", "#it{y} vs #it{p}_{T} (#bar{d})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + + histos.add("tracks/deuteron/h2DeuteronShiftYvsPt", "#it{y} vs #it{p}_{T} (d)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/deuteron/h2antiDeuteronShiftYvsPt", "#it{y} vs #it{p}_{T} (#bar{d})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/deuteron/h2DeuteronEtavsPt", "#it{#eta} vs #it{p}_{T} (d)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); histos.add("tracks/deuteron/h2antiDeuteronEtavsPt", "#it{#eta} vs #it{p}_{T} (#bar{d})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); } @@ -806,23 +826,52 @@ struct lfNucleiBATask { } if (enableHe) { histos.add("tracks/helium/h2HeliumYvsPt_Z2", "#it{y} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptHeAxis}}); + histos.add("tracks/helium/h2HeliumShiftYvsPt_Z2", "#it{y} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptHeAxis}}); histos.add("tracks/helium/h2HeliumEtavsPt_Z2", "#it{#eta} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptHeAxis}}); + histos.add("tracks/helium/h2antiHeliumYvsPt_Z2", "#it{y} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptHeAxis}}); + histos.add("tracks/helium/h2antiHeliumShiftYvsPt_Z2", "#it{y} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptHeAxis}}); + histos.add("tracks/helium/h2antiHeliumEtavsPt_Z2", "#it{#eta} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptHeAxis}}); + histos.add("tracks/helium/h1HeliumSpectra_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptHeAxis}); histos.add("tracks/helium/h1antiHeliumSpectra_Z2", "#it{p}_{T} (#bar{He})", HistType::kTH1F, {ptHeAxis}); if (enableDebug) { debugHistos.add("tracks/helium/h2HeliumPidTrackingVsPt", "#it{p}_{T} (He) vs PIDforTracking", HistType::kTH2F, {{80, 0, 8}, {12, -0.5, 11.5}}); debugHistos.add("tracks/helium/h2antiHeliumPidTrackingVsPt", "#it{p}_{T} (#bar{He}) vs PIDforTracking", HistType::kTH2F, {{80, 0, 8}, {12, -0.5, 11.5}}); + + debugHistos.add("tracks/helium/h2HeCutFlowVsPt", "He cut-flow checker;#it{p}_{T} (GeV/#it{c});selection step", HistType::kTH2F, {{ptHeAxis}, {10, -0.5, 9.5}}); + debugHistos.add("tracks/helium/h2antiHeCutFlowVsPt", "#bar{He} cut-flow checker;#it{p}_{T} (GeV/#it{c});selection step", HistType::kTH2F, {{ptHeAxis}, {10, -0.5, 9.5}}); + + auto hHeCutFlow = debugHistos.get(HIST("tracks/helium/h2HeCutFlowVsPt")); + hHeCutFlow->GetYaxis()->SetBinLabel(1, "all tracks"); + hHeCutFlow->GetYaxis()->SetBinLabel(2, "quality cuts"); + hHeCutFlow->GetYaxis()->SetBinLabel(3, "global track"); + hHeCutFlow->GetYaxis()->SetBinLabel(4, "p eta cuts"); + hHeCutFlow->GetYaxis()->SetBinLabel(5, "pt shift"); + hHeCutFlow->GetYaxis()->SetBinLabel(6, "rapidity"); + hHeCutFlow->GetYaxis()->SetBinLabel(7, "ITS PID"); + hHeCutFlow->GetYaxis()->SetBinLabel(8, "DCA"); + hHeCutFlow->GetYaxis()->SetBinLabel(9, "TPC PID"); + hHeCutFlow->GetYaxis()->SetBinLabel(10, "TOF hit"); + + auto hAntiHeCutFlow = debugHistos.get(HIST("tracks/helium/h2antiHeCutFlowVsPt")); + hAntiHeCutFlow->GetYaxis()->SetBinLabel(1, "all tracks"); + hAntiHeCutFlow->GetYaxis()->SetBinLabel(2, "quality cuts"); + hAntiHeCutFlow->GetYaxis()->SetBinLabel(3, "global track"); + hAntiHeCutFlow->GetYaxis()->SetBinLabel(4, "p eta cuts"); + hAntiHeCutFlow->GetYaxis()->SetBinLabel(5, "pt shift"); + hAntiHeCutFlow->GetYaxis()->SetBinLabel(6, "rapidity"); + hAntiHeCutFlow->GetYaxis()->SetBinLabel(7, "ITS PID"); + hAntiHeCutFlow->GetYaxis()->SetBinLabel(8, "DCA"); + hAntiHeCutFlow->GetYaxis()->SetBinLabel(9, "TPC PID"); + hAntiHeCutFlow->GetYaxis()->SetBinLabel(10, "TOF hit"); } if (outFlagOptions.doTOFplots && enableCentrality) { histos.add("tracks/helium/TOF/h2HeliumSpectraVsMult_Z2", "#it{p}_{T} (He)", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); histos.add("tracks/helium/TOF/h2antiHeliumSpectraVsMult_Z2", "#it{p}_{T} (#bar{He})", HistType::kTH2F, {{ptHeAxis}, {binsPercentile}}); } - - histos.add("tracks/helium/h2antiHeliumYvsPt_Z2", "#it{y} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptHeAxis}}); - histos.add("tracks/helium/h2antiHeliumEtavsPt_Z2", "#it{#eta} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptHeAxis}}); } if (enableAl) { histos.add("tracks/alpha/h1AlphaSpectra", "#it{p}_{T} (#alpha)", HistType::kTH1F, {ptAxis}); @@ -1112,7 +1161,7 @@ struct lfNucleiBATask { ayPdgPr->SetBinLabel(1, "undef."); ayPdgPr->SetBinLabel(2, "other"); for (int i = 0; i < NumMotherList; i++) { - ayPdgPr->SetBinLabel(i + 3, kMotherNames[i]); + ayPdgPr->SetBinLabel(i + 3, MotherNames[i]); } histos.add("tracks/proton/dca/before/hDCAxyVsPtantiProtonTrue", "DCAxy vs Pt (#bar{p}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); @@ -1184,7 +1233,7 @@ struct lfNucleiBATask { ayPdgDe->SetBinLabel(1, "undef."); ayPdgDe->SetBinLabel(2, "other"); for (int i = 0; i < NumMotherList; i++) { - ayPdgDe->SetBinLabel(i + 3, kMotherNames[i]); + ayPdgDe->SetBinLabel(i + 3, MotherNames[i]); } histos.add("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronTrue", "DCAxy vs Pt (#bar{d}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); @@ -1303,21 +1352,6 @@ struct lfNucleiBATask { histos.add("tracks/triton/dca/before/TOF/hDCAxyVsPtantiTritonTruePrim", "DCAxy vs Pt (#bar{t}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); histos.add("tracks/triton/dca/before/TOF/hDCAxyVsPtantiTritonTrueSec", "DCAxy vs Pt (#bar{t}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); histos.add("tracks/triton/dca/before/TOF/hDCAxyVsPtantiTritonTrueMaterial", "DCAxy vs Pt (#bar{t}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - - // Unused histograms - // histos.add("tracks/triton/dca/before/TOF/hDCAzVsPtTritonTrue", "DCAz vs Pt (t); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - - // histos.add("tracks/triton/dca/before/TOF/hDCAzVsPtTritonTruePrim", "DCAz vs Pt (t); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - // histos.add("tracks/triton/dca/before/TOF/hDCAzVsPtTritonTrueSec", "DCAz vs Pt (t); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - // histos.add("tracks/triton/dca/before/TOF/hDCAzVsPtTritonTrueMaterial", "DCAz vs Pt (t); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - // histos.add("tracks/triton/dca/before/TOF/hDCAzVsPtTritonTrueTransport", "DCAz vs Pt (t); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - - // histos.add("tracks/triton/dca/before/TOF/hDCAzVsPtantiTritonTrue", "DCAz vs Pt (#bar{t}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - - // histos.add("tracks/triton/dca/before/TOF/hDCAzVsPtantiTritonTruePrim", "DCAz vs Pt (#bar{t}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - // histos.add("tracks/triton/dca/before/TOF/hDCAzVsPtantiTritonTrueSec", "DCAz vs Pt (#bar{t}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - // histos.add("tracks/triton/dca/before/TOF/hDCAzVsPtantiTritonTrueMaterial", "DCAz vs Pt (#bar{t}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - // histos.add("tracks/triton/dca/before/TOF/hDCAzVsPtantiTritonTrueTransport", "DCAz vs Pt (#bar{t}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); } } @@ -1359,7 +1393,7 @@ struct lfNucleiBATask { ayPdgHe->SetBinLabel(1, "undef."); ayPdgHe->SetBinLabel(2, "other"); for (int i = 0; i < NumMotherList; i++) { - ayPdgHe->SetBinLabel(i + 3, kMotherNames[i]); + ayPdgHe->SetBinLabel(i + 3, MotherNames[i]); } histos.add("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTrue", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptZHeAxis}, {dcaxyAxis}}); @@ -2454,14 +2488,24 @@ struct lfNucleiBATask { histos.fill(HIST("event/eventSelection"), 10); } - float gamma = 0., massTOF = 0., massTOFhe = 0., massTOFantihe = 0., heTPCmomentum = 0.f, antiheTPCmomentum = 0.f, heP = 0.f, antiheP = 0.f, hePt = 0.f, antihePt = 0.f, antiDPt = 0.f, DPt = 0.f; - bool isTritonTPCpid = false; + if (evselOptions.useINELgt0cut && !event.isInelGt0()) + return; + if (evselOptions.useINELgt1cut && !event.isInelGt1()) + return; + + bool passPrTPCpid = false; + bool passDeTPCpid = false; + bool passTrTPCpid = false; + bool passHeTPCpid = false; + bool passAlTPCpid = false; bool prRapCut = false; bool deRapCut = false; bool trRapCut = false; bool heRapCut = false; bool alRapCut = false; + bool hasTOFplots = false; + // Event histos fill if (enableCentrality) histos.fill(HIST("event/h1VtxZ"), event.posZ(), centFT0M); @@ -2489,53 +2533,116 @@ struct lfNucleiBATask { } tracks.copyIndexBindings(tracksWithITS); + auto tpcChi2NclRange = (std::vector)trkqcOptions.tpcChi2NclCuts; + auto itsChi2NclRange = (std::vector)trkqcOptions.itsChi2NclCuts; for (auto const& track : tracksWithITS) { - if constexpr (!IsFilteredData) { - if (!track.isGlobalTrackWoDCA() && filterOptions.enableIsGlobalTrack) { - continue; - } - } - std::bitset<8> itsClusterMap = track.itsClusterMap(); + // Init all temp variables inside the track loop + float gamma = 0.; - if constexpr (!IsFilteredData) { - if (nsigmaITSvar.showAverageClusterSize && outFlagOptions.enablePIDplot) - histos.fill(HIST("tracks/avgClusterSizePerCoslInvVsITSlayers"), track.p(), averageClusterSizePerCoslInv(track), track.itsNCls()); + // Deuteron and helium pt init, before applying shift + const float trackPt = track.pt(); + const float trackP = track.p(); + const float trackTPCmomentum = track.tpcInnerParam(); + + float DPt = trackPt; + float antiDPt = trackPt; + + float hePt = trackPt; + float antihePt = trackPt; + + float heP = trackP; + float antiheP = trackP; + + float heTPCmomentum = trackTPCmomentum; + float antiheTPCmomentum = trackTPCmomentum; + + float massTOF = -99.f, massTOFhe = -99.f, massTOFantihe = -99.f; + + // all tracks checker + if (enableDebug && enableHe) { + if (track.sign() > 0) + debugHistos.fill(HIST("tracks/helium/h2HeCutFlowVsPt"), 2.f * track.pt(), 0); + else + debugHistos.fill(HIST("tracks/helium/h2antiHeCutFlowVsPt"), 2.f * track.pt(), 0); } - if (track.itsNCls() < trkqcOptions.cfgCutITSClusters || + std::bitset<8> itsClusterMap = track.itsClusterMap(); + + // Quality cuts + if ((trkqcOptions.cfgCutITSClusters >= 0 && track.itsNCls() < trkqcOptions.cfgCutITSClusters) || track.tpcNClsCrossedRows() < trkqcOptions.cfgCutTPCXRows || track.tpcNClsFound() < trkqcOptions.cfgCutTPCClusters || track.tpcCrossedRowsOverFindableCls() < trkqcOptions.cfgCutTPCCROFnd) { continue; } - auto tpcChi2NclRange = (std::vector)trkqcOptions.tpcChi2NclCuts; + // TCP/ITS Chi2/ncl cuts if ((track.tpcChi2NCl() < tpcChi2NclRange[0]) || (track.tpcChi2NCl() > tpcChi2NclRange[1])) continue; - auto itsChi2NclRange = (std::vector)trkqcOptions.itsChi2NclCuts; if ((track.itsChi2NCl() < itsChi2NclRange[0]) || (track.itsChi2NCl() > itsChi2NclRange[1])) continue; + // qchecks checker + if (enableDebug && enableHe) { + if (track.sign() > 0) + debugHistos.fill(HIST("tracks/helium/h2HeCutFlowVsPt"), 2.f * track.pt(), 1); + else + debugHistos.fill(HIST("tracks/helium/h2antiHeCutFlowVsPt"), 2.f * track.pt(), 1); + } + + // QA histos fill + if (enableDebug) { + histos.fill(HIST("qa/h1ITSncr"), track.itsNCls()); + histos.fill(HIST("qa/h1TPCncr"), track.tpcNClsCrossedRows()); + histos.fill(HIST("qa/h1TPCnfound"), track.tpcNClsFound()); + histos.fill(HIST("qa/h1rTPC"), track.tpcCrossedRowsOverFindableCls()); + histos.fill(HIST("qa/h1chi2ITS"), track.itsChi2NCl()); + histos.fill(HIST("qa/h1chi2TPC"), track.tpcChi2NCl()); + debugHistos.fill(HIST("debug/h2TPCsignVsTPCmomentum_AllTracks"), track.tpcInnerParam() / (1.f * track.sign()), track.tpcSignal()); + } + + // isGlobalTrack + if constexpr (!IsFilteredData) { + if (!track.isGlobalTrackWoDCA() && filterOptions.enableIsGlobalTrack) { + continue; + } + } + if (enableDebug && enableHe) { + if (track.sign() > 0) + debugHistos.fill(HIST("tracks/helium/h2HeCutFlowVsPt"), 2.f * track.pt(), 2); + else + debugHistos.fill(HIST("tracks/helium/h2antiHeCutFlowVsPt"), 2.f * track.pt(), 2); + } + // p & eta cut if (std::abs(track.tpcInnerParam()) < kinemOptions.cfgMomentumCut || std::abs(track.eta()) > kinemOptions.cfgEtaCut) continue; + if (enableDebug && enableHe) { + if (track.sign() > 0) + debugHistos.fill(HIST("tracks/helium/h2HeCutFlowVsPt"), 2.f * track.pt(), 3); + else + debugHistos.fill(HIST("tracks/helium/h2antiHeCutFlowVsPt"), 2.f * track.pt(), 3); + } if (outFlagOptions.enablePIDplot) { histos.fill(HIST("tracks/h1pT"), track.pt()); histos.fill(HIST("tracks/h1p"), track.p()); } - isTritonTPCpid = std::abs(track.tpcNSigmaTr()) < nsigmaTPCvar.nsigmaTPCTr; + passPrTPCpid = std::abs(track.tpcNSigmaPr()) < nsigmaTPCvar.nsigmaTPCPr; + passDeTPCpid = std::abs(track.tpcNSigmaDe()) < nsigmaTPCvar.nsigmaTPCDe; + passTrTPCpid = std::abs(track.tpcNSigmaTr()) < nsigmaTPCvar.nsigmaTPCTr; + passHeTPCpid = std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe; + passAlTPCpid = std::abs(track.tpcNSigmaAl()) < nsigmaTPCvar.nsigmaTPCAl; + + hasTOFplots = track.hasTOF() && outFlagOptions.doTOFplots; + bool heliumPID = track.pidForTracking() == o2::track::PID::Helium3 || track.pidForTracking() == o2::track::PID::Alpha; bool tritonPID = track.pidForTracking() == o2::track::PID::Triton; bool deuteronPID = track.pidForTracking() == o2::track::PID::Deuteron; - float shiftPtPos = 0.f; - float shiftPtNeg = 0.f; - float shiftPtPID = 0.f; - if (enablePtShiftHe && !fShiftPtHe) { fShiftPtHe = new TF1("fShiftPtHe", "[0] * exp([1] + [2] * x) + [3] + [4] * x", 0.f, 8.f); auto parHe = (std::vector)parShiftPtHe; // NOLINT @@ -2554,22 +2661,16 @@ struct lfNucleiBATask { fShiftAntiD->SetParameters(parAntiD[0], parAntiD[1], parAntiD[2], parAntiD[3], parAntiD[4]); } + // Deuteron pT-shift if (enablePtShiftPID && !fShiftPtPID) { fShiftPtPID = new TF1("fShiftPtPID", "[0] * exp([1] + [2] * x) + [3] + [4] * x + [5] * x * x + [6] * x * x * x", 0.f, 8.f); auto parPID = (std::vector)parShiftPtPID; // NOLINT fShiftPtPID->SetParameters(parPID[0], parPID[1], parPID[2], parPID[3], parPID[4], parPID[5], parPID[6]); } - switch (unableAntiDPtShift) { - case 0: - if (enablePtShiftAntiD && fShiftAntiD) { - auto shiftAntiD = fShiftAntiD->Eval(track.pt()); - antiDPt = track.pt() - shiftAntiD; - } - break; - case 1: - antiDPt = track.pt(); - break; + if (unableAntiDPtShift == 0 && enablePtShiftAntiD && fShiftAntiD) { + const auto shiftAntiD = fShiftAntiD->Eval(track.pt()); + antiDPt = track.pt() - shiftAntiD; } if (enablePtShiftD && !fShiftD) { @@ -2578,45 +2679,36 @@ struct lfNucleiBATask { fShiftD->SetParameters(parD[0], parD[1], parD[2], parD[3], parD[4]); } - switch (unableDPtShift) { - case 0: - if (enablePtShiftD && fShiftD) { - auto shiftD = fShiftD->Eval(track.pt()); - DPt = track.pt() - shiftD; - } - break; - case 1: - DPt = track.pt(); - break; + if (unableDPtShift == 0 && enablePtShiftD && fShiftD) { + const auto shiftD = fShiftD->Eval(track.pt()); + DPt = track.pt() - shiftD; } - switch (helium3Pt) { - case 0: - hePt = track.pt(); - if (enablePtShiftHe && fShiftPtHe) { - shiftPtPos = fShiftPtHe->Eval(2 * track.pt()); - hePt = track.pt() - shiftPtPos / 2.f; - } - antihePt = track.pt(); - if (enablePtShiftHe && fShiftPtantiHe) { - shiftPtNeg = fShiftPtantiHe->Eval(2 * track.pt()); - antihePt = track.pt() - shiftPtNeg / 2.f; - } - if (enablePtShiftPID && fShiftPtPID) { - shiftPtPID = fShiftPtPID->Eval(2 * track.pt()); + // Helium pT-shift and WrongPid pT-shift + if (enablePtShiftHe && fShiftPtHe) { + hePt -= fShiftPtHe->Eval(2.f * track.pt()) / 2.f; + } - if (tritonPID && (track.pt() <= cfgPtShiftPID)) { - hePt = track.pt() - shiftPtPID / 2.f; - antihePt = track.pt() - shiftPtPID / 2.f; - } - } - break; - case 1: - hePt = 2.f * track.pt(); - antihePt = 2.f * track.pt(); - break; + if (enablePtShiftHe && fShiftPtantiHe) { + antihePt -= fShiftPtantiHe->Eval(2.f * track.pt()) / 2.f; + } + + if (enablePtShiftPID && fShiftPtPID && tritonPID && track.pt() <= cfgPtShiftPID) { + const auto shiftPtPID = fShiftPtPID->Eval(2.f * track.pt()); + hePt = track.pt() - shiftPtPID / 2.f; + antihePt = track.pt() - shiftPtPID / 2.f; + } + + if (enableDebug && enableHe) { + if (track.sign() > 0) + debugHistos.fill(HIST("tracks/helium/h2HeCutFlowVsPt"), 2.f * hePt, 4); + else + debugHistos.fill(HIST("tracks/helium/h2antiHeCutFlowVsPt"), 2.f * antihePt, 4); } + heP = getPFromPt(track, hePt); + antiheP = getPFromPt(track, antihePt); + float nITSDe = 99.f; float nITSHe = 99.f; @@ -2624,13 +2716,7 @@ struct lfNucleiBATask { nITSDe = track.itsNSigmaDe(); nITSHe = track.itsNSigmaHe(); } - heP = track.p(); - antiheP = track.p(); - heTPCmomentum = track.tpcInnerParam(); - antiheTPCmomentum = track.tpcInnerParam(); - // auto parDCAxy = (std::vector)parDCAxycuts; - // auto parDCAz = (std::vector)parDCAzcuts; const auto& parDCAxy = parDCAxycuts.value; const auto& parDCAz = parDCAzcuts.value; @@ -2743,6 +2829,8 @@ struct lfNucleiBATask { passDCAxyCutAntiHe = dcaXY2 / std::pow(parDCAxy[3] * (parDCAxy[0] + parDCAxy[1] / std::pow(antihePt, parDCAxy[2])), 2) + dcaZ2 / std::pow(parDCAz[3] * (parDCAz[0] + parDCAz[1] / std::pow(antihePt, parDCAz[2])), 2) <= 1; passDCAzCutAntiHe = dcaXY2 / std::pow(parDCAxy[3] * (parDCAxy[0] + parDCAxy[1] / std::pow(antihePt, parDCAxy[2])), 2) + dcaZ2 / std::pow(parDCAz[3] * (parDCAz[0] + parDCAz[1] / std::pow(antihePt, parDCAz[2])), 2) <= 1; break; + default: + break; } // Rapidity cuts @@ -2750,34 +2838,50 @@ struct lfNucleiBATask { const float rap = track.rapidity(m2z); return (rap > kinemOptions.cfgRapidityCutLow) && (rap < kinemOptions.cfgRapidityCutHigh); }; + auto rapCheckFromPt = [&](const float pt, const float m2z) { + const float yShifted = getRapidityFromPtMass(track, pt, m2z); + return (yShifted > kinemOptions.cfgRapidityCutLow) && (yShifted < kinemOptions.cfgRapidityCutHigh); + }; prRapCut = rapCheck(MassProtonVal); - deRapCut = rapCheck(MassDeuteronVal); trRapCut = rapCheck(MassTritonVal); - heRapCut = rapCheck(MassHeliumVal / 2.0); alRapCut = rapCheck(MassAlphaVal / 2.0); + if (track.sign() > 0) { + deRapCut = rapCheckFromPt(DPt, MassDeuteronVal); + heRapCut = rapCheckFromPt(hePt, MassHeliumVal / 2.0); + } else { + deRapCut = rapCheckFromPt(antiDPt, MassDeuteronVal); + heRapCut = rapCheckFromPt(antihePt, MassHeliumVal / 2.0); + } + isDeuteron = enableDe && deRapCut; isHelium = enableHe && heRapCut; + if (enableDebug && isHelium) { + if (track.sign() > 0) + debugHistos.fill(HIST("tracks/helium/h2HeCutFlowVsPt"), 2.f * hePt, 5); + else + debugHistos.fill(HIST("tracks/helium/h2antiHeCutFlowVsPt"), 2.f * antihePt, 5); + } + // ITS PID cut bool passITSDeCut = !nsigmaITSvar.useITSDeCut || (nITSDe > nsigmaITSvar.nsigmaITSDe); bool passITSHeCut = !nsigmaITSvar.useITSHeCut || (nITSHe > nsigmaITSvar.nsigmaITSHe); if constexpr (IsMC && !IsFilteredData) { - int pdgCheck = track.mcParticle().pdgCode(); - if (std::abs(pdgCheck) == PDGDeuteron) + const int pdgCheck = std::abs(track.mcParticle().pdgCode()); + if (pdgCheck == PDGDeuteron) { histos.fill(HIST("tracks/hItsDeHeChecker"), 0); - if (std::abs(pdgCheck) == PDGHelium) + if (passITSDeCut) { + histos.fill(HIST("tracks/hItsDeHeChecker"), 2); + } + } else if (pdgCheck == PDGHelium) { histos.fill(HIST("tracks/hItsDeHeChecker"), 1); - } - - if constexpr (IsMC && !IsFilteredData) { - int pdgCheck = track.mcParticle().pdgCode(); - if ((std::abs(pdgCheck) == PDGDeuteron) && passITSDeCut) - histos.fill(HIST("tracks/hItsDeHeChecker"), 2); - if ((std::abs(pdgCheck) == PDGHelium) && passITSHeCut) - histos.fill(HIST("tracks/hItsDeHeChecker"), 3); + if (passITSHeCut) { + histos.fill(HIST("tracks/hItsDeHeChecker"), 3); + } + } } isDe = isDeuteron && passITSDeCut && track.sign() > 0; @@ -2786,6 +2890,13 @@ struct lfNucleiBATask { isHe = isHelium && passITSHeCut && track.sign() > 0; isAntiHe = isHelium && passITSHeCut && track.sign() < 0; + if (enableDebug && enableHe) { + if (isHe) + debugHistos.fill(HIST("tracks/helium/h2HeCutFlowVsPt"), 2.f * hePt, 6); + if (isAntiHe) + debugHistos.fill(HIST("tracks/helium/h2antiHeCutFlowVsPt"), 2.f * antihePt, 6); + } + isDeWoDCAxy = isDe && passDCAzCutDe; isAntiDeWoDCAxy = isAntiDe && passDCAzCutAntiDe; isHeWoDCAxy = isHe && passDCAzCutHe; @@ -2796,25 +2907,25 @@ struct lfNucleiBATask { isHeWoDCAz = isHe && passDCAxyCutHe; isAntiHeWoDCAz = isAntiHe && passDCAxyCutAntiHe; - isDeWoDCAxyWTPCpid = isDeWoDCAxy && std::abs(track.tpcNSigmaDe()) < nsigmaTPCvar.nsigmaTPCDe; - isAntiDeWoDCAxyWTPCpid = isAntiDeWoDCAxy && std::abs(track.tpcNSigmaDe()) < nsigmaTPCvar.nsigmaTPCDe; - isHeWoDCAxyWTPCpid = isHeWoDCAxy && std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe; - isAntiHeWoDCAxyWTPCpid = isAntiHeWoDCAxy && std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe; + isDeWoDCAxyWTPCpid = isDeWoDCAxy && passDeTPCpid; + isAntiDeWoDCAxyWTPCpid = isAntiDeWoDCAxy && passDeTPCpid; + isHeWoDCAxyWTPCpid = isHeWoDCAxy && passHeTPCpid; + isAntiHeWoDCAxyWTPCpid = isAntiHeWoDCAxy && passHeTPCpid; - isDeWoDCAzWTPCpid = isDeWoDCAz && std::abs(track.tpcNSigmaDe()) < nsigmaTPCvar.nsigmaTPCDe; - isAntiDeWoDCAzWTPCpid = isAntiDeWoDCAz && std::abs(track.tpcNSigmaDe()) < nsigmaTPCvar.nsigmaTPCDe; - isHeWoDCAzWTPCpid = isHeWoDCAz && std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe; - isAntiHeWoDCAzWTPCpid = isAntiHeWoDCAz && std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe; + isDeWoDCAzWTPCpid = isDeWoDCAz && passDeTPCpid; + isAntiDeWoDCAzWTPCpid = isAntiDeWoDCAz && passDeTPCpid; + isHeWoDCAzWTPCpid = isHeWoDCAz && passHeTPCpid; + isAntiHeWoDCAzWTPCpid = isAntiHeWoDCAz && passHeTPCpid; isDeWoTPCpid = isDe && passDCAzCutDe && passDCAxyCutDe; isAntiDeWoTPCpid = isAntiDe && passDCAzCutAntiDe && passDCAxyCutAntiDe; isHeWoTPCpid = isHe && passDCAzCutHe && passDCAxyCutHe; isAntiHeWoTPCpid = isAntiHe && passDCAzCutAntiHe && passDCAxyCutAntiHe; - isDeWTPCpid = isDeWoTPCpid && std::abs(track.tpcNSigmaDe()) < nsigmaTPCvar.nsigmaTPCDe; - isAntiDeWTPCpid = isAntiDeWoTPCpid && std::abs(track.tpcNSigmaDe()) < nsigmaTPCvar.nsigmaTPCDe; - isHeWTPCpid = isHeWoTPCpid && std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe; - isAntiHeWTPCpid = isAntiHeWoTPCpid && std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe; + isDeWTPCpid = isDeWoTPCpid && passDeTPCpid; + isAntiDeWTPCpid = isAntiDeWoTPCpid && passDeTPCpid; + isHeWTPCpid = isHeWoTPCpid && passHeTPCpid; + isAntiHeWTPCpid = isAntiHeWoTPCpid && passHeTPCpid; passDCAxyzCut = passDCAxyCut && passDCAzCut; @@ -2823,36 +2934,34 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/dca/before/hDCAxyVsDCAzVsPt"), track.dcaXY(), track.dcaZ(), track.pt()); histos.fill(HIST("tracks/dca/before/hDCAxyVsDCAz"), track.dcaZ(), track.dcaXY()); - if (isHe && std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe) { + if (isHe && passHeTPCpid) { histos.fill(HIST("tracks/helium/dca/before/h3DCAvsPtHelium"), track.dcaXY(), track.dcaZ(), hePt); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsDCAzVsPtHelium"), track.dcaXY(), track.dcaZ(), hePt); - } } - if (isAntiHe && std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe) { + if (isAntiHe && passHeTPCpid) { histos.fill(HIST("tracks/helium/dca/before/h3DCAvsPtantiHelium"), track.dcaXY(), track.dcaZ(), antihePt); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsDCAzVsPtantiHelium"), track.dcaXY(), track.dcaZ(), antihePt); - } } if (passDCAxyCut) { histos.fill(HIST("tracks/dca/before/hDCAzVsPt"), track.pt(), track.dcaZ()); - if (enablePr && prRapCut && (std::abs(track.tpcNSigmaPr()) < nsigmaTPCvar.nsigmaTPCPr)) { + if (enablePr && prRapCut && passPrTPCpid) { if (track.sign() > 0) { histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtProton"), track.pt(), track.dcaZ()); } else { histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtantiProton"), track.pt(), track.dcaZ()); } } - if (enableTr && trRapCut && isTritonTPCpid) { + if (enableTr && trRapCut && passTrTPCpid) { if (track.sign() > 0) { histos.fill(HIST("tracks/triton/dca/before/hDCAzVsPtTriton"), track.pt(), track.dcaZ()); } else { histos.fill(HIST("tracks/triton/dca/before/hDCAzVsPtantiTriton"), track.pt(), track.dcaZ()); } } - if (enableAl && alRapCut && (std::abs(track.tpcNSigmaAl()) < nsigmaTPCvar.nsigmaTPCAl)) { + if (enableAl && alRapCut && passAlTPCpid) { if (track.sign() > 0) { histos.fill(HIST("tracks/alpha/dca/before/hDCAzVsPtAlpha"), track.pt(), track.dcaZ()); } else { @@ -2877,18 +2986,16 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtHelium"), hePt, track.dcaZ()); if (!track.hasTOF() && (outFlagOptions.enableNoTOFPlots)) histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtHeliumNoTOF"), hePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtHelium"), hePt, track.dcaZ()); - } } if (isAntiHeWoDCAzWTPCpid) { histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtantiHelium"), antihePt, track.dcaZ()); if (!track.hasTOF() && (outFlagOptions.enableNoTOFPlots)) - histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtantiHeliumNoTOF"), hePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtantiHeliumNoTOF"), antihePt, track.dcaZ()); + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtantiHelium"), antihePt, track.dcaZ()); - } } } @@ -2919,14 +3026,12 @@ struct lfNucleiBATask { case PDGProton: if (enablePr && prRapCut && passDCAxyCut) { histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtProtonTrue"), track.pt(), track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAzVsPtProtonTrue"), track.pt(), track.dcaZ()); - } if (isPhysPrim) { histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtProtonTruePrim"), track.pt(), track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAzVsPtProtonTruePrim"), track.pt(), track.dcaZ()); - } } if (!isPhysPrim && !isProdByGen) { if (isWeakDecay) { @@ -2934,7 +3039,7 @@ struct lfNucleiBATask { } else { histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtProtonTrueMaterial"), track.pt(), track.dcaZ()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAzVsPtProtonTrueSec"), track.pt(), track.dcaZ()); } else { @@ -2947,14 +3052,13 @@ struct lfNucleiBATask { case -PDGProton: if (enablePr && prRapCut && passDCAxyCut) { histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtantiProtonTrue"), track.pt(), track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAzVsPtantiProtonTrue"), track.pt(), track.dcaZ()); } if (isPhysPrim) { histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtantiProtonTruePrim"), track.pt(), track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAzVsPtantiProtonTruePrim"), track.pt(), track.dcaZ()); - } } if (!isPhysPrim && !isProdByGen) { if (isWeakDecay) { @@ -2962,11 +3066,11 @@ struct lfNucleiBATask { } else { histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtantiProtonTrueMaterial"), track.pt(), track.dcaZ()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { - histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAzVsPtantiProtonTrueSec"), hePt, track.dcaZ()); + histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAzVsPtantiProtonTrueSec"), track.pt(), track.dcaZ()); } else { - histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAzVsPtantiProtonTrueMaterial"), hePt, track.dcaZ()); + histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAzVsPtantiProtonTrueMaterial"), track.pt(), track.dcaZ()); } } } @@ -2975,14 +3079,13 @@ struct lfNucleiBATask { case PDGDeuteron: if (isDeWoDCAz) { histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtDeuteronTrue"), DPt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/deuteron/dca/before/TOF/hDCAzVsPtDeuteronTrue"), DPt, track.dcaZ()); } if (isPhysPrim) { histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtDeuteronTruePrim"), DPt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/dca/before/TOF/hDCAzVsPtDeuteronTruePrim"), DPt, track.dcaZ()); - } } if (!isPhysPrim && !isProdByGen) { if (isWeakDecay) { @@ -2990,7 +3093,7 @@ struct lfNucleiBATask { } else { histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtDeuteronTrueMaterial"), DPt, track.dcaZ()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/deuteron/dca/before/TOF/hDCAzVsPtDeuteronTrueSec"), DPt, track.dcaZ()); } else { @@ -3003,14 +3106,13 @@ struct lfNucleiBATask { case -PDGDeuteron: if (isAntiDeWoDCAz) { histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtantiDeuteronTrue"), antiDPt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/deuteron/dca/before/TOF/hDCAzVsPtantiDeuteronTrue"), antiDPt, track.dcaZ()); } if (isPhysPrim) { histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtantiDeuteronTruePrim"), antiDPt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/dca/before/TOF/hDCAzVsPtantiDeuteronTruePrim"), antiDPt, track.dcaZ()); - } } if (!isPhysPrim && !isProdByGen) { if (isWeakDecay) { @@ -3018,7 +3120,7 @@ struct lfNucleiBATask { } else { histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtantiDeuteronTrueMaterial"), antiDPt, track.dcaZ()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/deuteron/dca/before/TOF/hDCAzVsPtantiDeuteronTrueSec"), antiDPt, track.dcaZ()); } else { @@ -3061,14 +3163,13 @@ struct lfNucleiBATask { case PDGHelium: if (isHeWoDCAz) { histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtHeliumTrue"), hePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtHeliumTrue"), hePt, track.dcaZ()); } if (isPhysPrim) { histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtHeliumTruePrim"), hePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtHeliumTruePrim"), hePt, track.dcaZ()); - } } if (!isPhysPrim && !isProdByGen) { if (isWeakDecay) { @@ -3076,7 +3177,7 @@ struct lfNucleiBATask { } else { histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtHeliumTrueMaterial"), hePt, track.dcaZ()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtHeliumTrueSec"), hePt, track.dcaZ()); } else { @@ -3089,21 +3190,19 @@ struct lfNucleiBATask { if ((event.has_mcCollision() && (track.mcParticle().mcCollisionId() != event.mcCollisionId())) || !event.has_mcCollision()) { if (isHeWoDCAz && outFlagOptions.makeWrongEventPlots) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAzVsPtHeliumTrue"), hePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAzVsPtHeliumTrue"), hePt, track.dcaZ()); - } if (isPhysPrim) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAzVsPtHeliumTruePrim"), hePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAzVsPtHeliumTruePrim"), hePt, track.dcaZ()); - } } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAzVsPtHeliumTrueTransport"), hePt, track.dcaZ()); if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAzVsPtHeliumTrueSec"), hePt, track.dcaZ()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAzVsPtHeliumTrueTransport"), hePt, track.dcaZ()); if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAzVsPtHeliumTrueSec"), hePt, track.dcaZ()); @@ -3117,12 +3216,11 @@ struct lfNucleiBATask { case -PDGHelium: if (isAntiHeWoDCAz) { histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtantiHeliumTrue"), antihePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtantiHeliumTrue"), antihePt, track.dcaZ()); - } if (isPhysPrim) { histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtantiHeliumTruePrim"), antihePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtantiHeliumTruePrim"), antihePt, track.dcaZ()); } } @@ -3132,7 +3230,7 @@ struct lfNucleiBATask { } else { histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtantiHeliumTrueMaterial"), antihePt, track.dcaZ()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtantiHeliumTrueSec"), antihePt, track.dcaZ()); } else { @@ -3145,21 +3243,19 @@ struct lfNucleiBATask { if ((event.has_mcCollision() && (track.mcParticle().mcCollisionId() != event.mcCollisionId())) || !event.has_mcCollision()) { if (isAntiHeWoDCAz && outFlagOptions.makeWrongEventPlots) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAzVsPtantiHeliumTrue"), antihePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAzVsPtantiHeliumTrue"), antihePt, track.dcaZ()); - } if (isPhysPrim) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAzVsPtantiHeliumTruePrim"), antihePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAzVsPtantiHeliumTruePrim"), antihePt, track.dcaZ()); - } } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAzVsPtantiHeliumTrueTransport"), antihePt, track.dcaZ()); if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAzVsPtantiHeliumTrueSec"), antihePt, track.dcaZ()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAzVsPtantiHeliumTrueTransport"), antihePt, track.dcaZ()); if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAzVsPtantiHeliumTrueSec"), antihePt, track.dcaZ()); @@ -3210,21 +3306,19 @@ struct lfNucleiBATask { default: if (isDeWoDCAzWTPCpid && outFlagOptions.makeFakeTracksPlots) { histos.fill(HIST("tracks/deuteron/dca/before/fake/hDCAzVsPtDeuteronTrue"), DPt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/dca/before/fake/TOF/hDCAzVsPtDeuteronTrue"), DPt, track.dcaZ()); - } if (isPhysPrim) { histos.fill(HIST("tracks/deuteron/dca/before/fake/hDCAzVsPtDeuteronTruePrim"), DPt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/dca/before/fake/TOF/hDCAzVsPtDeuteronTruePrim"), DPt, track.dcaZ()); - } } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/deuteron/dca/before/fake/hDCAzVsPtDeuteronTrueTransport"), DPt, track.dcaZ()); if (isWeakDecay) { histos.fill(HIST("tracks/deuteron/dca/before/fake/hDCAzVsPtDeuteronTrueSec"), DPt, track.dcaZ()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/deuteron/dca/before/fake/TOF/hDCAzVsPtDeuteronTrueTransport"), DPt, track.dcaZ()); if (isWeakDecay) { histos.fill(HIST("tracks/deuteron/dca/before/fake/TOF/hDCAzVsPtDeuteronTrueSec"), DPt, track.dcaZ()); @@ -3233,21 +3327,19 @@ struct lfNucleiBATask { } } else if (isAntiDeWoDCAzWTPCpid && outFlagOptions.makeFakeTracksPlots) { histos.fill(HIST("tracks/deuteron/dca/before/fake/hDCAzVsPtantiDeuteronTrue"), antiDPt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/dca/before/fake/TOF/hDCAzVsPtantiDeuteronTrue"), antiDPt, track.dcaZ()); - } if (isPhysPrim) { histos.fill(HIST("tracks/deuteron/dca/before/fake/hDCAzVsPtantiDeuteronTruePrim"), antiDPt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/dca/before/fake/TOF/hDCAzVsPtantiDeuteronTruePrim"), antiDPt, track.dcaZ()); - } } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/deuteron/dca/before/fake/hDCAzVsPtantiDeuteronTrueTransport"), antiDPt, track.dcaZ()); if (isWeakDecay) { histos.fill(HIST("tracks/deuteron/dca/before/fake/hDCAzVsPtantiDeuteronTrueSec"), antiDPt, track.dcaZ()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/deuteron/dca/before/fake/TOF/hDCAzVsPtantiDeuteronTrueTransport"), antiDPt, track.dcaZ()); if (isWeakDecay) { histos.fill(HIST("tracks/deuteron/dca/before/fake/TOF/hDCAzVsPtantiDeuteronTrueSec"), antiDPt, track.dcaZ()); @@ -3265,21 +3357,19 @@ struct lfNucleiBATask { default: if (isHeWoDCAzWTPCpid && outFlagOptions.makeFakeTracksPlots) { histos.fill(HIST("tracks/helium/dca/before/fake/hDCAzVsPtHeliumTrue"), hePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/fake/TOF/hDCAzVsPtHeliumTrue"), hePt, track.dcaZ()); - } if (isPhysPrim) { histos.fill(HIST("tracks/helium/dca/before/fake/hDCAzVsPtHeliumTruePrim"), hePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/fake/TOF/hDCAzVsPtHeliumTruePrim"), hePt, track.dcaZ()); - } } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/helium/dca/before/fake/hDCAzVsPtHeliumTrueTransport"), hePt, track.dcaZ()); if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/fake/hDCAzVsPtHeliumTrueSec"), hePt, track.dcaZ()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/before/fake/TOF/hDCAzVsPtHeliumTrueTransport"), hePt, track.dcaZ()); if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/fake/TOF/hDCAzVsPtHeliumTrueSec"), hePt, track.dcaZ()); @@ -3289,21 +3379,19 @@ struct lfNucleiBATask { } if (isAntiHeWoDCAzWTPCpid && outFlagOptions.makeFakeTracksPlots) { histos.fill(HIST("tracks/helium/dca/before/fake/hDCAzVsPtantiHeliumTrue"), antihePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/fake/TOF/hDCAzVsPtantiHeliumTrue"), antihePt, track.dcaZ()); - } if (isPhysPrim) { histos.fill(HIST("tracks/helium/dca/before/fake/hDCAzVsPtantiHeliumTruePrim"), antihePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/fake/TOF/hDCAzVsPtantiHeliumTruePrim"), antihePt, track.dcaZ()); - } } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/helium/dca/before/fake/hDCAzVsPtantiHeliumTrueTransport"), antihePt, track.dcaZ()); if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/fake/hDCAzVsPtantiHeliumTrueSec"), antihePt, track.dcaZ()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/before/fake/TOF/hDCAzVsPtantiHeliumTrueTransport"), antihePt, track.dcaZ()); if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/fake/TOF/hDCAzVsPtantiHeliumTrueSec"), antihePt, track.dcaZ()); @@ -3323,7 +3411,7 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/dca/before/hDCAxyVsPt"), track.pt(), track.dcaXY()); if (enablePr && prRapCut) { - if (std::abs(track.tpcNSigmaPr()) < nsigmaTPCvar.nsigmaTPCPr) { + if (passPrTPCpid) { if (track.sign() > 0) { histos.fill(HIST("tracks/proton/dca/before/hDCAxyVsPtProton"), track.pt(), track.dcaXY()); } else { @@ -3333,7 +3421,7 @@ struct lfNucleiBATask { } if (enableTr && trRapCut) { - if (isTritonTPCpid) { + if (passTrTPCpid) { if (track.sign() > 0) { histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtTriton"), track.pt(), track.dcaXY()); } else { @@ -3342,7 +3430,7 @@ struct lfNucleiBATask { } } if (enableAl && alRapCut) { - if (std::abs(track.tpcNSigmaAl()) < nsigmaTPCvar.nsigmaTPCAl) { + if (passAlTPCpid) { if (track.sign() > 0) { histos.fill(HIST("tracks/alpha/dca/before/hDCAxyVsPtAlpha"), track.pt(), track.dcaXY()); } else { @@ -3352,24 +3440,23 @@ struct lfNucleiBATask { } } - if (isDeWoDCAxyWTPCpid) { - if (usenITSLayer && !itsClusterMap.test(trkqcOptions.nITSLayer)) - continue; + if (isDeWoDCAxyWTPCpid && (!usenITSLayer || itsClusterMap.test(trkqcOptions.nITSLayer))) { if (enableCentrality) histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteronVsMult"), DPt, track.dcaXY(), centFT0M); else histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteron"), DPt, track.dcaXY()); - if (!track.hasTOF() && (outFlagOptions.enableNoTOFPlots)) + + if (!track.hasTOF() && outFlagOptions.enableNoTOFPlots) histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteronNoTOF"), DPt, track.dcaXY()); } - if (isAntiDeWoDCAxyWTPCpid) { - if (usenITSLayer && !itsClusterMap.test(trkqcOptions.nITSLayer)) - continue; + + if (isAntiDeWoDCAxyWTPCpid && (!usenITSLayer || itsClusterMap.test(trkqcOptions.nITSLayer))) { if (enableCentrality) histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronVsMult"), antiDPt, track.dcaXY(), centFT0M); else histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteron"), antiDPt, track.dcaXY()); - if (!track.hasTOF() && (outFlagOptions.enableNoTOFPlots)) + + if (!track.hasTOF() && outFlagOptions.enableNoTOFPlots) histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronNoTOF"), antiDPt, track.dcaXY()); } @@ -3377,17 +3464,15 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtHelium"), hePt, track.dcaXY()); if (!track.hasTOF() && (outFlagOptions.enableNoTOFPlots)) histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtHeliumNoTOF"), hePt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtHelium"), hePt, track.dcaXY()); - } } if (isAntiHeWoDCAxyWTPCpid) { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtantiHelium"), antihePt, track.dcaXY()); if (!track.hasTOF() && (outFlagOptions.enableNoTOFPlots)) histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtantiHeliumNoTOF"), antihePt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtantiHelium"), antihePt, track.dcaXY()); - } } } @@ -3408,8 +3493,8 @@ struct lfNucleiBATask { [[maybe_unused]] int firstMotherId = -1; [[maybe_unused]] int firstMotherPdg = -1; [[maybe_unused]] float firstMotherPt = -1.f; - [[maybe_unused]] int pdgMomList[kMaxNumMom]; - [[maybe_unused]] float ptMomList[kMaxNumMom]; + [[maybe_unused]] std::array pdgMomList{}; + [[maybe_unused]] std::array ptMomList{}; [[maybe_unused]] int nSaved = 0; if constexpr (IsFilteredData) { @@ -3451,7 +3536,7 @@ struct lfNucleiBATask { firstMotherPdg = pdgMom; firstMotherPt = ptMom; } - if (nSaved < kMaxNumMom) { + if (nSaved < MaxNumMom) { pdgMomList[nSaved] = pdgMom; ptMomList[nSaved] = ptMom; nSaved++; @@ -3473,14 +3558,12 @@ struct lfNucleiBATask { case PDGProton: if (enablePr && prRapCut && outFlagOptions.makeDCABeforeCutPlots && passDCAzCut) { histos.fill(HIST("tracks/proton/dca/before/hDCAxyVsPtProtonTrue"), track.pt(), track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAxyVsPtProtonTrue"), track.pt(), track.dcaXY()); - } if (isPhysPrim) { histos.fill(HIST("tracks/proton/dca/before/hDCAxyVsPtProtonTruePrim"), track.pt(), track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAxyVsPtProtonTruePrim"), track.pt(), track.dcaXY()); - } } if (!isPhysPrim && !isProdByGen) { if (isWeakDecay) { @@ -3491,25 +3574,25 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/proton/dca/before/hNumMothers"), nSaved); if (nSaved > 0) { for (int iMom = 0; iMom < nSaved; iMom++) { - int pdgMom = pdgMomList[iMom]; - float pdgSign = (pdgMom > 0) ? 1.0 : -1.0; - float ptMom = ptMomList[iMom]; + const int pdgMomCurrent = pdgMomList[iMom]; + const float pdgSign = (pdgMomCurrent > 0) ? 1.0f : -1.0f; + const float ptMomCurrent = ptMomList[iMom]; int motherSpeciesBin = -1; - if (pdgMom != -1) { + if (pdgMomCurrent != -1) { motherSpeciesBin = 0; for (int j = 0; j < NumMotherList; j++) { - if (std::abs(PdgMotherList[j]) == std::abs(pdgMom)) { + if (std::abs(PdgMotherList[j]) == std::abs(pdgMomCurrent)) { motherSpeciesBin = j + 1; break; } } } - histos.fill(HIST("tracks/proton/dca/before/hMomTrueMaterial"), pdgSign, motherSpeciesBin, ptMom); + histos.fill(HIST("tracks/proton/dca/before/hMomTrueMaterial"), pdgSign, motherSpeciesBin, ptMomCurrent); } } } } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAxyVsPtProtonTrueSec"), track.pt(), track.dcaXY()); } else { @@ -3522,14 +3605,12 @@ struct lfNucleiBATask { case -PDGProton: if (enablePr && prRapCut && outFlagOptions.makeDCABeforeCutPlots && passDCAzCut) { histos.fill(HIST("tracks/proton/dca/before/hDCAxyVsPtantiProtonTrue"), track.pt(), track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAxyVsPtantiProtonTrue"), track.pt(), track.dcaXY()); - } if (isPhysPrim) { histos.fill(HIST("tracks/proton/dca/before/hDCAxyVsPtantiProtonTruePrim"), track.pt(), track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAxyVsPtantiProtonTruePrim"), track.pt(), track.dcaXY()); - } } if (!isPhysPrim && !isProdByGen) { if (isWeakDecay) { @@ -3537,7 +3618,7 @@ struct lfNucleiBATask { } else { histos.fill(HIST("tracks/proton/dca/before/hDCAxyVsPtantiProtonTrueMaterial"), track.pt(), track.dcaXY()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/proton/dca/before/TOF/hDCAxyVsPtantiProtonTrueSec"), track.pt(), track.dcaXY()); } else { @@ -3551,16 +3632,14 @@ struct lfNucleiBATask { if (isDeWoDCAxy) { if (outFlagOptions.makeDCABeforeCutPlots) { histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteronTrue"), DPt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/dca/before/TOF/hDCAxyVsPtDeuteronTrue"), DPt, track.dcaXY()); - } } if (isPhysPrim) { if (outFlagOptions.makeDCABeforeCutPlots) { histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteronTruePrim"), DPt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/dca/before/TOF/hDCAxyVsPtDeuteronTruePrim"), DPt, track.dcaXY()); - } } if constexpr (IsFilteredData) { spectraGen.fill(HIST("deuteron/histDeuteronPtShift"), track.pt(), track.pt() - genPt); @@ -3588,25 +3667,25 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/deuteron/dca/before/hNumMothers"), nSaved); if (nSaved > 0) { for (int iMom = 0; iMom < nSaved; iMom++) { - int pdgMom = pdgMomList[iMom]; - float pdgSign = (pdgMom > 0) ? 1.0 : -1.0; - float ptMom = ptMomList[iMom]; + const int pdgMomCurrent = pdgMomList[iMom]; + const float pdgSign = (pdgMomCurrent > 0) ? 1.0f : -1.0f; + const float ptMomCurrent = ptMomList[iMom]; int motherSpeciesBin = -1; - if (pdgMom != -1) { + if (pdgMomCurrent != -1) { motherSpeciesBin = 0; for (int j = 0; j < NumMotherList; j++) { - if (std::abs(PdgMotherList[j]) == std::abs(pdgMom)) { + if (std::abs(PdgMotherList[j]) == std::abs(pdgMomCurrent)) { motherSpeciesBin = j + 1; break; } } } - histos.fill(HIST("tracks/deuteron/dca/before/hMomTrueMaterial"), pdgSign, motherSpeciesBin, ptMom); + histos.fill(HIST("tracks/deuteron/dca/before/hMomTrueMaterial"), pdgSign, motherSpeciesBin, ptMomCurrent); } } } } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/deuteron/dca/before/TOF/hDCAxyVsPtDeuteronTrueSec"), DPt, track.dcaXY()); } else { @@ -3621,16 +3700,14 @@ struct lfNucleiBATask { if (isAntiDeWoDCAxy) { if (outFlagOptions.makeDCABeforeCutPlots) { histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronTrue"), antiDPt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/dca/before/TOF/hDCAxyVsPtantiDeuteronTrue"), antiDPt, track.dcaXY()); - } } if (isPhysPrim) { if (outFlagOptions.makeDCABeforeCutPlots) { histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronTruePrim"), antiDPt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/dca/before/TOF/hDCAxyVsPtantiDeuteronTruePrim"), antiDPt, track.dcaXY()); - } } if constexpr (IsFilteredData) { spectraGen.fill(HIST("deuteron/histAntiDeuteronPtShift"), track.pt(), track.pt() - genPt); @@ -3655,7 +3732,7 @@ struct lfNucleiBATask { } else { histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronTrueMaterial"), antiDPt, track.dcaXY()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/deuteron/dca/before/TOF/hDCAxyVsPtantiDeuteronTrueSec"), antiDPt, track.dcaXY()); } else { @@ -3669,26 +3746,22 @@ struct lfNucleiBATask { case PDGTriton: if (enableTr && trRapCut && outFlagOptions.makeDCABeforeCutPlots && passDCAzCut) { histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtTritonTrue"), track.pt(), track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/triton/dca/before/TOF/hDCAxyVsPtTritonTrue"), track.pt(), track.dcaXY()); - } if (isPhysPrim) { histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtTritonTruePrim"), track.pt(), track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/triton/dca/before/TOF/hDCAxyVsPtTritonTruePrim"), track.pt(), track.dcaXY()); - } } if (!isPhysPrim && !isProdByGen) { if (isWeakDecay) { histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtTritonTrueSec"), track.pt(), track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/triton/dca/before/TOF/hDCAxyVsPtTritonTrueSec"), track.pt(), track.dcaXY()); - } } else { histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtTritonTrueMaterial"), track.pt(), track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/triton/dca/before/TOF/hDCAxyVsPtTritonTrueMaterial"), track.pt(), track.dcaXY()); - } } } } @@ -3696,15 +3769,12 @@ struct lfNucleiBATask { case -PDGTriton: if (enableTr && trRapCut && outFlagOptions.makeDCABeforeCutPlots && passDCAzCut) { histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtantiTritonTrue"), track.pt(), track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/triton/dca/before/TOF/hDCAxyVsPtantiTritonTrue"), track.pt(), track.dcaXY()); - } - if (isPhysPrim) { histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtantiTritonTruePrim"), track.pt(), track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/triton/dca/before/TOF/hDCAxyVsPtantiTritonTruePrim"), track.pt(), track.dcaXY()); - } } if (!isPhysPrim && isProdByGen) { // @@ -3712,14 +3782,12 @@ struct lfNucleiBATask { if (!isPhysPrim && !isProdByGen) { if (isWeakDecay) { histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtantiTritonTrueSec"), track.pt(), track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/triton/dca/before/TOF/hDCAxyVsPtantiTritonTrueSec"), track.pt(), track.dcaXY()); - } } else { histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtantiTritonTrueMaterial"), track.pt(), track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/triton/dca/before/TOF/hDCAxyVsPtantiTritonTrueMaterial"), track.pt(), track.dcaXY()); - } } } } @@ -3728,14 +3796,12 @@ struct lfNucleiBATask { if (isHeWoDCAxy) { if (outFlagOptions.makeDCABeforeCutPlots) { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtHeliumTrue"), hePt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtHeliumTrue"), hePt, track.dcaXY()); - } if (isPhysPrim) { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtHeliumTruePrim"), hePt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtHeliumTruePrim"), hePt, track.dcaXY()); - } } } if (!isPhysPrim && !isProdByGen && outFlagOptions.makeDCABeforeCutPlots) { @@ -3747,25 +3813,25 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/helium/dca/before/hNumMothers"), nSaved); if (nSaved > 0) { for (int iMom = 0; iMom < nSaved; iMom++) { - int pdgMom = pdgMomList[iMom]; - float pdgSign = (pdgMom > 0) ? 1.0 : -1.0; - float ptMom = ptMomList[iMom]; + const int pdgMomCurrent = pdgMomList[iMom]; + const float pdgSign = (pdgMomCurrent > 0) ? 1.0f : -1.0f; + const float ptMomCurrent = ptMomList[iMom]; int motherSpeciesBin = -1; - if (pdgMom != -1) { + if (pdgMomCurrent != -1) { motherSpeciesBin = 0; for (int j = 0; j < NumMotherList; j++) { - if (std::abs(PdgMotherList[j]) == std::abs(pdgMom)) { + if (std::abs(PdgMotherList[j]) == std::abs(pdgMomCurrent)) { motherSpeciesBin = j + 1; break; } } } - histos.fill(HIST("tracks/helium/dca/before/hMomTrueMaterial"), pdgSign, motherSpeciesBin, ptMom); + histos.fill(HIST("tracks/helium/dca/before/hMomTrueMaterial"), pdgSign, motherSpeciesBin, ptMomCurrent); } } } } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtHeliumTrueSec"), hePt, track.dcaXY()); } else { @@ -3778,21 +3844,19 @@ struct lfNucleiBATask { if ((event.has_mcCollision() && (track.mcParticle().mcCollisionId() != event.mcCollisionId())) || !event.has_mcCollision()) { if (isHeWoDCAxy && outFlagOptions.makeDCABeforeCutPlots && outFlagOptions.makeWrongEventPlots) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAxyVsPtHeliumTrue"), hePt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAxyVsPtHeliumTrue"), hePt, track.dcaXY()); - } if (isPhysPrim) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAxyVsPtHeliumTruePrim"), hePt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAxyVsPtHeliumTruePrim"), hePt, track.dcaXY()); - } } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAxyVsPtHeliumTrueTransport"), hePt, track.dcaXY()); if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAxyVsPtHeliumTrueSec"), hePt, track.dcaXY()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAxyVsPtHeliumTrueTransport"), hePt, track.dcaXY()); if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAxyVsPtHeliumTrueSec"), hePt, track.dcaXY()); @@ -3816,7 +3880,7 @@ struct lfNucleiBATask { spectraGen.fill(HIST("helium/histPtShiftHe_WrongPidDe"), 2.f * hePt, 2.f * hePt - track.mcParticle().pt()); spectraGen.fill(HIST("helium/histPtShiftVsEtaHe"), track.eta(), 2.f * hePt - track.mcParticle().pt()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { spectraGen.fill(HIST("helium/TOF/histPtShiftHe"), 2.f * hePt, 2.f * hePt - track.mcParticle().pt()); spectraGen.fill(HIST("helium/TOF/histPtShiftHeVsGen"), track.mcParticle().pt(), 2.f * hePt - track.mcParticle().pt()); } @@ -3833,14 +3897,12 @@ struct lfNucleiBATask { if (isAntiHeWoDCAxy) { if (outFlagOptions.makeDCABeforeCutPlots) { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTrue"), antihePt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtantiHeliumTrue"), antihePt, track.dcaXY()); - } if (isPhysPrim) { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTruePrim"), antihePt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtantiHeliumTruePrim"), antihePt, track.dcaXY()); - } } } if (!isPhysPrim && !isProdByGen && outFlagOptions.makeDCABeforeCutPlots) { @@ -3849,7 +3911,7 @@ struct lfNucleiBATask { } else { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTrueMaterial"), antihePt, track.dcaXY()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtantiHeliumTrueSec"), antihePt, track.dcaXY()); } else { @@ -3862,21 +3924,19 @@ struct lfNucleiBATask { if ((event.has_mcCollision() && (track.mcParticle().mcCollisionId() != event.mcCollisionId())) || !event.has_mcCollision()) { if (isAntiHeWoDCAxy && outFlagOptions.makeDCABeforeCutPlots && outFlagOptions.makeWrongEventPlots) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAxyVsPtantiHeliumTrue"), antihePt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAxyVsPtantiHeliumTrue"), antihePt, track.dcaXY()); - } if (isPhysPrim) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAxyVsPtantiHeliumTruePrim"), antihePt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAxyVsPtantiHeliumTruePrim"), antihePt, track.dcaXY()); - } } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAxyVsPtantiHeliumTrueTransport"), antihePt, track.dcaXY()); if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/wrong/hDCAxyVsPtantiHeliumTrueSec"), antihePt, track.dcaXY()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAxyVsPtantiHeliumTrueTransport"), antihePt, track.dcaXY()); if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/wrong/TOF/hDCAxyVsPtantiHeliumTrueSec"), antihePt, track.dcaXY()); @@ -3900,7 +3960,7 @@ struct lfNucleiBATask { spectraGen.fill(HIST("helium/histPtShiftantiHe_WrongPidDe"), 2.f * antihePt, 2.f * antihePt - track.mcParticle().pt()); spectraGen.fill(HIST("helium/histPtShiftVsEtaantiHe"), track.eta(), 2.f * antihePt - track.mcParticle().pt()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { spectraGen.fill(HIST("helium/TOF/histPtShiftantiHe"), 2.f * antihePt, 2.f * antihePt - track.mcParticle().pt()); spectraGen.fill(HIST("helium/TOF/histPtShiftantiHeVsGen"), track.mcParticle().pt(), 2.f * antihePt - track.mcParticle().pt()); } @@ -3954,16 +4014,14 @@ struct lfNucleiBATask { if (isDeWoDCAxyWTPCpid && outFlagOptions.makeFakeTracksPlots) { if (outFlagOptions.makeDCABeforeCutPlots) { histos.fill(HIST("tracks/deuteron/dca/before/fake/hDCAxyVsPtDeuteronTrue"), DPt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/dca/before/fake/TOF/hDCAxyVsPtDeuteronTrue"), DPt, track.dcaXY()); - } } if (isPhysPrim) { if (outFlagOptions.makeDCABeforeCutPlots) { histos.fill(HIST("tracks/deuteron/dca/before/fake/hDCAxyVsPtDeuteronTruePrim"), DPt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/dca/before/fake/TOF/hDCAxyVsPtDeuteronTruePrim"), DPt, track.dcaXY()); - } } } if (!isPhysPrim && !isProdByGen) { @@ -3973,7 +4031,7 @@ struct lfNucleiBATask { } else { histos.fill(HIST("tracks/deuteron/dca/before/fake/hDCAxyVsPtDeuteronTrueMaterial"), DPt, track.dcaXY()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/deuteron/dca/before/fake/TOF/hDCAxyVsPtDeuteronTrueSec"), DPt, track.dcaXY()); } else { @@ -3986,16 +4044,14 @@ struct lfNucleiBATask { if (isAntiDeWoDCAxyWTPCpid && outFlagOptions.makeFakeTracksPlots) { if (outFlagOptions.makeDCABeforeCutPlots) { histos.fill(HIST("tracks/deuteron/dca/before/fake/hDCAxyVsPtantiDeuteronTrue"), antiDPt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/dca/before/fake/TOF/hDCAxyVsPtantiDeuteronTrue"), antiDPt, track.dcaXY()); - } } if (isPhysPrim) { if (outFlagOptions.makeDCABeforeCutPlots) { histos.fill(HIST("tracks/deuteron/dca/before/fake/hDCAxyVsPtantiDeuteronTruePrim"), antiDPt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/dca/before/fake/TOF/hDCAxyVsPtantiDeuteronTruePrim"), antiDPt, track.dcaXY()); - } } } if (!isPhysPrim && !isProdByGen) { @@ -4005,7 +4061,7 @@ struct lfNucleiBATask { } else { histos.fill(HIST("tracks/deuteron/dca/before/fake/hDCAxyVsPtantiDeuteronTrueMaterial"), antiDPt, track.dcaXY()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/deuteron/dca/before/fake/TOF/hDCAxyVsPtantiDeuteronTrueSec"), antiDPt, track.dcaXY()); } else { @@ -4026,14 +4082,12 @@ struct lfNucleiBATask { if (isHeWoDCAxyWTPCpid && outFlagOptions.makeFakeTracksPlots) { if (outFlagOptions.makeDCABeforeCutPlots) { histos.fill(HIST("tracks/helium/dca/before/fake/hDCAxyVsPtHeliumTrue"), hePt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/fake/TOF/hDCAxyVsPtHeliumTrue"), hePt, track.dcaXY()); - } if (isPhysPrim) { histos.fill(HIST("tracks/helium/dca/before/fake/hDCAxyVsPtHeliumTruePrim"), hePt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/fake/TOF/hDCAxyVsPtHeliumTruePrim"), hePt, track.dcaXY()); - } } if (!isPhysPrim && !isProdByGen) { if (isWeakDecay) { @@ -4041,7 +4095,7 @@ struct lfNucleiBATask { } else { histos.fill(HIST("tracks/helium/dca/before/fake/hDCAxyVsPtHeliumTrueMaterial"), hePt, track.dcaXY()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/fake/TOF/hDCAxyVsPtHeliumTrueSec"), hePt, track.dcaXY()); } else { @@ -4054,14 +4108,12 @@ struct lfNucleiBATask { if (isAntiHeWoDCAxyWTPCpid && outFlagOptions.makeFakeTracksPlots) { if (outFlagOptions.makeDCABeforeCutPlots) { histos.fill(HIST("tracks/helium/dca/before/fake/hDCAxyVsPtantiHeliumTrue"), antihePt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/fake/TOF/hDCAxyVsPtantiHeliumTrue"), antihePt, track.dcaXY()); - } if (isPhysPrim) { histos.fill(HIST("tracks/helium/dca/before/fake/hDCAxyVsPtantiHeliumTruePrim"), antihePt, track.dcaXY()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/before/fake/TOF/hDCAxyVsPtantiHeliumTruePrim"), antihePt, track.dcaXY()); - } } if (!isPhysPrim && !isProdByGen) { if (isWeakDecay) { @@ -4069,7 +4121,7 @@ struct lfNucleiBATask { } else { histos.fill(HIST("tracks/helium/dca/before/fake/hDCAxyVsPtantiHeliumTrueMaterial"), antihePt, track.dcaXY()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isWeakDecay) { histos.fill(HIST("tracks/helium/dca/before/fake/TOF/hDCAxyVsPtantiHeliumTrueSec"), antihePt, track.dcaXY()); } else { @@ -4106,16 +4158,14 @@ struct lfNucleiBATask { if (isHeWTPCpid) { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsDCAzVsPtHelium"), track.dcaXY(), track.dcaZ(), hePt); histos.fill(HIST("tracks/helium/dca/after/h3DCAvsPtHelium"), track.dcaXY(), track.dcaZ(), hePt); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsDCAzVsPtHelium"), track.dcaXY(), track.dcaZ(), hePt); - } } if (isAntiHeWTPCpid) { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsDCAzVsPtantiHelium"), track.dcaXY(), track.dcaZ(), antihePt); histos.fill(HIST("tracks/helium/dca/after/h3DCAvsPtantiHelium"), track.dcaXY(), track.dcaZ(), antihePt); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsDCAzVsPtantiHelium"), track.dcaXY(), track.dcaZ(), antihePt); - } } if (passDCAxyzCut) { @@ -4124,7 +4174,7 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/dca/after/hDCAxyVsPt"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/dca/after/hDCAzVsPt"), track.pt(), track.dcaZ()); - if (enablePr && prRapCut && (std::abs(track.tpcNSigmaPr()) < nsigmaTPCvar.nsigmaTPCPr)) { + if (enablePr && prRapCut && passPrTPCpid) { if (track.sign() > 0) { histos.fill(HIST("tracks/proton/dca/after/hDCAxyVsPtProton"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/proton/dca/after/hDCAzVsPtProton"), track.pt(), track.dcaZ()); @@ -4133,7 +4183,7 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/proton/dca/after/hDCAzVsPtantiProton"), track.pt(), track.dcaZ()); } } - if (enableTr && trRapCut && isTritonTPCpid) { + if (enableTr && trRapCut && passTrTPCpid) { if (track.sign() > 0) { histos.fill(HIST("tracks/triton/dca/after/hDCAxyVsPtTriton"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/triton/dca/after/hDCAzVsPtTriton"), track.pt(), track.dcaZ()); @@ -4142,7 +4192,7 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/triton/dca/after/hDCAzVsPtantiTriton"), track.pt(), track.dcaZ()); } } - if (enableAl && alRapCut && (std::abs(track.tpcNSigmaAl()) < nsigmaTPCvar.nsigmaTPCAl)) { + if (enableAl && alRapCut && passAlTPCpid) { if (track.sign() > 0) { histos.fill(HIST("tracks/alpha/dca/after/hDCAxyVsPtAlpha"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/alpha/dca/after/hDCAzVsPtAlpha"), track.pt(), track.dcaZ()); @@ -4152,22 +4202,19 @@ struct lfNucleiBATask { } } } - if (isDeWTPCpid) { - if (usenITSLayer && !itsClusterMap.test(trkqcOptions.nITSLayer)) - continue; + if (isDeWTPCpid && (!usenITSLayer || itsClusterMap.test(trkqcOptions.nITSLayer))) { histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteron"), DPt, track.dcaXY()); histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteron"), DPt, track.dcaZ()); } - if (isAntiDeWTPCpid) { - if (usenITSLayer && !itsClusterMap.test(trkqcOptions.nITSLayer)) - continue; + if (isAntiDeWTPCpid && (!usenITSLayer || itsClusterMap.test(trkqcOptions.nITSLayer))) { histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtantiDeuteron"), antiDPt, track.dcaXY()); histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtantiDeuteron"), antiDPt, track.dcaZ()); } + if (isHeWTPCpid) { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtHelium"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtHelium"), hePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtHelium"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtHelium"), hePt, track.dcaZ()); } @@ -4175,7 +4222,7 @@ struct lfNucleiBATask { if (isAntiHeWTPCpid) { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtantiHelium"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtantiHelium"), antihePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHelium"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtantiHelium"), antihePt, track.dcaZ()); } @@ -4183,17 +4230,6 @@ struct lfNucleiBATask { } if (passDCAxyzCut) { - // QA histos fill - if (enableDebug) { - histos.fill(HIST("qa/h1ITSncr"), track.itsNCls()); - histos.fill(HIST("qa/h1TPCnfound"), track.tpcNClsFound()); - histos.fill(HIST("qa/h1TPCncr"), track.tpcNClsCrossedRows()); - histos.fill(HIST("qa/h1rTPC"), track.tpcCrossedRowsOverFindableCls()); - histos.fill(HIST("qa/h1chi2ITS"), track.tpcChi2NCl()); - histos.fill(HIST("qa/h1chi2TPC"), track.itsChi2NCl()); - debugHistos.fill(HIST("debug/h2TPCsignVsTPCmomentum_AllTracks"), track.tpcInnerParam() / (1.f * track.sign()), track.tpcSignal()); - } - if (enableDebug) { debugHistos.fill(HIST("debug/tracks/h1Eta"), track.eta()); debugHistos.fill(HIST("debug/tracks/h1VarPhi"), track.phi()); @@ -4232,6 +4268,11 @@ struct lfNucleiBATask { debugHistos.fill(HIST("debug/tracks/kaon/h2KaonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaKa()); } + if constexpr (!IsFilteredData) { + if (nsigmaITSvar.showAverageClusterSize && outFlagOptions.enablePIDplot) + histos.fill(HIST("tracks/avgClusterSizePerCoslInvVsITSlayers"), track.p(), averageClusterSizePerCoslInv(track), track.itsNCls()); + } + if (outFlagOptions.enableEffPlots) histos.fill(HIST("tracks/eff/h2pVsTPCmomentum"), track.tpcInnerParam(), track.p()); @@ -4269,6 +4310,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/proton/h2ProtonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaPr()); } break; + default: + break; } } if (enableTr && trRapCut) { @@ -4295,6 +4338,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/proton/h2antiProtonVspTNSigmaTPC"), track.pt(), track.tpcNSigmaPr()); } break; + default: + break; } } if (enableTr && trRapCut) { @@ -4306,7 +4351,7 @@ struct lfNucleiBATask { } // TOF - if (outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (enableDebug) { histos.fill(HIST("tracks/pion/h2PionVspTNSigmaTOF"), track.pt(), track.tofNSigmaPi()); histos.fill(HIST("tracks/kaon/h2KaonVspTNSigmaTOF"), track.pt(), track.tofNSigmaKa()); @@ -4328,6 +4373,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/proton/h2ProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); } break; + default: + break; } if (outFlagOptions.enableExpSignalTOF) histos.fill(HIST("tracks/proton/h2ProtonTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffPr()); @@ -4480,6 +4527,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/proton/h2antiProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); } break; + default: + break; } if (outFlagOptions.enableExpSignalTOF) histos.fill(HIST("tracks/proton/h2antiProtonTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffPr()); @@ -4632,6 +4681,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTPC"), DPt, track.tpcNSigmaDe()); } break; + default: + break; } } if (isAntiDeWoTPCpid) { @@ -4657,6 +4708,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/deuteron/h2antiDeuteronVspTNSigmaTPC"), antiDPt, track.tpcNSigmaDe()); } break; + default: + break; } } @@ -4665,6 +4718,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/helium/h2HeliumTPCExpSignalDiffVsPt"), hePt, track.tpcExpSignalDiffHe()); histos.fill(HIST("tracks/helium/h2HeliumVspTNSigmaITSHe"), track.p(), nITSHe); histos.fill(HIST("tracks/helium/h2HeliumVspTNSigmaTPC"), hePt, track.tpcNSigmaHe()); + if (enableDebug && enableHe) + debugHistos.fill(HIST("tracks/helium/h2HeCutFlowVsPt"), 2.f * hePt, 7); if (enableCentrality) histos.fill(HIST("tracks/helium/h3HeliumVspTNSigmaTPCVsMult"), hePt, track.tpcNSigmaHe(), centFT0M); } @@ -4673,6 +4728,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/helium/h2antiHeliumTPCExpSignalDiffVsPt"), antihePt, track.tpcExpSignalDiffHe()); histos.fill(HIST("tracks/helium/h2antiHeliumVspTNSigmaITSHe"), track.p(), nITSHe); histos.fill(HIST("tracks/helium/h2antiHeliumVspTNSigmaTPC"), antihePt, track.tpcNSigmaHe()); + if (enableDebug) + debugHistos.fill(HIST("tracks/helium/h2antiHeCutFlowVsPt"), 2.f * antihePt, 7); if (enableCentrality) histos.fill(HIST("tracks/helium/h3antiHeliumVspTNSigmaTPCVsMult"), antihePt, track.tpcNSigmaHe(), centFT0M); } @@ -4692,7 +4749,7 @@ struct lfNucleiBATask { } // TOF - if (outFlagOptions.doTOFplots) { + if (hasTOFplots) { if (isDeWTPCpid) { switch (useHasTRDConfig) { case 0: @@ -4708,6 +4765,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTOF"), DPt, track.tofNSigmaDe()); } break; + default: + break; } if (outFlagOptions.enableExpSignalTOF) histos.fill(HIST("tracks/deuteron/h2DeuteronTOFExpSignalDiffVsPt"), DPt, track.tofExpSignalDiffDe()); @@ -4728,6 +4787,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/deuteron/h2antiDeuteronVspTNSigmaTOF"), antiDPt, track.tofNSigmaDe()); } break; + default: + break; } if (outFlagOptions.enableExpSignalTOF) histos.fill(HIST("tracks/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt"), antiDPt, track.tofExpSignalDiffDe()); @@ -4756,7 +4817,7 @@ struct lfNucleiBATask { } if (enablePr) { - if (std::abs(track.tpcNSigmaPr()) < nsigmaTPCvar.nsigmaTPCPr && prRapCut) { + if (passPrTPCpid && prRapCut) { if (track.sign() > 0) { if (outFlagOptions.enableEffPlots) { histos.fill(HIST("tracks/eff/proton/hPtPr"), track.pt()); @@ -4783,7 +4844,7 @@ struct lfNucleiBATask { } } if (enableTr) { - if ((isTritonTPCpid) && trRapCut) { + if ((passTrTPCpid) && trRapCut) { if (track.sign() > 0) { if (outFlagOptions.enableEffPlots) { histos.fill(HIST("tracks/eff/triton/hPtTr"), track.pt()); @@ -4804,7 +4865,7 @@ struct lfNucleiBATask { } } if (enableAl) { - if ((std::abs(track.tpcNSigmaAl()) < nsigmaTPCvar.nsigmaTPCAl) && alRapCut) { + if (std::abs(track.tpcNSigmaAl()) < nsigmaTPCvar.nsigmaTPCAl && alRapCut) { if (track.sign() > 0) { histos.fill(HIST("tracks/alpha/h1AlphaSpectra"), track.pt()); if (outFlagOptions.enablePIDplot) @@ -4817,7 +4878,7 @@ struct lfNucleiBATask { } } - if (outFlagOptions.doTOFplots && track.hasTOF()) { + if (hasTOFplots) { if (outFlagOptions.enableEffPlots && enableDebug) { if (track.sign() > 0) debugHistos.fill(HIST("tracks/eff/hPtPTOF"), track.pt()); @@ -4842,6 +4903,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/h2TOFbetaVsP"), track.p() / (1.f * track.sign()), track.beta()); } break; + default: + break; } } @@ -4849,14 +4912,14 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/eff/h2TPCmomentumVsTOFExpMomentum"), track.tofExpMom(), track.tpcInnerParam()); if (enablePr && prRapCut) { - if (std::abs(track.tpcNSigmaPr()) < nsigmaTPCvar.nsigmaTPCPr && track.sign() > 0) { + if (passPrTPCpid && track.sign() > 0) { histos.fill(HIST("tracks/proton/h2ProtonTOFbetaVsP"), track.p(), track.beta()); if (outFlagOptions.enableEffPlots) { histos.fill(HIST("tracks/eff/proton/h2pVsTOFExpMomentumPr"), track.tofExpMom(), track.p()); histos.fill(HIST("tracks/eff/proton/h2TPCmomentumVsTOFExpMomentumPr"), track.tofExpMom(), track.tpcInnerParam()); } } - if (std::abs(track.tpcNSigmaPr()) < nsigmaTPCvar.nsigmaTPCPr && track.sign() < 0) { + if (passPrTPCpid && track.sign() < 0) { histos.fill(HIST("tracks/proton/h2antiProtonTOFbetaVsP"), track.p(), track.beta()); if (outFlagOptions.enableEffPlots) { histos.fill(HIST("tracks/eff/proton/h2pVsTOFExpMomentumantiPr"), track.tofExpMom(), track.p()); @@ -4865,14 +4928,14 @@ struct lfNucleiBATask { } } if (enableTr && trRapCut) { - if (isTritonTPCpid && track.sign() > 0) { + if (passTrTPCpid && track.sign() > 0) { histos.fill(HIST("tracks/triton/h2TritonTOFbetaVsP"), track.p(), track.beta()); if (outFlagOptions.enableEffPlots) { histos.fill(HIST("tracks/eff/triton/h2pVsTOFExpMomentumTr"), track.tofExpMom(), track.p()); histos.fill(HIST("tracks/eff/triton/h2TPCmomentumVsTOFExpMomentumTr"), track.tofExpMom(), track.tpcInnerParam()); } } - if (isTritonTPCpid && track.sign() < 0) { + if (passTrTPCpid && track.sign() < 0) { histos.fill(HIST("tracks/triton/h2antiTritonTOFbetaVsP"), track.p(), track.beta()); if (outFlagOptions.enableEffPlots) { histos.fill(HIST("tracks/eff/triton/h2pVsTOFExpMomentumantiTr"), track.tofExpMom(), track.p()); @@ -4905,6 +4968,7 @@ struct lfNucleiBATask { } histos.fill(HIST("tracks/deuteron/h1DeuteronSpectra"), DPt); histos.fill(HIST("tracks/deuteron/h2DeuteronYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron)), DPt); + histos.fill(HIST("tracks/deuteron/h2DeuteronShiftYvsPt"), getRapidityFromPtMass(track, DPt, o2::track::PID::getMass2Z(o2::track::PID::Deuteron)), DPt); histos.fill(HIST("tracks/deuteron/h2DeuteronEtavsPt"), track.eta(), DPt); histos.fill(HIST("tracks/deuteron/h2DeuteronVspNSigmaITSDe_wTPCpid"), track.p(), nITSDe); @@ -4918,6 +4982,7 @@ struct lfNucleiBATask { } histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectra"), antiDPt); histos.fill(HIST("tracks/deuteron/h2antiDeuteronYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron)), antiDPt); + histos.fill(HIST("tracks/deuteron/h2antiDeuteronShiftYvsPt"), getRapidityFromPtMass(track, antiDPt, o2::track::PID::getMass2Z(o2::track::PID::Deuteron)), antiDPt); histos.fill(HIST("tracks/deuteron/h2antiDeuteronEtavsPt"), track.eta(), antiDPt); histos.fill(HIST("tracks/deuteron/h2antiDeuteronVspNSigmaITSDe_wTPCpid"), track.p(), nITSDe); @@ -4930,7 +4995,10 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/eff/helium/h2pVsTPCmomentumHe"), heTPCmomentum, heP); } histos.fill(HIST("tracks/helium/h1HeliumSpectra_Z2"), 2 * hePt); + if (enableDebug && enableHe) + debugHistos.fill(HIST("tracks/helium/h2HeCutFlowVsPt"), 2.f * hePt, 8); histos.fill(HIST("tracks/helium/h2HeliumYvsPt_Z2"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); + histos.fill(HIST("tracks/helium/h2HeliumShiftYvsPt_Z2"), getRapidityFromPtMass(track, hePt, o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * hePt); histos.fill(HIST("tracks/helium/h2HeliumEtavsPt_Z2"), track.eta(), 2 * hePt); if (outFlagOptions.enablePIDplot) histos.fill(HIST("tracks/helium/h2TPCsignVsTPCmomentumHelium"), heTPCmomentum, track.tpcSignal()); @@ -4943,7 +5011,10 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/eff/helium/h2pVsTPCmomentumantiHe"), antiheTPCmomentum, antiheP); } histos.fill(HIST("tracks/helium/h1antiHeliumSpectra_Z2"), 2 * antihePt); + if (enableDebug) + debugHistos.fill(HIST("tracks/helium/h2antiHeCutFlowVsPt"), 2.f * antihePt, 8); histos.fill(HIST("tracks/helium/h2antiHeliumYvsPt_Z2"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * antihePt); + histos.fill(HIST("tracks/helium/h2antiHeliumShiftYvsPt_Z2"), getRapidityFromPtMass(track, antihePt, o2::track::PID::getMass2Z(o2::track::PID::Helium3)), 2 * antihePt); histos.fill(HIST("tracks/helium/h2antiHeliumEtavsPt_Z2"), track.eta(), 2 * antihePt); if (outFlagOptions.enablePIDplot) histos.fill(HIST("tracks/helium/h2TPCsignVsTPCmomentumantiHelium"), antiheTPCmomentum, track.tpcSignal()); @@ -4951,7 +5022,7 @@ struct lfNucleiBATask { debugHistos.fill(HIST("tracks/helium/h2antiHeliumPidTrackingVsPt"), 2 * antihePt, track.pidForTracking()); } - if (outFlagOptions.doTOFplots && track.hasTOF()) { + if (hasTOFplots) { if (isDeWTPCpid) { histos.fill(HIST("tracks/deuteron/h2DeuteronTOFbetaVsP"), track.p(), track.beta()); if (outFlagOptions.enableEffPlots) { @@ -5004,6 +5075,11 @@ struct lfNucleiBATask { massTOFhe = heP * std::sqrt(1.f / (track.beta() * track.beta()) - 1.f); massTOFantihe = antiheP * std::sqrt(1.f / (track.beta() * track.beta()) - 1.f); break; + default: + massTOF = -99.f; + massTOFhe = -99.f; + massTOFantihe = -99.f; + break; } if (passDCAxyzCut && outFlagOptions.doTOFplots && outFlagOptions.enablePIDplot) histos.fill(HIST("tracks/h2TPCsignVsBetaGamma"), (track.beta() * gamma) / (1.f * track.sign()), track.tpcSignal()); @@ -5029,7 +5105,7 @@ struct lfNucleiBATask { } if (enablePr) { - if ((std::abs(track.tpcNSigmaPr()) < nsigmaTPCvar.nsigmaTPCPr) && prRapCut) { + if (passPrTPCpid && prRapCut) { if (track.sign() > 0) { if (outFlagOptions.enableEffPlots) histos.fill(HIST("tracks/eff/proton/hPtPrTOF"), track.pt()); @@ -5078,7 +5154,7 @@ struct lfNucleiBATask { } } - if (enableTr && isTritonTPCpid && trRapCut) { + if (enableTr && passTrTPCpid && trRapCut) { const float m2diff = massTOF * massTOF - MassTritonVal * MassTritonVal; if (track.sign() > 0) { if (outFlagOptions.enableEffPlots) @@ -5161,8 +5237,10 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/helium/h2TOFmassHeliumVsPt"), 2.f * massTOFhe, hePt); histos.fill(HIST("tracks/helium/h2TOFmassDeltaHeliumVsPt"), 2.f * massTOFhe - MassHeliumVal, hePt); histos.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt"), 2.f * massTOFhe * 2.f * massTOFhe - MassHeliumVal * MassHeliumVal, hePt); + if (enableDebug && enableHe) + debugHistos.fill(HIST("tracks/helium/h2HeCutFlowVsPt"), 2.f * hePt, 9); if (enableCentrality) - histos.fill(HIST("tracks/helium/h3TOFmass2HeliumVsPtVsMult"), 2.f * massTOFantihe * 2.f * massTOFantihe - MassHeliumVal * MassHeliumVal, hePt, centFT0M); + histos.fill(HIST("tracks/helium/h3TOFmass2HeliumVsPtVsMult"), 2.f * massTOFhe * 2.f * massTOFhe - MassHeliumVal * MassHeliumVal, hePt, centFT0M); if (outFlagOptions.enableBetaCut && (track.beta() > cfgBetaCut)) { histos.fill(HIST("tracks/helium/h2TOFmassHeliumVsPt_BetaCut"), 2.f * massTOFhe, hePt); histos.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt_BetaCut"), 2.f * massTOFhe * 2.f * massTOFhe - MassHeliumVal * MassHeliumVal, hePt); @@ -5176,6 +5254,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/helium/h2TOFmassantiHeliumVsPt"), 2.f * massTOFantihe, antihePt); histos.fill(HIST("tracks/helium/h2TOFmassDeltaantiHeliumVsPt"), 2.f * massTOFantihe - MassHeliumVal, antihePt); histos.fill(HIST("tracks/helium/h2TOFmass2antiHeliumVsPt"), 2.f * massTOFantihe * 2.f * massTOFantihe - MassHeliumVal * MassHeliumVal, antihePt); + if (enableDebug) + debugHistos.fill(HIST("tracks/helium/h2antiHeCutFlowVsPt"), 2.f * antihePt, 9); if (enableCentrality) histos.fill(HIST("tracks/helium/h3TOFmass2antiHeliumVsPtVsMult"), 2.f * massTOFantihe * 2.f * massTOFantihe - MassHeliumVal * MassHeliumVal, antihePt, centFT0M); if (outFlagOptions.enableBetaCut && (track.beta() > cfgBetaCut)) { @@ -5332,9 +5412,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/proton/dca/after/hDCAxyVsPtProtonTrue"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/proton/dca/after/hDCAzVsPtProtonTrue"), track.pt(), track.dcaZ()); } - if (std::abs(track.tpcNSigmaPr()) < nsigmaTPCvar.nsigmaTPCPr) { + if (passPrTPCpid) histos.fill(HIST("tracks/proton/h1ProtonSpectraTrueWPID"), track.pt()); - } if (isPhysPrim) { histos.fill(HIST("tracks/proton/h1ProtonSpectraTruePrim"), track.pt()); if (outFlagOptions.makeDCAAfterCutPlots) { @@ -5386,7 +5465,7 @@ struct lfNucleiBATask { } } - if (std::abs(track.tpcNSigmaPr()) < nsigmaTPCvar.nsigmaTPCPr) { + if (passPrTPCpid) { if (enableTrackingEff) { if (isItsPassed) { debugHistos.fill(HIST("tracks/proton/trackingEffPID/h1ProtonSpectraPIDTruePrim_its"), track.pt()); @@ -5455,9 +5534,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/proton/dca/after/hDCAxyVsPtantiProtonTrue"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/proton/dca/after/hDCAzVsPtantiProtonTrue"), track.pt(), track.dcaZ()); } - if (std::abs(track.tpcNSigmaPr()) < nsigmaTPCvar.nsigmaTPCPr) { + if (passPrTPCpid) histos.fill(HIST("tracks/proton/h1antiProtonSpectraTrueWPID"), track.pt()); - } if (isPhysPrim) { histos.fill(HIST("tracks/proton/h1antiProtonSpectraTruePrim"), track.pt()); if (outFlagOptions.makeDCAAfterCutPlots) { @@ -5509,7 +5587,7 @@ struct lfNucleiBATask { } } - if (std::abs(track.tpcNSigmaPr()) < nsigmaTPCvar.nsigmaTPCPr) { + if (passPrTPCpid) { if (enableTrackingEff) { if (isItsPassed) { debugHistos.fill(HIST("tracks/proton/trackingEffPID/h1antiProtonSpectraPIDTruePrim_its"), track.pt()); @@ -5579,11 +5657,10 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteronTrue"), DPt, track.dcaXY()); histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteronTrue"), DPt, track.dcaZ()); } - if (std::abs(track.tpcNSigmaDe()) < nsigmaTPCvar.nsigmaTPCDe) { + if (passDeTPCpid) { histos.fill(HIST("tracks/deuteron/h1DeuteronSpectraTrueWPID"), DPt); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/hPtDeuteronTOFTrue"), DPt); - } } if (isPhysPrim) { histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTPCTruePrim"), DPt, track.tpcNSigmaDe()); @@ -5637,15 +5714,14 @@ struct lfNucleiBATask { } } - if (std::abs(track.tpcNSigmaDe()) < nsigmaTPCvar.nsigmaTPCDe) { + if (passDeTPCpid) { histos.fill(HIST("tracks/deuteron/h1DeuteronSpectraTrueWPIDPrim"), DPt); if (outFlagOptions.makeDCAAfterCutPlots) { histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteronTrueWPIDPrim"), DPt, track.dcaXY()); histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteronTrueWPIDPrim"), DPt, track.dcaZ()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/hPtDeuteronTOFTrueWPIDPrim"), DPt); - } if (enableTrackingEff) { if (isItsPassed) { @@ -5715,11 +5791,10 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtantiDeuteronTrue"), antiDPt, track.dcaXY()); histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtantiDeuteronTrue"), antiDPt, track.dcaZ()); } - if (std::abs(track.tpcNSigmaDe()) < nsigmaTPCvar.nsigmaTPCDe) { + if (passDeTPCpid) { histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectraTrueWPID"), antiDPt); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/hPtantiDeuteronTOFTrue"), antiDPt); - } } if (isPhysPrim) { histos.fill(HIST("tracks/deuteron/h2antiDeuteronVspTNSigmaTPCTruePrim"), antiDPt, track.tpcNSigmaDe()); @@ -5773,15 +5848,14 @@ struct lfNucleiBATask { } } - if (std::abs(track.tpcNSigmaDe()) < nsigmaTPCvar.nsigmaTPCDe) { + if (passDeTPCpid) { histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectraTrueWPIDPrim"), antiDPt); if (outFlagOptions.makeDCAAfterCutPlots) { histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtantiDeuteronTrueWPIDPrim"), antiDPt, track.dcaXY()); histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtantiDeuteronTrueWPIDPrim"), antiDPt, track.dcaZ()); } - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/deuteron/hPtantiDeuteronTOFTrueWPIDPrim"), antiDPt); - } if (enableTrackingEff) { if (isItsPassed) { @@ -5914,24 +5988,22 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtHeliumTrue"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtHeliumTrue"), hePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtHeliumTrue"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtHeliumTrue"), hePt, track.dcaZ()); } } - if (std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe) { + if (passHeTPCpid) { histos.fill(HIST("tracks/helium/h1HeliumSpectraTrueWPID_Z2"), 2 * hePt); if (enableCentrality) { histos.fill(HIST("tracks/helium/h2HeliumSpectraTrueWPIDVsMult_Z2"), 2 * hePt, centFT0M); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/TOF/h2HeliumSpectraTrueWPIDVsMult_Z2"), 2 * hePt, centFT0M); - } } if (outFlagOptions.enableEffPlots) { histos.fill(HIST("tracks/eff/helium/hPtHeTrue_Z2"), 2 * hePt); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/eff/helium/hPtHeTOFTrue_Z2"), 2 * hePt); - } } } if (isPhysPrim) { @@ -5941,8 +6013,8 @@ struct lfNucleiBATask { if constexpr (!IsFilteredData) histos.fill(HIST("tracks/helium/h2HeliumSpectraTruePrimGenVsMult_Z2"), track.mcParticle().pt(), centFT0M); } - if (std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe) { - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (passHeTPCpid) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/TOF/h1HeliumSpectraTruePrim_Z2"), 2 * hePt); if (enableCentrality) { histos.fill(HIST("tracks/helium/TOF/h2HeliumSpectraTruePrimVsMult_Z2"), 2 * hePt, centFT0M); @@ -5955,7 +6027,7 @@ struct lfNucleiBATask { if (outFlagOptions.makeDCAAfterCutPlots) { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtHeliumTruePrim"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtHeliumTruePrim"), hePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtHeliumTruePrim"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtHeliumTruePrim"), hePt, track.dcaZ()); } @@ -5966,7 +6038,7 @@ struct lfNucleiBATask { if (outFlagOptions.makeDCAAfterCutPlots) { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtHeliumTrueTransport"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtHeliumTrueTransport"), hePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtHeliumTrueTransport"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtHeliumTrueTransport"), hePt, track.dcaZ()); } @@ -5978,7 +6050,7 @@ struct lfNucleiBATask { if (outFlagOptions.makeDCAAfterCutPlots) { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtHeliumTrueSec"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtHeliumTrueSec"), hePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtHeliumTrueSec"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtHeliumTrueSec"), hePt, track.dcaZ()); } @@ -5992,27 +6064,25 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTrue_Z2"), 2 * antihePt); if (enableCentrality) { histos.fill(HIST("tracks/helium/h2antiHeliumSpectraTrueVsMult_Z2"), 2 * antihePt, centFT0M); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/helium/TOF/h2antiHeliumSpectraTrueWPIDVsMult_Z2"), 2 * antihePt, centFT0M); - } } if (outFlagOptions.makeDCAAfterCutPlots) { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTrue"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtantiHeliumTrue"), antihePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHeliumTrue"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtantiHeliumTrue"), antihePt, track.dcaZ()); } } - if (std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe) { + if (passHeTPCpid) { histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTrueWPID_Z2"), 2 * antihePt); if (enableCentrality) histos.fill(HIST("tracks/helium/h2antiHeliumSpectraTrueWPIDVsMult_Z2"), 2 * antihePt, centFT0M); if (outFlagOptions.enableEffPlots) { histos.fill(HIST("tracks/eff/helium/hPtantiHeTrue_Z2"), 2 * antihePt); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) histos.fill(HIST("tracks/eff/helium/hPtantiHeTOFTrue_Z2"), 2 * antihePt); - } } } if (isPhysPrim) { @@ -6023,8 +6093,8 @@ struct lfNucleiBATask { histos.fill(HIST("tracks/helium/h2antiHeliumSpectraTruePrimGenVsMult_Z2"), track.mcParticle().pt(), centFT0M); } - if (std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe) { - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (passHeTPCpid) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/TOF/h1antiHeliumSpectraTruePrim_Z2"), 2 * antihePt); if (enableCentrality) { histos.fill(HIST("tracks/helium/TOF/h2antiHeliumSpectraTruePrimVsMult_Z2"), 2 * antihePt, centFT0M); @@ -6037,7 +6107,7 @@ struct lfNucleiBATask { if (outFlagOptions.makeDCAAfterCutPlots) { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTruePrim"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtantiHeliumTruePrim"), antihePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHeliumTruePrim"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtantiHeliumTruePrim"), antihePt, track.dcaZ()); } @@ -6048,7 +6118,7 @@ struct lfNucleiBATask { if (outFlagOptions.makeDCAAfterCutPlots) { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTrueTransport"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtantiHeliumTrueTransport"), antihePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHeliumTrueTransport"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtantiHeliumTrueTransport"), antihePt, track.dcaZ()); } @@ -6061,7 +6131,7 @@ struct lfNucleiBATask { if (outFlagOptions.makeDCAAfterCutPlots) { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTrueSec"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtantiHeliumTrueSec"), antihePt, track.dcaZ()); - if (track.hasTOF() && outFlagOptions.doTOFplots) { + if (hasTOFplots) { histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHeliumTrueSec"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtantiHeliumTrueSec"), antihePt, track.dcaZ()); } @@ -6298,7 +6368,6 @@ struct lfNucleiBATask { } // CLOSING PROCESS MC RECO PROCESS_SWITCH(lfNucleiBATask, processMCRecoLfPid, "process mc reco with LfPid", false); - // Process function that runs on the original AO2D (for the MC) with the LfPIDcalibration void processMCRecoLfPidEv(EventCandidatesMC const& collisions, soa::Join const&, aod::McParticles const& mcParticles, @@ -6324,85 +6393,95 @@ struct lfNucleiBATask { const float pt = mcParticle.pt(); bool isPhysPrim = mcParticle.isPhysicalPrimary(); + const bool isHe = (pdg == PDGHelium); + const bool isAntiHe = (pdg == -PDGHelium); + // No cut spectraGen.fill(HIST("LfEv/pT_nocut"), pt); - if (pdg == PDGHelium) { + if (isHe) { spectraGen.fill(HIST("LfEv/helium/pT_nocut_He"), pt); if (isPhysPrim) spectraGen.fill(HIST("LfEv/helium/prim/pT_nocut_He"), pt); } - if (pdg == -PDGHelium) { + if (isAntiHe) { spectraGen.fill(HIST("LfEv/helium/pT_nocut_antiHe"), pt); if (isPhysPrim) spectraGen.fill(HIST("LfEv/helium/prim/pT_nocut_antiHe"), pt); } + // Trigger TVX if (hasTVX) { spectraGen.fill(HIST("LfEv/pT_TVXtrigger"), pt); - if (pdg == PDGHelium) { + if (isHe) { spectraGen.fill(HIST("LfEv/helium/pT_TVXtrigger_He"), pt); if (isPhysPrim) spectraGen.fill(HIST("LfEv/helium/prim/pT_TVXtrigger_He"), pt); } - if (pdg == -PDGHelium) { + if (isAntiHe) { spectraGen.fill(HIST("LfEv/helium/pT_TVXtrigger_antiHe"), pt); if (isPhysPrim) spectraGen.fill(HIST("LfEv/helium/prim/pT_TVXtrigger_antiHe"), pt); } } + // No Time Frame Border if (hasNoTFB) { spectraGen.fill(HIST("LfEv/pT_TFrameBorder"), pt); - if (pdg == PDGHelium) { + if (isHe) { spectraGen.fill(HIST("LfEv/helium/pT_TFrameBorder_He"), pt); if (isPhysPrim) spectraGen.fill(HIST("LfEv/helium/prim/pT_TFrameBorder_He"), pt); } - if (pdg == -PDGHelium) { + if (isAntiHe) { spectraGen.fill(HIST("LfEv/helium/pT_TFrameBorder_antiHe"), pt); if (isPhysPrim) spectraGen.fill(HIST("LfEv/helium/prim/pT_TFrameBorder_antiHe"), pt); } } + // No ITS ROF Frame Border if (hasNoItsRofFB) { spectraGen.fill(HIST("LfEv/pT_ITSROFBorder"), pt); - if (pdg == PDGHelium) { + if (isHe) { spectraGen.fill(HIST("LfEv/helium/pT_ITSROFBorder_He"), pt); if (isPhysPrim) spectraGen.fill(HIST("LfEv/helium/prim/pT_ITSROFBorder_He"), pt); } - if (pdg == -PDGHelium) { + if (isAntiHe) { spectraGen.fill(HIST("LfEv/helium/pT_ITSROFBorder_antiHe"), pt); if (isPhysPrim) spectraGen.fill(HIST("LfEv/helium/prim/pT_ITSROFBorder_antiHe"), pt); } } + // Sel8 MC if (hasTVX && hasNoTFB) { spectraGen.fill(HIST("LfEv/pT_MCsel8"), pt); - if (pdg == PDGHelium) { + if (isHe) { spectraGen.fill(HIST("LfEv/helium/pT_MCsel8_He"), pt); if (isPhysPrim) spectraGen.fill(HIST("LfEv/helium/prim/pT_MCsel8_He"), pt); } - if (pdg == -PDGHelium) { + if (isAntiHe) { spectraGen.fill(HIST("LfEv/helium/pT_MCsel8_antiHe"), pt); if (isPhysPrim) spectraGen.fill(HIST("LfEv/helium/prim/pT_MCsel8_antiHe"), pt); } } + // Sel8 tag if (hasSel8) { spectraGen.fill(HIST("LfEv/pT_sel8"), pt); - if (pdg == PDGHelium) + if (isHe) { spectraGen.fill(HIST("LfEv/helium/pT_sel8_He"), pt); - if (isPhysPrim) - spectraGen.fill(HIST("LfEv/helium/prim/pT_sel8_He"), pt); - if (pdg == -PDGHelium) + if (isPhysPrim) + spectraGen.fill(HIST("LfEv/helium/prim/pT_sel8_He"), pt); + } + if (isAntiHe) { spectraGen.fill(HIST("LfEv/helium/pT_sel8_antiHe"), pt); - if (isPhysPrim) - spectraGen.fill(HIST("LfEv/helium/prim/pT_sel8_antiHe"), pt); + if (isPhysPrim) + spectraGen.fill(HIST("LfEv/helium/prim/pT_sel8_antiHe"), pt); + } } } } @@ -6440,7 +6519,7 @@ struct lfNucleiBATask { if (enableEffEvtSet) { if (!effEvtSetReady) return; - if (!effEvtSet.count(mcIdx)) + if (!effEvtSet.contains(mcIdx)) return; } @@ -6737,47 +6816,66 @@ struct lfNucleiBATask { for (const auto& mcPart : mcParticles) { if (!mcPart.isPhysicalPrimary()) continue; - if (std::abs(mcPart.y()) >= CfgTpcClasses[0]) + if (mcPart.y() > kinemOptions.cfgRapidityCutHigh || mcPart.y() < kinemOptions.cfgRapidityCutLow) continue; - const float pt = mcPart.pt(); const int pdg = mcPart.pdgCode(); + const bool isDe = enableDe && (std::abs(pdg) == PDGDeuteron); + const bool isHe = enableHe && (std::abs(pdg) == PDGHelium); + + // Exclude other species + if (!isDe && !isHe) + continue; + + const float pt = mcPart.pt(); - if (pdg == PDGDeuteron) { - evLossHistos.fill(HIST("evLoss/pt/hDeuteronGen"), pt); - if (isTvxEvent) - evLossHistos.fill(HIST("evLoss/pt/hDeuteronTriggeredTVX"), pt); - if (isSel8Event) - evLossHistos.fill(HIST("evLoss/pt/hDeuteronTriggeredSel8"), pt); - if (isMCSel8Event) - evLossHistos.fill(HIST("evLoss/pt/hDeuteronTriggeredMCSel8"), pt); - } - if (pdg == -PDGDeuteron) { - evLossHistos.fill(HIST("evLoss/pt/hAntiDeuteronGen"), pt); - if (isTvxEvent) - evLossHistos.fill(HIST("evLoss/pt/hAntiDeuteronTriggeredTVX"), pt); - if (isSel8Event) - evLossHistos.fill(HIST("evLoss/pt/hAntiDeuteronTriggeredSel8"), pt); - if (isMCSel8Event) - evLossHistos.fill(HIST("evLoss/pt/hAntiDeuteronTriggeredMCSel8"), pt); - } - if (pdg == PDGHelium) { - evLossHistos.fill(HIST("evLoss/pt/hHeliumGen"), pt); - if (isTvxEvent) - evLossHistos.fill(HIST("evLoss/pt/hHeliumTriggeredTVX"), pt); - if (isSel8Event) - evLossHistos.fill(HIST("evLoss/pt/hHeliumTriggeredSel8"), pt); - if (isMCSel8Event) - evLossHistos.fill(HIST("evLoss/pt/hHeliumTriggeredMCSel8"), pt); - } - if (pdg == -PDGHelium) { - evLossHistos.fill(HIST("evLoss/pt/hAntiHeliumGen"), pt); - if (isTvxEvent) - evLossHistos.fill(HIST("evLoss/pt/hAntiHeliumTriggeredTVX"), pt); - if (isSel8Event) - evLossHistos.fill(HIST("evLoss/pt/hAntiHeliumTriggeredSel8"), pt); - if (isMCSel8Event) - evLossHistos.fill(HIST("evLoss/pt/hAntiHeliumTriggeredMCSel8"), pt); + switch (pdg) { + case PDGDeuteron: // Deuteron + if (!enableDe) + break; + evLossHistos.fill(HIST("evLoss/pt/hDeuteronGen"), pt); + if (isTvxEvent) + evLossHistos.fill(HIST("evLoss/pt/hDeuteronTriggeredTVX"), pt); + if (isSel8Event) + evLossHistos.fill(HIST("evLoss/pt/hDeuteronTriggeredSel8"), pt); + if (isMCSel8Event) + evLossHistos.fill(HIST("evLoss/pt/hDeuteronTriggeredMCSel8"), pt); + break; + case -PDGDeuteron: // Antideuteron + if (!enableDe) + break; + evLossHistos.fill(HIST("evLoss/pt/hAntiDeuteronGen"), pt); + if (isTvxEvent) + evLossHistos.fill(HIST("evLoss/pt/hAntiDeuteronTriggeredTVX"), pt); + if (isSel8Event) + evLossHistos.fill(HIST("evLoss/pt/hAntiDeuteronTriggeredSel8"), pt); + if (isMCSel8Event) + evLossHistos.fill(HIST("evLoss/pt/hAntiDeuteronTriggeredMCSel8"), pt); + break; + case PDGHelium: // Helium-3 + if (!enableHe) + break; + evLossHistos.fill(HIST("evLoss/pt/hHeliumGen"), pt); + if (isTvxEvent) + evLossHistos.fill(HIST("evLoss/pt/hHeliumTriggeredTVX"), pt); + if (isSel8Event) + evLossHistos.fill(HIST("evLoss/pt/hHeliumTriggeredSel8"), pt); + if (isMCSel8Event) + evLossHistos.fill(HIST("evLoss/pt/hHeliumTriggeredMCSel8"), pt); + break; + case -PDGHelium: // Antihelium-3 + if (!enableHe) + break; + evLossHistos.fill(HIST("evLoss/pt/hAntiHeliumGen"), pt); + if (isTvxEvent) + evLossHistos.fill(HIST("evLoss/pt/hAntiHeliumTriggeredTVX"), pt); + if (isSel8Event) + evLossHistos.fill(HIST("evLoss/pt/hAntiHeliumTriggeredSel8"), pt); + if (isMCSel8Event) + evLossHistos.fill(HIST("evLoss/pt/hAntiHeliumTriggeredMCSel8"), pt); + break; + default: + break; } } } diff --git a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx index c75d5273692..7f0864b61c1 100644 --- a/PWGLF/Tasks/Nuspex/multiplicityPt.cxx +++ b/PWGLF/Tasks/Nuspex/multiplicityPt.cxx @@ -13,12 +13,12 @@ /// \file multiplicityPt.cxx /// \brief Analysis to do PID with MC - Full correction factors for pions, kaons, protons -#include "PWGLF/DataModel/mcCentrality.h" -#include "PWGLF/Utils/inelGt.h" - +#include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -29,62 +29,116 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include +#include +#include +#include #include #include -#include +#include #include -#include #include -#include -#include +#include #include #include -#include #include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -using namespace o2::constants::math; using namespace constants::physics; using BCsRun3 = soa::Join; +// Reconstructed collisions joined with MC label + centrality +using ColEvSelsMC = soa::Join; + +// Data collision table (for processData) +using CollisionTableData = soa::Join; + +// Track tables - with TPC PID only +using TrackTableData = soa::Join; + +using TracksMC = soa::Join; + struct MultiplicityPt { - Service pdg; - Service ccdb; + // ── Services ────────────────────────────────────────────── + Service pdg{}; + Service ccdb{}; + + static constexpr int NCentHists{10}; + static constexpr int NPartHists{5}; + std::array, NCentHists> hDedxVsMomentumVsCentPos{}; + std::array, NCentHists> hDedxVsMomentumVsCentNeg{}; + std::array, NCentHists + 1> hDedxVspTMomentumVsCent{}; + std::array, NCentHists + 1> hMomentumVsEtaPos{}; + std::array, NCentHists + 1> hMomentumVsEtaNeg{}; + std::array, NCentHists + 1> hpTVsEtaPos{}; + std::array, NCentHists + 1> hpTVsEtaNeg{}; + // Total counts + std::array, NCentHists + 1> hTotalMomPosCent{}; + std::array, NCentHists + 1> hTotalMomNegCent{}; + std::array, NCentHists + 1> hTotalPtPosCent{}; + std::array, NCentHists + 1> hTotalPtNegCent{}; + // Counts for particles + std::array, NCentHists + 1>, NPartHists> hFracMomPosCent{}; + std::array, NCentHists + 1>, NPartHists> hFracMomNegCent{}; + std::array, NCentHists + 1>, NPartHists> hFracPtPosCent{}; + std::array, NCentHists + 1>, NPartHists> hFracPtNegCent{}; + + // ── Constant values ────────────────────────────────── static constexpr int CentBinMax = 100; - static constexpr int MultBinMax = 200; - static constexpr int RecMultBinMax = 100; - static constexpr int ParticlesType = 4; + static constexpr int NEvLabel = 15; static constexpr int ResponseMatrixTypes = 7; - static constexpr int CentralityClasses = 10; - - enum INELCutSelection : int { - INEL = 0, - INELgt0 = 1, - INELgt1 = 2 - }; + // ── Configurables: event ────────────────────────────────── Configurable isRun3{"isRun3", true, "is Run3 dataset"}; Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgINELCut{"cfgINELCut", 0, "INEL event selection: 0 no sel, 1 INEL>0, 2 INEL>1"}; + Configurable askForCustomTVX{"askForCustomTVX", false, "Ask for custom TVX rather than sel8"}; + Configurable removeITSROFrameBorder{"removeITSROFrameBorder", false, "Remove ITS Read-Out Frame border"}; + Configurable removeNoSameBunchPileup{"removeNoSameBunchPileup", false, "Remove no same bunch pileup"}; + Configurable requireIsGoodZvtxFT0vsPV{"requireIsGoodZvtxFT0vsPV", false, "Require good Z vertex FT0 vs PV"}; + Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", false, "Require vertex ITSTPC"}; + Configurable removeNoTimeFrameBorder{"removeNoTimeFrameBorder", false, "Remove no time frame border"}; + + // Gen-level event selection + Configurable selTVXMC{"selTVXMC", true, "Require TVX-equivalent at gen level"}; + Configurable isZvtxPosSelMC{"isZvtxPosSelMC", true, "Require |Zvtx| cfgCutEtaMax{"cfgCutEtaMax", 0.8f, "Max eta range for tracks"}; Configurable cfgCutEtaMin{"cfgCutEtaMin", -0.8f, "Min eta range for tracks"}; + Configurable cfgCutY{"cfgCutY", 0.5f, "Y range for tracks"}; Configurable cfgCutNsigma{"cfgCutNsigma", 3.0f, "nsigma cut range for tracks"}; - + Configurable lastRequiredTrdCluster{"lastRequiredTrdCluster", -1, "Last cluster to require in TRD"}; + Configurable requireTrdOnly{"requireTrdOnly", false, "Require only tracks from TRD"}; + Configurable requireNoTrd{"requireNoTrd", false, "Require tracks without TRD"}; + Configurable multiplicityEstimator{"multiplicityEstimator", 6, + "Multiplicity estimator: 0=NoMult, 1=MultFV0M, 2=MultFT0M, 3=MultFDDM, 4=MultTracklets, 5=MultTPC, 6=MultNTracksPV, 7=MultNTracksPVeta1, 8=CentFT0C, 9=CentFT0M, 10=CentFV0A"}; + + // Track cuts + Configurable enableDCAHistograms{"enableDCAHistograms", false, "Enable DCA histograms"}; Configurable enablePIDHistograms{"enablePIDHistograms", true, "Enable PID histograms"}; Configurable useCustomTrackCuts{"useCustomTrackCuts", true, "Flag to use custom track cuts"}; Configurable itsPattern{"itsPattern", 0, "0 = Run3ITSibAny, 1 = Run3ITSallAny, 2 = Run3ITSall7Layers, 3 = Run3ITSibTwo"}; @@ -96,73 +150,589 @@ struct MultiplicityPt { Configurable maxChi2PerClusterTPC{"maxChi2PerClusterTPC", 4.f, "Additional cut on the maximum value of the chi2 per cluster in the TPC"}; Configurable minChi2PerClusterTPC{"minChi2PerClusterTPC", 0.5f, "Additional cut on the minimum value of the chi2 per cluster in the TPC"}; Configurable maxChi2PerClusterITS{"maxChi2PerClusterITS", 36.f, "Additional cut on the maximum value of the chi2 per cluster in the ITS"}; - Configurable maxDcaXYFactor{"maxDcaXYFactor", 1.f, "Additional cut on the maximum value of the DCA xy (multiplicative factor)"}; - Configurable maxDcaZ{"maxDcaZ", 0.1f, "Additional cut on the maximum value of the DCA z"}; + Configurable nSigmaDCAxy{"nSigmaDCAxy", 1.f, "Additional cut on the maximum value of the DCA xy (multiplicative factor)"}; + Configurable dcaXYp0{"dcaXYp0", 0.0105f, "DCAxy formula: p0 + p1/pt^p2"}; + Configurable dcaXYp1{"dcaXYp1", 0.0350f, "DCAxy p1 parameter"}; + Configurable dcaXYp2{"dcaXYp2", 1.1f, "DCAxy p2 parameter"}; + Configurable nSigmaDCAz{"nSigmaDCAz", 1.f, "Additional cut on the maximum value of the DCA z (multiplicative factor)"}; + Configurable dcaZp0{"dcaZp0", 0.0105f, "DCAz formula: p0 + p1/pt^p2"}; + Configurable dcaZp1{"dcaZp1", 0.0350f, "DCAz p1 parameter"}; + Configurable dcaZp2{"dcaZp2", 1.1f, "DCAz p2 parameter"}; + // Configurable maxDcaZ{"maxDcaZ", 2.0f, "Additional cut on the maximum value of the DCA z"}; Configurable minTPCNClsFound{"minTPCNClsFound", 70.0f, "min number of found TPC clusters"}; Configurable minTPCNClsPID{"minTPCNClsPID", 130.0f, "min number of PID TPC clusters"}; Configurable nClTPCFoundCut{"nClTPCFoundCut", false, "Apply TPC found clusters cut"}; Configurable nClTPCPIDCut{"nClTPCPIDCut", true, "Apply TPC clusters for PID cut"}; + Configurable minITSnClusters{"minITSnClusters", 5, "minimum number of found ITS clusters"}; + Configurable cfgTrkLowPtCut{"cfgTrkLowPtCut", 0.15f, "Minimum constituent pT"}; - Configurable applyPhiCut{"applyPhiCut", false, "Apply phi sector cut to remove problematic TPC regions"}; + // PID selection + Configurable cfgCutNsigmaPi{"cfgCutNsigmaPi", 3.0f, "nsigma cut for pions"}; + Configurable cfgCutNsigmaKa{"cfgCutNsigmaKa", 2.5f, "nsigma cut for kaons"}; + Configurable cfgCutNsigmaPr{"cfgCutNsigmaPr", 2.5f, "nsigma cut for protons"}; + + // Phi cut parameters + Configurable applyPhiCut{"applyPhiCut", true, "Apply phi sector cut"}; Configurable pTthresholdPhiCut{"pTthresholdPhiCut", 2.0f, "pT threshold above which to apply phi cut"}; Configurable phiCutLowParam1{"phiCutLowParam1", 0.119297, "First parameter for low phi cut"}; Configurable phiCutLowParam2{"phiCutLowParam2", 0.000379693, "Second parameter for low phi cut"}; Configurable phiCutHighParam1{"phiCutHighParam1", 0.16685, "First parameter for high phi cut"}; Configurable phiCutHighParam2{"phiCutHighParam2", 0.00981942, "Second parameter for high phi cut"}; - Configurable cfgTrkLowPtCut{"cfgTrkLowPtCut", 0.15f, "Minimum constituent pT"}; + // ── Nch window for multiplicity axis ────────────────────── + Configurable tpcNchAcceptance{"tpcNchAcceptance", 0.8f, + "|eta| window for counting gen. Nch (multiplicity axis)"}; - Configurable cfgCutNsigmaPi{"cfgCutNsigmaPi", 3.0f, "nsigma cut for pions"}; - Configurable cfgCutNsigmaKa{"cfgCutNsigmaKa", 2.5f, "nsigma cut for kaons"}; - Configurable cfgCutNsigmaPr{"cfgCutNsigmaPr", 2.5f, "nsigma cut for protons"}; + // ── Histogram binning ──────────────────────────────────── + Configurable nBinsNch{"nBinsNch", 200, "Bins on gen-Nch axis"}; + Configurable maxNch{"maxNch", 200.0f, "Max gen Nch on histogram axis"}; + Configurable nBinsNPV{"nBinsNPV", 600, "N bins ITS tracks"}; + Configurable minNpv{"minNpv", 0, "Min NPV"}; + Configurable maxNpv{"maxNpv", 600, "Max NPV"}; ConfigurableAxis ptBinning{"ptBinning", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, "pT bin limits"}; ConfigurableAxis pFineBins{"pFineBins", {1995, 0.1, 40}, "Binning for momentum"}; ConfigurableAxis dedxBins{"dedxBins", {100, 0, 100}, "Binning for dedx"}; - std::vector centBinningStd = {0., 1., 5., 10., 15., 20., 30., 40., 50., 70., 100.}; - // Histogram names for V0s dE/dx analysis - static constexpr std::string_view DedxvsMomentumPos[ParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; - static constexpr std::string_view DedxvsMomentumNeg[ParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; + ConfigurableAxis dcaBins{"dcaBins", {200, -0.5, 0.5}, "Binning for DCA plots"}; + // ── Custom track-selection object ──────────────────────── + TrackSelection customTrackCuts; + + // ── TF1 pointers for phi cuts ──────────────────────────── + TF1* fphiCutLow = nullptr; + TF1* fphiCutHigh = nullptr; + + // ── Histogram registry ─────────────────────────────────── + HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry registryFrac{"registryFrac", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + // ── Preslice: group tracks by reco collision ────────────── + Preslice perCollision = aod::track::collisionId; + + // FT0 acceptance for TVX-equivalent gen-level selection + static constexpr float MinFT0A = 3.5f; + static constexpr float MaxFT0A = 4.9f; + static constexpr float MinFT0C = -3.3f; + static constexpr float MaxFT0C = -2.1f; + + static constexpr float MinCharge = 3.0f; + static constexpr int CentralityClasses = 10; + + static constexpr int ParticleTypes = 4; + // Response Matrix histogram names static constexpr std::string_view EtavspvspTPosPart[ResponseMatrixTypes] = {"heta_vs_pt_vs_p_all_Pos", "heta_vs_pt_vs_p_all_Pos_Pri", "heta_vs_pt_vs_p_all_Pos_Pri_MC", "heta_vs_pt_vs_p_all_Pos_Pri_MC_Part", "heta_vs_pt_vs_p_Pi_Pos", "heta_vs_pt_vs_p_K_Pos", "heta_vs_pt_vs_p_Pr_Pos"}; static constexpr std::string_view EtavspvspTNegPart[ResponseMatrixTypes] = {"heta_vs_pt_vs_p_all_Neg", "heta_vs_pt_vs_p_all_Neg_Pri", "heta_vs_pt_vs_p_all_Neg_Pri_MC", "heta_vs_pt_vs_p_all_Neg_Pri_MC_Part", "heta_vs_pt_vs_p_Pi_Neg", "heta_vs_pt_vs_p_K_Neg", "heta_vs_pt_vs_p_Pr_Neg"}; - // Particle fractions histograms - static constexpr std::string_view ParticleFractionsVsMomentumPos[ParticlesType + 1] = {"hFractionVsMomentum_Pion_Pos", "hFractionVsMomentum_Kaon_Pos", "hFractionVsMomentum_Proton_Pos", "hFractionVsMomentum_Electron_Pos", "hFractionVsMomentum_Muon_Pos"}; - static constexpr std::string_view ParticleFractionsVsPtPos[ParticlesType + 1] = {"hFractionVsPt_Pion_Pos", "hFractionVsPt_Kaon_Pos", "hFractionVsPt_Proton_Pos", "hFractionVsPt_Electron_Pos", "hFractionVsPt_Muon_Pos"}; - static constexpr std::string_view ParticleFractionsVsMomentumNeg[ParticlesType + 1] = {"hFractionVsMomentum_Pion_Neg", "hFractionVsMomentum_Kaon_Neg", "hFractionVsMomentum_Proton_Neg", "hFractionVsMomentum_Electron_Neg", "hFractionVsMomentum_Muon_Neg"}; + // Event counter bins + enum EvCutLabel { + kAllGen = 1, + kTVXequiv, + kVtxZ, + kINELgt0, + kRecoColl, + kRecoSelected + }; - static constexpr std::string_view ParticleFractionsVsPtNeg[ParticlesType + 1] = {"hFractionVsPt_Pion_Neg", "hFractionVsPt_Kaon_Neg", "hFractionVsPt_Proton_Neg", "hFractionVsPt_Electron_Neg", "hFractionVsPt_Muon_Neg"}; + // Particle species enum + enum ParticleSpecies : int { + kPion = 0, + kKaon = 1, + kProton = 2, + kAllCharged = 3, + kNSpecies = 4 + }; - // Fine binning - static constexpr std::string_view CentpPos[CentralityClasses + 1] = {"p_vs_eta_Cent0_1_Pos", "p_vs_eta_Cent1_5_Pos", "p_vs_eta_Cent5_10_Pos", "p_vs_eta_Cent10_15_Pos", "p_vs_eta_Cent15_20_Pos", "p_vs_eta_Cent20_30_Pos", "p_vs_eta_Cent30_40_Pos", "p_vs_eta_Cent40_50_Pos", "p_vs_eta_Cent50_70_Pos", "p_vs_eta_Cent70_100_Pos", "p_vs_eta_MB_Pos"}; - static constexpr std::string_view CentpNeg[CentralityClasses + 1] = {"p_vs_eta_Cent0_1_Neg", "p_vs_eta_Cent1_5_Neg", "p_vs_eta_Cent5_10_Neg", "p_vs_eta_Cent10_15_Neg", "p_vs_eta_Cent15_20_Neg", "p_vs_eta_Cent20_30_Neg", "p_vs_eta_Cent30_40_Neg", "p_vs_eta_Cent40_50_Neg", "p_vs_eta_Cent50_70_Neg", "p_vs_eta_Cent70_100_Neg", "p_vs_eta_MB_Neg"}; - static constexpr std::string_view CentpTPos[CentralityClasses + 1] = {"pT_vs_eta_Cent0_1_Pos", "pT_vs_eta_Cent1_5_Pos", "pT_vs_eta_Cent5_10_Pos", "pT_vs_eta_Cent10_15_Pos", "pT_vs_eta_Cent15_20_Pos", "pT_vs_eta_Cent20_30_Pos", "pT_vs_eta_Cent30_40_Pos", "pT_vs_eta_Cent40_50_Pos", "pT_vs_eta_Cent50_70_Pos", "pT_vs_eta_Cent70_100_Pos", "pT_vs_eta_MB_Pos"}; - static constexpr std::string_view CentpTNeg[CentralityClasses + 1] = {"pT_vs_eta_Cent0_1_Neg", "pT_vs_eta_Cent1_5_Neg", "pT_vs_eta_Cent5_10_Neg", "pT_vs_eta_Cent10_15_Neg", "pT_vs_eta_Cent15_20_Neg", "pT_vs_eta_Cent20_30_Neg", "pT_vs_eta_Cent30_40_Neg", "pT_vs_eta_Cent40_50_Neg", "pT_vs_eta_Cent50_70_Neg", "pT_vs_eta_Cent70_100_Neg", "pT_vs_eta_MB_Neg"}; + enum INELCutSelection : int { + INEL = 0, + INELgt0 = 1, + INELgt1 = 2 + }; - TrackSelection customTrackCuts; - TF1* fphiCutLow = nullptr; - TF1* fphiCutHigh = nullptr; + void init(InitContext const&) + { + // Setup custom track cuts + if (useCustomTrackCuts.value) { + customTrackCuts = getGlobalTrackSelectionRun3ITSMatch(itsPattern.value); + customTrackCuts.SetRequireITSRefit(requireITS.value); + customTrackCuts.SetRequireTPCRefit(requireTPC.value); + customTrackCuts.SetMinNClustersITS(minITSnClusters.value); + customTrackCuts.SetRequireGoldenChi2(requireGoldenChi2.value); + customTrackCuts.SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC.value); + customTrackCuts.SetMaxChi2PerClusterITS(maxChi2PerClusterITS.value); + customTrackCuts.SetMinNCrossedRowsTPC(minNCrossedRowsTPC.value); + customTrackCuts.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC.value); + customTrackCuts.SetMaxDcaXYPtDep([](float /*pt*/) { return 10000.f; }); + // customTrackCuts.SetMaxDcaZ(maxDcaZ.value); + } - HistogramRegistry ue; + // Initialize phi cut functions if enabled + if (applyPhiCut.value) { + fphiCutLow = new TF1("StandardPhiCutLow", + Form("%f/x/x+pi/18.0-%f", + phiCutLowParam1.value, phiCutLowParam2.value), + 0, 50); + fphiCutHigh = new TF1("StandardPhiCutHigh", + Form("%f/x+pi/18.0+%f", + phiCutHighParam1.value, phiCutHighParam2.value), + 0, 50); + LOGF(info, "Phi cut ENABLED for pT > %.1f GeV/c", pTthresholdPhiCut.value); + } - using CollisionTableData = soa::Join; - using TrackTableData = soa::Join; - using TrackTableMC = soa::Join; - using ParticlesMC = aod::McParticles; - using McCollisions = aod::McCollisions; - using RecoCollisions = aod::Collisions; + // Define axes + AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec dedxAxis = {dedxBins, "dE/dx (a. u.)"}; + AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; + AxisSpec pAxis = {ptBinning, "#it{p} (GeV/#it{c})"}; + AxisSpec pFineAxis{pFineBins, "#it{p} (GeV/c)"}; + AxisSpec pTFineAxis{pFineBins, "#it{p}_{T} (GeV/c)"}; - Preslice perMCCol = aod::mcparticle::mcCollisionId; + const AxisSpec centAxis{centBinningStd, "FT0M Centrality (%)"}; - enum ParticleSpecies : int { - PartPion = 0, - PartKaon = 1, - PartProton = 2, - }; + // Fine centrality binning (100 bins) + std::vector centBinningFine; + for (int i = 0; i <= CentBinMax; i++) { + centBinningFine.push_back(static_cast(i)); + } + const AxisSpec centFineAxis{centBinningFine, "FT0M Centrality (%)"}; + + const AxisSpec nchAxis{nBinsNch.value, 0.f, maxNch.value, + Form("Gen. N_{ch} (|#eta|<%.1f)", tpcNchAcceptance.value)}; + + const AxisSpec npvAxis{nBinsNPV.value, minNpv.value, maxNpv.value, "NPV"}; + const AxisSpec dcaXYAxis{105, -1.05f, 1.05f, "DCA_{xy} (cm)"}; + const AxisSpec zvtxAxis{60, -30.0, 30.0, "Vtx_{z} (cm)"}; + const AxisSpec nclAxis{161, -0.5, 160.5, "N_{cl} TPC"}; + AxisSpec dcaAxis{dcaBins, ""}; + // ======================================================================== + // EVENT COUNTER AND BASIC HISTOGRAMS + // ======================================================================== + registry.add("EventCounter", ";;Events", kTH1F, {{8, 0.5, 8.5}}); + { + auto h = registry.get(HIST("EventCounter")); + h->GetXaxis()->SetBinLabel(kAllGen, "All gen."); + h->GetXaxis()->SetBinLabel(kTVXequiv, "TVX-equiv."); + h->GetXaxis()->SetBinLabel(kVtxZ, "|Zvtx|GetXaxis()->SetBinLabel(kINELgt0, "INEL>0"); + h->GetXaxis()->SetBinLabel(kRecoColl, ">=1 reco coll."); + h->GetXaxis()->SetBinLabel(kRecoSelected, ">=1 reco+sel."); + } + + registry.add("NumberOfRecoCollisions", "Reco collisions per gen. collision;N_{reco};Entries", + kTH1F, {{10, -0.5, 9.5}}); + registry.add("zPosMC", "Gen. Vtx_{z} (evts w/ >=1 reco+sel. coll.);Vtx_{z} (cm);Entries", + kTH1F, {zvtxAxis}); + registry.add("zPosReco", "Reco. Vtx_{z} (selected);Vtx_{z} (cm);Entries", + kTH1F, {zvtxAxis}); + registry.add("T0Ccent", "FT0M centrality (selected);Centrality (%);Entries", + kTH1F, {centAxis}); + registry.add("T0CcentVsFoundFT0", "Found(1.5) NOT Found(0.5);;Status;", kTH2F, {{centAxis, {2, 0, 2}}}); + registry.add("T0CcentVsFoundFT0AndTVX", "Found(1.5) NOT Found(0.5);;Status;", kTH2F, {{centAxis, {2, 0, 2}}}); + registry.add("hvtxZ", "Vertex Z (data);Vertex Z (cm);Events", kTH1F, {{40, -20.0, 20.0}}); + registry.add("hvtxZmc", "MC vertex Z;Vertex Z (cm);Events", kTH1F, {{40, -20.0, 20.0}}); + + // ======================================================================== + // CENTRALITY DIAGNOSTIC HISTOGRAMS + // ======================================================================== + registry.add("Centrality/hCentRaw", "Raw FT0M Centrality (no cuts);Centrality (%);Counts", + kTH1D, {centFineAxis}); + registry.add("Centrality/hCentAfterVtx", "Centrality after vertex cut;Centrality (%);Counts", + kTH1D, {centFineAxis}); + registry.add("Centrality/hCentAfterINEL", "Centrality after INEL cut;Centrality (%);Counts", + kTH1D, {centFineAxis}); + registry.add("Centrality/hCentAfterAll", "Centrality after all cuts;Centrality (%);Counts", + kTH1D, {centFineAxis}); + registry.add("Centrality/hCentVsMult", "Centrality vs Generated Multiplicity;Centrality (%);N_{ch}^{gen}", + kTH2D, {centFineAxis, nchAxis}); + registry.add("Centrality/hMultVsCent", "Generated Multiplicity vs Centrality;N_{ch}^{gen};Centrality (%)", + kTH2D, {nchAxis, centFineAxis}); + registry.add("Centrality/hCentVsVz", "Centrality vs Vertex Z;Centrality (%);V_{z} (cm)", + kTH2D, {centFineAxis, {40, -20, 20}}); + registry.add("Centrality/hRecoMultVsCent", "Reconstructed Track Multiplicity vs Centrality;Centrality (%);N_{tracks}^{reco}", + kTH2D, {centFineAxis, {100, 0, 100}}); + registry.add("Centrality/hVertexResVsCent", "Vertex Resolution vs Centrality;Centrality (%);V_{z} resolution (cm)", + kTH2D, {centFineAxis, {100, -1, 1}}); + registry.add("NchVsNPV", ";Nch; NPV;", kTH2D, {{npvAxis, nchAxis}}); + registry.add("ExcludedEvtVsNch", ";Nch;Entries;", kTH1F, {nchAxis}); + registry.add("ExcludedEvtVsNPV", ";NPV;Entries;", kTH1F, {npvAxis}); + + // ======================================================================== + // INEL CLASS HISTOGRAMS + // ======================================================================== + registry.add("INEL/hINELClass", "INEL Class for MC Collisions;INEL Class;Counts", + kTH1D, {{3, 0.5, 3.5}}); + auto hINEL = registry.get(HIST("INEL/hINELClass")); + hINEL->GetXaxis()->SetBinLabel(1, "INEL0"); + hINEL->GetXaxis()->SetBinLabel(2, "INEL>0"); + hINEL->GetXaxis()->SetBinLabel(3, "INEL>1"); + registry.add("INEL/hINELVsCent", "INEL Class vs Centrality;Centrality (%);INEL Class", + kTH2D, {centFineAxis, {3, 0.5, 3.5}}); + + // ======================================================================== + // CUT FLOW HISTOGRAMS + // ======================================================================== + registry.add("CutFlow/hCutStats", "Cut Statistics;Cut Stage;Counts", + kTH1D, {{6, 0.5, 6.5}}); + auto hCut = registry.get(HIST("CutFlow/hCutStats")); + hCut->GetXaxis()->SetBinLabel(1, "All reco events"); + hCut->GetXaxis()->SetBinLabel(2, "Has MC match"); + hCut->GetXaxis()->SetBinLabel(3, "Has centrality"); + hCut->GetXaxis()->SetBinLabel(4, "Pass vertex"); + hCut->GetXaxis()->SetBinLabel(5, "Pass INEL"); + hCut->GetXaxis()->SetBinLabel(6, "Selected"); + registry.add("CutFlow/hCentPerCut", "Centrality Distribution at Each Cut;Cut Stage;Centrality (%)", + kTH2D, {{6, 0.5, 6.5}, centFineAxis}); + registry.add("evsel", "Event selection", HistType::kTH1D, {{20, 0.5, 20.5}}); + auto hEvSel = registry.get(HIST("evsel")); + for (int i = 1; i <= NEvLabel; i++) { + hEvSel->GetXaxis()->SetBinLabel(i, Form("Step %d", i)); + } + + // ======================================================================== + // MC COLLISION HISTOGRAMS + // ======================================================================== + registry.add("MC/GenRecoCollisions", "Generated and Reconstructed MC Collisions", + kTH1D, {{10, 0.5, 10.5}}); + auto hColl = registry.get(HIST("MC/GenRecoCollisions")); + hColl->GetXaxis()->SetBinLabel(1, "Collisions generated"); + hColl->GetXaxis()->SetBinLabel(2, "Collisions reconstructed"); + hColl->GetXaxis()->SetBinLabel(3, "INEL>0"); + hColl->GetXaxis()->SetBinLabel(4, "INEL>1"); + registry.add("NchMCcentVsTVX", ";Passed(1.5) NOT Passed(0.5);", kTH2F, {{nchAxis, {2, 0, 2}}}); + registry.add("Centrality_AllRecoEvt", "Generated Events Irrespective of number of reconstructions;Centrality;Entries", kTH1F, {centAxis}); + registry.add("Centrality_WRecoEvt", "Generated Events With at least One Rec. Collision;Centrality;Entries", kTH1F, {centAxis}); + registry.add("Centrality_WRecoEvtWSelCri", "Generated Events With at least One Rec. Collision + Sel. criteria;Centrality;Entries", kTH1F, {centAxis}); + + // ======================================================================== + // 2D and 3D CORRELATION HISTOGRAMS + // ======================================================================== + registry.add("NchMCVsCent", "Gen. N_{ch} vs FT0M centrality (reco+sel. evts);FT0M Centrality (%);Gen. N_{ch}", + kTH2F, {{centAxis, nchAxis}}); + registry.add("NchMCVsCentVsPt", "pT vs Gen. N_{ch} vs FT0M centrality;FT0M Centrality (%);Gen. N_{ch};#it{p}_{T}", + kTH3F, {{centAxis, nchAxis, ptAxis}}); + registry.add("hEta", "Track eta;#eta;Counts", kTH1D, {{20, -0.8, 0.8}}); + registry.add("hPhi", "Track phi;#varphi (rad);Counts", kTH1D, {{64, 0, o2::constants::math::TwoPI}}); + registry.add("EtaVsPhi", ";#eta;#varphi;", kTH2F, {{50, -1.0, 1.0}, {100, 0, o2::constants::math::TwoPI}}); + + // ======================================================================== + // EVENT LOSS HISTOGRAMS + // ======================================================================== + registry.add("NchMC_AllGen", "EVENT LOSS denom.;Gen. N_{ch};Entries", kTH1F, {nchAxis}); + registry.add("NchMC_WithRecoEvt", "EVENT LOSS numer.;Gen. N_{ch};Entries", kTH1F, {nchAxis}); + registry.add("MC/EventLoss/NchGenerated", "Generated charged multiplicity;N_{ch}^{gen};Counts", kTH1D, {nchAxis}); + registry.add("MC/EventLoss/NchGenerated_PhysicsSelected", "Generated charged multiplicity (physics selected);N_{ch}^{gen};Counts", kTH1D, {nchAxis}); + registry.add("MC/EventLoss/NchGenerated_Reconstructed", "Generated charged multiplicity (reconstructed);N_{ch}^{gen};Counts", kTH1D, {nchAxis}); + registry.add("MC/EventLoss/GenMultVsCent", "Generated charged particles vs FT0M centrality;FT0M Centrality (%);N_{ch}^{gen}", kTH2D, {centAxis, nchAxis}); + registry.add("MC/EventLoss/GenMultVsCent_Selected", "Generated vs FT0M centrality (selected);FT0M Centrality (%);N_{ch}^{gen}", kTH2D, {centAxis, nchAxis}); + registry.add("MC/EventLoss/GenMultVsCent_Rejected", "Generated vs FT0M centrality (rejected);FT0M Centrality (%);N_{ch}^{gen}", kTH2D, {centAxis, nchAxis}); + registry.add("hEventLossBreakdown", "Event loss breakdown", kTH1D, {{4, 0.5, 4.5}}); + auto hLoss = registry.get(HIST("hEventLossBreakdown")); + hLoss->GetXaxis()->SetBinLabel(1, "Physics selected"); + hLoss->GetXaxis()->SetBinLabel(2, "Reconstructed"); + hLoss->GetXaxis()->SetBinLabel(3, "Selected"); + hLoss->GetXaxis()->SetBinLabel(4, "Final efficiency"); + + // ======================================================================== + // SIGNAL LOSS HISTOGRAMS + // ======================================================================== + const std::vector speciesNames = {"Pi", "Ka", "Pr", "All"}; + for (int i = 0; i < ParticleTypes; ++i) { + const std::string& name = speciesNames[i]; + registry.add(Form("Pt%sVsNchMC_AllGen", name.c_str()), + Form("SIGNAL LOSS denom. (%s): all gen. evts.;#it{p}_{T};Gen. N_{ch}", name.c_str()), + kTH2F, {{ptAxis, nchAxis}}); + registry.add(Form("Pt%sVsNchMC_WithRecoEvt", name.c_str()), + Form("SIGNAL LOSS numer. (%s): gen. evts. w/ >=1 reco+sel.;#it{p}_{T};Gen. N_{ch}", name.c_str()), + kTH2F, {{ptAxis, nchAxis}}); + } + + // ======================================================================== + // TRACKING EFFICIENCY HISTOGRAMS + // ======================================================================== + for (int i = 0; i < ParticleTypes; ++i) { + const std::string& name = speciesNames[i]; + registry.add(Form("Pt%sVsCentMC_WithRecoEvt", name.c_str()), + Form("EFF denom. (%s): gen pT in reco+sel. evts.;#it{p}_{T}^{gen};FT0M Cent. (%s)", name.c_str(), ")"), + kTH2F, {{ptAxis, centAxis}}); + registry.add(Form("Pt%sVsCent_WithRecoEvt", name.c_str()), + Form("EFF numer. (%s): reco primaries (gen pT);#it{p}_{T}^{gen};FT0M Cent. (%s)", name.c_str(), ")"), + kTH2F, {{ptAxis, centAxis}}); + registry.add(Form("PtGen%sVsNchMC_WithRecoEvt", name.c_str()), + Form("EFF denom. (%s) vs gen Nch;#it{p}_{T}^{gen};Gen. N_{ch}", name.c_str()), + kTH2F, {{ptAxis, nchAxis}}); + registry.add(Form("PtGen%sVsNchMC_RecoTrk", name.c_str()), + Form("EFF numer. (%s) vs gen Nch;#it{p}_{T}^{gen};Gen. N_{ch}", name.c_str()), + kTH2F, {{ptAxis, nchAxis}}); + } + + // ======================================================================== + // MC CLOSURE HISTOGRAMS + // ======================================================================== + registry.add("MCclosure_PtMCPiVsNchMC", "MC closure Pi (gen);#it{p}_{T}^{gen};Gen. N_{ch}", kTH2F, {{ptAxis, nchAxis}}); + registry.add("MCclosure_PtMCKaVsNchMC", "MC closure Ka (gen);#it{p}_{T}^{gen};Gen. N_{ch}", kTH2F, {{ptAxis, nchAxis}}); + registry.add("MCclosure_PtMCPrVsNchMC", "MC closure Pr (gen);#it{p}_{T}^{gen};Gen. N_{ch}", kTH2F, {{ptAxis, nchAxis}}); + registry.add("MCclosure_PtPiVsNchMC", "MC closure Pi (reco);#it{p}_{T}^{reco};Gen. N_{ch}", kTH2F, {{ptAxis, nchAxis}}); + registry.add("MCclosure_PtKaVsNchMC", "MC closure Ka (reco);#it{p}_{T}^{reco};Gen. N_{ch}", kTH2F, {{ptAxis, nchAxis}}); + registry.add("MCclosure_PtPrVsNchMC", "MC closure Pr (reco);#it{p}_{T}^{reco};Gen. N_{ch}", kTH2F, {{ptAxis, nchAxis}}); + registry.add("MC/GenPtVsNch", "Generated pT vs Multiplicity;#it{p}_{T};N_{ch}^{gen}", kTH2D, {ptAxis, nchAxis}); + registry.add("MC/GenPtVsNch_PhysicsSelected", "Generated pT vs Multiplicity (physics selected);#it{p}_{T};N_{ch}^{gen}", kTH2D, {ptAxis, nchAxis}); + + // ======================================================================== + // DCA HISTOGRAMS FOR PRIMARY FRACTION + // ======================================================================== + registry.add("dcaVsPtPi", "PRIMARY FRAC. (Pi) - primaries;#it{p}_{T};DCA_{xy};FT0M Cent.", + kTH3F, {{ptAxis, dcaXYAxis, centAxis}}); + registry.add("dcaVsPtPr", "PRIMARY FRAC. (Pr) - primaries;#it{p}_{T};DCA_{xy};FT0M Cent.", + kTH3F, {{ptAxis, dcaXYAxis, centAxis}}); + registry.add("dcaVsPtPiDec", "PRIMARY FRAC. (Pi) - sec. from decays;#it{p}_{T};DCA_{xy};FT0M Cent.", + kTH3F, {{ptAxis, dcaXYAxis, centAxis}}); + registry.add("dcaVsPtPrDec", "PRIMARY FRAC. (Pr) - sec. from decays;#it{p}_{T};DCA_{xy};FT0M Cent.", + kTH3F, {{ptAxis, dcaXYAxis, centAxis}}); + registry.add("dcaVsPtPiMat", "PRIMARY FRAC. (Pi) - sec. from material;#it{p}_{T};DCA_{xy};FT0M Cent.", + kTH3F, {{ptAxis, dcaXYAxis, centAxis}}); + registry.add("dcaVsPtPrMat", "PRIMARY FRAC. (Pr) - sec. from material;#it{p}_{T};DCA_{xy};FT0M Cent.", + kTH3F, {{ptAxis, dcaXYAxis, centAxis}}); + + // ======================================================================== + // MEASURED SPECTRA + // ======================================================================== + for (int i = 0; i < ParticleTypes; ++i) { + const std::string& name = speciesNames[i]; + registry.add(Form("Pt%sMeasuredVsCent", name.c_str()), + Form("Measured %s (PID);#it{p}_{T};FT0M Centrality (%s)", name.c_str(), ")"), + kTH2F, {{ptAxis, centAxis}}); + registry.add(Form("Pt%sMeasuredVsNch", name.c_str()), + Form("Measured %s (PID) vs gen Nch;#it{p}_{T};Gen. N_{ch}", name.c_str()), + kTH2F, {{ptAxis, nchAxis}}); + } + + // ======================================================================== + // TPC CLUSTER HISTOGRAMS + // ======================================================================== + registry.add("hNclFoundTPC", "Number of TPC found clusters;N_{cl, found};Counts", kTH1D, {nclAxis}); + registry.add("hNclPIDTPC", "Number of TPC PID clusters;N_{cl, PID};Counts", kTH1D, {nclAxis}); + registry.add("hNclFoundTPCvsPt", "TPC found clusters vs pT;#it{p}_{T};N_{cl,found}", kTH2D, {ptAxis, nclAxis}); + registry.add("hNclPIDTPCvsPt", "TPC PID clusters vs pT;#it{p}_{T};N_{cl,PID}", kTH2D, {ptAxis, nclAxis}); + + // ======================================================================== + // INCLUSIVE HISTOGRAMS + // ======================================================================== + registry.add("Inclusive/hPtPrimGenAll", "All generated primaries (no cuts);#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtPrimBadVertex", "Generated primaries (bad vertex);#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtPrimGen", "Generated primaries (after physics selection);#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtPrimRecoEv", "Generated primaries (reco events);#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtPrimGoodEv", "Generated primaries (good events);#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtNumEff", "Tracking efficiency numerator;#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtDenEff", "Tracking efficiency denominator;#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtAllReco", "All reconstructed tracks;#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtPrimReco", "Reconstructed primaries;#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtSecReco", "Reconstructed secondaries;#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtMeasured", "All measured tracks;#it{p}_{T};Counts", kTH1D, {ptAxis}); + registry.add("Inclusive/hPtMeasuredVsCent", "All measured tracks (PID) vs centrality;#it{p}_{T};FT0M Centrality (%s)", kTH2D, {ptAxis, centAxis}); + registry.add("Inclusive/hPtMeasuredVsMult", "All measured tracks vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + + // Inclusive vs Multiplicity + registry.add("Inclusive/hPtPrimGenAllVsMult", "All generated primaries vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtPrimBadVertexVsMult", "Generated primaries (bad vertex) vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtPrimGenVsMult", "Generated primaries (after phys sel) vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtPrimRecoEvVsMult", "Generated primaries (reco events) vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtPrimGoodEvVsMult", "Generated primaries (good events) vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtNumEffVsMult", "Tracking efficiency numerator vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtDenEffVsMult", "Tracking efficiency denominator vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtAllRecoVsMult", "All reconstructed tracks vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtPrimRecoVsMult", "Reconstructed primaries vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + registry.add("Inclusive/hPtSecRecoVsMult", "Reconstructed secondaries vs mult;#it{p}_{T};Mult Class (%)", kTH2D, {ptAxis, nchAxis}); + + // ======================================================================== + // PER-SPECIES INCLUSIVE HISTOGRAMS + // ======================================================================== + const std::array particleNames = {"Pion", "Kaon", "Proton"}; + const std::array particleSymbols = {"#pi^{#pm}", "K^{#pm}", "p+#bar{p}"}; + + for (int iSpecies = 0; iSpecies < ParticleTypes - 1; ++iSpecies) { + const auto& name = particleNames[iSpecies]; + const auto& symbol = particleSymbols[iSpecies]; + + registry.add(Form("%s/hPtPrimGenAll", name.c_str()), + Form("All generated %s (no cuts);#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtPrimBadVertex", name.c_str()), + Form("Generated %s (bad vertex);#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtPrimGen", name.c_str()), + Form("Generated %s (after physics selection);#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtPrimRecoEv", name.c_str()), + Form("Generated %s (reco events);#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtPrimGoodEv", name.c_str()), + Form("Generated %s (good events);#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtNumEff", name.c_str()), + Form("%s tracking efficiency numerator;#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtDenEff", name.c_str()), + Form("%s tracking efficiency denominator;#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtAllReco", name.c_str()), + Form("All reconstructed %s;#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtPrimReco", name.c_str()), + Form("Reconstructed primary %s;#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtSecReco", name.c_str()), + Form("Reconstructed secondary %s;#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + registry.add(Form("%s/hPtMeasured", name.c_str()), + Form("Measured %s;#it{p}_{T};Counts", symbol.c_str()), kTH1D, {ptAxis}); + + // Per-species vs multiplicity + registry.add(Form("%s/hPtPrimGenAllVsMult", name.c_str()), + Form("All generated %s vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtPrimBadVertexVsMult", name.c_str()), + Form("Generated %s (bad vertex) vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtPrimGenVsMult", name.c_str()), + Form("Generated %s (after phys sel) vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtPrimRecoEvVsMult", name.c_str()), + Form("Generated %s (reco events) vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtPrimGoodEvVsMult", name.c_str()), + Form("Generated %s (good events) vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtNumEffVsMult", name.c_str()), + Form("%s tracking eff numerator vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtDenEffVsMult", name.c_str()), + Form("%s tracking eff denominator vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtAllRecoVsMult", name.c_str()), + Form("All reconstructed %s vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtPrimRecoVsMult", name.c_str()), + Form("Reconstructed primary %s vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtSecRecoVsMult", name.c_str()), + Form("Reconstructed secondary %s vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + registry.add(Form("%s/hPtMeasuredVsMult", name.c_str()), + Form("Measured %s vs mult;#it{p}_{T};Mult Class (%s)", symbol.c_str(), ")"), kTH2D, {ptAxis, nchAxis}); + } + + // ======================================================================== + // PID HISTOGRAMS + // ======================================================================== + registry.add("PtResolution", "pT resolution;#it{p}_{T}^{gen};(p_{T}^{reco}-p_{T}^{gen})/p_{T}^{gen}", + kTH2F, {{ptAxis, {100, -1.0, 1.0}}}); + + if (enablePIDHistograms) { + registry.add("Pion/hNsigmaTPC", "Pion TPC n#sigma;#it{p}_{T};n#sigma_{TPC}", + kTH2D, {{ptAxis, {200, -10, 10}}}); + registry.add("Kaon/hNsigmaTPC", "Kaon TPC n#sigma;#it{p}_{T};n#sigma_{TPC}", + kTH2D, {{ptAxis, {200, -10, 10}}}); + registry.add("Proton/hNsigmaTPC", "Proton TPC n#sigma;#it{p}_{T};n#sigma_{TPC}", + kTH2D, {{ptAxis, {200, -10, 10}}}); + } + + // ======================================================================== + // PHI CUT MONITORING + // ======================================================================== + if (applyPhiCut.value) { + registry.add("PhiCut/hPtVsPhiPrimeBefore", "pT vs #phi' before cut;p_{T};#phi'", + kTH2F, {{100, 0, 10}, {100, 0, 0.4}}); + registry.add("PhiCut/hPtVsPhiPrimeAfter", "pT vs #phi' after cut;p_{T};#phi'", + kTH2F, {{100, 0, 10}, {100, 0, 0.4}}); + } + // ======================================================================== + // DCA CUT MONITORING + // ======================================================================== + + registry.add("hDCAxyVsPt_before", "DCAxy vs pT before cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", + HistType::kTH2F, {{ptAxis}, {dcaAxis}}); + registry.add("hDCAzVsPt_before", "DCAz vs pT before cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", + HistType::kTH2F, {{ptAxis}, {dcaAxis}}); + registry.add("hDCAxyVsPt_after", "DCAxy vs pT after cut;#it{p}_{T} (GeV/c);DCA_{xy} (cm)", + HistType::kTH2F, {{ptAxis}, {dcaAxis}}); + registry.add("hDCAzVsPt_after", "DCAz vs pT after cut;#it{p}_{T} (GeV/c);DCA_{z} (cm)", + HistType::kTH2F, {{ptAxis}, {dcaAxis}}); + + // ======================================================================== + // CALIBRATION HISTOGRAMS + // ======================================================================== + registry.add("Calibration/hRawMultiplicity", "Raw multiplicity distribution;N_{ch};Events", + kTH1D, {{150, 0, 150}}); + + // ======================================================================== + // DEDX VS MOMENTUM HISTOGRAMS + // ======================================================================== + const std::array centNames = { + "Cent0_1", "Cent1_5", "Cent5_10", "Cent10_15", "Cent15_20", + "Cent20_30", "Cent30_40", "Cent40_50", "Cent50_70", "Cent70_100", "MB"}; + const std::array v0Names = { + "all", "Pi_v0", "Pr_v0", "El_v0"}; + for (int i = 0; i < ParticleTypes; ++i) { + const auto& part = v0Names[i]; + registry.add(Form("DedxVsMomentum/dEdx_vs_Momentum_%s_Pos", part.c_str()), + "dE/dx vs Momentum Positive", kTH3F, {{pAxis}, {dedxAxis}, {etaAxis}}); + registry.add(Form("DedxVsMomentum/dEdx_vs_Momentum_%s_Neg", part.c_str()), + "dE/dx vs Momentum Negative", kTH3F, {{pAxis}, {dedxAxis}, {etaAxis}}); + } + for (int i = 0; i < CentralityClasses; ++i) { + const auto& cent = centNames[i]; + hDedxVsMomentumVsCentPos[i] = registry.add(Form("DedxVsMomentum/dEdx_vs_Momentum_%s_Pos", cent.c_str()), "dE/dx vs Momentum Positive", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); + hDedxVsMomentumVsCentNeg[i] = registry.add(Form("DedxVsMomentum/dEdx_vs_Momentum_%s_Neg", cent.c_str()), "dE/dx vs Momentum Negative", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); + } + for (int i = 0; i < CentralityClasses + 1; ++i) { + const auto& cent = centNames[i]; + hDedxVspTMomentumVsCent[i] = registry.add(Form("DedxVsMomentum/dEdx_vs_pT_%s", cent.c_str()), "dE/dx vs pT", HistType::kTH3F, {{ptAxis}, {dedxAxis}, {etaAxis}}); + } + // ======================================================================== + // RESPONSE MATRIX HISTOGRAMS + // ======================================================================== + for (int i = 0; i < ResponseMatrixTypes; ++i) { + registry.add(("ResponseMatrix/" + std::string(EtavspvspTPosPart[i])).c_str(), + "eta vs pT vs p Positive", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); + registry.add(("ResponseMatrix/" + std::string(EtavspvspTNegPart[i])).c_str(), + "eta vs pT vs p Negative", HistType::kTH3F, + {{etaAxis}, {ptAxis}, {pAxis}}); + } + // ======================================================================== + // FINNER BINNING HISTOGRAMS + // ======================================================================== + for (int i = 0; i < CentralityClasses + 1; ++i) { + const auto& cent = centNames[i]; + hMomentumVsEtaPos[i] = registry.add(Form("Binning/p_vs_eta_%s_Pos", cent.c_str()), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); + hMomentumVsEtaNeg[i] = registry.add(Form("Binning/p_vs_eta_%s_Neg", cent.c_str()), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); + hpTVsEtaPos[i] = registry.add(Form("Binning/pT_vs_eta_%s_Pos", cent.c_str()), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); + hpTVsEtaNeg[i] = registry.add(Form("Binning/pT_vs_eta_%s_Neg", cent.c_str()), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); + } + + // ======================================================================== + // PARTICLE FRACTIONS HISTOGRAMS + // ======================================================================== + const std::array partName = {"Pion", "Kaon", "Proton", "Electron", "Muon"}; + for (int ic = 0; ic < NCentHists + 1; ++ic) { + const auto& cent = centNames[ic]; + hTotalMomPosCent[ic] = registryFrac.add( + Form("ParticleFractions/hTotalCountsVsMomentumPos_%s", cent.c_str()), + "Total counts vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); + hTotalMomNegCent[ic] = registryFrac.add( + Form("ParticleFractions/hTotalCountsVsMomentumNeg_%s", cent.c_str()), + "Total counts vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); + hTotalPtPosCent[ic] = registryFrac.add( + Form("ParticleFractions/hTotalCountsVsPtPos_%s", cent.c_str()), + "Total counts vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); + hTotalPtNegCent[ic] = registryFrac.add( + Form("ParticleFractions/hTotalCountsVsPtNeg_%s", cent.c_str()), + "Total counts vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); + + for (int ip = 0; ip < NPartHists; ++ip) { + const auto& part = partName[ip]; + hFracMomPosCent[ip][ic] = registryFrac.add( + Form("ParticleFractions/hFractionVsMomentum_%s_Pos_%s", part.c_str(), cent.c_str()), + "Fraction vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); + hFracMomNegCent[ip][ic] = registryFrac.add( + Form("ParticleFractions/hFractionVsMomentum_%s_Neg_%s", part.c_str(), cent.c_str()), + "Fraction vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); + hFracPtPosCent[ip][ic] = registryFrac.add( + Form("ParticleFractions/hFractionVsPt_%s_Pos_%s", part.c_str(), cent.c_str()), + "Fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); + hFracPtNegCent[ip][ic] = registryFrac.add( + Form("ParticleFractions/hFractionVsPt_%s_Neg_%s", part.c_str(), cent.c_str()), + "Fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); + } + } + + LOG(info) << "=== MultiplicityPt initialized with ALL histograms (including dE/dx) ==="; + LOG(info) << "tpcNchAcceptance = " << tpcNchAcceptance.value; + LOG(info) << "cfgINELCut = " << cfgINELCut.value; + LOG(info) << "selTVXMC = " << selTVXMC.value; + LOG(info) << "applyPhiCut = " << applyPhiCut.value; + // LOG(info) << "maxDcaZ = " << maxDcaZ.value; + } + // Get magnetic field from CCDB int getMagneticField(uint64_t timestamp) { static o2::parameters::GRPMagField* grpo = nullptr; @@ -172,941 +742,835 @@ struct MultiplicityPt { LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); return 0; } - LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); } return grpo->getNominalL3Field(); } + // Transform phi for phi cut float getTransformedPhi(const float phi, const int charge, const float magField) const { float transformedPhi = phi; - if (magField < 0) + if (magField < 0) { transformedPhi = o2::constants::math::TwoPI - transformedPhi; - if (charge < 0) + } + if (charge < 0) { transformedPhi = o2::constants::math::TwoPI - transformedPhi; + } transformedPhi += o2::constants::math::PI / 18.0f; transformedPhi = std::fmod(transformedPhi, o2::constants::math::PI / 9.0f); return transformedPhi; } - template - bool passedPhiCut(const TrackType& track, float magField) const + // Check phi cut + template + bool passedPhiCut(const T& track, float magField) const { if (!applyPhiCut.value) return true; if (track.pt() < pTthresholdPhiCut.value) return true; - float phi = track.phi(); - int charge = track.sign(); - - if (magField < 0) - phi = o2::constants::math::TwoPI - phi; - if (charge < 0) - phi = o2::constants::math::TwoPI - phi; - phi += o2::constants::math::PI / 18.0f; - phi = std::fmod(phi, o2::constants::math::PI / 9.0f); + float phiPrime = getTransformedPhi(track.phi(), track.sign(), magField); - if (phi < fphiCutHigh->Eval(track.pt()) && phi > fphiCutLow->Eval(track.pt())) + if (phiPrime < fphiCutHigh->Eval(track.pt()) && phiPrime > fphiCutLow->Eval(track.pt())) { return false; - return true; - } - - template - int countGeneratedChargedPrimaries(const ParticleContainer& particles, float etaMax, float ptMin) const - { - int count = 0; - for (const auto& particle : particles) { - auto pdgParticle = pdg->GetParticle(particle.pdgCode()); - if (!pdgParticle || pdgParticle->Charge() == 0.) - continue; - if (!particle.isPhysicalPrimary()) - continue; - if (std::abs(particle.eta()) > etaMax) - continue; - if (particle.pt() < ptMin) - continue; - count++; } - return count; - } - - template - bool passedNClTPCFoundCut(const T& trk) const - { - return !nClTPCFoundCut.value || trk.tpcNClsFound() >= minTPCNClsFound.value; + return true; } template - bool passedNClTPCPIDCut(const T& trk) const + bool passesTrackSelectionNoDCA(const T& track) const { - return !nClTPCPIDCut.value || trk.tpcNClsPID() >= minTPCNClsPID.value; - } + if (track.eta() < cfgCutEtaMin.value || track.eta() > cfgCutEtaMax.value) + return false; + if (track.pt() < cfgTrkLowPtCut.value) + return false; + if (track.tpcChi2NCl() < minChi2PerClusterTPC.value || track.tpcChi2NCl() > maxChi2PerClusterTPC.value) + return false; - template - bool passesCutWoDCA(TrackType const& track) const - { if (useCustomTrackCuts.value) { for (int i = 0; i < static_cast(TrackSelection::TrackCuts::kNCuts); i++) { - if (i == static_cast(TrackSelection::TrackCuts::kDCAxy) || - i == static_cast(TrackSelection::TrackCuts::kDCAz)) + if (i == static_cast(TrackSelection::TrackCuts::kDCAxy)) continue; if (!customTrackCuts.IsSelected(track, static_cast(i))) return false; } - return true; - } - return track.isGlobalTrackWoDCA(); - } - - template - bool passesDCAxyCut(TrackType const& track) const - { - if (useCustomTrackCuts.value) { - if (!passesCutWoDCA(track)) + } else { + if (!track.isGlobalTrackWoDCA()) return false; - constexpr float DcaXYConst = 0.0105f; - constexpr float DcaXYPtScale = 0.0350f; - constexpr float DcaXYPtPower = 1.1f; - const float maxDcaXY = maxDcaXYFactor.value * (DcaXYConst + DcaXYPtScale / std::pow(track.pt(), DcaXYPtPower)); - return std::abs(track.dcaXY()) <= maxDcaXY; } - return track.isGlobalTrack(); - } - template - bool passesTrackSelection(TrackType const& track, float magField = 0) const - { - if (track.eta() < cfgCutEtaMin.value || track.eta() > cfgCutEtaMax.value) - return false; - if (track.tpcChi2NCl() < minChi2PerClusterTPC.value || track.tpcChi2NCl() > maxChi2PerClusterTPC.value) - return false; - if (!passesCutWoDCA(track)) - return false; - if (!passesDCAxyCut(track)) + if (nClTPCFoundCut.value && track.tpcNClsFound() < minTPCNClsFound.value) return false; - if (!passedNClTPCFoundCut(track)) - return false; - if (!passedNClTPCPIDCut(track)) - return false; - if (!passedPhiCut(track, magField)) + if (nClTPCPIDCut.value && track.tpcNClsPID() < minTPCNClsPID.value) return false; + return true; } - template - bool passesPIDSelection(const TrackType& track, int species) const + // DCA xy cut + template + bool passesDCAxyCut(const T1& track) const { - float nsigmaTPC = 0.f; - float cutValue = 0.f; - - if (species == PartPion) { - nsigmaTPC = track.tpcNSigmaPi(); - cutValue = cfgCutNsigmaPi.value; - } else if (species == PartKaon) { - nsigmaTPC = track.tpcNSigmaKa(); - cutValue = cfgCutNsigmaKa.value; - } else if (species == PartProton) { - nsigmaTPC = track.tpcNSigmaPr(); - cutValue = cfgCutNsigmaPr.value; - } + const float maxDcaXY = nSigmaDCAxy.value * (dcaXYp0.value + dcaXYp1.value / std::pow(track.pt(), dcaXYp2.value)) / 3.0; + return std::abs(track.dcaXY()) < maxDcaXY; + } + // DCA z cut + template + bool passesDCAzCut(const T1& track) const + { + const float maxiDcaZ = nSigmaDCAz.value * (dcaZp0.value + dcaZp1.value / std::pow(track.pt(), dcaZp2.value)) / 3.0; + return std::abs(track.dcaZ()) < maxiDcaZ; + } - return std::abs(nsigmaTPC) < cutValue; + // Full track selection + template + bool passesTrackSelection(const T& track) const + { + return passesTrackSelectionNoDCA(track) && passesDCAxyCut(track) && passesDCAzCut(track); } - template - bool isGoodPrimary(ParticleType const& particle) const + template + bool isEventSelected(const C& col) const { - auto pdgParticle = pdg->GetParticle(particle.pdgCode()); - if (!pdgParticle || pdgParticle->Charge() == 0.) + if (askForCustomTVX.value) { + if (!col.selection_bit(aod::evsel::kIsTriggerTVX)) + return false; + } else { + if (!col.sel8()) + return false; + } + if (removeITSROFrameBorder.value && !col.selection_bit(aod::evsel::kNoITSROFrameBorder)) + return false; + if (removeNoSameBunchPileup.value && !col.selection_bit(aod::evsel::kNoSameBunchPileup)) + return false; + if (requireIsGoodZvtxFT0vsPV.value && !col.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) return false; - if (!particle.isPhysicalPrimary()) + if (requireIsVertexITSTPC.value && !col.selection_bit(aod::evsel::kIsVertexITSTPC)) return false; - if (std::abs(particle.eta()) >= cfgCutEtaMax.value) + if (removeNoTimeFrameBorder.value && !col.selection_bit(aod::evsel::kNoTimeFrameBorder)) return false; - if (particle.pt() < cfgTrkLowPtCut.value) + if (std::abs(col.posZ()) > cfgCutVertex.value) return false; return true; } - void processData(CollisionTableData::iterator const& collision, TrackTableData const& tracks, BCsRun3 const& bcs); - PROCESS_SWITCH(MultiplicityPt, processData, "process data", false); - - void processMC(TrackTableMC const& tracks, aod::McParticles const& particles, aod::McCollisions const& mcCollisions, - RecoCollisions const& collisions, aod::McCollisionLabels const& labels, aod::McCentFT0Ms const& centTable, BCsRun3 const& bcs); - PROCESS_SWITCH(MultiplicityPt, processMC, "process MC", true); - - void init(InitContext const&); - void endOfStream(EndOfStreamContext& /*eos*/) {} -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} - -void MultiplicityPt::init(InitContext const&) -{ - LOG(info) << "=================================================="; - LOG(info) << "Initializing MultiplicityPt task - FULL CORRECTION FACTORS"; - LOG(info) << "=================================================="; - - if (applyPhiCut.value) { - fphiCutLow = new TF1("StandardPhiCutLow", Form("%f/x/x+pi/18.0-%f", phiCutLowParam1.value, phiCutLowParam2.value), 0, 50); - fphiCutHigh = new TF1("StandardPhiCutHigh", Form("%f/x+pi/18.0+%f", phiCutHighParam1.value, phiCutHighParam2.value), 0, 50); + template + bool isEventSelectedMC(const C& col) const + { + if (std::abs(col.posZ()) > cfgCutVertex.value) + return false; + return true; } - if (useCustomTrackCuts.value) { - customTrackCuts = getGlobalTrackSelectionRun3ITSMatch(itsPattern.value); - customTrackCuts.SetRequireITSRefit(requireITS.value); - customTrackCuts.SetRequireTPCRefit(requireTPC.value); - customTrackCuts.SetRequireGoldenChi2(requireGoldenChi2.value); - customTrackCuts.SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC.value); - customTrackCuts.SetMaxChi2PerClusterITS(maxChi2PerClusterITS.value); - customTrackCuts.SetMinNCrossedRowsTPC(minNCrossedRowsTPC.value); - customTrackCuts.SetMinNClustersTPC(minTPCNClsFound.value); - customTrackCuts.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC.value); - customTrackCuts.SetMaxDcaXYPtDep([](float /*pt*/) { return 10000.f; }); - customTrackCuts.SetMaxDcaZ(maxDcaZ.value); - customTrackCuts.print(); + template + int bestPIDHypothesis(const T& track) const + { + const float nsPi = std::abs(track.tpcNSigmaPi()); + const float nsKa = std::abs(track.tpcNSigmaKa()); + const float nsPr = std::abs(track.tpcNSigmaPr()); + float best = 999.f; + int id = -1; + if (nsPi < cfgCutNsigmaPi.value && nsPi < best) { + best = nsPi; + id = kPion; + } + if (nsKa < cfgCutNsigmaKa.value && nsKa < best) { + best = nsKa; + id = kKaon; + } + if (nsPr < cfgCutNsigmaPr.value && nsPr < best) { + best = nsPr; + id = kProton; + } + return id; } - // Axis definitions - AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec dedxAxis = {dedxBins, "dE/dx (a. u.)"}; - AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; - AxisSpec pAxis = {ptBinning, "#it{p} (GeV/#it{c})"}; - AxisSpec pFineAxis{pFineBins, "#it{p} (GeV/c)"}; - AxisSpec pTFineAxis{pFineBins, "#it{p}_{T} (GeV/c)"}; - AxisSpec centAxis = {centBinningStd, "FT0M Centrality (%)"}; - - std::vector centBinningFine; - for (int i = 0; i <= CentBinMax; i++) - centBinningFine.push_back(static_cast(i)); - AxisSpec centFineAxis = {centBinningFine, "FT0M Centrality (%)"}; - - std::vector multBins; - for (int i = 0; i <= MultBinMax; i++) - multBins.push_back(static_cast(i)); - AxisSpec multAxis = {multBins, "N_{ch}^{gen} (|#eta|<0.8)"}; - - std::vector recoMultBins; - for (int i = 0; i <= RecMultBinMax; i++) - recoMultBins.push_back(static_cast(i)); - AxisSpec recoMultAxis = {recoMultBins, "N_{ch}^{reco}"}; - - ue.add("Centrality/hCentRaw", "Raw FT0M Centrality;Centrality (%);Counts", HistType::kTH1D, {centFineAxis}); - ue.add("Centrality/hCentAfterVtx", "Centrality after vertex cut;Centrality (%);Counts", HistType::kTH1D, {centFineAxis}); - ue.add("Centrality/hCentAfterAll", "Centrality after all cuts;Centrality (%);Counts", HistType::kTH1D, {centFineAxis}); - ue.add("Centrality/hCentVsMult", "Centrality vs Generated Multiplicity;Centrality (%);N_{ch}^{gen}", HistType::kTH2D, {centFineAxis, multAxis}); - ue.add("Centrality/hMultVsCent", "Generated Multiplicity vs Centrality;N_{ch}^{gen};Centrality (%)", HistType::kTH2D, {multAxis, centFineAxis}); - ue.add("Centrality/hRecoMultVsCent", "Reconstructed Track Multiplicity vs Centrality;Centrality (%);N_{tracks}^{reco}", HistType::kTH2D, {centFineAxis, recoMultAxis}); - - ue.add("CutFlow/hCutStats", "Cut Statistics;Cut Stage;Counts", HistType::kTH1D, {{5, 0.5, 5.5}}); - auto hCut = ue.get(HIST("CutFlow/hCutStats")); - hCut->GetXaxis()->SetBinLabel(1, "All collisions"); - hCut->GetXaxis()->SetBinLabel(2, "Has MC match"); - hCut->GetXaxis()->SetBinLabel(3, "Has centrality"); - hCut->GetXaxis()->SetBinLabel(4, "Pass vertex"); - hCut->GetXaxis()->SetBinLabel(5, "Selected"); - - ue.add("hEventLossBreakdown", "Event loss breakdown", HistType::kTH1D, {{3, 0.5, 3.5}}); - auto hLoss = ue.get(HIST("hEventLossBreakdown")); - hLoss->GetXaxis()->SetBinLabel(1, "Physics selected"); - hLoss->GetXaxis()->SetBinLabel(2, "Reconstructed"); - hLoss->GetXaxis()->SetBinLabel(3, "Selected"); - - ue.add("MC/GenRecoCollisions", "Generated and Reconstructed MC Collisions", HistType::kTH1D, {{5, 0.5, 5.5}}); - auto hColl = ue.get(HIST("MC/GenRecoCollisions")); - hColl->GetXaxis()->SetBinLabel(1, "Collisions generated"); - hColl->GetXaxis()->SetBinLabel(2, "INEL>0"); - hColl->GetXaxis()->SetBinLabel(3, "INEL>1"); - hColl->GetXaxis()->SetBinLabel(4, "Reconstructed"); - hColl->GetXaxis()->SetBinLabel(5, "Selected"); - - ue.add("MC/EventLoss/GenMultVsCent", "Generated charged particles vs FT0M centrality;FT0M Centrality (%);N_{ch}^{gen}", HistType::kTH2D, {centAxis, multAxis}); - ue.add("MC/EventLoss/GenMultVsCent_Selected", "Generated vs FT0M centrality (selected events);FT0M Centrality (%);N_{ch}^{gen}", HistType::kTH2D, {centAxis, multAxis}); - - ue.add("Inclusive/hPtGen", "Generated primaries (physics selected);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtReco", "All reconstructed tracks (track selection only);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtPrimReco", "Reconstructed primaries (MC matched);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Inclusive/hPtSecReco", "Reconstructed secondaries (MC matched);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - - ue.add("Pion/hPtPrimGenAll", "All generated #pi^{#pm} (no cuts);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Pion/hPtGenINEL", "Generated #pi^{#pm} in INEL>0 events (|#eta|<0.8, p_{T}>0.15);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Pion/hPtGenRecoEvent", "Generated #pi^{#pm} in reconstructed events (|#eta|<0.8, p_{T}>0.15);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Pion/hPtGen", "Generated #pi^{#pm} (physics selected);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Pion/hPtReco", "Reconstructed #pi^{#pm} (MC matched, any status);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Pion/hPtPrimReco", "Reconstructed primary #pi^{#pm} (MC matched);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Pion/hPtMeasured", "Measured #pi^{#pm} (PID selected);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - - ue.add("Pion/hPtGenRecoEvent_Mult", "Generated #pi^{#pm} in reconstructed events vs multiplicity;#it{p}_{T} (GeV/#it{c});N_{ch}^{gen}", HistType::kTH2D, {ptAxis, multAxis}); - ue.add("Pion/hPtGenINEL_Mult", "Generated #pi^{#pm} in INEL>0 events vs multiplicity;#it{p}_{T} (GeV/#it{c});N_{ch}^{gen}", HistType::kTH2D, {ptAxis, multAxis}); - - if (enablePIDHistograms) { - ue.add("Pion/hNsigmaTPC", "TPC n#sigma #pi^{#pm};#it{p}_{T} (GeV/#it{c});n#sigma_{TPC}", HistType::kTH2D, {ptAxis, {200, -10, 10}}); + int countGeneratedChargedPrimaries(const aod::McParticles& particles, float etaMax) const + { + int count = 0; + for (const auto& particle : particles) { + auto* pdgPart = pdg->GetParticle(particle.pdgCode()); + if (!pdgPart || std::abs(pdgPart->Charge()) < MinCharge) + continue; + if (!particle.isPhysicalPrimary()) + continue; + if (std::abs(particle.eta()) > etaMax) + continue; + if (particle.pt() < cfgTrkLowPtCut.value) + continue; + count++; + } + return count; } - ue.add("Kaon/hPtPrimGenAll", "All generated K^{#pm} (no cuts);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Kaon/hPtGenINEL", "Generated K^{#pm} in INEL>0 events (|#eta|<0.8, p_{T}>0.15);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Kaon/hPtGenRecoEvent", "Generated K^{#pm} in reconstructed events (|#eta|<0.8, p_{T}>0.15);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Kaon/hPtGen", "Generated K^{#pm} (physics selected);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Kaon/hPtReco", "Reconstructed K^{#pm} (MC matched, any status);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Kaon/hPtPrimReco", "Reconstructed primary K^{#pm} (MC matched);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Kaon/hPtMeasured", "Measured K^{#pm} (PID selected);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); + void processSim(aod::McCollisions::iterator const& mcCollision, + soa::SmallGroups const& collisions, + aod::McParticles const& mcParticles, + TracksMC const& tracksMC, + BCsRun3 const& /*bcs*/) + { + registry.fill(HIST("EventCounter"), kAllGen); - ue.add("Kaon/hPtGenRecoEvent_Mult", "Generated K^{#pm} in reconstructed events vs multiplicity;#it{p}_{T} (GeV/#it{c});N_{ch}^{gen}", HistType::kTH2D, {ptAxis, multAxis}); - ue.add("Kaon/hPtGenINEL_Mult", "Generated K^{#pm} in INEL>0 events vs multiplicity;#it{p}_{T} (GeV/#it{c});N_{ch}^{gen}", HistType::kTH2D, {ptAxis, multAxis}); + int nChFT0A = 0, nChFT0C = 0; + int nChINEL = 0; + int nChMCEta = 0; + std::vector particlePtBySpecies[4]; // Pi, Ka, Pr, All + std::vector particlePtAll; - if (enablePIDHistograms) { - ue.add("Kaon/hNsigmaTPC", "TPC n#sigma K^{#pm};#it{p}_{T} (GeV/#it{c});n#sigma_{TPC}", HistType::kTH2D, {ptAxis, {200, -10, 10}}); - } + // Store particle pT for MC closure + std::vector mcPiPt, mcKaPt, mcPrPt; - ue.add("Proton/hPtPrimGenAll", "All generated p+#bar{p} (no cuts);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Proton/hPtGenINEL", "Generated p+#bar{p} in INEL>0 events (|#eta|<0.8, p_{T}>0.15);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Proton/hPtGenRecoEvent", "Generated p+#bar{p} in reconstructed events (|#eta|<0.8, p_{T}>0.15);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Proton/hPtGen", "Generated p+#bar{p} (physics selected);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Proton/hPtReco", "Reconstructed p+#bar{p} (MC matched, any status);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Proton/hPtPrimReco", "Reconstructed primary p+#bar{p} (MC matched);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); - ue.add("Proton/hPtMeasured", "Measured p+#bar{p} (PID selected);#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH1D, {ptAxis}); + for (const auto& particle : mcParticles) { + auto* pdgPart = pdg->GetParticle(particle.pdgCode()); + if (!pdgPart || std::abs(pdgPart->Charge()) < MinCharge) + continue; + if (!particle.isPhysicalPrimary()) + continue; - ue.add("Proton/hPtGenRecoEvent_Mult", "Generated p+#bar{p} in reconstructed events vs multiplicity;#it{p}_{T} (GeV/#it{c});N_{ch}^{gen}", HistType::kTH2D, {ptAxis, multAxis}); - ue.add("Proton/hPtGenINEL_Mult", "Generated p+#bar{p} in INEL>0 events vs multiplicity;#it{p}_{T} (GeV/#it{c});N_{ch}^{gen}", HistType::kTH2D, {ptAxis, multAxis}); + const float eta = particle.eta(); + const float pt = particle.pt(); + + if (eta > MinFT0A && eta < MaxFT0A) + nChFT0A++; + if (eta > MinFT0C && eta < MaxFT0C) + nChFT0C++; + if (std::abs(eta) < 1.0f) + nChINEL++; + + if (std::abs(eta) < tpcNchAcceptance.value) { + nChMCEta++; + + const int absPDG = std::abs(particle.pdgCode()); + if (absPDG == PDG_t::kPiPlus) { + particlePtBySpecies[kPion].push_back(pt); + mcPiPt.push_back(pt); + } else if (absPDG == PDG_t::kKPlus) { + particlePtBySpecies[kKaon].push_back(pt); + mcKaPt.push_back(pt); + } else if (absPDG == PDG_t::kProton) { + particlePtBySpecies[kProton].push_back(pt); + mcPrPt.push_back(pt); + } + particlePtAll.push_back(pt); + } + } - if (enablePIDHistograms) { - ue.add("Proton/hNsigmaTPC", "TPC n#sigma p+#bar{p};#it{p}_{T} (GeV/#it{c});n#sigma_{TPC}", HistType::kTH2D, {ptAxis, {200, -10, 10}}); - } + // Fill NchMCcentVsTVX before TVX selection + registry.fill(HIST("NchMCcentVsTVX"), nChMCEta, 0.5); - ue.add("hEventsReco_Cent", "Reconstructed events vs centrality;FT0M Centrality (%);Counts", HistType::kTH1D, {centAxis}); - ue.add("hEventsINEL_Cent", "INEL>0 events vs centrality;FT0M Centrality (%);Counts", HistType::kTH1D, {centAxis}); - - ue.add("hNclFoundTPCBefore", "Number of TPC found clusters before tkr cuts", HistType::kTH1D, {{200, 0, 200}}); - ue.add("hNclPIDTPCBefore", "Number of TPC PID clusters before tkr cuts", HistType::kTH1D, {{200, 0, 200}}); - ue.add("hNclFoundTPCAfter", "Number of TPC found after tkr cuts", HistType::kTH1D, {{200, 0, 200}}); - ue.add("hNclPIDTPCAfter", "Number of TPC PID after tkr cuts", HistType::kTH1D, {{200, 0, 200}}); - ue.add("hEta", "Track eta;#eta;Counts", HistType::kTH1D, {{20, -0.8, 0.8}}); - ue.add("hPhi", "Track phi;#varphi (rad);Counts", HistType::kTH1D, {{64, 0, TwoPI}}); - ue.add("hvtxZ", "Vertex Z (data);Vertex Z (cm);Events", HistType::kTH1F, {{40, -20.0, 20.0}}); - - // De/Dx for ch and v0 particles - for (int i = 0; i < ParticlesType; ++i) { - ue.add(("DedxVsMomentum/" + std::string(DedxvsMomentumPos[i])).c_str(), - "dE/dx vs Momentum Positive", HistType::kTH3F, - {{pAxis}, {dedxAxis}, {etaAxis}}); - ue.add(("DedxVsMomentum/" + std::string(DedxvsMomentumNeg[i])).c_str(), - "dE/dx vs Momentum Negative", HistType::kTH3F, - {{pAxis}, {dedxAxis}, {etaAxis}}); - } - // pt vs p - for (int i = 0; i < ResponseMatrixTypes; ++i) { - ue.add(("ResponseMatrix/" + std::string(EtavspvspTPosPart[i])).c_str(), - "eta vs pT vs p Positive", HistType::kTH3F, - {{etaAxis}, {ptAxis}, {pAxis}}); - ue.add(("ResponseMatrix/" + std::string(EtavspvspTNegPart[i])).c_str(), - "eta vs pT vs p Negative", HistType::kTH3F, - {{etaAxis}, {ptAxis}, {pAxis}}); - } + if (selTVXMC.value && !(nChFT0A > 0 && nChFT0C > 0)) + return; + registry.fill(HIST("NchMCcentVsTVX"), nChMCEta, 1.5); + registry.fill(HIST("EventCounter"), kTVXequiv); - for (int i = 0; i < CentralityClasses + 1; ++i) { - ue.add(("Binning/" + std::string(CentpPos[i])).c_str(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); - ue.add(("Binning/" + std::string(CentpNeg[i])).c_str(), "p vs eta", HistType::kTH2F, {{etaAxis}, {pFineAxis}}); - ue.add(("Binning/" + std::string(CentpTPos[i])).c_str(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); - ue.add(("Binning/" + std::string(CentpTNeg[i])).c_str(), "pT vs eta", HistType::kTH2F, {{etaAxis}, {pTFineAxis}}); - } + if (isZvtxPosSelMC.value && std::abs(mcCollision.posZ()) > cfgCutVertex.value) + return; + registry.fill(HIST("EventCounter"), kVtxZ); - // ===== Particle Fractions as function of p and pT ===== - ue.add("ParticleFractions/hTotalCountsVsMomentumPos", "Total counts vs momentum;#it{p} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {pAxis}}); - ue.add("ParticleFractions/hTotalCountsVsPtPos", "Total counts vs pT;#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {ptAxis}}); - ue.add("ParticleFractions/hTotalCountsVsMomentumNeg", "Total counts vs momentum;#it{p} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {pAxis}}); - ue.add("ParticleFractions/hTotalCountsVsPtNeg", "Total counts vs pT;#it{p}_{T} (GeV/#it{c});Counts", HistType::kTH2D, {{etaAxis}, {ptAxis}}); - - for (int i = 0; i < ParticlesType + 1; ++i) { - ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsMomentumPos[i])).c_str(), - "Particle fraction vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); - ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsPtPos[i])).c_str(), - "Particle fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); - ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsMomentumNeg[i])).c_str(), - "Particle fraction vs momentum", HistType::kTH2D, {{etaAxis}, {pAxis}}); - ue.add(("ParticleFractions/" + std::string(ParticleFractionsVsPtNeg[i])).c_str(), - "Particle fraction vs pT", HistType::kTH2D, {{etaAxis}, {ptAxis}}); - } + if (cfgINELCut.value == 1 && nChINEL == 0) + return; + if (cfgINELCut.value == INELgt1 && nChINEL < INELgt1) + return; + registry.fill(HIST("EventCounter"), kINELgt0); - LOG(info) << "=== Initialization complete ==="; -} + const float nchF = static_cast(nChMCEta); -void MultiplicityPt::processMC(TrackTableMC const& tracks, - aod::McParticles const& particles, - aod::McCollisions const& mcCollisions, - RecoCollisions const& collisions, - aod::McCollisionLabels const& labels, - aod::McCentFT0Ms const& centTable, - BCsRun3 const& /*bcs*/) -{ + // Fill event loss denominator and MC closure + registry.fill(HIST("NchMC_AllGen"), nchF); + registry.fill(HIST("MC/EventLoss/NchGenerated"), nchF); - std::map mcCollisionToNch; - std::set physicsSelectedMCCollisions; - std::map mcCollisionToINELClass; - std::set inel0MCCollisions; - std::map mcCollToCentFromReco; // MC collision ID -> centrality from reco + for (const float& pt : mcPiPt) { + registry.fill(HIST("MCclosure_PtMCPiVsNchMC"), pt, nchF); + registry.fill(HIST("MC/GenPtVsNch"), pt, nchF); + } + for (const float& pt : mcKaPt) { + registry.fill(HIST("MCclosure_PtMCKaVsNchMC"), pt, nchF); + registry.fill(HIST("MC/GenPtVsNch"), pt, nchF); + } + for (const float& pt : mcPrPt) { + registry.fill(HIST("MCclosure_PtMCPrVsNchMC"), pt, nchF); + registry.fill(HIST("MC/GenPtVsNch"), pt, nchF); + } - ue.fill(HIST("MC/GenRecoCollisions"), 1.f, mcCollisions.size()); + // Fill physics-selected histograms (after vertex and INEL cuts) + registry.fill(HIST("MC/EventLoss/NchGenerated_PhysicsSelected"), nchF); + for (const float& pt : mcPiPt) { + registry.fill(HIST("MC/GenPtVsNch_PhysicsSelected"), pt, nchF); + } + for (const float& pt : mcKaPt) { + registry.fill(HIST("MC/GenPtVsNch_PhysicsSelected"), pt, nchF); + } + for (const float& pt : mcPrPt) { + registry.fill(HIST("MC/GenPtVsNch_PhysicsSelected"), pt, nchF); + } - for (const auto& mcCollision : mcCollisions) { - int64_t mcCollId = mcCollision.globalIndex(); - auto particlesInCollision = particles.sliceBy(perMCCol, mcCollId); + // Fill signal loss denominators + for (const float& pt : particlePtBySpecies[kPion]) { + registry.fill(HIST("PtPiVsNchMC_AllGen"), pt, nchF); + } + for (const float& pt : particlePtBySpecies[kKaon]) { + registry.fill(HIST("PtKaVsNchMC_AllGen"), pt, nchF); + } + for (const float& pt : particlePtBySpecies[kProton]) { + registry.fill(HIST("PtPrVsNchMC_AllGen"), pt, nchF); + } + for (const float& pt : particlePtAll) { + registry.fill(HIST("PtAllVsNchMC_AllGen"), pt, nchF); + } - // Check if event has at least 1 particle in acceptance (INEL>0) - bool hasParticleInAcceptance = false; - for (const auto& particle : particlesInCollision) { - auto pdgParticle = pdg->GetParticle(particle.pdgCode()); - if (!pdgParticle || pdgParticle->Charge() == 0.) - continue; - if (!particle.isPhysicalPrimary()) - continue; - if (std::abs(particle.eta()) >= cfgCutEtaMax.value) - continue; - if (particle.pt() < cfgTrkLowPtCut.value) - continue; - hasParticleInAcceptance = true; - break; + // Fill inclusive histograms - all generated + for (const float& pt : particlePtAll) { + registry.fill(HIST("Inclusive/hPtPrimGenAll"), pt); + registry.fill(HIST("Inclusive/hPtPrimGenAllVsMult"), pt, nchF); + } + for (const float& pt : mcPiPt) { + registry.fill(HIST("Pion/hPtPrimGenAll"), pt); + registry.fill(HIST("Pion/hPtPrimGenAllVsMult"), pt, nchF); + } + for (const float& pt : mcKaPt) { + registry.fill(HIST("Kaon/hPtPrimGenAll"), pt); + registry.fill(HIST("Kaon/hPtPrimGenAllVsMult"), pt, nchF); + } + for (const float& pt : mcPrPt) { + registry.fill(HIST("Proton/hPtPrimGenAll"), pt); + registry.fill(HIST("Proton/hPtPrimGenAllVsMult"), pt, nchF); } - if (hasParticleInAcceptance) { - inel0MCCollisions.insert(mcCollId); + for (const float& pt : particlePtAll) { + registry.fill(HIST("Inclusive/hPtPrimGen"), pt); + registry.fill(HIST("Inclusive/hPtPrimGenVsMult"), pt, nchF); } - int nGenCharged = countGeneratedChargedPrimaries(particlesInCollision, cfgCutEtaMax.value, cfgTrkLowPtCut.value); - mcCollisionToNch[mcCollId] = nGenCharged; - - bool inel0 = o2::pwglf::isINELgt0mc(particlesInCollision, pdg); - bool inel1 = o2::pwglf::isINELgt1mc(particlesInCollision, pdg); - int inelClass = inel1 ? 2 : (inel0 ? 1 : 0); - mcCollisionToINELClass[mcCollId] = inelClass; - - bool physicsSelected = (std::abs(mcCollision.posZ()) <= cfgCutVertex.value); - if (cfgINELCut.value == INELgt0 && !inel0) - physicsSelected = false; - if (cfgINELCut.value == INELgt1 && !inel1) - physicsSelected = false; - - if (physicsSelected) { - physicsSelectedMCCollisions.insert(mcCollId); - if (inel0) - ue.fill(HIST("MC/GenRecoCollisions"), 2.f); - if (inel1) - ue.fill(HIST("MC/GenRecoCollisions"), 3.f); + const int nRecColls = collisions.size(); + registry.fill(HIST("NumberOfRecoCollisions"), nRecColls); + + if (nRecColls == 0) + return; + registry.fill(HIST("EventCounter"), kRecoColl); + + int biggestNContribs = -1; + int bestCollisionIndex = -1; + for (const auto& col : collisions) { + if (col.numContrib() > biggestNContribs) { + biggestNContribs = col.numContrib(); + bestCollisionIndex = col.globalIndex(); + } } - // Fill generated particle spectra - for (const auto& particle : particlesInCollision) { - auto pdgParticle = pdg->GetParticle(particle.pdgCode()); - if (!pdgParticle || pdgParticle->Charge() == 0.) + for (const auto& collision : collisions) { + if (collision.globalIndex() != bestCollisionIndex) continue; - if (!particle.isPhysicalPrimary()) + if (!isEventSelectedMC(collision)) continue; - int pdgCode = std::abs(particle.pdgCode()); - float pt = particle.pt(); + registry.fill(HIST("EventCounter"), kRecoSelected); + + const float centrality = collision.centFT0M(); - // Fill hPtPrimGenAll for ALL generated particles (NO CUTS) - if (pdgCode == PDG_t::kPiPlus) { - ue.fill(HIST("Pion/hPtPrimGenAll"), pt); - } else if (pdgCode == PDG_t::kKPlus) { - ue.fill(HIST("Kaon/hPtPrimGenAll"), pt); - } else if (pdgCode == PDG_t::kProton) { - ue.fill(HIST("Proton/hPtPrimGenAll"), pt); + float magField = 0.f; + if (applyPhiCut.value) { + const auto& bc = collision.foundBC_as(); + magField = static_cast(getMagneticField(bc.timestamp())); } - // Fill hPtGenINEL for particles in INEL>0 events (with acceptance cuts) - if (hasParticleInAcceptance) { - if (std::abs(particle.eta()) >= cfgCutEtaMax.value) - continue; - if (particle.pt() < cfgTrkLowPtCut.value) - continue; + // Fill centrality and correlation histograms + registry.fill(HIST("Centrality/hCentRaw"), centrality); + registry.fill(HIST("NchMCVsCent"), centrality, nchF); + registry.fill(HIST("Centrality/hCentVsMult"), centrality, nchF); + registry.fill(HIST("Centrality/hMultVsCent"), nchF, centrality); + registry.fill(HIST("Centrality/hCentVsVz"), centrality, collision.posZ()); + registry.fill(HIST("Centrality_WRecoEvt"), centrality); + registry.fill(HIST("Centrality_WRecoEvtWSelCri"), centrality); + + for (const float& pt : particlePtAll) { + registry.fill(HIST("NchMCVsCentVsPt"), centrality, nchF, pt); + } - if (pdgCode == PDG_t::kPiPlus) { - ue.fill(HIST("Pion/hPtGenINEL"), pt); - ue.fill(HIST("Pion/hPtGenINEL_Mult"), pt, nGenCharged); - } else if (pdgCode == PDG_t::kKPlus) { - ue.fill(HIST("Kaon/hPtGenINEL"), pt); - ue.fill(HIST("Kaon/hPtGenINEL_Mult"), pt, nGenCharged); - } else if (pdgCode == PDG_t::kProton) { - ue.fill(HIST("Proton/hPtGenINEL"), pt); - ue.fill(HIST("Proton/hPtGenINEL_Mult"), pt, nGenCharged); - } + registry.fill(HIST("NchMC_WithRecoEvt"), nchF); + registry.fill(HIST("MC/EventLoss/NchGenerated_Reconstructed"), nchF); + registry.fill(HIST("MC/EventLoss/GenMultVsCent"), centrality, nchF); + registry.fill(HIST("zPosMC"), mcCollision.posZ()); + registry.fill(HIST("zPosReco"), collision.posZ()); + registry.fill(HIST("T0Ccent"), centrality); + + if (collision.has_foundFT0()) { + registry.fill(HIST("T0CcentVsFoundFT0"), centrality, 1.5); + } else { + registry.fill(HIST("T0CcentVsFoundFT0"), centrality, 0.5); + } + if (collision.has_foundFT0() && collision.selection_bit(aod::evsel::kIsTriggerTVX)) { + registry.fill(HIST("T0CcentVsFoundFT0AndTVX"), centrality, 1.5); + } else { + registry.fill(HIST("T0CcentVsFoundFT0AndTVX"), centrality, 0.5); } - // Apply acceptance cuts for physics-selected spectra - if (std::abs(particle.eta()) >= cfgCutEtaMax.value) - continue; - if (particle.pt() < cfgTrkLowPtCut.value) - continue; + // Fill inclusive histograms for reco events + for (const float& pt : particlePtAll) { + registry.fill(HIST("Inclusive/hPtPrimRecoEv"), pt); + registry.fill(HIST("Inclusive/hPtPrimRecoEvVsMult"), pt, nchF); + registry.fill(HIST("Inclusive/hPtPrimGoodEv"), pt); + registry.fill(HIST("Inclusive/hPtPrimGoodEvVsMult"), pt, nchF); + } - // Fill generated spectra (physics selected only) - if (physicsSelected) { - ue.fill(HIST("Inclusive/hPtGen"), pt); + // Fill signal loss numerators and efficiency denominators + for (const float& pt : particlePtBySpecies[kPion]) { + registry.fill(HIST("PtPiVsNchMC_WithRecoEvt"), pt, nchF); + registry.fill(HIST("PtPiVsCentMC_WithRecoEvt"), pt, centrality); + registry.fill(HIST("PtGenPiVsNchMC_WithRecoEvt"), pt, nchF); + } + for (const float& pt : particlePtBySpecies[kKaon]) { + registry.fill(HIST("PtKaVsNchMC_WithRecoEvt"), pt, nchF); + registry.fill(HIST("PtKaVsCentMC_WithRecoEvt"), pt, centrality); + registry.fill(HIST("PtGenKaVsNchMC_WithRecoEvt"), pt, nchF); + } + for (const float& pt : particlePtBySpecies[kProton]) { + registry.fill(HIST("PtPrVsNchMC_WithRecoEvt"), pt, nchF); + registry.fill(HIST("PtPrVsCentMC_WithRecoEvt"), pt, centrality); + registry.fill(HIST("PtGenPrVsNchMC_WithRecoEvt"), pt, nchF); + } + for (const float& pt : particlePtAll) { + registry.fill(HIST("PtAllVsNchMC_WithRecoEvt"), pt, nchF); + registry.fill(HIST("PtAllVsCentMC_WithRecoEvt"), pt, centrality); + registry.fill(HIST("PtGenAllVsNchMC_WithRecoEvt"), pt, nchF); + } - if (pdgCode == PDG_t::kPiPlus) { - ue.fill(HIST("Pion/hPtGen"), pt); - } else if (pdgCode == PDG_t::kKPlus) { - ue.fill(HIST("Kaon/hPtGen"), pt); - } else if (pdgCode == PDG_t::kProton) { - ue.fill(HIST("Proton/hPtGen"), pt); - } + // Fill efficiency denominator histograms + for (const float& pt : mcPiPt) { + registry.fill(HIST("Pion/hPtDenEff"), pt); + registry.fill(HIST("Pion/hPtDenEffVsMult"), pt, nchF); + } + for (const float& pt : mcKaPt) { + registry.fill(HIST("Kaon/hPtDenEff"), pt); + registry.fill(HIST("Kaon/hPtDenEffVsMult"), pt, nchF); + } + for (const float& pt : mcPrPt) { + registry.fill(HIST("Proton/hPtDenEff"), pt); + registry.fill(HIST("Proton/hPtDenEffVsMult"), pt, nchF); + } + for (const float& pt : particlePtAll) { + registry.fill(HIST("Inclusive/hPtDenEff"), pt); + registry.fill(HIST("Inclusive/hPtDenEffVsMult"), pt, nchF); } - } - } - std::map recoToMcMap; - std::map recoToCentMap; + const auto& groupedTracks = tracksMC.sliceBy(perCollision, collision.globalIndex()); - size_t nPairs = std::min(labels.size(), collisions.size()); - for (size_t i = 0; i < nPairs; ++i) { - const auto& collision = collisions.iteratorAt(i); - const auto& label = labels.iteratorAt(i); - recoToMcMap[collision.globalIndex()] = label.mcCollisionId(); - } + for (const auto& track : groupedTracks) { + if (track.eta() < cfgCutEtaMin.value || track.eta() > cfgCutEtaMax.value) + continue; + if (track.pt() < cfgTrkLowPtCut.value) + continue; + if (!track.has_mcParticle()) + continue; - size_t nCentPairs = std::min(centTable.size(), collisions.size()); - for (size_t i = 0; i < nCentPairs; ++i) { - const auto& collision = collisions.iteratorAt(i); - const auto& cent = centTable.iteratorAt(i); - float centValue = cent.centFT0M(); - recoToCentMap[collision.globalIndex()] = centValue; - ue.fill(HIST("Centrality/hCentRaw"), centValue); - } + // Before DCA cuts + registry.fill(HIST("hDCAxyVsPt_before"), track.pt(), track.dcaXY()); + registry.fill(HIST("hDCAzVsPt_before"), track.pt(), track.dcaZ()); - std::set reconstructedMCCollisions; - std::set selectedMCCollisions; - - for (const auto& collision : collisions) { - ue.fill(HIST("CutFlow/hCutStats"), 1); - - int64_t collId = collision.globalIndex(); - - // MC matching - auto mcIt = recoToMcMap.find(collId); - if (mcIt == recoToMcMap.end()) - continue; - ue.fill(HIST("CutFlow/hCutStats"), 2); - - int64_t mcCollId = mcIt->second; - auto nchIt = mcCollisionToNch.find(mcCollId); - if (nchIt == mcCollisionToNch.end()) - continue; - int nGenCharged = nchIt->second; - - auto inelIt = mcCollisionToINELClass.find(mcCollId); - int inelClass = (inelIt != mcCollisionToINELClass.end()) ? inelIt->second : 0; - - // Centrality - auto centIt = recoToCentMap.find(collId); - if (centIt == recoToCentMap.end()) - continue; - ue.fill(HIST("CutFlow/hCutStats"), 3); - - float cent = centIt->second; - if (cent < 0 || cent > CentBinMax) - continue; - - // Store centrality for this MC collision (used later for MC truth plots) - mcCollToCentFromReco[mcCollId] = cent; - - // Vertex cut - bool passVertex = std::abs(collision.posZ()) <= cfgCutVertex.value; - if (!passVertex) - continue; - ue.fill(HIST("CutFlow/hCutStats"), 4); - ue.fill(HIST("Centrality/hCentAfterVtx"), cent); - - // INEL cut - bool passINEL = true; - if (cfgINELCut.value == INELgt0 && inelClass < INELgt0) - passINEL = false; - if (cfgINELCut.value == INELgt1 && inelClass < INELgt1) - passINEL = false; - if (!passINEL) - continue; - - // Event passed all cuts - ue.fill(HIST("CutFlow/hCutStats"), 5); - ue.fill(HIST("Centrality/hCentAfterAll"), cent); - - ue.fill(HIST("MC/EventLoss/GenMultVsCent_Selected"), cent, nGenCharged); - ue.fill(HIST("Centrality/hCentVsMult"), cent, nGenCharged); - ue.fill(HIST("Centrality/hMultVsCent"), nGenCharged, cent); - ue.fill(HIST("hvtxZ"), collision.posZ()); - - selectedMCCollisions.insert(mcCollId); - reconstructedMCCollisions.insert(mcCollId); - - // Get magnetic field for phi cut - float magField = 0; - if (applyPhiCut.value) { - const auto& bc = collision.bc_as(); - magField = getMagneticField(bc.timestamp()); - } + if (applyPhiCut.value && track.pt() >= pTthresholdPhiCut.value) { + float phiPrime = getTransformedPhi(track.phi(), track.sign(), magField); + registry.fill(HIST("PhiCut/hPtVsPhiPrimeBefore"), track.pt(), phiPrime); + } - int nTracksInEvent = 0; + const auto& particle = track.mcParticle(); + auto* pdgPart = pdg->GetParticle(particle.pdgCode()); + if (!pdgPart || std::abs(pdgPart->Charge()) < MinCharge) + continue; - for (const auto& track : tracks) { - if (!track.has_collision()) - continue; - if (track.collisionId() != collId) - continue; - // Ncl distribution before cuts - ue.fill(HIST("hNclFoundTPCBefore"), track.tpcNClsFound()); - ue.fill(HIST("hNclPIDTPCBefore"), track.tpcNClsPID()); + const bool isPrimary = particle.isPhysicalPrimary(); + const bool isDecay = (!isPrimary) && (particle.getProcess() == TMCProcess::kPDecay); + const bool isMaterial = (!isPrimary) && (!isDecay); + (void)isMaterial; + const int absPDG = std::abs(particle.pdgCode()); + const bool isPi = (absPDG == PDG_t::kPiPlus); + const bool isKa = (absPDG == PDG_t::kKPlus); + const bool isPr = (absPDG == PDG_t::kProton); + + float momentum = track.p(); + float tpcSignal = track.tpcSignal(); + float eta = track.eta(); + int charge = track.sign(); + + int centIndex = -1; + for (int j = 0; j < CentralityClasses; ++j) { + if (centrality >= centBinningStd[j] && centrality < centBinningStd[j + 1]) { + centIndex = j; + break; + } + } + if (centIndex == -1) + continue; - if (!passesTrackSelection(track, magField)) - continue; + registry.fill(HIST("hEta"), track.eta()); + registry.fill(HIST("hPhi"), track.phi()); + registry.fill(HIST("EtaVsPhi"), track.eta(), track.phi()); + + // Fill TPC cluster histograms + registry.fill(HIST("hNclFoundTPC"), track.tpcNClsFound()); + registry.fill(HIST("hNclPIDTPC"), track.tpcNClsPID()); + registry.fill(HIST("hNclFoundTPCvsPt"), track.pt(), track.tpcNClsFound()); + registry.fill(HIST("hNclPIDTPCvsPt"), track.pt(), track.tpcNClsPID()); + + // Fill inclusive reconstructed histograms + registry.fill(HIST("Inclusive/hPtAllReco"), track.pt()); + registry.fill(HIST("Inclusive/hPtAllRecoVsMult"), track.pt(), nchF); + + if (isPi) { + registry.fill(HIST("Pion/hPtAllReco"), track.pt()); + registry.fill(HIST("Pion/hPtAllRecoVsMult"), track.pt(), nchF); + } else if (isKa) { + registry.fill(HIST("Kaon/hPtAllReco"), track.pt()); + registry.fill(HIST("Kaon/hPtAllRecoVsMult"), track.pt(), nchF); + } else if (isPr) { + registry.fill(HIST("Proton/hPtAllReco"), track.pt()); + registry.fill(HIST("Proton/hPtAllRecoVsMult"), track.pt(), nchF); + } - nTracksInEvent++; - // Ncl distribution before cuts - ue.fill(HIST("hNclFoundTPCAfter"), track.tpcNClsFound()); - ue.fill(HIST("hNclPIDTPCAfter"), track.tpcNClsPID()); - ue.fill(HIST("hEta"), track.eta()); - ue.fill(HIST("hPhi"), track.phi()); - ue.fill(HIST("Inclusive/hPtReco"), track.pt()); - - // ===== dE/dx and momentum for V0 cross-check histograms ===== - float tpcSignal = track.tpcSignal(); - float momentum = track.p(); // momentum total - float eta = track.eta(); - int charge = track.sign(); - - int centIndex = -1; - for (int j = 0; j < CentralityClasses; ++j) { - if (cent >= centBinningStd[j] && cent < centBinningStd[j + 1]) { - centIndex = j; - break; + if (passesTrackSelectionNoDCA(track)) { + if (isPrimary) { + if (isPi) + registry.fill(HIST("dcaVsPtPi"), track.pt(), track.dcaXY(), centrality); + if (isPr) + registry.fill(HIST("dcaVsPtPr"), track.pt(), track.dcaXY(), centrality); + } else if (isDecay) { + if (isPi) + registry.fill(HIST("dcaVsPtPiDec"), track.pt(), track.dcaXY(), centrality); + if (isPr) + registry.fill(HIST("dcaVsPtPrDec"), track.pt(), track.dcaXY(), centrality); + } else { + if (isPi) + registry.fill(HIST("dcaVsPtPiMat"), track.pt(), track.dcaXY(), centrality); + if (isPr) + registry.fill(HIST("dcaVsPtPrMat"), track.pt(), track.dcaXY(), centrality); + } } - } - if (centIndex == -1) - continue; - // dedx for all particles - if (charge > 0) { - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Pos"), momentum, tpcSignal, eta); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos"), eta, track.pt(), momentum); - // binning - ue.fill(HIST("Binning/p_vs_eta_MB_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_MB_Pos"), eta, track.pt()); - - // For centrality - switch (centIndex) { - case 0: - ue.fill(HIST("Binning/p_vs_eta_Cent0_1_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent0_1_Pos"), eta, track.pt()); - break; - case 1: - ue.fill(HIST("Binning/p_vs_eta_Cent1_5_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent1_5_Pos"), eta, track.pt()); - break; - case 2: - ue.fill(HIST("Binning/p_vs_eta_Cent5_10_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent5_10_Pos"), eta, track.pt()); - break; - case 3: - ue.fill(HIST("Binning/p_vs_eta_Cent10_15_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent10_15_Pos"), eta, track.pt()); - break; - case 4: - ue.fill(HIST("Binning/p_vs_eta_Cent15_20_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent15_20_Pos"), eta, track.pt()); - break; - case 5: - ue.fill(HIST("Binning/p_vs_eta_Cent20_30_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent20_30_Pos"), eta, track.pt()); - break; - case 6: - ue.fill(HIST("Binning/p_vs_eta_Cent30_40_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent30_40_Pos"), eta, track.pt()); - break; - case 7: - ue.fill(HIST("Binning/p_vs_eta_Cent40_50_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent40_50_Pos"), eta, track.pt()); - break; - case 8: - ue.fill(HIST("Binning/p_vs_eta_Cent50_70_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent50_70_Pos"), eta, track.pt()); - break; - case 9: - ue.fill(HIST("Binning/p_vs_eta_Cent70_100_Pos"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent70_100_Pos"), eta, track.pt()); - break; + if (!passesTrackSelection(track)) + continue; + + // After Trk cuts + registry.fill(HIST("hDCAxyVsPt_after"), track.pt(), track.dcaXY()); + registry.fill(HIST("hDCAzVsPt_after"), track.pt(), track.dcaZ()); + + if (applyPhiCut.value && !passedPhiCut(track, magField)) + continue; + + if (applyPhiCut.value && track.pt() >= pTthresholdPhiCut.value) { + float phiPrime = getTransformedPhi(track.phi(), track.sign(), magField); + registry.fill(HIST("PhiCut/hPtVsPhiPrimeAfter"), track.pt(), phiPrime); } - } else { - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Neg"), momentum, tpcSignal, eta); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg"), eta, track.pt(), momentum); - // binning - ue.fill(HIST("Binning/p_vs_eta_MB_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_MB_Neg"), eta, track.pt()); - - switch (centIndex) { - case 0: - ue.fill(HIST("Binning/p_vs_eta_Cent0_1_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent0_1_Neg"), eta, track.pt()); - break; - case 1: - ue.fill(HIST("Binning/p_vs_eta_Cent1_5_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent1_5_Neg"), eta, track.pt()); - break; - case 2: - ue.fill(HIST("Binning/p_vs_eta_Cent5_10_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent5_10_Neg"), eta, track.pt()); - break; - case 3: - ue.fill(HIST("Binning/p_vs_eta_Cent10_15_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent10_15_Neg"), eta, track.pt()); - break; - case 4: - ue.fill(HIST("Binning/p_vs_eta_Cent15_20_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent15_20_Neg"), eta, track.pt()); - break; - case 5: - ue.fill(HIST("Binning/p_vs_eta_Cent20_30_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent20_30_Neg"), eta, track.pt()); - break; - case 6: - ue.fill(HIST("Binning/p_vs_eta_Cent30_40_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent30_40_Neg"), eta, track.pt()); - break; - case 7: - ue.fill(HIST("Binning/p_vs_eta_Cent40_50_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent40_50_Neg"), eta, track.pt()); - break; - case 8: - ue.fill(HIST("Binning/p_vs_eta_Cent50_70_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent50_70_Neg"), eta, track.pt()); - break; - case 9: - ue.fill(HIST("Binning/p_vs_eta_Cent70_100_Neg"), eta, momentum); - ue.fill(HIST("Binning/pT_vs_eta_Cent70_100_Neg"), eta, track.pt()); - break; + + // Fill efficiency numerators (reconstructed primaries) + if (isPrimary) { + registry.fill(HIST("PtResolution"), particle.pt(), + (track.pt() - particle.pt()) / particle.pt()); + + registry.fill(HIST("Inclusive/hPtNumEff"), particle.pt()); + registry.fill(HIST("Inclusive/hPtNumEffVsMult"), particle.pt(), nchF); + registry.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); + registry.fill(HIST("Inclusive/hPtPrimRecoVsMult"), track.pt(), nchF); + + if (isPi) { + registry.fill(HIST("Pion/hPtNumEff"), particle.pt()); + registry.fill(HIST("Pion/hPtNumEffVsMult"), particle.pt(), nchF); + registry.fill(HIST("Pion/hPtPrimReco"), track.pt()); + registry.fill(HIST("Pion/hPtPrimRecoVsMult"), track.pt(), nchF); + } else if (isKa) { + registry.fill(HIST("Kaon/hPtNumEff"), particle.pt()); + registry.fill(HIST("Kaon/hPtNumEffVsMult"), particle.pt(), nchF); + registry.fill(HIST("Kaon/hPtPrimReco"), track.pt()); + registry.fill(HIST("Kaon/hPtPrimRecoVsMult"), track.pt(), nchF); + } else if (isPr) { + registry.fill(HIST("Proton/hPtNumEff"), particle.pt()); + registry.fill(HIST("Proton/hPtNumEffVsMult"), particle.pt(), nchF); + registry.fill(HIST("Proton/hPtPrimReco"), track.pt()); + registry.fill(HIST("Proton/hPtPrimRecoVsMult"), track.pt(), nchF); + } + + // Fill efficiency numerator histograms + if (isPi) { + registry.fill(HIST("PtPiVsCent_WithRecoEvt"), track.pt(), centrality); + registry.fill(HIST("PtGenPiVsNchMC_RecoTrk"), particle.pt(), nchF); + registry.fill(HIST("MCclosure_PtPiVsNchMC"), track.pt(), nchF); + } else if (isKa) { + registry.fill(HIST("PtKaVsCent_WithRecoEvt"), track.pt(), centrality); + registry.fill(HIST("PtGenKaVsNchMC_RecoTrk"), particle.pt(), nchF); + registry.fill(HIST("MCclosure_PtKaVsNchMC"), track.pt(), nchF); + } else if (isPr) { + registry.fill(HIST("PtPrVsCent_WithRecoEvt"), track.pt(), centrality); + registry.fill(HIST("PtGenPrVsNchMC_RecoTrk"), particle.pt(), nchF); + registry.fill(HIST("MCclosure_PtPrVsNchMC"), track.pt(), nchF); + } + registry.fill(HIST("PtAllVsCent_WithRecoEvt"), track.pt(), centrality); + registry.fill(HIST("PtGenAllVsNchMC_RecoTrk"), particle.pt(), nchF); + } else { + // Fill secondary particle histograms + registry.fill(HIST("Inclusive/hPtSecReco"), track.pt()); + registry.fill(HIST("Inclusive/hPtSecRecoVsMult"), track.pt(), nchF); + if (isPi) { + registry.fill(HIST("Pion/hPtSecReco"), track.pt()); + registry.fill(HIST("Pion/hPtSecRecoVsMult"), track.pt(), nchF); + } else if (isKa) { + registry.fill(HIST("Kaon/hPtSecReco"), track.pt()); + registry.fill(HIST("Kaon/hPtSecRecoVsMult"), track.pt(), nchF); + } else if (isPr) { + registry.fill(HIST("Proton/hPtSecReco"), track.pt()); + registry.fill(HIST("Proton/hPtSecRecoVsMult"), track.pt(), nchF); + } } - } - if (track.mcParticle().isPhysicalPrimary()) { + // ==================================================================== + // DEDX VS MOMENTUM HISTOGRAMS FILLING - ALL TRACKS + // ==================================================================== + hDedxVspTMomentumVsCent[10]->Fill(track.pt(), tpcSignal, eta); if (charge > 0) { - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri"), eta, track.pt(), momentum); + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Pos"), momentum, tpcSignal, eta); + hDedxVsMomentumVsCentPos[centIndex]->Fill(momentum, tpcSignal, eta); + hDedxVspTMomentumVsCent[centIndex]->Fill(track.pt(), tpcSignal, eta); + hMomentumVsEtaPos[centIndex]->Fill(eta, momentum); + hMomentumVsEtaPos[10]->Fill(eta, momentum); + hpTVsEtaPos[centIndex]->Fill(eta, track.pt()); + hpTVsEtaPos[10]->Fill(eta, track.pt()); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos"), eta, track.pt(), momentum); } else { - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri"), eta, track.pt(), momentum); + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_all_Neg"), momentum, tpcSignal, eta); + hDedxVsMomentumVsCentNeg[centIndex]->Fill(momentum, tpcSignal, eta); + hDedxVspTMomentumVsCent[centIndex]->Fill(track.pt(), tpcSignal, eta); + hMomentumVsEtaNeg[centIndex]->Fill(eta, momentum); + hMomentumVsEtaNeg[10]->Fill(eta, momentum); + hpTVsEtaNeg[centIndex]->Fill(eta, track.pt()); + hpTVsEtaNeg[10]->Fill(eta, track.pt()); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg"), eta, track.pt(), momentum); } - } - if (track.has_mcParticle()) { - const auto& particle = track.mcParticle(); - int pdgCode = std::abs(particle.pdgCode()); - if (particle.isPhysicalPrimary()) { + if (isPrimary) { if (charge > 0) { - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri_MC"), eta, track.pt(), momentum); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri"), eta, track.pt(), momentum); } else { - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri_MC"), eta, track.pt(), momentum); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri"), eta, track.pt(), momentum); } } - if (pdgCode == PDG_t::kPiPlus || pdgCode == PDG_t::kKPlus || pdgCode == PDG_t::kProton || pdgCode == PDG_t::kElectron || pdgCode == PDG_t::kMuonPlus) { - if (particle.isPhysicalPrimary()) { - // Fill total counts for fractions + + // ==================================================================== + // DEDX VS MOMENTUM HISTOGRAMS FILLING - PARTICLE SPECIFIC + // ==================================================================== + if (track.has_mcParticle() && isPrimary) { + int pdgCode = std::abs(particle.pdgCode()); + + if (charge > 0) { + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri_MC"), eta, track.pt(), momentum); + } else { + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri_MC"), eta, track.pt(), momentum); + } + + if (pdgCode == PDG_t::kPiPlus || pdgCode == PDG_t::kKPlus || pdgCode == PDG_t::kProton || + pdgCode == PDG_t::kElectron || pdgCode == PDG_t::kMuonPlus) { if (charge > 0) { - ue.fill(HIST("ParticleFractions/hTotalCountsVsMomentumPos"), eta, momentum); - ue.fill(HIST("ParticleFractions/hTotalCountsVsPtPos"), eta, track.pt()); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri_MC_Part"), eta, track.pt(), momentum); + hTotalMomPosCent[centIndex]->Fill(eta, momentum); + hTotalMomPosCent[10]->Fill(eta, momentum); + hTotalPtPosCent[centIndex]->Fill(eta, track.pt()); + hTotalPtPosCent[10]->Fill(eta, track.pt()); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Pos_Pri_MC_Part"), eta, track.pt(), momentum); } else { - ue.fill(HIST("ParticleFractions/hTotalCountsVsMomentumNeg"), eta, momentum); - ue.fill(HIST("ParticleFractions/hTotalCountsVsPtNeg"), eta, track.pt()); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri_MC_Part"), eta, track.pt(), momentum); + hTotalMomNegCent[centIndex]->Fill(eta, momentum); + hTotalMomNegCent[10]->Fill(eta, momentum); + hTotalPtNegCent[centIndex]->Fill(eta, track.pt()); + hTotalPtNegCent[10]->Fill(eta, track.pt()); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_all_Neg_Pri_MC_Part"), eta, track.pt(), momentum); } } - } - if (pdgCode == PDG_t::kPiPlus) { - ue.fill(HIST("Pion/hPtReco"), track.pt()); - if (particle.isPhysicalPrimary()) { - ue.fill(HIST("Pion/hPtPrimReco"), track.pt()); - ue.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); + if (pdgCode == PDG_t::kPiPlus) { if (charge > 0) { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Pion_Pos"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Pion_Pos"), eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Pos"), momentum, tpcSignal, eta); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pi_Pos"), eta, track.pt(), momentum); + hFracMomPosCent[0][centIndex]->Fill(eta, momentum); + hFracMomPosCent[0][10]->Fill(eta, momentum); + hFracPtPosCent[0][centIndex]->Fill(eta, track.pt()); + hFracPtPosCent[0][10]->Fill(eta, track.pt()); + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Pos"), momentum, tpcSignal, eta); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pi_Pos"), eta, track.pt(), momentum); } else { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Pion_Neg"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Pion_Neg"), eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Neg"), momentum, tpcSignal, eta); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pi_Neg"), eta, track.pt(), momentum); + hFracMomNegCent[0][centIndex]->Fill(eta, momentum); + hFracMomNegCent[0][10]->Fill(eta, momentum); + hFracPtNegCent[0][centIndex]->Fill(eta, track.pt()); + hFracPtNegCent[0][10]->Fill(eta, track.pt()); + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pi_v0_Neg"), momentum, tpcSignal, eta); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pi_Neg"), eta, track.pt(), momentum); } - - } else { - ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); - } - } else if (pdgCode == PDG_t::kKPlus) { - ue.fill(HIST("Kaon/hPtReco"), track.pt()); - if (particle.isPhysicalPrimary()) { - ue.fill(HIST("Kaon/hPtPrimReco"), track.pt()); - ue.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); + } else if (pdgCode == PDG_t::kKPlus) { if (charge > 0) { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Kaon_Pos"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Kaon_Pos"), eta, track.pt()); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_K_Pos"), eta, track.pt(), momentum); + hFracMomPosCent[1][centIndex]->Fill(eta, momentum); + hFracMomPosCent[1][10]->Fill(eta, momentum); + hFracPtPosCent[1][centIndex]->Fill(eta, track.pt()); + hFracPtPosCent[1][10]->Fill(eta, track.pt()); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_K_Pos"), eta, track.pt(), momentum); } else { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Kaon_Neg"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Kaon_Neg"), eta, track.pt()); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_K_Neg"), eta, track.pt(), momentum); + hFracMomNegCent[1][centIndex]->Fill(eta, momentum); + hFracMomNegCent[1][10]->Fill(eta, momentum); + hFracPtNegCent[1][centIndex]->Fill(eta, track.pt()); + hFracPtNegCent[1][10]->Fill(eta, track.pt()); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_K_Neg"), eta, track.pt(), momentum); } - } else { - ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); - } - } else if (pdgCode == PDG_t::kProton) { - ue.fill(HIST("Proton/hPtReco"), track.pt()); - if (particle.isPhysicalPrimary()) { - ue.fill(HIST("Proton/hPtPrimReco"), track.pt()); - ue.fill(HIST("Inclusive/hPtPrimReco"), track.pt()); + } else if (pdgCode == PDG_t::kProton) { if (charge > 0) { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Proton_Pos"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Proton_Pos"), eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Pos"), momentum, tpcSignal, eta); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pr_Pos"), eta, track.pt(), momentum); + hFracMomPosCent[2][centIndex]->Fill(eta, momentum); + hFracMomPosCent[2][10]->Fill(eta, momentum); + hFracPtPosCent[2][centIndex]->Fill(eta, track.pt()); + hFracPtPosCent[2][10]->Fill(eta, track.pt()); + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Pos"), momentum, tpcSignal, eta); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pr_Pos"), eta, track.pt(), momentum); } else { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Proton_Neg"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Proton_Neg"), eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Neg"), momentum, tpcSignal, eta); - ue.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pr_Neg"), eta, track.pt(), momentum); + hFracMomNegCent[2][centIndex]->Fill(eta, momentum); + hFracMomNegCent[2][10]->Fill(eta, momentum); + hFracPtNegCent[2][centIndex]->Fill(eta, track.pt()); + hFracPtNegCent[2][10]->Fill(eta, track.pt()); + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_Pr_v0_Neg"), momentum, tpcSignal, eta); + registry.fill(HIST("ResponseMatrix/heta_vs_pt_vs_p_Pr_Neg"), eta, track.pt(), momentum); } - } else { - ue.fill(HIST("Inclusive/hPtSecReco"), track.pt()); - } - } else if (pdgCode == PDG_t::kElectron) { - if (particle.isPhysicalPrimary()) { + } else if (pdgCode == PDG_t::kElectron) { if (charge > 0) { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Electron_Pos"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Electron_Pos"), eta, track.pt()); - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_El_v0_Pos"), momentum, tpcSignal, eta); + hFracMomPosCent[3][centIndex]->Fill(eta, momentum); + hFracMomPosCent[3][10]->Fill(eta, momentum); + hFracPtPosCent[3][centIndex]->Fill(eta, track.pt()); + hFracPtPosCent[3][10]->Fill(eta, track.pt()); + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_El_v0_Pos"), momentum, tpcSignal, eta); } else { - ue.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_El_v0_Neg"), momentum, tpcSignal, eta); - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Electron_Neg"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Electron_Neg"), eta, track.pt()); + hFracMomNegCent[3][centIndex]->Fill(eta, momentum); + hFracMomNegCent[3][10]->Fill(eta, momentum); + hFracPtNegCent[3][centIndex]->Fill(eta, track.pt()); + hFracPtNegCent[3][10]->Fill(eta, track.pt()); + registry.fill(HIST("DedxVsMomentum/dEdx_vs_Momentum_El_v0_Neg"), momentum, tpcSignal, eta); } - } - } else if (pdgCode == PDG_t::kMuonPlus) { - if (particle.isPhysicalPrimary()) { + } else if (pdgCode == PDG_t::kMuonPlus) { if (charge > 0) { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Muon_Pos"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Muon_Pos"), eta, track.pt()); + hFracMomPosCent[4][centIndex]->Fill(eta, momentum); + hFracMomPosCent[4][10]->Fill(eta, momentum); + hFracPtPosCent[4][centIndex]->Fill(eta, track.pt()); + hFracPtPosCent[4][10]->Fill(eta, track.pt()); } else { - ue.fill(HIST("ParticleFractions/hFractionVsMomentum_Muon_Neg"), eta, momentum); - ue.fill(HIST("ParticleFractions/hFractionVsPt_Muon_Neg"), eta, track.pt()); + hFracMomNegCent[4][centIndex]->Fill(eta, momentum); + hFracMomNegCent[4][10]->Fill(eta, momentum); + hFracPtNegCent[4][centIndex]->Fill(eta, track.pt()); + hFracPtNegCent[4][10]->Fill(eta, track.pt()); } } } - } - if (passesPIDSelection(track, PartPion)) { - ue.fill(HIST("Pion/hPtMeasured"), track.pt()); - if (enablePIDHistograms) { - ue.fill(HIST("Pion/hNsigmaTPC"), track.pt(), track.tpcNSigmaPi()); - } - } + // PID and measured spectra + const int species = bestPIDHypothesis(track); - if (passesPIDSelection(track, PartKaon)) { - ue.fill(HIST("Kaon/hPtMeasured"), track.pt()); - if (enablePIDHistograms) { - ue.fill(HIST("Kaon/hNsigmaTPC"), track.pt(), track.tpcNSigmaKa()); - } - } + registry.fill(HIST("Inclusive/hPtMeasured"), track.pt()); + registry.fill(HIST("Inclusive/hPtMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("Inclusive/hPtMeasuredVsMult"), track.pt(), nchF); - if (passesPIDSelection(track, PartProton)) { - ue.fill(HIST("Proton/hPtMeasured"), track.pt()); - if (enablePIDHistograms) { - ue.fill(HIST("Proton/hNsigmaTPC"), track.pt(), track.tpcNSigmaPr()); + if (species == kPion) { + registry.fill(HIST("PtPiMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("PtPiMeasuredVsNch"), track.pt(), nchF); + registry.fill(HIST("Pion/hPtMeasured"), track.pt()); + registry.fill(HIST("Pion/hPtMeasuredVsMult"), track.pt(), nchF); + if (enablePIDHistograms) { + registry.fill(HIST("Pion/hNsigmaTPC"), track.pt(), track.tpcNSigmaPi()); + } + } else if (species == kKaon) { + registry.fill(HIST("PtKaMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("PtKaMeasuredVsNch"), track.pt(), nchF); + registry.fill(HIST("Kaon/hPtMeasured"), track.pt()); + registry.fill(HIST("Kaon/hPtMeasuredVsMult"), track.pt(), nchF); + if (enablePIDHistograms) { + registry.fill(HIST("Kaon/hNsigmaTPC"), track.pt(), track.tpcNSigmaKa()); + } + } else if (species == kProton) { + registry.fill(HIST("PtPrMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("PtPrMeasuredVsNch"), track.pt(), nchF); + registry.fill(HIST("Proton/hPtMeasured"), track.pt()); + registry.fill(HIST("Proton/hPtMeasuredVsMult"), track.pt(), nchF); + if (enablePIDHistograms) { + registry.fill(HIST("Proton/hNsigmaTPC"), track.pt(), track.tpcNSigmaPr()); + } } + + registry.fill(HIST("PtAllMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("PtAllMeasuredVsNch"), track.pt(), nchF); } + break; } - - ue.fill(HIST("Centrality/hRecoMultVsCent"), cent, nTracksInEvent); } + PROCESS_SWITCH(MultiplicityPt, processSim, "Process MC simulation", true); - for (const auto& mcCollision : mcCollisions) { - int64_t mcCollId = mcCollision.globalIndex(); - - if (reconstructedMCCollisions.find(mcCollId) == reconstructedMCCollisions.end()) - continue; + void processData(CollisionTableData::iterator const& collision, + TrackTableData const& tracks, + BCsRun3 const& bcs) + { + (void)bcs; - auto centIt = mcCollToCentFromReco.find(mcCollId); - if (centIt == mcCollToCentFromReco.end()) - continue; + if (!isEventSelected(collision)) + return; - auto nchIt = mcCollisionToNch.find(mcCollId); - int nGenCharged = (nchIt != mcCollisionToNch.end()) ? nchIt->second : 0; + const float centrality = collision.centFT0M(); - auto particlesInCollision = particles.sliceBy(perMCCol, mcCollId); + float magField = 0; + if (applyPhiCut.value) { + const auto& bc = collision.bc_as(); + magField = getMagneticField(bc.timestamp()); + } - for (const auto& particle : particlesInCollision) { - auto pdgParticle = pdg->GetParticle(particle.pdgCode()); - if (!pdgParticle || pdgParticle->Charge() == 0.) - continue; - if (!particle.isPhysicalPrimary()) - continue; + registry.fill(HIST("hvtxZ"), collision.posZ()); - if (std::abs(particle.eta()) >= cfgCutEtaMax.value) + for (const auto& track : tracks) { + if (track.eta() < cfgCutEtaMin.value || track.eta() > cfgCutEtaMax.value) continue; - if (particle.pt() < cfgTrkLowPtCut.value) + if (track.pt() < cfgTrkLowPtCut.value) continue; - int pdgCode = std::abs(particle.pdgCode()); - float pt = particle.pt(); - - if (pdgCode == PDG_t::kPiPlus) { - ue.fill(HIST("Pion/hPtGenRecoEvent"), pt); - ue.fill(HIST("Pion/hPtGenRecoEvent_Mult"), pt, nGenCharged); - } else if (pdgCode == PDG_t::kKPlus) { - ue.fill(HIST("Kaon/hPtGenRecoEvent"), pt); - ue.fill(HIST("Kaon/hPtGenRecoEvent_Mult"), pt, nGenCharged); - } else if (pdgCode == PDG_t::kProton) { - ue.fill(HIST("Proton/hPtGenRecoEvent"), pt); - ue.fill(HIST("Proton/hPtGenRecoEvent_Mult"), pt, nGenCharged); + if (applyPhiCut.value && track.pt() >= pTthresholdPhiCut.value) { + float phiPrime = getTransformedPhi(track.phi(), track.sign(), magField); + registry.fill(HIST("PhiCut/hPtVsPhiPrimeBefore"), track.pt(), phiPrime); } - } - } - for (const auto& mcCollId : inel0MCCollisions) { - auto centIt = mcCollToCentFromReco.find(mcCollId); - if (centIt != mcCollToCentFromReco.end()) { - float cent = centIt->second; - int nGenCharged = mcCollisionToNch[mcCollId]; - ue.fill(HIST("MC/EventLoss/GenMultVsCent"), cent, nGenCharged); - ue.fill(HIST("hEventsINEL_Cent"), cent); - } - } + if (!passesTrackSelection(track)) + continue; - for (const auto& mcCollId : reconstructedMCCollisions) { - auto centIt = mcCollToCentFromReco.find(mcCollId); - if (centIt != mcCollToCentFromReco.end()) { - ue.fill(HIST("hEventsReco_Cent"), centIt->second); - } - } + if (applyPhiCut.value && !passedPhiCut(track, magField)) + continue; - ue.fill(HIST("hEventLossBreakdown"), 1.f, physicsSelectedMCCollisions.size()); - ue.fill(HIST("hEventLossBreakdown"), 2.f, reconstructedMCCollisions.size()); - ue.fill(HIST("hEventLossBreakdown"), 3.f, selectedMCCollisions.size()); + if (applyPhiCut.value && track.pt() >= pTthresholdPhiCut.value) { + float phiPrime = getTransformedPhi(track.phi(), track.sign(), magField); + registry.fill(HIST("PhiCut/hPtVsPhiPrimeAfter"), track.pt(), phiPrime); + } - ue.fill(HIST("MC/GenRecoCollisions"), 4.f, reconstructedMCCollisions.size()); - ue.fill(HIST("MC/GenRecoCollisions"), 5.f, selectedMCCollisions.size()); + registry.fill(HIST("hEta"), track.eta()); + registry.fill(HIST("hPhi"), track.phi()); + registry.fill(HIST("Inclusive/hPtMeasured"), track.pt()); + registry.fill(HIST("Inclusive/hPtMeasuredVsCent"), track.pt(), centrality); - LOG(info) << "\n=== EVENT STATISTICS ==="; - LOG(info) << "INEL>0 MC collisions: " << inel0MCCollisions.size(); - LOG(info) << "Physics selected MC collisions: " << physicsSelectedMCCollisions.size(); - LOG(info) << "Reconstructed collisions: " << reconstructedMCCollisions.size(); - LOG(info) << "Selected collisions: " << selectedMCCollisions.size(); + const int species = bestPIDHypothesis(track); + if (species == kPion) { + registry.fill(HIST("PtPiMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("Pion/hPtMeasured"), track.pt()); + if (enablePIDHistograms) { + registry.fill(HIST("Pion/hNsigmaTPC"), track.pt(), track.tpcNSigmaPi()); + } + } else if (species == kKaon) { + registry.fill(HIST("PtKaMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("Kaon/hPtMeasured"), track.pt()); + if (enablePIDHistograms) { + registry.fill(HIST("Kaon/hNsigmaTPC"), track.pt(), track.tpcNSigmaKa()); + } + } else if (species == kProton) { + registry.fill(HIST("PtPrMeasuredVsCent"), track.pt(), centrality); + registry.fill(HIST("Proton/hPtMeasured"), track.pt()); + if (enablePIDHistograms) { + registry.fill(HIST("Proton/hNsigmaTPC"), track.pt(), track.tpcNSigmaPr()); + } + } - if (physicsSelectedMCCollisions.size() > 0) { - float efficiency = 100.f * selectedMCCollisions.size() / physicsSelectedMCCollisions.size(); - LOG(info) << "Final efficiency: " << efficiency << "%"; + registry.fill(HIST("PtAllMeasuredVsCent"), track.pt(), centrality); + } } -} + PROCESS_SWITCH(MultiplicityPt, processData, "Process data", false); +}; -void MultiplicityPt::processData(CollisionTableData::iterator const& /*collision*/, - TrackTableData const& /*tracks*/, - BCsRun3 const& /*bcs*/) +// ============================================================ +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { + return WorkflowSpec{adaptAnalysisTask(cfgc)}; } diff --git a/PWGLF/Tasks/Nuspex/nucleiFromHypertritonMap.cxx b/PWGLF/Tasks/Nuspex/nucleiFromHypertritonMap.cxx index 13fadb46a50..5d96a361585 100644 --- a/PWGLF/Tasks/Nuspex/nucleiFromHypertritonMap.cxx +++ b/PWGLF/Tasks/Nuspex/nucleiFromHypertritonMap.cxx @@ -30,12 +30,11 @@ #include #include #include +#include #include #include #include -#include - #include #include #include diff --git a/PWGLF/Tasks/Nuspex/piKpRAA.cxx b/PWGLF/Tasks/Nuspex/piKpRAA.cxx index 89d75b08963..0d47d4cc8e2 100644 --- a/PWGLF/Tasks/Nuspex/piKpRAA.cxx +++ b/PWGLF/Tasks/Nuspex/piKpRAA.cxx @@ -60,6 +60,7 @@ #include #include #include +#include #include #include @@ -70,82 +71,90 @@ using namespace o2::constants::math; using namespace o2::framework::expressions; using namespace o2::aod::rctsel; -using ColEvSels = soa::Join; +using ColEvSels = soa::Join; using BCsRun3 = soa::Join; -using ColEvSelsMC = soa::Join; +using ColEvSelsMC = soa::Join; -using TracksFull = soa::Join; +using TracksFull = soa::Join; using TracksMC = soa::Join; -static constexpr int kNEtaHists{8}; - -std::array, kNEtaHists> dEdxPiV0{}; -std::array, kNEtaHists> dEdxPrV0{}; -std::array, kNEtaHists> dEdxElV0{}; -std::array, kNEtaHists> dEdxPiMC{}; -std::array, kNEtaHists> dEdxMuMC{}; -std::array, kNEtaHists> dEdx{}; -std::array, kNEtaHists> pTVsP{}; -std::array, kNEtaHists> nClVsP{}; -std::array, kNEtaHists> nCrRoVsNcl{}; -std::array, kNEtaHists> nClVsPElV0{}; -std::array, kNEtaHists> nClVsPPiV0{}; -std::array, kNEtaHists> nClVsPPrV0{}; -std::array, kNEtaHists> nClPIDVsnCl{}; -std::array, kNEtaHists> nClVsPp{}; -std::array, kNEtaHists> nCrRoVsNclp{}; -std::array, kNEtaHists> nClVsPpElV0{}; -std::array, kNEtaHists> nClVsPpPiV0{}; -std::array, kNEtaHists> nClVsPpPrV0{}; -std::array, kNEtaHists> nClPIDVsnClp{}; +static constexpr int KnEtaHists{8}; + +std::array, KnEtaHists> dEdxPiTOF{}; +std::array, KnEtaHists> dEdxPiTOF2{}; +std::array, KnEtaHists> dEdxPiV0{}; +std::array, KnEtaHists> dEdxPrV0{}; +std::array, KnEtaHists> dEdxElV0{}; +std::array, KnEtaHists> dEdx{}; +std::array, KnEtaHists> pTVsP{}; +std::array, KnEtaHists> nClVsP{}; +std::array, KnEtaHists> nClVsPElV0{}; +std::array, KnEtaHists> nClVsPPiV0{}; +std::array, KnEtaHists> nClVsPPrV0{}; +std::array, KnEtaHists> nClVsPp{}; +std::array, KnEtaHists> nClVsPpElV0{}; +std::array, KnEtaHists> nClVsPpPiV0{}; +std::array, KnEtaHists> nClVsPpPrV0{}; +std::array, KnEtaHists> etaTest{}; + +template +auto printArray(std::vector const& vec) +{ + std::stringstream ss; + ss << "[" << vec[0]; + for (auto i = 1u; i < vec.size(); ++i) { + ss << ", " << vec[i]; + } + ss << "]"; + return ss.str(); +} struct PiKpRAA { - static constexpr int kZeroInt{0}; - static constexpr int kSevenInt{7}; - - static constexpr float kZero{0.0f}; - static constexpr float kOne{1.0f}; - static constexpr float kTwoPtGeVSel{2.0f}; - static constexpr float kThree{3.0f}; - static constexpr float kTenToMinusNine{1e-9}; - static constexpr float kMinPtNchSel{0.1f}; - static constexpr float kMaxPtNchSel{3.0f}; - static constexpr float kMinCharge{3.f}; - static constexpr float kMinPMIP{0.4f}; - static constexpr float kMaxPMIP{0.6f}; - static constexpr float kMindEdxMIP{40.0f}; - static constexpr float kMaxdEdxMIP{60.0f}; - static constexpr float kMindEdxMIPPlateau{70.0f}; - static constexpr float kMaxdEdxMIPPlateau{90.0f}; - static constexpr float kMinFT0A{3.5f}; - static constexpr float kMaxFT0A{4.9f}; - static constexpr float kMinFT0C{-3.3f}; - static constexpr float kMaxFT0C{-2.1f}; - - static constexpr float kLowEta[kNEtaHists] = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6}; - static constexpr float kHighEta[kNEtaHists] = {-0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}; + static constexpr int KzeroInt{0}; + static constexpr int KsevenInt{7}; + + static constexpr float Kzero{0.0f}; + static constexpr float Kone{1.0f}; + static constexpr float KtwoPtGeVSel{2.0f}; + static constexpr float Kthree{3.0f}; + static constexpr float KtEnToMinusNine{1e-9}; + static constexpr float KminCharge{3.f}; + static constexpr float KminPMIP{0.4f}; + static constexpr float KmaxPMIP{0.6f}; + static constexpr float KmindEdxMIP{40.0f}; + static constexpr float KmaxdEdxMIP{60.0f}; + static constexpr float KmindEdxMIPPlateau{70.0f}; + static constexpr float KmaxdEdxMIPPlateau{90.0f}; + static constexpr float KminFT0A{3.5f}; + static constexpr float KmaxFT0A{4.9f}; + static constexpr float KminFT0C{-3.3f}; + static constexpr float KmaxFT0C{-2.1f}; static constexpr float DefaultLifetimeCuts[1][2] = {{30., 20.}}; Configurable> lifetimecut{"lifetimecut", {DefaultLifetimeCuts[0], 2, {"lifetimecutLambda", "lifetimecutK0S"}}, "lifetimecut"}; struct : ConfigurableGroup { - Configurable minEta{"minEta", -0.8, "Daughter minimum-eta selection"}; - Configurable maxEta{"maxEta", +0.8, "Daughter maximum-eta selection"}; + Configurable minEta{"minEta", -0.8, "minimum eta selection"}; + Configurable maxEta{"maxEta", +0.8, "maximum eta selection"}; Configurable minPt{"minPt", 0.1, "minimum pt of the tracks"}; Configurable maxPt{"maxPt", 10000000000.0, "maximum pt of the tracks"}; Configurable nSigmaDCAxy{"nSigmaDCAxy", 1.0, "nSigma DCAxy selection"}; Configurable nSigmaDCAz{"nSigmaDCAz", 1.0, "nSigma DCAz selection"}; Configurable minNCrossedRows{"minNCrossedRows", 70, "minimum number of crossed rows"}; - Configurable minNcls{"minNcls", 135, "minimum number of clusters for primary-particle selection"}; + Configurable minNcl{"minNcl", 135, "minimum number of clusters for primary-particle selection"}; Configurable minNClusITS{"minNClusITS", 7, "minimum number of ITS clusters"}; Configurable minChi2ClsTPC{"minChi2ClsTPC", 0.5, "Max chi2 per Cls TPC"}; Configurable maxChi2ClsTPC{"maxChi2ClsTPC", 4.0, "Max chi2 per Cls TPC"}; Configurable chi2ClsITS{"chi2ClsITS", 36.0, "chi2 per Cls ITS selection"}; Configurable maxElTOFBeta{"maxElTOFBeta", 0.1, "Maximum beta TOF selection"}; + Configurable maxPiTOFBeta{"maxPiTOFBeta", 0.005, "Maximum beta TOF selection for Pions"}; + // Configurable maxKaTOFBeta{"maxKaTOFBeta", 0.001, "Maximum beta TOF selection for Kaons"}; + // Configurable maxPrTOFBeta{"maxPrTOFBeta", 0.001, "Maximum beta TOF selection for Protons"}; + Configurable nSigmaPIDselPrim{"nSigmaPIDselPrim", 1.0, "N sigma selection for primary pions with TOF"}; // Phi cut Configurable applyPhiCut{"applyPhiCut", false, "Apply geometrical cut?"}; @@ -162,8 +171,9 @@ struct PiKpRAA { Configurable useTPCNsigma{"useTPCNsigma", false, "Include TPC Nsigma selection on decay products"}; // Selection criteria: acceptance - Configurable rapidityCut{"rapidityCut", 0.5, "rapidity"}; - Configurable minNcl{"minNcl", 135, "minimum number of clusters for V0 daughters"}; + Configurable minY{"minY", -0.1, "minimum rapidity selection"}; + Configurable maxY{"maxY", 0.8, "maximum rapidity selection"}; + Configurable minNclV0Daugther{"minNclV0Daugther", 135, "minimum number of clusters for V0 daughters"}; Configurable nSharedClusTpc{"nSharedClusTpc", 5, "maximum number of shared clusters"}; // Standard 5 topological criteria @@ -188,13 +198,12 @@ struct PiKpRAA { // Selection Configurable applyInvMassSel{"applyInvMassSel", true, "Select V0s close to the Inv. mass value"}; - Configurable selElecFromGammas{"selElecFromGammas", true, "track selection for electrons"}; Configurable dMassSel{"dMassSel", 0.01f, "Invariant mass selection"}; Configurable dMassSelG{"dMassSelG", 0.1f, "Inv mass selection gammas"}; // PID (TPC/TOF) Configurable dEdxPlateauSel{"dEdxPlateauSel", 50, "dEdx selection for electrons"}; - Configurable pidNsigmaCut{"pidNsigmaCut", 3.0, "pidNsigmaCut"}; + Configurable pidNsigmaCut{"pidNsigmaCut", 3.0, "N sigma selection for V0 daughters"}; } v0Selections; // Configurables Event Selection @@ -210,7 +219,7 @@ struct PiKpRAA { Configurable isCentSel{"isCentSel", true, "Centrality selection?"}; Configurable selHasBC{"selHasBC", true, "Has BC?"}; Configurable selHasFT0{"selHasFT0", true, "Has FT0?"}; - Configurable isT0Ccent{"isT0Ccent", true, "Use T0C-based centrality?"}; + Configurable centralitySelector{"centralitySelector", "FT0C", "which centrality selector?"}; Configurable useSel8{"useSel8", false, "Use sel8?"}; Configurable selTriggerTVX{"selTriggerTVX", true, "selTriggerTVX?"}; @@ -225,18 +234,15 @@ struct PiKpRAA { // Event selection Configurable posZcut{"posZcut", +10.0, "z-vertex position cut"}; - Configurable minT0CcentCut{"minT0CcentCut", 0.0, "Min T0C Cent. cut"}; - Configurable maxT0CcentCut{"maxT0CcentCut", 100.0, "Max T0C Cent. cut"}; + Configurable minCentCut{"minCentCut", 0.0, "Min Cent. cut"}; + Configurable maxCentCut{"maxCentCut", 100.0, "Max Cent. cut"}; Configurable minOccCut{"minOccCut", 0., "min Occu cut"}; Configurable maxOccCut{"maxOccCut", 500., "max Occu cut"}; - Configurable nSigmaNchCut{"nSigmaNchCut", 3., "nSigma Nch selection"}; Configurable tpcNchAcceptance{"tpcNchAcceptance", 0.5, "Eta window to measure Nch MC for Nch vs Cent distribution"}; - ConfigurableAxis binsPtPhiCut{"binsPtPhiCut", {VARIABLE_WIDTH, 0.0, 0.6, 0.8, 1.0, 1.4, 1.8, 2.2, 2.6, 3.0, 3.5, 4.0, 5.0, 7.0, 10.0, 15.0, 20.0, 25.0, 30.0, 40.0, 45.0, 50.0}, "pT"}; ConfigurableAxis binsPtV0s{"binsPtV0s", {VARIABLE_WIDTH, 0, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.2, 1.4, 1.6, 1.8, 2, 2.5, 3.0, 3.5, 4, 5, 7, 9, 12, 15, 20}, "pT"}; - ConfigurableAxis binsPtNcl{"binsPtNcl", {VARIABLE_WIDTH, 0.0, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, 7.0, 9.0, 12.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0}, "pT"}; ConfigurableAxis binsPt{"binsPt", {VARIABLE_WIDTH, 0.0, 0.1, 0.12}, "pT binning"}; - ConfigurableAxis binsCent{"binsCent", {VARIABLE_WIDTH, 0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100.}, "T0C binning"}; + ConfigurableAxis binsCent{"binsCent", {VARIABLE_WIDTH, 0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100.}, "Centrality bins"}; ConfigurableAxis binsZpos{"binsZpos", {60, -30.0, 30.0}, "Z pos axis"}; ConfigurableAxis axisEta{"axisEta", {50, -1.0, 1.0}, "Eta axis"}; ConfigurableAxis axisY{"axisY", {50, -1.0, 1.0}, "rapidity axis"}; @@ -249,12 +255,13 @@ struct PiKpRAA { ConfigurableAxis axisdEdx{"axisdEdx", {140, 20.0, 160.0}, "dEdx binning"}; ConfigurableAxis axisDCAxy{"axisDCAxy", {105, -1.05f, 1.05f}, "DCAxy axis"}; ConfigurableAxis axisPtFineFixedWidth{"axisPtFineFixedWidth", {250, 0.1f, 20.1f}, "DCAxy axis"}; - Configurable nBinsNch{"nBinsNch", 400, "N bins Nch (|eta|<0.8)"}; - Configurable nBinsNPV{"nBinsNPV", 600, "N bins ITS tracks"}; - Configurable minNch{"minNch", 0, "Min Nch (|eta|<0.8)"}; - Configurable maxNch{"maxNch", 400, "Max Nch (|eta|<0.8)"}; - Configurable minNpv{"minNpv", 0, "Min NPV"}; - Configurable maxNpv{"maxNpv", 600, "Max NPV"}; + ConfigurableAxis axisNPV{"axisNPV", {600, 0.0f, 600.0f}, "Number of Primary Vertex Contributors"}; + ConfigurableAxis axisNch{"axisNch", {400, 0.0f, 400.0f}, "N_{ch} Multiplicity"}; + + Configurable> vecLowEta{"vecLowEta", {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6}, "lower eta cuts"}; + Configurable> vecUpEta{"vecUpEta", {-0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}, "upper eta cuts"}; + Configurable> vecEndingEta{"vecEndingEta", {"86", "64", "42", "20", "02", "24", "46", "68"}, "string representing names for histogram distiction"}; + Configurable> vecLatexEta{"vecLatexEta", {"-0.8<#eta<-0.6", "-0.6<#eta<-0.4", "-0.4<#eta<-0.2", "-0.2<#eta< 0", "0<#eta<0.2", "0.2<#eta<0.4", "0.4<#eta< 0.6", "0.6<#eta< 0.8"}, "string representing an eta interval"}; // CCDB paths Configurable pathDCAxy{"pathDCAxy", "Users/o/omvazque/DCAxy/Test", "base path to the ccdb object"}; @@ -340,41 +347,6 @@ struct PiKpRAA { bool isCalPlateauLoaded = false; } etaCal; - // TrackSelection trkSelGlobalOpenDCAxy; - // TrackSelection trkSelGlobal; - - // TrackSelection trkSelOpenDCAxy() { - // TrackSelection selectedTracks; - // selectedTracks.SetTrackType(o2::aod::track::TrackTypeEnum::Track); // Run 3 track asked by default - // // selectedTracks.SetPtRange(trackSelections.minPt, trackSelections.maxPt); - // // selectedTracks.SetEtaRange(trackSelections.minEta, trackSelections.maxEta); - // // selectedTracks.SetRequireITSRefit(trackSelections.itsRefit); - // // selectedTracks.SetRequireTPCRefit(trackSelections.tpcRefit); - // // selectedTracks.SetRequireGoldenChi2(trackSelections.chi2Golden); - // // selectedTracks.SetMinNCrossedRowsTPC(trackSelections.minNCrossedRows); - // // selectedTracks.SetMinNCrossedRowsOverFindableClustersTPC(trackSelections.minNCrossedRowsOverFindableCls); - // // selectedTracks.SetRequireHitsInITSLayers(1, {0, 1, 2}); // one hit in any layer of the inner barrel - // // selectedTracks.SetMaxDcaZ(trackSelections.maxDCAZ); - // return selectedTracks; - // } - - // TrackSelection trkSelGlb() { - // TrackSelection selectedTracks; - // selectedTracks.SetTrackType(o2::aod::track::TrackTypeEnum::Track); // Run 3 track asked by default - // // selectedTracks.SetPtRange(trackSelections.minPt, trackSelections.maxPt); - // // selectedTracks.SetEtaRange(trackSelections.minEta, trackSelections.maxEta); - // // selectedTracks.SetRequireITSRefit(trackSelections.itsRefit); - // // selectedTracks.SetRequireTPCRefit(trackSelections.tpcRefit); - // // selectedTracks.SetRequireGoldenChi2(trackSelections.chi2Golden); - // // selectedTracks.SetMinNCrossedRowsTPC(trackSelections.minNCrossedRows); - // // selectedTracks.SetMinNCrossedRowsOverFindableClustersTPC(trackSelections.minNCrossedRowsOverFindableCls); - // // selectedTracks.SetRequireHitsInITSLayers(1, {0, 1, 2}); // one hit in any layer of the inner barrel - // // selectedTracks.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / pow(pt, 1.1f); }); - // // selectedTracks.SetMaxDcaZ(trackSelections.maxDCAZ); - // return selectedTracks; - // } - - int currentRunNumberNchSel; int currentRunNumberPhiSel; void init(InitContext const&) { @@ -384,10 +356,7 @@ struct PiKpRAA { rctChecker.init(rctLabel.value, rctCheckZDC.value, rctTreatLimitedAcceptanceAsBad.value); } - currentRunNumberNchSel = -1; currentRunNumberPhiSel = -1; - // trkSelGlobalOpenDCAxy = trkSelOpenDCAxy(); - // trkSelGlobal = trkSelGlb(); // define axes you want to use const std::string titlePorPTPC{trackSelections.usePinPhiSelection ? "#it{p} (GeV/#it{c})" : "#it{p} inner TPC wall (GeV/#it{c})"}; @@ -396,25 +365,25 @@ struct PiKpRAA { const AxisSpec axisNcl{161, -0.5, 160.5, "#it{N}_{cl}"}; const AxisSpec axisPt{binsPt, "#it{p}_{T} (GeV/#it{c})"}; const AxisSpec axisPtV0s{binsPtV0s, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec axisPtNcl{binsPtNcl, titlePorPTPC.data()}; - const AxisSpec axisXPhiCut{binsPtPhiCut, titlePorPTPC.data()}; const AxisSpec axisCent{binsCent, "Centrality Perc."}; - const char* endingEta[kNEtaHists] = {"86", "64", "42", "20", "02", "24", "46", "68"}; - const char* latexEta[kNEtaHists] = {"-0.8<#eta<-0.6", "-0.6<#eta<-0.4", "-0.4<#eta<-0.2", "-0.2<#eta<0", "0<#eta<0.2", "0.2<#eta<0.4", "0.4<#eta<0.6", "0.6<#eta<0.8"}; + const auto latexEta = (std::vector)vecLatexEta; + const auto endingEta = (std::vector)vecEndingEta; registry.add("EventCounter", ";;Events", kTH1F, {axisEvent}); registry.add("HasBCVsFT0VsTVXVsEvSel", "Alls=1 | BC=2 | FT0=3 | TVX=4 | EvSel=5;;", kTH1F, {{5, 0.5, 5.5}}); registry.add("zPos", "With Event Selection;;Entries;", kTH1F, {axisZpos}); - registry.add("T0Ccent", ";;Entries", kTH1F, {axisCent}); + registry.add("Centrality", ";;Entries", kTH1F, {axisCent}); registry.add("RCTSel", "Event accepted if flag=false: All=1 | RTC sel=2;;;", kTH1F, {{2, 0.5, 2.5}}); - registry.add("T0CcentVsRCTSel", "Event accepted if flag=false;;RCT Status;", kTH2F, {{{axisCent}, {9, 0.5, 9.5}}}); - registry.add("T0CcentVsFoundFT0", "Found(=1.5) NOT Found(=0.5);;Status;", kTH2F, {{{axisCent}, {2, 0, 2}}}); - registry.add("T0CcentVsBCVsFT0VsTVXVsEvSel", "All=1 | BC=2 | FT0=3 | TVX=4 | EvSel=5;;Status;", kTH2F, {{axisCent}, {5, 0.5, 5.5}}); - registry.add("NchVsCent", "Measured Nch v.s. Centrality (At least Once Rec. Coll. + Sel. criteria);;Nch", kTH2F, {{axisCent, {nBinsNch, minNch, maxNch}}}); - registry.add("NclVsEtaPID", ";#eta;Ncl used for PID", kTH2F, {axisEta, axisNcl}); - registry.add("NclVsEtaPIDp", ";#eta;#LTNcl#GT used for PID", kTProfile, {axisEta}); - registry.add("NclVsEta", ";#eta;Found Ncl TPC", kTH2F, {axisEta, axisNcl}); - registry.add("NclVsEtap", ";#eta;Found #LTNcl#GT TPC", kTProfile, {axisEta}); + registry.add("CentralityVsRCTSel", "Event accepted if flag=false;;RCT Status;", kTH2F, {{{axisCent}, {9, 0.5, 9.5}}}); + registry.add("CentralityVsFoundFT0", "Found(=1.5) NOT Found(=0.5);;Status;", kTH2F, {{{axisCent}, {2, 0, 2}}}); + registry.add("NchVsCent", "Measured Nch v.s. Centrality (At least Once Rec. Coll. + Sel. criteria);;Nch", kTH2F, {axisCent, axisNch}); + registry.add("NclVsEtaPID", "", kTH2F, {axisEta, axisNcl}); + registry.add("NclVsEtaPIDp", "", kTProfile, {axisEta}); + registry.add("NclVsEta", "", kTH2F, {axisEta, axisNcl}); + registry.add("NclVsEtap", "", kTProfile, {axisEta}); + registry.add("NclVsPhiHist", "", kTH2F, {{100, 0, o2::constants::math::TwoPI}, {axisNcl}}); + registry.add("NclVsPhiProfile", "", kTProfile, {{100, 0, o2::constants::math::TwoPI}}); + registry.add("EtaVsPhi", ";#eta;#varphi;", kTH2F, {{axisEta}, {100, 0, o2::constants::math::TwoPI}}); registry.add("MomentumTPCVsP", ";Global track momentum (GeV/#it{c});Momentum at inner wall of the TPC (GeV/#it{c});", kTH2F, {axisPtV0s, axisPtV0s}); registry.add("DCAxyVsPt", ";#it{p}_{T} (GeV/#it{c});DCA_{xy} (cm);", kTH2F, {{axisPtFineFixedWidth}, {axisDCAxy}}); registry.add("DCAzVsPt", ";#it{p}_{T} (GeV/#it{c});DCA_{z} (cm);", kTH2F, {{axisPtFineFixedWidth}, {axisDCAxy}}); @@ -448,7 +417,7 @@ struct PiKpRAA { x->SetBinLabel(19, "Nch Sel."); x->SetBinLabel(20, "INEL > 0"); - auto hrct = registry.get(HIST("T0CcentVsRCTSel")); + auto hrct = registry.get(HIST("CentralityVsRCTSel")); auto* y = hrct->GetYaxis(); y->SetBinLabel(1, "All"); y->SetBinLabel(2, "kFT0Bad"); @@ -461,7 +430,7 @@ struct PiKpRAA { y->SetBinLabel(9, "kTPCLimAccMCRepr"); if (doprocessCalibrationAndV0s) { - registry.add("NchVsNPV", ";Nch; NPV;", kTH2F, {{{nBinsNPV, minNpv, maxNpv}, {nBinsNch, minNch, maxNch}}}); + registry.add("NchVsNPV", ";Nch; NPV;", kTH2F, {axisNPV, axisNch}); registry.add("V0sCounter", ";V0 type; Entries;", kTH1F, {{4, 0.5, 4.5}}); registry.add("dcaDauVsPt", ";V0 #it{p}_{T} (GeV/#it{c});DCA_{xy} (cm) daughters;", kTH2F, {axisPt, axisDCAxy}); registry.add("nSigPiFromK0s", ";#it{n#sigma};;", kTH2F, {axisPtV0s, axisNsigmaTPC}); @@ -481,8 +450,8 @@ struct PiKpRAA { registry.add("MassLVsPt", ";;Inv. Mass (GeV/#it{c}^{2});", kTH2F, {axisPtV0s, axisLambdaMass}); registry.add("MassALVsPt", ";;Inv. Mass (GeV/#it{c}^{2});", kTH2F, {axisPtV0s, axisLambdaMass}); registry.add("MassGVsPt", ";;Inv. Mass (GeV/#it{c}^{2});", kTH2F, {axisPtV0s, axisGammaMass}); - registry.add("NclVsPhip", Form("Found #LTNcl#GT TPC;%s (GeV/#it{c});#varphi", titlePorPTPC.data()), kTProfile2D, {{{axisXPhiCut}, {350, 0.0, 0.35}}}); - registry.add("NclPIDVsPhip", Form("#LTNcl#GT used for PID;%s (GeV/#it{c});#varphi", titlePorPTPC.data()), kTProfile2D, {{{axisXPhiCut}, {350, 0.0, 0.35}}}); + registry.add("NclVsPhip", Form("Found #LTNcl#GT TPC;%s (GeV/#it{c});#varphi", titlePorPTPC.data()), kTProfile2D, {{{axisPt}, {350, 0.0, 0.35}}}); + registry.add("NclPIDVsPhip", Form("#LTNcl#GT used for PID;%s (GeV/#it{c});#varphi", titlePorPTPC.data()), kTProfile2D, {{{axisPt}, {350, 0.0, 0.35}}}); registry.add("NclVsEtaPiMIP", "MIP #pi^{+} + #pi^{-}: 0.4 < #it{p} < 0.6 [GeV/#it{c}], 40 < dE/dx < 60;#eta;Ncl TPC", kTH2F, {{{axisEta}, {161, -0.5, 160.5}}}); registry.add("NclVsEtaPiMIPp", "MIP #pi^{+} + #pi^{-}: 0.4 < #it{p} < 0.6 [GeV/#it{c}], 40 < dE/dx < 60;#eta;#LTNcl#GT TPC", kTProfile, {axisEta}); registry.add("NclVsEtaPiV0", ";#eta;Ncl TPC", kTH2F, {axisEta, axisNcl}); @@ -491,7 +460,6 @@ struct PiKpRAA { registry.add("NclVsEtaPrV0p", ";#eta;#LTNcl#GT TPC", kTProfile, {axisEta}); registry.add("NclVsEtaElV0", ";#eta;Ncl TPC", kTH2F, {axisEta, axisNcl}); registry.add("NclVsEtaElV0p", ";#eta;#LTNcl#GT TPC", kTProfile, {axisEta}); - registry.add("EtaVsPhi", ";#eta;#varphi;", kTH2F, {{axisEta}, {100, 0, o2::constants::math::TwoPI}}); registry.add("EtaVsYK0s", ";#eta;#it{y};", kTH2F, {axisEta, axisY}); registry.add("EtaVsYPiL", ";#eta;#it{y};", kTH2F, {axisEta, axisY}); registry.add("EtaVsYPrL", ";#eta;#it{y};", kTH2F, {axisEta, axisY}); @@ -511,24 +479,23 @@ struct PiKpRAA { registry.add("dEdxVsEtaElMIPV0p", "e^{+} + e^{-}: 0.4 <#it{p}_{T} < 0.6 [GeV/#it{c}];#eta; #LTdE/dx#GT", kTProfile, {axisEta}); registry.add("pTVsCent", "", kTH2F, {axisPt, axisCent}); - for (int i = 0; i < kNEtaHists; ++i) { - dEdx[i] = registry.add(Form("dEdx_%s", endingEta[i]), Form("%s;Momentum (GeV/#it{c});dE/dx;", latexEta[i]), kTH3F, {axisPt, axisdEdx, axisCent}); - pTVsP[i] = registry.add(Form("pTVsP_%s", endingEta[i]), Form("%s;Momentum (GeV/#it{c});#it{p}_{T} (GeV/#it{c});", latexEta[i]), kTH2F, {axisPt, axisPt}); - dEdxPiV0[i] = registry.add(Form("dEdxPiV0_%s", endingEta[i]), Form("#pi^{+} + #pi^{-}, %s;Momentum (GeV/#it{c});dE/dx;", latexEta[i]), kTH2F, {axisPtV0s, axisdEdx}); - dEdxPrV0[i] = registry.add(Form("dEdxPrV0_%s", endingEta[i]), Form("p + #bar{p}, %s;Momentum (GeV/#it{c});dE/dx;", latexEta[i]), kTH2F, {axisPtV0s, axisdEdx}); - dEdxElV0[i] = registry.add(Form("dEdxElV0_%s", endingEta[i]), Form("e^{+} + e^{-}, %s;Momentum (GeV/#it{c});dE/dx;", latexEta[i]), kTH2F, {axisPtV0s, axisdEdx}); - nClVsP[i] = registry.add(Form("NclVsPPrimaries_%s", endingEta[i]), Form("%s;;Ncl TPC", latexEta[i]), kTH2F, {axisPtNcl, axisNcl}); - nClPIDVsnCl[i] = registry.add(Form("NclPIDVsNcl_%s", endingEta[i]), Form("Primaries, %s;;", latexEta[i]), kTH2F, {axisNcl, axisNcl}); - nCrRoVsNcl[i] = registry.add(Form("NCrRoVsNcl_%s", endingEta[i]), Form("%s;;N Crossed Rows", latexEta[i]), kTH2F, {axisNcl, axisNcl}); - nClVsPElV0[i] = registry.add(Form("NclVsPElV0_%s", endingEta[i]), Form("%s;;Ncl TPC", latexEta[i]), kTH2F, {axisPtNcl, axisNcl}); - nClVsPPiV0[i] = registry.add(Form("NclVsPPiV0_%s", endingEta[i]), Form("%s;;Ncl TPC", latexEta[i]), kTH2F, {axisPtNcl, axisNcl}); - nClVsPPrV0[i] = registry.add(Form("NclVsPPrV0_%s", endingEta[i]), Form("%s;;Ncl TPC", latexEta[i]), kTH2F, {axisPtNcl, axisNcl}); - nClVsPp[i] = registry.add(Form("NclVsPrimariesp_%s", endingEta[i]), Form("%s;;#LT#it{N}_{cl}#GT TPC", latexEta[i]), kTProfile, {axisPtNcl}); - nCrRoVsNclp[i] = registry.add(Form("NCrRoVsNclp_%s", endingEta[i]), Form("%s;;#LT#it{N}_{cro rows}#GT TPC", latexEta[i]), kTProfile, {axisNcl}); - nClVsPpElV0[i] = registry.add(Form("NclVsPElV0p_%s", endingEta[i]), Form("%s;;#LT#it{N}_{cl}#GT TPC", latexEta[i]), kTProfile, {axisPtNcl}); - nClVsPpPiV0[i] = registry.add(Form("NclVsPPiV0p_%s", endingEta[i]), Form("%s;;#LT#it{N}_{cl}#GT TPC", latexEta[i]), kTProfile, {axisPtNcl}); - nClVsPpPrV0[i] = registry.add(Form("NclVsPPrV0p_%s", endingEta[i]), Form("%s;;#LT#it{N}_{cl}#GT TPC", latexEta[i]), kTProfile, {axisPtNcl}); - nClPIDVsnClp[i] = registry.add(Form("NclPIDVsNclp_%s", endingEta[i]), Form("%s;;#LT#it{N}_{cl} PID#GT TPC", latexEta[i]), kTProfile, {axisNcl}); + for (int i = 0; i < KnEtaHists; ++i) { + dEdx[i] = registry.add(Form("dEdx_%s", endingEta[i].c_str()), Form("%s;Momentum;dE/dx;", latexEta[i].c_str()), kTH3F, {axisPt, axisdEdx, axisCent}); + pTVsP[i] = registry.add(Form("pTVsP_%s", endingEta[i].c_str()), Form("%s;Momentum;#it{p}_{T} (GeV/#it{c});", latexEta[i].c_str()), kTH2F, {axisPt, axisPt}); + dEdxPiTOF[i] = registry.add(Form("dEdxPiTOF_%s", endingEta[i].c_str()), Form("#pi^{+} + #pi^{-}, %s;Momentum;dE/dx;", latexEta[i].c_str()), kTH2F, {axisPtV0s, axisdEdx}); + dEdxPiTOF2[i] = registry.add(Form("dEdxPiTOF2_%s", endingEta[i].c_str()), Form("#pi^{+} + #pi^{-}, %s;Momentum;dE/dx;", latexEta[i].c_str()), kTH2F, {axisPtV0s, axisdEdx}); + dEdxPiV0[i] = registry.add(Form("dEdxPiV0_%s", endingEta[i].c_str()), Form("#pi^{+} + #pi^{-}, %s;Momentum;dE/dx;", latexEta[i].c_str()), kTH2F, {axisPtV0s, axisdEdx}); + dEdxPrV0[i] = registry.add(Form("dEdxPrV0_%s", endingEta[i].c_str()), Form("p + #bar{p}, %s;Momentum;dE/dx;", latexEta[i].c_str()), kTH2F, {axisPtV0s, axisdEdx}); + dEdxElV0[i] = registry.add(Form("dEdxElV0_%s", endingEta[i].c_str()), Form("e^{+} + e^{-}, %s;Momentum;dE/dx;", latexEta[i].c_str()), kTH2F, {axisPtV0s, axisdEdx}); + nClVsP[i] = registry.add(Form("NclVsPPrimaries_%s", endingEta[i].c_str()), Form("%s;;Ncl TPC", latexEta[i].c_str()), kTH2F, {axisPtV0s, axisNcl}); + nClVsPElV0[i] = registry.add(Form("NclVsPElV0_%s", endingEta[i].c_str()), Form("%s;;Ncl TPC", latexEta[i].c_str()), kTH2F, {axisPtV0s, axisNcl}); + nClVsPPiV0[i] = registry.add(Form("NclVsPPiV0_%s", endingEta[i].c_str()), Form("%s;;Ncl TPC", latexEta[i].c_str()), kTH2F, {axisPtV0s, axisNcl}); + nClVsPPrV0[i] = registry.add(Form("NclVsPPrV0_%s", endingEta[i].c_str()), Form("%s;;Ncl TPC", latexEta[i].c_str()), kTH2F, {axisPtV0s, axisNcl}); + nClVsPp[i] = registry.add(Form("NclVsPrimariesp_%s", endingEta[i].c_str()), Form("%s;;#LT#it{N}_{cl}#GT TPC", latexEta[i].c_str()), kTProfile, {axisPtV0s}); + nClVsPpElV0[i] = registry.add(Form("NclVsPElV0p_%s", endingEta[i].c_str()), Form("%s;;#LT#it{N}_{cl}#GT TPC", latexEta[i].c_str()), kTProfile, {axisPtV0s}); + nClVsPpPiV0[i] = registry.add(Form("NclVsPPiV0p_%s", endingEta[i].c_str()), Form("%s;;#LT#it{N}_{cl}#GT TPC", latexEta[i].c_str()), kTProfile, {axisPtV0s}); + nClVsPpPrV0[i] = registry.add(Form("NclVsPPrV0p_%s", endingEta[i].c_str()), Form("%s;;#LT#it{N}_{cl}#GT TPC", latexEta[i].c_str()), kTProfile, {axisPtV0s}); + etaTest[i] = registry.add(Form("etaTest_%s", endingEta[i].c_str()), ";Eta;Entries;", kTH1F, {axisEta}); } } @@ -538,12 +505,13 @@ struct PiKpRAA { registry.add("dcaVsPtPrDec", "Secondary protons from decays;#it{p}_{T} (GeV/#it{c});DCA_{xy} (cm);Centrality Perc.;", kTH3F, {axisPt, axisDCAxy, axisCent}); registry.add("dcaVsPtPiMat", "Secondary pions from material interactions;#it{p}_{T} (GeV/#it{c});DCA_{xy} (cm);Centrality Perc.;", kTH3F, {axisPt, axisDCAxy, axisCent}); registry.add("dcaVsPtPrMat", "Secondary protons from material interactions;#it{p}_{T} (GeV/#it{c});DCA_{xy} (cm);Centrality Perc.;", kTH3F, {axisPt, axisDCAxy, axisCent}); - } + registry.add("DCAxyVsPtWithSelection", ";#it{p}_{T} (GeV/#it{c});DCA_{xy} (cm);", kTH2F, {{axisPtFineFixedWidth}, {axisDCAxy}}); + registry.add("DCAzVsPtWithSelection", ";#it{p}_{T} (GeV/#it{c});DCA_{z} (cm);", kTH2F, {{axisPtFineFixedWidth}, {axisDCAxy}}); - if (doprocessSim) { + registry.add("CentralityVsBCVsFT0VsTVXVsEvSel", "All=1 | BC=2 | FT0=3 | TVX=4 | EvSel=5;;Status;", kTH2F, {{axisCent}, {5, 0.5, 5.5}}); // MC events passing the TVX requirement - registry.add("NchMCcentVsTVX", ";Passed(=1.5) NOT Passed(=0.5);", kTH2F, {{{nBinsNch, minNch, maxNch}, {2, 0, 2}}}); + registry.add("NchMCcentVsTVX", ";Passed(=1.5) NOT Passed(=0.5);", kTH2F, {axisNch, {2, 0, 2}}); registry.add("NumberOfRecoCollisions", "Number of times Gen. Coll.are reconstructed;N;Entries", kTH1F, {{10, -0.5, 9.5}}); @@ -565,11 +533,11 @@ struct PiKpRAA { registry.add("PtPrVsCentMC_WithRecoEvt", "Generated Events With at least One Rec. Collision;;;", kTH2F, {axisPt, axisCent}); // Needed for the Gen. Nch to Centrality conversion - registry.add("NchMCVsCent", "Generated Nch v.s. Centrality (At least Once Rec. Coll. + Sel. criteria);;Gen. Nch MC (|#eta|<0.8)", kTH2F, {{axisCent, {nBinsNch, minNch, maxNch}}}); + registry.add("NchMCVsCent", "Generated Nch v.s. Centrality (At least Once Rec. Coll. + Sel. criteria);;Gen. Nch MC", kTH2F, {axisCent, axisNch}); // Needed to measure Event Loss - registry.add("NchMC_WithRecoEvt", "Generated Nch of Evts With at least one Rec. Coll. + Sel. criteria;Gen. Nch MC (|#eta|<0.8);Entries", kTH1F, {{nBinsNch, minNch, maxNch}}); - registry.add("NchMC_AllGen", "Generated Nch of All Gen. Evts.;Gen. Nch;Entries", kTH1F, {{nBinsNch, minNch, maxNch}}); + registry.add("NchMC_WithRecoEvt", "Generated Nch of Evts With at least one Rec. Coll. + Sel. criteria;Gen. Nch MC;Entries", kTH1F, {axisNch}); + registry.add("NchMC_AllGen", "Generated Nch of All Gen. Evts.;Gen. Nch;Entries", kTH1F, {axisNch}); // Needed to measure Event Splitting registry.add("Centrality_WRecoEvt", "Generated Events With at least One Rec. Collision And NO Sel. criteria;;Entries", kTH1F, {axisCent}); @@ -577,34 +545,29 @@ struct PiKpRAA { registry.add("Centrality_AllRecoEvt", "Generated Events Irrespective of the number of times it was reconstructed + Evt. Selections;;Entries", kTH1F, {axisCent}); // Needed to calculate the numerator of the Signal Loss correction - registry.add("PtPiVsNchMC_WithRecoEvt", "Generated Events With at least One Rec. Collision;;Gen. Nch (|#eta|<0.8);", kTH2F, {{axisPt, {nBinsNch, minNch, maxNch}}}); - registry.add("PtKaVsNchMC_WithRecoEvt", "Generated Events With at least One Rec. Collision;;Gen. Nch (|#eta|<0.8);", kTH2F, {{axisPt, {nBinsNch, minNch, maxNch}}}); - registry.add("PtPrVsNchMC_WithRecoEvt", "Generated Events With at least One Rec. Collision;;Gen. Nch (|#eta|<0.8);", kTH2F, {{axisPt, {nBinsNch, minNch, maxNch}}}); + registry.add("PtPiVsNchMC_WithRecoEvt", "Generated Events With at least One Rec. Collision;;Gen. Nch;", kTH2F, {axisPt, axisNch}); + registry.add("PtKaVsNchMC_WithRecoEvt", "Generated Events With at least One Rec. Collision;;Gen. Nch;", kTH2F, {axisPt, axisNch}); + registry.add("PtPrVsNchMC_WithRecoEvt", "Generated Events With at least One Rec. Collision;;Gen. Nch;", kTH2F, {axisPt, axisNch}); // Needed to calculate the denominator of the Signal Loss correction - registry.add("PtPiVsNchMC_AllGen", "All Generated Events;;Gen. Nch (|#eta|<0.8);", kTH2F, {{axisPt, {nBinsNch, minNch, maxNch}}}); - registry.add("PtKaVsNchMC_AllGen", "All Generated Events;;Gen. Nch (|#eta|<0.8);", kTH2F, {{axisPt, {nBinsNch, minNch, maxNch}}}); - registry.add("PtPrVsNchMC_AllGen", "All Generated Events;;Gen. Nch (|#eta|<0.8);", kTH2F, {{axisPt, {nBinsNch, minNch, maxNch}}}); - - registry.add("MCclosure_PtMCPiVsNchMC", "All Generated Events 4 MC closure;;Gen. Nch (|#eta|<0.8);", kTH2F, {{axisPt, {nBinsNch, minNch, maxNch}}}); - registry.add("MCclosure_PtMCKaVsNchMC", "All Generated Events 4 MC closure;;Gen. Nch (|#eta|<0.8);", kTH2F, {{axisPt, {nBinsNch, minNch, maxNch}}}); - registry.add("MCclosure_PtMCPrVsNchMC", "All Generated Events 4 MC closure;;Gen. Nch (|#eta|<0.8);", kTH2F, {{axisPt, {nBinsNch, minNch, maxNch}}}); + registry.add("PtPiVsNchMC_AllGen", "All Generated Events;;Gen. Nch;", kTH2F, {axisPt, axisNch}); + registry.add("PtKaVsNchMC_AllGen", "All Generated Events;;Gen. Nch;", kTH2F, {axisPt, axisNch}); + registry.add("PtPrVsNchMC_AllGen", "All Generated Events;;Gen. Nch;", kTH2F, {axisPt, axisNch}); - registry.add("MCclosure_PtPiVsNchMC", "Gen Evts With at least one Rec. Coll. + Sel. criteria 4 MC closure;;Gen. Nch (|#eta|<0.8);", kTH2F, {{axisPt, {nBinsNch, minNch, maxNch}}}); - registry.add("MCclosure_PtKaVsNchMC", "Gen Evts With at least one Rec. Coll. + Sel. criteria 4 MC closure;;Gen. Nch (|#eta|<0.8);", kTH2F, {{axisPt, {nBinsNch, minNch, maxNch}}}); - registry.add("MCclosure_PtPrVsNchMC", "Gen Evts With at least one Rec. Coll. + Sel. criteria 4 MC closure;;Gen. Nch (|#eta|<0.8);", kTH2F, {{axisPt, {nBinsNch, minNch, maxNch}}}); + registry.add("MCclosure_PtMCPiVsNchMC", "All Generated Events 4 MC closure;;Gen. Nch;", kTH2F, {axisPt, axisNch}); + registry.add("MCclosure_PtMCKaVsNchMC", "All Generated Events 4 MC closure;;Gen. Nch;", kTH2F, {axisPt, axisNch}); + registry.add("MCclosure_PtMCPrVsNchMC", "All Generated Events 4 MC closure;;Gen. Nch;", kTH2F, {axisPt, axisNch}); - for (int i = 0; i < kNEtaHists; ++i) { - dEdxPiMC[i] = registry.add(Form("dEdxPi_%s", endingEta[i]), Form("%s;Momentum (GeV/#it{c});dE/dx;", latexEta[i]), kTH2F, {axisPtV0s, axisdEdx}); - dEdxMuMC[i] = registry.add(Form("dEdxMu_%s", endingEta[i]), Form("%s;Momentum (GeV/#it{c});dE/dx;", latexEta[i]), kTH2F, {axisPtV0s, axisdEdx}); - } + registry.add("MCclosure_PtPiVsNchMC", "Gen Evts With at least one Rec. Coll. + Sel. criteria 4 MC closure;;Gen. Nch (|#eta|<0.8);", kTH2F, {axisPt, axisNch}); + registry.add("MCclosure_PtKaVsNchMC", "Gen Evts With at least one Rec. Coll. + Sel. criteria 4 MC closure;;Gen. Nch (|#eta|<0.8);", kTH2F, {axisPt, axisNch}); + registry.add("MCclosure_PtPrVsNchMC", "Gen Evts With at least one Rec. Coll. + Sel. criteria 4 MC closure;;Gen. Nch (|#eta|<0.8);", kTH2F, {axisPt, axisNch}); } LOG(info) << "\trequireGoodRct=" << requireGoodRct.value; LOG(info) << "\tccdbNoLaterThan=" << ccdbNoLaterThan.value; LOG(info) << "\tselINELgt0=" << selINELgt0.value; + LOG(info) << "\tcentralitySelector=" << centralitySelector.value; LOG(info) << "\tv0TypeSelection=" << static_cast(v0Selections.v0TypeSelection); - LOG(info) << "\tselElecFromGammas=" << v0Selections.selElecFromGammas; LOG(info) << "\tapplyInvMassSel=" << v0Selections.applyInvMassSel; LOG(info) << "\tminPt=" << trackSelections.minPt; LOG(info) << "\tmaxPt=" << trackSelections.maxPt; @@ -614,7 +577,6 @@ struct PiKpRAA { LOG(info) << "\tapplyNclSel=" << trackSelections.applyNclSel; LOG(info) << "\tapplyPhiCut=" << trackSelections.applyPhiCut; LOG(info) << "\tusePinPhiSelection=" << trackSelections.usePinPhiSelection; - LOG(info) << "\tcurrentRunNumberNchSel=" << currentRunNumberNchSel; LOG(info) << "\tcurrentRunNumberPhiSel=" << currentRunNumberPhiSel; LOG(info) << "\tpathDCAxy=" << pathDCAxy.value; LOG(info) << "\tpathDCAz=" << pathDCAz.value; @@ -646,14 +608,24 @@ struct PiKpRAA { } if (trackSelections.applyNclSel) { - LOG(info) << "\ttrackSelections.minNcls=" << trackSelections.minNcls; - LOG(info) << "\tv0Selections.minNcl=" << v0Selections.minNcl; + LOG(info) << "\ttrackSelections.minNcl=" << trackSelections.minNcl; + LOG(info) << "\tv0Selections.minNclV0Daugther=" << v0Selections.minNclV0Daugther; } if (loadHisWithDCASel) { + LOG(info) << "\tUsing DCAxy and DCAz selections"; LOG(info) << "\tpathDCAxy.value=" << pathDCAxy.value; LOG(info) << "\tpathDCAz.value=" << pathDCAz.value; + loadDCAselections(); + LOG(info) << "\tdcaSelectionsLoaded=" << cfgDCA.dcaSelectionsLoaded; } + + auto vecLowEtaSel = (std::vector)vecLowEta; + auto vecUpEtaSel = (std::vector)vecUpEta; + LOGF(info, "vecLowEta: %s", printArray(vecLowEtaSel).c_str()); + LOGF(info, "vecUpEta: %s", printArray(vecUpEtaSel).c_str()); + LOGF(info, "vecEndingEta: %s", printArray(endingEta).c_str()); + LOGF(info, "vecLatexEta: %s", printArray(latexEta).c_str()); } void processCalibrationAndV0s(ColEvSels::iterator const& collision, BCsRun3 const& /**/, aod::V0Datas const& v0s, aod::FV0As const& /**/, aod::FT0s const& /**/, TracksFull const& tracks) @@ -662,11 +634,22 @@ struct PiKpRAA { // Table's size: " << collisions.tableSize() << "\n"; // LOG(info) << "Run number: " << foundBC.runNumber() << "\n"; + const auto& kLowEta = (std::vector)vecLowEta; + const auto& kHighEta = (std::vector)vecUpEta; + const auto& foundBC = collision.foundBC_as(); const uint64_t timeStamp{foundBC.timestamp()}; const int magField{getMagneticField(timeStamp)}; const double nPV{collision.multNTracksPVeta1() / 1.}; - const float centrality{isT0Ccent ? collision.centFT0C() : collision.centFT0M()}; + float centrality{-999.0}; + if (centralitySelector.value == "FT0C") + centrality = collision.centFT0C(); + else if (centralitySelector.value == "FT0M") + centrality = collision.centFT0M(); + else if (centralitySelector.value == "FV0A") + centrality = collision.centFV0A(); + else + centrality = -999.0; // Apply RCT selection? if (requireGoodRct) { @@ -680,23 +663,23 @@ struct PiKpRAA { const bool isTPCPIDBad{requireBCRct ? foundBC.rct_bit(kTPCBadPID) : collision.rct_bit(kTPCBadPID)}; const bool isTPCLimAcc{requireBCRct ? foundBC.rct_bit(kTPCLimAccMCRepr) : collision.rct_bit(kTPCLimAccMCRepr)}; - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 1.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 1.0); if (!isFT0Bad) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 2.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 2.0); if (!isITSBad) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 3.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 3.0); if (!isITSLimAcc) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 4.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 4.0); if (!isTOFBad) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 5.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 5.0); if (!isTOFLimAcc) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 6.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 6.0); if (!isTPCTrackingBad) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 7.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 7.0); if (!isTPCPIDBad) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 8.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 8.0); if (!isTPCLimAcc) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 9.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 9.0); registry.fill(HIST("RCTSel"), 1.0); if (!rctChecker(collision)) @@ -712,26 +695,13 @@ struct PiKpRAA { // Control histogram //--------------------------- if (selHasFT0 && !collision.has_foundFT0()) - registry.fill(HIST("T0CcentVsFoundFT0"), centrality, 0.5); - - registry.fill(HIST("T0CcentVsFoundFT0"), centrality, 1.5); + registry.fill(HIST("CentralityVsFoundFT0"), centrality, 0.5); - if (loadHisWithDCASel) { - const int nextRunNumber{foundBC.runNumber()}; - if (currentRunNumberNchSel != nextRunNumber) { - loadDCAselections(timeStamp); - currentRunNumberNchSel = nextRunNumber; - LOG(info) << "\tcurrentRunNumberNchSel= " << currentRunNumberNchSel << " timeStamp = " << timeStamp; - } - - // return if DCA selection objects are nullptr - if (!(cfgDCA.hDCAxy && cfgDCA.hDCAz)) - return; - - if (!cfgDCA.dcaSelectionsLoaded) - return; - } + registry.fill(HIST("CentralityVsFoundFT0"), centrality, 1.5); + //--------------------------- + // Load Phi selection + //--------------------------- if (trackSelections.applyPhiCut) { const int nextRunNumber{foundBC.runNumber()}; if (currentRunNumberPhiSel != nextRunNumber) { @@ -746,7 +716,7 @@ struct PiKpRAA { } registry.fill(HIST("zPos"), collision.posZ()); - registry.fill(HIST("T0Ccent"), centrality); + registry.fill(HIST("Centrality"), centrality); // ================ // Track selection WITHOUT DCAxy and DCAz selections @@ -781,9 +751,9 @@ struct PiKpRAA { const double piRadiusNsigma{std::sqrt(std::pow(piTPCNsigma, 2.) + std::pow(piTOFNsigma, 2.))}; const double prRadiusNsigma{std::sqrt(std::pow(prTPCNsigma, 2.) + std::pow(prTOFNsigma, 2.))}; - if (piRadiusNsigma < kThree) + if (piRadiusNsigma < Kthree) registry.fill(HIST("dcaVsPtPi"), pt, dcaXy, centrality); - if (prRadiusNsigma < kThree) + if (prRadiusNsigma < Kthree) registry.fill(HIST("dcaVsPtPr"), pt, dcaXy, centrality); } @@ -792,9 +762,6 @@ struct PiKpRAA { // ================ for (const auto& track : tracks) { - // if (!trkSelGlobal.IsSelected(track)) - // continue; - const float momentum{track.p()}; const float pTPC{track.tpcInnerParam()}; const float pt{track.pt()}; @@ -806,7 +773,7 @@ struct PiKpRAA { const int16_t nclFound{track.tpcNClsFound()}; const int16_t nclPID{track.tpcNClsPID()}; const int16_t ncl{trackSelections.useNclsPID ? nclPID : nclFound}; - const int16_t nCrossedRows{track.tpcNClsCrossedRows()}; + // const int16_t nCrossedRows{track.tpcNClsCrossedRows()}; // ================ // DCAxy & DCAz Selections @@ -825,56 +792,73 @@ struct PiKpRAA { if (trackSelections.applyEtaCal && etaCal.isMIPCalLoaded) { const double dedxCal{etaCal.pEtaCal->GetBinContent(etaCal.pEtaCal->FindBin(eta))}; - if (dedxCal > kMindEdxMIP && dedxCal < kMaxdEdxMIP) + if (dedxCal > KmindEdxMIP && dedxCal < KmaxdEdxMIP) dedx *= (50.0 / dedxCal); else continue; } int indexEta{-999}; - for (int i = 0; i < kNEtaHists; ++i) { + for (int i = 0; i < KnEtaHists; ++i) { if (eta >= kLowEta[i] && eta < kHighEta[i]) { indexEta = i; break; } } - if (indexEta < kZeroInt || indexEta > kSevenInt) + if (indexEta < KzeroInt || indexEta > KsevenInt) continue; - if (momentum > kMinPMIP && momentum < kMaxPMIP && dedx > kMindEdxMIP && dedx < kMaxdEdxMIP) { + if (momentum > KminPMIP && momentum < KmaxPMIP && dedx > KmindEdxMIP && dedx < KmaxdEdxMIP) { registry.fill(HIST("dEdxVsEtaPiMIP"), eta, dedx); registry.fill(HIST("dEdxVsEtaPiMIPp"), eta, dedx); registry.fill(HIST("NclVsEtaPiMIP"), eta, ncl); registry.fill(HIST("NclVsEtaPiMIPp"), eta, ncl); } - if (momentum > kMinPMIP && momentum < kMaxPMIP && dedx > kMindEdxMIPPlateau && dedx < kMaxdEdxMIPPlateau) { + if (momentum > KminPMIP && momentum < KmaxPMIP && dedx > KmindEdxMIPPlateau && dedx < KmaxdEdxMIPPlateau) { if (track.hasTOF() && track.goodTOFMatch()) { const float tTOF{track.tofSignal()}; const float trkLength{track.length()}; const float tExpElTOF{track.tofExpSignalEl(tTOF)}; - if ((std::abs((tExpElTOF / tTOF) - kOne) < trackSelections.maxElTOFBeta) && tTOF > kZero && trkLength > kZero) { + if ((std::abs((tExpElTOF / tTOF) - Kone) < trackSelections.maxElTOFBeta) && tTOF > Kzero && trkLength > Kzero) { registry.fill(HIST("dEdxVsEtaElMIP"), eta, dedx); registry.fill(HIST("dEdxVsEtaElMIPp"), eta, dedx); } } } + if (track.hasTOF() && track.goodTOFMatch()) { + const float tTOF{track.tofSignal()}; + const float trkLength{track.length()}; + const float tExpPiTOF{track.tofExpSignalPi(tTOF)}; + const float tOFNsigmaPi{std::fabs(track.tofNSigmaPi())}; + const float tPCNsigmaPi{std::fabs(track.tpcNSigmaPi())}; + + if (tTOF > Kzero && trkLength > Kzero) { + if (std::abs((tExpPiTOF / tTOF) - Kone) < trackSelections.maxPiTOFBeta) { + dEdxPiTOF2[indexEta]->Fill(momentum, dedx); + } + + if (std::sqrt(std::pow(tOFNsigmaPi, 2.0) + std::pow(tPCNsigmaPi, 2.0)) < trackSelections.nSigmaPIDselPrim) { + dEdxPiTOF[indexEta]->Fill(momentum, dedx); + } + } + } + + etaTest[indexEta]->Fill(eta); dEdx[indexEta]->Fill(momentum, dedx, centrality); pTVsP[indexEta]->Fill(momentum, pt); nClVsP[indexEta]->Fill(pOrpTPC, ncl); nClVsPp[indexEta]->Fill(pOrpTPC, ncl); - nCrRoVsNcl[indexEta]->Fill(nCrossedRows, ncl); - nCrRoVsNclp[indexEta]->Fill(nCrossedRows, ncl); - nClPIDVsnCl[indexEta]->Fill(nclFound, nclPID); - nClPIDVsnClp[indexEta]->Fill(nclFound, nclPID); registry.fill(HIST("DCAxyVsPt"), pt, track.dcaXY()); registry.fill(HIST("DCAzVsPt"), pt, track.dcaZ()); registry.fill(HIST("MomentumTPCVsP"), momentum, pTPC); registry.fill(HIST("pTVsCent"), pt, centrality); registry.fill(HIST("EtaVsPhi"), eta, track.phi()); + registry.fill(HIST("NclVsPhiHist"), track.phi(), nclFound); + registry.fill(HIST("NclVsPhiProfile"), track.phi(), nclFound); registry.fill(HIST("NclVsEta"), eta, nclFound); registry.fill(HIST("NclVsEtap"), eta, nclFound); registry.fill(HIST("NclVsEtaPID"), eta, nclPID); @@ -939,7 +923,7 @@ struct PiKpRAA { // Eta calibration positive-charge track if (trackSelections.applyEtaCal && etaCal.isMIPCalLoaded) { const double dedxCal{etaCal.pEtaCal->GetBinContent(etaCal.pEtaCal->FindBin(posTrkEta))}; - if (dedxCal > kMindEdxMIP && dedxCal < kMaxdEdxMIP) + if (dedxCal > KmindEdxMIP && dedxCal < KmaxdEdxMIP) posTrkdEdx *= (50.0 / dedxCal); else continue; @@ -948,7 +932,7 @@ struct PiKpRAA { // Eta calibration negative-charge track if (trackSelections.applyEtaCal && etaCal.isMIPCalLoaded) { const double dedxCal{etaCal.pEtaCal->GetBinContent(etaCal.pEtaCal->FindBin(negTrkEta))}; - if (dedxCal > kMindEdxMIP && dedxCal < kMaxdEdxMIP) + if (dedxCal > KmindEdxMIP && dedxCal < KmaxdEdxMIP) negTrkdEdx *= (50.0 / dedxCal); else continue; @@ -971,24 +955,24 @@ struct PiKpRAA { int posIndexEta{-999}; int negIndexEta{-999}; - for (int i = 0; i < kNEtaHists; ++i) { + for (int i = 0; i < KnEtaHists; ++i) { if (posTrkEta >= kLowEta[i] && posTrkEta < kHighEta[i]) { posIndexEta = i; break; } } - for (int i = 0; i < kNEtaHists; ++i) { + for (int i = 0; i < KnEtaHists; ++i) { if (negTrkEta >= kLowEta[i] && negTrkEta < kHighEta[i]) { negIndexEta = i; break; } } - if (posIndexEta < kZeroInt || posIndexEta > kSevenInt) + if (posIndexEta < KzeroInt || posIndexEta > KsevenInt) continue; - if (negIndexEta < kZeroInt || negIndexEta > kSevenInt) + if (negIndexEta < KzeroInt || negIndexEta > KsevenInt) continue; registry.fill(HIST("ArmAfterTopoSel"), alpha, qT); @@ -1014,11 +998,11 @@ struct PiKpRAA { dEdxPiV0[posIndexEta]->Fill(posTrkP, posTrkdEdx); dEdxPiV0[negIndexEta]->Fill(negTrkP, negTrkdEdx); - if (posTrkP > kMinPMIP && posTrkP < kMaxPMIP && posTrkdEdx > kMindEdxMIP && posTrkdEdx < kMaxdEdxMIP) { + if (posTrkP > KminPMIP && posTrkP < KmaxPMIP && posTrkdEdx > KmindEdxMIP && posTrkdEdx < KmaxdEdxMIP) { registry.fill(HIST("dEdxVsEtaPiMIPV0"), posTrkEta, posTrkdEdx); registry.fill(HIST("dEdxVsEtaPiMIPV0p"), posTrkEta, posTrkdEdx); } - if (negTrkP > kMinPMIP && negTrkP < kMaxPMIP && negTrkdEdx > kMindEdxMIP && negTrkdEdx < kMaxdEdxMIP) { + if (negTrkP > KminPMIP && negTrkP < KmaxPMIP && negTrkdEdx > KmindEdxMIP && negTrkdEdx < KmaxdEdxMIP) { registry.fill(HIST("dEdxVsEtaPiMIPV0"), negTrkEta, negTrkdEdx); registry.fill(HIST("dEdxVsEtaPiMIPV0p"), negTrkEta, negTrkdEdx); } @@ -1029,7 +1013,7 @@ struct PiKpRAA { registry.fill(HIST("V0sCounter"), V0sCounter::Lambda); registry.fill(HIST("ArmL"), alpha, qT); registry.fill(HIST("MassLVsPt"), v0.pt(), v0.mLambda()); - if (posTrackCharge > kZero) { + if (posTrackCharge > Kzero) { registry.fill(HIST("nSigPrFromL"), posTrkPt, posTrack.tpcNSigmaPr()); registry.fill(HIST("NclVsEtaPrV0"), posTrkEta, posNcl); registry.fill(HIST("NclVsEtaPrV0p"), posTrkEta, posNcl); @@ -1037,13 +1021,11 @@ struct PiKpRAA { nClVsPpPrV0[posIndexEta]->Fill(posPorPTPC, posNcl); dEdxPrV0[posIndexEta]->Fill(posTrkP, posTrkdEdx); } - if (negTrackCharge < kZero) { + if (negTrackCharge < Kzero) { registry.fill(HIST("nSigPiFromL"), negTrkPt, negTrack.tpcNSigmaPi()); // registry.fill(HIST("NclVsEtaPiV0"), negTrkEta, negNcl); // registry.fill(HIST("NclVsEtaPiV0p"), negTrkEta, negNcl); - // nClVsPPiV0[negIndexEta]->Fill(negPorPt, negNcl); // nClVsPpPiV0[negIndexEta]->Fill(negPorPt, negNcl); - // dEdxPiV0[negIndexEta]->Fill(negTrkP, negTrkdEdx, centrality); } } @@ -1051,15 +1033,13 @@ struct PiKpRAA { registry.fill(HIST("V0sCounter"), V0sCounter::AntiLambda); registry.fill(HIST("ArmAL"), alpha, qT); registry.fill(HIST("MassALVsPt"), v0.pt(), v0.mAntiLambda()); - if (posTrackCharge > kZero) { + if (posTrackCharge > Kzero) { registry.fill(HIST("nSigPiFromAL"), posTrkPt, posTrack.tpcNSigmaPi()); // registry.fill(HIST("NclVsEtaPiV0"), posTrkEta, posNcl); // registry.fill(HIST("NclVsEtaPiV0p"), posTrkEta, posNcl); - // nClVsPPiV0[posIndexEta]->Fill(posPorPt, posNcl); // nClVsPpPiV0[posIndexEta]->Fill(posPorPt, posNcl); - // dEdxPiV0[posIndexEta]->Fill(posTrkP, posTrkdEdx, centrality); } - if (negTrackCharge < kZero) { + if (negTrackCharge < Kzero) { registry.fill(HIST("nSigPrFromAL"), negTrkPt, negTrack.tpcNSigmaPr()); registry.fill(HIST("NclVsEtaPrV0"), negTrkEta, negNcl); registry.fill(HIST("NclVsEtaPrV0p"), negTrkEta, negNcl); @@ -1092,11 +1072,11 @@ struct PiKpRAA { nClVsPpElV0[negIndexEta]->Fill(negPorPTPC, negNcl); nClVsPElV0[posIndexEta]->Fill(posPorPTPC, posNcl); nClVsPpElV0[posIndexEta]->Fill(posPorPTPC, posNcl); - if (posPorPTPC > kMinPMIP && posPorPTPC < kMaxPMIP && posTrkdEdx > kMindEdxMIPPlateau && posTrkdEdx < kMaxdEdxMIPPlateau) { + if (posPorPTPC > KminPMIP && posPorPTPC < KmaxPMIP && posTrkdEdx > KmindEdxMIPPlateau && posTrkdEdx < KmaxdEdxMIPPlateau) { registry.fill(HIST("dEdxVsEtaElMIPV0"), posTrkEta, posTrkdEdx); registry.fill(HIST("dEdxVsEtaElMIPV0p"), posTrkEta, posTrkdEdx); } - if (negPorPTPC > kMinPMIP && negPorPTPC < kMaxPMIP && negTrkdEdx > kMindEdxMIPPlateau && negTrkdEdx < kMaxdEdxMIPPlateau) { + if (negPorPTPC > KminPMIP && negPorPTPC < KmaxPMIP && negTrkdEdx > KmindEdxMIPPlateau && negTrkdEdx < KmaxdEdxMIPPlateau) { registry.fill(HIST("dEdxVsEtaElMIPV0"), negTrkEta, negTrkdEdx); registry.fill(HIST("dEdxVsEtaElMIPV0p"), negTrkEta, negTrkdEdx); } @@ -1113,6 +1093,10 @@ struct PiKpRAA { void processSim(aod::McCollisions::iterator const& mccollision, soa::SmallGroups const& collisions, BCsRun3 const& /*bcs*/, aod::FT0s const& /*ft0s*/, aod::McParticles const& mcParticles, TracksMC const& tracksMC) { + + const auto& kLowEta = (std::vector)vecLowEta; + const auto& kHighEta = (std::vector)vecUpEta; + //--------------------------- // Only INEL > 0 generated collisions // By counting number of primary charged particles in |eta| < 1 @@ -1133,7 +1117,7 @@ struct PiKpRAA { } // Is it a charged particle? - if (std::abs(charge) < kMinCharge) + if (std::abs(charge) < KminCharge) continue; // Is it a primary particle? @@ -1143,11 +1127,11 @@ struct PiKpRAA { const float eta{particle.eta()}; // TVX requirement - if (eta > kMinFT0A && eta < kMaxFT0A) { + if (eta > KminFT0A && eta < KmaxFT0A) { nChFT0A++; } - if (eta > kMinFT0C && eta < kMaxFT0C) { + if (eta > KminFT0C && eta < KmaxFT0C) { nChFT0C++; } @@ -1156,17 +1140,17 @@ struct PiKpRAA { } // INEL > 0 - if (std::abs(eta) > kOne) + if (std::abs(eta) > Kone) continue; nChMC++; } //--------------------------- - // Only events with at least one charged particle in the FT0A and FT0C acceptances + // Select only events with at least one charged particle in the FT0A and FT0C acceptances? //--------------------------- if (selTVXMC) { - if (!(nChFT0A > kZeroInt && nChFT0C > kZeroInt)) { + if (!(nChFT0A > KzeroInt && nChFT0C > KzeroInt)) { registry.fill(HIST("NchMCcentVsTVX"), nChMC, 0.5); return; } @@ -1174,17 +1158,17 @@ struct PiKpRAA { } //--------------------------- - // Only MC events with |Vtx Z| < 10 cm + // Select only MC events with |Vtx Z| < 10 cm? //--------------------------- if (isZvtxPosSelMC && (std::fabs(mccollision.posZ()) > posZcut)) { return; } //--------------------------- - // Only INEL > 0 generated events + // Select only INEL > 0 generated events? //--------------------------- if (selINELgt0) { - if (!(nChMC > kZeroInt)) { + if (!(nChMC > KzeroInt)) { return; } } @@ -1213,7 +1197,7 @@ struct PiKpRAA { } // Is it a charged particle? - if (std::abs(charge) < kMinCharge) + if (std::abs(charge) < KminCharge) continue; // Is it a primary particle? @@ -1239,24 +1223,39 @@ struct PiKpRAA { //--------------------------- // This is used for the denominator of the event loss correction + // Only charge particles within tpcNchAcceptance and without pT selection //--------------------------- registry.fill(HIST("NchMC_AllGen"), nChMCEta08); //--------------------------- - // Only Generated evets with at least one reconstrued collision + // How many times the Generated evet was reconstrued? //--------------------------- const auto& nRecColls{collisions.size()}; registry.fill(HIST("NumberOfRecoCollisions"), nRecColls); - if (nRecColls > kZeroInt) { + //--------------------------- + // Only Generated evets with at least one reconstrued collision + //--------------------------- + if (nRecColls > KzeroInt) { - // Finds the collisions with the largest number of contributors - // in case nRecColls is larger than One + //--------------------------- + // Looks for the collision with the largest number of contributors + // The selected collisions is identified with its index (bestCollisionIndex) + //--------------------------- int biggestNContribs{-1}; int bestCollisionIndex{-1}; for (const auto& collision : collisions) { - const float centrality{isT0Ccent ? collision.centFT0C() : collision.centFT0M()}; + float centrality{-999.0}; + if (centralitySelector.value == "FT0C") + centrality = collision.centFT0C(); + else if (centralitySelector.value == "FT0M") + centrality = collision.centFT0M(); + else if (centralitySelector.value == "FV0A") + centrality = collision.centFV0A(); + else + centrality = -999.0; + if (selHasFT0 && !collision.has_foundFT0()) { continue; } @@ -1269,9 +1268,6 @@ struct PiKpRAA { if (selHasBC && !collision.has_foundBC()) continue; - if (selHasFT0 && !collision.has_foundFT0()) - continue; - if (useSel8 && !collision.sel8()) continue; @@ -1297,7 +1293,9 @@ struct PiKpRAA { if (selNoSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) continue; + //--------------------------- // Needed to calculate denominator of the Event Splitting correction + //--------------------------- registry.fill(HIST("Centrality_AllRecoEvt"), centrality); } @@ -1307,7 +1305,15 @@ struct PiKpRAA { //--------------------------- for (const auto& collision : collisions) { - const float centrality{isT0Ccent ? collision.centFT0C() : collision.centFT0M()}; + float centrality{-999.0}; + if (centralitySelector.value == "FT0C") + centrality = collision.centFT0C(); + else if (centralitySelector.value == "FT0M") + centrality = collision.centFT0M(); + else if (centralitySelector.value == "FV0A") + centrality = collision.centFV0A(); + else + centrality = -999.0; //--------------------------- // Pick the collisions with the largest number of contributors @@ -1339,21 +1345,21 @@ struct PiKpRAA { registry.fill(HIST("Centrality_WRecoEvt"), centrality); registry.fill(HIST("zPosMC"), mccollision.posZ()); - registry.fill(HIST("T0CcentVsBCVsFT0VsTVXVsEvSel"), centrality, 1.0); + registry.fill(HIST("CentralityVsBCVsFT0VsTVXVsEvSel"), centrality, 1.0); registry.fill(HIST("HasBCVsFT0VsTVXVsEvSel"), 1.0); if (collision.has_foundBC()) { - registry.fill(HIST("T0CcentVsBCVsFT0VsTVXVsEvSel"), centrality, 2.0); + registry.fill(HIST("CentralityVsBCVsFT0VsTVXVsEvSel"), centrality, 2.0); registry.fill(HIST("HasBCVsFT0VsTVXVsEvSel"), 2.0); } if (collision.has_foundBC() && collision.has_foundFT0()) { - registry.fill(HIST("T0CcentVsBCVsFT0VsTVXVsEvSel"), centrality, 3.0); + registry.fill(HIST("CentralityVsBCVsFT0VsTVXVsEvSel"), centrality, 3.0); registry.fill(HIST("HasBCVsFT0VsTVXVsEvSel"), 3.0); } if (collision.has_foundBC() && collision.has_foundFT0() && collision.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { - registry.fill(HIST("T0CcentVsBCVsFT0VsTVXVsEvSel"), centrality, 4.0); + registry.fill(HIST("CentralityVsBCVsFT0VsTVXVsEvSel"), centrality, 4.0); registry.fill(HIST("HasBCVsFT0VsTVXVsEvSel"), 4.0); } @@ -1371,23 +1377,23 @@ struct PiKpRAA { const bool isTPCPIDBad{requireBCRct ? foundBC.rct_bit(kTPCBadPID) : collision.rct_bit(kTPCBadPID)}; const bool isTPCLimAcc{requireBCRct ? foundBC.rct_bit(kTPCLimAccMCRepr) : collision.rct_bit(kTPCLimAccMCRepr)}; - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 1.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 1.0); if (!isFT0Bad) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 2.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 2.0); if (!isITSBad) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 3.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 3.0); if (!isITSLimAcc) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 4.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 4.0); if (!isTOFBad) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 5.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 5.0); if (!isTOFLimAcc) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 6.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 6.0); if (!isTPCTrackingBad) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 7.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 7.0); if (!isTPCPIDBad) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 8.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 8.0); if (!isTPCLimAcc) - registry.fill(HIST("T0CcentVsRCTSel"), centrality, 9.0); + registry.fill(HIST("CentralityVsRCTSel"), centrality, 9.0); registry.fill(HIST("RCTSel"), 1.0); if (!rctChecker(collision)) @@ -1406,21 +1412,21 @@ struct PiKpRAA { registry.fill(HIST("NchMCVsCent"), centrality, nChMCEta08); registry.fill(HIST("NchMC_WithRecoEvt"), nChMCEta08); // Numerator of event loss correction registry.fill(HIST("zPos"), collision.posZ()); - registry.fill(HIST("T0Ccent"), centrality); + registry.fill(HIST("Centrality"), centrality); //--------------------------- // has_foundFT0() ? //--------------------------- if (collision.has_foundBC() && collision.has_foundFT0() && collision.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { - registry.fill(HIST("T0CcentVsBCVsFT0VsTVXVsEvSel"), centrality, 5.0); + registry.fill(HIST("CentralityVsBCVsFT0VsTVXVsEvSel"), centrality, 5.0); registry.fill(HIST("HasBCVsFT0VsTVXVsEvSel"), 5.0); } if (collision.has_foundFT0()) - registry.fill(HIST("T0CcentVsFoundFT0"), centrality, 1.5); + registry.fill(HIST("CentralityVsFoundFT0"), centrality, 1.5); else - registry.fill(HIST("T0CcentVsFoundFT0"), centrality, 0.5); + registry.fill(HIST("CentralityVsFoundFT0"), centrality, 0.5); //--------------------------- // All Generated events with at least one associated reconstructed collision @@ -1445,7 +1451,7 @@ struct PiKpRAA { } // Is it a charged particle? - if (std::abs(charge) < kMinCharge) + if (std::abs(charge) < KminCharge) continue; // Is it a primary particle? @@ -1495,9 +1501,12 @@ struct PiKpRAA { } // Is it a charged particle? - if (std::abs(charge) < kMinCharge) + if (std::abs(charge) < KminCharge) continue; + registry.fill(HIST("DCAxyVsPt"), track.pt(), track.dcaXY()); + registry.fill(HIST("DCAzVsPt"), track.pt(), track.dcaZ()); + float phiPrime{track.phi()}; phiPrimeFunc(phiPrime, magField, charge); @@ -1570,28 +1579,37 @@ struct PiKpRAA { } // Is it a charged particle? - if (std::abs(charge) < kMinCharge) + if (std::abs(charge) < KminCharge) continue; float phiPrime{track.phi()}; phiPrimeFunc(phiPrime, magField, charge); - const float pOrpTPC{trackSelections.usePinPhiSelection ? track.p() : track.tpcInnerParam()}; - int indexEta{-999}; const float eta{track.eta()}; - for (int i = 0; i < kNEtaHists; ++i) { + for (int i = 0; i < KnEtaHists; ++i) { if (eta >= kLowEta[i] && eta < kHighEta[i]) { indexEta = i; break; } } - if (indexEta < kZeroInt || indexEta > kSevenInt) + if (indexEta < KzeroInt || indexEta > KsevenInt) continue; nCh++; + registry.fill(HIST("MomentumTPCVsP"), track.p(), track.tpcInnerParam()); + registry.fill(HIST("DCAxyVsPtWithSelection"), track.pt(), track.dcaXY()); + registry.fill(HIST("DCAzVsPtWithSelection"), track.pt(), track.dcaZ()); + registry.fill(HIST("EtaVsPhi"), track.eta(), track.phi()); + registry.fill(HIST("NclVsPhiHist"), track.phi(), track.tpcNClsFound()); + registry.fill(HIST("NclVsPhiProfile"), track.phi(), track.tpcNClsFound()); + registry.fill(HIST("NclVsEta"), track.eta(), track.tpcNClsFound()); + registry.fill(HIST("NclVsEtap"), track.eta(), track.tpcNClsFound()); + registry.fill(HIST("NclVsEtaPID"), track.eta(), track.tpcNClsPID()); + registry.fill(HIST("NclVsEtaPIDp"), track.eta(), track.tpcNClsPID()); + bool isPrimary{false}; if (particle.isPhysicalPrimary()) isPrimary = true; @@ -1602,7 +1620,7 @@ struct PiKpRAA { bool isPi{false}; bool isKa{false}; bool isPr{false}; - bool isMu{false}; + // bool isMu{false}; if (particle.pdgCode() == PDG_t::kPiPlus || particle.pdgCode() == PDG_t::kPiMinus) { isPi = true; @@ -1610,20 +1628,14 @@ struct PiKpRAA { isKa = true; } else if (particle.pdgCode() == PDG_t::kProton || particle.pdgCode() == PDG_t::kProtonBar) { isPr = true; - } else if (particle.pdgCode() == PDG_t::kMuonPlus || particle.pdgCode() == PDG_t::kMuonMinus) { - isMu = true; } else { continue; } - if (isMu && !isPi && !isKa && !isPr) - dEdxMuMC[indexEta]->Fill(pOrpTPC, track.tpcSignal()); - if (isPi && !isKa && !isPr) { registry.fill(HIST("PtPiVsCent_WithRecoEvt"), track.pt(), centrality); // Numerator of tracking efficiency registry.fill(HIST("PtGenPiVsCent_WithRecoEvt"), particle.pt(), centrality); // Numerator of tracking efficiency registry.fill(HIST("MCclosure_PtPiVsNchMC"), track.pt(), nChMCEta08); - dEdxPiMC[indexEta]->Fill(pOrpTPC, track.tpcSignal()); } if (isKa && !isPi && !isPr) { registry.fill(HIST("PtKaVsCent_WithRecoEvt"), track.pt(), centrality); @@ -1649,7 +1661,7 @@ struct PiKpRAA { alpha = 0., qT = 0.; TVector3 pV0 = ppos + pneg; double pV0mag = pV0.Mag(); - if (pV0mag < kTenToMinusNine) + if (pV0mag < KtEnToMinusNine) return; // protect against zero momentum const TVector3 u = pV0 * (1.0 / pV0mag); @@ -1663,7 +1675,7 @@ struct PiKpRAA { // α: longitudinal asymmetry (uses + and − labels by charge) double denom = pLpos + pLneg; - if (std::abs(denom) < kTenToMinusNine) + if (std::abs(denom) < KtEnToMinusNine) return; // avoid 0 division (unphysical for V0s) alpha = (pLpos - pLneg) / denom; // equivalently / pV0mag @@ -1688,7 +1700,7 @@ struct PiKpRAA { dcaZcut *= trackSelections.nSigmaDCAz; } - if (std::abs(track.eta()) > trackSelections.maxEta) { + if (track.eta() < trackSelections.minEta || track.eta() > trackSelections.maxEta) { return false; } @@ -1714,7 +1726,7 @@ struct PiKpRAA { } // ==== Ncl selection ==== // - if (trackSelections.applyNclSel && ncl < trackSelections.minNcls) + if (trackSelections.applyNclSel && ncl < trackSelections.minNcl) return false; // ==== DCAxy & DCAz selections ==== // @@ -1723,6 +1735,12 @@ struct PiKpRAA { return false; } + // Flag to check that the DCA selections are loaded + // when asking to apply DCA + // ==== DCAxy & DCAz selections ==== // + if (loadHisWithDCASel && applyDca && !cfgDCA.dcaSelectionsLoaded) + return false; + return true; } @@ -1730,14 +1748,14 @@ struct PiKpRAA { bool selectV0Daughter(const T& track) { - const float eta{track.eta()}; + // const float eta{track.eta()}; const uint8_t nclShared{track.tpcNClsShared()}; const int16_t nCrossedRows{track.tpcNClsCrossedRows()}; const int16_t nclFound{track.tpcNClsFound()}; const int16_t nclPID{track.tpcNClsPID()}; const int16_t ncl{trackSelections.useNclsPID ? nclPID : nclFound}; - if (std::abs(eta) > trackSelections.maxEta) { + if (track.eta() < trackSelections.minEta || track.eta() > trackSelections.maxEta) { return false; } @@ -1751,7 +1769,7 @@ struct PiKpRAA { } // ==== Ncl selection ==== // - if (trackSelections.applyNclSel && ncl < v0Selections.minNcl) + if (trackSelections.applyNclSel && ncl < v0Selections.minNclV0Daugther) return false; // ==== Ncl shared ==== // @@ -1795,7 +1813,7 @@ struct PiKpRAA { const double dMassL{std::abs(v0.mLambda() - o2::constants::physics::MassLambda0)}; const double dMassAL{std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0)}; const double dMassG{std::abs(v0.mGamma() - o2::constants::physics::MassGamma)}; - const double rapidity{std::abs(v0.yK0Short())}; + const double rapidity{v0.yK0Short()}; const double lifeTime{v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short}; // Checks if DCA of daughters to PV passes selection @@ -1809,13 +1827,13 @@ struct PiKpRAA { bool isSelected{false}; if (v0Selections.useOfficialV0sSelOfDaughters) { - isSelected = lifeTime < v0Selections.lifeTimeCutK0s && rapidity < v0Selections.rapidityCut && dcaDaugToPV ? true : false; + isSelected = lifeTime < v0Selections.lifeTimeCutK0s && (rapidity > v0Selections.minY && rapidity < v0Selections.maxY) && dcaDaugToPV ? true : false; } if (!v0Selections.useOfficialV0sSelOfDaughters) { if (v0Selections.useTPCNsigma) - isSelected = lifeTime < v0Selections.lifeTimeCutK0s && rapidity < v0Selections.rapidityCut && posTPCNsigma < v0Selections.pidNsigmaCut && negTPCNsigma < v0Selections.pidNsigmaCut && dcaDaugToPV ? true : false; + isSelected = lifeTime < v0Selections.lifeTimeCutK0s && (rapidity > v0Selections.minY && rapidity < v0Selections.maxY) && posTPCNsigma < v0Selections.pidNsigmaCut && negTPCNsigma < v0Selections.pidNsigmaCut && dcaDaugToPV ? true : false; if (!v0Selections.useTPCNsigma) - isSelected = lifeTime < v0Selections.lifeTimeCutK0s && rapidity < v0Selections.rapidityCut && posTOFNsigma < v0Selections.pidNsigmaCut && negTOFNsigma < v0Selections.pidNsigmaCut && hasToF && goodToFmatch && dcaDaugToPV ? true : false; + isSelected = lifeTime < v0Selections.lifeTimeCutK0s && (rapidity > v0Selections.minY && rapidity < v0Selections.maxY) && posTOFNsigma < v0Selections.pidNsigmaCut && negTOFNsigma < v0Selections.pidNsigmaCut && hasToF && goodToFmatch && dcaDaugToPV ? true : false; } if (isSelected) { @@ -1848,7 +1866,7 @@ struct PiKpRAA { const double dMassK0s{std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short)}; const double dMassL{std::abs(v0.mLambda() - o2::constants::physics::MassLambda0)}; const double dMassG{std::abs(v0.mGamma() - o2::constants::physics::MassGamma)}; - const double rapidity{std::abs(v0.yLambda())}; + const double rapidity{v0.yLambda()}; const double lifeTime{v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0}; // Checks if DCA of daughters to PV passes selection @@ -1862,13 +1880,13 @@ struct PiKpRAA { bool isSelected{false}; if (v0Selections.useOfficialV0sSelOfDaughters) { - isSelected = lifeTime < v0Selections.lifeTimeCutLambda && rapidity < v0Selections.rapidityCut && dcaDaugToPV ? true : false; + isSelected = lifeTime < v0Selections.lifeTimeCutLambda && (rapidity > v0Selections.minY && rapidity < v0Selections.maxY) && dcaDaugToPV ? true : false; } if (!v0Selections.useOfficialV0sSelOfDaughters) { if (v0Selections.useTPCNsigma) - isSelected = lifeTime < v0Selections.lifeTimeCutLambda && rapidity < v0Selections.rapidityCut && posTPCNsigma < v0Selections.pidNsigmaCut && negTPCNsigma < v0Selections.pidNsigmaCut && dcaDaugToPV ? true : false; + isSelected = lifeTime < v0Selections.lifeTimeCutLambda && (rapidity > v0Selections.minY && rapidity < v0Selections.maxY) && posTPCNsigma < v0Selections.pidNsigmaCut && negTPCNsigma < v0Selections.pidNsigmaCut && dcaDaugToPV ? true : false; if (!v0Selections.useTPCNsigma) - isSelected = lifeTime < v0Selections.lifeTimeCutLambda && rapidity < v0Selections.rapidityCut && posTOFNsigma < v0Selections.pidNsigmaCut && negTOFNsigma < v0Selections.pidNsigmaCut && hasToF && goodToFmatch && dcaDaugToPV ? true : false; + isSelected = lifeTime < v0Selections.lifeTimeCutLambda && (rapidity > v0Selections.minY && rapidity < v0Selections.maxY) && posTOFNsigma < v0Selections.pidNsigmaCut && negTOFNsigma < v0Selections.pidNsigmaCut && hasToF && goodToFmatch && dcaDaugToPV ? true : false; } if (isSelected) { @@ -1901,7 +1919,7 @@ struct PiKpRAA { const double dMassK0s{std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short)}; const double dMassAL{std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0)}; const double dMassG{std::abs(v0.mGamma() - o2::constants::physics::MassGamma)}; - const double rapidity{std::abs(v0.yLambda())}; + const double rapidity{v0.yLambda()}; const double lifeTime{v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0}; // Checks if DCA of daughters to PV passes selection @@ -1915,13 +1933,13 @@ struct PiKpRAA { bool isSelected{false}; if (v0Selections.useOfficialV0sSelOfDaughters) { - isSelected = lifeTime < v0Selections.lifeTimeCutLambda && rapidity < v0Selections.rapidityCut && dcaDaugToPV ? true : false; + isSelected = lifeTime < v0Selections.lifeTimeCutLambda && (rapidity > v0Selections.minY && rapidity < v0Selections.maxY) && dcaDaugToPV ? true : false; } if (!v0Selections.useOfficialV0sSelOfDaughters) { if (v0Selections.useTPCNsigma) - isSelected = lifeTime < v0Selections.lifeTimeCutLambda && rapidity < v0Selections.rapidityCut && posTPCNsigma < v0Selections.pidNsigmaCut && negTPCNsigma < v0Selections.pidNsigmaCut && dcaDaugToPV ? true : false; + isSelected = lifeTime < v0Selections.lifeTimeCutLambda && (rapidity > v0Selections.minY && rapidity < v0Selections.maxY) && posTPCNsigma < v0Selections.pidNsigmaCut && negTPCNsigma < v0Selections.pidNsigmaCut && dcaDaugToPV ? true : false; if (!v0Selections.useTPCNsigma) - isSelected = lifeTime < v0Selections.lifeTimeCutLambda && rapidity < v0Selections.rapidityCut && posTOFNsigma < v0Selections.pidNsigmaCut && negTOFNsigma < v0Selections.pidNsigmaCut && hasToF && goodToFmatch && dcaDaugToPV ? true : false; + isSelected = lifeTime < v0Selections.lifeTimeCutLambda && (rapidity > v0Selections.minY && rapidity < v0Selections.maxY) && posTOFNsigma < v0Selections.pidNsigmaCut && negTOFNsigma < v0Selections.pidNsigmaCut && hasToF && goodToFmatch && dcaDaugToPV ? true : false; } if (isSelected) { @@ -1947,7 +1965,7 @@ struct PiKpRAA { const double dMassL{std::abs(v0.mLambda() - o2::constants::physics::MassLambda0)}; const double dMassAL{std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0)}; const double dMassG{std::abs(v0.mGamma() - o2::constants::physics::MassGamma)}; - const float yGamma = RecoDecay::y(std::array{v0.px(), v0.py(), v0.pz()}, o2::constants::physics::MassGamma); + const float rapidity = RecoDecay::y(std::array{v0.px(), v0.py(), v0.pz()}, o2::constants::physics::MassGamma); // Checks if DCA of daughters to PV passes selection const bool dcaDaugToPV{dcaPos > v0Selections.dcaElectronFromGamma && dcaNeg > v0Selections.dcaElectronFromGamma ? true : false}; @@ -1957,7 +1975,7 @@ struct PiKpRAA { return false; } - if (!(std::abs(yGamma) < v0Selections.rapidityCut)) + if (!(rapidity > v0Selections.minY && rapidity < v0Selections.maxY)) return false; bool isSelected{false}; @@ -1967,8 +1985,8 @@ struct PiKpRAA { isSelected = dcaDaugToPV && posTPCNsigma < v0Selections.pidNsigmaCut && negTPCNsigma < v0Selections.pidNsigmaCut ? true : false; if (isSelected) { - registry.fill(HIST("EtaVsYG"), negTrack.eta(), yGamma); - registry.fill(HIST("EtaVsYG"), posTrack.eta(), yGamma); + registry.fill(HIST("EtaVsYG"), negTrack.eta(), rapidity); + registry.fill(HIST("EtaVsYG"), posTrack.eta(), rapidity); } return isSelected; @@ -2003,7 +2021,7 @@ struct PiKpRAA { bool passesPhiSelection(const float& pt, const float& phi) { // Do not apply Phi Sel if pt < 2 GeV/c - if (pt < kTwoPtGeVSel) + if (pt < KtwoPtGeVSel) return true; bool isSelected{true}; @@ -2145,7 +2163,7 @@ struct PiKpRAA { } if (isCentSel) { - if (col.centFT0C() < minT0CcentCut || col.centFT0C() > maxT0CcentCut) { + if (col.centFT0C() < minCentCut || col.centFT0C() > maxCentCut) { return false; } registry.fill(HIST("EventCounter"), EvCutLabel::Centrality); @@ -2183,20 +2201,18 @@ struct PiKpRAA { } } - void loadDCAselections(uint64_t timeStamp) + void loadDCAselections() { if (pathDCAxy.value.empty() == false) { - cfgDCA.hDCAxy = ccdb->getForTimeStamp(pathDCAxy, timeStamp); - if (cfgDCA.hDCAxy == nullptr) { + cfgDCA.hDCAxy = ccdb->getForTimeStamp(pathDCAxy, ccdbNoLaterThan.value); + if (cfgDCA.hDCAxy == nullptr) LOGF(fatal, "Could not load hDCAxy histogram from %s", pathDCAxy.value.c_str()); - } } if (pathDCAz.value.empty() == false) { - cfgDCA.hDCAz = ccdb->getForTimeStamp(pathDCAz, timeStamp); - if (cfgDCA.hDCAz == nullptr) { + cfgDCA.hDCAz = ccdb->getForTimeStamp(pathDCAz, ccdbNoLaterThan.value); + if (cfgDCA.hDCAz == nullptr) LOGF(fatal, "Could not load hDCAz histogram from %s", pathDCAz.value.c_str()); - } } if (cfgDCA.hDCAxy && cfgDCA.hDCAz) cfgDCA.dcaSelectionsLoaded = true; diff --git a/PWGLF/Tasks/Resonances/CMakeLists.txt b/PWGLF/Tasks/Resonances/CMakeLists.txt index 74c48c0872a..eddc93d741b 100644 --- a/PWGLF/Tasks/Resonances/CMakeLists.txt +++ b/PWGLF/Tasks/Resonances/CMakeLists.txt @@ -24,6 +24,11 @@ o2physics_add_dpl_workflow(cksspinalignder PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(phiflowder + SOURCES phiflowder.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(k892analysis SOURCES k892analysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -309,6 +314,11 @@ o2physics_add_dpl_workflow(k892hadronphoton PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::AnalysisCCDB COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(k892hadronphotonbkg + SOURCES k892hadronphotonBkg.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::AnalysisCCDB + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(chk892li SOURCES chk892LI.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGLF/Tasks/Resonances/chk892LI.cxx b/PWGLF/Tasks/Resonances/chk892LI.cxx index ecdc279d04a..db27c412708 100644 --- a/PWGLF/Tasks/Resonances/chk892LI.cxx +++ b/PWGLF/Tasks/Resonances/chk892LI.cxx @@ -16,7 +16,6 @@ /// \author Su-Jeong Ji , Bong-Hwi Lim #include "PWGLF/DataModel/LFStrangenessTables.h" -// #include "PWGLF/DataModel/mcCentrality.h" #include "PWGLF/Utils/collisionCuts.h" #include "PWGLF/Utils/inelGt.h" @@ -444,6 +443,10 @@ struct Chk892LI { histos.add("EffKstar/genKstar_pri", "Gen primary Kstar (|y|<0.5)", HistType::kTH2F, {ptAxis, centAxis}); histos.add("EffKstar/genKstar_pri_pos", "Gen primary Kstar selected by vertex position (|y|<0.5)", HistType::kTH2F, {ptAxis, centAxis}); histos.add("EffKstar/recoKstar", "Kstar Reco matched (final all)", HistType::kTH2F, {ptAxis, centAxis}); + histos.add("EffKstar/recoKstar_vsGenMult", "Reco K* vs gen mid-rapidity multiplicity;#it{p}_{T};N_{ch}^{gen}", HistType::kTH2D, {ptAxis, genMultAxis}); + histos.add("EffKstar/genKstar_vsGenMult", "Gen K* vs gen mid-rapidity multiplicity;#it{p}_{T};N_{ch}^{gen}", HistType::kTH2D, {ptAxis, genMultAxis}); + histos.add("EffKstar/genKstar_pri_vsGenMult", "Gen primary Kstar (|y|<0.5) vs gen mid-rapidity multiplicity", HistType::kTH2D, {ptAxis, genMultAxis}); + histos.add("EffKstar/genKstar_pri_pos_vsGenMult", "Gen primary Kstar selected by vertex position (|y|<0.5) vs gen mid-rapidity multiplicity", HistType::kTH2D, {ptAxis, genMultAxis}); histos.add("Correction/sigLoss_den", "Gen Kstar (|y|<0.5) in truth class", HistType::kTH2F, {ptAxis, centAxis}); histos.add("Correction/sigLoss_den_pri", "Gen primary Kstar (|y|<0.5) in truth class", HistType::kTH2F, {ptAxis, centAxis}); @@ -1084,10 +1087,18 @@ struct Chk892LI { const float lCentrality = iter->second; + auto itGenMult = genMultByMcId.find(mcid); + if (itGenMult == genMultByMcId.end()) { + continue; + } + const int genMult = itGenMult->second; + histos.fill(HIST("EffKstar/genKstar"), part.pt(), lCentrality); + histos.fill(HIST("EffKstar/genKstar_vsGenMult"), part.pt(), genMult); if (part.vt() == 0) { histos.fill(HIST("EffKstar/genKstar_pri"), part.pt(), lCentrality); + histos.fill(HIST("EffKstar/genKstar_pri_vsGenMult"), part.pt(), genMult); } const auto mcc = part.mcCollision_as(); @@ -1100,6 +1111,7 @@ struct Chk892LI { if (distanceFromPV < fMaxPosPV) { histos.fill(HIST("EffKstar/genKstar_pri_pos"), part.pt(), lCentrality); + histos.fill(HIST("EffKstar/genKstar_pri_pos_vsGenMult"), part.pt(), genMult); } } } // effKstarProcessGen @@ -1123,9 +1135,14 @@ struct Chk892LI { if (iter == centTruthByAllowed.end()) { continue; } - const float lCentrality = iter->second; + auto itGenMult = genMultByMcId.find(mcid); + if (itGenMult == genMultByMcId.end()) { + continue; + } + const int genMult = itGenMult->second; + if (!SecondaryCuts.cfgByPassDauPIDSelection) { auto posDauTrack = v0.template posTrack_as(); auto negDauTrack = v0.template negTrack_as(); @@ -1134,6 +1151,7 @@ struct Chk892LI { if (!selectionPIDPion(negDauTrack)) continue; } + if (!selectionK0s(coll, v0)) continue; @@ -1163,6 +1181,7 @@ struct Chk892LI { if (isTrue) { histos.fill(HIST("EffKstar/recoKstar"), ptreco, lCentrality); + histos.fill(HIST("EffKstar/recoKstar_vsGenMult"), ptreco, genMult); histos.fill(HIST("MCReco/hInvmass_Kstar_true"), lCentrality, ptreco, lResoKstar.M()); } else { histos.fill(HIST("MCReco/hInvmass_Kstar_bkg"), lCentrality, ptreco, lResoKstar.M()); diff --git a/PWGLF/Tasks/Resonances/deltaAnalysis.cxx b/PWGLF/Tasks/Resonances/deltaAnalysis.cxx index 2a343c0f57e..7f7809de325 100644 --- a/PWGLF/Tasks/Resonances/deltaAnalysis.cxx +++ b/PWGLF/Tasks/Resonances/deltaAnalysis.cxx @@ -36,9 +36,6 @@ #include #include -#include -#include - #include #include #include diff --git a/PWGLF/Tasks/Resonances/doublephimeson.cxx b/PWGLF/Tasks/Resonances/doublephimeson.cxx index 0c5fa519efe..78d4e47102d 100644 --- a/PWGLF/Tasks/Resonances/doublephimeson.cxx +++ b/PWGLF/Tasks/Resonances/doublephimeson.cxx @@ -61,6 +61,7 @@ struct doublephimeson { Configurable maxPhiPt{"maxPhiPt", 100, "Maximum phi Pt"}; Configurable minPhiMass2{"minPhiMass2", 1.01, "Minimum phi mass2"}; Configurable maxPhiMass2{"maxPhiMass2", 1.03, "Maximum phi mass2"}; + Configurable minExoticPt{"minExoticPt", 6.0, "Minimum Exotic Pt"}; Configurable minExoticMass{"minExoticMass", 2.0, "Minimum Exotic mass"}; Configurable maxExoticMass{"maxExoticMass", 3.6, "Maximum Exotic mass"}; Configurable additionalEvsel{"additionalEvsel", false, "Additional event selection"}; @@ -70,6 +71,72 @@ struct doublephimeson { Configurable cutNsigmaTOF{"cutNsigmaTOF", 3.0, "nsigma cut TOF"}; Configurable momTOFCut{"momTOFCut", 1.8, "minimum pT cut for madnatory TOF"}; Configurable maxKaonPt{"maxKaonPt", 100.0, "maximum kaon pt cut"}; + + // ------------------------------------------------------------ + // pT-dependent phi mass peak and width from single-phi BW fits + // + // DeltaM = sqrt( ((m1 - mean(pt1))/width(pt1))^2 + // + ((m2 - mean(pt2))/width(pt2))^2 ) + // + // Units: + // pT : GeV/c + // mean : GeV/c^2 + // width : GeV/c^2 + // + // 35 pT-bin edges -> 34 mean/width values. + // ------------------------------------------------------------ + + Configurable> cfgPhiPtBins{ + "cfgPhiPtBins", + std::vector{ + 0.4, 0.5, 0.6, 0.8, 0.9, + 1.0, 1.1, 1.2, 1.4, 1.6, + 1.8, 2.0, 2.2, 2.4, 2.6, + 2.8, 3.0, 3.5, 4.0, 4.5, + 5.0, 6.0, 7.0, 8.0, 9.0, + 10.0, 12.0, 14.0, 16.0, 18.0, + 20.0, 25.0, 30.0, 40.0, 100.0}, + "pT bin edges for phi mass peak and width calibration"}; + + Configurable> cfgPhiMeanVsPt{ + "cfgPhiMeanVsPt", + std::vector{ + 1.01779, 1.01826, 1.01897, 1.01924, 1.01934, + 1.01938, 1.01942, 1.01945, 1.01946, 1.01947, + 1.01953, 1.01960, 1.01965, 1.01967, 1.01971, + 1.01972, 1.01974, 1.01977, 1.01980, 1.01983, + 1.01987, 1.01988, 1.01989, 1.01990, 1.01992, + 1.01992, 1.01990, 1.01990, 1.01990, 1.01990, + 1.01990, 1.01990, 1.01990, 1.01990}, + "phi mass peak vs pT from single-phi Breit-Wigner fit"}; + + Configurable> cfgPhiSigmaVsPt{ + "cfgPhiSigmaVsPt", + std::vector{ + 0.00507421, 0.00554344, 0.00554447, 0.00562718, 0.00548766, + 0.00541166, 0.00539718, 0.00539168, 0.00532416, 0.00534485, + 0.00547586, 0.00567904, 0.00579755, 0.00583511, 0.00587245, + 0.00600147, 0.00600020, 0.00610160, 0.00628558, 0.00646913, + 0.00678283, 0.00720555, 0.00753636, 0.00784207, 0.00814550, + 0.00854121, 0.00890474, 0.00981538, 0.01011060, 0.01077820, + 0.01112900, 0.01203120, 0.01372720, 0.02443550}, + "phi Breit-Wigner width vs pT from single-phi fit"}; + + Configurable cfgDefaultPhiMean{ + "cfgDefaultPhiMean", + 1.019461f, + "default phi mass peak if pT is outside calibration range"}; + + Configurable cfgDefaultPhiSigma{ + "cfgDefaultPhiSigma", + 0.0055f, + "default phi width if pT is outside calibration range"}; + + Configurable cfgMinAllowedPhiSigma{ + "cfgMinAllowedPhiSigma", + 1.0e-6f, + "protection against zero or negative phi width"}; + // Event Mixing Configurable nEvtMixing{"nEvtMixing", 1, "Number of events to mix"}; ConfigurableAxis CfgVtxBins{"CfgVtxBins", {10, -10, 10}, "Mixing bins - z-vertex"}; @@ -77,13 +144,15 @@ struct doublephimeson { // THnsparse bining ConfigurableAxis configThnAxisPtCorr{"configThnAxisPtCorr", {1000, 0.0, 100}, "#it{M} (GeV/#it{c}^{2})"}; - ConfigurableAxis configThnAxisInvMass{"configThnAxisInvMass", {1500, 2.0, 3.5}, "#it{M} (GeV/#it{c}^{2})"}; + ConfigurableAxis configThnAxisInvMass{"configThnAxisInvMass", {300, 2.4, 3.0}, "#it{M} (GeV/#it{c}^{2})"}; ConfigurableAxis configThnAxisInvMassPhi{"configThnAxisInvMassPhi", {20, 1.01, 1.03}, "#it{M} (GeV/#it{c}^{2})"}; ConfigurableAxis configThnAxisInvMassDeltaPhi{"configThnAxisInvMassDeltaPhi", {80, 0.0, 0.08}, "#it{M} (GeV/#it{c}^{2})"}; + ConfigurableAxis configThnAxisInvMassDeltaPhiSigma{"configThnAxisInvMassDeltaPhiSigma", {100, 0.0, 10}, "#it{M} (GeV/#it{c}^{2}) sigma"}; ConfigurableAxis configThnAxisDaugherPt{"configThnAxisDaugherPt", {25, 0.0, 50.}, "#it{p}_{T} (GeV/#it{c})"}; ConfigurableAxis configThnAxisPt{"configThnAxisPt", {40, 0.0, 20.}, "#it{p}_{T} (GeV/#it{c})"}; + ConfigurableAxis configThnAxisDaughterPt{"configThnAxisDaughterPt", {100, 0.0, 100.}, "daughter #it{p}_{T} (GeV/#it{c})"}; ConfigurableAxis configThnAxisKstar{"configThnAxisKstar", {200, 0.0, 2.0}, "#it{k}^{*} (GeV/#it{c})"}; - ConfigurableAxis configThnAxisDeltaR{"configThnAxisDeltaR", {200, 0.0, 2.0}, "#it{k}^{*} (GeV/#it{c})"}; + ConfigurableAxis configThnAxisDeltaR{"configThnAxisDeltaR", {VARIABLE_WIDTH, 0.0, 0.0001, 0.0003, 0.0005, 0.0007, 0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009, 0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 2.0, 10.0}, "#it{k}^{*} (GeV/#it{c})"}; ConfigurableAxis configThnAxisCosTheta{"configThnAxisCosTheta", {160, 0.0, 3.2}, "cos #theta{*}"}; ConfigurableAxis configThnAxisNumPhi{"configThnAxisNumPhi", {101, -0.5, 100.5}, "cos #theta{*}"}; ConfigurableAxis configThnAxisDeltaPt{"configThnAxisDeltaPt", {100, 0.0, 1.0}, "delta pt"}; @@ -103,18 +172,23 @@ struct doublephimeson { histos.add("hnsigmaTPCKaonPlus", "hnsigmaTPCKaonPlus", kTH2F, {{1000, -3.0, 3.0f}, {100, 0.0f, 10.0f}}); histos.add("hnsigmaTPCKaonMinus", "hnsigmaTPCKaonMinus", kTH2F, {{1000, -3.0, 3.0f}, {100, 0.0f, 10.0f}}); histos.add("hnsigmaTPCTOFKaon", "hnsigmaTPCTOFKaon", kTH3F, {{500, -3.0, 3.0f}, {500, -3.0, 3.0f}, {100, 0.0f, 10.0f}}); - histos.add("hPhiMass", "hPhiMass", kTH3F, {{40, 1.0, 1.04f}, {40, 1.0, 1.04f}, {100, 0.0f, 10.0f}}); + histos.add("hPhiMassVsPt", "hPhiMassVsPt", kTH2F, {{40, 1.0, 1.04f}, {1000, 0.0f, 100.0f}}); + histos.add("hPhiMass", "hPhiMass", kTH3F, {{40, 1.0, 1.04f}, {40, 1.0, 1.04f}, {250, 0.0f, 100.0f}}); + histos.add("hPhiMassNormalized", "hPhiMassNormalized", kTH3F, {{100, -10.0, 10.0f}, {100, -10.0, 10.0f}, {250, 0.0f, 100.0f}}); histos.add("hPhiMass2", "hPhiMass2", kTH2F, {{40, 1.0, 1.04f}, {40, 1.0f, 1.04f}}); histos.add("hkPlusDeltaetaDeltaPhi", "hkPlusDeltaetaDeltaPhi", kTH2F, {{400, -2.0, 2.0}, {640, -2.0 * TMath::Pi(), 2.0 * TMath::Pi()}}); histos.add("hkMinusDeltaetaDeltaPhi", "hkMinusDeltaetaDeltaPhi", kTH2F, {{400, -2.0, 2.0}, {640, -2.0 * TMath::Pi(), 2.0 * TMath::Pi()}}); histos.add("hDeltaRkaonplus", "hDeltaRkaonplus", kTH1F, {{800, 0.0, 8.0}}); histos.add("hDeltaRkaonminus", "hDeltaRkaonminus", kTH1F, {{800, 0.0, 8.0}}); histos.add("hPtCorrelation", "hPtCorrelation", kTH2F, {{400, 0.0, 40.0}, {5000, 0.0, 100.0}}); + histos.add("hPtCent", "hPtCent", kTH2F, {{100, 0.0, 100.0}, {100, 0.0, 100.0}}); const AxisSpec thnAxisdeltapt{configThnAxisDeltaPt, "Delta pt"}; + const AxisSpec thnAxisdaughterpt{configThnAxisDaughterPt, "Daughter pt"}; const AxisSpec thnAxisInvMass{configThnAxisInvMass, "#it{M} (GeV/#it{c}^{2})"}; const AxisSpec thnAxisPt{configThnAxisPt, "#it{p}_{T} (GeV/#it{c})"}; const AxisSpec thnAxisInvMassPhi{configThnAxisInvMassPhi, "#it{M} (GeV/#it{c}^{2})"}; const AxisSpec thnAxisInvMassDeltaPhi{configThnAxisInvMassDeltaPhi, "#it{M} (GeV/#it{c}^{2})"}; + const AxisSpec thnAxisInvMassDeltaPhiSigma{configThnAxisInvMassDeltaPhiSigma, "#it{M} (GeV/#it{c}^{2}) sigma"}; const AxisSpec thnAxisDeltaR{configThnAxisDeltaR, "#Delta R)"}; const AxisSpec thnAxisCosTheta{configThnAxisCosTheta, "cos #theta"}; const AxisSpec thnAxisNumPhi{configThnAxisNumPhi, "Number of phi meson"}; @@ -129,14 +203,27 @@ struct doublephimeson { histos.add("SEMassUnlike_DeltaRZA", "SEMassUnlike_DeltaRZA", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisDeltaRPhi, thnAxisZ, thnAxisA, thnAxisInvMassDeltaPhi}); histos.add("MEMassUnlike_DeltaRZA", "MEMassUnlike_DeltaRZA", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisDeltaRPhi, thnAxisZ, thnAxisA, thnAxisInvMassDeltaPhi}); histos.add("SEMassUnlike_AllVars", "SEMassUnlike_AllVars", HistType::kTHnSparseF, + {thnAxisInvMass, // M(phi-phi) + thnAxisPt, // pT(phi-phi) + thnAxisDeltaRPhi, // DeltaR(phi,phi) + thnAxisDeltaR, // min DeltaR(K,K) + thnAxisInvMassPhi, + thnAxisInvMassPhi, + thnAxisInvMassDeltaPhi, + thnAxisInvMassDeltaPhiSigma, + thnAxisPtCorr, + thnAxisNumPhi}); // pT correlation variable + + histos.add("MEMassUnlike_AllVars", "MEMassUnlike_AllVars", HistType::kTHnSparseF, {thnAxisInvMass, // M(phi-phi) thnAxisPt, // pT(phi-phi) thnAxisDeltaRPhi, // DeltaR(phi,phi) thnAxisDeltaR, // min DeltaR(K,K) - thnAxisZ, // z = pT1 / (pT1 + pT2) - thnAxisA, // A = |pT1 - pT2| / (pT1 + pT2) - thnAxisInvMassDeltaPhi, // DeltaM(phi1,phi2) - thnAxisPtCorr}); // pT correlation variable + thnAxisInvMassPhi, // m(phi1) + thnAxisInvMassPhi, // m(phi2) + thnAxisInvMassDeltaPhi, // DeltaM_phi + thnAxisPtCorr, + thnAxisNumPhi}); // pT correlation variable } // get kstar @@ -238,7 +325,10 @@ struct doublephimeson { } if (PIDStrategy == 1003) { - if (ptcand < 0.5 && nsigmaTPC > -2.0 && nsigmaTPC < 3.0) { + if (ptcand < 0.5 && TOFHit != 1 && nsigmaTPC > -2.0 && nsigmaTPC < 2.0) { + return true; + } + if (ptcand < 0.5 && TOFHit == 1 && std::sqrt(nsigmaTOF * nsigmaTOF + nsigmaTPC * nsigmaTPC) < 2.5) { return true; } if (ptcand >= 0.5) { @@ -251,6 +341,32 @@ struct doublephimeson { } } + if (PIDStrategy == 1008) { + if (ptcand < 0.5 && TOFHit != 1 && nsigmaTPC > -2.0 && nsigmaTPC < 2.0) { + return true; + } + if (ptcand < 0.5 && TOFHit == 1 && std::sqrt(nsigmaTOF * nsigmaTOF + nsigmaTPC * nsigmaTPC) < 2.5) { + return true; + } + if (ptcand >= 0.5) { + if (TOFHit != 1 && ptcand >= 0.5 && ptcand < 0.6 && nsigmaTPC > -1.5 && nsigmaTPC < 2.0) { + return true; + } + if (TOFHit != 1 && ptcand >= 0.6 && ptcand < 0.7 && nsigmaTPC > -1.0 && nsigmaTPC < 2.0) { + return true; + } + if (TOFHit != 1 && ptcand >= 0.7 && ptcand < 1.0 && nsigmaTPC > 0.0 && nsigmaTPC < 2.0) { + return true; + } + if (TOFHit != 1 && ptcand >= 1.0 && nsigmaTPC > -2.0 && nsigmaTPC < 2.0) { + return true; + } + if (TOFHit == 1 && std::sqrt(nsigmaTOF * nsigmaTOF + nsigmaTPC * nsigmaTPC) < 2.5) { + return true; + } + } + } + if (PIDStrategy == 1005) { // low pT: TPC-only if (ptcand < 0.5 && nsigmaTPC > -2.0 && nsigmaTPC < 3.0) { @@ -304,6 +420,35 @@ struct doublephimeson { } } + if (PIDStrategy == 1007) { + + const bool hasTOF = (TOFHit == 1); + const bool passTPC_low = (nsigmaTPC > -2.0 && nsigmaTPC < 3.0); + const bool passTPC_midNoTOF = (nsigmaTPC > -1.5 && nsigmaTPC < 3.0); + const bool passTPC_highNoTOF = (nsigmaTPC > -2.0 && nsigmaTPC < 2.0); + + const bool passTPC_TOF = + hasTOF && std::sqrt(nsigmaTOF * nsigmaTOF + nsigmaTPC * nsigmaTPC) < 2.5; + + if (ptcand < 0.5) { + if (passTPC_low) + return true; + } else if (ptcand < 0.7) { + if (hasTOF && passTPC_TOF) + return true; + if (!hasTOF && passTPC_midNoTOF) + return true; + } else if (ptcand < 1.1) { + if (passTPC_TOF) + return true; + } else { + if (hasTOF && passTPC_TOF) + return true; + if (!hasTOF && passTPC_highNoTOF) + return true; + } + } + if (PIDStrategy == 100) { if (ptcand < 1.2) { if (TOFHit == 1 && std::sqrt(nsigmaTOF * nsigmaTOF + nsigmaTPC * nsigmaTPC) < 2.5) { @@ -571,6 +716,91 @@ struct doublephimeson { TLorentzVector Phi1kaonplus, Phi1kaonminus, Phi2kaonplus, Phi2kaonminus; // TLorentzVector exoticRot, Phid1Rot; + int getPhiPtCalibBin(float pt) + { + const auto& bins = cfgPhiPtBins.value; + + if (bins.size() < 2) { + return -1; + } + + if (pt < bins.front()) { + return -1; + } + + for (size_t i = 0; i + 1 < bins.size(); ++i) { + if (pt >= bins[i] && pt < bins[i + 1]) { + return static_cast(i); + } + } + + if (pt >= bins.back()) { + return static_cast(bins.size()) - 2; + } + + return -1; + } + + float getPhiMassPeakVsPt(float pt) + { + const int ibin = getPhiPtCalibBin(pt); + const auto& means = cfgPhiMeanVsPt.value; + + if (ibin >= 0 && ibin < static_cast(means.size())) { + return means[ibin]; + } + + return cfgDefaultPhiMean.value; + } + + float getPhiWidthVsPt(float pt) + { + const int ibin = getPhiPtCalibBin(pt); + const auto& widths = cfgPhiSigmaVsPt.value; + + float width = cfgDefaultPhiSigma.value; + + if (ibin >= 0 && ibin < static_cast(widths.size())) { + width = widths[ibin]; + } + + if (width < cfgMinAllowedPhiSigma.value) { + width = cfgDefaultPhiSigma.value; + } + + return width; + } + + float getNormalizedDeltaMPhi(float m1, float pt1, float m2, float pt2) + { + const float mean1 = getPhiMassPeakVsPt(pt1); + const float mean2 = getPhiMassPeakVsPt(pt2); + + const float width1 = getPhiWidthVsPt(pt1); + const float width2 = getPhiWidthVsPt(pt2); + + return TMath::Sqrt( + TMath::Power((m1 - mean1) / width1, 2.0) + + TMath::Power((m2 - mean2) / width2, 2.0)); + } + + float getDeltaMPhi(float m1, float pt1, float m2, float pt2) + { + const float mean1 = getPhiMassPeakVsPt(pt1); + const float mean2 = getPhiMassPeakVsPt(pt2); + + return TMath::Sqrt( + TMath::Power((m1 - mean1), 2.0) + + TMath::Power((m2 - mean2), 2.0)); + } + + float getNormalizedMPhi(float m1, float pt1) + { + const float mean1 = getPhiMassPeakVsPt(pt1); + const float width1 = getPhiWidthVsPt(pt1); + return ((m1 - mean1) / width1); + } + void processSE(aod::RedPhiEvents::iterator const& collision, aod::PhiTracks const& phitracks) { if (additionalEvsel && (collision.numPos() < 2 || collision.numNeg() < 2)) { @@ -1285,9 +1515,8 @@ struct doublephimeson { const double minDR = minDRV[i]; // (optional but recommended) protect ptcorr from blow-ups - const double denom = (pair.Pt() - p1.Pt()); - if (std::abs(denom) < 1e-9) - continue; + const double denom = std::abs(pair.Pt() - p1.Pt()); + const double ptcorr = p1.Pt() / denom; histos.fill(HIST("hPtCorrelation"), pair.Pt(), ptcorr); @@ -1323,6 +1552,7 @@ struct doublephimeson { // --- phi multiplicity with PID --- int phimult = 0; + // int nBestPairingRejected = 0; for (auto const& t : phitracks) { const double kpluspt = std::hypot(t.phid1Px(), t.phid1Py()); const double kminuspt = std::hypot(t.phid2Px(), t.phid2Py()); @@ -1334,6 +1564,11 @@ struct doublephimeson { if (t.phiMass() < minPhiMass1 || t.phiMass() > maxPhiMass1) { continue; } + TLorentzVector phi1; + phi1.SetXYZM(t.phiPx(), t.phiPy(), t.phiPz(), t.phiMass()); + if (phi1.Pt() < minPhiPt || phi1.Pt() > maxPhiPt) { + continue; + } if (kpluspt > maxKaonPt || kminuspt > maxKaonPt) { continue; } @@ -1347,6 +1582,7 @@ struct doublephimeson { histos.fill(HIST("hnsigmaTPCTOFKaon"), t.phid1TPC(), t.phid1TOF(), kpluspt); histos.fill(HIST("hnsigmaTPCKaonPlus"), t.phid1TPC(), kpluspt); histos.fill(HIST("hnsigmaTPCKaonMinus"), t.phid2TPC(), kminuspt); + histos.fill(HIST("hPhiMassVsPt"), t.phiMass(), phi1.Pt()); ++phimult; } @@ -1358,11 +1594,12 @@ struct doublephimeson { constexpr double mPhiPDG = o2::constants::physics::MassPhi; // GeV/c^2 constexpr double mKPDG = o2::constants::physics::MassKPlus; // GeV/c^2 - const auto deltaMPhi = [=](double m1, double m2) { + const auto deltaMPhiNominal = [=](double m1, double m2) { const double d1 = m1 - mPhiPDG; const double d2 = m2 - mPhiPDG; return std::sqrt(d1 * d1 + d2 * d2); }; + const auto deltaR = [](double phi1, double eta1, double phi2, double eta2) { const double dphi = std::abs(TVector2::Phi_mpi_pi(phi1 - phi2)); const double deta = eta1 - eta2; @@ -1443,14 +1680,6 @@ struct doublephimeson { continue; } - // reject any shared daughter between the two phi candidates - if (t1.phid1Index() == t2.phid1Index() || - t1.phid1Index() == t2.phid2Index() || - t1.phid2Index() == t2.phid1Index() || - t1.phid2Index() == t2.phid2Index()) { - continue; - } - TLorentzVector phi2; TLorentzVector k2p; TLorentzVector k2m; @@ -1466,17 +1695,46 @@ struct doublephimeson { continue; } - const double dM = deltaMPhi(phi1.M(), phi2.M()); - if (dM > maxDeltaMPhi) { + TLorentzVector pair = phi1 + phi2; + if (pair.Pt() < minExoticPt) { continue; } - - TLorentzVector pair = phi1 + phi2; if (pair.M() < minExoticMass || pair.M() > maxExoticMass) { continue; } + // reject any shared daughter between the two phi candidates + if (t1.phid1Index() == t2.phid1Index() || + t1.phid1Index() == t2.phid2Index() || + t1.phid2Index() == t2.phid1Index() || + t1.phid2Index() == t2.phid2Index()) { + // LOGF(info,"track share",t1.phid1Index(),t1.phid2Index(),t2.phid1Index(),t2.phid2Index()); + continue; + } + // const double dMNominal = deltaMPhiNominal(phi1.M(), phi2.M()); + const double mCross12 = (k1p + k2m).M(); // K+ from phi1 + K- from phi2 + const double mCross21 = (k2p + k1m).M(); // K+ from phi2 + K- from phi1 + const double dMCross = deltaMPhiNominal(mCross12, mCross21); + // Reject this candidate only if the crossed assignment is more phi-like + if (dMCross > 1.01 && dMCross < 1.03) { + // ++nBestPairingRejected; + /* + LOGF(info, + "Best-pairing rejected: dMNominal = %.6f, dMCross = %.6f, " + "mPhi1 = %.6f, mPhi2 = %.6f, mCross12 = %.6f, mCross21 = %.6f", + dMNominal, + dMCross, + phi1.M(), + phi2.M(), + mCross12, + mCross21, + pair.Pt(), + pair.M()); + */ + continue; + } histos.fill(HIST("hPhiMass"), phi1.M(), phi2.M(), pair.Pt()); + histos.fill(HIST("hPhiMassNormalized"), getNormalizedMPhi(phi1.M(), phi1.Pt()), getNormalizedMPhi(phi2.M(), phi2.Pt()), pair.Pt()); ROOT::Math::PtEtaPhiMVector k1pV(k1p.Pt(), k1p.Eta(), k1p.Phi(), mKPDG); ROOT::Math::PtEtaPhiMVector k1mV(k1m.Pt(), k1m.Eta(), k1m.Phi(), mKPDG); @@ -1509,12 +1767,9 @@ struct doublephimeson { const double pairPt = pair.Pt(); const double dRphi = deltaR(p1.Phi(), p1.Eta(), p2.Phi(), p2.Eta()); const double minDR = minDRV[i]; - const double dM = deltaMPhi(p1.M(), p2.M()); - - const double denom = pairPt - p1.Pt(); - if (std::abs(denom) < 1e-9) { - continue; - } + const double dMNominal = getDeltaMPhi(p1.M(), p1.Pt(), p2.M(), p2.Pt()); + const double dMNominalNsigma = getNormalizedDeltaMPhi(p1.M(), p1.Pt(), p2.M(), p2.Pt()); + const double denom = std::abs(pairPt - p1.Pt()); const double ptcorr = p1.Pt() / denom; @@ -1524,29 +1779,21 @@ struct doublephimeson { if (ptsum <= 0.0) { continue; } - - const double z = pt1 / ptsum; - const double A = std::abs(pt1 - pt2) / ptsum; - - histos.fill(HIST("hPtCorrelation"), pairPt, ptcorr); - - histos.fill(HIST("SEMassUnlike"), - M, - minDR, - pairPt, - dRphi, - dM, - ptcorr); - - histos.fill(HIST("SEMassUnlike_AllVars"), - M, - pairPt, - dRphi, - minDR, - z, - A, - dM, - ptcorr); + if (pairPt > minExoticPt) { + histos.fill(HIST("hPtCorrelation"), pairPt, ptcorr); + histos.fill(HIST("hPtCent"), pairPt, collision.centrality()); + histos.fill(HIST("SEMassUnlike_AllVars"), + M, + pairPt, + dRphi, + minDR, + p1.M(), + p2.M(), + dMNominal, + dMNominalNsigma, + ptcorr, + pairV.size()); + } } } PROCESS_SWITCH(doublephimeson, processopti5, "Process Optimized same event with all variables", true); @@ -1554,6 +1801,265 @@ struct doublephimeson { SliceCache cache; using BinningTypeVertexContributor = ColumnBinningPolicy; + void processMixedEventopti5(aod::RedPhiEvents& collisions, aod::PhiTracks& phitracks) + { + auto tracksTuple = std::make_tuple(phitracks); + + BinningTypeVertexContributor binningOnPositions{{CfgVtxBins, CfgMultBins}, true}; + + SameKindPair pair{ + binningOnPositions, nEvtMixing, -1, collisions, tracksTuple, &cache}; + + constexpr double mKPDG = o2::constants::physics::MassKPlus; // GeV/c^2 + + const auto deltaR = [](double phi1, double eta1, double phi2, double eta2) { + const double dphi = std::abs(TVector2::Phi_mpi_pi(phi1 - phi2)); + const double deta = eta1 - eta2; + return std::sqrt(dphi * dphi + deta * deta); + }; + + const auto minKaonDeltaR = + [&](const ROOT::Math::PtEtaPhiMVector& kplus1, + const ROOT::Math::PtEtaPhiMVector& kminus1, + const ROOT::Math::PtEtaPhiMVector& kplus2, + const ROOT::Math::PtEtaPhiMVector& kminus2) { + const double dRkplus = + deltaR(kplus1.Phi(), kplus1.Eta(), kplus2.Phi(), kplus2.Eta()); + + const double dRkminus = + deltaR(kminus1.Phi(), kminus1.Eta(), kminus2.Phi(), kminus2.Eta()); + + histos.fill(HIST("hDeltaRkaonplus"), dRkplus); + histos.fill(HIST("hDeltaRkaonminus"), dRkminus); + + double minDR = dRkplus; + minDR = std::min(minDR, dRkminus); + + minDR = std::min(minDR, + deltaR(kplus1.Phi(), kplus1.Eta(), + kminus1.Phi(), kminus1.Eta())); + + minDR = std::min(minDR, + deltaR(kplus1.Phi(), kplus1.Eta(), + kminus2.Phi(), kminus2.Eta())); + + minDR = std::min(minDR, + deltaR(kplus2.Phi(), kplus2.Eta(), + kminus1.Phi(), kminus1.Eta())); + + minDR = std::min(minDR, + deltaR(kplus2.Phi(), kplus2.Eta(), + kminus2.Phi(), kminus2.Eta())); + + return minDR; + }; + + struct PhiCand { + ROOT::Math::PtEtaPhiMVector phi; + ROOT::Math::PtEtaPhiMVector kplus; + ROOT::Math::PtEtaPhiMVector kminus; + }; + + for (auto& [collision1, tracks1, collision2, tracks2] : pair) { + + if (collision1.index() == collision2.index()) { + continue; + } + + if (additionalEvsel) { + if (collision1.numPos() < 2 || collision1.numNeg() < 2) { + continue; + } + if (collision2.numPos() < 2 || collision2.numNeg() < 2) { + continue; + } + } + + std::vector cands1; + std::vector cands2; + + // ====================================================== + // Build phi candidates from event 1 + // ====================================================== + for (auto const& t1 : tracks1) { + const double kplus1pt = std::hypot(t1.phid1Px(), t1.phid1Py()); + const double kminus1pt = std::hypot(t1.phid2Px(), t1.phid2Py()); + + if (kplus1pt > maxKaonPt || kminus1pt > maxKaonPt) { + continue; + } + + if (!selectionPID(t1.phid1TPC(), t1.phid1TOF(), t1.phid1TOFHit(), + strategyPID1, kplus1pt)) { + continue; + } + + if (!selectionPID(t1.phid2TPC(), t1.phid2TOF(), t1.phid2TOFHit(), + strategyPID2, kminus1pt)) { + continue; + } + + if (t1.phiMass() < minPhiMass1 || t1.phiMass() > maxPhiMass1) { + continue; + } + + TLorentzVector phi1; + TLorentzVector k1p; + TLorentzVector k1m; + + phi1.SetXYZM(t1.phiPx(), t1.phiPy(), t1.phiPz(), t1.phiMass()); + k1p.SetXYZM(t1.phid1Px(), t1.phid1Py(), t1.phid1Pz(), mKPDG); + k1m.SetXYZM(t1.phid2Px(), t1.phid2Py(), t1.phid2Pz(), mKPDG); + + if (phi1.Pt() < minPhiPt || phi1.Pt() > maxPhiPt) { + continue; + } + + PhiCand cand; + cand.phi = ROOT::Math::PtEtaPhiMVector(phi1.Pt(), phi1.Eta(), phi1.Phi(), phi1.M()); + cand.kplus = ROOT::Math::PtEtaPhiMVector(k1p.Pt(), k1p.Eta(), k1p.Phi(), mKPDG); + cand.kminus = ROOT::Math::PtEtaPhiMVector(k1m.Pt(), k1m.Eta(), k1m.Phi(), mKPDG); + + cands1.emplace_back(std::move(cand)); + } + + // ====================================================== + // Build phi candidates from event 2 + // ====================================================== + for (auto const& t2 : tracks2) { + const double kplus2pt = std::hypot(t2.phid1Px(), t2.phid1Py()); + const double kminus2pt = std::hypot(t2.phid2Px(), t2.phid2Py()); + + if (kplus2pt > maxKaonPt || kminus2pt > maxKaonPt) { + continue; + } + + if (!selectionPID(t2.phid1TPC(), t2.phid1TOF(), t2.phid1TOFHit(), + strategyPID1, kplus2pt)) { + continue; + } + + if (!selectionPID(t2.phid2TPC(), t2.phid2TOF(), t2.phid2TOFHit(), + strategyPID2, kminus2pt)) { + continue; + } + + if (t2.phiMass() < minPhiMass2 || t2.phiMass() > maxPhiMass2) { + continue; + } + + TLorentzVector phi2; + TLorentzVector k2p; + TLorentzVector k2m; + + phi2.SetXYZM(t2.phiPx(), t2.phiPy(), t2.phiPz(), t2.phiMass()); + k2p.SetXYZM(t2.phid1Px(), t2.phid1Py(), t2.phid1Pz(), mKPDG); + k2m.SetXYZM(t2.phid2Px(), t2.phid2Py(), t2.phid2Pz(), mKPDG); + + if (phi2.Pt() < minPhiPt || phi2.Pt() > maxPhiPt) { + continue; + } + + PhiCand cand; + cand.phi = ROOT::Math::PtEtaPhiMVector(phi2.Pt(), phi2.Eta(), phi2.Phi(), phi2.M()); + cand.kplus = ROOT::Math::PtEtaPhiMVector(k2p.Pt(), k2p.Eta(), k2p.Phi(), mKPDG); + cand.kminus = ROOT::Math::PtEtaPhiMVector(k2m.Pt(), k2m.Eta(), k2m.Phi(), mKPDG); + + cands2.emplace_back(std::move(cand)); + } + + if (cands1.empty() || cands2.empty()) { + continue; + } + + // ====================================================== + // Build mixed-event phi-phi pairs + // ====================================================== + for (auto const& c1 : cands1) { + + TLorentzVector phi1; + TLorentzVector k1p; + TLorentzVector k1m; + + phi1.SetPtEtaPhiM(c1.phi.Pt(), c1.phi.Eta(), c1.phi.Phi(), c1.phi.M()); + k1p.SetPtEtaPhiM(c1.kplus.Pt(), c1.kplus.Eta(), c1.kplus.Phi(), mKPDG); + k1m.SetPtEtaPhiM(c1.kminus.Pt(), c1.kminus.Eta(), c1.kminus.Phi(), mKPDG); + + for (auto const& c2 : cands2) { + + TLorentzVector phi2; + TLorentzVector k2p; + TLorentzVector k2m; + + phi2.SetPtEtaPhiM(c2.phi.Pt(), c2.phi.Eta(), c2.phi.Phi(), c2.phi.M()); + k2p.SetPtEtaPhiM(c2.kplus.Pt(), c2.kplus.Eta(), c2.kplus.Phi(), mKPDG); + k2m.SetPtEtaPhiM(c2.kminus.Pt(), c2.kminus.Eta(), c2.kminus.Phi(), mKPDG); + + const double dM = getDeltaMPhi(phi1.M(), phi1.Pt(), + phi2.M(), phi2.Pt()); + + TLorentzVector pairPhiPhi = phi1 + phi2; + + if (pairPhiPhi.Pt() < minExoticPt) { + continue; + } + + const double minDR = + minKaonDeltaR(c1.kplus, c1.kminus, c2.kplus, c2.kminus); + + const double dRphi = + deltaR(phi1.Phi(), phi1.Eta(), phi2.Phi(), phi2.Eta()); + + const double denom = std::abs(pairPhiPhi.Pt() - phi1.Pt()); + if (denom < 1e-9) { + continue; + } + + const double ptcorr = phi1.Pt() / denom; + + const double pt1 = phi1.Pt(); + const double pt2 = phi2.Pt(); + const double ptsum = pt1 + pt2; + + if (ptsum <= 0.0) { + continue; + } + + const double z = pt1 / ptsum; + const double A = std::abs(pt1 - pt2) / ptsum; + + histos.fill(HIST("MEMassUnlike"), + pairPhiPhi.M(), + minDR, + pairPhiPhi.Pt(), + dRphi, + dM, + ptcorr); + + histos.fill(HIST("MEMassUnlike_DeltaRZA"), + pairPhiPhi.M(), + pairPhiPhi.Pt(), + pairPhiPhi.Pt() * dRphi, + z, + A, + dM); + + histos.fill(HIST("MEMassUnlike_AllVars"), + pairPhiPhi.M(), + pairPhiPhi.Pt(), + dRphi, + minDR, + phi1.M(), + phi2.M(), + dM, + ptcorr); + } + } + } + } + PROCESS_SWITCH(doublephimeson, processMixedEventopti5, + "Process EventMixing for combinatorial background", false); + void processMixedEvent(aod::RedPhiEvents& collisions, aod::PhiTracks& phitracks) { auto tracksTuple = std::make_tuple(phitracks); diff --git a/PWGLF/Tasks/Resonances/k892hadronphoton.cxx b/PWGLF/Tasks/Resonances/k892hadronphoton.cxx index e4fbc8c83f8..839079331fd 100644 --- a/PWGLF/Tasks/Resonances/k892hadronphoton.cxx +++ b/PWGLF/Tasks/Resonances/k892hadronphoton.cxx @@ -60,12 +60,12 @@ using namespace o2::framework::expressions; using KStars = soa::Join; using MCKStars = soa::Join; -static const std::vector PhotonSels = {"NoSel", "V0Type", "DCADauToPV", +static const std::vector photonSels = {"NoSel", "V0Type", "DCADauToPV", "DCADau", "DauTPCCR", "TPCNSigmaEl", "V0pT", "Y", "V0Radius", "RZCut", "Armenteros", "CosPA", "PsiPair", "Phi", "Mass"}; -static const std::vector KShortSels = {"NoSel", "V0Radius", "DCADau", "Armenteros", +static const std::vector kshortSels = {"NoSel", "V0Radius", "DCADau", "Armenteros", "CosPA", "Y", "TPCCR", "DauITSCls", "Lifetime", "TPCTOFPID", "DCADauToPV", "Mass"}; @@ -121,7 +121,7 @@ struct k892hadronphoton { } eventSelections; // generated - Configurable mc_keepOnlyFromGenerator{"mc_keepOnlyFromGenerator", true, "if true, consider only particles from generator to calculate efficiency."}; + Configurable mcKeepOnlyFromGenerator{"mcKeepOnlyFromGenerator", true, "if true, consider only particles from generator to calculate efficiency."}; // QA Configurable fillBkgQAhistos{"fillBkgQAhistos", false, "if true, fill MC QA histograms for Bkg study. Only works with MC."}; @@ -134,65 +134,65 @@ struct k892hadronphoton { //// K0Short criteria: struct : ConfigurableGroup { - Configurable KShort_MLThreshold{"KShort_MLThreshold", 0.1, "Decision Threshold value to select kshorts"}; - Configurable KShortMinDCANegToPv{"KShortMinDCANegToPv", .05, "min DCA Neg To PV (cm)"}; - Configurable KShortMinDCAPosToPv{"KShortMinDCAPosToPv", .05, "min DCA Pos To PV (cm)"}; - Configurable KShortMaxDCAV0Dau{"KShortMaxDCAV0Dau", 2.5, "Max DCA V0 Daughters (cm)"}; - Configurable KShortMinv0radius{"KShortMinv0radius", 0.0, "Min V0 radius (cm)"}; - Configurable KShortMaxv0radius{"KShortMaxv0radius", 40, "Max V0 radius (cm)"}; - Configurable KShortMinQt{"KShortMinQt", 0.1, "Min kshort qt value (AP plot) (GeV/c)"}; - Configurable KShortMaxQt{"KShortMaxQt", 2.5, "Max kshort qt value (AP plot) (GeV/c)"}; - Configurable KShortMinAlpha{"KShortMinAlpha", 0.0, "Min kshort alpha absolute value (AP plot)"}; - Configurable KShortMaxAlpha{"KShortMaxAlpha", 1.0, "Max kshort alpha absolute value (AP plot)"}; - Configurable KShortMinv0cospa{"KShortMinv0cospa", 0.95, "Min V0 CosPA"}; - Configurable KShortMaxLifeTime{"KShortMaxLifeTime", 30, "Max lifetime"}; - Configurable KShortWindow{"KShortWindow", 0.015, "Mass window around expected (in GeV/c2)"}; - Configurable KShortMaxRap{"KShortMaxRap", 0.8, "Max kshort rapidity"}; - Configurable KShortMaxDauEta{"KShortMaxDauEta", 0.8, "Max pseudorapidity of daughter tracks"}; + Configurable kshortMLThreshold{"kshortMLThreshold", 0.1, "Decision Threshold value to select kshorts"}; + Configurable kshortMinDCANegToPv{"kshortMinDCANegToPv", .05, "min DCA Neg To PV (cm)"}; + Configurable kshortMinDCAPosToPv{"kshortMinDCAPosToPv", .05, "min DCA Pos To PV (cm)"}; + Configurable kshortMaxDCAV0Dau{"kshortMaxDCAV0Dau", 2.5, "Max DCA V0 Daughters (cm)"}; + Configurable kshortMinv0radius{"kshortMinv0radius", 0.0, "Min V0 radius (cm)"}; + Configurable kshortMaxv0radius{"kshortMaxv0radius", 40, "Max V0 radius (cm)"}; + Configurable kshortMinQt{"kshortMinQt", 0.1, "Min kshort qt value (AP plot) (GeV/c)"}; + Configurable kshortMaxQt{"kshortMaxQt", 2.5, "Max kshort qt value (AP plot) (GeV/c)"}; + Configurable kshortMinAlpha{"kshortMinAlpha", 0.0, "Min kshort alpha absolute value (AP plot)"}; + Configurable kshortMaxAlpha{"kshortMaxAlpha", 1.0, "Max kshort alpha absolute value (AP plot)"}; + Configurable kshortMinv0cospa{"kshortMinv0cospa", 0.95, "Min V0 CosPA"}; + Configurable kshortMaxLifeTime{"kshortMaxLifeTime", 30, "Max lifetime"}; + Configurable kshortWindow{"kshortWindow", 0.015, "Mass window around expected (in GeV/c2)"}; + Configurable kshortMaxRap{"kshortMaxRap", 0.8, "Max kshort rapidity"}; + Configurable kshortMaxDauEta{"kshortMaxDauEta", 0.8, "Max pseudorapidity of daughter tracks"}; Configurable fselKShortTPCPID{"fselKShortTPCPID", true, "Flag to select kshort-like candidates using TPC NSigma."}; Configurable fselKShortTOFPID{"fselKShortTOFPID", false, "Flag to select kshort-like candidates using TOF NSigma."}; - Configurable KShortMaxTPCNSigmas{"KShortMaxTPCNSigmas", 1e+9, "Max TPC NSigmas for daughters"}; - // Configurable KShortPrMaxTOFNSigmas{"KShortPrMaxTOFNSigmas", 1e+9, "Max TOF NSigmas for daughters"}; - Configurable KShortPiMaxTOFNSigmas{"KShortPiMaxTOFNSigmas", 1e+9, "Max TOF NSigmas for daughters"}; - Configurable KShortMinTPCCrossedRows{"KShortMinTPCCrossedRows", 50, "Min daughter TPC Crossed Rows"}; - Configurable KShortMinITSclusters{"KShortMinITSclusters", 1, "minimum ITS clusters"}; - Configurable KShortRejectPosITSafterburner{"KShortRejectPosITSafterburner", false, "reject positive track formed out of afterburner ITS tracks"}; - Configurable KShortRejectNegITSafterburner{"KShortRejectNegITSafterburner", false, "reject negative track formed out of afterburner ITS tracks"}; + Configurable kshortMaxTPCNSigmas{"kshortMaxTPCNSigmas", 1e+9, "Max TPC NSigmas for daughters"}; + // Configurable kshortMaxTOFNSigmas{"kshortMaxTOFNSigmas", 1e+9, "Max TOF NSigmas for daughters"}; + Configurable kshortPiMaxTOFNSigmas{"kshortPiMaxTOFNSigmas", 1e+9, "Max TOF NSigmas for daughters"}; + Configurable kshortMinTPCCrossedRows{"kshortMinTPCCrossedRows", 50, "Min daughter TPC Crossed Rows"}; + Configurable kshortMinITSclusters{"kshortMinITSclusters", 1, "minimum ITS clusters"}; + Configurable kshortRejectPosITSafterburner{"kshortRejectPosITSafterburner", false, "reject positive track formed out of afterburner ITS tracks"}; + Configurable kshortRejectNegITSafterburner{"kshortRejectNegITSafterburner", false, "reject negative track formed out of afterburner ITS tracks"}; } kshortSelections; //// Photon criteria: struct : ConfigurableGroup { - Configurable Gamma_MLThreshold{"Gamma_MLThreshold", 0.1, "Decision Threshold value to select gammas"}; - Configurable Photonv0TypeSel{"Photonv0TypeSel", 7, "select on a certain V0 type (leave negative if no selection desired)"}; - Configurable PhotonMinDCADauToPv{"PhotonMinDCADauToPv", 0.0, "Min DCA daughter To PV (cm)"}; - Configurable PhotonMaxDCAV0Dau{"PhotonMaxDCAV0Dau", 3.5, "Max DCA V0 Daughters (cm)"}; - Configurable PhotonMinTPCCrossedRows{"PhotonMinTPCCrossedRows", 30, "Min daughter TPC Crossed Rows"}; - Configurable PhotonMinTPCNSigmas{"PhotonMinTPCNSigmas", -7, "Min TPC NSigmas for daughters"}; - Configurable PhotonMaxTPCNSigmas{"PhotonMaxTPCNSigmas", 7, "Max TPC NSigmas for daughters"}; - Configurable PhotonMinPt{"PhotonMinPt", 0.0, "Min photon pT (GeV/c)"}; - Configurable PhotonMaxPt{"PhotonMaxPt", 50.0, "Max photon pT (GeV/c)"}; - Configurable PhotonMaxRap{"PhotonMaxRap", 0.5, "Max photon rapidity"}; - Configurable PhotonMinRadius{"PhotonMinRadius", 3.0, "Min photon conversion radius (cm)"}; - Configurable PhotonMaxRadius{"PhotonMaxRadius", 115, "Max photon conversion radius (cm)"}; - Configurable PhotonMaxZ{"PhotonMaxZ", 240, "Max photon conversion point z value (cm)"}; - Configurable PhotonMaxQt{"PhotonMaxQt", 0.05, "Max photon qt value (AP plot) (GeV/c)"}; - Configurable PhotonMaxAlpha{"PhotonMaxAlpha", 0.95, "Max photon alpha absolute value (AP plot)"}; - Configurable PhotonMinV0cospa{"PhotonMinV0cospa", 0.80, "Min V0 CosPA"}; - Configurable PhotonMaxMass{"PhotonMaxMass", 0.10, "Max photon mass (GeV/c^{2})"}; - Configurable PhotonPsiPairMax{"PhotonPsiPairMax", 1e+9, "maximum psi angle of the track pair"}; - Configurable PhotonMaxDauEta{"PhotonMaxDauEta", 0.8, "Max pseudorapidity of daughter tracks"}; - Configurable PhotonLineCutZ0{"PhotonLineCutZ0", 7.0, "The offset for the linecute used in the Z vs R plot"}; - Configurable PhotonPhiMin1{"PhotonPhiMin1", -1, "Phi min value to reject photons, region 1 (leave negative if no selection desired)"}; - Configurable PhotonPhiMax1{"PhotonPhiMax1", -1, "Phi max value to reject photons, region 1 (leave negative if no selection desired)"}; - Configurable PhotonPhiMin2{"PhotonPhiMin2", -1, "Phi max value to reject photons, region 2 (leave negative if no selection desired)"}; - Configurable PhotonPhiMax2{"PhotonPhiMax2", -1, "Phi min value to reject photons, region 2 (leave negative if no selection desired)"}; + Configurable gammaMLThreshold{"gammaMLThreshold", 0.1, "Decision Threshold value to select gammas"}; + Configurable photonv0TypeSel{"photonv0TypeSel", 7, "select on a certain V0 type (leave negative if no selection desired)"}; + Configurable photonMinDCADauToPv{"photonMinDCADauToPv", 0.0, "Min DCA daughter To PV (cm)"}; + Configurable photonMaxDCAV0Dau{"photonMaxDCAV0Dau", 3.5, "Max DCA V0 Daughters (cm)"}; + Configurable photonMinTPCCrossedRows{"photonMinTPCCrossedRows", 30, "Min daughter TPC Crossed Rows"}; + Configurable photonMinTPCNSigmas{"photonMinTPCNSigmas", -7, "Min TPC NSigmas for daughters"}; + Configurable photonMaxTPCNSigmas{"photonMaxTPCNSigmas", 7, "Max TPC NSigmas for daughters"}; + Configurable photonMinPt{"photonMinPt", 0.0, "Min photon pT (GeV/c)"}; + Configurable photonMaxPt{"photonMaxPt", 50.0, "Max photon pT (GeV/c)"}; + Configurable photonMaxRap{"photonMaxRap", 0.5, "Max photon rapidity"}; + Configurable photonMinRadius{"photonMinRadius", 3.0, "Min photon conversion radius (cm)"}; + Configurable photonMaxRadius{"photonMaxRadius", 115, "Max photon conversion radius (cm)"}; + Configurable photonMaxZ{"photonMaxZ", 240, "Max photon conversion point z value (cm)"}; + Configurable photonMaxQt{"photonMaxQt", 0.05, "Max photon qt value (AP plot) (GeV/c)"}; + Configurable photonMaxAlpha{"photonMaxAlpha", 0.95, "Max photon alpha absolute value (AP plot)"}; + Configurable photonMinV0cospa{"photonMinV0cospa", 0.80, "Min V0 CosPA"}; + Configurable photonMaxMass{"photonMaxMass", 0.10, "Max photon mass (GeV/c^{2})"}; + Configurable photonPsiPairMax{"photonPsiPairMax", 1e+9, "maximum psi angle of the track pair"}; + Configurable photonMaxDauEta{"photonMaxDauEta", 0.8, "Max pseudorapidity of daughter tracks"}; + Configurable photonLineCutZ0{"photonLineCutZ0", 7.0, "The offset for the linecute used in the Z vs R plot"}; + Configurable photonPhiMin1{"photonPhiMin1", -1, "Phi min value to reject photons, region 1 (leave negative if no selection desired)"}; + Configurable photonPhiMax1{"photonPhiMax1", -1, "Phi max value to reject photons, region 1 (leave negative if no selection desired)"}; + Configurable photonPhiMin2{"photonPhiMin2", -1, "Phi max value to reject photons, region 2 (leave negative if no selection desired)"}; + Configurable photonPhiMax2{"photonPhiMax2", -1, "Phi min value to reject photons, region 2 (leave negative if no selection desired)"}; } photonSelections; struct : ConfigurableGroup { - Configurable KStarMaxRap{"KStarMaxRap", 0.5, "Max kstar rapidity"}; - Configurable KStarMaxRadius{"KStarMaxRadius", 200, "Max kstar decay radius"}; - Configurable KStarMaxDCADau{"KStarMaxDCADau", 50, "Max kstar DCA between daughters"}; - Configurable KStarMaxOPAngle{"KStarMaxOPAngle", 7, "Max kstar OP Angle between daughters"}; + Configurable kstarMaxRap{"kstarMaxRap", 0.5, "Max kstar rapidity"}; + Configurable kstarMaxRadius{"kstarMaxRadius", 200, "Max kstar decay radius"}; + Configurable kstarMaxDCADau{"kstarMaxDCADau", 50, "Max kstar DCA between daughters"}; + Configurable kstarMaxOPAngle{"kstarMaxOPAngle", 7, "Max kstar OP Angle between daughters"}; } kstarSelections; // Axis @@ -237,7 +237,7 @@ struct k892hadronphoton { ConfigurableAxis axisCandSel{"axisCandSel", {20, 0.5f, +20.5f}, "Candidate Selection"}; // ML - ConfigurableAxis MLProb{"MLOutput", {100, 0.0f, 1.0f}, ""}; + ConfigurableAxis mlProb{"mlOutput", {100, 0.0f, 1.0f}, ""}; void init(InitContext const&) { @@ -383,11 +383,9 @@ struct k892hadronphoton { histos.add(histodir + "/MC/KStar/hDCAPairDauVsPt", "hDCAPairDauVsPt", kTH2D, {axisDCAdau, axisPt}); // 1/pT Resolution: - if (fillResoQAhistos && histodir == "BeforeSel") { - + if (fillResoQAhistos) { histos.add(histodir + "/MC/Reso/h2dKShortPtResolution", "h2dKShortPtResolution", kTH2D, {axisInvPt, axisDeltaPt}); - histos.add(histodir + "/MC/Reso/h3dKShortPtResoVsTPCCR", "h3dKShortPtResoVsTPCCR", kTH3D, {axisInvPt, axisDeltaPt, axisTPCrows}); - histos.add(histodir + "/MC/Reso/h3dKShortPtResoVsTPCCR", "h3dKShortPtResoVsTPCCR", kTH3D, {axisInvPt, axisDeltaPt, axisTPCrows}); + histos.add(histodir + "/MC/Reso/h2dGammaPtResolution", "h2dGammaPtResolution", kTH2D, {axisInvPt, axisDeltaPt}); histos.add(histodir + "/MC/Reso/h2dKStarPtResolution", "h2dKStarPtResolution", kTH2D, {axisInvPt, axisDeltaPt}); histos.add(histodir + "/MC/Reso/h2dKStarRadiusResolution", "h2dKStarRadiusResolution", kTH2D, {axisPt, axisDeltaPt}); } @@ -396,10 +394,16 @@ struct k892hadronphoton { if (fillBkgQAhistos) { histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassKStar_All", "h2dPtVsMassKStar_All", kTH2D, {axisPt, axisKStarMass}); histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassKStar_TrueDaughters", "h2dPtVsMassKStar_TrueDaughters", kTH2D, {axisPt, axisKStarMass}); - histos.add(histodir + "/MC/BkgStudy/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassKStar_PhotonOmega", "h2dPtVsMassKStar_PhotonOmega", kTH2D, {axisPt, axisKStarMass}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassKStar_PhotonRho", "h2dPtVsMassKStar_PhotonRho", kTH2D, {axisPt, axisKStarMass}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassKStar_PhotonEta", "h2dPtVsMassKStar_PhotonEta", kTH2D, {axisPt, axisKStarMass}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassKStar_KShortKCharged", "h2dPtVsMassKStar_KShortKCharged", kTH2D, {axisPt, axisKStarMass}); + histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassKStar_KStarPionKaon", "h2dPtVsMassKStar_KStarPionKaon", kTH2D, {axisPt, axisKStarMass}); histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassKStar_TrueGammaFakeKShort", "h2dPtVsMassKStar_TrueGammaFakeKShort", kTH2D, {axisPt, axisKStarMass}); histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassKStar_FakeGammaTrueKShort", "h2dPtVsMassKStar_FakeGammaTrueKShort", kTH2D, {axisPt, axisKStarMass}); histos.add(histodir + "/MC/BkgStudy/h2dPtVsMassKStar_FakeDaughters", "h2dPtVsMassKStar_FakeDaughters", kTH2D, {axisPt, axisKStarMass}); + histos.add(histodir + "/MC/BkgStudy/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add(histodir + "/MC/BkgStudy/h2dTrueDaughtersMatrixGrandMother", "h2dTrueDaughtersMatrixGrandMother", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); } } } @@ -408,16 +412,16 @@ struct k892hadronphoton { histos.add("Selection/Photon/hCandidateSel", "hCandidateSel", kTH1D, {axisCandSel}); histos.add("Selection/KShort/hCandidateSel", "hCandidateSel", kTH1D, {axisCandSel}); - for (size_t i = 0; i < PhotonSels.size(); ++i) { - const auto& sel = PhotonSels[i]; + for (size_t i = 0; i < photonSels.size(); ++i) { + const auto& sel = photonSels[i]; histos.add(Form("Selection/Photon/h2d%s", sel.c_str()), ("h2d" + sel).c_str(), kTH2D, {axisPt, axisPhotonMass}); histos.get(HIST("Selection/Photon/hCandidateSel"))->GetXaxis()->SetBinLabel(i + 1, sel.c_str()); histos.add(Form("Selection/KStar/h2dPhoton%s", sel.c_str()), ("h2dPhoton" + sel).c_str(), kTH2D, {axisPt, axisKStarMass}); } - for (size_t i = 0; i < KShortSels.size(); ++i) { - const auto& sel = KShortSels[i]; + for (size_t i = 0; i < kshortSels.size(); ++i) { + const auto& sel = kshortSels[i]; histos.add(Form("Selection/KShort/h2d%s", sel.c_str()), ("h2d" + sel).c_str(), kTH2D, {axisPt, axisKShortMass}); histos.get(HIST("Selection/KShort/hCandidateSel"))->GetXaxis()->SetBinLabel(i + 1, sel.c_str()); @@ -450,7 +454,7 @@ struct k892hadronphoton { // Check whether the collision passes our collision selections // Should work with collisions, mccollisions, stracollisions and stramccollisions tables! template - bool IsEventAccepted(TCollision const& collision, bool fillHists) + bool isEventAccepted(TCollision const& collision, bool fillHists) { if (fillHists) histos.fill(HIST("hEventSelection"), 0. /* all collisions */); @@ -575,12 +579,12 @@ struct k892hadronphoton { if (eventSelections.maxIR >= 0 && interactionRate > eventSelections.maxIR) { return false; } - if (fillHists) - histos.fill(HIST("hEventSelection"), 19 /* Above max IR */); - // Fill centrality histogram after event selection - if (fillHists) + if (fillHists) { + histos.fill(HIST("hEventSelection"), 19 /* Above max IR */); + // Fill centrality histogram after event selection histos.fill(HIST("hEventCentrality"), centrality); + } return true; } @@ -599,7 +603,7 @@ struct k892hadronphoton { for (auto const& collision : groupedCollisions) { // consider event selections in the recoed <-> gen collision association, for the denominator (or numerator) of the efficiency (or signal loss)? if (eventSelections.useEvtSelInDenomEff) { - if (!IsEventAccepted(collision, false)) { + if (!isEventAccepted(collision, false)) { continue; } } @@ -648,7 +652,7 @@ struct k892hadronphoton { int nCollisions = 0; for (auto const& collision : groupedCollisions) { - if (!IsEventAccepted(collision, false)) { + if (!isEventAccepted(collision, false)) { continue; } @@ -683,7 +687,7 @@ struct k892hadronphoton { fillGeneratedEventProperties(mcCollisions, collisions); std::vector listBestCollisionIdx = getListOfRecoCollIndices(mcCollisions, collisions); - for (auto& genParticle : genParticles) { + for (const auto& genParticle : genParticles) { float centrality = 100.5f; // Has MC collision @@ -691,7 +695,7 @@ struct k892hadronphoton { continue; // Selection on the source (generator/transport) - if (!genParticle.producedByGenerator() && mc_keepOnlyFromGenerator) + if (!genParticle.producedByGenerator() && mcKeepOnlyFromGenerator) continue; // Select corresponding mc collision && Basic event selection @@ -736,61 +740,61 @@ struct k892hadronphoton { int retrieveV0TrackCode(TKStarObject const& kstar) { - int TrkCode = 10; // 1: TPC-only, 2: TPC+Something, 3: ITS-Only, 4: ITS+TPC + Something, 10: anything else + int trkCode = 10; // 1: TPC-only, 2: TPC+Something, 3: ITS-Only, 4: ITS+TPC + Something, 10: anything else if (isGamma) { if (kstar.photonPosTrackCode() == 1 && kstar.photonNegTrackCode() == 1) - TrkCode = 1; + trkCode = 1; if ((kstar.photonPosTrackCode() != 1 && kstar.photonNegTrackCode() == 1) || (kstar.photonPosTrackCode() == 1 && kstar.photonNegTrackCode() != 1)) - TrkCode = 2; + trkCode = 2; if (kstar.photonPosTrackCode() == 3 && kstar.photonNegTrackCode() == 3) - TrkCode = 3; + trkCode = 3; if (kstar.photonPosTrackCode() == 2 || kstar.photonNegTrackCode() == 2) - TrkCode = 4; + trkCode = 4; } else { if (kstar.kshortPosTrackCode() == 1 && kstar.kshortNegTrackCode() == 1) - TrkCode = 1; + trkCode = 1; if ((kstar.kshortPosTrackCode() != 1 && kstar.kshortNegTrackCode() == 1) || (kstar.kshortPosTrackCode() == 1 && kstar.kshortNegTrackCode() != 1)) - TrkCode = 2; + trkCode = 2; if (kstar.kshortPosTrackCode() == 3 && kstar.kshortNegTrackCode() == 3) - TrkCode = 3; + trkCode = 3; if (kstar.kshortPosTrackCode() == 2 || kstar.kshortNegTrackCode() == 2) - TrkCode = 4; + trkCode = 4; } - return TrkCode; + return trkCode; } - template + template void getResolution(TKStarObject const& kstar) { + // Check whether it is before or after selections + static constexpr std::string_view MainDir[] = {"BeforeSel", "AfterSel"}; //_______________________________________ // Gamma MC association - if (kstar.photonPDGCode() == PDG_t::kGamma) { + if (std::abs(kstar.photonPDGCode()) == PDG_t::kGamma) { if (kstar.photonmcpt() > 0) { - histos.fill(HIST("BeforeSel/MC/Reso/h3dGammaPtResoVsTPCCR"), 1.f / kstar.kshortmcpt(), 1.f / kstar.kshortPt() - 1.f / kstar.kshortmcpt(), -1 * kstar.photonNegTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("BeforeSel/MC/Reso/h3dGammaPtResoVsTPCCR"), 1.f / kstar.kshortmcpt(), 1.f / kstar.kshortPt() - 1.f / kstar.kshortmcpt(), kstar.photonPosTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("BeforeSel/MC/Reso/h2dGammaPtResolution"), 1.f / kstar.photonmcpt(), 1.f / kstar.photonPt() - 1.f / kstar.photonmcpt()); // pT resolution + // histos.fill(HIST(MainDir[mode]) + HIST("/MC/Reso/h2dGammaPtResolution"), 1.f / kstar.photonmcpt(), kstar.photonPt() - kstar.photonmcpt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Reso/h2dGammaPtResolution"), 1.f / kstar.photonmcpt(), (kstar.photonPt() - kstar.photonmcpt()) / kstar.photonmcpt()); } } //_______________________________________ // KShort MC association - if (kstar.kshortPDGCode() == PDG_t::kK0Short) { + if (std::abs(kstar.kshortPDGCode()) == PDG_t::kK0Short) { if (kstar.kshortmcpt() > 0) { - histos.fill(HIST("BeforeSel/MC/Reso/h2dKShortPtResolution"), 1.f / kstar.kshortmcpt(), 1.f / kstar.kshortPt() - 1.f / kstar.kshortmcpt()); // 1/pT resolution - histos.fill(HIST("BeforeSel/MC/Reso/h3dKShortPtResoVsTPCCR"), 1.f / kstar.kshortmcpt(), 1.f / kstar.kshortPt() - 1.f / kstar.kshortmcpt(), -1 * kstar.kshortNegTPCCrossedRows()); // 1/pT resolution - histos.fill(HIST("BeforeSel/MC/Reso/h3dKShortPtResoVsTPCCR"), 1.f / kstar.kshortmcpt(), 1.f / kstar.kshortPt() - 1.f / kstar.kshortmcpt(), kstar.kshortPosTPCCrossedRows()); // 1/pT resolution + // histos.fill(HIST(MainDir[mode]) + HIST("/MC/Reso/h2dKShortPtResolution"), 1.f / kstar.kshortmcpt(), kstar.kshortPt() - kstar.kshortmcpt()); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Reso/h2dKShortPtResolution"), 1.f / kstar.kshortmcpt(), (kstar.kshortPt() - kstar.kshortmcpt()) / kstar.kshortmcpt()); } } //_______________________________________ // KStar MC association if (kstar.isKStar()) { - histos.fill(HIST("BeforeSel/MC/Reso/h2dKStarRadiusResolution"), kstar.mcpt(), kstar.radius() - kstar.mcradius()); // pT resolution + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Reso/h2dKStarRadiusResolution"), kstar.mcpt(), kstar.radius() - kstar.mcradius()); // pT resolution if (kstar.mcpt() > 0) - histos.fill(HIST("BeforeSel/MC/Reso/h2dKStarPtResolution"), 1.f / kstar.mcpt(), 1.f / kstar.pt() - 1.f / kstar.mcpt()); // pT resolution + histos.fill(HIST(MainDir[mode]) + HIST("/MC/Reso/h2dKStarPtResolution"), 1.f / kstar.mcpt(), (1.f / kstar.pt() - 1.f / kstar.mcpt()) / (1.f / kstar.mcpt())); // pT resolution } } @@ -802,35 +806,57 @@ struct k892hadronphoton { static constexpr std::string_view MainDir[] = {"BeforeSel", "AfterSel"}; bool fIsKStar = kstar.isKStar(); - int PhotonPDGCode = kstar.photonPDGCode(); - int PhotonPDGCodeMother = kstar.photonPDGCodeMother(); - int KShortPDGCode = kstar.kshortPDGCode(); - int KShortPDGCodeMother = kstar.kshortPDGCodeMother(); + int photonPDGCode = kstar.photonPDGCode(); + int photonPDGCodeMother = kstar.photonPDGCodeMother(); + int photonPDGCodeGrandMother = kstar.photonPDGCodeGrandMother(); + int photonGlobalIndexGrandMother = kstar.photonGlobalIndexGrandMother(); + int kshortPDGCode = kstar.kshortPDGCode(); + int kshortPDGCodeMother = kstar.kshortPDGCodeMother(); + int kshortPDGCodeGrandMother = kstar.kshortPDGCodeGrandMother(); + int kshortGlobalIndexGrandMother = kstar.kshortGlobalIndexGrandMother(); float kstarpT = kstar.pt(); float kstarMass = kstar.kstarMass(); histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassKStar_All"), kstarpT, kstarMass); //_______________________________________ - // Real Gamma x Real KShort - but not from the same kstar! - if ((PhotonPDGCode == PDG_t::kGamma) && (KShortPDGCode == PDG_t::kK0Short) && (!fIsKStar)) { + // Real Gamma x Real KShort - but not direct decays from the same kstar! + if ((!fIsKStar) && (std::abs(photonPDGCode) == PDG_t::kGamma) && (std::abs(kshortPDGCode) == PDG_t::kK0Short)) { histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassKStar_TrueDaughters"), kstarpT, kstarMass); - histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dTrueDaughtersMatrix"), KShortPDGCodeMother, PhotonPDGCodeMother); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dTrueDaughtersMatrix"), kshortPDGCodeMother, photonPDGCodeMother); + histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dTrueDaughtersMatrixGrandMother"), kshortPDGCodeGrandMother, photonPDGCodeGrandMother); + + // coming from the same kstar (coupled), but via a different decay channel (K* -> K0 pi0 -> K0s gamma) + if (std::abs(kshortPDGCodeGrandMother) == o2::constants::physics::Pdg::kK0Star892 && std::abs(photonPDGCodeGrandMother) == o2::constants::physics::Pdg::kK0Star892 && (photonGlobalIndexGrandMother == kshortGlobalIndexGrandMother)) // K*(892)0 + histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassKStar_KStarPionKaon"), kstarpT, kstarMass); + + // Break down of different photon / kshort sources + if (std::abs(photonPDGCodeGrandMother) == o2::constants::physics::Pdg::kOmega) // omega(782) + histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassKStar_PhotonOmega"), kstarpT, kstarMass); + + if (std::abs(photonPDGCodeGrandMother) == PDG_t::kRho770Plus) // rho+-(770) + histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassKStar_PhotonRho"), kstarpT, kstarMass); + + if (std::abs(photonPDGCodeMother) == o2::constants::physics::Pdg::kEta) // eta + histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassKStar_PhotonEta"), kstarpT, kstarMass); + + if (std::abs(kshortPDGCodeGrandMother) == o2::constants::physics::Pdg::kKPlusStar892) // K*(892)+- + histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassKStar_KShortKCharged"), kstarpT, kstarMass); } //_______________________________________ // Real Gamma x fake KShort - if ((PhotonPDGCode == PDG_t::kGamma) && (KShortPDGCode != PDG_t::kK0Short)) + if ((std::abs(photonPDGCode) == PDG_t::kGamma) && (std::abs(kshortPDGCode) != PDG_t::kK0Short)) histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassKStar_TrueGammaFakeKShort"), kstarpT, kstarMass); //_______________________________________ // Fake Gamma x Real KShort - if ((PhotonPDGCode != PDG_t::kGamma) && ((KShortPDGCode == PDG_t::kK0Short))) + if ((std::abs(photonPDGCode) != PDG_t::kGamma) && ((std::abs(kshortPDGCode) == PDG_t::kK0Short))) histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassKStar_FakeGammaTrueKShort"), kstarpT, kstarMass); //_______________________________________ // Fake Gamma x Fake KShort - if ((PhotonPDGCode != PDG_t::kGamma) && (KShortPDGCode != PDG_t::kK0Short)) + if ((std::abs(photonPDGCode) != PDG_t::kGamma) && (std::abs(kshortPDGCode) != PDG_t::kK0Short)) histos.fill(HIST(MainDir[mode]) + HIST("/MC/BkgStudy/h2dPtVsMassKStar_FakeDaughters"), kstarpT, kstarMass); } @@ -842,14 +868,14 @@ struct k892hadronphoton { static constexpr std::string_view MainDir[] = {"BeforeSel", "AfterSel"}; // Get V0trackCode - int GammaTrkCode = retrieveV0TrackCode(kstar); - int KShortTrkCode = retrieveV0TrackCode(kstar); + int gammaTrkCode = retrieveV0TrackCode(kstar); + int kshortTrkCode = retrieveV0TrackCode(kstar); - float photonRZLineCut = TMath::Abs(kstar.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-photonSelections.PhotonMaxDauEta))) - photonSelections.PhotonLineCutZ0; + float photonRZLineCut = TMath::Abs(kstar.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-photonSelections.photonMaxDauEta))) - photonSelections.photonLineCutZ0; float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); //_______________________________________ // Photon - histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hTrackCode"), GammaTrkCode); + histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hTrackCode"), gammaTrkCode); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hV0Type"), kstar.photonV0Type()); histos.fill(HIST(MainDir[mode]) + HIST("/Photon/hDCANegToPV"), kstar.photonDCANegPV()); @@ -875,7 +901,7 @@ struct k892hadronphoton { //_______________________________________ // KShorts - histos.fill(HIST(MainDir[mode]) + HIST("/KShort/hTrackCode"), KShortTrkCode); + histos.fill(HIST(MainDir[mode]) + HIST("/KShort/hTrackCode"), kshortTrkCode); histos.fill(HIST(MainDir[mode]) + HIST("/KShort/hRadius"), kstar.kshortRadius()); histos.fill(HIST(MainDir[mode]) + HIST("/KShort/hDCADau"), kstar.kshortDCADau()); histos.fill(HIST(MainDir[mode]) + HIST("/KShort/hCosPA"), kstar.kshortCosPA()); @@ -978,8 +1004,8 @@ struct k892hadronphoton { //_______________________________________ // pT resolution histos - if ((mode == 0) && fillResoQAhistos) - getResolution(kstar); + if (fillResoQAhistos) + getResolution(kstar); } } } @@ -988,28 +1014,28 @@ struct k892hadronphoton { void fillSelHistos(TKStarObject const& kstar, int PDGRequired) { - static constexpr std::string_view PhotonSelsLocal[] = {"NoSel", "V0Type", "DCADauToPV", + static constexpr std::string_view photonSelsLocal[] = {"NoSel", "V0Type", "DCADauToPV", "DCADau", "DauTPCCR", "TPCNSigmaEl", "V0pT", "Y", "V0Radius", "RZCut", "Armenteros", "CosPA", "PsiPair", "Phi", "Mass"}; - static constexpr std::string_view KShortSelsLocal[] = {"NoSel", "V0Radius", "DCADau", "Armenteros", + static constexpr std::string_view kshortSelsLocal[] = {"NoSel", "V0Radius", "DCADau", "Armenteros", "CosPA", "Y", "TPCCR", "DauITSCls", "Lifetime", "TPCTOFPID", "DCADauToPV", "Mass"}; - if (PDGRequired == PDG_t::kGamma) { - if constexpr (selection_index >= 0 && selection_index < (int)std::size(PhotonSelsLocal)) { + if (std::abs(PDGRequired) == PDG_t::kGamma) { + if constexpr (selection_index >= 0 && selection_index < static_cast(std::size(photonSelsLocal))) { histos.fill(HIST("Selection/Photon/hCandidateSel"), selection_index); - histos.fill(HIST("Selection/Photon/h2d") + HIST(PhotonSelsLocal[selection_index]), kstar.photonPt(), kstar.photonMass()); - histos.fill(HIST("Selection/KStar/h2dPhoton") + HIST(PhotonSelsLocal[selection_index]), kstar.pt(), kstar.kstarMass()); + histos.fill(HIST("Selection/Photon/h2d") + HIST(photonSelsLocal[selection_index]), kstar.photonPt(), kstar.photonMass()); + histos.fill(HIST("Selection/KStar/h2dPhoton") + HIST(photonSelsLocal[selection_index]), kstar.pt(), kstar.kstarMass()); } } - if (PDGRequired == PDG_t::kK0Short) { - if constexpr (selection_index >= 0 && selection_index < (int)std::size(KShortSelsLocal)) { + if (std::abs(PDGRequired) == PDG_t::kK0Short) { + if constexpr (selection_index >= 0 && selection_index < static_cast(std::size(kshortSelsLocal))) { histos.fill(HIST("Selection/KShort/hCandidateSel"), selection_index); - histos.fill(HIST("Selection/KShort/h2d") + HIST(KShortSelsLocal[selection_index]), kstar.kshortPt(), kstar.kshortMass()); - histos.fill(HIST("Selection/KStar/h2dKShort") + HIST(KShortSelsLocal[selection_index]), kstar.pt(), kstar.kstarMass()); + histos.fill(HIST("Selection/KShort/h2d") + HIST(kshortSelsLocal[selection_index]), kstar.kshortPt(), kstar.kshortMass()); + histos.fill(HIST("Selection/KStar/h2dKShort") + HIST(kshortSelsLocal[selection_index]), kstar.pt(), kstar.kstarMass()); } } } @@ -1019,66 +1045,66 @@ struct k892hadronphoton { bool selectPhoton(TV0Object const& cand) { fillSelHistos<0>(cand, PDG_t::kGamma); - if (cand.photonV0Type() != photonSelections.Photonv0TypeSel && photonSelections.Photonv0TypeSel > -1) + if (cand.photonV0Type() != photonSelections.photonv0TypeSel && photonSelections.photonv0TypeSel > -1) return false; fillSelHistos<1>(cand, PDG_t::kGamma); - if ((TMath::Abs(cand.photonDCAPosPV()) < photonSelections.PhotonMinDCADauToPv) || (TMath::Abs(cand.photonDCANegPV()) < photonSelections.PhotonMinDCADauToPv)) + if ((TMath::Abs(cand.photonDCAPosPV()) < photonSelections.photonMinDCADauToPv) || (TMath::Abs(cand.photonDCANegPV()) < photonSelections.photonMinDCADauToPv)) return false; fillSelHistos<2>(cand, PDG_t::kGamma); - if (TMath::Abs(cand.photonDCADau()) > photonSelections.PhotonMaxDCAV0Dau) + if (TMath::Abs(cand.photonDCADau()) > photonSelections.photonMaxDCAV0Dau) return false; fillSelHistos<3>(cand, PDG_t::kGamma); - if ((cand.photonPosTPCCrossedRows() < photonSelections.PhotonMinTPCCrossedRows) || (cand.photonNegTPCCrossedRows() < photonSelections.PhotonMinTPCCrossedRows)) + if ((cand.photonPosTPCCrossedRows() < photonSelections.photonMinTPCCrossedRows) || (cand.photonNegTPCCrossedRows() < photonSelections.photonMinTPCCrossedRows)) return false; fillSelHistos<4>(cand, PDG_t::kGamma); - if (((cand.photonPosTPCNSigmaEl() < photonSelections.PhotonMinTPCNSigmas) || (cand.photonPosTPCNSigmaEl() > photonSelections.PhotonMaxTPCNSigmas))) + if (((cand.photonPosTPCNSigmaEl() < photonSelections.photonMinTPCNSigmas) || (cand.photonPosTPCNSigmaEl() > photonSelections.photonMaxTPCNSigmas))) return false; - if (((cand.photonNegTPCNSigmaEl() < photonSelections.PhotonMinTPCNSigmas) || (cand.photonNegTPCNSigmaEl() > photonSelections.PhotonMaxTPCNSigmas))) + if (((cand.photonNegTPCNSigmaEl() < photonSelections.photonMinTPCNSigmas) || (cand.photonNegTPCNSigmaEl() > photonSelections.photonMaxTPCNSigmas))) return false; fillSelHistos<5>(cand, PDG_t::kGamma); - if ((cand.photonPt() < photonSelections.PhotonMinPt) || (cand.photonPt() > photonSelections.PhotonMaxPt)) + if ((cand.photonPt() < photonSelections.photonMinPt) || (cand.photonPt() > photonSelections.photonMaxPt)) return false; fillSelHistos<6>(cand, PDG_t::kGamma); - if ((TMath::Abs(cand.photonY()) > photonSelections.PhotonMaxRap) || (TMath::Abs(cand.photonPosEta()) > photonSelections.PhotonMaxDauEta) || (TMath::Abs(cand.photonNegEta()) > photonSelections.PhotonMaxDauEta)) + if ((TMath::Abs(cand.photonY()) > photonSelections.photonMaxRap) || (TMath::Abs(cand.photonPosEta()) > photonSelections.photonMaxDauEta) || (TMath::Abs(cand.photonNegEta()) > photonSelections.photonMaxDauEta)) return false; fillSelHistos<7>(cand, PDG_t::kGamma); - if ((cand.photonRadius() < photonSelections.PhotonMinRadius) || (cand.photonRadius() > photonSelections.PhotonMaxRadius)) + if ((cand.photonRadius() < photonSelections.photonMinRadius) || (cand.photonRadius() > photonSelections.photonMaxRadius)) return false; fillSelHistos<8>(cand, PDG_t::kGamma); - float photonRZLineCut = TMath::Abs(cand.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-photonSelections.PhotonMaxDauEta))) - photonSelections.PhotonLineCutZ0; - if ((TMath::Abs(cand.photonRadius()) < photonRZLineCut) || (TMath::Abs(cand.photonZconv()) > photonSelections.PhotonMaxZ)) + float photonRZLineCut = TMath::Abs(cand.photonZconv()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-photonSelections.photonMaxDauEta))) - photonSelections.photonLineCutZ0; + if ((TMath::Abs(cand.photonRadius()) < photonRZLineCut) || (TMath::Abs(cand.photonZconv()) > photonSelections.photonMaxZ)) return false; fillSelHistos<9>(cand, PDG_t::kGamma); - if (cand.photonQt() > photonSelections.PhotonMaxQt) + if (cand.photonQt() > photonSelections.photonMaxQt) return false; - if (TMath::Abs(cand.photonAlpha()) > photonSelections.PhotonMaxAlpha) + if (TMath::Abs(cand.photonAlpha()) > photonSelections.photonMaxAlpha) return false; fillSelHistos<10>(cand, PDG_t::kGamma); - if (cand.photonCosPA() < photonSelections.PhotonMinV0cospa) + if (cand.photonCosPA() < photonSelections.photonMinV0cospa) return false; fillSelHistos<11>(cand, PDG_t::kGamma); - if (TMath::Abs(cand.photonPsiPair()) > photonSelections.PhotonPsiPairMax) + if (TMath::Abs(cand.photonPsiPair()) > photonSelections.photonPsiPairMax) return false; fillSelHistos<12>(cand, PDG_t::kGamma); - if ((((cand.photonPhi() > photonSelections.PhotonPhiMin1) && (cand.photonPhi() < photonSelections.PhotonPhiMax1)) || ((cand.photonPhi() > photonSelections.PhotonPhiMin2) && (cand.photonPhi() < photonSelections.PhotonPhiMax2))) && ((photonSelections.PhotonPhiMin1 != -1) && (photonSelections.PhotonPhiMax1 != -1) && (photonSelections.PhotonPhiMin2 != -1) && (photonSelections.PhotonPhiMax2 != -1))) + if ((((cand.photonPhi() > photonSelections.photonPhiMin1) && (cand.photonPhi() < photonSelections.photonPhiMax1)) || ((cand.photonPhi() > photonSelections.photonPhiMin2) && (cand.photonPhi() < photonSelections.photonPhiMax2))) && ((photonSelections.photonPhiMin1 != -1) && (photonSelections.photonPhiMax1 != -1) && (photonSelections.photonPhiMin2 != -1) && (photonSelections.photonPhiMax2 != -1))) return false; fillSelHistos<13>(cand, PDG_t::kGamma); - if (TMath::Abs(cand.photonMass()) > photonSelections.PhotonMaxMass) + if (TMath::Abs(cand.photonMass()) > photonSelections.photonMaxMass) return false; fillSelHistos<14>(cand, PDG_t::kGamma); @@ -1090,30 +1116,30 @@ struct k892hadronphoton { bool selectKShort(TV0Object const& cand) { fillSelHistos<0>(cand, PDG_t::kK0Short); - if ((cand.kshortRadius() < kshortSelections.KShortMinv0radius) || (cand.kshortRadius() > kshortSelections.KShortMaxv0radius)) + if ((cand.kshortRadius() < kshortSelections.kshortMinv0radius) || (cand.kshortRadius() > kshortSelections.kshortMaxv0radius)) return false; fillSelHistos<1>(cand, PDG_t::kK0Short); - if (TMath::Abs(cand.kshortDCADau()) > kshortSelections.KShortMaxDCAV0Dau) + if (TMath::Abs(cand.kshortDCADau()) > kshortSelections.kshortMaxDCAV0Dau) return false; fillSelHistos<2>(cand, PDG_t::kK0Short); - if ((cand.kshortQt() < kshortSelections.KShortMinQt) || (cand.kshortQt() > kshortSelections.KShortMaxQt)) + if ((cand.kshortQt() < kshortSelections.kshortMinQt) || (cand.kshortQt() > kshortSelections.kshortMaxQt)) return false; - if ((TMath::Abs(cand.kshortAlpha()) < kshortSelections.KShortMinAlpha) || (TMath::Abs(cand.kshortAlpha()) > kshortSelections.KShortMaxAlpha)) + if ((TMath::Abs(cand.kshortAlpha()) < kshortSelections.kshortMinAlpha) || (TMath::Abs(cand.kshortAlpha()) > kshortSelections.kshortMaxAlpha)) return false; fillSelHistos<3>(cand, PDG_t::kK0Short); - if (cand.kshortCosPA() < kshortSelections.KShortMinv0cospa) + if (cand.kshortCosPA() < kshortSelections.kshortMinv0cospa) return false; fillSelHistos<4>(cand, PDG_t::kK0Short); - if ((TMath::Abs(cand.kshortY()) > kshortSelections.KShortMaxRap) || (TMath::Abs(cand.kshortPosEta()) > kshortSelections.KShortMaxDauEta) || (TMath::Abs(cand.kshortNegEta()) > kshortSelections.KShortMaxDauEta)) + if ((TMath::Abs(cand.kshortY()) > kshortSelections.kshortMaxRap) || (TMath::Abs(cand.kshortPosEta()) > kshortSelections.kshortMaxDauEta) || (TMath::Abs(cand.kshortNegEta()) > kshortSelections.kshortMaxDauEta)) return false; fillSelHistos<5>(cand, PDG_t::kK0Short); - if ((cand.kshortPosTPCCrossedRows() < kshortSelections.KShortMinTPCCrossedRows) || (cand.kshortNegTPCCrossedRows() < kshortSelections.KShortMinTPCCrossedRows)) + if ((cand.kshortPosTPCCrossedRows() < kshortSelections.kshortMinTPCCrossedRows) || (cand.kshortNegTPCCrossedRows() < kshortSelections.kshortMinTPCCrossedRows)) return false; fillSelHistos<6>(cand, PDG_t::kK0Short); @@ -1121,38 +1147,37 @@ struct k892hadronphoton { // check minimum number of ITS clusters + reject ITS afterburner tracks if requested bool posIsFromAfterburner = cand.kshortPosChi2PerNcl() < 0; bool negIsFromAfterburner = cand.kshortNegChi2PerNcl() < 0; - if (cand.kshortPosITSCls() < kshortSelections.KShortMinITSclusters && (!kshortSelections.KShortRejectPosITSafterburner || posIsFromAfterburner)) + if (cand.kshortPosITSCls() < kshortSelections.kshortMinITSclusters && (!kshortSelections.kshortRejectPosITSafterburner || posIsFromAfterburner)) return false; - if (cand.kshortNegITSCls() < kshortSelections.KShortMinITSclusters && (!kshortSelections.KShortRejectNegITSafterburner || negIsFromAfterburner)) + if (cand.kshortNegITSCls() < kshortSelections.kshortMinITSclusters && (!kshortSelections.kshortRejectNegITSafterburner || negIsFromAfterburner)) return false; fillSelHistos<7>(cand, PDG_t::kK0Short); - if (cand.kshortLifeTime() > kshortSelections.KShortMaxLifeTime) + if (cand.kshortLifeTime() > kshortSelections.kshortMaxLifeTime) return false; // Separating kshort selections: fillSelHistos<8>(cand, PDG_t::kK0Short); // TPC Selection - if (kshortSelections.fselKShortTPCPID && (TMath::Abs(cand.kshortPosPiTPCNSigma()) > kshortSelections.KShortMaxTPCNSigmas)) + if (kshortSelections.fselKShortTPCPID && (TMath::Abs(cand.kshortPosPiTPCNSigma()) > kshortSelections.kshortMaxTPCNSigmas)) return false; - if (kshortSelections.fselKShortTPCPID && (TMath::Abs(cand.kshortNegPiTPCNSigma()) > kshortSelections.KShortMaxTPCNSigmas)) + if (kshortSelections.fselKShortTPCPID && (TMath::Abs(cand.kshortNegPiTPCNSigma()) > kshortSelections.kshortMaxTPCNSigmas)) return false; // // TOF Selection - // if (kshortSelections.fselKShortTOFPID && (TMath::Abs(cand.kshortPiTOFNSigma()) > kshortSelections.KShortPiMaxTOFNSigmas)) + // if (kshortSelections.fselKShortTOFPID && (TMath::Abs(cand.kshortPiTOFNSigma()) > kshortSelections.kshortPiMaxTOFNSigmas)) // return false; - // if (kshortSelections.fselKShortTOFPID && (TMath::Abs(cand.lambdaPiTOFNSigma()) > kshortSelections.KShortPiMaxTOFNSigmas)) + // if (kshortSelections.fselKShortTOFPID && (TMath::Abs(cand.lambdaPiTOFNSigma()) > kshortSelections.kshortPiMaxTOFNSigmas)) // return false; - // DCA Selection fillSelHistos<9>(cand, PDG_t::kK0Short); - if ((TMath::Abs(cand.kshortDCAPosPV()) < kshortSelections.KShortMinDCAPosToPv) || (TMath::Abs(cand.kshortDCANegPV()) < kshortSelections.KShortMinDCANegToPv)) + if ((TMath::Abs(cand.kshortDCAPosPV()) < kshortSelections.kshortMinDCAPosToPv) || (TMath::Abs(cand.kshortDCANegPV()) < kshortSelections.kshortMinDCANegToPv)) return false; // Mass Selection fillSelHistos<10>(cand, PDG_t::kK0Short); - if (TMath::Abs(cand.kshortMass() - o2::constants::physics::MassK0Short) > kshortSelections.KShortWindow) + if (TMath::Abs(cand.kshortMass() - o2::constants::physics::MassK0Short) > kshortSelections.kshortWindow) return false; fillSelHistos<11>(cand, PDG_t::kK0Short); @@ -1175,23 +1200,23 @@ struct k892hadronphoton { // KStar specific selections // Rapidity if constexpr (requires { cand.kstarMCY(); }) { // MC - if (TMath::Abs(cand.kstarMCY()) > kstarSelections.KStarMaxRap) + if (TMath::Abs(cand.kstarMCY()) > kstarSelections.kstarMaxRap) return false; } else { // Real data - if (TMath::Abs(cand.kstarY()) > kstarSelections.KStarMaxRap) + if (TMath::Abs(cand.kstarY()) > kstarSelections.kstarMaxRap) return false; } // V0Pair Radius - if (cand.radius() > kstarSelections.KStarMaxRadius) + if (cand.radius() > kstarSelections.kstarMaxRadius) return false; // DCA V0Pair Daughters - if (cand.dcadaughters() > kstarSelections.KStarMaxDCADau) + if (cand.dcadaughters() > kstarSelections.kstarMaxDCADau) return false; // Opening Angle - if (cand.opAngle() > kstarSelections.KStarMaxOPAngle) + if (cand.opAngle() > kstarSelections.kstarMaxOPAngle) return false; return true; @@ -1212,7 +1237,7 @@ struct k892hadronphoton { for (const auto& coll : collisions) { // Event selection - if (!IsEventAccepted(coll, true)) + if (!isEventAccepted(coll, true)) continue; // KStars loop diff --git a/PWGLF/Tasks/Resonances/k892hadronphotonBkg.cxx b/PWGLF/Tasks/Resonances/k892hadronphotonBkg.cxx new file mode 100644 index 00000000000..4cbd68e8ab0 --- /dev/null +++ b/PWGLF/Tasks/Resonances/k892hadronphotonBkg.cxx @@ -0,0 +1,811 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file k892hadronphotonBkg.cxx +/// \brief This is a ask that computes the same-event rotational and the mixed-event combinatorial backgrounds for the K*(892) -> K0S + gamma analysis. +/// \author Oussama Benchikhi + +#include "PWGLF/DataModel/LFStrangenessMLTables.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/ctpRateFetcher.h" +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using std::array; +using dauTracks = soa::Join; +using V0StandardDerivedDatas = soa::Join; + +static const std::vector photonSels = {"No Sel", "Mass", "Y", "Neg Eta", "Pos Eta", + "DCAToPV", "DCADau", "Radius", "Z", "CosPA", + "Phi", "Qt", "Alpha", "TPCCR", "TPC NSigma"}; +static const std::vector kshortSels = {"No Sel", "Mass", "Y", "Neg Eta", "Pos Eta", + "DCAToPV", "Radius", "Z", "DCADau", "Armenteros", + "CosPA", "TPCCR", "ITSNCls", "Lifetime", "TPC NSigma"}; + +struct k892hadronphotonBkg { + Service ccdb; + ctpRateFetcher rateFetcher; + TRandom3 rotRng{12345}; // struct member; fixed seed for reproducibility across grid jobs + + // Histogram registry + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Configurable doPPAnalysis{"doPPAnalysis", true, "if in pp, set to true"}; + + // For ML Selection + Configurable useMLScores{"useMLScores", false, "use ML scores to select candidates"}; + + // Interaction-rate retrieval (used by the event selection) + Configurable fGetIR{"fGetIR", false, "Flag to retrieve the IR info."}; + Configurable fIRCrashOnNull{"fIRCrashOnNull", false, "Flag to avoid CTP RateFetcher crash."}; + Configurable irSource{"irSource", "T0VTX", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; + + struct : ConfigurableGroup { + std::string prefix = "kstarBkgConfig"; + Configurable doSameEvtRotation{"doSameEvtRotation", false, "Same-event rotational background"}; + Configurable doEvtMixing{"doEvtMixing", false, "Mixed-event background"}; + Configurable nMix{"nMix", 5, "Number of mixed events"}; + Configurable deltaCollision{"deltaCollision", 25, "Min |Δ globalIndex| for mixing"}; + Configurable kstarMaxOPAngle{"kstarMaxOPAngle", 7.f, "Max opening angle (rad)"}; + Configurable kstarMaxRap{"kstarMaxRap", 0.5f, "Max |y(K*)|"}; + Configurable nBkgRot{"nBkgRot", 3, "Rotations per pair (rotational bkg)"}; + Configurable rotationalCut{"rotationalCut", 10, "theta band: [pi - pi/cut, pi + pi/cut]"}; + Configurable rotationalFactor{"rotationalFactor", 1.f, "Factor to scale the angle of rotation (rotationalFactor * PI)"}; + } kstarBkgConfig; + + ConfigurableAxis axisVertexMixBkg{"axisVertexMixBkg", {VARIABLE_WIDTH, -10.f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "z-vertex bins for mixing"}; + ConfigurableAxis axisCentralityMixBkg{"axisCentralityMixBkg", {VARIABLE_WIDTH, 0.0f, 1.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 110.0f}, "centrality bins for mixing"}; + + struct : ConfigurableGroup { + std::string prefix = "eventSelections"; // JSON group name + Configurable fUseEventSelection{"fUseEventSelection", false, "Apply event selection cuts"}; + Configurable requireSel8{"requireSel8", true, "require sel8 event selection"}; + Configurable requireTriggerTVX{"requireTriggerTVX", true, "require FT0 vertex (acceptable FT0C-FT0A time difference) at trigger level"}; + Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "reject events at ITS ROF border"}; + Configurable rejectTFBorder{"rejectTFBorder", true, "reject events at TF border"}; + Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", true, "require events with at least one ITS-TPC track"}; + Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", true, "require events with PV position along z consistent (within 1 cm) between PV reconstructed using tracks and PV using FT0 A-C time difference"}; + Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "require events with at least one of vertex contributors matched to TOF"}; + Configurable requireIsVertexTRDmatched{"requireIsVertexTRDmatched", false, "require events with at least one of vertex contributors matched to TRD"}; + Configurable rejectSameBunchPileup{"rejectSameBunchPileup", false, "reject collisions in case of pileup with another collision in the same foundBC"}; + Configurable requireNoCollInTimeRangeStd{"requireNoCollInTimeRangeStd", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds"}; + Configurable requireNoCollInTimeRangeStrict{"requireNoCollInTimeRangeStrict", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; + Configurable requireNoCollInTimeRangeNarrow{"requireNoCollInTimeRangeNarrow", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 2 microseconds"}; + Configurable requireNoCollInROFStd{"requireNoCollInROFStd", false, "reject collisions corrupted by the cannibalism, with other collisions within the same ITS ROF with mult. above a certain threshold"}; + Configurable requireNoCollInROFStrict{"requireNoCollInROFStrict", false, "reject collisions corrupted by the cannibalism, with other collisions within the same ITS ROF"}; + Configurable requireINEL0{"requireINEL0", true, "require INEL>0 event selection"}; + Configurable requireINEL1{"requireINEL1", false, "require INEL>1 event selection"}; + Configurable maxZVtxPosition{"maxZVtxPosition", 10., "max Z vtx position"}; + Configurable useFT0CbasedOccupancy{"useFT0CbasedOccupancy", false, "Use sum of FT0-C amplitudes for estimating occupancy? (if not, use track-based definition)"}; + // fast check on occupancy + Configurable minOccupancy{"minOccupancy", -1, "minimum occupancy from neighbouring collisions"}; + Configurable maxOccupancy{"maxOccupancy", -1, "maximum occupancy from neighbouring collisions"}; + // fast check on interaction rate + Configurable minIR{"minIR", -1, "minimum IR collisions"}; + Configurable maxIR{"maxIR", -1, "maximum IR collisions"}; + } eventSelections; + + //// Photon criteria: + struct : ConfigurableGroup { + std::string prefix = "photonSelections"; // JSON group name + Configurable gammaMLThreshold{"gammaMLThreshold", 0.1, "Decision Threshold value to select gammas"}; + Configurable photonv0TypeSel{"photonv0TypeSel", 7, "select on a certain V0 type (leave negative if no selection desired)"}; + Configurable photonMinDCADauToPv{"photonMinDCADauToPv", 0.0, "Min DCA daughter To PV (cm)"}; + Configurable photonMaxDCAV0Dau{"photonMaxDCAV0Dau", 3.5, "Max DCA V0 Daughters (cm)"}; + Configurable photonMinTPCCrossedRows{"photonMinTPCCrossedRows", 30, "Min daughter TPC Crossed Rows"}; + Configurable photonMinTPCNSigmas{"photonMinTPCNSigmas", -7, "Min TPC NSigmas for daughters"}; + Configurable photonMaxTPCNSigmas{"photonMaxTPCNSigmas", 7, "Max TPC NSigmas for daughters"}; + Configurable photonMinRapidity{"photonMinRapidity", -0.5, "v0 min rapidity"}; + Configurable photonMaxRapidity{"photonMaxRapidity", 0.5, "v0 max rapidity"}; + Configurable photonDauEtaMin{"photonDauEtaMin", -0.8, "Min pseudorapidity of daughter tracks"}; + Configurable photonDauEtaMax{"photonDauEtaMax", 0.8, "Max pseudorapidity of daughter tracks"}; + Configurable photonMinRadius{"photonMinRadius", 3.0, "Min photon conversion radius (cm)"}; + Configurable photonMaxRadius{"photonMaxRadius", 115, "Max photon conversion radius (cm)"}; + Configurable photonMinZ{"photonMinZ", -240, "Min photon conversion point z value (cm)"}; + Configurable photonMaxZ{"photonMaxZ", 240, "Max photon conversion point z value (cm)"}; + Configurable photonMaxQt{"photonMaxQt", 0.08, "Max photon qt value (AP plot) (GeV/c)"}; + Configurable photonMaxAlpha{"photonMaxAlpha", 1.0, "Max photon alpha absolute value (AP plot)"}; + Configurable photonMinV0cospa{"photonMinV0cospa", 0.80, "Min V0 CosPA"}; + Configurable photonMaxMass{"photonMaxMass", 0.10, "Max photon mass (GeV/c^{2})"}; + Configurable photonPhiMin1{"photonPhiMin1", -1, "Phi min value to reject photons, region 1 (leave negative if no selection desired)"}; + Configurable photonPhiMax1{"photonPhiMax1", -1, "Phi max value to reject photons, region 1 (leave negative if no selection desired)"}; + Configurable photonPhiMin2{"photonPhiMin2", -1, "Phi max value to reject photons, region 2 (leave negative if no selection desired)"}; + Configurable photonPhiMax2{"photonPhiMax2", -1, "Phi min value to reject photons, region 2 (leave negative if no selection desired)"}; + } photonSelections; + + // KShort criteria: + struct : ConfigurableGroup { + std::string prefix = "kshortSelections"; // JSON group name + Configurable kshortMLThreshold{"kshortMLThreshold", 0.1, "Decision Threshold value to select kshorts"}; + Configurable kshortMinDCANegToPv{"kshortMinDCANegToPv", .05, "min DCA Neg To PV (cm)"}; + Configurable kshortMinDCAPosToPv{"kshortMinDCAPosToPv", .05, "min DCA Pos To PV (cm)"}; + Configurable kshortMaxDCAV0Dau{"kshortMaxDCAV0Dau", 2.5, "Max DCA V0 Daughters (cm)"}; + Configurable kshortMinv0radius{"kshortMinv0radius", 0.0, "Min V0 radius (cm)"}; + Configurable kshortMaxv0radius{"kshortMaxv0radius", 40, "Max V0 radius (cm)"}; + Configurable kshortMinv0cospa{"kshortMinv0cospa", 0.95, "Min V0 CosPA"}; + Configurable kshortMaxLifeTime{"kshortMaxLifeTime", 20, "Max lifetime"}; + Configurable kshortWindow{"kshortWindow", 0.015, "Mass window around expected (in GeV/c2). Leave negative to disable"}; + Configurable kshortMinRapidity{"kshortMinRapidity", -0.5, "v0 min rapidity"}; + Configurable kshortMaxRapidity{"kshortMaxRapidity", 0.5, "v0 max rapidity"}; + Configurable kshortDauEtaMin{"kshortDauEtaMin", -0.8, "Min pseudorapidity of daughter tracks"}; + Configurable kshortDauEtaMax{"kshortDauEtaMax", 0.8, "Max pseudorapidity of daughter tracks"}; + Configurable kshortMinZ{"kshortMinZ", -240, "Min kshort decay point z value (cm)"}; + Configurable kshortMaxZ{"kshortMaxZ", 240, "Max kshort decay point z value (cm)"}; + Configurable kshortMinTPCCrossedRows{"kshortMinTPCCrossedRows", 50, "Min daughter TPC Crossed Rows"}; + Configurable kshortMinITSclusters{"kshortMinITSclusters", 1, "minimum ITS clusters"}; + Configurable kshortRejectPosITSafterburner{"kshortRejectPosITSafterburner", false, "reject positive track formed out of afterburner ITS tracks"}; + Configurable kshortRejectNegITSafterburner{"kshortRejectNegITSafterburner", false, "reject negative track formed out of afterburner ITS tracks"}; + Configurable kshortArmenterosCoefficient{"kshortArmenterosCoefficient", 0.2, "Armenteros-Podolanski coefficient to reject lambdas"}; + Configurable kshortMaxTPCNSigmas{"kshortMaxTPCNSigmas", 1e+9, "Max |TPC NSigma| (pion hypothesis) for K0S daughters"}; + } kshortSelections; + + struct : ConfigurableGroup { + // base properties + std::string prefix = "axisConfig"; // JSON group name + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for analysis"}; + ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 110.0f}, "Centrality"}; + ConfigurableAxis axisKStarMass{"axisKStarMass", {500, 0.6f, 1.6f}, "M_{K^{*}} (GeV/c^{2})"}; + ConfigurableAxis axisIRBinning{"axisIRBinning", {151, -10, 1500}, "Binning for the interaction rate (kHz)"}; + ConfigurableAxis axisCandSel{"axisCandSel", {15, 0.5f, +15.5f}, "Candidate Selection"}; + } axisConfig; + + void init(InitContext const&) + { + // setting CCDB service + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setFatalWhenNull(false); + + histos.add("hEventCentrality", "hEventCentrality", kTH1D, {axisConfig.axisCentrality}); + + if (eventSelections.fUseEventSelection) { + histos.add("hEventSelection", "hEventSelection", kTH1D, {{21, -0.5f, +20.5f}}); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "sel8 cut"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "kIsTriggerTVX"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(4, "kNoITSROFrameBorder"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(5, "kNoTimeFrameBorder"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(6, "posZ cut"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(7, "kIsVertexITSTPC"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(8, "kIsGoodZvtxFT0vsPV"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(9, "kIsVertexTOFmatched"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(10, "kIsVertexTRDmatched"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(11, "kNoSameBunchPileup"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(12, "kNoCollInTimeRangeStd"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(13, "kNoCollInTimeRangeStrict"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(14, "kNoCollInTimeRangeNarrow"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(15, "kNoCollInRofStd"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(16, "kNoCollInRofStrict"); + if (doPPAnalysis) { + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(17, "INEL>0"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "INEL>1"); + } else { + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(17, "Below min occup."); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "Above max occup."); + } + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(19, "Below min IR"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(20, "Above max IR"); + + if (fGetIR) { + histos.add("GeneralQA/hRunNumberNegativeIR", "", kTH1D, {{1, 0., 1.}}); + histos.add("GeneralQA/hInteractionRate", "hInteractionRate", kTH1D, {axisConfig.axisIRBinning}); + histos.add("GeneralQA/hCentralityVsInteractionRate", "hCentralityVsInteractionRate", kTH2D, {axisConfig.axisCentrality, axisConfig.axisIRBinning}); + } + } + + // Single-particle selection + histos.add("PhotonSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisConfig.axisCandSel}); + for (size_t i = 0; i < photonSels.size(); ++i) + histos.get(HIST("PhotonSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(i + 1, photonSels[i].c_str()); + + histos.add("KShortSel/hSelectionStatistics", "hSelectionStatistics", kTH1D, {axisConfig.axisCandSel}); + for (size_t i = 0; i < kshortSels.size(); ++i) + histos.get(HIST("KShortSel/hSelectionStatistics"))->GetXaxis()->SetBinLabel(i + 1, kshortSels[i].c_str()); + + if (kstarBkgConfig.doSameEvtRotation || kstarBkgConfig.doEvtMixing) { + histos.add("KStarBkg/hDeltaCollision", "hDeltaCollision", kTH1D, {{2000, -1000.f, 1000.f}}); + histos.add("KStarBkg/h2dCentralityCollPair", "h2dCentralityCollPair", kTH2D, {axisConfig.axisCentrality, axisConfig.axisCentrality}); + } + if (kstarBkgConfig.doSameEvtRotation) { + histos.add("KStarBkg/h2dRotKStarMassVsPt", "h2dRotKStarMassVsPt", kTH2D, {axisConfig.axisKStarMass, axisConfig.axisPt}); + histos.add("KStarBkg/h3dRotKStarMassVsPt", "h3dRotKStarMassVsPt", kTH3D, {axisConfig.axisCentrality, axisConfig.axisPt, axisConfig.axisKStarMass}); + histos.add("KStarBkg/h3dRotKStarPtVsOPAngle", "h3dRotKStarPtVsOPAngle", kTH3D, {{140, 0.f, 7.f}, axisConfig.axisPt, axisConfig.axisKStarMass}); + } + if (kstarBkgConfig.doEvtMixing) { + histos.add("KStarBkg/h2dMixedKStarMassVsPt", "h2dMixedKStarMassVsPt", kTH2D, {axisConfig.axisKStarMass, axisConfig.axisPt}); + histos.add("KStarBkg/h3dMixedKStarMassVsPt", "h3dMixedKStarMassVsPt", kTH3D, {axisConfig.axisCentrality, axisConfig.axisPt, axisConfig.axisKStarMass}); + histos.add("KStarBkg/h3dMixedKStarPtVsOPAngle", "h3dMixedKStarPtVsOPAngle", kTH3D, {{140, 0.f, 7.f}, axisConfig.axisPt, axisConfig.axisKStarMass}); + } + } + + //_______________________________________________ + // Event selection (identical to the builder) + template + bool isEventAccepted(TCollision const& collision, bool fillHists) + { + if (fillHists) + histos.fill(HIST("hEventSelection"), 0. /* all collisions */); + if (eventSelections.requireSel8 && !collision.sel8()) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 1 /* sel8 collisions */); + if (eventSelections.requireTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 2 /* FT0 vertex (acceptable FT0C-FT0A time difference) collisions */); + if (eventSelections.rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 3 /* Not at ITS ROF border */); + if (eventSelections.rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 4 /* Not at TF border */); + if (std::abs(collision.posZ()) > eventSelections.maxZVtxPosition) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 5 /* vertex-Z selected */); + if (eventSelections.requireIsVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 6 /* Contains at least one ITS-TPC track */); + if (eventSelections.requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 7 /* PV position consistency check */); + if (eventSelections.requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 8 /* PV with at least one contributor matched with TOF */); + if (eventSelections.requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 9 /* PV with at least one contributor matched with TRD */); + if (eventSelections.rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 10 /* Not at same bunch pile-up */); + if (eventSelections.requireNoCollInTimeRangeStd && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 11 /* No other collision within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds*/); + if (eventSelections.requireNoCollInTimeRangeStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 12 /* No other collision within +/- 10 microseconds */); + if (eventSelections.requireNoCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 13 /* No other collision within +/- 2 microseconds */); + if (eventSelections.requireNoCollInROFStd && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 14 /* No other collision within the same ITS ROF with mult. above a certain threshold */); + if (eventSelections.requireNoCollInROFStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 15 /* No other collision within the same ITS ROF */); + if (doPPAnalysis) { // we are in pp + if (eventSelections.requireINEL0 && collision.multNTracksPVeta1() < 1) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 16 /* INEL > 0 */); + if (eventSelections.requireINEL1 && collision.multNTracksPVeta1() < 2) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 17 /* INEL > 1 */); + } else { // we are in Pb-Pb + float collisionOccupancy = eventSelections.useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); + if (eventSelections.minOccupancy >= 0 && collisionOccupancy < eventSelections.minOccupancy) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 16 /* Below min occupancy */); + if (eventSelections.maxOccupancy >= 0 && collisionOccupancy > eventSelections.maxOccupancy) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 17 /* Above max occupancy */); + } + + // Fetch interaction rate only if required (in order to limit ccdb calls) + float interactionRate = (fGetIR) ? rateFetcher.fetch(ccdb.service, collision.timestamp(), collision.runNumber(), irSource, fIRCrashOnNull) * 1.e-3 : -1; + float centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + + if (fGetIR) { + if (interactionRate < 0) + histos.get(HIST("GeneralQA/hRunNumberNegativeIR"))->Fill(Form("%d", collision.runNumber()), 1); // This lists all run numbers without IR info! + + histos.fill(HIST("GeneralQA/hInteractionRate"), interactionRate); + histos.fill(HIST("GeneralQA/hCentralityVsInteractionRate"), centrality, interactionRate); + } + + if (eventSelections.minIR >= 0 && interactionRate < eventSelections.minIR) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 18 /* Below min IR */); + + if (eventSelections.maxIR >= 0 && interactionRate > eventSelections.maxIR) { + return false; + } + if (fillHists) { + histos.fill(HIST("hEventSelection"), 19 /* Above max IR */); + // Fill centrality histogram after event selection + histos.fill(HIST("hEventCentrality"), centrality); + } + return true; + } + + //_______________________________________________ + // Process v0 photon candidate + template + bool processPhotonCandidate(TV0Object const& gamma) + { + // V0 type selection + if (gamma.v0Type() != photonSelections.photonv0TypeSel && photonSelections.photonv0TypeSel > -1) + return false; + + float photonY = RecoDecay::y(std::array{gamma.px(), gamma.py(), gamma.pz()}, o2::constants::physics::MassGamma); + + if (useMLScores) { + if (gamma.gammaBDTScore() <= photonSelections.gammaMLThreshold) + return false; + + } else { + // Standard selection + // Gamma basic selection criteria: + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 1.); + if ((gamma.mGamma() < 0) || (gamma.mGamma() > photonSelections.photonMaxMass)) + return false; + + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 2.); + if ((photonY < photonSelections.photonMinRapidity) || (photonY > photonSelections.photonMaxRapidity)) + return false; + + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 3.); + if (gamma.negativeeta() < photonSelections.photonDauEtaMin || gamma.negativeeta() > photonSelections.photonDauEtaMax) + return false; + + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 4.); + if (gamma.positiveeta() < photonSelections.photonDauEtaMin || gamma.positiveeta() > photonSelections.photonDauEtaMax) + return false; + + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 5.); + if ((TMath::Abs(gamma.dcapostopv()) < photonSelections.photonMinDCADauToPv) || (TMath::Abs(gamma.dcanegtopv()) < photonSelections.photonMinDCADauToPv)) + return false; + + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 6.); + if (TMath::Abs(gamma.dcaV0daughters()) > photonSelections.photonMaxDCAV0Dau) + return false; + + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 7.); + if ((gamma.v0radius() < photonSelections.photonMinRadius) || (gamma.v0radius() > photonSelections.photonMaxRadius)) + return false; + + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 8.); + if ((gamma.z() < photonSelections.photonMinZ) || (gamma.z() > photonSelections.photonMaxZ)) + return false; + + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 9.); + if (gamma.v0cosPA() < photonSelections.photonMinV0cospa) + return false; + + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 10.); + float photonPhi = RecoDecay::phi(gamma.px(), gamma.py()); + if ((((photonPhi > photonSelections.photonPhiMin1) && (photonPhi < photonSelections.photonPhiMax1)) || ((photonPhi > photonSelections.photonPhiMin2) && (photonPhi < photonSelections.photonPhiMax2))) && ((photonSelections.photonPhiMin1 != -1) && (photonSelections.photonPhiMax1 != -1) && (photonSelections.photonPhiMin2 != -1) && (photonSelections.photonPhiMax2 != -1))) + return false; + + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 11.); + if (gamma.qtarm() > photonSelections.photonMaxQt) + return false; + + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 12.); + if (TMath::Abs(gamma.alpha()) > photonSelections.photonMaxAlpha) + return false; + + auto posTrackGamma = gamma.template posTrackExtra_as(); + auto negTrackGamma = gamma.template negTrackExtra_as(); + + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 13.); + if ((posTrackGamma.tpcCrossedRows() < photonSelections.photonMinTPCCrossedRows) || (negTrackGamma.tpcCrossedRows() < photonSelections.photonMinTPCCrossedRows)) + return false; + + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 14.); + if (((posTrackGamma.tpcNSigmaEl() < photonSelections.photonMinTPCNSigmas) || (posTrackGamma.tpcNSigmaEl() > photonSelections.photonMaxTPCNSigmas))) + return false; + + if (((negTrackGamma.tpcNSigmaEl() < photonSelections.photonMinTPCNSigmas) || (negTrackGamma.tpcNSigmaEl() > photonSelections.photonMaxTPCNSigmas))) + return false; + + histos.fill(HIST("PhotonSel/hSelectionStatistics"), 15.); + } + + return true; + } + + //_______________________________________________ + // Process K0Short candidate + template + bool processKShortCandidate(TV0Object const& kshort, TCollision const& collision) + { + // V0 type selection + if (kshort.v0Type() != 1) + return false; + + if (useMLScores) { + // if (kshort.k0ShortBDTScore() <= kshortSelections.kshortMLThreshold) + return false; + + } else { + // KShort basic selection criteria: + histos.fill(HIST("KShortSel/hSelectionStatistics"), 1.); + if ((TMath::Abs(kshort.mK0Short() - o2::constants::physics::MassK0Short) > kshortSelections.kshortWindow) && kshortSelections.kshortWindow > 0) + return false; + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 2.); + if ((kshort.yK0Short() < kshortSelections.kshortMinRapidity) || (kshort.yK0Short() > kshortSelections.kshortMaxRapidity)) + return false; + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 3.); + if ((kshort.negativeeta() < kshortSelections.kshortDauEtaMin) || (kshort.negativeeta() > kshortSelections.kshortDauEtaMax)) + return false; + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 4.); + if ((kshort.positiveeta() < kshortSelections.kshortDauEtaMin) || (kshort.positiveeta() > kshortSelections.kshortDauEtaMax)) + return false; + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 5.); + if ((TMath::Abs(kshort.dcapostopv()) < kshortSelections.kshortMinDCAPosToPv) || (TMath::Abs(kshort.dcanegtopv()) < kshortSelections.kshortMinDCANegToPv)) + return false; + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 6.); + if ((kshort.v0radius() < kshortSelections.kshortMinv0radius) || (kshort.v0radius() > kshortSelections.kshortMaxv0radius)) + return false; + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 7.); + if ((kshort.z() < kshortSelections.kshortMinZ) || (kshort.z() > kshortSelections.kshortMaxZ)) + return false; + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 8.); + if (TMath::Abs(kshort.dcaV0daughters()) > kshortSelections.kshortMaxDCAV0Dau) + return false; + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 9.); + if (kshort.qtarm() < kshortSelections.kshortArmenterosCoefficient * TMath::Abs(kshort.alpha())) + return false; + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 10.); + if (kshort.v0cosPA() < kshortSelections.kshortMinv0cospa) + return false; + + auto posTrackKShort = kshort.template posTrackExtra_as(); + auto negTrackKShort = kshort.template negTrackExtra_as(); + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 11.); + if ((posTrackKShort.tpcCrossedRows() < kshortSelections.kshortMinTPCCrossedRows) || (negTrackKShort.tpcCrossedRows() < kshortSelections.kshortMinTPCCrossedRows)) + return false; + + // MinITSCls + bool posIsFromAfterburner = posTrackKShort.itsChi2PerNcl() < 0; + bool negIsFromAfterburner = negTrackKShort.itsChi2PerNcl() < 0; + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 12.); + if (posTrackKShort.itsNCls() < kshortSelections.kshortMinITSclusters && (!kshortSelections.kshortRejectPosITSafterburner || posIsFromAfterburner)) + return false; + if (negTrackKShort.itsNCls() < kshortSelections.kshortMinITSclusters && (!kshortSelections.kshortRejectNegITSafterburner || negIsFromAfterburner)) + return false; + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 13.); + float fKShortLifeTime = kshort.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short; + if (fKShortLifeTime > kshortSelections.kshortMaxLifeTime) + return false; + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 14.); + // TPC PID selection on the K0S pion daughters (same convention as posTrackKShort.tpcNSigmaPi()) + if (((TMath::Abs(posTrackKShort.tpcNSigmaPi()) > kshortSelections.kshortMaxTPCNSigmas) || + (TMath::Abs(negTrackKShort.tpcNSigmaPi()) > kshortSelections.kshortMaxTPCNSigmas))) + return false; + + histos.fill(HIST("KShortSel/hSelectionStatistics"), 15.); + } + return true; + } + + //_______________________________________________ + // Compute same-event rotational background for K* within a single collision + template + void calculateRotBackground(TCollision const& coll, + std::vector const& photonIndices, + std::vector const& kshortIndices, + TV0s const& fullV0s) + { + if (photonIndices.empty() || kshortIndices.empty()) + return; + + const float centrality = doPPAnalysis ? coll.centFT0M() : coll.centFT0C(); + for (const int& kIdx : kshortIndices) { + const auto& kshort = fullV0s.rawIteratorAt(kIdx); + + for (const int& pIdx : photonIndices) { + const auto& photon = fullV0s.rawIteratorAt(pIdx); + + // photon as a massless 4-vector + ROOT::Math::PtEtaPhiMVector pGamma(photon.pt(), + photon.eta(), + photon.phi(), + 0.0); + + for (int irot = 0; irot < kstarBkgConfig.nBkgRot; ++irot) { + float theta = rotRng.Uniform(kstarBkgConfig.rotationalFactor * o2::constants::math::PI - o2::constants::math::PI / kstarBkgConfig.rotationalCut, + kstarBkgConfig.rotationalFactor * o2::constants::math::PI + o2::constants::math::PI / kstarBkgConfig.rotationalCut); + + ROOT::Math::PtEtaPhiMVector kRot(kshort.pt(), kshort.eta(), kshort.phi() + theta, o2::constants::physics::MassK0Short); + + auto kstar = pGamma + kRot; + + float rapidity = RecoDecay::y(std::array{static_cast(kstar.Px()), + static_cast(kstar.Py()), + static_cast(kstar.Pz())}, + o2::constants::physics::MassK0Star892); + if (std::abs(rapidity) > kstarBkgConfig.kstarMaxRap) + continue; + + // Opening angle between photon and rotated K0s (QA only, not used as a cut) + double cosOA = pGamma.Vect().Dot(kRot.Vect()) / (pGamma.P() * kRot.P()); + double openAngle = std::acos(cosOA); + + histos.fill(HIST("KStarBkg/h2dRotKStarMassVsPt"), kstar.M(), kstar.Pt()); + histos.fill(HIST("KStarBkg/h3dRotKStarMassVsPt"), centrality, kstar.Pt(), kstar.M()); + histos.fill(HIST("KStarBkg/h3dRotKStarPtVsOPAngle"), openAngle, kstar.Pt(), kstar.M()); + } + } + } + } + + //_______________________________________________ + // Centrality helper for the background (keeps the builder's semantics) + template + float getCentralityRun3Bkg(TCollision const& collision) + { + return doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + } + + //_______________________________________________ + // Main: same-event rotation + event mixing for K* background (data only) + using BkgBinningType = ColumnBinningPolicy; + template + void calculateKStarBkg(TCollisions const& collisions, TV0s const& fullV0s) + { + // Per-collision pools of selected photon and K0s V0 indices + std::vector> photonPool(collisions.size()); + std::vector> kshortPool(collisions.size()); + + // V0 grouping by straCollisionId + std::vector> v0grouped(collisions.size()); + for (const auto& v0 : fullV0s) { + v0grouped[v0.straCollisionId()].push_back(v0.globalIndex()); + } + + // ── Pass 1: populate pools using single-particle selections ── + for (const auto& coll : collisions) { + + if (eventSelections.fUseEventSelection && !isEventAccepted(coll, true)) + continue; + + for (size_t i = 0; i < v0grouped[coll.globalIndex()].size(); i++) { + auto v0 = fullV0s.rawIteratorAt(v0grouped[coll.globalIndex()][i]); + + if (processPhotonCandidate(v0)) + photonPool[coll.globalIndex()].push_back(v0.globalIndex()); + + if (processKShortCandidate(v0, coll)) + kshortPool[coll.globalIndex()].push_back(v0.globalIndex()); + } + + // Same-event rotational background + if (kstarBkgConfig.doSameEvtRotation) { + calculateRotBackground(coll, + photonPool[coll.globalIndex()], + kshortPool[coll.globalIndex()], + fullV0s); + } + } + + // Event Mixing + if (!kstarBkgConfig.doEvtMixing) + return; + + // Build the mixing binning locally: a struct member initialized from a + // ConfigurableAxis captures the default bins at task construction time (before + // the framework applies JSON overrides), silently ignoring user configuration. + BkgBinningType bkgColBinning{{axisVertexMixBkg, axisCentralityMixBkg}, true}; + + for (const auto& [coll1, coll2] : selfCombinations(bkgColBinning, kstarBkgConfig.nMix, -1, + collisions, collisions)) { + if (coll1.globalIndex() == coll2.globalIndex()) + continue; + + histos.fill(HIST("KStarBkg/hDeltaCollision"), + coll1.globalIndex() - coll2.globalIndex()); + histos.fill(HIST("KStarBkg/h2dCentralityCollPair"), + getCentralityRun3Bkg(coll1), getCentralityRun3Bkg(coll2)); + + if (std::abs(static_cast(coll1.globalIndex()) - static_cast(coll2.globalIndex())) < kstarBkgConfig.deltaCollision) + continue; + + auto const& photons1 = photonPool[coll1.globalIndex()]; + auto const& kshorts1 = kshortPool[coll1.globalIndex()]; + auto const& photons2 = photonPool[coll2.globalIndex()]; + auto const& kshorts2 = kshortPool[coll2.globalIndex()]; + + // K0s(coll1) × γ(coll2) + if (!kshorts1.empty() && !photons2.empty()) { + for (const int& kIdx : kshorts1) { + const auto& kshort = fullV0s.rawIteratorAt(kIdx); + float kP = std::hypot(kshort.px(), kshort.py(), kshort.pz()); + ROOT::Math::PxPyPzEVector fourMomKShort( + kshort.px(), kshort.py(), kshort.pz(), + std::sqrt(kP * kP + + o2::constants::physics::MassK0Short * + o2::constants::physics::MassK0Short)); + + for (const int& pIdx : photons2) { + const auto& photon = fullV0s.rawIteratorAt(pIdx); + float pP = std::hypot(photon.px(), photon.py(), photon.pz()); + ROOT::Math::PxPyPzEVector fourMomPhoton( + photon.px(), photon.py(), photon.pz(), pP); + + auto fourMomKStar = fourMomPhoton + fourMomKShort; + + double cosOA = fourMomPhoton.Vect().Dot(fourMomKShort.Vect()) / + (fourMomPhoton.P() * fourMomKShort.P()); + double openAngle = std::acos(cosOA); + float mass = fourMomKStar.M(); + float pt = fourMomKStar.Pt(); + // Rapidity computed under the K*(892) mass hypothesis (NOT the actual pair + // invariant mass) to match the same-event rotational background and the + // buildKStar signal selection, so the rapidity acceptance is identical for + // signal and all backgrounds. + float rapidity = RecoDecay::y(std::array{static_cast(fourMomKStar.Px()), + static_cast(fourMomKStar.Py()), + static_cast(fourMomKStar.Pz())}, + o2::constants::physics::MassK0Star892); + + if (openAngle > kstarBkgConfig.kstarMaxOPAngle) + continue; + if (std::abs(rapidity) > kstarBkgConfig.kstarMaxRap) + continue; + + histos.fill(HIST("KStarBkg/h2dMixedKStarMassVsPt"), mass, pt); + histos.fill(HIST("KStarBkg/h3dMixedKStarMassVsPt"), + getCentralityRun3Bkg(coll1), pt, mass); + histos.fill(HIST("KStarBkg/h3dMixedKStarPtVsOPAngle"), + openAngle, pt, mass); + } + } + } + + // γ(coll1) × K0s(coll2) + if (!photons1.empty() && !kshorts2.empty()) { + for (const int& pIdx : photons1) { + const auto& photon = fullV0s.rawIteratorAt(pIdx); + float pP = std::hypot(photon.px(), photon.py(), photon.pz()); + ROOT::Math::PxPyPzEVector fourMomPhoton( + photon.px(), photon.py(), photon.pz(), pP); + + for (const int& kIdx : kshorts2) { + const auto& kshort = fullV0s.rawIteratorAt(kIdx); + float kP = std::hypot(kshort.px(), kshort.py(), kshort.pz()); + ROOT::Math::PxPyPzEVector fourMomKShort( + kshort.px(), kshort.py(), kshort.pz(), + std::sqrt(kP * kP + + o2::constants::physics::MassK0Short * + o2::constants::physics::MassK0Short)); + + auto fourMomKStar = fourMomPhoton + fourMomKShort; + + double cosOA = fourMomPhoton.Vect().Dot(fourMomKShort.Vect()) / + (fourMomPhoton.P() * fourMomKShort.P()); + double openAngle = std::acos(cosOA); + float mass = fourMomKStar.M(); + float pt = fourMomKStar.Pt(); + // Rapidity computed under the K*(892) mass hypothesis (NOT the actual pair + // invariant mass) to match the same-event rotational background and the + // buildKStar signal selection, so the rapidity acceptance is identical for + // signal and all backgrounds. + float rapidity = RecoDecay::y(std::array{static_cast(fourMomKStar.Px()), + static_cast(fourMomKStar.Py()), + static_cast(fourMomKStar.Pz())}, + o2::constants::physics::MassK0Star892); + + if (openAngle > kstarBkgConfig.kstarMaxOPAngle) + continue; + if (std::abs(rapidity) > kstarBkgConfig.kstarMaxRap) + continue; + + histos.fill(HIST("KStarBkg/h2dMixedKStarMassVsPt"), mass, pt); + histos.fill(HIST("KStarBkg/h3dMixedKStarMassVsPt"), + getCentralityRun3Bkg(coll1), pt, mass); + histos.fill(HIST("KStarBkg/h3dMixedKStarPtVsOPAngle"), + openAngle, pt, mass); + } + } + } + } + } + + //_______________________________________________ + // Data process: same-event rotational + mixed-event K* background + void processKStarBkg(soa::Join const& collisions, + V0StandardDerivedDatas const& fullV0s, + dauTracks const&) + { + calculateKStarBkg(collisions, fullV0s); + } + + PROCESS_SWITCH(k892hadronphotonBkg, processKStarBkg, "Compute K* same-event rotational and mixed-event background (data)", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/Resonances/kstar0analysis.cxx b/PWGLF/Tasks/Resonances/kstar0analysis.cxx index ba0e75d4e1a..3cbc9f29503 100644 --- a/PWGLF/Tasks/Resonances/kstar0analysis.cxx +++ b/PWGLF/Tasks/Resonances/kstar0analysis.cxx @@ -136,6 +136,7 @@ struct Kstar0analysis { Configurable pidnSigmaPreSelectionCut{"pidnSigmaPreSelectionCut", 4.0f, "pidnSigma Cut for pre-selection of tracks"}; Configurable cByPassTOF{"cByPassTOF", false, "By pass TOF PID selection"}; // By pass TOF PID selection Configurable cPIDcutType{"cPIDcutType", 2, "cPIDcutType = 1 for square cut, 2 for circular cut"}; // By pass TOF PID selection + Configurable ispTdepPID{"ispTdepPID", false, "enable pT dependent PID"}; // Kaon Configurable> kaonTPCPIDpTintv{"kaonTPCPIDpTintv", {0.5f}, "pT intervals for Kaon TPC PID cuts"}; @@ -597,6 +598,24 @@ struct Kstar0analysis { return false; } + template + bool selectionPIDPion(const T& candidate) + { + auto vPionTPCPIDcuts = configPID.pionTPCPIDcuts.value; + auto vPionTPCTOFCombinedPIDcuts = configPID.pionTPCTOFCombinedPIDcuts.value; + + if (!configPID.cByPassTOF && candidate.hasTOF() && (candidate.tofNSigmaPi() * candidate.tofNSigmaPi() + candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi()) < (vPionTPCTOFCombinedPIDcuts[0] * vPionTPCTOFCombinedPIDcuts[0])) { + return true; + } + if (!configPID.cByPassTOF && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < vPionTPCPIDcuts[0]) { + return true; + } + if (configPID.cByPassTOF && std::abs(candidate.tpcNSigmaPi()) < vPionTPCPIDcuts[0]) { + return true; + } + return false; + } + template bool ptDependentPidKaon(const T& candidate) { @@ -669,6 +688,24 @@ struct Kstar0analysis { return false; } + template + bool selectionPIDKaon(const T& candidate) + { + auto vKaonTPCPIDcuts = configPID.kaonTPCPIDcuts.value; + auto vKaonTPCTOFCombinedPIDcuts = configPID.kaonTPCTOFCombinedPIDcuts.value; + + if (!configPID.cByPassTOF && candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (vKaonTPCTOFCombinedPIDcuts[0] * vKaonTPCTOFCombinedPIDcuts[0])) { + return true; + } + if (!configPID.cByPassTOF && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < vKaonTPCPIDcuts[0]) { + return true; + } + if (configPID.cByPassTOF && std::abs(candidate.tpcNSigmaKa()) < vKaonTPCPIDcuts[0]) { + return true; + } + return false; + } + auto static constexpr MinPtforProtonRejection = 1.0f; auto static constexpr MaxPtforProtonRejection = 2.0f; auto static constexpr MaxnSigmaforProtonRejection = 2.0f; @@ -786,7 +823,10 @@ struct Kstar0analysis { if (crejectProton && rejectProton(trk2)) // to remove proton contamination from the kaon track continue; - if (!ptDependentPidPion(trk1) || !ptDependentPidKaon(trk2)) + if (configPID.ispTdepPID && (!ptDependentPidPion(trk1) || !ptDependentPidKaon(trk2))) + continue; + + if (!configPID.ispTdepPID && (!selectionPIDPion(trk1) || !selectionPIDKaon(trk2))) continue; //// QA plots after the selection @@ -1313,22 +1353,6 @@ struct Kstar0analysis { // ========================= if (std::abs(part.pdgCode()) == Pdg::kK0Star892) { - std::vector daughterPDGs; - if (part.has_daughters()) { - auto daughter01 = mcParticles.rawIteratorAt(part.daughtersIds()[0] - mcParticles.offset()); - auto daughter02 = mcParticles.rawIteratorAt(part.daughtersIds()[1] - mcParticles.offset()); - daughterPDGs = {daughter01.pdgCode(), daughter02.pdgCode()}; - } else { - daughterPDGs = {-1, -1}; - } - - bool pass1 = std::abs(daughterPDGs[0]) == kKPlus || std::abs(daughterPDGs[1]) == kKPlus; // At least one decay to Kaon - bool pass2 = std::abs(daughterPDGs[0]) == kPiPlus || std::abs(daughterPDGs[1]) == kPiPlus; // At least one decay to Pion - - // Checking if we have both decay products - if (!pass1 || !pass2) - continue; - if (part.pdgCode() > 0) histos.fill(HIST("Result/SignalLoss/GenTruek892pt_den"), part.pt(), centrality); else diff --git a/PWGLF/Tasks/Resonances/kstar892LightIon.cxx b/PWGLF/Tasks/Resonances/kstar892LightIon.cxx index 580fd352909..3750eb6f02a 100644 --- a/PWGLF/Tasks/Resonances/kstar892LightIon.cxx +++ b/PWGLF/Tasks/Resonances/kstar892LightIon.cxx @@ -16,6 +16,7 @@ #include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/RCTSelectionFlags.h" +#include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -31,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -48,10 +48,13 @@ #include #include +#include #include #include #include +#include #include +#include #include using namespace o2; @@ -118,7 +121,7 @@ struct Kstar892LightIon { Configurable cfgITSChi2NCl{"cfgITSChi2NCl", 36.0, "ITS Chi2/NCl"}; Configurable cfgTPCChi2NClMax{"cfgTPCChi2NClMax", 4.0, "TPC Chi2/NCl"}; Configurable cfgTPCChi2NClMin{"cfgTPCChi2NClMin", 0.0, "TPC Chi2/NCl"}; - Configurable isUseITSTPCRefit{"isUseITSTPCRefit", false, "Require ITS Refit"}; + // Configurable isUseITSTPCRefit{"isUseITSTPCRefit", false, "Require ITS Refit"}; Configurable isApplyPtDepDCAxyCut{"isApplyPtDepDCAxyCut", false, "Apply pT dependent DCAxy cut"}; Configurable isGoldenChi2{"isGoldenChi2", false, "Apply golden chi2 cut"}; Configurable cfgDeepAngle{"cfgDeepAngle", 0.04, "Deep Angle cut value"}; @@ -135,15 +138,9 @@ struct Kstar892LightIon { Configurable motherRapidityMin{"motherRapidityMin", -0.5, "Minimum rapidity of mother"}; // PID selections - Configurable onlyTOF{"onlyTOF", false, "only TOF tracks"}; - Configurable onlyTOFHIT{"onlyTOFHIT", false, "accept only TOF hit tracks at high pt"}; - Configurable onlyTOFVeto{"onlyTOFVeto", false, "only select TOF tracks with TOF and TPC cuts"}; - Configurable onlyTPC{"onlyTPC", false, "only TPC tracks"}; - Configurable isApplypTdepPID{"isApplypTdepPID", false, "Apply pT dependent PID"}; - Configurable isApplypTdepPIDwTOF{"isApplypTdepPIDwTOF", false, "Apply pT dependent PID with compulsory TOF condition in a pT range"}; - Configurable isApplyMID{"isApplyMID", false, "Apply particle MID"}; - Configurable isApplypTdepMID{"isApplypTdepMID", false, "Apply pT dependent particle MID"}; - Configurable isApplypTdepMIDComp{"isApplypTdepMIDComp", false, "Apply pT dependent particle MID by comparing the nsigma value"}; + Configurable pidStrategy{"pidStrategy", 0, "0=Standard, 1=pTDependent, 2=pTDependentTOF, 3=ThreePtDependent, 4=PIDCompare"}; + Configurable pidMode{"pidMode", 0, "0=Combined,1=TPC,2=TOF,3=TOFHIT,4=TOFVeto"}; + Configurable midStrategy{"midStrategy", -1, "-1=Disabled, 0=Standard, 1=PtDependent, 2=PtDependentCompare"}; Configurable nsigmaCutTPCPi{"nsigmaCutTPCPi", 3.0, "TPC Nsigma cut for pions"}; Configurable nsigmaCutTPCKa{"nsigmaCutTPCKa", 3.0, "TPC Nsigma cut for kaons"}; @@ -152,20 +149,23 @@ struct Kstar892LightIon { Configurable nsigmaCutCombinedKa{"nsigmaCutCombinedKa", 3.0, "Combined Nsigma cut for kaon"}; Configurable nsigmaCutCombinedPi{"nsigmaCutCombinedPi", 3.0, "Combined Nsigma cut for pion"}; - Configurable nsigmaCutCombinedMID{"nsigmaCutCombinedMID", 3.0, "Combined Nsigma cut for pion and kaon in MID"}; Configurable nsigmaCutTPCMID{"nsigmaCutTPCMID", 1.0, "MID Nsigma cut for pion and kaon in TPC"}; Configurable isApplyFakeTrack{"isApplyFakeTrack", false, "Fake track selection"}; Configurable cfgFakeTrackCutKa{"cfgFakeTrackCutKa", 0.3, "Cut based on momentum difference in global and TPC tracks for kaons"}; Configurable cfgFakeTrackCutPi{"cfgFakeTrackCutPi", 0.3, "Cut based on momentum difference in global and TPC tracks for pions"}; - Configurable pionMIDpTLow{"pionMIDpTLow", 1.0, "Low pT cut for pion in MID"}; - Configurable pionMIDpTHigh{"pionMIDpTHigh", 2.5, "High pT cut for pion in MID"}; - Configurable kaonMIDpTLow{"kaonMIDpTLow", 0.7, "Low pT cut for kaon in MID"}; - Configurable kaonMIDpTHigh{"kaonMIDpTHigh", 2.5, "High pT cut for kaon in MID"}; + Configurable pionMidPtLow{"pionMidPtLow", 1.0, "Low pT cut for pion in MID"}; + Configurable pionMidPtHigh{"pionMidPtHigh", 2.5, "High pT cut for pion in MID"}; + Configurable kaonMidPtLow{"kaonMidPtLow", 0.7, "Low pT cut for kaon in MID"}; + Configurable kaonMidPtHigh{"kaonMidPtHigh", 2.5, "High pT cut for kaon in MID"}; - // Fixed variables - float lowPtCutPID = 0.5; + Configurable lowPtCutPid{"lowPtCutPid", 0.5, "Low pT cut for PID"}; + Configurable highPtCutPid{"highPtCutPid", 6.0, "High pT cut for PID"}; + + Configurable lowPtPid{"lowPtPid", 2.5, "Low pT cut for PID"}; + Configurable midPtPid{"midPtPid", 1.5, "Mid pT cut for PID"}; + Configurable highPtPid{"highPtPid", 2.5, "High pT cut for PID"}; Configurable selHasFT0MC{"selHasFT0MC", true, "Has FT0?"}; Configurable isZvtxPosSelMC{"isZvtxPosSelMC", true, "Zvtx position selection for MC events?"}; @@ -209,15 +209,53 @@ struct Kstar892LightIon { kNEstimators // useful if you want to iterate or size things }; - enum PIDParticle { + enum class PIDParticle { kPion, - kKaon, - kProton + kKaon + }; + + enum class PIDStrategy { + Standard, + PtDependent, + PtDependentTOF, + ThreePtDependent, + PIDCompare + }; + + enum class PIDMode { + Combined, + TPC, + TOF, + TOFHIT, + TOFVeto + }; + + enum class MIDStrategy { + Disabled = -1, + Standard = 0, + PtDependent = 1, + PtDependentCompare = 2 }; int noOfDaughters = 2; + int initialValue = -9999999; + double massPi = o2::constants::physics::MassPiPlus; + double massKa = o2::constants::physics::MassKPlus; + + double pionPidPtLow = 1.0, pionPidPtHigh = 2.5, kaonPidPtLow = 0.7, kaonPidPtHigh = 2.5; + + int kKstar14300 = 10311, kK11400Plus = 20323, kKStar1680Plus = 30323, kK21770Plus = 10325, kK21820Plus = 20325, kKstar14100 = 100313, kKstar16800 = 30313, kK218200 = 20315, kK217700 = 10315, kKstar214300 = 315, kKstar1430Plus = 10321; + + // ThreePtDependent PID cuts + // Regions: + // 0 : pT < lowPtCutPid + // 1 : lowPtCutPid <= pT < highPtCutPID + // 2 : pT >= highPtCutPID + // static constexpr std::array TPCPiCuts3Pt{3.0f, 1.5f, 2.0f}; + // static constexpr std::array TOFPiCuts3Pt{3.0f, 2.0f, 3.0f}; - double pionPIDpTLow = 1.0, pionPIDpTHigh = 2.5, kaonPIDpTLow = 0.7, kaonPIDpTHigh = 2.5; + // static constexpr std::array TPCKaCuts3Pt{2.0f, 1.5f, 2.0f}; + // static constexpr std::array TOFKaCuts3Pt{3.0f, 2.0f, 3.0f}; TRandom* rn = new TRandom(); @@ -336,8 +374,9 @@ struct Kstar892LightIon { hInvMass.add("h3KstarInvMasslikeSignPP", "kstar like Sign", kTH3F, {centralityAxis, ptAxis, invmassAxis}); hInvMass.add("h3KstarInvMasslikeSignMM", "kstar like Sign", kTH3F, {centralityAxis, ptAxis, invmassAxis}); } - if (calcRotational) + if (calcRotational) { hInvMass.add("h3KstarInvMassRotated", "kstar rotated", kTH3F, {centralityAxis, ptAxis, invmassAxis}); + } // MC histograms if (doprocessGen) { @@ -355,17 +394,19 @@ struct Kstar892LightIon { if (doprocessRec) { hMC.add("Rec/hAllRecCollisions", "All reconstructed events", kTH1F, {centralityAxis}); hMC.add("Rec/h1KstarRecMass", "Invariant mass of kstar meson", kTH1F, {invmassAxis}); - hMC.add("Rec/h2KstarRecpt1", "pT of kstar meson", kTH3F, {ptAxis, centralityAxis, invmassAxis}); - hMC.add("Rec/h2KstarRecpt2", "pT of kstar meson", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("Rec/h3KstarRec", "pT of reconstructed kstar meson", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("Rec/h3KstarGen", "pT of generated kstar meson", kTH3F, {ptAxis, centralityAxis, invmassAxis}); hMC.add("Rec/h1RecCent", "centrality reconstructed", kTH1F, {centralityAxis}); hMC.add("Rec/h1KSRecsplit", "KS meson Rec split", kTH1F, {{100, 0.0f, 10.0f}}); + + hMC.add("Rec/hMassShift", "#Delta M = m_{rec} - m_{gen}; #it{p}_{T}_{gen}; #it{p}_{T}_{rec}; #Delta M", kTH3F, {ptAxis, ptAxis, {2000, -0.1, 0.1}}); } // Signal Loss & Event Loss if (doprocessEvtLossSigLossMC) { hMC.add("ImpactCorr/hImpactParameterGen", "Impact parameter of generated MC events", kTH1F, {impactParAxis}); hMC.add("ImpactCorr/hImpactParameterRec", "Impact parameter of selected MC events", kTH1F, {impactParAxis}); - hMC.add("ImpactCorr/hImpactParvsCentrRec", "Impact parameter of selected MC events vs centrality", kTH2F, {{centralityAxis}, impactParAxis}); + hMC.add("ImpactCorr/hImpactParvsCentrRec", "Impact parameter of selected MC events vs centrality", kTH2F, {centralityAxis, impactParAxis}); hMC.add("ImpactCorr/hKstarGenBeforeEvtSel", "K*0 before event selections", kTH2F, {ptAxis, impactParAxis}); hMC.add("ImpactCorr/hKstarGenAfterEvtSel", "K*0 after event selections", kTH2F, {ptAxis, impactParAxis}); } @@ -413,6 +454,57 @@ struct Kstar892LightIon { hMC.add("Reflections/hKstarSelf", "Refelction template of Kstar", kTH3F, {ptAxis, centralityAxis, invmassAxis}); hMC.add("Reflections/hEtaToKpi", "Refelction template of Eta", kTH3F, {ptAxis, centralityAxis, invmassAxis}); hMC.add("Reflections/hEtaPrimeToKpi", "Refelction template of Eta'", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + + hMC.add("FeedDown/hK1_1270", "Distribution for K1(1270)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("FeedDown/hK1_1400", "Distribution for K1(1270)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("FeedDown/hKstar1410", "Distribution for K*(1410)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("FeedDown/hKstar0_1430_0", "Distribution for K*0(1430)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("FeedDown/hKstar0_1430_ch", "Distribution for K*+-(1430)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("FeedDown/hKstar2_1430", "Distribution for K*2(1430)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("FeedDown/hK2_1770", "Distribution for K2(1770)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("FeedDown/hK2_1820", "Distribution for K2(1820)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("FeedDown/hKstar1680", "Distribution for K2(1680)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + } + + if (doprocessRecCorrelatedBackground) { + hMC.add("CorrelatedBG/hKstar1410", "Wrong pair distribution for K*(1410)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("CorrelatedBG/hKstar0_1430", "Wrong pair distribution for K*(1410)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("CorrelatedBG/hK1_1270", "Wrong pair distribution for K*(1410)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("CorrelatedBG/hK1_1400", "Wrong pair distribution for K*(1410)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("CorrelatedBG/hKstar1680", "Wrong pair distribution for K*(1410)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("CorrelatedBG/hK2_1770", "Wrong pair distribution for K*(1410)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("CorrelatedBG/hK2_1820", "Wrong pair distribution for K*(1410)", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + } + if (doprocessTemplateMC) { + hMC.add("Template/hSignal", "True K*0 signal", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("Template/hKstarReflection", "K*0 signal due to mis-identification", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("Template/hSameMotherOther", "Kpi pair from same mother other than K*0", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("Template/hDifferentMother", "Kpi pair from different mothers", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("Template/hPrimaryResonance", "Kpi pair one primary another from decay", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("Template/hPrimaryPrimary", "Primary Kpi pair", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + } + + if (doprocessRecKinematics) { + hMC.add("Kinematics/h1RecCent", "centrality reconstructed", kTH1F, {centralityAxis}); + + hMC.add("Kinematics/hPDGMotherKstar", "Mother PDG of Ka and Pi from K*0", kTH2F, {{100000, -50000.0, 50000.0}, invmassAxis}); + hMC.add("Kinematics/hOpenAngleKstar", "Opening angle vs M(K#pi);Opening angle (rad);M(K#pi) (GeV/c^{2})", kTH2F, {{180, 0., o2::constants::math::PI}, invmassAxis}); + hMC.add("Kinematics/hDeltaPhiKstar", "#Delta#phi vs M(K#pi);#Delta#phi (rad);M(K#pi) (GeV/c^{2})", kTH2F, {{180, -o2::constants::math::PI, o2::constants::math::PI}, invmassAxis}); + hMC.add("Kinematics/hDeltaEtaKstar", "#Delta#eta vs M(K#pi);#Delta#eta;M(K#pi) (GeV/c^{2})", kTH2F, {{200, -2.0, 2.0}, invmassAxis}); + hMC.add("Kinematics/hDeltaRKstar", "#DeltaR vs M(K#pi);#DeltaR;M(K#pi) (GeV/c^{2})", kTH2F, {{200, 0.0, 5.0}, invmassAxis}); + hMC.add("Kinematics/hKaonPtKstar", "Kaon p_{T} vs M(K#pi);p_{T}^{K} (GeV/c);M(K#pi) (GeV/c^{2})", kTH2F, {ptAxis, invmassAxis}); + hMC.add("Kinematics/hPionPtKstar", "Pion p_{T} vs M(K#pi);p_{T}^{#pi} (GeV/c);M(K#pi) (GeV/c^{2})", kTH2F, {ptAxis, invmassAxis}); + + hMC.add("Kinematics/hPtCentMassKstar", "p_{T} vs Centrality vs M(K#pi);p_{T} (GeV/c);Centrality (%);M(K#pi) (GeV/c^{2})", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + + hMC.add("Kinematics/hOpenAngleOther", "Opening angle vs M(K#pi) (non-K*);Opening angle (rad);M(K#pi) (GeV/c^{2})", kTH2F, {{180, 0., o2::constants::math::PI}, invmassAxis}); + hMC.add("Kinematics/hDeltaPhiOther", "#Delta#phi vs M(K#pi) (non-K*);#Delta#phi (rad);M(K#pi) (GeV/c^{2})", kTH2F, {{180, -o2::constants::math::PI, o2::constants::math::PI}, invmassAxis}); + hMC.add("Kinematics/hDeltaEtaOther", "#Delta#eta vs M(K#pi) (non-K*);#Delta#eta;M(K#pi) (GeV/c^{2})", kTH2F, {{200, -2.0, 2.0}, invmassAxis}); + hMC.add("Kinematics/hDeltaROther", "#DeltaR vs M(K#pi) (non-K*);#DeltaR;M(K#pi) (GeV/c^{2})", kTH2F, {{200, 0.0, 5.0}, invmassAxis}); + hMC.add("Kinematics/hKaonPtOther", "Kaon p_{T} vs M(K#pi) (non-K*);p_{T}^{K} (GeV/c);M(K#pi) (GeV/c^{2})", kTH2F, {ptAxis, invmassAxis}); + hMC.add("Kinematics/hPionPtOther", "Pion p_{T} vs M(K#pi) (non-K*);p_{T}^{#pi} (GeV/c);M(K#pi) (GeV/c^{2})", kTH2F, {ptAxis, invmassAxis}); + hMC.add("Kinematics/hPtCentMassOther", "p_{T} vs Centrality vs M(K#pi) (non-K*);p_{T} (GeV/c);Centrality (%);M(K#pi) (GeV/c^{2})", kTH3F, {ptAxis, centralityAxis, invmassAxis}); + hMC.add("Kinematics/hOtherMotherPDG", "Common mother PDG of non-K* pairs;PDG Code;M(K#pi) (GeV/c^{2})", kTH2F, {{100000, -50000.0, 50000.0}, invmassAxis}); } if (doprocessMCCheck) { @@ -449,93 +541,117 @@ struct Kstar892LightIon { } } - double massPi = o2::constants::physics::MassPiPlus; - double massKa = o2::constants::physics::MassKPlus; - template bool selectionEvent(const Coll& collision, bool fillHist = false) // default to false { - if (fillHist) + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 0); + } - if (std::abs(collision.posZ()) > selectionConfig.cfgVrtxZCut) + if (std::abs(collision.posZ()) > selectionConfig.cfgVrtxZCut) { return false; - if (fillHist) + } + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 1); + } - if (selectionConfig.isApplysel8 && !collision.sel8()) + if (selectionConfig.isApplysel8 && !collision.sel8()) { return false; - if (fillHist) + } + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 2); + } - if (selectionConfig.isNoTimeFrameBorder && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) + if (selectionConfig.isNoTimeFrameBorder && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { return false; - if (fillHist) + } + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 3); + } - if (selectionConfig.isNoITSROFrameBorder && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) + if (selectionConfig.isNoITSROFrameBorder && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { return false; - if (fillHist) + } + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 4); + } - if (selectionConfig.isTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) + if (selectionConfig.isTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { return false; - if (fillHist) + } + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 5); + } - if (selectionConfig.isNoSameBunchPileup && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup))) + if (selectionConfig.isNoSameBunchPileup && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup))) { return false; - if (fillHist) + } + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 6); + } - if (selectionConfig.isGoodITSLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) + if (selectionConfig.isGoodITSLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { return false; - if (fillHist) + } + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 7); + } - if (selectionConfig.isNoCollInTimeRangeStandard && (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard))) + if (selectionConfig.isNoCollInTimeRangeStandard && (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard))) { return false; - if (fillHist) + } + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 8); + } - if (selectionConfig.isApplyOccCut && (std::abs(collision.trackOccupancyInTimeRange()) > selectionConfig.cfgOccCut)) + if (selectionConfig.isApplyOccCut && (std::abs(collision.trackOccupancyInTimeRange()) > selectionConfig.cfgOccCut)) { return false; - if (fillHist) + } + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 9); + } - if (rctCut.requireRCTFlagChecker && !rctChecker(collision)) + if (rctCut.requireRCTFlagChecker && !rctChecker(collision)) { return false; - if (fillHist) + } + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 10); + } - if (selectionConfig.isGoodZvtxFT0vsPV && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) + if (selectionConfig.isGoodZvtxFT0vsPV && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { return false; - if (fillHist) + } + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 11); + } if (selectionConfig.isVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { return false; } - if (fillHist) + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 12); + } if (selectionConfig.isVertexTOFMatched && !collision.selection_bit(aod::evsel::kIsVertexTOFmatched)) { return false; } - if (fillHist) + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 13); + } if (selectionConfig.isApplyINELgt0 && !collision.isInelGt0()) { return false; } - if (fillHist) + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 14); + } if (selectionConfig.isApplyhasFT0 && !collision.has_foundFT0()) { return false; } - if (fillHist) + if (fillHist) { hEventSelection.fill(HIST("hEventCut"), 15); + } return true; } @@ -544,59 +660,81 @@ struct Kstar892LightIon { bool selectionTrack(const T& candidate) { if (selectionConfig.isGlobalTracks) { - if (!candidate.isGlobalTrackWoDCA()) + if (!candidate.isGlobalTrackWoDCA()) { return false; - if (std::abs(candidate.pt()) < selectionConfig.cfgCutPT) + } + if (std::abs(candidate.pt()) < selectionConfig.cfgCutPT) { return false; + } - if (std::abs(candidate.eta()) > selectionConfig.cfgCutEta) + if (std::abs(candidate.eta()) > selectionConfig.cfgCutEta) { return false; + } if (!selectionConfig.isApplyPtDepDCAxyCut) { - if (std::abs(candidate.dcaXY()) > selectionConfig.cfgCutDCAxy) + if (std::abs(candidate.dcaXY()) > selectionConfig.cfgCutDCAxy) { return false; + } } else { - if (std::abs(candidate.dcaXY()) > (0.0105 + 0.035 / std::pow(candidate.pt(), 1.1))) + if (std::abs(candidate.dcaXY()) > (0.0105 + 0.035 / std::pow(candidate.pt(), 1.1))) { return false; + } } - if (selectionConfig.isGoldenChi2 && !candidate.passedGoldenChi2()) + if (selectionConfig.isGoldenChi2 && !candidate.passedGoldenChi2()) { return false; - if (std::abs(candidate.dcaZ()) > selectionConfig.cfgCutDCAz) - return false; - if (candidate.itsNCls() < selectionConfig.cfgITScluster) + } + if (std::abs(candidate.dcaZ()) > selectionConfig.cfgCutDCAz) { return false; - if (candidate.tpcNClsFound() < selectionConfig.cfgTPCcluster) + } + if (candidate.itsNCls() < selectionConfig.cfgITScluster) { return false; - if (candidate.itsChi2NCl() >= selectionConfig.cfgITSChi2NCl) + } + if (candidate.tpcNClsFound() < selectionConfig.cfgTPCcluster) { return false; - if (candidate.tpcChi2NCl() >= selectionConfig.cfgTPCChi2NClMax || candidate.tpcChi2NCl() < selectionConfig.cfgTPCChi2NClMin) + } + if (candidate.itsChi2NCl() >= selectionConfig.cfgITSChi2NCl) { return false; - if (selectionConfig.isPVContributor && !candidate.isPVContributor()) + } + if (candidate.tpcChi2NCl() >= selectionConfig.cfgTPCChi2NClMax || candidate.tpcChi2NCl() < selectionConfig.cfgTPCChi2NClMin) { return false; - if (selectionConfig.isUseITSTPCRefit && (!(o2::aod::track::ITSrefit) || !(o2::aod::track::TPCrefit))) + } + if (selectionConfig.isPVContributor && !candidate.isPVContributor()) { return false; - } else if (!selectionConfig.isGlobalTracks) { - if (std::abs(candidate.pt()) < selectionConfig.cfgCutPT) + } + // if (selectionConfig.isUseITSTPCRefit && (!(o2::aod::track::ITSrefit) || !(o2::aod::track::TPCrefit))) + // return false; + } else { + if (std::abs(candidate.pt()) < selectionConfig.cfgCutPT) { return false; + } // if (std::abs(candidate.eta()) > selectionConfig.cfgCutEta || std::abs(candidate.eta()) < selectionConfig.cfgCutEtaMin) - if (std::abs(candidate.eta()) > selectionConfig.cfgCutEta) + if (std::abs(candidate.eta()) > selectionConfig.cfgCutEta) { return false; + } // if (std::abs(candidate.dcaXY()) > selectionConfig.cfgCutDCAxy || std::abs(candidate.dcaXY()) < selectionConfig.cfgCutDCAxyMin) - if (std::abs(candidate.dcaXY()) > selectionConfig.cfgCutDCAxy) + if (std::abs(candidate.dcaXY()) > selectionConfig.cfgCutDCAxy) { return false; - if (std::abs(candidate.dcaZ()) > selectionConfig.cfgCutDCAz) + } + if (std::abs(candidate.dcaZ()) > selectionConfig.cfgCutDCAz) { return false; - if (candidate.itsNCls() < selectionConfig.cfgITScluster) + } + if (candidate.itsNCls() < selectionConfig.cfgITScluster) { return false; - if (candidate.tpcNClsFound() < selectionConfig.cfgTPCcluster) + } + if (candidate.tpcNClsFound() < selectionConfig.cfgTPCcluster) { return false; - if (candidate.itsChi2NCl() >= selectionConfig.cfgITSChi2NCl) + } + if (candidate.itsChi2NCl() >= selectionConfig.cfgITSChi2NCl) { return false; - if (candidate.tpcChi2NCl() >= selectionConfig.cfgTPCChi2NClMax || candidate.tpcChi2NCl() < selectionConfig.cfgTPCChi2NClMin) + } + if (candidate.tpcChi2NCl() >= selectionConfig.cfgTPCChi2NClMax || candidate.tpcChi2NCl() < selectionConfig.cfgTPCChi2NClMin) { return false; - if (selectionConfig.isPVContributor && !candidate.isPVContributor()) + } + if (selectionConfig.isPVContributor && !candidate.isPVContributor()) { return false; - if (selectionConfig.isPrimaryTrack && !candidate.isPrimaryTrack()) + } + if (selectionConfig.isPrimaryTrack && !candidate.isPrimaryTrack()) { return false; + } } return true; @@ -606,22 +744,18 @@ struct Kstar892LightIon { template bool selectionPair(const T1& candidate1, const T2& candidate2) { - double pt1, pt2, pz1, pz2, p1, p2, angle; - pt1 = candidate1.pt(); - pt2 = candidate2.pt(); - pz1 = candidate1.pz(); - pz2 = candidate2.pz(); - p1 = candidate1.p(); - p2 = candidate2.p(); - angle = std::acos((pt1 * pt2 + pz1 * pz2) / (p1 * p2)); - if (selectionConfig.isApplyDeepAngle && angle < selectionConfig.cfgDeepAngle) { - return false; - } - return true; + double pt1 = candidate1.pt(); + double pt2 = candidate2.pt(); + double pz1 = candidate1.pz(); + double pz2 = candidate2.pz(); + double p1 = candidate1.p(); + double p2 = candidate2.p(); + double angle = std::acos((pt1 * pt2 + pz1 * pz2) / (p1 * p2)); + return !selectionConfig.isApplyDeepAngle || angle >= selectionConfig.cfgDeepAngle; } template - bool isFakeTrack(const T& track, int PID) + bool isFakeTrack(const T& track, PIDParticle PID) { const auto pglobal = track.p(); const auto ptpc = track.tpcInnerParam(); @@ -638,237 +772,309 @@ struct Kstar892LightIon { } template - bool selectionPID(const T& candidate, int PID) + float tpcSigma(const T& c, PIDParticle pid) { - if (PID == PIDParticle::kPion) { - if (selectionConfig.onlyTOF) { - if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < selectionConfig.nsigmaCutTOFPi && candidate.beta() > selectionConfig.cfgTOFBetaCut) { - return true; - } - } else if (selectionConfig.onlyTOFHIT) { - if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < selectionConfig.nsigmaCutTOFPi && candidate.beta() > selectionConfig.cfgTOFBetaCut) { - return true; - } - if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi) { - return true; - } - } else if (selectionConfig.onlyTOFVeto) { - if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < selectionConfig.nsigmaCutTOFPi && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi) { - return true; - } - } else if (selectionConfig.onlyTPC) { - if (std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi) { - return true; - } - } else { - if (candidate.hasTOF() && (candidate.tofNSigmaPi() * candidate.tofNSigmaPi() + candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi()) < (selectionConfig.nsigmaCutCombinedPi * selectionConfig.nsigmaCutCombinedPi) && candidate.beta() > selectionConfig.cfgTOFBetaCut) { - return true; - } - if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi) { - return true; - } - } - } else if (PID == PIDParticle::kKaon) { - if (selectionConfig.onlyTOF) { - if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < selectionConfig.nsigmaCutTOFKa && candidate.beta() > selectionConfig.cfgTOFBetaCut) { - return true; - } - } else if (selectionConfig.onlyTOFHIT) { - if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < selectionConfig.nsigmaCutTOFKa && candidate.beta() > selectionConfig.cfgTOFBetaCut) { - return true; - } - if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa) { - return true; - } - } else if (selectionConfig.onlyTOFVeto) { - if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < selectionConfig.nsigmaCutTOFKa && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa) { - return true; - } - } else if (selectionConfig.onlyTPC) { - if (std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa) { - return true; - } - } else { - if (candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (selectionConfig.nsigmaCutCombinedKa * selectionConfig.nsigmaCutCombinedKa) && candidate.beta() > selectionConfig.cfgTOFBetaCut) { - return true; - } - if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa) { - return true; - } - } - } - return false; + return pid == PIDParticle::kPion ? c.tpcNSigmaPi() : c.tpcNSigmaKa(); } template - bool selectionPIDpTdep(const T& candidate, int PID) + float tofSigma(const T& c, PIDParticle pid) { - if (PID == PIDParticle::kPion) { - if (candidate.pt() < selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi) { - return true; - } - if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi && candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < selectionConfig.nsigmaCutTOFPi && candidate.beta() > selectionConfig.cfgTOFBetaCut) { - return true; - } - if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi && !candidate.hasTOF()) { - return true; - } - } else if (PID == PIDParticle::kKaon) { - if (candidate.pt() < selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa) { - return true; - } - if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa && candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < selectionConfig.nsigmaCutTOFKa && candidate.beta() > selectionConfig.cfgTOFBetaCut) { - return true; - } - if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa && !candidate.hasTOF()) { - return true; - } + return pid == PIDParticle::kPion ? c.tofNSigmaPi() : c.tofNSigmaKa(); + } + + template + float combinedNSigma2(const T& c, PIDParticle pid) + { + const float tpc = tpcSigma(c, pid); + const float tof = tofSigma(c, pid); + + return tpc * tpc + tof * tof; + } + + float tpcCut(PIDParticle pid) + { + return pid == PIDParticle::kPion ? selectionConfig.nsigmaCutTPCPi : selectionConfig.nsigmaCutTPCKa; + } + + float tofCut(PIDParticle pid) + { + return pid == PIDParticle::kPion ? selectionConfig.nsigmaCutTOFPi : selectionConfig.nsigmaCutTOFKa; + } + + float combinedCut(PIDParticle pid) + { + return pid == PIDParticle::kPion ? selectionConfig.nsigmaCutCombinedPi : selectionConfig.nsigmaCutCombinedKa; + } + + template + bool passTPC(const T& c, PIDParticle pid) + { + return std::abs(tpcSigma(c, pid)) < tpcCut(pid); + } + + template + bool passTOF(const T& c, PIDParticle pid) + { + return c.hasTOF() && std::abs(tofSigma(c, pid)) < tofCut(pid) && c.beta() > selectionConfig.cfgTOFBetaCut; + } + + template + bool passCombined(const T& c, PIDParticle pid) + { + if (!c.hasTOF() || c.beta() <= selectionConfig.cfgTOFBetaCut) { + return false; } - return false; + + const float cut = combinedCut(pid); + return combinedNSigma2(c, pid) < cut * cut; } template - bool selectionPIDpTdepTOF(const T& candidate, int PID) + bool selectionPID(const T& candidate, PIDParticle pid) { - if (PID == PIDParticle::kPion) { - if (candidate.pt() < pionPIDpTLow || candidate.pt() > pionPIDpTHigh) { - if (candidate.pt() < selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi) { - return true; - } - if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi && candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < selectionConfig.nsigmaCutTOFPi) { - return true; - } - if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi && !candidate.hasTOF()) { - return true; - } - } else { - if (candidate.hasTOF() && (candidate.tofNSigmaPi() * candidate.tofNSigmaPi() + candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi()) < (selectionConfig.nsigmaCutCombinedPi * selectionConfig.nsigmaCutCombinedPi)) { - return true; + const auto strategy = static_cast(selectionConfig.pidStrategy.value); + const auto mode = static_cast(selectionConfig.pidMode.value); + + switch (strategy) { + case PIDStrategy::Standard: { + switch (mode) { + case PIDMode::TPC: // Apply only TPC cut + return passTPC(candidate, pid); + + case PIDMode::TOF: // Apply only TOF cut + return passTOF(candidate, pid); + + case PIDMode::TOFVeto: // Require TOF hit; apply both TPC and TOF cuts. Tracks without TOF are rejected. + return passTPC(candidate, pid) && passTOF(candidate, pid); + + case PIDMode::TOFHIT: // Apply only TOF cut that has tof hits, apply TPC cut for the rest + if (candidate.hasTOF()) { + return passTOF(candidate, pid); + } + + return passTPC(candidate, pid); + + case PIDMode::Combined: // Apply combined cut if TOF is available, apply TPC cut for the rest + if (candidate.hasTOF()) { + return passCombined(candidate, pid); + } + + return passTPC(candidate, pid); + + default: + LOGF(fatal, "Unknown PID mode!"); + return false; } } - } else if (PID == PIDParticle::kKaon) { - if (candidate.pt() < kaonPIDpTLow || candidate.pt() > kaonPIDpTHigh) { - if (candidate.pt() < selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa) { - return true; - } - if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa && candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < selectionConfig.nsigmaCutTOFKa) { - return true; + + case PIDStrategy::PtDependent: // Apply TPC and TOF cut above lowPtCut, apply TPC cut for the rest + { + if (candidate.hasTOF() && candidate.pt() >= selectionConfig.lowPtCutPid) { + return passTPC(candidate, pid) && passTOF(candidate, pid); } - if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa && !candidate.hasTOF()) { - return true; + + return passTPC(candidate, pid); + } + + case PIDStrategy::PtDependentTOF: // Apply combined cut (requires TOF) in specific pT window, apply TPC+TOF cut for tracks with TOF hit above lowPtCut, apply TPC cut for the rest. + { + const bool inPtWindow = (pid == PIDParticle::kPion) ? (candidate.pt() >= pionPidPtLow && candidate.pt() <= pionPidPtHigh) : (candidate.pt() >= kaonPidPtLow && candidate.pt() <= kaonPidPtHigh); + + if (inPtWindow) { + return passCombined(candidate, pid); } - } else { - if (candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (selectionConfig.nsigmaCutCombinedKa * selectionConfig.nsigmaCutCombinedKa)) { - return true; + + if (candidate.hasTOF() && candidate.pt() >= selectionConfig.lowPtCutPid) { + return passTPC(candidate, pid) && passTOF(candidate, pid); } + + return passTPC(candidate, pid); } - } - return false; - } - template - bool selectionMID(const T& candidate, int PID) - { - if (PID == PIDParticle::kPion) { - if (selectionConfig.onlyTOF) { - if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < selectionConfig.nsigmaCutTPCMID) { - return true; - } - } else if (selectionConfig.onlyTPC) { - if (std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCMID) { - return true; + /* case PIDStrategy::ThreePtDependent: // Apply pT-dependent TPC and TOF cuts using three pT regions + { + const int region = (candidate.pt() < selectionConfig.lowPtCutPid) ? 0 : (candidate.pt() < selectionConfig.highPtCutPid) ? 1 + : 2; + + const float regionTPCCut = (pid == PIDParticle::kPion) ? TPCPiCuts3Pt[region] : TPCKaCuts3Pt[region]; + + const float regionTOFCut = (pid == PIDParticle::kPion) ? TOFPiCuts3Pt[region] : TOFKaCuts3Pt[region]; + + if (candidate.hasTOF()) { + return (std::abs(tpcSigma(candidate, pid)) < regionTPCCut) && (std::abs(tofSigma(candidate, pid)) < regionTOFCut) && (candidate.beta() > selectionConfig.cfgTOFBetaCut); + } + + return (std::abs(tpcSigma(candidate, pid)) < regionTPCCut); + } */ + + case PIDStrategy::ThreePtDependent: // Apply region-dependent PID cuts using one PID cut per pT region. In the middle pT region TOF is mandatory. + { + const float pidCut = (candidate.pt() < selectionConfig.lowPtCutPid) ? selectionConfig.lowPtPid : (candidate.pt() < selectionConfig.highPtCutPid) ? selectionConfig.midPtPid + : selectionConfig.highPtPid; + + // Low-pT region + if (candidate.pt() < selectionConfig.lowPtCutPid) { + if (candidate.hasTOF()) { + if (!candidate.hasTOF() || candidate.beta() <= selectionConfig.cfgTOFBetaCut) { + return false; + } + + return combinedNSigma2(candidate, pid) < pidCut * pidCut; + } + + return std::abs(tpcSigma(candidate, pid)) < pidCut; } - } else { - if (candidate.hasTOF() && (candidate.tofNSigmaPi() * candidate.tofNSigmaPi() + candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi()) < (selectionConfig.nsigmaCutCombinedMID * selectionConfig.nsigmaCutCombinedMID)) { - return true; + + // Mid-pT region (TOF mandatory) + if (candidate.pt() < selectionConfig.highPtCutPid) { + if (!candidate.hasTOF() || candidate.beta() <= selectionConfig.cfgTOFBetaCut) { + return false; + } + + return combinedNSigma2(candidate, pid) < pidCut * pidCut; } - if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCMID) { - return true; + + // High-pT region + if (candidate.hasTOF()) { + if (!candidate.hasTOF() || candidate.beta() <= selectionConfig.cfgTOFBetaCut) { + return false; + } + + return combinedNSigma2(candidate, pid) < pidCut * pidCut; } + + return std::abs(tpcSigma(candidate, pid)) < pidCut; } - } else if (PID == PIDParticle::kKaon) { - if (selectionConfig.onlyTOF) { - if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < selectionConfig.nsigmaCutTPCMID) { - return true; - } - } else if (selectionConfig.onlyTPC) { - if (std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCMID) { - return true; + + case PIDStrategy::PIDCompare: // Apply independent TPC/TOF cuts below lowPtCutPid, within lowPtCutPid and highPtCutPid, require TOF and accept the track only if its combined nsigma is smaller than that of the alternate PID hypothesis and above highPtCutPid if TOF is available, accept if the track passes combined cut and if TOF is not available, check if it passes TPC cut + { + if (candidate.pt() < selectionConfig.lowPtCutPid) { + if (candidate.hasTOF()) { + return passTPC(candidate, pid) && passTOF(candidate, pid); + } + return passTPC(candidate, pid); } - } else { - if (candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (selectionConfig.nsigmaCutCombinedMID * selectionConfig.nsigmaCutCombinedMID)) { - return true; + + if (candidate.pt() < selectionConfig.highPtCutPid) { + if (!candidate.hasTOF() || candidate.beta() <= selectionConfig.cfgTOFBetaCut) { + return false; + } + + const float sigmaComb2 = combinedNSigma2(candidate, pid); + + const float cut = combinedCut(pid); + if (sigmaComb2 >= cut * cut) { + return false; + } + + const PIDParticle otherPID = (pid == PIDParticle::kPion) ? PIDParticle::kKaon : PIDParticle::kPion; + + return sigmaComb2 < combinedNSigma2(candidate, otherPID); } - if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCMID) { - return true; + + if (candidate.hasTOF()) { + return passCombined(candidate, pid); } + + return passTPC(candidate, pid); } + + default: + LOGF(fatal, "Unknown PID strategy!"); } return false; } template - bool selectionMIDpTdep(const T& candidate, int PID) + bool isMisidentified(const T& candidate, PIDParticle pid) { - if (PID == PIDParticle::kPion) { - if (candidate.pt() >= selectionConfig.pionMIDpTLow && candidate.pt() < selectionConfig.pionMIDpTHigh && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCMID) { - return true; + const auto strategy = static_cast(selectionConfig.midStrategy.value); + const PIDParticle misPID = (pid == PIDParticle::kPion) ? PIDParticle::kKaon : PIDParticle::kPion; + + switch (strategy) { + case MIDStrategy::Disabled: + return false; + + case MIDStrategy::Standard: // Reject if track also satisfies TPC cut for the opposite hypothesis + return std::abs(tpcSigma(candidate, misPID)) < selectionConfig.nsigmaCutTPCMID; + + case MIDStrategy::PtDependent: // Reject if track is in MID pT window, has no TOF, and passes opposite TPC cut + { + const float lowPt = (pid == PIDParticle::kPion) ? selectionConfig.pionMidPtLow : selectionConfig.kaonMidPtLow; + const float highPt = (pid == PIDParticle::kPion) ? selectionConfig.pionMidPtHigh : selectionConfig.kaonMidPtHigh; + + return candidate.pt() >= lowPt && candidate.pt() < highPt && !candidate.hasTOF() && std::abs(tpcSigma(candidate, misPID)) < selectionConfig.nsigmaCutTPCMID; } - } else if (PID == PIDParticle::kKaon) { - if (candidate.pt() >= selectionConfig.kaonMIDpTLow && candidate.pt() < selectionConfig.kaonMIDpTHigh && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCMID) { - return true; + + case MIDStrategy::PtDependentCompare: // Reject if track is in MID pT window, has no TOF, and looks more like the opposite hypothesis than the signal hypothesis + { + const float lowPt = (pid == PIDParticle::kPion) ? selectionConfig.pionMidPtLow : selectionConfig.kaonMidPtLow; + const float highPt = (pid == PIDParticle::kPion) ? selectionConfig.pionMidPtHigh : selectionConfig.kaonMidPtHigh; + + return candidate.pt() >= lowPt && candidate.pt() < highPt && !candidate.hasTOF() && std::abs(tpcSigma(candidate, misPID)) < std::abs(tpcSigma(candidate, pid)); } + + default: + LOGF(fatal, "Unknown MID strategy!"); } return false; } - template - bool selectionMIDPtDepComp(const T& candidate, int PID) + template + std::vector> getAncestors(const MCParticle& particle) { - if (PID == PIDParticle::kPion) { - if (candidate.pt() >= selectionConfig.pionMIDpTLow && candidate.pt() < selectionConfig.pionMIDpTHigh && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < std::abs(candidate.tpcNSigmaKa())) { - return true; - } - } else if (PID == PIDParticle::kKaon) { - if (candidate.pt() >= selectionConfig.kaonMIDpTLow && candidate.pt() < selectionConfig.kaonMIDpTHigh && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < std::abs(candidate.tpcNSigmaPi())) { - return true; + std::vector> ancestors; + + std::function collect = [&](const auto& p) { + for (const auto& mother : p.template mothers_as()) { + + ancestors.emplace_back(mother.globalIndex(), std::abs(mother.pdgCode())); + collect(mother); } - } - return false; + }; + + collect(particle); + + return ancestors; } //*********Varibles declaration*************** - float centrality{-1.0}, theta2; - ROOT::Math::PxPyPzMVector daughter1, daughter2, daughterRot, mother, motherRot; + ROOT::Math::PxPyPzMVector daughter1, daughter2, daughterRot, genDaughter1, genDaughter2, mother, motherRot, genMother; + + float centrality = -1.0f, theta2 = 0.0f; + double genMass = 0.0, recMass = 0.0, recPt = 0.0, genPt = 0.0; + bool isMix = false; template - void fillInvMass(const T1& daughter1, const T1& daughter2, const T1& mother, float centrality, bool isMix, const T2& track1, const T2& track2) + void fillInvMass(const T1& argDaughter1, const T1& argDaughter2, const T1& argMother, float argCentrality, bool argIsMix, const T2& track1, const T2& track2) { if (track1.sign() * track2.sign() < 0) { - if (!isMix) { - if (mother.Rapidity() > selectionConfig.motherRapidityMin && mother.Rapidity() < selectionConfig.motherRapidityMax) { - hInvMass.fill(HIST("h3KstarInvMassUnlikeSign"), centrality, mother.Pt(), mother.M()); + if (!argIsMix) { + if (argMother.Rapidity() > selectionConfig.motherRapidityMin && argMother.Rapidity() < selectionConfig.motherRapidityMax) { + hInvMass.fill(HIST("h3KstarInvMassUnlikeSign"), argCentrality, argMother.Pt(), argMother.M()); } for (int i = 0; i < cRotations; i++) { theta2 = rn->Uniform(o2::constants::math::PI - o2::constants::math::PI / rotationalCut, o2::constants::math::PI + o2::constants::math::PI / rotationalCut); - daughterRot = ROOT::Math::PxPyPzMVector(daughter1.Px() * std::cos(theta2) - daughter1.Py() * std::sin(theta2), daughter1.Px() * std::sin(theta2) + daughter1.Py() * std::cos(theta2), daughter1.Pz(), daughter1.M()); - motherRot = daughterRot + daughter2; + daughterRot = ROOT::Math::PxPyPzMVector(argDaughter1.Px() * std::cos(theta2) - argDaughter1.Py() * std::sin(theta2), argDaughter1.Px() * std::sin(theta2) + argDaughter1.Py() * std::cos(theta2), argDaughter1.Pz(), argDaughter1.M()); + motherRot = daughterRot + argDaughter2; - if (calcRotational && (motherRot.Rapidity() > selectionConfig.motherRapidityMin && motherRot.Rapidity() < selectionConfig.motherRapidityMax)) - hInvMass.fill(HIST("h3KstarInvMassRotated"), centrality, motherRot.Pt(), motherRot.M()); + if (calcRotational && (motherRot.Rapidity() > selectionConfig.motherRapidityMin && motherRot.Rapidity() < selectionConfig.motherRapidityMax)) { + hInvMass.fill(HIST("h3KstarInvMassRotated"), argCentrality, motherRot.Pt(), motherRot.M()); + } } - } else if (isMix && (mother.Rapidity() > selectionConfig.motherRapidityMin && mother.Rapidity() < selectionConfig.motherRapidityMax)) { - hInvMass.fill(HIST("h3KstarInvMassMixed"), centrality, mother.Pt(), mother.M()); + } else if (argMother.Rapidity() > selectionConfig.motherRapidityMin && argMother.Rapidity() < selectionConfig.motherRapidityMax) { + hInvMass.fill(HIST("h3KstarInvMassMixed"), argCentrality, argMother.Pt(), argMother.M()); } } else { - if (!isMix) { - if (calcLikeSign && (mother.Rapidity() > selectionConfig.motherRapidityMin && mother.Rapidity() < selectionConfig.motherRapidityMax)) { + if (!argIsMix) { + if (calcLikeSign && (argMother.Rapidity() > selectionConfig.motherRapidityMin && argMother.Rapidity() < selectionConfig.motherRapidityMax)) { if (track1.sign() > 0 && track2.sign() > 0) { - hInvMass.fill(HIST("h3KstarInvMasslikeSignPP"), centrality, mother.Pt(), mother.M()); + hInvMass.fill(HIST("h3KstarInvMasslikeSignPP"), argCentrality, argMother.Pt(), argMother.M()); } else if (track1.sign() < 0 && track2.sign() < 0) { - hInvMass.fill(HIST("h3KstarInvMasslikeSignMM"), centrality, mother.Pt(), mother.M()); + hInvMass.fill(HIST("h3KstarInvMasslikeSignMM"), argCentrality, argMother.Pt(), argMother.M()); } } } @@ -907,16 +1113,14 @@ struct Kstar892LightIon { centrality = -1; - if (selectCentEstimator == kFT0M) { - centrality = collision.centFT0M(); - } else if (selectCentEstimator == kFT0A) { + if (selectCentEstimator == kFT0A) { centrality = collision.centFT0A(); } else if (selectCentEstimator == kFT0C) { centrality = collision.centFT0C(); } else if (selectCentEstimator == kFV0A) { centrality = collision.centFV0A(); } else { - centrality = collision.centFT0M(); // default + centrality = collision.centFT0M(); // default includes kFT0M } /* else if (selectCentEstimator == 4) { @@ -940,8 +1144,9 @@ struct Kstar892LightIon { continue; } - if (track1.globalIndex() == track2.globalIndex()) + if (track1.globalIndex() == track2.globalIndex()) { continue; + } if (!selectionPair(track1, track2)) { continue; @@ -980,32 +1185,24 @@ struct Kstar892LightIon { } // since we are using combinations full index policy, so repeated pairs are allowed, so we can check one with Kaon and other with pion - if ((!selectionConfig.isApplypTdepPID && !selectionConfig.isApplypTdepPIDwTOF) && !selectionPID(track1, 1)) // Track 1 is checked with Kaon - continue; - if ((!selectionConfig.isApplypTdepPID && !selectionConfig.isApplypTdepPIDwTOF) && !selectionPID(track2, 0)) // Track 2 is checked with Pion - continue; - - if (selectionConfig.isApplypTdepPID && !selectionPIDpTdep(track1, 1)) // Track 1 is checked with Kaon - continue; - if (selectionConfig.isApplypTdepPID && !selectionPIDpTdep(track2, 0)) // Track 2 is checked with Pion - continue; - - if (selectionConfig.isApplypTdepPIDwTOF && !selectionPIDpTdepTOF(track1, 1)) // Track 1 is checked with Kaon - continue; - if (selectionConfig.isApplypTdepPIDwTOF && !selectionPIDpTdepTOF(track2, 0)) // Track 2 is checked with Pion + if (!selectionPID(track1, PIDParticle::kKaon)) { // Track 1 is checked with Kaon continue; + } - if (selectionConfig.isApplyMID && (selectionMID(track1, 0) || selectionMID(track2, 1))) + if (!selectionPID(track2, PIDParticle::kPion)) { // Track 2 is checked with Pion continue; + } - if (selectionConfig.isApplypTdepMID && (selectionMIDpTdep(track1, 0) || selectionMIDpTdep(track2, 1))) + if (isMisidentified(track1, PIDParticle::kKaon)) { continue; - - if (selectionConfig.isApplypTdepMIDComp && (selectionMIDPtDepComp(track1, 0) || selectionMIDPtDepComp(track2, 1))) + } + if (isMisidentified(track2, PIDParticle::kPion)) { continue; + } - if (selectionConfig.isApplyFakeTrack && (isFakeTrack(track1, 1) || isFakeTrack(track2, 0))) + if (selectionConfig.isApplyFakeTrack && (isFakeTrack(track1, PIDParticle::kKaon) || isFakeTrack(track2, PIDParticle::kPion))) { continue; + } if (cQAplots) { hOthers.fill(HIST("hEta_after"), track1.eta()); @@ -1091,16 +1288,14 @@ struct Kstar892LightIon { centrality = -1; - if (selectCentEstimator == kFT0M) { - centrality = collision.centFT0M(); - } else if (selectCentEstimator == kFT0A) { + if (selectCentEstimator == kFT0A) { centrality = collision.centFT0A(); } else if (selectCentEstimator == kFT0C) { centrality = collision.centFT0C(); } else if (selectCentEstimator == kFV0A) { centrality = collision.centFV0A(); } else { - centrality = collision.centFT0M(); // default + centrality = collision.centFT0M(); // default includes kFT0M } // Fill the event counter @@ -1110,20 +1305,24 @@ struct Kstar892LightIon { } for (const auto& [track1, track2] : combinations(CombinationsFullIndexPolicy(tracks, tracks))) { - if (!selectionTrack(track1) || !selectionTrack(track2)) + if (!selectionTrack(track1) || !selectionTrack(track2)) { continue; + } const auto mctrack1 = track1.mcParticle(); const auto mctrack2 = track2.mcParticle(); - if (!track1.has_mcParticle() || !track2.has_mcParticle()) + if (!track1.has_mcParticle() || !track2.has_mcParticle()) { continue; // skip if no MC particle associated + } - if (!mctrack1.isPhysicalPrimary() || !mctrack2.isPhysicalPrimary()) + if (!mctrack1.isPhysicalPrimary() || !mctrack2.isPhysicalPrimary()) { continue; + } - if (track1.globalIndex() == track2.globalIndex()) + if (track1.globalIndex() == track2.globalIndex()) { continue; + } if (cQAplots) { hOthers.fill(HIST("dE_by_dx_TPC"), track1.p(), track1.tpcSignal()); @@ -1158,26 +1357,24 @@ struct Kstar892LightIon { } // since we are using combinations full index policy, so repeated pairs are allowed, so we can check one with Kaon and other with pion - if ((!selectionConfig.isApplypTdepPID && !selectionConfig.isApplypTdepPIDwTOF) && (!selectionPID(track1, 1) || !selectionPID(track2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion - continue; - - if (selectionConfig.isApplypTdepPID && (!selectionPIDpTdep(track1, 1) || !selectionPIDpTdep(track2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion - continue; - - if (selectionConfig.isApplypTdepPIDwTOF && (!selectionPIDpTdepTOF(track1, 1) || !selectionPIDpTdepTOF(track2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion + if (!selectionPID(track1, PIDParticle::kKaon)) { // Track 1 is checked with Kaon continue; + } - if (selectionConfig.isApplyMID && (selectionMID(track1, 0) || selectionMID(track2, 1))) + if (!selectionPID(track2, PIDParticle::kPion)) { // Track 2 is checked with Pion continue; + } - if (selectionConfig.isApplypTdepMID && (selectionMIDpTdep(track1, 0) || selectionMIDpTdep(track2, 1))) + if (isMisidentified(track1, PIDParticle::kKaon)) { continue; - - if (selectionConfig.isApplypTdepMIDComp && (selectionMIDPtDepComp(track1, 0) || selectionMIDPtDepComp(track2, 1))) + } + if (isMisidentified(track2, PIDParticle::kPion)) { continue; + } - if (selectionConfig.isApplyFakeTrack && (isFakeTrack(track1, 1) || isFakeTrack(track2, 0))) + if (selectionConfig.isApplyFakeTrack && (isFakeTrack(track1, PIDParticle::kKaon) || isFakeTrack(track2, PIDParticle::kPion))) { continue; + } if (cQAplots) { hOthers.fill(HIST("hEta_after"), track1.eta()); @@ -1269,7 +1466,7 @@ struct Kstar892LightIon { void processME(EventCandidatesMix const&, TrackCandidates const&) { // Map estimator to pair and centrality accessor - auto runMixing = [&](auto& pair, auto centralityGetter) { + auto runMixing = [&](const auto& pair, auto centralityGetter) { for (const auto& [c1, tracks1, c2, tracks2] : pair) { if (!selectionEvent(c1, false) || !selectionEvent(c2, false)) { // don't fill event cut histogram @@ -1279,33 +1476,26 @@ struct Kstar892LightIon { centrality = centralityGetter(c1); for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - if (!selectionTrack(t1) || !selectionTrack(t2)) + if (!selectionTrack(t1) || !selectionTrack(t2)) { continue; + } if (!selectionPair(t1, t2)) { continue; } - if ((!selectionConfig.isApplypTdepPID && !selectionConfig.isApplypTdepPIDwTOF) && (!selectionPID(t1, 1) || !selectionPID(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion - continue; - - if (selectionConfig.isApplypTdepPID && (!selectionPIDpTdep(t1, 1) || !selectionPIDpTdep(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion - continue; - - if (selectionConfig.isApplypTdepPIDwTOF && (!selectionPIDpTdepTOF(t1, 1) || !selectionPIDpTdepTOF(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion - continue; - - if (selectionConfig.isApplyMID && (selectionMID(t1, 0) || selectionMID(t2, 1))) - continue; - - if (selectionConfig.isApplypTdepMID && (selectionMIDpTdep(t1, 0) || selectionMIDpTdep(t2, 1))) + // t1 checked as kaon and t2 checked as pion + if (!selectionPID(t1, PIDParticle::kKaon) || !selectionPID(t2, PIDParticle::kPion)) { continue; + } - if (selectionConfig.isApplypTdepMIDComp && (selectionMIDPtDepComp(t1, 0) || selectionMIDPtDepComp(t2, 1))) + if (isMisidentified(t1, PIDParticle::kKaon) || isMisidentified(t2, PIDParticle::kPion)) { continue; + } - if (selectionConfig.isApplyFakeTrack && (isFakeTrack(t1, 1) || isFakeTrack(t2, 0))) + if (selectionConfig.isApplyFakeTrack && (isFakeTrack(t1, PIDParticle::kKaon) || isFakeTrack(t2, PIDParticle::kPion))) { continue; + } daughter1 = ROOT::Math::PxPyPzMVector(t1.px(), t1.py(), t1.pz(), massKa); daughter2 = ROOT::Math::PxPyPzMVector(t2.px(), t2.py(), t2.pz(), massPi); @@ -1348,7 +1538,7 @@ struct Kstar892LightIon { void processMEMC(EventCandidatesMC const&, TrackCandidatesMC const&, aod::McParticles const&, aod::McCollisions const&) { - auto runMixing = [&](auto& pair, auto centralityGetter) { + auto runMixing = [&](const auto& pair, auto centralityGetter) { for (const auto& [c1, tracks1, c2, tracks2] : pair) { if (!selectionEvent(c1, false) || !selectionEvent(c2, false)) { // don't fill event cut histogram @@ -1362,33 +1552,26 @@ struct Kstar892LightIon { centrality = centralityGetter(c1); for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - if (!selectionTrack(t1) || !selectionTrack(t2)) + if (!selectionTrack(t1) || !selectionTrack(t2)) { continue; + } if (!selectionPair(t1, t2)) { continue; } - if ((!selectionConfig.isApplypTdepPID && !selectionConfig.isApplypTdepPIDwTOF) && (!selectionPID(t1, 1) || !selectionPID(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion - continue; - - if (selectionConfig.isApplypTdepPID && (!selectionPIDpTdep(t1, 1) || !selectionPIDpTdep(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion - continue; - - if (selectionConfig.isApplypTdepPIDwTOF && (!selectionPIDpTdepTOF(t1, 1) || !selectionPIDpTdepTOF(t2, 0))) // Track 1 is checked with Kaon, track 2 is checked with Pion - continue; - - if (selectionConfig.isApplyMID && (selectionMID(t1, 0) || selectionMID(t2, 1))) - continue; - - if (selectionConfig.isApplypTdepMID && (selectionMIDpTdep(t1, 0) || selectionMIDpTdep(t2, 1))) + // t1 checked as kaon and t2 checked as pion + if (!selectionPID(t1, PIDParticle::kKaon) || !selectionPID(t2, PIDParticle::kPion)) { continue; + } - if (selectionConfig.isApplypTdepMIDComp && (selectionMIDPtDepComp(t1, 0) || selectionMIDPtDepComp(t2, 1))) + if (isMisidentified(t1, PIDParticle::kKaon) || isMisidentified(t2, PIDParticle::kPion)) { continue; + } - if (selectionConfig.isApplyFakeTrack && (isFakeTrack(t1, 1) || isFakeTrack(t2, 0))) + if (selectionConfig.isApplyFakeTrack && (isFakeTrack(t1, PIDParticle::kKaon) || isFakeTrack(t2, PIDParticle::kPion))) { continue; + } if (!t1.has_mcParticle() || !t2.has_mcParticle()) { continue; // skip if no MC particle associated @@ -1431,7 +1614,7 @@ struct Kstar892LightIon { return; } - if (selectionConfig.isApplyMCGenTVX && !(mcCollision.multMCFT0C() > 0 && mcCollision.multMCFT0A() > 0)) { + if (selectionConfig.isApplyMCGenTVX && (mcCollision.multMCFT0C() <= 0 || mcCollision.multMCFT0A() <= 0)) { return; } @@ -1452,17 +1635,16 @@ struct Kstar892LightIon { } centrality = collision.centFT0M(); - if (selectCentEstimator == kFT0M) { - centrality = collision.centFT0M(); - } else if (selectCentEstimator == kFT0A) { + if (selectCentEstimator == kFT0A) { centrality = collision.centFT0A(); } else if (selectCentEstimator == kFT0C) { centrality = collision.centFT0C(); } else if (selectCentEstimator == kFV0A) { centrality = collision.centFV0A(); } else { - centrality = collision.centFT0M(); // default + centrality = collision.centFT0M(); // default includes kFT0M } + hMC.fill(HIST("Gen/h1GenCent"), centrality); int occupancy = collision.trackOccupancyInTimeRange(); @@ -1522,12 +1704,14 @@ struct Kstar892LightIon { } int pdgDau = kCurrentDaughter.pdgCode(); - int charge = (pdgDau > 0) - (pdgDau < 0); + int charge = static_cast(pdgDau > 0) - static_cast(pdgDau < 0); - if (charge > 0) + if (charge > 0) { hasPos = true; - if (charge < 0) + } + if (charge < 0) { hasNeg = true; + } if (std::abs(pdgDau) == PDG_t::kKPlus) { passkaon = true; @@ -1551,16 +1735,14 @@ struct Kstar892LightIon { centrality = collision.centFT0M(); - if (selectCentEstimator == kFT0M) { - centrality = collision.centFT0M(); - } else if (selectCentEstimator == kFT0A) { + if (selectCentEstimator == kFT0A) { centrality = collision.centFT0A(); } else if (selectCentEstimator == kFT0C) { centrality = collision.centFT0C(); } else if (selectCentEstimator == kFV0A) { centrality = collision.centFV0A(); } else { - centrality = collision.centFT0M(); // default + centrality = collision.centFT0M(); // default includes kFT0M } hMC.fill(HIST("Rec/hAllRecCollisions"), centrality); @@ -1586,8 +1768,9 @@ struct Kstar892LightIon { continue; } - if (track1.index() <= track2.index()) + if (track1.index() <= track2.index()) { continue; + } if (!selectionPair(track1, track2)) { continue; @@ -1646,7 +1829,7 @@ struct Kstar892LightIon { } } - if (!(track1PDG == PDG_t::kPiPlus && track2PDG == PDG_t::kKPlus) && !(track1PDG == PDG_t::kKPlus && track2PDG == PDG_t::kPiPlus)) { + if ((track1PDG != PDG_t::kPiPlus || track2PDG != PDG_t::kKPlus) && (track1PDG != PDG_t::kKPlus || track2PDG != PDG_t::kPiPlus)) { continue; } @@ -1673,25 +1856,17 @@ struct Kstar892LightIon { } if (track1PDG == PDG_t::kPiPlus) { - if ((!selectionConfig.isApplypTdepPID && !selectionConfig.isApplypTdepPIDwTOF) && !(selectionPID(track1, 0) && selectionPID(track2, 1))) { // pion and kaon - continue; - } else if (selectionConfig.isApplypTdepPID && !(selectionPIDpTdep(track1, 0) && selectionPIDpTdep(track2, 1))) { // pion and kaon - continue; - } else if (selectionConfig.isApplypTdepPIDwTOF && !(selectionPIDpTdepTOF(track1, 0) && selectionPIDpTdepTOF(track2, 1))) { + if (!selectionPID(track1, PIDParticle::kPion) || !selectionPID(track2, PIDParticle::kKaon)) { // Treat track1 as the pion candidate and track2 as the kaon candidate continue; } - if (selectionConfig.isApplyMID && (selectionMID(track1, 1) || selectionMID(track2, 0))) - continue; - - if (selectionConfig.isApplypTdepMID && (selectionMIDpTdep(track1, 1) || selectionMIDpTdep(track2, 0))) - continue; - - if (selectionConfig.isApplypTdepMIDComp && (selectionMIDPtDepComp(track1, 1) || selectionMIDPtDepComp(track2, 0))) + if (isMisidentified(track1, PIDParticle::kPion) || isMisidentified(track2, PIDParticle::kKaon)) { continue; + } - if (selectionConfig.isApplyFakeTrack && (isFakeTrack(track1, 0) || isFakeTrack(track2, 1))) + if (selectionConfig.isApplyFakeTrack && (isFakeTrack(track1, PIDParticle::kPion) || isFakeTrack(track2, PIDParticle::kKaon))) { continue; + } if (cQAplots) { if (track1.sign() < 0 && track2.sign() > 0) { @@ -1727,25 +1902,17 @@ struct Kstar892LightIon { } } else if (track1PDG == PDG_t::kKPlus) { - if ((!selectionConfig.isApplypTdepPID && !selectionConfig.isApplypTdepPIDwTOF) && !(selectionPID(track1, 1) && selectionPID(track2, 0))) { // kaon and pion - continue; - } else if (selectionConfig.isApplypTdepPID && !(selectionPIDpTdep(track1, 1) && selectionPIDpTdep(track2, 0))) { // kaon and pion - continue; - } else if (selectionConfig.isApplypTdepPIDwTOF && !(selectionPIDpTdepTOF(track1, 1) && selectionPIDpTdepTOF(track2, 0))) { + if (!selectionPID(track1, PIDParticle::kKaon) || !selectionPID(track2, PIDParticle::kPion)) { // Treat track1 as the kaon candidate and track2 as the pion candidate continue; } - if (selectionConfig.isApplyMID && (selectionMID(track1, 0) || selectionMID(track2, 1))) - continue; - - if (selectionConfig.isApplypTdepMID && (selectionMIDpTdep(track1, 0) || selectionMIDpTdep(track2, 1))) - continue; - - if (selectionConfig.isApplypTdepMIDComp && (selectionMIDPtDepComp(track1, 0) || selectionMIDPtDepComp(track2, 1))) + if (isMisidentified(track1, PIDParticle::kKaon) || isMisidentified(track2, PIDParticle::kPion)) { continue; + } - if (selectionConfig.isApplyFakeTrack && (isFakeTrack(track1, 1) || isFakeTrack(track2, 0))) + if (selectionConfig.isApplyFakeTrack && (isFakeTrack(track1, PIDParticle::kKaon) || isFakeTrack(track2, PIDParticle::kPion))) { continue; + } if (cQAplots) { if (track1.sign() < 0 && track2.sign() > 0) { @@ -1798,21 +1965,38 @@ struct Kstar892LightIon { if (track1PDG == PDG_t::kPiPlus) { daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massPi); daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); + + genDaughter1 = ROOT::Math::PxPyPzMVector(mctrack1.px(), mctrack1.py(), mctrack1.pz(), massPi); + genDaughter2 = ROOT::Math::PxPyPzMVector(mctrack2.px(), mctrack2.py(), mctrack2.pz(), massKa); + } else if (track1PDG == PDG_t::kKPlus) { daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); - } - mother = daughter1 + daughter2; // Kstar meson + genDaughter1 = ROOT::Math::PxPyPzMVector(mctrack1.px(), mctrack1.py(), mctrack1.pz(), massKa); + genDaughter2 = ROOT::Math::PxPyPzMVector(mctrack2.px(), mctrack2.py(), mctrack2.pz(), massPi); + } - hMC.fill(HIST("Rec/h2KstarRecpt2"), mothertrack1.pt(), centrality, std::sqrt(mothertrack1.e() * mothertrack1.e() - mothertrack1.p() * mothertrack1.p())); + mother = daughter1 + daughter2; // Rec Kstar meson + genMother = genDaughter1 + genDaughter2; // Gen Kstar from MC daughters if (mother.Rapidity() < selectionConfig.motherRapidityMin || mother.Rapidity() > selectionConfig.motherRapidityMax) { continue; } - hMC.fill(HIST("Rec/h1KstarRecMass"), mother.M()); - hMC.fill(HIST("Rec/h2KstarRecpt1"), mother.Pt(), centrality, mother.M()); + recMass = mother.M(); + recPt = mother.Pt(); + + genMass = genMother.M(); + genPt = mothertrack1.pt(); + + hMC.fill(HIST("Rec/hMassShift"), genPt, recPt, recMass - genMass); + + hMC.fill(HIST("Rec/h3KstarGen"), genPt, centrality, genMass); + + hMC.fill(HIST("Rec/h1KstarRecMass"), recMass); + + hMC.fill(HIST("Rec/h3KstarRec"), recPt, centrality, recMass); } } } @@ -1825,7 +2009,7 @@ struct Kstar892LightIon { return; } - if (selectionConfig.isApplyMCGenTVX && !(mcCollision.multMCFT0C() > 0 && mcCollision.multMCFT0A() > 0)) { + if (selectionConfig.isApplyMCGenTVX && (mcCollision.multMCFT0C() <= 0 || mcCollision.multMCFT0A() <= 0)) { return; } @@ -1840,21 +2024,21 @@ struct Kstar892LightIon { centrality = -1.f; for (const auto& RecCollision : recCollisions) { - if (!RecCollision.has_mcCollision()) + if (!RecCollision.has_mcCollision()) { continue; - if (!selectionEvent(RecCollision, false)) // don't fill event cut histogram + } + if (!selectionEvent(RecCollision, false)) { // don't fill event cut histogram continue; + } - if (selectCentEstimator == kFT0M) { - centrality = RecCollision.centFT0M(); - } else if (selectCentEstimator == kFT0A) { + if (selectCentEstimator == kFT0A) { centrality = RecCollision.centFT0A(); } else if (selectCentEstimator == kFT0C) { centrality = RecCollision.centFT0C(); } else if (selectCentEstimator == kFV0A) { centrality = RecCollision.centFV0A(); } else { - centrality = RecCollision.centFT0M(); // default + centrality = RecCollision.centFT0M(); // default includes kFT0M } isSelectedEvent = true; @@ -1867,8 +2051,9 @@ struct Kstar892LightIon { // Generated MC for (const auto& mcPart : mcParticles) { - if ((mcPart.y() < selectionConfig.motherRapidityMin || mcPart.y() > selectionConfig.motherRapidityMax) || std::abs(mcPart.pdgCode()) != o2::constants::physics::kK0Star892) + if ((mcPart.y() < selectionConfig.motherRapidityMin || mcPart.y() > selectionConfig.motherRapidityMax) || std::abs(mcPart.pdgCode()) != o2::constants::physics::kK0Star892) { continue; + } // signal loss estimation hMC.fill(HIST("ImpactCorr/hKstarGenBeforeEvtSel"), mcPart.pt(), impactPar); @@ -1887,7 +2072,7 @@ struct Kstar892LightIon { return; } - if (selectionConfig.isApplyMCGenTVX && !(mcCollision.multMCFT0C() > 0 && mcCollision.multMCFT0A() > 0)) { + if (selectionConfig.isApplyMCGenTVX && (mcCollision.multMCFT0C() <= 0 || mcCollision.multMCFT0A() <= 0)) { return; } @@ -1903,19 +2088,18 @@ struct Kstar892LightIon { for (auto const& collision : recCollisions) { - if (!selectionEvent(collision, false)) + if (!selectionEvent(collision, false)) { continue; + } - if (selectCentEstimator == kFT0M) { - centrality = collision.centFT0M(); - } else if (selectCentEstimator == kFT0A) { + if (selectCentEstimator == kFT0A) { centrality = collision.centFT0A(); } else if (selectCentEstimator == kFT0C) { centrality = collision.centFT0C(); } else if (selectCentEstimator == kFV0A) { centrality = collision.centFV0A(); } else { - centrality = collision.centFT0M(); // default + centrality = collision.centFT0M(); // default includes kFT0M } isSelectedEvent = true; @@ -1934,8 +2118,9 @@ struct Kstar892LightIon { // Signal loss histograms for (auto const& mcPart : mcParticles) { - if ((mcPart.y() < selectionConfig.motherRapidityMin || mcPart.y() > selectionConfig.motherRapidityMax) || std::abs(mcPart.pdgCode()) != o2::constants::physics::kK0Star892) + if ((mcPart.y() < selectionConfig.motherRapidityMin || mcPart.y() > selectionConfig.motherRapidityMax) || std::abs(mcPart.pdgCode()) != o2::constants::physics::kK0Star892) { continue; + } const float pt = mcPart.pt(); @@ -1954,7 +2139,7 @@ struct Kstar892LightIon { return; } - if (selectionConfig.isApplyMCGenTVX && !(mcCollision.multMCFT0C() > 0 && mcCollision.multMCFT0A() > 0)) { + if (selectionConfig.isApplyMCGenTVX && (mcCollision.multMCFT0C() <= 0 || mcCollision.multMCFT0A() <= 0)) { return; } @@ -1970,23 +2155,22 @@ struct Kstar892LightIon { hMC.fill(HIST("AllLoss/hMultEta05Gen"), mult05); hMC.fill(HIST("AllLoss/hMultEta08Gen"), mult08); bool isSelectedEvent = false; - float centrality = -1.f; + centrality = -1.f; for (auto const& collision : recCollisions) { - if (!selectionEvent(collision, false)) + if (!selectionEvent(collision, false)) { continue; + } - if (selectCentEstimator == kFT0M) { - centrality = collision.centFT0M(); - } else if (selectCentEstimator == kFT0A) { + if (selectCentEstimator == kFT0A) { centrality = collision.centFT0A(); } else if (selectCentEstimator == kFT0C) { centrality = collision.centFT0C(); } else if (selectCentEstimator == kFV0A) { centrality = collision.centFV0A(); } else { - centrality = collision.centFT0M(); // default + centrality = collision.centFT0M(); // default includes kFT0M } isSelectedEvent = true; @@ -2008,8 +2192,9 @@ struct Kstar892LightIon { // Generated MC for (const auto& mcPart : mcParticles) { - if ((mcPart.y() < selectionConfig.motherRapidityMin || mcPart.y() > selectionConfig.motherRapidityMax) || std::abs(mcPart.pdgCode()) != o2::constants::physics::kK0Star892) + if ((mcPart.y() < selectionConfig.motherRapidityMin || mcPart.y() > selectionConfig.motherRapidityMax) || std::abs(mcPart.pdgCode()) != o2::constants::physics::kK0Star892) { continue; + } const float pt = mcPart.pt(); @@ -2033,16 +2218,14 @@ struct Kstar892LightIon { return; } - if (selectCentEstimator == kFT0M) { - centrality = collision.centFT0M(); - } else if (selectCentEstimator == kFT0A) { + if (selectCentEstimator == kFT0A) { centrality = collision.centFT0A(); } else if (selectCentEstimator == kFT0C) { centrality = collision.centFT0C(); } else if (selectCentEstimator == kFV0A) { centrality = collision.centFV0A(); } else { - centrality = collision.centFT0M(); // default + centrality = collision.centFT0M(); // default includes kFT0M } if (!selectionEvent(collision, false)) { @@ -2051,31 +2234,37 @@ struct Kstar892LightIon { for (const auto& [track1, track2] : combinations(CombinationsFullIndexPolicy(tracks, tracks))) { - if (!selectionTrack(track1) || !selectionTrack(track2)) + if (!selectionTrack(track1) || !selectionTrack(track2)) { continue; + } - if (track1.index() >= track2.index()) + if (track1.index() >= track2.index()) { continue; + } - if (track1.sign() * track2.sign() >= 0) + if (track1.sign() * track2.sign() >= 0) { continue; + } - if (!track1.has_mcParticle() || !track2.has_mcParticle()) + if (!track1.has_mcParticle() || !track2.has_mcParticle()) { continue; + } const auto mc1 = track1.mcParticle(); const auto mc2 = track2.mcParticle(); - if (!mc1.isPhysicalPrimary() || !mc2.isPhysicalPrimary()) + if (!mc1.isPhysicalPrimary() || !mc2.isPhysicalPrimary()) { continue; + } int pdg1 = std::abs(mc1.pdgCode()); int pdg2 = std::abs(mc2.pdgCode()); bool ok1 = (pdg1 == PDG_t::kPiPlus || pdg1 == PDG_t::kKPlus); bool ok2 = (pdg2 == PDG_t::kPiPlus || pdg2 == PDG_t::kKPlus); - if (!ok1 || !ok2) + if (!ok1 || !ok2) { continue; + } // pi-pi misidentification if (pdg1 == PDG_t::kPiPlus && pdg2 == PDG_t::kPiPlus) { @@ -2120,46 +2309,50 @@ struct Kstar892LightIon { void processRecReflection(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const&, EventMCGenerated const&) { - if (!collision.has_mcCollision()) + if (!collision.has_mcCollision()) { return; + } - if (!selectionEvent(collision, false)) + if (!selectionEvent(collision, false)) { return; + } centrality = -1.f; - if (selectCentEstimator == kFT0M) { - centrality = collision.centFT0M(); - } else if (selectCentEstimator == kFT0A) { + if (selectCentEstimator == kFT0A) { centrality = collision.centFT0A(); } else if (selectCentEstimator == kFT0C) { centrality = collision.centFT0C(); } else if (selectCentEstimator == kFV0A) { centrality = collision.centFV0A(); } else { - centrality = collision.centFT0M(); + centrality = collision.centFT0M(); // default includes kFT0M } - for (const auto& [track1, track2] : - combinations(CombinationsFullIndexPolicy(tracks, tracks))) { + for (const auto& [track1, track2] : combinations(CombinationsFullIndexPolicy(tracks, tracks))) { - if (!selectionTrack(track1) || !selectionTrack(track2)) + if (!selectionTrack(track1) || !selectionTrack(track2)) { continue; + } - if (track1.index() >= track2.index()) + if (track1.index() >= track2.index()) { continue; + } - if (track1.sign() * track2.sign() >= 0) + if (track1.sign() * track2.sign() >= 0) { continue; + } - if (!track1.has_mcParticle() || !track2.has_mcParticle()) + if (!track1.has_mcParticle() || !track2.has_mcParticle()) { continue; + } const auto mc1 = track1.mcParticle(); const auto mc2 = track2.mcParticle(); - if (!mc1.isPhysicalPrimary() || !mc2.isPhysicalPrimary()) + if (!mc1.isPhysicalPrimary() || !mc2.isPhysicalPrimary()) { continue; + } bool sameMother = false; int motherPDG = 0; @@ -2172,12 +2365,14 @@ struct Kstar892LightIon { break; } } - if (sameMother) + if (sameMother) { break; + } } - if (!sameMother) + if (!sameMother) { continue; + } int pdg1 = std::abs(mc1.pdgCode()); int pdg2 = std::abs(mc2.pdgCode()); @@ -2192,16 +2387,18 @@ struct Kstar892LightIon { ROOT::Math::PxPyPzMVector p2Pi(track2.px(), track2.py(), track2.pz(), massPi); auto fake1 = p1K + p2Pi; - if (fake1.Rapidity() > selectionConfig.motherRapidityMin && fake1.Rapidity() < selectionConfig.motherRapidityMax) + if (fake1.Rapidity() > selectionConfig.motherRapidityMin && fake1.Rapidity() < selectionConfig.motherRapidityMax) { hMC.fill(HIST("Reflections/hRhoToKpi"), fake1.Pt(), centrality, fake1.M()); + } // track 2 -> K ROOT::Math::PxPyPzMVector p1Pi(track1.px(), track1.py(), track1.pz(), massPi); ROOT::Math::PxPyPzMVector p2K(track2.px(), track2.py(), track2.pz(), massKa); auto fake2 = p1Pi + p2K; - if (fake2.Rapidity() > selectionConfig.motherRapidityMin && fake2.Rapidity() < selectionConfig.motherRapidityMax) + if (fake2.Rapidity() > selectionConfig.motherRapidityMin && fake2.Rapidity() < selectionConfig.motherRapidityMax) { hMC.fill(HIST("Reflections/hRhoToKpi"), fake2.Pt(), centrality, fake2.M()); + } } // ===================================================== @@ -2214,16 +2411,18 @@ struct Kstar892LightIon { ROOT::Math::PxPyPzMVector p2Pi(track2.px(), track2.py(), track2.pz(), massPi); auto fake1 = p1K + p2Pi; - if (fake1.Rapidity() > selectionConfig.motherRapidityMin && fake1.Rapidity() < selectionConfig.motherRapidityMax) + if (fake1.Rapidity() > selectionConfig.motherRapidityMin && fake1.Rapidity() < selectionConfig.motherRapidityMax) { hMC.fill(HIST("Reflections/hOmegaToKpi"), fake1.Pt(), centrality, fake1.M()); + } // track 2 -> K ROOT::Math::PxPyPzMVector p1Pi(track1.px(), track1.py(), track1.pz(), massPi); ROOT::Math::PxPyPzMVector p2K(track2.px(), track2.py(), track2.pz(), massKa); auto fake2 = p1Pi + p2K; - if (fake2.Rapidity() > selectionConfig.motherRapidityMin && fake2.Rapidity() < selectionConfig.motherRapidityMax) + if (fake2.Rapidity() > selectionConfig.motherRapidityMin && fake2.Rapidity() < selectionConfig.motherRapidityMax) { hMC.fill(HIST("Reflections/hOmegaToKpi"), fake2.Pt(), centrality, fake2.M()); + } } // ===================================================== @@ -2236,16 +2435,18 @@ struct Kstar892LightIon { ROOT::Math::PxPyPzMVector p2Pi(track2.px(), track2.py(), track2.pz(), massPi); auto fake1 = p1K + p2Pi; - if (fake1.Rapidity() > selectionConfig.motherRapidityMin && fake1.Rapidity() < selectionConfig.motherRapidityMax) + if (fake1.Rapidity() > selectionConfig.motherRapidityMin && fake1.Rapidity() < selectionConfig.motherRapidityMax) { hMC.fill(HIST("Reflections/hEtaToKpi"), fake1.Pt(), centrality, fake1.M()); + } // track 2 -> K ROOT::Math::PxPyPzMVector p1Pi(track1.px(), track1.py(), track1.pz(), massPi); ROOT::Math::PxPyPzMVector p2K(track2.px(), track2.py(), track2.pz(), massKa); auto fake2 = p1Pi + p2K; - if (fake2.Rapidity() > selectionConfig.motherRapidityMin && fake2.Rapidity() < selectionConfig.motherRapidityMax) + if (fake2.Rapidity() > selectionConfig.motherRapidityMin && fake2.Rapidity() < selectionConfig.motherRapidityMax) { hMC.fill(HIST("Reflections/hEtaToKpi"), fake2.Pt(), centrality, fake2.M()); + } } // ===================================================== @@ -2258,16 +2459,18 @@ struct Kstar892LightIon { ROOT::Math::PxPyPzMVector p2Pi(track2.px(), track2.py(), track2.pz(), massPi); auto fake1 = p1K + p2Pi; - if (fake1.Rapidity() > selectionConfig.motherRapidityMin && fake1.Rapidity() < selectionConfig.motherRapidityMax) + if (fake1.Rapidity() > selectionConfig.motherRapidityMin && fake1.Rapidity() < selectionConfig.motherRapidityMax) { hMC.fill(HIST("Reflections/hEtaPrimeToKpi"), fake1.Pt(), centrality, fake1.M()); + } // track 2 -> K ROOT::Math::PxPyPzMVector p1Pi(track1.px(), track1.py(), track1.pz(), massPi); ROOT::Math::PxPyPzMVector p2K(track2.px(), track2.py(), track2.pz(), massKa); auto fake2 = p1Pi + p2K; - if (fake2.Rapidity() > selectionConfig.motherRapidityMin && fake2.Rapidity() < selectionConfig.motherRapidityMax) + if (fake2.Rapidity() > selectionConfig.motherRapidityMin && fake2.Rapidity() < selectionConfig.motherRapidityMax) { hMC.fill(HIST("Reflections/hEtaPrimeToKpi"), fake2.Pt(), centrality, fake2.M()); + } } // ===================================================== @@ -2280,16 +2483,18 @@ struct Kstar892LightIon { ROOT::Math::PxPyPzMVector p2K(track2.px(), track2.py(), track2.pz(), massKa); auto fake1 = p1Pi + p2K; - if (fake1.Rapidity() > selectionConfig.motherRapidityMin && fake1.Rapidity() < selectionConfig.motherRapidityMax) + if (fake1.Rapidity() > selectionConfig.motherRapidityMin && fake1.Rapidity() < selectionConfig.motherRapidityMax) { hMC.fill(HIST("Reflections/hPhiToKpi"), fake1.Pt(), centrality, fake1.M()); + } // track 2 -> pi ROOT::Math::PxPyPzMVector p1K(track1.px(), track1.py(), track1.pz(), massKa); ROOT::Math::PxPyPzMVector p2Pi(track2.px(), track2.py(), track2.pz(), massPi); auto fake2 = p1K + p2Pi; - if (fake2.Rapidity() > selectionConfig.motherRapidityMin && fake2.Rapidity() < selectionConfig.motherRapidityMax) + if (fake2.Rapidity() > selectionConfig.motherRapidityMin && fake2.Rapidity() < selectionConfig.motherRapidityMax) { hMC.fill(HIST("Reflections/hPhiToKpi"), fake2.Pt(), centrality, fake2.M()); + } } // ===================================================== @@ -2303,14 +2508,598 @@ struct Kstar892LightIon { auto fake = p1Swap + p2Swap; - if (fake.Rapidity() > selectionConfig.motherRapidityMin && fake.Rapidity() < selectionConfig.motherRapidityMax) + if (fake.Rapidity() > selectionConfig.motherRapidityMin && fake.Rapidity() < selectionConfig.motherRapidityMax) { hMC.fill(HIST("Reflections/hKstarSelf"), fake.Pt(), centrality, fake.M()); + } + } + + // ========================================= + // Higher resonance feed-down + // ========================================= + + if ((pdg1 == PDG_t::kKPlus && pdg2 == PDG_t::kPiPlus) || (pdg1 == PDG_t::kPiPlus && pdg2 == PDG_t::kKPlus)) { + + ROOT::Math::PxPyPzMVector p1(track1.px(), track1.py(), track1.pz(), pdg1 == PDG_t::kKPlus ? massKa : massPi); + + ROOT::Math::PxPyPzMVector p2(track2.px(), track2.py(), track2.pz(), pdg2 == PDG_t::kKPlus ? massKa : massPi); + + auto pair = p1 + p2; + + if (pair.Rapidity() < selectionConfig.motherRapidityMin || pair.Rapidity() > selectionConfig.motherRapidityMax) { + continue; + } + + // ========================================== + // K1(1270) + // ========================================== + if (motherPDG == o2::constants::physics::kK1_1270Plus) { + hMC.fill(HIST("FeedDown/hK1_1270"), pair.Pt(), centrality, pair.M()); + } + + // ========================================== + // K1(1400) + // ========================================== + if (motherPDG == kK11400Plus) { + hMC.fill(HIST("FeedDown/hK1_1400"), pair.Pt(), centrality, pair.M()); + } + + // ========================================== + // K*(1410) + // ========================================== + if (motherPDG == kKstar14100) { + hMC.fill(HIST("FeedDown/hKstar1410"), pair.Pt(), centrality, pair.M()); + } + + // ========================================== + // K*0(1430) + // ========================================== + if (motherPDG == kKstar14300) { + hMC.fill(HIST("FeedDown/hKstar0_1430_0"), pair.Pt(), centrality, pair.M()); + } + + // ========================================== + // K*±(1430) + // ========================================== + if (motherPDG == kKstar1430Plus) { + hMC.fill(HIST("FeedDown/hKstar0_1430_ch"), pair.Pt(), centrality, pair.M()); + } + + // ========================================== + // K*2(1430) + // ========================================== + if (motherPDG == kKstar214300) { + hMC.fill(HIST("FeedDown/hKstar2_1430"), pair.Pt(), centrality, pair.M()); + } + + // ========================================== + // K2(1770) + // ========================================== + if (motherPDG == kK217700) { + hMC.fill(HIST("FeedDown/hK2_1770"), pair.Pt(), centrality, pair.M()); + } + + // ========================================== + // K2(1820) + // ========================================== + if (motherPDG == kK218200) { + hMC.fill(HIST("FeedDown/hK2_1820"), pair.Pt(), centrality, pair.M()); + } + + // ========================================== + // K*(1680) + // ========================================== + if (motherPDG == kKstar16800) { + hMC.fill(HIST("FeedDown/hKstar1680"), pair.Pt(), centrality, pair.M()); + } } } } PROCESS_SWITCH(Kstar892LightIon, processRecReflection, "Process reconstructed reflections", false); - Service pdg; + void processRecCorrelatedBackground(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const&, EventMCGenerated const&) + { + if (!collision.has_mcCollision()) { + return; + } + + if (!selectionEvent(collision, false)) { + return; + } + + centrality = -1.f; + + if (selectCentEstimator == kFT0A) { + centrality = collision.centFT0A(); + } else if (selectCentEstimator == kFT0C) { + centrality = collision.centFT0C(); + } else if (selectCentEstimator == kFV0A) { + centrality = collision.centFV0A(); + } else { + centrality = collision.centFT0M(); // default includes kFT0M + } + + for (const auto& [track1, track2] : combinations(CombinationsFullIndexPolicy(tracks, tracks))) { + + if (!selectionTrack(track1)) { + continue; + } + + if (!selectionTrack(track2)) { + continue; + } + + if (track1.index() >= track2.index()) { + continue; + } + + if (track1.sign() * track2.sign() >= 0) { + continue; + } + + if (!track1.has_mcParticle()) { + continue; + } + + if (!track2.has_mcParticle()) { + continue; + } + + auto mc1 = track1.mcParticle(); + auto mc2 = track2.mcParticle(); + + // if (!mc1.isPhysicalPrimary() || !mc2.isPhysicalPrimary()) + // continue; + + int pdg1 = std::abs(mc1.pdgCode()); + int pdg2 = std::abs(mc2.pdgCode()); + + if ((pdg1 != PDG_t::kKPlus || pdg2 != PDG_t::kPiPlus) && (pdg1 != PDG_t::kPiPlus || pdg2 != PDG_t::kKPlus)) { + continue; + } + + ROOT::Math::PxPyPzMVector p1(track1.px(), track1.py(), track1.pz(), pdg1 == PDG_t::kKPlus ? massKa : massPi); + ROOT::Math::PxPyPzMVector p2(track2.px(), track2.py(), track2.pz(), pdg2 == PDG_t::kKPlus ? massKa : massPi); + auto pair = p1 + p2; + + if (pair.Rapidity() < selectionConfig.motherRapidityMin || pair.Rapidity() > selectionConfig.motherRapidityMax) { + continue; + } + + bool trueKstar = false; + + for (const auto& m1 : mc1.mothers_as()) { + for (const auto& m2 : mc2.mothers_as()) { + + if (m1.globalIndex() == m2.globalIndex() && std::abs(m1.pdgCode()) == o2::constants::physics::kK0Star892) { + trueKstar = true; + break; + } + } + if (trueKstar) { + break; + } + } + if (trueKstar) { + continue; + } + + auto ancestors1 = getAncestors(mc1); + auto ancestors2 = getAncestors(mc2); + + bool fromK11270 = false; + bool fromK11400 = false; + bool fromKstar1680 = false; + bool fromK21770 = false; + bool fromK21820 = false; + bool fromKstar1410 = false; + bool fromKstar01430 = false; + + for (auto const& a1 : ancestors1) { + + for (auto const& a2 : ancestors2) { + + if (a1.first != a2.first) { + continue; + } + + int ancestorPdg = a1.second; + + if (ancestorPdg == o2::constants::physics::kK1_1270Plus) { + fromK11270 = true; + } + + if (ancestorPdg == kK11400Plus) { + fromK11400 = true; + } + + if (ancestorPdg == kKStar1680Plus) { + fromKstar1680 = true; + } + + if (ancestorPdg == kK21770Plus) { + fromK21770 = true; + } + + if (ancestorPdg == kK21820Plus) { + fromK21820 = true; + } + + if (ancestorPdg == kKstar14100) { + fromKstar1410 = true; + } + + if (ancestorPdg == kKstar14300) { + fromKstar01430 = true; + } + } + } + + if (fromKstar1410) { + hMC.fill(HIST("CorrelatedBG/hKstar1410"), pair.Pt(), centrality, pair.M()); + } + + if (fromKstar01430) { + hMC.fill(HIST("CorrelatedBG/hKstar0_1430"), pair.Pt(), centrality, pair.M()); + } + + if (fromK11270) { + hMC.fill(HIST("CorrelatedBG/hK1_1270"), pair.Pt(), centrality, pair.M()); + } + + if (fromK11400) { + hMC.fill(HIST("CorrelatedBG/hK1_1400"), pair.Pt(), centrality, pair.M()); + } + + if (fromKstar1680) { + hMC.fill(HIST("CorrelatedBG/hKstar1680"), pair.Pt(), centrality, pair.M()); + } + + if (fromK21770) { + hMC.fill(HIST("CorrelatedBG/hK2_1770"), pair.Pt(), centrality, pair.M()); + } + + if (fromK21820) { + hMC.fill(HIST("CorrelatedBG/hK2_1820"), pair.Pt(), centrality, pair.M()); + } + } + } + + PROCESS_SWITCH(Kstar892LightIon, processRecCorrelatedBackground, "Process correlated background", false); + + void processTemplateMC(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const&, EventMCGenerated const&) + { + if (!collision.has_mcCollision()) { + return; + } + + if (!selectionEvent(collision, false)) { + return; + } + + centrality = -1.f; + if (selectCentEstimator == kFT0A) { + centrality = collision.centFT0A(); + } else if (selectCentEstimator == kFT0C) { + centrality = collision.centFT0C(); + } else if (selectCentEstimator == kFV0A) { + centrality = collision.centFV0A(); + } else { + centrality = collision.centFT0M(); // default includes kFT0M + } + + auto classifyOrigin = [](const aod::McParticle& part, int64_t& motherIdx) -> int { + motherIdx = -1; + if (!part.has_mothers()) { + return 0; + } + for (const auto& mom : part.mothers_as()) { + if (!mom.producedByGenerator()) { + continue; + } + motherIdx = mom.globalIndex(); + if (std::abs(mom.pdgCode()) == o2::constants::physics::kK0Star892) { + return 1; + } + return 2; + } + return 0; + }; + + for (const auto& [track1, track2] : combinations(CombinationsFullIndexPolicy(tracks, tracks))) { + + if (!selectionTrack(track1) || !selectionTrack(track2)) { + continue; + } + + if (track1.globalIndex() == track2.globalIndex()) { + continue; + } + + if (!selectionPair(track1, track2)) { + continue; + } + + if (!selectionPID(track1, PIDParticle::kKaon)) { + continue; + } + if (!selectionPID(track2, PIDParticle::kPion)) { + continue; + } + + if (isMisidentified(track1, PIDParticle::kKaon)) { + continue; + } + if (isMisidentified(track2, PIDParticle::kPion)) { + continue; + } + + if (selectionConfig.isApplyFakeTrack && (isFakeTrack(track1, PIDParticle::kKaon) || isFakeTrack(track2, PIDParticle::kPion))) { + continue; + } + + if (!track1.has_mcParticle() || !track2.has_mcParticle()) { + continue; + } + + daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); + mother = daughter1 + daughter2; + + if (mother.Rapidity() < selectionConfig.motherRapidityMin || mother.Rapidity() > selectionConfig.motherRapidityMax) { + continue; + } + + recMass = mother.M(); + recPt = mother.Pt(); + + const auto mcKa = track1.mcParticle(); + const auto mcPi = track2.mcParticle(); + + if (selectionConfig.isPrimaryTrack && (!mcKa.isPhysicalPrimary() || !mcPi.isPhysicalPrimary())) { + continue; + } + + int64_t kaMotherIdx = -1; + int64_t piMotherIdx = -1; + const int kaOrigin = classifyOrigin(mcKa, kaMotherIdx); + const int piOrigin = classifyOrigin(mcPi, piMotherIdx); + + const bool kaIsKstar = (kaOrigin == 1); + const bool piIsKstar = (piOrigin == 1); + const bool kaHasParent = (kaOrigin != 0); + const bool piHasParent = (piOrigin != 0); + const bool sameMother = (kaMotherIdx >= 0) && (piMotherIdx >= 0) && (kaMotherIdx == piMotherIdx); + + if (kaIsKstar && piIsKstar && sameMother) { + const bool correctAssignment = (std::abs(mcKa.pdgCode()) == PDG_t::kKPlus) && (std::abs(mcPi.pdgCode()) == PDG_t::kPiPlus); + if (correctAssignment) { + hMC.fill(HIST("Template/hSignal"), recPt, centrality, recMass); + } else { + hMC.fill(HIST("Template/hKstarReflection"), recPt, centrality, recMass); + } + + } else if (sameMother && kaHasParent && piHasParent) { + hMC.fill(HIST("Template/hSameMotherOther"), recPt, centrality, recMass); + + } else if (!sameMother && kaHasParent && piHasParent) { + hMC.fill(HIST("Template/hDifferentMother"), recPt, centrality, recMass); + + } else if (kaHasParent != piHasParent) { + hMC.fill(HIST("Template/hPrimaryResonance"), recPt, centrality, recMass); + + } else { + hMC.fill(HIST("Template/hPrimaryPrimary"), recPt, centrality, recMass); + } + } + } + PROCESS_SWITCH(Kstar892LightIon, processTemplateMC, "Process MC Template Background", false); + + void processRecKinematics(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const&, EventMCGenerated const&) + { + if (!collision.has_mcCollision()) { + return; + } + + centrality = collision.centFT0M(); + + if (selectCentEstimator == kFT0A) { + centrality = collision.centFT0A(); + } else if (selectCentEstimator == kFT0C) { + centrality = collision.centFT0C(); + } else if (selectCentEstimator == kFV0A) { + centrality = collision.centFV0A(); + } else { + centrality = collision.centFT0M(); // default includes kFT0M + } + + if (!selectionEvent(collision, true)) { // fill MC event cut histogram + return; + } + + hMC.fill(HIST("Kinematics/h1RecCent"), centrality); + + // auto oldindex = -999; + + for (const auto& [track1, track2] : combinations(CombinationsFullIndexPolicy(tracks, tracks))) { + if (!selectionTrack(track1) || !selectionTrack(track2)) { + continue; + } + + if (!track1.has_mcParticle() || !track2.has_mcParticle()) { + continue; + } + + if (track1.index() <= track2.index()) { + continue; + } + + if (!selectionPair(track1, track2)) { + continue; + } + + if (track1.sign() * track2.sign() >= 0) { + continue; + } + + const auto mctrack1 = track1.mcParticle(); + const auto mctrack2 = track2.mcParticle(); + if (!mctrack1.isPhysicalPrimary() || !mctrack2.isPhysicalPrimary()) { + continue; + } + + int track1PDG = std::abs(mctrack1.pdgCode()); + int track2PDG = std::abs(mctrack2.pdgCode()); + + if ((track1PDG != PDG_t::kPiPlus || track2PDG != PDG_t::kKPlus) && (track1PDG != PDG_t::kKPlus || track2PDG != PDG_t::kPiPlus)) { + continue; + } + + ROOT::Math::PxPyPzMVector kVec; + ROOT::Math::PxPyPzMVector piVec; + + double phiK = 0.0, phiPi = 0.0; + double etaK = 0.0, etaPi = 0.0; + double ptK = 0.0, ptPi = 0.0; + + if (track1PDG == PDG_t::kKPlus) { + + if (!selectionPID(track1, PIDParticle::kKaon) || !selectionPID(track2, PIDParticle::kPion)) { // Treat track1 as the kaon candidate and track2 as the pion candidate + continue; + } + + if (isMisidentified(track1, PIDParticle::kKaon) || isMisidentified(track2, PIDParticle::kPion)) { + continue; + } + + if (selectionConfig.isApplyFakeTrack && (isFakeTrack(track1, PIDParticle::kKaon) || isFakeTrack(track2, PIDParticle::kPion))) { + continue; + } + + kVec = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + piVec = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); + + phiK = track1.phi(); + etaK = track1.eta(); + ptK = track1.pt(); + + phiPi = track2.phi(); + etaPi = track2.eta(); + ptPi = track2.pt(); + + } else { + + if (!selectionPID(track1, PIDParticle::kPion) || !selectionPID(track2, PIDParticle::kKaon)) { // Treat track1 as the pion candidate and track2 as the kaon candidate + continue; + } + + if (isMisidentified(track1, PIDParticle::kPion) || isMisidentified(track2, PIDParticle::kKaon)) { + continue; + } + + if (selectionConfig.isApplyFakeTrack && (isFakeTrack(track1, PIDParticle::kPion) || isFakeTrack(track2, PIDParticle::kKaon))) { + continue; + } + + kVec = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); + piVec = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massPi); + + phiK = track2.phi(); + etaK = track2.eta(); + ptK = track2.pt(); + + phiPi = track1.phi(); + etaPi = track1.eta(); + ptPi = track1.pt(); + } + + auto pair = kVec + piVec; + + double mass = pair.M(); + + double cosAngle = (kVec.Px() * piVec.Px() + kVec.Py() * piVec.Py() + kVec.Pz() * piVec.Pz()) / (kVec.P() * piVec.P()); + + cosAngle = std::clamp(cosAngle, -1.0, 1.0); + + double openAngle = std::acos(cosAngle); + + double dPhi = RecoDecay::constrainAngle(phiK - phiPi, -o2::constants::math::PI); + + double dEta = etaK - etaPi; + + double dR = std::sqrt(dPhi * dPhi + dEta * dEta); + + bool isTrueKstar = false; + bool hasCommonMother = false; + + int commonMotherPDG = initialValue; + + for (const auto& mothertrack1 : mctrack1.mothers_as()) { + for (const auto& mothertrack2 : mctrack2.mothers_as()) { + + if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) { + continue; + } + + if (mothertrack1.globalIndex() != mothertrack2.globalIndex()) { + continue; + } + + hasCommonMother = true; + commonMotherPDG = mothertrack1.pdgCode(); + + if (std::abs(commonMotherPDG) == o2::constants::physics::kK0Star892) { + isTrueKstar = true; + } + } + } + + if (pair.Rapidity() < selectionConfig.motherRapidityMin || pair.Rapidity() > selectionConfig.motherRapidityMax) { + continue; + } + + if (isTrueKstar) { + + hMC.fill(HIST("Kinematics/hPDGMotherKstar"), commonMotherPDG, mass); + + hMC.fill(HIST("Kinematics/hOpenAngleKstar"), openAngle, mass); + + hMC.fill(HIST("Kinematics/hDeltaPhiKstar"), dPhi, mass); + + hMC.fill(HIST("Kinematics/hDeltaEtaKstar"), dEta, mass); + + hMC.fill(HIST("Kinematics/hDeltaRKstar"), dR, mass); + + hMC.fill(HIST("Kinematics/hKaonPtKstar"), ptK, mass); + + hMC.fill(HIST("Kinematics/hPionPtKstar"), ptPi, mass); + + hMC.fill(HIST("Kinematics/hPtCentMassKstar"), pair.Pt(), centrality, mass); + + } else { + + hMC.fill(HIST("Kinematics/hOpenAngleOther"), openAngle, mass); + + hMC.fill(HIST("Kinematics/hDeltaPhiOther"), dPhi, mass); + + hMC.fill(HIST("Kinematics/hDeltaEtaOther"), dEta, mass); + + hMC.fill(HIST("Kinematics/hDeltaROther"), dR, mass); + + hMC.fill(HIST("Kinematics/hKaonPtOther"), ptK, mass); + + hMC.fill(HIST("Kinematics/hPionPtOther"), ptPi, mass); + + hMC.fill(HIST("Kinematics/hPtCentMassOther"), pair.Pt(), centrality, mass); + + if (hasCommonMother) { + hMC.fill(HIST("Kinematics/hOtherMotherPDG"), commonMotherPDG, mass); + } + } + } + } + PROCESS_SWITCH(Kstar892LightIon, processRecKinematics, "Process Reconstructed Kinematics", false); + + Service pdg{}; void processMCCheck(aod::McCollisions::iterator const& mccollision, soa::SmallGroups const& collisions, aod::McParticles const& mcParticles, TrackCandidatesMC const&) { @@ -2343,12 +3132,14 @@ struct Kstar892LightIon { } // Is it a charged particle? - if (std::abs(charge) < MinCharge) + if (std::abs(charge) < MinCharge) { continue; + } // Is it a primary particle? - if (!particle.isPhysicalPrimary()) + if (!particle.isPhysicalPrimary()) { continue; + } const float eta{particle.eta()}; @@ -2366,8 +3157,9 @@ struct Kstar892LightIon { } // INEL > 0 - if (std::abs(eta) > One) + if (std::abs(eta) > One) { continue; + } nChMC++; } @@ -2376,7 +3168,7 @@ struct Kstar892LightIon { // Only events with at least one charged particle in the FT0A and FT0C acceptances //--------------------------- if (selectionConfig.selTVXMC) { - if (!(nChFT0A > ZeroInt && nChFT0C > ZeroInt)) { + if (nChFT0A <= ZeroInt || nChFT0C <= ZeroInt) { hMC.fill(HIST("MCCheck/NchMCcentVsTVX"), nChMC, 0.5); return; } @@ -2414,16 +3206,14 @@ struct Kstar892LightIon { centrality = -1.f; for (const auto& collision : collisions) { - if (selectCentEstimator == kFT0M) { - centrality = collision.centFT0M(); - } else if (selectCentEstimator == kFT0A) { + if (selectCentEstimator == kFT0A) { centrality = collision.centFT0A(); } else if (selectCentEstimator == kFT0C) { centrality = collision.centFT0C(); } else if (selectCentEstimator == kFV0A) { centrality = collision.centFV0A(); } else { - centrality = collision.centFT0M(); // default + centrality = collision.centFT0M(); // default includes kFT0M } if (selectionConfig.selHasFT0MC && !collision.has_foundFT0()) { @@ -2448,16 +3238,14 @@ struct Kstar892LightIon { centrality = -1.f; for (const auto& collision : collisions) { - if (selectCentEstimator == kFT0M) { - centrality = collision.centFT0M(); - } else if (selectCentEstimator == kFT0A) { + if (selectCentEstimator == kFT0A) { centrality = collision.centFT0A(); } else if (selectCentEstimator == kFT0C) { centrality = collision.centFT0C(); } else if (selectCentEstimator == kFV0A) { centrality = collision.centFV0A(); } else { - centrality = collision.centFT0M(); // default + centrality = collision.centFT0M(); // default includes kFT0M } //--------------------------- @@ -2504,8 +3292,9 @@ struct Kstar892LightIon { // This histograms are used for the denominator of the tracking efficiency //--------------------------- for (const auto& mcPart : mcParticles) { - if ((mcPart.y() < selectionConfig.motherRapidityMin || mcPart.y() > selectionConfig.motherRapidityMax) || std::abs(mcPart.pdgCode()) != o2::constants::physics::kK0Star892) + if ((mcPart.y() < selectionConfig.motherRapidityMin || mcPart.y() > selectionConfig.motherRapidityMax) || std::abs(mcPart.pdgCode()) != o2::constants::physics::kK0Star892) { continue; + } hMC.fill(HIST("MCCheck/PtKstarVsCentMC_WithRecoEvt"), mcPart.pt(), centrality); hMC.fill(HIST("MCCheck/PtKstarVsNchMC_WithRecoEvt"), mcPart.pt(), nChMCEta08); // Numerator of signal loss @@ -2521,8 +3310,9 @@ struct Kstar892LightIon { // This is used for the denominator of the signal loss correction //--------------------------- for (const auto& mcPart : mcParticles) { - if ((mcPart.y() < selectionConfig.motherRapidityMin || mcPart.y() > selectionConfig.motherRapidityMax) || std::abs(mcPart.pdgCode()) != o2::constants::physics::kK0Star892) + if ((mcPart.y() < selectionConfig.motherRapidityMin || mcPart.y() > selectionConfig.motherRapidityMax) || std::abs(mcPart.pdgCode()) != o2::constants::physics::kK0Star892) { continue; + } hMC.fill(HIST("MCCheck/PtKstarVsNchMC_AllGen"), mcPart.pt(), nChMCEta08); } // Loop over Generated Particles diff --git a/PWGLF/Tasks/Resonances/kstarInOO.cxx b/PWGLF/Tasks/Resonances/kstarInOO.cxx index 2b0f71c60e6..b2840dca788 100644 --- a/PWGLF/Tasks/Resonances/kstarInOO.cxx +++ b/PWGLF/Tasks/Resonances/kstarInOO.cxx @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include @@ -65,15 +64,16 @@ struct kstarInOO { SliceCache cache; Preslice perCollision = aod::track::collisionId; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + //================================== - //|| - //|| Selection - //|| + //| + //| Selection + //| //================================== - // Event Selection Configurable cfgEventSelections{"cfgEventSelections", "sel8", "Set event selection"}; Configurable cfgEventVtxCut{"cfgEventVtxCut", 10.0, "V_z cut selection"}; + Configurable cfgEventMaxEta{"cfgEventMaxEta", 1.0, "set INEL event eta cut"}; ConfigurableAxis cfgCentAxis{"cfgCentAxis", {VARIABLE_WIDTH, 0.0, 1.0, 5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0}, "Binning of the centrality axis"}; Configurable cfgOccupancySel{"cfgOccupancySel", false, "Occupancy selection"}; Configurable cfgOccupancyMax{"cfgOccupancyMax", 999999., "maximum occupancy of tracks in neighbouring collisions in a given time range"}; @@ -86,9 +86,10 @@ struct kstarInOO { Configurable cfgTrackMaxDCArToPVcut{"cfgTrackMaxDCArToPVcut", 0.5, "Track DCAr cut to PV Maximum"}; Configurable cfgTrackMaxDCAzToPVcut{"cfgTrackMaxDCAzToPVcut", 2.0, "Track DCAz cut to PV Maximum"}; Configurable cfgTrackGlobalSel{"cfgTrackGlobalSel", true, "Global track selection"}; - Configurable cfgTrackPrimaryTrack{"cfgTrackPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz - Configurable cfgTrackConnectedToPV{"cfgTrackConnectedToPV", true, "PV contributor track selection"}; // PV Contriuibutor - Configurable cfgTrackGlobalWoDCATrack{"cfgTrackGlobalWoDCATrack", true, "Global track selection without DCA"}; // kQualityTracks (kTrackType | kTPCNCls | kTPCCrossedRows | kTPCCrossedRowsOverNCls | kTPCChi2NDF | kTPCRefit | kITSNCls | kITSChi2NDF | kITSRefit | kITSHits) | kInAcceptanceTracks (kPtRange | kEtaRange) + Configurable cfgTrackPrimaryTrack{"cfgTrackPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz + Configurable cfgTrackConnectedToPV{"cfgTrackConnectedToPV", true, "PV contributor track selection"}; // PV Contriuibutor + Configurable cfgTrackGlobalWoDCATrack{"cfgTrackGlobalWoDCATrack", true, "Global track selection without DCA"}; + // kQualityTracks (kTrackType | kTPCNCls | kTPCCrossedRows | kTPCCrossedRowsOverNCls | kTPCChi2NDF | kTPCRefit | kITSNCls | kITSChi2NDF | kITSRefit | kITSHits) | kInAcceptanceTracks (kPtRange | kEtaRange) // TPC Configurable cfgTrackFindableTPCClusters{"cfgTrackFindableTPCClusters", 50, "nFindable TPC Clusters"}; Configurable cfgTrackTPCCrossedRows{"cfgTrackTPCCrossedRows", 70, "nCrossed TPC Rows"}; @@ -119,6 +120,7 @@ struct kstarInOO { // MCGen Configurable cfgForceGenReco{"cfgForceGenReco", false, "Only consider events which are reconstructed (neglect event-loss)"}; Configurable cfgReqMcEffPID{"cfgReqMcEffPID", false, "Request McEfficiency PID"}; + Configurable cfgReqMcEffTrackQA{"cfgRecMcEffTrackQA", false, "Enable Jet Cut on Trig"}; // Pair Configurable cfgMinvNBins{"cfgMinvNBins", 300, "Number of bins for Minv axis"}; @@ -131,36 +133,42 @@ struct kstarInOO { Configurable cfgEventCutQA{"cfgEventCutsQA", false, "Enable Event QA Hists"}; Configurable cfgTrackCutQA{"cfgTrackCutQA", false, "Enable Track QA Hists"}; Configurable cfgJetQAHistos{"cfgJetQAHistos", false, "Enable Jet QA Histos"}; + Configurable cfgWoJetQA{"cfgWoJetQA", false, "Enable Without Jet QA Histos"}; Configurable cfgMCHistos{"cfgMCHistos", false, "Enable MC Hists"}; Configurable cfgMixedHistos{"cfgMixedHistos", false, "Enable Mixed Histos"}; Configurable cfgJetHistos{"cfgJetHistos", false, "Enable Jet Histos"}; Configurable cfgJetMCHistos{"cfgJetMCHistos", false, "Enable Jet MC Histos"}; + Configurable cfgJetdRHistos{"cfgJetdRHistos", false, "Enable Jet dR QA Histos"}; Configurable cfgCutonTrig{"cfgCutonTrig", false, "Enable Jet Cut on Trig"}; - Configurable cfgManualEvSel{"cfgManualEvSel", false, "Enable Manual EvSel"}; - Configurable cfgJetEvSel{"cfgJetEvSel", false, "Enable Manual JetEvSel"}; - //====================== - //|| - //|| JET - //|| + //| + //| JET + //| //====================== Configurable cfgJetpT{"cfgJetpT", 8.0, "Set Jet pT minimum"}; - Configurable cfgJetR{"cfgJetR", 0.4, "Set Jet radius parameter"}; + Configurable cfgJetR{"cfgJetR", 0.4, "Anti-kT Radius"}; + Configurable cfgJetdR{"cfgJetdR", 0.4, "Set Jet radius parameter"}; + Configurable cfgJetMaxEta{"cfgJetMaxEta", 0.9, "Set Jet Max Eta"}; + Configurable cfgSingleJet{"cfgSingleJet", false, "Enforces strict phi-jet correspondance"}; Configurable cfgReqJets{"cfgReqJets", false, "False: MB, True: Inside Jets"}; Configurable cfgRealTriggerMasks{"cfgRealTriggerMasks", "", "possible JE Trigger masks: fJetChLowPt,fJetChHighPt,fTrackLowPt,fTrackHighPt,fJetD0ChLowPt,fJetD0ChHighPt,fJetLcChLowPt,fJetLcChHighPt,fEMCALReadout,fJetFullHighPt,fJetFullLowPt,fJetNeutralHighPt,fJetNeutralLowPt,fGammaVeryHighPtEMCAL,fGammaVeryHighPtDCAL,fGammaHighPtEMCAL,fGammaHighPtDCAL,fGammaLowPtEMCAL,fGammaLowPtDCAL,fGammaVeryLowPtEMCAL,fGammaVeryLowPtDCAL"}; Configurable cfgTriggerMasksTest1{"cfgTriggerMasksTest1", "", "possible JE Trigger masks Test1"}; Configurable cfgTriggerMasksTest2{"cfgTriggerMasksTest2", "", "possible JE Trigger masks Test2"}; Configurable cfgTriggerMasksTest3{"cfgTriggerMasksTest3", "", "possible JE Trigger masks Test3"}; + Configurable cfgForceTrueINELgt{"cfgForceTrueINELgt", true, "Check generated event with True INELgt0"}; + + Configurable cfgIsKstar{"cfgIsKstar", false, "Swaps Phi for Kstar analysis"}; + Configurable cfgBR{"cfgBR", false, "Forces Gen. Charged BR Only"}; std::vector eventSelectionBits; std::vector RealTriggerMaskBits; std::vector triggerMaskBitsTest1; std::vector triggerMaskBitsTest2; std::vector triggerMaskBitsTest3; - // Main + void init(o2::framework::InitContext&) { // HISTOGRAMS @@ -179,6 +187,23 @@ struct kstarInOO { histos.add("hPosZ_AC", "hPosZ_AC", kTH1F, {{300, -15.0, 15.0}}); histos.add("hcentFT0C_BC", "centFT0C_BC", kTH1F, {{110, 0.0, 110.0}}); histos.add("hcentFT0C_AC", "centFT0C_AC", kTH1F, {{110, 0.0, 110.0}}); + + std::shared_ptr hCutFlow = histos.get(HIST("hEvent_Cut")); + std::vector eventCutLabels = { + "All Events", + "sel8", + Form("|Vz| < %.1f", cfgEventVtxCut.value), + "kIsGoodZvtxFT0vsPV", + "kNoSameBunchPileup", + "kNoTimeFrameBorder", + "kNoITSROFrameBorder", + "kNoCollInTimeRangeStandard", + "kIsGoodITSLayersAll", + Form("Occupancy < %.0f", cfgOccupancyMax.value), + "All passed events"}; + for (size_t i = 0; i < eventCutLabels.size(); ++i) { + hCutFlow->GetXaxis()->SetBinLabel(i + 1, eventCutLabels[i].c_str()); + } } if (cfgTrackCutQA) { histos.add("hDCArToPv_BC", "DCArToPv_BC", kTH1F, {axisDCAxy}); @@ -219,20 +244,50 @@ struct kstarInOO { } if (cfgJetQAHistos) { histos.add("nTriggerQA", "nTriggerQA", kTH1F, {{8, 0.0, 8.0}}); - histos.add("nTriggerQA_GoodEv", "nTriggerQA_GoodEv", kTH1F, {{8, 0.0, 8.0}}); - histos.add("nTriggerQA_GoodTrig", "nTriggerQA_GoodTrig", kTH1F, {{8, 0.0, 8.0}}); - histos.add("nTriggerQA_GoodEvTrig", "nTriggerQA_GoodEvTrig", kTH1F, {{8, 0.0, 8.0}}); histos.add("JetpT", "Jet pT (GeV/c)", kTH1F, {{4000, 0., 200.}}); histos.add("JetEta", "Jet Eta", kTH1F, {{100, -1.0, 1.0}}); histos.add("JetPhi", "Jet Phi", kTH1F, {{80, -1.0, 7.0}}); + histos.add("nGoodJets", "The number of good jets", kTH1F, {{6, -0.5, 5.5}}); + histos.add("nJetsPerEvent", "The number of jet per event", kTH1F, {{6, -0.5, 5.5}}); + histos.add("rawDimpT", "rawDimpT", kTH2F, {{1000, 0.0, 10.0}, {100, -0.5, 0.5}}); + histos.add("jetTrackEta", "Jet Track Eta", kTH1F, {{100, -1.0, 1.0}}); histos.add("jetTrackPhi", "Jet Track Phi", kTH1F, {{80, -1.0, 7.0}}); - - histos.add("nJetsPerEvent", "nJetsPerEvent", kTH1I, {{4, -0.5, 3.5}}); - histos.add("nGoodJets", "nGoodJets", kTH1I, {{4, -0.5, 3.5}}); + } + if (cfgJetdRHistos) { + histos.add("mcpjet_pt", "MC particle-level Jet pT (GeV/c)", kTH1F, {{2000, 0., 100.}}); + histos.add("mcpjet_eta", "MC particle-level Jet Eta", kTH1F, {{100, -1.0, 1.0}}); + histos.add("mcpjet_phi", "MC particle-level Jet Phi", kTH1F, {{80, -1.0, 7.0}}); + + histos.add("Gen_particle_All_BR", "Generated particle All pT (GeV/c)", kTH1F, {{2000, 0., 100.}}); + histos.add("Gen_particle_BR", "Gen_particle_BR", kTH1F, {minvAxis}); + histos.add("Gen_particle_pT", "Generated particle pT (GeV/c)", kTH1F, {{2000, 0., 100.}}); + + histos.add("dR_taggedjet_kaon", "dR between tagged jet and kaon wo pT cut", {HistType::kTH2F, {{60, 0., 1.5}, {100, 0., 20.}}}); + histos.add("dR_taggedjet_pion", "dR between tagged jet and pion wo pT cut", {HistType::kTH2F, {{60, 0., 1.5}, {100, 0., 20.}}}); + histos.add("dR_taggedjet_all", "dR between tagged jet and kpi", {HistType::kTH2F, {{60, 0., 1.5}, {100, 0., 20.}}}); + histos.add("dR_taggedjet_all_6_8", "dR between tagged jet and kpi 6 < jet pT < 8", {HistType::kTH2F, {{60, 0., 1.5}, {100, 0., 20.}}}); + + histos.add("missed_kpi_INJets_6_8", "missed kpi In Jets with 6 < jetPt < 8", {HistType::kTH2F, {{120, 0.0, 1.2}, {100, 0., 20.}}}); + histos.add("missed_kpi_INJets_8_10", "missed kpi In Jets with 8 < jetPt < 10", {HistType::kTH2F, {{120, 0.0, 1.2}, {100, 0., 20.}}}); + histos.add("missed_kpi_INJets_10_12", "missed kpi In Jets with 10 < jetPt < 12", {HistType::kTH2F, {{120, 0.0, 1.2}, {100, 0., 20.}}}); + histos.add("missed_kpi_INJets_12_15", "missed kpi In Jets with 12 < jetPt < 15", {HistType::kTH2F, {{120, 0.0, 1.2}, {100, 0., 20.}}}); + histos.add("missed_kpi_INJets_15_25", "missed kpi In Jets with 15 < jetPt < 25", {HistType::kTH2F, {{120, 0.0, 1.2}, {100, 0., 20.}}}); + histos.add("missed_kpi_INJets_25_infinite", "missed kpi In Jets with 25 < jetPt < infinite", {HistType::kTH2F, {{120, 0.0, 1.2}, {100, 0., 20.}}}); + histos.add("missed_kpi_INJets_8_infinite", "missed kpi In Jets with 8 < jetPt < infinite", {HistType::kTH2F, {{120, 0.0, 1.2}, {100, 0., 20.}}}); + + histos.add("recoveredJetpT_6_8to8_10", "recovered Jet pT", kTH1F, {{2000, 0., 100.}}); + histos.add("recoveredJetpT_6_8to8_10_kstarSpectra", "Kstar pT within the recovered Jet pT", kTH1F, {{2000, 0., 100.}}); + + histos.add("normalJetpT_8_kstarSpectra", "kstar pT in Jet > 8GeV/c", kTH1F, {{2000, 0., 100.}}); + histos.add("normalJetpT_6_8_kstarSpectra", "6 GeV/c < kstar pT in Jet < 8 GeV/c", kTH1F, {{2000, 0., 100.}}); + histos.add("normalJetpT_8_10_kstarSpectra", "8 GeV/c < kstar pT in Jet < 10 GeV/c", kTH1F, {{2000, 0., 100.}}); + histos.add("normalJetpT_10_12_kstarSpectra", "10 GeV/c < kstar pT in Jet < 12 GeV/c", kTH1F, {{2000, 0., 100.}}); + + histos.add("JetMigration", "bin to bin migration", {HistType::kTH2F, {{150, 0.0, 15.0, "True jet pT (GeV/c)"}, {150, 0., 15., "Recovered jet pT (GeV/c)"}}}); } //////////////////////////////////// @@ -247,10 +302,10 @@ struct kstarInOO { histos.add("hUSS_PiK_Mix", "hUSS_PiK_Mix", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); } if (cfgMCHistos) { - histos.add("nEvents_Gen", "nEvents_Gen", kTH1F, {{4, 0.0, 4.0}}); + histos.add("nEvents_Gen", "nEvents_Gen", kTH1F, {{7, 0.0, 7.0}}); histos.add("hUSS_TrueRec", "hUSS_TrueRec", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); - histos.add("hGen_pT_Raw", "Gen_pT_Raw (GeV/c)", kTH1F, {{800, 0., 40.}}); - histos.add("hGen_pT_GoodEv", "hGen_pT_GoodEv", kTHnSparseF, {cfgCentAxis, ptAxis}); + histos.add("hGen_pT_Kstar", "Gen_pT_Kstar (GeV/c)", kTH1F, {{800, 0., 40.}}); + histos.add("hRec_pT_Kstar", "Rec_pT_Kstar", kTHnSparseF, {cfgCentAxis, ptAxis}); } if (cfgJetHistos) { histos.add("hUSS_KPi_INSIDE", "hUSS_KPi_INSIDE", kTHnSparseF, {cfgCentAxis, dRAxis, ptAxis, minvAxis}); @@ -259,16 +314,15 @@ struct kstarInOO { histos.add("hLSS_PiK_INSIDE", "hLSS_PiK_INSIDE", kTHnSparseF, {cfgCentAxis, dRAxis, ptAxis, minvAxis}); } if (cfgJetMCHistos) { - histos.add("nEvents_Gen", "nEvents_Gen", kTH1F, {{7, -.0, 7.0}}); + histos.add("nEvents_Gen", "nEvents_Gen", kTH1F, {{7, 0.0, 7.0}}); histos.add("hUSS_TrueRec", "hUSS_TrueRec", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); histos.add("hUSS_TrueRec_INSIDE", "hUSS_TrueRec_INSIDE", kTHnSparseF, {cfgCentAxis, dRAxis, ptAxis, minvAxis}); - histos.add("hGen_pT_Raw", "Gen_pT_Raw (GeV/c)", kTH1F, {{800, 0., 40.}}); - histos.add("hGen_pT_GoodEv", "Gen_pT_GoodTrig (GeV/c)", kTH1F, {{800, 0., 40.}}); - histos.add("hGen_pT_GoodTrig", "Gen_pT_GoodTrig (GeV/c)", kTH1F, {{800, 0., 40.}}); - histos.add("hGen_pT_GoodEvTrig", "Gen_pT_GoodEvTrig (GeV/c)", kTH1F, {{800, 0., 40.}}); + histos.add("hGen_pT_Kstar", "Gen_pT_Kstar (GeV/c)", kTH1F, {{800, 0., 40.}}); + histos.add("hRec_pT_Kstar", "Rec_pT_Kstar (GeV/c)", kTH1F, {{800, 0., 40.}}); histos.add("hEffRec_pT", "EffRec_pT (GeV/c)", kTH1F, {{1600, 0., 80.}}); + histos.add("hEffRecTest0_pT", "EffRecTest0_pT (GeV/c)", kTH1F, {{800, 0., 40.}}); histos.add("hEffRecTest1_pT", "EffRecTest1_pT (GeV/c)", kTH1F, {{800, 0., 40.}}); histos.add("hEffRecTest2_pT", "EffRecTest2_pT (GeV/c)", kTH1F, {{800, 0., 40.}}); histos.add("hEffRecTest3_pT", "EffRecTest3_pT (GeV/c)", kTH1F, {{800, 0., 40.}}); @@ -277,29 +331,14 @@ struct kstarInOO { histos.add("hEffRecTest6_pT", "EffRecTest6_pT (GeV/c)", kTH1F, {{800, 0., 40.}}); histos.add("hEffRecTest7_pT", "EffRecTest7_pT (GeV/c)", kTH1F, {{800, 0., 40.}}); histos.add("hEffRecTest8_pT", "EffRecTest8_pT (GeV/c)", kTH1F, {{800, 0., 40.}}); - histos.add("hEffGen_pT", "EffGen_pT (GeV/c)", kTH1F, {{800, 0., 40.}}); + histos.add("hEffRecLowPtKstarDaughter", "EffRecLow Kstar daughter_pT (GeV/c)", kTH1F, {{800, 0., 40.}}); + + histos.add("hEffGen_pT", "EffGen_pT (GeV/c)", kTH1F, {{800, 0., 40.}}); histos.add("hMotherPdg1", "hMotherPdg1", kTH1F, {{5000, 0., 5000.}}); histos.add("hMotherPdg2", "hMotherPdg2", kTH1F, {{5000, 0., 5000.}}); } - std::shared_ptr hCutFlow = histos.get(HIST("hEvent_Cut")); - std::vector eventCutLabels = { - "All Events", - "sel8", - Form("|Vz| < %.1f", cfgEventVtxCut.value), - "kIsGoodZvtxFT0vsPV", - "kNoSameBunchPileup", - "kNoTimeFrameBorder", - "kNoITSROFrameBorder", - "kNoCollInTimeRangeStandard", - "kIsGoodITSLayersAll", - Form("Occupancy < %.0f", cfgOccupancyMax.value), - "All passed events"}; - for (size_t i = 0; i < eventCutLabels.size(); ++i) { - hCutFlow->GetXaxis()->SetBinLabel(i + 1, eventCutLabels[i].c_str()); - } - // Jet eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(static_cast(cfgEventSelections)); RealTriggerMaskBits = jetderiveddatautilities::initialiseTriggerMaskBits(cfgRealTriggerMasks); @@ -308,9 +347,9 @@ struct kstarInOO { triggerMaskBitsTest3 = jetderiveddatautilities::initialiseTriggerMaskBits(cfgTriggerMasksTest3); } // end of init - //====================== - //|| For LF Analysis - //====================== + //=============== + //| LF Analysis + //=============== using EventCandidates = soa::Join; //, aod::CentFT0Ms, aod::CentFT0As using EventCandidatesTrue = aod::McCollisions; using TrackCandidates = soa::Join; - //============== - //|| For jets - //============== + //================= + //|| Jet Analysis + //================= Filter JEPosZFilter = nabs(aod::jcollision::posZ) < cfgEventVtxCut; Filter JEMCPosZFilter = nabs(aod::jmccollision::posZ) < cfgEventVtxCut; - Filter jetCuts = aod::jet::pt > cfgJetpT&& aod::jet::r == nround(cfgJetR.node() * 100.0f); + Filter JetCuts = aod::jet::pt > cfgJetpT&& aod::jet::r == nround(cfgJetR.node() * 100.0f); - using JetTrackCandidates = soa::Join; using JetTrackCandidatesMC = soa::Join; - using JetFilteredJets = soa::Filtered>; - // For Mixed Event using BinningType = ColumnBinningPolicy; @@ -341,6 +377,10 @@ struct kstarInOO { double massKa = o2::constants::physics::MassKPlus; double massPi = o2::constants::physics::MassPiMinus; + static constexpr int Kstar0PDG = 313; + static constexpr int KaonPDG = 321; + static constexpr int PionPDG = 211; + //================================== //|| //|| Helper Templates @@ -360,19 +400,8 @@ struct kstarInOO { } } } // eventSelection histogram - if (objecttype == 2) { - if constexpr (requires { obj.posZ(); }) { - if (!pass) { - histos.fill(HIST("hPosZ_BC"), obj.posZ()); - histos.fill(HIST("hcentFT0C_BC"), obj.centFT0C()); - } else { - histos.fill(HIST("hPosZ_AC"), obj.posZ()); - histos.fill(HIST("hcentFT0C_AC"), obj.centFT0C()); - } - } - } // Jet eventSelection histogram if constexpr (requires { obj.tpcCrossedRowsOverFindableCls(); }) { - if (objecttype == 3) { + if (objecttype == 2) { if (!pass) { histos.fill(HIST("hDCArToPv_BC"), obj.dcaXY()); histos.fill(HIST("hDCAzToPv_BC"), obj.dcaZ()); @@ -400,7 +429,7 @@ struct kstarInOO { } } } // trackSelection - if (objecttype == 4) { + if (objecttype == 3) { if constexpr (requires { obj.pt(); }) { if (!pass) { histos.fill(HIST("QA_nSigma_kaon_TPC_BC"), obj.pt(), obj.tpcNSigmaKa()); @@ -413,7 +442,7 @@ struct kstarInOO { } } } // kaon pid Selection - if (objecttype == 5) { + if (objecttype == 4) { if constexpr (requires { obj.pt(); }) { if (!pass) { histos.fill(HIST("QA_nSigma_pion_TPC_BC"), obj.pt(), obj.tpcNSigmaPi()); @@ -559,10 +588,10 @@ struct kstarInOO { }; template - std::pair JeteventSelection(const EventType event, const bool QA) + std::pair JetEventSelection(const EventType event, const bool QA) { if (cfgEventCutQA && QA) { - fillQA(false, event, 2); + fillQA(false, event, 1); } if (!jetderiveddatautilities::selectCollision(event, eventSelectionBits)) { // sel8 @@ -572,7 +601,7 @@ struct kstarInOO { return {false, 2}; if (cfgEventCutQA && QA) { - fillQA(true, event, 2); + fillQA(true, event, 1); } return {true, 8}; }; @@ -581,7 +610,7 @@ struct kstarInOO { bool trackSelection(const TracksType track, const bool QA) { if (cfgTrackCutQA && QA) { - fillQA(false, track, 3); + fillQA(false, track, 2); } if (cfgTrackGlobalSel && !track.isGlobalTrack()) @@ -612,7 +641,7 @@ struct kstarInOO { return false; if (cfgTrackCutQA && QA) { - fillQA(true, track, 3); + fillQA(true, track, 2); } return true; }; @@ -625,7 +654,7 @@ struct kstarInOO { bool tpcPIDPassed{false}, tofPIDPassed{false}; if (cfgTrackCutQA && QA) { - fillQA(false, candidate, 4); + fillQA(false, candidate, 3); } // TPC @@ -665,7 +694,7 @@ struct kstarInOO { // TPC & TOF if (tpcPIDPassed && tofPIDPassed) { if (cfgTrackCutQA && QA) { - fillQA(true, candidate, 4); + fillQA(true, candidate, 3); } return true; } @@ -680,7 +709,7 @@ struct kstarInOO { bool tpcPIDPassed{false}, tofPIDPassed{false}; if (cfgTrackCutQA && QA) { - fillQA(false, candidate, 5); + fillQA(false, candidate, 4); } // TPC @@ -720,7 +749,7 @@ struct kstarInOO { // TPC & TOF if (tpcPIDPassed && tofPIDPassed) { if (cfgTrackCutQA && QA) { - fillQA(true, candidate, 5); + fillQA(true, candidate, 4); } return true; } @@ -732,10 +761,8 @@ struct kstarInOO { { if (!trackSelection(trk1, false) || !trackSelection(trk2, false)) return {}; - if (!trackPIDKaon(trk1, QA) || !trackPIDPion(trk2, QA)) return {}; - if (trk1.globalIndex() >= trk2.globalIndex()) return {}; @@ -751,8 +778,9 @@ struct kstarInOO { if (std::abs(lResonance.Eta()) > cfgTrackMaxEta) return {}; + return {lResonance}; - } + } // minvReconstruction template ROOT::Math::PxPyPzMVector TrueReconstruction(const TracksType& trk1, const TracksType& trk2) @@ -767,6 +795,9 @@ struct kstarInOO { if (!particle1.has_mothers() || !particle2.has_mothers()) { return {}; } + if (std::abs(particle1.eta()) > cfgTrackMaxEta || std::abs(particle2.eta()) > cfgTrackMaxEta) { + return {}; + } std::vector mothers1{}; std::vector mothers1PDG{}; @@ -782,27 +813,26 @@ struct kstarInOO { mothers2PDG.push_back(particle2_mom.pdgCode()); } - if (mothers1PDG[0] != 313) + if (mothers1PDG[0] != Kstar0PDG) return {}; // mother not K*0 - if (mothers2PDG[0] != 313) + if (mothers2PDG[0] != Kstar0PDG) return {}; // mothers not K*0 - if (mothers1[0] != mothers2[0]) return {}; // Kaon and pion not from the same K*0 - if (std::fabs(particle1.pdgCode()) != 211 && std::fabs(particle1.pdgCode()) != 321) + if (std::abs(particle1.pdgCode()) != PionPDG && std::abs(particle1.pdgCode()) != KaonPDG) return {}; - if (std::fabs(particle2.pdgCode()) != 211 && std::fabs(particle2.pdgCode()) != 321) + if (std::abs(particle2.pdgCode()) != PionPDG && std::abs(particle2.pdgCode()) != KaonPDG) return {}; double track1_mass, track2_mass; - if (std::fabs(particle1.pdgCode()) == 211) { + if (std::abs(particle1.pdgCode()) == PionPDG) { track1_mass = massPi; } else { track1_mass = massKa; } - if (std::fabs(particle2.pdgCode()) == 211) { + if (std::abs(particle2.pdgCode()) == PionPDG) { track2_mass = massPi; } else { track2_mass = massKa; @@ -813,15 +843,17 @@ struct kstarInOO { } ROOT::Math::PxPyPzMVector lTrueDaughter1, lTrueDaughter2, lTrueReso; - lTrueDaughter1 = ROOT::Math::PxPyPzMVector(trk1.px(), trk1.py(), trk1.pz(), track1_mass); - lTrueDaughter2 = ROOT::Math::PxPyPzMVector(trk2.px(), trk2.py(), trk2.pz(), track2_mass); + lTrueDaughter1 = ROOT::Math::PxPyPzMVector(particle1.px(), particle1.py(), particle1.pz(), track1_mass); + lTrueDaughter2 = ROOT::Math::PxPyPzMVector(particle2.px(), particle2.py(), particle2.pz(), track2_mass); lTrueReso = lTrueDaughter1 + lTrueDaughter2; if (lTrueReso.M() < 0) return {}; + if (std::abs(lTrueReso.Eta()) > cfgTrackMaxEta) + return {}; return {lTrueReso}; - } + } // TrueReconstruction template void TrackSlicing(const CollisionType& collision1, const TracksType&, const CollisionType& collision2, const TracksType&, const bool IsMix, const bool QA) @@ -872,7 +904,7 @@ struct kstarInOO { double DistinguishJets(const JetType& jets, ROOT::Math::PxPyPzMVector lResonance) { if (cDebugLevel > 0) - std::cout << "Finded multiple jets to the same phi." << std::endl; + LOG(info) << "Found multiple jets to the same phi."; double bestR = 0; double bestJetpT = 0; @@ -894,9 +926,9 @@ struct kstarInOO { template void JetTrackSlicing(aod::JetCollision const& collision, TracksType const& jetTracks, const JetType& chargedjets, const bool IsMix, const bool QA) { - //============================ - //| MB: Track Reconstruction - //============================ + //============= + //| Inclusive + //============= auto centrality = collision.centFT0C(); for (const auto& [track1, track2] : combinations(o2::soa::CombinationsUpperIndexPolicy(jetTracks, jetTracks))) { auto trk1 = track1.template track_as(); @@ -909,25 +941,28 @@ struct kstarInOO { fillMinv(objectType::MB, trk1, trk2, lResonance, centrality, -1.0, IsMix, flip); - //============================== - //| Jets: Track Reconstruction - //============================== + //======== + //| Jets + //======== bool jetFlag = false; int goodjets = 0; double jetpt = 0; + double R = 0; for (auto const& jet : chargedjets) { double phidiff = TVector2::Phi_mpi_pi(jet.phi() - lResonance.Phi()); double etadiff = jet.eta() - lResonance.Eta(); - double R = TMath::Sqrt((etadiff * etadiff) + (phidiff * phidiff)); + R = TMath::Sqrt((etadiff * etadiff) + (phidiff * phidiff)); + if (R < cfgJetR) { jetFlag = true; jetpt = jet.pt(); goodjets++; } - } + } // The loop of chargedjets if (cfgJetQAHistos) { histos.fill(HIST("nGoodJets"), goodjets); } + if (!cfgSingleJet) { if (goodjets > 1) { jetpt = DistinguishJets(chargedjets, lResonance); @@ -942,7 +977,7 @@ struct kstarInOO { } // JetTrackSlicing template - void JetTrackSlicingMC(aod::JetCollision const& collision, TracksType const& jetTracks, const JetType& chargedjets, const bool IsMix, const bool QA) + void JetTrackSlicingMC(aod::JetCollision const& collision, TracksType const& jetTracks, const JetType& mcdjets, const bool IsMix, const bool QA) { //============================ //| MB: Track Reconstruction @@ -961,14 +996,13 @@ struct kstarInOO { continue; fillMinv(objectType::MB, trk1, trk2, lResonance, centrality, -1.0, IsMix, flip); - //============================== //| Jets: Track Reconstruction //============================== bool jetFlag = false; int goodjets = 0; double jetpt = 0; - for (auto const& jet : chargedjets) { + for (auto const& jet : mcdjets) { double phidiff = TVector2::Phi_mpi_pi(jet.phi() - lResonance.Phi()); double etadiff = jet.eta() - lResonance.Eta(); double R = TMath::Sqrt((etadiff * etadiff) + (phidiff * phidiff)); @@ -983,26 +1017,13 @@ struct kstarInOO { } if (!cfgSingleJet) { if (goodjets > 1) { - jetpt = DistinguishJets(chargedjets, lResonance); + jetpt = DistinguishJets(mcdjets, lResonance); } } if (jetFlag) { fillMinv(objectType::Jets, trk1, trk2, lResonance, centrality, jetpt, IsMix, flip); } // jetFlag - - //=============================== - //| MB: Particle Reconstruction - //=============================== - auto lTrueReso = TrueReconstruction(trk1, trk2); - fillMinv(objectType::MBRecParticle, trk1, trk2, lTrueReso, centrality, -1.0, IsMix, false); - - //================================== - //| Jets: Particle Reconstruction - //================================== - if (jetFlag) { - fillMinv(objectType::JetsRecParticle, trk1, trk2, lTrueReso, centrality, jetpt, IsMix, false); - } // jetFlag } // filp } // Tracks loop } // JetTrackSlicingMC @@ -1012,19 +1033,39 @@ struct kstarInOO { //| JET DATA STUFF //| //======================================================= + using JetTrackCandidates = soa::Join; + using JetFilteredJets = soa::Filtered>; + int nJetEvents = 0; void processDataJets(o2::aod::JetCollision const& collision, JetFilteredJets const& chargedjets, JetTrackCandidates const& jetTracks, TrackCandidates const&) { if (cDebugLevel > 0) { nJetEvents++; - if ((nJetEvents + 1) % 10000 == 0) { - std::cout << "Processed Jet Data Events: " << nJetEvents << std::endl; + if ((nJetEvents + 1) % 10000 == 0) + LOG(info) << "Processed Jet Data Events: " << nJetEvents; + } + histos.fill(HIST("nEvents"), 0.5); // Raw event + + bool INELgt0 = false; + for (auto& jetTrack : jetTracks) { + if (std::abs(jetTrack.eta()) < cfgEventMaxEta) { + INELgt0 = true; + break; } } + if (!INELgt0) + return; + histos.fill(HIST("nEvents"), 1.5); // INEL>0 event - histos.fill(HIST("nEvents"), 0.5); // Raw event + auto [goodEv, code] = JetEventSelection(collision, true); + if (!goodEv) + return; + histos.fill(HIST("nEvents"), 2.5); // After selection // Trigger before we start jet finding + //===================== + //| Trigger + //===================== if (cfgCutonTrig) { bool RT = false; bool VTtest1 = false; @@ -1060,21 +1101,7 @@ struct kstarInOO { return; } } // Trigger cut - - histos.fill(HIST("nEvents"), 1.5); // Before passing the condition - - if (cfgManualEvSel) { - auto [goodEv, code] = JeteventSelection(collision, true); - if (!goodEv) - return; - } - - if (cfgJetEvSel) { - if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { - return; - } - } - histos.fill(HIST("nEvents"), 2.5); // Events after event quality selection for Inclusive + histos.fill(HIST("nEvents"), 3.5); // After trigger cut std::vector jetpT{}; std::vector jetEta{}; @@ -1082,6 +1109,9 @@ struct kstarInOO { bool HasJets = false; int nJets = 0; for (auto chargedjet : chargedjets) { + if (std::abs(chargedjet.eta()) > cfgJetMaxEta - cfgJetdR) + return; + jetpT.push_back(chargedjet.pt()); jetEta.push_back(chargedjet.eta()); jetPhi.push_back(chargedjet.phi()); @@ -1099,20 +1129,18 @@ struct kstarInOO { } //==================== - //|| Has Jets + //| Has Jets //==================== if (cfgReqJets) { if (!HasJets) return; } - histos.fill(HIST("nEvents"), 3.5); // Has jets + histos.fill(HIST("nEvents"), 4.5); // Has jets - bool INELgt0 = false; for (auto& jetTrack : jetTracks) { auto originTrack = jetTrack.track_as(); if (!trackSelection(originTrack, true)) continue; - INELgt0 = true; if (cfgJetQAHistos) { histos.fill(HIST("rawDimpT"), jetTrack.pt(), jetTrack.pt() - originTrack.pt()); @@ -1120,11 +1148,8 @@ struct kstarInOO { histos.fill(HIST("jetTrackPhi"), jetTrack.phi()); } } // jetTrack loop - if (!INELgt0) - return; JetTrackSlicing(collision, jetTracks, chargedjets, false, true); - } // ProcessDataJets PROCESS_SWITCH(kstarInOO, processDataJets, "process Data Jets", false); @@ -1134,37 +1159,35 @@ struct kstarInOO { //| //======================================================= int nJetMCEvents = 0; - void processMCJets(o2::aod::JetCollision const& collision, soa::Filtered const& mcdjets, JetTrackCandidatesMC const& jetTracks, TrackCandidatesMC const&, aod::McParticles const&) + void processMCJets(o2::aod::JetCollision const& collision, JetTrackCandidatesMC const& jetTracks, soa::Filtered const& mcdjets, TrackCandidatesMC const&, aod::McParticles const&, aod::JetParticles const&) { if (cDebugLevel > 0) { nJetMCEvents++; - if ((nJetMCEvents + 1) % 10000 == 0) { - std::cout << "Processed Jet MC Events: " << nJetMCEvents << std::endl; - } - } - histos.fill(HIST("nEvents"), 0.5); // Raw event - - if (std::abs(collision.posZ()) > cfgEventVtxCut) - return; - - if (!jetderiveddatautilities::selectTrigger(collision, RealTriggerMaskBits)) - return; - if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { - return; + if ((nJetMCEvents + 1) % 10000 == 0) + LOG(info) << "Processed Jet MC Events: " << nJetMCEvents; } - histos.fill(HIST("nEvents"), 1.5); // Before passing the condition + histos.fill(HIST("nEvents"), 0.5); // Gen event bool INELgt0 = false; for (auto& jetTrack : jetTracks) { - if (std::fabs(jetTrack.eta()) < cfgTrackMaxEta) { + if (std::abs(jetTrack.eta()) < cfgEventMaxEta) { INELgt0 = true; break; } } // jetTrack loop if (!INELgt0) return; + histos.fill(HIST("nEvents"), 1.5); // INEL>0 event + + auto [goodEv, code] = JetEventSelection(collision, true); + if (!goodEv) + return; + histos.fill(HIST("nEvents"), 2.5); // Inclusive event - histos.fill(HIST("nEvents"), 2.5); // Events after event quality selection for Inclusive + // The trigger option doesn't work + // if (!jetderiveddatautilities::selectTrigger(collision, RealTriggerMaskBits)) + // return; + // histos.fill(HIST("nEvents"), 3.5); // Events for Inclusive std::vector mcdjetpT{}; std::vector mcdjetEta{}; @@ -1173,6 +1196,9 @@ struct kstarInOO { bool HasJets = false; int nJets = 0; for (auto mcdjet : mcdjets) { + if (std::abs(mcdjet.eta()) > cfgJetMaxEta - cfgJetdR) + return; + mcdjetpT.push_back(mcdjet.pt()); mcdjetEta.push_back(mcdjet.eta()); mcdjetPhi.push_back(mcdjet.phi()); @@ -1191,17 +1217,18 @@ struct kstarInOO { } //==================== - //|| Has Jets + //| Has Jets //==================== if (cfgReqJets) { if (!HasJets) { return; } } - histos.fill(HIST("nEvents"), 3.5); // Has jets + histos.fill(HIST("nEvents"), 3.5); // Jet event - // JetTrackSlicingMC(collision, jetTracks, chargedjets, false, true); + // JetTrackSlicingMC(collision, jetTracks, mcdjets, false, true); + // Instead of using "JetTrackSlicingMC", Once we have to test showing the distribution each condition for (auto& [track1, track2] : combinations(o2::soa::CombinationsUpperIndexPolicy(jetTracks, jetTracks))) { auto trk1 = track1.track_as(); auto trk2 = track2.track_as(); @@ -1212,19 +1239,30 @@ struct kstarInOO { lDecayDaughterTest2 = ROOT::Math::PxPyPzMVector(trk2.px(), trk2.py(), trk2.pz(), massPi); lResonanceTest1 = lDecayDaughterTest1 + lDecayDaughterTest2; + if (cfgJetMCHistos) { + histos.fill(HIST("hEffRecTest0_pT"), lResonanceTest1.Pt()); + } + if (!trk1.has_mcParticle() || !trk2.has_mcParticle()) continue; if (cfgJetMCHistos) { histos.fill(HIST("hEffRecTest1_pT"), lResonanceTest1.Pt()); } - if (!trackSelection(trk1, true) || !trackSelection(trk2, false)) - continue; + ////////////////////////////// + ////////////////////////////// + if (cfgReqMcEffTrackQA) { // false, true + if (!trackSelection(trk1, true) || !trackSelection(trk2, false)) + continue; + } + ////////////////////////////// + ////////////////////////////// + if (cfgJetMCHistos) { histos.fill(HIST("hEffRecTest2_pT"), lResonanceTest1.Pt()); } - if (cfgReqMcEffPID) { + if (cfgReqMcEffPID) { // false, true if (!trackPIDKaon(trk1, true) || !trackPIDPion(trk2, true)) continue; } @@ -1253,7 +1291,7 @@ struct kstarInOO { } if (cfgJetMCHistos) { - histos.fill(HIST("hMotherPdg1"), std::fabs(mothers1PDG[0])); + histos.fill(HIST("hMotherPdg1"), std::abs(mothers1PDG[0])); } std::vector mothers2{}; std::vector mothers2PDG{}; @@ -1262,7 +1300,7 @@ struct kstarInOO { mothers2PDG.push_back(particle2_mom.pdgCode()); } if (cfgJetMCHistos) { - histos.fill(HIST("hMotherPdg2"), std::fabs(mothers2PDG[0])); + histos.fill(HIST("hMotherPdg2"), std::abs(mothers2PDG[0])); } if (mothers1[0] != mothers2[0]) @@ -1272,32 +1310,37 @@ struct kstarInOO { histos.fill(HIST("hEffRecTest5_pT"), lResonanceTest1.Pt()); } - if (std::fabs(particle1.pdgCode()) != 321) // kaon + if (std::abs(particle1.pdgCode()) != KaonPDG) // kaon continue; if (cfgJetMCHistos) { histos.fill(HIST("hEffRecTest6_pT"), lResonanceTest1.Pt()); } - if (std::fabs(particle2.pdgCode()) != 211) // pion + if (std::abs(particle2.pdgCode()) != PionPDG) // pion continue; if (cfgJetMCHistos) { histos.fill(HIST("hEffRecTest7_pT"), lResonanceTest1.Pt()); } - if (std::fabs(mothers1PDG[0]) != 313) + if (std::abs(mothers1PDG[0]) != Kstar0PDG) continue; // mother not K*0 if (cfgJetMCHistos) { histos.fill(HIST("hEffRecTest8_pT"), lResonanceTest1.Pt()); + if (lResonanceTest1.Pt() < 0.4) { + histos.fill(HIST("hEffRecLowPtKstarDaughter"), lDecayDaughterTest1.Pt()); + histos.fill(HIST("hEffRecLowPtKstarDaughter"), lDecayDaughterTest2.Pt()); + } } - if (std::fabs(mothers2PDG[0]) != 313) + if (std::abs(mothers2PDG[0]) != Kstar0PDG) continue; // mothers not K*0 if (cfgJetMCHistos) { histos.fill(HIST("hEffRec_pT"), lResonanceTest1.Pt()); } + } // track loop } // process loop PROCESS_SWITCH(kstarInOO, processMCJets, "process MC Jets", false); @@ -1312,29 +1355,33 @@ struct kstarInOO { { if (cDebugLevel > 0) { nEvents++; - if ((nEvents + 1) % 10000 == 0) { - std::cout << "Processed Data Events: " << nEvents << std::endl; - } + if ((nEvents + 1) % 10000 == 0) + LOG(info) << "Processed Data Events: " << nEvents; } - - auto [goodEv, code] = eventSelection(collision, true); histos.fill(HIST("nEvents"), 0.5); - if (!goodEv) - return; - bool INELgt0 = false; for (const auto& track : tracks) { - if (!trackSelection(track, true)) - continue; - if (std::fabs(track.eta()) < cfgTrackMaxEta) { + if (std::abs(track.eta()) < cfgEventMaxEta) { INELgt0 = true; + break; } } if (!INELgt0) return; histos.fill(HIST("nEvents"), 1.5); + auto [goodEv, code] = eventSelection(collision, true); + if (!goodEv) + return; + histos.fill(HIST("nEvents"), 2.5); + + // for trackQA plot + for (const auto& track : tracks) { + if (!trackSelection(track, true)) + continue; + } + TrackSlicing(collision, tracks, collision, tracks, false, true); } // processSameEvents @@ -1354,18 +1401,17 @@ struct kstarInOO { for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { if (cDebugLevel > 0) { nEventsMix++; - if ((nEventsMix + 1) % 10000 == 0) { - std::cout << "Processed DATA Mixed Events : " << nEventsMix << std::endl; - } + if ((nEventsMix + 1) % 10000 == 0) + LOG(info) << "Processed DATA Mixed Events : " << nEventsMix; } auto [goodEv1, code1] = eventSelection(collision1, false); auto [goodEv2, code2] = eventSelection(collision2, false); bool VtxMixFlag = false; bool CentMixFlag = false; // bool OccupanacyMixFlag = false; - if (std::fabs(collision1.posZ() - collision2.posZ()) <= cfgVtxMixCut) // set default to maybe 10 + if (std::abs(collision1.posZ() - collision2.posZ()) <= cfgVtxMixCut) // set default to maybe 10 VtxMixFlag = true; - if (std::fabs(collision1.centFT0C() - collision2.centFT0C()) <= cfgVtxMixCut) // set default to maybe 10 + if (std::abs(collision1.centFT0C() - collision2.centFT0C()) <= cfgVtxMixCut) // set default to maybe 10 CentMixFlag = true; if (!goodEv1 || !goodEv2) @@ -1392,30 +1438,34 @@ struct kstarInOO { nEventsMC++; if ((nEventsMC + 1) % 10000 == 0) { double histmem = histos.getSize(); - std::cout << histmem << std::endl; - std::cout << "process_SameEvent_MC: " << nEventsMC << std::endl; + LOG(info) << histmem; + LOG(info) << "process_SameEvent_MC: " << nEventsMC; } } - auto [goodEv, code] = eventSelection(collision, true); - histos.fill(HIST("nEvents"), 0.5); - if (!goodEv) - return; - bool INELgt0 = false; for (const auto& track : tracks) { - if (!trackSelection(track, true)) - continue; - if (std::fabs(track.eta()) < cfgTrackMaxEta) { + if (std::abs(track.eta()) < cfgEventMaxEta) { INELgt0 = true; + break; } } if (!INELgt0) return; - histos.fill(HIST("nEvents"), 1.5); + auto [goodEv, code] = eventSelection(collision, true); // sel8 & vtx + if (!goodEv) + return; + histos.fill(HIST("nEvents"), 2.5); + + // for trackQA plot + for (const auto& track : tracks) { + if (!trackSelection(track, true)) + continue; + } + TrackSlicingMC(collision, tracks, collision, tracks, false, true); } // processSameEvents_MC PROCESS_SWITCH(kstarInOO, processSameEventMC, "process Same Event MC", false); @@ -1434,9 +1484,8 @@ struct kstarInOO { for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { if (cDebugLevel > 0) { nEventsMCMix++; - if ((nEventsMCMix + 1) % 10000 == 0) { - std::cout << "Processed Mixed Events: " << nEventsMCMix << std::endl; - } + if ((nEventsMCMix + 1) % 10000 == 0) + LOG(info) << "Processed Mixed Events: " << nEventsMCMix; } auto [goodEv1, code1] = eventSelection(collision1, false); auto [goodEv2, code2] = eventSelection(collision2, false); @@ -1459,62 +1508,90 @@ struct kstarInOO { { if (cDebugLevel > 0) { ++nEventsGen; - if (nEventsGen % 10000 == 0) { - std::cout << "Processed MC (GEN) Events: " << nEventsGen << std::endl; - } + if (nEventsGen % 10000 == 0) + LOG(info) << "Processed MC (GEN) Events: " << nEventsGen; + } + if (cfgMCHistos) { + histos.fill(HIST("nEvents_Gen"), 0.5); // Gen events } + //======================= - //|| Event & Signal loss + //| Event & Signal loss //======================= + bool INELgt0 = false; + for (auto& particle : mcParticles) { + if (std::abs(particle.eta()) > cfgEventMaxEta) + continue; + if (particle.pt() <= 0.0) + continue; + INELgt0 = true; + break; + } + if (cfgForceTrueINELgt) { + if (!INELgt0) { + return; + } + } if (cfgMCHistos) { - histos.fill(HIST("nEvents_Gen"), 0.5); + histos.fill(HIST("nEvents_Gen"), 1.5); // INEL>0 Gen events & EL: denominator } + if (std::abs(collision.posZ()) > cfgEventVtxCut) + return; + for (auto& particle : mcParticles) { - if (particle.pdgCode() != 313) + if (std::abs(particle.pdgCode()) != Kstar0PDG) continue; - if (std::fabs(particle.eta()) > cfgTrackMaxEta) + if (std::abs(particle.eta()) > cfgTrackMaxEta) continue; - if (fabs(collision.posZ()) > cfgEventVtxCut) - break; if (cfgMCHistos) { - histos.fill(HIST("hGen_pT_Raw"), particle.pt()); + histos.fill(HIST("hGen_pT_Kstar"), particle.pt()); // SL: denominator } - } // Unreconstructed collisions(=Raw coll) for correction + } // Gen colls if (recocolls.size() <= 0) { // not reconstructed if (cfgForceGenReco) { return; } } + + //================= + //| Efficiency + //================= double centrality = -1; - for (auto& recocoll : recocolls) { - centrality = recocoll.centFT0C(); + bool hasGoodEv = false; + for (auto& recocoll : recocolls) { // poorly reconstructed auto [goodEv, code] = eventSelection(recocoll, true); - - if (cfgMCHistos) { - histos.fill(HIST("nEvents_Gen"), 1.5); - } + if (recocoll.posZ() > cfgEventVtxCut) + goodEv = false; if (!goodEv) continue; - } // recocolls (=reconstructed collisions) - //================= - //|| Efficiency - //================= + hasGoodEv = true; + centrality = recocoll.centFT0C(); + break; + } // recocolls + if (!hasGoodEv) + return; + if (cfgMCHistos) { + histos.fill(HIST("nEvents_Gen"), 2.5); // EL: numerator + } + for (auto& particle : mcParticles) { - if (particle.pdgCode() != 313) + if (std::abs(particle.pdgCode()) != Kstar0PDG) continue; // Not K*0 - if (std::fabs(particle.eta()) > cfgTrackMaxEta) + if (std::abs(particle.eta()) > cfgTrackMaxEta) + continue; + if (particle.pt() < cfgTrackMinPt) continue; if (cfgMCHistos) { - histos.fill(HIST("nEvents_Gen"), 2.5); - histos.fill(HIST("hGen_pT_GoodEv"), centrality, particle.pt()); - } // cfgMCHistos + histos.fill(HIST("hRec_pT_Kstar"), centrality, particle.pt()); // SL: numerator // eff: denominator + } + } // loop over particles - } // processMCTrue + } // processGen PROCESS_SWITCH(kstarInOO, processGen, "process Generated Particles", false); //============================================== @@ -1523,97 +1600,76 @@ struct kstarInOO { //| //============================================== int nprocessGenEvents = 0; - void processJetsGen(o2::aod::JetMcCollision const& collision, soa::SmallGroups> const& recocolls, aod::JetParticles const& mcParticles) + void processGenJets(o2::aod::JetMcCollision const& collision, soa::SmallGroups> const& recocolls, aod::JetParticles const& mcParticles) { if (cDebugLevel > 0) { ++nprocessGenEvents; - if (nprocessGenEvents % 10000 == 0) { - std::cout << "Processed MC (GEN) Events: " << nprocessGenEvents << std::endl; - } + if (nprocessGenEvents % 10000 == 0) + LOG(info) << "Processed MC (GEN) Events: " << nprocessGenEvents; + } + if (cfgJetMCHistos) { + histos.fill(HIST("nEvents_Gen"), 0.5); } //======================= - //|| Event & Signal loss + //| Event & Signal loss //======================= + bool INELgt0 = false; + for (auto& particle : mcParticles) { + if (std::abs(particle.eta()) > cfgEventMaxEta) + continue; + if (particle.pt() <= 0.0) + continue; + INELgt0 = true; + break; + } + if (cfgForceTrueINELgt) { + if (!INELgt0) { + return; + } + } if (cfgJetMCHistos) { - histos.fill(HIST("nEvents_Gen"), 0.5); + histos.fill(HIST("nEvents_Gen"), 1.5); // EL: denominator } + if (std::abs(collision.posZ()) > cfgEventVtxCut) + return; + for (auto& particle : mcParticles) { - if (particle.pdgCode() != 313) + if (std::abs(particle.pdgCode()) != Kstar0PDG) continue; - if (std::fabs(particle.eta()) > cfgTrackMaxEta) + if (std::abs(particle.eta()) > cfgTrackMaxEta) continue; - if (fabs(collision.posZ()) > cfgEventVtxCut) - break; if (cfgJetMCHistos) { - histos.fill(HIST("hGen_pT_Raw"), particle.pt()); + histos.fill(HIST("hGen_pT_Kstar"), particle.pt()); // SL: denominator } - } // Unrecon. collision(=Raw coll) for correction + } // Unreco. if (recocolls.size() <= 0) { // not reconstructed return; } - - for (auto& recocoll : recocolls) { // poorly reconstructed - if (recocoll.posZ() > cfgEventVtxCut) - continue; - auto goodEv = jetderiveddatautilities::selectCollision(recocoll, eventSelectionBits); - auto goodTrig = jetderiveddatautilities::selectTrigger(recocoll, RealTriggerMaskBits); - for (auto& particle : mcParticles) { - if (particle.pdgCode() != 313) - continue; - if (std::fabs(particle.eta()) > cfgTrackMaxEta) - continue; - if (cfgJetMCHistos) { - // check K* PID - if (goodEv) { - histos.fill(HIST("hGen_pT_GoodEv"), particle.pt()); - - } // goodEv - - if (goodTrig) { - histos.fill(HIST("hGen_pT_GoodTrig"), particle.pt()); - - } // goodTrig - - if (goodEv && goodTrig) { - histos.fill(HIST("hGen_pT_GoodEvTrig"), particle.pt()); - - if (cfgJetQAHistos) { - histos.fill(HIST("nTriggerQA"), 7.5); - } - - } // goodEvTrig - } // cfgJetMCHistos - } // mcParticles - } // recocolls (=reconstructed collisions) - //================= - //|| Efficiency + //| Efficiency //================= - // if (fabs(collision.posZ()) > cfgEventVtxCut) - // return; - for (auto& recocoll : recocolls) { // poorly reconstructed auto goodEv = jetderiveddatautilities::selectCollision(recocoll, eventSelectionBits); if (goodEv) { goodEv = jetderiveddatautilities::selectTrigger(recocoll, RealTriggerMaskBits); } - if (cfgJetMCHistos) { - histos.fill(HIST("nEvents_Gen"), 1.5); - } + if (std::abs(recocoll.posZ()) > cfgEventVtxCut) + goodEv = false; + if (!goodEv) return; - } + } // reco.coll if (cfgJetMCHistos) { - histos.fill(HIST("nEvents_Gen"), 2.5); + histos.fill(HIST("nEvents_Gen"), 2.5); // EL: numerator } for (auto& particle : mcParticles) { - if (particle.pdgCode() != 313) + if (std::abs(particle.pdgCode()) != Kstar0PDG) continue; - if (std::fabs(particle.eta()) > cfgTrackMaxEta) + if (std::abs(particle.eta()) > cfgTrackMaxEta) continue; if (particle.pt() < cfgTrackMinPt) continue; @@ -1622,12 +1678,12 @@ struct kstarInOO { if (cfg_Force_BR) { bool baddecay = false; for (auto& phidaughter : particle.daughters_as()) { - if (std::fabs(phidaughter.pdgCode()) != 321) { + if (std::abs(phidaughter.pdgCode()) != 321) { baddecay = true; break; } if (cfg_Force_Kaon_Acceptence) { - if (std::fabs(phidaughter.eta()) > cfg_Track_MaxEta) { + if (std::abs(phidaughter.eta()) > cfg_Track_MaxEta) { baddecay = true; break; } @@ -1640,20 +1696,226 @@ struct kstarInOO { */ if (cfgJetMCHistos) { - histos.fill(HIST("nEvents_Gen"), 3.5); - histos.fill(HIST("hEffGen_pT"), particle.pt()); - } // cfgJetMCHistos + histos.fill(HIST("hRec_pT_Kstar"), particle.pt()); // SL: numerator and eff: denominator + } + } // loop over particles } // end of process - PROCESS_SWITCH(kstarInOO, processJetsGen, "Process Generated Particles Inclusive&Jets", false); + PROCESS_SWITCH(kstarInOO, processGenJets, "Process Generated Particles Inclusive&Jets", false); - void processEventsDummy(EventCandidates::iterator const&, TrackCandidates const&) + int ndRtest = 0; + void processJetQA(o2::aod::JetMcCollision const& collision, soa::Filtered const& mcpjets, aod::JetParticles const& mcParticles, aod::McParticles const&) { - return; - } - PROCESS_SWITCH(kstarInOO, processEventsDummy, "dummy", false); -}; // kstarInOO + if (cDebugLevel > 0) { + ++ndRtest; + if (ndRtest % 10000 == 0) + LOG(info) << "Processed dR test: " << ndRtest; + } + + bool INELgt0 = false; + for (auto& mcpjet : mcpjets) { + if (std::abs(mcpjet.eta()) > cfgEventMaxEta) + continue; + if (mcpjet.pt() <= 0.0) + continue; + INELgt0 = true; + break; + } // Selection event through mcpjet loop + if (!INELgt0) + return; + + if (std::abs(collision.posZ()) > cfgEventVtxCut) + return; + histos.fill(HIST("nEvents"), 0.5); + + for (auto& mcParticle : mcParticles) { + if (std::abs(mcParticle.eta()) > cfgTrackMaxEta) + continue; + if (!mcParticle.has_daughters()) + continue; + + ROOT::Math::PxPyPzEVector lResonance; + lResonance = ROOT::Math::PxPyPzEVector(mcParticle.px(), mcParticle.py(), mcParticle.pz(), mcParticle.e()); + + int GenPID = 0; + if (!cfgIsKstar) + GenPID = 333; + else + GenPID = 313; + + if (std::abs(mcParticle.pdgCode()) != GenPID) + continue; + + if (cfgJetdRHistos) { + histos.fill(HIST("Gen_particle_All_BR"), mcParticle.pt()); + } + + bool skip = false; + int daughter_kaon = 0; + int daughter_pion = 0; + + if (!cfgIsKstar) { + for (auto& daughter : mcParticle.daughters_as()) { + if (std::abs(daughter.pdgCode()) != KaonPDG) + skip = true; + } + } else { + for (auto& daughter : mcParticle.daughters_as()) { + if (std::abs(daughter.pdgCode()) == KaonPDG) + ++daughter_kaon; + else if (std::abs(daughter.pdgCode()) == PionPDG) + ++daughter_pion; + } + if (daughter_kaon != 1 || daughter_pion != 1) + skip = true; + } // K*(892) + + if (skip && cfgBR) + continue; + + if (cfgJetdRHistos) { + histos.fill(HIST("Gen_particle_BR"), lResonance.M()); + histos.fill(HIST("Gen_particle_pT"), mcParticle.pt()); + } + + //================== + // Distinguish Jets + double bestR = 999; + double bestJetpT = 0; + double bestJetPhi = 0; + double bestJetEta = 0; + for (auto& mcpjet : mcpjets) { + if (mcpjet.pt() < cfgJetpT) + continue; + + if (cfgJetdRHistos) { + histos.fill(HIST("mcpjet_eta"), mcpjet.eta()); + histos.fill(HIST("mcpjet_phi"), mcpjet.phi()); + histos.fill(HIST("mcpjet_pt"), mcpjet.pt()); + } + + double dphi = TVector2::Phi_mpi_pi(mcpjet.phi() - lResonance.Phi()); + double deta = mcpjet.eta() - lResonance.Eta(); + double R = TMath::Sqrt((dphi * dphi) + (deta * deta)); + if (R < bestR) { + bestR = R; + bestJetpT = mcpjet.pt(); + bestJetPhi = mcpjet.phi(); + bestJetEta = mcpjet.eta(); + } + } // mcpJets + if (bestR > cfgJetdR) + continue; + + //================== + // daughters + double missing_pt = 0; + double dR_kaon, dR_pion; + bool kaon_out = false; + bool pion_out = false; + for (auto& daughter : mcParticle.daughters_as()) { + if (cfgIsKstar) { + if (std::abs(daughter.pdgCode()) == KaonPDG) { + + double dphi_kaon = TVector2::Phi_mpi_pi(bestJetPhi - daughter.phi()); + double deta_kaon = bestJetEta - daughter.eta(); + dR_kaon = TMath::Sqrt((dphi_kaon * dphi_kaon) + (deta_kaon * deta_kaon)); + + if (bestR < cfgJetdR) { + if (cfgJetdRHistos) { + histos.fill(HIST("dR_taggedjet_kaon"), dR_kaon, lResonance.Pt()); + histos.fill(HIST("dR_taggedjet_all"), dR_kaon, lResonance.Pt()); + } + if (dR_kaon > cfgJetdR) { + kaon_out = true; + missing_pt += daughter.pt(); + } + } // INSIDE Jets + } // kaon daughter + if (std::abs(daughter.pdgCode()) == PionPDG) { + + double dphi_pion = TVector2::Phi_mpi_pi(bestJetPhi - daughter.phi()); + double deta_pion = bestJetEta - daughter.eta(); + dR_pion = TMath::Sqrt((dphi_pion * dphi_pion) + (deta_pion * deta_pion)); + + if (bestR < cfgJetdR) { + if (cfgJetdRHistos) { + histos.fill(HIST("dR_taggedjet_pion"), dR_pion, lResonance.Pt()); + histos.fill(HIST("dR_taggedjet_all"), dR_pion, lResonance.Pt()); + + if (bestJetpT > 6.0 && bestJetpT < 8.0) + histos.fill(HIST("dR_taggedjet_all_6_8"), dR_pion, lResonance.Pt()); + } + if (dR_pion > cfgJetdR) { + pion_out = true; + missing_pt += daughter.pt(); + } + } // INSIDE Jets + } // pion daughter + } else { + if (std::abs(daughter.pdgCode()) == KaonPDG) { + double dphi_kaon = TVector2::Phi_mpi_pi(bestJetPhi - daughter.phi()); + double deta_kaon = bestJetEta - daughter.eta(); + dR_kaon = TMath::Sqrt((dphi_kaon * dphi_kaon) + (deta_kaon * deta_kaon)); + + if (bestR < cfgJetdR) { + if (cfgJetdRHistos) { + histos.fill(HIST("dR_taggedjet_kaon"), dR_kaon, lResonance.Pt()); + histos.fill(HIST("dR_taggedjet_all"), dR_kaon, lResonance.Pt()); + + if (bestJetpT > 6.0 && bestJetpT < 8.0) + histos.fill(HIST("dR_taggedjet_all_6_8"), dR_kaon, lResonance.Pt()); + } + + if (dR_kaon > cfgJetdR) { + kaon_out = true; + missing_pt = daughter.pt(); + } + } + } // kaon daughter + } // phi(1020) + } // daughter + + if (kaon_out || pion_out) { + double recoveredJetpT = bestJetpT + missing_pt; + if (cfgJetdRHistos) { + if (bestJetpT > 6.0 && bestJetpT < 8.0) { + histos.fill(HIST("normalJetpT_6_8_kstarSpectra"), lResonance.Pt()); + histos.fill(HIST("missed_kpi_INJets_6_8"), (bestJetpT - missing_pt) / bestJetpT, lResonance.Pt()); + if (recoveredJetpT > 8.0) { + histos.fill(HIST("recoveredJetpT_6_8to8_10"), recoveredJetpT); + histos.fill(HIST("recoveredJetpT_6_8to8_10_kstarSpectra"), lResonance.Pt()); + } + } + + if (bestJetpT > 8.0 && bestJetpT < 10.0) { + histos.fill(HIST("missed_kpi_INJets_8_10"), (bestJetpT - missing_pt) / bestJetpT, lResonance.Pt()); + histos.fill(HIST("normalJetpT_8_10_kstarSpectra"), lResonance.Pt()); + } + if (bestJetpT > 10.0 && bestJetpT < 12.0) { + histos.fill(HIST("missed_kpi_INJets_10_12"), (bestJetpT - missing_pt) / bestJetpT, lResonance.Pt()); + histos.fill(HIST("normalJetpT_10_12_kstarSpectra"), lResonance.Pt()); + } + if (bestJetpT > 12.0 && bestJetpT < 15.0) + histos.fill(HIST("missed_kpi_INJets_12_15"), (bestJetpT - missing_pt) / bestJetpT, lResonance.Pt()); + if (bestJetpT > 15.0 && bestJetpT < 25.0) + histos.fill(HIST("missed_kpi_INJets_15_25"), (bestJetpT - missing_pt) / bestJetpT, lResonance.Pt()); + if (bestJetpT > 25.0) + histos.fill(HIST("missed_kpi_INJets_25_infinite"), (bestJetpT - missing_pt) / bestJetpT, lResonance.Pt()); + + if (bestJetpT > 8.0) { + histos.fill(HIST("missed_kpi_INJets_8_infinite"), (bestJetpT - missing_pt) / bestJetpT, lResonance.Pt()); + histos.fill(HIST("normalJetpT_8_kstarSpectra"), lResonance.Pt()); + } + histos.fill(HIST("JetMigration"), bestJetpT, recoveredJetpT); + } // cfgJetdRHistos + } // kaon_out || pion_out + } // mcParticles + }; + + PROCESS_SWITCH(kstarInOO, processJetQA, "Process dR of K*0 Inclusive and Inside jet", false); +}; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; -}; +} diff --git a/PWGLF/Tasks/Resonances/kstarpbpb.cxx b/PWGLF/Tasks/Resonances/kstarpbpb.cxx index 851ee73a728..0a36e123a3d 100644 --- a/PWGLF/Tasks/Resonances/kstarpbpb.cxx +++ b/PWGLF/Tasks/Resonances/kstarpbpb.cxx @@ -8,13 +8,16 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -// sourav.kundu@cern.ch , sarjeeta.gami@cern.ch + +/// \file kstarpbpb.cxx +/// \brief Code for K*(892)^0 resonance flow and spin alignment analysis +/// \author sourav.kundu@cern.ch , sarjeeta.gami@cern.ch +/// #include "PWGLF/DataModel/EPCalibrationTables.h" #include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/RCTSelectionFlags.h" -#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -24,6 +27,7 @@ #include #include +#include #include #include #include @@ -44,7 +48,7 @@ #include #include #include -#include +#include #include #include @@ -59,15 +63,15 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::aod::rctsel; -struct kstarpbpb { +struct Kstarpbpb { struct : ConfigurableGroup { Configurable cfgURL{"cfgURL", "http://alice-ccdb.cern.ch", "Address of the CCDB to browse"}; - Configurable nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "Latest acceptable timestamp of creation for the object"}; + Configurable nolaterthan{"nolaterthan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "Latest acceptable timestamp of creation for the object"}; } cfgCcdbParam; // Enable access to the CCDB for the offset and correction constants and save them in dedicated variables. - Service ccdb; + Service ccdb{}; o2::ccdb::CcdbApi ccdbApi; // Service pdg; struct RCTCut : ConfigurableGroup { @@ -93,16 +97,14 @@ struct kstarpbpb { Configurable cfgCutCentrality{"cfgCutCentrality", 80.0f, "Accepted maximum Centrality"}; // track Configurable cfgCutCharge{"cfgCutCharge", 0.0, "cut on Charge"}; - Configurable additionalEvSel2{"additionalEvSel2", true, "Additional evsel2"}; - Configurable additionalEvSel3{"additionalEvSel3", true, "Additional evsel3"}; Configurable cfgCutPT{"cfgCutPT", 0.2, "PT cut on daughter track"}; Configurable cfgCutEta{"cfgCutEta", 0.8, "Eta cut on daughter track"}; Configurable cfgCutDCAxy{"cfgCutDCAxy", 2.0f, "DCAxy range for tracks"}; Configurable cfgCutDCAz{"cfgCutDCAz", 2.0f, "DCAz range for tracks"}; Configurable useGlobalTrack{"useGlobalTrack", true, "use Global track"}; Configurable usepolar{"usepolar", true, "flag to fill type of SA"}; - Configurable nsigmaCutTOF{"nsigmacutTOF", 3.0, "Value of the TOF Nsigma cut"}; - Configurable nsigmaCutTPC{"nsigmacutTPC", 3.0, "Value of the TPC Nsigma cut"}; + Configurable nsigmaCutTOF{"nsigmaCutTOF", 3.0, "Value of the TOF Nsigma cut"}; + Configurable nsigmaCutTPC{"nsigmaCutTPC", 3.0, "Value of the TPC Nsigma cut"}; Configurable isTOFOnly{"isTOFOnly", false, "use TOF only PID"}; Configurable nsigmaCutCombined{"nsigmaCutCombined", 3.0, "Value of the TOF Nsigma cut"}; Configurable cfgNoMixedEvents{"cfgNoMixedEvents", 1, "Number of mixed events per event"}; @@ -113,39 +115,41 @@ struct kstarpbpb { ConfigurableAxis configThnAxisPt{"configThnAxisPt", {100, 0.0, 10.}, "#it{p}_{T} (GeV/#it{c})"}; ConfigurableAxis configThnAxisCentrality{"configThnAxisCentrality", {8, 0., 80}, "Centrality"}; ConfigurableAxis configrapAxis{"configrapAxis", {VARIABLE_WIDTH, -0.8, -0.4, 0.4, 0.8}, "Rapidity"}; - Configurable removefaketrak{"removefaketrack", true, "Remove fake track from momentum difference"}; - Configurable ConfFakeKaonCut{"ConfFakeKaonCut", 0.1, "Cut based on track from momentum difference"}; + Configurable confFakeKaonCut{"confFakeKaonCut", 0.1, "Cut based on track from momentum difference"}; ConfigurableAxis configThnAxisV2{"configThnAxisV2", {400, -16, 16}, "V2"}; - Configurable additionalEvsel{"additionalEvsel", false, "Additional event selcection"}; - Configurable timFrameEvsel{"timFrameEvsel", false, "TPC Time frame boundary cut"}; - Configurable additionalEvselITS{"additionalEvselITS", true, "Additional event selcection for ITS"}; - Configurable ispTdepPID{"ispTdepPID", true, "pT dependent PID"}; Configurable isNoTOF{"isNoTOF", true, "isNoTOF"}; - Configurable PDGcheck{"PDGcheck", true, "PDGcheck"}; + Configurable pdgcheck{"pdgcheck", true, "pdgcheck"}; Configurable strategyPID{"strategyPID", 2, "PID strategy"}; Configurable cfgCutTOFBeta{"cfgCutTOFBeta", 0.0, "cut TOF beta"}; Configurable additionalQAplots{"additionalQAplots", true, "Additional QA plots"}; Configurable additionalQAplots1{"additionalQAplots1", true, "Additional QA plots"}; - Configurable confMinRot{"confMinRot", 5.0 * TMath::Pi() / 6.0, "Minimum of rotation"}; - Configurable confMaxRot{"confMaxRot", 7.0 * TMath::Pi() / 6.0, "Maximum of rotation"}; + Configurable confMinRot{"confMinRot", 5.0 * o2::constants::math::PI / 6.0, "Minimum of rotation"}; + Configurable confMaxRot{"confMaxRot", 7.0 * o2::constants::math::PI / 6.0, "Maximum of rotation"}; Configurable nBkgRotations{"nBkgRotations", 9, "Number of rotated copies (background) per each original candidate"}; Configurable fillRotation{"fillRotation", true, "fill rotation"}; - Configurable same{"same", true, "same event"}; - Configurable like{"like", false, "like-sign"}; Configurable fillSA{"fillSA", true, "same event SA"}; Configurable fillOccupancy{"fillOccupancy", false, "fill Occupancy"}; Configurable cfgOccupancyCut{"cfgOccupancyCut", 500, "Occupancy cut"}; Configurable useWeight{"useWeight", false, "use EP dep effi weight"}; Configurable useSP{"useSP", false, "use SP"}; + Configurable cfgMinTrackPt{"cfgMinTrackPt", 0.15f, + "Minimum track pT"}; + + Configurable cfgMaxTrackPt{"cfgMaxTrackPt", 10.0f, + "Maximum track pT"}; Configurable genacceptancecut{"genacceptancecut", true, "use acceptance cut for generated"}; Configurable avoidsplitrackMC{"avoidsplitrackMC", false, "avoid split track in MC"}; - Configurable ConfWeightPath{"ConfWeightPath", "Users/s/skundu/My/Object/fitweight", "Path to gain calibration"}; + Configurable additionalEvSel1{"additionalEvSel1", true, "Additional evsel1"}; + Configurable additionalEvSel2{"additionalEvSel2", true, "Additional evsel2"}; + Configurable additionalEvSel3{"additionalEvSel3", true, "Additional evsel3"}; + Configurable additionalEvSel4{"additionalEvSel4", true, "Additional evsel4"}; + Configurable confWeightPath{"confWeightPath", "Users/s/skundu/My/Object/fitweight", "Path to gain calibration"}; ConfigurableAxis axisPtKaonWeight{"axisPtKaonWeight", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f}, "pt axis"}; Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; Filter centralityFilter = nabs(aod::cent::centFT0C) < cfgCutCentrality; Filter acceptanceFilter = (nabs(aod::track::eta) < cfgCutEta && nabs(aod::track::pt) > cfgCutPT); - Filter DCAcutFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + Filter dcacutFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz); using EventCandidates = soa::Filtered>; using TrackCandidates = soa::Filtered>; @@ -185,17 +189,11 @@ struct kstarpbpb { AxisSpec occupancyAxis = {occupancyBinning, "Occupancy"}; histos.add("hEvtSelInfo", "hEvtSelInfo", kTH1F, {{10, 0, 10.0}}); if (!fillSA) { - if (same) { - histos.add("hSparseV2SASameEvent_V2", "hSparseV2SASameEvent_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); - } - if (like) { - histos.add("hSparseV2SAlikeEventNN_V2", "hSparseV2SAlikeEventNN_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); - histos.add("hSparseV2SAlikeEventPP_V2", "hSparseV2SAlikeEventPP_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); - } + histos.add("hSparseV2SASameEvent_V2", "hSparseV2SASameEvent_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); } if (fillRotation) { if (!fillSA) { - histos.add("hRotation", "hRotation", kTH1F, {{360, 0.0, 2.0 * TMath::Pi()}}); + histos.add("hRotation", "hRotation", kTH1F, {{360, 0.0, o2::constants::math::TwoPI}}); histos.add("hSparseV2SASameEventRotational_V2", "hSparseV2SASameEventRotational_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); } } @@ -206,27 +204,29 @@ struct kstarpbpb { histos.add("hSparseSAvsraprot", "hSparseSAvsraprot", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}, true); histos.add("hSparseSAvsrapmix", "hSparseSAvsrapmix", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}, true); } - if (!fillSA) { - histos.add("hSparseV2SAGen_V2", "hSparseV2SAGen_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); - histos.add("hSparseV2SARec_V2", "hSparseV2SARec_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); - histos.add("hpt", "hpt", kTH1F, {configThnAxisPt}); - histos.add("hMC", "MC Event statistics", kTH1F, {{10, 0.0f, 10.0f}}); - histos.add("h1PhiRecsplit", "Phi meson Rec split", kTH1F, {{100, 0.0f, 10.0f}}); - histos.add("CentPercentileMCRecHist", "MC Centrality", kTH1F, {{100, 0.0f, 100.0f}}); - histos.add("hSparseV2SAMixedEvent_V2", "hSparseV2SAMixedEvent_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); - histos.add("h2PhiGen2", "Phi meson gen", kTH2F, {configThnAxisPt, configThnAxisCentrality}); - histos.add("h2PhiRec2", "Phi meson Rec", kTH2F, {configThnAxisPt, configThnAxisCentrality}); - histos.add("hImpactParameter", "Impact parameter", kTH1F, {{200, 0.0f, 20.0f}}); - histos.add("hEventPlaneAngle", "hEventPlaneAngle", kTH1F, {{200, -2.0f * TMath::Pi(), 2.0f * TMath::Pi()}}); - histos.add("hSparseKstarMCGenWeight", "hSparseKstarMCGenWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, TMath::Pi()}, {400, 0.0f, 1}, configThnAxisPt, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCRecWeight", "hSparseKstarMCRecWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, TMath::Pi()}, {400, 0.0f, 1}, configThnAxisPt, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCGenKaonWeight", "hSparseKstarMCGenKaonWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, TMath::Pi()}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCRecKaonWeight", "hSparseKstarMCRecKaonWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, TMath::Pi()}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCRecKaonMissMatchWeight", "hSparseKstarMCRecKaonMissMatchWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, TMath::Pi()}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCGenPionWeight", "hSparseKstarMCGenPionWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, TMath::Pi()}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCRecPionWeight", "hSparseKstarMCRecPionWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, TMath::Pi()}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); - histos.add("hSparseKstarMCRecPionMissMatchWeight", "hSparseKstarMCRecPionMissMatchWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, TMath::Pi()}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); - } + histos.add("hSparseV2SAGen_V2", "hSparseV2SAGen_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); + histos.add("hSparseV2SARec_V2", "hSparseV2SARec_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); + histos.add("hpt", "hpt", kTH1F, {configThnAxisPt}); + histos.add("hMC", "MC Event statistics", kTH1F, {{10, 0.0f, 10.0f}}); + histos.add("h1PhiRecsplit", "Phi meson Rec split", kTH1F, {{100, 0.0f, 10.0f}}); + histos.add("CentPercentileMCRecHist", "MC Centrality", kTH1F, {{100, 0.0f, 100.0f}}); + histos.add("hSparseV2SAMixedEvent_V2", "hSparseV2SAMixedEvent_V2", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configThnAxisCentrality}); + histos.add("h2PhiGen2", "Phi meson gen", kTH2F, {configThnAxisPt, configThnAxisCentrality}); + histos.add("h2PhiRec2", "Phi meson Rec", kTH2F, {configThnAxisPt, configThnAxisCentrality}); + histos.add("hImpactParameter", "Impact parameter", kTH1F, {{200, 0.0f, 20.0f}}); + histos.add("hEventPlaneAngle", "hEventPlaneAngle", kTH1F, {{200, -o2::constants::math::TwoPI, o2::constants::math::TwoPI}}); + histos.add("hSparseKstarMCGenWeight", "hSparseKstarMCGenWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, configThnAxisPt, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCRecWeight", "hSparseKstarMCRecWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, configThnAxisPt, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCGenKaonWeight", "hSparseKstarMCGenKaonWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCRecKaonWeight", "hSparseKstarMCRecKaonWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCRecKaonMissMatchWeight", "hSparseKstarMCRecKaonMissMatchWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCGenPionWeight", "hSparseKstarMCGenPionWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCRecPionWeight", "hSparseKstarMCRecPionWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCRecPionMissMatchWeight", "hSparseKstarMCRecPionMissMatchWeight", HistType::kTHnSparseD, {configThnAxisCentrality, {36, 0.0f, o2::constants::math::PI}, {400, 0.0f, 1}, axisPtKaonWeight, {8, -0.8, 0.8}}); + histos.add("hSparseKstarMCGenSA", "hSparseKstarMCGenSA", HistType::kTHnSparseD, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}); + histos.add("hSparseKstarMCGenCosThetaStar_effy", "hSparseKstarMCGenCosThetaStar_effy", HistType::kTHnSparseD, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}); + histos.add("hSparseKstarMCRecSA", "hSparseKstarMCRecSA", HistType::kTHnSparseD, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}); + histos.add("hSparseKstarMCRecCosThetaStar_effy", "hSparseKstarMCRecCosThetaStar_effy", HistType::kTHnSparseD, {configThnAxisInvMass, configThnAxisPt, configThnAxisV2, configrapAxis, configThnAxisCentrality}); if (additionalQAplots1) { histos.add("hFTOCvsTPCSelected", "Mult correlation FT0C vs. TPC after selection", kTH2F, {{80, 0.0f, 80.0f}, {100, -0.5f, 5999.5f}}); histos.add("hCentrality", "Centrality distribution", kTH1F, {{200, 0.0, 200.0}}); @@ -276,19 +276,12 @@ struct kstarpbpb { histos.add("QAafter/TPC_Nsigma_allpi", "TPC NSigma for pion;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{pion};", {HistType::kTH3D, {{200, 0.0, 20.0}, {100, -6, 6}, {100, 0.0, 100.0}}}); } - // Event selection cut additional - Alex - if (additionalEvsel) { - fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.5*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); - fMultPVCutLow->SetParameters(2834.66, -87.0127, 0.915126, -0.00330136, 332.513, -12.3476, 0.251663, -0.00272819, 1.12242e-05); - fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 2.5*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); - fMultPVCutHigh->SetParameters(2834.66, -87.0127, 0.915126, -0.00330136, 332.513, -12.3476, 0.251663, -0.00272819, 1.12242e-05); - fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.5*([4]+[5]*x)", 0, 100); - fMultCutLow->SetParameters(1893.94, -53.86, 0.502913, -0.0015122, 109.625, -1.19253); - fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 3.*([4]+[5]*x)", 0, 100); - fMultCutHigh->SetParameters(1893.94, -53.86, 0.502913, -0.0015122, 109.625, -1.19253); - fMultMultPVCut = new TF1("fMultMultPVCut", "[0]+[1]*x+[2]*x*x", 0, 5000); - fMultMultPVCut->SetParameters(-0.1, 0.785, -4.7e-05); - } + histos.add("hMassSameEventLikeNN", "Same-event like-sign (--) mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); + histos.add("hMassSameEventLikePP", "Same-event like-sign (++) mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); + histos.add("hMassMixedEventLikeNN", "Mixed-event like-sign (--) mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); + histos.add("hMassMixedEventLikePP", "Mixed-event like-sign (++) mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); + histos.add("hMassMixedEventUnlike", "Mixed-event unlike-sign mass", kTH2F, {configThnAxisInvMass, configThnAxisCentrality}); + ccdb->setURL(cfgCcdbParam.cfgURL); ccdbApi.init("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); @@ -299,27 +292,6 @@ struct kstarpbpb { double massKa = o2::constants::physics::MassKPlus; double massPi = o2::constants::physics::MassPiMinus; - template - bool eventSelected(TCollision collision, const float& centrality) - { - if (collision.alias_bit(kTVXinTRD)) { - // TRD triggered - // return 0; - } - auto multNTracksPV = collision.multNTracksPV(); - if (multNTracksPV < fMultPVCutLow->Eval(centrality)) - return 0; - if (multNTracksPV > fMultPVCutHigh->Eval(centrality)) - return 0; - // if (multTrk < fMultCutLow->Eval(centrality)) - // return 0; - // if (multTrk > fMultCutHigh->Eval(centrality)) - // return 0; - // if (multTrk > fMultMultPVCut->Eval(multNTracksPV)) - // return 0; - - return 1; - } template bool selectionTrack(const T& candidate) { @@ -331,140 +303,88 @@ struct kstarpbpb { } return true; } - - template - bool selectionPIDNew(const T& candidate, int PID) - { - if (PID == 0) { - if (candidate.pt() < 0.5 && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { - return true; - } - if (candidate.pt() >= 0.5 && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC && candidate.hasTOF() && TMath::Abs(candidate.tofNSigmaKa()) < nsigmaCutTOF && candidate.beta() > cfgCutTOFBeta) { - return true; - } - if (candidate.pt() >= 0.5 && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC && !candidate.hasTOF()) { - return true; - } - } else if (PID == 1) { - if (candidate.pt() < 0.5 && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { - return true; - } - if (candidate.pt() >= 0.5 && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC && candidate.hasTOF() && TMath::Abs(candidate.tofNSigmaPi()) < nsigmaCutTOF && candidate.beta() > cfgCutTOFBeta) { - return true; - } - if (candidate.pt() >= 0.5 && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC && !candidate.hasTOF()) { - return true; - } - } - return false; - } + static constexpr float TPCOnlyPt = 0.5f; + static constexpr int Strategy = 2; template bool selectionPID2(const T& candidate, int PID) { if (PID == 0) { - if (candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && TMath::Abs(candidate.tofNSigmaKa()) < nsigmaCutTOF) { + if (candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && std::abs(candidate.tofNSigmaKa()) < nsigmaCutTOF) { return true; } } if (PID == 1) { - if (candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && TMath::Abs(candidate.tofNSigmaPi()) < nsigmaCutTOF) { + if (candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && std::abs(candidate.tofNSigmaPi()) < nsigmaCutTOF) { return true; } } return false; } - template - bool selectionPID(const T& candidate, int PID) - { - if (PID == 0) { - if (!isNoTOF && !candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { - return true; - } - if (!isNoTOF && candidate.hasTOF() && ((candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) + (candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa())) < (nsigmaCutCombined * nsigmaCutCombined)) { - return true; - } - if (isNoTOF && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { - return true; - } - } else if (PID == 1) { - if (!isNoTOF && !candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { - return true; - } - if (!isNoTOF && candidate.hasTOF() && ((candidate.tofNSigmaPi() * candidate.tofNSigmaPi()) + (candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi())) < (nsigmaCutCombined * nsigmaCutCombined)) { - return true; - } - if (isNoTOF && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { - return true; - } - } - return false; - } - template bool strategySelectionPID(const T& candidate, int PID, int strategy) { if (PID == 0) { if (strategy == 0) { - if (!isNoTOF && !candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { + if (!isNoTOF && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { return true; } - if (!isNoTOF && candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC && TMath::Abs(candidate.tofNSigmaKa()) < nsigmaCutTOF) { + if (!isNoTOF && candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC && std::abs(candidate.tofNSigmaKa()) < nsigmaCutTOF) { return true; } if (isNoTOF && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { return true; } } else if (strategy == 1) { - if (candidate.pt() < 0.5 && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { + if (!isNoTOF && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { return true; } - if (candidate.pt() >= 0.5 && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC && candidate.hasTOF() && TMath::Abs(candidate.tofNSigmaKa()) < nsigmaCutTOF && candidate.beta() > cfgCutTOFBeta) { + if (!isNoTOF && candidate.hasTOF() && ((candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) + (candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa())) < (nsigmaCutCombined * nsigmaCutCombined)) { return true; } - if (!useGlobalTrack && !candidate.hasTPC()) { + if (isNoTOF && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { return true; } - } else if (strategy == 2) { - if (candidate.pt() < 0.5 && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { + } else if (strategy == Strategy) { + if (candidate.pt() < TPCOnlyPt && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { return true; } - if (candidate.pt() >= 0.5 && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC && candidate.hasTOF() && TMath::Abs(candidate.tofNSigmaKa()) < nsigmaCutTOF && candidate.beta() > cfgCutTOFBeta) { + if (candidate.pt() >= TPCOnlyPt && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC && candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < nsigmaCutTOF && candidate.beta() > cfgCutTOFBeta) { return true; } - if (candidate.pt() >= 0.5 && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC && !candidate.hasTOF()) { + if (candidate.pt() >= TPCOnlyPt && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC && !candidate.hasTOF()) { return true; } } } if (PID == 1) { if (strategy == 0) { - if (!isNoTOF && !candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { + if (!isNoTOF && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { return true; } - if (!isNoTOF && candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC && TMath::Abs(candidate.tofNSigmaPi()) < nsigmaCutTOF) { + if (!isNoTOF && candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC && std::abs(candidate.tofNSigmaPi()) < nsigmaCutTOF) { return true; } if (isNoTOF && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { return true; } } else if (strategy == 1) { - if (candidate.pt() < 0.5 && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { + if (!isNoTOF && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { return true; } - if (candidate.pt() >= 0.5 && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC && candidate.hasTOF() && TMath::Abs(candidate.tofNSigmaPi()) < nsigmaCutTOF && candidate.beta() > cfgCutTOFBeta) { + if (!isNoTOF && candidate.hasTOF() && ((candidate.tofNSigmaPi() * candidate.tofNSigmaPi()) + (candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi())) < (nsigmaCutCombined * nsigmaCutCombined)) { return true; } - if (!useGlobalTrack && !candidate.hasTPC()) { + if (isNoTOF && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { return true; } - } else if (strategy == 2) { - if (candidate.pt() < 0.5 && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { + } else if (strategy == Strategy) { + if (candidate.pt() < TPCOnlyPt && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { return true; } - if (candidate.pt() >= 0.5 && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC && candidate.hasTOF() && TMath::Abs(candidate.tofNSigmaPi()) < nsigmaCutTOF && candidate.beta() > cfgCutTOFBeta) { + if (candidate.pt() >= TPCOnlyPt && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC && candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < nsigmaCutTOF && candidate.beta() > cfgCutTOFBeta) { return true; } - if (candidate.pt() >= 0.5 && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC && !candidate.hasTOF()) { + if (candidate.pt() >= TPCOnlyPt && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC && !candidate.hasTOF()) { return true; } } @@ -472,14 +392,14 @@ struct kstarpbpb { return false; } - double GetPhiInRange(double phi) + double getPhiInRange(double phi) { double result = phi; while (result < 0) { - result = result + 2. * TMath::Pi() / 2; + result += o2::constants::math::PI; } - while (result > 2. * TMath::Pi() / 2) { - result = result - 2. * TMath::Pi() / 2; + while (result >= o2::constants::math::PI) { // >= not > + result -= o2::constants::math::PI; } return result; } @@ -488,26 +408,28 @@ struct kstarpbpb { { const auto pglobal = track.p(); const auto ptpc = track.tpcInnerParam(); - if (TMath::Abs(pglobal - ptpc) > ConfFakeKaonCut) { - return true; - } - return false; + return std::abs(pglobal - ptpc) > confFakeKaonCut; } + + static constexpr float HalfPI = o2::constants::math::PI * 0.5f; ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for bin"}; ConfigurableAxis axisMultiplicityClass{"axisMultiplicityClass", {20, 0, 100}, "multiplicity percentile for bin"}; - ConfigurableAxis axisEPAngle{"axisEPAngle", {6, -TMath::Pi() / 2, TMath::Pi() / 2}, "event plane angle"}; + ConfigurableAxis axisEPAngle{"axisEPAngle", + {6, -HalfPI, HalfPI}, + "event plane angle"}; ConfigurableAxis axisOccup{"axisOccup", {20, -0.5, 40000.0}, "occupancy axis"}; - double v2, v2Rot; + double v2 = 0.; + double v2Rot = 0.; using BinningTypeVertexContributor = ColumnBinningPolicy; - ROOT::Math::PxPyPzMVector KstarMother, fourVecDauCM, daughter1, daughter2, kaonrot, kstarrot, KaonPlus, PionMinus; + ROOT::Math::PxPyPzMVector kstarMother, fourVecDauCM, daughter1, daughter2, kaonrot, kstarrot, kaonPlus, pionMinus; ROOT::Math::XYZVector threeVecDauCM, threeVecDauCMXY, eventplaneVec, eventplaneVecNorm; ROOT::Math::PxPyPzMVector daughter2rot, fourVecDauCMrot; ROOT::Math::XYZVector threeVecDauCMrot, threeVecDauCMXYrot; int currentRunNumber = -999; int lastRunNumber = -999; - TH2D* hweight; + TH2D* hweight = nullptr; void processSE(EventCandidates::iterator const& collision, TrackCandidates const& tracks, aod::BCsWithTimestamps const&) { histos.fill(HIST("hEvtSelInfo"), 0.5); @@ -515,7 +437,26 @@ struct kstarpbpb { return; } histos.fill(HIST("hEvtSelInfo"), 1.5); - if (!collision.sel8() || !collision.triggereventep() || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + if (!collision.sel8()) { + return; + } + if (!collision.triggereventep()) { + return; + } + if (additionalEvSel1 && + !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + return; + } + if (additionalEvSel2 && + !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + return; + } + if (additionalEvSel3 && + !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + return; + } + if (additionalEvSel4 && + !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { return; } histos.fill(HIST("hEvtSelInfo"), 2.5); @@ -525,32 +466,24 @@ struct kstarpbpb { auto psiFT0C = collision.psiFT0C(); auto psiFT0A = collision.psiFT0A(); auto psiTPC = collision.psiTPC(); - auto QFT0C = collision.qFT0C(); - auto QFT0A = collision.qFT0A(); - auto QTPC = collision.qTPC(); + auto qFT0C = collision.qFT0C(); + auto qFT0A = collision.qFT0A(); + auto qTPC = collision.qTPC(); if (fillOccupancy && occupancy > cfgOccupancyCut) { return; } histos.fill(HIST("hEvtSelInfo"), 3.5); - if (additionalEvsel && !eventSelected(collision, centrality)) { - return; - } - histos.fill(HIST("hEvtSelInfo"), 4.5); - if (additionalEvselITS && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { - return; - } - histos.fill(HIST("hEvtSelInfo"), 5.5); if (additionalQAplots1) { histos.fill(HIST("hFTOCvsTPCSelected"), centrality, multTPC); histos.fill(HIST("hPsiFT0C"), centrality, psiFT0C); histos.fill(HIST("hPsiFT0A"), centrality, psiFT0A); histos.fill(HIST("hPsiTPC"), centrality, psiTPC); - histos.fill(HIST("ResFT0CTPC"), centrality, TMath::Cos(2.0 * (psiFT0C - psiTPC))); - histos.fill(HIST("ResFT0CFT0A"), centrality, TMath::Cos(2.0 * (psiFT0C - psiFT0A))); - histos.fill(HIST("ResFT0ATPC"), centrality, TMath::Cos(2.0 * (psiTPC - psiFT0A))); - histos.fill(HIST("ResFT0CTPCSP"), centrality, QFT0C * QTPC * TMath::Cos(2.0 * (psiFT0C - psiTPC))); - histos.fill(HIST("ResFT0CFT0ASP"), centrality, QFT0C * QFT0A * TMath::Cos(2.0 * (psiFT0C - psiFT0A))); - histos.fill(HIST("ResFT0ATPCSP"), centrality, QTPC * QFT0A * TMath::Cos(2.0 * (psiTPC - psiFT0A))); + histos.fill(HIST("ResFT0CTPC"), centrality, std::cos(2.0 * (psiFT0C - psiTPC))); + histos.fill(HIST("ResFT0CFT0A"), centrality, std::cos(2.0 * (psiFT0C - psiFT0A))); + histos.fill(HIST("ResFT0ATPC"), centrality, std::cos(2.0 * (psiTPC - psiFT0A))); + histos.fill(HIST("ResFT0CTPCSP"), centrality, qFT0C * qTPC * std::cos(2.0 * (psiFT0C - psiTPC))); + histos.fill(HIST("ResFT0CFT0ASP"), centrality, qFT0C * qFT0A * std::cos(2.0 * (psiFT0C - psiFT0A))); + histos.fill(HIST("ResFT0ATPCSP"), centrality, qTPC * qFT0A * std::cos(2.0 * (psiTPC - psiFT0A))); histos.fill(HIST("hCentrality"), centrality); histos.fill(HIST("hOccupancy"), occupancy); histos.fill(HIST("hVtxZ"), collision.posZ()); @@ -558,16 +491,16 @@ struct kstarpbpb { auto bc = collision.bc_as(); currentRunNumber = collision.bc_as().runNumber(); if (useWeight && (currentRunNumber != lastRunNumber)) { - hweight = ccdb->getForTimeStamp(ConfWeightPath.value, bc.timestamp()); + hweight = ccdb->getForTimeStamp(confWeightPath.value, bc.timestamp()); } lastRunNumber = currentRunNumber; float weight1 = 1.0; float weight2 = 1.0; - for (auto track1 : tracks) { + for (const auto& track1 : tracks) { if (!selectionTrack(track1)) { continue; } - bool track1kaon = false; + auto track1ID = track1.globalIndex(); if (!isTOFOnly && !strategySelectionPID(track1, 0, strategyPID)) { continue; @@ -575,20 +508,20 @@ struct kstarpbpb { if (isTOFOnly && !selectionPID2(track1, 0)) { continue; } - track1kaon = true; if (useWeight) { - if (track1.pt() < 10.0 && track1.pt() > 0.15) { - weight1 = 1 + hweight->GetBinContent(hweight->FindBin(centrality, track1.pt() + 0.000005)) * TMath::Cos(2.0 * GetPhiInRange(track1.phi() - psiFT0C)); + if (track1.pt() < cfgMaxTrackPt && + track1.pt() > cfgMinTrackPt) { + weight1 = 1 + hweight->GetBinContent(hweight->FindBin(centrality, track1.pt() + 0.000005)) * std::cos(2.0 * getPhiInRange(track1.phi() - psiFT0C)); } else { weight1 = 1; } } - for (auto track2 : tracks) { + for (const auto& track2 : tracks) { if (!selectionTrack(track2)) { continue; } - bool track2pion = false; + auto track2ID = track2.globalIndex(); if (!isTOFOnly && !strategySelectionPID(track2, 1, strategyPID)) { continue; @@ -596,13 +529,11 @@ struct kstarpbpb { if (isTOFOnly && !selectionPID2(track2, 1)) { continue; } - track2pion = true; + if (track2ID == track1ID) { continue; } - if (!track1kaon || !track2pion) { - continue; - } + if (additionalQAplots) { histos.fill(HIST("QAafter/TPC_Nsigma_allka"), track1.pt(), track1.tpcNSigmaKa(), centrality); histos.fill(HIST("QAafter/TOF_Nsigma_allka"), track1.pt(), track1.tofNSigmaKa(), centrality); @@ -616,69 +547,79 @@ struct kstarpbpb { histos.fill(HIST("QAafter/trkDCAzpi"), track2.dcaZ()); } if (useWeight) { - if (track2.pt() < 10.0 && track2.pt() > 0.15) { - weight2 = 1 + hweight->GetBinContent(hweight->FindBin(centrality, track2.pt() + 0.000005)) * TMath::Cos(2.0 * GetPhiInRange(track2.phi() - psiFT0C)); + if (track2.pt() < cfgMaxTrackPt && + track2.pt() > cfgMinTrackPt) { + weight2 = 1 + hweight->GetBinContent(hweight->FindBin(centrality, track2.pt() + 0.000005)) * std::cos(2.0 * getPhiInRange(track2.phi() - psiFT0C)); } else { weight2 = 1; } } daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); - KstarMother = daughter1 + daughter2; - if (TMath::Abs(KstarMother.Rapidity()) > confRapidity) { + kstarMother = daughter1 + daughter2; + if (std::abs(kstarMother.Rapidity()) > confRapidity) { continue; } - auto phiminuspsi = GetPhiInRange(KstarMother.Phi() - psiFT0C); + auto phiMinusPsi = getPhiInRange(kstarMother.Phi() - psiFT0C); if (useSP) { - v2 = TMath::Cos(2.0 * phiminuspsi) * QFT0C; + v2 = std::cos(2.0 * phiMinusPsi) * qFT0C; } if (!useSP) { - v2 = TMath::Cos(2.0 * phiminuspsi); + v2 = std::cos(2.0 * phiMinusPsi); } auto totalweight = weight1 * weight2; - if (totalweight <= 0.0000005) { + static constexpr float MinTotalWeight = 5e-7f; + if (totalweight <= MinTotalWeight) { totalweight = 1.0; } if (additionalQAplots1) { - histos.fill(HIST("ResTrackSPFT0CTPC"), centrality, occupancy, QFT0C * QTPC * TMath::Cos(2.0 * (psiFT0C - psiTPC))); - histos.fill(HIST("ResTrackSPFT0CFT0A"), centrality, occupancy, QFT0C * QFT0A * TMath::Cos(2.0 * (psiFT0C - psiFT0A))); - histos.fill(HIST("ResTrackSPFT0ATPC"), centrality, occupancy, QTPC * QFT0A * TMath::Cos(2.0 * (psiTPC - psiFT0A))); + histos.fill(HIST("ResTrackSPFT0CTPC"), centrality, occupancy, qFT0C * qTPC * std::cos(2.0 * (psiFT0C - psiTPC))); + histos.fill(HIST("ResTrackSPFT0CFT0A"), centrality, occupancy, qFT0C * qFT0A * std::cos(2.0 * (psiFT0C - psiFT0A))); + histos.fill(HIST("ResTrackSPFT0ATPC"), centrality, occupancy, qTPC * qFT0A * std::cos(2.0 * (psiTPC - psiFT0A))); } if (!fillSA) { - if (same) { - if (useWeight) { - histos.fill(HIST("hSparseV2SASameEvent_V2"), KstarMother.M(), KstarMother.Pt(), v2, centrality, 1 / totalweight); - } else { - histos.fill(HIST("hSparseV2SASameEvent_V2"), KstarMother.M(), KstarMother.Pt(), v2, centrality); - } + + if (useWeight) { + histos.fill(HIST("hSparseV2SASameEvent_V2"), kstarMother.M(), kstarMother.Pt(), v2, centrality, 1 / totalweight); + } else { + histos.fill(HIST("hSparseV2SASameEvent_V2"), kstarMother.M(), kstarMother.Pt(), v2, centrality); } } int track1Sign = track1.sign(); int track2Sign = track2.sign(); + if (track1Sign * track2Sign > 0) { + if (track1Sign > 0) { + histos.fill(HIST("hMassSameEventLikePP"), kstarMother.M(), centrality); + } else { + histos.fill(HIST("hMassSameEventLikeNN"), kstarMother.M(), centrality); + } + } else { + } + if (fillSA) { - ROOT::Math::Boost boost{KstarMother.BoostToCM()}; + ROOT::Math::Boost boost{kstarMother.BoostToCM()}; fourVecDauCM = boost(daughter1); threeVecDauCM = fourVecDauCM.Vect(); threeVecDauCMXY = ROOT::Math::XYZVector(threeVecDauCM.X(), threeVecDauCM.Y(), 0.); eventplaneVec = ROOT::Math::XYZVector(std::cos(2.0 * psiFT0C), std::sin(2.0 * psiFT0C), 0); eventplaneVecNorm = ROOT::Math::XYZVector(std::sin(2.0 * psiFT0C), -std::cos(2.0 * psiFT0C), 0); - auto cosPhistarminuspsi = GetPhiInRange(fourVecDauCM.Phi() - psiFT0C); - auto SA = TMath::Cos(2.0 * cosPhistarminuspsi); + auto cosPhistarminuspsi = getPhiInRange(fourVecDauCM.Phi() - psiFT0C); + auto sa = std::cos(2.0 * cosPhistarminuspsi); auto cosThetaStar = eventplaneVecNorm.Dot(threeVecDauCM) / std::sqrt(threeVecDauCM.Mag2()) / std::sqrt(eventplaneVecNorm.Mag2()); if (track1Sign * track2Sign < 0) { if (usepolar) { - histos.fill(HIST("hSparseSAvsrapsameunlike"), KstarMother.M(), KstarMother.Pt(), cosThetaStar, KstarMother.Rapidity(), centrality); + histos.fill(HIST("hSparseSAvsrapsameunlike"), kstarMother.M(), kstarMother.Pt(), cosThetaStar, kstarMother.Rapidity(), centrality); } else { - histos.fill(HIST("hSparseSAvsrapsameunlike"), KstarMother.M(), KstarMother.Pt(), SA, KstarMother.Rapidity(), centrality); + histos.fill(HIST("hSparseSAvsrapsameunlike"), kstarMother.M(), kstarMother.Pt(), sa, kstarMother.Rapidity(), centrality); } } else if (track1Sign * track2Sign > 0) { if (usepolar) { - histos.fill(HIST("hSparseSAvsrapsamelike"), KstarMother.M(), KstarMother.Pt(), cosThetaStar, KstarMother.Rapidity(), centrality); + histos.fill(HIST("hSparseSAvsrapsamelike"), kstarMother.M(), kstarMother.Pt(), cosThetaStar, kstarMother.Rapidity(), centrality); } else { - histos.fill(HIST("hSparseSAvsrapsamelike"), KstarMother.M(), KstarMother.Pt(), SA, KstarMother.Rapidity(), centrality); + histos.fill(HIST("hSparseSAvsrapsamelike"), kstarMother.M(), kstarMother.Pt(), sa, kstarMother.Rapidity(), centrality); } } } @@ -695,16 +636,16 @@ struct kstarpbpb { auto rotkaonPy = track1.px() * std::sin(rotangle) + track1.py() * std::cos(rotangle); kaonrot = ROOT::Math::PxPyPzMVector(rotkaonPx, rotkaonPy, track1.pz(), massKa); kstarrot = kaonrot + daughter2; - if (TMath::Abs(kstarrot.Rapidity()) > confRapidity) { + if (std::abs(kstarrot.Rapidity()) > confRapidity) { continue; } - auto phiminuspsiRot = GetPhiInRange(kstarrot.Phi() - psiFT0C); + auto phiMinusPsiRot = getPhiInRange(kstarrot.Phi() - psiFT0C); if (useSP) { - v2Rot = TMath::Cos(2.0 * phiminuspsiRot) * QFT0C; + v2Rot = std::cos(2.0 * phiMinusPsiRot) * qFT0C; } if (!useSP) { - v2Rot = TMath::Cos(2.0 * phiminuspsiRot); + v2Rot = std::cos(2.0 * phiMinusPsiRot); } if (!fillSA) { histos.fill(HIST("hSparseV2SASameEventRotational_V2"), kstarrot.M(), kstarrot.Pt(), v2Rot, centrality); @@ -715,13 +656,13 @@ struct kstarpbpb { fourVecDauCMrot = boost(kaonrot); threeVecDauCMrot = fourVecDauCMrot.Vect(); threeVecDauCMXYrot = ROOT::Math::XYZVector(threeVecDauCMrot.X(), threeVecDauCMrot.Y(), 0.); - auto cosPhistarminuspsirot = GetPhiInRange(fourVecDauCMrot.Phi() - psiFT0C); - auto SArot = TMath::Cos(2.0 * cosPhistarminuspsirot); + auto cosPhistarminuspsirot = getPhiInRange(fourVecDauCMrot.Phi() - psiFT0C); + auto sarot = std::cos(2.0 * cosPhistarminuspsirot); auto cosThetaStarrot = eventplaneVecNorm.Dot(threeVecDauCMrot) / std::sqrt(threeVecDauCMrot.Mag2()) / std::sqrt(eventplaneVecNorm.Mag2()); if (usepolar) { histos.fill(HIST("hSparseSAvsraprot"), kstarrot.M(), kstarrot.Pt(), cosThetaStarrot, kstarrot.Rapidity(), centrality); } else { - histos.fill(HIST("hSparseSAvsraprot"), kstarrot.M(), kstarrot.Pt(), SArot, kstarrot.Rapidity(), centrality); + histos.fill(HIST("hSparseSAvsraprot"), kstarrot.M(), kstarrot.Pt(), sarot, kstarrot.Rapidity(), centrality); } } } @@ -730,415 +671,43 @@ struct kstarpbpb { } } } - PROCESS_SWITCH(kstarpbpb, processSE, "Process Same event latest", true); - /* - void processSameEvent(EventCandidates::iterator const& collision, TrackCandidates const& , aod::BCsWithTimestamps const&) - { - if (!collision.sel8()) { - return; - } - auto centrality = collision.centFT0C(); - auto multTPC = collision.multNTracksPV(); - auto QFT0C = collision.qFT0C(); - if (!collision.triggereventep()) { - return; - } - if (timFrameEvsel && (!collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { - return; - } - if (additionalEvSel2 && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { - return; - } - if (additionalEvSel3 && (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard))) { - return; - } - if (additionalEvselITS && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { - return; - } - int occupancy = collision.trackOccupancyInTimeRange(); - auto posThisColl = posTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - auto negThisColl = negTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - auto psiFT0C = collision.psiFT0C(); - auto psiFT0A = collision.psiFT0A(); - auto psiTPC = collision.psiTPC(); - if (fillOccupancy && occupancy >= cfgOccupancyCut) // occupancy info is available for this collision (*) - { - return; - } - if (additionalEvsel && !eventSelected(collision, centrality)) { - return; - } - if (additionalQAplots1) { - histos.fill(HIST("hFTOCvsTPCSelected"), centrality, multTPC); - histos.fill(HIST("hPsiFT0C"), centrality, psiFT0C); - histos.fill(HIST("hPsiFT0A"), centrality, psiFT0A); - histos.fill(HIST("hPsiTPC"), centrality, psiTPC); - histos.fill(HIST("ResFT0CTPC"), centrality, TMath::Cos(2.0 * (psiFT0C - psiTPC))); - histos.fill(HIST("ResFT0CFT0A"), centrality, TMath::Cos(2.0 * (psiFT0C - psiFT0A))); - histos.fill(HIST("ResFT0ATPC"), centrality, TMath::Cos(2.0 * (psiTPC - psiFT0A))); - histos.fill(HIST("hCentrality"), centrality); - histos.fill(HIST("hOccupancy"), occupancy); - histos.fill(HIST("hVtxZ"), collision.posZ()); - } - for (auto track1 : posThisColl) { - if (!selectionTrack(track1)) { - continue; - } - if (additionalQAplots) { - histos.fill(HIST("QAbefore/TPC_Nsigma_allka"), track1.pt(), track1.tpcNSigmaKa(), centrality); - histos.fill(HIST("QAbefore/TOF_Nsigma_allka"), track1.pt(), track1.tofNSigmaKa(), centrality); - histos.fill(HIST("QAbefore/trkDCAxyka"), track1.dcaXY()); - histos.fill(HIST("QAbefore/trkDCAzka"), track1.dcaZ()); - histos.fill(HIST("QAbefore/TOF_TPC_Mapka_allka"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); - } - - bool track1pion = false; - bool track1kaon = false; - if (ispTdepPID && !isTOFOnly && !(selectionPIDNew(track1, 0) || selectionPIDNew(track1, 1))) { - continue; - } - if (!ispTdepPID && !isTOFOnly && !(selectionPID(track1, 0) || selectionPID(track1, 1))) { - continue; - } - if (isTOFOnly && !(selectionPID2(track1, 0) || selectionPID2(track1, 1))) { - continue; - } - auto track1ID = track1.globalIndex(); - for (auto track2 : negThisColl) { - bool track2pion = false; - bool track2kaon = false; - if (!selectionTrack(track2)) { - continue; - } - if (additionalQAplots) { - histos.fill(HIST("QAbefore/TOF_TPC_Mapka_allpi"), track2.tofNSigmaPi(), track2.tpcNSigmaPi()); - histos.fill(HIST("QAbefore/TPC_Nsigma_allpi"), track2.pt(), track2.tpcNSigmaPi(), centrality); - histos.fill(HIST("QAbefore/TOF_Nsigma_allpi"), track2.pt(), track2.tofNSigmaPi(), centrality); - histos.fill(HIST("QAbefore/trkDCAxypi"), track2.dcaXY()); - histos.fill(HIST("QAbefore/trkDCAzpi"), track2.dcaZ()); - } - if (ispTdepPID && !isTOFOnly && !(selectionPIDNew(track2, 0) || selectionPIDNew(track2, 1))) { - continue; - } - if (!ispTdepPID && !isTOFOnly && !(selectionPID(track2, 0) || selectionPID(track2, 1))) { - continue; - } - if (isTOFOnly && !(selectionPID2(track2, 0) || selectionPID2(track2, 1))) { - continue; - } - auto track2ID = track2.globalIndex(); - if (track2ID == track1ID) { - continue; - } - if (track1.sign() * track2.sign() > 0) { - continue; - } + PROCESS_SWITCH(Kstarpbpb, processSE, "Process Same event latest", true); - if (ispTdepPID && !isTOFOnly) { - if (selectionPIDNew(track1, 1) && selectionPIDNew(track2, 0)) { - track1pion = true; - track2kaon = true; - if (removefaketrak && isFakeKaon(track2, 0)) { - continue; - } - } - if (selectionPIDNew(track2, 1) && selectionPIDNew(track1, 0)) { - track2pion = true; - track1kaon = true; - if (removefaketrak && isFakeKaon(track1, 0)) { - continue; - } - } - } - if (!ispTdepPID && !isTOFOnly) { - if (selectionPID(track1, 1) && selectionPID(track2, 0)) { - track1pion = true; - track2kaon = true; - if (removefaketrak && isFakeKaon(track2, 0)) { - continue; - } - } - if (selectionPID(track2, 1) && selectionPID(track1, 0)) { - track2pion = true; - track1kaon = true; - if (removefaketrak && isFakeKaon(track1, 0)) { - continue; - } - } - } - if (isTOFOnly) { - if (selectionPID2(track1, 1) && selectionPID2(track2, 0)) { - track1pion = true; - track2kaon = true; - if (removefaketrak && isFakeKaon(track2, 0)) { - continue; - } - } - if (selectionPID2(track2, 1) && selectionPID2(track1, 0)) { - track2pion = true; - track1kaon = true; - if (removefaketrak && isFakeKaon(track1, 0)) { - continue; - } - } - } - if (same) { - if (track1kaon && track2pion) { - if (additionalQAplots) { - histos.fill(HIST("QAafter/TPC_Nsigma_allka"), track1.pt(), track1.tpcNSigmaKa(), centrality); - histos.fill(HIST("QAafter/TOF_Nsigma_allka"), track1.pt(), track1.tofNSigmaKa(), centrality); - histos.fill(HIST("QAafter/trkDCAxyka"), track1.dcaXY()); - histos.fill(HIST("QAafter/trkDCAzka"), track1.dcaZ()); - histos.fill(HIST("QAafter/TOF_TPC_Mapka_allka"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); - histos.fill(HIST("QAafter/TOF_TPC_Mapka_allpi"), track2.tofNSigmaPi(), track2.tpcNSigmaPi()); - histos.fill(HIST("QAafter/TPC_Nsigma_allpi"), track2.pt(), track2.tpcNSigmaPi(), centrality); - histos.fill(HIST("QAafter/TOF_Nsigma_allpi"), track2.pt(), track2.tofNSigmaPi(), centrality); - histos.fill(HIST("QAafter/trkDCAxypi"), track2.dcaXY()); - histos.fill(HIST("QAafter/trkDCAzpi"), track2.dcaZ()); - } - daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); - } else if (track1pion && track2kaon) { - daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massPi); - daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); - } else { - continue; - } - - KstarMother = daughter1 + daughter2; - if (TMath::Abs(KstarMother.Rapidity()) > confRapidity) { - continue; - } - auto phiminuspsi = GetPhiInRange(KstarMother.Phi() - psiFT0C); - - if (useSP) { - v2 = TMath::Cos(2.0 * phiminuspsi) * QFT0C; - } - if (!useSP) { - v2 = TMath::Cos(2.0 * phiminuspsi); - } - - histos.fill(HIST("hSparseV2SASameEvent_V2"), KstarMother.M(), KstarMother.Pt(), v2, centrality); - } - if (fillRotation) { - for (int nrotbkg = 0; nrotbkg < nBkgRotations; nrotbkg++) { - auto anglestart = confMinRot; - auto angleend = confMaxRot; - auto anglestep = (angleend - anglestart) / (1.0 * (nBkgRotations - 1)); - auto rotangle = anglestart + nrotbkg * anglestep; - histos.fill(HIST("hRotation"), rotangle); - if (track1kaon && track2pion) { - auto rotkaonPx = track1.px() * std::cos(rotangle) - track1.py() * std::sin(rotangle); - auto rotkaonPy = track1.px() * std::sin(rotangle) + track1.py() * std::cos(rotangle); - kaonrot = ROOT::Math::PxPyPzMVector(rotkaonPx, rotkaonPy, track1.pz(), massKa); - daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); - } else if (track1pion && track2kaon) { - auto rotkaonPx = track2.px() * std::cos(rotangle) - track2.py() * std::sin(rotangle); - auto rotkaonPy = track2.px() * std::sin(rotangle) + track2.py() * std::cos(rotangle); - kaonrot = ROOT::Math::PxPyPzMVector(rotkaonPx, rotkaonPy, track2.pz(), massKa); - daughter2 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massPi); - } else { - continue; - } - kstarrot = kaonrot + daughter2; - if (TMath::Abs(kstarrot.Rapidity()) > confRapidity) { - continue; - } - auto phiminuspsiRot = GetPhiInRange(kstarrot.Phi() - psiFT0C); - - if (useSP) { - v2Rot = TMath::Cos(2.0 * phiminuspsiRot) * QFT0C; - } - if (!useSP) { - v2Rot = TMath::Cos(2.0 * phiminuspsiRot); - } - - histos.fill(HIST("hSparseV2SASameEventRotational_V2"), kstarrot.M(), kstarrot.Pt(), v2Rot, centrality); - } - } - } - } - } - PROCESS_SWITCH(kstarpbpb, processSameEvent, "Process Same event", false); - - void processlikeEvent(EventCandidates::iterator const& collision, TrackCandidates const& tracks, aod::BCs const&) + void processMixedEvent(EventCandidates const& collisions, TrackCandidates const& tracks) { - if (!collision.sel8()) { - return; - } - auto centrality = collision.centFT0C(); - auto QFT0C = collision.qFT0C(); - if (!collision.triggereventep()) { - return; - } - if (timFrameEvsel && (!collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { - return; - } - if (additionalEvSel2 && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { - return; - } - if (additionalEvSel3 && (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard))) { - return; - } - if (additionalEvselITS && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { - return; - } - int occupancy = collision.trackOccupancyInTimeRange(); - auto psiFT0C = collision.psiFT0C(); - if (fillOccupancy && occupancy >= cfgOccupancyCut) // occupancy info is available for this collision (*) - { - return; - } - if (additionalEvsel && !eventSelected(collision, centrality)) { - return; - } - for (auto track1 : tracks) { - if (!selectionTrack(track1)) { - continue; - } - bool track1pion = false; - bool track1kaon = false; - if (ispTdepPID && !isTOFOnly && !(selectionPIDNew(track1, 0) || selectionPIDNew(track1, 1))) { - continue; - } - if (!ispTdepPID && !isTOFOnly && !(selectionPID(track1, 0) || selectionPID(track1, 1))) { + auto tracksTuple = std::make_tuple(tracks); + BinningTypeVertexContributor binningOnPositions{{axisVertex, axisMultiplicityClass, axisEPAngle}, true}; + SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; + for (const auto& [collision1, tracks1, collision2, tracks2] : pair) { + if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(collision1)) { continue; } - if (isTOFOnly && !(selectionPID2(track1, 0) || selectionPID2(track1, 1))) { + if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(collision2)) { continue; } - for (auto track2 : tracks) { - bool track2pion = false; - bool track2kaon = false; - if (!selectionTrack(track2)) { - continue; - } - if (ispTdepPID && !isTOFOnly && !(selectionPIDNew(track2, 0) || selectionPIDNew(track2, 1))) { - continue; - } - if (!ispTdepPID && !isTOFOnly && !(selectionPID(track2, 0) || selectionPID(track2, 1))) { - continue; - } - if (isTOFOnly && !(selectionPID2(track2, 0) || selectionPID2(track2, 1))) { - continue; - } - if (track1.sign() * track2.sign() < 0) { - continue; - } - if (ispTdepPID && !isTOFOnly) { - if (selectionPIDNew(track1, 1) && selectionPIDNew(track2, 0)) { - track1pion = true; - track2kaon = true; - if (removefaketrak && isFakeKaon(track2, 0)) { - continue; - } - } - if (selectionPIDNew(track2, 1) && selectionPIDNew(track1, 0)) { - track2pion = true; - track1kaon = true; - if (removefaketrak && isFakeKaon(track1, 0)) { - continue; - } - } - } - if (!ispTdepPID && !isTOFOnly) { - if (selectionPID(track1, 1) && selectionPID(track2, 0)) { - track1pion = true; - track2kaon = true; - if (removefaketrak && isFakeKaon(track2, 0)) { - continue; - } - } - if (selectionPID(track2, 1) && selectionPID(track1, 0)) { - track2pion = true; - track1kaon = true; - if (removefaketrak && isFakeKaon(track1, 0)) { - continue; - } - } - } - if (isTOFOnly) { - if (selectionPID2(track1, 1) && selectionPID2(track2, 0)) { - track1pion = true; - track2kaon = true; - if (removefaketrak && isFakeKaon(track2, 0)) { - continue; - } - } - if (selectionPID2(track2, 1) && selectionPID2(track1, 0)) { - track2pion = true; - track1kaon = true; - if (removefaketrak && isFakeKaon(track1, 0)) { - continue; - } - } - } - if (track1kaon && track2pion) { - if (track1.sign() < 0 && track2.sign() < 0) { - - daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); - - KstarMother = daughter1 + daughter2; - if (TMath::Abs(KstarMother.Rapidity()) > confRapidity) { - continue; - } - auto phiminuspsi = GetPhiInRange(KstarMother.Phi() - psiFT0C); - - if (useSP) { - v2 = TMath::Cos(2.0 * phiminuspsi) * QFT0C; - } - if (!useSP) { - v2 = TMath::Cos(2.0 * phiminuspsi); - } - histos.fill(HIST("hSparseV2SAlikeEventNN_V2"), KstarMother.M(), KstarMother.Pt(), v2, centrality); - } - } else if (track1pion && track2kaon) { - if (track1.sign() > 0 && track2.sign() > 0) { - daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massPi); - daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); - KstarMother = daughter1 + daughter2; - if (TMath::Abs(KstarMother.Rapidity()) > confRapidity) { - continue; - } - auto phiminuspsi = GetPhiInRange(KstarMother.Phi() - psiFT0C); + if (!collision1.sel8() || + !collision2.sel8() || - if (useSP) { - v2 = TMath::Cos(2.0 * phiminuspsi) * QFT0C; - } - if (!useSP) { - v2 = TMath::Cos(2.0 * phiminuspsi); - } + !collision1.triggereventep() || + !collision2.triggereventep() || - histos.fill(HIST("hSparseV2SAlikeEventPP_V2"), KstarMother.M(), KstarMother.Pt(), v2, centrality); - } - } - } - } - } + (additionalEvSel1 && + (!collision1.selection_bit(aod::evsel::kNoTimeFrameBorder) || + !collision2.selection_bit(aod::evsel::kNoTimeFrameBorder))) || - PROCESS_SWITCH(kstarpbpb, processlikeEvent, "Process like event", false); - */ + (additionalEvSel2 && + (!collision1.selection_bit(aod::evsel::kNoITSROFrameBorder) || + !collision2.selection_bit(aod::evsel::kNoITSROFrameBorder))) || - void processMixedEvent(EventCandidates const& collisions, TrackCandidates const& tracks) - { + (additionalEvSel3 && + (!collision1.selection_bit(aod::evsel::kNoSameBunchPileup) || + !collision2.selection_bit(aod::evsel::kNoSameBunchPileup))) || - auto tracksTuple = std::make_tuple(tracks); - BinningTypeVertexContributor binningOnPositions{{axisVertex, axisMultiplicityClass, axisOccup}, true}; - SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; - for (auto& [collision1, tracks1, collision2, tracks2] : pair) { - if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(collision1)) { - continue; - } - if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(collision2)) { - continue; - } - if (!collision1.sel8() || !collision1.triggereventep() || !collision1.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision1.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision1.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !collision1.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { - continue; - } - if (!collision2.sel8() || !collision2.triggereventep() || !collision2.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision2.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision2.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !collision2.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + (additionalEvSel4 && + (!collision1.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV) || + !collision2.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)))) { continue; } if (collision1.bcId() == collision2.bcId()) { @@ -1151,40 +720,20 @@ struct kstarpbpb { continue; } auto centrality = collision1.centFT0C(); - auto centrality2 = collision2.centFT0C(); - auto psiFT0C = collision1.psiFT0C(); - auto QFT0C = collision1.qFT0C(); - if (additionalEvsel && !eventSelected(collision1, centrality)) { - continue; - } - if (additionalEvsel && !eventSelected(collision2, centrality2)) { - continue; - } - if (additionalEvselITS && !collision1.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { - continue; - } - if (additionalEvselITS && !collision2.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { - continue; - } + auto psiFT0C1 = collision1.psiFT0C(); + auto qFT0C1 = collision1.qFT0C(); + auto psiFT0C2 = collision2.psiFT0C(); + auto qFT0C2 = collision2.qFT0C(); - for (auto& [track1, track2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - if (track1.sign() * track2.sign() > 0) { - continue; - } - if (!selectionTrack(track1) || !selectionTrack(track2)) { + for (const auto& [track1, track2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + if (!selectionTrack(track1) || !selectionTrack(track2)) { continue; } - if (ispTdepPID && !isTOFOnly && !(selectionPIDNew(track1, 0))) { - continue; - } - if (ispTdepPID && !isTOFOnly && !(selectionPIDNew(track2, 1))) { - continue; - } - if (!ispTdepPID && !isTOFOnly && !(selectionPID(track1, 0))) { + if (!isTOFOnly && !strategySelectionPID(track1, 0, strategyPID)) { continue; } - if (!ispTdepPID && !isTOFOnly && !(selectionPID(track2, 1))) { + if (!isTOFOnly && !strategySelectionPID(track2, 1, strategyPID)) { continue; } if (isTOFOnly && !selectionPID2(track1, 0)) { @@ -1193,44 +742,63 @@ struct kstarpbpb { if (isTOFOnly && !selectionPID2(track2, 1)) { continue; } - // if (track1.sign() > 0 && track2.sign() < 0) { + daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); - /*} else if (track1.sign() < 0 && track2.sign() > 0) { - daughter2 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - daughter1 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); - }*/ - KstarMother = daughter1 + daughter2; - if (TMath::Abs(KstarMother.Rapidity()) > confRapidity) { + + kstarMother = daughter1 + daughter2; + if (std::abs(kstarMother.Rapidity()) > confRapidity) { continue; } - auto phiminuspsi = GetPhiInRange(KstarMother.Phi() - psiFT0C); - v2 = TMath::Cos(2.0 * phiminuspsi) * QFT0C; - if (!fillSA) { - if (track1.sign() * track2.sign() < 0) - histos.fill(HIST("hSparseV2SAMixedEvent_V2"), KstarMother.M(), KstarMother.Pt(), v2, centrality); - } - if (fillSA) { - ROOT::Math::Boost boost{KstarMother.BoostToCM()}; - fourVecDauCM = boost(daughter1); - threeVecDauCM = fourVecDauCM.Vect(); - threeVecDauCMXY = ROOT::Math::XYZVector(threeVecDauCM.X(), threeVecDauCM.Y(), 0.); - eventplaneVec = ROOT::Math::XYZVector(std::cos(2.0 * psiFT0C), std::sin(2.0 * psiFT0C), 0); - eventplaneVecNorm = ROOT::Math::XYZVector(std::sin(2.0 * psiFT0C), -std::cos(2.0 * psiFT0C), 0); - auto cosPhistarminuspsi = GetPhiInRange(fourVecDauCM.Phi() - psiFT0C); - auto SA = TMath::Cos(2.0 * cosPhistarminuspsi); - auto cosThetaStar = eventplaneVecNorm.Dot(threeVecDauCM) / std::sqrt(threeVecDauCM.Mag2()) / std::sqrt(eventplaneVecNorm.Mag2()); - if (usepolar) { - histos.fill(HIST("hSparseSAvsrapmix"), KstarMother.M(), KstarMother.Pt(), cosThetaStar, KstarMother.Rapidity(), centrality); + int s1 = track1.sign(); + int s2 = track2.sign(); + + if (s1 * s2 < 0) { + + auto phi1 = track1.phi(); + auto phi2 = track2.phi(); + auto phiKstar = kstarMother.Phi(); + + double term1 = qFT0C1 * std::cos(2.0 * getPhiInRange(phi1 - psiFT0C1)) * std::cos(2.0 * getPhiInRange(phi1 - phiKstar)); + double term2 = qFT0C2 * std::cos(2.0 * getPhiInRange(phi2 - psiFT0C2)) * std::cos(2.0 * getPhiInRange(phi2 - phiKstar)); + + v2 = term1 + term2; + + if (!fillSA) { + histos.fill(HIST("hSparseV2SAMixedEvent_V2"), kstarMother.M(), kstarMother.Pt(), v2, centrality); + } + histos.fill(HIST("hMassMixedEventUnlike"), kstarMother.M(), centrality); + + if (fillSA) { + ROOT::Math::Boost boost{kstarMother.BoostToCM()}; + fourVecDauCM = boost(daughter1); + threeVecDauCM = fourVecDauCM.Vect(); + threeVecDauCMXY = ROOT::Math::XYZVector(threeVecDauCM.X(), threeVecDauCM.Y(), 0.); + eventplaneVec = ROOT::Math::XYZVector(std::cos(2.0 * psiFT0C1), std::sin(2.0 * psiFT0C1), 0); + eventplaneVecNorm = ROOT::Math::XYZVector(std::sin(2.0 * psiFT0C1), -std::cos(2.0 * psiFT0C1), 0); + auto cosPhistarminuspsi = getPhiInRange(fourVecDauCM.Phi() - psiFT0C1); + auto sa = std::cos(2.0 * cosPhistarminuspsi); + auto cosThetaStar = eventplaneVecNorm.Dot(threeVecDauCM) / std::sqrt(threeVecDauCM.Mag2()) / std::sqrt(eventplaneVecNorm.Mag2()); + if (usepolar) { + histos.fill(HIST("hSparseSAvsrapmix"), kstarMother.M(), kstarMother.Pt(), cosThetaStar, kstarMother.Rapidity(), centrality); + } else { + histos.fill(HIST("hSparseSAvsrapmix"), kstarMother.M(), kstarMother.Pt(), sa, kstarMother.Rapidity(), centrality); + } + } + } else { + + if (s1 > 0) { + histos.fill(HIST("hMassMixedEventLikePP"), kstarMother.M(), centrality); } else { - histos.fill(HIST("hSparseSAvsrapmix"), KstarMother.M(), KstarMother.Pt(), SA, KstarMother.Rapidity(), centrality); + histos.fill(HIST("hMassMixedEventLikeNN"), kstarMother.M(), centrality); } } } } } - PROCESS_SWITCH(kstarpbpb, processMixedEvent, "Process Mixed event", true); + PROCESS_SWITCH(Kstarpbpb, processMixedEvent, "Process Mixed event", true); + void processMC(CollisionMCTrueTable::iterator const& /*TrueCollision*/, CollisionMCRecTableCentFT0C const& RecCollisions, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) { histos.fill(HIST("hMC"), 0); @@ -1242,7 +810,7 @@ struct kstarpbpb { histos.fill(HIST("hMC"), 2); return; } - for (auto& RecCollision : RecCollisions) { + for (const auto& RecCollision : RecCollisions) { auto psiFT0C = 0.0; histos.fill(HIST("hMC"), 3); if (!RecCollision.sel8()) { @@ -1250,11 +818,27 @@ struct kstarpbpb { continue; } - if (!RecCollision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !RecCollision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { - histos.fill(HIST("hMC"), 5); + if (additionalEvSel1 && + !RecCollision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + continue; + } + + if (additionalEvSel2 && + !RecCollision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + continue; + } + + if (additionalEvSel3 && + !RecCollision.selection_bit(aod::evsel::kNoSameBunchPileup)) { continue; } - if (TMath::Abs(RecCollision.posZ()) > cfgCutVertex) { + + if (additionalEvSel4 && + !RecCollision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + continue; + } + histos.fill(HIST("hMC"), 5); + if (std::abs(RecCollision.posZ()) > cfgCutVertex) { histos.fill(HIST("hMC"), 6); continue; } @@ -1262,23 +846,23 @@ struct kstarpbpb { auto centrality = RecCollision.centFT0C(); histos.fill(HIST("CentPercentileMCRecHist"), centrality); auto oldindex = -999; - auto Rectrackspart = RecTracks.sliceBy(perCollision, RecCollision.globalIndex()); + auto rectrackspart = RecTracks.sliceBy(perCollision, RecCollision.globalIndex()); // loop over reconstructed particle - for (auto track1 : Rectrackspart) { + for (const auto& track1 : rectrackspart) { if (!selectionTrack(track1)) { continue; } - if (ispTdepPID && !(selectionPIDNew(track1, 0))) { + if (!isTOFOnly && !strategySelectionPID(track1, 0, strategyPID)) { continue; } - if (!ispTdepPID && !(selectionPID(track1, 0))) { + if (isTOFOnly && !selectionPID2(track1, 0)) { continue; } if (!track1.has_mcParticle()) { continue; } auto track1ID = track1.index(); - for (auto track2 : Rectrackspart) { + for (const auto& track2 : rectrackspart) { auto track2ID = track2.index(); if (track2ID <= track1ID) { continue; @@ -1286,10 +870,10 @@ struct kstarpbpb { if (!selectionTrack(track2)) { continue; } - if (ispTdepPID && !(selectionPIDNew(track2, 1))) { + if (!isTOFOnly && !strategySelectionPID(track2, 1, strategyPID)) { continue; } - if (!ispTdepPID && !(selectionPID(track2, 1))) { + if (isTOFOnly && !selectionPID2(track2, 1)) { continue; } if (!track2.has_mcParticle()) { @@ -1300,35 +884,35 @@ struct kstarpbpb { } const auto mctrack1 = track1.mcParticle(); const auto mctrack2 = track2.mcParticle(); - int track1PDG = TMath::Abs(mctrack1.pdgCode()); - int track2PDG = TMath::Abs(mctrack2.pdgCode()); + int track1PDG = std::abs(mctrack1.pdgCode()); + int track2PDG = std::abs(mctrack2.pdgCode()); if (!mctrack1.isPhysicalPrimary()) { continue; } if (!mctrack2.isPhysicalPrimary()) { continue; } - if (!(track1PDG == 321 && track2PDG == 211)) { + if (track1PDG != PDG_t::kKPlus || track2PDG != PDG_t::kPiPlus) { continue; } - for (auto& mothertrack1 : mctrack1.mothers_as()) { - for (auto& mothertrack2 : mctrack2.mothers_as()) { + for (const auto& mothertrack1 : mctrack1.mothers_as()) { + for (const auto& mothertrack2 : mctrack2.mothers_as()) { if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) { continue; } if (mothertrack1 != mothertrack2) { continue; } - if (TMath::Abs(mothertrack1.y()) > confRapidity) { + if (std::abs(mothertrack1.y()) > confRapidity) { continue; } - if (PDGcheck && TMath::Abs(mothertrack1.pdgCode()) != 313) { + if (pdgcheck && std::abs(mothertrack1.pdgCode()) != o2::constants::physics::kK0Star892) { continue; } - if (ispTdepPID && !(selectionPIDNew(track1, 0) || selectionPIDNew(track2, 1))) { + if (!isTOFOnly && !(strategySelectionPID(track1, 0, strategyPID) || strategySelectionPID(track2, 1, strategyPID))) { continue; } - if (!ispTdepPID && !(selectionPID(track1, 0) || selectionPID(track2, 1))) { + if (isTOFOnly && !(selectionPID2(track1, 0) || selectionPID2(track2, 1))) { continue; } if (avoidsplitrackMC && oldindex == mothertrack1.globalIndex()) { @@ -1336,120 +920,138 @@ struct kstarpbpb { } oldindex = mothertrack1.globalIndex(); if (track1.sign() > 0 && track2.sign() < 0) { - KaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - PionMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); + kaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + pionMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); } if (track1.sign() < 0 && track2.sign() > 0) { - PionMinus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - KaonPlus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); + pionMinus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + kaonPlus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); } - KstarMother = KaonPlus + PionMinus; - if (TMath::Abs(KstarMother.Rapidity()) > confRapidity) { + kstarMother = kaonPlus + pionMinus; + if (std::abs(kstarMother.Rapidity()) > confRapidity) { continue; } - auto phiminuspsi = GetPhiInRange(KstarMother.Phi() - psiFT0C); + auto phiMinusPsi = getPhiInRange(kstarMother.Phi() - psiFT0C); + + v2 = std::cos(2.0 * phiMinusPsi); - v2 = TMath::Cos(2.0 * phiminuspsi); + histos.fill(HIST("hSparseV2SARec_V2"), kstarMother.M(), kstarMother.Pt(), v2, centrality); + histos.fill(HIST("h2PhiRec2"), kstarMother.pt(), centrality); + histos.fill(HIST("hpt"), kstarMother.Pt()); - histos.fill(HIST("hSparseV2SARec_V2"), KstarMother.M(), KstarMother.Pt(), v2, centrality); - histos.fill(HIST("h2PhiRec2"), KstarMother.pt(), centrality); - histos.fill(HIST("hpt"), KstarMother.Pt()); + { + ROOT::Math::Boost boost{kstarMother.BoostToCM()}; + auto fourVecDauCMRec = boost(kaonPlus); + auto threeVecDauCMRec = fourVecDauCMRec.Vect(); + auto eventplaneVecNormRec = ROOT::Math::XYZVector(std::sin(2.0 * psiFT0C), -std::cos(2.0 * psiFT0C), 0); + auto cosPhistarminuspsiRec = getPhiInRange(fourVecDauCMRec.Phi() - psiFT0C); + auto saRec = std::cos(2.0 * cosPhistarminuspsiRec); + auto cosThetaStarRec = eventplaneVecNormRec.Dot(threeVecDauCMRec) / std::sqrt(threeVecDauCMRec.Mag2()) / std::sqrt(eventplaneVecNormRec.Mag2()); + + histos.fill(HIST("hSparseKstarMCRecSA"), kstarMother.M(), kstarMother.Pt(), saRec, std::abs(kstarMother.Rapidity()), centrality); + histos.fill(HIST("hSparseKstarMCRecCosThetaStar_effy"), kstarMother.M(), kstarMother.Pt(), cosThetaStarRec, std::abs(kstarMother.Rapidity()), centrality); + } } } } } // loop over generated particle - for (auto& mcParticle : GenParticles) { - if (TMath::Abs(mcParticle.y()) > confRapidity) { + for (const auto& mcParticle : GenParticles) { + if (std::abs(mcParticle.y()) > confRapidity) { continue; } - if (PDGcheck && mcParticle.pdgCode() != 313) { + if (pdgcheck && mcParticle.pdgCode() != o2::constants::physics::kK0Star892) { continue; } auto kDaughters = mcParticle.daughters_as(); - if (kDaughters.size() != 2) { + static constexpr std::size_t NumberOfDaughters = 2; + + if (kDaughters.size() != NumberOfDaughters) { continue; } auto daughtp = false; auto daughtm = false; - for (auto kCurrentDaughter : kDaughters) { + for (const auto& kCurrentDaughter : kDaughters) { if (!kCurrentDaughter.isPhysicalPrimary()) { continue; } - if (kCurrentDaughter.pdgCode() == +321) { - if (genacceptancecut && kCurrentDaughter.pt() > cfgCutPT && TMath::Abs(kCurrentDaughter.eta()) < cfgCutEta) { + if (kCurrentDaughter.pdgCode() == +PDG_t::kKPlus) { + if (genacceptancecut && kCurrentDaughter.pt() > cfgCutPT && std::abs(kCurrentDaughter.eta()) < cfgCutEta) { daughtp = true; } if (!genacceptancecut) { daughtp = true; } - KaonPlus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); - } else if (kCurrentDaughter.pdgCode() == -211) { - if (genacceptancecut && kCurrentDaughter.pt() > cfgCutPT && TMath::Abs(kCurrentDaughter.eta()) < cfgCutEta) { + kaonPlus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); + } else if (kCurrentDaughter.pdgCode() == -PDG_t::kPiPlus) { + if (genacceptancecut && kCurrentDaughter.pt() > cfgCutPT && std::abs(kCurrentDaughter.eta()) < cfgCutEta) { daughtm = true; } if (!genacceptancecut) { daughtm = true; } - PionMinus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massPi); + pionMinus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massPi); } } if (daughtp && daughtm) { - KstarMother = KaonPlus + PionMinus; - if (TMath::Abs(KstarMother.Rapidity()) > confRapidity) { + kstarMother = kaonPlus + pionMinus; + if (std::abs(kstarMother.Rapidity()) > confRapidity) { continue; } - auto phiminuspsi = GetPhiInRange(KstarMother.Phi() - psiFT0C); + auto phiMinusPsi = getPhiInRange(kstarMother.Phi() - psiFT0C); - v2 = TMath::Cos(2.0 * phiminuspsi); + v2 = std::cos(2.0 * phiMinusPsi); - histos.fill(HIST("hSparseV2SAGen_V2"), KstarMother.M(), KstarMother.Pt(), v2, centrality); - histos.fill(HIST("h2PhiGen2"), KstarMother.pt(), centrality); + histos.fill(HIST("hSparseV2SAGen_V2"), kstarMother.M(), kstarMother.Pt(), v2, centrality); + histos.fill(HIST("h2PhiGen2"), kstarMother.pt(), centrality); + + { + ROOT::Math::Boost boost{kstarMother.BoostToCM()}; + auto fourVecDauCMGen = boost(kaonPlus); + auto threeVecDauCMGen = fourVecDauCMGen.Vect(); + auto eventplaneVecNormGen = ROOT::Math::XYZVector(std::sin(2.0 * psiFT0C), -std::cos(2.0 * psiFT0C), 0); + auto cosPhistarminuspsiGen = getPhiInRange(fourVecDauCMGen.Phi() - psiFT0C); + auto saGen = std::cos(2.0 * cosPhistarminuspsiGen); + auto cosThetaStarGen = eventplaneVecNormGen.Dot(threeVecDauCMGen) / std::sqrt(threeVecDauCMGen.Mag2()) / std::sqrt(eventplaneVecNormGen.Mag2()); + + histos.fill(HIST("hSparseKstarMCGenSA"), kstarMother.M(), kstarMother.Pt(), saGen, std::abs(kstarMother.Rapidity()), centrality); + histos.fill(HIST("hSparseKstarMCGenCosThetaStar_effy"), kstarMother.M(), kstarMother.Pt(), cosThetaStarGen, std::abs(kstarMother.Rapidity()), centrality); + } } } } // rec collision loop } // process MC - PROCESS_SWITCH(kstarpbpb, processMC, "Process MC", false); + PROCESS_SWITCH(Kstarpbpb, processMC, "Process MC", false); void processMCkstarWeight(CollisionMCTrueTable::iterator const& TrueCollision, CollisionMCRecTableCentFT0C const& RecCollisions, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) { float imp = TrueCollision.impactParameter(); float evPhi = TrueCollision.eventPlaneAngle() / 2.0; - float centclass = -999; - if (imp >= 0 && imp < 3.49) { - centclass = 2.5; - } - if (imp >= 3.49 && imp < 4.93) { - centclass = 7.5; - } - if (imp >= 4.93 && imp < 6.98) { - centclass = 15.0; - } - if (imp >= 6.98 && imp < 8.55) { - centclass = 25.0; - } - if (imp >= 8.55 && imp < 9.87) { - centclass = 35.0; - } - if (imp >= 9.87 && imp < 11) { - centclass = 45.0; - } - if (imp >= 11 && imp < 12.1) { - centclass = 55.0; - } - if (imp >= 12.1 && imp < 13.1) { - centclass = 65.0; - } - if (imp >= 13.1 && imp < 14) { - centclass = 75.0; + static constexpr std::array CentEdges = { + 0.0f, 3.49f, 4.93f, 6.98f, 8.55f, + 9.87f, 11.0f, 12.1f, 13.1f, 14.0f}; + + static constexpr std::array CentValues = { + 2.5f, 7.5f, 15.0f, 25.0f, 35.0f, + 45.0f, 55.0f, 65.0f, 75.0f}; + float centclass = -999.f; + + for (size_t i = 0; i < CentValues.size(); ++i) { + if (imp >= CentEdges[i] && imp < CentEdges[i + 1]) { + centclass = CentValues[i]; + break; + } } histos.fill(HIST("hImpactParameter"), imp); histos.fill(HIST("hEventPlaneAngle"), evPhi); - if (centclass < 0.0 || centclass > 80.0) { + static constexpr float MinCentrality = 0.0f; + static constexpr float MaxCentrality = 80.0f; + + if (centclass < MinCentrality || centclass > MaxCentrality) { return; } - for (auto& RecCollision : RecCollisions) { + for (const auto& RecCollision : RecCollisions) { auto psiFT0C = TrueCollision.eventPlaneAngle(); /* if (!RecCollision.sel8()) { @@ -1459,33 +1061,33 @@ struct kstarpbpb { continue; } */ - if (TMath::Abs(RecCollision.posZ()) > cfgCutVertex) { + if (std::abs(RecCollision.posZ()) > cfgCutVertex) { continue; } auto oldindex = -999; - auto Rectrackspart = RecTracks.sliceBy(perCollision, RecCollision.globalIndex()); + auto rectrackspart = RecTracks.sliceBy(perCollision, RecCollision.globalIndex()); // loop over reconstructed particle - for (auto track1 : Rectrackspart) { + for (const auto& track1 : rectrackspart) { if (!track1.has_mcParticle()) { continue; } const auto mctrack1 = track1.mcParticle(); - if (selectionTrack(track1) && strategySelectionPID(track1, 0, strategyPID) && TMath::Abs(mctrack1.pdgCode()) == 321 && mctrack1.isPhysicalPrimary()) { - histos.fill(HIST("hSparseKstarMCRecKaonWeight"), centclass, GetPhiInRange(mctrack1.phi() - psiFT0C), TMath::Power(TMath::Cos(2.0 * GetPhiInRange(mctrack1.phi() - psiFT0C)), 2.0), mctrack1.pt(), mctrack1.eta()); + if (selectionTrack(track1) && strategySelectionPID(track1, 0, strategyPID) && std::abs(mctrack1.pdgCode()) == PDG_t::kKPlus && mctrack1.isPhysicalPrimary()) { + histos.fill(HIST("hSparseKstarMCRecKaonWeight"), centclass, getPhiInRange(mctrack1.phi() - psiFT0C), std::pow(std::cos(2.0 * getPhiInRange(mctrack1.phi() - psiFT0C)), 2.0), mctrack1.pt(), mctrack1.eta()); } - if (selectionTrack(track1) && track1.pt() > 0.5 && track1.hasTOF() && TMath::Abs(track1.tofNSigmaKa()) > nsigmaCutTOF && TMath::Abs(track1.tpcNSigmaKa()) < nsigmaCutTPC && TMath::Abs(mctrack1.pdgCode()) == 321 && mctrack1.isPhysicalPrimary()) { - histos.fill(HIST("hSparseKstarMCRecKaonMissMatchWeight"), centclass, GetPhiInRange(mctrack1.phi() - psiFT0C), TMath::Power(TMath::Cos(2.0 * GetPhiInRange(mctrack1.phi() - psiFT0C)), 2.0), mctrack1.pt(), mctrack1.eta()); + if (selectionTrack(track1) && track1.pt() > TPCOnlyPt && track1.hasTOF() && std::abs(track1.tofNSigmaKa()) > nsigmaCutTOF && std::abs(track1.tpcNSigmaKa()) < nsigmaCutTPC && std::abs(mctrack1.pdgCode()) == PDG_t::kKPlus && mctrack1.isPhysicalPrimary()) { + histos.fill(HIST("hSparseKstarMCRecKaonMissMatchWeight"), centclass, getPhiInRange(mctrack1.phi() - psiFT0C), std::pow(std::cos(2.0 * getPhiInRange(mctrack1.phi() - psiFT0C)), 2.0), mctrack1.pt(), mctrack1.eta()); } - if (selectionTrack(track1) && strategySelectionPID(track1, 1, strategyPID) && TMath::Abs(mctrack1.pdgCode()) == 211 && mctrack1.isPhysicalPrimary()) { - histos.fill(HIST("hSparseKstarMCRecPionWeight"), centclass, GetPhiInRange(mctrack1.phi() - psiFT0C), TMath::Power(TMath::Cos(2.0 * GetPhiInRange(mctrack1.phi() - psiFT0C)), 2.0), mctrack1.pt(), mctrack1.eta()); + if (selectionTrack(track1) && strategySelectionPID(track1, 1, strategyPID) && std::abs(mctrack1.pdgCode()) == PDG_t::kPiPlus && mctrack1.isPhysicalPrimary()) { + histos.fill(HIST("hSparseKstarMCRecPionWeight"), centclass, getPhiInRange(mctrack1.phi() - psiFT0C), std::pow(std::cos(2.0 * getPhiInRange(mctrack1.phi() - psiFT0C)), 2.0), mctrack1.pt(), mctrack1.eta()); } - if (selectionTrack(track1) && track1.pt() > 0.5 && track1.hasTOF() && TMath::Abs(track1.tofNSigmaPi()) > nsigmaCutTOF && TMath::Abs(track1.tpcNSigmaPi()) < nsigmaCutTPC && TMath::Abs(mctrack1.pdgCode()) == 211 && mctrack1.isPhysicalPrimary()) { - histos.fill(HIST("hSparseKstarMCRecPionMissMatchWeight"), centclass, GetPhiInRange(mctrack1.phi() - psiFT0C), TMath::Power(TMath::Cos(2.0 * GetPhiInRange(mctrack1.phi() - psiFT0C)), 2.0), mctrack1.pt(), mctrack1.eta()); + if (selectionTrack(track1) && track1.pt() > TPCOnlyPt && track1.hasTOF() && std::abs(track1.tofNSigmaPi()) > nsigmaCutTOF && std::abs(track1.tpcNSigmaPi()) < nsigmaCutTPC && std::abs(mctrack1.pdgCode()) == PDG_t::kPiPlus && mctrack1.isPhysicalPrimary()) { + histos.fill(HIST("hSparseKstarMCRecPionMissMatchWeight"), centclass, getPhiInRange(mctrack1.phi() - psiFT0C), std::pow(std::cos(2.0 * getPhiInRange(mctrack1.phi() - psiFT0C)), 2.0), mctrack1.pt(), mctrack1.eta()); } auto track1ID = track1.index(); - for (auto track2 : Rectrackspart) { + for (const auto& track2 : rectrackspart) { if (!track2.has_mcParticle()) { continue; } @@ -1494,42 +1096,39 @@ struct kstarpbpb { continue; } const auto mctrack2 = track2.mcParticle(); - int track1PDG = TMath::Abs(mctrack1.pdgCode()); - int track2PDG = TMath::Abs(mctrack2.pdgCode()); + int track1PDG = std::abs(mctrack1.pdgCode()); + int track2PDG = std::abs(mctrack2.pdgCode()); if (!mctrack1.isPhysicalPrimary()) { continue; } if (!mctrack2.isPhysicalPrimary()) { continue; } - if (!(track1PDG == 321 && track2PDG == 211)) { + if (track1PDG != PDG_t::kKPlus || track2PDG != PDG_t::kPiPlus) { continue; } if (!selectionTrack(track1) || !selectionTrack(track2) || track1.sign() * track2.sign() > 0) { continue; } // PID check - if (ispTdepPID && !isTOFOnly && (!strategySelectionPID(track1, 0, strategyPID) || !strategySelectionPID(track2, 1, strategyPID))) { - continue; - } - if (!ispTdepPID && !isTOFOnly && (!selectionPID(track1, 0) || !selectionPID(track2, 1))) { + if (!isTOFOnly && (!strategySelectionPID(track1, 0, strategyPID) || !strategySelectionPID(track2, 1, strategyPID))) { continue; } if (isTOFOnly && (!selectionPID2(track1, 0) || !selectionPID2(track2, 1))) { continue; } - for (auto& mothertrack1 : mctrack1.mothers_as()) { - for (auto& mothertrack2 : mctrack2.mothers_as()) { + for (const auto& mothertrack1 : mctrack1.mothers_as()) { + for (const auto& mothertrack2 : mctrack2.mothers_as()) { if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) { continue; } if (mothertrack1 != mothertrack2) { continue; } - if (TMath::Abs(mothertrack1.y()) > confRapidity) { + if (std::abs(mothertrack1.y()) > confRapidity) { continue; } - if (TMath::Abs(mothertrack1.pdgCode()) != 313) { + if (std::abs(mothertrack1.pdgCode()) != o2::constants::physics::kK0Star892) { continue; } // if (avoidsplitrackMC && oldindex == mothertrack1.globalIndex()) { @@ -1539,62 +1138,66 @@ struct kstarpbpb { } // oldindex = mothertrack1.globalIndex(); oldindex = mothertrack1.index(); - auto PhiMinusPsi = GetPhiInRange(mothertrack1.phi() - psiFT0C); - histos.fill(HIST("hSparseKstarMCRecWeight"), centclass, PhiMinusPsi, TMath::Power(TMath::Cos(2.0 * PhiMinusPsi), 2.0), mothertrack1.pt(), mothertrack1.eta()); + auto phiMinusPsi = getPhiInRange(mothertrack1.phi() - psiFT0C); + histos.fill(HIST("hSparseKstarMCRecWeight"), centclass, phiMinusPsi, std::pow(std::cos(2.0 * phiMinusPsi), 2.0), mothertrack1.pt(), mothertrack1.eta()); } } } } // loop over generated particle - for (auto& mcParticle : GenParticles) { - if (TMath::Abs(mcParticle.eta()) > 0.8) // main acceptance + for (const auto& mcParticle : GenParticles) { + static constexpr float MaxEtaAcceptance = 0.8f; + if (std::abs(mcParticle.eta()) > MaxEtaAcceptance) { continue; - if (TMath::Abs(mcParticle.pdgCode()) == 321 && mcParticle.isPhysicalPrimary()) { - histos.fill(HIST("hSparseKstarMCGenKaonWeight"), centclass, GetPhiInRange(mcParticle.phi() - psiFT0C), TMath::Power(TMath::Cos(2.0 * GetPhiInRange(mcParticle.phi() - psiFT0C)), 2.0), mcParticle.pt(), mcParticle.eta()); } - if (TMath::Abs(mcParticle.pdgCode()) == 211 && mcParticle.isPhysicalPrimary()) { - histos.fill(HIST("hSparseKstarMCGenPionWeight"), centclass, GetPhiInRange(mcParticle.phi() - psiFT0C), TMath::Power(TMath::Cos(2.0 * GetPhiInRange(mcParticle.phi() - psiFT0C)), 2.0), mcParticle.pt(), mcParticle.eta()); + if (std::abs(mcParticle.pdgCode()) == PDG_t::kKPlus && mcParticle.isPhysicalPrimary()) { + histos.fill(HIST("hSparseKstarMCGenKaonWeight"), centclass, getPhiInRange(mcParticle.phi() - psiFT0C), std::pow(std::cos(2.0 * getPhiInRange(mcParticle.phi() - psiFT0C)), 2.0), mcParticle.pt(), mcParticle.eta()); } - if (TMath::Abs(mcParticle.y()) > confRapidity) { + if (std::abs(mcParticle.pdgCode()) == PDG_t::kPiPlus && mcParticle.isPhysicalPrimary()) { + histos.fill(HIST("hSparseKstarMCGenPionWeight"), centclass, getPhiInRange(mcParticle.phi() - psiFT0C), std::pow(std::cos(2.0 * getPhiInRange(mcParticle.phi() - psiFT0C)), 2.0), mcParticle.pt(), mcParticle.eta()); + } + if (std::abs(mcParticle.y()) > confRapidity) { continue; } - if (mcParticle.pdgCode() != 313) { + if (mcParticle.pdgCode() != o2::constants::physics::kK0Star892) { continue; } auto kDaughters = mcParticle.daughters_as(); - if (kDaughters.size() != 2) { + static constexpr std::size_t NumberOfDaughters = 2; + + if (kDaughters.size() != NumberOfDaughters) { continue; } auto daughtp = false; auto daughtm = false; - for (auto kCurrentDaughter : kDaughters) { + for (const auto& kCurrentDaughter : kDaughters) { if (!kCurrentDaughter.isPhysicalPrimary()) { continue; } - if (kCurrentDaughter.pdgCode() == +321) { - if (kCurrentDaughter.pt() > cfgCutPT && TMath::Abs(kCurrentDaughter.eta()) < cfgCutEta) { + if (kCurrentDaughter.pdgCode() == +PDG_t::kKPlus) { + if (kCurrentDaughter.pt() > cfgCutPT && std::abs(kCurrentDaughter.eta()) < cfgCutEta) { daughtp = true; } - KaonPlus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); - } else if (kCurrentDaughter.pdgCode() == -211) { - if (kCurrentDaughter.pt() > cfgCutPT && TMath::Abs(kCurrentDaughter.eta()) < cfgCutEta) { + kaonPlus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); + } else if (kCurrentDaughter.pdgCode() == -PDG_t::kPiPlus) { + if (kCurrentDaughter.pt() > cfgCutPT && std::abs(kCurrentDaughter.eta()) < cfgCutEta) { daughtm = true; } - PionMinus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massPi); + pionMinus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massPi); } } if (daughtp && daughtm) { - auto PhiMinusPsiGen = GetPhiInRange(mcParticle.phi() - psiFT0C); - histos.fill(HIST("hSparseKstarMCGenWeight"), centclass, PhiMinusPsiGen, TMath::Power(TMath::Cos(2.0 * PhiMinusPsiGen), 2.0), mcParticle.pt(), mcParticle.eta()); + auto phiMinusPsiGen = getPhiInRange(mcParticle.phi() - psiFT0C); + histos.fill(HIST("hSparseKstarMCGenWeight"), centclass, phiMinusPsiGen, std::pow(std::cos(2.0 * phiMinusPsiGen), 2.0), mcParticle.pt(), mcParticle.eta()); } } } // rec collision loop } // process MC - PROCESS_SWITCH(kstarpbpb, processMCkstarWeight, "Process MC kstar Weight", false); + PROCESS_SWITCH(Kstarpbpb, processMCkstarWeight, "Process MC kstar Weight", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc, TaskName{"kstarpbpb"})}; + adaptAnalysisTask(cfgc)}; } diff --git a/PWGLF/Tasks/Resonances/lambda1405analysis.cxx b/PWGLF/Tasks/Resonances/lambda1405analysis.cxx index 4f018c54fc3..e8771cbb8a6 100644 --- a/PWGLF/Tasks/Resonances/lambda1405analysis.cxx +++ b/PWGLF/Tasks/Resonances/lambda1405analysis.cxx @@ -17,13 +17,20 @@ #include "PWGLF/DataModel/LFLambda1405Table.h" #include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/Qvectors.h" +#include +#include #include +#include +#include +#include #include #include #include @@ -34,11 +41,18 @@ #include #include #include +#include +#include #include +#include +#include +#include +#include #include #include +#include #include #include #include @@ -48,9 +62,9 @@ using namespace o2::framework; using namespace o2::framework::expressions; using TracksFull = soa::Join; -using CollisionsFull = soa::Join; +using CollisionsFull = soa::Join; using CollisionsFullWCentQVecs = soa::Join; -using CollisionsFullMc = soa::Join; +using CollisionsFullMc = soa::Join; using CollisionsFullMcWCent = soa::Join; enum L1405DecayType { kSigmaMinusPiToPiPiNeutron = 0, @@ -67,42 +81,48 @@ struct lambda1405candidate { float pz = -1; // Pz of the Lambda(1405) candidate float pt() const { return std::sqrt(px * px + py * py); } // pT of the Lambda(1405) candidate float phi = -1; // Phi of the Lambda(1405) candidate - - bool isSigmaPlus = false; // True if compatible with Sigma+ - bool isSigmaMinus = false; // True if compatible with Sigma- - bool hasPiKink = false; // True if the Sigma candidate has a kink topology compatible with a pion - bool hasPrKink = false; // True if the Sigma candidate has a kink topology compatible with a proton - float sigmaMinusMass = -1; // Invariant mass of the Sigma- candidate - float sigmaPlusMass = -1; // Invariant mass of the Sigma+ candidate - float xiMinusMass = -1; // Invariant mass of the Xi- candidate - int sigmaSign = 0; // Sign of the Sigma candidate: 1 for matter, -1 for antimatter - float sigmaPt = -1; // pT of the Sigma daughter - float sigmaAlphaAP = -1; // Alpha of the Sigma - float sigmaQtAP = -1; // qT of the Sigma - float kinkPt = -1; // pT of the kink daughter - float kinkPiNSigTpc = -1; // Number of sigmas for the pion candidate from Sigma kink in Tpc - float kinkPiNSigTof = -1; // Number of sigmas for the pion candidate from Sigma kink in Tof - float kinkPrNSigTpc = -1; // Number of sigmas for the proton candidate from Sigma kink in Tpc - float kinkPrNSigTof = -1; // Number of sigmas for the proton candidate from Sigma kink in Tof - float kinkDcaDauToPv = -1; // DCA of the kink daughter to the primary vertex - float sigmaRadius = -1; // Radius of the Sigma decay vertex - - float piPt = -1; // pT of the pion daughter + float eta = -1; // Eta of the Lambda(1405) candidate + + bool isSigmaPlus = false; // True if compatible with Sigma+ + bool isSigmaMinus = false; // True if compatible with Sigma- + float sigmaMinusMass = -1; // Invariant mass of the Sigma- candidate + float sigmaPlusMass = -1; // Invariant mass of the Sigma+ candidate + float xiMinusMass = -1; // Invariant mass of the Xi- candidate + int sigmaSign = 0; // Sign of the Sigma candidate: 1 for matter, -1 for antimatter + float sigmaPt = -1; // pT of the Sigma daughter + float sigmaAlphaAP = -1; // Alpha of the Sigma + float sigmaQtAP = -1; // qT of the Sigma + float sigmaRadius = -1; // Radius of the Sigma decay vertex + float dcaSigmaToPv = -1; // DCA of the Sigma candidate to the primary vertex + float kinkPt = -1; // pT of the kink daughter + float kinkPiNSigTpc = -1; // Number of sigmas for the pion candidate from Sigma kink in Tpc + float kinkPiNSigTof = -1; // Number of sigmas for the pion candidate from Sigma kink in Tof + float kinkPrNSigTpc = -1; // Number of sigmas for the proton candidate from Sigma kink in Tpc + float kinkPrNSigTof = -1; // Number of sigmas for the proton candidate from Sigma kink in Tof + float kinkDcaDauToPv = -1; // DCA of the kink daughter to the primary vertex + + float bachPiPt = -1; // pT of the pion daughter float bachPiNSigTpc = -1; // Number of sigmas for the pion candidate float bachPiNSigTof = -1; // Number of sigmas for the pion candidate using Tof int kinkDauId = 0; // Id of the pion from Sigma decay in MC int sigmaId = 0; // Id of the Sigma candidate in MC - int piId = 0; // Id of the pion candidate in MC + int bachPiId = 0; // Id of the pion candidate in MC + + float centMult = -1; // Centrality of the collision + float pvContrib = -1; // Number of contributors to the primary vertex + float occupancy = -1; // Occupancy of the collision float scalarProd = -1; // Scalar product for flow analysis }; struct lambda1405analysis { int lambda1405PdgCode = 102132; // PDG code for Lambda(1405) - lambda1405candidate lambda1405Cand; // Lambda(1405) candidate structure Produces outputDataTable; // Output table for Lambda(1405) candidates Produces outputDataFlowTable; // Output table for Lambda(1405) flow analysis Produces outputDataTableMC; // Output table for Lambda(1405) candidates in MC + + Service ccdb; + // Histograms are defined with HistogramRegistry HistogramRegistry rEventSelection{"eventSelection", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry rLambda1405{"lambda1405", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; @@ -112,16 +132,21 @@ struct lambda1405analysis { // Configurable for event selection Configurable cutZVertex{"cutZVertex", 10.0f, "Accepted z-vertex range (cm)"}; Configurable cutEtaDaughter{"cutEtaDaughter", 0.8f, "Eta cut for daughter tracks"}; - Configurable cutDCAtoPvSigma{"cutDCAtoPvSigma", 0.1f, "Max DCA to primary vertex for Sigma candidates (cm)"}; - Configurable cutDCAtoPvPiFromSigma{"cutDCAtoPvPiFromSigma", 2., "Min DCA to primary vertex for pion from Sigma candidates (cm)"}; + Configurable cutDcaToPvSigma{"cutDcaToPvSigma", 0.1f, "Max DCA to primary vertex for Sigma candidates (cm)"}; + Configurable cutDcaToPvPiFromSigma{"cutDcaToPvPiFromSigma", 2., "Min DCA to primary vertex for pion from Sigma candidates (cm)"}; + Configurable cutMinPtL1405{"cutMinPtL1405", 2.0f, "Minimum pT cut for Lambda(1405) candidates (GeV/c)"}; Configurable cutUpperMass{"cutUpperMass", 1.6f, "Upper mass cut for Lambda(1405) candidates (GeV/c^2)"}; Configurable cutSigmaRadius{"cutSigmaRadius", 20.f, "Minimum radius for Sigma candidates (cm)"}; Configurable cutSigmaMass{"cutSigmaMass", 0.1, "Sigma mass window (MeV/c^2)"}; - Configurable cutNITSClusKink{"cutNITSClusKink", 3, "Minimum number of ITS clusters for pion candidate"}; - Configurable cutNTpcClusPi{"cutNTpcClusPi", 90, "Minimum number of Tpc clusters for pion candidate"}; + Configurable cutItsNClusKinkMin{"cutItsNClusKinkMin", 1, "Minimum number of ITS clusters for kink daughter"}; + Configurable cutItsNClusKinkMax{"cutItsNClusKinkMax", 3, "Maximum number of ITS clusters for kink daughter"}; + Configurable cutNTpcClus{"cutNTpcClus", 90, "Minimum number of Tpc clusters for pion candidate"}; Configurable cutNSigTpc{"cutNSigTpc", 3, "NSigTpcPion"}; Configurable cutNSigTof{"cutNSigTof", 3, "NSigTofPion"}; + Configurable cutMaxDcaZBach{"cutMaxDcaZBach", 0.1, "Maximum DcaZ for bachelor pion (cm)"}; + Configurable dcaXYBachNSigmaMax{"dcaXYBachNSigmaMax", 7, "Cut on number of sigma deviations from expected DCA in the transverse direction"}; + Configurable dcaXYPtBachFunc{"dcaXYPtBachFunc", "(0.0026+0.005/(x^1.01))", "Functional form of pt-dependent DCAxy cut"}; Configurable cutSigmaQtAPMin{"cutSigmaQtAPMin", "0.17", "Functional form of minimum qT(alpha) selection"}; Configurable cutSigmaQtAPMax{"cutSigmaQtAPMax", "0.2", "Functional form of minimum qT(alpha) selection"}; Configurable cutMinBachPiPtVsL1405Pt{"cutMinBachPiPtVsL1405Pt", "0", "Functional form of minimum qT(alpha) selection"}; @@ -130,8 +155,13 @@ struct lambda1405analysis { Configurable cutMaxSigmaPtVsL1405Pt{"cutMaxSigmaPtVsL1405Pt", "10", "Functional form of minimum qT(alpha) selection"}; // Configurables for flow analysis - Configurable centralityMin{"centralityMin", 0., "Minimum centrality accepted in SP/EP computation (not applied in resolution process)"}; - Configurable centralityMax{"centralityMax", 100., "Maximum centrality accepted in SP/EP computation (not applied in resolution process)"}; + Configurable centMultMin{"centMultMin", 0., "Minimum collision centrality/multiplicity accepted"}; + Configurable centMultMax{"centMultMax", 100., "Maximum collision centrality/multiplicity accepted"}; + Configurable occupancyMax{"occupancyMax", 3000000., "Maximum collision occupancy accepted"}; + Configurable minDEta{"minDEta", -1., "Minimum delta eta between L1405-track pairs"}; + Configurable assTrkMinPt{"assTrkMinPt", 0., "Minimum pT of associated track for 2PC"}; + Configurable assTrkMaxPt{"assTrkMaxPt", 10., "Maximum pT of associated track for 2PC"}; + Configurable saveDEtaDPhi{"saveDEtaDPhi", false, "If true, save the dEta and dPhi distributions for Lambda(1405) candidates"}; Configurable fillFlowTree{"fillFlowTree", false, "If true, fill the output tree with Lambda(1405) candidates"}; // Downsample for table filling @@ -140,33 +170,53 @@ struct lambda1405analysis { Configurable fillOutputTree{"fillOutputTree", true, "If true, fill the output tree with Lambda(1405) candidates"}; Configurable doLikeSignBkg{"doLikeSignBkg", false, "Use like-sign background"}; - Configurable useTof{"useTof", false, "Use Tof for PId for pion candidates"}; + Configurable useTof{"useTof", false, "Use Tof for PID for pion candidates"}; + Configurable recomputeSigmaMom{"recomputeSigmaMom", true, "Recalculate sigma momentum from daughter kinematics"}; + Configurable skipSigmasFailedRecompMom{"skipSigmasFailedRecompMom", false, "Skip sigmas for which momentum recalculation fails"}; + + // CCDB options + Configurable cfgMaterialCorrection{"cfgMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrNONE), "Type of material correction"}; + Configurable ccdbPath{"ccdbPath", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; - TF1 funcMinQtAlphaAP, funcMaxQtAlphaAP, funcMinBachPiPtVsL1405Pt, funcMaxBachPiPtVsL1405Pt, funcMinSigmaPtVsL1405Pt, funcMaxSigmaPtVsL1405Pt; + TF1 funcMinQtAlphaAP, funcMaxQtAlphaAP, funcMinBachPiPtVsL1405Pt, funcMaxBachPiPtVsL1405Pt, funcMinSigmaPtVsL1405Pt, funcMaxSigmaPtVsL1405Pt, funcDcaXYPtCutBachPi; using CollisionsCentSel = soa::Filtered; using McRecoCollisionsCentSel = soa::Filtered; - Filter filterCentrality = aod::cent::centFT0C >= centralityMin && aod::cent::centFT0C <= centralityMax; + Filter filterOccupancy = aod::evsel::ft0cOccupancyInTimeRange <= occupancyMax; + + PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; + + // Needed for DCA propagation of bachelor tracks + int mRunNumber; + float mBz; + o2::base::MatLayerCylSet* lut = nullptr; // Configurable axes - ConfigurableAxis axisCent{"axisCent", {10000, 0., 100.}, ""}; + ConfigurableAxis axisPvContrib{"axisPvContrib", {5000, 0., 5000.}, ""}; + ConfigurableAxis axisCent{"axisCent", {100, 0., 100.}, ""}; + ConfigurableAxis axisOccupancy{"axisOccupancy", {100, 0., 140000.}, ""}; ConfigurableAxis axisPtL1405{"axisPtL1405", {100, 0., 10.}, ""}; ConfigurableAxis axisPCompsL1405{"axisPCompsL1405", {100, -10., 10.}, ""}; - ConfigurableAxis axisPtKinkDaug{"axisPtKinkDaug", {100, -5., 5.}, ""}; + ConfigurableAxis axisPtKinkDaug{"axisPtKinkDaug", {100, 0., 10.}, ""}; ConfigurableAxis axisPtResolution{"axisPtResolution", {100, -0.5, 0.5}, ""}; - ConfigurableAxis axisMassL1405{"axisMassL1405", {100, 1.3, 1.8}, ""}; - ConfigurableAxis axisXi1530Mass{"axisXi1530Mass", {100, 1.4, 1.6}, ""}; + ConfigurableAxis axisMassL1405{"axisMassL1405", {500, 1.3, 1.8}, ""}; + ConfigurableAxis axisXi1530Mass{"axisXi1530Mass", {500, 1.3, 1.8}, ""}; ConfigurableAxis axisMassResolution{"axisMassResolution", {100, -0.1, 0.1}, ""}; ConfigurableAxis axisNSig{"axisNSig", {100, -5., 5.}, ""}; - ConfigurableAxis axisSigmaMass{"axisSigmaMass", {100, 1.1, 1.4}, ""}; - ConfigurableAxis axisXiMass{"axisXiMass", {100, 1.2, 1.5}, ""}; + ConfigurableAxis axisSigmaMass{"axisSigmaMass", {300, 1.1, 1.4}, ""}; + ConfigurableAxis axisXiMass{"axisXiMass", {300, 1.2, 1.5}, ""}; ConfigurableAxis axisVertexZ{"axisVertexZ", {100, -15., 15.}, ""}; ConfigurableAxis axisQtAP{"axisQtAP", {100, 0., 0.3}, ""}; ConfigurableAxis axisAlphaAP{"axisAlphaAP", {200, -1., 1.}, ""}; ConfigurableAxis axisSigmaRadius{"axisSigmaRadius", {100, 0., 100.}, ""}; ConfigurableAxis axisDcaSigmaToPv{"axisDcaSigmaToPv", {120, 0., 0.05}, ""}; ConfigurableAxis axisDcaKinkToPv{"axisDcaKinkToPv", {200, 0., 20.}, ""}; + ConfigurableAxis axisDcaBachPi{"axisDcaBachPi", {4000, -1., 1.}, ""}; + ConfigurableAxis axisDeltaEta{"axisDeltaEta", {100, -2., 2.}, ""}; + ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {64, -o2::constants::math::PIHalf, 3. * o2::constants::math::PIHalf}, ""}; ConfigurableAxis axisScalarProd{"axisScalarProd", {200, -4., 4.}, ""}; Preslice mKinkPerCol = aod::track::collisionId; @@ -179,165 +229,221 @@ struct lambda1405analysis { const AxisSpec pCompAxisL1405{axisPCompsL1405, "#it{p}_{comp} (GeV/#it{c})"}; const AxisSpec ptKinkDaugAxis{axisPtKinkDaug, "#it{p}_{T}^{#pi} (GeV/#it{c})"}; const AxisSpec ptResolutionAxis{axisPtResolution, "#it{p}_{T}^{rec} - #it{p}_{T}^{gen} (GeV/#it{c})"}; - const AxisSpec lambda1405MassAxis{axisMassL1405, "m (GeV/#it{c}^{2})"}; - const AxisSpec xi1530MassAxis{axisXi1530Mass, "m (GeV/#it{c}^{2})"}; + const AxisSpec lambda1405MassAxis{axisMassL1405, "m(#Sigma#pi) (GeV/#it{c}^{2})"}; + const AxisSpec xi1530MassAxis{axisXi1530Mass, "m(#Xi#pi) (GeV/#it{c}^{2})"}; const AxisSpec massResolutionAxis{axisMassResolution, "m_{rec} - m_{gen} (GeV/#it{c}^{2})"}; const AxisSpec nSigmaAxis{axisNSig, "n#sigma_{#pi}"}; - const AxisSpec sigmaMassAxis{axisSigmaMass, "m (GeV/#it{c}^{2})"}; - const AxisSpec xiMassAxis{axisXiMass, "m (GeV/#it{c}^{2})"}; - const AxisSpec vertexZAxis{axisVertexZ, "vrtx_{Z} [cm]"}; + const AxisSpec sigmaMassAxis{axisSigmaMass, "m(#Sigma) (GeV/#it{c}^{2})"}; + const AxisSpec xiMassAxis{axisXiMass, "m(#Xi) (GeV/#it{c}^{2})"}; + const AxisSpec vertexZAxis{axisVertexZ, "vtx_{Z} (cm)"}; const AxisSpec qtAxis{axisQtAP, "q_{T, AP}"}; const AxisSpec alphaAxis{axisAlphaAP, "#alpha_{AP}"}; - const AxisSpec sigmaRadiusAxis{axisSigmaRadius, "#Sigma radius (cm)"}; - const AxisSpec centAxis{axisCent, "Centrality"}; - const AxisSpec dcaSigmaToPvBinsAxis{axisDcaSigmaToPv, "DCA of mother to Pv"}; - const AxisSpec dcaKinkToPvBinsAxis{axisDcaKinkToPv, "DCA of kink to Pv"}; + const AxisSpec sigmaRadiusAxis{axisSigmaRadius, "Dec. radius #Sigma (cm)"}; + const AxisSpec centMultAxis{axisCent, "Centrality (%)"}; + const AxisSpec occAxis{axisOccupancy, "Occupancy FT0C"}; + const AxisSpec pvContribAxis{axisPvContrib, "PV Contributors"}; + const AxisSpec dcaSigmaToPvAxis{axisDcaSigmaToPv, "#Sigma DCA to PV (cm)"}; + const AxisSpec dcaKinkToPvAxis{axisDcaKinkToPv, "Kink daug. DCA to PV (cm)"}; + const AxisSpec dcaBachPiAxis{axisDcaBachPi, "Bach. #pi DCA to PV (cm)"}; + const AxisSpec deltaEtaAxis{axisDeltaEta, "#Delta#it{#eta}"}; + const AxisSpec deltaPhiAxis{axisDeltaPhi, "#Delta#it{#varphi}"}; const AxisSpec scalarProdAxis{axisScalarProd, "SP"}; rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); + rEventSelection.add("hCentMultVsPvContrib", "hCentMultVsPvContrib", {HistType::kTH2F, {centMultAxis, pvContribAxis}}); + rEventSelection.add("hOccVsPvContrib", "hOccVsPvContrib", {HistType::kTH2F, {occAxis, pvContribAxis}}); + rEventSelection.add("hCentVsOcc", "hCentVsOcc", {HistType::kTH2F, {centMultAxis, occAxis}}); // Sigma- candidate properties - rSigmaMinus.add("hSigmaMinusMass", "hSigmaMinusMass", {HistType::kTH1D, {sigmaMassAxis}}); - rSigmaMinus.add("hSigmaPlusMass", "hSigmaPlusMass", {HistType::kTH1D, {sigmaMassAxis}}); - rSigmaMinus.add("hSigmaMinusPt", "hSigmaMinusPt", {HistType::kTH1D, {ptAxis}}); - rSigmaMinus.add("hMassXiMinusSigmaMinus", "hMassXiMinusSigmaMinus", {HistType::kTH1D, {xiMassAxis}}); + rSigmaMinus.add("hMassXiMinusSigmaMinus", "hMassXiMinusSigmaMinus", {HistType::kTH2F, {xiMassAxis, sigmaMassAxis}}); rSigmaMinus.add("h2PtMassSigmaMinusBeforeCuts", "h2PtMassSigmaMinusBeforeCuts", {HistType::kTH2F, {ptAxis, sigmaMassAxis}}); rSigmaMinus.add("h2PtPiKinkNSigBeforeCutsSigmaMinus", "h2PtPiKinkNSigBeforeCutsSigmaMinus", {HistType::kTH2F, {ptAxis, nSigmaAxis}}); rSigmaMinus.add("h2dPtMassSigmaMinus", "h2dPtMassSigmaMinus", {HistType::kTH2F, {ptAxis, sigmaMassAxis}}); - rSigmaMinus.add("h2SigmaMinusMassVsLambdaMass", "h2SigmaMinusMassVsLambdaMass", {HistType::kTH2F, {lambda1405MassAxis, sigmaMassAxis}}); + rSigmaMinus.add("h2dPvContribMassSigmaMinus", "h2dPvContribMassSigmaMinus", {HistType::kTH2F, {pvContribAxis, sigmaMassAxis}}); + rSigmaMinus.add("h2dOccMassSigmaMinus", "h2dOccMassSigmaMinus", {HistType::kTH2F, {occAxis, sigmaMassAxis}}); + rSigmaMinus.add("h2dPvContribPtSigmaMinus", "h2dPvContribPtSigmaMinus", {HistType::kTH2F, {pvContribAxis, ptAxis}}); rSigmaMinus.add("h2KinkPiPtNSigTofSigmaMinus", "h2KinkPiPtNSigTofSigmaMinus", {HistType::kTH2F, {ptKinkDaugAxis, nSigmaAxis}}); - rSigmaMinus.add("h2KinkPrPtNSigTofSigmaMinus", "h2KinkPrPtNSigTofSigmaMinus", {HistType::kTH2F, {ptKinkDaugAxis, nSigmaAxis}}); rSigmaMinus.add("hSigmaMinusArmPod", "hSigmaMinusArmPod", {HistType::kTH2D, {alphaAxis, qtAxis}}); - rSigmaMinus.add("hSigmaMinusRadius", "hSigmaMinusRadius", {HistType::kTH1D, {sigmaRadiusAxis}}); - rSigmaMinus.add("hSigmaMinusDcaToPv", "hSigmaMinusDcaToPv", {HistType::kTH1D, {dcaSigmaToPvBinsAxis}}); - rSigmaMinus.add("hSigmaMinusKinkPt", "hSigmaMinusKinkPt", {HistType::kTH1D, {ptKinkDaugAxis}}); - rSigmaMinus.add("hSigmaMinusKinkTpcNSigPi", "hSigmaMinusKinkTpcNSigPi", {HistType::kTH1D, {nSigmaAxis}}); - rSigmaMinus.add("hSigmaMinusKinkTofNSigPi", "hSigmaMinusKinkTofNSigPi", {HistType::kTH1D, {nSigmaAxis}}); - rSigmaMinus.add("hSigmaMinusDcaKinkDauToPv", "hSigmaMinusDcaKinkDauToPv", {HistType::kTH1D, {dcaKinkToPvBinsAxis}}); + rSigmaMinus.add("hSigmaMinusRadius", "hSigmaMinusRadius", {HistType::kTH2F, {sigmaRadiusAxis, ptAxis}}); + rSigmaMinus.add("hSigmaMinusDcaToPv", "hSigmaMinusDcaToPv", {HistType::kTH2F, {dcaSigmaToPvAxis, ptAxis}}); + rSigmaMinus.add("hSigmaMinusKinkTpcNSigPi", "hSigmaMinusKinkTpcNSigPi", {HistType::kTH2F, {nSigmaAxis, ptKinkDaugAxis}}); + rSigmaMinus.add("hSigmaMinusKinkTofNSigPi", "hSigmaMinusKinkTofNSigPi", {HistType::kTH2F, {nSigmaAxis, ptKinkDaugAxis}}); + rSigmaMinus.add("hSigmaMinusDcaKinkDauToPv", "hSigmaMinusDcaKinkDauToPv", {HistType::kTH2F, {dcaKinkToPvAxis, ptAxis}}); + if (recomputeSigmaMom) { + rSigmaMinus.add("hDeltaPxRecalcSigmaMinus", "hDeltaPxRecalcSigmaMinus;#Delta #it{p}_{x}/p_{x};#it{p}_{x}", {HistType::kTH2F, {{800, -4, 4}, ptAxis}}); + rSigmaMinus.add("hDeltaPyRecalcSigmaMinus", "hDeltaPyRecalcSigmaMinus;#Delta #it{p}_{y}/p_{y};#it{p}_{y}", {HistType::kTH2F, {{800, -4, 4}, ptAxis}}); + rSigmaMinus.add("hDeltaPzRecalcSigmaMinus", "hDeltaPzRecalcSigmaMinus;#Delta #it{p}_{z}/p_{z};#it{p}_{z}", {HistType::kTH2F, {{800, -4, 4}, ptAxis}}); + rSigmaMinus.add("hRecalcPtFactorSigmaMinus", "hRecalcPtFactorSigmaMinus;Rescale factor;|#it{p}|", {HistType::kTH2F, {{250, 0, 5}, ptAxis}}); + } // Sigma+ candidate properties - rSigmaPlus.add("hSigmaMinusMass", "hSigmaMinusMass", {HistType::kTH1D, {sigmaMassAxis}}); - rSigmaPlus.add("hSigmaPlusMass", "hSigmaPlusMass", {HistType::kTH1D, {sigmaMassAxis}}); - rSigmaPlus.add("hSigmaPlusPt", "hSigmaPlusPt", {HistType::kTH1D, {ptAxis}}); rSigmaPlus.add("h2PtMassSigmaPlusBeforeCuts", "h2PtMassSigmaPlusBeforeCuts", {HistType::kTH2F, {ptAxis, sigmaMassAxis}}); - rSigmaPlus.add("h2PtPiKinkNSigBeforeCutsSigmaPlus", "h2PtPiKinkNSigBeforeCutsSigmaPlus", {HistType::kTH2F, {ptAxis, nSigmaAxis}}); - rSigmaPlus.add("h2PtPrKinkNSigBeforeCutsSigmaPlus", "h2PtPrKinkNSigBeforeCutsSigmaPlus", {HistType::kTH2F, {ptAxis, nSigmaAxis}}); + rSigmaPlus.add("h2PtPrKinkNSigBeforeCuts", "h2PtPrKinkNSigBeforeCuts", {HistType::kTH2F, {ptAxis, nSigmaAxis}}); rSigmaPlus.add("h2dPtMassSigmaPlus", "h2dPtMassSigmaPlus", {HistType::kTH2F, {ptAxis, sigmaMassAxis}}); - rSigmaPlus.add("h2SigmaPlusMassVsLambdaMass", "h2SigmaPlusMassVsLambdaMass", {HistType::kTH2F, {lambda1405MassAxis, sigmaMassAxis}}); + rSigmaPlus.add("h2dPvContribMassSigmaPlus", "h2dPvContribMassSigmaPlus", {HistType::kTH2F, {pvContribAxis, sigmaMassAxis}}); + rSigmaPlus.add("h2dOccMassSigmaPlus", "h2dOccMassSigmaPlus", {HistType::kTH2F, {occAxis, sigmaMassAxis}}); + rSigmaPlus.add("h2dPvContribPtSigmaPlus", "h2dPvContribPtSigmaPlus", {HistType::kTH2F, {pvContribAxis, ptAxis}}); rSigmaPlus.add("h2KinkPrPtNSigTofSigmaPlus", "h2KinkPrPtNSigTofSigmaPlus", {HistType::kTH2F, {ptKinkDaugAxis, nSigmaAxis}}); - rSigmaPlus.add("hSigmaPlusArmPod", "hSigmaPlusArmPod", {HistType::kTH2D, {alphaAxis, qtAxis}}); - rSigmaPlus.add("hSigmaPlusRadius", "hSigmaPlusRadius", {HistType::kTH1D, {sigmaRadiusAxis}}); - rSigmaPlus.add("hSigmaPlusDcaToPv", "hSigmaPlusDcaToPv", {HistType::kTH1D, {dcaSigmaToPvBinsAxis}}); - rSigmaPlus.add("hSigmaPlusKinkPt", "hSigmaPlusKinkPt", {HistType::kTH1D, {ptKinkDaugAxis}}); - rSigmaPlus.add("hSigmaPlusKinkTpcNSigPi", "hSigmaPlusKinkTpcNSigPi", {HistType::kTH1D, {nSigmaAxis}}); - rSigmaPlus.add("hSigmaPlusKinkTofNSigPi", "hSigmaPlusKinkTofNSigPi", {HistType::kTH1D, {nSigmaAxis}}); - rSigmaPlus.add("hSigmaPlusKinkTpcNSigPr", "hSigmaPlusKinkTpcNSigPr", {HistType::kTH1D, {nSigmaAxis}}); - rSigmaPlus.add("hSigmaPlusKinkTofNSigPr", "hSigmaPlusKinkTofNSigPr", {HistType::kTH1D, {nSigmaAxis}}); - rSigmaPlus.add("hSigmaPlusDcaKinkDauToPv", "hSigmaPlusDcaKinkDauToPv", {HistType::kTH1D, {dcaKinkToPvBinsAxis}}); - rSigmaPlus.add("hMassXiMinusSigmaPlus", "hMassXiMinusSigmaPlus", {HistType::kTH1D, {xiMassAxis}}); + rSigmaPlus.add("hSigmaPlusArmPod", "hSigmaPlusArmPod", {HistType::kTH2F, {alphaAxis, qtAxis}}); + rSigmaPlus.add("hSigmaPlusRadius", "hSigmaPlusRadius", {HistType::kTH2F, {sigmaRadiusAxis, ptAxis}}); + rSigmaPlus.add("hSigmaPlusDcaToPv", "hSigmaPlusDcaToPv", {HistType::kTH2F, {dcaSigmaToPvAxis, ptAxis}}); + rSigmaPlus.add("hSigmaPlusKinkTpcNSigPr", "hSigmaPlusKinkTpcNSigPr", {HistType::kTH2F, {nSigmaAxis, ptKinkDaugAxis}}); + rSigmaPlus.add("hSigmaPlusKinkTofNSigPr", "hSigmaPlusKinkTofNSigPr", {HistType::kTH2F, {nSigmaAxis, ptKinkDaugAxis}}); + rSigmaPlus.add("hSigmaPlusDcaKinkDauToPv", "hSigmaPlusDcaKinkDauToPv", {HistType::kTH2F, {dcaKinkToPvAxis, ptKinkDaugAxis}}); + rSigmaPlus.add("hMassXiMinusSigmaPlus", "hMassXiMinusSigmaPlus", {HistType::kTH2F, {xiMassAxis, sigmaMassAxis}}); + if (recomputeSigmaMom) { + rSigmaPlus.add("hDeltaPxRecalcSigmaPlus", "hDeltaPxRecalcSigmaPlus;#Delta #it{p}_{x}/p_{x};#it{p}_{x}", {HistType::kTH2F, {{800, -4, 4}, ptAxis}}); + rSigmaPlus.add("hDeltaPyRecalcSigmaPlus", "hDeltaPyRecalcSigmaPlus;#Delta #it{p}_{y}/p_{y};#it{p}_{y}", {HistType::kTH2F, {{800, -4, 4}, ptAxis}}); + rSigmaPlus.add("hDeltaPzRecalcSigmaPlus", "hDeltaPzRecalcSigmaPlus;#Delta #it{p}_{z}/p_{z};#it{p}_{z}", {HistType::kTH2F, {{800, -4, 4}, ptAxis}}); + rSigmaPlus.add("hRecalcPtFactorSigmaPlus", "hRecalcPtFactorSigmaPlus;Rescale factor;|#it{p}|", {HistType::kTH2F, {{250, 0, 5}, ptAxis}}); + } // Mass QA - rLambda1405.add("hMassL1405", "hMassL1405", {HistType::kTH1D, {lambda1405MassAxis}}); - rLambda1405.add("hMassXi1530", "hMassXi1530", {HistType::kTH1D, {xi1530MassAxis}}); + rLambda1405.add("h2SigmaMinusMassVsLambdaMass", "h2SigmaMinusMassVsLambdaMass", {HistType::kTH2F, {lambda1405MassAxis, sigmaMassAxis}}); + rLambda1405.add("h2SigmaPlusMassVsLambdaMass", "h2SigmaPlusMassVsLambdaMass", {HistType::kTH2F, {lambda1405MassAxis, sigmaMassAxis}}); + rLambda1405.add("hMassL1405", "hMassL1405", {HistType::kTH2F, {lambda1405MassAxis, ptAxis}}); + rLambda1405.add("hMassXi1530", "hMassXi1530", {HistType::kTH2F, {xi1530MassAxis, ptAxis}}); // Kinematic distributions - rLambda1405.add("hPx", "hPx;#it{p}_x;Counts", {HistType::kTH1D, {pCompAxisL1405}}); - rLambda1405.add("hPy", "hPy;#it{p}_y;Counts", {HistType::kTH1D, {pCompAxisL1405}}); - rLambda1405.add("hPz", "hPz;#it{p}_z;Counts", {HistType::kTH1D, {pCompAxisL1405}}); + rLambda1405.add("hPx", "hPx;#it{p}_{x};Counts", {HistType::kTH1D, {pCompAxisL1405}}); + rLambda1405.add("hPy", "hPy;#it{p}_{y};Counts", {HistType::kTH1D, {pCompAxisL1405}}); + rLambda1405.add("hPz", "hPz;#it{p}_{z};Counts", {HistType::kTH1D, {pCompAxisL1405}}); rLambda1405.add("hPt", "hPt", {HistType::kTH1D, {ptAxis}}); rLambda1405.add("hPhi", "hPhi", {HistType::kTH1D, {{128, -o2::constants::math::PI, o2::constants::math::PI}}}); + // Correlation histograms + rLambda1405.add("hDeltaEta", "hDeltaEta", {HistType::kTH1D, {deltaEtaAxis}}); + rLambda1405.add("hDeltaPhi", "hDeltaPhi", {HistType::kTH1D, {deltaPhiAxis}}); // Pion daughter properties - rLambda1405.add("hBachPiPt", "hBachPiPt", {HistType::kTH1D, {ptKinkDaugAxis}}); - rLambda1405.add("hBachPiNSigTpc", "hBachPiNSigTpc", {HistType::kTH1D, {nSigmaAxis}}); - rLambda1405.add("hBachPiNSigTof", "hBachPtNSigTof", {HistType::kTH1D, {nSigmaAxis}}); + rLambda1405.add("hPairedBachPiVsCent", "hPairedBachPiVsCent", {HistType::kTH2F, {centMultAxis, {1000, -0.5, 999.5}}}); rLambda1405.add("h2BachPiPtNSigTof", "h2BachPiPtNSigTof", {HistType::kTH2F, {ptKinkDaugAxis, nSigmaAxis}}); rLambda1405.add("h2BachPiPtNSigTpc", "h2BachPiPtNSigTpc", {HistType::kTH2F, {ptKinkDaugAxis, nSigmaAxis}}); + rLambda1405.add("h3BachPiDcaXYVsPt", "h3BachPiDcaXYVsPt", {HistType::kTH3F, {ptKinkDaugAxis, dcaBachPiAxis, centMultAxis}}); + rLambda1405.add("h3BachPiDcaZVsPt", "h3BachPiDcaZVsPt", {HistType::kTH3F, {ptKinkDaugAxis, dcaBachPiAxis, centMultAxis}}); + // Sparse histograms + std::vector axesMass = {lambda1405MassAxis, ptAxis, sigmaMassAxis, dcaSigmaToPvAxis, dcaKinkToPvAxis}; + if (doprocessMc || doprocessMcWCentSel) { + axesMass.push_back(pvContribAxis); + } else { + axesMass.push_back(centMultAxis); + } + rLambda1405.add("hSparseL1405", "THn for mass peak", HistType::kTHnSparseF, axesMass); + std::vector axesScalarProd = {lambda1405MassAxis, ptAxis, sigmaMassAxis, dcaSigmaToPvAxis, dcaKinkToPvAxis, centMultAxis, scalarProdAxis}; + if (doprocessDataWCentQVecs) { + rLambda1405.add("hSparseL1405ScalProd", "THn for SP", HistType::kTHnSparseF, axesScalarProd); + } + std::vector axesCorrel = {lambda1405MassAxis, ptAxis, deltaEtaAxis, deltaPhiAxis}; + if (saveDEtaDPhi) { + rLambda1405.add("hSparseL1405Correl", "THn for 2PC", HistType::kTHnSparseF, axesCorrel); + } // Selection QA - rSelections.add("hSelectionsL1405", "hSelectionsL1405", {HistType::kTH1D, {{7, -0.f, 6.5f}}}); + rSelections.add("hSelectionsL1405", "hSelectionsL1405", {HistType::kTH1D, {{6, -0.f, 5.5f}}}); rSelections.get(HIST("hSelectionsL1405"))->GetXaxis()->SetBinLabel(1, "All"); - rSelections.get(HIST("hSelectionsL1405"))->GetXaxis()->SetBinLabel(2, "Passed Sigma sel"); - rSelections.get(HIST("hSelectionsL1405"))->GetXaxis()->SetBinLabel(3, "Passed Bach PID sel"); + rSelections.get(HIST("hSelectionsL1405"))->GetXaxis()->SetBinLabel(2, "Sigma sel"); + rSelections.get(HIST("hSelectionsL1405"))->GetXaxis()->SetBinLabel(3, "Bach PID sel"); rSelections.get(HIST("hSelectionsL1405"))->GetXaxis()->SetBinLabel(4, "Upper mass sel"); - rSelections.get(HIST("hSelectionsL1405"))->GetXaxis()->SetBinLabel(5, "Correl. #Sigma #it{p}_{T} sel"); - rSelections.get(HIST("hSelectionsL1405"))->GetXaxis()->SetBinLabel(6, "Correl. bach. #pi #it{p}_{T} sel"); - rSelections.get(HIST("hSelectionsL1405"))->GetXaxis()->SetBinLabel(7, "Accepted"); - rSelections.add("hSelectionsSigmaPlus", "hSelectionsSigmaPlus", {HistType::kTH1D, {{7, -0.f, 6.5f}}}); + rSelections.get(HIST("hSelectionsL1405"))->GetXaxis()->SetBinLabel(5, "#it{p}_{T} Correl"); + rSelections.get(HIST("hSelectionsL1405"))->GetXaxis()->SetBinLabel(6, "Accepted"); + rSelections.add("hSelectionsSigmaPlus", "hSelectionsSigmaPlus", {HistType::kTH1D, {{8, -0.f, 7.5f}}}); rSelections.get(HIST("hSelectionsSigmaPlus"))->GetXaxis()->SetBinLabel(1, "All"); - rSelections.get(HIST("hSelectionsSigmaPlus"))->GetXaxis()->SetBinLabel(2, "Passed kink sel"); - rSelections.get(HIST("hSelectionsSigmaPlus"))->GetXaxis()->SetBinLabel(3, "Passed mass sel"); - rSelections.get(HIST("hSelectionsSigmaPlus"))->GetXaxis()->SetBinLabel(4, "Passed cutDCAtoPvSigma"); - rSelections.get(HIST("hSelectionsSigmaPlus"))->GetXaxis()->SetBinLabel(5, "Passed cutDCAtoPvPiFromSigma"); - rSelections.get(HIST("hSelectionsSigmaPlus"))->GetXaxis()->SetBinLabel(6, "Passed cutSigmaRadius"); - rSelections.get(HIST("hSelectionsSigmaPlus"))->GetXaxis()->SetBinLabel(7, "Passed cutSigmaQtAP"); - rSelections.add("hSelectionsSigmaMinus", "hSelectionsSigmaMinus", {HistType::kTH1D, {{7, -0.f, 6.5f}}}); + rSelections.get(HIST("hSelectionsSigmaPlus"))->GetXaxis()->SetBinLabel(2, "Kink"); + rSelections.get(HIST("hSelectionsSigmaPlus"))->GetXaxis()->SetBinLabel(3, "Mom recomp."); + rSelections.get(HIST("hSelectionsSigmaPlus"))->GetXaxis()->SetBinLabel(4, "Mass"); + rSelections.get(HIST("hSelectionsSigmaPlus"))->GetXaxis()->SetBinLabel(5, "DCA PV #Sigma"); + rSelections.get(HIST("hSelectionsSigmaPlus"))->GetXaxis()->SetBinLabel(6, "DCA PV #pi #leftarrow #Sigma"); + rSelections.get(HIST("hSelectionsSigmaPlus"))->GetXaxis()->SetBinLabel(7, "#Sigma Radius"); + rSelections.get(HIST("hSelectionsSigmaPlus"))->GetXaxis()->SetBinLabel(8, "#Sigma Qt"); + rSelections.add("hSelectionsSigmaMinus", "hSelectionsSigmaMinus", {HistType::kTH1D, {{8, -0.f, 7.5f}}}); rSelections.get(HIST("hSelectionsSigmaMinus"))->GetXaxis()->SetBinLabel(1, "All"); - rSelections.get(HIST("hSelectionsSigmaMinus"))->GetXaxis()->SetBinLabel(2, "Passed kink sel"); - rSelections.get(HIST("hSelectionsSigmaMinus"))->GetXaxis()->SetBinLabel(3, "Passed mass sel"); - rSelections.get(HIST("hSelectionsSigmaMinus"))->GetXaxis()->SetBinLabel(4, "Passed cutDCAtoPvSigma"); - rSelections.get(HIST("hSelectionsSigmaMinus"))->GetXaxis()->SetBinLabel(5, "Passed cutDCAtoPvPiFromSigma"); - rSelections.get(HIST("hSelectionsSigmaMinus"))->GetXaxis()->SetBinLabel(6, "Passed cutSigmaRadius"); - rSelections.get(HIST("hSelectionsSigmaMinus"))->GetXaxis()->SetBinLabel(7, "Passed cutSigmaQtAP"); + rSelections.get(HIST("hSelectionsSigmaMinus"))->GetXaxis()->SetBinLabel(2, "Kink"); + rSelections.get(HIST("hSelectionsSigmaMinus"))->GetXaxis()->SetBinLabel(3, "Mom recomp."); + rSelections.get(HIST("hSelectionsSigmaMinus"))->GetXaxis()->SetBinLabel(4, "Mass"); + rSelections.get(HIST("hSelectionsSigmaMinus"))->GetXaxis()->SetBinLabel(5, "DCA PV #Sigma"); + rSelections.get(HIST("hSelectionsSigmaMinus"))->GetXaxis()->SetBinLabel(6, "DCA PV Pi #leftarrow #Sigma"); + rSelections.get(HIST("hSelectionsSigmaMinus"))->GetXaxis()->SetBinLabel(7, "#Sigma Radius"); + rSelections.get(HIST("hSelectionsSigmaMinus"))->GetXaxis()->SetBinLabel(8, "#Sigma Qt"); + rSelections.add("hRecalcSigmaPlusMom", "hRecalcSigmaPlusMom", {HistType::kTH1D, {{5, -0.f, 4.5f}}}); + rSelections.get(HIST("hRecalcSigmaPlusMom"))->GetXaxis()->SetBinLabel(1, "All"); + rSelections.get(HIST("hRecalcSigmaPlusMom"))->GetXaxis()->SetBinLabel(2, "Non-null mom."); + rSelections.get(HIST("hRecalcSigmaPlusMom"))->GetXaxis()->SetBinLabel(3, "Non-null A"); + rSelections.get(HIST("hRecalcSigmaPlusMom"))->GetXaxis()->SetBinLabel(4, "Positive D"); + rSelections.get(HIST("hRecalcSigmaPlusMom"))->GetXaxis()->SetBinLabel(5, "Real sol."); + rSelections.add("hRecalcSigmaMinusMom", "hRecalcSigmaMinusMom", {HistType::kTH1D, {{5, -0.f, 4.5f}}}); + rSelections.get(HIST("hRecalcSigmaMinusMom"))->GetXaxis()->SetBinLabel(1, "All"); + rSelections.get(HIST("hRecalcSigmaMinusMom"))->GetXaxis()->SetBinLabel(2, "Non-null mom."); + rSelections.get(HIST("hRecalcSigmaMinusMom"))->GetXaxis()->SetBinLabel(3, "Non-null A"); + rSelections.get(HIST("hRecalcSigmaMinusMom"))->GetXaxis()->SetBinLabel(4, "Positive D"); + rSelections.get(HIST("hRecalcSigmaMinusMom"))->GetXaxis()->SetBinLabel(5, "Real sol."); rSelections.add("hSelectionsBachPi", "hSelectionsBachPi", {HistType::kTH1D, {{6, -0.f, 5.5f}}}); rSelections.get(HIST("hSelectionsBachPi"))->GetXaxis()->SetBinLabel(1, "All"); - rSelections.get(HIST("hSelectionsBachPi"))->GetXaxis()->SetBinLabel(2, "Sign sel"); - rSelections.get(HIST("hSelectionsBachPi"))->GetXaxis()->SetBinLabel(3, "Nsigma Tpc sel"); - rSelections.get(HIST("hSelectionsBachPi"))->GetXaxis()->SetBinLabel(4, "Tpc clusters sel"); - rSelections.get(HIST("hSelectionsBachPi"))->GetXaxis()->SetBinLabel(5, "#eta sel"); - rSelections.get(HIST("hSelectionsBachPi"))->GetXaxis()->SetBinLabel(6, "PID sel"); + rSelections.get(HIST("hSelectionsBachPi"))->GetXaxis()->SetBinLabel(2, "Sign"); + rSelections.get(HIST("hSelectionsBachPi"))->GetXaxis()->SetBinLabel(3, "Tpc N#sigma"); + rSelections.get(HIST("hSelectionsBachPi"))->GetXaxis()->SetBinLabel(4, "Tpc Ncls"); + rSelections.get(HIST("hSelectionsBachPi"))->GetXaxis()->SetBinLabel(5, "#eta"); + rSelections.get(HIST("hSelectionsBachPi"))->GetXaxis()->SetBinLabel(6, "DCA"); rSelections.add("hSelectionsKinkPi", "hSelectionsKinkPi", {HistType::kTH1D, {{7, -0.f, 6.5f}}}); rSelections.get(HIST("hSelectionsKinkPi"))->GetXaxis()->SetBinLabel(1, "All"); - rSelections.get(HIST("hSelectionsKinkPi"))->GetXaxis()->SetBinLabel(2, "Tpc N#sigma PID sel"); - rSelections.get(HIST("hSelectionsKinkPi"))->GetXaxis()->SetBinLabel(3, "Tpc N clusters sel"); - rSelections.get(HIST("hSelectionsKinkPi"))->GetXaxis()->SetBinLabel(4, "#eta sel"); - rSelections.get(HIST("hSelectionsKinkPi"))->GetXaxis()->SetBinLabel(5, "ITS clusters sel"); - rSelections.get(HIST("hSelectionsKinkPi"))->GetXaxis()->SetBinLabel(6, "has Tof sel"); - rSelections.get(HIST("hSelectionsKinkPi"))->GetXaxis()->SetBinLabel(7, "N#sigma Tof sel"); + rSelections.get(HIST("hSelectionsKinkPi"))->GetXaxis()->SetBinLabel(2, "Tpc N#sigma"); + rSelections.get(HIST("hSelectionsKinkPi"))->GetXaxis()->SetBinLabel(3, "Tpc Ncls"); + rSelections.get(HIST("hSelectionsKinkPi"))->GetXaxis()->SetBinLabel(4, "#eta"); + rSelections.get(HIST("hSelectionsKinkPi"))->GetXaxis()->SetBinLabel(5, "ITS cls"); + rSelections.get(HIST("hSelectionsKinkPi"))->GetXaxis()->SetBinLabel(6, "has TOF"); + rSelections.get(HIST("hSelectionsKinkPi"))->GetXaxis()->SetBinLabel(7, "N#sigma TOF"); rSelections.add("hSelectionsKinkPr", "hSelectionsKinkPr", {HistType::kTH1D, {{7, -0.f, 6.5f}}}); rSelections.get(HIST("hSelectionsKinkPr"))->GetXaxis()->SetBinLabel(1, "All"); - rSelections.get(HIST("hSelectionsKinkPr"))->GetXaxis()->SetBinLabel(2, "Tpc N#sigma PID sel"); - rSelections.get(HIST("hSelectionsKinkPr"))->GetXaxis()->SetBinLabel(3, "Tpc N clusters sel"); - rSelections.get(HIST("hSelectionsKinkPr"))->GetXaxis()->SetBinLabel(4, "#eta sel"); - rSelections.get(HIST("hSelectionsKinkPr"))->GetXaxis()->SetBinLabel(5, "ITS clusters sel"); - rSelections.get(HIST("hSelectionsKinkPr"))->GetXaxis()->SetBinLabel(6, "has Tof sel"); - rSelections.get(HIST("hSelectionsKinkPr"))->GetXaxis()->SetBinLabel(7, "N#sigma Tof sel"); + rSelections.get(HIST("hSelectionsKinkPr"))->GetXaxis()->SetBinLabel(2, "Tpc N#sigma"); + rSelections.get(HIST("hSelectionsKinkPr"))->GetXaxis()->SetBinLabel(3, "Tpc Ncls"); + rSelections.get(HIST("hSelectionsKinkPr"))->GetXaxis()->SetBinLabel(4, "#eta"); + rSelections.get(HIST("hSelectionsKinkPr"))->GetXaxis()->SetBinLabel(5, "ITS cls"); + rSelections.get(HIST("hSelectionsKinkPr"))->GetXaxis()->SetBinLabel(6, "has TOF"); + rSelections.get(HIST("hSelectionsKinkPr"))->GetXaxis()->SetBinLabel(7, "N#sigma TOF"); if (doprocessDataWCentQVecs) { - rLambda1405.add("hScalarProd", "hScalarProd", {HistType::kTH1D, {scalarProdAxis}}); - std::vector axesFlow = {lambda1405MassAxis, ptAxis, centAxis, scalarProdAxis}; + rLambda1405.add("hScalarProd", "hScalarProd", {HistType::kTH2F, {scalarProdAxis, ptAxis}}); + std::vector axesFlow = {lambda1405MassAxis, ptAxis, centMultAxis, scalarProdAxis}; rLambda1405.add("hSparseFlowL1405", "THn for SP", HistType::kTHnSparseF, axesFlow); } + // Add MC histograms if (doprocessMc || doprocessMcWCentSel) { - // Add MC histograms if needed, to sigmaminus - rLambda1405.add("hRecoL1405", "hRecoL1405;;Counts", {HistType::kTH2F, {{6, -0.5, 5.5}, ptAxis}}); - rLambda1405.get(HIST("hRecoL1405"))->GetXaxis()->SetBinLabel(1, "Reconstructed #Sigma (1405)"); - rLambda1405.get(HIST("hRecoL1405"))->GetXaxis()->SetBinLabel(2, "Has MC particle"); - rLambda1405.get(HIST("hRecoL1405"))->GetXaxis()->SetBinLabel(3, "Has #Sigma daug"); - rLambda1405.get(HIST("hRecoL1405"))->GetXaxis()->SetBinLabel(4, "Has bach #pi"); - rLambda1405.get(HIST("hRecoL1405"))->GetXaxis()->SetBinLabel(5, "Has mothers"); - rLambda1405.get(HIST("hRecoL1405"))->GetXaxis()->SetBinLabel(6, "Has same mother"); + + rSelections.add("hRecoNotMatchedCounter", "hRecoNotMatchedCounter", {HistType::kTH1D, {{4, -0.5, 3.5f}}}); + rSelections.get(HIST("hRecoNotMatchedCounter"))->GetXaxis()->SetBinLabel(1, "#Lambda(1405)"); + rSelections.get(HIST("hRecoNotMatchedCounter"))->GetXaxis()->SetBinLabel(2, "#Sigma"); + rSelections.get(HIST("hRecoNotMatchedCounter"))->GetXaxis()->SetBinLabel(3, "Kink daug"); + rSelections.get(HIST("hRecoNotMatchedCounter"))->GetXaxis()->SetBinLabel(4, "Bach #pi"); + + rSigmaPlus.add("h2DeltaGenRecoPtSigmaPlus", "h2DeltaGenRecoPtSigmaPlus", {HistType::kTH2F, {{600, -3, 3}, ptAxis}}); + rSigmaPlus.add("h2GenSigmaPlusPvContribPt", "h2GenSigmaPlusPvContribPt", {HistType::kTH2F, {pvContribAxis, ptAxis}}); + rSigmaMinus.add("h2DeltaGenRecoPtSigmaMinus", "h2DeltaGenRecoPtSigmaMinus", {HistType::kTH2F, {{600, -3, 3}, ptAxis}}); + rSigmaMinus.add("h2GenSigmaMinusPvContribPt", "h2GenSigmaMinusPvContribPt", {HistType::kTH2F, {pvContribAxis, ptAxis}}); + + rLambda1405.add("hRecoL1405", "hRecoL1405;;Counts", {HistType::kTH2F, {{4, -0.5, 3.5}, ptAxis}}); + rLambda1405.get(HIST("hRecoL1405"))->GetXaxis()->SetBinLabel(1, "Reco #Lambda(1405)"); + rLambda1405.get(HIST("hRecoL1405"))->GetXaxis()->SetBinLabel(2, "Has bach #pi"); + rLambda1405.get(HIST("hRecoL1405"))->GetXaxis()->SetBinLabel(3, "Has mothers"); + rLambda1405.get(HIST("hRecoL1405"))->GetXaxis()->SetBinLabel(4, "Matched"); rLambda1405.add("hGenL1405", "hGenL1405;;Counts", {HistType::kTH2F, {{3, -0.5, 2.5}, ptAxis}}); rLambda1405.get(HIST("hGenL1405"))->GetXaxis()->SetBinLabel(1, "#Lambda(1405) #rightarrow #Sigma^{-} #pi^{+} #rightarrow n #pi^{-} #pi^{+}"); rLambda1405.get(HIST("hGenL1405"))->GetXaxis()->SetBinLabel(2, "#Lambda(1405) #rightarrow #Sigma^{+} #pi^{-} #rightarrow n #pi^{+} #pi^{-}"); rLambda1405.get(HIST("hGenL1405"))->GetXaxis()->SetBinLabel(3, "#Lambda(1405) #rightarrow #Sigma^{+} #pi^{-} #rightarrow p #pi^{0} #pi^{-}"); + rLambda1405.add("h2GenL1405PvContribPt", "h2GenL1405PvContribPt", {HistType::kTH2F, {pvContribAxis, ptAxis}}); + rLambda1405.add("h2RecL1405PvContribPt", "h2RecL1405PvContribPt", {HistType::kTH2F, {pvContribAxis, ptAxis}}); rLambda1405.add("h2GenSigmaMinusArmPod", "h2GenSigmaMinusArmPod", {HistType::kTH2F, {alphaAxis, qtAxis}}); rLambda1405.add("h2GenSigmaPlusArmPod", "h2GenSigmaPlusArmPod", {HistType::kTH2F, {alphaAxis, qtAxis}}); - rLambda1405.add("h2GenPtVsBachPtSigmaMinusPiToPiPiNeutron", "h2GenPtVsBachPtSigmaMinusPiToPiPiNeutron;#Lambda(1405) #it{p}_{T} (GeV/c); Bach #pi #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); - rLambda1405.add("h2GenPtVsBachPtSigmaPlusPiToPiPiN", "h2GenPtVsBachPtSigmaPlusPiToPiPiN;#Lambda(1405) #it{p}_{T} (GeV/c); Bach #pi #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); - rLambda1405.add("h2GenPtVsBachPtSigmaPlusPiToPiPiP", "h2GenPtVsBachPtSigmaPlusPiToPiPiP;#Lambda(1405) #it{p}_{T} (GeV/c); Bach #pi #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); - rLambda1405.add("h2GenPtVsSigmaPtSigmaMinusPiToPiPiNeutron", "h2GenPtVsBachPtSigmaMinusPiToPiPiNeutron;#Lambda(1405) #it{p}_{T} (GeV/c); #Sigma #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); - rLambda1405.add("h2GenPtVsSigmaPtSigmaPlusPiToPiPiN", "h2GenPtVsBachPtSigmaPlusPiToPiPiN;#Lambda(1405) #it{p}_{T} (GeV/c); #Sigma #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); - rLambda1405.add("h2GenPtVsSigmaPtSigmaPlusPiToPiPiP", "h2GenPtVsBachPtSigmaPlusPiToPiPiP;#Lambda(1405) #it{p}_{T} (GeV/c); #Sigma #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); - rLambda1405.add("h2GenSigmaPtVsKinkPtSigmaMinusPiToPiPiNeutron", "h2GenSigmaPtVsKinkPtSigmaMinusPiToPiPiNeutron;#Sigma #it{p}_{T} (GeV/c); Kink #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); - rLambda1405.add("h2GenSigmaPtVsKinkPtSigmaPlusPiToPiPiN", "h2GenSigmaPtVsKinkPtSigmaPlusPiTo Pi PiNeutron;#Sigma #it{p}_{T} (GeV/c); Kink #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); - rLambda1405.add("h2GenSigmaPtVsKinkPtSigmaPlusPiToPiPiP", "h2GenSigmaPtVsKinkPtSigmaPlusPiToPiPiP;#Sigma #it{p}_{T} (GeV/c); Kink #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); + rLambda1405.add("h2GenPtVsBachPtSigmaMinus", "h2GenPtVsBachPtSigmaMinus;#Lambda(1405) #it{p}_{T} (GeV/c); Bach #pi #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); + rLambda1405.add("h2GenPtVsBachPtSigmaPlusToPi", "h2GenPtVsBachPtSigmaPlusToPi;#Lambda(1405) #it{p}_{T} (GeV/c); Bach #pi #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); + rLambda1405.add("h2GenPtVsBachPtSigmaPlusToPr", "h2GenPtVsBachPtSigmaPlusToPr;#Lambda(1405) #it{p}_{T} (GeV/c); Bach #pi #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); + rLambda1405.add("h2GenPtVsSigmaMinusPt", "h2GenPtVsBachPtSigmaMinus;#Lambda(1405) #it{p}_{T} (GeV/c); #Sigma #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); + rLambda1405.add("h2GenPtVsSigmaPlusToPiPt", "h2GenPtVsBachPtSigmaPlusToPi;#Lambda(1405) #it{p}_{T} (GeV/c); #Sigma #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); + rLambda1405.add("h2GenPtVsSigmaPlusToPrPt", "h2GenPtVsBachPtSigmaPlusToPr;#Lambda(1405) #it{p}_{T} (GeV/c); #Sigma #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); + rLambda1405.add("h2GenSigmaPtVsKinkPtSigmaMinus", "h2GenSigmaPtVsKinkPtSigmaMinus;#Sigma #it{p}_{T} (GeV/c); Kink #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); + rLambda1405.add("h2GenSigmaPtVsPiKinkPt", "h2GenSigmaPtVsPiKinkPt;#Sigma #it{p}_{T} (GeV/c); Kink #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); + rLambda1405.add("h2GenSigmaPtVsPrKinkPt", "h2GenSigmaPtVsPrKinkPt;#Sigma #it{p}_{T} (GeV/c); Kink #it{p}_{T} (GeV/c)", {HistType::kTH2F, {ptAxis, ptAxis}}); rLambda1405.add("h2MassResolutionFromSigmaMinus", "h2MassResolutionFromSigmaMinus", {HistType::kTH2F, {lambda1405MassAxis, massResolutionAxis}}); rLambda1405.add("h2PtResolutionFromSigmaMinus", "h2PtResolutionFromSigmaMinus", {HistType::kTH2F, {ptAxis, ptResolutionAxis}}); - // Add MC histograms if needed, to sigmaplus rLambda1405.add("h2MassResolutionFromSigmaPlus", "h2MassResolutionFromSigmaPlus", {HistType::kTH2F, {lambda1405MassAxis, massResolutionAxis}}); rLambda1405.add("h2PtResolutionFromSigmaPlus", "h2PtResolutionFromSigmaPlus", {HistType::kTH2F, {ptAxis, ptResolutionAxis}}); - // rLambda1405.add("h2PtMassMCWithSigmaDaug", "h2PtMassMCWithSigmaDaug", {HistType::kTH2F, {ptAxis, lambda1405MassAxis}}); - // rLambda1405.add("h2PtMassMCNoSigmaDaug", "h2PtMassMCNoSigmaDaug", {HistType::kTH2F, {ptAxis, lambda1405MassAxis}}); + rLambda1405.add("h2PtMassMC", "h2PtMassMC", {HistType::kTH2F, {ptAxis, lambda1405MassAxis}}); } // Functional selections @@ -353,6 +459,31 @@ struct lambda1405analysis { LOGF(info, "funcMinSigmaPtVsL1405Pt: %s", Form("%s", cutMinSigmaPtVsL1405Pt.value.data())); funcMaxSigmaPtVsL1405Pt = TF1("funcMaxSigmaPtVsL1405Pt", Form("%s", cutMaxSigmaPtVsL1405Pt.value.data()), 0., 100); LOGF(info, "funcMaxSigmaPtVsL1405Pt: %s", Form("%s", cutMaxSigmaPtVsL1405Pt.value.data())); + funcDcaXYPtCutBachPi = TF1("funcDcaXYPtCutBachPi", Form("[0]*%s", dcaXYPtBachFunc.value.data()), 0.001, 100); + funcDcaXYPtCutBachPi.SetParameter(0, dcaXYBachNSigmaMax); + LOGF(info, "DCAxy pt-dependence function: %s", Form("[0]*%s", dcaXYPtBachFunc.value.data())); + + rSelections.print(); + rSigmaMinus.print(); + rSigmaPlus.print(); + rLambda1405.print(); + + // Info for DCA propagation of bachelor tracks + mRunNumber = 0; + mBz = 0; + ccdb->setURL(ccdbPath); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + } + + template + float getCentMult(const TCollision& collision) + { + if constexpr (requires { collision.centFT0C(); }) { + return collision.centFT0C(); + } else { + return collision.multFT0C(); + } } float alphaAP(const std::array& momMother, const std::array& momKink) @@ -371,15 +502,96 @@ struct lambda1405analysis { return std::sqrt(p2A - dp * dp / p2V0); } + float recalcSigmaMom(bool& success, bool isSigmaMinus, float sigmaPx, float sigmaPy, float sigmaPz, float sigmaDauPx, float sigmaDauPy, float sigmaDauPz) + { + success = false; + if (isSigmaMinus) { + rSelections.fill(HIST("hRecalcSigmaMinusMom"), 0); // All + } else { + rSelections.fill(HIST("hRecalcSigmaPlusMom"), 0); // All + } + // Sigma- -> n + pi- (charged daughter = pion, neutral daughter = neutron) + // Sigma+ -> p + pi0 (charged daughter = proton, neutral daughter = pi0) + double massChargedDau = isSigmaMinus ? o2::constants::physics::MassPionCharged : o2::constants::physics::MassProton; + double massNeutralDau = isSigmaMinus ? o2::constants::physics::MassNeutron : o2::constants::physics::MassPionNeutral; + double massSigma = isSigmaMinus ? o2::constants::physics::MassSigmaMinus : o2::constants::physics::MassSigmaPlus; + + double pMother = std::sqrt(sigmaPx * sigmaPx + sigmaPy * sigmaPy + sigmaPz * sigmaPz); + if (pMother < 1e-12f) { + LOG(info) << "Recalculation of Sigma momentum failed: mother momentum is zero " << sigmaPx << ", " << sigmaPy << ", " << sigmaPz; + return -999.f; + } + if (isSigmaMinus) { + rSelections.fill(HIST("hRecalcSigmaMinusMom"), 1); // Non-zero momentum + } else { + rSelections.fill(HIST("hRecalcSigmaPlusMom"), 1); // Non-zero momentum + } + + double versorX = sigmaPx / pMother; + double versorY = sigmaPy / pMother; + double versorZ = sigmaPz / pMother; + double eChDau = std::sqrt(massChargedDau * massChargedDau + sigmaDauPx * sigmaDauPx + sigmaDauPy * sigmaDauPy + sigmaDauPz * sigmaDauPz); + double a = versorX * sigmaDauPx + versorY * sigmaDauPy + versorZ * sigmaDauPz; + double K = massSigma * massSigma + massChargedDau * massChargedDau - massNeutralDau * massNeutralDau; + double A = 4.0 * (eChDau * eChDau - a * a); + double B = -4.0 * a * K; + double C = 4.0 * eChDau * eChDau * massSigma * massSigma - K * K; + + if (std::abs(A) < 1e-6f) { + LOG(info) << "Recalculation of Sigma momentum failed: A is zero " << sigmaPx << ", " << sigmaPy << ", " << sigmaPz << ", A = " << A << ", B = " << B << ", C = " << C; + return -999.f; + } + if (isSigmaMinus) { + rSelections.fill(HIST("hRecalcSigmaMinusMom"), 2); // Non-zero A + } else { + rSelections.fill(HIST("hRecalcSigmaPlusMom"), 2); // Non-zero A + } + + double D = B * B - 4.0 * A * C; + if (D < 0.0) { + LOG(info) << "Recalculation of Sigma momentum failed: D is negative " << sigmaPx << ", " << sigmaPy << ", " << sigmaPz << ", A = " << A << ", B = " << B << ", C = " << C << ", D = " << D; + return -999.f; + } + if (isSigmaMinus) { + rSelections.fill(HIST("hRecalcSigmaMinusMom"), 3); // Positive D + } else { + rSelections.fill(HIST("hRecalcSigmaPlusMom"), 3); // Positive D + } + + double sqrtD = std::sqrt(D); + double P1 = (-B + sqrtD) / (2.0 * A); + double P2 = (-B - sqrtD) / (2.0 * A); + if (P2 < 0.0 && P1 < 0.0) { + LOG(info) << "Recalculation of Sigma momentum failed: both solutions are negative " << sigmaPx << ", " << sigmaPy << ", " << sigmaPz << ", P1: " << P1 << ", P2: " << P2; + return -999.f; + } + if (isSigmaMinus) { + rSelections.fill(HIST("hRecalcSigmaMinusMom"), 4); // Real solutions + } else { + rSelections.fill(HIST("hRecalcSigmaPlusMom"), 4); // Real solutions + } + + success = true; + if (P2 < 0.0) { + return static_cast(P1); + } + if (P1 < 0.0) { + return static_cast(P2); + } + double p1Diff = std::abs(P1 - pMother); + double p2Diff = std::abs(P2 - pMother); + return static_cast((p1Diff < p2Diff) ? P1 : P2); + } + template - bool selectPiBach(const TTrack& candidate) + bool selectPiBach(const TTrack& candidate, const o2::dataformats::VertexBase& vtx, float centMult) { if (std::abs(candidate.tpcNSigmaPi()) > cutNSigTpc) { return false; } rSelections.fill(HIST("hSelectionsBachPi"), 2); // Nsigma Tpc - if (candidate.tpcNClsFound() < cutNTpcClusPi) { + if (candidate.tpcNClsFound() < cutNTpcClus) { return false; } rSelections.fill(HIST("hSelectionsBachPi"), 3); // Tpc clusters @@ -389,6 +601,18 @@ struct lambda1405analysis { } rSelections.fill(HIST("hSelectionsBachPi"), 4); // Eta selection + o2::track::TrackParCov trackParCovTrack = getTrackParCov(candidate); + std::array dcaInfoMoth; + o2::base::Propagator::Instance()->propagateToDCABxByBz({vtx.getX(), vtx.getY(), vtx.getZ()}, + trackParCovTrack, 2.f, static_cast(cfgMaterialCorrection.value), + &dcaInfoMoth); + rLambda1405.fill(HIST("h3BachPiDcaXYVsPt"), candidate.pt(), dcaInfoMoth[0], centMult); + rLambda1405.fill(HIST("h3BachPiDcaZVsPt"), candidate.pt(), dcaInfoMoth[1], centMult); + if (std::abs(dcaInfoMoth[0]) > funcDcaXYPtCutBachPi.Eval(candidate.pt()) || std::abs(dcaInfoMoth[1]) > cutMaxDcaZBach) { + return false; + } + rSelections.fill(HIST("hSelectionsBachPi"), 5); // DCA selection + return true; } @@ -402,7 +626,7 @@ struct lambda1405analysis { } rSelections.fill(HIST("hSelectionsKinkPi"), 1); // Nsigma Tpc - if (candidate.tpcNClsFound() < cutNTpcClusPi) { + if (candidate.tpcNClsFound() < cutNTpcClus) { return false; } rSelections.fill(HIST("hSelectionsKinkPi"), 2); // Tpc clusters @@ -412,7 +636,7 @@ struct lambda1405analysis { } rSelections.fill(HIST("hSelectionsKinkPi"), 3); // Eta selection - if (candidate.itsNCls() < cutNITSClusKink) { + if (candidate.itsNCls() < cutItsNClusKinkMin || candidate.itsNCls() > cutItsNClusKinkMax) { return false; } rSelections.fill(HIST("hSelectionsKinkPi"), 4); // ITS clusters @@ -440,7 +664,7 @@ struct lambda1405analysis { } rSelections.fill(HIST("hSelectionsKinkPr"), 1); // Nsigma Tpc - if (candidate.tpcNClsFound() < cutNTpcClusPi) { + if (candidate.tpcNClsFound() < cutNTpcClus) { return false; } rSelections.fill(HIST("hSelectionsKinkPr"), 2); // Tpc clusters @@ -450,7 +674,7 @@ struct lambda1405analysis { } rSelections.fill(HIST("hSelectionsKinkPr"), 3); // eta selection - if (candidate.itsNCls() < cutNITSClusKink) { + if (candidate.itsNCls() < cutItsNClusKinkMin || candidate.itsNCls() > cutItsNClusKinkMax) { return false; } rSelections.fill(HIST("hSelectionsKinkPr"), 4); // ITS clusters @@ -472,44 +696,44 @@ struct lambda1405analysis { void fillHistosSigma(const lambda1405candidate& lambda1405Cand, const TCand& sigmaCand, const TTrack& kinkDauTrack) { - if (sigmaCand.mothSign() > 0) { - rSigmaPlus.fill(HIST("hSigmaPlusMass"), sigmaCand.mSigmaPlus()); + if (lambda1405Cand.isSigmaPlus) { rSigmaPlus.fill(HIST("h2dPtMassSigmaPlus"), sigmaCand.ptMoth(), sigmaCand.mSigmaPlus()); - rSigmaPlus.fill(HIST("hMassXiMinusSigmaPlus"), sigmaCand.mXiMinus()); + rSigmaPlus.fill(HIST("h2dPvContribMassSigmaPlus"), lambda1405Cand.pvContrib, sigmaCand.mSigmaPlus()); + rSigmaPlus.fill(HIST("h2dOccMassSigmaPlus"), lambda1405Cand.occupancy, sigmaCand.mSigmaPlus()); + rSigmaPlus.fill(HIST("h2dPvContribPtSigmaPlus"), lambda1405Cand.pvContrib, sigmaCand.ptMoth()); + rSigmaPlus.fill(HIST("hMassXiMinusSigmaPlus"), sigmaCand.mXiMinus(), sigmaCand.mSigmaPlus()); rSigmaPlus.fill(HIST("hSigmaPlusArmPod"), lambda1405Cand.sigmaAlphaAP, lambda1405Cand.sigmaQtAP); - rSigmaPlus.fill(HIST("hSigmaPlusPt"), sigmaCand.ptMoth()); - rSigmaPlus.fill(HIST("hSigmaPlusRadius"), lambda1405Cand.sigmaRadius); - rSigmaPlus.fill(HIST("hSigmaPlusDcaToPv"), sigmaCand.dcaMothPv()); - rSigmaPlus.fill(HIST("hSigmaPlusDcaKinkDauToPv"), sigmaCand.dcaDaugPv()); + rSigmaPlus.fill(HIST("hSigmaPlusRadius"), lambda1405Cand.sigmaRadius, sigmaCand.ptMoth()); + rSigmaPlus.fill(HIST("hSigmaPlusDcaToPv"), sigmaCand.dcaMothPv(), sigmaCand.ptMoth()); + rSigmaPlus.fill(HIST("hSigmaPlusDcaKinkDauToPv"), sigmaCand.dcaDaugPv(), sigmaCand.ptMoth()); + rSigmaPlus.fill(HIST("h2KinkPrPtNSigTofSigmaPlus"), lambda1405Cand.kinkPt, lambda1405Cand.kinkPrNSigTof); // Fill QA histos for kink daughter - rSigmaPlus.fill(HIST("hSigmaPlusKinkPt"), kinkDauTrack.pt()); - rSigmaPlus.fill(HIST("hSigmaPlusKinkTpcNSigPi"), kinkDauTrack.tpcNSigmaPi()); - rSigmaPlus.fill(HIST("hSigmaPlusKinkTofNSigPi"), kinkDauTrack.tofNSigmaPi()); - rSigmaPlus.fill(HIST("hSigmaPlusKinkTpcNSigPr"), kinkDauTrack.tpcNSigmaPr()); - rSigmaPlus.fill(HIST("hSigmaPlusKinkTofNSigPr"), kinkDauTrack.tofNSigmaPr()); + rSigmaPlus.fill(HIST("hSigmaPlusKinkTpcNSigPr"), kinkDauTrack.tpcNSigmaPr(), kinkDauTrack.pt()); + rSigmaPlus.fill(HIST("hSigmaPlusKinkTofNSigPr"), kinkDauTrack.tofNSigmaPr(), kinkDauTrack.pt()); } else { - rSigmaMinus.fill(HIST("hSigmaMinusMass"), sigmaCand.mSigmaMinus()); rSigmaMinus.fill(HIST("h2dPtMassSigmaMinus"), sigmaCand.ptMoth(), sigmaCand.mSigmaMinus()); - rSigmaMinus.fill(HIST("hMassXiMinusSigmaMinus"), sigmaCand.mXiMinus()); + rSigmaMinus.fill(HIST("h2dPvContribMassSigmaMinus"), lambda1405Cand.pvContrib, sigmaCand.mSigmaMinus()); + rSigmaMinus.fill(HIST("h2dOccMassSigmaMinus"), lambda1405Cand.occupancy, sigmaCand.mSigmaMinus()); + rSigmaMinus.fill(HIST("h2dPvContribPtSigmaMinus"), lambda1405Cand.pvContrib, sigmaCand.ptMoth()); + rSigmaMinus.fill(HIST("hMassXiMinusSigmaMinus"), sigmaCand.mXiMinus(), sigmaCand.mSigmaMinus()); rSigmaMinus.fill(HIST("hSigmaMinusArmPod"), lambda1405Cand.sigmaAlphaAP, lambda1405Cand.sigmaQtAP); - rSigmaMinus.fill(HIST("hSigmaMinusPt"), sigmaCand.ptMoth()); - rSigmaMinus.fill(HIST("hSigmaMinusRadius"), lambda1405Cand.sigmaRadius); - rSigmaMinus.fill(HIST("hSigmaMinusDcaToPv"), sigmaCand.dcaMothPv()); - rSigmaMinus.fill(HIST("hSigmaMinusDcaKinkDauToPv"), sigmaCand.dcaDaugPv()); + rSigmaMinus.fill(HIST("hSigmaMinusRadius"), lambda1405Cand.sigmaRadius, sigmaCand.ptMoth()); + rSigmaMinus.fill(HIST("hSigmaMinusDcaToPv"), sigmaCand.dcaMothPv(), sigmaCand.ptMoth()); + rSigmaMinus.fill(HIST("hSigmaMinusDcaKinkDauToPv"), sigmaCand.dcaDaugPv(), sigmaCand.ptMoth()); + rSigmaMinus.fill(HIST("h2KinkPiPtNSigTofSigmaMinus"), lambda1405Cand.kinkPt, lambda1405Cand.kinkPiNSigTof); // Fill QA histos for kink daughter - rSigmaMinus.fill(HIST("hSigmaMinusKinkPt"), kinkDauTrack.pt()); - rSigmaMinus.fill(HIST("hSigmaMinusKinkTpcNSigPi"), kinkDauTrack.tpcNSigmaPi()); - rSigmaMinus.fill(HIST("hSigmaMinusKinkTofNSigPi"), kinkDauTrack.tofNSigmaPi()); + rSigmaMinus.fill(HIST("hSigmaMinusKinkTpcNSigPi"), kinkDauTrack.tpcNSigmaPi(), kinkDauTrack.pt()); + rSigmaMinus.fill(HIST("hSigmaMinusKinkTofNSigPi"), kinkDauTrack.tofNSigmaPi(), kinkDauTrack.pt()); } } - template - void fillHistosLambda1405(const lambda1405candidate& cand, const TTrack& piTrack) + template + void fillHistosLambda1405(const lambda1405candidate& cand, const TTrack& trks) { // Fill QA histos for Lambda(1405) candidate - rLambda1405.fill(HIST("hMassL1405"), cand.massL1405); - rLambda1405.fill(HIST("hMassXi1530"), cand.massXi1530); + rLambda1405.fill(HIST("hMassL1405"), cand.massL1405, cand.pt()); + rLambda1405.fill(HIST("hMassXi1530"), cand.massXi1530, cand.pt()); rLambda1405.fill(HIST("hPx"), cand.px); rLambda1405.fill(HIST("hPy"), cand.py); rLambda1405.fill(HIST("hPz"), cand.pz); @@ -517,94 +741,215 @@ struct lambda1405analysis { rLambda1405.fill(HIST("hPhi"), cand.phi); // Bachelor Pi - rLambda1405.fill(HIST("hBachPiPt"), piTrack.pt() * (cand.isSigmaPlus ? -1 : 1)); // Invert pt for Sigma+ to have the correct charge correlation - rLambda1405.fill(HIST("hBachPiNSigTpc"), piTrack.tpcNSigmaPi()); - rLambda1405.fill(HIST("h2BachPiPtNSigTpc"), piTrack.pt(), piTrack.tpcNSigmaPi()); - rLambda1405.fill(HIST("hBachPiNSigTof"), piTrack.tofNSigmaPi()); - rLambda1405.fill(HIST("h2BachPiPtNSigTof"), piTrack.pt(), piTrack.tofNSigmaPi()); + rLambda1405.fill(HIST("h2BachPiPtNSigTpc"), cand.bachPiPt, cand.bachPiNSigTpc); + rLambda1405.fill(HIST("h2BachPiPtNSigTof"), cand.bachPiPt, cand.bachPiNSigTof); + + // std::vector axesMass = {lambda1405MassAxis, ptAxis, sigmaMassAxis, dcaSigmaToPvAxis, dcaKinkToPvAxis}; + // if (doprocessMc || doprocessMcWCentSel) { + // axesMass.push_back(pvContribAxis); + // } else { + // axesMass.push_back(centMultAxis); + // } + // rLambda1405.add("hSparseL1405", "THn for mass peak", HistType::kTHnSparseF, axes); + // std::vector axesScalarProd = {lambda1405MassAxis, ptAxis, sigmaMassAxis, dcaSigmaToPvAxis, dcaKinkToPvAxis, centMultAxis, scalarProdAxis}; + // if (doprocessDataWCentQVecs) { + // rLambda1405.add("hSparseL1405ScalProd", "THn for SP", HistType::kTHnSparseF, axesScalarProd); + // } + // std::vector axesCorrel = {lambda1405MassAxis, ptAxis, deltaEtaAxis, deltaPhiAxis}; + // if (saveDEtaDPhi) { + // rLambda1405.add("hSparseL1405Correl", "THn for 2PC", HistType::kTHnSparseF, axesCorrel); + // } + + auto hSparseMass = rLambda1405.get(HIST("hSparseL1405")); + std::vector sparseMassEntry = {cand.massL1405, cand.pt(), cand.sigmaMinusMass, cand.dcaSigmaToPv, cand.kinkDcaDauToPv}; + if constexpr (IsMC) { + sparseMassEntry.push_back(cand.pvContrib); + } else { + sparseMassEntry.push_back(cand.centMult); + } + hSparseMass->Fill(sparseMassEntry.data()); + if constexpr (FillQVectors) { + std::vector sparseScalProdEntry = {cand.massL1405, cand.pt(), cand.sigmaMinusMass, cand.dcaSigmaToPv, cand.kinkDcaDauToPv}; + sparseScalProdEntry.push_back(cand.centMult); + sparseScalProdEntry.push_back(cand.scalarProd); + auto hSparseScalProd = rLambda1405.get(HIST("hSparseL1405ScalProd")); + hSparseScalProd->Fill(sparseScalProdEntry.data()); + } + if constexpr (FillCorrelations) { + std::vector sparseCorrelEntry = {cand.massL1405, cand.pt(), cand.sigmaMinusMass, cand.dcaSigmaToPv, cand.kinkDcaDauToPv}; + auto hSparseCorrel = rLambda1405.get(HIST("hSparseL1405Correl")); + sparseCorrelEntry.push_back(0.0); // Δη + sparseCorrelEntry.push_back(0.0); // Δφ + const auto deltaEtaIdx = sparseCorrelEntry.size() - 2; + const auto deltaPhiIdx = sparseCorrelEntry.size() - 1; + + for (const auto& trk : trks) { + if (trk.globalIndex() == cand.bachPiId || trk.globalIndex() == cand.kinkDauId) { + continue; // Skip the bachelor pi and kink daughter + } + if (trk.pt() < assTrkMinPt || trk.pt() > assTrkMaxPt) { + continue; // Skip tracks outside the pT range + } + double deltaPhi = RecoDecay::constrainAngle(trk.phi() - cand.phi, -o2::constants::math::PIHalf); + double deltaEta = trk.eta() - cand.eta; + if (std::abs(deltaEta) < minDEta) { + continue; + } + sparseCorrelEntry[deltaEtaIdx] = deltaEta; + sparseCorrelEntry[deltaPhiIdx] = deltaPhi; + rLambda1405.fill(HIST("hDeltaEta"), deltaEta); + rLambda1405.fill(HIST("hDeltaPhi"), deltaPhi); + hSparseCorrel->Fill(sparseCorrelEntry.data()); + } + } } - void constructCollCandidates(aod::KinkCands::iterator const& sigmaCand, TracksFull const& tracks, std::vector& selectedCandidates) + void initCCDB(aod::BCs::iterator const& bc) { - rSelections.fill(HIST("hSelectionsL1405"), 0); // All candidates - - if (sigmaCand.mothSign() < 0) { - rSelections.fill(HIST("hSelectionsSigmaMinus"), 0); // All Sigma- candidates - } else { - rSelections.fill(HIST("hSelectionsSigmaPlus"), 0); // All Sigma+ candidates + if (mRunNumber == bc.runNumber()) { + return; } + mRunNumber = bc.runNumber(); + LOG(info) << "Initializing CCDB for run " << mRunNumber; + o2::parameters::GRPMagField* grpmag = ccdb->getForRun(grpmagPath, mRunNumber); + o2::base::Propagator::initFieldFromGRP(grpmag); + mBz = grpmag->getNominalL3Field(); + + if (!lut) { + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(lutPath)); + } + o2::base::Propagator::Instance()->setMatLUT(lut); + LOG(info) << "Task initialized for run " << mRunNumber << " with magnetic field " << mBz << " kZG"; + } + + template + void constructCollCandidates(const TColl& collision, aod::KinkCands::iterator const& sigmaCand, TracksFull const& tracks, std::vector& selectedCandidates) + { + + // Retrieve primary vertex, once for all candidates in the collision + auto const& bc = collision.template bc_as(); + initCCDB(bc); + o2::dataformats::VertexBase primaryVertex; + primaryVertex.setPos({collision.posX(), collision.posY(), collision.posZ()}); + primaryVertex.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + + lambda1405candidate lambda1405Cand{}; - auto kinkDauTrack = sigmaCand.trackDaug_as(); + rSelections.fill(HIST("hSelectionsL1405"), 0); // All candidates + rSelections.fill(HIST("hSelectionsSigmaMinus"), 0); // All Sigma- candidates + rSelections.fill(HIST("hSelectionsSigmaPlus"), 0); // All Sigma+ candidates + + auto kinkDauTrack = sigmaCand.template trackDaug_as(); bool isPiKink = selectPiKink(kinkDauTrack); bool isPrKink = selectPrKink(kinkDauTrack); if (!isPiKink && !isPrKink) { return; } - lambda1405Cand.hasPiKink = isPiKink; - lambda1405Cand.hasPrKink = isPrKink; - if (sigmaCand.mothSign() < 0) { + if (isPiKink) { // Dominated by Sigma-, Sigma+ treated as contamination + lambda1405Cand.isSigmaMinus = true; + lambda1405Cand.isSigmaPlus = false; rSelections.fill(HIST("hSelectionsSigmaMinus"), 1); // Passed kink sel - } else { + } else { // Only Sigma+ can have a proton as kink daughter + lambda1405Cand.isSigmaMinus = false; + lambda1405Cand.isSigmaPlus = true; rSelections.fill(HIST("hSelectionsSigmaPlus"), 1); // Passed kink sel } - // Sigma- or AntiSigma+ candidates - if (isPiKink && sigmaCand.mothSign() < 0) { - rSigmaMinus.fill(HIST("h2PtMassSigmaMinusBeforeCuts"), sigmaCand.mothSign() * sigmaCand.ptMoth(), sigmaCand.mSigmaMinus()); - rSigmaMinus.fill(HIST("h2PtPiKinkNSigBeforeCutsSigmaMinus"), sigmaCand.mothSign() * kinkDauTrack.pt(), kinkDauTrack.tpcNSigmaPi()); + auto sigmaMom = std::array{sigmaCand.pxMoth(), sigmaCand.pyMoth(), sigmaCand.pzMoth()}; + auto sigmaPt = std::sqrt(sigmaMom[0] * sigmaMom[0] + sigmaMom[1] * sigmaMom[1]); + if (recomputeSigmaMom) { + bool success{false}; + float sigmaPRecalc = recalcSigmaMom(success, lambda1405Cand.isSigmaMinus, + sigmaCand.pxMoth(), sigmaCand.pyMoth(), sigmaCand.pzMoth(), + sigmaCand.pxDaug(), sigmaCand.pyDaug(), sigmaCand.pzDaug()); + if (!success && skipSigmasFailedRecompMom) { + return; + } + if (success) { + float sigmaPOriginal = std::sqrt(sigmaCand.pxMoth() * sigmaCand.pxMoth() + + sigmaCand.pyMoth() * sigmaCand.pyMoth() + + sigmaCand.pzMoth() * sigmaCand.pzMoth()); + if (sigmaPRecalc > 0.f && sigmaPOriginal > 0.f) { + float scale = sigmaPRecalc / sigmaPOriginal; + sigmaMom[0] *= scale; + sigmaMom[1] *= scale; + sigmaMom[2] *= scale; + + sigmaPt = std::sqrt(sigmaMom[0] * sigmaMom[0] + sigmaMom[1] * sigmaMom[1]); + if (lambda1405Cand.isSigmaMinus) { + rSigmaMinus.fill(HIST("hDeltaPxRecalcSigmaMinus"), sigmaMom[0] - sigmaCand.pxMoth(), sigmaCand.pxMoth()); + rSigmaMinus.fill(HIST("hDeltaPyRecalcSigmaMinus"), sigmaMom[1] - sigmaCand.pyMoth(), sigmaCand.pyMoth()); + rSigmaMinus.fill(HIST("hDeltaPzRecalcSigmaMinus"), sigmaMom[2] - sigmaCand.pzMoth(), sigmaCand.pzMoth()); + rSigmaMinus.fill(HIST("hRecalcPtFactorSigmaMinus"), scale, sigmaPOriginal); + } else { + rSigmaPlus.fill(HIST("hDeltaPxRecalcSigmaPlus"), sigmaMom[0] - sigmaCand.pxMoth(), sigmaCand.pxMoth()); + rSigmaPlus.fill(HIST("hDeltaPyRecalcSigmaPlus"), sigmaMom[1] - sigmaCand.pyMoth(), sigmaCand.pyMoth()); + rSigmaPlus.fill(HIST("hDeltaPzRecalcSigmaPlus"), sigmaMom[2] - sigmaCand.pzMoth(), sigmaCand.pzMoth()); + rSigmaPlus.fill(HIST("hRecalcPtFactorSigmaPlus"), scale, sigmaPOriginal); + } + } + } + } + if (lambda1405Cand.isSigmaMinus) { + rSelections.fill(HIST("hSelectionsSigmaMinus"), 2); // Passed mass sel + } else { + rSelections.fill(HIST("hSelectionsSigmaPlus"), 2); // Passed mass sel } - if (isPiKink && sigmaCand.mothSign() > 0) { - rSigmaPlus.fill(HIST("h2PtMassSigmaPlusBeforeCuts"), sigmaCand.mothSign() * sigmaCand.ptMoth(), sigmaCand.mSigmaPlus()); - rSigmaPlus.fill(HIST("h2PtPiKinkNSigBeforeCutsSigmaPlus"), sigmaCand.mothSign() * kinkDauTrack.pt(), kinkDauTrack.tpcNSigmaPi()); + + // Sigma- or AntiSigma+ candidates + if (lambda1405Cand.isSigmaMinus) { + rSigmaMinus.fill(HIST("h2PtMassSigmaMinusBeforeCuts"), sigmaPt, sigmaCand.mSigmaMinus()); + rSigmaMinus.fill(HIST("h2PtPiKinkNSigBeforeCutsSigmaMinus"), kinkDauTrack.pt(), kinkDauTrack.tpcNSigmaPi()); } - // Only Sigma+ can have a proton as kink daughter - if (isPrKink) { - rSigmaPlus.fill(HIST("h2PtMassSigmaPlusBeforeCuts"), sigmaCand.mothSign() * sigmaCand.ptMoth(), sigmaCand.mSigmaPlus()); - rSigmaPlus.fill(HIST("h2PtPrKinkNSigBeforeCutsSigmaPlus"), sigmaCand.mothSign() * kinkDauTrack.pt(), kinkDauTrack.tpcNSigmaPr()); + if (lambda1405Cand.isSigmaPlus) { + rSigmaPlus.fill(HIST("h2PtMassSigmaPlusBeforeCuts"), sigmaPt, sigmaCand.mSigmaPlus()); + rSigmaPlus.fill(HIST("h2PtPrKinkNSigBeforeCuts"), kinkDauTrack.pt(), kinkDauTrack.tpcNSigmaPr()); } - lambda1405Cand.isSigmaPlus = isPrKink && (sigmaCand.mSigmaPlus() > o2::constants::physics::MassSigmaPlus - cutSigmaMass && sigmaCand.mSigmaPlus() < o2::constants::physics::MassSigmaPlus + cutSigmaMass); - lambda1405Cand.isSigmaMinus = isPiKink && (sigmaCand.mSigmaMinus() > o2::constants::physics::MassSigmaMinus - cutSigmaMass && sigmaCand.mSigmaMinus() < o2::constants::physics::MassSigmaMinus + cutSigmaMass); - if (!lambda1405Cand.isSigmaPlus && !lambda1405Cand.isSigmaMinus) { + if (lambda1405Cand.isSigmaMinus && (sigmaCand.mSigmaMinus() < o2::constants::physics::MassSigmaMinus - cutSigmaMass || + sigmaCand.mSigmaMinus() > o2::constants::physics::MassSigmaMinus + cutSigmaMass)) { return; } - if (sigmaCand.mothSign() < 0) { - rSelections.fill(HIST("hSelectionsSigmaMinus"), 2); // Passed mass sel + if (lambda1405Cand.isSigmaPlus && (sigmaCand.mSigmaPlus() < o2::constants::physics::MassSigmaPlus - cutSigmaMass || + sigmaCand.mSigmaPlus() > o2::constants::physics::MassSigmaPlus + cutSigmaMass)) { + return; + } + if (lambda1405Cand.isSigmaMinus) { + rSelections.fill(HIST("hSelectionsSigmaMinus"), 3); // Passed mass sel } else { - rSelections.fill(HIST("hSelectionsSigmaPlus"), 2); // Passed mass sel + rSelections.fill(HIST("hSelectionsSigmaPlus"), 3); // Passed mass sel } - float sigmaRad = std::hypot(sigmaCand.xDecVtx(), sigmaCand.yDecVtx()); - if (std::abs(sigmaCand.dcaMothPv()) > cutDCAtoPvSigma) { + if (std::abs(sigmaCand.dcaMothPv()) > cutDcaToPvSigma) { return; } - if (sigmaCand.mothSign() < 0) { - rSelections.fill(HIST("hSelectionsSigmaMinus"), 3); // Passed cutDCAtoPvSigma + if (lambda1405Cand.isSigmaMinus) { + rSelections.fill(HIST("hSelectionsSigmaMinus"), 4); // Passed cutDcaToPvSigma } else { - rSelections.fill(HIST("hSelectionsSigmaPlus"), 3); // Passed cutDCAtoPvSigma + rSelections.fill(HIST("hSelectionsSigmaPlus"), 4); // Passed cutDcaToPvSigma } - if (std::abs(sigmaCand.dcaDaugPv()) < cutDCAtoPvPiFromSigma) { + if (std::abs(sigmaCand.dcaDaugPv()) < cutDcaToPvPiFromSigma) { return; } - if (sigmaCand.mothSign() < 0) { - rSelections.fill(HIST("hSelectionsSigmaMinus"), 4); // cutDCAtoPvPiFromSigma + if (lambda1405Cand.isSigmaMinus) { + rSelections.fill(HIST("hSelectionsSigmaMinus"), 5); // cutDcaToPvPiFromSigma } else { - rSelections.fill(HIST("hSelectionsSigmaPlus"), 4); // cutDCAtoPvPiFromSigma + rSelections.fill(HIST("hSelectionsSigmaPlus"), 5); // cutDcaToPvPiFromSigma } + float sigmaRad = std::hypot(sigmaCand.xDecVtx(), sigmaCand.yDecVtx()); if (sigmaRad < cutSigmaRadius) { return; } - if (sigmaCand.mothSign() < 0) { - rSelections.fill(HIST("hSelectionsSigmaMinus"), 5); // Passed mass sel + if (lambda1405Cand.isSigmaMinus) { + rSelections.fill(HIST("hSelectionsSigmaMinus"), 6); // Passed radius sel } else { - rSelections.fill(HIST("hSelectionsSigmaPlus"), 5); // Passed mass sel + rSelections.fill(HIST("hSelectionsSigmaPlus"), 6); // Passed radius sel } auto kinkDauMom = std::array{sigmaCand.pxDaug(), sigmaCand.pyDaug(), sigmaCand.pzDaug()}; - auto sigmaMom = std::array{sigmaCand.pxMoth(), sigmaCand.pyMoth(), sigmaCand.pzMoth()}; // Sigma properties lambda1405Cand.sigmaId = sigmaCand.globalIndex(); lambda1405Cand.sigmaMinusMass = sigmaCand.mSigmaMinus(); @@ -613,18 +958,18 @@ struct lambda1405analysis { lambda1405Cand.sigmaSign = sigmaCand.mothSign(); lambda1405Cand.sigmaAlphaAP = alphaAP(sigmaMom, kinkDauMom); lambda1405Cand.sigmaQtAP = qtAP(sigmaMom, kinkDauMom); - lambda1405Cand.sigmaPt = sigmaCand.ptMoth(); + lambda1405Cand.sigmaPt = sigmaPt; lambda1405Cand.sigmaRadius = sigmaRad; - lambda1405Cand.kinkDcaDauToPv = sigmaCand.dcaDaugPv(); + lambda1405Cand.dcaSigmaToPv = sigmaCand.dcaMothPv(); if (lambda1405Cand.sigmaQtAP < funcMinQtAlphaAP.Eval(lambda1405Cand.sigmaAlphaAP) || lambda1405Cand.sigmaQtAP > funcMaxQtAlphaAP.Eval(lambda1405Cand.sigmaAlphaAP)) { return; } - if (sigmaCand.mothSign() < 0) { - rSelections.fill(HIST("hSelectionsSigmaMinus"), 6); // Passed mass sel + if (lambda1405Cand.isSigmaMinus) { + rSelections.fill(HIST("hSelectionsSigmaMinus"), 7); // Passed AP sel } else { - rSelections.fill(HIST("hSelectionsSigmaPlus"), 6); // Passed mass sel + rSelections.fill(HIST("hSelectionsSigmaPlus"), 7); // Passed AP sel } // Kink daughter properties @@ -634,25 +979,41 @@ struct lambda1405analysis { lambda1405Cand.kinkPiNSigTof = kinkDauTrack.tofNSigmaPi(); lambda1405Cand.kinkPrNSigTpc = kinkDauTrack.tpcNSigmaPr(); lambda1405Cand.kinkPrNSigTof = kinkDauTrack.tofNSigmaPr(); + lambda1405Cand.kinkDcaDauToPv = sigmaCand.dcaDaugPv(); - fillHistosSigma(lambda1405Cand, sigmaCand, kinkDauTrack); rSelections.fill(HIST("hSelectionsL1405"), 1); // Passed Sigma sel + // Collision properties + lambda1405Cand.pvContrib = collision.numContrib(); + lambda1405Cand.centMult = getCentMult(collision); + lambda1405Cand.occupancy = collision.ft0cOccupancyInTimeRange(); + + fillHistosSigma(lambda1405Cand, sigmaCand, kinkDauTrack); + + int countPairedBachPi{0}; for (const auto& piTrack : tracks) { rSelections.fill(HIST("hSelectionsBachPi"), 0); // All bachelors - bool isUnlikeSign = (piTrack.sign() != sigmaCand.mothSign()); - bool acceptPair = doLikeSignBkg ? !isUnlikeSign : isUnlikeSign; + // Needed to avoid spurious correlations in the Like-Sign case + if (piTrack.globalIndex() == kinkDauTrack.globalIndex()) { + continue; // Skip the kink daughter track + } + + bool acceptPair{false}; + if (doLikeSignBkg) { + acceptPair = (piTrack.sign() == sigmaCand.mothSign()); + } else { + acceptPair = (piTrack.sign() != sigmaCand.mothSign()); + } if (!acceptPair) { continue; } rSelections.fill(HIST("hSelectionsBachPi"), 1); - if (!selectPiBach(piTrack)) { + if (!selectPiBach(piTrack, primaryVertex, lambda1405Cand.centMult)) { continue; } - rSelections.fill(HIST("hSelectionsBachPi"), 5); // PID sel - rSelections.fill(HIST("hSelectionsL1405"), 2); // Bach Pi selection + rSelections.fill(HIST("hSelectionsL1405"), 2); // Bach Pi selection auto piMom = std::array{piTrack.px(), piTrack.py(), piTrack.pz()}; float invMass{-1.f}; @@ -667,8 +1028,8 @@ struct lambda1405analysis { rSelections.fill(HIST("hSelectionsL1405"), 3); // Upper mass selection // Daughter Pi properties - lambda1405Cand.piId = piTrack.globalIndex(); - lambda1405Cand.piPt = piTrack.pt(); + lambda1405Cand.bachPiId = piTrack.globalIndex(); + lambda1405Cand.bachPiPt = piTrack.pt(); lambda1405Cand.bachPiNSigTpc = piTrack.tpcNSigmaPi(); if (useTof) { lambda1405Cand.bachPiNSigTof = piTrack.tofNSigmaPi(); @@ -683,40 +1044,55 @@ struct lambda1405analysis { lambda1405Cand.py = sigmaMom[1] + piMom[1]; lambda1405Cand.pz = sigmaMom[2] + piMom[2]; lambda1405Cand.phi = std::atan2(lambda1405Cand.py, lambda1405Cand.px); + lambda1405Cand.eta = -std::log(std::tan(0.5 * std::atan2(std::hypot(lambda1405Cand.px, lambda1405Cand.py), lambda1405Cand.pz))); lambda1405Cand.scalarProd = -1; + if constexpr (requires { collision.qvecFT0CRe(); }) { + float const xQVec = collision.qvecFT0CRe(); + float const yQVec = collision.qvecFT0CIm(); + float const cos2Phi = std::cos(2 * lambda1405Cand.phi); + float const sin2Phi = std::sin(2 * lambda1405Cand.phi); + lambda1405Cand.scalarProd = cos2Phi * xQVec + sin2Phi * yQVec; + } // Check correlations between transverse momenta of L1405, sigma and bachelor pi if (std::hypot(sigmaCand.pxMoth(), sigmaCand.pyMoth()) < funcMinSigmaPtVsL1405Pt.Eval(lambda1405Cand.pt()) || std::hypot(sigmaCand.pxMoth(), sigmaCand.pyMoth()) > funcMaxSigmaPtVsL1405Pt.Eval(lambda1405Cand.pt())) { continue; } - rSelections.fill(HIST("hSelectionsL1405"), 4); // Accepted - if (piTrack.pt() < funcMinBachPiPtVsL1405Pt.Eval(lambda1405Cand.pt()) || piTrack.pt() > funcMaxBachPiPtVsL1405Pt.Eval(lambda1405Cand.pt())) { continue; } + rSelections.fill(HIST("hSelectionsL1405"), 4); // Pt correlations + + if (lambda1405Cand.pt() < cutMinPtL1405) { + continue; + } rSelections.fill(HIST("hSelectionsL1405"), 5); // Accepted - fillHistosLambda1405(lambda1405Cand, piTrack); - rSelections.fill(HIST("hSelectionsL1405"), 6); // Accepted selectedCandidates.push_back(lambda1405Cand); + countPairedBachPi++; } + rLambda1405.fill(HIST("hPairedBachPiVsCent"), lambda1405Cand.centMult, countPairedBachPi); } template bool checkSigmaKinkMC(const mcTrack& mcTrackSigma, const mcTrack& mcTrackKinkDau, float sigmaAbsPDG, float kinkAbsPDG, aod::McParticles const&) { + LOG(info) << "Checking Sigma kink decay for MC tracks: Sigma PDG = " << mcTrackSigma.pdgCode() << ", Kink daughter PDG = " << mcTrackKinkDau.pdgCode(); if (std::abs(mcTrackSigma.pdgCode()) != sigmaAbsPDG || std::abs(mcTrackKinkDau.pdgCode()) != kinkAbsPDG) { + LOG(info) << "PDG codes do not match expected values: Sigma PDG = " << sigmaAbsPDG << ", Kink daughter PDG = " << kinkAbsPDG; return false; // Not a valid Sigma kink decay } if (!mcTrackKinkDau.has_mothers()) { + LOG(info) << "Kink daughter has no mothers"; return false; // No mothers found } // Check if the kink comes from the Sigma bool isKinkFromSigma = false; for (const auto& mcMother : mcTrackKinkDau.template mothers_as()) { if (mcMother.globalIndex() == mcTrackSigma.globalIndex()) { + LOG(info) << "Kink daughter comes from the Sigma"; isKinkFromSigma = true; break; } @@ -725,35 +1101,30 @@ struct lambda1405analysis { } template - void fillOutputData(const TCollision& collision, const TCand& sigmaCands, const TTrack& kinkDauTrack) + void fillOutputData(const TCollision& collision, const TCand& sigmaCands, const TTrack& tracks) { - if constexpr (requires { collision.centFT0C(); }) { - if (collision.centFT0C() < centralityMin || collision.centFT0C() > centralityMax) { - return; - } - } if (std::abs(collision.posZ()) > cutZVertex || !collision.sel8()) { return; } rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + float centMult = getCentMult(collision); + if (centMult < centMultMin || centMult > centMultMax) { + return; + } + rEventSelection.fill(HIST("hCentMultVsPvContrib"), centMult, collision.numContrib()); + rEventSelection.fill(HIST("hOccVsPvContrib"), collision.ft0cOccupancyInTimeRange(), collision.numContrib()); + rEventSelection.fill(HIST("hCentVsOcc"), centMult, collision.ft0cOccupancyInTimeRange()); + for (const auto& sigmaCand : sigmaCands) { std::vector selectedCandidates; - constructCollCandidates(sigmaCand, kinkDauTrack, selectedCandidates); - for (auto& lambda1405Cand : selectedCandidates) { + constructCollCandidates(collision, sigmaCand, tracks, selectedCandidates); + for (const auto& lambda1405Cand : selectedCandidates) { if (lambda1405Cand.isSigmaMinus) { - rSigmaMinus.fill(HIST("h2SigmaMinusMassVsLambdaMass"), lambda1405Cand.sigmaSign * lambda1405Cand.sigmaPt, lambda1405Cand.sigmaMinusMass); - if (lambda1405Cand.hasPiKink) { - rSigmaMinus.fill(HIST("h2KinkPiPtNSigTofSigmaMinus"), lambda1405Cand.sigmaSign * lambda1405Cand.piPt, lambda1405Cand.bachPiNSigTof); - } - if (lambda1405Cand.hasPrKink) { - rSigmaMinus.fill(HIST("h2KinkPrPtNSigTofSigmaMinus"), lambda1405Cand.sigmaSign * lambda1405Cand.piPt, lambda1405Cand.bachPiNSigTof); - } - } - if (lambda1405Cand.isSigmaPlus) { - rSigmaPlus.fill(HIST("h2SigmaPlusMassVsLambdaMass"), lambda1405Cand.sigmaSign * lambda1405Cand.sigmaPt, lambda1405Cand.sigmaPlusMass); - rSigmaPlus.fill(HIST("h2KinkPrPtNSigTofSigmaPlus"), lambda1405Cand.sigmaSign * lambda1405Cand.piPt, lambda1405Cand.bachPiNSigTof); + rLambda1405.fill(HIST("h2SigmaMinusMassVsLambdaMass"), lambda1405Cand.massL1405, lambda1405Cand.sigmaMinusMass); + } else { + rLambda1405.fill(HIST("h2SigmaPlusMassVsLambdaMass"), lambda1405Cand.massL1405, lambda1405Cand.sigmaPlusMass); } - if (fillOutputTree) { + if (fillOutputTree || fillFlowTree) { float const ptCand = lambda1405Cand.pt(); if (downSampleFactor < 1.) { float const pseudoRndm = ptCand * 1000. - static_cast(ptCand * 1000); @@ -761,52 +1132,61 @@ struct lambda1405analysis { continue; } } - outputDataTable(lambda1405Cand.px, lambda1405Cand.py, lambda1405Cand.pz, - lambda1405Cand.massL1405, lambda1405Cand.massXi1530, - lambda1405Cand.sigmaMinusMass, lambda1405Cand.sigmaPlusMass, lambda1405Cand.xiMinusMass, - lambda1405Cand.sigmaPt, lambda1405Cand.sigmaAlphaAP, lambda1405Cand.sigmaQtAP, lambda1405Cand.sigmaRadius, - lambda1405Cand.kinkPt, - lambda1405Cand.kinkPiNSigTpc, lambda1405Cand.kinkPiNSigTof, - lambda1405Cand.kinkPrNSigTpc, lambda1405Cand.kinkPrNSigTof, - lambda1405Cand.kinkDcaDauToPv, - lambda1405Cand.bachPiNSigTpc, lambda1405Cand.bachPiNSigTof); - } - if constexpr (requires { collision.qvecFT0CRe(); }) { - float const xQVec = collision.qvecFT0CRe(); - float const yQVec = collision.qvecFT0CIm(); - float const cos2Phi = std::cos(2 * lambda1405Cand.phi); - float const sin2Phi = std::sin(2 * lambda1405Cand.phi); - lambda1405Cand.scalarProd = cos2Phi * xQVec + sin2Phi * yQVec; - float const ptCand = lambda1405Cand.pt(); - rLambda1405.fill(HIST("hSparseFlowL1405"), ptCand, lambda1405Cand.massL1405, collision.centFT0C(), lambda1405Cand.scalarProd); - if (fillFlowTree) { - if (downSampleFactor < 1.) { - float const pseudoRndm = ptCand * 1000. - static_cast(ptCand * 1000); - if (ptCand < ptDownSampleMax && pseudoRndm >= downSampleFactor) { - continue; - } - } + if (fillOutputTree) { + outputDataTable(lambda1405Cand.px, lambda1405Cand.py, lambda1405Cand.pz, + lambda1405Cand.massL1405, lambda1405Cand.massXi1530, + lambda1405Cand.sigmaMinusMass, lambda1405Cand.sigmaPlusMass, lambda1405Cand.xiMinusMass, + lambda1405Cand.sigmaPt, lambda1405Cand.sigmaAlphaAP, lambda1405Cand.sigmaQtAP, lambda1405Cand.sigmaRadius, + lambda1405Cand.kinkPt, + lambda1405Cand.kinkPiNSigTpc, lambda1405Cand.kinkPiNSigTof, + lambda1405Cand.kinkPrNSigTpc, lambda1405Cand.kinkPrNSigTof, + lambda1405Cand.kinkDcaDauToPv, + lambda1405Cand.bachPiNSigTpc, lambda1405Cand.bachPiNSigTof, + lambda1405Cand.centMult, lambda1405Cand.occupancy); + } else { outputDataFlowTable(ptCand, lambda1405Cand.massL1405, + lambda1405Cand.sigmaPt, lambda1405Cand.sigmaMinusMass, lambda1405Cand.sigmaPlusMass, lambda1405Cand.sigmaAlphaAP, lambda1405Cand.sigmaQtAP, lambda1405Cand.kinkPiNSigTpc, lambda1405Cand.kinkPiNSigTof, lambda1405Cand.kinkPrNSigTpc, lambda1405Cand.kinkPrNSigTof, lambda1405Cand.kinkDcaDauToPv, lambda1405Cand.bachPiNSigTpc, lambda1405Cand.bachPiNSigTof, - lambda1405Cand.scalarProd, collision.centFT0C()); + lambda1405Cand.scalarProd, lambda1405Cand.centMult); + } + } + + // Fill histograms + if constexpr (requires { collision.qvecFT0CRe(); }) { + if (saveDEtaDPhi) { + fillHistosLambda1405(lambda1405Cand, tracks); + } else { + fillHistosLambda1405(lambda1405Cand, tracks); + } + } else { + if (saveDEtaDPhi) { + fillHistosLambda1405(lambda1405Cand, tracks); + } else { + fillHistosLambda1405(lambda1405Cand, tracks); } } } } } - void processData(CollisionsFull::iterator const& collision, aod::KinkCands const& kinkCands, TracksFull const& tracks) + void processData(CollisionsFull::iterator const& collision, + aod::KinkCands const& kinkCands, + TracksFull const& tracks, + const aod::BCs&) { fillOutputData(collision, kinkCands, tracks); } PROCESS_SWITCH(lambda1405analysis, processData, "Data processing", true); - void processDataWCentQVecs(CollisionsCentSel::iterator const& collision, aod::KinkCands const& kinkCands, TracksFull const& tracks) + void processDataWCentQVecs(CollisionsCentSel::iterator const& collision, + aod::KinkCands const& kinkCands, + TracksFull const& tracks, + const aod::BCs&) { fillOutputData(collision, kinkCands, tracks); } @@ -885,62 +1265,98 @@ struct lambda1405analysis { } template - void fillOutputMc(const TCollision& collisions, const aod::KinkCands& sigmaCands, const aod::McTrackLabels& trackLabelsMC, const TTrack& tracks, const aod::McParticles& particlesMC) + void fillOutputMc(const TCollision& recoCollisions, + const aod::KinkCands& sigmaCands, + const aod::McTrackLabels& trackLabelsMC, + const TTrack& tracks, + const aod::McParticles& particlesMC) { - for (const auto& collision : collisions) { - if constexpr (requires { collision.centFT0C(); }) { - if (collision.centFT0C() < centralityMin || collision.centFT0C() > centralityMax) { - return; - } - } + LOG(info) << "Filling output MC for " << recoCollisions.size() << " collisions, " << sigmaCands.size() << " Sigma candidates, and " << tracks.size() << " tracks"; + for (const auto& collision : recoCollisions) { + LOG(info) << "\n\nProcessing collision with global index: " << collision.globalIndex() << " and " << sigmaCands.size() << " Sigma candidates, and " << tracks.size() << " tracks"; if (std::abs(collision.posZ()) > cutZVertex) { // || !collision.sel8()) { + LOG(info) << "Collision failed Z vertex cut: " << collision.posZ(); continue; } + LOG(info) << "Collision passed Z vertex cut: " << collision.posZ(); rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + float centMult = getCentMult(collision); + LOG(info) << "Collision centrality: " << centMult; + if (centMult < centMultMin || centMult > centMultMax) { + LOG(info) << "Collision failed centrality cut: " << centMult; + continue; + } + LOG(info) << "Collision passed centrality cut: " << centMult; + rEventSelection.fill(HIST("hCentMultVsPvContrib"), centMult, collision.numContrib()); + rEventSelection.fill(HIST("hOccVsPvContrib"), collision.ft0cOccupancyInTimeRange(), collision.numContrib()); + rEventSelection.fill(HIST("hCentVsOcc"), centMult, collision.ft0cOccupancyInTimeRange()); + auto sigmaCandsPerCol = sigmaCands.sliceBy(mKinkPerCol, collision.globalIndex()); auto tracksPerCol = tracks.sliceBy(mPerColTracks, collision.globalIndex()); + LOG(info) << "Start loop on " << sigmaCandsPerCol.size() << " Sigma candidates ... "; for (const auto& sigmaCand : sigmaCandsPerCol) { + LOG(info) << "Processing Sigma candidate with global index: " << sigmaCand.globalIndex(); + + // Perform the sigma matching here, so sigma histograms + // can be used for efficiency studies on the sigma + auto labelSigma = trackLabelsMC.rawIteratorAt(sigmaCand.trackMothId()); + auto labelKinkDaug = trackLabelsMC.rawIteratorAt(sigmaCand.trackDaugId()); + if (!labelSigma.has_mcParticle()) { + LOG(info) << "Sigma candidate with global index: " << sigmaCand.globalIndex() << " is not matched to MC particle"; + rSelections.fill(HIST("hRecoNotMatchedCounter"), 1); // Sigma not matched + } + if (!labelKinkDaug.has_mcParticle()) { + LOG(info) << "Kink daughter candidate with global index: " << sigmaCand.globalIndex() << " is not matched to MC particle"; + rSelections.fill(HIST("hRecoNotMatchedCounter"), 2); // Kink daughter not matched + } + auto genSigma = labelSigma.template mcParticle_as(); + auto genKinkDaug = labelKinkDaug.template mcParticle_as(); + + bool isSigmaMinusKink = checkSigmaKinkMC(genSigma, genKinkDaug, PDG_t::kSigmaMinus, PDG_t::kPiPlus, particlesMC); + bool isSigmaPlusToPiKink = checkSigmaKinkMC(genSigma, genKinkDaug, PDG_t::kSigmaPlus, PDG_t::kPiPlus, particlesMC); + bool isSigmaPlusToPrKink = checkSigmaKinkMC(genSigma, genKinkDaug, PDG_t::kSigmaPlus, PDG_t::kProton, particlesMC); + + if (!isSigmaMinusKink && !isSigmaPlusToPiKink && !isSigmaPlusToPrKink) { + LOG(info) << "Candidate is not a valid Sigma kink decay, skipping ..."; + continue; // Skip if not a valid Sigma kink decay + } + if (isSigmaMinusKink) { + LOG(info) << "Filling h2DeltaGenRecoPtSigmaMinus with: " << sigmaCand.ptMoth() - genSigma.pt() << ", " << sigmaCand.ptMoth(); + rSigmaMinus.fill(HIST("h2DeltaGenRecoPtSigmaMinus"), sigmaCand.ptMoth() - genSigma.pt(), sigmaCand.ptMoth()); + } + if (isSigmaPlusToPiKink || isSigmaPlusToPrKink) { + LOG(info) << "Filling h2DeltaGenRecoPtSigmaPlus with: " << sigmaCand.ptMoth() - genSigma.pt() << ", " << sigmaCand.ptMoth(); + rSigmaPlus.fill(HIST("h2DeltaGenRecoPtSigmaPlus"), sigmaCand.ptMoth() - genSigma.pt(), sigmaCand.ptMoth()); + } + std::vector selectedCandidates; - constructCollCandidates(sigmaCand, tracksPerCol, selectedCandidates); + LOG(info) << "Constructing Lambda(1405) candidates from Sigma candidate with global index: " << sigmaCand.globalIndex(); + constructCollCandidates(collision, sigmaCand, tracksPerCol, selectedCandidates); for (const auto& lambda1405Cand : selectedCandidates) { rLambda1405.fill(HIST("hRecoL1405"), 0., lambda1405Cand.pt()); // All reconstructed // Do MC association - auto mcLabPiKink = trackLabelsMC.rawIteratorAt(lambda1405Cand.kinkDauId); - auto mcLabSigma = trackLabelsMC.rawIteratorAt(lambda1405Cand.sigmaId); - auto mcLabPi = trackLabelsMC.rawIteratorAt(lambda1405Cand.piId); - if (!mcLabSigma.has_mcParticle() || !mcLabPiKink.has_mcParticle() || !mcLabPi.has_mcParticle()) { - continue; // Skip if no valid MC association - } - rLambda1405.fill(HIST("hRecoL1405"), 1., lambda1405Cand.pt()); // All with associated MC particle - - auto mcTrackKink = mcLabPiKink.mcParticle_as(); - auto mcTrackSigma = mcLabSigma.mcParticle_as(); - auto mcTrackPi = mcLabPi.mcParticle_as(); - - bool isSigmaMinusKink = checkSigmaKinkMC(mcTrackSigma, mcTrackKink, 3122, 211, particlesMC); - bool isSigmaPlusToPiKink = checkSigmaKinkMC(mcTrackSigma, mcTrackKink, 3222, 211, particlesMC); - bool isSigmaPlusToPrKink = checkSigmaKinkMC(mcTrackSigma, mcTrackKink, 3222, 2212, particlesMC); - - if (!isSigmaMinusKink && !isSigmaPlusToPiKink && !isSigmaPlusToPrKink) { - continue; // Skip if not a valid Sigma kink decay + auto labelBachPi = trackLabelsMC.rawIteratorAt(lambda1405Cand.bachPiId); + if (!labelBachPi.has_mcParticle()) { + rSelections.fill(HIST("hRecoNotMatchedCounter"), 3); // Bach pion not matched + continue; // Skip if no valid MC association } - rLambda1405.fill(HIST("hRecoL1405"), 2., lambda1405Cand.pt()); // Has kink decay in MC - if (std::abs(mcTrackPi.pdgCode()) != PDG_t::kPiPlus) { + auto genBachPi = labelBachPi.template mcParticle_as(); + if (std::abs(genBachPi.pdgCode()) != PDG_t::kPiPlus) { continue; // Skip if not a valid pion candidate } - rLambda1405.fill(HIST("hRecoL1405"), 3., lambda1405Cand.pt()); // Has bach pi + rLambda1405.fill(HIST("hRecoL1405"), 1., lambda1405Cand.pt()); // Has bach pi - if (!mcTrackSigma.has_mothers() || !mcTrackPi.has_mothers()) { + if (!genSigma.has_mothers() || !genBachPi.has_mothers()) { continue; // Skip if no mothers found } - rLambda1405.fill(HIST("hRecoL1405"), 4., lambda1405Cand.pt()); // Has mothers for Sigma and Pi + rLambda1405.fill(HIST("hRecoL1405"), 2., lambda1405Cand.pt()); // Has mothers for Sigma and Pi // check that labpi and labsigma have the same mother (a lambda1405 candidate) int lambda1405Id = -1; - for (const auto& piMother : mcTrackPi.mothers_as()) { - for (const auto& sigmaMother : mcTrackSigma.mothers_as()) { + for (const auto& piMother : genBachPi.template mothers_as()) { + for (const auto& sigmaMother : genSigma.template mothers_as()) { if (piMother.globalIndex() == sigmaMother.globalIndex() && std::abs(piMother.pdgCode()) == lambda1405PdgCode) { lambda1405Id = piMother.globalIndex(); break; // Found the mother, exit loop @@ -950,17 +1366,17 @@ struct lambda1405analysis { if (lambda1405Id == -1) { continue; // Skip if the Sigma and pion do not share the same lambda1405 candidate } - rLambda1405.fill(HIST("hRecoL1405"), 4., lambda1405Cand.pt()); // Has same mother + rLambda1405.fill(HIST("hRecoL1405"), 3., lambda1405Cand.pt()); // Has same mother auto lambda1405Mother = particlesMC.rawIteratorAt(lambda1405Id); float lambda1405Mass = std::sqrt(lambda1405Mother.e() * lambda1405Mother.e() - lambda1405Mother.p() * lambda1405Mother.p()); if (lambda1405Cand.isSigmaMinus) { - rSigmaMinus.fill(HIST("h2SigmaMinusMassVsLambdaMass"), lambda1405Cand.massL1405, lambda1405Cand.sigmaMinusMass); + rLambda1405.fill(HIST("h2SigmaMinusMassVsLambdaMass"), lambda1405Cand.massL1405, lambda1405Cand.sigmaMinusMass); rLambda1405.fill(HIST("h2MassResolutionFromSigmaMinus"), lambda1405Mass, lambda1405Mass - lambda1405Cand.massL1405); rLambda1405.fill(HIST("h2PtResolutionFromSigmaMinus"), lambda1405Cand.pt(), lambda1405Cand.pt() - lambda1405Mother.pt()); } if (lambda1405Cand.isSigmaPlus) { - rSigmaPlus.fill(HIST("h2SigmaPlusMassVsLambdaMass"), lambda1405Cand.massL1405, lambda1405Cand.sigmaPlusMass); + rLambda1405.fill(HIST("h2SigmaPlusMassVsLambdaMass"), lambda1405Cand.massL1405, lambda1405Cand.sigmaPlusMass); rLambda1405.fill(HIST("h2MassResolutionFromSigmaPlus"), lambda1405Mass, lambda1405Mass - lambda1405Cand.massL1405); rLambda1405.fill(HIST("h2PtResolutionFromSigmaPlus"), lambda1405Cand.pt(), lambda1405Cand.pt() - lambda1405Mother.pt()); } @@ -975,14 +1391,39 @@ struct lambda1405analysis { lambda1405Cand.kinkPrNSigTpc, lambda1405Cand.kinkPrNSigTof, lambda1405Cand.kinkDcaDauToPv, lambda1405Cand.bachPiNSigTpc, lambda1405Cand.bachPiNSigTof, - lambda1405Mother.pt(), lambda1405Mass, mcTrackSigma.pdgCode(), mcTrackKink.pdgCode()); + lambda1405Mother.pt(), lambda1405Mass, genSigma.pdgCode(), genBachPi.pdgCode(), + lambda1405Cand.centMult, lambda1405Cand.occupancy); } + fillHistosLambda1405(lambda1405Cand, tracksPerCol); } } } // Loop over generated particles to fill MC histograms for (const auto& mcPart : particlesMC) { + if (std::abs(mcPart.pdgCode()) != lambda1405PdgCode && + std::abs(mcPart.pdgCode()) != PDG_t::kSigmaMinus && + std::abs(mcPart.pdgCode()) != PDG_t::kSigmaPlus) { + continue; // Only consider Lambda(1405) and Sigma candidates + } + + // Compute generated PV contributors + const auto& recoCollsPerMcColl = recoCollisions.sliceBy(colPerMcCollision, mcPart.mcCollision().globalIndex()); + if (recoCollsPerMcColl.size() == 0) { + continue; // Skip if no reconstructed collisions associated with this MC collision + } + unsigned maxNumContrib = 0; + for (const auto& recCol : recoCollsPerMcColl) { + maxNumContrib = recCol.numContrib() > maxNumContrib ? recCol.numContrib() : maxNumContrib; + } + + // Needed for Sigma efficiency vs PV contributors + if (std::abs(mcPart.pdgCode()) == PDG_t::kSigmaMinus) { + rSigmaMinus.fill(HIST("h2GenSigmaMinusPvContribPt"), maxNumContrib, mcPart.pt()); + } + if (std::abs(mcPart.pdgCode()) == PDG_t::kSigmaPlus) { + rSigmaPlus.fill(HIST("h2GenSigmaPlusPvContribPt"), maxNumContrib, mcPart.pt()); + } if (std::abs(mcPart.pdgCode()) != lambda1405PdgCode) { continue; // Only consider Lambda(1405) candidates } @@ -999,36 +1440,50 @@ struct lambda1405analysis { // Generated Armenteros-Podolanski variables float genSigmaAlphaAP = alphaAP({sigmaDaug.px(), sigmaDaug.py(), sigmaDaug.pz()}, {sigmaKinkDaug.px(), sigmaKinkDaug.py(), sigmaKinkDaug.pz()}); float genSigmaQtAP = qtAP({sigmaDaug.px(), sigmaDaug.py(), sigmaDaug.pz()}, {sigmaKinkDaug.px(), sigmaKinkDaug.py(), sigmaKinkDaug.pz()}); + float mcMass = std::sqrt(mcPart.e() * mcPart.e() - mcPart.p() * mcPart.p()); + rLambda1405.fill(HIST("h2PtMassMC"), mcPart.pt(), mcMass); + rLambda1405.fill(HIST("h2GenL1405PvContribPt"), maxNumContrib, mcPart.pt()); if (decayChannel == kSigmaMinusPiToPiPiNeutron) { rLambda1405.fill(HIST("h2GenSigmaMinusArmPod"), genSigmaAlphaAP, genSigmaQtAP); - rLambda1405.fill(HIST("h2GenPtVsBachPtSigmaMinusPiToPiPiNeutron"), mcPart.pt(), bachPi.pt()); - rLambda1405.fill(HIST("h2GenPtVsSigmaPtSigmaMinusPiToPiPiNeutron"), mcPart.pt(), sigmaDaug.pt()); - rLambda1405.fill(HIST("h2GenSigmaPtVsKinkPtSigmaMinusPiToPiPiNeutron"), sigmaDaug.pt(), sigmaKinkDaug.pt()); + rLambda1405.fill(HIST("h2GenPtVsBachPtSigmaMinus"), mcPart.pt(), bachPi.pt()); + rLambda1405.fill(HIST("h2GenPtVsSigmaMinusPt"), mcPart.pt(), sigmaDaug.pt()); + rLambda1405.fill(HIST("h2GenSigmaPtVsKinkPtSigmaMinus"), sigmaDaug.pt(), sigmaKinkDaug.pt()); } if (decayChannel == kSigmaPlusPiToPiPiNeutron) { rLambda1405.fill(HIST("h2GenSigmaPlusArmPod"), genSigmaAlphaAP, genSigmaQtAP); - rLambda1405.fill(HIST("h2GenPtVsBachPtSigmaPlusPiToPiPiN"), mcPart.pt(), bachPi.pt()); - rLambda1405.fill(HIST("h2GenPtVsSigmaPtSigmaPlusPiToPiPiN"), mcPart.pt(), sigmaDaug.pt()); - rLambda1405.fill(HIST("h2GenSigmaPtVsKinkPtSigmaPlusPiToPiPiN"), sigmaDaug.pt(), sigmaKinkDaug.pt()); + rLambda1405.fill(HIST("h2GenPtVsBachPtSigmaPlusToPi"), mcPart.pt(), bachPi.pt()); + rLambda1405.fill(HIST("h2GenPtVsSigmaPlusToPiPt"), mcPart.pt(), sigmaDaug.pt()); + rLambda1405.fill(HIST("h2GenSigmaPtVsPiKinkPt"), sigmaDaug.pt(), sigmaKinkDaug.pt()); } if (decayChannel == kSigmaPlusPiToPiPiProton) { rLambda1405.fill(HIST("h2GenSigmaPlusArmPod"), genSigmaAlphaAP, genSigmaQtAP); - rLambda1405.fill(HIST("h2GenPtVsBachPtSigmaPlusPiToPiPiP"), mcPart.pt(), bachPi.pt()); - rLambda1405.fill(HIST("h2GenPtVsSigmaPtSigmaPlusPiToPiPiP"), mcPart.pt(), sigmaDaug.pt()); - rLambda1405.fill(HIST("h2GenSigmaPtVsKinkPtSigmaPlusPiToPiPiP"), sigmaDaug.pt(), sigmaKinkDaug.pt()); + rLambda1405.fill(HIST("h2GenPtVsBachPtSigmaPlusToPr"), mcPart.pt(), bachPi.pt()); + rLambda1405.fill(HIST("h2GenPtVsSigmaPlusToPrPt"), mcPart.pt(), sigmaDaug.pt()); + rLambda1405.fill(HIST("h2GenSigmaPtVsPrKinkPt"), sigmaDaug.pt(), sigmaKinkDaug.pt()); } } } - void processMc(CollisionsFullMc const& collisions, aod::KinkCands const& kinkCands, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC, TracksFull const& tracks) + void processMc(CollisionsFullMc const& recoCollisions, + aod::KinkCands const& kinkCands, + aod::McTrackLabels const& trackLabelsMC, + aod::McParticles const& particlesMC, + TracksFull const& tracks, + const aod::BCs&, + aod::McCollisions const&) { - fillOutputMc(collisions, kinkCands, trackLabelsMC, tracks, particlesMC); + fillOutputMc(recoCollisions, kinkCands, trackLabelsMC, tracks, particlesMC); } PROCESS_SWITCH(lambda1405analysis, processMc, "MC processing", false); - void processMcWCentSel(McRecoCollisionsCentSel const& collisions, aod::KinkCands const& kinkCands, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC, TracksFull const& tracks) + void processMcWCentSel(McRecoCollisionsCentSel const& recoCollisions, + aod::KinkCands const& kinkCands, + aod::McTrackLabels const& trackLabelsMC, + aod::McParticles const& particlesMC, + TracksFull const& tracks, + const aod::BCs&) { - fillOutputMc(collisions, kinkCands, trackLabelsMC, tracks, particlesMC); + fillOutputMc(recoCollisions, kinkCands, trackLabelsMC, tracks, particlesMC); } PROCESS_SWITCH(lambda1405analysis, processMcWCentSel, "MC processing with centrality selection", false); }; diff --git a/PWGLF/Tasks/Resonances/omega2012Analysis.cxx b/PWGLF/Tasks/Resonances/omega2012Analysis.cxx index 9bfdc99d194..2f9db446f51 100644 --- a/PWGLF/Tasks/Resonances/omega2012Analysis.cxx +++ b/PWGLF/Tasks/Resonances/omega2012Analysis.cxx @@ -33,9 +33,10 @@ #include #include +#include #include #include -#include +#include #include using namespace o2; @@ -49,7 +50,7 @@ struct Omega2012Analysis { static constexpr float kSmallNumber = 1e-10f; // Small number to avoid division by zero static constexpr float kMaxDCAV0ToPV = 1.0f; // Maximum DCA of V0 to PV static constexpr int kNumExpectedDaughters = 2; // Expected number of daughters for 2-body decay - static constexpr int kPlaceholderPdgCode = 9999999; // o2-linter: disable=pdg/explicit-code (placeholder for generator-specific Omega(2012) PDG code) + static constexpr int kPlaceholderPdgCode = 3335; SliceCache cache; Preslice perResoCollisionCasc = aod::resodaughter::resoCollisionId; Preslice perResoCollisionV0 = aod::resodaughter::resoCollisionId; @@ -70,10 +71,16 @@ struct Omega2012Analysis { // Basic pre-selections (mirroring refs) Configurable cMinPtcut{"cMinPtcut", 0.15, "Minimum pT for candidates"}; Configurable cMaxEtaCut{"cMaxEtaCut", 0.8, "Maximum |eta|"}; - // V0 selections (K0s) from k892pmanalysis - Configurable cV0MinCosPA{"cV0MinCosPA", 0.97, "V0 minimum pointing angle cosine"}; - Configurable cV0MaxDaughDCA{"cV0MaxDaughDCA", 1.0, "V0 daughter DCA Maximum"}; - Configurable cV0MassWindow{"cV0MassWindow", 0.0043, "Mass window for competing Lambda0 rejection"}; + Configurable cfgRapidityCut{"cfgRapidityCut", 0.5, "Rapidity cut"}; + Configurable cRecoINELgt0{"cRecoINELgt0", false, "Apply Reco INEL>0 event selection"}; + Configurable cKinCuts{"cKinCuts", false, "Kinematic cuts for Xi-K0s opening angle"}; + Configurable> cKinCutsPt{"cKinCutsPt", {0.0, 0.4, 0.6, 0.8, 1.0, 1.4, 1.8, 2.2, 2.6, 3.0, 4.0, 5.0, 6.0, 1e10}, "Omega(2012) pT bins for kinematic cuts"}; + Configurable> cKinLowerCutsAlpha{"cKinLowerCutsAlpha", {1.5, 1.0, 0.5, 0.3, 0.2, 0.15, 0.1, 0.08, 0.07, 0.06, 0.04, 0.02, 0.02}, "Lower cut on Xi-K0s opening angle"}; + Configurable> cKinUpperCutsAlpha{"cKinUpperCutsAlpha", {3.0, 2.0, 1.5, 1.4, 1.0, 0.8, 0.6, 0.5, 0.45, 0.35, 0.3, 0.25, 0.2}, "Upper cut on Xi-K0s opening angle"}; + // V0 selections (K0s) + Configurable cK0sMinCosPA{"cK0sMinCosPA", 0.98, "K0s minimum pointing angle cosine"}; + Configurable cK0sMaxDaughDCA{"cK0sMaxDaughDCA", 0.5, "K0s daughter DCA Maximum"}; + Configurable cK0sMassWindow{"cK0sMassWindow", 0.025, "Mass window for K0s selection (GeV/c^2)"}; Configurable cMaxV0Etacut{"cMaxV0Etacut", 0.8, "V0 maximum eta cut"}; // Xi (cascade) selections from xi1530Analysisqa.cxx @@ -116,12 +123,16 @@ struct Omega2012Analysis { // Enhanced K0s selections Configurable cK0sProperLifetimeMax{"cK0sProperLifetimeMax", 20.0, "K0s proper lifetime max (cm/c)"}; Configurable cK0sArmenterosQtMin{"cK0sArmenterosQtMin", 0.0, "K0s Armenteros qt min"}; - Configurable cK0sArmenterosAlphaMax{"cK0sArmenterosAlphaMax", 0.8, "K0s Armenteros alpha max"}; - Configurable cK0sDauPosDCAtoPVMin{"cK0sDauPosDCAtoPVMin", 0.1, "K0s positive daughter DCA to PV min"}; - Configurable cK0sDauNegDCAtoPVMin{"cK0sDauNegDCAtoPVMin", 0.1, "K0s negative daughter DCA to PV min"}; + Configurable cK0sArmenterosAlphaCoeff{"cK0sArmenterosAlphaCoeff", 0.2, "K0s Armenteros alpha coefficient"}; + Configurable cK0sDauPosDCAtoPVMin{"cK0sDauPosDCAtoPVMin", 0.05, "K0s positive daughter DCA to PV min"}; + Configurable cK0sDauNegDCAtoPVMin{"cK0sDauNegDCAtoPVMin", 0.05, "K0s negative daughter DCA to PV min"}; Configurable cK0sRadiusMin{"cK0sRadiusMin", 0.5, "K0s decay radius min"}; - Configurable cK0sRadiusMax{"cK0sRadiusMax", 100.0, "K0s decay radius max"}; + Configurable cK0sRadiusMax{"cK0sRadiusMax", 200.0, "K0s decay radius max"}; Configurable cK0sCrossMassRejection{"cK0sCrossMassRejection", true, "Enable Lambda mass rejection for K0s"}; + Configurable cK0sCrossMassRejectionWindow{"cK0sCrossMassRejectionWindow", 0.01, "Lambda mass rejection window for K0s (GeV/c^2)"}; + Configurable cK0sDaughterPiTPCNSigmaMax{"cK0sDaughterPiTPCNSigmaMax", 5.0, "Maximum TPC NSigma for K0s daughter pions"}; + Configurable cK0sPosDaughterMinCrossedRows{"cK0sPosDaughterMinCrossedRows", 50, "Minimum TPC crossed rows for K0s positive daughter"}; + Configurable cK0sNegDaughterMinCrossedRows{"cK0sNegDaughterMinCrossedRows", 50, "Minimum TPC crossed rows for K0s negative daughter"}; // Pion track selections for 3-body decay Configurable cPionPtMin{"cPionPtMin", 0.15, "Minimum pion pT"}; @@ -165,6 +176,10 @@ struct Omega2012Analysis { AxisSpec lifetimeAxis = {200, 0, 50, "Proper lifetime (cm/c)"}; AxisSpec armQtAxis = {100, 0, 0.3, "q_{T} (GeV/c)"}; AxisSpec armAlphaAxis = {100, -1.0, 1.0, "#alpha"}; + AxisSpec nsigmaAxis = {100, -5.0, 5.0, "N#sigma"}; + AxisSpec crossedRowsAxis = {160, 0, 160, "TPC crossed rows"}; + AxisSpec openingAngleAxis = {200, -0.15, 6.45, "#alpha_{oa}"}; + AxisSpec omegaKinPtAxis = {500, 0, 10, "#it{p}_{T} (GeV/#it{c})"}; // Event QA histograms histos.add("Event/posZ", "Event vertex Z position", kTH1F, {{200, -20., 20., "V_{z} (cm)"}}); @@ -212,6 +227,10 @@ struct Omega2012Analysis { histos.add("QAbefore/k0sArmenteros", "K0s Armenteros plot before cuts", kTH2F, {armAlphaAxis, armQtAxis}); histos.add("QAbefore/k0sDauPosDCA", "K0s positive daughter DCA before cuts", kTH2F, {ptAxisQA, dcaAxis}); histos.add("QAbefore/k0sDauNegDCA", "K0s negative daughter DCA before cuts", kTH2F, {ptAxisQA, dcaAxis}); + histos.add("QAbefore/k0sDauTPCNsigmaPosPi", "K0s positive daughter pion TPC NSigma before cuts", kTH2F, {ptAxisQA, nsigmaAxis}); + histos.add("QAbefore/k0sDauTPCNsigmaNegPi", "K0s negative daughter pion TPC NSigma before cuts", kTH2F, {ptAxisQA, nsigmaAxis}); + histos.add("QAbefore/k0sNCrossedRowsPos", "K0s positive daughter crossed rows before cuts", kTH2F, {ptAxisQA, crossedRowsAxis}); + histos.add("QAbefore/k0sNCrossedRowsNeg", "K0s negative daughter crossed rows before cuts", kTH2F, {ptAxisQA, crossedRowsAxis}); histos.add("QAafter/k0sMassPt", "K0s mass vs pT after cuts", kTH2F, {ptAxisQA, k0sMassAxis}); histos.add("QAafter/k0sPt", "K0s pT after cuts", kTH1F, {ptAxisQA}); @@ -224,19 +243,24 @@ struct Omega2012Analysis { histos.add("QAafter/k0sArmenteros", "K0s Armenteros plot after cuts", kTH2F, {armAlphaAxis, armQtAxis}); histos.add("QAafter/k0sDauPosDCA", "K0s positive daughter DCA after cuts", kTH2F, {ptAxisQA, dcaAxis}); histos.add("QAafter/k0sDauNegDCA", "K0s negative daughter DCA after cuts", kTH2F, {ptAxisQA, dcaAxis}); + histos.add("QAafter/k0sDauTPCNsigmaPosPi", "K0s positive daughter pion TPC NSigma after cuts", kTH2F, {ptAxisQA, nsigmaAxis}); + histos.add("QAafter/k0sDauTPCNsigmaNegPi", "K0s negative daughter pion TPC NSigma after cuts", kTH2F, {ptAxisQA, nsigmaAxis}); + histos.add("QAafter/k0sNCrossedRowsPos", "K0s positive daughter crossed rows after cuts", kTH2F, {ptAxisQA, crossedRowsAxis}); + histos.add("QAafter/k0sNCrossedRowsNeg", "K0s negative daughter crossed rows after cuts", kTH2F, {ptAxisQA, crossedRowsAxis}); // Resonance (2-body decay: Xi + K0s) histos.add("omega2012/invmass", "Invariant mass of Omega(2012) → Xi + K0s", kTH1F, {invMassAxis}); histos.add("omega2012/invmass_Mix", "Mixed event Invariant mass of Omega(2012) → Xi + K0s", kTH1F, {invMassAxis}); histos.add("omega2012/massPtCent", "Omega(2012) mass vs pT vs cent", kTH3F, {invMassAxis, ptAxis, centAxis}); histos.add("omega2012/massPtCent_Mix", "Mixed event Omega(2012) mass vs pT vs cent", kTH3F, {invMassAxis, ptAxis, centAxis}); + histos.add("QAbefore/omegaAlphaVsPt", "#alpha_{oa} vs p_{T} before kinematic cuts", kTH2F, {omegaKinPtAxis, openingAngleAxis}); + histos.add("QAafter/omegaAlphaVsPt", "#alpha_{oa} vs p_{T} after kinematic cuts", kTH2F, {omegaKinPtAxis, openingAngleAxis}); // 3-body decay: Xi + pi + K0s histos.add("omega2012_3body/invmass", "Invariant mass of Omega(2012) → Xi + #pi + K^{0}_{S}", kTH1F, {invMassAxis}); histos.add("omega2012_3body/massPtCent", "Omega(2012) 3-body mass vs pT vs cent", kTH3F, {invMassAxis, ptAxis, centAxis}); // Pion QA histograms for 3-body - AxisSpec nsigmaAxis = {100, -5.0, 5.0, "N#sigma"}; histos.add("QAbefore/pionPt", "Pion pT before cuts", kTH1F, {ptAxisQA}); histos.add("QAbefore/pionEta", "Pion eta before cuts", kTH1F, {{100, -2.0, 2.0, "#eta"}}); histos.add("QAbefore/pionDCAxy", "Pion DCAxy before cuts", kTH2F, {ptAxisQA, dcaxyAxis}); @@ -274,6 +298,93 @@ struct Omega2012Analysis { histos.add("MC/hMCTrueK0sPt", "MC True K0s pT", kTH1F, {ptAxis}); } + template + static std::array cascadeDaughterIds(const CascT& xi) + { + auto indices = xi.cascadeIndices(); + return {indices[0], indices[1], indices[2]}; + } + + template + static std::array v0DaughterIds(const V0Type& v0) + { + auto indices = v0.indices(); + return {indices[0], indices[1]}; + } + + template + static bool sharesAnyDaughterId(const std::array& first, const std::array& second) + { + for (const auto& firstId : first) { + for (const auto& secondId : second) { + if (firstId == secondId) { + return true; + } + } + } + return false; + } + + template + static bool sharesDaughterId(const std::array& daughters, int trackId) + { + for (const auto& daughterId : daughters) { + if (daughterId == trackId) { + return true; + } + } + return false; + } + + template + static int trackSourceId(const TrackT& track, const TrackIdsT& trackIds) + { + auto rowIndex = track.globalIndex(); + if (rowIndex >= 0 && rowIndex < trackIds.size()) { + return trackIds.rawIteratorAt(rowIndex).trackId(); + } + return rowIndex; + } + + template + bool kinCuts(const FirstVecT& firstDaughter, const SecondVecT& secondDaughter, const MotherVecT& mother, float& alpha) + { + auto firstP = std::sqrt(firstDaughter.Px() * firstDaughter.Px() + firstDaughter.Py() * firstDaughter.Py() + firstDaughter.Pz() * firstDaughter.Pz()); + auto secondP = std::sqrt(secondDaughter.Px() * secondDaughter.Px() + secondDaughter.Py() * secondDaughter.Py() + secondDaughter.Pz() * secondDaughter.Pz()); + if (firstP < kSmallNumber || secondP < kSmallNumber) { + alpha = 0.f; + return false; + } + + auto cosAlpha = (firstDaughter.Px() * secondDaughter.Px() + firstDaughter.Py() * secondDaughter.Py() + firstDaughter.Pz() * secondDaughter.Pz()) / (firstP * secondP); + if (cosAlpha > 1.) { + cosAlpha = 1.; + } else if (cosAlpha < -1.) { + cosAlpha = -1.; + } + alpha = std::acos(cosAlpha); + + std::vector kinCutsPt = static_cast>(cKinCutsPt); + std::vector kinLowerCutsAlpha = static_cast>(cKinLowerCutsAlpha); + std::vector kinUpperCutsAlpha = static_cast>(cKinUpperCutsAlpha); + + int kinCutsSize = static_cast(kinUpperCutsAlpha.size()); + if (kinCutsSize > static_cast(kinLowerCutsAlpha.size())) { + kinCutsSize = static_cast(kinLowerCutsAlpha.size()); + } + if (kinCutsSize > static_cast(kinCutsPt.size()) - 1) { + kinCutsSize = static_cast(kinCutsPt.size()) - 1; + } + + for (int i = 0; i < kinCutsSize; ++i) { + if ((mother.Pt() > kinCutsPt[i] && mother.Pt() <= kinCutsPt[i + 1]) && (alpha < kinLowerCutsAlpha[i] || alpha > kinUpperCutsAlpha[i])) { + return false; + } + } + + return true; + } + // Enhanced V0 selection (K0s) with detailed criteria template bool v0CutEnhanced(const CollisionType& collision, const V0Type& v0) @@ -285,9 +396,9 @@ struct Omega2012Analysis { return false; // Topological cuts - if (v0.v0CosPA() < cV0MinCosPA) + if (v0.v0CosPA() < cK0sMinCosPA) return false; - if (v0.daughDCA() > cV0MaxDaughDCA) + if (v0.daughDCA() > cK0sMaxDaughDCA) return false; // Enhanced selections from chk892Flow @@ -316,39 +427,34 @@ struct Omega2012Analysis { if (properLifetime > cK0sProperLifetimeMax) return false; - // Armenteros cut - skip for now as we don't have daughter momentum info in ResoV0s table - // If needed, this would require accessing daughter tracks separately or using alternative cuts + if (v0.qtarm() < cK0sArmenterosQtMin) + return false; // Mass window - if (std::abs(v0.mK0Short() - MassK0Short) > cV0MassWindow) + if (std::abs(v0.mK0Short() - MassK0Short) > cK0sMassWindow) return false; // Competing V0 rejection: remove (Anti)Λ if (cK0sCrossMassRejection) { - if (std::abs(v0.mLambda() - MassLambda) < cV0MassWindow) + if (std::abs(v0.mLambda() - MassLambda) < cK0sCrossMassRejectionWindow) return false; - if (std::abs(v0.mAntiLambda() - MassLambda) < cV0MassWindow) + if (std::abs(v0.mAntiLambda() - MassLambda) < cK0sCrossMassRejectionWindow) return false; } - return true; - } - - // Original V0 selection for backward compatibility - template - bool v0Cut(const V0Type& v0) - { - if (std::abs(v0.eta()) > cMaxV0Etacut) + if (std::abs(v0.daughterTPCNSigmaPosPi()) >= cK0sDaughterPiTPCNSigmaMax) return false; - if (v0.v0CosPA() < cV0MinCosPA) + if (std::abs(v0.daughterTPCNSigmaNegPi()) >= cK0sDaughterPiTPCNSigmaMax) return false; - if (v0.daughDCA() > cV0MaxDaughDCA) + + if (v0.nCrossedRowsPos() <= cK0sPosDaughterMinCrossedRows) return false; - // Competing V0 rejection: remove (Anti)Λ - if (std::abs(v0.mLambda() - MassLambda) < cV0MassWindow) + if (v0.nCrossedRowsNeg() <= cK0sNegDaughterMinCrossedRows) return false; - if (std::abs(v0.mAntiLambda() - MassLambda) < cV0MassWindow) + + if (v0.qtarm() < cK0sArmenterosAlphaCoeff * std::fabs(v0.alpha())) return false; + return true; } @@ -577,64 +683,34 @@ struct Omega2012Analysis { return true; } - template - void fill(const CollisionT& collision, const CascadesT& cascades, const V0sT& v0s) - { - auto cent = collision.cent(); - - // Fill event QA histograms (only for same-event) - if constexpr (!IsMix) { - histos.fill(HIST("Event/posZ"), collision.posZ()); - histos.fill(HIST("Event/centrality"), cent); - histos.fill(HIST("Event/posZvsCent"), collision.posZ(), cent); - histos.fill(HIST("Event/nCascades"), cascades.size()); - histos.fill(HIST("Event/nV0s"), v0s.size()); - } - - // Count candidates after cuts - int nCascAfterCuts = 0; - int nV0sAfterCuts = 0; + template + struct SelectedXiCandidate { + CandidateT candidate; + std::array daughterIds; + }; - for (const auto& xi : cascades) { - // QA before Xi cuts - detailed histograms - histos.fill(HIST("QAbefore/xiMass"), xi.mXi()); - histos.fill(HIST("QAbefore/xiPt"), xi.pt()); - histos.fill(HIST("QAbefore/xiEta"), xi.eta()); - histos.fill(HIST("QAbefore/xiDCAxy"), xi.pt(), xi.dcaXYCascToPV()); - histos.fill(HIST("QAbefore/xiDCAz"), xi.pt(), xi.dcaZCascToPV()); - histos.fill(HIST("QAbefore/xiV0CosPA"), xi.pt(), xi.v0CosPA()); - histos.fill(HIST("QAbefore/xiCascCosPA"), xi.pt(), xi.cascCosPA()); - histos.fill(HIST("QAbefore/xiV0Radius"), xi.pt(), xi.transRadius()); - histos.fill(HIST("QAbefore/xiCascRadius"), xi.pt(), xi.cascTransRadius()); - histos.fill(HIST("QAbefore/xiV0DauDCA"), xi.pt(), xi.daughDCA()); - histos.fill(HIST("QAbefore/xiCascDauDCA"), xi.pt(), xi.cascDaughDCA()); + template + struct SelectedK0sCandidate { + CandidateT candidate; + std::array daughterIds; + }; - if (!cascprimaryTrackCut(xi)) - continue; - if (!casctopCut(xi)) - continue; - - // Count cascades passing cuts - if constexpr (!IsMix) { - nCascAfterCuts++; - } - - // QA after Xi cuts - detailed histograms - histos.fill(HIST("QAafter/xiMass"), xi.mXi()); - histos.fill(HIST("QAafter/xiPt"), xi.pt()); - histos.fill(HIST("QAafter/xiEta"), xi.eta()); - histos.fill(HIST("QAafter/xiDCAxy"), xi.pt(), xi.dcaXYCascToPV()); - histos.fill(HIST("QAafter/xiDCAz"), xi.pt(), xi.dcaZCascToPV()); - histos.fill(HIST("QAafter/xiV0CosPA"), xi.pt(), xi.v0CosPA()); - histos.fill(HIST("QAafter/xiCascCosPA"), xi.pt(), xi.cascCosPA()); - histos.fill(HIST("QAafter/xiV0Radius"), xi.pt(), xi.transRadius()); - histos.fill(HIST("QAafter/xiCascRadius"), xi.pt(), xi.cascTransRadius()); - histos.fill(HIST("QAafter/xiV0DauDCA"), xi.pt(), xi.daughDCA()); - histos.fill(HIST("QAafter/xiCascDauDCA"), xi.pt(), xi.cascDaughDCA()); + template + auto selectK0sCandidates(const CollisionT& collision, const V0sT& v0s, int& nV0sAfterCuts) + { + using V0Candidate = std::decay_t; + std::vector> selectedK0s; + selectedK0s.reserve(v0s.size()); - // Build Xi + K0s - for (const auto& v0 : v0s) { - // QA before K0s selection - detailed histograms + for (const auto& v0 : v0s) { + float dx = v0.decayVtxX() - collision.posX(); + float dy = v0.decayVtxY() - collision.posY(); + float dz = v0.decayVtxZ() - collision.posZ(); + float l = std::sqrt(dx * dx + dy * dy + dz * dz); + float p = std::sqrt(v0.px() * v0.px() + v0.py() * v0.py() + v0.pz() * v0.pz()); + auto properLifetime = (l / (p + kSmallNumber)) * MassK0Short; + + if constexpr (FillQA) { histos.fill(HIST("QAbefore/k0sMassPt"), v0.pt(), v0.mK0Short()); histos.fill(HIST("QAbefore/k0sPt"), v0.pt()); histos.fill(HIST("QAbefore/k0sEta"), v0.eta()); @@ -642,28 +718,21 @@ struct Omega2012Analysis { histos.fill(HIST("QAbefore/k0sRadius"), v0.pt(), v0.transRadius()); histos.fill(HIST("QAbefore/k0sDauDCA"), v0.pt(), v0.daughDCA()); histos.fill(HIST("QAbefore/k0sDCAtoPV"), v0.pt(), std::abs(v0.dcav0topv())); - // Calculate proper lifetime manually - float dx = v0.decayVtxX() - collision.posX(); - float dy = v0.decayVtxY() - collision.posY(); - float dz = v0.decayVtxZ() - collision.posZ(); - float l = std::sqrt(dx * dx + dy * dy + dz * dz); - float p = std::sqrt(v0.px() * v0.px() + v0.py() * v0.py() + v0.pz() * v0.pz()); - auto properLifetime = (l / (p + 1e-10)) * MassK0Short; histos.fill(HIST("QAbefore/k0sProperLifetime"), v0.pt(), properLifetime); - // Skip Armenteros plot for now - requires daughter momentum info - // histos.fill(HIST("QAbefore/k0sArmenteros"), alpha, qt); + histos.fill(HIST("QAbefore/k0sArmenteros"), v0.alpha(), v0.qtarm()); histos.fill(HIST("QAbefore/k0sDauPosDCA"), v0.pt(), std::abs(v0.dcapostopv())); histos.fill(HIST("QAbefore/k0sDauNegDCA"), v0.pt(), std::abs(v0.dcanegtopv())); + histos.fill(HIST("QAbefore/k0sDauTPCNsigmaPosPi"), v0.pt(), v0.daughterTPCNSigmaPosPi()); + histos.fill(HIST("QAbefore/k0sDauTPCNsigmaNegPi"), v0.pt(), v0.daughterTPCNSigmaNegPi()); + histos.fill(HIST("QAbefore/k0sNCrossedRowsPos"), v0.pt(), v0.nCrossedRowsPos()); + histos.fill(HIST("QAbefore/k0sNCrossedRowsNeg"), v0.pt(), v0.nCrossedRowsNeg()); + } - if (!v0CutEnhanced(collision, v0)) - continue; - - // Count V0s passing cuts - if constexpr (!IsMix) { - nV0sAfterCuts++; - } + if (!v0CutEnhanced(collision, v0)) + continue; - // QA after K0s selection - detailed histograms + if constexpr (FillQA) { + nV0sAfterCuts++; histos.fill(HIST("QAafter/k0sMassPt"), v0.pt(), v0.mK0Short()); histos.fill(HIST("QAafter/k0sPt"), v0.pt()); histos.fill(HIST("QAafter/k0sEta"), v0.eta()); @@ -672,10 +741,102 @@ struct Omega2012Analysis { histos.fill(HIST("QAafter/k0sDauDCA"), v0.pt(), v0.daughDCA()); histos.fill(HIST("QAafter/k0sDCAtoPV"), v0.pt(), std::abs(v0.dcav0topv())); histos.fill(HIST("QAafter/k0sProperLifetime"), v0.pt(), properLifetime); - // Skip Armenteros plot for now - requires daughter momentum info - // histos.fill(HIST("QAafter/k0sArmenteros"), alpha, qt); + histos.fill(HIST("QAafter/k0sArmenteros"), v0.alpha(), v0.qtarm()); histos.fill(HIST("QAafter/k0sDauPosDCA"), v0.pt(), std::abs(v0.dcapostopv())); histos.fill(HIST("QAafter/k0sDauNegDCA"), v0.pt(), std::abs(v0.dcanegtopv())); + histos.fill(HIST("QAafter/k0sDauTPCNsigmaPosPi"), v0.pt(), v0.daughterTPCNSigmaPosPi()); + histos.fill(HIST("QAafter/k0sDauTPCNsigmaNegPi"), v0.pt(), v0.daughterTPCNSigmaNegPi()); + histos.fill(HIST("QAafter/k0sNCrossedRowsPos"), v0.pt(), v0.nCrossedRowsPos()); + histos.fill(HIST("QAafter/k0sNCrossedRowsNeg"), v0.pt(), v0.nCrossedRowsNeg()); + } + + selectedK0s.push_back({v0, v0DaughterIds(v0)}); + } + + return selectedK0s; + } + + template + auto selectXiCandidates(const CascadesT& cascades, int& nCascAfterCuts) + { + using XiCandidate = std::decay_t; + std::vector> selectedXis; + selectedXis.reserve(cascades.size()); + + for (const auto& xi : cascades) { + if constexpr (FillQA) { + histos.fill(HIST("QAbefore/xiMass"), xi.mXi()); + histos.fill(HIST("QAbefore/xiPt"), xi.pt()); + histos.fill(HIST("QAbefore/xiEta"), xi.eta()); + histos.fill(HIST("QAbefore/xiDCAxy"), xi.pt(), xi.dcaXYCascToPV()); + histos.fill(HIST("QAbefore/xiDCAz"), xi.pt(), xi.dcaZCascToPV()); + histos.fill(HIST("QAbefore/xiV0CosPA"), xi.pt(), xi.v0CosPA()); + histos.fill(HIST("QAbefore/xiCascCosPA"), xi.pt(), xi.cascCosPA()); + histos.fill(HIST("QAbefore/xiV0Radius"), xi.pt(), xi.transRadius()); + histos.fill(HIST("QAbefore/xiCascRadius"), xi.pt(), xi.cascTransRadius()); + histos.fill(HIST("QAbefore/xiV0DauDCA"), xi.pt(), xi.daughDCA()); + histos.fill(HIST("QAbefore/xiCascDauDCA"), xi.pt(), xi.cascDaughDCA()); + } + + if (!cascprimaryTrackCut(xi)) + continue; + if (!casctopCut(xi)) + continue; + + if constexpr (FillQA) { + nCascAfterCuts++; + histos.fill(HIST("QAafter/xiMass"), xi.mXi()); + histos.fill(HIST("QAafter/xiPt"), xi.pt()); + histos.fill(HIST("QAafter/xiEta"), xi.eta()); + histos.fill(HIST("QAafter/xiDCAxy"), xi.pt(), xi.dcaXYCascToPV()); + histos.fill(HIST("QAafter/xiDCAz"), xi.pt(), xi.dcaZCascToPV()); + histos.fill(HIST("QAafter/xiV0CosPA"), xi.pt(), xi.v0CosPA()); + histos.fill(HIST("QAafter/xiCascCosPA"), xi.pt(), xi.cascCosPA()); + histos.fill(HIST("QAafter/xiV0Radius"), xi.pt(), xi.transRadius()); + histos.fill(HIST("QAafter/xiCascRadius"), xi.pt(), xi.cascTransRadius()); + histos.fill(HIST("QAafter/xiV0DauDCA"), xi.pt(), xi.daughDCA()); + histos.fill(HIST("QAafter/xiCascDauDCA"), xi.pt(), xi.cascDaughDCA()); + } + + selectedXis.push_back({xi, cascadeDaughterIds(xi)}); + } + + return selectedXis; + } + + template + void fill(const CollisionT& collision, const CascadesT& cascades, const V0sT& v0s) + { + auto cent = collision.cent(); + + // Fill event QA histograms (only for same-event) + if constexpr (!IsMix) { + histos.fill(HIST("Event/posZ"), collision.posZ()); + histos.fill(HIST("Event/centrality"), cent); + histos.fill(HIST("Event/posZvsCent"), collision.posZ(), cent); + histos.fill(HIST("Event/nCascades"), cascades.size()); + histos.fill(HIST("Event/nV0s"), v0s.size()); + } + + // Count candidates after cuts + int nCascAfterCuts = 0; + int nV0sAfterCuts = 0; + + auto selectedK0s = selectK0sCandidates(collision, v0s, nV0sAfterCuts); + auto selectedXis = selectXiCandidates(cascades, nCascAfterCuts); + + for (const auto& selectedXi : selectedXis) { + const auto& xi = selectedXi.candidate; + + // Build Xi + K0s + for (const auto& selectedK0 : selectedK0s) { + const auto& v0 = selectedK0.candidate; + + if constexpr (!IsMix) { + if (sharesAnyDaughterId(selectedXi.daughterIds, selectedK0.daughterIds)) { + continue; + } + } // 4-vectors ROOT::Math::PxPyPzEVector pXi, pK0s, pRes; @@ -683,6 +844,27 @@ struct Omega2012Analysis { pK0s = ROOT::Math::PxPyPzEVector(ROOT::Math::PtEtaPhiMVector(v0.pt(), v0.eta(), v0.phi(), massK0)); pRes = pXi + pK0s; + float alpha = 0.f; + bool kinCutFlag = true; + if (cKinCuts) { + kinCutFlag = kinCuts(pXi, pK0s, pRes, alpha); + if constexpr (!IsMix) { + histos.fill(HIST("QAbefore/omegaAlphaVsPt"), pRes.Pt(), alpha); + } + } + + if (cKinCuts && !kinCutFlag) + continue; + + if constexpr (!IsMix) { + if (cKinCuts) { + histos.fill(HIST("QAafter/omegaAlphaVsPt"), pRes.Pt(), alpha); + } + } + + if (std::abs(pRes.Rapidity()) >= cfgRapidityCut) + continue; + if constexpr (!IsMix) { histos.fill(HIST("omega2012/invmass"), pRes.M()); histos.fill(HIST("omega2012/massPtCent"), pRes.M(), pRes.Pt(), cent); @@ -710,6 +892,9 @@ struct Omega2012Analysis { aod::ResoCascades const& resocasc, aod::ResoV0s const& resov0s) { + if (cRecoINELgt0 && !collision.isRecINELgt0()) + return; + fill(collision, resocasc, resov0s); } PROCESS_SWITCH(Omega2012Analysis, processData, "Process Event for data", false); @@ -722,25 +907,38 @@ struct Omega2012Analysis { auto cascV0sTuple = std::make_tuple(resocasc, resov0s); Pair pairs{colBinning, nEvtMixing, -1, collisions, cascV0sTuple, &cache}; - for (auto& [collision1, casc1, collision2, v0s2] : pairs) { // o2-linter: disable=const-ref-in-for-loop (structured binding cannot be const in this context) - auto cent = collision1.cent(); + for (const auto& [collision1, casc1, collision2, v0s2] : pairs) { + if (cRecoINELgt0 && (!collision1.isRecINELgt0() || !collision2.isRecINELgt0())) + continue; - for (const auto& xi : casc1) { - if (!cascprimaryTrackCut(xi)) - continue; - if (!casctopCut(xi)) - continue; + auto cent = collision1.cent(); + int unusedXiCount = 0; + int unusedK0sCount = 0; + auto selectedXis = selectXiCandidates(casc1, unusedXiCount); + auto selectedK0s = selectK0sCandidates(collision2, v0s2, unusedK0sCount); - for (const auto& v0 : v0s2) { - if (!v0CutEnhanced(collision2, v0)) - continue; + for (const auto& selectedXi : selectedXis) { + const auto& xi = selectedXi.candidate; - // 4-vectors for mixed event + for (const auto& selectedK0 : selectedK0s) { + const auto& v0 = selectedK0.candidate; ROOT::Math::PxPyPzEVector pXi, pK0s, pRes; pXi = ROOT::Math::PxPyPzEVector(ROOT::Math::PtEtaPhiMVector(xi.pt(), xi.eta(), xi.phi(), xi.mXi())); pK0s = ROOT::Math::PxPyPzEVector(ROOT::Math::PtEtaPhiMVector(v0.pt(), v0.eta(), v0.phi(), massK0)); pRes = pXi + pK0s; + float alpha = 0.f; + bool kinCutFlag = true; + if (cKinCuts) { + kinCutFlag = kinCuts(pXi, pK0s, pRes, alpha); + } + + if (cKinCuts && !kinCutFlag) + continue; + + if (std::abs(pRes.Rapidity()) >= cfgRapidityCut) + continue; + histos.fill(HIST("omega2012/invmass_Mix"), pRes.M()); histos.fill(HIST("omega2012/massPtCent_Mix"), pRes.M(), pRes.Pt(), cent); } @@ -767,16 +965,14 @@ struct Omega2012Analysis { void processMCGenerated(aod::McParticles const& mcParticles) { // Process MC generated particles (no reconstruction requirement) - // Omega(2012) PDG code: Need to check - likely custom or using generator-specific codes // This resonance decays to Xi + K0s for (const auto& mcParticle : mcParticles) { // Look for Omega(2012) - PDG code may vary by generator int pdg = mcParticle.pdgCode(); - // TODO: Determine correct PDG code for Omega(2012) - // Placeholder check - update with correct PDG code - if (std::abs(pdg) != kPlaceholderPdgCode) // o2-linter: disable=pdg/explicit-code (placeholder for generator-specific PDG code) + // TODO: Update the PDG code library to include Omega(2012) codes + if (std::abs(pdg) != kPlaceholderPdgCode) continue; // Fill generated level histograms @@ -825,49 +1021,22 @@ struct Omega2012Analysis { PROCESS_SWITCH(Omega2012Analysis, processMCGenerated, "Process MC generated particles (placeholder)", false); // Fill function for 3-body decay analysis - template - void fillThreeBody(const CollisionT& collision, const CascadesT& cascades, const V0sT& v0s, const TracksT& tracks) + template + void fillThreeBody(const CollisionT& collision, const CascadesT& cascades, const V0sT& v0s, const TracksT& tracks, const TrackIdsT& trackIds) { auto cent = collision.cent(); - - // Collect track IDs used in xi and v0 construction to exclude them from pion selection - std::set usedTrackIds; - - // Collect track IDs from xi cascades - for (const auto& xi : cascades) { - if (!cascprimaryTrackCut(xi)) - continue; - if (!casctopCut(xi)) - continue; - - // Add xi daughter track IDs from cascadeIndices array (ordered: positive, negative, bachelor) - auto cascIndices = xi.cascadeIndices(); - usedTrackIds.insert(cascIndices[0]); // positive track - usedTrackIds.insert(cascIndices[1]); // negative track - usedTrackIds.insert(cascIndices[2]); // bachelor track - } - - // Collect track IDs from v0s - for (const auto& v0 : v0s) { - if (!v0CutEnhanced(collision, v0)) - continue; - - // Add v0 daughter track IDs from indices array - auto v0Indices = v0.indices(); - usedTrackIds.insert(v0Indices[0]); // positive track - usedTrackIds.insert(v0Indices[1]); // negative track - } + int unusedXiCount = 0; + int unusedK0sCount = 0; + auto selectedXis = selectXiCandidates(cascades, unusedXiCount); + auto selectedK0s = selectK0sCandidates(collision, v0s, unusedK0sCount); // First loop: xi + pion to check xi1530 mass window - for (const auto& xi : cascades) { - if (!cascprimaryTrackCut(xi)) - continue; - if (!casctopCut(xi)) - continue; + for (const auto& selectedXi : selectedXis) { + const auto& xi = selectedXi.candidate; for (const auto& pion : tracks) { - // Skip pion tracks that are already used in xi construction - if (usedTrackIds.find(pion.globalIndex()) != usedTrackIds.end()) { + auto pionTrackId = trackSourceId(pion, trackIds); + if (sharesDaughterId(selectedXi.daughterIds, pionTrackId)) { continue; } @@ -925,9 +1094,14 @@ struct Omega2012Analysis { continue; // Second loop: v0 for the selected xi-pion pair - for (const auto& v0 : v0s) { - if (!v0CutEnhanced(collision, v0)) + for (const auto& selectedK0 : selectedK0s) { + const auto& v0 = selectedK0.candidate; + if (sharesAnyDaughterId(selectedXi.daughterIds, selectedK0.daughterIds)) { + continue; + } + if (sharesDaughterId(selectedK0.daughterIds, pionTrackId)) { continue; + } // 4-vectors for 3-body decay: Xi + K0s + pion ROOT::Math::PxPyPzEVector pXi, pK0s, pPion, pRes; @@ -937,6 +1111,9 @@ struct Omega2012Analysis { pRes = pXi + pK0s + pPion; + if (std::abs(pRes.Rapidity()) >= cfgRapidityCut) + continue; + histos.fill(HIST("omega2012_3body/invmass"), pRes.M()); histos.fill(HIST("omega2012_3body/massPtCent"), pRes.M(), pRes.Pt(), cent); } @@ -948,9 +1125,13 @@ struct Omega2012Analysis { void processThreeBodyWithTracks(const aod::ResoCollision& collision, aod::ResoCascades const& resocasc, aod::ResoV0s const& resov0s, - aod::ResoTracks const& resotracks) + aod::ResoTracks const& resotracks, + aod::ResoTrackTracks const& resotrackids) { - fillThreeBody(collision, resocasc, resov0s, resotracks); + if (cRecoINELgt0 && !collision.isRecINELgt0()) + return; + + fillThreeBody(collision, resocasc, resov0s, resotracks, resotrackids); } PROCESS_SWITCH(Omega2012Analysis, processThreeBodyWithTracks, "Process 3-body decay with ResoTracks", false); @@ -958,9 +1139,13 @@ struct Omega2012Analysis { void processThreeBodyWithMicroTracks(const aod::ResoCollision& collision, aod::ResoCascades const& resocasc, aod::ResoV0s const& resov0s, - aod::ResoMicroTracks const& resomicrotracks) + aod::ResoMicroTracks const& resomicrotracks, + aod::ResoMicroTrackTracks const& resomicrotrackids) { - fillThreeBody(collision, resocasc, resov0s, resomicrotracks); + if (cRecoINELgt0 && !collision.isRecINELgt0()) + return; + + fillThreeBody(collision, resocasc, resov0s, resomicrotracks, resomicrotrackids); } PROCESS_SWITCH(Omega2012Analysis, processThreeBodyWithMicroTracks, "Process 3-body decay with ResoMicroTracks", false); }; diff --git a/PWGLF/Tasks/Resonances/phi1020analysis.cxx b/PWGLF/Tasks/Resonances/phi1020analysis.cxx index 5aa6fcd35ce..c50093c91c2 100644 --- a/PWGLF/Tasks/Resonances/phi1020analysis.cxx +++ b/PWGLF/Tasks/Resonances/phi1020analysis.cxx @@ -136,6 +136,7 @@ struct Phi1020analysis { Configurable pidnSigmaPreSelectionCut{"pidnSigmaPreSelectionCut", 4.0f, "pidnSigma Cut for pre-selection of tracks"}; Configurable cByPassTOF{"cByPassTOF", false, "By pass TOF PID selection"}; // By pass TOF PID selection Configurable cPIDcutType{"cPIDcutType", 2, "cPIDcutType = 1 for square cut, 2 for circular cut"}; // By pass TOF PID selection + Configurable ispTdepPID{"ispTdepPID", false, "enable pT dependent PID"}; // Kaon Configurable> kaonTPCPIDpTintv{"kaonTPCPIDpTintv", {0.5f}, "pT intervals for Kaon TPC PID cuts"}; @@ -576,6 +577,24 @@ struct Phi1020analysis { return false; } + template + bool selectionPID(const T& candidate) + { + auto vKaonTPCPIDcuts = configPID.kaonTPCPIDcuts.value; + auto vKaonTPCTOFCombinedPIDcuts = configPID.kaonTPCTOFCombinedPIDcuts.value; + + if (!configPID.cByPassTOF && candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (vKaonTPCTOFCombinedPIDcuts[0] * vKaonTPCTOFCombinedPIDcuts[0])) { + return true; + } + if (!configPID.cByPassTOF && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < vKaonTPCPIDcuts[0]) { + return true; + } + if (configPID.cByPassTOF && std::abs(candidate.tpcNSigmaKa()) < vKaonTPCPIDcuts[0]) { + return true; + } + return false; + } + auto static constexpr MinPtforPionRejection = 1.0f; auto static constexpr MaxPtforPionRejection = 2.0f; auto static constexpr MaxnSigmaforPionRejection = 2.0f; @@ -685,7 +704,10 @@ struct Phi1020analysis { if (crejectPion && rejectPion(trk2)) // to remove pion contamination from the kaon track continue; - if (!ptDependentPidKaon(trk1) || !ptDependentPidKaon(trk2)) + if (configPID.ispTdepPID && (!ptDependentPidKaon(trk1) || !ptDependentPidKaon(trk2))) + continue; + + if (!configPID.ispTdepPID && (!selectionPID(trk1) || !selectionPID(trk2))) continue; //// QA plots after the selection @@ -1170,19 +1192,6 @@ struct Phi1020analysis { // ========================= if (std::abs(part.pdgCode()) == Pdg::kPhi) { - std::vector daughterPDGs; - if (part.has_daughters()) { - auto daughter01 = mcParticles.rawIteratorAt(part.daughtersIds()[0] - mcParticles.offset()); - auto daughter02 = mcParticles.rawIteratorAt(part.daughtersIds()[1] - mcParticles.offset()); - daughterPDGs = {daughter01.pdgCode(), daughter02.pdgCode()}; - } else { - daughterPDGs = {-1, -1}; - } - - if (std::abs(daughterPDGs[0]) != PDG_t::kKPlus || std::abs(daughterPDGs[1]) != PDG_t::kKPlus) { // At least one decay to Kaon - continue; - } - histos.fill(HIST("Result/SignalLoss/GenTruephi1020pt_den"), part.pt(), centrality); } } diff --git a/PWGLF/Tasks/Resonances/phiflowder.cxx b/PWGLF/Tasks/Resonances/phiflowder.cxx new file mode 100644 index 00000000000..1293ceb8b3b --- /dev/null +++ b/PWGLF/Tasks/Resonances/phiflowder.cxx @@ -0,0 +1,217 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file phiflowder.cxx +/// \brief Derived task for same-event and mixed-event Phi reconstruction for v1 +/// +/// \author Prottay Das + +#include "PWGLF/DataModel/LFPhiFlowTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include + +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct phiflowder { + + Configurable centMin{"centMin", 0.f, "Minimum centrality"}; + Configurable centMax{"centMax", 80.f, "Maximum centrality"}; + + Configurable useStoredPID{"useStoredPID", false, "Apply PID-bit selection using stored kaon PID mask"}; + Configurable pidChoice{"pidChoice", 2, "PID choice: 1, 2, 3, or 4"}; + Configurable pidExclusive{"pidExclusive", false, "Require exactly the selected PID bit"}; + + Configurable applyDeepAngle{"applyDeepAngle", false, "Apply minimum opening-angle cut for K+K- pairs"}; + Configurable deepAngleCut{"deepAngleCut", 0.04f, "Minimum K+K- opening angle"}; + + Configurable massMin{"massMin", 0.9f, "Minimum K+K- mass to fill"}; + Configurable massMax{"massMax", 1.2f, "Maximum K+K- mass to fill"}; + + ConfigurableAxis axisInvMass{"axisInvMass", {120, 0.9f, 1.2f}, "#it{M}_{K^{+}K^{-}} (GeV/#it{c}^{2})"}; + ConfigurableAxis axisPhiPt{"axisPhiPt", {100, 0.f, 10.f}, "#it{p}_{T}^{K^{+}K^{-}} (GeV/#it{c})"}; + ConfigurableAxis axisCent{"axisCent", {80, 0.f, 80.f}, "Centrality (%)"}; + ConfigurableAxis axisNKaons{"axisNKaons", {300, 0.f, 300.f}, "Number of stored kaons per event"}; + ConfigurableAxis axisNPairs{"axisNPairs", {500, 0.f, 5000.f}, "Number of K^{+}K^{-} pairs per event"}; + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + static constexpr uint8_t kPID1 = 1u << 0; + static constexpr uint8_t kPID2 = 1u << 1; + static constexpr uint8_t kPID3 = 1u << 2; + static constexpr uint8_t kPID4 = 1u << 3; + + SliceCache cache; + + void init(InitContext const&) + { + histos.add("hCentrality", "Centrality distribution", kTH1F, {axisCent}); + histos.add("hPhiMassSame", "Same-event K^{+}K^{-} invariant mass", kTH1F, {axisInvMass}); + histos.add("hPhiPtSame", "Same-event K^{+}K^{-} pT", kTH1F, {axisPhiPt}); + histos.add("hNplusPerEvent", "Number of stored K^{+} per event", kTH1F, {axisNKaons}); + histos.add("hNminusPerEvent", "Number of stored K^{-} per event", kTH1F, {axisNKaons}); + histos.add("hNphiSamePerEvent", "Number of same-event K^{+}K^{-} pairs per event", kTH1F, {axisNPairs}); + histos.add("hSparseSame", "Same-event K^{+}K^{-};M;pT;centrality", kTHnSparseF, {axisInvMass, axisPhiPt, axisCent}); + } + + uint8_t getRequiredPidBit() const + { + switch (pidChoice.value) { + case 1: + return kPID1; + case 2: + return kPID2; + case 3: + return kPID3; + case 4: + return kPID4; + default: + LOGF(warn, "Invalid pidChoice=%d. PID2 will be used.", pidChoice.value); + return kPID2; + } + } + + template + bool passStoredPID(const T& kaon) const + { + if (!useStoredPID.value) { + return true; + } + + const uint16_t mask = kaon.kaonPidMask(); + const uint8_t requiredBit = getRequiredPidBit(); + + if (pidExclusive.value) { + return mask == requiredBit; + } + + return (mask & requiredBit) != 0; + } + + bool passDeepAngle(float px1, float py1, float pz1, float px2, float py2, float pz2) const + { + if (!applyDeepAngle.value) { + return true; + } + + const double p1 = std::sqrt(px1 * px1 + py1 * py1 + pz1 * pz1); + const double p2 = std::sqrt(px2 * px2 + py2 * py2 + pz2 * pz2); + + if (p1 <= 0.0 || p2 <= 0.0) { + return false; + } + + const double cosAngle = std::clamp((px1 * px2 + py1 * py2 + pz1 * pz2) / (p1 * p2), -1.0, 1.0); + const double angle = std::acos(cosAngle); + + return angle >= deepAngleCut.value; + } + + Filter centralityFilter = (aod::kaonevent::cent >= centMin) && (aod::kaonevent::cent < centMax); + + using EventCandidates = soa::Filtered; + + Partition posKaons = aod::kaonpair::charge > int8_t{0}; + Partition negKaons = aod::kaonpair::charge < int8_t{0}; + + void processSameData(EventCandidates::iterator const& collision, aod::KaonTracks const& /*kaontracks*/) + { + const float centrality = collision.cent(); + + histos.fill(HIST("hCentrality"), centrality); + + auto posThisColl = posKaons->sliceByCached(aod::kaonpair::kaoneventId, collision.globalIndex(), cache); + auto negThisColl = negKaons->sliceByCached(aod::kaonpair::kaoneventId, collision.globalIndex(), cache); + + int nPlus = 0; + int nMinus = 0; + int nPhiSame = 0; + + for (const auto& kPlus : posThisColl) { + if (passStoredPID(kPlus)) { + nPlus++; + } + } + + for (const auto& kMinus : negThisColl) { + if (passStoredPID(kMinus)) { + nMinus++; + } + } + + histos.fill(HIST("hNplusPerEvent"), nPlus); + histos.fill(HIST("hNminusPerEvent"), nMinus); + + for (const auto& kPlus : posThisColl) { + if (!passStoredPID(kPlus)) { + continue; + } + + ROOT::Math::PxPyPzMVector plusVec(kPlus.px(), kPlus.py(), kPlus.pz(), o2::constants::physics::MassKPlus); + + for (const auto& kMinus : negThisColl) { + if (!passStoredPID(kMinus)) { + continue; + } + + if (!passDeepAngle(kPlus.px(), kPlus.py(), kPlus.pz(), kMinus.px(), kMinus.py(), kMinus.pz())) { + continue; + } + + ROOT::Math::PxPyPzMVector minusVec(kMinus.px(), kMinus.py(), kMinus.pz(), o2::constants::physics::MassKPlus); + + const auto phiCandidate = plusVec + minusVec; + + const float phiMass = phiCandidate.M(); + const float phiPt = phiCandidate.Pt(); + + if (phiMass < massMin || phiMass > massMax) { + continue; + } + + histos.fill(HIST("hPhiMassSame"), phiMass); + histos.fill(HIST("hPhiPtSame"), phiPt); + histos.fill(HIST("hSparseSame"), phiMass, phiPt, centrality); + + nPhiSame++; + } + } + + histos.fill(HIST("hNphiSamePerEvent"), nPhiSame); + } + + PROCESS_SWITCH(phiflowder, processSameData, "Process same-event K+K- pairs", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/Strangeness/cascpostprocessing.cxx b/PWGLF/Tasks/Strangeness/cascpostprocessing.cxx index 29ac791051d..2b6c5d094c3 100644 --- a/PWGLF/Tasks/Strangeness/cascpostprocessing.cxx +++ b/PWGLF/Tasks/Strangeness/cascpostprocessing.cxx @@ -26,7 +26,9 @@ #include #include +#include #include +#include #include #include #include @@ -44,7 +46,51 @@ using namespace o2::framework; using namespace o2::framework::expressions; struct LfCascpostprocessing { - static constexpr int OobRejTofOnly = 2; + static constexpr int TrackQualityTofHighPt = 2; + static constexpr int TrackQualityMinITS = 3; + + enum MisidentifiedParticleBin { + kMisIdUnknown = 0, + kMisIdElectron, + kMisIdMuon, + kMisIdPion, + kMisIdKaon, + kMisIdProton, + kMisIdK0Short, + kMisIdLambda, + kMisIdXi, + kMisIdOmega, + kMisIdOther, + kNMisidentifiedParticleBins + }; + + static int getMisidentifiedParticleBin(int pdgCode) + { + switch (TMath::Abs(pdgCode)) { + case 0: + return kMisIdUnknown; + case PDG_t::kElectron: + return kMisIdElectron; + case PDG_t::kMuonMinus: + return kMisIdMuon; + case PDG_t::kPiPlus: + return kMisIdPion; + case PDG_t::kKPlus: + return kMisIdKaon; + case PDG_t::kProton: + return kMisIdProton; + case PDG_t::kK0Short: + return kMisIdK0Short; + case PDG_t::kLambda0: + return kMisIdLambda; + case PDG_t::kXiMinus: + return kMisIdXi; + case PDG_t::kOmegaMinus: + return kMisIdOmega; + default: + return kMisIdOther; + } + } // Xi or Omega Configurable isXi{"isXi", 1, "Apply cuts for Xi identification"}; @@ -79,7 +125,8 @@ struct LfCascpostprocessing { Configurable nsigmatofPr{"nsigmatofPr", 6, "N sigma TOF Proton"}; Configurable nsigmatofKa{"nsigmatofKa", 6, "N sigma TOF Kaon"}; Configurable mintpccrrows{"mintpccrrows", 50, "min N TPC crossed rows"}; - Configurable dooobrej{"dooobrej", 0, "OOB rejection: 0 no selection, 1 = ITS||TOF, 2 = TOF only for pT > ptthrtof"}; + Configurable dooobrej{"dooobrej", 0, "Track association requirement: 0 no selection, 1 = ITS||TOF, 2 = TOF only for pT > ptthrtof, 3 = ITS hits >= trackQualityMinITS"}; + Configurable trackQualityMinITS{"trackQualityMinITS", 2, "Minimum ITS hits for dooobrej=3 track-quality variation"}; Configurable isSelectBachBaryon{"isSelectBachBaryon", 0, "Bachelor-baryon cascade selection"}; Configurable bachBaryonCosPA{"bachBaryonCosPA", 0.9999, "Bachelor baryon CosPA"}; @@ -107,6 +154,13 @@ struct LfCascpostprocessing { AxisSpec ptAxisPID = {50, 0.0f, 10.0f, "#it{p}_{T} (GeV/#it{c})"}; ConfigurableAxis etaAxis{"etaAxis", {40, -2.0f, 2.0f}, "#eta"}; AxisSpec pdgCodeAxis = {10001, -5000.5f, 5000.5f, "MC PDG code (0 = no MC assoc.)"}; + AxisSpec misidentifiedParticleAxis = {kNMisidentifiedParticleBins, -0.5f, static_cast(kNMisidentifiedParticleBins) - 0.5f, "Associated MC particle"}; + auto setMisidentifiedParticleLabels = [](TAxis* axis) { + TString misidentifiedParticleLabels[kNMisidentifiedParticleBins] = {"Unknown/no assoc.", "e", "#mu", "#pi", "K", "p", "K^{0}_{S}", "#Lambda", "#Xi", "#Omega", "Other"}; + for (int n = 1; n <= kNMisidentifiedParticleBins; n++) { + axis->SetBinLabel(n, misidentifiedParticleLabels[n - 1]); + } + }; ConfigurableAxis centFT0MAxis{"centFT0MAxis", {VARIABLE_WIDTH, 0., 0.01, 0.05, 0.1, 0.5, 1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 101, 105.5}, @@ -119,8 +173,8 @@ struct LfCascpostprocessing { AxisSpec rapidityAxis = {200, -2.0f, 2.0f, "y"}; - TString CutLabel[26] = {"All", "MassWin", "y", "EtaDau", "DCADauToPV", "CascCosPA", "V0CosPA", "DCACascDau", "DCAV0Dau", "rCasc", "rCascMax", "rV0", "rV0Max", "DCAV0ToPV", "LambdaMass", "TPCPr", "TPCPi", "TOFPr", "TOFPi", "TPCBach", "TOFBach", "ctau", "CompDecayMass", "Bach-baryon", "NTPCrows", "OOBRej"}; - TString CutLabelSummary[29] = {"MassWin", "y", "EtaDau", "dcapostopv", "dcanegtopv", "dcabachtopv", "CascCosPA", "V0CosPA", "DCACascDau", "DCAV0Dau", "rCasc", "rV0", "DCAV0ToPV", "LambdaMass", "TPCPr", "TPCPi", "TOFPr", "TOFPi", "TPCBach", "TOFBach", "proplifetime", "rejcomp", "ptthrtof", "bachBaryonCosPA", "bachBaryonDCAxyToPV", "NTPCrows", "OOBRej", "rCascMax", "rV0Max"}; + TString CutLabel[26] = {"All", "MassWin", "y", "EtaDau", "DCADauToPV", "CascCosPA", "V0CosPA", "DCACascDau", "DCAV0Dau", "rCasc", "rCascMax", "rV0", "rV0Max", "DCAV0ToPV", "LambdaMass", "TPCPr", "TPCPi", "TOFPr", "TOFPi", "TPCBach", "TOFBach", "ctau", "CompDecayMass", "Bach-baryon", "NTPCrows", "TrackQuality"}; + TString CutLabelSummary[29] = {"MassWin", "y", "EtaDau", "dcapostopv", "dcanegtopv", "dcabachtopv", "CascCosPA", "V0CosPA", "DCACascDau", "DCAV0Dau", "rCasc", "rV0", "DCAV0ToPV", "LambdaMass", "TPCPr", "TPCPi", "TOFPr", "TOFPi", "TPCBach", "TOFBach", "proplifetime", "rejcomp", "ptthrtof", "bachBaryonCosPA", "bachBaryonDCAxyToPV", "NTPCrows", "TrackQuality", "rCascMax", "rV0Max"}; registry.add("hCandidate", "hCandidate", HistType::kTH1F, {{26, -0.5, 25.5}}); for (Int_t n = 1; n <= registry.get(HIST("hCandidate"))->GetNbinsX(); n++) { @@ -242,6 +296,14 @@ struct LfCascpostprocessing { registry.add("hMisidentifiedCascPdgCode", "hMisidentifiedCascPdgCode", {HistType::kTH1F, {pdgCodeAxis}}); registry.add("hMisidentifiedCascMinusPdgCode", "hMisidentifiedCascMinusPdgCode", {HistType::kTH1F, {pdgCodeAxis}}); registry.add("hMisidentifiedCascPlusPdgCode", "hMisidentifiedCascPlusPdgCode", {HistType::kTH1F, {pdgCodeAxis}}); + registry.add("hMisidentifiedCascParticle", "hMisidentifiedCascParticle", {HistType::kTH1F, {misidentifiedParticleAxis}}); + registry.add("hMisidentifiedCascMinusParticle", "hMisidentifiedCascMinusParticle", {HistType::kTH1F, {misidentifiedParticleAxis}}); + registry.add("hMisidentifiedCascPlusParticle", "hMisidentifiedCascPlusParticle", {HistType::kTH1F, {misidentifiedParticleAxis}}); + registry.add("hMisidentifiedCascParticleVsPt", "hMisidentifiedCascParticleVsPt", {HistType::kTH2F, {ptAxis, misidentifiedParticleAxis}}); + setMisidentifiedParticleLabels(registry.get(HIST("hMisidentifiedCascParticle"))->GetXaxis()); + setMisidentifiedParticleLabels(registry.get(HIST("hMisidentifiedCascMinusParticle"))->GetXaxis()); + setMisidentifiedParticleLabels(registry.get(HIST("hMisidentifiedCascPlusParticle"))->GetXaxis()); + setMisidentifiedParticleLabels(registry.get(HIST("hMisidentifiedCascParticleVsPt"))->GetYaxis()); registry.add("hPtXiPlusTrue", "hPtXiPlusTrue", {HistType::kTH3F, {ptAxis, rapidityAxis, centFT0MAxis}}); registry.add("hPtXiMinusTrue", "hPtXiMinusTrue", {HistType::kTH3F, {ptAxis, rapidityAxis, centFT0MAxis}}); registry.add("hPtOmegaPlusTrue", "hPtOmegaPlusTrue", {HistType::kTH3F, {ptAxis, rapidityAxis, centFT0MAxis}}); @@ -433,14 +495,19 @@ struct LfCascpostprocessing { registry.fill(HIST("hCandidate"), ++counter); bool kHasTOF = (candidate.poshastof() || candidate.neghastof() || candidate.bachhastof()); bool kHasITS = ((candidate.positshits() > 1) || (candidate.negitshits() > 1) || (candidate.bachitshits() > 1)); + bool kPassMinITS = ((candidate.positshits() >= trackQualityMinITS) || (candidate.negitshits() >= trackQualityMinITS) || (candidate.bachitshits() >= trackQualityMinITS)); if (dooobrej == 1) { if (!kHasTOF && !kHasITS) continue; registry.fill(HIST("hCandidate"), ++counter); - } else if (dooobrej == OobRejTofOnly) { + } else if (dooobrej == TrackQualityTofHighPt) { if (!kHasTOF && (candidate.pt() > ptthrtof)) continue; registry.fill(HIST("hCandidate"), ++counter); + } else if (dooobrej == TrackQualityMinITS) { + if (!kPassMinITS) + continue; + registry.fill(HIST("hCandidate"), ++counter); } else { ++counter; } @@ -519,11 +586,16 @@ struct LfCascpostprocessing { // registry.fill(HIST("hBachITSHits"), candidate.bachitshits()); if (isMC && !isCorrectlyRec) { + const int misidentifiedParticleBin = getMisidentifiedParticleBin(candidate.mcPdgCode()); registry.fill(HIST("hMisidentifiedCascPdgCode"), candidate.mcPdgCode()); + registry.fill(HIST("hMisidentifiedCascParticle"), misidentifiedParticleBin); + registry.fill(HIST("hMisidentifiedCascParticleVsPt"), candidate.pt(), misidentifiedParticleBin); if (candidate.sign() < 0) { registry.fill(HIST("hMisidentifiedCascMinusPdgCode"), candidate.mcPdgCode()); + registry.fill(HIST("hMisidentifiedCascMinusParticle"), misidentifiedParticleBin); } else if (candidate.sign() > 0) { registry.fill(HIST("hMisidentifiedCascPlusPdgCode"), candidate.mcPdgCode()); + registry.fill(HIST("hMisidentifiedCascPlusParticle"), misidentifiedParticleBin); } } diff --git a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx index f0f141e01d6..177c3c29d01 100644 --- a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx +++ b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx @@ -126,6 +126,8 @@ struct HStrangeCorrelation { Configurable applyNewMCSelection{"applyNewMCSelection", false, "apply new MC Generated selection"}; Configurable doSeparateFT0Prediction{"doSeparateFT0Prediction", false, "separate FT0M to FT0A and FT0C in prediction process"}; Configurable useCentralityinPrediction{"useCentralityinPrediction", false, "if true, use centrality instead of multiplisity"}; + Configurable doMirroringInDelataEta{"doMirroringInDelataEta", false, "if true, fill only positive delta eta and mirror the negative side in post processing, Adjust the delta axis!"}; + Configurable fillCorrelationHistWithMass{"fillCorrelationHistWithMass", false, "if true, fill correlation histograms with particle mass"}; } masterConfigurations; // master analysis switches @@ -160,6 +162,8 @@ struct HStrangeCorrelation { ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.0, 1.0, 2.0, 3.0, 100}, "pt associated axis for histograms"}; ConfigurableAxis axisPtQA{"axisPtQA", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for QA histograms"}; ConfigurableAxis axisMassNSigma{"axisMassNSigma", {40, -2, 2}, "Axis for mass Nsigma"}; + ConfigurableAxis axisK0ShortMass{"axisK0ShortMass", {200, 0.400f, 0.600f}, "Inv. Mass (GeV/c^{2})"}; + ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.01f, 1.21f}, "Inv. Mass (GeV/c^{2})"}; ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 20, 40, 60, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300}, "Binning of the Multiplicity axis in model prediction process"}; ConfigurableAxis axisMidrapidityMultiplicity{"axisMidrapidityMultiplicity", {VARIABLE_WIDTH, 0, 20, 40, 60, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300}, "Binning of the Midrapidity Multiplicity axis in model prediction process"}; @@ -204,6 +208,7 @@ struct HStrangeCorrelation { Configurable checksRequireTPCChi2{"checksRequireTPCChi2", false, "require TPC chi2 per cluster for trigger and associated primary tracks"}; Configurable requireClusterInITS{"requireClusterInITS", false, "require cluster in ITS for V0 and cascade daughter tracks"}; Configurable minITSClustersForDaughterTracks{"minITSClustersForDaughterTracks", 1, "Minimum number of ITS clusters for V0 daughter tracks"}; + Configurable requireDCAzCut{"requireDCAzCut", false, "require DCAz cut for trigger and associated primary tracks"}; // --- Trigger: DCA variation from basic formula: |DCAxy| < 0.004f + (0.013f / pt) Configurable dcaXYconstant{"dcaXYconstant", 0.004, "[0] in |DCAxy| < [0]+[1]/pT"}; @@ -211,6 +216,11 @@ struct HStrangeCorrelation { // --- Assoc track: DCA variation from basic formula: |DCAxy| < 0.004f + (0.013f / pt) Configurable dcaXYconstantAssoc{"dcaXYconstantAssoc", 0.004, "[0] in |DCAxy| < [0]+[1]/pT"}; Configurable dcaXYpTdepAssoc{"dcaXYpTdepAssoc", 0.013, "[1] in |DCAxy| < [0]+[1]/pT"}; + + Configurable dcaZconstant{"dcaZconstant", 0.004, "[0] in |DCAz| < [0]+[1]/pT"}; + Configurable dcaZpTdep{"dcaZpTdep", 0.013, "[1] in |DCAz| < [0]+[1]/pT"}; + Configurable dcaZconstantAssoc{"dcaZconstantAssoc", 0.004, "[0] in |DCAz| < [0]+[1]/pT"}; + Configurable dcaZpTdepAssoc{"dcaZpTdepAssoc", 0.013, "[1] in |DCAz| < [0]+[1]/pT"}; Configurable dEdxCompatibility{"dEdxCompatibility", 1, "0: loose, 1: normal, 2: tight. Defined in HStrangeCorrelationFilter"}; } trackSelection; struct : ConfigurableGroup { @@ -225,6 +235,7 @@ struct HStrangeCorrelation { Configurable v0RadiusMax{"v0RadiusMax", 200, "v0radius"}; Configurable dcaBaryonToPV{"dcaBaryonToPV", 0.2, "DCA of baryon daughter track To PV"}; Configurable dcaMesonToPV{"dcaMesonToPV", 0.05, "DCA of meson daughter track To PV"}; + Configurable dcaDaugToPVForK0s{"dcaDaugToPVForK0s", 0, "DCA of K0s daughter tracks To PV"}; Configurable lifetimecutK0S{"lifetimecutK0S", 20, "lifetimecutK0S"}; Configurable lifetimecutLambda{"lifetimecutLambda", 30, "lifetimecutLambda"}; // original equation: lArmPt*2>TMath::Abs(lArmAlpha) only for K0S @@ -481,7 +492,8 @@ struct HStrangeCorrelation { if (v0.distovertotmom(pvx, pvy, pvz) * o2::constants::physics::MassK0Short < v0Selection.lifetimecutK0S) SETBIT(bitMap, 0); // DCA daughter to prim.vtx and armenteros - if (std::abs(v0.dcapostopv()) > v0Selection.dcaMesonToPV && std::abs(v0.dcanegtopv()) > v0Selection.dcaMesonToPV && v0.qtarm() * v0Selection.armPodCut > std::abs(v0.alpha())) + float dcaCut = v0Selection.dcaDaugToPVForK0s == 0 ? v0Selection.dcaMesonToPV : v0Selection.dcaDaugToPVForK0s; + if (std::abs(v0.dcapostopv()) > dcaCut && std::abs(v0.dcanegtopv()) > dcaCut && v0.qtarm() * v0Selection.armPodCut > std::abs(v0.alpha())) SETBIT(bitMap, 3); } if (masterConfigurations.doCorrelationLambda) { @@ -594,6 +606,10 @@ struct HStrangeCorrelation { if (std::abs(track.dcaXY()) > trackSelection.dcaXYconstant + trackSelection.dcaXYpTdep * std::abs(track.signed1Pt())) { return false; } + // systematic variations: trigger DCAz + if (trackSelection.requireDCAzCut && std::abs(track.dcaZ()) > trackSelection.dcaZconstant + trackSelection.dcaZpTdep * std::abs(track.signed1Pt())) { + return false; + } if (track.pt() > axisRanges[3][1] || track.pt() < axisRanges[3][0]) { return false; } @@ -627,6 +643,10 @@ struct HStrangeCorrelation { if (std::abs(track.dcaXY()) > trackSelection.dcaXYconstantAssoc + trackSelection.dcaXYpTdepAssoc * std::abs(track.signed1Pt())) { return false; } + // systematic variations: trigger DCAz + if (trackSelection.requireDCAzCut && std::abs(track.dcaZ()) > trackSelection.dcaZconstantAssoc + trackSelection.dcaZpTdepAssoc * std::abs(track.signed1Pt())) { + return false; + } if (track.pt() > axisRanges[2][1] || track.pt() < axisRanges[2][0]) { return false; } @@ -808,16 +828,14 @@ struct HStrangeCorrelation { //---] removing autocorrelations [--- auto postrack = assoc.posTrack_as(); auto negtrack = assoc.negTrack_as(); - if (!mixingInBf) { - if (doAutocorrelationRejection) { - if (trigg.globalIndex() == postrack.globalIndex()) { - histos.fill(HIST("hNumberOfRejectedPairsV0"), 0.5); - continue; - } - if (trigg.globalIndex() == negtrack.globalIndex()) { - histos.fill(HIST("hNumberOfRejectedPairsV0"), 0.5); - continue; - } + if (doAutocorrelationRejection) { + if (trigg.globalIndex() == postrack.globalIndex()) { + histos.fill(HIST("hNumberOfRejectedPairsV0"), 0.5); + continue; + } + if (trigg.globalIndex() == negtrack.globalIndex()) { + histos.fill(HIST("hNumberOfRejectedPairsV0"), 0.5); + continue; } } @@ -831,6 +849,9 @@ struct HStrangeCorrelation { float deltaphi = computeDeltaPhi(trigg.phi(), assoc.phi()); float deltaeta = trigg.eta() - assoc.eta(); + if (masterConfigurations.doMirroringInDelataEta) { + deltaeta = std::abs(deltaeta); + } float ptassoc = assoc.pt(); float pttrigger = trigg.pt(); @@ -905,9 +926,10 @@ struct HStrangeCorrelation { if (efficiencyFlags.applyEfficiencyPropagation) { totalEffUncert = std::sqrt(std::pow(efficiencyTrigg * efficiencyError, 2) + std::pow(efficiencyTriggError * efficiency, 2)); } + double binFillThn[6] = {deltaphi, deltaeta, ptassoc, pttrigger, pvz, mult}; if (TESTBIT(doCorrelation, Index) && (!efficiencyFlags.applyEfficiencyCorrection || efficiency != 0) && (masterConfigurations.doPPAnalysis || (TESTBIT(selMap, Index) && TESTBIT(selMap, Index + 3)))) { - if (assocCandidate.compatible(Index, trackSelection.dEdxCompatibility) && (!masterConfigurations.doMCassociation || assocCandidate.mcTrue(Index)) && (!doAssocPhysicalPrimary || assocCandidate.mcPhysicalPrimary()) && !mixing && -massWindowConfigurations.maxBgNSigma < assocCandidate.invMassNSigma(Index) && assocCandidate.invMassNSigma(Index) < -massWindowConfigurations.minBgNSigma) { + if (assocCandidate.compatible(Index, trackSelection.dEdxCompatibility) && (!masterConfigurations.doMCassociation || assocCandidate.mcTrue(Index)) && (!doAssocPhysicalPrimary || assocCandidate.mcPhysicalPrimary()) && !mixing && -massWindowConfigurations.maxBgNSigma < assocCandidate.invMassNSigma(Index) && assocCandidate.invMassNSigma(Index) < -massWindowConfigurations.minBgNSigma && !masterConfigurations.fillCorrelationHistWithMass) { fillCorrelationHistogram(histos.get(HIST("sameEvent/LeftBg/") + HIST(V0names[Index])), binFillThn, etaWeight, efficiency * efficiencyTrigg, totalEffUncert, purityTrigg, purityTriggErr); if (doDeltaPhiStarCheck) { double deltaPhiStar = calculateAverageDeltaPhiStar(triggForDeltaPhiStar, assocForDeltaPhiStar, bField); @@ -925,7 +947,22 @@ struct HStrangeCorrelation { } } } - if (assocCandidate.compatible(Index, trackSelection.dEdxCompatibility) && (!masterConfigurations.doMCassociation || assocCandidate.mcTrue(Index)) && (!doAssocPhysicalPrimary || assocCandidate.mcPhysicalPrimary()) && !mixing && -massWindowConfigurations.maxPeakNSigma < assocCandidate.invMassNSigma(Index) && assocCandidate.invMassNSigma(Index) < +massWindowConfigurations.maxPeakNSigma) { + if (assocCandidate.compatible(Index, trackSelection.dEdxCompatibility) && (!masterConfigurations.doMCassociation || assocCandidate.mcTrue(Index)) && (!doAssocPhysicalPrimary || assocCandidate.mcPhysicalPrimary()) && !mixing && (masterConfigurations.fillCorrelationHistWithMass || (-massWindowConfigurations.maxPeakNSigma < assocCandidate.invMassNSigma(Index) && assocCandidate.invMassNSigma(Index) < +massWindowConfigurations.maxPeakNSigma))) { + if (masterConfigurations.fillCorrelationHistWithMass) { + float massAssoc = 0.f; + switch (i) { + case 0: + massAssoc = assoc.mK0Short(); + break; + case 1: + massAssoc = assoc.mLambda(); + break; + case 2: + massAssoc = assoc.mAntiLambda(); + break; + } + binFillThn[1] = massAssoc; + } fillCorrelationHistogram(histos.get(HIST("sameEvent/Signal/") + HIST(V0names[Index])), binFillThn, etaWeight, efficiency * efficiencyTrigg, totalEffUncert, purityTrigg, purityTriggErr); if (std::abs(deltaphi) < checks.towardDeltaEtaRange && doITSClustersQA) { histos.fill(HIST("hITSClusters") + HIST(V0names[Index]) + HIST("NegativeDaughterToward"), ptassoc, negtrack.itsNCls(), assoc.v0radius()); @@ -951,7 +988,7 @@ struct HStrangeCorrelation { } } } - if (assocCandidate.compatible(Index, trackSelection.dEdxCompatibility) && (!masterConfigurations.doMCassociation || assocCandidate.mcTrue(Index)) && (!doAssocPhysicalPrimary || assocCandidate.mcPhysicalPrimary()) && !mixing && +massWindowConfigurations.minBgNSigma < assocCandidate.invMassNSigma(Index) && assocCandidate.invMassNSigma(Index) < +massWindowConfigurations.maxBgNSigma) { + if (assocCandidate.compatible(Index, trackSelection.dEdxCompatibility) && (!masterConfigurations.doMCassociation || assocCandidate.mcTrue(Index)) && (!doAssocPhysicalPrimary || assocCandidate.mcPhysicalPrimary()) && !mixing && +massWindowConfigurations.minBgNSigma < assocCandidate.invMassNSigma(Index) && assocCandidate.invMassNSigma(Index) < +massWindowConfigurations.maxBgNSigma && !masterConfigurations.fillCorrelationHistWithMass) { fillCorrelationHistogram(histos.get(HIST("sameEvent/RightBg/") + HIST(V0names[Index])), binFillThn, etaWeight, efficiency * efficiencyTrigg, totalEffUncert, purityTrigg, purityTriggErr); if (doDeltaPhiStarCheck) { double deltaPhiStar = calculateAverageDeltaPhiStar(triggForDeltaPhiStar, assocForDeltaPhiStar, bField); @@ -1006,7 +1043,7 @@ struct HStrangeCorrelation { for (const auto& collision : validCollisions[binnumb]) { BinningTypePP colBinning{{axesConfigurations.axisVtxZ, axesConfigurations.axisMult}, true}; // When 'collisionHasTriggOrAssoc' = 0: - // binContent(hMECollisionBins) = Σ(RunNumbers)[binContent(the same bin of hSECollisionBins) * masterConfigurations.mixingParameter - Σ(k=0 to min(masterConfigurations.mixingParameter,binContent)) k] + // binContent(hMECollisionBins) = Σ(Submitted jobs(done))[binContent(the same bin of hSECollisionBins) * masterConfigurations.mixingParameter - Σ(k=0 to min(masterConfigurations.mixingParameter,binContent)) k] // When 'collisionHasTriggOrAssoc' = 3 // More collision loss at higher peripheral centrality (fewer target particles); higher bincontent of HIST("mixedEvent/Signal/") + HIST(Cascadenames[Index]) // due to avoiding vector occupancy by collisions with no trigger&associated particles @@ -1025,6 +1062,9 @@ struct HStrangeCorrelation { if (efficiencyFlags.applyEfficiencyPropagation) { totalEffUncert = std::sqrt(std::pow(efficiencyTrigg * efficiencyAssocError, 2) + std::pow(efficiencyTriggError * efficiencyAssoc, 2)); } + if (masterConfigurations.doMirroringInDelataEta) { + deltaeta = std::abs(deltaeta); + } double binFillThn[6] = {deltaphi, deltaeta, ptassoc, pttrigger, pvz, mult}; static_for<0, 2>([&](auto i) { constexpr int Index = i.value; @@ -1044,7 +1084,8 @@ struct HStrangeCorrelation { if (validCollisions[binnumb].size() >= static_cast(masterConfigurations.mixingParameter)) { validCollisions[binnumb].erase(validCollisions[binnumb].begin()); } - validCollisions[binnumb].push_back(currentCollision); + if (!currentCollision.trigParticles.empty()) + validCollisions[binnumb].push_back(currentCollision); } void fillCorrelationsCascade(aod::TriggerTracks const& triggers, aod::AssocCascades const& assocs, bool mixing, bool mixingInBf, float pvx, float pvy, float pvz, float mult, double bField) @@ -1142,22 +1183,21 @@ struct HStrangeCorrelation { auto postrack = assoc.posTrack_as(); auto negtrack = assoc.negTrack_as(); auto bachtrack = assoc.bachelor_as(); - if (!mixingInBf) { - if (doAutocorrelationRejection) { - if (trigg.globalIndex() == postrack.globalIndex()) { - histos.fill(HIST("hNumberOfRejectedPairsCascades"), 0.5); - continue; - } - if (trigg.globalIndex() == negtrack.globalIndex()) { - histos.fill(HIST("hNumberOfRejectedPairsCascades"), 0.5); - continue; - } - if (trigg.globalIndex() == bachtrack.globalIndex()) { - histos.fill(HIST("hNumberOfRejectedPairsCascades"), 0.5); - continue; - } + if (doAutocorrelationRejection) { + if (trigg.globalIndex() == postrack.globalIndex()) { + histos.fill(HIST("hNumberOfRejectedPairsCascades"), 0.5); + continue; + } + if (trigg.globalIndex() == negtrack.globalIndex()) { + histos.fill(HIST("hNumberOfRejectedPairsCascades"), 0.5); + continue; + } + if (trigg.globalIndex() == bachtrack.globalIndex()) { + histos.fill(HIST("hNumberOfRejectedPairsCascades"), 0.5); + continue; } } + double phiProton = postrack.phi(); double etaProton = postrack.eta(); double ptProton = postrack.pt(); @@ -1179,6 +1219,9 @@ struct HStrangeCorrelation { float deltaphi = computeDeltaPhi(trigg.phi(), assoc.phi()); float deltaeta = trigg.eta() - assoc.eta(); + if (masterConfigurations.doMirroringInDelataEta) { + deltaeta = std::abs(deltaeta); + } float ptassoc = assoc.pt(); float pttrigger = trigg.pt(); @@ -1243,6 +1286,7 @@ struct HStrangeCorrelation { if (efficiencyFlags.applyEfficiencyPropagation) { totalEffUncert = std::sqrt(std::pow(efficiencyTrigg * efficiencyError, 2) + std::pow(efficiencyTriggError * efficiency, 2)); } + double binFillThn[6] = {deltaphi, deltaeta, ptassoc, pttrigger, pvz, mult}; if (TESTBIT(doCorrelation, Index + 3) && (!efficiencyFlags.applyEfficiencyCorrection || efficiency != 0) && (masterConfigurations.doPPAnalysis || (TESTBIT(cascselMap, Index) && TESTBIT(cascselMap, Index + 4) && TESTBIT(cascselMap, Index + 8) && TESTBIT(cascselMap, Index + 12)))) { if (assocCandidate.compatible(Index, trackSelection.dEdxCompatibility) && (!masterConfigurations.doMCassociation || assocCandidate.mcTrue(Index)) && (!doAssocPhysicalPrimary || assocCandidate.mcPhysicalPrimary()) && !mixing && -massWindowConfigurations.maxBgNSigma < assocCandidate.invMassNSigma(Index) && assocCandidate.invMassNSigma(Index) < -massWindowConfigurations.minBgNSigma) { @@ -1326,6 +1370,9 @@ struct HStrangeCorrelation { if (efficiencyFlags.applyEfficiencyPropagation) { totalEffUncert = std::sqrt(std::pow(efficiencyTrigg * efficiencyAssocError, 2) + std::pow(efficiencyTriggError * efficiencyAssoc, 2)); } + if (masterConfigurations.doMirroringInDelataEta) { + deltaeta = std::abs(deltaeta); + } double binFillThn[6] = {deltaphi, deltaeta, ptassoc, pttrigger, pvz, mult}; static_for<0, 3>([&](auto i) { constexpr int Index = i.value; @@ -1345,7 +1392,8 @@ struct HStrangeCorrelation { if (validCollisions[binnumb].size() >= static_cast(masterConfigurations.mixingParameter)) { validCollisions[binnumb].erase(validCollisions[binnumb].begin()); } - validCollisions[binnumb].push_back(currentCollision); + if (!currentCollision.trigParticles.empty()) + validCollisions[binnumb].push_back(currentCollision); } template void fillCorrelationsHadron(TTriggers const& triggers, THadrons const& assocs, bool mixing, float pvz, float mult, double bField) @@ -1419,6 +1467,9 @@ struct HStrangeCorrelation { } float deltaphi = computeDeltaPhi(trigg.phi(), assoc.phi()); float deltaeta = trigg.eta() - assoc.eta(); + if (masterConfigurations.doMirroringInDelataEta) { + deltaeta = std::abs(deltaeta); + } float ptassoc = assoc.pt(); float pttrigger = trigg.pt(); @@ -1483,6 +1534,7 @@ struct HStrangeCorrelation { totalEffUncert = std::sqrt(std::pow(efficiencyTrigger * efficiencyUncertainty, 2) + std::pow(efficiencyTriggerError * efficiency, 2)); totalPurityUncert = std::sqrt(std::pow(purityTrigger * purityUncertainty, 2) + std::pow(purity * purityTriggerError, 2)); } + double binFillThn[6] = {deltaphi, deltaeta, ptassoc, pttrigger, pvz, mult}; double deltaPhiStar = calculateAverageDeltaPhiStar(triggForDeltaPhiStar, assocForDeltaPhiStar, bField); if (!mixing) { @@ -1742,7 +1794,7 @@ struct HStrangeCorrelation { if (!masterConfigurations.doPPAnalysis) { // event selections in Pb-Pb histos.add("hEventSelection", "hEventSelection", kTH1F, {{10, 0, 10}}); - TString eventSelLabel[] = {"all", "sel8", "kIsTriggerTVX", "PV_{z}", "kIsGoodITSLayersAll", "kIsGoodZvtxFT0vsPV", "OccupCut", "kNoITSROFrameBorder", "kNoSameBunchPileup ", " kNoCollInTimeRangeStandard"}; + TString eventSelLabel[] = {"all", "sel8", "kIsTriggerTVX", "PV_{z}", "kIsGoodITSLayersAll", "kIsGoodZvtxFT0vsPV", "OccupCut", "kNoTimeFrameBorder", "kNoITSROFrameBorder", "kNoSameBunchPileup "}; for (int i = 1; i <= histos.get(HIST("hEventSelection"))->GetNbinsX(); i++) { histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(i, eventSelLabel[i - 1]); } @@ -1804,11 +1856,16 @@ struct HStrangeCorrelation { histos.add("EventQA/hPvz", ";pvz;Entries", kTH1F, {{30, -15, 15}}); histos.add("EventQA/hMultFT0vsTPC", ";centFT0M;multNTracksPVeta1", kTH2F, {{100, 0, 100}, {300, 0, 300}}); } + if (masterConfigurations.doFullCorrelationStudy && masterConfigurations.fillCorrelationHistWithMass) { + histos.add("sameEvent/Signal/K0Short", "", kTHnF, {axisDeltaPhiNDim, axesConfigurations.axisK0ShortMass, axisPtAssocNDim, axisPtTriggerNDim, axisVtxZNDim, axisMultNDim}); + histos.add("sameEvent/Signal/Lambda", "", kTHnF, {axisDeltaPhiNDim, axesConfigurations.axisLambdaMass, axisPtAssocNDim, axisPtTriggerNDim, axisVtxZNDim, axisMultNDim}); + histos.add("sameEvent/Signal/AntiLambda", "", kTHnF, {axisDeltaPhiNDim, axesConfigurations.axisLambdaMass, axisPtAssocNDim, axisPtTriggerNDim, axisVtxZNDim, axisMultNDim}); + } bool hStrange = false; for (int i = 0; i < AssocParticleTypes; i++) { - if (TESTBIT(doCorrelation, i) && (doprocessSameEventHV0s || doprocessSameEventHCascades)) { - if (masterConfigurations.doFullCorrelationStudy) + if (TESTBIT(doCorrelation, i)) { + if (masterConfigurations.doFullCorrelationStudy && !masterConfigurations.fillCorrelationHistWithMass) histos.add(fmt::format("sameEvent/Signal/{}", Particlenames[i]).c_str(), "", kTHnF, {axisDeltaPhiNDim, axisDeltaEtaNDim, axisPtAssocNDim, axisPtTriggerNDim, axisVtxZNDim, axisMultNDim}); if (doDeltaPhiStarCheck && masterConfigurations.doFullCorrelationStudy) { histos.add(fmt::format("sameEvent/Signal/{}DeltaPhiStar", Particlenames[i]).c_str(), "", kTH3F, {{100, -0.3, 0.3}, {50, -0.05, 0.05}, {2, -1, 1}}); // -1 oposite charge, 1 same charge @@ -1846,7 +1903,7 @@ struct HStrangeCorrelation { histos.add("hAssocPtResolution", ";p_{T}^{reconstructed} (GeV/c); p_{T}^{generated} (GeV/c)", kTH2F, {axesConfigurations.axisPtQA, axesConfigurations.axisPtQA}); } - if (hStrange && masterConfigurations.doFullCorrelationStudy) { + if (hStrange && masterConfigurations.doFullCorrelationStudy && !masterConfigurations.fillCorrelationHistWithMass) { histos.addClone("sameEvent/Signal/", "sameEvent/LeftBg/"); histos.addClone("sameEvent/Signal/", "sameEvent/RightBg/"); } diff --git a/PWGLF/Tasks/Strangeness/lambdapolsp.cxx b/PWGLF/Tasks/Strangeness/lambdapolsp.cxx index 3a44c100cdf..3e0751bfce1 100644 --- a/PWGLF/Tasks/Strangeness/lambdapolsp.cxx +++ b/PWGLF/Tasks/Strangeness/lambdapolsp.cxx @@ -39,15 +39,17 @@ #include #include -#include #include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) #include #include #include +#include #include #include #include +#include + #include #include #include @@ -83,7 +85,6 @@ struct lambdapolsp { struct : ConfigurableGroup { Configurable additionalEvSel{"additionalEvSel", false, "additionalEvSel"}; Configurable additionalEvSel2{"additionalEvSel2", false, "additionalEvSel2"}; - Configurable additionalEvSel3{"additionalEvSel3", false, "additionalEvSel3"}; Configurable additionalEvSel4{"additionalEvSel4", false, "additionalEvSel4"}; Configurable cfgMaxOccupancy{"cfgMaxOccupancy", 1000, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; Configurable cfgMinOccupancy{"cfgMinOccupancy", 0, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; @@ -92,10 +93,9 @@ struct lambdapolsp { Configurable cqvas{"cqvas", false, "change q vectors after shift correction"}; Configurable normbymag{"normbymag", false, "normalize by magnitude of q vectors for SP"}; Configurable useprofile{"useprofile", 3, "flag to select profile vs Sparse"}; - Configurable sys{"sys", 1, "flag to select systematic source"}; Configurable centestim{"centestim", 0, "flag to select centrality estimator"}; - Configurable dosystematic{"dosystematic", false, "flag to perform systematic study"}; Configurable needetaaxis{"needetaaxis", false, "flag to use last axis"}; + struct : ConfigurableGroup { Configurable doRandomPsi{"doRandomPsi", true, "randomize psi"}; Configurable doRandomPsiAC{"doRandomPsiAC", true, "randomize psiAC"}; @@ -170,18 +170,7 @@ struct lambdapolsp { Configurable spNbins{"spNbins", 2000, "Number of bins in sp"}; Configurable lbinsp{"lbinsp", -1.0, "lower bin value in sp histograms"}; Configurable hbinsp{"hbinsp", 1.0, "higher bin value in sp histograms"}; - // Configurable CentNbins{"CentNbins", 16, "Number of bins in cent histograms"}; - // Configurable lbinCent{"lbinCent", 0.0, "lower bin value in cent histograms"}; - // Configurable hbinCent{"hbinCent", 80.0, "higher bin value in cent histograms"}; } binGrp; - /* - ConfigurableAxis configcentAxis{"configcentAxis", {VARIABLE_WIDTH, 0.0, 10.0, 40.0, 80.0}, "Cent V0M"}; - ConfigurableAxis configthnAxispT{"configthnAxisPt", {VARIABLE_WIDTH, 0.2, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.5, 8.0, 10.0, 100.0}, "#it{p}_{T} (GeV/#it{c})"}; - ConfigurableAxis configetaAxis{"configetaAxis", {VARIABLE_WIDTH, -0.8, -0.4, -0.2, 0, 0.2, 0.4, 0.8}, "Eta"}; - ConfigurableAxis configthnAxisPol{"configthnAxisPol", {VARIABLE_WIDTH, -1.0, -0.6, -0.2, 0, 0.2, 0.4, 0.8}, "Pol"}; - ConfigurableAxis configbinAxis{"configbinAxis", {VARIABLE_WIDTH, -0.8, -0.4, -0.2, 0, 0.2, 0.4, 0.8}, "BA"}; - */ - // ConfigurableAxis configphiAxis{"configphiAxis", {VARIABLE_WIDTH, 0.0, 0.2, 0.4, 0.8, 1.0, 2.0, 2.5, 3.0, 4.0, 5.0, 5.5, 6.28}, "PhiAxis"}; struct : ConfigurableGroup { Configurable isQA{"isQA", true, "Flag to fill QA"}; @@ -191,7 +180,17 @@ struct lambdapolsp { ConfigurableAxis vzfineAxis{"vzfineAxis", {VARIABLE_WIDTH, 0.0, 10.0, 40.0, 80.0}, "vz fine axis"}; ConfigurableAxis qxZDCAxis{"qxZDCAxis", {VARIABLE_WIDTH, 0.0, 10.0, 40.0, 80.0}, "qx axis"}; ConfigurableAxis psiAxis{"psiAxis", {VARIABLE_WIDTH, 0.0, 10.0, 40.0, 80.0}, "psi axis"}; + + Configurable fillNUA{"fillNUA", true, "fillNUA"}; + Configurable useNUA{"useNUA", true, "useNUA"}; + ConfigurableAxis nuacentAxis{"nuaCentAxis", {4, 10.f, 50.f}, "centrality (%)"}; + ConfigurableAxis nuavzAxis{"nuaVzAxis", {5, -10.f, 10.f}, "V_{z} (cm)"}; + ConfigurableAxis nuaetaAxis{"nuaEtaAxis", {4, -0.8f, 0.8f}, "#eta"}; + ConfigurableAxis nuasignAxis{"nuaSignAxis", {2, -1.5f, 1.5f}, "charge sign"}; + ConfigurableAxis nuaphiAxis{"nuaPhiAxis", {72, 0.f, static_cast(TMath::TwoPi())}, "#varphi"}; + Configurable ConfNUA{"ConfNUA", "Users/p/prottay/My/Object/NUAwgtschk", "Path to NUA"}; } QAgrp; + struct : ConfigurableGroup { Configurable requireRCTFlagChecker{"requireRCTFlagChecker", true, "Check event quality in run condition table"}; Configurable cfgEvtRCTFlagCheckerLabel{"cfgEvtRCTFlagCheckerLabel", "CBT_hadronPID", "Evt sel: RCT flag checker label"}; @@ -258,7 +257,7 @@ struct lambdapolsp { histos.add("hpuxyQxypvscentpteta", "hpuxyQxypvscentpteta", HistType::kTHnSparseF, {axisGrp.configcentAxis, axisGrp.configthnAxispT, axisGrp.configetaAxis, spAxis}, true); histos.add("hpoddv1vscentpteta", "hpoddv1vscentpteta", HistType::kTHnSparseF, {axisGrp.configcentAxis, axisGrp.configthnAxispT, axisGrp.configetaAxis, spAxis}, true); histos.add("hpevenv1vscentpteta", "hpevenv1vscentpteta", HistType::kTHnSparseF, {axisGrp.configcentAxis, axisGrp.configthnAxispT, axisGrp.configetaAxis, spAxis}, true); - histos.add("hpv21", "hpv21", HistType::kTHnSparseF, {axisGrp.configcentAxis, axisGrp.configthnAxispT, axisGrp.configetaAxis, spAxis}, true); + /*histos.add("hpv21", "hpv21", HistType::kTHnSparseF, {axisGrp.configcentAxis, axisGrp.configthnAxispT, axisGrp.configetaAxis, spAxis}, true); histos.add("hpv22", "hpv22", HistType::kTHnSparseF, {axisGrp.configcentAxis, axisGrp.configthnAxispT, axisGrp.configetaAxis, spAxis}, true); histos.add("hpv23", "hpv23", HistType::kTHnSparseF, {axisGrp.configcentAxis, axisGrp.configthnAxispT, axisGrp.configetaAxis, spAxis}, true); histos.add("hpx2Tx1Ax1Cvscentpteta", "hpx2Tx1Ax1Cvscentpteta", HistType::kTHnSparseF, {axisGrp.configcentAxis, axisGrp.configthnAxispT, axisGrp.configetaAxis, spAxis}, true); @@ -284,7 +283,7 @@ struct lambdapolsp { histos.add("hpy1Ax1Cvscentpteta", "hpy1Ax1Cvscentpteta", HistType::kTHnSparseF, {axisGrp.configcentAxis, axisGrp.configthnAxispT, axisGrp.configetaAxis, spAxis}, true); histos.add("hpx2Tvscentpteta", "hpx2Tvscentpteta", HistType::kTHnSparseF, {axisGrp.configcentAxis, axisGrp.configthnAxispT, axisGrp.configetaAxis, spAxis}, true); histos.add("hpy2Tvscentpteta", "hpy2Tvscentpteta", HistType::kTHnSparseF, {axisGrp.configcentAxis, axisGrp.configthnAxispT, axisGrp.configetaAxis, spAxis}, true); - + */ histos.add("hpuxvscentpteta", "hpuxvscentpteta", HistType::kTHnSparseF, {axisGrp.configcentAxis, axisGrp.configthnAxispT, axisGrp.configetaAxis, spAxis}, true); histos.add("hpuyvscentpteta", "hpuyvscentpteta", HistType::kTHnSparseF, {axisGrp.configcentAxis, axisGrp.configthnAxispT, axisGrp.configetaAxis, spAxis}, true); /* @@ -494,6 +493,10 @@ struct lambdapolsp { histos.add("PsiZDC", "PsiZDC", kTH2F, {QAgrp.centfineAxis, QAgrp.psiAxis}); } + if (QAgrp.fillNUA) { + histos.add("hNUA", "hNUA", HistType::kTHnSparseF, {QAgrp.nuacentAxis, QAgrp.nuavzAxis, QAgrp.nuaetaAxis, QAgrp.nuasignAxis, QAgrp.nuaphiAxis}); + } + ccdb->setURL(cfgCcdbParam.cfgURL); ccdbApi.init("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); @@ -914,10 +917,9 @@ struct lambdapolsp { } ROOT::Math::PxPyPzMVector Lambda, AntiLambda, Lambdadummy, AntiLambdadummy, Proton, Pion, AntiProton, AntiPion, fourVecDauCM, K0sdummy, K0s; - ROOT::Math::XYZVector threeVecDauCM, threeVecDauCMXY; - double phiangle = 0.0; - // double angleLambda=0.0; - // double angleAntiLambda=0.0; + // double phiangle = 0.0; + // double angleLambda=0.0; + // double angleAntiLambda=0.0; double massLambda = o2::constants::physics::MassLambda; double massK0s = o2::constants::physics::MassK0Short; double massPr = o2::constants::physics::MassProton; @@ -935,8 +937,9 @@ struct lambdapolsp { TProfile2D* accprofileL; TProfile2D* accprofileAL; - // int currentRunNumber = -999; - // int lastRunNumber = -999; + int currentRunNumber = -999; + int lastRunNumber = -999; + THnSparseF* hNUAWeights = nullptr; using BCsRun3 = soa::Join; @@ -971,10 +974,6 @@ struct lambdapolsp { return; } // histos.fill(HIST("hCentrality3"), centrality); - if (evselGrp.additionalEvSel3 && (!collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { - return; - } - if (evselGrp.additionalEvSel4 && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { return; } @@ -983,8 +982,8 @@ struct lambdapolsp { return; } - // currentRunNumber = collision.foundBC_as().runNumber(); auto bc = collision.foundBC_as(); + currentRunNumber = collision.foundBC_as().runNumber(); auto vz = collision.vz(); auto vx = collision.vx(); @@ -1100,6 +1099,32 @@ struct lambdapolsp { auto uy = TMath::Sin(GetPhiInRange(track.phi())); // auto py=track.py(); + if (QAgrp.fillNUA) { + histos.fill(HIST("hNUA"), centrality, collision.posZ(), track.eta(), track.sign(), GetPhiInRange(track.phi())); + } + + float wNUA = 1.f; + if (QAgrp.useNUA && (currentRunNumber != lastRunNumber)) { + hNUAWeights = ccdb->getForTimeStamp(QAgrp.ConfNUA.value, bc.timestamp()); + } + + if (QAgrp.useNUA) { + constexpr int kCent = 0; + constexpr int kVz = 1; + constexpr int kEta = 2; + constexpr int kSign = 3; + constexpr int kPhi = 4; + + Int_t nuaBins[5] = { + hNUAWeights->GetAxis(kCent)->FindFixBin(centrality + 0.00001), + hNUAWeights->GetAxis(kVz)->FindFixBin(collision.posZ() + 0.00001), + hNUAWeights->GetAxis(kEta)->FindFixBin(track.eta() + 0.00001), + hNUAWeights->GetAxis(kSign)->FindFixBin(track.sign()), + hNUAWeights->GetAxis(kPhi)->FindFixBin(GetPhiInRange(track.phi()))}; + + wNUA = hNUAWeights->GetBinContent(nuaBins); + } + auto uxQxp = ux * modqxZDCA; auto uyQyp = uy * modqyZDCA; auto uxyQxyp = uxQxp + uyQyp; @@ -1108,7 +1133,7 @@ struct lambdapolsp { auto uxyQxyt = uxQxt + uyQyt; auto oddv1 = ux * (modqxZDCA - modqxZDCC) + uy * (modqyZDCA - modqyZDCC); auto evenv1 = ux * (modqxZDCA + modqxZDCC) + uy * (modqyZDCA + modqyZDCC); - auto v21 = TMath::Cos(2 * (GetPhiInRange(track.phi()) - psiZDCA - psiZDCC)); + /*auto v21 = TMath::Cos(2 * (GetPhiInRange(track.phi()) - psiZDCA - psiZDCC)); auto v22 = TMath::Cos(2 * (GetPhiInRange(track.phi()) + psiZDCA - psiZDCC)); auto v23 = TMath::Cos(2 * (GetPhiInRange(track.phi()) - psiZDC)); @@ -1135,77 +1160,77 @@ struct lambdapolsp { auto y2Tx1A = TMath::Sin(2 * GetPhiInRange(track.phi())) * modqxZDCA; auto y2Tx1C = TMath::Sin(2 * GetPhiInRange(track.phi())) * modqxZDCC; auto y2Ty1A = TMath::Sin(2 * GetPhiInRange(track.phi())) * modqyZDCA; - auto y2Ty1C = TMath::Sin(2 * GetPhiInRange(track.phi())) * modqyZDCC; + auto y2Ty1C = TMath::Sin(2 * GetPhiInRange(track.phi())) * modqyZDCC;*/ if (globalpt) { // if (sign > 0) { - histos.fill(HIST("hpuxQxpvscentpteta"), centrality, track.pt(), track.eta(), uxQxp); - histos.fill(HIST("hpuyQypvscentpteta"), centrality, track.pt(), track.eta(), uyQyp); - histos.fill(HIST("hpuxQxtvscentpteta"), centrality, track.pt(), track.eta(), uxQxt); - histos.fill(HIST("hpuyQytvscentpteta"), centrality, track.pt(), track.eta(), uyQyt); - - histos.fill(HIST("hpuxvscentpteta"), centrality, track.pt(), track.eta(), ux); - histos.fill(HIST("hpuyvscentpteta"), centrality, track.pt(), track.eta(), uy); - - histos.fill(HIST("hpuxyQxytvscentpteta"), centrality, track.pt(), track.eta(), uxyQxyt); - histos.fill(HIST("hpuxyQxypvscentpteta"), centrality, track.pt(), track.eta(), uxyQxyp); - histos.fill(HIST("hpoddv1vscentpteta"), centrality, track.pt(), track.eta(), oddv1); - histos.fill(HIST("hpevenv1vscentpteta"), centrality, track.pt(), track.eta(), evenv1); - - histos.fill(HIST("hpv21"), centrality, track.pt(), track.eta(), v21); - histos.fill(HIST("hpv22"), centrality, track.pt(), track.eta(), v22); - histos.fill(HIST("hpv23"), centrality, track.pt(), track.eta(), v23); - - histos.fill(HIST("hpx2Tx1Ax1Cvscentpteta"), centrality, track.pt(), track.eta(), x2Tx1Ax1C); - histos.fill(HIST("hpx2Ty1Ay1Cvscentpteta"), centrality, track.pt(), track.eta(), x2Ty1Ay1C); - histos.fill(HIST("hpy2Tx1Ay1Cvscentpteta"), centrality, track.pt(), track.eta(), y2Tx1Ay1C); - histos.fill(HIST("hpy2Ty1Ax1Cvscentpteta"), centrality, track.pt(), track.eta(), y2Ty1Ax1C); - histos.fill(HIST("hpx2Tvscentpteta"), centrality, track.pt(), track.eta(), x2T); - histos.fill(HIST("hpy2Tvscentpteta"), centrality, track.pt(), track.eta(), y2T); - histos.fill(HIST("hpx2Tx1Avscentpteta"), centrality, track.pt(), track.eta(), x2Tx1A); - histos.fill(HIST("hpx2Tx1Cvscentpteta"), centrality, track.pt(), track.eta(), x2Tx1C); - histos.fill(HIST("hpx2Ty1Avscentpteta"), centrality, track.pt(), track.eta(), x2Ty1A); - histos.fill(HIST("hpx2Ty1Cvscentpteta"), centrality, track.pt(), track.eta(), x2Ty1C); - histos.fill(HIST("hpy2Tx1Avscentpteta"), centrality, track.pt(), track.eta(), y2Tx1A); - histos.fill(HIST("hpy2Ty1Cvscentpteta"), centrality, track.pt(), track.eta(), y2Ty1C); - histos.fill(HIST("hpy2Ty1Avscentpteta"), centrality, track.pt(), track.eta(), y2Ty1A); - histos.fill(HIST("hpy2Tx1Cvscentpteta"), centrality, track.pt(), track.eta(), y2Tx1C); - histos.fill(HIST("hpx1Ax1Cvscentpteta"), centrality, track.pt(), track.eta(), x1Ax1C); - histos.fill(HIST("hpy1Ay1Cvscentpteta"), centrality, track.pt(), track.eta(), y1Ay1C); - histos.fill(HIST("hpx1Ay1Cvscentpteta"), centrality, track.pt(), track.eta(), x1Ay1C); - histos.fill(HIST("hpy1Ax1Cvscentpteta"), centrality, track.pt(), track.eta(), x1Cy1A); - histos.fill(HIST("hpx1Avscentpteta"), centrality, track.pt(), track.eta(), x1A); - histos.fill(HIST("hpx1Cvscentpteta"), centrality, track.pt(), track.eta(), x1C); - histos.fill(HIST("hpy1Avscentpteta"), centrality, track.pt(), track.eta(), y1A); - histos.fill(HIST("hpy1Cvscentpteta"), centrality, track.pt(), track.eta(), y1C); - + histos.fill(HIST("hpuxQxpvscentpteta"), centrality, track.pt(), track.eta(), uxQxp, wNUA); + histos.fill(HIST("hpuyQypvscentpteta"), centrality, track.pt(), track.eta(), uyQyp, wNUA); + histos.fill(HIST("hpuxQxtvscentpteta"), centrality, track.pt(), track.eta(), uxQxt, wNUA); + histos.fill(HIST("hpuyQytvscentpteta"), centrality, track.pt(), track.eta(), uyQyt, wNUA); + + histos.fill(HIST("hpuxvscentpteta"), centrality, track.pt(), track.eta(), ux, wNUA); + histos.fill(HIST("hpuyvscentpteta"), centrality, track.pt(), track.eta(), uy, wNUA); + + histos.fill(HIST("hpuxyQxytvscentpteta"), centrality, track.pt(), track.eta(), uxyQxyt, wNUA); + histos.fill(HIST("hpuxyQxypvscentpteta"), centrality, track.pt(), track.eta(), uxyQxyp, wNUA); + histos.fill(HIST("hpoddv1vscentpteta"), centrality, track.pt(), track.eta(), oddv1, wNUA); + histos.fill(HIST("hpevenv1vscentpteta"), centrality, track.pt(), track.eta(), evenv1, wNUA); + /* + histos.fill(HIST("hpv21"), centrality, track.pt(), track.eta(), v21,wNUA); + histos.fill(HIST("hpv22"), centrality, track.pt(), track.eta(), v22,wNUA); + histos.fill(HIST("hpv23"), centrality, track.pt(), track.eta(), v23,wNUA); + + histos.fill(HIST("hpx2Tx1Ax1Cvscentpteta"), centrality, track.pt(), track.eta(), x2Tx1Ax1C,wNUA); + histos.fill(HIST("hpx2Ty1Ay1Cvscentpteta"), centrality, track.pt(), track.eta(), x2Ty1Ay1C,wNUA); + histos.fill(HIST("hpy2Tx1Ay1Cvscentpteta"), centrality, track.pt(), track.eta(), y2Tx1Ay1C,wNUA); + histos.fill(HIST("hpy2Ty1Ax1Cvscentpteta"), centrality, track.pt(), track.eta(), y2Ty1Ax1C,wNUA); + histos.fill(HIST("hpx2Tvscentpteta"), centrality, track.pt(), track.eta(), x2T,wNUA); + histos.fill(HIST("hpy2Tvscentpteta"), centrality, track.pt(), track.eta(), y2T,wNUA); + histos.fill(HIST("hpx2Tx1Avscentpteta"), centrality, track.pt(), track.eta(), x2Tx1A,wNUA); + histos.fill(HIST("hpx2Tx1Cvscentpteta"), centrality, track.pt(), track.eta(), x2Tx1C,wNUA); + histos.fill(HIST("hpx2Ty1Avscentpteta"), centrality, track.pt(), track.eta(), x2Ty1A,wNUA); + histos.fill(HIST("hpx2Ty1Cvscentpteta"), centrality, track.pt(), track.eta(), x2Ty1C,wNUA); + histos.fill(HIST("hpy2Tx1Avscentpteta"), centrality, track.pt(), track.eta(), y2Tx1A,wNUA); + histos.fill(HIST("hpy2Ty1Cvscentpteta"), centrality, track.pt(), track.eta(), y2Ty1C,wNUA); + histos.fill(HIST("hpy2Ty1Avscentpteta"), centrality, track.pt(), track.eta(), y2Ty1A,wNUA); + histos.fill(HIST("hpy2Tx1Cvscentpteta"), centrality, track.pt(), track.eta(), y2Tx1C,wNUA); + histos.fill(HIST("hpx1Ax1Cvscentpteta"), centrality, track.pt(), track.eta(), x1Ax1C,wNUA); + histos.fill(HIST("hpy1Ay1Cvscentpteta"), centrality, track.pt(), track.eta(), y1Ay1C,wNUA); + histos.fill(HIST("hpx1Ay1Cvscentpteta"), centrality, track.pt(), track.eta(), x1Ay1C,wNUA); + histos.fill(HIST("hpy1Ax1Cvscentpteta"), centrality, track.pt(), track.eta(), x1Cy1A,wNUA); + histos.fill(HIST("hpx1Avscentpteta"), centrality, track.pt(), track.eta(), x1A,wNUA); + histos.fill(HIST("hpx1Cvscentpteta"), centrality, track.pt(), track.eta(), x1C,wNUA); + histos.fill(HIST("hpy1Avscentpteta"), centrality, track.pt(), track.eta(), y1A,wNUA); + histos.fill(HIST("hpy1Cvscentpteta"), centrality, track.pt(), track.eta(), y1C,wNUA); + */ /*} else { - histos.fill(HIST("hpuxQxpvscentptetaneg"), centrality, track.pt(), track.eta(), uxQxp); - histos.fill(HIST("hpuyQypvscentptetaneg"), centrality, track.pt(), track.eta(), uyQyp); - histos.fill(HIST("hpuxQxtvscentptetaneg"), centrality, track.pt(), track.eta(), uxQxt); - histos.fill(HIST("hpuyQytvscentptetaneg"), centrality, track.pt(), track.eta(), uyQyt); - - histos.fill(HIST("hpuxvscentptetaneg"), centrality, track.pt(), track.eta(), ux); - histos.fill(HIST("hpuyvscentptetaneg"), centrality, track.pt(), track.eta(), uy); - - histos.fill(HIST("hpuxyQxytvscentptetaneg"), centrality, track.pt(), track.eta(), uxyQxyt); - histos.fill(HIST("hpuxyQxypvscentptetaneg"), centrality, track.pt(), track.eta(), uxyQxyp); - histos.fill(HIST("hpoddv1vscentptetaneg"), centrality, track.pt(), track.eta(), oddv1); - histos.fill(HIST("hpevenv1vscentptetaneg"), centrality, track.pt(), track.eta(), evenv1); + histos.fill(HIST("hpuxQxpvscentptetaneg"), centrality, track.pt(), track.eta(), uxQxp,wNUA); + histos.fill(HIST("hpuyQypvscentptetaneg"), centrality, track.pt(), track.eta(), uyQyp,wNUA); + histos.fill(HIST("hpuxQxtvscentptetaneg"), centrality, track.pt(), track.eta(), uxQxt,wNUA); + histos.fill(HIST("hpuyQytvscentptetaneg"), centrality, track.pt(), track.eta(), uyQyt,wNUA); + + histos.fill(HIST("hpuxvscentptetaneg"), centrality, track.pt(), track.eta(), ux,wNUA); + histos.fill(HIST("hpuyvscentptetaneg"), centrality, track.pt(), track.eta(), uy,wNUA); + + histos.fill(HIST("hpuxyQxytvscentptetaneg"), centrality, track.pt(), track.eta(), uxyQxyt,wNUA); + histos.fill(HIST("hpuxyQxypvscentptetaneg"), centrality, track.pt(), track.eta(), uxyQxyp,wNUA); + histos.fill(HIST("hpoddv1vscentptetaneg"), centrality, track.pt(), track.eta(), oddv1,wNUA); + histos.fill(HIST("hpevenv1vscentptetaneg"), centrality, track.pt(), track.eta(), evenv1,wNUA); }*/ } else { - histos.fill(HIST("hpuxQxpvscentpteta"), centrality, track.tpcInnerParam(), track.eta(), uxQxp); - histos.fill(HIST("hpuyQypvscentpteta"), centrality, track.tpcInnerParam(), track.eta(), uyQyp); - histos.fill(HIST("hpuxQxtvscentpteta"), centrality, track.tpcInnerParam(), track.eta(), uxQxt); - histos.fill(HIST("hpuyQytvscentpteta"), centrality, track.tpcInnerParam(), track.eta(), uyQyt); - - histos.fill(HIST("hpuxvscentpteta"), centrality, track.pt(), track.eta(), ux); - histos.fill(HIST("hpuyvscentpteta"), centrality, track.pt(), track.eta(), uy); - - histos.fill(HIST("hpuxyQxytvscentpteta"), centrality, track.tpcInnerParam(), track.eta(), uxyQxyt); - histos.fill(HIST("hpuxyQxypvscentpteta"), centrality, track.tpcInnerParam(), track.eta(), uxyQxyp); - histos.fill(HIST("hpoddv1vscentpteta"), centrality, track.pt(), track.eta(), oddv1); - histos.fill(HIST("hpevenv1vscentpteta"), centrality, track.pt(), track.eta(), evenv1); + histos.fill(HIST("hpuxQxpvscentpteta"), centrality, track.tpcInnerParam(), track.eta(), uxQxp, wNUA); + histos.fill(HIST("hpuyQypvscentpteta"), centrality, track.tpcInnerParam(), track.eta(), uyQyp, wNUA); + histos.fill(HIST("hpuxQxtvscentpteta"), centrality, track.tpcInnerParam(), track.eta(), uxQxt, wNUA); + histos.fill(HIST("hpuyQytvscentpteta"), centrality, track.tpcInnerParam(), track.eta(), uyQyt, wNUA); + + histos.fill(HIST("hpuxvscentpteta"), centrality, track.pt(), track.eta(), ux, wNUA); + histos.fill(HIST("hpuyvscentpteta"), centrality, track.pt(), track.eta(), uy, wNUA); + + histos.fill(HIST("hpuxyQxytvscentpteta"), centrality, track.tpcInnerParam(), track.eta(), uxyQxyt, wNUA); + histos.fill(HIST("hpuxyQxypvscentpteta"), centrality, track.tpcInnerParam(), track.eta(), uxyQxyp, wNUA); + histos.fill(HIST("hpoddv1vscentpteta"), centrality, track.pt(), track.eta(), oddv1, wNUA); + histos.fill(HIST("hpevenv1vscentpteta"), centrality, track.pt(), track.eta(), evenv1, wNUA); } } } else { @@ -1343,6 +1368,7 @@ struct lambdapolsp { } } } + lastRunNumber = currentRunNumber; } PROCESS_SWITCH(lambdapolsp, processData, "Process data", true); @@ -1386,9 +1412,6 @@ struct lambdapolsp { return; } // histos.fill(HIST("hCentrality3"), centrality); - if (evselGrp.additionalEvSel3 && (!collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { - return; - } if (evselGrp.additionalEvSel4 && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { return; diff --git a/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx b/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx index 012685039f0..76b9d788c63 100644 --- a/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx +++ b/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx @@ -172,15 +172,33 @@ static inline int piIdx(const T& t) } } // namespace mcacc +// Optional fixed-leg correction pointers kept outside the task struct. +static TH3D* gFixedLLRep1 = nullptr; +static TH3D* gFixedULRep1 = nullptr; +static TH3D* gFixedALALRep1 = nullptr; + +static TH3D* gFixedLLRep2 = nullptr; +static TH3D* gFixedULRep2 = nullptr; +static TH3D* gFixedALALRep2 = nullptr; + struct lambdaspincorrderived { // BinningType colBinning; struct : ConfigurableGroup { Configurable cfgURL{"cfgURL", "http://alice-ccdb.cern.ch", "Address of the CCDB to browse"}; Configurable nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "Latest acceptable timestamp of creation for the object"}; + Configurable useFixedWeight{"useFixedWeight", false, "Use additional fixed-leg correction with useweight"}; + Configurable> ConfWeightPaths{ + "ConfWeightPaths", + std::vector{}, + "Replaced-leg CCDB paths in order: REP_LL_leg1,REP_UL_leg1,REP_ALAL_leg1,REP_LL_leg2,REP_UL_leg2,REP_ALAL_leg2"}; + Configurable> ConfFixedWeightPaths{ + "ConfFixedWeightPaths", + std::vector{}, + "Fixed-leg CCDB paths in order: FIX_LL_forRepLeg1,FIX_UL_forRepLeg1,FIX_ALAL_forRepLeg1,FIX_LL_forRepLeg2,FIX_UL_forRepLeg2,FIX_ALAL_forRepLeg2"}; } cfgCcdbParam; struct : ConfigurableGroup { - ConfigurableAxis cfgMixRadiusBins{"cfgMixRadiusBins", {VARIABLE_WIDTH, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 10.0, 12.0, 15.0, 20.0, 25.0, 30.0}, "Radius bins for V6 radius buffer"}; + ConfigurableAxis cfgMixRadiusBins{"cfgMixRadiusBins", {VARIABLE_WIDTH, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 10.0, 12.0, 15.0, 20.0, 25.0, 33.0}, "Radius bins for V6 radius buffer"}; } cfgMixRadiusParam; // Enable access to the CCDB for the offset and correction constants and save them in dedicated variables. @@ -200,14 +218,6 @@ struct lambdaspincorrderived { TH2D* hNUALambda = nullptr; TH2D* hNUAAntiLambda = nullptr; - Configurable ConfWeightPathLL{"ConfWeightPathLL", "Users/s/skundu/My/Object/spincorr/cent010LL", "Weight path"}; - Configurable ConfWeightPathALAL{"ConfWeightPathALAL", "Users/s/skundu/My/Object/spincorr/cent010LL", "Weight path"}; - Configurable ConfWeightPathLAL{"ConfWeightPathLAL", "Users/s/skundu/My/Object/spincorr/cent010LL", "Weight path"}; - Configurable ConfWeightPathALL{"ConfWeightPathALL", "Users/s/skundu/My/Object/spincorr/cent010LL", "Weight path"}; - Configurable ConfWeightPathLL2{"ConfWeightPathLL2", "Users/s/skundu/My/Object/spincorr/cent010LL", "Weight path 2"}; - Configurable ConfWeightPathALAL2{"ConfWeightPathALAL2", "Users/s/skundu/My/Object/spincorr/cent010LL", "Weight path 2"}; - Configurable ConfWeightPathLAL2{"ConfWeightPathLAL2", "Users/s/skundu/My/Object/spincorr/cent010LL", "Weight path 2"}; - Configurable ConfWeightPathALL2{"ConfWeightPathALL2", "Users/s/skundu/My/Object/spincorr/cent010LL", "Weight path 2"}; Configurable useNUA{"useNUA", false, "Apply single-candidate NUA weight in (phi,eta)"}; Configurable ConfNUAPathLambda{"ConfNUAPathLambda", "", "CCDB path for Lambda NUA TH2D(phi,eta)"}; Configurable ConfNUAPathAntiLambda{"ConfNUAPathAntiLambda", "", "CCDB path for AntiLambda NUA TH2D(phi,eta)"}; @@ -238,7 +248,17 @@ struct lambdaspincorrderived { Configurable harmonicDphi{"harmonicDphi", 2, "Harmonic delta phi"}; Configurable useweight{"useweight", 0, "Use weight"}; Configurable usePDGM{"usePDGM", 1, "Use PDG mass"}; - Configurable useAdditionalHisto{"useAdditionalHisto", 0, "Use additional histogram"}; + Configurable useAdditionalHisto{"useAdditionalHisto", 0, "Backward-compatible switch for extra Rap/Phi/PairMass THnSparse"}; + + // Output-control switches. Keep the final mass-mass-costheta sparse on by default, + // but allow heavy QA/additional sparses to be disabled in production. + Configurable fillBasicQAHistos{"fillBasicQAHistos", true, "Fill light QA histograms: pT-y, phi-eta, centrality, dphi, pt/eta vs cent"}; + Configurable fillReplacementQAHistos{"fillReplacementQAHistos", true, "Fill raw TGT/REP single-candidate replacement QA maps"}; + Configurable fillFixedLegQAHistos{"fillFixedLegQAHistos", false, "Fill fixed-leg TGT/SUC QA maps"}; + Configurable fillWeightQAHistos{"fillWeightQAHistos", false, "Fill weighted/final-weighted REP/FIX QA maps"}; + Configurable fillAnalysisSparses{"fillAnalysisSparses", false, "Fill extra deltaR/deltaRap/deltaPhi Analysis THnSparse objects"}; + Configurable fillAdditionalSparses{"fillAdditionalSparses", false, "Fill extra rapidity/dphi/pair-mass THnSparse objects"}; + Configurable checkDoubleStatus{"checkDoubleStatus", 0, "Check Double status"}; Configurable cosPA{"cosPA", 0.995, "Cosine Pointing Angle"}; Configurable radiusMin{"radiusMin", 3, "Minimum V0 radius"}; @@ -264,6 +284,8 @@ struct lambdaspincorrderived { // THnsparse bining ConfigurableAxis configThnAxisInvMass{"configThnAxisInvMass", {50, 1.09, 1.14}, "#it{M} (GeV/#it{c}^{2})"}; ConfigurableAxis configThnAxisR{"configThnAxisR", {VARIABLE_WIDTH, 0.0, 8.0}, "#it{R}"}; + ConfigurableAxis configThnAxisPt{"configThnAxisPt", {40, 0.5, 4.5}, "#it{R}"}; + ConfigurableAxis configThnAxisRap{"configThnAxisRap", {16, -0.8, 0.8}, "#it{R}"}; ConfigurableAxis configThnAxisPol{"configThnAxisPol", {VARIABLE_WIDTH, 0.0, 8.0}, "cos#it{#theta *}"}; ConfigurableAxis configThnAxisCentrality{"configThnAxisCentrality", {VARIABLE_WIDTH, 0.0, 80.0}, "Centrality"}; ConfigurableAxis configThnAxisRapidity{"configThnAxisRapidity", {VARIABLE_WIDTH, 0.0, 1.0}, "Rapidity"}; @@ -278,16 +300,80 @@ struct lambdaspincorrderived { void init(o2::framework::InitContext&) { - histos.add("hPtRadiusV0", "V0 QA;#it{p}_{T}^{V0} (GeV/#it{c});V0 decay radius (cm)", kTH2F, {{100, 0.0, 10.0}, {120, 0.0, 45.0}}); - histos.add("hPtYSame", "hPtYSame", kTH2F, {{100, 0.0, 10.0}, {200, -1.0, 1.0}}); - histos.add("hPtYMix", "hPtYMix", kTH2F, {{100, 0.0, 10.0}, {200, -1.0, 1.0}}); - histos.add("hPhiEtaSame", "hPhiEtaSame", kTH2F, {{720, 0.0, 2.0 * TMath::Pi()}, {200, -1.0, 1.0}}); - histos.add("hPhiEtaMix", "hPhiEtaMix", kTH2F, {{720, 0.0, 2.0 * TMath::Pi()}, {200, -1.0, 1.0}}); - histos.add("hCentrality", "Centrality distribution", kTH1F, {{configThnAxisCentrality}}); - histos.add("deltaPhiSame", "deltaPhiSame", HistType::kTH1D, {{72, -TMath::Pi(), TMath::Pi()}}, true); - histos.add("deltaPhiMix", "deltaPhiMix", HistType::kTH1D, {{72, -TMath::Pi(), TMath::Pi()}}, true); - histos.add("ptCent", "ptCent", HistType::kTH2D, {{100, 0.0, 10.0}, {8, 0.0, 80.0}}, true); - histos.add("etaCent", "etaCent", HistType::kTH2D, {{32, -0.8, 0.8}, {8, 0.0, 80.0}}, true); + if (fillBasicQAHistos) { + histos.add("hPtRadiusV0", "V0 QA;#it{p}_{T}^{V0} (GeV/#it{c});V0 decay radius (cm)", kTH2F, {{100, 0.0, 10.0}, {120, 0.0, 45.0}}); + histos.add("hPtYSame", "hPtYSame", kTH2F, {{100, 0.0, 10.0}, {200, -1.0, 1.0}}); + histos.add("hPtYMix", "hPtYMix", kTH2F, {{100, 0.0, 10.0}, {200, -1.0, 1.0}}); + histos.add("hPhiEtaSame", "hPhiEtaSame", kTH2F, {{720, 0.0, 2.0 * TMath::Pi()}, {200, -1.0, 1.0}}); + histos.add("hPhiEtaMix", "hPhiEtaMix", kTH2F, {{720, 0.0, 2.0 * TMath::Pi()}, {200, -1.0, 1.0}}); + histos.add("hCentrality", "Centrality distribution", kTH1F, {{configThnAxisCentrality}}); + histos.add("deltaPhiSame", "deltaPhiSame", HistType::kTH1D, {{72, -TMath::Pi(), TMath::Pi()}}, true); + histos.add("deltaPhiMix", "deltaPhiMix", HistType::kTH1D, {{72, -TMath::Pi(), TMath::Pi()}}, true); + histos.add("ptCent", "ptCent", HistType::kTH2D, {{100, 0.0, 10.0}, {8, 0.0, 80.0}}, true); + histos.add("etaCent", "etaCent", HistType::kTH2D, {{32, -0.8, 0.8}, {8, 0.0, 80.0}}, true); + } + + if (fillWeightQAHistos) { + // QA for weighting + histos.add("REP_LL_leg1_weighted", + "Weighted repl LL leg1;#phi;y/#eta;p_{T}", + HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("REP_LAL_leg1_weighted", + "Weighted repl LAL leg1;#phi;y/#eta;p_{T}", + HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("REP_ALL_leg1_weighted", + "Weighted repl ALL leg1;#phi;y/#eta;p_{T}", + HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("REP_ALAL_leg1_weighted", + "Weighted repl ALAL leg1;#phi;y/#eta;p_{T}", + HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("REP_LL_leg2_weighted", + "Weighted repl LL leg2;#phi;y/#eta;p_{T}", + HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("REP_LAL_leg2_weighted", + "Weighted repl LAL leg2;#phi;y/#eta;p_{T}", + HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("REP_ALL_leg2_weighted", + "Weighted repl ALL leg2;#phi;y/#eta;p_{T}", + HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("REP_ALAL_leg2_weighted", + "Weighted repl ALAL leg2;#phi;y/#eta;p_{T}", + HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + } + if (fillFixedLegQAHistos) { + // Fixed-leg QA for replacement-leg bias check. + // For repLeg1: leg1 is replaced, fixed leg is original leg2. + // For repLeg2: leg2 is replaced, fixed leg is original leg1. + + // Target fixed-leg maps: all requested SE pairs + histos.add("TGT_FIX_LL_forRepLeg1", "Target fixed LL for rep leg1;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("TGT_FIX_LAL_forRepLeg1", "Target fixed LAL for rep leg1;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("TGT_FIX_ALL_forRepLeg1", "Target fixed ALL for rep leg1;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("TGT_FIX_ALAL_forRepLeg1", "Target fixed ALAL for rep leg1;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("TGT_FIX_LL_forRepLeg2", "Target fixed LL for rep leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("TGT_FIX_LAL_forRepLeg2", "Target fixed LAL for rep leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("TGT_FIX_ALL_forRepLeg2", "Target fixed ALL for rep leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("TGT_FIX_ALAL_forRepLeg2", "Target fixed ALAL for rep leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + // Successful fixed-leg maps: only pairs where replacement was found + histos.add("SUC_FIX_LL_forRepLeg1", "Successful fixed LL for rep leg1;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("SUC_FIX_LAL_forRepLeg1", "Successful fixed LAL for rep leg1;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("SUC_FIX_ALL_forRepLeg1", "Successful fixed ALL for rep leg1;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("SUC_FIX_ALAL_forRepLeg1", "Successful fixed ALAL for rep leg1;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("SUC_FIX_LL_forRepLeg2", "Successful fixed LL for rep leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("SUC_FIX_LAL_forRepLeg2", "Successful fixed LAL for rep leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("SUC_FIX_ALL_forRepLeg2", "Successful fixed ALL for rep leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("SUC_FIX_ALAL_forRepLeg2", "Successful fixed ALAL for rep leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + } histos.add("hEtaPhiLambdaRaw", "Lambda raw;#phi;#eta", kTH2D, {{360, 0.0, 2.0 * TMath::Pi()}, {32, -0.8, 0.8}}); @@ -297,27 +383,48 @@ struct lambdaspincorrderived { histos.add("hNUAWeightLambda", "Lambda NUA weight", kTH1D, {{200, 0.0, 5.0}}); histos.add("hNUAWeightAntiLambda", "AntiLambda NUA weight", kTH1D, {{200, 0.0, 5.0}}); - // --- target/replacement single-leg occupancy maps for replacement correction - histos.add("TGT_LL_leg1", "Target LL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("TGT_LAL_leg1", "Target LAL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("TGT_ALL_leg1", "Target ALL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("TGT_ALAL_leg1", "Target ALAL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - - histos.add("REP_LL_leg1", "Repl LL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("REP_LAL_leg1", "Repl LAL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("REP_ALL_leg1", "Repl ALL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("REP_ALAL_leg1", "Repl ALAL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - - histos.add("TGT_LL_leg2", "Target LL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("TGT_LAL_leg2", "Target LAL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("TGT_ALL_leg2", "Target ALL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("TGT_ALAL_leg2", "Target ALAL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - - histos.add("REP_LL_leg2", "Repl LL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("REP_LAL_leg2", "Repl LAL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("REP_ALL_leg2", "Repl ALL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - histos.add("REP_ALAL_leg2", "Repl ALAL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); - + if (fillReplacementQAHistos) { + // --- target/replacement single-leg occupancy maps for replacement correction + histos.add("TGT_LL_leg1", "Target LL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("TGT_LAL_leg1", "Target LAL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("TGT_ALL_leg1", "Target ALL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("TGT_ALAL_leg1", "Target ALAL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("REP_LL_leg1", "Repl LL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("REP_LAL_leg1", "Repl LAL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("REP_ALL_leg1", "Repl ALL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("REP_ALAL_leg1", "Repl ALAL leg1", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("TGT_LL_leg2", "Target LL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("TGT_LAL_leg2", "Target LAL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("TGT_ALL_leg2", "Target ALL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("TGT_ALAL_leg2", "Target ALAL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("REP_LL_leg2", "Repl LL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("REP_LAL_leg2", "Repl LAL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("REP_ALL_leg2", "Repl ALL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("REP_ALAL_leg2", "Repl ALAL leg2", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + } + if (fillWeightQAHistos) { + // Final-weighted QA: filled with the exact same mixing correction weight + // used for the mixed-event sparse, excluding NUA. + // Correction categories are LL, UL=(LAL+ALL), ALAL. + histos.add("REP_LL_leg1_finalWeighted", "Final weighted REP LL leg1;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("REP_UL_leg1_finalWeighted", "Final weighted REP UL leg1;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("REP_ALAL_leg1_finalWeighted", "Final weighted REP ALAL leg1;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("REP_LL_leg2_finalWeighted", "Final weighted REP LL leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("REP_UL_leg2_finalWeighted", "Final weighted REP UL leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("REP_ALAL_leg2_finalWeighted", "Final weighted REP ALAL leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("SUC_FIX_LL_forRepLeg1_finalWeighted", "Final weighted fixed LL for rep leg1;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("SUC_FIX_UL_forRepLeg1_finalWeighted", "Final weighted fixed UL for rep leg1;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("SUC_FIX_ALAL_forRepLeg1_finalWeighted", "Final weighted fixed ALAL for rep leg1;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + + histos.add("SUC_FIX_LL_forRepLeg2_finalWeighted", "Final weighted fixed LL for rep leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("SUC_FIX_UL_forRepLeg2_finalWeighted", "Final weighted fixed UL for rep leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + histos.add("SUC_FIX_ALAL_forRepLeg2_finalWeighted", "Final weighted fixed ALAL for rep leg2;#phi;y/#eta;p_{T}", HistType::kTH3D, {ax_dphi_h, ax_deta, ax_ptpair}, true); + } histos.add("hSparseLambdaLambda", "hSparseLambdaLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); histos.add("hSparseLambdaAntiLambda", "hSparseLambdaAntiLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); histos.add("hSparseAntiLambdaLambda", "hSparseAntiLambdLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); @@ -328,17 +435,19 @@ struct lambdaspincorrderived { histos.add("hSparseAntiLambdaLambdaMixed", "hSparseAntiLambdaLambdaMixed", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); histos.add("hSparseAntiLambdaAntiLambdaMixed", "hSparseAntiLambdaAntiLambdaMixed", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisR}, true); - histos.add("hSparseLambdaLambdaAnalysis", "hSparseLambdaLambdaAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); - histos.add("hSparseLambdaAntiLambdaAnalysis", "hSparseLambdaAntiLambdaAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); - histos.add("hSparseAntiLambdaLambdaAnalysis", "hSparseAntiLambdLambdaAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); - histos.add("hSparseAntiLambdaAntiLambdaAnalysis", "hSparseAntiLambdaAntiLambdaAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); + if (fillAnalysisSparses) { + histos.add("hSparseLambdaLambdaAnalysis", "hSparseLambdaLambdaAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); + histos.add("hSparseLambdaAntiLambdaAnalysis", "hSparseLambdaAntiLambdaAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); + histos.add("hSparseAntiLambdaLambdaAnalysis", "hSparseAntiLambdLambdaAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); + histos.add("hSparseAntiLambdaAntiLambdaAnalysis", "hSparseAntiLambdaAntiLambdaAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); - histos.add("hSparseLambdaLambdaMixedAnalysis", "hSparseLambdaLambdaMixedAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); - histos.add("hSparseLambdaAntiLambdaMixedAnalysis", "hSparseLambdaAntiLambdaMixedAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); - histos.add("hSparseAntiLambdaLambdaMixedAnalysis", "hSparseAntiLambdaLambdaMixedAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); - histos.add("hSparseAntiLambdaAntiLambdaMixedAnalysis", "hSparseAntiLambdaAntiLambdaMixedAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); + histos.add("hSparseLambdaLambdaMixedAnalysis", "hSparseLambdaLambdaMixedAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); + histos.add("hSparseLambdaAntiLambdaMixedAnalysis", "hSparseLambdaAntiLambdaMixedAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); + histos.add("hSparseAntiLambdaLambdaMixedAnalysis", "hSparseAntiLambdaLambdaMixedAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); + histos.add("hSparseAntiLambdaAntiLambdaMixedAnalysis", "hSparseAntiLambdaAntiLambdaMixedAnalysis", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisDeltaR, configThnAxisDeltaRap, configThnAxisDeltaPhi}, true); + } - if (useAdditionalHisto) { + if (useAdditionalHisto || fillAdditionalSparses) { histos.add("hSparseRapLambdaLambda", "hSparseRapLambdaLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisRapidity}, true); histos.add("hSparseRapLambdaAntiLambda", "hSparseRapLambdaAntiLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisRapidity}, true); histos.add("hSparseRapAntiLambdaLambda", "hSparseRapAntiLambdLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisRapidity}, true); @@ -374,18 +483,70 @@ struct lambdaspincorrderived { ccdbApi.init("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); - ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); - LOGF(info, "Getting alignment offsets from the CCDB..."); + ccdb->setCreatedNotAfter(cfgCcdbParam.nolaterthan.value); + LOGF(info, "Getting alignment offsets from the CCDB (check carefully)..."); if (useweight) { - hweight1 = ccdb->getForTimeStamp(ConfWeightPathLL.value, cfgCcdbParam.nolaterthan.value); - hweight2 = ccdb->getForTimeStamp(ConfWeightPathLAL.value, cfgCcdbParam.nolaterthan.value); - hweight3 = ccdb->getForTimeStamp(ConfWeightPathALL.value, cfgCcdbParam.nolaterthan.value); - hweight4 = ccdb->getForTimeStamp(ConfWeightPathALAL.value, cfgCcdbParam.nolaterthan.value); + const auto& repPaths = cfgCcdbParam.ConfWeightPaths.value; + if (repPaths.size() < 6) { + LOGF(fatal, "ConfWeightPaths must contain 6 paths: REP_LL_leg1, REP_UL_leg1, REP_ALAL_leg1, REP_LL_leg2, REP_UL_leg2, REP_ALAL_leg2. Found %zu", repPaths.size()); + } + for (size_t i = 0; i < repPaths.size(); ++i) { + LOGF(info, "ConfWeightPaths[%zu] = '%s'", i, repPaths[i].c_str()); + } - hweight12 = ccdb->getForTimeStamp(ConfWeightPathLL2.value, cfgCcdbParam.nolaterthan.value); - hweight22 = ccdb->getForTimeStamp(ConfWeightPathLAL2.value, cfgCcdbParam.nolaterthan.value); - hweight32 = ccdb->getForTimeStamp(ConfWeightPathALL2.value, cfgCcdbParam.nolaterthan.value); - hweight42 = ccdb->getForTimeStamp(ConfWeightPathALAL2.value, cfgCcdbParam.nolaterthan.value); + auto loadRep = [&](int idx, const char* name) -> TH3D* { + if (idx < 0 || idx >= static_cast(repPaths.size()) || repPaths[idx].empty()) { + LOGF(fatal, "Missing replaced-leg path index %d for %s", idx, name); + return nullptr; + } + auto* h = ccdb->getForTimeStamp(repPaths[idx], cfgCcdbParam.nolaterthan.value); + if (!h) { + LOGF(fatal, "Could not load replaced-leg weight %s from path %s", name, repPaths[idx].c_str()); + } + return h; + }; + + hweight1 = loadRep(0, "REP_LL_leg1"); + hweight2 = loadRep(1, "REP_UL_leg1"); + hweight4 = loadRep(2, "REP_ALAL_leg1"); + hweight12 = loadRep(3, "REP_LL_leg2"); + hweight22 = loadRep(4, "REP_UL_leg2"); + hweight42 = loadRep(5, "REP_ALAL_leg2"); + + // Keep the old ALL pointers as aliases to the UL maps to avoid accidental null access. + hweight3 = hweight2; + hweight32 = hweight22; + + if (cfgCcdbParam.useFixedWeight) { + const auto& fixPaths = cfgCcdbParam.ConfFixedWeightPaths.value; + if (fixPaths.size() < 6) { + LOGF(fatal, "ConfFixedWeightPaths must contain 6 paths: FIX_LL_forRepLeg1, FIX_UL_forRepLeg1, FIX_ALAL_forRepLeg1, FIX_LL_forRepLeg2, FIX_UL_forRepLeg2, FIX_ALAL_forRepLeg2. Found %zu", fixPaths.size()); + } + for (size_t i = 0; i < fixPaths.size(); ++i) { + LOGF(info, "ConfFixedWeightPaths[%zu] = '%s'", i, fixPaths[i].c_str()); + } + + auto loadFixed = [&](int idx, const char* name) -> TH3D* { + if (idx < 0 || idx >= static_cast(fixPaths.size()) || fixPaths[idx].empty()) { + LOGF(fatal, "Missing fixed-leg path index %d for %s", idx, name); + return nullptr; + } + auto* h = ccdb->getForTimeStamp(fixPaths[idx], cfgCcdbParam.nolaterthan.value); + if (!h) { + LOGF(fatal, "Could not load fixed-leg weight %s from path %s", name, fixPaths[idx].c_str()); + } + return h; + }; + + gFixedLLRep1 = loadFixed(0, "FIX_LL_forRepLeg1"); + gFixedULRep1 = loadFixed(1, "FIX_UL_forRepLeg1"); + gFixedALALRep1 = loadFixed(2, "FIX_ALAL_forRepLeg1"); + gFixedLLRep2 = loadFixed(3, "FIX_LL_forRepLeg2"); + gFixedULRep2 = loadFixed(4, "FIX_UL_forRepLeg2"); + gFixedALALRep2 = loadFixed(5, "FIX_ALAL_forRepLeg2"); + + LOGF(info, "Fixed-leg weights enabled. Loaded paths: %zu", fixPaths.size()); + } } if (useNUA) { hNUALambda = ccdb->getForTimeStamp(ConfNUAPathLambda.value, cfgCcdbParam.nolaterthan.value); @@ -495,10 +656,112 @@ struct lambdaspincorrderived { return w; } + int getWeightCategory(int tag1, int tag2) const + { + // Correction categories: + // 0 = LL, 1 = UL = LAL + ALL, 2 = ALAL + if (tag1 == 0 && tag2 == 0) { + return 0; + } + if (tag1 == 1 && tag2 == 1) { + return 2; + } + return 1; + } + + template + void fillFinalWeightedMixingQA(int tag1, int tag2, + int mapLeg, + int replacedPos, + LV const& particle1, + LV const& particle2, + double weight) + { + // This QA is filled with the exact same mixing-correction weight used + // for the mixed-event sparse, before the NUA factor is applied. + // mapLeg = physical replacement branch used for the CCDB map (1 or 2) + // replacedPos = position of the replaced candidate after possible L#bar{L} reordering (1 or 2) + if (!fillWeightQAHistos) { + return; + } + if (!std::isfinite(weight) || weight <= 0.0) { + return; + } + if (mapLeg != 1 && mapLeg != 2) { + return; + } + + auto getEtaOrY = [&](LV const& p) { + return userapidity ? p.Rapidity() : p.Eta(); + }; + + const LV& rep = (replacedPos == 2) ? particle2 : particle1; + const LV& fix = (replacedPos == 2) ? particle1 : particle2; + + const double ptRep = rep.Pt(); + const double phiRep = RecoDecay::constrainAngle(rep.Phi(), 0.0F, harmonic); + const double etaRep = getEtaOrY(rep); + + const double ptFix = fix.Pt(); + const double phiFix = RecoDecay::constrainAngle(fix.Phi(), 0.0F, harmonic); + const double etaFix = getEtaOrY(fix); + + // Exact four pair tags are filled for the legacy REP_*_weighted maps. + // These are useful because UL can be formed later as LAL+ALL. + if (mapLeg == 1) { + if (tag1 == 0 && tag2 == 0) { + histos.fill(HIST("REP_LL_leg1_weighted"), phiRep, etaRep, ptRep, weight); + } else if (tag1 == 0 && tag2 == 1) { + histos.fill(HIST("REP_LAL_leg1_weighted"), phiRep, etaRep, ptRep, weight); + } else if (tag1 == 1 && tag2 == 0) { + histos.fill(HIST("REP_ALL_leg1_weighted"), phiRep, etaRep, ptRep, weight); + } else if (tag1 == 1 && tag2 == 1) { + histos.fill(HIST("REP_ALAL_leg1_weighted"), phiRep, etaRep, ptRep, weight); + } + } else { // mapLeg == 2 + if (tag1 == 0 && tag2 == 0) { + histos.fill(HIST("REP_LL_leg2_weighted"), phiRep, etaRep, ptRep, weight); + } else if (tag1 == 0 && tag2 == 1) { + histos.fill(HIST("REP_LAL_leg2_weighted"), phiRep, etaRep, ptRep, weight); + } else if (tag1 == 1 && tag2 == 0) { + histos.fill(HIST("REP_ALL_leg2_weighted"), phiRep, etaRep, ptRep, weight); + } else if (tag1 == 1 && tag2 == 1) { + histos.fill(HIST("REP_ALAL_leg2_weighted"), phiRep, etaRep, ptRep, weight); + } + } + + // Combined categories are filled for the final-weighted QA maps. + const int wcat = getWeightCategory(tag1, tag2); // 0=LL, 1=UL, 2=ALAL + + if (mapLeg == 1) { + if (wcat == 0) { + histos.fill(HIST("REP_LL_leg1_finalWeighted"), phiRep, etaRep, ptRep, weight); + histos.fill(HIST("SUC_FIX_LL_forRepLeg1_finalWeighted"), phiFix, etaFix, ptFix, weight); + } else if (wcat == 1) { + histos.fill(HIST("REP_UL_leg1_finalWeighted"), phiRep, etaRep, ptRep, weight); + histos.fill(HIST("SUC_FIX_UL_forRepLeg1_finalWeighted"), phiFix, etaFix, ptFix, weight); + } else if (wcat == 2) { + histos.fill(HIST("REP_ALAL_leg1_finalWeighted"), phiRep, etaRep, ptRep, weight); + histos.fill(HIST("SUC_FIX_ALAL_forRepLeg1_finalWeighted"), phiFix, etaFix, ptFix, weight); + } + } else { // mapLeg == 2 + if (wcat == 0) { + histos.fill(HIST("REP_LL_leg2_finalWeighted"), phiRep, etaRep, ptRep, weight); + histos.fill(HIST("SUC_FIX_LL_forRepLeg2_finalWeighted"), phiFix, etaFix, ptFix, weight); + } else if (wcat == 1) { + histos.fill(HIST("REP_UL_leg2_finalWeighted"), phiRep, etaRep, ptRep, weight); + histos.fill(HIST("SUC_FIX_UL_forRepLeg2_finalWeighted"), phiFix, etaFix, ptFix, weight); + } else if (wcat == 2) { + histos.fill(HIST("REP_ALAL_leg2_finalWeighted"), phiRep, etaRep, ptRep, weight); + histos.fill(HIST("SUC_FIX_ALAL_forRepLeg2_finalWeighted"), phiFix, etaFix, ptFix, weight); + } + } + } + void fillHistograms(int tag1, int tag2, const ROOT::Math::PtEtaPhiMVector& particle1, const ROOT::Math::PtEtaPhiMVector& particle2, const ROOT::Math::PtEtaPhiMVector& daughpart1, const ROOT::Math::PtEtaPhiMVector& daughpart2, - int datatype, float mixpairweight, int replacedLeg = 1) + int datatype, float mixpairweight, int replacedLeg = 1, int weightMapLeg = -1) { auto lambda1Mass = 0.0; auto lambda2Mass = 0.0; @@ -576,57 +839,131 @@ struct lambdaspincorrderived { double deltaRap = std::abs(particle1.Rapidity() - particle2.Rapidity()); double deltaR = TMath::Sqrt(deltaRap * deltaRap + dphi_pair * dphi_pair); - double epsWeight1 = 1.0; - double epsWeight2 = 1.0; + // only for weight lookup; must match fillReplacementControlMap() + double yOrEta1_forWeight = deta1; + double yOrEta2_forWeight = deta2; + + if (userapidity) { + yOrEta1_forWeight = particle1.Rapidity(); + yOrEta2_forWeight = particle2.Rapidity(); + } + + // `replacedLeg` is the position of the replaced candidate in the ordered pair + // passed to fillHistograms: 1 -> particle1, 2 -> particle2. + // `weightMapLeg` is the physical replacement branch used to select the CCDB map: + // 1 -> REP_*_leg1, 2 -> REP_*_leg2. This distinction is needed for unlike-sign + // pairs where the pair is reordered to Lambda-AntiLambda before filling. + const int replacedPos = replacedLeg; + const int ccdbMapLeg = (weightMapLeg > 0) ? weightMapLeg : replacedLeg; + + double epsWeightReplaced = 1.0; + double epsWeightFixed = 1.0; if (useweight && datatype == 1) { - if (tag1 == 0 && tag2 == 0) { - epsWeight1 = hweight1->GetBinContent(hweight1->FindBin(dphi1, deta1, pt1)); - epsWeight2 = hweight12->GetBinContent(hweight12->FindBin(dphi2, deta2, pt2)); - } else if (tag1 == 0 && tag2 == 1) { - epsWeight1 = hweight2->GetBinContent(hweight2->FindBin(dphi1, deta1, pt1)); - epsWeight2 = hweight22->GetBinContent(hweight22->FindBin(dphi2, deta2, pt2)); - } else if (tag1 == 1 && tag2 == 0) { - epsWeight1 = hweight3->GetBinContent(hweight3->FindBin(dphi1, deta1, pt1)); - epsWeight2 = hweight32->GetBinContent(hweight32->FindBin(dphi2, deta2, pt2)); - } else if (tag1 == 1 && tag2 == 1) { - epsWeight1 = hweight4->GetBinContent(hweight4->FindBin(dphi1, deta1, pt1)); - epsWeight2 = hweight42->GetBinContent(hweight42->FindBin(dphi2, deta2, pt2)); + const int wcat = getWeightCategory(tag1, tag2); + + auto getRepEps = [&](int mapLeg, double phi, double yOrEta, double pt) -> double { + TH3D* h = nullptr; + if (mapLeg == 1) { + if (wcat == 0) + h = hweight1; + else if (wcat == 1) + h = hweight2; + else if (wcat == 2) + h = hweight4; + } else if (mapLeg == 2) { + if (wcat == 0) + h = hweight12; + else if (wcat == 1) + h = hweight22; + else if (wcat == 2) + h = hweight42; + } + if (!h) { + return 1.0; + } + return h->GetBinContent(h->FindBin(phi, yOrEta, pt)); + }; + + auto getFixedEps = [&](int mapLeg, double phi, double yOrEta, double pt) -> double { + TH3D* h = nullptr; + if (mapLeg == 1) { + if (wcat == 0) + h = gFixedLLRep1; + else if (wcat == 1) + h = gFixedULRep1; + else if (wcat == 2) + h = gFixedALALRep1; + } else if (mapLeg == 2) { + if (wcat == 0) + h = gFixedLLRep2; + else if (wcat == 1) + h = gFixedULRep2; + else if (wcat == 2) + h = gFixedALALRep2; + } + if (!h) { + return 1.0; + } + return h->GetBinContent(h->FindBin(phi, yOrEta, pt)); + }; + + const double phiRep = (replacedPos == 2) ? dphi2 : dphi1; + const double yRep = (replacedPos == 2) ? yOrEta2_forWeight : yOrEta1_forWeight; + const double ptRep = (replacedPos == 2) ? pt2 : pt1; + epsWeightReplaced = getRepEps(ccdbMapLeg, phiRep, yRep, ptRep); + + if (cfgCcdbParam.useFixedWeight) { + const int fixedPos = (replacedPos == 2) ? 1 : 2; + const double phiFix = (fixedPos == 2) ? dphi2 : dphi1; + const double yFix = (fixedPos == 2) ? yOrEta2_forWeight : yOrEta1_forWeight; + const double ptFix = (fixedPos == 2) ? pt2 : pt1; + epsWeightFixed = getFixedEps(ccdbMapLeg, phiFix, yFix, ptFix); } } if (datatype == 0) { const double weight = pairNUAWeight; if (tag1 == 0 && tag2 == 0) { - histos.fill(HIST("hPtYSame"), particle1.Pt(), particle1.Rapidity(), nuaWeight1); - histos.fill(HIST("hPhiEtaSame"), dphi1, particle1.Eta(), nuaWeight1); + if (fillBasicQAHistos) + histos.fill(HIST("hPtYSame"), particle1.Pt(), particle1.Rapidity(), nuaWeight1); + if (fillBasicQAHistos) + histos.fill(HIST("hPhiEtaSame"), dphi1, particle1.Eta(), nuaWeight1); histos.fill(HIST("hSparseLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseLambdaLambdaAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); - if (useAdditionalHisto) { + if (fillAnalysisSparses) { + histos.fill(HIST("hSparseLambdaLambdaAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); + } + if (useAdditionalHisto || fillAdditionalSparses) { histos.fill(HIST("hSparseRapLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } } else if (tag1 == 0 && tag2 == 1) { histos.fill(HIST("hSparseLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseLambdaAntiLambdaAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); - if (useAdditionalHisto) { + if (fillAnalysisSparses) { + histos.fill(HIST("hSparseLambdaAntiLambdaAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); + } + if (useAdditionalHisto || fillAdditionalSparses) { histos.fill(HIST("hSparseRapLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } } else if (tag1 == 1 && tag2 == 0) { histos.fill(HIST("hSparseAntiLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseAntiLambdaLambdaAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); - if (useAdditionalHisto) { + if (fillAnalysisSparses) { + histos.fill(HIST("hSparseAntiLambdaLambdaAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); + } + if (useAdditionalHisto || fillAdditionalSparses) { histos.fill(HIST("hSparseRapAntiLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiAntiLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassAntiLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } } else if (tag1 == 1 && tag2 == 1) { histos.fill(HIST("hSparseAntiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseAntiLambdaAntiLambdaAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); - if (useAdditionalHisto) { + if (fillAnalysisSparses) { + histos.fill(HIST("hSparseAntiLambdaAntiLambdaAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); + } + if (useAdditionalHisto || fillAdditionalSparses) { histos.fill(HIST("hSparseRapAntiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiAntiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassAntiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); @@ -637,25 +974,39 @@ struct lambdaspincorrderived { double weight = mixpairweight; if (useweight) { - const double epsWeightReplaced = (replacedLeg == 2) ? epsWeight2 : epsWeight1; - if (!std::isfinite(epsWeightReplaced) || epsWeightReplaced <= 0.0) { + const double epsWeightTotal = epsWeightReplaced * epsWeightFixed; + + if (!std::isfinite(epsWeightTotal) || epsWeightTotal <= 0.0) { return; } - weight = mixpairweight / epsWeightReplaced; + weight = mixpairweight / epsWeightTotal; + } + + // This is the pure mixing-correction weight. + // Do not include NUA here, because TGT/REP/FIX QA maps were filled without NUA. + const double weightMixingQA = weight; + + if (useweight) { + fillFinalWeightedMixingQA(tag1, tag2, ccdbMapLeg, replacedPos, particle1, particle2, weightMixingQA); } + weight *= pairNUAWeight; if (!std::isfinite(weight) || weight <= 0.0) { return; } if (tag1 == 0 && tag2 == 0) { - if (replacedLeg == 1) { - histos.fill(HIST("hPtYMix"), particle1.Pt(), particle1.Rapidity(), nuaWeight1 * mixpairweight); - histos.fill(HIST("hPhiEtaMix"), dphi1, particle1.Eta(), nuaWeight1 * mixpairweight); + if (replacedLeg == 1 || replacedLeg == 2) { + if (fillBasicQAHistos) + histos.fill(HIST("hPtYMix"), particle1.Pt(), particle1.Rapidity(), nuaWeight1 * mixpairweight); + if (fillBasicQAHistos) + histos.fill(HIST("hPhiEtaMix"), dphi1, particle1.Eta(), nuaWeight1 * mixpairweight); } histos.fill(HIST("hSparseLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseLambdaLambdaMixedAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); - if (useAdditionalHisto) { + if (fillAnalysisSparses) { + histos.fill(HIST("hSparseLambdaLambdaMixedAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); + } + if (useAdditionalHisto || fillAdditionalSparses) { histos.fill(HIST("hSparseRapLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); @@ -663,24 +1014,30 @@ struct lambdaspincorrderived { } else if (tag1 == 0 && tag2 == 1) { histos.fill(HIST("hSparseLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseLambdaAntiLambdaMixedAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); - if (useAdditionalHisto) { + if (fillAnalysisSparses) { + histos.fill(HIST("hSparseLambdaAntiLambdaMixedAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); + } + if (useAdditionalHisto || fillAdditionalSparses) { histos.fill(HIST("hSparseRapLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } } else if (tag1 == 1 && tag2 == 0) { histos.fill(HIST("hSparseAntiLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseAntiLambdaLambdaMixedAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); - if (useAdditionalHisto) { + if (fillAnalysisSparses) { + histos.fill(HIST("hSparseAntiLambdaLambdaMixedAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); + } + if (useAdditionalHisto || fillAdditionalSparses) { histos.fill(HIST("hSparseRapAntiLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiAntiLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassAntiLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); } } else if (tag1 == 1 && tag2 == 1) { histos.fill(HIST("hSparseAntiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, weight); - histos.fill(HIST("hSparseAntiLambdaAntiLambdaMixedAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); - if (useAdditionalHisto) { + if (fillAnalysisSparses) { + histos.fill(HIST("hSparseAntiLambdaAntiLambdaMixedAnalysis"), particle1.M(), particle2.M(), cosThetaDiff, deltaR, deltaRap, std::abs(dphi_pair), weight); + } + if (useAdditionalHisto || fillAdditionalSparses) { histos.fill(HIST("hSparseRapAntiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, deltaRap, weight); histos.fill(HIST("hSparsePhiAntiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, dphi_pair, weight); histos.fill(HIST("hSparsePairMassAntiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, pairDummy.M(), weight); @@ -735,9 +1092,15 @@ struct lambdaspincorrderived { if (!selectionV0(v0)) { continue; } - histos.fill(HIST("hPtRadiusV0"), v0.lambdaPt(), v0.v0Radius()); - histos.fill(HIST("ptCent"), v0.lambdaPt(), centrality); - histos.fill(HIST("etaCent"), v0.lambdaEta(), centrality); + if (fillBasicQAHistos) { + histos.fill(HIST("hPtRadiusV0"), v0.lambdaPt(), v0.v0Radius()); + } + if (fillBasicQAHistos) { + histos.fill(HIST("ptCent"), v0.lambdaPt(), centrality); + } + if (fillBasicQAHistos) { + histos.fill(HIST("etaCent"), v0.lambdaEta(), centrality); + } proton = ROOT::Math::PtEtaPhiMVector(v0.protonPt(), v0.protonEta(), v0.protonPhi(), o2::constants::physics::MassProton); lambda = ROOT::Math::PtEtaPhiMVector(v0.lambdaPt(), v0.lambdaEta(), v0.lambdaPhi(), v0.lambdaMass()); const double phi = RecoDecay::constrainAngle(v0.lambdaPhi(), 0.0F, harmonic); @@ -760,7 +1123,8 @@ struct lambdaspincorrderived { proton2 = ROOT::Math::PtEtaPhiMVector(v02.protonPt(), v02.protonEta(), v02.protonPhi(), o2::constants::physics::MassProton); lambda2 = ROOT::Math::PtEtaPhiMVector(v02.lambdaPt(), v02.lambdaEta(), v02.lambdaPhi(), v02.lambdaMass()); if ((v0.v0Status() == 0 && v02.v0Status() == 1) || (v0.v0Status() == 1 && v02.v0Status() == 0)) - histos.fill(HIST("deltaPhiSame"), RecoDecay::constrainAngle(v0.lambdaPhi() - v02.lambdaPhi(), -TMath::Pi(), harmonicDphi)); + if (fillBasicQAHistos) + histos.fill(HIST("deltaPhiSame"), RecoDecay::constrainAngle(v0.lambdaPhi() - v02.lambdaPhi(), -TMath::Pi(), harmonicDphi)); // const int ptype = pairTypeCode(v0.v0Status(), v02.v0Status()); if (v0.v0Status() == 0 && v02.v0Status() == 0) { fillHistograms(0, 0, lambda, lambda2, proton, proton2, 0, 1.0); @@ -782,6 +1146,9 @@ struct lambdaspincorrderived { template void fillReplacementControlMap(int tag1, int tag2, int leg, bool isTarget, LV const& particle, float weight) { + if (!fillReplacementQAHistos) { + return; + } const double pt = particle.Pt(); const double phi = RecoDecay::constrainAngle(particle.Phi(), 0.0F, harmonic); @@ -803,6 +1170,8 @@ struct lambdaspincorrderived { } if (leg == 1 && !isTarget) { + + // Raw REP map: used to produce CCDB weight. if (tag1 == 0 && tag2 == 0) histos.fill(HIST("REP_LL_leg1"), phi, etaOrY, pt, weight); else if (tag1 == 0 && tag2 == 1) @@ -811,6 +1180,7 @@ struct lambdaspincorrderived { histos.fill(HIST("REP_ALL_leg1"), phi, etaOrY, pt, weight); else if (tag1 == 1 && tag2 == 1) histos.fill(HIST("REP_ALAL_leg1"), phi, etaOrY, pt, weight); + // Correct weighted REP QA is filled in fillHistograms(), after the exact final weight is computed. return; } @@ -827,6 +1197,8 @@ struct lambdaspincorrderived { } if (leg == 2 && !isTarget) { + + // Raw REP map: used to produce CCDB weight. if (tag1 == 0 && tag2 == 0) histos.fill(HIST("REP_LL_leg2"), phi, etaOrY, pt, weight); else if (tag1 == 0 && tag2 == 1) @@ -835,10 +1207,76 @@ struct lambdaspincorrderived { histos.fill(HIST("REP_ALL_leg2"), phi, etaOrY, pt, weight); else if (tag1 == 1 && tag2 == 1) histos.fill(HIST("REP_ALAL_leg2"), phi, etaOrY, pt, weight); + // Correct weighted REP QA is filled in fillHistograms(), after the exact final weight is computed. return; } } + template + void fillFixedLegControlMap(int tag1, int tag2, + int repLeg, + bool isTarget, + LV const& fixedParticle, + float weight) + { + if (!fillFixedLegQAHistos) { + return; + } + const double pt = fixedParticle.Pt(); + const double phi = RecoDecay::constrainAngle(fixedParticle.Phi(), 0.0F, harmonic); + double etaOrY = fixedParticle.Eta(); + if (userapidity) { + etaOrY = fixedParticle.Rapidity(); + } + + if (repLeg == 1) { + // leg1 is replaced, fixed leg is original leg2 + if (isTarget) { + if (tag1 == 0 && tag2 == 0) + histos.fill(HIST("TGT_FIX_LL_forRepLeg1"), phi, etaOrY, pt, weight); + else if (tag1 == 0 && tag2 == 1) + histos.fill(HIST("TGT_FIX_LAL_forRepLeg1"), phi, etaOrY, pt, weight); + else if (tag1 == 1 && tag2 == 0) + histos.fill(HIST("TGT_FIX_ALL_forRepLeg1"), phi, etaOrY, pt, weight); + else if (tag1 == 1 && tag2 == 1) + histos.fill(HIST("TGT_FIX_ALAL_forRepLeg1"), phi, etaOrY, pt, weight); + } else { + if (tag1 == 0 && tag2 == 0) + histos.fill(HIST("SUC_FIX_LL_forRepLeg1"), phi, etaOrY, pt, weight); + else if (tag1 == 0 && tag2 == 1) + histos.fill(HIST("SUC_FIX_LAL_forRepLeg1"), phi, etaOrY, pt, weight); + else if (tag1 == 1 && tag2 == 0) + histos.fill(HIST("SUC_FIX_ALL_forRepLeg1"), phi, etaOrY, pt, weight); + else if (tag1 == 1 && tag2 == 1) + histos.fill(HIST("SUC_FIX_ALAL_forRepLeg1"), phi, etaOrY, pt, weight); + } + return; + } + + if (repLeg == 2) { + // leg2 is replaced, fixed leg is original leg1 + if (isTarget) { + if (tag1 == 0 && tag2 == 0) + histos.fill(HIST("TGT_FIX_LL_forRepLeg2"), phi, etaOrY, pt, weight); + else if (tag1 == 0 && tag2 == 1) + histos.fill(HIST("TGT_FIX_LAL_forRepLeg2"), phi, etaOrY, pt, weight); + else if (tag1 == 1 && tag2 == 0) + histos.fill(HIST("TGT_FIX_ALL_forRepLeg2"), phi, etaOrY, pt, weight); + else if (tag1 == 1 && tag2 == 1) + histos.fill(HIST("TGT_FIX_ALAL_forRepLeg2"), phi, etaOrY, pt, weight); + } else { + if (tag1 == 0 && tag2 == 0) + histos.fill(HIST("SUC_FIX_LL_forRepLeg2"), phi, etaOrY, pt, weight); + else if (tag1 == 0 && tag2 == 1) + histos.fill(HIST("SUC_FIX_LAL_forRepLeg2"), phi, etaOrY, pt, weight); + else if (tag1 == 1 && tag2 == 0) + histos.fill(HIST("SUC_FIX_ALL_forRepLeg2"), phi, etaOrY, pt, weight); + else if (tag1 == 1 && tag2 == 1) + histos.fill(HIST("SUC_FIX_ALAL_forRepLeg2"), phi, etaOrY, pt, weight); + } + return; + } + } // Processing Event Mixing SliceCache cache; using BinningType = ColumnBinningPolicy; @@ -879,17 +1317,6 @@ struct lambdaspincorrderived { const bool doMixLeg1 = (cfgMixLegMode.value == 0 || cfgMixLegMode.value == 2); const bool doMixLeg2 = (cfgMixLegMode.value == 1 || cfgMixLegMode.value == 2); - if (doMixLeg1) { - fillReplacementControlMap(t1.v0Status(), t2.v0Status(), 1, true, - ROOT::Math::PtEtaPhiMVector(t1.lambdaPt(), t1.lambdaEta(), t1.lambdaPhi(), t1.lambdaMass()), - 1.0f); - } - if (doMixLeg2) { - fillReplacementControlMap(t1.v0Status(), t2.v0Status(), 2, true, - ROOT::Math::PtEtaPhiMVector(t2.lambdaPt(), t2.lambdaEta(), t2.lambdaPhi(), t2.lambdaMass()), - 1.0f); - } - struct PV { AllTrackCandidates* pool; int nRepl1 = 0; @@ -898,6 +1325,8 @@ struct lambdaspincorrderived { std::vector usable; int totalRepl = 0; + int totalRepl1 = 0; + int totalRepl2 = 0; int mixes = 0; for (auto it = eventPools[bin].rbegin(); it != eventPools[bin].rend() && mixes < nEvtMixing; ++it, ++mixes) { @@ -917,13 +1346,15 @@ struct lambdaspincorrderived { } if (doMixLeg1) { - if (checkKinematics(t1, tX)) { + // Single-track replacement: replace a candidate only by the same species. + if (tX.v0Status() == t1.v0Status() && checkKinematics(t1, tX)) { ++nRepl1; } } if (doMixLeg2) { - if (checkKinematics(t2, tX)) { + // Single-track replacement: replace a candidate only by the same species. + if (tX.v0Status() == t2.v0Status() && checkKinematics(t2, tX)) { ++nRepl2; } } @@ -932,6 +1363,8 @@ struct lambdaspincorrderived { if (nRepl1 > 0 || nRepl2 > 0) { usable.push_back(PV{&poolB, nRepl1, nRepl2}); totalRepl += nRepl1 + nRepl2; + totalRepl1 += nRepl1; + totalRepl2 += nRepl2; } } @@ -941,6 +1374,28 @@ struct lambdaspincorrderived { const float wBase = 1.0f / static_cast(totalRepl); + // Single-track replacement target must use the same branch normalization + // as the actually used replacement candidates. Per SE pair: + // sum REP_leg1 weights = totalRepl1 / totalRepl + // sum REP_leg2 weights = totalRepl2 / totalRepl + // Therefore TGT leg1/leg2 are filled with the same weights. + if (doMixLeg1 && totalRepl1 > 0) { + fillReplacementControlMap(t1.v0Status(), t2.v0Status(), 1, true, + ROOT::Math::PtEtaPhiMVector(t1.lambdaPt(), t1.lambdaEta(), t1.lambdaPhi(), t1.lambdaMass()), + static_cast(totalRepl1) * wBase); + fillFixedLegControlMap(t1.v0Status(), t2.v0Status(), 1, true, + ROOT::Math::PtEtaPhiMVector(t2.lambdaPt(), t2.lambdaEta(), t2.lambdaPhi(), t2.lambdaMass()), + static_cast(totalRepl1) * wBase); + } + if (doMixLeg2 && totalRepl2 > 0) { + fillReplacementControlMap(t1.v0Status(), t2.v0Status(), 2, true, + ROOT::Math::PtEtaPhiMVector(t2.lambdaPt(), t2.lambdaEta(), t2.lambdaPhi(), t2.lambdaMass()), + static_cast(totalRepl2) * wBase); + fillFixedLegControlMap(t1.v0Status(), t2.v0Status(), 2, true, + ROOT::Math::PtEtaPhiMVector(t1.lambdaPt(), t1.lambdaEta(), t1.lambdaPhi(), t1.lambdaMass()), + static_cast(totalRepl2) * wBase); + } + for (auto& pv : usable) { auto& poolB = *pv.pool; @@ -951,7 +1406,7 @@ struct lambdaspincorrderived { // -------- leg-1 replacement: (tX, t2) if (doMixLeg1) { - if (checkKinematics(t1, tX)) { + if (tX.v0Status() == t1.v0Status() && checkKinematics(t1, tX)) { fillReplacementControlMap(tX.v0Status(), t2.v0Status(), 1, false, ROOT::Math::PtEtaPhiMVector(tX.lambdaPt(), tX.lambdaEta(), tX.lambdaPhi(), tX.lambdaMass()), wBase); @@ -969,7 +1424,8 @@ struct lambdaspincorrderived { RecoDecay::constrainAngle(lambda2.Phi(), 0.0F, harmonic), -TMath::Pi(), harmonicDphi); - histos.fill(HIST("deltaPhiMix"), dPhi, wBase); + if (fillBasicQAHistos) + histos.fill(HIST("deltaPhiMix"), dPhi, wBase); fillHistograms(tX.v0Status(), t2.v0Status(), lambda, lambda2, proton, proton2, 1, wBase, 1); @@ -978,7 +1434,7 @@ struct lambdaspincorrderived { // -------- leg-2 replacement: (t1, tX) if (doMixLeg2) { - if (checkKinematics(t2, tX)) { + if (tX.v0Status() == t2.v0Status() && checkKinematics(t2, tX)) { fillReplacementControlMap(t1.v0Status(), tX.v0Status(), 2, false, ROOT::Math::PtEtaPhiMVector(tX.lambdaPt(), tX.lambdaEta(), tX.lambdaPhi(), tX.lambdaMass()), wBase); @@ -996,7 +1452,8 @@ struct lambdaspincorrderived { RecoDecay::constrainAngle(lambda2.Phi(), 0.0F, harmonic), -TMath::Pi(), harmonicDphi); - histos.fill(HIST("deltaPhiMix"), dPhi, wBase); + if (fillBasicQAHistos) + histos.fill(HIST("deltaPhiMix"), dPhi, wBase); fillHistograms(t1.v0Status(), tX.v0Status(), lambda, lambda2, proton, proton2, 1, wBase, 2); @@ -1270,9 +1727,15 @@ struct lambdaspincorrderived { if (!selectionV0MC(v0)) { continue; } - histos.fill(HIST("hPtRadiusV0"), mcacc::lamPt(v0), mcacc::v0Radius(v0)); - histos.fill(HIST("ptCent"), mcacc::lamPt(v0), centrality); - histos.fill(HIST("etaCent"), mcacc::lamEta(v0), centrality); + if (fillBasicQAHistos) { + histos.fill(HIST("hPtRadiusV0"), mcacc::lamPt(v0), mcacc::v0Radius(v0)); + } + if (fillBasicQAHistos) { + histos.fill(HIST("ptCent"), mcacc::lamPt(v0), centrality); + } + if (fillBasicQAHistos) { + histos.fill(HIST("etaCent"), mcacc::lamEta(v0), centrality); + } proton = ROOT::Math::PtEtaPhiMVector(mcacc::prPt(v0), mcacc::prEta(v0), mcacc::prPhi(v0), o2::constants::physics::MassProton); @@ -1337,17 +1800,31 @@ struct lambdaspincorrderived { return std::abs(deltaPhiMinusPiToPi(phiA, phiB)); } - // symmetric neighbors for phi: no wrap at edge + // symmetric neighbors for phi with periodic wrap at 0/2pi static inline void collectNeighborBinsPhi(int b, int nPhi, int nNeighbor, std::vector& out) { out.clear(); + if (nPhi <= 0 || b < 0 || b >= nPhi) { + return; + } + + if (2 * nNeighbor + 1 >= nPhi) { + out.reserve(nPhi); + for (int bb = 0; bb < nPhi; ++bb) { + out.push_back(bb); + } + return; + } + out.reserve(2 * nNeighbor + 1); for (int d = -nNeighbor; d <= nNeighbor; ++d) { - const int bb = b + d; - if (bb >= 0 && bb < nPhi) { - out.push_back(bb); + int bb = (b + d) % nPhi; + if (bb < 0) { + bb += nPhi; } + out.push_back(bb); } + std::sort(out.begin(), out.end()); out.erase(std::unique(out.begin(), out.end()), out.end()); } @@ -1674,6 +2151,26 @@ struct lambdaspincorrderived { const bool doMixLeg1 = (cfgMixLegMode.value == 0 || cfgMixLegMode.value == 2); const bool doMixLeg2 = (cfgMixLegMode.value == 1 || cfgMixLegMode.value == 2); + // Fill TGT maps before searching for replacements. This makes TGT the + // true same-event target phase space for the selected pair, matching the + // hPtYSame definition. REP below is filled only for accepted replacements. + if (doMixLeg1) { + fillReplacementControlMap(t1.v0Status(), t2.v0Status(), 1, true, + ROOT::Math::PtEtaPhiMVector(t1.lambdaPt(), t1.lambdaEta(), t1.lambdaPhi(), t1.lambdaMass()), + 1.0f); + fillFixedLegControlMap(t1.v0Status(), t2.v0Status(), 1, true, + ROOT::Math::PtEtaPhiMVector(t2.lambdaPt(), t2.lambdaEta(), t2.lambdaPhi(), t2.lambdaMass()), + 1.0f); + } + if (doMixLeg2) { + fillReplacementControlMap(t1.v0Status(), t2.v0Status(), 2, true, + ROOT::Math::PtEtaPhiMVector(t2.lambdaPt(), t2.lambdaEta(), t2.lambdaPhi(), t2.lambdaMass()), + 1.0f); + fillFixedLegControlMap(t1.v0Status(), t2.v0Status(), 2, true, + ROOT::Math::PtEtaPhiMVector(t1.lambdaPt(), t1.lambdaEta(), t1.lambdaPhi(), t1.lambdaMass()), + 1.0f); + } + if (doMixLeg1) { collectMatchesForReplacedLeg(t1, t2, colBin, curColIdx, matches1); limitMatchesToNEvents(matches1, nEvtMixing.value); @@ -1690,18 +2187,8 @@ struct lambdaspincorrderived { matches2.clear(); } - // --- fill target distributions for the original SE leg that is to be replaced - if (doMixLeg1) { - fillReplacementControlMap(t1.v0Status(), t2.v0Status(), 1, true, - ROOT::Math::PtEtaPhiMVector(t1.lambdaPt(), t1.lambdaEta(), t1.lambdaPhi(), t1.lambdaMass()), - 1.0f); - } - - if (doMixLeg2) { - fillReplacementControlMap(t1.v0Status(), t2.v0Status(), 2, true, - ROOT::Math::PtEtaPhiMVector(t2.lambdaPt(), t2.lambdaEta(), t2.lambdaPhi(), t2.lambdaMass()), - 1.0f); - } + // Do not fill TGT here. TGT has already been filled above as the + // selected same-event target phase space, independent of replacement success. int nFill1 = 0; int nFill2 = 0; // count actual accepted fills for leg-1 replacement @@ -1710,6 +2197,8 @@ struct lambdaspincorrderived { auto tX = V0s.iteratorAt(static_cast(m.rowIndex)); if (!selectionV0(tX)) continue; + if (tX.v0Status() != t1.v0Status()) + continue; if (!checkKinematics(t1, tX)) continue; if (tX.globalIndex() == t1.globalIndex()) @@ -1728,10 +2217,12 @@ struct lambdaspincorrderived { if (doMixLeg2) { for (auto const& m : matches2) { auto tY = V0s.iteratorAt(static_cast(m.rowIndex)); - if (!checkKinematics(t2, tY)) - continue; if (!selectionV0(tY)) continue; + if (tY.v0Status() != t2.v0Status()) + continue; + if (!checkKinematics(t2, tY)) + continue; if (tY.globalIndex() == t2.globalIndex()) continue; if (tY.globalIndex() == t1.globalIndex()) @@ -1747,8 +2238,23 @@ struct lambdaspincorrderived { if (nFill1 <= 0 && nFill2 <= 0) { continue; } - const int nUse = nFill1 + nFill2; - const float wSE = (nUse > 0) ? 1.0f / static_cast(nUse) : 0.0f; + // Residual-weight QA needs a leg-specific normalization: + // TGT_leg is filled once per same-event target candidate with weight 1. + // REP_leg is the average replacement distribution for that same target. + const float wSELeg1 = (nFill1 > 0) ? 1.0f / static_cast(nFill1) : 0.0f; + const float wSELeg2 = (nFill2 > 0) ? 1.0f / static_cast(nFill2) : 0.0f; + + const int nActiveMixBranches = ((doMixLeg1 && nFill1 > 0) ? 1 : 0) + + ((doMixLeg2 && nFill2 > 0) ? 1 : 0); + const float branchNorm = (cfgMixLegMode.value == 2 && nActiveMixBranches > 0) + ? 1.0f / static_cast(nActiveMixBranches) + : 1.0f; + const float finalMixWeightLeg1 = branchNorm * wSELeg1; + const float finalMixWeightLeg2 = branchNorm * wSELeg2; + + // Do not fill target maps here: TGT has already been filled above, + // before searching for replacements, so that TGT represents all selected + // same-event targets rather than only targets with successful replacements. if (doMixLeg1 && nFill1 > 0) { for (auto const& m : matches1) { @@ -1756,6 +2262,8 @@ struct lambdaspincorrderived { if (!selectionV0(tX)) { continue; } + if (tX.v0Status() != t1.v0Status()) + continue; if (!checkKinematics(t1, tX)) continue; if (tX.globalIndex() == t1.globalIndex()) @@ -1768,7 +2276,12 @@ struct lambdaspincorrderived { continue; fillReplacementControlMap(tX.v0Status(), t2.v0Status(), 1, false, ROOT::Math::PtEtaPhiMVector(tX.lambdaPt(), tX.lambdaEta(), tX.lambdaPhi(), tX.lambdaMass()), - wSE); + wSELeg1); + // Fixed leg for leg1 replacement is original t2. + // Fill only for successful replacement. + fillFixedLegControlMap(tX.v0Status(), t2.v0Status(), 1, false, + ROOT::Math::PtEtaPhiMVector(t2.lambdaPt(), t2.lambdaEta(), t2.lambdaPhi(), t2.lambdaMass()), + wSELeg1); auto proton = ROOT::Math::PtEtaPhiMVector(tX.protonPt(), tX.protonEta(), tX.protonPhi(), o2::constants::physics::MassProton); auto lambda = ROOT::Math::PtEtaPhiMVector(tX.lambdaPt(), tX.lambdaEta(), tX.lambdaPhi(), tX.lambdaMass()); auto proton2 = ROOT::Math::PtEtaPhiMVector(t2.protonPt(), t2.protonEta(), t2.protonPhi(), o2::constants::physics::MassProton); @@ -1776,19 +2289,20 @@ struct lambdaspincorrderived { // const int ptype = pairTypeCode(tX.v0Status(), t2.v0Status()); - const float meWeight = wSE; + const float meWeight = finalMixWeightLeg1; const float dPhi = deltaPhiMinusPiToPi((float)lambda.Phi(), (float)lambda2.Phi()); if ((tX.v0Status() == 0 && t2.v0Status() == 1) || (tX.v0Status() == 1 && t2.v0Status() == 0)) - histos.fill(HIST("deltaPhiMix"), dPhi, wSE); + if (fillBasicQAHistos) + histos.fill(HIST("deltaPhiMix"), dPhi, meWeight); const int s1 = tX.v0Status(); const int s2 = t2.v0Status(); if (s1 == 0 && s2 == 1) { - fillHistograms(0, 1, lambda, lambda2, proton, proton2, 1, meWeight, 1); + fillHistograms(0, 1, lambda, lambda2, proton, proton2, 1, meWeight, 1, 1); } else if (s1 == 1 && s2 == 0) { - fillHistograms(0, 1, lambda2, lambda, proton2, proton, 1, meWeight, 2); + fillHistograms(0, 1, lambda2, lambda, proton2, proton, 1, meWeight, 2, 1); } else { - fillHistograms(s1, s2, lambda, lambda2, proton, proton2, 1, meWeight, 1); + fillHistograms(s1, s2, lambda, lambda2, proton, proton2, 1, meWeight, 1, 1); } } } @@ -1799,6 +2313,8 @@ struct lambdaspincorrderived { if (!selectionV0(tY)) { continue; } + if (tY.v0Status() != t2.v0Status()) + continue; if (!checkKinematics(t2, tY)) continue; if (tY.globalIndex() == t2.globalIndex()) @@ -1811,24 +2327,30 @@ struct lambdaspincorrderived { continue; fillReplacementControlMap(t1.v0Status(), tY.v0Status(), 2, false, ROOT::Math::PtEtaPhiMVector(tY.lambdaPt(), tY.lambdaEta(), tY.lambdaPhi(), tY.lambdaMass()), - wSE); + wSELeg2); + // Fixed leg for leg2 replacement is original t1. + // Fill only for successful replacement. + fillFixedLegControlMap(t1.v0Status(), tY.v0Status(), 2, false, + ROOT::Math::PtEtaPhiMVector(t1.lambdaPt(), t1.lambdaEta(), t1.lambdaPhi(), t1.lambdaMass()), + wSELeg2); auto proton = ROOT::Math::PtEtaPhiMVector(t1.protonPt(), t1.protonEta(), t1.protonPhi(), o2::constants::physics::MassProton); auto lambda = ROOT::Math::PtEtaPhiMVector(t1.lambdaPt(), t1.lambdaEta(), t1.lambdaPhi(), t1.lambdaMass()); auto proton2 = ROOT::Math::PtEtaPhiMVector(tY.protonPt(), tY.protonEta(), tY.protonPhi(), o2::constants::physics::MassProton); auto lambda2 = ROOT::Math::PtEtaPhiMVector(tY.lambdaPt(), tY.lambdaEta(), tY.lambdaPhi(), tY.lambdaMass()); // const int ptype = pairTypeCode(t1.v0Status(), tY.v0Status()); - const float meWeight = wSE; + const float meWeight = finalMixWeightLeg2; const float dPhi = deltaPhiMinusPiToPi((float)lambda.Phi(), (float)lambda2.Phi()); - histos.fill(HIST("deltaPhiMix"), dPhi, wSE); + if (fillBasicQAHistos) + histos.fill(HIST("deltaPhiMix"), dPhi, meWeight); const int s1 = t1.v0Status(); const int s2 = tY.v0Status(); if (s1 == 0 && s2 == 1) { - fillHistograms(0, 1, lambda, lambda2, proton, proton2, 1, meWeight, 2); + fillHistograms(0, 1, lambda, lambda2, proton, proton2, 1, meWeight, 2, 2); } else if (s1 == 1 && s2 == 0) { - fillHistograms(0, 1, lambda2, lambda, proton2, proton, 1, meWeight, 1); + fillHistograms(0, 1, lambda2, lambda, proton2, proton, 1, meWeight, 1, 2); } else { - fillHistograms(s1, s2, lambda, lambda2, proton, proton2, 1, meWeight, 2); + fillHistograms(s1, s2, lambda, lambda2, proton, proton2, 1, meWeight, 2, 2); } } } @@ -2092,6 +2614,25 @@ struct lambdaspincorrderived { const bool doMixLeg1 = (cfgMixLegMode.value == 0 || cfgMixLegMode.value == 2); const bool doMixLeg2 = (cfgMixLegMode.value == 1 || cfgMixLegMode.value == 2); + // Fill MC TGT maps before searching for replacements, same definition as data: + // TGT is the selected same-event target phase space, independent of replacement success. + if (doMixLeg1) { + fillReplacementControlMap(mcacc::v0Status(t1), mcacc::v0Status(t2), 1, true, + ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(t1), mcacc::lamEta(t1), mcacc::lamPhi(t1), mcacc::lamMass(t1)), + 1.0f); + fillFixedLegControlMap(mcacc::v0Status(t1), mcacc::v0Status(t2), 1, true, + ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(t2), mcacc::lamEta(t2), mcacc::lamPhi(t2), mcacc::lamMass(t2)), + 1.0f); + } + if (doMixLeg2) { + fillReplacementControlMap(mcacc::v0Status(t1), mcacc::v0Status(t2), 2, true, + ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(t2), mcacc::lamEta(t2), mcacc::lamPhi(t2), mcacc::lamMass(t2)), + 1.0f); + fillFixedLegControlMap(mcacc::v0Status(t1), mcacc::v0Status(t2), 2, true, + ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(t1), mcacc::lamEta(t1), mcacc::lamPhi(t1), mcacc::lamMass(t1)), + 1.0f); + } + if (doMixLeg1) { collectMatchesForReplacedLeg(t1, t2, colBin, curColIdx, matches1); limitMatchesToNEvents(matches1, nEvtMixing.value); @@ -2106,18 +2647,9 @@ struct lambdaspincorrderived { } else { matches2.clear(); } - if (doMixLeg1) { - fillReplacementControlMap(mcacc::v0Status(t1), mcacc::v0Status(t2), 1, true, - ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(t1), mcacc::lamEta(t1), mcacc::lamPhi(t1), mcacc::lamMass(t1)), - 1.0f); - } - - if (doMixLeg2) { - fillReplacementControlMap(mcacc::v0Status(t1), mcacc::v0Status(t2), 2, true, - ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(t2), mcacc::lamEta(t2), mcacc::lamPhi(t2), mcacc::lamMass(t2)), - 1.0f); - } + // Do not fill TGT here. TGT has already been filled above as the + // selected same-event target phase space, independent of replacement success. int nFill1 = 0; int nFill2 = 0; @@ -2128,6 +2660,8 @@ struct lambdaspincorrderived { if (!selectionV0MC(tX)) continue; + if (mcacc::v0Status(tX) != mcacc::v0Status(t1)) + continue; if (!checkKinematicsMC(t1, tX)) continue; if (tX.globalIndex() == t1.globalIndex()) @@ -2149,6 +2683,8 @@ struct lambdaspincorrderived { if (!selectionV0MC(tY)) continue; + if (mcacc::v0Status(tY) != mcacc::v0Status(t2)) + continue; if (!checkKinematicsMC(t2, tY)) continue; if (tY.globalIndex() == t2.globalIndex()) @@ -2166,8 +2702,17 @@ struct lambdaspincorrderived { if (nFill1 <= 0 && nFill2 <= 0) { continue; } - const int nUse = nFill1 + nFill2; - const float wSE = (nUse > 0) ? 1.0f / static_cast(nUse) : 0.0f; + // Residual-weight QA needs the same leg-specific REP normalization in MC. + const float wSELeg1 = (nFill1 > 0) ? 1.0f / static_cast(nFill1) : 0.0f; + const float wSELeg2 = (nFill2 > 0) ? 1.0f / static_cast(nFill2) : 0.0f; + + const int nActiveMixBranches = ((doMixLeg1 && nFill1 > 0) ? 1 : 0) + + ((doMixLeg2 && nFill2 > 0) ? 1 : 0); + const float branchNorm = (cfgMixLegMode.value == 2 && nActiveMixBranches > 0) + ? 1.0f / static_cast(nActiveMixBranches) + : 1.0f; + const float finalMixWeightLeg1 = branchNorm * wSELeg1; + const float finalMixWeightLeg2 = branchNorm * wSELeg2; if (doMixLeg1 && nFill1 > 0) { for (auto const& m : matches1) { @@ -2175,6 +2720,8 @@ struct lambdaspincorrderived { if (!selectionV0MC(tX)) continue; + if (mcacc::v0Status(tX) != mcacc::v0Status(t1)) + continue; if (!checkKinematicsMC(t1, tX)) continue; if (tX.globalIndex() == t1.globalIndex()) @@ -2187,8 +2734,15 @@ struct lambdaspincorrderived { continue; fillReplacementControlMap(mcacc::v0Status(tX), mcacc::v0Status(t2), 1, false, ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(tX), mcacc::lamEta(tX), mcacc::lamPhi(tX), mcacc::lamMass(tX)), - wSE); - + wSELeg1); + // Fixed leg for MC leg1 replacement is original t2. + // Fill only for successful replacement. + fillFixedLegControlMap(mcacc::v0Status(tX), mcacc::v0Status(t2), 1, false, + ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(t2), + mcacc::lamEta(t2), + mcacc::lamPhi(t2), + mcacc::lamMass(t2)), + wSELeg1); auto pX = ROOT::Math::PtEtaPhiMVector(mcacc::prPt(tX), mcacc::prEta(tX), mcacc::prPhi(tX), o2::constants::physics::MassProton); auto lX = ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(tX), mcacc::lamEta(tX), mcacc::lamPhi(tX), @@ -2199,18 +2753,19 @@ struct lambdaspincorrderived { mcacc::lamMass(t2)); // const int ptype = pairTypeCode(mcacc::v0Status(tX), mcacc::v0Status(t2)); - const float meWeight = wSE; + const float meWeight = finalMixWeightLeg1; const float dPhi = deltaPhiMinusPiToPi((float)lX.Phi(), (float)l2.Phi()); - histos.fill(HIST("deltaPhiMix"), dPhi, wSE); + if (fillBasicQAHistos) + histos.fill(HIST("deltaPhiMix"), dPhi, meWeight); const int s1 = mcacc::v0Status(tX); const int s2 = mcacc::v0Status(t2); if (s1 == 0 && s2 == 1) { - fillHistograms(0, 1, lX, l2, pX, p2, 1, meWeight, 1); + fillHistograms(0, 1, lX, l2, pX, p2, 1, meWeight, 1, 1); } else if (s1 == 1 && s2 == 0) { - fillHistograms(0, 1, l2, lX, p2, pX, 1, meWeight, 2); + fillHistograms(0, 1, l2, lX, p2, pX, 1, meWeight, 2, 1); } else { - fillHistograms(s1, s2, lX, l2, pX, p2, 1, meWeight, 1); + fillHistograms(s1, s2, lX, l2, pX, p2, 1, meWeight, 1, 1); } } } @@ -2220,6 +2775,8 @@ struct lambdaspincorrderived { if (!selectionV0MC(tY)) continue; + if (mcacc::v0Status(tY) != mcacc::v0Status(t2)) + continue; if (!checkKinematicsMC(t2, tY)) continue; if (tY.globalIndex() == t2.globalIndex()) @@ -2232,8 +2789,15 @@ struct lambdaspincorrderived { continue; fillReplacementControlMap(mcacc::v0Status(t1), mcacc::v0Status(tY), 2, false, ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(tY), mcacc::lamEta(tY), mcacc::lamPhi(tY), mcacc::lamMass(tY)), - wSE); - + wSELeg2); + // Fixed leg for MC leg2 replacement is original t1. + // Fill only for successful replacement. + fillFixedLegControlMap(mcacc::v0Status(t1), mcacc::v0Status(tY), 2, false, + ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(t1), + mcacc::lamEta(t1), + mcacc::lamPhi(t1), + mcacc::lamMass(t1)), + wSELeg2); auto p1 = ROOT::Math::PtEtaPhiMVector(mcacc::prPt(t1), mcacc::prEta(t1), mcacc::prPhi(t1), o2::constants::physics::MassProton); auto l1 = ROOT::Math::PtEtaPhiMVector(mcacc::lamPt(t1), mcacc::lamEta(t1), mcacc::lamPhi(t1), @@ -2244,18 +2808,19 @@ struct lambdaspincorrderived { mcacc::lamMass(tY)); // const int ptype = pairTypeCode(mcacc::v0Status(t1), mcacc::v0Status(tY)); - const float meWeight = wSE; + const float meWeight = finalMixWeightLeg2; const float dPhi = deltaPhiMinusPiToPi((float)l1.Phi(), (float)lY.Phi()); - histos.fill(HIST("deltaPhiMix"), dPhi, wSE); + if (fillBasicQAHistos) + histos.fill(HIST("deltaPhiMix"), dPhi, meWeight); const int s1 = mcacc::v0Status(t1); const int s2 = mcacc::v0Status(tY); if (s1 == 0 && s2 == 1) { - fillHistograms(0, 1, l1, lY, p1, pY, 1, meWeight, 2); + fillHistograms(0, 1, l1, lY, p1, pY, 1, meWeight, 2, 2); } else if (s1 == 1 && s2 == 0) { - fillHistograms(0, 1, lY, l1, pY, p1, 1, meWeight, 1); + fillHistograms(0, 1, lY, l1, pY, p1, 1, meWeight, 1, 2); } else { - fillHistograms(s1, s2, l1, lY, p1, pY, 1, meWeight, 2); + fillHistograms(s1, s2, l1, lY, p1, pY, 1, meWeight, 2, 2); } } } diff --git a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx index e0352773f6b..8d2790a38a0 100644 --- a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx +++ b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx @@ -1155,7 +1155,8 @@ struct NonPromptCascadeTask { coll.multNTracksGlobal(), multreco, coll.centFT0M(), - coll.multFT0M()); + coll.multFT0M(), + coll.selection_bit(aod::evsel::kNoSameBunchPileup)); auto collIdx = NPCollsTable.lastIndex(); for (auto const& pt : recoPts) { NPRecoCandTable(collIdx, pt); @@ -1190,7 +1191,7 @@ struct NonPromptCascadeTask { } float centFT0M = coll.centFT0M(); float multFT0M = coll.multFT0M(); - NPCollsTable(mRunNumber, globalBC, coll.numContrib(), coll.multNTracksGlobal(), 0, centFT0M, multFT0M); + NPCollsTable(mRunNumber, globalBC, coll.numContrib(), coll.multNTracksGlobal(), 0, centFT0M, multFT0M, coll.selection_bit(aod::evsel::kNoSameBunchPileup)); } } }; diff --git a/PWGLF/Utils/nucleiUtils.h b/PWGLF/Utils/nucleiUtils.h index f389b6bfaec..961f8a6c0d3 100644 --- a/PWGLF/Utils/nucleiUtils.h +++ b/PWGLF/Utils/nucleiUtils.h @@ -122,6 +122,8 @@ struct SlimCandidate { uint64_t mcProcess = TMCProcess::kPNoProcess; float nsigmaTpc = -999.f; float nsigmaTof = -999.f; + float vx = -999.f; // production vertex x coordinate + float vy = -999.f; }; enum Species { diff --git a/PWGLF/Utils/strangenessBuilderModule.h b/PWGLF/Utils/strangenessBuilderModule.h index 73451ac734f..f58313bed1c 100644 --- a/PWGLF/Utils/strangenessBuilderModule.h +++ b/PWGLF/Utils/strangenessBuilderModule.h @@ -182,15 +182,51 @@ enum tableIndex { kV0Indices = 0, kCascFoundTags, nTables }; +// statics necessary for the configurables in this namespace +static constexpr int nPreselectParameters = 1; +static const std::vector preselectParticleNames{ + "Photon", + "K0s", + "Lambda", + "AntiLambda", + "XiMinus", + "XiPlus", + "OmegaMinus", + "OmegaPlus"}; + +static constexpr int nPreselectParticles = 8; +static const int defaultPreselectParameters[nPreselectParticles][nPreselectParameters]{ + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}, + {0}}; + +// table index : match order above +enum preselectParticleIndex { kGamma = 0, + kK0Short, + kLambda, + kAntiLambda, + kXiMinus, + kXiPlus, + kOmegaMinus, + kOmegaPlus, + nPartTypes }; + enum V0PreSelection : uint8_t { selGamma = 0, selK0Short, selLambda, - selAntiLambda }; + selAntiLambda, + nSelV0Types }; enum CascPreSelection : uint8_t { selXiMinus = 0, selXiPlus, selOmegaMinus, - selOmegaPlus }; + selOmegaPlus, + nSelCascTypes }; static constexpr float defaultK0MassWindowParameters[1][4] = {{2.81882e-03, 1.14057e-03, 1.72138e-03, 5.00262e-01}}; static constexpr float defaultLambdaWindowParameters[1][4] = {{1.17518e-03, 1.24099e-04, 5.47937e-03, 3.08009e-01}}; @@ -357,9 +393,11 @@ struct cascadeConfigurables : o2::framework::ConfigurableGroup { // preselection options struct preSelectOpts : o2::framework::ConfigurableGroup { std::string prefix = "preSelectOpts"; - o2::framework::Configurable preselectOnlyDesiredV0s{"preselectOnlyDesiredV0s", false, "preselect only V0s with compatible TPC PID and mass info"}; - o2::framework::Configurable preselectOnlyDesiredCascades{"preselectOnlyDesiredCascades", false, "preselect only Cascades with compatible TPC PID and mass info"}; + o2::framework::Configurable> preselectedSpecies{"preselectedSpecies", + {defaultPreselectParameters[0], nPreselectParticles, nPreselectParameters, preselectParticleNames, parameterNames}, + "Preselect this species with compatible TPC PID and mass info: 0/1 is false/true"}; + std::vector mEnabledPreselectedSpecies; // Vector of enabled preselected particle species // lifetime preselection options // apply lifetime cuts to V0 and cascade candidates // unit of measurement: centimeters @@ -546,6 +584,7 @@ class BuilderModule if (f == 1) { baseOpts.mEnabledTables[i] = 1; listOfRequestors[i] = "manual enabling"; + nEnabledTables++; } if (f == -1) { // autodetect this table in other devices @@ -559,6 +598,8 @@ class BuilderModule tableNameWithVersion += Form("_%03d", version); } if (input.matcher.binding == tableNameWithVersion) { + if (device.name == "strangenesstofpid") + continue; LOGF(info, "Device %s has subscribed to %s (version %i)", device.name, tableNames[i], version); listOfRequestors[i].Append(Form("%s ", device.name.c_str())); baseOpts.mEnabledTables[i] = 1; @@ -586,7 +627,16 @@ class BuilderModule hDeduplicationStatistics->GetXaxis()->SetBinLabel(2, "Deduplicated V0s"); } - if (preSelectOpts.preselectOnlyDesiredV0s.value == true) { + preSelectOpts.mEnabledPreselectedSpecies.resize(nPreselectParticles, 0); + LOGF(info, "Checking if preselections on V0s and cascades are required"); + for (int i = 0; i < nPreselectParticles; i++) { + if (preSelectOpts.preselectedSpecies->get(preselectParticleNames[i].c_str(), "enable")) { + preSelectOpts.mEnabledPreselectedSpecies[i] = 1; + LOGF(info, " ---> Preselection of %s enabled", preselectParticleNames[i]); + } + } + + if (preSelectOpts.mEnabledPreselectedSpecies[kGamma] || preSelectOpts.mEnabledPreselectedSpecies[kK0Short] || preSelectOpts.mEnabledPreselectedSpecies[kLambda] || preSelectOpts.mEnabledPreselectedSpecies[kAntiLambda]) { auto hPreselectionV0s = histos.template add("hPreselectionV0s", "hPreselectionV0s", o2::framework::HistType::kTH1D, {{16, -0.5f, 15.5f}}); hPreselectionV0s->GetXaxis()->SetBinLabel(1, "Not preselected"); hPreselectionV0s->GetXaxis()->SetBinLabel(2, "#gamma"); @@ -606,7 +656,7 @@ class BuilderModule hPreselectionV0s->GetXaxis()->SetBinLabel(16, "#gamma, K^{0}_{S}, #Lambda, #bar{#Lambda}"); } - if (preSelectOpts.preselectOnlyDesiredCascades.value == true) { + if (preSelectOpts.mEnabledPreselectedSpecies[kXiMinus] || preSelectOpts.mEnabledPreselectedSpecies[kXiPlus] || preSelectOpts.mEnabledPreselectedSpecies[kOmegaMinus] || preSelectOpts.mEnabledPreselectedSpecies[kOmegaPlus]) { auto hPreselectionCascades = histos.template add("hPreselectionCascades", "hPreselectionCascades", o2::framework::HistType::kTH1D, {{16, -0.5f, 15.5f}}); hPreselectionCascades->GetXaxis()->SetBinLabel(1, "Not preselected"); hPreselectionCascades->GetXaxis()->SetBinLabel(2, "#Xi^{-}"); @@ -1419,65 +1469,102 @@ class BuilderModule } } - if (!straHelper.buildV0Candidate(v0.collisionId, pvX, pvY, pvZ, posTrack, negTrack, posTrackPar, negTrackPar, v0.isCollinearV0, baseOpts.mEnabledTables[kV0Covs], v0BuilderOpts.generatePhotonCandidates)) { - products.v0dataLink(-1, -1); - continue; - } - if constexpr (requires { posTrack.tpcNSigmaEl(); }) { - if (preSelectOpts.preselectOnlyDesiredV0s) { - float lPt = RecoDecay::sqrtSumOfSquares( - straHelper.v0.positiveMomentum[0] + straHelper.v0.negativeMomentum[0], - straHelper.v0.positiveMomentum[1] + straHelper.v0.negativeMomentum[1]); - - float lPtot = RecoDecay::sqrtSumOfSquares( - straHelper.v0.positiveMomentum[0] + straHelper.v0.negativeMomentum[0], - straHelper.v0.positiveMomentum[1] + straHelper.v0.negativeMomentum[1], - straHelper.v0.positiveMomentum[2] + straHelper.v0.negativeMomentum[2]); - - float lLengthTraveled = RecoDecay::sqrtSumOfSquares( - straHelper.v0.position[0] - pvX, - straHelper.v0.position[1] - pvY, - straHelper.v0.position[2] - pvZ); - - uint8_t maskV0Preselection = 0; - - if ( // photon PID, mass, lifetime selection + std::vector preSelectedPIDV0s; + if (preSelectOpts.mEnabledPreselectedSpecies[kGamma] || preSelectOpts.mEnabledPreselectedSpecies[kK0Short] || preSelectOpts.mEnabledPreselectedSpecies[kLambda] || preSelectOpts.mEnabledPreselectedSpecies[kAntiLambda]) { + if constexpr (requires { posTrack.tpcNSigmaEl(); }) { // check PID for each particle species and mark which one passes the check + preSelectedPIDV0s.resize(nSelV0Types, 0); + if ( // photon PID selection + preSelectOpts.mEnabledPreselectedSpecies[kGamma] && std::abs(posTrack.tpcNSigmaEl()) < preSelectOpts.maxTPCpidNsigma && - std::abs(negTrack.tpcNSigmaEl()) < preSelectOpts.maxTPCpidNsigma && - std::abs(straHelper.v0.massGamma) < preSelectOpts.massCutPhoton) { - BITSET(maskV0Preselection, selGamma); + std::abs(negTrack.tpcNSigmaEl()) < preSelectOpts.maxTPCpidNsigma) { + preSelectedPIDV0s[kGamma] = 1; } - if ( // K0Short PID, mass, lifetime selection + if ( // K0Short PID selection + preSelectOpts.mEnabledPreselectedSpecies[kK0Short] && std::abs(posTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma && - std::abs(negTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma && - o2::constants::physics::MassKaonNeutral * lLengthTraveled / (lPtot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutK0S") && - std::abs(straHelper.v0.massK0Short - o2::constants::physics::MassKaonNeutral) < preSelectOpts.massWindownumberOfSigmas * getMassSigmaK0Short(lPt) + preSelectOpts.massWindowSafetyMargin) { - BITSET(maskV0Preselection, selK0Short); + std::abs(negTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma) { + preSelectedPIDV0s[kK0Short] = 1; } - if ( // Lambda PID, mass, lifetime selection + if ( // Lambda PID selection + preSelectOpts.mEnabledPreselectedSpecies[kLambda] && std::abs(posTrack.tpcNSigmaPr()) < preSelectOpts.maxTPCpidNsigma && - std::abs(negTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma && - o2::constants::physics::MassLambda * lLengthTraveled / (lPtot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutLambda") && - std::abs(straHelper.v0.massLambda - o2::constants::physics::MassLambda) < preSelectOpts.massWindownumberOfSigmas * getMassSigmaLambda(lPt) + preSelectOpts.massWindowSafetyMargin) { - BITSET(maskV0Preselection, selLambda); + std::abs(negTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma) { + preSelectedPIDV0s[kLambda] = 1; } if ( // antiLambda PID, mass, lifetime selection + preSelectOpts.mEnabledPreselectedSpecies[kAntiLambda] && std::abs(posTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma && - std::abs(negTrack.tpcNSigmaPr()) < preSelectOpts.maxTPCpidNsigma && - o2::constants::physics::MassLambda * lLengthTraveled / (lPtot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutLambda") && - std::abs(straHelper.v0.massAntiLambda - o2::constants::physics::MassLambda) < preSelectOpts.massWindownumberOfSigmas * getMassSigmaLambda(lPt) + preSelectOpts.massWindowSafetyMargin) { - BITSET(maskV0Preselection, selAntiLambda); + std::abs(negTrack.tpcNSigmaPr()) < preSelectOpts.maxTPCpidNsigma) { + preSelectedPIDV0s[kAntiLambda] = 1; } - histos.fill(HIST("hPreselectionV0s"), maskV0Preselection); - - if (maskV0Preselection == 0) { + // if particle species pass the PID selections, move onto the next candidates + if (!preSelectedPIDV0s[kGamma] && !preSelectedPIDV0s[kK0Short] && !preSelectedPIDV0s[kLambda] && !preSelectedPIDV0s[kAntiLambda]) { + histos.fill(HIST("hPreselectionV0s"), 0); products.v0dataLink(-1, -1); continue; } + } else { // if no PID information is available, do not cut on it and mark all PID checks as true + preSelectedPIDV0s.resize(nSelV0Types, 1); + } + } + + if (!straHelper.buildV0Candidate(v0.collisionId, pvX, pvY, pvZ, posTrack, negTrack, posTrackPar, negTrackPar, v0.isCollinearV0, baseOpts.mEnabledTables[kV0Covs], v0BuilderOpts.generatePhotonCandidates)) { + products.v0dataLink(-1, -1); + continue; + } + if (preSelectOpts.mEnabledPreselectedSpecies[kGamma] || preSelectOpts.mEnabledPreselectedSpecies[kK0Short] || preSelectOpts.mEnabledPreselectedSpecies[kLambda] || preSelectOpts.mEnabledPreselectedSpecies[kAntiLambda]) { + float lPt = RecoDecay::sqrtSumOfSquares( + straHelper.v0.positiveMomentum[0] + straHelper.v0.negativeMomentum[0], + straHelper.v0.positiveMomentum[1] + straHelper.v0.negativeMomentum[1]); + + float lPtot = RecoDecay::sqrtSumOfSquares( + straHelper.v0.positiveMomentum[0] + straHelper.v0.negativeMomentum[0], + straHelper.v0.positiveMomentum[1] + straHelper.v0.negativeMomentum[1], + straHelper.v0.positiveMomentum[2] + straHelper.v0.negativeMomentum[2]); + + float lLengthTraveled = RecoDecay::sqrtSumOfSquares( + straHelper.v0.position[0] - pvX, + straHelper.v0.position[1] - pvY, + straHelper.v0.position[2] - pvZ); + + uint8_t maskV0Preselection = 0; + + if ( // photon PID, mass, lifetime selection + preSelectOpts.mEnabledPreselectedSpecies[kGamma] && preSelectedPIDV0s[kGamma] && + std::abs(straHelper.v0.massGamma) < preSelectOpts.massCutPhoton) { + BITSET(maskV0Preselection, selGamma); + } + + if ( // K0Short PID, mass, lifetime selection + preSelectOpts.mEnabledPreselectedSpecies[kK0Short] && preSelectedPIDV0s[kK0Short] && + o2::constants::physics::MassKaonNeutral * lLengthTraveled / (lPtot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutK0S") && + std::abs(straHelper.v0.massK0Short - o2::constants::physics::MassKaonNeutral) < preSelectOpts.massWindownumberOfSigmas * getMassSigmaK0Short(lPt) + preSelectOpts.massWindowSafetyMargin) { + BITSET(maskV0Preselection, selK0Short); + } + + if ( // Lambda PID, mass, lifetime selection + preSelectOpts.mEnabledPreselectedSpecies[kLambda] && preSelectedPIDV0s[kLambda] && + o2::constants::physics::MassLambda * lLengthTraveled / (lPtot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutLambda") && + std::abs(straHelper.v0.massLambda - o2::constants::physics::MassLambda) < preSelectOpts.massWindownumberOfSigmas * getMassSigmaLambda(lPt) + preSelectOpts.massWindowSafetyMargin) { + BITSET(maskV0Preselection, selLambda); + } + + if ( // antiLambda PID, mass, lifetime selection + preSelectOpts.mEnabledPreselectedSpecies[kAntiLambda] && preSelectedPIDV0s[kAntiLambda] && + o2::constants::physics::MassLambda * lLengthTraveled / (lPtot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutLambda") && + std::abs(straHelper.v0.massAntiLambda - o2::constants::physics::MassLambda) < preSelectOpts.massWindownumberOfSigmas * getMassSigmaLambda(lPt) + preSelectOpts.massWindowSafetyMargin) { + BITSET(maskV0Preselection, selAntiLambda); + } + + histos.fill(HIST("hPreselectionV0s"), maskV0Preselection); + + if (maskV0Preselection == 0) { + products.v0dataLink(-1, -1); + continue; } } if (v0Map[iv0] == -1 && baseOpts.useV0BufferForCascades) { @@ -1919,6 +2006,55 @@ class BuilderModule auto const& posTrack = tracks.rawIteratorAt(cascade.posTrackId); auto const& negTrack = tracks.rawIteratorAt(cascade.negTrackId); auto const& bachTrack = tracks.rawIteratorAt(cascade.bachTrackId); + + std::vector preSelectedPIDCascades; + if (preSelectOpts.mEnabledPreselectedSpecies[kXiMinus] || preSelectOpts.mEnabledPreselectedSpecies[kXiPlus] || preSelectOpts.mEnabledPreselectedSpecies[kOmegaMinus] || preSelectOpts.mEnabledPreselectedSpecies[kOmegaPlus]) { + if constexpr (requires { posTrack.tpcNSigmaEl(); }) { // check PID for each particle species and mark which one passes the check + preSelectedPIDCascades.resize(nPartTypes, 0); + if ( // XiMinus PID selection + preSelectOpts.mEnabledPreselectedSpecies[kXiMinus] && + std::abs(posTrack.tpcNSigmaPr()) < preSelectOpts.maxTPCpidNsigma && + std::abs(negTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma && + std::abs(bachTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma) { + preSelectedPIDCascades[kXiMinus] = 1; + } + + if ( // XiPlus PID selection + preSelectOpts.mEnabledPreselectedSpecies[kXiPlus] && + std::abs(posTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma && + std::abs(negTrack.tpcNSigmaPr()) < preSelectOpts.maxTPCpidNsigma && + std::abs(bachTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma) { + preSelectedPIDCascades[kXiPlus] = 1; + } + + if ( // OmegaMinus PID selection + preSelectOpts.mEnabledPreselectedSpecies[kOmegaMinus] && + std::abs(posTrack.tpcNSigmaPr()) < preSelectOpts.maxTPCpidNsigma && + std::abs(negTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma && + std::abs(bachTrack.tpcNSigmaKa()) < preSelectOpts.maxTPCpidNsigma) { + preSelectedPIDCascades[kOmegaMinus] = 1; + } + + if ( // OmegaPlus PID selection + preSelectOpts.mEnabledPreselectedSpecies[kOmegaPlus] && + std::abs(posTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma && + std::abs(negTrack.tpcNSigmaPr()) < preSelectOpts.maxTPCpidNsigma && + std::abs(bachTrack.tpcNSigmaKa()) < preSelectOpts.maxTPCpidNsigma) { + preSelectedPIDCascades[kOmegaPlus] = 1; + } + + // if particle species pass the PID selections, move onto the next candidates + if (!preSelectedPIDCascades[kXiMinus] && !preSelectedPIDCascades[kXiPlus] && !preSelectedPIDCascades[kOmegaMinus] && !preSelectedPIDCascades[kOmegaPlus]) { + histos.fill(HIST("hPreselectionCascades"), 0); + products.cascdataLink(-1); + interlinks.cascadeToCascCores.push_back(-1); + continue; + } + } else { // if no PID information is available, do not cut on it and mark all PID checks as true + preSelectedPIDCascades.resize(nPartTypes, 1); + } + } + if (baseOpts.useV0BufferForCascades) { // this processing path uses a buffer of V0s so that no // additional minimization step is redone. It consumes less @@ -1962,85 +2098,71 @@ class BuilderModule } nCascades++; - if constexpr (requires { posTrack.tpcNSigmaEl(); }) { - if (preSelectOpts.preselectOnlyDesiredCascades) { - float lPt = RecoDecay::sqrtSumOfSquares( - straHelper.cascade.bachelorMomentum[0] + straHelper.cascade.positiveMomentum[0] + straHelper.cascade.negativeMomentum[0], - straHelper.cascade.bachelorMomentum[1] + straHelper.cascade.positiveMomentum[1] + straHelper.cascade.negativeMomentum[1]); - - float lPtot = RecoDecay::sqrtSumOfSquares( - straHelper.cascade.bachelorMomentum[0] + straHelper.cascade.positiveMomentum[0] + straHelper.cascade.negativeMomentum[0], - straHelper.cascade.bachelorMomentum[1] + straHelper.cascade.positiveMomentum[1] + straHelper.cascade.negativeMomentum[1], - straHelper.cascade.bachelorMomentum[2] + straHelper.cascade.positiveMomentum[2] + straHelper.cascade.negativeMomentum[2]); - - float lV0Ptot = RecoDecay::sqrtSumOfSquares( - straHelper.cascade.positiveMomentum[0] + straHelper.cascade.negativeMomentum[0], - straHelper.cascade.positiveMomentum[1] + straHelper.cascade.negativeMomentum[1], - straHelper.cascade.positiveMomentum[2] + straHelper.cascade.negativeMomentum[2]); - - float lLengthTraveled = RecoDecay::sqrtSumOfSquares( - straHelper.cascade.cascadePosition[0] - pvX, - straHelper.cascade.cascadePosition[1] - pvY, - straHelper.cascade.cascadePosition[2] - pvZ); - - float lV0LengthTraveled = RecoDecay::sqrtSumOfSquares( - straHelper.cascade.v0Position[0] - straHelper.cascade.cascadePosition[0], - straHelper.cascade.v0Position[1] - straHelper.cascade.cascadePosition[1], - straHelper.cascade.v0Position[2] - straHelper.cascade.cascadePosition[2]); - - uint8_t maskCascadePreselection = 0; - - if ( // XiMinus PID and mass selection - straHelper.cascade.charge < 0 && - std::abs(posTrack.tpcNSigmaPr()) < preSelectOpts.maxTPCpidNsigma && - std::abs(negTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma && - std::abs(bachTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma && - o2::constants::physics::MassLambda * lV0LengthTraveled / (lV0Ptot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutLambda") && - o2::constants::physics::MassXiMinus * lLengthTraveled / (lPtot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutXi") && - std::abs(straHelper.cascade.massXi - o2::constants::physics::MassXiMinus) < preSelectOpts.massWindownumberOfSigmas * getMassSigmaXi(lPt) + preSelectOpts.massWindowSafetyMargin) { - BITSET(maskCascadePreselection, selXiMinus); - } + if (preSelectOpts.mEnabledPreselectedSpecies[kXiMinus] || preSelectOpts.mEnabledPreselectedSpecies[kXiPlus] || preSelectOpts.mEnabledPreselectedSpecies[kOmegaMinus] || preSelectOpts.mEnabledPreselectedSpecies[kOmegaPlus]) { + float lPt = RecoDecay::sqrtSumOfSquares( + straHelper.cascade.bachelorMomentum[0] + straHelper.cascade.positiveMomentum[0] + straHelper.cascade.negativeMomentum[0], + straHelper.cascade.bachelorMomentum[1] + straHelper.cascade.positiveMomentum[1] + straHelper.cascade.negativeMomentum[1]); + + float lPtot = RecoDecay::sqrtSumOfSquares( + straHelper.cascade.bachelorMomentum[0] + straHelper.cascade.positiveMomentum[0] + straHelper.cascade.negativeMomentum[0], + straHelper.cascade.bachelorMomentum[1] + straHelper.cascade.positiveMomentum[1] + straHelper.cascade.negativeMomentum[1], + straHelper.cascade.bachelorMomentum[2] + straHelper.cascade.positiveMomentum[2] + straHelper.cascade.negativeMomentum[2]); + + float lV0Ptot = RecoDecay::sqrtSumOfSquares( + straHelper.cascade.positiveMomentum[0] + straHelper.cascade.negativeMomentum[0], + straHelper.cascade.positiveMomentum[1] + straHelper.cascade.negativeMomentum[1], + straHelper.cascade.positiveMomentum[2] + straHelper.cascade.negativeMomentum[2]); + + float lLengthTraveled = RecoDecay::sqrtSumOfSquares( + straHelper.cascade.cascadePosition[0] - pvX, + straHelper.cascade.cascadePosition[1] - pvY, + straHelper.cascade.cascadePosition[2] - pvZ); + + float lV0LengthTraveled = RecoDecay::sqrtSumOfSquares( + straHelper.cascade.v0Position[0] - straHelper.cascade.cascadePosition[0], + straHelper.cascade.v0Position[1] - straHelper.cascade.cascadePosition[1], + straHelper.cascade.v0Position[2] - straHelper.cascade.cascadePosition[2]); + + uint8_t maskCascadePreselection = 0; + + if ( // XiMinus PID and mass selection + preSelectOpts.mEnabledPreselectedSpecies[kXiMinus] && straHelper.cascade.charge < 0 && preSelectedPIDCascades[kXiMinus] && + o2::constants::physics::MassLambda * lV0LengthTraveled / (lV0Ptot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutLambda") && + o2::constants::physics::MassXiMinus * lLengthTraveled / (lPtot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutXi") && + std::abs(straHelper.cascade.massXi - o2::constants::physics::MassXiMinus) < preSelectOpts.massWindownumberOfSigmas * getMassSigmaXi(lPt) + preSelectOpts.massWindowSafetyMargin) { + BITSET(maskCascadePreselection, selXiMinus); + } - if ( // XiPlus PID and mass selection - straHelper.cascade.charge > 0 && - std::abs(posTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma && - std::abs(negTrack.tpcNSigmaPr()) < preSelectOpts.maxTPCpidNsigma && - std::abs(bachTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma && - o2::constants::physics::MassLambda * lV0LengthTraveled / (lV0Ptot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutLambda") && - o2::constants::physics::MassXiMinus * lLengthTraveled / (lPtot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutXi") && - std::abs(straHelper.cascade.massXi - o2::constants::physics::MassXiMinus) < preSelectOpts.massWindownumberOfSigmas * getMassSigmaXi(lPt) + preSelectOpts.massWindowSafetyMargin) { - BITSET(maskCascadePreselection, selXiPlus); - } + if ( // XiPlus PID and mass selection + preSelectOpts.mEnabledPreselectedSpecies[kXiPlus] && straHelper.cascade.charge > 0 && preSelectedPIDCascades[kXiPlus] && + o2::constants::physics::MassLambda * lV0LengthTraveled / (lV0Ptot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutLambda") && + o2::constants::physics::MassXiMinus * lLengthTraveled / (lPtot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutXi") && + std::abs(straHelper.cascade.massXi - o2::constants::physics::MassXiMinus) < preSelectOpts.massWindownumberOfSigmas * getMassSigmaXi(lPt) + preSelectOpts.massWindowSafetyMargin) { + BITSET(maskCascadePreselection, selXiPlus); + } - if ( // OmegaMinus PID and mass selection - straHelper.cascade.charge < 0 && - std::abs(posTrack.tpcNSigmaPr()) < preSelectOpts.maxTPCpidNsigma && - std::abs(negTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma && - std::abs(bachTrack.tpcNSigmaKa()) < preSelectOpts.maxTPCpidNsigma && - o2::constants::physics::MassLambda * lV0LengthTraveled / (lV0Ptot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutLambda") && - o2::constants::physics::MassOmegaMinus * lLengthTraveled / (lPtot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutOmega") && - std::abs(straHelper.cascade.massOmega - o2::constants::physics::MassOmegaMinus) < preSelectOpts.massWindownumberOfSigmas * getMassSigmaOmega(lPt) + preSelectOpts.massWindowSafetyMargin) { - BITSET(maskCascadePreselection, selOmegaMinus); - } + if ( // OmegaMinus PID and mass selection + preSelectOpts.mEnabledPreselectedSpecies[kOmegaMinus] && straHelper.cascade.charge < 0 && preSelectedPIDCascades[kOmegaMinus] && + o2::constants::physics::MassLambda * lV0LengthTraveled / (lV0Ptot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutLambda") && + o2::constants::physics::MassOmegaMinus * lLengthTraveled / (lPtot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutOmega") && + std::abs(straHelper.cascade.massOmega - o2::constants::physics::MassOmegaMinus) < preSelectOpts.massWindownumberOfSigmas * getMassSigmaOmega(lPt) + preSelectOpts.massWindowSafetyMargin) { + BITSET(maskCascadePreselection, selOmegaMinus); + } - if ( // OmegaPlus PID and mass selection - straHelper.cascade.charge > 0 && - std::abs(posTrack.tpcNSigmaPi()) < preSelectOpts.maxTPCpidNsigma && - std::abs(negTrack.tpcNSigmaPr()) < preSelectOpts.maxTPCpidNsigma && - std::abs(bachTrack.tpcNSigmaKa()) < preSelectOpts.maxTPCpidNsigma && - o2::constants::physics::MassLambda * lV0LengthTraveled / (lV0Ptot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutLambda") && - o2::constants::physics::MassOmegaMinus * lLengthTraveled / (lPtot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutOmega") && - std::abs(straHelper.cascade.massOmega - o2::constants::physics::MassOmegaMinus) < preSelectOpts.massWindownumberOfSigmas * getMassSigmaOmega(lPt) + preSelectOpts.massWindowSafetyMargin) { - BITSET(maskCascadePreselection, selOmegaPlus); - } + if ( // OmegaPlus PID and mass selection + preSelectOpts.mEnabledPreselectedSpecies[kOmegaPlus] && straHelper.cascade.charge > 0 && preSelectedPIDCascades[kOmegaPlus] && + o2::constants::physics::MassLambda * lV0LengthTraveled / (lV0Ptot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutLambda") && + o2::constants::physics::MassOmegaMinus * lLengthTraveled / (lPtot + 1e-13) < preSelectOpts.lifetimeCut->get("lifetimeCutOmega") && + std::abs(straHelper.cascade.massOmega - o2::constants::physics::MassOmegaMinus) < preSelectOpts.massWindownumberOfSigmas * getMassSigmaOmega(lPt) + preSelectOpts.massWindowSafetyMargin) { + BITSET(maskCascadePreselection, selOmegaPlus); + } - histos.fill(HIST("hPreselectionCascades"), maskCascadePreselection); + histos.fill(HIST("hPreselectionCascades"), maskCascadePreselection); - if (maskCascadePreselection == 0) { - products.cascdataLink(-1); - interlinks.cascadeToCascCores.push_back(-1); - continue; - } + if (maskCascadePreselection == 0) { + products.cascdataLink(-1); + interlinks.cascadeToCascCores.push_back(-1); + continue; } } diff --git a/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx b/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx index 575470dc8af..785227be049 100644 --- a/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx +++ b/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx @@ -358,6 +358,7 @@ struct DndetaMFTPbPb { Configurable cfgUseTrackSel{"cfgUseTrackSel", false, "Flag to apply track selection"}; Configurable cfgUseParticleSel{"cfgUseParticleSel", false, "Flag to apply particle selection"}; Configurable cfgUsePrimaries{"cfgUsePrimaries", false, "Select primary particles"}; + Configurable cfgUseSecondaries{"cfgUseSecondaries", false, "Select secondary particles"}; Configurable cfgRemoveTrivialAssoc{"cfgRemoveTrivialAssoc", false, "Skip trivial associations"}; Configurable cfgRemoveAmbiguousTracks{"cfgRemoveAmbiguousTracks", false, "Remove ambiguous tracks"}; Configurable cfgRemoveOrphanTracks{"cfgRemoveOrphanTracks", true, "Remove orphan tracks"}; @@ -1191,19 +1192,25 @@ struct DndetaMFTPbPb { registry.add("ReAssocMC/hNReAssocRecoColls", "Number of times generated collisions are reconstructed; N; Counts", HistType::kTH1F, {{10, -0.5, 9.5}}); - registry.add("ReAssocMC/hReAssocMCEventStatus", ";status", {HistType::kTH1F, {{static_cast(ReAssocMCEventStatus::nEvtReAsReAssocMCEventStatus), -0.5, +static_cast(ReAssocMCEventStatus::nEvtReAsReAssocMCEventStatus) - 0.5}}}); + registry.add({"ReAssocMC/EvtGenRecReassoc", ";status;centrality;occupancy", {HistType::kTHnSparseF, {{3, 0.5, 3.5}, centralityAxis, occupancyAxis}}}); + auto heff = registry.get(HIST("ReAssocMC/EvtGenRecReassoc")); + heff->GetAxis(0)->SetBinLabel(1, "All generated"); + heff->GetAxis(0)->SetBinLabel(2, "All reconstructed"); + heff->GetAxis(0)->SetBinLabel(3, "Selected reconstructed"); + + registry.add({"ReAssocMC/hReAssocMCEventStatus", ";status;centrality;occupancy", {HistType::kTHnSparseF, {{static_cast(ReAssocMCEventStatus::nEvtReAsReAssocMCEventStatus), -0.5, +static_cast(ReAssocMCEventStatus::nEvtReAsReAssocMCEventStatus) - 0.5}, centralityAxis, occupancyAxis}}}); std::string labelReAssocMCEventStatus[CevtReAsReAssocMCEventStatus]; labelReAssocMCEventStatus[static_cast(ReAssocMCEventStatus::kEvtReAsAll)] = "All"; labelReAssocMCEventStatus[static_cast(ReAssocMCEventStatus::kEvtReAsSelected)] = "Selected"; labelReAssocMCEventStatus[static_cast(ReAssocMCEventStatus::kEvtReAsHasMcColl)] = "Has Mc Coll"; labelReAssocMCEventStatus[static_cast(ReAssocMCEventStatus::kEvtReAsSplitVtxRemoved)] = "Split Vtx Removed"; labelReAssocMCEventStatus[static_cast(ReAssocMCEventStatus::kEvtReAsZVtxCutMC)] = "Vtx-z cut MC"; - registry.get(HIST("ReAssocMC/hReAssocMCEventStatus"))->SetMinimum(0.1); + // registry.get(HIST("ReAssocMC/hReAssocMCEventStatus"))->SetMinimum(0.1); for (int iBin = 0; iBin < static_cast(ReAssocMCEventStatus::nEvtReAsReAssocMCEventStatus); iBin++) { - registry.get(HIST("ReAssocMC/hReAssocMCEventStatus"))->GetXaxis()->SetBinLabel(iBin + 1, labelReAssocMCEventStatus[iBin].data()); + registry.get(HIST("ReAssocMC/hReAssocMCEventStatus"))->GetAxis(0)->SetBinLabel(iBin + 1, labelReAssocMCEventStatus[iBin].data()); } - registry.add("ReAssocMC/hReAssocMCTrackStatus", ";status", {HistType::kTH1F, {{static_cast(ReAssocMCTrackStatus::nReAssocMCTrackStatusCheck), -0.5, +static_cast(ReAssocMCTrackStatus::nReAssocMCTrackStatusCheck) - 0.5}}}); + registry.add({"ReAssocMC/hReAssocMCTrackStatus", ";status;centrality;occupancy", {HistType::kTHnSparseF, {{static_cast(ReAssocMCTrackStatus::nReAssocMCTrackStatusCheck), -0.5, +static_cast(ReAssocMCTrackStatus::nReAssocMCTrackStatusCheck) - 0.5}, centralityAxis, occupancyAxis}}}); std::string labelReAssocMCTrackStatus[CreAssocMCTrackStatus]; labelReAssocMCTrackStatus[static_cast(ReAssocMCTrackStatus::kTrkReAssocAll)] = "All"; labelReAssocMCTrackStatus[static_cast(ReAssocMCTrackStatus::kTrkBestSel)] = "Best sel"; @@ -1238,68 +1245,68 @@ struct DndetaMFTPbPb { labelReAssocMCTrackStatus[static_cast(ReAssocMCTrackStatus::kAssocBad)] = "Assoc bad"; labelReAssocMCTrackStatus[static_cast(ReAssocMCTrackStatus::kAssocBadIsCompTrue)] = "Assoc bad Comp True"; labelReAssocMCTrackStatus[static_cast(ReAssocMCTrackStatus::kAssocBadIsCompFalse)] = "Assoc bad Comp False"; - registry.get(HIST("ReAssocMC/hReAssocMCTrackStatus"))->SetMinimum(0.1); + // registry.get(HIST("ReAssocMC/hReAssocMCTrackStatus"))->SetMinimum(0.1); for (int iBin = 0; iBin < static_cast(ReAssocMCTrackStatus::nReAssocMCTrackStatusCheck); iBin++) { - registry.get(HIST("ReAssocMC/hReAssocMCTrackStatus"))->GetXaxis()->SetBinLabel(iBin + 1, labelReAssocMCTrackStatus[iBin].data()); + registry.get(HIST("ReAssocMC/hReAssocMCTrackStatus"))->GetAxis(0)->SetBinLabel(iBin + 1, labelReAssocMCTrackStatus[iBin].data()); } // Vertex resolution - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkIdGt0)] = registry.add("ReAssocMC/hVtxResIdGt0", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmb)] = registry.add("ReAssocMC/hVtxResNonAmb", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbGood)] = registry.add("ReAssocMC/hVtxResNonAmbGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbBad)] = registry.add("ReAssocMC/hVtxResNonAmbBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbID)] = registry.add("ReAssocMC/hVtxResNonAmbID", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDGood)] = registry.add("ReAssocMC/hVtxResNonAmbIDGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDBad)] = registry.add("ReAssocMC/hVtxResNonAmbIDBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkAmbID)] = registry.add("ReAssocMC/hVtxResAmbID", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkAmbIDGood)] = registry.add("ReAssocMC/hVtxResAmbIDGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkAmbIDBad)] = registry.add("ReAssocMC/hVtxResAmbIDBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtra)] = registry.add("ReAssocMC/hVtxResNonAmbIDExtra", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraGood)] = registry.add("ReAssocMC/hVtxResNonAmbIDExtraGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraBad)] = registry.add("ReAssocMC/hVtxResNonAmbIDExtraBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssoc)] = registry.add("ReAssocMC/hVtxResReAssoc", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocGood)] = registry.add("ReAssocMC/hVtxResReAssocGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompTrue)] = registry.add("ReAssocMC/hVtxResReAssocGoodIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompFalse)] = registry.add("ReAssocMC/hVtxResReAssocGoodIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocBad)] = registry.add("ReAssocMC/hVtxResReAssocBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompTrue)] = registry.add("ReAssocMC/hVtxResReAssocBadIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompFalse)] = registry.add("ReAssocMC/hVtxResReAssocBadIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssoc)] = registry.add("ReAssocMC/hVtxResAssoc", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocGood)] = registry.add("ReAssocMC/hVtxResAssocGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompTrue)] = registry.add("ReAssocMC/hVtxResAssocGoodIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompFalse)] = registry.add("ReAssocMC/hVtxResAssocGoodIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocBad)] = registry.add("ReAssocMC/hVtxResAssocBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocBadIsCompTrue)] = registry.add("ReAssocMC/hVtxResAssocBadIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocBadIsCompFalse)] = registry.add("ReAssocMC/hVtxResAssocBadIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkIdGt0)] = registry.add("ReAssocMC/hVtxResIdGt0", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmb)] = registry.add("ReAssocMC/hVtxResNonAmb", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbGood)] = registry.add("ReAssocMC/hVtxResNonAmbGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbBad)] = registry.add("ReAssocMC/hVtxResNonAmbBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbID)] = registry.add("ReAssocMC/hVtxResNonAmbID", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDGood)] = registry.add("ReAssocMC/hVtxResNonAmbIDGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDBad)] = registry.add("ReAssocMC/hVtxResNonAmbIDBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkAmbID)] = registry.add("ReAssocMC/hVtxResAmbID", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkAmbIDGood)] = registry.add("ReAssocMC/hVtxResAmbIDGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkAmbIDBad)] = registry.add("ReAssocMC/hVtxResAmbIDBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtra)] = registry.add("ReAssocMC/hVtxResNonAmbIDExtra", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraGood)] = registry.add("ReAssocMC/hVtxResNonAmbIDExtraGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraBad)] = registry.add("ReAssocMC/hVtxResNonAmbIDExtraBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssoc)] = registry.add("ReAssocMC/hVtxResReAssoc", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocGood)] = registry.add("ReAssocMC/hVtxResReAssocGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompTrue)] = registry.add("ReAssocMC/hVtxResReAssocGoodIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompFalse)] = registry.add("ReAssocMC/hVtxResReAssocGoodIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocBad)] = registry.add("ReAssocMC/hVtxResReAssocBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompTrue)] = registry.add("ReAssocMC/hVtxResReAssocBadIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompFalse)] = registry.add("ReAssocMC/hVtxResReAssocBadIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssoc)] = registry.add("ReAssocMC/hVtxResAssoc", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocGood)] = registry.add("ReAssocMC/hVtxResAssocGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompTrue)] = registry.add("ReAssocMC/hVtxResAssocGoodIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompFalse)] = registry.add("ReAssocMC/hVtxResAssocGoodIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocBad)] = registry.add("ReAssocMC/hVtxResAssocBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocBadIsCompTrue)] = registry.add("ReAssocMC/hVtxResAssocBadIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocBadIsCompFalse)] = registry.add("ReAssocMC/hVtxResAssocBadIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};#it{X}_{vtx}^{reco}#minus#it{X}_{vtx}^{gen} (cm);#it{Y}_{vtx}^{reco}#minus#it{Y}_{vtx}^{gen} (cm);#it{Z}_{vtx}^{reco}#minus#it{Z}_{vtx}^{gen} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, deltaZAxis, deltaZAxis, deltaZAxis, centralityAxis, occupancyAxis}); // DCA - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkIdGt0)] = registry.add("ReAssocMC/hDCAIdGt0", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmb)] = registry.add("ReAssocMC/hDCANonAmbAll", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbGood)] = registry.add("ReAssocMC/hDCANonAmbGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbBad)] = registry.add("ReAssocMC/hDCANonAmbBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbID)] = registry.add("ReAssocMC/hDCAAmbAll", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDGood)] = registry.add("ReAssocMC/hDCAAmbGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDBad)] = registry.add("ReAssocMC/hDCAAmbBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkAmbID)] = registry.add("ReAssocMC/hDCANonAmbAllE", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkAmbIDGood)] = registry.add("ReAssocMC/hDCANonAmbGoodE", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkAmbIDBad)] = registry.add("ReAssocMC/hDCANonAmbBadE", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtra)] = registry.add("ReAssocMC/hDCANonAmbIDExtra", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraGood)] = registry.add("ReAssocMC/hDCANonAmbIDExtraGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraBad)] = registry.add("ReAssocMC/hDCANonAmbIDExtraBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssoc)] = registry.add("ReAssocMC/hDCAReAssoc", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocGood)] = registry.add("ReAssocMC/hDCAReAssocGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompTrue)] = registry.add("ReAssocMC/hDCAReAssocGoodIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompFalse)] = registry.add("ReAssocMC/hDCAReAssocGoodIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocBad)] = registry.add("ReAssocMC/hDCAReAssocBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompTrue)] = registry.add("ReAssocMC/hDCAReAssocBadIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompFalse)] = registry.add("ReAssocMC/hDCAReAssocBadIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssoc)] = registry.add("ReAssocMC/hDCAAssoc", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocGood)] = registry.add("ReAssocMC/hDCAAssocGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompTrue)] = registry.add("ReAssocMC/hDCAAssocGoodIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompFalse)] = registry.add("ReAssocMC/hDCAAssocGoodIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocBad)] = registry.add("ReAssocMC/hDCAAssocBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocBadIsCompTrue)] = registry.add("ReAssocMC/hDCAAssocBadIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocBadIsCompFalse)] = registry.add("ReAssocMC/hDCAAssocBadIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm)", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkIdGt0)] = registry.add("ReAssocMC/hDCAIdGt0", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmb)] = registry.add("ReAssocMC/hDCANonAmbAll", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbGood)] = registry.add("ReAssocMC/hDCANonAmbGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbBad)] = registry.add("ReAssocMC/hDCANonAmbBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbID)] = registry.add("ReAssocMC/hDCAAmbAll", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDGood)] = registry.add("ReAssocMC/hDCAAmbGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDBad)] = registry.add("ReAssocMC/hDCAAmbBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkAmbID)] = registry.add("ReAssocMC/hDCANonAmbAllE", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkAmbIDGood)] = registry.add("ReAssocMC/hDCANonAmbGoodE", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkAmbIDBad)] = registry.add("ReAssocMC/hDCANonAmbBadE", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtra)] = registry.add("ReAssocMC/hDCANonAmbIDExtra", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraGood)] = registry.add("ReAssocMC/hDCANonAmbIDExtraGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraBad)] = registry.add("ReAssocMC/hDCANonAmbIDExtraBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssoc)] = registry.add("ReAssocMC/hDCAReAssoc", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocGood)] = registry.add("ReAssocMC/hDCAReAssocGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompTrue)] = registry.add("ReAssocMC/hDCAReAssocGoodIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompFalse)] = registry.add("ReAssocMC/hDCAReAssocGoodIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocBad)] = registry.add("ReAssocMC/hDCAReAssocBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompTrue)] = registry.add("ReAssocMC/hDCAReAssocBadIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompFalse)] = registry.add("ReAssocMC/hDCAReAssocBadIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssoc)] = registry.add("ReAssocMC/hDCAAssoc", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocGood)] = registry.add("ReAssocMC/hDCAAssocGood", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompTrue)] = registry.add("ReAssocMC/hDCAAssocGoodIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompFalse)] = registry.add("ReAssocMC/hDCAAssocGoodIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocBad)] = registry.add("ReAssocMC/hDCAAssocBad", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocBadIsCompTrue)] = registry.add("ReAssocMC/hDCAAssocBadIsCompTrue", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocBadIsCompFalse)] = registry.add("ReAssocMC/hDCAAssocBadIsCompFalse", ";#it{p}_{T}^{reco} (GeV/#it{c});#it{#eta}^{reco};DCA_{XY} (cm)^{reco}; DCA_{Z} (cm)^{reco}; DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", HistType::kTHnSparseF, {ptAxis, etaAxis, dcaxyAxis, dcazAxis, dcaxyAxis, dcazAxis, centralityAxis, occupancyAxis}); } if (doprocessEfficiencyInclusive) { @@ -1446,33 +1453,33 @@ struct DndetaMFTPbPb { registry.add({"AmbTracks/hVtxzMCrec", " ; Z_{vtx} (cm)", {HistType::kTH1F, {zAxis}}}); registry.add({"AmbTracks/DCAXY", " ; DCA_{XY} (cm)", {HistType::kTH1F, {dcaxyAxis}}}); - registry.add({"AmbTracks/DCAZ", " ; DCA_{Z} (cm)", {HistType::kTH1F, {dcazAxis}}}); + registry.add({"AmbTracks/DCAZ", " ; DCA_{Z} (cm); centrality; occupancy", {HistType::kTH1F, {dcazAxis}}}); registry.add({"AmbTracks/DCAXYBest", " ; DCA_{XY} (cm)", {HistType::kTH1F, {dcaxyAxis}}}); - registry.add({"AmbTracks/DCAZBest", " ; DCA_{Z} (cm)", {HistType::kTH1F, {dcazAxis}}}); + registry.add({"AmbTracks/DCAZBest", " ; DCA_{Z} (cm); centrality; occupancy", {HistType::kTH1F, {dcazAxis}}}); registry.add({"AmbTracks/DCAXYBestPrim", " ; DCA_{XY} (cm)", {HistType::kTH1F, {dcaxyAxis}}}); - registry.add({"AmbTracks/DCAZBestPrim", " ; DCA_{Z} (cm)", {HistType::kTH1F, {dcazAxis}}}); + registry.add({"AmbTracks/DCAZBestPrim", " ; DCA_{Z} (cm); centrality; occupancy", {HistType::kTH1F, {dcazAxis}}}); registry.add({"AmbTracks/DCAXYBestTrue", " ; DCA_{XY} (cm)", {HistType::kTH1F, {dcaxyAxis}}}); - registry.add({"AmbTracks/DCAZBestTrue", " ; DCA_{Z} (cm)", {HistType::kTH1F, {dcazAxis}}}); + registry.add({"AmbTracks/DCAZBestTrue", " ; DCA_{Z} (cm); centrality; occupancy", {HistType::kTH1F, {dcazAxis}}}); registry.add({"AmbTracks/DCAXYBestFalse", " ; DCA_{XY} (cm)", {HistType::kTH1F, {dcaxyAxis}}}); - registry.add({"AmbTracks/DCAZBestFalse", " ; DCA_{Z} (cm)", {HistType::kTH1F, {dcazAxis}}}); + registry.add({"AmbTracks/DCAZBestFalse", " ; DCA_{Z} (cm); centrality; occupancy", {HistType::kTH1F, {dcazAxis}}}); registry.add({"AmbTracks/DCAXYBestTrueOrigAssoc", " ; DCA_{XY} (cm)", {HistType::kTH1F, {dcaxyAxis}}}); registry.add({"AmbTracks/DCAXYBestTrueOrigReAssoc", " ; DCA_{XY} (cm)", {HistType::kTH1F, {dcaxyAxis}}}); - registry.add({"AmbTracks/DCAZBestTrueOrigAssoc", " ; DCA_{Z} (cm)", {HistType::kTH1F, {dcazAxis}}}); - registry.add({"AmbTracks/DCAZBestTrueOrigReAssoc", " ; DCA_{Z} (cm)", {HistType::kTH1F, {dcazAxis}}}); + registry.add({"AmbTracks/DCAZBestTrueOrigAssoc", " ; DCA_{Z} (cm); centrality; occupancy", {HistType::kTH1F, {dcazAxis}}}); + registry.add({"AmbTracks/DCAZBestTrueOrigReAssoc", " ; DCA_{Z} (cm); centrality; occupancy", {HistType::kTH1F, {dcazAxis}}}); - registry.add({"AmbTracks/Centrality/THnDCAxyBestGen", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); - registry.add({"AmbTracks/Centrality/THnDCAxyBestGenPrim", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); - registry.add({"AmbTracks/Centrality/THnDCAxyBestTrue", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); - registry.add({"AmbTracks/Centrality/THnDCAxyBestFalse", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); - registry.add({"AmbTracks/Centrality/THnDCAxyBestTrueOrigAssoc", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); - registry.add({"AmbTracks/Centrality/THnDCAxyBestTrueOrigReAssoc", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); + registry.add({"AmbTracks/Centrality/THnDCAxyBestGen", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); + registry.add({"AmbTracks/Centrality/THnDCAxyBestGenPrim", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); + registry.add({"AmbTracks/Centrality/THnDCAxyBestTrue", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); + registry.add({"AmbTracks/Centrality/THnDCAxyBestFalse", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); + registry.add({"AmbTracks/Centrality/THnDCAxyBestTrueOrigAssoc", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); + registry.add({"AmbTracks/Centrality/THnDCAxyBestTrueOrigReAssoc", "; p_{T} (GeV/c); #eta; Z_{vtx} (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", {HistType::kTHnSparseF, {ptAxis, etaAxis, zAxis, dcaxyAxis, dcazAxis, centralityAxis}}}); - registry.add({"AmbTracks/BestGenDxyz", "; #Delta X (cm); #Delta Y (cm); #Delta Z (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {deltaZAxis, deltaZAxis, deltaZAxis, dcaxyAxis, dcazAxis}}}); - registry.add({"AmbTracks/BestPrimDxyz", "; #Delta X (cm); #Delta Y (cm); #Delta Z (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {deltaZAxis, deltaZAxis, deltaZAxis, dcaxyAxis, dcazAxis}}}); - registry.add({"AmbTracks/BestTrueDxyz", "; #Delta X (cm); #Delta Y (cm); #Delta Z (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {deltaZAxis, deltaZAxis, deltaZAxis, dcaxyAxis, dcazAxis}}}); - registry.add({"AmbTracks/BestFalseDxyz", "; #Delta X (cm); #Delta Y (cm); #Delta Z (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {deltaZAxis, deltaZAxis, deltaZAxis, dcaxyAxis, dcazAxis}}}); - registry.add({"AmbTracks/BestTrueOrigReAssocDxyz", "; #Delta X (cm); #Delta Y (cm); #Delta Z (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {deltaZAxis, deltaZAxis, deltaZAxis, dcaxyAxis, dcazAxis}}}); - registry.add({"AmbTracks/BestTrueOrigAssocDxyz", "; #Delta X (cm); #Delta Y (cm); #Delta Z (cm); DCA_{XY} (cm); DCA_{Z} (cm)", {HistType::kTHnSparseF, {deltaZAxis, deltaZAxis, deltaZAxis, dcaxyAxis, dcazAxis}}}); + registry.add({"AmbTracks/BestGenDxyz", "; #Delta X (cm); #Delta Y (cm); #Delta Z (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", {HistType::kTHnSparseF, {deltaZAxis, deltaZAxis, deltaZAxis, dcaxyAxis, dcazAxis}}}); + registry.add({"AmbTracks/BestPrimDxyz", "; #Delta X (cm); #Delta Y (cm); #Delta Z (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", {HistType::kTHnSparseF, {deltaZAxis, deltaZAxis, deltaZAxis, dcaxyAxis, dcazAxis}}}); + registry.add({"AmbTracks/BestTrueDxyz", "; #Delta X (cm); #Delta Y (cm); #Delta Z (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", {HistType::kTHnSparseF, {deltaZAxis, deltaZAxis, deltaZAxis, dcaxyAxis, dcazAxis}}}); + registry.add({"AmbTracks/BestFalseDxyz", "; #Delta X (cm); #Delta Y (cm); #Delta Z (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", {HistType::kTHnSparseF, {deltaZAxis, deltaZAxis, deltaZAxis, dcaxyAxis, dcazAxis}}}); + registry.add({"AmbTracks/BestTrueOrigReAssocDxyz", "; #Delta X (cm); #Delta Y (cm); #Delta Z (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", {HistType::kTHnSparseF, {deltaZAxis, deltaZAxis, deltaZAxis, dcaxyAxis, dcazAxis}}}); + registry.add({"AmbTracks/BestTrueOrigAssocDxyz", "; #Delta X (cm); #Delta Y (cm); #Delta Z (cm); DCA_{XY} (cm); DCA_{Z} (cm); centrality; occupancy", {HistType::kTHnSparseF, {deltaZAxis, deltaZAxis, deltaZAxis, dcaxyAxis, dcazAxis}}}); } if (doprocessEventAndSignalLossCentFT0C) { @@ -1739,6 +1746,31 @@ struct DndetaMFTPbPb { return stdev; } + /// \brief check good rec vertex of corresponding mc coll is available in compatible rec coll + template + bool isRecInCompColl(AT atrack) + { + auto const& ids = atrack.compatibleCollIds(); + bool isInCoColl = false; + if (atrack.ambDegree() != 0) { + const int mcCollId = atrack.mcParticle().mcCollisionId(); + if (!ids.empty()) { + for (auto const& id : ids) { + auto itMcCollId = mapMcCollIdPerRecColl.find(id); + if (itMcCollId != mapMcCollIdPerRecColl.end()) { + if (itMcCollId->second == mcCollId) { + isInCoColl = true; + return isInCoColl; + } + } else { + return isInCoColl; + } + } + } + } + return isInCoColl; + } + void initCCDB(ExtBCs::iterator const& bc) { if (mRunNumber == bc.runNumber()) { @@ -2126,6 +2158,9 @@ struct DndetaMFTPbPb { if (gConf.cfgUsePrimaries && !particle.isPhysicalPrimary()) { return false; } + if (!gConf.cfgUsePrimaries && (gConf.cfgUseSecondaries && particle.isPhysicalPrimary())) { + return false; + } if (particle.eta() < trackCuts.minEta || particle.eta() > trackCuts.maxEta) { return false; } @@ -4530,8 +4565,8 @@ struct DndetaMFTPbPb { PROCESS_SWITCH(DndetaMFTPbPb, processAssocMC, "Process collision-association information, requires extra table from TrackToCollisionAssociation task (fillTableOfCollIdsPerTrack=true)", false); - template - void processReAssocMC(CollisionsWithMCLabels const& collisions, + template + void processReAssocMC(typename soa::Join const& collisions, B const& besttracks, FiltMcMftTracksWColls const& /*tracks*/, aod::McCollisions const& /*mcCollisions*/, @@ -4540,6 +4575,33 @@ struct DndetaMFTPbPb { { const auto& nRecoColls = collisions.size(); registry.fill(HIST("ReAssocMC/hNReAssocRecoColls"), 1.f, nRecoColls); + + float cGen = -1; + if constexpr (has_reco_cent) { + float crecMin = 105.f; + for (const auto& collision : collisions) { + if (isGoodEvent(collision)) { + float c = getRecoCent(collision); + if (c < crecMin) { + crecMin = c; + } + } + } + if (cGen < 0) + cGen = crecMin; + } + float occGen = -1.; + for (const auto& collision : collisions) { + if (isGoodEvent(collision)) { + float o = getOccupancy(collision, eventCuts.occupancyEstimator); + if (o > occGen) { + occGen = o; + } + } + } + + registry.fill(HIST("ReAssocMC/EvtGenRecReassoc"), 1., cGen, occGen); + if (nRecoColls > CintZero) { mapVtxXrec.clear(); mapVtxYrec.clear(); @@ -4565,14 +4627,23 @@ struct DndetaMFTPbPb { int nNoMC{0}; for (const auto& collision : collisions) { - registry.fill(HIST("ReAssocMC/hReAssocMCEventStatus"), static_cast(ReAssocMCEventStatus::kEvtReAsAll)); + auto occ = getOccupancy(collision, eventCuts.occupancyEstimator); + float crec = getRecoCent(collision); + + registry.fill(HIST("ReAssocMC/EvtGenRecReassoc"), 2., crec, occ); + registry.fill(HIST("ReAssocMC/hReAssocMCEventStatus"), static_cast(ReAssocMCEventStatus::kEvtReAsAll), crec, occ); + if (!isGoodEvent(collision)) { continue; } - registry.fill(HIST("ReAssocMC/hReAssocMCEventStatus"), static_cast(ReAssocMCEventStatus::kEvtReAsSelected)); + + registry.fill(HIST("ReAssocMC/EvtGenRecReassoc"), 3., crec, occ); + registry.fill(HIST("ReAssocMC/hReAssocMCEventStatus"), static_cast(ReAssocMCEventStatus::kEvtReAsSelected), crec, occ); + if (!collision.has_mcCollision()) { continue; } + int64_t recCollId = collision.globalIndex(); auto itMC = mapMcCollIdPerRecColl.find(recCollId); if (itMC == mapMcCollIdPerRecColl.end()) { @@ -4580,49 +4651,51 @@ struct DndetaMFTPbPb { continue; } - registry.fill(HIST("ReAssocMC/hReAssocMCEventStatus"), static_cast(ReAssocMCEventStatus::kEvtReAsHasMcColl)); + registry.fill(HIST("ReAssocMC/hReAssocMCEventStatus"), static_cast(ReAssocMCEventStatus::kEvtReAsHasMcColl), crec, occ); auto mcColl = collision.template mcCollision_as(); if (gConf.cfgRemoveSplitVertex && (bestCollIndex != collision.globalIndex())) { continue; } - registry.fill(HIST("ReAssocMC/hReAssocMCEventStatus"), static_cast(ReAssocMCEventStatus::kEvtReAsSplitVtxRemoved)); + registry.fill(HIST("ReAssocMC/hReAssocMCEventStatus"), static_cast(ReAssocMCEventStatus::kEvtReAsSplitVtxRemoved), crec, occ); if (eventCuts.useZVtxCutMC && (std::abs(mcColl.posZ()) >= eventCuts.maxZvtx)) { continue; } - registry.fill(HIST("ReAssocMC/hReAssocMCEventStatus"), static_cast(ReAssocMCEventStatus::kEvtReAsZVtxCutMC)); + registry.fill(HIST("ReAssocMC/hReAssocMCEventStatus"), static_cast(ReAssocMCEventStatus::kEvtReAsZVtxCutMC), crec, occ); for (auto const& atrack : besttracks) { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkReAssocAll)); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkReAssocAll), crec, occ); if (!isBestTrackSelected(atrack)) { continue; } - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkBestSel)); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkBestSel), crec, occ); const float bestDcaZ = getDCAz(atrack); auto itrack = atrack.template mfttrack_as(); if (!isTrackSelected(itrack)) { continue; } - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkSel)); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkSel), crec, occ); if (!itrack.has_collision()) { continue; } - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkHasColl)); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkHasColl), crec, occ); if (gConf.cfgRemoveReassigned) { if (itrack.collisionId() != atrack.bestCollisionId()) { continue; } } - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkReassignedRemoved)); - if (gConf.cfgRemoveOrphanTracks && atrack.compatibleCollIds().empty()) { + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkReassignedRemoved), crec, occ); + + auto ids = atrack.compatibleCollIds(); + if (gConf.cfgRemoveOrphanTracks && ids.empty()) { continue; } if (gConf.cfgRemoveTrivialAssoc) { - if (atrack.compatibleCollIds().empty() || (atrack.compatibleCollIds().size() == 1 && itrack.collisionId() == atrack.compatibleCollIds()[0])) { + if (ids.empty() || (ids.size() == 1 && itrack.collisionId() == ids[0])) { continue; } } - if (gConf.cfgRemoveAmbiguousTracks && (atrack.compatibleCollIds().size() != 1)) { + if (gConf.cfgRemoveAmbiguousTracks && (ids.size() != 1)) { continue; } if (itrack.collisionId() >= 0 && itrack.has_mcParticle() && itrack.mcMask() == 0) { @@ -4634,35 +4707,41 @@ struct DndetaMFTPbPb { if (gConf.cfgUseParticleSel && !isParticleSelected(particle)) { continue; } - auto collision = itrack.template collision_as(); + // auto collision = itrack.template collision_as(); float deltaX = -999.f; float deltaY = -999.f; float deltaZ = -999.f; - if (mapVtxXrec.find(atrack.bestCollisionId()) == mapVtxXrec.end()) { + auto vtxXtruth = atrack.mcParticle().mcCollision().posX(); + auto vtxYtruth = atrack.mcParticle().mcCollision().posY(); + auto vtxZtruth = atrack.mcParticle().mcCollision().posZ(); + + const int bestRecColl = atrack.bestCollisionId(); + auto itMapVtxXrec = mapVtxXrec.find(bestRecColl); + auto itMapVtxYrec = mapVtxYrec.find(bestRecColl); + auto itMapVtxZrec = mapVtxZrec.find(bestRecColl); + auto itMapMcCollIdPerRecColl = mapMcCollIdPerRecColl.find(bestRecColl); + + if (itMapVtxXrec == mapVtxXrec.end()) { continue; } - if (mapVtxYrec.find(atrack.bestCollisionId()) == mapVtxYrec.end()) { + if (itMapVtxYrec == mapVtxYrec.end()) { continue; } - if (mapVtxZrec.find(atrack.bestCollisionId()) == mapVtxZrec.end()) { + if (itMapVtxZrec == mapVtxZrec.end()) { continue; } - if (mapMcCollIdPerRecColl.find(atrack.bestCollisionId()) == mapMcCollIdPerRecColl.end()) { + if (itMapMcCollIdPerRecColl == mapMcCollIdPerRecColl.end()) { continue; } - const float vtxXbest = mapVtxXrec.find(atrack.bestCollisionId())->second; - const float vtxYbest = mapVtxYrec.find(atrack.bestCollisionId())->second; - const float vtxZbest = mapVtxZrec.find(atrack.bestCollisionId())->second; + const float vtxXbest = itMapVtxXrec->second; + const float vtxYbest = itMapVtxYrec->second; + const float vtxZbest = itMapVtxZrec->second; // LOGP(info, "\t ---> \t .... \t vtxZrec: {} - collision.posZ(): {}", vtxZrec, collision.posZ()); - const float mcCollIdRec = mapMcCollIdPerRecColl.find(atrack.bestCollisionId())->second; + const float mcCollIdRec = itMapMcCollIdPerRecColl->second; // LOGP(info, "\t ---> \t .... \t mcCollIdRec: {} - bestMCCol: {}", mcCollIdRec, bestMCCol); - auto vtxXtruth = atrack.mcParticle().mcCollision().posX(); - auto vtxYtruth = atrack.mcParticle().mcCollision().posY(); - auto vtxZtruth = atrack.mcParticle().mcCollision().posZ(); - deltaX = vtxXbest - vtxXtruth; deltaY = vtxYbest - vtxYtruth; deltaZ = vtxZbest - vtxZtruth; @@ -4672,145 +4751,128 @@ struct DndetaMFTPbPb { const auto dcaZtruth(particle.vz() - particle.mcCollision().posZ()); auto dcaXYtruth = std::sqrt(dcaXtruth * dcaXtruth + dcaYtruth * dcaYtruth); - // check good rec vertex of corresponding mc coll is available in compatible rec coll - auto const& ids = atrack.compatibleCollIds(); - bool isInCoColl = false; - if (atrack.ambDegree() != 0) { - const int mcCollId = atrack.mcParticle().mcCollisionId(); - if (!ids.empty()) { - for (auto const& id : ids) { - auto itMcCollId = mapMcCollIdPerRecColl.find(id); - if (itMcCollId != mapMcCollIdPerRecColl.end()) { - if (itMcCollId->second == mcCollId) { - isInCoColl = true; - break; - } - } - } - } - } - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkHasMcPart)); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkHasMcPart), crec, occ); if (ids.size() > 0) { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkIdGt0)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkIdGt0)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkIdGt0)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkIdGt0), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkIdGt0)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkIdGt0)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth, crec, occ); if (ids.size() == 1) { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmb)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmb)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmb)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmb), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmb)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmb)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth, crec, occ); if (collision.mcCollisionId() == particle.mcCollisionId()) { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbGood)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbGood)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbGood)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbGood), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbGood)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbGood)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth, crec, occ); } else { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbBad)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbBad)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbBad)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbBad), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbBad)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbBad)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth, crec, occ); } if (itrack.collisionId() == ids[0]) { // non ambiguous - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbID)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbID)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbID)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbID), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbID)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbID)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth, crec, occ); if (collision.mcCollisionId() == particle.mcCollisionId()) { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbIDGood)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDGood)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDGood)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbIDGood), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDGood)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDGood)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth, crec, occ); } else { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbIDBad)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDBad)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDBad)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbIDBad), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDBad)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDBad)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth, crec, occ); } } else if (itrack.collisionId() != ids[0]) { // ambiguous extra - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkAmbID)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkAmbID)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkAmbID)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkAmbID), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkAmbID)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkAmbID)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); if (collision.mcCollisionId() == particle.mcCollisionId()) { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkAmbIDGood)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkAmbIDGood)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkAmbIDGood)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkAmbIDGood), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkAmbIDGood)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkAmbIDGood)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); } else { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkAmbIDBad)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkAmbIDBad)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkAmbIDBad)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkAmbIDBad), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkAmbIDBad)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkAmbIDBad)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); } } else { // non ambiguous (extra) - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbIDExtra)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtra)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtra)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbIDExtra), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtra)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtra)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth, crec, occ); if (collision.mcCollisionId() == particle.mcCollisionId()) { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbIDExtraGood)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraGood)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraGood)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbIDExtraGood), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraGood)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraGood)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth, crec, occ); } else { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbIDExtraBad)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraBad)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraBad)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kTrkNonAmbIDExtraBad), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraBad)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kTrkNonAmbIDExtraBad)]->Fill(itrack.pt(), itrack.eta(), 0., 0., dcaXYtruth, dcaZtruth, crec, occ); } } } else { // ambiguous if (!itrack.has_collision()) { continue; } else if (itrack.collisionId() != atrack.bestCollisionId()) { // re-associated - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kReAssoc)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssoc)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssoc)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kReAssoc), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssoc)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssoc)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); if (collision.has_mcCollision() && mcCollIdRec == particle.mcCollisionId()) { // good coll - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kReAssocGood)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocGood)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocGood)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); - if (isInCoColl) { // coll vertex is among compatible colls - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kReAssocGoodIsCompTrue)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kReAssocGood), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocGood)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocGood)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); + if (isRecInCompColl(atrack)) { // coll vertex is among compatible colls + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kReAssocGoodIsCompTrue), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); } else { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kReAssocGoodIsCompFalse)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kReAssocGoodIsCompFalse), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocGoodIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); } } else { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kReAssocBad)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocBad)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocBad)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); - if (isInCoColl) { // coll vertex is among compatible colls - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kReAssocBadIsCompTrue)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kReAssocBad), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocBad)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocBad)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); + if (isRecInCompColl(atrack)) { // coll vertex is among compatible colls + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kReAssocBadIsCompTrue), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); } else { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kReAssocBadIsCompFalse)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kReAssocBadIsCompFalse), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kReAssocBadIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); } } } else { // associated - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kAssoc)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssoc)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssoc)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kAssoc), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssoc)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssoc)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); if (collision.has_mcCollision() && mcCollIdRec == particle.mcCollisionId()) { // good coll - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kAssocGood)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocGood)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocGood)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); - if (isInCoColl) { // coll vertex is among compatible colls - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kAssocGoodIsCompTrue)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kAssocGood), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocGood)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocGood)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); + if (isRecInCompColl(atrack)) { // coll vertex is among compatible colls + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kAssocGoodIsCompTrue), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); } else { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kAssocGoodIsCompFalse)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kAssocGoodIsCompFalse), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocGoodIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); } } else { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kAssocBad)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocBad)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocBad)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); - if (isInCoColl) { // coll vertex is among compatible colls - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kAssocBadIsCompTrue)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocBadIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocBadIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kAssocBad), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocBad)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocBad)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); + if (isRecInCompColl(atrack)) { // coll vertex is among compatible colls + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kAssocBadIsCompTrue), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocBadIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocBadIsCompTrue)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); } else { - registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kAssocBadIsCompFalse)); - hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocBadIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ); - hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocBadIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth); + registry.fill(HIST("ReAssocMC/hReAssocMCTrackStatus"), static_cast(ReAssocMCTrackStatus::kAssocBadIsCompFalse), crec, occ); + hReAssocVtxRes[static_cast(HistStatusReAssocVtx::kAssocBadIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), deltaX, deltaY, deltaZ, crec, occ); + hReAssocDCA[static_cast(HistStatusReAssocVtx::kAssocBadIsCompFalse)]->Fill(itrack.pt(), itrack.eta(), atrack.bestDCAXY(), bestDcaZ, dcaXYtruth, dcaZtruth, crec, occ); } } } @@ -4827,23 +4889,23 @@ struct DndetaMFTPbPb { } } - void processReAssoc2dMC(CollisionsWithMCLabels const& collisions, + void processReAssoc2dMC(soa::Join const& collisions, BestTracks2dWCollsMC const& besttracks, FiltMcMftTracksWColls const& tracks, aod::McCollisions const& mcCollisions, aod::McParticles const& particles) { - processReAssocMC(collisions, besttracks, tracks, mcCollisions, particles); + processReAssocMC(collisions, besttracks, tracks, mcCollisions, particles); } PROCESS_SWITCH(DndetaMFTPbPb, processReAssoc2dMC, "Process re-association information based on BestCollisionsFwd (2D) table", false); - void processReAssoc3dMC(CollisionsWithMCLabels const& collisions, + void processReAssoc3dMC(soa::Join const& collisions, BestTracks3dWCollsMC const& besttracks, FiltMcMftTracksWColls const& tracks, aod::McCollisions const& mcCollisions, aod::McParticles const& particles) { - processReAssocMC(collisions, besttracks, tracks, mcCollisions, particles); + processReAssocMC(collisions, besttracks, tracks, mcCollisions, particles); } PROCESS_SWITCH(DndetaMFTPbPb, processReAssoc3dMC, "Process re-association information based on BestCollisionsFwd3d (3D) table", true); diff --git a/PWGMM/UE/Tasks/uecharged.cxx b/PWGMM/UE/Tasks/uecharged.cxx index 8fef7ee4a8b..6e95a27e6db 100644 --- a/PWGMM/UE/Tasks/uecharged.cxx +++ b/PWGMM/UE/Tasks/uecharged.cxx @@ -13,7 +13,6 @@ /// \file uecharged.cxx /// \brief Underlying event analysis task /// \since November 2021 -/// \last update: April 2026 #include "PWGLF/Utils/inelGt.h" @@ -21,6 +20,7 @@ #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/McCollisionExtra.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -62,6 +62,7 @@ struct ueCharged { Configurable removeITSROFBorder{"event_removeITSROFBorder", false, "Remove ITS Read-Out Frame border and only apply kIsTriggerTVX & kNoTimeFrameBorder (recommended for MC)"}; Configurable cfgINELCut{"event_cfgINELCut", 0, "INEL event selection: 0 no sel, 1 INEL>0, 2 INEL>1"}; Configurable CollPosZ{"event_CollPosZ", 10.f, "Cut on the z component of the vertex position"}; + Configurable GoodITS{"event_GoodITS", true, "Numbers of inactive chips on all ITS layers are below maximum allowed values"}; Configurable analyzeEvandTracksel{"analyzeEvandTracksel", true, "Analyze the event and track selection"}; // Track selection configurables @@ -72,16 +73,16 @@ struct ueCharged { Configurable minPt{"trkcfg_minPt", 0.1f, "Set minimum pT of tracks"}; Configurable maxPt{"trkcfg_maxPt", 1e10f, "Set maximum pT of tracks"}; Configurable requireEta{"trkcfg_requireEta", 0.8f, "Set eta range of tracks"}; - Configurable requireITSRefit{"trkcfg_requireITSRefit", true, "Additional cut on the ITS requirement"}; - Configurable requireTPCRefit{"trkcfg_requireTPCRefit", true, "Additional cut on the TPC requirement"}; Configurable requireGoldenChi2{"trkcfg_requireGoldenChi2", true, "Additional cut on the GoldenChi2"}; Configurable maxChi2PerClusterTPC{"trkcfg_maxChi2PerClusterTPC", 4.f, "Additional cut on the maximum value of the chi2 per cluster in the TPC"}; Configurable maxChi2PerClusterITS{"trkcfg_maxChi2PerClusterITS", 36.f, "Additional cut on the maximum value of the chi2 per cluster in the ITS"}; - // Configurable minITSnClusters{"trkcfg_minITSnClusters", 5, "minimum number of found ITS clusters"}; Configurable minNCrossedRowsTPC{"trkcfg_minNCrossedRowsTPC", 70.f, "Additional cut on the minimum number of crossed rows in the TPC"}; - Configurable minNCrossedRowsOverFindableClustersTPC{"trkcfg_minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; Configurable maxDcaXYFactor{"trkcfg_maxDcaXYFactor", 1.f, "Multiplicative factor on the maximum value of the DCA xy"}; Configurable maxDcaZ{"trkcfg_maxDcaZ", 0.1f, "Additional cut on the maximum value of the DCA z"}; + // Configurable requireITSRefit{"trkcfg_requireITSRefit", true, "Additional cut on the ITS requirement"}; + // Configurable requireTPCRefit{"trkcfg_requireTPCRefit", true, "Additional cut on the TPC requirement"}; + // Configurable minNCrossedRowsOverFindableClustersTPC{"trkcfg_minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; + // Configurable minITSnClusters{"trkcfg_minITSnClusters", 5, "minimum number of found ITS clusters"}; Service pdg; @@ -94,6 +95,7 @@ struct ueCharged { using TrackMCTrueTable = aod::McParticles; // reconstructed collisions associated to MC collisions (small groups keyed by mcCollisionId) + using ColMCTrueTableWithExtra = soa::Join; using ColMCRecTable = soa::SmallGroups>; using TrackMCRecTable = soa::Join; using FilTrackMCRecTable = soa::Filtered; @@ -138,17 +140,17 @@ struct ueCharged { myTrkSel = getGlobalTrackSelectionRun3ITSMatch(setITSreq.value); myTrkSel.SetPtRange(minPt.value, maxPt.value); myTrkSel.SetEtaRange(-requireEta.value, requireEta.value); - myTrkSel.SetRequireITSRefit(requireITSRefit.value); - myTrkSel.SetRequireTPCRefit(requireTPCRefit.value); myTrkSel.SetRequireGoldenChi2(requireGoldenChi2.value); myTrkSel.SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC.value); myTrkSel.SetMaxChi2PerClusterITS(maxChi2PerClusterITS.value); - // myTrkSel.SetMinNClustersITS(minITSnClusters.value); myTrkSel.SetMinNCrossedRowsTPC(minNCrossedRowsTPC.value); - myTrkSel.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC.value); - // myTrkSel.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / pow(pt, 1.1f); }); myTrkSel.SetMaxDcaXYPtDep([](float /*pt*/) { return 10000.f; }); myTrkSel.SetMaxDcaZ(maxDcaZ.value); + // myTrkSel.SetRequireITSRefit(requireITSRefit.value); + // myTrkSel.SetRequireTPCRefit(requireTPCRefit.value); + // myTrkSel.SetMinNClustersITS(minITSnClusters.value); + // myTrkSel.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC.value); + // myTrkSel.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / pow(pt, 1.1f); }); myTrkSel.print(); } @@ -214,7 +216,7 @@ struct ueCharged { ue.add("vtxZEta", ";#eta;vtxZ", HistType::kTH2F, {{50, -2.5, 2.5, " "}, {60, -30, 30, " "}}); ue.add("phiEta", ";#eta;#varphi", HistType::kTH2F, {{50, -2.5, 2.5}, {200, 0., 2 * o2::constants::math::PI, " "}}); ue.add("hvtxZ", "vtxZ", HistType::kTH1F, {{40, -20.0, 20.0, " "}}); - ue.add("hCounter", "Counter; sel; Nev", HistType::kTH1D, {{7, 0, 7, " "}}); + ue.add("hCounter", "Counter; sel; Nev", HistType::kTH1D, {{8, 0, 8, " "}}); ue.add("hPtLeadingRecPS", "rec pTleading after physics selection", HistType::kTH1D, {ptAxist}); ue.add("hPtLeadingMeasured", "measured pTleading after physics selection", HistType::kTH1D, {ptAxist}); ue.add("hPtLeadingVsTracks", "", HistType::kTProfile, {{ptAxist}}); @@ -226,6 +228,7 @@ struct ueCharged { h->GetXaxis()->SetBinLabel(4, "NoSameBunchPileup"); h->GetXaxis()->SetBinLabel(5, "IsGoodZvtxFT0vsPV"); h->GetXaxis()->SetBinLabel(6, "posZ passed"); + h->GetXaxis()->SetBinLabel(7, "GoodITSLayersAll"); for (int i = 0; i < 3; ++i) { ue.add(pNumDenMeasuredPS[i].data(), "Number Density; ; #LT #it{N}_{trk} #GT", HistType::kTProfile, {ptAxist}); @@ -252,6 +255,8 @@ struct ueCharged { ue.add("hEtaLeadingVsPtLeading", " ", HistType::kTH2D, {{ptAxist}, {50, -2.5, 2.5, "#eta"}}); if (analyzeEvandTracksel) { + ue.add("hPtVsDCAxy", " ", HistType::kTH2D, {{ptAxis}, {225, -0.6, 0.6, "#it{DCA}_{xy} (cm)"}}); + ue.add("hPtVsDCAz", " ", HistType::kTH2D, {{ptAxis}, {225, -0.6, 0.6, "#it{DCA}_{z} (cm)"}}); const AxisSpec axisVtxZ{500, -25., 25., ""}; ue.add("hVtxFT0VsVtxCol", " ", HistType::kTH2D, {{axisVtxZ}, {axisVtxZ}}); ue.add("hVtxFT0VsVtxCol_afterSel8", " ", HistType::kTH2D, {{axisVtxZ}, {axisVtxZ}}); @@ -422,8 +427,14 @@ struct ueCharged { if ((std::abs(collision.posZ()) > CollPosZ)) { return false; } - ue.fill(HIST("hCounter"), 5); + + if (GoodITS && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + return false; + } + + ue.fill(HIST("hCounter"), 6); + return true; } @@ -470,6 +481,12 @@ struct ueCharged { } ue.fill(HIST("hCounter"), 5); + + if (GoodITS && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + return false; + } + + ue.fill(HIST("hCounter"), 6); return true; } @@ -652,7 +669,7 @@ struct ueCharged { } PROCESS_SWITCH(ueCharged, processData, "Process data", false); - void processMC(ColMCTrueTable::iterator const& mcCollision, + void processMC(ColMCTrueTableWithExtra::iterator const& mcCollision, ColMCRecTable const& RecCols, TrackMCTrueTable const& GenParticles, TrackMCRecTable const& RecTracks, @@ -672,20 +689,20 @@ struct ueCharged { ue.fill(HIST("hStat"), mcCollision.size()); const auto vtxZ = mcCollision.posZ(); - // pick best reconstructed collision associated to this mcCollision (max ntracks = recRow.size()) + // pick best reconstructed collision associated to this mcCollision using bestCollisionIndex bool foundRec = false; auto chosenRec = *RecCols.begin(); int64_t chosenRecGlobalIndex = -1; - int maxTracks = -1; - if (RecCols.size() != 0) { + int bestCollIdx = mcCollision.bestCollisionIndex(); + if (bestCollIdx >= 0) { + // Find the reconstructed collision with this index for (const auto& recRow : RecCols) { - int ntracks = recRow.size(); - if (ntracks > maxTracks) { + if (recRow.globalIndex() == bestCollIdx) { chosenRec = recRow; - chosenRecGlobalIndex = recRow.globalIndex(); - maxTracks = ntracks; + chosenRecGlobalIndex = bestCollIdx; foundRec = true; + break; } } } @@ -1154,12 +1171,17 @@ struct ueCharged { ue.fill(HIST("hvtxZ_after"), collision.posZ()); + if (!isMCEventSelected(collision)) + return; + int tracks_before = 0; int tracks_after = 0; for (auto& track : tracks) { if (track.hasITS() && track.hasTPC()) { + ue.fill(HIST("hPtVsDCAxy"), track.pt(), track.dcaXY()); + ue.fill(HIST("hPtVsDCAz"), track.pt(), track.dcaZ()); ue.fill(HIST("preselection_track/ITS/itsNCls"), track.itsNCls()); ue.fill(HIST("preselection_track/ITS/itsChi2NCl"), track.itsChi2NCl()); ue.fill(HIST("preselection_track/ITS/itsClusterMap"), track.itsClusterMap()); diff --git a/PWGUD/Core/UDHelpers.h b/PWGUD/Core/UDHelpers.h index 94d356501a7..ac3c5cf8b18 100644 --- a/PWGUD/Core/UDHelpers.h +++ b/PWGUD/Core/UDHelpers.h @@ -130,7 +130,7 @@ T compatibleBCs(B const& bc, uint64_t const& meanBC, int const& deltaBC, T const // check [min,max]BC to overlap with [bcs.iteratorAt([0,bcs.size() - 1]) if (maxBC < bcs.iteratorAt(0).globalBC() || minBC > bcs.iteratorAt(bcs.size() - 1).globalBC()) { LOGF(debug, " No overlap of [%d, %d] and [%d, %d]", minBC, maxBC, bcs.iteratorAt(0).globalBC(), bcs.iteratorAt(bcs.size() - 1).globalBC()); - return T{{bcs.asArrowTable()->Slice(0, 0)}, static_cast(0)}; + return bcs.emptySlice(); } // find slice of BCs table with BC in [minBC, maxBC] @@ -164,7 +164,7 @@ T compatibleBCs(B const& bc, uint64_t const& meanBC, int const& deltaBC, T const } // create bc slice - T bcslice{{bcs.asArrowTable()->Slice(minBCId, maxBCId - minBCId + 1)}, static_cast(minBCId)}; + auto bcslice = bcs.rawSlice(minBCId, maxBCId - minBCId + 1); bcs.copyIndexBindings(bcslice); LOGF(debug, " size of slice %d", bcslice.size()); return bcslice; @@ -179,7 +179,7 @@ T compatibleBCs(C const& collision, int ndt, T const& bcs, int nMinBCs = 7) // return if collisions has no associated BC if (!collision.has_foundBC() || ndt < 0) { - return T{{bcs.asArrowTable()->Slice(0, 0)}, static_cast(0)}; + return bcs.emptySlice(); } // get associated BC @@ -220,7 +220,7 @@ T MCcompatibleBCs(F const& collision, int const& ndt, T const& bcs, int const& n // return if collisions has no associated BC if (!collision.has_foundBC()) { LOGF(debug, "Collision %i - no BC found!", collision.globalIndex()); - return T{{bcs.asArrowTable()->Slice(0, 0)}, static_cast(0)}; + return bcs.emptySlice(); } // get associated BC diff --git a/PWGUD/Core/decayTree.cxx b/PWGUD/Core/decayTree.cxx index ded7c2fa329..a96156c0f9c 100644 --- a/PWGUD/Core/decayTree.cxx +++ b/PWGUD/Core/decayTree.cxx @@ -12,6 +12,7 @@ #include "decayTree.h" #include +#include #include #include @@ -1228,4 +1229,162 @@ std::vector> decayTree::combinations(int nPool) return copes; } +void decayTree::createHistograms(o2::framework::HistogramRegistry& registry) +{ + // definitions + auto etax = o2::framework::AxisSpec(100, -1.5, 1.5); + auto nSax = o2::framework::AxisSpec(300, -15.0, 15.0); + auto chi2ax = o2::framework::AxisSpec(100, 0.0, 5.0); + auto nClax = o2::framework::AxisSpec(170, 0.0, 170.0); + auto angax = o2::framework::AxisSpec(315, 0.0, 3.15); + auto dcaxyax = o2::framework::AxisSpec(400, -0.2, 0.2); + auto dcazax = o2::framework::AxisSpec(600, -0.3, 0.3); + auto sTPCax = o2::framework::AxisSpec(1000, 0., 1000.); + + std::string base; + std::string hname; + std::string annot; + fhistPointers.clear(); + for (const auto& res : getResonances()) { + auto max = o2::framework::AxisSpec(res->nmassBins(), res->massHistRange()[0], res->massHistRange()[1]); + auto momax = o2::framework::AxisSpec(res->nmomBins(), res->momHistRange()[0], res->momHistRange()[1]); + + // M-pT, M-eta, pT-eta + for (const auto& cc : fccs) { + base = cc; + base.append("/").append(res->name()).append("/"); + hname = base + "mpt"; + annot = "M versus pT; M (" + res->name() + ") GeV/c^{2}; pT (" + res->name() + ") GeV/c"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, momax}})}); + hname = base + "meta"; + annot = "M versus eta; M (" + res->name() + ") GeV/c^{2}; eta (" + res->name() + ")"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, etax}})}); + hname = base + "pteta"; + annot = "pT versus eta; pT (" + res->name() + ") GeV/c; eta (" + res->name() + ")"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {momax, etax}})}); + + // M versus daughters + auto daughs = res->getDaughters(); + auto ndaughs = daughs.size(); + for (auto i = 0; i < static_cast(ndaughs); i++) { + auto d1 = getResonance(daughs[i]); + + // M vs pT daughter + hname = base; + hname.append("MvspT_").append(res->name()).append(d1->name()); + annot = "M versus pT; M (" + res->name() + ") GeV/c^{2}; pT (" + d1->name() + ") GeV/c"; + auto momax1 = o2::framework::AxisSpec(d1->nmomBins(), d1->momHistRange()[0], d1->momHistRange()[1]); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, momax1}})}); + + // M vs eta daughter + hname = base; + hname.append("Mvseta_").append(res->name()).append(d1->name()); + annot = "M versus eta; M (" + res->name() + ") GeV/c^{2}; eta (" + d1->name() + ")"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, etax}})}); + + if (d1->isFinal()) { + // M vs dcaXYZ + hname = base; + hname.append("MvsdcaXY_").append(res->name()).append(d1->name()); + annot = "M versus dcaXY; M (" + res->name() + ") GeV/c^{2}; dca_{XY} (" + d1->name() + ") #mu m"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, dcaxyax}})}); + hname = base; + hname.append("MvsdcaZ_").append(res->name()).append(d1->name()); + annot = "M versus dcaZ; M (" + res->name() + ") GeV/c^{2}; dca_{Z} (" + d1->name() + ") #mu m"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, dcazax}})}); + + // M vs chi2 track + hname = base; + hname.append("Mvschi2_").append(res->name()).append(d1->name()); + annot = "M versus chi2; M (" + res->name() + ") GeV/c^{2}; chi2 (" + d1->name() + ")"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, chi2ax}})}); + + // M vs nCl track + hname = base; + hname.append("MvsnCl_").append(res->name()).append(d1->name()); + annot = "M versus nCl; M (" + res->name() + ") GeV/c^{2}; nCl (" + d1->name() + ")"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, nClax}})}); + + // M versus detector hits + hname = base; + hname.append("MvsdetHits_").append(res->name()).append(d1->name()); + annot = "M versus detector hits; M (" + res->name() + ") GeV/c^{2}; ITS + 2*TPC + 4*TRD + 8*TOF (" + d1->name() + ")"; + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, {16, -0.5, 15.5}}})}); + } else { + // M vs Mi + hname = base; + hname.append("MvsM_").append(res->name()).append(d1->name()); + annot = "M versus M; M (" + res->name() + ") GeV/c^{2}; M (" + d1->name() + ") GeV/c^{2}"; + auto max1 = o2::framework::AxisSpec(res->nmassBins(), d1->massHistRange()[0], d1->massHistRange()[1]); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, max1}})}); + } + } + + // daughters vs daughters + for (auto i = 0; i < static_cast(ndaughs - 1); i++) { + auto d1 = getResonance(daughs[i]); + auto max1 = o2::framework::AxisSpec(d1->nmassBins(), d1->massHistRange()[0], d1->massHistRange()[1]); + for (auto j = i + 1; j < static_cast(ndaughs); j++) { + auto d2 = getResonance(daughs[j]); + auto max2 = o2::framework::AxisSpec(d2->nmassBins(), d2->massHistRange()[0], d2->massHistRange()[1]); + + // M1 vs M2 + hname = base; + hname.append("MvsM_").append(d1->name()).append(d2->name()); + annot = std::string("M versus M; M (").append(d1->name()).append(") GeV/c^{2}; M (").append(d2->name()).append(") GeV/c^{2}"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max1, max2}})}); + + // angle(d1, d2) + hname = base; + hname.append("angle_").append(d1->name()).append(d2->name()); + annot = std::string("angle; Angle (").append(d1->name()).append(", ").append(d2->name()).append(")"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {angax}})}); + + // M vs angle(d1, d2) + hname = base; + hname.append("Mvsangle_").append(d1->name()).append(d2->name()); + annot = std::string("M versus angle; M (").append(res->name()).append(") GeV/c^{2}; Angle (").append(d1->name()).append(", ").append(d2->name()).append(")"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, angax}})}); + + // both daughters are finals + if (d1->isFinal() && d2->isFinal()) { + hname = base; + hname.append("TPCsignal_").append(d1->name()).append(d2->name()); + annot = std::string("TPC signal of both tracks; TPCsignal (").append(d1->name()).append("); TPCsignal (").append(d2->name()).append(")"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {sTPCax, sTPCax}})}); + } + } + } + + // for finals only + if (res->isFinal()) { + // dca + hname = base; + hname.append("dcaXY"); + annot = std::string("dcaXY; dca_{XY}(").append(res->name()).append(")"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {dcaxyax}})}); + hname = base; + hname.append("dcaZ"); + annot = std::string("dcaZ; dca_{Z}(").append(res->name()).append(")"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {dcazax}})}); + + // nSIgma[TPC, TOF] vs pT + for (const auto& det : fdets) { + for (const auto& part : fparts) { + hname = base; + hname.append("nS").append(part).append(det); + annot = std::string("nSigma_").append(det).append(" versus p; p (").append(res->name()).append(") GeV/c; nSigma_{").append(det).append(", ").append(part).append("} (").append(res->name()).append(")"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {momax, nSax}})}); + } + } + + // detector hits + hname = base; + hname.append("detectorHits"); + annot = std::string("detectorHits; Detector(").append(res->name()).append(")"); + fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {{4, 0.5, 4.5}}})}); + } + } + } +} // ----------------------------------------------------------------------------- diff --git a/PWGUD/Core/decayTree.h b/PWGUD/Core/decayTree.h index 162a1859181..05cd97968c0 100644 --- a/PWGUD/Core/decayTree.h +++ b/PWGUD/Core/decayTree.h @@ -12,7 +12,6 @@ #ifndef PWGUD_CORE_DECAYTREE_H_ #define PWGUD_CORE_DECAYTREE_H_ -#include #include #include @@ -29,6 +28,11 @@ #include #include +namespace o2::framework +{ +class HistogramRegistry; +} + // ----------------------------------------------------------------------------- class pidSelector { @@ -835,164 +839,7 @@ class decayTree } // create histograms - void createHistograms(o2::framework::HistogramRegistry& registry) - { - // definitions - auto etax = o2::framework::AxisSpec(100, -1.5, 1.5); - auto nSax = o2::framework::AxisSpec(300, -15.0, 15.0); - auto chi2ax = o2::framework::AxisSpec(100, 0.0, 5.0); - auto nClax = o2::framework::AxisSpec(170, 0.0, 170.0); - auto angax = o2::framework::AxisSpec(315, 0.0, 3.15); - auto dcaxyax = o2::framework::AxisSpec(400, -0.2, 0.2); - auto dcazax = o2::framework::AxisSpec(600, -0.3, 0.3); - auto sTPCax = o2::framework::AxisSpec(1000, 0., 1000.); - - std::string base; - std::string hname; - std::string annot; - fhistPointers.clear(); - for (const auto& res : getResonances()) { - auto max = o2::framework::AxisSpec(res->nmassBins(), res->massHistRange()[0], res->massHistRange()[1]); - auto momax = o2::framework::AxisSpec(res->nmomBins(), res->momHistRange()[0], res->momHistRange()[1]); - - // M-pT, M-eta, pT-eta - for (const auto& cc : fccs) { - base = cc; - base.append("/").append(res->name()).append("/"); - hname = base + "mpt"; - annot = "M versus pT; M (" + res->name() + ") GeV/c^{2}; pT (" + res->name() + ") GeV/c"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, momax}})}); - hname = base + "meta"; - annot = "M versus eta; M (" + res->name() + ") GeV/c^{2}; eta (" + res->name() + ")"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, etax}})}); - hname = base + "pteta"; - annot = "pT versus eta; pT (" + res->name() + ") GeV/c; eta (" + res->name() + ")"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {momax, etax}})}); - - // M versus daughters - auto daughs = res->getDaughters(); - auto ndaughs = daughs.size(); - for (auto i = 0; i < static_cast(ndaughs); i++) { - auto d1 = getResonance(daughs[i]); - - // M vs pT daughter - hname = base; - hname.append("MvspT_").append(res->name()).append(d1->name()); - annot = "M versus pT; M (" + res->name() + ") GeV/c^{2}; pT (" + d1->name() + ") GeV/c"; - auto momax1 = o2::framework::AxisSpec(d1->nmomBins(), d1->momHistRange()[0], d1->momHistRange()[1]); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, momax1}})}); - - // M vs eta daughter - hname = base; - hname.append("Mvseta_").append(res->name()).append(d1->name()); - annot = "M versus eta; M (" + res->name() + ") GeV/c^{2}; eta (" + d1->name() + ")"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, etax}})}); - - if (d1->isFinal()) { - // M vs dcaXYZ - hname = base; - hname.append("MvsdcaXY_").append(res->name()).append(d1->name()); - annot = "M versus dcaXY; M (" + res->name() + ") GeV/c^{2}; dca_{XY} (" + d1->name() + ") #mu m"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, dcaxyax}})}); - hname = base; - hname.append("MvsdcaZ_").append(res->name()).append(d1->name()); - annot = "M versus dcaZ; M (" + res->name() + ") GeV/c^{2}; dca_{Z} (" + d1->name() + ") #mu m"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, dcazax}})}); - - // M vs chi2 track - hname = base; - hname.append("Mvschi2_").append(res->name()).append(d1->name()); - annot = "M versus chi2; M (" + res->name() + ") GeV/c^{2}; chi2 (" + d1->name() + ")"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, chi2ax}})}); - - // M vs nCl track - hname = base; - hname.append("MvsnCl_").append(res->name()).append(d1->name()); - annot = "M versus nCl; M (" + res->name() + ") GeV/c^{2}; nCl (" + d1->name() + ")"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, nClax}})}); - - // M versus detector hits - hname = base; - hname.append("MvsdetHits_").append(res->name()).append(d1->name()); - annot = "M versus detector hits; M (" + res->name() + ") GeV/c^{2}; ITS + 2*TPC + 4*TRD + 8*TOF (" + d1->name() + ")"; - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, {16, -0.5, 15.5}}})}); - } else { - // M vs Mi - hname = base; - hname.append("MvsM_").append(res->name()).append(d1->name()); - annot = "M versus M; M (" + res->name() + ") GeV/c^{2}; M (" + d1->name() + ") GeV/c^{2}"; - auto max1 = o2::framework::AxisSpec(res->nmassBins(), d1->massHistRange()[0], d1->massHistRange()[1]); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, max1}})}); - } - } - - // daughters vs daughters - for (auto i = 0; i < static_cast(ndaughs - 1); i++) { - auto d1 = getResonance(daughs[i]); - auto max1 = o2::framework::AxisSpec(d1->nmassBins(), d1->massHistRange()[0], d1->massHistRange()[1]); - for (auto j = i + 1; j < static_cast(ndaughs); j++) { - auto d2 = getResonance(daughs[j]); - auto max2 = o2::framework::AxisSpec(d2->nmassBins(), d2->massHistRange()[0], d2->massHistRange()[1]); - - // M1 vs M2 - hname = base; - hname.append("MvsM_").append(d1->name()).append(d2->name()); - annot = std::string("M versus M; M (").append(d1->name()).append(") GeV/c^{2}; M (").append(d2->name()).append(") GeV/c^{2}"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max1, max2}})}); - - // angle(d1, d2) - hname = base; - hname.append("angle_").append(d1->name()).append(d2->name()); - annot = std::string("angle; Angle (").append(d1->name()).append(", ").append(d2->name()).append(")"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {angax}})}); - - // M vs angle(d1, d2) - hname = base; - hname.append("Mvsangle_").append(d1->name()).append(d2->name()); - annot = std::string("M versus angle; M (").append(res->name()).append(") GeV/c^{2}; Angle (").append(d1->name()).append(", ").append(d2->name()).append(")"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {max, angax}})}); - - // both daughters are finals - if (d1->isFinal() && d2->isFinal()) { - hname = base; - hname.append("TPCsignal_").append(d1->name()).append(d2->name()); - annot = std::string("TPC signal of both tracks; TPCsignal (").append(d1->name()).append("); TPCsignal (").append(d2->name()).append(")"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {sTPCax, sTPCax}})}); - } - } - } - - // for finals only - if (res->isFinal()) { - // dca - hname = base; - hname.append("dcaXY"); - annot = std::string("dcaXY; dca_{XY}(").append(res->name()).append(")"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {dcaxyax}})}); - hname = base; - hname.append("dcaZ"); - annot = std::string("dcaZ; dca_{Z}(").append(res->name()).append(")"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {dcazax}})}); - - // nSIgma[TPC, TOF] vs pT - for (const auto& det : fdets) { - for (const auto& part : fparts) { - hname = base; - hname.append("nS").append(part).append(det); - annot = std::string("nSigma_").append(det).append(" versus p; p (").append(res->name()).append(") GeV/c; nSigma_{").append(det).append(", ").append(part).append("} (").append(res->name()).append(")"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH2F, {momax, nSax}})}); - } - } - - // detector hits - hname = base; - hname.append("detectorHits"); - annot = std::string("detectorHits; Detector(").append(res->name()).append(")"); - fhistPointers.insert({hname, registry.add(hname.c_str(), annot.c_str(), {o2::framework::HistType::kTH1F, {{4, 0.5, 4.5}}})}); - } - } - } - } + void createHistograms(o2::framework::HistogramRegistry& registry); // ClassDefNV(decayTree, 1); }; diff --git a/PWGUD/TableProducer/DGBCCandProducer.cxx b/PWGUD/TableProducer/DGBCCandProducer.cxx index eb272397af3..cf62e50c84d 100644 --- a/PWGUD/TableProducer/DGBCCandProducer.cxx +++ b/PWGUD/TableProducer/DGBCCandProducer.cxx @@ -468,11 +468,11 @@ struct DGBCCandProducer { auto fwdTracksArray = ftibcSlice.begin().fwdtrack_as(); isDG = dgSelector.IsSelected(diffCuts, bcRange, tracksArray, fwdTracksArray); } else { - auto fwdTracksArray = FTCs{{fwdtracks.asArrowTable()->Slice(0, 0)}, (uint64_t)0}; + auto fwdTracksArray = fwdtracks.emptySlice(); isDG = dgSelector.IsSelected(diffCuts, bcRange, tracksArray, fwdTracksArray); } } else { - auto fwdTracksArray = FTCs{{fwdtracks.asArrowTable()->Slice(0, 0)}, (uint64_t)0}; + auto fwdTracksArray = fwdtracks.emptySlice(); isDG = dgSelector.IsSelected(diffCuts, bcRange, tracksArray, fwdTracksArray); } @@ -514,11 +514,11 @@ struct DGBCCandProducer { auto fwdTracksArray = ftibcPart.begin().fwdtrack_as(); isDG = dgSelector.IsSelected(diffCuts, bcRange, tracksArray, fwdTracksArray); } else { - auto fwdTracksArray = FTCs{{fwdtracks.asArrowTable()->Slice(0, 0)}, (uint64_t)0}; + auto fwdTracksArray = fwdtracks.emptySlice(); isDG = dgSelector.IsSelected(diffCuts, bcRange, tracksArray, fwdTracksArray); } } else { - auto fwdTracksArray = FTCs{{fwdtracks.asArrowTable()->Slice(0, 0)}, (uint64_t)0}; + auto fwdTracksArray = fwdtracks.emptySlice(); isDG = dgSelector.IsSelected(diffCuts, bcRange, tracksArray, fwdTracksArray); } @@ -683,11 +683,11 @@ struct DGBCCandProducer { auto fwdTracksArray = ftibc.fwdtrack_as(); isDG2 = dgSelector.IsSelected(diffCuts, bcRange, tracksArray, fwdTracksArray); } else { - auto fwdTracksArray = FTCs{{fwdtracks.asArrowTable()->Slice(0, 0)}, (uint64_t)0}; + auto fwdTracksArray = fwdtracks.emptySlice(); isDG2 = dgSelector.IsSelected(diffCuts, bcRange, tracksArray, fwdTracksArray); } } else { - auto fwdTracksArray = FTCs{{fwdtracks.asArrowTable()->Slice(0, 0)}, (uint64_t)0}; + auto fwdTracksArray = fwdtracks.emptySlice(); isDG2 = dgSelector.IsSelected(diffCuts, bcRange, tracksArray, fwdTracksArray); } diff --git a/PWGUD/Tasks/CMakeLists.txt b/PWGUD/Tasks/CMakeLists.txt index 2fb8fa5fbf9..0b4af02e173 100644 --- a/PWGUD/Tasks/CMakeLists.txt +++ b/PWGUD/Tasks/CMakeLists.txt @@ -14,7 +14,7 @@ o2physics_add_dpl_workflow(upc-polarisation-jpsi-incoh PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(upc +o2physics_add_dpl_workflow(upc-analysis SOURCES upcAnalysis.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase COMPONENT_NAME Analysis) @@ -99,17 +99,17 @@ o2physics_add_dpl_workflow(diff-qa PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::DGCutparHolder COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(dgcand-analyzer +o2physics_add_dpl_workflow(dg-cand-analyzer SOURCES dgCandAnalyzer.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::DGCutparHolder O2Physics::UDGoodRunSelector O2Physics::DGPIDSelector O2Physics::UDFSParser COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(upccand-analyzer +o2physics_add_dpl_workflow(upc-cand-analyzer SOURCES upcCandidateAnalyzer.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(upccand-producer-qa +o2physics_add_dpl_workflow(upc-cand-producer-qa SOURCES upcCandidateProducerQa.cpp PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase COMPONENT_NAME Analysis) @@ -119,7 +119,7 @@ o2physics_add_dpl_workflow(upc-mft PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::ReconstructionDataFormats O2::DetectorsBase O2::DetectorsCommonDataFormats COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(upc-veto +o2physics_add_dpl_workflow(upc-veto-analysis SOURCES upcVetoAnalysis.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase COMPONENT_NAME Analysis) @@ -214,8 +214,8 @@ o2physics_add_dpl_workflow(upc-semi-fwd-jpsi-rl PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::DGPIDSelector COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(upc-event-itsrof-counter - SOURCES upcEventITSROFcounter.cxx +o2physics_add_dpl_workflow(upc-event-its-rof-counter + SOURCES upcEventItsRofCounter.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::AnalysisCCDB COMPONENT_NAME Analysis) @@ -244,8 +244,8 @@ o2physics_add_dpl_workflow(upc-quarkonia-central-barrel PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(test-mc-std-tabs-rl - SOURCES testMcStdTabsRl.cxx +o2physics_add_dpl_workflow(upc-test-mc-std-tabs-rl + SOURCES upcTestMcStdTabsRl.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::ReconstructionDataFormats O2::DetectorsBase O2::DetectorsCommonDataFormats COMPONENT_NAME Analysis) @@ -289,12 +289,17 @@ o2physics_add_dpl_workflow(sg-exclusive-jpsi-midrapidity PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(fitbit-mapping - SOURCES upcTestFITBitMapping.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(upc-vm-rof + SOURCES upcVmRof.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(upc-test-fit-bit-mapping + SOURCES upcTestFitBitMapping.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(pt-spectra-inclusive-upc - SOURCES ptSpectraInclusiveUpc.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES ptSpectraInclusiveUpc.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGUD/Tasks/fwdMuonsUpc.cxx b/PWGUD/Tasks/fwdMuonsUpc.cxx index 6057c47f4cb..e7c684064c6 100644 --- a/PWGUD/Tasks/fwdMuonsUpc.cxx +++ b/PWGUD/Tasks/fwdMuonsUpc.cxx @@ -20,7 +20,7 @@ #include "Common/Core/RecoDecay.h" -#include +#include #include #include #include @@ -32,11 +32,13 @@ #include #include -#include -#include +#include +#include // IWYU pragma: keep (do not replace with Math/Vector4Dfwd.h) +#include #include #include +#include #include #include #include diff --git a/PWGUD/Tasks/ptSpectraInclusiveUpc.cxx b/PWGUD/Tasks/ptSpectraInclusiveUpc.cxx index f4523ae3135..ce4feb743db 100644 --- a/PWGUD/Tasks/ptSpectraInclusiveUpc.cxx +++ b/PWGUD/Tasks/ptSpectraInclusiveUpc.cxx @@ -19,9 +19,7 @@ #include "PWGUD/DataModel/UDTables.h" #include "Common/Core/RecoDecay.h" -#include "Common/DataModel/EventSelection.h" -#include #include #include #include diff --git a/PWGUD/Tasks/upcEventITSROFcounter.cxx b/PWGUD/Tasks/upcEventItsRofCounter.cxx similarity index 94% rename from PWGUD/Tasks/upcEventITSROFcounter.cxx rename to PWGUD/Tasks/upcEventItsRofCounter.cxx index 22fb272efc9..6f13a3fc111 100644 --- a/PWGUD/Tasks/upcEventITSROFcounter.cxx +++ b/PWGUD/Tasks/upcEventItsRofCounter.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file upcEventITSROFcounter.cxx +/// \file upcEventItsRofCounter.cxx /// \brief Personal task to analyze tau events from UPC collisions /// /// \author Roman Lavicka , Austrian Academy of Sciences & SMI @@ -51,12 +51,15 @@ using BCsWithRun3Matchings = soa::Join; using FullSGUDCollision = soa::Join::iterator; -struct UpcEventITSROFcounter { +struct UpcEventItsRofCounter { Service ccdb; SGSelector sgSelector; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + static constexpr int NCollFillCount = 12; // upper bound of collision-count loop filling the per-ROF histograms (last value goes to overflow of 11-bin histos) + static constexpr int DoubleGapSide = 2; // SGSelector convention: 0=A-gap, 1=C-gap, 2=double-gap + Configurable nTracksForUPCevent{"nTracksForUPCevent", 16, {"Maximum of tracks defining a UPC collision"}}; Configurable useTrueGap{"useTrueGap", true, {"Calculate gapSide for a given FV0/FT0/ZDC thresholds"}}; @@ -158,7 +161,7 @@ struct UpcEventITSROFcounter { arrUPCcolls[nUpcCollsInROF]++; } // end loop over ITSROFs - for (int ncol = 0; ncol < 12; ncol++) { + for (int ncol = 0; ncol < NCollFillCount; ncol++) { histos.get(HIST("Events/hCountCollisionsInROFborderMatching"))->Fill(ncol, arrAllColls[ncol]); histos.get(HIST("Events/hCountUPCcollisionsInROFborderMatching"))->Fill(ncol, arrUPCcolls[ncol]); } @@ -198,7 +201,7 @@ struct UpcEventITSROFcounter { } if (coll.flags() == 0) { - if (gapSide == 2) { + if (gapSide == DoubleGapSide) { histos.get(HIST("Runs/hStdModeCollDG"))->Fill(coll.runNumber()); } else if (gapSide == 1) { histos.get(HIST("Runs/hStdModeCollSG1"))->Fill(coll.runNumber()); @@ -208,7 +211,7 @@ struct UpcEventITSROFcounter { histos.get(HIST("Runs/hStdModeCollNG"))->Fill(coll.runNumber()); } } else { - if (gapSide == 2) { + if (gapSide == DoubleGapSide) { histos.get(HIST("Runs/hUpcModeCollDG"))->Fill(coll.runNumber()); } else if (gapSide == 1) { histos.get(HIST("Runs/hUpcModeCollSG1"))->Fill(coll.runNumber()); @@ -220,12 +223,12 @@ struct UpcEventITSROFcounter { } } - PROCESS_SWITCH(UpcEventITSROFcounter, processCounterPerITSROF, "Counts number of collisions per ITSROF", false); - PROCESS_SWITCH(UpcEventITSROFcounter, processCounterPerRun, "Counts number of whatever per RUN", true); + PROCESS_SWITCH(UpcEventItsRofCounter, processCounterPerITSROF, "Counts number of collisions per ITSROF", false); + PROCESS_SWITCH(UpcEventItsRofCounter, processCounterPerRun, "Counts number of whatever per RUN", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc)}; } diff --git a/PWGUD/Tasks/upcTestFITBitMapping.cxx b/PWGUD/Tasks/upcTestFitBitMapping.cxx similarity index 83% rename from PWGUD/Tasks/upcTestFITBitMapping.cxx rename to PWGUD/Tasks/upcTestFitBitMapping.cxx index eefd4f0aa83..bcee34c60fc 100644 --- a/PWGUD/Tasks/upcTestFITBitMapping.cxx +++ b/PWGUD/Tasks/upcTestFitBitMapping.cxx @@ -9,14 +9,17 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -// \FIT bits to phi, eta mapping -// \author Sandor Lokos, sandor.lokos@cern.ch -// \since March 2026 + +/// \file upcTestFitBitMapping.cxx +/// \brief FIT bits to phi, eta mapping +/// \author Sandor Lokos, sandor.lokos@cern.ch +/// \since March 2026 #include "PWGUD/Core/UDHelpers.h" // udhelpers::Bits256, makeBits256, testBit, getPhiEtaFromFitBit #include "PWGUD/DataModel/UDTables.h" // aod::UDCollisionFITBits -#include // o2::ft0::Geometry +#include // o2::constants::math::TwoPI +#include // o2::ft0::Geometry #include #include #include @@ -25,15 +28,14 @@ #include #include -#include #include -#include - using namespace o2; using namespace o2::framework; -struct UpcTestFITBitMapping { +struct UpcTestFitBitMapping { + static constexpr int Thr2Selector = 2; // value of whichThr that selects the Thr2 bit set + Configurable whichThr{"whichThr", 1, "Use 1=Thr1 bits or 2=Thr2 bits"}; Configurable maxEvents{"maxEvents", -1, "Process at most this many rows (-1 = all)"}; @@ -53,13 +55,13 @@ struct UpcTestFITBitMapping { HistogramRegistry registry{ "registry", { - {"hPhiA", "FT0A #varphi;#varphi;counts", {HistType::kTH1F, {{18, 0.0, 2. * M_PI}}}}, + {"hPhiA", "FT0A #varphi;#varphi;counts", {HistType::kTH1F, {{18, 0.0, o2::constants::math::TwoPI}}}}, {"hEtaA", "FT0A #eta;#eta;counts", {HistType::kTH1F, {{8, 3.5, 5.0}}}}, - {"hEtaPhiA", "FT0A #eta vs #varphi;#eta;#varphi", {HistType::kTH2F, {{8, 3.5, 5.0}, {18, 0.0, 2. * M_PI}}}}, + {"hEtaPhiA", "FT0A #eta vs #varphi;#eta;#varphi", {HistType::kTH2F, {{8, 3.5, 5.0}, {18, 0.0, o2::constants::math::TwoPI}}}}, - {"hPhiC", "FT0C #varphi;#varphi;counts", {HistType::kTH1F, {{18, 0.0, 2. * M_PI}}}}, + {"hPhiC", "FT0C #varphi;#varphi;counts", {HistType::kTH1F, {{18, 0.0, o2::constants::math::TwoPI}}}}, {"hEtaC", "FT0C #eta;#eta;counts", {HistType::kTH1F, {{8, -3.5, -2.0}}}}, - {"hEtaPhiC", "FT0C #eta vs #varphi;#eta;#varphi", {HistType::kTH2F, {{8, -3.5, -2.0}, {18, 0.0, 2. * M_PI}}}}, + {"hEtaPhiC", "FT0C #eta vs #varphi;#eta;#varphi", {HistType::kTH2F, {{8, -3.5, -2.0}, {18, 0.0, o2::constants::math::TwoPI}}}}, }}; void init(InitContext&) @@ -80,7 +82,7 @@ struct UpcTestFITBitMapping { // Use udhelpers' canonical packed type + builder udhelpers::Bits256 w{}; - if (whichThr == 2) { + if (whichThr == Thr2Selector) { w = udhelpers::makeBits256(row.thr2W0(), row.thr2W1(), row.thr2W2(), row.thr2W3()); } else { w = udhelpers::makeBits256(row.thr1W0(), row.thr1W1(), row.thr1W2(), row.thr1W3()); @@ -115,5 +117,5 @@ struct UpcTestFITBitMapping { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc, TaskName{"fitbit-mapping"})}; + adaptAnalysisTask(cfgc)}; } diff --git a/PWGUD/Tasks/testMcStdTabsRl.cxx b/PWGUD/Tasks/upcTestMcStdTabsRl.cxx similarity index 96% rename from PWGUD/Tasks/testMcStdTabsRl.cxx rename to PWGUD/Tasks/upcTestMcStdTabsRl.cxx index 7651b5e5c2a..d5477c9240e 100644 --- a/PWGUD/Tasks/testMcStdTabsRl.cxx +++ b/PWGUD/Tasks/upcTestMcStdTabsRl.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -/// \file testMcStdTabsRl.cxx +/// \file upcTestMcStdTabsRl.cxx /// \brief task to test the Monte Carlo UD production generatorIDs on hyperloop /// /// \author Roman Lavicka , Austrian Academy of Sciences & SMI @@ -41,7 +41,7 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::constants::physics; -struct TestMcStdTabsRl { +struct UpcTestMcStdTabsRl { // Global varialbes Service pdg; @@ -103,11 +103,11 @@ struct TestMcStdTabsRl { } // end processMCgenDG - PROCESS_SWITCH(TestMcStdTabsRl, processMCgen, "Iterate Monte Carlo UD tables with truth data.", true); + PROCESS_SWITCH(UpcTestMcStdTabsRl, processMCgen, "Iterate Monte Carlo UD tables with truth data.", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; + adaptAnalysisTask(cfgc)}; } diff --git a/PWGUD/Tasks/upcVmRof.cxx b/PWGUD/Tasks/upcVmRof.cxx new file mode 100644 index 00000000000..2522f4ad23c --- /dev/null +++ b/PWGUD/Tasks/upcVmRof.cxx @@ -0,0 +1,709 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +/// \file upcVmRof.cxx +/// \brief analysis of UPC vector meson production ROF by ROF +/// +/// \author Guillermo Contreras (jesus.guillermo.contreras.nuno@cern.ch), Czech Technical University in Prague + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using BCsTSsSels = soa::Join; +using ColSels = soa::Join; +using TRKs = soa::Join; + +using ColSel = ColSels::iterator; + +namespace o2::aod +{ +namespace datarows +{ +// collision info +DECLARE_SOA_COLUMN(RunNumber, runNumber, int32_t); +DECLARE_SOA_COLUMN(PosX, posX, float); +DECLARE_SOA_COLUMN(PosY, posY, float); +DECLARE_SOA_COLUMN(PosZ, posZ, float); +DECLARE_SOA_COLUMN(Chi2, chi2, float); +DECLARE_SOA_COLUMN(LocalBC, localBC, int); +DECLARE_SOA_COLUMN(LocalTF, localTF, int); +DECLARE_SOA_COLUMN(LocalROF, localROF, int); +DECLARE_SOA_COLUMN(UpcFlag, upcFlag, int); + +// FIT info +DECLARE_SOA_COLUMN(AmplitudeFT0A, amplitudeFT0A, float); +DECLARE_SOA_COLUMN(AmplitudeFT0C, amplitudeFT0C, float); +DECLARE_SOA_COLUMN(AmplitudeFV0A, amplitudeFV0A, float); +DECLARE_SOA_COLUMN(AmplitudeFDDA, amplitudeFDDA, float); +DECLARE_SOA_COLUMN(AmplitudeFDDC, amplitudeFDDC, float); +DECLARE_SOA_COLUMN(TimeFT0A, timeFT0A, float); +DECLARE_SOA_COLUMN(TimeFT0C, timeFT0C, float); +DECLARE_SOA_COLUMN(TimeFV0A, timeFV0A, float); +DECLARE_SOA_COLUMN(TimeFDDA, timeFDDA, float); +DECLARE_SOA_COLUMN(TimeFDDC, timeFDDC, float); +DECLARE_SOA_COLUMN(ChannelsFT0A, channelsFT0A, int); +DECLARE_SOA_COLUMN(ChannelsFT0C, channelsFT0C, int); +DECLARE_SOA_COLUMN(ChannelsFV0A, channelsFV0A, int); +DECLARE_SOA_COLUMN(ChannelsFDDA, channelsFDDA, int); +DECLARE_SOA_COLUMN(ChannelsFDDC, channelsFDDC, int); + +// ZDC info +DECLARE_SOA_COLUMN(EnergyCommonZNA, energyCommonZNA, float); +DECLARE_SOA_COLUMN(EnergyCommonZNC, energyCommonZNC, float); +DECLARE_SOA_COLUMN(TimeZNA, timeZNA, float); +DECLARE_SOA_COLUMN(TimeZNC, timeZNC, float); + +// track info +DECLARE_SOA_COLUMN(Pt1, pt1, float); +DECLARE_SOA_COLUMN(Eta1, eta1, float); +DECLARE_SOA_COLUMN(Phi1, phi1, float); +DECLARE_SOA_COLUMN(Q1, q1, int); +DECLARE_SOA_COLUMN(PidPion1, pidPion1, float); +DECLARE_SOA_COLUMN(PidElectron1, pidElectron1, float); +DECLARE_SOA_COLUMN(PidKaon1, pidKaon1, float); +DECLARE_SOA_COLUMN(PidProton1, pidProton1, float); +DECLARE_SOA_COLUMN(Pt2, pt2, float); +DECLARE_SOA_COLUMN(Eta2, eta2, float); +DECLARE_SOA_COLUMN(Phi2, phi2, float); +DECLARE_SOA_COLUMN(Q2, q2, int); +DECLARE_SOA_COLUMN(PidPion2, pidPion2, float); +DECLARE_SOA_COLUMN(PidElectron2, pidElectron2, float); +DECLARE_SOA_COLUMN(PidKaon2, pidKaon2, float); +DECLARE_SOA_COLUMN(PidProton2, pidProton2, float); +DECLARE_SOA_COLUMN(Pt3, pt3, float); +DECLARE_SOA_COLUMN(Eta3, eta3, float); +DECLARE_SOA_COLUMN(Phi3, phi3, float); +DECLARE_SOA_COLUMN(Q3, q3, int); +DECLARE_SOA_COLUMN(PidPion3, pidPion3, float); +DECLARE_SOA_COLUMN(PidElectron3, pidElectron3, float); +DECLARE_SOA_COLUMN(PidKaon3, pidKaon3, float); +DECLARE_SOA_COLUMN(PidProton3, pidProton3, float); +DECLARE_SOA_COLUMN(Pt4, pt4, float); +DECLARE_SOA_COLUMN(Eta4, eta4, float); +DECLARE_SOA_COLUMN(Phi4, phi4, float); +DECLARE_SOA_COLUMN(Q4, q4, int); +DECLARE_SOA_COLUMN(PidPion4, pidPion4, float); +DECLARE_SOA_COLUMN(PidElectron4, pidElectron4, float); +DECLARE_SOA_COLUMN(PidKaon4, pidKaon4, float); +DECLARE_SOA_COLUMN(PidProton4, pidProton4, float); +} // namespace datarows + +DECLARE_SOA_TABLE(TwoTrkTable, "AOD", "TWOTRKTABLE", + datarows::RunNumber, datarows::PosX, datarows::PosY, datarows::PosZ, datarows::Chi2, + datarows::LocalBC, datarows::LocalTF, datarows::LocalROF, datarows::UpcFlag, + datarows::AmplitudeFT0A, datarows::AmplitudeFT0C, datarows::AmplitudeFV0A, datarows::AmplitudeFDDA, datarows::AmplitudeFDDC, + datarows::TimeFT0A, datarows::TimeFT0C, datarows::TimeFV0A, datarows::TimeFDDA, datarows::TimeFDDC, + datarows::ChannelsFT0A, datarows::ChannelsFT0C, datarows::ChannelsFV0A, datarows::ChannelsFDDA, datarows::ChannelsFDDC, + datarows::EnergyCommonZNA, datarows::EnergyCommonZNC, datarows::TimeZNA, datarows::TimeZNC, + datarows::Pt1, datarows::Eta1, datarows::Phi1, datarows::Q1, datarows::PidPion1, datarows::PidElectron1, datarows::PidKaon1, datarows::PidProton1, + datarows::Pt2, datarows::Eta2, datarows::Phi2, datarows::Q2, datarows::PidPion2, datarows::PidElectron2, datarows::PidKaon2, datarows::PidProton2); +DECLARE_SOA_TABLE(FourTrkTable, "AOD", "FOURTRKTABLE", + datarows::RunNumber, datarows::PosX, datarows::PosY, datarows::PosZ, datarows::Chi2, + datarows::LocalBC, datarows::LocalTF, datarows::LocalROF, datarows::UpcFlag, + datarows::AmplitudeFT0A, datarows::AmplitudeFT0C, datarows::AmplitudeFV0A, datarows::AmplitudeFDDA, datarows::AmplitudeFDDC, + datarows::TimeFT0A, datarows::TimeFT0C, datarows::TimeFV0A, datarows::TimeFDDA, datarows::TimeFDDC, + datarows::ChannelsFT0A, datarows::ChannelsFT0C, datarows::ChannelsFV0A, datarows::ChannelsFDDA, datarows::ChannelsFDDC, + datarows::EnergyCommonZNA, datarows::EnergyCommonZNC, datarows::TimeZNA, datarows::TimeZNC, + datarows::Pt1, datarows::Eta1, datarows::Phi1, datarows::Q1, datarows::PidPion1, datarows::PidElectron1, datarows::PidKaon1, datarows::PidProton1, + datarows::Pt2, datarows::Eta2, datarows::Phi2, datarows::Q2, datarows::PidPion2, datarows::PidElectron2, datarows::PidKaon2, datarows::PidProton2, + datarows::Pt3, datarows::Eta3, datarows::Phi3, datarows::Q3, datarows::PidPion3, datarows::PidElectron3, datarows::PidKaon3, datarows::PidProton3, + datarows::Pt4, datarows::Eta4, datarows::Phi4, datarows::Q4, datarows::PidPion4, datarows::PidElectron4, datarows::PidKaon4, datarows::PidProton4); +} // namespace o2::aod + +struct UpcVmRof { + + // output + Produces twoTrkTable; + Produces fourTrkTable; + + // services + Service ccdb; // access to database + + // histograms + HistogramRegistry bcTH1Registry{"bcTH1Registry", {}}; + std::map> bcTH1Pointers; + HistogramRegistry bcTH2Registry{"bcTH2Registry", {}}; + std::map> bcTH2Pointers; + HistogramRegistry colTH1Registry{"colTH1Registry", {}}; + std::map> colTH1Pointers; + + // variables to store filling scheme info + std::bitset beamPatternA; + std::bitset beamPatternC; + std::bitset bcPatternA; + std::bitset bcPatternB; + std::bitset bcPatternC; + + // constants related to ITS ROFs + static constexpr int RofPerOrbit = 6; // valid for pO, OO and PbPb in Run 3 + static constexpr int RofShift = 64; // bc shift of ITS. Valid for pO, OO and PbPb in Run 3 + + // variables to store run info + int runNumberBc = 0; // run number used to process BCs + int runNumberCol = 0; // run number used to process collisions + int64_t sor = 0; // best known timestamp for the start of run + int64_t orbitsPerTF = 0; // number of orbits per TF + int64_t bcSOR = 0; // first bc of the first orbit + int64_t nBCsPerTF = 0; // duration of TF in bcs + int64_t nBCsPerROF = 0; // number of bcs per ROF + int64_t currentTF = -1; // current time frame being looked at + int64_t nTF = 0; // number of time frames in run + + // constant related to trigger mask indices + // https://github.com/AliceO2Group/AliceO2/blob/6c0251c35e5cbf6028d2bd6f7e30f9a4fd348e38/DataFormats/Detectors/CTP/src/Configuration.cxx#L1123 + // PbPb triggers: 1ZNC, FV0CH+FT0VTX, OO: 1ZNC, FT0CE+FT0VTX + static constexpr int Ft0VtxIdx = 2; + static constexpr int Ft0CeIdx = 4; + + // number of tracks for the selected event topologies + static constexpr int NTrksTwoBody = 2; + static constexpr int NTrksFourBody = 4; + + // information for selection collisions + Configurable maxAbsPosZ{"maxAbsPosZ", 10.0, "max |Z| position of vtx"}; + Configurable maxAbsTimeFT0{"maxAbsTimeFT0", 4.0, "max |time| in a FT0 side"}; + Configurable maxAmpFT0{"maxAmpFT0", 150.0, "max amplitude for signals in a FT0 side"}; + Configurable maxTrkTpcChi2{"maxTrkTpcChi2", 4.0, "max chi2 of TPC track"}; + Configurable maxTrkItsChi2{"maxTrkItsChi2", 36.0, "max chi2 of ITS track"}; + Configurable minTrkTpcClusters{"minTrkTpcClusters", 70.0, "minimum number of TPC clusters associated to the track"}; + Configurable maxTrkDcaZ{"maxTrkDcaZ", 2.0, "max DCA in z of track to vtx (cm)"}; + Configurable tfPerBin{"tfPerBin", 10000, "timeframes per bin 1e4 means some 28 s"}; + + //-------------------------------------------------------------------------------- + // get filling scheme + void getFillingScheme() + { + auto grplhcif = ccdb->getForTimeStamp("GLO/Config/GRPLHCIF", sor); + beamPatternA = grplhcif->getBunchFilling().getBeamPattern(0); + beamPatternC = grplhcif->getBunchFilling().getBeamPattern(1); + bcPatternA = beamPatternA & ~beamPatternC; + bcPatternB = beamPatternA & beamPatternC; + bcPatternC = ~beamPatternA & beamPatternC; + } // end getFillingScheme() + + //-------------------------------------------------------------------------------- + // store bc patterns + void fillBcPatternHistos(int run) + { + for (int i = 0; i < o2::constants::lhc::LHCMaxBunches; i++) { + if (bcPatternA.test(i)) { + bcTH1Pointers[Form("bc/%d/bcPatternA_H", run)]->Fill(i); + } + if (bcPatternB.test(i)) { + bcTH1Pointers[Form("bc/%d/bcPatternB_H", run)]->Fill(i); + } + if (bcPatternC.test(i)) { + bcTH1Pointers[Form("bc/%d/bcPatternC_H", run)]->Fill(i); + } + } + } // end fillBcPatternHistos + + //-------------------------------------------------------------------------------- + // get general run information + void getRunInfo(int run) + { + auto runInfo = o2::parameters::AggregatedRunInfo::buildAggregatedRunInfo(ccdb->instance(), run); + sor = runInfo.sor; // in ms + auto orbitSOR = runInfo.orbitSOR; + auto orbitEOR = runInfo.orbitEOR; + orbitsPerTF = runInfo.orbitsPerTF; + nBCsPerROF = o2::constants::lhc::LHCMaxBunches / RofPerOrbit; + bcSOR = orbitSOR * o2::constants::lhc::LHCMaxBunches; // first bc of the first orbit + nBCsPerTF = orbitsPerTF * o2::constants::lhc::LHCMaxBunches; // duration of TF in bcs + nTF = std::ceil((orbitEOR - orbitSOR) / orbitsPerTF); + } // end getRunInfo() + + //-------------------------------------------------------------------------------- + // compute Bc within the orbit + int64_t getBcWithinOrbit(int64_t globalBC) + { + return (globalBC % o2::constants::lhc::LHCMaxBunches); + } + + //-------------------------------------------------------------------------------- + // compute TF for this BC + int64_t getTimeFrame(int64_t globalBC) + { + return (globalBC - bcSOR) / nBCsPerTF; + } + + //-------------------------------------------------------------------------------- + // compute ROF for this BC + int getRof(int64_t thisBC) + { + int64_t bctmp = thisBC - RofShift; + if (bctmp < 0) + bctmp = o2::constants::lhc::LHCMaxBunches - RofShift - 1; + return static_cast(bctmp / nBCsPerROF); + } + + //-------------------------------------------------------------------------------- + // check flags for a bc + bool checkBcFlags(const auto& bc, int run) + { + bcTH1Pointers[Form("bc/%d/bcSel_H", run)]->Fill(0); + if (!bc.selection_bit(aod::evsel::kNoTimeFrameBorder)) + return false; + bcTH1Pointers[Form("bc/%d/bcSel_H", run)]->Fill(1); + if (!bc.selection_bit(aod::evsel::kNoITSROFrameBorder)) + return false; + bcTH1Pointers[Form("bc/%d/bcSel_H", run)]->Fill(2); + return true; + } // end checkBcFlags + + //-------------------------------------------------------------------------------- + // check flags for a colllision + bool checkColFlags(const auto& col, int run) + { + colTH1Pointers[Form("col/%d/colSel_H", run)]->Fill(0); + if (!col.has_foundBC()) + return false; + colTH1Pointers[Form("col/%d/colSel_H", run)]->Fill(1); + if (!col.selection_bit(aod::evsel::kNoTimeFrameBorder)) + return false; + colTH1Pointers[Form("col/%d/colSel_H", run)]->Fill(2); + if (!col.selection_bit(aod::evsel::kNoITSROFrameBorder)) + return false; + colTH1Pointers[Form("col/%d/colSel_H", run)]->Fill(3); + if (!col.selection_bit(aod::evsel::kIsVertexITSTPC)) + return false; + colTH1Pointers[Form("col/%d/colSel_H", run)]->Fill(4); + if (!col.selection_bit(aod::evsel::kNoSameBunchPileup)) + return false; + colTH1Pointers[Form("col/%d/colSel_H", run)]->Fill(5); + // missing: add rct flags + return true; + } // end checkColFlags + + //-------------------------------------------------------------------------------- + // add histos used in processBCs + void addBcHistos(int run) + { + // check if histos already created + if (bcTH1Pointers[Form("bc/%d/bcPatternA_H", run)]) { + return; + } + + // filling scheme + bcTH1Pointers[Form("bc/%d/bcPatternA_H", run)] = bcTH1Registry.add(Form("bc/%d/bcPatternA_H", run), "Pattern of bc-A; bcID;", + {HistType::kTH1D, {{o2::constants::lhc::LHCMaxBunches, -0.5, static_cast(o2::constants::lhc::LHCMaxBunches) - 0.5}}}); + bcTH1Pointers[Form("bc/%d/bcPatternB_H", run)] = bcTH1Registry.add(Form("bc/%d/bcPatternB_H", run), "Pattern of bc-B; bcID;", + {HistType::kTH1D, {{o2::constants::lhc::LHCMaxBunches, -0.5, static_cast(o2::constants::lhc::LHCMaxBunches) - 0.5}}}); + bcTH1Pointers[Form("bc/%d/bcPatternC_H", run)] = bcTH1Registry.add(Form("bc/%d/bcPatternC_H", run), "Pattern of bc-C; bcID;", + {HistType::kTH1D, {{o2::constants::lhc::LHCMaxBunches, -0.5, static_cast(o2::constants::lhc::LHCMaxBunches) - 0.5}}}); + + // trigger info + bcTH1Pointers[Form("bc/%d/bcSel_H", run)] = bcTH1Registry.add(Form("bc/%d/bcSel_H", run), "bc selection counter; selID; Counter", + {HistType::kTH1D, {{4, -0.5, 3.5}}}); + bcTH1Pointers[Form("bc/%d/tf_H", run)] = bcTH1Registry.add(Form("bc/%d/tf_H", run), "analysed time frames;TF;Counts", + {HistType::kTH1D, {{static_cast(nTF / tfPerBin), -0.5, static_cast(nTF) - 0.5}}}); + bcTH2Pointers[Form("bc/%d/ft0Vtx_H", run)] = bcTH2Registry.add(Form("bc/%d/ft0Vtx_H", run), "ft0Vtx triggers; TF; ROF; Counter", + {HistType::kTH2F, {{static_cast(nTF / tfPerBin), -0.5, static_cast(nTF) - 0.5}, {RofPerOrbit, -0.5, RofPerOrbit - 0.5}}}); + bcTH2Pointers[Form("bc/%d/ft0VtxCe_H", run)] = bcTH2Registry.add(Form("bc/%d/ft0VtxCe_H", run), "ft0VtxCe triggers; TF; ROF; Counter", + {HistType::kTH2F, {{static_cast(nTF / tfPerBin), -0.5, static_cast(nTF) - 0.5}, {RofPerOrbit, -0.5, RofPerOrbit - 0.5}}}); + + } // addBcHistos + + //-------------------------------------------------------------------------------- + // add histos used in processBCs + void addColHistos(int run) + { + // check if histos already created + if (colTH1Pointers[Form("col/%d/colSel_H", run)]) { + return; + } + + // counters + colTH1Pointers[Form("col/%d/colSel_H", run)] = colTH1Registry.add(Form("col/%d/colSel_H", run), + "collision selection counter; selID; Counter", + {HistType::kTH1D, {{25, -0.5, 24.5}}}); + colTH1Pointers[Form("col/%d/trkSel_H", run)] = colTH1Registry.add(Form("col/%d/trkSel_H", run), + "track selection counter; selID; Counter", + {HistType::kTH1D, {{10, -0.5, 9.5}}}); + // track properties + colTH1Pointers[Form("col/%d/tpcChi2_H", run)] = colTH1Registry.add(Form("col/%d/tpcChi2_H", run), + "track #chi^2 in TPC; #chi^2; Entries", + {HistType::kTH1D, {{100, 0, 5}}}); + colTH1Pointers[Form("col/%d/itsChi2_H", run)] = colTH1Registry.add(Form("col/%d/itsChi2_H", run), + "track #chi^2 in ITS; #chi^2; Entries", + {HistType::kTH1D, {{120, 0, 40}}}); + colTH1Pointers[Form("col/%d/tpcNcls_H", run)] = colTH1Registry.add(Form("col/%d/tpcNcls_H", run), + "track clusters in TPC; n-clusters; Entries", + {HistType::kTH1D, {{160, 0, 160}}}); + colTH1Pointers[Form("col/%d/tpcXoF_H", run)] = colTH1Registry.add(Form("col/%d/tpcXoF_H", run), + "track crossed rows over findable TPC clusters; XoF; Entries", + {HistType::kTH1D, {{150, 0.5, 2.0}}}); + colTH1Pointers[Form("col/%d/trkDcaZ_H", run)] = colTH1Registry.add(Form("col/%d/trkDcaZ_H", run), + "track z-DCA; z-dca (cm); Entries", + {HistType::kTH1D, {{100, -0.5, 0.5}}}); + colTH1Pointers[Form("col/%d/trkDcaXY_H", run)] = colTH1Registry.add(Form("col/%d/trkDcaXY_H", run), + "track xy-DCA; xy-dca (cm); Entries", + {HistType::kTH1D, {{100, -0.1, 0.1}}}); + // selected events per TF + colTH1Pointers[Form("col/%d/twoTrkTF_H", run)] = colTH1Registry.add(Form("col/%d/twoTrkTF_H", run), "Number of selected 2-trk events per;TF;Entries", + {HistType::kTH1D, {{static_cast(nTF / tfPerBin), -0.5, static_cast(nTF) - 0.5}}}); + colTH1Pointers[Form("col/%d/fourTrkTF_H", run)] = colTH1Registry.add(Form("col/%d/fourTrkTF_H", run), "Number of selected 4-trk events per;TF;Entries", + {HistType::kTH1D, {{static_cast(nTF / tfPerBin), -0.5, static_cast(nTF) - 0.5}}}); + + } // addColHistos + + //-------------------------------------------------------------------------------- + // initialization + void init(InitContext&) + { + // set access to db + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + } // end init() + + //-------------------------------------------------------------------------------- + // process BCs to get trigger information + void processBCs(BCsTSsSels const& bcs) + { + // check if new run + // -- assuming that each call to processBCs involves only one run + const auto& bcAt0 = bcs.iteratorAt(0); + if (runNumberBc != bcAt0.runNumber()) { // new run + runNumberBc = bcAt0.runNumber(); + getRunInfo(runNumberBc); + addBcHistos(runNumberBc); + getFillingScheme(); + fillBcPatternHistos(runNumberBc); + } + + //-------------------------------------------------------------------------------- + for (const auto& bc : bcs) { + // get info for this bc + int64_t thisBC = getBcWithinOrbit(bc.globalBC()); + int64_t thisTF = getTimeFrame(bc.globalBC()); + int thisROF = getRof(thisBC); + + // count TF seen + if (thisTF != currentTF) { + currentTF = thisTF; + bcTH1Pointers[Form("bc/%d/tf_H", runNumberBc)]->Fill(thisTF); + } + + // check that the bc pass the selection + if (!checkBcFlags(bc, runNumberBc)) + continue; + + // consider only b-bcs + if (!bcPatternB.test(thisBC)) + continue; + bcTH1Pointers[Form("bc/%d/bcSel_H", runNumberBc)]->Fill(3); + + // get triggers + std::bitset<64> mask = bc.inputMask(); + bool ft0vtxTrg = mask[Ft0VtxIdx]; + bool ft0ceTrg = mask[Ft0CeIdx]; + if (ft0vtxTrg) { + bcTH2Pointers[Form("bc/%d/ft0Vtx_H", runNumberBc)]->Fill(thisTF, thisROF); + if (ft0ceTrg) + bcTH2Pointers[Form("bc/%d/ft0VtxCe_H", runNumberBc)]->Fill(thisTF, thisROF); + } + } // loop over bcs + + // reset current time frame + currentTF = -1; + } // end processBCs + PROCESS_SWITCH(UpcVmRof, processBCs, "get BCs and trigger information", true); + + //-------------------------------------------------------------------------------- + // get collision information + void processCols(ColSel const& col, BCsTSsSels const&, TRKs const& tracks, + aod::FV0As const&, aod::FT0s const&, aod::FDDs const&, + aod::Zdcs const&) + { + // get info for this bc + auto bc = col.template foundBC_as(); + if (runNumberCol != bc.runNumber()) { // new run + runNumberCol = bc.runNumber(); + getRunInfo(runNumberCol); + getFillingScheme(); + addColHistos(runNumberCol); + } + int64_t thisBC = getBcWithinOrbit(bc.globalBC()); + int64_t thisTF = getTimeFrame(bc.globalBC()); + int64_t thisROF = getRof(thisBC); + + // select collision + if (!checkColFlags(col, runNumberCol)) + return; + + // accept only -B bcs + if (!bcPatternB.test(thisBC)) + return; + colTH1Pointers[Form("col/%d/colSel_H", runNumberCol)]->Fill(10); + + // select on zVtx + if (std::abs(col.posZ()) > maxAbsPosZ) + return; + colTH1Pointers[Form("col/%d/colSel_H", runNumberCol)]->Fill(11); + + // select number of contributors + if (!((col.numContrib() == NTrksTwoBody) || (col.numContrib() == NTrksFourBody))) + return; + if (col.numContrib() == NTrksTwoBody) { + colTH1Pointers[Form("col/%d/colSel_H", runNumberCol)]->Fill(16); + } + if (col.numContrib() == NTrksFourBody) { + colTH1Pointers[Form("col/%d/colSel_H", runNumberCol)]->Fill(18); + } + + // select tracks + std::vector selTrks; + colTH1Pointers[Form("col/%d/trkSel_H", runNumberCol)]->Fill(0); + for (const auto& track : tracks) { + if (!track.isPVContributor()) + continue; + colTH1Pointers[Form("col/%d/trkSel_H", runNumberCol)]->Fill(1); + if (!track.hasITS()) + continue; + colTH1Pointers[Form("col/%d/trkSel_H", runNumberCol)]->Fill(2); + if (!track.hasTPC()) + continue; + colTH1Pointers[Form("col/%d/trkSel_H", runNumberCol)]->Fill(3); + colTH1Pointers[Form("col/%d/tpcChi2_H", runNumberCol)]->Fill(track.tpcChi2NCl()); + colTH1Pointers[Form("col/%d/itsChi2_H", runNumberCol)]->Fill(track.itsChi2NCl()); + colTH1Pointers[Form("col/%d/tpcNcls_H", runNumberCol)]->Fill(track.tpcNClsFindable()); + colTH1Pointers[Form("col/%d/tpcXoF_H", runNumberCol)]->Fill(track.tpcCrossedRowsOverFindableCls()); + colTH1Pointers[Form("col/%d/trkDcaZ_H", runNumberCol)]->Fill(track.dcaZ()); + colTH1Pointers[Form("col/%d/trkDcaXY_H", runNumberCol)]->Fill(track.dcaXY()); + if (track.tpcChi2NCl() > maxTrkTpcChi2) + continue; + colTH1Pointers[Form("col/%d/trkSel_H", runNumberCol)]->Fill(4); + if (track.itsChi2NCl() > maxTrkItsChi2) + continue; + colTH1Pointers[Form("col/%d/trkSel_H", runNumberCol)]->Fill(5); + if (track.tpcNClsFindable() < minTrkTpcClusters) + continue; + colTH1Pointers[Form("col/%d/trkSel_H", runNumberCol)]->Fill(6); + if (std::abs(track.dcaZ()) > maxTrkDcaZ) + continue; + colTH1Pointers[Form("col/%d/trkSel_H", runNumberCol)]->Fill(7); + float maxTrkDcaXY = 0.0105 + 0.035 / std::pow(track.pt(), 1.1); + if (std::abs(track.dcaXY()) > maxTrkDcaXY) + continue; + colTH1Pointers[Form("col/%d/trkSel_H", runNumberCol)]->Fill(8); + selTrks.push_back(track); + } + if (!(((col.numContrib() == NTrksTwoBody) && (selTrks.size() == NTrksTwoBody)) || + ((col.numContrib() == NTrksFourBody) && (selTrks.size() == NTrksFourBody)))) + return; + + // selected events + if ((col.numContrib() == NTrksTwoBody) && (selTrks.size() == NTrksTwoBody)) { + colTH1Pointers[Form("col/%d/colSel_H", runNumberCol)]->Fill(17); + } + if ((col.numContrib() == NTrksFourBody) && (selTrks.size() == NTrksFourBody)) { + colTH1Pointers[Form("col/%d/colSel_H", runNumberCol)]->Fill(19); + } + + // FT0 selection + float aFT0A = 0; + float aFT0C = 0; + float tFT0A = 33; // default time to mark events without FT0 info + float tFT0C = 33; // default time to mark events without FT0 info + int nFT0A = 0; + int nFT0C = 0; + if (bc.has_foundFT0()) { + // a side + if (bc.foundFT0().isValidTimeA()) { // valid time + tFT0A = bc.foundFT0().timeA(); + if (std::abs(tFT0A) > maxAbsTimeFT0) + return; + colTH1Pointers[Form("col/%d/colSel_H", runNumberCol)]->Fill(12); + aFT0A = bc.foundFT0().sumAmpA(); + if (aFT0A > maxAmpFT0) + return; + colTH1Pointers[Form("col/%d/colSel_H", runNumberCol)]->Fill(13); + nFT0A = (bc.foundFT0().amplitudeA()).size(); + } // a side + // c side + if (bc.foundFT0().isValidTimeC()) { // valid time + tFT0C = bc.foundFT0().timeC(); + if (std::abs(tFT0C) > maxAbsTimeFT0) + return; + colTH1Pointers[Form("col/%d/colSel_H", runNumberCol)]->Fill(14); + aFT0C = bc.foundFT0().sumAmpC(); + if (aFT0C > maxAmpFT0) + return; + colTH1Pointers[Form("col/%d/colSel_H", runNumberCol)]->Fill(15); + nFT0C = (bc.foundFT0().amplitudeC()).size(); + } // c side + } // FT0 selection + + // final number of selected events + if ((col.numContrib() == NTrksTwoBody) && (selTrks.size() == NTrksTwoBody)) { + colTH1Pointers[Form("col/%d/colSel_H", runNumberCol)]->Fill(20); + } + if ((col.numContrib() == NTrksFourBody) && (selTrks.size() == NTrksFourBody)) { + colTH1Pointers[Form("col/%d/colSel_H", runNumberCol)]->Fill(21); + } + + // get FV0A info + float aFV0A = 0; + float tFV0A = 33; // default time to mark events without FV0 info + int nFV0A = 0; + if (bc.has_foundFV0()) { + tFV0A = bc.foundFV0().time(); + auto v = bc.foundFV0().amplitude(); + aFV0A = std::accumulate(v.begin(), v.end(), 0.f); + nFV0A = v.size(); + } // FV0A info + + // get FDD info + float aFDDA = 0; + float tFDDA = 33; // default time to mark events without FDD info + int nFDDA = 0; + float aFDDC = 0; + float tFDDC = 33; // default time to mark events without FDD info + int nFDDC = 0; + if (bc.has_foundFDD()) { + tFDDA = bc.foundFDD().timeA(); + auto vA = bc.foundFDD().chargeA(); + // channelPairs = {{0, 4}, {1, 5}, {2, 6}, {3, 7}}; + if (vA[0] > 0 && vA[4] > 0) { + aFDDA += 0.5 * (vA[0] + vA[4]); + nFDDA++; + } + if (vA[1] > 0 && vA[5] > 0) { + aFDDA += 0.5 * (vA[1] + vA[5]); + nFDDA++; + } + if (vA[2] > 0 && vA[6] > 0) { + aFDDA += 0.5 * (vA[2] + vA[6]); + nFDDA++; + } + if (vA[3] > 0 && vA[7] > 0) { + aFDDA += 0.5 * (vA[3] + vA[7]); + nFDDA++; + } + tFDDC = bc.foundFDD().timeC(); + auto vC = bc.foundFDD().chargeC(); + // channelPairs = {{0, 4}, {1, 5}, {2, 6}, {3, 7}}; + if (vC[0] > 0 && vC[4] > 0) { + aFDDC += 0.5 * (vC[0] + vC[4]); + nFDDC++; + } + if (vC[1] > 0 && vC[5] > 0) { + aFDDC += 0.5 * (vC[1] + vC[5]); + nFDDC++; + } + if (vC[2] > 0 && vC[6] > 0) { + aFDDC += 0.5 * (vC[2] + vC[6]); + nFDDC++; + } + if (vC[3] > 0 && vC[7] > 0) { + aFDDC += 0.5 * (vC[3] + vC[7]); + nFDDC++; + } + } // FDD info + + // get ZDC info + float tZNA = -999; // default time to mark events without ZN info + float tZNC = -999; // default time to mark events without ZN info + float eZNA = -999; + float eZNC = -999; + if (bc.has_zdc()) { + tZNA = (bc.zdc()).timeZNA(); + tZNC = (bc.zdc()).timeZNC(); + eZNA = (bc.zdc()).energyCommonZNA(); + eZNC = (bc.zdc()).energyCommonZNC(); + if (!std::isfinite(tZNA)) + tZNA = -999; + if (!std::isfinite(tZNC)) + tZNC = -999; + if (!std::isfinite(eZNA)) + eZNA = -999; + if (!std::isfinite(eZNC)) + eZNC = -999; + } // ZDC info + + // fill output table + int recoFlag = (col.flags() & dataformats::Vertex>::Flags::UPCMode) ? 1 : 0; + if (selTrks.size() == NTrksTwoBody) { + colTH1Pointers[Form("col/%d/twoTrkTF_H", runNumberCol)]->Fill(thisTF); + twoTrkTable(runNumberCol, col.posX(), col.posY(), col.posZ(), col.chi2(), thisBC, thisTF, thisROF, recoFlag, + aFT0A, aFT0C, aFV0A, aFDDA, aFDDC, tFT0A, tFT0C, tFV0A, tFDDA, tFDDC, nFT0A, nFT0C, nFV0A, nFDDA, nFDDC, + eZNA, eZNC, tZNA, tZNC, + selTrks[0].pt(), selTrks[0].eta(), selTrks[0].phi(), selTrks[0].sign(), + selTrks[0].tpcNSigmaPi(), selTrks[0].tpcNSigmaEl(), selTrks[0].tpcNSigmaKa(), selTrks[0].tpcNSigmaPr(), + selTrks[1].pt(), selTrks[1].eta(), selTrks[1].phi(), selTrks[1].sign(), + selTrks[1].tpcNSigmaPi(), selTrks[1].tpcNSigmaEl(), selTrks[1].tpcNSigmaKa(), selTrks[1].tpcNSigmaPr()); + } + if (selTrks.size() == NTrksFourBody) { + colTH1Pointers[Form("col/%d/fourTrkTF_H", runNumberCol)]->Fill(thisTF); + fourTrkTable(runNumberCol, col.posX(), col.posY(), col.posZ(), col.chi2(), thisBC, thisTF, thisROF, recoFlag, + aFT0A, aFT0C, aFV0A, aFDDA, aFDDC, tFT0A, tFT0C, tFV0A, tFDDA, tFDDC, nFT0A, nFT0C, nFV0A, nFDDA, nFDDC, + eZNA, eZNC, tZNA, tZNC, + selTrks[0].pt(), selTrks[0].eta(), selTrks[0].phi(), selTrks[0].sign(), + selTrks[0].tpcNSigmaPi(), selTrks[0].tpcNSigmaEl(), selTrks[0].tpcNSigmaKa(), selTrks[0].tpcNSigmaPr(), + selTrks[1].pt(), selTrks[1].eta(), selTrks[1].phi(), selTrks[1].sign(), + selTrks[1].tpcNSigmaPi(), selTrks[1].tpcNSigmaEl(), selTrks[1].tpcNSigmaKa(), selTrks[1].tpcNSigmaPr(), + selTrks[2].pt(), selTrks[2].eta(), selTrks[2].phi(), selTrks[2].sign(), + selTrks[2].tpcNSigmaPi(), selTrks[2].tpcNSigmaEl(), selTrks[2].tpcNSigmaKa(), selTrks[2].tpcNSigmaPr(), + selTrks[3].pt(), selTrks[3].eta(), selTrks[3].phi(), selTrks[3].sign(), + selTrks[3].tpcNSigmaPi(), selTrks[3].tpcNSigmaEl(), selTrks[3].tpcNSigmaKa(), selTrks[3].tpcNSigmaPr()); + } + + } // end processCol + PROCESS_SWITCH(UpcVmRof, processCols, "get collisions and track information", true); + +}; // end of struct UpcVmRof + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/Tools/ML/MlResponse.h b/Tools/ML/MlResponse.h index 4b5d976cb77..da75eff66e1 100644 --- a/Tools/ML/MlResponse.h +++ b/Tools/ML/MlResponse.h @@ -151,14 +151,8 @@ class MlResponse void init(bool enableOptimizations = false, int threads = 0) { uint8_t counterModel{0}; - const int numCachedIndices = static_cast(mCachedIndices.size()); for (const auto& path : mPaths) { mModels[counterModel].initModel(path, enableOptimizations, threads); - const int numInputNodes = mModels[counterModel].getNumInputNodes(); - if (numInputNodes != numCachedIndices) { - LOG(fatal) << "Number of input nodes in the model " << path << " is different from the number of input features indices (" << numInputNodes << " vs " << numCachedIndices << ")"; - return; - } ++counterModel; } } @@ -188,6 +182,13 @@ class MlResponse LOG(fatal) << "Model index " << nModel << " is out of range! The number of initialised models is " << mModels.size() << ". Please check your configurables."; } + const int numInputNodes = mModels[nModel].getNumInputNodes(); + const int numInputFeatures = static_cast(input.size()); + + if (numInputNodes != numInputFeatures) { + LOG(fatal) << "Number of input nodes in the model " << mPaths[nModel] << " is different from the number of input features to be tested (" << numInputNodes << " vs " << numInputFeatures << ")"; + } + TypeOutputScore* outputPtr = mModels[nModel].template evalModel(input); return std::vector{outputPtr, outputPtr + mNClasses}; } diff --git a/cppcheck_config b/cppcheck_suppressions similarity index 58% rename from cppcheck_config rename to cppcheck_suppressions index 506d113f69d..fe4e5d9b50a 100644 --- a/cppcheck_config +++ b/cppcheck_suppressions @@ -1,5 +1,9 @@ +functionStatic +missingInclude +missingIncludeSystem syntaxError unknownMacro -missingIncludeSystem -missingInclude +unreadVariable unusedStructMember:*.h +useStlAlgorithm +variableScope