Source code for bowhead.velocity

from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import *
import numpy as np


[docs]class Model: """Wound velocity model. The model is based on Gaussian Process Regression (GPR) and numerical differentiation. The GPR uses scikit-learn GPR class ``sklearn.gaussian_process.GaussianProcessRegressor``. Parameters ---------- area_kwargs : dictionary The keyword arguments to the area GPR model. perimeter_kwargs : dictionary The keyword arguments to the perimeter GPR model. Attributes ----------- area : area model Instances of GaussianProcessRegressor from scikit-learn. perimeter : perimeter model Instances of GaussianProcessRegressor from scikit-learn. time : sequence Sequence of the input time points. Defined when fitted. Notes ----- The keyword argument ``kernel`` is specifying the covariance function of the GPR models handling the area and perimeter. The default kernel is a sum of a linear and squared dotproduct kernel. See `scikit-learn <http://www.scikit-learn.org/stable/modules/gaussian_process.html>`_ for the different kernels that can be used. Note that the kernel hyperparameters are optimized during fitting. """ def __init__(self, area_kwargs = None, perimeter_kwargs = None): kernel = ConstantKernel() + 1*DotProduct()**2 kwargs = {'kernel': kernel, 'n_restarts_optimizer': 5, 'normalize_y': True} if area_kwargs is None: area_kwargs = kwargs if perimeter_kwargs is None: perimeter_kwargs = kwargs self.area = GaussianProcessRegressor(**area_kwargs) self.perimeter = GaussianProcessRegressor(**perimeter_kwargs) self.time = None
[docs] def fit(self, wounds): """Fitting the velocity model to wound data. Parameters ---------- wounds : sequence of dictionaries A sequence of wound dictionaries representing an experimental time series of the wound healing assay, as returned by :func:`detect`. The area, perimeter and time point of each wound is used to fit the overall velocity model. All these attributes should be positive scalars. Returns ------- self : Model The velocity model in a fitted state. """ wounds = sorted(wounds, key=lambda x: x['time']) self.time = np.array([x['time'] for x in wounds]) time = self.time.reshape(-1,1) self.area.alpha = np.array([x['area_variance'] for x in wounds]) self.area.fit(time, np.array([x['area'] for x in wounds])) self.perimeter.alpha = np.array([x['perimeter_variance'] for x in wounds]) self.perimeter.fit(time, np.array([x['perimeter'] for x in wounds])) return self
[docs] def predict(self, time, dt=.1, return_std=False): """Predicting a velocity curve of a wound healing experiment. In addition to the mean of the predictive distribution, also its standard deviation (return_std=True) can be requested. Parameters ----------- time : sequence Desired time points of the velocity prediction. Should be positive. dt : scalar The time interval for calculating velocity. return_std : bool Whether to include the standard deviation of the prediction or not. Returns ------- velocity, [vel_std] : 1d arrays Velocity and (optionally) it's standard deviation. Returned either one array or (if return_std=True) as a tuple (velocity, vel_std). """ time = np.asarray(time, dtype=float).round(4) linear_time = np.arange(time.min(), time.max(), dt, dtype=float).round(4) if len(linear_time) < 10: raise ValueError('choose a smaller dt for numeric stability') ptime = np.union1d(time, linear_time) area, a_std = self.area.predict(ptime.reshape(-1,1), return_std=True) peri, p_std = self.perimeter.predict(ptime.reshape(-1,1), return_std=True) da = np.gradient(area) / np.gradient(ptime) resolution = np.mean(np.gradient(self.time)) da_std = np.sqrt(2)*a_std / resolution vel = -da / peri frac_q = (da_std/da)**2 + (p_std/peri)**2 vel_std = np.abs(vel) * np.sqrt(frac_q) mask = np.in1d(ptime, time) velocity = vel[mask][np.argsort(time)] v_std = vel_std[mask][np.argsort(time)] if return_std: return velocity, v_std return velocity