Пример #1
0
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()
Пример #2
0
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
Пример #3
0
def FReD(direct_image, fiber_image, num_ap, pot, filt, dir_cut,\
             EXTEN=0, OUTPUT=0, FL=50, FR=4.2, FP='99,99',FO='-99'):
    '''
    Description:
        FReD is primary reduction tool for the FRD Bench. It takes in two
        images, one for the direct beam and one for the fiber beam, and
        produces outputs suitable for FRD analysis. The main tasks that
        FReD performs are:
            1) Producing curves of growth that show the enclosed energy
            as a function of radius
            
            2) Correcting both beam's data for effects that make the
            direct beam non-ideal
            
            3) Computing effective f-ratios for each beam. The effective
            f-ratio is the f-ratio an ideal lens would have if its enclosed
            energy was EE(r) at r.

     Input:
         direct_image - str
             The name of the FITS file containing the direct beam data
         fiber_image  - stf
             The name of the FITS file containing the fiber beam data
         num_ap - Int
             The number of apertures to use in creating the curve of growth
         EXTEN  - Int
             The FITS extension where the primary data is storred. This
             must be the same for both the direct and fiber beams
         OUTPUT - str
             The name of the output file. FReD produce no output besides
             this file, so if you don't set it then nothing will happen.
         FL     - Float
             The focal length of the lens used (L2)
         FR     - Float
             The focal ratio (f-number) of the lens used

     Output:
         The only output produced by FReD is the output file specified by the
         OUTPUT keyword. This file is a bunch of vectors suitable for plotting
         by an external package, like supermongo. See the output file header
         for more information on the file's contents.
     
     Version History:
         1.0 - 1.12.2011
         1.1 - 1.13.2011 - Changed from appetize to annulize_sb followed
                           by a cumsum.
         1.2 - 1.17.2011 - Changed to a corrected version of annulize (not
                           annulize_sb). The correction accounts for
                           incomplete data at large radii without having
                           to use surface brightness.
         1.3 - 10.2011   - Added FRD metrics
     '''


    version = 1.3
    # Shit's gonna get real real later on with variable names
    # just remember that d_ is for variables relating to the direct beam
    # and f_ is for variables relating to the fiber beam.
    #
    # Comments preceded by '#' relate to variable naming conventions
    
    direct_HDU = pyfits.open(direct_image)[EXTEN]
    fiber_HDU = pyfits.open(fiber_image)[EXTEN]
    
    d_exptime = direct_HDU.header['EXPTIME']
    f_exptime = fiber_HDU.header['EXPTIME']    
    
    direct = direct_HDU.data
    fiber = fiber_HDU.data
    
    direct[np.where(direct < dir_cut)] = 0.0
    
    if pot:
        # direct_time_str = direct_HDU.header['TIME-OBS']
        # fiber_time_str = fiber_HDU.header['TIME-OBS']

        # direct_time = np.float(direct_time_str[6:])\
        #     + np.float(direct_time_str[3:5])*60.\
        #     + np.float(direct_time_str[0:2])*3600.

        # fiber_time = np.float(fiber_time_str[6:])\
        #     + np.float(fiber_time_str[3:5])*60.\
        #     + np.float(fiber_time_str[0:2])*3600.
        
        # fcorrect = pot.get_correction(fiber_time,filt)
        # dcorrect = pot.get_correction(direct_time,filt)
        direct_start_time = direct_HDU.header['STARTIME']
        direct_end_time = direct_HDU.header['ENDTIME']
        fiber_start_time = fiber_HDU.header['STARTIME']
        fiber_end_time = fiber_HDU.header['ENDTIME']
        
