Пример #1
0
def voronoi_binning_example():
    """
    Usage example for the procedure VORONOI_2D_BINNING.

    It is assumed below that the file voronoi_2d_binning_example.txt
    resides in the current directory. Here columns 1-4 of the text file
    contain respectively the x, y coordinates of each SAURON lens
    and the corresponding Signal and Noise.

    """
    file_dir = path.dirname(path.realpath(__file__))  # path of this procedure
    x, y, signal, noise = np.loadtxt(file_dir +
                                     '/voronoi_2d_binning_example.txt',
                                     unpack=1,
                                     skiprows=3)
    targetSN = 50.0

    # Perform the actual computation. The vectors
    # (binNum, xNode, yNode, xBar, yBar, sn, nPixels, scale)
    # are all generated in *output*
    #
    binNum, xNode, yNode, xBar, yBar, sn, nPixels, scale = voronoi_2d_binning(
        x, y, signal, noise, targetSN, plot=1, quiet=0)

    # Save to a text file the initial coordinates of each pixel together
    # with the corresponding bin number computed by this procedure.
    # binNum uniquely specifies the bins and for this reason it is the only
    # number required for any subsequent calculation on the bins.
    #
    np.savetxt('voronoi_2d_binning_output.txt',
               np.column_stack([x, y, binNum]),
               fmt=b'%10.6f %10.6f %8i')
def voronoi_binning_example():
    """
    Usage example for the procedure VORONOI_2D_BINNING.

    It is assumed below that the file voronoi_2d_binning_example.txt
    resides in the current directory. Here columns 1-4 of the text file
    contain respectively the x, y coordinates of each SAURON lens
    and the corresponding Signal and Noise.

    """

    x, y, signal, noise = np.loadtxt('voronoi_2d_binning_example.txt', unpack=1, skiprows=3)
    targetSN = 50.0

    # Perform the actual computation. The vectors
    # (binNum, xNode, yNode, xBar, yBar, sn, nPixels, scale)
    # are all generated in *output*
    #
    binNum, xNode, yNode, xBar, yBar, sn, nPixels, scale = voronoi_2d_binning(
        x, y, signal, noise, targetSN, plot=1, quiet=0)

    # Save to a text file the initial coordinates of each pixel together
    # with the corresponding bin number computed by this procedure.
    # binNum uniquely specifies the bins and for this reason it is the only
    # number required for any subsequent calculation on the bins.
    #
    np.savetxt('voronoi_2d_binning_output.txt', np.column_stack([x, y, binNum]),
               fmt=b'%10.6f %10.6f %8i')
def tessellate(inputFile=datadir+cuberoot+'_vor.fits',targetSN=50):

    cubefits = pyfits.open(inputFile)
    
    cube = cubefits[0].data
    hdr = cubefits[0].header
    errors = cubefits[1].data

    #pdb.set_trace()
    #xx = np.arange(cube.shape[0])
    #yy = np.arange(cube.shape[1])
    good = np.where((cube > 0) & (errors > 0) & ((cube/errors) >= 2.))
    goodbad=np.zeros((cube.shape[0],cube.shape[1]),dtype=float)
    goodbad[good]=1.
    xx = good[1]
    yy = good[0]
    #pdb.set_trace()
    binNum, xNode, yNode, xBar, yBar, sn, nPixels, scale, pixSize = v2d.voronoi_2d_binning(xx, yy, cube[good], errors[good], targetSN, plot=1, quiet=0)
        
    py.close(1)
    py.figure(1,figsize=(8,8))
    py.subplots_adjust(left=0.16, right=0.94, top=0.95)
    py.subplot(211)
    rnd = np.argsort(np.random.random(xNode.size))  # Randomize bin colors
    # added in flips to display in the same orientation as the data
    # divide by 20 to put in arcsec (0.05 arcsec per pixel)
    xxpl = (xx - ppxf_m31.bhpos_pix[0]) * 0.05
    yypl = (np.flipud(yy) - ppxf_m31.bhpos_pix[1]) * 0.05
    xnpl = (xNode - ppxf_m31.bhpos_pix[0]) * 0.05
    ynpl = (yNode - ppxf_m31.bhpos_pix[1]) * 0.05
    v2d._display_pixels(xxpl, yypl, rnd[binNum], pixSize/20., horflip=True)
    py.plot(xnpl, ynpl, '+w', scalex=False, scaley=False) # do not rescale after imshow()
    py.plot([0], 'ko', markeredgewidth=2,markerfacecolor='None')
    py.axis('image')
    py.ylabel('Y (arcsec)')
    py.xlabel('X (arcsec)')
    py.title('Map of Voronoi bins')
    
    py.subplot(212)
    rad = np.sqrt(np.abs(xBar-bhpos_horpix[0])**2 + np.abs(yBar-bhpos_horpix[1])**2)  # Use centroids, NOT generators
    w = nPixels == 1
    py.plot(rad[~w]/20., sn[~w], 'or', label='Voronoi bins')
    py.xlabel('Distance from SMBH (arcsec)')
    py.ylabel('Bin S/N')
    py.axis([np.min(rad/20.), np.max(rad/20.), 0, np.max(sn)])  # x0, x1, y0, y1
    if np.sum(w) > 0:
        py.plot(rad[w]/20., sn[w], 'xb', label='single spaxels')
    py.axhline(targetSN)
    py.legend()
    py.pause(0.01)  # allow plot to appear in certain cases

    pdb.set_trace()
    outfile = os.path.dirname(inputFile)+'/voronoi_2d_binning_output.txt'
    np.savetxt(outfile, np.column_stack([xx, yy, binNum]),
               fmt=b'%10.6f %10.6f %8i')
