Gonimeter calibration
Added by Anonymous almost 16 years ago
I was doing the Modeled Stage Position calibration, but whenever I run the Goniomodeling "Measure" button after entering in my settings, the node would begin to "Aquire Point 0" and remain 'stuck' there with no updates on the log. I set it to collect 25 points but it's been running for 25 minutes without any sign of progress. It did invoke the correction node right before it began measuring, but there were no errors from it. Also, the stage hasn't moved at all.
I guess I should mention that I didn't do the Stage Posittion matrix calibration because the manual mentioned it was optional and that there might be some redundancy if I were to do the Modeled Stage Position calibration after that. Should I go ahead and do that?
If not, do you have any suggestions on how to get the Goniometer calibrated?
Thank you for the help!
Replies (15)
Re: Gonimeter calibration - Added by Anonymous almost 16 years ago
I was revisiting the stage calibration, but when I tried to calibrate that, it also failed (the stage shift is almost zero, so it aborts). We are beginning to think the problem might be that Leginon is unable to control the stage like it does the other settings; under the navigation node, we got the error "Set Instrument failed: unable to set instrument," so this seems to imply that that's why the gonionmeter and the stage calibration under the Matrix tool are failing. We can control everything else (lenses, current, camera, etc.), it just seems that we can't control the stage using Leginon.
Any help solving this problem would be greatly appreciated!
Re: Gonimeter calibration - Added by Jim Pulokas almost 16 years ago
Here is a quick test you can do on your Tecnai PC. Start the Python command line and run the following commands:
from pyScope import tecnai
t = tecnai.Tecnai()
t.setStagePosition({'x': 0, 'y': 0, 'z': 0})That is a short script to center the stage x,y,z to 0,0,0, and you can try it with different values.  The units are meters, so to set x = 20 micron, you would say 'x': 2e-5.Let me know if running this script gives you an error message.
Re: Gonimeter calibration - Added by Anonymous almost 16 years ago
Thanks for the response; this is what I got after I tried running that script:
C:\>python
Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyScope import tecnai
>>> t = tecnai.Tecnai()
>>> t.setStagePosition({'x':0,'y':0,'z':0})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python25\lib\site-packages\pyScope\tecnai.py", line 114, in setStageP
osition
self._setStagePosition(prevalue)
File "C:\Python25\lib\site-packages\pyScope\tecnai.py", line 603, in _setStage
Position
axes |= getattr(win32com.client.constants, 'axis' + key.upper())
File "C:\Python25\Lib\site-packages\win32com\client\__init__.py", line 170, in
__getattr__
raise AttributeError(a)
AttributeError: axisY
>>> t.setStagePosition({'x':0, 'y':0, 'z':0})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python25\lib\site-packages\pyScope\tecnai.py", line 114, in setStageP
osition
self._setStagePosition(prevalue)
File "C:\Python25\lib\site-packages\pyScope\tecnai.py", line 603, in _setStage
Position
axes |= getattr(win32com.client.constants, 'axis' + key.upper())
File "C:\Python25\Lib\site-packages\win32com\client\__init__.py", line 170, in
__getattr__
raise AttributeError(a)
AttributeError: axisY
>>>
	I should mention that the updatecom.py script never did work properly during installation--the error that I got for that is in another thread I posted in under PyScope (viewtopic.php?f=8&t=286 ). Another thing I should mention is that the Tecnai microscope (in this case TF20) has been updated to Tecnai version 4.0; it can get images and we've calibrated the beam and image shifts, it's just the stage we can't move using Legion. Though I tried this on the TF20, I originally experienced these problems on the Tecnai T12 (both updatecom.py errors are the same). The tecnai.py script is reproduced here below:
