def extract_data(catalogue, image_filename): """ Gets the RHT angle average from the pixels in the square around each star. Also gets the star's polarisation angle and error, aswell as its distance and error. """ # Star polarisation angle, polarisation error and distance data = pd.read_csv(catalogue) good_indices = get_indices_of_stars(catalogue, image_filename) pol_angle = data['pa'][good_indices] err_pol_angle = data['e_pa'][good_indices] dist = data['r_est'][good_indices] dist_err_low = data['r_lo'][good_indices] dist_err_high = data['r_hi'][good_indices] # NOTE: angles from squares not implemented yet. # XX, YY = draw_squares(catalogue, image_filename, square_size) # RHT angle average calculation ipoints, jpoints, hthets, naxis1, naxis2, wlen, smr, thresh = RHT_tools.get_RHT_data( image_filename) h = np.sum(hthets, axis=0) h_norm = h / np.max(h) # Total intensity per angle found, normalised. thets_arr = RHT_tools.get_thets(wlen, save=False) # x-axis containing angles thets_deg = thets_arr * 180 / np.pi return pol_angle, err_pol_angle, dist, dist_err_low, dist_err_high, thets_deg, h_norm
def get_all_RHT_data(image_filename): ipoints, jpoints, hthets, naxis1, naxis2, wlen, smr, thresh = RHT_tools.get_RHT_data( image_filename) thets_arr = RHT_tools.get_thets(wlen, save=False) # x-axis containing angles thets_deg = thets_arr * 180 / np.pi return ipoints, jpoints, hthets, naxis1, naxis2, wlen, smr, thresh, thets_deg
def make_polarplot(image_filename): """ Makes a polarplot of the image_filename. The RHT data is extracted and plotted onto a warped axes from -0.5 to 0.5 pi. This function contains a conversion of the angles hthets to be defined with respect to the RA axis. """ ipoints, jpoints, hthets, naxis1, naxis2, wlen, smr, thresh = RHT_tools.get_RHT_data( image_filename) thetas = np.concatenate(hthets) thetas_norm = thetas / np.max(thetas) thets_arr = RHT_tools.get_thets(wlen, save=False) / np.pi # Units of pi # Convert hthets to be defined w.r.t. RA axis w = WCS(image_filename) RA_hthets, DEC_hthets = w.all_pix2world(ipoints, jpoints, 0) header = fits.getheader(image_filename) rotate_by = (header['CRVAL1'] - RA_hthets) / 180 # Units of pi big_thets_arr_list = [] for index, value in enumerate(rotate_by): big_thets_arr_list.append((thets_arr + rotate_by[index]) % 1) big_thets_arr_list = np.concatenate(big_thets_arr_list) # Convert [0, pi] to [-0.5pi, 0,5pi] as in Jelic et al. 2018 indices_to_shift = np.where(big_thets_arr_list > 0.5) big_thets_arr_list[indices_to_shift] -= 1 # Plotting # If you want fill-between, they need to be in order... this does that. xdata = big_thets_arr_list * np.pi # Convert back to good units ydata = thetas_norm[np.argsort(xdata)] xdata = np.sort(xdata) fig = plt.figure(figsize=(18, 9)) ax1, aux_ax1 = setup_axes(fig, 111, theta=[-0.5 * np.pi, 0.5 * np.pi], radius=[0, ydata.max() * 1.05]) aux_ax1.plot(xdata, ydata, alpha=0.75) # aux_ax1.fill_between(xdata, y1=ydata, y2=0, facecolor='blue', interpolate=True, alpha=0.10) # plt.axhline(np.max(ydata), color='red', alpha=0.75) plt.savefig('polarplot_' + os.path.basename(image_filename).split('.')[0] + '.png', dpi=600, bbox_inches='tight') plt.show()
def bin_data_by_theta(data_fn, nbins=10): """ Places RHT data into cube binned by theta. Input: data_fn :: fits filename for RHT data nbins :: number of theta bins to separate RHT data into (default = 10) Output: theta_separated_backprojection :: 3D array, dimensions (naxis1, naxis2, nbins). :: contains backprojection summed into nbins chunks. """ # Separate into indices and R(theta) arrays ipoints, jpoints, rthetas, naxis1, naxis2 = RHT_tools.get_RHT_data(data_fn) npoints, nthetas = rthetas.shape print("There are %d theta bins" % nthetas) cube_thetas = np.zeros((naxis2, naxis1, nthetas), np.float_) cube_thetas[jpoints, ipoints, :] = rthetas theta_separated_backprojection = np.zeros((naxis2, naxis1, nbins), np.float_) for i in xrange(nbins): theta_separated_backprojection[:, :, i] = np.sum( cube_thetas[:, :, i * nbins:(i + 1) * nbins], axis=2) return theta_separated_backprojection
def get_RHT_data(rht_fn, verbose=False): ipoints, jpoints, rthetas, naxis1, naxis2 = RHT_tools.get_RHT_data(rht_fn) npoints, nthetas = rthetas.shape if verbose: print("There are %d theta bins" % nthetas) return ipoints, jpoints, rthetas, naxis1, naxis2, nthetas
def bin_data_by_theta(data_fn, nbins = 10): """ Places RHT data into cube binned by theta. Input: data_fn :: fits filename for RHT data nbins :: number of theta bins to separate RHT data into (default = 10) Output: theta_separated_backprojection :: 3D array, dimensions (naxis1, naxis2, nbins). :: contains backprojection summed into nbins chunks. """ # Separate into indices and R(theta) arrays ipoints, jpoints, rthetas, naxis1, naxis2 = RHT_tools.get_RHT_data(data_fn) npoints, nthetas = rthetas.shape print("There are %d theta bins" %nthetas) cube_thetas = np.zeros((naxis2, naxis1, nthetas), np.float_) cube_thetas[jpoints, ipoints, :] = rthetas theta_separated_backprojection = np.zeros((naxis2, naxis1, nbins), np.float_) for i in xrange(nbins): theta_separated_backprojection[:, :, i] = np.sum(cube_thetas[:, :, i*nbins:(i+1)*nbins], axis=2) return theta_separated_backprojection
def get_psi0_sampling_grid(self, hp_index, verbose = True): # Create psi0 sampling grid wlen = 75 psi0_sample_db = sqlite3.connect("theta_bin_0_wlen"+str(wlen)+"_db.sqlite") psi0_sample_cursor = psi0_sample_db.cursor() zero_theta = psi0_sample_cursor.execute("SELECT zerotheta FROM theta_bin_0_wlen75 WHERE id = ?", (hp_index,)).fetchone() # Create array of projected thetas from theta = 0 thets = RHT_tools.get_thets(wlen, save = False, verbose = verbose) self.sample_psi0 = np.mod(zero_theta - thets, np.pi) return self.sample_psi0
def plot_sims_and_rht(): """ plot density and RHT backprojection for a single beta at three timestamps """ fig, xarr = plt.subplots(2, 3, figsize=(10,7)) alltimes = ["0010", "0030", "0050"] beta = "20" for i, tstamp in enumerate(alltimes): # get relevant simulation and RHT data fn_rht = get_data_fn("z", 512, beta, tstamp, rhtparams=[25, 1, 0.7], type="density") fn_dens = get_data_fn("z", 512, beta, tstamp, rhtparams=None, type="density") fn_Qsim = get_data_fn("z", 512, beta, tstamp, rhtparams=None, type="Q") fn_Usim = get_data_fn("z", 512, beta, tstamp, rhtparams=None, type="U") rht_im = fits.getdata(fn_rht) dens_im = fits.getdata(fn_dens) Qsim = fits.getdata(fn_Qsim) Usim = fits.getdata(fn_Usim) ysize, xsize = rht_im.shape X, Y = np.meshgrid(np.arange(xsize), np.arange(ysize), indexing='ij') # plot density and backprojection fields xarr[0, i].pcolor(Y, X, np.log10(dens_im)) xarr[1, i].pcolor(Y, X, rht_im) # overplot pseudovectors from Bsim and theta_RHT overplot_vectors(Qsim, Usim, ax=xarr[0, i], norm=True, intrht=False, skipint=25) QRHT, URHT, URHTsq, QRHTsq, intrht = RHT_tools.grid_QU_RHT(fn_rht, save=False) overplot_vectors(QRHT, URHT, ax=xarr[1, i], norm=True, intrht=False, skipint=25) # title from timestamp xarr[0, i].set_title(r"$t = {}$".format(tstamp)) plt.suptitle(r"z, 512, $\beta$ = {}".format(beta)) xarr[0, 0].set_ylabel("log(density), $B_{sim}$ $\mathrm{overlaid}$") xarr[1, 0].set_ylabel(r"$\int R(\theta)$, $\theta_{RHT}$ $\mathrm{overlaid}$")
def single_theta_velocity_cube(theta_0=72, theta_bandwidth=10, wlen=75, smooth_radius=60, gaussian_footprint=True, gauss_footprint_len=5, circular_footprint_radius=3, binary_erode_dilate=True, hilatonly=True): """ Creates cube of Backprojection(x, y, v | theta_0) where dimensions are x, y, and velocity and each velocity slice contains the backprojection for that velocity, at a single theta. theta_0 :: approximate center theta value (in degrees). Actual value will be closest bin in xyt data. theta_bandwidth :: approximate width of theta range desired (in degrees) wlen :: RHT window length """ # Read in all SC_241 *original* data SC_241_original_fn = "/Volumes/DataDavy/GALFA/SC_241/cleaned/SC_241.66_28.675.best.fits" SC_241_all = fits.getdata(SC_241_original_fn) hdr = fits.getheader(SC_241_original_fn) # Velocity data should be third axis SC_241_all = SC_241_all.swapaxes(0, 2) SC_241_all = SC_241_all.swapaxes(0, 1) naxis2, naxis1, nchannels_total = SC_241_all.shape # Get Wide DR2 data in SC_241 region SC_241_wide_fn = "/Volumes/DataDavy/GALFA/DR2/SC_241_Wide/GALFA_HI_W_projected_SC_241.fits" SC_241_wide = fits.getdata(SC_241_wide_fn) SC_241_wide_hdr = fits.getheader(SC_241_wide_fn) # This is pretty slow with the full SC_241 region. I'm going to chop off the 3000 pixels at the lowest latitude. # Change header accordingly. if hilatonly is True: SC_241_all = SC_241_all[:, 3000:, :] SC_241_wide = SC_241_wide[:, :, 3000:] hdr["CRPIX1"] = hdr["CRPIX1"] - 3000 hdr["NAXIS1"] = hdr["NAXIS1"] - 3000 naxis1 = naxis1 - 3000 # Get thetas for given window length thets = RHT_tools.get_thets(wlen) # Get wide and mask velocities for application of mask to final data wide_vels = get_velocity_from_fits(SC_241_wide_fn) mask_vels = get_velocity_from_fits(SC_241_original_fn) # Get index of theta bin that is closest to theta_0 indx_0 = (np.abs(thets - np.radians(theta_0))).argmin() # Get index of beginning and ending thetas that are approximately theta_bandwidth centered on theta_0 indx_start = ( np.abs(thets - (thets[indx_0] - np.radians(theta_bandwidth / 2.0)))).argmin() indx_stop = ( np.abs(thets - (thets[indx_0] + np.radians(theta_bandwidth / 2.0)))).argmin() print("Actual theta range will be {} to {} degrees".format( np.degrees(thets[indx_start]), np.degrees(thets[indx_stop]))) print("Theta indices will be {} to {}".format(indx_start, indx_stop)) # Define velocity channels channels = [16, 17, 18, 19, 20, 21, 22, 23, 24] nchannels = len(channels) # Create a circular footprint for use in erosion / dilation. if gaussian_footprint is True: footprint = make_gaussian_footprint(theta_0=theta_0, wlen=gauss_footprint_len) # Mathematical definition of kernel flips y-axis footprint = footprint[::-1, :] else: footprint = make_circular_footprint(radius=circular_footprint_radius) # Initialize (x, y, v) cube xyv_theta0 = np.zeros((naxis2, naxis1, len(channels) * 4), np.float_) for ch_i, ch_ in enumerate(channels): # Grab channel-specific RHT data data, data_fn = get_data(ch_, verbose=False) ipoints, jpoints, rthetas, naxis1, naxis2 = RHT_tools.get_RHT_data( data_fn) # Sum relevant thetas thetasum_bp = np.zeros((naxis2, naxis1), np.float_) thetasum_bp[jpoints, ipoints] = np.nansum(rthetas[:, indx_start:(indx_stop + 1)], axis=1) if hilatonly is True: thetasum_bp = thetasum_bp[:, 3000:] if binary_erode_dilate is False: # Erode and dilate eroded_thetasum_bp = erode_data(thetasum_bp, footprint=footprint, structure=footprint) dilated_thetasum_bp = dilate_data(eroded_thetasum_bp, footprint=footprint, structure=footprint) # Turn into mask mask = np.ones(dilated_thetasum_bp.shape) mask[dilated_thetasum_bp <= 0] = 0 else: # Try making this a mask first, then binary erosion/dilation masked_thetasum_bp = np.ones(thetasum_bp.shape) masked_thetasum_bp[thetasum_bp <= 0] = 0 mask = binary_erosion(masked_thetasum_bp, structure=footprint) mask = binary_dilation(mask, structure=footprint) # Apply background subtraction to velocity slice. #background_subtracted_data = background_subtract(mask, SC_241_all[:, :, ch_], smooth_radius = smooth_radius, plotresults = False) # Get appropriate velocity slices for background subtraction closestvels = closest_velocities(wide_vels, mask_vels[ch_]) # These need to monotonically ascend closestvels = np.sort(closestvels) # Apply background subtraction to velocity slice. for cv_i, cv in enumerate(closestvels): time0 = time.time() wv_indx = list(wide_vels).index(cv) background_subtracted_data = background_subtract( mask, SC_241_wide[wv_indx, :, :], smooth_radius=smooth_radius, plotresults=False) # Place into channel bin xyv_theta0[:, :, ch_i * 4 + cv_i] = background_subtracted_data print("placing into bin {}".format(ch_i * 4 + cv_i)) time1 = time.time() print("slice {} took {} seconds".format(cv_i, time1 - time0)) hdr["NAXIS3"] = len(channels) * 4 hdr["THETA0"] = theta_0 hdr["THETAB"] = theta_bandwidth hdr["CRVAL3"] = np.nanmin( closest_velocities(wide_vels, mask_vels[channels[0]])) * 1000 # Convert to m/s hdr["CDELT3"] = SC_241_wide_hdr["CDELT3"] # Deal with python fits axis ordering xyv_theta0 = xyv_theta0.swapaxes(0, 2) xyv_theta0 = xyv_theta0.swapaxes(1, 2) fits.writeto( "xyv_theta0_" + str(theta_0) + "_thetabandwidth_" + str(theta_bandwidth) + "_ch" + str(channels[0]) + "_to_" + str(channels[-1]) + "_DR2_W_hilat.fits", xyv_theta0, hdr) return xyv_theta0, hdr, mask
def test_different_erosion_dilations(wlen=75, theta_0=72, theta_bandwidth=10): # Get thetas for given window length thets = RHT_tools.get_thets(wlen) # Get index of theta bin that is closest to theta_0 indx_0 = (np.abs(thets - np.radians(theta_0))).argmin() # Get index of beginning and ending thetas that are approximately theta_bandwidth centered on theta_0 indx_start = ( np.abs(thets - (thets[indx_0] - np.radians(theta_bandwidth / 2.0)))).argmin() indx_stop = ( np.abs(thets - (thets[indx_0] + np.radians(theta_bandwidth / 2.0)))).argmin() data, data_fn = get_data(20, verbose=False) ipoints, jpoints, rthetas, naxis1, naxis2 = RHT_tools.get_RHT_data(data_fn) # Sum relevant thetas thetasum_bp = np.zeros((naxis2, naxis1), np.float_) thetasum_bp[jpoints, ipoints] = np.nansum(rthetas[:, indx_start:(indx_stop + 1)], axis=1) # Only look at subset thetasum_bp = thetasum_bp[:, 4000:] # Try making this a mask first, then binary erosion/dilation masked_thetasum_bp = np.ones(thetasum_bp.shape) masked_thetasum_bp[thetasum_bp <= 0] = 0 gauss_footprint_len = 5 circ_footprint_rad = 2 footprint = make_gaussian_footprint(theta_0=-theta_0, wlen=gauss_footprint_len) circular_footprint = make_circular_footprint(radius=circ_footprint_rad) # circular binary erosion then gaussian binary dilation cbe_then_gbd = binary_erosion(masked_thetasum_bp, structure=circular_footprint) cbe_then_gbd = binary_dilation(cbe_then_gbd, structure=footprint) # gaussian binary dilation then circular binary erosion gbd_then_cbe = binary_dilation(masked_thetasum_bp, structure=footprint) gbd_then_cbe = binary_erosion(gbd_then_cbe, structure=circular_footprint) # circular binary erosion then circular binary dilation cbe_then_cbd = binary_dilation(masked_thetasum_bp, structure=circular_footprint) cbe_then_cbd = binary_erosion(cbe_then_cbd, structure=circular_footprint) # circular binary dilation then circular binary erosion cbd_then_cbe = binary_erosion(masked_thetasum_bp, structure=circular_footprint) cbd_then_cbe = binary_dilation(cbd_then_cbe, structure=circular_footprint) # gaussian binary dilation then gaussian binary erosion gbd_then_gbe = binary_dilation(masked_thetasum_bp, structure=footprint) gbd_then_gbe = binary_erosion(gbd_then_gbe, structure=footprint) # gaussian binary erosion then gaussian binary dilation gbe_then_gbd = binary_erosion(masked_thetasum_bp, structure=footprint) gbe_then_gbd = binary_dilation(gbe_then_gbd, structure=footprint) fig = plt.figure(facecolor="white") ax1 = fig.add_subplot(231) ax2 = fig.add_subplot(232) ax3 = fig.add_subplot(233) ax4 = fig.add_subplot(234) ax5 = fig.add_subplot(235) ax6 = fig.add_subplot(236) ims = [ cbe_then_gbd, gbd_then_cbe, cbe_then_cbd, cbd_then_cbe, gbd_then_gbe, gbe_then_gbd ] axs = [ax1, ax2, ax3, ax4, ax5, ax6] titles = [ "Circ Erosion, Gauss Dilation", "Gauss Dilation, Circ Erosion", "Circ Erosion, Circ Dilation", "Circ Dilation, Circ Erosion", "Gauss Dilation, Gauss Erosion", "Gauss Erosion, Gauss Dilation" ] plt.suptitle( "Binary Erosion and Dilation, Circular radius = {}, Gaussian Kernel Length = {}" .format(circ_footprint_rad, gauss_footprint_len)) for i in xrange(len(ims)): axs[i].imshow(ims[i], cmap="binary") axs[i].set_title(titles[i])
def get_RHT_data(rht_fn): ipoints, jpoints, rthetas, naxis1, naxis2 = RHT_tools.get_RHT_data(rht_fn) npoints, nthetas = rthetas.shape print("There are %d theta bins" % nthetas) return ipoints, jpoints, rthetas, naxis1, naxis2, nthetas
def single_theta_velocity_cube(theta_0 = 72, theta_bandwidth = 10, wlen = 75, smooth_radius = 60, gaussian_footprint = True, gauss_footprint_len = 5, circular_footprint_radius = 3, binary_erode_dilate = True, hilatonly = True): """ Creates cube of Backprojection(x, y, v | theta_0) where dimensions are x, y, and velocity and each velocity slice contains the backprojection for that velocity, at a single theta. theta_0 :: approximate center theta value (in degrees). Actual value will be closest bin in xyt data. theta_bandwidth :: approximate width of theta range desired (in degrees) wlen :: RHT window length """ # Read in all SC_241 *original* data SC_241_original_fn = "/Volumes/DataDavy/GALFA/SC_241/cleaned/SC_241.66_28.675.best.fits" SC_241_all = fits.getdata(SC_241_original_fn) hdr = fits.getheader(SC_241_original_fn) # Velocity data should be third axis SC_241_all = SC_241_all.swapaxes(0, 2) SC_241_all = SC_241_all.swapaxes(0, 1) naxis2, naxis1, nchannels_total = SC_241_all.shape # Get Wide DR2 data in SC_241 region SC_241_wide_fn = "/Volumes/DataDavy/GALFA/DR2/SC_241_Wide/GALFA_HI_W_projected_SC_241.fits" SC_241_wide = fits.getdata(SC_241_wide_fn) SC_241_wide_hdr = fits.getheader(SC_241_wide_fn) # This is pretty slow with the full SC_241 region. I'm going to chop off the 3000 pixels at the lowest latitude. # Change header accordingly. if hilatonly is True: SC_241_all = SC_241_all[:, 3000:, :] SC_241_wide = SC_241_wide[:, :, 3000:] hdr["CRPIX1"] = hdr["CRPIX1"] - 3000 hdr["NAXIS1"] = hdr["NAXIS1"] - 3000 naxis1 = naxis1 - 3000 # Get thetas for given window length thets = RHT_tools.get_thets(wlen) # Get wide and mask velocities for application of mask to final data wide_vels = get_velocity_from_fits(SC_241_wide_fn) mask_vels = get_velocity_from_fits(SC_241_original_fn) # Get index of theta bin that is closest to theta_0 indx_0 = (np.abs(thets - np.radians(theta_0))).argmin() # Get index of beginning and ending thetas that are approximately theta_bandwidth centered on theta_0 indx_start = (np.abs(thets - (thets[indx_0] - np.radians(theta_bandwidth/2.0)))).argmin() indx_stop = (np.abs(thets - (thets[indx_0] + np.radians(theta_bandwidth/2.0)))).argmin() print("Actual theta range will be {} to {} degrees".format(np.degrees(thets[indx_start]), np.degrees(thets[indx_stop]))) print("Theta indices will be {} to {}".format(indx_start, indx_stop)) # Define velocity channels channels = [16, 17, 18, 19, 20, 21, 22, 23, 24] nchannels = len(channels) # Create a circular footprint for use in erosion / dilation. if gaussian_footprint is True: footprint = make_gaussian_footprint(theta_0 = theta_0, wlen = gauss_footprint_len) # Mathematical definition of kernel flips y-axis footprint = footprint[::-1, :] else: footprint = make_circular_footprint(radius = circular_footprint_radius) # Initialize (x, y, v) cube xyv_theta0 = np.zeros((naxis2, naxis1, len(channels)*4), np.float_) for ch_i, ch_ in enumerate(channels): # Grab channel-specific RHT data data, data_fn = get_data(ch_, verbose = False) ipoints, jpoints, rthetas, naxis1, naxis2 = RHT_tools.get_RHT_data(data_fn) # Sum relevant thetas thetasum_bp = np.zeros((naxis2, naxis1), np.float_) thetasum_bp[jpoints, ipoints] = np.nansum(rthetas[:, indx_start:(indx_stop + 1)], axis = 1) if hilatonly is True: thetasum_bp = thetasum_bp[:, 3000:] if binary_erode_dilate is False: # Erode and dilate eroded_thetasum_bp = erode_data(thetasum_bp, footprint = footprint, structure = footprint) dilated_thetasum_bp = dilate_data(eroded_thetasum_bp, footprint = footprint, structure = footprint) # Turn into mask mask = np.ones(dilated_thetasum_bp.shape) mask[dilated_thetasum_bp <= 0] = 0 else: # Try making this a mask first, then binary erosion/dilation masked_thetasum_bp = np.ones(thetasum_bp.shape) masked_thetasum_bp[thetasum_bp <= 0] = 0 mask = binary_erosion(masked_thetasum_bp, structure = footprint) mask = binary_dilation(mask, structure = footprint) # Apply background subtraction to velocity slice. #background_subtracted_data = background_subtract(mask, SC_241_all[:, :, ch_], smooth_radius = smooth_radius, plotresults = False) # Get appropriate velocity slices for background subtraction closestvels = closest_velocities(wide_vels, mask_vels[ch_]) # These need to monotonically ascend closestvels = np.sort(closestvels) # Apply background subtraction to velocity slice. for cv_i, cv in enumerate(closestvels): time0 = time.time() wv_indx = list(wide_vels).index(cv) background_subtracted_data = background_subtract(mask, SC_241_wide[wv_indx, :, :], smooth_radius = smooth_radius, plotresults = False) # Place into channel bin xyv_theta0[:, :, ch_i*4 + cv_i] = background_subtracted_data print("placing into bin {}".format(ch_i*4 + cv_i)) time1 = time.time() print("slice {} took {} seconds".format(cv_i, time1 - time0)) hdr["NAXIS3"] = len(channels)*4 hdr["THETA0"] = theta_0 hdr["THETAB"] = theta_bandwidth hdr["CRVAL3"] = np.nanmin(closest_velocities(wide_vels, mask_vels[channels[0]]))*1000 # Convert to m/s hdr["CDELT3"] = SC_241_wide_hdr["CDELT3"] # Deal with python fits axis ordering xyv_theta0 = xyv_theta0.swapaxes(0, 2) xyv_theta0 = xyv_theta0.swapaxes(1, 2) fits.writeto("xyv_theta0_"+str(theta_0)+"_thetabandwidth_"+str(theta_bandwidth)+"_ch"+str(channels[0])+"_to_"+str(channels[-1])+"_DR2_W_hilat.fits", xyv_theta0, hdr) return xyv_theta0, hdr, mask
def test_different_erosion_dilations(wlen = 75, theta_0 = 72, theta_bandwidth = 10): # Get thetas for given window length thets = RHT_tools.get_thets(wlen) # Get index of theta bin that is closest to theta_0 indx_0 = (np.abs(thets - np.radians(theta_0))).argmin() # Get index of beginning and ending thetas that are approximately theta_bandwidth centered on theta_0 indx_start = (np.abs(thets - (thets[indx_0] - np.radians(theta_bandwidth/2.0)))).argmin() indx_stop = (np.abs(thets - (thets[indx_0] + np.radians(theta_bandwidth/2.0)))).argmin() data, data_fn = get_data(20, verbose = False) ipoints, jpoints, rthetas, naxis1, naxis2 = RHT_tools.get_RHT_data(data_fn) # Sum relevant thetas thetasum_bp = np.zeros((naxis2, naxis1), np.float_) thetasum_bp[jpoints, ipoints] = np.nansum(rthetas[:, indx_start:(indx_stop + 1)], axis = 1) # Only look at subset thetasum_bp = thetasum_bp[:, 4000:] # Try making this a mask first, then binary erosion/dilation masked_thetasum_bp = np.ones(thetasum_bp.shape) masked_thetasum_bp[thetasum_bp <= 0] = 0 gauss_footprint_len = 5 circ_footprint_rad = 2 footprint = make_gaussian_footprint(theta_0 = -theta_0, wlen = gauss_footprint_len) circular_footprint = make_circular_footprint(radius = circ_footprint_rad) # circular binary erosion then gaussian binary dilation cbe_then_gbd = binary_erosion(masked_thetasum_bp, structure = circular_footprint) cbe_then_gbd = binary_dilation(cbe_then_gbd, structure = footprint) # gaussian binary dilation then circular binary erosion gbd_then_cbe = binary_dilation(masked_thetasum_bp, structure = footprint) gbd_then_cbe = binary_erosion(gbd_then_cbe, structure = circular_footprint) # circular binary erosion then circular binary dilation cbe_then_cbd = binary_dilation(masked_thetasum_bp, structure = circular_footprint) cbe_then_cbd = binary_erosion(cbe_then_cbd, structure = circular_footprint) # circular binary dilation then circular binary erosion cbd_then_cbe = binary_erosion(masked_thetasum_bp, structure = circular_footprint) cbd_then_cbe = binary_dilation(cbd_then_cbe, structure = circular_footprint) # gaussian binary dilation then gaussian binary erosion gbd_then_gbe = binary_dilation(masked_thetasum_bp, structure = footprint) gbd_then_gbe = binary_erosion(gbd_then_gbe, structure = footprint) # gaussian binary erosion then gaussian binary dilation gbe_then_gbd = binary_erosion(masked_thetasum_bp, structure = footprint) gbe_then_gbd = binary_dilation(gbe_then_gbd, structure = footprint) fig = plt.figure(facecolor = "white") ax1 = fig.add_subplot(231) ax2 = fig.add_subplot(232) ax3 = fig.add_subplot(233) ax4 = fig.add_subplot(234) ax5 = fig.add_subplot(235) ax6 = fig.add_subplot(236) ims = [cbe_then_gbd, gbd_then_cbe, cbe_then_cbd, cbd_then_cbe, gbd_then_gbe, gbe_then_gbd] axs = [ax1, ax2, ax3, ax4, ax5, ax6] titles = ["Circ Erosion, Gauss Dilation", "Gauss Dilation, Circ Erosion", "Circ Erosion, Circ Dilation", "Circ Dilation, Circ Erosion", "Gauss Dilation, Gauss Erosion", "Gauss Erosion, Gauss Dilation"] plt.suptitle("Binary Erosion and Dilation, Circular radius = {}, Gaussian Kernel Length = {}".format(circ_footprint_rad, gauss_footprint_len)) for i in xrange(len(ims)): axs[i].imshow(ims[i], cmap = "binary") axs[i].set_title(titles[i])
def single_theta_velocity_cube(theta_0 = 72, theta_bandwidth = 10, wlen = 75, gaussian_footprint = True): """ Creates cube of Backprojection(x, y, v | theta_0) where dimensions are x, y, and velocity and each velocity slice contains the backprojection for that velocity, at a single theta. theta_0 :: approximate center theta value (in degrees). Actual value will be closest bin in xyt data. theta_bandwidth :: approximate width of theta range desired (in degrees) wlen :: RHT window length """ # Read in all SC_241 *original* data SC_241_all = fits.getdata("/Volumes/DataDavy/GALFA/SC_241/cleaned/SC_241.66_28.675.best.fits") hdr = fits.getheader("/Volumes/DataDavy/GALFA/SC_241/cleaned/SC_241.66_28.675.best.fits") # Velocity data should be third axis SC_241_all = SC_241_all.swapaxes(0, 2) SC_241_all = SC_241_all.swapaxes(0, 1) naxis2, naxis1, nchannels_total = SC_241_all.shape # Get thetas for given window length thets = RHT_tools.get_thets(wlen) # Get index of theta bin that is closest to theta_0 indx_0 = (np.abs(thets - np.radians(theta_0))).argmin() # Get index of beginning and ending thetas that are approximately theta_bandwidth centered on theta_0 indx_start = (np.abs(thets - (thets[indx_0] - np.radians(theta_bandwidth/2.0)))).argmin() indx_stop = (np.abs(thets - (thets[indx_0] + np.radians(theta_bandwidth/2.0)))).argmin() print("Actual theta range will be {} to {} degrees".format(np.degrees(thets[indx_start]), np.degrees(thets[indx_stop]))) print("Theta indices will be {} to {}".format(indx_start, indx_stop)) # Define velocity channels channels = [20]#[16, 17, 18, 19, 20, 21, 22, 23, 24] nchannels = len(channels) # Create a circular footprint for use in erosion / dilation. if gaussian_footprint is True: footprint = make_gaussian_footprint(theta_0 = theta_0, wlen = 5) # Mathematical definition of kernel flips y-axis footprint = footprint[::-1, :] else: footprint = make_circular_footprint(radius = 3) #circular_footprint = make_circular_footprint(radius = 2) # Initialize (x, y, v) cube xyv_theta0 = np.zeros((naxis2, naxis1, nchannels), np.float_) for ch_i, ch_ in enumerate(channels): # Grab channel-specific RHT data data, data_fn = get_data(ch_, verbose = False) ipoints, jpoints, rthetas, naxis1, naxis2 = RHT_tools.get_RHT_data(data_fn) # Sum relevant thetas thetasum_bp = np.zeros((naxis2, naxis1), np.float_) thetasum_bp[jpoints, ipoints] = np.nansum(rthetas[:, indx_start:(indx_stop + 1)], axis = 1) # Erode and dilate # Circular erosion #eroded_thetasum_bp = erode_data(thetasum_bp, footprint = circular_footprint) # Gaussian dilation #dilated_thetasum_bp = dilate_data(eroded_thetasum_bp, footprint = footprint, structure = footprint) # Turn into mask #mask = np.ones(dilated_thetasum_bp.shape) #mask[dilated_thetasum_bp <= 0] = 0 # Try making this a mask first, then binary erosion/dilation masked_thetasum_bp = np.ones(thetasum_bp.shape) masked_thetasum_bp[thetasum_bp <= 0] = 0 mask = binary_erosion(masked_thetasum_bp, structure = footprint) mask = binary_dilation(mask, structure = footprint) # Apply mask to relevant velocity data realdata_vel_slice = SC_241_all[:, :, ch_] realdata_vel_slice[mask == 0] = 0 # Place into channel bin xyv_theta0[:, :, ch_i] = realdata_vel_slice #return xyv_theta0 hdr["CHSTART"] = channels[0] hdr["CHSTOP"] = channels[-1] hdr["NAXIS3"] = len(channels) hdr["THETA0"] = theta_0 hdr["THETAB"] = theta_bandwidth hdr["CRPIX3"] = hdr["CRPIX3"] - channels[0] # Deal with python fits axis ordering xyv_theta0 = xyv_theta0.swapaxes(0, 2) xyv_theta0 = xyv_theta0.swapaxes(1, 2) #fits.writeto("xyv_theta0_"+str(theta_0)+"_thetabandwidth_"+str(theta_bandwidth)+"_ch"+str(channels[0])+"_to_"+str(channels[-1])+"_new_naxis3.fits", xyv_theta0, hdr) return xyv_theta0, hdr, mask