Skip to content

Commit

Permalink
Prepare for Python 3.13, fix issues with numpy>2 & matplotlib, (#1131)
Browse files Browse the repository at this point in the history
  • Loading branch information
eleftherioszisis authored Sep 27, 2024
1 parent 6705714 commit f1304bb
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 19 deletions.
2 changes: 1 addition & 1 deletion pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#R0903 - Too Few public methods
#W0511 - TODO in code
#R0401 - cyclic-import
disable=C0103,R0903,W0511,R0401,unspecified-encoding,consider-using-f-string
disable=C0103,R0903,W0511,R0401,unspecified-encoding,consider-using-f-string, too-many-positional-arguments

[FORMAT]
# Maximum number of characters on a single line.
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Scientific/Engineering :: Bio-Informatics",
]
dependencies = [
Expand Down
10 changes: 5 additions & 5 deletions tests/apps/test_morph_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,9 @@ def test_extract_stats_scalar_feature():
# 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},
}

assert res["all"] == {'max_number_of_forking_points': 277}
assert_almost_equal(res["morphology"]["sum_soma_volume"], 1424.4383771584492, decimal=4)


def test_extract_stats__kwarg_modes_multiple_features():
Expand Down Expand Up @@ -493,7 +492,8 @@ def test_extract_dataframe_multiproc():
actual = ms.extract_dataframe(morphs, REF_CONFIG, n_workers=os.cpu_count() + 1)
# drop raw features as they require too much test data to mock
actual = actual.drop(columns='raw_section_branch_orders', level=1)
assert len(w) == 1, "Warning not emitted"
assert len(w) >= 1, "Warning not emitted"

assert_frame_equal(actual, expected, check_dtype=False)

with warnings.catch_warnings(record=True) as w:
Expand Down
4 changes: 2 additions & 2 deletions tests/core/test_section.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ def test_section_base_func():
assert section.id == 0
assert_array_equal(section.points, [[0, 0, 0, 1], [0, 5, 0, 1]])
assert_almost_equal(section.length, 5)
assert_almost_equal(section.area, 31.41592653589793)
assert_almost_equal(section.volume, 15.707963267948964)
assert_almost_equal(section.area, 31.4159, decimal=4)
assert_almost_equal(section.volume, 15.7079, decimal=4)

# __nonzero__
assert section
Expand Down
2 changes: 1 addition & 1 deletion tests/core/test_soma.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def test_Soma_ThreePointCylinder():
assert 'SomaNeuromorphoThreePointCylinders' in str(sm)
assert isinstance(sm, soma.SomaNeuromorphoThreePointCylinders)
assert list(sm.center) == [0, 0, 0]
assert sm.radius == 44
assert_almost_equal(sm.radius, 44.0, decimal=5)


def test_Soma_ThreePointCylinder_invalid_radius():
Expand Down
18 changes: 16 additions & 2 deletions tests/features/test_get_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ def test_max_radial_distance():

