From 21a6276338ddb80a4929e6d80ac09cd4e4c71055 Mon Sep 17 00:00:00 2001 From: "Ankur Sinha (Ankur Sinha Gmail)" Date: Wed, 20 Sep 2023 19:27:01 +0100 Subject: [PATCH 1/4] perf(plotting): use `popitem` for iteration In the plotting, we're only iterating over the items of dicts once and never using them again. So, there is no reason for us to keep the items in memory. Instead, we can pop them after we process them. --- pyneuroml/plot/PlotMorphology.py | 9 +++++++-- pyneuroml/plot/PlotMorphologyVispy.py | 13 +++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/pyneuroml/plot/PlotMorphology.py b/pyneuroml/plot/PlotMorphology.py index bb214946d..c2961a55b 100644 --- a/pyneuroml/plot/PlotMorphology.py +++ b/pyneuroml/plot/PlotMorphology.py @@ -296,6 +296,9 @@ def plot_2D( logger.debug(f"pop_id_vs_color: {pop_id_vs_color}") logger.debug(f"pop_id_vs_radii: {pop_id_vs_radii}") + # not used, clear up + del cell_id_vs_cell + fig, ax = get_new_matplotlib_morph_plot(title, plane2d) axis_min_max = [float("inf"), -1 * float("inf")] @@ -322,7 +325,8 @@ def plot_2D( except KeyError: pass - for pop_id, cell in pop_id_vs_cell.items(): + while pop_id_vs_cell: + pop_id, cell = pop_id_vs_cell.popitem() pos_pop = positions[pop_id] # type: typing.Dict[typing.Any, typing.List[float]] # reinit point_cells for each loop @@ -337,7 +341,8 @@ def plot_2D( except KeyError: pass - for cell_index, pos in pos_pop.items(): + while pos_pop: + cell_index, pos = pos_pop.popitem() radius = pop_id_vs_radii[pop_id] if pop_id in pop_id_vs_radii else 10 color = pop_id_vs_color[pop_id] if pop_id in pop_id_vs_color else None diff --git a/pyneuroml/plot/PlotMorphologyVispy.py b/pyneuroml/plot/PlotMorphologyVispy.py index af5eca998..36b417c8b 100644 --- a/pyneuroml/plot/PlotMorphologyVispy.py +++ b/pyneuroml/plot/PlotMorphologyVispy.py @@ -398,7 +398,10 @@ def plot_interactive_3D( logger.debug(f"pop_id_vs_color: {pop_id_vs_color}") logger.debug(f"pop_id_vs_radii: {pop_id_vs_radii}") - if len(positions.keys()) > 1: + # not used, clear up + del cell_id_vs_cell + + if len(positions) > 1: only_pos = [] for posdict in positions.values(): for poss in posdict.values(): @@ -467,8 +470,9 @@ def plot_interactive_3D( except KeyError: pass - for pop_id, cell in pop_id_vs_cell.items(): - pos_pop = positions[pop_id] # type: typing.Dict[typing.Any, typing.List[float]] + while pop_id_vs_cell: + pop_id, cell = pop_id_vs_cell.popitem() + pos_pop = positions[pop_id] # reinit point_cells for each loop point_cells_pop = [] @@ -482,7 +486,8 @@ def plot_interactive_3D( except KeyError: pass - for cell_index, pos in pos_pop.items(): + while pos_pop: + cell_index, pos = pos_pop.popitem() radius = pop_id_vs_radii[pop_id] if pop_id in pop_id_vs_radii else 10 color = pop_id_vs_color[pop_id] if pop_id in pop_id_vs_color else None From bd42d8ad6c3a2165de2476c14526c7ae3082301b Mon Sep 17 00:00:00 2001 From: "Ankur Sinha (Ankur Sinha Gmail)" Date: Wed, 20 Sep 2023 23:29:16 +0100 Subject: [PATCH 2/4] fix(morph-plots): only load inc files if they're found --- pyneuroml/utils/__init__.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/pyneuroml/utils/__init__.py b/pyneuroml/utils/__init__.py index f266da0c6..717b0c278 100644 --- a/pyneuroml/utils/__init__.py +++ b/pyneuroml/utils/__init__.py @@ -97,11 +97,12 @@ def extract_position_info( # document for inc in nml_model_copy.includes: incl_loc = os.path.abspath(os.path.join(base_path, inc.href)) - inc = read_neuroml2_file(incl_loc) - for acell in inc.cells: - if acell.id in required_cell_types: - acell.biophysical_properties = None - nml_model_copy.add(acell) + if os.path.isfile(incl_loc): + inc = read_neuroml2_file(incl_loc) + for acell in inc.cells: + if acell.id in required_cell_types: + acell.biophysical_properties = None + nml_model_copy.add(acell) cell_elements.extend(nml_model_copy.cells) cell_elements.extend(nml_model_copy.cell2_ca_poolses) @@ -111,10 +112,11 @@ def extract_position_info( # add any included cells to the main document for inc in nml_model_copy.includes: incl_loc = os.path.abspath(os.path.join(base_path, inc.href)) - inc = read_neuroml2_file(incl_loc) - for acell in inc.cells: - acell.biophysical_properties = None - nml_model_copy.add(acell) + if os.path.isfile(incl_loc): + inc = read_neuroml2_file(incl_loc) + for acell in inc.cells: + acell.biophysical_properties = None + nml_model_copy.add(acell) cell_elements.extend(nml_model_copy.cells) cell_elements.extend(nml_model_copy.cell2_ca_poolses) From a222407c17ee46704999bb6754471966f1bf93e9 Mon Sep 17 00:00:00 2001 From: "Ankur Sinha (Ankur Sinha Gmail)" Date: Wed, 20 Sep 2023 23:32:25 +0100 Subject: [PATCH 3/4] fix(morph-plots): correct title generation --- pyneuroml/plot/PlotMorphology.py | 19 ++++++++++++------- pyneuroml/plot/PlotMorphologyVispy.py | 21 +++++++++++++++------ 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/pyneuroml/plot/PlotMorphology.py b/pyneuroml/plot/PlotMorphology.py index c2961a55b..b3066de51 100644 --- a/pyneuroml/plot/PlotMorphology.py +++ b/pyneuroml/plot/PlotMorphology.py @@ -261,13 +261,24 @@ def plot_2D( verbose=False, optimized=True, ) - + if title is None: + try: + title = f"{nml_model.networks[0].id} from {nml_file}" + except IndexError: + title = f"{nml_model.cells[0].id} from {nml_file}" elif isinstance(nml_file, Cell): nml_model = NeuroMLDocument(id="newdoc") nml_model.add(nml_file) + if title is None: + title = f"{nml_model.cells[0].id}" elif isinstance(nml_file, NeuroMLDocument): nml_model = nml_file + if title is None: + try: + title = f"{nml_model.networks[0].id} from {nml_file.id}" + except IndexError: + title = f"{nml_model.cells[0].id} from {nml_file.id}" else: raise TypeError( "Passed model is not a NeuroML file path, nor a neuroml.Cell, nor a neuroml.NeuroMLDocument" @@ -283,12 +294,6 @@ def plot_2D( nml_model, verbose, nml_file if type(nml_file) is str else "" ) - if title is None: - if len(nml_model.networks) > 0: - title = "2D plot of %s from %s" % (nml_model.networks[0].id, nml_file) - else: - title = "2D plot of %s" % (nml_model.cells[0].id) - if verbose: logger.debug(f"positions: {positions}") logger.debug(f"pop_id_vs_cell: {pop_id_vs_cell}") diff --git a/pyneuroml/plot/PlotMorphologyVispy.py b/pyneuroml/plot/PlotMorphologyVispy.py index 36b417c8b..e728ac057 100644 --- a/pyneuroml/plot/PlotMorphologyVispy.py +++ b/pyneuroml/plot/PlotMorphologyVispy.py @@ -357,11 +357,25 @@ def plot_interactive_3D( verbose=False, optimized=True, ) + if title is None: + try: + title = f"{nml_model.networks[0].id} from {nml_file}" + except IndexError: + title = f"{nml_model.cells[0].id} from {nml_file}" + elif isinstance(nml_file, Cell): nml_model = NeuroMLDocument(id="newdoc") nml_model.add(nml_file) + if title is None: + title = f"{nml_model.cells[0].id}" + elif isinstance(nml_file, NeuroMLDocument): nml_model = nml_file + if title is None: + try: + title = f"{nml_model.networks[0].id} from {nml_file.id}" + except IndexError: + title = f"{nml_model.cells[0].id} from {nml_file.id}" else: raise TypeError( "Passed model is not a NeuroML file path, nor a neuroml.Cell, nor a neuroml.NeuroMLDocument" @@ -386,12 +400,6 @@ def plot_interactive_3D( marker_points = [] marker_colors = [] - if title is None: - try: - title = f"{nml_model.networks[0].id} from {nml_file}" - except IndexError: - title = f"{nml_model.cells[0].id} from {nml_file}" - logger.debug(f"positions: {positions}") logger.debug(f"pop_id_vs_cell: {pop_id_vs_cell}") logger.debug(f"cell_id_vs_cell: {cell_id_vs_cell}") @@ -535,6 +543,7 @@ def plot_interactive_3D( or plot_type == "constant" or cell.id in constant_cells ): + logger.debug(f"Cell for 3d is: {cell.id}") pts, sizes, colors = plot_3D_cell_morphology( offset=pos, cell=cell, From c07f44618b98596dca8d834962e776082ee7efbc Mon Sep 17 00:00:00 2001 From: "Ankur Sinha (Ankur Sinha Gmail)" Date: Wed, 20 Sep 2023 23:48:06 +0100 Subject: [PATCH 4/4] chore(plots): print number of cells being plotted --- pyneuroml/plot/PlotMorphologyVispy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyneuroml/plot/PlotMorphologyVispy.py b/pyneuroml/plot/PlotMorphologyVispy.py index e728ac057..f6a0d73b9 100644 --- a/pyneuroml/plot/PlotMorphologyVispy.py +++ b/pyneuroml/plot/PlotMorphologyVispy.py @@ -407,6 +407,7 @@ def plot_interactive_3D( logger.debug(f"pop_id_vs_radii: {pop_id_vs_radii}") # not used, clear up + print(f"Plotting {len(cell_id_vs_cell)} cells") del cell_id_vs_cell if len(positions) > 1: