示例#1
0
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
示例#2
0
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
示例#3
0
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()
示例#4
0
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
示例#5
0
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
示例#6
0
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
示例#8
0
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}$")
示例#9
0
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
示例#10
0
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
示例#12
0
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
示例#13
0
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])
示例#14
0
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