def compareW(PSF,sig,accd,cx,cy): x1, y1 = centroid_com(PSF) x2, y2 = centroid_1dg(PSF) x3, y3 = centroid_2dg(PSF) errx1=cx-1-x1 erry1=cy-1-y1 errx2=cx-1-x2 erry2=cy-1-y2 errx3=cx-1-x3 erry3=cy-1-y3 err1=((errx1)**2+(erry1)**2)**0.5 err2=((errx2)**2+(erry2)**2)**0.5 err3=((errx3)**2+(erry3)**2)**0.5 # print("%.2e,%.2e,%.2e,%.2e,%.2e,%.2e," % ( errx1,erry1,errx2,erry2,errx3,erry3)) # Weighted Weight=GaussianFunc(sig,accd,cx,cy) PSFW=PSF*Weight x1, y1 = centroid_com(PSFW) x2, y2 = centroid_1dg(PSFW) x3, y3 = centroid_2dg(PSFW) errx12=cx-1-x1 erry12=cy-1-y1 errx22=cx-1-x2 erry22=cy-1-y2 errx32=cx-1-x3 erry32=cy-1-y3 err12=((errx12)**2+(erry12)**2)**0.5 err22=((errx22)**2+(erry22)**2)**0.5 err32=((errx32)**2+(erry32)**2)**0.5 # print("%.2e,%.2e,%.2e,%.2e,%.2e,%.2e," % ( errx12,erry12,errx22,erry22,errx32,erry32)) return err1,err2,err3,err12,err22,err32
def plot_image(): std = np.std(stamp[stamp == stamp]) x1, y1 = centroid_com(stamp) x2, y2 = centroid_1dg(stamp) x3, y3 = centroid_2dg(stamp) return [((x1 - dx + xcen), (x2 - dx + xcen), (x3 - dx + xcen)), ((y1 - dy + ycen), (y2 - dy + ycen), (y3 - dy + ycen))]
def psfpy(data): x1, y1 = centroid_com(data) x2, y2 = centroid_1dg(data) x3, y3 = centroid_2dg(data) # print(data) # print(x1,y1,x2,y2,x3,y3) # mean, median, std = sigma_clipped_stats(data, sigma=3.0, iters=5) # data -= median # subtract background cat = data_properties(data) # print (cat) #列输出 columns = [ 'id', 'xcentroid', 'ycentroid', 'semimajor_axis_sigma', 'semiminor_axis_sigma', 'orientation', 'cxx', 'cyy', 'cxy', 'eccentricity' ] tbl = cat.to_table(columns=columns) tbl['cxy'].info.format = '.10f' eccef = float(tbl['eccentricity']) str1 = str(tbl['semimajor_axis_sigma']) semimajorf = str1.split("[")[1].split("]")[0] str1 = str(tbl['semiminor_axis_sigma']) semiminorf = str1.split("[")[1].split("]")[0] str1 = str(tbl['orientation']) orientationf = str1.split("[")[1].split("]")[0] str1 = str(tbl['cxx']) cxxf = str1.split("[")[1].split("]")[0] str1 = str(tbl['cxy']) cxyf = str1.split("[")[1].split("]")[0] str1 = str(tbl['cyy']) cyyf = str1.split("[")[1].split("]")[0] return (x1, y1, x2, y2, x3, y3, semimajorf, semiminorf, eccef, orientationf, cxxf, cxyf, cyyf)
def find_shift(self, previous_x, previous_y, image_path): # choose how big a box to draw around your star size = 10 # 10 will make a 20x20 pixel box # open the second image and load it as an array image = fits.open( image_path ) # replace 'FullComb.fits' with the namne of your second image file data_array = image[0].data # Select just the box around the star data_square = data_array[ int(previous_y) - size:int(previous_y) + size, int(previous_x) - size:int(previous_x) + size] # note your x,y coords need to be an int plt.imshow(data_square, origin='lower', cmap='viridis') print(previous_x, previous_y) x, y = centroid_2dg(data_square) plt.plot(x, y, 'r*', label='new center') plt.show() x_shift = ((x - size) - (previous_x - int(previous_x)) ) # also correcting for the shift due to using int y_shift = ((y - size) - (previous_y - int(previous_y))) return x_shift, y_shift
def plot_psf(self, iob=0, iapt=0, max_r=15, figsize=None, ax=None): a = self._apertures_obj[iapt] m = a.to_mask()[iob] d = m.cutout(self.reduced) _, dmedian, _ = sigma_clipped_stats(d) d -= dmedian xc, yc = centroid_2dg(d) X, Y = meshgrid(arange(d.shape[1]), arange(d.shape[0])) r = sqrt((X - xc)**2 + (Y - yc)**2) if ax: fig, axl = None, ax else: fig, axl = subplots(figsize=figsize) axl.plot(r.ravel(), d.ravel() / d.max(), '.') setp(axl, xlabel='Distance from the PSF centre [pix]', ylabel='Normalised flux') if max_r: axl.set_xlim(0, max_r) sb.despine(ax=axl, offset=6) return fig, axl
def plot_image(posx, posy, count, prevstds): #We have to redefine the stamp every time, otherwise the program doesn't woek stamp = data[i][int(round(posy - dy)):int(round(posy + dy)), int(round(posx - dx)):int(round(posx + dx))] #this is just to keep track of how much recursing we do count = count + 1 std = np.std(stamp[stamp == stamp]) x1, y1 = centroid_com(stamp) x2, y2 = centroid_1dg(stamp) x3, y3 = centroid_2dg(stamp) xavg = np.average([x2, x3]) yavg = np.average([y2, y3]) xstd = np.std([x2, x3]) ystd = np.std([y2, y3]) #xavg = np.average([x1,x2,x3]) #yavg = np.average([y1,y2,y3]) #xstd = np.std([x1,x2,x3]) #ystd = np.std([y1,y2,y3]) #print(count, posx-dx+xavg, posy-dy+yavg, xstd, ystd) # RECURSION BITCH limit 100 times, while either std is higher than our 0.1 threshold # and as long as the std is getting smaller if (xstd + ystd > prevstds[0] + prevstds[1]): return posx, posy, prevstds[0]**(-2), prevstds[1]**(-2), count - 1 if count < 100 and (xstd > 0.1 or ystd > 0.1) and (xstd <= prevstds[0] and ystd <= prevstds[1]): return plot_image(posx - dx + xavg, posy - dy + yavg, count, [xstd, ystd]) else: return posx - dx + xavg, posy - dy + yavg, 1 / (xstd**2), 1 / ( ystd**2), count
def cut_center_bright(image, center, radius,kernel = 'gaussian', return_center=False,plot=True,center_float = False): """ Auto cut the image, with with brightest center in the center. kernel: define the center. """ temp_center = np.asarray(center) # print temp_center.astype(int) radius = radius img_test = cut_image(image=image, center=temp_center.astype(int), radius=radius) if kernel == 'gaussian': for i in range(3): frm_q = int(len(img_test)/2.5) from photutils import centroid_2dg test_center = frm_q + centroid_2dg(img_test[frm_q:-frm_q,frm_q:-frm_q]) if i ==2 and plot==True : print test_center fig, ax = plt.subplots(1, 1) ax.imshow(img_test[frm_q:-frm_q,frm_q:-frm_q], origin='lower') marker = '+' ms, mew = 30, 2. plt.plot(test_center[0]-frm_q, test_center[1]-frm_q, color='b', marker=marker, ms=ms, mew=mew) plt.show() print 'test_center - radius', test_center, radius center_shift = np.array((test_center - radius)) if i ==2 and plot==True : print 'center_shift',center_shift center = (center.astype(int) + np.round(center_shift)) center_f = center.astype(int) + center_shift img_test = cut_image(image=image, center=center, radius=radius) if i ==2 and plot==True : plt_center = img_test[frm_q:-frm_q,frm_q:-frm_q].shape plt.plot(plt_center[0]/2, plt_center[1]/2, color='r', marker=marker, ms=ms, mew=mew) plt.imshow(img_test[frm_q:-frm_q,frm_q:-frm_q], origin='lower') plt.show() cut_c_b = img_test elif kernel == 'center_bright': frm_q = int(len(img_test)/2.5) test_center = np.asarray(np.where(img_test == img_test[frm_q:-frm_q,frm_q:-frm_q].max()))[:,0] center_shift = np.array((test_center- radius))[::-1] center = (temp_center.astype(int) + np.round(center_shift)) cut_c_b = cut_image(image=image, center=center, radius=radius) plt_center = img_test[frm_q:-frm_q,frm_q:-frm_q].shape if plot==True: marker = '+' ms, mew = 30, 2. plt.plot(plt_center[0]/2, plt_center[1]/2, color='c', marker='+', ms=30, mew=2) plt.imshow(cut_c_b[frm_q:-frm_q,frm_q:-frm_q], origin='lower') plt.show() if return_center==False: return cut_c_b elif return_center==True and center_float==False: return cut_c_b, center elif return_center==True and center_float==True: return cut_c_b, center_f
def plot_image_monster(posx, posy): stamp = data[i][int(round(posy - dy)):int(round(posy + dy)), int(round(posx - dx)):int(round(posx + dx))] std = np.std(stamp[stamp == stamp]) x2, y2 = centroid_1dg(stamp) x3, y3 = centroid_2dg(stamp) xavg = ((x2 - dx + posx) + (x3 - dx + posx)) / 2 yavg = ((y2 - dy + posy) + (y3 - dy + posy)) / 2 xstd = np.std([x2, x3]) ystd = np.std([y2, y3]) return xavg, yavg
def centroid(a): top=19 bot=12 a = ma.masked_invalid(a) #a=sigma_clip(a, sigma=7, iters=1) a=a[bot:top+1, bot:top+1] a2=np.multiply(a,a) beta_np=np.sum(a)**2/np.sum(a2) xcg, ycg = centroid_2dg(a)+bot xc, yc = centroid_com(a)+bot return xc,yc, xcg, ycg
def plot_image(): std = np.std(stamp[stamp==stamp]) plt.imshow(stamp, interpolation='nearest', origin = 'lower', vmin = -1.*std, vmax = 3.*std, cmap='bone') plt.tick_params(axis='both', which='major', labelsize=8) circle0 = plt.Circle((dx,dy),0.1) x1, y1 = centroid_com(stamp) circle1 = plt.Circle((x1,y1),0.1,color='r') ax.add_artist(circle1) x2, y2 = centroid_1dg(stamp) circle2 = plt.Circle((x2,y2),0.1,color='b') ax.add_artist(circle2) x3, y3 = centroid_2dg(stamp) circle3 = plt.Circle((x3,y3),0.1,color='g') ax.add_artist(circle3) return ((x1, y1),(x2, y2),(x3, y3))
def get_centroid(image, method='com'): ''' centroid_com(): Calculates the object 'center of mass' from 2D image moments. centroid_1dg(): Calculates the centroid by fitting 1D Gaussians to the marginal x and y distributions of the data. centroid_2dg(): Calculates the centroid by fitting a 2D Gaussian to the 2D distribution of the data. Default is centroid_2dg. ''' if method == 'com': x, y = centroid_com(image) elif method == '1d_gaussian': x, y = centroid_1dg(image) else: #default x, y = centroid_2dg(image) return (x, y)
def plot_image(posx,posy, count, prevstds): stamp = data[int(round(posy-dy)):int(round(posy+dy)), int(round(posx-dx)):int(round(posx+dx))] count = count +1 std = np.std(stamp[stamp==stamp]) x1, y1 = centroid_com(stamp) x2, y2 = centroid_1dg(stamp) x3, y3 = centroid_2dg(stamp) xavg = np.average([x1,x2,x3]) yavg = np.average([y1,y2,y3]) xstd = np.std([x1,x2,x3]) ystd = np.std([y1,y2,y3]) # RECURSION BITCH if count < 100 and (xstd > 0.1 or ystd > 0.1) and (xstd <= prevstds[0] and ystd <= prevstds[1]): print(count, posx-dx+xavg, posy-dy+yavg, xstd, ystd) return plot_image(posx-dx+xavg, posy-dy+yavg, count, [xstd,ystd]) else: return posx-dx+xavg, posy-dy+yavg, 1/(xstd**2), 1/(ystd**2), count
def get_fitgausscent(scidata, xguess, yguess, window_size=11): """ Determines the centroid of the point source in the image 'file_name' by fitting a 2-D gaussian. Args: scidata : FITS file data in which the centroid of the point source is to be determined xguess : Guess value of the X-centroid of the point source in pixels yguess : Guess value of the Y-centroid of the point source in pixels window_size : Window (square) size in pixels to be used for determining the centroid Returns: xcen : Estimated X-centroid of the point source ycen : Estimated Y-centroid of the point source """ window_size = int(window_size) xlow, xhigh, ylow, yhigh = determine_bounds(xguess, yguess, window_size) xcen, ycen = centroid_2dg(scidata[xlow:xhigh, ylow:yhigh]) xcen += xlow ycen += ylow return xcen, ycen
def centroid(imdat, x0, y0, boxsize=11): """ Locate a source in the image near position (x0,y0) using a 2-D gaussian centroid algorithm. :param imdat: image data (2-D array) :param x0: initial guess of x pixel location of the source :param y0: initial guess of y pixel location of the source :param boxsize: size of the box to search in (pixels) :return: """ # create a mask that masks out all the pixels more than boxsize/2 # pixels from the first-guess SN position (the center of the image, # or the target location specified by the user) halfbox = boxsize / 2. mask = np.ones(imdat.shape, dtype=bool) mask[int(y0 - halfbox):int(y0 + halfbox), int(x0 - halfbox):int(x0 + halfbox)] = False xnew, ynew = photutils.centroid_2dg(imdat, mask=mask) return xnew, ynew
def get_centroid(image, method='com'): ''' centroid_com(): Calculates the object “center of mass” from 2D image moments. centroid_1dg(): Calculates the centroid by fitting 1D Gaussians to the marginal x and y distributions of the data. centroid_2dg(): Calculates the centroid by fitting a 2D Gaussian to the 2D distribution of the data. Default is com. ''' if method == 'com': x, y = centroid_com(image) return (x, y) elif method == '1d_gaussian': x, y = centroid_1dg(image) return (x, y) elif method == '2d_gaussian': #bug: takes too much time; fit may be unsuccessful x, y = centroid_2dg(image) return (x, y) else: print('invalid centroiding algorithm') sys.exit()
def recenter_source(self, data): """Recenters source position in cutout and updates x,y attributes""" # Archive old positions. self.old_x = self.x self.old_y = self.y if self.is_empty: self.x, self.y = np.nan, np.nan else: # Fit 2D gaussian xg1, yg1 = centroid_2dg(self.cutout) dx = xg1 + self.sx.start - self.x dy = yg1 + self.sy.start - self.y dr = (dx**2. + dy**2.)**.5 if dr > 2.: print('Large shift of {},{} computed.'.format(dx, dy)) print('Rejecting and keeping original x, y coordinates') else: self.x = xg1 + self.sx.start self.y = yg1 + self.sy.start self._setup_cutout(data)
def centroid_cb(self, w): im = self.fitsimage.get_image().get_data() try: xc = int(float(self.w.x_center.get_text())) yc = int(float(self.w.y_center.get_text())) box = int(float(self.w.centroid_box.get_text())) except ValueError: return if box < 3: box = 3 self.w.centroid_box.set_text('3') elif box > min(xc, yc, im.shape[0] - yc, im.shape[1] - xc): box = int(min(xc, yc, im.shape[0] - yc, im.shape[1] - xc)) self.w.centroid_box.set_text(str(box)) x0 = xc - box // 2 y0 = yc - box // 2 subim = im[y0:y0+box+1, x0:x0+box+1] cxy = photutils.centroid_2dg(subim) self.w.x_center.set_text('{:.2f}'.format(cxy[0] + x0)) self.w.y_center.set_text('{:.2f}'.format(cxy[1] + y0))
orient=image_header['orientat']%360 array_of_PSFs = []; for i in range(100): filename = " PSFmodel_" + str(i + 1) + ".npy" array_of_PSFs.append(np.load(filename)) array_of_PSFs = np.asarray(array_of_PSFs) bestprim=[] bestsec=[] tempout=[] cx=int((array_of_PSFs[0].shape[1]-1)/2) cy=int((array_of_PSFs[0].shape[0]-1)/2) for itr,output in enumerate(outputs): xp=output[1][1]+centroid_2dg(array_of_PSFs[output[3]])[0]-cx yp=output[1][0]+centroid_2dg(array_of_PSFs[output[3]])[1]-cy xs=output[2][1]+centroid_2dg(array_of_PSFs[output[5]])[0]-cx ys=output[2][0]+centroid_2dg(array_of_PSFs[output[5]])[1]-cy x1=cx+centroid_2dg(array_of_PSFs[output[3]])[0]-cx y1=cy+centroid_2dg(array_of_PSFs[output[3]])[1]-cy x2=cx+centroid_2dg(array_of_PSFs[output[5]])[0]-cx y2=cy+centroid_2dg(array_of_PSFs[output[5]])[1]-cy angle=(orient-90+math.atan2(ys-yp,xs-xp)*180/math.pi)%180 if (ys-yp,xs-xp)==(0,0): angle = 0.0 sep=(((xp-xs)*PlateScaleX)**2+((yp-ys)*PlateScaleY)**2)**(1/2) tempout.append((output[0],)+((yp,xp),(ys,xs))+output[3:8]+(angle,sep))
#newim = imdata[y-size:y+size,x-size:x+size] del imdata, imdata12 #print(newim[size,size]) newim = im - im12 plt.figure(figsize=[18, 8]) plt.subplot(131) plt.imshow(newim) vari_funcs.no_ticks() #plt.plot(size,size,'k+') plt.title('08B - 12B') #x1, y1 = centroid_com(newim) #x2, y2 = centroid_1dg(newim) x3, y3 = centroid_2dg(newim) #plt.plot(x1,y1,'r+') #plt.plot(x2,y2,'m+') plt.plot(x3, y3, 'b+') imuppthresh = 190 im[im > imuppthresh] = imuppthresh imlowthresh = 0 im[im < imlowthresh] = imlowthresh im12[im12 > imuppthresh] = imuppthresh im12[im12 < imlowthresh] = imlowthresh #newim[newim>imuppthresh] = imuppthresh #newim[newim<imlowthresh] = imlowthresh #plt.figure(figsize=[8,8]) plt.subplot(132)
def centroidFinder(x, y, data, r): """Experimental, doesnt work""" xx = int(x) yy = int(y) chunk = data[yy-r : yy+r, xx-r : xx+r] x, y = photutils.centroid_2dg(x, y, chunk)
def apphot(imagename, ext=1, coofile='', colnames='default', outname='default', ap_radii=[12.0], sep_out=False, backmethod='mean', backglobal=False, method='subpixel', subpixels=5, centroid=False, pixelwise_error=None, effective_gain=None, mask=None, annulus=4., dannulus=2., verbose=False): """Performs aperture photometry for all given aperture radii (pixels). *mag files will be generated in cwd. They will not be overwriten. A new file will be appended with '.n', where n is (1,2,3,...). ## Need a switch for doing either full-frame background or background ## via annulus? Parameters ---------- imagename : string or array Either name of the FITS file or the array containing the data of that extension. ext : int Extension of FITS file to be read. Default of 1. coofile : string Name of the coordinate file. colnames : list of strings The column names of the x and y. If default, assumes they are 'xcentroid' and 'ycentroid', which daofind returns. A non-default example is ['col3', 'col4'] (base of 1). outname : string Name desired for output *mag file. By default, it is <imagename>.mag<.n>, where 'n' increases from 1 if the *mag file already exists. ap_radii : list of floats or ints The apertures. Units of pixels. sep_out : {True, False} If on, will create a seperate out file for each aperture radius. If off will add a row for each aperture for each source. Off by default. backmethod : string Method of calculating background. Currently 'mean' only supported option. backglobal : {True, False} Do either global background subtraction (where sources get masked and mean/median/mode taken of frame) or local (using the annulus and dannulus values). By default False - so background is local by default. method : string Method to use for determining overlap between the aperture and pixels. Options include ['center', 'subpixel', 'exact'], but not all options are available for all types of apertures. More precise methods will generally be slower. subpixels : int, optional If 'subpixel' is selected in method parameter, resample pixels by this factor (in each dimension). That is, each pixel is divided into subpixels ** 2 subpixels. centroid : {True, False} Turn on to centroid sources with ``phoutils.morphology.centroid_2dg``. Only recommended for single-source images for now. pixelwise_error : {True, False} For ``error`` and/or ``effective_gain`` arrays. If `True`, assume ``error`` and/or ``effective_gain`` vary significantly within an aperture: sum contribution from each pixel. If `False`, assume ``error`` and ``effective_gain`` do not vary significantly within an aperture. Use the single value of ``error`` and/or ``effective_gain`` at the center of each aperture as the value for the entire aperture. Default is `True`. #error : #effective_gain : mask : array of bool Must be same dimensions as image. annulus : int or float The factor to multiply aperture radius by. For calculating background. dannulus : int or float The depth of the annulus in pixels. verbose : {True, False} Set to True if want to print the tables to screen. False by default. Returns ------- phot_tab or mega_phot_tab : `~astropy.table.Table` A table of the photometry with the following columns: * ``'aperture_sum'``: Sum of the values within the aperture. * ``'aperture_sum_err'``: Corresponding uncertainty in ``'aperture_sum'`` values. Returned only if input ``error`` is not `None`. * ``'xcenter'``, ``'ycenter'``: x and y pixel coordinates of the center of the apertures. Unit is pixel. * ``'xcenter_input'``, ``'ycenter_input'``: input x and y coordinates as they were given in the input ``positions`` parameter. Outputs ------- If 'sep_out' True, then for each radius in 'ap_radii', <imagename><_radius>.mag. If the file already exists, a number will be appended. An image named abcdefg.fits with aperture radii of 5.0 and 12.0 will get *mag out files named, for example, as abcdefg.fits_5.0.mag abcdefg.fits_5.0.mag.1 abcdefg.fits_5.0.mag.2 ... and abcdefg.fits_12.0.mag abcdefg.fits_12.0.mag.1 abcdefg.fits_12.0.mag.2 ... If 'sep_out' False, then all radii are in same file for each source and the file is named as <imagename>.mag. Then naming scheme for an image name of abcdefg.fits is abcdefg.fits.mag abcdefg.fits.mag.1 abcdefg.fits.mag.2 ... In both cases of 'sep_out', <imagename> can be replaced by 'outname' if default is not set. The *mag files contain the five columns 'ID', 'radius', 'aperture_sum', 'xcenter', and 'ycenter'. Each row is a new ID. If 'sep_out' False then each ID will have a new row for each aperture. Notes ----- Doesn't handle singletons well! If only 1 star in coo file, it will NOT join tables (for some reason), so will need set sep_out=True. Also, it will print the x and y coords to file within brackets (again, for some reason) and I don't know what to do about that. """ # Fetch function metadata. current_params = locals() func_name = sys._getframe().f_code.co_name # Read in FITS file. if '.fits' in imagename: hdulist = fits.open(imagename) data = hdulist[ext].data hdulist.close() else: data = imagename current_params['imagename'] = 'numpy array' # If a mask is given, set the parameter so shows nicely in outfile. if mask != None: current_params['mask'] = 'numpy array' # Read the coo file to get the positions. coo_tab = ascii.read(coofile) print(coo_tab) if len(coo_tab) == 0: print("Coordinate file is empty. Returning...") return Table() if colnames == 'default': xcoords = list(coo_tab['xcentroid']) ycoords = list(coo_tab['ycentroid']) else: xcoords = list(coo_tab[colnames[0]]) ycoords = list(coo_tab[colnames[1]]) positions = [xcoords, ycoords] # If centroiding coordinates set to True, if centroid: positions = centroid_2dg(data) # If finding a global background, only need do this once. if backglobal: # This will add a 'global_bkgrd' column. # This does not quite work at this time if a source is near an edge. # Also, need have an exception if the imagename is a data array bkgrd, bkgrd_rms = meanclip_bkgrd(imagename, ext, backmethod, xcoords, ycoords) # Create mega-table if a single file for all apertures is selected. if not sep_out: mega_phot_tab = Table() for radius in ap_radii: radius = float(radius) # Get aperture objects using pixel coord positions. apertures = CircularAperture(positions, r=radius) # Do local background subtraction #annulus_apertures = CircularAnnulus(positions, r_in=radius*annulus, r_out=(radius*annulus)+dannulus) annulus_apertures = CircularAnnulus(positions, r_in=annulus, r_out=annulus + dannulus) # Get an error # this should be sky_sig?? how get that? # Then do photometry on the ap radius objects # the table has three columns, named 'aperture_sum', 'xcenter', # and 'ycenter'. # The returned table is potentially 'bad' because aperture_photometry # returns the x and y coords as numpy arrays if there is only one # row of them. It only does this to coords, for reasons only it # knows. This breaks stuff. We fix it below. bad_phot_tab = aperture_photometry( data, apertures, method=method, subpixels=subpixels, pixelwise_error=pixelwise_error, #effective_gain=effective_gain, mask=mask) #,error phot_tab = Table() if len(bad_phot_tab) == 1: # Change xcenter and ycenter so not in tuples. phot_tab = fix_aperture_photometry(phot_tab, bad_phot_tab) else: # Rows should be properly formatted; just set nice table # equal to the bad (now we know not-bad) table. phot_tab = bad_phot_tab # Find backgrounds, either local or global. if backglobal: # Add column to table. The global background was already # calculated since it only needs be done once. phot_tab['global_bkgrd'] = bkgrd elif not backglobal: # Get a background table for annulus apertures. # This will add 'mean_local_bkgrd' and 'tot_local_bkgrd' columns, # where the first is the mean bkgrd per pixels in the annulus # and the total is the mean multiplied by the area of the source's aperture, # which should be used to subtract from the source's flux. bkgrd_phot_tab = Table() bad_bkgrd_phot_tab = aperture_photometry( data, annulus_apertures, method=method, subpixels=subpixels, pixelwise_error=pixelwise_error, mask=mask) if len(bad_bkgrd_phot_tab) == 1: bkgrd_phot_tab = fix_aperture_photometry( bkgrd_phot_tab, bad_bkgrd_phot_tab) else: bkgrd_phot_tab = bad_bkgrd_phot_tab ### possibly make the below into a function ### if backmethod == 'mean': # Calculate mean local background bkgrd_mean = bkgrd_phot_tab[ 'aperture_sum'] / annulus_apertures.area() bkgrd_sum = bkgrd_mean * apertures.area() phot_tab['mean_local_bkgrd'] = bkgrd_mean phot_tab['tot_local_bkgrd'] = bkgrd_sum # Add two more columns: one for ID and one for Aperture. col_id = Column(name='ID', data=np.arange(1, len(phot_tab['xcenter']) + 1)) col_ap = Column(name='radius', data=radius * np.ones(len(phot_tab['xcenter']))) phot_tab.add_column(col_id, 0) phot_tab.add_column(col_ap, 1) # Prepare to write the phot_table in a *mag file. # Create basename for out file. if outname == 'default': if sep_out: baseoutname = '{}_{}.mag'.format( coofile.split('.coo')[0], radius) else: baseoutname = '{}.mag'.format(coofile.split('.coo')[0]) else: if sep_out: baseoutname = '{}_{}.mag'.format(outname, radius) else: baseoutname = '{}.mag'.format(outname) # Check whether file already exists. If yes, append number. fileoutname = baseoutname i = 1 while os.path.isfile(fileoutname): fileoutname = baseoutname fileoutname = '{}.{}'.format(fileoutname, i) i += 1 if sep_out: # If creating a seperate *mag file for earch aperture. write_out_photfile(fileoutname, phot_tab, current_params, func_name) elif (not sep_out) and (len(mega_phot_tab) == 0): # If this is the first iteration, mega_phot_tab is empty and # can just be set equal to phot_tab. mega_phot_tab = phot_tab print("Created mega_phot_tab: {}".format(mega_phot_tab)) else: # If this is a subsequent iteration, mega_phot_tab already exists and # so just need add rows. print("Trying to join phot_tab to mega_phot_tab") if verbose: print(phot_tab) print(mega_phot_tab) mega_phot_tab = table.join(mega_phot_tab, phot_tab, join_type='outer') if not sep_out: # If writing all apertures to single file, write out the mega-table. write_out_photfile(fileoutname, mega_phot_tab, current_params, func_name) # Clear variable. del data return mega_phot_tab else: # Clear variable. del data return phot_tab
hdu_list = fits.open(image_file, ignore_missing_end=True) image = hdu_list[0].data print(image.shape) print( 'Please enter the x and y bounds for a box surrounding the approximate candidate position\n' ) xmin = int(input('Lower x value:')) xmax = int(input('Upper x value:')) ymin = int(input('Lower y value:')) ymax = int(input('Upper y value:')) #note y is first, x is second below snapshot = image[ymin:ymax, xmin:xmax] x, y = centroid_2dg(snapshot) aa = x + xmin + 1 bb = y + ymin + 1 print('Position is:\n') print((aa, bb)) #plt.figure() plt.imshow(snapshot, cmap='gray') plt.gca().invert_yaxis() marker = '+' ms, mew = 15, 2. plt.plot(x, y, color='red', marker=marker, ms=ms, mew=mew) plt.show() #Start of aperture photometry print('Would you like to do aperture photometry on this source?\n')
def plot_image(): std = np.std(stamp[stamp == stamp]) x1, y1 = centroid_com(stamp) x2, y2 = centroid_1dg(stamp) x3, y3 = centroid_2dg(stamp) return np.array([[x1, x2, x3], [y1, y2, y3]])
def center_circlesym(im, xr, yr, rmax, mask=None): '''Finds the center of a star image assuming circular symmetry PARAMETERS: im : the input image xr : vector of x-offsets from the center of the image yr : vector of y-offsets from the center of the image rmax : maximum radius to consider mask : optional 1/0 mask, 1 specifies pixels to ignore. RETURNS: xc : the center x position yc : the center y position grid : grid of results (xr vs yr vs stddev) ''' if mask is None: mask = np.zeros_like(im) dimx = im.shape[1] ### x dimy = im.shape[0] ### y x = (np.arange(dimx) + 0.5) / dimx * 2.0 - 1.0 y = ((np.arange(dimy) + 0.5) / dimy * 2.0 - 1.0) * (dimy / dimx) xx, yy = np.meshgrid(x, y) xc = 2. * xr / dimx yc = 2. * yr / dimy XX = np.repeat(xx[np.newaxis, :, :], len(xc), axis=0) YY = np.repeat(yy[np.newaxis, :, :], len(xc), axis=0) XX = (XX.T - xc).T YY = (YY.T - yc).T XX2 = XX * XX YY2 = YY * YY print(len(im)) grid = np.zeros((len(yr), len(xr))) print('Out of ' + str(len(xc)) + ' rows, this many have finished: ') for i in np.arange(len(xc)): print(str(i) + ', ', end='', flush=True) for j in np.arange(len(yc)): x2 = XX2[i, :, :] y2 = YY2[j, :, :] r2 = x2 + y2 rsq = np.sqrt(r2) r = 0.5 * rsq * dimx for k in np.arange(rmax + 1): vals = im[(r >= k) & (r < k + 1) & (mask == 0)] # if (i == len(yc)/2) &(j == len(yc)/2): # print(i, k) # plt.figure() # ind = (r >=k) & (r < k+1) & (mask == 0) # im2 = np.copy(im) # # im2 = im2 * ind # xreal = i + (dimx/2.) - (len(xr)/2.) # yreal = j + (dimx/2.) - (len(yr)/2.) # plt.plot(xreal, yreal, marker='*', color='yellow') # plt.imshow(im2, cmap='magma') # plt.title('r = ' + str(k)) # plt.axis('off') # plt.savefig(f'/Users/sbetti/Desktop/radii/R{k}.png') # plt.show() if len(vals) > 0: sd = np.nanstd(vals) if not np.isfinite(sd): sd = 0 med = np.nanmedian(vals) div = (sd / abs(med))**2. grid[j, i] += div # if (i == len(yc)/2) &(j == len(xc)/2): # plt.figure() # plt.imshow(grid*-1, cmap='magma') # plt.savefig(f'/Users/sbetti/Desktop/radii/grid.png') # plt.show() print() # pos = np.where(grid == np.min(grid)) fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3) ax1.imshow(im, cmap='magma', origin='lower') ax2.imshow(mask, cmap='magma', origin='lower') ax3.imshow(-1 * grid, cmap='magma', origin='lower') ax1.axis('off') ax2.axis('off') ax3.axis('off') plt.show() # fits.writeto('grid.fits', -1*grid, overwrite=True) # xcc, ycc = gcntrd(-1 * grid, pos[1][0], pos[0][0], 0.5 * len(xr)) # xcc = xcc[0][0] # ycc = ycc[0][0] # print('gcntd center:', xcc, ycc) # xcc, ycc = fit_gaussian(-1*grid, pos[1][0], pos[0][0]) # print('fit_gaussian center:', xcc, ycc) # xcc, ycc = centroid_2dg(-1*grid) # print('centroid_2dg center:', xcc, ycc) xcc, ycc = centroid_2dg(-1 * grid) print('centroid_1dg center:', xcc, ycc) ##calculating centroid for small grid xc = xcc + (dimx / 2.) - (len(xr) / 2.) yc = ycc + (dimy / 2.) - (len(yr) / 2.) return xc, yc
def get_centroid_cutout(self, x, y, box_size=30, method="howell", dao_fwhm=10., dao_SNR=100., plot=False, plot_full=False, stretch=None): """ Perform centroiding on a cutout window. INPUT: x - a touple y - box_size - the total box size in pixels method - the centroiding method to use for cutout. This can be "centroid_2dg" "centroid_com" "daofind" OUTPUT: centroid positions EXAMPLE: PM = PhotoMetry(filenames[0]) PM.perform_photometry() print(PM.get_centroid_cutout(234.227204448,25.6594515323,method="daofind",plot=True)) print(PM.get_centroid_cutout(234.227204448,25.6594515323,method="centroid_com",plot=True)) print(PM.get_centroid_cutout(234.227204448,25.6594515323,method="centroid_2dg",plot=True)) print(PM.get_centroid_cutout(234.227204448,25.6594515323,method="daofind",box_size=50,stretch="HistEqStretch")) print(PM.get_centroid_cutout(234.227204448,25.6594515323,method="centroid_com",plot=True,box_size=50)) print(PM.get_centroid_cutout(234.227204448,25.6594515323,method="centroid_2dg",plot=True,box_size=50)) """ int_x = int(round(x)) int_y = int(round(y)) postage_stamp = photutils.utils.cutouts.cutout_footprint( self.data, (int_x, int_y), box_size) # Only interested in the image data [1] is the mask postage_stamp = np.array(postage_stamp[0]) #plt.imshow(postage_stamp) #print(postage_stamp) if method == "centroid_2dg": x_stamp_centroid, y_stamp_centroid = photutils.centroid_com( postage_stamp) elif method == "centroid_com": x_stamp_centroid, y_stamp_centroid = photutils.centroid_2dg( postage_stamp) elif method == "daofind": daofind = DAOStarFinder(fwhm=dao_fwhm, threshold=dao_SNR * self.bkg_sigma) sources = daofind(postage_stamp) positions = (sources['xcentroid'], sources['ycentroid']) x_stamp_centroid, y_stamp_centroid = float(positions[0]), float( positions[1]) elif method == "howell": x_stamp_centroid, y_stamp_centroid = self.howell_center( postage_stamp) else: print( "Error: method must be 'daofind', centroid_2dg', 'centroid_com' or 'howell'" ) pass x_centroid = x_stamp_centroid + int_x - box_size / 2. y_centroid = y_stamp_centroid + int_y - box_size / 2. if plot: fig, ax = plt.subplots() if stretch: norm = gkastro.stretch_data(postage_stamp, method=stretch) else: norm = None ax.imshow(postage_stamp, origin="lower", extent=[ int_x - box_size / 2., int_x + box_size / 2., int_y - box_size / 2., int_y + box_size / 2. ], interpolation="none", norm=norm) ax.set_xlim(int_x - box_size / 2., int_x + box_size / 2.) ax.set_ylim(int_y - box_size / 2., int_y + box_size / 2.) ax.set_xlabel("X pixel") ax.set_ylabel("Y pixel") ax.plot(x_centroid, y_centroid, color='#1f77b4', marker="+", ms=30, mew=2) if plot_full: fig, ax = plt.subplots() ax.imshow(self.data, origin="lower") ax.plot(x_centroid, y_centroid, color='#1f77b4', marker="+", ms=30, mew=2) return x_centroid, y_centroid
def plot_imageY(xcen, ycen): std = np.std(stamp[stamp == stamp]) x1, y1 = centroid_com(stamp) x2, y2 = centroid_1dg(stamp) x3, y3 = centroid_2dg(stamp) return [y1, y2, y3]
def find_star_fit(pos_star, \ peak_bezel=0, \ peak_max_dist=10, \ half_cbox=inputs.cbox_size_star//2, \ peak_threshold=5.): ''' Calculates the plausible stellar positions in the image. From the input 'positions', which contains the star's catalog positions in image XY coordinate, this function calculates the fitted star position. It crops the image centered at the catalog center +- cbox_size. Then do the 'find_peak', and rejects the image if the farthest peak distance is larger than peak_max_dist. This may mean that there are more than two stars in the field. ''' output = np.zeros_like(pos_star) for i in range(0, len(pos_star)): x_star = pos_star[i,0].copy().astype(int) y_star = pos_star[i,1].copy().astype(int) image_cbox = image_reduc[y_star-half_cbox:y_star+half_cbox,\ x_star-half_cbox:x_star+half_cbox].copy() mean, med, std = sigma_clipped_stats(image_cbox, sigma=3.0, iters=10) image_cbox -= med # primitive sky subtraction threshold = peak_threshold * std peaks = find_peaks(image_cbox, threshold=threshold) if len(peaks) == 0: output[i, :] = -1, -1 continue pos_peak = np.zeros((len(peaks),2)) if len(peaks) > 1: for j in range(0, len(peaks)): pos_peak[j, 0] = peaks[j]['x_peak'] pos_peak[j, 1] = peaks[j]['y_peak'] dist = cdist(pos_peak, pos_peak) if dist.max() > peak_max_dist: output[i, :] = -1, -1 continue # plt.imshow(image_cbox, origin='lower') # #x_star = pos_star[i,0].astype(int) #y_star = pos_star[i,1].astype(int) #image_cbox = image_reduc[y_star-inputs.cbox_size_star//2:y_star+inputs.cbox_size_star//2,\ # x_star-inputs.cbox_size_star//2:x_star+inputs.cbox_size_star//2] #plt.imshow(image_cbox, origin='lower') #plt.plot(np.mean(pos_peak[:,0]), np.mean(pos_peak[:,1]), '*') #fitted_x, fitted_y = centroid_2dg(image_cbox) #plt.plot(fitted_x, fitted_y, 'X') # # # #mean, med, std = sigma_clipped_stats(image_cbox, sigma=3.0, iters=10) #threshold = med + (5 * std) #peaks = find_peaks(image_cbox, threshold=threshold) #fitted_x, fitted_y = centroid_2dg(image_cbox) #fitted_x + pos_star[i,0] - cbox_size #fitted_y + pos_star[i,1] - cbox_size # from photutils import centroid_com, centroid_1dg, centroid_2dg # plt.imshow(image_cbox) # x1, y1 = centroid_com(image_cbox) # x2, y2 = centroid_2dg(image_cbox) # x3, y3 = centroid_1dg(image_cbox) # plt.plot(x1, y1, markersize=15, marker='*', color='blue') # plt.plot(x2, y2, markersize=15, marker='*', color='red') # plt.plot(x3, y3, markersize=15, marker='*', color='white') # I would conclude that 2dg gives more appropriate centers in most cases! mask_lo = image_cbox < -3*std mask_hi = image_cbox > peaks['peak_value'].max() # change pixels outside the above range to median (i.e., 0) image_cbox[np.logical_or(mask_lo, mask_hi)] = 0 fitted_x, fitted_y = centroid_2dg(image_cbox) output[i, 0] = fitted_x + pos_star[i,0] - half_cbox output[i, 1] = fitted_y + pos_star[i,1] - half_cbox # plt.imshow(image_cbox) # plt.colorbar() # plt.plot(fitted_x, fitted_y, '*') # plt.show() # plt.cla() # print('{0} {1:5.2f} {2:5.2f}'.format(i, fitted_x, fitted_y)) return output
def get_center(img): """ Return the center x,y coordinate of a reference star in an image using gaussian centering.""" x, y = centroid_2dg(img) return (x,y)
) #处理逐行数据:strip表示把头尾的'\n'去掉,split表示以空格来分割行数据,然后把处理后的行数据返回到list列表中 # print(list) A[A_row:] = list[0:accd] #把处理后的数据放到方阵A中。list[0:3]表示列表的0,1,2列数据放到矩阵A中的A_row行 A_row += 1 #然后方阵A的下一行接着读 #print(line) #print(A[0]) #打印 方阵A里的数据 # for i in range(1,101): # for j in range(1,accd+1): # B[j-1]=A[(i-1)*accd+j-1] # print(B[j-1]) data = A x1, y1 = centroid_com(data) x2, y2 = centroid_1dg(data) x3, y3 = centroid_2dg(data) # print(data) # print(x1,y1,x2,y2,x3,y3) # mean, median, std = sigma_clipped_stats(data, sigma=3.0, iters=5) # data -= median # subtract background cat = data_properties(data) # print (cat) #列输出 columns = [ 'id', 'xcentroid', 'ycentroid', 'semimajor_axis_sigma', 'semiminor_axis_sigma', 'orientation', 'cxx', 'cyy', 'cxy', 'eccentricity' ] tbl = cat.to_table(columns=columns) tbl['cxy'].info.format = '.10f' eccef = float(tbl['eccentricity'])
def recenter(image, pos, window_size=5, method="1dg"): """ Recenter each star in each frame of the image cube before performing aperture photometry to take care of slight misalignments between frames because of atmospheric turbulence and tracking/pointing errors. Parameters ---------- image : numpy array 2D image pos : list List of (x,y) tuples for star positions window_size : int Window size in which to fit the gaussian to the star to calculate new center method : string Method used to find center of the star. Options are 1d Gaussian fit, 2d gaussian fit or com (center of mass) Returns ------- xcen, ycen : float Source x and y centers """ pos = np.asarray(pos) ny, nx = image.shape window_size = int(window_size) nstars = pos.shape[0] star_pos = np.zeros([nstars, 2], dtype=np.float32) for i in range(nstars): x, y = pos[i][0], pos[i][1] xmin, xmax = int(x) - int(window_size / 2), int(x) + int( window_size / 2) + 1 ymin, ymax = int(y) - int(window_size / 2), int(y) + int( window_size / 2) + 1 if xmin < 0: xmin = 0 if ymin < 0: ymin = 0 if xmax > nx: xmax = nx if ymax > ny: ymax = ny if method == "1dg": xcen, ycen = centroid_1dg(image[ymin:ymax, xmin:xmax]) elif method == "2dg": xcen, ycen = centroid_2dg(image[ymin:ymax, xmin:xmax]) elif method == "com": xcen, ycen = centroid_com(image[ymin:ymax, xmin:xmax]) if (np.abs(xmin + xcen - x)) > 3. or (np.abs(ymin + ycen - y)) > 3.: star_pos[i, 0] = x star_pos[i, 1] = y else: star_pos[i, 0] = xmin + xcen star_pos[i, 1] = ymin + ycen return star_pos