{"action":"created","comment":{"url":"https://api.github.com/repos/mne-tools/mne-python/pulls/comments/71057181","id":71057181,"diff_hunk":"@@ -1,266 +1,332 @@\n-\"\"\"Xdawn implementation.\"\"\"\n # Authors: Alexandre Barachant <alexandre.barachant@gmail.com>\n+#          Asish Panda <asishrocks95@gmail.com>\n+#          Jean-Remi King <jeanremi.king@gmail.com>\n #\n # License: BSD (3-clause)\n \n-import copy as cp\n-\n import numpy as np\n from scipy import linalg\n+from ..cov import Covariance, _regularized_covariance\n+from ..decoding import TransformerMixin, BaseEstimator\n \n-from ..io.base import _BaseRaw\n-from ..epochs import _BaseEpochs\n-from .. import Covariance, EvokedArray, Evoked, EpochsArray\n-from ..io.pick import pick_types\n-from .ica import _get_fast_dot\n-from ..utils import logger\n-from ..cov import _regularized_covariance\n-from ..channels.channels import ContainsMixin\n \n+def _construct_signal_from_epochs(epochs, events, sfreq, tmin):\n+    \"\"\"Reconstruct pseudo continuous signal from epochs.\"\"\"\n+    n_epochs, n_channels, n_times = epochs.shape\n+    tmax = tmin + n_times / float(sfreq)\n+    start = (np.min(events[:, 0]) + int(tmin * sfreq))\n+    stop = (np.max(events[:, 0]) + int(tmax * sfreq) + 1)\n+\n+    n_samples = stop - start\n+    n_epochs, n_channels, n_times = epochs.shape\n+    events_pos = events[:, 0] - events[0, 0]\n+\n+    raw = np.zeros((n_channels, n_samples))\n+    for idx in range(n_epochs):\n+        onset = events_pos[idx]\n+        offset = onset + n_times\n+        raw[:, onset:offset] = epochs[idx]\n+\n+    return raw\n \n-def _least_square_evoked(data, events, event_id, tmin, tmax, sfreq):\n-    \"\"\"Least square estimation of evoked response from data.\n+\n+def _least_square_evoked(epochs, events, tmin, sfreq):\n+    \"\"\"Least square estimation of evoked response from epochs.\n \n     Parameters\n     ----------\n-    data : ndarray, shape (n_channels, n_times)\n-        The data to estimates evoked\n-    events : ndarray, shape (n_events, 3)\n+    epochs : array, shape (n_channels, n_times)\n+        The epochs data to estimate evoked.\n+    events : array, shape (n_events, 3)\n         The events typically returned by the read_events function.\n         If some events don't match the events of interest as specified\n         by event_id, they will be ignored.\n-    event_id : dict\n-        The id of the events to consider\n     tmin : float\n         Start time before event.\n-    tmax : float\n-        End time after event.\n     sfreq : float\n         Sampling frequency.\n \n     Returns\n     -------\n-    evokeds_data : dict of ndarray\n-        A dict of evoked data for each event type in event_id.\n-    toeplitz : dict of ndarray\n-        A dict of toeplitz matrix for each event type in event_id.\n+    evokeds_data : array, shape (n_class * n_components, n_channels)\n+        An concatenated array of evoked data for each event type.\n+    toeplitz : array, shape (n_class * n_components, n_channels)\n+        An concatenated array of toeplitz matrix for each event type.\n     \"\"\"\n-    nmin = int(tmin * sfreq)\n-    nmax = int(tmax * sfreq)\n-\n-    window = nmax - nmin\n-    n_samples = data.shape[1]\n-    toeplitz_mat = dict()\n-    full_toep = list()\n-    for eid in event_id:\n+\n+    n_epochs, n_channels, n_times = epochs.shape\n+    tmax = tmin + n_times / float(sfreq)\n+\n+    # Deal with shuffled epochs\n+    events = events.copy()\n+    events[:, 0] -= events[0, 0] + int(tmin * sfreq)\n+\n+    # Contruct raw signal\n+    raw = _construct_signal_from_epochs(epochs, events, sfreq, tmin)\n+\n+    # Compute average evoked\n+    n_min, n_max = int(tmin * sfreq), int(tmax * sfreq)\n+    window = n_max - n_min\n+    n_samples = raw.shape[1]\n+    toeplitz_mat = list()\n+    classes = np.unique(events[:, 2])\n+    for ii, this_class in enumerate(classes):\n         # select events by type\n-        ix_ev = events[:, -1] == event_id[eid]\n+        sel = events[:, 2] == this_class\n \n         # build toeplitz matrix\n         trig = np.zeros((n_samples, 1))\n-        ix_trig = (events[ix_ev, 0]) + nmin\n+        ix_trig = (events[sel, 0]) + n_min\n         trig[ix_trig] = 1\n-        toep_mat = linalg.toeplitz(trig[0:window], trig)\n-        toeplitz_mat[eid] = toep_mat\n-        full_toep.append(toep_mat)\n+        toeplitz_mat.append(linalg.toeplitz(trig[0:window], trig))\n \n     # Concatenate toeplitz\n-    full_toep = np.concatenate(full_toep)\n+    toeplitz_mat = np.array(toeplitz_mat)\n+    full_toep = np.concatenate(toeplitz_mat)\n \n     # least square estimation\n     predictor = np.dot(linalg.pinv(np.dot(full_toep, full_toep.T)), full_toep)\n-    all_evokeds = np.dot(predictor, data.T)\n-    all_evokeds = np.vsplit(all_evokeds, len(event_id))\n+    all_evokeds = np.dot(predictor, raw.T)\n+    all_evokeds = np.transpose(np.vsplit(all_evokeds, len(classes)), (0, 2, 1))\n \n-    # parse evoked response\n-    evoked_data = dict()\n-    for idx, eid in enumerate(event_id):\n-        evoked_data[eid] = all_evokeds[idx].T\n+    return all_evokeds, toeplitz_mat\n \n-    return evoked_data, toeplitz_mat\n \n+def _fit_xdawn(epochs, y, n_components, reg=None, signal_cov=None,\n+               events=None, tmin=0., sfreq=1.):\n+    \"\"\"Fit filters and coefs using Xdawn Algorithm.\n \n-def _check_overlapp(epochs):\n-    \"\"\"check if events are overlapped.\"\"\"\n-    isi = np.diff(epochs.events[:, 0])\n-    window = int((epochs.tmax - epochs.tmin) * epochs.info['sfreq'])\n-    # Events are overlapped if the minimal inter-stimulus interval is smaller\n-    # than the time window.\n-    return isi.min() < window\n+    Xdawn is a spatial filtering method designed to improve the signal\n+    to signal + noise ratio (SSNR) of the event related responses. Xdawn was\n+    originaly designed for P300 evoked potential by enhancing the target\n+    response with respect to the non-target response. This implementation is a\n+    generalization to any type of event related response.\n \n+    Parameters\n+    ----------\n+    epochs : array, shape (n_epochs, n_channels, n_times)\n+        The epochs data.\n+    y : array, shape (n_epochs)\n+        The epochs class.\n+    n_components : int (default 2)\n+        The number of components to decompose the signals signals.\n+    reg : float | str | None (default None)\n+        If not None, allow regularization for covariance estimation\n+        if float, shrinkage covariance is used (0 <= shrinkage <= 1).\n+        if str, optimal shrinkage using Ledoit-Wolf Shrinkage ('ledoit_wolf')\n+        or Oracle Approximating Shrinkage ('oas').\n+    signal_cov : None | Covariance | array, shape (n_channels, n_channels)\n+        The signal covariance used for whitening of the data.\n+        if None, the covariance is estimated from the epochs signal.\n+    events : array, shape (n_epochs, 3)\n+        The epochs events, used to correct for epochs overlap.\n+    tmin : float\n+        Epochs starting time. Only used if events is passed to correct for\n+        epochs overlap.\n+    sfreq : float\n+        Sampling frequency.  Only used if events is passed to correct for\n+        epochs overlap.\n \n-def _construct_signal_from_epochs(events, sfreq, tmin, tmax, epochs_data):\n-    \"\"\"Reconstruct pseudo continuous signal from epochs.\"\"\"\n-    start = (np.min(events[:, 0]) + int(tmin * sfreq))\n-    stop = (np.max(events[:, 0]) + int(tmax * sfreq) + 1)\n \n-    n_samples = stop - start\n-    n_epochs, n_channels, n_times = epochs_data.shape\n-    events_pos = events[:, 0] - events[0, 0]\n+    Attributes\n+    ----------\n+    filters_ : array, shape (n_channels, n_channels)\n+        The Xdawn components used to decompose the data for each event type.\n+    patterns_ : array, shape (n_channels, n_channels)\n+        The Xdawn patterns used to restore the signals for each event type.\n \n-    data = np.zeros((n_channels, n_samples))\n-    for idx in range(n_epochs):\n-        onset = events_pos[idx]\n-        offset = onset + n_times\n-        data[:, onset:offset] = epochs_data[idx]\n+    References\n+    ----------\n+    [1] Rivet, B., Souloumiac, A., Attina, V., & Gibert, G. (2009). xDAWN\n+    algorithm to enhance evoked potentials: application to brain-computer\n+    interface. Biomedical Engineering, IEEE Transactions on, 56(8), 2035-2043.\n+    [2] Rivet, B., Cecotti, H., Souloumiac, A., Maby, E., & Mattout, J. (2011,\n+    August). Theoretical analysis of xDAWN algorithm: application to an\n+    efficient sensor selection in a P300 BCI. In Signal Processing Conference,\n+    2011 19th European (pp. 1382-1386). IEEE.\n \n-    return data\n \n+    See Also\n+    --------\n+    CSP\n+    \"\"\"\n+    n_epochs, n_channels, n_times = epochs.shape\n+\n+    classes = np.unique(y)\n+\n+    # Retrieve or compute whitening covariance\n+    if signal_cov is None:\n+        signal_cov = _regularized_covariance(np.hstack(epochs), reg)\n+    elif isinstance(signal_cov, Covariance):\n+        signal_cov = signal_cov.data\n+    if not isinstance(signal_cov, np.ndarray) or (\n+            not np.array_equal(signal_cov.shape, np.tile(epochs.shape[1], 2))):\n+        raise ValueError('signal_cov must be None, a covariance instance '\n+                         'or a array of shape (n_chans, n_chans)')\n+\n+    # Get prototype events\n+    if events is not None:\n+        evokeds, toeplitzs = _least_square_evoked(epochs, events, tmin, sfreq)","path":"mne/preprocessing/xdawn.py","position":234,"original_position":234,"commit_id":"14a1f4db781f2b1a44e7ccf7afa382db5953d729","original_commit_id":"14a1f4db781f2b1a44e7ccf7afa382db5953d729","user":{"login":"jona-sassenhagen","id":4321826,"avatar_url":"https://avatars.githubusercontent.com/u/4321826?v=3","gravatar_id":"","url":"https://api.github.com/users/jona-sassenhagen","html_url":"https://github.com/jona-sassenhagen","followers_url":"https://api.github.com/users/jona-sassenhagen/followers","following_url":"https://api.github.com/users/jona-sassenhagen/following{/other_user}","gists_url":"https://api.github.com/users/jona-sassenhagen/gists{/gist_id}","starred_url":"https://api.github.com/users/jona-sassenhagen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jona-sassenhagen/subscriptions","organizations_url":"https://api.github.com/users/jona-sassenhagen/orgs","repos_url":"https://api.github.com/users/jona-sassenhagen/repos","events_url":"https://api.github.com/users/jona-sassenhagen/events{/privacy}","received_events_url":"https://api.github.com/users/jona-sassenhagen/received_events","type":"User","site_admin":false},"body":"Btw this (that is, `_least_square_evoked`) is where an encoder model backbone would fit in.\r\n`toeplitz` is an encoder's X, `evokeds` are the coefs of the fitted model/the estimated rERPs.\r\n\r\n(As @alexandrebarachant has noted a few times, originally, XDawn is applied to continuous data, and this internally re-creates the continuous data.)","created_at":"2016-07-16T00:43:36Z","updated_at":"2016-07-16T00:43:36Z","html_url":"https://github.com/mne-tools/mne-python/pull/3425#discussion_r71057181","pull_request_url":"https://api.github.com/repos/mne-tools/mne-python/pulls/3425","_links":{"self":{"href":"https://api.github.com/repos/mne-tools/mne-python/pulls/comments/71057181"},"html":{"href":"https://github.com/mne-tools/mne-python/pull/3425#discussion_r71057181"},"pull_request":{"href":"https://api.github.com/repos/mne-tools/mne-python/pulls/3425"}}},"pull_request":{"url":"https://api.github.com/repos/mne-tools/mne-python/pulls/3425","id":77690749,"html_url":"https://github.com/mne-tools/mne-python/pull/3425","diff_url":"https://github.com/mne-tools/mne-python/pull/3425.diff","patch_url":"https://github.com/mne-tools/mne-python/pull/3425.patch","issue_url":"https://api.github.com/repos/mne-tools/mne-python/issues/3425","number":3425,"state":"open","locked":false,"title":"Refactor: Xdawn","user":{"login":"kingjr","id":4881164,"avatar_url":"https://avatars.githubusercontent.com/u/4881164?v=3","gravatar_id":"","url":"https://api.github.com/users/kingjr","html_url":"https://github.com/kingjr","followers_url":"https://api.github.com/users/kingjr/followers","following_url":"https://api.github.com/users/kingjr/following{/other_user}","gists_url":"https://api.github.com/users/kingjr/gists{/gist_id}","starred_url":"https://api.github.com/users/kingjr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kingjr/subscriptions","organizations_url":"https://api.github.com/users/kingjr/orgs","repos_url":"https://api.github.com/users/kingjr/repos","events_url":"https://api.github.com/users/kingjr/events{/privacy}","received_events_url":"https://api.github.com/users/kingjr/received_events","type":"User","site_admin":false},"body":"## Fixes\r\n* weird channels picking\r\n* unstable unit test\r\n\r\n## Update example\r\n* use XdawnTransformer Object\r\n* use `inverse_transform` method\r\n* use train and test set\r\n\r\n## Enhancement\r\n* allow overlapping events sin new `XdawnTransformer`\r\n* add `xdawn_fit` private function for more explicit args.\r\n\r\n## API:\r\n* new `XdawnTransformer` devoid of any fancy objects (Evoked / dictionary etc), and only uses numpy\r\n* Deprecates high level `mne.preprocessing.Xdawn`\r\n\r\ncc @kaichogami @alexandrebarachant @dengemann ","created_at":"2016-07-15T23:15:08Z","updated_at":"2016-07-16T00:43:36Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ee29c1acaa2157d967361d6c04bb3618022fcfb0","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/mne-tools/mne-python/pulls/3425/commits","review_comments_url":"https://api.github.com/repos/mne-tools/mne-python/pulls/3425/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/3425/comments","statuses_url":"https://api.github.com/repos/mne-tools/mne-python/statuses/14a1f4db781f2b1a44e7ccf7afa382db5953d729","head":{"label":"kingjr:xdawn_clean","ref":"xdawn_clean","sha":"14a1f4db781f2b1a44e7ccf7afa382db5953d729","user":{"login":"kingjr","id":4881164,"avatar_url":"https://avatars.githubusercontent.com/u/4881164?v=3","gravatar_id":"","url":"https://api.github.com/users/kingjr","html_url":"https://github.com/kingjr","followers_url":"https://api.github.com/users/kingjr/followers","following_url":"https://api.github.com/users/kingjr/following{/other_user}","gists_url":"https://api.github.com/users/kingjr/gists{/gist_id}","starred_url":"https://api.github.com/users/kingjr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kingjr/subscriptions","organizations_url":"https://api.github.com/users/kingjr/orgs","repos_url":"https://api.github.com/users/kingjr/repos","events_url":"https://api.github.com/users/kingjr/events{/privacy}","received_events_url":"https://api.github.com/users/kingjr/received_events","type":"User","site_admin":false},"repo":{"id":19731468,"name":"mne-python","full_name":"kingjr/mne-python","owner":{"login":"kingjr","id":4881164,"avatar_url":"https://avatars.githubusercontent.com/u/4881164?v=3","gravatar_id":"","url":"https://api.github.com/users/kingjr","html_url":"https://github.com/kingjr","followers_url":"https://api.github.com/users/kingjr/followers","following_url":"https://api.github.com/users/kingjr/following{/other_user}","gists_url":"https://api.github.com/users/kingjr/gists{/gist_id}","starred_url":"https://api.github.com/users/kingjr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kingjr/subscriptions","organizations_url":"https://api.github.com/users/kingjr/orgs","repos_url":"https://api.github.com/users/kingjr/repos","events_url":"https://api.github.com/users/kingjr/events{/privacy}","received_events_url":"https://api.github.com/users/kingjr/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/kingjr/mne-python","description":"MNE : Magnetoencephalography (MEG) and Electroencephalography (EEG) in Python","fork":true,"url":"https://api.github.com/repos/kingjr/mne-python","forks_url":"https://api.github.com/repos/kingjr/mne-python/forks","keys_url":"https://api.github.com/repos/kingjr/mne-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kingjr/mne-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kingjr/mne-python/teams","hooks_url":"https://api.github.com/repos/kingjr/mne-python/hooks","issue_events_url":"https://api.github.com/repos/kingjr/mne-python/issues/events{/number}","events_url":"https://api.github.com/repos/kingjr/mne-python/events","assignees_url":"https://api.github.com/repos/kingjr/mne-python/assignees{/user}","branches_url":"https://api.github.com/repos/kingjr/mne-python/branches{/branch}","tags_url":"https://api.github.com/repos/kingjr/mne-python/tags","blobs_url":"https://api.github.com/repos/kingjr/mne-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kingjr/mne-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kingjr/mne-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/kingjr/mne-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kingjr/mne-python/statuses/{sha}","languages_url":"https://api.github.com/repos/kingjr/mne-python/languages","stargazers_url":"https://api.github.com/repos/kingjr/mne-python/stargazers","contributors_url":"https://api.github.com/repos/kingjr/mne-python/contributors","subscribers_url":"https://api.github.com/repos/kingjr/mne-python/subscribers","subscription_url":"https://api.github.com/repos/kingjr/mne-python/subscription","commits_url":"https://api.github.com/repos/kingjr/mne-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/kingjr/mne-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/kingjr/mne-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/kingjr/mne-python/issues/comments{/number}","contents_url":"https://api.github.com/repos/kingjr/mne-python/contents/{+path}","compare_url":"https://api.github.com/repos/kingjr/mne-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kingjr/mne-python/merges","archive_url":"https://api.github.com/repos/kingjr/mne-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kingjr/mne-python/downloads","issues_url":"https://api.github.com/repos/kingjr/mne-python/issues{/number}","pulls_url":"https://api.github.com/repos/kingjr/mne-python/pulls{/number}","milestones_url":"https://api.github.com/repos/kingjr/mne-python/milestones{/number}","notifications_url":"https://api.github.com/repos/kingjr/mne-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kingjr/mne-python/labels{/name}","releases_url":"https://api.github.com/repos/kingjr/mne-python/releases{/id}","deployments_url":"https://api.github.com/repos/kingjr/mne-python/deployments","created_at":"2014-05-13T08:28:44Z","updated_at":"2014-06-02T12:58:51Z","pushed_at":"2016-07-16T00:19:14Z","git_url":"git://github.com/kingjr/mne-python.git","ssh_url":"git@github.com:kingjr/mne-python.git","clone_url":"https://github.com/kingjr/mne-python.git","svn_url":"https://github.com/kingjr/mne-python","homepage":"http://martinos.org/mne/","size":87812,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"mne-tools:master","ref":"master","sha":"3efd6f8b411571c481f45d03028c6fb9b83d43b1","user":{"login":"mne-tools","id":583875,"avatar_url":"https://avatars.githubusercontent.com/u/583875?v=3","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://avatars.githubusercontent.com/u/583875?v=3","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":"2016-07-13T13:08:57Z","pushed_at":"2016-07-16T00:19:15Z","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":179747,"stargazers_count":215,"watchers_count":215,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":205,"mirror_url":null,"open_issues_count":192,"forks":205,"open_issues":192,"watchers":215,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mne-tools/mne-python/pulls/3425"},"html":{"href":"https://github.com/mne-tools/mne-python/pull/3425"},"issue":{"href":"https://api.github.com/repos/mne-tools/mne-python/issues/3425"},"comments":{"href":"https://api.github.com/repos/mne-tools/mne-python/issues/3425/comments"},"review_comments":{"href":"https://api.github.com/repos/mne-tools/mne-python/pulls/3425/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/3425/commits"},"statuses":{"href":"https://api.github.com/repos/mne-tools/mne-python/statuses/14a1f4db781f2b1a44e7ccf7afa382db5953d729"}}}}
{"actor":{"display_login":"jona-sassenhagen"}}