def normalize_mc_params(params, source): """ Normalize a single row of motion parameters to the SPM format. SPM saves motion parameters as: x Right-Left (mm) y Anterior-Posterior (mm) z Superior-Inferior (mm) rx Pitch (rad) ry Roll (rad) rz Yaw (rad) """ if source.upper() == 'FSL': params = params[[3, 4, 5, 0, 1, 2]] elif source.upper() in ('AFNI', 'FSFAST'): params = params[np.asarray([4, 5, 3, 1, 2, 0]) + (len(params) > 6)] params[3:] = params[3:] * np.pi / 180. elif source.upper() == 'NIPY': from nipy.algorithms.registration import to_matrix44, aff2euler matrix = to_matrix44(params) params = np.zeros(6) params[:3] = matrix[:3, 3] params[-1:2:-1] = aff2euler(matrix) return params
def _get_affine_matrix(params, source): """Return affine matrix given a set of translation and rotation parameters params : np.array (upto 12 long) in native package format source : the package that generated the parameters supports SPM, AFNI, FSFAST, FSL, NIPY """ if source == 'FSL': params = params[[3, 4, 5, 0, 1, 2]] elif source in ('AFNI', 'FSFAST'): params = params[np.asarray([4, 5, 3, 1, 2, 0]) + (len(params) > 6)] params[3:] = params[3:] * np.pi / 180. if source == 'NIPY': # nipy does not store typical euler angles, use nipy to convert from nipy.algorithms.registration import to_matrix44 return to_matrix44(params) # process for FSL, SPM, AFNI and FSFAST rotfunc = lambda x: np.array([[np.cos(x), np.sin(x)], [-np.sin(x), np.cos(x)]]) q = np.array([0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0]) if len(params) < 12: params = np.hstack((params, q[len(params):])) params.shape = (len(params),) # Translation T = np.eye(4) T[0:3, -1] = params[0:3] # Rotation Rx = np.eye(4) Rx[1:3, 1:3] = rotfunc(params[3]) Ry = np.eye(4) Ry[(0, 0, 2, 2), (0, 2, 0, 2)] = rotfunc(params[4]).ravel() Rz = np.eye(4) Rz[0:2, 0:2] = rotfunc(params[5]) # Scaling S = np.eye(4) S[0:3, 0:3] = np.diag(params[6:9]) # Shear Sh = np.eye(4) Sh[(0, 0, 1), (1, 2, 2)] = params[9:12] if source in ('AFNI', 'FSFAST'): return np.dot(T, np.dot(Ry, np.dot(Rx, np.dot(Rz, np.dot(S, Sh))))) return np.dot(T, np.dot(Rx, np.dot(Ry, np.dot(Rz, np.dot(S, Sh)))))
def _get_affine_matrix(params, source): """Return affine matrix given a set of translation and rotation parameters params : np.array (upto 12 long) in native package format source : the package that generated the parameters supports SPM, AFNI, FSFAST, FSL, NIPY """ if source == 'FSL': params = params[[3, 4, 5, 0, 1, 2]] elif source in ('AFNI', 'FSFAST'): params = params[np.asarray([4, 5, 3, 1, 2, 0]) + (len(params) > 6)] params[3:] = params[3:] * np.pi / 180. if source == 'NIPY': # nipy does not store typical euler angles, use nipy to convert from nipy.algorithms.registration import to_matrix44 return to_matrix44(params) #process for FSL, SPM, AFNI and FSFAST rotfunc = lambda x: np.array([[np.cos(x), np.sin(x)], [-np.sin(x), np.cos(x)]]) q = np.array([0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0]) if len(params) < 12: params = np.hstack((params, q[len(params):])) params.shape = (len(params), ) # Translation T = np.eye(4) T[0:3, -1] = params[0:3] # Rotation Rx = np.eye(4) Rx[1:3, 1:3] = rotfunc(params[3]) Ry = np.eye(4) Ry[(0, 0, 2, 2), (0, 2, 0, 2)] = rotfunc(params[4]).ravel() Rz = np.eye(4) Rz[0:2, 0:2] = rotfunc(params[5]) # Scaling S = np.eye(4) S[0:3, 0:3] = np.diag(params[6:9]) # Shear Sh = np.eye(4) Sh[(0, 0, 1), (1, 2, 2)] = params[9:12] if source in ('AFNI', 'FSFAST'): return np.dot(T, np.dot(Ry, np.dot(Rx, np.dot(Rz, np.dot(S, Sh))))) return np.dot(T, np.dot(Rx, np.dot(Ry, np.dot(Rz, np.dot(S, Sh)))))