Line data Source code
1 : /**
2 : * @file TCMakerMichelElectronAlgorithm.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/MichelElectron/TCMakerMichelElectronAlgorithm.hpp"
10 :
11 : #include "TRACE/trace.h"
12 : #define TRACE_NAME "TCMakerMichelElectronAlgorithm"
13 :
14 : #include <vector>
15 :
16 : using namespace triggeralgs;
17 :
18 : using Logging::TLVL_DEBUG_ALL;
19 : using Logging::TLVL_DEBUG_HIGH;
20 : using Logging::TLVL_DEBUG_LOW;
21 : using Logging::TLVL_DEBUG_INFO;
22 : using Logging::TLVL_VERY_IMPORTANT;
23 :
24 : void
25 0 : TCMakerMichelElectronAlgorithm::process(const TriggerActivity& activity,
26 : std::vector<TriggerCandidate>& output_tc)
27 : {
28 :
29 0 : std::vector<TriggerActivity::TriggerActivityData> ta_list = { static_cast<TriggerActivity::TriggerActivityData>(
30 0 : activity) };
31 :
32 : // The first time process() is called, reset window object.
33 0 : if (m_current_window.is_empty()) {
34 0 : m_current_window.reset(activity);
35 0 : m_activity_count++;
36 : // Trivial TC Logic:
37 : // If the request has been made to not trigger on number of channels or
38 : // total adc, simply construct a trigger candidate from any single activity.
39 0 : if ((!m_trigger_on_adc) && (!m_trigger_on_n_channels)) {
40 :
41 : // add_window_to_record(m_current_window);
42 : // dump_window_record();
43 0 : TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TCM:ME] Constructing TC.";
44 :
45 0 : TriggerCandidate tc = construct_tc();
46 0 : output_tc.push_back(tc);
47 :
48 : // Clear the current window (only has a single TA in it)
49 0 : m_current_window.clear();
50 0 : }
51 0 : return;
52 : }
53 :
54 : // FIX ME: Only want to call this if running in debug mode.
55 : // add_window_to_record(m_current_window);
56 :
57 : // If the difference between the current TA's start time and the start of the window
58 : // is less than the specified window size, add the TA to the window.
59 0 : if ((activity.time_start - m_current_window.time_start) < m_window_length) {
60 0 : TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TCM:ME] Window not yet complete, adding the activity to the window.";
61 0 : m_current_window.add(activity);
62 : }
63 : // If the addition of the current TA to the window would make it longer
64 : // than the specified window length, don't add it but check whether the sum of all adc in
65 : // the existing window is above the specified threshold. If it is, and we are triggering on ADC,
66 : // make a TA and start a fresh window with the current TP.
67 0 : else if (m_current_window.adc_integral > m_adc_threshold && m_trigger_on_adc) {
68 0 : TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TCM:ME] ADC integral in window is greater than specified threshold.";
69 0 : TriggerCandidate tc = construct_tc();
70 :
71 0 : output_tc.push_back(tc);
72 0 : TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TCM:ME] Resetting window with activity.";
73 0 : m_current_window.reset(activity);
74 0 : }
75 : // If the addition of the current TA to the window would make it longer
76 : // than the specified window length, don't add it but check whether the number of hit channels in
77 : // the existing window is above the specified threshold. If it is, and we are triggering on channels,
78 : // make a TC and start a fresh window with the current TA.
79 0 : else if (m_current_window.n_channels_hit() > m_n_channels_threshold && m_trigger_on_n_channels) {
80 0 : tc_number++;
81 : // output_tc.push_back(construct_tc());
82 0 : m_current_window.reset(activity);
83 0 : TLOG_DEBUG(TLVL_DEBUG_INFO) << "[TCM:ME] Should not see this!";
84 : }
85 : // If it is not, move the window along.
86 : else {
87 0 : TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TCM:ME] Window is at required length but specified threshold not met, shifting window along.";
88 0 : m_current_window.move(activity, m_window_length);
89 : }
90 :
91 : //TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TCM:ME] " m_current_window;
92 :
93 0 : m_activity_count++;
94 :
95 : // if(m_activity_count % 500 == 0) dump_window_record();
96 :
97 0 : return;
98 0 : }
99 :
100 : void
101 0 : TCMakerMichelElectronAlgorithm::configure(const nlohmann::json& config)
102 : {
103 0 : TriggerCandidateMaker::configure(config);
104 :
105 : // FIX ME: Use some schema here. Also can't work out how to pass booleans.
106 0 : if (config.is_object()) {
107 0 : if (config.contains("trigger_on_adc"))
108 0 : m_trigger_on_adc = config["trigger_on_adc"];
109 0 : if (config.contains("trigger_on_n_channels"))
110 0 : m_trigger_on_n_channels = config["trigger_on_n_channels"];
111 0 : if (config.contains("adc_threshold"))
112 0 : m_adc_threshold = config["adc_threshold"];
113 0 : if (config.contains("n_channels_threshold"))
114 0 : m_n_channels_threshold = config["n_channels_threshold"];
115 0 : if (config.contains("window_length"))
116 0 : m_window_length = config["window_length"];
117 : // if (config.contains("channel_map")) m_channel_map = config["channel_map"];
118 : }
119 0 : if (m_trigger_on_adc && m_trigger_on_n_channels) {
120 0 : TLOG_DEBUG(TLVL_VERY_IMPORTANT) << "[TCM:ME] Triggering on ADC count and number of channels is not supported.";
121 0 : throw BadConfiguration(ERS_HERE, TRACE_NAME);
122 : }
123 0 : if (!m_trigger_on_adc && !m_trigger_on_n_channels) {
124 0 : TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TCM:ME] Both trigger flags are false. Passing TAs through 1:1.";
125 : }
126 :
127 0 : return;
128 : }
129 :
130 : TriggerCandidate
131 0 : TCMakerMichelElectronAlgorithm::construct_tc() const
132 : {
133 0 : TriggerActivity latest_ta_in_window = m_current_window.inputs.back();
134 :
135 0 : TriggerCandidate tc;
136 0 : tc.time_start = m_current_window.time_start;
137 0 : tc.time_end = latest_ta_in_window.time_end;
138 0 : tc.time_candidate = m_current_window.time_start;
139 0 : tc.detid = latest_ta_in_window.detid;
140 0 : tc.type = m_tc_type_out;
141 0 : tc.algorithm = TriggerCandidate::Algorithm::kMichelElectron;
142 :
143 : // Take the list of triggeralgs::TriggerActivity in the current
144 : // window and convert them (implicitly) to detdataformats'
145 : // TriggerActivityData, which is the base class of TriggerActivity
146 0 : for (auto& ta : m_current_window.inputs) {
147 0 : tc.inputs.push_back(ta);
148 : }
149 :
150 0 : return tc;
151 0 : }
152 :
153 : bool
154 0 : TCMakerMichelElectronAlgorithm::check_adjacency() const
155 : {
156 : // FIX ME: An adjacency check on the channels which have hits.
157 0 : return true;
158 : }
159 :
160 : // Functions below this line are for debugging purposes.
161 : void
162 0 : TCMakerMichelElectronAlgorithm::add_window_to_record(Window window)
163 : {
164 0 : m_window_record.push_back(window);
165 0 : return;
166 : }
167 :
168 : void
169 0 : TCMakerMichelElectronAlgorithm::dump_window_record()
170 : {
171 : // FIX ME: Need to index this outfile in the name by detid or something similar.
172 0 : std::ofstream outfile;
173 0 : outfile.open("window_record_tcm.csv", std::ios_base::app);
174 :
175 0 : for (auto window : m_window_record) {
176 0 : outfile << window.time_start << ",";
177 0 : outfile << window.inputs.back().time_start << ",";
178 0 : outfile << window.inputs.back().time_start - window.time_start << ",";
179 0 : outfile << window.adc_integral << ",";
180 0 : outfile << window.n_channels_hit() << ",";
181 0 : outfile << window.inputs.size() << std::endl;
182 0 : }
183 :
184 0 : outfile.close();
185 :
186 0 : m_window_record.clear();
187 :
188 0 : return;
189 0 : }
190 :
191 : /*
192 : void
193 : TCMakerMichelElectronAlgorithm::flush(timestamp_t, std::vector<TriggerCandidate>& output_tc)
194 : {
195 : // Check the status of the current window, construct TC if conditions are met. Regardless
196 : // of whether the conditions are met, reset the window.
197 : if(m_current_window.adc_integral > m_adc_threshold && m_trigger_on_adc){
198 : //else if(m_current_window.adc_integral > m_conf.adc_threshold && m_conf.trigger_on_adc){
199 : //TLOG_DEBUG(TRACE_NAME) << "ADC integral in window is greater than specified threshold.";
200 : output_tc.push_back(construct_tc());
201 : }
202 : else if(m_current_window.n_channels_hit() > m_n_channels_threshold && m_trigger_on_n_channels){
203 : //else if(m_current_window.n_channels_hit() > m_conf.n_channels_threshold && m_conf.trigger_on_n_channels){
204 : //TLOG_DEBUG(TRACE_NAME) << "Number of channels hit in the window is greater than specified threshold.";
205 : output_tc.push_back(construct_tc());
206 : }
207 :
208 : //TLOG_DEBUG(TRACE_NAME) << "Clearing the current window, on the arrival of the next input_tp, the window will be
209 : reset."; m_current_window.clear();
210 :
211 : return;
212 : }*/
213 :
214 12 : REGISTER_TRIGGER_CANDIDATE_MAKER(TRACE_NAME, TCMakerMichelElectronAlgorithm)
|