Skip to content

Commit

Permalink
Merge pull request #1 from PennLINC/enh/hcp
Browse files Browse the repository at this point in the history
HCP ingress
  • Loading branch information
smeisler authored Aug 30, 2024
2 parents 23f0e01 + 5e03c3b commit 2c26306
Show file tree
Hide file tree
Showing 13 changed files with 1,025 additions and 43 deletions.
6 changes: 2 additions & 4 deletions ingress2qsirecon/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
"""Ingress2QSIRecon.
Your description here
"""

Ingress2QSIRecon.
"""
3 changes: 3 additions & 0 deletions ingress2qsirecon/cli/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
Ingress2QSIRecon.
"""
75 changes: 75 additions & 0 deletions ingress2qsirecon/cli/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from __future__ import annotations

import os
import shutil
from pathlib import Path

from beartype import beartype

import ingress2qsirecon
from ingress2qsirecon.cli.parser import _build_parser
from ingress2qsirecon.utils.functions import create_layout
from ingress2qsirecon.utils.workflows import create_ingress2qsirecon_wf


@beartype
def _ingress2qsirecon(**kwargs):
"""
The main function
This initializes the import directories, then creates and run the nipype workflow.
"""
# Get the command line arguments
input_dir = Path(kwargs["input_dir"])
output_dir = Path(kwargs["output_dir"])
input_pipeline = kwargs["input_pipeline"]
participant_label = kwargs["participant_label"]
work_dir = Path(kwargs["work_dir"])
check_gradients = kwargs["check_gradients"]
dry_run = kwargs["dry_run"]
symlink = kwargs["symlink"]

# Raise NotImplemented errors for options not implemented yet
if check_gradients or dry_run or symlink:
raise NotImplementedError("--check_gradients, --dry_run, and --symlink are not implemented yet.")

# Create working directory
if not work_dir.exists():
work_dir.mkdir(parents=True)
os.chdir(work_dir)

# If output_dir doesn't exist, create it
if not output_dir.exists():
output_dir.mkdir(parents=True)

# Move BIDS scaffold files to output directory
ingress2recon_dir = os.path.dirname(ingress2qsirecon.__file__)
if not os.path.exists(os.path.join(output_dir, "dataset_description.json")):
shutil.copytree(os.path.join(ingress2recon_dir, "data", "bids_scaffold"), output_dir, dirs_exist_ok=True)

# If participant_label not defined, make it empty list
if participant_label is None:
participant_label = []

# Make list of dictionaries with all information about the ingressions, one dict per subject
layouts = create_layout(input_dir, output_dir, input_pipeline, participant_label)

# Create and run overall workflow, which will be broken down to single subject workflows
ingress2qsirecon_wf = create_ingress2qsirecon_wf(layouts, base_dir=work_dir)
ingress2qsirecon_wf.run()


def main():
"""
The main entry point of the CLI.
This function is responsible for parsing command line arguments and running the main code.
"""
parser = _build_parser()
args = parser.parse_args()
args_dict = vars(args)
_ingress2qsirecon(**args_dict)


if __name__ == '__main__':
main()
99 changes: 99 additions & 0 deletions ingress2qsirecon/cli/parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
"""Parser."""


def _build_parser(**kwargs):
"""Build parser object.
``kwargs`` are passed to ``argparse.ArgumentParser`` (mainly useful for debugging).
"""
import os
from argparse import (
ArgumentDefaultsHelpFormatter,
ArgumentParser,
)
from functools import partial
from pathlib import Path

def _path_exists(path, parser):
"""Ensure a given path exists."""
if path is None or not Path(path).exists():
raise parser.error(f"Path does not exist: <{path}>.")
return Path(path).absolute()

def _drop_sub(value):
return value[4:] if value.startswith("sub-") else value

parser = ArgumentParser(
description=f"Ingress2QSIRecon: Restructuring Bespoke Data for Use in QSIRecon",
formatter_class=ArgumentDefaultsHelpFormatter,
**kwargs,
)
PathExists = partial(_path_exists, parser=parser)

# Required, positional arguments
parser.add_argument(
"input_dir",
action="store",
type=PathExists,
help="Root folder of dataset to ingress, e.g., HCP1200 or UKB. "
"Should contain subject folders (e.g., '100307' for HCP).",
)
parser.add_argument(
"output_dir",
action="store",
type=Path,
help="The output path for restructured data.",
)
parser.add_argument(
"input_pipeline",
action="store",
choices=["hcpya", "ukb"],
help="specify which pipeline was used to create the data specified "
"in the --input_dir. Current options include 'hcpya' for "
"the HCP young adult minimal preprocessing pipeline and 'ukb' for data processed "
"with the UK BioBank minimal preprocessing pipeline.",
)

# Optional arguments
optional = parser.add_argument_group("Optional arguments")
optional.add_argument(
"--participant-label",
"--participant_label",
action="store",
nargs="+",
type=_drop_sub,
help="A space delimited list of subject folder names / identifiers to process "
"(e.g., '100307' for HCP). If not specified, all found folders will be processed. "
"Currently runs subjects serially.",
)
optional.add_argument(
"--work_dir",
"--work-dir",
"-w",
action="store",
type=Path,
default=Path(os.getcwd()),
help="The working directory for the processing. "
"If not specified, the current working directory will be used.",
)
optional.add_argument(
"--check_gradients",
"--check-gradients",
action="store_true",
default=False,
help="NOT IMPLEMENTED YET. Run dwigradcheck on gradient table. This adds a lot of time to the processing. ",
)
optional.add_argument(
"--dry-run",
"--dry_run",
action="store_true",
default=False,
help="NOT IMPLEMENTED YET. Will return file reorganization mappings without performing the reorganization.",
)
optional.add_argument(
"--symlink",
action="store_true",
default=False,
help="NOT IMPLEMENTED YET. Rather than copying files, create symlinks (shortcuts) in the output directory.",
)
return parser
1 change: 1 addition & 0 deletions ingress2qsirecon/data/bids_scaffold/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is an example README file for BIDS validation.
19 changes: 19 additions & 0 deletions ingress2qsirecon/data/bids_scaffold/dataset_description.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"Name": "BIDS-ified Data for QSIRecon",
"BIDSVersion": "1.9.0",
"DatasetType": "derivative",
"License": "CC0",
"Authors": [
"PennLINC",
"Your Computer"
],
"ReferencesAndLinks": [
"https://github.com/PennLINC/ingress2qsirecon"
],
"GeneratedBy": [
{
"Name": "ingress2qsirecon",
"Version": "latest"
}
]
}
36 changes: 0 additions & 36 deletions ingress2qsirecon/main.py

This file was deleted.

3 changes: 3 additions & 0 deletions ingress2qsirecon/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
Ingress2QSIRecon.
"""
Loading

0 comments on commit 2c26306

Please sign in to comment.