DUNE-DAQ
DUNE Trigger and Data Acquisition software
Toggle main menu visibility
Loading...
Searching...
No Matches
dunedaq
sourcecode
triggeralgs
src
TAMakerHorizontalMuonAlgorithm.cpp
Go to the documentation of this file.
1
8
9
#include "
triggeralgs/HorizontalMuon/TAMakerHorizontalMuonAlgorithm.hpp
"
10
#include "TRACE/trace.h"
11
#define TRACE_NAME "TAMakerHorizontalMuonAlgorithm"
12
#include <vector>
13
#include <math.h>
14
#include <vector>
15
16
using namespace
triggeralgs
;
17
18
using
Logging::TLVL_DEBUG_ALL
;
19
using
Logging::TLVL_DEBUG_MEDIUM
;
20
21
void
22
TAMakerHorizontalMuonAlgorithm::process
(
const
TriggerPrimitive
& input_tp,
23
std::vector<TriggerActivity>& output_ta)
24
{
25
26
uint16_t adjacency;
27
28
// Add useful info about recived TPs here for FW and SW TPG guys.
29
if
(
m_print_tp_info
) {
30
TLOG_DEBUG
(
TLVL_DEBUG_ALL
) <<
"[TAM:HM] TP Start Time: "
<< input_tp.
time_start
31
<<
", TP ADC Sum: "
<< input_tp.
adc_integral
32
<<
", TP SOT: "
<< input_tp.
samples_over_threshold
<<
", TP ADC Peak: "
<< input_tp.
adc_peak
33
<<
", TP Offline Channel ID: "
<< input_tp.
channel
;
34
TLOG_DEBUG
(
TLVL_DEBUG_ALL
) <<
"[TAM:HM] Adjacency of current window is: "
<<
check_adjacency
();
35
}
36
37
// 0) FIRST TP =====================================================================
38
// The first time process() is called, reset the window object.
39
if
(
m_current_window
.is_empty()) {
40
m_current_window
.reset(input_tp);
41
return
;
42
}
43
44
// If the difference between the current TP's start time and the start of the window
45
// is less than the specified window size, add the TP to the window.
46
if
((input_tp.
time_start
-
m_current_window
.time_start) <
m_window_length
) {
47
m_current_window
.add(input_tp);
48
}
49
50
// 1) ADC THRESHOLD EXCEEDED =======================================================
51
// If the addition of the current TP to the window would make it longer specified
52
// window length, don't add it but check whether the ADC integral if the existing
53
// window is above the configured threshold. If it is, and we are triggering on ADC,
54
// make a TA and start a fresh window with the current TP.
55
else
if
(
m_current_window
.adc_integral >
m_adc_threshold
&&
m_trigger_on_adc
) {
56
57
auto
ta =
construct_ta
();
58
59
TLOG_DEBUG
(
TLVL_DEBUG_MEDIUM
) <<
"[TA:HM]: Emitting ADC threshold trigger with "
<<
m_current_window
.adc_integral
60
<<
" window ADC integral. ta.time_start="
<< ta.time_start
61
<<
" ta.time_end="
<< ta.time_end;
62
63
output_ta.push_back(ta);
64
m_current_window
.reset(input_tp);
65
}
66
67
// 2) MULTIPLICITY - N UNQIUE CHANNELS EXCEEDED =====================================
68
// If the addition of the current TP to the window would make it longer than the
69
// specified window length, don't add it but check whether the number of hit channels
70
// in the existing window is above the specified threshold. If it is, and we are triggering
71
// on channel multiplicity, make a TA and start a fresh window with the current TP.
72
else
if
(
m_current_window
.n_channels_hit() >
m_n_channels_threshold
&&
m_trigger_on_n_channels
) {
73
74
TLOG_DEBUG
(
TLVL_DEBUG_MEDIUM
) <<
"[TAM:HM] Emitting multiplicity trigger with "
75
<<
m_current_window
.n_channels_hit() <<
" unique channels hit."
;
76
77
output_ta.push_back(
construct_ta
());
78
m_current_window
.reset(input_tp);
79
}
80
81
// 3) ADJACENCY THRESHOLD EXCEEDED ==================================================
82
// If the addition of the current TP to the window would make it longer than the
83
// specified window length, don't add it but check whether the adjacency of the
84
// current window exceeds the configured threshold. If it does, and we are triggering
85
// on adjacency, then create a TA and reset the window with the new/current TP.
86
else
if
((adjacency =
check_adjacency
()) >
m_adjacency_threshold
&&
m_trigger_on_adjacency
) {
87
88
//for (auto tp : m_current_window.inputs){ dump_tp(tp); }
89
90
// Check for a new maximum, display the largest seen adjacency in the log.
91
// uint16_t adjacency = check_adjacency();
92
if
(adjacency >
m_max_adjacency
) {
93
m_max_adjacency
= adjacency;
94
}
95
TLOG_DEBUG
(
TLVL_DEBUG_MEDIUM
) <<
"[TAM:HM] Emitting track and multiplicity TA with adjacency "
96
<<
check_adjacency
() <<
" and multiplicity "
<<
m_current_window
.n_channels_hit()
97
<<
". The ADC integral of this TA is "
<<
m_current_window
.adc_integral
98
<<
" and the largest longest track seen so far is "
<<
m_max_adjacency
;
99
100
output_ta.push_back(
construct_ta
());
101
m_current_window
.reset(input_tp);
102
}
103
104
// Temporary triggering logic for Adam's large SOT TPs. Trigger on very large SOT TPs.
105
else
if
(
m_trigger_on_sot
&& input_tp.
samples_over_threshold
>
m_sot_threshold
) {
106
107
// If the incoming TP has a large time over threshold, we might have a cluster of
108
// interesting physics activity surrounding it. Trigger on that.
109
TLOG_DEBUG
(
TLVL_DEBUG_MEDIUM
) <<
"[TAM:HM] Emitting a TA due to a TP with a very large samples over threshold: "
110
<< input_tp.
samples_over_threshold
<<
" ticks and offline channel: "
<< input_tp.
channel
111
<<
", where the ADC integral of that TP is "
<< input_tp.
adc_integral
;
112
output_ta.push_back(
construct_ta
());
113
m_current_window
.reset(input_tp);
114
}
115
116
// 4) Otherwise, slide the window along using the current TP.
117
else
{
118
m_current_window
.move(input_tp,
m_window_length
);
119
}
120
121
return
;
122
}
123
124
void
125
TAMakerHorizontalMuonAlgorithm::configure
(
const
nlohmann::json& config)
126
{
127
TriggerActivityMaker::configure
(config);
128
129
if
(config.is_object()) {
130
if
(config.contains(
"trigger_on_adc"
))
131
m_trigger_on_adc
= config[
"trigger_on_adc"
];
132
if
(config.contains(
"trigger_on_n_channels"
))
133
m_trigger_on_n_channels
= config[
"trigger_on_n_channels"
];
134
if
(config.contains(
"adc_threshold"
))
135
m_adc_threshold
= config[
"adc_threshold"
];
136
if
(config.contains(
"n_channels_threshold"
))
137
m_n_channels_threshold
= config[
"n_channels_threshold"
];
138
if
(config.contains(
"window_length"
))
139
m_window_length
= config[
"window_length"
];
140
if
(config.contains(
"trigger_on_adjacency"
))
141
m_trigger_on_adjacency
= config[
"trigger_on_adjacency"
];
142
if
(config.contains(
"adjacency_tolerance"
))
143
m_adj_tolerance
= config[
"adjacency_tolerance"
];
144
if
(config.contains(
"adjacency_threshold"
))
145
m_adjacency_threshold
= config[
"adjacency_threshold"
];
146
if
(config.contains(
"print_tp_info"
))
147
m_print_tp_info
= config[
"print_tp_info"
];
148
if
(config.contains(
"trigger_on_sot"
))
149
m_trigger_on_sot
= config[
"trigger_on_sot"
];
150
if
(config.contains(
"sot_threshold"
))
151
m_sot_threshold
= config[
"sot_threshold"
];
152
}
153
154
}
155
156
TriggerActivity
157
TAMakerHorizontalMuonAlgorithm::construct_ta
()
const
158
{
159
160
TriggerActivity
ta;
161
162
TriggerPrimitive
last_tp =
m_current_window
.inputs.back();
163
164
ta.
time_start
= last_tp.
time_start
;
165
ta.
time_end
= last_tp.
time_start
+ last_tp.
samples_over_threshold
* 32;
// FIXME: Replace the hard-coded SOT to TOT scaling.
166
ta.
time_peak
= last_tp.
samples_to_peak
* 32 + last_tp.
time_start
;
// FIXME: Replace STP to `time_peak` conversion.
167
ta.
time_activity
= ta.
time_peak
;
168
ta.
channel_start
= last_tp.
channel
;
169
ta.
channel_end
= last_tp.
channel
;
170
ta.
channel_peak
= last_tp.
channel
;
171
ta.
adc_integral
=
m_current_window
.adc_integral;
172
ta.
adc_peak
= last_tp.
adc_integral
;
173
ta.
detid
= last_tp.
detid
;
174
ta.
type
=
TriggerActivity::Type::kTPC
;
175
ta.
algorithm
=
TriggerActivity::Algorithm::kHorizontalMuon
;
176
ta.
inputs
=
m_current_window
.inputs;
177
178
for
(
const
auto
& tp : ta.
inputs
) {
179
ta.
time_start
= std::min(ta.
time_start
, tp.time_start);
180
ta.
time_end
= std::max(ta.
time_end
, tp.time_start + tp.samples_over_threshold * 32);
// FIXME: Replace the hard-coded SOT to TOT scaling.
181
ta.
channel_start
= std::min(ta.
channel_start
,
channel_t
(tp.channel));
182
ta.
channel_end
= std::max(ta.
channel_end
,
channel_t
(tp.channel));
183
if
(tp.adc_peak > ta.
adc_peak
) {
184
ta.
time_peak
= tp.samples_to_peak * 32 + tp.time_start;
// FIXME: Replace STP to `time_peak` conversion.
185
ta.
adc_peak
= tp.adc_peak;
186
ta.
channel_peak
= tp.channel;
187
}
188
}
189
190
return
ta;
191
}
192
193
uint16_t
194
TAMakerHorizontalMuonAlgorithm::check_adjacency
()
const
195
{
196
// This function returns the adjacency value for the current window, where adjacency
197
// is defined as the maximum number of consecutive wires containing hits. It accepts
198
// a configurable tolerance paramter, which allows up to adj_tolerance missing hits
199
// on adjacent wires before restarting the adjacency count. The maximum gap is 4 which
200
// comes from tuning on December 2021 coldbox data, and June 2022 coldbox runs.
201
202
uint16_t adj = 1;
// Initialise adjacency, 1 for the first wire.
203
uint16_t max = 0;
// Maximum adjacency of window, which this function returns
204
unsigned
int
channel = 0;
// Current channel ID
205
unsigned
int
next_channel = 0;
// Next channel ID
206
unsigned
int
next = 0;
// The next position in the hit channels vector
207
unsigned
int
tol_count = 0;
// Tolerance count, should not pass adj_tolerance
208
209
// Generate a channelID ordered list of hit channels for this window
210
std::vector<int> chanList;
211
for
(
auto
tp :
m_current_window
.inputs) {
212
chanList.push_back(
channel_t
(tp.channel));
213
}
214
std::sort(chanList.begin(), chanList.end());
215
216
// ADAJACENCY LOGIC ====================================================================
217
// =====================================================================================
218
// Adjcancency Tolerance = Number of times prepared to skip missed hits before resetting
219
// the adjacency count. This accounts for things like dead channels / missed TPs. The
220
// maximum gap is 4 which comes from tuning on December 2021 coldbox data, and June 2022
221
// coldbox runs.
222
for
(
int
i = 0; i < chanList.size(); ++i) {
223
224
next = (i + 1) % chanList.size();
// Loops back when outside of channel list range
225
channel = chanList.at(i);
226
next_channel = chanList.at(next);
// Next channel with a hit
227
228
// End of vector condition.
229
if
(next_channel == 0) {
230
next_channel = channel - 1;
231
}
232
233
// Skip same channel hits.
234
if
(next_channel == channel) {
235
continue
;
236
}
237
238
// If next hit is on next channel, increment the adjacency count.
239
else
if
(next_channel == channel + 1) {
240
++adj;
241
}
242
243
// If next channel is not on the next hit, but the 'second next', increase adjacency
244
// but also tally up with the tolerance counter.
245
else
if
(((next_channel == channel + 2) || (next_channel == channel + 3) || (next_channel == channel + 4) ||
246
(next_channel == channel + 5)) &&
247
(tol_count <
m_adj_tolerance
)) {
248
++adj;
249
for
(
int
i = 0; i < next_channel - channel; ++i) {
250
++tol_count;
251
}
252
}
253
254
// If next hit isn't within reach, end the adjacency count and check for a new max.
255
// Reset variables for next iteration.
256
else
{
257
if
(adj > max) {
258
max = adj;
259
}
260
adj = 1;
261
tol_count = 0;
262
}
263
}
264
265
return
max;
266
}
267
268
// =====================================================================================
269
// Functions below this line are for debugging purposes.
270
// =====================================================================================
271
void
272
TAMakerHorizontalMuonAlgorithm::add_window_to_record
(
TPWindow
window)
273
{
274
m_window_record
.push_back(window);
275
return
;
276
}
277
278
// Function to dump the details of the TA window currently on record
279
void
280
TAMakerHorizontalMuonAlgorithm::dump_window_record
()
281
{
282
std::ofstream outfile;
283
outfile.open(
"window_record_tam.csv"
, std::ios_base::app);
284
285
for
(
auto
window :
m_window_record
) {
286
outfile << window.time_start <<
","
;
287
outfile << window.inputs.back().time_start <<
","
;
288
outfile << window.inputs.back().time_start - window.time_start <<
","
;
289
outfile << window.adc_integral <<
","
;
290
outfile << window.n_channels_hit() <<
","
;
// Number of unique channels with hits
291
outfile << window.inputs.size() <<
","
;
// Number of TPs in TPWindow
292
outfile << window.inputs.back().channel <<
","
;
// Last TP Channel ID
293
outfile << window.inputs.front().channel <<
","
;
// First TP Channel ID
294
outfile <<
check_adjacency
() <<
","
;
// New adjacency value for the window
295
outfile <<
check_sot
() << std::endl;
// Summed window SOT
296
}
297
298
outfile.close();
299
m_window_record
.clear();
300
301
return
;
302
}
303
304
// Function to add current TP details to a text file for testing and debugging.
305
void
306
TAMakerHorizontalMuonAlgorithm::dump_tp
(
TriggerPrimitive
const
& input_tp)
307
{
308
std::ofstream outfile;
309
outfile.open(
"coldbox_tps.txt"
, std::ios_base::app);
310
311
// Output relevant TP information to file
312
outfile << input_tp.
time_start
<<
" "
;
313
outfile << input_tp.
samples_over_threshold
<<
" "
;
// 50MHz ticks
314
outfile << input_tp.
samples_to_peak
<<
" "
;
315
outfile << input_tp.
channel
<<
" "
;
// Offline channel ID
316
outfile << input_tp.
adc_integral
<<
" "
;
317
outfile << input_tp.
adc_peak
<<
" "
;
318
outfile << input_tp.
detid
<<
" "
;
// Det ID - Identifies detector element
319
outfile.close();
320
321
return
;
322
}
323
324
int
325
TAMakerHorizontalMuonAlgorithm::check_sot
()
const
326
{
327
// Here, we just want to sum up all the sot values for each TP within window,
328
// and return this sot of the window.
329
int
window_sot = 0;
330
for
(
auto
tp :
m_current_window
.inputs) {
331
window_sot += tp.samples_over_threshold;
332
}
333
334
return
window_sot;
335
}
336
337
// Register algo in TA Factory
338
REGISTER_TRIGGER_ACTIVITY_MAKER
(
TRACE_NAME
,
TAMakerHorizontalMuonAlgorithm
)
TRACE_NAME
#define TRACE_NAME
Definition
TimestampEstimatorTimeSync.cpp:17
REGISTER_TRIGGER_ACTIVITY_MAKER
#define REGISTER_TRIGGER_ACTIVITY_MAKER(tam_name, tam_class)
Definition
TriggerActivityFactory.hpp:14
triggeralgs::TAMakerHorizontalMuonAlgorithm
Definition
TAMakerHorizontalMuonAlgorithm.hpp:19
triggeralgs::TAMakerHorizontalMuonAlgorithm::m_window_length
timestamp_t m_window_length
Definition
TAMakerHorizontalMuonAlgorithm.hpp:46
triggeralgs::TAMakerHorizontalMuonAlgorithm::check_adjacency
uint16_t check_adjacency() const
Definition
TAMakerHorizontalMuonAlgorithm.cpp:194
triggeralgs::TAMakerHorizontalMuonAlgorithm::dump_tp
void dump_tp(TriggerPrimitive const &input_tp)
Definition
TAMakerHorizontalMuonAlgorithm.cpp:306
triggeralgs::TAMakerHorizontalMuonAlgorithm::m_adc_threshold
uint32_t m_adc_threshold
Definition
TAMakerHorizontalMuonAlgorithm.hpp:40
triggeralgs::TAMakerHorizontalMuonAlgorithm::m_window_record
std::vector< TPWindow > m_window_record
Definition
TAMakerHorizontalMuonAlgorithm.hpp:52
triggeralgs::TAMakerHorizontalMuonAlgorithm::configure
void configure(const nlohmann::json &config)
Definition
TAMakerHorizontalMuonAlgorithm.cpp:125
triggeralgs::TAMakerHorizontalMuonAlgorithm::m_max_adjacency
int m_max_adjacency
Definition
TAMakerHorizontalMuonAlgorithm.hpp:39
triggeralgs::TAMakerHorizontalMuonAlgorithm::m_adjacency_threshold
uint16_t m_adjacency_threshold
Definition
TAMakerHorizontalMuonAlgorithm.hpp:38
triggeralgs::TAMakerHorizontalMuonAlgorithm::m_adj_tolerance
uint16_t m_adj_tolerance
Definition
TAMakerHorizontalMuonAlgorithm.hpp:42
triggeralgs::TAMakerHorizontalMuonAlgorithm::m_trigger_on_sot
bool m_trigger_on_sot
Definition
TAMakerHorizontalMuonAlgorithm.hpp:35
triggeralgs::TAMakerHorizontalMuonAlgorithm::m_trigger_on_adjacency
bool m_trigger_on_adjacency
Definition
TAMakerHorizontalMuonAlgorithm.hpp:34
triggeralgs::TAMakerHorizontalMuonAlgorithm::dump_window_record
void dump_window_record()
Definition
TAMakerHorizontalMuonAlgorithm.cpp:280
triggeralgs::TAMakerHorizontalMuonAlgorithm::m_n_channels_threshold
uint16_t m_n_channels_threshold
Definition
TAMakerHorizontalMuonAlgorithm.hpp:41
triggeralgs::TAMakerHorizontalMuonAlgorithm::process
void process(const TriggerPrimitive &input_tp, std::vector< TriggerActivity > &output_ta)
TP processing function that creates & fills TAs.
Definition
TAMakerHorizontalMuonAlgorithm.cpp:22
triggeralgs::TAMakerHorizontalMuonAlgorithm::m_current_window
TPWindow m_current_window
Definition
TAMakerHorizontalMuonAlgorithm.hpp:28
triggeralgs::TAMakerHorizontalMuonAlgorithm::add_window_to_record
void add_window_to_record(TPWindow window)
Definition
TAMakerHorizontalMuonAlgorithm.cpp:272
triggeralgs::TAMakerHorizontalMuonAlgorithm::m_print_tp_info
bool m_print_tp_info
Definition
TAMakerHorizontalMuonAlgorithm.hpp:37
triggeralgs::TAMakerHorizontalMuonAlgorithm::construct_ta
TriggerActivity construct_ta() const
Definition
TAMakerHorizontalMuonAlgorithm.cpp:157
triggeralgs::TAMakerHorizontalMuonAlgorithm::m_sot_threshold
uint16_t m_sot_threshold
Definition
TAMakerHorizontalMuonAlgorithm.hpp:36
triggeralgs::TAMakerHorizontalMuonAlgorithm::m_trigger_on_n_channels
bool m_trigger_on_n_channels
Definition
TAMakerHorizontalMuonAlgorithm.hpp:33
triggeralgs::TAMakerHorizontalMuonAlgorithm::m_trigger_on_adc
bool m_trigger_on_adc
Definition
TAMakerHorizontalMuonAlgorithm.hpp:32
triggeralgs::TAMakerHorizontalMuonAlgorithm::check_sot
int check_sot() const
Definition
TAMakerHorizontalMuonAlgorithm.cpp:325
triggeralgs::TPWindow
Definition
TPWindow.hpp:21
triggeralgs::TriggerActivityMaker::configure
virtual void configure(const nlohmann::json &config)
Definition
TriggerActivityMaker.hpp:111
TLOG_DEBUG
#define TLOG_DEBUG(lvl,...)
Definition
Logging.hpp:112
triggeralgs
Definition
AbstractFactory.hpp:18
triggeralgs::TLVL_DEBUG_MEDIUM
@ TLVL_DEBUG_MEDIUM
Definition
Logging.hpp:23
triggeralgs::TLVL_DEBUG_ALL
@ TLVL_DEBUG_ALL
Definition
Logging.hpp:25
triggeralgs::TriggerPrimitive
dunedaq::trgdataformats::TriggerPrimitive TriggerPrimitive
Definition
TriggerPrimitive.hpp:22
triggeralgs::channel_t
dunedaq::trgdataformats::channel_t channel_t
Definition
Types.hpp:20
TAMakerHorizontalMuonAlgorithm.hpp
dunedaq::trgdataformats::TriggerActivityData::algorithm
Algorithm algorithm
Definition
TriggerActivityData.hpp:57
dunedaq::trgdataformats::TriggerActivityData::channel_peak
channel_t channel_peak
Definition
TriggerActivityData.hpp:52
dunedaq::trgdataformats::TriggerActivityData::time_activity
timestamp_t time_activity
Definition
TriggerActivityData.hpp:49
dunedaq::trgdataformats::TriggerActivityData::adc_integral
uint64_t adc_integral
Definition
TriggerActivityData.hpp:53
dunedaq::trgdataformats::TriggerActivityData::Type::kTPC
@ kTPC
Definition
TriggerActivityData.hpp:22
dunedaq::trgdataformats::TriggerActivityData::type
Type type
Definition
TriggerActivityData.hpp:56
dunedaq::trgdataformats::TriggerActivityData::time_peak
timestamp_t time_peak
Definition
TriggerActivityData.hpp:48
dunedaq::trgdataformats::TriggerActivityData::Algorithm::kHorizontalMuon
@ kHorizontalMuon
Definition
TriggerActivityData.hpp:32
dunedaq::trgdataformats::TriggerActivityData::adc_peak
uint16_t adc_peak
Definition
TriggerActivityData.hpp:54
dunedaq::trgdataformats::TriggerActivityData::channel_end
channel_t channel_end
Definition
TriggerActivityData.hpp:51
dunedaq::trgdataformats::TriggerActivityData::time_end
timestamp_t time_end
Definition
TriggerActivityData.hpp:47
dunedaq::trgdataformats::TriggerActivityData::channel_start
channel_t channel_start
Definition
TriggerActivityData.hpp:50
dunedaq::trgdataformats::TriggerActivityData::time_start
timestamp_t time_start
Definition
TriggerActivityData.hpp:46
dunedaq::trgdataformats::TriggerActivityData::detid
detid_t detid
Definition
TriggerActivityData.hpp:55
dunedaq::trgdataformats::TriggerPrimitive::detid
uint64_t detid
Definition
TriggerPrimitive.hpp:33
dunedaq::trgdataformats::TriggerPrimitive::channel
uint64_t channel
Definition
TriggerPrimitive.hpp:36
dunedaq::trgdataformats::TriggerPrimitive::samples_over_threshold
uint64_t samples_over_threshold
Definition
TriggerPrimitive.hpp:38
dunedaq::trgdataformats::TriggerPrimitive::adc_peak
uint64_t adc_peak
Definition
TriggerPrimitive.hpp:43
dunedaq::trgdataformats::TriggerPrimitive::time_start
uint64_t time_start
Definition
TriggerPrimitive.hpp:39
dunedaq::trgdataformats::TriggerPrimitive::samples_to_peak
uint64_t samples_to_peak
Definition
TriggerPrimitive.hpp:40
dunedaq::trgdataformats::TriggerPrimitive::adc_integral
uint64_t adc_integral
Definition
TriggerPrimitive.hpp:42
triggeralgs::TriggerActivity
Definition
TriggerActivity.hpp:20
triggeralgs::TriggerActivity::inputs
std::vector< TriggerPrimitive > inputs
Definition
TriggerActivity.hpp:33
Generated on
for DUNE-DAQ by
1.17.0