From: lempinen Date: Thu, 1 Sep 2011 09:33:42 +0000 (+0000) Subject: Support both .txt and .xml init file formats X-Git-Tag: simantics-1.5~47 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=52d5e4adbc4dd1f2a0e56c3c3b208cd380a3872b;p=simantics%2Fsysdyn.git Support both .txt and .xml init file formats git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@22020 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.modelica/src/org/simantics/modelica/InitWriter.java b/org.simantics.modelica/src/org/simantics/modelica/InitWriter.java new file mode 100644 index 00000000..6b90a2f9 --- /dev/null +++ b/org.simantics.modelica/src/org/simantics/modelica/InitWriter.java @@ -0,0 +1,182 @@ +package org.simantics.modelica; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.HashMap; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Class to change values of parameters in modelica init.xml files + * @author tlteemu + * + */ +public class InitWriter { + + /** + * Change the given init parameter values for XML init file + * @param file path to the init.xml file + * @param inits name-value map + * @return + */ + public static boolean writeXML(String file, HashMap inits) { + Document doc; + try { + doc = DocumentBuilderFactory.newInstance() + .newDocumentBuilder().parse(new InputSource(file)); + + + // Locate the node(s) + XPath xpath = XPathFactory.newInstance().newXPath(); + + for(String name : inits.keySet()) { + NodeList nodes = null; + try { + // First try normal variables + nodes = (NodeList)xpath.evaluate + ("//fmiModelDescription/ModelVariables/ScalarVariable[@name='" + name + "']/Real/@start", + doc, + XPathConstants.NODESET); + if(nodes.getLength() == 0) { + // If normal variables were not found, try if it is an experiment attribute + nodes = (NodeList)xpath.evaluate + ("//fmiModelDescription/DefaultExperiment/@" + name, + doc, + XPathConstants.NODESET); + } + } catch (XPathExpressionException e) { + + } + if (nodes != null) { + // make the change. There should be only one node. + for (int idx = 0; idx < nodes.getLength(); idx++) { + Node n = nodes.item(idx); + n.setNodeValue(inits.get(name).replaceAll("\"", "")); + } + } + } + + // Save the result + Transformer xformer = TransformerFactory.newInstance().newTransformer(); + xformer.transform + (new DOMSource(doc), new StreamResult(new File(file))); + + return true; + } catch (SAXException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } catch (TransformerConfigurationException e) { + e.printStackTrace(); + } catch (TransformerFactoryConfigurationError e) { + e.printStackTrace(); + } catch (TransformerException e) { + e.printStackTrace(); + } + + return false; + + } + + /** + * Change the given init parameter values for TXT init file + * @param file path to the init.xml file + * @param inits name-value map + * @return + */ + public static boolean writeTXT(String file, HashMap inits) { + HashMap initials = new HashMap(); + HashMap order = new HashMap(); + + InputStream is; + try { + is = new FileInputStream(file); + int orderNumber = 0; + while(true) { + String line = getLine(is); + if(line == null) + return false; + if(line.isEmpty()) + break; + if(line.contains("//")) { + String[] nn = line.split("//", 2); + String key = nn[1].trim(); + String value = nn[0].trim(); + if(inits.containsKey(key)) { + value = inits.get(key); + } + initials.put(key, value); + order.put(orderNumber, key); + } + orderNumber++; + } + is.close(); + + PrintStream s = new PrintStream(file); + for(int j = 0; j < orderNumber ; j++) { + String key = order.get(j); + if (key != null) { + s.println(initials.get(key) + " // " + key); + } else { + s.println("0.0"); + } + } + s.close(); + + return true; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + private static String getLine(InputStream stream) { + if(stream == null) + return null; + StringBuilder b = new StringBuilder(); + try { + while(true) { + int c = stream.read(); + if(c == -1) { + stream = null; + return b.toString(); + } + else if(c == '\n') + return b.toString(); + else if(c == '\r') + ; + else + b.append((char)c); + } + } catch (IOException e) { + return null; + } + + } +} \ No newline at end of file diff --git a/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java b/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java index ee9e4738..e9b448e5 100644 --- a/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java +++ b/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java @@ -14,7 +14,6 @@ package org.simantics.modelica; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; @@ -29,375 +28,349 @@ import org.osgi.framework.Bundle; public class ModelicaManager { - public enum OSType { - APPLE, LINUX, SUN, WINDOWS, UNKNOWN - } - - public static OSType calculateOS() { - String osName = System.getProperty("os.name"); - assert osName != null; - osName = osName.toLowerCase(); - if (osName.startsWith("mac os x")) - return OSType.APPLE; - if (osName.startsWith("windows")) - return OSType.WINDOWS; - if (osName.startsWith("linux")) - return OSType.LINUX; - if (osName.startsWith("sun")) - return OSType.SUN; - return OSType.UNKNOWN; - } - - public static File getModelicaHome() { - - String dir = System.getenv("OPENMODELICAHOME"); - File omhome = null; - - String osName = System.getProperty("os.name"); - OSType os = calculateOS(); - - if (os == OSType.UNKNOWN) - throw new UnsatisfiedLinkError("unknown OS '" + osName + "' for running OpenModelica"); - - // If OPENMODELICAHOME is found, try to return the folder. - if(dir != null) { - switch (os) { - case APPLE: - case LINUX: - case SUN: - omhome = new File(dir); - if(omhome.isDirectory()) - return omhome; - else - break; - case WINDOWS: - omhome = new File(dir); - if(omhome.isDirectory()) - return omhome; - else - break; - } - } - - // OPENMODELICAHOMe was not found or the folder does not exist. Try built-in OpenModelica for windows - if(os.equals(OSType.WINDOWS)) { - - Bundle bundle = Platform.getBundle("org.simantics.openmodelica.win32"); - if (bundle != null) { - try{ - URL entry = bundle.getEntry("/"); - if(entry != null) { - URL fileURL = FileLocator.toFileURL(entry); - File root = new File( URLDecoder.decode(fileURL.getPath(), "UTF-8") ); - File f = new File(root, "OpenModelica1.7.0"); - return f; - } - } - catch (Exception e) { - e.printStackTrace(); - } - } - } - - // OS was not windows or built-in OpenModelica did not work - switch (os) { - case APPLE: - case LINUX: - case SUN: - return new File("/usr/bin/omc"); - case WINDOWS: - return new File("c:/OpenModelica1.7.0"); - default: - throw new UnsatisfiedLinkError("Unsupported operating system: " + os); - } - } - - public static File getModelicaExecutable(File simulationDir) { - - File modelicaHome = getModelicaHome(); - - if(!modelicaHome.isDirectory()) - throw new UnsatisfiedLinkError("OpenModelica probably not installed. Tried to find it from: " + modelicaHome.getAbsolutePath()); - - try { - File omBat = new File(simulationDir, "om.bat"); - FileWriter fw = new FileWriter(omBat); - BufferedWriter out = new BufferedWriter(fw); - out.write("@echo off"); - out.newLine(); - out.write("set OPENMODELICAHOME=" + modelicaHome.getAbsolutePath()); - out.newLine(); - out.write("set OPENMODELICALIBRARY=%OPENMODELICAHOME%\\lib\\omlibrary\\msl31"); - out.newLine(); - out.write("%OPENMODELICAHOME%\\bin\\omc.exe %*"); - out.newLine(); - out.close(); - fw.close(); - - return omBat; - } catch (IOException e) { - e.printStackTrace(); - throw new UnsatisfiedLinkError("OpenModelica probably not installed. Tried to find it from: " + modelicaHome.getAbsolutePath()); - } - } - - public static File getSimulationExecutableBat(File exeFile) { - - File modelicaHome = getModelicaHome(); - - File folder = new File(exeFile.getParent()); - - try { - File exeBat = new File(folder, exeFile.getName() + ".bat"); - FileWriter fw = new FileWriter(exeBat); - BufferedWriter out = new BufferedWriter(fw); - - out.write("@echo off"); - out.newLine(); - out.write("set OPENMODELICAHOME=" + modelicaHome.getAbsolutePath()); - out.newLine(); - out.write("set OPENMODELICALIBRARY=%OPENMODELICAHOME%\\lib\\omlibrary\\msl31"); - out.newLine(); - out.write("set OMPATH=%OPENMODELICAHOME%\\bin"); - out.newLine(); - out.write("echo %PATH%|findstr /i %OMPATH% >nul:"); - out.newLine(); - out.write("if %errorlevel%==1 set PATH=%PATH%;%OMPATH%"); - out.newLine(); - out.write(exeFile.getAbsolutePath() + " %*"); - out.newLine(); - - out.close(); - fw.close(); - return exeBat; - } - catch (IOException e) { - e.printStackTrace(); - throw new UnsatisfiedLinkError("Creating bat for the exe failed"); - } - } - - protected static File createTempDirectory() throws IOException { - final File temp = File.createTempFile("temp", Long.toString(System.nanoTime())); - if(!(temp.delete())) - throw new IOException("Could not delete temp file: " + temp.getAbsolutePath()); - if(!(temp.mkdir())) - throw new IOException("Could not create temp directory: " + temp.getAbsolutePath()); - return (temp); - } - - protected static boolean recursiveDelete(File fileOrDir) { - if(fileOrDir.isDirectory()) - for(File innerFile: fileOrDir.listFiles()) - if(!recursiveDelete(innerFile)) - return false; - return fileOrDir.delete(); - } - - protected static String readFile(File file) throws IOException { - InputStream stream = new FileInputStream(file); - byte[] buffer = new byte[(int)file.length()]; - stream.read(buffer); - stream.close(); - return new String(buffer); - } - - public static void printProcessOutput(final Process process, final IModelicaMonitor monitor) { - Thread thread = new Thread() { - @Override - public void run() { - InputStream stream = process.getInputStream(); - StringBuilder b = new StringBuilder(); - while(true) { - try { - int c; - - c = stream.read(); - - if(c <= 0) - break; - if((char)c != '\n') - b.append((char)c); - else { - System.out.println("OMC output: " + b.toString()); - String message = b.toString(); - message = message.trim(); - if(message.startsWith("\"")) - message = message.substring(1); - monitor.message(message); - b.delete(0, b.length()); - } - } catch (IOException e) { - System.err.println("Not able to read simulation output"); - e.printStackTrace(); - } - } - } - }; - thread.run(); - - } - - public static SimulationLocation createInputFiles(File simulationDir, String modelName, String modelText, HashMap inits, String additionalScript) throws IOException { - System.out.println(simulationDir.getAbsolutePath()); - modelName = modelName.replace(" ", ""); - File modelFile = new File(simulationDir, modelName + ".mo"); - File scriptFile = new File(simulationDir, modelName + ".mos"); - String outputFormat = inits.containsKey("outputFormat") ? inits.get("outputFormat") : "\"plt\""; - { - PrintStream s = new PrintStream(modelFile); - s.print(modelText); - s.close(); - } - - { - PrintStream s = new PrintStream(scriptFile); - if(additionalScript != null) - s.println(additionalScript); - s.println("loadFile(\"" + modelName + ".mo\");"); - s.print("buildModel("+modelName+ - ",startTime="+inits.get("start value")+ - ",stopTime="+inits.get("stop value")+ - ",method="+inits.get("method")+ - ",outputFormat="+ outputFormat - ); - if(inits.containsKey("tolerance")) { - s.print(",tolerance="+inits.get("tolerance")); - } - s.print(");\n"); - s.println("getErrorString();"); - s.close(); - } - - OSType os = calculateOS(); - String suffix = OSType.WINDOWS.equals(os) ? ".exe" : ""; - - return new SimulationLocation( - simulationDir, - new File(simulationDir, modelName + ".mos"), - new File(simulationDir, modelName + "_res." + outputFormat.substring(1, outputFormat.length()-1)), - new File(simulationDir, modelName + "_init.txt"), - new File(simulationDir, modelName + suffix) - ); - } - - public static void buildModel(SimulationLocation simulationLocation, IModelicaMonitor monitor) throws ModelicaException { - try { - File omc = getModelicaExecutable(simulationLocation.simulationDir); - - if(omc == null) { - monitor.message("OpenModelica not found! Install it from www.openmodelica.org"); - throw new ModelicaException("OpenModelica not found"); - } - - Process process = new ProcessBuilder( - omc.getAbsolutePath(), - simulationLocation.inputFile.getAbsolutePath() - ) - .directory(simulationLocation.simulationDir.getAbsoluteFile()) - .redirectErrorStream(true) - .start(); - printProcessOutput(process, monitor); - - if(!simulationLocation.exeFile.isFile()) - throw new ModelicaException(".exe file not created\nSee log at " + simulationLocation.simulationDir.getAbsolutePath()); - - } catch(IOException e) { - e.printStackTrace(); - } - - } - - public static Process runModelica(SimulationLocation simulationLocation, IModelicaMonitor monitor, HashMap inits) throws IOException { - - try { - - writeInits(simulationLocation, inits); - - Process process = new ProcessBuilder( - getSimulationExecutableBat(simulationLocation.exeFile).getAbsolutePath() - ) - .directory(simulationLocation.simulationDir.getAbsoluteFile()) - .redirectErrorStream(true) - .start(); - - return process; - } catch(IOException e) { - e.printStackTrace(); - } - return null; - } - - private static void writeInits(SimulationLocation simulationLocation, HashMap inits) { - - HashMap initials = new HashMap(); - HashMap order = new HashMap(); - - InputStream is; - try { - is = new FileInputStream(simulationLocation.initFile); - int orderNumber = 0; - while(true) { - String line = getLine(is); - if(line == null) - return; - if(line.isEmpty()) - break; - if(line.contains("//")) { - String[] nn = line.split("//", 2); - String key = nn[1].trim(); - String value = nn[0].trim(); - if(inits.containsKey(key)) { - value = inits.get(key); - } - initials.put(key, value); - order.put(orderNumber, key); - } - orderNumber++; - } - is.close(); - - PrintStream s = new PrintStream(simulationLocation.initFile); - for(int j = 0; j < orderNumber ; j++) { - String key = order.get(j); - if (key != null) { - s.println(initials.get(key) + " // " + key); - } else { - s.println("0.0"); - } - } - s.close(); - - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - - private static String getLine(InputStream stream) { - if(stream == null) - return null; - StringBuilder b = new StringBuilder(); - try { - while(true) { - int c = stream.read(); - if(c == -1) { - stream = null; - return b.toString(); - } - else if(c == '\n') - return b.toString(); - else if(c == '\r') - ; - else - b.append((char)c); - } - } catch (IOException e) { - return null; - } - - } - + public enum OSType { + APPLE, LINUX, SUN, WINDOWS, UNKNOWN + } + + public static OSType calculateOS() { + String osName = System.getProperty("os.name"); + assert osName != null; + osName = osName.toLowerCase(); + if (osName.startsWith("mac os x")) + return OSType.APPLE; + if (osName.startsWith("windows")) + return OSType.WINDOWS; + if (osName.startsWith("linux")) + return OSType.LINUX; + if (osName.startsWith("sun")) + return OSType.SUN; + return OSType.UNKNOWN; + } + + public static File getModelicaHome() { + + String dir = System.getenv("OPENMODELICAHOME"); + File omhome = null; + + String osName = System.getProperty("os.name"); + OSType os = calculateOS(); + + if (os == OSType.UNKNOWN) + throw new UnsatisfiedLinkError("unknown OS '" + osName + "' for running OpenModelica"); + + // If OPENMODELICAHOME is found, try to return the folder. + if(dir != null) { + switch (os) { + case APPLE: + case LINUX: + case SUN: + omhome = new File(dir); + if(omhome.isDirectory()) + return omhome; + else + break; + case WINDOWS: + omhome = new File(dir); + if(omhome.isDirectory()) + return omhome; + else + break; + } + } + + // OPENMODELICAHOMe was not found or the folder does not exist. Try built-in OpenModelica for windows + if(os.equals(OSType.WINDOWS)) { + + Bundle bundle = Platform.getBundle("org.simantics.openmodelica.win32"); + if (bundle != null) { + try{ + URL entry = bundle.getEntry("/"); + if(entry != null) { + URL fileURL = FileLocator.toFileURL(entry); + File root = new File( URLDecoder.decode(fileURL.getPath(), "UTF-8") ); + File f = new File(root, "OpenModelica1.7.0"); + return f; + } + } + catch (Exception e) { + e.printStackTrace(); + } + } + } + + // OS was not windows or built-in OpenModelica did not work + switch (os) { + case APPLE: + case LINUX: + case SUN: + return new File("/usr/bin/omc"); + case WINDOWS: + return new File("c:/OpenModelica1.7.0"); + default: + throw new UnsatisfiedLinkError("Unsupported operating system: " + os); + } + } + + public static File getModelicaExecutable(File simulationDir) { + + File modelicaHome = getModelicaHome(); + + if(!modelicaHome.isDirectory()) + throw new UnsatisfiedLinkError("OpenModelica probably not installed. Tried to find it from: " + modelicaHome.getAbsolutePath()); + + try { + File omBat = new File(simulationDir, "om.bat"); + FileWriter fw = new FileWriter(omBat); + BufferedWriter out = new BufferedWriter(fw); + out.write("@echo off"); + out.newLine(); + out.write("set OPENMODELICAHOME=" + modelicaHome.getAbsolutePath()); + out.newLine(); + out.write("set OPENMODELICALIBRARY=%OPENMODELICAHOME%\\lib\\omlibrary\\msl31"); + out.newLine(); + out.write("%OPENMODELICAHOME%\\bin\\omc.exe %*"); + out.newLine(); + out.close(); + fw.close(); + + return omBat; + } catch (IOException e) { + e.printStackTrace(); + throw new UnsatisfiedLinkError("OpenModelica probably not installed. Tried to find it from: " + modelicaHome.getAbsolutePath()); + } + } + + public static File getSimulationExecutableBat(File exeFile) { + + File modelicaHome = getModelicaHome(); + + File folder = new File(exeFile.getParent()); + + try { + File exeBat = new File(folder, exeFile.getName() + ".bat"); + FileWriter fw = new FileWriter(exeBat); + BufferedWriter out = new BufferedWriter(fw); + + out.write("@echo off"); + out.newLine(); + out.write("set OPENMODELICAHOME=" + modelicaHome.getAbsolutePath()); + out.newLine(); + out.write("set OPENMODELICALIBRARY=%OPENMODELICAHOME%\\lib\\omlibrary\\msl31"); + out.newLine(); + out.write("set OMPATH=%OPENMODELICAHOME%\\bin"); + out.newLine(); + out.write("echo %PATH%|findstr /i %OMPATH% >nul:"); + out.newLine(); + out.write("if %errorlevel%==1 set PATH=%PATH%;%OMPATH%"); + out.newLine(); + out.write(exeFile.getAbsolutePath() + " %*"); + out.newLine(); + + out.close(); + fw.close(); + return exeBat; + } + catch (IOException e) { + e.printStackTrace(); + throw new UnsatisfiedLinkError("Creating bat for the exe failed"); + } + } + + protected static File createTempDirectory() throws IOException { + final File temp = File.createTempFile("temp", Long.toString(System.nanoTime())); + if(!(temp.delete())) + throw new IOException("Could not delete temp file: " + temp.getAbsolutePath()); + if(!(temp.mkdir())) + throw new IOException("Could not create temp directory: " + temp.getAbsolutePath()); + return (temp); + } + + protected static boolean recursiveDelete(File fileOrDir) { + if(fileOrDir.isDirectory()) + for(File innerFile: fileOrDir.listFiles()) + if(!recursiveDelete(innerFile)) + return false; + return fileOrDir.delete(); + } + + protected static String readFile(File file) throws IOException { + InputStream stream = new FileInputStream(file); + byte[] buffer = new byte[(int)file.length()]; + stream.read(buffer); + stream.close(); + return new String(buffer); + } + + public static void printProcessOutput(final Process process, final IModelicaMonitor monitor) { + Thread thread = new Thread() { + @Override + public void run() { + InputStream stream = process.getInputStream(); + StringBuilder b = new StringBuilder(); + while(true) { + try { + int c; + + c = stream.read(); + + if(c <= 0) + break; + if((char)c != '\n') + b.append((char)c); + else { + System.out.println("OMC output: " + b.toString()); + String message = b.toString(); + message = message.trim(); + if(message.startsWith("\"")) + message = message.substring(1); + monitor.message(message); + b.delete(0, b.length()); + } + } catch (IOException e) { + System.err.println("Not able to read simulation output"); + e.printStackTrace(); + } + } + } + }; + thread.run(); + + } + + public static SimulationLocation createInputFiles(File simulationDir, String modelName, String modelText, HashMap inits, String additionalScript) throws IOException { + System.out.println(simulationDir.getAbsolutePath()); + modelName = modelName.replace(" ", ""); + File modelFile = new File(simulationDir, modelName + ".mo"); + File scriptFile = new File(simulationDir, modelName + ".mos"); + String outputFormat = inits.containsKey("outputFormat") ? inits.get("outputFormat") : "\"plt\""; + { + PrintStream s = new PrintStream(modelFile); + s.print(modelText); + s.close(); + } + + { + PrintStream s = new PrintStream(scriptFile); + if(additionalScript != null) + s.println(additionalScript); + s.println("loadFile(\"" + modelName + ".mo\");"); + s.print("buildModel("+modelName+ + ",startTime="+inits.get("start value")+ + ",stopTime="+inits.get("stop value")+ + ",method="+inits.get("method")+ + ",outputFormat="+ outputFormat + ); + if(inits.containsKey("tolerance")) { + s.print(",tolerance="+inits.get("tolerance")); + } + s.print(");\n"); + s.println("getErrorString();"); + s.close(); + } + + OSType os = calculateOS(); + String suffix = OSType.WINDOWS.equals(os) ? ".exe" : ""; + + return new SimulationLocation( + simulationDir, + new File(simulationDir, modelName + ".mos"), + new File(simulationDir, modelName + "_res." + outputFormat.substring(1, outputFormat.length()-1)), + new File(simulationDir, modelName + "_init.txt"), + new File(simulationDir, modelName + suffix) + ); + } + + public static void buildModel(SimulationLocation simulationLocation, IModelicaMonitor monitor) throws ModelicaException { + try { + File omc = getModelicaExecutable(simulationLocation.simulationDir); + + if(omc == null) { + monitor.message("OpenModelica not found! Install it from www.openmodelica.org"); + throw new ModelicaException("OpenModelica not found"); + } + + Process process = new ProcessBuilder( + omc.getAbsolutePath(), + simulationLocation.inputFile.getAbsolutePath() + ) + .directory(simulationLocation.simulationDir.getAbsoluteFile()) + .redirectErrorStream(true) + .start(); + printProcessOutput(process, monitor); + + if(!simulationLocation.exeFile.isFile()) + throw new ModelicaException(".exe file not created\nSee log at " + simulationLocation.simulationDir.getAbsolutePath()); + + } catch(IOException e) { + e.printStackTrace(); + } + + } + + public static Process runModelica(SimulationLocation simulationLocation, IModelicaMonitor monitor, HashMap inits) throws IOException { + + try { + + writeInits(simulationLocation, inits); + + Process process = new ProcessBuilder( + getSimulationExecutableBat(simulationLocation.exeFile).getAbsolutePath() + ) + .directory(simulationLocation.simulationDir.getAbsoluteFile()) + .redirectErrorStream(true) + .start(); + + return process; + } catch(IOException e) { + e.printStackTrace(); + } + return null; + } + + private static void writeInits(SimulationLocation simulationLocation, HashMap inits) { + /* How the correct input file format should be investigated: + try { + + List command = new ArrayList(); + command.add(getModelicaHome().getAbsolutePath() + "\\bin\\omc.exe"); + command.add("+version"); + + ProcessBuilder builder = new ProcessBuilder(command); + Map environ = builder.environment(); + environ.put("OPENMODELICAHOME", getModelicaHome().getAbsolutePath()); + + builder.directory(new File(System.getenv("temp"))); + + Process process; + process = builder.start(); + + InputStream is = process.getInputStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + String line; + while ((line = br.readLine()) != null) { + System.out.println("OpenModelica Version: " + line); + } + + } catch (IOException e) { + e.printStackTrace(); + } + */ + + // OpenModelica version number has stayed the same after changing the + // init format to nightly builds. + if(simulationLocation.initFile.getAbsolutePath().endsWith(".txt")) { + File xmlTest = new File(simulationLocation.initFile.getAbsolutePath().replace(".txt", ".xml")); + if(xmlTest.exists()) { + simulationLocation.initFile = xmlTest; + } + } + + if(simulationLocation.initFile.getAbsolutePath().endsWith(".txt")) { + InitWriter.writeTXT(simulationLocation.initFile.getAbsolutePath(), inits); + } else { + InitWriter.writeXML(simulationLocation.initFile.getAbsolutePath(), inits); + + } + } } diff --git a/org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java b/org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java index 2e104443..a7068a38 100644 --- a/org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java +++ b/org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java @@ -22,6 +22,20 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + /** * Class that reads OpenModelica result files. * @author Hannu Niemistö @@ -30,18 +44,18 @@ public class SimulationResult { List variables = new ArrayList(); List initials = new ArrayList(); - - class TimeValuePair { - public String time; - public String value; - - public TimeValuePair(String time, String value) { - this.time = time; - this.value = value; - } - } - - HashMap> errors = new HashMap>(); + + class TimeValuePair { + public String time; + public String value; + + public TimeValuePair(String time, String value) { + this.time = time; + this.value = value; + } + } + + HashMap> errors = new HashMap>(); static String getLine(InputStream stream) { if(stream == null) @@ -69,12 +83,81 @@ public class SimulationResult { public void readInits(File file) throws FileNotFoundException, IOException { - InputStream is = new FileInputStream(file); - readInits(is); - is.close(); + + if(file.getName().endsWith("txt")) { + InputStream is = new FileInputStream(file); + readInitsTXT(is); + is.close(); + } else if(file.getName().endsWith("xml")) { + readInitsXML(file.getAbsolutePath()); + } } - public void readInits(InputStream stream) { + public void readInitsXML(String file) { + Document doc; + try { + doc = DocumentBuilderFactory.newInstance() + .newDocumentBuilder().parse(new InputSource(file)); + + XPath xpath = XPathFactory.newInstance().newXPath(); + + List times = new ArrayList(2); + Node node; + // Find start time + node = (Node)xpath.evaluate + ("//fmiModelDescription/DefaultExperiment/@startTime", + doc, + XPathConstants.NODE); + times.add(Double.parseDouble(node.getNodeValue())); + // Find end time + node = (Node)xpath.evaluate + ("//fmiModelDescription/DefaultExperiment/@stopTime", + doc, + XPathConstants.NODE); + times.add(Double.parseDouble(node.getNodeValue())); + + NodeList nodes; + // Find parameters and constants + nodes = (NodeList)xpath.evaluate + ("//fmiModelDescription/ModelVariables/ScalarVariable[@variability='parameter']", + doc, + XPathConstants.NODESET); + + // make the change. There should be only one node. + List values; + NodeList children; + for (int idx = 0; idx < nodes.getLength(); idx++) { + Node n = nodes.item(idx); + children = n.getChildNodes(); + for(int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if(child.getNodeName().equals("Real")) { + Double d = Double.parseDouble(child.getAttributes().getNamedItem("start").getNodeValue()); + values = new ArrayList(2); + values.add(d); + values.add(d); + initials.add( + new DataSet(n.getAttributes().getNamedItem("name").getNodeValue(), + times , + values)); + break; + } + } + } + } catch (SAXException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } catch (TransformerFactoryConfigurationError e) { + e.printStackTrace(); + } catch (XPathExpressionException e) { + e.printStackTrace(); + } + } + + public void readInitsTXT(InputStream stream) { HashMap mappedInitials = new HashMap(); while(true) { String line = getLine(stream); @@ -92,17 +175,17 @@ public class SimulationResult { } catch (NumberFormatException nfe) { continue; // Not a valid double } - + } } - + double startTime = mappedInitials.get("start value"); double stopTime = mappedInitials.get("stop value"); List times = new ArrayList(2); times.add(startTime); times.add(stopTime); - + for(String key : mappedInitials.keySet()) { List values = new ArrayList(2); values.add(mappedInitials.get(key)); @@ -169,7 +252,7 @@ public class SimulationResult { public List getInitialValueDataSets() { return initials; } - + /** * Gets DataSet for variable. Loops first the variables and then initials. * @param name the name of the variable @@ -179,28 +262,28 @@ public class SimulationResult { for(DataSet set : variables) if(set.name.equals(name)) return set; - for(DataSet set : initials) - if(set.name.equals(name)) - return set; - return null; + for(DataSet set : initials) + if(set.name.equals(name)) + return set; + return null; } - - + + /** * Return errors encountered during reading of the results. * * @return */ public String getResultReadErrors() { - StringBuilder errorString = new StringBuilder(); + StringBuilder errorString = new StringBuilder(); if(!errors.isEmpty()) { - errorString.append("Number format errors (Time, Value):\n"); - for(String key : errors.keySet()) { - errorString.append("\n" + key + ":\n"); - for(TimeValuePair tv : errors.get(key)) { - errorString.append(" " + tv.time + ", " + tv.value + "\n"); - } - } + errorString.append("Number format errors (Time, Value):\n"); + for(String key : errors.keySet()) { + errorString.append("\n" + key + ":\n"); + for(TimeValuePair tv : errors.get(key)) { + errorString.append(" " + tv.time + ", " + tv.value + "\n"); + } + } } return errorString.toString(); }