{"action":"created","comment":{"url":"https://api.github.com/repos/zfit/zfit/pulls/comments/232467583","pull_request_review_id":173677004,"id":232467583,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzMjQ2NzU4Mw==","diff_hunk":"@@ -1,25 +1,220 @@\n+import abc\n+\n+import pep487\n import tensorflow as tf\n+from typing import Optional\n+\n+import zfit\n+from .limits import convert_to_range, Range\n+import zfit.util.checks\n \n \n-def unbinned_nll(probs=None, weights=None, log_probs=None):\n+def unbinned_nll(pdf, data, fit_range, constraints: Optional[dict] = None) -> tf.Tensor:\n     \"\"\"Return unbinned negative log likelihood graph for a PDF\n \n     Args:\n-        probs (Tensor): The probabilities\n-        weights (Tensor): Weights of the `probs`\n-        log_probs (Tensor): The logarithmic probabilites\n+        fit_range ():\n+        pdf (Tensor): The probabilities\n+        data (Tensor): Weights of the `probs`\n+        constraints (dict): A dictionary containing the constraints for certain parameters. The key\n+            is the parameter while the value is a pdf with at least a `prob(x)` method.\n \n     Returns:\n         graph: the unbinned nll\n \n     Raises:\n         ValueError: if both `probs` and `log_probs` are specified.\n     \"\"\"\n-    if probs is not None and log_probs is not None:\n-        raise ValueError(\"Cannot specify 'probs' and 'log_probs'\")\n-    if probs is not None:\n-        log_probs = tf.log(probs)\n-    if weights is not None:\n-        log_probs += tf.log(weights)\n-    nll = -tf.reduce_sum(log_probs)\n-    return nll\n+    if constraints is None:\n+        constraints = {}\n+    if zfit.util.checks.isiterable(pdf):\n+        if not len(pdf) == len(data) == len(fit_range):  # TODO: pay attention to fit_range, what if just one range?\n+            raise ValueError(\"The number of given pdfs, data and fit_ranges do not match.\")\n+        else:\n+            if not isinstance(fit_range[0], Range):\n+                raise ValueError(\"If several pdfs are given, the ranges in `fit_range` have to be a \"\n+                                 \"`Range` and not just tuples (because of disambiguity).\")\n+            nlls = [unbinned_nll(pdf=p, data=d, fit_range=r, constraints=constraints)\n+                    for p, d, r in zip(pdf, data, fit_range)]\n+            nll_finished = tf.reduce_sum(nlls)\n+    else:  # TODO: complicated limits?\n+        fit_range = convert_to_range(fit_range, dims=Range.FULL)\n+        limits = fit_range.get_boundaries()\n+        assert len(limits[0]) == 1, \"multiple limits not (yet) supported in nll.\"\n+        (lower,), (upper,) = limits\n+\n+        in_limits = tf.logical_and(lower <= data, data <= upper)\n+        data = tf.boolean_mask(tensor=data, mask=in_limits)\n+        log_probs = tf.log(pdf.prob(data, norm_range=fit_range))\n+        nll = -tf.reduce_sum(log_probs)\n+        if constraints:\n+            constraints_log_prob = tf.reduce_sum([tf.log(dist.prob(param)) for param, dist in constraints.items()])\n+            nll -= constraints_log_prob\n+        nll_finished = nll\n+    return nll_finished\n+\n+\n+#\n+# def extended_unbinned_NLL(pdfs, integrals, n_obs, nsignals,\n+#                           param_gauss=None, param_gauss_mean=None, param_gauss_sigma=None,\n+#                           log_multi_gauss=None):\n+#     \"\"\"\n+#     Return unbinned negative log likelihood graph for a PDF\n+#     pdfs       : concatenated array of several PDFs (different regions/channels)\n+#     integrals  : array of precalculated integrals of the corresponding pdfs\n+#     n_obs       : array of observed num. of events, used in the extended fit and in the\n+#     normalization of the pdf\n+#                  (needed since when I concatenate the pdfs I loose the information on how many\n+#                  data points are fitted with the pdf)\n+#     nsignals   : array of fitted number of events resulted from the extended fit (function of the\n+#     fit parameters, prop to BR)\n+#     param_gauss : list of parameter to be gaussian constrained (CKM pars, etc.)\n+#     param_gauss_mean : mean of parameter to be gaussian constrained\n+#     param_gauss_sigma : sigma parameter to be gaussian constrained\n+#     log_multi_gauss : log of the multi-gaussian to be included in the Likelihood (FF & alphas)\n+#     \"\"\"\n+#     # tf.add_n(log(pdf(x))) - tf.add_n(Nev*Norm)\n+#     nll = - (tf.reduce_sum(tf.log(pdfs)) - tf.reduce_sum(\n+#         tf.cast(n_obs, tf.float64) * tf.log(integrals)))\n+#\n+#     # Extended fit to number of events\n+#     nll += - tf.reduce_sum(-nsignals + tf.cast(n_obs, tf.float64) * tf.log(nsignals))\n+#\n+#     # gaussian constraints on parameters (CKM) # tf.add_n( (par-mean)^2/(2*sigma^2) )\n+#     if param_gauss is not None:\n+#         nll += tf.reduce_sum(\n+#             tf.square(param_gauss - param_gauss_mean) / (2. * tf.square(param_gauss_sigma)))\n+#\n+#     # multivariate gaussian constraints on param that have correlations (alphas, FF)\n+#     if log_multi_gauss is not None:\n+#         nll += - log_multi_gauss\n+#\n+#     return nll\n+\n+class LossInterface(pep487.ABC):\n+\n+    @abc.abstractmethod\n+    def eval(self):\n+        raise NotImplementedError\n+\n+    @abc.abstractmethod\n+    def add_constraint(self, constraint):\n+        raise NotImplementedError\n+\n+    @abc.abstractmethod\n+    def errordef(self, func):\n+        raise NotImplementedError\n+\n+    @property\n+    # @abc.abstractmethod\n+    def pdf(self):\n+        raise NotImplementedError\n+\n+    @property\n+    # @abc.abstractmethod\n+    def data(self):\n+        raise NotImplementedError\n+\n+    @property\n+    # @abc.abstractmethod\n+    def fit_range(self):\n+        raise NotImplementedError\n+\n+\n+class BaseLoss(LossInterface):\n+\n+    def __init__(self, pdf, data, fit_range, constraints=None):\n+        # constraints = {} if constraints == {} else constraints # protect mutable argument\n+        self._simultaneous = None\n+        if constraints is None:\n+            constraints = {}\n+        pdf, data, fit_range = self._input_check(pdf, data, fit_range)\n+        self._pdf = pdf\n+        self._data = data\n+        self._fit_range = fit_range\n+        self._constraints = constraints\n+\n+    def __init_subclass__(cls, **kwargs):\n+        cls._name = \"UnnamedSubBaseLoss\"\n+\n+    def _input_check(self, pdf, data, fit_range):\n+        # TODO\n+        return pdf, data, fit_range\n+\n+    def add_constraint(self, constraint):\n+        if not isinstance(constraint, dict):\n+            raise TypeError(\"`constraint` has to be a dict, is currently {}\".format(type(constraint)))\n+        overwritting_keys = set(constraint).intersection(self._constraints)\n+        if overwritting_keys:\n+            raise ValueError(\"Cannot change existing constraints but only add (currently). Constrain for \"\n+                             \"parameter(s) {} already there.\".format(overwritting_keys))\n+        self._constraints.update(constraint)\n+\n+    @property\n+    def name(self):\n+        return self._name\n+\n+    @property\n+    def pdf(self):\n+        return self._pdf\n+\n+    @property\n+    def data(self):\n+        return self._data\n+\n+    @property\n+    def fit_range(self):\n+        fit_range = self._fit_range\n+        # fit_range = convert_to_range(self._fit_range)\n+        return fit_range\n+\n+    @property\n+    def constraints(self):\n+        return self._constraints\n+\n+    @abc.abstractmethod\n+    def _loss_func(self, pdf, data, fit_range, constraints=None):\n+        raise NotImplementedError\n+\n+    def eval(self):\n+        try:\n+            return self._loss_func(pdf=self.pdf, data=self.data, fit_range=self.fit_range, constraints=self.constraints)\n+        except NotImplementedError:\n+            raise NotImplementedError(\"_loss_func not defined!\")\n+\n+\n+def errordef_nll(sigma):\n+    return sigma\n+\n+\n+class UnbinnedNLL(BaseLoss):\n+    _name = \"UnbinnedNLL\"\n+\n+    def _loss_func(self, pdf, data, fit_range, constraints):\n+        return unbinned_nll(pdf=pdf, data=data, fit_range=fit_range, constraints=constraints)","path":"zfit/core/loss.py","position":206,"original_position":206,"commit_id":"187d2051367a00f8242752d1390b729d81c8b108","original_commit_id":"187d2051367a00f8242752d1390b729d81c8b108","user":{"login":"mayou36","id":17454848,"node_id":"MDQ6VXNlcjE3NDU0ODQ4","avatar_url":"https://avatars3.githubusercontent.com/u/17454848?v=4","gravatar_id":"","url":"https://api.github.com/users/mayou36","html_url":"https://github.com/mayou36","followers_url":"https://api.github.com/users/mayou36/followers","following_url":"https://api.github.com/users/mayou36/following{/other_user}","gists_url":"https://api.github.com/users/mayou36/gists{/gist_id}","starred_url":"https://api.github.com/users/mayou36/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mayou36/subscriptions","organizations_url":"https://api.github.com/users/mayou36/orgs","repos_url":"https://api.github.com/users/mayou36/repos","events_url":"https://api.github.com/users/mayou36/events{/privacy}","received_events_url":"https://api.github.com/users/mayou36/received_events","type":"User","site_admin":false},"body":"True, there is no direct need... Reminds me that I forgot to add the `__add__`, will be done.","created_at":"2018-11-10T22:08:19Z","updated_at":"2018-11-10T22:08:19Z","html_url":"https://github.com/zfit/zfit/pull/53#discussion_r232467583","pull_request_url":"https://api.github.com/repos/zfit/zfit/pulls/53","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/zfit/zfit/pulls/comments/232467583"},"html":{"href":"https://github.com/zfit/zfit/pull/53#discussion_r232467583"},"pull_request":{"href":"https://api.github.com/repos/zfit/zfit/pulls/53"}},"in_reply_to_id":232466388},"pull_request":{"url":"https://api.github.com/repos/zfit/zfit/pulls/53","id":229908225,"node_id":"MDExOlB1bGxSZXF1ZXN0MjI5OTA4MjI1","html_url":"https://github.com/zfit/zfit/pull/53","diff_url":"https://github.com/zfit/zfit/pull/53.diff","patch_url":"https://github.com/zfit/zfit/pull/53.patch","issue_url":"https://api.github.com/repos/zfit/zfit/issues/53","number":53,"state":"open","locked":false,"title":"WIP: Constraints and Loss Class","user":{"login":"mayou36","id":17454848,"node_id":"MDQ6VXNlcjE3NDU0ODQ4","avatar_url":"https://avatars3.githubusercontent.com/u/17454848?v=4","gravatar_id":"","url":"https://api.github.com/users/mayou36","html_url":"https://github.com/mayou36","followers_url":"https://api.github.com/users/mayou36/followers","following_url":"https://api.github.com/users/mayou36/following{/other_user}","gists_url":"https://api.github.com/users/mayou36/gists{/gist_id}","starred_url":"https://api.github.com/users/mayou36/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mayou36/subscriptions","organizations_url":"https://api.github.com/users/mayou36/orgs","repos_url":"https://api.github.com/users/mayou36/repos","events_url":"https://api.github.com/users/mayou36/events{/privacy}","received_events_url":"https://api.github.com/users/mayou36/received_events","type":"User","site_admin":false},"body":"Added a LossClass (Interface, Base and an implementation, UnbinnedNLL)\r\nAdded constraints support\r\n\r\n+ a lot of small changes\r\n\r\nTODOs:\r\n- [ ] `__add__` for loss\r\n- [ ] move unbinned_nll function body inside nll","created_at":"2018-11-10T19:22:19Z","updated_at":"2018-11-10T22:08:19Z","closed_at":null,"merged_at":null,"merge_commit_sha":"45fc5ec557358c4ef11da3e22938669d7cdef4bb","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/zfit/zfit/pulls/53/commits","review_comments_url":"https://api.github.com/repos/zfit/zfit/pulls/53/comments","review_comment_url":"https://api.github.com/repos/zfit/zfit/pulls/comments{/number}","comments_url":"https://api.github.com/repos/zfit/zfit/issues/53/comments","statuses_url":"https://api.github.com/repos/zfit/zfit/statuses/187d2051367a00f8242752d1390b729d81c8b108","head":{"label":"zfit:constraints","ref":"constraints","sha":"187d2051367a00f8242752d1390b729d81c8b108","user":{"login":"zfit","id":37655297,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM3NjU1Mjk3","avatar_url":"https://avatars2.githubusercontent.com/u/37655297?v=4","gravatar_id":"","url":"https://api.github.com/users/zfit","html_url":"https://github.com/zfit","followers_url":"https://api.github.com/users/zfit/followers","following_url":"https://api.github.com/users/zfit/following{/other_user}","gists_url":"https://api.github.com/users/zfit/gists{/gist_id}","starred_url":"https://api.github.com/users/zfit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zfit/subscriptions","organizations_url":"https://api.github.com/users/zfit/orgs","repos_url":"https://api.github.com/users/zfit/repos","events_url":"https://api.github.com/users/zfit/events{/privacy}","received_events_url":"https://api.github.com/users/zfit/received_events","type":"Organization","site_admin":false},"repo":{"id":126311570,"node_id":"MDEwOlJlcG9zaXRvcnkxMjYzMTE1NzA=","name":"zfit","full_name":"zfit/zfit","private":false,"owner":{"login":"zfit","id":37655297,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM3NjU1Mjk3","avatar_url":"https://avatars2.githubusercontent.com/u/37655297?v=4","gravatar_id":"","url":"https://api.github.com/users/zfit","html_url":"https://github.com/zfit","followers_url":"https://api.github.com/users/zfit/followers","following_url":"https://api.github.com/users/zfit/following{/other_user}","gists_url":"https://api.github.com/users/zfit/gists{/gist_id}","starred_url":"https://api.github.com/users/zfit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zfit/subscriptions","organizations_url":"https://api.github.com/users/zfit/orgs","repos_url":"https://api.github.com/users/zfit/repos","events_url":"https://api.github.com/users/zfit/events{/privacy}","received_events_url":"https://api.github.com/users/zfit/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/zfit/zfit","description":"(pre-beta stage!) zfit is a complete NLL minimisation library based on TensorFlow (for now) with PDFs. The focus is on scalability, paralellization and ease-of-use (no cython, no C++ needed to extend)","fork":false,"url":"https://api.github.com/repos/zfit/zfit","forks_url":"https://api.github.com/repos/zfit/zfit/forks","keys_url":"https://api.github.com/repos/zfit/zfit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zfit/zfit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zfit/zfit/teams","hooks_url":"https://api.github.com/repos/zfit/zfit/hooks","issue_events_url":"https://api.github.com/repos/zfit/zfit/issues/events{/number}","events_url":"https://api.github.com/repos/zfit/zfit/events","assignees_url":"https://api.github.com/repos/zfit/zfit/assignees{/user}","branches_url":"https://api.github.com/repos/zfit/zfit/branches{/branch}","tags_url":"https://api.github.com/repos/zfit/zfit/tags","blobs_url":"https://api.github.com/repos/zfit/zfit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zfit/zfit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zfit/zfit/git/refs{/sha}","trees_url":"https://api.github.com/repos/zfit/zfit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zfit/zfit/statuses/{sha}","languages_url":"https://api.github.com/repos/zfit/zfit/languages","stargazers_url":"https://api.github.com/repos/zfit/zfit/stargazers","contributors_url":"https://api.github.com/repos/zfit/zfit/contributors","subscribers_url":"https://api.github.com/repos/zfit/zfit/subscribers","subscription_url":"https://api.github.com/repos/zfit/zfit/subscription","commits_url":"https://api.github.com/repos/zfit/zfit/commits{/sha}","git_commits_url":"https://api.github.com/repos/zfit/zfit/git/commits{/sha}","comments_url":"https://api.github.com/repos/zfit/zfit/comments{/number}","issue_comment_url":"https://api.github.com/repos/zfit/zfit/issues/comments{/number}","contents_url":"https://api.github.com/repos/zfit/zfit/contents/{+path}","compare_url":"https://api.github.com/repos/zfit/zfit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zfit/zfit/merges","archive_url":"https://api.github.com/repos/zfit/zfit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zfit/zfit/downloads","issues_url":"https://api.github.com/repos/zfit/zfit/issues{/number}","pulls_url":"https://api.github.com/repos/zfit/zfit/pulls{/number}","milestones_url":"https://api.github.com/repos/zfit/zfit/milestones{/number}","notifications_url":"https://api.github.com/repos/zfit/zfit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zfit/zfit/labels{/name}","releases_url":"https://api.github.com/repos/zfit/zfit/releases{/id}","deployments_url":"https://api.github.com/repos/zfit/zfit/deployments","created_at":"2018-03-22T09:31:20Z","updated_at":"2018-11-09T00:35:40Z","pushed_at":"2018-11-10T21:54:41Z","git_url":"git://github.com/zfit/zfit.git","ssh_url":"git@github.com:zfit/zfit.git","clone_url":"https://github.com/zfit/zfit.git","svn_url":"https://github.com/zfit/zfit","homepage":"","size":440,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":31,"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","node_id":"MDc6TGljZW5zZTU="},"forks":0,"open_issues":31,"watchers":3,"default_branch":"develop"}},"base":{"label":"zfit:develop","ref":"develop","sha":"69f5e88fa6e1abf69b01ceef0640fc1bf5196c6e","user":{"login":"zfit","id":37655297,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM3NjU1Mjk3","avatar_url":"https://avatars2.githubusercontent.com/u/37655297?v=4","gravatar_id":"","url":"https://api.github.com/users/zfit","html_url":"https://github.com/zfit","followers_url":"https://api.github.com/users/zfit/followers","following_url":"https://api.github.com/users/zfit/following{/other_user}","gists_url":"https://api.github.com/users/zfit/gists{/gist_id}","starred_url":"https://api.github.com/users/zfit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zfit/subscriptions","organizations_url":"https://api.github.com/users/zfit/orgs","repos_url":"https://api.github.com/users/zfit/repos","events_url":"https://api.github.com/users/zfit/events{/privacy}","received_events_url":"https://api.github.com/users/zfit/received_events","type":"Organization","site_admin":false},"repo":{"id":126311570,"node_id":"MDEwOlJlcG9zaXRvcnkxMjYzMTE1NzA=","name":"zfit","full_name":"zfit/zfit","private":false,"owner":{"login":"zfit","id":37655297,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM3NjU1Mjk3","avatar_url":"https://avatars2.githubusercontent.com/u/37655297?v=4","gravatar_id":"","url":"https://api.github.com/users/zfit","html_url":"https://github.com/zfit","followers_url":"https://api.github.com/users/zfit/followers","following_url":"https://api.github.com/users/zfit/following{/other_user}","gists_url":"https://api.github.com/users/zfit/gists{/gist_id}","starred_url":"https://api.github.com/users/zfit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zfit/subscriptions","organizations_url":"https://api.github.com/users/zfit/orgs","repos_url":"https://api.github.com/users/zfit/repos","events_url":"https://api.github.com/users/zfit/events{/privacy}","received_events_url":"https://api.github.com/users/zfit/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/zfit/zfit","description":"(pre-beta stage!) zfit is a complete NLL minimisation library based on TensorFlow (for now) with PDFs. The focus is on scalability, paralellization and ease-of-use (no cython, no C++ needed to extend)","fork":false,"url":"https://api.github.com/repos/zfit/zfit","forks_url":"https://api.github.com/repos/zfit/zfit/forks","keys_url":"https://api.github.com/repos/zfit/zfit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zfit/zfit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zfit/zfit/teams","hooks_url":"https://api.github.com/repos/zfit/zfit/hooks","issue_events_url":"https://api.github.com/repos/zfit/zfit/issues/events{/number}","events_url":"https://api.github.com/repos/zfit/zfit/events","assignees_url":"https://api.github.com/repos/zfit/zfit/assignees{/user}","branches_url":"https://api.github.com/repos/zfit/zfit/branches{/branch}","tags_url":"https://api.github.com/repos/zfit/zfit/tags","blobs_url":"https://api.github.com/repos/zfit/zfit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zfit/zfit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zfit/zfit/git/refs{/sha}","trees_url":"https://api.github.com/repos/zfit/zfit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zfit/zfit/statuses/{sha}","languages_url":"https://api.github.com/repos/zfit/zfit/languages","stargazers_url":"https://api.github.com/repos/zfit/zfit/stargazers","contributors_url":"https://api.github.com/repos/zfit/zfit/contributors","subscribers_url":"https://api.github.com/repos/zfit/zfit/subscribers","subscription_url":"https://api.github.com/repos/zfit/zfit/subscription","commits_url":"https://api.github.com/repos/zfit/zfit/commits{/sha}","git_commits_url":"https://api.github.com/repos/zfit/zfit/git/commits{/sha}","comments_url":"https://api.github.com/repos/zfit/zfit/comments{/number}","issue_comment_url":"https://api.github.com/repos/zfit/zfit/issues/comments{/number}","contents_url":"https://api.github.com/repos/zfit/zfit/contents/{+path}","compare_url":"https://api.github.com/repos/zfit/zfit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zfit/zfit/merges","archive_url":"https://api.github.com/repos/zfit/zfit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zfit/zfit/downloads","issues_url":"https://api.github.com/repos/zfit/zfit/issues{/number}","pulls_url":"https://api.github.com/repos/zfit/zfit/pulls{/number}","milestones_url":"https://api.github.com/repos/zfit/zfit/milestones{/number}","notifications_url":"https://api.github.com/repos/zfit/zfit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zfit/zfit/labels{/name}","releases_url":"https://api.github.com/repos/zfit/zfit/releases{/id}","deployments_url":"https://api.github.com/repos/zfit/zfit/deployments","created_at":"2018-03-22T09:31:20Z","updated_at":"2018-11-09T00:35:40Z","pushed_at":"2018-11-10T21:54:41Z","git_url":"git://github.com/zfit/zfit.git","ssh_url":"git@github.com:zfit/zfit.git","clone_url":"https://github.com/zfit/zfit.git","svn_url":"https://github.com/zfit/zfit","homepage":"","size":440,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":31,"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","node_id":"MDc6TGljZW5zZTU="},"forks":0,"open_issues":31,"watchers":3,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/zfit/zfit/pulls/53"},"html":{"href":"https://github.com/zfit/zfit/pull/53"},"issue":{"href":"https://api.github.com/repos/zfit/zfit/issues/53"},"comments":{"href":"https://api.github.com/repos/zfit/zfit/issues/53/comments"},"review_comments":{"href":"https://api.github.com/repos/zfit/zfit/pulls/53/comments"},"review_comment":{"href":"https://api.github.com/repos/zfit/zfit/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/zfit/zfit/pulls/53/commits"},"statuses":{"href":"https://api.github.com/repos/zfit/zfit/statuses/187d2051367a00f8242752d1390b729d81c8b108"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"mayou36"}}