44import re
55
66
7- from numpydoc .docscrape import ClassDoc
7+ from numpydoc .docscrape import ClassDoc , FunctionDoc
88import nimare .meta .cbma as nicoords
99import nimare .meta .ibma as niimgs
1010import nimare .meta .kernel as nikern
1111import nimare .correct as crrct
1212import nimare
1313
1414PARAM_OPTIONAL_REGEX = re .compile (
15- r"(?:\:obj\:`)?(?P<type>.*?)` ?(?:, optional|\(optional\))?$"
15+ r"(?:\:obj\:`)?(?P<type>\{.*\}|.*?)(?:`) ?(?:(?: , optional|\(optional\))|(?:, default=(?P<default>.*) ))?$"
1616)
1717
1818NIMARE_CORRECTORS = [
2525NIMARE_IMAGE_ALGORITHMS = [
2626 cls
2727 for cls in inspect .getmembers (niimgs , inspect .isclass )
28- if cls [0 ] not in ["NiftiMasker" , "MetaEstimator" ]
28+ if cls [0 ] not in [
29+ "NiftiMasker" ,
30+ "MetaEstimator" ,
31+ "Memory" ,
32+ "Estimator" ,
33+ "IBMAEstimator" ,
34+ "Memory"
35+ ]
2936]
3037
3138
3845 "SCALE" : "ALEKernel" ,
3946}
4047
48+ BLACKLIST_ALGORITHMS = [
49+ "SCALE"
50+ ]
51+
4152BLACKLIST_PARAMS = [
4253 "n_cores" ,
4354 "memory_limit" ,
4455 "null_distributions_" ,
4556 "inputs_" ,
4657 "masker" ,
4758 "kernel_transformer" ,
59+ "memory" ,
60+ "memory_level" ,
61+ "result" ,
62+ "self" ,
4863]
4964
5065config = {
@@ -61,26 +76,112 @@ def _derive_type(type_name):
6176 type_name , _ = spl [0 ], spl [1 :]
6277 optional_type = PARAM_OPTIONAL_REGEX .match (type_name )
6378 if optional_type :
64- return optional_type .group ("type" )
65- return type_name
79+ return optional_type .group ("type" ), optional_type .group ("default" )
80+ return type_name , None
81+
82+
83+ def _derive_default (class_signature , param ):
84+ default = getattr (
85+ cls_signature .parameters .get (param .name ), "default" , None
86+ )
87+ if isinstance (default , tuple ):
88+ default = default [0 ]
89+
90+ if default is inspect ._empty :
91+ default = None
92+
93+ # try to parse default from docstring
94+ if default is None :
95+ dtype , default = _derive_type (param .type )
96+ if default is not None :
97+ if dtype == "int" :
98+ default = int (default )
99+ elif dtype == "float" :
100+ default = float (default )
101+ elif dtype == "bool" :
102+ if default .lower () == "true" :
103+ default = True
104+ elif default .lower () == "false" :
105+ default = False
106+ elif dtype == "str" :
107+ default = str (default )
108+ elif dtype == "list" :
109+ default = list (default )
110+ elif dtype == "tuple" :
111+ default = tuple (default )
112+ elif dtype == "dict" :
113+ default = dict (default )
114+ elif dtype == "set" :
115+ default = set (default )
116+ elif dtype == "NoneType" :
117+ default = None
118+ else :
119+ raise ValueError (f"Unknown type: { dtype } " )
120+ if isinstance (default , tuple ):
121+ default = default [0 ]
122+ return default
123+
124+
125+ def _check_fwe (cls ):
126+ # Check if the method exists
127+ has_method = hasattr (cls , 'correct_fwe_montecarlo' )
128+ if has_method :
129+ # Get the method
130+ method = getattr (cls , 'correct_fwe_montecarlo' )
131+
132+ # Get the source code of the method
133+ source_code = inspect .getsource (method )
134+
135+ # Check if the source code contains 'NotImplementedError'
136+ fwe_enabled = 'NotImplementedError' not in source_code
137+ else :
138+ fwe_enabled = False
139+
140+ if fwe_enabled :
141+ # Get the signature of the method
142+ method_signature = inspect .signature (method )
143+
144+ # get the function docstring
145+ mdocs = FunctionDoc (method )
146+
147+ # Get the default parameters of the method
148+ method_default_parameters = {
149+ param .name : {
150+ "description" : " " .join (param .desc ),
151+ "type" : _derive_type (param .type )[0 ] or None ,
152+ "default" : _derive_default (method_signature , param ),
153+ }
154+ for param in mdocs ._parsed_data ["Parameters" ]
155+ if param .name not in BLACKLIST_PARAMS
156+ },
157+
158+ if isinstance (method_default_parameters , tuple ):
159+ method_default_parameters = method_default_parameters [0 ]
160+
161+ return True , method_default_parameters
162+ else :
163+ return False , None
66164
67165
68166for algo , cls in NIMARE_COORDINATE_ALGORITHMS :
167+ if algo in BLACKLIST_ALGORITHMS :
168+ continue
69169 docs = ClassDoc (cls )
70170 cls_signature = inspect .signature (cls )
171+
71172 config ["CBMA" ][algo ] = {
72173 "summary" : " " .join (docs ._parsed_data ["Summary" ]),
73174 "parameters" : {
74175 param .name : {
75176 "description" : " " .join (param .desc ),
76- "type" : _derive_type (param .type ) or None ,
77- "default" : getattr (
78- cls_signature .parameters .get (param .name ), "default" , None
79- ),
177+ "type" : _derive_type (param .type )[0 ] or None ,
178+ "default" : _derive_default (cls_signature , param ),
80179 }
81180 for param in docs ._parsed_data ["Parameters" ]
82181 if param .name not in BLACKLIST_PARAMS
83182 },
183+ "FWE_enabled" : _check_fwe (cls )[0 ],
184+ "FWE_parameters" : _check_fwe (cls )[1 ],
84185 }
85186
86187 kern_cls = getattr (nikern , DEFAULT_KERNELS [algo ])
@@ -91,10 +192,8 @@ def _derive_type(type_name):
91192 "kernel__"
92193 + param .name : {
93194 "description" : " " .join (param .desc ),
94- "type" : _derive_type (param .type ),
95- "default" : getattr (
96- kern_cls_signature .parameters .get (param .name ), "default" , None
97- ),
195+ "type" : _derive_type (param .type )[0 ],
196+ "default" : _derive_default (kern_cls_signature , param ),
98197 }
99198 for param in kern_docs ._parsed_data ["Parameters" ]
100199 if param .name not in BLACKLIST_PARAMS
@@ -109,10 +208,8 @@ def _derive_type(type_name):
109208 "parameters" : {
110209 param .name : {
111210 "description" : " " .join (param .desc ),
112- "type" : _derive_type (param .type ) or None ,
113- "default" : getattr (
114- cls_signature .parameters .get (param .name ), "default" , None
115- ),
211+ "type" : _derive_type (param .type )[0 ] or None ,
212+ "default" : _derive_default (cls_signature , param ),
116213 }
117214 for param in docs ._parsed_data ["Parameters" ]
118215 if param .name not in BLACKLIST_PARAMS
@@ -121,27 +218,36 @@ def _derive_type(type_name):
121218
122219
123220for algo , cls in NIMARE_IMAGE_ALGORITHMS :
221+ if algo in BLACKLIST_ALGORITHMS :
222+ continue
124223 docs = ClassDoc (cls )
125224 cls_signature = inspect .signature (cls )
126225 config ["IBMA" ][algo ] = {
127226 "summary" : " " .join (docs ._parsed_data ["Summary" ]),
128227 "parameters" : {
129228 param .name : {
130229 "description" : " " .join (param .desc ),
131- "type" : _derive_type (param .type ) or None ,
132- "default" : getattr (
133- cls_signature .parameters .get (param .name ), "default" , None
134- ),
230+ "type" : _derive_type (param .type )[0 ] or None ,
231+ "default" : _derive_default (cls_signature , param ),
135232 }
136233 for param in docs ._parsed_data ["Parameters" ]
137234 if param .name not in BLACKLIST_PARAMS
138235 },
236+ "FWE_enabled" : _check_fwe (cls )[0 ],
237+ "FWE_parameters" : _check_fwe (cls )[1 ],
139238 }
140239
240+ # SET MANUAL DEFAULTS (Hacks!)
241+ # for some reason treating this as a set causes errors :(
242+ config ["CORRECTOR" ]["FWECorrector" ]["parameters" ]["method" ]["type" ] = "str"
243+ # since we don't have sample size, setting another reasonable default
244+ config ["CBMA" ]["ALE" ]["parameters" ]["kernel__fwhm" ]["default" ] = 8
245+ config ["CBMA" ]["ALESubtraction" ]["parameters" ]["kernel__fwhm" ]["default" ] = 8
141246
142247# save config file
143248fname = (
144249 Path (__file__ ).parent .parent
250+ / "NiMARE"
145251 / "src"
146252 / "assets"
147253 / "config"
0 commit comments