diff --git a/pymaid/tests/conftest.py b/pymaid/tests/conftest.py new file mode 100644 index 0000000..e2efc16 --- /dev/null +++ b/pymaid/tests/conftest.py @@ -0,0 +1,63 @@ +import os +import pytest +import navis +from contextlib import contextmanager +import logging +import pymaid + +logger = logging.getLogger(__name__) + + +@contextmanager +def igraph_context(use_igraph): + orig = navis.config.use_igraph + logger.debug(f"Setting navis.config.use_igraph = {use_igraph}") + navis.config.use_igraph = use_igraph + yield use_igraph + logger.debug(f"Resetting navis.config.use_igraph = {orig}") + navis.config.use_igraph = orig + + +@pytest.fixture(scope="session", params=[True, False]) +def use_igraph(request): + with igraph_context(request.param) as use: + yield use + + +@pytest.fixture(scope="module") +def client(): + return pymaid.CatmaidInstance( + os.environ.get("PYMAID_TEST_SERVER_URL", 'https://fafb.catmaid.virtualflybrain.org/'), + os.environ.get("PYMAID_TEST_TOKEN"), + os.environ.get("PYMAID_TEST_HTTP_USER"), + os.environ.get("PYMAID_TEST_HTTP_PW"), + make_global=True, + ) + + +@pytest.fixture(scope="module") +def skids(): + return [ + int(s) for s in os.environ.get( + "PYMAID_TEST_SKIDS", + "16,1299740,4744251" + ).split(",") + ] + + +@pytest.fixture(scope="module") +def annotation_names(): + return os.environ.get( + "PYMAID_TEST_ANNOTATIONS", + 'Paper: Dolan and Belliart-Guérin et al. 2018,Paper: Wang et al 2020a' + ).split(",") + + +@pytest.fixture(scope="module") +def volume_name(): + return os.environ.get("PYMAID_TEST_VOLUME", "LH_R") + + +@pytest.fixture(scope="module") +def stack_id(): + return int(os.environ.get("PYMAID_TEST_STACK_ID", 1)) diff --git a/pymaid/tests/test_graph.py b/pymaid/tests/test_graph.py new file mode 100644 index 0000000..349cd5d --- /dev/null +++ b/pymaid/tests/test_graph.py @@ -0,0 +1,81 @@ +import pytest +import pymaid +import navis as ns +import numpy as np + +SEED = 1991 + +@pytest.fixture(scope="module") +def neuron_list(client, skids): + return pymaid.get_neuron(skids[0:2], remote_instance=client) + + +@pytest.fixture(scope="module") +def neuron(neuron_list): + n = neuron_list[0] + return n.reroot(n.soma, inplace=False) + +@pytest.fixture(scope="module") +def leaf_slab(neuron): + rng = np.random.default_rng(SEED) + leaf_id = neuron.nodes[neuron.nodes.type == 'end'].sample( + 1, random_state=rng).iloc[0].node_id + slab_id = neuron.nodes[neuron.nodes.type == 'slab'].sample( + 1, random_state=rng).iloc[0].node_id + return (leaf_id, slab_id) + + +def test_reroot(neuron_list, neuron, leaf_slab, use_igraph): + leaf_id, slab_id = leaf_slab + assert neuron.reroot(leaf_id, inplace=False) is not None + assert neuron_list.reroot(neuron_list.soma, inplace=False) is not None + + +def test_distal_to(neuron, leaf_slab, use_igraph): + leaf_id, slab_id = leaf_slab + assert ns.distal_to(neuron, leaf_id, neuron.root) + assert not ns.distal_to(neuron, neuron.root, leaf_id) + + +def test_distance(neuron, use_igraph): + leaf_id = neuron.nodes[neuron.nodes.type == 'end'].iloc[0].node_id + + assert ns.dist_between(neuron, leaf_id, neuron.root) is not None + assert ns.dist_between(neuron, neuron.root, leaf_id) is not None + + +def test_find_bp(neuron, use_igraph): + assert ns.find_main_branchpoint(neuron, reroot_soma=False) is not None + + +def test_split_fragments(neuron, use_igraph): + assert ns.split_into_fragments(neuron, n=2, reroot_soma=False) is not None + + +def test_longest_neurite(neuron, use_igraph): + assert ns.longest_neurite(neuron, n=2, reroot_soma=False) is not None + + +def test_cut_neuron(neuron, leaf_slab, use_igraph): + leaf_id, slab_id = leaf_slab + dist, prox = ns.cut_skeleton(neuron, slab_id) + assert dist.nodes.shape != prox.nodes.shape + + # Make sure dist and prox check out + assert ns.distal_to(neuron, dist.root, prox.root) + + +def test_subset(neuron, use_igraph): + assert isinstance( + ns.subset_neuron(neuron, neuron.segments[0]), + pymaid.CatmaidNeuron + ) + + +def test_node_sorting(neuron, use_igraph): + result = ns.graph.node_label_sorting(neuron) + assert isinstance(result, np.ndarray) + + +def test_geodesic_matrix(neuron, use_igraph): + geo = ns.geodesic_matrix(neuron) diff --git a/pymaid/tests/test_pymaid.py b/pymaid/tests/test_pymaid.py index 15b819d..c655337 100644 --- a/pymaid/tests/test_pymaid.py +++ b/pymaid/tests/test_pymaid.py @@ -35,6 +35,7 @@ import warnings import os import matplotlib as mpl +import pytest #if os.environ.get('DISPLAY', '') == '': # warnings.warn('No display found. Using template backend (nothing ' # 'will show).') @@ -605,104 +606,6 @@ def test_guess_radius(self): pymaid.CatmaidNeuron) -class TestGraphs(unittest.TestCase): - """Test graph functions.""" - - def try_conditions(func): - """Runs each test under various conditions and asserts that results - are always the same.""" - - def wrapper(self, *args, **kwargs): - ns.config.use_igraph = False - res1 = func(self, *args, **kwargs) - if igraph: - ns.config.use_igraph = True - res2 = func(self, *args, **kwargs) - self.assertEqual(res1, res2) - return res1 - return wrapper - - def setUp(self): - self.rm = pymaid.CatmaidInstance(server=config_test.server_url, - http_user=config_test.http_user, - http_password=config_test.http_pw, - api_token=config_test.token, - make_global=True) - - self.nl = pymaid.get_neuron(config_test.test_skids[0:2], - remote_instance=self.rm) - - self.n = self.nl[0] - self.n.reroot(self.n.soma) - - # Get some random leaf node - self.leaf_id = self.n.nodes[self.n.nodes.type == 'end'].sample( - 1).iloc[0].node_id - self.slab_id = self.n.nodes[self.n.nodes.type == 'slab'].sample( - 1).iloc[0].node_id - - @try_conditions - def test_reroot(self): - self.assertIsNotNone(self.n.reroot(self.leaf_id, inplace=False)) - self.assertIsNotNone(self.nl.reroot(self.nl.soma, inplace=False)) - - @try_conditions - def test_distal_to(self): - self.assertTrue(ns.distal_to(self.n, self.leaf_id, self.n.root)) - self.assertFalse(ns.distal_to(self.n, self.n.root, self.leaf_id)) - - @try_conditions - def test_distance(self): - leaf_id = self.n.nodes[self.n.nodes.type == 'end'].iloc[0].node_id - - self.assertIsNotNone(ns.dist_between(self.n, - leaf_id, - self.n.root)) - self.assertIsNotNone(ns.dist_between(self.n, - self.n.root, - leaf_id)) - - @try_conditions - def test_find_bp(self): - self.assertIsNotNone(ns.find_main_branchpoint(self.n, - reroot_soma=False)) - - @try_conditions - def test_split_fragments(self): - self.assertIsNotNone(ns.split_into_fragments(self.n, - n=2, - reroot_soma=False)) - - @try_conditions - def test_longest_neurite(self): - self.assertIsNotNone(ns.longest_neurite(self.n, - n=2, - reroot_soma=False)) - - @try_conditions - def test_cut_neuron(self): - dist, prox = ns.cut_skeleton(self.n, self.slab_id) - self.assertNotEqual(dist.nodes.shape, prox.nodes.shape) - - # Make sure dist and prox check out - self.assertTrue(ns.distal_to(self.n, dist.root, prox.root)) - - @try_conditions - def test_subset(self): - self.assertIsInstance(ns.subset_neuron(self.n, - self.n.segments[0]), - pymaid.CatmaidNeuron) - - @try_conditions - def test_node_sorting(self): - self.assertIsInstance(ns.graph.node_label_sorting(self.n), - list) - - @try_conditions - def test_geodesic_matrix(self): - geo = ns.geodesic_matrix(self.n) - - class TestConnectivity(unittest.TestCase): """Test connectivity-related functions."""