class Galfitter(object): def __init__(self, root='sdssj1723+3411', filter='f140w', galfit_exec='galfit', catfile=None, segfile=None): self.root = root self.galfit_exec = galfit_exec self.filter = filter data = self.get_data(filter=filter, catfile=catfile, segfile=segfile) self.sci, self.wht, self.seg, self.cat, self.wcs = data self.flt_files = self.get_flt_files(sci_hdu=self.sci) self.DPSF = DrizzlePSF(flt_files=self.flt_files, info=None, driz_image=self.sci.filename()) def get_data(self, filter='f140w', catfile=None, segfile=None): import glob sci_file = glob.glob('{0}-{1}_dr?_sci.fits'.format(self.root, filter)) sci = pyfits.open(sci_file[0]) wht = pyfits.open(sci_file[0].replace('sci','wht')) if segfile is None: segfile = sci_file[0].split('_dr')[0]+'_seg.fits' seg = pyfits.open(segfile) if catfile is None: catfile = '{0}-{1}.cat.fits'.format(self.root, filter) cat = utils.GTable.gread(catfile) wcs = pywcs.WCS(sci[0].header, relax=True) return sci, wht, seg, cat, wcs def get_flt_files(self, sci_hdu=None): flt_files = [] h = self.sci[0].header for i in range(h['NDRIZIM']): file = h['D{0:03d}DATA'.format(i+1)].split('[sci')[0] if file not in flt_files: flt_files.append(file) return flt_files @staticmethod def fit_arrays(sci, wht, seg, psf, id=None, platescale=0.06, exptime=0, path='/tmp/', galfit_exec='galfit', gaussian_guess=False, components=[GalfitSersic()], recenter=True, psf_sample=1): rms = 1/np.sqrt(wht)#*exptime if exptime > 0: rms = np.sqrt((rms*exptime)**2+sci*exptime*(sci > 0))/exptime rms[wht == 0] = 1e30 if id is not None: mask = ((seg > 0) & (seg != id)) | (wht == 0) else: mask = wht == 0 sh = sci.shape[0] fp = open(path+'galfit.feedme','w') fp.write(GALFIT_IMAGES.format(input=path+'gf_sci.fits', output=path+'gf_out.fits', sigma=path+'gf_rms.fits', psf=path+'gf_psf.fits', mask=path+'gf_mask.fits', xmax=sh, ymax=sh, sh=sh, ps=platescale, psf_sample=psf_sample)) if gaussian_guess: fit, q, theta = fit_gauss(sci) from astropy.coordinates import Angle import astropy.units as u for comp in components: if recenter: comp.set(pos=[sh/2., sh/2.]) if gaussian_guess: comp.set(q=q, pa=Angle.wrap_at(theta*u.rad, 360*u.deg).to(u.deg).value) fp.write(str(comp)) fp.close() pyfits.writeto(path+'gf_sci.fits', data=sci, overwrite=True) pyfits.writeto(path+'gf_rms.fits', data=rms, overwrite=True) pyfits.writeto(path+'gf_mask.fits', data=mask*1, overwrite=True) pyfits.writeto(path+'gf_psf.fits', data=psf, overwrite=True) for ext in ['out', 'model']: if os.path.exists(path+'gf_{0}.fits'.format(ext)): os.remove(path+'gf_{0}.fits'.format(ext)) os.system('{0} {1}/galfit.feedme'.format(galfit_exec, path)) def fit_object(self, id=449, radec=(None, None), size=40, components=[GalfitSersic()], recenter=True, get_mosaic=True, gaussian_guess=False, get_extended=True): """ Fit an object """ if id is not None: rd = self.cat['X_WORLD', 'Y_WORLD'][self.cat['NUMBER'] == id][0] radec = tuple(rd) xy = self.wcs.all_world2pix([radec[0]], [radec[1]], 0) xy = np.array(xy).flatten() xp = np.cast[int](np.round(xy)) slx, sly, wcs_slice = self.DPSF.get_driz_cutout(ra=radec[0], dec=radec[1], get_cutout=False, size=size) #drz_cutout = self.get_driz_cutout(ra=ra, dec=dec, get_cutout=True) h = self.sci[0].header psf = self.DPSF.get_psf(ra=radec[0], dec=radec[1], filter=self.filter.upper(), wcs_slice=wcs_slice, pixfrac=h['D001PIXF'], kernel=h['D001KERN'], get_extended=get_extended) exptime = h['EXPTIME'] sci = self.sci[0].data[sly, slx]#*exptime wht = self.wht[0].data[sly, slx] rms = 1/np.sqrt(wht)#*exptime rms = np.sqrt((rms*exptime)**2+sci*exptime*(sci > 0))/exptime rms[wht == 0] = 1e30 seg = self.seg[0].data[sly, slx] if id is not None: mask = ((seg > 0) & (seg != id)) | (wht == 0) else: mask = wht == 0 sh = sci.shape[0] path = '/tmp/' psf_file = '{0}-{1}_psf_{2:05d}.fits'.format(self.root, self.filter, id) fp = open(path+'galfit.feedme','w') fp.write(GALFIT_IMAGES.format(input=path+'gf_sci.fits', output=path+'gf_out.fits', sigma=path+'gf_rms.fits', psf=psf_file, mask=path+'gf_mask.fits', xmax=sh, ymax=sh, sh=sh, ps=self.DPSF.driz_pscale, psf_sample=1)) if gaussian_guess: fit, q, theta = fit_gauss(sci) from astropy.coordinates import Angle import astropy.units as u for comp in components: if recenter: comp.set(pos=[sh/2., sh/2.]) if gaussian_guess: comp.set(q=q, pa=Angle.wrap_at(theta*u.rad, 360*u.deg).to(u.deg).value) fp.write(str(comp)) fp.close() pyfits.writeto(path+'gf_sci.fits', data=sci, overwrite=True) pyfits.writeto(path+'gf_rms.fits', data=rms, overwrite=True) pyfits.writeto(path+'gf_mask.fits', data=mask*1, overwrite=True) #pyfits.writeto(path+'gf_psf.fits', data=psf[1].data, overwrite=True) pyfits.writeto(psf_file, data=psf[1].data, overwrite=True) for ext in ['out', 'model']: if os.path.exists(path+'gf_{0}.fits'.format(ext)): os.remove(path+'gf_{0}.fits'.format(ext)) os.system('{0} {1}/galfit.feedme'.format(self.galfit_exec, path)) #out = pyfits.open('/tmp/gf_out.fits') # Get in DRZ frame gf_file = glob.glob('galfit.[0-9]*')[-1] lines = open(gf_file).readlines() for il, line in enumerate(lines): if line.startswith('A)'): lines[il] = 'A) {0} # Input data image (FITS file)\n'.format(self.sci.filename()) if line.startswith('B)'): lines[il] = 'B) {0}-{1}_galfit_{2:05d}.fits # Output data image block\n'.format(self.root, self.filter, id) if line.startswith('P) 0'): lines[il] = "P) 1 # Choose: 0=optimize, 1=model, 2=imgblock, 3=subcomps\n" if line.startswith('H)'): out_sh = self.sci[0].data.shape lines[il] = "H) 1 {0} 1 {1} # Image region to fit (xmin xmax ymin ymax)\n".format(out_sh[1], out_sh[0]) if line.startswith(' 1)'): xy = np.cast[float](line.split()[1:3]) lines[il] = ' 1) {0} {1} 1 1 # Position x, y\n'.format(xy[0]+slx.start, xy[1]+sly.start) fp = open('galfit.{0}.{1:05d}'.format(self.filter, id),'w') fp.writelines(lines) fp.close() os.system('{0} galfit.{1}.{2:05d}'.format(self.galfit_exec, self.filter, id)) model = pyfits.open('{0}-{1}_galfit_{2:05d}.fits'.format(self.root, self.filter, id), mode='update') model[0].data /= self.sci[0].header['EXPTIME'] model.flush() return(lines, model) model = pyfits.open('/tmp/gf_model.fits') if False: full_model = self.sci[0].data*0 full_model += model[0].data pyfits.writeto('{0}-{1}_galfit.fits'.format(self.root, self.filter), data=full_model, header=self.sci[0].header, overwrite=True)
class Galfitter(object): def __init__(self, root='sdssj1723+3411', filter='f140w', galfit_exec='galfit', catfile=None, segfile=None): self.root = root self.galfit_exec = galfit_exec self.filter = filter data = self.get_data(filter=filter, catfile=catfile, segfile=segfile) self.sci, self.wht, self.seg, self.cat, self.wcs = data self.flt_files = self.get_flt_files(sci_hdu=self.sci) self.DPSF = DrizzlePSF(flt_files=self.flt_files, info=None, driz_image=self.sci.filename()) def get_data(self, filter='f140w', catfile=None, segfile=None): import glob sci_file = glob.glob('{0}-{1}_dr?_sci.fits'.format(self.root, filter)) sci = pyfits.open(sci_file[0]) wht = pyfits.open(sci_file[0].replace('sci', 'wht')) if segfile is None: segfile = sci_file[0].split('_dr')[0] + '_seg.fits' seg = pyfits.open(segfile) if catfile is None: catfile = '{0}-{1}.cat.fits'.format(self.root, filter) cat = utils.GTable.gread(catfile) wcs = pywcs.WCS(sci[0].header, relax=True) return sci, wht, seg, cat, wcs def get_flt_files(self, sci_hdu=None): flt_files = [] h = self.sci[0].header for i in range(h['NDRIZIM']): file = h['D{0:03d}DATA'.format(i + 1)].split('[sci')[0] if file not in flt_files: flt_files.append(file) return flt_files @staticmethod def fit_arrays(sci, wht, seg, psf, id=None, platescale=0.06, exptime=0, path='/tmp', root='gf', galfit_exec='galfit', ab_zeropoint=26, gaussian_guess=False, components=[GalfitSersic()], recenter=True, psf_sample=1, write_constraints=True): """ Fit array data with Galfit """ from astropy.coordinates import Angle import astropy.units as u rms = 1 / np.sqrt(wht) # *exptime if exptime > 0: rms = np.sqrt((rms * exptime)**2 + sci * exptime * (sci > 0)) / exptime rms[wht == 0] = 1e30 if id is not None: mask = ((seg > 0) & (seg != id)) | (wht == 0) else: mask = wht == 0 sh = sci.shape[0] fp = open('{0}/{1}.feedme'.format(path, root), 'w') sci_file = '{0}/{1}_sci.fits'.format(path, root) constraints_file = sci_file.replace('_sci.fits', '.constraints') cmd = GALFIT_IMAGES.format(input=sci_file, output=sci_file.replace('_sci', '_out'), sigma=sci_file.replace('_sci', '_rms'), psf=sci_file.replace('_sci', '_psf'), mask=sci_file.replace('_sci', '_mask'), constraints=constraints_file, xmax=sh, ymax=sh, sh=sh, ps=platescale, psf_sample=psf_sample, ab_zeropoint=ab_zeropoint) fp.write(cmd) if gaussian_guess: fit, q, theta = fit_gauss(sci) if (not os.path.exists(constraints_file)) & (write_constraints): fpc = open(constraints_file, 'w') else: fpc = None for i, comp in enumerate(components): if recenter: comp.set(pos=[sh / 2., sh / 2.]) if gaussian_guess: comp.set(q=q, pa=Angle.wrap_at(theta * u.rad, 360 * u.deg).to(u.deg).value) fp.write(str(comp)) if fpc is not None: fpc.write(SERSIC_CONSTRAINTS.format(comp=i + 1)) fp.close() if fpc is not None: fpc.close() pyfits.writeto(sci_file, data=sci, overwrite=True) pyfits.writeto(sci_file.replace('_sci', '_rms'), data=rms, overwrite=True) pyfits.writeto(sci_file.replace('_sci', '_mask'), data=mask * 1, overwrite=True) pyfits.writeto(sci_file.replace('_sci', '_psf'), data=psf, overwrite=True) for ext in ['out', 'model']: fi = sci_file.replace('_sci', '_' + ext) if os.path.exists(fi): os.remove(fi) os.system('{0} {1}/{2}.feedme'.format(galfit_exec, path, root)) # Move galfit.[latest] to output file gf_files = glob.glob('galfit.[0-9]*') gf_files.sort() gf_log = sci_file.replace('_sci.fits', '.gfmodel') os.system('mv {0} {1}'.format(gf_files[-1], gf_log)) lines = open(gf_log).readlines() # Results dictionary res = {} res['rms'] = rms res['mask'] = mask * 1 im = pyfits.open(sci_file.replace('_sci', '_out')) res['model'] = im[2] res['resid'] = im[3] res['ascii'] = lines return res def fit_object(self, id=449, radec=(None, None), size=40, components=[GalfitSersic()], recenter=True, get_mosaic=True, gaussian_guess=False, get_extended=True): """ Fit an object """ if id is not None: rd = self.cat['X_WORLD', 'Y_WORLD'][self.cat['NUMBER'] == id][0] radec = tuple(rd) xy = self.wcs.all_world2pix([radec[0]], [radec[1]], 0) xy = np.array(xy).flatten() xp = np.cast[int](np.round(xy)) slx, sly, wcs_slice = self.DPSF.get_driz_cutout(ra=radec[0], dec=radec[1], get_cutout=False, size=size) #drz_cutout = self.get_driz_cutout(ra=ra, dec=dec, get_cutout=True) h = self.sci[0].header psf = self.DPSF.get_psf(ra=radec[0], dec=radec[1], filter=self.filter.upper(), wcs_slice=wcs_slice, pixfrac=h['D001PIXF'], kernel=h['D001KERN'], get_extended=get_extended) exptime = h['EXPTIME'] sci = self.sci[0].data[sly, slx] # *exptime wht = self.wht[0].data[sly, slx] rms = 1 / np.sqrt(wht) # *exptime rms = np.sqrt((rms * exptime)**2 + sci * exptime * (sci > 0)) / exptime rms[wht == 0] = 1e30 seg = self.seg[0].data[sly, slx] if id is not None: mask = ((seg > 0) & (seg != id)) | (wht == 0) else: mask = wht == 0 sh = sci.shape[0] path = '/tmp/' psf_file = '{0}-{1}_psf_{2:05d}.fits'.format(self.root, self.filter, id) fp = open(path + 'galfit.feedme', 'w') fp.write( GALFIT_IMAGES.format(input=path + 'gf_sci.fits', output=path + 'gf_out.fits', sigma=path + 'gf_rms.fits', psf=psf_file, mask=path + 'gf_mask.fits', xmax=sh, ymax=sh, sh=sh, ps=self.DPSF.driz_pscale, psf_sample=1, constraints='none', ab_zeropoint=26)) if gaussian_guess: fit, q, theta = fit_gauss(sci) from astropy.coordinates import Angle import astropy.units as u for comp in components: if recenter: comp.set(pos=[sh / 2., sh / 2.]) if gaussian_guess: comp.set(q=q, pa=Angle.wrap_at(theta * u.rad, 360 * u.deg).to(u.deg).value) fp.write(str(comp)) fp.close() pyfits.writeto(path + 'gf_sci.fits', data=sci, overwrite=True) pyfits.writeto(path + 'gf_rms.fits', data=rms, overwrite=True) pyfits.writeto(path + 'gf_mask.fits', data=mask * 1, overwrite=True) #pyfits.writeto(path+'gf_psf.fits', data=psf[1].data, overwrite=True) pyfits.writeto(psf_file, data=psf[1].data, overwrite=True) for ext in ['out', 'model']: if os.path.exists(path + 'gf_{0}.fits'.format(ext)): os.remove(path + 'gf_{0}.fits'.format(ext)) os.system('{0} {1}/galfit.feedme'.format(self.galfit_exec, path)) #out = pyfits.open('/tmp/gf_out.fits') # Get in DRZ frame gf_file = glob.glob('galfit.[0-9]*')[-1] lines = open(gf_file).readlines() for il, line in enumerate(lines): if line.startswith('A)'): lines[ il] = 'A) {0} # Input data image (FITS file)\n'.format( self.sci.filename()) if line.startswith('B)'): lines[ il] = 'B) {0}-{1}_galfit_{2:05d}.fits # Output data image block\n'.format( self.root, self.filter, id) if line.startswith('P) 0'): lines[ il] = "P) 1 # Choose: 0=optimize, 1=model, 2=imgblock, 3=subcomps\n" if line.startswith('H)'): out_sh = self.sci[0].data.shape lines[ il] = "H) 1 {0} 1 {1} # Image region to fit (xmin xmax ymin ymax)\n".format( out_sh[1], out_sh[0]) if line.startswith(' 1)'): xy = np.cast[float](line.split()[1:3]) lines[il] = ' 1) {0} {1} 1 1 # Position x, y\n'.format( xy[0] + slx.start, xy[1] + sly.start) fp = open('galfit.{0}.{1:05d}'.format(self.filter, id), 'w') fp.writelines(lines) fp.close() os.system('{0} galfit.{1}.{2:05d}'.format(self.galfit_exec, self.filter, id)) model = pyfits.open('{0}-{1}_galfit_{2:05d}.fits'.format( self.root, self.filter, id), mode='update') model[0].data /= self.sci[0].header['EXPTIME'] model.flush() return (lines, model) model = pyfits.open('/tmp/gf_model.fits') if False: full_model = self.sci[0].data * 0 full_model += model[0].data pyfits.writeto('{0}-{1}_galfit.fits'.format(self.root, self.filter), data=full_model, header=self.sci[0].header, overwrite=True)
class Galfitter(object): def __init__(self, root='sdssj1723+3411', filter='f140w', galfit_exec='galfit'): self.root = root self.galfit_exec = galfit_exec self.filter = filter data = self.get_data(filter=filter) self.sci, self.wht, self.seg, self.cat, self.wcs = data self.flt_files = self.get_flt_files(sci_hdu=self.sci) self.DPSF = DrizzlePSF(flt_files=self.flt_files, info=None, driz_image=self.sci.filename()) def get_data(self, filter='f140w'): sci = pyfits.open('{0}-{1}_drz_sci.fits'.format(self.root, filter)) wht = pyfits.open('{0}-{1}_drz_wht.fits'.format(self.root, filter)) seg = pyfits.open('{0}-{1}_seg.fits'.format(self.root, filter)) cat = grizli.utils.GTable.gread('{0}-{1}.cat'.format( self.root, filter)) wcs = pywcs.WCS(sci[0].header, relax=True) return sci, wht, seg, cat, wcs def get_flt_files(self, sci_hdu=None): flt_files = [] h = self.sci[0].header for i in range(h['NDRIZIM']): flt_files.append(h['D{0:03d}DATA'.format(i + 1)].split('[sci')[0]) return flt_files def fit_object(self, id=449, radec=(None, None), size=40, components=[GalfitSersic()], recenter=True, get_mosaic=True, gaussian_guess=False): """ Fit an object """ if id is not None: rd = self.cat['X_WORLD', 'Y_WORLD'][self.cat['NUMBER'] == id][0] radec = tuple(rd) xy = self.wcs.all_world2pix([radec[0]], [radec[1]], 0) xy = np.array(xy).flatten() xp = np.cast[int](np.round(xy)) slx, sly, wcs_slice = self.DPSF.get_driz_cutout(ra=radec[0], dec=radec[1], get_cutout=False, size=size) #drz_cutout = self.get_driz_cutout(ra=ra, dec=dec, get_cutout=True) h = self.sci[0].header psf = self.DPSF.get_psf(ra=radec[0], dec=radec[1], filter=self.filter.upper(), wcs_slice=wcs_slice, pixfrac=h['D001PIXF'], kernel=h['D001KERN'], get_extended=True) exptime = h['EXPTIME'] sci = self.sci[0].data[sly, slx] #*exptime wht = self.wht[0].data[sly, slx] rms = 1 / np.sqrt(wht) #*exptime rms = np.sqrt((rms * exptime)**2 + sci * exptime * (sci > 0)) / exptime rms[wht == 0] = 1e30 seg = self.seg[0].data[sly, slx] if id is not None: mask = ((seg > 0) & (seg != id)) | (wht == 0) else: mask = wht == 0 sh = sci.shape[0] path = '/tmp/' psf_file = '{0}-{1}_psf_{2:05d}.fits'.format(self.root, self.filter, id) fp = open(path + 'galfit.feedme', 'w') fp.write( GALFIT_IMAGES.format(input=path + 'gf_sci.fits', output=path + 'gf_out.fits', sigma=path + 'gf_rms.fits', psf=psf_file, mask=path + 'gf_mask.fits', xmax=sh, ymax=sh, sh=sh)) if gaussian_guess: fit, q, theta = fit_gauss(sci) from astropy.coordinates import Angle import astropy.units as u for comp in components: if recenter: comp.set(pos=[sh / 2., sh / 2.]) if gaussian_guess: comp.set(q=q, pa=Angle.wrap_at(theta * u.rad, 360 * u.deg).to(u.deg).value) fp.write(str(comp)) fp.close() pyfits.writeto(path + 'gf_sci.fits', data=sci, overwrite=True) pyfits.writeto(path + 'gf_rms.fits', data=rms, overwrite=True) pyfits.writeto(path + 'gf_mask.fits', data=mask * 1, overwrite=True) #pyfits.writeto(path+'gf_psf.fits', data=psf[1].data, overwrite=True) pyfits.writeto(psf_file, data=psf[1].data, overwrite=True) for ext in ['out', 'model']: if os.path.exists(path + 'gf_{0}.fits'.format(ext)): os.remove(path + 'gf_{0}.fits'.format(ext)) os.system('{0} {1}/galfit.feedme'.format(self.galfit_exec, path)) #out = pyfits.open('/tmp/gf_out.fits') # Get in DRZ frame gf_file = glob.glob('galfit.[0-9]*')[-1] lines = open(gf_file).readlines() for il, line in enumerate(lines): if line.startswith('A)'): lines[ il] = 'A) {0} # Input data image (FITS file)\n'.format( self.sci.filename()) if line.startswith('B)'): lines[ il] = 'B) {0}-{1}_galfit_{2:05d}.fits # Output data image block\n'.format( self.root, self.filter, id) if line.startswith('P) 0'): lines[ il] = "P) 1 # Choose: 0=optimize, 1=model, 2=imgblock, 3=subcomps\n" if line.startswith('H)'): out_sh = self.sci[0].data.shape lines[ il] = "H) 1 {0} 1 {1} # Image region to fit (xmin xmax ymin ymax)\n".format( out_sh[1], out_sh[0]) if line.startswith(' 1)'): xy = np.cast[float](line.split()[1:3]) lines[il] = ' 1) {0} {1} 1 1 # Position x, y\n'.format( xy[0] + slx.start, xy[1] + sly.start) fp = open('galfit.{0}.{1:05d}'.format(self.filter, id), 'w') fp.writelines(lines) fp.close() os.system('{0} galfit.{1}.{2:05d}'.format(self.galfit_exec, self.filter, id)) return (lines) model = pyfits.open('/tmp/gf_model.fits') if False: full_model = self.sci[0].data * 0 full_model += model[0].data pyfits.writeto('{0}-{1}_galfit.fits'.format(self.root, self.filter), data=full_model, header=self.sci[0].header, overwrite=True)