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 <[email protected]> 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 _______________________________________________ debian-med-commit mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-med-commit
