Esempio n. 1
0
def test_pre_fit():
    # No pre-defined elements. Use all possible elements activated at
    # given energy
    y0 = synthetic_spectrum()
    x0 = np.arange(len(y0))
    # the following items should appear
    item_list = ['Ar_K', 'Fe_K', 'compton', 'elastic']

    param = get_para()

    # fit without weights
    x, y_total, area_v = linear_spectrum_fitting(x0, y0, param, weights=None)
    for v in item_list:
        assert v in y_total

    sum1 = np.sum([v for v in y_total.values()], axis=0)
    # r squares as a measurement
    r1 = 1 - np.sum((sum1 - y0)**2) / np.sum((y0 - np.mean(y0))**2)
    assert r1 > 0.85

    # fit with weights
    w = 1 / np.sqrt(y0 + 1)
    x, y_total, area_v = linear_spectrum_fitting(x0, y0, param, weights=w)
    for v in item_list:
        assert v in y_total
    sum2 = np.sum([v for v in y_total.values()], axis=0)
    # r squares as a measurement
    r2 = 1 - np.sum((sum2 - y0)**2) / np.sum((y0 - np.mean(y0))**2)
    assert r2 > 0.85
Esempio n. 2
0
def test_pre_fit():
    # No pre-defined elements. Use all possible elements activated at
    # given energy
    y0 = synthetic_spectrum()
    x0 = np.arange(len(y0))
    # the following items should appear
    item_list = ['Ar_K', 'Fe_K', 'compton', 'elastic']

    param = get_para()

    # fit without weights
    x, y_total, area_v = linear_spectrum_fitting(x0, y0, param, weights=None)
    for v in item_list:
        assert_true(v in y_total)

    sum1 = np.sum([v for v in y_total.values()], axis=0)
    # r squares as a measurement
    r1 = 1 - np.sum((sum1-y0)**2)/np.sum((y0-np.mean(y0))**2)
    assert_true(r1 > 0.85)

    # fit with weights
    w = 1/np.sqrt(y0+1)
    x, y_total, area_v = linear_spectrum_fitting(x0, y0, param, weights=w)
    for v in item_list:
        assert_true(v in y_total)
    sum2 = np.sum([v for v in y_total.values()], axis=0)
    # r squares as a measurement
    r2 = 1 - np.sum((sum2-y0)**2)/np.sum((y0-np.mean(y0))**2)
    assert_true(r2 > 0.85)
Esempio n. 3
0
def fit_each_pixel_with_nnls(data, params, elemental_lines=None,
                             weights=None):
    """
    Fit a spectrum with a linear model.

    Parameters
    ----------
    data : array
        spectrum intensity
    param : dict
        fitting parameters
    elemental_lines : list, optional
            e.g., ['Na_K', Mg_K', 'Pt_M'] refers to the
            K lines of Sodium, the K lines of Magnesium, and the M
            lines of Platinum. If elemental_lines is set as None,
            all the possible lines activated at given energy will be used.
    """
    param = copy.deepcopy(parameter)
    if incident_energy is not None:
        param['coherent_sct_amplitude']['value'] = incident_energy
    # cut data into proper range
    low = param['non_fitting_values']['energy_bound_low']['value']
    high = param['non_fitting_values']['energy_bound_high']['value']
    a0 = param['e_offset']['value']
    a1 = param['e_linear']['value']
    x, y = define_range(data, low, high, a0, a1)
    # pixel fitting
    _, result_dict, area_dict = linear_spectrum_fitting(x, y,
                                    elemental_lines=elemental_lines,
                                    weighs=weighs)
    return result_dict
Esempio n. 4
0
def fit_pixel_per_file_no_multi(dir_path,
                                file_prefix,
                                fileID,
                                param,
                                interpath,
                                save_spectrum=True):
    """
    Single pixel fit of experiment data. No multiprocess is applied.

    .. warning :: This function is not optimized as it calls
    linear_spectrum_fitting function, where lots of repeated
    calculation are processed.

    Parameters
    ----------
    data : array
        3D data of experiment spectrum
    param : dict
        fitting parameters

    Returns
    -------
    dict :
        fitting values for all the elements
    """

    num_str = "{:03d}".format(fileID)
    filename = file_prefix + num_str
    file_path = os.path.join(dir_path, filename)
    with h5py.File(file_path, "r") as f:
        data = f[interpath][:]
    datas = data.shape

    elist = param["non_fitting_values"]["element_list"].split(", ")
    elist = [e.strip(" ") for e in elist]

    non_element = ["compton", "elastic", "background"]
    total_list = elist + non_element

    result_map = dict()
    for v in total_list:
        if save_spectrum:
            result_map.update({v: np.zeros([datas[0], datas[1], datas[2]])})
        else:
            result_map.update({v: np.zeros([datas[0], datas[1]])})

    for i in range(datas[0]):
        for j in range(datas[1]):
            x, result, area_v = linear_spectrum_fitting(data[i, j, :],
                                                        param,
                                                        elemental_lines=elist,
                                                        constant_weight=1.0)
            for v in total_list:
                if v in result:
                    if save_spectrum:
                        result_map[v][i, j, :len(result[v])] = result[v]
                    else:
                        result_map[v][i, j] = np.sum(result[v])

    return result_map
