예제 #1
0
    def __tables_to_peak_collection(self, peak_tag, table_params, table_errors):
        def convert_from_table_to_arrays(table_ws):  # TODO put this in mantid_helper
            # Table column names
            table_col_names = table_ws.getColumnNames()
            num_sub_runs = table_ws.rowCount()

            # Set the structured numpy array
            data_type_list = [(name, np.float32) for name in table_col_names]
            struct_array = np.zeros(num_sub_runs, dtype=data_type_list)

            # get fitted parameter value
            for col_index, param_name in enumerate(table_col_names):
                # get value from column in value table
                struct_array[param_name] = table_ws.column(col_index)

            return struct_array

        peak_params_value_array = convert_from_table_to_arrays(table_params)
        peak_params_error_array = convert_from_table_to_arrays(table_errors)
        fit_cost_array = peak_params_value_array['chi2']

        # Create PeakCollection instance
        peak_object = PeakCollection(peak_tag=peak_tag, peak_profile=self._peak_function,
                                     background_type=self._background_function, wavelength=self._wavelength)
        peak_object.set_peak_fitting_values(self._subruns, peak_params_value_array,
                                            peak_params_error_array, fit_cost_array)

        return peak_object
예제 #2
0
def test_peak_collection_init():
    assert PeakCollection('test1', 'Gaussian', 'Linear')

    assert PeakCollection('test2', 'Gaussian', 'Linear', wavelength=22.)

    d_peak_collection = PeakCollection('test3',
                                       'Gaussian',
                                       'Linear',
                                       d_reference=1.26)
    assert d_peak_collection
    d_ref, d_ref_err = d_peak_collection.get_d_reference()
    np.testing.assert_equal(d_ref, np.asarray((1.26, )))
    np.testing.assert_equal(d_ref_err, np.asarray((0., )))
예제 #3
0
    def read_peak_parameters(self, peak_tag):
        """Get the parameters related to a peak

        The parameters including
        (1) peak profile (2) sub runs (3) chi2 (4) parameter names (5) parameter values

        Returns
        -------
        ~pyrs.peaks.peak_collection.PeakCollection
            All of the information from fitting a peak across subruns
        """
        # Get main group
        peak_main_group = self._project_h5[HidraConstants.PEAKS]

        # Get peak entry
        if peak_tag not in peak_main_group.keys():
            raise RuntimeError('Peak tag {} cannot be found'.format(peak_tag))
        peak_entry = peak_main_group[peak_tag]

        # Get all the attribute and data
        profile = peak_entry.attrs[HidraConstants.PEAK_PROFILE]
        background = peak_entry.attrs[HidraConstants.BACKGROUND_TYPE]
        sub_run_array = peak_entry[HidraConstants.SUB_RUNS].value
        chi2_array = peak_entry[HidraConstants.PEAK_FIT_CHI2].value
        param_values = peak_entry[HidraConstants.PEAK_PARAMS].value
        error_values = peak_entry[HidraConstants.PEAK_PARAMS_ERROR].value

        # validate the information makes sense
        if param_values.shape != error_values.shape:
            raise RuntimeError(
                'Parameters[{}] and Errors[{}] have different shape'.format(
                    param_values.shape, error_values.shape))
        peak_collection = PeakCollection(peak_tag,
                                         profile,
                                         background,
                                         self.read_wavelengths(),
                                         projectfilename=self._file_name,
                                         runnumber=self.read_run_number())

        peak_collection.set_peak_fitting_values(subruns=sub_run_array,
                                                parameter_values=param_values,
                                                parameter_errors=error_values,
                                                fit_costs=chi2_array)

        # Optionally for strain: reference peak center in dSpacing: (strain)
        if HidraConstants.D_REFERENCE in list(peak_entry.keys()):
            # If reference position D is ever written to this project
            ref_d_array = peak_entry[HidraConstants.D_REFERENCE].value
            if HidraConstants.D_REFERENCE_ERROR in list(peak_entry.keys()):
                ref_d_error = peak_entry[
                    HidraConstants.D_REFERENCE_ERROR].value
                peak_collection.set_d_reference(ref_d_array, ref_d_error)
            else:
                peak_collection.set_d_reference(ref_d_array)

        return peak_collection
