def synthetic_spectrum(): param = get_para() x = np.arange(2000) pileup_peak = ['Si_Ka1-Si_Ka1', 'Si_Ka1-Ce_La1'] elemental_lines = ['Ar_K', 'Fe_K', 'Ce_L', 'Pt_M'] + pileup_peak elist, matv, area_v = construct_linear_model(x, param, elemental_lines, default_area=1e5) return np.sum(matv, 1) #In case that y0 might be zero at certain points.
def calculate_profile(x, y, param, elemental_lines, default_area=1e5): """ Calculate the spectrum profile based on given paramters. Use function construct_linear_model from xrf_model. Parameters ---------- x : array channel array y : array spectrum intensity param : dict paramters elemental_lines : list such as Si_K, Pt_M required_length : optional, int the length of the array might change due to trim process, so predifine the length to a given value. default_area : float default value for the gaussian area of each element Returns ------- x : array trimmed energy range temp_d : dict dict of array area_dict : dict dict of area for elements and other peaks """ # Need to use deepcopy here to avoid unexpected change on parameter dict fitting_parameters = copy.deepcopy(param) total_list, matv, area_dict = construct_linear_model(x, fitting_parameters, elemental_lines, default_area=default_area) temp_d = {k: v for (k, v) in zip(total_list, matv.transpose())} # add background bg = snip_method(y, fitting_parameters['e_offset']['value'], fitting_parameters['e_linear']['value'], fitting_parameters['e_quadratic']['value'], width=fitting_parameters['non_fitting_values']['background_width']) temp_d['background'] = bg x_energy = (fitting_parameters['e_offset']['value'] + fitting_parameters['e_linear']['value'] * x + fitting_parameters['e_quadratic']['value'] * x**2) return x_energy, temp_d, area_dict
def synthetic_spectrum(): param = get_para() x = np.arange(2000) pileup_peak = ['Si_Ka1-Si_Ka1', 'Si_Ka1-Ce_La1'] user_peak = ['user_peak1'] elemental_lines = (['Ar_K', 'Fe_K', 'Ce_L', 'Pt_M'] + pileup_peak + user_peak) elist, matv, area_v = construct_linear_model(x, param, elemental_lines, default_area=1e5) # In case that y0 might be zero at certain points. return np.sum(matv, 1)
def test_pixel_fit_multiprocess(): param = get_para() y0 = synthetic_spectrum() x = np.arange(len(y0)) pileup_peak = ['Si_Ka1-Si_Ka1', 'Si_Ka1-Ce_La1'] user_peak = ['user_peak1'] elemental_lines = (['Ar_K', 'Fe_K', 'Ce_L', 'Pt_M'] + pileup_peak + user_peak) default_area = 1e5 elist, matv, area_v = construct_linear_model(x, param, elemental_lines, default_area=default_area) exp_data = np.zeros([2, 1, len(y0)]) for i in range(exp_data.shape[0]): exp_data[i, 0, :] = y0 results = fit_pixel_multiprocess_nnls(exp_data, matv, param, use_snip=True) # output area of dict result_map = calculate_area(elist, matv, results, param, first_peak_area=True) # compare input list and output elemental list assert_array_equal(elist, elemental_lines + ['compton', 'elastic']) # Total len includes all the elemental list, compton, elastic and # two more items, which are summed area of background and r-squared total_len = len(elist) + 2 assert_array_equal(results.shape, [2, 1, total_len]) # same exp data should output same results assert_array_equal(results[0, :, :], results[1, :, :]) for k, v in six.iteritems(result_map): assert_equal(v[0, 0], v[1, 0]) if k in ['snip_bkg', 'r_squared']: # bkg is not a fitting parameter, and r_squared is just a # statistical output. # Only compare the fitting parameters, such as area of each peak. continue # compare with default value 1e5, and get difference < 1% assert abs(v[0, 0] * 0.01 - default_area) / default_area < 1e-2
def test_pixel_fit_multiprocess(): param = get_para() y0 = synthetic_spectrum() x = np.arange(len(y0)) pileup_peak = ['Si_Ka1-Si_Ka1', 'Si_Ka1-Ce_La1'] user_peak = ['user_peak1'] elemental_lines = (['Ar_K', 'Fe_K', 'Ce_L', 'Pt_M'] + pileup_peak + user_peak) default_area = 1e5 elist, matv, area_v = construct_linear_model(x, param, elemental_lines, default_area=default_area) exp_data = np.zeros([2, 1, len(y0)]) for i in range(exp_data.shape[0]): exp_data[i, 0, :] = y0 results = fit_pixel_multiprocess_nnls(exp_data, matv, param, use_snip=True) # output area of dict result_map = calculate_area(elist, matv, results, param, first_peak_area=True) # compare input list and output elemental list assert_array_equal(elist, elemental_lines+['compton', 'elastic']) # Total len includes all the elemental list, compton, elastic and # two more items, which are summed area of background and r-squared total_len = len(elist) + 2 assert_array_equal(results.shape, [2, 1, total_len]) # same exp data should output same results assert_array_equal(results[0, :, :], results[1, :, :]) for k, v in six.iteritems(result_map): assert_equal(v[0, 0], v[1, 0]) if k in ['snip_bkg', 'r_squared']: # bkg is not a fitting parameter, and r_squared is just a # statistical output. # Only compare the fitting parameters, such as area of each peak. continue # compare with default value 1e5, and get difference < 1% assert_true(abs(v[0, 0] * 0.01 - default_area) / default_area < 1e-2)