{ "info": { "author": "Peter Madigan and Sam Kohn", "author_email": "pmadigan@lbl.gov", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Science/Research", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3" ], "description": "# larpix-control\n\nControl the LArPix chip\n\n[![Documentation Status](https://readthedocs.org/projects/larpix-control/badge/?version=stable)](https://larpix-control.readthedocs.io/en/stable/?badge=stable)\n[![Build Status](https://travis-ci.com/larpix/larpix-control.svg?branch=master)](https://travis-ci.com/larpix/larpix-control)\n\n## Setup and installation\n\nThis code is intended to work on both Python 2.7+ and Python 3.6+.\n\nInstall larpix-control from pip with\n\n```\npip install larpix-control\n```\n\nTo return your namespace to the pre-larpix state, just\nrun `pip uninstall larpix-control`. If you'd prefer to download the code\nyourself, you can. Just run `pip install .` from the root directory of\nthe repository.\n\n### Tests\n\nYou can run tests to convince yourself that the software works as\nexpected. After `pip install`ing this package, you can run the tests\nfrom the repository root directory with the simple command `pytest`.\n\nYou can read the tests to see examples of how to call all of the common\nfunctions.\n\n## File structure\n\nThe larpix package contains:\n```\nlarpix\n|-- larpix\n|-- io\n| |-- fakeio\n| |-- serialport\n| `-- zmq_io\n|-- logger\n| |-- h5_logger\n| `-- stdout_logger\n|-- quickstart\n|-- timestamp\n|-- bitarrayhelper\n|-- serial_helpers\n| |-- analyzers\n| |-- dataformatter\n| |-- dataloader\n| `-- datalogger\n`-- configs\n |-- chip\n | |-- csa_bypass.json\n | |-- default.json\n | |-- physics.json\n | `-- quiet.json\n `-- controller\n |-- pcb-10_chip_info.json\n |-- pcb-1_chip_info.json\n |-- pcb-2_chip_info.json\n |-- pcb-3_chip_info.json\n |-- pcb-4_chip_info.json\n |-- pcb-5_chip_info.json\n `-- pcb-6_chip_info.json\n```\n\n## Minimal working example\n\nSo you're not a tutorials kind of person. Here's a minimal working\nexample for you to play around with:\n\n```python\n>>> from larpix.larpix import Controller, Packet\n>>> from larpix.io.fakeio import FakeIO\n>>> from larpix.logger.stdout_logger import StdoutLogger\n>>> controller = Controller()\n>>> controller.io = FakeIO()\n>>> controller.logger = StdoutLogger(buffer_length=0)\n>>> controller.logger.enable()\n>>> chip1 = controller.add_chip('1-1-1') # (access key)\n>>> chip1.config.global_threshold = 25\n>>> controller.write_configuration('1-1-1', 25) # chip key, register 25\n[ Config write | Chip key: '1-1-1' | Chip: 1 | Register: 25 | Value: 16 | Parity: 1 (valid: True) ]\n>>> packet = Packet(b'\\x04\\x14\\x80\\xc4\\x03\\xf2 ')\n>>> packet_bytes = packet.bytes()\n>>> pretend_input = ([packet], packet_bytes)\n>>> controller.io.queue.append(pretend_input)\n>>> controller.run(0.05, 'test run')\n>>> print(controller.reads[0])\n[ Data | Chip key: None | Chip: 1 | Channel: 5 | Timestamp: 123456 | ADC data: 120 | FIFO Half: False | FIFO Full: False | Parity: 1 (valid: True) ]\n```\n\n## Tutorial\n\nThis tutorial runs through how to use all of the main functionality of\nlarpix-control.\n\nTo access the package contents, use one of the two following `import`\nstatements:\n\n```python\nimport larpix # use the larpix namespace\n# or ...\nfrom larpix.larpix import * # import all core larpix classes into the current namespace\n```\n\nThe rest of the tutorial will assume you've imported all of the core larpix\nclasses via a ``from larpix.larpix import *`` command.\n\n### Create a LArPix Controller\n\nThe LArPix Controller translates high-level ideas like \"read\nconfiguration register 10\" into communications to and from LArPix ASICs,\nand interprets the received data into a usable format.\n\nController objects communicate with LArPix ASICs via an IO interface.\nCurrently available IO interfaces are ``SerialPort``, ``ZMQ_IO`` and\n``FakeIO``. We'll work with ``FakeIO`` in this tutorial, but all the\ncode will still work with properly initialized versions of the other IO\ninterfaces.\n\nSet things up with\n\n```python\nfrom larpix.io.fakeio import FakeIO\nfrom larpix.logger.stdout_logger import StdoutLogger\ncontroller = Controller()\ncontroller.io = FakeIO()\ncontroller.logger = StdoutLogger(buffer_length=0)\ncontroller.logger.enable()\n```\n\nThe ``FakeIO`` object imitates a real IO interface for testing purposes.\nIt directs its output to stdout (i.e. it prints the output), and it\ntakes its input from a manually-updated queue. At the end of each\nrelevant section of the tutorial will be code for adding the expected\noutput to the queue. You'll have to refill the queue each time you run\nthe code.\n\nSimilarly, the ``StdoutLogger`` mimics the real logger interface for testing. It\nprints nicely formatted records of read / write commands to stdout every\n``buffer_length`` packets. The logger interface requires enabling the\nlogger before messages will be stored. Before ending the python session, every\nlogger should be disabled to flush any remaining packets stored in the buffer.\n\n### Set up LArPix Chips\n\nChip objects represent actual LArPix ASICs. For each ASIC you want to\ncommunicate with, create a LArPix Chip object and add it to the\nController.\n\n```python\nchipid = 5\nchip_key = '1-1-5'\nchip5 = controller.add_chip(chip_key)\nchip5 = controller.get_chip(chip_key)\n```\n\nThe `chip_key` field specifies the necessary information for the `controller.io`\nobject to route packets to/from the chip. The details of how this key maps to a\nphysical chip is implemented separately for each `larpix.io` class.\n\nThe key itself consists of 3 1-byte integer values that represent the 3\nlow-level layers in larpix readout:\n\n - the io group: this is the highest layer and represents a control system that\n communicates with multiple IO channels\n\n - the io channel: this is the middle layer and represents a single MOSI/MISO\n pair\n\n - the chip id: this is the lowest layer and represents a single chip on a\n MOSI/MISO network\n\nIf you want to interact with chip keys directly, you can instantiate one using\na valid keystring (three 1-byte integers separated by dashes, e.g. ``'1-1-1'``).\nPlease note that the ids of 0 and 255 are reserved for special functions.\n\n```python\nfrom larpix.larpix import Key\nexample_key = Key('1-2-3')\n```\n\nYou can grab relevant information from the key via a number of useful methods\nand attributes:\n\n```python\nexample_key.io_group # 1\nexample_key.io_channel # 2\nexample_key.chip_id # 3\nexample_key.to_dict() # returns a dict with the above keys / values\n```\n\nIf you are using a ``Key`` in a script, we recommend that you generate the keys\nvia the ``Key.from_dict()`` method which will protect against updates to the key\nformatting.\n\nYou can read the docs to learn more about ``Key`` functionality.\n\n### Adjust the configuration of the LArPix Chips\n\nEach Chip object manages its own configuration in software.\nConfigurations can be adjusted by name using attributes of the Chip's\nconfiguration:\n\n```python\nchip5.config.global_threshold = 35 # entire register = 1 number\nchip5.config.periodic_reset = 1 # one bit as part of a register\nchip5.config.channel_mask[20] = 1 # one bit per channel\n```\n\nValues are validated, and invalid values will raise exceptions.\n\nNote: Changing the configuration of a Chip object does *not* change the\nconfiguration on the ASIC.\n\nOnce the configuration is set, the new values must be sent to the LArPix\nASICs. There is an appropriate Controller method for that:\n\n```python\ncontroller.write_configuration(chip_key) # send all registers\ncontroller.write_configuration(chip_key, 32) # send only register 32\ncontroller.write_configuration(chip_key, [32, 50]) # send registers 32 and 50\n```\n\nRegister addresses can be looked up using the configuration object:\n\n```python\nglobal_threshold_reg = chip5.config.global_threshold_address\n```\n\nFor configurations which extend over multiple registers, the relevant\nattribute will end in ``_addresses``. Certain configurations share a\nsingle register, whose attribute has all of the names in it. View the\ndocumentation or source code to find the name to look up. (Or look at\nthe LArPix data sheet.)\n\n### Reading the configuration from LArPix ASICs\n\nThe current configuration state of the LArPix ASICs can be requested by\nsending out \"configuration read\" requests using the Controller:\n\n```python\ncontroller.read_configuration(chip_key)\n```\n\nThe same variations to read only certain registers are implemented for\nreading as for writing.\n\nThe responses from the LArPix ASICs are stored for inspection. See the\nsection on \"Inspecting received data\" for more.\n\nFakeIO queue code:\n\n```python\npackets = chip5.get_configuration_packets(Packet.CONFIG_READ_PACKET)\nbytestream = b'bytes for the config read packets'\ncontroller.io.queue.append((packets, bytestream))\n```\n\n### Receiving data from LArPix ASICs\n\nWhen it is first initialized, the LArPix Controller ignores and discards\nall data that it receives from LArPix. The Controller must be activated\nby calling ``start_listening()``. All received data will then be\naccumulated in an implementation-dependent queue or buffer, depending\non the IO interface used. To read the data from the buffer, call the\ncontroller's ``read()`` method, which returns both the raw bytestream\nreceived as well as a list of LArPix Packet objects which have been\nextracted from the bytestream. To stop listening for new data, call\n``stop_listening()``. Finally, to store the data in the controller\nobject, call the ``store_packets`` method. All together:\n\n```python\ncontroller.start_listening()\n# Data arrives...\npackets, bytestream = controller.read()\n# More data arrives...\npackets2, bytestream2 = controller.read()\ncontroller.stop_listening()\nmessage = 'First data arrived!'\nmessage2 = 'More data arrived!'\ncontroller.store_packets(packets, bytestream, message)\ncontroller.store_packets(packets, bytestream2, message2)\n```\n\nThere is a common pattern for reading data, namely to start listening,\nthen check in periodically for new data, and then after a certain amount\nof time has passed, stop listening and store all the data as one\ncollection. The method ``run(timelimit, message)`` accomplishes just this.\n\n```python\nduration = 10 # seconds\nmessage = '10-second data run'\ncontroller.run(duration, message)\n```\n\nFakeIO queue code for the first code block:\n\n```python\npackets = [Packet()] * 40\nbytestream = b'bytes from the first set of packets'\ncontroller.io.queue.append((packets, bytestream))\npackets2 = [Packet()] * 30\nbytestream2 = b'bytes from the second set of packets'\ncontroller.io.queue.append((packets2, bytestream2))\n```\n\nfakeIO queue code for the second code block:\n\n```python\npackets = [Packet()] * 5\nbytestream = b'[bytes from read #%d] '\nfor i in range(100):\n controller.io.queue.append((packets, bytestream%i))\n```\n\n### Inspecting received data\n\nOnce data is stored in the controller, it is available in the ``reads``\nattribute as a list of all data runs. Each element of the list is a\nPacketCollection object, which functions like a list of Packet objects\neach representing one LArPix packet.\n\nPacketCollection objects can be indexed like a list:\n\n```python\nrun1 = controller.reads[0]\nfirst_packet = run1[0] # Packet object\nfirst_ten_packets = run1[0:10] # smaller PacketCollection object\n\nfirst_packet_bits = run1[0, 'bits'] # string representation of bits in packet\nfirst_ten_packet_bits = run1[0:10, 'bits'] # list of strings\n```\n\nPacketCollections can be printed to display the contents of the Packets\nthey contain. To prevent endless scrolling, only the first ten and last ten\npackets are displayed, and the number of omitted packets is noted. To\nview the omitted packets, use a slice around the area of interest.\n\n```python\nprint(run1) # prints the contents of the packets\nprint(run1[10:30]) # prints 20 packets from the middle of the run\n```\n\nIn interactive Python, returned objects are not printed, but rather\ntheir \"representation\" is printed (cf. the ``__repr__`` method). The\nrepresentation of PacketCollections is a listing of the number of\npackets, the \"read id\" (a.k.a. the run number), and the message\nassociated with the PacketCollection when it was created.\n\n### Individual LArPix Packets\n\nLArPix Packet objects represent individual LArPix UART packets. They\nhave attributes which can be used to inspect or modify the contents of\nthe packet.\n\n```python\npacket = run1[0]\n# all packets\npacket.packet_type # unique in that it gives the bits representation\npacket.chipid # all other properties return Python numbers\npacket.chip_key # key for association to a unique chip\npacket.parity_bit_value\n# data packets\npacket.channel_id\npacket.dataword\npacket.timestamp\npacket.fifo_half_flag # 1 or 0\npacket.fifo_full_flag # 1 or 0\n# config packets\npacket.register_address\npacket.register_data\n# test packets\npacket.test_counter\n```\n\nInternally, packets are represented as an array of bits, and the\ndifferent attributes use Python \"properties\" to seamlessly convert\nbetween the bits representation and a more intuitive integer\nrepresentation. The bits representation can be inspected with the\n``bits`` attribute.\n\nPacket objects do not restrict you from adjusting an attribute for an\ninappropriate packet type. For example, you can create a data packet and\nthen set ``packet.register_address = 5``. This will adjust the packet\nbits corresponding to a configuration packet's \"register\\_address\"\nregion, which is probably not what you want for your data packet.\n\nPackets have a parity bit which enforces odd parity, i.e. the sum of\nall the individual bits in a packet must be an odd number. The parity\nbit can be accessed as above using the ``parity_bit_value`` attribute.\nThe correct parity bit can be computed using ``compute_parity()``,\nand the validity of a packet's parity can be checked using\n``has_valid_parity()``. When constructing a new packet, the correct\nparity bit can be assigned using ``assign_parity()``.\n\nIndividual packets can be printed to show a human-readable\ninterpretation of the packet contents. The printed version adjusts its\noutput based on the packet type, so a data packet will show the data\nword, timestamp, etc., while a configuration packet will show the register\naddress and register data.\n\nLike with PacketCollections, Packets also have a \"representation\" view\nbased on the bytes that make up the packet. This can be useful for\ncreating new packets since a Packet's representation is also a vaild\ncall to the Packet constructor. So the output from an interactive\nsession can be copied as input or into a script to create the same\npacket.\n\n### Logging communications with LArPix ASICs using the HDF5Logger\n\nTo create a permanent record of communications with the LArPix ASICs, an\n`HDF5Logger` is used. To create a new logger\n\n```python\nfrom larpix.logger.h5_logger import HDF5Logger\ncontroller.logger = HDF5Logger(filename=None, buffer_length=10000) # a filename of None uses the default filename formatting\ncontroller.logger.enable() # starts tracking all communications\n```\n\nYou can also initialize and enable the logger in one call by passing the\n``enabled`` keyword argument (which defaults to ``False``):\n\n```\ncontroller.logger = HDF5Logger(filename=None, enabled=True)\n```\n\nNow whenever you send or receive packets, they will be captured by the logger\nand added to the logger's buffer. Once `buffer_length` packets have been\ncaptured the packets will be written out to the file. You can force the logger\nto dump the currently held packets at any time using `HDF5Logger.flush()`\n\n```python\ncontroller.verify_configuration()\ncontroller.logger.flush()\n```\n\nIn the event that you want to temporarily stop tracking communications,\nthe `disable` and `enable` commands do exactly what you think they might.\n\n```python\ncontroller.logger.disable() # stop tracking\n# any communication here is ignored\ncontroller.logger.enable() # start tracking again\ncontroller.logger.is_enabled() # returns True if tracking\n```\n\nOnce you have finished your tests, be sure to disable the logger. If you do not,\nyou will lose any data still in the buffer of the logger object. We strongly recommend\nwrapping logger code with a `try, except` statement if you can. Any remaining\npackets in the buffer are flushed to the file upon disabling.\n\n```python\ncontroller.logger.disable()\n```\n\n### Viewing data from the HDF5Logger\n\nThe ``HDF5Logger`` uses a format called LArPix+HDF5v1.0 that is specified in\nthe ``larpix.format.hdf5format`` module (and\n[documentation](https://larpix-control.readthedocs.io/en/stable/)\nstarting in v2.3.0). That module contains a ``to_file`` method which is\nused internally by ``HDF5Logger`` and a ``from_file`` method that you\ncan use to load the file contents back into LArPix Control. The\nLArPix+HDF5 format is a \"plain HDF5\" format that can be inspected with\n``h5py`` or any language's HDF5 binding.\n\nTo open the HDF5 file from python\n\n```python\nimport h5py\ndatafile = h5py.File('')\n```\n\nWithin the datafile there is one group (`'_header'`) and two datasets\n(``'packets'`` and ``'messages'``). The header group contains some useful meta information about\nwhen the datafile was created and the file format version number, stored as\nattributes.\n\n```python\nlist(datafile.keys()) # ['_header', 'messages', 'packets']\nlist(datafile['_header'].attrs) # ['created', 'modified', version']\n```\n\nThe packets are stored sequentially as a `numpy` mixed-type arrays within the\nrows of the HDF5 dataset. The columns refer to the element of the numpy mixed\ntype array. The specifics of the data type and entries are set by the\n``larpix.format.hdf5format.dtype`` object - see the larpix-control docs for more information.\nYou can inspect a packet as a tuple simply by accessing its respective position within the\nHDF5 dataset.\n\n```python\nraw_value = datafile['packets'][0] # e.g. (b'0-246', 3, 246, 1, 1, -1, -1, -1, -1, -1, -1, 0, 0)\nraw_values = datafile['packets'][-100:] # last 100 packets in file\n```\n\nIf you want to make use of `numpy`'s mixed type arrays, you can convert the\nraw values to the proper encoding by retrieving it as a list (of length\n1, for example) via\n\n```python\npacket_repr = raw_values[0:1] # list with one element\npacket_repr['chip_key'] # chip key for packet, e.g. b'1-1-246'\npacket_repr['adc_counts'] # list of ADC values for each packet\npacket_repr.dtype # description of data type (with names of each column)\n```\n\nYou can also view entire \"columns\" of data:\n\n```python\n# all packets' ADC counts, including non-data packets\nraw_values['adc_counts']\n# Select based on data type using a numpy bool / \"mask\" array:\nraw_values['adc_counts'][raw_values['type'] == 0] # all data packets' ADC counts\n```\n\n``h5py`` and ``numpy`` optimize the retrieval of data so you can read\ncertain columns or rows without loading the entire data file into memory.\n\nDon't forget to close the file when you are done. (Not necessary in\ninteractive python sessions if you are about to quit.)\n\n```python\ndatafile.close()\n```\n\n## Running with a Bern DAQ board\n\nSince you have completed the tutorial with the `FakeIO` class, you are now ready\nto interface with some LArPix ASICs. If you have a Bern DAQ v2-3 setup you can\nfollow along with the rest of the tutorial.\n\nBefore you can configure the system, you will need to generate a configuration\nfile for the ZMQ_IO or MultiZMQ_IO interface. This provides the mapping from\nchip keys to physical devices. In the case of the ZMQ interface, it maps\nio group #s to the IP address of the DAQ board. A number of example\nconfigurations are provided in the installation under\n``larpix/configs/io/.json``, which may work for your purposes. We\nrecommend reading the docs about how to create one of these configuration files.\nBy default the system looks for configuration in the pwd, before looking for the\ninstallation files. If you only have one DAQ board on your network, likely\nyou will load the ``io/daq-srv<#>.json`` configuration.\n\nWith the DAQ system up and running\n```python\n>>> from larpix.larpix import Controller\n>>> from larpix.io.zmq_io import ZMQ_IO\n>>> controller = Controller()\n>>> controller.io = ZMQ_IO(config_filepath='')\n>>> controller.load('controller/pcb-<#>_chip_info.json')\n>>> controller.io.ping()\n>>> for key,chip in controller.chips.items():\n... chip.config.load('chip/quiet.json')\n... print(key, chip.config)\n... controller.write_configuration(key)\n>>> controller.run(1,'checking the data rate')\n>>> controller.reads[-1]\n\n```\nThis should give you a quiet state with no data packets. Occasionally, there can\nbe a few packets left in one of the system buffers (LArPix, FPGA, DAQ server). A\nsecond run command should return without any new packets.\n\nIf you are using the v1.5 anode, you may need to reconfigure the miso/mosi mapping (since the miso/mosi pair for a daisy chain is not necessarily on a single channel). To do this, pass a `miso_map` or `mosi_map` to the `ZMQ_IO` object on initialization:\n```python\n>>> controller.io = ZMQ_IO(config_filepath='', miso_map={2:1}) # relabels packets received on channel 2 as packets from channel 1\n```\n\n### Check configurations\nIf you are still receiving data, you can check that the hardware chip configuration\nmatch the software chip configurations with\n```python\n>>> controller.verify_configuration()\n(True, {})\n```\nIf the configuration read packets don't match the software chip configuration, this\nwill return\n```python\n>>> controller.verify_configuration()\n(False, {: (, ), ...})\n```\nMissing packets will show up as\n```python\n>>> controller.verify_configuration()\n(False, {: (, None), ...})\n```\nIf your configurations match, and you still receive data then you are likely seeing\nsome pickup on the sensor from the environment -- *good luck!*\n\n### Enable a single channel\n```python\n>>> chip_key = '1-1-3'\n>>> controller.disable() # mask off all channel\n>>> controller.enable(chip_key, [0]) # enable channel 0 of chip\n```\n\n### Set the global threshold of a chip\n```python\n>>> controller.chips[chip_key].config.global_threshold = 40\n>>> controller.write_configuration(chip_key)\n>>> controller.verify_configuration(chip_key)\n(True, {})\n```\n\n### Inject a pulse into a specific channel\n```python\n>>> controller.enable_testpulse(chip_key, [0]) # connect channel 0 to the test pulse circuit and initialize the internal DAC to 255\n>>> controller.issue_testpulse(chip_key, 10) # inject a pulse of size 10DAC by stepping down the DAC\n\n>>> controller.disable_testpulse(chip_key) # disconnect test pulse circuit from all channels on chip\n```\nYou will need to periodically reset the DAC to 255, otherwise you will receive a\n`ValueError` once the DAC reaches the minimum specified value.\n```python\n>>> controller.enable_testpulse(chip_key, [0], start_dac=255)\n>>> controller.issue_testpulse(chip_key, 50, min_dac=200) # the min_dac keyword sets the lower bound for the DAC (useful to avoid non-linearities at around 70-80DAC)\n\n>>> controller.issue_testpulse(chip_key, 50, min_dac=200)\nValueError: Minimum DAC exceeded\n>>> controller.enable_testpulse(chip_key, [0], start_dac=255)\n>>> controller.issue_testpulse(chip_key, 50, min_dac=200)\n\n\n```\n\n### Enable the analog monitor on a channel\n```python\n>>> controller.enable_analog_monitor(chip_key, 0) # drive buffer output of channel 0 out on analog monitor line\n>>> controller.disable_analog_monitor(chip_key) # disable the analog monitor on chip\n```\nWhile the software enforces that only one channel per chip is being driven out on\nthe analog monitor, you must disable the analog monitor if moving between chips.\n\n\n## Miscellaneous implementation details\n\n### Endian-ness\n\nWe use the convention that the LSB is sent out first and read in first.\nThe location of the LSB in arrays and lists changes from object to\nobject based on the conventions of the other packages we interact with.\n\nIn particular, pyserial sends out index 0 first, so for `bytes` objects,\nindex 0 will generally have the LSB. On the other hand, bitstrings\ntreats the _last_ index as the LSB, which is also how numbers are\nusually displayed on screen, e.g. `0100` in binary means 4 not 2. So for\n`BitArray` and `Bits` objects, the LSB will generally be last.\n\nNote that this combination leads to the slightly awkward convention that\nthe least significant bit of a bytestring is the *last bit* of the\n*first byte*. For example, if bits[15:0] of a packet are\n`0000 0010 0000 0001` ( = 0x0201 = 513), then the bytes will be sent out as\n`b'\\x01\\x02'`.\n\n### The Configuration object\n\nThe `Configuration` object represents all of the options in the LArPix\nconfiguration register. Each row in the configuration table in the LArPix datasheet\nhas a corresponding attribute in the `Configuration` object. Per-channel\nattributes are stored in a list, and all other attributes are stored as\na simple integer. (This includes everything from single bits to values\nsuch as \"reset cycles,\" which spans 3 bytes.)\n\n`Configuration` objects also have some helper methods for enabling and\ndisabling per-channel settings (such as `csa_testpulse_enable` or\n`channel_mask`). The relevant methods are listed here and should be\nprefixed with either `enable_` or `disable_`:\n\n - `channels` enables/disables the `channel_mask` register\n - `external_trigger` enables/disables the `external_trigger_mask`\n register\n - `testpulse` enables/disables the `csa_testpulse_enable` register\n - `analog_monitor` enables/disables the `csa_monitor_select` register\n\nMost of these methods accept an optional list of channels to enable or\ndisable (and with no list specified acts on all channels). The exception\nis `enable_analog_monitor` (and its `disable` counterpart): the `enable`\nmethod requires a particular channel to be specified, and the `disable`\nmethod does not require any argument at all. This is because at most one\nchannel is allowed to have the analog monitor enabled.\n\nThe machinery of the `Configuration` object ensures that each value is\nconverted to the appropriate set of bits when it comes time to send\nactual commands to the physical chip. Although this is not transparent\nto you as a user of this library, you might want to know that two sets of\nconfiguration options are always sent together in the same configuration\npacket:\n\n - `csa_gain`, `csa_bypass`, and `internal_bypass` are combined into a\n single byte, so even though they have their own attributes, they must\n be written to the physical chip together\n\n - `test_mode`, `cross_trigger_mode`, `periodic_reset`, and\n `fifo_diagnostic` work the same way\n\nSimilarly, all of the per-channel options (except for the pixel trim\nthresholds) are sent in 4 groups of 8 channels.\n\nConfigurations can be loaded by importing `larpix.configs` and running\nthe `load` function. This function searches for a configuration with the\ngiven filename relative to the current directory before searching the\n\"system\" location (secretly it's in the larpix/configs/ folder). This is\nsimilar to `#include \"header.h\"` behavior in C.\n\nConfigurations can be saved by calling `chip.config.write` with the\ndesired filename.\n\nOnce the Chip object has been configured, the configuration must be sent\nto the physical chip.\n\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/larpix/larpix-control", "keywords": "dune physics", "license": "", "maintainer": "", "maintainer_email": "", "name": "larpix-control", "package_url": "https://pypi.org/project/larpix-control/", "platform": "", "project_url": "https://pypi.org/project/larpix-control/", "project_urls": { "Homepage": "https://github.com/larpix/larpix-control" }, "release_url": "https://pypi.org/project/larpix-control/2.3.0/", "requires_dist": [ "pyserial (~=3.4)", "pytest (~=4.2)", "larpix-geometry (==0.3.0)", "bitarray (~=0.8)", "pyzmq (~=16.0)", "sphinx-rtd-theme (~=0.4.2)", "numpy (~=1.16)", "h5py (~=2.9)", "bidict (~=0.18.0)" ], "requires_python": "", "summary": "Control the LArPix chip", "version": "2.3.0" }, "last_serial": 5575182, "releases": { "0.3.0.dev0": [ { "comment_text": "", "digests": { "md5": "56763f48ceb590fab0e5708a63f13269", "sha256": "ca4c3edd762c05300e6fa50059c4393a8ff566d83ba3a3fa82bb0d848165422b" }, "downloads": -1, "filename": "larpix_control-0.3.0.dev0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "56763f48ceb590fab0e5708a63f13269", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 14531, "upload_time": "2017-10-19T07:34:48", "url": "https://files.pythonhosted.org/packages/27/dd/b130258b0f15d85e5b4a0e8e953f1c4e61d1fcac3283c8099b29876109c6/larpix_control-0.3.0.dev0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1a1b9c2f1d034cc749c24981ed0eb8b4", "sha256": "790d9bc78a2431ec30adb385932a3fd0ae8bd540e7656569aa5fcf413054473c" }, "downloads": -1, "filename": "larpix-control-0.3.0.dev0.tar.gz", "has_sig": false, "md5_digest": "1a1b9c2f1d034cc749c24981ed0eb8b4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13857, "upload_time": "2017-10-19T07:34:51", "url": "https://files.pythonhosted.org/packages/4d/11/4252d928592c66910822493fcd380eeef82924bc616efc9ef9f7db300431/larpix-control-0.3.0.dev0.tar.gz" } ], "0.3.1.dev0": [ { "comment_text": "", "digests": { "md5": "94288c6b238caac10a958bd92476f627", "sha256": "5c25657aa65e6624c7f5020b09409e860da8334853508dcf16f007d3cdeed5d6" }, "downloads": -1, "filename": "larpix_control-0.3.1.dev0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "94288c6b238caac10a958bd92476f627", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 16352, "upload_time": "2017-10-19T07:34:50", "url": "https://files.pythonhosted.org/packages/d3/4b/038afcaaf4e56932daed54d02228917ac1eae6385d1fdb2bc454eb22b00d/larpix_control-0.3.1.dev0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "90f4ef4e9ff3f1a180f5ebe5eb58ac7b", "sha256": "0bb6a5a740f451d1752e21dbe9efc8a946f46a4a2bfb162459341f03d9a3aac2" }, "downloads": -1, "filename": "larpix-control-0.3.1.dev0.tar.gz", "has_sig": false, "md5_digest": "90f4ef4e9ff3f1a180f5ebe5eb58ac7b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17086, "upload_time": "2017-10-19T07:34:53", "url": "https://files.pythonhosted.org/packages/36/67/3369e299914c57610162497063b784f7a7b67c4537f97a9b8f10913068ba/larpix-control-0.3.1.dev0.tar.gz" } ], "0.4.1.dev1": [ { "comment_text": "", "digests": { "md5": "10b0717dbf265745ae69c4ca71434448", "sha256": "6c950deadf4223a9949cc63b9ac93c84990790f058b806737e830c44ce1c1277" }, "downloads": -1, "filename": "larpix_control-0.4.1.dev1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "10b0717dbf265745ae69c4ca71434448", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 21257, "upload_time": "2017-10-27T23:49:23", "url": "https://files.pythonhosted.org/packages/21/06/1ad0ac0602b69407d33321c0882850b649504ee849c975d88cd007e73539/larpix_control-0.4.1.dev1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7762464be777f8f6cda41b41996c56cb", "sha256": "db0d73600bf89d92139a92e9c58b3fad66df4bd56c93a2944c630b8a1ccfb4cd" }, "downloads": -1, "filename": "larpix-control-0.4.1.dev1.tar.gz", "has_sig": false, "md5_digest": "7762464be777f8f6cda41b41996c56cb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23684, "upload_time": "2017-10-27T23:49:26", "url": "https://files.pythonhosted.org/packages/f6/40/baf15118f2b514e1aba29d01f0fc22d42c8e04b212579555476c1126879f/larpix-control-0.4.1.dev1.tar.gz" } ], "0.4.1.dev2": [ { "comment_text": "", "digests": { "md5": "8bd942869bedb52489f885c3517a7672", "sha256": "a2c2d7a90d2d5965c9139b6738b91f4badb25474bcd3b02ce0d9d9e8da298dbb" }, "downloads": -1, "filename": "larpix_control-0.4.1.dev2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "8bd942869bedb52489f885c3517a7672", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 21300, "upload_time": "2017-10-28T00:20:57", "url": "https://files.pythonhosted.org/packages/df/d6/a07a22dc9763eff5a436bd0b29cb01cf1f00cc1da19492763b1ad3c2790b/larpix_control-0.4.1.dev2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "48023698ecc9cd8f1d19e570ce2b4f70", "sha256": "d751cbfb01af198d813affe189151df9f590c7de3e3696d5f049d71d3689900c" }, "downloads": -1, "filename": "larpix-control-0.4.1.dev2.tar.gz", "has_sig": false, "md5_digest": "48023698ecc9cd8f1d19e570ce2b4f70", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23733, "upload_time": "2017-10-28T00:21:00", "url": "https://files.pythonhosted.org/packages/32/82/4a4111759bfb2309d186dec1b8a61d8a844df67d5b0036e46e63b32265d7/larpix-control-0.4.1.dev2.tar.gz" } ], "0.4.1.dev3": [ { "comment_text": "", "digests": { "md5": "2738179295207cfce17ff39ba4d06707", "sha256": "9c52f586a598207c5542d401a58355fcb8dd71e2d6add6330c0af04db6a826e7" }, "downloads": -1, "filename": "larpix_control-0.4.1.dev3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "2738179295207cfce17ff39ba4d06707", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 21342, "upload_time": "2017-11-01T18:39:43", "url": "https://files.pythonhosted.org/packages/81/e8/14d6f501cac48b9d30260900dec8551d973120c4f32b5584ed9ae5466995/larpix_control-0.4.1.dev3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "edc947cb2ab49b5269166d879ec55fcd", "sha256": "f902660697fee053e8d008e9b1ff8b66d728c9ad812138bf89dcfcbfa8d0ee76" }, "downloads": -1, "filename": "larpix-control-0.4.1.dev3.tar.gz", "has_sig": false, "md5_digest": "edc947cb2ab49b5269166d879ec55fcd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23750, "upload_time": "2017-11-01T18:39:46", "url": "https://files.pythonhosted.org/packages/05/00/a1754819da1d1ae2a0adc08c813c7809ab2958721a4da4f070a57bf8238c/larpix-control-0.4.1.dev3.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "37738c7c395a364512787301b48542eb", "sha256": "06dc741ac0570e5d03fd427ccfde583ec39d00382ddf9fe51b4503c28fdd847d" }, "downloads": -1, "filename": "larpix_control-0.5.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "37738c7c395a364512787301b48542eb", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 27213, "upload_time": "2017-11-14T18:34:45", "url": "https://files.pythonhosted.org/packages/4f/a7/3fa00b88a17ad95f891e6103a16cc8613a13d4a50c1341465aab69960d12/larpix_control-0.5.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e187cbe342e4a2b0aed1a83be939f995", "sha256": "4bbdac2321762b9bf6f17efc935fcec07a9c0f951b0e8a4debf005fda2c54b08" }, "downloads": -1, "filename": "larpix-control-0.5.0.tar.gz", "has_sig": false, "md5_digest": "e187cbe342e4a2b0aed1a83be939f995", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29045, "upload_time": "2017-11-14T18:34:50", "url": "https://files.pythonhosted.org/packages/ce/7e/5aa3fcca67d3b5d57f53e79149e08eef088e70465046bed2444a45e12ab3/larpix-control-0.5.0.tar.gz" } ], "0.5.1": [ { "comment_text": "", "digests": { "md5": "cb74806355492f35ab2f34c9a8fa15d4", "sha256": "28f28bd4ea2e2e445f66173568bdcb120d31279ed55945079ed28643eddb0d85" }, "downloads": -1, "filename": "larpix_control-0.5.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "cb74806355492f35ab2f34c9a8fa15d4", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 27773, "upload_time": "2017-11-14T22:37:26", "url": "https://files.pythonhosted.org/packages/37/6b/0b5ecd8b775b3b64ccaca59539bc3cef847686ddc6e7e0ec03a8d260ed74/larpix_control-0.5.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ffe17040b61fcedfdefff4018639971e", "sha256": "1f9d83e8e63b36d9bf7e30016b34e19964c5e15cdfe233f4017bdeb1bc750d00" }, "downloads": -1, "filename": "larpix-control-0.5.1.tar.gz", "has_sig": false, "md5_digest": "ffe17040b61fcedfdefff4018639971e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29396, "upload_time": "2017-11-14T22:37:32", "url": "https://files.pythonhosted.org/packages/9b/e6/cccd0a164df63e2fba03bdb65b6619fc477ce9ee5402d4cea05ebef3321e/larpix-control-0.5.1.tar.gz" } ], "0.5.2": [ { "comment_text": "", "digests": { "md5": "69c97f9c08a27d42658cb266f205fd99", "sha256": "4fc7b217cf752bc1f00a8d39e906849b9bdceb82288f18453d10fc01aaf7679d" }, "downloads": -1, "filename": "larpix_control-0.5.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "69c97f9c08a27d42658cb266f205fd99", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 27772, "upload_time": "2017-11-14T22:43:27", "url": "https://files.pythonhosted.org/packages/c6/ce/bc3b8e8a164ad46fa3f3ff2f3f598da70413e8ed35824f491a89592aef10/larpix_control-0.5.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "70574add7ba5ed1b3e59e8688fc862a8", "sha256": "d8ed43c608c5547626212f01ab52590025437744ff16764ea30474fb4f8d7330" }, "downloads": -1, "filename": "larpix-control-0.5.2.tar.gz", "has_sig": false, "md5_digest": "70574add7ba5ed1b3e59e8688fc862a8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29691, "upload_time": "2017-11-14T22:43:33", "url": "https://files.pythonhosted.org/packages/dd/a4/c0847b88b9866a249e676278c4c400e9a0794297da1354a6beb565484c32/larpix-control-0.5.2.tar.gz" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "1ff770a67ede9e024388556a5ac33966", "sha256": "5019d9e0dd53131029e97bb36d70eb1ca25b319b0af2f6b6131bf132ba75ebbd" }, "downloads": -1, "filename": "larpix_control-0.6.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "1ff770a67ede9e024388556a5ac33966", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 28327, "upload_time": "2017-11-15T22:42:40", "url": "https://files.pythonhosted.org/packages/93/b0/b0296fdd128930f9776e3295d8b0084dc999b4a11a340de0a997712a0639/larpix_control-0.6.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e00ff9ef2abbccee6aaf77024c157c02", "sha256": "575d2a997e366e9b28af0e83531b5e0da0ee58192ce3de313f1559f57ec4e02a" }, "downloads": -1, "filename": "larpix-control-0.6.0.tar.gz", "has_sig": false, "md5_digest": "e00ff9ef2abbccee6aaf77024c157c02", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30234, "upload_time": "2017-11-15T22:42:46", "url": "https://files.pythonhosted.org/packages/4c/94/1380177da21b450f81d60252b033091c8d89954cc96124c10333e31da1e1/larpix-control-0.6.0.tar.gz" } ], "2.2.1": [ { "comment_text": "", "digests": { "md5": "e769672a6a3577763cb12b584e8b0d21", "sha256": "eacff42b91038ea334cea7d7c1b2b73bb163ddd80ddc5eac12a57ffe3511e122" }, "downloads": -1, "filename": "larpix_control-2.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "e769672a6a3577763cb12b584e8b0d21", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 54151, "upload_time": "2019-06-11T00:25:41", "url": "https://files.pythonhosted.org/packages/96/ac/4508431f6daaa27ae324574d17883aeb567d6dea9cff3ecc503c991fee27/larpix_control-2.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "cd73b3d093bd9fa87d9c5c6d3eb929ac", "sha256": "edd3b4ee1db3ad30b159ad4a8bcfe848af6f99baacac30015f57dc5bf9d23133" }, "downloads": -1, "filename": "larpix-control-2.2.1.tar.gz", "has_sig": false, "md5_digest": "cd73b3d093bd9fa87d9c5c6d3eb929ac", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 59701, "upload_time": "2019-06-11T00:25:42", "url": "https://files.pythonhosted.org/packages/32/55/b1823995099b787fb97d1ffecb36c91fb969e3fac51514ab45de17c0effb/larpix-control-2.2.1.tar.gz" } ], "2.2.1rc2": [ { "comment_text": "", "digests": { "md5": "57de56cf2ad2e9e3f9ddee6fa119643a", "sha256": "fd21027e9c10c11b0aa560bb5ca106f8ba37c47280247f61a46922c7b03318b1" }, "downloads": -1, "filename": "larpix_control-2.2.1rc2-py3-none-any.whl", "has_sig": false, "md5_digest": "57de56cf2ad2e9e3f9ddee6fa119643a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 69832, "upload_time": "2019-06-04T00:03:01", "url": "https://files.pythonhosted.org/packages/ef/b2/06cf0af1e763547f44b7bf8adea58ff42c4a6517366fe863a8c85125195a/larpix_control-2.2.1rc2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6f6ec2840efc656687b153008fb73294", "sha256": "567573f1268ccdcc727d919b9fca3c78b06c11b1dff7b9fb94db3217cdc4c395" }, "downloads": -1, "filename": "larpix-control-2.2.1rc2.tar.gz", "has_sig": false, "md5_digest": "6f6ec2840efc656687b153008fb73294", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 62795, "upload_time": "2019-06-04T00:03:03", "url": "https://files.pythonhosted.org/packages/72/bb/d7e4bd2c6cc74abc12e7b261e56fdd84633289f4e24815831bdecf54cdaa/larpix-control-2.2.1rc2.tar.gz" } ], "2.2.1rc3": [ { "comment_text": "", "digests": { "md5": "48c38cf42f53afeb41b64ea23797b3ad", "sha256": "76be45aa5d3d94084dacbe37c8a4a084886cca670eeac7786792965f42df8d61" }, "downloads": -1, "filename": "larpix_control-2.2.1rc3-py3-none-any.whl", "has_sig": false, "md5_digest": "48c38cf42f53afeb41b64ea23797b3ad", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 54174, "upload_time": "2019-06-10T23:39:37", "url": "https://files.pythonhosted.org/packages/40/83/231943d2f2c34251abd16a0e90d619742a306bd4b5f084ec3e283036c0f8/larpix_control-2.2.1rc3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d4020ab8641c7cdb380bb7ccfca31e84", "sha256": "f0079b04fa150f523dbcf4ccb5e13a891caba9931375e255b298c98dfa8236a3" }, "downloads": -1, "filename": "larpix-control-2.2.1rc3.tar.gz", "has_sig": false, "md5_digest": "d4020ab8641c7cdb380bb7ccfca31e84", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 59595, "upload_time": "2019-06-10T23:39:38", "url": "https://files.pythonhosted.org/packages/2f/5a/17c9dfd0c4ac85d66055a529898fe89baf2588b9e948ca4105456704008a/larpix-control-2.2.1rc3.tar.gz" } ], "2.3.0": [ { "comment_text": "", "digests": { "md5": "5650fdb3ec9919231a66dfb9853ff892", "sha256": "535921874ca57a17b00290d80eca6ad651251b634cdf193d221e7897b99e381f" }, "downloads": -1, "filename": "larpix_control-2.3.0-py2-none-any.whl", "has_sig": false, "md5_digest": "5650fdb3ec9919231a66dfb9853ff892", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 75356, "upload_time": "2019-07-24T01:25:34", "url": "https://files.pythonhosted.org/packages/11/cf/e672275c0c7422e48f127d10f11df4c62321fa03e2bac3f03532fa861781/larpix_control-2.3.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f7b17a8e1fc8719ecb520974d621529d", "sha256": "fe8edd08169a05dc17566985f9c3bdeb4ef158409ba87c1bf8454d2347558b67" }, "downloads": -1, "filename": "larpix_control-2.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "f7b17a8e1fc8719ecb520974d621529d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 75356, "upload_time": "2019-07-16T23:15:13", "url": "https://files.pythonhosted.org/packages/77/b6/9e52f8fdb7b2a88795fb74f111181ba34ef8cc946dee11a15eaedbc23b62/larpix_control-2.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c1ffa845d7892d15121ff97a674bd23c", "sha256": "e0f71e37a7b999d61886ed159b4c0f77bbec9805e2f8284134d35e703e1b1bac" }, "downloads": -1, "filename": "larpix-control-2.3.0.tar.gz", "has_sig": false, "md5_digest": "c1ffa845d7892d15121ff97a674bd23c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 92433, "upload_time": "2019-07-16T23:15:15", "url": "https://files.pythonhosted.org/packages/4c/12/e22b5b208aec807eace6cb4a6540d2f73937be2dcca299b534baa64f09b5/larpix-control-2.3.0.tar.gz" } ], "2.3.0rc1": [ { "comment_text": "", "digests": { "md5": "0fe9c8b5b62248e8c72fef5431f39edf", "sha256": "ee22727966d08f52899246adf7f0c60d1bd44d5a44f8cc3c36ea9bfdd5522251" }, "downloads": -1, "filename": "larpix_control-2.3.0rc1-py3-none-any.whl", "has_sig": false, "md5_digest": "0fe9c8b5b62248e8c72fef5431f39edf", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 75221, "upload_time": "2019-07-01T19:44:27", "url": "https://files.pythonhosted.org/packages/e3/4a/0cb56b1c07a95925b06362c583dd071fa09de3d96fed33852e2aaeaa6362/larpix_control-2.3.0rc1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "71ae8518d0f5d1622b48f9b0f393d65f", "sha256": "468ab5c946e7bfa30154f5cf8a2874446ea3e6bf25791fb8269551f4836268f0" }, "downloads": -1, "filename": "larpix-control-2.3.0rc1.tar.gz", "has_sig": false, "md5_digest": "71ae8518d0f5d1622b48f9b0f393d65f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 90903, "upload_time": "2019-07-01T19:44:35", "url": "https://files.pythonhosted.org/packages/0d/72/67003859509a90b7f1d1a2da09142b3e8038ead4fe2750b7cc9ce3940114/larpix-control-2.3.0rc1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "5650fdb3ec9919231a66dfb9853ff892", "sha256": "535921874ca57a17b00290d80eca6ad651251b634cdf193d221e7897b99e381f" }, "downloads": -1, "filename": "larpix_control-2.3.0-py2-none-any.whl", "has_sig": false, "md5_digest": "5650fdb3ec9919231a66dfb9853ff892", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 75356, "upload_time": "2019-07-24T01:25:34", "url": "https://files.pythonhosted.org/packages/11/cf/e672275c0c7422e48f127d10f11df4c62321fa03e2bac3f03532fa861781/larpix_control-2.3.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f7b17a8e1fc8719ecb520974d621529d", "sha256": "fe8edd08169a05dc17566985f9c3bdeb4ef158409ba87c1bf8454d2347558b67" }, "downloads": -1, "filename": "larpix_control-2.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "f7b17a8e1fc8719ecb520974d621529d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 75356, "upload_time": "2019-07-16T23:15:13", "url": "https://files.pythonhosted.org/packages/77/b6/9e52f8fdb7b2a88795fb74f111181ba34ef8cc946dee11a15eaedbc23b62/larpix_control-2.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c1ffa845d7892d15121ff97a674bd23c", "sha256": "e0f71e37a7b999d61886ed159b4c0f77bbec9805e2f8284134d35e703e1b1bac" }, "downloads": -1, "filename": "larpix-control-2.3.0.tar.gz", "has_sig": false, "md5_digest": "c1ffa845d7892d15121ff97a674bd23c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 92433, "upload_time": "2019-07-16T23:15:15", "url": "https://files.pythonhosted.org/packages/4c/12/e22b5b208aec807eace6cb4a6540d2f73937be2dcca299b534baa64f09b5/larpix-control-2.3.0.tar.gz" } ] }