gondola_core/events/
rb_event.rs

1//! This files provides an event structure to pack 
2//! and bookkeep RB data
3//!
4// This file is part of gaps-online-software and published 
5// under the GPLv3 license
6
7use crate::prelude::*;
8
9/// Get the traces for a set of RBEvents
10///
11/// This will return a cube of 
12/// The sice of this cube will be fixed
13/// in two dimensions, but not the third
14///
15/// The rationale of this is to be able 
16/// to quickly calculate means over all
17/// channels.
18///
19/// Shape
20/// \[ch:9\]\[nevents\]\[adc_bin:1024\]
21///
22/// # Args:
23///   events - events to get the traces from
24pub fn unpack_traces<T>(events : &Vec<RBEvent>)
25  -> Vec<Vec<Vec<T>>> 
26  where T: Float + NumAssign + NumCast + Copy {
27  let nevents          = events.len();
28  let mut traces       = Vec::<Vec::<Vec::<T>>>::new();
29  let mut trace        = Vec::<T>::with_capacity(NWORDS);
30  let mut stop_cells   = Vec::<isize>::new();
31  let mut empty_events = Vec::<Vec::<T>>::new();
32  for _ in 0..nevents {
33    empty_events.push(trace.clone());
34  }
35  for ch in 0..NCHN {
36    traces.push(empty_events.clone());
37    for (k,ev) in events.iter().enumerate() {
38      trace.clear();
39      stop_cells.push(ev.header.stop_cell as isize);
40      for k in 0..NWORDS {
41        // the unwrap here can be debated. Technically it does 
42        // only ensure that the cast can be possible
43        trace.push(T::from(ev.adc[ch][k]).unwrap());
44      }
45      traces[ch][k] = trace.clone();
46    }
47  }
48  traces
49}
50
51
52/// Event data for each individual ReadoutBoard (RB)
53#[derive(Debug, Clone, PartialEq)]
54#[cfg_attr(feature="pybindings", pyclass)]
55pub struct RBEvent {
56  pub data_type     : DataType,
57  pub status        : EventStatus,
58  pub header        : RBEventHeader,
59  pub adc           : Vec<Vec<u16>>,
60  pub hits          : Vec<TofHit>,
61  // not getting serialized
62  pub creation_time : Option<Instant>,
63}
64
65impl RBEvent {
66
67  pub fn new() -> Self {
68    let mut adc = Vec::<Vec<u16>>::with_capacity(NCHN);
69    for _ in 0..NCHN {
70      adc.push(Vec::<u16>::new());
71    }
72    Self {
73      data_type     : DataType::Unknown,
74      status        : EventStatus::Unknown,
75      header        : RBEventHeader::new(),
76      adc           : adc,
77      hits          : Vec::<TofHit>::new(),
78      creation_time : Some(Instant::now())
79    }
80  }
81
82  //#[deprecated(since="0.11", note="check seems meaningnless")] 
83  pub fn trace_check(&self) -> bool {
84    let mut check  = true;
85    let mut nchan  = 0usize;
86    let mut failed = true;
87    for ch in self.header.get_channels() {
88      if self.adc[ch as usize].len() != NWORDS {
89        check = false;
90      }
91      for k in &self.adc[ch as usize] {
92        if *k != u16::MAX {
93          // just check that not all bins are 
94          // u16::MAX. They get set to that
95          // value in case of an error
96          // also if that happens to any of 
97          // the channels, throw the whole 
98          // event away.
99          failed = false;
100        }
101      }
102      nchan += 1;
103    }
104    // for the calibration we want to have all 
105    // channels!
106    check && nchan == NCHN && !failed
107  }
108
109  pub fn has_any_mangling_flag(&self) -> bool {
110    match self.status {
111      EventStatus::ChnSyncErrors 
112      | EventStatus::CellSyncErrors
113      | EventStatus::CellAndChnSyncErrors => {
114        return true;
115      }
116      _ => {
117        return false;
118      }
119    }
120  }
121
122  /// Check if we have all the channel data even as 
123  /// indicated by the header
124  pub fn self_check(&self) -> Result<(),AnalysisError>  {
125    let mut pass = false;
126    for ch in self.header.get_channels() {
127      if self.adc[ch as usize].len() == 0 {
128        error!("RB {} expects ch {} but it is empty!", self.header.rb_id, ch + 1);
129        println!("{}", self.header);
130        pass = false;
131      }
132    }
133    if !pass {
134      return Err(AnalysisError::MissingChannel);
135    }
136    Ok(())
137  }
138
139  /// Deconstruct the RBEvent to form RBWaveforms
140  pub fn get_rbwaveforms(&self) -> Vec<RBWaveform> {
141    // FIXME - fix it, this drives me crazy
142    let mut waveforms   = Vec::<RBWaveform>::new();
143    // at max, we can have 4 waveform packets
144    let active_channels = self.header.get_channels();
145    let pid             = self.header.get_rbpaddleid();
146    if active_channels.contains(&0) || active_channels.contains(&1) {
147      let paddle_id  = pid.get_paddle_id(1);
148      let mut wf     = RBWaveform::new();
149      wf.rb_id       = self.header.rb_id;
150      wf.event_id    = self.header.event_id;
151      wf.stop_cell   = self.header.stop_cell;
152      wf.paddle_id   = paddle_id.0;
153      if paddle_id.1 {
154        // then b is channel 1 (or 0)
155        wf.adc_b   = self.adc[0].clone();
156        wf.adc_a   = self.adc[1].clone();
157        wf.rb_channel_b = 0;
158        wf.rb_channel_a = 1;
159      } else {
160        wf.adc_a   = self.adc[0].clone();
161        wf.adc_b   = self.adc[1].clone();
162        wf.rb_channel_b = 1;
163        wf.rb_channel_a = 0;
164      }
165      waveforms.push(wf);
166    }
167    if active_channels.contains(&2) || active_channels.contains(&3) {
168      let paddle_id  = pid.get_paddle_id(3);
169      let mut wf     = RBWaveform::new();
170      wf.rb_id       = self.header.rb_id;
171      wf.event_id    = self.header.event_id;
172      wf.stop_cell   = self.header.stop_cell;
173      wf.paddle_id   = paddle_id.0;
174      if paddle_id.1 {
175        // channel order flipped!
176        wf.adc_b   = self.adc[2].clone();
177        wf.adc_a   = self.adc[3].clone();
178        wf.rb_channel_b = 2;
179        wf.rb_channel_a = 3;
180      } else {
181        wf.adc_a   = self.adc[2].clone();
182        wf.adc_b   = self.adc[3].clone();
183        wf.rb_channel_b = 3;
184        wf.rb_channel_a = 2;
185      }
186      waveforms.push(wf);
187    }
188    if active_channels.contains(&4) || active_channels.contains(&5) {
189      let paddle_id  = pid.get_paddle_id(5);
190      let mut wf     = RBWaveform::new();
191      wf.rb_id       = self.header.rb_id;
192      wf.event_id    = self.header.event_id;
193      wf.stop_cell   = self.header.stop_cell;
194      wf.paddle_id   = paddle_id.0;
195      if paddle_id.1 {
196        // then b is channel 1 (or 0)
197        wf.adc_b   = self.adc[4].clone();
198        wf.adc_a   = self.adc[5].clone();
199        wf.rb_channel_b = 4;
200        wf.rb_channel_a = 5;
201      } else {
202        wf.adc_a   = self.adc[4].clone();
203        wf.adc_b   = self.adc[5].clone();
204        wf.rb_channel_b = 5;
205        wf.rb_channel_a = 4;
206      }
207      waveforms.push(wf);
208    }
209    if active_channels.contains(&6) || active_channels.contains(&7) {
210      let paddle_id  = pid.get_paddle_id(7);
211      let mut wf     = RBWaveform::new();
212      wf.rb_id       = self.header.rb_id;
213      wf.event_id    = self.header.event_id;
214      wf.stop_cell   = self.header.stop_cell;
215      wf.paddle_id   = paddle_id.0;
216      if paddle_id.1 {
217        // then b is channel 1 (or 0)
218        wf.adc_b   = self.adc[6].clone();
219        wf.adc_a   = self.adc[7].clone();
220        wf.rb_channel_b = 6;
221        wf.rb_channel_a = 7;
222      } else {
223        wf.adc_a   = self.adc[6].clone();
224        wf.adc_b   = self.adc[7].clone();
225        wf.rb_channel_b = 6;
226        wf.rb_channel_a = 7;
227      }
228      waveforms.push(wf);
229    }
230    waveforms
231  }
232
233  /// Get the datatype from a bytestream when we know
234  /// that it is an RBEvent
235  ///
236  /// The data type is encoded in byte 3
237  pub fn extract_datatype(stream : &Vec<u8>) -> Result<DataType, SerializationError> {
238    if stream.len() < 3 {
239      return Err(SerializationError::StreamTooShort);
240    }
241    // TODO This might panic! Is it ok?
242    Ok(DataType::try_from(stream[2]).unwrap_or(DataType::Unknown))
243  }
244  
245  /// decode the len field in the in memroy represention of 
246  /// RBEventMemoryView
247  pub fn get_channel_packet_len(stream : &Vec<u8>, pos : usize) -> Result<(usize, Vec::<u8>), SerializationError> {
248    // len is at position 4 
249    // roi is at postion 6
250    if stream.len() < 8 {
251      return Err(SerializationError::StreamTooShort);
252    }
253    let mut _pos = pos + 4;
254    let packet_len = parse_u16(stream, &mut _pos) as usize * 2; // len is in 2byte words
255    if packet_len < 44 {
256      // There is only header data 
257      error!("Event fragment - no channel data!");
258      return Ok((packet_len.into(), Vec::<u8>::new()));
259    }
260    let nwords     = parse_u16(stream, &mut _pos) as usize + 1; // roi is max bin (first is 0)
261    debug!("Got packet len of {} bytes, roi of {}", packet_len, nwords);
262    let channel_packet_start = pos + 36;
263    let nchan_data = packet_len - 44;
264    if stream.len() < channel_packet_start + nchan_data {
265      error!("We claim there should be channel data, but the event is too short!");
266      return Err(SerializationError::StreamTooShort)
267    }
268
269    let mut nchan = 0usize;
270    //println!("========================================");
271    //println!("{} {} {}", nchan, nwords, nchan_data);
272    //println!("========================================");
273    while nchan * (2*nwords + 6) < nchan_data {
274      nchan += 1;
275    }
276    if nchan * (2*nwords + 6) != nchan_data {
277      error!("NCHAN consistency check failed! nchan {} , nwords {}, packet_len {}", nchan, nwords, packet_len);
278    }
279    let mut ch_ids = Vec::<u8>::new();
280    _pos = channel_packet_start;
281    for _ in 0..nchan {
282      ch_ids.push(parse_u16(stream, &mut _pos) as u8);
283      _pos += (nwords*2) as usize;
284      _pos += 4; // trailer
285    }
286    debug!("Got channel ids {:?}", ch_ids);
287    Ok((nchan_data.into(), ch_ids))
288  }
289
290  /// Get the event id from a RBEvent represented by bytestream
291  /// without decoding the whole event
292  ///
293  /// This should be faster than decoding the whole event.
294  pub fn extract_eventid(stream : &Vec<u8>) -> Result<u32, SerializationError> {
295    if stream.len() < 30 {
296      return Err(SerializationError::StreamTooShort);
297    }
298    // event header starts at position 7
299    // in the header, it is as positon 3
300    let event_id = parse_u32(stream, &mut 10);
301    Ok(event_id)
302  }
303
304  pub fn get_ndatachan(&self) -> usize {
305    self.adc.len()
306  }
307
308  pub fn get_channel_by_id(&self, ch : usize) -> Result<&Vec::<u16>, UserError> {
309    if ch >= 9 {
310      error!("channel_by_id expects numbers from 0-8!");
311      return Err(UserError::IneligibleChannelLabel)
312    }
313    return Ok(&self.adc[ch]);
314  }
315
316  pub fn get_channel_by_label(&self, ch : u8) -> Result<&Vec::<u16>, UserError>  {
317    if ch == 0 || ch > 9 {
318      error!("channel_by_label expects numbers from 1-9!");
319      return Err(UserError::IneligibleChannelLabel)
320    }
321    Ok(&self.adc[ch as usize -1])
322  }
323
324  /// Similar to the "official" from_bytestream, this will get the 
325  /// event from a bytestream, omitting the waveforms. This will allow
326  /// for a faster readout in case waveforms are not needed.
327  pub fn from_bytestream_nowaveforms(stream : &Vec<u8>, pos : &mut usize)
328    -> Result<Self, SerializationError> {
329    let mut event = Self::new();
330    if parse_u16(stream, pos) != Self::HEAD {
331      error!("The given position {} does not point to a valid header signature of {}", pos, Self::HEAD);
332      return Err(SerializationError::HeadInvalid {});
333    }
334    event.data_type = DataType::try_from(parse_u8(stream, pos)).unwrap_or(DataType::Unknown);
335    event.status    = EventStatus::try_from(parse_u8(stream, pos)).unwrap_or(EventStatus::Unknown);
336    //let nchan_data  = parse_u8(stream, pos);
337    let n_hits      = parse_u8(stream, pos);
338    event.header    = RBEventHeader::from_bytestream(stream, pos)?;
339    //let ch_ids      = event.header.get_active_data_channels();
340    let stream_len  = stream.len();
341    if event.header.is_event_fragment() {
342      debug!("Fragmented event {} found!", event.header.event_id);
343      let tail_pos = seek_marker(stream, Self::TAIL, *pos)?;
344      * pos = tail_pos + 2 as usize;
345      // the event fragment won't have channel data, so 
346      // let's move on to the next TAIL marker:ta
347      return Ok(event);
348    }
349    if event.header.drs_lost_trigger() {
350      debug!("Event {} has lost trigger!", event.header.event_id);
351      let tail_pos = seek_marker(stream, Self::TAIL, *pos)?;
352      * pos = tail_pos + 2 as usize;
353      return Ok(event);
354    }
355    let mut decoded_ch = Vec::<u8>::new();
356    // here is the only change to from_bytestream. 
357    // We are simply skipping the waveforms, but 
358    // still read the hits
359    for ch in event.header.get_channels().iter() {
360      if *pos + 2*NWORDS >= stream_len {
361        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);
362        let tail_pos = seek_marker(stream, Self::TAIL, *pos)?;
363        * pos = tail_pos + 2 as usize;
364        return Err(SerializationError::WrongByteSize {})
365      }
366      decoded_ch.push(*ch);
367      // 2*NWORDS because stream is Vec::<u8> and it is 16 bit words.
368      *pos += 2*NWORDS;
369    }
370    for _ in 0..n_hits {
371      match TofHit::from_bytestream(stream, pos) {
372        Err(err) => {
373          error!("Can't read TofHit! Err {err}");
374          let mut h = TofHit::new();
375          h.valid = false;
376          event.hits.push(h);
377        },
378        Ok(h) => {
379          event.hits.push(h);
380        }
381      }
382    }
383    let tail = parse_u16(stream, pos);
384    if tail != Self::TAIL {
385      error!("After parsing the event, we found an invalid tail signature {}", tail);
386      return Err(SerializationError::TailInvalid);
387    }
388    Ok(event)
389  }
390}
391
392impl TofPackable for RBEvent {
393  const TOF_PACKET_TYPE : TofPacketType = TofPacketType::RBEvent;
394}
395
396impl Serialization for RBEvent {
397  const HEAD : u16 = 0xAAAA;
398  const TAIL : u16 = 0x5555;
399  
400  fn from_bytestream(stream : &Vec<u8>, pos : &mut usize)
401    -> Result<Self, SerializationError> {
402    let mut event = Self::new();
403    if parse_u16(stream, pos) != Self::HEAD {
404      error!("The given position {} does not point to a valid header signature of {}", pos, Self::HEAD);
405      return Err(SerializationError::HeadInvalid {});
406    }
407    event.data_type = DataType::try_from(parse_u8(stream, pos)).unwrap_or(DataType::Unknown);
408    event.status    = EventStatus::try_from(parse_u8(stream, pos)).unwrap_or(EventStatus::Unknown);
409    //let nchan_data  = parse_u8(stream, pos);
410    let n_hits      = parse_u8(stream, pos);
411    event.header    = RBEventHeader::from_bytestream(stream, pos)?;
412    //let ch_ids      = event.header.get_active_data_channels();
413    let stream_len  = stream.len();
414    if event.header.is_event_fragment() {
415      debug!("Fragmented event {} found!", event.header.event_id);
416      let tail_pos = seek_marker(stream, Self::TAIL, *pos)?;
417      * pos = tail_pos + 2 as usize;
418      // the event fragment won't have channel data, so 
419      // let's move on to the next TAIL marker:ta
420      return Ok(event);
421    }
422    if event.header.drs_lost_trigger() {
423      debug!("Event {} has lost trigger!", event.header.event_id);
424      let tail_pos = seek_marker(stream, Self::TAIL, *pos)?;
425      * pos = tail_pos + 2 as usize;
426      return Ok(event);
427    }
428    let mut decoded_ch = Vec::<u8>::new();
429    for ch in event.header.get_channels().iter() {
430      if *pos + 2*NWORDS >= stream_len {
431        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);
432        let tail_pos = seek_marker(stream, Self::TAIL, *pos)?;
433        * pos = tail_pos + 2 as usize;
434        return Err(SerializationError::WrongByteSize {})
435      }
436      decoded_ch.push(*ch);
437      // 2*NWORDS because stream is Vec::<u8> and it is 16 bit words.
438      let data = &stream[*pos..*pos+2*NWORDS];
439      //event.adc[k as usize] = u8_to_u16(data);
440      event.adc[*ch as usize] = u8_to_u16(data);
441      *pos += 2*NWORDS;
442    }
443    for _ in 0..n_hits {
444      match TofHit::from_bytestream(stream, pos) {
445        Err(err) => {
446          error!("Can't read TofHit! Err {err}");
447          let mut h = TofHit::new();
448          h.valid = false;
449          event.hits.push(h);
450        },
451        Ok(h) => {
452          event.hits.push(h);
453        }
454      }
455    }
456    let tail = parse_u16(stream, pos);
457    //println!("{:?}", &stream[*pos-10..*pos+2]);
458    //println!("{} {}", pos, stream.len());
459    if tail != Self::TAIL {
460      error!("After parsing the event, we found an invalid tail signature {}", tail);
461      return Err(SerializationError::TailInvalid);
462    }
463    Ok(event)
464  }
465  
466  fn to_bytestream(&self) -> Vec<u8> {
467    let mut stream = Vec::<u8>::with_capacity(18530);
468    //let mut stream = Vec::<u8>::new();
469    stream.extend_from_slice(&Self::HEAD.to_le_bytes());
470    stream.push(self.data_type as u8);
471    stream.push(self.status as u8);
472    //let nchan_data  = self.adc.len() as u8;
473    //stream.push(nchan_data);
474    let n_hits      = self.hits.len() as u8;
475    stream.push(n_hits);
476    stream.extend_from_slice(&self.header.to_bytestream());
477    // for an empty channel, we will add an empty vector
478    let add_channels = !self.header.is_event_fragment() & !self.header.drs_lost_trigger();
479    if add_channels {
480      for n in 0..NCHN {
481        for k in 0..NWORDS {
482          if self.adc[n].len() == 0 {
483            continue;
484          }
485          stream.extend_from_slice(&self.adc[n][k].to_le_bytes());  
486        }
487      }
488      // this is way slower
489      //for channel_adc in self.adc.iter() {
490      //  stream.extend_from_slice(&u16_to_u8(&channel_adc)); 
491      //}
492    }
493    //if self.ch9_adc.len() > 0 {
494    //  stream.extend_from_slice(&u16_to_u8(&self.ch9_adc));
495    //}
496    for h in self.hits.iter() {
497      stream.extend_from_slice(&h.to_bytestream());
498    }
499    stream.extend_from_slice(&Self::TAIL.to_le_bytes());
500    stream
501  }
502}
503
504impl Default for RBEvent {
505
506  fn default () -> Self {
507    Self::new()
508  }
509}
510
511impl fmt::Display for RBEvent {
512  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
513    let mut adc = Vec::<usize>::new();
514    for k in 0..self.adc.len() -1 {
515      adc.push(self.adc[k].len());
516    }
517    let mut ch9_str = String::from("[");
518    for k in self.adc[8].iter().take(5) {
519      ch9_str += &k.to_string();
520      ch9_str += ","
521    }
522    ch9_str += " .. :";
523    ch9_str += &self.adc[8].len().to_string();
524    ch9_str += "]";
525    let mut ch_field = String::from("[\n");
526    for (ch, vals) in self.adc.iter().enumerate() {
527      if ch == 8 {
528        continue;
529      }
530      let label = (ch + 1).to_string();
531      ch_field += "  [ch ";
532      ch_field += &ch.to_string();
533      ch_field += "('";
534      ch_field += &label;
535      ch_field += "') ";
536      for n in vals.iter().take(5) {
537        ch_field += &n.to_string();
538        ch_field += ",";
539      }
540      ch_field += "..:";
541      ch_field += &vals.len().to_string();
542      ch_field += "]\n";
543    }
544    ch_field += "]\n";
545    write!(f, "<RBEvent 
546  data type     : {},
547  event status  : {},
548  {}
549  .. .. 
550  has ch9       : {},
551    -> ch9      : {},
552  data channels : 
553    -> {},
554  n hits        : {},
555.. .. .. .. .. .. .. .. >",
556    self.data_type,
557    self.status,
558    self.header,
559    self.header.has_ch9(),
560    ch9_str,
561    ch_field,
562    self.hits.len())
563  }
564}
565
566#[cfg(feature = "random")]
567impl FromRandom for RBEvent {
568    
569  fn from_random() -> Self {
570    let mut event   = RBEvent::new();
571    let header      = RBEventHeader::from_random();
572    let mut rng     = rand::rng();
573    event.data_type = DataType::from_random(); 
574    event.status    = EventStatus::from_random();
575    event.header    = header;
576    // set a good status byte. RBEvents from 
577    // random will always be good
578    // status_byte is tested in RBEventHeader test
579    // and here we want to make sure channel data 
580    // gets serialized
581    // status byte of 0 means it is good
582    event.header.status_byte = 0;
583    //if !event.header.event_fragment && !event.header.lost_trigger {
584    for ch in event.header.get_channels().iter() {
585      let random_numbers: Vec<u16> = (0..NWORDS).map(|_| rng.random()).collect();
586      event.adc[*ch as usize] = random_numbers;
587    }
588    event.creation_time = None;
589    event
590  }
591}
592
593//-----------------------------------------------------------
594  
595#[cfg(feature="pybindings")]
596#[pymethods]
597impl RBEvent {
598
599  #[getter]
600  fn get_status(&self) -> EventStatus {
601    self.status
602  }
603
604  // FIXME - use PyReadonlyArray? Needs test
605  /// Get adc values directly from the RBEvent with zero copy
606  ///
607  /// The channel has to go from 1-9
608  fn get_waveform<'_py>(&self, py: Python<'_py>, channel : usize) -> PyResult<Bound<'_py, PyArray1<u16>>> {  
609    if channel < 1 || channel > 9 {
610      return Err(PyValueError::new_err("Channel must be > 0 and < 9"));
611    }
612    let data = &self.adc[channel - 1];
613    let py_array = data.to_pyarray(py);
614    Ok(py_array)
615  }
616  
617  fn get_waveform_slow<'_py>(&self, py: Python<'_py>, channel : usize) -> PyResult<Bound<'_py, PyArray1<u16>>> {  
618    let wf  = self.get_channel_by_id(channel).unwrap().clone();
619    let arr = PyArray1::<u16>::from_vec(py, wf);
620    Ok(arr)
621  }
622  
623  
624  #[getter]
625  fn get_hits(&self) -> Vec<TofHit> {
626    self.hits.clone()
627  }
628 
629  // FIXME - no clear if a new object is created here 
630  #[getter]
631  fn get_header<'_py>(&self, py : Python<'_py>) -> PyResult<Bound<'_py , RBEventHeader>> {
632    Bound::<'_py, RBEventHeader>::new(py, self.header)
633  }
634  
635  #[getter]
636  fn waveforms(&self) -> Vec<RBWaveform> {
637    self.get_rbwaveforms().clone()
638  }
639}
640
641#[cfg(feature="pybindings")]
642pythonize_packable!(RBEvent);
643
644//-----------------------------------------------------------
645
646//FIXME - test needs some review
647#[test]
648fn serialization_rbevent() {
649  for _ in 0..100 {
650    let event  = RBEvent::from_random();
651    let stream = event.to_bytestream();
652    println!("[test rbevent] stream.len()   {:?}", stream.len());
653    let test   = RBEvent::from_bytestream(&stream, &mut 0).unwrap();
654    println!("[test rbevent] event frag   {:?}", event.header.is_event_fragment());
655    println!("[test rbevent] lost trig    {:?}", event.header.drs_lost_trigger());
656    println!("[test rbevent] event frag   {:?}", test.header.is_event_fragment());
657    println!("[test rbevent] lost trig    {:?}", test.header.drs_lost_trigger());
658    assert_eq!(event.header, test.header);
659    assert_eq!(event.header.get_nchan(), test.header.get_nchan());
660    assert_eq!(event.header.get_channels(), test.header.get_channels());
661    assert_eq!(event.data_type, test.data_type);
662    assert_eq!(event.status, test.status);
663    assert_eq!(event.adc.len(), test.adc.len());
664    assert_eq!(event.hits.len(), test.hits.len());
665    println!("[test rbevent] get_channels() {:?}", event.header.get_channels());
666    assert_eq!(event.adc[0].len(), test.adc[0].len());
667    assert_eq!(event.adc[1].len(), test.adc[1].len());
668    assert_eq!(event.adc[2].len(), test.adc[2].len());
669    assert_eq!(event.adc[3].len(), test.adc[3].len());
670    assert_eq!(event.adc[4].len(), test.adc[4].len());
671    assert_eq!(event.adc[5].len(), test.adc[5].len());
672    assert_eq!(event.adc[6].len(), test.adc[6].len());
673    assert_eq!(event.adc[7].len(), test.adc[7].len());
674    assert_eq!(event.adc[8].len(), test.adc[8].len());
675    assert_eq!(event.adc[0], test.adc[0]);
676    assert_eq!(event.adc[1], test.adc[1]);
677    assert_eq!(event.adc[2], test.adc[2]);
678    assert_eq!(event.adc[3], test.adc[3]);
679    assert_eq!(event.adc[4], test.adc[4]);
680    assert_eq!(event.adc[5], test.adc[5]);
681    assert_eq!(event.adc[6], test.adc[6]);
682    assert_eq!(event.adc[7], test.adc[7]);
683    assert_eq!(event.adc[8], test.adc[8]);
684    //for ch in (event.header.get_channels().iter()){
685    //  assert_eq!(event.adc[*ch as usize], test.adc[*ch as usize]);
686    //}
687    //assert_eq!(event, test);
688
689    //if head.header.event_fragment == test.header.event_fragment {
690    //  println!("Event fragment found, no channel data available!");
691    //} else {
692    //  assert_eq!(head, test);
693    //}
694  }
695}
696
697#[test]
698fn pack_rbevent() {
699  for _ in 0..100 {
700    let mut event          = RBEvent::from_random();
701    let fix_time           = Instant::now();
702    event.creation_time    = None;
703    let mut test : RBEvent = event.pack().unpack().unwrap();
704    test.creation_time     = None;
705    assert_eq!(event, test);
706  }
707}
708