Belle II Software  release-08-01-10
CDCCrossTalkLibrary.h
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 #pragma once
9 
10 #include <iostream>
11 #include <iomanip>
12 #include <map>
13 #include <TObject.h>
14 #include <TRandom.h>
15 #include <cdc/dbobjects/CDCCrossTalkClasses.h>
16 
17 using std::vector;
18 using std::upper_bound;
19 using std::equal_range;
20 using std::pair;
21 
22 namespace Belle2 {
31  class CDCCrossTalkLibrary: public TObject {
32  public:
33 
37  CDCCrossTalkLibrary() = default;
38 
45  void addAsicRecord(const Short_t channel, const Short_t ADC, const asicChannels& asicInfo)
46  {
47  Short_t ch8 = channel % 8;
48  adcAsicTuple entry{ADC, ch8, asicInfo};
49  // keep sorted
50  auto place = upper_bound(m_library.begin(), m_library.end(), entry, adc_search());
51  m_library.insert(place, entry);
52  }
53 
54 
65  const vector< pair<Short_t, asicChannel> > getLibraryCrossTalk(Short_t channel, Short_t TDCin, Short_t ADCin, Short_t TOTin,
66  size_t entry = 0, bool insertSignalToOutput = false) const
67  {
68  // output
69  vector< pair<Short_t, asicChannel> > outRec;
70  auto prob = gRandom->Uniform();
71 
72  if (prob > pCrossTalk(ADCin)) {
74  if (insertSignalToOutput)
75  outRec.emplace_back(std::make_pair(channel, asicChannel{TDCin, ADCin, TOTin}));
76  return outRec;
77  }
78 
79  // find a range of possible candidates
80  Short_t ch8 = channel % 8;
81  adcChannelPair query{ADCin, ch8};
82  auto pADC = equal_range(m_library.begin(), m_library.end(), query, adc_search());
83 
84  size_t size = std::distance(pADC.first, pADC.second);
85  size_t val = 0;
86 
87 
88  if (entry != 0) {
89  // select modulo
90  val = entry % size;
91  } else {
92  // select random
93  val = gRandom->Integer(size);
94  }
95 
96  asicChannels rec;
97  bool recNotSet = true;
98  if (size == 0) {
99  if (pADC.first == m_library.end()) {
100  rec = m_library.back().record;
101  recNotSet = false;
102  } else {
103  if (pADC.first->Channel == ch8) {
104  rec = (pADC.first)->record;
105  recNotSet = false;
106  } else { // need to step back, if possible
107  if ((--pADC.first)->Channel == ch8) {
108  rec = (--pADC.first)->record;
109  recNotSet = false;
110  } else {
111  B2WARNING("Could not find CDC Cross talk library entry for channel, ADC: " << channel << " " << ADCin);
112  if (insertSignalToOutput)
113  outRec.emplace_back(std::make_pair(channel, asicChannel{TDCin, ADCin, TOTin}));
114  return outRec;
115  }
116  }
117  }
118  } else {
119  size_t count = 0;
120  for (auto p = pADC.first; p != pADC.second; ++p) {
121  if (count == val) {
122  rec = p->record;
123  recNotSet = false;
124  }
125  count += 1;
126  }
127  }
128 
129  B2ASSERT("CDC cross talk record not set", !recNotSet);
130 
132  Short_t DeltaTDC = TDCin - rec[ch8].TDC;
133 
134  if (abs(DeltaTDC) > 1000) {
135  B2WARNING("Large xTalk DeltaTDC=" << DeltaTDC);
136  }
137 
138  // std::cout << TDCin << " HHH " << rec[ch8].TDC << " " << ch8 << "\n";
139 
140 
141  for (int i = 0; i < 8; i += 1) {
142  if (rec[i].TDC > 0) {
143  if (i == ch8) { // store input values
144  B2ASSERT("CDC Cross talk entry for the selected channel cannot be empty " << ch8 << " " << rec[ch8].TDC, rec[ch8].TDC > -1);
145  if (insertSignalToOutput)
146  outRec.emplace_back(std::make_pair(channel, asicChannel{TDCin, ADCin, TOTin}));
147  } else { // adjust TDC for the cross talk, keep ADC and TOT
148  Short_t TDCout = rec[i].TDC + DeltaTDC;
149  outRec.emplace_back(std::make_pair(i - ch8 + channel, asicChannel{TDCout, rec[i].ADC, rec[i].TOT}));
150  }
151  }
152  }
153  return outRec;
154  }
155 
156 
157 
161  void dump(int verbosity) const
162  {
163  std::cout << "Content of CDCCrossTalkLibrary" << std::endl;
164  std::cout << "Size = " << m_library.size() << "\n";
165  if (verbosity < 1) return;
166 
167  for (size_t i = 0 ; i < m_library.size(); i += 1) {
168  auto [adc, ch, record] = m_library[i];
169  std::cout << "ADC: " << adc << " CH: " << ch << " count: " << i << "\n";
170  std::cout << " TDC ADC TOT \n";
171  for (auto rec : record) {
172  std::cout << " " << rec.TDC << " " << rec.ADC << " " << rec.TOT << "\n";
173  }
174  }
175  std::cout << "Probability of cross talk vs ADC: \n";
176  for (size_t a = 0; a < 8196; a++) {
177  std::cout << "P(" << a << ")=" << m_pCrossTalk[a] << "\n";
178  }
179  }
180 
182  void dumpEntry(size_t entry)
183  {
184 
185  if (entry > m_library.size()) entry = m_library.size() - 1;
186  auto [adc, ch, record] = m_library[entry];
187  std::cout << "ADC:" << adc << " CH: " << ch << " Size: " << m_library.size() << "\n";
188  std::cout << " TDC ADC TOT \n";
189  for (auto rec : record) {
190  std::cout << " " << rec.TDC << " " << rec.ADC << " " << rec.TOT << "\n";
191  }
192 
193  }
194 
198  double pCrossTalk(const Short_t ADC) const
199  {
200  if (ADC < 0) return 0;
201  if (ADC >= 8196) return 1;
202  return m_pCrossTalk[ADC];
203  }
204 
206  void setPCrossTalk(const double* probs)
207  {
208  for (size_t i = 0; i < m_pCrossTalk.size(); i += 1) {
209  m_pCrossTalk[i] = probs[i];
210  }
211  }
212 
213  private:
214  std::vector<adcAsicTuple> m_library;
215  array<float, 8196> m_pCrossTalk;
216 
218  };
219 
221 } // end namespace Belle2
Database object for ASIC crosstalk library.
void dumpEntry(size_t entry)
Dump single entry, for a given channel.
const vector< pair< Short_t, asicChannel > > getLibraryCrossTalk(Short_t channel, Short_t TDCin, Short_t ADCin, Short_t TOTin, size_t entry=0, bool insertSignalToOutput=false) const
Get cross talk record from the library.
ClassDef(CDCCrossTalkLibrary, 2)
ClassDef.
void setPCrossTalk(const double *probs)
Store x-talk probability.
void dump(int verbosity) const
Print out contents of the library.
CDCCrossTalkLibrary()=default
Default constructor.
array< float, 8196 > m_pCrossTalk
x-talk probability
double pCrossTalk(const Short_t ADC) const
Get probability of the cross talk.
void addAsicRecord(const Short_t channel, const Short_t ADC, const asicChannels &asicInfo)
Add a new ASIC record to the library.
std::vector< adcAsicTuple > m_library
Library.
array< asicChannel, 8 > asicChannels
fixed sized array of ASIC channels
Abstract base class for different kinds of events.
tuple to store ADC,Channel -> 8 asicChannels
functions to search in the sorted list of tuples
record to be used to store ASIC info