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
11#include <functional>
16#include "trigger/Issues.hpp"
17#include "trigger/Latency.hpp"
20
22#include "iomanager/Sender.hpp"
24#include "logging/Logging.hpp"
30
31namespace dunedaq::trigger {
32
43
45{
46public:
48
53 HSISourceModel(): datahandlinglibs::SourceConcept() {}
54 ~HSISourceModel() override
55 {
56 m_data_receiver.reset();
57 m_data_sender.reset();
58 m_signals.clear();
59 }
60
61 void init(const confmodel::DaqModule* cfg) override
62 {
63 if (cfg->get_outputs().size() != 1) {
64 throw datahandlinglibs::InitializationError(ERS_HERE, "Only 1 output supported for subscribers");
65 }
67
68 if (cfg->get_inputs().size() != 1) {
69 throw datahandlinglibs::InitializationError(ERS_HERE, "Only 1 input supported for subscribers");
70 }
72 auto data_reader = cfg->cast<appmodel::DataSubscriberModule>();
73 if (data_reader == nullptr) {
74 throw datahandlinglibs::InitializationError(ERS_HERE, "DAQ module is not a DataReader");
75 }
76 auto hsi_conf = data_reader->get_configuration()->cast<appmodel::HSI2TCTranslatorConf>();
77 if (hsi_conf == nullptr) {
78 throw datahandlinglibs::InitializationError(ERS_HERE, "Missing HSI2TCTranslatorConf");
79 }
80
81 // Get the HSI-signal to TC-output map
82 for (auto win : hsi_conf->get_signals()) {
84 tc_type = static_cast<triggeralgs::TriggerCandidate::Type>(
86
87 // Throw error if unknown TC type
89 throw datahandlinglibs::InitializationError(ERS_HERE, "Provided an unknown TC type output to HSISourceModel");
90 }
91
92 // Throw error if already exists
93 uint32_t signal = win->get_signal_type();
94 if (m_signals.count(signal)) {
95 throw datahandlinglibs::InitializationError(ERS_HERE, "Provided more than one of the same HSI signal ID input to HSISourceModel");
96 }
97
98 // Fill the signal-tctype map
99 m_signals[signal] = { tc_type,
100 win->get_time_before(),
101 win->get_time_after() };
102
103 TLOG() << "Will cover HSI signal id: " << signal << " to TC type: " << win->get_tc_type_name()
104 << " window before: " << win->get_time_before() << " window after: " << win->get_time_after();
105 }
106
107 m_prescale = hsi_conf->get_prescale();
108 m_latency_monitoring.store( hsi_conf->get_latency_monitoring() );
109
110 }
111
112 void start() {
113 m_data_receiver->add_callback(std::bind(&HSISourceModel::handle_payload, this, std::placeholders::_1));
114
115 m_running_flag.store(true);
116
118 m_tcs_made_count.store(0);
119 m_tcs_sent_count.store(0);
120 m_tcs_dropped_count.store(0);
121 }
122
123 void stop() {
124 m_data_receiver->remove_callback();
125 m_running_flag.store(false);
127 }
128
129 bool handle_payload(dfmessages::HSIEvent& data) // NOLINT(build/unsigned)
130 {
132 if (m_latency_monitoring.load()) m_latency_instance.update_latency_in( data.timestamp );
133
134 // Prescale after n-hsi received
136 return true;
137 }
138
139 TLOG_DEBUG(1) << "Received HSIEvent with signal map " << data.signal_map << " and timestamp " << data.timestamp;
140
141 // Iterate over all the signals
142 uint32_t signal_map = data.signal_map;
143 while (signal_map) {
144 // Get the index of the least significant bit
145 int bit_index = __builtin_ctzll(signal_map);
146 uint32_t signal = 1 << bit_index;
147
148 // Throw an error if we don't have this signal bit configured
149 if (!m_signals.count(signal)) {
150 throw dunedaq::trigger::SignalTypeError(ERS_HERE, "HSI subscriber" , data.signal_map);
151 }
152
153 // Create the trigger candidate
155 candidate.time_start = data.timestamp - m_signals[signal].time_before;
156 candidate.time_end = data.timestamp + m_signals[signal].time_after;
157 candidate.time_candidate = data.timestamp;
158 // throw away bits 31-16 of header, that's OK for now
159 candidate.detid = (uint)detdataformats::DetID::Subdetector::kDAQ ; // NOLINT(build/unsigned)
160 candidate.type = m_signals[signal].type;
162 candidate.inputs = {};
164
166 // Send the TC
167 if (!m_data_sender->try_send(std::move(candidate), iomanager::Sender::s_no_block)) {
169 }
170 else {
172 }
173
174 // Clear the least significant bit
175 signal_map &= signal_map - 1;
176 }
177
178 return true;
179 }
180
181 void generate_opmon_data() override
182 {
184
185 info.set_received_events_count( m_received_events_count );
186 info.set_tcs_made_count( m_tcs_made_count );
187 info.set_tcs_sent_count( m_tcs_sent_count );
188 info.set_tcs_dropped_count( m_tcs_dropped_count );
189
190 this->publish(std::move(info));
191
192 if ( m_latency_monitoring.load() && m_running_flag.load() ) {
193 opmon::TriggerLatency lat_info;
194
197
198 this->publish(std::move(lat_info));
199 }
200 }
201
203 {
204 TLOG() << "HSI Source Model opmon counters summary:";
205 TLOG() << "------------------------------";
206 TLOG() << "Signals received: \t" << m_received_events_count;
207 TLOG() << "TCs made: \t\t" << m_tcs_made_count;
208 TLOG() << "TCs sent: \t\t" << m_tcs_sent_count;
209 TLOG() << "TCs dropped: \t\t" << m_tcs_dropped_count;
210 TLOG();
211 }
212
213private:
215 std::shared_ptr<source_t> m_data_receiver;
216
218 std::shared_ptr<sink_t> m_data_sender;
219
221 std::map<uint32_t, HSISignal> m_signals;
222
223 //Stats
224 using metric_counter_type = uint64_t;
225 std::atomic<metric_counter_type> m_received_events_count{0};
226 std::atomic<metric_counter_type> m_tcs_made_count{0};
227 std::atomic<metric_counter_type> m_tcs_sent_count{0};
228 std::atomic<metric_counter_type> m_tcs_dropped_count{0};
229
231 uint64_t m_prescale;
232
233 // Create an instance of the Latency class
234 std::atomic<bool> m_running_flag{ false };
235 std::atomic<bool> m_latency_monitoring{ false };
237 std::atomic<metric_counter_type> m_latency_in{ 0 };
238 std::atomic<metric_counter_type> m_latency_out{ 0 };
239};
240
241} // namespace dunedaq::trigger
242
243#endif // TRIGGER_PLUGINS_HSISOURCEMODEL_HPP_
#define ERS_HERE
const dunedaq::appmodel::DataReaderConf * get_configuration() const
Get "configuration" relationship value.
uint32_t get_prescale() const
Get "prescale" attribute value. Prescale factor to apply to HSIEvent input.
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
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
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:43
latency get_latency_in() const
Definition Latency.hpp:48
latency get_latency_out() const
Definition Latency.hpp:53
void update_latency_in(uint64_t latency)
Definition Latency.hpp:38
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
#define TLOG(...)
Definition macro.hpp:22
int string_to_trigger_candidate_type(const std::string &name)
static std::shared_ptr< iomanager::SenderConcept< Datatype > > get_iom_sender(iomanager::ConnectionId const &id)
static std::shared_ptr< iomanager::ReceiverConcept< Datatype > > get_iom_receiver(iomanager::ConnectionId const &id)
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