""" Read xml representation of a model composite
"""
from __future__ import absolute_import
from __future__ import print_function
from path import Path
import xml.etree.ElementTree as xml
import six
from pycropml.modelunit import ModelUnit
from . import parameterset as pset
from pycropml import pparse
import os
from . import initialization
[docs]
class ModelDefinition(object):
"""
Model name, id, version and step
"""
def __init__(self, kwds):
self._attributes = kwds
for k, v in six.iteritems(kwds):
self.__setattr__(k,v)
def __repr__(self):
return str(self._attributes)
[docs]
class ModelComposition(ModelDefinition):
""" Formal description of a Model Composite. """
def __init__(self, kwds):
ModelDefinition.__init__(self, kwds)
self.description = None
self.model = []
self.initialization = []
self.inputlink=[]
self.outputlink=[]
self.internallink=[]
self.parametersets = {}
self.inputs=[]
self.outputs=[]
self.path = None
self.aPath=None
self.states=[]
[docs]
def add_description(self, description):
""" TODO """
self.description = description
def __repr__(self):
return 'ModelComposition'
[docs]
class Description(object):
""" Model Composition Description.
A description is defined by:
- Title
- Authors
- Institution
- Reference
- Abstract
"""
def __init__(self):
self.Title = ''
self.Authors= ''
self.Institution = ''
self.Reference = ''
self.Abstract = ''
[docs]
class Models(ModelComposition, ModelUnit):
def __init__(self, name, modelid, file, package_name=None):
self.name=name
self.modelid=modelid
self.file=file
self.package_name = package_name
self.inputs = None
self.outputs = None
self.description = None
self.parametersets = None
self.testsets = None
self.function = []
self.initialization = None
[docs]
class Parser(object):
""" Read an XML file and transform it in our object model.
"""
[docs]
def parse(self, fn):
raise Exception('Not Implemented')
[docs]
def dispatch(self, elt):
return self.__getattribute__(elt.tag)(elt)
[docs]
class ModelParser(Parser):
"""Read an XML file and transform it in our object model."""
[docs]
def parse(self, fn):
self.modelcompos = []
self.aPath = os.path.abspath(fn)
self.path_mc = retrieve_path(fn)
# Current proxy node for managing properties
doc = xml.parse(fn)
root = doc.getroot()
self.dispatch(root)
return self.modelcompos
[docs]
def dispatch(self, elt):
#try:
return self.__getattribute__(elt.tag)(elt)
[docs]
def ModelComposition(self, elts):
""" ModelComposition (Description, Models, Inputlink,Outputlink,externallink)
"""
kwds = elts.attrib
self._modelcompo = ModelComposition(kwds)
self._modelcompo.path = self.path_mc
self._modelcompo.aPath = self.aPath
self.modelcompos.append(self._modelcompo)
for elt in list(elts):
self.dispatch(elt)
[docs]
def Description(self, elts):
""" Description (Title,Authors,Institution,Reference,Abstract)
"""
desc = Description()
for elt in list(elts):
self.name = desc.__setattr__(elt.tag, elt.text)
self._modelcompo.add_description(desc)
[docs]
def Initialization(self, elt):
language=elt.attrib["language"]
name=elt.attrib["name"]
filename=elt.attrib["filename"]
#description =elt.attrib["description"]
code = initialization.Initialization(name,language, filename)
self._modelcompo.initialization.append(code)
[docs]
def Parametersets(self, elts):
""" Parametersets (Parameterset)
"""
#print('Parametersets')
for elt in list(elts):
self.Parameterset(elt)
[docs]
def Parameterset(self, elts):
""" Parameterset
"""
#print('Parameterset: ')
properties = elts.attrib
name = properties.pop('name')
_parameterset = pset.parameterset(self._modelcompo, name, properties)
for elt in list(elts):
self.param(_parameterset, elt)
name = _parameterset.name
self._modelcompo.parametersets[name] = _parameterset
[docs]
def param(self, pset, elt):
""" Param
"""
#print('Param: ', elt.attrib, elt.text)
properties = elt.attrib
name = properties['name']
pset.params[name] = elt.text
[docs]
def Composition(self, elts):
for elt in list(elts):
self.dispatch(elt)
[docs]
def Model(self, elt):
""" Models
"""
name=elt.attrib["name"]
modelid=elt.attrib["id"]
file = elt.attrib["filename"]
if "package_name" in elt.attrib:
package_name=elt.attrib["package_name"]
else: package_name=None
mod = Models(name, modelid, file, package_name)
self._modelcompo.model.append(mod)
[docs]
def Links(self, elt):
"""
Retrieve different types of links
"""
inputs = elt.findall("InputLink")
outputs = elt.findall("OutputLink")
internals = elt.findall("InternalLink")
for input in inputs:
inp = input.attrib
self._modelcompo.inputlink.append(inp)
if inp["source"] not in self._modelcompo.inputs:
self._modelcompo.inputs.append(inp["source"])
for output in outputs:
out = output.attrib
self._modelcompo.outputlink.append(out)
if out["target"] not in self._modelcompo.outputs:
self._modelcompo.outputs.append(out["target"])
for internal in internals :
inter = internal.attrib
self._modelcompo.internallink.append(inter)
[docs]
def model_parser(fn):
"""
Parse a composite model and return the model.
Returns ModelComposite object of the CropML Model.
"""
parser = ModelParser()
return parser.parse(fn)
[docs]
def retrieve_path(fn):
path_ = Path.splitpath(Path(fn))[0]
return os.path.dirname(path_)