예제 #1
0
def test_save_and_read_csv_without_name(tmpdir):
    original_fitting_data = FittingData(data=RAW_DATA)
    original_fitting_data.save_csv(tmpdir)
    loaded_fitting_data = FittingData.read_from_csv(
        Path(tmpdir / "fitting_data.csv"))

    assert_fitting_data_are_equal(original_fitting_data, loaded_fitting_data)
예제 #2
0
def case_unselect_one_record():
    fitting_data = FittingData(COLUMNS)
    fitting_data.unselect_record(2)
    return (
        fitting_data,
        [1] + list(range(3, NUMBER_OF_RECORDS + 1)),
    )
def test_set_cell_not_allowed_because_of_non_existing_row():
    fitting_data = FittingData(COLUMNS)
    value = np.random.uniform(0, 10)
    column = np.random.choice(COLUMNS_NAMES)

    with pytest.raises(FittingDataSetError, match="^Record number 13 does not exists$"):
        fitting_data.set_cell(NUMBER_OF_RECORDS + 1, column, value)
예제 #4
0
def test_save_and_read_excel_without_name(tmpdir):
    original_fitting_data = FittingData(data=RAW_DATA)
    original_fitting_data.save_excel(tmpdir, sheet=SHEET_NAME)
    loaded_fitting_data = FittingData.read_from_excel(
        Path(tmpdir / "fitting_data.xlsx"), SHEET_NAME)

    assert_fitting_data_are_equal(original_fitting_data, loaded_fitting_data)
def test_set_header_with_same_header_does_not_change_anything(header_name):
    fitting_data = FittingData(COLUMNS)
    fitting_data.set_header(header_name, header_name)

    for header in COLUMNS_NAMES:
        assert fitting_data.data[header] == pytest.approx(
            COLUMNS[header]
        ), f'Header "{header}" has changed unexpectedly'
예제 #6
0
def case_select_multiple_records():
    fitting_data = FittingData(COLUMNS)
    fitting_data.unselect_all_records()
    fitting_data.select_record(2)
    fitting_data.select_record(5)
    fitting_data.select_record(3)
    fitting_data.select_record(10)
    return fitting_data, [2, 3, 5, 10]
def test_set_cell_not_allowed_because_of_non_existing_column():
    fitting_data = FittingData(COLUMNS)
    value = np.random.uniform(0, 10)

    with pytest.raises(
        FittingDataSetError, match='^Column name "I do not exist" does not exists$'
    ):
        fitting_data.set_cell(0, "I do not exist", value)
def test_header_cannot_already_exist(header_name):
    fitting_data = FittingData(COLUMNS)
    new_header = np.random.choice(
        [header for header in COLUMNS_NAMES if header != header_name]
    )
    with pytest.raises(
        FittingDataSetError, match=f'^The column name:"{new_header}" is already used.$'
    ):
        fitting_data.set_header(header_name, new_header)
예제 #9
0
def case_select_all_records():
    fitting_data = FittingData(COLUMNS)
    fitting_data.unselect_all_records()
    fitting_data.select_record(2)
    fitting_data.select_record(5)
    fitting_data.select_all_records()
    return fitting_data, list(range(1, NUMBER_OF_RECORDS + 1))
예제 #10
0
def case_unselect_multiple():
    fitting_data = FittingData(COLUMNS)
    fitting_data.unselect_record(2)
    fitting_data.unselect_record(5)
    fitting_data.unselect_record(3)
    fitting_data.unselect_record(10)
    return fitting_data, [1, 4, 6, 7, 8, 9] + list(range(11, NUMBER_OF_RECORDS + 1))
def test_set_cell_not_allowed_because_of_non_float_value():
    fitting_data = FittingData(COLUMNS)
    column = np.random.choice(COLUMNS_NAMES)
    record = np.random.randint(1, NUMBER_OF_RECORDS + 1)
    value = "I'm not a float"

    with pytest.raises(
        FittingDataSetError,
        match=(
            f'^The cell at record number:"{record}", column:"{column}"'
            f" has invalid syntax: I'm not a float.$"
        ),
    ):
        fitting_data.set_cell(record, column, value)
def test_x_larger_than_size(column):
    with pytest.raises(
            FittingDataColumnIndexError,
            match=
            "^No column number 11 in data. index should be between 1 and 10$",
    ):
        FittingData(COLUMNS, **{column: 11})
