def run_linear(self, image): n_slice, n_ref_rows, n_fe = self.refShape N1 = image.shape[-1] n_conj_rows = n_ref_rows - self.xleave # form the S[u]S*[u+1] array: inv_ref = ifft(image.ref_data[0]) inv_ref = inv_ref[:,:-self.xleave,:] * \ N.conjugate(inv_ref[:,self.xleave:,:]) # Adjust the percentile parameter to reflect the percentage of # points that actually have data (not the pctage of all points). # Do this by determining the fraction of points that pass an # intensity threshold masking step. ir_mask = build_3Dmask(N.abs(inv_ref), 0.1) self.percentile *= ir_mask.sum() / (n_conj_rows * n_slice * n_fe) # partition the phase data based on acquisition order: # pos_order, neg_order define which rows in a slice are grouped # (remember not to count the lines contaminated by artifact!) pos_order = (self.ref_alpha[:n_conj_rows] > 0).nonzero()[0] neg_order = (self.ref_alpha[:n_conj_rows] < 0).nonzero()[0] # in Varian scans, the phase of the 0th product seems to be # contaminated.. so throw it out if there is at least one more # even-odd product # case < 3 ref rows: can't solve problem # case 3 ref rows: p0 from (0,1), n0 from (1,2) # case >=4 ref rows: p0 from (2,3), n0 from (1,2) (can kick line 0) # if the amount of data can support it, throw out p0 if len(pos_order) > 1: pos_order = pos_order[1:] phs_vol = unwrap_ref_volume(inv_ref) phs_mean, q1_mask = mean_and_mask(phs_vol[:, pos_order, :], phs_vol[:, neg_order, :], self.percentile, self.good_slices) ### SOLVE FOR THE SYSTEM PARAMETERS if not self.shear_correct: if self.force_6p_soln: # solve for a1,a2,a3,a4,a5,a6, keep (a1,a3,a5) coefs = solve_phase_6d(phs_mean, q1_mask) coefs = coefs[0::2] else: coefs = solve_phase_3d(phs_mean, q1_mask) print coefs return correction_volume_3d(self.volShape, self.alpha, *coefs) else: coefs = solve_phase_6d(phs_mean, q1_mask) print coefs return correction_volume_6d(self.volShape, self.alpha, self.beta, *coefs)
def run_linear(self, image): n_slice, n_ref_rows, n_fe = self.refShape N1 = image.shape[-1] n_conj_rows = n_ref_rows - self.xleave # form the S[u]S*[u+1] array: inv_ref = ifft(image.ref_data[0]) inv_ref = inv_ref[:, : -self.xleave, :] * N.conjugate(inv_ref[:, self.xleave :, :]) # Adjust the percentile parameter to reflect the percentage of # points that actually have data (not the pctage of all points). # Do this by determining the fraction of points that pass an # intensity threshold masking step. ir_mask = build_3Dmask(N.abs(inv_ref), 0.1) self.percentile *= ir_mask.sum() / (n_conj_rows * n_slice * n_fe) # partition the phase data based on acquisition order: # pos_order, neg_order define which rows in a slice are grouped # (remember not to count the lines contaminated by artifact!) pos_order = (self.ref_alpha[:n_conj_rows] > 0).nonzero()[0] neg_order = (self.ref_alpha[:n_conj_rows] < 0).nonzero()[0] # in Varian scans, the phase of the 0th product seems to be # contaminated.. so throw it out if there is at least one more # even-odd product # case < 3 ref rows: can't solve problem # case 3 ref rows: p0 from (0,1), n0 from (1,2) # case >=4 ref rows: p0 from (2,3), n0 from (1,2) (can kick line 0) # if the amount of data can support it, throw out p0 if len(pos_order) > 1: pos_order = pos_order[1:] phs_vol = unwrap_ref_volume(inv_ref) phs_mean, q1_mask = mean_and_mask( phs_vol[:, pos_order, :], phs_vol[:, neg_order, :], self.percentile, self.good_slices ) ### SOLVE FOR THE SYSTEM PARAMETERS if not self.shear_correct: if self.force_6p_soln: # solve for a1,a2,a3,a4,a5,a6, keep (a1,a3,a5) coefs = solve_phase_6d(phs_mean, q1_mask) coefs = coefs[0::2] else: coefs = solve_phase_3d(phs_mean, q1_mask) print coefs return correction_volume_3d(self.volShape, self.alpha, *coefs) else: coefs = solve_phase_6d(phs_mean, q1_mask) print coefs return correction_volume_6d(self.volShape, self.alpha, self.beta, *coefs)
def run_centric(self, image): # centric sampling for epidw goes [0,..,31] then [-1,..,-32] # in index terms this is [32,33,..,63] + [31,30,..,0] # solving for angle(S[u]S*[u+1]) is equal to the basic problem for u>=0 # for u<0: # angle(S[u]S*[u+1]) = 2[sign-flip-terms]*(-1)^(u+1) + [shear-terms] # = -(2[sign-flip-terms]*(-1)^u - [shear-terms]) # so by flipping the sign on the phs means data, we can solve for the # sign-flipping (raster) terms and the DC offset terms with the same # equations. n_slice, n_ref_rows, n_fe = self.refShape n_vol_rows = self.volShape[-2] n_conj_rows = n_ref_rows - 2 # this is S[u]S*[u+1].. now with n_ref_rows-1 rows inv_ref = ifft(image.ref_data[0]) inv_ref = inv_ref[:, :-1, :] * N.conjugate(inv_ref[:, 1:, :]) # Adjust the percentile parameter to reflect the percentage of # points that actually have data (not the pctage of all points). # Do this by determining the fraction of points that pass an # intensity threshold masking step. ir_mask = build_3Dmask(N.abs(inv_ref), 0.1) self.percentile *= ir_mask.sum() / (n_conj_rows * (n_slice * n_fe)) # in the lower segment, do NOT grab the n_ref_rows/2-th line.. # its product spans the two segments cnj_upper = inv_ref[:, n_ref_rows / 2:, :].copy() cnj_lower = inv_ref[:, :n_ref_rows / 2 - 1, :].copy() phs_evn_upper = unwrap_ref_volume(cnj_upper[:, 0::2, :]) phs_odd_upper = unwrap_ref_volume(cnj_upper[:, 1::2, :]) # 0th phase diff on the upper trajectory is contaminated by eddy curr, # throw it out if possible: if phs_evn_upper.shape[-2] > 1: phs_evn_upper = phs_evn_upper[:, 1:, :] phs_evn_lower = unwrap_ref_volume(cnj_lower[:, 0::2, :]) phs_odd_lower = unwrap_ref_volume(cnj_lower[:, 1::2, :]) # 0th phase diff on downward trajectory (== S[u]S*[u+1] for u=-30) # is contaminated too if phs_evn_lower.shape[-2] > 1: phs_evn_lower = phs_evn_lower[:, :-1, :] phs_mean_upper, q1_mask_upper = \ mean_and_mask(phs_evn_upper, phs_odd_upper, self.percentile, self.good_slices) phs_mean_lower, q1_mask_lower = \ mean_and_mask(phs_evn_lower, phs_odd_lower, self.percentile, self.good_slices) if not self.shear_correct: # for upper (u>=0), solve normal SVD if self.force_6p_soln: coefs = solve_phase_6d(phs_mean_upper, q1_mask_upper) coefs = coefs[0::2] else: coefs = solve_phase_3d(phs_mean_upper, q1_mask_upper) print coefs theta_upper = correction_volume_3d(self.volShape, self.alpha, *coefs) # for lower (u < 0), solve with negative data if self.force_6p_soln: coefs = solve_phase_6d(-phs_mean_lower, q1_mask_lower) coefs = coefs[0::2] else: coefs = solve_phase_3d(-phs_mean_lower, q1_mask_lower) print coefs theta_lower = correction_volume_3d(self.volShape, self.alpha, *coefs) theta_lower[:, n_vol_rows / 2:, :] = theta_upper[:, n_vol_rows / 2:, :] return theta_lower else: # for upper (u>=0), solve normal SVD coefs = solve_phase_6d(phs_mean_upper, q1_mask_upper) print coefs theta_upper = correction_volume_6d(self.volShape, self.alpha, self.beta, *coefs) # for lower (u < 0), solve with negative data coefs = solve_phase_6d(-phs_mean_lower, q1_mask_lower) print coefs theta_lower = correction_volume_6d(self.volShape, self.alpha, self.beta, *coefs) theta_lower[:, n_vol_rows / 2:, :] = theta_upper[:, n_vol_rows / 2:, :] return theta_lower
def run_centric(self, image): # centric sampling for epidw goes [0,..,31] then [-1,..,-32] # in index terms this is [32,33,..,63] + [31,30,..,0] # solving for angle(S[u]S*[u+1]) is equal to the basic problem for u>=0 # for u<0: # angle(S[u]S*[u+1]) = 2[sign-flip-terms]*(-1)^(u+1) + [shear-terms] # = -(2[sign-flip-terms]*(-1)^u - [shear-terms]) # so by flipping the sign on the phs means data, we can solve for the # sign-flipping (raster) terms and the DC offset terms with the same # equations. n_slice, n_ref_rows, n_fe = self.refShape n_vol_rows = self.volShape[-2] n_conj_rows = n_ref_rows - 2 # this is S[u]S*[u+1].. now with n_ref_rows-1 rows inv_ref = ifft(image.ref_data[0]) inv_ref = inv_ref[:, :-1, :] * N.conjugate(inv_ref[:, 1:, :]) # Adjust the percentile parameter to reflect the percentage of # points that actually have data (not the pctage of all points). # Do this by determining the fraction of points that pass an # intensity threshold masking step. ir_mask = build_3Dmask(N.abs(inv_ref), 0.1) self.percentile *= ir_mask.sum() / (n_conj_rows * (n_slice * n_fe)) # in the lower segment, do NOT grab the n_ref_rows/2-th line.. # its product spans the two segments cnj_upper = inv_ref[:, n_ref_rows / 2 :, :].copy() cnj_lower = inv_ref[:, : n_ref_rows / 2 - 1, :].copy() phs_evn_upper = unwrap_ref_volume(cnj_upper[:, 0::2, :]) phs_odd_upper = unwrap_ref_volume(cnj_upper[:, 1::2, :]) # 0th phase diff on the upper trajectory is contaminated by eddy curr, # throw it out if possible: if phs_evn_upper.shape[-2] > 1: phs_evn_upper = phs_evn_upper[:, 1:, :] phs_evn_lower = unwrap_ref_volume(cnj_lower[:, 0::2, :]) phs_odd_lower = unwrap_ref_volume(cnj_lower[:, 1::2, :]) # 0th phase diff on downward trajectory (== S[u]S*[u+1] for u=-30) # is contaminated too if phs_evn_lower.shape[-2] > 1: phs_evn_lower = phs_evn_lower[:, :-1, :] phs_mean_upper, q1_mask_upper = mean_and_mask(phs_evn_upper, phs_odd_upper, self.percentile, self.good_slices) phs_mean_lower, q1_mask_lower = mean_and_mask(phs_evn_lower, phs_odd_lower, self.percentile, self.good_slices) if not self.shear_correct: # for upper (u>=0), solve normal SVD if self.force_6p_soln: coefs = solve_phase_6d(phs_mean_upper, q1_mask_upper) coefs = coefs[0::2] else: coefs = solve_phase_3d(phs_mean_upper, q1_mask_upper) print coefs theta_upper = correction_volume_3d(self.volShape, self.alpha, *coefs) # for lower (u < 0), solve with negative data if self.force_6p_soln: coefs = solve_phase_6d(-phs_mean_lower, q1_mask_lower) coefs = coefs[0::2] else: coefs = solve_phase_3d(-phs_mean_lower, q1_mask_lower) print coefs theta_lower = correction_volume_3d(self.volShape, self.alpha, *coefs) theta_lower[:, n_vol_rows / 2 :, :] = theta_upper[:, n_vol_rows / 2 :, :] return theta_lower else: # for upper (u>=0), solve normal SVD coefs = solve_phase_6d(phs_mean_upper, q1_mask_upper) print coefs theta_upper = correction_volume_6d(self.volShape, self.alpha, self.beta, *coefs) # for lower (u < 0), solve with negative data coefs = solve_phase_6d(-phs_mean_lower, q1_mask_lower) print coefs theta_lower = correction_volume_6d(self.volShape, self.alpha, self.beta, *coefs) theta_lower[:, n_vol_rows / 2 :, :] = theta_upper[:, n_vol_rows / 2 :, :] return theta_lower