DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
dpdklibs_udp_receiver.py
Go to the documentation of this file.
1#!/usr/bin/env python
2import socket
3import sys
4import binascii
5import fddetdataformats
6import time
7import click
8
9N_STREAM = 128
10FRAME_SIZE = 7200
11FRAME_TS_GAP = 2048
12FRAME_TS_GAP = 2000
13
14def print_header(wib_frame,prefix="\t"):
15 header = wib_frame.get_daqheader()
16 print(f'{prefix}Version: 0x{header.version:x}')
17 print(f'{prefix}Detector ID: 0x{header.det_id:x}')
18 print(f'{prefix}(Crate,Slot,Stream): (0x{header.crate_id:x},0x{header.slot_id:x},0x{header.stream_id:x})')
19 print(f'{prefix}Timestamp: 0x{header.timestamp:x}')
20 print(f'{prefix}Seq ID: {header.seq_id}')
21 print(f'{prefix}Block length: 0x{header.block_length:x}')
22
23def dump_data(data):
24 print(f'Size of the message received: {len(data)}')
25 data2=data
26
27
28 # if len(data)%2 ==1:
29 # data2=data[0:-1]
30 # print("\n".join(str(binascii.hexlify(data2,' ', bytes_per_sep=8)).split(' ')))
31 n_word = (len(data) // 8) +len(data) % 8
32 for i in range(n_word):
33 w = int.from_bytes(data[i*8:(i+1)*8], byteorder='little', signed=False)
34 print(f"0x{w:016x}")
35
36@click.command()
37@click.option('-d', '--dump', is_flag=True, default=False)
38@click.option('-c', '--count', type=int, default=None)
39@click.option('-p', '--port', type=int, default=0x4444)
40@click.option('-g', '--gap', type=int, default=None)
41@click.option('-f', '--frame-type', type=click.Choice(['wib', 'tde']), default='wib')
42def main(dump, count, port, gap, frame_type):
43 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
44
45 s.bind(('', port))
46
47 prev_stream = {}
48 i=0
49 dtstart = time.time()
50 dtlast = dtstart
51 sampling = 100000
52 match frame_type:
53 case 'wib':
54 frame_class = fddetdataformats.WIBEthFrame
55 port = port if not port is None else 0x4444
56 gap = gap if not gap is None else 2048
57 case 'tde':
58 frame_class = fddetdataformats.TDEEthFrame
59 port = port if not port is None else 54323
60 gap = gap if not gap is None else 2000
61
62 print('Starting receiver')
63 while (count==None or i<count):
64 # while i<10:
65 data, address = s.recvfrom(20000)
66 wf = frame_class(data)
67 header = wf.get_daqheader()
68
69
70 # hdr_id = header.stream_id
71 hdr_id = (header.det_id, header.crate_id, header.slot_id, header.stream_id)
72
73 # if hdr_id < N_STREAM:
74 stream_ts = header.timestamp
75 # print(hdr_id, header.seq_id, hex(stream_ts))
76 if dump:
77 dump_data(data[0:32])
78
79 if hdr_id not in prev_stream:
80 pass
81 else:
82 prev_strm_ts = prev_stream[hdr_id]
83 if (stream_ts - prev_strm_ts) != FRAME_TS_GAP:
84 print(f'delta_ts {stream_ts-prev_strm_ts} for {hdr_id} ')
85
86
87 # if prev_stream[hdr_id] is None:
88 # pass
89 # elif (stream_ts-prev_stream[hdr_id]) != 2048:
90 # print(f'delta_ts {stream_ts-prev_stream[hdr_id]} for det {header.det_id} strm {hdr_id} ')
91 prev_stream[hdr_id] = stream_ts
92
93
94 i+=1;
95 if i%100000 ==0:
96 dtnow = time.time()
97 avg_throughput = FRAME_SIZE*i/(1000000*(dtnow-dtstart))
98 throughput = FRAME_SIZE*sampling/(1000000*(dtnow-dtlast))
99 print(f'Received {i} packets; throughput = {throughput:.3f} MB/s [avg = {avg_throughput:.3f} MB/s]')
100 dtlast = dtnow
101 print_header(wf)
102 for k,ts in prev_stream.items():
103 if ts is None:
104 continue
105 print(f"stream {k}: last_ts {ts}")
106
107 # b = data
108 # for i in rnage(len(b)//8):
109 # w = [f"{s:02x}" for s in b[8*i:8*(i+1)]]
110 # w.reverse()
111 # print("0x"+''.join(w))
112
113if __name__ == '__main__':
114 main()
115
main(dump, count, port, gap, frame_type)
print_header(wib_frame, prefix="\t")