예제 #13
0
def case_fitting(case_path):
    with open(str(case_path), mode="r") as json_file:
        json_obj = json.load(json_file)
    func_name = json_obj["fit_function"]
    func = FittingFunctionsRegistry.load(func_name)
    fix = json_obj.get("fix", None)
    if fix is not None:
        for index, value in fix:
            func.fix(index, value)
    data_dict = json_obj["data"]
    data = FittingData(
        OrderedDict([
            ("x", data_dict["x"]),
            ("xerr", data_dict["xerr"]),
            ("y", data_dict["y"]),
            ("yerr", data_dict["yerr"]),
        ]))
    a0 = json_obj.get("a0", None)
    result = fit(data=data, func=func, a0=a0)
    decimal = json_obj.get("decimal", 2)
    inp = dict(actual_result=result,
               a0=a0,
               func=func,
               delta=np.power(10.0, -decimal))
    expected_result = json_obj["result"]
    return inp, expected_result
def test_x_zero_index(column):
    with pytest.raises(
            FittingDataColumnIndexError,
            match=
            "^No column number 0 in data. index should be between 1 and 10$",
    ):
        FittingData(COLUMNS, **{column: 0})
예제 #15
0
    def read_csv(self, filepath):
        """
        Read data from csv file.

        :param filepath: path of the csv file
        """
        self.fitting_data = FittingData.read_from_csv(filepath)
def test_set_header_allowed(i):
    old_header = COLUMNS_NAMES[i]
    new_header = "new_header"
    fitting_data = FittingData(deepcopy(COLUMNS))
    fitting_data.set_header(old_header, new_header)

    constant_headers = [header for header in COLUMNS_NAMES if header != old_header]
    for header in constant_headers:
        assert fitting_data.data[header] == pytest.approx(
            COLUMNS[header]
        ), f'Header "{header}" has changed unexpectedly'
    assert fitting_data.data[new_header] == pytest.approx(
        COLUMNS[old_header]
    ), f'Header "{new_header}" has changed unexpectedly'
    assert set(fitting_data.all_columns) == set(
        constant_headers + [new_header]
    ), "Did not update all columns"
def test_exception_risen_because_of_columns_length():
    data = deepcopy(COLUMNS)
    data["a"] = data["a"][:-2]
    with pytest.raises(
            FittingDataColumnsLengthError,
            match="^All columns in FittingData should have the same length$",
    ):
        FittingData(data=data)
def case_jumbled_columns():
    fitting_data = FittingData(COLUMNS,
                               x_column=3,
                               xerr_column=1,
                               y_column="b",
                               yerr_column=9)
    expected_columns = Columns(x="c", xerr="a", y="b", yerr="i")
    return fitting_data, expected_columns
예제 #19
0
    def read_excel(self, filepath, sheet):
        """
        Read data from excel file.

        :param filepath: path of the excel file
        :param sheet: sheet from which to read the data.
        """
        self.fitting_data = FittingData.read_from_excel(filepath, sheet)
def test_set_cell_allowed(record_number, column_name):
    fitting_data = FittingData(deepcopy(COLUMNS))
    value = np.random.uniform(0, 10)
    fitting_data.set_cell(
        record_number=record_number,
        column_name=column_name,
        value=value,
    )

    for column in COLUMNS_NAMES:
        for i in range(NUMBER_OF_RECORDS):
            if column == column_name and i + 1 == record_number:
                assert fitting_data.data[column][i] == value, "New value was not set"
            else:
                assert (
                    fitting_data.data[column][i] == COLUMNS[column][i]
                ), "Data was change unexpectedly"
예제 #21
0
def test_set_selection_with_different_size():
    fitting_data = FittingData(COLUMNS)

    def set_records_indices():
        fitting_data.records_indices = [False, False, True]

    with pytest.raises(
        FittingDataColumnsSelectionError,
        match=f"^Should select {NUMBER_OF_RECORDS} records, only 3 selected.$",
    ):
        set_records_indices()
예제 #22
0
def test_set_selection_with_non_boolean_values():
    fitting_data = FittingData(COLUMNS)

    def set_records_indices():
        fitting_data.records_indices = [False, False, "dummy"] + [True] * (
            NUMBER_OF_RECORDS - 3
        )

    with pytest.raises(
        FittingDataColumnsSelectionError,
        match="^When setting record indices, all values should be booleans.$",
    ):
        set_records_indices()
 def __init__(self, fitting_data: FittingData, app: toga.App):
     """Initialize window."""
     super().__init__(title="Choose Records", size=RECORD_WINDOW_SIZE)
     main_box = toga.Box(style=Pack(direction=COLUMN))
     data_box = toga.Box()
     self.__checkboxes = [
         toga.Switch(
             label="",
             is_on=fitting_data.is_selected(i),
             style=Pack(height=LINE_HEIGHT),
         ) for i in range(1, fitting_data.length + 1)
     ]
     data_box.add(
         toga.Box(
             style=Pack(
                 flex=1,
                 direction=COLUMN,
                 padding_left=SMALL_PADDING,
                 padding_right=SMALL_PADDING,
             ),
             children=[
                 toga.Label(text="Chosen", style=Pack(height=LINE_HEIGHT))
             ] + self.__checkboxes,  # noqa: W503
         ))
     for header, column in fitting_data.data.items():
         data_box.add(
             toga.Box(
                 style=Pack(
                     flex=1,
                     direction=COLUMN,
                     padding_left=SMALL_PADDING,
                     padding_right=SMALL_PADDING,
                 ),
                 children=[
                     toga.Label(text=header, style=Pack(height=LINE_HEIGHT))
                 ] + [  # noqa: W503
                     toga.Label(text=element,
                                style=Pack(height=LINE_HEIGHT))
                     for element in column
                 ],
             ))
     main_box.add(data_box)
     main_box.add(
         LineBox(children=[
             toga.Button(label="Save",
                         on_press=self.save_action(fitting_data))
         ], ))
     scroller = toga.ScrollContainer(content=main_box)
     self.content = scroller
     self.app = app
