Line data Source code
1 : /**
2 : * @file AVXFrugalPedestalSubtractProcessor.cpp
3 : *
4 : * @copyright This is part of the DUNE DAQ Software Suite, copyright 2020.
5 : * Licensing/copyright details are in the COPYING file that you should have
6 : * received with this code.
7 : */
8 :
9 : #include "tpglibs/AVXFrugalPedestalSubtractProcessor.hpp"
10 :
11 : namespace tpglibs {
12 :
13 10 : REGISTER_AVXPROCESSOR_CREATOR("AVXFrugalPedestalSubtractProcessor", AVXFrugalPedestalSubtractProcessor)
14 :
15 0 : void AVXFrugalPedestalSubtractProcessor::configure(const nlohmann::json& config, const int16_t* /* plane_numbers */) {
16 : #ifdef TPGLIBS_ENABLE_STATE_MONITORING
17 : m_internal_state_name_registry.register_internal_state("pedestal",
18 : std::shared_ptr<__m256i>(&m_pedestal, [](auto*){}));
19 : m_internal_state_name_registry.register_internal_state("accum",
20 : std::shared_ptr<__m256i>(&m_accum, [](auto*){}));
21 : configure_internal_state_collection(config);
22 : #endif
23 :
24 0 : m_accum_limit = config["accum_limit"];
25 0 : }
26 :
27 0 : __m256i AVXFrugalPedestalSubtractProcessor::process(const __m256i& signal) {
28 : #ifdef TPGLIBS_ENABLE_STATE_MONITORING
29 : m_samples++;
30 : if (m_collect_internal_state_flag && (m_samples % m_sample_period == 0)) {
31 : m_internal_state_buffer_manager.write_to_active_buffer();
32 : }
33 : #endif
34 :
35 : // Find the channels that are above or below the pedestal.
36 0 : __m256i is_gt = _mm256_cmpgt_epi16(signal, m_pedestal);
37 0 : __m256i is_lt = _mm256_cmpgt_epi16(m_pedestal, signal);
38 :
39 : // Update m_accum.
40 0 : __m256i to_add = _mm256_setzero_si256(); // Assumes equal to pedestal.
41 0 : to_add = _mm256_blendv_epi8(to_add, _mm256_set1_epi16(1), is_gt); // Set the above pedestal case.
42 0 : to_add = _mm256_blendv_epi8(to_add, _mm256_set1_epi16(-1), is_lt); // Set the below pedestal case.
43 :
44 0 : m_accum = _mm256_add_epi16(m_accum, to_add);
45 :
46 : // Check the accum limit condition.
47 0 : is_gt = _mm256_cmpgt_epi16(m_accum, _mm256_set1_epi16(m_accum_limit)); // m_accum > +limit.
48 0 : is_lt = _mm256_cmpgt_epi16(_mm256_set1_epi16(-1*m_accum_limit), m_accum); // m_accum < -limit = -limit > m_accum.
49 :
50 0 : to_add = _mm256_setzero_si256();
51 0 : to_add = _mm256_blendv_epi8(to_add, _mm256_set1_epi16(1), is_gt);
52 0 : to_add = _mm256_blendv_epi8(to_add, _mm256_set1_epi16(-1), is_lt);
53 :
54 : // Update pedestal.
55 0 : m_pedestal = _mm256_adds_epi16(m_pedestal, to_add);
56 :
57 : // Reset too high/low m_accum channels.
58 0 : __m256i need_reset = _mm256_or_si256(is_lt, is_gt);
59 0 : m_accum = _mm256_blendv_epi8(m_accum, _mm256_setzero_si256(), need_reset);
60 :
61 0 : return AVXProcessor::process(_mm256_sub_epi16(signal, m_pedestal));
62 : }
63 :
64 : } // namespace tpglibs
|