{"action":"created","comment":{"url":"https://api.github.com/repos/metoppv/improver/pulls/comments/204692415","pull_request_review_id":139793404,"id":204692415,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwNDY5MjQxNQ==","diff_hunk":"@@ -0,0 +1,367 @@\n+# -*- coding: utf-8 -*-\n+# -----------------------------------------------------------------------------\n+# (C) British Crown Copyright 2017-2018 Met Office.\n+# All rights reserved.\n+#\n+# Redistribution and use in source and binary forms, with or without\n+# modification, are permitted provided that the following conditions are met:\n+#\n+# * Redistributions of source code must retain the above copyright notice, this\n+#   list of conditions and the following disclaimer.\n+#\n+# * Redistributions in binary form must reproduce the above copyright notice,\n+#   this list of conditions and the following disclaimer in the documentation\n+#   and/or other materials provided with the distribution.\n+#\n+# * Neither the name of the copyright holder nor the names of its\n+#   contributors may be used to endorse or promote products derived from\n+#   this software without specific prior written permission.\n+#\n+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n+# POSSIBILITY OF SUCH DAMAGE.\n+\"\"\"Unit tests for the LapseRate plugin.\"\"\"\n+\n+import numpy as np\n+import unittest\n+\n+import cf_units\n+from iris.cube import Cube\n+from iris.tests import IrisTest\n+from iris.coords import (DimCoord,\n+                         AuxCoord)\n+\n+from improver.grids import STANDARD_GRID_CCRS\n+\n+from improver.lapse_rate import LapseRate\n+\n+\n+def reset_cube_data(temperature_cube, orography_cube, land_sea_mask_cube):\n+    \"\"\" Resets the cube data to its defaults. \"\"\"\n+    temperature_cube.data[:, :, :] = 0\n+    orography_cube.data[:] = 0\n+    land_sea_mask_cube.data[:] = 1\n+\n+\n+class Test__repr__(IrisTest):\n+    \"\"\"Test the repr method.\"\"\"\n+\n+    def test_basic(self):\n+        \"\"\"Test that the __repr__ returns the expected string.\"\"\"\n+        result = str(LapseRate())\n+        msg = ('<LapseRate>')\n+        self.assertEqual(result, msg)\n+\n+\n+class Test_calc_lapse_rate(IrisTest):\n+    \"\"\"Test the _calc_lapse_rate function.\"\"\"\n+\n+    def setUp(self):\n+        \"\"\"Sets up arrays.\"\"\"\n+\n+        self.temperature = np.array([280.06, 279.97, 279.90, 280.15, 280.03,\n+                                     279.96, 280.25, 280.33, 280.27])\n+        self.orography = np.array([174.67, 179.87, 188.46, 155.84, 169.58,\n+                                   185.05, 134.90, 144.00, 157.89])\n+\n+    def test_returns_expected_values(self):\n+        \"\"\"Test that the function returns expected lapse rate. \"\"\"\n+\n+        expected_out = -0.00765005774676\n+        result = LapseRate()._calc_lapse_rate(self.temperature, self.orography)\n+        self.assertArrayAlmostEqual(result, expected_out)\n+\n+    def test_handles_nan(self):\n+        \"\"\"Test that the function returns a blank value when central point\n+           is NaN.\"\"\"\n+\n+        self.temperature[4] = np.nan\n+        expected_out = 0.0\n+        result = LapseRate()._calc_lapse_rate(self.temperature, self.orography)\n+        self.assertArrayAlmostEqual(result, expected_out)\n+\n+\n+class Test_create_heightdiff_mask(IrisTest):\n+    \"\"\"Test the _create_heightdiff_mask function.\"\"\"\n+\n+    def setUp(self):\n+        \"\"\"Sets up arrays.\"\"\"\n+\n+        self.orography = np.array([[35, 40, 20, 10, 0, 10, 20, -30, -40],\n+                                   [35, 40, 20, 10, 0, 10, 20, -30, -40]])\n+\n+    def test_returns_expected_values(self):\n+        \"\"\"Test that the function returns True at points where the height\n+           difference to the central pixel is greater than 35m.\"\"\"\n+\n+        expected_out = np.array(\n+            [[True, True, False, False, False, False, False, False, True],\n+             [True, True, False, False, False, False, False, False, True]])\n+\n+        result = LapseRate()._create_heightdiff_mask(self.orography)\n+        self.assertArrayAlmostEqual(result, expected_out)\n+\n+    def test_change_height_thresh(self):\n+        \"\"\"Test that the function performs as expected when the height\n+           difference threshold has been changed.\"\"\"\n+\n+        expected_out = np.array(\n+            [[False, True, False, False, False, False, False, False, True],\n+             [False, True, False, False, False, False, False, False, True]])\n+\n+        result = LapseRate(max_height_diff=40)._create_heightdiff_mask(\n+            self.orography)\n+        self.assertArrayAlmostEqual(result, expected_out)\n+\n+\n+class Test_process(IrisTest):\n+    \"\"\"Test the LapseRate processing works\"\"\"\n+\n+    def setUp(self):\n+        \"\"\"Create cubes containing a regular grid.\"\"\"\n+\n+        grid_size = 5\n+        data = np.zeros((1, grid_size, grid_size))\n+\n+        realization = DimCoord([0], 'realization', units=1)\n+        time = DimCoord([402192.5], standard_name='time',\n+                        units=cf_units.Unit('hours since 1970-01-01 00:00:00',\n+                                            calendar='gregorian'))\n+        projection_y = DimCoord(np.arange(0, grid_size, 1),\n+                                'projection_y_coordinate',\n+                                units='m',\n+                                coord_system=STANDARD_GRID_CCRS)\n+        projection_x = DimCoord(np.arange(0, grid_size, 1),\n+                                'projection_x_coordinate',\n+                                units='m',\n+                                coord_system=STANDARD_GRID_CCRS)\n+\n+        # Set up temperature cube.\n+        self.temperature = Cube(data, standard_name='air_temperature',\n+                                dim_coords_and_dims=[(realization, 0),\n+                                                     (projection_y, 1),\n+                                                     (projection_x, 2)],\n+                                units='K')\n+\n+        self.temperature.add_aux_coord(time)\n+        height = AuxCoord([1.5], standard_name='height', units='m')\n+        self.temperature.add_aux_coord(height)\n+        self.temperature.attributes['institution'] = 'Met Office'\n+\n+        # Copies temperature cube to create orography cube.\n+        self.orography = self.temperature.copy()[0]\n+        self.orography.remove_coord('realization')\n+        self.orography.rename('surface_altitude')\n+        self.orography.units = cf_units.Unit('m')\n+\n+        # Copies orography cube to create land/sea mask cube.\n+        self.land_sea_mask = self.orography.copy()\n+        self.land_sea_mask.rename('land_binary_mask')\n+        self.land_sea_mask.units = cf_units.Unit('1')\n+\n+    def test_basic(self):\n+        \"\"\"Test that the plugin returns expected data type. \"\"\"\n+\n+        result = LapseRate().process(self.temperature, self.orography,\n+                                     self.land_sea_mask)\n+        self.assertIsInstance(result, Cube)\n+\n+    def test_fails_if_data_is_not_cube(self):\n+        \"\"\"Test code raises a Type Error if input cubes are not cubes.\"\"\"\n+        incorrect_input = 50.0\n+\n+        msg = 'Temperature input is not a cube, but {0}'.format(\n+            type(incorrect_input))\n+        with self.assertRaisesRegexp(TypeError, msg):\n+            LapseRate().process(incorrect_input, self.orography,\n+                                self.land_sea_mask)\n+\n+        msg = 'Orography input is not a cube, but {0}'.format(\n+            type(incorrect_input))\n+        with self.assertRaisesRegexp(TypeError, msg):\n+            LapseRate().process(self.temperature, incorrect_input,\n+                                self.land_sea_mask)\n+\n+        msg = 'Land/Sea mask input is not a cube, but {0}'.format(\n+            type(incorrect_input))\n+        with self.assertRaisesRegexp(TypeError, msg):\n+            LapseRate().process(self.temperature, self.orography,\n+                                incorrect_input)\n+\n+    def test_fails_if_cube_wrong_units(self):\n+        \"\"\"Test code raises a Value Error if input cubes are the\n+           wrong units.\"\"\"\n+\n+        # Copies cube and converts to wrong units.\n+        incorrect_temp = self.temperature.copy()\n+        incorrect_temp.convert_units('celsius')\n+        incorrect_orog = self.orography.copy()\n+        incorrect_orog.convert_units('feet')\n+\n+        msg = 'Temperature cube units are {}, must be Kelvin!'.format(\n+           incorrect_temp.units)\n+        with self.assertRaisesRegexp(ValueError, msg):\n+            LapseRate().process(incorrect_temp, self.orography,\n+                                self.land_sea_mask)\n+\n+        msg = 'Orography cube units are {}, must be metres!'.format(\n+           incorrect_orog.units)\n+        with self.assertRaisesRegexp(ValueError, msg):\n+            LapseRate().process(self.temperature, incorrect_orog,\n+                                self.land_sea_mask)\n+\n+    def test_return_single_precision(self):\n+        \"\"\"Test that the function returns cube of float32.\"\"\"\n+        result = LapseRate().process(self.temperature, self.orography,\n+                                     self.land_sea_mask)\n+        self.assertEqual(result.dtype, np.float32)\n+\n+    def test_constant_temp_orog(self):\n+        \"\"\"Test that the function returns expected 0.01980198 values where the\n+           temperature and orography fields are constant values.\n+           This value is because, where the data is such that the gradient\n+           value is meaningless, then numpy.linalg.lstsq will calculate\n+           the gradient assuming that the intercept is zero.\n+           The mathematical validity of this approach is unclear. The FORTRAN\n+           code used in the operational system has statements that catch\n+           odd gradient values and subistuite them with DALR. This will\n+           require further investigation.\n+        \"\"\"","path":"lib/improver/tests/lapse_rate/Test_LapseRate.py","position":237,"original_position":237,"commit_id":"edb32077347944aadea19bc237daad106d523a2c","original_commit_id":"edb32077347944aadea19bc237daad106d523a2c","user":{"login":"cgsandford","id":35029690,"node_id":"MDQ6VXNlcjM1MDI5Njkw","avatar_url":"https://avatars1.githubusercontent.com/u/35029690?v=4","gravatar_id":"","url":"https://api.github.com/users/cgsandford","html_url":"https://github.com/cgsandford","followers_url":"https://api.github.com/users/cgsandford/followers","following_url":"https://api.github.com/users/cgsandford/following{/other_user}","gists_url":"https://api.github.com/users/cgsandford/gists{/gist_id}","starred_url":"https://api.github.com/users/cgsandford/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cgsandford/subscriptions","organizations_url":"https://api.github.com/users/cgsandford/orgs","repos_url":"https://api.github.com/users/cgsandford/repos","events_url":"https://api.github.com/users/cgsandford/events{/privacy}","received_events_url":"https://api.github.com/users/cgsandford/received_events","type":"User","site_admin":false},"body":"This doesn't need to be all in this docstring.  Please move discussion of the validity of the current method to the relevant JIRA ticket.","created_at":"2018-07-24T09:51:03Z","updated_at":"2018-07-24T09:54:59Z","html_url":"https://github.com/metoppv/improver/pull/603#discussion_r204692415","pull_request_url":"https://api.github.com/repos/metoppv/improver/pulls/603","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/metoppv/improver/pulls/comments/204692415"},"html":{"href":"https://github.com/metoppv/improver/pull/603#discussion_r204692415"},"pull_request":{"href":"https://api.github.com/repos/metoppv/improver/pulls/603"}}},"pull_request":{"url":"https://api.github.com/repos/metoppv/improver/pulls/603","id":201243808,"node_id":"MDExOlB1bGxSZXF1ZXN0MjAxMjQzODA4","html_url":"https://github.com/metoppv/improver/pull/603","diff_url":"https://github.com/metoppv/improver/pull/603.diff","patch_url":"https://github.com/metoppv/improver/pull/603.patch","issue_url":"https://api.github.com/repos/metoppv/improver/issues/603","number":603,"state":"open","locked":false,"title":"Added Lapse Rate code and basic test","user":{"login":"MarkWorsfold","id":35810969,"node_id":"MDQ6VXNlcjM1ODEwOTY5","avatar_url":"https://avatars2.githubusercontent.com/u/35810969?v=4","gravatar_id":"","url":"https://api.github.com/users/MarkWorsfold","html_url":"https://github.com/MarkWorsfold","followers_url":"https://api.github.com/users/MarkWorsfold/followers","following_url":"https://api.github.com/users/MarkWorsfold/following{/other_user}","gists_url":"https://api.github.com/users/MarkWorsfold/gists{/gist_id}","starred_url":"https://api.github.com/users/MarkWorsfold/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MarkWorsfold/subscriptions","organizations_url":"https://api.github.com/users/MarkWorsfold/orgs","repos_url":"https://api.github.com/users/MarkWorsfold/repos","events_url":"https://api.github.com/users/MarkWorsfold/events{/privacy}","received_events_url":"https://api.github.com/users/MarkWorsfold/received_events","type":"User","site_admin":false},"body":"Addresses #GitHubissuenum\r\n\r\nDescription:\r\nCreated basic Lapse Rate code - there are unresolved questions which are highlighted in the doc string for the class.\r\nI have added an extremely basic unit test file, this is not intended to be the finished version. It is simply to allow the user to run the code themselves using a simplistic dataset.\r\n\r\nTesting:\r\n - [ x] Ran tests and they passed OK\r\n - [ x] Added new tests for the new feature(s)\r\n","created_at":"2018-07-13T10:00:32Z","updated_at":"2018-07-24T09:54:59Z","closed_at":null,"merged_at":null,"merge_commit_sha":"25d44cc132bf93e0f46fbedc0931c4c2123fca73","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/metoppv/improver/pulls/603/commits","review_comments_url":"https://api.github.com/repos/metoppv/improver/pulls/603/comments","review_comment_url":"https://api.github.com/repos/metoppv/improver/pulls/comments{/number}","comments_url":"https://api.github.com/repos/metoppv/improver/issues/603/comments","statuses_url":"https://api.github.com/repos/metoppv/improver/statuses/edb32077347944aadea19bc237daad106d523a2c","head":{"label":"MarkWorsfold:IMPRO_683","ref":"IMPRO_683","sha":"edb32077347944aadea19bc237daad106d523a2c","user":{"login":"MarkWorsfold","id":35810969,"node_id":"MDQ6VXNlcjM1ODEwOTY5","avatar_url":"https://avatars2.githubusercontent.com/u/35810969?v=4","gravatar_id":"","url":"https://api.github.com/users/MarkWorsfold","html_url":"https://github.com/MarkWorsfold","followers_url":"https://api.github.com/users/MarkWorsfold/followers","following_url":"https://api.github.com/users/MarkWorsfold/following{/other_user}","gists_url":"https://api.github.com/users/MarkWorsfold/gists{/gist_id}","starred_url":"https://api.github.com/users/MarkWorsfold/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MarkWorsfold/subscriptions","organizations_url":"https://api.github.com/users/MarkWorsfold/orgs","repos_url":"https://api.github.com/users/MarkWorsfold/repos","events_url":"https://api.github.com/users/MarkWorsfold/events{/privacy}","received_events_url":"https://api.github.com/users/MarkWorsfold/received_events","type":"User","site_admin":false},"repo":{"id":120636183,"node_id":"MDEwOlJlcG9zaXRvcnkxMjA2MzYxODM=","name":"improver","full_name":"MarkWorsfold/improver","owner":{"login":"MarkWorsfold","id":35810969,"node_id":"MDQ6VXNlcjM1ODEwOTY5","avatar_url":"https://avatars2.githubusercontent.com/u/35810969?v=4","gravatar_id":"","url":"https://api.github.com/users/MarkWorsfold","html_url":"https://github.com/MarkWorsfold","followers_url":"https://api.github.com/users/MarkWorsfold/followers","following_url":"https://api.github.com/users/MarkWorsfold/following{/other_user}","gists_url":"https://api.github.com/users/MarkWorsfold/gists{/gist_id}","starred_url":"https://api.github.com/users/MarkWorsfold/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MarkWorsfold/subscriptions","organizations_url":"https://api.github.com/users/MarkWorsfold/orgs","repos_url":"https://api.github.com/users/MarkWorsfold/repos","events_url":"https://api.github.com/users/MarkWorsfold/events{/privacy}","received_events_url":"https://api.github.com/users/MarkWorsfold/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/MarkWorsfold/improver","description":"IMPROVER is a library of algorithms for meteorological post-processing and verification.","fork":true,"url":"https://api.github.com/repos/MarkWorsfold/improver","forks_url":"https://api.github.com/repos/MarkWorsfold/improver/forks","keys_url":"https://api.github.com/repos/MarkWorsfold/improver/keys{/key_id}","collaborators_url":"https://api.github.com/repos/MarkWorsfold/improver/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/MarkWorsfold/improver/teams","hooks_url":"https://api.github.com/repos/MarkWorsfold/improver/hooks","issue_events_url":"https://api.github.com/repos/MarkWorsfold/improver/issues/events{/number}","events_url":"https://api.github.com/repos/MarkWorsfold/improver/events","assignees_url":"https://api.github.com/repos/MarkWorsfold/improver/assignees{/user}","branches_url":"https://api.github.com/repos/MarkWorsfold/improver/branches{/branch}","tags_url":"https://api.github.com/repos/MarkWorsfold/improver/tags","blobs_url":"https://api.github.com/repos/MarkWorsfold/improver/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/MarkWorsfold/improver/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/MarkWorsfold/improver/git/refs{/sha}","trees_url":"https://api.github.com/repos/MarkWorsfold/improver/git/trees{/sha}","statuses_url":"https://api.github.com/repos/MarkWorsfold/improver/statuses/{sha}","languages_url":"https://api.github.com/repos/MarkWorsfold/improver/languages","stargazers_url":"https://api.github.com/repos/MarkWorsfold/improver/stargazers","contributors_url":"https://api.github.com/repos/MarkWorsfold/improver/contributors","subscribers_url":"https://api.github.com/repos/MarkWorsfold/improver/subscribers","subscription_url":"https://api.github.com/repos/MarkWorsfold/improver/subscription","commits_url":"https://api.github.com/repos/MarkWorsfold/improver/commits{/sha}","git_commits_url":"https://api.github.com/repos/MarkWorsfold/improver/git/commits{/sha}","comments_url":"https://api.github.com/repos/MarkWorsfold/improver/comments{/number}","issue_comment_url":"https://api.github.com/repos/MarkWorsfold/improver/issues/comments{/number}","contents_url":"https://api.github.com/repos/MarkWorsfold/improver/contents/{+path}","compare_url":"https://api.github.com/repos/MarkWorsfold/improver/compare/{base}...{head}","merges_url":"https://api.github.com/repos/MarkWorsfold/improver/merges","archive_url":"https://api.github.com/repos/MarkWorsfold/improver/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/MarkWorsfold/improver/downloads","issues_url":"https://api.github.com/repos/MarkWorsfold/improver/issues{/number}","pulls_url":"https://api.github.com/repos/MarkWorsfold/improver/pulls{/number}","milestones_url":"https://api.github.com/repos/MarkWorsfold/improver/milestones{/number}","notifications_url":"https://api.github.com/repos/MarkWorsfold/improver/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/MarkWorsfold/improver/labels{/name}","releases_url":"https://api.github.com/repos/MarkWorsfold/improver/releases{/id}","deployments_url":"https://api.github.com/repos/MarkWorsfold/improver/deployments","created_at":"2018-02-07T15:53:28Z","updated_at":"2018-02-07T15:53:30Z","pushed_at":"2018-07-24T08:13:17Z","git_url":"git://github.com/MarkWorsfold/improver.git","ssh_url":"git@github.com:MarkWorsfold/improver.git","clone_url":"https://github.com/MarkWorsfold/improver.git","svn_url":"https://github.com/MarkWorsfold/improver","homepage":"http://improver.readthedocs.io/en/latest/","size":3581,"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":"metoppv:master","ref":"master","sha":"0bdce4a95be28353302e38218dca4f7036fefaf1","user":{"login":"metoppv","id":26465485,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI2NDY1NDg1","avatar_url":"https://avatars2.githubusercontent.com/u/26465485?v=4","gravatar_id":"","url":"https://api.github.com/users/metoppv","html_url":"https://github.com/metoppv","followers_url":"https://api.github.com/users/metoppv/followers","following_url":"https://api.github.com/users/metoppv/following{/other_user}","gists_url":"https://api.github.com/users/metoppv/gists{/gist_id}","starred_url":"https://api.github.com/users/metoppv/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/metoppv/subscriptions","organizations_url":"https://api.github.com/users/metoppv/orgs","repos_url":"https://api.github.com/users/metoppv/repos","events_url":"https://api.github.com/users/metoppv/events{/privacy}","received_events_url":"https://api.github.com/users/metoppv/received_events","type":"Organization","site_admin":false},"repo":{"id":85334761,"node_id":"MDEwOlJlcG9zaXRvcnk4NTMzNDc2MQ==","name":"improver","full_name":"metoppv/improver","owner":{"login":"metoppv","id":26465485,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI2NDY1NDg1","avatar_url":"https://avatars2.githubusercontent.com/u/26465485?v=4","gravatar_id":"","url":"https://api.github.com/users/metoppv","html_url":"https://github.com/metoppv","followers_url":"https://api.github.com/users/metoppv/followers","following_url":"https://api.github.com/users/metoppv/following{/other_user}","gists_url":"https://api.github.com/users/metoppv/gists{/gist_id}","starred_url":"https://api.github.com/users/metoppv/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/metoppv/subscriptions","organizations_url":"https://api.github.com/users/metoppv/orgs","repos_url":"https://api.github.com/users/metoppv/repos","events_url":"https://api.github.com/users/metoppv/events{/privacy}","received_events_url":"https://api.github.com/users/metoppv/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/metoppv/improver","description":"IMPROVER is a library of algorithms for meteorological post-processing and verification.","fork":false,"url":"https://api.github.com/repos/metoppv/improver","forks_url":"https://api.github.com/repos/metoppv/improver/forks","keys_url":"https://api.github.com/repos/metoppv/improver/keys{/key_id}","collaborators_url":"https://api.github.com/repos/metoppv/improver/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/metoppv/improver/teams","hooks_url":"https://api.github.com/repos/metoppv/improver/hooks","issue_events_url":"https://api.github.com/repos/metoppv/improver/issues/events{/number}","events_url":"https://api.github.com/repos/metoppv/improver/events","assignees_url":"https://api.github.com/repos/metoppv/improver/assignees{/user}","branches_url":"https://api.github.com/repos/metoppv/improver/branches{/branch}","tags_url":"https://api.github.com/repos/metoppv/improver/tags","blobs_url":"https://api.github.com/repos/metoppv/improver/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/metoppv/improver/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/metoppv/improver/git/refs{/sha}","trees_url":"https://api.github.com/repos/metoppv/improver/git/trees{/sha}","statuses_url":"https://api.github.com/repos/metoppv/improver/statuses/{sha}","languages_url":"https://api.github.com/repos/metoppv/improver/languages","stargazers_url":"https://api.github.com/repos/metoppv/improver/stargazers","contributors_url":"https://api.github.com/repos/metoppv/improver/contributors","subscribers_url":"https://api.github.com/repos/metoppv/improver/subscribers","subscription_url":"https://api.github.com/repos/metoppv/improver/subscription","commits_url":"https://api.github.com/repos/metoppv/improver/commits{/sha}","git_commits_url":"https://api.github.com/repos/metoppv/improver/git/commits{/sha}","comments_url":"https://api.github.com/repos/metoppv/improver/comments{/number}","issue_comment_url":"https://api.github.com/repos/metoppv/improver/issues/comments{/number}","contents_url":"https://api.github.com/repos/metoppv/improver/contents/{+path}","compare_url":"https://api.github.com/repos/metoppv/improver/compare/{base}...{head}","merges_url":"https://api.github.com/repos/metoppv/improver/merges","archive_url":"https://api.github.com/repos/metoppv/improver/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/metoppv/improver/downloads","issues_url":"https://api.github.com/repos/metoppv/improver/issues{/number}","pulls_url":"https://api.github.com/repos/metoppv/improver/pulls{/number}","milestones_url":"https://api.github.com/repos/metoppv/improver/milestones{/number}","notifications_url":"https://api.github.com/repos/metoppv/improver/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/metoppv/improver/labels{/name}","releases_url":"https://api.github.com/repos/metoppv/improver/releases{/id}","deployments_url":"https://api.github.com/repos/metoppv/improver/deployments","created_at":"2017-03-17T16:51:29Z","updated_at":"2018-07-19T14:29:07Z","pushed_at":"2018-07-24T09:07:29Z","git_url":"git://github.com/metoppv/improver.git","ssh_url":"git@github.com:metoppv/improver.git","clone_url":"https://github.com/metoppv/improver.git","svn_url":"https://github.com/metoppv/improver","homepage":"http://improver.readthedocs.io/en/latest/","size":3611,"stargazers_count":17,"watchers_count":17,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":28,"mirror_url":null,"archived":false,"open_issues_count":106,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":28,"open_issues":106,"watchers":17,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/metoppv/improver/pulls/603"},"html":{"href":"https://github.com/metoppv/improver/pull/603"},"issue":{"href":"https://api.github.com/repos/metoppv/improver/issues/603"},"comments":{"href":"https://api.github.com/repos/metoppv/improver/issues/603/comments"},"review_comments":{"href":"https://api.github.com/repos/metoppv/improver/pulls/603/comments"},"review_comment":{"href":"https://api.github.com/repos/metoppv/improver/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/metoppv/improver/pulls/603/commits"},"statuses":{"href":"https://api.github.com/repos/metoppv/improver/statuses/edb32077347944aadea19bc237daad106d523a2c"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"cgsandford"}}