Belle II Software  release-08-01-10
AsicBackgroundDetector.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 <tracking/trackFindingCDC/findlets/minimal/AsicBackgroundDetector.h>
9 #include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
10 #include <tracking/trackFindingCDC/utilities/StringManipulation.h>
11 #include <framework/core/ModuleParamList.templateDetails.h>
12 #include <cdc/dataobjects/CDCHit.h>
13 #include <framework/logging/Logger.h>
14 #include <iostream>
15 
16 using namespace Belle2;
17 using namespace TrackFindingCDC;
18 using std::vector;
19 using std::map;
20 using std::pair;
21 using std::sort;
22 
24 {
26  // database:
27  m_channelMapFromDB = std::make_unique<DBArray<CDCChannelMap>> ();
28 
29  if ((*m_channelMapFromDB).isValid()) {
30  B2DEBUG(25, "CDC Channel map is valid");
31  } else {
32  B2FATAL("CDC Channel map is not valid");
33  }
34 }
35 
37 {
39 
40  // Load map from DB:
41  for (const auto& cm : (*m_channelMapFromDB)) {
42  const int isl = cm.getISuperLayer();
43  const int il = cm.getILayer();
44  const int iw = cm.getIWire();
45  const int iBoard = cm.getBoardID();
46  const int iCh = cm.getBoardChannel();
47  const WireID wireId(isl, il, iw);
48  m_map[wireId.getEWire()] = std::pair<int, int>(iBoard, iCh);
49  }
50 }
51 
53 {
54  return "Marks hits as background using ASIC-based filter.";
55 }
56 
57 void AsicBackgroundDetector::apply(std::vector<CDCWireHit>& wireHits)
58 {
59 
60  map< pair<int, int>, vector<CDCWireHit*>> groupedByAsic;
61  for (CDCWireHit& wireHit : wireHits) {
62  auto eWire = wireHit.getWireID().getEWire();
63  B2ASSERT("Channel map NOT found for the channel", m_map.count(eWire) > 0);
64  auto board = m_map[eWire].first;
65  auto channel = m_map[eWire].second;
66  auto asicID = pair<int, int>(board, channel / 8); // ASIC are groups of 8 channels
67  groupedByAsic[asicID].push_back(&wireHit);
68  };
69  for (auto& asicList : groupedByAsic) {
70  applyAsicFilter(asicList.second);
71  };
72 
73  return;
74 }
75 
76 void AsicBackgroundDetector::exposeParameters(ModuleParamList* moduleParamList, const std::string& prefix)
77 {
78  Super::exposeParameters(moduleParamList, prefix);
79  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "minimalHitNumberASIC"),
81  "Required number of hits per ASIC for background check",
83  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "deviationFromMedianTDCinASIC"),
85  "Flag hits as cross talk if TDC does not deviate from median more than this value",
87  moduleParamList->addParameter(TrackFindingCDC::prefixed(prefix, "minimalNSignalASIC"),
89  "Flag background hits only when ASIC contains no more than this number of signal hits",
91 }
92 
93 void AsicBackgroundDetector::applyAsicFilter(std::vector<CDCWireHit*>& wireHits)
94 {
95 
96  if (wireHits.size() < m_minimal_hit_number) {
97  return;
98  };
99 
100  if (wireHits.size() > 8) {
102  auto eWire = wireHits[0]->getWireID().getEWire();
103  auto board = m_map[eWire].first;
104 
105  if (m_max_asic_error_messages > 0) {
106  B2ERROR("Number of hits per asic should not exceed 8, observe too many hits."
107  << LogVar("nHits", wireHits.size())
108  << LogVar("Board ID", board));
110  } else {
111  B2WARNING("Number of hits per asic should not exceed 8, observe too many hits."
112  << LogVar("nHits", wireHits.size())
113  << LogVar("Board ID", board));
114  }
115 
117  for (auto& hit : wireHits) {
118  (*hit)->setBackgroundFlag();
119  (*hit)->setTakenFlag();
120  }
121  return;
122  }
123 
124  // compute median time:
125  vector<short> times;
126  for (auto& hit : wireHits) {
127  short tdc = hit->getHit()->getTDCCount();
128  times.push_back(tdc);
129  }
130  sort(times.begin(), times.end());
131  int mid = times.size() / 2;
132  double median = times.size() % 2 == 0 ? (times[mid] + times[mid - 1]) / 2 : times[mid];
133 
134  size_t nbg = 0;
135  int adcOnMedian = 0;
136  int adcOffMedian = 0;
137  for (auto& hit : wireHits) {
138  int adc = hit->getHit()->getADCCount();
139  if (fabs(hit->getHit()->getTDCCount() - median) < m_deviation_from_median) {
140  nbg++;
141  if (adc > adcOnMedian) adcOnMedian = adc;
142  } else {
143  if (adc > adcOffMedian) adcOffMedian = adc;
144  }
145  }
146 
147  if ((nbg < times.size()) // at least 1 hit with different TDC ("signal")
148  && (nbg > 1) // more than one candidate hits
149  && (nbg > times.size() - m_nsignal_max) // a few background hits
150  && (adcOnMedian < adcOffMedian) // triggered by large ADC "signal"
151  ) {
152 
153  // mark hits too close to the median time as background:
154  for (auto& hit : wireHits) {
155  if (fabs(hit->getHit()->getTDCCount() - median) < m_deviation_from_median) {
156  (*hit)->setBackgroundFlag();
157  (*hit)->setTakenFlag();
158  }
159  }
160  }
161 }
The Module parameter list class.
virtual void apply(std::vector< CDCWireHit > &wireHits) final
Main algorithm marking hit as background.
std::unique_ptr< DBArray< CDCChannelMap > > m_channelMapFromDB
Channel map retrieved from DB.
double m_deviation_from_median
distance from median TDC, to be considered as bg.
void beginRun() final
Reload channel map if needed.
size_t m_nsignal_max
max. number of signal-like hits in ASIC for background check
std::map< int, std::pair< int, int > > m_map
map from ewire to board/channel ID
std::string getDescription() final
Short description of the findlet.
size_t m_max_asic_error_messages
max. number of logged error messages for number of hits per ASIC check
virtual void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) final
Expose the parameters to a module.
size_t m_minimal_hit_number
min. number of hits in ASIC for background check
void applyAsicFilter(std::vector< CDCWireHit * > &wireHits)
Algorithm marking hit as background for each CDC ASIC.
Class representing a hit wire in the central drift chamber.
Definition: CDCWireHit.h:55
void initialize() override
Receive and dispatch signal before the start of the event processing.
void beginRun() override
Receive and dispatch signal for the beginning of a new run.
virtual void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix)
Forward prefixed parameters of this findlet to the module parameter list.
Definition: Findlet.h:69
Class to identify a wire inside the CDC.
Definition: WireID.h:34
unsigned short getEWire() const
Getter for encoded wire number.
Definition: WireID.h:154
Class to store variables with their name which were sent to the logging service.
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
Abstract base class for different kinds of events.