5252for place in places_to_look :
5353 for root , folders , files in os .walk (place ):
5454 for file in files :
55- if file .endswith ("pyproject.toml" ) and "petdeface" in os .path .join (root , file ):
55+ if file .endswith ("pyproject.toml" ) and "petdeface" in os .path .join (
56+ root , file
57+ ):
5658 toml_file = os .path .join (root , file )
5759
5860 with open (toml_file , "r" ) as f :
7173 # we check the version with a regex expression to see if all of the parts are there
7274 if re .match (r"\d+\.\d+\.\d+" , __version__ ):
7375 break
74-
76+
7577 if __version__ != "unable to locate version number in pyproject.toml" :
76- # we try to load the version using import lib
77- __version__ = importlib .metadata .version ("petdeface" )
78- if re .match (r"\d+\.\d+\.\d+" , __version__ ):
79- break
78+ # we try to load the version using import lib
79+ __version__ = importlib .metadata .version ("petdeface" )
80+ if re .match (r"\d+\.\d+\.\d+" , __version__ ):
81+ break
8082
8183
8284def locate_freesurfer_license ():
@@ -101,7 +103,7 @@ def locate_freesurfer_license():
101103 else :
102104 return fs_license_env_var
103105 else :
104- # collect freesurfer home environment variable and look there instead
106+ # collect freesurfer home environment variable and look there instead
105107 fs_home = pathlib .Path (os .environ .get ("FREESURFER_HOME" , "" ))
106108 if not fs_home :
107109 raise ValueError (
@@ -271,7 +273,10 @@ def deface(args: Union[dict, argparse.Namespace]) -> None:
271273 for subject_id in subjects :
272274 try :
273275 single_subject_wf = init_single_subject_wf (
274- subject_id , args .bids_dir , preview_pics = args .preview_pics
276+ subject_id ,
277+ args .bids_dir ,
278+ preview_pics = args .preview_pics ,
279+ anat_only = args .anat_only ,
275280 )
276281 except FileNotFoundError :
277282 single_subject_wf = None
@@ -294,9 +299,10 @@ def deface(args: Union[dict, argparse.Namespace]) -> None:
294299
295300def init_single_subject_wf (
296301 subject_id : str ,
297- bids_data : [pathlib .Path , BIDSLayout ],
302+ bids_data : Union [pathlib .Path , BIDSLayout ],
298303 output_dir : pathlib .Path = None ,
299304 preview_pics = False ,
305+ anat_only = False ,
300306) -> Workflow :
301307 """
302308 Organize the preprocessing pipeline for a single subject.
@@ -307,6 +313,10 @@ def init_single_subject_wf(
307313 :type bids_data: pathlib.Path, BIDSLayout]
308314 :param output_dir: _description_, defaults to None
309315 :type output_dir: pathlib.Path, optional
316+ :param preview_pics: _description_, defaults to False
317+ :type preview_pics: bool, optional
318+ :param anat_only: _description_, defaults to False
319+ :type anat_only: bool, optional
310320 :raises FileNotFoundError: _description_
311321 :return: _description_
312322 :rtype: Workflow
@@ -404,71 +414,80 @@ def init_single_subject_wf(
404414 t1w_workflows [t1w_file ] = {"workflow" : t1w_wf , "anat_string" : anat_string }
405415
406416 workflow = Workflow (name = name )
407- for pet_file , t1w_file in subject_data .items ():
408- try :
409- ses_id = re .search ("ses-[^_|\/]*" , str (pet_file )).group (0 )
410- pet_string = f"sub-{ subject_id } _{ ses_id } "
411- except AttributeError :
412- ses_id = ""
413- pet_string = f"sub-{ subject_id } "
417+ if anat_only :
418+ for each in t1w_workflows .values ():
419+ workflow .add_nodes ([each ["workflow" ]])
420+ else :
421+ for pet_file , t1w_file in subject_data .items ():
422+ try :
423+ ses_id = re .search ("ses-[^_|\/]*" , str (pet_file )).group (0 )
424+ pet_string = f"sub-{ subject_id } _{ ses_id } "
425+ except AttributeError :
426+ ses_id = ""
427+ pet_string = f"sub-{ subject_id } "
414428
415- # collect run info from pet file
416- try :
417- run_id = "_" + re .search ("run-[^_|\/]*" , str (pet_file )).group (0 )
418- except AttributeError :
419- run_id = ""
420- pet_wf_name = f"pet_{ pet_string } { run_id } _wf"
421- pet_wf = Workflow (name = pet_wf_name )
422-
423- weighted_average = Node (
424- WeightedAverage (pet_file = pet_file ), name = "weighted_average"
425- )
429+ # collect run info from pet file
430+ try :
431+ run_id = "_" + re .search ("run-[^_|\/]*" , str (pet_file )).group (0 )
432+ except AttributeError :
433+ run_id = ""
434+ pet_wf_name = f"pet_{ pet_string } { run_id } _wf"
435+ pet_wf = Workflow (name = pet_wf_name )
436+
437+ weighted_average = Node (
438+ WeightedAverage (pet_file = pet_file ), name = "weighted_average"
439+ )
426440
427- # rename registration file to something more descriptive than registration.lta
428- # we do this here to account for mulitple runs during the same session
429- mricoreg = MRICoreg (reference_file = t1w_file )
430- mricoreg .inputs .out_lta_file = f"{ pet_string } { run_id } _desc-pet2anat_pet.lta"
441+ # rename registration file to something more descriptive than registration.lta
442+ # we do this here to account for mulitple runs during the same session
443+ mricoreg = MRICoreg (reference_file = t1w_file )
444+ mricoreg .inputs .out_lta_file = f"{ pet_string } { run_id } _desc-pet2anat_pet.lta"
431445
432- coreg_pet_to_t1w = Node (mricoreg , "coreg_pet_to_t1w" )
446+ coreg_pet_to_t1w = Node (mricoreg , "coreg_pet_to_t1w" )
433447
434- deface_pet = Node (ApplyMideface (in_file = pet_file ), name = "deface_pet" )
448+ deface_pet = Node (ApplyMideface (in_file = pet_file ), name = "deface_pet" )
435449
436- pet_wf .connect (
437- [
438- (weighted_average , coreg_pet_to_t1w , [("out_file" , "source_file" )]),
439- (coreg_pet_to_t1w , deface_pet , [("out_lta_file" , "lta_file" )]),
440- (
441- coreg_pet_to_t1w ,
442- datasink ,
443- [("out_lta_file" , f"{ pet_string .replace ('_' , '.' )} .pet.@{ run_id } " )],
444- ),
445- (
446- deface_pet ,
447- datasink ,
448- [
449- (
450- "out_file" ,
451- f"{ pet_string .replace ('_' , '.' )} .pet.@defaced{ run_id } " ,
452- )
453- ],
454- ),
455- ]
456- )
450+ pet_wf .connect (
451+ [
452+ (weighted_average , coreg_pet_to_t1w , [("out_file" , "source_file" )]),
453+ (coreg_pet_to_t1w , deface_pet , [("out_lta_file" , "lta_file" )]),
454+ (
455+ coreg_pet_to_t1w ,
456+ datasink ,
457+ [
458+ (
459+ "out_lta_file" ,
460+ f"{ pet_string .replace ('_' , '.' )} .pet.@{ run_id } " ,
461+ )
462+ ],
463+ ),
464+ (
465+ deface_pet ,
466+ datasink ,
467+ [
468+ (
469+ "out_file" ,
470+ f"{ pet_string .replace ('_' , '.' )} .pet.@defaced{ run_id } " ,
471+ )
472+ ],
473+ ),
474+ ]
475+ )
457476
458- workflow .connect (
459- [
460- (
461- t1w_workflows [t1w_file ]["workflow" ],
462- pet_wf ,
463- [
464- (
465- f"deface_t1w_{ t1w_workflows [t1w_file ]['anat_string' ]} .out_facemask" ,
466- "deface_pet.facemask" ,
467- )
468- ],
469- )
470- ]
471- )
477+ workflow .connect (
478+ [
479+ (
480+ t1w_workflows [t1w_file ]["workflow" ],
481+ pet_wf ,
482+ [
483+ (
484+ f"deface_t1w_{ t1w_workflows [t1w_file ]['anat_string' ]} .out_facemask" ,
485+ "deface_pet.facemask" ,
486+ )
487+ ],
488+ )
489+ ]
490+ )
472491
473492 return workflow
474493
@@ -718,13 +737,12 @@ def __init__(
718737 self ,
719738 bids_dir ,
720739 output_dir = None ,
721- anat_only = False , # TODO: currently not implemented
740+ anat_only = False ,
722741 subject = "" ,
723- session = "" , # TODO: currently not implemented
724742 n_procs = 2 ,
725743 skip_bids_validator = True ,
726- remove_existing = True , # TODO: currently not implemented
727- placement = "adjacent" , # TODO: currently not implemented
744+ remove_existing = True ,
745+ placement = "adjacent" ,
728746 preview_pics = True ,
729747 excludeparticipant = [],
730748 ):
@@ -734,7 +752,6 @@ def __init__(
734752 self .output_dir = output_dir
735753 self .anat_only = anat_only
736754 self .subject = subject
737- self .session = session
738755 self .n_procs = n_procs
739756 self .skip_bids_validator = skip_bids_validator
740757 self .preview_pics = preview_pics
@@ -747,7 +764,9 @@ def __init__(
747764 if not self .fs_license .exists ():
748765 raise ValueError ("Freesurfer license is not valid" )
749766 else :
750- print (f"Using freesurfer license at { self .fs_license } found in system env at $FREESURFER_LICENSE" )
767+ print (
768+ f"Using freesurfer license at { self .fs_license } found in system env at $FREESURFER_LICENSE"
769+ )
751770
752771 def run (self ):
753772 """
@@ -760,7 +779,6 @@ def run(self):
760779 "output_dir" : self .output_dir ,
761780 "anat_only" : self .anat_only ,
762781 "subject" : self .subject ,
763- "session" : self .session ,
764782 "n_procs" : self .n_procs ,
765783 "skip_bids_validator" : self .skip_bids_validator ,
766784 "participant_label" : self .subject ,
@@ -795,9 +813,9 @@ def cli():
795813 default = None ,
796814 )
797815 parser .add_argument (
798- ' analysis_level' ,
799- nargs = '?' ,
800- default = ' participant' ,
816+ " analysis_level" ,
817+ nargs = "?" ,
818+ default = " participant" ,
801819 help = "This BIDS app always operates at the participant level, if this argument is changed it will be ignored and run as "
802820 "a participant level analysis" ,
803821 )
@@ -817,14 +835,6 @@ def cli():
817835 required = False ,
818836 default = "" ,
819837 )
820- parser .add_argument (
821- "--session" ,
822- "-ses" ,
823- help = "The label of the session to be processed." ,
824- type = str ,
825- required = False ,
826- default = "" ,
827- )
828838 parser .add_argument (
829839 "--docker" ,
830840 "-d" ,
@@ -1010,7 +1020,11 @@ def main(): # noqa: max-complexity: 12
10101020 elif args .singularity :
10111021 singularity_command = f"singularity exec -e"
10121022
1013- if args .output_dir == "None" or args .output_dir is None or args .output_dir == "" :
1023+ if (
1024+ args .output_dir == "None"
1025+ or args .output_dir is None
1026+ or args .output_dir == ""
1027+ ):
10141028 args .output_dir = args .bids_dir / "derivatives" / "petdeface"
10151029
10161030 # create output directory if it doesn't exist
@@ -1051,7 +1065,9 @@ def main(): # noqa: max-complexity: 12
10511065 "Freesurfer license not found, please set FREESURFER_LICENSE environment variable or place license.txt in FREESURFER_HOME"
10521066 )
10531067
1054- singularity_command += f" --bind { str (license_location )} :/opt/freesurfer/license.txt"
1068+ singularity_command += (
1069+ f" --bind { str (license_location )} :/opt/freesurfer/license.txt"
1070+ )
10551071 singularity_command += f" docker://openneuropet/petdeface:{ __version__ } "
10561072 singularity_command += f" petdeface"
10571073 singularity_command += args_string
@@ -1060,14 +1076,12 @@ def main(): # noqa: max-complexity: 12
10601076
10611077 subprocess .run (singularity_command , shell = True )
10621078
1063-
10641079 else :
10651080 petdeface = PetDeface (
10661081 bids_dir = args .bids_dir ,
10671082 output_dir = args .output_dir ,
10681083 anat_only = args .anat_only ,
10691084 subject = args .participant_label ,
1070- session = args .session ,
10711085 n_procs = args .n_procs ,
10721086 skip_bids_validator = args .skip_bids_validator ,
10731087 remove_existing = args .remove_existing ,
0 commit comments