def voronoi_binning(xysn_file, v2b_file, v2b_xy_file):
    """
    Follows example script provided from Michele Cappellari for voronoi 2d binning
    INPUT: XYSN_FILE (x_y_signal_noise.txt)
    OUTPUT: V2B_FILE (v2b_output_sn30.txt), V2B_XY_FILE (v2b_output_xy_sn30.txt)

    Output variables of voronoi_2d_binning (copied straight from the description in the script):
        BINNUMBER: Vector (same size as X) containing the bin number assigned to each input pixel. The index goes from
            zero to Nbins-1. This vector alone is enough to make *any* subsequent computation on the binned data.
            Everything else is optional!
        XBIN: Vector (size Nbins) of the X coordinates of the bin generators. These generators uniquely define the
            Voronoi tessellation.
        YBIN: Vector (size Nbins) of Y coordinates of the bin generators.
        XBAR: Vector (size Nbins) of X coordinates of the bins luminosity weighted centroids. Useful for plotting
            interpolated data.
        YBAR: Vector (size Nbins) of Y coordinates of the bins luminosity weighted centroids.
        SN: Vector (size Nbins) with the final SN of each bin.
        NPIXELS: Vector (size Nbins) with the number of pixels of each bin.
        SCALE: Vector (size Nbins) with the scale length of the Weighted Voronoi Tessellation, when the /WVT keyword is
            set. In that case SCALE is *needed* together with the coordinates XBIN and YBIN of the generators, to
            compute the tessellation (but one can also simply use the BINNUMBER vector).
    """

    if os.path.exists(v2b_file):
        print('File {} already exists'.format(v2b_file))
        return

    y, x, signal, noise = np.loadtxt(xysn_file, unpack=True)  # , skiprows=3)

    # Only select pixels where the signal and noise is nonzero, this often results in a few missed pixels
    # around the border of the image. This method is easier than parsing the xysn_file to manually remove pixels with
    # noise values <= 0.
    #
    noise = noise[noise > 0.]
    signal = signal[noise > 0.]
    x = x[noise > 0.]
    y = y[noise > 0.]

    # Perform the actual computation. The vectors (binNum, xNode, yNode, xBar, yBar, sn, nPixels, scale)
    # are all generated in *output*
    #
    binNum, xNode, yNode, xBar, yBar, sn, nPixels, scale = voronoi_2d_binning(x, y, signal, noise, TARGET_SN,
                                                                              plot=1, quiet=0)

    # Save to a text file the initial coordinates of each pixel together with the corresponding bin number computed
    # by this procedure. binNum uniquely specifies the bins and for this reason it is the only
    # number required for any subsequent calculation on the bins.
    #
    np.savetxt(v2b_file, np.column_stack([x, y, binNum]), header='x  y  binNum', fmt=b'%10.6f %10.6f %8i')
    np.savetxt(v2b_xy_file, np.column_stack([xBar, yBar, xNode, yNode]), header='xBar  yBar  xNode   yNode',
               fmt=b'%10.6f %10.6f %10.6f %10.6f')
Пример #5
0
def voronoi_binning(R50,
                    Mr,
                    n_rect_bins=500,
                    n_per_voronoi_bin=5000,
                    save=False):
    ''' Voronoi bin in terms of R50 and Mr'''

    rect_bin_val, R50_bin_edges, Mr_bin_edges = np.histogram2d(
        R50, Mr, n_rect_bins)

    rect_bins_table = Table(data=[R50_bin_edges, Mr_bin_edges],
                            names=['R50_bin_edges', 'Mr_bin_edges'])
    rect_bins_table.meta['nrectbin'] = n_rect_bins  # add value for number of
    # bins to the table.

    # Get bin centres + number of bins:
    R50_bin_centres = 0.5 * (R50_bin_edges[:-1] + R50_bin_edges[1:])
    Mr_bin_centres = 0.5 * (Mr_bin_edges[:-1] + Mr_bin_edges[1:])
    n_R50_bins = len(R50_bin_centres)
    n_Mr_bins = len(Mr_bin_centres)

    # Get ranges:
    R50_bins_min, Mr_bins_min = map(np.min, (R50_bin_centres, Mr_bin_centres))
    R50_bins_max, Mr_bins_max = map(np.max, (R50_bin_centres, Mr_bin_centres))
    R50_bins_range = R50_bins_max - R50_bins_min
    Mr_bins_range = Mr_bins_max - Mr_bins_min

    # 'Ravel' out the coordinate bins (length of this array = n_bin*n_bin)
    R50_bin_coords = R50_bin_centres.repeat(n_rect_bins).reshape(
        n_rect_bins, n_rect_bins).ravel()
    Mr_bin_coords = Mr_bin_centres.repeat(n_rect_bins).reshape(
        n_rect_bins, n_rect_bins).T.ravel()

    # Only keep bins that contain a galaxy:
    signal = rect_bin_val.ravel()  # signal=number of gals.
    ok_bin = (signal > 0).nonzero()[0]
    signal = signal[ok_bin]

    # Normalise x + y to be between 0 and 1:
    x = (R50_bin_coords[ok_bin] - R50_bins_min) / R50_bins_range
    y = (Mr_bin_coords[ok_bin] - Mr_bins_min) / Mr_bins_range

    # Voronoi_2d_binning aims for a target S/N
    noise = np.sqrt(signal)
    targetSN = np.sqrt(n_per_voronoi_bin)

    output = voronoi_2d_binning(x,
                                y,
                                signal,
                                noise,
                                targetSN,
                                plot=0,
                                quiet=1,
                                wvt=True)
    binNum, xNode, yNode, xBar, yBar, sn, nPixels, scale = output

    vbin = np.unique(binNum)
    count = (sn**2).astype(np.int)

    count = count
    R50_vbin_mean = (xBar * R50_bins_range + R50_bins_min)
    Mr_vbin_mean = (yBar * Mr_bins_range + Mr_bins_min)
    nPixels = nPixels

    vbins_table = Table(
        data=[vbin, R50_vbin_mean, Mr_vbin_mean, count, nPixels],
        names=['vbin', 'R50', 'Mr', 'count_gals', 'count_rect_bins'])
    vbins_table.meta['nrectbin'] = n_rect_bins
    vbins_table.meta['nperbin'] = n_per_voronoi_bin

    # Populate elements of the rectangular grid with
    # the voronoi bin indices and counts
    rect_bin_voronoi_bin = (np.zeros(np.product(rect_bin_val.shape), np.int) -
                            1)
    rect_bin_voronoi_bin[ok_bin] = binNum
    rect_bin_count = np.zeros_like(rect_bin_voronoi_bin)
    rect_bin_count[ok_bin] = count

    rect_vbins_table = Table(
        data=[R50_bin_coords, Mr_bin_coords, rect_bin_voronoi_bin],
        names=['R50', 'Mr', 'vbin'])

    rect_bins_table.meta['nrectbin'] = n_rect_bins
    rect_bins_table.meta['nperbin'] = n_per_voronoi_bin

    if save == True:
        rect_bins_table.write(save_directory + 'rect_bins_table.fits',
                              overwrite=True)
        vbins_table.write(save_directory + 'vbins_table.fits', overwrite=True)
        rect_vbins_table.write(save_directory + 'rect_vbins_table.fits',
                               overwrite=True)

    return (rect_bins_table, vbins_table, rect_vbins_table, Mr_bins_min,
            Mr_bins_range, R50_bins_min, R50_bins_range)