예제 #4
0
def check_peak_collection(peak_shape,
                          NUM_SUBRUN,
                          target_errors,
                          wavelength=None,
                          d_reference=None,
                          target_d_spacing_center=np.nan,
                          target_d_spacing_center_error=np.asarray([0., 0.]),
                          target_strain=np.nan,
                          target_strain_error=np.asarray([0., 0.])):
    """check the peak collection

    Parameters
    ----------
    subruns : numpy.array
        1D numpy array for sub run numbers
    peak_shape : str
            Peak shape
    target_errors : numpy.ndarray
        numpy structured array for peak/background parameter fitted target error
    wavelength : float
        neutron wavelength
    target_d_spacing_center : list
        d spacing center target value
    target_d_spacing_center_error : list
        d spacing center target error

    Returns
    -------

    """
    subruns = np.arange(NUM_SUBRUN) + 1
    chisq = np.array([42., 43.])
    raw_peaks_array = np.zeros(NUM_SUBRUN,
                               dtype=get_parameter_dtype(peak_shape, 'Linear'))
    if peak_shape == 'PseudoVoigt':
        raw_peaks_array['Intensity'] = [1, 2]
        raw_peaks_array['FWHM'] = np.array([4, 5], dtype=float)
        raw_peaks_array['Mixing'] = [0, 1]
    else:
        raw_peaks_array['Height'] = [1, 2]
        raw_peaks_array['Sigma'] = np.array([4, 5], dtype=float)
    raw_peaks_array['PeakCentre'] = [90., 91.]

    # background terms are both zeros
    raw_peaks_errors = np.zeros(NUM_SUBRUN,
                                dtype=get_parameter_dtype(
                                    peak_shape, 'Linear'))
    if wavelength is None:
        peaks = PeakCollection('testing', peak_shape, 'Linear')
    else:
        peaks = PeakCollection('testing',
                               peak_shape,
                               'Linear',
                               wavelength=wavelength)

    # uncertainties are being set to zero
    peaks.set_peak_fitting_values(subruns, raw_peaks_array, raw_peaks_errors,
                                  chisq)

    # check general features
    assert peaks
    np.testing.assert_equal(peaks.get_subruns(), subruns)
    np.testing.assert_equal(peaks.get_chisq(), chisq)
    assert len(peaks.get_fit_status()) == NUM_SUBRUN
    assert peaks.runnumber == -1  # tests don't have real data
    assert peaks.projectfilename == ''  # tests don't have real data

    # check raw/native parameters
    obs_raw_peaks, obs_raw_errors = peaks.get_native_params()
    np.testing.assert_equal(obs_raw_peaks, raw_peaks_array)
    np.testing.assert_equal(obs_raw_errors, raw_peaks_errors)
    # check effective parameters
    obs_eff_peaks, obs_eff_errors = peaks.get_effective_params()
    assert obs_eff_peaks.size == NUM_SUBRUN
    np.testing.assert_equal(obs_eff_errors, target_errors)
    np.testing.assert_equal(obs_eff_peaks['Center'],
                            raw_peaks_array['PeakCentre'])
    if peak_shape == 'PseudoVoigt':
        np.testing.assert_equal(obs_eff_peaks['Intensity'],
                                raw_peaks_array['Intensity'])
        np.testing.assert_equal(obs_eff_peaks['FWHM'], raw_peaks_array['FWHM'])
        np.testing.assert_equal(obs_eff_peaks['Mixing'],
                                raw_peaks_array['Mixing'])
    else:
        np.testing.assert_equal(obs_eff_peaks['Height'],
                                raw_peaks_array['Height'])
        np.testing.assert_equal(
            obs_eff_peaks['FWHM'],
            2. * np.sqrt(2. * np.log(2.)) * raw_peaks_array['Sigma'])
    np.testing.assert_equal(obs_eff_peaks['A0'], NUM_SUBRUN * [0.])
    np.testing.assert_equal(obs_eff_peaks['A1'], NUM_SUBRUN * [0.])

    # check d spacing
    obs_dspacing, obs_dspacing_errors = peaks.get_dspacing_center()
    np.testing.assert_allclose(obs_dspacing,
                               target_d_spacing_center,
                               atol=0.01)
    np.testing.assert_allclose(obs_dspacing_errors,
                               target_d_spacing_center_error,
                               atol=0.01)

    # check strain
    if d_reference is None:
        peaks.set_d_reference()
    else:
        peaks.set_d_reference(values=d_reference)
    microstrain, microstrain_error = peaks.get_strain(units='microstrain')
    np.testing.assert_allclose(microstrain, target_strain, atol=0.5)
    np.testing.assert_allclose(microstrain_error,
                               target_strain_error,
                               atol=0.5)

    # check the alternate units
    strain, strain_error = peaks.get_strain(units='strain')
    np.testing.assert_allclose(strain, microstrain / 1e6, atol=0.5)
    np.testing.assert_allclose(strain_error, microstrain_error / 1e6, atol=0.5)
