Package: libertem-dectris
LiberTEM-dectris-rsThis is a Python package for efficiently receiving data from DECTRIS detectors
withthe zeromq interface.
The low-level, high-frequency operations are performed in a background thread
implemented in rust, and multiple frames are batched together for further
processing in Python.Usageimportnumpyasnpimportlibertem_dectrisfromlibertem_live.detectors.dectris.DEigerClientimportDEigerClient# trigger acquisition via the REST API, needs `libertem-live`nimages=256*256ec=DEigerClient('localhost',8910)# hostname and port of the DCU REST APIec.setDetectorConfig('ntrigger',1)ec.setDetectorConfig('nimages',1)ec.setDetectorConfig('trigger_mode','exte')ec.setDetectorConfig('ntrigger',nimages)result=ec.sendDetectorCommand('arm')sequence_id=result['sequence id']conn=libertem_dectris.DectrisConnection(uri="tcp://localhost:9999",handle_path="/tmp/dectris_shm",frame_stack_size=32,num_slots=2000,bytes_per_frame=512*512,huge=False,)# as we have armed the detector above, we know the sequence number# that we should expect:# (in other cases, can also call# `conn.start_passive` and `conn.wait_for_arm` to passively wait for# the detector to be armed)conn.start(sequence_id)# any other process can use a `CamClient` to use data# stored in the SHM:cam_client=libertem_dectris.CamClient(conn.get_socket_path())try:whileTrue:# get at most `max_size` frames as a stack# (might get less at the end of the acquisition)stack_handle=conn.get_next_stack(max_size=32)# if the receiver is idle, stack_handle will be None here:ifstack_handleisNone:break# the expected shape and data type:frame_shape=tuple(reversed(stack_handle.get_shape()))dtype=np.dtype(stack_handle.get_pixel_type()).newbyteorder(stack_handle.get_endianess())# pre-allocate some memory for the pixel data:# (would be pulled out of the loop in real code)buf=np.zeros((len(stack_handle),)+frame_shape,dtype=dtype)# decompress into the pre-allocated buffercam_client.decompress_frame_stack(stack_handle,out=buf)# free up the shared memory slot for this frame stack:cam_client.done(stack_handle)# we can still use the decompressed data:buf.sum()finally:conn.close()# clean up background thread etc.cam_client.close()Changelogv0.2.10Add functionality to generate mock data for sending via the simulatorAdd missing numpy dependencyMake debug output a bit more reliablev0.2.9Add more debug and trace outputv0.2.7Log more details inDectrisConnection.log_shm_statsand change log level toINFOIncrease timeout for sending headers and framesv0.2.4 - v0.2.6Updated examples and CI configurationv0.2.3Addenv_logger: set environment variableLIBERTEM_DECTRIS_LOG_LEVELto e.g.'INFO'to enable loggingImproved error handling: raise an exception instead of panicing on serialization errorsIgnore messages with mismatching series IDAdd explicit checks for the correctheader_detaillevelsMove code into monorepov0.2.2Vendorbitshuffleand addFrame.decompress_intomethod, PR#10v0.2.1Catch frame ID mismatch, PR#9v0.2.0Addedlibertem_dectris.headerssubmodule that exports header classesAdded ways to createlibertem_dectris.Frameandlibertem_dectris.FrameStackobjects from Python, mostly useful for testingAdded binding to random port for the simulatorProperly parametrize with zmq endpoint URIFix many clippy complaintsv0.1.0Initial release!DevelopmentThis package is usingpyo3withmaturinto create the Python bindings.  First, make surematurinis installed in your Python environment:(venv)$pipinstallmaturinThen, after each change to the rust code, runmaturin develop -rto build and
install a new version of the wheel.As we vendorbitshuffle, make sure to clone withgit clone --recursive ..., or manuallytake care of initializing and updating submodules.Releaseupdate changelog abovebump version in Cargo.toml if not already bumped, and pushcreate a release from the GitHub UI, creating a new tag vX.Y.Zdone!