Belle II Software  release-05-02-19
KLMChannelStatusAlgorithm.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2020 Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Kirill Chilikin *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 /* Own header. */
12 #include <klm/calibration/KLMChannelStatusAlgorithm.h>
13 
14 /* Belle 2 headers. */
15 #include <framework/logging/Logger.h>
16 
17 /* ROOT headers. */
18 #include <TTree.h>
19 
20 using namespace Belle2;
21 
23 {
24 }
25 
27 {
28  m_ModuleStatus = new KLMChannelStatus(*results.m_ModuleStatus);
29  m_ChannelStatus = new KLMChannelStatus(*results.m_ChannelStatus);
30  m_HitMapChannel = results.m_HitMapChannel;
31  m_HitMapModule = results.m_HitMapModule;
32  m_HitMapSector = results.m_HitMapSector;
33  m_HitMapModuleNoHot = results.m_HitMapModuleNoHot;
34  m_HitMapSectorNoHot = results.m_HitMapSectorNoHot;
35  m_ModuleActiveChannelMap = results.m_ModuleActiveChannelMap;
36  m_TotalHitNumber = results.m_TotalHitNumber;
37  m_HitNumberBKLM = results.m_HitNumberBKLM;
38  m_HitNumberEKLM = results.m_HitNumberEKLM;
39  m_HitNumberBKLMNoHot = results.m_HitNumberBKLMNoHot;
40  m_HitNumberEKLMNoHot = results.m_HitNumberEKLMNoHot;
41 }
42 
44 {
45  if (m_ModuleStatus != nullptr)
46  delete m_ModuleStatus;
47  if (m_ChannelStatus != nullptr)
48  delete m_ChannelStatus;
49 }
50 
52  CalibrationAlgorithm("KLMChannelStatusCollector"),
53  m_ElementNumbers(&(KLMElementNumbers::Instance()))
54 {
55 }
56 
58 {
59 }
60 
62 {
63  uint16_t channel, module, sector;
64  unsigned int hits, moduleHits, maxHits;
65  /*
66  * Fill channel hit map. Note that more than one entry can exist for the same
67  * channel due to merging of collected data for several runs. Thus, the
68  * number of hits is summed.
69  */
70  std::shared_ptr<TTree> calibrationData;
71  calibrationData = getObjectPtr<TTree>("calibration_data");
72  calibrationData->SetBranchAddress("channel", &channel);
73  calibrationData->SetBranchAddress("hits", &hits);
74  int n = calibrationData->GetEntries();
79  for (int i = 0; i < n; ++i) {
80  calibrationData->GetEntry(i);
82  channel, m_Results.m_HitMapChannel.getChannelData(channel) + hits);
84  if (m_ElementNumbers->isBKLMChannel(channel))
85  m_Results.m_HitNumberBKLM += hits;
86  else
87  m_Results.m_HitNumberEKLM += hits;
88  }
90  /*
91  * A new object is created, because saveCalibration() stores a pointer
92  * to KLMChannelStatus, and it is necessary to save the payloads to commit
93  * them at the end of calibration.
94  */
97  /* If there are no hits, then mark all channels as dead. */
98  KLMChannelIndex klmChannels;
99  if (m_Results.m_TotalHitNumber == 0) {
100  for (KLMChannelIndex& klmChannel : klmChannels) {
101  channel = klmChannel.getKLMChannelNumber();
103  }
104  saveCalibration(m_Results.m_ChannelStatus, "KLMChannelStatus");
106  }
107  /* Fill module and sector hit maps. */
109  for (KLMChannelIndex& klmModule : klmModules)
110  m_Results.m_HitMapModule.setChannelData(klmModule.getKLMModuleNumber(), 0);
112  for (KLMChannelIndex& klmSector : klmSectors)
113  m_Results.m_HitMapSector.setChannelData(klmSector.getKLMSectorNumber(), 0);
114  for (KLMChannelIndex& klmChannel : klmChannels) {
115  channel = klmChannel.getKLMChannelNumber();
116  module = klmChannel.getKLMModuleNumber();
117  sector = klmChannel.getKLMSectorNumber();
118  hits = m_Results.m_HitMapChannel.getChannelData(channel);
120  module, m_Results.m_HitMapModule.getChannelData(module) + hits);
122  sector, m_Results.m_HitMapSector.getChannelData(sector) + hits);
123  }
124  /*
125  * Mark all channels in modules without hits as dead.
126  * Search for hot channels.
127  */
128  for (KLMChannelIndex& klmModule : klmModules) {
129  module = klmModule.getKLMModuleNumber();
130  moduleHits = m_Results.m_HitMapModule.getChannelData(module);
131  KLMChannelIndex klmNextModule(klmModule);
132  ++klmNextModule;
133  KLMChannelIndex klmChannel(klmModule);
135  if (moduleHits == 0) {
136  for (; klmChannel != klmNextModule; ++klmChannel) {
137  channel = klmChannel.getKLMChannelNumber();
139  }
141  continue;
142  }
143  unsigned int activeChannels = 0;
144  for (; klmChannel != klmNextModule; ++klmChannel) {
145  channel = klmChannel.getKLMChannelNumber();
146  hits = m_Results.m_HitMapChannel.getChannelData(channel);
147  if (hits > 0)
148  activeChannels++;
149  }
150  m_Results.m_ModuleActiveChannelMap.setChannelData(module, activeChannels);
151  KLMChannelIndex klmChannelMaxHits;
152  while (1) {
153  klmChannel = klmModule;
155  maxHits = 0;
156  for (; klmChannel != klmNextModule; ++klmChannel) {
157  channel = klmChannel.getKLMChannelNumber();
160  continue;
161  hits = m_Results.m_HitMapChannel.getChannelData(channel);
162  if (hits > maxHits) {
163  klmChannelMaxHits = klmChannel;
164  maxHits = hits;
165  }
166  }
167  if (maxHits == 0)
168  break;
169  if (!markHotChannel(klmChannelMaxHits.getKLMChannelNumber(),
170  moduleHits, activeChannels))
171  break;
172  moduleHits -= maxHits;
173  activeChannels--;
174  }
175  }
176  /* Fill module and sector hit maps with hot channels subtracted. */
177  for (KLMChannelIndex& klmModule : klmModules)
178  m_Results.m_HitMapModuleNoHot.setChannelData(klmModule.getKLMModuleNumber(), 0);
179  for (KLMChannelIndex& klmSector : klmSectors)
180  m_Results.m_HitMapSectorNoHot.setChannelData(klmSector.getKLMSectorNumber(), 0);
183  for (KLMChannelIndex& klmChannel : klmChannels) {
184  channel = klmChannel.getKLMChannelNumber();
186  continue;
187  module = klmChannel.getKLMModuleNumber();
188  sector = klmChannel.getKLMSectorNumber();
189  hits = m_Results.m_HitMapChannel.getChannelData(channel);
191  module, m_Results.m_HitMapModuleNoHot.getChannelData(module) + hits);
193  sector, m_Results.m_HitMapSectorNoHot.getChannelData(sector) + hits);
194  if (m_ElementNumbers->isBKLMChannel(channel))
196  else
198  }
199  /* Sector status. */
200  int activeSectorsBKLM = 0;
201  int activeSectorsEKLM = 0;
202  for (KLMChannelIndex& klmSector : klmSectors) {
203  sector = klmSector.getKLMSectorNumber();
205  if (hits > 0) {
206  if (m_ElementNumbers->isBKLMChannel(sector))
207  activeSectorsBKLM++;
208  else
209  activeSectorsEKLM++;
210  }
211  }
212  double averageHitsActiveSector = 0;
213  if (activeSectorsBKLM > 0) {
214  averageHitsActiveSector = double(m_Results.m_HitNumberBKLMNoHot) /
215  activeSectorsBKLM;
216  }
217  for (KLMChannelIndex bklmSector = klmSectors.beginBKLM();
218  bklmSector != klmSectors.endBKLM(); ++bklmSector) {
219  sector = bklmSector.getKLMSectorNumber();
220  calibrateSector(sector, averageHitsActiveSector);
221  }
222  if (activeSectorsEKLM > 0) {
223  averageHitsActiveSector = double(m_Results.m_HitNumberEKLMNoHot) /
224  activeSectorsBKLM;
225  }
226  for (KLMChannelIndex eklmSector = klmSectors.beginEKLM();
227  eklmSector != klmSectors.endEKLM(); ++eklmSector) {
228  sector = eklmSector.getKLMSectorNumber();
229  calibrateSector(sector, averageHitsActiveSector);
230  }
231  /* Module status. */
232  if (m_Results.m_ModuleStatus == nullptr)
234  for (KLMChannelIndex& klmModule : klmModules)
235  calibrateModule(klmModule.getKLMModuleNumber());
236  /* Channel-based calibration. */
237  bool notEnoughData = false;
238  for (KLMChannelIndex& klmModule : klmModules) {
239  module = klmModule.getKLMModuleNumber();
240  moduleHits = m_Results.m_HitMapModuleNoHot.getChannelData(module);
241  KLMChannelIndex klmNextModule(klmModule);
242  ++klmNextModule;
243  KLMChannelIndex klmChannel(klmModule);
245  if (moduleHits == 0)
246  continue;
247  unsigned int activeChannels = 0;
248  for (; klmChannel != klmNextModule; ++klmChannel) {
249  channel = klmChannel.getKLMChannelNumber();
251  continue;
252  hits = m_Results.m_HitMapChannel.getChannelData(channel);
253  if (hits > 0)
254  activeChannels++;
255  }
256  double averageHits = double(moduleHits) / activeChannels;
257  if (averageHits < m_MinimalAverageHitNumber && !m_ForcedCalibration) {
258  if (!notEnoughData) {
259  B2INFO("KLM module " << klmModule.getKLMModuleNumber() <<
260  " (subdetector " << klmModule.getSubdetector() <<
261  ", section " << klmModule.getSection() <<
262  ", sector " << klmModule.getSector() <<
263  ", layer " << klmModule.getLayer() <<
264  "): " << moduleHits << " hits, average: " << averageHits << ".");
265  }
266  notEnoughData = true;
267  continue;
268  }
269  klmChannel = klmModule;
271  for (; klmChannel != klmNextModule; ++klmChannel)
273  }
274  if (notEnoughData)
276  saveCalibration(m_Results.m_ChannelStatus, "KLMChannelStatus");
278 }
279 
281  uint16_t sector, double averageHitsActiveSector)
282 {
283  unsigned int hits = m_Results.m_HitMapSectorNoHot.getChannelData(sector);
284  if (hits == 0)
285  return;
286  double r = log(hits / averageHitsActiveSector) / log(10.);
287  if (fabs(r) > m_MaximalLogSectorHitsRatio) {
288  B2WARNING("Number of hits in sector " << sector << " (" << hits <<
289  ") strongly deviates from the average (" <<
290  averageHitsActiveSector <<
291  "), the 10-based logarithm of the ratio is " << r << ".");
292  }
293 }
294 
296 {
297  unsigned int hits = m_Results.m_HitMapModule.getChannelData(module);
298  if (hits >= m_MinimalModuleHitNumber) {
301  } else {
303  module, KLMChannelStatus::c_Dead);
304  }
305 }
306 
308  uint16_t channel, unsigned int moduleHits, int activeChannels)
309 {
310  unsigned int hits = m_Results.m_HitMapChannel.getChannelData(channel);
311  if (activeChannels == 1) {
314  channel, KLMChannelStatus::c_Hot);
315  return true;
316  }
317  } else {
318  double r = hits / (double(moduleHits - hits) / (activeChannels - 1));
319  if (hits >= m_MinimalHitNumberHotChannel &&
322  channel, KLMChannelStatus::c_Hot);
323  return true;
324  }
325  }
326  return false;
327 }
328 
330 {
331  unsigned int hits = m_Results.m_HitMapChannel.getChannelData(channel);
334  return;
335  if (hits > 0) {
337  channel, KLMChannelStatus::c_Normal);
338  } else {
340  channel, KLMChannelStatus::c_Dead);
341  }
342 }
Belle2::KLMChannelIndex::endEKLM
KLMChannelIndex & endEKLM()
Last channel for EKLM.
Definition: KLMChannelIndex.cc:211
Belle2::KLMChannelStatusAlgorithm::Results::m_ModuleActiveChannelMap
KLMChannelMapValue< unsigned int > m_ModuleActiveChannelMap
Module active-channel map (number of active channels in module).
Definition: KLMChannelStatusAlgorithm.h:177
Belle2::KLMChannelStatusAlgorithm::Results::m_HitMapModule
KLMChannelMapValue< unsigned int > m_HitMapModule
Module hit map.
Definition: KLMChannelStatusAlgorithm.h:165
Belle2::KLMChannelStatusAlgorithm::m_MinimalHitNumberRatioHotChannel
double m_MinimalHitNumberRatioHotChannel
Minimal ratio of number of hits in this channel and average over other channels in this module to mar...
Definition: KLMChannelStatusAlgorithm.h:352
Belle2::KLMChannelStatusAlgorithm::m_MinimalHitNumberHotChannel
unsigned int m_MinimalHitNumberHotChannel
Minimal number of hits to mark to mark the channel as hot.
Definition: KLMChannelStatusAlgorithm.h:346
Belle2::KLMChannelStatusAlgorithm::Results::m_HitMapModuleNoHot
KLMChannelMapValue< unsigned int > m_HitMapModuleNoHot
Module hit map (no hit channels).
Definition: KLMChannelStatusAlgorithm.h:171
Belle2::KLMChannelStatus::c_Undetermined
@ c_Undetermined
Undetermined (used during calibration).
Definition: KLMChannelStatus.h:59
Belle2::KLMElementNumbers::isBKLMChannel
bool isBKLMChannel(uint16_t channel) const
Determine whether a given channel is in BKLM.
Definition: KLMElementNumbers.cc:82
Belle2::KLMChannelStatus::c_Hot
@ c_Hot
Hot channel (large background).
Definition: KLMChannelStatus.h:56
Belle2::KLMChannelStatusAlgorithm::m_MaximalLogSectorHitsRatio
double m_MaximalLogSectorHitsRatio
Maximal absolute value of the logarithm (base 10) of the ratio of the number of hits in this sector a...
Definition: KLMChannelStatusAlgorithm.h:340
Belle2::KLMChannelIndex::endBKLM
KLMChannelIndex & endBKLM()
Last channel for BKLM.
Definition: KLMChannelIndex.cc:195
Belle2::KLMChannelStatusAlgorithm::~KLMChannelStatusAlgorithm
~KLMChannelStatusAlgorithm()
Destructor.
Definition: KLMChannelStatusAlgorithm.cc:57
Belle2::KLMChannelStatusAlgorithm::Results::Results
Results()
Constructor.
Definition: KLMChannelStatusAlgorithm.cc:22
Belle2::KLMChannelStatusAlgorithm::Results::m_HitMapSectorNoHot
KLMChannelMapValue< unsigned int > m_HitMapSectorNoHot
Sector hit map (no hot channels).
Definition: KLMChannelStatusAlgorithm.h:174
Belle2::KLMChannelStatusAlgorithm::m_ForcedCalibration
bool m_ForcedCalibration
Whether the calibration is forced (calibrate even for insufficient average number of hits).
Definition: KLMChannelStatusAlgorithm.h:328
Belle2::KLMChannelStatus
KLM channel status.
Definition: KLMChannelStatus.h:37
Belle2::KLMChannelIndex::c_IndexLevelLayer
@ c_IndexLevelLayer
Layer.
Definition: KLMChannelIndex.h:52
Belle2::CalibrationAlgorithm::saveCalibration
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
Definition: CalibrationAlgorithm.cc:290
Belle2::KLMChannelStatusAlgorithm::calibrateChannel
void calibrateChannel(uint16_t channel)
Calibrate channel.
Definition: KLMChannelStatusAlgorithm.cc:329
Belle2::KLMChannelStatusAlgorithm::Results::m_ModuleStatus
KLMChannelStatus * m_ModuleStatus
Module status.
Definition: KLMChannelStatusAlgorithm.h:156
Belle2::KLMChannelIndex::beginEKLM
KLMChannelIndex beginEKLM()
First channel for EKLM.
Definition: KLMChannelIndex.cc:205
Belle2::KLMChannelStatusAlgorithm::Results::~Results
~Results()
Destructor.
Definition: KLMChannelStatusAlgorithm.cc:43
Belle2::KLMChannelStatusAlgorithm::Results::m_HitNumberEKLMNoHot
unsigned int m_HitNumberEKLMNoHot
Number of hits in EKLM (no hot channels).
Definition: KLMChannelStatusAlgorithm.h:192
Belle2::KLMChannelStatusAlgorithm::m_MinimalModuleHitNumber
unsigned int m_MinimalModuleHitNumber
Minimal module hit number for module-based calibration.
Definition: KLMChannelStatusAlgorithm.h:331
Belle2::CalibrationAlgorithm::c_OK
@ c_OK
Finished successfuly =0 in Python.
Definition: CalibrationAlgorithm.h:51
Belle2::KLMChannelStatusAlgorithm::m_MinimalAverageHitNumber
double m_MinimalAverageHitNumber
Minimal average number of hits per channel required for calibration.
Definition: KLMChannelStatusAlgorithm.h:334
Belle2::KLMChannelStatusAlgorithm::Results::m_HitMapSector
KLMChannelMapValue< unsigned int > m_HitMapSector
Sector hit map.
Definition: KLMChannelStatusAlgorithm.h:168
Belle2::KLMChannelStatusAlgorithm::calibrate
CalibrationAlgorithm::EResult calibrate() override
Calibration.
Definition: KLMChannelStatusAlgorithm.cc:61
Belle2::KLMChannelIndex::getKLMChannelNumber
uint16_t getKLMChannelNumber() const
Get KLM channel number.
Definition: KLMChannelIndex.cc:145
Belle2::KLMChannelIndex::beginBKLM
KLMChannelIndex beginBKLM()
First channel for BKLM.
Definition: KLMChannelIndex.cc:189
Belle2::CalibrationAlgorithm::clearCalibrationData
void clearCalibrationData()
Clear calibration data.
Definition: CalibrationAlgorithm.h:334
Belle2::KLMChannelIndex::c_IndexLevelSector
@ c_IndexLevelSector
Sector.
Definition: KLMChannelIndex.h:49
Belle2::KLMChannelStatus::c_Dead
@ c_Dead
Dead channel (no signal).
Definition: KLMChannelStatus.h:53
Belle2::KLMChannelStatusAlgorithm::Results::m_TotalHitNumber
unsigned int m_TotalHitNumber
Total hit number.
Definition: KLMChannelStatusAlgorithm.h:180
Belle2::KLMChannelStatusAlgorithm::Results::m_HitNumberBKLMNoHot
unsigned int m_HitNumberBKLMNoHot
Number of hits in BKLM (no hot channels).
Definition: KLMChannelStatusAlgorithm.h:189
Belle2::KLMChannelStatusAlgorithm::Results::m_HitMapChannel
KLMChannelMapValue< unsigned int > m_HitMapChannel
Channel hit map.
Definition: KLMChannelStatusAlgorithm.h:162
Belle2::KLMChannelMapValue::setChannelData
void setChannelData(uint16_t channel, const T data)
Set channel data.
Definition: KLMChannelMapValue.h:81
Belle2::KLMChannelMapValue::setDataAllChannels
void setDataAllChannels(const T data)
Set data for all channels.
Definition: KLMChannelMapValue.h:96
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::KLMChannelStatusAlgorithm::Results::m_ChannelStatus
KLMChannelStatus * m_ChannelStatus
Channel status.
Definition: KLMChannelStatusAlgorithm.h:159
Belle2::KLMChannelStatusAlgorithm::calibrateModule
void calibrateModule(uint16_t module)
Calibrate module.
Definition: KLMChannelStatusAlgorithm.cc:295
Belle2::KLMChannelStatus::setChannelStatus
void setChannelStatus(uint16_t channel, enum ChannelStatus status)
Set channel status.
Definition: KLMChannelStatus.cc:40
Belle2::KLMChannelStatusAlgorithm::calibrateSector
void calibrateSector(uint16_t sector, double averageHitsActiveSector)
Caliobrate sector.
Definition: KLMChannelStatusAlgorithm.cc:280
Belle2::KLMChannelStatusAlgorithm::m_Results
Results m_Results
Calibration results.
Definition: KLMChannelStatusAlgorithm.h:358
Belle2::KLMChannelStatusAlgorithm::m_MinimalHitNumberSingleHotChannel
unsigned int m_MinimalHitNumberSingleHotChannel
Minimal number of hits in a single channel to mark it as hot.
Definition: KLMChannelStatusAlgorithm.h:343
Belle2::CalibrationAlgorithm::EResult
EResult
The result of calibration.
Definition: CalibrationAlgorithm.h:50
Belle2::KLMChannelStatusAlgorithm::Results
Calibration results.
Definition: KLMChannelStatusAlgorithm.h:44
Belle2::KLMChannelStatusAlgorithm::KLMChannelStatusAlgorithm
KLMChannelStatusAlgorithm()
Constructor.
Definition: KLMChannelStatusAlgorithm.cc:51
Belle2::CalibrationAlgorithm::c_NotEnoughData
@ c_NotEnoughData
Needs more data =2 in Python.
Definition: CalibrationAlgorithm.h:53
Belle2::KLMChannelIndex
KLM channel index.
Definition: KLMChannelIndex.h:33
Belle2::CalibrationAlgorithm
Base class for calibration algorithms.
Definition: CalibrationAlgorithm.h:47
Belle2::KLMChannelStatus::setStatusAllChannels
void setStatusAllChannels(enum ChannelStatus status)
Set staus for all channels.
Definition: KLMChannelStatus.cc:53
Belle2::KLMElementNumbers
KLM element numbers.
Definition: KLMElementNumbers.h:37
Belle2::KLMChannelStatus::c_Normal
@ c_Normal
Normally operating channel.
Definition: KLMChannelStatus.h:50
Belle2::KLMChannelMapValue::getChannelData
const T getChannelData(uint16_t channel) const
Get channel data.
Definition: KLMChannelMapValue.h:65
Belle2::KLMChannelIndex::setIndexLevel
void setIndexLevel(enum IndexLevel indexLevel)
Set index level.
Definition: KLMChannelIndex.cc:67
Belle2::KLMChannelStatus::getChannelStatus
enum ChannelStatus getChannelStatus(uint16_t channel) const
Get channel status.
Definition: KLMChannelStatus.cc:32
Belle2::KLMChannelStatusAlgorithm::Results::m_HitNumberBKLM
unsigned int m_HitNumberBKLM
Number of hits in BKLM.
Definition: KLMChannelStatusAlgorithm.h:183
Belle2::KLMChannelStatusAlgorithm::Results::m_HitNumberEKLM
unsigned int m_HitNumberEKLM
Number of hits in EKLM.
Definition: KLMChannelStatusAlgorithm.h:186
Belle2::KLMChannelIndex::c_IndexLevelStrip
@ c_IndexLevelStrip
Strip.
Definition: KLMChannelIndex.h:58
Belle2::KLMChannelStatusAlgorithm::markHotChannel
bool markHotChannel(uint16_t channel, unsigned int moduleHits, int activeChannels)
Mark hot channel.
Definition: KLMChannelStatusAlgorithm.cc:307
Belle2::KLMChannelStatusAlgorithm::m_ElementNumbers
const KLMElementNumbers * m_ElementNumbers
Element numbers.
Definition: KLMChannelStatusAlgorithm.h:355