{"action":"created","comment":{"url":"https://api.github.com/repos/soft-matter/pims/pulls/comments/48424262","id":48424262,"diff_hunk":"@@ -20,6 +20,8 @@\n from pims.tiff_stack import TiffStack_tifffile  # noqa\n from .spe_stack import SpeStack\n \n+from pims.viewer import Viewer, ViewerPipeline","path":"pims/api.py","position":4,"original_position":4,"commit_id":"f17fddfcf7a38e1b664d5fef1c2e7b6f703cb80c","original_commit_id":"f17fddfcf7a38e1b664d5fef1c2e7b6f703cb80c","user":{"login":"tacaswell","id":199813,"avatar_url":"https://avatars.githubusercontent.com/u/199813?v=3","gravatar_id":"","url":"https://api.github.com/users/tacaswell","html_url":"https://github.com/tacaswell","followers_url":"https://api.github.com/users/tacaswell/followers","following_url":"https://api.github.com/users/tacaswell/following{/other_user}","gists_url":"https://api.github.com/users/tacaswell/gists{/gist_id}","starred_url":"https://api.github.com/users/tacaswell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tacaswell/subscriptions","organizations_url":"https://api.github.com/users/tacaswell/orgs","repos_url":"https://api.github.com/users/tacaswell/repos","events_url":"https://api.github.com/users/tacaswell/events{/privacy}","received_events_url":"https://api.github.com/users/tacaswell/received_events","type":"User","site_admin":false},"body":":-1:  on importing this in the api","created_at":"2015-12-24T19:14:13Z","updated_at":"2015-12-24T19:14:13Z","html_url":"https://github.com/soft-matter/pims/pull/220#discussion_r48424262","pull_request_url":"https://api.github.com/repos/soft-matter/pims/pulls/220","_links":{"self":{"href":"https://api.github.com/repos/soft-matter/pims/pulls/comments/48424262"},"html":{"href":"https://github.com/soft-matter/pims/pull/220#discussion_r48424262"},"pull_request":{"href":"https://api.github.com/repos/soft-matter/pims/pulls/220"}}},"pull_request":{"url":"https://api.github.com/repos/soft-matter/pims/pulls/220","id":54549686,"html_url":"https://github.com/soft-matter/pims/pull/220","diff_url":"https://github.com/soft-matter/pims/pull/220.diff","patch_url":"https://github.com/soft-matter/pims/pull/220.patch","issue_url":"https://api.github.com/repos/soft-matter/pims/issues/220","number":220,"state":"open","locked":false,"title":"ENH Viewer","user":{"login":"caspervdw","id":8937919,"avatar_url":"https://avatars.githubusercontent.com/u/8937919?v=3","gravatar_id":"","url":"https://api.github.com/users/caspervdw","html_url":"https://github.com/caspervdw","followers_url":"https://api.github.com/users/caspervdw/followers","following_url":"https://api.github.com/users/caspervdw/following{/other_user}","gists_url":"https://api.github.com/users/caspervdw/gists{/gist_id}","starred_url":"https://api.github.com/users/caspervdw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caspervdw/subscriptions","organizations_url":"https://api.github.com/users/caspervdw/orgs","repos_url":"https://api.github.com/users/caspervdw/repos","events_url":"https://api.github.com/users/caspervdw/events{/privacy}","received_events_url":"https://api.github.com/users/caspervdw/received_events","type":"User","site_admin":false},"body":"This adds a Viewer based on [`skimage.viewer.CollectionViewer`](http://scikit-image.org/docs/dev/api/skimage.viewer.html). This is useful because a large part of my (an probably many others) workflow is just looking at the images and checking out the effect of different parameters on the image. This kind of work is much more optimal inside for example ImageJ, because you get direct feedback. However, ImageJ is not as fast as PIMS in loading images *and* it doesn't have my favourite particle tracking tool... hence this viewer.\r\n\r\nTo show the viewer:\r\n\r\n    reader = pims.Viewer().show()\r\n\r\nThen use the `Open` menu option to open and view a video. When the window is closed, the reader is returned.\r\n\r\nYou can also display an already opened reader:\r\n\r\n    pims.Viewer(pims.open(filename)).show()\r\n\r\n### Pipelines\r\nI modified the skimage code for plugins so that it can add pipelines: functions that lazily modify a reader. The nice thing about the Viewer is that you can see the effect of a pipeline directly using sliders to modify the parameters of the pipeline. Because this went pretty far in the code of both the viewer and the plugins, I decided to reimplement the whole `skimage.viewer` class and not subclass it.\r\n\r\nFull example:\r\n\r\n    import numpy as np\r\n    from pims.viewer import Viewer, ViewerPipeline, Slider\r\n\r\n    def add_noise(img, noise_level):\r\n        return img + np.random.random(img.shape) * noise_level\r\n\r\n    AddNoise = ViewerPipeline(add_noise) + Slider('noise_level', 0, 100, 0)\r\n    viewer = Viewer()\r\n    viewer += AddNoise\r\n    original, noise_added = viewer.show()\r\n\r\nNow the original reader is returned next to a reader that has a pipeline wrapped around.\r\n\r\n### 3D rendering\r\nAdditonally (because I personally look mainly at 3D images), it wraps the 3D OpenGL viewer from `pyqtgraph` so 3D images can be rendered 3D (something I really like :-D )\r\n\r\n### N dimensional files\r\nThe viewer expects a `FramesSequenceND`. Because `FramesSequenceND` is aware of its dimensions, it is easy to impelement sliders that makes you able to navigate the reader (for instance in `z`, `c`, `t`). When a `FramesSequence` is used, it is wrapped inside a helper class that makes it behave like a `FramesSequenceND`.\r\n\r\n### To do\r\nMany things, but to start:\r\n* better docstrings (I'll say it myself)\r\n* debugging on systems with different python and PyQt/PySide versions\r\n* drag&drop files to open them\r\n* opening lists of files (coupled to `ImageSequence`)\r\n* allow pipelines that change the shape of the reader\r\n* allow plotting pipelines for instance to wrap `trackpy.annotate`","created_at":"2015-12-24T12:56:43Z","updated_at":"2015-12-24T19:14:13Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e48c65f04f56854f6181831a739b0b64ad7ad6d5","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/soft-matter/pims/pulls/220/commits","review_comments_url":"https://api.github.com/repos/soft-matter/pims/pulls/220/comments","review_comment_url":"https://api.github.com/repos/soft-matter/pims/pulls/comments{/number}","comments_url":"https://api.github.com/repos/soft-matter/pims/issues/220/comments","statuses_url":"https://api.github.com/repos/soft-matter/pims/statuses/f17fddfcf7a38e1b664d5fef1c2e7b6f703cb80c","head":{"label":"caspervdw:viewer","ref":"viewer","sha":"f17fddfcf7a38e1b664d5fef1c2e7b6f703cb80c","user":{"login":"caspervdw","id":8937919,"avatar_url":"https://avatars.githubusercontent.com/u/8937919?v=3","gravatar_id":"","url":"https://api.github.com/users/caspervdw","html_url":"https://github.com/caspervdw","followers_url":"https://api.github.com/users/caspervdw/followers","following_url":"https://api.github.com/users/caspervdw/following{/other_user}","gists_url":"https://api.github.com/users/caspervdw/gists{/gist_id}","starred_url":"https://api.github.com/users/caspervdw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caspervdw/subscriptions","organizations_url":"https://api.github.com/users/caspervdw/orgs","repos_url":"https://api.github.com/users/caspervdw/repos","events_url":"https://api.github.com/users/caspervdw/events{/privacy}","received_events_url":"https://api.github.com/users/caspervdw/received_events","type":"User","site_admin":false},"repo":{"id":24762820,"name":"pims","full_name":"caspervdw/pims","owner":{"login":"caspervdw","id":8937919,"avatar_url":"https://avatars.githubusercontent.com/u/8937919?v=3","gravatar_id":"","url":"https://api.github.com/users/caspervdw","html_url":"https://github.com/caspervdw","followers_url":"https://api.github.com/users/caspervdw/followers","following_url":"https://api.github.com/users/caspervdw/following{/other_user}","gists_url":"https://api.github.com/users/caspervdw/gists{/gist_id}","starred_url":"https://api.github.com/users/caspervdw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caspervdw/subscriptions","organizations_url":"https://api.github.com/users/caspervdw/orgs","repos_url":"https://api.github.com/users/caspervdw/repos","events_url":"https://api.github.com/users/caspervdw/events{/privacy}","received_events_url":"https://api.github.com/users/caspervdw/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/caspervdw/pims","description":"Python Image Sequence: Load video and sequential images in many formats with a simple, consistent interface.","fork":true,"url":"https://api.github.com/repos/caspervdw/pims","forks_url":"https://api.github.com/repos/caspervdw/pims/forks","keys_url":"https://api.github.com/repos/caspervdw/pims/keys{/key_id}","collaborators_url":"https://api.github.com/repos/caspervdw/pims/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/caspervdw/pims/teams","hooks_url":"https://api.github.com/repos/caspervdw/pims/hooks","issue_events_url":"https://api.github.com/repos/caspervdw/pims/issues/events{/number}","events_url":"https://api.github.com/repos/caspervdw/pims/events","assignees_url":"https://api.github.com/repos/caspervdw/pims/assignees{/user}","branches_url":"https://api.github.com/repos/caspervdw/pims/branches{/branch}","tags_url":"https://api.github.com/repos/caspervdw/pims/tags","blobs_url":"https://api.github.com/repos/caspervdw/pims/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/caspervdw/pims/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/caspervdw/pims/git/refs{/sha}","trees_url":"https://api.github.com/repos/caspervdw/pims/git/trees{/sha}","statuses_url":"https://api.github.com/repos/caspervdw/pims/statuses/{sha}","languages_url":"https://api.github.com/repos/caspervdw/pims/languages","stargazers_url":"https://api.github.com/repos/caspervdw/pims/stargazers","contributors_url":"https://api.github.com/repos/caspervdw/pims/contributors","subscribers_url":"https://api.github.com/repos/caspervdw/pims/subscribers","subscription_url":"https://api.github.com/repos/caspervdw/pims/subscription","commits_url":"https://api.github.com/repos/caspervdw/pims/commits{/sha}","git_commits_url":"https://api.github.com/repos/caspervdw/pims/git/commits{/sha}","comments_url":"https://api.github.com/repos/caspervdw/pims/comments{/number}","issue_comment_url":"https://api.github.com/repos/caspervdw/pims/issues/comments{/number}","contents_url":"https://api.github.com/repos/caspervdw/pims/contents/{+path}","compare_url":"https://api.github.com/repos/caspervdw/pims/compare/{base}...{head}","merges_url":"https://api.github.com/repos/caspervdw/pims/merges","archive_url":"https://api.github.com/repos/caspervdw/pims/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/caspervdw/pims/downloads","issues_url":"https://api.github.com/repos/caspervdw/pims/issues{/number}","pulls_url":"https://api.github.com/repos/caspervdw/pims/pulls{/number}","milestones_url":"https://api.github.com/repos/caspervdw/pims/milestones{/number}","notifications_url":"https://api.github.com/repos/caspervdw/pims/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/caspervdw/pims/labels{/name}","releases_url":"https://api.github.com/repos/caspervdw/pims/releases{/id}","created_at":"2014-10-03T15:08:09Z","updated_at":"2015-04-20T13:45:07Z","pushed_at":"2015-12-24T12:19:28Z","git_url":"git://github.com/caspervdw/pims.git","ssh_url":"git@github.com:caspervdw/pims.git","clone_url":"https://github.com/caspervdw/pims.git","svn_url":"https://github.com/caspervdw/pims","homepage":"","size":5342,"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":"soft-matter:master","ref":"master","sha":"fea1b47c629927f5238e64914dcc4ff09e9d0da6","user":{"login":"soft-matter","id":5857177,"avatar_url":"https://avatars.githubusercontent.com/u/5857177?v=3","gravatar_id":"","url":"https://api.github.com/users/soft-matter","html_url":"https://github.com/soft-matter","followers_url":"https://api.github.com/users/soft-matter/followers","following_url":"https://api.github.com/users/soft-matter/following{/other_user}","gists_url":"https://api.github.com/users/soft-matter/gists{/gist_id}","starred_url":"https://api.github.com/users/soft-matter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/soft-matter/subscriptions","organizations_url":"https://api.github.com/users/soft-matter/orgs","repos_url":"https://api.github.com/users/soft-matter/repos","events_url":"https://api.github.com/users/soft-matter/events{/privacy}","received_events_url":"https://api.github.com/users/soft-matter/received_events","type":"Organization","site_admin":false},"repo":{"id":14318232,"name":"pims","full_name":"soft-matter/pims","owner":{"login":"soft-matter","id":5857177,"avatar_url":"https://avatars.githubusercontent.com/u/5857177?v=3","gravatar_id":"","url":"https://api.github.com/users/soft-matter","html_url":"https://github.com/soft-matter","followers_url":"https://api.github.com/users/soft-matter/followers","following_url":"https://api.github.com/users/soft-matter/following{/other_user}","gists_url":"https://api.github.com/users/soft-matter/gists{/gist_id}","starred_url":"https://api.github.com/users/soft-matter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/soft-matter/subscriptions","organizations_url":"https://api.github.com/users/soft-matter/orgs","repos_url":"https://api.github.com/users/soft-matter/repos","events_url":"https://api.github.com/users/soft-matter/events{/privacy}","received_events_url":"https://api.github.com/users/soft-matter/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/soft-matter/pims","description":"Python Image Sequence: Load video and sequential images in many formats with a simple, consistent interface.","fork":false,"url":"https://api.github.com/repos/soft-matter/pims","forks_url":"https://api.github.com/repos/soft-matter/pims/forks","keys_url":"https://api.github.com/repos/soft-matter/pims/keys{/key_id}","collaborators_url":"https://api.github.com/repos/soft-matter/pims/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/soft-matter/pims/teams","hooks_url":"https://api.github.com/repos/soft-matter/pims/hooks","issue_events_url":"https://api.github.com/repos/soft-matter/pims/issues/events{/number}","events_url":"https://api.github.com/repos/soft-matter/pims/events","assignees_url":"https://api.github.com/repos/soft-matter/pims/assignees{/user}","branches_url":"https://api.github.com/repos/soft-matter/pims/branches{/branch}","tags_url":"https://api.github.com/repos/soft-matter/pims/tags","blobs_url":"https://api.github.com/repos/soft-matter/pims/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/soft-matter/pims/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/soft-matter/pims/git/refs{/sha}","trees_url":"https://api.github.com/repos/soft-matter/pims/git/trees{/sha}","statuses_url":"https://api.github.com/repos/soft-matter/pims/statuses/{sha}","languages_url":"https://api.github.com/repos/soft-matter/pims/languages","stargazers_url":"https://api.github.com/repos/soft-matter/pims/stargazers","contributors_url":"https://api.github.com/repos/soft-matter/pims/contributors","subscribers_url":"https://api.github.com/repos/soft-matter/pims/subscribers","subscription_url":"https://api.github.com/repos/soft-matter/pims/subscription","commits_url":"https://api.github.com/repos/soft-matter/pims/commits{/sha}","git_commits_url":"https://api.github.com/repos/soft-matter/pims/git/commits{/sha}","comments_url":"https://api.github.com/repos/soft-matter/pims/comments{/number}","issue_comment_url":"https://api.github.com/repos/soft-matter/pims/issues/comments{/number}","contents_url":"https://api.github.com/repos/soft-matter/pims/contents/{+path}","compare_url":"https://api.github.com/repos/soft-matter/pims/compare/{base}...{head}","merges_url":"https://api.github.com/repos/soft-matter/pims/merges","archive_url":"https://api.github.com/repos/soft-matter/pims/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/soft-matter/pims/downloads","issues_url":"https://api.github.com/repos/soft-matter/pims/issues{/number}","pulls_url":"https://api.github.com/repos/soft-matter/pims/pulls{/number}","milestones_url":"https://api.github.com/repos/soft-matter/pims/milestones{/number}","notifications_url":"https://api.github.com/repos/soft-matter/pims/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/soft-matter/pims/labels{/name}","releases_url":"https://api.github.com/repos/soft-matter/pims/releases{/id}","created_at":"2013-11-12T00:55:12Z","updated_at":"2015-12-05T15:45:29Z","pushed_at":"2015-12-24T12:56:44Z","git_url":"git://github.com/soft-matter/pims.git","ssh_url":"git@github.com:soft-matter/pims.git","clone_url":"https://github.com/soft-matter/pims.git","svn_url":"https://github.com/soft-matter/pims","homepage":"http://soft-matter.github.io/pims/","size":5982,"stargazers_count":21,"watchers_count":21,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":17,"mirror_url":null,"open_issues_count":31,"forks":17,"open_issues":31,"watchers":21,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/soft-matter/pims/pulls/220"},"html":{"href":"https://github.com/soft-matter/pims/pull/220"},"issue":{"href":"https://api.github.com/repos/soft-matter/pims/issues/220"},"comments":{"href":"https://api.github.com/repos/soft-matter/pims/issues/220/comments"},"review_comments":{"href":"https://api.github.com/repos/soft-matter/pims/pulls/220/comments"},"review_comment":{"href":"https://api.github.com/repos/soft-matter/pims/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/soft-matter/pims/pulls/220/commits"},"statuses":{"href":"https://api.github.com/repos/soft-matter/pims/statuses/f17fddfcf7a38e1b664d5fef1c2e7b6f703cb80c"}}}}