def test_2_gaussian_1_subrun(setup_1_subrun, fit_domain):
    """Fit 2 Gaussian peaks for 1 sub run

    Returns
    -------

    """
    fit_engine = PeakFitEngineFactory.getInstance(
        setup_1_subrun['workspace'],
        peak_function_name='Gaussian',
        background_function_name='Linear',
        wavelength=np.nan)

    # Fit

    fit_result = fit_engine.fit_multiple_peaks(peak_tags=['Left', 'Right'],
                                               x_mins=fit_domain[0],
                                               x_maxs=fit_domain[1])
    number_of_peakCollection = 2.
    # Test the fitted parameters: effective parameters
    # Effective parameter list: ['Center', 'Height', 'Intensity', 'FWHM', 'Mixing', 'A0', 'A1']
    # Read data
    sub_runs = fit_result.peakcollections[0].sub_runs
    fit_costs = fit_result.peakcollections[0].fitting_costs
    eff_param_values, eff_param_errors = fit_result.peakcollections[
        0].get_effective_params()
    assert eff_param_values.size == 1, '1 sub run'
    assert len(eff_param_values.dtype.names) == 7, '7 effective parameters'
    '''
    if abs(eff_param_values[2][0] - expected_intensity) < 1E-03:
        plt.plot(data_x, data_y, label='Test 2 Gaussian')
        plt.plot(model_x, model_y, label='Fitted Gaussian')
        plt.legend()
        plt.show()
        raise AssertionError('Peak intensity {} shall be equal to {}.'
                             ''.format(eff_param_values[2, 0], expected_intensity))
    '''

    # Test the fitted parameters: native parameters
    native_params = PeakShape.GAUSSIAN.native_parameters
    native_params.extend(BackgroundFunction.LINEAR.native_parameters)
    sub_runs2 = fit_result.peakcollections[0].sub_runs
    fit_cost2 = fit_result.peakcollections[0].fitting_costs
    param_values, param_errors = fit_result.peakcollections[
        0].get_native_params()
    parameters = setup_1_subrun['parameters'][0]
    # Test
    assert sub_runs.size == 1 == sub_runs2.size
    np.testing.assert_equal(fit_cost2, fit_costs)

    np.testing.assert_equal(eff_param_values['Center'],
                            param_values['PeakCentre'])
    np.testing.assert_allclose(eff_param_values['Center'],
                               parameters['peak_center'],
                               rtol=2e-2,
                               err_msg='Peak center is not correct')

    # Parameters verified
    assert_checks(fit_result, parameters, param_values,
                  number_of_peakCollection)
Beispiel #2
0
def test_retrieve_fit_metadata(source_project_file, output_project_file,
                               peak_type, peak_info):
    """A full set of test including loading project,  fitting peaks, write fitting result and exporting fitting
    result and calculated peaks

    Parameters
    ----------
    source_project_file
    output_project_file
    peak_type
    peak_info

    Returns
    -------

    """
    if os.path.exists(source_project_file) is False:
        pytest.skip('{} does not exist on Travis'.format(source_project_file))

    # Create calibration control
    controller = pyrscore.PyRsCore()

    # Load project file to HidraWorkspace
    project_name = 'Jean Peaks'
    hd_ws = controller.load_hidra_project(source_project_file,
                                          project_name=project_name,
                                          load_detector_counts=False,
                                          load_diffraction=True)

    # set wave length
    # TODO : @Jean please find out the correct value
    hd_ws.set_wavelength(1.071, False)

    # Set peak fitting engine
    # create a controller from factory
    fit_engine = PeakFitEngineFactory.getInstance(
        hd_ws, peak_function_name=peak_type, background_function_name='Linear')

    # Fit peak
    fit_result = fit_engine.fit_peaks(peak_tag=peak_info.tag,
                                      x_min=peak_info.left_bound,
                                      x_max=peak_info.right_bound)

    # Retrieve all effective peak parameters
    peakcollection = fit_result.peakcollections[0]
    eff_param_value_array, eff_param_error_array = peakcollection.get_effective_params(
    )

    # result file
    ref_h5 = h5py.File(output_project_file, 'w')
    peak_entry = ref_h5.create_group(peak_info.tag)
    peak_entry.create_dataset('Center', data=eff_param_value_array['Center'])
    peak_entry.create_dataset('Height', data=eff_param_value_array['Height'])
    peak_entry.create_dataset('FWHM', data=eff_param_value_array['FWHM'])
    peak_entry.create_dataset('Mixing', data=eff_param_value_array['Mixing'])
    peak_entry.create_dataset('Intensity',
                              data=eff_param_value_array['Intensity'])
    ref_h5.close()