#        filt = 'V'

        pot.set_ref(filt,direct_start_time,direct_end_time)

        dcorrect = pot.get_correction2(direct_start_time,direct_end_time,filt)
        fcorrect = pot.get_correction2(fiber_start_time,fiber_end_time,filt)
        print '   Direct throughput correction is '+str(dcorrect)
        print '   Fiber throughput correction is '+str(fcorrect)
        
        direct *= dcorrect
        fiber *= fcorrect
        
        if debug: 
            pot.plot(filt,[direct_start_time,direct_end_time,fiber_start_time,fiber_end_time])
            raw_input('    Tput plots...')


    if debug: print '    Annulizing...'
    d_rvec, d_sb, d_sberr = ADE.fast_annulize(direct,num_ap)
    f_rvec, f_sb, f_sberr = ADE.fast_annulize(fiber,num_ap)

    if debug:
        plt.clf()
        fig = plt.figure(0)
        ax1 = fig.add_subplot(221)
        ax1.plot(d_rvec,d_sb)
        ax1.plot(f_rvec,f_sb)
        ax1.set_xlabel('Radius [px]')
        ax1.set_ylabel('Counts [ADU]')
        fig.show()
        raw_input('     hit enter or something')

    '''Turn pixels into an physical length. The SBIG STL-1001E has 24 micron
    square pixels'''
    d_rvec *= 0.024 #-> mm
    f_rvec *= 0.024

    if debug: print '    Cumsumming...'
    d_flux = np.cumsum(d_sb)
    f_flux = np.cumsum(f_sb)
    d_ferr = (np.cumsum(d_sberr**2))**0.5
    f_ferr = (np.cumsum(f_sberr**2))**0.5

    if debug:
        ax2 = fig.add_subplot(222)
        ax2.plot(d_rvec, d_flux)
        ax2.plot(f_rvec, f_flux)
        ax2.set_xlabel('Radius [mm]')
        ax2.set_ylabel('Cumulative flux [ADU]')
        fig.show()
        raw_input('     Cumsum')
        

    '''Now we normalize the fluxes so we are talking about EE, the enclosed
    energy'''
    if debug: print '    EEing...'
    d_max = np.max(d_flux)
    f_max = np.max(f_flux)
    d_EE = d_flux/d_max
    f_EE = f_flux/f_max
    '''we'll use f_EE_nd for plotting later'''
    f_EE_nd = f_flux/d_max
#    d_fmaxerr = d_ferr[np.where(d_flux == d_max)[0]]
#    f_fmaxerr = f_ferr[np.where(f_flux == f_max)[0]]
#    d_EEerr = ((d_ferr/d_max)**2 + (d_fmaxerr*d_flux/(d_max**2))**2)**0.5
#    f_EEerr = ((f_ferr/f_max)**2 + (f_fmaxerr*f_flux/(f_max**2))**2)**0.5

    '''Now we need to use the difference between an ideal beam and the direct
    beam (which should be ideal) to create a correction that we can apply
    to both the direct and fiber data'''
    
    # _correction will correspond to corrections that will be applied to
    # get corrected values and _c will correspond to values that have 
    # been corrected
    
    f_r_correction = np.zeros(f_EE.size,dtype=float)
    d_r_c = np.zeros(d_EE.size,dtype=float)

    if debug: print '    Correcting...'
    j=0
    for k in range(f_r_correction.size):
        # Naming conventions here match what is in my notebook on pages
        # 47 through 51
        
        '''First the direct beam'''
        d_r_c[k] = (d_EE[k]*(FL/(2*FR))**2)**0.5
        
        '''Now the fiber beam'''
        f_r_i = (f_EE[k]*(FL/(2*FR))**2)**0.5

        '''find the closest d_EE value that is less than f_EE[k]'''
        while d_EE[j] < f_EE[k]: j += 1
 
        '''interpolate'''
        m = (d_EE[j] - d_EE[j-1])/(d_rvec[j] - d_rvec[j-1])
        r_d = (f_EE[k] - d_EE[j-1])/m + d_rvec[j-1]

        '''f_dr2 is f_dr**2'''
        f_dr2 = r_d**2 - f_r_i**2
        f_r_correction[k] = f_dr2

#        if debug: print (f_rvec[k]**2 - f_r_correction[k])**0.5, f_rvec[k]**2, f_r_correction[k]

        '''We do this to fix some weirdness that might happen at really large
        radii. It's more of a visual appeal thing than anything else'''
        if (np.abs(f_rvec[k]**2 - f_r_correction[k]))**0.5 <\
                (np.abs(f_rvec[k-1]**2 - f_r_correction[k-1]))**0.5 \
                or (f_rvec[k]**2 - f_r_correction[k]) < 0:
#            if debug: print ' here'
            f_r_correction[k] = f_r_correction[k-1]

    '''Actually perform the correction on the fiber data'''
    f_r_c = (f_rvec**2 - f_r_correction)**0.5

    d_rerr = (np.abs(d_r_c - d_rvec))**0.5
    f_rerr = (np.abs(f_r_c - f_rvec))**0.5
    
