예제 #1
0
def TOF(time, n_dataset, parms, data, glbl):
    # time of flight signal model. The function takes an array of uncorrected time in seconds and
    #   returns an array with the corresponing comptute signal

    # averaging_type = glbl.averaging_types[n_dataset-1]
    # prob_curve_type = glbl.functions[n_dataset-1]
    angles = glbl.angles_list
    cutoff_type = glbl.cutoff_types[n_dataset - 1]
    mass_molecules = data.mass_molecules
    mass_factor = np.sqrt(mass_molecules[n_dataset - 1] / glbl.massH2)
    y_scale = parms["y_scale_%i" % n_dataset].value
    baseline = parms["baseline_%i" % n_dataset].value
    # tcutc    = Params['tcutc_%i'     %NDataSet].value
    # tcutw    = Params['tcutw_%i'     %NDataSet].value
    ion_tof = parms["ion_tof_%i" % n_dataset].value * mass_factor
    # Temperature = Params['Temp_%i' %NDataSet].value

    # subtract the ion flight time and eliminate singularity that would occur at time = 0
    time = time - ion_tof * 1e-6
    time = np.where(time != 0, time, np.repeat(0.01e-6, len(time)))

    cutoff = cutoff_function(parms, data, glbl, n_dataset, time, cutoff_type)
    signal0 = angular_averaging(time, n_dataset, angles, parms, glbl, data)
    signal = signal0 * cutoff * y_scale + baseline

    return signal
예제 #2
0
def ProbFromTOFInversion(time, signal, n_dataset, parms, averaging_type, theta_angles,
                         prob_curve_type, cutoff_type, mass_molecules):
    # time of flight signal model. The function takes an uncorrected time in seconds and returns a signal
    
    mass_factor = np.sqrt(mass_molecules[n_dataset - 1] / glbl.massH2)
    ffr_dist  = parms['ffr_%i' % n_dataset].value * 1E-3
    max_tof   = parms['y_scale_%i' % n_dataset].value
    baseline = parms['baseline_%i' % n_dataset].value
    TimeCorr = parms['IonTOF_%i' % n_dataset].value * mass_factor
    Temperature = parms['Temp_%i' % n_dataset].value

    # subtract the ion flight time and eliminate singularity that would occur at time = 0
    time = time - TimeCorr * 1E-6  
    time = np.where(time != 0, time, np.repeat(0.01E-6, len(time)))
            
    CutOff = cutoff_function(parms, data, n_dataset, time, cutoff_type)

    velocity_distribution = 0.                        # Initialize Signal to 0

    if averaging_type == "PointDetector":    
        # Averaging performed taking into account different flight time for different angles
        for theta in theta_angles:
            # v = x / t = ( L / cos(theta) ) / t
            velocity = ffr_dist / (time * np.cos(np.radians(theta))) 
            Ekin = (0.5 * glbl.AMU * velocity ** 2.) * glbl.eVConst
            # Enorm = Ekin * np.cos( np.radians(theta) )**2. # Reaction probability depends on normal energy
            velocity_distribution = velocity_distribution                   \
                                   + velocity**4.                         \
                                   * np.exp(-Ekin / (glbl.kb * Temperature)) \
                                   * np.cos( np.radians(theta) )**2.      \
                                   * np.sin( np.radians(theta) ) \
                                     * glbl.theta_step

    elif averaging_type == "None":
        # No angular averaging
        velocity = ffr_dist / time
        Ekin = (0.5 * glbl.AMU * velocity ** 2.) * glbl.eVConst
        # Enorm = Ekin
        velocity_distribution = velocity**4. * np.exp(-Ekin / (glbl.kb * Temperature))
        
        # kludge to fix divide by zero runtime error        
        for ii in range(len(velocity_distribution)):
            if velocity_distribution[ii] == 0:
                velocity_distribution[ii] = 1E-100
        

    ProbFromTOF = (signal - baseline) / (max_tof * velocity_distribution * CutOff)
    Energy = 0.5 * glbl.AMU * (ffr_dist / time) ** 2. * glbl.eVConst
    

    return Energy, ProbFromTOF
