DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
TAMakerChannelAdjacencyAlgorithm.cpp
Go to the documentation of this file.
1
10#include "TRACE/trace.h"
12#define TRACE_NAME "TAMakerChannelAdjacencyAlgorithm"
13#include <math.h>
14#include <vector>
15
16using namespace triggeralgs;
17
18using Logging::TLVL_DEBUG_LOW;
19
20void
22 std::vector<TriggerActivity>& output_ta)
23{
24
25 // Add useful info about recived TPs here for FW and SW TPG guys.
26 if (m_print_tp_info) {
27 TLOG_DEBUG(TLVL_DEBUG_LOW) << " ########## m_current_window is reset ##########\n"
28 << " TP Start Time: " << input_tp.time_start << ", TP ADC Sum: " << input_tp.adc_integral
29 << ", TP SOT: " << input_tp.samples_over_threshold << ", TP ADC Peak: " << input_tp.adc_peak
30 << ", TP Offline Channel ID: " << input_tp.channel << "\n";
31 }
32
33 // 0) FIRST TP =====================================================================
34 // The first time process() is called, reset the window object.
36 m_current_window.reset(input_tp);
37 return;
38 }
39
40 // If the difference between the current TP's start time and the start of the window
41 // is less than the specified window size, add the TP to the window.
42 bool adj_pass = 0; // sets to true when adjacency logic is satisfied
43 bool window_filled = 1; // sets to true when window is ready to test the adjacency logic
45 m_current_window.add(input_tp);
46 window_filled = 0;
47 TLOG_DEBUG(TLVL_DEBUG_LOW) << "m_current_window.time_start " << m_current_window.time_start << "\n";
48 }
49
50 else {
51 TPWindow win_adj_max;
52
53 bool ta_found = 1;
54 while (ta_found) {
55
56 // make m_current_window_tmp a copy of m_current_window and clear m_current_window
57 TPWindow m_current_window_tmp = m_current_window;
59
60 // make m_current_window a new window of non-overlapping tps (of m_current_window_tmp and win_adj_max)
61 for (auto tp : m_current_window_tmp.inputs) {
62 bool new_tp = 1;
63 for (auto tp_sel : win_adj_max.inputs) {
64 if (tp.channel == tp_sel.channel) {
65 new_tp = 0;
66 break;
67 }
68 }
69 if (new_tp)
71 }
72
73 // check adjacency -> win_adj_max now contains only those tps that make the track
74 win_adj_max = check_adjacency();
75 if (win_adj_max.inputs.size() > 0) {
76
77 adj_pass = 1;
78 ta_found = 1;
79 output_ta.push_back(construct_ta(win_adj_max));
80 } else
81 ta_found = 0;
82 }
83 if (adj_pass)
84 m_current_window.reset(input_tp);
85 }
86
87 // if adjacency logic is not true, slide the window along using the current TP.
88 if (window_filled && !adj_pass) {
90 }
91
92 return;
93}
94
95void
97{
99 if (config.is_object()) {
100 if (config.contains("window_length"))
101 m_window_length = config["window_length"];
102 if (config.contains("adjacency_tolerance"))
103 m_adj_tolerance = config["adjacency_tolerance"];
104 if (config.contains("adjacency_threshold"))
105 m_adjacency_threshold = config["adjacency_threshold"];
106 if (config.contains("print_tp_info"))
107 m_print_tp_info = config["print_tp_info"];
108 }
109}
110
113{
114
116
117 TriggerPrimitive last_tp = win_adj_max.inputs.back();
118
119 ta.time_start = last_tp.time_start;
120 ta.time_end = last_tp.time_start;
121 ta.time_peak = last_tp.samples_to_peak * 32 + last_tp.time_start; // FIXME: Replace STP to `time_peak` conversion.
122 ta.time_activity = ta.time_peak;
123 ta.channel_start = last_tp.channel;
124 ta.channel_end = last_tp.channel;
125 ta.channel_peak = last_tp.channel;
126 ta.adc_integral = win_adj_max.adc_integral;
127 ta.adc_peak = last_tp.adc_peak;
128 ta.detid = last_tp.detid;
131 ta.inputs = win_adj_max.inputs;
132
133 for (const auto& tp : ta.inputs) {
134 ta.time_start = std::min(ta.time_start, tp.time_start);
135 ta.time_end = std::max(ta.time_end, tp.time_start);
136 ta.channel_start = std::min(ta.channel_start, channel_t(tp.channel));
137 ta.channel_end = std::max(ta.channel_end, channel_t(tp.channel));
138 if (tp.adc_peak > ta.adc_peak) {
139 ta.time_peak = tp.samples_to_peak * 32 + tp.time_start; // FIXME: Replace STP to `time_peak` conversion.
140 ta.adc_peak = tp.adc_peak;
141 ta.channel_peak = tp.channel;
142 }
143 }
144
145 return ta;
146}
147
148// std::vector<TriggerPrimitive>
151{
152 // This function deals with tp window (m_current_window), select adjacent tps (with a channel gap from 0 to 5; sum of
153 // all gaps < m_adj_tolerance), checks if track length > m_adjacency_threshold: return the tp window (win_adj_max,
154 // which is subset of the input tp window)
155
156 unsigned int channel = 0; // Current channel ID
157 unsigned int next_channel = 0; // Next channel ID
158 unsigned int next = 0; // The next position in the hit channels vector
159 unsigned int tol_count = 0; // Tolerance count, should not pass adj_tolerance
160
161 // Generate a channelID ordered list of hit channels for this window; second element of pair is tps
162 std::vector<std::pair<int, TriggerPrimitive>> chanTPList;
163 for (auto tp : m_current_window.inputs) {
164 chanTPList.push_back(std::make_pair(channel_t(tp.channel), tp));
165 }
166 std::sort(chanTPList.begin(),
167 chanTPList.end(),
168 [](const std::pair<int, TriggerPrimitive>& a, const std::pair<int, TriggerPrimitive>& b) {
169 return (a.first < b.first);
170 });
171
172 // ADAJACENCY LOGIC ====================================================================
173 // =====================================================================================
174 // Adjcancency Tolerance = Number of times prepared to skip missed hits before resetting
175 // the adjacency count (win_adj). This accounts for things like dead channels / missed TPs.
176
177 // add first tp, and then if tps are on next channels (check code below to understand the definition)
178 TPWindow win_adj;
179 TPWindow win_adj_max; // if track length > m_adjacency_threshold, set win_adj_max = win_adj; return win_adj_max;
180
181 for (int i = 0; i < chanTPList.size(); ++i) {
182
183 win_adj_max.clear();
184
185 next = (i + 1) % chanTPList.size(); // Loops back when outside of channel list range
186 channel = chanTPList.at(i).first;
187 next_channel = chanTPList.at(next).first; // Next channel with a hit
188
189 // End of vector condition.
190 if (next == 0) {
191 next_channel = channel - 1;
192 }
193
194 // Skip same channel hits.
195 if (next_channel == channel)
196 continue;
197
198 // If win_adj size == zero, add current tp
199 if (win_adj.inputs.size() == 0)
200 win_adj.add(chanTPList[i].second);
201
202 // If next hit is on next channel, increment the adjacency count
203 if (next_channel - channel == 1) {
204 win_adj.add(chanTPList[next].second);
205 }
206
207 // Allow a max gap of 5 channels (e.g., 45 and 50; 46, 47, 48, 49 are missing); increment the adjacency count
208 // Sum of gaps should be < adj_tolerance (e.g., if toleance is 30, the max total gap can vary from 0 to 29+4 = 33)
209 else if (next_channel - channel > 0 && next_channel - channel <= 5 && tol_count < m_adj_tolerance) {
210 win_adj.add(chanTPList[next].second);
211 tol_count += next_channel - channel - 1;
212 }
213
214 // if track length > m_adjacency_threshold, set win_adj_max = win_adj;
215 else if (win_adj.inputs.size() > m_adjacency_threshold) {
216 win_adj_max = win_adj;
217 break;
218 }
219
220 // If track length < m_adjacency_threshold, reset variables for next iteration.
221 else {
222 tol_count = 0;
223 win_adj.clear();
224 }
225 }
226
227 return win_adj_max;
228}
229
230// =====================================================================================
231// Functions below this line are for debugging purposes.
232// =====================================================================================
233void
235{
236 m_window_record.push_back(window);
237 return;
238}
239
240// Register algo in TA Factory
#define REGISTER_TRIGGER_ACTIVITY_MAKER(tam_name, tam_class)
void process(const TriggerPrimitive &input_tp, std::vector< TriggerActivity > &output_ta)
TP processing function that creates & fills TAs.
void reset(TriggerPrimitive const &input_tp)
Definition TPWindow.cpp:79
void add(TriggerPrimitive const &input_tp)
Definition TPWindow.cpp:20
bool is_empty() const
Definition TPWindow.cpp:14
std::vector< TriggerPrimitive > inputs
Definition TPWindow.hpp:40
void move(TriggerPrimitive const &input_tp, timestamp_t const &window_length)
Definition TPWindow.cpp:45
timestamp_t time_start
Definition TPWindow.hpp:37
virtual void configure(const nlohmann::json &config)
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
dunedaq::trgdataformats::channel_t channel_t
Definition Types.hpp:20
#define TRACE_NAME
A single energy deposition on a TPC or PDS channel.
std::vector< TriggerPrimitive > inputs