1use std::fmt;
24use colored::Colorize;
26
27use crate::packets::{
28 TofPacket,
29 PacketType
30};
31use crate::events::TofHit;
32use crate::constants::{NWORDS, NCHN};
33use crate::serialization::{
34 u8_to_u16,
35 Serialization,
36 SerializationError,
37 search_for_u16,
38 Packable,
39 parse_u8,
40 parse_u16,
41 parse_u32,
42};
43
44use crate::events::{
45 DataType,
46 EventStatus,
47};
48use crate::errors::{
49 UserError,
50 AnalysisError,
51 CalibrationError,
52};
53use crate::io::RBEventMemoryStreamer;
54use crate::calibrations::{
55 RBCalibrations,
56 clean_spikes,
57};
58
59#[cfg(feature="database")]
60use crate::database::ReadoutBoard;
61
62cfg_if::cfg_if! {
63 if #[cfg(feature = "random")] {
64 use crate::FromRandom;
65 extern crate rand;
66 use rand::Rng;
67 }
68}
69
70#[derive(Debug, Copy, Clone, PartialEq)]
73pub struct RBPaddleID {
74 pub paddle_12 : u8,
76 pub paddle_34 : u8,
78 pub paddle_56 : u8,
80 pub paddle_78 : u8,
82 pub channel_order : u8
86}
87
88impl Default for RBPaddleID {
89 fn default() -> Self {
90 Self::new()
91 }
92}
93
94impl fmt::Display for RBPaddleID {
95 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96 let mut repr = String::from("<RBPaddleID:");
97 for k in 1..9 {
98 let pid = self.get_paddle_id(k);
99 let ord = self.get_order_str(k);
100 repr += &(format!("\n {k} -> {} ({ord})", pid.0))
101 }
102 repr += ">";
103 write!(f, "{}", repr)
104 }
105}
106
107impl RBPaddleID {
108 pub fn new() -> Self {
109 RBPaddleID {
110 paddle_12 : 0,
111 paddle_34 : 0,
112 paddle_56 : 0,
113 paddle_78 : 0,
114 channel_order : 0
115 }
116 }
117
118 pub fn to_u64(&self) -> u64 {
119 let val : u64 = (self.channel_order as u64) << 32 | (self.paddle_78 as u64) << 24 | (self.paddle_56 as u64) << 16 | (self.paddle_34 as u64) << 8 | self.paddle_12 as u64;
120 val
121 }
122
123 pub fn get_order_flipped(&self, channel : u8) -> bool {
131 match channel {
132 1 | 2 => {
133 return (self.channel_order & 1) == 1;
134 }
135 3 | 4 => {
136 return (self.channel_order & 2) == 2;
137 }
138 5 | 6 => {
139 return (self.channel_order & 4) == 4;
140 }
141 7 | 8 => {
142 return (self.channel_order & 8) == 8;
143 }
144 _ => {
145 error!("{} is not a valid RB channel!", channel);
146 return false;
147 }
148 }
149 }
150
151 pub fn get_order_str(&self, channel : u8) -> String {
152 if self.get_order_flipped(channel) {
153 return String::from("BA");
154 } else {
155 return String::from("AB");
156 }
157 }
158
159 pub fn is_a(&self, channel : u8) -> bool {
160 match channel {
161 1 => {
162 if self.get_order_flipped(channel) {
163 return false;
164 } else {
165 return true
166 }
167 }
168 2 => {
169 if self.get_order_flipped(channel) {
170 return true;
171 } else {
172 return false
173 }
174 }
175 3 => {
176 if self.get_order_flipped(channel) {
177 return false;
178 } else {
179 return true
180 }
181 }
182 4 => {
183 if self.get_order_flipped(channel) {
184 return true;
185 } else {
186 return false
187 }
188 }
189 5 => {
190 if self.get_order_flipped(channel) {
191 return false;
192 } else {
193 return true
194 }
195 }
196 6 => {
197 if self.get_order_flipped(channel) {
198 return true;
199 } else {
200 return false
201 }
202 }
203 7 => {
204 if self.get_order_flipped(channel) {
205 return false;
206 } else {
207 return true
208 }
209 }
210 8 => {
211 if self.get_order_flipped(channel) {
212 return true;
213 } else {
214 return false
215 }
216 }
217 _ => {
218 error!("{} is not a valid RB channel!", channel);
219 return false;
220 }
221 }
222 }
223
224 pub fn from_u64(val : u64) -> Self {
225 let paddle_12 : u8 = ((val & 0xFF)) as u8;
226 let paddle_34 : u8 = ((val & 0xFF00) >> 8) as u8;
227 let paddle_56 : u8 = ((val & 0xFF0000) >> 16) as u8;
228 let paddle_78 : u8 = ((val & 0xFF000000) >> 24) as u8;
229 let channel_order : u8 = ((val & 0xFF00000000) >> 32) as u8;
230 Self {
231 paddle_12,
232 paddle_34,
233 paddle_56,
234 paddle_78,
235 channel_order,
236 }
237 }
238
239 #[cfg(feature="database")]
240 pub fn from_rb( rb : &ReadoutBoard) -> Self {
241 let mut rb_pid = RBPaddleID::new();
242 rb_pid.paddle_12 = rb.paddle12.paddle_id as u8;
243 rb_pid.paddle_34 = rb.paddle34.paddle_id as u8;
244 rb_pid.paddle_56 = rb.paddle56.paddle_id as u8;
245 rb_pid.paddle_78 = rb.paddle78.paddle_id as u8;
246 let mut flipped = 0u8 ;
247 if rb.paddle12_chA != 1 {
248 flipped |= 1;
249 }
250 if rb.paddle34_chA != 3 {
251 flipped |= 2;
252 }
253 if rb.paddle56_chA != 5 {
254 flipped |= 4;
255 }
256 if rb.paddle78_chA != 7 {
257 flipped |= 8;
258 }
259 rb_pid.channel_order = flipped;
260 rb_pid
261 }
262
263 pub fn get_paddle_id(&self, channel : u8) -> (u8, bool) {
268 let flipped = self.get_order_flipped(channel);
269 match channel {
270 1 | 2 => {
271 return (self.paddle_12, flipped);
272 }
273 3 | 4 => {
274 return (self.paddle_34, flipped);
275 }
276 5 | 6 => {
277 return (self.paddle_56, flipped);
278 }
279 7 | 8 => {
280 return (self.paddle_78, flipped);
281 }
282 _ => {
283 error!("{} is not a valid RB channel!", channel);
284 return (0,false);
285 }
286 }
287 }
288}
289
290#[cfg(feature = "random")]
291impl FromRandom for RBPaddleID {
292
293 fn from_random() -> Self {
294 let mut rb_pid = Self::new();
295 let mut rng = rand::thread_rng();
296 rb_pid.paddle_12 = rng.gen::<u8>();
297 rb_pid.paddle_34 = rng.gen::<u8>();
298 rb_pid.paddle_56 = rng.gen::<u8>();
299 rb_pid.paddle_78 = rng.gen::<u8>();
300 rb_pid.channel_order = rng.gen::<u8>();
301 rb_pid
302 }
303}
304
305pub fn unpack_traces_f64(events : &Vec<RBEvent>)
321 -> Vec<Vec<Vec<f64>>> {
322 let nevents = events.len();
323 let mut traces = Vec::<Vec::<Vec::<f64>>>::new();
324 let mut trace = Vec::<f64>::with_capacity(NWORDS);
325 let mut stop_cells = Vec::<isize>::new();
326 let mut empty_events = Vec::<Vec::<f64>>::new();
327 for _ in 0..nevents {
328 empty_events.push(trace.clone());
329 }
330 for ch in 0..NCHN {
331 traces.push(empty_events.clone());
332 for (k,ev) in events.iter().enumerate() {
333 trace.clear();
334 stop_cells.push(ev.header.stop_cell as isize);
335 for k in 0..NWORDS {
336 trace.push(ev.adc[ch][k] as f64);
337 }
338 traces[ch][k] = trace.clone();
339 }
340 }
341 traces
342}
343
344pub fn unpack_traces_f32(events : &Vec<RBEvent>)
345 -> Vec<Vec<Vec<f32>>> {
346 let nevents = events.len();
347 let mut traces = Vec::<Vec::<Vec::<f32>>>::new();
348 let mut trace = Vec::<f32>::with_capacity(NWORDS);
349 let mut stop_cells = Vec::<isize>::new();
350 let mut empty_events = Vec::<Vec::<f32>>::new();
351 for _ in 0..nevents {
352 empty_events.push(trace.clone());
353 }
354 for ch in 0..NCHN {
355 traces.push(empty_events.clone());
356 for (k,ev) in events.iter().enumerate() {
357 trace.clear();
358 stop_cells.push(ev.header.stop_cell as isize);
359 for k in 0..NWORDS {
360 trace.push(ev.adc[ch][k] as f32);
361 }
362 traces[ch][k] = trace.clone();
363 }
364 }
365 traces
366}
367
368
369#[derive(Debug, Clone, PartialEq)]
374pub struct RBEvent {
375 pub data_type : DataType,
376 pub status : EventStatus,
377 pub header : RBEventHeader,
378 pub adc : Vec<Vec<u16>>,
379 pub hits : Vec<TofHit>,
380}
381
382impl RBEvent {
383
384 pub fn new() -> Self {
385 let mut adc = Vec::<Vec<u16>>::with_capacity(NCHN);
386 for _ in 0..NCHN {
387 adc.push(Vec::<u16>::new());
388 }
389 Self {
390 data_type : DataType::Unknown,
391 status : EventStatus::Unknown,
392 header : RBEventHeader::new(),
393 adc : adc,
394 hits : Vec::<TofHit>::new(),
395 }
396 }
397
398 pub fn has_any_mangling_flag(&self) -> bool {
399 match self.status {
400 EventStatus::ChnSyncErrors
401 | EventStatus::CellSyncErrors
402 | EventStatus::CellAndChnSyncErrors => {
403 return true;
404 }
405 _ => {
406 return false;
407 }
408 }
409 }
410
411 pub fn self_check(&self) -> Result<(),AnalysisError> {
414 let mut pass = false;
415 for ch in self.header.get_channels() {
416 if self.adc[ch as usize].len() == 0 {
417 error!("RB {} expects ch {} but it is empty!", self.header.rb_id, ch + 1);
418 println!("{}", self.header);
419 pass = false;
420 }
421 }
422 if !pass {
423 return Err(AnalysisError::MissingChannel);
424 }
425 Ok(())
426 }
427
428 pub fn get_rbwaveforms(&self) -> Vec<RBWaveform> {
430 let mut waveforms = Vec::<RBWaveform>::new();
432 let active_channels = self.header.get_channels();
434 let pid = self.header.get_rbpaddleid();
435 if active_channels.contains(&0) || active_channels.contains(&1) {
436 let paddle_id = pid.get_paddle_id(1);
437 let mut wf = RBWaveform::new();
438 wf.rb_id = self.header.rb_id;
439 wf.event_id = self.header.event_id;
440 wf.stop_cell = self.header.stop_cell;
441 wf.paddle_id = paddle_id.0;
442 if paddle_id.1 {
443 wf.adc_b = self.adc[0].clone();
445 wf.adc_a = self.adc[1].clone();
446 wf.rb_channel_b = 0;
447 wf.rb_channel_a = 1;
448 } else {
449 wf.adc_a = self.adc[0].clone();
450 wf.adc_b = self.adc[1].clone();
451 wf.rb_channel_b = 1;
452 wf.rb_channel_a = 0;
453 }
454 waveforms.push(wf);
455 }
456 if active_channels.contains(&2) || active_channels.contains(&3) {
457 let paddle_id = pid.get_paddle_id(3);
458 let mut wf = RBWaveform::new();
459 wf.rb_id = self.header.rb_id;
460 wf.event_id = self.header.event_id;
461 wf.stop_cell = self.header.stop_cell;
462 wf.paddle_id = paddle_id.0;
463 if paddle_id.1 {
464 wf.adc_b = self.adc[2].clone();
466 wf.adc_a = self.adc[3].clone();
467 wf.rb_channel_b = 2;
468 wf.rb_channel_a = 3;
469 } else {
470 wf.adc_a = self.adc[2].clone();
471 wf.adc_b = self.adc[3].clone();
472 wf.rb_channel_b = 3;
473 wf.rb_channel_a = 2;
474 }
475 waveforms.push(wf);
476 }
477 if active_channels.contains(&4) || active_channels.contains(&5) {
478 let paddle_id = pid.get_paddle_id(5);
479 let mut wf = RBWaveform::new();
480 wf.rb_id = self.header.rb_id;
481 wf.event_id = self.header.event_id;
482 wf.stop_cell = self.header.stop_cell;
483 wf.paddle_id = paddle_id.0;
484 if paddle_id.1 {
485 wf.adc_b = self.adc[4].clone();
487 wf.adc_a = self.adc[5].clone();
488 wf.rb_channel_b = 4;
489 wf.rb_channel_a = 5;
490 } else {
491 wf.adc_a = self.adc[4].clone();
492 wf.adc_b = self.adc[5].clone();
493 wf.rb_channel_b = 5;
494 wf.rb_channel_a = 4;
495 }
496 waveforms.push(wf);
497 }
498 if active_channels.contains(&6) || active_channels.contains(&7) {
499 let paddle_id = pid.get_paddle_id(7);
500 let mut wf = RBWaveform::new();
501 wf.rb_id = self.header.rb_id;
502 wf.event_id = self.header.event_id;
503 wf.stop_cell = self.header.stop_cell;
504 wf.paddle_id = paddle_id.0;
505 if paddle_id.1 {
506 wf.adc_b = self.adc[6].clone();
508 wf.adc_a = self.adc[7].clone();
509 wf.rb_channel_b = 6;
510 wf.rb_channel_a = 7;
511 } else {
512 wf.adc_a = self.adc[6].clone();
513 wf.adc_b = self.adc[7].clone();
514 wf.rb_channel_b = 6;
515 wf.rb_channel_a = 7;
516 }
517 waveforms.push(wf);
518 }
519 waveforms
520 }
521
522 pub fn extract_datatype(stream : &Vec<u8>) -> Result<DataType, SerializationError> {
527 if stream.len() < 3 {
528 return Err(SerializationError::StreamTooShort);
529 }
530 Ok(DataType::try_from(stream[2]).unwrap_or(DataType::Unknown))
532 }
533
534 pub fn get_channel_packet_len(stream : &Vec<u8>, pos : usize) -> Result<(usize, Vec::<u8>), SerializationError> {
537 if stream.len() < 8 {
540 return Err(SerializationError::StreamTooShort);
541 }
542 let mut _pos = pos + 4;
543 let packet_len = parse_u16(stream, &mut _pos) as usize * 2; if packet_len < 44 {
545 error!("Event fragment - no channel data!");
547 return Ok((packet_len.into(), Vec::<u8>::new()));
548 }
549 let nwords = parse_u16(stream, &mut _pos) as usize + 1; debug!("Got packet len of {} bytes, roi of {}", packet_len, nwords);
551 let channel_packet_start = pos + 36;
552 let nchan_data = packet_len - 44;
553 if stream.len() < channel_packet_start + nchan_data {
554 error!("We claim there should be channel data, but the event is too short!");
555 return Err(SerializationError::StreamTooShort)
556 }
557
558 let mut nchan = 0usize;
559 while nchan * (2*nwords + 6) < nchan_data {
563 nchan += 1;
564 }
565 if nchan * (2*nwords + 6) != nchan_data {
566 error!("NCHAN consistency check failed! nchan {} , nwords {}, packet_len {}", nchan, nwords, packet_len);
567 }
568 let mut ch_ids = Vec::<u8>::new();
569 _pos = channel_packet_start;
570 for _ in 0..nchan {
571 ch_ids.push(parse_u16(stream, &mut _pos) as u8);
572 _pos += (nwords*2) as usize;
573 _pos += 4; }
575 debug!("Got channel ids {:?}", ch_ids);
576 Ok((nchan_data.into(), ch_ids))
577 }
578
579 pub fn extract_eventid(stream : &Vec<u8>) -> Result<u32, SerializationError> {
584 if stream.len() < 30 {
585 return Err(SerializationError::StreamTooShort);
586 }
587 let event_id = parse_u32(stream, &mut 10);
590 Ok(event_id)
591 }
592
593 pub fn get_ndatachan(&self) -> usize {
594 self.adc.len()
595 }
596
597 pub fn get_channel_by_id(&self, ch : usize) -> Result<&Vec::<u16>, UserError> {
598 if ch >= 9 {
599 error!("channel_by_id expects numbers from 0-8!");
600 return Err(UserError::IneligibleChannelLabel)
601 }
602 return Ok(&self.adc[ch]);
603 }
604
605 pub fn get_channel_by_label(&self, ch : u8) -> Result<&Vec::<u16>, UserError> {
606 if ch == 0 || ch > 9 {
607 error!("channel_by_label expects numbers from 1-9!");
608 return Err(UserError::IneligibleChannelLabel)
609 }
610 Ok(&self.adc[ch as usize -1])
611 }
612
613 pub fn from_bytestream_nowaveforms(stream : &Vec<u8>, pos : &mut usize)
617 -> Result<Self, SerializationError> {
618 let mut event = Self::new();
619 if parse_u16(stream, pos) != Self::HEAD {
620 error!("The given position {} does not point to a valid header signature of {}", pos, Self::HEAD);
621 return Err(SerializationError::HeadInvalid {});
622 }
623 event.data_type = DataType::try_from(parse_u8(stream, pos)).unwrap_or(DataType::Unknown);
624 event.status = EventStatus::try_from(parse_u8(stream, pos)).unwrap_or(EventStatus::Unknown);
625 let n_hits = parse_u8(stream, pos);
627 event.header = RBEventHeader::from_bytestream(stream, pos)?;
628 let stream_len = stream.len();
630 if event.header.is_event_fragment() {
631 debug!("Fragmented event {} found!", event.header.event_id);
632 let tail_pos = search_for_u16(Self::TAIL, stream, *pos)?;
633 * pos = tail_pos + 2 as usize;
634 return Ok(event);
637 }
638 if event.header.drs_lost_trigger() {
639 debug!("Event {} has lost trigger!", event.header.event_id);
640 let tail_pos = search_for_u16(Self::TAIL, stream, *pos)?;
641 * pos = tail_pos + 2 as usize;
642 return Ok(event);
643 }
644 let mut decoded_ch = Vec::<u8>::new();
645 for ch in event.header.get_channels().iter() {
649 if *pos + 2*NWORDS >= stream_len {
650 error!("The channel data for event {} ch {} seems corrupt! We want to get channels {:?}, but have decoded only {:?}, because the stream ends {} bytes too early!",event.header.event_id, ch, event.header.get_channels(), decoded_ch, *pos + 2*NWORDS - stream_len);
651 let tail_pos = search_for_u16(Self::TAIL, stream, *pos)?;
652 * pos = tail_pos + 2 as usize;
653 return Err(SerializationError::WrongByteSize {})
654 }
655 decoded_ch.push(*ch);
656 *pos += 2*NWORDS;
658 }
659 for _ in 0..n_hits {
660 match TofHit::from_bytestream(stream, pos) {
661 Err(err) => {
662 error!("Can't read TofHit! Err {err}");
663 let mut h = TofHit::new();
664 h.valid = false;
665 event.hits.push(h);
666 },
667 Ok(h) => {
668 event.hits.push(h);
669 }
670 }
671 }
672 let tail = parse_u16(stream, pos);
673 if tail != Self::TAIL {
674 error!("After parsing the event, we found an invalid tail signature {}", tail);
675 return Err(SerializationError::TailInvalid);
676 }
677 Ok(event)
678 }
679}
680
681impl Packable for RBEvent {
682 const PACKET_TYPE : PacketType = PacketType::RBEvent;
683}
684
685impl Serialization for RBEvent {
686 const HEAD : u16 = 0xAAAA;
687 const TAIL : u16 = 0x5555;
688
689 fn from_bytestream(stream : &Vec<u8>, pos : &mut usize)
690 -> Result<Self, SerializationError> {
691 let mut event = Self::new();
692 if parse_u16(stream, pos) != Self::HEAD {
693 error!("The given position {} does not point to a valid header signature of {}", pos, Self::HEAD);
694 return Err(SerializationError::HeadInvalid {});
695 }
696 event.data_type = DataType::try_from(parse_u8(stream, pos)).unwrap_or(DataType::Unknown);
697 event.status = EventStatus::try_from(parse_u8(stream, pos)).unwrap_or(EventStatus::Unknown);
698 let n_hits = parse_u8(stream, pos);
700 event.header = RBEventHeader::from_bytestream(stream, pos)?;
701 let stream_len = stream.len();
703 if event.header.is_event_fragment() {
704 debug!("Fragmented event {} found!", event.header.event_id);
705 let tail_pos = search_for_u16(Self::TAIL, stream, *pos)?;
706 * pos = tail_pos + 2 as usize;
707 return Ok(event);
710 }
711 if event.header.drs_lost_trigger() {
712 debug!("Event {} has lost trigger!", event.header.event_id);
713 let tail_pos = search_for_u16(Self::TAIL, stream, *pos)?;
714 * pos = tail_pos + 2 as usize;
715 return Ok(event);
716 }
717 let mut decoded_ch = Vec::<u8>::new();
718 for ch in event.header.get_channels().iter() {
719 if *pos + 2*NWORDS >= stream_len {
720 error!("The channel data for event {} ch {} seems corrupt! We want to get channels {:?}, but have decoded only {:?}, because the stream ends {} bytes too early!",event.header.event_id, ch, event.header.get_channels(), decoded_ch, *pos + 2*NWORDS - stream_len);
721 let tail_pos = search_for_u16(Self::TAIL, stream, *pos)?;
722 * pos = tail_pos + 2 as usize;
723 return Err(SerializationError::WrongByteSize {})
724 }
725 decoded_ch.push(*ch);
726 let data = &stream[*pos..*pos+2*NWORDS];
728 event.adc[*ch as usize] = u8_to_u16(data);
730 *pos += 2*NWORDS;
731 }
732 for _ in 0..n_hits {
733 match TofHit::from_bytestream(stream, pos) {
734 Err(err) => {
735 error!("Can't read TofHit! Err {err}");
736 let mut h = TofHit::new();
737 h.valid = false;
738 event.hits.push(h);
739 },
740 Ok(h) => {
741 event.hits.push(h);
742 }
743 }
744 }
745 let tail = parse_u16(stream, pos);
746 if tail != Self::TAIL {
749 error!("After parsing the event, we found an invalid tail signature {}", tail);
750 return Err(SerializationError::TailInvalid);
751 }
752 Ok(event)
753 }
754
755 fn to_bytestream(&self) -> Vec<u8> {
756 let mut stream = Vec::<u8>::with_capacity(18530);
757 stream.extend_from_slice(&Self::HEAD.to_le_bytes());
759 stream.push(self.data_type as u8);
760 stream.push(self.status as u8);
761 let n_hits = self.hits.len() as u8;
764 stream.push(n_hits);
765 stream.extend_from_slice(&self.header.to_bytestream());
766 let add_channels = !self.header.is_event_fragment() & !self.header.drs_lost_trigger();
768 if add_channels {
769 for n in 0..NCHN {
770 for k in 0..NWORDS {
771 if self.adc[n].len() == 0 {
772 continue;
773 }
774 stream.extend_from_slice(&self.adc[n][k].to_le_bytes());
775 }
776 }
777 }
782 for h in self.hits.iter() {
786 stream.extend_from_slice(&h.to_bytestream());
787 }
788 stream.extend_from_slice(&Self::TAIL.to_le_bytes());
789 stream
790 }
791}
792
793impl Default for RBEvent {
794
795 fn default () -> Self {
796 Self::new()
797 }
798}
799
800impl fmt::Display for RBEvent {
801 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
802 let mut adc = Vec::<usize>::new();
803 for k in 0..self.adc.len() -1 {
804 adc.push(self.adc[k].len());
805 }
806 let mut ch9_str = String::from("[");
807 for k in self.adc[8].iter().take(5) {
808 ch9_str += &k.to_string();
809 ch9_str += ","
810 }
811 ch9_str += " .. :";
812 ch9_str += &self.adc[8].len().to_string();
813 ch9_str += "]";
814 let mut ch_field = String::from("[\n");
815 for (ch, vals) in self.adc.iter().enumerate() {
816 if ch == 8 {
817 continue;
818 }
819 let label = (ch + 1).to_string();
820 ch_field += " [ch ";
821 ch_field += &ch.to_string();
822 ch_field += "('";
823 ch_field += &label;
824 ch_field += "') ";
825 for n in vals.iter().take(5) {
826 ch_field += &n.to_string();
827 ch_field += ",";
828 }
829 ch_field += "..:";
830 ch_field += &vals.len().to_string();
831 ch_field += "]\n";
832 }
833 ch_field += "]\n";
834 write!(f, "<RBEvent
835 data type : {},
836 event status : {},
837 {}
838 .. ..
839 has ch9 : {},
840 -> ch9 : {},
841 data channels :
842 -> {},
843 n hits : {},
844.. .. .. .. .. .. .. .. >",
845 self.data_type,
846 self.status,
847 self.header,
848 self.header.has_ch9(),
849 ch9_str,
850 ch_field,
851 self.hits.len())
852 }
853}
854
855#[cfg(feature = "random")]
856impl FromRandom for RBEvent {
857
858 fn from_random() -> Self {
859 let mut event = RBEvent::new();
860 let header = RBEventHeader::from_random();
861 let mut rng = rand::thread_rng();
862 event.data_type = DataType::from_random();
863 event.status = EventStatus::from_random();
864 event.header = header;
865 event.header.status_byte = 0;
872 for ch in event.header.get_channels().iter() {
874 let random_numbers: Vec<u16> = (0..NWORDS).map(|_| rng.gen()).collect();
875 event.adc[*ch as usize] = random_numbers;
876 }
877 event
879 }
880}
881
882
883impl From<&TofPacket> for RBEvent {
884 fn from(pk : &TofPacket) -> Self {
885 match pk.packet_type {
886 PacketType::RBEvent => {
899 match RBEvent::from_bytestream(&pk.payload, &mut 0) {
900 Ok(event) => {
901 return event;
902 }
903 Err(err) => {
904 error!("Can not decode RBEvent - will return empty event! {err}");
905 return RBEvent::new();
906 }
907 }
908 },
909 PacketType::RBEventMemoryView => {
910 let mut streamer = RBEventMemoryStreamer::new();
911 streamer.add(&pk.payload, pk.payload.len());
912 match streamer.get_event_at_pos_unchecked(None) {
913 None => {
914 return RBEvent::new();
915 },
916 Some(ev) => {
917 return ev;
918 }
919 }
920 },
921
922 _ => {
923 error!("Can not deal with {}! Returning empty event", pk);
924 return RBEvent::new();
925 }
926 }
927 }
928}
929
930
931#[derive(Debug, Clone, PartialEq)]
936pub struct RBEventHeader {
937 pub rb_id : u8 ,
941 pub event_id : u32 ,
944 pub stop_cell : u16 ,
947 pub pid_ch12 : u8,
949 pub pid_ch34 : u8,
951 pub pid_ch56 : u8,
953 pub pid_ch78 : u8,
955 pub pid_ch_order : u8,
957 pub rsvd1 : u8,
959 pub rsvd2 : u8,
961 pub rsvd3 : u8,
963 pub fpga_temp : u16,
966 pub drs_deadtime : u16,
969 pub timestamp32 : u32,
970 pub timestamp16 : u16,
971 pub deadtime_instead_temp : bool,
974 status_byte : u8,
977 channel_mask : u16,
987}
988
989impl RBEventHeader {
990
991 pub fn new() -> Self {
992 Self {
993 rb_id : 0,
994 status_byte : 0,
995 event_id : 0,
996 channel_mask : 0,
997 stop_cell : 0,
998 pid_ch12 : 0,
999 pid_ch34 : 0,
1000 pid_ch56 : 0,
1001 pid_ch78 : 0,
1002 pid_ch_order : 0,
1003 rsvd1 : 0,
1004 rsvd2 : 0,
1005 rsvd3 : 0,
1006 fpga_temp : 0,
1007 drs_deadtime : 0,
1008 timestamp32 : 0,
1009 timestamp16 : 0,
1010 deadtime_instead_temp : false,
1011 }
1012 }
1013
1014 pub fn set_channel_mask(&mut self, channel_mask : u16) {
1019 if self.deadtime_instead_temp {
1020 self.channel_mask = 2u16.pow(15) | channel_mask;
1021 } else {
1022 self.channel_mask = channel_mask;
1023 }
1024 }
1025
1026 pub fn get_channel_mask(&self) -> u16 {
1030 self.channel_mask & 0x1ff
1031 }
1032
1033 pub fn parse_channel_mask(ch_mask : u16) -> (bool, u16) {
1039 let channel_mask : u16;
1040 let deadtime_instead_temp : bool
1041 = ch_mask >> 15 == 1;
1042 channel_mask = ch_mask & 0x1ff;
1043 (deadtime_instead_temp, channel_mask)
1044 }
1045
1046 pub fn extract_eventid_from_rbheader(stream :&Vec<u8>) -> u32 {
1048 let event_id = parse_u32(stream, &mut 3); event_id
1052 }
1053
1054 pub fn is_event_fragment(&self) -> bool {
1055 self.status_byte & 1 > 0
1056 }
1057
1058 pub fn drs_lost_trigger(&self) -> bool {
1059 (self.status_byte >> 1) & 1 > 0
1060 }
1061
1062 pub fn lost_lock(&self) -> bool {
1063 (self.status_byte >> 2) & 1 > 0
1064 }
1065
1066 pub fn lost_lock_last_sec(&self) -> bool {
1067 (self.status_byte >> 3) & 1 > 0
1068 }
1069
1070 pub fn is_locked(&self) -> bool {
1071 !self.lost_lock()
1072 }
1073
1074 pub fn is_locked_last_sec(&self) -> bool {
1075 !self.lost_lock_last_sec()
1076 }
1077
1078 pub fn parse_status(&mut self, status_bytes : u16) {
1080 self.status_byte = (status_bytes & 0xf) as u8;
1082 self.fpga_temp = status_bytes >> 4;
1083 }
1084
1085 pub fn get_fpga_temp(&self) -> f32 {
1087 let zynq_temp = (((self.fpga_temp & 4095) as f32 * 503.975) / 4096.0) - 273.15;
1088 zynq_temp
1089 }
1090
1091 pub fn has_ch9(&self) -> bool {
1094 self.channel_mask & 256 > 0
1095 }
1096
1097 pub fn get_rbpaddleid(&self) -> RBPaddleID {
1098 let mut pid = RBPaddleID::new();
1099 pid.paddle_12 = self.pid_ch12;
1100 pid.paddle_34 = self.pid_ch34;
1101 pid.paddle_56 = self.pid_ch56;
1102 pid.paddle_78 = self.pid_ch78;
1103 pid.channel_order = self.pid_ch_order;
1104 pid
1105 }
1106
1107 pub fn set_rbpaddleid(&mut self, pid : &RBPaddleID) {
1108 self.pid_ch12 = pid.paddle_12;
1109 self.pid_ch34 = pid.paddle_34;
1110 self.pid_ch56 = pid.paddle_56;
1111 self.pid_ch78 = pid.paddle_78;
1112 self.pid_ch_order = pid.channel_order;
1113 }
1114
1115 pub fn get_channels(&self) -> Vec<u8> {
1122 let mut channels = Vec::<u8>::with_capacity(8);
1123 for k in 0..9 {
1124 if self.channel_mask & (1 << k) > 0 {
1125 channels.push(k);
1126 }
1127 }
1128 channels
1129 }
1130
1131 pub fn get_active_paddles(&self) -> Vec<(u8,bool)> {
1133 let mut active_paddles = Vec::<(u8,bool)>::new();
1136 let active_channels = self.get_channels();
1137 let pid = self.get_rbpaddleid();
1138 let mut ch0_pair_done = false;
1139 let mut ch2_pair_done = false;
1140 let mut ch4_pair_done = false;
1141 let mut ch6_pair_done = false;
1142 for ch in active_channels {
1143 if (ch == 0 || ch == 1) && !ch0_pair_done {
1144 active_paddles.push(pid.get_paddle_id(ch));
1145 ch0_pair_done = true;
1146 }
1147 if (ch == 2 || ch == 3) && !ch2_pair_done {
1148 active_paddles.push(pid.get_paddle_id(ch));
1149 ch2_pair_done = true;
1150 }
1151 if (ch == 4 || ch == 5) && !ch4_pair_done {
1152 active_paddles.push(pid.get_paddle_id(ch));
1153 ch4_pair_done = true;
1154 }
1155 if (ch == 6 || ch == 7) && !ch6_pair_done {
1156 active_paddles.push(pid.get_paddle_id(ch));
1157 ch6_pair_done = true;
1158 }
1159 }
1160 active_paddles
1161 }
1162
1163 pub fn get_nchan(&self) -> usize {
1165 self.get_channels().len()
1166 }
1167
1168 pub fn get_timestamp48(&self) -> u64 {
1169 ((self.timestamp16 as u64) << 32) | self.timestamp32 as u64
1170 }
1171}
1172
1173impl Default for RBEventHeader {
1174 fn default() -> Self {
1175 Self::new()
1176 }
1177}
1178
1179
1180impl fmt::Display for RBEventHeader {
1181 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1182 let mut repr = String::from("<RBEventHeader:");
1183 repr += &(format!("\n RB ID {}",self.rb_id ));
1184 repr += &(format!("\n event id {}",self.event_id ));
1185 repr += &(format!("\n ch mask {}",self.channel_mask ));
1186 repr += &(format!("\n has ch9 {}",self.has_ch9() ));
1187 repr += &(format!("\n ch mapping {}",self.get_rbpaddleid() ));
1188 if self.deadtime_instead_temp {
1189 repr += &(format!("\n DRS deadtime : {:.2}", self.drs_deadtime));
1190 } else {
1191 repr += &(format!("\n FPGA T [\u{00B0}C] : {:.2}", self.get_fpga_temp()));
1192 }
1193 repr += &(format!("\n timestamp32 {}", self.timestamp32 ));
1194 repr += &(format!("\n timestamp16 {}", self.timestamp16 ));
1195 repr += &(format!("\n |-> timestamp48 {}", self.get_timestamp48() ));
1196 repr += &(format!("\n stop cell {}", self.stop_cell ));
1197 let mut perfect = true;
1200 if self.drs_lost_trigger() {
1201 repr += &"\n !! DRS4 REPORTS LOST TRIGGER!".red().bold();
1202 perfect = false;
1203 }
1204 if self.is_event_fragment() {
1205 repr += &"\n !! EVENT FRAGMENT!".red().bold();
1206 perfect = false;
1207 }
1208 if self.lost_lock() {
1209 repr += &"\n !! RB CLOCK IS NOT LOCKED!".yellow().bold();
1210 perfect = false;
1211 }
1212 if self.lost_lock_last_sec() {
1213 repr += &"\n !! RB CLOCK HAS LOST ITS LOCK WITHIN THE LAST SECOND!".yellow().bold();
1214 perfect = false;
1215 }
1216 if perfect {
1217 repr += &"\n -- locked: YES, locked last second; YES, no event fragemnet, and no lost trigger!".green();
1218 }
1219 repr += ">";
1220 write!(f, "{}", repr)
1221 }
1222}
1223
1224impl Serialization for RBEventHeader {
1225
1226 const HEAD : u16 = 0xAAAA;
1227 const TAIL : u16 = 0x5555;
1228 const SIZE : usize = 30; fn from_bytestream(stream : &Vec<u8>, pos : &mut usize)
1231 -> Result<Self, SerializationError> {
1232 let mut header = Self::new();
1233 Self::verify_fixed(stream, pos)?;
1234 header.rb_id = parse_u8 (stream, pos);
1235 header.event_id = parse_u32(stream, pos);
1236 let ch_mask = parse_u16(stream, pos);
1237 let (deadtime_instead_temp, channel_mask)
1238 = Self::parse_channel_mask(ch_mask);
1239 header.deadtime_instead_temp = deadtime_instead_temp;
1240 header.set_channel_mask(channel_mask);
1241 header.status_byte = parse_u8 (stream, pos);
1242 header.stop_cell = parse_u16(stream, pos);
1243 header.pid_ch12 = parse_u8(stream, pos);
1244 header.pid_ch34 = parse_u8(stream, pos);
1245 header.pid_ch56 = parse_u8(stream, pos);
1246 header.pid_ch78 = parse_u8(stream, pos);
1247 header.pid_ch_order = parse_u8(stream, pos);
1248 header.rsvd1 = parse_u8(stream, pos);
1249 header.rsvd2 = parse_u8(stream, pos);
1250 header.rsvd3 = parse_u8(stream, pos);
1251 if deadtime_instead_temp {
1252 header.drs_deadtime = parse_u16(stream, pos);
1253 } else {
1254 header.fpga_temp = parse_u16(stream, pos);
1255 }
1256 header.timestamp32 = parse_u32(stream, pos);
1257 header.timestamp16 = parse_u16(stream, pos);
1258 *pos += 2; Ok(header)
1260 }
1261
1262
1263 fn to_bytestream(&self) -> Vec<u8> {
1264 let mut stream = Vec::<u8>::with_capacity(Self::SIZE);
1265 stream.extend_from_slice(&Self::HEAD.to_le_bytes());
1266 stream.extend_from_slice(&self.rb_id .to_le_bytes());
1267 stream.extend_from_slice(&self.event_id .to_le_bytes());
1268 let ch_mask = ((self.deadtime_instead_temp as u16) << 15) | self.get_channel_mask();
1269 stream.extend_from_slice(&ch_mask .to_le_bytes());
1270 stream.extend_from_slice(&self.status_byte .to_le_bytes());
1271 stream.extend_from_slice(&self.stop_cell .to_le_bytes());
1272 stream.push(self.pid_ch12 );
1273 stream.push(self.pid_ch34 );
1274 stream.push(self.pid_ch56 );
1275 stream.push(self.pid_ch78 );
1276 stream.push(self.pid_ch_order);
1277 stream.push(self.rsvd1 );
1278 stream.push(self.rsvd2 );
1279 stream.push(self.rsvd3 );
1280 if self.deadtime_instead_temp {
1281 stream.extend_from_slice(&self.drs_deadtime .to_le_bytes());
1282 } else {
1283 stream.extend_from_slice(&self.fpga_temp .to_le_bytes());
1284 }
1285 stream.extend_from_slice(&self.timestamp32 .to_le_bytes());
1286 stream.extend_from_slice(&self.timestamp16 .to_le_bytes());
1287 stream.extend_from_slice(&RBEventHeader::TAIL.to_le_bytes());
1288 stream
1289 }
1290}
1291
1292#[cfg(feature = "random")]
1293impl FromRandom for RBEventHeader {
1294
1295 fn from_random() -> Self {
1296 let mut header = RBEventHeader::new();
1297 let mut rng = rand::thread_rng();
1298
1299 header.rb_id = rng.gen::<u8>();
1300 header.event_id = rng.gen::<u32>();
1301 header.status_byte = rng.gen::<u8>();
1302 header.stop_cell = rng.gen::<u16>();
1303 header.pid_ch12 = rng.gen::<u8>();
1304 header.pid_ch34 = rng.gen::<u8>();
1305 header.pid_ch56 = rng.gen::<u8>();
1306 header.pid_ch78 = rng.gen::<u8>();
1307 header.pid_ch_order = rng.gen::<u8>();
1308 header.rsvd1 = rng.gen::<u8>();
1309 header.rsvd2 = rng.gen::<u8>();
1310 header.rsvd3 = rng.gen::<u8>();
1311 header.deadtime_instead_temp = rng.gen::<bool>();
1312 if header.deadtime_instead_temp {
1313 header.drs_deadtime = rng.gen::<u16>();
1314 } else {
1315 header.fpga_temp = rng.gen::<u16>();
1316 }
1317 let ch_mask = rng.gen::<u16>() & 0x1ff;
1319 header.set_channel_mask(ch_mask);
1320 header.timestamp32 = rng.gen::<u32>();
1321 header.timestamp16 = rng.gen::<u16>();
1322 header
1323 }
1324}
1325
1326#[derive(Debug, Clone, PartialEq)]
1327pub struct RBWaveform {
1328 pub event_id : u32,
1329 pub rb_id : u8,
1330 pub rb_channel_a : u8,
1332 pub rb_channel_b : u8,
1333 pub stop_cell : u16,
1335 pub adc_a : Vec<u16>,
1336 pub adc_b : Vec<u16>,
1337 pub paddle_id : u8,
1338 pub voltages_a : Vec<f32>,
1339 pub nanoseconds_a : Vec<f32>,
1340 pub voltages_b : Vec<f32>,
1341 pub nanoseconds_b : Vec<f32>
1342}
1343
1344impl RBWaveform {
1345
1346 pub fn new() -> Self {
1347 Self {
1348 event_id : 0,
1349 rb_id : 0,
1350 rb_channel_a : 0,
1351 rb_channel_b : 0,
1352 stop_cell : 0,
1353 paddle_id : 0,
1354 adc_a : Vec::<u16>::new(),
1355 voltages_a : Vec::<f32>::new(),
1356 nanoseconds_a : Vec::<f32>::new(),
1357 adc_b : Vec::<u16>::new(),
1358 voltages_b : Vec::<f32>::new(),
1359 nanoseconds_b : Vec::<f32>::new()
1360 }
1361 }
1362
1363 pub fn calibrate(&mut self, cali : &RBCalibrations) -> Result<(), CalibrationError> {
1364 if cali.rb_id != self.rb_id {
1365 error!("Calibration is for board {}, but wf is for {}", cali.rb_id, self.rb_id);
1366 return Err(CalibrationError::WrongBoardId);
1367 }
1368 let mut voltages = vec![0.0f32;1024];
1369 let mut nanosecs = vec![0.0f32;1024];
1370 cali.voltages(self.rb_channel_a as usize + 1,
1371 self.stop_cell as usize,
1372 &self.adc_a,
1373 &mut voltages);
1374 self.voltages_a = voltages.clone();
1375 cali.nanoseconds(self.rb_channel_a as usize + 1,
1376 self.stop_cell as usize,
1377 &mut nanosecs);
1378 self.nanoseconds_a = nanosecs.clone();
1379 cali.voltages(self.rb_channel_b as usize + 1,
1380 self.stop_cell as usize,
1381 &self.adc_b,
1382 &mut voltages);
1383 self.voltages_b = voltages;
1384 cali.nanoseconds(self.rb_channel_b as usize + 1,
1385 self.stop_cell as usize,
1386 &mut nanosecs);
1387 self.nanoseconds_b = nanosecs;
1388 Ok(())
1389 }
1390
1391 pub fn apply_spike_filter(&mut self) {
1393 clean_spikes(&mut self.voltages_a, true);
1394 clean_spikes(&mut self.voltages_b, true);
1395 }
1396}
1397
1398impl Packable for RBWaveform {
1399 const PACKET_TYPE : PacketType = PacketType::RBWaveform;
1400}
1401
1402impl Serialization for RBWaveform {
1403 const HEAD : u16 = 43690; const TAIL : u16 = 21845; fn from_bytestream(stream : &Vec<u8>, pos : &mut usize)
1407 -> Result<Self, SerializationError> {
1408 let mut wf = RBWaveform::new();
1409 if parse_u16(stream, pos) != Self::HEAD {
1410 error!("The given position {} does not point to a valid header signature of {}", pos, Self::HEAD);
1411 return Err(SerializationError::HeadInvalid {});
1412 }
1413 wf.event_id = parse_u32(stream, pos);
1414 wf.rb_id = parse_u8 (stream, pos);
1415 wf.rb_channel_a = parse_u8 (stream, pos);
1416 wf.rb_channel_b = parse_u8 (stream, pos);
1417 wf.stop_cell = parse_u16(stream, pos);
1418 wf.paddle_id = parse_u8 (stream, pos);
1419 if stream.len() < *pos+2*NWORDS {
1420 return Err(SerializationError::StreamTooShort);
1421 }
1422 let data_a = &stream[*pos..*pos+2*NWORDS];
1423 wf.adc_a = u8_to_u16(data_a);
1424 *pos += 2*NWORDS;
1425 let data_b = &stream[*pos..*pos+2*NWORDS];
1426 wf.adc_b = u8_to_u16(data_b);
1427 *pos += 2*NWORDS;
1428 if parse_u16(stream, pos) != Self::TAIL {
1429 error!("The given position {} does not point to a tail signature of {}", pos, Self::TAIL);
1430 return Err(SerializationError::TailInvalid);
1431 }
1432 Ok(wf)
1433 }
1434
1435 fn to_bytestream(&self) -> Vec<u8> {
1436 let mut stream = Vec::<u8>::new();
1437 stream.extend_from_slice(&Self::HEAD.to_le_bytes());
1438 stream.extend_from_slice(&self.event_id.to_le_bytes());
1439 stream.extend_from_slice(&self.rb_id.to_le_bytes());
1440 stream.extend_from_slice(&self.rb_channel_a.to_le_bytes());
1441 stream.extend_from_slice(&self.rb_channel_b.to_le_bytes());
1442 stream.extend_from_slice(&self.stop_cell.to_le_bytes());
1443 stream.push(self.paddle_id);
1444 if self.adc_a.len() != 0 {
1445 for k in 0..NWORDS {
1446 stream.extend_from_slice(&self.adc_a[k].to_le_bytes());
1447 }
1448 }
1449 if self.adc_b.len() != 0 {
1450 for k in 0..NWORDS {
1451 stream.extend_from_slice(&self.adc_b[k].to_le_bytes());
1452 }
1453 }
1454 stream.extend_from_slice(&Self::TAIL.to_le_bytes());
1455 stream
1456 }
1457}
1458
1459impl fmt::Display for RBWaveform {
1460 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1461 let mut repr = String::from("<RBWaveform:");
1462 repr += &(format!("\n Event ID : {}", self.event_id));
1463 repr += &(format!("\n RB : {}", self.rb_id));
1464 repr += &(format!("\n ChannelA : {}", self.rb_channel_a));
1465 repr += &(format!("\n ChannelB : {}", self.rb_channel_b));
1466 repr += &(format!("\n Paddle ID : {}", self.paddle_id));
1467 repr += &(format!("\n Stop cell : {}", self.stop_cell));
1468 if self.adc_a.len() >= 273 {
1469 repr += &(format!("\n adc [A] [{}] : .. {} {} {} ..",self.adc_a.len(), self.adc_a[270], self.adc_a[271], self.adc_a[272]));
1470 } else {
1471 repr += &(String::from("\n adc [A] [EMPTY]"));
1472 }
1473 if self.adc_b.len() >= 273 {
1474 repr += &(format!("\n adc [B] [{}] : .. {} {} {} ..",self.adc_b.len(), self.adc_b[270], self.adc_b[271], self.adc_b[272]));
1475 } else {
1476 repr += &(String::from("\n adc [B] [EMPTY]"));
1477 }
1478 write!(f, "{}", repr)
1479 }
1480}
1481
1482#[cfg(feature = "random")]
1483impl FromRandom for RBWaveform {
1484
1485 fn from_random() -> Self {
1486 let mut wf = Self::new();
1487 let mut rng = rand::thread_rng();
1488 wf.event_id = rng.gen::<u32>();
1489 wf.rb_id = rng.gen::<u8>();
1490 wf.rb_channel_a = rng.gen::<u8>();
1491 wf.rb_channel_b = rng.gen::<u8>();
1492 wf.stop_cell = rng.gen::<u16>();
1493 wf.paddle_id = rng.gen::<u8>();
1494 let random_numbers_a: Vec<u16> = (0..NWORDS).map(|_| rng.gen()).collect();
1495 wf.adc_a = random_numbers_a;
1496 let random_numbers_b: Vec<u16> = (0..NWORDS).map(|_| rng.gen()).collect();
1497 wf.adc_b = random_numbers_b;
1498 wf
1499 }
1500}
1501
1502#[test]
1503#[cfg(feature = "random")]
1504fn pack_rbwaveform() {
1505 for _ in 0..100 {
1506 let wf = RBWaveform::from_random();
1507 let test : RBWaveform = wf.pack().unpack().unwrap();
1508 assert_eq!(wf, test);
1509 }
1510}
1511
1512#[test]
1513#[cfg(feature = "random")]
1514fn pack_rbpaddleid() {
1515 for _ in 0..100 {
1516 let pid = RBPaddleID::from_random();
1517 let test = pid.to_u64();
1518 let pid_back = RBPaddleID::from_u64(test);
1519 assert_eq!(pid, pid_back);
1520 }
1521}
1522
1523#[cfg(feature = "database")]
1524#[cfg(feature = "random")]
1525#[test]
1526fn rbpaddleid_from_rb() {
1527let mut rng = rand::thread_rng();
1528 let channels = vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 7u8];
1529 for _ in 0..100 {
1530 let mut rb = ReadoutBoard::new();
1531 rb.paddle12.paddle_id = rng.gen::<u8>() as i16;
1532 let mut idx = rng.gen_range(0..2);
1533 rb.paddle12_chA = channels[idx];
1534 idx = rng.gen_range(2..4);
1535 rb.paddle34.paddle_id = rng.gen::<u8>() as i16;
1536 rb.paddle34_chA = channels[idx];
1537 idx = rng.gen_range(4..6);
1538 rb.paddle56.paddle_id = rng.gen::<u8>() as i16;
1539 rb.paddle56_chA = channels[idx];
1540 idx = rng.gen_range(6..8);
1541 rb.paddle78.paddle_id = rng.gen::<u8>() as i16;
1542 rb.paddle78_chA = channels[idx];
1543
1544 let pid = RBPaddleID::from_rb(&rb);
1545 assert_eq!(pid.paddle_12, rb.paddle12.paddle_id as u8);
1546 assert_eq!(pid.paddle_34, rb.paddle34.paddle_id as u8);
1547 assert_eq!(pid.paddle_56, rb.paddle56.paddle_id as u8);
1548 assert_eq!(pid.paddle_78, rb.paddle78.paddle_id as u8);
1549 for ch in &channels {
1550 if pid.get_order_flipped(*ch) {
1551 if *ch == 1 || *ch == 2 {
1552 assert_eq!(rb.paddle12_chA,2);
1553 }
1554 if *ch == 3 || *ch == 4 {
1555 assert_eq!(rb.paddle34_chA,4);
1556 }
1557 if *ch == 5 || *ch == 6 {
1558 assert_eq!(rb.paddle56_chA,6);
1559 }
1560 if *ch == 7 || *ch == 8 {
1561 assert_eq!(rb.paddle78_chA,8);
1562 }
1563 }
1564 }
1565 }
1566}
1567
1568#[cfg(all(test,feature = "random"))]
1569mod test_rbevents {
1570 use crate::serialization::Serialization;
1571 use crate::FromRandom;
1572 use crate::events::{
1573 RBEvent,
1574 RBEventHeader,
1575 };
1576
1577 #[test]
1578 fn serialization_rbeventheader() {
1579 for _ in 0..100 {
1580 let mut pos = 0usize;
1581 let head = RBEventHeader::from_random();
1582 println!("{}", head);
1583 let stream = head.to_bytestream();
1584 assert_eq!(stream.len(), RBEventHeader::SIZE);
1585 let test = RBEventHeader::from_bytestream(&stream, &mut pos).unwrap();
1586 println!("{}", test);
1587 assert_eq!(pos, RBEventHeader::SIZE);
1588 assert_eq!(head, test);
1589 assert_eq!(head.lost_lock() , test.lost_lock());
1590 assert_eq!(head.lost_lock_last_sec(), test.lost_lock_last_sec());
1591 assert_eq!(head.drs_lost_trigger() , test.drs_lost_trigger());
1592 assert_eq!(head, test);
1593 }
1594 }
1595
1596 #[test]
1597 fn serialization_rbevent() {
1598 for _ in 0..100 {
1599 let event = RBEvent::from_random();
1600 let stream = event.to_bytestream();
1601 println!("[test rbevent] stream.len() {:?}", stream.len());
1602 let test = RBEvent::from_bytestream(&stream, &mut 0).unwrap();
1603 println!("[test rbevent] event frag {:?}", event.header.is_event_fragment());
1604 println!("[test rbevent] lost trig {:?}", event.header.drs_lost_trigger());
1605 println!("[test rbevent] event frag {:?}", test.header.is_event_fragment());
1606 println!("[test rbevent] lost trig {:?}", test.header.drs_lost_trigger());
1607 assert_eq!(event.header, test.header);
1608 assert_eq!(event.header.get_nchan(), test.header.get_nchan());
1609 assert_eq!(event.header.get_channels(), test.header.get_channels());
1610 assert_eq!(event.data_type, test.data_type);
1611 assert_eq!(event.status, test.status);
1612 assert_eq!(event.adc.len(), test.adc.len());
1613 assert_eq!(event.hits.len(), test.hits.len());
1614 println!("[test rbevent] get_channels() {:?}", event.header.get_channels());
1615 assert_eq!(event.adc[0].len(), test.adc[0].len());
1616 assert_eq!(event.adc[1].len(), test.adc[1].len());
1617 assert_eq!(event.adc[2].len(), test.adc[2].len());
1618 assert_eq!(event.adc[3].len(), test.adc[3].len());
1619 assert_eq!(event.adc[4].len(), test.adc[4].len());
1620 assert_eq!(event.adc[5].len(), test.adc[5].len());
1621 assert_eq!(event.adc[6].len(), test.adc[6].len());
1622 assert_eq!(event.adc[7].len(), test.adc[7].len());
1623 assert_eq!(event.adc[8].len(), test.adc[8].len());
1624 assert_eq!(event.adc[0], test.adc[0]);
1625 assert_eq!(event.adc[1], test.adc[1]);
1626 assert_eq!(event.adc[2], test.adc[2]);
1627 assert_eq!(event.adc[3], test.adc[3]);
1628 assert_eq!(event.adc[4], test.adc[4]);
1629 assert_eq!(event.adc[5], test.adc[5]);
1630 assert_eq!(event.adc[6], test.adc[6]);
1631 assert_eq!(event.adc[7], test.adc[7]);
1632 assert_eq!(event.adc[8], test.adc[8]);
1633 }
1644 }
1645}