def get_stats(): level_list = [4,5,6,7,8,9,10,11,12] fits_vals = np.array([]) fits_err = np.array([]) for level in level_list: fits_list = glob.glob('PD_{}_*_ds.fits'.format(level)) imarray = np.array([]) for image in fits_list: print image data = pyfits.open(image)[0].data center = ADE.centroid(data) dist = ADE.dist_gen(data,center) * 0.024 idx = np.where(dist < 6.75) fits_data = data[idx] imarray = np.append(imarray,np.mean(fits_data)) fits_vals = np.append(fits_vals,np.mean(imarray)) fits_err = np.append(fits_err,np.std(imarray)) return fits_vals, fits_err
def gen_resp(): # level_list = [4,5,6,7,8,9,10,11,12] level_list = [1,2,3,4,5,6,7] PD_vals = np.array([]) fits_vals = np.array([]) PD_err = np.array([]) fits_err = np.array([]) for level in level_list: PD_signal = np.loadtxt('PD_{}.txt'.format(level),usecols=(1,),unpack=True) fits_raw = pyfits.open('PD_{}_FINAL.fits'.format(level))[0].data center = ADE.centroid(fits_raw) dist = ADE.dist_gen(fits_raw,center) * 0.024 idx = np.where(dist < 6.75) fits_data = fits_raw[idx] PD_vals = np.append(PD_vals,np.mean(PD_signal)) PD_err = np.append(PD_err,np.std(PD_signal)) fits_vals = np.append(fits_vals,np.mean(fits_data)) fits_err = np.append(fits_err,np.std(fits_data)) level_vec = np.array(level_list)/12. fig = plt.figure() ax1 = fig.add_subplot(211) PD_plot = PD_vals/PD_vals[-1] PD_err_plot = PD_err/PD_vals[-1] fits_plot = fits_vals/fits_vals[-1] fits_err_plot = fits_err/fits_vals[-1] # ax1.errorbar(PD_vals,fits_vals,xerr=PD_err,yerr=fits_err,linestyle='x') ax1.plot(fits_vals,PD_vals,'.') # ax1.axhline(y=95693.7799/2,linestyle=':') # ax1.text(1.,95000,'Full Well') ax1.set_ylabel('PD Voltage') ax1.set_xlabel('CCD Mean Counts') # ax1.set_xscale('log') # ax1.set_yscale('log') ax2 = fig.add_subplot(212) ax2.plot(fits_vals,fits_vals/PD_vals,'.') ax2.set_xlabel('CCD Mean Counts') ax2.set_ylabel('CCD/PD') # ax2.set_xscale('log') # ax2.set_yscale('log') fig.show() return level_vec, fits_vals, fits_err, PD_vals, PD_err
def metatron(data, center, phi, dp, sp, pixelsize): ''' Description: metatron uses the relevant physical parameters from the laser bench setup and computes a transform that goes from the detector plane (what we measure) to the screen plane (what we want to measure). It is a helper function only intended to be called by fat_angel. Inputs: data - ndarray The data to be transformed. This is only used to make sure the transform has the right dimensions. center - Tuple The center of the ring in pixels phi - Float The angle between the detector normal and the screen normal in radians. dp - Float The distance from the center of the screen to the front glass of the camera lens, in millimeters. sp - Float The image distance given the object distance and lens focal length, in millimeters. pixelsize - Float The size of the detector pixels, in microns. Output: The output is a ndarray that contains the real physical distance of each pixel from the center of the ring at the SCREEN PLANE. In other words, all the pixels of the same value correspond to a perfect circle on the screen. ''' '''first get the distances in the detector plane''' r = ADE.dist_gen(data,center)*pixelsize alpha = ADE.angle_gen(data,center) '''now transform. See my notebook pages 101-103 for an explanation''' # den = sp**2*(np.cos(2*alpha) - 2*np.cos(alpha)**2*np.cos(2*phi))\ # + 4*r**2 - 3*sp**2 # bignum = 2*dp*r*(\ # (sp-r)*(sp+r)\ # *(3 + np.cos(2*phi) - 2*np.cos(2*alpha)*np.sin(phi)**2)\ # )**0.5 # t_dist = (4*dp*r**2*np.cos(alpha)*np.sin(phi) - bignum)/den den = sp*(np.cos(alpha)**2*np.cos(phi)**2 + np.sin(alpha)**2)**0.5 \ + r*np.cos(alpha)*np.sin(phi) t_dist = dp*r/den return t_dist
def zion(findstr, catfile, outstr, EXTEN=0): file_list = glob.glob(findstr) catData = np.loadtxt(catfile, skiprows=1) sort_idx = np.argsort(catData[:,0]) catData = catData[sort_idx] for i in range(len(file_list)): print(file_list[i]) hdu = pyfits.open(file_list[i]) image = hdu[EXTEN].data imAngle = hdu[EXTEN].header['ANGLE'] idx = np.where(catData[:,0] == imAngle)[0] radius = np.average(catData[:,3][idx]) width = np.average(catData[:,4][idx]) cent = ADE.centroid(image) dims = image.shape imRad = radius + width cutIm = image[cent[0] - imRad:cent[0] + imRad,\ cent[1] - imRad:cent[1] + imRad] bigIm = pl.imresize(cutIm, (1028,1028)) frameNumber = idx[0] name = str(frameNumber).zfill(3)+'_'+str(imAngle)+outstr+'.fits' if len(glob.glob(name)) == 0: pyfits.PrimaryHDU(bigIm).writeto(name) return
def format_data(data1, data2, dim): ''' format_data is used to take data from the laser bench and return specially formatted data for use by get_slope and get_shift. This program assumes that the [:,1] dimension of the data corresponds to ring radius and that the data contains both negative and positive angles. ''' (OneInTwo, TwoInOne) = ADE.multi_where(data1[:,0], data2[:,0]) data1Overlap = data1[OneInTwo] data2Overlap = data2[TwoInOne] data1GT = data1Overlap[:,dim][np.where(data1Overlap[:,0] >= 0)] data1LT = data1Overlap[:,dim][np.where(data1Overlap[:,0] < 0)] data2GT = data2Overlap[:,dim][np.where(data2Overlap[:,0] >= 0)] data2LT = data2Overlap[:,dim][np.where(data2Overlap[:,0] < 0)] data1GT.sort() data1LT.sort() data2GT.sort() data2LT.sort() return (np.array([data1GT, data2GT]), np.array([data1LT,data2LT]))
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 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 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 find_offset_old(self,datafile, nonlinmin, nonlinmax, exclude, threshold): '''find_offset is used to determine the systematic offset present in the experimental setup that causes data to not be symmetric about zero input angle. It reads in the output of laserBench and returns the offset (in degrees)''' input_a, output_a = np.loadtxt(datafile,usecols=(0,1),unpack=True) for e in exclude: did = np.where(input_a == e) output_a = np.delete(output_a, did) input_a = np.delete(input_a, did) pidx = np.where(input_a > nonlinmax) nidx = np.where(input_a < nonlinmin) in_a = np.append(input_a[nidx],input_a[pidx]) out_a = np.append(-1*output_a[nidx],output_a[pidx]) error = np.zeros(in_a.size)+1 b = 1000. offset = 0. while abs(b) > threshold: m, b = ADE.fit_line(in_a,out_a,error) offset += b in_a += b return offset
def jump_test(inifile): ''' to be run in /d/monk/eigenbrot/MANGA/20121015 ''' options = ConfigParser() options.read(inifile) finald = [] for d in ['d1','d2','d3','d4']: nood = N(options) nood.get_darks() nood.fill_dict(d,nood.direct) nood.sub_darks(nood.direct) nood.ratios = {'direct': {'data': {'V':{}}}} nood.direct_to_ratios(nood.direct) nood.combine() finald.append(nood.ratios['direct']['data']['V']['direct']['final']) os.system('rm *_ds.fits') print "reduction finished" countarr = np.array([]) voltarr = np.array([]) pot = thePot(options) for image in finald: hdu = pyfits.open(image)[0] fits_raw = hdu.data center = ADE.centroid(fits_raw) dist = ADE.dist_gen(fits_raw,center) * 0.024 idx = np.where(dist < 6.75) fits_data = fits_raw[idx] countarr = np.append(countarr,np.mean(fits_data)) stime = hdu.header['STARTIME'] etime = hdu.header['ENDTIME'] voltage = pot.get_voltage(stime,etime,'V') voltarr = np.append(voltarr,voltage) print "\nImage :{:>15}{:>15}{:>15}{:>15}\nCounts :{:15.3E}{:15.3E}{:15.3E}{:15.3E}\nVoltage:{:15.2f}{:15.2f}{:15.2f}{:15.2f}".format(*finald+countarr.tolist()+voltarr.tolist()) print "-"*(4*15+8) print "Ratio :{:15.3E}{:15.3E}{:15.3E}{:15.3E}\n".format(*(countarr/voltarr).tolist()) return countarr, voltarr, countarr/voltarr
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 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 disc2rings(image,angles): HDU = pyfits.open(image)[0] data = np.float32(HDU.data) FL = HDU.header['FOCALLEN'] print FL dims = data.shape cent = ADE.centroid(data) dist = ADE.dist_gen(data,cent) ring_stack = np.zeros((1,dims[0],dims[1]),dtype=np.float32) sangles = np.sort(angles) sangles *= np.pi/180 for i in range(sangles.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 print r1, r2, r2 - r1 idx = np.where((dist > r1) & (dist <= r2)) temp = np.zeros(dims,dtype=np.float32) temp[idx] = data[idx] ring_stack = np.vstack((ring_stack,np.array([temp]))) return ring_stack[1:]
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 sodom(findstr, exten=0): angles = {} file_list = glob.glob(findstr) for image in file_list: angle = pyfits.open(image)[exten].header['ANGLE'] if angle not in angles.keys(): angles[angle] = [] angles[angle].append(image) iraf.imcombine.combine = 'average' iraf.imcombin.reject = 'none' for theta in angles.keys(): if angles[theta][0].find('../') > -1: s = 3 else: s = 0 name = 'final_'+angles[theta][0][s:angles[theta][0].rfind('_')]+'.fits' iraf.imcombine(','.join([s+'['+str(exten)+']' for s in angles[theta]]),name) ADE.mediclean(name,name) return
def clean_VI(searchstr): """Takes FITS files generated by LabView and: 1) Poor man's bkgrnd subtraction with ADE.mediclean 2) Sets the Primary Hdu to 0 instead of LabView's 1 """ in_files = glob(searchstr) for image in in_files: HDU = pyfits.open(image)[1] cleaned_data = ADE.mediclean(HDU.data[220:870,290:960]) clean_name = image.split('.fits')[0].split('/')[-1] + '.cleaned.fits' pyfits.PrimaryHDU(cleaned_data,HDU.header).writeto(clean_name) return
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 cent_test(data,phi,dp,sp,pixelsize): ''' Description: cent_test really trys hard to find the center of a ring image that has been disorted because it is on a screen. It uses your favorite non-derivative minimization algorithm to find where the FWHM of the annulized ring is smallest. The logic here is that as we go off center the FWHM gets larger because each TRUE ring annulus is sampled at a few differet radii. The reason we can't use a trasform produced by metatron is that the transform itself is heavily dependant on knowing the correct center. Inputs: data - ndarray The ring data phi - Float The angle between the detector normal and the screen normal, in radians. dp - Float The distance from the screen center to the front glass of the camera lens, in millimeters. sp - Float The image distance of the lense, in millimeters. Output: A tuple containing the x and y coordinates of the best fit center, in pixel units. ''' 'a centroid is still a good starting point' cent = ADE.centroid(data) if debug: print "initial center: "+str(cent[0])+','+str(cent[1]) '''here is where the actual minimization happens, the values for xtol and ftol were chosen with speed in mind (also, we don't really need precision to better than 0.1 pixels).''' lstsq = spo.fmin_powell(func,np.array([cent[0],cent[1]])\ ,args=(data,phi,dp,sp,pixelsize)\ ,xtol=0.01,ftol=0.01) return lstsq
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 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 find_offset(self,datafile, nonlinmin, nonlinmax, exclude, threshold): input_a, output_a = np.loadtxt(datafile,usecols=(0,1),unpack=True) for e in exclude: did = np.where(input_a == e) output_a = np.delete(output_a, did) input_a = np.delete(input_a, did) pidx = np.where(input_a > nonlinmax) nidx = np.where(input_a < nonlinmin) in_a = np.append(input_a[nidx],input_a[pidx]) out_a = np.append(-1*output_a[nidx],output_a[pidx]) e = np.zeros(in_a.size)+1 b = 1000. offset = 0. while abs(b) > threshold: m, b = ADE.fit_line(in_a,out_a,e) offset += b in_a += b return offset
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
return np.array([rarr,outarr,stdarr]) @jit(argtypes=[int16],restype=float32[:]) def test(num): 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)
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 kegstand(searchstr,EEfigs,Nfig,EE=0.50): """Given an input list of fits files this function will try to compute the f-ratio of the SDSS test stand input beam. """ R = np.array([]) dprime = np.array([]) pp = PDF(EEfigs) pp2 = PDF(Nfig) in_files = glob(searchstr) for image in in_files: print image HDU = pyfits.open(image)[0] dp = float(image.split('_')[1].split('.fits')[0]) dprime = np.append(dprime, dp) radius = get_radius(HDU.data,pp,EE) R = np.append(R, radius) print "d: {:4.3f}, R: {:4.3f}".format(dp,radius) dprime *= -1 # Ns = np.array([]) # for k in range(numtrys): # sampleidx = np.random.randint(dprime.size, size = dprime.size) # tempdp = dprime[sampleidx] # tempR = R[sampleidx] # Ns = np.append(Ns, # (2.*ADE.polyclip(tempdp,tempR,1,niter=10).c[0])**-1) fit_coef = ADE.polyclip(dprime,R,1,niter=10).c slope = fit_coef[0] ### compute the uncertainty N = (2.*slope)**-1 # N = np.mean(Ns) # N_err = np.std(Ns) Nfit = np.poly1d(fit_coef) fitd = np.linspace(dprime.min(),dprime.max(),50) ### compute the uncertainty see = (np.sum((R - np.polyval(fit_coef,dprime))**2)/(R.size - 2))**0.5 slope_err = see * (1/(np.sum((dprime - np.mean(dprime))**2)))**0.5 N_err = slope_err/(2.*slope**2) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(dprime,R,marker='s',linestyle='') ax.plot(fitd,Nfit(fitd),'k:',label='linear fit') ax.set_xlabel("$-d^'$ [mm]") ax.set_ylabel('$R$ [mm]') ax.legend(loc=0) ax.set_title('{}\nN: {:3.2f}$\pm$ {:3.2f}'.\ format(datetime.now().isoformat(' '),N,N_err)) pp2.savefig(fig) pp.close() pp2.close() return N, N_err