{"action":"created","comment":{"url":"https://api.github.com/repos/nistats/nistats/pulls/comments/53210977","id":53210977,"diff_hunk":"@@ -0,0 +1,296 @@\n+\"\"\"\n+Permutation tests for first level and second level analysis.\n+\"\"\"\n+# Author: Martin Perez-Guevara, <mperezguevara@gmail.com>, jan. 2016\n+import warnings\n+import numpy as np\n+from sklearn.utils import check_random_state\n+import sklearn.externals.joblib as joblib\n+from sklearn.base import clone\n+from nistats.design_matrix import make_design_matrix\n+import time\n+import sys\n+\n+\n+def _meet_contrast_conditions(con_val):\n+    \"\"\"Check if permutation test is allowed for given contrast values.\"\"\"\n+    # No F tests\n+    if type(con_val[0]) is list:\n+        return False\n+    # Not with less or more than 2 conditions\n+    if len(np.where(con_val != 0.0)[0]) != 2:\n+        return False\n+    return True\n+\n+\n+def _permutations_glm(original_stat, glm_ref, imgs, design_matrix_objs,\n+                      con_val, con_id, con_labels, n_perm_chunk=10000,\n+                      two_sided_test=True,\n+                      random_state=None,\n+                      n_perm=10000,\n+                      thread_id=1,\n+                      verbose=0):\n+    \"\"\"Massively univariate group analysis with permuted OLS on a data chunk.\n+    To be used in a parallel computing context.\n+    Parameters\n+    ----------\n+    design_matrix_objs: list of [time_frames, paradigm, kwargs dict].\n+        frame_times is an array of shape (n_frames,) representing the timing\n+        of the scans in seconds. Paradigm is a DataFrame instance with the\n+        description of the experimental paradigm. kwargs are any other\n+        arguments that could be passed to the function make_design_matrix\n+        defined in nistats.design_matrix.\n+\n+    original_stat : array-like, shape=(n_voxels)\n+        t-scores obtained for the original (non-permuted) data.\n+\n+    n_perm_chunk : int,\n+        Number of permutations to be performed.\n+\n+    two_sided_test : boolean,\n+        If True, performs an unsigned t-test. Both positive and negative\n+        effects are considered; the null hypothesis is that the effect is zero.\n+        If False, only positive effects are considered as relevant. The null\n+        hypothesis is that the effect is zero or negative.\n+\n+    random_state : int or None,\n+        Seed for random number generator, to have the same permutations\n+        in each computing units.\n+\n+    Returns\n+    -------\n+    unc_ranks_parts: array-like, shape=(n_voxels)\n+        Accumulated count of permuted stats over original stats,\n+        to compute uncorrected p-values. (limited to this permutation chunk).\n+\n+    smax_parts : array-like, shape=(n_perm_chunk, )\n+        Distribution of the (max) t-statistic under the null hypothesis\n+        (limited to this permutation chunk).\n+\n+    References\n+    ----------\n+    [1] Nichols, T. E., & Holmes, A. P. (2002). Nonparametric permutation\n+    tests for functional neuroimaging: a primer with examples. Human brain\n+    mapping, 15(1), 1-25..\n+    \"\"\"\n+    # initialize the seed of the random generator\n+    rng = check_random_state(random_state)\n+\n+    # run the permutations\n+    smax_parts = np.empty((n_perm_chunk))\n+    unc_rank_parts = np.zeros(len(original_stat))\n+    # Infer conditions to permute\n+    conditions = np.where(con_val != 0.0)\n+    t0 = time.time()\n+    for i in range(n_perm_chunk):\n+        # Shuffle labels of the conditions in the design matrix\n+        design_matrices = []\n+\n+        for frame_times, paradigm, kwargs in design_matrix_objs:\n+            perm_paradigm = paradigm.copy()\n+            con_idx = np.where(con_val != 0.0)[0]\n+            conditions = [con_labels[x] for x in con_idx]\n+            selection = np.array([False for x in range(len(paradigm))])\n+            for condition in conditions:\n+                selection = selection | (perm_paradigm['name'] == condition)\n+            sel_labels = perm_paradigm[selection]\n+            labels_idx = sel_labels.index.tolist()\n+            perm_labels = rng.permutation(sel_labels['name'].tolist())\n+            for lidx, perm_label in zip(labels_idx, perm_labels):\n+                perm_paradigm.loc[lidx, 'name'] = perm_label\n+\n+            design_matrices.append(make_design_matrix(frame_times,\n+                                                      perm_paradigm,\n+                                                      **kwargs))\n+\n+        # Get permuted stat\n+        glm_obj = clone(glm_ref)\n+        permuted_stat, = glm_obj.fit(imgs, design_matrices) \\\n+                                .transform(con_val, contrast_name=con_id,\n+                                           output_z=False, output_stat=True)\n+        permuted_stat = glm_obj.masker_.transform(permuted_stat)[0]\n+\n+        # For uncorrected p-values\n+        if two_sided_test:\n+            unc_rank_parts += (np.fabs(permuted_stat) < original_stat)\n+        else:\n+            unc_rank_parts += (permuted_stat < original_stat)\n+\n+        # For corrected p-values\n+        smax_parts[i] = np.max(permuted_stat)\n+\n+        if verbose > 0:\n+            # We print every 10 permutations or more often\n+            step = 11 - min(verbose, 10)\n+            if (i % step == 0):\n+                # If there is only one job, progress information is fixed\n+                if n_perm == n_perm_chunk:\n+                    crlf = \"\\r\"\n+                else:\n+                    crlf = \"\\n\"\n+                percent = float(i) / n_perm_chunk\n+                percent = round(percent * 100, 2)\n+                dt = time.time() - t0\n+                # We use a max to avoid a division by zero\n+                remaining = (100. - percent) / max(0.01, percent) * dt\n+                sys.stderr.write(\n+                    \"Job #%d, processed %d/%d permutations for contrast %s \"\n+                    \"(%0.2f%%, %i seconds remaining)%s\"\n+                    % (thread_id, i, n_perm_chunk, con_id, percent, remaining,\n+                       crlf))\n+\n+    return unc_rank_parts, smax_parts\n+\n+\n+def first_level_permutation_test(contrasts, glm_ref, imgs,\n+                                 design_matrix_objs, n_perm=50,\n+                                 two_sided_test=True, cluster_threshold=None,\n+                                 random_state=None, verbose=1, n_jobs=1):\n+    \"\"\"Estimate uncorrected and FWE corrected p-values for voxel activation and\n+    cluster size.\n+\n+    Parameters\n+    ----------\n+    contrasts: dict with string as key and list of float as value,\n+        The key corresponds to the contrast name and the list size must\n+        corresponds to the number of columns in the design matrices.\n+        Currently only contrasts between two conditions can be computed.\n+        So every contrast value must be of the form [...,+-1.,...,-+1.,...].\n+        Contrasts considering more than two conditions will be ignored.\n+\n+    glm_ref: FirstLevelGLM instance,\n+        To provide any GLM computation specification. This object will be\n+        taken as a reference, new copies will the same parameters will be\n+        created to be fitted on imgs and design_matrices.\n+\n+    imgs: Niimg-like object or list of Niimg-like objects,\n+        See http://nilearn.github.io/building_blocks/manipulating_mr_images.html#niimg.\n+        Data on which the GLM will be fitted. If this is a list,\n+        the affine is considered the same for all.\n+\n+    design_matrix_objs: list of [time_frames, paradigm, kwargs dict].\n+        frame_times is an array of shape (n_frames,) representing the timing\n+        of the scans in seconds. Paradigm is a DataFrame instance with the\n+        description of the experimental paradigm. kwargs are any other\n+        arguments that could be passed to the function make_design_matrix\n+        defined in nistats.design_matrix.\n+\n+    n_perm: int, optional\n+        Number of permutations. Greater than 0. Defaults to 10000.\n+\n+    two_sided_test : boolean,\n+        If True, performs an unsigned t-test. Both positive and negative\n+        effects are considered; the null hypothesis is that the effect is zero.\n+        If False, only positive effects are considered as relevant. The null\n+        hypothesis is that the effect is zero or negative.\n+\n+    cluster_threshold: None or float, optional\n+        Threshold for computation of cluster size statistics. If None will\n+        not compute cluster size statistics.\n+\n+    n_jobs : integer, optional\n+        The number of CPUs to use to do the computation. -1 means\n+        'all CPUs', -2 'all CPUs but one', and so on.\n+\n+    verbose : integer, optional\n+        Indicate the level of verbosity. By default, nothing is printed.\n+\n+    Returns\n+    -------\n+    contrast_results: dict with string as key and tuple of two Nifti1File\n+        objects as value. The key is the contrast name and the first\n+        nifti file contains the uncorrected p values derived from the\n+        permutations at the voxel level, while the second nifti file contains\n+        the corrected p values derived from the permutations whole brain max\n+        statistic.\n+    \"\"\"\n+    # check n_jobs (number of CPUs)\n+    if n_jobs == 0:  # invalid according to joblib's conventions\n+        raise ValueError(\"'n_jobs == 0' is not a valid choice. \"\n+                         \"Please provide a positive number of CPUs, or -1 \"\n+                         \"for all CPUs, or a negative number (-i) for \"\n+                         \"'all but (i-1)' CPUs (joblib conventions).\")\n+    elif n_jobs < 0:\n+        n_jobs = max(1, joblib.cpu_count() - int(n_jobs) + 1)\n+    else:\n+        n_jobs = min(n_jobs, joblib.cpu_count())\n+\n+    # Check n_perm\n+    if n_perm <= 0:\n+        raise ValueError(\"'n_perm <= 0' is not a valid choice.\")\n+\n+    # Process one contrast at a time\n+    contrast_results = {}\n+    for (con_id, con_val) in contrasts.iteritems():\n+        # Check permutation can be performed on contrasts\n+        if not _meet_contrast_conditions(con_val):\n+            warnings.warn('Contrast %s do not meet conditions.'\n+                          'Computation ignored.' % (con_id,))\n+            continue\n+\n+        # Get original stat\n+        design_matrices = []\n+        for time_frames, paradigm, kwargs in design_matrix_objs:\n+            design_matrices.append(make_design_matrix(time_frames, paradigm,\n+                                                      **kwargs))\n+        glm_obj = clone(glm_ref)\n+        original_stat, = glm_obj.fit(imgs, design_matrices) \\\n+                                .transform(con_val, contrast_name=con_id,\n+                                           output_z=False, output_stat=True)\n+        original_stat = glm_obj.masker_.transform(original_stat)[0]\n+        if two_sided_test:\n+            original_stat = np.fabs(original_stat)\n+        # Check possible permutations\n+\n+        # Distribute permutations across jobs\n+        if n_perm > n_jobs:\n+            n_perm_chunks = np.asarray([n_perm / n_jobs] * n_jobs,\n+                                       dtype=int)\n+            n_perm_chunks[-1] += n_perm % n_jobs\n+        elif n_perm > 0:\n+            warnings.warn('The specified number of permutations is %d and '\n+                          'the number of jobs to be performed in parallel was '\n+                          'set to %s. This is incompatible so only %d jobs will '\n+                          'be running. You may want to perform more permutations '\n+                          'in order to take the most of the available computing '\n+                          'resources.' % (n_perm, n_jobs, n_perm))\n+            n_perm_chunks = np.ones(n_perm, dtype=int)\n+\n+        # initialize the seed of the random generator\n+        rng = check_random_state(random_state)\n+\n+        per = joblib.Parallel(n_jobs=n_jobs, verbose=verbose)(","path":"nistats/permutation_tests.py","position":262,"original_position":262,"commit_id":"ca3c912acb27de852cd751726b0b487bd0f370b5","original_commit_id":"ca3c912acb27de852cd751726b0b487bd0f370b5","user":{"login":"bthirion","id":234454,"avatar_url":"https://avatars.githubusercontent.com/u/234454?v=3","gravatar_id":"","url":"https://api.github.com/users/bthirion","html_url":"https://github.com/bthirion","followers_url":"https://api.github.com/users/bthirion/followers","following_url":"https://api.github.com/users/bthirion/following{/other_user}","gists_url":"https://api.github.com/users/bthirion/gists{/gist_id}","starred_url":"https://api.github.com/users/bthirion/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bthirion/subscriptions","organizations_url":"https://api.github.com/users/bthirion/orgs","repos_url":"https://api.github.com/users/bthirion/repos","events_url":"https://api.github.com/users/bthirion/events{/privacy}","received_events_url":"https://api.github.com/users/bthirion/received_events","type":"User","site_admin":false},"body":"`permutation_results` rather than `per`\r\nThe names should always be as explicit as possible.","created_at":"2016-02-17T18:48:40Z","updated_at":"2016-02-17T18:48:40Z","html_url":"https://github.com/nistats/nistats/pull/51#discussion_r53210977","pull_request_url":"https://api.github.com/repos/nistats/nistats/pulls/51","_links":{"self":{"href":"https://api.github.com/repos/nistats/nistats/pulls/comments/53210977"},"html":{"href":"https://github.com/nistats/nistats/pull/51#discussion_r53210977"},"pull_request":{"href":"https://api.github.com/repos/nistats/nistats/pulls/51"}}},"pull_request":{"url":"https://api.github.com/repos/nistats/nistats/pulls/51","id":57883593,"html_url":"https://github.com/nistats/nistats/pull/51","diff_url":"https://github.com/nistats/nistats/pull/51.diff","patch_url":"https://github.com/nistats/nistats/pull/51.patch","issue_url":"https://api.github.com/repos/nistats/nistats/issues/51","number":51,"state":"open","locked":false,"title":"basic first level permutation tests","user":{"login":"MartinPerez","id":8766915,"avatar_url":"https://avatars.githubusercontent.com/u/8766915?v=3","gravatar_id":"","url":"https://api.github.com/users/MartinPerez","html_url":"https://github.com/MartinPerez","followers_url":"https://api.github.com/users/MartinPerez/followers","following_url":"https://api.github.com/users/MartinPerez/following{/other_user}","gists_url":"https://api.github.com/users/MartinPerez/gists{/gist_id}","starred_url":"https://api.github.com/users/MartinPerez/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MartinPerez/subscriptions","organizations_url":"https://api.github.com/users/MartinPerez/orgs","repos_url":"https://api.github.com/users/MartinPerez/repos","events_url":"https://api.github.com/users/MartinPerez/events{/privacy}","received_events_url":"https://api.github.com/users/MartinPerez/received_events","type":"User","site_admin":false},"body":"Here I provide the localizer example modified to perform basic contrasts first level permutation tests. I also provide an initial proposal for a permutation API. I am convinced this API is far from optimal, particularly I find cumbersome the way I am passing the design matrix objs to the permutation test. I would support #40, since I think having a design matrix object would allow me to pass it and access all relevant information from it as I do from the FirstLevelGLM object.\r\n\r\nI am not sure on what would be the appropriate way to write tests for this functionality. In any case first eye tests seem nice. Following we can see the comparison between the original z score map for the contrast reading-visual for uncorrected p<0.1, then the permuted version for uncorrected p<0.1 and finally the permuted version for corrected p<0.5. The correction is very strong. 600 permutations were performed.\r\n\r\n![reading-visual_z_map](https://cloud.githubusercontent.com/assets/8766915/12727625/072d823e-c91e-11e5-910b-acbccc750518.png)\r\n\r\n![reading-visual_unc_pval](https://cloud.githubusercontent.com/assets/8766915/12727694/59534bca-c91e-11e5-80c7-9ea7d708fa03.png)\r\n\r\n![reading-visual_cor_pval](https://cloud.githubusercontent.com/assets/8766915/12727704/63e4048a-c91e-11e5-8eaf-4fbc7306effe.png)\r\n","created_at":"2016-02-01T19:00:24Z","updated_at":"2016-02-17T18:48:40Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ef2a47ac19066eaf15cc4d446cad09b914674f4c","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/nistats/nistats/pulls/51/commits","review_comments_url":"https://api.github.com/repos/nistats/nistats/pulls/51/comments","review_comment_url":"https://api.github.com/repos/nistats/nistats/pulls/comments{/number}","comments_url":"https://api.github.com/repos/nistats/nistats/issues/51/comments","statuses_url":"https://api.github.com/repos/nistats/nistats/statuses/ca3c912acb27de852cd751726b0b487bd0f370b5","head":{"label":"MartinPerez:permutation_tests_example","ref":"permutation_tests_example","sha":"ca3c912acb27de852cd751726b0b487bd0f370b5","user":{"login":"MartinPerez","id":8766915,"avatar_url":"https://avatars.githubusercontent.com/u/8766915?v=3","gravatar_id":"","url":"https://api.github.com/users/MartinPerez","html_url":"https://github.com/MartinPerez","followers_url":"https://api.github.com/users/MartinPerez/followers","following_url":"https://api.github.com/users/MartinPerez/following{/other_user}","gists_url":"https://api.github.com/users/MartinPerez/gists{/gist_id}","starred_url":"https://api.github.com/users/MartinPerez/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MartinPerez/subscriptions","organizations_url":"https://api.github.com/users/MartinPerez/orgs","repos_url":"https://api.github.com/users/MartinPerez/repos","events_url":"https://api.github.com/users/MartinPerez/events{/privacy}","received_events_url":"https://api.github.com/users/MartinPerez/received_events","type":"User","site_admin":false},"repo":{"id":41736457,"name":"nistats","full_name":"MartinPerez/nistats","owner":{"login":"MartinPerez","id":8766915,"avatar_url":"https://avatars.githubusercontent.com/u/8766915?v=3","gravatar_id":"","url":"https://api.github.com/users/MartinPerez","html_url":"https://github.com/MartinPerez","followers_url":"https://api.github.com/users/MartinPerez/followers","following_url":"https://api.github.com/users/MartinPerez/following{/other_user}","gists_url":"https://api.github.com/users/MartinPerez/gists{/gist_id}","starred_url":"https://api.github.com/users/MartinPerez/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MartinPerez/subscriptions","organizations_url":"https://api.github.com/users/MartinPerez/orgs","repos_url":"https://api.github.com/users/MartinPerez/repos","events_url":"https://api.github.com/users/MartinPerez/events{/privacy}","received_events_url":"https://api.github.com/users/MartinPerez/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/MartinPerez/nistats","description":"Modeling and statistical inference on fMRI data in Python ","fork":true,"url":"https://api.github.com/repos/MartinPerez/nistats","forks_url":"https://api.github.com/repos/MartinPerez/nistats/forks","keys_url":"https://api.github.com/repos/MartinPerez/nistats/keys{/key_id}","collaborators_url":"https://api.github.com/repos/MartinPerez/nistats/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/MartinPerez/nistats/teams","hooks_url":"https://api.github.com/repos/MartinPerez/nistats/hooks","issue_events_url":"https://api.github.com/repos/MartinPerez/nistats/issues/events{/number}","events_url":"https://api.github.com/repos/MartinPerez/nistats/events","assignees_url":"https://api.github.com/repos/MartinPerez/nistats/assignees{/user}","branches_url":"https://api.github.com/repos/MartinPerez/nistats/branches{/branch}","tags_url":"https://api.github.com/repos/MartinPerez/nistats/tags","blobs_url":"https://api.github.com/repos/MartinPerez/nistats/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/MartinPerez/nistats/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/MartinPerez/nistats/git/refs{/sha}","trees_url":"https://api.github.com/repos/MartinPerez/nistats/git/trees{/sha}","statuses_url":"https://api.github.com/repos/MartinPerez/nistats/statuses/{sha}","languages_url":"https://api.github.com/repos/MartinPerez/nistats/languages","stargazers_url":"https://api.github.com/repos/MartinPerez/nistats/stargazers","contributors_url":"https://api.github.com/repos/MartinPerez/nistats/contributors","subscribers_url":"https://api.github.com/repos/MartinPerez/nistats/subscribers","subscription_url":"https://api.github.com/repos/MartinPerez/nistats/subscription","commits_url":"https://api.github.com/repos/MartinPerez/nistats/commits{/sha}","git_commits_url":"https://api.github.com/repos/MartinPerez/nistats/git/commits{/sha}","comments_url":"https://api.github.com/repos/MartinPerez/nistats/comments{/number}","issue_comment_url":"https://api.github.com/repos/MartinPerez/nistats/issues/comments{/number}","contents_url":"https://api.github.com/repos/MartinPerez/nistats/contents/{+path}","compare_url":"https://api.github.com/repos/MartinPerez/nistats/compare/{base}...{head}","merges_url":"https://api.github.com/repos/MartinPerez/nistats/merges","archive_url":"https://api.github.com/repos/MartinPerez/nistats/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/MartinPerez/nistats/downloads","issues_url":"https://api.github.com/repos/MartinPerez/nistats/issues{/number}","pulls_url":"https://api.github.com/repos/MartinPerez/nistats/pulls{/number}","milestones_url":"https://api.github.com/repos/MartinPerez/nistats/milestones{/number}","notifications_url":"https://api.github.com/repos/MartinPerez/nistats/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/MartinPerez/nistats/labels{/name}","releases_url":"https://api.github.com/repos/MartinPerez/nistats/releases{/id}","deployments_url":"https://api.github.com/repos/MartinPerez/nistats/deployments","created_at":"2015-09-01T12:12:28Z","updated_at":"2016-01-31T13:27:28Z","pushed_at":"2016-02-10T23:01:20Z","git_url":"git://github.com/MartinPerez/nistats.git","ssh_url":"git@github.com:MartinPerez/nistats.git","clone_url":"https://github.com/MartinPerez/nistats.git","svn_url":"https://github.com/MartinPerez/nistats","homepage":null,"size":286,"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":"nistats:master","ref":"master","sha":"61c93f092bbb4d9a4d28f6ca60ba27df5c437305","user":{"login":"nistats","id":12428142,"avatar_url":"https://avatars.githubusercontent.com/u/12428142?v=3","gravatar_id":"","url":"https://api.github.com/users/nistats","html_url":"https://github.com/nistats","followers_url":"https://api.github.com/users/nistats/followers","following_url":"https://api.github.com/users/nistats/following{/other_user}","gists_url":"https://api.github.com/users/nistats/gists{/gist_id}","starred_url":"https://api.github.com/users/nistats/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nistats/subscriptions","organizations_url":"https://api.github.com/users/nistats/orgs","repos_url":"https://api.github.com/users/nistats/repos","events_url":"https://api.github.com/users/nistats/events{/privacy}","received_events_url":"https://api.github.com/users/nistats/received_events","type":"Organization","site_admin":false},"repo":{"id":35545854,"name":"nistats","full_name":"nistats/nistats","owner":{"login":"nistats","id":12428142,"avatar_url":"https://avatars.githubusercontent.com/u/12428142?v=3","gravatar_id":"","url":"https://api.github.com/users/nistats","html_url":"https://github.com/nistats","followers_url":"https://api.github.com/users/nistats/followers","following_url":"https://api.github.com/users/nistats/following{/other_user}","gists_url":"https://api.github.com/users/nistats/gists{/gist_id}","starred_url":"https://api.github.com/users/nistats/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nistats/subscriptions","organizations_url":"https://api.github.com/users/nistats/orgs","repos_url":"https://api.github.com/users/nistats/repos","events_url":"https://api.github.com/users/nistats/events{/privacy}","received_events_url":"https://api.github.com/users/nistats/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nistats/nistats","description":"Modeling and statistical inference on fMRI data in Python ","fork":false,"url":"https://api.github.com/repos/nistats/nistats","forks_url":"https://api.github.com/repos/nistats/nistats/forks","keys_url":"https://api.github.com/repos/nistats/nistats/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nistats/nistats/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nistats/nistats/teams","hooks_url":"https://api.github.com/repos/nistats/nistats/hooks","issue_events_url":"https://api.github.com/repos/nistats/nistats/issues/events{/number}","events_url":"https://api.github.com/repos/nistats/nistats/events","assignees_url":"https://api.github.com/repos/nistats/nistats/assignees{/user}","branches_url":"https://api.github.com/repos/nistats/nistats/branches{/branch}","tags_url":"https://api.github.com/repos/nistats/nistats/tags","blobs_url":"https://api.github.com/repos/nistats/nistats/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nistats/nistats/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nistats/nistats/git/refs{/sha}","trees_url":"https://api.github.com/repos/nistats/nistats/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nistats/nistats/statuses/{sha}","languages_url":"https://api.github.com/repos/nistats/nistats/languages","stargazers_url":"https://api.github.com/repos/nistats/nistats/stargazers","contributors_url":"https://api.github.com/repos/nistats/nistats/contributors","subscribers_url":"https://api.github.com/repos/nistats/nistats/subscribers","subscription_url":"https://api.github.com/repos/nistats/nistats/subscription","commits_url":"https://api.github.com/repos/nistats/nistats/commits{/sha}","git_commits_url":"https://api.github.com/repos/nistats/nistats/git/commits{/sha}","comments_url":"https://api.github.com/repos/nistats/nistats/comments{/number}","issue_comment_url":"https://api.github.com/repos/nistats/nistats/issues/comments{/number}","contents_url":"https://api.github.com/repos/nistats/nistats/contents/{+path}","compare_url":"https://api.github.com/repos/nistats/nistats/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nistats/nistats/merges","archive_url":"https://api.github.com/repos/nistats/nistats/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nistats/nistats/downloads","issues_url":"https://api.github.com/repos/nistats/nistats/issues{/number}","pulls_url":"https://api.github.com/repos/nistats/nistats/pulls{/number}","milestones_url":"https://api.github.com/repos/nistats/nistats/milestones{/number}","notifications_url":"https://api.github.com/repos/nistats/nistats/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nistats/nistats/labels{/name}","releases_url":"https://api.github.com/repos/nistats/nistats/releases{/id}","deployments_url":"https://api.github.com/repos/nistats/nistats/deployments","created_at":"2015-05-13T11:44:31Z","updated_at":"2016-02-04T00:02:36Z","pushed_at":"2016-02-05T10:53:19Z","git_url":"git://github.com/nistats/nistats.git","ssh_url":"git@github.com:nistats/nistats.git","clone_url":"https://github.com/nistats/nistats.git","svn_url":"https://github.com/nistats/nistats","homepage":null,"size":303,"stargazers_count":12,"watchers_count":12,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":13,"mirror_url":null,"open_issues_count":28,"forks":13,"open_issues":28,"watchers":12,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/nistats/nistats/pulls/51"},"html":{"href":"https://github.com/nistats/nistats/pull/51"},"issue":{"href":"https://api.github.com/repos/nistats/nistats/issues/51"},"comments":{"href":"https://api.github.com/repos/nistats/nistats/issues/51/comments"},"review_comments":{"href":"https://api.github.com/repos/nistats/nistats/pulls/51/comments"},"review_comment":{"href":"https://api.github.com/repos/nistats/nistats/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/nistats/nistats/pulls/51/commits"},"statuses":{"href":"https://api.github.com/repos/nistats/nistats/statuses/ca3c912acb27de852cd751726b0b487bd0f370b5"}}}}