def test_section_tortuosity():
assert_allclose(
_stats(features.get('section_tortuosity', POP)), (1.0, 4.657, 440.408, 1.342), rtol=1e-3
_stats(features.get('section_tortuosity', POP)),
(1.0, 4.657, 440.408, 1.342),
rtol=1e-3,
)
assert_allclose(
_stats(features.get('section_tortuosity', POP, neurite_type=NeuriteType.all)),
Expand Down Expand Up @@ -326,6 +328,7 @@ def test_total_length():
assert_allclose(
features.get('total_length', POP, neurite_type=NeuriteType.axon),
[207.8797736031714, 207.81088341560977, 11767.156115224638],
rtol=1e-6,
)
assert_allclose(
features.get('total_length', POP, neurite_type=NeuriteType.apical_dendrite),
Expand Down Expand Up @@ -518,12 +521,14 @@ def test_neurite_volumes():
assert_allclose(
_stats(features.get('total_volume_per_neurite', POP, neurite_type=NeuriteType.axon)),
(276.58135508666612, 277.5357232437392, 830.85568094763551, 276.95189364921185),
rtol=1e-3,
)
assert_allclose(
_stats(
features.get('total_volume_per_neurite', POP, neurite_type=NeuriteType.apical_dendrite)
),
(271.94122143951864, 271.94122143951864, 271.94122143951864, 271.94122143951864),
rtol=1e-3,
)
assert_allclose(
_stats(
Expand Down Expand Up @@ -567,52 +572,61 @@ def test_neurite_density():
assert_allclose(
_stats(features.get('neurite_volume_density', POP)),
(6.1847539631150784e-06, 0.52464681266899216, 1.9767794901940539, 0.19767794901940539),
rtol=1e-6,
)
assert_allclose(
_stats(features.get('neurite_volume_density', POP, neurite_type=NeuriteType.all)),
(6.1847539631150784e-06, 0.52464681266899216, 1.9767794901940539, 0.19767794901940539),
rtol=1e-6,
)
assert_allclose(
_stats(features.get('neurite_volume_density', POP, neurite_type=NeuriteType.axon)),
(6.1847539631150784e-06, 0.26465213325053372, 0.5275513670655404, 0.1758504556885134),
1e-6,
rtol=1e-6,
)
assert_allclose(
_stats(
features.get('neurite_volume_density', POP, neurite_type=NeuriteType.apical_dendrite)
),
(0.43756606998299519, 0.43756606998299519, 0.43756606998299519, 0.43756606998299519),
rtol=1e-6,
)
assert_allclose(
_stats(
features.get('neurite_volume_density', POP, neurite_type=NeuriteType.basal_dendrite)
),
(0.00034968816544949771, 0.52464681266899216, 1.0116620531455183, 0.16861034219091972),
rtol=1e-6,
)

assert_allclose(
_stats(features.get('neurite_volume_density', NRN)),
(0.24068543213643726, 0.52464681266899216, 1.4657913638494682, 0.36644784096236704),
rtol=1e-6,
)
assert_allclose(
_stats(features.get('neurite_volume_density', NRN, neurite_type=NeuriteType.all)),
(0.24068543213643726, 0.52464681266899216, 1.4657913638494682, 0.36644784096236704),
rtol=1e-6,
)
assert_allclose(
_stats(features.get('neurite_volume_density', NRN, neurite_type=NeuriteType.axon)),
(0.26289304906104355, 0.26289304906104355, 0.26289304906104355, 0.26289304906104355),
rtol=1e-6,
)
assert_allclose(
_stats(
features.get('neurite_volume_density', NRN, neurite_type=NeuriteType.apical_dendrite)
),
(0.43756606998299519, 0.43756606998299519, 0.43756606998299519, 0.43756606998299519),
rtol=1e-6,
)
assert_allclose(
_stats(
features.get('neurite_volume_density', NRN, neurite_type=NeuriteType.basal_dendrite)
),
(0.24068543213643726, 0.52464681266899216, 0.76533224480542938, 0.38266612240271469),
rtol=1e-6,
)


Expand Down
9 changes: 5 additions & 4 deletions tests/features/test_morphology.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ def test_soma_volume():


def test_soma_surface_area():
assert_allclose(morphology.soma_surface_area(SIMPLE), 12.566370614359172)
assert_allclose(morphology.soma_surface_area(NRN), 0.1075095256160432)
assert_allclose(morphology.soma_surface_area(SIMPLE), 12.566370614359172, rtol=1e-6)
assert_allclose(morphology.soma_surface_area(NRN), 0.1075095256160432, rtol=1e-6)


def test_soma_radius():
Expand All @@ -105,11 +105,11 @@ def surface(r0, r1, h):

basal_area = surface(1, 1, 5) + surface(1, 0, 5) + surface(1, 0, 6)
ret = morphology.total_area_per_neurite(SIMPLE, neurite_type=BASAL_DENDRITE)
assert_almost_equal(ret[0], basal_area)
assert_almost_equal(ret[0], basal_area, decimal=5)

axon_area = surface(1, 1, 4) + surface(1, 0, 5) + surface(1, 0, 6)
ret = morphology.total_area_per_neurite(SIMPLE, neurite_type=AXON)
assert_almost_equal(ret[0], axon_area)
assert_almost_equal(ret[0], axon_area, decimal=5)

ret = morphology.total_area_per_neurite(SIMPLE)
assert np.allclose(ret, [basal_area, axon_area])
Expand Down Expand Up @@ -143,6 +143,7 @@ def test_total_volume_per_neurite():
assert_allclose(
total_volumes,
[271.94122143951864, 281.24754646913954, 274.98039928781355, 276.73860261723024],
rtol=1e-6,
)


Expand Down
4 changes: 2 additions & 2 deletions tests/features/test_neurite.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def test_neurite_volume_density():
0.24068543213643726,
0.26289304906104355,
]
assert_allclose(vol_density, ref_density)
assert_allclose(vol_density, ref_density, rtol=1e-6)


def test_neurite_volume_density_failed_convex_hull():
Expand Down Expand Up @@ -215,7 +215,7 @@ def test_segment_areas():
def test_segment_volumes():
expected = [[15.70796327, 5.23598776, 6.28318531], [12.56637061, 6.28318531, 5.23598776]]
result = [neurite.segment_volumes(s) for s in SIMPLE.neurites]
assert_allclose(result, expected)
assert_allclose(result, expected, rtol=1e-6)


def test_segment_midpoints():
Expand Down
11 changes: 10 additions & 1 deletion tests/view/test_matplotlib_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@
import warnings
from io import StringIO
from pathlib import Path
from packaging.version import parse

import numpy as np
import matplotlib
from neurom import load_morphology
from neurom.core.types import NeuriteType
from neurom.view import matplotlib_utils, matplotlib_impl
Expand Down Expand Up @@ -112,7 +114,14 @@ def test_tree3d(get_fig_3d):
xy_bounds = ax.xy_dataLim.bounds
np.testing.assert_allclose(xy_bounds, (-5.0, 0.0, 11.0, 5.0))
zz_bounds = ax.zz_dataLim.bounds
np.testing.assert_allclose(zz_bounds, (0.0, 0.0, 1.0, 1.0))

# auto scaling of data limits was fixed for LineCollection3D
# in 3.9.1+ fixing the previously wrong bbox limits
# See: https://github.com/matplotlib/matplotlib/pull/28403
if parse(matplotlib.__version__) < parse("3.9.1"):
np.testing.assert_allclose(zz_bounds, (0.0, 0.0, 1.0, 1.0))
else:
np.testing.assert_allclose(zz_bounds, (0.0, 0.0, 0.0, 1.0))


def test_morph3d(get_fig_3d):
Expand Down
3 changes: 2 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ envlist =
coverage
tutorial
check-packaging
py{38,39,310,311,312}
py{38,39,310,311,312,313}

[testenv]
deps =
Expand Down Expand Up @@ -102,3 +102,4 @@ python =
3.10: py310, tutorial
3.11: py311, check-packaging
3.12: py312
3.13: py313

0 comments on commit f1304bb

Please sign in to comment.