Source code for pymt.component.model

import os

import yaml

from .component import Component


[docs]def get_exchange_item_mapping(items): """Construct a mapping for exchange items. Parameters ---------- items : iterable List of exchange item names or (*dest*, *src*) tuples. Returns ------- items : list List of (*dest*, *src*) tuples of name mappings. Examples -------- >>> from pymt.component.model import get_exchange_item_mapping >>> get_exchange_item_mapping([('foo', 'bar'), 'baz']) [('foo', 'bar'), ('baz', 'baz')] >>> get_exchange_item_mapping([dict(source='bar', ... destination='foo'), 'baz']) [('foo', 'bar'), ('baz', 'baz')] """ mapping = [] for item in items: if isinstance(item, str): item_map = (item, item) else: try: item_map = (item["destination"], item["source"]) except TypeError: item_map = item if len(item_map) != 2: raise ValueError(item) mapping.append(item_map) return mapping
[docs]class Model: def __init__(self, components, driver=None, duration=0.0): self._components = dict(components) self._driver = driver self._duration = duration def __getitem__(self, name): return self._components[name] @property def components(self): """Names of the components.""" return list(self._components.keys()) @property def driver(self): """Name of the driver component.""" return self._driver @driver.setter def driver(self, driver): """Set the driver component.""" if driver in self.components: self._driver = driver else: raise ValueError("%s not a component of the model" % driver) @property def duration(self): """Length of time the model will run.""" return self._duration @duration.setter def duration(self, duration): """Set length of time the model will run.""" self._duration = duration
[docs] def go(self, filename=None): """Start the model.""" if filename: with open(filename) as f: model = yaml.safe_load(f.read()) self._driver, self._duration = (model["driver"], model["duration"]) self._components[self.driver].go(self.duration)
[docs] @classmethod def load(cls, source): """Construct a model from a YAML-formatted string. Parameters ---------- source : str or file_like YAML-formatted model configuration. Returns ------- model : Model A newly-created Model. Examples -------- >>> from pymt.framework.services import del_component_instances >>> del_component_instances(['air_port']) >>> from pymt.component.model import Model >>> source = ''' ... name: air_port ... class: AirPort ... connectivity: [] ... ''' >>> model = Model.load(source) >>> model.components ['air_port'] >>> model.driver is None True >>> model.duration 0.0 >>> model.driver = 'air_port' >>> model.duration = 1. >>> model['air_port'].current_time 0.0 >>> model.go() # doctest: +NORMALIZE_WHITESPACE {name: air_port, status: running, time: 1.0} >>> model['air_port'].current_time 1.0 """ components, connectivities = Model.load_components( source, with_connectivities=True ) for name, component in components.items(): for port in connectivities[name]: mapping = get_exchange_item_mapping(port["exchange_items"]) component.connect( port["name"], components[port["connect"]], vars_to_map=mapping ) return cls(components)
[docs] @classmethod def from_file(cls, filename): """Construct a Model from the contents of a file. Parameters ---------- filename : str Name of the model configuration file. Returns ------- model : Model A newly-created model. """ with open(filename) as fp: return cls.load(fp)
[docs] @classmethod def from_file_like(cls, file_like): """Construct a Model from the contents of a file-like object. Parameters ---------- file_like : file_like A file-like object that contains the model configuration. Returns ------- model : Model A newly-created model. """ return cls.load(file_like)
[docs] @classmethod def from_string(cls, contents): """Construct a Model from a string. Parameters ---------- contents : str A string that contains the model configuration. Returns ------- model : Model A newly-created model. """ return cls.load(contents)
[docs] @staticmethod def load_components(source, with_connectivities=False): """Construct a list of model components from a string. Parameters ---------- source : str or file_like YAML-formatted components configuration. with_connectivities : boolean (optional) Return connectivity dictionary along with components. Returns ------- components : dict Dictionary of newly-created components. Examples -------- >>> from pymt.framework.services import del_component_instances >>> del_component_instances(['air_port']) >>> from pymt.component.model import Model >>> source = ''' ... name: air_port ... class: AirPort ... connectivity: [] ... ''' >>> components = Model.load_components(source) >>> list(components.keys()) ['air_port'] """ components = {} connectivities = {} prefix = os.getcwd() for section in yaml.safe_load_all(source): try: section["run_dir"] = os.path.join(prefix, section.get("run_dir", ".")) except AttributeError: raise ValueError(section) components[section["name"]] = Component.from_dict(section) if with_connectivities: connectivities[section["name"]] = section["connectivity"] if with_connectivities: return components, connectivities else: return components