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
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
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