Beispiel #3
0
def test_3_gaussian_3_subruns(target_values):
    """Test fitting 3 Gaussian peaks may or may not on a 3 sub runs

    This is an extreme case such that
    sub run = 1: peak @ 75            X in [68, 78]
    sub run = 2: peak @ 75 and @ 80   X in [72, 82]
    sub run = 3: peak @ 80 and @ 85   X in [78, 88]

    Returns
    -------

    """
    # Create dictionary for test data for 3 sub runs
    test_2g_dict = dict()

    # sub run 1
    vec_x_0 = np.arange(500).astype(float) * 0.02 + 68.
    vec_y_0 = generate_test_gaussian(vec_x_0, [75.], [3.], [10.])['values']
    test_2g_dict[1] = vec_x_0, vec_y_0

    # sub run 2
    vec_x_1 = np.arange(500).astype(float) * 0.02 + 72.
    vec_y_1 = generate_test_gaussian(vec_x_1, [75., 80], [3., 3.5], [15., 5])['values']
    test_2g_dict[2] = vec_x_1, vec_y_1

    # sub run 3
    vec_x_2 = np.arange(500).astype(float) * 0.02 + 78.
    vec_y_2 = generate_test_gaussian(vec_x_2, [80., 85], [3.5, 3.7], [0.2, 7.5])['values']
    test_2g_dict[3] = vec_x_2, vec_y_2

    # Create a workspace based on this
    test_hd_ws = generate_hydra_workspace_multiple_sub_runs('3 G 3 S', test_2g_dict)

    # Fit
    fit_engine = PeakFitEngineFactory.getInstance(test_hd_ws, peak_function_name='Gaussian',
                                                  background_function_name='Linear', wavelength=np.nan)
    fit_result = fit_engine.fit_multiple_peaks(peak_tags=['Left', 'Middle', 'Right'],
                                               x_mins=(72.5, 77.5, 82.5),
                                               x_maxs=(77.5, 82.5, 87.5))

    # Verify fitting result
    # ['Height', 'PeakCentre', 'Sigma'],
    gaussian_native_params = PeakShape.GAUSSIAN.native_parameters
    gaussian_native_params.extend(BackgroundFunction.LINEAR.native_parameters)

    # peak 'Left'
    fit_cost2_lp = fit_result.peakcollections[0].fitting_costs
    param_values_lp, param_errors_lp = fit_result.peakcollections[0].get_native_params()

    # Parameters verified
    np.testing.assert_allclose(param_values_lp['Height'][0], target_values['peak_center'][0], rtol=50.0)
    np.testing.assert_allclose(param_values_lp['Sigma'][0], target_values['sigma'][0], rtol=50.0)
    np.testing.assert_allclose(param_values_lp['A0'][0], target_values['background_A0'][0], rtol=50.0)
    np.testing.assert_allclose(param_values_lp['A1'][0], target_values['background_A1'][0], rtol=50.0)

    assert np.isinf(fit_cost2_lp[2]), 'Sub run 3 does not have peak @ 75 (Peak-Left).  Chi2 shall be infinity but' \
                                      ' not {}'.format(fit_cost2_lp[2])