Пример #6
0
def voronoi_binning(R50, Mr,n_rect_bins=500, n_per_voronoi_bin=5000,save=False):
    ''' Voronoi bin in terms of R50 and Mr'''
    
    rect_bin_val, R50_bin_edges, Mr_bin_edges = np.histogram2d(R50, Mr, n_rect_bins)

    rect_bins_table = Table(data=[R50_bin_edges, Mr_bin_edges],
                            names=['R50_bin_edges', 'Mr_bin_edges'])
    rect_bins_table.meta['nrectbin'] = n_rect_bins # add value for number of 
    # bins to the table. 
    
    # Get bin centres + number of bins:
    R50_bin_centres = 0.5*(R50_bin_edges[:-1] + R50_bin_edges[1:])
    Mr_bin_centres = 0.5*(Mr_bin_edges[:-1] + Mr_bin_edges[1:]) 
    n_R50_bins = len(R50_bin_centres)
    n_Mr_bins = len(Mr_bin_centres)

    # Get ranges:
    R50_bins_min, Mr_bins_min = map(np.min, (R50_bin_centres, Mr_bin_centres))
    R50_bins_max, Mr_bins_max = map(np.max, (R50_bin_centres, Mr_bin_centres))
    R50_bins_range = R50_bins_max - R50_bins_min
    Mr_bins_range = Mr_bins_max - Mr_bins_min
    
    # 'Ravel' out the coordinate bins (length of this array = n_bin*n_bin)
    R50_bin_coords = R50_bin_centres.repeat(n_rect_bins).reshape(n_rect_bins, n_rect_bins).ravel()
    Mr_bin_coords = Mr_bin_centres.repeat(n_rect_bins).reshape(n_rect_bins, n_rect_bins).T.ravel()

    # Only keep bins that contain a galaxy:
    signal = rect_bin_val.ravel() # signal=number of gals.
    ok_bin = (signal > 0).nonzero()[0]
    signal = signal[ok_bin]

    # Normalise x + y to be between 0 and 1:
    x = (R50_bin_coords[ok_bin] - R50_bins_min) / R50_bins_range
    y = (Mr_bin_coords[ok_bin] - Mr_bins_min) / Mr_bins_range

    # Voronoi_2d_binning aims for a target S/N
    noise = np.sqrt(signal)
    targetSN = np.sqrt(n_per_voronoi_bin)

    output = voronoi_2d_binning(x, y, signal, noise, targetSN, plot=0,
				quiet=1, wvt=True)
    binNum, xNode, yNode, xBar, yBar, sn, nPixels, scale = output

    vbin = np.unique(binNum)
    count = (sn**2).astype(np.int)
    
    count = count
    R50_vbin_mean = (xBar * R50_bins_range + R50_bins_min)
    Mr_vbin_mean = (yBar * Mr_bins_range + Mr_bins_min)
    nPixels = nPixels
    
    vbins_table = Table(data=[vbin, R50_vbin_mean, Mr_vbin_mean,
                              count, nPixels],
                        names=['vbin', 'R50', 'Mr', 
                               'count_gals', 'count_rect_bins'])
    vbins_table.meta['nrectbin'] = n_rect_bins
    vbins_table.meta['nperbin'] = n_per_voronoi_bin
    
    # Populate elements of the rectangular grid with
    # the voronoi bin indices and counts
    rect_bin_voronoi_bin = (np.zeros(np.product(rect_bin_val.shape), np.int)
			    - 1)
    rect_bin_voronoi_bin[ok_bin] = binNum
    rect_bin_count = np.zeros_like(rect_bin_voronoi_bin)
    rect_bin_count[ok_bin] = count
    
    rect_vbins_table = Table(data=[R50_bin_coords, Mr_bin_coords,
                             rect_bin_voronoi_bin],
                             names=['R50', 'Mr', 'vbin'])
    
    rect_bins_table.meta['nrectbin'] = n_rect_bins
    rect_bins_table.meta['nperbin'] = n_per_voronoi_bin
    
    if save == True:
        rect_bins_table.write(save_directory + 'rect_bins_table.fits',
                              overwrite=True)
        vbins_table.write(save_directory + 'vbins_table.fits',
                          overwrite=True)
        rect_vbins_table.write(save_directory + 'rect_vbins_table.fits',
                               overwrite=True)

    return (rect_bins_table, vbins_table, rect_vbins_table, Mr_bins_min,
            Mr_bins_range, R50_bins_min, R50_bins_range)