예제 #24
0
def function_cases(odr_mock, request):
    func, kwargs, model_extra_kwargs, fit_a0 = (
        request.param["func"],
        request.param.get("kwargs", {}),
        request.param.get("model_extra_kwargs", {}),
        request.param.get("a0", a0),
    )
    data = FittingData.random(fit_func=func)
    result = fit(data=data, func=func, a0=fit_a0, **kwargs)
    return dict(
        func=func,
        data=data,
        result=result,
        model_extra_kwargs=model_extra_kwargs,
        a0=fit_a0,
        mocks=odr_mock,
    )
예제 #25
0
def random_fitting_data(mocker, fitting_arguments, random_sigma_mock,
                        random_error_mock):
    random_array_mock = mocker.patch("eddington.fitting_data.random_array")
    random_array_side_effect = []
    if "a" not in fitting_arguments:
        random_array_side_effect.append(a)
    if "x" not in fitting_arguments:
        random_array_side_effect.append(x)
    random_array_mock.side_effect = random_array_side_effect
    return (
        FittingData.random(dummy_func1, **fitting_arguments),
        dict(
            params=fitting_arguments,
            random_array=random_array_mock,
            random_sigma=random_sigma_mock,
            random_error=random_error_mock,
        ),
    )
예제 #26
0
    def select_default_sheet(self):
        """
        Automatically choose the first valid sheet.

        If it fails to find a valid sheet, resets the input file.
        """
        for sheet in self.input_file_box.sheets_options:
            if sheet != NO_VALUE:
                try:
                    self.data_columns_box.fitting_data = FittingData.read_from_excel(
                        Path(self.input_file_box.file_path), sheet)
                    self.input_file_box.selected_sheet = sheet
                    return
                except FittingDataError:
                    pass

        if self.data_columns_box.fitting_data is None:
            self.main_window.error_dialog(
                title="Input data error",
                message=("No sheet available with valid data.\n"
                         "Please fix the file or load another one."),
            )
            self.input_file_box.file_path = None
def test_header_cannot_be_set_to_be_empty(header_name):
    fitting_data = FittingData(COLUMNS)
    with pytest.raises(
        FittingDataSetError, match="^Cannot set new header to be empty$"
    ):
        fitting_data.set_header(header_name, "")
예제 #28
0
from eddington import FittingData
from tests.fitting_data import (
    COLUMNS,
    COLUMNS_NAMES,
    CONTENT,
    DEFAULT_SHEET,
    NUMBER_OF_RECORDS,
)

DECIMAL = 5

DIRECTORY_PATH = Path("/path/to/directory")
EPSILON = 1e-5

FIT_DATA = FittingData(COLUMNS)


def assert_workbook_calls(workbook,
                          sheet_name=DEFAULT_SHEET,
                          name="fitting_data"):
    worksheet = workbook.active
    assert worksheet.title == sheet_name
    assert (worksheet.append.call_count == NUMBER_OF_RECORDS +
            1), "worksheet append called unexpected number of times"
    assert worksheet.append.call_args_list[0] == call(
        COLUMNS_NAMES), "worksheet append called unexpected number of times"
    for i in range(NUMBER_OF_RECORDS):
        assert worksheet.append.call_args_list[i + 1][0][0] == pytest.approx(
            CONTENT[i],
            rel=EPSILON), "worksheet append called unexpected number of times"