# COPYRIGHT:
# The Leginon software is Copyright 2003
# The Scripps Research Institute, La Jolla, CA
# For terms of the license agreement
# see http://emg.nysbc.org/software/leginon-license
import tem
import time
import sys
try:
import pythoncom
import win32com.client
import winerror
try:
try:
import tecnaicom
except ImportError:
from pyScope import tecnaicom
except ImportError:
pass
try:
try:
import ldcom
except ImportError:
from pyScope import ldcom
except ImportError:
pass
try:
try:
import adacom
except ImportError:
from pyScope import adacom
except ImportError:
adacom = None
except ImportError:
pass
# if a stage position movement is less than the following, then ignore it
minimum_stage = {
'x': 5e-8,
'y': 5e-8,
'z': 5e-8,
'a': 6e-5,
}
class MagnificationsUninitialized(Exception):
pass
class Tecnai(tem.TEM):
name = 'Tecnai'
def __init__(self):
tem.TEM.__init__(self)
self.correctedstage = True
pythoncom.CoInitializeEx(pythoncom.COINIT_MULTITHREADED)
try:
self.tecnai = win32com.client.Dispatch('Tecnai.Instrument')
except pythoncom.com_error, (hr, msg, exc, arg):
raise RuntimeError('unable to initialize Tecnai interface, %s' % msg)
try:
self.lowdose = win32com.client.Dispatch('LDServer.LdSrv')
except pythoncom.com_error, (hr, msg, exc, arg):
print 'unable to initialize low dose interface, %s' % msg
self.lowdose = None
try:
self.exposure = win32com.client.Dispatch('adaExp.TAdaExp',
clsctx=pythoncom.CLSCTX_LOCAL_SERVER)
except:
self.exposure = None
self.magnifications = []
self.mainscreenscale = 44000.0 / 50000.0
def getMagnificationsInitialized(self):
if self.magnifications:
return True
else:
return False
def setCorrectedStagePosition(self, value):
self.correctedstage = bool(value)
return self.correctedstage
def getCorrectedStagePosition(self):
return self.correctedstage
def checkStagePosition(self, position):
current = self.getStagePosition()
bigenough = {}
for axis in ('x', 'y', 'z', 'a'):
if axis in position:
delta = abs(position[axis] - current[axis])
if delta > minimum_stage[axis]:
bigenough[axis] = position[axis]
return bigenough
def setStagePosition(self, value):
# pre-position x and y (maybe others later)
value = self.checkStagePosition(value)
if not value:
return
if self.correctedstage:
delta = 2e-6
stagenow = self.getStagePosition()
# calculate pre-position
prevalue = {}
for axis in ('x','y','z'):
if axis in value:
prevalue[axis] = value[axis] - delta
if prevalue:
self._setStagePosition(prevalue)
return self._setStagePosition(value)
def normalizeLens(self, lens = 'all'):
if lens == 'all':
self.tecnai.NormalizeAll()
elif lens == 'objective':
self.tecnai.Projection.Normalize(win32com.client.constants.pnmObjective)
elif lens == 'projector':
self.tecnai.Projection.Normalize(win32com.client.constants.pnmProjector)
elif lens == 'allprojection':
self.tecnai.Projection.Normalize(win32com.client.constants.pnmAll)
elif lens == 'spotsize':
self.tecnai.Illumination.Normalize(win32com.client.constants.nmSpotsize)
elif lens == 'intensity':
self.tecnai.Illumination.Normalize(win32com.client.constants.nmIntensity)
elif lens == 'condenser':
self.tecnai.Illumination.Normalize(win32com.client.constants.nmCondenser)
elif lens == 'minicondenser':
self.tecnai.Illumination.Normalize(win32com.client.constants.nmMiniCondenser)
elif lens == 'objectivepole':
self.tecnai.Illumination.Normalize(win32com.client.constants.nmObjectivePole)
elif lens == 'allillumination':
self.tecnai.Illumination.Normalize(win32com.client.constants.nmAll)
else:
raise ValueError
def getScreenCurrent(self):
return float(self.tecnai.Camera.ScreenCurrent)
def getGunTilt(self):
value = {'x': None, 'y': None}
value['x'] = float(self.tecnai.Gun.Tilt.X)
value['y'] = float(self.tecnai.Gun.Tilt.Y)
return value
def setGunTilt(self, vector, relative = 'absolute'):
if relative == 'relative':
try:
vector['x'] += self.tecnai.Gun.Tilt.X
except KeyError:
pass
try:
vector['y'] += self.tecnai.Gun.Tilt.Y
except KeyError:
pass
elif relative == 'absolute':
pass
else:
raise ValueError
vec = self.tecnai.Gun.Tilt
try:
vec.X = vector['x']
except KeyError:
pass
try:
vec.Y = vector['y']
except KeyError:
pass
self.tecnai.Gun.Tilt = vec
def getGunShift(self):
value = {'x': None, 'y': None}
value['x'] = self.tecnai.Gun.Shift.X
value['y'] = self.tecnai.Gun.Shift.Y
return value
def setGunShift(self, vector, relative = 'absolute'):
if relative == 'relative':
try:
vector['x'] += self.tecnai.Gun.Shift.X
except KeyError:
pass
try:
vector['y'] += self.tecnai.Gun.Shift.Y
except KeyError:
pass
elif relative == 'absolute':
pass
else:
raise ValueError
vec = self.tecnai.Gun.Shift
try:
vec.X = vector['x']
except KeyError:
pass
try:
vec.Y = vector['y']
except KeyError:
pass
self.tecnai.Gun.Shift = vec
def getHighTensionStates(self):
return ['off', 'on', 'disabled']
def getHighTensionState(self):
state = self.tecnai.Gun.HTState
if state == win32com.client.constants.htOff:
return 'off'
elif state == win32com.client.constants.htOn:
return 'on'
elif state == win32com.client.constants.htDisabled:
return 'disabled'
else:
raise RuntimeError('unknown high tension state')
def getHighTension(self):
return float(self.tecnai.Gun.HTValue)
def setHighTension(self, ht):
self.tecnai.Gun.HTValue = ht
def getIntensity(self):
return float(self.tecnai.Illumination.Intensity)
def setIntensity(self, intensity, relative = 'absolute'):
if relative == 'relative':
intensity += self.tecnai.Illumination.Intensity
elif relative == 'absolute':
pass
else:
raise ValueError
self.tecnai.Illumination.Intensity = intensity
def getDarkFieldMode(self):
if self.tecnai.Illumination.DFMode == win32com.client.constants.dfOff:
return 'off'
elif self.tecnai.Illumination.DFMode == win32com.client.constants.dfCartesian:
return 'cartesian'
elif self.tecnai.Illumination.DFMode == win32com.client.constants.dfConical:
return 'conical'
else:
raise SystemError
def setDarkFieldMode(self, mode):
if mode == 'off':
self.tecnai.Illumination.DFMode = win32com.client.constants.dfOff
elif mode == 'cartesian':
self.tecnai.Illumination.DFMode = win32com.client.constants.dfCartesian
elif mode == 'conical':
self.tecnai.Illumination.DFMode = win32com.client.constants.dfConical
else:
raise ValueError
def getBeamBlank(self):
if self.tecnai.Illumination.BeamBlanked == 0:
return 'off'
elif self.tecnai.Illumination.BeamBlanked == 1:
return 'on'
else:
raise SystemError
def setBeamBlank(self, bb):
if bb == 'off' :
self.tecnai.Illumination.BeamBlanked = 0
elif bb == 'on':
self.tecnai.Illumination.BeamBlanked = 1
else:
raise ValueError
def getStigmator(self):
value = {'condenser': {'x': None, 'y': None},
'objective': {'x': None, 'y': None},
'diffraction': {'x': None, 'y': None}}
value['condenser']['x'] = \
float(self.tecnai.Illumination.CondenserStigmator.X)
value['condenser']['y'] = \
float(self.tecnai.Illumination.CondenserStigmator.Y)
value['objective']['x'] = \
float(self.tecnai.Projection.ObjectiveStigmator.X)
value['objective']['y'] = \
float(self.tecnai.Projection.ObjectiveStigmator.Y)
value['diffraction']['x'] = \
float(self.tecnai.Projection.DiffractionStigmator.X)
value['diffraction']['y'] = \
float(self.tecnai.Projection.DiffractionStigmator.Y)
return value
def setStigmator(self, stigs, relative = 'absolute'):
for key in stigs.keys():
if key == 'condenser':
stigmator = self.tecnai.Illumination.CondenserStigmator
elif key == 'objective':
stigmator = self.tecnai.Projection.ObjectiveStigmator
elif key == 'diffraction':
stigmator = self.tecnai.Projection.DiffractionStigmator
else:
raise ValueError
if relative == 'relative':
try:
stigs[key]['x'] += stigmator.X
except KeyError:
pass
try:
stigs[key]['y'] += stigmator.Y
except KeyError:
pass
elif relative == 'absolute':
pass
else:
raise ValueError
try:
stigmator.X = stigs[key]['x']
except KeyError:
pass
try:
stigmator.Y = stigs[key]['y']
except KeyError:
pass
if key == 'condenser':
self.tecnai.Illumination.CondenserStigmator = stigmator
elif key == 'objective':
self.tecnai.Projection.ObjectiveStigmator = stigmator
elif key == 'diffraction':
self.tecnai.Projection.DiffractionStigmator = stigmator
else:
raise ValueError
def getSpotSize(self):
return int(self.tecnai.Illumination.SpotsizeIndex)
def setSpotSize(self, ss, relative = 'absolute'):
if relative == 'relative':
ss += self.tecnai.Illumination.SpotsizeIndex
elif relative == 'absolute':
pass
else:
raise ValueError
self.tecnai.Illumination.SpotsizeIndex = ss
def getBeamTilt(self):
value = {'x': None, 'y': None}
value['x'] = float(self.tecnai.Illumination.RotationCenter.X)
value['y'] = float(self.tecnai.Illumination.RotationCenter.Y)
return value
def setBeamTilt(self, vector, relative = 'absolute'):
if relative == 'relative':
try:
vector['x'] += self.tecnai.Illumination.RotationCenter.X
except KeyError:
pass
try:
vector['y'] += self.tecnai.Illumination.RotationCenter.Y
except KeyError:
pass
elif relative == 'absolute':
pass
else:
raise ValueError
vec = self.tecnai.Illumination.RotationCenter
try:
vec.X = vector['x']
except KeyError:
pass
try:
vec.Y = vector['y']
except KeyError:
pass
self.tecnai.Illumination.RotationCenter = vec
def getBeamShift(self):
value = {'x': None, 'y': None}
value['x'] = float(self.tecnai.Illumination.Shift.X)
value['y'] = float(self.tecnai.Illumination.Shift.Y)
return value
def setBeamShift(self, vector, relative = 'absolute'):
if relative == 'relative':
try:
vector['x'] += self.tecnai.Illumination.Shift.X
except KeyError:
pass
try:
vector['y'] += self.tecnai.Illumination.Shift.Y
except KeyError:
pass
elif relative == 'absolute':
pass
else:
raise ValueError
vec = self.tecnai.Illumination.Shift
try:
vec.X = vector['x']
except KeyError:
pass
try:
vec.Y = vector['y']
except KeyError:
pass
self.tecnai.Illumination.Shift = vec
def getImageShift(self):
value = {'x': None, 'y': None}
value['x'] = float(self.tecnai.Projection.ImageBeamShift.X)
value['y'] = float(self.tecnai.Projection.ImageBeamShift.Y)
return value
def setImageShift(self, vector, relative = 'absolute'):
if relative == 'relative':
try:
vector['x'] += self.tecnai.Projection.ImageBeamShift.X
except KeyError:
pass
try:
vector['y'] += self.tecnai.Projection.ImageBeamShift.Y
except KeyError:
pass
elif relative == 'absolute':
pass
else:
raise ValueError
vec = self.tecnai.Projection.ImageBeamShift
try:
vec.X = vector['x']
except KeyError:
pass
try:
vec.Y = vector['y']
except KeyError:
pass
self.tecnai.Projection.ImageBeamShift = vec
def getRawImageShift(self):
value = {'x': None, 'y': None}
value['x'] = float(self.tecnai.Projection.ImageShift.X)
value['y'] = float(self.tecnai.Projection.ImageShift.Y)
return value
def setRawImageShift(self, vector, relative = 'absolute'):
if relative == 'relative':
try:
vector['x'] += self.tecnai.Projection.ImageShift.X
except KeyError:
pass
try:
vector['y'] += self.tecnai.Projection.ImageShift.Y
except KeyError:
pass
elif relative == 'absolute':
pass
else:
raise ValueError
vec = self.tecnai.Projection.ImageShift
try:
vec.X = vector['x']
except KeyError:
pass
try:
vec.Y = vector['y']
except KeyError:
pass
self.tecnai.Projection.ImageShift = vec
def getDefocus(self):
return float(self.tecnai.Projection.Defocus)
def setDefocus(self, defocus, relative = 'absolute'):
if relative == 'relative':
defocus += self.tecnai.Projection.Defocus
elif relative == 'absolute':
pass
else:
raise ValueError
self.tecnai.Projection.Defocus = defocus
def resetDefocus(self):
self.tecnai.Projection.ResetDefocus()
def getMagnification(self, index=None):
if index is None:
return int(round(self.tecnai.Projection.Magnification))
elif not self.getMagnificationsInitialized():
raise MagnificationsUninitialized
else:
try:
return self.magnifications[index]
except IndexError:
raise ValueError('invalid magnification index')
def getMainScreenMagnification(self):
return int(round(self.tecnai.Projection.Magnification*self.mainscreenscale))
def getMainScreenScale(self):
return self.mainscreenscale
def setMainScreenScale(self, mainscreenscale):
self.mainscreenscale = mainscreenscale
def setMagnification(self, mag):
if not self.getMagnificationsInitialized():
raise MagnificationsUninitialized
try:
mag = int(round(mag))
except TypeError:
try:
mag = int(mag)
except:
raise TypeError
try:
index = self.magnifications.index(mag)
except ValueError:
raise ValueError('invalid magnification')
self.setMagnificationIndex(index)
return
def getMagnificationIndex(self, magnification=None):
if magnification is None:
return self.tecnai.Projection.MagnificationIndex - 1
elif not self.getMagnificationsInitialized():
raise MagnificationsUninitialized
else:
try:
return self.magnifications.index(magnification)
except IndexError:
raise ValueError('invalid magnification')
def setMagnificationIndex(self, value):
self.tecnai.Projection.MagnificationIndex = value + 1
def getMagnifications(self):
return self.magnifications
def setMagnifications(self, magnifications):
self.magnifications = magnifications
def findMagnifications(self):
savedindex = self.getMagnificationIndex()
magnifications = []
previousindex = None
index = 0
while True:
self.setMagnificationIndex(index)
index = self.getMagnificationIndex()
if index == previousindex:
break
magnifications.append(self.getMagnification())
previousindex = index
index += 1
self.setMagnifications(magnifications)
self.setMagnificationIndex(savedindex)
def getStagePosition(self):
value = {}
value['x'] = float(self.tecnai.Stage.Position.X)
value['y'] = float(self.tecnai.Stage.Position.Y)
value['z'] = float(self.tecnai.Stage.Position.Z)
value['a'] = float(self.tecnai.Stage.Position.A)
try:
value['b'] = float(self.tecnai.Stage.Position.B)
except:
pass
return value
def _setStagePosition(self, position, relative = 'absolute'):
#        tolerance = 1.0e-4
#        polltime = 0.01
if relative == 'relative':
for key in position:
position[key] += getattr(self.tecnai.Stage.Position, key.upper())
elif relative != 'absolute':
raise ValueError
pos = self.tecnai.Stage.Position
axes = 0
for key, value in position.items():
setattr(pos, key.upper(), value)
axes |= getattr(win32com.client.constants, 'axis' + key.upper())
try:
self.tecnai.Stage.Goto(pos, axes)
except pythoncom.com_error, (hr, msg, exc, arg):
#print 'Stage.Goto failed with error %d: %s' % (hr, msg)
if exc is None:
raise ValueError('no extended error information, assuming stage limit was hit')
else:
wcode, source, text, helpFile, helpId, scode = exc
if winerror.SUCCEEDED(wcode) and text is None:
raise ValueError('no extended error information, assuming stage limit was hit')
else:
raise RuntimeError(text)
#        for key in position:
#            while abs(getattr(self.tecnai.Stage.Position, key.upper())
#                                - getattr(pos, key.upper())) > tolerance:
#                time.sleep(polltime)
def getLowDoseStates(self):
return ['on', 'off', 'disabled']
def getLowDose(self):
try:
if (self.lowdose.IsInitialized == 1) and (self.lowdose.LowDoseActive == win32com.client.constants.IsOn):
return 'on'
else:
return 'off'
except pythoncom.com_error, (hr, msg, exc, arg):
if exc is None:
# No extended error information, assuming low dose is disabled
return 'disabled'
else:
wcode, source, text, helpFile, helpId, scode = exc
if winerror.SUCCEEDED(wcode) and text is None:
# No extended error information, assuming low dose is disabled
return 'disabled'
else:
raise RuntimeError(text)
def setLowDose(self, ld):
try:
if ld == 'off' :
self.lowdose.LowDoseActive = win32com.client.constants.IsOff
elif ld == 'on':
if self.lowdose.IsInitialized == 0:
raise RuntimeError('Low dose is not initialized')
else:
self.lowdose.LowDoseActive = win32com.client.constants.IsOn
else:
raise ValueError
except pythoncom.com_error, (hr, msg, exc, arg):
if exc is None:
# No extended error information, assuming low dose is disenabled
raise RuntimeError('Low dose is not enabled')
else:
wcode, source, text, helpFile, helpId, scode = exc
if winerror.SUCCEEDED(wcode) and text is None:
# No extended error information, assuming low dose is disenabled
raise RuntimeError('Low dose is not enabled')
else:
raise RuntimerError(text)
def getLowDoseModes(self):
return ['exposure', 'focus1', 'focus2', 'search', 'unknown', 'disabled']
def getLowDoseMode(self):
try:
if self.lowdose.LowDoseState == win32com.client.constants.eExposure:
return 'exposure'
elif self.lowdose.LowDoseState == win32com.client.constants.eFocus1:
return 'focus1'
elif self.lowdose.LowDoseState == win32com.client.constants.eFocus2:
return 'focus2'
elif self.lowdose.LowDoseState == win32com.client.constants.eSearch:
return 'search'
else:
return 'unknown'
except pythoncom.com_error, (hr, msg, exc, arg):
if exc is None:
# No extended error information, assuming low dose is disenabled
return 'disabled'
else:
wcode, source, text, helpFile, helpId, scode = exc
if winerror.SUCCEEDED(wcode) and text is None:
# No extended error information, assuming low dose is disenabled
return 'disabled'
else:
raise RuntimerError(text)
def setLowDoseMode(self, mode):
try:
if mode == 'exposure':
self.lowdose.LowDoseState = win32com.client.constants.eExposure
elif mode == 'focus1':
self.lowdose.LowDoseState = win32com.client.constants.eFocus1
elif mode == 'focus2':
self.lowdose.LowDoseState = win32com.client.constants.eFocus2
elif mode == 'search':
self.lowdose.LowDoseState = win32com.client.constants.eSearch
else:
raise ValueError
except pythoncom.com_error, (hr, msg, exc, arg):
if exc is None:
# No extended error information, assuming low dose is disenabled
raise RuntimeError('Low dose is not enabled')
else:
wcode, source, text, helpFile, helpId, scode = exc
if winerror.SUCCEEDED(wcode) and text is None:
# No extended error information, assuming low dose is disenabled
raise RuntimeError('Low dose is not enabled')
else:
raise RuntimerError(text)
def getDiffractionMode(self):
if self.tecnai.Projection.Mode == win32com.client.constants.pmImaging:
return 'imaging'
elif self.tecnai.Projection.Mode == win32com.client.constants.pmDiffraction:
return 'diffraction'
else:
raise SystemError
def setDiffractionMode(self, mode):
if mode == 'imaging':
self.tecnai.Projection.Mode = win32com.client.constants.pmImaging
elif mode == 'diffraction':
self.tecnai.Projection.Mode = win32com.client.constants.pmDiffraction
else:
raise ValueError
return 0
def getShutterPositions(self):
return ['open', 'closed']
def setShutter(self, state):
if self.exposure is None:
raise RuntimeError('setShutter requires adaExp')
if state == 'open':
if self.exposure.OpenShutter != 0:
raise RuntimeError('Open shutter failed')
elif state == 'closed':
if self.exposure.CloseShutter != 0:
raise RuntimeError('Close shutter failed')
else:
raise ValueError('Invalid value for setShutter \'%s\'' % (state,))
def getShutter(self):
if self.exposure is None:
raise RuntimeError('getShutter requires adaExp')
status = self.exposure.ShutterStatus
if status:
return 'closed'
else:
return 'open'
def getExternalShutterStates(self):
return ['connected', 'disconnected']
def setExternalShutter(self, state):
if self.exposure is None:
raise RuntimeError('setExternalShutter requires adaExp')
if state == 'connected':
if self.exposure.ConnectExternalShutter != 0:
raise RuntimeError('Connect shutter failed')
elif state == 'disconnected':
if self.exposure.DisconnectExternalShutter != 0:
raise RuntimeError('Disconnect shutter failed')
else:
raise ValueError('Invalid value for setExternalShutter \'%s\'' % (state,))
def getExternalShutter(self):
if self.exposure is None:
raise RuntimeError('getExternalShutter requires adaExp')
status = self.exposure.ExternalShutterStatus
if status:
return 'connected'
else:
return 'disconnected'
def preFilmExposure(self, value):
if self.exposure is None:
raise RuntimeError('preFilmExposure requires adaExp')
if not value:
return
if self.getFilmStock() < 1:
raise RuntimeError('No film to take exposure')
if self.exposure.LoadPlate != 0:
raise RuntimeError('Load plate failed')
if self.exposure.ExposePlateLabel != 0:
raise RuntimeError('Expose plate label failed')
def postFilmExposure(self, value):
if self.exposure is None:
raise RuntimeError('postFilmExposure requires adaExp')
if not value:
return
if self.exposure.UnloadPlate != 0:
raise RuntimeError('Unload plate failed')
#        if self.exposure.UpdateExposureNumber != 0:
#            raise RuntimeError('Update exposure number failed')
def filmExposure(self, value):
if not value:
return
'''
if self.getFilmStock() < 1:
raise RuntimeError('No film to take exposure')
if self.exposure.CloseShutter != 0:
raise RuntimeError('Close shutter (pre-exposure) failed')
if self.exposure.DisconnectExternalShutter != 0:
raise RuntimeError('Disconnect external shutter failed')
if self.exposure.LoadPlate != 0:
raise RuntimeError('Load plate failed')
if self.exposure.ExposePlateLabel != 0:
raise RuntimeError('Expose plate label failed')
if self.exposure.OpenShutter != 0:
raise RuntimeError('Open (pre-exposure) shutter failed')
'''
self.tecnai.Camera.TakeExposure()
'''
if self.exposure.CloseShutter != 0:
raise RuntimeError('Close shutter (post-exposure) failed')
if self.exposure.UnloadPlate != 0:
raise RuntimeError('Unload plate failed')
if self.exposure.UpdateExposureNumber != 0:
raise RuntimeError('Update exposure number failed')
if self.exposure.ConnectExternalShutter != 0:
raise RuntimeError('Connect external shutter failed')
if self.exposure.OpenShutter != 0:
raise RuntimeError('Open shutter (post-exposure) failed')
'''
def getMainScreenPositions(self):
return ['up', 'down', 'unknown']
def getMainScreenPosition(self):
timeout = 5.0
sleeptime = 0.05
while (self.tecnai.Camera.MainScreen
== win32com.client.constants.spUnknown):
time.sleep(sleeptime)
if self.tecnai.Camera.MainScreen != win32com.client.constants.spUnknown:
break
timeout -= sleeptime
if timeout <= 0.0:
return 'unknown'
if self.tecnai.Camera.MainScreen == win32com.client.constants.spUp:
return 'up'
elif self.tecnai.Camera.MainScreen == win32com.client.constants.spDown:
return 'down'
else:
return 'unknown'
def getSmallScreenPosition(self):
if self.tecnai.Camera.IsSmallScreenDown:
return 'down'
else:
return 'up'
def setMainScreenPosition(self, mode):
if mode == 'up':
self.tecnai.Camera.MainScreen = win32com.client.constants.spUp
elif mode == 'down':
self.tecnai.Camera.MainScreen = win32com.client.constants.spDown
else:
raise ValueError
def getHolderStatus(self):
if adacom is None:
raise RuntimeError('getHolderStatus requires adaExp')
if self.exposure.SpecimenHolderInserted == adacom.constants.eInserted:
return 'inserted'
elif self.exposure.SpecimenHolderInserted == adacom.constants.eNotInserted:
return 'not inserted'
else:
return 'unknown'
def getHolderTypes(self):
return ['no holder', 'single tilt', 'cryo', 'unknown']
def getHolderType(self):
if self.exposure is None:
raise RuntimeError('getHolderType requires adaExp')
if self.exposure.CurrentSpecimenHolderName == u'No Specimen Holder':
return 'no holder'
elif self.exposure.CurrentSpecimenHolderName == u'Single Tilt':
return 'single tilt'
elif self.exposure.CurrentSpecimenHolderName == u'ST Cryo Holder':
return 'cryo'
else:
return 'unknown'
def setHolderType(self, holdertype):
if self.exposure is None:
raise RuntimeError('setHolderType requires adaExp')
if holdertype == 'no holder':
holderstr = u'No Specimen Holder'
elif holdertype == 'single tilt':
holderstr = u'Single Tilt'
elif holdertype == 'cryo':
holderstr = u'ST Cryo Holder'
else:
raise ValueError('invalid holder type specified')
for i in [1,2,3]:
if self.exposure.SpecimenHolderName(i) == holderstr:
self.exposure.SetCurrentSpecimenHolder(i)
return
raise SystemError('no such holder available')
def getStageStatus(self):
if adacom is None:
raise RuntimeError('getStageStatus requires adaExp')
if self.exposure.GonioLedStatus == adacom.constants.eOn:
return 'busy'
elif self.exposure.GonioLedStatus == adacom.constants.eOff:
return 'ready'
else:
return 'unknown'
def getTurboPump(self):
if adacom is None:
raise RuntimeError('getTurboPump requires adaExp')
if self.exposure.GetTmpStatus == adacom.constants.eOn:
return 'on'
elif self.exposure.GetTmpStatus == adacom.constants.eOff:
return 'off'
else:
return 'unknown'
def setTurboPump(self, mode):
if adacom is None:
raise RuntimeError('setTurboPump requires adaExp')
if mode == 'on':
self.exposure.SetTmp(adacom.constants.eOn)
elif mode == 'off':
self.exposure.SetTmp(adacom.constants.eOff)
else:
raise ValueError
def getColumnValvePositions(self):
return ['open', 'closed']
def getColumnValvePosition(self):
if self.tecnai.Vacuum.ColumnValvesOpen:
return 'open'
else:
return 'closed'
def setColumnValvePosition(self, state):
if state == 'closed':
self.tecnai.Vacuum.ColumnValvesOpen = 0
elif state == 'open':
self.tecnai.Vacuum.ColumnValvesOpen = 1
else:
raise ValueError
def getVacuumStatus(self):
status = self.tecnai.Vacuum.Status
if status == win32com.client.constants.vsOff:
return 'off'
elif status == win32com.client.constants.vsCameraAir:
return 'camera'
elif status == win32com.client.constants.vsBusy:
return 'busy'
elif status == win32com.client.constants.vsReady:
return 'ready'
elif status == win32com.client.constants.vsUnknown:
return 'unknown'
elif status == win32com.client.constants.vsElse:
return 'else'
else:
return 'unknown'
#    def getColumnPressure(self):
#        return float(self.tecnai.Vacuum.Gauges('P4').Pressure)
def getObjectiveExcitation(self):
return float(self.tecnai.Projection.ObjectiveExcitation)
def getFocus(self):
return float(self.tecnai.Projection.Focus)
def setFocus(self, value):
self.tecnai.Projection.Focus = value
def getFilmStock(self):
return self.tecnai.Camera.Stock
def getFilmExposureNumber(self):
return self.tecnai.Camera.ExposureNumber % 100000
def setFilmExposureNumber(self, value):
self.tecnai.Camera.ExposureNumber = (self.tecnai.Camera.ExposureNumber
/ 100000) * 100000 + value
def getFilmExposureTypes(self):
return ['manual', 'automatic']
def getFilmExposureType(self):
if self.tecnai.Camera.ManualExposure:
return 'manual'
else:
return 'automatic'
def setFilmExposureType(self, value):
if value ==  'manual':
self.tecnai.Camera.ManualExposure = True
elif value == 'automatic':
self.tecnai.Camera.ManualExposure = False
else:
raise ValueError('Invalid value for film exposure type')
def getFilmExposureTime(self):
if self.tecnai.Camera.ManualExposure:
return self.getFilmManualExposureTime()
else:
return self.getFilmAutomaticExposureTime()
def getFilmManualExposureTime(self):
return float(self.tecnai.Camera.ManualExposureTime)
def setFilmManualExposureTime(self, value):
self.tecnai.Camera.ManualExposureTime = value
def getFilmAutomaticExposureTime(self):
return float(self.tecnai.Camera.MeasuredExposureTime)
def getFilmText(self):
return str(self.tecnai.Camera.FilmText)
def setFilmText(self, value):
self.tecnai.Camera.FilmText = value
def getFilmUserCode(self):
return str(self.tecnai.Camera.Usercode)
def setFilmUserCode(self, value):
self.tecnai.Camera.Usercode = value
def getFilmDateTypes(self):
return ['no date', 'DD-MM-YY', 'MM/DD/YY', 'YY.MM.DD', 'unknown']
def getFilmDateType(self):
filmdatetype = self.tecnai.Camera.PlateLabelDateType
if filmdatetype == win32com.client.constants.dtNoDate:
return 'no date'
elif filmdatetype == win32com.client.constants.dtDDMMYY:
return 'DD-MM-YY'
elif filmdatetype == win32com.client.constants.dtMMDDYY:
return 'MM/DD/YY'
elif filmdatetype == win32com.client.constants.dtYYMMDD:
return 'YY.MM.DD'
else:
return 'unknown'
def setFilmDateType(self, value):
if value == 'no date':
self.tecnai.Camera.PlateLabelDateType \
= win32com.client.constants.dtNoDate
elif value == 'DD-MM-YY':
self.tecnai.Camera.PlateLabelDateType \
= win32com.client.constants.dtDDMMYY
elif value == 'MM/DD/YY':
self.tecnai.Camera.PlateLabelDateType \
= win32com.client.constants.dtMMDDYY
elif value == 'YY.MM.DD':
self.tecnai.Camera.PlateLabelDateType \
= win32com.client.constants.dtYYMMDD
else:
raise ValueError('Invalid film date type specified')
def runBufferCycle(self):
try:
self.tecnai.Vacuum.RunBufferCycle()
except pythoncom.com_error, (hr, msg, exc, arg):
if exc is None:
raise RuntimeError('no extended error information')
else:
wcode, source, text, helpFile, helpId, scode = exc
if winerror.SUCCEEDED(wcode) and text is None:
raise RuntimeError('no extended error information')
else:
raise RuntimeError(text)
	Thanks for the help!
