Source code for lfpykit.cellgeometry

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Copyright (C) 2020 Computational Neuroscience Group, NMBU.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
"""

import numpy as np


[docs]class CellGeometry(object): ''' Base class representing the geometry of multicompartment neuron models. Assumptions - each compartment is piecewise linear between their start and endpoints - each compartment has a constant diameter - the transmembrane current density is constant along the compartment axis Parameters ---------- x: ndarray of floats shape (n_seg x 2) array of start- and end-point coordinates of each compartment along x-axis in units of (µm) y: ndarray shape (n_seg x 2) array of start- and end-point coordinates of each compartment along y-axis in units of (µm) z: ndarray shape (n_seg x 2) array of start- and end-point coordinates of each compartment along z-axis in units of (µm) d: ndarray shape (n_seg) or shape (n_seg x 2) array of compartment diameters in units of (µm). If the 2nd axis is equal to 2, conical frusta is assumed. Attributes ---------- totnsegs: int number of compartments x: ndarray of floats shape (totnsegs x 2) array of start- and end-point coordinates of each compartment along x-axis in units of (µm) y: ndarray shape (totnsegs x 2) array of start- and end-point coordinates of each compartment along y-axis in units of (µm) z: ndarray shape (totnsegs x 2) array of start- and end-point coordinates of each compartment along z-axis in units of (µm) d: ndarray shape (totnsegs) array of compartment diameters in units of (µm) length: ndarray lenght of each compartment in units of um area: ndarray array of compartment surface areas in units of um^2 ''' def __init__(self, x, y, z, d): # check input assert np.all([type(x) is np.ndarray, type(y) is np.ndarray, type(z) is np.ndarray, type(d) is np.ndarray]), \ 'x, y, z and d must be of type numpy.ndarray' assert x.ndim == y.ndim == z.ndim == 2, \ 'x, y and z must be of shape (n_seg x 2)' assert x.shape == y.shape == z.shape, \ 'x, y and z must all be the same shape' assert x.shape[1] == 2, \ 'the last axis of x, y and z must be of length 2' assert d.shape == x.shape or (d.ndim == 1 and d.size == x.shape[0]), \ 'd must either be 1-dimensional with size == n_seg ' + \ 'or 2-dimensional with d.shape == x.shape' # set attributes self.x = x self.y = y self.z = z self.d = d # derived attributes self.totnsegs = self.x.shape[0] self._set_length() self._set_area() def _set_length(self): self.length = np.sqrt(np.diff(self.x, axis=-1)**2 + np.diff(self.y, axis=-1)**2 + np.diff(self.z, axis=-1)**2).flatten() def _set_area(self): if self.d.ndim == 1: self.area = self.length * np.pi * self.d else: # Surface area of conical frusta # A = pi*(r1+r2)*sqrt((r1-r2)^2 + h^2) r = self.d / 2 self.area = np.pi * r.sum(axis=-1) * \ np.sqrt(np.diff(r, axis=-1).ravel()**2 + self.length**2)