#    if debug: print (np.abs(f_r_c - f_rvec))**0.5

    ################

    if debug: print '    Computing...'
    '''For the various plots we want to make we need to have the f-numbers
    which is pretty easy b/c it only depends on radius'''
    # N stands for f-number, a la my notes
    d_N = FL/(2*d_rvec)
    f_N = FL/(2*f_rvec)
    d_N_c = FL/(2*d_r_c)
    f_N_c = FL/(2*f_r_c)

    '''We also need the EFFECTIVE f-number, which is the what the f-number
    of the lens in an ideal system would be if the enclosed energy was 
    EE[k] at r[k]'''
    #_e is for an effective quantity
    d_N_e = d_N*(d_EE)**0.5
    f_N_e = f_N*(f_EE)**0.5
    d_N_e_c = d_N_c*(d_EE)**0.5
    f_N_e_c = f_N_c*(f_EE)**0.5

    ##################

    '''Before we go any further we will compute some metrics of throughput.
    For this we'll first need to put fluxes in units of counts/time so that
    different exposure times do not affect the result'''
    
    d_ADUrate = d_flux/d_exptime
    f_ADUrate = f_flux/f_exptime

    '''We will compute the relative ADU/time at various percentages of the
    total'''
    
    tput_100 = float(f_ADUrate.max() / d_ADUrate.max())
    testtput = f_ADUrate[-1] / d_ADUrate[-1]

    print "Tput_100 is {}\nTest is {}".format(tput_100,testtput)

    rf5 = FL/10.
    rf4 = FL/8.
    rf32 = FL/6.4
    rf3 = FL/6.
    rf47 = FL/9.4
    # rf42 = FL/8.4
    # rf4 = FL/8.
    # rf38 = FL/7.6
    # rf3 = FL/6.
    rf_input = FL/(2.*FR)

    if rf4 > f_r_c.max():
        print "Max fiber radius reached at f/4. ({} > {})".format(rf4, f_r_c.max())

