{"action":"created","comment":{"url":"https://api.github.com/repos/nilearn/nilearn/pulls/comments/26089492","id":26089492,"diff_hunk":"@@ -0,0 +1,168 @@\n+\"\"\"\n+Neuroimaging file input and output.\n+\"\"\"\n+# Author: Gael Varoquaux, Alexandre Abraham, Philippe Gervais\n+# License: simplified BSD\n+\n+import copy\n+import gc\n+import collections\n+from six import string_types\n+\n+import numpy as np\n+\n+import nibabel\n+\n+from .numpy_conversions import as_ndarray\n+\n+\n+def _get_shape(img):\n+    # Use the fact that Nifti1Image has a shape attribute that is\n+    # faster than loading the data from disk\n+    if hasattr(img, 'shape'):\n+        shape = img.shape\n+    else:\n+        shape = img.get_data().shape\n+    return shape\n+\n+\n+def _safe_get_data(img):\n+    \"\"\" Get the data in the image without having a side effect on the\n+        Nifti1Image object\n+    \"\"\"\n+    if hasattr(img, '_data_cache') and img._data_cache is None:\n+        # Copy locally the Nift1Image object to avoid the side effect of data\n+        # loading\n+        img = copy.deepcopy(img)\n+    # typically the line below can double memory usage\n+    # that's why we invoke a forced call to the garbage collector\n+    gc.collect()\n+    return img.get_data()\n+\n+\n+def is_img(obj):\n+    \"\"\" Check for get_data and get_affine method in an object\n+\n+    Parameters\n+    ----------\n+    obj: any object\n+        Tested object\n+\n+    Returns\n+    -------\n+    is_img: boolean\n+        True if get_data and get_affine methods are present and callable,\n+        False otherwise.\n+    \"\"\"\n+\n+    # We use a try/except here because this is the way hasattr works\n+    try:\n+        get_data = getattr(obj, \"get_data\")\n+        get_affine = getattr(obj, \"get_affine\")\n+        return callable(get_data) and callable(get_affine)\n+    except AttributeError:\n+        return False\n+\n+\n+# XXX add dtype option for masks\n+def load_img(img):\n+    \"\"\"Load a niimg and check if it has required methods\n+    \"\"\"\n+    if isinstance(img, string_types):\n+        # data is a filename, we load it\n+        img = nibabel.load(img)\n+    elif not is_img(img):\n+        raise TypeError(\"Data given cannot be converted to a nifti\"\n+                        \" image: this object -'%s'- does not expose\"\n+                        \" get_data or get_affine methods\"\n+                        % short_repr(img))\n+    return img\n+\n+\n+def new_img_like(ref_img, data, affine, copy_header=False):\n+    \"\"\"Create a new image of the same class as the reference image\n+\n+    Parameters\n+    ----------\n+    ref_img: Niimg-like image\n+        Reference image. The new image will be of the same type.\n+\n+    data: numpy array\n+        Data to be stored in the image\n+\n+    affine: 4x4 numpy array\n+        Transformation matrix\n+\n+    copy_header: boolean, optional\n+        Indicated if the header of the reference image should be used to\n+        create the new image\n+\n+    Returns\n+    -------\n+\n+    new_img: nibabel.SpatialImage\n+        An image which has the same type as the reference image.\n+    \"\"\"\n+    # XXX If the niimg is a list of 3D images, we don't need to load them all\n+    # But this is a bit ugly\n+    if hasattr(ref_img, \"__iter__\") and not isinstance(ref_img, string_types):\n+        ref_img = next(ref_img)\n+    ref_img = load_img(ref_img)","path":"nilearn/_utils/niimg.py","position":99,"original_position":110,"commit_id":"e670d6713b1b7f105e6f37da26b1e4d95e61dff9","original_commit_id":"24436d7f17f17376620a51ee09e0cd7eb4d06d49","user":{"login":"AlexandreAbraham","id":1647301,"avatar_url":"https://avatars.githubusercontent.com/u/1647301?v=3","gravatar_id":"","url":"https://api.github.com/users/AlexandreAbraham","html_url":"https://github.com/AlexandreAbraham","followers_url":"https://api.github.com/users/AlexandreAbraham/followers","following_url":"https://api.github.com/users/AlexandreAbraham/following{/other_user}","gists_url":"https://api.github.com/users/AlexandreAbraham/gists{/gist_id}","starred_url":"https://api.github.com/users/AlexandreAbraham/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AlexandreAbraham/subscriptions","organizations_url":"https://api.github.com/users/AlexandreAbraham/orgs","repos_url":"https://api.github.com/users/AlexandreAbraham/repos","events_url":"https://api.github.com/users/AlexandreAbraham/events{/privacy}","received_events_url":"https://api.github.com/users/AlexandreAbraham/received_events","type":"User","site_admin":false},"body":"Some code like that may help but there will still be a side effect on the generator provided:\r\n```\r\ndef _iter_first(first, iterable):\r\n    yield first\r\n    for i in iterable:\r\n        yield i\r\n\r\n\r\ndef sneak_peek(iterable):\r\n    first = next(iterable)\r\n    return _iter_first(first, iterable), first\r\n```","created_at":"2015-03-10T00:14:26Z","updated_at":"2015-03-10T00:14:26Z","html_url":"https://github.com/nilearn/nilearn/pull/478#discussion_r26089492","pull_request_url":"https://api.github.com/repos/nilearn/nilearn/pulls/478","_links":{"self":{"href":"https://api.github.com/repos/nilearn/nilearn/pulls/comments/26089492"},"html":{"href":"https://github.com/nilearn/nilearn/pull/478#discussion_r26089492"},"pull_request":{"href":"https://api.github.com/repos/nilearn/nilearn/pulls/478"}}},"pull_request":{"url":"https://api.github.com/repos/nilearn/nilearn/pulls/478","id":30370830,"html_url":"https://github.com/nilearn/nilearn/pull/478","diff_url":"https://github.com/nilearn/nilearn/pull/478.diff","patch_url":"https://github.com/nilearn/nilearn/pull/478.patch","issue_url":"https://api.github.com/repos/nilearn/nilearn/issues/478","number":478,"state":"open","locked":false,"title":"Put specific nibabel code in a separate module","user":{"login":"AlexandreAbraham","id":1647301,"avatar_url":"https://avatars.githubusercontent.com/u/1647301?v=3","gravatar_id":"","url":"https://api.github.com/users/AlexandreAbraham","html_url":"https://github.com/AlexandreAbraham","followers_url":"https://api.github.com/users/AlexandreAbraham/followers","following_url":"https://api.github.com/users/AlexandreAbraham/following{/other_user}","gists_url":"https://api.github.com/users/AlexandreAbraham/gists{/gist_id}","starred_url":"https://api.github.com/users/AlexandreAbraham/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AlexandreAbraham/subscriptions","organizations_url":"https://api.github.com/users/AlexandreAbraham/orgs","repos_url":"https://api.github.com/users/AlexandreAbraham/repos","events_url":"https://api.github.com/users/AlexandreAbraham/events{/privacy}","received_events_url":"https://api.github.com/users/AlexandreAbraham/received_events","type":"User","site_admin":false},"body":"This PR is a first step toward fixing #380. I have simply moved all nibabel related code (except for test code and a special hack in MultiPCA) to an indenpendant module. Since this code is already tested by most of nilearn functions, I simply added a test for a special case that wasn't covered.\r\n\r\nI think that the discussion will mostly focus on the naming conventions. I'd like to merge it fast as it will massively impact further PR. We should also be careful for the upcoming PR: nibabel must never be imported except for test (because nilearn input are nibabel objects) and specific Nifti1Image manipulation (in the latter case, the code should be in the dedicated module).","created_at":"2015-03-03T12:54:41Z","updated_at":"2015-03-10T00:14:26Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ec601a1d52a3fc060417d2dbb4b4c1f77f35138c","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/nilearn/nilearn/pulls/478/commits","review_comments_url":"https://api.github.com/repos/nilearn/nilearn/pulls/478/comments","review_comment_url":"https://api.github.com/repos/nilearn/nilearn/pulls/comments{/number}","comments_url":"https://api.github.com/repos/nilearn/nilearn/issues/478/comments","statuses_url":"https://api.github.com/repos/nilearn/nilearn/statuses/e670d6713b1b7f105e6f37da26b1e4d95e61dff9","head":{"label":"AlexandreAbraham:isolate_nibabel","ref":"isolate_nibabel","sha":"e670d6713b1b7f105e6f37da26b1e4d95e61dff9","user":{"login":"AlexandreAbraham","id":1647301,"avatar_url":"https://avatars.githubusercontent.com/u/1647301?v=3","gravatar_id":"","url":"https://api.github.com/users/AlexandreAbraham","html_url":"https://github.com/AlexandreAbraham","followers_url":"https://api.github.com/users/AlexandreAbraham/followers","following_url":"https://api.github.com/users/AlexandreAbraham/following{/other_user}","gists_url":"https://api.github.com/users/AlexandreAbraham/gists{/gist_id}","starred_url":"https://api.github.com/users/AlexandreAbraham/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AlexandreAbraham/subscriptions","organizations_url":"https://api.github.com/users/AlexandreAbraham/orgs","repos_url":"https://api.github.com/users/AlexandreAbraham/repos","events_url":"https://api.github.com/users/AlexandreAbraham/events{/privacy}","received_events_url":"https://api.github.com/users/AlexandreAbraham/received_events","type":"User","site_admin":false},"repo":{"id":4038777,"name":"nilearn","full_name":"AlexandreAbraham/nilearn","owner":{"login":"AlexandreAbraham","id":1647301,"avatar_url":"https://avatars.githubusercontent.com/u/1647301?v=3","gravatar_id":"","url":"https://api.github.com/users/AlexandreAbraham","html_url":"https://github.com/AlexandreAbraham","followers_url":"https://api.github.com/users/AlexandreAbraham/followers","following_url":"https://api.github.com/users/AlexandreAbraham/following{/other_user}","gists_url":"https://api.github.com/users/AlexandreAbraham/gists{/gist_id}","starred_url":"https://api.github.com/users/AlexandreAbraham/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AlexandreAbraham/subscriptions","organizations_url":"https://api.github.com/users/AlexandreAbraham/orgs","repos_url":"https://api.github.com/users/AlexandreAbraham/repos","events_url":"https://api.github.com/users/AlexandreAbraham/events{/privacy}","received_events_url":"https://api.github.com/users/AlexandreAbraham/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/AlexandreAbraham/nilearn","description":"NeuroImaging with the Scikit-learn: fMRI inverse inference tutorial","fork":true,"url":"https://api.github.com/repos/AlexandreAbraham/nilearn","forks_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/forks","keys_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/teams","hooks_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/hooks","issue_events_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/issues/events{/number}","events_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/events","assignees_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/assignees{/user}","branches_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/branches{/branch}","tags_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/tags","blobs_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/git/refs{/sha}","trees_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/statuses/{sha}","languages_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/languages","stargazers_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/stargazers","contributors_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/contributors","subscribers_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/subscribers","subscription_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/subscription","commits_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/commits{/sha}","git_commits_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/git/commits{/sha}","comments_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/comments{/number}","issue_comment_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/issues/comments{/number}","contents_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/contents/{+path}","compare_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/merges","archive_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/downloads","issues_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/issues{/number}","pulls_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/pulls{/number}","milestones_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/milestones{/number}","notifications_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/labels{/name}","releases_url":"https://api.github.com/repos/AlexandreAbraham/nilearn/releases{/id}","created_at":"2012-04-16T08:08:33Z","updated_at":"2015-03-09T15:39:37Z","pushed_at":"2015-03-09T19:23:41Z","git_url":"git://github.com/AlexandreAbraham/nilearn.git","ssh_url":"git@github.com:AlexandreAbraham/nilearn.git","clone_url":"https://github.com/AlexandreAbraham/nilearn.git","svn_url":"https://github.com/AlexandreAbraham/nilearn","homepage":"http://nisl.github.com/","size":6993,"stargazers_count":4,"watchers_count":4,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":7,"forks":1,"open_issues":7,"watchers":4,"default_branch":"master"}},"base":{"label":"nilearn:master","ref":"master","sha":"0760e65dbd122dcb9989b3e3a2ec72ce168522eb","user":{"login":"nilearn","id":4646912,"avatar_url":"https://avatars.githubusercontent.com/u/4646912?v=3","gravatar_id":"","url":"https://api.github.com/users/nilearn","html_url":"https://github.com/nilearn","followers_url":"https://api.github.com/users/nilearn/followers","following_url":"https://api.github.com/users/nilearn/following{/other_user}","gists_url":"https://api.github.com/users/nilearn/gists{/gist_id}","starred_url":"https://api.github.com/users/nilearn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nilearn/subscriptions","organizations_url":"https://api.github.com/users/nilearn/orgs","repos_url":"https://api.github.com/users/nilearn/repos","events_url":"https://api.github.com/users/nilearn/events{/privacy}","received_events_url":"https://api.github.com/users/nilearn/received_events","type":"Organization","site_admin":false},"repo":{"id":1235740,"name":"nilearn","full_name":"nilearn/nilearn","owner":{"login":"nilearn","id":4646912,"avatar_url":"https://avatars.githubusercontent.com/u/4646912?v=3","gravatar_id":"","url":"https://api.github.com/users/nilearn","html_url":"https://github.com/nilearn","followers_url":"https://api.github.com/users/nilearn/followers","following_url":"https://api.github.com/users/nilearn/following{/other_user}","gists_url":"https://api.github.com/users/nilearn/gists{/gist_id}","starred_url":"https://api.github.com/users/nilearn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nilearn/subscriptions","organizations_url":"https://api.github.com/users/nilearn/orgs","repos_url":"https://api.github.com/users/nilearn/repos","events_url":"https://api.github.com/users/nilearn/events{/privacy}","received_events_url":"https://api.github.com/users/nilearn/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nilearn/nilearn","description":"Machine learning for NeuroImaging in Python","fork":false,"url":"https://api.github.com/repos/nilearn/nilearn","forks_url":"https://api.github.com/repos/nilearn/nilearn/forks","keys_url":"https://api.github.com/repos/nilearn/nilearn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nilearn/nilearn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nilearn/nilearn/teams","hooks_url":"https://api.github.com/repos/nilearn/nilearn/hooks","issue_events_url":"https://api.github.com/repos/nilearn/nilearn/issues/events{/number}","events_url":"https://api.github.com/repos/nilearn/nilearn/events","assignees_url":"https://api.github.com/repos/nilearn/nilearn/assignees{/user}","branches_url":"https://api.github.com/repos/nilearn/nilearn/branches{/branch}","tags_url":"https://api.github.com/repos/nilearn/nilearn/tags","blobs_url":"https://api.github.com/repos/nilearn/nilearn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nilearn/nilearn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nilearn/nilearn/git/refs{/sha}","trees_url":"https://api.github.com/repos/nilearn/nilearn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nilearn/nilearn/statuses/{sha}","languages_url":"https://api.github.com/repos/nilearn/nilearn/languages","stargazers_url":"https://api.github.com/repos/nilearn/nilearn/stargazers","contributors_url":"https://api.github.com/repos/nilearn/nilearn/contributors","subscribers_url":"https://api.github.com/repos/nilearn/nilearn/subscribers","subscription_url":"https://api.github.com/repos/nilearn/nilearn/subscription","commits_url":"https://api.github.com/repos/nilearn/nilearn/commits{/sha}","git_commits_url":"https://api.github.com/repos/nilearn/nilearn/git/commits{/sha}","comments_url":"https://api.github.com/repos/nilearn/nilearn/comments{/number}","issue_comment_url":"https://api.github.com/repos/nilearn/nilearn/issues/comments{/number}","contents_url":"https://api.github.com/repos/nilearn/nilearn/contents/{+path}","compare_url":"https://api.github.com/repos/nilearn/nilearn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nilearn/nilearn/merges","archive_url":"https://api.github.com/repos/nilearn/nilearn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nilearn/nilearn/downloads","issues_url":"https://api.github.com/repos/nilearn/nilearn/issues{/number}","pulls_url":"https://api.github.com/repos/nilearn/nilearn/pulls{/number}","milestones_url":"https://api.github.com/repos/nilearn/nilearn/milestones{/number}","notifications_url":"https://api.github.com/repos/nilearn/nilearn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nilearn/nilearn/labels{/name}","releases_url":"https://api.github.com/repos/nilearn/nilearn/releases{/id}","created_at":"2011-01-09T19:02:23Z","updated_at":"2015-03-09T17:45:11Z","pushed_at":"2015-03-09T17:45:11Z","git_url":"git://github.com/nilearn/nilearn.git","ssh_url":"git@github.com:nilearn/nilearn.git","clone_url":"https://github.com/nilearn/nilearn.git","svn_url":"https://github.com/nilearn/nilearn","homepage":"http://nilearn.github.io","size":12175,"stargazers_count":75,"watchers_count":75,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":56,"mirror_url":null,"open_issues_count":76,"forks":56,"open_issues":76,"watchers":75,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/nilearn/nilearn/pulls/478"},"html":{"href":"https://github.com/nilearn/nilearn/pull/478"},"issue":{"href":"https://api.github.com/repos/nilearn/nilearn/issues/478"},"comments":{"href":"https://api.github.com/repos/nilearn/nilearn/issues/478/comments"},"review_comments":{"href":"https://api.github.com/repos/nilearn/nilearn/pulls/478/comments"},"review_comment":{"href":"https://api.github.com/repos/nilearn/nilearn/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/nilearn/nilearn/pulls/478/commits"},"statuses":{"href":"https://api.github.com/repos/nilearn/nilearn/statuses/e670d6713b1b7f105e6f37da26b1e4d95e61dff9"}}}}