import numpy from argparse import ArgumentParser from ctypes import * FOLDER_MOD = 100000 FILE_MOD = 1000 FILE_EXTENSION = ".bin" MODULE_X_SIZE = 1024 MODULE_Y_SIZE = 512 MODULE_N_PIXELS = MODULE_X_SIZE * MODULE_Y_SIZE MODULE_N_BYTES = MODULE_N_PIXELS * 2 class BufferBinaryFormat(Structure): _pack_ = 1 _fields_ = [("FORMAT_MARKER", c_char), ("pulse_id", c_uint64), ("frame_index", c_uint64), ("daq_rec", c_uint64), ("n_recv_packets", c_uint64), ("module_id", c_uint64), ("data", c_uint16 * MODULE_N_PIXELS)] class BinaryBufferReader(object): def __init__(self, root_folder, n_modules): self.root_folder = root_folder self.n_modules = n_modules def read_pulse_id(self, pulse_id): index_in_file = get_file_frame_index(pulse_id) n_bytes_offset = index_in_file * sizeof(BufferBinaryFormat) n_bytes_to_read = sizeof(BufferBinaryFormat) metadata = {"pulse_id": 0, "frame_index": 0, "daq_rec": 0, "is_good_frame": True} data = numpy.zeros(shape=[self.n_modules*MODULE_Y_SIZE*MODULE_X_SIZE], dtype="byte") metadata_init = False for i_module in range(self.n_modules): device_name = "M%02d" % i_module filename = get_filename( root_folder=self.root_folder, device_name=device_name, pulse_id=pulse_id) print("Reading file", filename, "for module", i_module) with open(filename, 'rb') as input_file: input_file.seek(n_bytes_offset) frame_buffer = BufferBinaryFormat.from_buffer_copy( input_file.read(n_bytes_to_read)) if frame_buffer.FORMAT_MARKER == 0xBE: is_good_frame = frame_buffer.n_recv_packets == 128 if is_good_frame: if not metadata_init: metadata["pulse_id"] = frame_buffer.pulse_id metadata["frame_index"] = frame_buffer.frame_index metadata["daq_rec"] = frame_buffer.daq_rec metadata_init = True if metadata["is_good_frame"]: if metadata["pulse_id"] != frame_buffer.pulse_id: metadata["is_good_frame"] = False if metadata["frame_index"] != frame_buffer.frame_index: metadata["is_good_frame"] = False if metadata["daq_rec"] != frame_buffer.daq_rec: metadata["is_good_frame"] = False else: metadata["is_good_frame"] = False print("Module", i_module, "n_lost_packets", 128-frame_buffer.n_recv_packets) start_byte_image = MODULE_N_BYTES * i_module stop_byte_image = start_byte_image + MODULE_N_BYTES frame_data = numpy.frombuffer(frame_buffer.data, count=MODULE_N_BYTES, dtype="bytes") data[start_byte_image:stop_byte_image] = frame_data else: metadata["is_good_frame"] = False print("No data for module", i_module, "at pulse_id", pulse_id) if not metadata_init: metadata["is_good_frame"] = False return metadata, data def get_file_frame_index(pulse_id): file_base = pulse_id // FILE_MOD file_base *= FILE_MOD return pulse_id - file_base def get_filename(root_folder, device_name, pulse_id): folder_base = pulse_id // FOLDER_MOD folder_base *= FOLDER_MOD file_base = pulse_id // FILE_MOD file_base *= FILE_MOD return "%s/%s/%s/%s%s" % (root_folder, device_name, folder_base, file_base, FILE_EXTENSION) def main(): parser = ArgumentParser(description='Read DAQ Binary Buffer') parser.add_argument('root_folder', type=str, help="Absolute path to root folder of device.") parser.add_argument('n_modules', type=int, help="Number of modules to read from this device.") parser.add_argument('pulse_id', type=int, help="Pulse_id to retrieve.") arguments = parser.parse_args() reader = BinaryBufferReader(arguments.root_folder, arguments.n_modules) metadata, data = reader.read_pulse_id(arguments.pulse_id) print(metadata) if __name__ == "__main__": main()