Single Particle Data Collection Using SerialEM

Author:

Chen Xu

Contact:

<chen.xu@umassmed.edu>

Date created:

Oct 18, 2016

Last updated:

Apr 29, 2025

Abstract

This document is to list step-by-step operations to perform single particle data collection using SerialEM. I often receive requests to provide script/macro for single particle data collection using SerialEM as control program. It is not very easy to explain that script/macro itself is only the small portion of whole operation steps. I realized that a brief but detailed protocol for whole process is perhaps more useful, specially for novice cryoEM users. It should be useful for more experience users as well as a quick checklist in case some step is forgotten. I wrote something similiar at Brandeis EM webpage, but here I rewrite this to reflect newer hardware of microscope and camera, and with updated SerialEM scripts/macros.

A Krios with K2 Summit camera and FEI Ceta camera is the base hardware setup for this protocol.

Note

This doc is a working progress. If you have comment and suggestion, please let me know. Thank you!

Check Scope Condition and Perform Tuning

Before you commit large dataset time, it is always a good idea to check scope condition to make sure everything is good. Calm down and be patient! Here are a few things I usually check.

  • Check Gun Lens, Extracting Voltage, High Tension are set at correct values.

  • Stare for a few seconds at the focused beam at the highest SA mag, to see if the beam has good shape and there is no shaking or jumping.

  • From Direct Alignment, do gun tilt, beam tilt PP, Coma-Free alignment if needed.

  • Check Thon Ring at roughly the same condition (mag, dose) as your image condition. Make sure there is no obvious frequency cutoff, and Thon Ring reaches the resolution as in good condition.

Prepare Cameras

For K2 camera, perform full procedure to prepare backgrounds from DM interface. This include software and hardware backgrounds. The hardware background file is for processor to use, while the software gain reference files sit in K2 computer for final software image correction. I was told the software gain reference was more stable than hardware background, but not sure this is still the case. Any way, just perform the full procedure following DM steps.

  • After preparing camera, take a single shot with proper dose rate (~5-10 e/pix/s) for 1 second with no specimen and do an FFT. The FFT should show clean background without strong center cross or lines. - For Ceta camera, do the same from FEI user interface.

Make Low Mag Montage (LMM) Map or Grid Atlas

It saves time with large area detector. Therefore, Ceta camera is probably better for this step.

  • Select Ceta from Camera Control Setup

  • Insert/load your cryo grids

  • Set mag at ~87X, retract Obj Aperture

  • Spread beam to cover whole Ceta camera area

  • Start SerialEM if not yet

  • Select Ceta from SerialEM camera control setup and FEI Camera ocx.

  • Setup camera condition from SerialEM: Record (e.g. bin=4, exposure=0.4); a Record image gives proper counts (~2000)

  • Navigator menu -> Open

  • Navigator menu -> Montaging & Grids -> Setup Full Montage; define montage file to open

  • Montage Control Panel -> Start

  • Click “Yes” to make final overview of montage into a map

  • Close the montage file

Tip

If you are not happy with the aligning of the pieces, you may check and uncheck boxes like “Treat sloopy…” and reload the map.

Setup Low Dose Condition

You should have known how to setup Low Dose condition already. Here are some tips.

  • Turn on Low Dose Mode from SerialEM Low Dose control panel

  • Setup R beam first so that dose on detector and on specimen are all good.

  • Defocus offset 100um for View is usually a good start.

  • Always cycle “area” (low dose mode) in one directional looped fashion, i.e., V-F-T-R-V…

  • Using the same spotszise for all the areas (low dose modes) is a good idea.

Make Medium Mag Montage Maps

  • select K2 camera from Camera Control Setup (from now on)

  • add a polygon (a mesh) in LMM map

  • add points for good meshes at center

  • add one landmark such as a dirt point in LMM map

  • take the landmark into View image (you may use FlowCam to move that feature into middle first.)

  • while landmark point being current (highlighted), left click on the landmark in View image, a green cross will appear

  • Navigator menu -> Shift to Marker -> Yes (this will change all the coordinates for all the navigator items)

  • highlighting polygon item on navigator window, so it is currently selected

  • Navigator menu -> Montaging & Grids -> Setup Polygon Montage -> Check “using View …” in the dialog window -> define montage filename.

  • Add flag “A” to all the interested mesh point items

  • Navigator menu -> Acquire At Points … -> Check “Eucentric Rough” in Pre-action and “Acquire Montage Map” in main action

  • When finished, the MMM maps should be added to Navigator windows. You perhaps can close the montage file now.

Draw Grids Points for Each Mesh

For each of the MMM map, do the following steps to add group points.

  • add a polygon item to exclude bad area

  • add 5 point items to define grid geometry

  • make any of the 5 items in the group is currently selected

  • Navigator menu -> Montaging & Grids -> Set Group Size (10um is a good start)

  • Navigator menu -> Montaging & Grids -> Check “Divide point into Groups”

  • Navigator menu -> Montaging & Grids -> Add Grid Points -> give polygon item number -> Flag “A” for all