Пример #7
0
    Xbin = np.cos(theta) * X + np.sin(theta) * Y
    Ybin = -np.sin(theta) * X + np.cos(theta) * Y
    if options.circle:
        aa = Re
        bb = Re
    R = ((Xbin / aa)**2 + (Ybin / bb)**2)**0.5
    ii = (R < 2.5)  # *(~(((Xbin+73.0)**2 + (Ybin+15.0)**2)**0.5<15.0))
    xbin = X[ii].reshape(-1)  # x position for each spaxel
    ybin = Y[ii].reshape(-1)  # y position for each spaxel
    signal = img_ifu[ii].reshape(-1)
    signal = signal.clip(1.0)
    print(signal == 0).sum()
    noise = np.sqrt(signal)
    targetSN = 20.0
    binNum, xNode, yNode, xBar, yBar, sn, nPixels, scale = voronoi_2d_binning(
        xbin, ybin, signal, noise, targetSN, plot=1, quiet=1)
    plt.savefig('%s/ifu/voronoi_bin.png' % path, dpi=300)

    # Re and 2.5 Re ellipse
    phi = np.linspace(0, 2 * np.pi, 100)
    xx_tem = aa * np.cos(phi) / kpc2arcsec
    yy_tem = bb * np.sin(phi) / kpc2arcsec
    xx = np.cos(-theta) * xx_tem + np.sin(-theta) * yy_tem  # xx, yy in kpc
    yy = -np.sin(-theta) * xx_tem + np.cos(-theta) * yy_tem

    fig = plt.figure(figsize=(6, 6))
    ax = fig.add_subplot(1, 1, 1)
    ax.axis('equal')
    ax.set_adjustable('box-forced')
    ax.imshow(np.log10(img_M),
              origin='lower',
Пример #8
0
def binning():
    file = 'NGC0528-V500.rscube.fits'
    hdu = pyfits.open(file)
    gal_lin = hdu[0].data  # axes are wav,y,x
    h1 = hdu[0].header
    gal_err = hdu[1].data
    badpix = hdu[3].data

    xs = 70
    ys = 70
    ws = gal_lin.shape[0]

    #Remove badpixels

    medgal = np.zeros((ys, xs))
    medgalerr = np.zeros((ys, xs))

    xarr = np.zeros(xs * ys)
    yarr = np.zeros(xs * ys)
    medarr = np.zeros(xs * ys)
    mederrarr = np.zeros(xs * ys)

    count = 0
    for i in range(xs):
        for j in range(ys):
            no = np.where(badpix[:, j, i] == 1)[0]
            numbd = no.size
            numgd = ws - numbd
            if numgd > 0 and numgd < ws:
                cgal = np.delete(gal_lin[:, j, i], no)
                cgalerr = np.delete(gal_err[:, j, i], no)
                medgal[j, i] = np.median(cgal)
                medgalerr[j, i] = np.median(cgalerr)
            elif numgd == 0:
                medgal[j, i] = 0.0
                medgalerr[j, i] = 0.0
            elif numgd == ws:
                medgal[j, i] = np.median(cgal)
                medgalerr[j, i] = np.median(cgalerr)
            xarr[count] = i
            yarr[count] = j
            medarr[count] = medgal[j, i]
            mederrarr[count] = medgalerr[j, i]
            count = count + 1

    hdu = pyfits.PrimaryHDU(medgal)
    hdu.writeto('medgal.fits', clobber=True)
    #Remove low S/N pixels

    x = np.zeros(0)
    y = np.zeros(0)
    signal = np.zeros(0)
    noise = np.zeros(0)
    gd = 0

    for i in range(count):
        if medarr[i] > 0.05 and mederrarr[i] < 100:
            gd = gd + 1
            x = np.append(x, xarr[i])
            y = np.append(y, yarr[i])
            signal = np.append(signal, medarr[i])
            noise = np.append(noise, mederrarr[i])

    output = np.zeros((gd, 4))
    output[:, 0] = x
    output[:, 1] = y
    output[:, 2] = signal
    output[:, 3] = noise

    np.savetxt('medgalpy.txt', output, fmt="%10.3g")

    #Voronoi binning

    targetSN = 80
    binNum, xNode, yNode, xBar, yBar, sn, nPixels, scale = voronoi_2d_binning(
        x, y, signal, noise, targetSN, plot=1, quiet=1)

    np.savetxt('voronoi_2d_binning_output.txt',
               np.column_stack([x, y, binNum]),
               fmt=b'%10.6f %10.6f %8i')
    np.savetxt('bins.txt', np.column_stack([xNode, yNode]), fmt="%10.3g")
    nbins = xNode.shape[0]

    avspec = np.zeros((nbins, ws))
    avspecerr = np.zeros((nbins, ws))
    binflux = np.zeros(nbins)
    x = x.astype(int)
    y = y.astype(int)
    for j in range(nbins):
        b = np.where(binNum == j)[0]
        valbin = b.size
        if valbin == 1:
            for i in range(ws):
                avspec[j, i] = gal_lin[i, y[b], x[b]]
                avspecerr[j, i] = gal_err[i, y[b], x[b]]
        else:
            for i in range(ws):
                avspec[j, i] = np.sum(gal_lin[i, y[b], x[b]]) / valbin
                avspecerr[j, i] = np.sum(gal_err[i, y[b], x[b]]) / valbin
        binflux[j] = np.sum(avspec[j, :])

    np.savetxt('binflux.txt', binflux, fmt="%10.3g")

    hdu = pyfits.PrimaryHDU(avspec)
    hdu.writeto('galaxybinspy.fits', clobber=True)
Пример #9
0
def makeIFUbins(img_ifu, img_M, sol, pa, eps, path, circle = True):
    '''
    sol, pa, eps are MGE fitting results.
    Save relavent files to "path".
    '''
    ba = 1.0-eps
    theta = -((90.-pa)/180.*np.pi)
    Re = getRe(sol)
    print('Re: %.2f'%Re)
    aa = Re/np.sqrt(ba)
    bb = Re*np.sqrt(ba)

    naxis_ifu = img_ifu.shape[0]
    naxis_img = img_M.shape[0]
    # !!! be careful, x,y should be in arcsec, not kpc!
    x = np.linspace(-naxis_ifu*pix2arcsec/2,
                    naxis_ifu*pix2arcsec/2, naxis_ifu)

    y = np.linspace(-naxis_ifu*pix2arcsec/2,
                    naxis_ifu*pix2arcsec/2, naxis_ifu)
    X, Y = np.meshgrid(x, y)

    Xbin = np.cos(theta)*X+np.sin(theta)*Y
    Ybin = -np.sin(theta)*X+np.cos(theta)*Y
    if circle:
        aa = Re
        bb = Re
    R = ((Xbin/aa)**2+(Ybin/bb)**2)**0.5
    ii = (R < 2.5)  # *(~(((Xbin+73.0)**2 + (Ybin+15.0)**2)**0.5<15.0))
    xbin = X[ii].reshape(-1)  # x position for each spaxel
    ybin = Y[ii].reshape(-1)  # y position for each spaxel
    signal = img_ifu[ii].reshape(-1)
    signal = signal.clip(1.0)
    print((signal == 0).sum())
    noise = np.sqrt(signal)
    targetSN = 20.0
    binNum, xNode, yNode, xBar, yBar, sn, nPixels, scale, fig = \
        voronoi_2d_binning(xbin, ybin, signal, noise, targetSN, plot=1, quiet=1)
    fig.savefig('%s/voronoi_bin.eps'%path, dpi=300)

    # Re and 2.5 Re ellipse
    phi = np.linspace(0, 2*np.pi, 100)
    xx_tem = aa * np.cos(phi) / kpc2arcsec
    yy_tem = bb * np.sin(phi) / kpc2arcsec
    xx = np.cos(-theta)*xx_tem+np.sin(-theta)*yy_tem  # xx, yy in kpc
    yy = -np.sin(-theta)*xx_tem+np.cos(-theta)*yy_tem

    fig = plt.figure(figsize=(6, 6))
    ax = fig.add_subplot(1, 1, 1)
    ax.axis('equal')
    ax.set_adjustable('box-forced')
    ax.imshow(np.log10(img_M), origin='lower',
              extent=(-ui.boxsize_img/2, ui.boxsize_img/2,
                      -ui.boxsize_img/2, ui.boxsize_img/2))
    ax.plot(xNode/kpc2arcsec, yNode/kpc2arcsec, 'ok',
            markersize=1.0, alpha=0.3)
    ax.plot(xx, yy, 'c', alpha=0.6, lw=2)
    ax.plot(2.5*xx, 2.5*yy, 'c', alpha=0.6, lw=2)
    ax.set_xlim([-ui.boxsize_img/2, ui.boxsize_img/2])
    ax.set_ylim([-ui.boxsize_img/2, ui.boxsize_img/2])
    plt.xlabel("kpc")
    plt.ylabel("kpc")
    fig.savefig('%s/img.eps'%path, dpi=300)

    # output some necessary files and figures
    # convex hull
    hull = ConvexHull(np.array([xbin, ybin]).T)
    x_hull = xbin[hull.vertices][::-1]
    y_hull = ybin[hull.vertices][::-1]  # must be clockwise!
    R = (x_hull**2 + y_hull**2)**0.5
    Rmax = np.mean(R.max())
    r = R.copy() * 0.0
    for i in range(len(r)):
        position = np.array([[x_hull[i-1], x_hull[i]],
                             [y_hull[i-1], y_hull[i]]])
        vector1 = np.array([position[0, 1], position[1, 1]])
        vector2 = np.array([position[0, 1]-position[0, 0],
                            position[1, 1]-position[1, 0]])
        project_length = abs(np.dot(vector1, vector2) /
                             np.sqrt(np.dot(vector2, vector2)))
        r[i] = (np.dot(vector1, vector1) - project_length**2)**0.5
    Rmin = np.mean(r.min())
    Rect_x_min = np.mean(x_hull.min())
    Rect_x_max = np.mean(x_hull.max())
    Rect_y_min = np.mean(y_hull.min())
    Rect_y_max = np.mean(y_hull.max())
    with open('%s/IFU_hull'%path, 'w') as ff:
        print(('{0:d}  {1:+e}  {2:+e}  {3:+e}  {4:+e}  {5:+e}  {6:+e}'
            .format(len(x_hull)+1, Rmin, Rmax, Rect_x_min,
                    Rect_x_max, Rect_y_min, Rect_y_max)), file = ff)
        for i in range(len(x_hull)):
            print('{0:+e}  {1:+e}'.format(x_hull[i], y_hull[i]), file = ff)
        print('{0:+e}  {1:+e}'.format(x_hull[0], y_hull[0]), file = ff)
    fig = plt.figure(figsize=(6, 6))
    ax = fig.add_subplot(1, 1, 1)
    ax.plot(xNode, yNode, 'o', markersize=2.0)
    ax.plot(xbin, ybin, '.r', markersize=0.5, alpha=0.5)
    for simplex in hull.simplices:
        ax.plot(hull.points[simplex, 0], hull.points[simplex, 1], 'k-')
    circle = Circle(xy=(0.0, 0.0), fc='none', radius=Rmin,
                    ec='c', zorder=1, lw=2.)
    ax.add_artist(circle)
    circle = Circle(xy=(0.0, 0.0), fc='none', radius=Rmax,
                    ec='c', zorder=1, lw=2.)
    ax.add_artist(circle)
    squre = Rectangle(xy=(Rect_x_min, Rect_y_min), fc='none',
                      width=Rect_x_max-Rect_x_min,
                      height=Rect_y_max-Rect_y_min, ec='r', zorder=1, lw=2.)
    ax.add_artist(squre)
    ax.set_aspect(1)
    ax.set_aspect('equal', adjustable='box', anchor='C')
    xlim = [Rect_x_min, Rect_x_max]
    ylim = [Rect_y_min, Rect_y_max]
    lim = [min(xlim[0], ylim[0]), max(xlim[1], ylim[1])]
    ax.set_xlim(lim)
    ax.set_ylim(lim)
    ax.set_xlabel('x arcsec')
    ax.set_ylabel('y arcsec')
    fig.savefig('%s/IFU_hull.eps'%path, dpi=300)
    # spaxel bins
    with open('%s/spaxel_bins.dat'%path, 'w') as ff:
        for i in range(len(xbin)):
            print('{:12f} {:12f} {:6d}'.format(xbin[i],ybin[i],binNum[i]), file = ff)
    # voronoi bins
    with open('%s/voronoi_bins.dat'%path, 'w') as ff:
        for i in range(len(xNode)):
            print(('{:6d} {:12f} {:12f} {:12f} {:6d}'
                .format(i, xNode[i], yNode[i], 0.1, 1)), file = ff)
def binning_spaxels(galaxy,
                    targetSN=None,
                    opt='kin',
                    auto_override=False,
                    debug=False,
                    set_range=None):
    print '     Voronoi Binning'
    # ----------===============================================---------
    # ----------============ Default parameters ===============---------
    # ----------===============================================---------
    dir = "%s/Data/muse" % (cc.base_dir)
    data_file = "%s/analysis/galaxies.txt" % (dir)
    # Check if file has anything in it - it does need to exsist.
    try:
        d = np.loadtxt(data_file, unpack=True, dtype=str)
        galaxy_gals = d[0][1:]
        x_gals, y_gals = d[1][1:].astype(int), d[2][1:].astype(int)
        SN_gals = {d[i][0]: d[i][1:].astype(float) for i in range(3, len(d))}
    except StopIteration:
        galaxy_gals = np.array([])
        x_gals = np.array([])
        y_gals = np.array([])
        SN_gals = {}

    try:
        SN_used_gals = SN_gals['SN_%s' % (opt)]
    except KeyError:
        SN_used_gals = np.zeros([len(galaxy_gals)])

    i_gal = np.where(galaxy_gals == galaxy)[0]
    if len(i_gal) == 0:
        i_gal = -1
        galaxy_gals = np.append(galaxy_gals, galaxy)

    if targetSN is None and i_gal != -1:
        targetSN = SN_used_gals[i_gal]
    elif targetSN is not None and i_gal != -1:
        targetSN = check_overwrite(float(targetSN), SN_used_gals[i_gal],
                                   auto_override)
        SN_used_gals[i_gal] = targetSN
    elif targetSN is not None and i_gal == -1:
        SN_used_gals = np.append(SN_used_gals, targetSN)
    else:
        targetSN = 30.0
        SN_used_gals = np.append(SN_used_gals, targetSN)

    if i_gal == -1:
        x_gals = np.append(x_gals, 0)
        y_gals = np.append(y_gals, 0)

        SN_gals = {t: np.append(v, 0) for t, v in SN_gals.iteritems()}

# ----------================= Save SN_used ===============---------
    SN_gals['SN_%s' % (opt)] = SN_used_gals

    temp = "{0:12}{1:4}{2:4}" + ''.join([
        '{%i:%i}' % (i + 3, len(t) + 1) for i, t in enumerate(SN_gals.keys())
    ]) + '\n'

    SN_titles = list(SN_gals.keys())
    with open(data_file, 'w') as f:
        f.write(temp.format("Galaxy", "x", "y", *(s for s in SN_titles)))
        for i in range(len(galaxy_gals)):
            f.write(
                temp.format(galaxy_gals[i], str(int(x_gals[i])),
                            str(int(y_gals[i])),
                            *(str(round(SN_gals[s][i], 2))
                              for s in SN_titles)))

# ----------================ Find S/N ================------------
# Final wildcard notes that depending on the method used the quadrants
#may or may not have been flux calibrated.
    dataCubeDirectory = get_dataCubeDirectory(galaxy)

    f = fits.open(dataCubeDirectory)
    galaxy_data, header = f[1].data, f[1].header
    galaxy_noise = f[2].data

    ## write key parameters from header - can then be altered in future
    CRVAL_spec = header['CRVAL3']
    CDELT_spec = header['CD3_3']

    s = galaxy_data.shape

    x = np.zeros(s[1] * s[2])
    y = np.zeros(s[1] * s[2])

    if set_range is not None:
        set_range[0] = max(set_range[0], CRVAL_spec)
        set_range_pix = (set_range - CRVAL_spec) / CDELT_spec
    else:
        set_range_pix = np.array([0, s[0]])
    set_range_pix = set_range_pix.astype(int)

    # collapsing the spectrum for each spaxel.
    if debug:
        signal = np.array(
            galaxy_data[int(np.mean(set_range_pix)), :, :].flatten())
        # noise = np.sqrt(galaxy_noise[s[0]/2,:,:])#.flatten())
        noise = np.sqrt(np.abs(
            galaxy_data[int(np.mean(set_range_pix)), :, :])).flatten()
    else:
        signal = np.zeros((s[1], s[2]))
        # flux = np.zeros((s[1],s[2]))
        noise = np.zeros((s[1], s[2]))
        blocks = 10
        bl_delt1 = int(np.ceil(s[1] / float(blocks)))
        bl_delt2 = int(np.ceil(s[2] / float(blocks)))
        for i in xrange(blocks):
            for j in xrange(blocks):
                # flux[bl_delt1*i:bl_delt1*(i+1),bl_delt2*j:bl_delt2*(j+1)] = np.trapz(
                # 	galaxy_data[set_range_pix[0]:set_range_pix[1],
                # 	bl_delt1*i:bl_delt1*(i+1), bl_delt2*j:bl_delt2*(j+1)], axis=0,
                # 	dx=CDELT_spec)
                signal[bl_delt1*i:bl_delt1*(i+1),bl_delt2*j:bl_delt2*(j+1)] = \
                 np.nanmedian(galaxy_data[set_range_pix[0]:set_range_pix[1],
                 bl_delt1*i:bl_delt1*(i+1), bl_delt2*j:bl_delt2*(j+1)], axis=0)
                noise[bl_delt1*i:bl_delt1*(i+1),bl_delt2*j:bl_delt2*(j+1)] = \
                 np.nanmedian(galaxy_noise[set_range_pix[0]:set_range_pix[1],
                 bl_delt1*i:bl_delt1*(i+1), bl_delt2*j:bl_delt2*(j+1)], axis=0)
        # signal_sav = np.array(signal)
        # noise_sav = np.array(noise)
        signal = signal.flatten()
        noise = noise.flatten()

        bad_pix = (signal <= 0) + (noise <= 0)
        signal[bad_pix] = np.nan
        noise[bad_pix] = np.nan
        # noise +=0.000001

    galaxy_data = []
    del galaxy_data
    galaxy_noise = []
    del galaxy_noise

    for i in range(s[1]):
        for j in range(s[2]):
            # Assign x and y
            x[i * s[2] + j] = i
            y[i * s[2] + j] = j
    # x = max(x)-x

    mask = (np.isfinite(signal)) * (np.isfinite(noise))

    # nobin = signal/noise > targetSN*2

    # signal = signal[mask + ~nobin]
    # noise = noise[mask + ~nobin]
    # x = x[mask + ~nobin]
    # y = y[mask + ~nobin]
    # n_spaxels = np.sum(mask) # include the not-for-binning-bins

    signal = signal[mask]
    noise = noise[mask]
    x = x[mask]
    y = y[mask]
    n_spaxels = np.sum(mask)

    # fig,ax=plt.subplots()
    # s1=signal_sav/(flux/s[0])
    # s_order = np.sort(s1).flatten()
    # s1[s1>s_order[-15]] = s_order[-16]
    # a= ax.imshow(s1)
    # ax.set_title("'signal'/flux")
    # fig.colorbar(a)

    # fig2,ax2=plt.subplots()
    # a = ax2.imshow(noise_sav/(flux/s[0]))
    # fig2.colorbar(a)
    # ax2.set_title("'noise'/flux")

    # fig3,ax3=plt.subplots()
    # a = ax3.imshow(noise_sav/np.sqrt(flux/s[0]))
    # fig3.colorbar(a)
    # ax3.set_title("'noise'/sqrt(flux)")
    # plt.show()

    if not os.path.exists("%s/analysis/%s/%s/setup" % (dir, galaxy, opt)):
        os.makedirs("%s/analysis/%s/%s/setup" % (dir, galaxy, opt))

    # if not debug:
    binNum, xNode, yNode, xBar, yBar, sn, nPixels, scale = voronoi_2d_binning(
        x,
        y,
        signal,
        noise,
        targetSN,
        quiet=True,
        plot=False,
        saveTo='%s/analysis/%s/%s/setup/binning.png' % (dir, galaxy, opt))
    plt.close('all')
    # else:
    # 	binNum = np.arange(len(x))
    # 	xBar = x
    # 	yBar = y

    # xBar = np.append(xBar, x[nobin])
    # yBar = np.append(yBar, y[nobin])
    # binNum = np.append(binNum, np.arange(np.sum(nobin))+max(binNum)+1)

    order = np.argsort(binNum)
    xBin = np.zeros(n_spaxels)
    yBin = np.zeros(n_spaxels)

    # spaxel number
    i = 0
    for bin in range(max(binNum) + 1):
        while i < n_spaxels and bin == binNum[order[i]]:
            xBin[order[i]] = xBar[bin]
            yBin[order[i]] = yBar[bin]
            # move onto next spaxel
            i = i + 1

# ------------================ Saving Results ===============---------------

    temp = "{0:5}{1:5}{2:8}{3:10}{4:10}\n"
    temp2 = "{0:12}{1:12}\n"

    with open(
            "%s/analysis/%s/%s/setup/voronoi_2d_binning_output.txt" %
        (dir, galaxy, opt), 'w') as f:
        f.write(temp.format('X"', 'Y"', 'BIN_NUM', 'XBIN', 'YBIN'))
        for i in range(len(xBin)):
            f.write(
                temp.format(str(int(x[i])), str(int(y[i])),
                            str(int(binNum[i])), str(round(xBin[i], 5)),
                            str(round(yBin[i], 5))))

    with open(
            "%s/analysis/%s/%s/setup/voronoi_2d_binning_output2.txt" %
        (dir, galaxy, opt), 'w') as f:
        f.write(temp2.format('XBAR', 'YBAR'))
        for i in range(len(xBar)):
            f.write(
                temp2.format(str(round(xBar[i], 5)), str(round(yBar[i], 5))))

    print 'Number of bins: ', max(binNum) + 1
Пример #11
0
def binning():
    file = "NGC0528-V500.rscube.fits"
    hdu = pyfits.open(file)
    gal_lin = hdu[0].data  # axes are wav,y,x
    h1 = hdu[0].header
    gal_err = hdu[1].data
    badpix = hdu[3].data

    xs = 70
    ys = 70
    ws = gal_lin.shape[0]

    # Remove badpixels

    medgal = np.zeros((ys, xs))
    medgalerr = np.zeros((ys, xs))

    xarr = np.zeros(xs * ys)
    yarr = np.zeros(xs * ys)
    medarr = np.zeros(xs * ys)
    mederrarr = np.zeros(xs * ys)

    count = 0
    for i in range(xs):
        for j in range(ys):
            no = np.where(badpix[:, j, i] == 1)[0]
            numbd = no.size
            numgd = ws - numbd
            if numgd > 0 and numgd < ws:
                cgal = np.delete(gal_lin[:, j, i], no)
                cgalerr = np.delete(gal_err[:, j, i], no)
                medgal[j, i] = np.median(cgal)
                medgalerr[j, i] = np.median(cgalerr)
            elif numgd == 0:
                medgal[j, i] = 0.0
                medgalerr[j, i] = 0.0
            elif numgd == ws:
                medgal[j, i] = np.median(cgal)
                medgalerr[j, i] = np.median(cgalerr)
            xarr[count] = i
            yarr[count] = j
            medarr[count] = medgal[j, i]
            mederrarr[count] = medgalerr[j, i]
            count = count + 1

    hdu = pyfits.PrimaryHDU(medgal)
    hdu.writeto("medgal.fits", clobber=True)
    # Remove low S/N pixels

    x = np.zeros(0)
    y = np.zeros(0)
    signal = np.zeros(0)
    noise = np.zeros(0)
    gd = 0

    for i in range(count):
        if medarr[i] > 0.05 and mederrarr[i] < 100:
            gd = gd + 1
            x = np.append(x, xarr[i])
            y = np.append(y, yarr[i])
            signal = np.append(signal, medarr[i])
            noise = np.append(noise, mederrarr[i])

    output = np.zeros((gd, 4))
    output[:, 0] = x
    output[:, 1] = y
    output[:, 2] = signal
    output[:, 3] = noise

    np.savetxt("medgalpy.txt", output, fmt="%10.3g")

    # Voronoi binning

    targetSN = 80
    binNum, xNode, yNode, xBar, yBar, sn, nPixels, scale = voronoi_2d_binning(
        x, y, signal, noise, targetSN, plot=1, quiet=1
    )

    np.savetxt("voronoi_2d_binning_output.txt", np.column_stack([x, y, binNum]), fmt=b"%10.6f %10.6f %8i")
    np.savetxt("bins.txt", np.column_stack([xNode, yNode]), fmt="%10.3g")
    nbins = xNode.shape[0]

    avspec = np.zeros((nbins, ws))
    avspecerr = np.zeros((nbins, ws))
    binflux = np.zeros(nbins)
    x = x.astype(int)
    y = y.astype(int)
    for j in range(nbins):
        b = np.where(binNum == j)[0]
        valbin = b.size
        if valbin == 1:
            for i in range(ws):
                avspec[j, i] = gal_lin[i, y[b], x[b]]
                avspecerr[j, i] = gal_err[i, y[b], x[b]]
        else:
            for i in range(ws):
                avspec[j, i] = np.sum(gal_lin[i, y[b], x[b]]) / valbin
                avspecerr[j, i] = np.sum(gal_err[i, y[b], x[b]]) / valbin
        binflux[j] = np.sum(avspec[j, :])

    np.savetxt("binflux.txt", binflux, fmt="%10.3g")

    hdu = pyfits.PrimaryHDU(avspec)
    hdu.writeto("galaxybinspy.fits", clobber=True)