Beispiel #4
0
def test_1_gaussian_1_subrun(setup_1_subrun, fit_domain):
    """Test fitting single Gaussian peak on 1 spectrum with background

    Returns
    -------
    None

    """
    # initialize fit engine
    fit_engine = PeakFitEngineFactory.getInstance(setup_1_subrun['workspace'], peak_function_name='Gaussian',
                                                  background_function_name='Linear', wavelength=np.nan,
                                                  out_of_plane_angle=None)

    # Fit
    peak_tag = 'UnitTestGaussian'
    fit_result = fit_engine.fit_peaks(peak_tag=peak_tag, x_min=fit_domain[0], x_max=fit_domain[1])
    number_of_peakCollection = 1
    # get back the peak collection
    peakcollection = fit_result.peakcollections[0]
    assert peakcollection.peak_tag == peak_tag
    parameters = setup_1_subrun['parameters'][0]
    # Test the fitted parameters
    fit_costs = peakcollection.fitting_costs
    sub_runs = peakcollection.sub_runs
    eff_param_values, eff_param_errors = peakcollection.get_effective_params()
    assert eff_param_values.dtype.names[0] == 'Center'
    np.testing.assert_almost_equal(eff_param_values['Center'], parameters['peak_center'], decimal=1)
    print_peak_results_and_check_positive(eff_param_values, eff_param_errors)

    # Read data again for raw data
    native_params = PeakShape.GAUSSIAN.native_parameters
    native_params.extend(BackgroundFunction.LINEAR.native_parameters)

    # assert_checks(fit_result, native_params, number_of_peakCollection, peak_tag,
    # peak_center, peak_intensity, peak_FWHM, background_A0, baclground_A1)
    sub_runs2 = peakcollection.sub_runs
    fit_cost2 = peakcollection.fitting_costs
    param_values, param_errors = peakcollection.get_native_params()

    # Test
    assert sub_runs.size == 1 == sub_runs2.size
    np.testing.assert_equal(fit_cost2, fit_costs)

    # Effective parameter list: ['Center', 'Height', 'Intensity', 'FWHM', 'Mixing', 'A0', 'A1']
    assert eff_param_values['Center'] == param_values['PeakCentre']   # center
    np.testing.assert_allclose(param_values['PeakCentre'], parameters['peak_center'], rtol=3e-2,
                               err_msg='Peak center is not correct')

    # Parameters verified
    assert_checks(fit_result, parameters, param_values, number_of_peakCollection)

    # fit goodness
    assert fit_costs[0] < 2.0, 'Fit cost (chi2 = {}) is too large'.format(fit_costs[0])  # TODO was 0.5
Beispiel #5
0
def test_improve_quality():
    """This is a test to improve the quality of peak fitting.

    Data are from the real HB2B data previously reported problematic

    Returns
    -------

    """
    # Define HiDRA project file name and skip test if it does not exist (on Travis)
    project_file_name = '/HFIR/HB2B/IPTS-22731/shared/autoreduce/HB2B_1060.h5'
    if not os.path.exists(project_file_name):
        pytest.skip('{} does not exist on Travis'.format(project_file_name))

    # Create calibration control
    controller = pyrscore.PyRsCore()

    # Load project file to HidraWorkspace
    project_name = 'Jean Peaks'
    hd_ws = controller.load_hidra_project(project_file_name,
                                          project_name=project_name,
                                          load_detector_counts=False,
                                          load_diffraction=True)

    # set wave length
    # TODO : @Jean please find out the correct value
    wavelength = 1.071
    hd_ws.set_wavelength(wavelength, False)

    peak_type = 'Gaussian'

    # Set peak fitting engine
    # create a controller from factory
    fit_engine = PeakFitEngineFactory.getInstance(
        hd_ws,
        peak_function_name=peak_type,
        background_function_name='Linear',
        wavelength=wavelength)

    # Fit peak @ left
    peak_info_left = PeakInfo(91.7, 87., 93., 'Left Peak')

    fit_result = fit_engine.fit_peaks(peak_tag=peak_info_left.tag,
                                      x_min=peak_info_left.left_bound,
                                      x_max=peak_info_left.right_bound)
    assert fit_result

    # Fit the right peak
    peak_info_left = PeakInfo(95.8, 93.5, 98.5, 'Right Peak')

    fit_engine.fit_peaks(peak_tag=peak_info_left.tag,
                         x_min=peak_info_left.left_bound,
                         x_max=peak_info_left.right_bound)
