def make_RGB(sigmax=3,sigmin=1,write=False): Blue,header = fits.getdata('Blue.fit',0,header=True) Green,header = fits.getdata('Green.fit',0,header=True) Red,header = fits.getdata('Red.fit',0,header=True) bmed = np.median(Blue) gmed = np.median(Green) rmed = np.median(Red) bsig = rb.std(Blue) gsig = rb.std(Green) rsig = rb.std(Red) final = np.zeros((Blue.shape[0],Blue.shape[1],3),dtype=float) final[:,:,0] = img_scale.sqrt(Red,scale_min=rmed+sigmin*rsig,scale_max=rmed+sigmax*rsig) final[:,:,1] = img_scale.sqrt(Green,scale_min=gmed+sigmin*gsig,scale_max=gmed+sigmax*gsig) final[:,:,2] = img_scale.sqrt(Blue,scale_min=bmed+sigmin*bsig,scale_max=bmed+sigmax*bsig) plt.ion() plt.figure(99) plt.imshow(final,aspect='equal') if write: plt.savefig('RGB.png',dpi=300) return
def wind_dir_pressure(year=2013): from statsmodels.nonparametric.kernel_density import KDEMultivariate as KDE import robust as rb min2 = 0 sigfac = 3 sigsamp = 5 d = get_data(year=year) wdir = d["winddir_deg"] wdir_rand = wdir + np.random.normal(0,12,len(wdir)) bad = np.isnan(wdir_rand) wdir_rand[bad] = np.random.uniform(0,360,np.sum(bad)) press = d["pressure"] dist1 = wdir_rand dist2 = press med1 = np.median(dist1) sig1 = rb.std(dist1) datamin1 = np.min(dist1) datamax1 = np.max(dist1) min1 = 0.0 max1 = 360.0 med2 = np.median(dist2) sig2 = rb.std(dist2) datamin2 = np.min(dist2) datamax2 = np.max(dist2) min2 = np.min(dist2) max2 = np.max(dist2) X, Y = np.mgrid[min1:max1:100j, min2:max2:100j] positions = np.vstack([X.ravel(), Y.ravel()]) values = np.vstack([dist1, dist2]) kernel = KDE(values,var_type='cc',bw=[sig1/sigsamp,sig2/sigsamp]) Z = np.reshape(kernel.pdf(positions).T, X.shape) aspect = (max1-min1)/(max2-min2) * 8.5/11.0 plot_params() plt.ion() plt.figure(5,figsize=(11,8.5)) plt.clf() ax = plt.subplot(111) ax.imshow(np.rot90(Z), cmap=plt.cm.CMRmap_r,aspect=aspect, \ extent=[min1, max1, min2, max2],origin='upper') ax.yaxis.labelpad = 12 ax.set_ylabel('Atmospheric Pressure (in-Hg)',fontsize=fs) ax.set_xlabel('Wind Direction (degrees)',fontsize=fs) plt.title('Wind Direction and Pressure at Thacher Observatory in '+str(year),fontsize=fs) plt.savefig('Wind_Direction_Pressure_'+str(year)+'.png',dpi=300) mpl.rcdefaults() return
def make_RGB(): Blue,header = pf.getdata('Blue.fit',0,header=True) Green,header = pf.getdata('Green.fit',0,header=True) Red,header = pf.getdata('Red.fit',0,header=True) G = h.pyfits.open('Green.fit') Gh = h.pyfits.getheader('Green.fit') B = h.pyfits.open('Blue.fit') Bh = h.pyfits.getheader('Blue.fit') R = h.pyfits.open('Red.fit') Rh = h.pyfits.getheader('Red.fit') Bnew = h.hcongrid(B[0].data,B[0].header,Gh) Rnew = h.hcongrid(R[0].data,R[0].header,Gh) Blue = Bnew Green,header = readimage('Green.fit') Red = Rnew bmed = np.median(Blue) gmed = np.median(Green) rmed = np.median(Red) bsig = rb.std(Blue) gsig = rb.std(Green) rsig = rb.std(Red) final = np.zeros((Blue.shape[0],Blue.shape[1],3),dtype=float) sigmin = 1.25 sigmax = 15 final[:,:,0] = img_scale.sqrt(Red,scale_min=rmed+sigmin*rsig,scale_max=rmed+0.6*sigmax*rsig) final[:,:,1] = img_scale.sqrt(Green,scale_min=gmed+sigmin*gsig,scale_max=gmed+0.6*sigmax*gsig) final[:,:,2] = img_scale.sqrt(Blue,scale_min=bmed+sigmin*bsig,scale_max=bmed+0.6*sigmax*bsig) plt.ion() plt.figure(99) #plt.imshow(img,aspect='equal') plt.xlim(250,1550) plt.ylim(288,1588) plt.xticks([]) plt.yticks([]) plt.imshow(final,aspect='equal') return
def show_image(file,lowsig=1,hisig=4,skyonly=False,write=False): # Get image and header image, header = pf.getdata(file, 0, header=True) # Keep region determined by eye image = image[:,200:1270] # Region of sky to determine statistics determined by eye if skyonly: region = image[280:775,200:900] else: region = image sig = rb.std(region) med = np.median(region) mean = np.mean(region) vmin = med - lowsig*sig vmax = med + hisig*sig plt.ion() plt.figure(99,figsize=(15,8)) plt.clf() plt.imshow(image,vmin=vmin,vmax=vmax,cmap='gray', interpolation='nearest',origin='upper') plt.axis('off') plt.colorbar() if write: plt.savefig('AllSkyImage.png',dpi=300) return
def movie_image(file,lowsig=1,hisig=4): # Get image and header image, header = pf.getdata(file, 0, header=True) date = header['DATE-OBS'] time = 'UT'+header['TIME-OBS'] # Keep region determined by eye image = image[:,200:1270] # Do statistics for image display sig = rb.std(image) med = np.median(image) mean = np.mean(image) vmin = med - lowsig*sig vmax = med + hisig*sig # Plot image plt.imshow(image,vmin=vmin,vmax=vmax,cmap='gray', interpolation='nearest',origin='upper') plt.annotate(date,[0.08,0.92],horizontalalignment='left', xycoords='figure fraction',fontsize=14,color='white') plt.annotate(time,[0.92,0.92],horizontalalignment='right', xycoords='figure fraction',fontsize=14,color='white') # Turn axis labeling off plt.axis('off') return
def clip2(data, robust=True): """ Alternate sigma-clipping flagger for spectrometer data. This function assumes that the data have already been bandpassed in frequency and time and then uses a iterative method to find and flag outliters. """ for j in xrange(params.sc_passes): mask = data.mask * 1 for i in range(data.shape[1]): i0 = max([0, i - params.sc_bp_window_f / 2]) i1 = min([i + params.sc_bp_window_f / 2, data.shape[1] - 1]) try: assert (robust) mn, st = robust.mean(data[:, i0:i1 + 1]), robust.std( data[:, i0:i1 + 1]) except: mn, st = np.ma.mean(data[:, i0:i1 + 1]), np.ma.std( data[:, i0:i1 + 1]) bad = np.where(np.abs(data[:, i] - 1) > params.sigma * st)[0] mask[bad, i] |= True data.mask = mask * 1 return data.mask
def show_image(image,siglo=3,sighi=7): med = np.median(image) sig = rb.std(image) plt.ion() plt.figure() vmin = med - siglo*sig vmax = med + sighi*sig plt.imshow(image,vmin=vmin,vmax=vmax,cmap='gray') return
def display_image(image,siglo=3,sighi=7,fignum=2): med = np.median(image) sig = rb.std(image) plt.ion() plt.figure(fignum) vmin = med - siglo*sig vmax = med + sighi*sig plt.imshow(image,vmin=vmin,vmax=vmax,cmap='gray') return
def readimage(imfile,plot=False,siglo=3,sighi=7): image,header = fits.getdata(imfile,0,header=True) med = np.median(image) sig = rb.std(image) if plot: plt.ion() plt.figure(1) vmin = med - siglo*sig vmax = med + sighi*sig plt.imshow(image,vmin=vmin,vmax=vmax,cmap='gray') return image,header
def compareData(name1, name2, plot=False): #read data data1 = data[data['Name']== name1]['Length'] data2 = data[data['Name']== name2]['Length'] #exclude outliers mean1, mean2 = rb.mean(data1.values), rb.mean(data2.values) std1, std2 = rb.std(data1.values), rb.std(data2.values) data1 = data1[data1.values>(mean1-std1)] data2 = data2[data2.values>(mean2-std2)] #std1 = np.std(lengths1) if plot: #plot histograms plt.ion() plt.figure(1) plt.clf() plt.hist(data1.values,bins=np.linspace(4.75,5.75,30), label=name1, alpha=0.5,histtype='barstacked',stacked=True) plt.hist(data2.values,bins=np.linspace(4.75,5.75,30), label=name2, alpha=0.5,histtype='barstacked',stacked=True) plt.legend() #plot CDFs plt.figure(2) xs1 = np.sort(data1) ys1 = np.arange(1, len(xs1)+1)/float(len(xs1)) plt.plot(xs1,ys1,'g-',label=name1) cdf = ECDF(data2) plt.plot(cdf.x, cdf.y,'r-',label=name2) plt.legend() #preform ks test and student t-test d,pk = ks_2samp(data1,data2) t,pt = ttest_ind(data1,data2,equal_var=False) #print d,pk,pt return pk, pt
def data_look(file,lowsig=1,hisig=4): # Get image and header image, header = pf.getdata(file, 0, header=True) sig = rb.std(image) med = np.median(image) mean = np.mean(image) vmin = med - lowsig*sig vmax = med + hisig*sig plt.ion() plt.figure(99,figsize=(15,8)) plt.clf() plt.imshow(image,vmin=vmin,vmax=vmax,cmap='gray', interpolation='nearest',origin='upper') plt.axis('off') plt.colorbar()
def display_image(file,lowsig=1,hisig=4): # Get image and header image, header = pf.getdata(file, 0, header=True) # Do statistics for image display sig = rb.std(image) med = np.median(image) mean = np.mean(image) vmin = med - lowsig*sig vmax = med + hisig*sig # Plot image plt.imshow(image,vmin=vmin,vmax=vmax,cmap='gray', interpolation='nearest',origin='upper') # Turn axis labeling off plt.axis('off') return
def data_look(file, lowsig=1, hisig=4): # Get image and header image, header = pf.getdata(file, 0, header=True) sig = rb.std(image) med = np.median(image) mean = np.mean(image) vmin = med - lowsig * sig vmax = med + hisig * sig plt.ion() plt.figure(99, figsize=(15, 8)) plt.clf() plt.imshow(image, vmin=vmin, vmax=vmax, cmap='gray', interpolation='nearest', origin='upper') plt.axis('off') plt.colorbar()
def display_image(file, lowsig=1, hisig=4): # Get image and header image, header = pf.getdata(file, 0, header=True) # Do statistics for image display sig = rb.std(image) med = np.median(image) mean = np.mean(image) vmin = med - lowsig * sig vmax = med + hisig * sig # Plot image plt.imshow(image, vmin=vmin, vmax=vmax, cmap='gray', interpolation='nearest', origin='upper') # Turn axis labeling off plt.axis('off') return
def wind_speed_pressure(year=2013,peak=False): from statsmodels.nonparametric.kernel_density import KDEMultivariate as KDE import robust as rb min2 = 0 sigfac = 3 sigsamp = 5 d = get_data(year=year) if peak: wind = d['windhi'] tag = 'peak' word = 'Peak ' else: wind = d["wind"] tag = 'ave' word = 'Average ' wind_rand = wind + np.random.normal(0,0.5,len(wind)) press = d["pressure"] dist1 = press dist2 = wind_rand med1 = np.median(dist1) sig1 = rb.std(dist1) datamin1 = np.min(dist1) datamax1 = np.max(dist1) min1 = np.min(dist1) max1 = np.max(dist1) med2 = np.median(dist2) sig2 = rb.std(dist2) datamin2 = np.min(dist2) datamax2 = np.max(dist2) max2 = min(med2 + sigfac*sig2,datamax2) X, Y = np.mgrid[min1:max1:100j, min2:max2:100j] positions = np.vstack([X.ravel(), Y.ravel()]) values = np.vstack([dist1, dist2]) kernel = KDE(values,var_type='cc',bw=[sig1/sigsamp,sig2/sigsamp]) Z = np.reshape(kernel.pdf(positions).T, X.shape) aspect = (max1-min1)/(max2-min2) * 8.5/11.0 plot_params() plt.ion() plt.figure(5,figsize=(11,8.5)) plt.clf() ax = plt.subplot(111) ax.imshow(np.rot90(Z), cmap=plt.cm.CMRmap_r,aspect=aspect, \ extent=[min1, max1, min2, max2],origin='upper') ax.yaxis.labelpad = 12 ax.set_xlabel('Atmospheric Pressure (in-Hg)',fontsize=fs) ax.set_ylabel(word+'Wind Speed (mph)',fontsize=fs) plt.title('Wind Speed and Pressure at Thacher Observatory in '+str(year),fontsize=fs) plt.savefig('Wind'+tag+'_Pressure_'+str(year)+'.png',dpi=300) mpl.rcdefaults() return
# Get indices of 5 degree field pixsz = np.sqrt(header['CD1_1']**2 + header['CD1_2']**2) radpix = 2.5/pixsz ap = djs_photfrac(ypix,xpix,radpix,xdimen=xsz,ydimen=ysz) # Smooth image sigma = 2*radpix/2.355 if do_smooth: smooth = gaussian_filter(image,sigma) else: smooth = image # Image characteristics and plot sig = rb.std(smooth) med = np.median(smooth) vmin = med - 3*sig vmax = med + 5*sig plt.figure(1) plt.clf() plt.imshow(smooth,vmin=vmin,vmax=vmax,cmap='gist_heat',interpolation='nearest', \ origin='lower') plt.scatter(xpix,ypix,marker='+',s=100,facecolor='none',edgecolor='yellow', \ linewidth=1.5) plt.xlim(0,xsz) plt.ylim(0,ysz) plt.axis('off') plt.title('Field Center') plt.savefig('Center.png',dpi=300)
def master_bias(files, write=True, outdir='/', readnoise=False, clobber=False, verbose=True, float32=True, tag='', median=True): """ Overview: --------- Create master bias frame from series of biases (median filter). Returns a master_bias frame and writes FITS file to disk in specified directory. Optionally, the read noise is calculated from the variance of each pixel in the bias stack. This is *very* slow. So only use this option if you really need to. The readnoise image is also written to disk. Inputs: ------- files : List of flat field files from which a master bias will be created. Must be provided, no default. Keyword arguments: ------------------ write : Toggle to write files to disk (default True) outdir : Directory to which output files are written (default pwd) clobber : Toggle to overwrite files if they already exist in outdir (default False) readnoise : Do readnoise calculation (very slow! default False) verbose : Print out progress (default True) Calling sequence: ----------------- master_bias = master_bias(biasfiles,write=True,readnoise=False, outdir='/home/users/bob/stuff/') """ # Don't redo master_bias unless clobber keyword set name = outdir + 'master_bias_' + tag + '.fits' if len(glob.glob(name)) == 1 and not clobber: print("Master bias already exists!") master_bias = fits.getdata(name, 0, header=False) return master_bias # Get information from inputs and create stack array fct = len(files) image, header = fits.getdata(files[0], 0, header=True) ysz, xsz = image.shape stack = np.zeros((fct, ysz, xsz)) temps = [] hout = header # Load stack array and get CCD temperatures for i in np.arange(fct): output = '\nReading {}: frame {} of {} \r'.format(files[i].split('/')[-1], \ str(i + 1), str(fct)) sys.stdout.write(output) sys.stdout.flush() image, header = fits.getdata(files[i], 0, header=True) temps.append(header["CCD-TEMP"]) stack[i, :, :] = image # Calculate read noise directly from bias frames if prompted if readnoise: rn = np.zeros((ysz, xsz)) print("Starting readnoise calculation") pbar = tqdm(desc='Calculating readnoise', total=ysz, unit='rows') for i in np.arange(ysz): for j in np.arange(xsz): rn[i, j] = rb.std(stack[:, i, j]) pbar.update(1) # Make a nice plot (after all that hard work) aspect = np.float(xsz) / np.float(ysz) plt.figure(39, figsize=(5 * aspect * 1.2, 5)) plt.clf() sig = rb.std(rn) med = np.median(rn) mean = np.mean(rn) vmin = med - 2 * sig vmax = med + 2 * sig plt.imshow(rn, vmin=vmin, vmax=vmax, cmap='gist_heat', interpolation='nearest', origin='lower') plt.colorbar() plt.annotate(r'$\bar{\sigma}$ = %.2f cts' % mean, [0.95, 0.87], horizontalalignment='right', xycoords='axes fraction', fontsize='large') # path_effects=[PathEffects.SimpleLineShadow(linewidth=3,foreground="w")]) plt.annotate(r'med($\sigma$) = %.2f cts' % med, [0.95, 0.8], horizontalalignment='right', xycoords='axes fraction', fontsize='large') # path_effects=[PathEffects.withStroke(linewidth=3,foreground="w")]) plt.annotate(r'$\sigma_\sigma$ = %.2f cts' % sig, [0.95, 0.73], horizontalalignment='right', xycoords='axes fraction', fontsize='large') # path_effects=[PathEffects.withStroke(linewidth=3,foreground="w")]) plt.title("Read Noise") plt.xlabel("pixel number") plt.ylabel("pixel number") if write: plt.savefig(outdir + 'readnoise' + tag + '.png', dpi=300) # Calculate master bias frame by median filter print('Calculating median of stacked frames...') if median: master_bias = np.median(stack, axis=0) else: master_bias = np.mean(stack, axis=0) # Make a plot aspect = np.float(xsz) / np.float(ysz) plt.figure(38, figsize=(5 * aspect * 1.2, 5)) plt.clf() sig = rb.std(master_bias) med = np.median(master_bias) vmin = med - 2 * sig vmax = med + 2 * sig plt.imshow(master_bias, vmin=vmin, vmax=vmax, cmap='gist_heat', interpolation='nearest', origin='lower') plt.colorbar() plt.annotate('Bias Level = %.2f cts' % med, [0.95, 0.87], horizontalalignment='right', xycoords='axes fraction', fontsize='large', color='k') # path_effects=[PathEffects.withStroke(linewidth=3,foreground="w")]) plt.annotate(r'$\sigma$ = %.2f cts' % sig, [0.95, 0.8], horizontalalignment='right', xycoords='axes fraction', fontsize='large') # path_effects=[PathEffects.withStroke(linewidth=3,foreground="w")]) plt.annotate(r'$\langle T_{\rm CCD} \rangle$ = %.2f C' % np.median(temps), [0.95, 0.73], horizontalalignment='right', xycoords='axes fraction', fontsize='large') # path_effects=[PathEffects.withStroke(linewidth=3,foreground="w")]) plt.title("Master Bias") plt.xlabel("pixel number") plt.ylabel("pixel number") # Write out bias, readnoise and plot if write: name = outdir + 'master_bias_' + tag plt.savefig(name + '.png', dpi=300) # hout = fits.Header() hout['HISTORY'] = 'This is a median master' hout['MCCDTEMP'] = (np.median(temps), "Median CCD temperature") hout["TEMPSIG"] = (np.std(temps), "CCD temperature RMS") hout["MEDBIAS"] = (med, "Median bias level (cts)") hout["BIASSIG"] = (sig, "Bias RMS (cts)") if len(glob.glob(name + '.fits')) == 1: os.system('rm ' + name + '.fits') if float32: fits.writeto(name + '.fits', np.float32(master_bias), hout) else: fits.writeto(name + '.fits', master_bias, hout) if readnoise: name = outdir + 'readnoise' + tag if len(glob.glob(name + '.fits')) == 1: os.system('rm ' + name + '.fits') if float32: fits.writeto(name + '.fits', np.float32(rn), hout) else: fits.writeto(name + '.fits', rn, hout) return master_bias
def master_dark(files, bias=None, write=True, outdir='/', clobber=False, float32=True, tag='', median=True): """ Overview: --------- Create master dark frame from series of darks (median filter). Returns a master dark frame. If write is specified, a FITS file will be written to "outdir" (default is pwd). Inputs: ------- files : List of flat field files from which a master dark will be created. Must be provided, no default. Keyword arguments: ------------------ bias : Master bias frame (default None) write : Toggle to write files to disk (default True) outdir : Directory to which output files are written (default pwd) clobber : Toggle to overwrite files if they already exist in outdir (default False) Calling sequence: ----------------- master_dark = master_dark(darkfiles,bias=master_bias,write=True, outdir='/home/users/bob/stuff/') """ # Don't redo master_dark unless clobber keyword set name = outdir + 'master_dark_' + tag + '.fits' if len(glob.glob(name)) == 1 and not clobber: print("Master dark already exists!") master_dark = fits.getdata(name, 0, header=False) return master_dark # Get information from inputs and create stack array fct = len(files) image, header = fits.getdata(files[0], 0, header=True) ysz, xsz = image.shape stack = np.zeros((fct, ysz, xsz)) temps = [] exps = [] hout = header # Load stack array and get CCD temperatures for i in np.arange(fct): output = '\nReading {}: frame {} of {} \r'.format(files[i].split('/')[-1], \ str(i + 1), str(fct)) sys.stdout.write(output) sys.stdout.flush() image, header = fits.getdata(files[i], 0, header=True) exp = header["EXPOSURE"] exps.append(exp) temps.append(header["CCD-TEMP"]) # if length(bias) == 1: # image = np.float(image)/exp # ============================================================================= # else: # image = (image-bias)/exp # ============================================================================= stack[i, :, :] = image # Obtain statistics for the master dark image header # Temperature tmax = np.max(temps) tmin = np.min(temps) tmean = np.mean(temps) tmed = np.median(temps) tsig = np.std(temps) # Exposure times expmax = np.max(exps) expmin = np.min(exps) print('') print("Minimum CCD Temp. %.2f C" % tmin) print("Maximum CCD Temp. %.2f C" % tmax) print("CCD Temp. rms: %.3f C" % tsig) print("CCD Temp. mean: %.2f C" % tmean) print("CCD Temp. median: %.2f C" % tmed) # Create master dark by median filter or mean if median: master_dark = np.median(stack, axis=0) else: master_dark = np.mean(stack, axis=0) # Make a plot sig = rb.std(master_dark) med = np.median(master_dark) vmin = med - 2 * sig vmax = med + 2 * sig aspect = np.float(xsz) / np.float(ysz) plt.figure(37, figsize=(5 * aspect * 1.2, 5)) plt.clf() plt.imshow(master_dark, vmin=vmin, vmax=vmax, cmap='gist_heat', interpolation='nearest', origin='lower') plt.colorbar() plt.annotate('Dark Current = %.2f cts' % med, [0.72, 0.8], horizontalalignment='right', xycoords='figure fraction', fontsize='large') # path_effects=[PathEffects.withStroke(linewidth=3,foreground="w")]) plt.annotate(r'$\sigma$ = %.2f cts' % sig, [0.72, 0.75], horizontalalignment='right', xycoords='figure fraction', fontsize='large') # path_effects=[PathEffects.withStroke(linewidth=3,foreground="w")]) plt.annotate(r'$\langle T_{\rm CCD} \rangle$ = %.2f C' % np.median(temps), [0.72, 0.7], horizontalalignment='right', xycoords='figure fraction', fontsize='large') # path_effects=[PathEffects.withStroke(linewidth=3,foreground="w")]) plt.title("Master Dark") plt.xlabel("pixel number") plt.ylabel("pixel number") # Write out plot and master dark array if write: name = outdir + 'master_dark_' + tag plt.savefig(name + '.png', dpi=300) # hout = fits.Header() hout['HISTORY'] = 'This is a median master' hout["TEMPMAX"] = (tmax, "Maximum CCD temperature") hout["TEMPMIN"] = (tmin, "Minimum CCD temperature") hout["TEMPMED"] = (tmed, "Median CCD temperature") hout["TEMPMN"] = (tmean, "Mean CCD temperature") hout["TEMPSIG"] = (tsig, "CCD temperature RMS") hout["EXPMAX"] = (expmax, "Maximum exposure time") hout["EXPMIN"] = (expmin, "Minimum exposure time") hout["DARKCNT"] = (med, "Median dark current (cts)") hout["DARKSIG"] = (sig, "Dark current RMS (cts)") if len(glob.glob(name)) == 1: os.system('rm ' + name + '.fits') if float32: fits.writeto(name + '.fits', np.float32(master_dark), hout) else: fits.writeto(name + '.fits', master_dark, hout) return master_dark
def master_flat(files, bias=None, dark=None, write=True, outdir='/', tag='', clobber=False, stretch=3, float32=True, median=True): """ Overview: --------- Create a master flat using (optionally) a provided bias and dark frame. Output is written to "outdir" in FITS format. Inputs: ------- files : List of flat field files from which a master flat will be created. Must be provided, no default. Keyword arguments: ------------------ bias : Master bias frame (default None) dark : Master dark frame calibrated in ADU/sec (default None) band : Band from which flatis being produced write : Toggle to write files to disk (default True) outdir : Directory to which output files are written (default pwd) clobber : Toggle to overwrite files if they already exist in outdir (default False) stretch : Multiple of the noise RMS to stretch image (default 3) Calling sequence: ----------------- master_flat = master_flat(flatfiles,bias=master_bias,dark=master_dark,write=True, outdir='/home/users/bob/stuff/') """ # Don't redo master_flat unless clobber keyword set name = outdir + 'master_flat_' + tag + '.fits' if len(glob.glob(name)) == 1 and not clobber: print("Master flat already exists!") master_flat = fits.getdata(name, 0, header=False) return master_flat # Get information from inputs and create stack array fct = len(files) image, header = fits.getdata(files[0], 0, header=True) filter = header["filter"] ysz, xsz = image.shape stack = np.zeros((fct, ysz, xsz)) hout = header # Load stack array and get CCD temperatures meds = [] for i in np.arange(fct): output = '\nReading {}: frame {} of {} \r'.format(files[i].split('/')[-1], \ str(i + 1), str(fct)) sys.stdout.write(output) sys.stdout.flush() image, header = fits.getdata(files[i], 0, header=True) image = np.float32(image) if header["filter"] != filter: sys.exit("Filters do not match!") # ============================================================================= # if length(bias) > 1: # image -= bias # if length(dark) > 1: # exptime = header['EXPTIME'] # image -= dark*exptime # ============================================================================= meds.append(np.median(image)) # stack[i, :, :] = image / np.median(image) stack[i, :, :] = image # Obtain statistics for the master dark image header med = np.median(meds) sig = np.std(meds) # Create master flat by median filter if median: master_flat = np.median(stack, axis=0) else: master_flat = np.mean(stack, axis=0) # Make a plot sig = rb.std(master_flat) med = np.median(master_flat) vmin = med - stretch * sig vmax = med + stretch * sig aspect = np.float(xsz) / np.float(ysz) plt.figure(40, figsize=(5 * aspect * 1.2, 5)) plt.clf() plt.imshow(master_flat, vmin=vmin, vmax=vmax, cmap='gist_heat', interpolation='nearest', origin='lower') plt.colorbar() plt.title("Master Flat") plt.xlabel("pixel number") plt.ylabel("pixel number") # Write out plot and master flat array if write: plt.savefig(outdir + 'master_flat' + tag + '.png', dpi=300) # hout = fits.Header() hout['HISTORY'] = 'This is a median master' hout["FILTER"] = (filter, "Filter used when taking image") hout["MEDCTS"] = (med, "Median counts in individual flat frames") hout["MEDSIG"] = (sig, "Median count RMS in individual flat frames") # ============================================================================= # if length(bias) > 1: # hout.add_comment("Bias subtracted") # if length(dark) > 1: # hout.add_comment("Dark subtracted") # ============================================================================= if len(glob.glob(outdir + 'master_flat' + tag + '.fits')) == 1: os.system('rm ' + outdir + 'master_flat' + tag + '.fits') if float32: fits.writeto(outdir + 'master_flat_' + tag + '.fits', np.float32(master_flat), hout) else: fits.writeto(outdir + 'master_flat_' + tag + '.fits', master_flat, hout) return master_flat