DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
TPGenerator.hpp
Go to the documentation of this file.
1
9#ifndef TPGLIBS_TPGENERATOR_HPP_
10#define TPGLIBS_TPGENERATOR_HPP_
11
13
15
16#include <utility>
17
18namespace tpglibs {
19
28 static const uint8_t m_num_channels_per_pipeline = 16; // AVX2 with int16 data samples allows us to process 16 channels.
29 uint8_t m_num_pipelines = 0; // Gets set inside configure.
30 std::vector<AVXPipeline> m_tpg_pipelines;
32 std::vector<uint16_t> m_sot_minima{1,1,1}; // Defaults to 1 for all planes.
33
34 public:
42 void configure(const std::vector<std::pair<std::string, nlohmann::json>>& configs,
43 const std::vector<std::pair<dunedaq::trgdataformats::channel_t, int16_t>> channel_plane_numbers,
44 const int sample_tick_difference);
45
51 void set_sot_minima(const std::vector<uint16_t>& sot_minima);
52
61 template <typename T>
62 std::vector<dunedaq::trgdataformats::TriggerPrimitive> operator()(const T* frame) {
63 // Max number of TPs for a channel: number of time samples / 2.
64 std::vector<dunedaq::trgdataformats::TriggerPrimitive> tp_aggr;
65 tp_aggr.reserve(T::s_num_channels * T::s_time_samples_per_frame / 2);
66
67 const typename T::word_t (*words_ptr)[T::s_bits_per_adc] = frame->adc_words;
68 const uint64_t timestamp = frame->get_timestamp();
69
70 const int register_alignment = T::s_bits_per_adc * m_num_channels_per_pipeline;
71 // Loop in time.
72 for (int t = 0; t < T::s_time_samples_per_frame; t++) {
73 const typename T::word_t *time_sample = *(words_ptr + t);
74 char* cursor = (char*) time_sample; // Need to walk in terms of bytes/bits.
75
76 // Loop in pipelines.
77 for (int p = 0; p < m_num_pipelines; p++) {
78 if (p == m_num_pipelines - 1)
79 cursor -= 4; // Take a step of 32 bit backwards for the last sub-frame.
80
81 __m256i regi = _mm256_lddqu_si256((__m256i*)cursor);
82
83 if (p == m_num_pipelines - 1) // Permute the row order to use the same operation.
84 regi = _mm256_permutevar8x32_epi32(regi, _mm256_setr_epi32(1, 2, 3, 4, 5, 6, 7, 0));
85
86 __m256i expanded_subframe = expand_frame(regi);
87 std::vector<dunedaq::trgdataformats::TriggerPrimitive> tps = m_tpg_pipelines[p].process(expanded_subframe);
88
89 for (auto tp : tps) {
90 tp.time_start = (t - tp.samples_over_threshold) * m_sample_tick_difference + timestamp;
91 tp_aggr.push_back(tp);
92 }
93 cursor += register_alignment / 8; // Numerator is in bits. Need bytes.
94 }
95 }
96
97 return tp_aggr;
98 }
99
100 private:
101 __m256i expand_frame(const __m256i& regi);
102 __m256i old_expand_frame(const __m256i& regi);
103};
104
105} // namespace tpglibs
106
107#endif // TPGLIBS_TPGENERATOR_HPP_
TPG driving class.
std::vector< dunedaq::trgdataformats::TriggerPrimitive > operator()(const T *frame)
Driving function for the TPG.
std::vector< uint16_t > m_sot_minima
void set_sot_minima(const std::vector< uint16_t > &sot_minima)
Set the minimum samples over threshold for a TP according to plane.
void configure(const std::vector< std::pair< std::string, nlohmann::json > > &configs, const std::vector< std::pair< dunedaq::trgdataformats::channel_t, int16_t > > channel_plane_numbers, const int sample_tick_difference)
Setup and configure the AVX pipelines.
__m256i expand_frame(const __m256i &regi)
std::vector< AVXPipeline > m_tpg_pipelines
__m256i old_expand_frame(const __m256i &regi)
Expansion from 14-bit signals to 16-bit.
static const uint8_t m_num_channels_per_pipeline