Skip to content

Commit

Permalink
NeuroMorpho: Can use neuron names as file names (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
adrien-berchet authored Mar 15, 2023
1 parent 16a65dd commit 93c7d8a
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 15 deletions.
4 changes: 2 additions & 2 deletions morphapi/api/mouselight.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@


"""
Collections of functions to query http://ml-neuronbrowser.janelia.org/ and get data about either the status of the API,
Collections of functions to query https://ml-neuronbrowser.janelia.org/ and get data about either the status of the API,
the brain regions or the neurons available.
Queries are sent by sending POST requests to http://ml-neuronbrowser.janelia.org/graphql
Queries are sent by sending POST requests to https://ml-neuronbrowser.janelia.org/graphql
with a string query.
"""

Expand Down
22 changes: 18 additions & 4 deletions morphapi/api/neuromorphorg.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,25 @@ def build_filepath(self, neuron_id):
return os.path.join(self.neuromorphorg_cache, f"{neuron_id}.swc")

def download_neurons(
self, neurons, _name=None, load_neurons=True, **kwargs
self,
neurons,
_name=None,
load_neurons=True,
use_neuron_names=False,
**kwargs,
):
"""
Downloads neuronal morphological data and saves it to .swc files.
It then returns a list of Neuron instances with morphological data for each neuron.
:param neurons: list of neurons metadata (as returned by one of the functions
used to fetch metadata)
used to fetch metadata)
:param _name: used internally to save cached neurons with a different prefix when the
class is used to download neurons for other APIs
class is used to download neurons for other APIs
:param load_neurons: if set to True, the neurons are loaded into a
`morphapi.morphology.morphology.Neuron` object and returned
:param use_neuron_names: if set to True, the filenames use the names of the neurons instead
of their IDs
"""
if not isinstance(neurons, (list, tuple)):
neurons = [neurons]
Expand All @@ -154,7 +163,12 @@ class is used to download neurons for other APIs
except KeyError:
pass

filepath = self.build_filepath(neuron["neuron_id"])
if use_neuron_names:
filepath = self.build_filepath(
neuron.get("neuron_name", neuron["neuron_id"])
)
else:
filepath = self.build_filepath(neuron["neuron_id"])
load_current_neuron = load_neurons

if not os.path.isfile(filepath):
Expand Down
2 changes: 1 addition & 1 deletion morphapi/paths_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def __init__(self, base_dir=None, **kwargs):
if base_dir is None:
self.base_dir = Path.home() / ".morphapi"
else:
self.base_dir = base_dir
self.base_dir = Path(base_dir)

self.base_dir.mkdir(exist_ok=True)

Expand Down
39 changes: 31 additions & 8 deletions tests/test_download.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from pathlib import Path

from morphapi.api.allenmorphology import AllenMorphology
from morphapi.api.mouselight import MouseLightAPI
from morphapi.api.neuromorphorg import NeuroMorpOrgAPI


def test_neuromorpho_download():
api = NeuroMorpOrgAPI()
def test_neuromorpho_download(tmpdir):
api = NeuroMorpOrgAPI(base_dir=tmpdir)
cache_path = Path(api.neuromorphorg_cache)

metadata, _ = api.get_neurons_metadata(
size=2, # Can get the metadata for up to 500 neurons at the time
species="mouse",
Expand All @@ -15,15 +19,34 @@ def test_neuromorpho_download():
if len(metadata) != 2:
raise ValueError("Incorrect metadata length")

assert len(list(cache_path.iterdir())) == 0
neurons = api.download_neurons(metadata)

if len(neurons) != len(metadata):
raise ValueError
assert len(neurons) == len(metadata)
assert len(list(cache_path.iterdir())) == 2

neurons = [neuron.create_mesh()[1] for neuron in neurons]

# Test no load
assert api.download_neurons(metadata, load_neurons=False)[0].points is None
assert len(list(cache_path.iterdir())) == 2

# Test using neuron names
assert (
api.download_neurons(
metadata, load_neurons=False, use_neuron_names=True
)[0].points
is None
)
assert len(list(cache_path.iterdir())) == 4

cache_files = list(cache_path.iterdir())
assert sorted([i.name for i in cache_files]) == [
"10075.swc",
"10076.swc",
"C1q-Cell7-40x.swc",
"Ctrl-Cell3-40x.swc",
]

# Test failure
metadata[0]["neuron_id"] = "BAD ID"
Expand All @@ -34,8 +57,8 @@ def test_neuromorpho_download():
assert neurons[0].points is None


def test_mouselight_download():
mlapi = MouseLightAPI()
def test_mouselight_download(tmpdir):
mlapi = MouseLightAPI(base_dir=tmpdir)

neurons_metadata = mlapi.fetch_neurons_metadata(
filterby="soma", filter_regions=["MOs"]
Expand Down Expand Up @@ -87,8 +110,8 @@ def test_mouselight_download():
assert filtered_neurons_metadata == filtered_neurons_metadata_atlas


def test_allen_morphology_download():
am = AllenMorphology()
def test_allen_morphology_download(tmpdir):
am = AllenMorphology(base_dir=tmpdir)

# Select some mouse neurons in the primary visual cortex
neurons_df = am.neurons.loc[
Expand Down

0 comments on commit 93c7d8a

Please sign in to comment.