1use crate::prelude::*;
5use colored::Colorize;
6
7
8#[derive(Debug, Copy, Clone, PartialEq)]
9#[cfg_attr(feature="pybindings", pyclass)]
10pub struct EventBuilderHB {
11 pub met_seconds : u64,
13 pub n_mte_received_tot : u64,
15 pub n_rbe_received_tot : u64,
17 pub n_rbe_per_te : u64,
19 pub n_rbe_discarded_tot : u64,
21 pub n_mte_skipped : u64,
24 pub n_timed_out : u64,
28 pub n_sent : u64,
31 pub delta_mte_rbe : u64,
33 pub event_cache_size : u64,
35 pub event_id_cache_size : u64,
38 pub drs_bsy_lost_hg_hits : u64,
41 pub rbe_wo_mte : u64,
43 pub mte_receiver_cbc_len : u64,
46 pub rbe_receiver_cbc_len : u64,
49 pub tp_sender_cbc_len : u64,
52 pub n_rbe_from_past : u64,
55 pub n_rbe_orphan : u64,
56 pub n_rbe_per_loop : u64,
58 pub data_mangled_ev : u64,
60 pub timestamp : u64,
64}
65
66impl EventBuilderHB {
67 pub fn new() -> Self {
68 Self {
69 met_seconds : 0,
70 n_mte_received_tot : 0,
71 n_rbe_received_tot : 0,
72 n_rbe_per_te : 0,
73 n_rbe_discarded_tot : 0,
74 n_mte_skipped : 0,
75 n_timed_out : 0,
76 n_sent : 0,
77 delta_mte_rbe : 0,
78 event_cache_size : 0,
79 event_id_cache_size : 0,
80 drs_bsy_lost_hg_hits : 0,
81 rbe_wo_mte : 0,
82 mte_receiver_cbc_len : 0,
83 rbe_receiver_cbc_len : 0,
84 tp_sender_cbc_len : 0,
85 n_rbe_per_loop : 0,
86 n_rbe_orphan : 0,
87 n_rbe_from_past : 0,
88 data_mangled_ev : 0,
89 timestamp : 0,
91 }
92 }
93
94 pub fn get_average_rbe_te(&self) -> f64 {
98 if self.n_sent > 0 {
99 return self.n_rbe_per_te as f64 / self.n_sent as f64;
100 }
101 0.0
102 }
103
104 pub fn get_timed_out_frac(&self) -> f64 {
105 if self.n_sent > 0 {
106 return self.n_timed_out as f64 / self.n_sent as f64;
107 }
108 0.0
109 }
110
111 pub fn get_incoming_vs_outgoing_mte(&self) -> f64 {
116 if self.n_sent > 0 {
117 return self.n_mte_received_tot as f64 / self.n_sent as f64;
118 }
119 0.0
120 }
121
122 pub fn get_nrbe_discarded_frac(&self) -> f64 {
123 if self.n_rbe_received_tot > 0 {
124 return self.n_rbe_discarded_tot as f64 / self.n_rbe_received_tot as f64;
125 }
126 0.0
127 }
128
129 pub fn get_mangled_frac(&self) -> f64 {
130 if self.n_mte_received_tot > 0 {
131 return self.data_mangled_ev as f64 / self.n_mte_received_tot as f64;
132 }
133 0.0
134 }
135
136 pub fn get_drs_lost_frac(&self) -> f64 {
137 if self.n_rbe_received_tot > 0 {
138 return self.drs_bsy_lost_hg_hits as f64 / self.n_rbe_received_tot as f64;
139 }
140 0.0
141 }
142
143 pub fn pretty_print(&self) -> String {
144 let mut repr = String::from("");
145 repr += &(format!("\n \u{2B50} \u{2B50} \u{2B50} \u{2B50} \u{2B50} EVENTBUILDER HEARTBTEAT \u{2B50} \u{2B50} \u{2B50} \u{2B50} \u{2B50} "));
146 repr += &(format!("\n Mission elapsed time (MET) [s] : {}", self.met_seconds).bright_purple());
147 repr += &(format!("\n Num. events sent : {}", self.n_sent).bright_purple());
148 repr += &(format!("\n Size of event cache : {}", self.event_cache_size).bright_purple());
149 repr += &(format!("\n Num. events timed out : {}", self.n_timed_out).bright_purple());
151 repr += &(format!("\n Percent events timed out : {:.2}%", self.get_timed_out_frac()*(100 as f64)).bright_purple());
152 if self.n_mte_received_tot > 0{
158 repr += &(format!("\n \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504}"));
159 repr += &(format!("\n Num. evts with ANY data mangling : {}" , self.data_mangled_ev));
160 repr += &(format!("\n Per. evts with ANY data mangling : {:.2}%" , self.get_mangled_frac()*(100 as f64)));
161 }
162 else {repr += &(format!("\n Percent events with data mangling: unable to calculate"));}
163 repr += &(format!("\n \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504}"));
164 repr += &(format!("\n Received MTEvents : {}", self.n_mte_received_tot).bright_purple());
165 repr += &(format!("\n Skipped MTEvents : {}", self.n_mte_skipped).bright_purple());
166 repr += &(format!("\n Incoming/outgoing MTEvents fraction : {:.2}", self.get_incoming_vs_outgoing_mte()).bright_purple());
167 repr += &(format!("\n \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504}"));
168 repr += &(format!("\n Received RBEvents : {}", self.n_rbe_received_tot).bright_purple());
169 repr += &(format!("\n RBEvents Discarded : {}", self.n_rbe_discarded_tot).bright_purple());
170 repr += &(format!("\n Percent RBEvents discarded : {:.2}%", self.get_nrbe_discarded_frac()*(100 as f64)).bright_purple());
171 repr += &(format!("\n DRS4 busy lost hits : {}", self.drs_bsy_lost_hg_hits).bright_purple());
172 repr += &(format!("\n RDS4 busy lost hits fraction : {:.2}%", self.get_drs_lost_frac()*(100.0 as f64)).bright_purple());
173 repr += &(format!("\n \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504}"));
174 if self.n_sent > 0 && self.n_mte_received_tot > 0 {
175 repr += &(format!("\n RBEvent/Evts sent : {:.2}", (self.n_rbe_received_tot as f64/ self.n_sent as f64)).bright_purple());
176 repr += &(format!("\n RBEvent/MTEvents : {:.2}", (self.n_rbe_received_tot as f64 / self.n_mte_received_tot as f64)).bright_purple()); }
177 repr += &(format!("\n Current RBevents / iteration : {:.2}", self.n_rbe_per_loop).bright_purple());
178 repr += &(format!("\n Num. RBEvents with evid from past : {}", self.n_rbe_from_past).bright_purple());
179 repr += &(format!("\n Num. orphan RBEvents : {}", self.n_rbe_orphan).bright_purple());
180 repr += &(format!("\n\n Getting MTE from cache for RBEvent failed {} times :(", self.rbe_wo_mte).bright_blue());
181 repr += &(format!("\n \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504} \u{2504}"));
182 repr += &(format!("\n Ch. len MTE Receiver : {}", self.mte_receiver_cbc_len).bright_purple());
183 repr += &(format!("\n Ch. len RBE Reveiver : {}", self.rbe_receiver_cbc_len).bright_purple());
184 repr += &(format!("\n Ch. len TP Sender : {}", self.tp_sender_cbc_len).bright_purple());
185 repr += &(format!("\n \u{2B50} \u{2B50} \u{2B50} \u{2B50} \u{2B50} END EVENTBUILDER HEARTBTEAT \u{2B50} \u{2B50} \u{2B50} \u{2B50} \u{2B50}"));
186 repr
187 }
188}
189
190
191impl MoniData for EventBuilderHB {
192 fn get_board_id(&self) -> u8 {
193 0
194 }
195
196 fn get_timestamp(&self) -> u64 {
197 self.timestamp
198 }
199
200 fn set_timestamp(&mut self, ts : u64) {
201 self.timestamp = ts;
202 }
203
204 fn get(&self, varname : &str) -> Option<f32> {
206 match varname {
207 "board_id" => Some(0.0),
208 "met_seconds" => Some(self.met_seconds as f32),
209 "n_mte_received_tot" => Some(self.n_mte_received_tot as f32),
210 "n_rbe_received_tot" => Some(self.n_rbe_received_tot as f32),
211 "n_rbe_per_te" => Some(self.n_rbe_per_te as f32),
212 "n_rbe_discarded_tot" => Some(self.n_rbe_discarded_tot as f32),
213 "n_mte_skipped" => Some(self.n_mte_skipped as f32),
214 "n_timed_out" => Some(self.n_timed_out as f32),
215 "n_sent" => Some(self.n_sent as f32),
216 "delta_mte_rbe" => Some(self.delta_mte_rbe as f32),
217 "event_cache_size" => Some(self.event_cache_size as f32),
218 "event_id_cache_size" => Some(self.event_id_cache_size as f32),
219 "drs_bsy_lost_hg_hits" => Some(self.drs_bsy_lost_hg_hits as f32),
220 "rbe_wo_mte" => Some(self.rbe_wo_mte as f32),
221 "mte_receiver_cbc_len" => Some(self.mte_receiver_cbc_len as f32),
222 "rbe_receiver_cbc_len" => Some(self.rbe_receiver_cbc_len as f32),
223 "tp_sender_cbc_len" => Some(self.tp_sender_cbc_len as f32),
224 "n_rbe_per_loop" => Some(self.n_rbe_per_loop as f32),
225 "n_rbe_orphan" => Some(self.n_rbe_orphan as f32),
226 "n_rbe_from_past" => Some(self.n_rbe_from_past as f32),
227 "data_mangled_ev" => Some(self.data_mangled_ev as f32),
228 "timestamp" => Some(self.timestamp as f32),
229 _ => None
230 }
231 }
232
233 fn keys() -> Vec<&'static str> {
235 vec!["board_id", "met_seconds", "n_mte_received_tot",
236 "n_rbe_received_tot", "n_rbe_per_te", "n_rbe_discarded_tot",
237 "n_mte_skipped", "n_timed_out", "n_sent", "delta_mte_rbe",
238 "event_cache_size", "event_id_cache_size","drs_bsy_lost_hg_hits",
239 "rbe_wo_mte", "mte_receiver_cbc_len", "rbe_receiver_cbc_len",
240 "tp_sender_cbc_len", "n_rbe_per_loop", "n_rbe_orphan", "n_rbe_from_past",
241 "data_mangled_ev", "timestamp"]
242 }
243}
244
245moniseries!(EventBuilderHBSeries,EventBuilderHB);
246
247#[cfg(feature="pybindings")]
248#[pymethods]
249impl EventBuilderHB {
250 #[getter]
254 #[pyo3(name="average_rbe_te")]
255 fn get_average_rbe_te_py(&self) -> f64 {
256 self.get_average_rbe_te()
257 }
258
259 #[getter]
260 #[pyo3(name="timed_out_frac")]
261 pub fn get_timed_out_frac_py(&self) -> f64 {
262 self.get_timed_out_frac()
263 }
264
265 #[getter]
266 #[pyo3(name="incoming_vs_outgoing_mte")]
267 pub fn get_incoming_vs_outgoing_mte_py(&self) -> f64 {
268 self.get_incoming_vs_outgoing_mte()
269 }
270
271 #[getter]
272 #[pyo3(name="nrbe_discarded_frac")]
273 pub fn get_nrbe_discarded_frac_py(&self) -> f64 {
274 self.get_nrbe_discarded_frac()
275 }
276
277 #[getter]
278 #[pyo3(name="mangled_frac")]
279 pub fn get_mangled_frac_py(&self) -> f64 {
280 self.get_mangled_frac()
281 }
282
283 #[getter]
284 #[pyo3(name="drs_lost_frac")]
285 pub fn get_drs_lost_frac_py(&self) -> f64 {
286 self.get_drs_lost_frac()
287 }
288}
289
290#[cfg(feature="pybindings")]
291pythonize_monidata!(EventBuilderHB);
292#[cfg(feature="pybindings")]
293pythonize_packable!(EventBuilderHB);
294
295impl Default for EventBuilderHB {
298 fn default () -> Self {
299 Self::new()
300 }
301}
302
303impl TofPackable for EventBuilderHB {
304 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::EventBuilderHB;
305}
306
307impl Serialization for EventBuilderHB {
308 const HEAD : u16 = 0xAAAA;
309 const TAIL : u16 = 0x5555;
310 const SIZE : usize = 156; fn from_bytestream(stream : &Vec<u8>,
313 pos : &mut usize)
314 -> Result<Self, SerializationError>{
315 Self::verify_fixed(stream,pos)?;
316 let mut hb = EventBuilderHB::new();
317 hb.met_seconds = parse_u64(stream,pos);
318 hb.n_mte_received_tot = parse_u64(stream,pos);
319 hb.n_rbe_received_tot = parse_u64(stream,pos);
320 hb.n_rbe_per_te = parse_u64(stream,pos);
321 hb.n_rbe_discarded_tot = parse_u64(stream,pos);
322 hb.n_mte_skipped = parse_u64(stream,pos);
323 hb.n_timed_out = parse_u64(stream,pos);
324 hb.n_sent = parse_u64(stream,pos);
325 hb.delta_mte_rbe = parse_u64(stream,pos);
326 hb.event_cache_size = parse_u64(stream,pos);
327 hb.drs_bsy_lost_hg_hits = parse_u64(stream,pos);
329 hb.rbe_wo_mte = parse_u64(stream,pos);
330 hb.mte_receiver_cbc_len = parse_u64(stream,pos);
331 hb.rbe_receiver_cbc_len = parse_u64(stream,pos);
332 hb.tp_sender_cbc_len = parse_u64(stream,pos);
333 hb.n_rbe_per_loop = parse_u64(stream,pos);
334 hb.n_rbe_from_past = parse_u64(stream,pos);
335 hb.n_rbe_orphan = parse_u64(stream,pos);
336 hb.data_mangled_ev = parse_u64(stream,pos);
337 *pos += 2;
339 Ok(hb)
340 }
341
342 fn to_bytestream(&self) -> Vec<u8> {
343 let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
344 bs.extend_from_slice(&Self::HEAD.to_le_bytes());
345 bs.extend_from_slice(&self.met_seconds.to_le_bytes());
346 bs.extend_from_slice(&self.n_mte_received_tot.to_le_bytes());
347 bs.extend_from_slice(&self.n_rbe_received_tot.to_le_bytes());
348 bs.extend_from_slice(&self.n_rbe_per_te.to_le_bytes());
349 bs.extend_from_slice(&self.n_rbe_discarded_tot.to_le_bytes());
350 bs.extend_from_slice(&self.n_mte_skipped.to_le_bytes());
351 bs.extend_from_slice(&self.n_timed_out.to_le_bytes());
352 bs.extend_from_slice(&self.n_sent.to_le_bytes());
353 bs.extend_from_slice(&self.delta_mte_rbe.to_le_bytes());
354 bs.extend_from_slice(&self.event_cache_size.to_le_bytes());
355 bs.extend_from_slice(&self.drs_bsy_lost_hg_hits.to_le_bytes());
357 bs.extend_from_slice(&self.rbe_wo_mte.to_le_bytes());
358 bs.extend_from_slice(&self.mte_receiver_cbc_len.to_le_bytes());
359 bs.extend_from_slice(&self.rbe_receiver_cbc_len.to_le_bytes());
360 bs.extend_from_slice(&self.tp_sender_cbc_len.to_le_bytes());
361 bs.extend_from_slice(&self.n_rbe_per_loop.to_le_bytes());
362 bs.extend_from_slice(&self.n_rbe_from_past.to_le_bytes());
363 bs.extend_from_slice(&self.n_rbe_orphan.to_le_bytes());
364 bs.extend_from_slice(&self.data_mangled_ev.to_le_bytes());
365 bs.extend_from_slice(&Self::TAIL.to_le_bytes());
367 bs
368 }
369}
370
371#[cfg(feature="random")]
372impl FromRandom for EventBuilderHB {
373 fn from_random() -> Self {
374 let mut rng = rand::rng();
375 Self {
376 met_seconds : rng.random::<u64>(),
377 n_rbe_received_tot : rng.random::<u64>(),
378 n_rbe_per_te : rng.random::<u64>(),
379 n_rbe_discarded_tot : rng.random::<u64>(),
380 n_mte_skipped : rng.random::<u64>(),
381 n_timed_out : rng.random::<u64>(),
382 n_sent : rng.random::<u64>(),
383 delta_mte_rbe : rng.random::<u64>(),
384 event_cache_size : rng.random::<u64>(),
385 event_id_cache_size : 0,
388 drs_bsy_lost_hg_hits : rng.random::<u64>(),
389 rbe_wo_mte : rng.random::<u64>(),
390 mte_receiver_cbc_len : rng.random::<u64>(),
391 rbe_receiver_cbc_len : rng.random::<u64>(),
392 tp_sender_cbc_len : rng.random::<u64>(),
393 n_mte_received_tot : rng.random::<u64>(),
394 n_rbe_per_loop : rng.random::<u64>(),
395 n_rbe_from_past : rng.random::<u64>(),
396 n_rbe_orphan : rng.random::<u64>(),
397 data_mangled_ev : rng.random::<u64>(),
398 timestamp : 0
399 }
400 }
401}
402
403impl fmt::Display for EventBuilderHB {
404 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
405 let mut repr = String::from("<EVTBLDRHearbeat: ");
406 repr += &self.pretty_print();
407 write!(f, "{}>", repr)
408 }
409}
410
411#[cfg(feature="random")]
412#[test]
413fn pack_eventbuilderhb() {
414 for _ in 0..100 {
415 let hb = EventBuilderHB::from_random();
416 let test : EventBuilderHB = hb.pack().unpack().unwrap();
417 assert_eq!(hb, test);
418 }
419}
420