def resolve_simulation(self, fc, ct): """ Resolve simulation specifications. """ for run in ct.simulation.runs: try: run2 = Run( fc.component_references[ run.component].referenced_component, run.variable, fc.parameters[run.increment].numeric_value, fc.parameters[run.total].numeric_value) except: raise ModelError( "Unable to resolve simulation run parameters in component '{0}'", fc.id) fc.simulation.add(run2) for record in ct.simulation.records: try: record2 = Record( fc.paths[record.quantity].value, fc.parameters[record.scale].numeric_value if record.scale else 1, fc.texts[record.color].value if record.color else '#000000') except: raise ModelError( "Unable to resolve simulation record parameters in component '{0}'", fc.id) fc.simulation.add(record2) for dd in ct.simulation.data_displays: try: dd2 = DataDisplay(fc.texts[dd.title].value, '') if 'timeScale' in fc.parameters: dd2.timeScale = fc.parameters['timeScale'].numeric_value except: raise ModelError( "Unable to resolve simulation display parameters in component '{0}'", fc.id) fc.simulation.add(dd2) for dw in ct.simulation.data_writers: try: path = '.' if fc.texts[dw.path] and fc.texts[dw.path].value: path = fc.texts[dw.path].value dw2 = DataWriter(path, fc.texts[dw.file_name].value) except: raise ModelError( "Unable to resolve simulation writer parameters in component '{0}'", fc.id) fc.simulation.add(dw2)
def __init__(self, id, context, component_type, extends = None): """ Constructor @param id: Id/name for this component. @type id: string @param context: The context in which to create this component. @type context: lems.model.context.Context @param component_type: Type of component. @type component_type: string @param extends: Component extended by this one. @param extends: string @note: Atleast one of component_type or extends must be valid. """ Contextual.__init__(self, id, context, Context.COMPONENT) self.id = id """ Globally unique name for this component. @type: string """ self.component_type = component_type """ Type of component. @type: string """ if component_type == None and extends == None: raise ModelError('Component definition requires a component type ' + 'or a base component') self.extends = extends """ Name of component extended by this component..
def fix_parameter(self, parameter_name, value_string, model): """ Fixes the value of a parameter to the specified value. @param parameter_name: Name of the parameter to be fixed. @type parameter_name: string @param value_string: Value to which the parameter needs to be fixed to. For example, "30mV" or "45 kg" @type string @param model: Model object storing the current model. (Needed to find the dimension for the specified symbol) @type model: lems.model.model.Model @attention: Having to pass the model in as a parameter is a temporary hack. This should fixed at some point of time, once PyLEMS is able to run a few example files. @raise ModelError: Raised when the parameter does not exist in this component type. """ parameter = self.lookup_parameter(parameter_name) if parameter == None: raise ModelError('Parameter ' + value_string + ' not present in ' + self.name) parameter.fix_value(value_string, model)
def add_regime(self, name, initial=False): """ Adds a behavior regime to the list of regimes in this behavior profile. @param name: Name of the behavior regime. @type name: string @param initial: Is this the initial regime? Default: False @type initial: Boolean """ if name in self.regimes: raise ModelError('Duplicate regime ' + name) if initial: for rn in self.regimes: if self.regimes[rn].initial: raise ('Cannot define two initial regimes in the same' + ' behavior profile') regime = Regime(name, initial) if initial: self.current_regime = regime self.regimes[name] = regime
def add(self, child): """ Adds a typed child object to the component type. @param child: Child object to be added. """ if isinstance(child, Parameter): self.add_parameter(child) elif isinstance(child, DerivedParameter): self.add_derived_parameter(child) elif isinstance(child, Constant): self.add_constant(child) elif isinstance(child, Exposure): self.add_exposure(child) elif isinstance(child, Requirement): self.add_requirement(child) elif isinstance(child, Children): self.add_children(child) elif isinstance(child, Text): self.add_text(child) elif isinstance(child, Link): self.add_link(child) elif isinstance(child, Path): self.add_path(child) elif isinstance(child, EventPort): self.add_event_port(child) elif isinstance(child, ComponentReference): self.add_component_reference(child) elif isinstance(child, Attachments): self.add_attachments(child) else: raise ModelError('Unsupported child element')
def add_derived_variable(self, name, exposure, dimension, value, select, reduce): """ Adds a derived variable to the behavior current object. @param name: Name of the derived variable. @type name: string @param exposure: Exposed name of the derived variable. @type exposure: string @param dimension: Dimension ofthe derived variable. @type dimension: string @param value: Value expression for the derived variable. @type value: string @param select: Target component selection for reduction operations. @type select: string @param reduce: Reduce operation. @type reduce: string @raise ModelError: Raised when the derived variable is already defined in this behavior regime. """ if name in self.derived_variables: raise ModelError("Duplicate derived variable '{0}'".format(name)) if value == None and select == None and reduce == None: raise ModelError("Derived variable '{0}' must specify either a " "value expression or a reduce " "operation".format(name)) if value != None and (select != None or reduce != None): raise ModelError("Derived variable '{0}' cannot specify both " "value expressions or select/reduce " "operations".format(name)) if select == None and reduce != None: raise ModelError("Reduce target not specified for derived " "variable '{0}'".format(name)) self.derived_variables[name] = DerivedVariable(name, exposure, dimension, value, select, reduce)
def add(self, child): """ Adds a typed child object to the component. @param child: Child object to be added. """ if isinstance(child, Component): self.add_child(child) else: raise ModelError('Unsupported child element')
def add(self, child): """ Adds a typed child object to the event handler. @param child: Child object to be added. """ if isinstance(child, Action): self.add_action(child) else: raise ModelError('Unsupported child element')
def add(self, child): """ Adds a typed child object to the structure object. @param child: Child object to be added. """ if isinstance(child, Assign): self.add_assign(child) else: raise ModelError('Unsupported child element')
def add(self, child): """ Adds a typed child object to the conditional derived variable. @param child: Child object to be added. """ if isinstance(child, Case): self.add_case(child) else: raise ModelError('Unsupported child element')
def resolve_component_structure_from_type(self, comp_context, type_context, component): """ Resolves the specified component's structure from component type. @param comp_context: Component's context object. @type comp_context: lems.model.context.Context @param type_context: Component type's context object. @type type_context: lems.model.context.Context @param component: Component to be resolved. @type component: lems.model.component.Component @raise ModelError: Raised when the component type cannot be resolved. """ comp_str = comp_context.structure type_str = type_context.structure comp_str.event_connections = type_str.event_connections for c in type_str.single_child_defs: raise ModelError('TODO') for c in type_str.multi_child_defs: n = type_str.multi_child_defs[c] if c in comp_context.component_refs: component = comp_context.component_refs[c] if n in comp_context.parameters: number = int(comp_context.parameters[n].numeric_value) comp_str.add_multi_child_def(component, number) else: raise ModelError("Trying to multi-instantiate using an " "invalid number parameter '{0}'".\ format(n)) else: raise ModelError("Trying to multi-instantiate from an " "invalid component reference '{0}'".format(\ c))
def add_exposure(self, name): """ Adds a state variable exposure to the current context. @param name: Name of the state variable being exposed. @type name: string @raise ModelError: Raised when the exposure name already exists in the current context. @raise ModelError: Raised when the exposure name is not being defined in the context of a component type. """ if self.context_type != Context.COMPONENT_TYPE: raise ModelError("Exposure names can only be defined in " "a component type - '{0}'".format(name)) if name in self.exposures: raise ModelError("Duplicate exposure name '{0}'".format(name)) self.exposures += [name]
def add_multi_child_def(self, component, number): """ Adds a single-child instantiation definition to this component type. @param component: Name of component reference used as template for instantiating the child. @type component: string @param number: Number of objects to be instantiated. @type number: string """ if component in self.single_child_defs: raise ModelError("Duplicate child multiinstantiation = " "'{0}'".format(component)) if self.multi_child_defs != {}: raise ModelError("Only one multi-instantiation is permitted " "per component type - '{0}'".format(component)) self.multi_child_defs[component] = number
def add_behavior_profile(self, name): """ Adds a behavior profile to the current context. @param name: Name of the behavior profile. @type name: string """ if name in self.behavior_profiles: raise ModelError("Duplicate behavior profile '{0}'".format(name)) self.behavior_profiles[name] = Behavior(name) self.select_behavior_profile(name)
def add_path_var(self, name, value=None): """ Adds a path variable to the current context. @param name: Name of the path variable. @type name: string @param value: Value of the path variable. @type value: string @raise ModelError: Raised when the path variable already exists in the current context. """ if self.context_type != Context.COMPONENT_TYPE: raise ModelError("Path variables can only be defined in " "a component type - '{0}'".format(name)) if name in self.paths: raise ModelError("Duplicate path variable '{0}'".format(name)) self.paths[name] = value
def add_link_var(self, name, type=None): """ Adds a link variable to the current context. @param name: Name of the link variable. @type name: string @param type: Type of the link variable. @type type: string @raise ModelError: Raised when the link variable already exists in the current context. """ if self.context_type != Context.COMPONENT_TYPE: raise ModelError("Link variables can only be defined in " "a component type - '{0}'".format(name)) if name in self.links: raise ModelError("Duplicate link variable '{0}'".format(name)) self.links[name] = type
def add_single_child_def(self, component): """ Adds a single-child instantiation definition to this component type. @param component: Name of component reference used as template for instantiating the child. @type component: string """ if component in self.single_child_defs: raise ModelError("Duplicate child instantiation = '{0}'".format(\ component)) self.single_child_defs.append(component)
def raise_error(self, message, context): s = 'Caught ModelError in lems' context_name_stack = [] while context != None: context_name_stack.insert(0, context.name) context = context.parent for context_name in context_name_stack: s += '.' + context_name s += ':\n ' + message raise ModelError(s)
def set_value(self, value): """ Sets the value of this parameter. @param value: Value for this parameter. For example, "30mV" or "45 kg" @type value: string @raise ModelError: Raised ModelError if the parameter is already fixed. """ if self.fixed: raise ModelError('Parameter already fixed.') self.value = value
def select_behavior_profile(self, name): """ Selects a behavior profile by name. @param name: Name of the behavior profile. @type name: string @raise ModelError: Raised when the specified behavior profile is undefined in the current context. """ if name not in self.behavior_profiles: raise ModelError("Unknown behavior profile '{0}'".format(name)) self.selected_behavior_profile = self.behavior_profiles[name]
def add_show(self, src, scale): """ Adds a record objects to the list of record objects in this behavior regime. @param src: Path to the element(s) that defines what should be shown @type src: string @param scale: Scale of the quantity to be recorded @type scale: string """ if src in self.shows: raise ModelError('Duplicate show {0}'.format(quantity)) self.shows[src] = Record(src, scale)
def add_component(self, component): """ Adds a component to the list of defined components in the current context. @param component: Component to be added @type component: lems.model.component.ComponentType @raise ModelError: Raised when the component is already defined in the current context. """ if component.id in self.components: raise ModelError("Duplicate component '{0}'".format(component.id)) self.components[component.id] = component
def add_component_type(self, component_type): """ Adds a component type to the list of defined component types in the current context. @param component_type: Component type to be added @type component_type: lems.model.component.ComponentType @raise ModelError: Raised when the component type is already defined in the current context. """ if component_type.name in self.component_types: raise ModelError("Duplicate component type '{0}'".format(\ component_type.name)) self.component_types[component_type.name] = component_type
def add(self, child): """ Adds a typed child object to the simulation spec. @param child: Child object to be added. """ if isinstance(child, Run): self.add_run(child) elif isinstance(child, Record): self.add_record(child) elif isinstance(child, DataDisplay): self.add_data_display(child) elif isinstance(child, DataWriter): self.add_data_writer(child) else: raise ModelError('Unsupported child element')
def add_parameter(self, parameter): """ Adds a parameter to the list of defined parameters in the current context. @param parameter: Parameter to be added @type parameter: lems.model.parameter.ParameterType @raise ModelError: Raised when the parameter is already defined in the current context. """ if parameter.name in self.parameters: raise ModelError("Duplicate parameter type '{0}'".format(\ parameter.name)) self.parameters[parameter.name] = parameter
def __init__(self, name, dimension, fixed=False, value=None, numeric_value=None): """ Constructor @param name: Name of this parameter. @type name: string @param dimension: Dimension of this parameter. @type dimension: string @param fixed: Is this parameter fixed? @type fixed: Boolean @param value: Value of this parameter. @type value: string """ self.name = name """ Parameter name. @type: string """ self.dimension = dimension """ Dimension for this parameter. @type: string """ self.fixed = fixed """ Set to True if this parameter has a fixed value. @type: Boolean """ if fixed and value == None: raise ModelError('A numeric value must be provided to fix' + 'this parameter') self.value = value """ Value for this parameter. @type: string """ self.numeric_value = numeric_value """ Numeric value of this parameter in terms of standard units.
def add_child(self, child): """ Adds a child object to the list of child objects in the current context. @param child: Child object. @type child: lems.model.component.Component @raise ModelError: Raised when a child is instantiated inside a component type. """ if self.context_type == Context.COMPONENT_TYPE: raise ModelError("Child definition '{0}' not permitted in " "component type definition '{1}'".format(\ child.id, self.name)) self.children.append(child)
def add_time_derivative(self, variable, value): """ Adds a state variable to the behavior current object. @param variable: Name of the state variable whose time derivative is being specified. @type variable: string @param value: Time derivative expression. @type value: string @raise ModelError: Raised when the time derivative for this state variable is already defined in this behavior regime. """ if variable in self.time_derivatives: raise ModelError('Duplicate time derivative for ' + variable) self.time_derivatives[variable] = TimeDerivative(variable, value)
def add(self, child): """ Adds a typed child object to the structure object. @param child: Child object to be added. """ if isinstance(child, With): self.add_with(child) elif isinstance(child, EventConnection): self.add_event_connection(child) elif isinstance(child, ChildInstance): self.add_child_instance(child) elif isinstance(child, MultiInstantiate): self.add_multi_instantiate(child) elif isinstance(child, ForEach): self.add_for_each(child) else: raise ModelError('Unsupported child element')
def add_child_def(self, name, type): """ Adds a child object definition to the list of single-instance child object definitions in the current context. @param name: Name of the child object. @type name: string @param type: Type of the child object. @type type: string @raise ModelError: Raised when the definition is already in the current context. """ if name in self.child_defs: raise ModelError("Duplicate child definition '{0}'".format(name)) self.child_defs[name] = type