DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
DAPHNE_binding_test.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2
3import sys
4from fddetdataformats import DAPHNEFrame, DAPHNEFrameHeader, DAPHNEFramePeakDescriptorData
5
6
7NUM_CHANNELS = 1
8NUM_ADCS = 1024
9ADC_MAX = (1 << 14) - 1
10
11
13 frame = DAPHNEFrame()
14 if frame is None:
15 print("FAIL: DAPHNEFrame default construction returned None")
16 return 1
17
18 size = DAPHNEFrame.sizeof()
19 if size <= 0:
20 print(f"FAIL: DAPHNEFrame.sizeof() returned {size}, expected > 0")
21 return 1
22
23 print("PASS: DAPHNEFrame construction and sizeof")
24 return 0
25
26
28 if DAPHNEFrame.version != 2:
29 print(f"FAIL: DAPHNEFrame.version expected 2, got {DAPHNEFrame.version}")
30 return 1
31 if DAPHNEFrame.s_num_adcs != NUM_ADCS:
32 print(f"FAIL: DAPHNEFrame.s_num_adcs expected {NUM_ADCS}, got {DAPHNEFrame.s_num_adcs}")
33 return 1
34 if DAPHNEFrame.s_bits_per_adc != 14:
35 print(f"FAIL: DAPHNEFrame.s_bits_per_adc expected 14, got {DAPHNEFrame.s_bits_per_adc}")
36 return 1
37 if DAPHNEFrame.s_expected_bytes != DAPHNEFrame.sizeof():
38 print(f"FAIL: DAPHNEFrame.s_expected_bytes {DAPHNEFrame.s_expected_bytes} != sizeof {DAPHNEFrame.sizeof()}")
39 return 1
40 if DAPHNEFrameHeader.s_expected_bytes <= 0:
41 print(f"FAIL: DAPHNEFrameHeader.s_expected_bytes invalid: {DAPHNEFrameHeader.s_expected_bytes}")
42 return 1
43 if DAPHNEFramePeakDescriptorData.s_expected_bytes <= 0:
44 print(
45 "FAIL: DAPHNEFramePeakDescriptorData.s_expected_bytes invalid: "
46 f"{DAPHNEFramePeakDescriptorData.s_expected_bytes}"
47 )
48 return 1
49 if DAPHNEFramePeakDescriptorData.max_peaks != 5:
50 print(f"FAIL: DAPHNEFramePeakDescriptorData.max_peaks expected 5, got {DAPHNEFramePeakDescriptorData.max_peaks}")
51 return 1
52 print("PASS: DAPHNEFrame nested/static members")
53 return 0
54
55
57 frame = DAPHNEFrame()
58 frame.set_timestamp(0x112233445566)
59 frame.set_channel(9)
60 raw = frame.get_bytes()
61 if len(raw) != DAPHNEFrame.sizeof():
62 print(f"FAIL: get_bytes() length {len(raw)} != sizeof() {DAPHNEFrame.sizeof()}")
63 return 1
64 clone = DAPHNEFrame(raw)
65 if clone.get_timestamp() != 0x112233445566:
66 print(f"FAIL: bytes round-trip timestamp mismatch: got {clone.get_timestamp():#x}")
67 return 1
68 if clone.get_channel() != 9:
69 print(f"FAIL: bytes round-trip channel mismatch: got {clone.get_channel()}")
70 return 1
71 print("PASS: DAPHNEFrame bytes constructor roundtrip")
72 return 0
73
74
76 earlier = DAPHNEFrame()
77 later = DAPHNEFrame()
78 earlier.set_timestamp(100)
79 later.set_timestamp(200)
80 if not (earlier < later):
81 print("FAIL: __lt__ expected earlier < later by timestamp")
82 return 1
83 if later < earlier:
84 print("FAIL: __lt__ expected later !< earlier by timestamp")
85 return 1
86
87 same_ts_low_ch = DAPHNEFrame()
88 same_ts_high_ch = DAPHNEFrame()
89 same_ts_low_ch.set_timestamp(300)
90 same_ts_high_ch.set_timestamp(300)
91 same_ts_low_ch.set_channel(1)
92 same_ts_high_ch.set_channel(2)
93 if not (same_ts_low_ch < same_ts_high_ch):
94 print("FAIL: __lt__ expected channel tie-breaker low < high")
95 return 1
96 print("PASS: __lt__ ordering by timestamp then channel")
97 return 0
98
99
100def test_timestamp() -> int:
101 frame = DAPHNEFrame()
102 test_ts = 0xAABBCCDDEEFF
103 frame.set_timestamp(test_ts)
104 got = frame.get_timestamp()
105 if got != test_ts:
106 print(f"FAIL: set/get_timestamp: set {test_ts:#x}, got {got:#x}")
107 return 1
108 print("PASS: set_timestamp / get_timestamp")
109 return 0
110
111
112def test_channel() -> int:
113 frame = DAPHNEFrame()
114 for val in (0, 1, 31, 63):
115 frame.set_channel(val)
116 got = frame.get_channel()
117 if got != val:
118 print(f"FAIL: set_channel({val}), get_channel() returned {got}")
119 return 1
120 print("PASS: set_channel / get_channel")
121 return 0
122
123
125 frame = DAPHNEFrame()
126 hdr = frame.daq_header
127 if hdr is None:
128 print("FAIL: daq_header returned None")
129 return 1
130 hdr_alias = frame.get_daqheader()
131 if hdr_alias is None:
132 print("FAIL: get_daqheader() returned None")
133 return 1
134 print("PASS: daq_header accessible")
135 return 0
136
137
138def test_set_geoid() -> int:
139 frame = DAPHNEFrame()
140 crate_id = 8
141 slot_id = 5
142 link_id = 12
143 hdr = frame.daq_header
144 hdr.crate_id = crate_id
145 hdr.slot_id = slot_id
146 hdr.link_id = link_id
147
148 if hdr.crate_id != crate_id:
149 print(f"FAIL: crate_id mismatch, got {hdr.crate_id}")
150 return 1
151 if hdr.slot_id != slot_id:
152 print(f"FAIL: slot_id mismatch, got {hdr.slot_id}")
153 return 1
154 if hdr.link_id != link_id:
155 print(f"FAIL: link_id mismatch, got {hdr.link_id}")
156 return 1
157
158 print("PASS: DAPHNEFrame DAQHeader geoid fields can be set directly")
159 return 0
160
161
163 frame = DAPHNEFrame()
164 header = frame.header
165 header_alias = frame.get_header()
166
167 if header_alias is None:
168 print("FAIL: get_header() returned None")
169 return 1
170
171 header.channel = 17
172 if frame.get_channel() != 17:
173 print(f"FAIL: header.channel set/get mismatch, got {frame.get_channel()}")
174 return 1
175
176 header.algorithm_id = 3
177 if header.algorithm_id != 3:
178 print(f"FAIL: header.algorithm_id mismatch, got {header.algorithm_id}")
179 return 1
180
181 header.r1 = 1
182 if header.r1 != 1:
183 print(f"FAIL: header.r1 mismatch, got {header.r1}")
184 return 1
185
186 header.trigger_sample_value = 512
187 if header.trigger_sample_value != 512:
188 print(f"FAIL: header.trigger_sample_value mismatch, got {header.trigger_sample_value}")
189 return 1
190
191 header.threshold = 1200
192 if header.threshold != 1200:
193 print(f"FAIL: header.threshold mismatch, got {header.threshold}")
194 return 1
195
196 header.baseline = 900
197 if header.baseline != 900:
198 print(f"FAIL: header.baseline mismatch, got {header.baseline}")
199 return 1
200 if header_alias.baseline != 900:
201 print(f"FAIL: get_header alias mismatch, got {header_alias.baseline}")
202 return 1
203
204 print("PASS: DAPHNEFrameHeader properties")
205 return 0
206
207
208def test_adc_single() -> int:
209 frame = DAPHNEFrame()
210 frame.set_adc(0, 321)
211 if frame.get_adc(0) != 321:
212 print(f"FAIL: set_adc/get_adc mismatch at index 0, got {frame.get_adc(0)}")
213 return 1
214 print("PASS: single ADC set/get (adc index 0)")
215 return 0
216
217
219 frame = DAPHNEFrame()
220 frame.set_adc(0, ADC_MAX)
221 got = frame.get_adc(0)
222 if got != ADC_MAX:
223 print(f"FAIL: max ADC value {ADC_MAX}: got {got}")
224 return 1
225 print(f"PASS: max ADC value ({ADC_MAX}) preserved")
226 return 0
227
228
230 frame = DAPHNEFrame()
231 test_cases = [
232 (0, 100),
233 (1, 200),
234 (2, 300),
235 (NUM_ADCS - 1, 9999),
236 ]
237 for adc_idx, val in test_cases:
238 frame.set_adc(adc_idx, val)
239 for adc_idx, expected in test_cases:
240 got = frame.get_adc(adc_idx)
241 if got != expected:
242 print(f"FAIL: ADC independence: index={adc_idx}: expected {expected}, got {got}")
243 return 1
244 print("PASS: ADC cell independence across multiple indices")
245 return 0
246
247
249 frame = DAPHNEFrame()
250 for adc_idx in range(NUM_ADCS):
251 frame.set_adc(adc_idx, adc_idx * 100 % (ADC_MAX + 1))
252 for adc_idx in range(NUM_ADCS):
253 expected = adc_idx * 100 % (ADC_MAX + 1)
254 got = frame.get_adc(adc_idx)
255 if got != expected:
256 print(f"FAIL: all-adcs test: adc index {adc_idx}: expected {expected}, got {got}")
257 return 1
258 print(f"PASS: all {NUM_ADCS} ADC values read back correctly")
259 return 0
260
261
263 frame = DAPHNEFrame()
264 try:
265 frame.get_adc(NUM_ADCS)
266 print("FAIL: get_adc with out-of-range index should have raised an exception")
267 return 1
268 except Exception:
269 pass
270 print("PASS: out-of-range ADC index raises exception as expected")
271 return 0
272
273
274def test_peaks_data() -> int:
275 frame = DAPHNEFrame()
276 peaks = frame.peaks_data()
277
278 peaks.set_found(1, 0)
279 if peaks.is_found(0) != 1:
280 print(f"FAIL: peaks found(0) expected 1, got {peaks.is_found(0)}")
281 return 1
282
283 peaks.set_adc_integral(12345, 1)
284 if peaks.get_adc_integral(1) != 12345:
285 print(f"FAIL: adc_integral(1) mismatch, got {peaks.get_adc_integral(1)}")
286 return 1
287
288 peaks.set_num_subpeaks(7, 2)
289 if peaks.get_num_subpeaks(2) != 7:
290 print(f"FAIL: num_subpeaks(2) mismatch, got {peaks.get_num_subpeaks(2)}")
291 return 1
292
293 peaks.set_samples_over_baseline(200, 3)
294 if peaks.get_samples_over_baseline(3) != 200:
295 print(f"FAIL: samples_over_baseline(3) mismatch, got {peaks.get_samples_over_baseline(3)}")
296 return 1
297
298 peaks.set_adc_max(4000, 4)
299 if peaks.get_adc_max(4) != 4000:
300 print(f"FAIL: adc_max(4) mismatch, got {peaks.get_adc_max(4)}")
301 return 1
302
303 peaks.set_sample_max(123, 4)
304 if peaks.get_sample_max(4) != 123:
305 print(f"FAIL: sample_max(4) mismatch, got {peaks.get_sample_max(4)}")
306 return 1
307
308 peaks.set_sample_start(777, 0)
309 if peaks.get_sample_start(0) != 777:
310 print(f"FAIL: sample_start(0) mismatch, got {peaks.get_sample_start(0)}")
311 return 1
312
313 peaks.found_0 = 1
314 if peaks.found_0 != 1:
315 print(f"FAIL: found_0 property mismatch, got {peaks.found_0}")
316 return 1
317
318 peaks.adc_integral_0 = 54321
319 if peaks.adc_integral_0 != 54321:
320 print(f"FAIL: adc_integral_0 property mismatch, got {peaks.adc_integral_0}")
321 return 1
322
323 print("PASS: DAPHNEFramePeakDescriptorData methods and properties")
324 return 0
325
326
327def main() -> int:
328 tests = [
329 test_construction_and_size,
330 test_static_members,
331 test_bytes_roundtrip,
332 test_less_than_operator,
333 test_timestamp,
334 test_channel,
335 test_daqheader_accessible,
336 test_set_geoid,
337 test_header_properties,
338 test_adc_single,
339 test_adc_max_value,
340 test_adc_independence,
341 test_adc_all_channels_one_sample,
342 test_adc_out_of_range,
343 test_peaks_data,
344 ]
345
346 failures = 0
347 for test in tests:
348 failures += test()
349
350 print()
351 if failures == 0:
352 print("All DAPHNEFrame Python binding tests passed")
353 else:
354 print(f"{failures} DAPHNEFrame Python binding test(s) FAILED")
355 return failures
356
357
358if __name__ == "__main__":
359 sys.exit(main())