Belle II Software  release-08-01-10
eclChargedPID.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #include <framework/gearbox/Const.h>
9 #include <framework/gearbox/Unit.h>
10 #include <framework/datastore/StoreArray.h>
11 
12 #include <ecl/dataobjects/ECLPidLikelihood.h>
13 #include <ecl/dbobjects/ECLChargedPidPDFs.h>
14 
15 #include <utility>
16 #include <gtest/gtest.h>
17 
18 #include <TF1.h>
19 
20 namespace Belle2 {
27  class ECLChargedPIDTest : public ::testing::Test {
28 
29  protected:
31  virtual void SetUp()
32  {
34 
35  StoreArray<ECLPidLikelihood> ecl_likelihoods;
36  ecl_likelihoods.registerInDataStore();
37 
38  StoreArray<ECLPidLikelihood> ecl_likelihoods_plus;
39  ecl_likelihoods_plus.registerInDataStore();
40 
41  StoreArray<ECLPidLikelihood> ecl_likelihoods_minus;
42  ecl_likelihoods_minus.registerInDataStore();
43 
45  }
46 
48  virtual void TearDown()
49  {
51  }
52 
53  };
54 
56  TEST_F(ECLChargedPIDTest, ECLPidLikelihoodSettersAndGetters)
57  {
58 
59  StoreArray<ECLPidLikelihood> ecl_likelihoods;
60 
61  auto* lk = ecl_likelihoods.appendNew();
62 
63  lk->setLogLikelihood(Const::electron, 0.12);
64  lk->setLogLikelihood(Const::muon, 0.58);
65  lk->setLogLikelihood(Const::pion, 0.28);
66  lk->setLogLikelihood(Const::kaon, 0.38);
67  lk->setLogLikelihood(Const::proton, 0.48);
68 
69  EXPECT_FLOAT_EQ(lk->getLogLikelihood(Const::electron), 0.12);
70  EXPECT_FLOAT_EQ(lk->getLogLikelihood(Const::muon), 0.58);
71  EXPECT_FLOAT_EQ(lk->getLogLikelihood(Const::pion), 0.28);
72  EXPECT_FLOAT_EQ(lk->getLogLikelihood(Const::kaon), 0.38);
73  EXPECT_FLOAT_EQ(lk->getLogLikelihood(Const::proton), 0.48);
74 
75  } // Testcases for ECLPidLikelihood setters and getters.
76 
78  TEST_F(ECLChargedPIDTest, TestECLPdfs)
79  {
80 
81  ECLChargedPidPDFs eclPdfs;
82 
83  float pmin_vals[] = {0.2, 0.6, 1.0, 100.0};
84  float thetamin_vals[] = {0.21, 0.56, 2.24, 2.70};
85 
86  TH2F histgrid("binsgrid",
87  "bins grid",
88  sizeof(thetamin_vals) / sizeof(float) - 1,
89  thetamin_vals,
90  sizeof(pmin_vals) / sizeof(float) - 1,
91  pmin_vals);
92 
93  eclPdfs.setEnergyUnit(Unit::GeV);
94  eclPdfs.setAngularUnit(Unit::rad);
95 
96  eclPdfs.setPdfCategories(&histgrid);
97 
98  // Create a set of fictitious (normalised) PDFs of E/p, for various signed particle hypotheses.
99  // The first element in the pair is the true charge.
100 
101  typedef std::pair<int, TF1> pdfSet;
102 
103  pdfSet pdf_el = std::make_pair(-1, TF1("pdf_el", "TMath::Gaus(x, 1.0, 0.2, true)", 0.0, 1.3));
104  pdfSet pdf_elanti = std::make_pair(1, TF1("pdf_elanti", "TMath::Gaus(x, 0.9, 0.2, true)", 0.0, 1.2));
105 
106  pdfSet pdf_mu = std::make_pair(-1, TF1("pdf_mu", "TMath::Gaus(x, 0.3, 0.2, true)", 0.0, 1.0));
107  pdfSet pdf_muanti = std::make_pair(1, TF1("pdf_muanti", "TMath::Gaus(x, 0.35, 0.22, true)", 0.0, 1.0));
108 
109  pdfSet pdf_pi = std::make_pair(1, TF1("pdf_pi", "TMath::Gaus(x, 0.4, 0.1, true)", 0.0, 1.0));
110  pdfSet pdf_pianti = std::make_pair(-1, TF1("pdf_pianti", "TMath::Gaus(x, 0.38, 0.15, true)", 0.0, 1.0));
111 
112  pdfSet pdf_k = std::make_pair(1, TF1("pdf_k", "TMath::Gaus(x, 0.38, 0.2, true)", 0.0, 1.0));
113  pdfSet pdf_kanti = std::make_pair(-1, TF1("pdf_kanti", "TMath::Gaus(x, 0.5, 0.22, true)", 0.0, 1.0));
114 
115  pdfSet pdf_p = std::make_pair(1, TF1("pdf_p", "TMath::Gaus(x, 1.0, 0.4, true)", 0.0, 1.6));
116  pdfSet pdf_panti = std::make_pair(-1, TF1("pdf_panti", "TMath::Gaus(x, 1.3, 0.5, true)", 0.0, 2.0));
117 
118  pdfSet pdf_d = std::make_pair(1, TF1("pdf_d", "TMath::Gaus(x, 1.1, 0.45, true)", 0.0, 1.6));
119  pdfSet pdf_danti = std::make_pair(-1, TF1("pdf_danti", "TMath::Gaus(x, 1.2, 0.6, true)", 0.0, 2.0));
120 
121  std::map<unsigned int, std::vector<pdfSet>> pdfs = {
122  {Const::electron.getPDGCode(), std::vector<pdfSet>{pdf_el, pdf_elanti}},
123  {Const::muon.getPDGCode(), std::vector<pdfSet>{pdf_mu, pdf_muanti}},
124  {Const::pion.getPDGCode(), std::vector<pdfSet>{pdf_pi, pdf_pianti}},
125  {Const::kaon.getPDGCode(), std::vector<pdfSet>{pdf_k, pdf_kanti}},
126  {Const::proton.getPDGCode(), std::vector<pdfSet>{pdf_p, pdf_panti}},
127  {Const::deuteron.getPDGCode(), std::vector<pdfSet>{pdf_d, pdf_danti}},
128  };
129 
130  // E/p is the only variable considered in the test.
131  std::vector<ECLChargedPidPDFs::InputVar> varids = {ECLChargedPidPDFs::InputVar::c_EoP};
132 
133  // Fill the DB PDF map.
134  // (Use the same PDF for all (clusterTheta, p) bins for simplicity).
135  for (auto& [pdg, pdf_setlist] : pdfs) {
136  for (auto& pdf_set : pdf_setlist) {
137  for (int ip(1); ip <= histgrid.GetNbinsY(); ++ip) {
138  for (int jth(1); jth <= histgrid.GetNbinsX(); ++jth) {
139  for (const auto& varid : varids) {
140  eclPdfs.add(pdg, pdf_set.first, ip, jth, varid, &pdf_set.second);
141  }
142  }
143  }
144  }
145  }
146 
147  // Store the value of the PDFs in here, and pass it to the ECLPidLikelihood object later on.
148  float likelihoods_plus[Const::ChargedStable::c_SetSize];
149  float likelihoods_minus[Const::ChargedStable::c_SetSize];
150 
151  // Choose an arbitrary set of (clusterTheta, p), and of E/p.
152  double clusterTheta = 1.047; // (X) --> clusterTheta [rad] = 60 [deg]
153  double p = 0.85; // (Y) --> P [GeV] = 850 [MeV]
154  double eop = 0.87;
155 
156  // Now read the PDFs.
157  for (const auto& [pdg, pdf_setlist] : pdfs) {
158  for (const auto& pdf_set : pdf_setlist) {
159  float pdfval = eclPdfs.getPdf(pdg, pdf_set.first, p, clusterTheta, varids.at(0))->Eval(eop);
160  EXPECT_NEAR(pdf_set.second.Eval(eop), pdfval, 0.001);
161  if (pdf_set.first < 0) {
162  likelihoods_minus[Const::chargedStableSet.find(pdg).getIndex()] = log(pdfval);
163  } else {
164  likelihoods_plus[Const::chargedStableSet.find(pdg).getIndex()] = log(pdfval);
165  }
166  }
167  }
168 
169  // Set the ECL likelihood dataobjects
170  StoreArray<ECLPidLikelihood> ecl_likelihoods_minus;
171  const auto* lk_minus = ecl_likelihoods_minus.appendNew(likelihoods_minus);
172  StoreArray<ECLPidLikelihood> ecl_likelihoods_plus;
173  const auto* lk_plus = ecl_likelihoods_plus.appendNew(likelihoods_plus);
174 
175  for (const auto& [pdg, pdf_setlist] : pdfs) {
176  for (const auto& pdf_set : pdf_setlist) {
177  float logl;
178  float logl_expect = log(pdf_set.second.Eval(eop));
179  if (pdf_set.first < 0) {
180  logl = lk_minus->getLogLikelihood(Const::chargedStableSet.find(pdg));
181  } else {
182  logl = lk_plus->getLogLikelihood(Const::chargedStableSet.find(pdg));
183  }
184  EXPECT_NEAR(logl_expect, logl, 0.01);
185  }
186  }
187 
188  } // Testcases for ECL PDFs.
189 
191 } // namespace
static const unsigned int c_SetSize
Number of elements (for use in array bounds etc.)
Definition: Const.h:606
const ParticleType & find(int pdg) const
Returns particle in set with given PDG code, or invalidParticle if not found.
Definition: Const.h:562
int getPDGCode() const
PDG code.
Definition: Const.h:464
int getIndex() const
This particle's index in the associated set.
Definition: Const.h:452
static const ChargedStable muon
muon particle
Definition: Const.h:651
static const ParticleSet chargedStableSet
set of charged stable particles
Definition: Const.h:609
static const ChargedStable pion
charged pion particle
Definition: Const.h:652
static const ChargedStable proton
proton particle
Definition: Const.h:654
static const ChargedStable kaon
charged kaon particle
Definition: Const.h:653
static const ChargedStable electron
electron particle
Definition: Const.h:650
static const ChargedStable deuteron
deuteron particle
Definition: Const.h:655
static DataStore & Instance()
Instance of singleton Store.
Definition: DataStore.cc:54
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition: DataStore.cc:94
void reset(EDurability durability)
Frees memory occupied by data store items and removes all objects from the map.
Definition: DataStore.cc:86
Test the ECL charged PID.
virtual void TearDown()
Clear datastore.
virtual void SetUp()
Set up a few arrays and objects in the datastore.
Class representing the DB payload w/ information about ECL PDF parameters for a set of particle hypot...
void add(const unsigned int pdg, const int true_charge, const unsigned int i, const unsigned int j, const InputVar varid, TF1 *pdf)
Fills the internal maps for a given hypothesis and category (clusterTheta, p).
void setPdfCategories(TH2F *h)
Set the 2D (clusterTheta, p) grid representing the categories for which PDFs are defined.
const TF1 * getPdf(const unsigned int pdg, const int charge, const double &p, const double &theta, const InputVar varid) const
Return the PDF of this observable for this candidate's reconstructed (p, clusterTheta),...
void setAngularUnit(const double &unit)
Set the angular unit to be consistent w/ the one used in the fit.
void setEnergyUnit(const double &unit)
Set the energy unit to be consistent w/ the one used in the fit.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:246
static const double rad
Standard of [angle].
Definition: Unit.h:50
static const double GeV
Standard of [energy, momentum, mass].
Definition: Unit.h:51
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
Definition: globalLabel.cc:72
Abstract base class for different kinds of events.