def findBrightImageFromNorm(self, normdata):
        '''
		Find BrighetImageData based on imported NormImageData.
		This is needed for older data since BrightImageData was
		not linked to AcquisitionImages previously.
		'''
        if normdata['bright']:
            return normdata['bright']
        timestamp = normdata.timestamp
        normcam = normdata['camera']
        qcam = leginondata.CameraEMData(dimension=normcam['dimension'],
                                        offset=normcam['offset'],
                                        binning=normcam['binning'],
                                        ccdcamera=normcam['ccdcamera'])
        qcam['exposure type'] = 'normal'
        qcam['energy filtered'] = normcam['energy filtered']

        normscope = normdata['scope']
        qscope = leginondata.ScopeEMData(tem=normscope['tem'])
        qscope['high tension'] = normscope['high tension']
        q = leginondata.BrightImageData(camera=qcam,
                                        scope=qscope,
                                        channel=normdata['channel'])
        brightlist = q.query()
        for brightdata in brightlist:
            if brightdata.timestamp < timestamp:
                break
        return brightdata
	def alreadyAcquired(self, targetdata, presetname):
		'''
		determines if image already acquired using targetdata and presetname
		'''
		## if image exists with targetdata and presetdata, no acquire
		## we expect target to be exact, however, presetdata may have
		## changed so we only query on preset name

		# seems to have trouple with using original targetdata as
		# a query, so use a copy with only some of the fields
		presetquery = leginondata.PresetData(name=presetname)
		targetquery = leginondata.AcquisitionImageTargetData(initializer=targetdata)
		## don't care if drift correction was done on target after image was
		## acquired, so ignore version, delta row/col, parentimage, and fromtarget
		targetquery['version'] = None
		targetquery['delta row'] = None
		targetquery['delta column'] = None
		targetquery['image'] = None
		targetquery['fromtarget'] = None
		imagequery = leginondata.AcquisitionImageData(target=targetquery, preset=presetquery)
		## other things to fill in
		imagequery['scope'] = leginondata.ScopeEMData()
		imagequery['camera'] = leginondata.CameraEMData()
		imagequery['session'] = leginondata.SessionData()
		datalist = self.research(datainstance=imagequery)
		if datalist:
			## no need to acquire again, but need to republish
			self.reportStatus('output', 'Image was acquired previously, republishing')
			imagedata = datalist[0]
			self.publishDisplayWait(imagedata)
			return True
		else:
			return False
    def researchCorrectorImageData(self, type, scopedata, cameradata, channel):
        if type == 'dark':
            imagetemp = leginondata.DarkImageData()
        elif type == 'bright':
            imagetemp = leginondata.BrightImageData()
        elif type == 'norm':
            imagetemp = leginondata.NormImageData()
        else:
            return None

        ## query only based on certain camera parameters, not all
        imagetemp['camera'] = leginondata.CameraEMData()
        for key in ('ccdcamera', 'dimension', 'binning', 'offset',
                    'gain index'):
            imagetemp['camera'][key] = cameradata[key]
        # query only based on certain scope parameters, not all
        imagetemp['scope'] = leginondata.ScopeEMData()
        for key in ('tem', 'high tension'):
            imagetemp['scope'][key] = scopedata[key]
        imagetemp['channel'] = channel
        try:
            ref = imagetemp.query(results=1)
        except Exception, e:
            self.logger.warning('Reference image query failed: %s' % e)
            ref = None
    def calculateTiles(self, tilesize):
        ## figure out the final shape of global space
        rowsize = int(numpy.ceil(float(self.shape[0]) / tilesize) * tilesize)
        colsize = int(numpy.ceil(float(self.shape[1]) / tilesize) * tilesize)

        ## make list of stage center for each tile
        print 'calculating tile positions...'
        centerpixel = rowsize / 2.0 - 0.5, colsize / 2.0 - 0.5
        firstpixel = tilesize / 2.0 - 0.5
        rowi = 0
        tiles = ordereddict.OrderedDict()
        for row in numpy.arange(firstpixel, rowsize, tilesize):
            coli = 0
            for col in numpy.arange(firstpixel, colsize, tilesize):
                pixel = {
                    'row': row - centerpixel[0],
                    'col': col - centerpixel[1]
                }
                newstage = self.trans.transform(pixel, self.stage, self.bin)
                tilescope = leginondata.ScopeEMData(initializer=self.scope)
                tilescope['stage position'] = newstage
                tilecamera = leginondata.CameraEMData(initializer=self.camera)
                tilecamera['dimension'] = {'x': tilesize, 'y': tilesize}
                args = tilescope, tilecamera, self.timestamp
                kwargs = {'rotation': self.rotation}
                tiles[(rowi, coli)] = {'args': args, 'kwargs': kwargs}
                coli += 1
            rowi += 1

        print 'Calculated %d tiles, %d rows, %d cols' % (len(tiles), rowi,
                                                         coli)
        return tiles
