Source code for neurorosettes.neurons

"""This module deals with the neuron structure and functions"""
from dataclasses import dataclass
import numpy as np

from neurorosettes.subcellular import Neurite, ObjectFactory
from neurorosettes.clocks import CellClocks, ClocksFactory
from neurorosettes.physics import normalize_vector


[docs]class Neuron: """ Class to represent a neuron as a combination of a cell body and neurites. Parameters ---------- position The center position of the neuron's cell body. outgrowth_axis The direction of growth of the neuron's neurites. factory The factory object to be used to create new neuron components. clocks The rates of the neuron's biological processes. max_number_of_neurites The total number of neurites a neuron can have before proliferation is blocked. differentiation_grade The starting differentiation stage of the neurite, represented by the initial number of neurites. """ def __init__( self, position: np.ndarray, outgrowth_axis: np.ndarray, factory: ObjectFactory, clocks: CellClocks, max_number_of_neurites: int = 4, differentiation_grade: int = 0, ) -> None: self.cell = factory.get_cell_body(position) self.outgrowth_axis = outgrowth_axis self.clocks = clocks self.max_number_of_neurites = max_number_of_neurites self.neurites = [] if differentiation_grade != 0: self.create_first_neurite(factory) for _ in range(1, differentiation_grade): self.create_secondary_neurite(factory) @property def cell_radius(self): """The radius of the neuron's cell body.""" return self.cell.mechanics.radius @property def ready_for_division(self): """If the neuron is ready to proliferate.""" return self.clocks.cycle_clock.signal @property def ready_for_differentiation(self): """If the neuron is ready to differentiate.""" return self.clocks.differentiation_clock.signal @property def ready_to_die(self): """If the neuron is ready to die.""" return self.clocks.death_clock.signal
[docs] def set_outgrowth_axis(self, coordinates: np.ndarray) -> None: """ Sets the axis that neurites will follow when new neurites are created. Prameters ---------- outgrowth_axis The direction of growth of the neuron's neurites. """ if np.linalg.norm(coordinates) > 1.0: coordinates = normalize_vector(coordinates) self.outgrowth_axis[0] = coordinates[0] self.outgrowth_axis[1] = coordinates[1] self.outgrowth_axis[2] = coordinates[2]
[docs] def get_neurite_position_on_cell_surface(self) -> np.ndarray: """Returns the coordinates on the cell surface where the first neurite should be placed""" connector = self.neurites[0].distal_point - self.cell.position unit_connector = connector / np.linalg.norm(connector) new_point = self.cell.position + unit_connector * self.cell.mechanics.radius return new_point
[docs] def place_neurite_on_cell_surface(self, neurite: Neurite) -> None: """ Places the neurite base on the cell surface according to the cell-distal vector. Parameters ---------- neurite The neurite to be placed on the cell body's surface. """ neurite_attachment_coordinates = self.get_neurite_position_on_cell_surface() neurite.move_proximal_point(neurite_attachment_coordinates)
[docs] def create_first_neurite(self, factory: ObjectFactory) -> None: """ Creates a neurite attached to the soma cell Parameters ---------- factory The factory object to be used to create new neuron components. """ proximal_point = ( self.cell.position + self.outgrowth_axis * self.cell.mechanics.radius ) neurite = factory.get_neurite(proximal_point, self.outgrowth_axis) self.neurites.append(neurite) self.clocks.cycle_clock.cycle_block = True
[docs] def create_secondary_neurite(self, factory: ObjectFactory) -> None: """ Creates a neurite attached to the most recent neurite. Parameters ---------- factory The factory object to be used to create new neuron components. """ if len(self.neurites) >= self.max_number_of_neurites: return proximal_point = self.neurites[-1].distal_point neurite = factory.get_neurite(proximal_point, self.outgrowth_axis) self.neurites.append(neurite)
[docs]@dataclass class NeuronFactory: """ Helper class to create instances of neurons based on defined properties. """ max_number_of_neurites: int """The maximum number of neurites that a neuron can have.""" objects_factory: ObjectFactory """The ObjectFactory used to create new object instances.""" clocks_factory: ClocksFactory """The ClocksFactory used to create new clock instances."""
[docs] def create_neuron( self, coordinates: np.ndarray, outgrowth_axis: np.ndarray ) -> Neuron: """Returns a Neuron object placed in the given coordinates.""" clocks = self.clocks_factory.get_clocks() return Neuron( coordinates, outgrowth_axis, self.objects_factory, clocks, self.max_number_of_neurites, )