tof_dataclasses/events/
rb_event.rs

1//! Readoutboard binary event formats, former denoted as BLOB (binary large object)
2//! 
3//! The structure is the following
4//!
5//!
6//! - RBEventHeader  - timestamp, status, len of event, but no channel data. This
7//!                    represents compression level 2
8//!
9//! - RBEvent        - still "raw" event, however, with modified fields 
10//!                    (removed superflous ones, changed meaning of some others)
11//!                    Each RBEvent has a header and a body which is the channel 
12//!                    data. Data in this form represents compression level 1
13//!
14//! - RBWaveform     - a single waveform from a single RB. This can be used to 
15//!                    deconstruct TofEvents so that the flight computer does not
16//!                    struggle with the large packet size.
17//!
18//! 
19//! * features: "random" - provides "::from_random" for all structs allowing to 
20//!   populate them with random data for tests.
21//!
22
23use std::fmt;
24//use std::collections::HashMap;
25use 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/// Squeze the rb channel - paddle mapping into 5 bytes
71/// for a single RB
72#[derive(Debug, Copy, Clone, PartialEq)]
73pub struct RBPaddleID {
74  /// Paddle connected to RB channel 1/2
75  pub paddle_12     : u8,
76  /// Paddle connected to RB channel 3/4
77  pub paddle_34     : u8,
78  /// Paddle connected to RB channel 5/6
79  pub paddle_56     : u8,
80  /// Paddle connected to RB channel 7/8
81  pub paddle_78     : u8,
82  /// Order - 1 if the smaller channel is the 
83  /// A side, 2, if the smaller channel is the 
84  /// B side
85  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  /// Typically, the A-side will be connected to a lower channel id
124  ///
125  /// If the order is flipped, the lower channel will be connected to 
126  /// the B-side
127  ///
128  /// # Arguments
129  /// * channel : RB channel (1-8)
130  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  /// Get the paddle id together with the information 
264  /// if this is the A side
265  ///
266  /// channel in rb channels (starts at 1)
267  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
305/// Get the traces for a set of RBEvents
306///
307/// This will return a cube of 
308/// The sice of this cube will be fixed
309/// in two dimensions, but not the third
310///
311/// The rationale of this is to be able 
312/// to quickly calculate means over all
313/// channels.
314///
315/// Shape
316/// \[ch:9\]\[nevents\]\[adc_bin:1024\]
317///
318/// # Args:
319///   events - events to get the traces from
320pub 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/// Event data for each individual ReadoutBoard (RB)
370///
371/// 
372///
373#[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  /// Check if we have all the channel data even as 
412  /// indicated by the header
413  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  /// Deconstruct the RBEvent to form RBWaveforms
429  pub fn get_rbwaveforms(&self) -> Vec<RBWaveform> {
430    // FIXME - fix it, this drives me crazy
431    let mut waveforms   = Vec::<RBWaveform>::new();
432    // at max, we can have 4 waveform packets
433    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        // then b is channel 1 (or 0)
444        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        // channel order flipped!
465        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        // then b is channel 1 (or 0)
486        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        // then b is channel 1 (or 0)
507        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  /// Get the datatype from a bytestream when we know
523  /// that it is an RBEvent
524  ///
525  /// The data type is encoded in byte 3
526  pub fn extract_datatype(stream : &Vec<u8>) -> Result<DataType, SerializationError> {
527    if stream.len() < 3 {
528      return Err(SerializationError::StreamTooShort);
529    }
530    // TODO This might panic! Is it ok?
531    Ok(DataType::try_from(stream[2]).unwrap_or(DataType::Unknown))
532  }
533  
534  /// decode the len field in the in memroy represention of 
535  /// RBEventMemoryView
536  pub fn get_channel_packet_len(stream : &Vec<u8>, pos : usize) -> Result<(usize, Vec::<u8>), SerializationError> {
537    // len is at position 4 
538    // roi is at postion 6
539    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; // len is in 2byte words
544    if packet_len < 44 {
545      // There is only header data 
546      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; // roi is max bin (first is 0)
550    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    //println!("========================================");
560    //println!("{} {} {}", nchan, nwords, nchan_data);
561    //println!("========================================");
562    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; // trailer
574    }
575    debug!("Got channel ids {:?}", ch_ids);
576    Ok((nchan_data.into(), ch_ids))
577  }
578
579  /// Get the event id from a RBEvent represented by bytestream
580  /// without decoding the whole event
581  ///
582  /// This should be faster than decoding the whole event.
583  pub fn extract_eventid(stream : &Vec<u8>) -> Result<u32, SerializationError> {
584    if stream.len() < 30 {
585      return Err(SerializationError::StreamTooShort);
586    }
587    // event header starts at position 7
588    // in the header, it is as positon 3
589    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  /// Similar to the "official" from_bytestream, this will get the 
614  /// event from a bytestream, omitting the waveforms. This will allow
615  /// for a faster readout in case waveforms are not needed.
616  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 nchan_data  = parse_u8(stream, pos);
626    let n_hits      = parse_u8(stream, pos);
627    event.header    = RBEventHeader::from_bytestream(stream, pos)?;
628    //let ch_ids      = event.header.get_active_data_channels();
629    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      // the event fragment won't have channel data, so 
635      // let's move on to the next TAIL marker:ta
636      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    // here is the only change to from_bytestream. 
646    // We are simply skipping the waveforms, but 
647    // still read the hits
648    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      // 2*NWORDS because stream is Vec::<u8> and it is 16 bit words.
657      *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 nchan_data  = parse_u8(stream, pos);
699    let n_hits      = parse_u8(stream, pos);
700    event.header    = RBEventHeader::from_bytestream(stream, pos)?;
701    //let ch_ids      = event.header.get_active_data_channels();
702    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      // the event fragment won't have channel data, so 
708      // let's move on to the next TAIL marker:ta
709      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      // 2*NWORDS because stream is Vec::<u8> and it is 16 bit words.
727      let data = &stream[*pos..*pos+2*NWORDS];
728      //event.adc[k as usize] = u8_to_u16(data);
729      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    //println!("{:?}", &stream[*pos-10..*pos+2]);
747    //println!("{} {}", pos, stream.len());
748    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    //let mut stream = Vec::<u8>::new();
758    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 nchan_data  = self.adc.len() as u8;
762    //stream.push(nchan_data);
763    let n_hits      = self.hits.len() as u8;
764    stream.push(n_hits);
765    stream.extend_from_slice(&self.header.to_bytestream());
766    // for an empty channel, we will add an empty vector
767    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      // this is way slower
778      //for channel_adc in self.adc.iter() {
779      //  stream.extend_from_slice(&u16_to_u8(&channel_adc)); 
780      //}
781    }
782    //if self.ch9_adc.len() > 0 {
783    //  stream.extend_from_slice(&u16_to_u8(&self.ch9_adc));
784    //}
785    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    // set a good status byte. RBEvents from 
866    // random will always be good
867    // status_byte is tested in RBEventHeader test
868    // and here we want to make sure channel data 
869    // gets serialized
870    // status byte of 0 means it is good
871    event.header.status_byte = 0;
872    //if !event.header.event_fragment && !event.header.lost_trigger {
873    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    //}
878    event
879  }
880}
881
882
883impl From<&TofPacket> for RBEvent {
884  fn from(pk : &TofPacket) -> Self {
885    match pk.packet_type {
886      //PacketType::RBEventMemoryView => {
887      //  match RBEvent::extract_from_rbeventmemoryview(&pk.payload, &mut 0) {
888      //    Ok(event) => {
889      //      return event;
890      //    }
891      //    Err(err) => { 
892      //      error!("Can not get RBEvent from RBEventMemoryView! Error {err}!");
893      //      error!("Returning empty event!");
894      //      return RBEvent::new();
895      //    }
896      //  }
897      //},
898      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/// The RBEvent header gets generated once per event
932/// per RB. 
933/// Contains information about event id, timestamps,
934/// etc.
935#[derive(Debug, Clone, PartialEq)]
936pub struct RBEventHeader { 
937  /// Readoutboard ID - should be in the range 1-50
938  /// not consecutive, there are some missing.
939  /// In general, we have 40 boards
940  pub rb_id                : u8   ,
941  /// The event ID as sent from the MTB or self-generated
942  /// if not latched to the MTB
943  pub event_id             : u32  ,
944  /// The DRS stop cell. This is vital information which is
945  /// needed for the calibration
946  pub stop_cell            : u16  , 
947  /// RBPaddleID - component 
948  pub pid_ch12             : u8,
949  /// RBPaddleID - component
950  pub pid_ch34             : u8,
951  /// RBPaddleID - component
952  pub pid_ch56             : u8,
953  /// RBPaddleID - component
954  pub pid_ch78             : u8,
955  /// RBPaddleID - component
956  pub pid_ch_order         : u8,
957  /// Reserved
958  pub rsvd1                : u8,
959  /// Reserved
960  pub rsvd2                : u8,
961  /// Reserved
962  pub rsvd3                : u8,
963  /// The adc value for the temperature
964  /// of the FPGA
965  pub fpga_temp             : u16, 
966  /// DRS deadtime as read out from the 
967  /// register
968  pub drs_deadtime          : u16,
969  pub timestamp32           : u32,
970  pub timestamp16           : u16,
971  /// Store the drs_deadtime instead 
972  /// of the fpga temperature
973  pub deadtime_instead_temp : bool,
974  /// The status byte contains information about lsos of lock
975  /// and event fragments and needs to be decoded
976  status_byte               : u8,
977  /// The channel mask is 9bit for the 9 channels.
978  /// This leaves 7 bits of space so we actually 
979  /// hijack that for the version information 
980  /// 
981  /// Bit 15 will be set 1 in case we are sending
982  /// the DRS_DEADTIME instead of FPGA TEMP
983  ///
984  /// FIXME - make this proper and use ProtocolVersion 
985  ///         instead
986  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  /// Set the channel mask with the 9bit number
1015  ///
1016  /// Set bit 15 to either 1 or 0 depending on
1017  /// deadtime_instead_temp
1018  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  /// Just return the channel mask and strip of 
1027  /// the part which contains the information about
1028  /// drs deadtime or fpga temp
1029  pub fn get_channel_mask(&self) -> u16 {
1030    self.channel_mask & 0x1ff 
1031  }
1032
1033  /// Get the channel mask from a bytestream.
1034  /// 
1035  /// This takes into acount that bit 15 is 
1036  /// used to convey information about if we
1037  /// stored the drs temperature or deadtime
1038  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  /// Only get the eventid from a binary stream
1047  pub fn extract_eventid_from_rbheader(stream :&Vec<u8>) -> u32 {
1048    // event id is 18 bytes in (including HEAD bytes)
1049    // event id is 3 bytes in (including HEAD bytes)
1050    let event_id = parse_u32(stream, &mut 3); // or should it be 5?
1051    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  /// extract lock, drs busy and fpga temp from status field
1079  pub fn parse_status(&mut self, status_bytes : u16) {
1080    // status byte is only 4bit really
1081    self.status_byte        = (status_bytes & 0xf) as u8;
1082    self.fpga_temp = status_bytes >> 4;
1083  }
1084
1085  /// Get the temperature value (Celsius) from the fpga_temp adc.
1086  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  /// Check if the channel 9 is present in the 
1092  /// channel mask
1093  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  /// Decode the channel mask into channel ids.
1116  ///
1117  /// The channel ids inside the memory representation
1118  /// of the RB Event data ("blob") are from 0-7
1119  ///
1120  /// We keep ch9 seperate.
1121  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  /// Get the active paddles
1132  pub fn get_active_paddles(&self) -> Vec<(u8,bool)> {
1133    // FIXME - help. Make this nicer. My brain is fried 
1134    // at this point. Please. I'll be thankful.
1135    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  /// Get the number of data channels + 1 for ch9
1164  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    //repr += &("\n  dtap0            ".to_owned() + &self.dtap0.to_string()); 
1198    //repr += &("\n  crc32            ".to_owned() + &self.crc32.to_string()); 
1199    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; // size in bytes with HEAD and TAIL
1229
1230  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; // account for tail earlier 
1259    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    // make sure the generated channel mask is valid!
1318    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  /// FIXME - this is form 0-8, but should it be from 1-9?
1331  pub rb_channel_a  : u8,
1332  pub rb_channel_b  : u8,
1333  /// DRS4 stop cell
1334  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  /// Apply Jamie's simple spike filter to the calibrated voltages
1392  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; //0xAAAA
1404  const TAIL               : u16    = 21845; //0x5555
1405  
1406  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      //for ch in (event.header.get_channels().iter()){
1634      //  assert_eq!(event.adc[*ch as usize], test.adc[*ch as usize]);
1635      //}
1636      //assert_eq!(event, test);
1637      
1638      //if head.header.event_fragment == test.header.event_fragment {
1639      //  println!("Event fragment found, no channel data available!");
1640      //} else {
1641      //  assert_eq!(head, test);
1642      //}
1643    }
1644  }
1645}