|
| 1 | +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. |
| 2 | +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. |
| 3 | +// All rights not expressly granted are reserved. |
| 4 | +// |
| 5 | +// This software is distributed under the terms of the GNU General Public |
| 6 | +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". |
| 7 | +// |
| 8 | +// In applying this license CERN does not waive the privileges and immunities |
| 9 | +// granted to it by virtue of its status as an Intergovernmental Organization |
| 10 | +// or submit itself to any jurisdiction. |
| 11 | + |
| 12 | +/// |
| 13 | +/// \file PIDResponseITS.h |
| 14 | +/// \since 2024-11-12 |
| 15 | +/// \author Nicolò Jacazio nicolo.jacazio@cern.ch |
| 16 | +/// \author Francesco Mazzaschi francesco.mazzaschi@cern.ch |
| 17 | +/// \brief Set of tables, tasks and utilities to provide the interface between |
| 18 | +/// the analysis data model and the PID response of the ITS |
| 19 | +/// |
| 20 | + |
| 21 | +#ifndef COMMON_DATAMODEL_PIDRESPONSEITS_H_ |
| 22 | +#define COMMON_DATAMODEL_PIDRESPONSEITS_H_ |
| 23 | + |
| 24 | +// O2 includes |
| 25 | +#include "Framework/ASoA.h" |
| 26 | +#include "Framework/AnalysisDataModel.h" |
| 27 | +#include "ReconstructionDataFormats/PID.h" |
| 28 | +#include "Framework/Logger.h" |
| 29 | + |
| 30 | +namespace o2::aod |
| 31 | +{ |
| 32 | + |
| 33 | +struct ITSResponse { |
| 34 | + static float averageClusterSize(uint32_t itsClusterSizes) |
| 35 | + { |
| 36 | + float average = 0; |
| 37 | + int nclusters = 0; |
| 38 | + |
| 39 | + for (int layer = 0; layer < 7; layer++) { |
| 40 | + if ((itsClusterSizes >> (layer * 4)) & 0xf) { |
| 41 | + nclusters++; |
| 42 | + average += (itsClusterSizes >> (layer * 4)) & 0xf; |
| 43 | + } |
| 44 | + } |
| 45 | + if (nclusters == 0) { |
| 46 | + return 0; |
| 47 | + } |
| 48 | + return average / nclusters; |
| 49 | + }; |
| 50 | + |
| 51 | + template <o2::track::PID::ID id> |
| 52 | + static float expSignal(const float momentum) |
| 53 | + { |
| 54 | + static constexpr float inverseMass = 1. / o2::track::pid_constants::sMasses[id]; |
| 55 | + static constexpr float charge = static_cast<float>(o2::track::pid_constants::sCharges[id]); |
| 56 | + const float bg = momentum * inverseMass; |
| 57 | + return (mITSRespParams[0] / (std::pow(bg, mITSRespParams[1])) + mITSRespParams[2]) * std::pow(charge, mChargeFactor); |
| 58 | + } |
| 59 | + |
| 60 | + template <o2::track::PID::ID id> |
| 61 | + static float nSigmaITS(uint32_t itsClusterSizes, float momentum) |
| 62 | + { |
| 63 | + const float exp = expSignal<id>(momentum); |
| 64 | + const float average = averageClusterSize(itsClusterSizes); |
| 65 | + const float resolution = mResolution * exp; |
| 66 | + return (average - exp) / resolution; |
| 67 | + }; |
| 68 | + |
| 69 | + static void setParameters(float p0, float p1, float p2, float chargeFactor, float resolution) |
| 70 | + { |
| 71 | + if (mIsInitialized) { |
| 72 | + LOG(fatal) << "ITSResponse parameters already initialized"; |
| 73 | + } |
| 74 | + mIsInitialized = true; |
| 75 | + mITSRespParams[0] = p0; |
| 76 | + mITSRespParams[1] = p1; |
| 77 | + mITSRespParams[2] = p2; |
| 78 | + mChargeFactor = chargeFactor; |
| 79 | + mResolution = resolution; |
| 80 | + } |
| 81 | + |
| 82 | + private: |
| 83 | + static std::array<float, 3> mITSRespParams; |
| 84 | + static float mChargeFactor; |
| 85 | + static float mResolution; |
| 86 | + static bool mIsInitialized; |
| 87 | +}; |
| 88 | + |
| 89 | +std::array<float, 3> ITSResponse::mITSRespParams = {0.903, 2.014, 2.440}; |
| 90 | +float ITSResponse::mChargeFactor = 2.299999952316284f; |
| 91 | +float ITSResponse::mResolution = 0.15f; |
| 92 | +bool ITSResponse::mIsInitialized = false; |
| 93 | + |
| 94 | +namespace pidits |
| 95 | +{ |
| 96 | +DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaElImp, itsNSigmaEl, //! Nsigma separation with the ITS detector for electrons |
| 97 | + [](uint32_t itsClusterSizes, float momentum) -> float { |
| 98 | + return ITSResponse::nSigmaITS<o2::track::PID::Electron>(itsClusterSizes, momentum); |
| 99 | + }); |
| 100 | + |
| 101 | +DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaMuImp, itsNSigmaMu, //! Nsigma separation with the ITS detector for muons |
| 102 | + [](uint32_t itsClusterSizes, float momentum) -> float { |
| 103 | + return ITSResponse::nSigmaITS<o2::track::PID::Muon>(itsClusterSizes, momentum); |
| 104 | + }); |
| 105 | + |
| 106 | +DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaPiImp, itsNSigmaPi, //! Nsigma separation with the ITS detector for pions |
| 107 | + [](uint32_t itsClusterSizes, float momentum) -> float { |
| 108 | + return ITSResponse::nSigmaITS<o2::track::PID::Pion>(itsClusterSizes, momentum); |
| 109 | + }); |
| 110 | + |
| 111 | +DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaKaImp, itsNSigmaKa, //! Nsigma separation with the ITS detector for kaons |
| 112 | + [](uint32_t itsClusterSizes, float momentum) -> float { |
| 113 | + return ITSResponse::nSigmaITS<o2::track::PID::Kaon>(itsClusterSizes, momentum); |
| 114 | + }); |
| 115 | + |
| 116 | +DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaPrImp, itsNSigmaPr, //! Nsigma separation with the ITS detector for protons |
| 117 | + [](uint32_t itsClusterSizes, float momentum) -> float { |
| 118 | + return ITSResponse::nSigmaITS<o2::track::PID::Proton>(itsClusterSizes, momentum); |
| 119 | + }); |
| 120 | + |
| 121 | +DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaDeImp, itsNSigmaDe, //! Nsigma separation with the ITS detector for deuterons |
| 122 | + [](uint32_t itsClusterSizes, float momentum) -> float { |
| 123 | + return ITSResponse::nSigmaITS<o2::track::PID::Deuteron>(itsClusterSizes, momentum); |
| 124 | + }); |
| 125 | + |
| 126 | +DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaTrImp, itsNSigmaTr, //! Nsigma separation with the ITS detector for tritons |
| 127 | + [](uint32_t itsClusterSizes, float momentum) -> float { |
| 128 | + return ITSResponse::nSigmaITS<o2::track::PID::Triton>(itsClusterSizes, momentum); |
| 129 | + }); |
| 130 | + |
| 131 | +DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaHeImp, itsNSigmaHe, //! Nsigma separation with the ITS detector for helium3 |
| 132 | + [](uint32_t itsClusterSizes, float momentum) -> float { |
| 133 | + return ITSResponse::nSigmaITS<o2::track::PID::Helium3>(itsClusterSizes, momentum); |
| 134 | + }); |
| 135 | + |
| 136 | +DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaAlImp, itsNSigmaAl, //! Nsigma separation with the ITS detector for alphas |
| 137 | + [](uint32_t itsClusterSizes, float momentum) -> float { |
| 138 | + return ITSResponse::nSigmaITS<o2::track::PID::Alpha>(itsClusterSizes, momentum); |
| 139 | + }); |
| 140 | + |
| 141 | +// Define user friendly names for the columns to join with the tracks |
| 142 | +using ITSNSigmaEl = ITSNSigmaElImp<o2::aod::track::ITSClusterSizes, o2::aod::track::P>; |
| 143 | +using ITSNSigmaMu = ITSNSigmaMuImp<o2::aod::track::ITSClusterSizes, o2::aod::track::P>; |
| 144 | +using ITSNSigmaPi = ITSNSigmaPiImp<o2::aod::track::ITSClusterSizes, o2::aod::track::P>; |
| 145 | +using ITSNSigmaKa = ITSNSigmaKaImp<o2::aod::track::ITSClusterSizes, o2::aod::track::P>; |
| 146 | +using ITSNSigmaPr = ITSNSigmaPrImp<o2::aod::track::ITSClusterSizes, o2::aod::track::P>; |
| 147 | +using ITSNSigmaDe = ITSNSigmaDeImp<o2::aod::track::ITSClusterSizes, o2::aod::track::P>; |
| 148 | +using ITSNSigmaTr = ITSNSigmaTrImp<o2::aod::track::ITSClusterSizes, o2::aod::track::P>; |
| 149 | +using ITSNSigmaHe = ITSNSigmaHeImp<o2::aod::track::ITSClusterSizes, o2::aod::track::P>; |
| 150 | +using ITSNSigmaAl = ITSNSigmaAlImp<o2::aod::track::ITSClusterSizes, o2::aod::track::P>; |
| 151 | + |
| 152 | +} // namespace pidits |
| 153 | +} // namespace o2::aod |
| 154 | + |
| 155 | +#endif // COMMON_DATAMODEL_PIDRESPONSEITS_H_ |
0 commit comments