Ejemplo n.º 1
0
def test_to_file_v2_0_timestamp_packet(tmpfile, timestamp_packet):
    to_file(tmpfile, [timestamp_packet], version='2.0')
    f = h5py.File(tmpfile, 'r')
    assert len(f['packets']) == 1
    row = f['packets'][0]
    props = dtype_property_index_lookup['2.0']['packets']
    assert row[3] == 4  # packet_type
    new_packet = TimestampPacket()
    new_packet.timestamp = row[props['timestamp']]
    assert new_packet == timestamp_packet
Ejemplo n.º 2
0
def test_message_format_test_packets(chip):
    expected_packets = chip.get_configuration_packets(Packet.CONFIG_READ_PACKET)
    expected_messages = [b'\x01\x00'+b'D'+b'\x02'+b'\x00'*4 + packet.bytes() + b'\x00' for packet in expected_packets]
    ts_packet = TimestampPacket(timestamp=123456789)
    expected_packets += [ts_packet]
    expected_messages += [b'\x01\x00'+b'T'+b'\x00'*5 + ts_packet.bytes() + b'\x00']
    print(expected_packets[-1])
    print(expected_messages[-1])
    print(dataserver_message_decode(expected_messages)[-1])
    print(expected_messages[-1])
    print(dataserver_message_encode(expected_packets)[-1])
    assert expected_messages == dataserver_message_encode(expected_packets)
    assert expected_packets == dataserver_message_decode(expected_messages)
Ejemplo n.º 3
0
def _parse_packets_v1_0(row, message_dset, *args, **kwargs):
    if row['type'] == 4:
        return TimestampPacket(row['timestamp'])
    if row['type'] == 5:
        index = row['counter']
        message_row = message_dset[index]
        message = message_row['message'].decode()
        timestamp = row['timestamp']
        return MessagePacket(message, timestamp)
    if row['type'] < 4:
        p = Packet_v1()
        p.chip_key = row['chip_key']
        p.packet_type = row['type']
        p.chipid = row['chipid']
        p.parity_bit_value = row['parity']
        if p.packet_type == Packet_v1.DATA_PACKET:
            p.channel = row['channel']
            p.timestamp = row['timestamp']
            p.dataword = row['adc_counts']
            p.fifo_half_flag = row['fifo_half']
            p.fifo_full_flag = row['fifo_full']
        elif p.packet_type == Packet_v1.TEST_PACKET:
            p.counter = row['counter']
        elif (p.packet_type == Packet_v1.CONFIG_WRITE_PACKET
              or p.packet_type == Packet_v1.CONFIG_READ_PACKET):
            p.register_address = row['register']
            p.register_data = row['value']
        p.direction = row['direction']
        return p
    return None
Ejemplo n.º 4
0
    def add_timestamps(packets, positions, timestamps=0):
        '''
        Insert timestamp packets into a list of packets in the given
        positions.

        Convenience method for modifying lists of packets to add to the
        FakeIO queue. Modifies the list in-place.

        The positions are with respect to the indexes of the original
        list, so that the inserted element is just before the element
        that originally had that index. e.g.

        >>> add_timestamps([a, b, c, d], [1, 3])
        [a, TimestampPacket(...), b, c, TimestampPacket(...), d]

        If timestamps is a list, those timestamps will be used for the
        TimestampPackets. If it is an int, it will be taken as the
        starting time, and each subsequent packet will be incremented by
        1. A default starting time of 0 is assumed.

        '''
        npositions = len(positions)
        if isinstance(timestamps, int):
            timestamps = list(range(timestamps, timestamps + npositions))
        for position, timestamp in reversed(list(zip(positions, timestamps))):
            packets.insert(position, TimestampPacket(timestamp))
