@@ -127,21 +127,14 @@ def import_formulas(self):
127127 else :
128128 # autodetect formulas assuming first letter is f
129129 formulas = {f : getattr (mod , f ) for f in dir (mod ) if f [:2 ] == 'f_' }
130+ if not len (formulas ):
131+ for f in dir (mod ):
132+ mod_attr = getattr (mod , f )
133+ if inspect .isfunction (mod_attr ):
134+ formulas [f ] = mod_attr
130135 return formulas
131136
132137
133- # methods for auto detecting functions in module
134- # do it using types.FunctionType
135- # import types
136- # f = {f: getattr(mod, f)
137- # for f in mod_attr
138- # if isinstance(getattr(mod, f), types.FunctionType)}
139- # do it using inspect.isfunction()
140- # import inspect
141- # f = {f: getattr(mod, f)
142- # for f in mod_attr if inspect.isfunction(getattr(mod, f))}
143-
144-
145138class NumericalExpressionImporter (FormulaImporter ):
146139 """
147140 Import formulas from numerical expressions using Python Numexpr.
@@ -215,48 +208,57 @@ def __init__(self):
215208 self .units = {}
216209 #: constant arguments that are not included in covariance calculation
217210 self .isconstant = {}
211+ # sequence of formulas, don't propagate uncertainty or units
212+ for f in self .formulas :
213+ self .islinear [f ] = True
214+ self .args [f ] = inspect .getargspec (self .formulas [f ]).args
218215 formula_param = self .parameters .get ('formulas' ) # formulas key
216+ # if formulas is a list or if it can't be iterated as a dictionary
217+ # then log warning and return
219218 try :
220- # formula dictionary
221- for k , v in formula_param .iteritems ():
222- if not v :
223- # skip formula if attributes are null or empty
224- continue
225- # get islinear formula attribute
226- self .islinear [k ] = v .get ('islinear' , True )
227- # get positional arguments
228- self .args [k ] = v .get ('args' )
229- if self .args [k ] is None :
230- # use inspect if args not specified
231- self .args [k ] = inspect .getargspec (self .formulas [k ]).args
232- # get constant arguments to exclude from covariance
233- self .isconstant [k ] = v .get ('isconstant' )
219+ formula_param_generator = formula_param .iteritems ()
220+ except AttributeError as err :
221+ LOGGER .warning ('Attribute Error: %s' , err .message )
222+ return
223+ # formula dictionary
224+ for k , v in formula_param_generator :
225+ if not v :
226+ # skip formula if attributes are null or empty
227+ continue
228+ # get islinear formula attribute
229+ is_linear = v .get ('islinear' )
230+ if is_linear is not None :
231+ self .islinear [k ] = is_linear
232+ # get positional arguments
233+ f_args = v .get ('args' )
234+ if f_args is not None :
235+ self .args [k ] = f_args
236+ # get constant arguments to exclude from covariance
237+ self .isconstant [k ] = v .get ('isconstant' )
238+ if self .isconstant [k ] is not None :
239+ argn = [n for n , a in enumerate (self .args [k ]) if a not in
240+ self .isconstant [k ]]
241+ LOGGER .debug ('%s arg nums: %r' , k , argn )
242+ self .formulas [k ] = unc_wrapper_args (* argn )(self .formulas [k ])
243+ # get units of returns and arguments
244+ self .units [k ] = v .get ('units' )
245+ if self .units [k ] is not None :
246+ # append units for covariance and Jacobian if all args
247+ # constant and more than one return output
234248 if self .isconstant [k ] is not None :
235- argn = [n for n , a in enumerate (self .args [k ]) if a not in
236- self .isconstant [k ]]
237- LOGGER .debug ('%s arg nums: %r' , k , argn )
238- self .formulas [k ] = unc_wrapper_args (* argn )(self .formulas [k ])
239- # get units of returns and arguments
240- self .units [k ] = v .get ('units' )
241- if self .units [k ] is not None :
242- # append units for covariance and Jacobian if all args
243- # constant and more than one return output
244- if self .isconstant [k ] is not None :
245- if isinstance (self .units [k ][0 ], basestring ):
246- self .units [k ][0 ] = [self .units [k ][0 ]]
247- try :
248- self .units [k ][0 ] += [None , None ]
249- except TypeError :
250- self .units [k ][0 ] += (None , None )
251- # wrap function with Pint's unit wrapper
252- self .formulas [k ] = UREG .wraps (* self .units [k ])(
253- self .formulas [k ]
254- )
255- except TypeError :
256- # sequence of formulas, don't propagate uncertainty or units
257- for f in self .formulas :
258- self .islinear [f ] = True
259- self .args [f ] = inspect .getargspec (self .formulas [f ]).args
249+ # check if retval units is a string or None before adding
250+ # extra units for Jacobian and covariance
251+ ret_units = self .units [k ][0 ]
252+ if isinstance (ret_units , basestring ) or ret_units is None :
253+ self .units [k ][0 ] = [ret_units ]
254+ try :
255+ self .units [k ][0 ] += [None , None ]
256+ except TypeError :
257+ self .units [k ][0 ] += (None , None )
258+ # wrap function with Pint's unit wrapper
259+ self .formulas [k ] = UREG .wraps (* self .units [k ])(
260+ self .formulas [k ]
261+ )
260262
261263 def __getitem__ (self , item ):
262264 return self .formulas [item ]
0 commit comments