def test_correct_data_multi_fit(self): """ Tests correct data on a multifit problem. """ fitting_problem = FittingProblem(self.options) fitting_problem.multifit = True x_data = [ np.array([-0.5, 0.0, 1.0, 0.5, 1.5, 2.0, 2.5, 3.0, 4.0]), np.array([-0.5, 0.0, 1.0, 0.5, 1.4, 2.0, 2.5, 3.0, 4.0]), np.array([-0.5, 0.0, 1.0, 0.5, 1.7, 2.0, 2.5, 3.0, 4.0]) ] y_data = [ np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]), np.array([0.0, 1.0, 2.0, 3.0, 24.0, 5.0, 6.0, 7.0, 8.0]), np.array([0.0, 1.0, 2.8, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]) ] e_data = [ np.array([1.0, 20.0, 30.0, 40.0, 50.0, 60.0, 1.0, 6.0, 9.0]), np.array([1.0, 20.0, 30.0, 40.0, 50.0, 60.0, 1.0, 6.0, 9.0]), np.array([1.0, 20.0, 30.0, 40.0, 50.0, 60.0, 1.0, 6.0, 9.0]) ] start_x = [0.5, 1.1, 0.0] end_x = [2.5, 2.6, 1.0] expected_x_data = [ np.array([0.5, 1.0, 1.5, 2.0, 2.5]), np.array([1.4, 2.0, 2.5]), np.array([0.0, 0.5, 1.0]) ] expected_y_data = [ np.array([3.0, 2.0, 4.0, 5.0, 6.0]), np.array([24.0, 5.0, 6.0]), np.array([1.0, 3.0, 2.8]) ] expected_e_data = [ np.array([40.0, 30.0, 50.0, 60.0, 1.0]), np.array([50.0, 60.0, 1.0]), np.array([20.0, 40.0, 30.0]) ] fitting_problem.data_x = x_data fitting_problem.data_y = y_data fitting_problem.data_e = e_data fitting_problem.start_x = start_x fitting_problem.end_x = end_x fitting_problem.correct_data() for i in range(3): self.assertTrue( np.isclose( fitting_problem.data_x[i][fitting_problem.sorted_index[i]], expected_x_data[i]).all()) self.assertTrue( np.isclose( fitting_problem.data_y[i][fitting_problem.sorted_index[i]], expected_y_data[i]).all()) self.assertTrue( np.isclose( fitting_problem.data_e[i][fitting_problem.sorted_index[i]], expected_e_data[i]).all()) self.options.cost_func_type = "nlls" fitting_problem.correct_data() for i in range(3): self.assertTrue( np.isclose( fitting_problem.data_x[i][fitting_problem.sorted_index[i]], expected_x_data[i]).all()) self.assertTrue( np.isclose( fitting_problem.data_y[i][fitting_problem.sorted_index[i]], expected_y_data[i]).all()) self.assertIs(fitting_problem.data_e[i], None)
def parse(self): """ Parse the Fitbenchmark problem file into a Fitting Problem. :return: The fully parsed fitting problem :rtype: fitbenchmarking.parsing.fitting_problem.FittingProblem """ # pylint: disable=attribute-defined-outside-init fitting_problem = FittingProblem(self.options) self._entries = self._get_data_problem_entries() software = self._entries['software'].lower() if not (software in import_success and import_success[software][0]): error = import_success[software][1] raise MissingSoftwareError('Requirements are missing for {} parser' ': {}'.format(software, error)) self._parsed_func = self._parse_function() if software == 'mantid' and self._entries['input_file'][0] == '[': fitting_problem.multifit = True # NAME fitting_problem.name = self._entries['name'] # DATA data_points = [_get_data_points(p) for p in self._get_data_file()] # FUNCTION if software == 'mantid': fitting_problem.function = self._create_mantid_function() fitting_problem.format = 'mantid' elif software == 'sasview': fitting_problem.function = self._create_sasview_function() fitting_problem.format = 'sasview' # EQUATION equation_count = len(self._parsed_func) if equation_count == 1: fitting_problem.equation = self._parsed_func[0]['name'] else: fitting_problem.equation = '{} Functions'.format(equation_count) # STARTING VALUES fitting_problem.starting_values = self._get_starting_values() # PARAMETER RANGES vr = _parse_range(self._entries.get('parameter_ranges', '')) fitting_problem.value_ranges = vr if vr != {} else None # FIT RANGES fit_ranges_str = self._entries.get('fit_ranges', '') # this creates a list of strs like '{key: val, ...}' and parses each fit_ranges = [ _parse_range('{' + r.split('}')[0] + '}') for r in fit_ranges_str.split('{')[1:] ] if fitting_problem.multifit: num_files = len(data_points) fitting_problem.data_x = [d[:, 0] for d in data_points] fitting_problem.data_y = [d[:, 1] for d in data_points] fitting_problem.data_e = [ d[:, 2] if d.shape[1] > 2 else None for d in data_points ] if not fit_ranges: fit_ranges = [{} for _ in range(num_files)] fitting_problem.start_x = [ f['x'][0] if 'x' in f else None for f in fit_ranges ] fitting_problem.end_x = [ f['x'][1] if 'x' in f else None for f in fit_ranges ] else: fitting_problem.data_x = data_points[0][:, 0] fitting_problem.data_y = data_points[0][:, 1] if data_points[0].shape[1] > 2: fitting_problem.data_e = data_points[0][:, 2] if fit_ranges and 'x' in fit_ranges[0]: fitting_problem.start_x = fit_ranges[0]['x'][0] fitting_problem.end_x = fit_ranges[0]['x'][1] if software == 'mantid': # String containing the function name(s) and the starting parameter # values for each function. fitting_problem.additional_info['mantid_equation'] \ = self._entries['function'] if fitting_problem.multifit: fitting_problem.additional_info['mantid_ties'] \ = self._parse_ties() return fitting_problem