Updating box coordinates after correction

Hi Tim,

I looked at magnification distortion of data we collected at the end of January 2016 at Janelia (the left Krios with the energy filter). We did not take images of gold crystals, but I do have diffraction from my molecules (much lower resolution than the gold) and from that I obtain ~1% distortion with an angle of ~110 degrees (K2 super resolution pixel size is 0.855 A). These values are similar than in your paper, but of course my estimation is probably much less accurate compared to the 2.4 ring of the gold. Do you know whether anyone recently repeated the gold measurements on this scope? Since the particle diameter is almost 600 A and after reading your paper, I pay now attention to this issue.

Anyway, my question is whether you have a formula for calculating the pixel coordinates of an object after correction, e.g. stretching or shrinking the image? If you scale, does the center or a corner of the image stay in place? For instance, if in the original image a particular particle is located at x_original, y_original what are x_corrected, y_corrected?

All the best, Simon

Hi Simon,

I have not measured the distortions on the Krios 1 - but, I think that the guys at the facility may well have, so if you contact them - they can probably provide you with the values.

I have almost always picked on the distortion corrected images, but I did once do the co-ordinate correction. During the scaling it is the centre that stays in place. You should be able treat it as a rotation, scale, backwards rotation. Of course you could do it in one step, but it's easier to think about separately, basically I think you would need to do something like this (this may not be exactly right, but should give you an idea) :-

1. If your coords are not set so that 0,0 is the centre of the image, then make it so that they are (most likely by subtracting half a box)
2. Rotate the coords by the specified angle in degrees.
3. Scale the rotated coords in X,Y by the inverse of the major / minor axis scale factors
4. Rotate them back by the inverse of the angle.
5. If you had to change them in step 1, change them back.

The relevant code from the fortran correction program looks like this :

angle_in_radians = convert(distortion_angle,degrees,radians)

! You need to take the inverse of the scale factors, this is because the scale factors are estimated in Fourier space, but correction done in real space.

x_scale_factor = 1.0e0 / major_axis_scale_factor
y_scale_factor = 1.0e0 / minor_axis_scale_factor

! Initial rotation - here half of the image size is also subtracted so that the coordinates are centred at 0

new_x = real(y - self%GetPhysicalIndexOfBoxCenter(2))*sin(-angle_in_radians) + real(x - self%GetPhysicalIndexOfBoxCenter(1))*cos(-angle_in_radians)
new_y = real(y - self%GetPhysicalIndexOfBoxCenter(2))*cos(-angle_in_radians) - real(x - self%GetPhysicalIndexOfBoxCenter(1))*sin(-angle_in_radians)

! Scaling

new_x = new_x * x_scale_factor
new_y = new_y * y_scale_factor

! Rotate back

final_x = real(new_y)*sin(angle_in_radians) + real(new_x)*cos(angle_in_radians)
final_y = real(new_y)*cos(angle_in_radians) - real(new_x)*sin(angle_in_radians)

! Add on half the box again to go back to original coord system

final_x = final_x + self%GetPhysicalIndexOfBoxCenter(1)
final_y = final_y + self%GetPhysicalIndexOfBoxCenter(2)

Hope this helps!

Tim

In reply to by timgrant

Thanks, Tim!

This will help me a lot to make a script for the coordinate transformation. I'll ask the Krios 1 staff whether they have some recent values.

Simon

This is a transformation written in python:

##############################################################

import numpy as np

# micrograph dimensions
mic_x=1919
mic_y=1855

# original pixel coordinates
x_original=149
y_original=1719

# values from mag_distortion_estimate program
angle_deg=70.0
major_scale=1.08
minor_scale=0.95

angle_rad=(float(angle_deg)/180.0)*np.pi

# pixel location relative to center of micrograph
x=float(x_original)-float(mic_x)/2.0
y=float(y_original)-float(mic_y)/2.0

# rotate
r = np.sqrt(x**2+y**2)
phi = np.arctan2(y,x)+angle_rad

# scale
x = r*np.cos(phi)*major_scale
y = r*np.sin(phi)*minor_scale

# rotate back
r = np.sqrt(x**2+y**2)
phi = np.arctan2(y,x)-angle_rad

# pixel location relative to edge of micrograph
x_correct = r*np.cos(phi)+float(mic_x)/2.0
y_correct = r*np.sin(phi)+float(mic_y)/2.0

print 'Original pixel coordinates: {0:6d},{1:6d}'.format(int(x_original),int(y_original))
print 'Corrected pixel coordinates: {0:6d},{1:6d}'.format(int(x_correct),int(y_correct))

##############################################################