Beispiel #6
0
    def fit_multi_peaks(self):

        QApplication.setOverrideCursor(Qt.WaitCursor)

        _peak_range_list = [
            tuple(_range) for _range in
            self.parent._ui_graphicsView_fitSetup.list_peak_ranges
        ]
        _peak_center_list = [
            np.mean([left, right]) for (left, right) in _peak_range_list
        ]
        _peak_tag_list = [
            "peak{}".format(_index)
            for _index, _ in enumerate(_peak_center_list)
        ]
        _peak_function_name = str(
            self.parent.ui.comboBox_peakType.currentText())

        _peak_xmin_list = [left for (left, _) in _peak_range_list]
        _peak_xmax_list = [right for (_, right) in _peak_range_list]

        # Fit peak
        hd_ws = self.parent.hidra_workspace

        _wavelength = hd_ws.get_wavelength(True, True)
        fit_engine = PeakFitEngineFactory.getInstance(hd_ws,
                                                      _peak_function_name,
                                                      'Linear',
                                                      wavelength=_wavelength)
        fit_result = fit_engine.fit_multiple_peaks(_peak_tag_list,
                                                   _peak_xmin_list,
                                                   _peak_xmax_list)
        self.parent.fit_result = fit_result

        self.parent.populate_fit_result_table(fit_result=fit_result)
        # self.parent.update_list_of_2d_plots_axis()

        o_gui = GuiUtilities(parent=self.parent)
        o_gui.set_1D_2D_axis_comboboxes(with_clear=True,
                                        fill_raw=True,
                                        fill_fit=True)
        o_gui.initialize_combobox()
        o_gui.enabled_export_csv_widgets(enabled=True)
        o_gui.enabled_2dplot_widgets(enabled=True)

        o_plot = Plot(parent=self.parent)
        o_plot.plot_2d()

        QApplication.restoreOverrideCursor()
def test_pseudovoigt_HB2B_1060(target_values):
    """This is a test of Pseudovoigt peak fitting for HB2B 1060.

     Data are from the real HB2B data previously reported problematic


     """
    # Define HiDRA project file name and skip test if it does not exist (on Travis)

    project_file_name = 'tests/data/HB2B_1060_first3_subruns.h5'

    if not os.path.exists(project_file_name):
        pytest.skip('{} does not exist on Travis'.format(project_file_name))

    # Create calibration control
    controller = pyrscore.PyRsCore()

    # Load project file to HidraWorkspace
    project_name = 'HB2B_1060 Peaks'
    hd_ws = controller.load_hidra_project(project_file_name,
                                          project_name=project_name,
                                          load_detector_counts=False,
                                          load_diffraction=True)

    peak_type = 'PseudoVoigt'
    # Set peak fitting engine
    # create a controller from factory
    fit_engine = PeakFitEngineFactory.getInstance(
        hd_ws,
        peak_function_name=peak_type,
        background_function_name='Linear',
        wavelength=np.nan)

    # Fit peak @ left and right
    peak_info_left = PeakInfo(91.7, 87., 93., 'Left Peak')
    peak_info_right = PeakInfo(95.8, 93.5, 98.5, 'Right Peak')

    fit_result = fit_engine.fit_multiple_peaks(
        peak_tags=[peak_info_left.tag, peak_info_right.tag],
        x_mins=[peak_info_left.left_bound, peak_info_right.left_bound],
        x_maxs=[peak_info_left.right_bound, peak_info_right.right_bound])

    assert len(fit_result.peakcollections) == 2, 'two PeakCollection'
    assert fit_result.fitted
    assert fit_result.difference

    # peak 'Left'
    param_values_lp, _ = fit_result.peakcollections[0].get_native_params()

    # peak 'Right'
    param_values_rp, _ = fit_result.peakcollections[1].get_native_params()

    assert param_values_lp.size == 3, '3 subruns'
    assert len(param_values_lp.dtype.names) == 6, '6 native parameters'

    assert param_values_rp.size == 3, '3 subruns'
    assert len(param_values_rp.dtype.names) == 6, '6 native parameters'

    np.testing.assert_allclose(param_values_lp['Intensity'],
                               target_values['Intensity'][0],
                               atol=0.9)
    np.testing.assert_allclose(param_values_lp['PeakCentre'],
                               target_values['peak_center'][0],
                               atol=0.8)
    np.testing.assert_allclose(param_values_lp['FWHM'],
                               target_values['FWHM'][0],
                               atol=1.)
    np.testing.assert_allclose(param_values_lp['A0'],
                               target_values['background_A0'][0],
                               atol=1.)
    np.testing.assert_allclose(param_values_lp['A1'],
                               target_values['background_A1'][0],
                               atol=1.)

    np.testing.assert_allclose(param_values_rp['Intensity'],
                               target_values['Intensity'][1],
                               atol=0.01)
    np.testing.assert_allclose(param_values_rp['PeakCentre'],
                               target_values['peak_center'][1],
                               atol=1)
    np.testing.assert_allclose(param_values_rp['FWHM'],
                               target_values['FWHM'][1],
                               atol=1.2)
    np.testing.assert_allclose(param_values_rp['A0'],
                               target_values['background_A0'][1],
                               atol=1.)
    np.testing.assert_allclose(param_values_rp['A1'],
                               target_values['background_A1'][1],
                               atol=1.)
