DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
TAMakerProtoDUNEBSMWindowAlgorithm.cpp
Go to the documentation of this file.
1
8
10
11#include "TRACE/trace.h"
12#define TRACE_NAME "TAMakerProtoDUNEBSMWindowAlgorithm"
13
14#include <vector>
15#include <chrono>
16
17using namespace triggeralgs;
22
23void
24TAMakerProtoDUNEBSMWindowAlgorithm::process(const TriggerPrimitive& input_tp, std::vector<TriggerActivity>& output_ta)
25{
26
27 if(m_current_window.is_empty()){
28 // Reset window with new TP
29 m_current_window.reset(input_tp);
30 // Initialise last time an XGBoost prediction was made
32 // Iterate number of TPs in the window
34 // First time operator is called set ROP first and last channel
35 unsigned int detelement = channelMap->get_element_id_from_offline_channel(input_tp.channel);
36 unsigned int plane = channelMap->get_plane_from_offline_channel(input_tp.channel);
37
38 // Are we on the collection plane? Use XGBoost model for collection plane TPs
39 // evaluate the sum of the TP charge if on induction planes
40 // Induction plane IDs = 0, 1
41 // Collection plane ID = 2
42 if (plane > 1) m_collection_plane = true;
43
44 // Use PlaneInfo object to get the first and last channels on plane
45 PlaneInfo plane_info = m_det_plane_map.get_plane_info(m_channel_map_name, detelement, plane);
46 m_first_channel = static_cast<channel_t>(plane_info.min_channel);
47 m_n_channels_on_plane = static_cast<channel_t>(plane_info.n_channels);
48
49 // If we are in PD-VD use 'effective' channel mapping for CRPs
50 // (but only for collection plane)
52 m_pdvd_eff_channel_mapper = std::make_unique<PDVDEffectiveChannelMap>(plane_info.min_channel, plane_info.n_channels);
53 // Get the first effective channel and number of effective channels on the plane
54 m_first_channel = m_pdvd_eff_channel_mapper->remapCollectionPlaneChannel(m_first_channel);
55 m_n_channels_on_plane = m_pdvd_eff_channel_mapper->getNEffectiveChannels();
56 }
57
58 TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TAM:BSMW] 1st Chan = " << m_first_channel << ", N channels on plane = " << m_n_channels_on_plane << std::endl
59 << "Number of channel bins = " << m_num_chanbins;
60 return;
61 }
62
63 // If the difference between the current TP's start time and the start of the window
64 // is less than the specified window size, add the TP to the window.
65 if((input_tp.time_start - m_current_window.time_start) < m_window_length){
66 TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TAM:BSMW] Window not yet complete, adding the input_tp to the window.";
67 m_current_window.add(input_tp);
68 }
69
70 // If the addition of the current TP to the window would make it longer
71 // than the specified window length, don't add it
72 // First, if these are not collection plane TPs, just evaluate the total charge
73 // If the total charge on the induction plane crosses a threshold, create a TA
75 TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TAM:BSMW] ADC integral in window is greater than specified threshold.";
76 output_ta.push_back(construct_ta());
77 TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TAM:BSMW] Resetting window with input_tp.";
78 m_current_window.reset(input_tp);
79 }
80
81 // If the addition of the current TP to the window would make it longer
82 // than the specified window length, don't add it
83 // Check the TPs are on the collection plane - if they are we can use XGBoost
84 // Instead check whether it has been long enough since the last XGBoost prediction
85 // then run the model to determine whether to create a TA
86 else if (m_collection_plane &&
87 (m_current_window.time_start - m_last_pred_time) > m_bin_length && // check enough time has passed since last window
88 m_current_window.adc_integral > m_adc_threshold_collection && // set a low minimum threshold for the ADC integral sum
89 compute_treelite_classification() // XGBoost classifier
90 )
91 {
92 TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TAM:BSMW] XGBoost neutrino prob. is greater than specified threshold.";
93 output_ta.push_back(construct_ta());
94 TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TAM:BSMW] Resetting window with input_tp.";
95 m_current_window.reset(input_tp);
96 }
97 // If it is not, move the window along.
98 else{
99 TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TAM:BSMW] Window is at required length but adc/bdt threshold not met, shifting window along.";
100 m_current_window.move(input_tp, m_window_length);
101 }
102
103 TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TAM:BSMW] " << m_current_window;
104
106
107 return;
108
109}
110
111void
113{
114 if (config.is_object()){
115 if (config.contains("channel_map_name")) m_channel_map_name = config["channel_map_name"];
116 if (config.contains("adc_threshold_induction")) m_adc_threshold_induction = config["adc_threshold_induction"];
117 if (config.contains("bdt_threshold")) m_bdt_threshold = config["bdt_threshold"];
118 }
119 else{
120 TLOG_DEBUG(TLVL_IMPORTANT) << "[TAM:BSMW] Use DEFAULT values of channel_map_name, adc_threshold_induction and bdt_threshold.";
121 }
122
123 TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TAM:BSMW] Channel map name is " << m_channel_map_name <<
124 ". ADC threshold for the induction planes set to " << m_adc_threshold_induction <<
125 ". BDT threshold for collection plane set to " << m_bdt_threshold;
126
127 channelMap = dunedaq::detchannelmaps::make_tpc_map(m_channel_map_name);
128
129 // If we are in PD-VD, set boolean to true to enable effective channel mapping
130 if (m_channel_map_name == "PD2VDTPCChannelMap" || m_channel_map_name == "PD2VDBottomTPCChannelMap" ||
131 m_channel_map_name == "PD2VDTopTPCChannelMap") {
132 m_pdvd_map = true;
133 } else { // else we are in PD-HD and we use true channel mapping
134 m_pdvd_map = false;
135 }
136
138
139 m_compiled_model_interface = std::make_unique<CompiledModelInterface>(nbatch, m_pdvd_map);
140
141 const size_t num_feature = m_compiled_model_interface->GetNumFeatures();
142
143 flat_batched_inputs.resize(num_feature);
144
145 flat_batched_Entries.clear();
146 for (size_t i = 0; i < num_feature; ++i) {
147 union Entry zero;
148 zero.fvalue = 0.0;
149 flat_batched_Entries.emplace_back(zero);
150 }
151}
152
155{
156 TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TAM:BSMW] I am constructing a trigger activity!";
157
158 TriggerPrimitive latest_tp_in_window = m_current_window.tp_list.back();
159 // The time_peak, time_activity, channel_* and adc_peak fields of this TA are irrelevent
160 // for the purpose of this trigger alg.
162 ta.time_start = m_current_window.time_start;
163 ta.time_end = latest_tp_in_window.time_start + latest_tp_in_window.samples_over_threshold * 32;
164 ta.time_peak = latest_tp_in_window.samples_to_peak * 32 + latest_tp_in_window.time_start;
165 ta.time_activity = ta.time_peak;
166 ta.channel_start = latest_tp_in_window.channel;
167 ta.channel_end = latest_tp_in_window.channel;
168 ta.channel_peak = latest_tp_in_window.channel;
169 ta.adc_integral = m_current_window.adc_integral;
170 ta.adc_peak = latest_tp_in_window.adc_peak;
171 ta.detid = latest_tp_in_window.detid;
174 ta.inputs = m_current_window.tp_list;
175 return ta;
176}
177
198
199// Register algo in TA Factory
#define REGISTER_TRIGGER_ACTIVITY_MAKER(tam_name, tam_class)
#define TRACE_NAME
Name used by TRACE TLOG calls from this source file.
std::unique_ptr< PDVDEffectiveChannelMap > m_pdvd_eff_channel_mapper
void process(const TriggerPrimitive &input_tp, std::vector< TriggerActivity > &output_ta)
TP processing function that creates & fills TAs.
std::shared_ptr< dunedaq::detchannelmaps::TPCChannelMap > channelMap
std::unique_ptr< CompiledModelInterface > m_compiled_model_interface
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
@ TLVL_DEBUG_HIGH
Definition Logging.hpp:24
dunedaq::trgdataformats::timestamp_t timestamp_t
Definition Types.hpp:16
dunedaq::trgdataformats::TriggerPrimitive TriggerPrimitive
dunedaq::trgdataformats::channel_t channel_t
Definition Types.hpp:20
std::vector< TriggerPrimitive > inputs