1use std::collections::HashMap;
9
10use pyo3::prelude::*;
11use pyo3::exceptions::PyValueError;
12
13use comfy_table::modifiers::UTF8_ROUND_CORNERS;
16use comfy_table::presets::UTF8_FULL;
17use comfy_table::*;
18
19use tof_dataclasses::ipbus::IPBus;
20use tof_dataclasses::events::MasterTriggerEvent;
21
22use liftof_lib::master_trigger::registers::*;
23use liftof_lib::master_trigger as mt_api;
24
25use crate::PyMasterTriggerEvent;
26
27#[pyfunction]
28#[pyo3(name="prescale_to_u32")]
29pub fn wrap_prescale_to_u32(prescale : f32) -> u32 {
33 let mut _prescale = prescale;
34 prescale_to_u32(prescale)
35}
36
37#[pyclass]
38#[pyo3(name = "MasterTrigger")]
39pub struct PyMasterTrigger {
40 ipbus : IPBus,
41}
42
43#[pymethods]
44impl PyMasterTrigger {
45 #[new]
46 fn new(target_address : &str) -> Self {
47 let ipbus = IPBus::new(target_address).expect("Unable to connect to {target_address}");
48 Self {
49 ipbus : ipbus,
50 }
51 }
52
53 fn reset_daq(&mut self) -> PyResult<()>{
54 match self.ipbus.write(0x10,1) {
55 Ok(result) => {
56 return Ok(result);
57 }
58 Err(err) => {
59 return Err(PyValueError::new_err(err.to_string()));
60 }
61 }
62 }
63
64 fn get_expected_pid(&mut self) -> PyResult<u16> {
65 match self.ipbus.get_target_next_expected_packet_id(){
66 Ok(result) => {
67 return Ok(result);
68 }
69 Err(err) => {
70 return Err(PyValueError::new_err(err.to_string()));
71 }
72 }
73 }
74
75 fn realign_packet_id(&mut self) -> PyResult<()> {
76 match self.ipbus.realign_packet_id() {
77 Ok(_) => {
78 return Ok(());
79 }
80 Err(err) => {
81 return Err(PyValueError::new_err(err.to_string()));
82 }
83 }
84 }
85
86 fn set_packet_id(&mut self, pid : u16) {
87 self.ipbus.pid = pid;
88 }
89
90 fn get_packet_id(&mut self) -> u16 {
91 self.ipbus.pid
92 }
93
94 #[getter]
95 fn rate(&mut self) -> PyResult<u32> {
97 match TRIGGER_RATE.get(&mut self.ipbus) {
98 Ok(rate) => {
99 return Ok(rate);
100 }
101 Err(err) => {
102 return Err(PyValueError::new_err(err.to_string()));
103 }
104 }
105 }
106
107 #[getter]
108 fn lost_rate(&mut self) -> PyResult<u32> {
114 match LOST_TRIGGER_RATE.get(&mut self.ipbus) {
115 Ok(rate) => {
116 return Ok(rate);
117 }
118 Err(err) => {
119 return Err(PyValueError::new_err(err.to_string()));
120 }
121 }
122 }
123
124 #[getter]
125 fn rb_lost_rate(&mut self) -> PyResult<u32> {
127 match RB_LOST_TRIGGER_RATE.get(&mut self.ipbus) {
128 Ok(rate) => {
129 return Ok(rate);
130 }
131 Err(err) => {
132 return Err(PyValueError::new_err(err.to_string()));
133 }
134 }
135 }
136
137 #[getter]
139 fn tiu_lost_rate(&mut self) -> PyResult<u32> {
140 match TIU_LOST_TRIGGER_RATE.get(&mut self.ipbus) {
141 Ok(rate) => {
142 return Ok(rate);
143 }
144 Err(err) => {
145 return Err(PyValueError::new_err(err.to_string()));
146 }
147 }
148 }
149
150 #[getter]
151 fn get_tiu_emulation_mode(&mut self) -> PyResult<u32> {
154 match TIU_EMULATION_MODE.get(&mut self.ipbus) {
155 Ok(mode) => {
156 return Ok(mode);
157 }
158 Err(err) => {
159 return Err(PyValueError::new_err(err.to_string()));
160 }
161 }
162 }
163
164 #[setter]
165 fn set_tiu_emulation_mode(&mut self, value : u32) -> PyResult<()> {
166 match TIU_EMULATION_MODE.set(&mut self.ipbus, value) {
167 Ok(_) => {
168 return Ok(());
169 }
170 Err(err) => {
171 return Err(PyValueError::new_err(err.to_string()));
172 }
173 }
174 }
175
176 #[setter]
177 fn set_tiu_emulation_mode_bsy_cnt(&mut self, cycles : u32) -> PyResult<()> {
178 match TIU_EMU_BUSY_CNT.set(&mut self.ipbus, cycles) {
179 Ok(_) => {
180 return Ok(());
181 }
182 Err(err) => {
183 return Err(PyValueError::new_err(err.to_string()));
184 }
185 }
186 }
187
188 #[getter]
189 fn get_tiu_emulation_mode_bsy_cnt(&mut self) -> PyResult<u32> {
190 match TIU_EMU_BUSY_CNT.get(&mut self.ipbus) {
191 Ok(value) => {
192 return Ok(value);
193 }
194 Err(err) => {
195 return Err(PyValueError::new_err(err.to_string()));
196 }
197 }
198 }
199
200 fn get_enable_cyclic_trig(&mut self) -> PyResult<bool> {
201 match TRIG_CYCLIC_EN.get(&mut self.ipbus) {
202 Ok(value) => {
203 return Ok(value > 0);
204 }
205 Err(err) => {
206 return Err(PyValueError::new_err(err.to_string()));
207 }
208 }
209 }
210
211 fn disable_cyclic_trig(&mut self) -> PyResult<()> {
212 match TRIG_CYCLIC_EN.set(&mut self.ipbus, 0x0) {
213 Ok(_) => {
214 return Ok(());
215 }
216 Err(err) => {
217 return Err(PyValueError::new_err(err.to_string()));
218 }
219 }
220 }
221
222 fn enable_cyclic_trig(&mut self) -> PyResult<()> {
223 match TRIG_CYCLIC_EN.set(&mut self.ipbus, 0x1) {
224 Ok(_) => {
225 return Ok(());
226 }
227 Err(err) => {
228 return Err(PyValueError::new_err(err.to_string()));
229 }
230 }
231 }
232
233 fn get_cyclic_trigger_interval(&mut self) -> PyResult<u32> {
234 match TRIG_CYCLIC_INTERVAL.get(&mut self.ipbus) {
235 Ok(interval) => {
236 return Ok(interval);
237 }
238 Err(err) => {
239 return Err(PyValueError::new_err(err.to_string()));
240 }
241 }
242 }
243
244 fn set_cyclic_trigger_interval(&mut self, interval : u32) -> PyResult<()> {
245 match TRIG_CYCLIC_INTERVAL.set(&mut self.ipbus, interval) {
246 Ok(_) => {
247 return Ok(());
248 }
249 Err(err) => {
250 return Err(PyValueError::new_err(err.to_string()));
251 }
252 }
253 }
254
255 fn trigger(&mut self) -> PyResult<()> {
257 match FORCE_TRIGGER.set(&mut self.ipbus, 1) {
258 Ok(_) => {
259 return Ok(());
260 }
261 Err(err) => {
262 return Err(PyValueError::new_err(err.to_string()));
263 }
264 }
265 }
266
267 fn set_poisson_trigger(&mut self, rate : u32) -> PyResult<()> {
268 let clk_period = 100000000;
269 let rate_val = (u32::MAX*rate)/clk_period;match TRIG_GEN_RATE.set(&mut self.ipbus, rate_val) {
271 Ok(_) => {
272 return Ok(());
273 }
274 Err(err) => {
275 return Err(PyValueError::new_err(err.to_string()));
276 }
277 }
278 }
279
280 fn set_gaps_track_trigger(&mut self, prescale : f32, use_beta : bool) -> PyResult<()> {
281 match mt_api::control::set_gaps_track_trigger(&mut self.ipbus, prescale, use_beta) {
282 Ok(_) => {
283 return Ok(());
284 }
285 Err(err) => {
286 return Err(PyValueError::new_err(err.to_string()));
287 }
288 }
289 }
290
291 fn set_gaps_any_trigger(&mut self, prescale : f32, use_beta : bool) -> PyResult<()> {
292 match mt_api::control::set_gaps_any_trigger(&mut self.ipbus, prescale, use_beta) {
293 Ok(_) => {
294 return Ok(());
295 }
296 Err(err) => {
297 return Err(PyValueError::new_err(err.to_string()));
298 }
299 }
300 }
301
302 fn set_gaps_central_track_trigger(&mut self, prescale : f32, use_beta : bool) -> PyResult<()> {
303 match mt_api::control::set_gaps_central_track_trigger(&mut self.ipbus, prescale, use_beta) {
304 Ok(_) => {
305 return Ok(());
306 }
307 Err(err) => {
308 return Err(PyValueError::new_err(err.to_string()));
309 }
310 }
311 }
312
313 fn set_gaps422_central_track_trigger(&mut self, prescale : f32, use_beta : bool) -> PyResult<()> {
314 match mt_api::control::set_gaps422_central_track_trigger(&mut self.ipbus, prescale, use_beta) {
315 Ok(_) => {
316 return Ok(());
317 }
318 Err(err) => {
319 return Err(PyValueError::new_err(err.to_string()));
320 }
321 }
322 }
323
324 fn get_lt_link_en0(&mut self) -> PyResult<u32> {
326 match LT_LINK_EN0.get(&mut self.ipbus) {
327 Ok(value) => {
328 return Ok(value);
329 }
330 Err(err) => {
331 return Err(PyValueError::new_err(err.to_string()));
332 }
333 }
334 }
335 fn get_lt_link_en1(&mut self) -> PyResult<u32> {
337 match LT_LINK_EN1.get(&mut self.ipbus) {
338 Ok(value) => {
339 return Ok(value);
340 }
341 Err(err) => {
342 return Err(PyValueError::new_err(err.to_string()));
343 }
344 }
345 }
346 fn get_lt_link_en02(&mut self) -> PyResult<u32> {
348 match LT_LINK_EN2.get(&mut self.ipbus) {
349 Ok(value) => {
350 return Ok(value);
351 }
352 Err(err) => {
353 return Err(PyValueError::new_err(err.to_string()));
354 }
355 }
356 }
357 fn get_lt_link_en3(&mut self) -> PyResult<u32> {
359 match LT_LINK_EN3.get(&mut self.ipbus) {
360 Ok(value) => {
361 return Ok(value);
362 }
363 Err(err) => {
364 return Err(PyValueError::new_err(err.to_string()));
365 }
366 }
367 }
368 fn get_lt_link_en4(&mut self) -> PyResult<u32> {
370 match LT_LINK_EN4.get(&mut self.ipbus) {
371 Ok(value) => {
372 return Ok(value);
373 }
374 Err(err) => {
375 return Err(PyValueError::new_err(err.to_string()));
376 }
377 }
378 }
379 fn set_lt_link_en0(&mut self, value : u32) -> PyResult<u32> {
381 match LT_LINK_EN0.set(&mut self.ipbus, value) {
382 Ok(_) => {
383 return Ok(value);
384 }
385 Err(err) => {
386 return Err(PyValueError::new_err(err.to_string()));
387 }
388 }
389 }
390 fn set_lt_link_en1(&mut self, value : u32) -> PyResult<u32> {
392 match LT_LINK_EN1.set(&mut self.ipbus, value) {
393 Ok(_) => {
394 return Ok(value);
395 }
396 Err(err) => {
397 return Err(PyValueError::new_err(err.to_string()));
398 }
399 }
400 }
401 fn set_lt_link_en2(&mut self, value : u32) -> PyResult<u32> {
403 match LT_LINK_EN2.set(&mut self.ipbus, value) {
404 Ok(_) => {
405 return Ok(value);
406 }
407 Err(err) => {
408 return Err(PyValueError::new_err(err.to_string()));
409 }
410 }
411 }
412 fn set_lt_link_en3(&mut self, value : u32) -> PyResult<u32> {
414 match LT_LINK_EN3.set(&mut self.ipbus, value) {
415 Ok(_) => {
416 return Ok(value);
417 }
418 Err(err) => {
419 return Err(PyValueError::new_err(err.to_string()));
420 }
421 }
422 }
423 fn set_lt_link_en4(&mut self, value : u32) -> PyResult<u32> {
425 match LT_LINK_EN4.set(&mut self.ipbus, value) {
426 Ok(_) => {
427 return Ok(value);
428 }
429 Err(err) => {
430 return Err(PyValueError::new_err(err.to_string()));
431 }
432 }
433 }
434 fn get_lt_link_automask(&mut self) -> PyResult<bool> {
436 match LT_LINK_AUTOMASK.get(&mut self.ipbus) {
437 Ok(value) => {
438 return Ok(value != 0);
439 }
440 Err(err) => {
441 return Err(PyValueError::new_err(err.to_string()));
442 }
443 }
444 }
445 fn set_lt_link_automask(&mut self, toggle : bool) -> PyResult<bool> {
447 match LT_LINK_AUTOMASK.set(&mut self.ipbus, toggle as u32) {
448 Ok(_) => {
449 return Ok(true);
450 }
451 Err(err) => {
452 return Err(PyValueError::new_err(err.to_string()));
453 }
454 }
455 }
456fn get_gaps_trigger_prescale(&mut self) -> PyResult<f32> {
457 match GAPS_TRIG_PRESCALE.get(&mut self.ipbus) {
458 Ok (prescale_bus) => {
459 let prescale_val = (u32::MAX as f32 * prescale_bus as f32).floor() as f32;
460 return Ok(prescale_val)
461 }
462 Err(err) => {
463 return Err(PyValueError::new_err(err.to_string()));
464 }
465 }
466}
467
468fn set_gaps_trigger_prescale(&mut self, prescale : f32) -> PyResult<f32> {
469 let prescale_val = (f32::MAX * prescale as f32).floor() as u32;
470 match GAPS_TRIG_PRESCALE.set(&mut self.ipbus, prescale_val) {
471 Ok(_) => {
472 return Ok(prescale)
473 }
474 Err(err) => {
475 return Err(PyValueError::new_err(err.to_string()));
476 }
477 }
478}
479
480fn set_track_trigger_is_global(&mut self) -> PyResult<()> {
481 match TRACK_CENTRAL_IS_GLOBAL.set(&mut self.ipbus, 1) {
482 Ok(_) => {
483 return Ok(());
484 }
485 Err(err) => {
486 return Err(PyValueError::new_err(err.to_string()));
487 }
488 }
489 }
490
491
492 fn get_ltb_links_ready(&mut self) -> PyResult<HashMap<u8, u32>> {
493 let registers = [LT_LINK_READY0, LT_LINK_READY1,
494 LT_LINK_READY2, LT_LINK_READY3,
495 LT_LINK_READY4];
496 let mut ready = HashMap::<u8, u32>::new();
497 for (k,reg) in registers.iter().enumerate() {
498 match reg.get(&mut self.ipbus) {
499 Err(err) => {
500 return Err(PyValueError::new_err(err.to_string()));
501 }
502 Ok(cnt) => {
503 ready.insert(k as u8, cnt);
504 }
505 }
506 }
507 Ok(ready)
508 }
509
510 fn get_ltb_event_cnts(&mut self) -> PyResult<HashMap<u8, u32>> {
511 let registers = [LT0, LT1, LT2, LT3, LT4, LT5, LT6, LT7, LT8, LT9,
512 LT10, LT11, LT12, LT13, LT14, LT15, LT16, LT17, LT18, LT19,
513 LT20, LT21, LT22, LT23, LT24];
514 let mut counters = HashMap::<u8, u32>::new();
515 for (k,reg) in registers.iter().enumerate() {
516 match reg.get(&mut self.ipbus) {
517 Err(err) => {
518 return Err(PyValueError::new_err(err.to_string()));
519 }
520 Ok(cnt) => {
521 counters.insert(k as u8, cnt);
522 }
523 }
524 }
525 let mut table = Table::new();
527 table
528 .load_preset(UTF8_FULL)
529 .apply_modifier(UTF8_ROUND_CORNERS)
530 .set_content_arrangement(ContentArrangement::Dynamic)
531 .set_width(80)
532 .set_header(vec!["LT 0", "LT 1", "LT 2", "LT 3", "LT 4"])
533 .add_row(vec![
534 Cell::new(&(format!("{}", counters[&0]))),
535 Cell::new(&(format!("{}", counters[&1]))),
536 Cell::new(&(format!("{}", counters[&2]))),
537 Cell::new(&(format!("{}", counters[&3]))),
538 Cell::new(&(format!("{}", counters[&4]))),
539 ])
541 .add_row(vec![
542 Cell::new(String::from("LT 5")),
543 Cell::new(String::from("LT 6")),
544 Cell::new(String::from("LT 7")),
545 Cell::new(String::from("LT 8")),
546 Cell::new(String::from("LT 9")),
547 ])
548 .add_row(vec![
549 Cell::new(&(format!("{}", counters[&5]))),
550 Cell::new(&(format!("{}", counters[&6]))),
551 Cell::new(&(format!("{}", counters[&7]))),
552 Cell::new(&(format!("{}", counters[&8]))),
553 Cell::new(&(format!("{}", counters[&9]))),
554 ])
555 .add_row(vec![
556 Cell::new(String::from("LT 10")),
557 Cell::new(String::from("LT 11")),
558 Cell::new(String::from("LT 12")),
559 Cell::new(String::from("LT 13")),
560 Cell::new(String::from("LT 14")),
561 ])
562 .add_row(vec![
563 Cell::new(&(format!("{}", counters[&10]))),
564 Cell::new(&(format!("{}", counters[&11]))),
565 Cell::new(&(format!("{}", counters[&12]))),
566 Cell::new(&(format!("{}", counters[&13]))),
567 Cell::new(&(format!("{}", counters[&14]))),
568 ])
569 .add_row(vec![
570 Cell::new(String::from("LT 15")),
571 Cell::new(String::from("LT 16")),
572 Cell::new(String::from("LT 17")),
573 Cell::new(String::from("LT 18")),
574 Cell::new(String::from("LT 19")),
575 ])
576 .add_row(vec![
577 Cell::new(&(format!("{}", counters[&15]))),
578 Cell::new(&(format!("{}", counters[&16]))),
579 Cell::new(&(format!("{}", counters[&17]))),
580 Cell::new(&(format!("{}", counters[&18]))),
581 Cell::new(&(format!("{}", counters[&19]))),
582 ])
583 .add_row(vec![
584 Cell::new(String::from("LT 20")),
585 Cell::new(String::from("LT 21")),
586 Cell::new(String::from("LT 22")),
587 Cell::new(String::from("LT 23")),
588 Cell::new(String::from("LT 24")),
589 ])
590 .add_row(vec![
591 Cell::new(&(format!("{}", counters[&20]))),
592 Cell::new(&(format!("{}", counters[&21]))),
593 Cell::new(&(format!("{}", counters[&22]))),
594 Cell::new(&(format!("{}", counters[&23]))),
595 Cell::new(&(format!("{}", counters[&24]))),
596 ]);
597
598 let column = table.column_mut(2).expect("Our table has three columns");
600 column.set_cell_alignment(CellAlignment::Right);
601 println!("{table}");
602 Ok(counters)
603 }
604
605 fn get_rb_event_cnts(&mut self) -> PyResult<HashMap<u8, u8>> {
607 let registers = [RB0_CNTS, RB1_CNTS, RB2_CNTS, RB3_CNTS, RB4_CNTS,
608 RB5_CNTS, RB6_CNTS, RB7_CNTS, RB8_CNTS, RB9_CNTS,
609 RB10_CNTS, RB11_CNTS, RB12_CNTS, RB13_CNTS, RB14_CNTS,
610 RB15_CNTS, RB16_CNTS, RB17_CNTS, RB18_CNTS, RB19_CNTS,
611 RB20_CNTS, RB21_CNTS, RB22_CNTS, RB23_CNTS, RB24_CNTS,
612 RB25_CNTS, RB26_CNTS, RB27_CNTS, RB28_CNTS, RB29_CNTS,
613 RB30_CNTS, RB31_CNTS, RB32_CNTS, RB33_CNTS, RB34_CNTS,
614 RB35_CNTS, RB36_CNTS, RB37_CNTS, RB38_CNTS, RB39_CNTS,
615 RB40_CNTS, RB41_CNTS, RB42_CNTS, RB43_CNTS, RB44_CNTS,
616 RB45_CNTS, RB46_CNTS, RB47_CNTS, RB48_CNTS, RB49_CNTS];
617 let mut counters = HashMap::<u8, u8>::new();
618 for (k,reg) in registers.iter().enumerate() {
619 match reg.get(&mut self.ipbus) {
620 Err(err) => {
621 return Err(PyValueError::new_err(err.to_string()));
622 }
623 Ok(cnt) => {
624 counters.insert(k as u8, cnt as u8);
625 }
626 }
627 }
628 let mut table = Table::new();
629 table
630 .load_preset(UTF8_FULL)
631 .apply_modifier(UTF8_ROUND_CORNERS)
632 .set_content_arrangement(ContentArrangement::Dynamic)
633 .set_width(60)
634 .set_header(vec!["RB 0", "RB 1", "RB 2", "RB 3", "RB 4"])
635 .add_row(vec![
636 Cell::new(&(format!("{}", counters[&0]))),
637 Cell::new(&(format!("{}", counters[&1]))),
638 Cell::new(&(format!("{}", counters[&2]))),
639 Cell::new(&(format!("{}", counters[&3]))),
640 Cell::new(&(format!("{}", counters[&4]))),
641 ])
643 .add_row(vec![
644 Cell::new(String::from("RB 5")),
645 Cell::new(String::from("RB 6")),
646 Cell::new(String::from("RB 7")),
647 Cell::new(String::from("RB 8")),
648 Cell::new(String::from("RB 9")),
649 ])
650 .add_row(vec![
651 Cell::new(&(format!("{}", counters[&5]))),
652 Cell::new(&(format!("{}", counters[&6]))),
653 Cell::new(&(format!("{}", counters[&7]))),
654 Cell::new(&(format!("{}", counters[&8]))),
655 Cell::new(&(format!("{}", counters[&9]))),
656 ])
657 .add_row(vec![
658 Cell::new(String::from("RB 10")),
659 Cell::new(String::from("RB 11")),
660 Cell::new(String::from("RB 12")),
661 Cell::new(String::from("RB 13")),
662 Cell::new(String::from("RB 14")),
663 ])
664 .add_row(vec![
665 Cell::new(&(format!("{}", counters[&10]))),
666 Cell::new(&(format!("{}", counters[&11]))),
667 Cell::new(&(format!("{}", counters[&12]))),
668 Cell::new(&(format!("{}", counters[&13]))),
669 Cell::new(&(format!("{}", counters[&14]))),
670 ])
671 .add_row(vec![
672 Cell::new(String::from("RB 15")),
673 Cell::new(String::from("RB 16")),
674 Cell::new(String::from("RB 17")),
675 Cell::new(String::from("RB 18")),
676 Cell::new(String::from("RB 19")),
677 ])
678 .add_row(vec![
679 Cell::new(&(format!("{}", counters[&15]))),
680 Cell::new(&(format!("{}", counters[&16]))),
681 Cell::new(&(format!("{}", counters[&17]))),
682 Cell::new(&(format!("{}", counters[&18]))),
683 Cell::new(&(format!("{}", counters[&19]))),
684 ])
685 .add_row(vec![
686 Cell::new(String::from("RB 20")),
687 Cell::new(String::from("RB 21")),
688 Cell::new(String::from("RB 22")),
689 Cell::new(String::from("RB 23")),
690 Cell::new(String::from("RB 24")),
691 ])
692 .add_row(vec![
693 Cell::new(&(format!("{}", counters[&20]))),
694 Cell::new(&(format!("{}", counters[&21]))),
695 Cell::new(&(format!("{}", counters[&22]))),
696 Cell::new(&(format!("{}", counters[&23]))),
697 Cell::new(&(format!("{}", counters[&24]))),
698 ])
699 .add_row(vec![
700 Cell::new(String::from("RB 25")),
701 Cell::new(String::from("RB 26")),
702 Cell::new(String::from("RB 27")),
703 Cell::new(String::from("RB 28")),
704 Cell::new(String::from("RB 29")),
705 ])
706 .add_row(vec![
707 Cell::new(&(format!("{}", counters[&25]))),
708 Cell::new(&(format!("{}", counters[&26]))),
709 Cell::new(&(format!("{}", counters[&27]))),
710 Cell::new(&(format!("{}", counters[&28]))),
711 Cell::new(&(format!("{}", counters[&29]))),
712 ])
713 .add_row(vec![
714 Cell::new(String::from("RB 30")),
715 Cell::new(String::from("RB 31")),
716 Cell::new(String::from("RB 32")),
717 Cell::new(String::from("RB 33")),
718 Cell::new(String::from("RB 34")),
719 ])
720 .add_row(vec![
721 Cell::new(&(format!("{}", counters[&30]))),
722 Cell::new(&(format!("{}", counters[&31]))),
723 Cell::new(&(format!("{}", counters[&32]))),
724 Cell::new(&(format!("{}", counters[&33]))),
725 Cell::new(&(format!("{}", counters[&34]))),
726 ])
727 .add_row(vec![
728 Cell::new(String::from("RB 35")),
729 Cell::new(String::from("RB 36")),
730 Cell::new(String::from("RB 37")),
731 Cell::new(String::from("RB 38")),
732 Cell::new(String::from("RB 39")),
733 ])
734 .add_row(vec![
735 Cell::new(&(format!("{}", counters[&35]))),
736 Cell::new(&(format!("{}", counters[&36]))),
737 Cell::new(&(format!("{}", counters[&37]))),
738 Cell::new(&(format!("{}", counters[&38]))),
739 Cell::new(&(format!("{}", counters[&39]))),
740 ])
741 .add_row(vec![
742 Cell::new(String::from("RB 40")),
743 Cell::new(String::from("RB 41")),
744 Cell::new(String::from("RB 42")),
745 Cell::new(String::from("RB 43")),
746 Cell::new(String::from("RB 44")),
747 ])
748 .add_row(vec![
749 Cell::new(&(format!("{}", counters[&40]))),
750 Cell::new(&(format!("{}", counters[&41]))),
751 Cell::new(&(format!("{}", counters[&42]))),
752 Cell::new(&(format!("{}", counters[&43]))),
753 Cell::new(&(format!("{}", counters[&44]))),
754 ])
755 .add_row(vec![
756 Cell::new(String::from("RB 45")),
757 Cell::new(String::from("RB 46")),
758 Cell::new(String::from("RB 47")),
759 Cell::new(String::from("RB 48")),
760 Cell::new(String::from("RB 49")),
761 ])
762 .add_row(vec![
763 Cell::new(&(format!("{}", counters[&45]))),
764 Cell::new(&(format!("{}", counters[&46]))),
765 Cell::new(&(format!("{}", counters[&47]))),
766 Cell::new(&(format!("{}", counters[&48]))),
767 Cell::new(&(format!("{}", counters[&49]))),
768 ]);
769
770 let column = table.column_mut(2).expect("Our table has three columns");
772 column.set_cell_alignment(CellAlignment::Right);
773 println!("{table}");
774 Ok(counters)
775 }
776
777 fn reset_rb_counters(&mut self) -> PyResult<()> {
779 println!("{}", RB_CNTS_RESET);
780 match RB_CNTS_RESET.set(&mut self.ipbus, 1) {
781 Ok(_) => {
782 return Ok(());
783 }
784 Err(err) => {
785 return Err(PyValueError::new_err(err.to_string()));
786 }
787 }
788 }
789
790 fn reset_ltb_counters(&mut self) -> PyResult<()> {
792 match LT_HIT_CNT_RESET.set(&mut self.ipbus, 1) {
793 Ok(_) => {
794 return Ok(());
795 }
796 Err(err) => {
797 return Err(PyValueError::new_err(err.to_string()));
798 }
799 }
800 }
801
802 fn set_ltb_ch_mask(&mut self, lt_link : u8, mask : u8) -> PyResult<()> {
809 let registers = [LT0_CHMASK, LT1_CHMASK, LT2_CHMASK, LT3_CHMASK, LT4_CHMASK,
810 LT5_CHMASK, LT6_CHMASK, LT7_CHMASK, LT8_CHMASK, LT9_CHMASK,
811 LT10_CHMASK, LT11_CHMASK, LT12_CHMASK, LT13_CHMASK, LT14_CHMASK,
812 LT15_CHMASK, LT16_CHMASK, LT17_CHMASK, LT18_CHMASK, LT19_CHMASK,
813 LT20_CHMASK, LT21_CHMASK, LT22_CHMASK, LT23_CHMASK, LT24_CHMASK];
814 if lt_link as usize > registers.len() {
815 return Err(PyValueError::new_err(String::from("Mask has to be in range 0-24!")));
816 }
817
818 match registers[lt_link as usize].set(&mut self.ipbus, mask as u32) {
819 Ok(_) => {
820 return Ok(());
821 }
822 Err(err) => {
823 return Err(PyValueError::new_err(err.to_string()));
824 }
825 }
826 }
827
828
829 fn set_trace_suppression(&mut self, trace_sup : bool) -> PyResult<()> {
830 let read_all_rb : u32;
831 if trace_sup {
832 read_all_rb = 0;
833 } else {
834 read_all_rb = 1;
835 }
836 match RB_READ_ALL_CHANNELS.set(&mut self.ipbus, read_all_rb) {
837 Ok(_) => {
838 Ok(())
839 }
840 Err(err) => {
841 return Err(PyValueError::new_err(err.to_string()));
842 }
843 }
844 }
845
846 fn get_trace_suppression(&mut self) -> PyResult<u32> {
847 match RB_READ_ALL_CHANNELS.get(&mut self.ipbus) {
848 Ok(cnt) => {
849 return Ok(cnt);
850 }
851 Err(err) => {
852 return Err(PyValueError::new_err(err.to_string()));
853 }
854 }
855 }
856
857 fn set_total_tof_thresh(&mut self, value : u32) -> PyResult<()> {
858 match TOTAL_TOF_THRESH.set(&mut self.ipbus, value) {
859 Ok(_) => {
860 Ok(())
861 }
862 Err(err) => {
863 return Err(PyValueError::new_err(err.to_string()));
864 }
865 }
866 }
867
868 fn get_total_tof_thresh(&mut self) -> PyResult<u32> {
869 match TOTAL_TOF_THRESH.get(&mut self.ipbus) {
870 Ok(cnt) => {
871 return Ok(cnt);
872 }
873 Err(err) => {
874 return Err(PyValueError::new_err(err.to_string()));
875 }
876 }
877 }
878
879 fn set_inner_tof_thresh(&mut self, value : u32) -> PyResult<()> {
880 match INNER_TOF_THRESH.set(&mut self.ipbus, value) {
881 Ok(_) => {
882 return Ok(());
883 }
884 Err(err) => {
885 return Err(PyValueError::new_err(err.to_string()));
886 }
887 }
888 }
889
890 fn get_inner_tof_thresh(&mut self) -> PyResult<u32> {
891 match INNER_TOF_THRESH.get(&mut self.ipbus) {
892 Ok(cnt) => {
893 return Ok(cnt);
894 }
895 Err(err) => {
896 return Err(PyValueError::new_err(err.to_string()));
897 }
898 }
899 }
900
901 fn set_outer_tof_thresh(&mut self, value : u32) -> PyResult<()> {
902 match OUTER_TOF_THRESH.set(&mut self.ipbus, value) {
903 Ok(_) => {
904 return Ok(());
905 }
906 Err(err) => {
907 return Err(PyValueError::new_err(err.to_string()));
908 }
909 }
910 }
911
912 fn get_outer_tof_thresh(&mut self) -> PyResult<u32> {
913 match OUTER_TOF_THRESH.get(&mut self.ipbus) {
914 Ok(cnt) => {
915 return Ok(cnt);
916 }
917 Err(err) => {
918 return Err(PyValueError::new_err(err.to_string()));
919 }
920 }
921 }
922
923 fn set_cube_side_thresh(&mut self, value : u32) -> PyResult<()> {
924 match CUBE_SIDE_THRESH.set(&mut self.ipbus, value) {
925 Ok(_) => {
926 return Ok(());
927 }
928 Err(err) => {
929 return Err(PyValueError::new_err(err.to_string()));
930 }
931 }
932 }
933
934 fn get_cube_side_thresh(&mut self) -> PyResult<u32> {
935 match CUBE_SIDE_THRESH.get(&mut self.ipbus) {
936 Ok(cnt) => {
937 return Ok(cnt);
938 }
939 Err(err) => {
940 return Err(PyValueError::new_err(err.to_string()));
941 }
942 }
943 }
944
945 fn set_cube_top_thresh(&mut self, value : u32) -> PyResult<()> {
946 match CUBE_TOP_THRESH.set(&mut self.ipbus, value) {
947 Ok(_) => {
948 return Ok(());
949 }
950 Err(err) => {
951 return Err(PyValueError::new_err(err.to_string()));
952 }
953 }
954 }
955
956 fn get_cube_top_thresh(&mut self) -> PyResult<u32> {
957 match CUBE_TOP_THRESH.get(&mut self.ipbus) {
958 Ok(cnt) => {
959 return Ok(cnt);
960 }
961 Err(err) => {
962 return Err(PyValueError::new_err(err.to_string()));
963 }
964 }
965 }
966
967 fn set_cube_bot_thresh(&mut self, value : u32) -> PyResult<()> {
968 match CUBE_BOT_THRESH.set(&mut self.ipbus, value) {
969 Ok(_) => {
970 return Ok(());
971 }
972 Err(err) => {
973 return Err(PyValueError::new_err(err.to_string()));
974 }
975 }
976 }
977
978 fn get_cube_bot_thresh(&mut self) -> PyResult<u32> {
979 match CUBE_BOT_THRESH.get(&mut self.ipbus) {
980 Ok(cnt) => {
981 return Ok(cnt);
982 }
983 Err(err) => {
984 return Err(PyValueError::new_err(err.to_string()));
985 }
986 }
987 }
988
989 fn set_cube_corner_thresh(&mut self, value : u32) -> PyResult<()> {
990 match CUBE_CORNER_THRESH.set(&mut self.ipbus, value) {
991 Ok(_) => {
992 return Ok(());
993 }
994 Err(err) => {
995 return Err(PyValueError::new_err(err.to_string()));
996 }
997 }
998 }
999
1000 fn get_cube_corner_thresh(&mut self) -> PyResult<u32> {
1001 match CUBE_CORNER_THRESH.get(&mut self.ipbus) {
1002 Ok(cnt) => {
1003 return Ok(cnt);
1004 }
1005 Err(err) => {
1006 return Err(PyValueError::new_err(err.to_string()));
1007 }
1008 }
1009 }
1010
1011 fn set_umbrella_thresh(&mut self, value : u32) -> PyResult<()> {
1012 match UMBRELLA_THRESH.set(&mut self.ipbus, value) {
1013 Ok(_) => {
1014 return Ok(());
1015 }
1016 Err(err) => {
1017 return Err(PyValueError::new_err(err.to_string()));
1018 }
1019 }
1020 }
1021
1022 fn get_umbrella_thresh(&mut self) -> PyResult<u32> {
1023 match UMBRELLA_THRESH.get(&mut self.ipbus) {
1024 Ok(cnt) => {
1025 return Ok(cnt);
1026 }
1027 Err(err) => {
1028 return Err(PyValueError::new_err(err.to_string()));
1029 }
1030 }
1031 }
1032
1033 fn set_umbrella_center_thresh(&mut self, value : u32) -> PyResult<()> {
1034 match UMBRELLA_CENTER_THRESH.set(&mut self.ipbus, value) {
1035 Ok(_) => {
1036 return Ok(());
1037 }
1038 Err(err) => {
1039 return Err(PyValueError::new_err(err.to_string()));
1040 }
1041 }
1042 }
1043
1044 fn get_umbrella_center_thresh(&mut self) -> PyResult<u32> {
1045 match UMBRELLA_CENTER_THRESH.get(&mut self.ipbus) {
1046 Ok(cnt) => {
1047 return Ok(cnt);
1048 }
1049 Err(err) => {
1050 return Err(PyValueError::new_err(err.to_string()));
1051 }
1052 }
1053 }
1054
1055 fn set_cortina_thresh(&mut self, value : u32) -> PyResult<()> {
1056 match CORTINA_THRESH.set(&mut self.ipbus, value) {
1057 Ok(_) => {
1058 return Ok(());
1059 }
1060 Err(err) => {
1061 return Err(PyValueError::new_err(err.to_string()));
1062 }
1063 }
1064 }
1065
1066 fn get_cortina_thresh(&mut self) -> PyResult<u32> {
1067 match CORTINA_THRESH.get(&mut self.ipbus) {
1068 Ok(cnt) => {
1069 return Ok(cnt);
1070 }
1071 Err(err) => {
1072 return Err(PyValueError::new_err(err.to_string()));
1073 }
1074 }
1075 }
1076
1077 fn set_configurable_trigger(&mut self, value : u32) -> PyResult<()> {
1078 match CONFIGURABLE_TRIGGER_EN.set(&mut self.ipbus, value) {
1079 Ok(_) => {
1080 return Ok(());
1081 }
1082 Err(err) => {
1083 return Err(PyValueError::new_err(err.to_string()));
1084 }
1085 }
1086 }
1087
1088 fn get_configurable_trigger(&mut self) -> PyResult<u32> {
1089 match CONFIGURABLE_TRIGGER_EN.get(&mut self.ipbus) {
1090 Ok(cnt) => {
1091 return Ok(cnt);
1092 }
1093 Err(err) => {
1094 return Err(PyValueError::new_err(err.to_string()));
1095 }
1096 }
1097 }
1098
1099 fn set_any_trigger(&mut self, prescale : u32) -> PyResult<()> {
1100 match ANY_TRIG_PRESCALE.set(&mut self.ipbus, prescale) {
1101 Ok(_) => {
1102 return Ok(());
1103 }
1104 Err(err) => {
1105 return Err(PyValueError::new_err(err.to_string()));
1106 }
1107 }
1108 }
1109
1110 fn set_track_trigger(&mut self, prescale : u32) -> PyResult<()> {
1111 match TRACK_TRIG_PRESCALE.set(&mut self.ipbus, prescale) {
1112 Ok(_) => {
1113 return Ok(());
1114 }
1115 Err(err) => {
1116 return Err(PyValueError::new_err(err.to_string()));
1117 }
1118 }
1119 }
1120
1121 fn set_central_track_trigger(&mut self, prescale : u32) -> PyResult<()> {
1122 match TRACK_CENTRAL_PRESCALE.set(&mut self.ipbus, prescale) {
1123 Ok(_) => {
1124 return Ok(());
1125 }
1126 Err(err) => {
1127 return Err(PyValueError::new_err(err.to_string()));
1128 }
1129 }
1130 }
1131
1132 fn use_tiu_aux_link(&mut self, use_it : bool) -> PyResult<()> {
1133 match mt_api::control::use_tiu_aux_link(&mut self.ipbus, use_it) {
1134 Ok(_) => {
1135 return Ok(());
1136 }
1137 Err(err) => {
1138 return Err(PyValueError::new_err(err.to_string()));
1139 }
1140 }
1141 }
1142
1143 fn stop_all_triggers(&mut self) -> PyResult<()> {
1144 match mt_api::control::unset_all_triggers(&mut self.ipbus) {
1145 Ok(_) => {
1146 return Ok(());
1147 }
1148 Err(err) => {
1149 return Err(PyValueError::new_err(err.to_string()));
1150 }
1151 }
1152 }
1153
1154 fn set_umbcube_trigger(&mut self) -> PyResult<()> {
1155 match mt_api::control::set_umbcube_trigger(&mut self.ipbus) {
1156 Ok(_) => {
1157 return Ok(());
1158 }
1159 Err(err) => {
1160 return Err(PyValueError::new_err(err.to_string()));
1161 }
1162 }
1163 }
1164
1165 fn set_umbcubez_trigger(&mut self) -> PyResult<()> {
1166 match mt_api::control::set_umbcubez_trigger(&mut self.ipbus) {
1167 Ok(_) => {
1168 return Ok(());
1169 }
1170 Err(err) => {
1171 return Err(PyValueError::new_err(err.to_string()));
1172 }
1173 }
1174 }
1175
1176 fn set_umbcorcube_trigger(&mut self) -> PyResult<()> {
1177 match mt_api::control::set_umbcorcube_trigger(&mut self.ipbus) {
1178 Ok(_) => {
1179 return Ok(());
1180 }
1181 Err(err) => {
1182 return Err(PyValueError::new_err(err.to_string()));
1183 }
1184 }
1185 }
1186
1187 fn set_corcubeside_trigger(&mut self) -> PyResult<()> {
1188 match mt_api::control::set_corcubeside_trigger(&mut self.ipbus) {
1189 Ok(_) => {
1190 return Ok(());
1191 }
1192 Err(err) => {
1193 return Err(PyValueError::new_err(err.to_string()));
1194 }
1195 }
1196 }
1197
1198 fn set_umb3cube_trigger(&mut self) -> PyResult<()> {
1199 match mt_api::control::set_umb3cube_trigger(&mut self.ipbus) {
1200 Ok(_) => {
1201 return Ok(());
1202 }
1203 Err(err) => {
1204 return Err(PyValueError::new_err(err.to_string()));
1205 }
1206 }
1207 }
1208
1209 #[getter]
1210 fn get_tiu_busy_ignore(&mut self) -> PyResult<bool> {
1211 match TIU_BUSY_IGNORE.get(&mut self.ipbus) {
1212 Ok(bsy) => {
1213 let res = bsy != 0;
1214 return Ok(res);
1215 }
1216 Err(err) => {
1217 return Err(PyValueError::new_err(err.to_string()));
1218 }
1219 }
1220 }
1221
1222 #[setter]
1223 fn set_tiu_busy_ignore(&mut self, bsy : bool) -> PyResult<()> {
1224 match TIU_BUSY_IGNORE.set(&mut self.ipbus, bsy as u32) {
1225 Ok(_) => {
1226 return Ok(());
1227 }
1228 Err(err) => {
1229 return Err(PyValueError::new_err(err.to_string()));
1230 }
1231 }
1232 }
1233
1234 #[getter]
1235 fn get_tiu_busy_stuck(&mut self) -> PyResult<bool> {
1236 match TIU_BUSY_STUCK.get(&mut self.ipbus) {
1237 Ok(value) => {
1238 return Ok(value > 0);
1239 }
1240 Err(err) => {
1241 return Err(PyValueError::new_err(err.to_string()));
1242 }
1243 }
1244 }
1245
1246 #[getter]
1247 fn get_tiu_bad(&mut self) -> PyResult<bool> {
1248 match TIU_BAD.get(&mut self.ipbus) {
1249 Ok(value) => {
1250 return Ok(value > 0);
1251 }
1252 Err(err) => {
1253 return Err(PyValueError::new_err(err.to_string()));
1254 }
1255 }
1256 }
1257
1258 fn get_event_cnt(&mut self) -> PyResult<u32> {
1259 match EVENT_CNT.get(&mut self.ipbus) {
1260 Ok(cnt) => {
1261 return Ok(cnt);
1262 }
1263 Err(err) => {
1264 return Err(PyValueError::new_err(err.to_string()));
1265 }
1266 }
1267 }
1268
1269 fn get_event_queue_size(&mut self)
1270 -> PyResult<u32> {
1271 match EVQ_SIZE.get(&mut self.ipbus) {
1272 Ok(cnt) => {
1273 return Ok(cnt);
1274 }
1275 Err(err) => {
1276 return Err(PyValueError::new_err(err.to_string()));
1277 }
1278 }
1279 }
1280
1281 fn get_event_queue_full(&mut self)
1282 -> PyResult<u32> {
1283 match EVQ_FULL.get(&mut self.ipbus) {
1284 Ok(cnt) => {
1285 return Ok(cnt);
1286 }
1287 Err(err) => {
1288 return Err(PyValueError::new_err(err.to_string()));
1289 }
1290 }
1291 }
1292
1293 fn get_nevents_in_queue(&mut self)
1294 -> PyResult<u32> {
1295 match EVQ_NUM_EVENTS.get(&mut self.ipbus) {
1296 Ok(cnt) => {
1297 return Ok(cnt);
1298 }
1299 Err(err) => {
1300 return Err(PyValueError::new_err(err.to_string()));
1301 }
1302 }
1303 }
1304
1305
1306
1307 fn get_event(&mut self, read_until_footer : bool, verbose : bool, debug : bool)
1308 -> PyResult<PyMasterTriggerEvent> {
1309 let use_dbg_version = debug;
1310 if !use_dbg_version {
1311 let mut event = PyMasterTriggerEvent::new();
1312 match mt_api::get_event(&mut self.ipbus) {
1313 None => {
1314 Ok(event)
1317 }
1318 Some(Err(err)) => {
1319 return Err(PyValueError::new_err(err.to_string()));
1321 }
1322 Some(Ok(mte)) => {
1323 event.set_event(mte);
1324 Ok(event)
1325 }
1326 }
1327 } else {
1328 let mut n_daq_words : u16;
1332 let mut n_daq_words_actual : u16;
1333 loop {
1334 match EVQ_NUM_EVENTS.get(&mut self.ipbus) {
1335 Err(_err) => {
1336 continue;
1337 }
1338 Ok(nevents_in_q) => {
1339 if nevents_in_q == 0 {
1340 if verbose {
1341 println!("[MasterTrigger::get_event] => EventQueue empty!!");
1342 }
1343 return Err(PyValueError::new_err(String::from("<MasterTriggerError: EventQueueEmpty>")));
1344 }
1345 }
1346 }
1347 match self.ipbus.read(0x13) {
1348 Err(_err) => {
1349 continue;
1354 },
1355 Ok(_n_words) => {
1356 n_daq_words = (_n_words >> 16) as u16;
1357 if _n_words == 0 {
1358 continue;
1359 }
1360 let rest = n_daq_words % 2;
1362 n_daq_words /= 2 + rest; break;
1366 }
1367 }
1368 }
1369 let mut data : Vec<u32>;
1370 if verbose {
1371 println!("[MasterTrigger::get_event] => Will query DAQ for {n_daq_words} words!");
1372 }
1373 n_daq_words_actual = n_daq_words;
1374 match self.ipbus.read_multiple(
1375 0x11,
1376 n_daq_words as usize,
1377 false) {
1378 Err(err) => {
1379 if verbose {
1380 println!("[MasterTrigger::get_event] => failed! {err}");
1381 }
1382 return Err(PyValueError::new_err(err.to_string()));
1383 }
1384 Ok(_data) => {
1385 data = _data;
1386 for (i,word) in data.iter().enumerate() {
1387 let desc : &str;
1388 let desc_str : String;
1389 match i {
1391 0 => desc = "HEADER",
1392 1 => desc = "EVENTID",
1393 2 => desc = "TIMESTAMP",
1394 3 => desc = "TIU_TIMESTAMP",
1395 4 => desc = "TIU_GPS32",
1396 5 => desc = "TIU_GPS16 + TRIG_SOURCE",
1397 6 => desc = "RB MASK 0",
1398 7 => desc = "RB MASK 1",
1399 8 => {
1400 desc_str = format!("BOARD MASK ({} ltbs)", word.count_ones());
1402 desc = &desc_str;
1403 },
1404 _ => desc = "?"
1405 }
1406 if verbose {
1407 println!("[MasterTrigger::get_event] => DAQ word {} \t({:x}) \t[{}]", word, word, desc);
1408 }
1409 }
1410 }
1411 }
1412 if data[0] != 0xAAAAAAAA {
1413 if verbose {
1414 println!("[MasterTrigger::get_event] => Got MTB data, but the header is incorrect {}", data[0]);
1415 }
1416 return Err(PyValueError::new_err(String::from("Incorrect header value!")));
1417 }
1418 let foot_pos = (n_daq_words - 1) as usize;
1419 if data.len() <= foot_pos {
1420 if verbose {
1421 println!("[MasterTrigger::get_event] => Got MTB data, but the format is not correct");
1422 }
1423 return Err(PyValueError::new_err(String::from("Empty data!")));
1424 }
1425 if data[foot_pos] != 0x55555555 {
1426 if verbose {
1427 println!("[MasterTrigger::get_event] => Did not read unti footer!");
1428 }
1429 if read_until_footer {
1430 if verbose {
1431 println!("[MasterTrigger::get_event] => .. will read additional words!");
1432 }
1433 loop {
1434 match self.ipbus.read(0x11) {
1435 Err(err) => {
1436 if verbose {
1437 println!("[MasterTrigger::get_event] => Issues reading from 0x11");
1438 }
1439 return Err(PyValueError::new_err(err.to_string()));
1440 },
1441 Ok(next_word) => {
1442 n_daq_words_actual += 1;
1443 data.push(next_word);
1444 if next_word == 0x55555555 {
1445 break;
1446 }
1447 }
1448 }
1449 }
1450 if verbose {
1451 println!("[MasterTrigger::get_event] => We read {} additional words!", n_daq_words_actual - n_daq_words);
1452 }
1453 } else {
1454 if verbose {
1455 println!("[MasterTrigger::get_event] => Got MTB data, but the footer is incorrect {}", data[foot_pos]);
1456 }
1457 return Err(PyValueError::new_err(String::from("Footer incorrect!")));
1458 }
1459 }
1460
1461 let mut mte = MasterTriggerEvent::new();
1467 mte.event_id = data[1];
1468 mte.timestamp = data[2];
1469 mte.tiu_timestamp = data[3];
1470 mte.tiu_gps32 = data[4];
1471 mte.tiu_gps16 = (data[5] & 0x0000ffff) as u16;
1472 mte.trigger_source = ((data[5] & 0xffff0000) >> 16) as u16;
1473 let rbmask = (data[7] as u64) << 31 | data[6] as u64;
1475 mte.mtb_link_mask = rbmask;
1476 mte.dsi_j_mask = data[8];
1477 let mut n_hit_words = n_daq_words_actual - 9 - 2; if n_hit_words > n_daq_words_actual {
1479 n_hit_words = 0;
1480 println!("[MasterTrigger::get_event] N hit word calculation failed! fixing... {}", n_hit_words);
1481 }
1482 if verbose {
1483 println!("[MasterTrigger::get_event] => Will read {} hit word", n_hit_words);
1484 }
1485 for k in 1..n_hit_words+1 {
1486 if verbose {
1487 println!("[MasterTrigger::get_event] => Getting word {}", k);
1488 }
1489 let first = (data[8 + k as usize] & 0x0000ffff) as u16;
1490 let second = ((data[8 + k as usize] & 0xffff0000) >> 16) as u16;
1491 mte.channel_mask.push(first);
1492 if second != 0 {
1493 mte.channel_mask.push(second);
1494 }
1495 }
1496 if verbose {
1497 println!("[MasterTrigger::get_event] => Got MTE \n{}", mte);
1498 }
1499 let mut event = PyMasterTriggerEvent::new();
1500 event.set_event(mte);
1501 Ok(event)
1502 }
1503 }
1504}
1505