Test Main Script to Run

A very simple script for single particle can look like this:

buffer = T
RealignToNavItem 0
ResetImageShift 2
#Copy A $buffer     #comment out if a fixed template in $buffer is used.
AcquireToMatchBuffer $buffer
AlignTo $buffer 0 1

#AutoCenterBeam
CycleTargetDefocus -0.5 -1.5 10
Autofocus

# use one of following lines
#Record
MultipleRecords

Lets load the script to script editor and try to run it.

LD-Group.txt
  1ScriptName LD-Group
  2
  3## when to perform CenterBeam and AutoFocus, and defocus range
  4groupOption = 1                 # 1 = at group head, 0 = at every item 
  5defLow = -1.0 
  6defHigh = -2.5
  7step = 0.1  
  8
  9## Drift control
 10driftControl = 1                # 1 = yes, 0 = no
 11limit = 3.0                     # Angstroms
 12
 13## X,Y positioning
 14templateOption = 1              # 1 = to use a fixed ref, 0 = use dynamic one
 15refBuffer = P                   # reference buffer for template image
 16
 17## Multi or single shot
 18multiShot = 1                   # 1 = multishit, 0 = single shot
 19
 20########## no edit below ##########
 21RealignToNavItem 0
 22ResetImageShift 2
 23If $templateOption == 1
 24    Echo  --- assuming you have a template image in buffer $refBuffer ---
 25Else
 26    Copy A $refBuffer           # use dynamic ref (whole image itself)
 27Endif 
 28AcquireToMatchBuffer $refBuffer
 29AlignTo $refBuffer 0 1
 30
 31## turn ON drift protection if it's off so Autofocus can report drift
 32ReportUserSetting DriftProtection DP 
 33If $DP == 0
 34    SetUserSetting DriftProtection 1 1
 35Endif     
 36
 37## center beam & focus
 38ReportGroupStatus gs            # 1 = group head, 0 = inividual, 2 = group member
 39If $groupOption == 0
 40    #AutoCenterBeam             
 41    CallFunction CycleTargetDefocus $defLow $defHigh $step
 42    AutoFocus
 43Else
 44    If $gs == 1 OR $gs == 0     
 45        #AutoCenterBeam         
 46        CallFunction CycleTargetDefocus $defLow $defHigh $step
 47        AutoFocus
 48    Else
 49        Echo    group member, skip focusing...
 50    Endif 
 51Endif
 52
 53## drift                        # if reported drift is high, call drift control
 54If $driftControl == 1
 55   ReportFocusDrift FD 
 56   If $FD > 0.09                # 0.09 reported here is close to real 2.0A/s.   
 57     CallFunction Drift $limit
 58   Endif 
 59Endif
 60
 61## shot
 62AdjustBeamTiltforIS             # needed for single shot, so leave it here regardless
 63If multiShot == 1
 64    MultipleRecords
 65Elseif multiShot == 0
 66    Record
 67Endif 
 68
 69## post-exposure
 70RefineZLP 30                    # refine ZLP every 30 minutes
 71
 72####### Functions
 73Function CycleTargetDefocus 3 0 defLow defHigh step
 74Echo ===> Running CycleTargetDefocus ...
 75Echo   --- Range and Step (um)  => [ $defLow, $defHigh ], [ $step ] ---
 76
 77delta = -1 * $step
 78SuppressReports
 79ReportTargetDefocus tarFocus
 80If $tarFocus > $defLow OR $tarFocus < $defHigh
 81   SetTargetDefocus $defLow
 82Else 
 83   IncTargetDefocus $delta
 84   ChangeFocus $delta
 85Endif
 86
 87ReportTargetDefocus 
 88EndFunction
 89
 90######
 91Function Drift 1 0 crit 
 92# A function to measure drift rate, if good, skip to the end of loop. 
 93# Otherwise, exit execution -- i.e. skip the point. 
 94Echo ===> Running Drift $crit (A)...
 95
 96shot = F
 97interval = 4
 98times = 10
 99
100period = $interval + 1
101$shot
102Delay $interval
103Loop $times index
104   $shot
105   AlignTo B
106   ReportAlignShift
107   ClearAlignment
108   dx = $repVal3
109   dy = $repVal4
110   dist = sqrt $dx * $dx + $dy * $dy
111   rate = $dist / $period * 10	
112   echo Rate = $rate A/sec
113   echo ----------------
114
115   If $rate < $crit
116      echo Drift is low enough after shot $index      
117      break
118   Elseif  $index < $times
119      Delay $interval
120   Else
121     echo Drift never got below $crit: Skipping ...
122     exit   
123   Endif
124EndLoop
125EndFunction

