DUNE-DAQ
DUNE Trigger and Data Acquisition software
Toggle main menu visibility
Loading...
Searching...
No Matches
dunedaq
sourcecode
triggeralgs
src
TAMakerSWIFTAlgorithm.cpp
Go to the documentation of this file.
1
#include "
triggeralgs/SWIFT/TAMakerSWIFTAlgorithm.hpp
"
2
3
#include "TRACE/trace.h"
4
#define TRACE_NAME "TriggerActivityMakerSWIFTPlugin"
5
6
#include <cassert>
7
#include <iostream>
8
#include <cmath>
9
10
namespace
triggeralgs
{
11
12
// configuration
13
void
TriggerActivityMakerSWIFT::configure
(
const
nlohmann::json& config)
14
{
15
//window settings
16
m_window_length
= config.value(
"window_length"
, 32000);
// in DTS ticks (32 * 1000 readout ticks @ 500ns/tick)
17
m_inspect_energy_threshold_sadc
= config.value(
"inspect_energy_threshold_sadc"
, 15000);
18
m_accept_energy_threshold_sadc
= config.value(
"accept_energy_threshold_sadc"
, 55000);
19
20
//tp filtering settings
21
m_min_adc_peak
= config.value(
"min_adc_peak"
, 80);
//ADC
22
m_min_samples_over_threshold
= config.value(
"min_samples_over_threshold"
, 256);
// 8 * 32 DTS ticks while still using TPv1 FIXME
23
24
//clustering
25
//these depend on detector properties. default values for HD
26
m_cm_per_tick
= config.value(
"cm_per_tick"
, 0.016 * 0.16);
// sampling rate [us/tick] * drift velocity [cm/us]
27
m_wire_pitch
= config.value(
"wire_pitch"
, 0.48);
// cm
28
m_db_min_samples
= config.value(
"min_samples"
, 2);
//min. number of TPs for valid cluster
29
m_db_eps
= config.value(
"epsilon"
, 2);
//dbscan search radius in cm
30
m_cluster_energy_cut_sadc
= config.value(
"cluster_energy_cut_sadc"
, 22000);
// min energy of dominant cluster eng. in window for acceptance
31
32
assert(
m_window_length
> 0);
33
}
34
35
//TP refinement
36
bool
TriggerActivityMakerSWIFT::preprocess
(
const
TriggerPrimitive
& input_tp){
37
if
((input_tp.
adc_peak
<
m_min_adc_peak
) && (input_tp.
samples_over_threshold
<
m_min_samples_over_threshold
)) {
38
return
false
;
39
}
40
return
true
;
41
}
42
43
// Reset window state
44
void
TriggerActivityMakerSWIFT::reset_window_state
(uint64_t new_window_start) {
45
m_window_start
= new_window_start;
46
m_window_energy_sadc
= 0;
47
m_tp_count
= 0;
48
m_current_ta
=
TriggerActivity
();
49
m_current_ta
.time_start =
m_window_start
;
50
}
51
52
//main function for binning TPs into fixed-size time windows
53
//assumes TPs are strictly time-ordered
54
void
TriggerActivityMakerSWIFT::process
(
const
TriggerPrimitive
& input_tp, std::vector<TriggerActivity>& output_tas)
55
{
56
57
// Apply TP filtering
58
if
(!
preprocess
(input_tp)) {
59
return
;
60
}
61
62
// If TP is valid, determine which window this TP belongs to
63
const
uint64_t tp_window_start = (input_tp.
time_start
/
m_window_length
) *
m_window_length
;
64
65
// Initialise on first TP
66
if
(!
m_initialised
) {
67
68
//create TA instance once at run start
69
m_current_ta
=
TriggerActivity
();
70
71
//reset window state
72
reset_window_state
(tp_window_start);
73
m_initialised
=
true
;
74
}
75
76
//if TP belongs to past window (already closed), reject it (not ideal)
77
if
(tp_window_start <
m_window_start
){
78
return
;
79
}
80
81
//if TP belongs to future window, close existing TA and start a new one at current time
82
if
(tp_window_start >
m_window_start
){
83
close_window
(output_tas);
84
reset_window_state
(tp_window_start);
85
}
86
87
//If we got here, the TP belongs to the current window
88
m_current_ta
.inputs.push_back(input_tp);
89
m_window_energy_sadc
+= input_tp.
adc_integral
;
90
++
m_tp_count
;
91
}
92
93
//function which gets called when the window is closed.
94
//main window categorisation & TA generation happens here
95
void
TriggerActivityMakerSWIFT::close_window
(std::vector<TriggerActivity>& output_tas) {
96
97
if
(
m_current_ta
.inputs.empty())
return
;
98
99
//Prompt window categorisatoin : immidiate accept, inspect, reject based on local energy in window
100
WindowDecision
decision;
101
if
(
m_window_energy_sadc
>=
m_accept_energy_threshold_sadc
) decision =
WindowDecision::kAccept
;
102
else
if
(
m_window_energy_sadc
>=
m_inspect_energy_threshold_sadc
) decision =
WindowDecision::kInspect
;
103
else
return
;
// Reject
104
105
// cluster inspect cases
106
if
(decision ==
WindowDecision::kInspect
) {
107
const
uint64_t max_cluster_energy =
extract_dominant_cluster_energy
(
m_current_ta
.inputs,
m_db_eps
,
m_db_min_samples
);
108
if
(max_cluster_energy <=
m_cluster_energy_cut_sadc
)
return
;
// reject window if it didn't pass inspection
109
}
110
111
// Emit TA: should only reach this step if dealing with Accept, or Inspect windows that passed clustering
112
set_ta_attributes
();
113
output_tas.push_back(
m_current_ta
);
114
}
115
116
117
118
//Clustering function: density-based clustering in t-z, where both coordinates are expressed in cm.
119
//returns only max eng. for now, as that's the param. based on which decision is made.
120
//FIXME eventually want this step to return nclusrers, mean cluster eng. etc.
121
uint64_t
TriggerActivityMakerSWIFT::extract_dominant_cluster_energy
(
const
std::vector<TriggerPrimitive>& tps,
float
eps,
int
min_samples){
122
123
struct
Point {
124
float
z;
125
float
t;
126
uint64_t adc;
127
};
128
129
//since time and channel are in different units, express TPs as points in unified coordinate system (z,t)
130
std::vector<Point> points;
131
points.reserve(tps.size());
132
for
(
const
auto
& tp : tps) {
133
points.push_back({tp.channel *
m_wire_pitch
, (tp.time_start -
m_window_start
) *
m_cm_per_tick
, tp.adc_integral});
134
}
135
136
const
int
N = points.size();
//number of elements to cluster
137
int
cluster_id = 0;
138
std::vector<int> labels(N, -1);
// initialise all labels to noise for now
139
std::vector<uint8_t> visited(N, 0);
140
float
eps2 = eps * eps;
//clustering radius
141
142
for
(
int
i = 0; i < N; ++i) {
143
if
(visited[i])
continue
;
144
visited[i] = 1;
145
146
std::vector<int> neigh;
147
const
float
zi = points[i].z;
148
const
float
ti = points[i].t;
149
for
(
int
j = 0; j < N; ++j) {
150
float
dz = points[j].z - zi;
151
float
dt = points[j].t - ti;
152
if
(dz*dz + dt*dt <= eps2) neigh.push_back(j);
153
}
154
155
if
(neigh.size() <
static_cast<
size_t
>
(min_samples)) {
156
labels[i] = -1;
157
continue
;
158
}
159
160
labels[i] = cluster_id;
161
162
size_t
k = 0;
163
while
(k < neigh.size()) {
164
int
j = neigh[k];
165
166
if
(!visited[j]) {
167
visited[j] = 1;
168
169
std::vector<int> neigh2;
170
const
float
zj = points[j].z;
171
const
float
tj = points[j].t;
172
for
(
int
m = 0; m < N; ++m) {
173
float
dz = points[m].z - zj;
174
float
dt = points[m].t - tj;
175
if
(dz*dz + dt*dt <= eps2) neigh2.push_back(m);
176
}
177
if
(neigh2.size() >=
static_cast<
size_t
>
(min_samples)) {
178
for
(
int
m : neigh2) {
179
if
(std::find(neigh.begin(), neigh.end(), m) == neigh.end())
180
neigh.push_back(m);
181
}
182
}
183
}
184
185
if
(labels[j] == -1) labels[j] = cluster_id;
186
++k;
187
}
188
++cluster_id;
189
}
190
191
// once clusters are formed, calculate the energies
192
std::vector<uint64_t> cluster_sums(cluster_id, 0);
193
for
(
int
i = 0; i < N; ++i) {
194
if
(labels[i] >= 0) cluster_sums[labels[i]] += points[i].adc;
195
}
196
//return dominant cluster energy in window
197
if
(cluster_sums.empty())
return
0;
198
return
*std::max_element(cluster_sums.begin(), cluster_sums.end());
199
}
200
201
202
//TA feature extraction - FIXME most of these fields are somewhat useless
203
void
TriggerActivityMakerSWIFT::set_ta_attributes
()
204
{
205
m_current_ta
.time_start =
m_window_start
;
206
m_current_ta
.time_end =
m_window_start
+
m_window_length
;
207
m_current_ta
.adc_integral =
m_window_energy_sadc
;
208
209
const
TriggerPrimitive
& first_tp =
m_current_ta
.inputs.front();
210
m_current_ta
.detid = first_tp.
detid
;
211
m_current_ta
.type =
TriggerActivity::Type::kTPC
;
212
m_current_ta
.algorithm =
TriggerActivity::Algorithm::kSWIFT
;
213
214
215
dunedaq::trgdataformats::channel_t
min_ch = first_tp.
channel
;
216
dunedaq::trgdataformats::channel_t
max_ch = first_tp.
channel
;
217
218
// Peak quantities
219
m_current_ta
.adc_peak = 0;
220
for
(
const
auto
& tp :
m_current_ta
.inputs) {
221
if
(tp.channel < min_ch) min_ch = tp.channel;
222
if
(tp.channel > max_ch) max_ch = tp.channel;
223
224
if
(tp.adc_peak >
m_current_ta
.adc_peak) {
225
m_current_ta
.adc_peak = tp.adc_peak;
226
m_current_ta
.channel_peak = tp.channel;
227
m_current_ta
.time_peak = tp.time_start;
228
}
229
}
230
231
m_current_ta
.channel_start = min_ch;
232
m_current_ta
.channel_end = max_ch;
233
m_current_ta
.time_activity =
m_current_ta
.time_peak;
234
235
}
236
237
238
void
TriggerActivityMakerSWIFT::flush
(
timestamp_t
/*until*/
, std::vector<TriggerActivity>& output_tas)
239
{
240
if
(!
m_initialised
)
return
;
241
close_window
(output_tas);
242
}
243
244
REGISTER_TRIGGER_ACTIVITY_MAKER
(
TRACE_NAME
,
TriggerActivityMakerSWIFT
)
245
246
}
// namespace triggeralgs
TAMakerSWIFTAlgorithm.hpp
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
TriggerActivity
TriggerActivity
Definition
TriggerActivity_serialization.hpp:37
triggeralgs::TriggerActivityMakerSWIFT
Definition
TAMakerSWIFTAlgorithm.hpp:17
triggeralgs::TriggerActivityMakerSWIFT::m_cm_per_tick
float m_cm_per_tick
Definition
TAMakerSWIFTAlgorithm.hpp:42
triggeralgs::TriggerActivityMakerSWIFT::m_cluster_energy_cut_sadc
uint64_t m_cluster_energy_cut_sadc
Definition
TAMakerSWIFTAlgorithm.hpp:46
triggeralgs::TriggerActivityMakerSWIFT::m_current_ta
TriggerActivity m_current_ta
Definition
TAMakerSWIFTAlgorithm.hpp:27
triggeralgs::TriggerActivityMakerSWIFT::preprocess
bool preprocess(const TriggerPrimitive &input_tp)
TP pre-processing/filtering.
Definition
TAMakerSWIFTAlgorithm.cpp:36
triggeralgs::TriggerActivityMakerSWIFT::set_ta_attributes
void set_ta_attributes()
Definition
TAMakerSWIFTAlgorithm.cpp:203
triggeralgs::TriggerActivityMakerSWIFT::extract_dominant_cluster_energy
uint64_t extract_dominant_cluster_energy(const std::vector< TriggerPrimitive > &tps, float eps, int min_samples)
Definition
TAMakerSWIFTAlgorithm.cpp:121
triggeralgs::TriggerActivityMakerSWIFT::reset_window_state
void reset_window_state(uint64_t new_window_start)
Definition
TAMakerSWIFTAlgorithm.cpp:44
triggeralgs::TriggerActivityMakerSWIFT::configure
void configure(const nlohmann::json &config)
Definition
TAMakerSWIFTAlgorithm.cpp:13
triggeralgs::TriggerActivityMakerSWIFT::m_inspect_energy_threshold_sadc
uint64_t m_inspect_energy_threshold_sadc
Definition
TAMakerSWIFTAlgorithm.hpp:34
triggeralgs::TriggerActivityMakerSWIFT::m_db_eps
float m_db_eps
Definition
TAMakerSWIFTAlgorithm.hpp:45
triggeralgs::TriggerActivityMakerSWIFT::m_window_start
uint64_t m_window_start
Definition
TAMakerSWIFTAlgorithm.hpp:53
triggeralgs::TriggerActivityMakerSWIFT::m_window_energy_sadc
uint64_t m_window_energy_sadc
Definition
TAMakerSWIFTAlgorithm.hpp:54
triggeralgs::TriggerActivityMakerSWIFT::m_db_min_samples
int m_db_min_samples
Definition
TAMakerSWIFTAlgorithm.hpp:44
triggeralgs::TriggerActivityMakerSWIFT::m_min_adc_peak
uint16_t m_min_adc_peak
Definition
TAMakerSWIFTAlgorithm.hpp:38
triggeralgs::TriggerActivityMakerSWIFT::close_window
void close_window(std::vector< TriggerActivity > &output_tas)
Definition
TAMakerSWIFTAlgorithm.cpp:95
triggeralgs::TriggerActivityMakerSWIFT::m_min_samples_over_threshold
uint16_t m_min_samples_over_threshold
Definition
TAMakerSWIFTAlgorithm.hpp:39
triggeralgs::TriggerActivityMakerSWIFT::m_window_length
uint64_t m_window_length
Definition
TAMakerSWIFTAlgorithm.hpp:33
triggeralgs::TriggerActivityMakerSWIFT::flush
void flush(timestamp_t until, std::vector< TriggerActivity > &output_tas) override
Definition
TAMakerSWIFTAlgorithm.cpp:238
triggeralgs::TriggerActivityMakerSWIFT::m_accept_energy_threshold_sadc
uint64_t m_accept_energy_threshold_sadc
Definition
TAMakerSWIFTAlgorithm.hpp:35
triggeralgs::TriggerActivityMakerSWIFT::process
void process(const TriggerPrimitive &input_tp, std::vector< TriggerActivity > &output_tas) override
TP processing function that creates & fills TAs.
Definition
TAMakerSWIFTAlgorithm.cpp:54
triggeralgs::TriggerActivityMakerSWIFT::WindowDecision
WindowDecision
Definition
TAMakerSWIFTAlgorithm.hpp:58
triggeralgs::TriggerActivityMakerSWIFT::WindowDecision::kAccept
@ kAccept
Definition
TAMakerSWIFTAlgorithm.hpp:58
triggeralgs::TriggerActivityMakerSWIFT::WindowDecision::kInspect
@ kInspect
Definition
TAMakerSWIFTAlgorithm.hpp:58
triggeralgs::TriggerActivityMakerSWIFT::m_initialised
bool m_initialised
Definition
TAMakerSWIFTAlgorithm.hpp:52
triggeralgs::TriggerActivityMakerSWIFT::m_wire_pitch
float m_wire_pitch
Definition
TAMakerSWIFTAlgorithm.hpp:43
triggeralgs::TriggerActivityMakerSWIFT::m_tp_count
uint16_t m_tp_count
Definition
TAMakerSWIFTAlgorithm.hpp:55
dunedaq::trgdataformats::channel_t
uint32_t channel_t
Definition
Types.hpp:52
triggeralgs
Definition
AbstractFactory.hpp:18
triggeralgs::timestamp_t
dunedaq::trgdataformats::timestamp_t timestamp_t
Definition
Types.hpp:16
triggeralgs::TriggerPrimitive
dunedaq::trgdataformats::TriggerPrimitive TriggerPrimitive
Definition
TriggerPrimitive.hpp:22
dunedaq::trgdataformats::TriggerActivityData::Type::kTPC
@ kTPC
Definition
TriggerActivityData.hpp:22
dunedaq::trgdataformats::TriggerActivityData::Algorithm::kSWIFT
@ kSWIFT
Definition
TriggerActivityData.hpp:39
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::adc_integral
uint64_t adc_integral
Definition
TriggerPrimitive.hpp:42
Generated on
for DUNE-DAQ by
1.17.0