diff --git a/neuroscout_cli/commands/get.py b/neuroscout_cli/commands/get.py index 5987308..f427754 100644 --- a/neuroscout_cli/commands/get.py +++ b/neuroscout_cli/commands/get.py @@ -2,16 +2,16 @@ import tarfile import logging import sys +import datalad from pathlib import Path from shutil import copy from packaging import version from neuroscout_cli.commands.base import Command from neuroscout_cli import __version__ as VERSION -from datalad.api import install, get -import datalad from bids.utils import convert_JSON -from ..tools.convert import check_convert_model +from ..tools.convert import check_convert_mode +from pyns.fetch_utils import fetch_images datalad.ui.ui.set_backend('console') @@ -32,7 +32,7 @@ def __init__(self, options): self.main_dir.mkdir(parents=True, exist_ok=True) self.bundle_dir.mkdir(parents=True, exist_ok=True) - def download_bundle(self, no_get=False): + def download(self, no_get=False): """ Download analysis bundle and setup preproc dir """ # If tarball doesn't exist, download it bundle_tarball = self.bundle_dir / f'{self.bundle_id}.tar.gz' @@ -58,81 +58,26 @@ def download_bundle(self, no_get=False): (self.bundle_dir / 'model.json').absolute() ) # Convert if necessary - self.dataset_dir = self.download_dir / self.resources['dataset_name'] - - # Install DataLad dataset if dataset_dir does not exist - if not self.dataset_dir.exists() and not no_get: - # Use datalad to install the preproc dataset - install(source=self.resources['preproc_address'], - path=str(self.dataset_dir)) - - for option in ['preproc', 'fmriprep']: - if (self.dataset_dir / option).exists(): - self.preproc_dir = (self.dataset_dir / option).absolute() - break - else: - self.preproc_dir = self.dataset_dir - - return 0 - - def download_data(self, no_get=False): - """ Use DataLad to download necessary data to disk """ + # Load model with self.model_path.open() as f: model = convert_JSON(json.load(f)) - try: - # Custom logic to fetch and avoid indexing dataset - paths = [] - - # Custom logic to fetch relevant files - # Avoiding PyBIDS for peformance gains in indexing - tasks = model['input'].get('task', '') - if not isinstance(tasks, list): - subjects = [tasks] - tasks = [ f'task-{t}*' for t in tasks] + self.preproc_dir, paths = fetch_images( + self.resources['dataset_name'], self.dataset_dir, no_get=no_get, + preproc_address=self.resources['preproc_address'], + datalad_jobs=self.options.get('datalad_jobs', -1), + fetch_json=True, fetch_brain_mask=True, **model['input']) - subjects = model['input'].get('subject', ['*']) - if not isinstance(subjects, list): - subjects = [subjects] - - run_ids = model['input'].get('run', ['']) - if not isinstance(run_ids, list): - runs = [run_ids] - runs = [f'run-{r}*' if r else r for r in run_ids] - runs += [f'run-{str(r).zfill(2)}*' if r else r for r in run_ids] - runs = list(set(runs)) - - for sub in subjects: - for run in runs: - for task in tasks: - pre = f'sub-{sub}/**/func/*{task}{run}space-MNI152NLin2009cAsym*' - paths += list(self.preproc_dir.glob(pre + 'preproc*.nii.gz')) - paths += list(self.preproc_dir.glob(pre + 'brain_mask.nii.gz')) - - if not paths: - raise Exception("No images suitable for download.") - - # Get all JSON files - paths += list(self.preproc_dir.rglob('*.json')) + self.dataset_dir = self.preproc_dir.parent - # Get with DataLad - if not no_get: - get([str(p) for p in paths], dataset=self.dataset_dir, jobs=self.options['datalad_jobs']) - - except Exception as exp: - if hasattr(exp, 'failed'): - message = exp.failed[0]['message'] - raise ValueError("Datalad failed. Reason: {}".format(message)) - else: - raise exp - - # Copy meta-data to root of preproc_dir - meta = list(self.bundle_dir.glob('task-*json'))[0] - if not (self.preproc_dir/ meta.parts[-1]).exists(): - copy(meta, self.preproc_dir) + if not no_get: + # Copy meta-data to root of preproc_dir + meta = list(self.bundle_dir.glob('task-*json'))[0] + if not (self.preproc_dir/ meta.parts[-1]).exists(): + copy(meta, self.preproc_dir) return 0 - + def _check_version(self): # Check version req = self.resources.get('version_required', 0.3) @@ -149,10 +94,10 @@ def _check_version(self): sys.exit(1) def run(self, no_get=False): - retcode = self.download_bundle(no_get=no_get) - - if not self.options.get('bundle_only', False): - retcode = self.download_data(no_get=no_get) + bundle_only = self.options.get('bundle_only', False) + if bundle_only: + no_get = True + retcode = self.download(no_get=no_get) return retcode