Source code for bsb.connectivity.connectome.glomerulus_golgi

import numpy as np
from ..strategy import ConnectionStrategy
from ...helpers import DistributionConfiguration
from ...functions import get_distances
from scipy.stats.distributions import truncexpon


[docs]class ConnectomeGlomerulusGolgi(ConnectionStrategy): """ Legacy implementation for the connections between Golgi cells and glomeruli. """ defaults = {"detailed": False, "contacts": DistributionConfiguration.cast(1)} casts = {"detailed": bool, "contacts": DistributionConfiguration.cast}
[docs] def validate(self): if self.detailed: morphologies = self.to_cell_types[0].list_all_morphologies() if not morphologies: raise ConfigurationError( "Can't create detailed glomerulus to Golgi connections without any morphologies for the Golgi cell." ) elif len(morphologies) > 1: raise NotImplementedError( "Detailed glomerulus to Golgi connections can only be made for a single morphology." + " (Requires the selection of morphologies to be moved from the connection module to the placement module)" ) mr = self.scaffold.morphology_repository morphology = mr.get_morphology(morphologies[0]) self.dendritic_compartments = morphology.get_compartments(["dendrites"]) self.morphology = morphology
def connect(self): # Gather information for the legacy code block below. glomerulus_cell_type = self.from_cell_types[0] golgi_cell_type = self.to_cell_types[0] glomeruli = self.scaffold.cells_by_type[glomerulus_cell_type.name] golgis = self.scaffold.cells_by_type[golgi_cell_type.name] first_glomerulus = int(glomeruli[0, 0]) r_goc_vol = golgi_cell_type.morphology.dendrite_radius if self.detailed: compartments = np.ones((0, 2)) * -1 comps = self.dendritic_compartments total_compartments = len(comps) def connectome_glom_goc(first_glomerulus, glomeruli, golgicells, r_goc_vol): nonlocal compartments glom_bd = np.zeros((0, 2)) glom_x = glomeruli[:, 2] glom_y = glomeruli[:, 3] glom_z = glomeruli[:, 4] # If synaptic contacts need to be made we use this exponential distribution # to pick the closer by compartments. exp_dist = truncexpon(b=5, scale=0.03) # for all Golgi cells: calculate which glomeruli fall into the volume of GoC # basolateral dendrites, then choose 40 of them for the connection and delete # them from successive computations, since 1 axon is connected to 1 GoC for golgi_id, golgi_type, golgi_x, golgi_y, golgi_z in golgicells: # Geometric constraints: glom less than `r_goc_vol` away from golgi and # golgi cell soma above glom. volume_matrix = ( ((glom_x - golgi_x) ** 2) + ((glom_y - golgi_y) ** 2) + ((glom_z - golgi_z) ** 2) - (r_goc_vol ** 2) ).__le__(0) & glom_y.__le__(golgi_y) # finds indexes of granules that can potentially be connected good_gloms = np.where(volume_matrix == True)[0] # Translate local id to simulation id connected_gloms = good_gloms + first_glomerulus if self.detailed: # Draw a sample from the configured contacts distribution for each # connected glomerulus. samples = [int(x) for x in self.contacts.draw(len(connected_gloms))] # The total synaptic contacts is the sum of the contacts with each # glomerulus. total_contacts = sum(samples) # Compose an empty connection matrix to hold the connection records matrix = np.zeros((total_contacts, 2)) # Holds the connection_compartments for this golgi cell gg_comps = np.ones(matrix.shape) * -1 # Draw rolls from the exponential distribution equal to the total amount # of synaptic contacts to be made between this Golgi cell and all its # glomeruli. rolls = exp_dist.rvs(size=total_contacts) pointer = 0 for i, cg in enumerate(connected_gloms): sample = samples[i] _end = pointer + sample # Fill in `sample` records of the connection matrix matrix[pointer:_end, 0] = cg matrix[pointer:_end, 1] = golgi_id gid = good_gloms[i] # Get the distance sorted compartment indices d = np.array( get_distances( [c.start for c in comps], [ glom_x[gid] - golgi_x, glom_y[gid] - golgi_y, glom_z[gid] - golgi_z, ], ) ) d_comps = np.argsort(d) # Pick compartments according to a exponential distribution mapped # through the distance indices: high chance to pick closeby comps. gg_comps[pointer:_end, 1] = [ comps[d_comps[int(k * total_compartments)]].id for k in rolls[pointer:_end] ] pointer = _end # Stack the connection matrix glom_bd = np.vstack((glom_bd, matrix)) # Stack the compartment matrix compartments = np.vstack((compartments, gg_comps)) else: matrix = np.zeros((len(connected_gloms), 2)) matrix[:, 0] = connected_gloms # from cell matrix[:, 1] = golgi_id # to cell glom_bd = np.vstack((glom_bd, matrix)) return glom_bd connectome = connectome_glom_goc(first_glomerulus, glomeruli, golgis, r_goc_vol) if self.detailed: morphologies = np.zeros(connectome.shape) morphology_map = [self.morphology.morphology_name] self.scaffold.connect_cells( self, connectome, compartments=compartments, morphologies=morphologies, morpho_map=morphology_map, ) else: self.scaffold.connect_cells(self, connectome)