tof_dataclasses/events/
rb_eventmemoryview.rs

1use std::fmt;
2use crate::serialization::{parse_u8,
3                           parse_u16,
4                           parse_u32,
5                           parse_u32_for_16bit_words,
6                           parse_u64,
7                           search_for_u16,
8                           Serialization,
9                           SerializationError};
10
11use crate::constants::{NCHN,
12                       NWORDS};
13
14cfg_if::cfg_if! {
15  if #[cfg(feature = "random")]  {
16    use crate::FromRandom;
17    extern crate rand;
18    use rand::Rng;
19  }
20}
21
22/// RBEventMemoryView is the closest representation of actual 
23/// RB binary data in memory, with a fixed number of 
24/// channels at compile time, optimized for speed by 
25/// using fixed (at compile time) sizes for channels 
26/// and sample size
27///
28/// FIXME - the channel mask is only one byte, 
29///         and we can get rid of 3 bytes for 
30///         the DNA
31#[deprecated(since="0.7.2", note="RBEvent is sufficient to fulfill all our needs!")]
32#[derive(Debug, Clone, PartialEq)]
33pub struct RBEventMemoryView {
34  pub head            : u16, // Head of event marker
35  pub status          : u16,
36  pub len             : u16,
37  pub roi             : u16,
38  pub dna             : u64, 
39  pub fw_hash         : u16,
40  pub id              : u16,   
41  pub ch_mask         : u16,
42  pub event_id        : u32,
43  pub dtap0           : u16,
44  pub dtap1           : u16,
45  pub timestamp_32    : u32,
46  pub timestamp_16    : u16,
47  pub ch_head         : [ u16; NCHN],
48  pub ch_adc          : [[u16; NWORDS];NCHN], 
49  pub ch_trail        : [ u32; NCHN],
50  pub stop_cell       : u16,
51  pub crc32           : u32,
52  pub tail            : u16, // End of event marker
53}
54
55impl RBEventMemoryView {
56
57  // the size is fixed, assuming fixed
58  // nchannel and sample size
59  
60  pub fn new() -> Self {
61    Self {
62      head            : 0, // Head of event marker
63      status          : 0,
64      len             : 0,
65      roi             : 0,
66      dna             : 0, 
67      fw_hash         : 0,
68      id              : 0,   
69      ch_mask         : 0,
70      event_id        : 0,
71      dtap0           : 0,
72      dtap1           : 0,
73      timestamp_32    : 0,
74      timestamp_16    : 0,
75      ch_head         : [ 0; NCHN],
76      ch_adc          : [[0; NWORDS];NCHN], 
77      ch_trail        : [ 0; NCHN],
78      stop_cell       : 0,
79      crc32           : 0,
80      tail            : 0, // End of event marker
81    }
82  }
83
84  // FIXME
85  pub fn decode_event_id(bytestream : &[u8]) -> Result<u32, SerializationError> {
86    let stream = bytestream.to_vec();
87    let mut pos = 0usize;
88    let head_pos = search_for_u16(Self::HEAD, &stream, pos)?; 
89    let tail_pos = search_for_u16(Self::TAIL, &stream, pos + Self::SIZE-2)?;
90    // At this state, this can be a header or a full event. Check here and
91    // proceed depending on the options
92    if tail_pos + 2 - pos != Self::SIZE {
93      error!("Event seems incomplete. Seing {} bytes, but expecting {}", tail_pos + 2 - head_pos, RBEventMemoryView::SIZE);
94      //error!("{:?}", &stream[head_pos + 18526..head_pos + 18540]);
95      //pos = pos + 2; //start_pos += RBEventMemoryView::SIZE;
96      return Err(SerializationError::EventFragment);
97    }
98    pos = pos + 2 + 2 + 2 + 2 + 8 + 2 + 2 + 2;
99    let event_id = parse_u32_for_16bit_words(&stream, &mut pos); 
100    Ok(event_id)
101  }
102
103  pub fn get_active_data_channels(&self) -> Vec<u8> {
104    let mut active_channels = Vec::<u8>::with_capacity(8);
105    for ch in 1..9 {
106      if self.ch_mask as u8 & (ch as u8 -1).pow(2) == (ch as u8 -1).pow(2) {
107        active_channels.push(ch);
108      }
109    }
110    active_channels
111  }
112
113  
114  pub fn get_n_datachan(&self) -> u8 {
115    self.get_active_data_channels().len() as u8
116  }
117}
118
119impl Default for RBEventMemoryView {
120  fn default() -> Self {
121    Self::new()
122  }
123}
124
125
126impl fmt::Display for RBEventMemoryView {
127  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128    write!(f, "<RBEventMemoryView:\n
129           \t RB {},\n
130           \t len {}, \n
131           \t roi {}, \n
132           \t dna {}, \n
133           \t hash {},   \n
134           \t chmask {}, \n
135           \t dtap0 {}, \n
136           \t dtap1 {}, \n
137           \t event id {}, \n
138           \t timestamp32 {}, \n
139           \t timestamp16 {}, \n 
140           \t crc32 {},\n",
141           self.id, self.len, self.roi, self.dna, self.fw_hash,
142           self.ch_mask, self.dtap0, self.dtap1, self.event_id,
143           self.timestamp_32, self.timestamp_16, self.crc32)
144  }
145}
146
147impl Serialization for RBEventMemoryView {
148  const SIZE : usize = 18530;
149  const HEAD : u16   = 0xAAAA;
150  const TAIL : u16   = 0x5555;
151
152  fn to_bytestream(&self) -> Vec<u8> {
153    let mut stream = Vec::<u8>::with_capacity(Self::SIZE);
154    stream.extend_from_slice(&Self::HEAD.to_le_bytes());
155    stream.extend_from_slice(&self.status  .to_le_bytes());
156    stream.extend_from_slice(&self.len     .to_le_bytes());
157    stream.extend_from_slice(&self.roi     .to_le_bytes());
158    stream.extend_from_slice(&self.dna     .to_le_bytes());
159    stream.extend_from_slice(&self.fw_hash .to_le_bytes());
160    stream.extend_from_slice(&self.id      .to_le_bytes());  
161    stream.extend_from_slice(&self.ch_mask .to_le_bytes());
162    let four_bytes = self.event_id.to_be_bytes();
163    let four_bytes_shuffle = [four_bytes[1],
164                              four_bytes[0],
165                              four_bytes[3],
166                              four_bytes[2]];
167    stream.extend_from_slice(&four_bytes_shuffle); 
168    
169
170    //stream.extend_from_slice(&self.event_id.to_le_bytes());
171    stream.extend_from_slice(&self.dtap0   .to_le_bytes());
172    stream.extend_from_slice(&self.dtap1   .to_le_bytes());
173    stream.extend_from_slice(&self.timestamp_32.to_le_bytes());
174    stream.extend_from_slice(&self.timestamp_16.to_le_bytes());
175    for n in 0..NCHN {
176      stream.extend_from_slice(&self.ch_head[n].to_le_bytes());
177      for k in 0..NWORDS {
178        stream.extend_from_slice(&self.ch_adc[n][k].to_le_bytes());  
179      }
180      stream.extend_from_slice(&self.ch_trail[n].to_le_bytes());
181    }
182
183    stream.extend_from_slice(&self.stop_cell.to_le_bytes());
184   // four_bytes = self.crc32.to_be_bytes();
185   // four_bytes_shuffle = [four_bytes[1],
186   //                       four_bytes[0],
187   //                       four_bytes[3],
188   //                       four_bytes[2]];
189   // stream.extend_from_slice(&four_bytes_shuffle); 
190    stream.extend_from_slice(&self.crc32.to_le_bytes());
191    stream.extend_from_slice(&Self::TAIL.to_le_bytes());
192    stream
193  }
194
195  fn from_bytestream(stream : &Vec<u8>, pos : &mut usize)
196    -> Result<Self, SerializationError> {
197    let mut bin_data = Self::new();
198    let head_pos = search_for_u16(Self::HEAD, stream, *pos)?; 
199    let tail_pos = search_for_u16(Self::TAIL, stream, head_pos + Self::SIZE-2)?;
200    // At this state, this can be a header or a full event. Check here and
201    // proceed depending on the options
202    if tail_pos + 2 - head_pos != Self::SIZE {
203      error!("Event seems incomplete. Seing {} bytes, but expecting {}", tail_pos + 2 - head_pos, RBEventMemoryView::SIZE);
204      //error!("{:?}", &stream[head_pos + 18526..head_pos + 18540]);
205      *pos = head_pos + 2; //start_pos += RBEventMemoryView::SIZE;
206      return Err(SerializationError::EventFragment);
207    }
208    *pos = head_pos + 2; 
209    bin_data.status         = parse_u16(&stream, pos);
210    bin_data.len            = parse_u16(&stream, pos);
211    bin_data.roi            = parse_u16(&stream, pos);
212    bin_data.dna            = parse_u64(&stream, pos); 
213    bin_data.fw_hash        = parse_u16(&stream, pos);
214    bin_data.id             = parse_u16(&stream, pos);   
215    bin_data.ch_mask        = parse_u8 (&stream, pos) as u16;
216    *pos += 1;
217    bin_data.event_id       = parse_u32_for_16bit_words(&stream, pos);
218    bin_data.dtap0          = parse_u16(&stream, pos);
219    bin_data.dtap1          = parse_u16(&stream, pos);
220    bin_data.timestamp_32   = parse_u32(&stream, pos);
221    bin_data.timestamp_16   = parse_u16(&stream, pos);
222    //let nch = bin_data.get_n_datachan();
223    for n in 0..NCHN as usize {
224      bin_data.ch_head[n]   = parse_u16(&stream, pos);
225      for k in 0..NWORDS {
226        bin_data.ch_adc[n][k] = 0x3FFF & parse_u16(&stream, pos);  
227      }
228      bin_data.ch_trail[n]  =  parse_u32(&stream, pos);
229    }
230
231    bin_data.stop_cell      =  parse_u16(&stream, pos);
232    bin_data.crc32          =  parse_u32(&stream, pos);
233    bin_data.head           =  Self::HEAD;
234    bin_data.tail           =  Self::TAIL;
235    *pos += 2; // since we deserialized the tail earlier and 
236              // didn't account for it
237    Ok(bin_data)
238  }
239}
240
241#[cfg(feature = "random")]
242impl FromRandom for RBEventMemoryView {
243    
244  fn from_random() -> Self {
245    let mut bin_data = Self::new();
246    let mut rng = rand::thread_rng();
247    let mut nchan = rng.gen::<u8>();
248    while nchan > 9 {
249      nchan = rng.gen::<u8>();
250    }
251    let roi = nchan as usize * (2 + 4 + 2 * NWORDS);  
252    bin_data.head           =  0xAAAA; // Head of event marker
253    bin_data.status         =  rng.gen::<u16>();
254    bin_data.len            =  rng.gen::<u16>();
255    bin_data.roi            =  roi as u16;
256    bin_data.dna            =  rng.gen::<u64>(); 
257    bin_data.fw_hash        =  rng.gen::<u16>();
258    let rb_id               =  rng.gen::<u8>() as u16;   
259    bin_data.id             =  rb_id;
260    bin_data.id             =  rb_id << 8;   
261    bin_data.ch_mask        =  rng.gen::<u8>() as u16;
262    bin_data.event_id       =  rng.gen::<u32>();
263    bin_data.dtap0          =  rng.gen::<u16>();
264    bin_data.dtap1          =  rng.gen::<u16>();
265    bin_data.timestamp_32   =  rng.gen::<u32>();
266    bin_data.timestamp_16   =  rng.gen::<u16>();
267    //let nch = bin_data.get_n_datachan();
268    for n in 0..nchan as usize {
269      bin_data.ch_head[n]   =  rng.gen::<u16>();
270      bin_data.ch_trail[n]  =  rng.gen::<u32>();
271      for k in 0..NWORDS {
272        bin_data.ch_adc[n][k] = 0x3FFF & rng.gen::<u16>();  
273      }
274    }
275
276    bin_data.stop_cell      =  rng.gen::<u16>();
277    bin_data.crc32          =  rng.gen::<u32>();
278    bin_data.tail           =  0x5555; // End of event marker
279    bin_data
280  }
281}
282
283#[test]
284#[cfg(feature = "random")]  
285fn serialization_rbmemoryview() {
286  let head = RBEventMemoryView::from_random();
287  let test = RBEventMemoryView::from_bytestream(&head.to_bytestream(), &mut 0).unwrap();
288  assert_eq!(head, test);
289}
290