Skip to content

Commit

Permalink
Merge branch 'main' into ns-rse/748-grain-profiles-grainstats
Browse files Browse the repository at this point in the history
  • Loading branch information
ns-rse committed Apr 15, 2024
2 parents 50c0c36 + a5f4926 commit 74916b1
Show file tree
Hide file tree
Showing 33 changed files with 2,317 additions and 1,121 deletions.
27 changes: 27 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
# numpydoc validation - Linting docstrings with pre-commit numpydoc
836e1bf5347eb7a9f97e784e783045c0287b3fe9
2580811edefac867938ee0c4b705649a493e5d4f
b35307bb55c703b44f6a28652e33dd64cc184e43
af779c5a16c261716097573ba8cb8a5f882e04c0
7f0818349e7a06d51654d0554e8ba8a879402ddb
57a0c001d79c72fd459158fcec7acb27dfae2734
7a265dab01aa661965adf7cb0c85605e08366ea8
83649f8697746e5c839ee90d1dc04d3a96777657
31b3c86f532ba6c276af393dc78c839b5007fe7b
0af8d30ff4685ee721b25272b36b3652aeaeb18f
e028184b234e50dd67abdf1cf81e40d90f72f4f1
46e014b1b5b73d089068e81874b56d0141eec9a3
db41c74333a5ee0fbb9758155770c282e01e7ecb
acfc93c178c54fef30266a27c1b0d418d0c367c7
0c4c4f7b7f448339f83af856c78979bb0c20554a
f79295ed2fbf989c392caf554d82077bfea7756e
119e3d989f84f6711c1140a7dd8617fbffaa39e1
e18d311603fbf1e9c4251382dea6d11a91a2dc17
165f5dc1688d590b326d5664c9211eb4d10dcb6a
3fc2d275f2d354918d0c431a786ec6aac48843a9
86bae88351eec40ad18163478f070b972231283b
0fd0707948c1fbca47fc4e79b7a2c04b36da5c4f
583e0e3b9edcd31d3f81c31313999ed2016ae091
68a220ab800406a84f726a850cc0a2230f862eb3
a0aef99cb350575e481d0d6e8c5c39e1f0704017

# codespell
e9f1c8fa0904d643285901110e7a026f3427dc15

Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
matrix:
os: ["ubuntu-latest", "macos-latest", "windows-latest"]
python-version: ["3.9", "3.10", "3.11"]
python-version: ["3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- name: Set up Python
Expand All @@ -25,7 +25,11 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Upgrade pip and install test dependencies
run: |
pip install --upgrade pip
pip install --upgrade virtualenv
pip install --upgrade pip setuptools
pip show pip setuptools
virtualenv --upgrade-embed-wheels
# virtualenv --reset-app-data
pip install -e .[tests]
- name: Test with pytest
run: |
Expand Down
11 changes: 8 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,20 @@ repos:
args: []

- repo: https://github.com/asottile/pyupgrade
rev: v3.15.0
rev: v3.15.2
hooks:
- id: pyupgrade
args: [--py38-plus]

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.2.0
rev: v0.3.5
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix, --show-fixes]

- repo: https://github.com/psf/black-pre-commit-mirror
rev: 24.1.1
rev: 24.3.0
hooks:
- id: black
types: [python]
Expand Down Expand Up @@ -68,6 +68,11 @@ repos:
hooks:
- id: nbstripout

- repo: https://github.com/numpy/numpydoc
rev: v1.7.0
hooks:
- id: numpydoc-validation

- repo: local
hooks:
- id: pylint
Expand Down
23 changes: 23 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,29 @@ skip = '*.spm*,*.mplstyle'
count = ''
quiet-level = 3

[tool.numpydoc_validation]
checks = [
"all", # Perform all check except those listed below
"ES01",
"EX01",
"PR10", # Conflicts with black formatting
"SA01",
]
exclude = [ # don't report on objects that match any of these regex
"\\.undocumented_method$",
"\\.__repr__$",
"^test_",
"^conftest",
"^dnatrcing",
"^tracingfuncs",
"^conf$",
]
override_SS05 = [ # override SS05 to allow docstrings starting with these words
"^Process ",
"^Assess ",
"^Access ",
]

[project.scripts]
topostats = "topostats.entry_point:entry_point"
run_topostats = "topostats.entry_point:legacy_run_topostats_entry_point"
Expand Down
8 changes: 8 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import numpy as np
import pandas as pd
import pySPM
import pytest
import yaml

