Skip to content

Commit 9ab2c88

Browse files
committed
fix cubids validate --participant-label
1 parent 2229e56 commit 9ab2c88

File tree

2 files changed

+67
-5
lines changed

2 files changed

+67
-5
lines changed

cubids/cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,10 +1101,10 @@ def _main(argv=None):
11011101
options = _get_parser().parse_args(argv)
11021102
args = vars(options).copy()
11031103
args.pop("func")
1104-
1104+
11051105
# Automatically set validation_scope='subject' when --participant-label is provided
11061106
if "participant_label" in args and "validation_scope" in args:
11071107
if args["participant_label"]:
11081108
args["validation_scope"] = "subject"
1109-
1109+
11101110
options.func(**args)

cubids/workflows.py

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def _validate_single_subject(args):
4646
A tuple containing:
4747
- subject (str): Subject label
4848
- files_list (list): List of file paths for this subject
49+
- bids_dir (str): Path to the original BIDS directory
4950
- ignore_nifti_headers (bool): Whether to ignore NIfTI headers
5051
- local_validator (bool): Whether to use local validator
5152
- schema (str or None): Path to schema file as string
@@ -56,7 +57,7 @@ def _validate_single_subject(args):
5657
A tuple containing (subject, pd.DataFrame) with validation results.
5758
Returns (subject, None) if no issues found.
5859
"""
59-
subject, files_list, ignore_nifti_headers, local_validator, schema = args
60+
subject, files_list, bids_dir, ignore_nifti_headers, local_validator, schema = args
6061

6162
# Convert schema string back to Path if it exists
6263
schema_path = Path(schema) if schema is not None else None
@@ -104,6 +105,28 @@ def _link_or_copy(src_path, dst_path):
104105
output_path = os.path.join(tmp_file_dir, str(Path(file_path).name))
105106
_link_or_copy(file_path, output_path)
106107

108+
# Ensure dataset_description.json is available in temp root
109+
dataset_description_path = os.path.join(temporary_bids_dir, "dataset_description.json")
110+
if not os.path.exists(dataset_description_path):
111+
# Try to find dataset_description.json in the provided file list first
112+
source_dataset_description_path = None
113+
for candidate_path in files_list:
114+
if os.path.basename(candidate_path) == "dataset_description.json":
115+
source_dataset_description_path = candidate_path
116+
break
117+
# If not in file list, try to get it from the original bids_dir
118+
if not source_dataset_description_path and bids_dir:
119+
potential_path = os.path.join(bids_dir, "dataset_description.json")
120+
if os.path.exists(potential_path):
121+
source_dataset_description_path = potential_path
122+
if source_dataset_description_path:
123+
_link_or_copy(source_dataset_description_path, dataset_description_path)
124+
125+
# Ensure the subject folder exists as a directory in temp root
126+
subject_folder_path = os.path.join(temporary_bids_dir, subject)
127+
if not os.path.exists(subject_folder_path):
128+
os.makedirs(subject_folder_path, exist_ok=True)
129+
107130
# Ensure participants.tsv is available in temp root
108131
# copy from original file list if missing
109132
participants_tsv_path = os.path.join(temporary_bids_dir, "participants.tsv")
@@ -115,6 +138,11 @@ def _link_or_copy(src_path, dst_path):
115138
if os.path.basename(candidate_path) == "participants.tsv":
116139
source_participants_tsv_path = candidate_path
117140
break
141+
# If not in file list, try to get it from the original bids_dir
142+
if not source_participants_tsv_path and bids_dir:
143+
potential_path = os.path.join(bids_dir, "participants.tsv")
144+
if os.path.exists(potential_path):
145+
source_participants_tsv_path = potential_path
118146
if source_participants_tsv_path:
119147
_link_or_copy(source_participants_tsv_path, participants_tsv_path)
120148
except Exception: # noqa: BLE001
@@ -273,10 +301,12 @@ def validate(
273301

274302
# Convert schema Path to string if it exists (for multiprocessing pickling)
275303
schema_str = str(schema) if schema is not None else None
304+
# Convert bids_dir to string for multiprocessing pickling
305+
bids_dir_str = str(bids_dir)
276306

277307
# Prepare arguments for each subject
278308
validation_args = [
279-
(subject, files_list, ignore_nifti_headers, local_validator, schema_str)
309+
(subject, files_list, bids_dir_str, ignore_nifti_headers, local_validator, schema_str)
280310
for subject, files_list in subjects_dict.items()
281311
]
282312

@@ -346,6 +376,32 @@ def _link_or_copy(src_path, dst_path):
346376
output = os.path.join(tmp_file_dir, str(Path(file_path).name))
347377
_link_or_copy(file_path, output)
348378

379+
# Ensure dataset_description.json is available in temp root
380+
dataset_description_path = os.path.join(
381+
temporary_bids_dir, "dataset_description.json"
382+
)
383+
if not os.path.exists(dataset_description_path):
384+
# Try to find dataset_description.json in the provided file list first
385+
source_dataset_description_path = None
386+
for candidate_path in files_list:
387+
if os.path.basename(candidate_path) == "dataset_description.json":
388+
source_dataset_description_path = candidate_path
389+
break
390+
# If not in file list, try to get it from the original bids_dir
391+
if not source_dataset_description_path:
392+
potential_path = os.path.join(bids_dir, "dataset_description.json")
393+
if os.path.exists(potential_path):
394+
source_dataset_description_path = potential_path
395+
if source_dataset_description_path:
396+
_link_or_copy(
397+
source_dataset_description_path, dataset_description_path
398+
)
399+
400+
# Ensure the subject folder exists as a directory in temp root
401+
subject_folder_path = os.path.join(temporary_bids_dir, subject)
402+
if not os.path.exists(subject_folder_path):
403+
os.makedirs(subject_folder_path, exist_ok=True)
404+
349405
# Ensure participants.tsv exists; copy if missing, then filter
350406
participants_tsv_path = os.path.join(temporary_bids_dir, "participants.tsv")
351407
if not os.path.exists(participants_tsv_path):
@@ -355,6 +411,11 @@ def _link_or_copy(src_path, dst_path):
355411
if os.path.basename(candidate_path) == "participants.tsv":
356412
source_participants_tsv_path = candidate_path
357413
break
414+
# If not in file list, try to get it from the original bids_dir
415+
if not source_participants_tsv_path:
416+
potential_path = os.path.join(bids_dir, "participants.tsv")
417+
if os.path.exists(potential_path):
418+
source_participants_tsv_path = potential_path
358419
if source_participants_tsv_path:
359420
_link_or_copy(source_participants_tsv_path, participants_tsv_path)
360421
except Exception: # noqa: BLE001
@@ -456,7 +517,8 @@ def bids_version(bids_dir, write=False, schema=None):
456517

457518
# build a dictionary with {SubjectLabel: [List of files]}
458519
# run first subject only
459-
subject_dict = build_first_subject_path(bids_dir, subject)
520+
subject_path = os.path.join(bids_dir, subject)
521+
subject_dict = build_first_subject_path(bids_dir, subject_path)
460522

461523
# Iterate over the dictionary
462524
for subject, files_list in subject_dict.items():

0 commit comments

Comments
 (0)