otsdaq-mu2e-stm  5.02.01
data_struct.hh
1 #ifndef DATA_STRUCT_HH_
2 #define DATA_STRUCT_HH_
3 
4 // STM data header
5 #include "Mu2e-STMDAQ/config/stm_data.hh"
6 
7 // Struct of baseline fit data
8 struct baseline_fit{
9 
10  // Baseline Gaussian Values
11  double w0 = 0;
12  double mu0 = 0;
13  double sigma0 = 0;
14 
15  // Pulse Tail Exponential Values
16  double w1 = 0;
17  double t = 0;
18  double lambda = 0;
19 
20  // Reinitalise struct
21  void reset() {
22  w0 = 0;
23  mu0 = 0;
24  sigma0 = 0;
25  w1 = 0;
26  t = 0;
27  lambda = 0;
28  }
29 
30 };
31 
32 // Pulse height
33 struct pulse_height {
34  int16_t time = 0; // Peak time
35  int16_t height = 0; // Peak height
36  pulse_height(int16_t t, int16_t h)
37  : time(t), height(h) {}
38 };
39 
40 // Zero suppression
41 struct zs_region {
42  size_t start = 0; // Data start of zs peak data
43  size_t len = 0; // Data length of zs peak data
44  zs_region(size_t s, size_t l)
45  : start(s), len(l) {}
46 };
47 
48 // Zero suppression
49 struct zs_data {
50  size_t adc_count = 0; // Total zs data found in this EWT
51  std::vector<zs_region> zs_regions; // All zs data regions found in this EWT
52  bool prescale = false; // Prescale this zs data?
53 };
54 
55 // Raw data
56 struct raw_info {
57  size_t start = 0; // Buffer index of start of event's ADC data
58  size_t len = 0; // Length of event's ADC data in the buffer
59  bool prescale = false; // Prescale this raw data?
60 };
61 
62 // EWT information
63 struct EWT_info {
64  uint64_t EWT = 0; // The EWT number
65  sw_event_header hdr = {}; // The EWTS new header data
66  raw_info raw; // The raw data information of this EWT
67  zs_data zs; // All zs data found in this EWT
68  std::vector<pulse_height> ph; // All peak heights found in this EW
69  bool bad_data = false; // Is this EWT's data bad (e.g. dropped packets)?
70 };
71 
72 // Define vector type
73 using EWTinfo = std::vector<EWT_info>;
74 
75 // Data struct buffer
76 struct DataStruct {
77 
78  // The fixed buffer number
79  const int buffer_num;
80 
81  // Do not use flag
82  bool do_not_use = false;
83 
84  // Data vectors
85  alignas(64) std::vector<int16_t> raw; // Raw data
86  std::vector<int16_t> zs; // Zero-suppressed data
87  std::vector<double> ph; // Pulse height buffer
88 
89  // Data lengths
90  size_t orig_len = 0, raw_len = 0, zs_len = 0, noise_len = 0, ph_len = 0;
91 
92  // Packet info
93  size_t packet_count = 0;
94  size_t dropped_packet_count = 0;
95  std::vector<std::pair<uint32_t,uint32_t>> dropped_packets;
96  bool has_idle_timeout;
97 
98  // EWT info
99  size_t EWT_count = 0;
100  size_t lost_EWT_count = 0;
101  std::vector<std::pair<uint64_t,uint64_t>> lost_EWTs;
102  std::vector<std::pair<uint64_t,uint64_t>> incomplete_EWTs;
103  bool has_null_hb;
104 
105  // The EWT data
106  EWTinfo EWTs;
107 
108  // Zero suppression
109  size_t zs_overflow_num = 0;
110  std::vector<uint64_t> peak_index;
111  std::vector<zs_region> zs_data;
112  std::atomic<bool> peak_finding_finished{false};
113 
114  // Baseline calculation
115  std::vector<uint64_t> hist_counts_window; // Sliding window histogram
116  std::vector<uint64_t> hist_counts_all; // All data histogram
117  uint64_t total_window = 0; // Total Window histogram counts
118  uint64_t total_all = 0; // Total all data histrogram counts
119  baseline_fit baseline_all; // All data baseline fit results
120  baseline_fit baseline_window; // Sliding window baseline fit results
121 
122  // The baseline values averaged since the start of the run
123  double baseline_mean_avg = 0;
124  double baseline_sigma_avg = 0;
125  // The current baseline values of the data in this buffer only
126  double baseline_mean_current = 0;
127  double baseline_sigma_current = 0;
128  // Noise data for DQM
129  std::vector<int16_t> noise_data;
130  std::vector<int16_t> noise_data_fft;
131 
132  // MWD output
133  size_t peak_count = 0;
134 
135  // PH Candidates
136  struct PulseCandidate {
137 
138  uint32_t ewtIndex = 0;
139  uint64_t ewtStart = 0;
140 
141  int pulseStart;
142  int64_t pulseStartGlobal;
143  int searchEnd;
144 
145  float adaptiveThreshold;
146  float baselineMean;
147  float baselineStd;
148 
149  bool stitchedCandidate = false;
150  };
151 
152  std::vector<PulseCandidate> pulseCandidates;
153 
154  // CPU performace/efficiency metrics
155  std::vector<std::pair<const std::string, double>> cpu_performance;
156 
157  // Prescale
158  std::vector<bool> raw_ps_bool; // Which events are being kept (1=keep)
159 
160  // Constructor initializes the buffer with a fixed size
161  DataStruct(const std::shared_ptr<STMdata>& stm,
162  int buffer_num_,
163  std::vector<std::string> op_names)
164  : buffer_num(buffer_num_),
165  raw(stm->buffer_config.raw_len),
166  zs(stm->buffer_config.zs_len),
167  ph(stm->buffer_config.ph_len),
168  EWTs(stm->buffer_config.max_event_num),
169  hist_counts_window(stm->baseline_config.hist_bin_num),
170  hist_counts_all(stm->baseline_config.hist_bin_num),
171  noise_data(),
172  pulseCandidates(),
173  cpu_performance([&]{
174  std::vector<std::pair<const std::string,double>> v;
175  v.reserve(op_names.size());
176  for (const auto& name : op_names) {
177  v.emplace_back(name, 0.0);
178  }
179  return v;
180  }())
181  {
182  noise_data.reserve(stm->buffer_config.baseline_len);
183  pulseCandidates.reserve(stm->buffer_config.ph_len/2);
184  reset(); // Ensure clean state on creation
185  }
186 
187  // Reinitalise the data struct
188  void reset() {
189  do_not_use = false;
190  // Reset vector contents
191  std::fill(raw.begin(), raw.end(), 0);
192  std::fill(zs.begin(), zs.end(), 0);
193  std::fill(ph.begin(), ph.end(), 0);
194  orig_len = raw_len = zs_len = ph_len = 0;
195  packet_count = 0;
196  dropped_packet_count = 0;
197  dropped_packets.resize(0);
198  has_idle_timeout = false;
199  EWT_count = 0;
200  lost_EWT_count = 0;
201  lost_EWTs.resize(0);
202  incomplete_EWTs.resize(0);
203  has_null_hb = false;
204  for (auto& e : EWTs) {
205  e.EWT = 0;
206  e.raw = raw_info{}; // if raw_info is trivially copyable
207  e.zs.adc_count = 0;
208  e.zs.zs_regions.clear();
209  e.zs.prescale = false;
210  e.ph.clear();
211  e.bad_data = false;
212  }
213  zs_overflow_num = 0;
214  peak_index.resize(0);
215  zs_data.clear();
216  std::fill(hist_counts_window.begin(), hist_counts_window.end(), 0);
217  std::fill(hist_counts_all.begin(), hist_counts_all.end(), 0);
218  baseline_mean_avg = 0;
219  baseline_sigma_avg = 0;
220  baseline_mean_current = 0;
221  baseline_sigma_current = 0;
222  baseline_window.reset();
223  baseline_all.reset();
224  noise_data.clear();
225  pulseCandidates.clear();
226  std::fill(raw_ps_bool.begin(), raw_ps_bool.end(), 0);
227  peak_count = 0;
228  // peaks.resize(0);
229  for (auto& entry : cpu_performance) entry.second = 0.0;
230  }
231 
232  // Destructor
233  ~DataStruct() = default;
234 
235 };
236 
237 #endif // DATA_STRUCT_HH_