GitHub PullRequestReviewCommentEvent at 2014-11-25 19:01:30
Repository: pims
Actor: tacaswell
Payload: {"action":"created","comment":{"url":"https://api.github.com/repos/soft-matter/pims/pulls/comments/20885951","id":20885951,"diff_hunk":"@@ -0,0 +1,298 @@\n+from __future__ import (absolute_import, division, print_function)\n+\n+import numpy as np\n+\n+from pims.base_frames import FramesSequence\n+from pims.frame import Frame\n+\n+\n+try:\n+    import javabridge\n+except ImportError:\n+    javabridge = None\n+    \n+try:\n+    import bioformats\n+except ImportError:\n+    bioformats = None\n+    \n+try:\n+    from pandas import DataFrame\n+except ImportError:\n+    DataFrame = None\n+    \n+def available():\n+    try:\n+        import javabridge\n+        import bioformats\n+    except ImportError:\n+        return False\n+    else:\n+        return True\n+\n+def jwtofloat(jwrapper):\n+    if jwrapper != None:\n+        return float(str(jwrapper))\n+    else:\n+        return None\n+        \n+def jwtoint(jwrapper):\n+    if jwrapper != None:\n+        return int(str(jwrapper))\n+    else:\n+        return None\n+        \n+def jwtostr(jwrapper):\n+    if jwrapper != None:\n+        return str(jwrapper)\n+    else:\n+        return None\n+        \n+def jwtoauto(jwrapper):\n+    if jwrapper == None:\n+        return None\n+    jw = str(jwrapper)\n+    try:\n+        return int(jw)\n+    except ValueError:\n+        try:\n+            return float(jw)\n+        except ValueError:\n+            return jw    \n+            \n+class BioformatsReader2D(FramesSequence):\n+    \"\"\"Reads 2D images from the frames of a file supported by bioformats into an\n+    iterable object that returns images as numpy arrays.\n+    \n+    Required:\n+    https://github.com/CellProfiler/python-bioformats\n+    https://github.com/CellProfiler/python-javabridge\n+     or (windows compiled) http://www.lfd.uci.edu/~gohlke/pythonlibs/#javabridge   \n+    \n+    Only tested with Nikon ND2 files\n+    For files larger than 4GB, 64 bits Python, Javabridge and JDK are required\n+\n+    Parameters\n+    ----------\n+    filename: string\n+    process_func: function, optional\n+        callable with signature `proc_img = process_func(img)`,\n+        which will be applied to the data from each frame\n+    series: active image series index (change with property series)\n+    \n+    Metadata\n+    ----------\n+    Standard metadata: \n+     - number of series\n+     - per series:   - size C, T, Z, Y, X\n+                     - physical pixelsizes X, Y, Z\n+     - per frame:         - indices plane, series, Z, C, T\n+        (as dictionary)   - physical locations X, Y, Z, T\n+                    \n+     - more can be read out using metadataretrieve, passing the method as a \n+     string. All further arguments will be passed to that method. Example: \n+     \n+         frames.metadataretrieve('getPlaneDeltaT', 0, 50)\n+         evaluates MetadataRetrieve.getPlaneDeltaT(0, 50)\n+     \n+     documentation on MetadataRetrieve methods can be found here:\n+     http://downloads.openmicroscopy.org/bio-formats/5.0.4/api/loci/formats/meta/MetadataRetrieve.html\n+     - a bioformats.OMEXML object can also be obtained using .omexml, see \n+     https://github.com/CellProfiler/python-bioformats\"\"\"\n+     \n+    @classmethod\n+    def class_exts(cls):\n+        return {'nd2'} | super(BioformatsReader2D, cls).class_exts()\n+\n+    def __init__(self, filename, series=0, process_func=None, as_grey=False):\n+        self.filename = str(filename)\n+        self._series = series        \n+        self._validate_process_func(process_func)\n+        self._initializereader()\n+        self._change_series() \n+    \n+    def _initializereader(self):\n+        javabridge.start_vm(class_path=bioformats.JARS,max_heap_size='512m')\n+        self._reader = bioformats.get_image_reader(self.filename, self.filename) \n+        if self._reader.rdr.isRGB():\n+            raise NotImplementedError('RGB images are not supported')\n+        self._jmd = javabridge.JWrapper(self._reader.rdr.getMetadataStore())        \n+        self._size_series = self._reader.rdr.getSeriesCount()\n+        self._metadatacolumns = ['plane', 'series', 'indexC', 'indexZ', \n+                                 'indexT','X', 'Y', 'Z', 'T']\n+           \n+    def _change_series(self):   \n+        series = self._series   \n+        self._reader.rdr.setSeries(series)\n+        \n+        # make use of built-in methods of bioformats to determine numpy dtype\n+        im, md = self._get_frame_2D(series, 0)     \n+        self._pixel_type = im.dtype\n+        \n+        self._sizeC = self._reader.rdr.getSizeC()\n+        self._sizeT = self._reader.rdr.getSizeT()\n+        self._sizeZ = self._reader.rdr.getSizeZ()\n+        self._sizeY = self._reader.rdr.getSizeY()\n+        self._sizeX = self._reader.rdr.getSizeX()\n+        self._planes = self._reader.rdr.getImageCount()       \n+        self._pixelX = jwtofloat(self._jmd.getPixelsPhysicalSizeX(series))\n+        self._pixelY = jwtofloat(self._jmd.getPixelsPhysicalSizeY(series))\n+        self._pixelZ = jwtofloat(self._jmd.getPixelsPhysicalSizeZ(series))\n+        if self._pixelY == None:\n+            self._pixelY = self._pixelX                       \n+            \n+    def __len__(self):\n+        return self._planes\n+\n+    def close(self):  \n+        bioformats.release_image_reader(self.filename)\n+        \n+\n+    @property\n+    def pixelsizes(self):\n+        return {'X': self._pixelX, 'Y': self._pixelY, 'Z': self._pixelZ}        \n+        \n+    @property\n+    def sizes(self):\n+        return {'series': self._size_series, 'X': self._sizeX, 'Y': self._sizeY, \n+                'Z': self._sizeZ, 'C': self._sizeC, 'T': self._sizeT}\n+                        \n+    @property\n+    def series(self):\n+        return self._series\n+    @series.setter\n+    def series(self, value):\n+        if value >= self._size_series:\n+            raise IndexError('Series index out of bounds.')\n+        else:\n+            if value != self._series:\n+                self._series = value\n+                self._change_series()\n+        \n+    @property\n+    def frame_shape(self):\n+        return self._sizeX, self._sizeY\n+        \n+    def get_frame(self, j):\n+        im, metadata = self._get_frame(self.series, j)\n+        imageproc = self.process_func(im)\n+        return Frame(imageproc, frame_no=j, metadata=metadata) \n+        \n+    def _get_frame(self, series, j):\n+        im, metadata = self._get_frame_2D(series, j)\n+        metadataproc = dict(zip(self._metadatacolumns, metadata))        \n+        return im, metadataproc\n+        \n+    def _get_frame_2D(self, series, j):       \n+        im = self._reader.read(series=series, index=j)    \n+\n+        metadata = (j,\n+                series,\n+                jwtoint(self._jmd.getPlaneTheC(series, j)),\n+                jwtoint(self._jmd.getPlaneTheZ(series, j)),\n+                jwtoint(self._jmd.getPlaneTheT(series, j)),\n+                jwtofloat(self._jmd.getPlanePositionX(series, j)),\n+                jwtofloat(self._jmd.getPlanePositionY(series, j)),\n+                jwtofloat(self._jmd.getPlanePositionZ(series, j)),\n+                jwtofloat(self._jmd.getPlaneDeltaT(series, j)))\n+\n+        return im, metadata\n+        \n+    def omexml(self):\n+        xml = bioformats.get_omexml_metadata(self.filename)\n+        return bioformats.OMEXML(xml)        \n+        \n+    def metadataretrieve(self, mdr, *args):\n+        try:\n+            jw = getattr(self._jmd, mdr)(*args)\n+        except AttributeError or TypeError:\n+            return None\n+        return jwtoauto(jw)        \n+     \n+    @property\n+    def pixel_type(self):\n+        return self._pixel_type\n+\n+    def __repr__(self):\n+        # May be overwritten by subclasses\n+        result = \"\"\"<Frames>\n+            Source: {filename}\n+            Series: {mp}, active: {mpa}\n+            Framecount: {count} frames\n+            Colordepth: {c}\n+            Zstack depth: {z}\n+            Time frames: {t}\n+            Frame Shape: {w} x {h}\"\"\".format(w=self._sizeX,\n+                                              h=self._sizeY,\n+                                              mp=self._size_series,\n+                                              mpa=self._series,\n+                                              count=self._planes,\n+                                              z=self._sizeZ,\n+                                              t=self._sizeT,\n+                                              c=self._sizeC,\n+                                              filename=self.filename)\n+        return result\n+        \n+        \n+class BioformatsReader3D(BioformatsReader2D):\n+    \"\"\"Extends BioformatsReader2D\n+    Reads 3D images from the frames of a file supported by bioformats into an\n+    iterable object that returns images as numpy arrays, indexed by T index.\n+\n+    Parameters\n+    ----------\n+    filename : string\n+    process_func : function, optional\n+        callable with signature `proc_img = process_func(img)`,\n+        which will be applied to the data from each frame\n+    C : list of color channels to read (change with property channel)\n+    series : active Series index (change with property series)\n+    \n+    Metadata\n+    ----------\n+    see BioformatsReader2D class docstring\n+    \n+    \"\"\"\n+    @classmethod\n+    def class_exts(cls):\n+        return {'nd2'} | super(BioformatsReader3D, cls).class_exts()\n+\n+    def __init__(self, filename, mode='auto', C=[0], series=0, \n+                 process_func=None, as_grey=False):\n+        if not hasattr(C, '__iter__'):\n+            C = [C]    \n+        self._channel = C\n+        \n+        super(BioformatsReader3D, self).__init__(filename, series, process_func)                \n+        \n+    def __len__(self):\n+        return self._sizeT    \n+                    \n+    @property\n+    def channel(self):\n+        return self._channel\n+    @channel.setter\n+    def channel(self, value):\n+        if not hasattr(value, '__iter__'):\n+            value = [value]\n+        if np.any(np.greater_equal(value, self._sizeC)) or np.any(np.less(value, 0)):\n+            raise IndexError('Channel index out of bounds.')\n+        if value != self._channel:\n+            self._channel = value\n+                \n+    def _get_frame(self, series, t):\n+        imlist = np.empty((len(self.channel), self._sizeZ, ","path":"pims/bioformats.py","position":284,"original_position":284,"commit_id":"4367e8a94f66b5d5051c4fa6005cde6c3d469faa","original_commit_id":"4367e8a94f66b5d5051c4fa6005cde6c3d469faa","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":"probably want to make this the proper int type.  `empty` does save a bit of time, but can be dangerous as your array is full of garbage.  It is probably better to use `zeros` as there is no way (and of course by saying this I will be wrong) that memory allocation is the bottle neck (not the python<-> java, the java, or the disk I/O).","created_at":"2014-11-25T19:01:30Z","updated_at":"2014-11-25T19:01:30Z","html_url":"https://github.com/soft-matter/pims/pull/109#discussion_r20885951","pull_request_url":"https://api.github.com/repos/soft-matter/pims/pulls/109","_links":{"self":{"href":"https://api.github.com/repos/soft-matter/pims/pulls/comments/20885951"},"html":{"href":"https://github.com/soft-matter/pims/pull/109#discussion_r20885951"},"pull_request":{"href":"https://api.github.com/repos/soft-matter/pims/pulls/109"}}},"pull_request":{"url":"https://api.github.com/repos/soft-matter/pims/pulls/109","id":22217809,"html_url":"https://github.com/soft-matter/pims/pull/109","diff_url":"https://github.com/soft-matter/pims/pull/109.diff","patch_url":"https://github.com/soft-matter/pims/pull/109.patch","issue_url":"https://api.github.com/repos/soft-matter/pims/issues/109","number":109,"state":"open","locked":false,"title":"Pims bioformats","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 is a wrapper for python-bioformats. Required are:\r\n- https://github.com/CellProfiler/python-bioformats\r\n- manually overwrite loci_tools.jar with newest version\r\n- https://github.com/CellProfiler/python-javabridge\r\n   or (windows compiled) http://www.lfd.uci.edu/~gohlke/pythonlibs/#javabridge   \r\n- Java JDK\r\n\r\nUnless you are not planning to work with big files, 64bits everything is required.\r\n\r\nBig files still have long loading times because metadata of all frames is read in the beginning. Maybe it is better to put all metadata routines separate from get_frame and _initialize, then the user can choose. A lot more metadata can be pulled from _jmd, see http://downloads.openmicroscopy.org/bio-formats/5.0.5/api/loci/formats/meta/MetadataRetrieve.html\r\n\r\nget_frame results in a 3D image (if _dimension = 3), its index is the time index, its channels are set by the property channel and the multipoint index by the property multipoint. You can force it to 2D, then the index is the plane index. \r\n\r\nThere is a strange issue with nd2 files: sometimes CTZYX images appear as multipoint CTYX images. The code checks for a suspicious file and then automatically goes to a mode that corrects for this issue ('use MP as Z')","created_at":"2014-10-03T17:39:29Z","updated_at":"2014-11-25T19:01:30Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2e4c9e461757945090e6343e74b38c9eb7d81202","assignee":null,"milestone":{"url":"https://api.github.com/repos/soft-matter/pims/milestones/2","labels_url":"https://api.github.com/repos/soft-matter/pims/milestones/2/labels","id":735772,"number":2,"title":"v0.3","description":null,"creator":{"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},"open_issues":6,"closed_issues":11,"state":"open","created_at":"2014-07-29T15:27:10Z","updated_at":"2014-10-31T20:22:18Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/soft-matter/pims/pulls/109/commits","review_comments_url":"https://api.github.com/repos/soft-matter/pims/pulls/109/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/109/comments","statuses_url":"https://api.github.com/repos/soft-matter/pims/statuses/4367e8a94f66b5d5051c4fa6005cde6c3d469faa","head":{"label":"caspervdw:pims-bioformats","ref":"pims-bioformats","sha":"4367e8a94f66b5d5051c4fa6005cde6c3d469faa","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":"2014-10-06T11:04:35Z","pushed_at":"2014-11-25T16:33:18Z","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":4002,"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":"2eeae80db83b9fee8e3ec065775c44ded1b8fd9e","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":"2014-11-24T14:52:39Z","pushed_at":"2014-11-24T14:52:39Z","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":"","size":5546,"stargazers_count":7,"watchers_count":7,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":11,"mirror_url":null,"open_issues_count":20,"forks":11,"open_issues":20,"watchers":7,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/soft-matter/pims/pulls/109"},"html":{"href":"https://github.com/soft-matter/pims/pull/109"},"issue":{"href":"https://api.github.com/repos/soft-matter/pims/issues/109"},"comments":{"href":"https://api.github.com/repos/soft-matter/pims/issues/109/comments"},"review_comments":{"href":"https://api.github.com/repos/soft-matter/pims/pulls/109/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/109/commits"},"statuses":{"href":"https://api.github.com/repos/soft-matter/pims/statuses/4367e8a94f66b5d5051c4fa6005cde6c3d469faa"}}}}