예제 #5
0
def test_strain_io():
    """Test PeakCollection writing and reading with *D reference*

    Returns
    -------

    """
    # Generate a unique test file
    now = datetime.datetime.now()
    test_file_name = 'test_strain_io_{}.h5'.format(now.toordinal())
    test_ref_d = 1.23454321
    test_ref_d2 = np.array([1.23, 1.24, 1.25])
    peak_tag = 'Fake Peak D'
    peak_tag_2 = 'Fake Peak D Diff'

    # Generate a HiDRA project file
    test_project_file = HidraProjectFile(test_file_name,
                                         HidraProjectFileMode.OVERWRITE)

    # Create a ND array for output parameters
    param_names = PeakShape.PSEUDOVOIGT.native_parameters + BackgroundFunction.LINEAR.native_parameters
    data_type = list()
    for param_name in param_names:
        data_type.append((param_name, np.float32))
    test_error_array = np.zeros(3, dtype=data_type)
    test_params_array = np.zeros(3, dtype=data_type)

    for i in range(3):
        # sub run
        for j, par_name in enumerate(param_names):
            test_params_array[par_name][i] = 2**i + 0.1 * 3**j
            test_error_array[par_name][i] = np.sqrt(
                abs(test_params_array[par_name][i]))
    # END-FOR
    chi2_array = np.array([0.323, 0.423, 0.523])

    # Add test data to output
    peaks = PeakCollection(peak_tag, PeakShape.PSEUDOVOIGT,
                           BackgroundFunction.LINEAR)
    peaks.set_peak_fitting_values(np.array([1, 2, 3]), test_params_array,
                                  test_error_array, chi2_array)
    peaks.set_d_reference(test_ref_d)

    # Add 2nd peak
    peaks2 = PeakCollection(peak_tag_2, PeakShape.PSEUDOVOIGT,
                            BackgroundFunction.LINEAR)
    peaks2.set_peak_fitting_values(np.array([1, 2, 3]), test_params_array,
                                   test_error_array, chi2_array)
    peaks2.set_d_reference(test_ref_d2)

    # Write
    test_project_file.write_peak_parameters(peaks)
    test_project_file.write_peak_parameters(peaks2)
    # Save
    test_project_file.save(verbose=False)

    # Verify
    assert os.path.exists(test_file_name), 'Test project file for peak fitting result {} cannot be found.' \
                                           ''.format(test_file_name)

    # import
    verify_project_file = HidraProjectFile(test_file_name,
                                           HidraProjectFileMode.READONLY)

    # check tags
    peak_tags = verify_project_file.read_peak_tags()
    assert peak_tag in peak_tags and peak_tag_2 in peak_tags
    assert len(peak_tags) == 2

    # Get d-reference of peak 1 to check
    peak_info = verify_project_file.read_peak_parameters(peak_tag)
    verify_d_ref = peak_info.get_d_reference()
    gold_ref_d = np.array([test_ref_d] * 3)
    np.testing.assert_allclose(verify_d_ref, gold_ref_d)

    # Get d-reference of peak 2 to check
    peak_info2 = verify_project_file.read_peak_parameters(peak_tag_2)
    verify_d_ref_2 = peak_info2.get_d_reference()
    np.testing.assert_allclose(verify_d_ref_2, test_ref_d2)

    # Clean
    os.remove(test_file_name)

    return
