def fractional_anisotropy_std(d, dperp0, dperp1, d_std, dperp0_std, dperp1_std, covariances=None): """Calculate the standard deviation of the fractional anisotropy (FA) using error propagation. Args: d (ndarray): an 1d array dperp0 (ndarray): an 1d array dperp1 (ndarray): an 1d array d_std (ndarray): an 1d array dperp0_std (ndarray): an 1d array dperp1_std (ndarray): an 1d array covariances (dict): optionally, a matrix holding the covariances. This expects the keys to be like: '<param_0>_to_<param_1>'. The order of the parameter names does not matter. Returns: ndarray: the standard deviation of the fraction anisotropy using error propagation of the diffusivities. """ gradient = DTIMeasures._get_fractional_anisotropy_gradient( d, dperp0, dperp1) covars = create_covariance_matrix(d.shape[0], { 'd.std': d_std, 'dperp0.std': dperp0_std, 'dperp1.std': dperp1_std }, ['d', 'dperp0', 'dperp1'], covariances) return np.nan_to_num( np.sqrt( voxelwise_vector_matrix_vector_product(gradient, covars, gradient)))
def extra_output_maps(results): np.warnings.filterwarnings('ignore') Rb, RM0a, fterm, gM0a, T1a_T2a, s0 = [ np.squeeze(results[n]) for n in ('QMT.Rb', 'QMT.RM0a', 'QMT.fterm', 'QMT.gM0a', 'QMT.T1a_T2a', 'S0.s0') ] Rb_std, RM0a_std, fterm_std, gM0a_std, T1a_T2a_std, s0_std = [ np.squeeze(results.get(n + '.std', 0)) for n in ('QMT.Rb', 'QMT.RM0a', 'QMT.fterm', 'QMT.gM0a', 'QMT.T1a_T2a', 'S0.s0') ] R_obs = 1. / results.get_input_data('T1') if len(R_obs.shape) > 1: R_obs = R_obs[:, 0] Ra = R_obs / (1.0 + ((RM0a * fterm * (Rb - R_obs)) / (Rb - R_obs + RM0a))) f = fterm * Ra / (1.0 + fterm * Ra) covars = create_covariance_matrix(f.shape[0], results, ['QMT.RM0a', 'QMT.fterm', 'QMT.Rb'], results.get('covariances', None)) Ra_gradient = get_ra_gradient(R_obs, RM0a, fterm, Rb) Ra_std = np.nan_to_num( np.sqrt( voxelwise_vector_matrix_vector_product(Ra_gradient, covars, Ra_gradient))) f_gradient = get_f_gradient(R_obs, RM0a, fterm, Rb) f_std = np.nan_to_num( np.sqrt( voxelwise_vector_matrix_vector_product(f_gradient, covars, f_gradient))) values = { 'QMT.PD': gM0a * s0, 'QMT.T1_f': 1.0 / Ra, 'QMT.T2_f': (1.0 / Ra) / T1a_T2a, 'QMT.k_bf': RM0a * f / (1.0 - f), 'QMT.f_b': f, 'QMT.Ra': Ra, } values.update({ 'QMT.PD.std': np.nan_to_num(np.sqrt(gM0a**2 * s0_std + s0**2 * gM0a_std)), 'QMT.T1_f.std': np.nan_to_num(np.sqrt(Ra_std / Ra**4)), 'QMT.T2_f.std': np.nan_to_num( np.sqrt((Ra**2 * T1a_T2a_std + Ra_std * T1a_T2a**2) / (Ra**4 * T1a_T2a**4))), 'QMT.k_bf.std': np.nan_to_num( np.sqrt((RM0a**2 * f_std + RM0a_std * f**2 * (f - 1.0)**2) / (f - 1.0)**4)), 'QMT.f_b.std': f_std, 'QMT.Ra.std': Ra_std, }) return values