def ratio_test(t_file,data_path): T = thePot(t_file) fits_list = glob(data_path+'/*.FIT') volts = np.array([]) counts = np.array([]) for fits in fits_list: print fits, HDU = pyfits.open(fits)[0] exptime = HDU.header['EXPTIME'] timestr = HDU.header['TIME-OBS'] obstime = np.float(timestr[6:])\ + np.float(timestr[3:5])*60.\ + np.float(timestr[0:2])*3600. voltage = T.get_voltage(obstime,obstime+exptime,'V') r, sb, e = ADE.fast_annulize(HDU.data,300) r *= 0.024 flux = np.cumsum(sb) rate = flux/exptime ADU = np.interp(54/10.,r,rate) print voltage, ADU volts = np.append(volts,voltage) counts = np.append(counts,ADU) fit = ADE.fit_line(volts,counts,np.ones(counts.shape)) print fit fig = plt.figure() ax = fig.add_subplot(111) ax.plot(volts,counts,'.') ax.set_xlabel('Voltage') ax.set_ylabel('ADU/s') fig.show()
def get_radius(data,pp,EEcut): """Takes in a 2D numpy array and computes the radius of the beam profile. This function uses a parabola fit to find the true beam radius. """ r, sb, err = ADE.fast_annulize(data,300) r *= 0.0044 flux = np.cumsum(sb) EE = flux/flux.max() cutr = np.where(EE >= EEcut)[0][0] EEfit = np.poly1d(np.polyfit(r[:cutr],EE[:cutr],2)) fitr = np.linspace(r.min(),r.max(),500) fitEE = EEfit(fitr) r1 = np.interp(1.0,fitEE,fitr) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(r,EE,marker='.',linestyle='',markersize=0.7) ax.plot(fitr,fitEE,'-',alpha=0.4) ax.set_xlabel('r [mm]') ax.set_ylabel('EE') ax.axvline(r1,linestyle='-',alpha=0.4) ax.axhline(1.0,linestyle=':',color='k',alpha=0.2) ax.set_ylim(0,1.1) # ax.set_xlim(0,1.5*r1) ax.set_title('r: {:3.2f} mm'.format(r1)) if pp: pp.savefig(fig) return r1
def FReD(direct_image, fiber_image, num_ap, pot, filt, dir_cut,\ EXTEN=0, OUTPUT=0, FL=50, FR=4.2, FP='99,99',FO='-99'): ''' Description: FReD is primary reduction tool for the FRD Bench. It takes in two images, one for the direct beam and one for the fiber beam, and produces outputs suitable for FRD analysis. The main tasks that FReD performs are: 1) Producing curves of growth that show the enclosed energy as a function of radius 2) Correcting both beam's data for effects that make the direct beam non-ideal 3) Computing effective f-ratios for each beam. The effective f-ratio is the f-ratio an ideal lens would have if its enclosed energy was EE(r) at r. Input: direct_image - str The name of the FITS file containing the direct beam data fiber_image - stf The name of the FITS file containing the fiber beam data num_ap - Int The number of apertures to use in creating the curve of growth EXTEN - Int The FITS extension where the primary data is storred. This must be the same for both the direct and fiber beams OUTPUT - str The name of the output file. FReD produce no output besides this file, so if you don't set it then nothing will happen. FL - Float The focal length of the lens used (L2) FR - Float The focal ratio (f-number) of the lens used Output: The only output produced by FReD is the output file specified by the OUTPUT keyword. This file is a bunch of vectors suitable for plotting by an external package, like supermongo. See the output file header for more information on the file's contents. Version History: 1.0 - 1.12.2011 1.1 - 1.13.2011 - Changed from appetize to annulize_sb followed by a cumsum. 1.2 - 1.17.2011 - Changed to a corrected version of annulize (not annulize_sb). The correction accounts for incomplete data at large radii without having to use surface brightness. 1.3 - 10.2011 - Added FRD metrics ''' version = 1.3 # Shit's gonna get real real later on with variable names # just remember that d_ is for variables relating to the direct beam # and f_ is for variables relating to the fiber beam. # # Comments preceded by '#' relate to variable naming conventions direct_HDU = pyfits.open(direct_image)[EXTEN] fiber_HDU = pyfits.open(fiber_image)[EXTEN] d_exptime = direct_HDU.header['EXPTIME'] f_exptime = fiber_HDU.header['EXPTIME'] direct = direct_HDU.data fiber = fiber_HDU.data direct[np.where(direct < dir_cut)] = 0.0 if pot: # direct_time_str = direct_HDU.header['TIME-OBS'] # fiber_time_str = fiber_HDU.header['TIME-OBS'] # direct_time = np.float(direct_time_str[6:])\ # + np.float(direct_time_str[3:5])*60.\ # + np.float(direct_time_str[0:2])*3600. # fiber_time = np.float(fiber_time_str[6:])\ # + np.float(fiber_time_str[3:5])*60.\ # + np.float(fiber_time_str[0:2])*3600. # fcorrect = pot.get_correction(fiber_time,filt) # dcorrect = pot.get_correction(direct_time,filt) direct_start_time = direct_HDU.header['STARTIME'] direct_end_time = direct_HDU.header['ENDTIME'] fiber_start_time = fiber_HDU.header['STARTIME'] fiber_end_time = fiber_HDU.header['ENDTIME'] # filt = 'V' pot.set_ref(filt,direct_start_time,direct_end_time) dcorrect = pot.get_correction2(direct_start_time,direct_end_time,filt) fcorrect = pot.get_correction2(fiber_start_time,fiber_end_time,filt) print ' Direct throughput correction is '+str(dcorrect) print ' Fiber throughput correction is '+str(fcorrect) direct *= dcorrect fiber *= fcorrect if debug: pot.plot(filt,[direct_start_time,direct_end_time,fiber_start_time,fiber_end_time]) raw_input(' Tput plots...') if debug: print ' Annulizing...' d_rvec, d_sb, d_sberr = ADE.fast_annulize(direct,num_ap) f_rvec, f_sb, f_sberr = ADE.fast_annulize(fiber,num_ap) if debug: plt.clf() fig = plt.figure(0) ax1 = fig.add_subplot(221) ax1.plot(d_rvec,d_sb) ax1.plot(f_rvec,f_sb) ax1.set_xlabel('Radius [px]') ax1.set_ylabel('Counts [ADU]') fig.show() raw_input(' hit enter or something') '''Turn pixels into an physical length. The SBIG STL-1001E has 24 micron square pixels''' d_rvec *= 0.024 #-> mm f_rvec *= 0.024 if debug: print ' Cumsumming...' d_flux = np.cumsum(d_sb) f_flux = np.cumsum(f_sb) d_ferr = (np.cumsum(d_sberr**2))**0.5 f_ferr = (np.cumsum(f_sberr**2))**0.5 if debug: ax2 = fig.add_subplot(222) ax2.plot(d_rvec, d_flux) ax2.plot(f_rvec, f_flux) ax2.set_xlabel('Radius [mm]') ax2.set_ylabel('Cumulative flux [ADU]') fig.show() raw_input(' Cumsum') '''Now we normalize the fluxes so we are talking about EE, the enclosed energy''' if debug: print ' EEing...' d_max = np.max(d_flux) f_max = np.max(f_flux) d_EE = d_flux/d_max f_EE = f_flux/f_max '''we'll use f_EE_nd for plotting later''' f_EE_nd = f_flux/d_max # d_fmaxerr = d_ferr[np.where(d_flux == d_max)[0]] # f_fmaxerr = f_ferr[np.where(f_flux == f_max)[0]] # d_EEerr = ((d_ferr/d_max)**2 + (d_fmaxerr*d_flux/(d_max**2))**2)**0.5 # f_EEerr = ((f_ferr/f_max)**2 + (f_fmaxerr*f_flux/(f_max**2))**2)**0.5 '''Now we need to use the difference between an ideal beam and the direct beam (which should be ideal) to create a correction that we can apply to both the direct and fiber data''' # _correction will correspond to corrections that will be applied to # get corrected values and _c will correspond to values that have # been corrected f_r_correction = np.zeros(f_EE.size,dtype=float) d_r_c = np.zeros(d_EE.size,dtype=float) if debug: print ' Correcting...' j=0 for k in range(f_r_correction.size): # Naming conventions here match what is in my notebook on pages # 47 through 51 '''First the direct beam''' d_r_c[k] = (d_EE[k]*(FL/(2*FR))**2)**0.5 '''Now the fiber beam''' f_r_i = (f_EE[k]*(FL/(2*FR))**2)**0.5 '''find the closest d_EE value that is less than f_EE[k]''' while d_EE[j] < f_EE[k]: j += 1 '''interpolate''' m = (d_EE[j] - d_EE[j-1])/(d_rvec[j] - d_rvec[j-1]) r_d = (f_EE[k] - d_EE[j-1])/m + d_rvec[j-1] '''f_dr2 is f_dr**2''' f_dr2 = r_d**2 - f_r_i**2 f_r_correction[k] = f_dr2 # if debug: print (f_rvec[k]**2 - f_r_correction[k])**0.5, f_rvec[k]**2, f_r_correction[k] '''We do this to fix some weirdness that might happen at really large radii. It's more of a visual appeal thing than anything else''' if (np.abs(f_rvec[k]**2 - f_r_correction[k]))**0.5 <\ (np.abs(f_rvec[k-1]**2 - f_r_correction[k-1]))**0.5 \ or (f_rvec[k]**2 - f_r_correction[k]) < 0: # if debug: print ' here' f_r_correction[k] = f_r_correction[k-1] '''Actually perform the correction on the fiber data''' f_r_c = (f_rvec**2 - f_r_correction)**0.5 d_rerr = (np.abs(d_r_c - d_rvec))**0.5 f_rerr = (np.abs(f_r_c - f_rvec))**0.5 # if debug: print (np.abs(f_r_c - f_rvec))**0.5 ################ if debug: print ' Computing...' '''For the various plots we want to make we need to have the f-numbers which is pretty easy b/c it only depends on radius''' # N stands for f-number, a la my notes d_N = FL/(2*d_rvec) f_N = FL/(2*f_rvec) d_N_c = FL/(2*d_r_c) f_N_c = FL/(2*f_r_c) '''We also need the EFFECTIVE f-number, which is the what the f-number of the lens in an ideal system would be if the enclosed energy was EE[k] at r[k]''' #_e is for an effective quantity d_N_e = d_N*(d_EE)**0.5 f_N_e = f_N*(f_EE)**0.5 d_N_e_c = d_N_c*(d_EE)**0.5 f_N_e_c = f_N_c*(f_EE)**0.5 ################## '''Before we go any further we will compute some metrics of throughput. For this we'll first need to put fluxes in units of counts/time so that different exposure times do not affect the result''' d_ADUrate = d_flux/d_exptime f_ADUrate = f_flux/f_exptime '''We will compute the relative ADU/time at various percentages of the total''' tput_100 = float(f_ADUrate.max() / d_ADUrate.max()) testtput = f_ADUrate[-1] / d_ADUrate[-1] print "Tput_100 is {}\nTest is {}".format(tput_100,testtput) rf5 = FL/10. rf4 = FL/8. rf32 = FL/6.4 rf3 = FL/6. rf47 = FL/9.4 # rf42 = FL/8.4 # rf4 = FL/8. # rf38 = FL/7.6 # rf3 = FL/6. rf_input = FL/(2.*FR) if rf4 > f_r_c.max(): print "Max fiber radius reached at f/4. ({} > {})".format(rf4, f_r_c.max()) # d_ADU_input = np.interp(rf_input,d_rvec,d_ADUrate) d_ADU_input = d_ADUrate.max() # tput_f5 = np.interp(rf5,f_r_c,f_ADUrate)/d_ADUf5 # tput_f4 = np.interp(rf4,f_r_c,f_ADUrate)/d_ADUf4 # tput_f5b = np.interp(rf5,f_r_c,f_EE) # tput_f4b = np.interp(rf4,f_r_c,f_EE) f_ADUf5 = np.interp(rf5,f_rvec,f_ADUrate) f_ADUf4 = np.interp(rf4,f_rvec,f_ADUrate) f_ADUf3 = np.interp(rf3,f_rvec,f_ADUrate) f_ADUf32 = np.interp(rf32,f_rvec,f_ADUrate) f_ADUf47 = np.interp(rf47,f_rvec,f_ADUrate) tput_f5 = f_ADUf5/d_ADU_input tput_f4 = f_ADUf4/d_ADU_input tput_f3 = f_ADUf3/d_ADU_input tput_f32 = f_ADUf32/d_ADU_input tput_f47 = f_ADUf47/d_ADU_input # f_ADUf42 = np.interp(rf42,f_rvec,f_ADUrate) # f_ADUf4 = np.interp(rf4,f_rvec,f_ADUrate) # f_ADUf38 = np.interp(rf38,f_rvec,f_ADUrate) # f_ADUf3 = np.interp(rf3,f_rvec,f_ADUrate) # tput_f42 = f_ADUf42/d_ADU_input # tput_f4 = f_ADUf4/d_ADU_input # tput_f38 = f_ADUf38/d_ADU_input # tput_f3 = f_ADUf3/d_ADU_input tput_f5b = np.interp(rf5,f_rvec,f_EE) tput_f4b = np.interp(rf4,f_rvec,f_EE) r_ideal = FL/(2*FR) r_ideal_test = d_r_c[np.where(f_ADUrate == f_ADUrate.max())[0]] metric = np.interp(r_ideal, f_r_c, f_EE) metric80 = FL/(2*np.interp(0.82,f_EE,f_r_c)) metric90 = FL/(2*np.interp(0.9,f_EE,f_r_c)) if debug: try: direct_V = pot.get_voltage(direct_start_time,direct_end_time,filt) fiber_V = pot.get_voltage(fiber_start_time,fiber_end_time,filt) except KeyError: direct_V,drawV = (1.0,1.0) fiber_V,frawV = (1.0,1.0) ax3 = fig.add_subplot(223) ax3.plot(f_rvec,f_ADUrate,'g') ax3.plot(d_rvec,d_ADUrate,'b') ax3.set_xlabel('Radius [mm]') ax3.set_ylabel('Count rate [ADU/s]') ax3.axvline(ls=':',x=rf32,color='b') ax3.axvline(ls='--',x=rf32,color='g') ax3.axvline(ls=':',x=rf4,color='k') ax3.axvline(ls=':',x=rf5,color='k') ax3.axhline(ls='--',y=sloanf,color='g') ax3.axhline(ls=':',y=sloand,color='b') infostr = "\tFiber ratio at f/3.2 ({:}mm): {:8.4E}".format(rf32,sloanf/fiber_V)+\ "\n\tDirect ratio at f/3.2 ({}mm): {:8.4E}".format(rf32,sloand/direct_V)+\ "\n\tFiber counts/s at (f/4, f/5): ({:8.4E}, {:8.4E})".format(f_ADUf4,f_ADUf5)+\ "\n\tDirect counts/s at (f/4, f/5): ({:8.4E}, {:8.4E})".format(d_ADUf4,d_ADUf5)+\ "\n\tFiber voltages are : {:4.4f}".format(fiber_V)+\ "\n\tDirect voltages are : {:4.4f}".format(direct_V)+\ "\n\tSloan metric is {}".format(sloan_m)+\ "\n\tFull direct is: {:8.4E}".format(float(d_ADUrate.max()))+\ "\n\tMax d_r_c value is: {:4.2f}".format(d_r_c.max())+\ "\n\tr_ideal is: {:4.2f}".format(r_ideal)+\ "\n\tr_max is: {}".format(r_ideal_test) ax3.text(1.1,0.4,infostr,transform=ax3.transAxes,ha='left',va='center') print infostr fig.suptitle('{} - {}'.format(os.popen('pwd').readlines()[0],datetime.now().isoformat(' '))) fig.show() raw_input(" ADUrate") ################## '''Grab some information about the data for the header''' try: filt = pyfits.open(direct_image)[EXTEN].header['FILTER'] except KeyError: filt = 'NA' try: fiber = pyfits.open(direct_image)[EXTEN].header['OBSERVER'] except KeyError: fiber = 'NA' try: polish = pyfits.open(direct_image)[EXTEN].header['TELESCOP'] except KeyError: polish = 'NA' if OUTPUT: f = open(OUTPUT,'w') f.write('# Generated by FReD v.'+str(version)+'\n' +'# Output writen on: '+datetime.now().isoformat(' ')+'\n' +'# Input file (direct beam): '+direct_image+'\n' +'# Input file (fiber beam): '+fiber_image+'\n' +'# Number of apertures: '+str(num_ap)+'\n' +'# Focal length and beam speed: '+str(FL)+'mm '+str(FR)+'\n' +'# Filter: '+filt+'\n' +'# Fiber input position: '+FP+'\n' +'# Fiber output position: '+FO+'\n' +'# Harness: '+polish+'\n' +'# Total Throughput: '+str(tput_100)+'\n' +'# Direct image cutoff: '+str(dir_cut)+'\n' +'#\n' +'# d_r = aperture radius of direct beam (mm)\n' +'# f_r = aperture radius of fiber beam (mm)\n' +'# d_N = f-ratio of direct beam\n' +'# f_N = f-ratio of fiber beam\n' +'# d_r_c = corrected direct beam radius (mm)\n' +'# f_r_c = corrected fiber beam radius (mm)\n' +'# d_N_c = corrected direct f-ratio\n' +'# f_N_c = corrected fiber f-ratio\n' +'# d_EE = normalized enclosed energy of direct beam\n' +'# f_EE = normalized enclosed energy of fiber beam\n' +'# d_N_e = effective f-ratio for direct beam\n' +'# f_N_e = effective f-ratio for fiber beam\n' +'# d_N_e_c = effective f-ratio for corrected direct beam\n' +'# f_N_e_c = effective f-ratio for corrected fiber beam\n' +'#\n' +'# d_r f_r d_N f_N d_r_c' +' f_r_c d_N_c f_N_c d_EE f_EE' +' d_N_e f_N_e d_N_e_c f_N_e_c\n' +'# 1 2 3 4 5' +' 6 7 8 9 10' +' 11 12 13 14\n') for i in range(min(d_rvec.size,f_rvec.size)): np.array([d_rvec[i], f_rvec[i], d_N[i], f_N[i], d_r_c[i], f_r_c[i], d_N_c[i], f_N_c[i], d_EE[i], f_EE[i], d_N_e[i], f_N_e[i], d_N_e_c[i], f_N_e_c[i]]).tofile(f,sep=' ',format='%9.3E') f.write('\n') f.close() return ((metric90,metric80,tput_100,tput_f5,tput_f47, tput_f4,tput_f32,tput_f3,tput_f5b,tput_f4b),(d_N,d_N_c,f_N,f_N_c,d_EE,f_EE,f_EE_nd))