Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions bluecellulab/cell/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,6 @@ def __init__(self,
emodel_properties: Template specific emodel properties.
"""
super().__init__()
self.template_params = TemplateParams(
template_filepath=template_path,
morph_filepath=morphology_path,
template_format=template_format,
emodel_properties=emodel_properties,
)
if cell_id is None:
cell_id = CellId("", Cell.last_id)
Cell.last_id += 1
Expand All @@ -111,6 +105,12 @@ def __init__(self,

# Load the template
neuron_template = NeuronTemplate(template_path, morphology_path, template_format, emodel_properties)
self.template_params = TemplateParams(
template_filepath=template_path,
morph_filepath=neuron_template.morph_filepath,
template_format=template_format,
emodel_properties=emodel_properties,
)
self.template_id = neuron_template.template_name # useful to map NEURON and python objects
self.cell = neuron_template.get_cell(self.cell_id.id)
if template_format == 'v6':
Expand Down
1 change: 0 additions & 1 deletion bluecellulab/cell/morphio_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,6 @@ def __init__(self, input_file, options=0):
if not is_h5_container_path(input_file):
input_file = resolve_case_insensitive_path(input_file)
self._collection_dir, self._morph_name, self._morph_ext = split_morphology_path(input_file)
self._morph_ext = self._morph_ext.lower()
self._options = options
self._build_morph()
# This logic is similar to what's in BaseCell, but at this point we are still
Expand Down
5 changes: 4 additions & 1 deletion bluecellulab/cell/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

import neuron

from bluecellulab.cell.morphio_wrapper import split_morphology_path
from bluecellulab.cell.morphio_wrapper import is_h5_container_path, resolve_case_insensitive_path, split_morphology_path
from bluecellulab.circuit import EmodelProperties
from bluecellulab.exceptions import BluecellulabError
from bluecellulab.type_aliases import HocObjectType
Expand Down Expand Up @@ -110,6 +110,9 @@ def __init__(
if not os.path.exists(template_filepath):
raise FileNotFoundError(f"Couldn't find template file: {template_filepath}")

if not is_h5_container_path(morph_filepath):
morph_filepath = resolve_case_insensitive_path(morph_filepath)

# Check morphology path - handle H5 container paths
if not self._is_valid_morphology_path(morph_filepath):
raise FileNotFoundError(f"Couldn't find morphology file: {morph_filepath}")
Expand Down
61 changes: 36 additions & 25 deletions tests/test_cell/test_morphology_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
SectionName,
split_morphology_path,
)
from bluecellulab.cell.template import NeuronTemplate


class TestMorphologyWrapper:
Expand Down Expand Up @@ -59,42 +60,52 @@ def test_split_morphology_path_container_with_cell_name(self, tmp_path):
assert morph_name == "cell_name"
assert morph_ext == ""

def test_case_insensitive_morphology_path(self, tmp_path):
def test_case_insensitive_morphology_path_linux_like(self, tmp_path):
p = tmp_path / "cell.ASC"
p.write_text("dummy")

with patch.object(MorphIOWrapper, "_build_morph"):
with patch.object(MorphIOWrapper, "_get_section_names", return_value=[]):
with patch.object(MorphIOWrapper, "_build_sec_typeid_distrib"):
wrapper = MorphIOWrapper(str(tmp_path / "cell.asc"))
wrong_case = tmp_path / "cell.asc"
original_exists = Path.exists

def linux_like_exists(path):
if path == wrong_case:
return False
return original_exists(path)

with (
patch.object(Path, "exists", linux_like_exists),
patch.object(MorphIOWrapper, "_build_morph"),
patch.object(MorphIOWrapper, "_get_section_names", return_value=[]),
patch.object(MorphIOWrapper, "_build_sec_typeid_distrib"),
):
wrapper = MorphIOWrapper(str(wrong_case))

assert wrapper._morph_name == "cell"
assert wrapper._morph_ext == ".asc"
assert wrapper._morph_ext == ".ASC"

def test_case_insensitive_morphology_path_reverse(self, tmp_path):
"""Should also work if file is lowercase and input is uppercase."""
p = tmp_path / "cell.asc"
p.write_text("dummy")
def test_neuron_template_resolves_case_insensitive_morphology_path(self, tmp_path):
"""NeuronTemplate should validate wrong-case morphology filenames."""
morph_file = tmp_path / "cell.ASC"
morph_file.write_text("dummy")

with patch.object(MorphIOWrapper, "_build_morph"):
with patch.object(MorphIOWrapper, "_get_section_names", return_value=[]):
with patch.object(MorphIOWrapper, "_build_sec_typeid_distrib"):
wrapper = MorphIOWrapper(str(tmp_path / "cell.ASC"))
template_file = tmp_path / "template.hoc"
template_file.write_text("begintemplate T\nendtemplate T\n")

assert wrapper._morph_name == "cell"
assert wrapper._morph_ext == ".asc"
wrong_case = tmp_path / "cell.asc"
original_exists = Path.exists

def test_extension_normalization(self, tmp_path):
"""Extension should always be normalized to lowercase."""
p = tmp_path / "cell.SWC"
p.write_text("dummy")
def linux_like_exists(path):
if path == wrong_case:
return False
return original_exists(path)

with patch.object(MorphIOWrapper, "_build_morph"):
with patch.object(MorphIOWrapper, "_get_section_names", return_value=[]):
with patch.object(MorphIOWrapper, "_build_sec_typeid_distrib"):
wrapper = MorphIOWrapper(str(p))
with (
patch.object(Path, "exists", linux_like_exists),
patch.object(NeuronTemplate, "load", return_value="T"),
):
template = NeuronTemplate(str(template_file), str(wrong_case), "v5", None)

assert wrapper._morph_ext == ".swc"
assert template.morph_filepath == str(morph_file)

def test_morphology_wrapper_init_success(self):
"""Test successful MorphologyWrapper initialization with real H5 file."""
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ deps =
pandas-stubs>=2.0.0
types-setuptools>=67.8.0.0
ruff>=0.0.270
docformatter>=1.7.2
docformatter>=1.7.2,<1.7.8 # docformatter 1.7.8 has tokenisation regressions; pin until upstream fixes
commands =
ruff check . --select F541,F401 --per-file-ignores="__init__.py:F401"
pycodestyle {[base]name} --ignore=E501,W504,W503
Expand Down