Esempio n. 5
0
    def find_peak(self, threshv=0.1):
        """
        Run automatic peak finding, and save results as dict of object.

        Parameters
        ----------
        threshv : float
            The value will not be shown on GUI if it is smaller than the threshold.
        """
        self.define_range()  # in case the energy calibraiton changes
        self.prefit_x, out_dict, area_dict = linear_spectrum_fitting(self.x0,
                                                                     self.y0,
                                                                     self.param_new)
        logger.info('Energy range: {}, {}'.format(
            self.param_new['non_fitting_values']['energy_bound_low']['value'],
            self.param_new['non_fitting_values']['energy_bound_high']['value']))

        prefit_dict = OrderedDict()
        for k, v in six.iteritems(out_dict):
            ps = PreFitStatus(z=get_Z(k),
                              energy=get_energy(k),
                              area=area_dict[k],
                              spectrum=v,
                              maxv=np.around(np.max(v), self.max_area_dig),
                              norm=-1,
                              lbd_stat=False)
            prefit_dict.update({k: ps})

        logger.info('Automatic Peak Finding found elements as : {}'.format(
            list(prefit_dict.keys())))
        self.EC.delete_all()
        self.EC.add_to_dict(prefit_dict)
Esempio n. 6
0
    def find_peak(self, threshv=0.1):
        """
        Run automatic peak finding, and save results as dict of object.

        Parameters
        ----------
        threshv : float
            The value will not be shown on GUI if it is smaller than the threshold.
        """
        self.define_range()  # in case the energy calibraiton changes
        self.prefit_x, out_dict, area_dict = linear_spectrum_fitting(self.x0,
                                                                     self.y0,
                                                                     self.param_new)
        logger.info('Energy range: {}, {}'.format(
            self.param_new['non_fitting_values']['energy_bound_low']['value'],
            self.param_new['non_fitting_values']['energy_bound_high']['value']))

        prefit_dict = OrderedDict()
        for k, v in six.iteritems(out_dict):
            ps = PreFitStatus(z=get_Z(k),
                              energy=get_energy(k),
                              area=area_dict[k],
                              spectrum=v,
                              maxv=np.around(np.max(v), self.max_area_dig),
                              norm=-1,
                              lbd_stat=False)
            prefit_dict.update({k: ps})

        logger.info('Automatic Peak Finding found elements as : {}'.format(
            list(prefit_dict.keys())))
        self.EC.delete_all()
        self.EC.add_to_dict(prefit_dict)
Esempio n. 7
0
def fit_pixel_per_file_no_multi(dir_path, file_prefix,
                                fileID, param, interpath,
                                save_spectrum=True):
    """
    Single pixel fit of experiment data. No multiprocess is applied.

    .. warning :: This function is not optimized as it calls
    linear_spectrum_fitting function, where lots of repeated
    calculation are processed.

    Parameters
    ----------
    data : array
        3D data of experiment spectrum
    param : dict
        fitting parameters

    Returns
    -------
    dict :
        fitting values for all the elements
    """

    num_str = '{:03d}'.format(fileID)
    filename = file_prefix + num_str
    file_path = os.path.join(dir_path, filename)
    with h5py.File(file_path, 'r') as f:
        data = f[interpath][:]
    datas = data.shape

    elist = param['non_fitting_values']['element_list'].split(', ')
    elist = [e.strip(' ') for e in elist]

    non_element = ['compton', 'elastic', 'background']
    total_list = elist + non_element

    result_map = dict()
    for v in total_list:
        if save_spectrum:
            result_map.update({v: np.zeros([datas[0], datas[1], datas[2]])})
        else:
            result_map.update({v: np.zeros([datas[0], datas[1]])})

    for i in xrange(datas[0]):
        for j in xrange(datas[1]):
            x, result, area_v = linear_spectrum_fitting(data[i, j, :], param,
                                                        elemental_lines=elist,
                                                        constant_weight=1.0)
            for v in total_list:
                if v in result:
                    if save_spectrum:
                        result_map[v][i, j, :len(result[v])] = result[v]
                    else:
                        result_map[v][i, j] = np.sum(result[v])

    return result_map