Skip to content

Commit 79d3757

Browse files
authored
Merge branch 'main' into singularity
2 parents 0f49b78 + 029b954 commit 79d3757

File tree

6 files changed

+1839
-1362
lines changed

6 files changed

+1839
-1362
lines changed

.readthedocs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ build:
1515
- pip install poetry
1616
- poetry config virtualenvs.create false
1717
post_install:
18-
- poetry install
18+
- VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install --with=dev
1919

2020
# Build documentation in the "docs/" directory with Sphinx
2121
sphinx:

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ This software can be installed via source or via pip from PyPi with `pip install
3636

3737
```bash
3838
usage: petdeface.py [-h] [--output_dir OUTPUT_DIR] [--anat_only]
39-
[--subject SUBJECT] [--session SESSION] [--docker]
39+
[--subject SUBJECT] [--session SESSION] [--docker]
4040
[--singularity] [--n_procs N_PROCS] [--skip_bids_validator]
4141
[--version] [--placement PLACEMENT] [--remove_existing]
42-
input_dir
42+
[--excludesubject] input_dir
4343

4444
PetDeface
4545

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

7274
Working example usage:

docs/usage.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ Additional options can be found in the help menu::
113113
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.
114114
--remove_existing, -r
115115
Remove existing output files in output_dir.
116+
--excludesubject EXCLUDESUBJECT [EXCLUDESUBJECT ...]
117+
Exclude a subject(s) from the defacing workflow. e.g. --excludesubject sub-01 sub-02
116118

117119
Docker Based
118120
------------

petdeface/petdeface.py

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,42 @@ def deface(args: Union[dict, argparse.Namespace]) -> None:
223223
if not check_valid_fs_license() and not locate_freesurfer_license().exists():
224224
raise Exception("You need a valid FreeSurfer license to proceed!")
225225

226-
if args.participant_label:
227-
participants = [args.participant_label]
228-
else:
226+
if args.subject:
227+
subjects = args.subject
228+
# if subject contains the string sub-, remove it to avoid redundancy as pybids will add it uses the
229+
# right side of the sub- string as the subject label
230+
if any("sub-" in subject for subject in subjects):
231+
print("One or more subject contains sub- string")
232+
subjects = [
233+
subject.replace("sub-", "") for subject in subjects if "sub-" in subject
234+
]
235+
# raise error if a supplied subject is not contained in the dataset
229236
participants = collect_participants(
230237
args.bids_dir, bids_validate=~args.skip_bids_validator
231238
)
239+
for subject in subjects:
240+
if subject not in participants:
241+
raise FileNotFoundError(
242+
f"sub-{subject} not found in dataset {args.bids_dir}"
243+
)
244+
else:
245+
subjects = collect_participants(
246+
args.bids_dir, bids_validate=~args.skip_bids_validator
247+
)
248+
249+
# check to see if any subjects are excluded from the defacing workflow
250+
if args.excludesubject != []:
251+
print(
252+
f"Removing the following subjects {args.excludesubject} from the defacing workflow"
253+
)
254+
args.excludesubject = [
255+
subject.replace("sub-", "") for subject in args.excludesubject
256+
]
257+
subjects = [
258+
subject for subject in subjects if subject not in args.excludesubject
259+
]
260+
261+
print(f"Subjects remaining in the defacing workflow: {subjects}")
232262

233263
# clean up and create derivatives directories
234264
if args.output_dir == "None" or args.output_dir is None:
@@ -238,7 +268,7 @@ def deface(args: Union[dict, argparse.Namespace]) -> None:
238268

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

241-
for subject_id in participants:
271+
for subject_id in subjects:
242272
try:
243273
single_subject_wf = init_single_subject_wf(
244274
subject_id, args.bids_dir, preview_pics=args.preview_pics
@@ -290,6 +320,8 @@ def init_single_subject_wf(
290320

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

294326
# check if any t1w images exist for the pet images
295327
for pet_image, t1w_image in subject_data.items():
@@ -694,6 +726,7 @@ def __init__(
694726
remove_existing=True, # TODO: currently not implemented
695727
placement="adjacent", # TODO: currently not implemented
696728
preview_pics=True,
729+
excludesubject=[],
697730
):
698731
self.bids_dir = bids_dir
699732
self.remove_existing = remove_existing
@@ -705,6 +738,7 @@ def __init__(
705738
self.n_procs = n_procs
706739
self.skip_bids_validator = skip_bids_validator
707740
self.preview_pics = preview_pics
741+
self.excludesubject = excludesubject
708742

709743
# check if freesurfer license is valid
710744
self.fs_license = check_valid_fs_license()
@@ -733,6 +767,7 @@ def run(self):
733767
"placement": self.placement,
734768
"remove_existing": self.remove_existing,
735769
"preview_pics": self.preview_pics,
770+
"excludesubject": self.excludesubject,
736771
}
737772
)
738773
wrap_up_defacing(
@@ -772,6 +807,7 @@ def cli():
772807
"-s",
773808
help="The label of the subject to be processed.",
774809
type=str,
810+
nargs="+",
775811
required=False,
776812
default="",
777813
)
@@ -833,6 +869,14 @@ def cli():
833869
action="store_true",
834870
default=False,
835871
)
872+
parser.add_argument(
873+
"--excludesubject",
874+
help="Exclude a subject(s) from the defacing workflow. e.g. --excludesubject sub-01 sub-02",
875+
type=str,
876+
nargs="+",
877+
required=False,
878+
default=[],
879+
)
836880

837881
arguments = parser.parse_args()
838882
return arguments
@@ -1023,6 +1067,7 @@ def main(): # noqa: max-complexity: 12
10231067
remove_existing=args.remove_existing,
10241068
placement=args.placement,
10251069
preview_pics=args.preview_pics,
1070+
excludesubject=args.excludesubject,
10261071
)
10271072
petdeface.run()
10281073

0 commit comments

Comments
 (0)