Line data Source code
1 : /**
2 : * @file TCMakerChannelAdjacencyAlgorithm.cpp
3 : *
4 : * This is part of the DUNE DAQ Application Framework, copyright 2021.
5 : * Licensing/copyright details are in the COPYING file that you should have
6 : * received with this code.
7 : */
8 :
9 : #include "triggeralgs/ChannelAdjacency/TCMakerChannelAdjacencyAlgorithm.hpp"
10 : #include "triggeralgs/Logging.hpp"
11 :
12 : #include "TRACE/trace.h"
13 : #define TRACE_NAME "TCMakerChannelAdjacencyAlgorithm"
14 :
15 : #include <math.h>
16 : #include <vector>
17 :
18 : using namespace triggeralgs;
19 :
20 : using Logging::TLVL_DEBUG_ALL;
21 : using Logging::TLVL_DEBUG_HIGH;
22 : using Logging::TLVL_DEBUG_MEDIUM;
23 : using Logging::TLVL_VERY_IMPORTANT;
24 :
25 : void
26 0 : TCMakerChannelAdjacencyAlgorithm::process(const TriggerActivity& activity,
27 : std::vector<TriggerCandidate>& output_tc)
28 : {
29 :
30 : // The first time process() is called, reset window object.
31 0 : if (m_current_window.is_empty()) {
32 0 : m_current_window.reset(activity);
33 0 : m_activity_count++;
34 : }
35 :
36 : // If the difference between the current TA's start time and the start of the window
37 : // is less than the specified window size, add the TA to the window.
38 0 : else if ((activity.time_start - m_current_window.time_start) < m_window_length) {
39 0 : TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TCM:CA] Window not yet complete, adding the activity to the window.";
40 0 : m_current_window.add(activity);
41 : }
42 : // If it is not, move the window along.
43 : else {
44 0 : TLOG_DEBUG(TLVL_DEBUG_ALL)
45 0 : << "[TCM:CA] TAWindow is at required length but specified threshold not met, shifting window along.";
46 0 : m_current_window.move(activity, m_window_length);
47 : }
48 :
49 : // If the addition of the current TA to the window would make it longer
50 : // than the specified window length, don't add it but check whether the sum of all adc in
51 : // the existing window is above the specified threshold. If it is, and we are triggering on ADC,
52 : // make a TA and start a fresh window with the current TP.
53 0 : if (m_current_window.adc_integral > m_adc_threshold && m_trigger_on_adc) {
54 0 : TLOG_DEBUG(TLVL_DEBUG_MEDIUM) << "[TCM:CA] m_current_window.adc_integral " << m_current_window.adc_integral
55 0 : << " - m_adc_threshold " << m_adc_threshold;
56 0 : TriggerCandidate tc = construct_tc();
57 0 : TLOG_DEBUG(TLVL_DEBUG_MEDIUM) << "[TCM:CA] tc.time_start=" << tc.time_start << " tc.time_end=" << tc.time_end
58 0 : << " len(tc.inputs) " << tc.inputs.size();
59 :
60 0 : for (const auto& ta : tc.inputs) {
61 0 : TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TCM:CA] [TA] ta.time_start=" << ta.time_start << " ta.time_end=" << ta.time_end
62 0 : << " ta.adc_integral=" << ta.adc_integral;
63 : }
64 :
65 0 : output_tc.push_back(tc);
66 0 : m_current_window.clear();
67 0 : }
68 :
69 : // If the addition of the current TA to the window would make it longer
70 : // than the specified window length, don't add it but check whether the number of hit channels in
71 : // the existing window is above the specified threshold. If it is, and we are triggering on channels,
72 : // make a TC and start a fresh window with the current TA.
73 0 : else if (m_current_window.n_channels_hit() > m_n_channels_threshold && m_trigger_on_n_channels) {
74 0 : output_tc.push_back(construct_tc());
75 0 : m_current_window.clear();
76 : }
77 :
78 0 : m_activity_count++;
79 0 : return;
80 : }
81 :
82 : void
83 0 : TCMakerChannelAdjacencyAlgorithm::configure(const nlohmann::json& config)
84 : {
85 0 : TriggerCandidateMaker::configure(config);
86 :
87 0 : if (config.is_object()) {
88 0 : if (config.contains("trigger_on_adc"))
89 0 : m_trigger_on_adc = config["trigger_on_adc"];
90 0 : if (config.contains("trigger_on_n_channels"))
91 0 : m_trigger_on_n_channels = config["trigger_on_n_channels"];
92 0 : if (config.contains("adc_threshold"))
93 0 : m_adc_threshold = config["adc_threshold"];
94 0 : if (config.contains("n_channels_threshold"))
95 0 : m_n_channels_threshold = config["n_channels_threshold"];
96 0 : if (config.contains("window_length"))
97 0 : m_window_length = config["window_length"];
98 : }
99 :
100 : // Both trigger flags were false. This will never trigger.
101 0 : if (!m_trigger_on_adc && !m_trigger_on_n_channels) {
102 0 : TLOG_DEBUG(TLVL_VERY_IMPORTANT) << "[TCM:CA] Not triggering! All trigger flags are false!";
103 0 : throw BadConfiguration(ERS_HERE, TRACE_NAME);
104 : }
105 :
106 0 : return;
107 : }
108 :
109 : TriggerCandidate
110 0 : TCMakerChannelAdjacencyAlgorithm::construct_tc() const
111 : {
112 0 : TriggerActivity latest_ta_in_window = m_current_window.inputs.back();
113 :
114 0 : TriggerCandidate tc;
115 0 : tc.time_start = m_current_window.time_start;
116 0 : tc.time_end = latest_ta_in_window.inputs.back().time_start;
117 0 : tc.time_candidate = m_current_window.time_start;
118 0 : tc.detid = latest_ta_in_window.detid;
119 0 : tc.type = m_tc_type_out;
120 0 : tc.algorithm = TriggerCandidate::Algorithm::kChannelAdjacency;
121 :
122 : // Take the list of triggeralgs::TriggerActivity in the current
123 : // window and convert them (implicitly) to detdataformats'
124 : // TriggerActivityData, which is the base class of TriggerActivity
125 0 : for (auto& ta : m_current_window.inputs) {
126 0 : tc.inputs.push_back(ta);
127 0 : if (ta.time_end > tc.time_end) {
128 0 : tc.time_end = ta.time_end;
129 : }
130 : }
131 :
132 0 : return tc;
133 0 : }
134 :
135 : // Functions below this line are for debugging purposes.
136 : void
137 0 : TCMakerChannelAdjacencyAlgorithm::add_window_to_record(TAWindow window)
138 : {
139 0 : m_window_record.push_back(window);
140 0 : return;
141 : }
142 :
143 12 : REGISTER_TRIGGER_CANDIDATE_MAKER(TRACE_NAME, TCMakerChannelAdjacencyAlgorithm)
|