{"action":"created","comment":{"url":"https://api.github.com/repos/mne-tools/mne-python/pulls/comments/174926910","pull_request_review_id":104374123,"id":174926910,"diff_hunk":"@@ -1,56 +1,512 @@\n-# Author: Roman Goj <roman.goj@gmail.com>\n+# -*- coding: utf-8 -*-\n+# Authors: Marijn van Vliet <w.m.vanvliet@gmail.com>\n+#          Susanna Aro <susanna.aro@aalto.fi>\n+#          Roman Goj <roman.goj@gmail.com>\n #\n # License: BSD (3-clause)\n \n import copy as cp\n+import numbers\n \n import numpy as np\n-\n-from ..io.pick import pick_types\n-from ..utils import logger, verbose, warn\n+from .tfr import cwt, morlet\n+from ..io.pick import pick_channels\n+from ..utils import (logger, verbose, warn, copy_function_doc_to_method_doc,\n+                     deprecated)\n+from ..viz.misc import plot_csd\n from ..time_frequency.multitaper import (dpss_windows, _mt_spectra,\n                                          _csd_from_mt, _psd_from_mt_adaptive)\n-\n-from ..externals.six.moves import xrange as range\n+from ..parallel import parallel_func\n+from ..externals.h5io import read_hdf5, write_hdf5\n \n \n class CrossSpectralDensity(object):\n     \"\"\"Cross-spectral density.\n \n+    Given a list of time series, the CSD matrix denotes for each pair of time\n+    series, the cross-spectral density. This matrix is symmetric and internally\n+    stored as a vector.\n+\n+    This object can store multiple CSD matrices: one for each frequency.\n+    Use ``.get_data(freq)`` to obtain an CSD matrix as an ndarray.\n+\n     Parameters\n     ----------\n-    data : array of shape (n_channels, n_channels)\n-        The cross-spectral density matrix.\n+    data : ndarray, shape ((n_channels**2 + n_channels) / 2, n_frequencies)\n+        For each frequency, the cross-spectral density matrix in vector format.\n     ch_names : list of string\n-        List of channels' names.\n-    projs :\n-        List of projectors used in CSD calculation.\n-    bads :\n-        List of bad channels.\n-    freqs : float | list of float\n-        Frequency or frequencies for which the CSD matrix was calculated. If a\n-        list is passed, data is a sum across CSD matrices for all frequencies.\n+        List of string names for each channel.\n+    tmin : float\n+        Start of the time window for which CSD was calculated in seconds.\n+    tmax : float\n+        End of the time window for which CSD was calculated in seconds.\n+    frequencies : float | list of float | list of list of float\n+        Frequency or frequencies for which the CSD matrix was calculated. When\n+        averaging across frequencies (see the :func:`CrossSpectralDensity.mean`\n+        function), this will be a list of lists that contains for each\n+        frequency bin, the frequencies that were averaged. Frequencies should\n+        always be sorted.\n     n_fft : int\n-        Length of the FFT used when calculating the CSD matrix.\n+        The number of FFT points or samples that have been used in the\n+        computation of this CSD.\n+    projs : list of Projection | None\n+        List of projectors to apply to timeseries data when using this CSD\n+        object to compute a DICS beamformer. Defaults to ``None``, which means\n+        no projectors will be applied.\n+\n+    See Also\n+    --------\n+    csd_epochs\n+    csd_array\n     \"\"\"\n \n-    def __init__(self, data, ch_names, projs, bads, freqs,\n-                 n_fft):  # noqa: D102\n-        self.data = data\n-        self.dim = len(data)\n-        self.ch_names = cp.deepcopy(ch_names)\n-        self.projs = cp.deepcopy(projs)\n-        self.bads = cp.deepcopy(bads)\n-        self.freqs = np.atleast_1d(np.copy(freqs))\n+    def __init__(self, data, ch_names, tmin, tmax, frequencies, n_fft,","path":"mne/time_frequency/csd.py","position":88,"original_position":88,"commit_id":"391f02860d8fd81d5d29c223589d3df37f2dce53","original_commit_id":"391f02860d8fd81d5d29c223589d3df37f2dce53","user":{"login":"agramfort","id":161052,"avatar_url":"https://avatars2.githubusercontent.com/u/161052?v=4","gravatar_id":"","url":"https://api.github.com/users/agramfort","html_url":"https://github.com/agramfort","followers_url":"https://api.github.com/users/agramfort/followers","following_url":"https://api.github.com/users/agramfort/following{/other_user}","gists_url":"https://api.github.com/users/agramfort/gists{/gist_id}","starred_url":"https://api.github.com/users/agramfort/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/agramfort/subscriptions","organizations_url":"https://api.github.com/users/agramfort/orgs","repos_url":"https://api.github.com/users/agramfort/repos","events_url":"https://api.github.com/users/agramfort/events{/privacy}","received_events_url":"https://api.github.com/users/agramfort/received_events","type":"User","site_admin":false},"body":"why is tmin, tmax necessary?","created_at":"2018-03-15T20:46:29Z","updated_at":"2018-03-15T20:46:29Z","html_url":"https://github.com/mne-tools/mne-python/pull/5021#discussion_r174926910","pull_request_url":"https://api.github.com/repos/mne-tools/mne-python/pulls/5021","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/mne-tools/mne-python/pulls/comments/174926910"},"html":{"href":"https://github.com/mne-tools/mne-python/pull/5021#discussion_r174926910"},"pull_request":{"href":"https://api.github.com/repos/mne-tools/mne-python/pulls/5021"}}},"pull_request":{"url":"https://api.github.com/repos/mne-tools/mne-python/pulls/5021","id":175287927,"html_url":"https://github.com/mne-tools/mne-python/pull/5021","diff_url":"https://github.com/mne-tools/mne-python/pull/5021.diff","patch_url":"https://github.com/mne-tools/mne-python/pull/5021.patch","issue_url":"https://api.github.com/repos/mne-tools/mne-python/issues/5021","number":5021,"state":"open","locked":false,"title":"extend cross-spectral density (CSD) functionality","user":{"login":"wmvanvliet","id":428273,"avatar_url":"https://avatars3.githubusercontent.com/u/428273?v=4","gravatar_id":"","url":"https://api.github.com/users/wmvanvliet","html_url":"https://github.com/wmvanvliet","followers_url":"https://api.github.com/users/wmvanvliet/followers","following_url":"https://api.github.com/users/wmvanvliet/following{/other_user}","gists_url":"https://api.github.com/users/wmvanvliet/gists{/gist_id}","starred_url":"https://api.github.com/users/wmvanvliet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wmvanvliet/subscriptions","organizations_url":"https://api.github.com/users/wmvanvliet/orgs","repos_url":"https://api.github.com/users/wmvanvliet/repos","events_url":"https://api.github.com/users/wmvanvliet/events{/privacy}","received_events_url":"https://api.github.com/users/wmvanvliet/received_events","type":"User","site_admin":false},"body":"## Relation to the DICS PR\r\n\r\nThis overhaul of the CSD functionality was started in #4797, but is now split off into it's own PR. In this PR, the DICS code has been left untouched, except for some minor modifications to use the new CSD objects.\r\n\r\n## New CSD object\r\n\r\nThe CrossSpectralDensity object has been extended. It can now contain multiple CSD matrices. Since it is a very common use case to want to compute the CSD for multiple frequency bands, the intended workflow is now:\r\n\r\n - Compute the CSD for all desired frequencies once\r\n - Save it to avoid recomputing this beast\r\n - Use `csd.mean` to average across frequency bands at will\r\n - Feed the CSD object into `dics_source_power` to obtain an STC with the desired frequency bands as the \"time\" dimension.\r\n\r\n`CrossSpectralDensity` objects have a `save` method and there is now a `read_csd` function.\r\n\r\n## Refactoring of the old csd functions\r\n\r\nThe `csd_epochs` and `csd_array` functions have been refactored to mimic the `tfr_*` functions. Instead of using `mode=\"...\"` we now have:\r\n - `csd_fourier`\r\n - `csd_multitaper`\r\n - `csd_array_fourier`\r\n - `csd_array_multitaper`\r\n\r\nThe old functions still remain with the `@deprecated` flag and simply delegate to the new functions. The old unit tests also still remain (and pass).\r\n\r\n## New functionality\r\n\r\nThe ability of using Morlet wavelets to estimate the CSD has been added, so now we also have:\r\n - `csd_morlet`\r\n - `csd_array_morlet`\r\n\r\nCSD objects have a shiny plotting function to visually verify the result. It can also plot the channel-to-channel coherence (`mode='coh'`) which is useful for debugging your connectivity results.\r\n\r\n","created_at":"2018-03-15T15:28:29Z","updated_at":"2018-03-15T20:46:29Z","closed_at":null,"merged_at":null,"merge_commit_sha":"90ebe36a0b9436298789cf8f63d8e43f20b7e749","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/mne-tools/mne-python/pulls/5021/commits","review_comments_url":"https://api.github.com/repos/mne-tools/mne-python/pulls/5021/comments","review_comment_url":"https://api.github.com/repos/mne-tools/mne-python/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mne-tools/mne-python/issues/5021/comments","statuses_url":"https://api.github.com/repos/mne-tools/mne-python/statuses/391f02860d8fd81d5d29c223589d3df37f2dce53","head":{"label":"wmvanvliet:csd4","ref":"csd4","sha":"391f02860d8fd81d5d29c223589d3df37f2dce53","user":{"login":"wmvanvliet","id":428273,"avatar_url":"https://avatars3.githubusercontent.com/u/428273?v=4","gravatar_id":"","url":"https://api.github.com/users/wmvanvliet","html_url":"https://github.com/wmvanvliet","followers_url":"https://api.github.com/users/wmvanvliet/followers","following_url":"https://api.github.com/users/wmvanvliet/following{/other_user}","gists_url":"https://api.github.com/users/wmvanvliet/gists{/gist_id}","starred_url":"https://api.github.com/users/wmvanvliet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wmvanvliet/subscriptions","organizations_url":"https://api.github.com/users/wmvanvliet/orgs","repos_url":"https://api.github.com/users/wmvanvliet/repos","events_url":"https://api.github.com/users/wmvanvliet/events{/privacy}","received_events_url":"https://api.github.com/users/wmvanvliet/received_events","type":"User","site_admin":false},"repo":{"id":23457160,"name":"mne-python","full_name":"wmvanvliet/mne-python","owner":{"login":"wmvanvliet","id":428273,"avatar_url":"https://avatars3.githubusercontent.com/u/428273?v=4","gravatar_id":"","url":"https://api.github.com/users/wmvanvliet","html_url":"https://github.com/wmvanvliet","followers_url":"https://api.github.com/users/wmvanvliet/followers","following_url":"https://api.github.com/users/wmvanvliet/following{/other_user}","gists_url":"https://api.github.com/users/wmvanvliet/gists{/gist_id}","starred_url":"https://api.github.com/users/wmvanvliet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wmvanvliet/subscriptions","organizations_url":"https://api.github.com/users/wmvanvliet/orgs","repos_url":"https://api.github.com/users/wmvanvliet/repos","events_url":"https://api.github.com/users/wmvanvliet/events{/privacy}","received_events_url":"https://api.github.com/users/wmvanvliet/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/wmvanvliet/mne-python","description":"MNE : Magnetoencephalography (MEG) and Electroencephalography (EEG) in Python","fork":true,"url":"https://api.github.com/repos/wmvanvliet/mne-python","forks_url":"https://api.github.com/repos/wmvanvliet/mne-python/forks","keys_url":"https://api.github.com/repos/wmvanvliet/mne-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wmvanvliet/mne-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wmvanvliet/mne-python/teams","hooks_url":"https://api.github.com/repos/wmvanvliet/mne-python/hooks","issue_events_url":"https://api.github.com/repos/wmvanvliet/mne-python/issues/events{/number}","events_url":"https://api.github.com/repos/wmvanvliet/mne-python/events","assignees_url":"https://api.github.com/repos/wmvanvliet/mne-python/assignees{/user}","branches_url":"https://api.github.com/repos/wmvanvliet/mne-python/branches{/branch}","tags_url":"https://api.github.com/repos/wmvanvliet/mne-python/tags","blobs_url":"https://api.github.com/repos/wmvanvliet/mne-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wmvanvliet/mne-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wmvanvliet/mne-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/wmvanvliet/mne-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wmvanvliet/mne-python/statuses/{sha}","languages_url":"https://api.github.com/repos/wmvanvliet/mne-python/languages","stargazers_url":"https://api.github.com/repos/wmvanvliet/mne-python/stargazers","contributors_url":"https://api.github.com/repos/wmvanvliet/mne-python/contributors","subscribers_url":"https://api.github.com/repos/wmvanvliet/mne-python/subscribers","subscription_url":"https://api.github.com/repos/wmvanvliet/mne-python/subscription","commits_url":"https://api.github.com/repos/wmvanvliet/mne-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/wmvanvliet/mne-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/wmvanvliet/mne-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/wmvanvliet/mne-python/issues/comments{/number}","contents_url":"https://api.github.com/repos/wmvanvliet/mne-python/contents/{+path}","compare_url":"https://api.github.com/repos/wmvanvliet/mne-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wmvanvliet/mne-python/merges","archive_url":"https://api.github.com/repos/wmvanvliet/mne-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wmvanvliet/mne-python/downloads","issues_url":"https://api.github.com/repos/wmvanvliet/mne-python/issues{/number}","pulls_url":"https://api.github.com/repos/wmvanvliet/mne-python/pulls{/number}","milestones_url":"https://api.github.com/repos/wmvanvliet/mne-python/milestones{/number}","notifications_url":"https://api.github.com/repos/wmvanvliet/mne-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wmvanvliet/mne-python/labels{/name}","releases_url":"https://api.github.com/repos/wmvanvliet/mne-python/releases{/id}","deployments_url":"https://api.github.com/repos/wmvanvliet/mne-python/deployments","created_at":"2014-08-29T08:06:25Z","updated_at":"2016-11-08T12:26:26Z","pushed_at":"2018-03-15T15:22:11Z","git_url":"git://github.com/wmvanvliet/mne-python.git","ssh_url":"git@github.com:wmvanvliet/mne-python.git","clone_url":"https://github.com/wmvanvliet/mne-python.git","svn_url":"https://github.com/wmvanvliet/mne-python","homepage":"http://martinos.org/mne/","size":98420,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":1,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"mne-tools:master","ref":"master","sha":"e85df44c0636ab0910e4de1de4f49700b68efcb5","user":{"login":"mne-tools","id":583875,"avatar_url":"https://avatars3.githubusercontent.com/u/583875?v=4","gravatar_id":"","url":"https://api.github.com/users/mne-tools","html_url":"https://github.com/mne-tools","followers_url":"https://api.github.com/users/mne-tools/followers","following_url":"https://api.github.com/users/mne-tools/following{/other_user}","gists_url":"https://api.github.com/users/mne-tools/gists{/gist_id}","starred_url":"https://api.github.com/users/mne-tools/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mne-tools/subscriptions","organizations_url":"https://api.github.com/users/mne-tools/orgs","repos_url":"https://api.github.com/users/mne-tools/repos","events_url":"https://api.github.com/users/mne-tools/events{/privacy}","received_events_url":"https://api.github.com/users/mne-tools/received_events","type":"Organization","site_admin":false},"repo":{"id":1301584,"name":"mne-python","full_name":"mne-tools/mne-python","owner":{"login":"mne-tools","id":583875,"avatar_url":"https://avatars3.githubusercontent.com/u/583875?v=4","gravatar_id":"","url":"https://api.github.com/users/mne-tools","html_url":"https://github.com/mne-tools","followers_url":"https://api.github.com/users/mne-tools/followers","following_url":"https://api.github.com/users/mne-tools/following{/other_user}","gists_url":"https://api.github.com/users/mne-tools/gists{/gist_id}","starred_url":"https://api.github.com/users/mne-tools/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mne-tools/subscriptions","organizations_url":"https://api.github.com/users/mne-tools/orgs","repos_url":"https://api.github.com/users/mne-tools/repos","events_url":"https://api.github.com/users/mne-tools/events{/privacy}","received_events_url":"https://api.github.com/users/mne-tools/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mne-tools/mne-python","description":"MNE : Magnetoencephalography (MEG) and Electroencephalography (EEG) in Python","fork":false,"url":"https://api.github.com/repos/mne-tools/mne-python","forks_url":"https://api.github.com/repos/mne-tools/mne-python/forks","keys_url":"https://api.github.com/repos/mne-tools/mne-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mne-tools/mne-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mne-tools/mne-python/teams","hooks_url":"https://api.github.com/repos/mne-tools/mne-python/hooks","issue_events_url":"https://api.github.com/repos/mne-tools/mne-python/issues/events{/number}","events_url":"https://api.github.com/repos/mne-tools/mne-python/events","assignees_url":"https://api.github.com/repos/mne-tools/mne-python/assignees{/user}","branches_url":"https://api.github.com/repos/mne-tools/mne-python/branches{/branch}","tags_url":"https://api.github.com/repos/mne-tools/mne-python/tags","blobs_url":"https://api.github.com/repos/mne-tools/mne-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mne-tools/mne-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mne-tools/mne-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/mne-tools/mne-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mne-tools/mne-python/statuses/{sha}","languages_url":"https://api.github.com/repos/mne-tools/mne-python/languages","stargazers_url":"https://api.github.com/repos/mne-tools/mne-python/stargazers","contributors_url":"https://api.github.com/repos/mne-tools/mne-python/contributors","subscribers_url":"https://api.github.com/repos/mne-tools/mne-python/subscribers","subscription_url":"https://api.github.com/repos/mne-tools/mne-python/subscription","commits_url":"https://api.github.com/repos/mne-tools/mne-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/mne-tools/mne-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/mne-tools/mne-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/mne-tools/mne-python/issues/comments{/number}","contents_url":"https://api.github.com/repos/mne-tools/mne-python/contents/{+path}","compare_url":"https://api.github.com/repos/mne-tools/mne-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mne-tools/mne-python/merges","archive_url":"https://api.github.com/repos/mne-tools/mne-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mne-tools/mne-python/downloads","issues_url":"https://api.github.com/repos/mne-tools/mne-python/issues{/number}","pulls_url":"https://api.github.com/repos/mne-tools/mne-python/pulls{/number}","milestones_url":"https://api.github.com/repos/mne-tools/mne-python/milestones{/number}","notifications_url":"https://api.github.com/repos/mne-tools/mne-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mne-tools/mne-python/labels{/name}","releases_url":"https://api.github.com/repos/mne-tools/mne-python/releases{/id}","deployments_url":"https://api.github.com/repos/mne-tools/mne-python/deployments","created_at":"2011-01-28T03:31:13Z","updated_at":"2018-03-15T19:10:47Z","pushed_at":"2018-03-15T15:28:30Z","git_url":"git://github.com/mne-tools/mne-python.git","ssh_url":"git@github.com:mne-tools/mne-python.git","clone_url":"https://github.com/mne-tools/mne-python.git","svn_url":"https://github.com/mne-tools/mne-python","homepage":"http://martinos.org/mne/","size":98417,"stargazers_count":425,"watchers_count":425,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":380,"mirror_url":null,"archived":false,"open_issues_count":274,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":380,"open_issues":274,"watchers":425,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mne-tools/mne-python/pulls/5021"},"html":{"href":"https://github.com/mne-tools/mne-python/pull/5021"},"issue":{"href":"https://api.github.com/repos/mne-tools/mne-python/issues/5021"},"comments":{"href":"https://api.github.com/repos/mne-tools/mne-python/issues/5021/comments"},"review_comments":{"href":"https://api.github.com/repos/mne-tools/mne-python/pulls/5021/comments"},"review_comment":{"href":"https://api.github.com/repos/mne-tools/mne-python/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mne-tools/mne-python/pulls/5021/commits"},"statuses":{"href":"https://api.github.com/repos/mne-tools/mne-python/statuses/391f02860d8fd81d5d29c223589d3df37f2dce53"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"agramfort"}}