def centroid(self, frame): x = int(self.x[frame]) y = int(self.y[frame]) gaussian = fit_2dgaussian(frame.imdata[y-w:y+w, x-w:x+w]) x += gaussian.x_mean.value - w y += gaussian.y_mean.value - w return x, y
def fiduciali(self, image, point_to_use): ''' Parameters ---------- ima: numpy array image from which to derive the location of the fiducial points point_to_use: int number of fiducial points to use (1 or 5) Returns ------- par_list: numpy array [number of points,2] list of x, y coord ''' ima = np.copy(image) par_ima_list = [] for i in range(point_to_use): ima_cut, y_min, x_min = self._imaCutter(ima, self._pixelCut) par_cut = fit_2dgaussian(ima_cut)._parameters par_ima = np.copy(par_cut) par_ima[2] = np.int(par_cut[2] + x_min) par_ima[3] = np.int(par_cut[3] + y_min) coord = np.array([par_cut[2] + x_min, par_cut[3] + y_min]) ima[par_ima[3].astype(int) - self._pixelCut:par_ima[3].astype(int) + self._pixelCut, par_ima[2].astype(int) - self._pixelCut:par_ima[2].astype(int) + self._pixelCut] = 0 par_ima_list.append(coord) return np.array(par_ima_list)
def FWHM(self, frame): x = int(self.x[frame]) y = int(self.y[frame]) gaussian = fit_2dgaussian(frame.imdata[y-w:y+w, x-w:x+w]) r = 2 * np.sqrt(gaussian.x_stddev + gaussian.y_stddev )*( np.sqrt(2*np.log(2)) ) return r
def fine_center(data,positions,box_size=10): positions=positions.astype(int) fine_positions=[];fine_fwmh=[];fine_snr=[] for i in range(len(positions)): data_find=data[(positions[i][1]-box_size):(positions[i][1]+box_size),(positions[i][0]-box_size):(positions[i][0]+box_size)] try: print('Star_%u is fitting...'%(i+1)) gaussian_fit=fit_2dgaussian(data_find) except: print('ERROR:fine_center') return [-1],[-1],[-1] fine_positions.append(np.array([gaussian_fit.x_mean.value,gaussian_fit.y_mean.value])) fine_fwmh.append(np.max([gaussian_fit.x_stddev.value,gaussian_fit.y_stddev.value])*2) fine_snr.append(gaussian_fit.amplitude/gaussian_fit.constant) return np.array(fine_positions)+positions-box_size,np.array(fine_fwmh),np.array(fine_snr)
def __init__( self, parent, x, y, isVar, mag=None, r=None, d_d=None, d_a=None, name=None ): parent.make_current() cls = type(self) if hasattr(cls, 'n'): cls.n += 1 else: cls.n = 1 if name is not None: self.name = name else: self.name = 'Star_' + str(cls.n) self.mag = mag self.isVar = isVar if(self.isVar): self.varMag = dict() self.apertures = dict() self.annuli = dict() self.x = dict() self.y = dict() if r is None: gaussian = fit_2dgaussian(parent.imdata[y-w:y+w, x-w:x+w]) x += gaussian.x_mean.value - w y += gaussian.y_mean.value - w r = 2 * np.sqrt( gaussian.x_stddev + gaussian.y_stddev )*( np.sqrt(2*np.log(2)) ) if d_d is None: d_d = r if d_a is None: d_a = r R = r + d_d self.apertures[parent] = CircularAperture([x, y], r) self.annuli[parent] = CircularAnnulus([x, y], R, R+d_a) self.r = r self.d_d = d_d self.d_a = d_a self.x[parent] = x self.y[parent] = y print("Created star", self, "in frame", parent)
def updateCoords(self, frame, x, y, gauss=False): x = int(x) y = int(y) if gauss: try: # plt.figure() # plt.imshow(frame.imdata[y-2*w:y+2*w, x-2*w:x+2*w], cmap='gray') # plt.title('Gaussian fitting space') # plt.show() gaussian = fit_2dgaussian(frame.imdata[y-w:y+w, x-w:x+w]) x += gaussian.x_mean.value - w y += gaussian.y_mean.value - w except ValueError: print( '({}, {}: [{}:{}, {}:{}]'.format( self.x[frame], self.y[frame], y-w, y+w, x-w, x+w ) ) self.apertures[frame] = CircularAperture([x, y], self.r) self.annuli[frame] = CircularAnnulus( [x, y], self.r+self.d_d, self.r+self.d_d+self.d_a ) self.x[frame] = x self.y[frame] = y
def dataquality(cubeslist, maskslist): """ Perform bunch of QA checks to asses the final data quality of reduction """ import os import numpy as np from astropy.io import fits from mypython.fits import pyregmask as msk from mypython.ifu import muse_utils as mutil from mypython.ifu import muse_source as msrc from matplotlib.backends.backend_pdf import PdfPages import matplotlib.pyplot as plt import matplotlib.cm as cm from astropy.stats import sigma_clipped_stats try: from photutils import CircularAperture, aperture_photometry,\ data_properties, properties_table, centroids except: print("To run checks need photutils package") return print("Perform QA checks...") #make QA folder if not os.path.exists('QA'): os.makedirs('QA') #cube names cname = "COMBINED_CUBE.fits" iname = "COMBINED_IMAGE.fits" #first identify bright sources in final white image catsrc = msrc.findsources(iname, cname, check=True, output='QA', nsig=5, minarea=20) #make rsdss images if not (os.path.isfile('QA/sdssr.fits')): mutil.cube2img(cname, write='QA/sdssr.fits', wrange=None, helio=0, filt=129) rsdssall = fits.open('QA/sdssr.fits') segmask = fits.open('QA/segmap.fits') whiteref = fits.open(iname) #select round and bright objects shapesrc = catsrc['a'] / catsrc['b'] roundsrc = catsrc[np.where((shapesrc < 1.1) & (catsrc['cflux'] > 50))] imgfield = fits.open(iname) rms = np.std(imgfield[0].data) #perform aperture photometry on rband image - data already skysub positions = [roundsrc['x'], roundsrc['y']] apertures = CircularAperture(positions, r=10.) phot_table = aperture_photometry(rsdssall[1].data, apertures) phot_table_white = aperture_photometry(whiteref[0].data, apertures) rmag = -2.5 * np.log10( phot_table['aperture_sum']) + rsdssall[0].header['ZPAB'] wmag = -2.5 * np.log10(phot_table_white['aperture_sum']) #find FWHM on rband image fwhm = np.zeros(len(rmag)) for ii in range(len(rmag)): subdata=rsdssall[1].data[roundsrc['y'][ii]-10:roundsrc['y'][ii]+10,\ roundsrc['x'][ii]-10:roundsrc['x'][ii]+10] tdfit = centroids.fit_2dgaussian(subdata, error=None, mask=None) fwhm[ii] = 2.3548 * 0.5 * (tdfit.x_stddev + tdfit.y_stddev ) * rsdssall[0].header['PC2_2'] * 3600. #find rms of cube - mask sources and add edge buffer maskwbuffer = np.copy(segmask[1].data) maskwbuffer[0:30, :] = 9999 maskwbuffer[-31:-1, :] = 9999 maskwbuffer[:, 0:30] = 9999 maskwbuffer[:, -31:-1] = 9999 cwrms, crms = mutil.cubestat(cname, mask=maskwbuffer) #open diagnostic output with PdfPages('QA/QAfile.pdf') as pdf: ########################### #display field with r mag # ########################### plt.figure(figsize=(10, 10)) plt.imshow(imgfield[0].data, origin='low', clim=[-0.5 * rms, 0.5 * rms], cmap='gray_r') #mark round soruces plt.scatter(roundsrc['x'], roundsrc['y'], color='red') for ii in range(len(rmag)): plt.text(roundsrc['x'][ii], roundsrc['y'][ii], " " + str(rmag[ii]), color='red') plt.title('Round sources with SDSS r mag') pdf.savefig() # saves the current figure into a pdf page plt.close() ########################### #display FWHM # ########################### plt.figure(figsize=(10, 10)) plt.scatter(rmag, fwhm, color='red') plt.xlabel('Source rmag') plt.ylabel('FWHM (arcsec)') plt.title('Median FWHM {}'.format(np.median(fwhm))) pdf.savefig() # saves the current figure into a pdf page plt.close() ########################### #check centroid # ########################### plt.figure(figsize=(10, 10)) #loop on exposures for tmpc in open(cubeslist, 'r'): thisob = tmpc.split('/')[1] thisexp = tmpc.split('_')[3] wname = '../{}/Proc/DATACUBE_FINAL_LINEWCS_{}_white2.fits'.format( thisob, thisexp) wfits = fits.open(wname) #now loop on sources delta_x = np.zeros(len(rmag)) delta_y = np.zeros(len(rmag)) for ii in range(len(rmag)): subdata=wfits[0].data[roundsrc['y'][ii]-10:roundsrc['y'][ii]+10,\ roundsrc['x'][ii]-10:roundsrc['x'][ii]+10] x1, y1 = centroids.centroid_2dg(subdata) delta_x[ii] = 10.5 - x1 delta_y[ii] = 10.5 - y1 #plot for this subunit plt.scatter(delta_x * rsdssall[0].header['PC2_2'] * 3600., delta_y * rsdssall[0].header['PC2_2'] * 3600.) plt.xlabel('Delta x (arcsec)') plt.ylabel('Delta y (arcsec)') plt.title('Check exposure aligment') pdf.savefig() # saves the current figure into a pdf page plt.close() ########################### #check fluxing # ########################### #make a check on fluxing plt.figure(figsize=(10, 10)) #loop on exposures for tmpc in open(cubeslist, 'r'): thisob = tmpc.split('/')[1] thisexp = tmpc.split('_')[3] wname = '../{}/Proc/DATACUBE_FINAL_LINEWCS_{}_white2.fits'.format( thisob, thisexp) wfits = fits.open(wname) phot_this_white = aperture_photometry(wfits[0].data, apertures) wmag_this = -2.5 * np.log10(phot_this_white['aperture_sum']) #plot for this subunit ii = np.argsort(rmag) dd = wmag - wmag_this plt.plot(rmag[ii], dd[ii], label=thisob + thisexp) plt.xlabel('SDSS R mag') plt.ylabel('Delta White Mag') plt.title('Check exposure photometry') plt.legend() pdf.savefig() # saves the current figure into a pdf page plt.close() #display rms stats + compute stats over cubes plt.figure(figsize=(10, 10)) plt.semilogy(cwrms, crms, label='Coadd') for tmpc in open(cubeslist, 'r'): cwrms_this, crms_this = mutil.cubestat(tmpc.strip(), mask=maskwbuffer) plt.semilogy(cwrms_this, crms_this, label=tmpc.split('/')[1] + tmpc.split('_')[3]) plt.xlabel('Wave (A)') plt.ylabel('RMS (SB units)') plt.legend() plt.title('RMS in cubex') pdf.savefig() # saves the current figure into a pdf page plt.close()
def _center_2dg_iteration(ccd, position_xy, cbox_size=5., csigma=3., max_shift_step=None, ssky=0, error=None, verbose=False): ''' Find the intensity-weighted centroid of the image iteratively Returns ------- position_xy : float The centroided location in the original image coordinate in image XY. shift : float The total distance between the initial guess and the fitted centroid, i.e., the distance between `(xc_img, yc_img)` and `position_xy`. ''' cut = Cutout2D(ccd.data, position=position_xy, size=cbox_size) e_cut = Cutout2D(error.data, position=position_xy, size=cbox_size) if ANNULUS is not None: ANNULUS.positions = position_xy ssky = sky_fit(ccd=ccd, annulus=ANNULUS, **sky_kw)["ssky"][0] cthresh = np.min(cut.data) + csigma * ssky mask = (cut.data < cthresh) # using pixels only above med + 3*std for centroiding is recommended. # See Ma+2009, Optics Express, 17, 8525 # -- I doubt this... YPBach 2019-07-08 10:43:54 (KST: GMT+09:00) if verbose: n_all = np.size(mask) n_rej = np.count_nonzero(mask.astype(int)) print(f"\t{n_rej} / {n_all} rejected [threshold = {cthresh:.3f} " + f"from min ({np.min(cut.data):.3f}) " + f"+ csigma ({csigma}) * ssky ({ssky:.3f})]") if ccd.mask is not None: cutmask = Cutout2D(ccd.mask, position=position_xy, size=cbox_size) mask += cutmask yy, xx = np.mgrid[:cut.data.shape[0], :cut.data.shape[1]] g_fit = fit_2dgaussian(data=cut.data, error=e_cut.data, mask=mask) g_fit = Gaussian2D_correct(g_fit) x_c_cut = g_fit.x_mean.value y_c_cut = g_fit.y_mean.value # The position is in the cutout image coordinate, e.g., (3, 3). pos_new_naive = cut.to_original_position((x_c_cut, y_c_cut)) # convert the cutout image coordinate to original coordinate. # e.g., (3, 3) becomes something like (137, 189) dx, dy, shift = scaling_shift(position_xy, pos_new_naive, max_shift_step=max_shift_step, verbose=verbose) pos_new = np.array([position_xy[0] + dx, position_xy[1] + dy]) return pos_new, shift, g_fit, cut, e_cut, g_fit(xx, yy)