{"action":"created","comment":{"url":"https://api.github.com/repos/ska-sa/katdal/pulls/comments/181303234","pull_request_review_id":111903571,"id":181303234,"diff_hunk":"@@ -0,0 +1,400 @@\n+################################################################################\n+# Copyright (c) 2017-2018, National Research Foundation (Square Kilometre Array)\n+#\n+# Licensed under the BSD 3-Clause License (the \"License\"); you may not use\n+# this file except in compliance with the License. You may obtain a copy\n+# of the License at\n+#\n+#   https://opensource.org/licenses/BSD-3-Clause\n+#\n+# Unless required by applicable law or agreed to in writing, software\n+# distributed under the License is distributed on an \"AS IS\" BASIS,\n+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+# See the License for the specific language governing permissions and\n+# limitations under the License.\n+################################################################################\n+\n+\"\"\"Function to apply TelescopeState calibration to visibilities.\n+\n+Hold, interpolate and apply cal solutions from a katdal object.\n+Code largely pilfered from the katdal_loader in katsdpimager, but using a katdal object\n+rather than a filename, so that things are a bit more portable. \"\"\"\n+\n+import dask.array as da\n+import numpy as np\n+\n+from .lazy_indexer import LazyTransform\n+from .sensordata import _safe_linear_interp\n+\n+\n+class CalibrationReadError(RuntimeError):\n+    \"\"\"An error occurred in loading calibration values from file\"\"\"\n+    pass\n+\n+\n+class CalibrationValueError(ValueError):\n+    \"\"\"An error occurred in the calculation of calibration coefficients\"\"\"\n+    pass\n+\n+\n+class SimpleInterpolate1D(object):\n+    def __init__(self, x, y):\n+        self._x = x\n+        self._y = y\n+\n+    def __call__(self, x):\n+        y_re = np.empty((x.shape[0], self._y.shape[1], self._y.shape[2], self._y.shape[3]))\n+        y_im = np.empty((x.shape[0], self._y.shape[1], self._y.shape[2], self._y.shape[3]))\n+        # Interpolate across nans in time axis.\n+        for ch_idx in range(self._y.shape[1]):\n+            for pol_idx in range(self._y.shape[2]):\n+                for ant_idx in range(self._y.shape[3]):\n+                    y_re[:, ch_idx, pol_idx, ant_idx] = _safe_linear_interp(self._x,\n+                                                                            self._y[:, ch_idx, pol_idx, ant_idx].real,\n+                                                                            x)\n+                    y_im[:, ch_idx, pol_idx, ant_idx] = _safe_linear_interp(self._x,\n+                                                                            self._y[:, ch_idx, pol_idx, ant_idx].imag,\n+                                                                            x)\n+        y = y_re + y_im\n+        return y\n+\n+\n+class ComplexInterpolate1D(object):\n+    def __init__(self, x, y):\n+        self._x = x\n+        self._y = y\n+        self._mag = np.abs(y)\n+        self._phase = y / self._mag\n+\n+    def __call__(self, x):\n+        mag = np.empty((x.shape[0], self._y.shape[1], self._y.shape[2], self._y.shape[3]))\n+        phase_re = np.empty((x.shape[0], self._y.shape[1], self._y.shape[2], self._y.shape[3]))\n+        phase_im = np.empty((x.shape[0], self._y.shape[1], self._y.shape[2], self._y.shape[3]))\n+        # Interpolate across nans in time axis.\n+        for ch_idx in range(self._y.shape[1]):\n+            for pol_idx in range(self._y.shape[2]):\n+                for ant_idx in range(self._y.shape[3]):\n+                    mag[:, ch_idx, pol_idx, ant_idx] = _safe_linear_interp(self._x,\n+                                                                           self._mag[:, ch_idx, pol_idx, ant_idx],\n+                                                                           x)\n+                    phase_re[:, ch_idx, pol_idx, ant_idx] = _safe_linear_interp(self._x,\n+                                                                                self._phase[:, ch_idx, pol_idx, ant_idx].real,\n+                                                                                x)\n+                    phase_im[:, ch_idx, pol_idx, ant_idx] = _safe_linear_interp(self._x,\n+                                                                                self._phase[:, ch_idx, pol_idx, ant_idx].imag,\n+                                                                                x)\n+        phase = phase_re + phase_im\n+        return phase / np.abs(phase) * mag\n+\n+\n+def interpolate_nans_1d(y):\n+    \"\"\"Interpolate over nans in a timeseries.\n+\n+    When interpolating the per-channel timeseries, the channels with more\n+    nan values will deviate from the neighboring channels appearing as spikes\n+    when the mean over time is plotted.\n+    \"\"\"\n+    if np.isnan(y).all():\n+        return y  # nothing to do, all nan values\n+    if np.isfinite(y).all():\n+        return y  # nothing to do, all values valid\n+\n+    # interpolate across nans\n+    nan_locs = np.isnan(y)\n+    xi = np.nonzero(~nan_locs)[0]\n+    yi = y[xi]\n+    x = np.arange(len(y))\n+    y = _safe_linear_interp(xi, yi, x)\n+    return y\n+\n+\n+def _get_cal_sensor(key, katdal_obj):\n+    \"\"\"Load a calibrator solution from sensors.\n+    \"\"\"\n+    values = []\n+    timestamps = []\n+    for sensor in katdal_obj.file['TelescopeState'].keys():\n+        if key in sensor:\n+            value = katdal_obj.sensor['TelescopeState/{}'.format(sensor)]\n+            timestamp = katdal_obj.sensor.timestamps\n+            try:\n+                values = np.vstack((values, value))\n+                timestamps = np.vstack((timestamps, timestamp))\n+            except ValueError:\n+                values = np.asarray(value)\n+                timestamps = np.asarray(timestamp)\n+    timestamps = np.reshape(timestamps, timestamps.size)\n+    if timestamps.size > 1:\n+        timestamps = timestamps.squeeze()\n+    return timestamps, values\n+\n+\n+def _get_cal_antlist(katdal_obj):\n+    \"\"\"Load antenna list used for calibration.\n+    If the value does not match the antenna list in the katdal dataset,\n+    a :exc:`CalibrationReadError` is raised. Eventually this could be\n+    extended to allow for an antenna list that doesn't match by permuting\n+    the calibration solutions.\n+    \"\"\"\n+    cal_antlist = katdal_obj._get_telstate_attr('cal_antlist')\n+    if isinstance(cal_antlist, np.ndarray):\n+        cal_antlist = cal_antlist.tolist()\n+    if cal_antlist != [ant.name for ant in katdal_obj.ants]:\n+        raise CalibrationReadError('cal_antlist does not match katdal antenna list')\n+    return cal_antlist\n+\n+\n+def _get_cal_pol_ordering(katdal_obj):\n+    \"\"\"Load polarization ordering used by calibration solutions.\n+\n+    Returns\n+    -------\n+    dict\n+        Keys are 'h' and 'v' and values are 0 and 1, in some order\n+    \"\"\"\n+    cal_pol_ordering = katdal_obj._get_telstate_attr('cal_pol_ordering')\n+    try:\n+        cal_pol_ordering = np.array(cal_pol_ordering)\n+    except (NameError, SyntaxError):\n+        raise\n+    except Exception as e:\n+        raise CalibrationReadError(str(e))\n+\n+    if cal_pol_ordering.shape != (4, 2):\n+        # assume newer telstate format\n+        pol_dict = {}\n+        for idx, pol in enumerate(cal_pol_ordering):\n+            pol_dict[pol] = idx\n+        return pol_dict\n+\n+    # older format needs more work\n+    if cal_pol_ordering[0, 0] != cal_pol_ordering[0, 1]:\n+        raise CalibrationReadError('cal_pol_ordering[0] is not consistent')\n+    if cal_pol_ordering[1, 0] != cal_pol_ordering[1, 1]:\n+        raise CalibrationReadError('cal_pol_ordering[1] is not consistent')\n+    order = [cal_pol_ordering[0, 0], cal_pol_ordering[1, 0]]\n+    if set(order) != set('vh'):\n+        raise CalibrationReadError('cal_pol_ordering does not contain h and v')\n+    return {order[0]: 0, order[1]: 1}\n+\n+\n+def _get_cal_product(key, katdal_obj, **kwargs):\n+    \"\"\"Loads calibration solutions from a katdal file.\n+\n+    If an error occurs while loading the data, a warning is printed and the\n+    return value is ``None``. Any keyword args are passed to\n+    :func:`SimpleInterplate1D` or `ComplexInterpolate1D`.","path":"katdal/caldata.py","position":186,"original_position":186,"commit_id":"f04b6f344e9e7ccb8a8e687f3683000aba5064ec","original_commit_id":"f04b6f344e9e7ccb8a8e687f3683000aba5064ec","user":{"login":"bmerry","id":1963944,"avatar_url":"https://avatars1.githubusercontent.com/u/1963944?v=4","gravatar_id":"","url":"https://api.github.com/users/bmerry","html_url":"https://github.com/bmerry","followers_url":"https://api.github.com/users/bmerry/followers","following_url":"https://api.github.com/users/bmerry/following{/other_user}","gists_url":"https://api.github.com/users/bmerry/gists{/gist_id}","starred_url":"https://api.github.com/users/bmerry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bmerry/subscriptions","organizations_url":"https://api.github.com/users/bmerry/orgs","repos_url":"https://api.github.com/users/bmerry/repos","events_url":"https://api.github.com/users/bmerry/events{/privacy}","received_events_url":"https://api.github.com/users/bmerry/received_events","type":"User","site_admin":false},"body":"Missing `o` in `SimpleInterplate1D`. `:func:` should be `:class:` and ComplexInterpolate1D should also have the `:class:` prefix.","created_at":"2018-04-13T07:16:13Z","updated_at":"2018-04-13T08:02:32Z","html_url":"https://github.com/ska-sa/katdal/pull/131#discussion_r181303234","pull_request_url":"https://api.github.com/repos/ska-sa/katdal/pulls/131","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/ska-sa/katdal/pulls/comments/181303234"},"html":{"href":"https://github.com/ska-sa/katdal/pull/131#discussion_r181303234"},"pull_request":{"href":"https://api.github.com/repos/ska-sa/katdal/pulls/131"}}},"pull_request":{"url":"https://api.github.com/repos/ska-sa/katdal/pulls/131","id":175872734,"html_url":"https://github.com/ska-sa/katdal/pull/131","diff_url":"https://github.com/ska-sa/katdal/pull/131.diff","patch_url":"https://github.com/ska-sa/katdal/pull/131.patch","issue_url":"https://api.github.com/repos/ska-sa/katdal/issues/131","number":131,"state":"open","locked":false,"title":"Applycal using numpy arrays","user":{"login":"rubyvanrooyen","id":1318643,"avatar_url":"https://avatars2.githubusercontent.com/u/1318643?v=4","gravatar_id":"","url":"https://api.github.com/users/rubyvanrooyen","html_url":"https://github.com/rubyvanrooyen","followers_url":"https://api.github.com/users/rubyvanrooyen/followers","following_url":"https://api.github.com/users/rubyvanrooyen/following{/other_user}","gists_url":"https://api.github.com/users/rubyvanrooyen/gists{/gist_id}","starred_url":"https://api.github.com/users/rubyvanrooyen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rubyvanrooyen/subscriptions","organizations_url":"https://api.github.com/users/rubyvanrooyen/orgs","repos_url":"https://api.github.com/users/rubyvanrooyen/repos","events_url":"https://api.github.com/users/rubyvanrooyen/events{/privacy}","received_events_url":"https://api.github.com/users/rubyvanrooyen/received_events","type":"User","site_admin":false},"body":"I am reasonably sure this caldata implementation works on smallish files or on systems with a large RAM.\r\n\r\nWould like to merge with master here to delete the current branch.\r\nWill create a new branch for optimisation with large matrices","created_at":"2018-03-19T11:34:41Z","updated_at":"2018-04-13T08:02:32Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8a42356ed22f867ab552fa907bb4e82286b2fba1","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/ska-sa/katdal/pulls/131/commits","review_comments_url":"https://api.github.com/repos/ska-sa/katdal/pulls/131/comments","review_comment_url":"https://api.github.com/repos/ska-sa/katdal/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ska-sa/katdal/issues/131/comments","statuses_url":"https://api.github.com/repos/ska-sa/katdal/statuses/f04b6f344e9e7ccb8a8e687f3683000aba5064ec","head":{"label":"ska-sa:applycal","ref":"applycal","sha":"f04b6f344e9e7ccb8a8e687f3683000aba5064ec","user":{"login":"ska-sa","id":1210238,"avatar_url":"https://avatars3.githubusercontent.com/u/1210238?v=4","gravatar_id":"","url":"https://api.github.com/users/ska-sa","html_url":"https://github.com/ska-sa","followers_url":"https://api.github.com/users/ska-sa/followers","following_url":"https://api.github.com/users/ska-sa/following{/other_user}","gists_url":"https://api.github.com/users/ska-sa/gists{/gist_id}","starred_url":"https://api.github.com/users/ska-sa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ska-sa/subscriptions","organizations_url":"https://api.github.com/users/ska-sa/orgs","repos_url":"https://api.github.com/users/ska-sa/repos","events_url":"https://api.github.com/users/ska-sa/events{/privacy}","received_events_url":"https://api.github.com/users/ska-sa/received_events","type":"Organization","site_admin":false},"repo":{"id":12869013,"name":"katdal","full_name":"ska-sa/katdal","owner":{"login":"ska-sa","id":1210238,"avatar_url":"https://avatars3.githubusercontent.com/u/1210238?v=4","gravatar_id":"","url":"https://api.github.com/users/ska-sa","html_url":"https://github.com/ska-sa","followers_url":"https://api.github.com/users/ska-sa/followers","following_url":"https://api.github.com/users/ska-sa/following{/other_user}","gists_url":"https://api.github.com/users/ska-sa/gists{/gist_id}","starred_url":"https://api.github.com/users/ska-sa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ska-sa/subscriptions","organizations_url":"https://api.github.com/users/ska-sa/orgs","repos_url":"https://api.github.com/users/ska-sa/repos","events_url":"https://api.github.com/users/ska-sa/events{/privacy}","received_events_url":"https://api.github.com/users/ska-sa/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ska-sa/katdal","description":"Data access library for the MeerKAT project","fork":false,"url":"https://api.github.com/repos/ska-sa/katdal","forks_url":"https://api.github.com/repos/ska-sa/katdal/forks","keys_url":"https://api.github.com/repos/ska-sa/katdal/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ska-sa/katdal/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ska-sa/katdal/teams","hooks_url":"https://api.github.com/repos/ska-sa/katdal/hooks","issue_events_url":"https://api.github.com/repos/ska-sa/katdal/issues/events{/number}","events_url":"https://api.github.com/repos/ska-sa/katdal/events","assignees_url":"https://api.github.com/repos/ska-sa/katdal/assignees{/user}","branches_url":"https://api.github.com/repos/ska-sa/katdal/branches{/branch}","tags_url":"https://api.github.com/repos/ska-sa/katdal/tags","blobs_url":"https://api.github.com/repos/ska-sa/katdal/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ska-sa/katdal/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ska-sa/katdal/git/refs{/sha}","trees_url":"https://api.github.com/repos/ska-sa/katdal/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ska-sa/katdal/statuses/{sha}","languages_url":"https://api.github.com/repos/ska-sa/katdal/languages","stargazers_url":"https://api.github.com/repos/ska-sa/katdal/stargazers","contributors_url":"https://api.github.com/repos/ska-sa/katdal/contributors","subscribers_url":"https://api.github.com/repos/ska-sa/katdal/subscribers","subscription_url":"https://api.github.com/repos/ska-sa/katdal/subscription","commits_url":"https://api.github.com/repos/ska-sa/katdal/commits{/sha}","git_commits_url":"https://api.github.com/repos/ska-sa/katdal/git/commits{/sha}","comments_url":"https://api.github.com/repos/ska-sa/katdal/comments{/number}","issue_comment_url":"https://api.github.com/repos/ska-sa/katdal/issues/comments{/number}","contents_url":"https://api.github.com/repos/ska-sa/katdal/contents/{+path}","compare_url":"https://api.github.com/repos/ska-sa/katdal/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ska-sa/katdal/merges","archive_url":"https://api.github.com/repos/ska-sa/katdal/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ska-sa/katdal/downloads","issues_url":"https://api.github.com/repos/ska-sa/katdal/issues{/number}","pulls_url":"https://api.github.com/repos/ska-sa/katdal/pulls{/number}","milestones_url":"https://api.github.com/repos/ska-sa/katdal/milestones{/number}","notifications_url":"https://api.github.com/repos/ska-sa/katdal/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ska-sa/katdal/labels{/name}","releases_url":"https://api.github.com/repos/ska-sa/katdal/releases{/id}","deployments_url":"https://api.github.com/repos/ska-sa/katdal/deployments","created_at":"2013-09-16T14:12:17Z","updated_at":"2018-04-10T13:26:59Z","pushed_at":"2018-04-11T13:29:52Z","git_url":"git://github.com/ska-sa/katdal.git","ssh_url":"git@github.com:ska-sa/katdal.git","clone_url":"https://github.com/ska-sa/katdal.git","svn_url":"https://github.com/ska-sa/katdal","homepage":"","size":1156,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"archived":false,"open_issues_count":8,"license":{"key":"bsd-3-clause","name":"BSD 3-Clause \"New\" or \"Revised\" License","spdx_id":"BSD-3-Clause","url":"https://api.github.com/licenses/bsd-3-clause"},"forks":4,"open_issues":8,"watchers":3,"default_branch":"master"}},"base":{"label":"ska-sa:master","ref":"master","sha":"49bf3f160134e0ff88eba0a6d551e31cc5710d5d","user":{"login":"ska-sa","id":1210238,"avatar_url":"https://avatars3.githubusercontent.com/u/1210238?v=4","gravatar_id":"","url":"https://api.github.com/users/ska-sa","html_url":"https://github.com/ska-sa","followers_url":"https://api.github.com/users/ska-sa/followers","following_url":"https://api.github.com/users/ska-sa/following{/other_user}","gists_url":"https://api.github.com/users/ska-sa/gists{/gist_id}","starred_url":"https://api.github.com/users/ska-sa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ska-sa/subscriptions","organizations_url":"https://api.github.com/users/ska-sa/orgs","repos_url":"https://api.github.com/users/ska-sa/repos","events_url":"https://api.github.com/users/ska-sa/events{/privacy}","received_events_url":"https://api.github.com/users/ska-sa/received_events","type":"Organization","site_admin":false},"repo":{"id":12869013,"name":"katdal","full_name":"ska-sa/katdal","owner":{"login":"ska-sa","id":1210238,"avatar_url":"https://avatars3.githubusercontent.com/u/1210238?v=4","gravatar_id":"","url":"https://api.github.com/users/ska-sa","html_url":"https://github.com/ska-sa","followers_url":"https://api.github.com/users/ska-sa/followers","following_url":"https://api.github.com/users/ska-sa/following{/other_user}","gists_url":"https://api.github.com/users/ska-sa/gists{/gist_id}","starred_url":"https://api.github.com/users/ska-sa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ska-sa/subscriptions","organizations_url":"https://api.github.com/users/ska-sa/orgs","repos_url":"https://api.github.com/users/ska-sa/repos","events_url":"https://api.github.com/users/ska-sa/events{/privacy}","received_events_url":"https://api.github.com/users/ska-sa/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ska-sa/katdal","description":"Data access library for the MeerKAT project","fork":false,"url":"https://api.github.com/repos/ska-sa/katdal","forks_url":"https://api.github.com/repos/ska-sa/katdal/forks","keys_url":"https://api.github.com/repos/ska-sa/katdal/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ska-sa/katdal/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ska-sa/katdal/teams","hooks_url":"https://api.github.com/repos/ska-sa/katdal/hooks","issue_events_url":"https://api.github.com/repos/ska-sa/katdal/issues/events{/number}","events_url":"https://api.github.com/repos/ska-sa/katdal/events","assignees_url":"https://api.github.com/repos/ska-sa/katdal/assignees{/user}","branches_url":"https://api.github.com/repos/ska-sa/katdal/branches{/branch}","tags_url":"https://api.github.com/repos/ska-sa/katdal/tags","blobs_url":"https://api.github.com/repos/ska-sa/katdal/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ska-sa/katdal/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ska-sa/katdal/git/refs{/sha}","trees_url":"https://api.github.com/repos/ska-sa/katdal/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ska-sa/katdal/statuses/{sha}","languages_url":"https://api.github.com/repos/ska-sa/katdal/languages","stargazers_url":"https://api.github.com/repos/ska-sa/katdal/stargazers","contributors_url":"https://api.github.com/repos/ska-sa/katdal/contributors","subscribers_url":"https://api.github.com/repos/ska-sa/katdal/subscribers","subscription_url":"https://api.github.com/repos/ska-sa/katdal/subscription","commits_url":"https://api.github.com/repos/ska-sa/katdal/commits{/sha}","git_commits_url":"https://api.github.com/repos/ska-sa/katdal/git/commits{/sha}","comments_url":"https://api.github.com/repos/ska-sa/katdal/comments{/number}","issue_comment_url":"https://api.github.com/repos/ska-sa/katdal/issues/comments{/number}","contents_url":"https://api.github.com/repos/ska-sa/katdal/contents/{+path}","compare_url":"https://api.github.com/repos/ska-sa/katdal/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ska-sa/katdal/merges","archive_url":"https://api.github.com/repos/ska-sa/katdal/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ska-sa/katdal/downloads","issues_url":"https://api.github.com/repos/ska-sa/katdal/issues{/number}","pulls_url":"https://api.github.com/repos/ska-sa/katdal/pulls{/number}","milestones_url":"https://api.github.com/repos/ska-sa/katdal/milestones{/number}","notifications_url":"https://api.github.com/repos/ska-sa/katdal/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ska-sa/katdal/labels{/name}","releases_url":"https://api.github.com/repos/ska-sa/katdal/releases{/id}","deployments_url":"https://api.github.com/repos/ska-sa/katdal/deployments","created_at":"2013-09-16T14:12:17Z","updated_at":"2018-04-10T13:26:59Z","pushed_at":"2018-04-11T13:29:52Z","git_url":"git://github.com/ska-sa/katdal.git","ssh_url":"git@github.com:ska-sa/katdal.git","clone_url":"https://github.com/ska-sa/katdal.git","svn_url":"https://github.com/ska-sa/katdal","homepage":"","size":1156,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"archived":false,"open_issues_count":8,"license":{"key":"bsd-3-clause","name":"BSD 3-Clause \"New\" or \"Revised\" License","spdx_id":"BSD-3-Clause","url":"https://api.github.com/licenses/bsd-3-clause"},"forks":4,"open_issues":8,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ska-sa/katdal/pulls/131"},"html":{"href":"https://github.com/ska-sa/katdal/pull/131"},"issue":{"href":"https://api.github.com/repos/ska-sa/katdal/issues/131"},"comments":{"href":"https://api.github.com/repos/ska-sa/katdal/issues/131/comments"},"review_comments":{"href":"https://api.github.com/repos/ska-sa/katdal/pulls/131/comments"},"review_comment":{"href":"https://api.github.com/repos/ska-sa/katdal/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ska-sa/katdal/pulls/131/commits"},"statuses":{"href":"https://api.github.com/repos/ska-sa/katdal/statuses/f04b6f344e9e7ccb8a8e687f3683000aba5064ec"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"bmerry"}}