{"action":"created","comment":{"url":"https://api.github.com/repos/obspy/obspy/pulls/comments/36022382","id":36022382,"diff_hunk":"@@ -172,6 +173,255 @@ def weighted_average_slopes(data, old_start, old_dt, new_start, new_dt,\n     return return_data\n \n \n+# Map corresponding to the enum on the C side of things.\n+_LANCZOS_KERNEL_MAP = {\n+    \"lanczos\": 0,\n+    \"hanning\": 1,\n+    \"blackman\": 2\n+}\n+\n+\n+def lanczos_interpolation(data, old_start, old_dt, new_start, new_dt, new_npts,\n+                          a, window=\"lanczos\", *args, **kwargs):\n+    r\"\"\"\n+    Function performing Lanczos resampling, see\n+    http://en.wikipedia.org/wiki/Lanczos_resampling for details. Essentially a\n+    finite support version of sinc resampling (the ideal reconstruction\n+    filter). For large values of ``a`` it converges towards sinc resampling. If\n+    used for downsampling, make sure to apply a proper anti-aliasing lowpass\n+    filter first.\n+\n+    .. note::\n+\n+        In most cases you do not want to call this method directly but invoke\n+        it via either the :meth:`obspy.core.stream.Stream.interpolate` or the\n+        :meth:`obspy.core.trace.Trace.interpolate` method. These offer a nicer\n+        API that naturally integrates with the rest of ObsPy. Use\n+        ``method=\"lanczos\"`` to use this interpolation method. In that case the\n+        only additional parameters of interest are ``a`` and ``window``.\n+\n+    :type data: array_like\n+    :param data: Array to interpolate.\n+    :type old_start: float\n+    :param old_start: The start of the array as a number.\n+    :type old_start: float\n+    :param old_dt: The time delta of the current array.\n+    :type new_start: float\n+    :param new_start: The start of the interpolated array. Must be greater\n+        or equal to the current start of the array.\n+    :type new_dt: float\n+    :param new_dt: The desired new time delta.\n+    :type new_npts: int\n+    :param new_npts: The new number of samples.\n+    :type a: int\n+    :param a: The width of the window in samples on either side. Runtimes\n+        scales linearly with the value of ``a`` but the interpolation also get\n+        better.\n+    :type window: str\n+    :param window: The window used to multiply the sinc function with. One\n+        of ``\"lanczos\"``, ``\"hanning\"``, ``\"blackman\"``. The window determines\n+        the trade-off between \"sharpness\" and the amplitude of the wiggles in\n+        the pass and stop band. Please use the\n+        :func:`~obspy.signal.interpolation.plot_lanczos_windows` function to\n+        judge these for any given application.\n+\n+    Values of ``a`` >= 20 show good results even for data that has\n+    energy close to the Nyquist frequency. If your data is way oversampled","path":"obspy/signal/interpolation.py","position":74,"original_position":74,"commit_id":"f754a7e5b38b2d2300473cd764abd9693a8a160e","original_commit_id":"f754a7e5b38b2d2300473cd764abd9693a8a160e","user":{"login":"QuLogic","id":302469,"avatar_url":"https://avatars.githubusercontent.com/u/302469?v=3","gravatar_id":"","url":"https://api.github.com/users/QuLogic","html_url":"https://github.com/QuLogic","followers_url":"https://api.github.com/users/QuLogic/followers","following_url":"https://api.github.com/users/QuLogic/following{/other_user}","gists_url":"https://api.github.com/users/QuLogic/gists{/gist_id}","starred_url":"https://api.github.com/users/QuLogic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/QuLogic/subscriptions","organizations_url":"https://api.github.com/users/QuLogic/orgs","repos_url":"https://api.github.com/users/QuLogic/repos","events_url":"https://api.github.com/users/QuLogic/events{/privacy}","received_events_url":"https://api.github.com/users/QuLogic/received_events","type":"User","site_admin":false},"body":"`way` -> `extremely`","created_at":"2015-07-31T22:28:19Z","updated_at":"2015-07-31T22:28:19Z","html_url":"https://github.com/obspy/obspy/pull/1101#discussion_r36022382","pull_request_url":"https://api.github.com/repos/obspy/obspy/pulls/1101","_links":{"self":{"href":"https://api.github.com/repos/obspy/obspy/pulls/comments/36022382"},"html":{"href":"https://github.com/obspy/obspy/pull/1101#discussion_r36022382"},"pull_request":{"href":"https://api.github.com/repos/obspy/obspy/pulls/1101"}}},"pull_request":{"url":"https://api.github.com/repos/obspy/obspy/pulls/1101","id":41291755,"html_url":"https://github.com/obspy/obspy/pull/1101","diff_url":"https://github.com/obspy/obspy/pull/1101.diff","patch_url":"https://github.com/obspy/obspy/pull/1101.patch","issue_url":"https://api.github.com/repos/obspy/obspy/issues/1101","number":1101,"state":"open","locked":false,"title":"Lanczos Resampling/Interpolation","user":{"login":"krischer","id":800487,"avatar_url":"https://avatars.githubusercontent.com/u/800487?v=3","gravatar_id":"","url":"https://api.github.com/users/krischer","html_url":"https://github.com/krischer","followers_url":"https://api.github.com/users/krischer/followers","following_url":"https://api.github.com/users/krischer/following{/other_user}","gists_url":"https://api.github.com/users/krischer/gists{/gist_id}","starred_url":"https://api.github.com/users/krischer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/krischer/subscriptions","organizations_url":"https://api.github.com/users/krischer/orgs","repos_url":"https://api.github.com/users/krischer/repos","events_url":"https://api.github.com/users/krischer/events{/privacy}","received_events_url":"https://api.github.com/users/krischer/received_events","type":"User","site_admin":false},"body":"This PR adds Lanczos interpolation to ObsPy as has already been discussed a couple of times. Its an extended version of what we already had in Instaseis rewritten in C. I hooked it into `Stream.interpolate`/`Trace.interpolate` as it is a kind of interpolation method and it fits the existing API very well.\r\n\r\nIt is almost always better then the existing interpolation methods and should come in very handy for changing the sampling rate. Results are pretty nice:\r\n\r\n```python\r\nimport matplotlib.pylab as plt\r\nimport numpy as np\r\nimport obspy\r\n\r\ndata = np.sin(np.linspace(0, 200 * np.pi, 250))\r\n\r\ntr = obspy.Trace(data=data)\r\n\r\ntr2 = tr.copy()\r\ntr2.interpolate(method=\"lanczos\", a=25, sampling_rate=100)\r\n\r\nplt.figure(figsize=(18, 8))\r\nplt.plot(tr.times(), tr.data, \"o\", label=\"samples\")\r\nplt.plot(tr2.times(), tr2.data, label=\"resampled\")\r\nplt.plot(np.linspace(0, 249, 10000),\r\n         np.sin(np.linspace(0, 200 * np.pi, 10000)), \"--\",\r\n         label=\"original\", color=\"k\")\r\nplt.legend()\r\nplt.xlim(30, 40)\r\nplt.show()\r\n```\r\n\r\n<img width=\"1057\" alt=\"screen shot 2015-07-31 at 00 40 55\" src=\"https://cloud.githubusercontent.com/assets/800487/8996975/da6cc77a-371c-11e5-97ca-bc42f78578a8.png\">\r\n\r\nI put quite some work into the documentation - pages of interest:\r\n\r\n* http://www.geophysik.uni-muenchen.de/~krischer/doc_lanczos/packages/autogen/obspy.signal.interpolation.lanczos_interpolation.html\r\n* http://www.geophysik.uni-muenchen.de/~krischer/doc_lanczos/packages/autogen/obspy.signal.interpolation.plot_lanczos_windows.html\r\n* http://www.geophysik.uni-muenchen.de/~krischer/doc_lanczos/packages/autogen/obspy.core.trace.Trace.interpolate.html\r\n\r\nIt currently supports three different windows to taper the sinc function which represent different trade-offs between accuracy and \"wiggliness\". If somebody feels we need more please let me know.\r\n\r\n![obspy-signal-interpolation-plot_lanczos_windows-1](https://cloud.githubusercontent.com/assets/800487/8997147/5d6d2f60-371e-11e5-9553-21a65dbd123d.png)\r\n\r\nFurthermore the `interpolate()` method now has an additional argument: `time_shift` - a cheap way to shift seismograms by subsamples. Not as good as a Fourier domain shift but still pretty useful in many cases.\r\n\r\nThere is still some optimization potential in the C code which could speed it up so if anyone wants to have a go: Please feel free :-)\r\n\r\n@martinvandriel Just pinging you to make you aware of this.\r\n\r\nShould be ready for review!","created_at":"2015-07-30T23:00:13Z","updated_at":"2015-07-31T22:28:19Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c6161c53e744e3a3dd5a1d4916a2a0588931bb31","assignee":null,"milestone":{"url":"https://api.github.com/repos/obspy/obspy/milestones/8","html_url":"https://github.com/obspy/obspy/milestones/0.11.0","labels_url":"https://api.github.com/repos/obspy/obspy/milestones/8/labels","id":725009,"number":8,"title":"0.11.0","description":"","creator":{"login":"barsch","id":602450,"avatar_url":"https://avatars.githubusercontent.com/u/602450?v=3","gravatar_id":"","url":"https://api.github.com/users/barsch","html_url":"https://github.com/barsch","followers_url":"https://api.github.com/users/barsch/followers","following_url":"https://api.github.com/users/barsch/following{/other_user}","gists_url":"https://api.github.com/users/barsch/gists{/gist_id}","starred_url":"https://api.github.com/users/barsch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/barsch/subscriptions","organizations_url":"https://api.github.com/users/barsch/orgs","repos_url":"https://api.github.com/users/barsch/repos","events_url":"https://api.github.com/users/barsch/events{/privacy}","received_events_url":"https://api.github.com/users/barsch/received_events","type":"User","site_admin":false},"open_issues":45,"closed_issues":19,"state":"open","created_at":"2014-07-18T08:42:03Z","updated_at":"2015-07-31T08:42:43Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/obspy/obspy/pulls/1101/commits","review_comments_url":"https://api.github.com/repos/obspy/obspy/pulls/1101/comments","review_comment_url":"https://api.github.com/repos/obspy/obspy/pulls/comments{/number}","comments_url":"https://api.github.com/repos/obspy/obspy/issues/1101/comments","statuses_url":"https://api.github.com/repos/obspy/obspy/statuses/f754a7e5b38b2d2300473cd764abd9693a8a160e","head":{"label":"krischer:lanczos_resampling","ref":"lanczos_resampling","sha":"f754a7e5b38b2d2300473cd764abd9693a8a160e","user":{"login":"krischer","id":800487,"avatar_url":"https://avatars.githubusercontent.com/u/800487?v=3","gravatar_id":"","url":"https://api.github.com/users/krischer","html_url":"https://github.com/krischer","followers_url":"https://api.github.com/users/krischer/followers","following_url":"https://api.github.com/users/krischer/following{/other_user}","gists_url":"https://api.github.com/users/krischer/gists{/gist_id}","starred_url":"https://api.github.com/users/krischer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/krischer/subscriptions","organizations_url":"https://api.github.com/users/krischer/orgs","repos_url":"https://api.github.com/users/krischer/repos","events_url":"https://api.github.com/users/krischer/events{/privacy}","received_events_url":"https://api.github.com/users/krischer/received_events","type":"User","site_admin":false},"repo":{"id":5830460,"name":"obspy","full_name":"krischer/obspy","owner":{"login":"krischer","id":800487,"avatar_url":"https://avatars.githubusercontent.com/u/800487?v=3","gravatar_id":"","url":"https://api.github.com/users/krischer","html_url":"https://github.com/krischer","followers_url":"https://api.github.com/users/krischer/followers","following_url":"https://api.github.com/users/krischer/following{/other_user}","gists_url":"https://api.github.com/users/krischer/gists{/gist_id}","starred_url":"https://api.github.com/users/krischer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/krischer/subscriptions","organizations_url":"https://api.github.com/users/krischer/orgs","repos_url":"https://api.github.com/users/krischer/repos","events_url":"https://api.github.com/users/krischer/events{/privacy}","received_events_url":"https://api.github.com/users/krischer/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/krischer/obspy","description":"ObsPy: A Python Toolbox for seismology/seismological observatories.","fork":true,"url":"https://api.github.com/repos/krischer/obspy","forks_url":"https://api.github.com/repos/krischer/obspy/forks","keys_url":"https://api.github.com/repos/krischer/obspy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/krischer/obspy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/krischer/obspy/teams","hooks_url":"https://api.github.com/repos/krischer/obspy/hooks","issue_events_url":"https://api.github.com/repos/krischer/obspy/issues/events{/number}","events_url":"https://api.github.com/repos/krischer/obspy/events","assignees_url":"https://api.github.com/repos/krischer/obspy/assignees{/user}","branches_url":"https://api.github.com/repos/krischer/obspy/branches{/branch}","tags_url":"https://api.github.com/repos/krischer/obspy/tags","blobs_url":"https://api.github.com/repos/krischer/obspy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/krischer/obspy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/krischer/obspy/git/refs{/sha}","trees_url":"https://api.github.com/repos/krischer/obspy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/krischer/obspy/statuses/{sha}","languages_url":"https://api.github.com/repos/krischer/obspy/languages","stargazers_url":"https://api.github.com/repos/krischer/obspy/stargazers","contributors_url":"https://api.github.com/repos/krischer/obspy/contributors","subscribers_url":"https://api.github.com/repos/krischer/obspy/subscribers","subscription_url":"https://api.github.com/repos/krischer/obspy/subscription","commits_url":"https://api.github.com/repos/krischer/obspy/commits{/sha}","git_commits_url":"https://api.github.com/repos/krischer/obspy/git/commits{/sha}","comments_url":"https://api.github.com/repos/krischer/obspy/comments{/number}","issue_comment_url":"https://api.github.com/repos/krischer/obspy/issues/comments{/number}","contents_url":"https://api.github.com/repos/krischer/obspy/contents/{+path}","compare_url":"https://api.github.com/repos/krischer/obspy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/krischer/obspy/merges","archive_url":"https://api.github.com/repos/krischer/obspy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/krischer/obspy/downloads","issues_url":"https://api.github.com/repos/krischer/obspy/issues{/number}","pulls_url":"https://api.github.com/repos/krischer/obspy/pulls{/number}","milestones_url":"https://api.github.com/repos/krischer/obspy/milestones{/number}","notifications_url":"https://api.github.com/repos/krischer/obspy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/krischer/obspy/labels{/name}","releases_url":"https://api.github.com/repos/krischer/obspy/releases{/id}","created_at":"2012-09-16T15:34:42Z","updated_at":"2014-11-20T12:15:18Z","pushed_at":"2015-07-31T16:18:12Z","git_url":"git://github.com/krischer/obspy.git","ssh_url":"git@github.com:krischer/obspy.git","clone_url":"https://github.com/krischer/obspy.git","svn_url":"https://github.com/krischer/obspy","homepage":"https://github.com/obspy/obspy/wiki","size":63846,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":0,"forks":2,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"obspy:master","ref":"master","sha":"7302884497fd3fad045b4839c3dd90bf31d82212","user":{"login":"obspy","id":1701221,"avatar_url":"https://avatars.githubusercontent.com/u/1701221?v=3","gravatar_id":"","url":"https://api.github.com/users/obspy","html_url":"https://github.com/obspy","followers_url":"https://api.github.com/users/obspy/followers","following_url":"https://api.github.com/users/obspy/following{/other_user}","gists_url":"https://api.github.com/users/obspy/gists{/gist_id}","starred_url":"https://api.github.com/users/obspy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/obspy/subscriptions","organizations_url":"https://api.github.com/users/obspy/orgs","repos_url":"https://api.github.com/users/obspy/repos","events_url":"https://api.github.com/users/obspy/events{/privacy}","received_events_url":"https://api.github.com/users/obspy/received_events","type":"Organization","site_admin":false},"repo":{"id":5731348,"name":"obspy","full_name":"obspy/obspy","owner":{"login":"obspy","id":1701221,"avatar_url":"https://avatars.githubusercontent.com/u/1701221?v=3","gravatar_id":"","url":"https://api.github.com/users/obspy","html_url":"https://github.com/obspy","followers_url":"https://api.github.com/users/obspy/followers","following_url":"https://api.github.com/users/obspy/following{/other_user}","gists_url":"https://api.github.com/users/obspy/gists{/gist_id}","starred_url":"https://api.github.com/users/obspy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/obspy/subscriptions","organizations_url":"https://api.github.com/users/obspy/orgs","repos_url":"https://api.github.com/users/obspy/repos","events_url":"https://api.github.com/users/obspy/events{/privacy}","received_events_url":"https://api.github.com/users/obspy/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/obspy/obspy","description":"ObsPy: A Python Toolbox for seismology/seismological observatories.","fork":false,"url":"https://api.github.com/repos/obspy/obspy","forks_url":"https://api.github.com/repos/obspy/obspy/forks","keys_url":"https://api.github.com/repos/obspy/obspy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/obspy/obspy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/obspy/obspy/teams","hooks_url":"https://api.github.com/repos/obspy/obspy/hooks","issue_events_url":"https://api.github.com/repos/obspy/obspy/issues/events{/number}","events_url":"https://api.github.com/repos/obspy/obspy/events","assignees_url":"https://api.github.com/repos/obspy/obspy/assignees{/user}","branches_url":"https://api.github.com/repos/obspy/obspy/branches{/branch}","tags_url":"https://api.github.com/repos/obspy/obspy/tags","blobs_url":"https://api.github.com/repos/obspy/obspy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/obspy/obspy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/obspy/obspy/git/refs{/sha}","trees_url":"https://api.github.com/repos/obspy/obspy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/obspy/obspy/statuses/{sha}","languages_url":"https://api.github.com/repos/obspy/obspy/languages","stargazers_url":"https://api.github.com/repos/obspy/obspy/stargazers","contributors_url":"https://api.github.com/repos/obspy/obspy/contributors","subscribers_url":"https://api.github.com/repos/obspy/obspy/subscribers","subscription_url":"https://api.github.com/repos/obspy/obspy/subscription","commits_url":"https://api.github.com/repos/obspy/obspy/commits{/sha}","git_commits_url":"https://api.github.com/repos/obspy/obspy/git/commits{/sha}","comments_url":"https://api.github.com/repos/obspy/obspy/comments{/number}","issue_comment_url":"https://api.github.com/repos/obspy/obspy/issues/comments{/number}","contents_url":"https://api.github.com/repos/obspy/obspy/contents/{+path}","compare_url":"https://api.github.com/repos/obspy/obspy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/obspy/obspy/merges","archive_url":"https://api.github.com/repos/obspy/obspy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/obspy/obspy/downloads","issues_url":"https://api.github.com/repos/obspy/obspy/issues{/number}","pulls_url":"https://api.github.com/repos/obspy/obspy/pulls{/number}","milestones_url":"https://api.github.com/repos/obspy/obspy/milestones{/number}","notifications_url":"https://api.github.com/repos/obspy/obspy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/obspy/obspy/labels{/name}","releases_url":"https://api.github.com/repos/obspy/obspy/releases{/id}","created_at":"2012-09-08T19:17:46Z","updated_at":"2015-07-30T21:06:38Z","pushed_at":"2015-07-31T16:24:04Z","git_url":"git://github.com/obspy/obspy.git","ssh_url":"git@github.com:obspy/obspy.git","clone_url":"https://github.com/obspy/obspy.git","svn_url":"https://github.com/obspy/obspy","homepage":"http://www.obspy.org","size":84416,"stargazers_count":146,"watchers_count":146,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":103,"mirror_url":null,"open_issues_count":96,"forks":103,"open_issues":96,"watchers":146,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/obspy/obspy/pulls/1101"},"html":{"href":"https://github.com/obspy/obspy/pull/1101"},"issue":{"href":"https://api.github.com/repos/obspy/obspy/issues/1101"},"comments":{"href":"https://api.github.com/repos/obspy/obspy/issues/1101/comments"},"review_comments":{"href":"https://api.github.com/repos/obspy/obspy/pulls/1101/comments"},"review_comment":{"href":"https://api.github.com/repos/obspy/obspy/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/obspy/obspy/pulls/1101/commits"},"statuses":{"href":"https://api.github.com/repos/obspy/obspy/statuses/f754a7e5b38b2d2300473cd764abd9693a8a160e"}}}}