def center_of_flux(LF, x, y, R): """This function finds the center of flux for all desired stellar object""" # Packages: from numpy import zeros, max, sum, round, meshgrid, argmax # Extract data: r, r_max = R[0], R[2] x, y = x.astype(int), y.astype(int) # Outer: loops over all stars: center_x = zeros(len(x)) center_y = zeros(len(y)) for i in range(len(x)): x_grid, y_grid = meshgrid(range(x[i]-r_max,x[i]+r_max), range(y[i]-r_max,y[i]+r_max)) square = LF[y_grid, x_grid] # Square frame of each image # Test: FITS(square,'linear'); plt.plot(x_grid-x[i]+r_max, y_grid-y[i]+r_max, 'b*'); plt.show() # Inner: loops over all pixels: for j in range(2*r): x_max_i = max(square) # Row and value of max pixel pixel_i = square.index(x_max_i) # Index of max value pixel _, y_max_i = max(square[x_max_i, :]) # Column for max pixel x_max[j] = x_max_i # Rows gathers in a list y_max[j] = y_max_i # Columns gathers in a list pixel[j] = pixel_i # Max pixels gathers in a list square[x_max_i, y_max_i] = 0 # Max pixel is set to zero to find the nextr # Flux center is found: flux = sum(pixel) # Total flux from pixels center_x = 1/flux*dot(pixel,x_max) # Flux-center in x center_y = 1/flux*dot(pixel,y_max) # Flux-center in y # Center of fluc for all stars: cen = [center_x-r, center_y-r] return cen
def aperture(LF, x, y, R, plot): """------------------------------------------- FUNCTION ------------------------------------------------: This function find stellar flux with a circular aperture. ----------INPUT: LF : Light Frame (LF) x, y : Stellar coordinate R : [r, r_min, r_max]: aperture, inner and outer radius for background plot : Plot if you like. ----------------------------------------------------------------------------- aperture """ # Packages: from numpy import meshgrid, ogrid, sqrt, mean, median, argmax, sum, cos, sin, nonzero # Split varibles: r, r_min, r_max = R[0], R[1], R[2] x, y = int(x), int(y) # Make meshgrid maks: x_grid, y_grid = meshgrid(range(x - r_max, x + r_max), range(y - r_max, y + r_max)) square = LF[y_grid, x_grid] # Square frame of each image c = sqrt((x_grid - x)**2 + (y_grid - y)**2) # Equation of a circle # Background: c_sky = ((c >= r_min) * (c <= r_max)) * square # r_max^2 dimensional array sky_mean = mean(c_sky[nonzero(c_sky)]) # Mean sky flux sky_medi = median(c_sky[nonzero(c_sky)]) # Median sky flux flux_sky = 3 * sky_medi - 2 * sky_mean # Sky flux # Star: c_star = (c <= r) * square star = c_star[nonzero(c_star)] - flux_sky # Stellar corrected pixels n_pix_star = sum(c <= r) # Number of used star pixels flux_star = sum(star) # Flux from star # Plot zoom-in on star with aperture: if plot == 3: FITS(square, 'linear') t = linspace(0, 2 * pi) x_off = (2 * r_max + 1) / 2 y_off = (2 * r_max + 1) / 2 plt.plot(x_off, y_off, '+r') plt.plot(r * cos(t) + x_off, r * sin(t) + y_off, 'g-') plt.plot(r_min * cos(t) + x_off, r_min * sin(t) + y_off, 'b-') plt.plot(r_max * cos(t) + x_off, r_max * sin(t) + y_off, 'b-') plt.show() # Shows only figure ones in loop sys.exit() return flux_sky, n_pix_star, flux_star
def image_reduction(path, LF_name, FF_name=None, DF_name=None, BF_name=None, plot=None, save=None): """ This function takes all loaded flat-frames, dark-frames, bias-frames and combine them to one master-flat-field image. ----------INPUT: imagetype : Format of images (fits, jpg etc.). LF_name : Name of Light Frames (LF) except end number. FF_name : Name of Flat Frames (FF) except end number. DF_name : Name of Dark Frames (DF) except end number. BF_name : Name of Bias Frames (BF) except end number. N : Number of [LF, FF, DF, BF] frames. plot : If plot=1: plots all relevant frames.. save : If save=1: saves all corrected light frames in seperate files. ---------OUTPUT: CF_i : Corrected Frames (CF).""" start_time = time.time() # Take time #--------------------- # Load data available: #--------------------- print('1/3 (%.3f s): Load correction frames' %(time.time()-start_time)) LF_files = np.sort(glob.glob('{}{}*'.format(path, LF_name))) if FF_name is not None: # Flats FF_files = np.sort(glob.glob('{}{}*'.format(path, FF_name))) FF_i = np.array([fits.getdata(str(files)) for files in FF_files]) if DF_name is not None: # Darks DF_files = np.sort(glob.glob('{}{}*'.format(path, DF_name))) DF_i = np.array([fits.getdata(str(files)) for files in DF_files]) if BF_name is not None: # Bias' BF_files = np.sort(glob.glob('{}{}*'.format(path, BF_name))) BF_i = np.array([fits.getdata(str(files)) for files in BF_files]) #-------------------- # Use data available: #-------------------- print('2/3 (%.3f s): Making master correction frames' %(time.time()-start_time)) # Bias, Darks, and Flats: if all(x is not None for x in [FF_name, DF_name, BF_name]): # Make master bias: BF = np.median(BF_i, axis=0) # Make master dark: hdulist0 = fits.open('{}'.format(str(LF_files[0]))) hdulist1 = fits.open('{}'.format(str(DF_files[0]))) t_exp_LF = hdulist0[0].header['EXPTIME'] # Exposure time (CHANGE NAME IF NEEDED!) t_exp_DF = hdulist1[0].header['EXPTIME'] # Exposure time (CHANGE NAME IF NEEDED!) DF = (t_exp_LF/t_exp_LF) * np.median(DF_i - BF, axis=0) DF[DF<=0] = np.median(np.median(DF, axis=1)) # Avoid negative flux # Make master flat: FF = np.median(FF_i - BF - DF, axis=0) FF = FF/np.max(FF) FF[FF<=0] = np.median(np.median(FF, axis=1)) # Avoid negative flux # Darks and Flats: if all(x is not None for x in [DF_name, FF_name]) and BF_name is None: # Make master dark: hdulist0 = fits.open('{}'.format(str(LF_files[0]))) hdulist1 = fits.open('{}'.format(str(DF_files[0]))) t_exp_LF = hdulist0[0].header['EXPTIME'] # Exposure time (CHANGE NAME IF NEEDED!) t_exp_DF = hdulist1[0].header['EXPTIME'] # Exposure time (CHANGE NAME IF NEEDED!) DF = (t_exp_LF/t_exp_LF) * np.median(DF_i, axis=0) DF[DF<0] = 0 # Avoid negative flux # Make master flat: FF = np.median(FF_i - DF, axis=0) FF = FF/np.max(FF) # Bias and Flats: if all(x is not None for x in [BF_name, FF_name]) and DF_name is None: # Make master bias: BF = np.median(BF_i, axis=0) # Make master flat: FF = np.median(FF_i - BF, axis=0) FF = FF/np.max(FF) FF[FF<0] = 0 # Bias: if BF_name is not None and DF_name is None and FF_name is None: BF = np.median(BF_i, axis=0) # Darks: if DF_name is not None and BF_name is None and FF_name is None: DF = np.median(DF_i, axis=0) # Flats: if FF_name is not None and BF_name is None and DF_name is None: FF = np.median(FF_i, axis=0) print '----------------------------------------' print 'Bias -- std: {:.7}, mean: {:.7}'.format(np.std(BF), np.mean(BF)) print 'Dark -- std: {:.7}, mean: {:.7}'.format(np.std(DF), np.mean(DF)) print 'Flat -- std: {:.7}, mean: {:.7}'.format(np.std(FF), np.mean(FF)) print '----------------------------------------' #------------------------ # Correct science frames: #------------------------ print('3/3 (%.3f s): Performs image correction on science frames and save images' \ %(time.time()-start_time)) # Construct 3D cube of light-frames and flat-frames with dim(number, x-dim, y-dim): for i in range(len(LF_files)): LF_i = fits.getdata(str(LF_files[i])) #plt.imshow(LF_i, vmin=200, vmax=10000); plt.show(); sys.exit() if all(x is not None for x in [FF_name, DF_name, BF_name]): LF = (LF_i - BF - DF)/FF if all(x is not None for x in [DF_name, FF_name]) and BF_name is None: LF = (LF_i - DF)/FF if all(x is not None for x in [BF_name, FF_name]) and DF_name is None: LF = (LF_i - BF)/FF if BF_name is not None and DF_name is None and FF_name is None: LF = LF_i - BF if DF_name is not None and BF_name is None and FF_name is None: LF = LF_i - DF if FF_name is not None and BF_name is None and DF_name is None: LF = LF_i/FF # Save: if save==1: fits.writeto(('{}{}_reduce_%03d.fits'.format(path, LF_name) %i), LF) # Take time: print('Filter done in time: %.5f s' %(time.time() - start_time)) # Plot: if plot==1: if FF_name!=None: FITS(FF, 'linear', 5); plt.show() if DF_name!=None: FITS(DF, 'linear'); plt.show() if BF_name!=None: FITS(BF, 'linear', 5); plt.show() FITS(LF_i[0], 'linear', 2); plt.show() FITS(LF[0], 'linear', 2); plt.show() return
def aperture_photometry(path, LF_name, coor_name, coor_target, R, dm_int=None, plot=None, save=None): #start_time = time.time() #from Photometry import aperture, SNR, center_of_flux #--- DATA ---# LF_files0 = np.sort(glob.glob('{}{}*'.format(path, LF_name[0]))) LF_files1 = np.sort(glob.glob('{}{}*'.format(path, LF_name[1]))) LF0 = fits.getdata(str(LF_files0[0])) LF1 = fits.getdata(str(LF_files1[0])) coor_stars = loadtxt('{}{}.txt'.format(path, coor_name)) x, y = coor_stars[:,1], coor_stars[:,0] # Stellar coordinates xs, ys = coor_target[0], coor_target[1] # Target coordinates n = len(LF_files1) # Number of images #--- CONSTANTS ---# gain = 0.73 # Gain of camera: electrons pr ADU (ADU = counts from object)- ajust to camera! ron = 3.3 # Read out noise - ajust to camera! con = 25 # Magnitude constant r = R[0] # Aperture radius = R[1] # Minimum aperture radius to measure sky flux r_max = R[2] # Maximum aperture radius to measure sky flux N = len(x) # Number of stars (start) h, w = shape(LF1) # Image dimentions (height, width) #--- STELLAR COORDINATES ---# # Make target star the first star: d = zeros(N) for i in range(N): d[i] = sqrt((xs-x[i])**2+(ys-y[i])**2) # Simple pythagorean geometry index_min = argmin(d) # Find target star by geometry x = roll(x, -index_min) # Shift data to target star index y = roll(y, -index_min) # Check if stellar coordinates are closer than r_max: i_x1 = where(x<r_max)[0]; i_x2 = where(x>w-r_max)[0] i_y1 = where(y<r_max)[0]; i_y2 = where(y>h-r_max)[0] i_xy = hstack([i_x1, i_x2, i_y1, i_y2]) # Discard these coordinates: X = delete(x, i_xy) Y = delete(y, i_xy) N = len(X) # New number of stars # Plot if you like: if plot==2: FITS(LF1,'linear'); plt.plot(x,y,'ro',mfc='none'); plt.plot(x[0],y[0],'b+');\ plt.plot(x[i_xy], y[i_xy],'y*'); plt.show() #--- FIND OPTIMAL APERTURE RADIUS ---# if plot==3: SNR_r = optimal_aperture(LF1, X[0], Y[0], R, gain, ron, plot) #--- PHOTOMETRY ---# # Find fluxes: flux_star = zeros((n,N)) SNR_i = zeros((n,N)) time = zeros(n) for i in range(n): # Loop over all images: hdulist = fits.open(str(LF_files0[i])) time[i] = Time(hdulist[0].header['DATE'], scale='utc').jd # Scaling to utc time and Julian Date LF = fits.getdata(str(LF_files1[i])) for j in range(N): # Loop over all stars and find flux (using same radius): flux_sky, n_pix_star, flux_star[i][j] = aperture(LF, X[j], Y[j], R, plot) SNR_i[i][j] = SNR(flux_sky, n_pix_star, flux_star[i][j], gain, ron) #--- SEEING CORRECTION ---#: mag_star = -2.5*log10(flux_star[:,0])+con # From flux to magnitude for target star mag_ref = -2.5*log10(flux_star[:,range(1,N)])+con # From flux to magnitude for reference stars # Find all delta-mag (dm): #print mag_star; sys.exit() dm = zeros((n,N-1)) for i in range(n): dm[i] = mag_ref[0,:]-mag_ref[i,:] # dm from 0th frame to every other # Make trumpet plot: dm_med = median(dm,axis=0) # Using all stars: mag_all = mag_star + median(dm, axis=1) # Using all stars # Which stars should be used to correct with: if dm_int==None: dm_int = [-0.01, 0.01, 3, 10] # Using interval: im_x = where((mag_ref[0,:]>dm_int[0])*(mag_ref[0,:]<dm_int[1]))[0] im_y = where((dm_med>dm_int[2])*(dm_med<dm_int[3]))[0] im_xy = list(set(im_x).intersection(im_y)) mag_int = mag_star + median(dm[:,im_xy], axis=1) # Plot results: if plot==1 or plot==2: plot_trumpet(mag_ref, dm_med, dm_int, im_xy, '$m_i$', '$m_0\, -\, m_i$', 'Trumpet - Seeing Corretion') plt.show() MAG(time, [mag_star, mag_all, mag_int], ['.', 'r.', 'g*'], '$t$ (hours) - UTC JD', '$m$') plt.show() return
def star_finder(path, LF_name, sigma=2, plot=None, save=None): """ This function finds all stellar object that is more lumious than TOL. ----------INPUT: path : Directory path to data N : Number of frames LF_name : Filename of Light Frame (LF) method : Method to be used: Centroids='cen', PSF='psf' sigma : Number of standard deviations used for flux criterion plot : Plot==1 display found stars save : save==1 saves a corrdinates [x, y] ---------OUTPUT: x_cen, y_cen : x and y coordinates of found stars. """ # Packages: import time, sys, glob import numpy as np from astropy.io import fits import scipy.ndimage as snd import matplotlib.pyplot as plt from Plot_Tools import FITS #----------- # Load data: #----------- LF_files = np.sort(glob.glob('{}{}*'.format(path, LF_name))) LF0 = fits.getdata(str(LF_files[0])) h, w = np.shape(LF0) # Heigh and width n = len(LF_files) # Number of images # Use same number of stars in all frames from statistic: threshold = mean(LF0) + sigma*std(LF0) labels, m = snd.label(LF0>threshold, ones((3,3))) print 'Using %i stars to shift images' %m #------------------ # Align image data: #------------------ LF_align = np.zeros((n, h, w)) for i in range(n): LF_i = fits.getdata(str(LF_files[i])) cen = snd.center_of_mass(LF_i, labels, range(m)) x_cen_i = np.array(cen)[:,0] y_cen_i = np.array(cen)[:,1] if i==0: # Initial mean values: x_ini = np.median(x_cen_i, axis=0) y_ini = np.median(y_cen_i, axis=0) # Frames are shifted using and interpolation of the frames: x_shift = np.median(x_cen_i, axis=0) y_shift = np.median(y_cen_i, axis=0) x_diff = np.diff([x_ini, x_shift]) y_diff = np.diff([y_ini, y_shift]) LF_align[i] = snd.interpolation.shift(LF_i, [x_diff, y_diff]) # Save images if you like: if save==1: fits.writeto(('{}{}_align_%03d.fits'.format(path, LF_name) %i), LF_align[i], overwrite=True) #------------- # Coordinates: #------------- LF = np.median(LF_align, axis=0) cen = snd.center_of_mass(LF, labels, range(m)) x_cen = np.array(cen)[:,0] y_cen = np.array(cen)[:,1] if plot==1: FITS(LF, 'linear', 2); plt.plot(y_cen, x_cen, 'r+'); plt.show() if save==1: np.savetxt('{}{}'.format(path, 'star_coor.txt'), np.vstack([x_cen, y_cen]).T)
def aperture_photometry(self, coor_name, coor_target, R, dm_int=None, plot=None, save=None): """------------------------------------------- MAIN FUNCTION -------------------------------------- This function ----------INPUT: images : ---------OUTPUT: master_flat : """ print '--------------------------------------------------------------------- aperture_photometry' #start_time = time.time() from Photometry import aperture, SNR, center_of_flux #--- CONSTANTS ---# gain = 0.73 # Gain of camera: electrons pr ADU (ADU = counts from object)- ajust to camera! ron = 3.3 # Read out noise - ajust to camera! con = 25 # Magnitude constant r = R[ 0] # Aperture radius = R[1] # Minimum aperture radius to measure sky flux rmin = R[1] rmax = R[2] # Maximum aperture radius to measure sky flux #--- STELLAR COORDINATES ---# # Load stellar coordinates: if type(coor_name) == str: coor_stars = np.loadtxt('{}{}.txt'.format(self.path, coor_name)) if type(coor_name) == list: coor_stars = coor_stars else: print('ERROR: STELLAR COORDINATES HAS A WRONG FORMAT') x, y = coor_stars[:, 1], coor_stars[:, 0] # Stellar coordinates xt, yt = coor_target[0], coor_target[1] # Target coordinates N = len(x) # Number of stars used # Make target star the first star: d = np.zeros(N) for i in range(N): d[i] = np.sqrt( (xt - x[i])**2 + (yt - y[i])**2) # Simple pythagorean geometry index_min = np.argmin(d) # Find target star by geometry x = np.roll(x, -index_min) # Shift data to target star index y = np.roll(y, -index_min) # Check if stellar coordinates are closer than r_max: i_x1 = np.where(x < rmax)[0] i_x2 = np.where(x > self.w - rmax)[0] i_y1 = np.where(y < rmax)[0] i_y2 = np.where(y > self.h - rmax)[0] i_xy = np.hstack([i_x1, i_x2, i_y1, i_y2]) # Discard these coordinates: X = np.delete(x, i_xy) Y = np.delete(y, i_xy) N = len(X) # New number of stars # Check coordinates if you like: if plot == 2: LF = pyfits.getdata(str(self.LF_files[0])) fig, ax = plt.subplots(1, 1) FITS(LF, 'linear') plt.plot(x, y, 'ro', mfc='none') plt.plot(x[0], y[0], 'b+') plt.plot(x[i_xy], y[i_xy], 'y*') plot_settings(fig, ax) plt.show() #--- FIND OPTIMAL APERTURE RADIUS ---# if plot == 3: LF = pyfits.getdata(str(self.LF_files[0])) SNR_r = optimal_aperture(LF, X[0], Y[0], R, gain, ron, plot) #--- PHOTOMETRY ---# # Find fluxes: flux_star = np.zeros((n, N)) SNR_i = np.zeros((n, N)) time = np.zeros(n) for i in range(n): # Loop over all images: hdulist = fits.open('{}{}_%03d.fits'.format(path, LF_name) % i) LF = fits.getdata('{}{}_%03d.fits'.format(path, LF_name) % i) time[i] = Time( hdulist[0].header['date'], scale='utc').jd # Scaling to utc time and Julian Date for j in range( N ): # Loop over all stars and find flux (using same radius): flux_sky, n_pix_star, flux_star[i][j] = aperture( LF, X[j], Y[j], R, plot) SNR_i[i][j] = SNR(flux_sky, n_pix_star, flux_star[i][j], gain, ron) #--- SEEING CORRECTION ---#: mag_star = -2.5 * log10( flux_star[:, 0]) + con # From flux to magnitude for target star mag_ref = -2.5 * log10(flux_star[:, range( 1, N)]) + con # From flux to magnitude for reference stars # Find all delta-mag (dm): dm = zeros((n, N - 1)) for i in range(n): dm[i] = mag_ref[0, :] - mag_ref[ i, :] # dm from 0th frame to every other # Make trumpet plot: dm_med = median(dm, axis=0) # Using all stars: mag_all = mag_star + median(dm, axis=1) # Using all stars # Which stars should be used to correct with: if dm_int == None: dm_int = [-0.01, 0.01, 3, 10] # Using interval: im_x = where( (mag_ref[0, :] > dm_int[0]) * (mag_ref[0, :] < dm_int[1]))[0] im_y = where((dm_med > dm_int[2]) * (dm_med < dm_int[3]))[0] im_xy = list(set(im_x).intersection(im_y)) mag_int = mag_star + median(dm[:, im_xy], axis=1) # Plot trumpet: if plot == 1 or plot == 2: plot_trumpet(mag_ref, dm_med, dm_int, im_xy, '$m_i$', '$m_0\, -\, m_i$', \ 'Trumpet - Seeing Corretion') plt.show() MAG(time, [mag_star, mag_all, mag_int], ['.', 'r.', 'g*'], '$t$ (days) - UTC JD', '$m$') plt.show() return
def aperture(self, LF, x, y, aperture, background): """ This function calculate the stellar and sky background flux either using a highly elliptical aperture or a aperture that traces the the Center Of Flux (COF) to fit the startrails. The routine returns stellar flux 'flux_star', the sky background flux 'flux_sky', and the number of stellar pixels 'n_pix_star'. """ # Aperture only handle integers: x, y = int(x), int(y) # Grid for aperture: x_grid, y_grid = meshgrid(range(self.w), range(self.h)) grid = LF[y_grid, x_grid] # Grid xx = x_grid - x # Displacement for stellar x coor yy = y_grid - y # Displacement for stellar y coor # The aperture: a = aperture[1] # Star radius/semi-minor axis b = aperture[2] # Star semi-major axis (circle if a = b) r_min = aperture[3] # min radius r_max = aperture[4] # phi = math.radians(aperture[5]) # Tilt angle: [0:180] deg # Global background: if background == 'global': flux_sky = self.global_sky_background(LF) #--- CIRCULAR OR ELLIPTIC APERTURE ---# if aperture[0] == 'ellipse': # Parametrasation and rotation of the ellipse (1 = x^2/a^2 + y^2/b^2) phi = phi - pi / 2 # The ellipse have an offset from unity circle EE_star = (xx * cos(phi) + yy * sin(phi))**2 / a**2 + ( xx * sin(phi) - yy * cos(phi))**2 / b**2 EE_sky_min = (xx * cos(phi) + yy * sin(phi))**2 / ( a + r_min)**2 + (xx * sin(phi) - yy * cos(phi))**2 / (b + r_min)**2 EE_sky_max = (xx * cos(phi) + yy * sin(phi))**2 / ( a + r_max)**2 + (xx * sin(phi) - yy * cos(phi))**2 / (b + r_max)**2 # Local background: if background == 'local': sky_grid = ((EE_sky_min > 1) * (EE_sky_max < 1) ) * grid # Sky background determined by width q sky_pixs = sky_grid[nonzero(sky_grid)] # Sky pixel values flux_sky = 3 * median(sky_pixs) - 2 * mean( sky_pixs) # Robust sky background flux # Star: star_grid = (EE_star <= 1) * grid star_pixs = star_grid[nonzero( star_grid)] - flux_sky # Stellar corrected pixels n_pix_star = sum(EE_star <= 1) # Number of used star pixels flux_star = sum(star_pixs) # Flux from star #--- TRACE APERTURE ---# if aperture[0] == 'trace': # Star initial: CC_star = sqrt(xx**2 + yy**2) - a # Start frame used to trace from: star_grid = (CC_star <= 1) * grid # Star images star_pixs = star_grid[nonzero(star_grid)] # Stellar pixels n_pix_star = len(star_pixs) # Number of pixels in circle # Loop-step in x or y depends on phi: # Step in x and finds y centroid for each step: if 0 <= phi <= pi / 4 or pi * 3 / 4 <= phi <= pi: step = 'x step' x_step = range(b) y_step = zeros(b) # Step in y and finds x centroid for each step: if pi / 4 < phi < pi * 3 / 4: step = 'y step' x_step = zeros(b) y_step = range(b) # Loop over trace step: x_cen = zeros(b) y_cen = zeros(b) star_true = zeros((b, self.h, self.w)) sky_true = zeros((b, self.h, self.w)) for i in range(b): # Find Center Of Flux (COF): y_cen[i], x_cen[i] = self.center_of_flux(star_img, n_pix_star) if step == 'x step': XX = x + x_step[i] YY = y_cen[i] + y_step[i] if step == 'y step': YY = y + y_step[i] XX = x_cen[i] + x_step[i] # A circular aperture is used to trace with: CC_star = sqrt((x_grid - XX)**2 + (y_grid - YY)**2) - a star_true[i] = (CC_star <= 1 ) # Array of true and false statement: star star_img = star_true[i] * grid # Image: star n_pix_star = len( star_img[nonzero(star_img)]) # Number of pixels: star # If local background: if background == 'local': CC_sky = sqrt((x_grid - XX)**2 + (y_grid - YY)**2) - a_sky sky_true[i] = ( (CC_star > 1) * (CC_sky < 1) ) * grid # Array of true and false statement: sky # Local sky flux: if background == 'local': star_false = np.logical_not(np.sum( star_true, axis=0)) # Invert to get rid of star sky_true_x = np.sum(sky_true, axis=0) > 0 sky_img = sky_true_x.astype( np.int) * star_false * LF # Here bol: True*False = False sky = sky_img[nonzero(sky_img)] flux_sky = 3 * median(sky) - 2 * mean(sky) # Robust sky flux # Stellar flux: star_true_x = np.sum(star_true, axis=0) > 0 # Bool array of stellar pixels star_img = star_true_x.astype(np.int) * LF # Stellar image star = star_img[nonzero( star_img)] - flux_sky # Stellar corrected pixels n_star_pix = len(star) flux_star = sum(star_img) # PLOT IF YOU LIKE: if self.plot == 1: # Elliptic aperture with local background: if aperture[0] == 'ellipse': from plot_tools import plot_ellipse FITS(LF, 'linear', 2) plot_ellipse(a, b, math.degrees(phi), x, y, 'g') # Stellar aperture plot_ellipse(a_sky, b_sky, math.degrees(phi), x, y, 'm') # Background aperture plt.show() # Box aperture with local background: if aperture[0] == 'trace': t = linspace(0, 2 * pi) FITS(LF, 'linear', 2) [ plt.plot(a_sky * cos(t) + (x + x_step[i]), a_sky * sin(t) + y_cen[i], 'b-') for i in range(b) ] [ plt.plot(a * cos(t) + (x + x_step[i]), a * sin(t) + y_cen[i], 'g-') for i in range(b) ] plt.show() return flux_sky, n_pix_star, flux_star