{"action":"created","comment":{"url":"https://api.github.com/repos/mne-tools/mne-python/pulls/comments/34899078","id":34899078,"diff_hunk":"@@ -973,45 +990,72 @@ def resample(self, sfreq, npad=100, window='boxcar',\n         \"\"\"\n         if not self.preload:\n             raise RuntimeError('Can only resample preloaded data')\n+\n+        inst = self.copy() if copy else self\n+\n+        if events is None:\n+            # No event object supplied. Perform some basic detection of\n+            # dropped events anyway\n+            original_events = find_events(inst)\n+\n         sfreq = float(sfreq)\n-        o_sfreq = float(self.info['sfreq'])\n+        o_sfreq = float(inst.info['sfreq'])\n \n-        offsets = np.concatenate(([0], np.cumsum(self._raw_lengths)))\n+        offsets = np.concatenate(([0], np.cumsum(inst._raw_lengths)))\n         new_data = list()\n+\n+        ratio = sfreq / o_sfreq\n+\n         # set up stim channel processing\n         if stim_picks is None:\n-            stim_picks = pick_types(self.info, meg=False, ref_meg=False,\n+            stim_picks = pick_types(inst.info, meg=False, ref_meg=False,\n                                     stim=True, exclude=[])\n         stim_picks = np.asanyarray(stim_picks)\n-        ratio = sfreq / o_sfreq\n-        for ri in range(len(self._raw_lengths)):\n-            data_chunk = self._data[:, offsets[ri]:offsets[ri + 1]]\n+\n+        for ri in range(len(inst._raw_lengths)):\n+            data_chunk = inst._data[:, offsets[ri]:offsets[ri + 1]]\n             new_data.append(resample(data_chunk, sfreq, o_sfreq, npad,\n                                      n_jobs=n_jobs))\n             new_ntimes = new_data[ri].shape[1]\n \n-            # Now deal with the stim channels. In empirical testing, it was\n-            # faster to resample all channels (above) and then replace the\n-            # stim channels than it was to only resample the proper subset\n-            # of channels and then use np.insert() to restore the stims\n-\n-            # figure out which points in old data to subsample\n-            # protect against out-of-bounds, which can happen (having\n-            # one sample more than expected) due to padding\n-            stim_inds = np.minimum(np.floor(np.arange(new_ntimes) /\n-                                            ratio).astype(int),\n-                                   data_chunk.shape[1] - 1)\n-            for sp in stim_picks:\n-                new_data[ri][sp] = data_chunk[[sp]][:, stim_inds]\n-\n-            self._first_samps[ri] = int(self._first_samps[ri] * ratio)\n-            self._last_samps[ri] = self._first_samps[ri] + new_ntimes - 1\n-            self._raw_lengths[ri] = new_ntimes\n-\n-        # adjust affected variables\n-        self._data = np.concatenate(new_data, axis=1)\n-        self.info['sfreq'] = sfreq\n-        self._update_times()\n+            # In empirical testing, it was faster to resample all channels\n+            # (above) and then replace the stim channels than it was to only\n+            # resample the proper subset of channels and then use np.insert()\n+            # to restore the stims.\n+            stim_resampled = _resample_stim_channels(\n+                data_chunk[stim_picks], new_data[ri].shape[1],\n+                data_chunk.shape[1])\n+            new_data[ri][stim_picks] = stim_resampled\n+\n+            inst._first_samps[ri] = int(inst._first_samps[ri] * ratio)\n+            inst._last_samps[ri] = inst._first_samps[ri] + new_ntimes - 1\n+            inst._raw_lengths[ri] = new_ntimes\n+\n+        inst._data = np.concatenate(new_data, axis=1)\n+        inst.info['sfreq'] = sfreq\n+        inst._update_times()\n+\n+        if events is None:\n+            # Did we loose events?\n+            resampled_events = find_events(inst)\n+            if len(resampled_events) != len(original_events):\n+                warnings.warn(\n+                    'Resampling of the stim channels caused event '\n+                    'information to become unreliable. Consider finding '\n+                    'events on the original data and passing the event '\n+                    'matrix as a parameter.'\n+                )\n+\n+            return inst\n+        else:\n+            if copy:\n+                events = events.copy()\n+\n+            events[:, 0] = np.minimum(\n+                np.round(events[:, 0] * ratio).astype(int),\n+                inst._data.shape[1]","path":"mne/io/base.py","position":170,"original_position":170,"commit_id":"aca3d345e6598e10b1352c7ccc947bb4901eaf97","original_commit_id":"aca3d345e6598e10b1352c7ccc947bb4901eaf97","user":{"login":"Eric89GXL","id":2365790,"avatar_url":"https://avatars.githubusercontent.com/u/2365790?v=3","gravatar_id":"","url":"https://api.github.com/users/Eric89GXL","html_url":"https://github.com/Eric89GXL","followers_url":"https://api.github.com/users/Eric89GXL/followers","following_url":"https://api.github.com/users/Eric89GXL/following{/other_user}","gists_url":"https://api.github.com/users/Eric89GXL/gists{/gist_id}","starred_url":"https://api.github.com/users/Eric89GXL/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Eric89GXL/subscriptions","organizations_url":"https://api.github.com/users/Eric89GXL/orgs","repos_url":"https://api.github.com/users/Eric89GXL/repos","events_url":"https://api.github.com/users/Eric89GXL/events{/privacy}","received_events_url":"https://api.github.com/users/Eric89GXL/received_events","type":"User","site_admin":false},"body":"the round could move you outside the bounds I think\r\n\r\nin terms of not being just `min` it's because it's an array that's being operated on","created_at":"2015-07-17T15:17:58Z","updated_at":"2015-07-17T15:17:58Z","html_url":"https://github.com/mne-tools/mne-python/pull/2298#discussion_r34899078","pull_request_url":"https://api.github.com/repos/mne-tools/mne-python/pulls/2298","_links":{"self":{"href":"https://api.github.com/repos/mne-tools/mne-python/pulls/comments/34899078"},"html":{"href":"https://github.com/mne-tools/mne-python/pull/2298#discussion_r34899078"},"pull_request":{"href":"https://api.github.com/repos/mne-tools/mne-python/pulls/2298"}}},"pull_request":{"url":"https://api.github.com/repos/mne-tools/mne-python/pulls/2298","id":39945786,"html_url":"https://github.com/mne-tools/mne-python/pull/2298","diff_url":"https://github.com/mne-tools/mne-python/pull/2298.diff","patch_url":"https://github.com/mne-tools/mne-python/pull/2298.patch","issue_url":"https://api.github.com/repos/mne-tools/mne-python/issues/2298","number":2298,"state":"open","locked":false,"title":"MRG: Resampling without losing events","user":{"login":"wmvanvliet","id":428273,"avatar_url":"https://avatars.githubusercontent.com/u/428273?v=3","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":"Resampling the stim channel is a tricky business. If you are not\r\ncareful, you might lose events.\r\n\r\nConsider the following stim data, all zeros with two event onsets:\r\n\r\n      y = [0, 0, 1, 0, 0, 0, 0, 1, 0, 0]\r\n\r\nIf we naively downsample by a factor of 2, this becomes:\r\n\r\n     y = [0, 1, 0, 0, 0]\r\n\r\nwhoops, event lost. In the current implementation, no warning is given whatsoever.\r\n\r\nThis commit first extracts the onsets on which the stim signal changes:\r\n\r\n     onsets = [0, 2, 3, 6, 7]\r\n\r\nresample those:\r\n\r\n    onsets = [0, 1, 1, 3, 3]\r\n\r\nnudge overlapping onsets (by default by maximally 1 sample, but this can be changed):\r\n\r\n    onsets = [0, 1, 2, 3, 4]\r\n\r\nand reconstruct the resampled stim data:\r\n\r\n    y = [0, 1, 0, 1, 0]\r\n\r\nno events lost!\r\n\r\nIf events get delayed too much or fall out of bounds, it fails loud.","created_at":"2015-07-14T18:20:03Z","updated_at":"2015-07-17T15:17:58Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9252c3f5cd195c288133bbbd13620d0ccc0f4427","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/mne-tools/mne-python/pulls/2298/commits","review_comments_url":"https://api.github.com/repos/mne-tools/mne-python/pulls/2298/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/2298/comments","statuses_url":"https://api.github.com/repos/mne-tools/mne-python/statuses/aca3d345e6598e10b1352c7ccc947bb4901eaf97","head":{"label":"wmvanvliet:resample_stim","ref":"resample_stim","sha":"aca3d345e6598e10b1352c7ccc947bb4901eaf97","user":{"login":"wmvanvliet","id":428273,"avatar_url":"https://avatars.githubusercontent.com/u/428273?v=3","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://avatars.githubusercontent.com/u/428273?v=3","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}","created_at":"2014-08-29T08:06:25Z","updated_at":"2015-05-08T07:28:50Z","pushed_at":"2015-07-17T14:56:53Z","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":79788,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"mne-tools:master","ref":"master","sha":"c0859548280e37801d03dfa99e006e3187ea709b","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}","created_at":"2011-01-28T03:31:13Z","updated_at":"2015-07-10T19:14:50Z","pushed_at":"2015-07-17T15:10:21Z","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":182547,"stargazers_count":138,"watchers_count":138,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":130,"mirror_url":null,"open_issues_count":186,"forks":130,"open_issues":186,"watchers":138,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mne-tools/mne-python/pulls/2298"},"html":{"href":"https://github.com/mne-tools/mne-python/pull/2298"},"issue":{"href":"https://api.github.com/repos/mne-tools/mne-python/issues/2298"},"comments":{"href":"https://api.github.com/repos/mne-tools/mne-python/issues/2298/comments"},"review_comments":{"href":"https://api.github.com/repos/mne-tools/mne-python/pulls/2298/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/2298/commits"},"statuses":{"href":"https://api.github.com/repos/mne-tools/mne-python/statuses/aca3d345e6598e10b1352c7ccc947bb4901eaf97"}}}}