diff --git a/neuroml/nml/gds_imports-template.py b/neuroml/nml/gds_imports-template.py index 403fac3..797beb0 100644 --- a/neuroml/nml/gds_imports-template.py +++ b/neuroml/nml/gds_imports-template.py @@ -1,6 +1,7 @@ import inspect import math import typing +from functools import cached_property, lru_cache from math import pi, sqrt from operator import attrgetter diff --git a/neuroml/nml/generatedssupersuper.py b/neuroml/nml/generatedssupersuper.py index 5fa4e1b..2753ece 100644 --- a/neuroml/nml/generatedssupersuper.py +++ b/neuroml/nml/generatedssupersuper.py @@ -535,6 +535,7 @@ def parentinfo(self, return_format="string"): "GdsCollector_", "GeneratedsSuperSuper", "attrgetter", + "cached_property", ] # do not show parameters here, they are indicated by members below diff --git a/neuroml/nml/helper_methods.py b/neuroml/nml/helper_methods.py index fe30935..f3f3db1 100644 --- a/neuroml/nml/helper_methods.py +++ b/neuroml/nml/helper_methods.py @@ -911,6 +911,7 @@ def __str__(self): source='''\ # Get segment object by its id + @lru_cache(maxsize=1000) def get_segment(self, segment_id: int) -> Segment: """Get segment object by its id @@ -947,6 +948,7 @@ def get_segments_by_substring(self, substring: str) -> typing.Dict[str, Segment] # Get the proximal point of a segment, even the proximal field is None and # so the proximal point is on the parent (at a point set by fraction_along) + @lru_cache(maxsize=1000) def get_actual_proximal(self, segment_id: str): """Get the proximal point of a segment. @@ -976,6 +978,7 @@ def get_actual_proximal(self, segment_id: str): return p + @lru_cache(maxsize=1000) def get_segment_length(self, segment_id: str) -> float: """Get the length of the segment. @@ -993,6 +996,7 @@ def get_segment_length(self, segment_id: str) -> float: return length + @lru_cache(maxsize=1000) def get_segment_surface_area(self, segment_id: str) -> float: """Get the surface area of the segment. @@ -1010,6 +1014,7 @@ def get_segment_surface_area(self, segment_id: str) -> float: return temp_seg.surface_area + @lru_cache(maxsize=1000) def get_segment_volume(self, segment_id: str) -> float: """Get volume of segment @@ -1029,6 +1034,14 @@ def get_segment_volume(self, segment_id: str) -> float: def get_segment_ids_vs_segments(self) -> typing.Dict[str, Segment]: """Get a dictionary of segment IDs and the segments in the cell. + :return: dictionary with segment ID as key, and segment as value + """ + return self.segment_ids_vs_segments + + @cached_property + def segment_ids_vs_segments(self) -> typing.Dict[str, Segment]: + """Get a dictionary of segment IDs and the segments in the cell. + :return: dictionary with segment ID as key, and segment as value """ @@ -1038,6 +1051,7 @@ def get_segment_ids_vs_segments(self) -> typing.Dict[str, Segment]: return segments + @lru_cache(maxsize=1000) def get_all_segments_in_group(self, segment_group: typing.Union[str, SegmentGroup], assume_all_means_all: bool = True) -> typing.List[int]: @@ -1235,6 +1249,7 @@ def get_ordered_segments_in_groups(self, return ord_segs + @lru_cache(maxsize=1000) def get_segment_group(self, sg_id: str) -> SegmentGroup: """Return the SegmentGroup object for the specified segment group id. diff --git a/neuroml/nml/nml.py b/neuroml/nml/nml.py index 49ff93c..29514e3 100644 --- a/neuroml/nml/nml.py +++ b/neuroml/nml/nml.py @@ -2,8 +2,8 @@ # -*- coding: utf-8 -*- # -# Generated Tue Aug 20 10:23:13 2024 by generateDS.py version 2.44.1. -# Python 3.11.9 (main, Apr 17 2024, 00:00:00) [GCC 14.0.1 20240411 (Red Hat 14.0.1-0)] +# Generated Wed Sep 11 16:30:43 2024 by generateDS.py version 2.44.1. +# Python 3.11.9 (main, Aug 23 2024, 00:00:00) [GCC 14.2.1 20240801 (Red Hat 14.2.1-1)] # # Command line options: # ('-o', 'nml.py') @@ -36,6 +36,7 @@ import os import re as re_ import typing +from functools import cached_property, lru_cache from math import pi, sqrt from operator import attrgetter @@ -48429,6 +48430,7 @@ def _buildChildren( super(Cell, self)._buildChildren(child_, node, nodeName_, True) # Get segment object by its id + @lru_cache(maxsize=1000) def get_segment(self, segment_id: int) -> Segment: """Get segment object by its id @@ -48471,6 +48473,7 @@ def get_segments_by_substring(self, substring: str) -> typing.Dict[str, Segment] # Get the proximal point of a segment, even the proximal field is None and # so the proximal point is on the parent (at a point set by fraction_along) + @lru_cache(maxsize=1000) def get_actual_proximal(self, segment_id: str): """Get the proximal point of a segment. @@ -48504,6 +48507,7 @@ def get_actual_proximal(self, segment_id: str): return p + @lru_cache(maxsize=1000) def get_segment_length(self, segment_id: str) -> float: """Get the length of the segment. @@ -48521,6 +48525,7 @@ def get_segment_length(self, segment_id: str) -> float: return length + @lru_cache(maxsize=1000) def get_segment_surface_area(self, segment_id: str) -> float: """Get the surface area of the segment. @@ -48538,6 +48543,7 @@ def get_segment_surface_area(self, segment_id: str) -> float: return temp_seg.surface_area + @lru_cache(maxsize=1000) def get_segment_volume(self, segment_id: str) -> float: """Get volume of segment @@ -48557,6 +48563,14 @@ def get_segment_volume(self, segment_id: str) -> float: def get_segment_ids_vs_segments(self) -> typing.Dict[str, Segment]: """Get a dictionary of segment IDs and the segments in the cell. + :return: dictionary with segment ID as key, and segment as value + """ + return self.segment_ids_vs_segments + + @cached_property + def segment_ids_vs_segments(self) -> typing.Dict[str, Segment]: + """Get a dictionary of segment IDs and the segments in the cell. + :return: dictionary with segment ID as key, and segment as value """ @@ -48566,6 +48580,7 @@ def get_segment_ids_vs_segments(self) -> typing.Dict[str, Segment]: return segments + @lru_cache(maxsize=1000) def get_all_segments_in_group( self, segment_group: typing.Union[str, SegmentGroup], @@ -48773,6 +48788,7 @@ def get_ordered_segments_in_groups( return ord_segs + @lru_cache(maxsize=1000) def get_segment_group(self, sg_id: str) -> SegmentGroup: """Return the SegmentGroup object for the specified segment group id. diff --git a/neuroml/nml/regenerate-nml.sh b/neuroml/nml/regenerate-nml.sh index abda3e2..64d587b 100755 --- a/neuroml/nml/regenerate-nml.sh +++ b/neuroml/nml/regenerate-nml.sh @@ -56,6 +56,7 @@ reformat () { if command -v ruff > /dev/null 2>&1 then echo "Formatting new nml.py with ruff" + ruff check --select I --fix nml.py ruff format nml.py else echo "ruff is not installed" diff --git a/neuroml/test/test_cell.py b/neuroml/test/test_cell.py index 1cbf673..16c883e 100644 --- a/neuroml/test/test_cell.py +++ b/neuroml/test/test_cell.py @@ -392,6 +392,11 @@ def test_get_morphology_root(self): root_seg = acell.get_segment(0) new_id = 99999 root_seg.id = new_id + + # clear the cache, otherwise it'll return the old value again in + # other function calls also + acell.get_segment.cache_clear() + # also update all descendents to ensure cell remains valid for seg in acell.morphology.segments: par = seg.parent