Skip to content

Commit

Permalink
updated workflow to support individual subject selection (#44)
Browse files Browse the repository at this point in the history
Workflow now supports selection of single or mulitple subjects 

--subject flag and --excludesubject flag is also now available for use.
Minor fixes:
* update docs
* update rtd build
* update lock and pyproject.toml
  • Loading branch information
bendhouseart authored Nov 8, 2024
1 parent 76f8298 commit 029b954
Show file tree
Hide file tree
Showing 6 changed files with 1,816 additions and 1,351 deletions.
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ build:
- pip install poetry
- poetry config virtualenvs.create false
post_install:
- poetry install
- VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install --with=dev

# Build documentation in the "docs/" directory with Sphinx
sphinx:
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ This software can be installed via source or via pip from PyPi with `pip install
usage: petdeface.py [-h] [--output_dir OUTPUT_DIR] [--anat_only]
[--subject SUBJECT] [--session SESSION] [--docker]
[--n_procs N_PROCS] [--skip_bids_validator] [--version]
[--placement PLACEMENT] [--remove_existing] input_dir
[--placement PLACEMENT] [--remove_existing] [--excludesubject]
input_dir

PetDeface

Expand All @@ -65,6 +66,8 @@ options:
w/ defaced at input_dir
'derivatives': does all of the defacing within the derivatives folder in input_dir.
--remove_existing, -r Remove existing output files in output_dir.
--excludesubject EXCLUDESUBJECT [EXCLUDESUBJECT ...]
Exclude a subject(s) from the defacing workflow. e.g. --excludesubject sub-01 sub-02
```

Working example usage:
Expand Down
2 changes: 2 additions & 0 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ Additional options can be found in the help menu::
e.g. replaces faced PET and T1w images w/ defaced at input_dir'derivatives': does all of the defacing within the derivatives folder in input_dir.
--remove_existing, -r
Remove existing output files in output_dir.
--excludesubject EXCLUDESUBJECT [EXCLUDESUBJECT ...]
Exclude a subject(s) from the defacing workflow. e.g. --excludesubject sub-01 sub-02

Docker Based
------------
Expand Down
53 changes: 49 additions & 4 deletions petdeface/petdeface.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,42 @@ def deface(args: Union[dict, argparse.Namespace]) -> None:
if not check_valid_fs_license():
raise Exception("You need a valid FreeSurfer license to proceed!")

if args.participant_label:
participants = [args.participant_label]
else:
if args.subject:
subjects = args.subject
# if subject contains the string sub-, remove it to avoid redundancy as pybids will add it uses the
# right side of the sub- string as the subject label
if any("sub-" in subject for subject in subjects):
print("One or more subject contains sub- string")
subjects = [
subject.replace("sub-", "") for subject in subjects if "sub-" in subject
]
# raise error if a supplied subject is not contained in the dataset
participants = collect_participants(
args.bids_dir, bids_validate=~args.skip_bids_validator
)
for subject in subjects:
if subject not in participants:
raise FileNotFoundError(
f"sub-{subject} not found in dataset {args.bids_dir}"
)
else:
subjects = collect_participants(
args.bids_dir, bids_validate=~args.skip_bids_validator
)

# check to see if any subjects are excluded from the defacing workflow
if args.excludesubject != []:
print(
f"Removing the following subjects {args.excludesubject} from the defacing workflow"
)
args.excludesubject = [
subject.replace("sub-", "") for subject in args.excludesubject
]
subjects = [
subject for subject in subjects if subject not in args.excludesubject
]

print(f"Subjects remaining in the defacing workflow: {subjects}")

# clean up and create derivatives directories
if args.output_dir == "None" or args.output_dir is None:
Expand All @@ -216,7 +246,7 @@ def deface(args: Union[dict, argparse.Namespace]) -> None:

petdeface_wf = Workflow(name="petdeface_wf", base_dir=output_dir)

for subject_id in participants:
for subject_id in subjects:
try:
single_subject_wf = init_single_subject_wf(
subject_id, args.bids_dir, preview_pics=args.preview_pics
Expand Down Expand Up @@ -268,6 +298,8 @@ def init_single_subject_wf(

data = collect_anat_and_pet(bids_data)
subject_data = data.get(subject_id)
if subject_data is None:
raise FileNotFoundError(f"Could not find data for subject sub-{subject_id}")

# check if any t1w images exist for the pet images
for pet_image, t1w_image in subject_data.items():
Expand Down Expand Up @@ -672,6 +704,7 @@ def __init__(
remove_existing=True, # TODO: currently not implemented
placement="adjacent", # TODO: currently not implemented
preview_pics=True,
excludesubject=[],
):
self.bids_dir = bids_dir
self.remove_existing = remove_existing
Expand All @@ -683,6 +716,7 @@ def __init__(
self.n_procs = n_procs
self.skip_bids_validator = skip_bids_validator
self.preview_pics = preview_pics
self.excludesubject = excludesubject

# check if freesurfer license is valid
self.fs_license = check_valid_fs_license()
Expand All @@ -707,6 +741,7 @@ def run(self):
"placement": self.placement,
"remove_existing": self.remove_existing,
"preview_pics": self.preview_pics,
"excludesubject": self.excludesubject,
}
)
wrap_up_defacing(
Expand Down Expand Up @@ -746,6 +781,7 @@ def cli():
"-s",
help="The label of the subject to be processed.",
type=str,
nargs="+",
required=False,
default="",
)
Expand Down Expand Up @@ -800,6 +836,14 @@ def cli():
action="store_true",
default=False,
)
parser.add_argument(
"--excludesubject",
help="Exclude a subject(s) from the defacing workflow. e.g. --excludesubject sub-01 sub-02",
type=str,
nargs="+",
required=False,
default=[],
)

arguments = parser.parse_args()
return arguments
Expand Down Expand Up @@ -928,6 +972,7 @@ def main(): # noqa: max-complexity: 12
remove_existing=args.remove_existing,
placement=args.placement,
preview_pics=args.preview_pics,
excludesubject=args.excludesubject,
)
petdeface.run()

Expand Down
Loading

0 comments on commit 029b954

Please sign in to comment.