示例#1
0
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
示例#2
0
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)
示例#3
0
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
示例#4
0
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)
示例#5
0
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
示例#6
0
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)
示例#7
0
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()
示例#8
0
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()
示例#9
0
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()
示例#10
0
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
示例#11
0
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:])
示例#12
0
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
示例#13
0
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])
示例#14
0
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])
示例#15
0
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
示例#16
0
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
示例#17
0
    
    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 *