Example #5
0
 def measureImageShiftComaMatrix(self, shift_n, shift_step, repeat,
                                 tilt_value, settle):
     ''' Measure coma for a range of image shift and fit the results 
                             to a straight line on individual axis.  Strickly speaking should
                             use orthogonal distance regression.'''
     calibration_client = self.calibration_clients['beam tilt']
     f = open(self.session['name'] + 'tilt.dat', 'w')
     tem = self.instrument.getTEMData()
     shift0 = self.instrument.tem.ImageShift
     state = leginondata.ScopeEMData()
     tilt0 = self.instrument.tem.BeamTilt
     state['image shift'] = shift0
     state['beam tilt'] = tilt0
     coma0 = tilt0
     tdict = {}
     xydict = {}
     ordered_axes = ['x', 'y']
     debug = False
     try:
         for axis in ordered_axes:
             tdata = []
             data = {'x': [], 'y': []}
             for i in range(0, 2 * shift_n + 1):
                 shift = (i - shift_n) * shift_step
                 tdata.append(shift)
                 state['image shift'][axis] = shift0[axis] + shift
                 self.instrument.setData(state)
                 newshift = self.instrument.tem.ImageShift
                 self.logger.info(
                     'Image Shift ( %5.2f, %5.2f)' %
                     (newshift['x'] * 1e6, newshift['y'] * 1e6))
                 text = '%5.2f %5.2f ' % (newshift['x'] * 1e6,
                                          newshift['y'] * 1e6)
                 xarray, yarray = calibration_client.repeatMeasureComaFree(
                     tilt_value, settle, repeat)
                 xmean = xarray.mean()
                 ymean = yarray.mean()
                 text = text + "%5.2f %5.2f %5.2f %5.2f" % (
                     xmean * 1000, xarray.std() * 1000, ymean * 1000,
                     yarray.std() * 1000) + '\n'
                 f.write(text)
                 state['image shift'] = shift0
                 state['beam tilt'] = tilt0
                 self.instrument.setData(state)
                 comatilt = {'x': xmean, 'y': ymean}
                 data['x'].append(xmean)
                 data['y'].append(ymean)
                 self.checkAbort()
             tdict[axis] = tdata
             xydict[axis] = data
         matrix, coma0 = calibration_client.calculateImageShiftComaMatrix(
             tdict, xydict)
     except:
         raise
         matrix = None
     f.close()
     return matrix, coma0
