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