def solve_phase_degen(data_xx, data_yy, model_xx, model_yy, ubls, plot=False):#data should be time by ubl at single freq. data * phasegensolution = model if data_xx.shape != data_yy.shape or data_xx.shape != model_xx.shape or data_xx.shape != model_yy.shape or data_xx.shape[1] != ubls.shape[0]: raise ValueError("Shapes mismatch: %s %s %s %s, ubl shape %s"%(data_xx.shape, data_yy.shape, model_xx.shape, model_yy.shape, ubls.shape)) A = np.zeros((len(ubls) * 2, 2)) b = np.zeros(len(ubls) * 2) nrow = 0 for p, (data, model) in enumerate(zip([data_xx, data_yy], [model_xx, model_yy])): for u, ubl in enumerate(ubls): amp_mask = (np.abs(data[:, u]) > (np.median(np.abs(data[:, u])) / 2.)) A[nrow] = ubl[:2] b[nrow] = omni.medianAngle(np.angle(model[:, u] / data[:, u])[amp_mask]) nrow += 1 if plot: plt.hist((np.array(A).dot(phase_cal)-b + PI)%TPI-PI) plt.title('phase fitting error') plt.show() #sooolve return omni.solve_slope(np.array(A), np.array(b), 1)
matrix = (la.pinv(A.transpose().dot(A)).dot(A.transpose())) solution[pol] = matrix.dot(avg_angle.transpose()) ##use delay fit to further correct rephasing degeneracies in linearcalpar avg_angle_error = np.angle(linearcalpar[pol]) - np.outer(np.arange(nfreq) * dfreq + startfreq, solution[pol][0]) - solution[pol][1] avg_angle_error = (avg_angle_error + PI)%TPI - PI fit_degen = avg_angle_error.dot(AAA.transpose()) fit_degen[np.isnan(fit_degen)] = 0 linearcalpar[pol] = linearcalpar[pol] / np.exp(1.j*fit_degen) avg_angle_error = (avg_angle_error - fit_degen + PI)%TPI - PI #remove degeneracy in solution solution_degen = np.zeros_like(solution[pol]) solution_degen[1] = omni.medianAngle(solution[pol][1]) solution[pol][1] = (solution[pol][1] - solution_degen[1] + PI) % TPI - PI for sdi in range(5): solution_degen = solution_degen + solution[pol].dot(AAA.transpose()) solution[pol] = solution[pol] - solution[pol].dot(AAA.transpose()) solution[pol][1] = (solution[pol][1] + PI) % TPI - PI delay[pol][calibrators[pol].Info.subsetant] = solution[pol][0] / TPI #print la.norm(solution[pol][1]) linearcalpar[pol] = linearcalpar[pol] / np.exp(1.j* (np.outer(np.arange(nfreq) * dfreq + startfreq, solution_degen[0]) + solution_degen[1])) #for flagged frequencies, use NaN#the phase model model_phase = np.array([(np.arange(nfreq)*dfreq + startfreq) * solution[pol][0, a] + solution[pol][1, a] for a in range(linearcalpar[pol].shape[1])]).transpose() linearcalpar[pol][freq_flag] = np.nan#np.exp(1.j * model_phase[freq_flag]) linearcalpar[pol][np.isnan(linearcalpar[pol])] = np.nan#np.exp(1.j * model_phase[np.isnan(linearcalpar[pol])]) #also create linearcalpar counter part that is purely the model phase and unity amp
cdata[p] = omni.apply_calpar2(rawdata[p], crosscalpar[pol[0]], crosscalpar[pol[1]], c.totalVisibilityId) del(rawdata) ################################################################################# ############################solve for overall constant########################### ################################################################################# crossextract, cross_chisq = omni.extract_crosspol_ubl(cdata, c.Info.get_info()) red_enough = c.ublcount > (max(c.ublcount) / 2) #treat all ubls above half max ublcount equally when computing the x-y angle xy_candidates = np.empty(list(cdata.shape)[1:3] + [np.sum(red_enough)], dtype='float32') for i,u in enumerate(np.arange(c.nUBL)[red_enough].astype(int)): xy_candidates[..., i] = np.angle(crossextract[0,...,u]/crossextract[1,...,u]) with warnings.catch_warnings(): warnings.filterwarnings("ignore",category=RuntimeWarning) overall_angle = omni.medianAngle(xy_candidates, axis = -1) / 2 median_overall_angle = omni.medianAngle(omni.medianAngle(xy_candidates, axis = -1), axis = 0) / 2 prev_valid = -1 for i in range(1, len(median_overall_angle)): if not (np.isnan(median_overall_angle[i-1]) or (prev_valid >= 0 and abs((median_overall_angle[i-1] - median_overall_angle[prev_valid] + PI/2)%PI-PI/2) > PI/4)): prev_valid = i - 1 if prev_valid >= 0: offset = median_overall_angle[prev_valid]-PI/2 else: offset = -PI/2 median_overall_angle[i] = (median_overall_angle[i] - offset)%(PI) + offset offset = median_overall_angle[None]-PI/2 overall_angle = (overall_angle - offset)%(PI) + offset if make_plots:
solution[pol] = matrix.dot(avg_angle.transpose()) ##use delay fit to further correct rephasing degeneracies in linearcalpar avg_angle_error = np.angle(linearcalpar[pol]) - np.outer( np.arange(nfreq) * dfreq + startfreq, solution[pol][0]) - solution[pol][1] avg_angle_error = (avg_angle_error + PI) % TPI - PI fit_degen = avg_angle_error.dot(AAA.transpose()) fit_degen[np.isnan(fit_degen)] = 0 linearcalpar[pol] = linearcalpar[pol] / np.exp(1.j * fit_degen) avg_angle_error = (avg_angle_error - fit_degen + PI) % TPI - PI #remove degeneracy in solution solution_degen = np.zeros_like(solution[pol]) solution_degen[1] = omni.medianAngle(solution[pol][1]) solution[pol][1] = (solution[pol][1] - solution_degen[1] + PI) % TPI - PI for sdi in range(5): solution_degen = solution_degen + solution[pol].dot( AAA.transpose()) solution[pol] = solution[pol] - solution[pol].dot( AAA.transpose()) solution[pol][1] = (solution[pol][1] + PI) % TPI - PI delay[pol][calibrators[pol].Info. subsetant] = solution[pol][0] / TPI #print la.norm(solution[pol][1]) linearcalpar[pol] = linearcalpar[pol] / np.exp(1.j * (np.outer( np.arange(nfreq) * dfreq + startfreq, solution_degen[0]) + solution_degen[1]))
matrix = (la.pinv(A.transpose().dot(A)).dot(A.transpose())) solution[pol] = matrix.dot(avg_angle.transpose()) ##use delay fit to further correct rephasing degeneracies in linearcalpar avg_angle_error = np.angle(linearcalpar[pol]) - np.outer(np.arange(nfreq) * dfreq + startfreq, solution[pol][0]) - solution[pol][1] avg_angle_error = (avg_angle_error + PI)%TPI - PI fit_degen = avg_angle_error.dot(AAA.transpose()) fit_degen[np.isnan(fit_degen)] = 0 linearcalpar[pol] = linearcalpar[pol] / np.exp(1.j*fit_degen) avg_angle_error = (avg_angle_error - fit_degen + PI)%TPI - PI #remove degeneracy in solution solution_degen = np.zeros_like(solution[pol]) solution_degen[1] = omni.medianAngle(solution[pol][1]) solution[pol][1] = (solution[pol][1] - solution_degen[1] + PI) % TPI - PI for sdi in range(5): solution_degen = solution_degen + solution[pol].dot(AAA.transpose()) solution[pol] = solution[pol] - solution[pol].dot(AAA.transpose()) solution[pol][1] = (solution[pol][1] + PI) % TPI - PI delay[pol][calibrators[pol].Info.subsetant] = solution[pol][0] / TPI #print la.norm(solution[pol][1]) linearcalpar[pol] = linearcalpar[pol] / np.exp(1.j* (np.outer(np.arange(nfreq) * dfreq + startfreq, solution_degen[0]) + solution_degen[1])) #for flagged frequencies, use NaN#the phase model model_phase = np.array([(np.arange(nfreq)*dfreq + startfreq) * solution[pol][0, a] + solution[pol][1, a] for a in range(linearcalpar[pol].shape[1])]).transpose() if input_type != 'odf': linearcalpar[pol][freq_flag] = np.nan#np.exp(1.j * model_phase[freq_flag]) #linearcalpar[pol][np.isnan(linearcalpar[pol])] = np.exp(1.j * model_phase[np.isnan(linearcalpar[pol])])
cdata[p] = omni.apply_calpar2(rawdata[p], crosscalpar[pol[0]], crosscalpar[pol[1]], c.totalVisibilityId) del(rawdata) ################################################################################# ############################solve for overall constant########################### ################################################################################# crossextract, cross_chisq = omni.extract_crosspol_ubl(cdata, c.Info.get_info()) red_enough = c.ublcount > (max(c.ublcount) / 2) #treat all ubls above half max ublcount equally when computing the x-y angle xy_candidates = np.empty(list(cdata.shape)[1:3] + [np.sum(red_enough)], dtype='float32') for i,u in enumerate(np.arange(c.nUBL)[red_enough].astype(int)): xy_candidates[..., i] = np.angle(crossextract[0,...,u]/crossextract[1,...,u]) with warnings.catch_warnings(): warnings.filterwarnings("ignore",category=RuntimeWarning) overall_angle = omni.medianAngle(xy_candidates, axis = -1) / 2 median_overall_angle = omni.medianAngle(xy_candidates.transpose(0,2,1).reshape((xy_candidates.shape[0]*xy_candidates.shape[2],xy_candidates.shape[1])), axis = 0) / 2 prev_valid = -1 valids1 = np.zeros(len(median_overall_angle), dtype='bool') for i in range(1, len(median_overall_angle)): if not (np.isnan(median_overall_angle[i-1]) or (prev_valid >= 0 and abs((median_overall_angle[i-1] - median_overall_angle[prev_valid] + PI/2)%PI-PI/2) > PI/4)): prev_valid = i - 1 valids1[i-1] = True if prev_valid >= 0: offset = median_overall_angle[prev_valid]-PI/2 else: offset = -PI/2 median_overall_angle[i] = (median_overall_angle[i] - offset)%(PI) + offset offset = median_overall_angle[None]-PI/2