Reference

Live Context

class libertem_live.api.LiveContext(executor: JobExecutor | None = None, plot_class: Live2DPlot | None = None)[source]

LiveContext handles the computational resources needed to run UDFs on live data streams. It is the entry point to most interactions with the LiberTEM-live API.

A LiveContext behaves like a libertem.api.Context in most circumstances. Notable differences are that it currently starts an PipelinedExecutor instead of a DaskJobExecutor if no executor is passed in the constructor, and that it can prepare and run acquisitions on top of loading offline datasets.

The docstrings for most functions are inherited from the base class. Most methods, in particular run_udf() and run_udf_iter(), now accept both an acquisition object and a dataset as the dataset parameter.

make_acquisition(*, conn: AsiTpx3DetectorConnection, nav_shape: tuple[int, ...] | None = None, frames_per_partition: int | None = None, controller: AcquisitionController | None = None, pending_aq: PendingAcquisition | None = None, hooks: Hooks | None = None) AsiTpx3Acquisition[source]
make_acquisition(*, conn: DectrisDetectorConnection, nav_shape: tuple[int, ...] | None = None, frames_per_partition: int | None = None, controller: AcquisitionController | None = None, pending_aq: PendingAcquisition | None = None, hooks: Hooks | None = None) DectrisAcquisition
make_acquisition(*, conn: MerlinDetectorConnection, nav_shape: tuple[int, ...] | None = None, frames_per_partition: int | None = None, controller: AcquisitionController | None = None, pending_aq: PendingAcquisition | None = None, hooks: Hooks | None = None) MerlinAcquisition
make_acquisition(*, conn: MemoryConnection, nav_shape: tuple[int, ...] | None = None, frames_per_partition: int | None = None, controller: AcquisitionController | None = None, pending_aq: PendingAcquisition | None = None, hooks: Hooks | None = None) MemoryAcquisition

Create an acquisition object.

Examples

>>> data = np.random.random((23, 42, 51, 67))
>>> ctx = LiveContext()  
>>> with ctx.make_connection('memory').open(data=data) as conn:
...     aq = ctx.make_acquisition(conn=conn)
...     ctx.run_udf(dataset=aq, udf=SumUDF())
{'intensity': ...}
make_connection(detector_type: Literal['asi_tpx3']) AsiTpx3ConnectionBuilder[source]
make_connection(detector_type: Literal['dectris']) DectrisConnectionBuilder
make_connection(detector_type: Literal['merlin']) MerlinConnectionBuilder
make_connection(detector_type: Literal['memory']) MemoryConnectionBuilder

Connect to a detector system.

Parameters:

detector_type – The detector type as a string. Further connection parameters are passed to the open method of the returned builder object.

Examples

>>> data = np.random.random((23, 42, 51, 67))
>>> ctx = LiveContext()  
>>> with ctx.make_connection('memory').open(data=data) as conn:
...     print("connected!")
connected!
prepare_acquisition(detector_type, *args, trigger=None, **kwargs)[source]

This method has been removed, please use make_connection and make_acquisition.

UDFs

We include some utility UDFs in LiberTEM-live that are mostly useful for the live processing use-case:

class libertem_live.udf.monitor.PartitionMonitorUDF(dtype='float32')[source]

Sum up frames in a partition and update result with the latest partition result.

This is useful for live processing as a beam monitor if individual frames contain not enough signal. Partial sums of an offline dataset are more easily accessible with SumUDF with a ROI.

The result is the sum of the partition that was merged last. The end result depends on the merge order.

Parameters:

dtype (numpy.dtype, optional) – Preferred dtype for computation, default ‘float32’. The actual dtype will be determined from this value and the dataset’s dtype using numpy.result_type(). See also Preferred input dtype.

class libertem_live.udf.monitor.SignalMonitorUDF(**kwargs: Any | AuxBufferWrapper)[source]

Return the most recently processed signal space element (frame).

This is useful for live processing as a beam monitor. Individual frames in an offline dataset are more easily accessible with PickUDF.

