pycro-manager Python Library

repository·main·Indexed 41 days ago

https://github.com/micro-manager/pycro-manager

A Python library for customized microscope hardware control and integration with image processing. It serves as a bridge to Micro-Manager and Micro-Magellan or as a standalone backend. Key features include multi-dimensional acquisitions (MDA), adaptive 'smart microscopy' workflows using AcquisitionFuture, acquisition hooks for custom code injection, and support for large datasets via Dask and napari visualization.

Tokens
16.9K
Snippets
55
Records
80
Agent score
52%

What's inside pycro-manager

  1. Overview of Pycro-Manager

    main

    pycromanager is a Python package designed for microscope hardware automation and image acquisition. It is built to be flexible, providing various components that can be used independently or combined to support a wide range of microscopy applications.

    To begin using the library, users should refer to the user_guide for foundational knowledge, or the tutorials section for Jupyter Notebook-based examples of specific applications.

  2. Call Java code from Python

    main

    Pycro-Manager can execute Java code from within Python using the PyJavaZ library. This enables several advanced workflows:

    • Micro-Manager UI Control: Programmatically interact with the Micro-Manager user interface via the Studio API.
    • Plugin Support: Control Micro-Manager plugins (e.g., Micro-Magellan) directly from Python.
    • Legacy Script Compatibility: Run existing Beanshell scripts with minimal modifications.
    • Custom Java Integration: Integrate your own custom Java code into your Python-based workflows.
  3. Use High-level APIs for microscopy experiments

    main

    For most microscopy tasks, use the Acquisition class. It is designed to simplify complex experiments and data handling.

    Key capabilities include:

    • Experiment Control: Manage 3D volumes, time series, and multi-channel data.
    • Hardware Customization: Support for non-standard hardware and custom acquisition schemes.
    • Data Access: Retrieve data using the Dataset class as numpy or dask arrays.
    • Visualization: Includes a built-in image viewer (which can be disabled if building a custom application).
  4. Return multiple images from an Image Processor

    main

    An image processor can return multiple images by returning a list of (image, metadata) tuples. When doing this, you must modify the metadata['Axes'] field to uniquely identify each image (e.g., by changing the channel name) so that the saving and viewing logic can distinguish them.

    import numpy as np
    import copy
    
    def img_process_fn(image, metadata):
        # Create a second image and metadata copy
        image_2 = np.array(image, copy=True)
        metadata_2 = copy.deepcopy(metadata)
        
        # Update Axes to uniquely identify the new image
        metadata_2['Axes']['channel'] = 'New_channel'
        metadata['Axes']['channel'] = 'Old_channel'
        
        return [(image, metadata), (image_2, metadata_2)]
  5. How to customize the acquisition process

    main

    Pycro-Manager provides several extension points to modify how acquisitions behave. These processes run asynchronously (on different threads) to maximize performance:

    • Acquisition Events (acq_events): Define custom acquisition instructions.
    • Acquisition Hooks (acq_hooks): Inject custom code at specific points in the acquisition lifecycle.
    • Image Processors (img_processors): Modify or process image data on-the-fly during acquisition.
    • Image Saved Callbacks (image_saved_callbacks): Execute custom code immediately after an image is saved and displayed.
  6. Understand Pycro-Manager backends and operational modes

    main

    Pycro-Manager provides a consistent Python API that works across three distinct operational modes. The choice of backend depends on whether you need the Micro-Manager GUI and your specific performance requirements for data handling.

    Operational Modes

    1. Full Micro-Manager application mode: Uses the Java backend. This provides access to the complete Micro-Manager GUI and all its features.
    2. Headless mode (Java): Uses the Java backend without the Micro-Manager GUI. This is useful for custom applications or running on a server while still using the standard Micro-Manager components.
    3. Headless mode (Python): Uses the Python backend. This provides pure Python implementations of the components.

    Choosing a Backend: Performance Trade-offs

    • Java Backend: Communication between Java and Python can be a bottleneck (typically < 100 MB/s). To mitigate this, Pycro-Manager is designed to minimize data transfer; for example, the Acquisition class performs acquisition and saving within the Java layer for maximum speed.
    • Python Backend: This is advantageous when you need to rapidly process data in Python without saving it to disk first, such as when implementing a custom Python-based live viewer.
  7. Choose a Pycro-Manager running mode

    main

    Pycro-Manager can operate in two distinct modes depending on your needs:

    1. Alongside Micro-Manager Desktop: The recommended mode for most users. It runs alongside the Micro-Manager GUI, allowing you to use the desktop application for microscope configuration and hardware testing while controlling it via Python.
    2. Headless Mode: The Micro-Manager Core is launched programmatically without the desktop application. This is useful for automated environments where a GUI is not required.
  8. How hardware triggering and sequencing work in Pycro-Manager

    main
    Hardware triggering and sequencing minimize computer-hardware communication latency by pre-loading hardware components with instruction sequences (like stage positions or laser digital outputs). These sequences execute independently of the computer, using TTL (Transistor-Transistor Logic) pulses to synchronize devices. This allows for much faster image acquisition compared to computer-controlled triggering.
  9. Specify an acquisition event

    main

    An acquisition event is a dictionary that defines the parameters for an image acquisition. To trigger an image acquisition, the event must contain either the 'channel' key within 'axes' or the 'axes' key itself. If these are missing, the event is used for hardware control only.

    Key fields include:

    • 'axes': A dictionary of positions along various axes.
      • 'channel': A special axis name that overlays different positions in different colors in the viewer.
      • 'row' and 'column': Special values used by XYTiledAcquisition to convert to stage coordinates for grid layouts.
    • 'config_group': A list ['group_name', 'preset_name'] to control hardware properties.
    • 'z': Controls the default z stage device (e.g., Core-Focus) in $\mu m$.
    • 'stage_positions': A list of dictionaries to control multiple specific devices by name and position in $\mu m$.
    • 'x', 'y': XY stage positions in $\mu m$.
    • 'exposure': Exposure time in ms.
    • 'camera': The name of the camera device to use (if not the default 'Core-camera').
    • 'properties': A list of ['DeviceName', 'PropertyName', 'PropertyValue'] for arbitrary hardware settings.
    • 'tags': Custom metadata that will be added to the resultant image's metadata.
    event = {
        'axes': {
            'axis1_name': 1,
            'axis2_name': 'first_position', 
            'channel': 'DAPI',
            'row': 1,
            'column': 0,
        },
        'config_group': ['name_of_config_group', 'name_of_preset'],
        'exposure': 10.6,
        'z': 123.45,
        'stage_positions': 
                [{'z_stage1_name': 12.34}, 
                 {'z_stage2_name': 1234.566}],
        'min_start_time': 100,
        'x': 123.4,
        'y': 567.8,
        'camera': 'a_camera_device_name',
        'properties': [['DeviceName', 'PropertyName', 'PropertyValue'], 
                       ['OtherDeviceName', 'OtherPropertyName', 'OtherPropertyValue']],
        'tags': {
            'whatever_you_want_here': 54,
            'something_else': 'here'}
    }