Scripting Resources for DigitalMicrograph™

Banner Image

Dave Mitchell's DigitalMicrograph™ Scripting Website

Home | Scripts | Examples | Functions | Recent Updates | Tutorials | Resources | Publications | Consulting | Projects | Contact & Bio | Private | Search

Tutorial: Script Commands to Interact with Microscopes and Cameras

Microscope Commands

Gatan have provided a series of generic commands for interacting with microscopes. There are also instrument specific commands which may work. For example, I have written a large number of scripts for communicating with JEOL 2000FXII and 2010 instruments via a serial interface (eg 'Save JEOL Microscope Configuration'). These scripts worked by simply sending JEOL commands to the microscope via the serial interface. These are the same commands that you can type directly into the microscope (up to about JEM-2011 vintage). The JEOL command language is rather arcane, and of course serial communications are notoriously unreliable. Fortunately, modern microscopes (eg JEOL 1400, 2100, 2200) communicate via ethernet and the high level Gatan generic commands are handled by the communications interface with the specific microscope. You need this interface working before these commands will work. If your DigitalMicrograph system sources such things as magnification automatically, then you have working communications. In principal, using these generic commands should be straightforward. Since Gatan support them, you should find they continue to work through software updates. If you can possibly use the generic commands in preference to the instrument specific ones, please do so.

For an example of the use of EM commands, see my TEM Control script. I have used these EM commands on a modern JEOL 2100 with ethernet communication. I found I didn't need to bother with any of the communication set up/close functions or with the prepare commands. It may be that these are necessary for systems using Serial communication only. Try using the EM functions without invoking these in the first instance to see if it works.


Generic (Gatan supported) EM Commands (GMS 1.x)

I am indebted to Phil Ahrenkiel, Gareth Vaughn, Christoph Gammer and others for expanding my original list quite significantly.This list now looks like a useful set of tools. Note double refers to a two-byte number variable. Where variables are referred to as just 'number' these too may be double precision, but I have not tested this. The same applies to number variables described as long - the lack of consistency reflects the varied sources of this information. An * denotes a variable passed into the function eg in the various 'get' functions where the passed in variable has the relevant value assigned to it ie this is a variable not a direct numeric value such as 42 (which is, after all, the answer to life, the universe and everything). In the 'set' functions either a variable can be provided which contains the value, or a direct numeric value can be supplied to set the value. This notation is not used consistently below - so use context as a guide). If you discover any more EM commands, please let me know, and I'll keep this list updated. The support status of these commands by Gatan is not clear, so functions may change or stop working when software gets updated - but probably not.


void EMSetFocus( long focus )
long EMGetFocus( void )
void EMChangeFocus(number df)            //Change the focus by df


number EMGetMagIndex()
EMSetMagIndex(number index)

EMGetMagnification( void )
void EMSetMagnification( double mag )
Boolean EMGetMagnification( float *mag )
Boolean EMCanGetMagnification()
Boolean EMCanGetMagnification( Boolean *can )
number EMGetMagnification(void)


void EMSetBrightness( long brightness )
long EMGetBrightness( void )

Spot Size

number EMGetSpotSize(void)    ; // Spot Size-1
void EMSetSpotSize(number nSpot)            //nSpot=SpotSize-1


void EMPrepareTilt( )
void EMChangeTilt(number x,number y)            //Change the tilt by x,y
void EMSetBeamTilt( long tiltX, long tiltY )
void EMGetBeamTilt( long *tiltX, long *tiltY )


void EMPrepareImageShift( )
void EMPrepareShift( )
void EMImageShift(number x,number y)            //Shift the image by x,y.
void EMBeamShift( number x,number y)            //Shift the beam by x, y

void EMSetImageShift( long shiftX, long shiftY )
void EMGetImageShift( long *shiftX, long *shiftY )
void EMSetBeamShift( long shiftX, long shiftY )
void EMGetBeamShift( long *shiftX, long *shiftY )

