telemetry_dataclasses/
packets.rs

1//! Basic telemetry packets
2//!
3
4pub mod magnetometer;
5
6pub use magnetometer::MagnetoMeter;
7
8use std::fmt;
9use std::collections::HashMap;
10use log::{
11  //info,
12  debug,
13  error
14};
15
16use tof_dataclasses::errors::SerializationError;
17use tof_dataclasses::serialization::{
18  parse_u8,
19  parse_u16,
20  parse_u32,
21  parse_u64,
22  Serialization,
23  Packable
24};
25
26use tof_dataclasses::database::{
27  TrackerStrip
28};
29
30use tof_dataclasses::events::TofEventSummary;
31use tof_dataclasses::packets::{
32  TofPacket,
33  PacketType
34};
35
36#[cfg(feature = "pybindings")]
37use pyo3::pyclass;
38
39/// Recreate 48bit timestamp from u32 and u16
40pub fn make_systime(lower : u32, upper : u16) -> u64 {
41  (upper as u64) << 32 | lower as u64
42}
43
44
45#[derive(Debug, Copy, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
46#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
47#[repr(u8)]
48pub enum TelemetryPacketType {
49  Unknown            = 0,
50  CardHKP            = 30,
51  CoolingHK          = 40,
52  PDUHK              = 50,
53  Tracker            = 80,
54  TrackerDAQCntr     = 81,
55  GPS                = 82,
56  TrkTempLeak        = 83,
57  BoringEvent        = 90,
58  RBWaveform         = 91,
59  AnyTofHK           = 92,
60  GcuEvtBldSettings  = 93,
61  LabJackHK          = 100,
62  MagHK              = 108,
63  GcuMon             = 110,
64  InterestingEvent   = 190,
65  NoGapsTriggerEvent = 191,
66  NoTofDataEvent     = 192,
67  Ack                = 200,     
68  AnyTrackerHK       = 255,
69  // unknown/unused stuff
70  TmP33              = 33,
71  TmP34              = 34,
72  TmP37              = 37,
73  TmP38              = 38,
74  TmP55              = 55,
75  TmP64              = 64,
76  //TmP92            = 92,
77  TmP96              = 96,
78  TmP214             = 214,
79}
80
81impl From<u8> for TelemetryPacketType {
82  fn from(value: u8) -> Self {
83    match value {
84      0     => TelemetryPacketType::Unknown,
85      30    => TelemetryPacketType::CardHKP,
86      40    => TelemetryPacketType::CoolingHK,
87      50    => TelemetryPacketType::PDUHK,
88      80    => TelemetryPacketType::Tracker,
89      81    => TelemetryPacketType::TrackerDAQCntr,
90      82    => TelemetryPacketType::GPS,
91      83    => TelemetryPacketType::TrkTempLeak,
92      90    => TelemetryPacketType::BoringEvent,
93      91    => TelemetryPacketType::RBWaveform,
94      92    => TelemetryPacketType::AnyTofHK,
95      93    => TelemetryPacketType::GcuEvtBldSettings,
96      100   => TelemetryPacketType::LabJackHK,
97      108   => TelemetryPacketType::MagHK,
98      110   => TelemetryPacketType::GcuMon,
99      190   => TelemetryPacketType::InterestingEvent,
100      191   => TelemetryPacketType::NoGapsTriggerEvent,
101      192   => TelemetryPacketType::NoTofDataEvent,
102      200   => TelemetryPacketType::Ack,
103      255   => TelemetryPacketType::AnyTrackerHK,
104      _     => TelemetryPacketType::Unknown,
105    }
106  }
107}
108
109impl fmt::Display for TelemetryPacketType {
110  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111    let r = serde_json::to_string(self).unwrap_or(
112      String::from("Error - Don't understand packet type!"));
113    write!(f, "<TelemetryPacketType: {}>", r)
114  }
115}
116
117#[derive(Debug, Clone, PartialEq)]
118pub struct TelemetryPacket {
119  pub header  : TelemetryHeader,
120  pub payload : Vec<u8>
121}
122
123impl TelemetryPacket {
124  pub fn new() -> Self {
125    Self {
126      header  : TelemetryHeader::new(),
127      payload : Vec::<u8>::new()
128    }
129  }
130
131  pub fn from_bytestream(stream : &Vec<u8>, pos : &mut usize) -> Result<Self, SerializationError> {
132    let mut tpacket = TelemetryPacket::new();
133    let header  = TelemetryHeader::from_bytestream(stream, pos)?;
134    tpacket.header = header;
135    //println!("Found header {}", tpacket.header);
136    // it seems the payload size is header.size
137    // fix - the payload is either sizeof(header) + payload.len 
138    tpacket.payload = stream[*pos..*pos + header.length as usize - TelemetryHeader::SIZE].to_vec();
139    Ok(tpacket)
140  }
141
142  // FIXME - this needs to be a trait
143  pub fn to_bytestream(&self) -> Vec<u8> {
144    let mut stream = Vec::<u8>::new();
145    let mut s_head = self.header.to_bytestream();
146    stream.append(&mut s_head);
147    stream.extend_from_slice(self.payload.as_slice());
148    //stream.append(&mut self.payload);
149    stream
150  }
151}
152
153impl fmt::Display for TelemetryPacket {
154  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
155    let mut repr = String::from("<TelemetryPacket:");
156    repr += &(format!("\n  Header      : {}",self.header));
157    repr += &(format!("\n  Payload len : {}>",self.payload.len()));
158    write!(f, "{}", repr)
159  }
160}
161
162
163#[derive(Debug, Copy, Clone, PartialEq)]
164pub struct TelemetryHeader {
165  pub sync      : u16,
166  pub ptype     : u8,
167  pub timestamp : u32,
168  pub counter   : u16,
169  pub length    : u16,
170  pub checksum  : u16
171}
172
173//    fn from_bytestream(
174//    bytestream: &Vec<u8>,
175//    pos: &mut usize
176//) -> Result<Self, SerializationError>
177
178impl TelemetryHeader {
179
180  pub fn new() -> Self {
181    Self {
182      sync      : 0,
183      ptype     : 0,
184      timestamp : 0,
185      counter   : 0,
186      length    : 0,
187      checksum  : 0,
188    }
189  }
190
191  /// A re-implementation of make_packet_stub
192  pub fn forge(packet_type : u8) -> Self {
193    let mut header = Self::new();
194    header.sync  = 0x90EB;
195    header.ptype   = packet_type;
196    header
197  }
198
199//{
200//   std::vector<uint8_t> bytes(13,0);
201//   *reinterpret_cast<uint16_t*>(&bytes[0]) = 0x90EB;
202//   bytes[2] = type;
203//   if(timestamp == 0)
204//      timestamp = bfsw::timestamp_64ms();
205//   *reinterpret_cast<uint32_t*>(&bytes[3]) = timestamp;
206//   *reinterpret_cast<uint16_t*>(&bytes[7]) = counter;
207//   *reinterpret_cast<uint16_t*>(&bytes[9]) = length;
208//   *reinterpret_cast<uint16_t*>(&bytes[11]) = 0;
209//   return bytes;
210  /// This is a reimplementation of bfsw's timestamp_to_double
211  pub fn get_gcutime(&self) -> f64 {
212    (self.timestamp as f64) * 0.064 + 1631030675.0
213  }
214}
215
216impl Serialization for TelemetryHeader {
217  
218  const HEAD : u16 = 0x90eb;
219  const TAIL : u16 = 0x0000; // there is no tail for telemetry packets
220  const SIZE : usize = 13; 
221
222  fn from_bytestream(stream : &Vec<u8>,
223                     pos    : &mut usize)
224    -> Result<Self, SerializationError> {
225    if stream.len() < *pos + Self::SIZE {
226      return Err(SerializationError::StreamTooShort);
227    }
228    if parse_u16(stream, pos) != 0x90eb {
229      error!("The given position {} does not point to a valid header signature of {}", pos, 0x90eb);
230      return Err(SerializationError::HeadInvalid {});
231    }
232    let mut thead = TelemetryHeader::new();
233    thead.sync      = 0x90eb;
234    thead.ptype     = parse_u8 (stream, pos);
235    thead.timestamp = parse_u32(stream, pos);
236    thead.counter   = parse_u16(stream, pos);
237    thead.length    = parse_u16(stream, pos);
238    thead.checksum  = parse_u16(stream, pos);
239    Ok(thead)
240  }
241  
242  fn to_bytestream(&self) -> Vec<u8> {
243    let mut stream = Vec::<u8>::new();
244    //let head : u16 = 0x90eb;
245    // "SYNC" is the header signature
246    stream.extend_from_slice(&self.sync.to_le_bytes());
247    stream.extend_from_slice(&self.ptype.to_le_bytes());
248    stream.extend_from_slice(&self.timestamp.to_le_bytes());
249    stream.extend_from_slice(&self.counter.to_le_bytes());
250    stream.extend_from_slice(&self.length.to_le_bytes());
251    stream.extend_from_slice(&self.checksum.to_le_bytes());
252    stream
253  }
254
255}
256
257impl fmt::Display for TelemetryHeader {
258  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
259    let mut repr = String::from("<TelemetryHeader:");
260    repr += &(format!("\n  Header      : {}",self.sync));
261    repr += &(format!("\n  Packet Type : {}",self.ptype));
262    repr += &(format!("\n  Timestamp   : {}",self.timestamp));
263    repr += &(format!("\n  Counter     : {}",self.counter));
264    repr += &(format!("\n  Length      : {}",self.length));
265    repr += &(format!("\n  Checksum    : {}>",self.checksum));
266    write!(f, "{}", repr)
267  }
268}
269
270
271/// The acknowledgement packet used within the 
272/// bfsw code
273pub struct AckBfsw {
274  pub header    : TelemetryHeader,
275  pub ack_type  : u8,
276  pub ret_code1 : u8,
277  pub ret_code2 : u8,
278  pub body      : Vec<u8>
279}
280
281impl AckBfsw {
282  pub fn new() -> Self {
283    //let mut header = TelemetryHeader::new(),
284
285    Self {
286      header    : TelemetryHeader::new(),
287      ack_type  : 1,
288      ret_code1 : 0,
289      ret_code2 : 0,
290      body      : Vec::<u8>::new()
291    }
292  }
293  
294  //pub fn to_bytestream(&self) -> Vec<u8> {
295  //  let mut stream = Vec::<u8>::new();
296  //  let mut s_head = self.header.to_bytestream();
297  //  stream.append(&mut s_head);
298  //  stream.extend_from_slice(self.payload.as_slice());
299  //  //stream.append(&mut self.payload);
300  //  stream
301  //}
302}
303
304impl Serialization for AckBfsw {
305  
306  const HEAD : u16 = 0x90eb;
307  const TAIL : u16 = 0x0000; // there is no tail for telemetry packets
308  const SIZE : usize = 13; 
309
310  fn from_bytestream(stream : &Vec<u8>,
311                     pos    : &mut usize)
312    -> Result<Self, SerializationError> {
313    if stream.len() < *pos + 3 {
314      return Err(SerializationError::StreamTooShort);
315    }
316    let mut ack   = AckBfsw::new();
317    ack.ack_type  = parse_u8(stream, pos);
318    ack.ret_code1 = parse_u8(stream, pos);
319    ack.ret_code2 = parse_u8(stream, pos);
320    Ok(ack)
321  }
322  
323  fn to_bytestream(&self) -> Vec<u8> {
324    let mut stream = Vec::<u8>::new();
325    stream.push(self.ack_type);
326    stream.push(self.ret_code1);
327    stream.push(self.ret_code2);
328    stream
329  }
330}
331
332impl Packable for AckBfsw {
333  const PACKET_TYPE : PacketType = PacketType::BfswAckPacket;
334}
335
336impl fmt::Display for AckBfsw {
337  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
338    let mut repr = String::from("<AckBfsw:");
339    //repr += &(format!("\n  Header      : {}" ,self.sync));
340    //repr += &(format!("\n  Packet Type : {}" ,self.ptype));
341    //repr += &(format!("\n  Timestamp   : {}" ,self.timestamp));
342    repr += &(format!("\n  Ack Type    : {}" ,self.ack_type));
343    repr += &(format!("\n  Ret Code1   : {}" ,self.ret_code1));
344    repr += &(format!("\n  Ret Code2   : {}>",self.ret_code2));
345    write!(f, "{}", repr)
346  }
347}
348
349pub struct MergedEvent {
350  
351  pub header              : TelemetryHeader,
352  pub creation_time       : u64,
353  pub event_id            : u32,
354  pub tracker_events      : Vec<TrackerEvent>,
355  /// in case this is version 2, we don't have
356  /// tracker_events, but new-style tracker hits
357  /// (TrackerHitV2)
358  pub tracker_hitsv2      : Vec<TrackerHitV2>,
359  pub tracker_oscillators : Vec<u64>,
360  pub tof_event           : TofEventSummary,
361  pub raw_data            : Vec<u8>,
362  pub flags0              : u8,
363  pub flags1              : u8,
364  pub version             : u8
365}
366
367impl MergedEvent {
368
369  pub fn new() -> Self {
370    let mut tracker_oscillators = Vec::<u64>::new();
371    for _ in 0..10 {
372      tracker_oscillators.push(0);
373    }
374    Self {
375      header              : TelemetryHeader::new(),
376      creation_time       : 0,
377      event_id            : 0,
378      tracker_events      : Vec::<TrackerEvent>::new(),
379      tracker_hitsv2      : Vec::<TrackerHitV2>::new(),
380      tracker_oscillators : tracker_oscillators,
381      tof_event           : TofEventSummary::new(),
382      raw_data            : Vec::<u8>::new(),
383      flags0              : 0,
384      flags1              : 1,
385      version             : 0, 
386    }
387  }
388
389  #[deprecated(since="0.10.2", note="Consider using the public atttribute tof_event instead. This one makes uses of an unnessessary clone operation!")]
390  pub fn get_tofeventsummary(&self) -> Result<TofEventSummary, SerializationError> {
391    return Ok(self.tof_event.clone());
392  }
393
394  pub fn from_bytestream(stream : &Vec<u8>,
395                         pos    : &mut usize)
396    -> Result<Self, SerializationError> {
397    let mut me        = MergedEvent::new();
398    let version      = parse_u8(stream, pos);
399    me.version       = version;
400    //println!("_version {}", _version);
401    me.flags0         = parse_u8(stream, pos);
402    // skip a bunch of Alex newly implemented things
403    // FIXME
404    if version == 0 {
405      me.flags1      = parse_u8(stream, pos);
406    } else {
407      *pos += 8;
408    }
409
410    me.event_id       = parse_u32(stream, pos);
411    //println!("EVENT ID {}", me.event_id);
412    let _tof_delim    = parse_u8(stream, pos);
413    //println!("TOF delim : {}", _tof_delim);
414    if stream.len() <= *pos + 2 {
415      error!("Not able to parse merged event!");
416      return Err(SerializationError::StreamTooShort);
417    }
418   let num_tof_bytes = parse_u16(stream, pos) as usize;
419    //println!("Num TOF bytes : {}", num_tof_bytes);
420    if stream.len() < *pos+num_tof_bytes {
421      error!("Not enough bytes for TOF packet! Expected {}, seen {}", *pos+num_tof_bytes as usize, stream.len());
422      return Err(SerializationError::StreamTooShort); 
423    }
424    let pos_before = *pos;
425    let tof_pack   = TofPacket::from_bytestream(stream, pos)?;
426    let ts         = tof_pack.unpack::<TofEventSummary>()?;
427    // sanity check - is tofpacket as long as num_tof_bytes lets us believe?
428    if pos_before + num_tof_bytes != *pos {
429      println!("Tofpacket {}", tof_pack);
430      error!("Byte misalignment. Expected {num_tof_bytes}, got {pos} - {pos_before}"); 
431      return Err(SerializationError::WrongByteSize);
432    }
433    me.tof_event = ts;
434    let trk_delim    = parse_u8(stream, pos);
435
436    //println!("TRK delim {}", trk_delim);
437    if trk_delim != 0xbb {
438      return Err(SerializationError::HeadInvalid);
439    }
440    if version == 1 {
441      let num_trk_hits = parse_u16(stream, pos);
442      if (*pos + (num_trk_hits as usize)*4 ) > stream.len() {
443        return Err(SerializationError::StreamTooShort);
444      }
445      for _ in 0..num_trk_hits { 
446        let mut hit  = TrackerHitV2::new();
447        let strip_id = parse_u16(stream, pos);
448        let adc      = parse_u16(stream, pos);
449        hit.channel  = strip_id & 0b11111;
450        hit.module   = (strip_id >> 5) & 0b111;
451        hit.row      = (strip_id >> 8) & 0b111;
452        hit.layer    = (strip_id >> 11) & 0b1111;
453        hit.adc      = adc;
454        me.tracker_hitsv2.push(hit);
455      }
456      // oscillators
457      let oscillators_delimiter = parse_u8(stream, pos);
458      if oscillators_delimiter != 0xcc {
459        return Err(SerializationError::HeadInvalid);
460      }
461      let osc_flags = parse_u8(stream, pos);
462      let mut oscillator_idx = Vec::<u8>::new();
463      for j in 0..8 {
464        if (osc_flags >> j & 0b1) > 0 {
465          oscillator_idx.push(j)
466        }
467      }
468      if (*pos + oscillator_idx.len()*6) > stream.len() {
469        return Err(SerializationError::StreamTooShort);
470      }
471      for idx in oscillator_idx.iter() {
472        let lower = parse_u32(stream, pos);
473        let upper = parse_u16(stream, pos);
474        let osc : u64 = (upper as u64) << 32 | (lower as u64);
475        me.tracker_oscillators[*idx as usize] = osc;
476      }
477    } else if version == 0 {
478      let num_trk_bytes = parse_u16(stream, pos);
479      if (num_trk_bytes as usize + *pos - 2) > stream.len() {
480        return Err(SerializationError::StreamTooShort);
481      }
482      //println!("Num TRK bytes : {}", num_trk_bytes);
483      // for now, don't unpack tracker data
484      //*pos += num_trk_bytes as usize;
485      let max_pos = *pos + num_trk_bytes as usize;
486      loop {
487         //if *pos > max_pos {
488         //  //return Err(SerializationError::StreamTooLong);
489         //} 
490         if *pos >= max_pos {
491           break;
492         }
493         if *pos >= stream.len() {
494           break;
495         }
496         let mut te = TrackerEvent::from_bytestream(stream, pos)?;
497         //println!("{}",te);
498         te.event_id = me.event_id;
499         me.tracker_events.push(te);
500         //if(rc < 0)
501         //{
502         //   spdlog::info("DEBUG event.unpack rc = {}", rc);
503         //   return -9;
504         //}
505         //else
506         //{
507         //    tracker_events.push_back(std::move(event));
508         //    i += rc;
509         //}
510      }
511    } else {
512      error!("Unrecognized version {version}!");
513    } 
514    Ok(me)
515  }
516}
517
518impl fmt::Display for MergedEvent {
519  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
520    let mut repr     = String::from("<MergedEvent:");
521    let tof_str  = format!("\n  {}", self.tof_event);
522    let tof_evid = self.tof_event.event_id;
523    let mut good_hits = 0;
524    let mut evids = Vec::<u32>::new();
525    if self.version == 0 {
526      for ev in &self.tracker_events {
527        evids.push(ev.event_id);
528        for h in &ev.hits { 
529          if h.adc != 0 {
530            good_hits += 1;
531          }
532        }
533      evids.sort();
534      evids.dedup();
535      }
536    } else if self.version == 1 {
537      for _ in &self.tracker_hitsv2 {
538        good_hits += 1;
539      }
540    }
541    repr += &(format!("  {}", self.header));
542    repr += "\n  ** ** ** MERGED  ** ** **";
543    repr += &(format!("\n  version         {}", self.version));
544    repr += &(format!("\n  event ID        {}", self.event_id));  
545    if self.version == 0 {
546      repr += &(format!("\n  -- TOF          {}", tof_evid));
547      repr += &(format!("\n  -- TRK          {:?}", evids));
548    }
549    repr += "\n  ** ** ** TRACKER ** ** **";
550    if self.version == 0 {
551      repr += &(format!("\n  N Trk events    {}", self.tracker_events.len()));
552    } else if self.version == 1 {
553      repr += &(format!("\n  Trk oscillators {:?}", self.tracker_oscillators)); 
554    }
555    repr += &(format!("\n  N Good Trk Hits {}", good_hits));
556    repr += &tof_str;
557    write!(f,"{}", repr)
558  }
559}
560
561#[derive(Debug, Clone)]
562pub struct TrackerEvent {
563
564  pub layer      : u8,
565  pub flags1     : u8,
566  pub event_id   : u32,
567  pub event_time : u64,
568  pub hits       : Vec<TrackerHit>,
569}
570
571impl TrackerEvent {
572
573  pub fn new() -> Self {
574    Self { 
575      layer      : 0,
576      flags1     : 0,
577      event_id   : 0,
578      event_time : 0,
579      hits       : Vec::<TrackerHit>::new(),
580    }
581  }
582
583  /// Loop over the filtered hits, returning only those satisfying a condition
584  ///
585  /// # Arguments:
586  /// 
587  /// * filter : filter function - take input hit and decide if it should be 
588  ///            returned
589  pub fn filter_hits(&self, filter : fn(&TrackerHit) -> bool) -> Vec<TrackerHit> {
590    let mut filtered_hits = Vec::<TrackerHit>::new();
591    for h in &self.hits {
592      if filter(h) {
593        filtered_hits.push(*h);
594      }
595    }
596    filtered_hits
597  }
598
599  pub fn from_bytestream(stream : &Vec<u8>,
600                         pos    : &mut usize)
601    -> Result<Self, SerializationError> {
602  if *pos + 8 > stream.len() {
603    return Err(SerializationError::StreamTooShort);
604  }
605  let mut te = TrackerEvent::new();
606  // first timestamp
607  let ts32   = parse_u32(stream, pos);
608  let ts16   = parse_u16(stream, pos);
609  let ts64   = ((ts16 as u64) << 16) | ts32 as u64;
610  te.event_time = ts64;
611  
612  te.layer   = parse_u8(stream, pos);
613  let nhits  = parse_u8(stream, pos); 
614  //println!("See layer {} and nhits {}, expected size {}", te.layer, nhits, nhits as usize * TrackerHit::SIZE); 
615  //panic!("uff der titantic! (na wo sonst wohl?)");
616  for _ in 0..nhits {
617    te.hits.push(TrackerHit::from_bytestream(stream, pos)?);
618  }
619  Ok(te)
620  }
621}
622
623impl fmt::Display for TrackerEvent {
624  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
625    let mut repr = String::from("<TrackerEvent:");
626    repr += &(format!("\n  EventTime     : {}" ,self.event_time));
627    repr += &(format!("\n  EventID       : {}" ,self.event_id));
628    repr += &(format!("\n  Layer         : {}" ,self.layer));
629    repr += &(format!("\n  Flags1        : {}" ,self.flags1));
630    repr += &(format!("\n**** HITS {} ****", self.hits.len()));
631    for h in &self.hits {
632      repr += &(format!("\n {}", h));
633    }
634    write!(f, "{}", repr)
635  }
636}
637
638#[derive(Debug, Copy, Clone)]
639pub struct TrackerHitV2 {
640  pub layer           : u16,
641  pub row             : u16,
642  pub module          : u16,
643  pub channel         : u16,
644  pub adc             : u16,
645  pub oscillator      : u64,
646
647  // not getting serialized
648  pub x               : f32,
649  pub y               : f32,
650  pub z               : f32,
651  pub has_coordinates : bool,
652}
653
654impl TrackerHitV2 {
655  //const SIZE : usize = 18;
656  
657  pub fn new() -> Self {
658    Self {
659      layer           : 0,
660      row             : 0,
661      module          : 0,
662      channel         : 0,
663      adc             : 0,
664      oscillator      : 0,
665      x               : 0.0,
666      y               : 0.0,
667      z               : 0.0,
668      has_coordinates : false,
669    }
670  }
671 
672  /// Calculate the strip id from layer, module, row and channel
673  pub fn get_stripid(&self) -> u32 {
674    self.channel as u32 + (self.module as u32)*100 + (self.row as u32)*10000 + (self.layer as u32)*10000
675  }
676
677  pub fn set_coordinates(&mut self, strip_map : &HashMap<u32, TrackerStrip>) {
678    match strip_map.get(&self.get_stripid()) {
679      None  => error!("Can not get strip for strip id {}" , self.get_stripid()),
680      Some(strip) => { 
681        self.x = strip.global_pos_x_l0;
682        self.y = strip.global_pos_y_l0;
683        self.z = strip.global_pos_z_l0;
684      }
685    }
686  }
687}
688
689impl fmt::Display for TrackerHitV2 {
690  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
691    let mut repr = String::from("<TrackerHitV2:");
692    repr += &(format!("\n  Layer, Row, Module, Channel : {} {} {} {}" ,self.layer, self.row, self.module, self.channel));
693    repr += &(format!("\n  ADC           : {}" ,self.adc));
694    repr += &(format!("\n  Oscillator    : {}",self.oscillator));
695    if self.has_coordinates {
696      repr += &(format!("\n -- coordinates x : {} , y : {} , z {}>", self.x, self.y, self.z));
697    } else {
698      repr += "\n -- [no coordinates set]>";
699    }
700    write!(f, "{}", repr)
701  }
702}
703
704#[derive(Debug, Copy, Clone)]
705pub struct TrackerHit {
706  pub row             : u8,
707  pub module          : u8,
708  pub channel         : u8,
709  pub adc             : u16,
710  pub asic_event_code : u8,
711}
712
713impl TrackerHit {
714  const SIZE : usize = 6;
715
716  pub fn new() -> Self {
717    Self {
718      row             : 0,
719      module          : 0,
720      channel         : 0,
721      adc             : 0,
722      asic_event_code : 0,
723    }
724  }
725
726  pub fn from_bytestream(stream : &Vec<u8>,
727                         pos    : &mut usize)
728    -> Result<Self, SerializationError> {
729    if *pos + Self::SIZE > stream.len() {
730      return Err(SerializationError::StreamTooShort);
731    }
732
733    let mut th         = TrackerHit::new();
734    th.row             = parse_u8(stream, pos);
735    th.module          = parse_u8(stream, pos);
736    th.channel         = parse_u8(stream, pos);
737    th.adc             = parse_u16(stream, pos);
738    th.asic_event_code = parse_u8(stream, pos);
739    Ok(th)
740  } 
741}
742
743impl fmt::Display for TrackerHit {
744  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
745    let mut repr = String::from("<TrackerHit:");
746    repr += &(format!("\n  Row           : {}" ,self.row));
747    repr += &(format!("\n  Module        : {}" ,self.module));
748    repr += &(format!("\n  Channel       : {}" ,self.channel));
749    repr += &(format!("\n  ADC           : {}" ,self.adc));
750    repr += &(format!("\n  ASIC Ev. Code : {}>",self.asic_event_code));
751    write!(f, "{}", repr)
752  }
753}
754
755#[derive(Clone)]
756pub struct TrackerHeader {
757  pub sync        : u16,
758  pub crc         : u16,
759  pub sys_id      : u8,
760  pub packet_id   : u8,
761  pub length      : u16,
762  pub daq_count   : u16,
763  pub sys_time    : u64,
764  pub version     : u8,
765} 
766
767impl TrackerHeader {
768  
769  pub const SIZE : usize = 17;
770
771  pub fn new() -> Self {
772    Self {
773      sync        : 0,
774      crc         : 0,
775      sys_id      : 0,
776      packet_id   : 0,
777      length      : 0,
778      daq_count   : 0,
779      sys_time    : 0,
780      version     : 0,
781    }
782  }
783
784  pub fn from_bytestream(stream: &Vec<u8>,
785                         pos: &mut usize)
786    -> Result<Self, SerializationError> {
787    if stream.len() <= Self::SIZE {
788      error!("Unable to decode TrackerHeader!"); 
789      return Err(SerializationError::StreamTooShort);
790    }
791    let mut h     = TrackerHeader::new();
792    h.sync        = parse_u16(stream, pos);
793    h.crc         = parse_u16(stream, pos); 
794    h.sys_id      = parse_u8 (stream, pos);
795    h.packet_id   = parse_u8 (stream, pos);
796    h.length      = parse_u16(stream, pos);
797    h.daq_count   = parse_u16(stream, pos);
798    let lower     = parse_u32(stream, pos);
799    let upper     = parse_u16(stream, pos);
800    h.sys_time    = make_systime(lower, upper);
801    h.version     = parse_u8 (stream, pos);
802    Ok(h)
803  }
804}
805
806impl fmt::Display for TrackerHeader {
807  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
808    let mut repr = String::from("<TrackerHeader");
809    repr    += &(format!("\n  Sync     : {}", self.sync));
810    repr    += &(format!("\n  Crc      : {}", self.crc));
811    repr    += &(format!("\n  PacketID : {}", self.packet_id));
812    repr    += &(format!("\n  Length   : {}", self.length));
813    repr    += &(format!("\n  DAQ Cnt  : {}", self.daq_count));
814    repr    += &(format!("\n  Sys Time : {}", self.sys_time));
815    repr    += &(format!("\n  Version  : {}>", self.version));
816    write!(f, "{}", repr)
817  }
818}
819
820
821pub struct GPSPacket {
822  pub telemetry_header : TelemetryHeader,
823  pub tracker_header   : TrackerHeader,
824  pub utc_time         : u32,
825  pub gps_info         : u8
826}
827
828impl GPSPacket {
829  pub fn new() -> Self {
830    Self {
831      telemetry_header : TelemetryHeader::new(),
832      tracker_header   : TrackerHeader::new(),
833      utc_time         : 0,
834      gps_info         : 0,
835    }
836  }
837  
838  pub fn from_bytestream(stream: &Vec<u8>,
839                         pos: &mut usize)
840    -> Result<Self, SerializationError> {
841    let mut gps_p       = GPSPacket::new();
842    gps_p.tracker_header   = TrackerHeader::from_bytestream(stream, pos)?;
843    if stream.len() == *pos as usize {
844      error!("Packet contains only header!");
845      return Ok(gps_p);
846    }
847    gps_p.utc_time = parse_u32(stream, pos);
848    gps_p.gps_info = parse_u8(stream, pos);
849    Ok(gps_p)
850  }
851}
852
853impl fmt::Display for GPSPacket {
854  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
855    let mut repr = String::from("<GPSPacket");
856    repr    += &(format!("\n {}", self.telemetry_header));
857    repr    += &(format!("\n {}", self.tracker_header));
858    repr    += "\n*** GPS TIME ***";
859    repr    += &(format!("\n UTC TIME (32bit) {}", self.utc_time));
860    repr    += &(format!("\n GSP INFO (8bit)  {}", self.gps_info));
861    repr    += ">";
862    write!(f, "{}", repr)
863  }
864}
865
866/// Re-implementation of Alex' tracker packet
867pub struct TrackerPacket {
868  pub telemetry_header : TelemetryHeader,
869  pub tracker_header   : TrackerHeader,
870  pub events           : Vec<TrackerEvent>,
871}
872
873impl fmt::Display for TrackerPacket {
874  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
875    let mut repr = String::from("<TrackerPacket");
876    repr    += &(format!("\n {}", self.telemetry_header));
877    repr    += &(format!("\n {}", self.tracker_header));
878    repr    += "\n*** Events ***";
879    for ev in &self.events {
880      repr  += &(format!("\n {}", ev));
881    }
882    repr    += ">";
883    write!(f, "{}", repr)
884  }
885}
886
887impl TrackerPacket {
888  pub fn new() -> Self {
889    Self {
890      telemetry_header : TelemetryHeader::new(),
891      tracker_header   : TrackerHeader::new(),
892      events           : Vec::<TrackerEvent>::new(),
893    }
894  }
895  
896  pub fn from_bytestream(stream: &Vec<u8>,
897                         pos: &mut usize)
898    -> Result<Self, SerializationError> {
899    let mut tp          = TrackerPacket::new();
900    tp.tracker_header   = TrackerHeader::from_bytestream(stream, pos)?;
901    if stream.len() == *pos as usize {
902      error!("Packet contains only header!");
903      return Ok(tp);
904    }
905    let _settings       = parse_u8(stream, pos);
906
907    loop {    
908      let mut event    = TrackerEvent::new();
909      event.layer      = tp.tracker_header.sys_id;
910      if *pos + 12 > stream.len() {
911        error!("Unable to decode header part for tracker event!");
912        return Err(SerializationError::StreamTooShort);
913      }
914      let num_hits     = parse_u8(stream, pos);
915      event.flags1     = parse_u8(stream, pos);
916      event.event_id   = parse_u32(stream, pos);
917      let ts32         = parse_u32(stream, pos);
918      let ts16         = parse_u16(stream, pos);
919      event.event_time = (ts16 as u64) << 32 | ts32 as u64;
920      if num_hits > 192 {
921        //isn't a real event, looking at filler bytes.
922        //once event packets stop having filler,
923        //logic here will need to change
924        break; 
925      }
926      if *pos + 3*(num_hits as usize) > stream.len() {
927        error!("We expect {} hits, but the stream is not long enough!", num_hits);
928        return Err(SerializationError::StreamTooShort);
929      }
930      for _ in 0..num_hits {
931        let h0 = parse_u8(stream, pos);
932        let h1 = parse_u8(stream, pos);
933        let h2 = parse_u8(stream, pos);
934        let asic_event_code : u8 = h2 >> 6;
935        let channel : u8  = h0 & 0x1f;
936        let module  : u8  = h0 >> 5;
937        let row     : u8  = h1 & 0x7;
938        let adc     : u16 = (((h2 as u16) & 0x3f) << 5) | (h1 as u16) >> 3; 
939        event.hits.push(TrackerHit { row, module, channel, adc, asic_event_code});
940      }
941      tp.events.push(event);
942      if tp.events.len() > 170 {
943        error!(">170 events in this packet!");
944        return Err(SerializationError::StreamTooLong);
945      }
946    }
947    Ok(tp)
948  }
949}
950      
951pub struct TrackerTempLeakPacket {
952  pub telemetry_header : TelemetryHeader,
953  pub tracker_header   : TrackerHeader,
954  pub row_offset       : u8,
955  pub templeak         : [[u32;6];6],
956  pub seu              : [[u32;6];6]
957}
958
959impl fmt::Display for TrackerTempLeakPacket {
960  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
961    let mut repr = String::from("<TrackerTempLeakPacket");
962    repr    += &(format!("\n {}", self.telemetry_header));
963    repr    += &(format!("\n {}", self.tracker_header));
964    repr    += &(format!("\n ROW OFFSET {}", self.row_offset));
965    repr    += "\n*** TEMPLEAK ***";
966    for k in 0..6 {
967      repr  += &(format!("\n {:?}", self.templeak[k]));
968    }
969    repr    += "\n*** SEU ***";
970    for k in 0..6 {
971      repr  += &(format!("\n {:?}", self.seu[k]));
972    }
973    repr    += ">";
974    write!(f, "{}", repr)
975  }
976}
977
978impl TrackerTempLeakPacket {
979  pub fn new() -> Self {
980    Self {
981      telemetry_header : TelemetryHeader::new(),
982      tracker_header   : TrackerHeader::new(),
983      row_offset       : 0,
984      templeak         : [[0;6];6],
985      seu              : [[0;6];6]
986    }
987  }
988  
989  pub fn from_bytestream(stream: &Vec<u8>,
990                         pos: &mut usize)
991    -> Result<Self, SerializationError> {
992    let mut tp          = TrackerTempLeakPacket::new();
993    tp.tracker_header   = TrackerHeader::from_bytestream(stream, pos)?;
994    if stream.len() == *pos as usize {
995      error!("Packet contains only header!");
996      return Ok(tp);
997    }
998    if stream.len() - *pos < (36*3 + 1) {
999      return Err(SerializationError::StreamTooShort);
1000    }
1001    let row_info = parse_u8(stream, pos);
1002    tp.row_offset = row_info & 0x7;
1003    for row in 0..6 {
1004      for module in 0..6 {
1005        let b0 = parse_u8(stream, pos) as u32;
1006        let b1 = parse_u8(stream, pos) as u32;
1007        let b2 = parse_u8(stream, pos) as u32;
1008        let seu_ : u32 = b2 >> 1;
1009        let mut templeak_ : u32 = (b2 << 10) | (b1 << 2)  | (b0 >> 6);
1010        templeak_ &= 0x7ff;
1011        tp.templeak[row][module] = templeak_;
1012        tp.seu[row][module] = seu_;
1013      }
1014    }
1015    Ok(tp)
1016  }
1017}
1018
1019pub struct TrackerDAQTempPacket {
1020  pub telemetry_header : TelemetryHeader,
1021  pub tracker_header   : TrackerHeader,
1022  pub rom_id           : [u64;256],
1023  pub temp             : [u16;256]
1024}
1025
1026impl fmt::Display for TrackerDAQTempPacket {
1027  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1028    let mut repr = String::from("<TrackerDAQTempPacket");
1029    repr    += &(format!("\n {}", self.telemetry_header));
1030    repr    += &(format!("\n {}", self.tracker_header));
1031    repr    += "\n*** ROM ID ***";
1032    repr  += &(format!("\n {:?}", self.rom_id));
1033    repr    += "\n*** TEMP ***";
1034    repr  += &(format!("\n {:?}>", self.temp));
1035    write!(f, "{}", repr)
1036  }
1037}
1038
1039impl TrackerDAQTempPacket {
1040  pub fn new() -> Self {
1041    Self {
1042      telemetry_header : TelemetryHeader::new(),
1043      tracker_header   : TrackerHeader::new(),
1044      rom_id           : [0;256],
1045      temp             : [0;256]
1046    }
1047  }
1048  
1049  pub fn from_bytestream(stream: &Vec<u8>,
1050                         pos: &mut usize)
1051    -> Result<Self, SerializationError> {
1052    let mut tp          = TrackerDAQTempPacket::new();
1053    tp.tracker_header   = TrackerHeader::from_bytestream(stream, pos)?;
1054    if tp.tracker_header.packet_id != 0x09 {
1055      error!("This is not a TrackerDAQTempPacket, but has packet_id {} instead!", tp.tracker_header.packet_id);
1056      return Err(SerializationError::IncorrectPacketType);
1057    }
1058    debug!("tracker header {}", tp.tracker_header);
1059    if stream.len() == *pos as usize {
1060      error!("Packet contains only header!");
1061      return Ok(tp);
1062    }
1063    //if stream.len() - *pos < (36*3 + 1) {
1064    //  return Err(SerializationError::StreamTooShort);
1065    //}
1066    // this is hack, since the TreckerHeader in this packet does not have a 
1067    // version (-> Alex) 
1068    *pos -= 1;
1069    let dummy64 = 0u64;
1070    let dummy16 = 0u16;
1071    error!("{}", tp.tracker_header);
1072    error!("Expected of the packet {}", (tp.tracker_header.length as usize)/2);
1073    for k in 0..256usize {
1074      if k < (tp.tracker_header.length as usize)/2 {
1075        tp.rom_id[k] = parse_u64(stream, pos);
1076        tp.temp[k]   = parse_u16(stream, pos);
1077      } else {
1078        tp.rom_id[k] = dummy64;
1079        tp.temp[k]   = dummy16;
1080      }
1081    }
1082    Ok(tp)
1083  }
1084}
1085
1086pub struct TrackerDAQHSKPacket {
1087  pub telemetry_header : TelemetryHeader,
1088  pub tracker_header   : TrackerHeader,
1089  pub temp             : [u16;12],
1090}
1091
1092impl fmt::Display for TrackerDAQHSKPacket {
1093  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1094    let mut repr = String::from("<TrackerDAQHSKPacket");
1095    repr    += &(format!("\n {}", self.telemetry_header));
1096    repr    += &(format!("\n {}", self.tracker_header));
1097    repr    += "\n*** TEMP ***";
1098    repr    += &(format!("\n {:?}>", self.temp));
1099    write!(f, "{}", repr)
1100  }
1101}
1102
1103impl TrackerDAQHSKPacket {
1104  pub fn new() -> Self {
1105    Self {
1106      telemetry_header : TelemetryHeader::new(),
1107      tracker_header   : TrackerHeader::new(),
1108      temp             : [0;12]
1109    }
1110  }
1111  
1112  pub fn from_bytestream(stream: &Vec<u8>,
1113                         pos: &mut usize)
1114    -> Result<Self, SerializationError> {
1115    let mut tp          = TrackerDAQHSKPacket::new();
1116    tp.tracker_header   = TrackerHeader::from_bytestream(stream, pos)?;
1117    if tp.tracker_header.packet_id != 0xff {
1118      error!("This is not a TrackerDAQHSKPacket, but has packet_id {} instead!", tp.tracker_header.packet_id);
1119      return Err(SerializationError::IncorrectPacketType);
1120    }
1121    if stream.len() == *pos as usize {
1122      error!("Packet contains only header!");
1123      return Ok(tp);
1124    }
1125    //if stream.len() - *pos < (36*3 + 1) {
1126    //  return Err(SerializationError::StreamTooShort);
1127    //}
1128    // this is hack, since the TreckerHeader in this packet does not have a 
1129    // version (-> Alex) 
1130    *pos += 193; // skip a bunch of other stuff right now (Alex)
1131    for k in 0..12usize {
1132      tp.temp[k]   = parse_u16(stream, pos);
1133    }
1134    Ok(tp)
1135  }
1136}
1137
1138pub struct TrackerEventIDEchoPacket {
1139  pub telemetry_header : TelemetryHeader,
1140  pub tracker_header   : TrackerHeader,
1141  pub temp             : [u16;12],
1142  pub event_id         : u32,
1143  pub event_id_errors  : u16,
1144}
1145
1146impl fmt::Display for TrackerEventIDEchoPacket {
1147  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1148    let mut repr = String::from("<TrackerEventIDEchoPacket");
1149    repr    += &(format!("\n {}", self.telemetry_header));
1150    repr    += &(format!("\n {}", self.tracker_header));
1151    repr    += "\n*** TEMP ***";
1152    repr    += &(format!("\n {:?}>", self.temp));
1153    write!(f, "{}", repr)
1154  }
1155}
1156
1157impl TrackerEventIDEchoPacket {
1158  pub fn new() -> Self {
1159    Self {
1160      telemetry_header : TelemetryHeader::new(),
1161      tracker_header   : TrackerHeader::new(),
1162      temp             : [0;12],
1163      event_id         : 0,
1164      event_id_errors  : 0,
1165    }
1166  }
1167  
1168  pub fn from_bytestream(stream: &Vec<u8>,
1169                         pos: &mut usize)
1170    -> Result<Self, SerializationError> {
1171    let mut tp          = TrackerEventIDEchoPacket::new();
1172    tp.tracker_header   = TrackerHeader::from_bytestream(stream, pos)?;
1173    if tp.tracker_header.packet_id != 0x03 {
1174      error!("This is not a TrackerEventIDEchoPacket, but has packet_id {} instead!", tp.tracker_header.packet_id);
1175      return Err(SerializationError::IncorrectPacketType);
1176    }
1177    if stream.len() == *pos as usize {
1178      error!("Packet contains only header!");
1179      return Ok(tp);
1180    }
1181    //if stream.len() - *pos < (36*3 + 1) {
1182    //  return Err(SerializationError::StreamTooShort);
1183    //}
1184    tp.event_id        = parse_u32(stream, pos);
1185    tp.event_id_errors = parse_u16(stream, pos);
1186    Ok(tp)
1187  }
1188}
1189
1190
1191/// This is mine :) Not telemetry
1192pub struct GapsTracker {
1193
1194}
1195
1196pub struct GapsEvent {
1197  pub tof     : TofEventSummary,
1198  pub tracker : Vec<TrackerEvent>
1199}
1200
1201impl GapsEvent {
1202  pub fn new() -> Self {
1203    Self {
1204      tof     : TofEventSummary::new(),
1205      tracker : Vec::<TrackerEvent>::new(),
1206    }
1207  }
1208}
1209
1210impl fmt::Display for GapsEvent {
1211  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1212    let mut repr = String::from("<GapsEvent");
1213    repr    += "\n  *** TOF ***";
1214    repr    += &(format!("\n  {}", self.tof));
1215    repr    += "*** TRACKER ***";
1216    for ev in &self.tracker {
1217      repr    += &(format!("\n  -- {}", ev));
1218    }
1219    repr    += ">";
1220    write!(f, "{}", repr)
1221  }
1222}
1223
1224