def test_lazy_loop_calculator_cls():
    """Test the lazy loop calculator class."""
    calc = {
        'formula': 'pythagorian_thm',
        'args': {
            'data': {
                'adjacent': 'a',
                'opposite': 'b'
            },
            'outputs': {}
        },
        'returns': ['c']
    }
    formula_reg = FormulaRegistry()
    formula_reg.register(
        {'pythagorian_thm': UREG.wraps(*PYTHAGOREAN_UNITS)(f_pythagorian_thm)},
        args={'pythagorian_thm': ['adjacent', 'opposite']},
        units={'pythagorian_thm': PYTHAGOREAN_UNITS},
        isconstant={'pythagorian_thm': None})
    data_reg = DataRegistry()
    data_reg.register(
        {
            'a': [3., 5., 7., 9., 11.] * UREG('cm'),
            'b': [4., 12., 24., 40., 60.] * UREG('cm')
        },
        uncertainty=None,
        variance=None,
        isconstant={
            'a': True,
            'b': True
        })
    out_reg = OutputRegistry()
    out_reg.register({'c': np.zeros(5) * UREG.m})
    # repeat args are listed as formula names, not data reg names!
    calculator = LazyLoopingCalculator(repeat_args=['adjacent', 'opposite'])
    calculator.calculate(calc, formula_reg, data_reg, out_reg)
    assert np.allclose(out_reg['c'].m, PYTHAGOREAN_TRIPLES)  # check magnitudes
    assert out_reg['c'].u == UREG.m  # output units are meters
    return out_reg
예제 #2
0
 def __init__(self):
     if hasattr(self, 'param_file'):
         # read and load JSON parameter map file as "parameters"
         with open(self.param_file, 'r') as fp:
             #: dictionary of parameters for reading formula source file
             self.parameters = json.load(fp)
     else:
         #: parameter file
         self.param_file = None
     # check for path listed in param file
     if 'path' in self.parameters and self.parameters.get('path') is None:
         proxy_file = self.param_file if self.param_file else __file__
         # use the same path as the param file or this file if no param file
         self.parameters['path'] = os.path.dirname(proxy_file)
     #: formulas loaded by the importer using specified parameters
     self.formulas = self.formula_importer(self.parameters).import_formulas()
     #: linearity determined by each data source?
     self.islinear = {}
     #: positional arguments
     self.args = {}
     #: expected units of returns and arguments as pair of tuples
     self.units = {}
     #: constant arguments that are not included in covariance calculation
     self.isconstant = {}
     # sequence of formulas, don't propagate uncertainty or units
     for f in self.formulas:
         self.islinear[f] = True
         self.args[f] = inspect.getargspec(self.formulas[f]).args
     formula_param = self.parameters.get('formulas')  # formulas key
     # if formulas is a list or if it can't be iterated as a dictionary
     # then log warning and return
     try:
         formula_param_generator = formula_param.iteritems()
     except AttributeError as err:
         LOGGER.warning('Attribute Error: %s', err.message)
         return
     # formula dictionary
     for k, v in formula_param_generator:
         if not v:
             # skip formula if attributes are null or empty
             continue
         # get islinear formula attribute
         is_linear = v.get('islinear')
         if is_linear is not None:
             self.islinear[k] = is_linear
         # get positional arguments
         f_args = v.get('args')
         if f_args is not None:
             self.args[k] = f_args
         # get constant arguments to exclude from covariance
         self.isconstant[k] = v.get('isconstant')
         if self.isconstant[k] is not None:
             argn = [n for n, a in enumerate(self.args[k]) if a not in
                     self.isconstant[k]]
             LOGGER.debug('%s arg nums: %r', k, argn)
             self.formulas[k] = unc_wrapper_args(*argn)(self.formulas[k])
         # get units of returns and arguments
         self.units[k] = v.get('units')
         if self.units[k] is not None:
             # append units for covariance and Jacobian if all args
             # constant and more than one return output
             if self.isconstant[k] is not None:
                 # check if retval units is a string or None before adding
                 # extra units for Jacobian and covariance
                 ret_units = self.units[k][0]
                 if isinstance(ret_units, basestring) or ret_units is None:
                     self.units[k][0] = [ret_units]
                 try:
                     self.units[k][0] += [None, None]
                 except TypeError:
                     self.units[k][0] += (None, None)
             # wrap function with Pint's unit wrapper
             self.formulas[k] = UREG.wraps(*self.units[k])(
                 self.formulas[k]
             )
예제 #3
0
 def __init__(self):
     if hasattr(self, 'param_file'):
         # read and load JSON parameter map file as "parameters"
         with open(self.param_file, 'r') as fp:
             #: dictionary of parameters for reading formula source file
             self.parameters = json.load(fp)
     else:
         #: parameter file
         self.param_file = None
     # check for path listed in param file
     if 'path' in self.parameters and self.parameters.get('path') is None:
         proxy_file = self.param_file if self.param_file else __file__
         # use the same path as the param file or this file if no param file
         self.parameters['path'] = os.path.dirname(proxy_file)
     #: formulas loaded by the importer using specified parameters
     self.formulas = self.formula_importer(self.parameters).import_formulas()
     #: linearity determined by each data source?
     self.islinear = {}
     #: positional arguments
     self.args = {}
     #: expected units of returns and arguments as pair of tuples
     self.units = {}
     #: constant arguments that are not included in covariance calculation
     self.isconstant = {}
     # sequence of formulas, don't propagate uncertainty or units
     for f in self.formulas:
         self.islinear[f] = True
         self.args[f] = inspect.getargspec(self.formulas[f]).args
     formula_param = self.parameters.get('formulas')  # formulas key
     # if formulas is a list or if it can't be iterated as a dictionary
     # then log warning and return
     try:
         formula_param_generator = formula_param.iteritems()
     except AttributeError as err:
         LOGGER.warning('Attribute Error: %s', err.message)
         return
     # formula dictionary
     for k, v in formula_param_generator:
         if not v:
             # skip formula if attributes are null or empty
             continue
         # get islinear formula attribute
         is_linear = v.get('islinear')
         if is_linear is not None:
             self.islinear[k] = is_linear
         # get positional arguments
         f_args = v.get('args')
         if f_args is not None:
             self.args[k] = f_args
         # get constant arguments to exclude from covariance
         self.isconstant[k] = v.get('isconstant')
         if self.isconstant[k] is not None:
             argn = [n for n, a in enumerate(self.args[k]) if a not in
                     self.isconstant[k]]
             LOGGER.debug('%s arg nums: %r', k, argn)
             self.formulas[k] = unc_wrapper_args(*argn)(self.formulas[k])
         # get units of returns and arguments
         self.units[k] = v.get('units')
         if self.units[k] is not None:
             # append units for covariance and Jacobian if all args
             # constant and more than one return output
             if self.isconstant[k] is not None:
                 # check if retval units is a string or None before adding
                 # extra units for Jacobian and covariance
                 ret_units = self.units[k][0]
                 if isinstance(ret_units, basestring) or ret_units is None:
                     self.units[k][0] = [ret_units]
                 try:
                     self.units[k][0] += [None, None]
                 except TypeError:
                     self.units[k][0] += (None, None)
             # wrap function with Pint's unit wrapper
             self.formulas[k] = UREG.wraps(*self.units[k])(
                 self.formulas[k]
             )