Hello,
I am writing a script to convert my aretomo3 imod-style .xf file and .tlt file into a json to do an EMAN2 reconstruction with the --load flag. I have kind of used a combination of Alistair Burt's
emanjson2imodxf and tomoguide's
aretomo3torelion5. But I am noticing some discrepancies between how imod and eman2 reconstruct and I was wondering if you could help.
This is my code:
def readxf(xf_file, tlt_file):
# EMAN translates then rotates, IMOD rotates then translates
# R(x+dx, y+dy) = R(x, y) + R(dx, dy)
# IMOD (dx, dy) is the rotated EMAN (dx, dy)
xf_array = np.loadtxt(xf_file) #load imod xf file
tlt_array = np.loadtxt(tlt_file) #load imod tlt file
A11 = xf_array[:,0] #column 1 in xf 0,0 of 2D rot matrix
A12 = xf_array[:,1] #column 2 in xf 0,1 of 2D rot matrix
A21 = xf_array[:,2] #column 3 in xf 1,0 of 2D rot matrix
A22 = xf_array[:,3] #column 4 in xf 1,1 of 2D rot matrix
dx_imod = xf_array[:,4] #column 5 in xf, shift in x
dy_imod = xf_array[:,5] #column 6 in xf shift in y
rotation_matrices = np.zeros([len(A11),3,3]) #make empty array to put xf file data into 3x3 transformation matrices
rotation_matrices[:, 0, 0] = A11
rotation_matrices[:, 0, 1] = A12
rotation_matrices[:, 1, 0] = A21
rotation_matrices[:, 1, 1] = A22
rotation_matrices[:, 0, 2] = dx_imod
rotation_matrices[:, 1, 2] = dy_imod
rotation_matrices[:, 2, 2] = [1.0]*len(A11)
T_inv = np.linalg.inv(rotation_matrices) #invert matrices to find shift in eman
dx_eman = T_inv[:,0,2]
dy_eman = T_inv[:,1,2]
z_rot = np.degrees(np.arctan2(A12,A11))#find refined tilt axis in degrees
y_tilt = tlt_array #list of tilt angles from tlt
x_tilt = [0.0]*len(A11) #xtilt is 0
return dx_eman, dy_eman, z_rot, y_tilt, x_tilt
def imodxf2emanjson(xf_file, tlt_file): #tomoguide for aretomo to relion
Path('info').mkdir(parents=True, exist_ok=True) #make directory in eman style structure
json_name = f'info/{tomo_name}_info.json' #name of json
tomo_json = js_open_dict(json_name) #open empty json
dx, dy, z_rot, y_tilt, x_tilt = readxf(xf_file, tlt_file) #get data from xf file
json = np.stack((dx, dy, z_rot, y_tilt, x_tilt), axis=-1) #xf data in correct format
tomo_json['apix_unbin'] = '2.21' #pixel size angstroms
tomo_json['tlt_file']="tiltseries/tomo01.mrc.hdf" #tilt series path
tomo_json['tlt_params'] = json #write xf data to json tlt_params
When I use the tilt axis calculated from the xf file (-90.17) my tomogram is a 180 degree rotation about z away from the imod reconstruction. I noticed that in the documentation it says imod stores the tilt axis with the opposite sign (90.17) which would be 180 degrees away, but when I reconstruct with this the z seems to be flipped (more like 180 about y and 90 about z). I have attached screenshots for reference (slice number is the z slice).
Many thanks,
Molly