This script calls two functions - CycleTargetDefocus and Drift. This is a standalone script. Some other functions can found here on github.com.

If running with python support, the code looks something like this:

LD-Group-Python.txt
  1#!Python
  2#ScriptName LD-Group-Python
  3import serialem
  4from math import sqrt
  5
  6### user defined parameters
  7# when to do focus and center beam, set range
  8groupOption = 1         # 1 = only group head, 0 = every item
  9defLow, defHigh, step = -1.0, -2.5, 0.1
 10
 11# drift control, limit 
 12driftControl = 1        # 1 = yes, 0 = no 
 13limit = 3.0
 14
 15# for X,Y position
 16templateOption = 1      # 1 = use fixed ref, 0 = dynamic one (whole image)
 17refBuffer = 'P'
 18
 19# multi or single shot
 20multiShot = 1           # 1 = multi, 0 = single
 21
 22#### no editing below ####
 23
 24### Functions
 25def CycleTargetDefocus(defLow, defHigh, step):
 26    print(' ---> running CycleTargetDefocus ...')
 27    print(' --- defLow, defHigh, step = ', defLow, defHigh, step, '---')
 28    serialem.SuppressReports()
 29    tarFocus = serialem.ReportTargetDefocus()   # float
 30    if tarFocus > defLow or tarFocus < defHigh:
 31        serialem.SetTargetDefocus()
 32    else:
 33        serialem.IncTargetDefocus(-step)
 34        serialem.ChangeFocus(-step)
 35    serialem.ReportTargetDefocus()
 36
 37def Drift(crit):
 38    print(' ---> Running Drift ', crit, 'A ...')
 39    shot = serialem.Focus                       # without () -> alias to function reference itself
 40    interval = 4
 41    times = 10
 42    period = interval + 1
 43    #
 44    shot()
 45    serialem.Delay(interval)
 46    for index in range(1, times+1):
 47        shot()
 48        serialem.AlignTo('B', 0, 1)
 49        aliShift = serialem.ReportAlignShift()
 50        dx, dy = aliShift[2], aliShift[3]
 51        rate = sqrt(dx*dx + dy*dy)/period*10
 52        print(' Rate =', rate, 'A/sec')
 53        if rate < crit:
 54            print('Drift is low enough after shot ', index)
 55            break
 56        elif index < times:
 57            serialem.Delay(interval)
 58        else:
 59            print('Drift never got below ', crit, 'skipping...')
 60            serialem.Exit()
 61
 62### main
 63
 64serialem.RealignToNavItem(0)
 65serialem.ResetImageShift(2)
 66if templateOption == 1:
 67    print(' --- assuming a template image in buffer', refBuffer, '---')
 68elif templateOption == 0:
 69    serialem.Copy('A', refBuffer)
 70else:
 71    print('templateOption needs to be 0 or 1, please fix it and continue')
 72    serialem.exit()
 73serialem.AcquireToMatchBuffer(refBuffer)
 74serialem.AlignTo(refBuffer, 0, 1)
 75
 76# turn on Autofocus drift protection so it reports drift rate
 77DP = serialem.ReportUserSetting('DriftProtection')    # float
 78if DP == 0.:
 79    serialem.SetUserSetting('DriftProtection', 1, 1)
 80
 81# center beam and defocus
 82gs = serialem.ReportGroupStatus()      # tuple
 83gs = gs[0]                             # now a float
 84if groupOption == 0:
 85    serialem.AutoCenterBeam()
 86    CycleTargetDefocus(defLow, defHigh, step)
 87    serialem.Autofocus()
 88else:
 89    if gs == 1. or gs == 0.:
 90        serialem.AutoCenterBeam()
 91        CycleTargetDefocus(defLow, defHigh, step)
 92        serialem.AutoCenterBeam()
 93    else:
 94        print('   group member, skip focusing ...')
 95
 96# drift 
 97if driftControl == 1:
 98    FD = serialem.ReportFocusDrift()
 99    if FD > 0.09:
100        Drift(limit)
101
102# shot
103serialem.AdjustBeamTiltforIS()      # keep this line 
104if multiShot == 1:
105    serialem.MultipleRecords()
106elif multiShot == 0:
107    serialem.Record()
108
109# post-expose
110serialem.RefineZLP(30)              # if GIF exists 
111

This is a good time to test running this script on one of the point items in navigator window, to make sure it runs fine.

Final Checking

Now we should check to make sure all the conditions are good for batch data collections for hours and days.

  • Low Dose beams lined up for all the modes (area is the term SerialEM uses)

  • Record beam has proper intensity

  • Objective aperture is inserted and centered

  • Objective Stigmation is good

  • Thon ring with R beam on carbon area shows good scope condition

  • Total exposure time, frame time, total frame number, binning, output file options, frame saving folder etc. are all good.

Run it!

Navigator -> Acquire at Points… -> Run Script “LD-Group” in Main action -> OK.