Belle II Software  release-08-01-10
KLMStripEfficiencyAlgorithm.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 
9 /* Own header. */
10 #include <klm/calibration/KLMStripEfficiencyAlgorithm.h>
11 
12 /* KLM headers. */
13 #include <klm/dataobjects/KLMChannelIndex.h>
14 
15 /* ROOT headers. */
16 #include <TFile.h>
17 #include <TH1F.h>
18 
19 using namespace Belle2;
20 
22 {
23 }
24 
26 {
27  m_AchievedPrecision = results.m_AchievedPrecision;
28  m_MatchedDigits = results.m_MatchedDigits;
29  m_ExtHits = results.m_ExtHits;
31  m_Efficiency = new float[nPlanes];
32  m_ExtHitsPlane = new int[nPlanes];
33  std::memcpy(m_Efficiency, results.m_Efficiency, nPlanes * sizeof(float));
34  std::memcpy(m_ExtHitsPlane, results.m_ExtHitsPlane, nPlanes * sizeof(int));
35 }
36 
38 {
39  if (m_Efficiency != nullptr)
40  delete m_Efficiency;
41  if (m_ExtHitsPlane != nullptr)
42  delete m_ExtHitsPlane;
43 }
44 
46  CalibrationAlgorithm("KLMStripEfficiencyCollector"),
47  m_ElementNumbers(&(KLMElementNumbers::Instance())),
48  m_PlaneArrayIndex(&(KLMPlaneArrayIndex::Instance())),
49  m_StripEfficiency(nullptr)
50 {
51  int nPlanes = m_PlaneArrayIndex->getNElements();
52  m_Results.m_Efficiency = new float[nPlanes];
53  m_Results.m_ExtHitsPlane = new int[nPlanes];
54 }
55 
57 {
58  if (m_StripEfficiency != nullptr)
59  delete m_StripEfficiency;
60 }
61 
63 {
64  /* Get collected results. */
65  int nPlanes = m_PlaneArrayIndex->getNElements();
66  TH1F* efficiencyHistogram =
67  new TH1F("plane_efficiency", "KLM plane efficiency",
68  nPlanes, -0.5, double(nPlanes) - 0.5);
69  std::shared_ptr<TH1F> matchedDigitsInPlane;
70  matchedDigitsInPlane = getObjectPtr<TH1F>("matchedDigitsInPlane");
71  m_Results.m_MatchedDigits = matchedDigitsInPlane->Integral();
72  std::shared_ptr<TH1F> allExtHitsInPlane;
73  allExtHitsInPlane = getObjectPtr<TH1F>("allExtHitsInPlane");
74  m_Results.m_ExtHits = allExtHitsInPlane->Integral();
75  matchedDigitsInPlane.get()->Sumw2();
76  allExtHitsInPlane.get()->Sumw2();
77  efficiencyHistogram->Divide(matchedDigitsInPlane.get(),
78  allExtHitsInPlane.get(), 1, 1, "B");
79  for (int i = 0; i < nPlanes; ++i) {
80  m_Results.m_Efficiency[i] = efficiencyHistogram->GetBinContent(i + 1);
81  m_Results.m_ExtHitsPlane[i] = allExtHitsInPlane->GetBinContent(i + 1);
82  }
83  /* Check whether the amount of data is sufficient. */
84  bool notEnoughData = false;
87  for (KLMChannelIndex& klmPlane : klmPlanes) {
88  KLMPlaneNumber plane = klmPlane.getKLMPlaneNumber();
89  KLMPlaneNumber planeIndex = m_PlaneArrayIndex->getIndex(plane);
90  int extHits = allExtHitsInPlane->GetBinContent(planeIndex + 1);
91  float efficiencyError = efficiencyHistogram->GetBinError(planeIndex + 1);
92  if (efficiencyError > m_Results.m_AchievedPrecision)
93  m_Results.m_AchievedPrecision = efficiencyError;
94  /*
95  * No hits is not considered as "not enough data", because this can
96  * happen in case KLM is excluded.
97  */
98  switch (m_CalibrationStage) {
100  if (extHits != 0 && extHits < m_MinimalExtHits)
101  notEnoughData = true;
102  break;
104  if (efficiencyError > m_RequestedPrecision)
105  notEnoughData = true;
106  break;
107  }
108  }
109  /*
110  * Fill the payload. A new object is created, because saveCalibration()
111  * stores a pointer to KLMStripEfficiency, and it is necessary to save
112  * the payloads to commit them at the end of calibration.
113  */
115  (!notEnoughData || m_ForcedCalibration)) {
117  KLMChannelIndex klmChannels;
118  for (KLMChannelIndex& klmChannel : klmChannels) {
119  int subdetector = klmChannel.getSubdetector();
120  int section = klmChannel.getSection();
121  int sector = klmChannel.getSector();
122  int layer = klmChannel.getLayer();
123  int plane = klmChannel.getPlane();
124  int strip = klmChannel.getStrip();
125  KLMPlaneNumber planeKLM = 0;
126  if (subdetector == KLMElementNumbers::c_BKLM) {
127  planeKLM = m_ElementNumbers->planeNumberBKLM(
128  section, sector, layer, plane);
129  } else {
130  planeKLM = m_ElementNumbers->planeNumberEKLM(
131  section, sector, layer, plane);
132  }
133  KLMPlaneNumber planeIndex = m_PlaneArrayIndex->getIndex(planeKLM);
134  float efficiency = efficiencyHistogram->GetBinContent(planeIndex + 1);
135  float efficiencyError = efficiencyHistogram->GetBinError(planeIndex + 1);
136  /* Fill the efficiency for this strip. */
137  if (subdetector == KLMElementNumbers::c_BKLM) {
139  section, sector, layer, plane, strip, efficiency, efficiencyError);
140  } else {
142  section, sector, layer, plane, strip, efficiency, efficiencyError);
143  }
144  }
145  saveCalibration(m_StripEfficiency, "KLMStripEfficiency");
146  }
147  /* Write histograms to output file. */
148  TFile* outputFile = new TFile(m_OutputFileName.c_str(), "recreate");
149  outputFile->cd();
150  matchedDigitsInPlane.get()->Write();
151  allExtHitsInPlane.get()->Write();
152  efficiencyHistogram->Write();
153  delete efficiencyHistogram;
154  delete outputFile;
155  /* Set output status. */
156  if (notEnoughData && !m_ForcedCalibration)
159 }
160 
162  const float* efficiency) const
163 {
164  const int nPlanes = KLMPlaneArrayIndex::Instance().getNElements();
165  int newPlanes = 0;
166  for (int i = 0; i < nPlanes; ++i) {
167  if (m_Efficiency[i] > 0 && efficiency[i] == 0)
168  newPlanes++;
169  }
170  return newPlanes;
171 }
172 
174  const int* extHitsPlane) const
175 {
176  const int nPlanes = KLMPlaneArrayIndex::Instance().getNElements();
177  int newPlanes = 0;
178  for (int i = 0; i < nPlanes; ++i) {
179  if (m_ExtHitsPlane[i] > 0 && extHitsPlane[i] == 0)
180  newPlanes++;
181  }
182  return newPlanes;
183 }
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
EResult
The result of calibration.
@ c_OK
Finished successfuly =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
KLM channel index.
int getSubdetector() const
Get subdetector.
uint16_t getNElements() const
Get number of elements.
uint16_t getIndex(uint16_t number) const
Get element index.
KLM element numbers.
KLMPlaneNumber planeNumberEKLM(int section, int sector, int layer, int plane) const
Get channel number for EKLM.
KLMPlaneNumber planeNumberBKLM(int section, int sector, int layer, int plane) const
Get plane number for BKLM.
KLM plane array index.
static const KLMPlaneArrayIndex & Instance()
Instantiation.
Calibration results or supplementary results calculated from the input data.
int newMeasuredPlanes(const float *efficiency) const
Get number of new measured planes.
float m_AchievedPrecision
Achieved precision of efficiency measurement.
int newExtHitsPlanes(const int *extHitsPlane) const
Get number of new measured planes with ExtHits.
@ c_MeasurablePlaneCheck
Check of set of planes with determined efficiency.
enum CalibrationStage m_CalibrationStage
Calibration stage.
bool m_ForcedCalibration
Whether the calibration is forced.
const KLMElementNumbers * m_ElementNumbers
Element numbers.
const KLMPlaneArrayIndex * m_PlaneArrayIndex
Plane array index.
KLMStripEfficiency * m_StripEfficiency
Efficiency data object.
CalibrationAlgorithm::EResult calibrate() override
Calibration.
int m_MinimalExtHits
Minimal number of ExtHits per plane.
float m_RequestedPrecision
Requested precision of efficiency measurement.
DBObject used to store the efficiencies of KLM strips.
void setEndcapEfficiency(int section, int sector, int layer, int plane, int strip, float efficiency, float efficiencyError=0.)
Set efficiency and relative error for a single EKLM strip using the geometrical infos.
void setBarrelEfficiency(int section, int sector, int layer, int plane, int strip, float efficiency, float efficiencyError=0.)
Set efficiency and relative error for a single BKLM strip using the geometrical infos.
uint16_t KLMPlaneNumber
Plane number.
Abstract base class for different kinds of events.