Skip to content

Merge pull request #32 from AgriculturalModelExchangeInitiative/master #253

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/pycropml/transpiler/antlr_py/csharp/csharpTransformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1175,7 +1175,7 @@ def visit_class_type(self, node,namespace_or_type_name, OBJECT, DYNAMIC, STRING,
typ = x[0] if isinstance(x, list) else x
return {"type":typ, "pseudo_type":x}
if OBJECT:
return self.visit(OBJECT)
return {"type":"object", "pseudo_type":"object"}
if DYNAMIC:
return self.visit(DYNAMIC)
if STRING:
Expand Down Expand Up @@ -1225,7 +1225,7 @@ def visit_local_constant_declaration(self, node, CONST, type_, constant_declarat
typ = self.visit(type_)
decls = self.visit(constant_declarators)
for d in decls:
d["type"] = typ
d["type"] = typ["pseudo_type"]
res["decl"].append(d)
return res

Expand Down
4 changes: 3 additions & 1 deletion src/pycropml/transpiler/antlr_py/simplace/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ def run_simplace(components, output):
if not isdir(cyml_rep):
cyml_rep.mkdir()
models = []
p = SimplaceExtraction()
auxiliary = p.getAuxiliary(compositeStrat)
for strat in simpleStrat:
print(strat)
with open(strat, "r") as f:
Expand All @@ -96,7 +98,7 @@ def run_simplace(components, output):
strAsg = to_CASG(dictasgt)

mm = SimplaceExtraction()
mm.modelunit(strAsg)
mm.modelunit(strAsg, auxiliary)
mm.model.description

names = [ j.name for j in mm.model.inputs + mm.model.outputs]
Expand Down
28 changes: 26 additions & 2 deletions src/pycropml/transpiler/antlr_py/simplace/simplaceExtraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def getOutputs(self, tree):
outs = list(map(lambda out: out.instance.name, setouts))
return outs

def modelunit(self, tree):
def modelunit(self, tree, auxiliary):
desc = self.description(tree)
self.model= ModelUnit({"name":desc["name"], "version":"001", "timestep":"1"})
description = self.model_desc(desc)
Expand Down Expand Up @@ -149,6 +149,9 @@ def modelunit(self, tree):
elif att == "rate": category = "rate"
elif att == "state": category = "state"
else: category = att.lower()

if auxiliary[self.model.name] and name in auxiliary[self.model.name]:
category = "auxiliary"

if name in ins and name in outnames: category = "state"

Expand Down Expand Up @@ -271,7 +274,28 @@ def modelcomposition(self, xfile, models):
return self.mc



def getAuxiliary(self, xfile):
doc = xml.parse(xfile)
root = doc.getroot()
compositeid = root.attrib["class"]
name = compositeid.split(".")[-1]
print("composite name", name)
mods = []
res = {}
for el in list(root):
for l in list(el):
if l.tag=="simcomponent":
mu_name = l.attrib["id"]
mods.append(mu_name)
res[mu_name]=[]
for j in list(l):
attr = j.attrib
if j.tag == "input" and "source" in attr:
id = attr["id"]
mod = attr["source"].split(".")[0]
if mod != name:
res[mu_name].append(id)
return res



Expand Down
181 changes: 168 additions & 13 deletions src/pycropml/transpiler/generators/rGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from path import Path
from pycropml.transpiler.Parser import parser
from pycropml.transpiler.ast_transform import AstTransformer, transform_to_syntax_tree
from pycropml.nameconvention import signature2, signature2_from_name

class RGenerator(CodeGenerator, RRules):
"""This class contains the specific properties of
Expand Down Expand Up @@ -239,6 +240,70 @@ def visit_function_definition(self, node):
self.newline(extra=1)
self.newline(node)
self.funcname = node.name
if node.name.startswith("init_"):
self.write(f"#' @Title Initialization of the {self.model.description.Title}")
self.newline(1)
for arg in node.params:
for inp in self.model.inputs:
if arg.name == inp.name:
self.write(f"#' @param {inp.name} ({inp.unit}) {inp.description} {inp.parametercategory if 'parametercategory' in dir(inp) else inp.variablecategory} ({inp.default}, {inp.min}-{inp.max}) ")
self.newline(1)
self.write(f"#'")
self.newline(1)
self.write(f"#' @return")
self.newline(1)
for out in self.model.outputs:
if out.variablecategory=="state":
self.write(f"#' \item {out.name} ({out.unit}) {out.description} {out.variablecategory} ({out.min}-{inp.max}) ")
self.newline(1)
self.newline(1)
self.write(f"#'")
self.newline(1)
self.write(f"#' @export")
self.newline(1)

if self.model and node.name.startswith("model_") and node.name.split("model_")[1]==signature(self.model):
print(dir(self.model.description))
self.write(f"#' @Title {self.model.description.Title}")
self.newline(1)
self.write(f"#' @Description {self.model.description.ExtendedDescription}")
self.newline(1)
self.write(f"#' @Authors {self.model.description.Authors} ")
self.newline(1)
self.write(f"#' @Institutions {self.model.description.Institution}")
self.newline(1)
self.write(f"#' @Reference {self.model.description.Reference}")
self.newline(1)
self.write(f"#' @Version {self.model.version}")
self.newline(1)
self.write(f"#'")
self.newline(1)
for inp in self.model.inputs:
self.write(f"#' @param {inp.name} ({inp.unit}) {inp.description} {inp.parametercategory if 'parametercategory' in dir(inp) else inp.variablecategory} ({inp.default}, {inp.min}-{inp.max}) ")
self.newline(1)
self.write(f"#'")
self.newline(1)
self.write(f"#' @return")
self.newline(1)
for out in self.model.outputs:
self.write(f"#' \item {out.name} ({out.unit}) {out.description} {out.variablecategory} ({out.min}-{inp.max}) ")
self.newline(1)
self.write(f"#'")
self.newline(1)
self.write(f"#' @export")
self.newline(1)



"""self.write(self.doc.header)
self.newline(node)
self.write(self.doc.desc)
self.newline(node)
self.write(self.doc.inputs_doc)
self.newline(node)
self.write(self.doc.outputs_doc)
self.newline(node)
self.model = None"""
self.write('%s <- function (' % node.name)
for i, pa in enumerate(node.params):
self.write(pa.name)
Expand All @@ -249,16 +314,6 @@ def visit_function_definition(self, node):
self.write(',\n ')
self.write('){')
self.newline(node)
if self.model and node.name.startswith("model_") and node.name.split("model_")[1]==signature(self.model):
self.write(self.doc.header)
self.newline(node)
self.write(self.doc.desc)
self.newline(node)
self.write(self.doc.inputs_doc)
self.newline(node)
self.write(self.doc.outputs_doc)
self.newline(node)
self.model = None
self.body(node.block)
self.newline(node)
self.write("}")
Expand Down Expand Up @@ -432,22 +487,122 @@ class RCompo(RGenerator):
for C# languages.
"""
def __init__(self, tree, model=None, name=None):
RGenerator.__init__(self,tree, model, name)
self.tree = tree
self.model = model
self.name = name
RGenerator.__init__(self,tree, model, self.name)
x = os.path.split(self.model.aPath)[0]
z=x.split('\\')#.pop()
z.pop()
sourcePath = "/".join(z)+"/src/r"
self.write("library (gsubfn) ")
self.newline()
self.write("setwd('%s')"%sourcePath)
self.write("#setwd('%s')"%sourcePath)
self.newline()
for m in self.model.model:
self.write("source('%s.r')"%m.name.lower().capitalize())
self.newline()

if not self.model.initialization:
self.newline(1)
self.write(f"#' @Title Initialization of {signature2_from_name(self.model.name)} component")
self.newline(1)
self.write(f"#' ")
self.newline(1)
self.initcomposition(tree)
self.newline(extra=1)


def visit_module(self, node):
self.newline(extra=1)
self.newline(node)
self.visit(node.body)

def initcomposition(self, node):
print(self.model.name)
name = "init_"+ signature2_from_name(self.model.name)
pas = []
inps = []
z = ""
for i, pa in enumerate(self.model.inputlink):
p_source = pa["source"]
p_target = pa["target"].split(".")[1]
for m in self.model.model:
for inp in m.inputs:
n=None
if p_target == inp.name and ("parametercategory" in dir(inp) or inp.variablecategory == "exogenous") and p_target not in pas:
z = z + p_source + ", "
pas.append(p_target)
n = 1
inps.append(inp)

outs = []
for m in self.model.ord:
for mod in self.model.model:
if m == mod.name and "initialization" in dir(mod) and mod.initialization:
for out in mod.outputs:
if out.variablecategory == "state":
outs.append(out)

for inp in inps:
self.write(f"#' @param {inp.name} ({inp.unit}) {inp.description} {inp.parametercategory if 'parametercategory' in dir(inp) else inp.variablecategory} ({inp.default}, {inp.min}-{inp.max}) ")
self.newline(1)

self.write(f"#'")
self.newline(1)
self.write(f"#' @return")
self.newline(1)
for out in outs:
self.write(f"#' \item {out.name} ({out.unit}) {out.description} {out.variablecategory} ({out.min}-{inp.max}) ")
self.newline(1)

self.write(f"#'")
self.newline(1)
self.write(f"#' @export")
self.newline(1)
self.write(f"{name} <- function(")
z = z[:-2]
self.write(z)

self.write("){")
self.newline(1)
self.indentation += 1
states = []
print([{m.name:m.variablecategory} for m in self.model.inputs if "variablecategory" in dir(m)])
for m in self.model.inputs:
if "variablecategory" in dir(m) and (m.variablecategory == "state" or m.variablecategory == "auxiliary"):
states.append(m.name)
print(states)
for n in self.model.diff_in:
# write assignment such as key = value
if self.model.diff_in[n] not in states:
self.write(f"{n} <- {self.model.diff_in[n]}")
self.newline(1)

for m in self.model.ord:
for mod in self.model.model:
if m == mod.name and "initialization" in dir(mod) and mod.initialization:
self.write(f"i_{signature(mod)} <- init_{signature(mod)}(")
par =[]
for inp in mod.inputs:
if "parametercategory" in dir(inp):
par.append(inp.name)
elif inp.variablecategory == "exogenous":
par.append(inp.name)
for i, pa in enumerate(par):
self.write(pa)
if i!= (len(par)-1):
self.write(', ')
self.write(")")
self.newline(1)

self.newline(1)
self.write("return (list (")
self.multValreturn(outs)
self.write("))")
self.indentation -= 1
self.write("}")


def visit_tuple(self,node):
self.write("list[")
for n in node.elements:
Expand Down
Loading