top bar

Difference between revisions of "Using the Micro-Manager python library"

(Python programming introduction)
(Code samples)
Line 37: Line 37:
 
MM package from your distribution repository, in most cases, ships with CMMCore, MMCorePy (python 2 or 3 wrapper) and MMCoreJ, but without GUI. At least your system variables should be already configured properly. Python and Numpy would be installed by your package manager as dependency.
 
MM package from your distribution repository, in most cases, ships with CMMCore, MMCorePy (python 2 or 3 wrapper) and MMCoreJ, but without GUI. At least your system variables should be already configured properly. Python and Numpy would be installed by your package manager as dependency.
  
== First steps ==
+
== Using Python API ==
 
Familiarize yourself with Micro-Manager and learn how to connect it to your hardware by MMStudio GUI.
 
Familiarize yourself with Micro-Manager and learn how to connect it to your hardware by MMStudio GUI.
 
* Find your device on [[Device Support|this page]] and figure out what adapter you need.
 
* Find your device on [[Device Support|this page]] and figure out what adapter you need.
Line 45: Line 45:
 
Images returned by calls to an instance of the pythonized Micro-Manager core class ([http://www.micro-manager.org/content/doc/mmcore_api/html/class_c_m_m_core.html CMMCore]) are stored in numpy arrays for convenience, and can be easily displayed by pylab (matplotlib) commands. Here is a short example (using matplotlib) that demonstrates use of the python wrapper to acquire and display an image.
 
Images returned by calls to an instance of the pythonized Micro-Manager core class ([http://www.micro-manager.org/content/doc/mmcore_api/html/class_c_m_m_core.html CMMCore]) are stored in numpy arrays for convenience, and can be easily displayed by pylab (matplotlib) commands. Here is a short example (using matplotlib) that demonstrates use of the python wrapper to acquire and display an image.
  
<code><pre>
+
=== First steps ===
# Create a Micro-Manager core object:
+
{{Note|Next code snippets aims to be most generic. We use numpy and matplotlib as is from pure python interactive shell, but it's convenient to use IPython with nice autocompletion capabilities.}}
import MMCorePy
+
mmc = MMCorePy.CMMCore()
+
  
#  Load and initialize the demo camera device:
+
Start python interactive session. Import `MMCorePy` and make sure everything is working properly.
mmc.loadDevice("cam","DemoCamera","DCam")
+
mmc.initializeDevice("cam")
+
  
# Snap and retrieve an image:
+
    >>> import MMCorePy
mmc.snapImage()
+
    >>> mmc = MMCorePy.CMMCore()  # Instance micromanager core
im1 = mmc.getImage()
+
    >>> mmc.getVersionInfo()
 +
    'MMCore version 2.3.2'
 +
    >>> mmc.getAPIVersionInfo()
 +
    'Device API version 59, Module API version 10'
  
# Display the image:
+
We just get some basic information about current Micromanager installation. If there an `ImportError`, check your PYTHONPATH variable.
from pylab import *
+
 
ion() # Activate interactive mode
+
=== Device loading ===
figure()
+
{{Note|You can get all needed parameters names from Micromanager configuration file, generated by MMStudio.}}
imshow(im1,cmap = cm.gray)
+
 
</pre>
+
Let's take step closer to hardware. Micromanager have couple of dummy devices, suitable for learning purposes. Load DemoCamera:
</code>
+
 
 +
    # Demo camera example, continuation of previous listing
 +
    >>> mmc.loadDevice('Camera', 'DemoCamera', 'DCam')
 +
    >>> mmc.initializeAllDevices()
 +
    >>> mmc.setCameraDevice('Camera')
 +
 
 +
=== Snapping single image ===
 +
==== Grayscale ====
 +
 
 +
    >>> mmc.snapImage()
 +
    >>> img = mmc.getImage()  # img - it's just numpy array
 +
    >>> img
 +
    array([[12, 12, 13, ..., 11, 12, 12],
 +
          [12, 12, 13, ..., 11, 12, 12],
 +
          [12, 13, 13, ..., 12, 12, 12],
 +
          ...,
 +
          [22, 22, 22, ..., 22, 22, 22],
 +
          [22, 22, 22, ..., 22, 22, 22],
 +
          [22, 22, 22, ..., 22, 22, 22]], dtype=uint8)
 +
 
 +
By default it's grayscale 8-bit image, presented as two-dimensional numpy array. Let's see him with matplotlib.
 +
 
 +
    >>> import matplotlib.pyplot as plt
 +
    >>> plt.imshow(img, cmap='gray')
 +
    >>> plt.show()  # And window will appear
 +
 
 +
==== Color ====
 +
Of course, color image is more suitable for optical microscopy purposes. So take one:
 +
 
 +
    >>> mmc.setProperty('Camera', 'PixelType', '32bitRGB')  # Change pixel type
 +
    >>> rgb32 = mmc.getImage()
 +
    >>> rgb32
 +
    array([[1250067, 1250067, 1315860, ..., 1250067, 1250067, 1250067],
 +
          [1250067, 1315603, 1315860, ..., 1250067, 1250067, 1250067],
 +
          [1250067, 1315859, 1315860, ..., 1250067, 1250067, 1250067],
 +
          ...,
 +
          [1246483, 1246483, 1246483, ..., 1181204, 1246740, 1246484],
 +
          [1246483, 1246483, 1246483, ..., 1246740, 1246740, 1246483],
 +
          [1246483, 1246483, 1312019, ..., 1246740, 1246740, 1246483]], dtype=uint32)
 +
 
 +
Interesting output isn't it? We expect something like 3-dimensional RGB array, but get bunch of uints in 2-D shape.
 +
 
 +
==== Numpy array ====
 +
Now we should look at RGB32 data structure.
 +
 
 +
    low memory address    ---->      high memory address
 +
    | pixel | pixel | pixel | pixel | pixel | pixel |...
 +
    |-------|-------|-------|-------|-------|-------|...
 +
    |B|G|R|A|B|G|R|A|B|G|R|A|B|G|R|A|B|G|R|A|B|G|R|A|...
 +
    http://avisynth.nl/index.php/RGB32
 +
 
 +
Let's numpy handle that.
 +
 
 +
    >>> import numpy as np
 +
    >>> rgb32.view(dtype=np.uint8).reshape(
 +
            rgb32.shape[0], rgb32.shape[1], 4)[...,2::-1]
 +
View RGB32 as RGB array (no copy).
 +
 
 +
=== Continuous acquisition ===
 +
{{Warning|'''Don't run this code directly.''' It's a partial sample.}}
 +
 
 +
    mmc.startContinuousSequenceAcquisition(1)
 +
    while True:
 +
        rgb32 = mmc.getLastImage()
 +
        if mmc.getRemainingImageCount() > 0:
 +
            rgb32 = mmc.getLastImage()
 +
            # or rgb32 = mmc.popNextImage()
 +
            # Efficient conversion without data copying.
 +
            bgr = rgb32.view(dtype=np.uint8).reshape(
 +
                rgb32.shape[0], rgb32.shape[1], 4)[..., :3]
  
 
A longer example script, [https://github.com/mdcurtis/micromanager-upstream/blob/master/bindist/any-platform/MMCoreWrapDemo.py MMCoreWrapDemo.py], is available in the Micro-Manager root directory.
 
A longer example script, [https://github.com/mdcurtis/micromanager-upstream/blob/master/bindist/any-platform/MMCoreWrapDemo.py MMCoreWrapDemo.py], is available in the Micro-Manager root directory.
Line 80: Line 148:
 
* [https://github.com/mdcurtis/micromanager-upstream Micromaanger SVN-tracking repository on Github]
 
* [https://github.com/mdcurtis/micromanager-upstream Micromaanger SVN-tracking repository on Github]
  
Written by Eugene Dvoretsky -- [[User:Radioxoma|Radioxoma]] ([[User talk:Radioxoma|talk]]) 10:00, 8 June 2014 (PDT)
+
Written by Eugene Dvoretsky -- [[User:Radioxoma|Radioxoma]] ([[User talk:Radioxoma|talk]]) 17:07, 9 June 2014 (PDT)
  
 
{{Programming_Sidebar}}
 
{{Programming_Sidebar}}

Revision as of 17:07, 9 June 2014

MMCorePy is a wrapper that allows you to control microscope hardware from python interactive session or scripts. It's support Windows, Mac and Linux.

Micromanager's main parts:

  • CMMCore - basic module, written in C++. Script languages like python just wrap it by swig.
  • Device adapters - various libraries that allow support for various hardware. If you want to built one and extend MM devise support, feel free to use SDK.
  • MMCorePy - python wrapper. MM build scripts are support both python 2 and 3, but windows version ships with python 2 bindings only.
  • MMCoreJ - java wrapper
  • MMStudio - Micromanager GUI (technically it is ImageJ plugin).

Environment setup

You must install python2 and numpy. Windows users may prefer using an python distribution instead manual separate installation.

Manual

  • python 2.7.x (python2 is default for windows now)
  • numpy 1.7.x Micormanager represent imaging data as multidimensional numpy arrays.

Using python distributions

It's convenient to install a distribution which includes Python, numpy, scientific libraries, GUI frameworks and IDEs. All distributions have a free version, some of them have extended paid version, but you can request free academic license.

Useful libraries

  • Scipy - scientific algorithms, multidimensional image processing toolbox.
  • Matplotlib - fastest way to show your image data.
  • Opencv - computer vision and image processing library. Sometimes faster than scipy.
  • Pillow - very basic image processing. Scipy uses it for image loading and writing.
  • Scikit-image - "pythonic" scientific-oriented image processing algorithms collection.
  • IPython - improved interactive python environment

Micromanager installation

Windows & Mac

Download and install Micro-Manager on your computer. Add Micromanager installation folder to PYTHONPATH (i.e. "C:\Program Files\Micro-Manager-1.4", it should contain MMCorePy.py and _MMCorePy.pyd files). Create variable if it not exist. At now you can import MMCorePy without an error.

Linux

MM package from your distribution repository, in most cases, ships with CMMCore, MMCorePy (python 2 or 3 wrapper) and MMCoreJ, but without GUI. At least your system variables should be already configured properly. Python and Numpy would be installed by your package manager as dependency.

Using Python API

Familiarize yourself with Micro-Manager and learn how to connect it to your hardware by MMStudio GUI.

Images returned by calls to an instance of the pythonized Micro-Manager core class (CMMCore) are stored in numpy arrays for convenience, and can be easily displayed by pylab (matplotlib) commands. Here is a short example (using matplotlib) that demonstrates use of the python wrapper to acquire and display an image.

First steps

Note
Next code snippets aims to be most generic. We use numpy and matplotlib as is from pure python interactive shell, but it's convenient to use IPython with nice autocompletion capabilities.

Start python interactive session. Import `MMCorePy` and make sure everything is working properly.

   >>> import MMCorePy
   >>> mmc = MMCorePy.CMMCore()  # Instance micromanager core
   >>> mmc.getVersionInfo()
   'MMCore version 2.3.2'
   >>> mmc.getAPIVersionInfo()
   'Device API version 59, Module API version 10'

We just get some basic information about current Micromanager installation. If there an `ImportError`, check your PYTHONPATH variable.

Device loading

Note
You can get all needed parameters names from Micromanager configuration file, generated by MMStudio.

Let's take step closer to hardware. Micromanager have couple of dummy devices, suitable for learning purposes. Load DemoCamera:

   # Demo camera example, continuation of previous listing
   >>> mmc.loadDevice('Camera', 'DemoCamera', 'DCam')
   >>> mmc.initializeAllDevices()
   >>> mmc.setCameraDevice('Camera')

Snapping single image

Grayscale

   >>> mmc.snapImage()
   >>> img = mmc.getImage()  # img - it's just numpy array
   >>> img
   array([[12, 12, 13, ..., 11, 12, 12],
          [12, 12, 13, ..., 11, 12, 12],
          [12, 13, 13, ..., 12, 12, 12],
          ...,
          [22, 22, 22, ..., 22, 22, 22],
          [22, 22, 22, ..., 22, 22, 22],
          [22, 22, 22, ..., 22, 22, 22]], dtype=uint8)

By default it's grayscale 8-bit image, presented as two-dimensional numpy array. Let's see him with matplotlib.

   >>> import matplotlib.pyplot as plt
   >>> plt.imshow(img, cmap='gray')
   >>> plt.show()  # And window will appear

Color

Of course, color image is more suitable for optical microscopy purposes. So take one:

   >>> mmc.setProperty('Camera', 'PixelType', '32bitRGB')  # Change pixel type
   >>> rgb32 = mmc.getImage()
   >>> rgb32
   array([[1250067, 1250067, 1315860, ..., 1250067, 1250067, 1250067],
          [1250067, 1315603, 1315860, ..., 1250067, 1250067, 1250067],
          [1250067, 1315859, 1315860, ..., 1250067, 1250067, 1250067],
          ...,
          [1246483, 1246483, 1246483, ..., 1181204, 1246740, 1246484],
          [1246483, 1246483, 1246483, ..., 1246740, 1246740, 1246483],
          [1246483, 1246483, 1312019, ..., 1246740, 1246740, 1246483]], dtype=uint32)

Interesting output isn't it? We expect something like 3-dimensional RGB array, but get bunch of uints in 2-D shape.

Numpy array

Now we should look at RGB32 data structure.

   low memory address    ---->      high memory address
   | pixel | pixel | pixel | pixel | pixel | pixel |...
   |-------|-------|-------|-------|-------|-------|...
   |B|G|R|A|B|G|R|A|B|G|R|A|B|G|R|A|B|G|R|A|B|G|R|A|...
   http://avisynth.nl/index.php/RGB32

Let's numpy handle that.

   >>> import numpy as np
   >>> rgb32.view(dtype=np.uint8).reshape(
           rgb32.shape[0], rgb32.shape[1], 4)[...,2::-1]

View RGB32 as RGB array (no copy).

Continuous acquisition

Warning
Don't run this code directly. It's a partial sample.
   mmc.startContinuousSequenceAcquisition(1)
   while True:
       rgb32 = mmc.getLastImage()
       if mmc.getRemainingImageCount() > 0:
           rgb32 = mmc.getLastImage()
           # or rgb32 = mmc.popNextImage()
           # Efficient conversion without data copying.
           bgr = rgb32.view(dtype=np.uint8).reshape(
               rgb32.shape[0], rgb32.shape[1], 4)[..., :3]

A longer example script, MMCoreWrapDemo.py, is available in the Micro-Manager root directory.

Also check out micromanager-samples repo for python code samples (live video acquisition, property discovery etc).

Further reading

Micromanager code

Written by Eugene Dvoretsky -- Radioxoma (talk) 17:07, 9 June 2014 (PDT)

© Micro-Manager : Vale Lab, UCSF 2006-2011 | All Rights Reserved | Contact