def createGlobalOutput(imdata, angle=0.0, bin=1):
    sys.stderr.write('creating global image space\n')
    timestamp = imdata.timestamp
    scope = leginondata.ScopeEMData(initializer=imdata['scope'])
    camera = leginondata.CameraEMData(initializer=imdata['camera'])
    binning = {
        'x': camera['binning']['x'] * bin,
        'y': camera['binning']['y'] * bin
    }
    camera['binning'] = binning
    globaloutput = MontageImage(scope, camera, timestamp, rotation=angle)
    return globaloutput
    def queryCorrectionImage(self, scopedata, camdata, type, channel):
        # only query based on instrument and high tension
        scope = leginondata.ScopeEMData()
        scope['tem'] = scopedata['tem']
        scope['high tension'] = scopedata['high tension']

        # only query based on instrument, dimension, binning, offset
        camera = leginondata.CameraEMData()
        camera['ccdcamera'] = camdata['ccdcamera']
        camera['dimension'] = camdata['dimenion']
        camera['binning'] = camdata['binning']
        camera['offset'] = camdata['offset']

        ## first try requested channel, then try any channel
        corimg = None
        for channel in (channel, None):
            ## try cache
            try:
                key = self.getkey(scopedata, camdata, type, channel)
                return self.cache[key]
            except KeyError:
                pass
            self.node.logger.info('Loading %s...' % self.formatKey(key))
            qimage = leginondata.CorrectionImageData(scope=scope,
                                                     camera=camera,
                                                     type=type,
                                                     channel=channel)
            try:
                corimg = qimage.query(results=1)
                corimg = corimg[0]
                break
            except:
                pass

                self.node.logger.warning(
                    'requested correction channel %s not available, using channel: %s'
                    % (channel, corimg['channel']))
            else:
                self.node.logger.error('No correction image in database')
                corimg = None

        if corimg is not None:
            self.node.logger.info('Correction image loaded: %s' %
                                  (corimg['filename'], ))
            ## make it float to do float math later
            image = numpy.asarray(corimg['image'], numpy.float32)
            key = self.getkey(corimg['scope'], corimg['camera'],
                              corimg['type'], corimg['channel'])
            self.cache[key] = image
        else:
            image = None
        return image
 def __init__(self, scope, camera, timestamp, fileref=None, rotation=0.0):
     self.scope = leginondata.ScopeEMData(initializer=scope)
     self.camera = leginondata.CameraEMData(initializer=camera)
     self.shape = self.camera['dimension']['y'], self.camera['dimension'][
         'x']
     self.fileref = fileref
     self.timestamp = timestamp
     self.trans = caltransformer.getTransformer(scope['tem'],
                                                camera['ccdcamera'],
                                                scope['high tension'],
                                                scope['magnification'],
                                                timestamp, rotation)
     self.newStage(scope['stage position'])
    def storeCorrectorImageData(self, imagedata, type, channel):

        # check for bad shape
        imarray = imagedata['image']
        shape = imarray.shape
        cameradata = imagedata['camera']
        dim = cameradata['dimension']
        if dim['x'] != shape[1] or dim['y'] != shape[0]:
            raise RuntimeError('%s: bad array shape: %s' % (
                type,
                shape,
            ))

        if type == 'dark':
            refclass = leginondata.DarkImageData
        elif type == 'bright':
            refclass = leginondata.BrightImageData
        elif type == 'norm':
            refclass = leginondata.NormImageData
        refdata = refclass(initializer=imagedata)

        refdata['filename'] = self.makeCorrectorImageFilename(
            type, channel, imarray.shape)

        ## replace session of scope, camera, refdata with ref session
        refsession = self.getReferenceSession()
        scopedata = refdata['scope']
        cameradata = refdata['camera']
        newscope = leginondata.ScopeEMData(initializer=scopedata)
        newscope['session'] = refsession
        newcamera = leginondata.CameraEMData(initializer=cameradata)
        newcamera['session'] = refsession
        refdata['session'] = refsession
        refdata['scope'] = newscope
        refdata['camera'] = newcamera
        refdata['channel'] = channel

        self.logger.info('Saving new %s' % (type, ))
        refdata.insert(force=True)
        self.logger.info('Saved: %s' % (refdata['filename'], ))

        ## store in cache
        key = self.makeCorrectorKey(type, scopedata, cameradata, channel)
        ref_cache[key] = refdata

        return refdata
    def getAlternativeChannelNorm(self, refdata):
        '''
		Get norm image data of the other channel closest in time
		'''
        if refdata is None:
            return None
        reftype = 'norm'
        timestamp = refdata.timestamp
        refcam = refdata['camera']
        qcam = leginondata.CameraEMData(dimension=refcam['dimension'],
                                        offset=refcam['offset'],
                                        binning=refcam['binning'],
                                        ccdcamera=refcam['ccdcamera'])
        qcam['exposure time'] = refcam['exposure time']
        qcam['energy filtered'] = refcam['energy filtered']
        qcam['gain index'] = refcam['gain index']

        refscope = refdata['scope']
        qscope = leginondata.ScopeEMData(tem=refscope['tem'])
        qscope['high tension'] = refscope['high tension']
        altchannel = int(refdata['channel'] == 0)
        q = self.createRefQuery(reftype, qcam, qscope, altchannel)
        reflist = q.query()
        if len(reflist) == 0:
            # Not to query exposure time if none found
            qcam['exposure time'] = None
            q = self.createRefQuery(reftype, qcam, qscope, altchannel)
            reflist = q.query()
        if len(reflist) == 0:
            #no switching, no alternative channel found
            return refdata
        for newrefdata in reflist:
            if newrefdata.timestamp < timestamp:
                break
        before_ref = newrefdata
        reflist.reverse()
        for newrefdata in reflist:
            if newrefdata.timestamp > timestamp:
                break
        after_ref = newrefdata
        if after_ref.timestamp - timestamp > timestamp - before_ref.timestamp:
            return before_ref
        else:
            return after_ref
