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
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., )))
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
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)
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
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
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)