The result is most likely the last frame of each partition for the individual merge steps. The end result depends on the merge order.

class libertem_live.udf.record.RecordUDF(filename, _is_master=True)[source]

Record input data as NumPy .npy file

Parameters:
  • filename (str or path-like) – Filename where to save. The file will be overwritten if it exists.

  • _is_master (bool) – Internal flag, keep at default value.

Base classes

class libertem_live.detectors.base.connection.DetectorConnection[source]

Base class for detector connections.

close()[source]

Close the connection. It’s important to call this function once you don’t need the connection anymore, as an open connection might interfere with other software using the detector.

If possible, use this object as a context manager instead, using a with-statement.

wait_for_acquisition(timeout: float | None = None) PendingAcquisition | None[source]

Wait for at most timeout seconds for an acquisition to start. This does not perform any triggering itself and expects something external to arm and trigger the acquisition.

Once the detector is armed, this function returns a PendingAcquisition, which can be converted to a full Acquisition object using libertem_live.api.LiveContext.make_acquisition().

The function returns None on timeout.

Parameters:

timeout – Timeout in seconds. If None, wait indefinitely.

class libertem_live.detectors.base.connection.PendingAcquisition[source]

A token object that can be obtained from libertem_live.detectors.base.connection.DetectorConnection.wait_for_acquisition().

Pass this object into libertem_live.api.LiveContext.make_acquisition() to start processing the incoming data stream.

property nav_shape: tuple[int, ...] | None

The concrete nav_shape, if it is known by the detector

property nimages: int

The total number of images that are expected for this acquisition

Hooks

class libertem_live.hooks.DetermineNavShapeEnv(nimages: int, shape_hint: tuple[int, ...] | None)[source]

Parameter object used in on_determine_nav_shape()

nimages: int

The total number of images in the acquisition.

shape_hint: tuple[int, ...] | None

Shape that was passed into make_acquisition(), can contain placeholders, i.e. (-1, 256) or (-1, -1).

class libertem_live.hooks.Hooks[source]

Interface for defining actions to perform in reaction to events. This is setup- and possibly experiment-specific and can, for example, encode how the microscope, scan engine and detector are synchronized.

By implementing methods of this interface, you can “hook into” the lifecycle of an acquisition at different important events.

Each hook method gets a specific environment object as a parameter, that includes all necessary context information from current state of the acquisition.

on_determine_nav_shape(env: DetermineNavShapeEnv) tuple[int, ...] | None[source]

This hook is called to determine the N-D nav shape for the acquisition. This is needed as many detectors only know about the 1D shape, i.e. the number of images to acquire. For some, the controller may be able to determine the nav shape, but for others, this is specific to the setup or experiment.

The user can give a shape hint when creating the acquisition object, for example by passing nav_shape=(-1, 256) to make_acquisition().

If the default behavior is not working as intended, the user can override this method for their specific setup. Example: ask the microscope via its API what the current scan settings are.

Only called in passive mode, as we need a concrete nav_shape as user input in active mode.

Order of operations:

  • If the nav_shape passed into libertem_live.api.LiveContext.make_acquisition() is concrete, i.e. is not None and doesn’t contain any -1 values, use that

  • If this hook is implemented and returns a tuple, use that

  • If the controller for the specific detector type can give us the concrete nav_shape, use that

  • If none of the above succeed, try to make a square out of the number of frames

  • If all above fails, raise a RuntimeError

on_ready_for_data(env: ReadyForDataEnv)[source]

This hook is called whenever we are ready for data, i.e. the detector is armed.

Usually, at this point, the next step is triggering the microscope or scan generator to start a scan.

It is only called in active mode, where we control when the detector is armed - in passive mode, the data is possibly already being received and we don’t control when this happens at all.

class libertem_live.hooks.ReadyForDataEnv(aq: AcquisitionProtocol)[source]

Parameter object used in on_ready_for_data()

aq: AcquisitionProtocol

The acquisition object which will receive the data.