Source code for tvb.datatypes.local_connectivity
# -*- coding: utf-8 -*-
#
#
# TheVirtualBrain-Scientific Package. This package holds all simulators, and
# analysers necessary to run brain-simulations. You can use it stand alone or
# in conjunction with TheVirtualBrain-Framework Package. See content of the
# documentation-folder for more details. See also http://www.thevirtualbrain.org
#
# (c) 2012-2023, Baycrest Centre for Geriatric Care ("Baycrest") and others
#
# 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.
# You should have received a copy of the GNU General Public License along with this
# program. If not, see <http://www.gnu.org/licenses/>.
#
#
# CITATION:
# When using The Virtual Brain for scientific publications, please cite it as explained here:
# https://www.thevirtualbrain.org/tvb/zwei/neuroscience-publications
#
#
import numpy
import scipy.sparse
from tvb.basic.neotraits.api import HasTraits, Attr, Float, narray_summary_info
from tvb.basic.readers import try_get_absolute_path, FileReader
from tvb.datatypes import equations, surfaces
[docs]class LocalConnectivity(HasTraits):
"""
A sparse matrix for representing the local connectivity within the Cortex.
"""
surface = Attr(field_type=surfaces.CorticalSurface, label="Surface")
matrix = Attr(field_type=scipy.sparse.spmatrix, required=False)
equation = Attr(
field_type=equations.FiniteSupportEquation,
label="Spatial",
required=False,
default=equations.Gaussian())
cutoff = Float(
label="Cutoff distance (mm)",
default=40.0,
doc="Distance at which to truncate the evaluation in mm.")
# Temporary obj
matrix_gdist = None
[docs] def compute(self):
"""
Compute current Matrix.
"""
self.log.info("Mapping geodesic distance through the LocalConnectivity.")
# Start with data being geodesic_distance_matrix, then map it through equation
# Then replace original data with result...
self.matrix_gdist.data = self.equation.evaluate(self.matrix_gdist.data)
# Homogenise spatial discretisation effects across the surface
nv = self.matrix_gdist.shape[0]
ind = numpy.arange(nv, dtype=int)
pos_mask = self.matrix_gdist.data > 0.0
neg_mask = self.matrix_gdist.data < 0.0
pos_con = self.matrix_gdist.copy()
neg_con = self.matrix_gdist.copy()
pos_con.data[neg_mask] = 0.0
neg_con.data[pos_mask] = 0.0
pos_contrib = pos_con.sum(axis=1)
pos_contrib = numpy.array(pos_contrib).squeeze()
neg_contrib = neg_con.sum(axis=1)
neg_contrib = numpy.array(neg_contrib).squeeze()
pos_mean = pos_contrib.mean()
neg_mean = neg_contrib.mean()
if ((pos_mean != 0.0 and any(pos_contrib == 0.0)) or
(neg_mean != 0.0 and any(neg_contrib == 0.0))):
msg = "Cortical mesh is too coarse for requested LocalConnectivity."
self.log.warning(msg)
bad_verts = ()
if pos_mean != 0.0:
bad_verts = bad_verts + numpy.nonzero(pos_contrib == 0.0)
if neg_mean != 0.0:
bad_verts = bad_verts + numpy.nonzero(neg_contrib == 0.0)
self.log.debug("Problem vertices are: %s" % str(bad_verts))
pos_hf = numpy.zeros(shape=pos_contrib.shape)
pos_hf[pos_contrib != 0] = pos_mean / pos_contrib[pos_contrib != 0]
neg_hf = numpy.zeros(shape=neg_contrib.shape)
neg_hf[neg_contrib != 0] = neg_mean / neg_contrib[neg_contrib != 0]
pos_hf_diag = scipy.sparse.csc_matrix((pos_hf, (ind, ind)), shape=(nv, nv))
neg_hf_diag = scipy.sparse.csc_matrix((neg_hf, (ind, ind)), shape=(nv, nv))
homogenious_conn = (pos_hf_diag * pos_con) + (neg_hf_diag * neg_con)
# Then replace unhomogenised result with the spatially homogeneous one...
if not homogenious_conn.has_sorted_indices:
homogenious_conn.sort_indices()
self.matrix = homogenious_conn
[docs] @staticmethod
def from_file(source_file="local_connectivity_16384.mat"):
result = LocalConnectivity()
source_full_path = try_get_absolute_path("tvb_data.local_connectivity", source_file)
reader = FileReader(source_full_path)
result.matrix = reader.read_array(matlab_data_name="LocalCoupling")
return result
[docs] def summary_info(self):
"""
Gather scientifically interesting summary information from an instance
of this datatype.
"""
_, _, v = scipy.sparse.find(self.matrix)
return narray_summary_info(v, ar_name='matrix-nonzero')
[docs] def compute_sparse_matrix(self):
"""
NOTE: Before calling this method, the surface field
should already be set on the local connectivity.
Computes the sparse matrix for this local connectivity.
"""
if self.surface is None:
raise AttributeError('Require surface to compute local connectivity.')
self.matrix_gdist = surfaces.gdist.local_gdist_matrix(
self.surface.vertices.astype(numpy.float64),
self.surface.triangles.astype(numpy.int32),
max_distance=self.cutoff)
self.compute()
# Avoid having a large data-set in memory.
self.matrix_gdist = None