UUBDownsampleFilter.h
Go to the documentation of this file.
1 #ifndef _sdet_UUBDownsampleFilter_h_
2 #define _sdet_UUBDownsampleFilter_h_
3 
4 #include <utl/Trace.h>
5 #include <utl/TimeDistribution.h>
6 #include <utl/AugerUnits.h>
7 #include <utl/Math.h>
8 
9 
10 namespace sdet {
11 
27  namespace {
28 
29  // FIR coefficients from Dave Nitz's implementation in UUB firmware
30  constexpr int kFirCoefficients[] = { 5, 0, 12, 22, 0, -61, -96, 0, 256, 551, 681, 551, 256, 0, -96, -61, 0, 22, 12, 0, 5 };
31  // FIR normalization
32  // in firmware an 11-bit right shift is used instead, ie 2048
33  constexpr int kFirNormalizationBitShift = 11;
34  //const int kFirNormalization = 2059; // true norm of FIR
35  //constexpr double kFirNormalization = (1 << kFirNormalizationBitShift); // actually used
36  constexpr double kUbSampling = 25*utl::nanosecond;
37  constexpr int kADCSaturation = 4095;
38 
39 
40  // enforce ADC saturation, both ways
41  inline
42  constexpr
43  int
44  Clip(const int i)
45  {
46  return std::max(0, std::min(i, kADCSaturation));
47  }
48 
49  }
50 
51 
52  // phase can be one only of { 0, 1, 2 }
53  inline
55  UUBDownsampleFilter(const utl::TraceI& trace, const int phase = 1)
56  {
57  // input trace is assumed to have 8.333ns binning
58  const int n = trace.GetSize();
59  if (!n)
60  return utl::TraceI(0, kUbSampling);
61  const int m = utl::Length(kFirCoefficients);
62  const int m2 = m / 2;
63  std::vector<int> t;
64  t.reserve(n + 2*m2);
65  // pad front with the first trace values, but backwards
66  for (int i = m2; i; --i)
67  t.push_back(trace[i]);
68  // copy the whole trace
69  for (int i = 0; i < n; ++i)
70  t.push_back(trace[i]);
71  // pad back with the last trace values, but backwards
72  for (int i = 1; i <= m2; ++i)
73  t.push_back(trace[n-1-i]);
74  const int n3 = n / 3;
75  utl::TraceI res(n3, kUbSampling);
76  for (int k = 0; k < n3; ++k) {
77  auto& v = res[k];
78  const int i = 3*k + phase;
79  for (int j = 0; j < m; ++j)
80  v += t[i + j] * kFirCoefficients[j];
81  v >>= kFirNormalizationBitShift;
82  v = Clip(v);
83  }
84  return res;
85  }
86 
87 
88  // phase can be one only of { 0, 1, 2 }
89  inline
91  UUBDownsampleFilter(const utl::TimeDistributionI& trace, const int phase = 1)
92  {
93  const int n = trace.GetNumSlots();
94  if (!n)
95  return utl::TimeDistributionI(kUbSampling);
96  const int m = utl::Length(kFirCoefficients);
97  const int m2 = m / 2;
98  std::vector<int> t;
99  t.reserve(n + 2*m2);
100  // pad front with first values, but backwards
101  const int start = trace.GetStart();
102  for (int i = m2; i; --i)
103  t.push_back(trace.At(start + i));
104  // copy the whole trace
105  const int stop = trace.GetStop();
106  for (int i = start; i <= stop; ++i)
107  t.push_back(trace.At(i));
108  // pad back with last values, but backwards
109  for (int i = 1; i <= m2; ++i)
110  t.push_back(trace.At(stop - i));
111  utl::TimeDistributionI res(kUbSampling);
112  const int startIndex = utl::FloorDiv(start+2, 3);
113  const int stopIndex = utl::FloorDiv(stop-2, 3);
114  for (int k = startIndex; k < stopIndex; ++k) {
115  auto& v = res[k];
116  const int i = 3*k + phase - start;
117  for (int j = 0; j < m; ++j)
118  v += t[i + j] * kFirCoefficients[j];
119  v >>= kFirNormalizationBitShift;
120  v = Clip(v);
121  }
122  return res;
123  }
124 
125 
126  // helpers for vectors of traces
127 
128  template<class Trace>
129  inline
130  std::vector<Trace>
131  UUBDownsampleFilter(const std::vector<Trace>& traces)
132  {
133  std::vector<Trace> r;
134  r.reserve(traces.size());
135  for (const auto& t : traces)
136  r.emplace_back(UUBDownsampleFilter(t));
137  return r;
138  }
139 
140 
141  template<class Trace>
142  inline
143  std::vector<Trace>
144  UUBDownsampleFilter(const std::vector<const Trace*>& traces)
145  {
146  std::vector<Trace> r;
147  r.reserve(traces.size());
148  for (const auto t : traces)
149  r.emplace_back(UUBDownsampleFilter(*t));
150  return r;
151  }
152 
153 }
154 
155 
156 #endif
T At(const double time) const
int GetStart() const
First slot with data.
Trace< int > TraceI
Definition: Trace-fwd.h:24
Histogram class for time distributions with suppressed empty bins.
constexpr double m2
Definition: AugerUnits.h:122
#define max(a, b)
constexpr double nanosecond
Definition: AugerUnits.h:143
utl::TraceI UUBDownsampleFilter(const utl::TraceI &trace, const int phase=1)
int GetStop() const
Last slot with data (1 less than First slot if no data)
constexpr int FloorDiv(const int num, const int den)
SizeType GetSize() const
Definition: Trace.h:156
int GetNumSlots() const
Number of slots from first slot with data up to last slot with data, including empty slots...
TimeDistribution< int > TimeDistributionI
constexpr double m
Definition: AugerUnits.h:121

, generated on Tue Sep 26 2023.