예제 #6
0
def test_peak_fitting_result_io():
    """Test peak fitting result's writing and reading

    Returns
    -------

    """
    # Generate a unique test file
    now = datetime.datetime.now()
    test_file_name = 'test_peak_io_{}.hdf'.format(now.toordinal())

    # Generate a HiDRA project file
    test_project_file = HidraProjectFile(test_file_name,
                                         HidraProjectFileMode.OVERWRITE)

    # Create a ND array for output parameters
    param_names = PeakShape.PSEUDOVOIGT.native_parameters + BackgroundFunction.LINEAR.native_parameters
    data_type = list()
    for param_name in param_names:
        data_type.append((param_name, np.float32))
    test_error_array = np.zeros(3, dtype=data_type)
    test_params_array = np.zeros(3, dtype=data_type)

    for i in range(3):
        # sub run
        for j, par_name in enumerate(param_names):
            test_params_array[par_name][i] = 2**i + 0.1 * 3**j
            test_error_array[par_name][i] = np.sqrt(
                abs(test_params_array[par_name][i]))
    # END-FOR
    chi2_array = np.array([0.323, 0.423, 0.523])

    # Add test data to output
    peaks = PeakCollection('test fake', PeakShape.PSEUDOVOIGT,
                           BackgroundFunction.LINEAR)
    peaks.set_peak_fitting_values(np.array([1, 2, 3]), test_params_array,
                                  test_error_array, chi2_array)

    test_project_file.write_peak_parameters(peaks)

    test_project_file.save(False)

    # Check
    assert os.path.exists(test_file_name), 'Test project file for peak fitting result {} cannot be found.' \
                                           ''.format(test_file_name)
    print('[INFO] Peak parameter test project file: {}'.format(test_file_name))

    # Import
    verify_project_file = HidraProjectFile(test_file_name,
                                           HidraProjectFileMode.READONLY)

    # get the tags
    peak_tags = verify_project_file.read_peak_tags()
    assert 'test fake' in peak_tags
    assert len(peak_tags) == 1

    # get the parameter of certain
    peak_info = verify_project_file.read_peak_parameters('test fake')

    # peak profile
    assert peak_info.peak_profile == str(PeakShape.PSEUDOVOIGT)
    assert peak_info.background_type == str(BackgroundFunction.LINEAR)

    # sub runs
    assert np.allclose(peak_info.sub_runs, np.array([1, 2, 3]))

    # parameter values
    # print('DEBUG:\n  Expected: {}\n  Found: {}'.format(test_params_array, peak_info[3]))
    peak_values, peak_errors = peak_info.get_native_params()
    assert_allclose_structured_numpy_arrays(test_params_array, peak_values)
    # np.testing.assert_allclose(peak_info[3], test_params_array, atol=1E-12)

    # parameter values
    # assert np.allclose(peak_info[4], test_error_array, 1E-12)
    assert_allclose_structured_numpy_arrays(test_error_array, peak_errors)

    # Clean
    os.remove(test_file_name)

    return
예제 #7
0
def test_write_csv():
    csv_filename = 'test_write_single.csv'
    if os.path.exists(csv_filename):
        os.remove(csv_filename)

    # create a PeakCollection
    gaussian = PeakShape.GAUSSIAN
    linear = BackgroundFunction.LINEAR

    subruns = [1, 2, 3]
    data_type = [
        (name, numpy.float32)
        for name in gaussian.native_parameters + linear.native_parameters
    ]
    data = numpy.zeros(len(subruns),
                       dtype=data_type)  # doesn't matter what the values are
    error = numpy.zeros(len(subruns),
                        dtype=data_type)  # doesn't matter what the values are

    peaks = PeakCollection('fake', gaussian, linear)
    peaks.set_peak_fitting_values(subruns, data, error, [10., 20., 30.])

    # create a SampleLog
    sample = SampleLogs()
    sample.subruns = subruns
    sample['variable1'] = numpy.linspace(0., 100., len(subruns))
    sample['variable2'] = numpy.linspace(
        100., 200., len(subruns))  # not to be found in the output
    sample['constant1'] = numpy.linspace(
        1., 1. + 5E-11, len(subruns))  # values less than tolerance
    sample['string1'] = numpy.array(
        ['a constant string'] *
        sample.subruns.size)  # will be constant as well

    # write things out to disk
    generator = SummaryGenerator(
        csv_filename,
        log_list=['variable1', 'constant1', 'missing1', 'string1'])
    generator.setHeaderInformation(dict())  # means empty header

    generator.write_csv(sample, [peaks])

    assert os.path.exists(csv_filename), '{} was not created'.format(
        csv_filename)

    EXPECTED_HEADER = '''# IPTS number
# Run
# Scan title
# Sample name
# Item number
# HKL phase
# Strain direction
# Monochromator setting
# Calibration file
# Hidra project file
# Manual vs auto reduction
# missing: missing1
# constant1 = 1 +/- 2e-11
# string1 = a constant string'''.split('\n')

    # verify the file contents
    with open(csv_filename, 'r') as handle:
        # read in the file and remove whitespace
        contents = [line.strip() for line in handle.readlines()]

    # verify exact match on the header
    for exp, obs in zip(contents[:len(EXPECTED_HEADER)], EXPECTED_HEADER):
        assert exp == obs

    # verify the column headers
    assert contents[len(EXPECTED_HEADER)].startswith(
        'sub-run,variable1,fake_dspacing_center,')
    assert contents[len(EXPECTED_HEADER)].endswith(',fake_chisq')

    assert len(contents) == len(EXPECTED_HEADER) + 1 + len(
        subruns), 'Does not have full body'
    # verify that the number of columns is correct
    # columns are (subruns, one log, parameter values, uncertainties, chisq)
    for line in contents[len(EXPECTED_HEADER) +
                         1:]:  # skip past header and constant log
        assert len(line.split(',')) == 1 + 1 + 9 * 2 + 1

    # cleanup
    os.remove(csv_filename)