{"action":"created","comment":{"url":"https://api.github.com/repos/PyAbel/PyAbel/pulls/comments/49206989","id":49206989,"diff_hunk":"@@ -1,11 +1,70 @@\n # -*- coding: utf-8 -*-\n import numpy as np\n+from abel.tools import index_coords, cart2polar\n \n \n # This file includes functions that have a known analytical Abel transform.\n-# They are used in unit testing as well for comparing different iAbel impementations.\n+# They are used in unit testing as well for comparing different Abel impementations.\n # See BaseAnalytical class for more information.\n \n+def sample_image_dribinski(n=361, origin=None):\n+    \"\"\"\n+    Sample test image used in the BASEX paper Rev. Sci. Instrum. 73, 2634 (2002) \n+    9x Gaussian functions of half-width 4 pixel + 1 background width 3600\n+      - anisotropy - ß = -1  for cosθ term\n+                   - ß = +2  for sinθ term\n+                   - ß =  0  isotropic, no angular variation\n+    (there are some missing negative exponents in the publication)\n+\n+    Parameters\n+    ----------\n+     - n: integer (square) image width (height)\n+     - origin: tuple,  (row, col) center of image\n+\n+    Returns\n+    -------\n+     - IM: 2D n x n numpy array image\n+\n+    \"\"\"\n+\n+    def Gauss (r, r0, sigma2):\n+        return np.exp(-(r-r0)**2/sigma2)\n+\n+    def I(r, theta):  # intensity function Eq. (16)\n+        t0 = 7*Gauss(r, 10, 4)*np.sin(theta)**2\n+        t1 = 3*Gauss(r, 15, 4)\n+        t2 = 5*Gauss(r, 20, 4)*np.cos(theta)**2\n+    \n+        t3 =   Gauss(r, 70, 4)\n+        t4 = 2*Gauss(r, 85, 4)*np.cos(theta)**2\n+        t5 =   Gauss(r, 100, 4)*np.sin(theta)**2\n+\n+        t6 = 2*Gauss(r, 145, 4)*np.sin(theta)**2\n+        t7 =   Gauss(r, 150, 4)\n+        t8 = 3*Gauss(r, 155, 4)*np.cos(theta)**2\n+\n+        t9 = 20*Gauss(r, 45, 3600)  # background under t3 to t5\n+    \n+        return 2000*(t0+t1+t2) + 200*(t3+t4+t5) + 50*(t6+t7+t8) + t9\n+\n+    # set up an dummy image 2D n x n numpy array shape \n+    im = np.arange(n*n).reshape((n,n))\n+\n+    if origin is None:\n+        origin = (n//2+n%2, n//2+n%2)\n+\n+    # determine cartesian coordinates (x,y), for each pixel\n+    x, y = index_coords(im, origin=origin)","path":"abel/analytical.py","position":58,"original_position":58,"commit_id":"f654b42069d109f114b22670fb60a15cd1af5730","original_commit_id":"f654b42069d109f114b22670fb60a15cd1af5730","user":{"login":"DanHickstein","id":1107796,"avatar_url":"https://avatars.githubusercontent.com/u/1107796?v=3","gravatar_id":"","url":"https://api.github.com/users/DanHickstein","html_url":"https://github.com/DanHickstein","followers_url":"https://api.github.com/users/DanHickstein/followers","following_url":"https://api.github.com/users/DanHickstein/following{/other_user}","gists_url":"https://api.github.com/users/DanHickstein/gists{/gist_id}","starred_url":"https://api.github.com/users/DanHickstein/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DanHickstein/subscriptions","organizations_url":"https://api.github.com/users/DanHickstein/orgs","repos_url":"https://api.github.com/users/DanHickstein/repos","events_url":"https://api.github.com/users/DanHickstein/events{/privacy}","received_events_url":"https://api.github.com/users/DanHickstein/received_events","type":"User","site_admin":false},"body":"It might be more straightforward to use meshgrid, since that's basically what you are setting up. (Also, I'm not sure if this is as real python style, but I tend to use lower-case ``x`` for variables or 1D arrays, and ``X`` for 2D arrays.) You could use:\r\n\r\n```python\r\nx = np.arange(n)\r\nX,Y = np.meshgrid(x,x)\r\nR,THETA = cart2polar(X,Y) \r\nIM = I(R,THETA)","created_at":"2016-01-08T16:28:54Z","updated_at":"2016-01-08T16:28:54Z","html_url":"https://github.com/PyAbel/PyAbel/pull/67#discussion_r49206989","pull_request_url":"https://api.github.com/repos/PyAbel/PyAbel/pulls/67","_links":{"self":{"href":"https://api.github.com/repos/PyAbel/PyAbel/pulls/comments/49206989"},"html":{"href":"https://github.com/PyAbel/PyAbel/pull/67#discussion_r49206989"},"pull_request":{"href":"https://api.github.com/repos/PyAbel/PyAbel/pulls/67"}}},"pull_request":{"url":"https://api.github.com/repos/PyAbel/PyAbel/pulls/67","id":55433545,"html_url":"https://github.com/PyAbel/PyAbel/pull/67","diff_url":"https://github.com/PyAbel/PyAbel/pull/67.diff","patch_url":"https://github.com/PyAbel/PyAbel/pull/67.patch","issue_url":"https://api.github.com/repos/PyAbel/PyAbel/issues/67","number":67,"state":"open","locked":false,"title":"Updated hansenlaw, tools, tests, examples","user":{"login":"stggh","id":10932229,"avatar_url":"https://avatars.githubusercontent.com/u/10932229?v=3","gravatar_id":"","url":"https://api.github.com/users/stggh","html_url":"https://github.com/stggh","followers_url":"https://api.github.com/users/stggh/followers","following_url":"https://api.github.com/users/stggh/following{/other_user}","gists_url":"https://api.github.com/users/stggh/gists{/gist_id}","starred_url":"https://api.github.com/users/stggh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stggh/subscriptions","organizations_url":"https://api.github.com/users/stggh/orgs","repos_url":"https://api.github.com/users/stggh/repos","events_url":"https://api.github.com/users/stggh/events{/privacy}","received_events_url":"https://api.github.com/users/stggh/received_events","type":"User","site_admin":false},"body":"I have been on a summer break (part 1 break finishes this Monday) and have made a few code changes, as discussed issue #60 (anisotropy parameter calculation), #55 (forward Abel transform using hansenlaw algorithm), issue #39 (polar grid coordinate sizes), issue #36 (consistent naming, in particular, `_abel_hansenlaw_transform_core()`, and `inverse=True/False` parameter). Top-right quadrant, `Q0` is now the orientation for the `transform` code (issue #56). I have updated the HL examples, and tools. In the `example_all_O2.py` the `three_point_transform()` did not finish in a sensible time and so has been commented out.\r\n\r\nI think it would be a good time to incorporate the changes since they provide new functionality.\r\n\r\n\r\n**NB  these changes may break legacy code** \r\n  -  calculate_speeds returns speeds, r, theta        \r\n  -  cart2polar   - angle now referenced to vertical  \r\n  -  polar2cart                                       \r\n\r\n**Summary** (in plain text - any markup is accidental!)\r\n(1)  abel/\r\n\r\n   (a) abel.hansenlaw.py\r\n\r\n   _abel_hansenlaw_transform_core  = forward and backward Abel transforms\r\n\r\n   Q0 top-right quadrant is now the default (cf the old Q1 top-left)\r\n\r\n\r\n   (b) abel.analytica.py\r\n\r\n    added sample_image_dribinski(n=361, origin=None)\r\n\r\n      to generate the BASEX model image\r\n\r\n(2) abel.tools.py\r\n\r\n    (a) calculate_speeds(IM, origin=None, Jacobian=False, dr=1, dt=None)\r\n\r\n      New parameters:\r\n       -Jacobian: multiply intensity by    r**2 sin theta\r\n\r\n       -dr: radial coordinate spacing\r\n       -dt: theta coordinate spacing (degrees) - best left as default\r\n --------\r\n\r\n    (b) calculate_angular_distributions(IM, radial_ranges=None)\r\n\r\n     This function mirrors calculate_speeds with sum along axis=0 (radius)\r\n      parameters:\r\n        - radial_ranges: tuple list [(r0, r1), (r2, r3), ...]\r\n                      Evaluate the intensity vs angle for the radial\r\n                      ranges r0_r1, r2_r3, etc.\r\n     returns\r\n        - theta, intensity-vs-theta for each radial range (ri, rj)\r\n --------\r\n\r\n    (c) center_image_by_slice(IM, slice_width=10, r_range=(0,-1),\r\n                          pixel_center=True):\r\n\r\n       Center image by comparing opposite side, vertical and\r\n       horizontal slice profiles\r\n\r\n       Parameters\r\n       ----------\r\n         - IM : rows x cols numpy array\r\n         - slice_width : add together this number of rows (cols) to improve signal\r\n\r\n         - r_range(rmin,rmax): radial range [rmin,rmax] for slide profile comparison\r\n         - pixel_center: boolean, make center of image within a pixel\r\n --------\r\n\r\n    (d) anisotropy_parameter(theta, intensity, theta_ranges=None)\r\n\r\n       Evaluates beta using least-squares fitting\r\n      (NB may be a bug with the theta range evaluation)\r\n\r\n\r\n --------\r\n\r\n    (e) reproject_image_into_polar(data, origin=None, rmax='corner', dr=1, dt=None)\r\n\r\n      new parameters\r\n            - rmax:   radius maximum, beyond which no projection is done\r\n               'corner' => sqrt((rows//2)**2+(cols//2)**2)\r\n                  - used to convert the whole cartesian image to polar\r\n               otherwise the minimum of the 1/2 width or 1/2 height of the image\r\n               = min((rows//2, cols//2)\r\n                  - used to convert only the circular region that fits within\r\n                    the image\r\n     - dr: radial coordinate spacing for the grid interpolation\r\n             tests show that there is not much point in going below 0.5\r\n     - dt: angular coordinate spacing (in degrees)\r\n\r\n --------\r\n\r\n(3) abel.tests.test_hansenlaw.py\r\n\r\n   added  \"Curve A\" functions f(r), g(R)  - these really belong in\r\n   abel/analytical.py\r\n\r\n  Modified tests to pass ;-)\r\n   hansenlaw performs better with a larger size image (pixels)\r\n   boosted n=51 -> 1001\r\n\r\n   added forward tests\r\n\r\n   Note, the comparision ratios are somewhat relaxed and could\r\n   possibly be improved. In general hansenlaw misbehaves near\r\n   the image center. This may be associated with residual origin center\r\n   issues.\r\n\r\n   To do - add further tests for anisotropy calculations\r\n\r\n(4) abel.examples\r\n\r\n     Modified hansenlaw tests to work with new calculate_speeds O/P format\r\n~                                       \r\n","created_at":"2016-01-08T07:49:10Z","updated_at":"2016-01-08T16:28:54Z","closed_at":null,"merged_at":null,"merge_commit_sha":"63175ceb2056e592802a1c2943e74df8324fb236","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/PyAbel/PyAbel/pulls/67/commits","review_comments_url":"https://api.github.com/repos/PyAbel/PyAbel/pulls/67/comments","review_comment_url":"https://api.github.com/repos/PyAbel/PyAbel/pulls/comments{/number}","comments_url":"https://api.github.com/repos/PyAbel/PyAbel/issues/67/comments","statuses_url":"https://api.github.com/repos/PyAbel/PyAbel/statuses/f654b42069d109f114b22670fb60a15cd1af5730","head":{"label":"stggh:master","ref":"master","sha":"f654b42069d109f114b22670fb60a15cd1af5730","user":{"login":"stggh","id":10932229,"avatar_url":"https://avatars.githubusercontent.com/u/10932229?v=3","gravatar_id":"","url":"https://api.github.com/users/stggh","html_url":"https://github.com/stggh","followers_url":"https://api.github.com/users/stggh/followers","following_url":"https://api.github.com/users/stggh/following{/other_user}","gists_url":"https://api.github.com/users/stggh/gists{/gist_id}","starred_url":"https://api.github.com/users/stggh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stggh/subscriptions","organizations_url":"https://api.github.com/users/stggh/orgs","repos_url":"https://api.github.com/users/stggh/repos","events_url":"https://api.github.com/users/stggh/events{/privacy}","received_events_url":"https://api.github.com/users/stggh/received_events","type":"User","site_admin":false},"repo":{"id":46905320,"name":"PyAbel","full_name":"stggh/PyAbel","owner":{"login":"stggh","id":10932229,"avatar_url":"https://avatars.githubusercontent.com/u/10932229?v=3","gravatar_id":"","url":"https://api.github.com/users/stggh","html_url":"https://github.com/stggh","followers_url":"https://api.github.com/users/stggh/followers","following_url":"https://api.github.com/users/stggh/following{/other_user}","gists_url":"https://api.github.com/users/stggh/gists{/gist_id}","starred_url":"https://api.github.com/users/stggh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stggh/subscriptions","organizations_url":"https://api.github.com/users/stggh/orgs","repos_url":"https://api.github.com/users/stggh/repos","events_url":"https://api.github.com/users/stggh/events{/privacy}","received_events_url":"https://api.github.com/users/stggh/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/stggh/PyAbel","description":"A python package for Abel and inverse Abel transforms","fork":true,"url":"https://api.github.com/repos/stggh/PyAbel","forks_url":"https://api.github.com/repos/stggh/PyAbel/forks","keys_url":"https://api.github.com/repos/stggh/PyAbel/keys{/key_id}","collaborators_url":"https://api.github.com/repos/stggh/PyAbel/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/stggh/PyAbel/teams","hooks_url":"https://api.github.com/repos/stggh/PyAbel/hooks","issue_events_url":"https://api.github.com/repos/stggh/PyAbel/issues/events{/number}","events_url":"https://api.github.com/repos/stggh/PyAbel/events","assignees_url":"https://api.github.com/repos/stggh/PyAbel/assignees{/user}","branches_url":"https://api.github.com/repos/stggh/PyAbel/branches{/branch}","tags_url":"https://api.github.com/repos/stggh/PyAbel/tags","blobs_url":"https://api.github.com/repos/stggh/PyAbel/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/stggh/PyAbel/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/stggh/PyAbel/git/refs{/sha}","trees_url":"https://api.github.com/repos/stggh/PyAbel/git/trees{/sha}","statuses_url":"https://api.github.com/repos/stggh/PyAbel/statuses/{sha}","languages_url":"https://api.github.com/repos/stggh/PyAbel/languages","stargazers_url":"https://api.github.com/repos/stggh/PyAbel/stargazers","contributors_url":"https://api.github.com/repos/stggh/PyAbel/contributors","subscribers_url":"https://api.github.com/repos/stggh/PyAbel/subscribers","subscription_url":"https://api.github.com/repos/stggh/PyAbel/subscription","commits_url":"https://api.github.com/repos/stggh/PyAbel/commits{/sha}","git_commits_url":"https://api.github.com/repos/stggh/PyAbel/git/commits{/sha}","comments_url":"https://api.github.com/repos/stggh/PyAbel/comments{/number}","issue_comment_url":"https://api.github.com/repos/stggh/PyAbel/issues/comments{/number}","contents_url":"https://api.github.com/repos/stggh/PyAbel/contents/{+path}","compare_url":"https://api.github.com/repos/stggh/PyAbel/compare/{base}...{head}","merges_url":"https://api.github.com/repos/stggh/PyAbel/merges","archive_url":"https://api.github.com/repos/stggh/PyAbel/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/stggh/PyAbel/downloads","issues_url":"https://api.github.com/repos/stggh/PyAbel/issues{/number}","pulls_url":"https://api.github.com/repos/stggh/PyAbel/pulls{/number}","milestones_url":"https://api.github.com/repos/stggh/PyAbel/milestones{/number}","notifications_url":"https://api.github.com/repos/stggh/PyAbel/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/stggh/PyAbel/labels{/name}","releases_url":"https://api.github.com/repos/stggh/PyAbel/releases{/id}","created_at":"2015-11-26T05:12:44Z","updated_at":"2015-11-26T05:12:46Z","pushed_at":"2016-01-08T10:34:46Z","git_url":"git://github.com/stggh/PyAbel.git","ssh_url":"git@github.com:stggh/PyAbel.git","clone_url":"https://github.com/stggh/PyAbel.git","svn_url":"https://github.com/stggh/PyAbel","homepage":"","size":18948,"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":"PyAbel:master","ref":"master","sha":"422ea842dd663009cbb867de717b891292e208aa","user":{"login":"PyAbel","id":15894666,"avatar_url":"https://avatars.githubusercontent.com/u/15894666?v=3","gravatar_id":"","url":"https://api.github.com/users/PyAbel","html_url":"https://github.com/PyAbel","followers_url":"https://api.github.com/users/PyAbel/followers","following_url":"https://api.github.com/users/PyAbel/following{/other_user}","gists_url":"https://api.github.com/users/PyAbel/gists{/gist_id}","starred_url":"https://api.github.com/users/PyAbel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PyAbel/subscriptions","organizations_url":"https://api.github.com/users/PyAbel/orgs","repos_url":"https://api.github.com/users/PyAbel/repos","events_url":"https://api.github.com/users/PyAbel/events{/privacy}","received_events_url":"https://api.github.com/users/PyAbel/received_events","type":"Organization","site_admin":false},"repo":{"id":30170345,"name":"PyAbel","full_name":"PyAbel/PyAbel","owner":{"login":"PyAbel","id":15894666,"avatar_url":"https://avatars.githubusercontent.com/u/15894666?v=3","gravatar_id":"","url":"https://api.github.com/users/PyAbel","html_url":"https://github.com/PyAbel","followers_url":"https://api.github.com/users/PyAbel/followers","following_url":"https://api.github.com/users/PyAbel/following{/other_user}","gists_url":"https://api.github.com/users/PyAbel/gists{/gist_id}","starred_url":"https://api.github.com/users/PyAbel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PyAbel/subscriptions","organizations_url":"https://api.github.com/users/PyAbel/orgs","repos_url":"https://api.github.com/users/PyAbel/repos","events_url":"https://api.github.com/users/PyAbel/events{/privacy}","received_events_url":"https://api.github.com/users/PyAbel/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/PyAbel/PyAbel","description":"A python package for Abel and inverse Abel transforms","fork":false,"url":"https://api.github.com/repos/PyAbel/PyAbel","forks_url":"https://api.github.com/repos/PyAbel/PyAbel/forks","keys_url":"https://api.github.com/repos/PyAbel/PyAbel/keys{/key_id}","collaborators_url":"https://api.github.com/repos/PyAbel/PyAbel/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/PyAbel/PyAbel/teams","hooks_url":"https://api.github.com/repos/PyAbel/PyAbel/hooks","issue_events_url":"https://api.github.com/repos/PyAbel/PyAbel/issues/events{/number}","events_url":"https://api.github.com/repos/PyAbel/PyAbel/events","assignees_url":"https://api.github.com/repos/PyAbel/PyAbel/assignees{/user}","branches_url":"https://api.github.com/repos/PyAbel/PyAbel/branches{/branch}","tags_url":"https://api.github.com/repos/PyAbel/PyAbel/tags","blobs_url":"https://api.github.com/repos/PyAbel/PyAbel/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/PyAbel/PyAbel/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/PyAbel/PyAbel/git/refs{/sha}","trees_url":"https://api.github.com/repos/PyAbel/PyAbel/git/trees{/sha}","statuses_url":"https://api.github.com/repos/PyAbel/PyAbel/statuses/{sha}","languages_url":"https://api.github.com/repos/PyAbel/PyAbel/languages","stargazers_url":"https://api.github.com/repos/PyAbel/PyAbel/stargazers","contributors_url":"https://api.github.com/repos/PyAbel/PyAbel/contributors","subscribers_url":"https://api.github.com/repos/PyAbel/PyAbel/subscribers","subscription_url":"https://api.github.com/repos/PyAbel/PyAbel/subscription","commits_url":"https://api.github.com/repos/PyAbel/PyAbel/commits{/sha}","git_commits_url":"https://api.github.com/repos/PyAbel/PyAbel/git/commits{/sha}","comments_url":"https://api.github.com/repos/PyAbel/PyAbel/comments{/number}","issue_comment_url":"https://api.github.com/repos/PyAbel/PyAbel/issues/comments{/number}","contents_url":"https://api.github.com/repos/PyAbel/PyAbel/contents/{+path}","compare_url":"https://api.github.com/repos/PyAbel/PyAbel/compare/{base}...{head}","merges_url":"https://api.github.com/repos/PyAbel/PyAbel/merges","archive_url":"https://api.github.com/repos/PyAbel/PyAbel/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/PyAbel/PyAbel/downloads","issues_url":"https://api.github.com/repos/PyAbel/PyAbel/issues{/number}","pulls_url":"https://api.github.com/repos/PyAbel/PyAbel/pulls{/number}","milestones_url":"https://api.github.com/repos/PyAbel/PyAbel/milestones{/number}","notifications_url":"https://api.github.com/repos/PyAbel/PyAbel/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/PyAbel/PyAbel/labels{/name}","releases_url":"https://api.github.com/repos/PyAbel/PyAbel/releases{/id}","created_at":"2015-02-02T03:59:28Z","updated_at":"2015-12-15T18:33:01Z","pushed_at":"2016-01-08T10:34:47Z","git_url":"git://github.com/PyAbel/PyAbel.git","ssh_url":"git@github.com:PyAbel/PyAbel.git","clone_url":"https://github.com/PyAbel/PyAbel.git","svn_url":"https://github.com/PyAbel/PyAbel","homepage":"","size":68131,"stargazers_count":4,"watchers_count":4,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5,"mirror_url":null,"open_issues_count":18,"forks":5,"open_issues":18,"watchers":4,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/PyAbel/PyAbel/pulls/67"},"html":{"href":"https://github.com/PyAbel/PyAbel/pull/67"},"issue":{"href":"https://api.github.com/repos/PyAbel/PyAbel/issues/67"},"comments":{"href":"https://api.github.com/repos/PyAbel/PyAbel/issues/67/comments"},"review_comments":{"href":"https://api.github.com/repos/PyAbel/PyAbel/pulls/67/comments"},"review_comment":{"href":"https://api.github.com/repos/PyAbel/PyAbel/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/PyAbel/PyAbel/pulls/67/commits"},"statuses":{"href":"https://api.github.com/repos/PyAbel/PyAbel/statuses/f654b42069d109f114b22670fb60a15cd1af5730"}}}}