[med-svn] [python-mne] 88/353: ENH : support algebra of covariance matrices + fix writing when cov is computed in python
Yaroslav Halchenko
debian at onerussian.com
Fri Nov 27 17:24:35 UTC 2015
This is an automated email from the git hooks/post-receive script.
yoh pushed a commit to tag 0.4
in repository python-mne.
commit 0c22e6093c8ba04d800ec856e3363b3d13c257a0
Author: Alexandre Gramfort <alexandre.gramfort at inria.fr>
Date: Tue Feb 28 10:52:47 2012 +0100
ENH : support algebra of covariance matrices + fix writing when cov is computed in python
---
mne/cov.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++++--
mne/tests/test_cov.py | 38 +++++++++++++++++++++----
2 files changed, 109 insertions(+), 8 deletions(-)
diff --git a/mne/cov.py b/mne/cov.py
index 091829b..086f50e 100644
--- a/mne/cov.py
+++ b/mne/cov.py
@@ -23,8 +23,40 @@ from .fiff.pick import pick_types, channel_indices_by_type
from .epochs import _is_good
+def _check_covs_algebra(cov1, cov2):
+ if cov1.ch_names != cov2.ch_names:
+ raise ValueError('Both Covariance do not have the same list of '
+ 'channels.')
+ if map(str, cov1._cov['projs']) != map(str, cov2._cov['projs']):
+ raise ValueError('Both Covariance do not have the same list of '
+ 'SSP projections.')
+ if cov1._cov['bads'] != cov2._cov['bads']:
+ raise ValueError('Both Covariance do not have the same list of '
+ 'bad channels.')
+
+
class Covariance(object):
- """Noise covariance matrix"""
+ """Noise covariance matrix
+
+ Parameters
+ ----------
+ fname: string
+ The name of the raw file
+
+ kind: 'full' | 'diagonal'
+ The type of covariance.
+
+ Attributes
+ ----------
+ data : 2D array of shape [n_channels x n_channels]
+ The covariance
+
+ ch_names: list of string
+ List of channels' names
+
+ nfree : int
+ Number of degrees of freedom i.e. number of time points used
+ """
_kind_to_id = dict(full=1, sparse=2, diagonal=3) # XXX : check
_id_to_kind = {1: 'full', 2: 'sparse', 3: 'diagonal'} # XXX : check
@@ -49,6 +81,7 @@ class Covariance(object):
self._cov = cov
self.data = cov['data']
self.ch_names = cov['names']
+ self.nfree = cov['nfree']
def save(self, fname):
"""save covariance matrix in a FIF file"""
@@ -60,6 +93,23 @@ class Covariance(object):
s += ", data : %s" % self.data
return "Covariance (%s)" % s
+ def __add__(self, cov):
+ """Add Covariance taking into account number of degrees of freedom"""
+ _check_covs_algebra(self, cov)
+ this_cov = copy.deepcopy(cov)
+ this_cov.data[:] += self.data
+ this_cov._cov['nfree'] += self._cov['nfree']
+ this_cov.nfree = this_cov._cov['nfree']
+ return this_cov
+
+ def __iadd__(self, cov):
+ """Add Covariance taking into account number of degrees of freedom"""
+ _check_covs_algebra(self, cov)
+ self.data[:] += cov.data
+ self._cov['nfree'] += cov._cov['nfree']
+ self.nfree = cov._cov['nfree']
+ return self
+
###############################################################################
# IO
@@ -125,8 +175,8 @@ def read_cov(fid, node, cov_kind):
# Diagonal is stored
data = tag.data
diagmat = True
- print ' %d x %d diagonal covariance (kind = %d) found.' \
- % (dim, dim, cov_kind)
+ print (' %d x %d diagonal covariance (kind = %d) found.'
+ % (dim, dim, cov_kind))
else:
from scipy import sparse
@@ -263,6 +313,18 @@ def compute_raw_data_covariance(raw, tmin=None, tmax=None, tstep=0.2,
cov = Covariance(None)
cov.data = data
cov.ch_names = [raw.info['ch_names'][k] for k in picks_data]
+ cov.nfree = n_samples
+
+ # XXX : do not compute eig and eigvec now (think it's better...)
+ eig = None
+ eigvec = None
+
+ # Store structure for fif
+ cov._cov = dict(kind=1, diag=False, dim=len(data), names=cov.ch_names,
+ data=data, projs=copy.deepcopy(raw.info['projs']),
+ bads=raw.info['bads'], nfree=n_samples, eig=eig,
+ eigvec=eigvec)
+
return cov
@@ -310,6 +372,17 @@ def compute_covariance(epochs, keep_sample_mean=True):
cov = Covariance(None)
cov.data = data
cov.ch_names = ch_names
+ cov.nfree = n_samples
+
+ # XXX : do not compute eig and eigvec now (think it's better...)
+ eig = None
+ eigvec = None
+
+ # Store structure for fif
+ cov._cov = dict(kind=1, diag=False, dim=len(data), names=ch_names,
+ data=data, projs=copy.deepcopy(epochs.info['projs']),
+ bads=epochs.info['bads'], nfree=n_samples, eig=eig,
+ eigvec=eigvec)
print "Number of samples used : %d" % n_samples
print '[done]'
diff --git a/mne/tests/test_cov.py b/mne/tests/test_cov.py
index 2124f02..ab28ab1 100644
--- a/mne/tests/test_cov.py
+++ b/mne/tests/test_cov.py
@@ -29,11 +29,8 @@ def test_io_cov():
write_cov_file('cov.fif', cov)
- fid, tree, _ = fiff_open('cov.fif')
- cov2 = read_cov(fid, tree, cov_type)
- fid.close()
-
- assert_array_almost_equal(cov['data'], cov2['data'])
+ cov2 = Covariance('cov.fif')
+ assert_array_almost_equal(cov['data'], cov2.data)
def test_cov_estimation_on_raw_segment():
@@ -48,6 +45,14 @@ def test_cov_estimation_on_raw_segment():
assert_true(linalg.norm(cov.data - cov_mne.data, ord='fro')
/ linalg.norm(cov.data, ord='fro')) < 1e-6
+ # test IO when computation done in Python
+ cov.save('test-cov.fif') # test saving
+ cov_read = Covariance('test-cov.fif')
+ assert_true(cov_read.ch_names == cov.ch_names)
+ assert_true(cov_read.nfree == cov.nfree)
+ assert_true((linalg.norm(cov.data - cov_read.data, ord='fro')
+ / linalg.norm(cov.data, ord='fro')) < 1e-5)
+
def test_cov_estimation_with_triggers():
"""Estimate raw with triggers
@@ -73,3 +78,26 @@ def test_cov_estimation_with_triggers():
assert_true(cov_mne.ch_names == cov.ch_names)
assert_true((linalg.norm(cov.data - cov_mne.data, ord='fro')
/ linalg.norm(cov.data, ord='fro')) < 0.06)
+
+ # test IO when computation done in Python
+ cov.save('test-cov.fif') # test saving
+ cov_read = Covariance('test-cov.fif')
+ assert_true(cov_read.ch_names == cov.ch_names)
+ assert_true(cov_read.nfree == cov.nfree)
+ assert_true((linalg.norm(cov.data - cov_read.data, ord='fro')
+ / linalg.norm(cov.data, ord='fro')) < 1e-5)
+
+
+def test_arithmetic_cov():
+ """Test arithmetic with noise covariance matrices
+ """
+ cov = Covariance(cov_fname)
+ cov_sum = cov + cov
+ assert_array_almost_equal(2 * cov.nfree, cov_sum.nfree)
+ assert_array_almost_equal(2 * cov.data, cov_sum.data)
+ assert_true(cov.ch_names == cov_sum.ch_names)
+
+ cov += cov
+ assert_array_almost_equal(cov_sum.nfree, cov.nfree)
+ assert_array_almost_equal(cov_sum.data, cov.data)
+ assert_true(cov_sum.ch_names == cov.ch_names)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/python-mne.git
More information about the debian-med-commit
mailing list