Source code for AFQ.data.fetch

from dipy.align import resample
from dipy.segment.clustering import QuickBundles
from dipy.segment.metric import AveragePointwiseEuclideanMetric
from dipy.segment.featurespeed import ResampleFeature
from dipy.io.streamline import (
    load_tractogram, save_tractogram, StatefulTractogram, Space)
from dipy.data.fetcher import _make_fetcher
import dipy.data as dpd
from AFQ.utils.path import drop_extension, apply_cmd_to_afq_derivs

import os
import os.path as op
import json
from glob import glob
import shutil

import numpy as np
import pandas as pd
import logging
import time
from tqdm import tqdm

import warnings
import nibabel as nib
import boto3
from botocore import UNSIGNED
from botocore.client import Config


# capture templateflow resource warning and log
default_warning_format = warnings.formatwarning
try:
    warnings.formatwarning = lambda msg, *args, **kwargs: f'{msg}'
    logging.captureWarnings(True)
    pywarnings_logger = logging.getLogger('py.warnings')
    console_handler = logging.StreamHandler()
    console_handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
    pywarnings_logger.addHandler(console_handler)

    warnings.filterwarnings(
        "default", category=ResourceWarning,
        module="templateflow")

    from templateflow import api as tflow
finally:
    logging.captureWarnings(False)
    warnings.formatwarning = default_warning_format


__all__ = ["fetch_callosum_templates", "read_callosum_templates",
           "fetch_or_templates", "read_or_templates",
           "fetch_templates", "read_templates",
           "fetch_stanford_hardi_tractography",
           "read_stanford_hardi_tractography",
           "organize_stanford_data",
           "fetch_stanford_hardi_lv1"]


# Set a user-writeable file-system location to put files:
if 'AFQ_HOME' in os.environ:
    afq_home = os.environ['AFQ_HOME']
else:
    afq_home = op.join(op.expanduser('~'), 'AFQ_data')

baseurl = "https://ndownloader.figshare.com/files/"


def _make_reusable_fetcher(name, folder, baseurl, remote_fnames, local_fnames,
                           doc="", md5_list=None, **make_fetcher_kwargs):
    def fetcher():
        all_files_downloaded = True
        for fname in local_fnames:
            if not op.exists(op.join(folder, fname)):
                all_files_downloaded = False
        if all_files_downloaded:
            files = {}
            for i, (f, n), in enumerate(zip(remote_fnames, local_fnames)):
                files[n] = (baseurl + f, md5_list[i] if
                            md5_list is not None else None)
            return files, folder
        else:
            return _make_fetcher(
                name, folder, baseurl, remote_fnames, local_fnames,
                doc=doc, **make_fetcher_kwargs)()
    fetcher.__name__ = name
    fetcher.__doc__ = doc
    return fetcher


def _fetcher_to_template(fetcher, as_img=False, resample_to=False):
    if isinstance(resample_to, str):
        resample_to = nib.load(resample_to)
    files, folder = fetcher()
    template_dict = {}
    for f in files:
        img = op.join(folder, f)
        if as_img:
            img = nib.load(img)
        if resample_to:
            img = nib.Nifti1Image(resample(img.get_fdata(),
                                           resample_to,
                                           img.affine,
                                           resample_to.affine).get_fdata(),
                                  resample_to.affine)
        template_dict[drop_extension(f)] = img
    return template_dict


callosum_fnames = ["Callosum_midsag.nii.gz",
                   "L_AntFrontal.nii.gz",
                   "L_Motor.nii.gz",
                   "L_Occipital.nii.gz",
                   "L_Orbital.nii.gz",
                   "L_PostParietal.nii.gz",
                   "L_SupFrontal.nii.gz",
                   "L_SupParietal.nii.gz",
                   "L_Temporal.nii.gz",
                   "R_AntFrontal.nii.gz",
                   "R_Motor.nii.gz",
                   "R_Occipital.nii.gz",
                   "R_Orbital.nii.gz",
                   "R_PostParietal.nii.gz",
                   "R_SupFrontal.nii.gz",
                   "R_SupParietal.nii.gz",
                   "R_Temporal.nii.gz"]

callosum_remote_fnames = ["5273794", "5273797", "5273800", "5273803",
                          "5273806", "5273809", "5273812", "5273815",
                          "5273821", "5273818", "5273824", "5273827",
                          "5273830", "5273833", "5273836", "5273839",
                          "5273842"]

callosum_md5_hashes = ["709fa90baadeacd64f1d62b5049a4125",
                       "987c6169de807c4e93dc2cbd7a25d506",
                       "0da114123d0b0097b96fe450a459550b",
                       "6d845bd10504f67f1dc17f9000076d7e",
                       "e16c7873ef4b08d26b77ef746dab8237",
                       "47193fd4df1ea17367817466de798b90",
                       "7e78bf9671e6945f4b2f5e7c30595a3c",
                       "8adbb947377ff7b484c88d8c0ffc2125",
                       "0fd981a4d0847e0642ff96e84fe44e47",
                       "87c4855efa406d8fb004cffb8259180e",
                       "c7969bcf5f2343fd9ce9c49b336cf14c",
                       "bb4372b88991932150205ffb22aa6cb7",
                       "d198d4e7db18ddc7236cf143ecb8342e",
                       "d0f6edef64b0c710c92e634496085dda",
                       "85eaee44665f244db5adae2e259833f6",
                       "25f24eb22879a05d12bda007c81ea55a",
                       "2664e0b8c2d9c59f13649a89bfcce399"]