Ejemplo n.º 5
0
def dataserver_message_decode(msgs,
                              key_generator=None,
                              version=(1, 0),
                              **kwargs):
    r'''
    Convert a list of larpix data server messages into packets. A key generator
    should be provided if packets are to be used with an ``larpix.io.IO``
    object. The data server messages provide a ``chip_id`` and ``io_chain`` for
    keys. Additional keyword arguments can be passed along to the key generator. E.g.::

        from larpix.larpix import Key
        def ex_key_gen(chip_id, io_chain, io_group):
            return Key(Key.key_format.format(
                chip_id=chip_id,
                io_channel=io_chain,
                io_group=io_group
            ))

        msg = b'\x01\x00D\x01\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00'
        packets = dataserver_message_decode([msg], key_generator=ex_key_gen, io_group=1)
        packets[0] # Packet(b'\x04\x00\x00\x00\x00\x00\x00'), key of '1-1-1'

    :param msgs: list of bytestream messages each starting with a single 8-byte header word, followed by N 8-byte data words

    :param key_generator: optional, a method that takes ``chip_id`` and ``io_chain`` as arguments and returns a ``larpix.Key`` object

    :param version: optional, message version to validate against, ``tuple`` of major, minor version numbers

    :returns: list of ``larpix.Packet`` and ``larpix.TimestampPacket`` objects

    '''
    packets = []
    for msg in msgs:
        major, minor = struct.unpack('BB', msg[:2])
        if (major, minor) != version:
            warnings.warn(
                'Message version mismatch! Expected {}, received {}'.format(
                    version, (major, minor)))
        msg_type = struct.unpack('c', msg[2:3])[0]
        if msg_type == b'T':
            timestamp = struct.unpack('L', msg[8:15] +
                                      b'\x00')[0]  # only use 7-bytes
            packets.append(TimestampPacket(timestamp=timestamp))
        elif msg_type == b'D':
            io_chain = struct.unpack('B', msg[3:4])[0]
            payload = msg[8:]
            if len(payload) % 8 == 0:
                for start_index in range(0, len(payload), 8):
                    packet_bytes = payload[start_index:start_index + 7]
                    packets.append(Packet(packet_bytes))
                    if key_generator:
                        packets[-1].chip_key = key_generator(
                            chip_id=packets[-1].chipid,
                            io_chain=io_chain,
                            **kwargs)
        elif msg_type == b'H':
            print('Heartbeat message: {}'.format(msg[3:]))
    return packets
Ejemplo n.º 6
0
def test_record_deprecated_3_0_0(tmpdir):
    logger = HDF5Logger(directory=str(tmpdir))
    with pytest.warns(DeprecationWarning):
        logger.open()

    logger.record([Packet()])
    assert len(logger._buffer['packets']) == 1
    logger.record([TimestampPacket(timestamp=123)])
    assert len(logger._buffer['packets']) == 2
Ejemplo n.º 7
0
def dataserver_message_decode(msgs, version=(1, 0), **kwargs):
    r'''
    Convert a list of larpix data server messages into packets. Additional packet meta data can be passed along via kwargs E.g.::

        msg = b'\x01\x00D\x01\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00'
        packets = dataserver_message_decode([msg], io_group=1)
        packets[0] # Packet(b'\x04\x00\x00\x00\x00\x00\x00'), key of '1-1-1'

    :param msgs: list of bytestream messages each starting with a single 8-byte header word, followed by N 8-byte data words

    :param version: optional, message version to validate against, ``tuple`` of major, minor version numbers

    :returns: list of ``larpix.Packet`` and ``larpix.TimestampPacket`` objects

    '''
    packets = []
    for msg in msgs:
        major, minor = struct.unpack('BB', msg[:2])
        if (major, minor) != version:
            warnings.warn(
                'Message version mismatch! Expected {}, received {}'.format(
                    version, (major, minor)))
        msg_type = struct.unpack('c', msg[2:3])[0]
        if msg_type == b'T':
            timestamp = struct.unpack('L', msg[8:15] +
                                      b'\x00')[0]  # only use 7-bytes
            packets.append(TimestampPacket(timestamp=timestamp))
            if kwargs:
                for key, value in kwargs.items():
                    setattr(packets[-1], key, value)
        elif msg_type == b'D':
            io_chain = struct.unpack('B', msg[3:4])[0]
            payload = msg[8:]
            if len(payload) % 8 == 0:
                for start_index in range(0, len(payload), 8):
                    packet_bytes = payload[start_index:start_index + 8]
                    if Packet == Packet_v1:
                        packets.append(Packet(packet_bytes[:-1]))
                    elif Packet == Packet_v2:
                        packets.append(Packet(packet_bytes))
                    packets[-1].io_channel = io_chain
                    if kwargs:
                        for key, value in kwargs.items():
                            setattr(packets[-1], key, value)
        elif msg_type == b'H':
            print('Heartbeat message: {}'.format(msg[3:]))
    return packets
Ejemplo n.º 8
0
def _parse_packets_v2_0(row, message_dset, *args, **kwargs):
    if row['packet_type'] == 4:
        return TimestampPacket(row['timestamp'])
    if row['packet_type'] == 5:
        index = row['counter']
        message_row = message_dset[index]
        message = message_row['message'].decode()
        timestamp = row['timestamp']
        return MessagePacket(message, timestamp)
    if row['packet_type'] < 4:
        p = Packet_v2()
        p.io_group = row['io_group']
        p.io_channel = row['io_channel']
        p.chip_id = row['chip_id']
        p.packet_type = row['packet_type']
        p.downstream_marker = row['downstream_marker']
        p.parity = row['parity']
        p.valid_parity = row['valid_parity']
        p.direction = row['direction']
        if p.packet_type == Packet_v2.DATA_PACKET:
            p.channel_id = row['channel_id']
            p.timestamp = row['timestamp']
            p.dataword = row['dataword']
            p.trigger_type = row['trigger_type']
            p.local_fifo = row['local_fifo']
            p.shared_fifo = row['shared_fifo']
            if row['fifo_diagnostics_enabled'] != 0:
                p.fifo_diagnostics_enabled = True
                p.local_fifo = row['local_fifo_events']
                p.shared_fifo = row['shared_fifo_events']
                p.timestamp = row['timestamp']
        elif p.packet_type in (Packet_v2.CONFIG_READ_PACKET,
                               Packet_v2.CONFIG_WRITE_PACKET):
            p.register_address = row['register_address']
            p.register_data = row['register_data']
        return p
    return None