Example #11
0
    def __calibrateStigmator(self, beam_tilt, delta, stigmator):
        if self.initInstruments():
            raise RuntimeError('cannot initialize instrument')

        calibration_client = self.calibration_clients['beam tilt']

        magnification = self.instrument.tem.Magnification
        high_tension = self.instrument.tem.HighTension
        probe = self.instrument.tem.ProbeMode

        # set up the stigmator states
        axes = ('x', 'y')
        deltas = (delta / 2.0, -delta / 2.0)
        for stig_axis in axes:
            self.logger.info('Calibrating stig. %s-axis...' % stig_axis)
            parameters = []
            states = []
            for delta in deltas:
                v = dict(stigmator)
                v[stig_axis] += delta
                parameters.append(v[stig_axis])
                s = leginondata.ScopeEMData(stigmator={'objective': v})
                states.append(s)

            matrix = numpy.identity(2, numpy.float)
            for i, tilt_axis in enumerate(axes):
                self.logger.info('Calibrating on %s-axis...' % tilt_axis)
                args = (tilt_axis, beam_tilt, states)
                kwargs = {
                    'correct_tilt': self.settings['correct tilt'],
                    'settle': self.settings['settling time'],
                }
                shifts = calibration_client.measureDisplacements(
                    *args, **kwargs)
                args = (shifts, parameters, beam_tilt)
                matrix[:, i] = calibration_client.eq11(*args)
                self.checkAbort()

            # store calibration
            type = 'stig' + stig_axis
            args = (high_tension, magnification, type, matrix)
            kwargs = {'probe': probe}
            calibration_client.storeMatrix(*args, **kwargs)
    def getEMTargetData(self, check_preset_name=None):
        target_data = self.reference_target
        if target_data is None:
            raise MoveError('no reference target available')
        move_type = self.settings['move type']
        calibration_client = self.calibration_clients[move_type]

        target_delta_row = target_data['delta row']
        target_delta_column = target_data['delta column']
        pixel_shift = {'row': -target_delta_row, 'col': -target_delta_column}
        target_scope = leginondata.ScopeEMData(
            initializer=target_data['scope'])
        for i in ['image shift', 'beam shift', 'stage position']:
            target_scope[i] = dict(target_data['scope'][i])
        target_camera = target_data['camera']

        args = (pixel_shift, target_scope, target_camera)
        try:
            scope = calibration_client.transform(*args)
        except calibrationclient.NoMatrixCalibrationError, e:
            message = 'no %s calibration to move to reference target: %s'
            raise MoveError(message % (move_type, e))
    def getBrightImageFromNorm(self, normdata):
        '''
		Get bright image used to produce the norm image
		This is made to be back compatible to early leginondata that
		has no bright image association but would be the closest in time before
		the norm was calculated
		'''
        if normdata is None:
            return None
        # newer leginon data will have bright image associated with norm image
        if 'bright' in normdata.keys() and normdata['bright'] is not None:
            return normdata['bright']
        # bright image may have the same CameraEMData
        q = leginondata.BrightImageData(camera=normdata['camera'])
        brightresults = q.query(results=1)
        if brightresults:
            return brightresults[0]
        # otherwise need to look up timestamp
        timestamp = normdata.timestamp
        normcam = normdata['camera']
        qcam = leginondata.CameraEMData(dimension=normcam['dimension'],
                                        offset=normcam['offset'],
                                        binning=normcam['binning'],
                                        ccdcamera=normcam['ccdcamera'])
        qcam['exposure type'] = 'normal'
        qcam['energy filtered'] = normcam['energy filtered']
        qcam['gain index'] = normcam['gain index']

        normscope = normdata['scope']
        qscope = leginondata.ScopeEMData(tem=normscope['tem'])
        qscope['high tension'] = normscope['high tension']
        q = leginondata.BrightImageData(camera=qcam,
                                        scope=qscope,
                                        channel=normdata['channel'])
        brightlist = q.query()
        for brightdata in brightlist:
            if brightdata.timestamp < timestamp:
                break
        return brightdata
