tof_dataclasses/
status.rs

1//! Detector status indicators
2//!
3
4use std::fmt;
5use std::collections::HashMap;
6
7cfg_if::cfg_if! {
8  if #[cfg(feature = "random")]  {
9    use crate::FromRandom;
10    use rand::Rng;
11  }
12}
13
14use crate::serialization::{
15  Serialization,
16  SerializationError,
17  Packable,
18  parse_u32
19};
20
21use crate::packets::PacketType;
22
23/// Report dead channels/non-active detectors
24/// for the TOF system
25///
26/// This is a very simple approach
27/// A channels are the paddle_id - 1
28/// while B channels are encoded as paddle_id - 159
29///
30/// Dead channels will be 0, active channels 
31/// will be 1
32#[derive(Debug, Copy, Clone, PartialEq)]
33pub struct TofDetectorStatus {
34  pub channels000_031 : u32,
35  pub channels032_063 : u32,
36  pub channels064_095 : u32,
37  pub channels096_127 : u32,
38  pub channels128_159 : u32,
39  pub channels160_191 : u32,
40  pub channels192_223 : u32,
41  pub channels224_255 : u32,
42  pub channels256_297 : u32,
43  pub channels298_319 : u32,
44}
45
46impl TofDetectorStatus {
47 
48  pub fn new() -> Self {
49    Self {
50      channels000_031 : 0xFFFFFFFF,
51      channels032_063 : 0xFFFFFFFF,
52      channels064_095 : 0xFFFFFFFF,
53      channels096_127 : 0xFFFFFFFF,
54      channels128_159 : 0xFFFFFFFF,
55      channels160_191 : 0xFFFFFFFF,
56      channels192_223 : 0xFFFFFFFF,
57      channels224_255 : 0xFFFFFFFF,
58      channels256_297 : 0xFFFFFFFF,
59      channels298_319 : 0xFFFFFFFF,
60    }
61  }
62
63  /// Update the dead channel list form a HashMap with 
64  /// paddle information as it is created in the 
65  /// RB communication threads of liftof-cc
66  pub fn update_from_map(&mut self, paddles : HashMap<u16,bool>) {
67    for k in 0..320 {
68      if let Some(val) = paddles.get(&(&k + 1)) {
69        if k < 32 && *val {
70          self.channels000_031 = self.channels000_031 | (k as u32) ;
71        } else if k < 64 && *val  {
72          self.channels032_063 = self.channels032_063 | (k as u32) - 32;
73        } else if k < 96 && *val  {
74          self.channels064_095 = self.channels064_095 | (k as u32) - 64;
75        } else if k < 128 && *val {
76          self.channels096_127 = self.channels096_127 | (k as u32) - 96;
77        } else if k < 160 && *val {
78          self.channels128_159 = self.channels128_159 | (k as u32) - 125;
79        } else if k < 192 && *val {
80          self.channels160_191 = self.channels160_191 | (k as u32) - 160;
81        } else if k < 224 && *val {
82          self.channels192_223 = self.channels192_223 | (k as u32) - 192;
83        } else if k < 256 && *val {
84          self.channels224_255 = self.channels224_255 | (k as u32) - 224;
85        } else if k < 298 && *val {
86          self.channels256_297 = self.channels256_297 | (k as u32) - 256;
87        } else if k < 320 && *val {
88          self.channels298_319 = self.channels298_319 | (k as u32) - 298;
89        }
90      } else {
91        error!("No entry in paddle status map for channel {}", k);
92        continue;
93      }
94    }
95  }
96
97  /// Get all paddle ids which have dead 
98  /// channels on the A-side
99  pub fn get_dead_paddles_a(&self) -> Vec<u8> {
100    let mut dead_a = Vec::<u8>::new();
101    let inactive = self.get_inactive_channels_idx();
102    for k in inactive.iter() {
103      if *k < 160 {
104        dead_a.push(*k as u8);
105      }
106    }
107    dead_a
108  }
109
110  /// Get all paddle ids which have dead 
111  /// channels on the B-side
112  pub fn get_dead_paddles_b(&self) -> Vec<u8> {
113    let mut dead_b = Vec::<u8>::new();
114    let inactive = self.get_inactive_channels_idx();
115    for k in inactive.iter() {
116      if *k >= 160 {
117        dead_b.push((*k-159) as u8);
118      }
119    }
120    dead_b
121  }
122
123  /// Index of inactive channels in the range of 
124  /// 0-319. These indizes are MTBChannel numbers
125  fn get_inactive_channels_idx(&self) -> Vec<u16> {
126    let mut channels = Vec::<u16>::new();
127    for k in 0..10 {
128      if (self.channels000_031 >> k & 0x1) == 1 {
129        channels.push(k);
130      }
131    }
132    for k in 0..10 {
133      if (self.channels032_063 >> k & 0x1) == 1 {
134        channels.push(k + 32);
135      }
136    }
137    for k in 0..10 {
138      if (self.channels064_095 >> k & 0x1) == 1 {
139        channels.push(k + 64);
140      }
141    }
142    for k in 0..10 {
143      if (self.channels096_127 >> k & 0x1) == 1 {
144        channels.push(k + 96);
145      }
146    }
147    for k in 0..10 {
148      if (self.channels128_159 >> k & 0x1) == 1 {
149        channels.push(k + 128);
150      }
151    }
152    for k in 0..10 {
153      if (self.channels160_191 >> k & 0x1) == 1 {
154        channels.push(k + 160);
155      }
156    }
157    for k in 0..10 {
158      if (self.channels192_223 >> k & 0x1) == 1 {
159        channels.push(k + 192);
160      }
161    }
162    for k in 0..10 {
163      if (self.channels224_255 >> k & 0x1) == 1 {
164        channels.push(k + 224);
165      }
166    }
167    for k in 0..10 {
168      if (self.channels256_297 >> k & 0x1) == 1 {
169        channels.push(k + 256);
170      }
171    }
172    for k in 0..10 {
173      if (self.channels298_319 >> k & 0x1) == 1 {
174        channels.push(k + 298);
175      }
176    }
177    channels
178  }
179
180  ///// Index of inactive channels in the range of 
181  ///// 0-319. These indizes are MTBChannel numbers
182  //fn get_active_channels_idx(&self) -> Vec<u16> {
183  //  let inactive_channels   = self.get_inactive_channels_idx();
184  //  let mut active_channels = Vec::<u16>::new();
185  //  for ch in 0..329 {
186  //    if !inactive_channels.contains(&ch) {
187  //      active_channels.push(ch);
188  //    }
189  //  }
190  //  active_channels
191  //}
192}
193
194impl Default for TofDetectorStatus {
195  fn default() -> Self {
196    Self::new()
197  }
198}
199
200impl Serialization for TofDetectorStatus {
201  const HEAD : u16   = 0xAAAA;
202  const TAIL : u16   = 0x5555;
203  const SIZE : usize = 44; 
204  
205  fn from_bytestream(stream     : &Vec<u8>,
206                     pos        : &mut usize)
207    -> Result<Self, SerializationError>{
208      Self::verify_fixed(stream, pos)?;
209      let mut status = TofDetectorStatus::new();
210      status.channels000_031 = parse_u32(stream, pos); 
211      status.channels032_063 = parse_u32(stream, pos); 
212      status.channels064_095 = parse_u32(stream, pos); 
213      status.channels096_127 = parse_u32(stream, pos); 
214      status.channels128_159 = parse_u32(stream, pos); 
215      status.channels160_191 = parse_u32(stream, pos); 
216      status.channels192_223 = parse_u32(stream, pos); 
217      status.channels224_255 = parse_u32(stream, pos); 
218      status.channels256_297 = parse_u32(stream, pos); 
219      status.channels298_319 = parse_u32(stream, pos); 
220      *pos += 2;
221      Ok(status)
222  } 
223  
224  fn to_bytestream(&self) -> Vec<u8> {
225    let mut bs = Vec::<u8>::with_capacity(Self::SIZE);
226    bs.extend_from_slice(&Self::HEAD.to_le_bytes());
227    bs.extend_from_slice(&self.channels000_031.to_le_bytes());
228    bs.extend_from_slice(&self.channels032_063.to_le_bytes());
229    bs.extend_from_slice(&self.channels064_095.to_le_bytes());
230    bs.extend_from_slice(&self.channels096_127.to_le_bytes());
231    bs.extend_from_slice(&self.channels128_159.to_le_bytes());
232    bs.extend_from_slice(&self.channels160_191.to_le_bytes());
233    bs.extend_from_slice(&self.channels192_223.to_le_bytes());
234    bs.extend_from_slice(&self.channels224_255.to_le_bytes());
235    bs.extend_from_slice(&self.channels256_297.to_le_bytes());
236    bs.extend_from_slice(&self.channels298_319.to_le_bytes());
237    bs.extend_from_slice(&Self::TAIL.to_le_bytes());
238    bs
239  }
240}
241
242impl Packable for TofDetectorStatus {
243  const PACKET_TYPE : PacketType = PacketType::TofDetectorStatus;
244}
245
246impl fmt::Display for TofDetectorStatus {
247  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
248    let mut repr : String = String::from("<TofDetectorStatus");
249    repr += &(format!("\n Ch 000 - 031 {:x}", &self.channels000_031));
250    repr += &(format!("\n Ch 032 - 063 {:x}", &self.channels032_063));
251    repr += &(format!("\n Ch 064 - 095 {:x}", &self.channels064_095));
252    repr += &(format!("\n Ch 096 - 127 {:x}", &self.channels096_127));
253    repr += &(format!("\n Ch 128 - 159 {:x}", &self.channels128_159));
254    repr += &(format!("\n Ch 160 - 191 {:x}", &self.channels160_191));
255    repr += &(format!("\n Ch 192 - 223 {:x}", &self.channels192_223));
256    repr += &(format!("\n Ch 224 - 255 {:x}", &self.channels224_255));
257    repr += &(format!("\n Ch 256 - 297 {:x}", &self.channels256_297));
258    repr += &(format!("\n Ch 298 - 319 {:x}>", &self.channels298_319));
259    write!(f, "{}", repr)
260  }
261}
262
263#[cfg(feature = "random")]
264impl FromRandom for TofDetectorStatus {
265  fn from_random() -> Self {
266    let mut status  = TofDetectorStatus::new();
267    let mut rng     = rand::thread_rng();
268    status.channels000_031 = rng.gen::<u32>();
269    status.channels032_063 = rng.gen::<u32>();
270    status.channels064_095 = rng.gen::<u32>();
271    status.channels096_127 = rng.gen::<u32>();
272    status.channels128_159 = rng.gen::<u32>();
273    status.channels160_191 = rng.gen::<u32>();
274    status.channels192_223 = rng.gen::<u32>();
275    status.channels224_255 = rng.gen::<u32>();
276    status.channels256_297 = rng.gen::<u32>();
277    status.channels298_319 = rng.gen::<u32>();
278    status
279  }
280}
281
282#[cfg(feature = "random")]
283#[test]
284fn pack_tofdetectorstatus() {
285  for _ in 0..100 {
286    let status  = TofDetectorStatus::from_random();
287    let test : TofDetectorStatus = status.pack().unpack().unwrap();
288    assert_eq!(status, test);
289  }
290}
291