[docs]fetch_callosum_templates = _make_reusable_fetcher( "fetch_callosum_templates", op.join(afq_home, 'callosum_templates'), baseurl, callosum_remote_fnames, callosum_fnames, md5_list=callosum_md5_hashes, doc="Download AFQ callosum templates")
[docs]def read_callosum_templates(as_img=True, resample_to=False): """Load AFQ callosum templates from file Parameters ---------- as_img : bool, optional If True, values are `Nifti1Image`. Otherwise, values are paths to Nifti files. Default: True resample_to : str or nibabel image class instance, optional A template image to resample to. Typically, this should be the template to which individual-level data are registered. Defaults to the MNI template. Default: False Returns ------- dict with: keys: names of template ROIs and values: nibabel Nifti1Image objects from each of the ROI nifti files. """ logger = logging.getLogger('AFQ') logger.debug('loading callosum templates') tic = time.perf_counter() template_dict = _fetcher_to_template( fetch_callosum_templates, as_img=as_img, resample_to=resample_to) toc = time.perf_counter() logger.debug(f'callosum templates loaded in {toc - tic:0.4f} seconds') return template_dict
########################################################################## # Pediatric templates: # -------------------- # # Templates include the UNC 0-1-2 Infant Atlases and waypoint ROIs matched # to the atlas. # # Information on: # # - atlas: https://www.nitrc.org/projects/pediatricatlas # # - pediatric templates: https://github.com/yeatmanlab/AFQ/tree/babyAFQ # # Templates downloaded from: # # - https://figshare.com/articles/dataset/ROIs_probabilistic_maps_and_transform_data_for_pediatric_automated_fiber_quantification/13027487 # noqa # pediatric_fnames = [ "ATR_roi1_L.nii.gz", "ATR_roi1_R.nii.gz", "ATR_roi2_L.nii.gz", "ATR_roi2_R.nii.gz", "ATR_roi3_L.nii.gz", "ATR_roi3_R.nii.gz", "CGC_roi1_L.nii.gz", "CGC_roi1_R.nii.gz", "CGC_roi2_L.nii.gz", "CGC_roi2_R.nii.gz", "CGC_roi3_L.nii.gz", "CGC_roi3_R.nii.gz", "CST_roi1_L.nii.gz", "CST_roi1_R.nii.gz", "CST_roi2_L.nii.gz", "CST_roi2_R.nii.gz", "FA_L.nii.gz", "FA_R.nii.gz", "FP_L.nii.gz", "FP_R.nii.gz", "HCC_roi1_L.nii.gz", "HCC_roi1_R.nii.gz", "HCC_roi2_L.nii.gz", "HCC_roi2_R.nii.gz", "IFO_roi1_L.nii.gz", "IFO_roi1_R.nii.gz", "IFO_roi2_L.nii.gz", "IFO_roi2_R.nii.gz", "IFO_roi3_L.nii.gz", "IFO_roi3_R.nii.gz", "ILF_roi1_L.nii.gz", "ILF_roi1_R.nii.gz", "ILF_roi2_L.nii.gz", "ILF_roi2_R.nii.gz", "LH_Parietal.nii.gz", "RH_Parietal.nii.gz", "MdLF_roi1_L.nii.gz", "MdLF_roi1_R.nii.gz", "SLF_roi1_L.nii.gz", "SLF_roi1_R.nii.gz", "SLF_roi2_L.nii.gz", "SLF_roi2_R.nii.gz", "SLFt_roi2_L.nii.gz", "SLFt_roi2_R.nii.gz", "SLFt_roi3_L.nii.gz", "SLFt_roi3_R.nii.gz", "UNC_roi1_L.nii.gz", "UNC_roi1_R.nii.gz", "UNC_roi2_L.nii.gz", "UNC_roi2_R.nii.gz", "UNC_roi3_L.nii.gz", "UNC_roi3_R.nii.gz", "VOF_box_L.nii.gz", "VOF_box_R.nii.gz", "UNCNeo-withCerebellum-for-babyAFQ.nii.gz", "UNCNeo_JHU_tracts_prob-for-babyAFQ.nii.gz", "mid-saggital.nii.gz", "OR_rightV1.nii.gz", "OR_rightThal.nii.gz", "OR_right_roi3.nii.gz", "OR_leftV1.nii.gz", "OR_leftThal.nii.gz", "OR_left_roi3.nii.gz", "pARC_R_start.nii.gz", "pARC_L_start.nii.gz", "VOF_box_small_L.nii.gz", "VOF_box_small_R.nii.gz", "VOF_L_start.nii.gz", "VOF_R_start.nii.gz", ] pediatric_md5_hashes = [ "2efe0deb19ac9e175404bf0cb29d9dbd", "c2e07cd50699527bd7b0cbbe88703c56", "76b36d8d6759df58131644281ed16bd2", "645102225bad33da30bafd41d24b3ab0", "45ec94d42fdc9448afa6760c656920e9", "54e3cb1b8c242be279f1410d8bb3c383", "1ee9f7e8b21ef8ceee81d5a7a178ef33", "4f11097f7ae317aa8d612511be79e2f1", "1c4c0823c23b676d6d35004d93b9c695", "d4830d558cc8f707ebec912b32d197a5", "c405e0dbd9a4091c77b3d1ad200229b4", "ec0aeccc6661d2ee5ed79259383cdcee", "2802cd227b550f6e85df0fec1d515c29", "385addb999dc6d76957d2a35c4ee74bb", "0dd14c02b272263adbe2246880979c9d", "99dac5a00c10d81d222f020162fd6194", "e49ba370edca96734d9376f551d413db", "f59e9e69e06325198f70047cd63c3bdc", "ae3bd2931f95adae0280a8f75cd3ca9b", "c409a0036b8c2dd4d03d11fbc6bfbdcd", "c2597a474ea5ec9e3126c35fd238f6b2", "67af59c934147c9f9ff6e0b76c4cc6eb", "72d0bbc0b6162e9291fdc450c103a1f0", "51f5041be63ad0ac10d1ac09e3bf1a8e", "6200f5cdc1402dce46dedd505468b147", "83cb5bf6b9b1eda63c8643871e84a6d4", "2a5d8d309b1256d6e48958e112201c2c", "ba24d0915fdff215a403480d0a7745c9", "1001e833d1344274d543ffd02a66af80", "03e20c5eebcd4d439c4ffb36d26a10d9", "6200f5cdc1402dce46dedd505468b147", "83cb5bf6b9b1eda63c8643871e84a6d4", "a6ae325cce2dc4bb21b52ee4c6ca844f", "a96a31df8f96ccf1c5f871a18e4a2d72", "65b7378ca85689a5f23b1b84a6ed78f0", "ce0d0ea696ef51c671aa118e11192e2d", "ce4918086ca1e829698576bcf95db62b", "96168d2eff74ec2acf9065f499732526", "6b20ba319d44472ec21d6ece937605bb", "26b1cf6ec8bd365dde42e3efe9beeac2", "0b3ccf06564d973bfcfff9a87e74f8b5", "84f3426033a2b225b0920b2622864375", "5351b3cb7efa9aa8e83e266342809ebe", "4e8a34aaba4e0f22a6149f38620dc39d", "682c08f66e8c2cf9e4e60f5ce308c76c", "9077affd4f3a8a1d6b44678cde4b3bf4", "5adf36f00669cc547d5eb978acf46266", "66a8002688ffdf3943722361da90ec6a", "efb5ae138df92019541861f9aa6a4d57", "757ec61078b2e9f9a073871b3216ff7a", "ff1e238c52a21f8cc5d44ac614d9627f", "cf16dd2767c6ab2d3fceb2890f6c3e41", "6016621e244b60b9c69fd44b055e4a03", "fd495a2c94b6b13bfb4cd63e293d3fc0", "bf81a23d80f55e5f1eb0c16717193105", "6f8bf8f70216788d14d9a49a3c664b16", "19df0297d6a2ac21da5e432645d63174", "b4ffb957a2adbb8b76966e4ea28dbdf1", "3de1bc5aae4c76164f34515e2e84939c", "705ba1cbfc42ce64a54dda2b732f81f2", "bc6d4f880d3eb281358af1c764779704", "a3b6a7be067aa12af273482baee1498d", "f035813314960eb91f3a4dae508a68e5", "728461f81fcfa8f02ff3af969ab6499c", "5c1c87ee71c512b38a0711b93bb7e9fe", "4652bcf7a1f2b7cdeec52956eb884795", "e1c4bf76d2c98dcf6ffe00399a6e8b07", "0ecabd68fa9c56614e2a694359c0a545", "4c93bea7a72ac2b7475201acef5a1fc4", ] pediatric_remote_fnames = [ "24880625", "24880628", "24880631", "24880634", "24880637", "24880640", "24880643", "24880646", "24880649", "24880652", "24880655", "24880661", "24880664", "24880667", "46407571", "46407568", "24880676", "24880679", "24880685", "24880688", "24880691", "24880694", "24880697", "24880700", "24880703", "24880706", "24880712", "24880715", "24880718", "24880721", "24880724", "24880727", "24880730", "24880733", "24880736", "24880748", "24880739", "24880742", "24880754", "24880757", "24880760", "24880763", "24880769", "24880772", "24880775", "24880778", "24880781", "24880787", "24880790", "24880793", "24880796", "24880802", "24880805", "24880808", "24880616", "24880613", "24986396", "42120480", "42120483", "42120486", "42120489", "42120492", "42120495", "42121791", "42121794", "42121836", "42121839", "42121803", "42121806", ] fetch_pediatric_templates = _make_reusable_fetcher( 'fetch_pediatric_templates', op.join(afq_home, 'pediatric_templates'), 'https://ndownloader.figshare.com/files/', pediatric_remote_fnames, pediatric_fnames, md5_list=pediatric_md5_hashes, doc='Download pediatric templates' ) def read_pediatric_templates(as_img=True, resample_to=False): """ Load pediatric pyAFQ templates. Used to create pediatric `bundle_dict`. Parameters ---------- as_img : bool, optional If True, values are `Nifti1Image`. Otherwise, values are paths to Nifti files. Default: True resample_to : str or nibabel image class instance, optional A template image to resample to. Typically, this should be the template to which individual-level data are registered. Defaults to the MNI template. Default: False Returns ------- dict : keys = names of template ROIs, and values = `Nifti1Image` from each of the ROI nifti files. """ print('Loading pediatric templates...', flush=True) pediatric_templates = _fetcher_to_template( fetch_pediatric_templates, as_img=as_img, resample_to=resample_to) # For the arcuate (AF/ARC), reuse the SLF ROIs pediatric_templates['ARC_roi1_L'] = pediatric_templates['SLF_roi1_L'] pediatric_templates['ARC_roi1_R'] = pediatric_templates['SLF_roi1_R'] pediatric_templates['ARC_roi2_L'] = pediatric_templates['SLFt_roi2_L'] pediatric_templates['ARC_roi2_R'] = pediatric_templates['SLFt_roi2_R'] pediatric_templates['ARC_roi3_L'] = pediatric_templates['SLFt_roi3_L'] pediatric_templates['ARC_roi3_R'] = pediatric_templates['SLFt_roi3_R'] # For the middle longitudinal fasciculus (MdLF) reuse ILF ROI pediatric_templates['MdLF_roi2_L'] = pediatric_templates['ILF_roi2_L'] pediatric_templates['MdLF_roi2_R'] = pediatric_templates['ILF_roi2_R'] return pediatric_templates def read_resample_roi(roi, resample_to=None, threshold=False): """ Reads an roi from file-name/img and resamples it to conform with another file-name/img. Parameters ---------- roi : str or nibabel image class instance. Should contain a binary volume with 1s in the region of interest and 0s elsewhere. resample_to : str or nibabel image class instance, optional A template image to resample to. Typically, this should be the template to which individual-level data are registered. Defaults to the MNI template. threshold: bool or float If set to False (default), resampled result is returned. Otherwise, the resampled result is thresholded at this value and binarized. This is not applied if the input ROI is already in the space of the output. Returns ------- nibabel image class instance that contains the binary ROI resampled into the requested space. """ if isinstance(roi, str): roi = nib.load(roi) if resample_to is None: resample_to = read_mni_template() if isinstance(resample_to, str): resample_to = nib.load(resample_to) if resample_to is False or np.allclose(resample_to.affine, roi.affine): return roi as_array = resample( roi.get_fdata(), resample_to, roi.affine, resample_to.affine).get_fdata() if threshold: as_array = (as_array > threshold).astype(int) img = nib.Nifti1Image( as_array, resample_to.affine) return img template_fnames = ["ATR_roi1_L.nii.gz", "ATR_roi1_R.nii.gz", "ATR_roi2_L.nii.gz", "ATR_roi2_R.nii.gz", "ATR_L_prob_map.nii.gz", "ATR_R_prob_map.nii.gz", "CGC_roi1_L.nii.gz", "CGC_roi1_R.nii.gz", "CGC_roi2_L.nii.gz", "CGC_roi2_R.nii.gz", "CGC_L_prob_map.nii.gz", "CGC_R_prob_map.nii.gz", "CST_roi1_L.nii.gz", "CST_roi1_R.nii.gz", "CST_roi2_L.nii.gz", "CST_roi2_R.nii.gz", "CST_L_prob_map.nii.gz", "CST_R_prob_map.nii.gz", "FA_L.nii.gz", "FA_R.nii.gz", "FA_prob_map.nii.gz", "FP_L.nii.gz", "FP_R.nii.gz", "FP_prob_map.nii.gz", "HCC_roi1_L.nii.gz", "HCC_roi1_R.nii.gz", "HCC_roi2_L.nii.gz", "HCC_roi2_R.nii.gz", "HCC_L_prob_map.nii.gz", "HCC_R_prob_map.nii.gz", "IFO_roi1_L.nii.gz", "IFO_roi1_R.nii.gz", "IFO_roi2_L.nii.gz", "IFO_roi2_R.nii.gz", "IFO_L_prob_map.nii.gz", "IFO_R_prob_map.nii.gz", "ILF_roi1_L.nii.gz", "ILF_roi1_R.nii.gz", "ILF_roi2_L.nii.gz", "ILF_roi2_R.nii.gz", "ILF_L_prob_map.nii.gz", "ILF_R_prob_map.nii.gz", "SLF_roi1_L.nii.gz", "SLF_roi1_R.nii.gz", "SLF_roi2_L.nii.gz", "SLF_roi2_R.nii.gz", "SLFt_roi2_L.nii.gz", "SLFt_roi2_R.nii.gz", "SLF_L_prob_map.nii.gz", "SLF_R_prob_map.nii.gz", "UNC_roi1_L.nii.gz", "UNC_roi1_R.nii.gz", "UNC_roi2_L.nii.gz", "UNC_roi2_R.nii.gz", "UNC_L_prob_map.nii.gz", "UNC_R_prob_map.nii.gz", "ARC_L_prob_map.nii.gz", "ARC_R_prob_map.nii.gz", "VOF_R_end.nii.gz", "VOF_R_start.nii.gz", "VOF_L_end.nii.gz", "VOF_L_start.nii.gz", "pARC_R_start.nii.gz", "pARC_L_start.nii.gz", "ARC_R_end.nii.gz", "ARC_R_start.nii.gz", "ARC_L_end.nii.gz", "ARC_L_start.nii.gz", "UNC_R_end.nii.gz", "UNC_R_start.nii.gz", "UNC_L_end.nii.gz", "UNC_L_start.nii.gz", "SLF_R_end.nii.gz", "SLF_R_start.nii.gz", "SLF_L_end.nii.gz", "SLF_L_start.nii.gz", "ILF_R_end.nii.gz", "ILF_R_start.nii.gz", "ILF_L_end.nii.gz", "ILF_L_start.nii.gz", "IFO_R_end.nii.gz", "IFO_R_start.nii.gz", "IFO_L_end.nii.gz", "IFO_L_start.nii.gz", "FA_end.nii.gz", "FA_start.nii.gz", "FP_end.nii.gz", "FP_start.nii.gz", "CGC_R_start.nii.gz", "CGC_L_start.nii.gz", "CST_R_end.nii.gz", "CST_R_start.nii.gz", "CST_L_end.nii.gz", "CST_L_start.nii.gz", "ATR_R_end.nii.gz", "ATR_R_start.nii.gz", "ATR_L_end.nii.gz", "ATR_L_start.nii.gz"] template_remote_fnames = ["5273680", "5273683", "5273686", "5273689", "11458274", "11458277", "5273695", "5273692", "5273698", "5273701", "11458268", "11458271", "5273704", "5273707", "46407574", "46407577", "11458262", "11458265", "5273716", "5273719", "11458220", "5273722", "5273725", "11458226", "5273728", "5273731", "5273734", "5273746", "11458259", "11458256", "5273737", "5273740", "5273743", "5273749", "11458250", "11458253", "5273752", "5273755", "5273758", "5273761", "11458244", "11458247", "5273764", "5273767", "5273770", "5273773", "5273776", "5273791", "11458238", "11458241", "5273779", "5273782", "5273785", "5273788", "11458223", "11458229", "11458232", "11458235", "40943957", "40943960", "40943966", "40943969", "40943972", "40943975", "40943978", "40943981", "40943984", "40943987", "40943990", "40943993", "40943996", "40943999", "40944002", "40944005", "40944008", "40944011", "40944014", "40944017", "40944020", "40944023", "40944026", "40944029", "40944032", "40944035", "40944038", "40944041", "40944044", "40944047", "40944050", "40944053", "40944056", "40944059", "40944062", "40944065", "40944068", "40944074", "40944077", "40944080"] template_md5_hashes = ["6b7aaed1a2982fd0ea436a223133908b", "fd60d46d4e3cbd906c86e4c9e4fd6e2a", "3aba60b169a35c38640de4ec29d362c8", "12716a5688a1809fbaed1d58d2e68b59", "c5637f471df861d9bbb45604db34770b", "850cc4c04d7241747063fe3cd440b2ce", "8e8973bc7838c8744914d402f52d91ca", "c5fa4e6e685e695c006823b6784d2407", "e1fab77f21d5303ed52285f015e24f0b", "5f89defec3753fd75cd688c7bfb20a36", "a4f3cd65b06fb25f63d5dab7592f00f2", "7e73ab02db30a3ad6bd9e82148c2486e", "f9db3154955a20b67c2dda758800d14c", "73941510c798c1ed1b03e2bd481cd5c7", "b20e0caa54cf35002cd06cf6033b964f", "e751306df304af32c3ce7617913bbd30", "fd012bc89f6bed7bd54530195496bac4", "3406906a86e633cc102127cf210a1063", "9040a7953dcbbf131d135c866182d8ef", "a72e17194824fcd838a594a2eb50c72e", "627d7bb2e6d55f8243da815a36d9ff1a", "55adbe9b8279185eedbe342149e1ff90", "5a7412a3cf0fb185eec53d1989df2f7c", "1aa36e83ae7b5555bb19d776ede9c18d", "ba453196ff179b0e31172806e313b52c", "d85c6574526b296935f34bf4f65cd493", "9b81646317f59c7db087f27e2f85679e", "9806e82c250e4604534b96917f87b7e8", "213d3fb1ccd756d878f9b50b765b1c8f", "f1e7e6bc51aa0aa279c54fb3805fb5e3", "0e68a9feaaddcc9b4d667c2f15903368", "d45020a87ee4bb496edd350631d91f6a", "75c2c911826ec4b23159f9bd80e3c039", "55d616ea9e0c646adc1aafa0f5fbe625", "dee83fa6b03cfa5e0f5c965953aa6778", "a13eef7059c98568adfefbab660e434e", "045b7d5c6341997f3f0120c3a4212ad8", "d174b1359ba982b03840436c93b7bbb4", "fff9753f394fc4c73fb2ae40b3b4dde0", "cd278b4dd6ff77481ea9ac16485a5ae2", "7bdf5111265107091c7a2fca9215de30", "7d4a43714504e6e930f922c9bc2a13d5", "af2bcedf47e193686af329b9a8e259da", "9a1122943579d11ba169d3ad87a75625", "627903f7a06627bfd4153dc9245fa390", "1714cd7f989c3435bdd5a2076e6272a0", "1fa2114049707a4e05b53f9d95730375", "b6663067d5ea53c70cb8803948f8adf7", "d3e068997ebc60407bd6e9576e47dede", "27ecfbd1d2f98213e52d73b7d70fe0e7", "fa141bb2d951bec486916acda3652d95", "d391d073e86e28588be9a6d01b2e7a82", "a3e085562e6b8111c7ebc358f9450c8b", "d65c67910807504735e034f7ea92d590", "93cb24a9128db1a6c34a09eaf79fe7f0", "71a7455cb4062dc39b1677c118c7b5a5", "19590c712f1776da1fdba64d4eb7f1f6", "04d5af0feb2c1b5b52a87ccbbf148e4b", "53c277be990d00f7de04f2ea35e74d73", "d37d815fd1bdaaf3a9d2dcfc3ccb1345", "95ed3189d8ac152945e6be1eb24381a3", "a9007e6f2d6ae13ef182f65057c06573", "c6eb9ee33b7caf691749e266f89e8ec4", "a06b2e2e52c09a601f683dc39859a7f1", "bee876a34fdb03e69a418b791f90975a", "680749c9e4565bc02492019d57d8e7d7", "ffc157e9f73a43eff23821f2cfca614a", "a92beacd59ff2c90408edc7407a571c4", "1c0b570bb2d622718b01ee2c429a5d15", "4d3db603f7cc86b5696b1514c5b43e0e", "96c644616e8724b4d071c64981363e6c", "9be681028226aa9b70fac46f8e376282", "e19274bd1ee58906c03f5f9a7c4f01c5", "1d33ac68aeb8eb444c07b5a853414727", "ca3c698154d77217c9480123a49c73dd", "b17d876c0ca51f0e3ec6177382aa4ecf", "6ff7e2dd357affc7c4e4d79f5f5866e9", "96c644616e8724b4d071c64981363e6c", "de045095d914d4929409e062fc1a09b6", "e19274bd1ee58906c03f5f9a7c4f01c5", "69009da4aa52607962ec99b9e248a39f", "2b106da3ed88e4cc9a5b4c391cf3445d", "de045095d914d4929409e062fc1a09b6", "0d28a8e367646f9f0036ba7a100e49e5", "69009da4aa52607962ec99b9e248a39f", "1c0b570bb2d622718b01ee2c429a5d15", "ffc157e9f73a43eff23821f2cfca614a", "69009da4aa52607962ec99b9e248a39f", "de045095d914d4929409e062fc1a09b6", "9d897a3ab960931c5119a9bbfc6d7838", "0046be49e39cf8c639418c805de8b9e2", "67d8f24bd749d8a9094ccb9d8e63fa25", "5736d28551296253f879c4b0d450b70e", "67d8f24bd749d8a9094ccb9d8e63fa25", "5736d28551296253f879c4b0d450b70e", "5f2c0c0f1b7b32ba0a8474a460a2b980", "ffc157e9f73a43eff23821f2cfca614a", "a8d308a93b26242c04b878c733cb252f", "1c0b570bb2d622718b01ee2c429a5d15"]
[docs]fetch_templates = _make_reusable_fetcher( "fetch_templates", op.join(afq_home, 'templates'), baseurl, template_remote_fnames, template_fnames, md5_list=template_md5_hashes, doc="Download AFQ templates")
[docs]def read_templates(as_img=True, resample_to=False): """Load AFQ templates from file Parameters ---------- as_img : bool, optional If True, values are `Nifti1Image`. Otherwise, values are paths to Nifti files. Default: True resample_to : str or nibabel image class instance, optional A template image to resample to. Typically, this should be the template to which individual-level data are registered. Defaults to the MNI template. Default: False Returns ------- dict with: keys: names of template ROIs and values: nibabel Nifti1Image objects from each of the ROI nifti files. """ logger = logging.getLogger('AFQ') logger.debug('loading AFQ templates') tic = time.perf_counter() template_dict = _fetcher_to_template( fetch_templates, as_img=as_img, resample_to=resample_to) toc = time.perf_counter() logger.debug(f'AFQ templates loaded in {toc - tic:0.4f} seconds') return template_dict
cp_fnames = [ "ICP_L_inferior_prob.nii.gz", "ICP_L_superior_prob.nii.gz", "ICP_R_inferior_prob.nii.gz", "ICP_R_superior_prob.nii.gz", "MCP_L_inferior_prob.nii.gz", "MCP_L_superior_prob.nii.gz", "MCP_R_inferior_prob.nii.gz", "MCP_R_superior_prob.nii.gz", "SCP_L_inferior_prob.nii.gz", "SCP_L_inter_prob.nii.gz", "SCP_L_superior_prob.nii.gz", "SCP_R_inferior_prob.nii.gz", "SCP_R_inter_prob.nii.gz", "SCP_R_superior_prob.nii.gz"] cp_remote_fnames = [ "40897772", "40897787", "40897805", "40897769", "40897778", "40897799", "40897784", "40897808", "40897772", "40897781", "40897793", "40897790", "40897775", "40897796"] cp_md5_hashes = [ "7ec3a78f30aefe8c7e2a99773941b8f4", "fc6b088f359201aff480d8e2f7b17eef", "e9688ff4554b768f79a64731705107f9", "f1959600d6aaae58d7ba4ce5e63c5e3b", "e68c669d58bd2cbb3490bd952957009e", "eb7643fd54f6046cd71b7ac085679594", "746da79d0639630c1eb872b2895814ee", "3f69b20a8a7dec4839cef461667d18a5", "4d95b3d3804352eae6e66fe024f1baf5", "a9410ab5fe3240cc8ef929062d54cc9e", "531babda0dd284bda4a5b4b1303f8266", "dde4907d7914dfe71ed07436b073bd75", "c02f2fcb48c33fe4b2988087075e9566", "62e32e090cd326790c3fdbc6acb8eb75"] fetch_cp_templates = _make_reusable_fetcher( "fetch_cb_templates", op.join(afq_home, 'cp_templates'), baseurl, cp_remote_fnames, cp_fnames, md5_list=cp_md5_hashes, doc="Download AFQ cerebellar penducles templates") def read_cp_templates(as_img=True, resample_to=False): """Load AFQ Cerebellar penducles templates from file Parameters ---------- as_img : bool, optional If True, values are `Nifti1Image`. Otherwise, values are paths to Nifti files. Default: True resample_to : str or nibabel image class instance, optional A template image to resample to. Typically, this should be the template to which individual-level data are registered. Defaults to the MNI template. Default: False Returns ------- dict with: keys: names of template ROIs and values: nibabel Nifti1Image objects from each of the ROI nifti files. """ logger = logging.getLogger('AFQ') logger.debug('loading or templates') tic = time.perf_counter() template_dict = _fetcher_to_template( fetch_cp_templates, as_img=as_img, resample_to=resample_to) toc = time.perf_counter() logger.debug( f'Cerebellar peduncles templates loaded in {toc - tic:0.4f} seconds') return template_dict or_fnames = [ "left_thal_MNI.nii.gz", "left_V1_MNI.nii.gz", "right_thal_MNI.nii.gz", "right_V1_MNI.nii.gz", "left_OP_MNI.nii.gz", "left_OR_1.nii.gz", "left_OR_2.nii.gz", "left_pos_thal_MNI.nii.gz", "left_TP_MNI.nii.gz", "right_OP_MNI.nii.gz", "right_OR_1.nii.gz", "right_OR_2.nii.gz", "right_pos_thal_MNI.nii.gz", "right_TP_MNI.nii.gz", ] or_remote_fnames = [ "36514170", "26831633", "36514173", "26831639", "26831642", "26831645", "26831648", "26831651", "26831654", "26831657", "26831660", "26831663", "26831666", "26831669", ] or_md5_hashes = [ "a45126a727c4b5d843b2f7aae181825f", "ad996c67bf5cc59fc3a7b60255873b67", "7a75c3ddd25335277a099626dbc946ac", "cc88fb4671311404eb9dfa8fa11a59e0", "9cff03af586d9dd880750cef3e0bf63f", "ff728ba3ffa5d1600bcd19fdef8182c4", "4f1978e418a3169609375c28b3eba0fd", "fd163893081b520f4594171aeea04f39", "bf795d197912b5e074d248d2763c6930", "13efde1efe0de52683cbf352ecba457e", "75c7bd2092950578e599a2dcb218909f", "8f3890fa8c26a568503226757f7e7d6c", "f239aa3140809152da8884ff879dde1b", "60a748567e4dd81b40ad8967a14cb09e", ] ar_fnames = [ "AAL_Thal_R.nii.gz", "AAL_Thal_L.nii.gz", "AAL_TempSup_L.nii.gz", "AAL_TempSup_R.nii.gz", ] ar_remote_fnames = [ "43817367", "43817370", "43817373", "43817376", ] ar_md5_hashes = [ "5f2c0c0f1b7b32ba0a8474a460a2b980", "a8d308a93b26242c04b878c733cb252f", "92a255f706dd4e09268c5bc6bf2876e4", "ec0a3ef3cb3a4c549dd783dc8aeceeee", ] fetch_ar_templates = _make_reusable_fetcher( "fetch_ar_templates", op.join(afq_home, 'ar_templates'), baseurl, ar_remote_fnames, ar_fnames, md5_list=ar_md5_hashes, doc="Download AFQ or templates") def read_ar_templates(as_img=True, resample_to=False): """Load AFQ AR templates from file Parameters ---------- as_img : bool, optional If True, values are `Nifti1Image`. Otherwise, values are paths to Nifti files. Default: True resample_to : str or nibabel image class instance, optional A template image to resample to. Typically, this should be the template to which individual-level data are registered. Defaults to the MNI template. Default: False Returns ------- dict with: keys: names of template ROIs and values: nibabel Nifti1Image objects from each of the ROI nifti files. """ logger = logging.getLogger('AFQ') logger.debug('loading ar templates') tic = time.perf_counter() template_dict = _fetcher_to_template( fetch_ar_templates, as_img=as_img, resample_to=resample_to) toc = time.perf_counter() logger.debug(f'or templates loaded in {toc - tic:0.4f} seconds') return template_dict
[docs]fetch_or_templates = _make_reusable_fetcher( "fetch_or_templates", op.join(afq_home, 'or_templates'), baseurl, or_remote_fnames, or_fnames, md5_list=or_md5_hashes, doc="Download AFQ or templates")
[docs]def read_or_templates(as_img=True, resample_to=False): """Load AFQ OR templates from file Parameters ---------- as_img : bool, optional If True, values are `Nifti1Image`. Otherwise, values are paths to Nifti files. Default: True resample_to : str or nibabel image class instance, optional A template image to resample to. Typically, this should be the template to which individual-level data are registered. Defaults to the MNI template. Default: False Returns ------- dict with: keys: names of template ROIs and values: nibabel Nifti1Image objects from each of the ROI nifti files. """ logger = logging.getLogger('AFQ') logger.debug('loading or templates') tic = time.perf_counter() template_dict = _fetcher_to_template( fetch_or_templates, as_img=as_img, resample_to=resample_to) toc = time.perf_counter() logger.debug(f'or templates loaded in {toc - tic:0.4f} seconds') return template_dict
stanford_hardi_tractography_remote_fnames = ["5325715", "5325718", "25289735"] stanford_hardi_tractography_hashes = ['6f4bdae702031a48d1cd3811e7a42ef9', 'f20854b4f710577c58bd01072cfb4de6', '294bfd1831861e8635eef8834ff18892'] stanford_hardi_tractography_fnames = [ 'mapping.nii.gz', 'tractography_subsampled.trk', 'full_segmented_cleaned_tractography.trk']
[docs]fetch_stanford_hardi_tractography = _make_reusable_fetcher( "fetch_stanford_hardi_tractography", op.join(afq_home, 'stanford_hardi_tractography'), baseurl, stanford_hardi_tractography_remote_fnames, stanford_hardi_tractography_fnames, md5_list=stanford_hardi_tractography_hashes, doc="""Download Stanford HARDI tractography and mapping. For testing purposes""")
[docs]def read_stanford_hardi_tractography(): """ Reads a minimal tractography from the Stanford dataset. """ files, folder = fetch_stanford_hardi_tractography() files_dict = {} files_dict['mapping.nii.gz'] = nib.load( op.join(afq_home, 'stanford_hardi_tractography', 'mapping.nii.gz')) # We need the original data as reference dwi_img, gtab = dpd.read_stanford_hardi() files_dict['tractography_subsampled.trk'] = load_tractogram( op.join(afq_home, 'stanford_hardi_tractography', 'tractography_subsampled.trk'), dwi_img, bbox_valid_check=False, trk_header_check=False).streamlines files_dict['full_segmented_cleaned_tractography.trk'] = load_tractogram( op.join( afq_home, 'stanford_hardi_tractography', 'full_segmented_cleaned_tractography.trk'), dwi_img).streamlines return files_dict
def to_bids_description(path, fname='dataset_description.json', BIDSVersion="1.4.0", **kwargs): """Dumps a dict into a bids description at the given location""" kwargs.update({"BIDSVersion": BIDSVersion}) desc_file = op.join(path, fname) with open(desc_file, 'w') as outfile: json.dump(kwargs, outfile) def organize_cfin_data(path=None): """ Create the expected file-system structure for the CFIN multi b-value diffusion data-set. """ dpd.fetch_cfin_multib() if path is None: os.makedirs(afq_home, exist_ok=True) path = afq_home bids_path = op.join(path, 'cfin_multib',) derivatives_path = op.join(bids_path, 'derivatives') dmriprep_folder = op.join(derivatives_path, 'dmriprep') if not op.exists(derivatives_path): anat_folder = op.join(dmriprep_folder, 'sub-01', 'ses-01', 'anat') os.makedirs(anat_folder, exist_ok=True) dwi_folder = op.join(dmriprep_folder, 'sub-01', 'ses-01', 'dwi') os.makedirs(dwi_folder, exist_ok=True) t1_img = dpd.read_cfin_t1() nib.save(t1_img, op.join(anat_folder, 'sub-01_ses-01_T1w.nii.gz')) dwi_img, gtab = dpd.read_cfin_dwi() nib.save(dwi_img, op.join(dwi_folder, 'sub-01_ses-01_dwi.nii.gz')) np.savetxt(op.join(dwi_folder, 'sub-01_ses-01_dwi.bvec'), gtab.bvecs) np.savetxt(op.join(dwi_folder, 'sub-01_ses-01_dwi.bval'), gtab.bvals) to_bids_description( bids_path, **{"BIDSVersion": "1.0.0", "Name": "CFIN", "Subjects": ["sub-01"]}) to_bids_description( dmriprep_folder, **{"Name": "CFIN", "PipelineDescription": {"Name": "dipy"}, "GeneratedBy": [{"Name": "dipy"}]})
[docs]def organize_stanford_data(path=None, clear_previous_afq=None): """ If necessary, downloads the Stanford HARDI dataset into DIPY directory and creates a BIDS compliant file-system structure in AFQ data directory: ~/AFQ_data/ └── stanford_hardi ├── dataset_description.json └── derivatives ├── freesurfer │ ├── dataset_description.json │ └── sub-01 │ └── ses-01 │ └── anat │ ├── sub-01_ses-01_T1w.nii.gz │ └── sub-01_ses-01_seg.nii.gz └── vistasoft ├── dataset_description.json └── sub-01 └── ses-01 └── dwi ├── sub-01_ses-01_dwi.bval ├── sub-01_ses-01_dwi.bvec └── sub-01_ses-01_dwi.nii.gz Parameters ---------- path : str or None Path to download dataset to, by default it is ~/AFQ_data/. clear_previous_afq : str or None Whether to clear previous afq results in the stanford hardi dataset. If not None, can be "all", "track", "recog", "prof". Default: None """ logger = logging.getLogger('AFQ') # fetches data for first subject and session logger.info('fetching Stanford HARDI data') dpd.fetch_stanford_hardi() if path is None: if not op.exists(afq_home): logger.info(f'creating AFQ home directory: {afq_home}') os.makedirs(afq_home, exist_ok=True) path = afq_home bids_path = op.join(path, 'stanford_hardi',) derivatives_path = op.join(bids_path, 'derivatives') dmriprep_folder = op.join(derivatives_path, 'vistasoft') freesurfer_folder = op.join(derivatives_path, 'freesurfer') if clear_previous_afq is not None and op.exists(derivatives_path): afq_folder = op.join(derivatives_path, 'afq') if clear_previous_afq == "all": if op.exists(afq_folder): shutil.rmtree(afq_folder) else: apply_cmd_to_afq_derivs( op.join(afq_folder, "sub-01/ses-01"), op.join(afq_folder, "sub-01/ses-01/sub-01_ses-01"), dependent_on=clear_previous_afq) if not op.exists(derivatives_path): logger.info(f'creating derivatives directory: {derivatives_path}') # anatomical data anat_folder = op.join(freesurfer_folder, 'sub-01', 'ses-01', 'anat') os.makedirs(anat_folder, exist_ok=True) t1_img = dpd.read_stanford_t1() nib.save(t1_img, op.join(anat_folder, 'sub-01_ses-01_T1w.nii.gz')) seg_img = dpd.read_stanford_labels()[-1] nib.save(seg_img, op.join(anat_folder, 'sub-01_ses-01_seg.nii.gz')) # diffusion-weighted imaging data dwi_folder = op.join(dmriprep_folder, 'sub-01', 'ses-01', 'dwi') os.makedirs(dwi_folder, exist_ok=True) dwi_img, gtab = dpd.read_stanford_hardi() nib.save(dwi_img, op.join(dwi_folder, 'sub-01_ses-01_dwi.nii.gz')) np.savetxt(op.join(dwi_folder, 'sub-01_ses-01_dwi.bvec'), gtab.bvecs) np.savetxt(op.join(dwi_folder, 'sub-01_ses-01_dwi.bval'), gtab.bvals) else: logger.info('Dataset is already in place. If you want to fetch it ' + 'again please first remove the folder ' + derivatives_path) # Dump out the description of the dataset to_bids_description(bids_path, **{"Name": "Stanford HARDI", "Subjects": ["sub-01"]}) # And descriptions of the pipelines in the derivatives: to_bids_description(dmriprep_folder, **{"Name": "Stanford HARDI", "PipelineDescription": {"Name": "vistasoft"}, "GeneratedBy": [{"Name": "vistasoft"}]}) to_bids_description(freesurfer_folder, **{"Name": "Stanford HARDI", "PipelineDescription": {"Name": "freesurfer"}, "GeneratedBy": [{"Name": "freesurfer"}]})
[docs]fetch_stanford_hardi_lv1 = _make_reusable_fetcher( "fetch_stanford_hardi_lv1", op.join(afq_home, 'stanford_hardi', 'derivatives/freesurfer/sub-01/ses-01/anat'), 'https://stacks.stanford.edu/file/druid:ng782rw8378/', ["SUB1_LV1.nii.gz"], ["sub-01_ses-01_desc-LV1_anat.nii.gz"], md5_list=["e403c602e53e5491414f86af5f08a913"], doc="Download the LV1 segmentation for the Standord Hardi subject", unzip=False)
fetch_hcp_atlas_16_bundles = _make_reusable_fetcher( "fetch_hcp_atlas_16_bundles", op.join(afq_home, 'hcp_atlas_16_bundles'), 'https://ndownloader.figshare.com/files/', ["11921522"], ["atlas_16_bundles.zip"], md5_list=["b071f3e851f21ba1749c02fc6beb3118"], doc="Download minimal Recobundles atlas", unzip=True) fetch_hcp_atlas_80_bundles = _make_reusable_fetcher( "fetch_hcp_atlas_80_bundles", op.join(afq_home, 'hcp_atlas_80_bundles'), 'https://ndownloader.figshare.com/files/', ["13638644"], ["Atlas_80_Bundles.zip"], md5_list=["78331d527a10ec000d4f33bac472e099"], doc="Download 80-bundle Recobundles atlas", unzip=True) def read_hcp_atlas(n_bundles=16, as_file=False): """ as_file : bool, optional If True, values are paths to sls. Otherwise, the sl are located and the centroids calculated. Default: False n_bundles : int 16 or 80, which selects among the two different atlases: https://figshare.com/articles/Simple_model_bundle_atlas_for_RecoBundles/6483614 # noqa https://figshare.com/articles/Advanced_Atlas_of_80_Bundles_in_MNI_space/7375883 # noqa """ bundle_dict = {} if n_bundles == 16: _, folder = fetch_hcp_atlas_16_bundles() atlas_folder = "Atlas_in_MNI_Space_16_bundles" elif n_bundles == 80: _, folder = fetch_hcp_atlas_80_bundles() atlas_folder = "Atlas_80_Bundles" whole_brain = op.join( folder, atlas_folder, 'whole_brain', 'whole_brain_MNI.trk') if not as_file: whole_brain = load_tractogram( whole_brain, 'same', bbox_valid_check=False).streamlines bundle_dict['whole_brain'] = whole_brain bundle_files = glob( op.join( folder, atlas_folder, "bundles", "*.trk")) centroid_folder = op.join( folder, atlas_folder, "centroid") os.makedirs(centroid_folder, exist_ok=True) for bundle_file in bundle_files: bundle = drop_extension(op.split(bundle_file)[-1]) centroid_file = op.join(centroid_folder, f"{bundle}.trk") bundle_dict[bundle] = {} if not op.exists(centroid_file): bundle_sl = load_tractogram( bundle_file, 'same', bbox_valid_check=False) feature = ResampleFeature(nb_points=100) metric = AveragePointwiseEuclideanMetric(feature) qb = QuickBundles(np.inf, metric=metric) cluster = [qb.cluster(bundle_sl.streamlines).centroids[0]] save_tractogram( StatefulTractogram( cluster, bundle_sl, Space.RASMM), centroid_file, bbox_valid_check=False) if not as_file: bundle_dict[bundle]['sl'] = load_tractogram( bundle_file, 'same', bbox_valid_check=False).streamlines bundle_dict[bundle]['centroid'] = load_tractogram( centroid_file, "same", bbox_valid_check=False).streamlines else: bundle_dict[bundle]['sl'] = bundle_file bundle_dict[bundle]['centroid'] = centroid_file # For some reason, this file-name has a 0 in it, instead of an O: bundle_dict["IFOF_R"] = bundle_dict["IF0F_R"] # In the 80-bundle case, there are two files, and both have identical # content, so this is fine: del bundle_dict["IF0F_R"] return bundle_dict fetch_aal_atlas = _make_reusable_fetcher( "fetch_aal_atlas", op.join(afq_home, 'aal_atlas'), 'https://ndownloader.figshare.com/files/', ["28416852", "28416855"], ["MNI_AAL_AndMore.nii.gz", "MNI_AAL.txt"], md5_list=["69395b75a16f00294a80eb9428bf7855", "59fd3284b17de2fbe411ca1c7afe8c65"], doc="Download the AAL atlas", unzip=False) def read_aal_atlas(resample_to=None): """ Reads the AAL atlas [1]_. Parameters ---------- template : nib.Nifti1Image class instance, optional If provided, this is the template used and AAL atlas should be registered and aligned to this template .. [1] Tzourio-Mazoyer N, Landeau B, Papathanassiou D, Crivello F, Etard O, Delcroix N, Mazoyer B, Joliot M. (2002). Automated anatomical labeling of activations in SPM using a macroscopic anatomical parcellation of the MNI MRI single-subject brain. Neuroimage. 2002; 15(1):273-89. """ file_dict, folder = fetch_aal_atlas() out_dict = {} for f in file_dict: if f.endswith('.txt'): out_dict['labels'] = pd.read_csv(op.join(folder, f)) else: out_dict['atlas'] = nib.load(op.join(folder, f)) if resample_to is not None: data = out_dict['atlas'].get_fdata() oo = [] for ii in range(data.shape[-1]): oo.append(resample( data[..., ii], resample_to, out_dict['atlas'].affine, resample_to.affine).get_fdata()) out_dict['atlas'] = nib.Nifti1Image(np.stack(oo, -1), resample_to.affine) return out_dict def _apply_mask(template_img, resolution=1): """ Helper function, gets MNI brain mask and applies it to template_img. Parameters ---------- template_img : nib.Nifti1Image Unmasked template resolution : int, optional Resolution of mask. Default: 1 Returns ------- Masked template as nib.Nifti1Image """ mask_img = nib.load(str(tflow.get('MNI152NLin2009cAsym', resolution=resolution, desc='brain', suffix='mask'))) template_data = template_img.get_fdata() mask_data = mask_img.get_fdata() if mask_data.shape != template_data.shape: mask_img = nib.Nifti1Image( resample( mask_data, template_data, mask_img.affine, template_img.affine).get_fdata(), template_img.affine) mask_data = mask_img.get_fdata() out_data = template_data * mask_data return nib.Nifti1Image(out_data, template_img.affine) def read_mni_template(resolution=1, mask=True, weight="T2w"): """ Reads the MNI T1w or T2w template Parameters ---------- resolution : int, optional. Either 1 or 2, the resolution in mm of the voxels. Default: 1. mask : bool, optional Whether to mask the data with a brain-mask before returning the image. Default : True weight: str, optional Which relaxation technique to use. Should be either "T2w" or "T1w". Default : "T2w" Returns ------- nib.Nifti1Image class instance containing masked or unmasked T1w or template. """ template_img = nib.load(str(tflow.get('MNI152NLin2009cAsym', desc=None, resolution=resolution, suffix=weight, extension='nii.gz'))) if not mask: return template_img else: return _apply_mask(template_img, resolution) fetch_biobank_templates = \ _make_reusable_fetcher( "fetch_biobank_templates", op.join(afq_home, 'biobank_templates'), "http://biobank.ctsu.ox.ac.uk/showcase/showcase/docs/", ["bmri_group_means.zip"], ["bmri_group_means.zip"], data_size="1.1 GB", doc="Download UK Biobank templates", unzip=True) def read_ukbb_fa_template(mask=True): """ Reads the UK Biobank FA template Parameters ---------- mask : bool, optional Whether to mask the data with a brain-mask before returning the image. Default : True Returns ------- nib.Nifti1Image class instance containing the FA template. """ fa_folder = op.join( afq_home, 'biobank_templates', 'UKBiobank_BrainImaging_GroupMeanTemplates' ) fa_path = op.join( fa_folder, 'dti_FA.nii.gz' ) if not op.exists(fa_path): logger = logging.getLogger('AFQ') logger.warning( "Downloading brain MRI group mean statistics from UK Biobank. " + "This download is approximately 1.1 GB. " + "It is currently necessary to access the FA template.") files, folder = fetch_biobank_templates() # remove zip for filename in files: os.remove(op.join(folder, filename)) # remove non-FA related directories for filename in os.listdir(fa_folder): full_path = op.join(fa_folder, filename) if full_path != fa_path: if os.path.isfile(full_path): os.remove(full_path) else: shutil.rmtree(full_path) template_img = nib.load(fa_path) if not mask: return template_img else: return _apply_mask(template_img, 1) def fetch_hcp(subjects, hcp_bucket='hcp-openaccess', profile_name="hcp", path=None, study='HCP_1200', aws_access_key_id=None, aws_secret_access_key=None): """ Fetch HCP diffusion data and arrange it in a manner that resembles the BIDS [1]_ specification. Parameters ---------- subjects : list Each item is an integer, identifying one of the HCP subjects hcp_bucket : string, optional The name of the HCP S3 bucket. Default: "hcp-openaccess" profile_name : string, optional The name of the AWS profile used for access. Default: "hcp" path : string, optional Path to save files into. Default: '~/AFQ_data' study : string, optional Which HCP study to grab. Default: 'HCP_1200' aws_access_key_id : string, optional AWS credentials to HCP AWS S3. Will only be used if `profile_name` is set to False. aws_secret_access_key : string, optional AWS credentials to HCP AWS S3. Will only be used if `profile_name` is set to False. Returns ------- dict with remote and local names of these files, path to BIDS derivative dataset Notes ----- To use this function with its default setting, you need to have a file '~/.aws/credentials', that includes a section: [hcp] AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXX AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXX The keys are credentials that you can get from HCP (see https://wiki.humanconnectome.org/display/PublicData/How+To+Connect+to+Connectome+Data+via+AWS) # noqa Local filenames are changed to match our expected conventions. .. [1] Gorgolewski et al. (2016). The brain imaging data structure, a format for organizing and describing outputs of neuroimaging experiments. Scientific Data, 3::160044. DOI: 10.1038/sdata.2016.44. """ if profile_name: boto3.setup_default_session(profile_name=profile_name) elif aws_access_key_id is not None and aws_secret_access_key is not None: boto3.setup_default_session( aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key) else: raise ValueError("Must provide either a `profile_name` or ", "both `aws_access_key_id` and ", "`aws_secret_access_key` as input to 'fetch_hcp'") s3 = boto3.resource('s3') bucket = s3.Bucket(hcp_bucket) if path is None: if not op.exists(afq_home): os.mkdir(afq_home) my_path = afq_home else: my_path = path base_dir = op.join(my_path, study, 'derivatives', 'dmriprep') if not os.path.exists(base_dir): os.makedirs(base_dir, exist_ok=True) data_files = {} for subject in subjects: # We make a single session folder per subject for this case, because # AFQ api expects session structure: sub_dir = op.join(base_dir, f'sub-{subject}') sess_dir = op.join(sub_dir, "ses-01") if not os.path.exists(sub_dir): os.makedirs(os.path.join(sess_dir, 'dwi'), exist_ok=True) os.makedirs(os.path.join(sess_dir, 'anat'), exist_ok=True) data_files[op.join(sess_dir, 'dwi', f'sub-{subject}_dwi.bval')] =\ f'{study}/{subject}/T1w/Diffusion/bvals' data_files[op.join(sess_dir, 'dwi', f'sub-{subject}_dwi.bvec')] =\ f'{study}/{subject}/T1w/Diffusion/bvecs' data_files[op.join(sess_dir, 'dwi', f'sub-{subject}_dwi.nii.gz')] =\ f'{study}/{subject}/T1w/Diffusion/data.nii.gz' data_files[op.join(sess_dir, 'anat', f'sub-{subject}_T1w.nii.gz')] =\ f'{study}/{subject}/T1w/T1w_acpc_dc.nii.gz' data_files[op.join(sess_dir, 'anat', f'sub-{subject}_aparc+aseg_seg.nii.gz')] =\ f'{study}/{subject}/T1w/aparc+aseg.nii.gz' download_files = {} for k in data_files.keys(): if not op.exists(k): download_files[k] = data_files[k] if len(download_files.keys()): with tqdm(total=len(download_files.keys())) as pbar: for k in download_files.keys(): pbar.set_description_str(f"Downloading {k}") bucket.download_file(data_files[k], k) pbar.update() # Create the BIDS dataset description file text hcp_acknowledgements = """Data were provided by the Human Connectome Project, WU-Minn Consortium (Principal Investigators: David Van Essen and Kamil Ugurbil; 1U54MH091657) funded by the 16 NIH Institutes and Centers that support the NIH Blueprint for Neuroscience Research; and by the McDonnell Center for Systems Neuroscience at Washington University.""", # noqa to_bids_description(op.join(my_path, study), **{"Name": study, "Acknowledgements": hcp_acknowledgements, "Subjects": subjects}) # Create the BIDS derivatives description file text to_bids_description(base_dir, **{"Name": study, "Acknowledgements": hcp_acknowledgements, "PipelineDescription": {'Name': 'dmriprep'}, "GeneratedBy": [{'Name': 'dmriprep'}]}) return data_files, op.join(my_path, study) def fetch_hbn_preproc(subjects, path=None): """ Fetches data from the Healthy Brain Network POD2 study [1, 2]_. Parameters ---------- subjects : list Identifiers of the subjects to download. For example: ["NDARAA112DMH", "NDARAA117NEJ"]. path : string, optional Path to save files into. Default: '~/AFQ_data' Returns ------- dict with remote and local names of these files, path to BIDS derivative dataset Notes ----- .. [1] Alexander LM, Escalera J, Ai L, et al. An open resource for transdiagnostic research in pediatric mental health and learning disorders. Sci Data. 2017;4:170181. .. [2] Richie-Halford A, Cieslak M, Ai L, et al. An analysis-ready and quality controlled resource for pediatric brain white-matter research. Scientific Data. 2022;9(1):1-27. """ # Anonymous access: client = boto3.client('s3', config=Config(signature_version=UNSIGNED)) if path is None: if not op.exists(afq_home): os.mkdir(afq_home) my_path = afq_home else: my_path = path base_dir = op.join(my_path, "HBN", 'derivatives', 'qsiprep') if not os.path.exists(base_dir): os.makedirs(base_dir, exist_ok=True) data_files = {} for subject in subjects: initial_query = client.list_objects( Bucket="fcp-indi", Prefix=f"data/Projects/HBN/BIDS_curated/sub-{subject}/") ses = initial_query['Contents'][0]["Key"].split('/')[5] query = client.list_objects( Bucket="fcp-indi", Prefix=f"data/Projects/HBN/BIDS_curated/derivatives/qsiprep/sub-{subject}/") # noqa file_list = [kk["Key"] for kk in query["Contents"]] sub_dir = op.join(base_dir, f'sub-{subject}') ses_dir = op.join(sub_dir, ses) if not os.path.exists(sub_dir): os.makedirs(os.path.join(sub_dir, 'anat'), exist_ok=True) os.makedirs(os.path.join(sub_dir, 'figures'), exist_ok=True) os.makedirs(os.path.join(ses_dir, 'dwi'), exist_ok=True) os.makedirs(os.path.join(ses_dir, 'anat'), exist_ok=True) for remote in file_list: full = remote.split("Projects")[-1][1:].replace("/BIDS_curated", "") local = op.join(my_path, full) data_files[local] = remote download_files = {} for k in data_files.keys(): if not op.exists(k): download_files[k] = data_files[k] if len(download_files.keys()): with tqdm(total=len(download_files.keys())) as pbar: for k in download_files.keys(): pbar.set_description_str(f"Downloading {k}") client.download_file("fcp-indi", download_files[k], k) pbar.update() # Create the BIDS dataset description file text hbn_acknowledgements = """XXX""", # noqa to_bids_description(op.join(my_path, "HBN"), **{"Name": "HBN", "Acknowledgements": hbn_acknowledgements, "Subjects": subjects}) # Create the BIDS derivatives description file text to_bids_description(base_dir, **{"Name": "HBN", "Acknowledgements": hbn_acknowledgements, "PipelineDescription": {'Name': 'qsiprep'}, "GeneratedBy": [{'Name': 'qsiprep'}]}) return data_files, op.join(my_path, "HBN") def fetch_hbn_afq(subjects, path=None): """ Fetches AFQ derivatives for Healthy Brain Network POD2 study [1, 2]_. Parameters ---------- subjects : list Identifiers of the subjects to download. For example: ["NDARAA112DMH", "NDARAA117NEJ"]. path : string, optional Path to save files into. Default: '~/AFQ_data' Returns ------- dict with remote and local names of these files, path to BIDS derivative dataset Notes ----- .. [1] Alexander LM, Escalera J, Ai L, et al. An open resource for transdiagnostic research in pediatric mental health and learning disorders. Sci Data. 2017;4:170181. .. [2] Richie-Halford A, Cieslak M, Ai L, et al. An analysis-ready and quality controlled resource for pediatric brain white-matter research. Scientific Data. 2022;9(1):1-27. """ # Anonymous access: client = boto3.client('s3', config=Config(signature_version=UNSIGNED)) if path is None: if not op.exists(afq_home): os.mkdir(afq_home) my_path = afq_home else: my_path = path base_dir = op.join(my_path, "HBN", 'derivatives', 'afq') if not os.path.exists(base_dir): os.makedirs(base_dir, exist_ok=True) data_files = {} for subject in subjects: initial_query = client.list_objects( Bucket="fcp-indi", Prefix=f"data/Projects/HBN/BIDS_curated/sub-{subject}/") ses = initial_query['Contents'][0]["Key"].split('/')[5] query = client.list_objects( Bucket="fcp-indi", Prefix=f"data/Projects/HBN/BIDS_curated/derivatives/afq/sub-{subject}/") # noqa file_list = [kk["Key"] for kk in query["Contents"]] sub_dir = op.join(base_dir, f'sub-{subject}') ses_dir = op.join(sub_dir, ses) for deriv_dir in ["bundles", "clean_bundles", "ROIs", "tract_profile_plots", "viz_bundles"]: this_deriv = os.path.join(ses_dir, deriv_dir) if not os.path.exists(this_deriv): os.makedirs(this_deriv, exist_ok=True) for remote in file_list: full = remote.split("Projects")[-1][1:].replace("/BIDS_curated", "") local = op.join(afq_home, full) data_files[local] = remote download_files = {} for k in data_files.keys(): if not op.exists(k): download_files[k] = data_files[k] if len(download_files.keys()): with tqdm(total=len(download_files.keys())) as pbar: for k in download_files.keys(): pbar.set_description_str(f"Downloading {k}") client.download_file("fcp-indi", download_files[k], k) pbar.update() # Create the BIDS dataset description file text hbn_acknowledgements = """XXX""", # noqa to_bids_description(op.join(my_path, "HBN"), **{"Name": "HBN", "Acknowledgements": hbn_acknowledgements, "Subjects": subjects}) # Create the BIDS derivatives description file text to_bids_description(base_dir, **{"Name": "HBN", "PipelineDescription": {'Name': 'afq'}, "GeneratedBy": [{'Name': 'afq'}]}) return data_files, op.join(my_path, "HBN")