Example #14
0
	def makeStates(self):
		## list of tilts entered by user in degrees, converted to radians
		tiltstr = self.settings['tilts']
		try:
			alphatilts = eval(tiltstr)
		except:
			self.logger.error('Invalid tilt list')
			return
		## check for singular value
		if isinstance(alphatilts, float) or isinstance(alphatilts, int):
			alphatilts = (alphatilts,)
		if len(alphatilts) == 0:
			self.logger.warning("Please set to Bypass if you do not want to repeat")
			return []
		self.makeTiltPatterns(alphatilts)
		states = []
		self.logger.info('tilt series =' + str(alphatilts))
		for a in alphatilts:
			rad = a * 3.14159 / 180.0
			scope = leginondata.ScopeEMData()
			scope['stage position'] = {'a': rad}
			states.append(scope)
		return states
        def calculateMosaicImage(self):
                '''
                calculates (but does not generate) an unscaled mosaic image
                '''
                if not self.tiles:
                        return
                param = self.calibrationclient.parameter()
                ## calculate parameter center of final mosaic image
                center = {'x': 0.0, 'y': 0.0}
                for tile in self.tiles:
                        tileparam = tile.imagedata['scope'][param]
                        center['x'] += tileparam['x']
                        center['y'] += tileparam['y']
                n = len(self.tiles)
                center['x'] /= n
                center['y'] /= n
                self.center = center

                ## Calculate pixel vector on final image to center of 
                ## each tile.
                ## To use calibrationclient's itransform method, we need
                ## a fake image from which to calculate a pixel vector
                ## Maybe could use an actual final image leginondata.
                someimage = self.tiles[0].imagedata
                self.fakescope = leginondata.ScopeEMData(initializer=someimage['scope'])
                self.fakescope[param] = dict(someimage['scope'][param])
                self.fakescope[param].update(center)
                ## assume the final fake image has same binning as first tile
                self.fakecamera = leginondata.CameraEMData(initializer=someimage['camera'])
                tile0 = self.tiles[0]
                mosaic0 = mosaic1 = None
                for tile in self.tiles:
                        tileparam = {}
                        ## calculate the parameter shift from center of 
                        ## mosaic image to center of tile
                        for axis in ('x','y'):
                                tileparam[axis] = tile.imagedata['scope'][param][axis]
                        ## calculate corresponding pixel shift (float)
                        center2center = self.positionByCalibration(tileparam)
                        ## for targeting, until it's fixed
                        tile.position = center2center

                        ## pixel shift mosaic center to tile center (int)
                        center2center = self.round(center2center)
                        tile.center_vect = center2center

                        ## pixel shift from center of mosaic to corners of tile
                        shape = tile.image.shape
                        corner_vect = center2center[0]-shape[0]/2, center2center[1]-shape[1]/2
                        corner1_vect = corner_vect[0]+shape[0], corner_vect[1]+shape[1]
                        tile.corner_vect = corner_vect
                        ## check if this is a min or max in the mosaic
                        if mosaic0 is None:
                                mosaic0 = [corner_vect[0], corner_vect[1]]
                                mosaic1 = [corner1_vect[0], corner1_vect[1]]
                        for axis in (0,1):
                                if corner_vect[axis] < mosaic0[axis]:
                                        mosaic0[axis] = corner_vect[axis]
                                if corner1_vect[axis] > mosaic1[axis]:
                                        mosaic1[axis] = corner1_vect[axis]
                ## mosaic shape at full scale
                self.mosaicshape = mosaic1[0]-mosaic0[0], mosaic1[1]-mosaic0[1]

                ## center of mosaic image
                mosaic_center = self.mosaicshape[0]/2, self.mosaicshape[1]/2

                ## position of corner and center
                for tile in self.tiles:
                        corner_pos = tile.corner_vect[0]-mosaic0[0], tile.corner_vect[1]-mosaic0[1]
                        center_pos = tile.center_vect[0]-mosaic0[0], tile.center_vect[1]-mosaic0[1]
                        tile.corner_pos = corner_pos
                        tile.center_pos = center_pos
        def targetToEMTargetData(self, targetdata,movetype):
                '''
                copied from acquisition but get move type from old emtarget
                '''
                emtargetdata = leginondata.EMTargetData()
                if targetdata is not None:
                        # get relevant info from target data
                        targetdeltarow = targetdata['delta row']
                        targetdeltacolumn = targetdata['delta column']
                        origscope = targetdata['scope']
                        targetscope = leginondata.ScopeEMData(initializer=origscope)
                        ## copy these because they are dictionaries that could
                        ## otherwise be shared (although transform() should be
                        ## smart enough to create copies as well)
                        targetscope['stage position'] = dict(origscope['stage position'])
                        targetscope['image shift'] = dict(origscope['image shift'])
                        targetscope['beam shift'] = dict(origscope['beam shift'])

                        oldpreset = targetdata['preset']

                        zdiff = 0.0
                        ### simulated target does not require transform
                        if targetdata['type'] == 'simulated':
                                newscope = origscope
                        else:
                                targetcamera = targetdata['camera']

                                ## to shift targeted point to center...
                                deltarow = -targetdeltarow
                                deltacol = -targetdeltacolumn

                                pixelshift = {'row':deltarow, 'col':deltacol}
                                ## figure out scope state that gets to the target
                                calclient = self.calclients[movetype]
                                try:
                                        newscope = calclient.transform(pixelshift, targetscope, targetcamera)
                                except calibrationclient.NoMatrixCalibrationError, e:
                                        m = 'No calibration for acquisition move to target: %s'
                                        self.logger.error(m % (e,))
                                        raise NoMoveCalibration(m)

                                ## if stage is tilted and moving by image shift,
                                ## calculate z offset between center of image and target
                                if movetype in ('image shift','image beam shift','beam shift') and abs(targetscope['stage position']['a']) > 0.02:
                                        calclient = self.calclients['stage position']
                                        try:
                                                tmpscope = calclient.transform(pixelshift, targetscope, targetcamera)
                                        except calibrationclient.NoMatrixCalibrationError:
                                                message = 'No stage calibration for z measurement'
                                                self.logger.error(message)
                                                raise NoMoveCalibration(message)
                                        ydiff = tmpscope['stage position']['y'] - targetscope['stage position']['y']
                                        zdiff = ydiff * numpy.sin(targetscope['stage position']['a'])

                        ### check if stage position is valid
                        if newscope['stage position']:
                                self.validateStagePosition(newscope['stage position'])

                        emtargetdata['preset'] = oldpreset
                        emtargetdata['movetype'] = movetype
                        emtargetdata['image shift'] = dict(newscope['image shift'])
                        emtargetdata['beam shift'] = dict(newscope['beam shift'])
                        emtargetdata['stage position'] = dict(newscope['stage position'])
                        emtargetdata['delta z'] = zdiff