Re: Gonimeter calibration - Added by Anonymous almost 16 years ago
Another quick question (not related to the problem directly, but with the board in general):
When will the workshop you are having end? I appreciate the helpful responses you have provided so far (I really do!), but they have been few and far between, understandably so because of the workshop.
Right now, we are just stuck on this stage calibration step which is probably related to the pyScope issue I mentioned earlier. I just wish to know when you will be back to a normal schedule since we have to share the microscope with other groups in our department, and I don't want to keep them from using the microscope because we are stuck on Leginon. I feel that knowing when we can get more timely responses for our problems will allow us to better use our limited time on the microscope.
Again, thank you very much for your assistance!
Re: Gonimeter calibration - Added by Jim Pulokas almost 16 years ago
The workshop will be over on Friday, so you should be getting more attention after that. The stage movement problem is related to the updatecom.py problem. I will go over to the pyScope thread to respond to that now...
Re: Gonimeter calibration - Added by Anonymous almost 16 years ago
Now that I have the pyScope stuff sorted out, I revisited the Goniometer calibration. The stage is now moving and it's not longer stuck on the 0th point, but when I tried running the calibration, every single point out of 25 was rejected. I didn't get too much time to figure out how to fix it, but I thought a 25% tolerance was fairly generous and was wondering if there is something I should be looking into (some underlying problem). I don't want to 'fix' it by just increasing the tolerance (if possible).
The manual says that some valid points are rejected if the tolerance is too low--how can I determine if the sift are well-correlated?
Re: Gonimeter calibration - Added by Anchi Cheng almost 16 years ago
Carlos,
You can display the correlation map as well as the peak Leginon finds in your "GonioModeling" node.  Same function is available in all
calibration nodes.  Switching between what the imageviewer display is controled by tools on the left of the display area.  Select from "Image", "Correlation" which to display by clicking on the computer display icon.
Add the correlation peak position the program finds by pressing the orange "+" down.  Note that the correlation map origin is at the top-left corner,
which means that if the two images it correlates  are identical, you get a peak at the top-left corner, not the center of the image.
Anchi
Re: Gonimeter calibration - Added by Jim Pulokas almost 16 years ago
Here is a more detailed description of why calibration measurements are rejected:
The stage calibration (and many others) depend on already having done the pixel size calibration. This means that for every magnification, we already have a pixel size stored in the database. In our case, we measure pixel size by observing the diffraction pattern of a catalase crystal. We only directly measure this for a few of our higher magnifications, like 50,000 and 80,000. Then we extrapolate the other pixel sizes for other magnifications.
During stage calibration, the stage is requested to move a certain distance, then the resulting pixel shift is measured using image correlation. For example, the stage may move 5 um, then the correlation finds that the image shifted 100 pixels. This results in a measured pixel size of 5um / 100 pixels = 0.05 um/pixel. Rather than using catalase crystal, we are now using the stage movement as the basis for the measure. The stage measurement is compared with the catalase measurement and if they are not close enough within the specified tolerance, then the measurement is rejected.
Therefore, these are two possible reasons why this is failing:
1. The image correlation is not working. As Anchi stated, you can view the correlation image, and display the peak that Leginon found on this image. If it is finding something other than the true peak, then that is the problem. It could be that the stage movement is too far to make a correlation between the two images (no overlapping area between the two images). It could also be that there is not enough contrast in the image to get a good correlation peak (try more defocus).
2. The pixel size calibration stored in the database it not very good. This is frequently the case for lower magnifications where we did not directly measure from a catalase crystal, we just extrapolated using the nominal magnification. If you confirmed that the correlation is working, and the peak that is detected is true, then you can fully trust the measurement. Then all you have to do is make Leginon trust it. You can either set a very high tolerance until the measurements are accepted, or you can edit the pixel size calibration to a more realistic value, based on your new measurements of stage position.
Re: Gonimeter calibration - Added by Anonymous almost 16 years ago
I think I found what the problem was; for some reason, it's not detecting the peak properly. As I understand it, the peak is supposed to move, and the difference between the new and previous peak positions are measured to get the shift in pixels. However, the peak in the images (signified by an orange + sign) stays in the top left in the exact same spot, almost on the top edge, giving a measured pixel size of "0.0". This results in the point being rejected (gives "Error 1.0").
I'm not sure why it thinks the peak is up there. The "bad pixels" are at the bottom left, not the top right, and the area seems to be perfectly normal when we take images (no dead pixels, etc). What would you suggest I do to make Leginon read the correct peak? I already tried changing between phase and cross correlation.
(Note: we didn't have this problem on the TF20, just the T12).
Re: Gonimeter calibration - Added by Jim Pulokas almost 16 years ago
When you view the images during the calibration, you should see that the sample is moving between consecutive images.  If you view the correlation image, the peak should show up in a location that indicates how far consecutive images have moved.  There is one correlation image produced for every two images acquired.  Here is simple graphic that shows what you might expect to see.  First time I have tried linking to an image, so hope this works... 
 
Notice that the stage is shown to move in one direction for the entire series of images,  for example the stage X axis direction.  Then another series is done by moving only in the Y axis direction.  The position of the peak relative to the corner of the image indicates the direction and distance of the shift between the two consecutive images.  Therefore, you expect the peak to be in roughly the same direction and distance for each movement.  However, the reason we are trying to model this behavior is because the distance is actually not always the same, so you will notice a slight variation in the position of the peak.
The peak should not always show up at the corner of the image, which indicates a 0,0 shift between consectutive images. If you see that the stage is shifting in the images, but the peak shows up at the corner, then the images are not getting corrected properly. When you say that the peak is shown in the corner of the image, do you mean that the marker shows up at the corner of the image, and this is where you actually see the peak (bright spot) in the correlation image. Or does that mean you can see a real peak somewhere else on the correlation image even thought the marker shows up at the corner. If the images are not properly normalized, then you can get a false peak at the corner, and sometimes still see the real peak elsewhere in the correlation. Try again doing the correction dark/bright images for both channels. The reason we have the two channels is to prevent this false peak.
Re: Gonimeter calibration - Added by Jim Pulokas almost 16 years ago
Additionally, you can send us your dark and bright images and we can see if they look ok.  Try redoing your dark/bright images, just for whatever image size and binning you are using in your calibration.  Then go into the directory where images are stored for your sesssion and find the most recent dark/bright images.   This will be in whatever image path you set up for your session and the file names will be for example:
09nov18a_Corrector_dark_00013.mrc
09nov18a_Corrector_bright_00013.mrc
Just find the most recent dark and bright and send them as email attachment, or put them somewhere we can download them from you.
Re: Gonimeter calibration - Added by Anonymous almost 16 years ago
Thanks Jim; we retook the reference images like you suggested, and they seem to fine. The corrected images we're getting seem good (free of artifacts, good contrast). The problem we seem to be encountering then (that we didn't get with the TF20) is that the calibrated pixel size doesn't seem to be used during the goniomodeling step. The peak actually is moving now (slightly) and Leginon detects the shift in the peak by moving orange corsair, and the correlation display shows a white peak where the corsair is, but it's not recording the change in position itself. What we get is something like this:
Acquiring Point 18...
Position 0.0, 0.0
Delta 0.0
Correlation shift -11.7631921935, 227.299208071
Measured pixel size 0.0
Error 1.0
Rejected...
Acquiring Point 19...
And so on.
We think it had something to do with the pixel size not being calibrated properly. We followed the procedure on the manual on how to do it, and we also followed the same procedure for the TF20 (where it worked), although the magnifications are slightly different in the T12 (e.g. T12 uses 560x instead of 550x). We're worried that Leginon is not using the pixel sizes we put in and that's why the calibrated pixel size is showing up as zero... What do you think?
Thanks for all your help so far--I was thinking I would skip this step for now and work on the other calibrations if I could, though it's a very important calibration that I definitely need to fix sooner rather than later...
I'll see if I can get some screen caps to show you exactly what I mean.
Re: Gonimeter calibration - Added by Anchi Cheng almost 16 years ago
I have some guesses on what your problem is.
Frist, the pixelsize you enter is the actual pixelsize you get on CCD which normally
has a post magnification factor.  For example, if the magnification on the FEI GUI is 500 x, it means that 1um at the
sample would be shown as 500 um at the film camera.  If you scan the film at 15 um per pixel, you get a pixelsize of
15/500 um per pixel or 0.03 um/pixel = 3e-8 m/pixel.  CCD is normally further down in the column which means the image
is further magnified.  Let's say that the post mag is 1.5.  Then the pixelsize you need to put in Leginon for 500 x is
3e-8/1.5 = 3e-8 m/pixel.  If your F20 and T12 camera have different postmag, the two pixel sizes would be even more
different than 550x to 560x.
Go to your "Pixel Size" node in your Calibration application and check the pixelsize value saved
by clicking on the green arrow which opens the list of all pixel size calibrations for your instrument.
Second, It might be that for some reason it is recorded at 0 m/pixel when you extract the values from higher mags.
You can redo the extrapolation or enter a number you know is closer to the true value for your instrument and mag.
Anchi
Re: Gonimeter calibration - Added by Anonymous almost 16 years ago
Hi Anchi and Jim,
I think I found out what was wrong. After skipping ahead to the navigation section to test the other calibrations, I tried doing the stage calibration anyway to see what type of errors I would get -- anything to help me troubleshoot.
The error that came up said that I had not calibrated the simCCDcamera and the simTEM correctly, so it aborted the navigation step (image shift worked correctly). I thought that maybe the calibrations of the real instruments were being disrupted by the simulated instruments somehow. I checked the settings to make sure that the real instruments were being selected for each of the calibrations (they were). I tried again and got the same types of errors on the goniomodeling node.
I decided to test my theory for sure by commenting out the two simulated instruments in the pyScope config file. This did the trick--when I went back to the goniomodeling step, the peak shifts started getting detected and the points were being saved to the database. I didn't get a chance to test the quality of the calibration by using navigation mode (ran out of scheduled time on the microscope), but I did get a rough curve in the goniomedeling admin tools, so things are starting to look more promising.
I'm curious as to why we didn't have this problem on the TF20; we did not (for the most part) have any problems with the simulated instruments, but still--it might useful to know in case anyone else in the future runs into the same problems! I would suggest just having the two instruments that you are going to calibrate as the only ones enabled, as I also had to keep checking to make sure they were selected.
Thanks for the help! I will undoubtedly need it again when I return to this tomorrow. <img src="{SMILIES_PATH}/icon_lol.gif" alt=":lol:" title="Laughing" />
Re: Gonimeter calibration - Added by Anchi Cheng almost 16 years ago
Carlos,
In general, you want to send a preset to scope before calibration. Default in Leginon listens to what the microscope and ccd was last sent to and use it to aquire images and to do calibration. We did that so that you can calibrate at only the mags required for your real experiment. Unless you've changed the settings to "Overwrite Preset", Leginon should not use the camera and tem settings in the calibration or navigation nodes. It might be that you have a mixture of instrument in your presets, some using SimTEM/SimCAM and some using real ones. The database was confused because of it. Even though the problem is fixed, I still encourage you to make a copy of your current database and tell Jim and I where to get it (in e-mail for privacy). We can look through it to tell you when and what has gone wrong since the database records the history of all these changes. It will help us to create better error catching mechanism in the future.
Anchi