DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
HSISourceModel.hpp
Go to the documentation of this file.
1
8#ifndef TRIGGER_PLUGINS_HSISOURCEMODEL_HPP_
9#define TRIGGER_PLUGINS_HSISOURCEMODEL_HPP_
10
14#include "trigger/Issues.hpp"
15#include "trigger/Latency.hpp"
19#include <functional>
20
28#include "iomanager/Sender.hpp"
29#include "logging/Logging.hpp"
30
31namespace dunedaq::trigger {
32
43
45{
46public:
48
57 ~HSISourceModel() override
58 {
59 m_data_receiver.reset();
60 m_data_sender.reset();
61 m_signals.clear();
62 }
63
64 void init(const confmodel::DaqModule* cfg) override
65 {
66 if (cfg->get_outputs().size() != 1) {
67 throw datahandlinglibs::InitializationError(ERS_HERE, "Only 1 output supported for subscribers");
68 }
69 m_data_sender = get_iom_sender<triggeralgs::TriggerCandidate>(cfg->get_outputs()[0]->UID());
70
71 if (cfg->get_inputs().size() != 1) {
72 throw datahandlinglibs::InitializationError(ERS_HERE, "Only 1 input supported for subscribers");
73 }
74 m_data_receiver = get_iom_receiver<dfmessages::HSIEvent>(cfg->get_inputs()[0]->UID());
75 auto data_reader = cfg->cast<appmodel::DataSubscriberModule>();
76 if (data_reader == nullptr) {
77 throw datahandlinglibs::InitializationError(ERS_HERE, "DAQ module is not a DataReader");
78 }
79 auto hsi_conf = data_reader->get_configuration()->cast<appmodel::HSI2TCTranslatorConf>();
80 if (hsi_conf == nullptr) {
81 throw datahandlinglibs::InitializationError(ERS_HERE, "Missing HSI2TCTranslatorConf");
82 }
83
84 // Get the HSI-signal to TC-output map
85 for (auto win : hsi_conf->get_signals()) {
87 tc_type = static_cast<triggeralgs::TriggerCandidate::Type>(
89
90 // Throw error if unknown TC type
92 throw datahandlinglibs::InitializationError(ERS_HERE, "Provided an unknown TC type output to HSISourceModel");
93 }
94
95 // Throw error if already exists
96 uint32_t signal = win->get_signal_type();
97 if (m_signals.count(signal)) {
98 throw datahandlinglibs::InitializationError(
99 ERS_HERE, "Provided more than one of the same HSI signal ID input to HSISourceModel");
100 }
101
102 // Fill the signal-tctype map
103 m_signals[signal] = { tc_type, win->get_time_before(), win->get_time_after() };
104
105 TLOG() << "Will cover HSI signal id: " << signal << " to TC type: " << win->get_tc_type_name()
106 << " window before: " << win->get_time_before() << " window after: " << win->get_time_after();
107 }
108
109 m_prescale = hsi_conf->get_prescale();
110 m_latency_monitoring.store(hsi_conf->get_latency_monitoring());
111 }
112
113 void start()
114 {
115 m_data_receiver->add_callback(std::bind(&HSISourceModel::handle_payload, this, std::placeholders::_1));
116
117 m_running_flag.store(true);
118
120 m_tcs_made_count.store(0);
121 m_tcs_sent_count.store(0);
122 m_tcs_dropped_count.store(0);
123 }
124
125 void stop()
126 {
127 m_data_receiver->remove_callback();
128 m_running_flag.store(false);
130 }
131
132 bool handle_payload(dfmessages::HSIEvent& data) // NOLINT(build/unsigned)
133 {
135 if (m_latency_monitoring.load())
137
138 // Prescale after n-hsi received
140 return true;
141 }
142
143 TLOG_DEBUG(1) << "Received HSIEvent with signal map " << data.signal_map << " and timestamp " << data.timestamp;
144
145 // Iterate over all the signals
146 uint32_t signal_map = data.signal_map;
147 while (signal_map) {
148 // Get the index of the least significant bit
149 int bit_index = __builtin_ctzll(signal_map);
150 uint32_t signal = 1 << bit_index;
151
152 // Throw an error if we don't have this signal bit configured
153 if (!m_signals.count(signal)) {
154 throw dunedaq::trigger::SignalTypeError(ERS_HERE, "HSI subscriber", data.signal_map);
155 }
156
157 // Create the trigger candidate
159 candidate.time_start = data.timestamp - m_signals[signal].time_before;
160 candidate.time_end = data.timestamp + m_signals[signal].time_after;
161 candidate.time_candidate = data.timestamp;
162 // throw away bits 31-16 of header, that's OK for now
163 candidate.detid = (uint)detdataformats::DetID::Subdetector::kDAQ; // NOLINT(build/unsigned)
164 candidate.type = m_signals[signal].type;
166 candidate.inputs = {};
168
169 if (m_latency_monitoring.load())
171 // Send the TC
172 if (!m_data_sender->try_send(std::move(candidate), iomanager::Sender::s_no_block)) {
174 } else {
176 }
177
178 // Clear the least significant bit
179 signal_map &= signal_map - 1;
180 }
181
182 return true;
183 }
184
185 void generate_opmon_data() override
186 {
188
189 info.set_received_events_count(m_received_events_count);
190 info.set_tcs_made_count(m_tcs_made_count);
191 info.set_tcs_sent_count(m_tcs_sent_count);
192 info.set_tcs_dropped_count(m_tcs_dropped_count);
193
194 this->publish(std::move(info));
195
196 if (m_latency_monitoring.load() && m_running_flag.load()) {
197 opmon::TriggerLatency lat_info;
198
201
202 this->publish(std::move(lat_info));
203 }
204 }
205
207 {
208 TLOG() << "HSI Source Model opmon counters summary:";
209 TLOG() << "------------------------------";
210 TLOG() << "Signals received: \t" << m_received_events_count;
211 TLOG() << "TCs made: \t\t" << m_tcs_made_count;
212 TLOG() << "TCs sent: \t\t" << m_tcs_sent_count;
213 TLOG() << "TCs dropped: \t\t" << m_tcs_dropped_count;
214 TLOG();
215 }
216
217private:
219 std::shared_ptr<source_t> m_data_receiver;
220
222 std::shared_ptr<sink_t> m_data_sender;
223
225 std::map<uint32_t, HSISignal> m_signals;
226
227 // Stats
228 using metric_counter_type = uint64_t;
229 std::atomic<metric_counter_type> m_received_events_count{ 0 };
230 std::atomic<metric_counter_type> m_tcs_made_count{ 0 };
231 std::atomic<metric_counter_type> m_tcs_sent_count{ 0 };
232 std::atomic<metric_counter_type> m_tcs_dropped_count{ 0 };
233
235 uint64_t m_prescale;
236
237 // Create an instance of the Latency class
238 std::atomic<bool> m_running_flag{ false };
239 std::atomic<bool> m_latency_monitoring{ false };
241 std::atomic<metric_counter_type> m_latency_in{ 0 };
242 std::atomic<metric_counter_type> m_latency_out{ 0 };
243};
244
245} // namespace dunedaq::trigger
246
247#endif // TRIGGER_PLUGINS_HSISOURCEMODEL_HPP_
#define ERS_HERE
const dunedaq::appmodel::DataReaderConf * get_configuration() const
Get "configuration" relationship value.
const TARGET * cast() const noexcept
Casts object to different class.
const std::vector< const dunedaq::confmodel::Connection * > & get_inputs() const
Get "inputs" relationship value. List of connections to/from this module.
const std::vector< const dunedaq::confmodel::Connection * > & get_outputs() const
Get "outputs" relationship value. Output connections from this module.
static constexpr timeout_t s_no_block
Definition Sender.hpp:26
void publish(google::protobuf::Message &&, CustomOrigin &&co={}, OpMonLevel l=to_level(EntryOpMonLevel::kDefault)) const noexcept
std::atomic< metric_counter_type > m_tcs_made_count
std::atomic< metric_counter_type > m_latency_out
dunedaq::iomanager::ReceiverConcept< dfmessages::HSIEvent > source_t
dunedaq::iomanager::SenderConcept< triggeralgs::TriggerCandidate > sink_t
uint64_t m_prescale
{rescale for the input HSIEvents, default 1
std::atomic< bool > m_latency_monitoring
std::atomic< metric_counter_type > m_received_events_count
dunedaq::trigger::Latency m_latency_instance
void init(const confmodel::DaqModule *cfg) override
std::shared_ptr< sink_t > m_data_sender
std::map< uint32_t, HSISignal > m_signals
map of HSI signal ID bits to TC output configurations
bool handle_payload(dfmessages::HSIEvent &data)
std::atomic< metric_counter_type > m_latency_in
datahandlinglibs::SourceConcept inherited
std::shared_ptr< source_t > m_data_receiver
HSISourceModel()
SourceModel Constructor.
std::atomic< metric_counter_type > m_tcs_sent_count
std::atomic< metric_counter_type > m_tcs_dropped_count
void update_latency_out(uint64_t latency)
Definition Latency.hpp:46
latency get_latency_in() const
Definition Latency.hpp:49
latency get_latency_out() const
Definition Latency.hpp:52
void update_latency_in(uint64_t latency)
Definition Latency.hpp:43
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:116
#define TLOG(...)
Definition macro.hpp:21
TriggerCandidateData::Type string_to_trigger_candidate_type(const std::string &name)
dunedaq::trgdataformats::timestamp_t timestamp_t
Definition Types.hpp:16
A message used to convey an HSI event.
Definition HSIEvent.hpp:26
Struct holding configuration for one HSI signal bit.
triggeralgs::TriggerCandidate::Type type
triggeralgs::timestamp_t time_before
triggeralgs::timestamp_t time_after
std::vector< dunedaq::trgdataformats::TriggerActivityData > inputs