2
2
from nipype .interfaces .base import traits_extension
3
3
from pydra .engine import specs
4
4
5
- import os , yaml , black , imp
5
+ import os , sys , yaml , black , imp
6
6
import traits
7
7
from pathlib import Path
8
8
import typing as ty
9
9
import inspect
10
- import pytest
11
-
10
+ import click
11
+ import warnings
12
+ import functools
12
13
14
+ sys .path .append (str (Path (__file__ ).resolve ().parent .parent / 'specs' ))
15
+ import callables
13
16
14
17
class FSLConverter :
15
18
@@ -31,8 +34,7 @@ class FSLConverter:
31
34
]
32
35
33
36
34
- def __init__ (self , interface_name ,
35
- interface_spec_file = Path (os .path .dirname (__file__ )) / "../specs/fsl_conv_param.yml" ):
37
+ def __init__ (self , interface_name , interface_spec_file ):
36
38
self .interface_name = interface_name
37
39
with interface_spec_file .open () as f :
38
40
self .interface_spec = yaml .safe_load (f )[self .interface_name ]
@@ -348,7 +350,6 @@ def function_callables(self):
348
350
python_functions_spec = Path (os .path .dirname (__file__ )) / "../specs/callables.py"
349
351
if not python_functions_spec .exists ():
350
352
raise Exception ("specs/callables.py file is needed if output_callables in the spec files" )
351
- from specs import callables
352
353
fun_str = ""
353
354
fun_names = list (set (self .interface_spec ["output_callables" ].values ()))
354
355
fun_names .sort ()
@@ -416,14 +417,55 @@ def string_formats(self, argstr, name):
416
417
return argstr_new
417
418
418
419
419
-
420
- @pytest .mark .parametrize ("interface_name" ,
421
- ["BET" , "MCFLIRT" , "FLIRT" , "FNIRT" , "ApplyWarp" , "SliceTimer" ,
422
- "SUSAN" , "PRELUDE" , "FIRST" , "FAST" ]
423
- )
424
- def test_convert_file (interface_name ):
425
- converter = FSLConverter (interface_name = interface_name )
426
-
427
- dirname_interf = Path (__file__ ).parent .parent / "pydra/tasks/fsl/preprocess"
428
-
429
- input_spec , output_spec = converter .pydra_specs (write = True , dirname = dirname_interf )
420
+ FSL_MODULES = ['aroma' , 'dti' , 'epi' , 'fix' , 'maths' , 'model' , 'possum' , 'preprocess' , 'utils' ]
421
+
422
+ @click .command ()
423
+ @click .option ("-i" , "--interface_name" , required = True , default = "all" ,
424
+ help = "name of the interface (name used in Nipype, e.g. BET) or all (default)"
425
+ "if all is used all interfaces from the spec file will be created" )
426
+ @click .option ("-m" , "--module_name" , required = True , help = f"name of the module from the list { FSL_MODULES } " )
427
+ def create_pydra_spec (interface_name , module_name ):
428
+ if module_name not in FSL_MODULES :
429
+ raise Exception (f"module name { module_name } not available;"
430
+ f"should be from the list { FSL_MODULES } " )
431
+
432
+ spec_file = Path (os .path .dirname (__file__ )) / f"../specs/fsl_{ module_name } _param.yml"
433
+ if not spec_file .exists ():
434
+ raise Exception (f"the specification file doesn't exist for the module { module_name } ,"
435
+ f"create the specification file in { spec_file .parent } " )
436
+
437
+ @functools .lru_cache ()
438
+ def all_interfaces (module ):
439
+ nipype_module = getattr (fsl , module )
440
+ all_specs = [el for el in dir (nipype_module ) if "InputSpec" in el ]
441
+ all_interf = [el .replace ("InputSpec" , "" ) for el in all_specs ]
442
+
443
+ # interfaces in the spec file
444
+ with open (spec_file ) as f :
445
+ spec_interf = yaml .safe_load (f ).keys ()
446
+
447
+ if set (all_interf ) - set (spec_interf ):
448
+ warnings .warn (f"some interfaces are not in the spec file: "
449
+ f"{ set (all_interf ) - set (spec_interf )} , "
450
+ f"and pydra interfaces will not be created for them" )
451
+ return spec_interf
452
+
453
+ if interface_name == "all" :
454
+ interface_list = all_interfaces (module_name )
455
+ elif interface_name in all_interfaces (module_name ):
456
+ interface_list = [interface_name ]
457
+ else :
458
+ raise Exception (f"interface_name has to be 'all' "
459
+ f"or a name from the list { all_interfaces (module_name )} " )
460
+
461
+ dirname_interf = Path (__file__ ).parent .parent / f"pydra/tasks/fsl/{ module_name } "
462
+ dirname_interf .mkdir (exist_ok = True )
463
+
464
+ for interface_el in interface_list :
465
+ converter = FSLConverter (
466
+ interface_name = interface_el ,
467
+ interface_spec_file = Path (__file__ ).parent .parent / "specs/fsl_preprocess_param.yml" )
468
+ converter .pydra_specs (write = True , dirname = dirname_interf )
469
+
470
+ if __name__ == '__main__' :
471
+ create_pydra_spec ()
0 commit comments