def test_1_pv_1_subrun(setup_1_subrun, fit_domain):
    """
    Test fitting single Pseudo-voigt peak with background
    Returns
    -------
    None
    """
    # Generate test workspace and initialize fit engine

    fit_engine = PeakFitEngineFactory.getInstance(
        setup_1_subrun['workspace'],
        peak_function_name='PseudoVoigt',
        background_function_name='Linear',
        wavelength=np.nan)

    # Fit
    peak_tag = 'UnitTestPseudoVoigt'

    fit_result = fit_engine.fit_peaks(peak_tag=peak_tag,
                                      x_min=fit_domain[0],
                                      x_max=fit_domain[1])
    number_of_peakCollection = 1.
    # get back the peak collection
    peakcollection = fit_result.peakcollections[0]
    assert peakcollection.peak_tag == peak_tag
    parameters = setup_1_subrun['parameters'][0]

    # Test the fitted parameters
    sub_runs = peakcollection.sub_runs
    eff_param_values, eff_param_errors = peakcollection.get_effective_params()
    fit_costs = peakcollection.fitting_costs

    assert eff_param_values.dtype.names[0] == 'Center'
    np.testing.assert_almost_equal(eff_param_values['Center'],
                                   parameters['peak_center'],
                                   decimal=1)
    print_peak_results_and_check_positive(eff_param_values, eff_param_errors)

    # Read data again for raw data
    native_params = PeakShape.PSEUDOVOIGT.native_parameters
    native_params.extend(BackgroundFunction.LINEAR.native_parameters)
    sub_runs2 = peakcollection.sub_runs
    fit_cost2 = peakcollection.fitting_costs
    param_values, param_errors = peakcollection.get_native_params()
    print('Ordered native parameters: {}'.format(native_params))

    # Test
    assert sub_runs.shape == (1, ) == sub_runs2.shape
    assert np.allclose(fit_cost2, fit_costs, 0.0000001)

    # Effective parameter list: ['Center', 'Height', 'Intensity', 'FWHM', 'Mixing', 'A0', 'A1']
    # Native parameters: ['Mixing', 'Intensity', 'PeakCentre', 'FWHM', 'A0', 'A1']
    assert eff_param_values['Mixing'] == param_values['Mixing']  # mixing
    assert eff_param_values['Center'] == param_values['PeakCentre']  # center
    assert eff_param_values['Intensity'] == param_values[
        'Intensity']  # intensity

    assert_checks(fit_result,
                  parameters,
                  param_values,
                  number_of_peakCollection,
                  peak_profile_type='PseudoVoigt')

    if fit_costs[0] > 1.0:
        # Plot
        model_x = fit_result.fitted.readX(0)
        model_y = fit_result.fitted.readY(0)
        data_x, data_y = setup_1_subrun[
            'workspace'].get_reduced_diffraction_data(1, None)
        assert data_x.shape == model_x.shape
        assert data_y.shape == model_y.shape
        plt.clf()
        plt.plot(data_x, data_y, label='Test 2 Gaussian 3 sub runs')
        plt.plot(model_x, model_y, label='Fitted 2 Gaussian 3 sub runs')
        plt.legend()
        # plt.show()
        raise AssertionError(
            'Fit cost (chi2 = {}) is too large (criteria = 1.)'.format(
                fit_costs[0]))
