LArPix-Control Software Documentation¶
Here is the documentation for LArPix Control.
LArPix Control Core¶
Controllers¶
-
class
larpix.controller.
Controller
[source]¶ Controls a collection of LArPix Chip objects.
Reading data:
The specific interface for reading data is selected by specifying the
io
attribute. These objects all have similar behavior for reading in new data. On initialization, the object will discard any LArPix packets sent from ASICs. To begin saving incoming packets, callstart_listening()
. Data will then build up in some form of internal register or queue. The queue can be emptied with a call toread()
, which empties the queue and returns a list of Packet objects that were in the queue. Theio
object will still be listening for new packets during and after this process. If the queue/register fills up, data may be discarded/lost. To stop saving incoming packets and retrieve any packets still in the queue, callstop_listening()
. While the Controller is listening, packets can be sent using the appropriate methods without interrupting the incoming data stream.With the the LArPix v2 asic, a network io structure is used. To keep track of this network and to insure the proper bring-up procedure is followed. The controller has a
network
attribute. This is an ordered dict with multiple layers corresponding to the chip key layers. It assumes that each hydra network is distinct on a given io channel. On a given io channel, the hydra network is represented as three directed graphsmiso_us
,miso_ds
, andmosi
.:controller.network[1] # Represents all networks on io group 1 controller.network[1][1] # Represents the network on io group 1, io channel 1 controller.network[1][1]['mosi'] # directed graph representing mosi links
Nodes within the network are added automatically whenever you add a chip to the controller:
list(controller.network[1][1]['mosi'].nodes()) # chip ids of known mosi nodes list(controller.network[1][1]['miso_us'].nodes()) # chip ids of known miso_us nodes list(controller.network[1][1]['miso_ds'].nodes()) # chip ids of known miso_ds nodes controller.network[1][1]['miso_us'].nodes[5] # attributes associated with node 5 controller.add_chip('1-1-6', version=2, root=True) list(controller.network[1][1]['miso_us'].nodes()) # [5, 6]
The ‘root’ node is used to indicate which chips should be brought up first when initializing the network.
Accessing connections between nodes is done via edges:
list(controller.network[1][1]['miso_us'].edges()) # [] controller.add_network_link(1,1,'miso_us',(6,5),0) # link chips 6 -> 5 in the miso_us graph via chip 6's uart channel 0 list(controller.network[1][1]['miso_us'].edges()) # [(6,5)] direction indicates the data flow direction controller.network[1][1]['miso_us'].edges[(6,5)] # attributes associated with link ('uart': 0)
In order to set up a ‘working’ network, you’ll need to add the proper links in the miso_ds and mosi graphs as well.:
controller.add_network_link(1,1,'miso_ds',(5,6),2) controller.add_network_link(1,1,'mosi',(6,5),0) controller.add_network_link(1,1,'mosi',(5,6),2)
External systems (e.g. the fpga you are using to communicate with the chips) are conventionally called
'ext0', 'ext1', ...
and shouldn’t be forgotten in the network configuration! These nodes are used to determine the miso/mosi configuration for the linked chips.:controller.add_network_link(1,1,'mosi',('ext',6),1) # link chip 6 to 'ext' via chip 6's uart channel 0 controller.add_network_link(1,1,'miso_ds',(6,'ext'),1) # same for miso_ds list(controller.network[1][1]['miso_ds'].edges()) list(controller.network[1][1]['mosi'].edges())
To then initialize a component on the network, run controller.init_network(1,1,6). This will modify the correct registers of chip 1-1-6 and send the configuration commands to the system.:
controller.init_network(1,1,6) controller.init_network(1,1,5)
Keep in mind, the order in which you initialize the network is important (e.g. chip 6 needs to be initialized before chip 5 since it is upstream from chip 6).
You may also reset a particular node with reset_network(<io_group>,<io_channel>,<chip_id>) which resets the network configuration of a particular node.:
controller.reset_network(1,1,5) controller.reset_network(1,1,6)
This is all rather tedious to do manually, so there a few shortcuts to make declaring and configuring the network easier. If you don’t want to initialize or reset each node in order, you may allow the controller to figure out the proper order (based on the root nodes) and configure all of the chips.:
controller.init_network(1,1) # configure the 1-1 network controller.reset_network(1,1) # revert the 1-1 network to it's original state
In the event that you need to access the chip keys of a network in the order of their depth within the network, use:
controller.get_network_keys(1,1) # get a list of chip keys starting with the root node and descending into the network controller.get_network_keys(1,1,root_first_traversal=False) # get a list of chip keys starting with the chips deepest in the network and ascending
You may also specify a network configuration file and use this to create all of the necessary network links and chips. See <https://larpix-control.readthedocs.io/en/stable/api/configs/controller.html> for how to create one of these files. This is the generally recommended means of creating and loading a Hydra io network.:
# as an example for bringing up a hydra network from a config file controller.load('<network config file>.json') # load your network and chips for io_group, io_channels in controller.network.items(): for io_channel in io_channels: controller.init_network(io_group, io_channel) # update configurations and write to chips
Properties and attributes:
chips
: theChip
objects that the controller controlsreads
: list of all the PacketCollections that have been sent back to this controller. PacketCollections are created byrun
,write_configuration
,read_configuration
,multi_write_configuration
,multi_read_configuration
, andstore_packets
.network
: a collection of networkx directed graph objects representing the miso_us, miso_ds, and mosi connections between chips (not applicable for v1 asics)
-
add_chip
(chip_key, version=2, config=None, root=False)[source]¶ Add a specified chip to the Controller chips.
Parameters: - chip_key – chip key to specify unique chip
- version – asic version of chip
- config – configuration to assign chip when creating (otherwise uses default)
- root – specifies if this is a root node as used by the hydra io network
Returns: Chip
that was added
-
add_network_link
(io_group, io_channel, network_name, chip_ids, uart)[source]¶ Adds a link within the specified network (
mosi
,miso_ds
, ormiso_us
) on the specified uart. Directionality is important: first key represents the tail (where packets are coming from) and the second is the head (where packets are going). The uart channel refers to the tail’s uart channel (for'miso_*'
) and to the head’s uart channel for ('mosi'
). Links can be formed with non-key objects to allow for network communications with objects that are not larpix chips (e.g. an external fpga).For example to specify a miso downstream link between chips
'1-1-3'
and'1-1-2'
on chip'1-1-3'
’s uart 0, the arguments should be:controller.add_network_link('miso_ds', 1, 1, (3,2), 0)
This represents a link where chip
'1-1-3'
will transfer packets out of its uart 0 to a destination of chip'1-1-2'
(unspecified uart).No network validation is performed, so use with caution!
Parameters: - network_name –
str
from('miso_us','miso_ds','mosi')
- io_group – io group to add network link in
- io_channel – io channel to add network link in
- chip_ids –
tuple
of two chip ids to link (order is important – first is ‘tail’ second is ‘head’, data flows from the ‘tail’ to the ‘head’ in all networks) - uart –
int
referring to which uart channel this link occurs over, for'miso_*'
networks the uart channel refers to the uart on the sender (i.e. the ‘tail’ of the edge in the directed graph), but for'mosi'
networks the uart channel refers to the uart on the receiver (i.e. the ‘head’ of the edge in the directed graph)
- network_name –
-
add_network_node
(io_group, io_channel, network_names, chip_id, root=False)[source]¶ Adds a node to the specified network (
mosi
,miso_ds
, ormiso_us
) with no links. Generally, this is not needed as network nodes are added automatically with thecontroller.add_chip()
method. ‘Special’ (i.e. non-key) nodes can be specified to insert nodes that do not represent larpix chips (e.g. an external fpga). A node can be declared as a root node, which is used as a flag to select the starting node during initialization.Parameters: - network_names – list of networks or name of single network to create a node in
- io_group – io group to create node within
- io_channel – io channel to create node within
- chip_id – chip id to associate with node (note that all chip ids must be unique on a network)
- root – specifies if this node should be a root node (default=False)
-
get_network_ids
(io_group, io_channel, root_first_traversal=True)[source]¶ Returns a list of chip ids in order of depth within the miso_us network
Parameters: - io_group – io group of network
- io_channel – io channel of network
- root_first_traversal –
True
to traverse network starting from root nodes then increasing in network depth,False
to traverse network starting from nodes furthest from root nodes and then decreasing in network depth
-
get_network_keys
(io_group, io_channel, root_first_traversal=True)[source]¶ Returns a list of chip ids in order of depth within the miso_us network
Parameters: - io_group – io group of network
- io_channel – io channel of network
- root_first_traversal –
True
to traverse network starting from root nodes then increasing in network depth,False
to traverse network starting from nodes furthest from root nodes and then decreasing in network depth
-
remove_chip
(chip_key)[source]¶ Remove a specified chip from the Controller chips.
Parameters: chip_key – chip key to specify unique chip
-
load
(filename)[source]¶ Loads the specified file that describes the chip ids and IO network
Parameters: filename – File path to configuration file
-
load_network
(filename, version=2)[source]¶ Loads the specified file using the hydra io network configuration format with either a miso_us_uart_map/miso_ds_uart_map/mosi_uart_map specification or a miso_uart_map/mosi_uart_map/usds_uart_map specification.
After loading the network, running
controller.init_network(<io group>, <io channel>)
will configure the chips with specified chip ids in the order declared in fileParameters: filename – File path to configuration file
-
load_controller
(filename)[source]¶ Loads the specified file using the basic key, chip format
The chip key is the Controller access key that gets communicated to/from the io object when sending and receiving packets.
Parameters: filename – File path to configuration file
-
grow_network
(io_group, io_channel, chip_id, miso_uart_map=[3, 0, 1, 2], mosi_uart_map=[0, 1, 2, 3], usds_link_map=[2, 3, 0, 1], chip_id_generator=<function Controller._default_chip_id_generator>, timeout=0.01, modify_mosi=False, differential=True, version=2)[source]¶ Recurisve algorithm to auto-complete a network from a stub. It works by attempting to link to each available upstream node in succession, keeping links that are verified. Repeats on each newly generated node until no possible links remain.
To use with a completely unconfigured network you must first configure the root node representing the control system:
controller.add_network_node(io_group, io_channel, controller.network_names, 'ext', root=True)
You can then grow the network from this stub:
controller.grow_network(io_group, io_channel, 'ext')
This algorithim is limited to a regular geometry defined by the same miso_uart_map/mosi_uart_map/usds_link_map for each chip.
Parameters: - io_group – the io group designation for the network
- io_channel – the io channel designation for the network
- chip_id – the chip id of the chip to start growth from
- miso_uart_map – a length 4 iterable indicating the miso channel used to send data to a chip at position i relative to the active chip
- mosi_uart_map – a length 4 iterable indicating the mosi channel used to receive data from a chip at position i relative to the active chip
- usds_link_map – a length 4 iterable indicating the relative position of the active chip from the perspective of the chip at position i
- chip_id_generator – a function that takes a controller, io_group, and io_channel and returns a unique chip id for that network
- timeout – the time duration in seconds to wait for a response from each configured node
- modify_mosi – flag to configure each chip’s mosi, if set to
True
algorithm will also write the mosi configuration when probing chips, this will almost certainly leave you with deaf nodes and is not what you want. Leave at defaultFalse
- differential –
True
to also enable differential signalling
Returns: the generated ‘miso_us’, ‘miso_ds’, and ‘mosi’ networks as a dict
-
init_network_and_verify
(io_group=1, io_channel=1, chip_id=None, timeout=0.2, retries=10, modify_mosi=True, differential=True)[source]¶ Runs init network, verifying that registers are updated properly at each step Will exit if any chip network configuration cannot be set correctly after
retries
attempts
-
init_network
(io_group=1, io_channel=1, chip_id=None, modify_mosi=True, differential=True, tx_slices=15, i_tx_diff=0)[source]¶ Configure a Hydra io node specified by chip_id, if none are specified, load complete network To configure a Hydra io network, the following steps are followed:
- Enable miso_us of parent chip
- Enable mosi of parent chip
- Write chip_id to chip on io group + io channel (assuming chip id 1)
- Write enable_piso_downstream to chip chip_id (also enable differential if desired)
- Write enable_posi to chip chip_id (optional)
-
reset_network
(io_group=1, io_channel=1, chip_id=None)[source]¶ Resets the hydra IO network To reset a Hydra io network node, the following steps are followed:
- Write enable_posi [1,1,1,1] to chip
- Write enable_piso_downstream [0,0,0,0] to chip
- Write chip_id 1 to chip
- Disable miso_us channel of parent chip
If no chip_id is specified, network is reset in reverse order (starting from chips with no outgoing miso_us connections, working up the miso_us tree)
-
read
()[source]¶ Read any packets that have arrived and return (packets, bytestream) where bytestream is the bytes that were received.
The returned list will contain packets that arrived since the last call to
read
orstart_listening
, whichever was most recent.
-
write_configuration
(chip_key, registers=None, write_read=0, message=None, connection_delay=0.2)[source]¶ Send the configurations stored in chip.config to the LArPix ASIC.
By default, sends all registers. If registers is an int, then only that register is sent. If registers is a string, then the sent registers will set by looking at the configuration register map. If registers is an iterable, then all of the registers in the iterable are sent.
If write_read == 0 (default), the configurations will be sent and the current listening state will not be affected. If the controller is currently listening, then the listening state will not change and the value of write_read will be ignored. If write_read > 0 and the controller is not currently listening, then the controller will listen for
write_read
seconds beginning immediately before the packets are sent out, read the io queue, and save the packets into thereads
data member. Note that the controller will only read the queue once, so if a lot of data is expected, you should handle the reads manually and set write_read to 0 (default).
-
read_configuration
(chip_key, registers=None, timeout=1, message=None, connection_delay=0.2)[source]¶ Send “configuration read” requests to the LArPix ASIC.
By default, request all registers. If registers is an int, then only that register is reqeusted. If registers is an iterable, then all of the registers in the iterable are requested.
If the controller is currently listening, then the requests will be sent and no change to the listening state will occur. (The value of
timeout
will be ignored.) If the controller is not currently listening, then the controller will listen fortimeout
seconds beginning immediately before the first packet is sent out, and will save any received packets in thereads
data member.
-
multi_write_configuration
(chip_reg_pairs, write_read=0, message=None, connection_delay=0.2)[source]¶ Send multiple write configuration commands at once.
chip_reg_pairs
should be a list/iterable whose elements are an valid arguments toController.write_configuration
, excluding thewrite_read
argument. Just like in the singleController.write_configuration
, settingwrite_read > 0
will have the controller read data during and after it writes, for however many seconds are specified.Examples:
These first 2 are equivalent and write the full configurations
>>> controller.multi_write_configuration([chip_key1, chip_key2, ...]) >>> controller.multi_write_configuration([(chip_key1, None), chip_key2, ...])
These 2 write the specified registers for the specified chips in the specified order
>>> controller.multi_write_configuration([(chip_key1, 1), (chip_key2, 2), ...]) >>> controller.multi_write_configuration([(chip_key1, range(10)), chip_key2, ...])
-
differential_write_configuration
(chip_config_pairs, write_read=0, message=None, connection_delay=0.2)[source]¶ Send different configuration registers between configs passed in
chip_config_pairs
and existing configs. Performs a singlemulti_write_configuration
.Parameters: chip_config_pairs – list of (chip_key, config_object)
pairs to perform differential write againstReturns: list of (chip_key, list_of_registers)
pairs
-
multi_read_configuration
(chip_reg_pairs, timeout=1, message=None, connection_delay=0.2)[source]¶ Send multiple read configuration commands at once.
chip_reg_pairs
should be a list/iterable whose elements are chip keys (to read entire configuration) or (chip_key, registers) tuples to read only the specified register(s). Registers could beNone
(i.e. all), anint
for that register only, or an iterable of ints.Examples:
These first 2 are equivalent and read the full configurations
>>> controller.multi_read_configuration([chip_key1, chip_key2, ...]) >>> controller.multi_read_configuration([(chip_key1, None), chip_key2, ...])
These 2 read the specified registers for the specified chips in the specified order
>>> controller.multi_read_configuration([(chip_key1, 1), (chip_key2, 2), ...]) >>> controller.multi_read_configuration([(chip_key1, range(10)), chip_key2, ...])
-
run
(timelimit, message)[source]¶ Read data from the LArPix ASICs for the given
timelimit
and associate the received Packets with the givenmessage
.
-
verify_registers
(chip_key_register_pairs, timeout=1, connection_delay=0.02, n=1)[source]¶ Read chip configuration from specified chip and registers and return
True
if the read chip configuration matches the current configuration stored in chip instance.Parameters: - chip_key_register_pair – a
list
of key register pairs as documented incontroller.multi_read_configuration
- timeout – set how long to wait for response in seconds (optional)
- n – sets maximum recursion depth, will continue to attempt to verify registers until this depth is reached or all registers have responded, a value <1 allows for infinite recursion (optional)
Returns: 2-
tuple
of abool
representing if all registers match and adict
representing all differences. Differences are specified as{<chip_key>: {<register>: (<expected>, <read>)}}
- chip_key_register_pair – a
-
verify_configuration
(chip_keys=None, timeout=1, connection_delay=0.02, n=1)[source]¶ Read chip configuration from specified chip(s) and return
True
if the read chip configuration matches the current configuration stored in chip instance.chip_keys
can be a single chip key, a list of chip keys, orNone
. Ifchip_keys
isNone
all chips will be verified.Also returns a dict containing the values of registers that are different (read register, stored register)
Parameters: - chip_keys –
list
of chip_keys to verify - timeout – how long to wait for response in seconds
- n – set recursion limit for rechecking non-responding registers
Returns: 2-
tuple
with same format ascontroller.verify_registers
- chip_keys –
-
verify_network
(chip_keys=None, timeout=1)[source]¶ Read chip network configuration from specified chip(s) and return
True
if the read chip configurations matches Only valid for v2 chips.Parameters: - chip_keys –
list
of chip_keys to verify or singe chip_key to verify - timeout – how long to wait for response in seconds
Returns: 2-
tuple
with same format ascontroller.verify_registers
- chip_keys –
-
enforce_registers
(chip_key_register_pairs, timeout=1, connection_delay=0.02, n=1, n_verify=1)[source]¶ Read chip configuration from specified chip and registers and write registers to read chip configurations that do not match the current configuration stored in chip instance.
Parameters: - chip_key_register_pair – a
list
of key register pairs as documented incontroller.multi_read_configuration
- timeout – set how long to wait for response in seconds (optional)
- n – sets maximum recursion depth, will continue to attempt to enforce registers until this depth is reached or all registers have responded, a value <1 allows for infinite recursion (optional)
- n_verify – maximum recursion depth for verify registers (optional)
Returns: 2-
tuple
with same format ascontroller.verify_registers
- chip_key_register_pair – a
-
enforce_configuration
(chip_keys=None, timeout=1, connection_delay=0.02, n=1, n_verify=1)[source]¶ Read chip configuration from specified chip(s) and write registers to read chip configuration that do not match the current configuration stored in chip instance.
chip_keys
can be a single chip key, a list of chip keys, orNone
. Ifchip_keys
isNone
all chip configs will be enforced.Also returns a dict containing the values of registers that are different (read register, stored register)
Parameters: - chip_keys –
list
of chip_keys to verify - timeout – how long to wait for response in seconds
- n – set recursion limit for enforcing non-matching registers (optional)
- n_verify – set recursion limit for verifying registers (optional)
Returns: 2-
tuple
with same format ascontroller.verify_registers
- chip_keys –
-
enable_analog_monitor
(chip_key, channel)[source]¶ Enable the analog monitor on a single channel on the specified chip. Note: If monitoring a different chip, call disable_analog_monitor first to ensure that the monitor to that chip is disconnected.
-
disable_analog_monitor
(chip_key=None, channel=None)[source]¶ Disable the analog monitor for a specified chip and channel, if none are specified disable the analog monitor for all chips in self.chips and all channels
-
enable_testpulse
(chip_key, channel_list, start_dac=255)[source]¶ Prepare chip for pulsing - enable testpulser and set a starting dac value for specified chip/channel
-
issue_testpulse
(chip_key, pulse_dac, min_dac=0, read_time=0.1)[source]¶ Reduce the testpulser dac by
pulse_dac
and write_read to chip forread_time
seconds
-
disable_testpulse
(chip_key=None, channel_list=None)[source]¶ Disable testpulser for specified chip/channels. If none specified, disable for all chips/channels
-
disable
(chip_key=None, channel_list=None)[source]¶ Update channel mask to disable specified chips/channels. If none specified, disable all chips/channels
Chips¶
-
class
larpix.chip.
Chip
(chip_key, version=2)[source]¶ Represents one LArPix chip and helps with configuration and packet generation.
-
is_chip_id_set
()[source]¶ Check if chip id (as specified by unique key) matches the chip id stored in the configuration. Only valid for v2 asics, if v1 asic, will always return
True
Note: Even if this function returns True, it’s possible the chip ID has not been sent from the larpix-control software onto the ASIC hardware
-
get_configuration_packets
(packet_type, registers=None)[source]¶ Return a list of Packet objects to read or write (depending on
packet_type
) the specified configuration registers (or all registers by default).
-
get_configuration_write_packets
(registers=None)[source]¶ Return a list of Packet objects to write corresponding to the specified configuration registers (all by default)
-
get_configuration_read_packets
(registers=None)[source]¶ Return a list of Packet objects to write corresponding to the specified configuration registers (all by default)
-
Chip keys¶
-
class
larpix.key.
Key
(*args)[source]¶ A unique specification for routing data to a particular detector sub-system. At the core, a key is represented by 3-unsigned 1-byte integer fields which refer to an id code within a layer of the LArPix DAQ system heirarchy. Field 0 represents the io group id number, field 1 represents the io channel connecting to a MISO/MOSI pair, and field 2 represents the chip id. The io group is the device controlling a set of MOSI/MISO pairs, the io channel is a single MOSI/MISO pair controlling a collection of LArPix asics, and the chip id uniquely identifies a chip on a single MISO/MISO network.
Each field should be a 1-byte unsigned integer (0-255) providing a unique lookup value for each component in the system. The id values of 0 and 255 are reserved for special functionality.
A key can be specified by a string of
'<io group>-<io channel>-<chip id>'
, by io group, io channel, and chip id, or by using other Keys.Keys are hashed by their string representation and are equivalent to their string representation so:
key = Key(1,1,1) # io group, io channel, chip id key == Key('1-1-1') # True key == Key(key) # True key == '1-1-1' # True key == (1,1,1) # True d = { key: 'example' } d[key] == 'example' # True d['1-1-1'] == 'example' # True
Keys are “psuedo-immutable”, i.e. you cannot change a Key’s io_group, io_channel, or chip_id after it has been created.
-
keystring
¶ Key string specifying key io group, io channel, and chip id in the format:
'<io group>-<io channel>-<chip id>'
-
chip_id
¶ 1-byte unsigned integer representing the physical chip id (hardwired for v1 ASICs, assigned dynamically for v2 ASICs)
-
io_channel
¶ 1-byte unsigned integer representing the physical io channel. This identifies a single MOSI/MISO pair used to communicate with a single network of up to 254 chips.
-
io_group
¶ 1-byte unsigned integer representing the physical device used to read out up to 254 io channels.
-
static
is_valid_keystring
(keystring)[source]¶ Check if keystring can be interpreted as a larpix.Key
Returns: True
if the keystring can be interpreted as a larpix.Key
-
Packets¶
-
class
larpix.packet.packet_v1.
Packet_v1
(bytestream=None)[source]¶ A single 54-bit LArPix UART data packet.
LArPix Packet objects have attributes for inspecting and modifying the contents of the packet.
Internally, packets are represented as an array of bits, and the different attributes use Python “properties” to seamlessly convert between the bits representation and a more intuitive integer representation. The bits representation can be inspected with the
bits
attribute.Packet objects do not restrict you from adjusting an attribute for an inappropriate packet type. For example, you can create a data packet and then set
packet.register_address = 5
. This will adjust the packet bits corresponding to a configuration packet’s “register_address” region, which is probably not what you want for your data packet.Packets have a parity bit which enforces odd parity, i.e. the sum of all the individual bits in a packet must be an odd number. The parity bit can be accessed as above using the
parity_bit_value
attribute. The correct parity bit can be computed usingcompute_parity()
, and the validity of a packet’s parity can be checked usinghas_valid_parity()
. When constructing a new packet, the correct parity bit can be assigned usingassign_parity()
.Individual packets can be printed to show a human-readable interpretation of the packet contents. The printed version adjusts its output based on the packet type, so a data packet will show the data word, timestamp, etc., while a configuration packet will show the register address and register data.
-
bytes
()[source]¶ Construct the bytes that make up the packet.
Byte 0 is the first byte that would be sent out and contains the first 8 bits of the packet (i.e. packet type and part of the chip ID).
Note: The internal bits representation of the packet has a different endian-ness compared to the output of this method.
-
-
class
larpix.packet.packet_v2.
Packet_v2
(bytestream=None)[source]¶ Representation of a 64 bit LArPix v2 (or LightPix v1) UART data packet.
Packet_v2 objects are internally represented as bitarrays, but a variety of helper properties allow one to access and set the data stored in the bitarrays in a natural fashion. E.g.:
p = Packet_v2() # initialize a packet of zeros p.packet_type # fetch packet type bits and convert to uint p.packet_type = 2 # set the packet type to a config write packet print(p.bits) # the bits have been updated!
Packet_v2 objects don’t enforce any value validation, so set these fields with caution!
In FIFO diagnostics mode, the bits are to be interpreted in a different way. At this point, there is no way for the
Packet_v2
to automatically know if it is in FIFO diagnostics mode. If you are operating the chips in this mode you can manually setPacket_v2.fifo_diagnostics_enabled = True
to interpret data packets in this fashion by default, or setpacket.fifo_diagnostics_enabled = True
for a single packet. Just remember that if you modifypacket.fifo_diagnostics_enabled
, it will no longer use the default.
-
class
larpix.packet.timestamp_packet.
TimestampPacket
(timestamp=None, code=None)[source]¶ A packet-like object which just contains an integer timestamp.
This class implements many methods used by Packet, so it functions smoothly in lists of packets and in PacketCollection.
If neither
timestamp
norcode
is provided then this TimestampPacket will have a timestamp ofNone
until it is manually set.Parameters: - timestamp – optional, integer timestamp of this packet
- code – optional, encoded timestamp as a 7-byte unsigned int
obtainable from calling the
bytes
method.
-
class
larpix.packet.message_packet.
MessagePacket
(message, timestamp)[source]¶ A packet-like object which contains a string message and timestamp.
Parameters: - message – a string message of length less than 64
- timestamp – the timestamp of the message
-
class
larpix.packet.packet_collection.
PacketCollection
(packets, bytestream=None, message='', read_id=None, skipped=None)[source]¶ Represents a group of packets that were sent to or received from LArPix.
Index into the PacketCollection as if it were a list:
>>> collection[0] Packet(b'') >>> first_ten = collection[:10] >>> len(first_ten) 10 >>> type(first_ten) larpix.larpix.PacketCollection >>> first_ten.message 'my packets | subset slice(None, 10, None)'
To view the bits representation, add ‘bits’ to the index:
>>> collection[0, 'bits'] '00000000 00000000 00000000 00000000 00000000 00000000 000111' >>> bits_format_first_10 = collection[:10, 'bits'] >>> type(bits_format_first_10[0]) str
-
extract
(*attrs, **selection)[source]¶ Extract the given attribute(s) from packets specified by selection and return a list.
Any attribute of a Packet is a valid attribute or selection
Usage:
>>> # Return a list of adc counts from any data packets >>> dataword = collection.extract('dataword', packet_type=0) >>> # Return a list of timestamps from chip 2 data >>> timestamps = collection.extract('timestamp', chip_id=2, packet_type=Packet_v2.DATA_PACKET) >>> # Return the most recently read global threshold from chip 5 >>> threshold = collection.extract('register_value', register_address=32, packet_type=3, chip_id=5)[-1] >>> # Return multiple attributes >>> chip_keys, channel_ids = zip(*collection.extract('chip_key','channel_id'))
Note
selecting on
timestamp
will also select TimestampPacket values.
-
LArPix ASIC Configuration Registers¶
Below are links to the auto-generated python representations of the LArPix ASIC registers.
LArPix v1 ASIC Configuration Registers¶
-
Configuration.
register_names
= ['pixel_trim_dac', 'threshold_global', 'csa_gain', 'csa_bypass_enable', 'bypass_caps_en', 'csa_enable', 'ibias_tdac', 'ibias_comp', 'ibias_buffer', 'ibias_csa', 'ibias_vref_buffer', 'ibias_vcm_buffer', 'ibias_tpulse', 'ref_current_trim', 'override_ref', 'ref_kickstart', 'vref_dac', 'vcm_dac', 'csa_bypass_select', 'csa_monitor_select', 'csa_testpulse_enable', 'csa_testpulse_dac', 'current_monitor_bank0', 'current_monitor_bank1', 'current_monitor_bank2', 'current_monitor_bank3', 'voltage_monitor_bank0', 'voltage_monitor_bank1', 'voltage_monitor_bank2', 'voltage_monitor_bank3', 'voltage_monitor_refgen', 'digital_monitor_enable', 'digital_monitor_select', 'digital_monitor_chan', 'slope_control0', 'slope_control1', 'slope_control2', 'slope_control3', 'chip_id', 'load_config_defaults', 'enable_fifo_diagnostics', 'clk_ctrl', 'enable_miso_upstream', 'enable_miso_downstream', 'enable_miso_differential', 'enable_mosi', 'test_mode_uart0', 'test_mode_uart1', 'test_mode_uart2', 'test_mode_uart3', 'enable_cross_trigger', 'enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto', 'adc_hold_delay', 'adc_burst_length', 'channel_mask', 'external_trigger_mask', 'cross_trigger_mask', 'periodic_trigger_mask', 'periodic_reset_cycles', 'periodic_trigger_cycles', 'enable_dynamic_reset', 'enable_min_delta_adc', 'threshold_polarity', 'reset_length', 'mark_first_packet', 'reset_threshold', 'min_delta_adc', 'digital_threshold']¶
-
class
larpix.configuration.configuration_v1.
Configuration_v1
[source]¶ Represents the desired configuration state of a LArPix v1 chip.
-
register_names
= ['pixel_trim_thresholds', 'global_threshold', 'csa_gain', 'csa_bypass', 'internal_bypass', 'csa_bypass_select', 'csa_monitor_select', 'csa_testpulse_enable', 'csa_testpulse_dac_amplitude', 'test_mode', 'cross_trigger_mode', 'periodic_reset', 'fifo_diagnostic', 'sample_cycles', 'test_burst_length', 'adc_burst_length', 'channel_mask', 'external_trigger_mask', 'reset_cycles']¶ This attribute lists the names of all available configuration registers. Each register name is available as its own attribute for inspecting and setting the value of the corresponding register.
Certain configuration values are set channel-by-channel. These are represented by a list of values. For example:
>>> conf.pixel_trim_thresholds[2:5] [16, 16, 16] >>> conf.channel_mask[20] = 1 >>> conf.external_trigger_mask = [0] * 32
Additionally, other configuration values take up more than or less than one complete register. These are still set by referencing the appropriate name. For example,
cross_trigger_mode
shares a register with a few other values, and adjusting the value of thecross_trigger_mode
attribute will leave the other values unchanged.
-
enable_channels
(list_of_channels=None)[source]¶ Shortcut for changing the channel mask for the given channels to “enable” (i.e. 0).
-
disable_channels
(list_of_channels=None)[source]¶ Shortcut for changing the channel mask for the given channels to “disable” (i.e. 1).
-
enable_external_trigger
(list_of_channels=None)[source]¶ Shortcut for enabling the external trigger functionality for the given channels. (I.e. disabling the mask.)
-
disable_external_trigger
(list_of_channels=None)[source]¶ Shortcut for disabling the external trigger functionality for the given channels. (I.e. enabling the mask.)
-
enable_testpulse
(list_of_channels=None)[source]¶ Shortcut for enabling the test pulser for the given channels.
-
disable_testpulse
(list_of_channels=None)[source]¶ Shortcut for disabling the test pulser for the given channels.
-
LArPix v2 ASIC Configuration Registers¶
-
class
larpix.configuration.configuration_v2.
Configuration_v2
[source]¶ Represents the desired configuration state of a LArPix v2 chip.
Each register name is available as its own attribute for inspecting and setting the value of the corresponding register.
Certain configuration values are set channel-by-channel. These are represented by a list of values. For example:
>>> conf.pixel_trim_dac[2:5] [16, 16, 16] >>> conf.channel_mask[20] = 1 >>> conf.external_trigger_mask = [0] * 64
Additionally, other configuration values take up more than or less than one complete register. These are still set by referencing the appropriate name. For example,
cross_trigger_mode
shares a register with a few other values, and adjusting the value of thecross_trigger_mode
attribute will leave the other values unchanged.Each register name can cover more than one ‘physical’ register depending on the size of the data it holds. You can see which physical registers a given register name corresponds to by using the register_map attribute, e.g.:
>>> conf.register_map['digital_threshold'] # 64 registers, 1 per channel range(173, 237) >>> conf.register_map['enable_dynamic_reset'] # Register 170 range(170, 171) >>> conf.register_map['enable_min_delta_adc'] # Shares register 170 range(170, 171)
-
adc_burst_length
¶ simple value property
registers:
range(130, 131)
valid types:
<class 'int'>
value range:
0
to255
-
adc_hold_delay
¶ simple value property
registers:
range(129, 130)
valid types:
<class 'int'>
value range:
0
to15
-
bypass_caps_en
¶ compound property
registers:
range(65, 66)
bits:
[2]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['csa_gain', 'csa_bypass_enable']
-
channel_mask
¶ list-like property
list length:
64
registers:
range(131, 139)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
chip_id
¶ simple value property
registers:
range(122, 123)
valid types:
<class 'int'>
value range:
0
to255
-
clk_ctrl
¶ compound property
registers:
range(123, 124)
bits:
[3, 4]
valid types:
<class 'int'>
value range:
0
to2
shares a register with:
['load_config_defaults', 'enable_fifo_diagnostics']
-
cross_trigger_mask
¶ list-like property
list length:
64
registers:
range(147, 155)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
csa_bypass_enable
¶ compound property
registers:
range(65, 66)
bits:
[1]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['csa_gain', 'bypass_caps_en']
-
csa_bypass_select
¶ list-like property
list length:
64
registers:
range(84, 92)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
csa_enable
¶ list-like property
list length:
64
registers:
range(66, 74)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
csa_gain
¶ compound property
registers:
range(65, 66)
bits:
[0]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['csa_bypass_enable', 'bypass_caps_en']
-
csa_monitor_select
¶ list-like property
list length:
64
registers:
range(92, 100)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
csa_testpulse_dac
¶ simple value property
registers:
range(108, 109)
valid types:
<class 'int'>
value range:
0
to255
-
csa_testpulse_enable
¶ list-like property
list length:
64
registers:
range(100, 108)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
current_monitor_bank0
¶ list-like property
list length:
4
registers:
range(109, 110)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
current_monitor_bank1
¶ list-like property
list length:
4
registers:
range(110, 111)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
current_monitor_bank2
¶ list-like property
list length:
4
registers:
range(111, 112)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
current_monitor_bank3
¶ list-like property
list length:
4
registers:
range(112, 113)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
digital_monitor_chan
¶ simple value property
registers:
range(119, 120)
valid types:
<class 'int'>
value range:
0
to63
-
digital_monitor_enable
¶ compound property
registers:
range(118, 119)
bits:
[0]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['digital_monitor_select']
-
digital_monitor_select
¶ compound property
registers:
range(118, 119)
bits:
[1, 2, 3, 4]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to10
shares a register with:
['digital_monitor_enable']
-
digital_threshold
¶ list-like property
list length:
64
registers:
range(173, 237)
element valid types:
<class 'int'>
element value range:
0
to255
-
enable_cross_trigger
¶ compound property
registers:
range(128, 129)
bits:
[0]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
enable_dynamic_reset
¶ compound property
registers:
range(170, 171)
bits:
[0]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_min_delta_adc', 'threshold_polarity', 'reset_length', 'mark_first_packet']
-
enable_fifo_diagnostics
¶ compound property
registers:
range(123, 124)
bits:
[2]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['load_config_defaults', 'clk_ctrl']
-
enable_hit_veto
¶ compound property
registers:
range(128, 129)
bits:
[6]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto']
-
enable_min_delta_adc
¶ compound property
registers:
range(170, 171)
bits:
[1]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_dynamic_reset', 'threshold_polarity', 'reset_length', 'mark_first_packet']
-
enable_miso_differential
¶ compound list-like property
list length:
4
registers:
range(125, 126)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
shares a register with:
['enable_miso_downstream']
-
enable_miso_downstream
¶ compound list-like property
list length:
4
registers:
range(125, 126)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
shares a register with:
['enable_miso_differential']
-
enable_miso_upstream
¶ list-like property
list length:
4
registers:
range(124, 125)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
enable_mosi
¶ list-like property
list length:
4
registers:
range(126, 127)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
enable_periodic_reset
¶ compound property
registers:
range(128, 129)
bits:
[1]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
enable_periodic_trigger
¶ compound property
registers:
range(128, 129)
bits:
[3]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
enable_periodic_trigger_veto
¶ compound property
registers:
range(128, 129)
bits:
[5]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_hit_veto']
-
enable_rolling_periodic_reset
¶ compound property
registers:
range(128, 129)
bits:
[2]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
enable_rolling_periodic_trigger
¶ compound property
registers:
range(128, 129)
bits:
[4]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
external_trigger_mask
¶ list-like property
list length:
64
registers:
range(139, 147)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
ibias_buffer
¶ simple value property
registers:
range(76, 77)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_comp
¶ simple value property
registers:
range(75, 76)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_csa
¶ simple value property
registers:
range(77, 78)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_tdac
¶ simple value property
registers:
range(74, 75)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_tpulse
¶ simple value property
registers:
range(80, 81)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_vcm_buffer
¶ simple value property
registers:
range(79, 80)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_vref_buffer
¶ simple value property
registers:
range(78, 79)
valid types:
<class 'int'>
value range:
0
to15
-
load_config_defaults
¶ compound property
registers:
range(123, 124)
bits:
[1]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_fifo_diagnostics', 'clk_ctrl']
-
mark_first_packet
¶ compound property
registers:
range(170, 171)
bits:
[6]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_dynamic_reset', 'enable_min_delta_adc', 'threshold_polarity', 'reset_length']
-
min_delta_adc
¶ simple value property
registers:
range(172, 173)
valid types:
<class 'int'>
value range:
0
to255
-
override_ref
¶ compound property
registers:
range(81, 82)
bits:
[5]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['ref_current_trim', 'ref_kickstart']
-
periodic_reset_cycles
¶ simple value property
registers:
range(163, 166)
valid types:
<class 'int'>
value range:
0
to16777215
-
periodic_trigger_cycles
¶ simple value property
registers:
range(166, 170)
valid types:
<class 'int'>
value range:
0
to4294967295
-
periodic_trigger_mask
¶ list-like property
list length:
64
registers:
range(155, 163)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
pixel_trim_dac
¶ list-like property
list length:
64
registers:
range(0, 64)
element valid types:
<class 'int'>
element value range:
0
to31
-
ref_current_trim
¶ compound property
registers:
range(81, 82)
bits:
[0, 1, 2, 3, 4]
valid types:
<class 'int'>
value range:
0
to31
shares a register with:
['override_ref', 'ref_kickstart']
-
ref_kickstart
¶ compound property
registers:
range(81, 82)
bits:
[6]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['ref_current_trim', 'override_ref']
-
reset_length
¶ compound property
registers:
range(170, 171)
bits:
[3, 4, 5]
valid types:
<class 'int'>
value range:
0
to7
shares a register with:
['enable_dynamic_reset', 'enable_min_delta_adc', 'threshold_polarity', 'mark_first_packet']
-
reset_threshold
¶ simple value property
registers:
range(171, 172)
valid types:
<class 'int'>
value range:
0
to255
-
slope_control0
¶ compound property
registers:
range(120, 121)
bits:
[0, 1, 2, 3]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['slope_control1']
-
slope_control1
¶ compound property
registers:
range(120, 121)
bits:
[4, 5, 6, 7]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['slope_control0']
-
slope_control2
¶ compound property
registers:
range(121, 122)
bits:
[0, 1, 2, 3]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['slope_control3']
-
slope_control3
¶ compound property
registers:
range(121, 122)
bits:
[4, 5, 6, 7]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['slope_control2']
-
test_mode_uart0
¶ compound property
registers:
range(127, 128)
bits:
[0, 1]
valid types:
<class 'int'>
value range:
0
to4
shares a register with:
['test_mode_uart1', 'test_mode_uart2', 'test_mode_uart3']
-
test_mode_uart1
¶ compound property
registers:
range(127, 128)
bits:
[2, 3]
valid types:
<class 'int'>
value range:
0
to4
shares a register with:
['test_mode_uart0', 'test_mode_uart2', 'test_mode_uart3']
-
test_mode_uart2
¶ compound property
registers:
range(127, 128)
bits:
[4, 5]
valid types:
<class 'int'>
value range:
0
to4
shares a register with:
['test_mode_uart0', 'test_mode_uart1', 'test_mode_uart3']
-
test_mode_uart3
¶ compound property
registers:
range(127, 128)
bits:
[6, 7]
valid types:
<class 'int'>
value range:
0
to4
shares a register with:
['test_mode_uart0', 'test_mode_uart1', 'test_mode_uart2']
-
threshold_global
¶ simple value property
registers:
range(64, 65)
valid types:
<class 'int'>
value range:
0
to255
-
threshold_polarity
¶ compound property
registers:
range(170, 171)
bits:
[2]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_dynamic_reset', 'enable_min_delta_adc', 'reset_length', 'mark_first_packet']
-
vcm_dac
¶ simple value property
registers:
range(83, 84)
valid types:
<class 'int'>
value range:
0
to255
-
voltage_monitor_bank0
¶ list-like property
list length:
3
registers:
range(113, 114)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
voltage_monitor_bank1
¶ list-like property
list length:
3
registers:
range(114, 115)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
voltage_monitor_bank2
¶ list-like property
list length:
3
registers:
range(115, 116)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
voltage_monitor_bank3
¶ list-like property
list length:
3
registers:
range(116, 117)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
voltage_monitor_refgen
¶ list-like property
list length:
8
registers:
range(117, 118)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
vref_dac
¶ simple value property
registers:
range(82, 83)
valid types:
<class 'int'>
value range:
0
to255
-
LightPix ASIC Configuration Registers¶
-
class
larpix.configuration.configuration_lightpix_v1.
Configuration_Lightpix_v1
[source]¶ Represents the desired configuration state of a LightPix v1 chip.
This is a small extension of the LArPix v2 configuration register space to include the additional registers associated with LightPix, see the v2 configuration class for a more detailed description of the implementation.
-
adc_burst_length
¶ simple value property
registers:
range(130, 131)
valid types:
<class 'int'>
value range:
0
to255
-
adc_hold_delay
¶ simple value property
registers:
range(129, 130)
valid types:
<class 'int'>
value range:
0
to15
-
bypass_caps_en
¶ compound property
registers:
range(65, 66)
bits:
[2]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['csa_gain', 'csa_bypass_enable']
-
channel_mask
¶ list-like property
list length:
64
registers:
range(131, 139)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
chip_id
¶ simple value property
registers:
range(122, 123)
valid types:
<class 'int'>
value range:
0
to255
-
clk_ctrl
¶ compound property
registers:
range(123, 124)
bits:
[3, 4]
valid types:
<class 'int'>
value range:
0
to2
shares a register with:
['load_config_defaults', 'enable_fifo_diagnostics']
-
cross_trigger_mask
¶ list-like property
list length:
64
registers:
range(147, 155)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
csa_bypass_enable
¶ compound property
registers:
range(65, 66)
bits:
[1]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['csa_gain', 'bypass_caps_en']
-
csa_bypass_select
¶ list-like property
list length:
64
registers:
range(84, 92)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
csa_enable
¶ list-like property
list length:
64
registers:
range(66, 74)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
csa_gain
¶ compound property
registers:
range(65, 66)
bits:
[0]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['csa_bypass_enable', 'bypass_caps_en']
-
csa_monitor_select
¶ list-like property
list length:
64
registers:
range(92, 100)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
csa_testpulse_dac
¶ simple value property
registers:
range(108, 109)
valid types:
<class 'int'>
value range:
0
to255
-
csa_testpulse_enable
¶ list-like property
list length:
64
registers:
range(100, 108)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
current_monitor_bank0
¶ list-like property
list length:
4
registers:
range(109, 110)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
current_monitor_bank1
¶ list-like property
list length:
4
registers:
range(110, 111)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
current_monitor_bank2
¶ list-like property
list length:
4
registers:
range(111, 112)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
current_monitor_bank3
¶ list-like property
list length:
4
registers:
range(112, 113)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
digital_monitor_chan
¶ simple value property
registers:
range(119, 120)
valid types:
<class 'int'>
value range:
0
to63
-
digital_monitor_enable
¶ compound property
registers:
range(118, 119)
bits:
[0]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['digital_monitor_select']
-
digital_monitor_select
¶ compound property
registers:
range(118, 119)
bits:
[1, 2, 3, 4]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to10
shares a register with:
['digital_monitor_enable']
-
digital_threshold
¶ list-like property
list length:
64
registers:
range(173, 237)
element valid types:
<class 'int'>
element value range:
0
to255
-
enable_cross_trigger
¶ compound property
registers:
range(128, 129)
bits:
[0]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
enable_dynamic_reset
¶ compound property
registers:
range(170, 171)
bits:
[0]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_min_delta_adc', 'threshold_polarity', 'reset_length', 'mark_first_packet']
-
enable_fifo_diagnostics
¶ compound property
registers:
range(123, 124)
bits:
[2]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['load_config_defaults', 'clk_ctrl']
-
enable_hit_veto
¶ compound property
registers:
range(128, 129)
bits:
[6]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto']
-
enable_min_delta_adc
¶ compound property
registers:
range(170, 171)
bits:
[1]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_dynamic_reset', 'threshold_polarity', 'reset_length', 'mark_first_packet']
-
enable_miso_differential
¶ compound list-like property
list length:
4
registers:
range(125, 126)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
shares a register with:
['enable_miso_downstream']
-
enable_miso_downstream
¶ compound list-like property
list length:
4
registers:
range(125, 126)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
shares a register with:
['enable_miso_differential']
-
enable_miso_upstream
¶ list-like property
list length:
4
registers:
range(124, 125)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
enable_mosi
¶ list-like property
list length:
4
registers:
range(126, 127)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
enable_periodic_reset
¶ compound property
registers:
range(128, 129)
bits:
[1]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
enable_periodic_trigger
¶ compound property
registers:
range(128, 129)
bits:
[3]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
enable_periodic_trigger_veto
¶ compound property
registers:
range(128, 129)
bits:
[5]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_hit_veto']
-
enable_rolling_periodic_reset
¶ compound property
registers:
range(128, 129)
bits:
[2]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
enable_rolling_periodic_trigger
¶ compound property
registers:
range(128, 129)
bits:
[4]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
external_trigger_mask
¶ list-like property
list length:
64
registers:
range(139, 147)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
hit_threshold
¶ compound property
registers:
range(237, 238)
bits:
[1, 2, 3, 4, 5, 6, 7]
valid types:
<class 'int'>
value range:
0
to127
shares a register with:
['lightpix_mode']
-
ibias_buffer
¶ simple value property
registers:
range(76, 77)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_comp
¶ simple value property
registers:
range(75, 76)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_csa
¶ simple value property
registers:
range(77, 78)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_tdac
¶ simple value property
registers:
range(74, 75)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_tpulse
¶ simple value property
registers:
range(80, 81)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_vcm_buffer
¶ simple value property
registers:
range(79, 80)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_vref_buffer
¶ simple value property
registers:
range(78, 79)
valid types:
<class 'int'>
value range:
0
to15
-
lightpix_mode
¶ compound property
registers:
range(237, 238)
bits:
[0]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['hit_threshold']
-
load_config_defaults
¶ compound property
registers:
range(123, 124)
bits:
[1]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_fifo_diagnostics', 'clk_ctrl']
-
mark_first_packet
¶ compound property
registers:
range(170, 171)
bits:
[6]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_dynamic_reset', 'enable_min_delta_adc', 'threshold_polarity', 'reset_length']
-
min_delta_adc
¶ simple value property
registers:
range(172, 173)
valid types:
<class 'int'>
value range:
0
to255
-
override_ref
¶ compound property
registers:
range(81, 82)
bits:
[5]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['ref_current_trim', 'ref_kickstart']
-
periodic_reset_cycles
¶ simple value property
registers:
range(163, 166)
valid types:
<class 'int'>
value range:
0
to16777215
-
periodic_trigger_cycles
¶ simple value property
registers:
range(166, 170)
valid types:
<class 'int'>
value range:
0
to4294967295
-
periodic_trigger_mask
¶ list-like property
list length:
64
registers:
range(155, 163)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
pixel_trim_dac
¶ list-like property
list length:
64
registers:
range(0, 64)
element valid types:
<class 'int'>
element value range:
0
to31
-
ref_current_trim
¶ compound property
registers:
range(81, 82)
bits:
[0, 1, 2, 3, 4]
valid types:
<class 'int'>
value range:
0
to31
shares a register with:
['override_ref', 'ref_kickstart']
-
ref_kickstart
¶ compound property
registers:
range(81, 82)
bits:
[6]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['ref_current_trim', 'override_ref']
-
reset_length
¶ compound property
registers:
range(170, 171)
bits:
[3, 4, 5]
valid types:
<class 'int'>
value range:
0
to7
shares a register with:
['enable_dynamic_reset', 'enable_min_delta_adc', 'threshold_polarity', 'mark_first_packet']
-
reset_threshold
¶ simple value property
registers:
range(171, 172)
valid types:
<class 'int'>
value range:
0
to255
-
slope_control0
¶ compound property
registers:
range(120, 121)
bits:
[0, 1, 2, 3]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['slope_control1']
-
slope_control1
¶ compound property
registers:
range(120, 121)
bits:
[4, 5, 6, 7]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['slope_control0']
-
slope_control2
¶ compound property
registers:
range(121, 122)
bits:
[0, 1, 2, 3]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['slope_control3']
-
slope_control3
¶ compound property
registers:
range(121, 122)
bits:
[4, 5, 6, 7]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['slope_control2']
-
test_mode_uart0
¶ compound property
registers:
range(127, 128)
bits:
[0, 1]
valid types:
<class 'int'>
value range:
0
to4
shares a register with:
['test_mode_uart1', 'test_mode_uart2', 'test_mode_uart3']
-
test_mode_uart1
¶ compound property
registers:
range(127, 128)
bits:
[2, 3]
valid types:
<class 'int'>
value range:
0
to4
shares a register with:
['test_mode_uart0', 'test_mode_uart2', 'test_mode_uart3']
-
test_mode_uart2
¶ compound property
registers:
range(127, 128)
bits:
[4, 5]
valid types:
<class 'int'>
value range:
0
to4
shares a register with:
['test_mode_uart0', 'test_mode_uart1', 'test_mode_uart3']
-
test_mode_uart3
¶ compound property
registers:
range(127, 128)
bits:
[6, 7]
valid types:
<class 'int'>
value range:
0
to4
shares a register with:
['test_mode_uart0', 'test_mode_uart1', 'test_mode_uart2']
-
threshold_global
¶ simple value property
registers:
range(64, 65)
valid types:
<class 'int'>
value range:
0
to255
-
threshold_polarity
¶ compound property
registers:
range(170, 171)
bits:
[2]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_dynamic_reset', 'enable_min_delta_adc', 'reset_length', 'mark_first_packet']
-
timeout
¶ simple value property
registers:
range(238, 239)
valid types:
<class 'int'>
value range:
0
to255
-
vcm_dac
¶ simple value property
registers:
range(83, 84)
valid types:
<class 'int'>
value range:
0
to255
-
voltage_monitor_bank0
¶ list-like property
list length:
3
registers:
range(113, 114)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
voltage_monitor_bank1
¶ list-like property
list length:
3
registers:
range(114, 115)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
voltage_monitor_bank2
¶ list-like property
list length:
3
registers:
range(115, 116)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
voltage_monitor_bank3
¶ list-like property
list length:
3
registers:
range(116, 117)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
voltage_monitor_refgen
¶ list-like property
list length:
8
registers:
range(117, 118)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
vref_dac
¶ simple value property
registers:
range(82, 83)
valid types:
<class 'int'>
value range:
0
to255
-
LArPix v2b ASIC Configuration Registers¶
-
class
larpix.configuration.configuration_v2b.
Configuration_v2b
[source]¶ Represents the desired configuration state of a LArPix v2b chip.
Each register name is available as its own attribute for inspecting and setting the value of the corresponding register.
Certain configuration values are set channel-by-channel. These are represented by a list of values. For example:
>>> conf.pixel_trim_dac[2:5] [16, 16, 16] >>> conf.channel_mask[20] = 1 >>> conf.external_trigger_mask = [0] * 64
Additionally, other configuration values take up more than or less than one complete register. These are still set by referencing the appropriate name. For example,
cross_trigger_mode
shares a register with a few other values, and adjusting the value of thecross_trigger_mode
attribute will leave the other values unchanged.Each register name can cover more than one ‘physical’ register depending on the size of the data it holds. You can see which physical registers a given register name corresponds to by using the register_map attribute, e.g.:
>>> conf.register_map['digital_threshold'] # 64 registers, 1 per channel range(173, 237) >>> conf.register_map['enable_dynamic_reset'] # Register 170 range(170, 171) >>> conf.register_map['enable_min_delta_adc'] # Shares register 170 range(170, 171)
-
RESERVED
¶ simple value property
registers:
range(237, 239)
valid types:
<class 'int'>
value range:
0
to0
-
adc_burst_length
¶ simple value property
registers:
range(130, 131)
valid types:
<class 'int'>
value range:
0
to255
-
adc_hold_delay
¶ simple value property
registers:
range(120, 122)
valid types:
<class 'int'>
value range:
0
to65535
-
bypass_caps_en
¶ compound property
registers:
range(65, 66)
bits:
[2]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['csa_gain', 'csa_bypass_enable']
-
channel_mask
¶ list-like property
list length:
64
registers:
range(131, 139)
element valid types:
<class 'int'>
element value range:
0
to1
-
chip_id
¶ simple value property
registers:
range(122, 123)
valid types:
<class 'int'>
value range:
0
to255
-
clk_ctrl
¶ compound property
registers:
range(123, 124)
bits:
[3, 4]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to3
shares a register with:
['enable_tx_dynamic_powerdown', 'load_config_defaults', 'enable_fifo_diagnostics', 'tx_dynamic_powerdown_cycles']
-
cross_trigger_mask
¶ list-like property
list length:
64
registers:
range(147, 155)
element valid types:
<class 'int'>
element value range:
0
to1
-
csa_bypass_enable
¶ compound property
registers:
range(65, 66)
bits:
[1]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['csa_gain', 'bypass_caps_en']
-
csa_bypass_select
¶ list-like property
list length:
64
registers:
range(84, 92)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
csa_enable
¶ list-like property
list length:
64
registers:
range(66, 74)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
csa_gain
¶ compound property
registers:
range(65, 66)
bits:
[0]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['csa_bypass_enable', 'bypass_caps_en']
-
csa_monitor_select
¶ list-like property
list length:
64
registers:
range(92, 100)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
csa_testpulse_dac
¶ simple value property
registers:
range(108, 109)
valid types:
<class 'int'>
value range:
0
to255
-
csa_testpulse_enable
¶ list-like property
list length:
64
registers:
range(100, 108)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
current_monitor_bank0
¶ list-like property
list length:
4
registers:
range(109, 110)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
current_monitor_bank1
¶ list-like property
list length:
4
registers:
range(110, 111)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
current_monitor_bank2
¶ list-like property
list length:
4
registers:
range(111, 112)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
current_monitor_bank3
¶ list-like property
list length:
4
registers:
range(112, 113)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
digital_monitor_chan
¶ simple value property
registers:
range(119, 120)
valid types:
<class 'int'>
value range:
0
to63
-
digital_monitor_enable
¶ compound property
registers:
range(118, 119)
bits:
[0]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['digital_monitor_select']
-
digital_monitor_select
¶ compound property
registers:
range(118, 119)
bits:
[1, 2, 3, 4]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to10
shares a register with:
['digital_monitor_enable']
-
digital_threshold
¶ list-like property
list length:
64
registers:
range(173, 237)
element valid types:
<class 'int'>
element value range:
0
to255
-
enable_cross_trigger
¶ compound property
registers:
range(128, 129)
bits:
[0]
valid types:
<class 'int'>
value range:
0
to1
shares a register with:
['enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
enable_dynamic_reset
¶ compound property
registers:
range(170, 171)
bits:
[0]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_min_delta_adc', 'threshold_polarity', 'reset_length', 'mark_first_packet']
-
enable_fifo_diagnostics
¶ compound property
registers:
range(123, 124)
bits:
[2]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_tx_dynamic_powerdown', 'load_config_defaults', 'clk_ctrl', 'tx_dynamic_powerdown_cycles']
-
enable_hit_veto
¶ compound property
registers:
range(128, 129)
bits:
[6]
valid types:
<class 'int'>
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto']
-
enable_min_delta_adc
¶ compound property
registers:
range(170, 171)
bits:
[1]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_dynamic_reset', 'threshold_polarity', 'reset_length', 'mark_first_packet']
-
enable_periodic_reset
¶ compound property
registers:
range(128, 129)
bits:
[1]
valid types:
<class 'int'>
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
enable_periodic_trigger
¶ compound property
registers:
range(128, 129)
bits:
[3]
valid types:
<class 'int'>
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
enable_periodic_trigger_veto
¶ compound property
registers:
range(128, 129)
bits:
[5]
valid types:
<class 'int'>
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_hit_veto']
-
enable_piso_downstream
¶ list-like property
list length:
4
registers:
range(125, 126)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
enable_piso_upstream
¶ list-like property
list length:
4
registers:
range(124, 125)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
enable_posi
¶ list-like property
list length:
4
registers:
range(126, 127)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
enable_rolling_periodic_reset
¶ compound property
registers:
range(128, 129)
bits:
[2]
valid types:
<class 'int'>
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_periodic_trigger', 'enable_rolling_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
enable_rolling_periodic_trigger
¶ compound property
registers:
range(128, 129)
bits:
[4]
valid types:
<class 'int'>
value range:
0
to1
shares a register with:
['enable_cross_trigger', 'enable_periodic_reset', 'enable_rolling_periodic_reset', 'enable_periodic_trigger', 'enable_periodic_trigger_veto', 'enable_hit_veto']
-
enable_tx_dynamic_powerdown
¶ compound property
registers:
range(123, 124)
bits:
[0]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['load_config_defaults', 'enable_fifo_diagnostics', 'clk_ctrl', 'tx_dynamic_powerdown_cycles']
-
external_trigger_mask
¶ list-like property
list length:
64
registers:
range(139, 147)
element valid types:
<class 'int'>
element value range:
0
to1
-
i_rx0
¶ compound property
registers:
range(243, 244)
bits:
[0, 1, 2, 3]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['i_rx1']
-
i_rx1
¶ compound property
registers:
range(243, 244)
bits:
[4, 5, 6, 7]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['i_rx0']
-
i_rx2
¶ compound property
registers:
range(244, 245)
bits:
[0, 1, 2, 3]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['i_rx3']
-
i_rx3
¶ compound property
registers:
range(244, 245)
bits:
[4, 5, 6, 7]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['i_rx2']
-
i_rx_clk
¶ compound property
registers:
range(245, 246)
bits:
[0, 1, 2, 3]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['i_rx_rst']
-
i_rx_ext_trig
¶ simple value property
registers:
range(246, 247)
valid types:
<class 'int'>
value range:
0
to15
-
i_rx_rst
¶ compound property
registers:
range(245, 246)
bits:
[4, 5, 6, 7]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['i_rx_clk']
-
i_tx_diff0
¶ compound property
registers:
range(241, 242)
bits:
[0, 1, 2, 3]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['i_tx_diff1']
-
i_tx_diff1
¶ compound property
registers:
range(241, 242)
bits:
[4, 5, 6, 7]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['i_tx_diff0']
-
i_tx_diff2
¶ compound property
registers:
range(242, 243)
bits:
[0, 1, 2, 3]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['i_tx_diff3']
-
i_tx_diff3
¶ compound property
registers:
range(242, 243)
bits:
[4, 5, 6, 7]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['i_tx_diff2']
-
ibias_buffer
¶ simple value property
registers:
range(76, 77)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_comp
¶ simple value property
registers:
range(75, 76)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_csa
¶ simple value property
registers:
range(77, 78)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_tdac
¶ simple value property
registers:
range(74, 75)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_tpulse
¶ simple value property
registers:
range(80, 81)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_vcm_buffer
¶ simple value property
registers:
range(79, 80)
valid types:
<class 'int'>
value range:
0
to15
-
ibias_vref_buffer
¶ simple value property
registers:
range(78, 79)
valid types:
<class 'int'>
value range:
0
to15
-
load_config_defaults
¶ compound property
registers:
range(123, 124)
bits:
[1]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_tx_dynamic_powerdown', 'enable_fifo_diagnostics', 'clk_ctrl', 'tx_dynamic_powerdown_cycles']
-
mark_first_packet
¶ compound property
registers:
range(170, 171)
bits:
[6]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_dynamic_reset', 'enable_min_delta_adc', 'threshold_polarity', 'reset_length']
-
min_delta_adc
¶ simple value property
registers:
range(172, 173)
valid types:
<class 'int'>
value range:
0
to255
-
override_ref
¶ compound property
registers:
range(81, 82)
bits:
[5]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['ref_current_trim', 'ref_kickstart']
-
periodic_reset_cycles
¶ simple value property
registers:
range(163, 166)
valid types:
<class 'int'>
value range:
0
to16777215
-
periodic_trigger_cycles
¶ simple value property
registers:
range(166, 170)
valid types:
<class 'int'>
value range:
0
to4294967295
-
periodic_trigger_mask
¶ list-like property
list length:
64
registers:
range(155, 163)
element valid types:
<class 'int'>
element value range:
0
to1
-
pixel_trim_dac
¶ list-like property
list length:
64
registers:
range(0, 64)
element valid types:
<class 'int'>
element value range:
0
to31
-
r_term0
¶ simple value property
registers:
range(247, 248)
valid types:
<class 'int'>
value range:
0
to31
-
r_term1
¶ simple value property
registers:
range(248, 249)
valid types:
<class 'int'>
value range:
0
to31
-
r_term2
¶ simple value property
registers:
range(249, 250)
valid types:
<class 'int'>
value range:
0
to31
-
r_term3
¶ simple value property
registers:
range(250, 251)
valid types:
<class 'int'>
value range:
0
to31
-
r_term_clk
¶ simple value property
registers:
range(251, 252)
valid types:
<class 'int'>
value range:
0
to31
-
r_term_ext_trig
¶ simple value property
registers:
range(253, 254)
valid types:
<class 'int'>
value range:
0
to31
-
r_term_reset
¶ simple value property
registers:
range(252, 253)
valid types:
<class 'int'>
value range:
0
to31
-
ref_current_trim
¶ compound property
registers:
range(81, 82)
bits:
[0, 1, 2, 3, 4]
valid types:
<class 'int'>
value range:
0
to31
shares a register with:
['override_ref', 'ref_kickstart']
-
ref_kickstart
¶ compound property
registers:
range(81, 82)
bits:
[6]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['ref_current_trim', 'override_ref']
-
reset_length
¶ compound property
registers:
range(170, 171)
bits:
[3, 4, 5]
valid types:
<class 'int'>
value range:
0
to7
shares a register with:
['enable_dynamic_reset', 'enable_min_delta_adc', 'threshold_polarity', 'mark_first_packet']
-
reset_threshold
¶ simple value property
registers:
range(171, 172)
valid types:
<class 'int'>
value range:
0
to255
-
shadow_reset_length
¶ simple value property
registers:
range(129, 130)
valid types:
<class 'int'>
value range:
0
to255
-
test_mode_uart0
¶ compound property
registers:
range(127, 128)
bits:
[0, 1]
valid types:
<class 'int'>
value range:
0
to3
shares a register with:
['test_mode_uart1', 'test_mode_uart2', 'test_mode_uart3']
-
test_mode_uart1
¶ compound property
registers:
range(127, 128)
bits:
[2, 3]
valid types:
<class 'int'>
value range:
0
to3
shares a register with:
['test_mode_uart0', 'test_mode_uart2', 'test_mode_uart3']
-
test_mode_uart2
¶ compound property
registers:
range(127, 128)
bits:
[4, 5]
valid types:
<class 'int'>
value range:
0
to3
shares a register with:
['test_mode_uart0', 'test_mode_uart1', 'test_mode_uart3']
-
test_mode_uart3
¶ compound property
registers:
range(127, 128)
bits:
[6, 7]
valid types:
<class 'int'>
value range:
0
to3
shares a register with:
['test_mode_uart0', 'test_mode_uart1', 'test_mode_uart2']
-
threshold_global
¶ simple value property
registers:
range(64, 65)
valid types:
<class 'int'>
value range:
0
to255
-
threshold_polarity
¶ compound property
registers:
range(170, 171)
bits:
[2]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to1
shares a register with:
['enable_dynamic_reset', 'enable_min_delta_adc', 'reset_length', 'mark_first_packet']
-
tx_dynamic_powerdown_cycles
¶ compound property
registers:
range(123, 124)
bits:
[5, 6, 7]
valid types:
(<class 'int'>, <class 'bool'>)
value range:
0
to7
shares a register with:
['enable_tx_dynamic_powerdown', 'load_config_defaults', 'enable_fifo_diagnostics', 'clk_ctrl']
-
tx_slices0
¶ compound property
registers:
range(239, 240)
bits:
[0, 1, 2, 3]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['tx_slices1']
-
tx_slices1
¶ compound property
registers:
range(239, 240)
bits:
[4, 5, 6, 7]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['tx_slices0']
-
tx_slices2
¶ compound property
registers:
range(240, 241)
bits:
[0, 1, 2, 3]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['tx_slices3']
-
tx_slices3
¶ compound property
registers:
range(240, 241)
bits:
[4, 5, 6, 7]
valid types:
<class 'int'>
value range:
0
to15
shares a register with:
['tx_slices2']
-
v_cm_lvds_tx0
¶ compound property
registers:
range(254, 255)
bits:
[0, 1, 2]
valid types:
<class 'int'>
value range:
0
to7
shares a register with:
[]
-
v_cm_lvds_tx1
¶ compound property
registers:
range(254, 255)
bits:
[4, 5, 6]
valid types:
<class 'int'>
value range:
0
to7
shares a register with:
['v_cm_lvds_tx0', 'v_cm_lvds_tx0']
-
v_cm_lvds_tx2
¶ compound property
registers:
range(255, 256)
bits:
[0, 1, 2]
valid types:
<class 'int'>
value range:
0
to7
shares a register with:
['v_cm_lvds_tx3']
-
v_cm_lvds_tx3
¶ compound property
registers:
range(255, 256)
bits:
[4, 5, 6]
valid types:
<class 'int'>
value range:
0
to7
shares a register with:
['v_cm_lvds_tx2']
-
vcm_dac
¶ simple value property
registers:
range(83, 84)
valid types:
<class 'int'>
value range:
0
to255
-
voltage_monitor_bank0
¶ list-like property
list length:
3
registers:
range(113, 114)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
voltage_monitor_bank1
¶ list-like property
list length:
3
registers:
range(114, 115)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
voltage_monitor_bank2
¶ list-like property
list length:
3
registers:
range(115, 116)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
voltage_monitor_bank3
¶ list-like property
list length:
3
registers:
range(116, 117)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
voltage_monitor_refgen
¶ list-like property
list length:
8
registers:
range(117, 118)
element valid types:
(<class 'int'>, <class 'bool'>)
element value range:
0
to1
-
vref_dac
¶ simple value property
registers:
range(82, 83)
valid types:
<class 'int'>
value range:
0
to255
-
LArPix Configuration Files¶
Here is the documentation for the configuration files.
Chip configuration files¶
This module contains chip configuration files. They are formatted as standard
JSON files with the following fields: "_config_type"
, "class"
, and
"register_values"
. The _config_type
field should always be set to
"chip"
and is used for validation when loading the configuration. An
optional "_include"
field can be used to specify other configurations to
inherit configuration values from. Configuration inheritance occurs in the order
specified in the list so if a conflict is encountered, fields from a file later
in the list will overwrite fields from a file earlier in the list.
Additionally, the class
field provides additional validation. There are two
configuration classes: "Configuration_v1"
, "Configuration_v2"
, and "Configuration_Lightpix_v1"
, each
corresponding to its respective larpix.configuration
class. Attempting to
load a Configuration_v1
config file to a Configuration_v2
object and
vice versa will raise a runtime error.
The register_values
field is a dict of the register name and the value to
use. All non-default fields should be specified, but it is recommended to use no
more than the minimum required. The following is an example of a partially-specified v2 configuration
file, which will maintain the current configuration except for the specified fields:
{
"_config_type": "chip",
"_include": []
"class": "Configuration_v2",
"register_values": {
"enable_periodic_reset": 1,
"enable_periodic_trigger": 1,
"enable_rolling_periodic_trigger": 1,
"periodic_trigger_cycles": 100000
}
}
Here is an example using the configuration file inheritance:
{
"_config_type": "chip",
"_include": ["chip/default_v2.json"]
}
Which will be expanded to be the equivalent of:
{
"_config_type": "chip",
"_include": [],
"class": "Configuration_v2",
"register_values": {
"pixel_trim_dac": [16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16],
"threshold_global": 255,
"csa_gain": 1,
"csa_bypass_enable": 0,
"bypass_caps_en": 1,
"csa_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
"ibias_tdac": 8,
"ibias_comp": 8,
"ibias_buffer": 8,
"ibias_csa": 8,
"ibias_vref_buffer": 8,
"ibias_vcm_buffer": 8,
"ibias_tpulse": 6,
"ref_current_trim": 16,
"override_ref": 0,
"ref_kickstart": 0,
"vref_dac": 219,
"vcm_dac": 77,
"csa_bypass_select": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"csa_monitor_select": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"csa_testpulse_enable": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
"csa_testpulse_dac": 0,
"current_monitor_bank0": [0, 0, 0, 0],
"current_monitor_bank1": [0, 0, 0, 0],
"current_monitor_bank2": [0, 0, 0, 0],
"current_monitor_bank3": [0, 0, 0, 0],
"voltage_monitor_bank0": [0, 0, 0],
"voltage_monitor_bank1": [0, 0, 0],
"voltage_monitor_bank2": [0, 0, 0],
"voltage_monitor_bank3": [0, 0, 0],
"voltage_monitor_refgen": [0, 0, 0, 0, 0, 0, 0, 0],
"digital_monitor_enable": 1,
"digital_monitor_select": 0,
"digital_monitor_chan": 0,
"slope_control0": 0,
"slope_control1": 0,
"slope_control2": 0,
"slope_control3": 0,
"chip_id": 1,
"load_config_defaults": 0,
"enable_fifo_diagnostics": 0,
"clk_ctrl": 0,
"enable_miso_upstream": [0, 0, 0, 0],
"enable_miso_downstream": [0, 0, 0, 0],
"enable_miso_differential": [0, 0, 0, 0],
"enable_mosi": [0, 0, 0, 0],
"test_mode_uart0": 0,
"test_mode_uart1": 0,
"test_mode_uart2": 0,
"test_mode_uart3": 0,
"enable_cross_trigger": 0,
"enable_periodic_reset": 0,
"enable_rolling_periodic_reset": 0,
"enable_periodic_trigger": 0,
"enable_rolling_periodic_trigger": 0,
"enable_periodic_trigger_veto": 1,
"enable_hit_veto": 1,
"adc_hold_delay": 0,
"adc_burst_length": 0,
"channel_mask": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
"external_trigger_mask": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
"cross_trigger_mask": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
"periodic_trigger_mask": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
"periodic_reset_cycles": 4096,
"periodic_trigger_cycles": 0,
"enable_dynamic_reset": 0,
"enable_min_delta_adc": 0,
"threshold_parity": 1,
"reset_length": 1,
"mark_first_packet": 1,
"reset_threshold": 0,
"min_delta_adc": 0,
"digital_threshold": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
}
}
Controller configuration files¶
This module contains controller configuration files, used to specify the physical asics present and their network structure
V2 Configuration¶
The v2 configuration file is a standard JSON file structured as follows:
{
"_config_type": "controller",
"_include": [<optional list of files to inherit from>],
"name": <string identifier for configuration ID, e.g. "pcb-3", or "acube-2x2">,
"layout": <string identifier for layout version, e.g. "1.2.0">,
"asic_version": 2,
"network": {
"miso_uart_map": [<uart channel for position in array, required>, ...],
"mosi_uart_map": [<uart channel for position in array, required>, ...],
"usds_link_map": [<position of chip relative to neighbor, required>, ...],
"<io_group>": {
"miso_uart_map": [<uart channels for io_group, optional>, ...],
...
"<io_channel>": {
"miso_uart_map": [<uart channels for io_group, optional>, ...],
...
"nodes": [
{
"chip_id": <chip id of first chip to load into network>,
"miso_us": [<chip_ids of upstream chips, null if no upstream chip, optional>],
"miso_ds": [<chip_ids of downstream chips, optional>],
"mosi": [<chip_ids of chips to listen to, optional>],
"root": <bool indicating if this is a root node, optional>,
"miso_uart_map": [<uart channels for chip, optional>, ...],
...
},
...
]
},
...
},
...
}
}
The structure allows for a lot of flexibility in the network configuration, while
maintaining a relatively terse format for simple configurations. Generally, a
Hydra network can be described using three directed graphs which we call
miso upstream (miso_us
), miso downstream (miso_ds
), and mosi (mosi
). The miso_us
graph
represents the flow of outgoing upstream packets (i.e. the direction of configuration
write packets). The miso_ds
graph represents the flow of outgoing downstream packet
(i.e. the direction of configuration read and data packets). The mosi
graph
represents the flow of incoming packets of either type. The overall LArPix
network is then defined with a collection of Hydra networks, each associated
with a specific io_group and io_channel. The io_group
, io_channel
pair must
be unique for each Hydra network.
For the configuration file, the basic requirement for each hydra network is that for each node in the network, you must specify a chip id. The chip id must be an integer between 2 and 254 for an ASIC, but other systems (i.e. an FPGA that can interpret the LArPix UART protocol) can be specified by a string. Each chip id must be unique within each io_group, io_channel sub-network.
To specify links within the 3 directed graphs (miso_us
, miso_ds
, and mosi
), a
4-item array is used. Each 4-item array indicates the chip id of the neighboring
nodes that should be connected to the given chip. So for example:
{
"chip_id": 23,
"miso_us": [24,null,null,null],
"miso_ds": [null,22,null,null],
"mosi": [24,22,null,null]
}
will create a miso_us
graph where data flows from chip 23 to chip 24, a miso_ds
graph where data flows from chip 23 to chip 22, and a mosi
graph where data
flows from chip 24 to 23 and chip 22 to 23 (note the opposite convention for the
mosi graph).
The position of the chip id within the 4-item array indicates the relative physical
location of the neighboring chip. A suggested ordering might be
[<top>,<left>,<down>,<right>]
, thus the previous example indicates
that the current chip should be linked to chip 24 which is above the current chip.
The definition of <top>
, <left>
, <down>
, and <right>
is fixed by which of
the four LArPix UARTs is used to communicate to a chip in that position. This
is declared with the "miso_uart_map"
and "mosi_uart_map"
definitions.
As an example, the upper left corner of the LArPix ASIC is UART 0 and the upper
right corner of the chip is UART 3, thus we can define
<top>
as the first position in each array by declaring
"miso_uart_map": [3,X,X,X]
and "mosi_uart_map": [0,X,X,X]
which will read
packets in on UART 0 and send packets out on UART 3. It doesn’t matter where
in the array <top>
is defined, as long as you have a consistent convention between
the miso_uart_map
, mosi_uart_map
, and each of your network node’s (miso_us
, miso_ds
,
and mosi
).
It would become very tedious and difficult to debug if for every node you had
to specify all of the links on all three of the graphs, so the configuration
parser is smarter than that. Most of the time, the networks that you’ll want to
specify have the same upstream and downstream connections (albeit with the
directions flipped), so if the "miso_ds"
field is not explicitly defined, it
will be inferred based on the miso_us
network that was created. Likewise, usually
the mosi
connections should be the same as the upstream and downstream connections.
Thus, if this field is not set explicitly it will be inferred automatically based
on the miso_us
graph and the miso_ds
graph.
However, in order for the auto-parsing methods to work, they need some information
about how the chips are oriented with respect to each other. This is defined by
the "usds_link_map"
. This field is also a 4-item array, however the value now
represents the position of the given chip from the perspective of the neighbor.
So, following the example from above, we can define two directions <top>
and
<bottom>
with "miso_uart_map": [3,X,1,X]
and "mosi_uart_map": [0,X,2,X]
.
If we have two chips (let’s say 22 and 23 with chip 23 above chip 22), to
determine the "usds_link_map"
we have to consider both where chip 23 is from the
perspective of chip 22 (<top>
, or index 0 from our definition) and where chip 22
is from the perspective of chip 23 (<bottom>
, or index 2 from out definition).
This means that the "usds_link_map"
for chip 22 should be [2,X,X,X]
, or in
other words, the chip (23) that is in the direction of <top>
(index 0) from
the current chip (22) sees the current chip (22) in the direction of <down>
(index 2). Likewise the "usds_link_map"
for chip 23 should be [X,X,0,X]
.
Now as long as you maintain the same definitions of <top>
and <bottom>
for
all of the chips in the network, you can set "usds_link_map"
at the top level
to be [2,X,0,X]
you don’t need to worry about figuring this out for each
node in the network… phew.
The final necessary component of the configuration is to declare some nodes
as root
nodes. These are special nodes which are used to indicate the first
node to be configured during the initialization of the network. Typically, the
placeholder node representing the external system is set as the root node.
Putting all of this together, a simple example of a complete network configuration is provided below:
"network": {
"1": {
"2": {
"nodes": [
{
"chip_id": "ext",
"miso_us": [null,null,2,null],
"root": true
}
{
"chip_id": 2,
"miso_us": [null,3,null,null]
},
{
"chip_id": 3
}
]
}
}
"miso_uart_map": [3,0,1,2],
"mosi_uart_map": [0,1,2,3],
"usds_link_map": [2,3,0,1]
}
In this example, we define a single 2-chip Hydra network with io_group=1
and io_channel=2
. The "nodes"
array is filled with dict``s representing each
node in the network. Globally, we've defined our "directions" with the
``miso_uart_map
and mosi_uart_map
, and we’ve set up the usds_link_map
so
that the auto-parsing algorithm can work. Within the "nodes"
array, we specify
three nodes (ext
, 2
, 3
); two of which represent chips (2
, 3
), and one of
which represents the external FPGA used to communicate with the network (ext
).
The external FPGA is set as the root
node so that the initialization of the
network starts from there. We’ve declared miso_us
links for the ext
and
2
nodes, but because we have not specified any miso_ds
or mosi
links, the
auto-parsing algorithm with generate the following graphs:
miso_us: 'ext' -> 2 -> 3
miso_ds: 'ext' <- 2 <- 3
mosi: 'ext' <-> 2 <-> 3
with the active uarts:
miso_us: 1 -> 0 -> X
miso_ds: X <- 3 <- 2
mosi: 2,0 <-> 1,3 <-> 3
Or, assuming you are using our definition above for <top>
, <bottom>
, etc.:
ext
v
3 < 2
The top-level "_include"
field can be used to specify files to inherit from.
All fields of the configuration down to the "nodes"
array level can be inherited.
A standard use for this would be to specify each hydra network for a given channel
independently, and inherit from all of the files in a single configuration
file. E.g.:
{
"_config_type": "controller",
"_include": [
"network-1-1.json",
"network-1-2.json",
"network-1-3.json",
"network-1-4.json",
"network-2-1.json",
"network-2-2.json",
"network-2-3.json",
"network-2-4.json"
],
"name": "multi-io-group-network"
}
LightPix Configuration¶
LightPix uses the same interface as LArPix v2 but with:
"asic_version": "lightpix-v1.0"
V1 Configuration¶
The v1 configuration file is a standard JSON file structured as follows:
{
"name": <string identifier for PCB ID, e.g. "pcb-3">,
"layout": <string identifier for layout version, e.g. "1.2.0">,
"asic_version": 1,
"chip_list": [<A list of chip keys, one for each chip, in daisy-chain order>]
}
All fields are necessary.
See the larpix-geometry documentation <https://github.com/samkohn/larpix-geometry> for a listing of all the layout versions.
IO configuration files¶
This module contains io configuration files used by io classes to look up
detector components based on the io_group
and io_channel
contained within
chip keys. See the larpix core documentation for more details on larpix.Key
objects.
JSON formatting¶
The format is a standard JSON file structured as follows:
{
"_config_type": "io",
"io_class": "<name of io class config should be used with>",
"io_group": [
[<io group number>, <assoc. value to be used by io class>],
...
]
}
Field description¶
The "_config_type": "io"
field is used in loading for validation (so that
you don’t accidentally try to load a chip
config into your io class. This
will always be “io” for io confiugration files.
The "io_class": "<name>"
field is used to specify the io class that the
configuration is compatible with. Examples are provided for each built-in io
class.
The "io_group": [[<group #>, <io class spec.>], ...]
list is a list of pairs
used to create a map between the io_group
number and the internal
representation used by the io class. E.g. the MultiZMQ_IO uses the IP address to
identify the io_group
.
LArPix IO¶
Implementations¶
Here is the documentation for various implemented IO classes.
Serial Port IO Interface¶
The serial port IO interface.
-
class
larpix.io.serialport.
SerialPort
(port=None, baudrate=1000000, timeout=0)[source]¶ Wrapper for various serial port interfaces across platforms.
Automatically loads correct driver based on the supplied port name:
'/dev/anything'
==> Linux ==> pySerial'scan-ftdi'
==> MacOS ==> libFTDI
-
classmethod
decode
(msgs, leftover_bytes=b'')[source]¶ Decodes a list of serial port bytestreams to packets
-
classmethod
is_valid_chip_key
(key)[source]¶ Valid chip keys must be strings formatted as:
'<io_chain>-<chip_id>'
-
send
(packets)[source]¶ Format the packets as a bytestream and send it to the FPGA and on to the LArPix ASICs.
-
set_larpix_uart_clk_ratio
(value)[source]¶ Sends a special command to modify the larpix uart clk ratio (how many clock cycles correspond to one bit). A value of 2 means 1 uart bit == 2 clk cycles
-
set_larpix_reset_cnt
(value)[source]¶ Sends a special command to modify the length of the reset signal sent to the larpix chips. The reset will be held low for value + 1 larpix clk rising edges
-
larpix_reset
()[source]¶ Sends a special command to issue a larpix reset pulse. Pulse length is set by set_larpix_reset_cnt().
-
set_utility_pulse
(pulse_len=None, pulse_rep=None)[source]¶ Sends a special command to issue set up utility pulser. Pulse length is the number of larpix clk cyles pulse is high, and pulse rep is the number of clk cycles until the next pulse.
-
enable_utility_pulse
()[source]¶ Sends a special command to enable the utility pulser. Pulse characteristics can be set by set_utility_pulse().
ZeroMQ IO Interface¶
-
class
larpix.io.zmq_io.
ZMQ_IO
(config_filepath=None, **kwargs)[source]¶ The ZMQ_IO object interfaces with the Bern LArPix v2 module using the ZeroMQ communications protocol. This class wraps the
io.multizmq_io.MultiZMQ_IO
class, and enables a slightly simpler chip key formatting in the special case that you are only interfacing with a single daq board.This object handles the required communications, and also has extra methods for additional functionality, including system reset, packet count, clock frequency, and more.
-
load
(filepath=None)[source]¶ Loads a specified IO configuration
Parameters: filepath – path to io configuration file (JSON)
-
set_clock
(freq_khz)[source]¶ Set the LArPix CLK2X freqency (in kHz).
Parameters: freq_khz – CLK2X freq in khz to set
-
set_testpulse_freq
(divisor)[source]¶ Set the testpulse frequency, computed by dividing the CLK2X frequency by
divisor
.
-
Multi-ZeroMQ IO Interface¶
-
class
larpix.io.multizmq_io.
MultiZMQ_IO
(config_filepath=None, miso_map=None, mosi_map=None)[source]¶ The MultiZMQ_IO object interfaces with a network of Bern LArPix v2 modules using Igor’s ZeroMQ communications protocol.
This object handles the required communications, and also has extra methods for additional functionality, including system reset, packet count, clock frequency, and more.
By default, when creating a MultiZMQ_IO object, the
io/default.json
configuration will attempt to be loaded unless otherwise specified. The path relative to the pwd is checked first, followed by the path of the larpix-control installation.-
send
(packets)[source]¶ Function for sending larpix packet objects
Parameters: packets – list
of larpixPacket
objects to send via IOReturns: None
-
empty_queue
()[source]¶ Process any awaiting messages from all ZMQ connections. Will continue to read until the hwm is reached or there are no more awaiting messages.
Returns: 2-tuple containing a list of received packets and the full bytestream
-
reset
(addresses=None)[source]¶ Send a reset pulse to the LArPix ASICs.
Parameters: addresses – list
of daq board addresses to reset, ifNone
reset all addresses
-
set_clock
(freq_khz, addresses=None)[source]¶ Set the LArPix CLK2X freqency (in kHz).
Parameters: - freq_khz – CLK2X freq in khz to set
- addresses –
list
of daq board addresses to change frequency, ifNone
modifies all addresses
-
set_testpulse_freq
(divisor, address)[source]¶ Set the testpulse frequency, computed by dividing the CLK2X frequency by
divisor
.Parameters: - divisor – test pulse frequency divisor
- address – daq board addresses to change test pulse freq
-
get_packet_count
(io_channel, address)[source]¶ Get the number of packets received, as determined by the number of UART “start” bits processed.
Parameters: - io_channel – IO channel to check
- address – address of daq board
-
FakeIO IO Interface¶
A module for the FakeIO class.
-
class
larpix.io.fakeio.
FakeIO
[source]¶ An IO stand-in that sends output to stdout (i.e. print) and reads input from a data member that can be set in advance.
The queue is implemented as a
collections.deque
object. Data can be queued up in advance through repeated calls toqueue.append()
. The first element of the queue will be passed on to theController.read
method each time it is called. This is a true queue, i.e. first-in, first-out.The format for an element of the queue is a tuple:
([list_of_Packets], b'corresponding bytes')
.Although meaningless in terms of the internal implementation,
FakeIO
objects contain an internal state determining whether the object is currently “listening,” and will raise aRuntimeError
ifempty_queue
is called when the object is not listening.-
static
add_timestamps
(packets, positions, timestamps=0)[source]¶ 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.
-
static
PACMAN IO Interface¶
-
class
larpix.io.pacman_io.
PACMAN_IO
(config_filepath=None, hwm=20000, relaxed=True, timeout=-1, raw_directory='./', raw_filename=None)[source]¶ The PACMAN_IO object interfaces with a network of PACMAN boards each running a pacman-cmdserver and pacman-dataserver.
This object handles the ZMQ messaging protocol to send and receive formatted messages to/from the PACMAN boards. If you want more info on how messages are formatted, see
larpix.format.pacman_msg_format
.The PACMAN_IO object has five flags for optimizing communications which you may or may not want to enable:
group_packets_by_io_group
interleave_packets_by_io_channel
double_send_packets
enable_raw_file_writing
disable_packet_parsing
To enable each option set the flag to
True
; to disable, set toFalse
.- The
group_packets_by_io_group
option is enabled by default and assembles the packets sent in each call tosend
into as few messages as possible destined for a single io group. E.g. sending three packets (2 forio_group=1
, 1 forio_group=2
) will combine the packets forio_group=1
into a single message to transfer over the network. This reduces overhead associated with network latency and allows large data transfers to happen much faster. - The
interleave_packets_by_io_channel
option is enabled by default and interleaves packets within a given message to each io_channel on a given io_group. E.g. 3 packets destined forio_channel=1
,io_channel=1
, andio_channel=2
will be reordered toio_channel=1
,io_channel=2
, andio_channel=1
. The order of the packets is preserved for each io_channel. This increases the data throughput by about a factor of N, where N is the number of io channels in the message. - The
double_send_packets
option is disabled by default and duplicates each packet sent to the PACMAN by a call tosend()
. This is potentially useful for working around the 512 bug when you need to insure that a packet reaches a chip, but you don’t care about introducing extra packets into the system (i.e. when configuring chips). - The
enable_raw_file_writing
option will directly dump data to a larpix raw hdf5 formatted file. This is used as a more performant means of logging data (seelarpix.format.rawhdf5format
). The data file name can be accessed or changed via theraw_filename
attribute, or can be set when creating thePACMAN_IO
object with theraw_directory
andraw_filename
keyword args. - The
disable_packet_parsing
option will skip converting PACMAN messages intolarpix.packet
types. Thus ifdisable_packet_parsing=True
, every call toempty_queue
will return[], b''
. Typically used in conjunction withenable_raw_file_writing
, this allows the PACMAN_IO class to read data much faster.
-
empty_queue
()[source]¶ Fetch and parse waiting packets on pacman data socket
returns tuple of list of packets, full bytestream of all messages
-
cleanup
()[source]¶ Close the ZMQ objects to prevent a memory leak.
This method is only required if you plan on instantiating a new
PACMAN_IO
object.
-
get_reg
(reg, io_group=None)[source]¶ Read a 32-bit register from the pacman PL
If no
io_group
is specified, returns adict
ofio_group, reg_value
else returns reg_value
-
ping
(io_group=None)[source]¶ Send a ping message
If no
io_group
is specified, returns adict
ofio_group, response
else returns response
-
get_vddd
(io_group=None)[source]¶ Gets PACMAN VDDD voltage
Returns VDDD and IDDD values from the built-in ADC as a tuple of mV and mA respectively
-
set_vddd
(vddd_dac=54691, io_group=None, settling_time=0.1)[source]¶ Sets PACMAN VDDD voltage
If no
vddd_dac
value is specified, sets VDDD to default of ~1.8VReturns the resulting VDDD and IDDD values from the built-in ADC as a tuple of mV and mA respectively
-
get_vdda
(io_group=None)[source]¶ Gets PACMAN VDDA voltage
Returns VDDA and IDDA values from the built-in ADC as a tuple of mV and mA respectively
-
set_vdda
(vdda_dac=54691, io_group=None, settling_time=0.1)[source]¶ Sets PACMAN VDDA voltage
If no
vdda_dac
value is specified, sets VDDA to default of ~1.8VReturns the resulting VDDA and IDDA values from the built-in ADC as a tuple of mV and mA respectively
-
get_vplus
(io_group=None)[source]¶ Gets PACMAN Vplus voltage
Returns Vplus and Iplus values from the built-in ADC as a tuple of mV and mA respectively
-
enable_tile
(tile_indices=None, io_group=None)[source]¶ Enables the specified pixel tile(s) (first tile is index=0, second tile is index=1, …).
Returns the value of the new tile enable mask
-
disable_tile
(tile_indices=None, io_group=None)[source]¶ Disables the specified pixel tile(s) (first tile is index=0, second tile is index=1, …).
Returns the value of the new tile enable mask
IO Class API¶
-
class
larpix.io.
IO
[source]¶ Base class for IO objects that explicitly describes the necessary functions required by any IO class implementation. Additional functions are not used by the larpix core classes.
-
__init__
()[source]¶ Declaration of IO object
Variables: is_listening – flag for start_listening
andstop_listening
-
load
(filepath=None)[source]¶ Loads a specified IO configuration
Parameters: filepath – path to io configuration file (JSON)
-
encode
(packets)[source]¶ Encodes a list of packets into a list of IO message objects
Parameters: packets – list
of larpixPacket
objects to encode into IO messagesReturns: list
of IO messages
-
decode
(msgs, **kwargs)[source]¶ Decodes a list of IO message objects into respective larpix
Packet
objectsParameters: - msgs –
list
of IO messages - kwargs – additional contextual information required to decode messages (implementation specific)
Returns: list
of larpixPacket
objects- msgs –
-
send
(packets)[source]¶ Function for sending larpix packet objects
Parameters: packets – list
of larpixPacket
objects to send via IOReturns: None
-
empty_queue
()[source]¶ Read and remove the current items in the internal queue. The details of the queue implementation is left up to the specific IO class. Generally returns all packets that have been read since last call to
start_listening
orempty_queue
, whichever was most recent.Returns: tuple
of (list
ofPacket
objects, raw bytestream)
-
LArPix Logger¶
-
class
larpix.logger.logger.
Logger
(enabled=False, *args, **kwargs)[source]¶ Base class for larpix logger objects that explicity describes the necessary functions for a Logger implementation. Additional functions are not built into the larpix core.
-
WRITE
= 0¶ Flag to indicate packets were sent to ASICs
-
READ
= 1¶ Flag to indicate packets were received from ASICs
-
record_configs
(chips)[source]¶ Save specified chip configs to log file (if applicable)
Parameters: configs – list of Chips to log
-
record
(data, direction=0, *args, **kwargs)[source]¶ Log specified data.
Parameters: - data –
list
of data to be written to log. Valid data types are specified by logger implementation. Raises aValueError
if datatype is invalid. - direction –
Logger.WRITE
if packets were sent to ASICs,Logger.READ
if packets were received from ASICs. (default:Logger.WRITE
)
- data –
-
Implementations¶
Here is the documentation for the various LArPix loggers.
Stdout Logger Interface¶
-
class
larpix.logger.stdout_logger.
StdoutLogger
(filename=None, buffer_length=0, mode='wa', enabled=False)[source]¶ The StdoutLogger is logger class that acts as a test logger class. All objects are displayed according to their string representation and routed to stdout.
Parameters: - buffer_length – how many data messages to hang on to before flushing buffer to stdout
- mode – how logger file should be opened (not implemented in
StdoutLogger
)
-
record
(data, direction=0)[source]¶ Send the specified data to stdout
Parameters: - data – list of data to be written to log
- direction – 0 if packets were sent to ASICs, 1 if packets were received from ASICs. optional, default=0
HDF5 Logger Interface¶
-
class
larpix.logger.h5_logger.
HDF5Logger
(filename=None, buffer_length=10000, directory='', version='2.4', enabled=False)[source]¶ The HDF5Logger is a logger class for logging packets to the LArPix+HDF5 format.
The file format is implemented in
larpix.format.hdf5format
, which also contains a function to convert back from LArPix+HDF5 to LArPix packets.Variables: data_desc_map – specifies the mapping between objects sent to the logger and the specific logger buffer to store them in. As of LArPix+HDF5 version 1.0 and larpix-control version 2.3.0 there is only one buffer called
'packets'
which stores all of the data to send to LArPix+HDF5.Parameters: - filename – filename to store data (appended to
directory
) (optional, default:None
) - buffer_length – how many data messages to hang on to before flushing
buffer to the file (optional, default:
10000
) - directory – the directory to save the data in (optional, default: ‘’)
- version – the format version of LArPix+HDF5 to use (optional,
default:
larpix.format.hdf5format.latest_version
)
-
record_configs
(chips)[source]¶ Write the specified chip configurations to the log file
Note
this method will also flush any data in the buffer to the log file
Parameters: chips – list of chips to record timestamps
-
record
(data, direction=0)[source]¶ Send the specified data to log file
Note
buffer is flushed after all
data
is placed in buffer, this means that the buffer size will exceed the set value temporarilyParameters: - data – list of data to be written to log
- direction –
Logger.WRITE
if packets were sent to ASICs,Logger.READ
if packets were received from ASICs. (default:Logger.WRITE
)
- filename – filename to store data (appended to
LArPix Formats¶
The data formats used for LArPix are:
LArPix+HDF5 Format¶
This module gives access to the LArPix+HDF5 file format.
File format description¶
All LArPix+HDF5 files use the HDF5 format so that they can be read and written using any language that has an HDF5 binding. The documentation for the Python h5py binding is at <http://docs.h5py.org>.
The to_file
and from_file
methods translate between a list of
Packet-like objects and an HDF5 data file. from_file
can be used to
load up the full file all at once or just a subset of rows (supposing
the full file was too big to fit in memory). To access the data most
efficiently, do not rely on from_file
and instead perform analysis
directly on the HDF5 data file.
File Header¶
The file header can be found in the /_header
HDF5 group. At a
minimum, the header will contain the following HDF5 attributes:
version
: a string containing the LArPix+HDF5 versioncreated
: a Unix timestamp of the file’s creation timemodified
: a Unix timestamp of the file’s last-modified time
Versions¶
The LArPix+HDF5 format is self-describing and versioned. This means as
the format evolves, the files themselves will identify which version
of the format should be used to interpret them. When writing a file
with to_file
, the format version can be specified, or by default,
the latest version is used. When reading a file with from_file
, by
default, the format version of the actual file is used. If a specific
format version is expected or required, that version can be specified,
and a RuntimeError
will be raised if a different format version is
encountered.
The versions are always in the format major.minor
and are stored as
strings (e.g. '1.0'
, '1.5'
, 2.0
).
The minor format will increase if a non-breaking change is made, so that a script compatible with a lower minor version will also work with files that have a higher minor version. E.g. a script designed to work with v1.0 will also work with v1.5. The reverse is not necessarily true: a script designed to work with v1.5 may not work with v1.0 files.
The major format will increase if a breaking change is made. This means that a script designed to work with v1.5 will likely not work with v2.0 files, and vice versa.
File Data¶
The file data is saved in HDF5 datasets, and the specific data format depends on the LArPix+HDF5 version.
Version 2.4 description¶
For version 2.4, chip configuration objects can be saved to the 'configs'
dataset. For compatibility reasons, only 1 type of asic configuration can be
stored per hdf5 file.
The configs
dataset
contains a timestamped entry for each chip config that has been logged
Shape:
(N,)
,N >= 0
Attrs:
asic_version
(U25
/unicode string): a global asic version to use with this dataset, depending on the asic version a different length datatype is used.Datatype: a compound datatype (called “structured type” in h5py/numpy). Keys/fields:
timestamp
(u8
/unsigned long): a DAQ-system unix timestamp associated with when the config was written to the fileio_group
(u1
/unsigned byte): an id associated with the high-level io group associated with this network nodeio_channel
(u1
/unsigned byte): the id associated with the mid-level io channel associated with this network nodechip_id
(u1
/unsigned byte): the id associated with the low-level asicregisters
((239,)u1
: unsigned byte): the value at each of the asic’s register addresses
Version 2.3 description¶
For version 2.3, the receipt_timestamp
(u4
/unsigned int) field
has been added to the packets
dataset. Additionally, “empty” fields
for data/config write/config read/test packets are now filled according
to the bit content of the packet. E.g. a row representing a config write
packet will still fill the dataword
column as though the packet was
a data packet. Finally, there are some moderate performance improvements.
Version 2.2 description¶
For version 2.2, two new packet types have been introduced to store
data contained in SyncPacket
and TriggerPacket
, with type
being 6 and 7 respectively.
SyncPacket
will fill the timestamp
field with the 32-bit
timestamp associated with the sync packet, the dataword
field
with the value of clk_source
(if applicable), ant the
trigger_type
field with the sync type (an unsigned byte).
TriggerPacket
will fill the timestamp
field with the 32-bit
timestamp associated with the trigger packet and the trigger_type
field with the trigger bits (an unsigned byte).
Version 2.1 description¶
For version 2.1, there are two dataset: packets
and messages
.
The packets
dataset
contains a list of all of the packets sent and received during a
particular time interval.
Shape:
(N,)
,N >= 0
Datatype: a compound datatype (called “structured type” in h5py/numpy). Not all fields are relevant for each packet. Unused fields are set to a default value of 0 or the empty string. Keys/fields:
io_group
(u1
/unsigned byte): an id associated with the high-level io group associated with this packetio_channel
(u1
/unsigned byte): the id associated with the mid-level io channel associated with this packetpacket_type
(u1
/unsigned byte): the packet type code, which can be interpreted according to the map stored in the ‘packets’ attribute ‘packet_types’chip_id
(u1
/unsigned byte): the LArPix chip idparity
(u1
/unsigned byte): the packet parity bit (0 or 1)valid_parity
(u1
/unsigned byte): 1 if the packet parity is valid (odd), 0 if it is invaliddownstream_marker
(u1
/unsigned byte): a marker to indicate the hydra io network direction for this packetchannel_id
(u1
/unsigned byte): the ASIC channeltimestamp
(u8
/unsigned 8-byte long int): the timestamp associated with the packet. Caution: this field does “triple duty” as both the ASIC timestamp in data packets (type
== 0), as the global timestamp in timestamp packets (type
== 4), and as the message timestamp in message packets (type
== 5).first_packet
(u1
/unsigned byte): indicates if this is the packet recieved in a trigger burst (v2.1 or newer only)dataword
(u1
/unsigned byte): the ADC data wordtrigger_type
(u1
/unsigned byte): the trigger type assciated with this packetlocal_fifo` (``u1
/unsigned byte): 1 if the channel FIFO is >50% full, 3 if the channel FIFO is 100% fullshared_fifo
(u1
/unsigned byte): 1 if the chip FIFO is >50% full, 3 if the channel FIFO is 100% fullregister_address
(u1
/unsigned byte): the configuration register indexregister_data
(u1
/unsigned byte): the configuration register valuedirection
(u1
/unsigned byte): 0 if packet was sent to ASICs, 1 if packet was received from ASICs.local_fifo_events
(u1
/unsigned byte): number of packets in the channel FIFO (only valid if FIFO diagnostics are enabled)shared_fifo_events
(u2
/unsigned byte): number of packets in the chip FIFO (only valid if FIFO diagnostics are enabled)counter
(u4
/unsigned 4-byte int): the message index (only valid for message type packets)fifo_diagnostics_enabled
(u1
/unsigned byte): flag for when fifo diagnostics are enabled (1 if enabled, 0 if not)Packet types lookup: the
packets
dataset has an attribute'packet_types'
which contains the following lookup table for packets:0: 'data', 1: 'test', 2: 'config write', 3: 'config read', 4: 'timestamp', 5: 'message',
The messages
dataset has the full messages referred to by message
packets in the packets
dataset.
Shape:
(N,)
,N >= 0
Datatype: a compound datatype with fields:
message
(S64
/64-character string): the messagetimestamp
(u8
/unsigned 8-byte long int): the timestamp associated with the messageindex
(u4
/unsigned 4-byte int): the message index, which should be equal to the row index in themessages
dataset
Version 1.0 description¶
For version 1.0, there are two dataset: packets
and messages
.
The packets
dataset
contains a list of all of the packets sent and received during a
particular time interval.
Shape:
(N,)
,N >= 0
Datatype: a compound datatype (called “structured type” in h5py/numpy). Not all fields are relevant for each packet. Unused fields are set to a default value of 0 or the empty string. Keys/fields:
chip_key
(S32
/32-character string): the chip key identifying the ASIC associated with this packettype
(u1
/unsigned byte): the packet type code, which can be interpreted according to the map stored in the raw_packet attribute ‘packet_types’chipid
(u1
/unsigned byte): the LArPix chipidparity
(u1
/unsigned byte): the packet parity bit (0 or 1)valid_parity
(u1
/unsigned byte): 1 if the packet parity is valid (odd), 0 if it is invalidchannel
(u1
/unsigned byte): the ASIC channeltimestamp
(u8
/unsigned 8-byte long int): the timestamp associated with the packet. Caution: this field does “triple duty” as both the ASIC timestamp in data packets (type
== 0), as the global timestamp in timestamp packets (type
== 4), and as the message timestamp in message packets (type
== 5).adc_counts
(u1
/unsigned byte): the ADC data wordfifo_half
(u1
/unsigned byte): 1 if the FIFO half full flag is present, 0 otherwise.fifo_full
(u1
/unsigned byte): 1 if the FIFO full flag is present, 0 otherwise.register
(u1
/unsigned byte): the configuration register indexvalue
(u1
/unsigned byte): the configuration register valuecounter
(u4
/unsigned 4-byte int): the test counter value, or the message index. Caution: this field does “double duty” as the counter for test packets (type
== 1) and as the message index for message packets (type
== 5).direction
(u1
/unsigned byte): 0 if packet was sent to ASICs, 1 if packet was received from ASICs.Packet types lookup: the
packets
dataset has an attribute'packet_types'
which contains the following lookup table for packets:0: 'data', 1: 'test', 2: 'config write', 3: 'config read', 4: 'timestamp', 5: 'message',
The messages
dataset has the full messages referred to by message
packets in the packets
dataset.
Shape:
(N,)
,N >= 0
Datatype: a compound datatype with fields:
message
(S64
/64-character string): the messagetimestamp
(u8
/unsigned 8-byte long int): the timestamp associated with the messageindex
(u4
/unsigned 4-byte int): the message index, which should be equal to the row index in themessages
dataset
Examples¶
Plot a histogram of ADC counts (selecting packet type to be data packets only)
>>> import matplotlib.pyplot as plt
>>> import h5py
>>> f = h5py.File('output.h5', 'r')
>>> packets = f['packets']
>>> plt.hist(packets['adc_counts'][packets['type'] == 0])
>>> plt.show()
Load the first 10 packets in a file into Packet objects and print any MessagePacket packets to the console
>>> from larpix.format.hdf5format import from_file
>>> from larpix.larpix import MessagePacket
>>> result = from_file('output.h5', end=10)
>>> for packet in result['packets']:
... if isinstance(packet, MessagePacket):
... print(packet)
-
larpix.format.hdf5format.
latest_version
= '2.4'¶ The most recent / up-to-date LArPix+HDF5 format version
-
larpix.format.hdf5format.
dtypes
¶ The dtype specification used in the HDF5 files.
Structure:
{version: {dset_name: [structured dtype fields]}}
-
larpix.format.hdf5format.
dtype_property_index_lookup
¶ A map between attribute name and “column index” in the structured dtypes.
Structure:
{version: {dset_name: {field_name: index}}}
-
larpix.format.hdf5format.
to_file
(filename, packet_list=None, chip_list=None, mode='a', version=None, workers=None)[source]¶ Save the given packets to the given file.
This method can be used to update an existing file.
Parameters: - filename – the name of the file to save to
- packet_list – any iterable of objects of type
Packet
,TimestampPacket
,SyncPacket
, orTriggerPacket
. - chip_list – any iterable of objects of type
Chip
. - mode – optional, the “file mode” to open the data file
(default:
'a'
) - version – optional, the LArPix+HDF5 format version to use. If
writing a new file and version is unspecified or
None
, the latest version will be used. If writing an existing file and version is unspecified orNone
, the existing file’s version will be used. If writing an existing file and version is specified and does not exactly match the existing file’s version, aRuntimeError
will be raised. (default:None
)
-
larpix.format.hdf5format.
from_file
(filename, version=None, start=None, end=None, load_configs=None)[source]¶ Read the data from the given file into LArPix Packet objects.
Parameters: - filename – the name of the file to read
- version – the format version. Specify this parameter to
enforce a version check. When a specific version such as
'1.5'
is specified, aRuntimeError
will be raised if the stored format version number is not an exact match. If a version is prefixed with'~'
such as'~1.5'
, aRuntimeError
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 orNone
, will use the stored format version. - start – the index of the first row to read
- end – the index after the last row to read (same semantics as
Python
range
) - load_configs – a flag to indicate if configs should be fetched from file, a
value of
True
will load all configs and a value of typeslice
will load the specified subset.
Returns packet_dict: a dict with keys
'packets'
containing a list of packet objects;'configs'
containing a list of chip objects; and'created'
,'modified'
, and'version'
, containing the file metadata.
LArPix raw HDF5 Format¶
This is an alternative to the ``larpix.format.hdf5format``format that allows for much faster conversion to file at the expense of human readability.
To use, pass a list of bytestring messages into the to_rawfile()
method:
msgs = [b'this is a test message', b'this is a different message']
to_rawfile('raw.h5', msgs)
To access the data in the file, the inverse method from_rawfile()
is used:
rd = from_rawfile('raw.h5')
rd['msgs'] # [b'this is a test message', b'this is a different message']
Messages may be recieved from multiple io_group
sources, in this case, a
per-message header with io_group
can be specified as a list of integers of
the same length as the msgs
list and passed into the file at the same time:
msgs = [b'message from 1', b'message from 2']
io_groups = [1, 2]
to_rawfile('raw.h5', msgs=msgs, msg_headers={'io_groups': io_groups})
rd = from_rawfile('raw.h5')
rd['msgs'] # [b'message from 1', b'message from 2']
rd['msg_headers']['io_groups'] # [1, 2]
File versioning¶
Some version validation is included with the file format through
the version
and io_version
file metadata. When creating a new file, a
file format version can be provided with the version
keyword argument as
a string formatted 'major.minor'
:
to_rawfile('raw_v0_0.h5', version='0.0')
Subsequent writes to the file will only occur if the requested file version and the existing file versions are compatible. Incompatiblity occurs if there is a difference in the major version number or the minor version number is less than the requested file version:
to_rawfile('raw_v0_0.h5', version='0.1') # fails due to minor version incompatibility
to_rawfile('raw_v0_0.h5', version='1.0') # fails due to major version incompatibility
By default, the most recent file version is used.
On the file read side, a version number can be requested and the file will be parsed assuming a specific version:
from_rawfile('raw_v0_0.h5', version='0.0')
from_rawfile('raw_v0_0.h5', version='0.1') # fails due to minor version incompatiblity
from_rawfile('raw_v0_0.h5', version='1.0') # fails due to major version compatibility
The io_version
optional metadata marks the version of the io message format
that was used to encode the message bytestrings. If present as a keyword
argument when writing to the file, an AssertionError
will be raised if
the io version is incompatible with the existing one stored in metadata:
to_rawfile('raw_io_v0_0.h5', io_version='0.0')
to_rawfile('raw_io_v0_0.h5', io_version='0.1') # fails due to minor version incompatibility
to_rawfile('raw_io_v0_0.h5', io_version='1.0') # fails due to major version incompatibility
A similar mechanism occurs when requesting an io version when reading from the file:
from_rawfile('raw_io_v0_0.h5', io_version='0.1') # fails due to minor version incompatibility
from_rawfile('raw_io_v0_0.h5', io_version='1.0') # fails due to major version
from_rawfile('raw_io_v0_0.h5', io_version='0.0')
I think it is worthwhile to further clarify the io_version
and the file
version
, as this might be confusing. In particular, you might be asking,
“What io versions are compatible with what file versions?” The rawhdf5format
is a way of wrapping raw binary data into a format that only requires HDF5 to
parse. The file version represents this HDF5 structuring (the hdf5 dataset
formats, file metadata, what message header data is available). Whereas the
io_version
represents the formatting of the binary data that the file
contains. So the answer to that question is: all file versions are compatible
with all io versions.
Converting to other file types¶
This format was created with a specific application in mind - provide a
temporary but fast file format for PACMAN messages. When used in this
case, to convert to the standard larpix.format.hdf5format
:
from larpix.format.pacman_msg_format import parse
from larpix.format.hdf5format import to_file
rd = from_rawfile('raw.h5')
pkts = list()
for io_group,msg in zip(rd['msg_headers']['io_groups'], rd['msgs']):
pkts.extend(parse(msg, io_group=io_group))
to_file('new_filename.h5', packet_list=pkts)
but as always, the most efficient means of accessing the data is to operate on the data itself, rather than converting between types.
Metadata (v0.0)¶
The group meta
contains file metadata stored as attributes:
created
:float
, unix timestamp since the 1970 epoch in seconds indicating when file was first createdmodified
:float
, unix timestamp since the 1970 epoch in seconds indicating when the file was last written toversion
:str
, file version, formatted as'major.minor'
io_version
:str
, optional version for message bytestring encoding, formatted as'major.minor'
Datasets (v0.0)¶
The hdf5 format contains two datasets msgs
and msg_headers
:
msgs
: shape(N,)
; variable-lengthuint1
arrays encoding each message bytestring
msg_headers
: shape(N,)
; numpy structured array with fields:
'io_group'
:uint1
representing theio_group
associated with each message
-
larpix.format.rawhdf5format.
latest_version
= '0.0'¶ Most up-to-date raw larpix hdf5 format version.
-
larpix.format.rawhdf5format.
dataset_dtypes
¶ Description of the datasets and their dtypes used in each version of the raw larpix hdf5 format.
Structured as
dataset_dtypes['<version>']['<dataset>'] = <dtype>
.
-
larpix.format.rawhdf5format.
to_rawfile
(filename, msgs=None, version=None, msg_headers=None, io_version=None)[source]¶ Write a list of bytestring messages to an hdf5 file. If the file exists, the messages will appended to the end of the dataset.
Parameters: - filename – desired filename for the file to write or update
- msgs – iterable of variable-length bytestrings to write to the file. If
None
specified, will only create file and update metadata. - version – a string of major.minor version desired. If
None
specified, will use the latest file format version (if new file) or version in file (if updating an existing file). - msg_headers – a dict of iterables to associate with each message header. Iterables must be same length as
msgs
. IfNone
specified, will use a default value of0
for each message. Keys are dtype field names specified indataset_dtypes[version]['msg_headers'].names
- io_version – optional metadata to associate with file corresponding to the io format version of the bytestring messages. Throws
RuntimeError
if version incompatibility encountered in an existing file.
-
larpix.format.rawhdf5format.
len_rawfile
(filename, attempts=1)[source]¶ Check the total number of messages in a file
Parameters: - filename – filename to check
- attempts – a parameter only relevant if file is being actively written to by another process, specifies number of refreshes to try if a synchronized state between the datasets is not achieved. A value less than
0
busy blocks until a synchronized state is achieved. A value greater than0
tries to achieve synchronization a max ofattempts
before throwing aRuntimeError
. And a value of0
does not attempt to synchronize (not recommended).
Returns: int
number of messages in file
-
larpix.format.rawhdf5format.
from_rawfile
(filename, start=None, end=None, version=None, io_version=None, msg_headers_only=False, mask=None, attempts=1)[source]¶ Read a chunk of bytestring messages from an existing file
Parameters: - filename – filename to read bytestrings from
- start – index for the start position when reading from the file (default =
None
). If a value less than 0 is specified, index is relative to the end of the file. IfNone
is specified, data is read from the start of the file. If amask
is specified, does nothing. - end – index for the end position when reading from the file (default =
None
). If a value less than 0 is specified, index is relative to the end of the file. IfNone
is specified, data is read until the end of the file. If amask
is specified, does nothing. - version – required version compatibility. If
None
specified, uses the version stored in the file metadata - io_version – required io version compatibility. If
None
specified, does not check theio_version
file metadata - msg_headers_only – optional flag to only load header information and not message bytestrings (
'msgs'
value in return dict will beNone
ifmsg_headers_only=True
) - mask – boolean mask alternative to
start
andend
chunk specification to indicate specific file rows to load. Boolean 1D array with length equal tolen_rawfile(filename)
- attempts – a parameter only relevant if file is being actively written to by another process, specifies number of refreshes to try if a synchronized state between the datasets is not achieved. A value less than
0
busy blocks until a synchronized state is achieved. A value greater than0
tries to achieve synchronization a max ofattempts
before throwing aRuntimeError
. And a value of0
does not attempt to synchronize (not recommended).
Returns: dict
with keys for'created'
,'modified'
,'version'
, and'io_version'
metadata, along with'msgs'
(alist
of bytestring messages) and'msg_headers'
(a dict with message header field name:list
of message header field data, 1 per message)
LArPix interface message formats¶
The module contains all the message formats used by systems that interface with larpix-control:
- dataserver_message_encode: convert from packets to the data server messaging format
- dataserver_message_decode: convert from data server messaging format to packets
-
larpix.format.message_format.
dataserver_message_encode
(packets, version=(1, 0))[source]¶ Convert a list of packets to larpix dataserver messages. DAQ board messages are formatted using 8-byte words with the first word being a header word describing the interpretation of other words in the message. These messages are formatted as follows
- All messages:
byte[0] = major version
byte[1] = minor version
byte[2] = message type
b'D'
: LArPix datab'T'
: Timestamp datab'H'
: Heartbeat
- LArPix heartbeat messages:
- byte[3] =
b'H'
- byte[4] =
b'B'
- byte[5:7] are unused
- byte[3] =
- LArPix data messages:
- byte[3] = io channel
- bytes[4:7] are unused
- bytes[8:] = raw LArPix 7-byte UART words ending in a single null byte
- Timestamp data messages:
- byte[3:7] are unused
- byte[8:14] = 7-byte Unix timestamp
- byte[15] is unused
Example usage:
from larpix.larpix import Packet, Key packet = Packet() packet.chip_key = Key('1-1-1') msgs = datserver_message_encode([packet]) msgs[0] # b'\x01\x00D\x01\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00' msgs[0][:8] # header msgs[0][8:] # data words
Parameters: - packets – list of
larpix.Packet
objects - version – optional, encode a message in specified version format,
tuple
of major, minor numbers
Returns: list of bytestream messages, 1 for each packet
-
larpix.format.message_format.
dataserver_message_decode
(msgs, version=(1, 0), **kwargs)[source]¶ 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'
Parameters: - msgs – list of bytestream messages each starting with a single 8-byte header word, followed by N 8-byte data words
- version – optional, message version to validate against,
tuple
of major, minor version numbers
Returns: list of
larpix.Packet
andlarpix.TimestampPacket
objects
PACMAN interface message format¶
A python interface to the pacman ZMQ message format.
The pacman ZMQ messages are a raw bytestring with two components: a short header and N words. It’s a bit cumbersome to work with bytestrings in data (and keep track of endianness / etc), so this module allows you to translate between native python objects and the pacman message bytestring.
To import this module:
import larpix.format.pacman_msg_format as pacman_msg_fmt
Access to the message content is provided by the parse_msg(msg)
method which
takes a single pacman message bytestring as an argument, e.g.:
msg = b'!-----P---------------' # a simple ping response data = pacman_msg_fmt.parse_msg(msg) # (('REP',123456,1), [('PONG')]) msg = b'D-----D------datadata' # a simple data message data = pacman_msg_fmt.parse_msg(msg) # (('DATA',123456,1), [('DATA',1,1234,b'datadata')])
The creation of messages can be performed with the inverse method,
format_msg(msg_type, msg_words)
. Here, the msg_type
is one of 'DATA'
,
'REQ'
, or 'REP'
, and msg_words
is a list
of tuples indicating the word
type (index 0) and the word data (index 1, 2, …). Word types are specified
by strings that can be found in the word_type_table
. The necessary fields
(and primitive types) for the word data is described in the word_fmt_table
.
E.g.:
data = ('REP', [('PONG')]) # simple ping response msg = pacman_msg_fmt.format_msg(*data) # b'!----P' data = ('DATA', [('DATA',1,1234,b'datadata')]) msg = pacman_msg_fmt.format_msg(*data) # b'D----Ddatadata'
To facilitate translating to/from larpix-control
packet objects, you can use
the format(pkts, msg_type)
and parse(msg, io_group=None)
methods. E.g.:
packet = Packet_v2() packet.io_channel = 1 msg = pacman_msg_fmt.format([packet]) # b'?----D' packets = pacman_msg_fmt.parse(msg, io_group=1) # [Packet_v2(b'')] packets[0].io_group # 1
Note that no io_group
data is contained within a pacman message. This means
that when formatting messages, packets’ io_group
field is ignored, and when
parsing messages, an io_group
value needs to be specified at the time of
parsing.
-
larpix.format.pacman_msg_format.
latest_version
= '0.0'¶ Most up-to-date message format version.
-
larpix.format.pacman_msg_format.
format_header
(msg_type, msg_words)[source]¶ Generates a header-formatted bytestring of message type
msg_type
and withmsg_words
specified words
-
larpix.format.pacman_msg_format.
format_word
(msg_type, word_type, *data)[source]¶ Generates a word-formatted bytestring of word type specified by the
msg_type
andword_type
. The data contained within the word should be passed in as additional positional arguments in the order that they appear in the word (least significant byte first). E.g. for a data word:data_word = format_word('DATA','DATA',<io_channel>,<receipt_timestamp>,<data_word_content>)
-
larpix.format.pacman_msg_format.
parse_header
(msg)[source]¶ Returns a tuple of the data contained in the header:
(<msg type>, <msg time>, <msg words>)
-
larpix.format.pacman_msg_format.
parse_word
(msg_type, word)[source]¶ Returns a tuple of data contained in word (little endian), first item is always the word type
-
larpix.format.pacman_msg_format.
format_msg
(msg_type, msg_words)[source]¶ msg_words
should be a list of tuples that can be unpacked and passed intoformat_word
-
larpix.format.pacman_msg_format.
parse_msg
(msg)[source]¶ returns a tuple of:
(<header data>, [<word 0 data>, ...])
-
larpix.format.pacman_msg_format.
format
(packets, msg_type='REQ', ts_pacman=0)[source]¶ Converts larpix packets into a single PACMAN message. The message header is automatically generated.
Note:: For request messages, this method only formats
Packet_v2
objects. For data messages, this method only formatsPacket_v2
,SyncPacket
, andTriggerPacket
objects.
-
larpix.format.pacman_msg_format.
parse
(msg, io_group=None)[source]¶ Converts a PACMAN message into larpix packets
The header is parsed into a
TimestampPacket
, data words are parsed intoPacket_v2
objects, trigger words are parsed intoTriggerPacket
objects, and sync words are parsed intoSyncPacket
objects.