def build_python(xmile_file): """ Load the xml file and pass the relevant elements to the builder class """ smile_parser = SMILEParser() xml_parser = etree.XMLParser(encoding="utf-8", recover=True) root = etree.parse(xmile_file, parser=xml_parser).getroot() NS = root.nsmap.values()[0] filename = '.'.join(xmile_file.split('.')[:-1]) + '.py' builder.new_model(filename) # add aux and flow nodes flaux_xpath = '//ns:model/ns:variables/ns:aux|//ns:model/ns:variables/ns:flow' for element in root.xpath(flaux_xpath, namespaces={'ns': NS}): identifier = smile_parser.parse(element.attrib['name'], context='defn') pyeqn = smile_parser.parse( element.xpath('ns:eqn', namespaces={'ns': NS})[0].text) builder.add_flaux(filename, identifier, pyeqn) # add nodes for the derivatives of stocks stock_xpath = '//ns:model/ns:variables/ns:stock' for element in root.xpath(stock_xpath, namespaces={'ns': NS}): identifier = smile_parser.parse(element.attrib['name'], context='defn') inflows = [ smile_parser.parse(e.text) for e in element.xpath('ns:inflow', namespaces={'ns': NS}) ] outflows = [ smile_parser.parse(e.text) for e in element.xpath('ns:outflow', namespaces={'ns': NS}) ] pyeqn = ' + '.join(inflows) if inflows else '' pyeqn += ' - ' + ' - '.join(outflows) if outflows else '' initial_value = smile_parser.parse( element.xpath('ns:eqn', namespaces={'ns': NS})[0].text) builder.add_stock(filename, identifier, pyeqn, initial_value) #Get timeseries information from the XMILE file tstart = smile_parser.parse( root.xpath('//ns:sim_specs/ns:start', namespaces={'ns': NS})[0].text) builder.add_flaux(filename, 'initial_time', tstart) tstop = smile_parser.parse( root.xpath('//ns:sim_specs/ns:stop', namespaces={'ns': NS})[0].text) builder.add_flaux(filename, 'final_time', tstop) dt = smile_parser.parse( root.xpath('//ns:sim_specs/ns:dt', namespaces={'ns': NS})[0].text) builder.add_flaux(filename, 'time_step', dt) return filename
def build_python(xmile_file): """ Load the xml file and pass the relevant elements to the builder class """ smile_parser = SMILEParser() xml_parser = etree.XMLParser(encoding="utf-8", recover=True) root = etree.parse(xmile_file, parser=xml_parser).getroot() NS = root.nsmap.values()[0] filename = '.'.join(xmile_file.split('.')[:-1])+'.py' builder.new_model(filename) # add aux and flow nodes flaux_xpath = '//ns:model/ns:variables/ns:aux|//ns:model/ns:variables/ns:flow' for element in root.xpath(flaux_xpath, namespaces={'ns':NS}): identifier = smile_parser.parse(element.attrib['name'], context='defn') pyeqn = smile_parser.parse(element.xpath('ns:eqn', namespaces={'ns':NS})[0].text) builder.add_flaux(filename, identifier, pyeqn) # add nodes for the derivatives of stocks stock_xpath = '//ns:model/ns:variables/ns:stock' for element in root.xpath(stock_xpath,namespaces={'ns':NS}): identifier = smile_parser.parse(element.attrib['name'], context='defn') inflows = [smile_parser.parse(e.text) for e in element.xpath('ns:inflow', namespaces={'ns':NS})] outflows = [smile_parser.parse(e.text) for e in element.xpath('ns:outflow', namespaces={'ns':NS})] pyeqn = ' + '.join(inflows) if inflows else '' pyeqn += ' - '+' - '.join(outflows) if outflows else '' initial_value = smile_parser.parse(element.xpath('ns:eqn', namespaces={'ns':NS})[0].text) builder.add_stock(filename, identifier, pyeqn, initial_value) #Get timeseries information from the XMILE file tstart = smile_parser.parse(root.xpath('//ns:sim_specs/ns:start',namespaces={'ns':NS})[0].text) builder.add_flaux(filename, 'initial_time', tstart) tstop = smile_parser.parse(root.xpath('//ns:sim_specs/ns:stop',namespaces={'ns':NS})[0].text) builder.add_flaux(filename, 'final_time', tstop) dt = smile_parser.parse(root.xpath('//ns:sim_specs/ns:dt',namespaces={'ns':NS})[0].text) builder.add_flaux(filename, 'time_step', dt) return filename
def visit_ModelEntry(self, n, (_1, Identifier, _2, tld1, _3, Unit, _4, tld2, _5, Docstring, _6, pipe, _7)): """All we have to do here is add to the docstring of the relevant function the things that arent available at lower levels. The stock/flaux/lookup visitors will take care of adding methods to the class """ #string = 'Units: %s \n'%Unit + Docstring #builder.add_to_element_docstring(self.component_class, Identifier, string) pass def visit_Stock(self, n, (Identifier, _1, eq, _2, integ, _3, lparen, _4, NL1, _5, expression, _6, comma, _7, NL2, _8, initial_condition, _9, rparen)): builder.add_stock(self.filename, Identifier, expression, initial_condition) return Identifier def visit_Flaux(self, n, (Identifier, _1, eq, SNL, expression)): builder.add_flaux(self.filename, Identifier, expression) return Identifier def visit_Lookup(self, n, (Identifier, _1, lparen, _2, NL1, _3, Range, _4, CopairList, _5, rparen)): builder.add_lookup(self.filename, Identifier, Range, CopairList) return Identifier def visit_Unit(self, n, vc): return n.text.strip()
visit_Entry = visit_Component = NodeVisitor.lift_child def visit_ModelEntry(self, n, (_1, Identifier, _2, tld1, _3, Unit, _4, tld2, _5, Docstring, _6, pipe, _7)): """All we have to do here is add to the docstring of the relevant function the things that arent available at lower levels. The stock/flaux/lookup visitors will take care of adding methods to the class """ #string = 'Units: %s \n'%Unit + Docstring #builder.add_to_element_docstring(self.component_class, Identifier, string) pass def visit_Stock(self, n, (Identifier, _1, eq, _2, integ, _3, lparen, _4, NL1, _5, expression, _6, comma, _7, NL2, _8, initial_condition, _9, rparen)): builder.add_stock(self.filename, Identifier, expression, initial_condition) return Identifier def visit_Flaux(self, n, (Identifier, _1, eq, SNL, expression)): builder.add_flaux(self.filename, Identifier, expression) return Identifier def visit_Lookup(self, n, (Identifier, _1, lparen, _2, NL1, _3, Range, _4, CopairList, _5, rparen)): builder.add_lookup(self.filename, Identifier, Range, CopairList) return Identifier def visit_Unit(self, n, vc): return n.text.strip() visit_Docstring = visit_Unit