Source code for bluecellulab.cell.section_distance

# 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.
"""Distance computing functionality between Neuron sections."""

import neuron
import numpy as np


[docs] class EuclideanSectionDistance: """Calculate euclidian distance between positions on two sections. Parameters ---------- hsection1 : hoc section such as cADpyr_L2TPC_bluecellulab[0].apic[1] First section hsection2 : hoc section Second section location1 : float range x along hsection1 location2 : float range x along hsection2 dimensions : string planes to project on, e.g. 'xy' """ def __call__( self, hsection1, hsection2, location1: float = 0.5, location2: float = 0.5, dimensions: str = "xyz", ): """Computes and returns the distance.""" xs_interp1, ys_interp1, zs_interp1 = self.grindaway(hsection1) xs_interp2, ys_interp2, zs_interp2 = self.grindaway(hsection2) x1 = xs_interp1[int(np.floor((len(xs_interp1) - 1) * location1))] y1 = ys_interp1[int(np.floor((len(ys_interp1) - 1) * location1))] z1 = zs_interp1[int(np.floor((len(zs_interp1) - 1) * location1))] x2 = xs_interp2[int(np.floor((len(xs_interp2) - 1) * location2))] y2 = ys_interp2[int(np.floor((len(ys_interp2) - 1) * location2))] z2 = zs_interp2[int(np.floor((len(zs_interp2) - 1) * location2))] distance = 0 if "x" in dimensions: distance += (x1 - x2) ** 2 if "y" in dimensions: distance += (y1 - y2) ** 2 if "z" in dimensions: distance += (z1 - z2) ** 2 distance = np.sqrt(distance) return distance
[docs] @staticmethod def grindaway(hsection): """Grindaway.""" # get the data for the section n_segments = int(neuron.h.n3d(sec=hsection)) n_comps = hsection.nseg xs = np.zeros(n_segments) ys = np.zeros(n_segments) zs = np.zeros(n_segments) lengths = np.zeros(n_segments) for index in range(n_segments): xs[index] = neuron.h.x3d(index, sec=hsection) ys[index] = neuron.h.y3d(index, sec=hsection) zs[index] = neuron.h.z3d(index, sec=hsection) lengths[index] = neuron.h.arc3d(index, sec=hsection) # to use Vector class's .interpolate() # must first scale the independent variable # i.e. normalize length along centroid lengths /= lengths[-1] # initialize the destination "independent" vector # range = np.array(n_comps+2) comp_range = np.arange(0, n_comps + 2) / n_comps - 1.0 / (2 * n_comps) comp_range[0] = 0 comp_range[-1] = 1 # length contains the normalized distances of the pt3d points # along the centroid of the section. These are spaced at # irregular intervals. # range contains the normalized distances of the nodes along the # centroid of the section. These are spaced at regular intervals. # Ready to interpolate. xs_interp = np.interp(comp_range, lengths, xs) ys_interp = np.interp(comp_range, lengths, ys) zs_interp = np.interp(comp_range, lengths, zs) return xs_interp, ys_interp, zs_interp