Source code for continuousflex.protocols.utilities.dynamo
# This function converts a Dynamo table into xmipp (scipion) metadata file
# given a metadata input containing a list of the subtomograms
from pwem.emlib import metadata as md
import numpy as np
from math import sin, cos, radians
from xmippLib import Euler_matrix2angles
import pandas as pd
import math
[docs]def dynamo_mat(tdrot, tilt, narot, shiftx, shifty, shiftz):
tdrot = radians(tdrot)
tilt = radians(tilt)
narot = radians(narot)
cotd = cos(tdrot)
sitd = sin(tdrot)
coti = cos(tilt)
siti = sin(tilt)
cona = cos(narot)
sina = sin(narot)
m = np.zeros([4,4])
m[0,0] = cotd * cona - sitd * coti * sina
m[1,0] = - cona * sitd - cotd * coti * sina
m[2,0] = sina * siti
m[0,1] = cotd * sina + cona * sitd * coti
m[1,1] = cotd * cona * coti - sitd * sina
m[2,1] = -cona * siti
m[0,2] = sitd * siti
m[1,2] = cotd * siti
m[2,2] = coti
# The 4th column
m[0,3] = shiftx
m[1,3] = shifty
m[2,3] = shiftz
m[3,3] = 1
return m
[docs]def matrix2eulerAngles(A):
abs_sb = np.sqrt(A[0, 2] * A[0, 2] + A[1, 2] * A[1, 2])
if (abs_sb > 16 * np.exp(-5)):
gamma = math.atan2(A[1, 2], -A[0, 2])
alpha = math.atan2(A[2, 1], A[2, 0])
if (abs(np.sin(gamma)) < np.exp(-5)):
sign_sb = np.sign(-A[0, 2] / np.cos(gamma))
else:
if np.sin(gamma) > 0:
sign_sb = np.sign(A[1, 2])
else:
sign_sb = -np.sign(A[1, 2])
beta = math.atan2(sign_sb * abs_sb, A[2, 2])
else:
if (np.sign(A[2, 2]) > 0):
alpha = 0
beta = 0
gamma = math.atan2(-A[1, 0], A[0, 0])
else:
alpha = 0
beta = np.pi
gamma = math.atan2(A[1, 0], -A[0, 0])
gamma = np.rad2deg(gamma)
beta = np.rad2deg(beta)
alpha = np.rad2deg(alpha)
return alpha, beta, gamma, A[0, 3], A[1, 3], A[2, 3]
[docs]def tbl2metadata(table, mdfi, mdfo):
tbl = pd.read_csv(table, delimiter=' ', header=None)
x = tbl[:][3]
y = tbl[:][4]
z = tbl[:][5]
tdrot = tbl[:][6]
tiltd = tbl[:][7]
narot = tbl[:][8]
# change the angles from Dynamo convention to xmipp convention
rot = []
tilt = []
psi = []
shiftx = []
shifty = []
shiftz = []
for i in range(tbl.shape[0]):
TransMat = dynamo_mat(tdrot[i], tiltd[i], narot[i], x[i], y[i], z[i])
rot_i, tilt_i, psi_i, shiftx_i, shifty_i, shiftz_i = matrix2eulerAngles(TransMat)
rot.append(rot_i)
tilt.append(tilt_i)
psi.append(psi_i)
shiftx.append(shiftx_i)
shifty.append(shifty_i)
shiftz.append(shiftz_i)
md_out = md.MetaData(mdfi)
i = 0
for objId in md_out:
md_out.setValue(md.MDL_SHIFT_X, shiftx[i],objId)
md_out.setValue(md.MDL_SHIFT_Y, shifty[i],objId)
md_out.setValue(md.MDL_SHIFT_Z, shiftz[i], objId)
md_out.setValue(md.MDL_ANGLE_ROT, rot[i], objId)
md_out.setValue(md.MDL_ANGLE_TILT, tilt[i], objId)
md_out.setValue(md.MDL_ANGLE_PSI, psi[i], objId)
md_out.setValue(md.MDL_ANGLE_Y, 0.0, objId)
i += 1
pass
md_out.write(mdfo)