def test_2_gaussian_3_subruns(target_values):
    """Testing fitting 2 Gaussian peaks among 3 sub runs.

    Some of the sub runs may not have one specific peak or the peak may be off center too much.

    This is an extreme case such that
    sub run = 1: peak @ 75 and @ 83
    sub run = 2: peak @ 75 and @ 80
    sub run = 3: peak @ 75 very low and @ 80

    Returns
    -------
    None

    """
    # Generate 3 sub runs
    vec_x = np.arange(750).astype(float) * 0.02 + 70.

    # Create dictionary for test data
    test_2g_dict = dict()

    # sub run 1
    vec_y = generate_test_gaussian(vec_x, [75., 83], [3., 3.5],
                                   [10., 5])['values']
    test_2g_dict[1] = vec_x, vec_y

    # sub run 2
    vec_y = generate_test_gaussian(vec_x, [75., 80], [3., 3.5],
                                   [15., 5])['values']
    test_2g_dict[2] = vec_x, vec_y

    # sub run 3
    vec_y = generate_test_gaussian(vec_x, [75., 80], [3.1, 3.5],
                                   [0.2, 7.5])['values']
    test_2g_dict[3] = vec_x, vec_y

    # Create a workspace based on this
    test_hd_ws = generate_hydra_workspace_multiple_sub_runs(
        '3 G 3 S', test_2g_dict)

    # Fit
    fit_engine = PeakFitEngineFactory.getInstance(
        test_hd_ws,
        peak_function_name='Gaussian',
        background_function_name='Linear',
        wavelength=np.nan)
    fit_result = fit_engine.fit_multiple_peaks(peak_tags=['Left', 'Right'],
                                               x_mins=(72.5, 77.5),
                                               x_maxs=(77.5, 82.5))

    # were there returns
    assert len(fit_result.peakcollections) == 2, 'Two PeakCollection'
    assert fit_result.fitted
    assert fit_result.difference

    # Verify fitting result
    # ['Height', 'PeakCentre', 'Sigma'],
    gaussian_native_params = PeakShape.GAUSSIAN.native_parameters
    gaussian_native_params.extend(BackgroundFunction.LINEAR.native_parameters)

    # peak 'Left'
    param_values_lp, param_errors_lp = fit_result.peakcollections[
        0].get_native_params()

    # peak 'Right'
    param_values_rp, param_errors_rp = fit_result.peakcollections[
        1].get_native_params()
    """
    Left
    Chi2: [0.3144778  0.32581177 0.31288937]
    Height (0)
        [ 9.75107193 15.30580711  0.10662809]
        [0.34154591 0.34128258 0.25921181]
    Center (1)
        [74.99655914 74.99921417 76.14541626]
        [0.0059319  0.00377185 0.75386631]
    Sigma (2)
        [0.14838572 0.14782989 0.28031287]
        [0.00608054 0.00388058 0.85695982]

    Right
    Chi2: [0.32870555 0.33221155 0.32712516]
    Note: chi2[0] can be infinity sometimes
    Height
        [0.41185206 4.91072798 7.52280378]
        [0.6211102  0.31933406 0.30802685]
    Center
        [78.88805389 79.9979248  80.00099945]
        [0.0767037  0.01266132 0.00856138]
    Sigma
        [0.04440744 0.17071389 0.18304431]
        [0.07783635 0.01304373 0.00897603]
    """

    # Get effective peak parameters
    effective_param_values, effective_param_errors = fit_result.peakcollections[
        0].get_effective_params()
    assert effective_param_values.size == 3, '3 subruns'
    assert len(
        effective_param_values.dtype.names) == 7, '7 effective parameters'

    # TODO it is odd that there are only two in the the setup function and 3 in the result
    np.testing.assert_allclose(param_values_lp['Height'][:2],
                               target_values['peak_height'],
                               atol=20.)
    np.testing.assert_allclose(param_values_lp['PeakCentre'][:2],
                               target_values['peak_center'],
                               rtol=50.)
    np.testing.assert_allclose(param_values_lp['Sigma'][:2],
                               target_values['sigma'],
                               rtol=50.)
    np.testing.assert_allclose(param_values_lp['A0'][:2],
                               target_values['background_A0'],
                               rtol=50.)
    np.testing.assert_allclose(param_values_lp['A1'][:2],
                               target_values['background_A1'],
                               rtol=50.)

    effective_param_values, effective_param_errors = fit_result.peakcollections[
        1].get_effective_params()
    assert effective_param_values.size == 3, '3 subruns'
    assert len(
        effective_param_values.dtype.names) == 7, '7 effective parameters'