Expand Down Expand Up @@ -373,6 +374,13 @@ def load_scan_spm() -> LoadScans:
return LoadScans([RESOURCES / "minicircle.spm"], channel="Height")


@pytest.fixture()
def spm_channel_data() -> pySPM.SPM.SPM_image:
"""Instantiate channel data from a LoadScans object."""
scan = pySPM.Bruker(RESOURCES / "minicircle.spm")
return scan.get_channel("Height")


@pytest.fixture()
def load_scan_ibw() -> LoadScans:
"""Instantiate a LoadScans object from a .ibw file."""
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 26 additions & 19 deletions tests/test_entry_point.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,42 +68,49 @@ def test_entry_point_subprocess_help(capsys, argument: str, option: str) -> None
@pytest.mark.parametrize(
("options", "expected_function", "expected_arg_name", "expected_arg_value"),
[
(
pytest.param(
[
"process",
"-c dummy/config/dir/config.yaml",
"-c",
"dummy/config/dir/config.yaml",
],
run_topostats,
"config_file",
" dummy/config/dir/config.yaml",
Path("dummy/config/dir/config.yaml"),
id="Process with config file argument",
),
(
pytest.param(
[
"process",
"-b /tmp/",
"-b",
"/tmp/", # noqa: S108
],
run_topostats,
"base_dir",
" /tmp/",
Path("/tmp/"), # noqa: S108
id="Process with base dir argument",
),
(
pytest.param(
[
"create-config",
"--filename",
"dummy/config/dir/config.yaml",
],
write_config_with_comments,
"filename",
"dummy/config/dir/config.yaml",
Path("dummy/config/dir/config.yaml"),
id="Create config with output filename",
),
(
pytest.param(
[
"summary",
"-l dummy/config/dir/var_to_label.yaml",
"-l",
"dummy/config/dir/var_to_label.yaml",
],
run_toposum,
"var_to_label",
" dummy/config/dir/var_to_label.yaml",
Path("dummy/config/dir/var_to_label.yaml"),
id="Summary with label file.",
),
],
)
Expand All @@ -114,10 +121,8 @@ def test_entry_point(
returned_args = entry_point(options, testing=True)
# convert argparse's Namespace object to dictionary
returned_args_dict = vars(returned_args)

# check that the correct function is collected
assert returned_args.func == expected_function

# check that the argument has successfully been passed through into the dictionary
assert returned_args_dict[expected_arg_name] == expected_arg_value

Expand All @@ -133,28 +138,30 @@ def test_entry_point_create_config_file(tmp_path: Path) -> None:
f"{tmp_path}",
]
)

assert Path(f"{tmp_path}/test_create_config.yaml").is_file()


# Test that the right functions are returned with the right arguments
@pytest.mark.parametrize(
("options", "expected_arg_name", "expected_arg_value"),
[
(
pytest.param(
[
"-c dummy/config/dir/config.yaml",
"-c",
"dummy/config/dir/config.yaml",
],
"config_file",
" dummy/config/dir/config.yaml",
Path("dummy/config/dir/config.yaml"),
id="Test using -c flag for config file",
),
(
pytest.param(
[
"--config",
"dummy/config/dir/config.yaml",
],
"config_file",
"dummy/config/dir/config.yaml",
Path("dummy/config/dir/config.yaml"),
id="Test using --config flag for config file",
),
],
)
Expand Down
41 changes: 27 additions & 14 deletions tests/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import logging
from datetime import datetime
from pathlib import Path
from unittest.mock import patch

import h5py
import numpy as np
import pandas as pd
import pySPM
import pytest

from topostats.io import (
Expand Down Expand Up @@ -605,20 +607,31 @@ def test_gwy_read_component(load_scan_dummy: LoadScans) -> None:
assert list(test_dict.values()) == [{"test nested component": 3}]


# FIXME : Get this test working
# @pytest.mark.parametrize(
# "unit, x, y, expected",
# [
# ("um", 100, 100, 97.65625),
# ("nm", 50, 50, 0.048828125),
# ],
# )
# def test_extract_pixel_to_nm_scaling(load_scan: LoadScans, unit, x, y, expected) -> None:
# """Test extraction of pixels to nanometer scaling."""
# load_scan.load_spm()
# load_scan._spm_pixel_to_nm_scaling() {"unit": unit, "x": x, "y": y}
# test_filters_random.extract_pixel_to_nm_scaling()
# assert test_filters_random.pixel_to_nm_scaling == expected
@patch("pySPM.SPM.SPM_image.pxs")
@pytest.mark.parametrize(
("unit", "x", "y", "expected_px2nm"),
[
pytest.param("mm", 0.01, 0.01, 10000, id="mm units; square"),
pytest.param("um", 1.5, 1.5, 1500, id="um units; square"),
pytest.param("nm", 50, 50, 50, id="nm units; square"),
pytest.param("pm", 233, 233, 0.233, id="pm units; square"),
pytest.param("pm", 1, 512, 0.001, id="pm units; rectangular (thin)"),
pytest.param("pm", 512, 1, 0.512, id="pm units; rectangular (tall)"),
],
)
def test__spm_pixel_to_nm_scaling(
mock_pxs,
load_scan_spm: LoadScans,
spm_channel_data: pySPM.SPM.SPM_image,
unit: str,
x: int,
y: int,
expected_px2nm: float,
) -> None:
"""Test extraction of pixels to nanometer scaling."""
mock_pxs.return_value = [(x, unit), (y, unit)] # issue is that pxs is a func that returns the data
result = load_scan_spm._spm_pixel_to_nm_scaling(spm_channel_data)
assert result == expected_px2nm


@pytest.mark.parametrize(
Expand Down
34 changes: 9 additions & 25 deletions tests/test_plottingfuncs.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import pytest
from matplotlib.axes import Axes
from matplotlib.figure import Figure
from skimage import io

from topostats.grains import Grains
from topostats.io import LoadScans
Expand Down Expand Up @@ -108,29 +107,17 @@ def test_save_figure(
assert isinstance(ax, Axes)


def test_save_array_figure(tmp_path: Path):
"""Tests that the image array is saved."""
rng2 = np.random.default_rng()
Images(
data=rng2.random((10, 10)),
output_dir=tmp_path,
filename="result",
).save_array_figure()
assert Path(tmp_path / "result.png").exists()


@pytest.mark.mpl_image_compare(baseline_dir="resources/img/")
def test_plot_and_save_no_colorbar(load_scan_data: LoadScans, tmp_path: Path) -> None:
def test_plot_and_save_no_colorbar(load_scan_data: LoadScans, plotting_config: dict, tmp_path: Path) -> None:
"""Test plotting without colorbar."""
plotting_config["colorbar"] = False
fig, _ = Images(
data=load_scan_data.image,
output_dir=tmp_path,
filename="01-raw_heightmap",
pixel_to_nm_scaling=load_scan_data.pixel_to_nm_scaling,
title="Raw Height",
colorbar=False,
axes=True,
image_set="all",
**plotting_config,
).plot_and_save()
return fig

Expand All @@ -145,17 +132,15 @@ def test_plot_histogram_and_save(load_scan_data: LoadScans, tmp_path: Path) -> N


@pytest.mark.mpl_image_compare(baseline_dir="resources/img/")
def test_plot_and_save_colorbar(load_scan_data: LoadScans, tmp_path: Path) -> None:
"""Test plotting with colorbar."""
def test_plot_and_save_colorbar_and_axes(load_scan_data: LoadScans, plotting_config: dict, tmp_path: Path) -> None:
"""Test plotting with colorbar and axes (True in default_config.yaml)."""
fig, _ = Images(
data=load_scan_data.image,
output_dir=tmp_path,
filename="01-raw_heightmap",
pixel_to_nm_scaling=load_scan_data.pixel_to_nm_scaling,
title="Raw Height",
colorbar=True,
axes=True,
image_set="all",
**plotting_config,
).plot_and_save()
return fig

Expand All @@ -174,20 +159,19 @@ def test_plot_and_save_no_axes(load_scan_data: LoadScans, plotting_config: dict,
return fig


@pytest.mark.mpl_image_compare(baseline_dir="resources/img/")
def test_plot_and_save_no_axes_no_colorbar(load_scan_data: LoadScans, plotting_config: dict, tmp_path: Path) -> None:
"""Test plotting without axes and without the colourbar."""
plotting_config["axes"] = False
plotting_config["colorbar"] = False
Images(
fig, _ = Images(
data=load_scan_data.image,
output_dir=tmp_path,
filename="01-raw_heightmap",
title="Raw Height",
**plotting_config,
).plot_and_save()
img = io.imread(tmp_path / "01-raw_heightmap.png")
assert np.sum(img) == 1535334
assert img.shape == (64, 64, 4)
return fig


@pytest.mark.mpl_image_compare(baseline_dir="resources/img/")
Expand Down
Loading

0 comments on commit 74916b1

Please sign in to comment.