def _compare_positions(a, b, max_dist=0.003, max_angle=5.): """Compare estimated cHPI positions""" from scipy.interpolate import interp1d trans, rot, t = a trans_est, rot_est, t_est = b quats_est = _rot_to_quat(rot_est) # maxfilter produces some times that are implausibly large (weird) use_mask = (t >= t_est[0]) & (t <= t_est[-1]) t = t[use_mask] trans = trans[use_mask] quats = _rot_to_quat(rot) quats = quats[use_mask] # double-check our angle function for q in (quats, quats_est): angles = _angle_between_quats(q, q) assert_allclose(angles, 0., atol=1e-5) # < 3 mm translation difference between MF and our estimation trans_est_interp = interp1d(t_est, trans_est, axis=0)(t) worst = np.sqrt(np.sum((trans - trans_est_interp) ** 2, axis=1)).max() assert_true(worst <= max_dist, '%0.1f > %0.1f mm' % (1000 * worst, 1000 * max_dist)) # < 5 degrees rotation difference between MF and our estimation # (note that the interpolation will make this slightly worse) quats_est_interp = interp1d(t_est, quats_est, axis=0)(t) worst = 180 * _angle_between_quats(quats_est_interp, quats).max() / np.pi assert_true(worst <= max_angle, '%0.1f > %0.1f deg' % (worst, max_angle,))
def _compare_positions(a, b, max_dist=0.003, max_angle=5.): """Compare estimated cHPI positions""" from scipy.interpolate import interp1d trans, rot, t = a trans_est, rot_est, t_est = b quats_est = _rot_to_quat(rot_est) # maxfilter produces some times that are implausibly large (weird) use_mask = (t >= t_est[0]) & (t <= t_est[-1]) t = t[use_mask] trans = trans[use_mask] quats = _rot_to_quat(rot) quats = quats[use_mask] # double-check our angle function for q in (quats, quats_est): angles = _angle_between_quats(q, q) assert_allclose(angles, 0., atol=1e-5) # < 3 mm translation difference between MF and our estimation trans_est_interp = interp1d(t_est, trans_est, axis=0)(t) worst = np.sqrt(np.sum((trans - trans_est_interp)**2, axis=1)).max() assert_true(worst <= max_dist, '%0.1f > %0.1f mm' % (1000 * worst, 1000 * max_dist)) # < 5 degrees rotation difference between MF and our estimation # (note that the interpolation will make this slightly worse) quats_est_interp = interp1d(t_est, quats_est, axis=0)(t) worst = 180 * _angle_between_quats(quats_est_interp, quats).max() / np.pi assert_true(worst <= max_angle, '%0.1f > %0.1f deg' % ( worst, max_angle, ))
def test_quaternions(): """Test quaternion calculations """ rots = [np.eye(3)] for fname in [test_fif_fname, ctf_fname, hp_fif_fname]: rots += [read_info(fname)['dev_head_t']['trans'][:3, :3]] for rot in rots: assert_allclose(rot, _quat_to_rot(_rot_to_quat(rot)), rtol=1e-5, atol=1e-5) rot = rot[np.newaxis, np.newaxis, :, :] assert_allclose(rot, _quat_to_rot(_rot_to_quat(rot)), rtol=1e-5, atol=1e-5) # let's make sure our angle function works in some reasonable way for ii in range(3): for jj in range(3): a = np.zeros(3) b = np.zeros(3) a[ii] = 1. b[jj] = 1. expected = np.pi if ii != jj else 0. assert_allclose(_angle_between_quats(a, b), expected, atol=1e-5)
def test_quaternions(): """Test quaternion calculations """ rots = [np.eye(3)] for fname in [test_fif_fname, ctf_fname, hp_fif_fname]: rots += [read_info(fname)['dev_head_t']['trans'][:3, :3]] # nasty numerical cases rots += [ np.array([ [-0.99978541, -0.01873462, -0.00898756], [-0.01873462, 0.62565561, 0.77987608], [-0.00898756, 0.77987608, -0.62587152], ]) ] rots += [ np.array([ [0.62565561, -0.01873462, 0.77987608], [-0.01873462, -0.99978541, -0.00898756], [0.77987608, -0.00898756, -0.62587152], ]) ] rots += [ np.array([ [-0.99978541, -0.00898756, -0.01873462], [-0.00898756, -0.62587152, 0.77987608], [-0.01873462, 0.77987608, 0.62565561], ]) ] for rot in rots: assert_allclose(rot, _quat_to_rot(_rot_to_quat(rot)), rtol=1e-5, atol=1e-5) rot = rot[np.newaxis, np.newaxis, :, :] assert_allclose(rot, _quat_to_rot(_rot_to_quat(rot)), rtol=1e-5, atol=1e-5) # let's make sure our angle function works in some reasonable way for ii in range(3): for jj in range(3): a = np.zeros(3) b = np.zeros(3) a[ii] = 1. b[jj] = 1. expected = np.pi if ii != jj else 0. assert_allclose(_angle_between_quats(a, b), expected, atol=1e-5)