def test_add_units(self, vars_nounits): r"""Test add_units.""" for v in vars_nounits: x = units.add_units(v, 'cm') assert (units.has_units(x)) assert (units.add_units(1.0, '') == 1.0) assert (units.add_units(1.0, 'n/a') == 1.0)
def run(tmin, tmax, tstep): mass = 2000.0 mesh_in = YggInput('mesh') mesh_out = YggOutput('mesh') mass = units.add_units(mass, 'g') tmin = units.add_units(tmin, 'hrs') tmax = units.add_units(tmax, 'hrs') tstep = units.add_units(tstep, 'hrs') t = tmin while t <= tmax: # Receive mesh as input flag, mesh = mesh_in.recv() if not flag: raise Exception("Error receiving mesh from input") mesh = mesh.as_trimesh() # Grow mesh # (pretend this is a biologically complex calculation) scale = units.get_data(mass * t / units.add_units(1.5e6, 'g*hrs')) mesh.vertices[:, 2] += mesh.vertices[:, 2] * scale # Send mesh to output for this timestep flag = mesh_out.send(mesh) if not flag: raise Exception("Error sending mesh to output") # Advance time step t += tstep return mesh
def get_testing_options(cls): r"""Get testing options for the filter class. Returns: list: Mutiple dictionaries of keywords and messages that will pass/fail for those keywords. """ def fcond(x): return (units.get_data(x) != 3) return [{ 'kwargs': { 'function': fcond }, 'pass': [ 1, 2, units.add_units(1, 'cm'), np.ones(3, int), units.add_units(np.ones(3, int), 'cm') ], 'fail': [ 3, units.add_units(3, 'cm'), 3 * np.ones(3, int), units.add_units(3 * np.ones(3, int), 'cm') ] }]
def get_testing_options(cls): r"""Get testing options for the filter class. Returns: list: Mutiple dictionaries of keywords and messages that will pass/fail for those keywords. """ out = [{ 'kwargs': { 'statement': '%x% != 2' }, 'pass': [1, 3], 'fail': [2] }, { 'kwargs': { 'statement': '%x% != array([0, 0, 0])' }, 'pass': [np.ones(3, int)], 'fail': [np.zeros(3, int)] }, { 'kwargs': { 'statement': '%x% != add_units(1, "cm")' }, 'pass': [units.add_units(2, 'cm')], 'fail': [units.add_units(1, 'cm')] }, { 'kwargs': { 'statement': '%x% != ' + repr(units.add_units(1, 'cm')) }, 'pass': [units.add_units(2, 'cm')], 'fail': [units.add_units(1, 'cm')] }] return out
def get_testing_options(cls): r"""Get testing options for the transform class. Returns: list: Multiple dictionaries of keywords and messages before/after pairs that will result from the transform created by the provided keywords. """ out = [{ 'kwargs': { 'statement': '%x%**3' }, 'in/out': [(1, 1), (2, 8)] }, { 'kwargs': { 'statement': '%x% * array([1, 1, 1])' }, 'in/out': [(1, np.ones(3, int)), (2, 2 * np.ones(3, int))] }, { 'kwargs': { 'statement': '%x% * ' + repr(units.add_units(1.0, 'cm')) }, 'in/out': [(1.0, units.add_units(1.0, 'cm')), (2.0, units.add_units(2.0, 'cm'))] }, { 'kwargs': { 'statement': '%x%**3' }, 'in/out': [(iter([1, 2]), iter([1, 8]))] }] return out
def run(tmin, tmax, tstep): mass_out = YggOutput('mass') plant2root = YggTimesync('plant2root') tmin = units.add_units(tmin, 'days') tmax = units.add_units(tmax, 'days') tstep = units.add_units(tstep, 'days') t = tmin mass = 0 while t <= tmax: # Calculate mass for the time step # (pretend this is a biologically complex calculation) mass += t * units.add_units(0.2, 'kg/days') # Synchronize data for time step with the root model plant_state = {'mass': mass} flag, plant_state = plant2root.call(t, plant_state) if not flag: raise Exception("Error performing time-step synchronization " "with plant model.") # Send masses to output flag = mass_out.send({'time': t, 'total_mass': plant_state['mass'], 'root_mass': mass, 'plant_mass': plant_state['mass'] - mass}) if not flag: raise Exception("Error sending masses to output") # Advance time step t += tstep return mass
def main(t_step, t_units): r"""Function to execute integration. Args: t_step (float): The time step that should be used. t_units (str): Units of the time step. """ print('Hello from Python other_model: timestep = %s %s' % (t_step, t_units)) t_step = units.add_units(t_step, t_units) t_start = units.add_units(0.0, t_units) t_end = units.add_units(1.0, 'day') state = timestep_calc(t_start) # Set up connections matching yaml # Timestep synchonization connection will default to 'timesync' timesync = YggTimesync('timesync') out = YggOutput('output') # Initialize state and synchronize with other models t = t_start ret, state = timesync.call(t, state) if not ret: raise RuntimeError("other_model(Python): Initial sync failed.") print('other_model(Python): t = % 8s' % t, end='') for k, v in state.items(): print(', %s = %+ 5.2f' % (k, v), end='') print('') # Send initial state to output flag = out.send(dict(state, time=t)) if not flag: raise RuntimeError("other_model(Python): Failed to send " "initial output for t=%s." % t) # Iterate until end while t < t_end: # Perform calculations to update the state t = t + t_step state = timestep_calc(t) # Synchronize the state ret, state = timesync.call(t, state) if not ret: raise RuntimeError("other_model(Python): sync for t=%f failed." % t) print('other_model(Python): t = % 8s' % t, end='') for k, v in state.items(): print(', %s = %+ 5.2f' % (k, v), end='') print('') # Send output flag = out.send(dict(state, time=t)) if not flag: raise RuntimeError( "other_model(Python): Failed to send output for t=%s." % t) print('Goodbye from Python other_model')
def __init__(self, *args, **kwargs): super(TestUnitsMetaschemaProperty, self).__init__(*args, **kwargs) self._valid = [(1, ''), (units.add_units(1, 'cm'), 'm')] self._invalid = [(units.add_units(1, 'cm'), 'kg')] self._valid_compare = [('cm', 'cm'), ('cm', 'm'), ('m', 'cm'), ('', 'cm'), ('cm', '')] self._invalid_compare = [('cm', 'g')]
def test_add_units(self): r"""Test add_units.""" for v in self._vars_nounits: x = units.add_units(v, 'cm') assert (units.has_units(x)) self.assert_equal(units.add_units(1.0, ''), 1.0) self.assert_equal(units.add_units(1.0, 'n/a'), 1.0)
def timestep_calc(t, model): r"""Updates the state based on the time where x is a sine wave with period of 10 days and y is a cosine wave with a period of 5 days. If model is 'A', the forth state variable will be 'a', a sine with a period of 2.5 days. If model is 'B', the forth state variable will be 'b', a cosine with a period of 2.5 days. Args: t (float): Current time. model (str): Identifier for the model (A or B). Returns: dict: Map of state parameters. """ if model == 'A': state = { 'x': np.sin(2.0 * np.pi * t / units.add_units(10, 'day')), 'y': np.cos(2.0 * np.pi * t / units.add_units(5, 'day')), 'z1': -np.cos(2.0 * np.pi * t / units.add_units(20, 'day')), 'z2': -np.cos(2.0 * np.pi * t / units.add_units(20, 'day')), 'a': np.sin(2.0 * np.pi * t / units.add_units(2.5, 'day')) } else: state = { 'xvar': x2xvar(np.sin(2.0 * np.pi * t / units.add_units(10, 'day'))), 'yvar': np.cos(2.0 * np.pi * t / units.add_units(5, 'day')), 'z': -2.0 * np.cos(2.0 * np.pi * t / units.add_units(20, 'day')), 'b': np.cos(2.0 * np.pi * t / units.add_units(2.5, 'day')) } return state
def run(mesh, tmin, tmax, tstep): mass = 2000.0 light_rpc = YggRpcClient('light_plant') light_out = YggOutput('light') plant2root = YggTimesync('plant2root') mass = units.add_units(mass, 'g') tmin = units.add_units(tmin, 'hrs') tmax = units.add_units(tmax, 'hrs') tstep = units.add_units(tstep, 'hrs') t = tmin i = 0 while t <= tmax: # Perform send portion of call to synchronize data for time step # with the root model root_state = {'mass': mass} flag = plant2root.send(t, root_state) if not flag: raise Exception("Error performing time-step synchronization " "with root model.") # Get light data by calling light model flag, light = light_rpc.call(mesh.vertices[:, 2], t) if not flag: raise Exception("Error calling light model") # Perform receive portion of call to synchronize data for time step # with the root model flag, root_state = plant2root.recv() if not flag: raise Exception("Error performing recv for time-step " "synchronization with root model.") mass = root_state['mass'] # Grow mesh # (pretend this is a biologically complex calculation) scale = units.get_data(mass * light / units.add_units(1.0, 'kg')) mesh.vertices[:, 2] += mesh.vertices[:, 2] * scale # Save mesh for this timestep filename_mesh = os.path.join(_dir, f'../output/mesh_{i:03d}.obj') with open(filename_mesh, 'w') as fd: mesh.export(fd, 'obj') # Send light to output flag = light_out.send(light) if not flag: raise Exception("Error sending light to output") # Advance time step t += tstep i += 1 return mesh
def test_convert_R_unit_string(self): r"""Test convert_R_unit_string.""" pairs = [('g', 'g'), ('g2', '(g**2)'), ('g2 km s-2', '(g**2)*km*(s**-2)'), ('degC d', 'degC*d'), (tools.bytes2str(b'\xc2\xb0C d'), tools.bytes2str(b'\xc2\xb0C*d')), ('h', 'hr'), ('hrs/kg', 'hr/kg'), ('', ''), ('cm**(-2)', '(cm**-2)')] for x, y in pairs: self.assert_equal(units.convert_R_unit_string(x), y) self.assert_equal(units.convert_R_unit_string(y), y) units.add_units(1.0, x)
def wrapped_map_sent2recv(obj): if (not isinstance(obj, bytes)) or (obj != tools.YGG_MSG_EOF): field_units = testing_options.get('field_units', None) if field_units: if isinstance(obj, dict): return {k: units.add_units(v, u, dtype=data2dtype(v)) for (k, v), u in zip(obj.items(), field_units)} elif isinstance(obj, (list, tuple)): return [units.add_units(x, u, dtype=data2dtype(x)) for x, u in zip(obj, field_units)] return obj
def map_sent2recv(self, obj): r"""Convert a sent object into a received one.""" if not self.instance.is_eof(obj): field_units = self.testing_options.get('field_units', None) if field_units: if isinstance(obj, dict): return {k: units.add_units(v, u, dtype=data2dtype(v)) for (k, v), u in zip(obj.items(), field_units)} elif isinstance(obj, (list, tuple)): return [units.add_units(x, u, dtype=data2dtype(x)) for x, u in zip(obj, field_units)] return obj
def _generate_data(cls, typedef, numeric_value=None): r"""Generate mock data for the specified type. Args: typedef (dict): Type definition. Returns: object: Python object of the specified type. """ dtype = definition2dtype(typedef) subtype = typedef.get('subtype', typedef['type']) if subtype in ['bytes', 'unicode']: if subtype == 'bytes': value = b'x' * int(typedef['precision'] / 8) else: value = 'x' * int(typedef['precision'] / 32) elif numeric_value is not None: value = numeric_value else: value = 1.0 if typedef['type'] == '1darray': out = np.repeat(np.array([value], dtype), typedef.get('length', 2)) elif typedef['type'] == 'ndarray': out = np.tile(np.array([value], dtype), typedef.get('shape', (4, 5))) else: out = np.array([value], dtype)[0] out = units.add_units(out, typedef.get('units', '')) return out
def from_array(cls, arr, unit_str=None, dtype=None, typedef=None): r"""Get object representation of the data. Args: arr (np.ndarray): Numpy array. unit_str (str, optional): Units that should be added to returned object. dtype (np.dtype, optional): Numpy data type that should be maintained as a base class when adding units. Defaults to None and is determined from the object or typedef (if provided). typedef (dict, optional): Type definition that should be used to decode the object. Defaults to None and is determined from the object or dtype (if provided). Returns: object: Object representation of the data in the input array. """ # if (typedef is None) and (dtype is not None): # typedef = dtype2definition(dtype) # elif (dtype is None) and (typedef is not None): # dtype = definition2dtype(typedef) if (cls.name not in ['1darray', 'ndarray']) and (arr.ndim > 0): out = arr[0] else: out = arr if typedef is not None: # Cast numpy type to native python type if they are equivalent out = cls.as_python_type(out, typedef) if unit_str is not None: if dtype is None: dtype = data2dtype(out) out = units.add_units(out, unit_str, dtype=dtype) return out
def timestep_calc(t): r"""Updates the state based on the time where x is a sine wave with period of 10 days and y is a cosine wave with a period of 5 days. Args: t (float): Current time. Returns: dict: Map of state parameters. """ state = { 'x': np.sin(2.0 * np.pi * t / units.add_units(10, 'day')), 'y': np.cos(2.0 * np.pi * t / units.add_units(5, 'day')) } return state
def concatenate(cls, objects, as_array=False, **kwargs): r"""Concatenate objects to get object that would be recieved if the concatenated serialization were deserialized. Args: objects (list): Objects to be concatenated. as_array (bool, optional): If True, the objects in the list are complete columns in a table and as_format is set to True. Defaults to False. **kwargs: Additional keyword arguments are ignored. Returns: list: Set of objects that results from concatenating those provided. """ if len(objects) == 0: return [] if as_array: units_list = [units.get_units(ix) for ix in objects[0]] out = [[ units.add_units(np.hstack([x[i] for x in objects]), u) for i, u in enumerate(units_list) ]] elif isinstance(objects[0], bytes): out = [b''.join(objects)] else: return super(DefaultSerialize, cls).concatenate(objects, **kwargs) return out
def setup(self, *args, **kwargs): r"""Setup, create variables for testing.""" self._vars_nounits = [1.0, np.zeros(5), int(1)] self._vars_units = [ units.add_units(v, 'cm') for v in self._vars_nounits ] super(TestUnits, self).setup(*args, **kwargs)
def valid_decoded(self, value, valid_units, dtype): r"""list: Objects that are valid under this type.""" out = [value] for x in valid_units: out.append(units.add_units(copy.deepcopy(out[0]), x)) out.append(np.array([], dtype)) return out
def func_deserialize(self, msg): r"""Deserialize a message. Args: msg: Message to be deserialized. Returns: obj: Deserialized message. """ if self.format_str is None: raise RuntimeError("Format string is not defined.") if self.as_array: out = serialize.table_to_array( msg, self.format_str, use_astropy=self.use_astropy, names=self.get_field_names(as_bytes=True)) out = self.datatype.coerce_type(out) else: out = list(serialize.process_message(msg, self.format_str)) field_units = self.get_field_units() if field_units is not None: out = [units.add_units(x, u) for x, u in zip(out, field_units)] return out
def timestep_calc(t): r"""Updates the state based on the time where x is a sine wave with period of 10 days and y is a cosine wave with a period of 5 days. Args: t (float): Current time. Returns: dict: Map of state parameters. """ state = { "carbonAllocation2Roots": units.add_units(10.0, 'g'), "saturatedConductivity": units.add_units(10.0, 'g') } return state
def finalize_element(): if is_arr: out[k][0] = np.array(out[k][0]) out[k][1] = np.array(out[k][1]) if k_units: if is_arr: if ';' in k_units: u1, u2 = k_units.split(';') u1 = self.parse_units(u1.strip()) u2 = self.parse_units(u2.strip()) out[k][0] = units.add_units(out[k][0], u1) out[k][1] = units.add_units(out[k][1], u2) else: out[k][1] = units.add_units(out[k][1], self.parse_units(k_units)) else: out[k] = units.add_units(out[k], self.parse_units(k_units))
def __init__(self, *args, **kwargs): super(TestLengthMetaschemaProperty, self).__init__(*args, **kwargs) nele = 3 valid = np.zeros(nele, 'float') self._valid = [(valid, nele), (units.add_units(valid, 'cm'), nele)] self._invalid = [(valid, nele - 1)] self._valid_compare = [(nele, nele)] self._invalid_compare = [(nele - 1, nele), (nele, nele - 1)]
def test_from_array(self): r"""Test getting object from array.""" test_val = self._value test_kws = {} if 'units' in self._typedef: test_val = units.add_units(test_val, self._typedef['units']) test_kws['unit_str'] = self._typedef['units'] self.assert_equal(self.instance.from_array(self._array, **test_kws), test_val)
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 value(self, class_name, array, value_units): r"""dict: Test value.""" if 'Array' not in class_name: out = array[0] else: out = array if value_units: out = units.add_units(out, value_units) return out
def __init__(self, *args, **kwargs): super(TestShapeMetaschemaProperty, self).__init__(*args, **kwargs) nele = (3, 4) valid = np.zeros(nele, 'float') self._valid = [(valid, nele), (units.add_units(valid, 'cm'), nele)] self._invalid = [(valid, (nele[0], nele[1] - 1))] self._valid_compare = [(nele, nele), (nele, list(nele))] self._invalid_compare = [(nele, nele[::-1]), (nele, nele[:-1])]
def test_from_array(self, value, typedef_base, array, instance, nested_approx): r"""Test getting object from array.""" test_val = value test_kws = {} if 'units' in typedef_base: test_val = units.add_units(test_val, typedef_base['units']) test_kws['unit_str'] = typedef_base['units'] assert (instance.from_array(array, **test_kws) == nested_approx(test_val))
def __init__(self, *args, **kwargs): super(TestScalarMetaschemaType_units, self).__init__(*args, **kwargs) self._typedef['units'] = 'cm' self._valid_encoded.append(copy.deepcopy(self._valid_encoded[0])) self._valid_encoded[-1]['units'] = 'cm' self._valid_encoded.append(copy.deepcopy(self._valid_encoded[0])) self._valid_encoded[-1]['units'] = 'm' self._valid_decoded.append(copy.deepcopy(self._valid_decoded[0])) self._valid_decoded[-1] = units.add_units(self._valid_decoded[-1], 'm') # Version with incorrect units self._invalid_encoded.append(copy.deepcopy(self._valid_encoded[0])) self._invalid_encoded[-1]['units'] = 's'