{"action":"created","comment":{"url":"https://api.github.com/repos/metoppv/improver/pulls/comments/147655883","pull_request_review_id":72779852,"id":147655883,"diff_hunk":"@@ -0,0 +1,434 @@\n+# -*- coding: utf-8 -*-\n+# -----------------------------------------------------------------------------\n+# (C) British Crown Copyright 2017 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+\"\"\"Module to contain Psychrometric Calculations.\"\"\"\n+\n+import warnings\n+from cf_units import Unit\n+import improver.constants as cc\n+import numpy as np\n+import iris\n+\n+from improver.psychrometric_calculations import svp_table\n+\n+\n+class Utilities(object):\n+\n+    \"\"\"\n+    Utilities for pschrometric calculations.\n+    \"\"\"\n+\n+    def __init__(self):\n+        \"\"\"\n+        Initialise class.\n+        \"\"\"\n+        pass\n+\n+    def __repr__(self):\n+        \"\"\"Represent the configured plugin instance as a string.\"\"\"\n+        result = ('<Utilities>')\n+        return result\n+\n+    @staticmethod\n+    def specific_heat_of_moist_air(mixing_ratio):\n+        \"\"\"\n+        Calculate the specific heat capacity for moist air by combining that of\n+        dry air and water vapour in proportion given by the specific humidity.\n+\n+        Args:\n+            mixing_ratio (iris.cube.Cube):\n+                Cube of specific humidity (fractional).\n+        Returns:\n+            iris.cube.Cube:\n+                Specific heat capacity of moist air (J kg-1 K-1).\n+        \"\"\"\n+        specific_heat = ((-1.*mixing_ratio + 1.) * cc.U_CP_DRY_AIR +\n+                         mixing_ratio * cc.U_CP_WATER_VAPOUR)\n+        specific_heat.rename('specific_heat')\n+        return specific_heat\n+\n+    @staticmethod\n+    def latent_heat_of_condensation(temperature_input):\n+        \"\"\"\n+        Calculate a temperature adjusted latent heat of condensation for water\n+        vapour using the relationship employed by the UM.\n+\n+        Args:\n+            temperature_input (iris.cube.Cube):\n+                A cube of air temperatures (Celsius, converted if not).\n+        Returns:\n+            iris.cube.Cube:\n+                Temperature adjusted latent heat of condesation (J kg-1).\n+        \"\"\"\n+        temperature = temperature_input.copy()\n+        temperature.convert_units('celsius')\n+        latent_heat = (-1. * cc.U_LATENT_HEAT_T_DEPENDENCE * temperature +\n+                       cc.U_LH_CONDENSATION_WATER)\n+        latent_heat.units = cc.U_LH_CONDENSATION_WATER.units\n+        latent_heat.rename('latent_heat_of_condensation')\n+        return latent_heat\n+\n+    @staticmethod\n+    def calculate_enthalpy(mixing_ratio, specific_heat, latent_heat,\n+                           temperature):\n+        \"\"\"\n+        Calculate the enthalpy (total energy per unit mass) of air (J kg-1).\n+\n+        Args:\n+            mixing_ratio (iris.cube.Cube):\n+                Cube of mixing ratios.\n+            specific_heat (iris.cube.Cube):\n+                Cube of specific heat capacities of moist air (J kg-1 K-1).\n+            latent_heat (iris.cube.Cube):\n+                Cube of latent heats of condensation of water vapour\n+                (J kg-1).\n+            temperature (iris.cube.Cube):\n+                A cube of air temperatures (K).\n+        Returns:\n+           enthalpy (iris.cube.Cube):\n+               A cube of enthalpy values calculated at the same points as the\n+               input cubes (J kg-1).\n+        \"\"\"\n+        enthalpy = latent_heat * mixing_ratio + specific_heat * temperature\n+        enthalpy.rename('enthalpy_of_air')\n+        return enthalpy\n+\n+    @staticmethod\n+    def calculate_d_enthalpy_dt(mixing_ratio, specific_heat,\n+                                latent_heat, temperature_input):\n+        \"\"\"\n+        Calculate the enthalpy gradient with respect to temperature.\n+\n+        Args:\n+            mixing_ratio (iris.cube.Cube):\n+                Cube of mixing ratios.\n+            specific_heat (iris.cube.Cube):\n+                Cube of specific heat capacities of moist air (J kg-1 K-1).\n+            latent_heat (iris.cube.Cube):\n+                Cube of latent heats of condensation of water vapour\n+                (J kg-1).\n+            temperature_input (iris.cube.Cube):\n+                A cube of temperatures (K, or converted).\n+\n+        Returns:\n+            iris.cube.Cube:\n+                A cube of the enthalpy gradient with respect to temperature.\n+        \"\"\"\n+        temperature = temperature_input.copy()\n+        temperature.convert_units('K')\n+        numerator = (mixing_ratio * latent_heat ** 2)\n+        denominator = cc.U_R_WATER_VAPOUR * temperature ** 2\n+        return numerator/denominator + specific_heat\n+\n+    @staticmethod\n+    def saturation_vapour_pressure_goff_gratch(temperature):\n+        \"\"\"\n+        Saturation Vapour pressure in a water vapour system calculated using\n+        the Goff-Gratch Equation (WMO standard method).\n+\n+        Args:\n+            temperature (iris.cube.Cube):\n+                Cube of temperature which will be converted to Kelvin\n+                prior to calculation. Valid from 173K to 373K\n+\n+        Returns:\n+            svp (iris.cube.Cube):\n+                Cube containing the saturation vapour pressure of a pure\n+                water vapour system. A correction must be applied to the data\n+                when used to convert this to the SVP in air; see the\n+                WetBulbTemperature._pressure_correct_svp function.\n+\n+        References:\n+            Numerical data and functional relationships in science and\n+            technology. New series. Group V. Volume 4. Meteorology.\n+            Subvolume b. Physical and chemical properties of the air, P35.\n+        \"\"\"\n+        constants = {1: 10.79574,\n+                     2: 5.028,\n+                     3: 1.50475E-4,\n+                     4: -8.2969,\n+                     5: 0.42873E-3,\n+                     6: 4.76955,\n+                     7: 0.78614,\n+                     8: -9.09685,\n+                     9: 3.56654,\n+                     10: 0.87682,\n+                     11: 0.78614}\n+        triple_pt = cc.TRIPLE_PT_WATER\n+\n+        # Values for which method is considered valid (see reference).\n+        WetBulbTemperature._check_range(temperature, 173., 373.)\n+\n+        data = temperature.data.copy()\n+        for cell in np.nditer(data, op_flags=['readwrite']):\n+            if cell > triple_pt:\n+                n0 = constants[1] * (1. - triple_pt / cell)\n+                n1 = constants[2] * np.log10(cell / triple_pt)\n+                n2 = constants[3] * (1. - np.power(10.,\n+                                                   (constants[4] *\n+                                                    (cell / triple_pt - 1.))))\n+                n3 = constants[5] * (np.power(10., (constants[6] *\n+                                                    (1. - triple_pt / cell))) -\n+                                     1.)\n+                log_es = n0 - n1 + n2 + n3 + constants[7]\n+                cell[...] = (np.power(10., log_es))\n+            else:\n+                n0 = constants[8] * ((triple_pt / cell) - 1.)\n+                n1 = constants[9] * np.log10(triple_pt / cell)\n+                n2 = constants[10] * (1. - (cell / triple_pt))\n+                log_es = n0 - n1 + n2 + constants[11]\n+                cell[...] = (np.power(10., log_es))\n+\n+        # Create SVP cube\n+        svp = iris.cube.Cube(\n+            data, long_name='saturated_vapour_pressure', units='hPa')\n+        # Output of the Goff-Gratch is in hPa, but we want to return in Pa.\n+        svp.convert_units('Pa')\n+        return svp\n+\n+\n+class WetBulbTemperature(object):\n+\n+    \"\"\"\n+    A plugin to calculate wet bulb temperatures from air temperature, relative\n+    humidity, and pressure data. Calculations are performed using a Newton\n+    iterator, with saturated vapour pressures drawn from a lookup table using\n+    linear interpolation.\n+\n+    The svp_table used in this plugin is imported (see top of file). It is a\n+    table of saturated vapour pressures calculated for a range of temperatures.\n+    The import also brings in attributes that describe the range of\n+    temperatures covered by the table and the increments in the table.\n+\n+    \"\"\"\n+    def __init__(self, precision=0.005):\n+        \"\"\"\n+        Initialise class.\n+\n+        Args:\n+            precision (float):\n+                The precision to which the Newton iterator must converge before\n+                returning wet bulb temperatures.\n+        \"\"\"\n+        self.precision = precision\n+\n+    def __repr__(self):\n+        \"\"\"Represent the configured plugin instance as a string.\"\"\"\n+        result = ('<WetBulbTemperature: precision: {}>'.format(self.precision))\n+        return result\n+\n+    @staticmethod\n+    def _check_range(cube, low, high):\n+        \"\"\"Function to wrap functionality for throwing out temperatures\n+        too low or high for a method to use safely.\n+\n+        Args:\n+            cube (iris.cube.Cube):\n+                A cube of temperature.\n+\n+            low (int or float):\n+                Lowest allowable temperature for check\n+\n+            high (int or float):\n+                Highest allowable temperature for check\n+\n+        Raises:\n+            UserWarning : If any of the values in cube.data are outside the\n+                          bounds set by the low and high variables.\n+        \"\"\"\n+        if cube.data.max() > high or cube.data.min() < low:\n+            emsg = (\"Wet bulb temperatures are being calculated for conditions\"\n+                    \" beyond the valid range of the saturated vapour pressure\"\n+                    \" lookup table (< {}K or > {}K). Input cube has\\n\"\n+                    \"Lowest temperature = {}\\nHighest temperature = {}\")\n+            warnings.warn(emsg.format(low, high, cube.data.min(),\n+                                      cube.data.max()))\n+\n+    def _lookup_svp(self, temperature):\n+        \"\"\"\n+        Looks up a value for the saturation vapour pressure of water vapour\n+        using the temperature and a table of values. These tabulated values\n+        have been calculated using the utilties.ancillary_creation\n+        SaturatedVapourPressureTable plugin that uses the Goff-Gratch method.\n+\n+        Args:\n+            temperature (iris.cube.Cube):\n+                A cube of air temperatures (K).\n+        Returns:\n+            svp (iris.cube.Cube):\n+                A cube of saturated vapour pressures (Pa).\n+        \"\"\"\n+        T_min = svp_table.T_MIN\n+        T_max = svp_table.T_MAX\n+        delta_T = svp_table.T_INCREMENT\n+        self._check_range(temperature, T_min, T_max)\n+        temperatures = temperature.data\n+        T_clipped = np.clip(temperatures, T_min, T_max)","path":"lib/improver/psychrometric_calculations/psychrometric_calculations.py","position":null,"original_position":293,"commit_id":"e5fb67141672a5caf82102970355e8afe12d71db","original_commit_id":"1f95520532b7221e03698f2e1caf762fbe73840a","user":{"login":"fionaRust","id":16209648,"avatar_url":"https://avatars3.githubusercontent.com/u/16209648?v=4","gravatar_id":"","url":"https://api.github.com/users/fionaRust","html_url":"https://github.com/fionaRust","followers_url":"https://api.github.com/users/fionaRust/followers","following_url":"https://api.github.com/users/fionaRust/following{/other_user}","gists_url":"https://api.github.com/users/fionaRust/gists{/gist_id}","starred_url":"https://api.github.com/users/fionaRust/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fionaRust/subscriptions","organizations_url":"https://api.github.com/users/fionaRust/orgs","repos_url":"https://api.github.com/users/fionaRust/repos","events_url":"https://api.github.com/users/fionaRust/events{/privacy}","received_events_url":"https://api.github.com/users/fionaRust/received_events","type":"User","site_admin":false},"body":"Ok we'll leave it as it is.","created_at":"2017-10-30T09:51:27Z","updated_at":"2017-10-30T09:51:27Z","html_url":"https://github.com/metoppv/improver/pull/307#discussion_r147655883","pull_request_url":"https://api.github.com/repos/metoppv/improver/pulls/307","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/metoppv/improver/pulls/comments/147655883"},"html":{"href":"https://github.com/metoppv/improver/pull/307#discussion_r147655883"},"pull_request":{"href":"https://api.github.com/repos/metoppv/improver/pulls/307"}},"in_reply_to_id":146831659},"pull_request":{"url":"https://api.github.com/repos/metoppv/improver/pulls/307","id":147272586,"html_url":"https://github.com/metoppv/improver/pull/307","diff_url":"https://github.com/metoppv/improver/pull/307.diff","patch_url":"https://github.com/metoppv/improver/pull/307.patch","issue_url":"https://api.github.com/repos/metoppv/improver/issues/307","number":307,"state":"open","locked":false,"title":"IMPRO-337 (#290) Wet bulb temperature plugin + CLI","user":{"login":"bayliffe","id":28042362,"avatar_url":"https://avatars3.githubusercontent.com/u/28042362?v=4","gravatar_id":"","url":"https://api.github.com/users/bayliffe","html_url":"https://github.com/bayliffe","followers_url":"https://api.github.com/users/bayliffe/followers","following_url":"https://api.github.com/users/bayliffe/following{/other_user}","gists_url":"https://api.github.com/users/bayliffe/gists{/gist_id}","starred_url":"https://api.github.com/users/bayliffe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bayliffe/subscriptions","organizations_url":"https://api.github.com/users/bayliffe/orgs","repos_url":"https://api.github.com/users/bayliffe/repos","events_url":"https://api.github.com/users/bayliffe/events{/privacy}","received_events_url":"https://api.github.com/users/bayliffe/received_events","type":"User","site_admin":false},"body":"Addition of a tool to create a saturate vapour pressure look-up table and the implementation of a plugin to use this to calculate wet bulb temperatures. A CLI to return WBTs has also been written.\r\n\r\nTicket: #290 \r\n\r\nTesting:\r\n - [x] Ran tests and they passed OK\r\n - [x] Added new tests for the new feature(s)","created_at":"2017-10-18T11:17:29Z","updated_at":"2017-10-30T09:51:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"048a0fef2f8f71b8971c6517cafbfa306e3ce2cf","assignee":{"login":"bayliffe","id":28042362,"avatar_url":"https://avatars3.githubusercontent.com/u/28042362?v=4","gravatar_id":"","url":"https://api.github.com/users/bayliffe","html_url":"https://github.com/bayliffe","followers_url":"https://api.github.com/users/bayliffe/followers","following_url":"https://api.github.com/users/bayliffe/following{/other_user}","gists_url":"https://api.github.com/users/bayliffe/gists{/gist_id}","starred_url":"https://api.github.com/users/bayliffe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bayliffe/subscriptions","organizations_url":"https://api.github.com/users/bayliffe/orgs","repos_url":"https://api.github.com/users/bayliffe/repos","events_url":"https://api.github.com/users/bayliffe/events{/privacy}","received_events_url":"https://api.github.com/users/bayliffe/received_events","type":"User","site_admin":false},"assignees":[{"login":"bayliffe","id":28042362,"avatar_url":"https://avatars3.githubusercontent.com/u/28042362?v=4","gravatar_id":"","url":"https://api.github.com/users/bayliffe","html_url":"https://github.com/bayliffe","followers_url":"https://api.github.com/users/bayliffe/followers","following_url":"https://api.github.com/users/bayliffe/following{/other_user}","gists_url":"https://api.github.com/users/bayliffe/gists{/gist_id}","starred_url":"https://api.github.com/users/bayliffe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bayliffe/subscriptions","organizations_url":"https://api.github.com/users/bayliffe/orgs","repos_url":"https://api.github.com/users/bayliffe/repos","events_url":"https://api.github.com/users/bayliffe/events{/privacy}","received_events_url":"https://api.github.com/users/bayliffe/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/metoppv/improver/pulls/307/commits","review_comments_url":"https://api.github.com/repos/metoppv/improver/pulls/307/comments","review_comment_url":"https://api.github.com/repos/metoppv/improver/pulls/comments{/number}","comments_url":"https://api.github.com/repos/metoppv/improver/issues/307/comments","statuses_url":"https://api.github.com/repos/metoppv/improver/statuses/e5fb67141672a5caf82102970355e8afe12d71db","head":{"label":"bayliffe:WBTMethod","ref":"WBTMethod","sha":"e5fb67141672a5caf82102970355e8afe12d71db","user":{"login":"bayliffe","id":28042362,"avatar_url":"https://avatars3.githubusercontent.com/u/28042362?v=4","gravatar_id":"","url":"https://api.github.com/users/bayliffe","html_url":"https://github.com/bayliffe","followers_url":"https://api.github.com/users/bayliffe/followers","following_url":"https://api.github.com/users/bayliffe/following{/other_user}","gists_url":"https://api.github.com/users/bayliffe/gists{/gist_id}","starred_url":"https://api.github.com/users/bayliffe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bayliffe/subscriptions","organizations_url":"https://api.github.com/users/bayliffe/orgs","repos_url":"https://api.github.com/users/bayliffe/repos","events_url":"https://api.github.com/users/bayliffe/events{/privacy}","received_events_url":"https://api.github.com/users/bayliffe/received_events","type":"User","site_admin":false},"repo":{"id":89453063,"name":"improver","full_name":"bayliffe/improver","owner":{"login":"bayliffe","id":28042362,"avatar_url":"https://avatars3.githubusercontent.com/u/28042362?v=4","gravatar_id":"","url":"https://api.github.com/users/bayliffe","html_url":"https://github.com/bayliffe","followers_url":"https://api.github.com/users/bayliffe/followers","following_url":"https://api.github.com/users/bayliffe/following{/other_user}","gists_url":"https://api.github.com/users/bayliffe/gists{/gist_id}","starred_url":"https://api.github.com/users/bayliffe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bayliffe/subscriptions","organizations_url":"https://api.github.com/users/bayliffe/orgs","repos_url":"https://api.github.com/users/bayliffe/repos","events_url":"https://api.github.com/users/bayliffe/events{/privacy}","received_events_url":"https://api.github.com/users/bayliffe/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bayliffe/improver","description":"IMPROVER","fork":true,"url":"https://api.github.com/repos/bayliffe/improver","forks_url":"https://api.github.com/repos/bayliffe/improver/forks","keys_url":"https://api.github.com/repos/bayliffe/improver/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bayliffe/improver/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bayliffe/improver/teams","hooks_url":"https://api.github.com/repos/bayliffe/improver/hooks","issue_events_url":"https://api.github.com/repos/bayliffe/improver/issues/events{/number}","events_url":"https://api.github.com/repos/bayliffe/improver/events","assignees_url":"https://api.github.com/repos/bayliffe/improver/assignees{/user}","branches_url":"https://api.github.com/repos/bayliffe/improver/branches{/branch}","tags_url":"https://api.github.com/repos/bayliffe/improver/tags","blobs_url":"https://api.github.com/repos/bayliffe/improver/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bayliffe/improver/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bayliffe/improver/git/refs{/sha}","trees_url":"https://api.github.com/repos/bayliffe/improver/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bayliffe/improver/statuses/{sha}","languages_url":"https://api.github.com/repos/bayliffe/improver/languages","stargazers_url":"https://api.github.com/repos/bayliffe/improver/stargazers","contributors_url":"https://api.github.com/repos/bayliffe/improver/contributors","subscribers_url":"https://api.github.com/repos/bayliffe/improver/subscribers","subscription_url":"https://api.github.com/repos/bayliffe/improver/subscription","commits_url":"https://api.github.com/repos/bayliffe/improver/commits{/sha}","git_commits_url":"https://api.github.com/repos/bayliffe/improver/git/commits{/sha}","comments_url":"https://api.github.com/repos/bayliffe/improver/comments{/number}","issue_comment_url":"https://api.github.com/repos/bayliffe/improver/issues/comments{/number}","contents_url":"https://api.github.com/repos/bayliffe/improver/contents/{+path}","compare_url":"https://api.github.com/repos/bayliffe/improver/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bayliffe/improver/merges","archive_url":"https://api.github.com/repos/bayliffe/improver/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bayliffe/improver/downloads","issues_url":"https://api.github.com/repos/bayliffe/improver/issues{/number}","pulls_url":"https://api.github.com/repos/bayliffe/improver/pulls{/number}","milestones_url":"https://api.github.com/repos/bayliffe/improver/milestones{/number}","notifications_url":"https://api.github.com/repos/bayliffe/improver/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bayliffe/improver/labels{/name}","releases_url":"https://api.github.com/repos/bayliffe/improver/releases{/id}","deployments_url":"https://api.github.com/repos/bayliffe/improver/deployments","created_at":"2017-04-26T07:45:39Z","updated_at":"2017-04-26T07:47:12Z","pushed_at":"2017-10-27T15:29:50Z","git_url":"git://github.com/bayliffe/improver.git","ssh_url":"git@github.com:bayliffe/improver.git","clone_url":"https://github.com/bayliffe/improver.git","svn_url":"https://github.com/bayliffe/improver","homepage":null,"size":1797,"stargazers_count":1,"watchers_count":1,"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,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"metoppv:master","ref":"master","sha":"be0f355cfbad7d72391c370978ea55872d6b53f8","user":{"login":"metoppv","id":26465485,"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,"name":"improver","full_name":"metoppv/improver","owner":{"login":"metoppv","id":26465485,"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":"2017-10-25T21:54:21Z","pushed_at":"2017-10-27T15:29:52Z","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":"","size":1772,"stargazers_count":4,"watchers_count":4,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":19,"mirror_url":null,"archived":false,"open_issues_count":100,"forks":19,"open_issues":100,"watchers":4,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/metoppv/improver/pulls/307"},"html":{"href":"https://github.com/metoppv/improver/pull/307"},"issue":{"href":"https://api.github.com/repos/metoppv/improver/issues/307"},"comments":{"href":"https://api.github.com/repos/metoppv/improver/issues/307/comments"},"review_comments":{"href":"https://api.github.com/repos/metoppv/improver/pulls/307/comments"},"review_comment":{"href":"https://api.github.com/repos/metoppv/improver/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/metoppv/improver/pulls/307/commits"},"statuses":{"href":"https://api.github.com/repos/metoppv/improver/statuses/e5fb67141672a5caf82102970355e8afe12d71db"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"fionaRust"}}