From fc4e504549a62f5b66d450b4570e03e38c937459 Mon Sep 17 00:00:00 2001 From: Padraig Gleeson Date: Thu, 19 Nov 2015 13:51:25 +0000 Subject: [PATCH] Adding support for reading & writing elements. Throws error is model with Property is simulated. See https://github.com/LEMS/pylems/issues/16 --- lems/__init__.py | 2 +- lems/model/component.py | 55 +++++++++++++++++++++++++++++++++++++++++ lems/model/model.py | 7 ++++++ lems/parser/LEMS.py | 33 +++++++++++++++++++++++++ lems/sim/build.py | 4 +++ testpy2.sh | 2 +- 6 files changed, 101 insertions(+), 2 deletions(-) diff --git a/lems/__init__.py b/lems/__init__.py index 9cfdafb..15cacee 100644 --- a/lems/__init__.py +++ b/lems/__init__.py @@ -8,4 +8,4 @@ logger = logging.getLogger('LEMS') -__version__ = '0.4.4' +__version__ = '0.4.5' diff --git a/lems/model/component.py b/lems/model/component.py index ae5cc7d..65873bb 100644 --- a/lems/model/component.py +++ b/lems/model/component.py @@ -96,6 +96,41 @@ def toxml(self): """ return '' + + + +class Property(LEMSBase): + """ + Store the specification of a property. + """ + + def __init__(self, name, dimension = None, description = ''): + """ + Constructor. + """ + + self.name = name + """ Name of the property. + @type: str """ + + self.dimension = dimension + """ Physical dimensions of the property. + @type: str """ + + self.description = description + """ Description of the property. + @type: str """ + + + def toxml(self): + """ + Exports this object into a LEMS XML object + """ + + return '' + class IndexParameter(LEMSBase): """ @@ -615,6 +650,10 @@ def __init__(self): """ Map of parameters in this component type. @type: Map(str -> lems.model.component.Parameter) """ + self.properties = Map() + """ Map of properties in this component type. + @type: Map(str -> lems.model.component.Property) """ + self.derived_parameters = Map() """ Map of derived_parameters in this component type. @type: Map(str -> lems.model.component.Parameter) """ @@ -697,6 +736,17 @@ def add_parameter(self, parameter): self.parameters[parameter.name] = parameter + + def add_property(self, property): + """ + Adds a property to this component type. + + @param property: Property to be added. + @type property: lems.model.component.Property + """ + + self.properties[property.name] = property + def add_derived_parameter(self, derived_parameter): """ Adds a derived_parameter to this component type. @@ -853,6 +903,8 @@ def add(self, child): if isinstance(child, Parameter): self.add_parameter(child) + elif isinstance(child, Property): + self.add_property(child) elif isinstance(child, DerivedParameter): self.add_derived_parameter(child) elif isinstance(child, IndexParameter): @@ -926,6 +978,9 @@ def toxml(self): chxmlstr = '' + for property in self.properties: + chxmlstr += property.toxml() + for parameter in self.parameters: chxmlstr += parameter.toxml() diff --git a/lems/model/model.py b/lems/model/model.py index e7366d0..5c68a8a 100644 --- a/lems/model/model.py +++ b/lems/model/model.py @@ -346,6 +346,8 @@ def merge_component_types(self, ct, base_ct): else: ct.parameters[parameter.name] = base_ct.parameters[parameter.name] + merge_maps(ct.properties, base_ct.properties) + merge_maps(ct.derived_parameters, base_ct.derived_parameters) merge_maps(ct.index_parameters, base_ct.index_parameters) merge_maps(ct.constants, base_ct.constants) @@ -415,6 +417,11 @@ def fatten_component(self, c): raise ModelError("Parameter '{0}' not initialized for component '{1}'", parameter.name, c.id) + ### Resolve properties + for property in ct.properties: + property2 = property.copy() + fc.add(property2) + ### Resolve derived_parameters for derived_parameter in ct.derived_parameters: derived_parameter2 = derived_parameter.copy() diff --git a/lems/parser/LEMS.py b/lems/parser/LEMS.py index 1403d5a..3860ab2 100644 --- a/lems/parser/LEMS.py +++ b/lems/parser/LEMS.py @@ -116,6 +116,7 @@ def init_parser(self): 'componentreference', 'exposure', 'eventport', 'fixed', 'link', 'parameter', + 'property', 'indexparameter', 'path', 'requirement', 'componentrequirement', @@ -187,6 +188,7 @@ def init_parser(self): self.tag_parse_table['onevent'] = self.parse_on_event self.tag_parse_table['onstart'] = self.parse_on_start self.tag_parse_table['parameter'] = self.parse_parameter + self.tag_parse_table['property'] = self.parse_property self.tag_parse_table['path'] = self.parse_path self.tag_parse_table['record'] = self.parse_record self.tag_parse_table['regime'] = self.parse_regime @@ -1181,6 +1183,37 @@ def parse_parameter(self, node): parameter = Parameter(name, dimension) self.current_component_type.add_parameter(parameter) + + def parse_property(self, node): + """ + Parses + + @param node: Node containing the element + @type node: xml.etree.Element + + @raise ParseError: Raised when the property does not have a name. + @raise ParseError: Raised when the property does not have a + dimension. + """ + + if self.current_component_type == None: + self.raise_error('Property can only be defined in ' + + 'a component type') + + try: + name = node.lattrib['name'] + except: + self.raise_error(' must specify a name') + + try: + dimension = node.lattrib['dimension'] + except: + self.raise_error("Property '{0}' has no dimension", + name) + + property = Property(name, dimension) + + self.current_component_type.add_property(property) def parse_index_parameter(self, node): diff --git a/lems/sim/build.py b/lems/sim/build.py index a8c24c9..6d0c8fe 100644 --- a/lems/sim/build.py +++ b/lems/sim/build.py @@ -106,6 +106,10 @@ def build_runnable(self, component, parent = None, id_ = None): for parameter in component.parameters: runnable.add_instance_variable(parameter.name, parameter.numeric_value) + + + for property in component.properties: + raise NotImplementedError("Property element is not stable in PyLEMS yet, see https://github.com/LEMS/pylems/issues/16") derived_parameter_code = [] diff --git a/testpy2.sh b/testpy2.sh index e45f4e4..c538528 100755 --- a/testpy2.sh +++ b/testpy2.sh @@ -5,4 +5,4 @@ python2.7 examples/apitest.py python2.7 examples/apitest2.py python2.7 examples/loadtest.py python2.7 lems/dlems/exportdlems.py -python2.7 pylems -I ../NeuroML2/NeuroML2CoreTypes ../NeuroML2/LEMSexamples/LEMS_NML2_Ex2_Izh.xml +python2.7 pylems -I ../NeuroML2/NeuroML2CoreTypes ../NeuroML2/LEMSexamples/LEMS_NML2_Ex5_DetCell.xml