@@ -619,11 +619,12 @@ def _str_none(val):
619619 '--output-layout' ,
620620 action = 'store' ,
621621 default = 'bids' ,
622- choices = ('bids' , 'legacy' ),
622+ choices = ('bids' , 'legacy' , 'multiverse' ),
623623 help = 'Organization of outputs. bids (default) places NiBabies derivatives '
624624 'directly in the output directory, and defaults to placing FreeSurfer '
625625 'derivatives in <output-dir>/sourcedata/freesurfer. legacy creates derivative '
626- 'datasets as subdirectories of outputs.' ,
626+ 'datasets as subdirectories of outputs. multiverse appends the version and a hash '
627+ 'of parameters used to the output folder - the hash is also applied to the output files.' ,
627628 )
628629 g_other .add_argument (
629630 '-w' ,
@@ -834,27 +835,62 @@ def parse_args(args=None, namespace=None):
834835 applied."""
835836 )
836837
838+ config .workflow .skull_strip_template = config .workflow .skull_strip_template [0 ]
839+
837840 bids_dir = config .execution .bids_dir
838841 output_dir = config .execution .output_dir
839842 work_dir = config .execution .work_dir
840843 version = config .environment .version
841844 output_layout = config .execution .output_layout
845+ config .execution .parameters_hash = config .hash_config (config .get ())
842846
843- if config .execution .fs_subjects_dir is None :
844- if output_layout == 'bids' :
845- config .execution .fs_subjects_dir = output_dir / 'sourcedata' / 'freesurfer'
846- elif output_layout == 'legacy' :
847- config .execution .fs_subjects_dir = output_dir / 'freesurfer'
847+ # Multiverse behaves as a cross between bids and legacy
848848 if config .execution .nibabies_dir is None :
849- if output_layout == 'bids' :
850- config .execution .nibabies_dir = output_dir
851- elif output_layout == 'legacy' :
852- config .execution .nibabies_dir = output_dir / 'nibabies'
849+ match output_layout :
850+ case 'bids' :
851+ config .execution .nibabies_dir = output_dir
852+ case 'legacy' :
853+ config .execution .nibabies_dir = output_dir / 'nibabies'
854+ case 'multiverse' :
855+ config .loggers .cli .warning (
856+ 'Multiverse output selected - assigning output directory based on version'
857+ ' and configuration hash.'
858+ )
859+ config .execution .nibabies_dir = (
860+ output_dir
861+ / f'nibabies-{ version .split ("+" , 1 )[0 ]} -{ config .execution .parameters_hash } '
862+ )
863+ case _:
864+ config .loggers .cli .warning ('Unknown output layout %s' , output_layout )
865+ pass
866+
867+ nibabies_dir = config .execution .nibabies_dir
868+
869+ if config .execution .fs_subjects_dir is None :
870+ match output_layout :
871+ case 'bids' :
872+ config .execution .fs_subjects_dir = output_dir / 'sourcedata' / 'freesurfer'
873+ case 'legacy' :
874+ config .execution .fs_subjects_dir = output_dir / 'freesurfer'
875+ case 'multiverse' :
876+ config .execution .fs_subjects_dir = (
877+ nibabies_dir / 'sourcedata' / f'freesurfer-{ config .execution .parameters_hash } '
878+ )
879+ case _:
880+ pass
881+
853882 if config .workflow .surface_recon_method == 'mcribs' :
854- if output_layout == 'bids' :
855- config .execution .mcribs_dir = output_dir / 'sourcedata' / 'mcribs'
856- elif output_layout == 'legacy' :
857- config .execution .mcribs_dir = output_dir / 'mcribs'
883+ match output_layout :
884+ case 'bids' :
885+ config .execution .mcribs_dir = output_dir / 'sourcedata' / 'mcribs'
886+ case 'legacy' :
887+ config .execution .mcribs_dir = output_dir / 'mcribs'
888+ case 'multiverse' :
889+ config .execution .mcribs_dir = (
890+ nibabies_dir / 'sourcedata' / f'mcribs-{ config .execution .parameters_hash } '
891+ )
892+ case _:
893+ pass
858894 # Ensure the directory is created
859895 config .execution .mcribs_dir .mkdir (exist_ok = True , parents = True )
860896
@@ -909,7 +945,6 @@ def parse_args(args=None, namespace=None):
909945 participant_ids = config .execution .participant_label ,
910946 session_ids = config .execution .session_id ,
911947 )
912- config .workflow .skull_strip_template = config .workflow .skull_strip_template [0 ]
913948
914949 # finally, write config to file
915950 config_file = config .execution .work_dir / config .execution .run_uuid / 'config.toml'
0 commit comments