{"action":"created","comment":{"url":"https://api.github.com/repos/nipy/dipy/pulls/comments/205493035","pull_request_review_id":140766711,"id":205493035,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwNTQ5MzAzNQ==","diff_hunk":"@@ -0,0 +1,278 @@\n+from __future__ import division, print_function, absolute_import\n+from dipy.workflows.workflow import Workflow\n+import logging\n+import numpy as np\n+import nibabel as nib\n+from dipy.workflows.core import write_gif\n+from dipy.io.image import load_affine_matrix\n+from dipy.viz.regtools import overlay_slices\n+from dipy.viz import (window, actor)\n+\n+from dipy.viz.window import snapshot\n+\n+\n+class VisualizeRegisteredImage(Workflow):\n+\n+    def process_image_data(self, static_img, moved_img):\n+\n+        \"\"\"\n+        Function for pre-processing the image data. It involves\n+        normalizing and copying static, moving images in the\n+        red and green channel, respectively.\n+\n+        type_vis: str\n+            The type of visualisation being created. This affects the\n+            range of values to be selected from the moved image.\n+\n+        return: the normalized image data and range of pixels to be\n+        selected.\n+        \"\"\"\n+\n+        static_img = 255 * ((static_img - static_img.min()) /\n+                            (static_img.max() - static_img.min()))\n+        moved_img = 255 * ((moved_img - moved_img.min()) /\n+                           (moved_img.max() - moved_img.min()))\n+\n+        # Create the color images\n+        overlay = np.zeros(shape=(static_img.shape) + (3,), dtype=np.uint8)\n+        overlay[..., 0] = static_img\n+        overlay[..., 1] = moved_img\n+        mean, std = overlay[overlay > 0].mean(), overlay[overlay > 0].std()\n+        value_range = (mean - 0.5 * std, mean + 1.5 * std)\n+        return overlay, value_range\n+\n+    def get_row_cols(self, num_slices):\n+\n+        \"\"\"\n+        Experimetal helper function to get the number\n+        of rows and columns for the mosaic.\n+\n+        num_slices: int\n+            The number of slices as obtained from the\n+            create_mosaic function.\n+        return: the number of rows and columns.\n+        \"\"\"\n+        rows, cols = 0, 0\n+\n+        while True:\n+            if num_slices % 5 == 0:\n+                break\n+            num_slices += 1\n+\n+        for i in range(5, num_slices):\n+\n+            if num_slices % i == 0:\n+                rows = i\n+                cols = num_slices // i\n+                break\n+\n+        return rows, cols\n+\n+    def create_mosaic(self, static_img, moved_img,\n+                      affine, fname):\n+        \"\"\"\n+        Function for creating the mosaic of the moved image. It\n+        currently only supports slices from the axial plane.\n+\n+        fname: str, optional\n+            Filename to be used for saving the mosaic (default 'mosaic.png').\n+        \"\"\"\n+\n+        overlay, value_range = self.process_image_data(static_img,\n+                                                       moved_img)\n+\n+        renderer = window.Renderer()\n+        renderer.background((0.5, 0.5, 0.5))\n+\n+        slice_actor = actor.slicer(overlay, affine, value_range)\n+        renderer.projection('parallel')\n+\n+        cnt = 0\n+        X, Y, num_slices = slice_actor.shape[:3]\n+\n+        rows, cols = self.get_row_cols(num_slices)\n+        border = 5\n+\n+        for j in range(rows):\n+            for i in range(cols):\n+                slice_mosaic = slice_actor.copy()\n+                slice_mosaic.display(None, None, cnt)\n+                slice_mosaic.SetPosition((X + border) * i,\n+                                         0.5 * cols * (Y + border) -\n+                                         (Y + border) * j, 0)\n+                slice_mosaic.SetInterpolate(False)\n+                renderer.add(slice_mosaic)\n+                renderer.reset_camera()\n+                renderer.zoom(1.6)\n+                cnt += 1\n+                if cnt > num_slices:\n+                    break\n+            if cnt > num_slices:\n+                break\n+\n+        renderer.reset_camera()\n+        renderer.zoom(1.6)\n+\n+        window.record(renderer, out_path=fname,\n+                      size=(900, 600), reset_camera=False)\n+\n+    def adjust_color_range(self, img):\n+\n+        \"\"\"\n+        Function to adjust the range of colors in numpy array\n+        to create the GIF (GIF standard only supports 256 colours).\n+\n+        return\n+        The numpy array with scaled down range of color values.\n+        \"\"\"\n+\n+        # Interpolating to range 0-15 for reducing the colours.\n+        img[..., 0] = np.interp(img[..., 0], (img[..., 0].min(),\n+                                              img[..., 0].max()), (0, 14))\n+        img[..., 1] = np.interp(img[..., 1], (img[..., 1].min(),\n+                                              img[..., 1].max()), (0, 14))\n+        img = np.round(img, 0).astype('uint8')\n+\n+        # Interpolating back to the range 0-255 for getting GIF range.\n+        img[..., 0] = np.interp(img[..., 0], (img[..., 0].min(),\n+                                              img[..., 0].max()), (0, 255))\n+        img[..., 1] = np.interp(img[..., 1], (img[..., 1].min(),\n+                                              img[..., 1].max()), (0, 255))\n+\n+        img = np.round(img, 0).astype('uint8')\n+\n+        return img\n+\n+    def animate_overlap_with_renderer(self, static_img, moved_img,\n+                                      sli_type, fname, affine):\n+\n+        \"\"\"\n+        Function for creating the animated GIF from the slices of the\n+        registered image.\n+        It uses the renderer object to control the dimensions of the\n+        created GIF and for correcting the orientation.\n+        Patameters\n+        ----------\n+        sli_type : str (optional)","path":"dipy/workflows/vis_registeration.py","position":156,"original_position":156,"commit_id":"09ad312dc24513e7051c877181c64c582eaac4ca","original_commit_id":"09ad312dc24513e7051c877181c64c582eaac4ca","user":{"login":"nilgoyette","id":2658640,"node_id":"MDQ6VXNlcjI2NTg2NDA=","avatar_url":"https://avatars3.githubusercontent.com/u/2658640?v=4","gravatar_id":"","url":"https://api.github.com/users/nilgoyette","html_url":"https://github.com/nilgoyette","followers_url":"https://api.github.com/users/nilgoyette/followers","following_url":"https://api.github.com/users/nilgoyette/following{/other_user}","gists_url":"https://api.github.com/users/nilgoyette/gists{/gist_id}","starred_url":"https://api.github.com/users/nilgoyette/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nilgoyette/subscriptions","organizations_url":"https://api.github.com/users/nilgoyette/orgs","repos_url":"https://api.github.com/users/nilgoyette/repos","events_url":"https://api.github.com/users/nilgoyette/events{/privacy}","received_events_url":"https://api.github.com/users/nilgoyette/received_events","type":"User","site_admin":false},"body":"You're only saving 2 characters. It's not worth it. Can you please name it `slice_type`?","created_at":"2018-07-26T15:05:35Z","updated_at":"2018-07-26T15:38:37Z","html_url":"https://github.com/nipy/dipy/pull/1595#discussion_r205493035","pull_request_url":"https://api.github.com/repos/nipy/dipy/pulls/1595","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/nipy/dipy/pulls/comments/205493035"},"html":{"href":"https://github.com/nipy/dipy/pull/1595#discussion_r205493035"},"pull_request":{"href":"https://api.github.com/repos/nipy/dipy/pulls/1595"}}},"pull_request":{"url":"https://api.github.com/repos/nipy/dipy/pulls/1595","id":203694867,"node_id":"MDExOlB1bGxSZXF1ZXN0MjAzNjk0ODY3","html_url":"https://github.com/nipy/dipy/pull/1595","diff_url":"https://github.com/nipy/dipy/pull/1595.diff","patch_url":"https://github.com/nipy/dipy/pull/1595.patch","issue_url":"https://api.github.com/repos/nipy/dipy/issues/1595","number":1595,"state":"open","locked":false,"title":"Workflow for visualizing the quality of the registered data with DIPY","user":{"login":"parichit","id":12007458,"node_id":"MDQ6VXNlcjEyMDA3NDU4","avatar_url":"https://avatars2.githubusercontent.com/u/12007458?v=4","gravatar_id":"","url":"https://api.github.com/users/parichit","html_url":"https://github.com/parichit","followers_url":"https://api.github.com/users/parichit/followers","following_url":"https://api.github.com/users/parichit/following{/other_user}","gists_url":"https://api.github.com/users/parichit/gists{/gist_id}","starred_url":"https://api.github.com/users/parichit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/parichit/subscriptions","organizations_url":"https://api.github.com/users/parichit/orgs","repos_url":"https://api.github.com/users/parichit/repos","events_url":"https://api.github.com/users/parichit/events{/privacy}","received_events_url":"https://api.github.com/users/parichit/received_events","type":"User","site_admin":false},"body":"This branch is created from the older 'affine_visual' branch and only focuses on integrating the visualization support for the registered images.\r\n\r\nThese changes will form the part of the visual quality assessment in the DIPY workflows and will complement the quantitative assessment from the affine_registration branch.","created_at":"2018-07-25T01:09:11Z","updated_at":"2018-07-26T15:38:38Z","closed_at":null,"merged_at":null,"merge_commit_sha":"968d9d2b6f23dfdb2137dccc114b454328aead37","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/nipy/dipy/pulls/1595/commits","review_comments_url":"https://api.github.com/repos/nipy/dipy/pulls/1595/comments","review_comment_url":"https://api.github.com/repos/nipy/dipy/pulls/comments{/number}","comments_url":"https://api.github.com/repos/nipy/dipy/issues/1595/comments","statuses_url":"https://api.github.com/repos/nipy/dipy/statuses/09ad312dc24513e7051c877181c64c582eaac4ca","head":{"label":"parichit:visualisation_modules","ref":"visualisation_modules","sha":"09ad312dc24513e7051c877181c64c582eaac4ca","user":{"login":"parichit","id":12007458,"node_id":"MDQ6VXNlcjEyMDA3NDU4","avatar_url":"https://avatars2.githubusercontent.com/u/12007458?v=4","gravatar_id":"","url":"https://api.github.com/users/parichit","html_url":"https://github.com/parichit","followers_url":"https://api.github.com/users/parichit/followers","following_url":"https://api.github.com/users/parichit/following{/other_user}","gists_url":"https://api.github.com/users/parichit/gists{/gist_id}","starred_url":"https://api.github.com/users/parichit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/parichit/subscriptions","organizations_url":"https://api.github.com/users/parichit/orgs","repos_url":"https://api.github.com/users/parichit/repos","events_url":"https://api.github.com/users/parichit/events{/privacy}","received_events_url":"https://api.github.com/users/parichit/received_events","type":"User","site_admin":false},"repo":{"id":132988743,"node_id":"MDEwOlJlcG9zaXRvcnkxMzI5ODg3NDM=","name":"dipy","full_name":"parichit/dipy","owner":{"login":"parichit","id":12007458,"node_id":"MDQ6VXNlcjEyMDA3NDU4","avatar_url":"https://avatars2.githubusercontent.com/u/12007458?v=4","gravatar_id":"","url":"https://api.github.com/users/parichit","html_url":"https://github.com/parichit","followers_url":"https://api.github.com/users/parichit/followers","following_url":"https://api.github.com/users/parichit/following{/other_user}","gists_url":"https://api.github.com/users/parichit/gists{/gist_id}","starred_url":"https://api.github.com/users/parichit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/parichit/subscriptions","organizations_url":"https://api.github.com/users/parichit/orgs","repos_url":"https://api.github.com/users/parichit/repos","events_url":"https://api.github.com/users/parichit/events{/privacy}","received_events_url":"https://api.github.com/users/parichit/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/parichit/dipy","description":"Diffusion MR Imaging in Python","fork":true,"url":"https://api.github.com/repos/parichit/dipy","forks_url":"https://api.github.com/repos/parichit/dipy/forks","keys_url":"https://api.github.com/repos/parichit/dipy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/parichit/dipy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/parichit/dipy/teams","hooks_url":"https://api.github.com/repos/parichit/dipy/hooks","issue_events_url":"https://api.github.com/repos/parichit/dipy/issues/events{/number}","events_url":"https://api.github.com/repos/parichit/dipy/events","assignees_url":"https://api.github.com/repos/parichit/dipy/assignees{/user}","branches_url":"https://api.github.com/repos/parichit/dipy/branches{/branch}","tags_url":"https://api.github.com/repos/parichit/dipy/tags","blobs_url":"https://api.github.com/repos/parichit/dipy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/parichit/dipy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/parichit/dipy/git/refs{/sha}","trees_url":"https://api.github.com/repos/parichit/dipy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/parichit/dipy/statuses/{sha}","languages_url":"https://api.github.com/repos/parichit/dipy/languages","stargazers_url":"https://api.github.com/repos/parichit/dipy/stargazers","contributors_url":"https://api.github.com/repos/parichit/dipy/contributors","subscribers_url":"https://api.github.com/repos/parichit/dipy/subscribers","subscription_url":"https://api.github.com/repos/parichit/dipy/subscription","commits_url":"https://api.github.com/repos/parichit/dipy/commits{/sha}","git_commits_url":"https://api.github.com/repos/parichit/dipy/git/commits{/sha}","comments_url":"https://api.github.com/repos/parichit/dipy/comments{/number}","issue_comment_url":"https://api.github.com/repos/parichit/dipy/issues/comments{/number}","contents_url":"https://api.github.com/repos/parichit/dipy/contents/{+path}","compare_url":"https://api.github.com/repos/parichit/dipy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/parichit/dipy/merges","archive_url":"https://api.github.com/repos/parichit/dipy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/parichit/dipy/downloads","issues_url":"https://api.github.com/repos/parichit/dipy/issues{/number}","pulls_url":"https://api.github.com/repos/parichit/dipy/pulls{/number}","milestones_url":"https://api.github.com/repos/parichit/dipy/milestones{/number}","notifications_url":"https://api.github.com/repos/parichit/dipy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/parichit/dipy/labels{/name}","releases_url":"https://api.github.com/repos/parichit/dipy/releases{/id}","deployments_url":"https://api.github.com/repos/parichit/dipy/deployments","created_at":"2018-05-11T04:21:42Z","updated_at":"2018-05-11T04:21:45Z","pushed_at":"2018-07-26T03:10:21Z","git_url":"git://github.com/parichit/dipy.git","ssh_url":"git@github.com:parichit/dipy.git","clone_url":"https://github.com/parichit/dipy.git","svn_url":"https://github.com/parichit/dipy","homepage":"http://dipy.org","size":33008,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"nipy:master","ref":"master","sha":"b55303c02dcfc5657b429e66abd6a877e1d66d39","user":{"login":"nipy","id":233707,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIzMzcwNw==","avatar_url":"https://avatars2.githubusercontent.com/u/233707?v=4","gravatar_id":"","url":"https://api.github.com/users/nipy","html_url":"https://github.com/nipy","followers_url":"https://api.github.com/users/nipy/followers","following_url":"https://api.github.com/users/nipy/following{/other_user}","gists_url":"https://api.github.com/users/nipy/gists{/gist_id}","starred_url":"https://api.github.com/users/nipy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nipy/subscriptions","organizations_url":"https://api.github.com/users/nipy/orgs","repos_url":"https://api.github.com/users/nipy/repos","events_url":"https://api.github.com/users/nipy/events{/privacy}","received_events_url":"https://api.github.com/users/nipy/received_events","type":"Organization","site_admin":false},"repo":{"id":505209,"node_id":"MDEwOlJlcG9zaXRvcnk1MDUyMDk=","name":"dipy","full_name":"nipy/dipy","owner":{"login":"nipy","id":233707,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIzMzcwNw==","avatar_url":"https://avatars2.githubusercontent.com/u/233707?v=4","gravatar_id":"","url":"https://api.github.com/users/nipy","html_url":"https://github.com/nipy","followers_url":"https://api.github.com/users/nipy/followers","following_url":"https://api.github.com/users/nipy/following{/other_user}","gists_url":"https://api.github.com/users/nipy/gists{/gist_id}","starred_url":"https://api.github.com/users/nipy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nipy/subscriptions","organizations_url":"https://api.github.com/users/nipy/orgs","repos_url":"https://api.github.com/users/nipy/repos","events_url":"https://api.github.com/users/nipy/events{/privacy}","received_events_url":"https://api.github.com/users/nipy/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nipy/dipy","description":"Diffusion MR Imaging in Python","fork":false,"url":"https://api.github.com/repos/nipy/dipy","forks_url":"https://api.github.com/repos/nipy/dipy/forks","keys_url":"https://api.github.com/repos/nipy/dipy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nipy/dipy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nipy/dipy/teams","hooks_url":"https://api.github.com/repos/nipy/dipy/hooks","issue_events_url":"https://api.github.com/repos/nipy/dipy/issues/events{/number}","events_url":"https://api.github.com/repos/nipy/dipy/events","assignees_url":"https://api.github.com/repos/nipy/dipy/assignees{/user}","branches_url":"https://api.github.com/repos/nipy/dipy/branches{/branch}","tags_url":"https://api.github.com/repos/nipy/dipy/tags","blobs_url":"https://api.github.com/repos/nipy/dipy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nipy/dipy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nipy/dipy/git/refs{/sha}","trees_url":"https://api.github.com/repos/nipy/dipy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nipy/dipy/statuses/{sha}","languages_url":"https://api.github.com/repos/nipy/dipy/languages","stargazers_url":"https://api.github.com/repos/nipy/dipy/stargazers","contributors_url":"https://api.github.com/repos/nipy/dipy/contributors","subscribers_url":"https://api.github.com/repos/nipy/dipy/subscribers","subscription_url":"https://api.github.com/repos/nipy/dipy/subscription","commits_url":"https://api.github.com/repos/nipy/dipy/commits{/sha}","git_commits_url":"https://api.github.com/repos/nipy/dipy/git/commits{/sha}","comments_url":"https://api.github.com/repos/nipy/dipy/comments{/number}","issue_comment_url":"https://api.github.com/repos/nipy/dipy/issues/comments{/number}","contents_url":"https://api.github.com/repos/nipy/dipy/contents/{+path}","compare_url":"https://api.github.com/repos/nipy/dipy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nipy/dipy/merges","archive_url":"https://api.github.com/repos/nipy/dipy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nipy/dipy/downloads","issues_url":"https://api.github.com/repos/nipy/dipy/issues{/number}","pulls_url":"https://api.github.com/repos/nipy/dipy/pulls{/number}","milestones_url":"https://api.github.com/repos/nipy/dipy/milestones{/number}","notifications_url":"https://api.github.com/repos/nipy/dipy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nipy/dipy/labels{/name}","releases_url":"https://api.github.com/repos/nipy/dipy/releases{/id}","deployments_url":"https://api.github.com/repos/nipy/dipy/deployments","created_at":"2010-02-06T11:43:08Z","updated_at":"2018-07-26T11:30:15Z","pushed_at":"2018-07-26T14:23:42Z","git_url":"git://github.com/nipy/dipy.git","ssh_url":"git@github.com:nipy/dipy.git","clone_url":"https://github.com/nipy/dipy.git","svn_url":"https://github.com/nipy/dipy","homepage":"http://dipy.org","size":32922,"stargazers_count":175,"watchers_count":175,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":218,"mirror_url":null,"archived":false,"open_issues_count":177,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":218,"open_issues":177,"watchers":175,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/nipy/dipy/pulls/1595"},"html":{"href":"https://github.com/nipy/dipy/pull/1595"},"issue":{"href":"https://api.github.com/repos/nipy/dipy/issues/1595"},"comments":{"href":"https://api.github.com/repos/nipy/dipy/issues/1595/comments"},"review_comments":{"href":"https://api.github.com/repos/nipy/dipy/pulls/1595/comments"},"review_comment":{"href":"https://api.github.com/repos/nipy/dipy/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/nipy/dipy/pulls/1595/commits"},"statuses":{"href":"https://api.github.com/repos/nipy/dipy/statuses/09ad312dc24513e7051c877181c64c582eaac4ca"}},"author_association":"NONE"}}
{"actor":{"display_login":"nilgoyette"}}