Camera Length

void EMSetCameraLength( double cam )
double EMGetCameraLength( void )
Boolean EMCanGetCameraLength( void)

High Tension

void EMSetBeamEnergy( double beamEnergy )
void EMGetHighTensionOffsetRange( double *minVal, double *maxVal )
void EMSetHighTensionOffset( double offset )
double EMGetHighTensionOffset( void )

void EMSetHighTensionOffsetEnabled( Boolean )
Boolean EMGetHighTensionOffsetEnabled( void )
threadsafe Boolean EMHasHighTensionOffset( void )
double EMGetHighTension( void )
Boolean EMCanGetHighTension( void )


void EMSetStagePositions(long axisFlags, double x, double y, double z, double a, double b)
void EMGetStagePositions(long axisFlags, double *x, double *y, double *z, double *a, double *b)
number EMGetStageXY(double x, double y)
void EMSetStageXY(double x, double y

double EMGetStageX(void)            //um
double EMGetStageY(void)            //um
number EMGetStageZ(void)            //um

void EMSetStageX(number X)            //um
void EMSetStageY(number Y)            //um
void EMSetStageZ(number Z)            //um

number EMGetStageAlpha(void)            //deg
number EMGetStageBeta(void)            //deg
void EMSetStagealpha(double a)
void EMSetStageBeta(double b)


void EMPrepareStigmation( )
void EMChangeStigmation(number x,number y)// Change the stigmation by x, y.

EMGetObjectiveStigmation(number stigX, number stigY)
EMSetObjectiveStigmation(number stigX, number stigY)

EMGetCondensorStigmation(number stigX, number stigY)
EMSetCondensorStigmation(number stigX, number stigY)

Column modes/settings//utility etc.

dm_string EMGetOperationMode( void )
void EMSetIlluminationMode( dm_string mode )
void EMSetImagingOpticsMode( dm_string mode )
void EMSetMicroscope( dm_string microscopeName)

Boolean EMUnitTest( dm_string test_options)
Boolean EMIsReady( void )
void EMWaitUntilReady( void )
Boolean EMInitialize( void )
Boolean EMIsMicroscopeInitialized( void )

TagGroup EMGetImagingOpticsModes( void )
dm_string EMGetImagingOpticsMode( void )
Boolean EMCanGetImagingOpticsMode( void )

Boolean EMIsSTEMMode( char *mode )
Boolean EMIsTEMMode( char *mode )
Boolean EMIsDiffractionMode( char *mode )
Boolean EMIsImagingMode( char *mode )


void EMSetupCommunication( void )
void EMCloseCommunication( void ) //Close communication to the microscope.

Low-level access to serial port

number EMGetSerialReadQueue(void)
string EMSerialReadHex(number numBytes )
void EMSerialWriteHex(string hexMessage )


Generic (Gatan-supported) EM Commands (GMS 2.x)

When I first started writing DM scripts to control a microscope it was around the late 90's and I was working with serial controlled JEOL TEMs. This class of microscope had their own internal command language. Commands could be entered at the internal JEOL keyboard. Although the syntax was a bit clunky and the response slow, I could control virtually any aspect of the microscope, from raising the screen to ramping the HT. The DM script simply had to squirt the relevant JEOL command along the serial line as text and off the microscope went and did its thing. Oh happy days. Gatan built into DM a series of generic microscope control commands (the EM commands). These allowed one to do many things. The microscope interface plugin (JEOLCOMM in the case of JEOL microscopes) took care of converting these commands into something which the microscope could understand. All well and good, as it meant scripters could write code which should work on all brands of microscope. However, the rot seems to have set in. In my last job I was trying to control an FEI Osiris microscope and some functionality was locked out by the manufacturer. What I was trying to do was control the HT, and so perhaps it was deemed that external code changing HT on a FEG is a bad idea - hence the lockout. What appears below is the current listing of EM Commands as of GMS 2.30. As you will see some of the functionality which used to be available in GMS 1.x is gone. For example the ability to change the microscope mode (TEM/Diffraction). I don't know whether this is down to Gatan or the microscope vendors. Either way, I have to say this is a retrograde step. Microscopy grows ever more sophisticated and users wish to have ever better control over their microscopes and microscopy experiments. If anyone who reads this is in any position to do anything about it, please do so. I want full control external over everything on my microscope. OK I could forego being able to change the extraction voltage on the FEG and opening and closing vacuum valves - but everything else I want to control - including the HT, the microscope mode, individual lenses, deflectors and stigmators. I know I am not alone in this.


Boolean EMCanGetCameraLength( )
Boolean EMCanGetHighTension( )
Boolean EMCanGetIlluminationMode( )
Boolean EMCanGetImagingOpticsMode( )
Boolean EMCanGetMagnification( )

void EMChangeBeamShift( Number xAmount, Number yAmount )
void EMChangeBeamTilt( Number xAmount, Number yAmount )
void EMChangeCalibratedBeamShift( Number xAmount, Number yAmount )
void EMChangeCalibratedBeamTilt( Number xAmount, Number yAmount )
void EMChangeCalibratedFocus( Number amount )

void EMChangeCalibratedImageShift( Number xAmount, Number yAmount )
void EMChangeCalibratedObjectiveStigmation( Number xAmount, Number yAmount )
void EMChangeCondensorStigmation( Number xAmount, Number yAmount )
void EMChangeFocus( Number amount )
void EMChangeImageShift( Number xAmount, Number yAmount )

void EMChangeObjectiveStigmation( Number xAmount, Number yAmount )
void EMGetBeamShift( NumberVariable shiftX, NumberVariable shiftY )
void EMGetBeamTilt( NumberVariable tiltX, NumberVariable tiltY )
Number EMGetBrightness( )
void EMGetCalibratedBeamShift( NumberVariable shiftX, NumberVariable shiftY )

void EMGetCalibratedBeamTilt( NumberVariable tiltX, NumberVariable tiltY )
Number EMGetCalibratedCameraLength( String deviceLocation, TagGroup stateInfo, NumberVariable calCL, Number matchOptions )
Number EMGetCalibratedFieldOfView( String deviceLocation, TagGroup stateInfo, NumberVariable calFOV, Number matchOptions )
Number EMGetCalibratedFocus( )
void EMGetCalibratedImageShift( NumberVariable shiftX, NumberVariable shiftY )

Number EMGetCalibratedMag( String deviceLocation, TagGroup stateInfo, NumberVariable calMag, Number matchOptions )
void EMGetCalibratedObjectiveStigmation( NumberVariable stigX, NumberVariable stigY )
TagGroup EMGetCalibrationStateTags( )
Number EMGetCameraLength( )
void EMGetCondensorStigmation( NumberVariable stigX, NumberVariable stigY )

Number EMGetFocus( )
Number EMGetHighTension( )
String EMGetIlluminationMode( )
TagGroup EMGetIlluminationModes( )
EMGetIlluminationModes().TagGroupOpenBrowserWindow("Available Illumination Modes",0)void EMGetImageShift( NumberVariable shiftX, NumberVariable shiftY )
String EMGetImagingOpticsMode( )

TagGroup EMGetImagingOpticsModes( )
TagGroup modes = EMGetImagingOpticsModes()
Number EMGetMagIndex( )
Number EMGetMagnification( )
String EMGetMicroscopeName( )
void EMGetObjectiveStigmation( NumberVariable stigX, NumberVariable stigY )

String EMGetOperationMode( )
Number EMGetScreenPosition( )
Number EMGetSpotSize( )
Number EMGetStageAlpha( )
Number EMGetStageBeta( )

void EMGetStagePositions( Number axisFlags, NumberVariable x, NumberVariable y, NumberVariable z, NumberVariable a, NumberVariable b )
void EMGetStageXY( NumberVariable x, NumberVariable y )
Number EMGetStageX( )
Number EMGetStageY( )
Number EMGetStageZ( )

Boolean EMIsReady( )
void EMSetBeamShift( Number shiftX, Number shiftY )
void EMSetBeamTilt( Number tiltX, Number tiltY )
void EMSetBrightness( Number brightness )
void EMSetCalibratedBeamShift( Number shiftX, Number shiftY )

void EMSetCalibratedBeamTilt( Variable tiltX, Variable tiltY )
void EMSetCalibratedFocus( Number focus )
void EMSetCalibratedImageShift( Number shiftX, Number shiftY)

void EMSetCalibratedObjectiveStigmation( Number stigX, Number stigY )
void EMSetCondensorStigmation( Number stigX, Number stigY )
Number EMSetFocus( Number focus )
void EMSetImageShift( Number shiftX, Number shiftY )
void EMSetMagIndex( Number index )

void EMSetObjectiveStigmation( Number stigX, Number stigY )
void EMSetScreenPosition( Number pos )
void EMSetSpotSize( Number spotSize )
void EMSetStageAlpha( Number a )
void EMSetStageBeta( Number b )

void EMSetStagePositions( Number axisFlags, Number x, Number y, Number z, Number a, Number b )
void EMSetStageXY( Number x, Number y )
void EMSetStageX( Number x )
void EMSetStageY( Number y )
void EMSetStageZ( Number z )
void EMUpdateCalibrationState( )
void EMWaitUntilReady( )



Gatan Camera Manager commands

I am indebted to Phil Ahrenkiel for the information in the quick reference section below. This contains many of the commonly used Camera Manager (CM) commands. Previously the SSC-series of commands would have been used for camera access. This new set of commands provides a wealth of extra functionality and control. The SSC commands are probably still supported, but I have not tested this.

A more complete listing of all the CM commands (courtesy of Gatan) along with additional supporting information can be downloaded as a text file. The file is a .s file. This is plain text, the same as a DM script. It can be opened in any text editor or in DigitalMicrograph.






There are two main coordinate systems used when specifying readout area on a CCD, raw coordinates

and binned coordinates. Raw coordinates for a CCD map the accessible active area of the CCD and

are not affected by camera orientation, binning, or readout transposition. The coordinates are

label the effective CCD pixels with values in [0,ccd_width-1]x[0,ccd_height-1], where the effective

active area of the CCD has size (ccd_width,ccd_height). An effective CCD pixel is the smallest

grouping of CCD pixels distinguishable via the controller ( for some MSC's, for example, the controller

bins the CCD pixels by '2' to get an effective CCD area of 2048x2048 from a 4096x4096 CCD ).

Binned coordinates for a given set of acquisition parameters are affected by the default camera

orientation and the binning and transpose in the acquisition parameters. The coordinates are

determined by the largest image that can be read by enlarging the raw CCD coordinates of the acquisition

parameters, but leaving all other settings constant. This is the coordinate system used when

specifying read area in old-style 'SSC*Acquire' commands. Note if a CCD dimension is not divisible

by the binning in that dimension, then there is some ambiguity about which CCD pixels make up

each binned pixel: for ccd size (ccd_width,ccd_height) and binning '(bin_x,bin_y)', binned pixel

(0,0) can have any CCD pixel in the range [0,mod(ccd_width,bin_x))x[0,mod(ccd_height,bin_y)) as its

top-left pixel. When setting the read area of a set of acquisition parameters in terms of binned pixels

the ambiguity is resolved using the alignment of the top-left binned pixel in the current read area in CCD



Camera orientation and image transpositions are described by a number which encodes a transformation generated

by 90 degree rotations and reflections. The number consists of three flags at bits '0', '1', and '8', where

with any diagonal flip performed after any horizontal or vertical flip. In terms of rotation followed

by a horizontal flip, the values represent




The camera orientation is specified in the camera by a default transpose. By default, after an acquisition the resulting image is transposed by the default transpose before being placed in an image.


The following are only available for cameras with controller class "MSC" or "FirstLight"




Currently, there are two levels of software control of temperature: none and full. Full control

basically means the camera supports reading the current temperature, specifying a set point temperature,

and checking whether the temperature has stabilized at the set point ( currently only cameras with

controller class "PICM" support this ). On top of this are implemented 'startup', 'shutdown' and 'target'

temperatures. While the camera is active, if a 'target' temperature is set, the camera temperature is

brought to the target temperature in the background at a maximum rate specified by the maximum temperature

change rate. The 'startup' temperature if specified is used as the initial target temperature, and the

'shutdown' temperature is made the set point of the camera when the camera is deactivated.


The following functions are used to create a base camera acquisition parameter set. The parameters specify

an unprocessed ( except for defect correction ), unbinned read of the entire CCD with exposure '1.0' seconds.

Most of the remainaing parameters in effect are copied from the 'Record' parameter set, except that all extra

processing ( including auto-exposure and frame summing ) is turned off. The only exceptions are that the

functions containing 'View' are set to prefer continuous readout, and if the camera has a range of readout

qualities the 'Low', 'Medium', and 'High' specify a level.

The following functions are for manipulating the standard, persisted camera acquisition parameters, currently

just 'Search', 'Focus', and 'Record'. In general, persistent parameter sets can be created using the first

function by specifying a mode name, style name, and parameter set name. Parameter sets so created are linked

to a location in the global tags, so calling 'CM_LoadCameraAcquisitionParameterSet' will initialize the parameter

set with settings from tags, and 'CM_SaveCameraAcquisitionParameterSet' will save the parameter set to tags.

Parameter sets created by other means are not linked to a tag location and will fail if either of those functions

are called. To create a parameter set linked to one of the standard persisted sets, use the following:

Acquisition Parameters:


Shutter-Related Readout Parameters

Extra processing


Given a 'camera' and an arbitrary set of acquisition parameters 'acq_params', 'CM_Validate_AcquisitionParameters'

can be used to ensure that the parameters have appropriate settings, and 'CM_CameraCalcImageForm' can be used

to determine an appropriate size and data type. 'CM_AcquireImage' can be used to acquire a single image as

specified by 'acq_params'.


JEOL-Specific Commands

(I'm sure there must be more?)

JEOLCOM_SetScreen(0) //set fluorescent to 0°
JEOLCOM_SetScreen(1) //set fluorescent to 7°
JEOLCOM_SetScreen(2) //set fluorescent to 90°


Philips-Specific Commands

I am indebted to Steffen Meyer of Gatan for compiling this list.

Number CMTurnKnob(Number whichknob, Number steps )

double CM(void)
dm_string CMGetVersion(void)
dm_string CMGetInstrument(void)
void CMShowVers(void)

Number CMSetUpCommunication(void)
Number CMCloseCommunication(void)
Number CMChangeFocus(Number amount)
Number CMChangeMag(Number amount)
Number CMSetSpot(Number amount)
Number CMChangeC2(Number amount)
Number CMSetFine(void)
Number CMSetCoarse(void)
Number CMStigOn(void)
Number CMStigOff(void)
Number CMDfOn(void)
Number CMDfOff(void)
Number CMChangeShift(Number xamount,Number yamount)
Number CMChangeMulti(Number xamount,Number yamount)
Number CMSetMag(Number amount)
Number CMSetLowDose(void)
Number CMBlankOn(void)
Number CMBlankOff(void)
Number CMReset(void)
Number CMReady(void)
Number CMExposure(void)
Number CMPressSoftKey(Number whichkey,Number unmofTimes)

Number CMTiltGoniometerTo(Number degrees)
Number CMXGoniometerTo(Number position)
Number CMYGoniometerTo(Number position)