예제 #29
0
    def __init__(self, fitting_data: FittingData, font_size: FontSize,
                 app: toga.App):
        """Initialize window."""
        super().__init__(title="Choose Records", size=RECORD_WINDOW_SIZE)
        self.__fitting_data = fitting_data
        main_box = toga.Box(style=Pack(direction=COLUMN))
        data_box = toga.Box()
        statistics_box = toga.Box()
        font_size_value = FontSize.get_font_size(font_size)
        self.__update_on_check = True
        self.__statistics_labels = {
            (column, parameter): toga.Label(
                text=to_relevant_precision_string(
                    getattr(fitting_data.statistics(column), parameter, 0)),
                style=Pack(height=LINE_HEIGHT,
                           width=COLUMN_WIDTH,
                           font_size=font_size_value),
            )
            for column, parameter in itertools.product(
                fitting_data.all_columns, Statistics.parameters())
        }
        self.__checkboxes = [
            toga.Switch(
                label="",
                is_on=fitting_data.is_selected(i),
                on_toggle=self.select_records,
                style=Pack(height=LINE_HEIGHT,
                           width=COLUMN_WIDTH,
                           font_size=font_size_value),
            ) for i in range(1, fitting_data.length + 1)
        ]
        self.__all_checkbox = toga.Switch(
            label="",
            is_on=self.are_all_selected(),
            on_toggle=self.select_all,
            style=Pack(height=TITLES_LINE_HEIGHT, font_size=font_size_value),
        )
        self.__selected_records_label = toga.Label(
            text="",
            style=Pack(font_size=font_size_value,
                       width=COLUMN_WIDTH,
                       height=TITLES_LINE_HEIGHT),
        )
        data_box.add(
            toga.Box(
                style=Pack(
                    flex=1,
                    direction=COLUMN,
                    padding_left=SMALL_PADDING,
                    padding_right=SMALL_PADDING,
                ),
                children=[
                    toga.Box(
                        style=Pack(
                            height=TITLES_LINE_HEIGHT,
                            font_size=font_size_value,
                        ),
                        children=[
                            self.__all_checkbox, self.__selected_records_label
                        ],
                    ),
                    *self.__checkboxes,
                ],
            ))
        for header, column in fitting_data.data.items():
            data_box.add(
                toga.Box(
                    style=Pack(
                        flex=1,
                        direction=COLUMN,
                        padding_left=SMALL_PADDING,
                        padding_right=SMALL_PADDING,
                    ),
                    children=[
                        toga.Label(
                            text=header,
                            style=Pack(
                                height=TITLES_LINE_HEIGHT,
                                width=COLUMN_WIDTH,
                                font_size=font_size_value,
                                font_weight=BOLD,
                            ),
                        ),
                        *[
                            toga.Label(
                                text=to_relevant_precision_string(element),
                                style=Pack(
                                    height=LINE_HEIGHT,
                                    width=COLUMN_WIDTH,
                                    font_size=font_size_value,
                                ),
                            ) for element in column
                        ],
                    ],
                ))
        main_box.add(data_box)
        main_box.add(toga.Divider())
        statistics_box.add(
            toga.Box(
                style=Pack(
                    flex=1,
                    direction=COLUMN,
                    padding_left=SMALL_PADDING,
                    padding_right=SMALL_PADDING,
                ),
                children=[
                    toga.Label(
                        text=parameter.replace("_", " ").title(),
                        style=Pack(
                            height=LINE_HEIGHT,
                            width=COLUMN_WIDTH,
                            font_size=font_size_value,
                            font_weight=BOLD,
                        ),
                    ) for parameter in Statistics.parameters()
                ],
            ))
        for header, column in fitting_data.data.items():
            statistics_box.add(
                toga.Box(
                    style=Pack(
                        flex=1,
                        direction=COLUMN,
                        padding_left=SMALL_PADDING,
                        padding_right=SMALL_PADDING,
                    ),
                    children=[
                        self.__statistics_labels[(header, parameter)]
                        for parameter in Statistics.parameters()
                    ],
                ))
        main_box.add(statistics_box)
        main_box.add(
            LineBox(children=[
                toga.Button(label="Close", on_press=lambda _: self.close())
            ], ))
        scroller = toga.ScrollContainer(content=main_box)
        self.content = scroller
        self.app = app

        self.update()
예제 #30
0
HAS_LEGEND = "has_legend"
DOES_NOT_HAVE_LEGEND = "does_not_have_legend"

EPSILON = 1e-5

FUNC = linear
X = np.arange(1, 11)
A1, A2, A3 = np.array([1, 1]), np.array([3,
                                         2]), np.array([3.924356, 1.2345e-5])
A1_REPR, A2_REPR, A3_REPR = (
    "[a[0]=1.000, a[1]=1.000]",
    "[a[0]=3.000, a[1]=2.000]",
    "[a[0]=3.924, a[1]=1.234e-05]",
)
FIT_DATA = FittingData.random(FUNC,
                              x=X,
                              a=np.array([1, 2]),
                              measurements=X.shape[0])
TITLE_NAME = "Title"


@case(tags=[DOES_NOT_HAVE_LEGEND])
def case_no_args(mock_figure):
    x = np.arange(0.1, 10.9, step=0.0108)

    kwargs = dict(a=A1)
    plot_calls = [([x, FUNC(A1, x)], dict(label=A1_REPR))]
    return kwargs, plot_calls, mock_figure


@case(tags=[DOES_NOT_HAVE_LEGEND])
def case_xmin(mock_figure):