def assertUnitsEqual(self, first, second, msg=None): r"""Assertion for equality in case of objects with units.""" if units.has_units(first) and units.has_units(second): first = units.convert_to(first, units.get_units(second)) self.assertEqual(units.get_data(first), units.get_data(second), msg=msg)
def test_convert_to(self, vars_units): r"""Test convert_to.""" units.convert_to(1, 'm') for v in vars_units: units.convert_to(v, 'm') with pytest.raises(ValueError): units.convert_to(v, 's') x = units.add_units(int(1), 'umol') units.convert_to(x, 'mol')
def transform_type(cls, obj, typedef=None): r"""Transform an object based on type info. Args: obj (object): Object to transform. typedef (dict, optional): Type definition that should be used to transform the object. Defaults to None. Returns: object: Transformed object. """ if typedef is None: return obj typedef0 = cls.encode_type(obj) typedef1 = copy.deepcopy(typedef0) typedef1.update(**typedef) dtype = ScalarMetaschemaProperties.definition2dtype(typedef1) arr = cls.to_array(obj).astype(dtype, casting='same_kind') out = cls.from_array(arr, unit_str=typedef0.get('units', None), dtype=dtype) out = cls.as_python_type(out, typedef) return units.convert_to(out, typedef1.get('units', None))
def assert_equal(x, y): r"""Assert that two messages are equivalent. Args: x (object): Python object to compare against y. y (object): Python object to compare against x. Raises: AssertionError: If the two messages are not equivalent. """ if isinstance(y, (list, tuple)): assert(isinstance(x, (list, tuple))) ut.assertEqual(len(x), len(y)) for ix, iy in zip(x, y): assert_equal(ix, iy) elif isinstance(y, dict): assert(issubclass(y.__class__, dict)) # ut.assertEqual(type(x), type(y)) ut.assertEqual(len(x), len(y)) for k, iy in y.items(): ix = x[k] assert_equal(ix, iy) elif isinstance(y, (np.ndarray, pd.DataFrame)): if units.has_units(y) and (not units.has_units(x)): # pragma: debug y = units.get_data(y) elif (not units.has_units(y)) and units.has_units(x): x = units.get_data(x) np.testing.assert_array_equal(x, y) else: if units.has_units(y) and units.has_units(x): x = units.convert_to(x, units.get_units(y)) assert_equal(units.get_data(x), units.get_data(y)) else: if units.has_units(y) and (not units.has_units(x)): # pragma: debug y = units.get_data(y) elif (not units.has_units(y)) and units.has_units(x): x = units.get_data(x) ut.assertEqual(x, y)
def test_convert_to(self): r"""Test convert_to.""" units.convert_to(1, 'm') for v in self._vars_units: units.convert_to(v, 'm') self.assert_raises(ValueError, units.convert_to, v, 's')
def response_loop(cls, client_model, request_id, rpc, time, internal_variables, external_variables, tables, table_units, table_lock, synonyms, interpolation, aggregation): r"""Check for available data and send response if it is available. Args: client_model (str): Name of model that made the request. request_id (str): ID associated with request that should be responded to. rpc (ServerComm): Server RPC comm that should be used to reply to the request when the data is available. time (pandas.Timedelta): Time to get variables at. internal_variables (list): Variables that model is requesting that it also calculates. external_variables (list): Variables that model is requesting that will be provided by other models. tables (dict): Mapping from model name to pandas DataFrames containing variables supplied by the model. table_units (dict): Mapping from model name to dictionaries mapping from variable names to units. table_lock (RLock): Thread-safe lock for accessing table. synonyms (dict): Dictionary mapping from base variables to alternate variables and mapping functions used to convert between the variables. Defaults to empty dict and no conversions are performed. interpolation (dict): Mapping from model name to the interpolation kwargs that should be used. Defaults to empty dictionary. aggregation (dict): Mapping from variable name to the aggregation method that should be used. Defaults to empty dictionary. """ if not (rpc.all_clients_connected and cls.check_for_data( time, tables, table_units, table_lock, rpc.open_clients)): # Don't start sampling until all clients have connected # and there is data available for the requested timestep tools.sleep(1.0) return tot = cls.merge(tables, table_units, table_lock, rpc.open_clients, synonyms, interpolation, aggregation) # Update external units for k in external_variables: if k not in table_units[client_model]: table_units[client_model][k] = table_units['base'][k] # Check if data is available at the desired timestep? # Convert units for k in tot.columns: funits = units.get_conversion_function( table_units['base'][k], table_units[client_model][k]) tot[k] = tot[k].apply(funits) # Transform back to variables expected by the model for kbase, alt in synonyms.get(client_model, {}).items(): if alt['base2alt'] is not None: alt_vars = alt['base2alt'](tot[kbase]) if isinstance(alt_vars, (tuple, list)): assert (len(alt_vars) == len(alt['alt'])) for k, v in zip(alt['alt'], alt_vars): tot[k] = v else: assert (len(alt['alt']) == 1) tot[alt['alt'][0]] = alt_vars else: tot[alt['alt'][0]] = tot[kbase] # Get state state = {} for v in internal_variables + external_variables: v_res = tot.loc[time, v] state[v] = units.add_units(v_res, table_units[client_model][v]) time_u = units.convert_to(units.convert_from_pandas_timedelta(time), table_units[client_model]['time']) flag = rpc.send_to(request_id, state) if not flag: # pragma: debug raise RuntimeError( ("Failed to send response to " "request %s for time %s from " "model %s.") % (request_id, time_u, client_model)) raise multitasking.BreakLoopException