def chimap(x0,x1): chi = np.empty((x0.size,x1.size)) fiber_list = ['300_1P.2P_RF3f.fits','300_1P.2P_RF42f.fits','300_1P.2P_RF63f.fits','300_1P.2P_RF135f.fits'] radii = np.empty((1,num_ap)) powers = np.empty((1,num_ap)) for fiber in fiber_list: data = pyfits.open(fiber)[0].data r,p = ADE.annulize(data,num_ap) radii = np.vstack((radii,r)) powers = np.vstack((powers,p/np.sum(p))) radii = radii[1:] powers = powers[1:] for i in range(x0.size): print str(i) for j in range(x1.size): print ' '+str(j) chi[i,j] = func((x0[i],x1[j]),radii,powers) return x0,x1,chi
def scales(initial): global X0, X1, CH # X0 = X1 = CH = np.array([]) fiber_list = ['300_1P.2P_RF3f.fits','300_1P.2P_RF42f.fits','300_1P.2P_RF63f.fits','300_1P.2P_RF135f.fits'] radii = np.empty((1,num_ap)) powers = np.empty((1,num_ap)) for fiber in fiber_list: data = pyfits.open(fiber)[0].data r,p = ADE.annulize(data,num_ap) radii = np.vstack((radii,r)) powers = np.vstack((powers,p/np.sum(p))) radii = radii[1:] powers = powers[1:] x0 = np.array(initial) print "starting minimization" xf = spo.fmin(func,x0,args=(radii,powers),xtol=0.0001,ftol=0.00001) return (xf)
def omnom(fitsfile,pp,EEcut=0.5,fitsexten=0): data = pyfits.open(fitsfile)[fitsexten].data r, sb, err = ADE.annulize(data,300) # r *= 0.024 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.5) ax.plot(fitr,fitEE,':') 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.3*r1) ax.set_title('{}\nr: {:3.2f} mm'.format(fitsfile,r1)) pp.savefig(fig) return r1
def disc2rings(image,angles,dscale): '''takes a image and splits it into rings of constant thickness. The rings are centered at the angles specified in angles and the output rings are flattened azimuthally.''' HDU = pyfits.open(image)[0] data = np.float32(HDU.data) FL = HDU.header['FOCALLEN'] length = num_ap r, f = ADE.annulize(data,length) print 'sum of data: '+str(np.sum(f)) '''convert the pixel radii to output angle''' a = np.arctan(r*pixelsize/FL)*180/np.pi*dscale ring_stack = np.zeros((1,length),dtype=np.float32) sangles = np.sort(angles) for i in range(sangles.size): a_mid = sangles[i] '''the next few lines define the range of angles on either side of the requested angle we should use and deals with exceptions that happen at the smallest and largest angles.''' if i == 0: a0_mid = -1*sangles[i] else: a0_mid = sangles[i-1] try: a2_mid = sangles[i+1] except IndexError:a2_mid = a_mid + (a_mid - a0_mid) a1 = (a_mid + a0_mid)/2 if i == 0: amin = a1 a2 = (a_mid + a2_mid)/2 idx = np.where((a > a1) & (a <= a2)) counts = np.mean(f[idx]) '''sometimes the range of angles is so small that the mean is nan. we change that to 0''' if np.isnan(counts): counts = 0 fi = np.zeros(length) fi[idx] = counts ring_stack = np.vstack((ring_stack,np.array([fi]))) midx = np.where(a >= amin)[0][0] output_rings = ring_stack[1:] output_rings *= np.sum(f[midx:])/np.sum(output_rings) print 'sum of model: '+str(np.sum(output_rings)) return (a,output_rings)
def func(p,data,phi,dp,sp,pixelsize): '''func is the function to be minimized by get_cent. It returns the value of the FWHM''' '''seems a little dumb to essentially have to run the entire reduction routine every iteration, but that's just life I guess.''' t_dist = metatron(data,(p[0],p[1]),phi,dp,sp,pixelsize) (r,f) = ADE.annulize(data,90,distances=t_dist) (_,r1,r2) = find_peak(r,f) diff = r2 - r1 return diff
def diff_trend(images, angle_vecs, power_vecs): fiber_powers = np.empty((1,300)) for i in range(len(images)): data = pyfits.open(images[i])[0].data r, p = ADE.annulize(data,num_ap) p /= np.sum(p) pangles = np.arctan(r*pixelsize/FL)*180./np.pi ip = np.interp(angle_vecs[i],pangles,p) fiber_powers = np.vstack((fiber_powers,ip)) fiber_powers = fiber_powers[1:] for power in power_vecs: power /= np.sum(power) print fiber_powers.shape print power_vecs.shape return np.sum(np.abs(fiber_powers - power_vecs),axis=1)
def plot_smear(rings,title): FL = 50.0 pangles = np.zeros(300) powers = np.zeros(300) for i in range(rings.shape[0]): print i r,f = ADE.annulize(rings[i],300) powers += f pangles = np.arctan(r*24e-3/FL)*180/np.pi # for i in range(angles.size): # r_mid = FL*np.tan(sangles[i])/24e-3 # # if i == 0: r0_mid = -1*FL*np.tan(sangles[i])/24e-3 # else: r0_mid = FL*np.tan(sangles[i-1])/24e-3 # # try:r2_mid = FL*np.tan(sangles[i+1])/24e-3 # except IndexError:r2_mid = r_mid + (r_mid - r0_mid) # # r1 = (r_mid + r0_mid)/2 # r2 = (r_mid + r2_mid)/2 # # #for plotting # a1 = np.arctan(r1*24e-3/FL)*180/np.pi # a2 = np.arctan(r2*24e-3/FL)*180/np.pi # pangles = np.append(pangles,np.linspace(a1,a2,num=100,endpoint=False)) # powers = np.append(powers,np.zeros(100)+np.sum(rings[i])) fig = plt.figure(3) plt.clf() ax = fig.add_subplot('111') ax.plot(pangles,powers) ax.set_xlabel('Angle [deg]') ax.set_ylabel('Power') ax.set_xlim(0,18) ax.set_title(title) fig.show()
def plot_data(im_name,title,clear,dscale,fnum=1): '''plots the power profile of some image in some specified figure number''' data = pyfits.open(im_name)[0].data r,f = ADE.annulize(data,num_ap) f /= np.sum(f) pangles = np.arctan(r*pixelsize/FL)*180./np.pi*dscale fig = plt.figure(fnum) if clear: plt.clf() ax = fig.add_subplot('111') ax.plot(pangles,f) ax.set_xlabel('Output Angle [deg]') ax.set_ylabel('Normalized Power') ax.set_xlim(0,18) ax.set_title(title) fig.show()
def plot_data(im_name,title,fnum=1): FL = 50.0 data = pyfits.open(im_name)[0].data r,f = ADE.annulize(data,num_ap) f /= np.sum(f) pangles = np.arctan(r*24e-3/FL)*180/np.pi fig = plt.figure(fnum) plt.clf() ax = fig.add_subplot('111') ax.plot(pangles,f) ax.set_xlabel('Angle [deg]') ax.set_ylabel('Normalized Power') ax.set_xlim(0,18) ax.set_title(title) fig.show()
def nomlom(fitsfile,x,fitsexten=0): data = pyfits.open(fitsfile)[0].data r, sb, err = ADE.annulize(data,300) # r *= 0.024 flux = np.cumsum(sb) EE = flux/flux.max() radii = np.array([]) print ' Extracting radii for EE = 1/x:' for i in x: print '\tx = {:n}'.format(i) targetEE = 1./i radii = np.append(radii,np.interp(targetEE,EE,r)) return radii
def disc2rings(image,angles): HDU = pyfits.open(image)[0] data = np.float32(HDU.data) FL = HDU.header['FOCALLEN'] length = num_ap r, f = ADE.annulize(data,length) a = np.arctan(r*24e-3/FL)*180/np.pi ring_stack = np.zeros((1,length),dtype=np.float32) sangles = np.sort(angles) # sangles *= np.pi/180 for i in range(sangles.size): a_mid = sangles[i] if i == 0: a0_mid = -1*sangles[i] else: a0_mid = sangles[i-1] try: a2_mid = sangles[i+1] except IndexError:a2_mid = a_mid + (a_mid - a0_mid) a1 = (a_mid + a0_mid)/2 a2 = (a_mid + a2_mid)/2 idx = np.where((a > a1) & (a <= a2)) counts = np.mean(f[idx]) fi = np.zeros(length) fi[idx] = counts ring_stack = np.vstack((ring_stack,np.array([fi]))) return (a,ring_stack[1:])
def plot_all(x0,x1,sl=None): print x0, x1 direct_list = ['300_RF3d.fits','300_RF42d.fits','300_RF63d.fits','300_RF135d.fits'] fiber_list = ['300_1P.2P_RF3f.fits','300_1P.2P_RF42f.fits','300_1P.2P_RF63f.fits','300_1P.2P_RF135f.fits'] fig = plt.figure(5) plt.clf() for i in range(len(fiber_list)): a,_,_,comb,_ = sauron(direct_list[i],'full_better8.4.11',\ '20110624_better8.4.11.dat',\ x0,x1,exclude=[-17.0,1.5]) if sl: print sl[i][0], sl[i][1] a2,_,_,comb2,_ = sauron(direct_list[i],'full_better8.4.11',\ '20110624_better8.4.11.dat',\ sl[i][0],sl[i][1],exclude=[-17.0,1.5]) data = pyfits.open(fiber_list[i])[0].data r,f = ADE.annulize(data,num_ap) f /= np.sum(f) pangles = np.arctan(r*pixelsize/FL)*180./np.pi*x0 if sl: pangles2 = np.arctan(r*pixelsize/FL)*180./np.pi*sl[i][0] ax = fig.add_subplot(2,2,i+1) ax.plot(pangles,f,a,comb/comb.sum()) if sl: ax.plot(pangles2,f,'b--',a2,comb2/comb2.sum(),'g--') ax.set_xlabel('Output Angle [deg]') ax.set_ylabel('Power') ax.set_title(direct_list[i]) plt.suptitle(time.asctime(time.localtime())) fig.show() return
def fat_angel(findstr, num_ap, EXTEN=0, OUTPUT=0, PIXELPITCH=1, FIBERSIZE=500): ''' Description: Fat_angel is deisgned to process a large number of data from the laser bench. It takes an input string, findstr, and computes the width and radius of the ring in each data image. Surface brightness profiles are found using Annulize in the ADEUtils package with the number of annuli specfied in the num_ap input. Output can be directed to a file for plotting bliss. Inputs: findstr- Str A string containing the names of the data files to use. Wildcards are allowed so you can chose a single file or as many as want. Files are assumed to be FITS files. num_ap - Int The number of annuli to use when constructing the surface brightness profile. EXTEN - Int The FITS extension where the primary data is stored. As of right now there is no way to specify different extensions for different files. OUTPUT - Str Name of output file. Output contains angle, ring radius, and ring width in column form PIXELPITCH - Float Size of the camera pixels in micrometers. This is only used to get the correct scale on the debug plots. Output: Output is a tuple of Numpy vectors containing angle, ring radius, and ring width. Example: Assume you have a bunch of data called X_red.fits where X is some data iterator. >>lb.fat_angel('*_red.fits',150,EXTEN=1,OUTPUT='my_data.dat') ''' file_list = glob.glob(findstr) numfiles = len(file_list) 'initialize some data arrays' widths = np.zeros(numfiles) radii = np.zeros(numfiles) angles = np.zeros(numfiles) r1_vec = np.zeros(numfiles) r2_vec = np.zeros(numfiles) frd_widths = np.zeros(numfiles) xcent = np.zeros(numfiles) ycent = np.zeros(numfiles) t1 = time.time() for i in range(numfiles): print(file_list[i]) ADE.mediclean(file_list[i],'clean'+file_list[i],exten=EXTEN) huds = pyfits.open('clean'+file_list[i]) data = huds[EXTEN].data 'get the angle from the FITS header. MUCH easier in python than IDL!' angles[i] = huds[EXTEN].header['ANGLE'] '''poor man's background subtraction''' mode = ADE.mode(data)[0][0] if debug: print 'Mode = '+str( mode) 'Annulize!' if debug: fig0 = plt.figure(0) plt.clf() t0 = time.time() (r_vec,fluxes,center) = ADE.annulize(data,num_ap,NOREAD=1)#,MODE=mode) print "Annulize took "+str(time.time() - t0)+" seconds" plt.plot(r_vec*PIXELPITCH,fluxes) fig0.show() else: (r_vec,fluxes,center) = ADE.annulize(data,num_ap,NOREAD=1)#,MODE=mode) '''Compute the cdf from the pdf (fluxes). Working with the CDF allows us to assume that the annulus is gaussian-ish without having to worry about the particulars''' (rm_idx,r1,r2) = find_peak(r_vec,fluxes) rm = r_vec[rm_idx] # r1 = r_vec[r1_idx] # r2 = r_vec[r2_idx] 'Now deconvolve and find the width of the FRD smearing kernel' # (frd_width,frd) = decon(r_vec,fluxes,rm_idx,r2,r1,FIBERSIZE,PIXELPITCH) # global frd_sav # frd_sav = frd if debug: fig1 = plt.figure(fignum) plt.clf() sp0 = fig1.add_subplot(222) sp0.plot(r_vec*PIXELPITCH, np.cumsum(fluxes)/np.max(np.cumsum(fluxes))) sp0.axvline(x=rm*PIXELPITCH,ls='--',lw=0.3) sp0.axvline(x=r1*PIXELPITCH,ls='--',lw=0.3) sp0.axvline(x=r2*PIXELPITCH,ls='--',lw=0.3) sp0.set_xlabel("Radius (um)") sp0.set_ylabel("% of total counts") sp0.set_title("Normalized CDF") # plt.figure(0) sp1 = fig1.add_subplot(221) sp1.plot(r_vec*PIXELPITCH,fluxes) sp1.axvline(x=rm*PIXELPITCH,ls='--',lw=0.3) sp1.axvline(x=r1*PIXELPITCH,ls='--',lw=0.3) sp1.axvline(x=r2*PIXELPITCH,ls='--',lw=0.3) sp1.set_xlabel("Radius (um)") sp1.set_ylabel("Counts") sp1.set_title("Ring Profile") # sp2 = fig1.add_subplot(224) # sp2.plot(r_vec*PIXELPITCH, frd) # sp2.set_xlabel("Radius (um)") # sp2.set_ylabel("??") # sp2.set_title("FRD kernel") plt.suptitle("Angle = "+str(angles[i])+" degrees\n"+file_list[i]) fig1.show() print "Center: "+str(center) if numfiles > 1: raw_input("press enter to continue...\n") widths[i] = r2 - r1 radii[i] = rm r1_vec[i] = r1 r2_vec[i] = r2 # frd_widths[i] = frd_width xcent[i] = center[0] ycent[i] = center[1] print "Total annulize time was "+str(time.time()-t1)+" seconds" 'We sort the data just make the output a little more readable' sort_idx = np.argsort(angles) widths *= PIXELPITCH radii *= PIXELPITCH r1_vec *= PIXELPITCH r2_vec *= PIXELPITCH frd_widths *= PIXELPITCH if OUTPUT: f = open(OUTPUT, 'w') f.write('#angle radius width r1 r2 frd width center\n') for i in range(angles.shape[0]): np.array([angles[sort_idx][i], radii[sort_idx][i], widths[sort_idx][i], r1_vec[sort_idx][i], r2_vec[sort_idx][i], frd_widths[sort_idx][i], xcent[sort_idx][i], ycent[sort_idx][i]]).\ tofile(f, sep=' ',format='%3.4f') f.write('\n') return (angles[sort_idx], radii[sort_idx], widths[sort_idx], r1_vec[sort_idx], r2_vec[sort_idx], frd_widths[sort_idx], xcent[sort_idx], ycent[sort_idx])
def fat_angel(findstr, num_ap, phi, dp, f, exten=0, output=0, pixelpitch=1, fibersize=500): ''' Description: fat_angel is deisgned to process a large number of data from the laser bench. It takes an input string, findstr, and computes the width and radius of the ring in each data image. The images are first cleaned using a median subtraction algorithm, which assumes that your S/N is very good. Surface brightness profiles are found using Annulize in the ADEUtils package with the number of annuli specfied in the num_ap input. Output can be directed to a file for plotting bliss. Inputs: findstr- Str A string containing the names of the data files to use. Wildcards are allowed so you can chose a single file or as many as want. Files are assumed to be FITS files. num_ap - Int The number of annuli to use when constructing the surface brightness profile. phi - Float The angle between the screen normal and the detector normal in RADIANS. dp - Float The distance, in millimeters, from the center of the screen to the front glass of the camera lens. f - Float The nominal focal length of the camera lens in millimeters. Read this number off of the lens body. exten - Int The FITS extension where the primary data is stored. As of right now there is no way to specify different extensions for different files. output - Str Name of output file. Output contains angle, ring radius, and ring width in column form pixelpitch - Float Size of the camera pixels in micrometers. Output: Output is a tuple of Numpy vectors that each contain the folling info: Field: Description: 0 input angle 1 ring radius (mm) 2 ring width (mm) 3 inner ring radius (mm) 4 outer ring radius (mm) 5,6 the x and y coordinates of the ring center (pixels) Example: Assume you have a bunch of data called X_red.fits where X is some data iterator. >>lb.fat_angel('*_red.fits',150,0.319,1084,26,exten=1,output='my_data.dat') ''' file_list = glob.glob(findstr) numfiles = len(file_list) 'initialize some data arrays' widths = np.zeros(numfiles) radii = np.zeros(numfiles) angles = np.zeros(numfiles) r1_vec = np.zeros(numfiles) r2_vec = np.zeros(numfiles) xcent = np.zeros(numfiles) ycent = np.zeros(numfiles) t1 = time.time() for i in range(numfiles): print(file_list[i]) huds = pyfits.open(file_list[i]) data = np.float32(huds[exten].data) 'get the angle from the FITS header. MUCH easier in python than IDL!' angles[i] = huds[exten].header['ANGLE'] '''get rid of the background noise with mediclean. This algorithm is very good if you have bodacious S/N''' data = ADE.mediclean(data) '''given the nominal focal length, f, and object distance, dp, we can approximate the image distance, sp, using the thin lens eq.''' sp = (1/float(f) - 1/float(dp))**-1 '''find the center of the image by minimizing the reported ring width''' center = cent_test(data,phi,dp,sp,pixelpitch) # center = ADE.centroid(data) '''t_dist holds the transformation from the detector space to screen space''' t_dist = metatron(data,center,phi,dp,sp,pixelpitch) 'Annulize!' if debug: t0 = time.time() (r_vec,fluxes) = ADE.annulize(data,num_ap,distances=t_dist) print "Annulize took "+str(time.time() - t0)+" seconds" else: (r_vec,fluxes) = ADE.annulize(data,num_ap,distances=t_dist) '''find_peak uses the CDF of the fluxes to find the peak and interpolation to find the limits of the FWHM. Working with the CDF allows us to assume that the annulus is gaussian-ish without having to worry about the particulars''' (rm_idx,r1,r2) = find_peak(r_vec,fluxes) rm = r_vec[rm_idx] if debug: '''plot a bunch of stuff''' fig1 = plt.figure(fignum) plt.clf() sp0 = fig1.add_subplot(212) sp0.plot(r_vec, np.cumsum(fluxes)/np.max(np.cumsum(fluxes))) sp0.axvline(x=rm,ls='--',lw=0.3) sp0.axvline(x=r1,ls='--',lw=0.3) sp0.axvline(x=r2,ls='--',lw=0.3) sp0.set_xlabel("Radius (mm)") sp0.set_ylabel("% of total counts") sp0.set_title("Normalized CDF") sp1 = fig1.add_subplot(211) sp1.plot(r_vec,fluxes) sp1.axvline(x=rm,ls='--',lw=0.3) sp1.axvline(x=r1,ls='--',lw=0.3) sp1.axvline(x=r2,ls='--',lw=0.3) sp1.set_xlabel("Radius (mm)") sp1.set_ylabel("Counts") sp1.set_title("Ring Profile") plt.suptitle("Angle = "+str(angles[i])+" degrees\n"+file_list[i]) fig1.show() print "Center: "+str(center) if numfiles > 1: raw_input("press enter to continue...\n") widths[i] = r2 - r1 radii[i] = rm r1_vec[i] = r1 r2_vec[i] = r2 xcent[i] = center[0] ycent[i] = center[1] print "Total annulize time was "+str(time.time()-t1)+" seconds" 'We sort the data by angle to make the output a little more readable' sort_idx = np.argsort(angles) if output: f = open(output, 'w') f.write('#angle radius width r1 r2 center\n') for i in range(angles.shape[0]): np.array([angles[sort_idx][i], radii[sort_idx][i], widths[sort_idx][i], r1_vec[sort_idx][i], r2_vec[sort_idx][i], xcent[sort_idx][i], ycent[sort_idx][i]]).\ tofile(f, sep=' ',format='%3.4f') f.write('\n') return (angles[sort_idx], radii[sort_idx], widths[sort_idx], r1_vec[sort_idx], r2_vec[sort_idx], xcent[sort_idx], ycent[sort_idx])
def FReD(direct_image, fiber_image, num_ap, OUTPUT=0, FL=50, FR=4.2): ''' 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 - 4.28.2011 - Corrected a slight error in the fiber correction calculation. Instead of f_r_c = f_r - abs(x - y) we have f_r_c = f_r - (y - x). This shouldn't make too much of a difference b/c usually y > x. ''' 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 (d_rvec, d_sb) = ADE.annulize(direct_image,num_ap,EXTEN=exten) (f_rvec, f_sb) = ADE.annulize(fiber_image,num_ap,EXTEN=exten) '''Turn pixels into an physical length. The SBIG STL-1001E has 24 micron square pixels''' d_rvec *= 0.024 #-> mm f_rvec *= 0.024 d_flux = np.cumsum(d_sb) f_flux = np.cumsum(f_sb) '''Now we normalize the fluxes so we are talking about EE, the enclosed energy''' print np.max(d_flux)/np.max(f_flux) d_EE = d_flux/np.max(d_flux) f_EE = f_flux/np.max(f_flux) '''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) 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 '''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 ((f_rvec[k]**2 - f_r_correction[k])**0.5) <\ ((f_rvec[k-1]**2 - f_r_correction[k-1])**0.5): 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 ############# '''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 ################## '''Grab some information about the data for the header''' try: filt = pyfits.open(direct_image)[exten].header['FILTER'] except KeyError: filt = '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' +'# Focal length and beam speed: '+str(FL)+'mm '+str(FR)+'\n' +'# Filter: '+filt+'\n' +'# Polish: '+polish+'\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
def fat_angel(name, num_ap, phi, dp, f, fsg, pixelpitch, exten, q, lock): ''' Description: fat_angel is deisgned to process a large number of data from the laser bench. It takes an input string, findstr, and computes the width and radius of the ring in each data image. The images are first cleaned using a median subtraction algorithm, which assumes that your S/N is very good. Surface brightness profiles are found using Annulize in the ADEUtils package with the number of annuli specfied in the num_ap input. Output can be directed to a file for plotting bliss. Inputs: findstr- Str A string containing the names of the data files to use. Wildcards are allowed so you can chose a single file or as many as want. Files are assumed to be FITS files. num_ap - Int The number of annuli to use when constructing the surface brightness profile. phi - Float The angle between the screen normal and the detector normal in RADIANS. dp - Float The distance, in millimeters, from the center of the screen to the front glass of the camera lens. f - Float The nominal focal length of the camera lens in millimeters. Read this number off of the lens body. exten - Int The FITS extension where the primary data is stored. As of right now there is no way to specify different extensions for different files. output - Str Name of output file. Output contains angle, ring radius, and ring width in column form pixelpitch - Float Size of the camera pixels in micrometers. Output: Output is a tuple of Numpy vectors that each contain the folling info: Field: Description: 0 input angle 1 ring radius (mm) 2 ring width (mm) 3 inner ring radius (mm) 4 outer ring radius (mm) 5,6 the x and y coordinates of the ring center (pixels) Example: Assume you have a bunch of data called X_red.fits where X is some data iterator. >>lb.fat_angel('*_red.fits',150,0.319,1084,26,exten=1,output='my_data.dat') ''' print name huds = pyfits.open(name) data = np.float32(huds[exten].data) 'get the angle from the FITS header. MUCH easier in python than IDL!' angle = huds[exten].header['ANGLE'] '''get rid of the background noise with mediclean. This algorithm is very good if you have bodacious S/N''' data = ADE.mediclean(data) '''given the nominal focal length, f, and object distance, dp, we can approximate the image distance, sp, using the thin lens eq.''' sp = (1/float(f) - 1/float(dp))**-1 '''find the center of the image by minimizing the reported ring width''' center = cent_test(data,phi,dp,sp,pixelpitch) #slow and right # center = ADE.centroid(data) #fast and wrong '''t_dist holds the transformation from the detector space to screen space''' t_dist = metatron(data,center,phi,dp,sp,pixelpitch) 'Annulize!' (r_vec,fluxes,errors) = ADE.annulize(data,num_ap,distances=t_dist) '''find_peak uses the CDF of the fluxes to find the peak and interpolation to find the limits of the FWHM. Working with the CDF allows us to assume that the annulus is gaussian-ish without having to worry about the particulars''' (rp,r1,r2) = find_peak(r_vec,fluxes) ap = np.arctan(rp/fsg)*180/np.pi a1 = np.arctan(r1/fsg)*180/np.pi a2 = np.arctan(r2/fsg)*180/np.pi awidth = a2 - a1 rwidth = r2 - r1 xcent = center[0] ycent = center[1] if full_output: 'write power profile info for use by theModule' if not os.path.exists(full_dir): os.makedirs(full_dir) angs = np.arctan(r_vec/fsg)*180/np.pi write_full(angs,fluxes,angle,ap) q.put((angle,ap,rp,awidth,rwidth,r1,r2,xcent,ycent)) return
l = np.array([],dtype=np.float32) for i in range(num): l = np.append(l,i) # x = np.array(l,dtype=np.float32) return l print 'Running test...' data = pyfits.open('scratch/test.fits')['SB'].data ddata = np.array(data,dtype=np.float32) cent = ADE.centroid(ddata) dist = ADE.dist_gen(ddata,cent) at1 = time.time() aderes = ADE.annulize(ddata,300) at2 = time.time() nt1 = time.time() nres = numba_cent(ddata,dist,dist.max(),300) nt2 = time.time() print np.mean(nres - aderes,axis=1) print np.std(nres - aderes,axis=1) print 'ADE time was: {:4.5f} s\nNumba time was: {:4.5f} s'.format(at2 - at1, nt2-nt1) # numba_cent(24) # from numba import *