Lucipy Synchronous Client
API refererence
An Synchronous Hybrid Controller Python Client for REDAC/LUCIDAC
This is a minimal python client, making simple things simple. That means things like device managament is capable of the python REPL without headache, following the KISS principle.
This client implementation does not feature strong typing, dataclasses, asynchronous functions. Instead, it implements a blocking API and tries to mimic the way how the Model-1 Hybrid Controller interface worked (the one in https://github.com/anabrid/pyanalog/).
This is a single file implementation focussing on portability and minimal dependencies. If you have pyserial installed, it will be used, otherwise this also runs fine without.
- class lucipy.synchc.tcpsocket(host, port, auto_reconnect=True)[source]
A socket with readline support
- class lucipy.synchc.serialsocket(device)[source]
Uses pyserial to connect to directly attached device
- class lucipy.synchc.jsonlines(actual_socket)[source]
Middleware that speaks dictionaries at front and JSON at back
- lucipy.synchc.endpoint2socket(endpoint_url: Endpoint | str) tcpsocket | serialsocket[source]
Provides the appropriate socket for a given endpoint
- class lucipy.synchc.LUCIDAC(endpoint_url=None, auto_reconnect=True, register_methods=True)[source]
This kind of class is known as HybridController in other codes. It serves as primary entry point for the lucipy code.
The constructor has a variety of variants how to be called:
- Parameters:
endpoint_url –
If no endpoint (either as string or Endpoint class instance) is provided, will lookup the environment variable
LUCIDAC_ENDPOINT.If neither an endpoint nor the environment variable is set, autodetection is applied and the first connection is chosen. Note that if no LUCIDAC is attached via USB serial, the zeroconf detection will require a few hundred milliseconds, depending on your network.
auto_reconnect – Whether reconnect in case of los connection
register_methods – Register typical message types exposed by the server as methods for this class. This allows to call
hc.foo(bar)instead ofhc.query("foo", bar).
- req_id
Eth Mac address of Microcontroller, required for the circuit entity hierarchy
- hc_mac
Storage for stateful preparation of runs.
- run_config
Storage for stateful preparation of runs.
- register_methods(commands, memoizable=[], overwrite=False)[source]
register method shorthands. Typically this method is only used by __init__.
- static determine_idal_ic_time_from_k0s(mIntConfig)[source]
Given a MIntBlock configuration, which looks like
[{k:1000,ic:...},{k:10000,ic:...}...], determines the ideal ic time, in nanoseconds
- set_config(config)[source]
config being something like
dict("/U": ..., "/C": ...), i.e. the entities for a single cluster. There is only one cluster in LUCIDAC.Warning
This also determines the ideal IC time if that has not been set before (either manually or in a previous run).
- set_op_time(*, ns=0, us=0, ms=0)[source]
Sets OP-Time with clear units. Returns computed value, which is just the sum of all arguments.
Consider the limitations reported in
start_run().Note that this function signature is somewhat comparable to python builtin datetime.timedelta, however Python’s timedelta has only microseconds resolution which is not as highly-resolved as in LUCIDAC.
- Parameters:
ns – nanoseconds
us – microseconds
ms – milliseconds
- set_daq(*, num_channels=0, sample_op=True, sample_op_end=True, sample_rate=500000)[source]
- Parameters:
num_channels – Data aquisition specific - number of channels to sample. Between 0 (no data aquisition) and 8 (all channels)
sample_op – Sample a first point exactly when optime starts
sample_op_end – Sample a last point exactly when optime ends
sample_rate – Number of samples requested over the overall optime (TODO: check if this descrption is correct)
- set_run(*, halt_on_external_trigger=False, halt_on_overload=True, ic_time=None, op_time=None)[source]
- Parameters:
halt_on_external_trigger – Whether halt the run if external input triggers
halt_on_overload – Whether halt the run if overload occurs during computation
ic_time – Request time to load initial conditions, in nanoseconds. This time depends on the k0 factors. However, it is rarely neccessary to tune this parameter, once useful values have been used. If not set, a value derived from the (first time in object lifetime) configuration set will be used.
op_time – Request time for simulation, in nanoseconds. This is the most important option for this method. Note that by a current limitation in the hardware, only op_times < 1sec are supported.
- class lucipy.synchc.LUCIGroup(master: LUCIDAC, *minions: LUCIDAC)[source]
Group of LUCIDACs in a master/minion setup. Usage is like
>>> gru = LUCIDAC("tcp://foo") >>> kevin = LUCIDAC("tcp://bar") >>> bob = LUCIDAC("tcp://baz") >>> group = LUCIGroup(gru, kevin, bob) >>> group.set_circuit(...) >>> group.start_run() ...