@@ -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