from leginon import leginondata
import dbdatakeeper

dk = dbdatakeeper.DBDataKeeper(('asdf', 3), None)

md = leginondata.MyData()
mod = leginondata.MyOtherData()
mod['stuff'] = 6
mod['encore'] = 'asdf'

md['other'] = mod

scopedata = leginondata.ScopeEMData(('scopeasdf', ),
                                    initializer={
                                        'magnification': 1501,
                                        'beam tilt': {
                                            'x': 1.1,
                                            'y': 2.2
                                        }
                                    })
cameradata = leginondata.CameraEMData(('camasdf', ),
                                      initializer={
                                          'exposure time': 510,
                                          'binning': {
                                              'x': 1,
                                              'y': 1
                                          }
                                      })

## PresetData
pdata = leginondata.NewPresetData(('pdata', 1))
pdata['name'] = 'hole3'
	def targetToEMTargetData(self, targetdata, z=None):
		'''
		convert an ImageTargetData to an EMTargetData object
		using chosen move type.
		The result is a valid scope state that will center
		the target on the camera, but not necessarily at the
		desired preset.  It is shifted from the preset of the 
		original targetdata.

		Certain fields are reset to None becuase they are not
		necessary, and cause problems if used between different
		magnification modes (LM, M, SA).
		'''
		emtargetdata = leginondata.EMTargetData()
		if targetdata is not None:
			# get relevant info from target data
			targetdeltarow = targetdata['delta row']
			targetdeltacolumn = targetdata['delta column']
			origscope = targetdata['scope']
			targetscope = leginondata.ScopeEMData(initializer=origscope)
			## copy these because they are dictionaries that could
			## otherwise be shared (although transform() should be
			## smart enough to create copies as well)
			targetscope['stage position'] = dict(origscope['stage position'])
			targetscope['image shift'] = dict(origscope['image shift'])
			targetscope['beam shift'] = dict(origscope['beam shift'])

			if z is not None:
				# since presetsmanager settings 'only xy' is always True, this
				# is only good for database record
				targetscope['stage position']['z'] = z

			movetype = self.settings['move type']
			oldpreset = targetdata['preset']

			zdiff = 0.0
			### simulated target does not require transform
			if targetdata['type'] == 'simulated':
				newscope = origscope
			else:
				targetcamera = targetdata['camera']
		
				## to shift targeted point to center...
				deltarow = -targetdeltarow
				deltacol = -targetdeltacolumn
		
				pixelshift = {'row':deltarow, 'col':deltacol}
		
				## figure out scope state that gets to the target
				calclient = self.calclients[movetype]
				try:
					newscope = calclient.transform(pixelshift, targetscope, targetcamera)
				except calibrationclient.NoMatrixCalibrationError, e:
					raise NoMoveCalibration(e)

				## if stage is tilted and moving by image shift,
				## calculate z offset between center of image and target
				if movetype in ('image shift','image beam shift','beam shift') and abs(targetscope['stage position']['a']) > 0.02:
					calclient = self.calclients['stage position']
					try:
						tmpscope = calclient.transform(pixelshift, targetscope, targetcamera)
					except calibrationclient.NoMatrixCalibrationError,e:
						raise NoMoveCalibration(e)
					ydiff = tmpscope['stage position']['y'] - targetscope['stage position']['y']
					zdiff = ydiff * numpy.sin(targetscope['stage position']['a'])