DigitalMicrograph and Stand-Alone Python Integration
Weng E Lei, Dieter Weber, Alexander Clausen, Jacob Wilbrink · Microscopy and Microanalysis · 2024
From its inception in the 1980’s on the MacIntosh computer, DigitalMicrograph has had its own proprietary scripting language - DM Scripting. This has allowed for the development of many large and small automation routines over the decades [1,2]. Python was added into DigitalMicrograph about 5 years ago because of its increased popularity as a programming language [3]. This addition lowered the threshold to scripting in DigitalMicrograph and at the same time expanded its capabilities by making all Python libraries immediately available, for example for machine learning (TensorFlow) and sophisticated data mining (SciKit-learn) [4]. However, it turned out there are some limitations with embedded Python when trying to develop larger solutions. The main limitation is related to threading, arising to issues when trying to use certain libraries and functions. To resolve these issues, we introduce here a method to run Python stand-alone, for example as a Jupyter Notebook, and interact with DigitalMicrograph efficiently. We do this by developing a plug-in in DigitalMicrograph using the freely available DM-SDK, and communicating to Python using the ZeroMQ messaging library and the JSON data-interchange format. The basic idea of the new integration approach is that a custom DigitalMicrograph plug-in is developed using the DM-SDK, that can communicate with stand-alone Python. All communication is done using ZeroMQ (zmq) and JSON and no new Python libraries are required. Here is a simple workflow when acquiring a camera image using this approach: All code for this example will be made available so that the reader can expand on it for their own application. A more advanced application is related to 4D-STEM Acquisition. Sending a sequence of detector images quickly in a stream-like fashion, as opposed to polling individual frames, enables fast live 4D STEM and other live imaging techniques with high frame rate. To keep up with the data rate of modern detectors, parallel processing and/or GPU acceleration are required. Sending the data over an efficient protocol like ZeroMQ, as opposed to receiving it in an embedded Python interpreter, brings several advantages in that scenario: 1. The receiving side is not limited to Python, but the protocol can be implemented with languages like C++ or Rust as well. As an example, LiberTEM-live [7] is developed mostly in Python but uses Rust-based extensions to implement high-speed receiver interfaces for cameras. 2. The receiving code can run as a separate process, which reduces interference between the host application and the processing engine, such as locking, thread management, memory management and handling of other resources. In particular, this simplifies using Jupyter notebooks, which are challenging to run from an embedded Python interpreter. 3. The processing application can run on a separate computer. This avoids overloading the computer that controls the camera hardware, allows using remote systems for processing, such as nodes of a HPC cluster, and makes orchestrating a complex experimental setup consisting of multiple devices easier. We have shown some use cases on how one can integrate DigitalMicrograph image acquisition into standalone applications, using ZMQ networking and JSON messaging. It improves interoperability, enables high-speed live processing, and allows the user to work from more familiar environments, such as Jupyter Notebooks.