Python: Gatan, Inc. 5794 W. Las Positas Blvd. Pleasanton, CA 94588 T +1.925.463.0200
Python: Gatan, Inc. 5794 W. Las Positas Blvd. Pleasanton, CA 94588 T +1.925.463.0200
Gatan, Inc.
5794 W. Las Positas Blvd.
Pleasanton, CA 94588
t +1.925.463.0200
support@gatan.com
w w w .gatan.com
Copyright 2020 Gatan Inc. All Rights Reserved
All rights reserved. No parts of this work may be reproduced in any form or by any means - graphic,
electronic, or mechanical, including photocopying, recording, taping, or information storage and retrieval
systems - without the written permission of the publisher.
Products that are referred to in this document may be either trademarks and/or registered trademarks of the
respective owners. The publisher and the author make no claim to these trademarks.
While every precaution has been taken in the preparation of this document, the publisher and the author
assume no responsibility for errors or omissions, or for damages resulting from the use of information
contained in this document or from the use of programs and source code that may accompany it. In no event
shall the publisher and the author be liable for any loss of profit or any other commercial damage caused or
alleged to have been caused directly or indirectly by this document.
Publisher
Gatan, Inc.
Technical Editors
Gatan Software Team
Document revision
Rev 3.4.3.3213
www.gatan.com
Python
Table of Contents
1 Python 1
1.1 Installation .and
. . .Configuration
...................................................................1
Index 45
Python page 1
1 Python
Python
The DigitalMicrograph scripting language has been around for many years and provides complete
access to the image processing and analysis capabilities of the application as well as enabling control
of Gatan cameras, the DigiScan and an interface to the microscope. In recent years the Python
language has grown as an all-purpose scripting language and many libraries have been created to
provide specialized image processing, data analysis and visualization capabilities that go beyond what
can be achieved in DigitalMicrograph. We have therefore added Python as a hosted language to
DigitalMicrograph. You can now access much of the capability of DigitalMicrograph, control Gatan
cameras, the DigiScan and communicate with the microscope, as well as access any Python library
from this hosted Python environment.
DigitalMicrograph adds classes to the hosted Python environment that provide access to the key
objects within DigitalMicrograph scripting, objects like the Image, ImageDocument, ImageDisplay,
LinePlotImageDisplay, Component, Window, and TagGroup, as well as Camera, DigiScan and
Microscope. The interfaces of these classes are described in the Reference chapter.
The Python scripting environment is installed through the Gatan Microscopy Suite (GMS) installer.
There is no specific GMS license required. The installer makes use of Miniconda from Continuum
Analytics to install the Conda package manager, Python, and NumPy, the fundamental package for
scientific computing in Python.
Python
Python page 2
1.1.1 Installation
Installation
The Python scripting environment is installed by the GMS installer.
1. Select the button for "Yes, install Python support" in the GMS installer.
The GMS installer will then install Miniconda with Python and NumPy.
Python
Python page 3
1.1.2 Configuration
Configuration
There are many versions of Python and its associated libraries. The GMS installer contains a particular
version of Miniconda and it, in turn, installs a particular version of each of Python and NumPy. By
default Python in DigitalMicrograph will use these matching versions. If you have separately installed
another version of Python, using an independent installer, it may be possible to use that version in
DigitalMicrograph instead. This is only likely to work for Python versions that differ by minor version, e.
g. 3.7.5 and 3.7.6.
If you create alternate Python environments through a command line prompt using Conda they will not
be available for selection in DigitalMicrograph. You can only choose between alternate installations of
Python.
1. Choose Global Info... on the File menu and select the Scripting entry in the list at the left
Python
Python page 4
The currently selected installation of Python is displayed. The listed versions are those
that are likely to work with DigitalMicrograph. Although installations that differ only by
minor version are listed, only the one labeled GMS_VENV_PYTHON is guaranteed to be
compatible with DigitalMicrograph.
DigitalMicrograph will launch and run the Python interpreter associated with the selected
installation when running Python scripts.
Numpy configuration
The Numpy package installed by the GMS installer uses OpenBLAS as its linear algebra library. This is
Python
Python page 5
the recommended Numpy configuration in order to avoid version conflicts and system instabilities with
GMS which itself uses the MKL libraries.
When updating additional Python packages, care should be taken that this configuration is not changed
and packages use consistent dependencies on Numpy. In particular conda installs have a tendency to
default Numpy back to using the MKL libraries. It is recommended to use pip installs instead.
The Anaconda Prompt was installed with Miniconda during GMS installation and can be
found in the Windows start menu.
2. Within the Anaconda Prompt, activate the environment you want to modify.
Python
Python page 6
Type: python
Python
Python page 7
1. Open the Anaconda Prompt and activates the GMS_VENV_PYTHON environment as shown
above
3. When installing additional packages, use pip install (not conda) to avoid defaulting back to
MKL.
1. Open the Anaconda Prompt and activates the GMS_VENV_PYTHON environment as shown
above
2. Use conda install for Numpy. The package manager will update all other affected packages:
Python
Python page 8
1. Open the Anaconda Prompt and activates the GMS_VENV_PYTHON environment as shown
above
2. Use conda to list installed packages and provided additional information. Neither command
should return error messages.
Additional packages
The basic installation of Python does not include any packages other than NumPy, but additional
Python packages can be installed. The selected default Python installation is the virtual environment
named GMS_VENV_PYTHON. You can use both pip and conda commands to install packages to this
environment from the Anaconda Prompt, however pip is recommended as conda may change the
Numpy configuration.
As an example, the versatile machine-learning library scikit-learn can be used from within
DigitalMicrograph directly on acquired data (see application examples).
1. Ensure the computer has a working internet connection. Packages will be automatically
downloaded.
The Anaconda Prompt was installed with Miniconda during GMS installation and can be
found in the Windows start menu.
Python
Python page 9
3. Within the Anaconda Prompt, activate the environment you want to modify.
Python
Python page 10
Open a script window ( CTRL + K ) and ensure the scripting language Python is
chosen.
import DigitalMicrograph as DM
import joblib
import scipy
import sklearn
DM.ClearResults()
print( 'joblib : ', joblib.__version__ )
print( 'SciPy : ', scipy.__version__ )
print( 'scikit-learn : ', sklearn.__version__ )
1.1.4 Licenses
Licenses
The Miniconda package manager, Python and the NumPy package are licensed from the following.
Miniconda, Conda
© 2017 Continuum Analytics, Inc. (dba Anaconda, Inc.). https://www.anaconda.com. All Rights
Reserved
Redistribution and use in source and binary forms, with or without modification, are permitted provided
that the following conditions are met:
Python
Python page 11
Redistributions of source code must retain the above copyright notice, this list of conditions
and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials provided
with the distribution.
Neither the name of Continuum Analytics, Inc. nor the names of its contributors may be used
to endorse or promote products derived from this software without specific prior written
permission.
Python
1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual
or Organization ("Licensee") accessing and otherwise using Python 3.7.4 software in source or binary
form and its associated documentation.
2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a
nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display
publicly, prepare derivative works, distribute, and otherwise use Python 3.7.4 alone or in any derivative
version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e.,
"Copyright © 2001-2019 Python Software Foundation; All Rights Reserved" are retained in Python
3.7.4 alone or in any derivative version prepared by Licensee.
3. In the event Licensee prepares a derivative work that is based on or incorporates Python 3.7.4 or
any part thereof, and wants to make the derivative work available to others as provided herein, then
Licensee hereby agrees to include in any such work a brief summary of the changes made to Python
3.7.4.
4. PSF is making Python 3.7.4 available to Licensee on an "AS IS" basis. PSF MAKES NO
REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT
NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF
MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
PYTHON 3.7.4 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
Python
Python page 12
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 3.7.4 FOR
ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 3.7.4, OR ANY DERIVATIVE
THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
6. This License Agreement will automatically terminate upon a material breach of its terms and
conditions.
7. Nothing in this License Agreement shall be deemed to create any relationship of agency,
partnership, or joint venture between PSF and Licensee. This License Agreement does not grant
permission to use PSF trademarks or trade name in a trademark sense to endorse or promote
products or services of Licensee, or any third party.
8. By copying, installing or otherwise using Python 3.7.4, Licensee agrees to be bound by the terms
and conditions of this License Agreement.
NumPy
Redistribution and use in source and binary forms, with or without modification, are permitted provided
that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions
and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials provided
with the distribution.
Neither the name of the NumPy Developers nor the names of any contributors may be used
to endorse or promote products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Python
Python page 13
Scripting in Python
Python scripts are edited and run from the same script window that is used to edit and run a
DigitalMicrograph script. When Python support is installed the script window gains a language selector
to choose between DigitalMicrograph scripting and Python scripting.
Running a Script
A Python script can be run on the same thread as the user interface of DigitalMicrograph (the
foreground thread) or a new thread can be created (a background thread) and the script run on that.
This choice is controlled by a check-box at the bottom of the editor window.
The default is to run the script on a background thread, because scripts run on the same thread as the
user interface of DigitalMicrograph prevent all user interaction with the application during script run
time. It is not possible to interrupt the Python script in this case, and it may become necessary to kill
DigitalMicrograph to escape from a poorly written script.
Python
Python page 14
Some Python packages will not perform correctly if run on a background thread, and may even crash
DigitalMicrograph if they are not run on the foreground thread. One example of such a package is the
commonly used Matplotlib package.
Only one Python script may be run at a time. If you attempt to run a second script DigitalMicrograph
will display an error message.
1. Click on the Execute button in the scripting window or hit Ctrl-Enter on the keyboard
The script in the window will be run on either the user interface (foreground thread) or a
background thread, depending on the state of the "Execute in background" check box.
Only one Python script can be executing at any time.
If there is a Python script running on a background thread it will be stopped. There are
times when the Python interpreter may be holding on to the Python Global Interpreter
Lock and at these times the DigitalMicrograph cannot stop the running script and will
instead present an information dialog explaining the problem.
Some Python scripts, in particular when using additional libraries utilizing external UI
windows, require to be run on the foreground thread and may crash DigitalMicrograph
otherwise. To prevent accidental launching of the scripts on a background thread, such
a script itself may contain the following initial code lines:
Python
Python page 15
if ( False == DM.IsScriptOnMainThread() ):
print( 'This script requires to be run on the main
thread.' )
exit()
A Python script can directly manipulate image data held in DigitalMicrograph. This is achieved by
mapping NumPy arrays onto the memory of the DigitalMicrograph images. This sharing of memory
access imposes some restrictions- see the examples on Images and NumPy arrays.
"Inversion" of dimensions
DigitalMicrograph image images store their elements with first dimension index incrementing
first, i.e consecutive values describe the next pixel in X direction until a row is completed. Only
then does the Y coordinate get incremented by one and the X coordinated reset to zero.
Similarly, only after all rows have been filled will the Z coordinate be incremented to move to the
next plane.
NumPy arrays, unfortunately, use the opposite indexing concept, incrementing the last
dimension index first. As a result, NumPy arrays mapped onto DigitalMicrograph images, and
DigitalMicrograph images created from NumPy arrays exhibit an apparent 'flip' of dimensions.
Memory layout
DigitalMicrograph images require continuous memory arrays with a memory-layout in 'C' order.
Numpy arrays, however, can be in either 'C' or 'F' layout, specifying the order of values in the
array. An array of 'C' layout can be created from an array in 'F' layout using the copy()
command with the parameter order='C'.
Python
Python page 16
NumPy arrays connected to DigitalMicrograph images directly address the same memory
space. When using a Python script to change these values, one has to be careful to only use
syntax which modifies the existing memory. Many Python commands instead create new data
arrays and subsequently assign a variable to this new array. Such commands will not update
DigitalMicrograph image data!
Updating the data in a NumPy array that is connected to a DigitalMicrograph image does not
automatically trigger a display update in DigitalMicrograph. This has to be explicitly requested
by the UpdateImage() script command.
NumPy arrays are a very flexible object and not all of them can be used as a source for a
DigitalMicrograph image. If an invalid data format is encountered, an error message will be
presented. NumPy arrays also support views on data. Here, the actual data order in memory is
unchanged, but auxiliary meta data describes how it should be addressed. This is most often
used to access non-contiguous data, which can not be used as a memory array for a
DigitalMicrograph image. For this reason, it is not possible to create a DigitalMicrograph image
directly from a NumPy array view. Instead, a contiguous copy of the view needs to be created
first.
Hybrid Scripts
Python
Python page 17
DigitalMicrograph hosts two different scripting languages, the Python scripts described here and it's
own scripting language known as DigitalMicrograph script (DM-script).
Each of the two script languages has commands to call scripts of the other variety, allowing for
interesting mixed 'hybrid' scripting. This can be useful as either language has its strengths and
weaknesses.
The example section on hybrid scripts shows some interesting applications.
Python
Python page 18
Please note that other DigitalMIcrograph UI items - including the Results window - may not
update during Python execution on the main thread.
Also keep in mind that there can only be a single Python script execution at any time. If a
Python script is launched while another one is still executed, an error dialog will be shown.
1.3 Examples
Examples
This section shows some simple Python script examples for DigitalMicrograph.
Python
Python page 19
print( '\nFormated string:\n\t second value = {1:3.1f} \n\t first value = {0:3
Python
Python page 20
DM.ClearResults()
print('Python: ',sys.version)
print('Numpy : ',np.version.full_version)
print('Python path:',DM.GetPYTHONPATH())
Python
Python page 21
'''
import DigitalMicrograph as DM
import numpy as np
Python
Python page 22
'''
Demonstration of accessing the two front-most images in GMS
'''
import DigitalMicrograph as DM
#Find the front image, and get the image data as numpy array
image1 = DM.GetFrontImage()
image1_data = image1.GetNumArray()
#Find the next image, and get its image data as numpy array
image2 = image1.FindNextImage()
image2_data = image2.GetNumArray()
Python
Python page 23
Python
Python page 24
import numpy as np
Python
Python page 25
Y, X = np.ogrid[:h, :w]
dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)
#Set Radius as fraction of the image size (from center to the nearest edge)
RADIUS_FRACTION = .5
Python
Python page 26
del img_masked
if ( img is None ):
print( 'No image was found' )
else:
img.ShowImage()
img.SetName( 'Found image!' )
if ( img is None ):
print( 'No image "', searchName, '" was found' )
else:
img.ShowImage()
img.SetName( 'Found image!' )
Python
Python page 27
import DigitalMicrograph as DM
if ( img is None ):
print( 'No image [', searchStr, '] was found' )
else:
img.ShowImage()
img.SetName( 'Found image!' )
ImageDisplays
Example 1: Adding annotations to an imageDisplay
'''
Example of adding annotation components to an ImageDisplay.
The script uses the front-most displayed image. If none is
found, it creates and displays one.
'''
import DigitalMicrograph as DM
import numpy as np
testImg = 0
if ( 0<DM.CountImageDocuments() ):
testImg = DM.GetFrontImage()
else:
testImg = DM.CreateImage( np.arange(120000).reshape(300, 400).copy() )
testImg.ShowImage()
sx = testImg.GetDimensionSize(0)
sy = testImg.GetDimensionSize(1)
img_disp = testImg.GetImageDisplay(0)
# Cleanup
del img_disp
del testImg
Python
Python page 28
'''
This script sets the drawing properties of all annotations
on the front-most displayed image.
'''
import DigitalMicrograph as DM
if ( 0 == DM.CountImageDocuments() ):
exit()
testImg = DM.GetFrontImage()
img_disp = testImg.GetImageDisplay(0)
nSubComp = img_disp.CountChildren()
for index in range(nSubComp):
comp = img_disp.GetChild(index)
comp.SetForegroundColor(0,1,0) # green
comp.SetBackgroundColor(0.2,0.2,0.5)# dark blue
comp.SetFillMode(2) # not filled
comp.SetDrawingMode(1) # with outline
# Cleanup
del img_disp
del testImg
Python
Python page 29
print( 'Tags have been added to the image as can be seen in the image display'
Python
Python page 30
Python
Python page 31
Hardware access
Python
Python page 32
useImgID = 0
# Variant 2: Provide a suitable data container (size and type must match)
signalIndex = 1 # 2nd assigned STEM Detector
selectSignal = True
dataByte = 4
array = np.zeros(shape=(size,size),dtype='uint32')
dmImg = DM.CreateImage( array )
dmImg.ShowImage()
useImgID = dmImg.GetID()
dmImg.SetName( "Provided image" )
del dmImg # Always delete image variables again when no longer needed
DM.DS_DialogEnabled( False )
DM.DS_StartAcquisition_2( paramID, continuous, synchronous )
DM.DS_DialogEnabled( True )
Python
Python page 33
preImg.ShowImage()
DM.OkDialog( 'Image created, now acquire...' )
cam.AcquireInPlace( preImg, exposure, bin, bin, kUnproc )
del preImg # Always delete Py_Image variables again
cam.StopContinuousAcquisition( )
del dstImage # Always delete Py_Image variables again
mic = DM.Py_Microscope()
Application examples
Python
Python page 34
'''
This example requires the scikit-learn packages to be installed.
The script assumes a STEM SI image is front most on the workspace.
This is a 3D image which contains spectral data along the z-dimension
for individual points of the xy-array. Typically, this will be an
EELS or EDS data set.
The example performs NMF decomposition on the data, trying to find a
set of non-negative components which can represent the data by linear
combination.
'''
import DigitalMicrograph as DM
import numpy as np
import sys
import joblib
import scipy
import sklearn
# Do the NMF
from sklearn.decomposition import NMF
estimator = NMF(n_components=wanted_components, init='nndsvd', tol=5e-3)
estimator.fit( data )
Python
Python page 35
def SharedAxisDemo():
"""
Shared Axis Demo
https://matplotlib.org/gallery/subplots_axes_and_figures/shared_axis_demo
"""
ax1 = plt.subplot(311)
plt.plot(t, s1)
plt.setp(ax1.get_xticklabels(), fontsize=6)
# share x only
ax2 = plt.subplot(312, sharex=ax1)
plt.plot(t, s2)
Python
Python page 36
plt.setp(ax2.get_xticklabels(), visible=False)
# share x and y
ax3 = plt.subplot(313, sharex=ax1, sharey=ax1)
plt.plot(t, s3)
plt.xlim(0.01, 5.0)
plt.show()
def ScatterPlotWithHistogramDemo():
"""
Scatter plot with histograms
https://matplotlib.org/gallery/lines_bars_and_markers/scatter_hist.html
"""
# the random data
x = np.random.randn(1000)
y = np.random.randn(1000)
ax_scatter = plt.axes(rect_scatter)
ax_scatter.tick_params(direction='in', top=True, right=True)
ax_histx = plt.axes(rect_histx)
ax_histx.tick_params(direction='in', labelbottom=False)
ax_histy = plt.axes(rect_histy)
ax_histy.tick_params(direction='in', labelleft=False)
Python
Python page 37
ax_histx.set_xlim(ax_scatter.get_xlim())
ax_histy.set_ylim(ax_scatter.get_ylim())
plt.show()
def ContourDemo():
"""
Contour Demo
https://matplotlib.org/gallery/images_contours_and_fields/contour_demo.ht
"""
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2
fig, ax = plt.subplots()
CS = ax.contour(X, Y, Z)
ax.clabel(CS, inline=1, fontsize=10)
ax.set_title('Simplest default with labels')
plt.show()
SharedAxisDemo()
ScatterPlotWithHistogramDemo()
ContourDemo()
Python
Python page 38
# Show as DM image
DM.CreateImage( Mono ).ShowImage()
#Specify User-Set Parameters (500, 1024, 4) are recommended for first try
#Larger values for any of these parameters will increase the time required
NUM_STARS_PER_ARM = 500
IMAGE_SIZE = 1024
KERN_SIZE = 4
Python
Python page 39
y1 = np.exp(b*(th))*np.sin(th+np.pi)
sx = np.random.normal(0, 0.25, n)
sy = np.random.normal(0, 0.25, n)
xc = np.concatenate(((x+sy),(x1+sx)))
yc = np.concatenate(((y+sx),(y1+sy)))
dmax = 1.01*max(max(np.abs(xc)),max(np.abs(yc)))
DM.CreateImage(image_data).ShowImage()
Python
Python page 40
# Execute DM script
DM.ExecuteScriptString( dmScript )
Python
Python page 41
number id = StemSI.ImageGetID()
number nCh = StemSI.ImageGetDimensionSize(2)
number nPts = StemSI.ImageGetDimensionSize(0) * StemSI.ImageGetDimensionS
// Build Python-script
string pyScript = "# This is a Python script"
pyScript += "import numpy as np" + "\n"
pyScript += "import sklearn" + "\n"
pyScript += "from sklearn.decomposition import NMF" + "\n"
Python
Python page 42
// Continue with DM-script after results have been created and shown by P
image compStack := GetFrontImage()
compStack.SetName( "NMF components of '" + StemSI.ImageGetName() + "'" )
return compStack
}
Python
Python page 43
ax1.grid(True)
1.4 Reference
Reference
From Python scripting you can access the major classes of objects in DigitalMicrograph and control
the Camera or a DigiScan. You can also communicate with the microscope.
The DigitalMicrograph namespace contains general functions as well as functions that create and
provide access to instances of the classes. The individual classes provide access to the properties
and behavior of the objects they represent.
namespace DigitalMicrograph
class Py_Window
class Py_ImageDocument
class Py_Image
Python
Python page 44
class Py_Component
class Py_ImageDisplay
class Py_LinePlotImageDisplay
class Py_ROI
class Py_ScriptObject
class Py_TagGroup
class Py_Camera
class Py_Microscope
Python
Index page 45
Index
I
ImageDisplays 27
Python