gondola_core/events/
tracker_daq_event_packet.rs1use crate::prelude::*;
9
10#[derive(Debug, Clone, PartialEq)]
13#[cfg_attr(feature="pybindings", pyclass)]
14pub struct TrackerDAQEventPacket {
15 pub header : TelemetryPacketHeader,
16 pub daq_header : TrackerHeader,
17 pub events : Vec<TrackerDAQEvent>,
18 pub run_id : u16,
19 pub run_id_old : u8,
20 pub n_hits : u16,
24}
25
26impl TrackerDAQEventPacket {
27
28 pub fn new() -> Self {
29 Self {
30 header : TelemetryPacketHeader::new(),
31 daq_header : TrackerHeader::new(),
32 events : Vec::<TrackerDAQEvent>::new(),
33 run_id : 0,
34 run_id_old : 0,
35 n_hits : 0,
36 }
37 }
38
39 pub fn emit_empty(&self) -> Self {
44 Self {
45 header : self.header.clone(),
46 daq_header : self.daq_header.clone(),
47 events : Vec::<TrackerDAQEvent>::new(),
48 run_id : self.run_id,
49 run_id_old : self.run_id_old,
50 n_hits : self.n_hits,
51 }
52 }
53
54 pub fn add_event(&mut self, ev : TrackerDAQEvent) {
56 self.events.push(ev);
57 }
58
59
60 pub fn clear_events(&mut self) {
63 self.events.clear();
64 }
65
66 pub fn pack(&self) -> TelemetryPacket {
68 let mut tp = TelemetryPacket::new();
69 tp.header = self.header.clone();
70 tp.payload = self.to_bytestream();
71 tp.header.length = TelemetryPacketHeader::SIZE as u16 + tp.payload.len() as u16;
74 tp
76 }
77
78 pub fn remove_event(&mut self,evid : u32) {
86 self.events.retain(|x| x.event_id != evid);
87 }
88
89 pub fn get_hits(&self) -> Vec<TrackerHit> {
92 let mut hits = Vec::<TrackerHit>::new();
93 for ev in &self.events {
94 hits.extend_from_slice(&ev.hits);
95 }
96 hits
97 }
98
99 pub fn get_event_ids(&self) -> Vec<u32> {
102 let mut evids = Vec::<u32>::new();
103 for ev in &self.events {
104 evids.push(ev.event_id);
105 }
106 evids
107 }
108
109 pub fn get_event_for_evid(&self, evid : u32) -> Option<TrackerDAQEvent> {
111 for ev in &self.events {
112 if ev.event_id == evid {
113 return Some(ev.clone())
114 }
115 }
116 None
117 }
118
119 pub fn get_hits_for_evid(&self, evid : u32) -> Vec<TrackerHit> {
121 let mut hits = Vec::<TrackerHit>::new();
122 for ev in &self.events {
123 if ev.event_id == evid {
124 hits.extend_from_slice(&ev.hits);
125 }
126 }
127 hits
128 }
129
130 pub fn from_telemetrypacket(packet : &TelemetryPacket) -> Result<Self, SerializationError> {
131 match Self::from_bytestream(&packet.payload, &mut 0) {
132 Ok(mut event) => {
133 event.header = packet.header.clone();
134 return Ok(event);
135 }
136 Err(err) => {
137 return Err(err);
138 }
139 }
140 }
141}
142
143impl Serialization for TrackerDAQEventPacket {
144
145 fn from_bytestream(stream : &Vec<u8>,
146 pos : &mut usize)
147 -> Result<Self, SerializationError> {
148 let mut ev = Self::new();
149 ev.daq_header = TrackerHeader::from_bytestream(stream, pos)?;
150 if ev.daq_header.version >= 5 {
151 ev.run_id = parse_u16(stream, pos);
152 } else {
153 ev.run_id_old = parse_u8(stream, pos);
154 }
155 let event_header_size = 12usize;
156 loop {
157 if ev.events.len() > 170 {
158 error!("There seem to be more than 170 events (!) in the tracker. This is nonsense!");
159 return Err(SerializationError::TooManyTrackerEvents);
160 }
161 if ev.daq_header.version >= 4 {
162 if *pos + 1 == stream.len() {
163 if stream[*pos] == 0xff {
164 return Ok(ev);
165 }
166 }
167 if *pos == stream.len() {
168 return Ok(ev);
169 }
170 }
171 if *pos + event_header_size > stream.len() {
172 error!("Unable to read more TrackerEvents! Stream is too short!");
173 println!("{}", ev);
174 println!("pos {} , stream {}",pos, stream.len());
175 println!("Unable to read more TrackerEvents! Stream is too short!");
176 return Err(SerializationError::StreamTooShort);
177 }
178
179 let mut daq_event = TrackerDAQEvent::new();
180 daq_event.layer = ev.daq_header.sys_id;
181 let n_hits = parse_u8(stream, pos);
182 daq_event.flags1 = parse_u8(stream, pos);
183 daq_event.event_id = parse_u32(stream, pos);
184 daq_event.event_time32 = parse_u32(stream, pos);
185 daq_event.event_time16 = parse_u16(stream, pos);
186 if n_hits > 192 {
187 error!("We see more than 192 hits in the event! This seems to be an issue.");
188 return Err(SerializationError::TooManyTrackerHits);
189 }
190 if (*pos + (3*(n_hits as usize))) > stream.len() {
191 error!("Unable to read all {} tracker hits! Stream is too short!", n_hits);
192 println!("Unable to read all {} tracker hits! Stream is too short!", n_hits);
193 return Err(SerializationError::StreamTooShort);
194 }
195 for _ in 0..n_hits {
196 let h0 = parse_u8(stream, pos);
197 let h1 = parse_u8(stream, pos);
198 let h2 = parse_u8(stream, pos);
199 let asic_event_code = h2 >> 6;
200 let channel = h0 & 0b11111;
201 let module = h0 >> 5;
202 let row = h1 & 0b111;
203 let adc : u16 = ((h2 as u16 & 0b00111111) << 5) | (h1 >> 3) as u16;
204 let mut hit = TrackerHit::new();
205 hit.layer = daq_event.layer - 128;
206 hit.row = row ;
207 hit.module = module ;
208 hit.channel = channel;
209 hit.adc = adc ;
210 hit.asic_event_code = asic_event_code;
211 daq_event.hits.push(hit);
212 ev.n_hits += 1;
213 }
214 ev.events.push(daq_event);
215 }
216 }
217
218 fn to_bytestream(&self) -> Vec<u8> {
219 let mut stream = self.daq_header.to_bytestream();
220 stream.extend_from_slice(&self.run_id.to_le_bytes());
221 for ev in &self.events {
222 stream.push(ev.hits.len() as u8);
223 stream.push(ev.flags1);
224 stream.extend_from_slice(&ev.event_id.to_le_bytes());
225 stream.extend_from_slice(&ev.event_time32.to_le_bytes());
226 stream.extend_from_slice(&ev.event_time16.to_le_bytes());
227 for h in &ev.hits {
228 let h0 = ((h.module << 5) | (h.channel & 0b11111)) as u8;
229 let h1_adc = h.adc & 0b11111;
230 let h2_adc = h.adc >> 5;
231 let h1 = ((h1_adc << 3) as u8) | (h.row as u8 & 0b111);
232 let h2 = (h.asic_event_code << 6) as u16 | h2_adc;
233 stream.push(h0);
234 stream.push(h1);
235 stream.push(h2 as u8);
236 }
237 }
238 stream
239 }
240
241}
242
243impl TelemetryPackable for TrackerDAQEventPacket {
244 const TEL_PACKET_TYPE : TelemetryPacketType = TelemetryPacketType::Tracker;
245}
246
247impl fmt::Display for TrackerDAQEventPacket {
248 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
249 let mut repr = String::from("<TrackerDAQEventPacket:");
250 repr += &(format!("\n TrackerHeader : {}", self.daq_header));
251 repr += &(format!("\n Run ID/Run ID (old) : {} {}", self.run_id, self.run_id_old));
252 repr += &(format!("\n - N DAQ ev., N Hits : {} {}", self.events.len(), self.n_hits));
253 for daq in &self.events {
254 repr += &(format!("\n {}", daq));
255 }
256 repr += "\n";
257 write!(f, "{}", repr)
258 }
259}
260
261#[cfg(feature="random")]
262impl FromRandom for TrackerDAQEventPacket {
263
264 fn from_random() -> Self {
265 let mut packet = Self::new();
266 let mut rng = rand::rng();
267 packet.header = TelemetryPacketHeader::from_random();
268 packet.daq_header = TrackerHeader::from_random();
269 packet.events = Vec::<TrackerDAQEvent>::new();
270 packet.run_id = rng.random::<u16>();
271 let n_events : u8 = rng.random_range(0..6);
273 for _ in 0..n_events {
275 let mut ev = TrackerDAQEvent::from_random();
276 ev.layer = packet.daq_header.sys_id;
277 for h in &mut ev.hits {
278 h.oscillator = 0;
280 h.layer = ev.layer - 128;
281 }
282 packet.events.push(ev);
283 }
284 packet
285 }
286}
287
288#[test]
289#[cfg(feature="random")]
290fn serialize_deserialize_trackerdaqeventpacket() {
291 for _ in 0..100 {
292 let packet = TrackerDAQEventPacket::from_random();
293 let stream = packet.to_bytestream();
294 let test = TrackerDAQEventPacket::from_bytestream(&stream, &mut 0).unwrap();
295 assert_eq!(packet.run_id , test.run_id);
296 assert_eq!(packet.run_id_old, test.run_id_old);
297 assert_eq!(packet.events.len(), test.events.len());
298 assert_eq!(packet.daq_header, test.daq_header);
299 for k in 0..packet.events.len() {
301 assert_eq!(packet.events[k],test.events[k]);
302 }
303 }
305}
306
307#[test]
308#[cfg(feature="random")]
309fn serialize_deserialize_trackerdaqemptyeventpacket() {
310 for _ in 0..100 {
311 let pre_packet = TrackerDAQEventPacket::from_random();
312 let packet = pre_packet.emit_empty();
313 let stream = packet.to_bytestream();
314 let test = TrackerDAQEventPacket::from_bytestream(&stream, &mut 0).unwrap();
315 assert_eq!(packet.run_id , test.run_id);
316 assert_eq!(packet.run_id_old, test.run_id_old);
317 assert_eq!(packet.events.len(), test.events.len());
318 assert_eq!(packet.daq_header, test.daq_header);
319 for k in 0..packet.events.len() {
321 assert_eq!(packet.events[k],test.events[k]);
322 }
323 }
325}
326
327#[test]
328#[cfg(feature="random")]
329fn serialize_deserialize_trackerdaqmodifyeventpacket() {
330 for _ in 0..100 {
331 let pre_packet = TrackerDAQEventPacket::from_random();
332 let mut packet = pre_packet.emit_empty();
333 if pre_packet.events.len() > 0 {
334 packet.add_event(pre_packet.events[0].clone());
335 }
336 let stream = packet.to_bytestream();
337 let test = TrackerDAQEventPacket::from_bytestream(&stream, &mut 0).unwrap();
338 assert_eq!(packet.run_id , test.run_id);
339 assert_eq!(packet.run_id_old, test.run_id_old);
340 assert_eq!(packet.events.len(), test.events.len());
341 assert_eq!(packet.daq_header, test.daq_header);
342 for k in 0..packet.events.len() {
344 assert_eq!(packet.events[k],test.events[k]);
345 }
346 }
348}
349
350#[cfg(feature="pybindings")]
351#[pymethods]
352impl TrackerDAQEventPacket {
353
354 #[staticmethod]
355 #[pyo3(name="from_telemetrypacket")]
356 fn from_telemetrypacket_py(packet : TelemetryPacket) -> PyResult<Self> {
357 match Self::from_bytestream(&packet.payload, &mut 0) {
358 Ok(mut event) => {
359 event.header = packet.header.clone();
360 return Ok(event);
361 }
362 Err(err) => {
363 return Err(PyValueError::new_err(err.to_string()));
364 }
365 }
366 }
367
368
369 #[pyo3(name="to_bytestream")]
370 fn to_bytestream_py(&self) -> Vec<u8> {
371 self.to_bytestream()
372 }
373
374 #[staticmethod]
375 #[pyo3(name="from_bytestream")]
376 fn from_bytestream_py(stream : Vec<u8>,
377 pos : usize) -> PyResult<Self> {
378 let mut position = pos;
379 Ok(Self::from_bytestream(&stream, &mut position).unwrap())
380 }
381
382
383 #[pyo3(name="add_event")]
388 fn add_event_py(&mut self, ev : TrackerDAQEvent) {
389 self.add_event(ev);
390 }
391
392 #[pyo3(name="emit_empty")]
396 fn emit_empty_py(&self) -> Self {
397 self.emit_empty()
398 }
399
400 #[pyo3(name="pack")]
403 fn pack_py(&self) -> TelemetryPacket {
404 self.pack()
405 }
406
407 #[pyo3(name="remove_event")]
415 fn remove_event_py(&mut self, evid : u32) {
416 self.remove_event(evid);
417 }
418
419 #[getter]
420 fn get_gcutime(&self) -> f64 {
421 self.header.get_gcutime()
422 }
423
424 #[getter]
425 fn get_nhits(&self) -> u16 {
426 self.n_hits
427 }
428
429 #[getter]
430 #[pyo3(name="event_ids")]
431 fn get_event_ids_py(&self) -> Vec<u32> {
432 self.get_event_ids()
433 }
434
435 #[pyo3(name="get_event_for_evid")]
437 fn get_event_for_evid_py(&self, evid : u32) -> Option<TrackerDAQEvent> {
438 self.get_event_for_evid(evid)
439 }
440
441 #[getter]
442 fn get_header(&self) -> TrackerHeader {
443 self.daq_header
444 }
445
446 #[getter]
447 fn get_events(&self) -> Vec<TrackerDAQEvent> {
448 self.events.clone()
449 }
450
451 #[pyo3(name="get_hits_for_evid")]
453 fn get_hits_for_evid_py(&self, evid : u32) -> Vec<TrackerHit> {
454 self.get_hits_for_evid(evid).clone()
455 }
456
457 #[getter]
458 fn get_run_id(&self) -> u16 {
459 self.run_id
460 }
461
462 #[getter]
463 fn get_run_id_old(&self) -> u8 {
464 self.run_id_old
465 }
466}
467
468#[cfg(feature="pybindings")]
469pythonize!(TrackerDAQEventPacket);
470