예제 #3
0
def write_fit_out(glbl, data, path, control_filename, fit_number, fit_result, PlotDataSets):
    state_string = 'v' + str(data.states[0][0]) + 'j' + str(data.states[0][1])
    result_filename = 'Fit' + fit_number + '_' + data.molecules[0] + \
                      '_' + state_string + '_' + glbl.functions[0] + '.fit_out'

    parms = fit_result.params

    with open(path + result_filename, 'w') as result_file:
        result_file.write('#\n')
        result_file.write('# Fit {} Results\n'.format(fit_number))
        result_file.write('#\n')
        result_file.write('#' + 60 * '-' + '\n')
        result_file.write('# Control file: \n') 
        result_file.write('# {}\n'.format(control_filename))
        result_file.write('#' + 60 * '-' + '\n')

        # --------------------------------------------------------------------------
        # write the control file to the result file
        # --------------------------------------------------------------------------
        with open(control_filename, 'r') as cmd:
            cmd_lines = cmd.readlines()

        for line in cmd_lines:
            result_file.write('# ' + line)

        # result_file.write('\n#' + 60 * '-' + '\n')
        # result_file.write('# End Control File\n')
        # result_file.write('#' + 60 * '-' + '\n')

        # --------------------------------------------------------------------------
        # write the angular averaging parameters
        # --------------------------------------------------------------------------
        result_file.write('#\n')
        result_file.write('#' + 60 * '-' + '\n')
        result_file.write('# Angular Averaging Parameters\n')
        result_file.write('#' + 60 * '-' + '\n')
        result_file.write('# points_source    : ' + str(glbl.points_source) + '\n')
        result_file.write('# points_detector  : ' + str(glbl.points_detector) + '\n')
        result_file.write('# z_source         : ' + str(glbl.z_source) + '\n')
        result_file.write('# r_source         : ' + str(glbl.r_source) + '\n')
        result_file.write('# z_aperture       : ' + str(glbl.z_aperture) + '\n')
        result_file.write('# r_aperture       : ' + str(glbl.r_aperture) + '\n')
        result_file.write('# z_final          : ' + str(glbl.z_final) + '\n')
        result_file.write('# r_final          : ' + str(glbl.r_final) + '\n')
        # result_file.write('# it mse\n')

        for i in range(0, len(glbl.angles_list), 10):
            result_file.write('# angles_list : ' + str(glbl.angles_list[i: i + 10]) + '\n')
        # result_file.write('#' + 60 * '-' + '\n')
        # result_file.write('# End Angular Averaging Parameter\n')
        # result_file.write('#' + 60 * '-' + '\n')
        result_file.write('#\n')

        # --------------------------------------------------------------------------
        # write the fit report to the result file
        # --------------------------------------------------------------------------
        result_file.write('#' + 60 * '-' + '\n')
        result_file.write('# Fit Report\n')
        result_file.write('#' + 60 * '-' + '\n')

        #------------------------------------------------------------------------------------------
        # first write chi square and reduced chi square in scientific format
        # standard fit report use numbers with 3 places after decimal point
        # which results in print 0.000 sometimes
        #------------------------------------------------------------------------------------------
        result_file.write('# chi-square             = {:10.3e}'.format(fit_result.chisqr) + '\n')
        result_file.write('# reduced chi-square     = {:10.3e}'.format(fit_result.redchi) + '\n')
        result_file.write('#\n')
        
        report = lmfit.fit_report(fit_result).split('\n')
        for line in report:
            result_file.write('# ' + line + '\n')
        # result_file.write('#' + 60 * '-' + '\n')
        # result_file.write('# End Fit Report\n')
        # result_file.write('#' + 60 * '-' + '\n')
        result_file.write('#\n')

        # --------------------------------------------------------------------------
        # the number of datasets to plot
        # --------------------------------------------------------------------------
        result_file.write('#' + 60 * '-' + '\n')
        result_file.write('# Data for plots\n')
        result_file.write('#' + 60 * '-' + '\n')
        result_file.write('# Number of plots : ' + str(len(PlotDataSets)) + '\n')
        result_file.write('#' + 60 * '-' + '\n')
        result_file.write('#\n')

        # --------------------------------------------------------------------------
        # for each data set, write plot title, information for labels, and data
        # --------------------------------------------------------------------------
            
        for i in range(len(PlotDataSets)):
            n_dataset = i + 1

            n_min = data.fit_index_ranges[i][0]
            n_max = data.fit_index_ranges[i][1]
            t_min = data.datasets[i][0][n_min] * 1E6
            t_max = data.datasets[i][0][n_max] * 1E6
            ProbCurveType = glbl.functions[i]
            averaging_type = glbl.averaging_types[i]
            # DataFile = signal_filenames[i]
            cutoff_type = glbl.cutoff_types[i]

            result_file.write('#' + 60 * '-' + '\n')
            result_file.write('# Plot ' + str(n_dataset) + '\n')
            result_file.write('#' + 60 * '-' + '\n')

            # --------------------------------------------------------------------------
            # write the plot title
            # --------------------------------------------------------------------------
            result_file.write('# Title             : ')
            result_file.write('Fit {:04d}_{}'.format(int(fit_number), n_dataset) + '\n')

            # -------------------------------------------------------------------------------------
            # write information for the plot labels
            # -------------------------------------------------------------------------------------
            comment = glbl.comments[i]
            if comment == None:
                comment = ''
            
            signal_file = glbl.signal_filenames[i]
            
            background_file = glbl.background_filenames[i]
            if background_file == None:
                background_file = 'none'
            
            result_file.write('# commment          : ' + comment             + '\n')
            result_file.write('# signal_file       : ' + signal_file         + '\n')
            result_file.write('# background_file   : ' + background_file     + '\n')
            result_file.write('# date              : ' + data.dates[i]       + '\n')            
            result_file.write('# molecule          : ' + data.molecules[i]   + '\n')
            result_file.write('# states            : ' + str(data.states[i]) + '\n')
            
            result_file.write('# function          : ' + ProbCurveType       + '\n')
            
            if averaging_type == 'none':
                avg_type_label = 'No Averaging'
            elif averaging_type == 'point_detector':
                avg_type_label = 'Point Detector'
            elif averaging_type == 'line_detector':
                avg_type_label = 'Line Detector'
            result_file.write('# avg_type_label    : ' + avg_type_label + '\n')
            
            #--------------------------------------------------------------------------------------
            # write time range of fit and t_min, t_max, threshold, number points averaged
            #--------------------------------------------------------------------------------------
            result_file.write('#\n')
            result_file.write('#' + 60 * '-' + '\n')
            result_file.write('# fit range and how determined \n')
            result_file.write('#' + 60 * '-' + '\n')
            n_tup = (n_min, n_max)
            t_tup = (t_min, t_max)
            result_file.write('# fit_time_range    : ' + str(glbl.fit_ranges[i])      + '\n')            
            result_file.write('# n_min, n_max      : ' + str(n_tup)                   + '\n')
            result_file.write('# threshold         : ' + str(glbl.thresholds[i])      + '\n')
            result_file.write('# n_delt for avg    : ' + str(glbl.n_delts[i])          + '\n')
            result_file.write('# t_min, t_max      : ' + str(t_tup)                   + '\n')
            
            #--------------------------------------------------------------------------------------
            # write time range of fit and t_min, t_max, threshold, number points averaged
            #--------------------------------------------------------------------------------------
            result_file.write('#\n')
            result_file.write('#' + 60 * '-' + '\n')
            result_file.write('# baseline and how determined \n')
            result_file.write('#' + 60 * '-' + '\n')
            baseline = fit_result.params['baseline_' + str(n_dataset)].value            
            result_file.write('# baseline_range    : ' + str(glbl.baseline_ranges[i]) + '\n')            
            result_file.write('# baseline          : ' + str(baseline)                + '\n')
            result_file.write('#\n')
            
            #--------------------------------------------------------------------------------------
            # write the parmameters for current plot                        
            #--------------------------------------------------------------------------------------
            result_file.write('#' + 60 * '-' + '\n')
            result_file.write('# parameters used in fit \n')            
            result_file.write('#' + 60 * '-' + '\n')
            parms = fit_result.params         
            for p in parms:
                p_name  = p.rsplit('_',1)[0]
                p_n     = int(p.rsplit('_',1)[1])
                if p_n != n_dataset :
                    continue
                result_file.write('# ' + '{:17}'.format(p_name +'_label') + ' : ')
                result_file.write('{:>10.3g}'.format(parms[p].value))
             
                if parms[p_name + '_1'].glbl and i > 0:
                    result_file.write(', (global)\n')
                if not parms[p].vary:
                    result_file.write(', (fixed)\n')
                else:
                    stderr = '{:6.3f}'.format(parms[p].stderr)
                    result_file.write(', (' + unicodedata.lookup('plus-minus sign')
                                       + str(stderr) + ')\n')             

            #--------------------------------------------------------------------------------------# --------------------------------------------------------------------------
            # Get the point where time > 2E-6 sec and ignore earlier points to avoid noise
            #--------------------------------------------------------------------------------------# --------------------------------------------------------------------------
            # i_start = np.where(PlotDataSets[i][0] > 2.0E-6)[0][0]
            #--------------------------------------------------------------------------------------# --------------------------------------------------------------------------
            # Decided it is not a good idea to not print all the data
            # Better to write the plot routine to ignore the data
            #--------------------------------------------------------------------------------------# --------------------------------------------------------------------------
            
            i_start = 0  # maybe not a good idea to throw away data

            #--------------------------------------------------------------------------------------# --------------------------------------------------------------------------
            # Get the plot data and convert time to microseconds
            #--------------------------------------------------------------------------------------# --------------------------------------------------------------------------
            Time = PlotDataSets[i][0][i_start:]
            Signal = PlotDataSets[i][1][i_start:]
            Fit = compute_tof.TOF(Time, n_dataset, fit_result.params, data, glbl)

            mass_factor = np.sqrt(data.mass_molecules[i] / glbl.massH2)
            ion_tof = fit_result.params['ion_tof_%i' % n_dataset].value * mass_factor

            #--------------------------------------------------------------------------------------
            # Compute cutoff for plotting.
            #   Create a new time array which is corrected for ion time of flight
            #   Replace time=0 by time = 1e-8 to remove singularity in velocity and
            #   energy if t=0
            #--------------------------------------------------------------------------------------
            Time2 = Time - ion_tof * 1E-6
            Time2 = np.where(Time2 != 0, Time2, np.repeat(0.01E-6, len(Time)))
            Cutoff = cutoff_function(fit_result.params, data, glbl,
                                            n_dataset, Time2, cutoff_type)
            # Convert time to microseconds for plotting
            Time = Time * 1E6  # convert to microseconds for plotting

            #---------- ---------------------------------------------------------------------------
            # write the number of data lines and range of lines fit
            # -------------------------------------------------------------------------------------
            result_file.write('# n_points          : ' + str(len(Time)) + '\n')
            result_file.write('#' + 68 * '-' + '\n')

            # -------------------------------------------------------------------------------------
            # write the plot data
            # -------------------------------------------------------------------------------------
            result_file.write('# time            Signal                Fit                 Cutoff\n')
            result_file.write('#' + 68 * '-' + '\n')
            result_file.write('# Begin data\n')

            for j in range(len(Time)):
                result_file.write('{:6.2f} {:20.5e} {:20.5e} {:20.5e}\n'
                                  .format(Time[j], Signal[j], Fit[j], Cutoff[j]))

            result_file.write('# End data\n')
            result_file.write('#' + 68 * '-' + '\n')
            result_file.write('# End Plot ' + str(n_dataset) + '\n')

    # end comment out for profiling

    # print("--- %s seconds ---" % (time.time() - start_time))

    return result_filename