New in version 0.2.

LiberTEM-live has support for all DECTRIS detectors that support the SIMPLON API, including QUADRO and ARINA.

Hardware and Software Requirements

You should have LiberTEM-live installed on a computer that has a fast (10Gbit+) connection to the DECTRIS DCU (detector control unit). The exact requirements on this computer depend on the computation you want to run and the framerate you want to run it at. For reference, a 10-core system was sufficient for live processing using the QUADRO at full speed; for ARINA, we used a 24-core AMD EPYC.

We have tested on both Linux and Windows. If you have a choice, Linux should be preferred since it achieved good performance more consistently during our tests.

Usage examples

This section shortly gives examples how to connect LiberTEM-live to a DECTRIS DCU. Depending on you setup, you may want to actively control the detector parameters, synchronization and triggering, which we call active mode, or you may just want to listen for ongoing acquisitions, and start processing once the detector is armed and triggered, which we call the passive mode.

See the DECTRIS reference section for a description of the acquisition parameters.

Common to both active and passive mode is the initialization, creating a LiveContext and connecting to the DCU:

from libertem.viz.bqp import BQLive2DPlot
from libertem_live.api import LiveContext
from libertem.udf.sum import SumUDF

ctx = LiveContext(plot_class=BQLive2DPlot)

# connect to the DECTRIS DCU, and set up a shared memory area:
conn = ctx.make_connection('dectris').open(

Active mode

In active mode, the acquisition is controlled actively from the same Python script or notebook that also controls the processing with LiberTEM-live. That means it will set detector settings, arm the detector and has the possibility to integrate with microscope APIs to trigger the scan.

from libertem_live.api import Hooks

class MyHooks(Hooks):
    def on_ready_for_data(self, env):
        You can trigger the scan here, if you have a microscope control API
        height, width =
        microscope.trigger_scan(width, height, dwelltime=10e-6)

# prepare for acquisition, setting up scan parameters etc.
aq = ctx.make_acquisition(
    nav_shape=(128, 128),

# run one or more UDFs on the live data stream:
ctx.run_udf(dataset=aq, udf=SumUDF())

Passive mode

In passive mode, LiberTEM-live only controls a minimal set of detector parameters. It enables streaming mode, and makes sure headers are sent with the right detail level. Other detector parameters are supposed to be set from the outside, for example using vendor software. Instead of arming the detector, we wait for the detector to be armed, and then start receiving and processing data.

# NOTE: this is the part that is usually done by an external software,
# but we include it here to have a running example:
ec = conn.get_api_client()

# If the timeout is hit, pending_aq is None.
# In a real situation, make sure to test for this,
# for example by looping until a pending acquisition
pending_aq = conn.wait_for_acquisition(timeout=10.0)

# prepare for acquisition
# note that we still have to set the nav_shape here, because
# we don't get this from the detector - it's controlled by
# the scan engine or the microscope.
aq = ctx.make_acquisition(
    nav_shape=(128, 128),

# run one or more UDFs on the live data stream:
ctx.run_udf(dataset=aq, udf=SumUDF())

Implementation notes

The receiving code is written in Rust with Python bindings, and is available in the LiberTEM-dectris package, in the LiberTEM-rs repository. This includes development tools, for example for capturing dumps of the raw stream of zeromq messages, and tools for inspecting and manipulating such dumps. There is also a command-line tool installed with LiberTEM-live, called libertem-live-dectris-sim, which can replay these dumps and effectively simulate a DECTRIS detector.

If you are encountering errors while using our DECTRIS support, you can enable logging of low-level events by setting the environment variable LIBERTEM_DECTRIS_LOG_LEVEL to WARN, DEBUG or even TRACE. The latter can output a huge amount of messages, so it is not recommended to be used from a jupyter notebook.