#    d_ADU_input = np.interp(rf_input,d_rvec,d_ADUrate)
        
    d_ADU_input = d_ADUrate.max()

    # tput_f5 = np.interp(rf5,f_r_c,f_ADUrate)/d_ADUf5
    # tput_f4 = np.interp(rf4,f_r_c,f_ADUrate)/d_ADUf4
    # tput_f5b = np.interp(rf5,f_r_c,f_EE)
    # tput_f4b = np.interp(rf4,f_r_c,f_EE)

    f_ADUf5 = np.interp(rf5,f_rvec,f_ADUrate)
    f_ADUf4 = np.interp(rf4,f_rvec,f_ADUrate)
    f_ADUf3 = np.interp(rf3,f_rvec,f_ADUrate)
    f_ADUf32 = np.interp(rf32,f_rvec,f_ADUrate)
    f_ADUf47 = np.interp(rf47,f_rvec,f_ADUrate)

    tput_f5 = f_ADUf5/d_ADU_input
    tput_f4 = f_ADUf4/d_ADU_input
    tput_f3 = f_ADUf3/d_ADU_input
    tput_f32 = f_ADUf32/d_ADU_input
    tput_f47 = f_ADUf47/d_ADU_input

    # f_ADUf42 = np.interp(rf42,f_rvec,f_ADUrate)
    # f_ADUf4 = np.interp(rf4,f_rvec,f_ADUrate)
    # f_ADUf38 = np.interp(rf38,f_rvec,f_ADUrate)
    # f_ADUf3 = np.interp(rf3,f_rvec,f_ADUrate)

    # tput_f42 = f_ADUf42/d_ADU_input
    # tput_f4 = f_ADUf4/d_ADU_input
    # tput_f38 = f_ADUf38/d_ADU_input
    # tput_f3 = f_ADUf3/d_ADU_input

    tput_f5b = np.interp(rf5,f_rvec,f_EE)
    tput_f4b = np.interp(rf4,f_rvec,f_EE)
        
    r_ideal = FL/(2*FR)
    r_ideal_test = d_r_c[np.where(f_ADUrate == f_ADUrate.max())[0]]
    metric = np.interp(r_ideal, f_r_c, f_EE)
    metric80 = FL/(2*np.interp(0.82,f_EE,f_r_c))
    metric90 = FL/(2*np.interp(0.9,f_EE,f_r_c))
    
    if debug:
        try:
            direct_V = pot.get_voltage(direct_start_time,direct_end_time,filt)
            fiber_V = pot.get_voltage(fiber_start_time,fiber_end_time,filt)
        except KeyError:
            direct_V,drawV = (1.0,1.0)
            fiber_V,frawV = (1.0,1.0)
        ax3 = fig.add_subplot(223)
        ax3.plot(f_rvec,f_ADUrate,'g')
        ax3.plot(d_rvec,d_ADUrate,'b')
        ax3.set_xlabel('Radius [mm]')
        ax3.set_ylabel('Count rate [ADU/s]')
        ax3.axvline(ls=':',x=rf32,color='b')
        ax3.axvline(ls='--',x=rf32,color='g')
        ax3.axvline(ls=':',x=rf4,color='k')
        ax3.axvline(ls=':',x=rf5,color='k')
        ax3.axhline(ls='--',y=sloanf,color='g')
        ax3.axhline(ls=':',y=sloand,color='b')
        infostr = "\tFiber ratio at f/3.2 ({:}mm): {:8.4E}".format(rf32,sloanf/fiber_V)+\
            "\n\tDirect ratio at f/3.2 ({}mm): {:8.4E}".format(rf32,sloand/direct_V)+\
            "\n\tFiber counts/s at (f/4, f/5): ({:8.4E}, {:8.4E})".format(f_ADUf4,f_ADUf5)+\
            "\n\tDirect counts/s at (f/4, f/5): ({:8.4E}, {:8.4E})".format(d_ADUf4,d_ADUf5)+\
            "\n\tFiber voltages are : {:4.4f}".format(fiber_V)+\
            "\n\tDirect voltages are : {:4.4f}".format(direct_V)+\
            "\n\tSloan metric is {}".format(sloan_m)+\
            "\n\tFull direct is:  {:8.4E}".format(float(d_ADUrate.max()))+\
            "\n\tMax d_r_c value is: {:4.2f}".format(d_r_c.max())+\
            "\n\tr_ideal is: {:4.2f}".format(r_ideal)+\
            "\n\tr_max is: {}".format(r_ideal_test)
        ax3.text(1.1,0.4,infostr,transform=ax3.transAxes,ha='left',va='center')
        print infostr
        fig.suptitle('{} - {}'.format(os.popen('pwd').readlines()[0],datetime.now().isoformat(' ')))
        fig.show()
        raw_input("    ADUrate")

    ##################
    '''Grab some information about the data for the header'''
    try:
        filt = pyfits.open(direct_image)[EXTEN].header['FILTER']
    except KeyError:
        filt = 'NA'
    try:
        fiber = pyfits.open(direct_image)[EXTEN].header['OBSERVER']
    except KeyError:
        fiber = 'NA'
    try:
        polish = pyfits.open(direct_image)[EXTEN].header['TELESCOP']
    except KeyError:
        polish = 'NA'

    if OUTPUT:
        f = open(OUTPUT,'w')
        f.write('# Generated by FReD v.'+str(version)+'\n'
                +'# Output writen on: '+datetime.now().isoformat(' ')+'\n'
                +'# Input file (direct beam): '+direct_image+'\n'
                +'# Input file (fiber beam): '+fiber_image+'\n'
                +'# Number of apertures: '+str(num_ap)+'\n'
                +'# Focal length and beam speed: '+str(FL)+'mm '+str(FR)+'\n'
                +'# Filter: '+filt+'\n'
                +'# Fiber input position: '+FP+'\n'
                +'# Fiber output position: '+FO+'\n'
                +'# Harness: '+polish+'\n'
                +'# Total Throughput: '+str(tput_100)+'\n'
                +'# Direct image cutoff: '+str(dir_cut)+'\n'
                +'#\n'
                +'# d_r     = aperture radius of direct beam (mm)\n'
                +'# f_r     = aperture radius of fiber beam (mm)\n'
                +'# d_N     = f-ratio of direct beam\n'
                +'# f_N     = f-ratio of fiber beam\n'
                +'# d_r_c   = corrected direct beam radius (mm)\n'
                +'# f_r_c   = corrected fiber beam radius (mm)\n'
                +'# d_N_c   = corrected direct f-ratio\n'
                +'# f_N_c   = corrected fiber f-ratio\n'
                +'# d_EE    = normalized enclosed energy of direct beam\n'
                +'# f_EE    = normalized enclosed energy of fiber beam\n'
                +'# d_N_e   = effective f-ratio for direct beam\n'
                +'# f_N_e   = effective f-ratio for fiber beam\n'
                +'# d_N_e_c = effective f-ratio for corrected direct beam\n'
                +'# f_N_e_c = effective f-ratio for corrected fiber beam\n'
                +'#\n'
                +'#     d_r        f_r        d_N        f_N      d_r_c'
                +'      f_r_c      d_N_c      f_N_c       d_EE       f_EE'
                +'      d_N_e      f_N_e    d_N_e_c    f_N_e_c\n'
                +'#       1          2          3          4          5'
                +'          6          7          8          9         10'
                +'         11         12         13         14\n')
        
        for i in range(min(d_rvec.size,f_rvec.size)):
            np.array([d_rvec[i],
                      f_rvec[i],
                      d_N[i],
                      f_N[i],
                      d_r_c[i],
                      f_r_c[i],
                      d_N_c[i],
                      f_N_c[i],
                      d_EE[i],
                      f_EE[i],
                      d_N_e[i],
                      f_N_e[i],
                      d_N_e_c[i],
                      f_N_e_c[i]]).tofile(f,sep='  ',format='%9.3E')
            f.write('\n')
        f.close()
        
    return ((metric90,metric80,tput_100,tput_f5,tput_f47,
             tput_f4,tput_f32,tput_f3,tput_f5b,tput_f4b),(d_N,d_N_c,f_N,f_N_c,d_EE,f_EE,f_EE_nd))