From 3347693ef2a54c6029d75453ba117b6e965b6243 Mon Sep 17 00:00:00 2001 From: Eleftherios Zisis Date: Thu, 25 Jan 2024 15:06:30 +0100 Subject: [PATCH] Fix warnings in tests (#1093) * Replace np.alltrue with np.all * Remove return statements from test * Use set_layout_engine instead of set_tight_layout * Silence precision warnings in comparison test with mock data * Use importlib instead of pkg_resources * Silence expected warnings in tests * Filter cli soma volume warning --- neurom/apps/__init__.py | 12 +++++++++++- neurom/apps/cli.py | 6 +++--- neurom/apps/morph_check.py | 8 ++------ neurom/apps/morph_stats.py | 12 +++++------- neurom/view/matplotlib_utils.py | 2 +- pyproject.toml | 1 + tests/apps/test_cli.py | 2 ++ tests/apps/test_morph_stats.py | 8 +++++++- tests/geom/test_geom.py | 4 ++-- tests/test_import.py | 6 +----- tests/test_stats.py | 5 ++++- tests/test_viewer.py | 10 +++++++++- 12 files changed, 48 insertions(+), 28 deletions(-) diff --git a/neurom/apps/__init__.py b/neurom/apps/__init__.py index 1633ad858..8eb261172 100644 --- a/neurom/apps/__init__.py +++ b/neurom/apps/__init__.py @@ -27,11 +27,21 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """Helper code for neurom applications.""" +import sys import logging - +from pathlib import Path import yaml + from neurom.exceptions import ConfigError +if sys.version_info >= (3, 9): # pragma: no cover + import importlib.resources as importlib_resources +else: + import importlib_resources # pragma: no cover + +EXAMPLE_CHECK_CONFIG = Path(importlib_resources.files("neurom.apps"), "config", "morph_check.yaml") +EXAMPLE_STATS_CONFIG = Path(importlib_resources.files("neurom.apps"), "config", "morph_stats.yaml") + L = logging.getLogger(__name__) diff --git a/neurom/apps/cli.py b/neurom/apps/cli.py index 34d7012d5..69383e3fd 100644 --- a/neurom/apps/cli.py +++ b/neurom/apps/cli.py @@ -33,7 +33,7 @@ import click import matplotlib.pyplot as plt -from neurom.apps import morph_stats, morph_check +from neurom.apps import morph_stats, morph_check, EXAMPLE_CHECK_CONFIG, EXAMPLE_STATS_CONFIG from neurom import load_morphology from neurom.view import matplotlib_impl, matplotlib_utils @@ -85,7 +85,7 @@ def view(input_file, is_3d, plane, backend, realistic_diameters): 'https://neurom.readthedocs.io/en/latest/morph_stats.html') @click.argument('datapath', required=False) @click.option('-C', '--config', type=click.Path(exists=True, dir_okay=False), - default=morph_stats.EXAMPLE_CONFIG, show_default=True, + default=EXAMPLE_STATS_CONFIG, show_default=True, help='Configuration File') @click.option('-o', '--output', type=click.Path(exists=False, dir_okay=False), help='Path to output file, if it ends in .json, a json file is created,' @@ -106,7 +106,7 @@ def stats(datapath, config, output, full_config, as_population, ignored_exceptio 'https://neurom.readthedocs.io/en/latest/morph_check.html') @click.argument('datapath') @click.option('-C', '--config', type=click.Path(exists=True, dir_okay=False), - default=morph_check.EXAMPLE_CONFIG, show_default=True, + default=EXAMPLE_CHECK_CONFIG, show_default=True, help='Configuration File') @click.option('-o', '--output', type=click.Path(exists=False, dir_okay=False), help='Path to output json summary file', required=True) diff --git a/neurom/apps/morph_check.py b/neurom/apps/morph_check.py index 8797e80cb..9dd3e90cf 100644 --- a/neurom/apps/morph_check.py +++ b/neurom/apps/morph_check.py @@ -29,13 +29,9 @@ """Check on morphologies.""" import json -from pathlib import Path -import pkg_resources -from neurom.apps import get_config +from neurom.apps import get_config, EXAMPLE_CHECK_CONFIG from neurom.check.runner import CheckRunner -EXAMPLE_CONFIG = Path(pkg_resources.resource_filename('neurom.apps', 'config'), 'morph_check.yaml') - def main(datapath, config, output): """Main function that checks morphologies. @@ -45,7 +41,7 @@ def main(datapath, config, output): config (str|Path): path to a statistics config file output (str|Path): path to output the resulted checks file """ - config = get_config(config, EXAMPLE_CONFIG) + config = get_config(config, EXAMPLE_CHECK_CONFIG) checker = CheckRunner(config) summary = checker.run(datapath) with open(output, 'w') as json_output: diff --git a/neurom/apps/morph_stats.py b/neurom/apps/morph_stats.py index 8b67d257c..f91e95d5d 100644 --- a/neurom/apps/morph_stats.py +++ b/neurom/apps/morph_stats.py @@ -38,14 +38,13 @@ from collections.abc import Sized from copy import deepcopy from functools import partial -from pathlib import Path -import pkg_resources + import numpy as np import pandas as pd from morphio import SomaError import neurom as nm -from neurom.apps import get_config +from neurom.apps import get_config, EXAMPLE_STATS_CONFIG from neurom.core.morphology import Morphology, Neurite from neurom.core.population import Population from neurom.exceptions import ConfigError @@ -56,7 +55,6 @@ L = logging.getLogger(__name__) -EXAMPLE_CONFIG = Path(pkg_resources.resource_filename('neurom.apps', 'config'), 'morph_stats.yaml') IGNORABLE_EXCEPTIONS = {'SomaError': SomaError} @@ -117,7 +115,7 @@ def extract_dataframe(morphs, config, n_workers=1): return pd.DataFrame(columns=pd.MultiIndex.from_tuples(columns), data=rows) -extract_dataframe.__doc__ += str(EXAMPLE_CONFIG) +extract_dataframe.__doc__ += str(EXAMPLE_STATS_CONFIG) def _get_feature_stats(feature_name, morphs, modes, kwargs): @@ -234,7 +232,7 @@ def extract_stats(morphs, config): return dict(stats) -extract_stats.__doc__ += str(EXAMPLE_CONFIG) +extract_stats.__doc__ += str(EXAMPLE_STATS_CONFIG) def _get_header(results): @@ -366,7 +364,7 @@ def main(datapath, config, output_file, is_full_config, as_population, ignored_e as_population (bool): treat ``datapath`` as directory of morphologies population ignored_exceptions (list|tuple|None): exceptions to ignore when loading a morphology """ - config = full_config() if is_full_config else get_config(config, EXAMPLE_CONFIG) + config = full_config() if is_full_config else get_config(config, EXAMPLE_STATS_CONFIG) if 'neurite' in config and 'neurite_type' not in config: error = ConfigError('"neurite_type" missing from config, but "neurite" set') diff --git a/neurom/view/matplotlib_utils.py b/neurom/view/matplotlib_utils.py index 9d1314b12..77d2eb559 100644 --- a/neurom/view/matplotlib_utils.py +++ b/neurom/view/matplotlib_utils.py @@ -220,7 +220,7 @@ def plot_style(fig, ax, # pylint: disable=too-many-arguments, too-many-locals ax.set_aspect(aspect_ratio) if tight: - fig.set_tight_layout(True) + fig.set_layout_engine("tight") def plot_title(ax, pretitle='', title='Figure', posttitle='', title_fontsize=14, title_arg=None): diff --git a/pyproject.toml b/pyproject.toml index 57037bc82..1f25bf59a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,6 +35,7 @@ dependencies = [ 'pyyaml>=3.10', 'scipy>=1.2.0', 'tqdm>=4.8.4', + 'importlib_resources>=1.3; python_version < "3.9"', ] dynamic = ["version"] diff --git a/tests/apps/test_cli.py b/tests/apps/test_cli.py index dbf616fe7..2c6311065 100644 --- a/tests/apps/test_cli.py +++ b/tests/apps/test_cli.py @@ -1,6 +1,7 @@ import json from pathlib import Path import tempfile +import pytest import pandas as pd import yaml @@ -73,6 +74,7 @@ def test_morph_stat(): 'all:max_section_branch_orders', 'morphology:mean_soma_radius'} +@pytest.mark.filterwarnings('ignore::UserWarning') def test_morph_stat_full_config(): runner = CliRunner() filename = DATA / 'h5/v1/Neuron.h5' diff --git a/tests/apps/test_morph_stats.py b/tests/apps/test_morph_stats.py index 5dd3e32f8..acaeaf8ac 100644 --- a/tests/apps/test_morph_stats.py +++ b/tests/apps/test_morph_stats.py @@ -186,7 +186,9 @@ def test_stats_new_format_set_arg(): def test_extract_stats_scalar_feature(): + m = nm.load_morphology(DATA_PATH / 'neurolucida' / 'bio_neuron-000.asc') + config = { 'neurite_type': ['ALL'], 'neurite': { @@ -196,7 +198,11 @@ def test_extract_stats_scalar_feature(): 'soma_volume': ['sum'], } } - res = ms.extract_stats(m, config) + with warnings.catch_warnings(): + # silence warning about approximating soma volume with a sphere + warnings.simplefilter("ignore", category=UserWarning) + res = ms.extract_stats(m, config) + assert res == {'all': {'max_number_of_forking_points': 277}, 'morphology': {'sum_soma_volume': 1424.4383771584492}} diff --git a/tests/geom/test_geom.py b/tests/geom/test_geom.py index e1ef70bba..7141fd892 100644 --- a/tests/geom/test_geom.py +++ b/tests/geom/test_geom.py @@ -52,7 +52,7 @@ def test_bounding_box(): obj = PointObj() obj.points = pts - assert np.alltrue(geom.bounding_box(obj) == [[-100, -2, -3], [42, 55, 33]]) + assert np.all(geom.bounding_box(obj) == [[-100, -2, -3], [42, 55, 33]]) def test_bounding_box_morphology(): @@ -78,7 +78,7 @@ def test_convex_hull_points(): # This leverages scipy ConvexHull and we don't want # to re-test scipy, so simply check that the points are the same. hull = geom.convex_hull(NRN) - assert np.alltrue(hull.points == NRN.points[:, :3]) + assert np.all(hull.points == NRN.points[:, :3]) def test_convex_hull_volume(): diff --git a/tests/test_import.py b/tests/test_import.py index a7415383f..1629a69a2 100644 --- a/tests/test_import.py +++ b/tests/test_import.py @@ -27,8 +27,4 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. def test_import_neurom(): - try: - import neurom - return True - except Exception: - return False + import neurom diff --git a/tests/test_stats.py b/tests/test_stats.py index 0e1200b30..3daf27e44 100644 --- a/tests/test_stats.py +++ b/tests/test_stats.py @@ -31,7 +31,6 @@ Since the stats module consists of simple wrappers to scipy.stats functions, these tests are only sanity checks. """ - import numpy as np from neurom import stats as st @@ -201,11 +200,15 @@ def test_compare_two_wilcoxon(): assert_almost_equal(results2.dist, 0.0, decimal=5) assert_almost_equal(results2.pvalue, 0.0, decimal=5) + +@pytest.mark.filterwarnings("ignore") # Ignore precision warnings def test_compare_two_ttest(): results1 = st.compare_two(distr1, distr1, test=st.StatTests.ttest) + assert np.isnan(results1.dist) assert np.isnan(results1.pvalue) + results2 = st.compare_two(distr1, distr2, test=st.StatTests.ttest) assert np.isinf(results2.dist) assert_almost_equal(results2.pvalue, 0.0, decimal=5) diff --git a/tests/test_viewer.py b/tests/test_viewer.py index 2f843ddbd..13ad6058d 100644 --- a/tests/test_viewer.py +++ b/tests/test_viewer.py @@ -27,6 +27,7 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os +import warnings import tempfile from pathlib import Path @@ -35,7 +36,14 @@ if 'DISPLAY' not in os.environ: # noqa matplotlib.use('Agg') # noqa -from neurom import NeuriteType, load_morphology, viewer +from neurom.exceptions import NeuroMDeprecationWarning + +with warnings.catch_warnings(): + # no need to warn about the deprecated module in this test + warnings.simplefilter("ignore", category=NeuroMDeprecationWarning) + from neurom import viewer + +from neurom import NeuriteType, load_morphology from neurom.view import matplotlib_utils import pytest