Source code for bluecellulab.cell.plotting

# Copyright 2023-2024 Blue Brain Project / EPFL

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Plotting functions for the cell module."""

from __future__ import annotations

import neuron

import bluecellulab


[docs] class PlottableMixin: """Mixin responsible of plotting functions of a cell.""" def __init__(self) -> None: """Store the persistent objects.""" self.cell_dendrograms: list[bluecellulab.Dendrogram] = [] self.plot_windows: list[bluecellulab.PlotWindow] = [] self.fih_plots = None self.fih_weights = None # As long as no PlotWindow or active Dendrogram exist, don't update self.plot_callback_necessary = False
[docs] def delete_plottable(self) -> None: """NEURON state to be cleaned upon object destruction.""" self.fih_plots = None self.fih_weights = None
[docs] def add_plot_window(self, var_list, xlim=None, ylim=None, title=""): """Add a window to plot a variable.""" xlim = [0, 1000] if xlim is None else xlim ylim = [-100, 100] if ylim is None else ylim for var_name in var_list: if var_name not in self.recordings: self.add_recording(var_name) self.plot_windows.append(bluecellulab.PlotWindow( var_list, self, xlim, ylim, title)) self.plot_callback_necessary = True
[docs] def add_dendrogram( self, variable=None, active=False, save_fig_path=None, interactive=False, scale_bar=True, scale_bar_size=10.0, fig_title=None): """Show a dendrogram of the cell.""" self._init_psections() cell_dendrogram = bluecellulab.Dendrogram( self.psections, variable=variable, active=active, save_fig_path=save_fig_path, interactive=interactive, scale_bar=scale_bar, scale_bar_size=scale_bar_size, fig_title=fig_title) cell_dendrogram.redraw() self.cell_dendrograms.append(cell_dendrogram) if active: self.plot_callback_necessary = True
[docs] def init_callbacks(self): """Initialize the callback function (if necessary).""" if not self.delayed_weights.empty(): self.fih_weights = neuron.h.FInitializeHandler( 1, self.weights_callback) if self.plot_callback_necessary: self.fih_plots = neuron.h.FInitializeHandler(1, self.plot_callback)
[docs] def weights_callback(self): """Callback function that updates the delayed weights, when a certain delay has been reached.""" while not self.delayed_weights.empty() and \ abs(self.delayed_weights.queue[0][0] - neuron.h.t) < \ neuron.h.dt: (_, (sid, weight)) = self.delayed_weights.get() if sid in self.connections: if self.connections[sid].post_netcon is not None: self.connections[sid].post_netcon.weight[0] = weight if not self.delayed_weights.empty(): neuron.h.cvode.event( self.delayed_weights.queue[0][0], self.weights_callback )
[docs] def plot_callback(self): """Update all the windows.""" for window in self.plot_windows: window.redraw() for cell_dendrogram in self.cell_dendrograms: cell_dendrogram.redraw() neuron.h.cvode.event( neuron.h.t + 1, self.plot_callback)