def gc_ast_err_vs_snr(n_init=0, n_sims=10): """ Analyze how starfinder astrometric error changes with signal-to-noise ratio. Do this by planting known GC stars on a simulated sky background and readnoise/dark current image. Then try to recover the stars with starfinder and measure the astrometric errors. """ workDir = '/u/jlu/work/gc/ao_performance/ast_err_vs_snr/gc/' sky, dc, noise, gain = image_noise_properites() # IN e- background = (sky + dc) # in e- imgCount = 150 # The total number of individual exposures that went # into this image. print '' print 'SIMULATED IMAGE PROPERTIES:' print ' assuming %d science exposures' % imgCount print ' constant = %.1f DN (%.1f e-)' % (background/gain, background) print ' additional noise approximated with gaussian' print ' sigma = %.1f DN (%.1f e-)' % (noise/gain, noise) # Start with the background that Starfinder fit... it is smoothed. img = pyfits.getdata('mag10maylgs_kp_back.fits') img += background * gain # Noise from read out and sky subtraction (in e-) otherNoise = stats.norm.rvs(scale=noise, size=img.shape) # We are going to plant stars on this image using one of our # own PSFs. Each star we plant has to have photon noise from # itself as well. psf, hdr = pyfits.getdata('mag10maylgs_kp_psf.fits', header=True) # Repair the PSF so we don't have negative values idx1 = np.where(psf <= 0) idx2 = np.where(psf > 0) psf[idx1] = psf[idx2].min() # Read in the GC starlist gcstars = starTables.StarfinderList('mag10maylgs_kp_rms.lis', hasErrors=True) allIDLroots = [] for nn in range(n_init, n_init+n_sims): # Create a new image newImage = img.copy() # Now plant the stars for ii in range(len(gcstars.x)): mag = gcstars.mag[ii] flux = gcstars.counts[ii] # We need to add photon noise to the PSF. # Scale up the PSF temporarily since poisson() only # returns integers. tmp = psf * flux * gain # set flux=1 since we already scaled it. starPlant.addStar(newImage, tmp, gcstars.x[ii]+1.0, gcstars.y[ii]+1.0, 1.0) # Planted positions are actually rounded to the nearest # pixel to avoid interpolation noise.... do the same in the # input star list. gcstars.x[ii] = round(gcstars.x[ii]) gcstars.y[ii] = round(gcstars.y[ii]) # Fix negative pixels idx = np.where(newImage < 0) newImage[idx] = 0 # Now add noise to the image, compensate for large number of exposures newImage = stats.poisson.rvs((newImage * imgCount).tolist()) newImage = np.array(newImage, dtype=float) # necessary for starfinder newImage /= imgCount newImage += otherNoise # Subtract off sky/dark newImage -= background # Convert back to DN newImage /= gain # Save the new image, and copy over all the necessary files. suffix = str(nn).zfill(4) fitsFile = 'sim_img_%s.fits' % suffix psfFile = 'sim_img_%s_psf.fits' % suffix backFile = 'sim_img_%s_back.fits' % suffix cooFile = 'sim_img_%s.coo' % suffix lisFile = 'sim_orig_%s.lis' % suffix print 'Writing ', fitsFile gcutil.rmall([fitsFile]) pyfits.writeto(fitsFile, newImage, hdr, output_verify='silentfix') shutil.copyfile('mag10maylgs_kp_psf.fits', psfFile) shutil.copyfile('mag10maylgs_kp_back.fits', backFile) shutil.copyfile('mag10maylgs_kp.coo', cooFile) gcstars.saveToFile(lisFile) # Write out a starfinder batch file idlRoot = 'idl_sim_img_%s' % suffix _batch = open(idlRoot + '.batch', 'w') _batch.write("find_stf, ") _batch.write("'" + fitsFile + "', 0.8, /trimfake\n") _batch.write("exit\n") _batch.close() gcutil.rmall([idlRoot + '.log']) allIDLroots.append(idlRoot) for root in allIDLroots: print 'idl < %s.batch >& %s.log' % (root, root)
def gc_ast_err_vs_snr(n_init=0, n_sims=10): """ Analyze how starfinder astrometric error changes with signal-to-noise ratio. Do this by planting known GC stars on a simulated sky background and readnoise/dark current image. Then try to recover the stars with starfinder and measure the astrometric errors. """ workDir = '/u/jlu/work/gc/ao_performance/ast_err_vs_snr/gc/' sky, dc, noise, gain = image_noise_properites() # IN e- background = (sky + dc) # in e- imgCount = 150 # The total number of individual exposures that went # into this image. print '' print 'SIMULATED IMAGE PROPERTIES:' print ' assuming %d science exposures' % imgCount print ' constant = %.1f DN (%.1f e-)' % (background / gain, background) print ' additional noise approximated with gaussian' print ' sigma = %.1f DN (%.1f e-)' % (noise / gain, noise) # Start with the background that Starfinder fit... it is smoothed. img = pyfits.getdata('mag10maylgs_kp_back.fits') img += background * gain # Noise from read out and sky subtraction (in e-) otherNoise = stats.norm.rvs(scale=noise, size=img.shape) # We are going to plant stars on this image using one of our # own PSFs. Each star we plant has to have photon noise from # itself as well. psf, hdr = pyfits.getdata('mag10maylgs_kp_psf.fits', header=True) # Repair the PSF so we don't have negative values idx1 = np.where(psf <= 0) idx2 = np.where(psf > 0) psf[idx1] = psf[idx2].min() # Read in the GC starlist gcstars = starTables.StarfinderList('mag10maylgs_kp_rms.lis', hasErrors=True) allIDLroots = [] for nn in range(n_init, n_init + n_sims): # Create a new image newImage = img.copy() # Now plant the stars for ii in range(len(gcstars.x)): mag = gcstars.mag[ii] flux = gcstars.counts[ii] # We need to add photon noise to the PSF. # Scale up the PSF temporarily since poisson() only # returns integers. tmp = psf * flux * gain # set flux=1 since we already scaled it. starPlant.addStar(newImage, tmp, gcstars.x[ii] + 1.0, gcstars.y[ii] + 1.0, 1.0) # Planted positions are actually rounded to the nearest # pixel to avoid interpolation noise.... do the same in the # input star list. gcstars.x[ii] = round(gcstars.x[ii]) gcstars.y[ii] = round(gcstars.y[ii]) # Fix negative pixels idx = np.where(newImage < 0) newImage[idx] = 0 # Now add noise to the image, compensate for large number of exposures newImage = stats.poisson.rvs((newImage * imgCount).tolist()) newImage = np.array(newImage, dtype=float) # necessary for starfinder newImage /= imgCount newImage += otherNoise # Subtract off sky/dark newImage -= background # Convert back to DN newImage /= gain # Save the new image, and copy over all the necessary files. suffix = str(nn).zfill(4) fitsFile = 'sim_img_%s.fits' % suffix psfFile = 'sim_img_%s_psf.fits' % suffix backFile = 'sim_img_%s_back.fits' % suffix cooFile = 'sim_img_%s.coo' % suffix lisFile = 'sim_orig_%s.lis' % suffix print 'Writing ', fitsFile gcutil.rmall([fitsFile]) pyfits.writeto(fitsFile, newImage, hdr, output_verify='silentfix') shutil.copyfile('mag10maylgs_kp_psf.fits', psfFile) shutil.copyfile('mag10maylgs_kp_back.fits', backFile) shutil.copyfile('mag10maylgs_kp.coo', cooFile) gcstars.saveToFile(lisFile) # Write out a starfinder batch file idlRoot = 'idl_sim_img_%s' % suffix _batch = open(idlRoot + '.batch', 'w') _batch.write("find_stf, ") _batch.write("'" + fitsFile + "', 0.8, /trimfake\n") _batch.write("exit\n") _batch.close() gcutil.rmall([idlRoot + '.log']) allIDLroots.append(idlRoot) for root in allIDLroots: print 'idl < %s.batch >& %s.log' % (root, root)
def ast_err_vs_snr(n_init=0, n_sims=1000): """ Analyze how starfinder astrometric error changes with signal-to-noise ratio. Do this by planting stars on a simulated sky background and readnoise/dark current image. Then try to recover the stars with starfinder and measure the astrometric errors. """ sky, dc, noise, gain = image_noise_properites() # IN e- background = (sky + dc) # in e- imgCount = 150 # The total number of individual exposures that went # into this image. print '' print 'SIMULATED IMAGE PROPERTIES:' print ' assuming %d science exposures' % imgCount print ' constant = %.1f DN (%.1f e-)' % (background/gain, background) print ' additional noise approximated with gaussian' print ' sigma = %.1f DN (%.1f e-)' % (noise/gain, noise) img = np.zeros((1024, 1024), dtype=float) img += background # Noise from read out and sky subtraction (in e-) otherNoise = stats.norm.rvs(scale=noise, size=(1024,1024)) # We are going to plant stars on this image using one of our # own PSFs. Each star we plant has to have photon noise from # itself as well. psf, hdr = pyfits.getdata('mag10maylgs_kp_psf.fits', header=True) # Repair the PSF so we don't have negative values idx1 = np.where(psf <= 0) idx2 = np.where(psf > 0) psf[idx1] = psf[idx2].min() # Seperate the PSFs by 2" since this is the Starfinder box size. step = 200 # in pixels # Pulled these numbers from the calibrated starlists for 10maylgs. mag0 = 9.782 flux0 = 20522900.000 # Randomly select from a distribution of magnitudes. magMin = 9.0 magMax = 22.0 # Number of samples (stars planted) #numStars = 100 stopN = n_sims + n_init allIDLroots = [] nn = n_init while nn <= stopN: # Create a new image newImage = img.copy() brightCoords = None brightMag = 1000 # Make a new starlist with the input info. newStars = starTables.StarfinderList(None, hasErrors=False) # Now plant the stars for xx in range(step, img.shape[1]-step, step): for yy in range(step, img.shape[0]-step, step): mag = np.random.uniform(magMin, magMax) flux = flux0 * 10**(-0.4 * (mag - mag0)) # We need to add photon noise to the PSF. # Scale up the PSF temporarily since poisson() only # returns integers. tmp = psf * flux * gain #print '%4s x = %4d y = %4d mag = %5.2f flux = %.2f' % \ # (nn, xx, yy, mag, flux) newName = 'sim_%s' % str(nn).zfill(4) # set flux=1 since we already scaled it. starPlant.addStar(newImage, tmp, xx, yy, 1.0) newStars.append(newName, mag, xx-1, yy-1, counts=flux, epoch=2010.342) # Updare our record of the brightest star in the image. if mag < brightMag: brightMag = mag brightCoords = [xx, yy] nn += 1 # Fix negative pixels idx = np.where(newImage < 0) newImage[idx] = 0 # Now add noise to the image, compensate for large number of exposures newImage = stats.poisson.rvs((newImage * imgCount).tolist()) newImage = np.array(newImage, dtype=float) # necessary for starfinder newImage /= imgCount newImage += otherNoise # Subtract off sky/dark newImage -= background # Convert back to DN newImage /= gain # Make a background image. img_back = np.zeros((1024, 1024), dtype=float) # Save the new image, and copy over all the necessary files. suffix = str(nn).zfill(4) fitsFile = 'sim_img_%s.fits' % suffix psfFile = 'sim_img_%s_psf.fits' % suffix backFile = 'sim_img_%s_back.fits' % suffix cooFile = 'sim_img_%s.coo' % suffix lisFile = 'sim_orig_%s.lis' % suffix print 'Writing ', fitsFile gcutil.rmall([fitsFile, backFile]) pyfits.writeto(fitsFile, newImage, hdr, output_verify='silentfix') pyfits.writeto(backFile, img_back, hdr, output_verify='silentfix') # Resort the starlist so the brightest star is at the top mdx = newStars.mag.argsort() newStars.name = newStars.name[mdx] newStars.mag = newStars.mag[mdx] newStars.epoch = newStars.epoch[mdx] newStars.x = newStars.x[mdx] newStars.y = newStars.y[mdx] newStars.snr = newStars.snr[mdx] newStars.corr = newStars.corr[mdx] newStars.nframes = newStars.nframes[mdx] newStars.counts = newStars.counts[mdx] newStars.saveToFile(lisFile) shutil.copyfile('mag10maylgs_kp_psf.fits', psfFile) _coo = open(cooFile, 'w') _coo.write('%.2f %.2f\n' % (brightCoords[0], brightCoords[1])) _coo.close() # Write out a starfinder batch file idlRoot = 'idl_sim_img_%s' % suffix _batch = open(idlRoot + '.batch', 'w') _batch.write("find_stf, ") _batch.write("'" + fitsFile + "', 0.8, /trimfake\n") _batch.write("exit\n") _batch.close() gcutil.rmall([idlRoot + '.log']) allIDLroots.append(idlRoot) for root in allIDLroots: print 'idl < %s.batch >& %s.log' % (root, root)
def ast_err_vs_snr(n_init=0, n_sims=1000): """ Analyze how starfinder astrometric error changes with signal-to-noise ratio. Do this by planting stars on a simulated sky background and readnoise/dark current image. Then try to recover the stars with starfinder and measure the astrometric errors. """ sky, dc, noise, gain = image_noise_properites() # IN e- background = (sky + dc) # in e- imgCount = 150 # The total number of individual exposures that went # into this image. print '' print 'SIMULATED IMAGE PROPERTIES:' print ' assuming %d science exposures' % imgCount print ' constant = %.1f DN (%.1f e-)' % (background / gain, background) print ' additional noise approximated with gaussian' print ' sigma = %.1f DN (%.1f e-)' % (noise / gain, noise) img = np.zeros((1024, 1024), dtype=float) img += background # Noise from read out and sky subtraction (in e-) otherNoise = stats.norm.rvs(scale=noise, size=(1024, 1024)) # We are going to plant stars on this image using one of our # own PSFs. Each star we plant has to have photon noise from # itself as well. psf, hdr = pyfits.getdata('mag10maylgs_kp_psf.fits', header=True) # Repair the PSF so we don't have negative values idx1 = np.where(psf <= 0) idx2 = np.where(psf > 0) psf[idx1] = psf[idx2].min() # Seperate the PSFs by 2" since this is the Starfinder box size. step = 200 # in pixels # Pulled these numbers from the calibrated starlists for 10maylgs. mag0 = 9.782 flux0 = 20522900.000 # Randomly select from a distribution of magnitudes. magMin = 9.0 magMax = 22.0 # Number of samples (stars planted) #numStars = 100 stopN = n_sims + n_init allIDLroots = [] nn = n_init while nn <= stopN: # Create a new image newImage = img.copy() brightCoords = None brightMag = 1000 # Make a new starlist with the input info. newStars = starTables.StarfinderList(None, hasErrors=False) # Now plant the stars for xx in range(step, img.shape[1] - step, step): for yy in range(step, img.shape[0] - step, step): mag = np.random.uniform(magMin, magMax) flux = flux0 * 10**(-0.4 * (mag - mag0)) # We need to add photon noise to the PSF. # Scale up the PSF temporarily since poisson() only # returns integers. tmp = psf * flux * gain #print '%4s x = %4d y = %4d mag = %5.2f flux = %.2f' % \ # (nn, xx, yy, mag, flux) newName = 'sim_%s' % str(nn).zfill(4) # set flux=1 since we already scaled it. starPlant.addStar(newImage, tmp, xx, yy, 1.0) newStars.append(newName, mag, xx - 1, yy - 1, counts=flux, epoch=2010.342) # Updare our record of the brightest star in the image. if mag < brightMag: brightMag = mag brightCoords = [xx, yy] nn += 1 # Fix negative pixels idx = np.where(newImage < 0) newImage[idx] = 0 # Now add noise to the image, compensate for large number of exposures newImage = stats.poisson.rvs((newImage * imgCount).tolist()) newImage = np.array(newImage, dtype=float) # necessary for starfinder newImage /= imgCount newImage += otherNoise # Subtract off sky/dark newImage -= background # Convert back to DN newImage /= gain # Make a background image. img_back = np.zeros((1024, 1024), dtype=float) # Save the new image, and copy over all the necessary files. suffix = str(nn).zfill(4) fitsFile = 'sim_img_%s.fits' % suffix psfFile = 'sim_img_%s_psf.fits' % suffix backFile = 'sim_img_%s_back.fits' % suffix cooFile = 'sim_img_%s.coo' % suffix lisFile = 'sim_orig_%s.lis' % suffix print 'Writing ', fitsFile gcutil.rmall([fitsFile, backFile]) pyfits.writeto(fitsFile, newImage, hdr, output_verify='silentfix') pyfits.writeto(backFile, img_back, hdr, output_verify='silentfix') # Resort the starlist so the brightest star is at the top mdx = newStars.mag.argsort() newStars.name = newStars.name[mdx] newStars.mag = newStars.mag[mdx] newStars.epoch = newStars.epoch[mdx] newStars.x = newStars.x[mdx] newStars.y = newStars.y[mdx] newStars.snr = newStars.snr[mdx] newStars.corr = newStars.corr[mdx] newStars.nframes = newStars.nframes[mdx] newStars.counts = newStars.counts[mdx] newStars.saveToFile(lisFile) shutil.copyfile('mag10maylgs_kp_psf.fits', psfFile) _coo = open(cooFile, 'w') _coo.write('%.2f %.2f\n' % (brightCoords[0], brightCoords[1])) _coo.close() # Write out a starfinder batch file idlRoot = 'idl_sim_img_%s' % suffix _batch = open(idlRoot + '.batch', 'w') _batch.write("find_stf, ") _batch.write("'" + fitsFile + "', 0.8, /trimfake\n") _batch.write("exit\n") _batch.close() gcutil.rmall([idlRoot + '.log']) allIDLroots.append(idlRoot) for root in allIDLroots: print 'idl < %s.batch >& %s.log' % (root, root)