Ejemplo n.º 9
0
def timestamp_packet():
    p = TimestampPacket(timestamp=12345)
    return p
Ejemplo n.º 10
0
def test_record(tmpdir):
    logger = HDF5Logger(directory=str(tmpdir), enabled=True)
    logger.record([Packet()])
    assert len(logger._buffer['packets']) == 1
    logger.record([TimestampPacket(timestamp=123)])
    assert len(logger._buffer['packets']) == 2
Ejemplo n.º 11
0
def from_file(filename, version=None, start=None, end=None):
    '''
    Read the data from the given file into LArPix Packet objects.

    :param filename: the name of the file to read
    :param version: the format version. Specify this parameter to
        enforce a version check. When a specific version such as
        ``'1.5'`` is specified, a ``RuntimeError`` will be raised if the
        stored format version number is not an exact match. If a version
        is prefixed with ``'~'`` such as ``'~1.5'``, a ``RuntimeError``
        will be raised if the stored format version is *incompatible*
        with the specified version. Compatible versions are those with
        the same major version and at least the same minor version. E.g.
        for ``'~1.5'``, versions between v1.5 and v2.0 are compatible.
        If unspecified or ``None``, will use the stored format version.
    :param start: the index of the first row to read
    :param end: the index after the last row to read (same semantics as
        Python ``range``)
    :returns packet_dict: a dict with keys ``'packets'`` containing a
        list of packet objects; and ``'created'``, ``'modified'``, and
        ``'version'``, containing the file metadata.

    '''
    with h5py.File(filename, 'r') as f:
        file_version = f['_header'].attrs['version']
        if version is None:
            version = file_version
        elif version[0] == '~':
            file_major, _, file_minor = file_version.split('.')
            version_major, _, version_minor = version.split('.')
            version_major = version_major[1:]
            if (file_major != version_major or file_minor < version_minor):
                raise RuntimeError('Incompatible versions: existing: %s, '
                                   'specified: %s' % (file_version, version))
            else:
                version = file_version
        elif version == file_version:
            pass
        else:
            raise RuntimeError('Incompatible versions: existing: %s, '
                               'specified: %s' % (file_version, version))
        if version not in dtypes:
            raise RuntimeError('Unknown version: %s' % version)
        if version == '0.0':
            dset_name = 'raw_packet'
        else:
            dset_name = 'packets'
            message_dset_name = 'messages'
            message_props = (
                dtype_property_index_lookup[version][message_dset_name])
            message_dset = f[message_dset_name]
        props = dtype_property_index_lookup[version][dset_name]
        packets = []
        if start is None and end is None:
            dset_iter = f[dset_name]
        else:
            dset_iter = f[dset_name][start:end]
        for row in dset_iter:
            if row[props['type']] == 4:
                packets.append(TimestampPacket(row[props['timestamp']]))
                continue
            if row[props['type']] == 5:
                index = row[props['counter']]
                message_row = message_dset[index]
                message = message_row[message_props['message']].decode()
                timestamp = row[props['timestamp']]
                packets.append(MessagePacket(message, timestamp))
                continue
            p = Packet()
            p.chip_key = row[props['chip_key']]
            p.packet_type = row[props['type']]
            p.chipid = row[props['chipid']]
            p.parity_bit_value = row[props['parity']]
            if p.packet_type == Packet.DATA_PACKET:
                p.channel = row[props['channel']]
                p.timestamp = row[props['timestamp']]
                p.dataword = row[props['adc_counts']]
                p.fifo_half_flag = row[props['fifo_half']]
                p.fifo_full_flag = row[props['fifo_full']]
            elif p.packet_type == Packet.TEST_PACKET:
                p.counter = row[props['counter']]
            elif (p.packet_type == Packet.CONFIG_WRITE_PACKET
                  or p.packet_type == Packet.CONFIG_READ_PACKET):
                p.register_address = row[props['register']]
                p.register_data = row[props['value']]
            if version != '0.0':
                p.direction = row[props['direction']]
            packets.append(p)
        return {
            'packets': packets,
            'created': f['_header'].attrs['created'],
            'modified': f['_header'].attrs['modified'],
            'version': f['_header'].attrs['version'],
        }