{"action":"created","comment":{"url":"https://api.github.com/repos/UT-CHG/BET/pulls/comments/71374233","id":71374233,"diff_hunk":"@@ -0,0 +1,561 @@\n+# Copyright (C) 2014-2016 The BET Development Team\n+\n+r\"\"\" \n+This module provides methods for calulating error estimates of \n+the probability measure for calculate probability measures.\n+\n+* :mod:`~bet.calculateErrors.cell_connectivity_exact` calculates \n+the connectivity of cells.\n+* :mod:`~bet.calculateErrors.boundary_sets` calculates which cells are \n+on the boundary and strictly interior for contour events.\n+* :class:`~bet.calculateErrors.sampling_error` is for calculating error\n+estimates due to sampling\n+* :class:`~bet.calculateErrors.model_error` is for calculating error\n+estimates due to error in solution of QoIs\n+\n+\"\"\"\n+\n+from bet.Comm import comm, MPI \n+import numpy as np\n+import math\n+import logging\n+import scipy.spatial as spatial\n+import bet.util as util\n+import bet.calculateP.calculateP as calculateP\n+import bet.sample as samp\n+\n+class wrong_argument_type(Exception):\n+    \"\"\"\n+    Exception for when the argument is not one of the acceptible\n+    types.\n+    \"\"\"\n+class type_not_yet_written(Exception):\n+    \"\"\"\n+    Exception for when the method is not yet written.\n+    \"\"\"\n+\n+def cell_connectivity_exact(disc):\n+    \"\"\"\n+    \n+    Calculates contour events of the cells and its neighbors\n+\n+    :param disc: An object containing the discretization information.\n+    :type disc: class:`bet.sample.discretization`\n+\n+    :rtype: list\n+    :returns: list of lists of neighboring cells\n+\n+    \"\"\"\n+    from scipy.spatial import Delaunay\n+    from collections import defaultdict\n+    import itertools\n+    import numpy.linalg as nlinalg\n+\n+    # Check inputs\n+    if not isinstance(disc, samp.discretization):\n+        msg = \"The argument must be of type bet.sample.discretization.\"\n+        raise wrong_argument_type(msg)\n+\n+    if not isinstance(disc._input_sample_set, samp.voronoi_sample_set):\n+        msg = \"disc._input_sample_set must be of type bet.sample.voronoi_sample_set defined with the 2-norm\"\n+        raise wrong_argument_type(msg)\n+    elif disc._input_sample_set._p_norm != 2.0:\n+        msg = \"disc._input_sample_set must be of type bet.sample.voronoi_sample_set defined with the 2-norm\"\n+        raise wrong_argument_type(msg)\n+\n+    num = disc.check_nums()\n+    # Set up necessary pointers\n+    if disc.get_io_ptr() is None:\n+        disc.set_io_ptr()\n+        \n+    if disc._input_sample_set._dim == 1:\n+        s_sort = disc._input_sample_set._values.flat[:].argsort()\n+        neiList = defaultdict(set)\n+        for p in range(num): \n+            order = s_sort[p]\n+            if order > 0:\n+                val = np.equal(s_sort, order - 1)\n+                args  = np.argwhere(val)                \n+                neiList[p].add(disc._io_ptr[args[0][0]])\n+                neiList[args[0][0]].add(disc._io_ptr[p])\n+    else:\n+        # Form Delaunay triangulation\n+        tri = Delaunay(disc._input_sample_set._values)\n+\n+        # Find neighbors\n+        neiList = defaultdict(set)\n+        for p in tri.vertices:\n+            for i,j in itertools.combinations(p,2):\n+                neiList[i].add(disc._io_ptr[j])\n+                neiList[j].add(disc._io_ptr[i])\n+    # Get rid of redundant entries\n+    for i in range(num):\n+        neiList[i] = list(set(neiList[i]))\n+\n+    return neiList\n+\n+def boundary_sets(disc, nei_list):\n+    \"\"\"\n+    \n+    Calculates the the neighboring Voronoi cells for each cell.\n+\n+    :param disc: An object containing the discretization information.\n+    :type disc: class:`bet.sample.discretization`\n+    :param nei_list: list of lists defining contour events of neighboring cells.\n+    :type nei_list: list\n+\n+    :rtype: tuple\n+    :returns: (B_N, C_N) as defined in Butler et al. 2015.\n+\n+    \"\"\"\n+    from collections import defaultdict\n+\n+    # Check inputs\n+    if not isinstance(disc, samp.discretization):\n+        msg = \"The argument must be of type bet.sample.discretization.\"\n+        raise wrong_argument_type(msg)\n+\n+    if not isinstance(disc._input_sample_set, samp.voronoi_sample_set):\n+        msg = \"disc._input_sample_set must be of type bet.sample.voronoi_sample_set defined with the 2-norm\"\n+        raise wrong_argument_type(msg)\n+    elif disc._input_sample_set._p_norm != 2.0:\n+\n+        msg = \"disc._input_sample_set must be of type bet.sample.voronoi_sample_set defined with the 2-norm\"\n+        raise wrong_argument_type(msg)\n+\n+    num = disc.check_nums()\n+    \n+    # Form necessary pointers\n+    if disc.get_io_ptr() is None:\n+        disc.set_io_ptr()\n+    # Define strictly interior and boundary cells for each contour event\n+    B_N = defaultdict(list)\n+    C_N = defaultdict(list)\n+    for i in range(num):\n+        contour_event = disc._io_ptr[i]\n+        if nei_list[i] == [contour_event]:\n+            B_N[contour_event].append(i)\n+        for j in nei_list[i]:\n+            C_N[j].append(i)\n+    \n+    return (B_N, C_N)\n+\n+class sampling_error(object):\n+    \"\"\"\n+    A class for calculating the error due to sampling for a discretization.\n+    \"\"\"\n+    def __init__(self, disc, exact=True):\n+        \"\"\"\n+          \n+        Set things up for a given discretization\n+          \n+        :param disc: An object containing the discretization information.\n+        :type disc: class:`bet.sample.discretization`\n+        :param exact: Whether or not to use exact connectivity\n+        :type exact: bool\n+        \n+        \"\"\"\n+        # Check inputs\n+        if not isinstance(disc, samp.discretization):\n+            msg = \"The argument must be of type bet.sample.discretization.\"\n+            raise wrong_argument_type(msg)\n+\n+        self.disc = disc \n+        self.num = self.disc.check_nums()\n+\n+        # Set up neighbor list and B_N and C_N\n+        if exact:\n+            nei_list = cell_connectivity_exact(self.disc)\n+        else:\n+            msg = \"sampling_error only handles exact connectivity for now.\"\n+            raise type_not_yet_written(msg)\n+        \n+        (self.B_N, self.C_N) = boundary_sets(self.disc, nei_list)\n+        \n+    def calculate_for_contour_events(self):\n+        \"\"\"\n+        Calculate the sampling error bounds for each contour event.\n+\n+        :rtype tuple\n+        :returns: (up_list, low_list) where up_list is a list of\n+        the upper bounds for each contour event and low_list is a list\n+        of the lower bounds.\n+\n+        \"\"\"\n+        up_list = []\n+        low_list = []\n+        # Check for and possibly calculate volumes\n+        if self.disc._input_sample_set._volumes is None:\n+            if self.disc._emulated_input_sample_set is not None:\n+                logging.warning(\"Using emulated points to estimate volumes.\")\n+                self.disc._input_sample_set.estimate_volume_emulated(self.disc._emulated_input_sample_set)\n+            else:\n+                logging.warning(\"Making MC assumption to estimate volumes.\")\n+                self.disc._input_sample_set.estimate_volume_mc()\n+\n+        # Loop over contour events and calculate error bounds\n+        ops_num = self.disc._output_probability_set.check_num()\n+        for i in range(ops_num):\n+            if self.disc._output_probability_set._probabilities[i] > 0.0:\n+                lam_vol = np.zeros((self.num,))\n+                indices = np.equal(self.disc._io_ptr,i)\n+                lam_vol[indices] = self.disc._input_sample_set._volumes[indices]\n+                if i in self.B_N:\n+                    val1 = np.sum(self.disc._input_sample_set._volumes[self.B_N[i]])\n+                    val2 = np.sum(lam_vol[self.B_N[i]])\n+                \n+                    val3 = np.sum(self.disc._input_sample_set._volumes[self.C_N[i]])\n+                    val4 = np.sum(lam_vol[self.C_N[i]])\n+                \n+                    term1 = val2/val3 - 1.0\n+                    term2 = val4/val1 - 1.0\n+                    up_list.append(self.disc._output_probability_set._probabilities[i]*max(term1,term2))\n+                    low_list.append(self.disc._output_probability_set._probabilities[i]*min(term1,term2))\n+                else:\n+                    up_list.append(float('nan'))\n+                    low_list.append(float('nan'))\n+                \n+            else:\n+                up_list.append(0.0)\n+                low_list.append(0.0)\n+\n+        return (up_list, low_list)\n+\n+    def calculate_for_sample_set_region(self, s_set, \n+                                     region, emulated_set=None):\n+        \"\"\"\n+        Calculate the sampling error bounds for a region of the input space\n+        defined by a sample set object.\n+\n+        :param s_set: sample set for which to calculate error\n+        :type s_set: :class:`bet.sample.sample_set_base`\n+        :param region: region of s_set for which to calculate error\n+        :type region: int\n+        :param emulated_set: sample set for volume emulation\n+        :type emulated_set: :class:`bet.sample_set_base`\n+\n+        :rtype tuple\n+        :returns: (upper_bound, lower_bound) the upper and lower bounds\n+        for the error.\n+\n+        \"\"\"\n+        # Set up marker\n+        self.disc._input_sample_set.local_to_global()\n+        if s_set._region is None:\n+            msg = \"regions must be defined for the sample set.\"\n+            raise wrong_argument_type(msg)\n+        marker = np.equal(s_set._region, region)\n+        if not np.any(marker):\n+            msg = \"The given region does not exist.\"\n+            raise wrong_argument_type(msg)\n+            \n+            \n+        # Set up discretizations\n+        if emulated_set is not None:\n+            disc = self.disc.copy()\n+            disc.set_emulated_input_sample_set(emulated_set)\n+            disc.set_emulated_ii_ptr(globalize=False)\n+            disc_new = samp.discretization(input_sample_set = s_set,\n+                                           output_sample_set = s_set,\n+                                           emulated_input_sample_set = emulated_set)\n+            disc_new.set_emulated_ii_ptr(globalize=False)\n+        elif self.disc._emulated_input_sample_set is not None:\n+            logging.warning(\"Using emulated_input_sample_set for volume emulation\")\n+            disc = self.disc\n+            if disc._emulated_ii_ptr is None:\n+                disc.set_emulated_ii_ptr(globalize=False)\n+            disc_new = samp.discretization(input_sample_set = s_set,\n+                                           output_sample_set = s_set,\n+                                           emulated_input_sample_set = self.disc._emulated_input_sample_set)\n+            \n+            disc_new.set_emulated_ii_ptr(globalize=False)\n+        else:\n+            logging.warning(\"Using input_sample_set for volume emulation\")\n+            disc = self.disc.copy()\n+            disc.set_emulated_input_sample_set(disc._input_sample_set)\n+            disc.set_emulated_ii_ptr(globalize=False)\n+            \n+            disc_new = samp.discretization(input_sample_set = s_set,\n+                                           output_sample_set = s_set,\n+                                           emulated_input_sample_set = self.disc._input_sample_set)\n+            disc_new.set_emulated_ii_ptr(globalize=False)\n+        \n+        # Emulated points in the the region\n+        in_A = marker[disc_new._emulated_ii_ptr_local]\n+        \n+        upper_bound = 0.0\n+        lower_bound = 0.0\n+        # Loop over contour intervals and add error contributions\n+        ops_num = self.disc._output_probability_set.check_num()\n+        for i in range(ops_num):\n+            if self.disc._output_probability_set._probabilities[i] > 0.0:\n+                indices = np.equal(disc._io_ptr, i)\n+                in_Ai = indices[disc._emulated_ii_ptr_local]\n+                \n+                sum1 = np.sum(np.logical_and(in_A, in_Ai))\n+                sum2 = np.sum(in_Ai)\n+                sum1 = comm.allreduce(sum1, op=MPI.SUM)\n+                sum2 = comm.allreduce(sum2, op=MPI.SUM)\n+                if sum2 == 0.0:\n+                    return (float('nan'), float('nan'))\n+                E = float(sum1)/float(sum2)\n+\n+                in_B_N = np.zeros(in_A.shape, dtype=np.bool)","path":"bet/calculateP/calculateError.py","position":303,"original_position":303,"commit_id":"54ce526d99b5e8ab0be383fd782671890a36ba53","original_commit_id":"54ce526d99b5e8ab0be383fd782671890a36ba53","user":{"login":"lcgraham","id":3008749,"avatar_url":"https://avatars.githubusercontent.com/u/3008749?v=3","gravatar_id":"","url":"https://api.github.com/users/lcgraham","html_url":"https://github.com/lcgraham","followers_url":"https://api.github.com/users/lcgraham/followers","following_url":"https://api.github.com/users/lcgraham/following{/other_user}","gists_url":"https://api.github.com/users/lcgraham/gists{/gist_id}","starred_url":"https://api.github.com/users/lcgraham/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lcgraham/subscriptions","organizations_url":"https://api.github.com/users/lcgraham/orgs","repos_url":"https://api.github.com/users/lcgraham/repos","events_url":"https://api.github.com/users/lcgraham/events{/privacy}","received_events_url":"https://api.github.com/users/lcgraham/received_events","type":"User","site_admin":false},"body":"add line comment","created_at":"2016-07-19T16:29:36Z","updated_at":"2016-07-19T16:29:36Z","html_url":"https://github.com/UT-CHG/BET/pull/250#discussion_r71374233","pull_request_url":"https://api.github.com/repos/UT-CHG/BET/pulls/250","_links":{"self":{"href":"https://api.github.com/repos/UT-CHG/BET/pulls/comments/71374233"},"html":{"href":"https://github.com/UT-CHG/BET/pull/250#discussion_r71374233"},"pull_request":{"href":"https://api.github.com/repos/UT-CHG/BET/pulls/250"}}},"pull_request":{"url":"https://api.github.com/repos/UT-CHG/BET/pulls/250","id":77895158,"html_url":"https://github.com/UT-CHG/BET/pull/250","diff_url":"https://github.com/UT-CHG/BET/pull/250.diff","patch_url":"https://github.com/UT-CHG/BET/pull/250.patch","issue_url":"https://api.github.com/repos/UT-CHG/BET/issues/250","number":250,"state":"open","locked":false,"title":"Add error estimates","user":{"login":"smattis","id":997385,"avatar_url":"https://avatars.githubusercontent.com/u/997385?v=3","gravatar_id":"","url":"https://api.github.com/users/smattis","html_url":"https://github.com/smattis","followers_url":"https://api.github.com/users/smattis/followers","following_url":"https://api.github.com/users/smattis/following{/other_user}","gists_url":"https://api.github.com/users/smattis/gists{/gist_id}","starred_url":"https://api.github.com/users/smattis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smattis/subscriptions","organizations_url":"https://api.github.com/users/smattis/orgs","repos_url":"https://api.github.com/users/smattis/repos","events_url":"https://api.github.com/users/smattis/events{/privacy}","received_events_url":"https://api.github.com/users/smattis/received_events","type":"User","site_admin":false},"body":"Adds modules for calculating error estimates and for surrogate models. Also adds an example to show how to use them.","created_at":"2016-07-18T23:15:30Z","updated_at":"2016-07-19T16:29:36Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e83cd44e792e3b409f69d1baf0a6f1c0b63f3e8c","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/UT-CHG/BET/pulls/250/commits","review_comments_url":"https://api.github.com/repos/UT-CHG/BET/pulls/250/comments","review_comment_url":"https://api.github.com/repos/UT-CHG/BET/pulls/comments{/number}","comments_url":"https://api.github.com/repos/UT-CHG/BET/issues/250/comments","statuses_url":"https://api.github.com/repos/UT-CHG/BET/statuses/54ce526d99b5e8ab0be383fd782671890a36ba53","head":{"label":"smattis:add-error-estimates","ref":"add-error-estimates","sha":"54ce526d99b5e8ab0be383fd782671890a36ba53","user":{"login":"smattis","id":997385,"avatar_url":"https://avatars.githubusercontent.com/u/997385?v=3","gravatar_id":"","url":"https://api.github.com/users/smattis","html_url":"https://github.com/smattis","followers_url":"https://api.github.com/users/smattis/followers","following_url":"https://api.github.com/users/smattis/following{/other_user}","gists_url":"https://api.github.com/users/smattis/gists{/gist_id}","starred_url":"https://api.github.com/users/smattis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smattis/subscriptions","organizations_url":"https://api.github.com/users/smattis/orgs","repos_url":"https://api.github.com/users/smattis/repos","events_url":"https://api.github.com/users/smattis/events{/privacy}","received_events_url":"https://api.github.com/users/smattis/received_events","type":"User","site_admin":false},"repo":{"id":31750830,"name":"BET-1","full_name":"smattis/BET-1","owner":{"login":"smattis","id":997385,"avatar_url":"https://avatars.githubusercontent.com/u/997385?v=3","gravatar_id":"","url":"https://api.github.com/users/smattis","html_url":"https://github.com/smattis","followers_url":"https://api.github.com/users/smattis/followers","following_url":"https://api.github.com/users/smattis/following{/other_user}","gists_url":"https://api.github.com/users/smattis/gists{/gist_id}","starred_url":"https://api.github.com/users/smattis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smattis/subscriptions","organizations_url":"https://api.github.com/users/smattis/orgs","repos_url":"https://api.github.com/users/smattis/repos","events_url":"https://api.github.com/users/smattis/events{/privacy}","received_events_url":"https://api.github.com/users/smattis/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/smattis/BET-1","description":"Butler, Estep, Tavener Method - A python based package for measure-theoretic stochastic inverse and forward problems.","fork":true,"url":"https://api.github.com/repos/smattis/BET-1","forks_url":"https://api.github.com/repos/smattis/BET-1/forks","keys_url":"https://api.github.com/repos/smattis/BET-1/keys{/key_id}","collaborators_url":"https://api.github.com/repos/smattis/BET-1/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/smattis/BET-1/teams","hooks_url":"https://api.github.com/repos/smattis/BET-1/hooks","issue_events_url":"https://api.github.com/repos/smattis/BET-1/issues/events{/number}","events_url":"https://api.github.com/repos/smattis/BET-1/events","assignees_url":"https://api.github.com/repos/smattis/BET-1/assignees{/user}","branches_url":"https://api.github.com/repos/smattis/BET-1/branches{/branch}","tags_url":"https://api.github.com/repos/smattis/BET-1/tags","blobs_url":"https://api.github.com/repos/smattis/BET-1/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/smattis/BET-1/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/smattis/BET-1/git/refs{/sha}","trees_url":"https://api.github.com/repos/smattis/BET-1/git/trees{/sha}","statuses_url":"https://api.github.com/repos/smattis/BET-1/statuses/{sha}","languages_url":"https://api.github.com/repos/smattis/BET-1/languages","stargazers_url":"https://api.github.com/repos/smattis/BET-1/stargazers","contributors_url":"https://api.github.com/repos/smattis/BET-1/contributors","subscribers_url":"https://api.github.com/repos/smattis/BET-1/subscribers","subscription_url":"https://api.github.com/repos/smattis/BET-1/subscription","commits_url":"https://api.github.com/repos/smattis/BET-1/commits{/sha}","git_commits_url":"https://api.github.com/repos/smattis/BET-1/git/commits{/sha}","comments_url":"https://api.github.com/repos/smattis/BET-1/comments{/number}","issue_comment_url":"https://api.github.com/repos/smattis/BET-1/issues/comments{/number}","contents_url":"https://api.github.com/repos/smattis/BET-1/contents/{+path}","compare_url":"https://api.github.com/repos/smattis/BET-1/compare/{base}...{head}","merges_url":"https://api.github.com/repos/smattis/BET-1/merges","archive_url":"https://api.github.com/repos/smattis/BET-1/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/smattis/BET-1/downloads","issues_url":"https://api.github.com/repos/smattis/BET-1/issues{/number}","pulls_url":"https://api.github.com/repos/smattis/BET-1/pulls{/number}","milestones_url":"https://api.github.com/repos/smattis/BET-1/milestones{/number}","notifications_url":"https://api.github.com/repos/smattis/BET-1/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/smattis/BET-1/labels{/name}","releases_url":"https://api.github.com/repos/smattis/BET-1/releases{/id}","deployments_url":"https://api.github.com/repos/smattis/BET-1/deployments","created_at":"2015-03-06T03:31:06Z","updated_at":"2016-05-12T19:32:48Z","pushed_at":"2016-07-18T23:10:22Z","git_url":"git://github.com/smattis/BET-1.git","ssh_url":"git@github.com:smattis/BET-1.git","clone_url":"https://github.com/smattis/BET-1.git","svn_url":"https://github.com/smattis/BET-1","homepage":"http://ut-chg.github.io/BET","size":38566,"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":"UT-CHG:master","ref":"master","sha":"a262876775b1bda08c64c610fe1c1cc6b1c257e0","user":{"login":"UT-CHG","id":8753973,"avatar_url":"https://avatars.githubusercontent.com/u/8753973?v=3","gravatar_id":"","url":"https://api.github.com/users/UT-CHG","html_url":"https://github.com/UT-CHG","followers_url":"https://api.github.com/users/UT-CHG/followers","following_url":"https://api.github.com/users/UT-CHG/following{/other_user}","gists_url":"https://api.github.com/users/UT-CHG/gists{/gist_id}","starred_url":"https://api.github.com/users/UT-CHG/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/UT-CHG/subscriptions","organizations_url":"https://api.github.com/users/UT-CHG/orgs","repos_url":"https://api.github.com/users/UT-CHG/repos","events_url":"https://api.github.com/users/UT-CHG/events{/privacy}","received_events_url":"https://api.github.com/users/UT-CHG/received_events","type":"Organization","site_admin":false},"repo":{"id":18813599,"name":"BET","full_name":"UT-CHG/BET","owner":{"login":"UT-CHG","id":8753973,"avatar_url":"https://avatars.githubusercontent.com/u/8753973?v=3","gravatar_id":"","url":"https://api.github.com/users/UT-CHG","html_url":"https://github.com/UT-CHG","followers_url":"https://api.github.com/users/UT-CHG/followers","following_url":"https://api.github.com/users/UT-CHG/following{/other_user}","gists_url":"https://api.github.com/users/UT-CHG/gists{/gist_id}","starred_url":"https://api.github.com/users/UT-CHG/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/UT-CHG/subscriptions","organizations_url":"https://api.github.com/users/UT-CHG/orgs","repos_url":"https://api.github.com/users/UT-CHG/repos","events_url":"https://api.github.com/users/UT-CHG/events{/privacy}","received_events_url":"https://api.github.com/users/UT-CHG/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/UT-CHG/BET","description":"Butler, Estep, Tavener Method - A python based package for measure-theoretic stochastic inverse and forward problems.","fork":false,"url":"https://api.github.com/repos/UT-CHG/BET","forks_url":"https://api.github.com/repos/UT-CHG/BET/forks","keys_url":"https://api.github.com/repos/UT-CHG/BET/keys{/key_id}","collaborators_url":"https://api.github.com/repos/UT-CHG/BET/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/UT-CHG/BET/teams","hooks_url":"https://api.github.com/repos/UT-CHG/BET/hooks","issue_events_url":"https://api.github.com/repos/UT-CHG/BET/issues/events{/number}","events_url":"https://api.github.com/repos/UT-CHG/BET/events","assignees_url":"https://api.github.com/repos/UT-CHG/BET/assignees{/user}","branches_url":"https://api.github.com/repos/UT-CHG/BET/branches{/branch}","tags_url":"https://api.github.com/repos/UT-CHG/BET/tags","blobs_url":"https://api.github.com/repos/UT-CHG/BET/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/UT-CHG/BET/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/UT-CHG/BET/git/refs{/sha}","trees_url":"https://api.github.com/repos/UT-CHG/BET/git/trees{/sha}","statuses_url":"https://api.github.com/repos/UT-CHG/BET/statuses/{sha}","languages_url":"https://api.github.com/repos/UT-CHG/BET/languages","stargazers_url":"https://api.github.com/repos/UT-CHG/BET/stargazers","contributors_url":"https://api.github.com/repos/UT-CHG/BET/contributors","subscribers_url":"https://api.github.com/repos/UT-CHG/BET/subscribers","subscription_url":"https://api.github.com/repos/UT-CHG/BET/subscription","commits_url":"https://api.github.com/repos/UT-CHG/BET/commits{/sha}","git_commits_url":"https://api.github.com/repos/UT-CHG/BET/git/commits{/sha}","comments_url":"https://api.github.com/repos/UT-CHG/BET/comments{/number}","issue_comment_url":"https://api.github.com/repos/UT-CHG/BET/issues/comments{/number}","contents_url":"https://api.github.com/repos/UT-CHG/BET/contents/{+path}","compare_url":"https://api.github.com/repos/UT-CHG/BET/compare/{base}...{head}","merges_url":"https://api.github.com/repos/UT-CHG/BET/merges","archive_url":"https://api.github.com/repos/UT-CHG/BET/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/UT-CHG/BET/downloads","issues_url":"https://api.github.com/repos/UT-CHG/BET/issues{/number}","pulls_url":"https://api.github.com/repos/UT-CHG/BET/pulls{/number}","milestones_url":"https://api.github.com/repos/UT-CHG/BET/milestones{/number}","notifications_url":"https://api.github.com/repos/UT-CHG/BET/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/UT-CHG/BET/labels{/name}","releases_url":"https://api.github.com/repos/UT-CHG/BET/releases{/id}","deployments_url":"https://api.github.com/repos/UT-CHG/BET/deployments","created_at":"2014-04-15T19:51:31Z","updated_at":"2016-04-17T01:54:29Z","pushed_at":"2016-07-18T23:15:31Z","git_url":"git://github.com/UT-CHG/BET.git","ssh_url":"git@github.com:UT-CHG/BET.git","clone_url":"https://github.com/UT-CHG/BET.git","svn_url":"https://github.com/UT-CHG/BET","homepage":"http://ut-chg.github.io/BET","size":10677,"stargazers_count":4,"watchers_count":4,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":11,"mirror_url":null,"open_issues_count":12,"forks":11,"open_issues":12,"watchers":4,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/UT-CHG/BET/pulls/250"},"html":{"href":"https://github.com/UT-CHG/BET/pull/250"},"issue":{"href":"https://api.github.com/repos/UT-CHG/BET/issues/250"},"comments":{"href":"https://api.github.com/repos/UT-CHG/BET/issues/250/comments"},"review_comments":{"href":"https://api.github.com/repos/UT-CHG/BET/pulls/250/comments"},"review_comment":{"href":"https://api.github.com/repos/UT-CHG/BET/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/UT-CHG/BET/pulls/250/commits"},"statuses":{"href":"https://api.github.com/repos/UT-CHG/BET/statuses/54ce526d99b5e8ab0be383fd782671890a36ba53"}}}}
{"actor":{"display_login":"lcgraham"}}