Source code for mcmodels.models.voxel.voxel_model

"""
Module containing object :class:`VoxelModel`. The only difference between this
estimator and :class:`NadarayaWatson` is that class:`VoxelModel` one treats the
full injection volume (masked and flattened) as the input data `X` instead of
only the centroids. Thus, :class:'VoxelModel` must be instatiated with the
array of source_voxels, and the input data `X` must be passed as a tuple of arrays
: (centroids, injections) or a concatenated array.
"""
# Authors: Joseph Knox <josephk@alleninstitute.org>
# License: Allen Institute Software License

from __future__ import division
import numpy as np

from scipy.sparse import issparse
from sklearn.utils.validation import check_is_fitted

from ...regressors import NadarayaWatson


[docs]class VoxelModel(NadarayaWatson): """Voxel-scale interpolation model for mesoscale connectivity. Parameters ---------- source_voxels : array-like, shape=(n_voxels, 3) List of voxel coordinates at which to interpolate. Examples -------- >>> from mcmodels.core import VoxelModelCache >>> from mcmodels.models import VoxelModel >>> cache = VoxelModelCache >>> # get cortical experiment data >>> cortex_data = cache.get_experiment_data(injection_structure_ids=[315]) >>> source_voxels = cortex_data.source_mask.coordinates >>> reg = VoxelModel(source_voxels) >>> reg.fit((cortex_data.centroids, cortex_data.injections)) VoxelModel(source_voxels=array([[ ... ]])) References ---------- Knox et al. 'High resolution data-driven model of the mouse connectome'. bioRxiv 293019; doi: https://doi.org/10.1101/293019 See also -------- NadarayaWatson """
[docs] def __init__(self, source_voxels, kernel="linear", degree=3, coef0=1, gamma=None, kernel_params=None): super(VoxelModel, self).__init__(kernel=kernel, degree=degree, coef0=coef0, gamma=gamma, kernel_params=kernel_params) self.source_voxels = source_voxels self.dimension = self.source_voxels.shape[1]
def _compute_weights(self, X, y=None): K = self._get_kernel(X, y) return self._normalize_kernel(K, overwrite=True)
[docs] def fit(self, X, y, sample_weight=None): """Fit Voxel Model. NOTE : X is a concatenation (column wise) of the injection centroid coordinates and the injection volumes. This choice was made to be consistent with the sklearn.core.BaseEstimator fit and predict schema Parameters ---------- X : {array-like, sparse matrix}, shape=(n_exps, 3+n_source_voxels) Centroid coordinates concatenated with the injection density for each training experiment. y : {array-like, sparse matrix}, shape=(n_exps, n_target_voxels) Normalized projection density for each training experiment Returns ------- self : returns an instance of self. """ if isinstance(X, (list, tuple)): centroids = X[0] else: # assume array centroids = X[:, :self.dimension] X, y = self._check_fit_arrays(centroids, y, sample_weight) self.y_ = y self.weights_ = self._compute_weights(self.source_voxels, centroids) return self
[docs] def predict(self, X): """Predict projection volumes given injection volumes. NOTE : X is a concatenation (column wise) of the injection centroid coordinates and the injection volumes. This choice was made to be consistent with the sklearn.core.BaseEstimator fit and predict schema Parameters ---------- X : {array-like, sparse matrix}, shape=(n_exps, 3+n_source_voxels) Centroid coordinates concatenated with the injection density for each test experiment. Returns ------- C : array, shape=(X.shape[0], y.shape[1]) Predicted normalized projection densities. """ check_is_fitted(self, ["weights_", "y_"]) if isinstance(X, (list, tuple)): injection = X[1] else: #assume array injection = X[:, self.dimension:] if len(injection.shape) == 1: injection = injection.reshape(-1, 1) # has to be of form sparse.dot(dense) y = self.y_.toarray() if issparse(self.y_) else self.y_ return injection.dot(self.weights_).dot(y)
[docs] def get_weights(self): """Overwrite of NadarayaWatson.get_weights.""" check_is_fitted(self, ["weights_", "y_"]) return self.weights_
@property def weights(self): """Return model weights.""" check_is_fitted(self, ["weights_", "y_"]) return self.weights_ @property def nodes(self): """Return model nodes (data).""" check_is_fitted(self, ["weights_", "y_"]) return self.y_