8 #include "Mu2e-STMDAQ/processing/dqm_manager.hh"
10 #include "Mu2e-STMDAQ/dqm/dqm_structs.hh"
12 #include "Mu2e-STMDAQ/processing/operation_manager.hh"
14 #include "Mu2e-STMDAQ/processing/udp.hh"
17 DQM::DQM(
const Config& cfg_,
18 const std::shared_ptr<AsyncLogger>& logger_,
19 const std::shared_ptr<STMdata>& stm_,
20 const std::shared_ptr<SignalHandler>& signal_,
27 , baseline_mean_prev(stm->baseline_config.prev_mean)
28 , baseline_sigma_prev(stm->baseline_config.prev_sigma)
29 , baseline_nbins(stm->baseline_config.hist_bin_num)
30 , noise_len(stm->buffer_config.baseline_len)
31 , raw_len(stm->dqm_config.raw_len)
32 , peak_nbins(stm->dqm_config.peak_nbins)
33 , min_ph(stm->dqm_config.min_ph)
34 , inv_wid(stm->dqm_config.inv_bin_wid)
35 , peak_hist_window(peak_nbins, 0)
36 , peak_hist_all(peak_nbins, 0)
37 , window_size_buffers(stm->baseline_config.hist_window_buffers)
38 , per_buffer_hists(window_size_buffers, std::vector<uint64_t>(peak_nbins, 0))
39 , num_dropped_packets(0)
43 size_t baseline_bytes =
45 ((baseline_nbins - 1) *
sizeof(uint64_t)) +
46 (noise_len *
sizeof(int16_t)) + 7 +
50 ((raw_len - 1) *
sizeof(int16_t)) +
55 (((2 * peak_nbins) - 1) *
60 registerBlock<dqm_data_raw>(DQMPageType::RAW,
"/dqm_raw_data", raw_bytes);
61 registerBlock<dqm_data_baseline>(
62 DQMPageType::BASELINE,
"/dqm_adc_baseline", baseline_bytes);
63 registerBlock<dqm_data_peak>(DQMPageType::PEAKS,
"/dqm_peak_data", peak_bytes);
66 register_operation(
"update_dqm", [
this](
auto& b) { update_dqm(b); });
72 this->op_num = op_man->getUseOps().size() - 1;
80 registerBlock<dqm_data_daq>(DQMPageType::SPEEDS,
"/dqm_daq_data", daq_bytes);
83 auto t0 = std::chrono::steady_clock::now();
84 auto prev_baseline = t0;
90 constexpr
auto baseline_period = std::chrono::milliseconds{200};
91 constexpr
auto raw_period = std::chrono::milliseconds{200};
92 constexpr
auto peak_period = std::chrono::milliseconds{200};
93 constexpr
auto cpu_period = std::chrono::milliseconds{1000};
94 constexpr
auto alarm_period = std::chrono::milliseconds{200};
97 void DQM::update_dqm(std::shared_ptr<DataStruct>& buffer)
101 histogram_peaks(buffer);
104 auto now = std::chrono::steady_clock::now();
107 if(now - prev_baseline >= baseline_period)
110 update_dqm_baseline(buffer);
116 if(now - prev_raw >= raw_period)
119 update_dqm_raw(buffer);
125 if(now - prev_peak >= peak_period)
128 update_dqm_peak(buffer);
134 if(now - prev_cpu >= cpu_period)
137 update_cpu_performance(buffer);
143 void DQM::alarm_info(std::shared_ptr<DataStruct>& buffer)
146 if(buffer->dropped_packet_count > 0)
148 num_dropped_packets += buffer->dropped_packet_count;
153 void DQM::histogram_peaks(std::shared_ptr<DataStruct>& buffer)
157 for(
int b = 0; b < peak_nbins; b++)
159 peak_hist_window[b] -= per_buffer_hists[window_index][b];
160 total_window -= per_buffer_hists[window_index][b];
161 per_buffer_hists[window_index][b] = 0;
165 for(
const auto& ewt : buffer->EWTs)
167 for(
const auto& pulse : ewt.ph)
170 int16_t height = pulse.height;
172 if(height < min_ph || height > 0)
176 int bin = int((height - min_ph) * inv_wid);
179 ++per_buffer_hists[window_index][bin];
180 ++peak_hist_window[bin];
181 ++peak_hist_all[bin];
187 if(window_index == window_size_buffers)
192 void DQM::update_dqm_baseline(std::shared_ptr<DataStruct>& buffer)
195 auto* baseline = get<dqm_data_baseline>(DQMPageType::BASELINE);
198 baseline->gen_start.fetch_add(1, std::memory_order_release);
201 baseline->timestamp_ns = get_current_time_ns();
202 baseline->baseline_mean_prev = baseline_mean_prev;
203 baseline->baseline_sigma_prev = baseline_sigma_prev;
204 baseline->baseline_mean_avg = buffer->baseline_mean_avg;
205 baseline->baseline_sigma_avg = buffer->baseline_sigma_avg;
206 baseline->baseline_mean_current = buffer->baseline_mean_current;
207 baseline->baseline_sigma_current = buffer->baseline_sigma_current;
208 baseline->baseline_fit_mean_all = buffer->baseline_all.mu0;
209 baseline->baseline_fit_sigma_all = buffer->baseline_all.sigma0;
210 baseline->baseline_fit_mean_wind = buffer->baseline_window.mu0;
211 baseline->baseline_fit_sigma_wind = buffer->baseline_window.sigma0;
212 baseline->baseline_bins = baseline_nbins;
213 baseline->noise_len = noise_len;
216 uint64_t* hist_dest =
reinterpret_cast<uint64_t*
>(baseline->baseline_data);
218 hist_dest, buffer->hist_counts_all.data(), baseline_nbins *
sizeof(uint64_t));
221 size_t copy_len = std::min(buffer->noise_data.size(),
static_cast<size_t>(noise_len));
222 int16_t* noise_dest =
reinterpret_cast<int16_t*
>(baseline->baseline_data +
223 (baseline_nbins *
sizeof(uint64_t)));
224 std::memcpy(noise_dest, buffer->noise_data.data(), copy_len *
sizeof(int16_t));
226 if(copy_len < noise_len)
227 std::memset(noise_dest + copy_len, 0, (noise_len - copy_len) *
sizeof(int16_t));
230 uintptr_t noise_end_addr =
231 reinterpret_cast<uintptr_t
>(noise_dest) + (noise_len *
sizeof(int16_t));
232 uintptr_t aligned_gen_end_addr = (noise_end_addr + 7) & ~7;
233 auto* gen_end_ptr =
reinterpret_cast<std::atomic<uint64_t>*
>(aligned_gen_end_addr);
236 gen_end_ptr->store(baseline->gen_start.load(std::memory_order_acquire),
237 std::memory_order_release);
241 void DQM::update_dqm_raw(std::shared_ptr<DataStruct>& buffer)
244 auto* raw = get<dqm_data_raw>(DQMPageType::RAW);
247 raw->gen_start.fetch_add(1, std::memory_order_release);
250 raw->timestamp_ns = get_current_time_ns();
252 raw->raw_len = raw_len;
255 int16_t* raw_dest =
reinterpret_cast<int16_t*
>(raw->raw_data);
256 size_t copy_len = std::min(buffer->raw_len,
static_cast<size_t>(raw_len));
257 std::memcpy(raw_dest, buffer->raw.data(), copy_len *
sizeof(int16_t));
259 if(copy_len < raw_len)
260 std::memset(raw_dest + copy_len, 0, (raw_len - copy_len) *
sizeof(int16_t));
263 uintptr_t raw_end_addr =
264 reinterpret_cast<uintptr_t
>(raw_dest) + (raw_len *
sizeof(int16_t));
265 uintptr_t aligned_gen_end_addr = (raw_end_addr + 7) & ~7;
266 auto* gen_end_ptr =
reinterpret_cast<std::atomic<uint64_t>*
>(aligned_gen_end_addr);
269 gen_end_ptr->store(raw->gen_start.load(std::memory_order_acquire),
270 std::memory_order_release);
274 void DQM::update_dqm_peak(std::shared_ptr<DataStruct>& buffer)
277 auto*
peaks = get<dqm_data_peak>(DQMPageType::PEAKS);
280 peaks->gen_start.fetch_add(1, std::memory_order_release);
283 peaks->timestamp_ns = get_current_time_ns();
285 peaks->peak_nbins = peak_nbins;
288 std::memcpy(
peaks->peak_data, peak_hist_all.data(), peak_nbins *
sizeof(uint64_t));
290 std::memcpy(
peaks->peak_data + peak_nbins,
291 peak_hist_window.data(),
292 peak_nbins *
sizeof(uint64_t));
296 reinterpret_cast<std::atomic<uint64_t>*
>(
peaks->peak_data + 2 * peak_nbins);
299 gen_end_ptr->store(
peaks->gen_start.load(std::memory_order_acquire),
300 std::memory_order_release);
308 void DQM::update_cpu_performance(std::shared_ptr<DataStruct>& buffer)
310 auto daq_perf = get<dqm_data_daq>(DQMPageType::SPEEDS);
313 daq_perf->gen_start.fetch_add(1, std::memory_order_release);
316 daq_perf->timestamp_ns = get_current_time_ns();
319 daq_perf->num_dropped_packets = num_dropped_packets;
323 daq_perf->adc_temp = temp;
326 daq_perf->num_ops = op_num;
329 std::ostringstream oss;
330 oss <<
"Operation speed (Gbit/s): ";
332 bool first_entry =
true;
333 for(
size_t i = 0; i < buffer->cpu_performance.size(); ++i)
335 const auto& name = buffer->cpu_performance[i].first;
336 double perf = buffer->cpu_performance[i].second;
339 if(name.find(
"DQM") != std::string::npos)
345 oss << name <<
"=" << std::fixed << std::setprecision(2) << perf;
349 std::memset(daq_perf->ops_data[i].name, 0, 32);
350 std::strncpy(daq_perf->ops_data[i].name, name.c_str(), 31);
353 daq_perf->ops_data[i].speed = perf;
356 logger->log(oss.str(), 1);
358 uintptr_t data_end_addr =
359 reinterpret_cast<uintptr_t
>(daq_perf->ops_data) + (op_num *
sizeof(
op_entry));
360 uintptr_t aligned_gen_end_addr = (data_end_addr + 7) & ~7;
361 auto* gen_end_ptr =
reinterpret_cast<std::atomic<uint64_t>*
>(aligned_gen_end_addr);
363 gen_end_ptr->store(daq_perf->gen_start.load(std::memory_order_acquire),
364 std::memory_order_release);
367 uint64_t DQM::get_current_time_ns()
369 return std::chrono::duration_cast<std::chrono::nanoseconds>(
370 std::chrono::system_clock::now().time_since_epoch())