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')
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)
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)
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',
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)
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
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)