Belle II Software development
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
19using namespace Belle2;
20
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
42
44 CalibrationAlgorithm("KLMStripEfficiencyCollector"),
45 m_ElementNumbers(&(KLMElementNumbers::Instance())),
47 m_StripEfficiency(nullptr)
48{
49 int nPlanes = m_PlaneArrayIndex->getNElements();
50 m_Results.m_Efficiency = new float[nPlanes];
51 m_Results.m_ExtHitsPlane = new int[nPlanes];
52}
53
59
61{
62 /* Get collected results. */
63 int nPlanes = m_PlaneArrayIndex->getNElements();
64 TH1F* efficiencyHistogram =
65 new TH1F("plane_efficiency", "KLM plane efficiency",
66 nPlanes, -0.5, double(nPlanes) - 0.5);
67 std::shared_ptr<TH1F> matchedDigitsInPlane;
68 matchedDigitsInPlane = getObjectPtr<TH1F>("matchedDigitsInPlane");
69 m_Results.m_MatchedDigits = matchedDigitsInPlane->Integral();
70 std::shared_ptr<TH1F> allExtHitsInPlane;
71 allExtHitsInPlane = getObjectPtr<TH1F>("allExtHitsInPlane");
72 m_Results.m_ExtHits = allExtHitsInPlane->Integral();
73 matchedDigitsInPlane.get()->Sumw2();
74 allExtHitsInPlane.get()->Sumw2();
75 efficiencyHistogram->Divide(matchedDigitsInPlane.get(),
76 allExtHitsInPlane.get(), 1, 1, "B");
77 for (int i = 0; i < nPlanes; ++i) {
78 m_Results.m_Efficiency[i] = efficiencyHistogram->GetBinContent(i + 1);
79 m_Results.m_ExtHitsPlane[i] = allExtHitsInPlane->GetBinContent(i + 1);
80 }
81 /* Check whether the amount of data is sufficient. */
82 bool notEnoughData = false;
83 m_Results.m_AchievedPrecision = 0;
85 for (const KLMChannelIndex& klmPlane : klmPlanes) {
86 KLMPlaneNumber plane = klmPlane.getKLMPlaneNumber();
87 KLMPlaneNumber planeIndex = m_PlaneArrayIndex->getIndex(plane);
88 int extHits = allExtHitsInPlane->GetBinContent(planeIndex + 1);
89 float efficiencyError = efficiencyHistogram->GetBinError(planeIndex + 1);
90 if (efficiencyError > m_Results.m_AchievedPrecision)
91 m_Results.m_AchievedPrecision = efficiencyError;
92 /*
93 * No hits is not considered as "not enough data", because this can
94 * happen in case KLM is excluded.
95 */
96 switch (m_CalibrationStage) {
98 if (extHits != 0 && extHits < m_MinimalExtHits)
99 notEnoughData = true;
100 break;
102 if (efficiencyError > m_RequestedPrecision)
103 notEnoughData = true;
104 break;
105 }
106 }
107 /*
108 * Fill the payload. A new object is created, because saveCalibration()
109 * stores a pointer to KLMStripEfficiency, and it is necessary to save
110 * the payloads to commit them at the end of calibration.
111 */
113 (!notEnoughData || m_ForcedCalibration)) {
115 KLMChannelIndex klmChannels;
116 for (const KLMChannelIndex& klmChannel : klmChannels) {
117 int subdetector = klmChannel.getSubdetector();
118 int section = klmChannel.getSection();
119 int sector = klmChannel.getSector();
120 int layer = klmChannel.getLayer();
121 int plane = klmChannel.getPlane();
122 int strip = klmChannel.getStrip();
123 KLMPlaneNumber planeKLM = 0;
124 if (subdetector == KLMElementNumbers::c_BKLM) {
125 planeKLM = m_ElementNumbers->planeNumberBKLM(
126 section, sector, layer, plane);
127 } else {
128 planeKLM = m_ElementNumbers->planeNumberEKLM(
129 section, sector, layer, plane);
130 }
131 KLMPlaneNumber planeIndex = m_PlaneArrayIndex->getIndex(planeKLM);
132 float efficiency = efficiencyHistogram->GetBinContent(planeIndex + 1);
133 float efficiencyError = efficiencyHistogram->GetBinError(planeIndex + 1);
134 /* Fill the efficiency for this strip. */
135 if (subdetector == KLMElementNumbers::c_BKLM) {
136 m_StripEfficiency->setBarrelEfficiency(
137 section, sector, layer, plane, strip, efficiency, efficiencyError);
138 } else {
139 m_StripEfficiency->setEndcapEfficiency(
140 section, sector, layer, plane, strip, efficiency, efficiencyError);
141 }
142 }
143 saveCalibration(m_StripEfficiency, "KLMStripEfficiency");
144 }
145 /* Write histograms to output file. */
146 TFile* outputFile = new TFile(m_OutputFileName.c_str(), "recreate");
147 outputFile->cd();
148 matchedDigitsInPlane.get()->Write();
149 allExtHitsInPlane.get()->Write();
150 efficiencyHistogram->Write();
151 delete efficiencyHistogram;
152 delete outputFile;
153 /* Set output status. */
154 if (notEnoughData && !m_ForcedCalibration)
157}
158
160 const float* efficiency) const
161{
162 const int nPlanes = KLMPlaneArrayIndex::Instance().getNElements();
163 int newPlanes = 0;
164 for (int i = 0; i < nPlanes; ++i) {
165 if (m_Efficiency[i] > 0 && efficiency[i] == 0)
166 newPlanes++;
167 }
168 return newPlanes;
169}
170
172 const int* extHitsPlane) const
173{
174 const int nPlanes = KLMPlaneArrayIndex::Instance().getNElements();
175 int newPlanes = 0;
176 for (int i = 0; i < nPlanes; ++i) {
177 if (m_ExtHitsPlane[i] > 0 && extHitsPlane[i] == 0)
178 newPlanes++;
179 }
180 return newPlanes;
181}
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 successfully =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
CalibrationAlgorithm(const std::string &collectorModuleName)
Constructor - sets the prefix for collected objects (won't be accesses until execute(....
KLM channel index.
uint16_t getNElements() const
Get number of elements.
KLM plane array index.
static const KLMPlaneArrayIndex & Instance()
Instantiation.
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.
std::shared_ptr< T > getObjectPtr(const std::string &name, const std::vector< Calibration::ExpRun > &requestedRuns)
Get calibration data object by name and list of runs, the Merge function will be called to generate t...
uint16_t KLMPlaneNumber
Plane number.
Abstract base class for different kinds of events.