]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Support mat-format simulation results
authorlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 22 Nov 2011 13:34:47 +0000 (13:34 +0000)
committerlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Tue, 22 Nov 2011 13:34:47 +0000 (13:34 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@23324 ac1ea38d-2e2b-0410-8846-a27921b304fc

13 files changed:
org.simantics.modelica/META-INF/MANIFEST.MF
org.simantics.modelica/src/org/simantics/modelica/data/CSVSimulationResult.java
org.simantics.modelica/src/org/simantics/modelica/data/DataSet.java
org.simantics.modelica/src/org/simantics/modelica/data/DoubleMatrix.java [new file with mode: 0644]
org.simantics.modelica/src/org/simantics/modelica/data/IntMatrix.java [new file with mode: 0644]
org.simantics.modelica/src/org/simantics/modelica/data/Mat4Reader.java [new file with mode: 0644]
org.simantics.modelica/src/org/simantics/modelica/data/MatSimulationResult.java [new file with mode: 0644]
org.simantics.modelica/src/org/simantics/modelica/data/Matrix.java [new file with mode: 0644]
org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java
org.simantics.modelica/src/org/simantics/modelica/data/StringMatrix.java [new file with mode: 0644]
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynDataSet.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynResult.java

index 972e7f9024f3bbdb5c0c878119c6d947d035bd6c..80e82f4e0fc4d3c8dbcbf0779b1a75462e9a0d38 100644 (file)
@@ -5,9 +5,10 @@ Bundle-SymbolicName: org.simantics.modelica;singleton:=true
 Bundle-Version: 1.0.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Require-Bundle: gnu.trove2;bundle-version="2.0.4",
- org.simantics.databoard;bundle-version="0.5.2",
  org.eclipse.osgi;bundle-version="3.6.0",
- org.eclipse.core.runtime;bundle-version="3.6.0"
+ org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.simantics.history;bundle-version="1.0.0",
+ org.simantics.databoard;bundle-version="0.6.3"
 Export-Package: org.simantics.modelica,
  org.simantics.modelica.data
 Bundle-Activator: org.simantics.modelica.Activator
index 742beeb3b4db0510f22048b47a2819e585cda041..1c3b1e2f228ced7380a40a40c48378ff9c840833 100644 (file)
@@ -15,11 +15,18 @@ import java.io.InputStream;
 import java.util.ArrayList;\r
 import java.util.HashMap;\r
 \r
-\r
+/**\r
+ * class for supporting csv-format simulation results\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
 public class CSVSimulationResult extends SimulationResult {\r
 \r
        HashMap<String, DataSet> valueMap = new HashMap<String, DataSet>();\r
        \r
+       /**\r
+        * Overridden method to support csv-formatted simulation results\r
+        */\r
        @Override\r
     public void read(InputStream stream) {\r
                errors.clear();\r
@@ -35,28 +42,30 @@ public class CSVSimulationResult extends SimulationResult {
                // Create lists for receiving values for each variable. Names still with quotes.\r
                for(String name : names) {\r
                        if(!name.isEmpty())\r
-                               valueMap.put(name, new DataSet(name, new ArrayList<Double>(), new ArrayList<Double>()));\r
+                               valueMap.put(name, new DataSet(name, new double[numberOfTimeSteps], new double[numberOfTimeSteps]));\r
                }\r
 \r
+               int row = 0;\r
         // Data sets\r
                while((line = getLine(stream)) != null) {      \r
             if(line.isEmpty())\r
                 break;\r
                        String[] values = line.split(",");\r
-                       for(int i = 0; i<values.length; i++) {\r
-                               if(values[i] != null && !values[i].isEmpty() && i < names.length) {\r
+                       for(int valueIndex = 0; valueIndex <values.length; valueIndex++) {\r
+                               if(values[valueIndex] != null && !values[valueIndex].isEmpty() && valueIndex < names.length) {\r
                                        try {\r
-                                               valueMap.get(names[i]).values.add(Double.parseDouble(values[i]));\r
+                                               valueMap.get(names[valueIndex]).values[row] = Double.parseDouble(values[valueIndex]);\r
                                        } catch (NumberFormatException e) {\r
-                                               ArrayList<TimeValuePair> list = errors.get(names[i]);\r
+                                               ArrayList<TimeValuePair> list = errors.get(names[valueIndex]);\r
                                                if(list == null) {\r
                                                        list = new ArrayList<TimeValuePair>();\r
-                                                       errors.put(names[i], list);\r
+                                                       errors.put(names[valueIndex], list);\r
                                                }\r
-                                               list.add(new TimeValuePair(values[0], values[i]));\r
+                                               list.add(new TimeValuePair(values[0], values[valueIndex]));\r
                                        }\r
                                }\r
                        }\r
+                       row++;\r
                }\r
         \r
         // Add time values for each dataset and add them to variables. \r
index 1a1546e24ee379c0841cf6307ec339435431ce3f..c1c4bae92c2870ee27de351180f4b00d57a66c1a 100644 (file)
  *******************************************************************************/\r
 package org.simantics.modelica.data;\r
 \r
-import java.util.List;\r
-\r
 /**\r
  * Simulation result for one variable.\r
  * @author Hannu Niemistö\r
  */\r
 public class DataSet {\r
     public String name;\r
-    public List<Double> times;\r
-    public List<Double> values;\r
+    public double[] times;\r
+    public double[] values;\r
     \r
-    public DataSet(String name, List<Double> times, List<Double> values) {\r
+    public DataSet(String name, double[] times, double[] values) {\r
         this.name = name;\r
         this.times = times;\r
         this.values = values;\r
diff --git a/org.simantics.modelica/src/org/simantics/modelica/data/DoubleMatrix.java b/org.simantics.modelica/src/org/simantics/modelica/data/DoubleMatrix.java
new file mode 100644 (file)
index 0000000..d8ace79
--- /dev/null
@@ -0,0 +1,38 @@
+package org.simantics.modelica.data;\r
+\r
+/**\r
+ * Copied from Hannu's DoubleMatrix in org.simantics.modelica.data\r
+ * \r
+ * To be replaced with the original when SysDyn and Modelica tools \r
+ * are synchronized to use the same OpenModelica plugin\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class DoubleMatrix extends Matrix {\r
+    public final int rows;\r
+    public final int columns;\r
+    public final double[] data;\r
+\r
+    public DoubleMatrix(String name, int rows, int columns) {\r
+        super(name);\r
+        this.rows = rows;\r
+        this.columns = columns;\r
+        this.data = new double[rows*columns];\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder b = new StringBuilder();\r
+        b.append("double " + name + "(" + rows + "," + columns + ")\n");\r
+        for(int i=0;i<columns;++i) {\r
+            for(int j=0;j<rows;++j) {\r
+                if(j > 0)\r
+                    b.append(' ');\r
+                b.append(data[i*rows + j]);                            \r
+            }\r
+            b.append('\n');\r
+        }\r
+        return b.toString();\r
+    }\r
+}\r
diff --git a/org.simantics.modelica/src/org/simantics/modelica/data/IntMatrix.java b/org.simantics.modelica/src/org/simantics/modelica/data/IntMatrix.java
new file mode 100644 (file)
index 0000000..6f3d6d4
--- /dev/null
@@ -0,0 +1,49 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.modelica.data;\r
+\r
+/**\r
+ * Copied from Hannu's IntMatrix in org.simantics.modelica.data\r
+ * \r
+ * To be replaced with the original when SysDyn and Modelica tools \r
+ * are synchronized to use the same OpenModelica plugin\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class IntMatrix extends Matrix {\r
+    public final int rows;\r
+    public final int columns;\r
+    public final int[] data;\r
+\r
+    public IntMatrix(String name, int rows, int columns) {\r
+        super(name);\r
+        this.rows = rows;\r
+        this.columns = columns;\r
+        this.data = new int[rows*columns];\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder b = new StringBuilder();\r
+        b.append("int " + name + "(" + rows + "," + columns + ")\n");\r
+        for(int i=0;i<columns;++i) {\r
+            for(int j=0;j<rows;++j) {\r
+                if(j > 0)\r
+                    b.append(' ');\r
+                b.append(data[i*rows + j]);                            \r
+            }\r
+            b.append('\n');\r
+        }\r
+        return b.toString();\r
+    }\r
+}\r
diff --git a/org.simantics.modelica/src/org/simantics/modelica/data/Mat4Reader.java b/org.simantics.modelica/src/org/simantics/modelica/data/Mat4Reader.java
new file mode 100644 (file)
index 0000000..0d89636
--- /dev/null
@@ -0,0 +1,149 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.modelica.data;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+/**\r
+ * Copied from Hannu's Mat4Reader in org.simantics.modelica.data\r
+ * \r
+ * To be replaced with the original when SysDyn and Modelica tools \r
+ * are synchronized to use the same OpenModelica plugin\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class Mat4Reader {\r
+\r
+    InputStream in;\r
+\r
+    public Mat4Reader(InputStream in) {\r
+        this.in = in;\r
+    }\r
+\r
+    private final int getInt() throws IOException {\r
+        int ch1 = in.read();\r
+        int ch2 = in.read();\r
+        int ch3 = in.read();\r
+        int ch4 = in.read();\r
+        return ((ch1 << 0) + (ch2 << 8) + (ch3 << 16) + (ch4 << 24));\r
+    }\r
+\r
+    private final long getLong() throws IOException {\r
+        int ch1 = in.read();\r
+        int ch2 = in.read();\r
+        int ch3 = in.read();\r
+        int ch4 = in.read();\r
+        int ch5 = in.read();\r
+        int ch6 = in.read();\r
+        int ch7 = in.read();\r
+        int ch8 = in.read();\r
+        return ((((long)ch1) << 0) + (((long)ch2) << 8) + (((long)ch3) << 16) + (((long)ch4) << 24) +\r
+                (((long)ch5) << 32) + (((long)ch6) << 40) + (((long)ch7) << 48) + (((long)ch8) << 56));\r
+    }\r
+\r
+    private final double getDouble() throws IOException {\r
+        return Double.longBitsToDouble(getLong());\r
+    }\r
+\r
+    private String getString(int length) throws IOException {\r
+        byte[] buffer = new byte[length];\r
+        int pos = 0;\r
+        while(pos < length)\r
+            pos += in.read(buffer, pos, length-pos);\r
+        return new String(buffer, "UTF-8");\r
+    }\r
+\r
+    public Matrix readMatrix() throws IOException {\r
+        int type = getInt();\r
+        int rows = getInt();\r
+        int columns = getInt();\r
+        int imagf = getInt();\r
+        int namlen = getInt();\r
+\r
+        String name = getString(namlen-1);\r
+        in.read();\r
+\r
+        if(imagf > 0)\r
+            throw new IOException("Imaginary part of the matrix is not supported (matrix " + name + ").");\r
+\r
+        switch(type) {\r
+        case 0: {\r
+            DoubleMatrix matrix = new DoubleMatrix(name, rows, columns);\r
+            int size = rows*columns;\r
+            double[] data = matrix.data;\r
+            for(int i=0;i<size;++i)\r
+                data[i] = getDouble();\r
+            return matrix;\r
+        } \r
+        case 20: {\r
+            IntMatrix matrix = new IntMatrix(name, rows, columns);\r
+            int size = rows*columns;\r
+            int[] data = matrix.data;\r
+            for(int i=0;i<size;++i)\r
+                data[i] = getInt();\r
+            return matrix;\r
+        }\r
+        case 51: {\r
+            StringMatrix matrix = new StringMatrix(name, columns);\r
+            String[] data = matrix.data;\r
+            for(int i=0;i<columns;++i)\r
+                data[i] = getString(rows).trim();\r
+            return matrix;\r
+        }\r
+        default:\r
+            throw new IOException("Matrix " + name + " has unsupported data type " + type + ".");\r
+        }\r
+    }\r
+\r
+    public static Map<String, double[]> read(InputStream in) throws IOException {\r
+        Mat4Reader reader = new Mat4Reader(in);\r
+        reader.readMatrix(); // Header\r
+        StringMatrix names = (StringMatrix)reader.readMatrix(); // Variable names\r
+        reader.readMatrix(); // Variable descriptions\r
+        IntMatrix info = (IntMatrix)reader.readMatrix(); // Data info\r
+        if(info.rows != 4 || info.columns != names.rows )\r
+            throw new IOException("Invalid result data.");\r
+        int[] infoData = info.data;\r
+        /*for(int i=0;i<info.columns;++i)\r
+            if(infoData[i*4] != 2)\r
+                throw new IOException("Unexpected storage of results.");*/\r
+        reader.readMatrix(); // Some result data matrix?\r
+        DoubleMatrix values = (DoubleMatrix)reader.readMatrix();\r
+        in.close();\r
+        \r
+        HashMap<String, double[]> result = new HashMap<String, double[]>();\r
+        double[] valueData = values.data;\r
+        int rows = values.rows;\r
+        //System.out.println("cols="+values.columns+", rows=" +values.rows+ ", data.length="+valueData.length);\r
+        for(int i=0;i<info.columns;++i) {\r
+            if(infoData[i*4] != 2)\r
+                continue;\r
+            double[] v = new double[values.columns];\r
+            int sc = infoData[i*4+1];\r
+            int c = sc > 0 ? sc-1 : 1-sc;\r
+            //System.out.println("i=" + i + ", sc=" + sc + ", c=" + c);\r
+            for(int j=0;j<v.length;++j)\r
+                v[j] = valueData[rows*j+c];\r
+            if(sc < 0)\r
+                for(int j=0;j<v.length;++j)\r
+                    v[j] = -v[j];\r
+            result.put(names.data[i], v);\r
+        }\r
+        return result;\r
+        \r
+    }\r
+\r
+}\r
diff --git a/org.simantics.modelica/src/org/simantics/modelica/data/MatSimulationResult.java b/org.simantics.modelica/src/org/simantics/modelica/data/MatSimulationResult.java
new file mode 100644 (file)
index 0000000..e563d51
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.modelica.data;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.util.Map;\r
+\r
+/**\r
+ * SimulationResult for Mat-formatted simulations results\r
+ *  \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class MatSimulationResult extends SimulationResult {\r
+    \r
+    @Override\r
+    public void read(InputStream stream) {\r
+        Map<String, double[]> valueMap = null;\r
+        try {\r
+            valueMap =  Mat4Reader.read(stream);\r
+        } catch (IOException e) {\r
+            e.printStackTrace();\r
+            return;\r
+        }\r
+        \r
+        DataSet ds;\r
+        double[] times = valueMap.get("time");\r
+        for(String key : valueMap.keySet()) {\r
+            ds = new DataSet(key, times, valueMap.get(key));\r
+            variables.add(ds);\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.modelica/src/org/simantics/modelica/data/Matrix.java b/org.simantics.modelica/src/org/simantics/modelica/data/Matrix.java
new file mode 100644 (file)
index 0000000..1e68c1b
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.modelica.data;\r
+\r
+/**\r
+ * Copied from Hannu's Matrix in org.simantics.modelica.data\r
+ * \r
+ * To be replaced with the original when SysDyn and Modelica tools \r
+ * are synchronized to use the same OpenModelica plugin\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public abstract class Matrix {\r
+    public final String name;\r
+\r
+    public Matrix(String name) {\r
+        this.name = name;\r
+    }\r
+}\r
index a7068a38548511e63ab543c8f205fb7fafcacb88..3d379ca47ad5009577512f333df4ebc7a48bc4b1 100644 (file)
@@ -14,8 +14,10 @@ package org.simantics.modelica.data;
 import java.io.File;\r
 import java.io.FileInputStream;\r
 import java.io.FileNotFoundException;\r
+import java.io.FileReader;\r
 import java.io.IOException;\r
 import java.io.InputStream;\r
+import java.io.LineNumberReader;\r
 import java.util.ArrayList;\r
 import java.util.HashMap;\r
 import java.util.List;\r
@@ -38,13 +40,21 @@ import org.xml.sax.SAXException;
 \r
 /**\r
  * Class that reads OpenModelica result files.\r
+ * \r
+ * SimulationResult class reads plt-files. Extended classes read other types.\r
+ * \r
+ * Will be replaced with a common OpenModelica plugin\r
  * @author Hannu Niemistö\r
  */\r
 public class SimulationResult {    \r
 \r
     List<DataSet> variables = new ArrayList<DataSet>();\r
     List<DataSet> initials = new ArrayList<DataSet>();\r
-\r
+    protected int numberOfTimeSteps = 0;\r
+    \r
+    /**\r
+     * Private class used in displaying errors\r
+     */\r
     class TimeValuePair {\r
         public String time;\r
         public String value;\r
@@ -57,6 +67,11 @@ public class SimulationResult {
 \r
     HashMap<String, ArrayList<TimeValuePair>> errors = new HashMap<String, ArrayList<TimeValuePair>>();\r
 \r
+    /**\r
+     * Get the next line in the plt-file\r
+     * @param stream plt-file input stream\r
+     * @return next line in the stream\r
+     */\r
     static String getLine(InputStream stream) {\r
         if(stream == null)\r
             return null;\r
@@ -82,6 +97,14 @@ public class SimulationResult {
     }\r
 \r
 \r
+    /**\r
+     * Read parameters that are located in the inits-file to the simulation result.\r
+     * Supports both txt and xml type inits.\r
+     * \r
+     * @param file inits-file\r
+     * @throws FileNotFoundException \r
+     * @throws IOException\r
+     */\r
     public void readInits(File file) throws FileNotFoundException, IOException {\r
 \r
         if(file.getName().endsWith("txt")) {\r
@@ -93,6 +116,11 @@ public class SimulationResult {
         }\r
     }\r
 \r
+    /**\r
+     * Read xml inits\r
+     * \r
+     * @param file xml-formatted inits file\r
+     */\r
     public void readInitsXML(String file) {\r
         Document doc;\r
         try {\r
@@ -101,20 +129,20 @@ public class SimulationResult {
 \r
             XPath xpath = XPathFactory.newInstance().newXPath();\r
 \r
-            List<Double> times = new ArrayList<Double>(2);\r
+            double[] times = new double[2];\r
             Node node;\r
             // Find start time\r
             node = (Node)xpath.evaluate\r
                     ("//fmiModelDescription/DefaultExperiment/@startTime",\r
                             doc, \r
                             XPathConstants.NODE);\r
-            times.add(Double.parseDouble(node.getNodeValue()));\r
+            times[0] = Double.parseDouble(node.getNodeValue());\r
             // Find end time\r
             node = (Node)xpath.evaluate\r
                     ("//fmiModelDescription/DefaultExperiment/@stopTime",\r
                             doc, \r
                             XPathConstants.NODE);\r
-            times.add(Double.parseDouble(node.getNodeValue()));\r
+            times[1] = Double.parseDouble(node.getNodeValue());\r
             \r
             NodeList nodes;\r
             // Find parameters and constants\r
@@ -124,7 +152,7 @@ public class SimulationResult {
                             XPathConstants.NODESET);\r
 \r
             // make the change. There should be only one node.\r
-            List<Double> values;\r
+            double[] values;\r
             NodeList children;\r
             for (int idx = 0; idx < nodes.getLength(); idx++) {\r
                 Node n = nodes.item(idx);\r
@@ -133,9 +161,7 @@ public class SimulationResult {
                     Node child = children.item(i);\r
                     if(child.getNodeName().equals("Real")) {\r
                         Double d = Double.parseDouble(child.getAttributes().getNamedItem("start").getNodeValue());\r
-                        values = new ArrayList<Double>(2);\r
-                        values.add(d);\r
-                        values.add(d);\r
+                        values = new double[] {d,d};\r
                         initials.add(\r
                                 new DataSet(n.getAttributes().getNamedItem("name").getNodeValue(), \r
                                         times , \r
@@ -157,6 +183,10 @@ public class SimulationResult {
         }\r
     }\r
 \r
+    /**\r
+     * Read txt inits\r
+     * @param stream txt-formatted init file\r
+     */\r
     public void readInitsTXT(InputStream stream) {\r
         HashMap<String, Double> mappedInitials = new HashMap<String, Double>();\r
         while(true) {\r
@@ -182,14 +212,11 @@ public class SimulationResult {
 \r
         double startTime = mappedInitials.get("start value");\r
         double stopTime = mappedInitials.get("stop value");\r
-        List<Double> times = new ArrayList<Double>(2);\r
-        times.add(startTime);\r
-        times.add(stopTime);\r
+        double[] times = new double[] {startTime, stopTime};\r
 \r
         for(String key : mappedInitials.keySet()) {\r
-            List<Double> values = new ArrayList<Double>(2);\r
-            values.add(mappedInitials.get(key));\r
-            values.add(mappedInitials.get(key));\r
+            double d = mappedInitials.get(key);\r
+            double[] values = new double[] {d, d};\r
             initials.add(new DataSet(key, times , values));\r
         }\r
     }\r
@@ -197,12 +224,33 @@ public class SimulationResult {
 \r
     final static Pattern p1 = Pattern.compile("DataSet: ([^ ]*)");\r
 \r
+    /**\r
+     * Read result file\r
+     * \r
+     * @param file result file\r
+     * @throws FileNotFoundException\r
+     * @throws IOException\r
+     */\r
     public void read(File file) throws FileNotFoundException, IOException {\r
+        // First check the number of time steps\r
+        FileReader fr = new FileReader(file);\r
+        LineNumberReader  lnr = new LineNumberReader(fr);\r
+        lnr.skip(Long.MAX_VALUE);\r
+        numberOfTimeSteps = lnr.getLineNumber() - 1; // minus the first row, which is for names\r
+        lnr.close();\r
+        fr.close();\r
+\r
         InputStream is = new FileInputStream(file);\r
         read(is);\r
         is.close();\r
     }\r
 \r
+    \r
+    /**\r
+     * Read result file. The basic implementation supports\r
+     * plt-formatted results. Overridden to support other formats. \r
+     * @param stream FileInputStream for the result file\r
+     */\r
     public void read(InputStream stream) {\r
         while(true) {\r
             String line = getLine(stream);\r
@@ -219,8 +267,9 @@ public class SimulationResult {
                 return;\r
             String name = matcher.group(1);\r
 \r
-            List<Double> times = new ArrayList<Double>();\r
-            List<Double> values = new ArrayList<Double>();\r
+            double[] dtimes = new double[numberOfTimeSteps];\r
+            double[] dvalues = new double[numberOfTimeSteps];\r
+            int i = 0;\r
             while(true) {\r
                 String line = getLine(stream);\r
                 if(line == null)\r
@@ -228,14 +277,18 @@ public class SimulationResult {
                 if(line.isEmpty())\r
                     break;\r
                 String[] nn = line.split(", ", 2);\r
-                times.add(Double.parseDouble(nn[0]));\r
-                values.add(Double.parseDouble(nn[1]));\r
+                dtimes[i] = Double.parseDouble(nn[0]);\r
+                dvalues[i] = Double.parseDouble(nn[1]);\r
+                i++;\r
             }\r
 \r
-            variables.add(new DataSet(name, times, values));\r
+            variables.add(new DataSet(name, dtimes, dvalues));\r
         }\r
     }\r
 \r
+    /**\r
+     * Filter result set\r
+     */\r
     public void filter() {\r
         ArrayList<DataSet> newVariables = new ArrayList<DataSet>();\r
         for(DataSet dataSet : variables) {\r
@@ -245,10 +298,18 @@ public class SimulationResult {
         variables = newVariables;\r
     }\r
 \r
+    /**\r
+     * Get datasets for the variables in this result\r
+     * @return variable datasets\r
+     */\r
     public List<DataSet> getVariableDataSets() {\r
         return variables;\r
     }\r
 \r
+    /**\r
+     * Get datasets for the initial values in this simulation\r
+     * @return initial value datasets\r
+     */\r
     public List<DataSet> getInitialValueDataSets() {\r
         return initials;\r
     }\r
diff --git a/org.simantics.modelica/src/org/simantics/modelica/data/StringMatrix.java b/org.simantics.modelica/src/org/simantics/modelica/data/StringMatrix.java
new file mode 100644 (file)
index 0000000..8cfbea0
--- /dev/null
@@ -0,0 +1,41 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.modelica.data;\r
+\r
+/**\r
+ * Copied from Hannu's StringMatrix in org.simantics.modelica.data\r
+ * \r
+ * To be replaced with the original when SysDyn and Modelica tools \r
+ * are synchronized to use the same OpenModelica plugin\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class StringMatrix extends Matrix {\r
+    public final int rows;\r
+    public final String[] data;\r
+\r
+    public StringMatrix(String name, int rows) {\r
+        super(name);\r
+        this.rows = rows;\r
+        this.data = new String[rows];\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder b = new StringBuilder();\r
+        b.append("char " + name + "(" + rows + ")\n");\r
+        for(String row : data)\r
+            b.append(row + "\n");\r
+        return b.toString();\r
+    }\r
+}\r
index 431f5eb5e580f7b47ff1483989afcbcae6bc4dbe..89e53db517d4626e98caab3372cb8aca3eba8b1e 100644 (file)
  *******************************************************************************/\r
 package org.simantics.sysdyn.manager;\r
 \r
-import java.util.List;\r
-\r
 import org.simantics.modelica.data.DataSet;\r
 \r
+/**\r
+ * Extension for the basic Modelica result {@link DataSet} containing also an optional result name.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
 public class SysdynDataSet extends DataSet {\r
 \r
-    public String result;\r
+    public String result; // Name of the result file if this is not the result of the current simulation\r
 \r
-    public SysdynDataSet(String name, String result, List<Double> times, List<Double> values) {\r
+    public SysdynDataSet(String name, String result, double[] times, double[] values) {\r
         super(name, times, values);\r
         this.result = result;\r
     }\r
index 0a857906a7b2c4c1db85ecc36849c8a48880685a..25bff4f823b17b3773c4ce69bd726341f6f87c26 100644 (file)
@@ -32,16 +32,17 @@ import org.eclipse.core.runtime.IProgressMonitor;
 import org.simantics.db.ReadGraph;\r
 import org.simantics.db.Resource;\r
 import org.simantics.db.Session;\r
-import org.simantics.db.common.request.ReadRequest;\r
 import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
 import org.simantics.db.exception.ServiceException;\r
+import org.simantics.db.request.Read;\r
 import org.simantics.layer0.Layer0;\r
 import org.simantics.modelica.IModelicaMonitor;\r
 import org.simantics.modelica.ModelicaException;\r
 import org.simantics.modelica.ModelicaManager;\r
 import org.simantics.modelica.SimulationLocation;\r
 import org.simantics.modelica.data.CSVSimulationResult;\r
+import org.simantics.modelica.data.MatSimulationResult;\r
 import org.simantics.modelica.data.SimulationResult;\r
 import org.simantics.objmap.IMapping;\r
 import org.simantics.objmap.IMappingListener;\r
@@ -70,553 +71,639 @@ import org.simantics.sysdyn.representation.expressions.ParameterExpression;
 \r
 /**\r
  * Maintains a Java representation of system dynamic model.\r
- * @author Hannu Niemist&ouml;\r
+ * @author Hannu Niemistö\r
  */\r
 public class SysdynModel implements IMappingListener, IModel {\r
 \r
-       private Session session;\r
+    private Session session;\r
 \r
-       private IMapping mapping;\r
+    private IMapping mapping;\r
 \r
-       private Resource configurationResource;\r
-       private Resource modelResource;\r
-       \r
-       private Configuration configuration;\r
+    private Resource configurationResource;\r
+    private Resource modelResource;\r
 \r
-       private Set<Configuration> modules = new HashSet<Configuration>();\r
+    private Configuration configuration;\r
 \r
-       private Process process;\r
-       private boolean canceled;\r
-       private SimulationResult result;\r
-       private SysdynResult sysdynResult;\r
+    private Set<Configuration> modules = new HashSet<Configuration>();\r
+\r
+    private Process process;\r
+    private boolean canceled;\r
+    private SimulationResult result;\r
+    private SysdynResult sysdynResult;\r
+\r
+    private CopyOnWriteArrayList<Runnable> modificationListeners =\r
+            new CopyOnWriteArrayList<Runnable>();\r
+    private CopyOnWriteArrayList<Runnable> resultListeners =\r
+            new CopyOnWriteArrayList<Runnable>();\r
 \r
-       private CopyOnWriteArrayList<Runnable> modificationListeners =\r
-               new CopyOnWriteArrayList<Runnable>();\r
-       private CopyOnWriteArrayList<Runnable> resultListeners =\r
-               new CopyOnWriteArrayList<Runnable>();\r
-       \r
     protected THashSet<VariableValueSubscription> variableValueSubscriptions = new THashSet<VariableValueSubscription>();\r
     protected volatile VariableValueSubscription[] variableValueSubscriptionsSnapshot = null;\r
 \r
-       @SuppressWarnings("rawtypes")\r
-       private Map<Class, Object> services = new HashMap<Class, Object>();\r
-\r
-       private String previousModelStructure;\r
-       private HashMap<String, String> previousImportantInits = new HashMap<String, String>();\r
-\r
-       private File simulationDir;\r
-\r
-       void readModules(ReadGraph graph, Resource configResource, Set<Resource> result) throws DatabaseException {\r
-\r
-               if(!result.add(configResource)) return;\r
-\r
-               Layer0 l0 = Layer0.getInstance(graph);\r
-               SysdynResource sr = SysdynResource.getInstance(graph);\r
-               StructuralResource2 str = StructuralResource2.getInstance(graph);\r
-\r
-               for(Resource part : graph.getObjects(configResource, l0.ConsistsOf)) {\r
-                       if(graph.isInstanceOf(part, sr.Module)) {\r
-                               Resource type = graph.getPossibleType(part, sr.Module);\r
-                               Resource config = graph.getPossibleObject(type, str.IsDefinedBy);\r
-                               readModules(graph, config, result);\r
-                       }\r
-               }\r
-\r
-       }\r
-\r
-       Set<Resource> readModules(ReadGraph graph, Resource configResource) throws DatabaseException {\r
-               HashSet<Resource> result = new HashSet<Resource>();\r
-               readModules(graph, configResource, result);\r
-               return result;\r
-       }\r
-\r
-       private void createMapping(ReadGraph g) throws DatabaseException {\r
-               SysdynSchema schema = new SysdynSchema(g);\r
-               mapping = Mappings.createWithListening(schema);\r
-               mapping.addMappingListener(SysdynModel.this);\r
-               configuration = (Configuration)mapping.map(g, configurationResource);\r
-               for(Resource config : readModules(g, configurationResource)) {\r
-                       modules.add((Configuration)mapping.map(g, config));\r
-               }\r
-//             System.out.println("Loaded model with " + modules.size() + " modules.");\r
-       }\r
-\r
-       public SysdynModel(ReadGraph g, Resource configurationResource) {\r
-               this.session = g.getSession();\r
-               this.configurationResource = configurationResource;\r
-\r
-               try {\r
-                       createMapping(g);\r
-               } catch(DatabaseException e) {\r
-                       e.printStackTrace();\r
-               }\r
-               sysdynResult = new SysdynResult();\r
-               sysdynResult.setResult(new SimulationResult());\r
-\r
-               previousModelStructure = "";\r
-       }\r
-\r
-\r
-       /*\r
-        * some dummy(?) stuff for experiments\r
-        */\r
-       public SysdynModel(Resource modelResource) {\r
-               this.modelResource = modelResource;\r
-       }\r
-\r
-       public synchronized void simulate(final IModelicaMonitor monitor, final IProgressMonitor progressMonitor, final Experiment experiment) throws IOException {\r
-               canceled = false;\r
-               progressMonitor.subTask("Write modelica classes");\r
-               \r
-               // Write Modelica files\r
-               ModelicaWriter writer = new ModelicaWriter();\r
-               try {\r
-                   for(Configuration c : modules) {\r
-                       writer.write(c);\r
-                   }\r
-               } catch (Exception e) {\r
-                   setExperimentStopped(experiment);\r
-                   \r
-                   \r
-                   monitor.showConsole();\r
-                   \r
-                   monitor.message("Error when writing Modelica code.");\r
-                   return;\r
-               }\r
-               \r
-               progressMonitor.worked(1);\r
-\r
-               progressMonitor.subTask("Write initial files");\r
-               String modelText = writer.toString();\r
-               HashMap<String, String> inits = getInits(configuration, "");\r
-               Model model = configuration.getModel();\r
-               Double startTime = model.getStartTime();\r
-               Double stopTime = model.getStopTime();\r
-               Double numberOfIntervals = model.getOutputInterval();\r
-               inits.put("start value", startTime.toString());\r
-               inits.put("stop value", stopTime.toString());\r
-               String outputFormat = "\"csv\"";\r
-               inits.put("outputFormat", outputFormat);\r
-               if(numberOfIntervals != null) {\r
-                       inits.put("step value", numberOfIntervals.toString());\r
-               } else {\r
-                       inits.put("step value", "" + (stopTime - startTime) / 500);\r
-               }\r
-               String method = "\"" + model.getSolver() + "\"";\r
-               inits.put("method", method);\r
-               if(model.getTolerance() != null)\r
-                       inits.put("tolerance", model.getTolerance().toString());\r
-\r
-               StringBuilder functionscript = new StringBuilder();\r
-               for(String path : FunctionUtils.getLibraryPathsForModelica(this)) {\r
-                       System.out.println("loadFile(\"" + path + "\");\n");\r
-                       functionscript.append("loadFile(\"" + path + "\");\n"); \r
-               }\r
-               \r
-               final SimulationLocation simulationLocation = ModelicaManager.createInputFiles(\r
-                               getSimulationDir(),\r
-                               configuration.getName(),\r
-                               modelText,\r
-                               inits,\r
-                               functionscript.toString());\r
-               \r
-\r
-               progressMonitor.worked(1);\r
-\r
-\r
-               if (!simulationLocation.exeFile.isFile() || hasStructureChanged(modelText, inits)) {\r
-                       progressMonitor.subTask("Build model");\r
-                       previousModelStructure = modelText;\r
-                       System.out.println("== Modelica == ");\r
+    @SuppressWarnings("rawtypes")\r
+    private Map<Class, Object> services = new HashMap<Class, Object>();\r
+\r
+    private String previousModelStructure;\r
+    private HashMap<String, String> previousImportantInits = new HashMap<String, String>();\r
+\r
+    private File simulationDir;\r
+\r
+    /**\r
+     * Recursively read all module configurations that are used in \r
+     * configResource and its components children\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param configResource Configuration\r
+     * @param result set containing all encountered configurations\r
+     * @throws DatabaseException\r
+     */\r
+    void readModules(ReadGraph graph, Resource configResource, Set<Resource> result) throws DatabaseException {\r
+\r
+        // if result does not contain this resource, add it to the result\r
+        if(!result.add(configResource)) return;\r
+\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        StructuralResource2 str = StructuralResource2.getInstance(graph);\r
+\r
+        for(Resource part : graph.getObjects(configResource, l0.ConsistsOf)) {\r
+            if(graph.isInstanceOf(part, sr.Module)) {\r
+                Resource type = graph.getPossibleType(part, sr.Module);\r
+                Resource config = graph.getPossibleObject(type, str.IsDefinedBy);\r
+                // Recursively readModules\r
+                readModules(graph, config, result);\r
+            }\r
+        }\r
+\r
+    }\r
+\r
+    /**\r
+     * Get all modules that have been used in configResource and its children\r
+     * @param graph ReadGraph\r
+     * @param configResource Configuration\r
+     * @return All modules (configuration resources) that have been used in configResource  \r
+     * @throws DatabaseException\r
+     */\r
+    Set<Resource> readModules(ReadGraph graph, Resource configResource) throws DatabaseException {\r
+        HashSet<Resource> result = new HashSet<Resource>();\r
+        readModules(graph, configResource, result);\r
+        return result;\r
+    }\r
+\r
+    /**\r
+     * Create an ObjMapping\r
+     * @param g ReadGraph\r
+     * @throws DatabaseException\r
+     */\r
+    private void createMapping(ReadGraph g) throws DatabaseException {\r
+        SysdynSchema schema = new SysdynSchema(g);\r
+        mapping = Mappings.createWithListening(schema);\r
+        mapping.addMappingListener(SysdynModel.this);\r
+        configuration = (Configuration)mapping.map(g, configurationResource);\r
+        for(Resource config : readModules(g, configurationResource)) {\r
+            modules.add((Configuration)mapping.map(g, config));\r
+        }\r
+    }\r
+\r
+    /**\r
+     * New Sysdyn model\r
+     * @param g ReadGraph\r
+     * @param configurationResource Configration resource of the model\r
+     */\r
+    public SysdynModel(ReadGraph g, Resource configurationResource) {\r
+        this.session = g.getSession();\r
+        this.configurationResource = configurationResource;\r
+\r
+        try {\r
+            createMapping(g);\r
+        } catch(DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+\r
+        // initialize results\r
+        sysdynResult = new SysdynResult();\r
+        sysdynResult.setResult(new SimulationResult());\r
+\r
+        previousModelStructure = "";\r
+    }\r
+\r
+\r
+    /*\r
+     * a dummy(?) call for experiments\r
+     */\r
+    public SysdynModel(Resource modelResource) {\r
+        this.modelResource = modelResource;\r
+    }\r
+\r
+    /**\r
+     * Simulate this model\r
+     * @param monitor IModelicaMonitor\r
+     * @param progressMonitor IProgressMonitor\r
+     * @param experiment SysdynExperiment\r
+     * @throws IOException\r
+     */\r
+    public synchronized void simulate(final IModelicaMonitor monitor, final IProgressMonitor progressMonitor, final Experiment experiment) throws IOException {\r
+        canceled = false;\r
+        progressMonitor.subTask("Write modelica classes");\r
+\r
+        // Write Modelica files\r
+        ModelicaWriter writer = new ModelicaWriter();\r
+        try {\r
+            // Write all configurations once\r
+            for(Configuration c : modules) {\r
+                writer.write(c);\r
+            }\r
+        } catch (Exception e) {\r
+            // Stop experiment and show console\r
+            setExperimentStopped(experiment);\r
+            monitor.showConsole();\r
+            monitor.message("Error when writing Modelica code.");\r
+            return;\r
+        }\r
+        String modelText = writer.toString();\r
+        progressMonitor.worked(1);\r
+\r
+        // Write initial files and add init-parameters\r
+        progressMonitor.subTask("Write initial files");\r
+        HashMap<String, String> inits = getInits(configuration, "");\r
+        Model model = configuration.getModel();\r
+        Double startTime = model.getStartTime();\r
+        Double stopTime = model.getStopTime();\r
+        Double numberOfIntervals = model.getOutputInterval();\r
+        inits.put("start value", startTime.toString());\r
+        inits.put("stop value", stopTime.toString());\r
+        String outputFormat = "\"mat\"";\r
+        inits.put("outputFormat", outputFormat);\r
+        if(numberOfIntervals != null) {\r
+            inits.put("step value", numberOfIntervals.toString());\r
+        } else {\r
+            inits.put("step value", "" + (stopTime - startTime) / 500);\r
+        }\r
+        String method = "\"" + model.getSolver() + "\"";\r
+        inits.put("method", method);\r
+        if(model.getTolerance() != null)\r
+            inits.put("tolerance", model.getTolerance().toString());\r
+\r
+        // add loadFile script to load all related functions and function libraries \r
+        StringBuilder functionscript = new StringBuilder();\r
+        for(String path : FunctionUtils.getLibraryPathsForModelica(this)) {\r
+            functionscript.append("loadFile(\"" + path + "\");\n");    \r
+        }\r
+\r
+        // Create simulation files\r
+        final SimulationLocation simulationLocation = ModelicaManager.createInputFiles(\r
+                getSimulationDir(),\r
+                configuration.getName(),\r
+                modelText,\r
+                inits,\r
+                functionscript.toString());\r
+\r
+\r
+        progressMonitor.worked(1);\r
+\r
+        // Build the model and store previous model structure and inits that affect the building\r
+        // If there is no exe file OR the model structure has not changed, no need to build\r
+        if (!simulationLocation.exeFile.isFile() || hasStructureChanged(modelText, inits)) {\r
+            progressMonitor.subTask("Build model");\r
+            previousModelStructure = modelText;\r
+//                     System.out.println("== Modelica == ");\r
 //                     System.out.println(writer.toString());\r
-                       System.out.println("== Modelica ends == ");\r
-\r
-                       try {\r
-                               simulationLocation.exeFile.delete();\r
-                               ModelicaManager.buildModel(simulationLocation, monitor);\r
-                               previousImportantInits.clear();\r
-                               previousImportantInits.put("start value", startTime.toString());\r
-                               previousImportantInits.put("stop value", stopTime.toString());\r
-                               previousImportantInits.put("method", method);\r
-                               previousImportantInits.put("outputFormat", outputFormat);\r
-                       } catch (ModelicaException e) {\r
-                               if(e.getMessage() != null)\r
-                                       monitor.message(e.getMessage());\r
-                               monitor.showConsole();\r
-                               canceled = true;\r
-                               previousModelStructure = "";\r
-                       }\r
-               }\r
-\r
-               progressMonitor.worked(1);\r
-\r
-               if(simulationLocation != null && !canceled) {\r
-                       progressMonitor.subTask("Simulate model");\r
-                       process = ModelicaManager.runModelica(\r
-                                       simulationLocation,\r
-                                       monitor,\r
-                                       inits\r
-                       );\r
-                       ModelicaManager.printProcessOutput(process, monitor);\r
-\r
-                       Thread resultThread = new Thread() {\r
-                               @Override\r
-                               public void run() {\r
-                                       try {\r
-                                               process.waitFor();\r
-\r
-                                               if(!canceled) {\r
-                                                       progressMonitor.worked(1);\r
-                                                       progressMonitor.subTask("Read results");\r
-                                                       result = new CSVSimulationResult();\r
-                                                       result.read(simulationLocation.outputFile);\r
-                                                       result.readInits(simulationLocation.initFile);\r
-                                                       result.filter();\r
-                                                       sysdynResult.setResult(result);\r
-                                                       progressMonitor.worked(1);\r
-                                                       resultChanged();\r
-                                                       \r
-                                                       setExperimentStopped(experiment);\r
-                                                       \r
-                                                       String errorString = result.getResultReadErrors();\r
-                                                       if(errorString != null && !errorString.isEmpty()) \r
-                                                               monitor.message(errorString);\r
-                                               }\r
-                                       } catch (FileNotFoundException e) {\r
-                                               e.printStackTrace();\r
-                                       } catch (IOException e) {\r
-                                               e.printStackTrace();\r
-                                       } catch (InterruptedException e) {\r
-                                               e.printStackTrace();\r
-                                       }\r
-                               }\r
-                       };\r
-                       resultThread.run();\r
-               }\r
-               if(canceled)\r
-                       setExperimentStopped(experiment);\r
-               process = null;\r
-       }\r
-\r
-       private void setExperimentStopped(Experiment experiment) {\r
-               if(experiment instanceof SysdynExperiment) {\r
-                       SysdynExperiment e = (SysdynExperiment)experiment;\r
-                       if(e.getState() != ExperimentState.DISPOSED)\r
-                               e.simulate(false);\r
-               }\r
-       }\r
-\r
-       private boolean hasStructureChanged(String modelText, Map<String, String> inits) {\r
-               \r
-               \r
-               BufferedReader current = new BufferedReader(\r
-                               new StringReader(modelText));\r
-               BufferedReader previous = new BufferedReader(\r
-                               new StringReader(previousModelStructure));\r
-\r
-               String c, p;\r
-               try {\r
-                       c = current.readLine();\r
-                       p = previous.readLine();\r
-                       \r
-                       while (c != null && p != null) {\r
-                               if(!c.equals(p)) {\r
-                                       if(c.contains("parameter") && p.contains("parameter")) {\r
-                                               int i = c.indexOf("=");\r
-                                               if(!c.substring(0, i).equals(p.substring(0, i))) {\r
-                                                       // different parameter definition\r
-                                                       return true;\r
-                                               }\r
-                                       } else {\r
-                                               // other than a line containing parameters differs\r
-                                               return true;\r
-                                       }\r
-                               }\r
-                               c = current.readLine();\r
-                               p = previous.readLine();\r
-                       }\r
-                       \r
-                       if((c == null && p != null) || (c != null && p == null)) {\r
-                               // different lengths\r
-                               return true;\r
-                       }\r
-\r
-               } catch(IOException e) {\r
-                       //e.printStackTrace();\r
-                       return true;\r
-               }\r
-\r
-               for(String key : previousImportantInits.keySet()) {\r
-                       if(!inits.containsKey(key) || !previousImportantInits.get(key).equals(inits.get(key)))\r
-                               return true;\r
-               }\r
-               return false;\r
-       }\r
-\r
-       public void cancelSimulation() {\r
-               canceled = true;\r
-               if(process != null) {\r
-                       process.destroy();\r
-               }\r
-       }\r
-\r
-       public synchronized boolean update(ReadGraph graph) throws DatabaseException {\r
-               if(mapping.isDomainModified()) {\r
-                       mapping.updateRange(graph);\r
-                       Set<Resource> configs = readModules(graph, configurationResource); \r
-                       for(Resource config : configs) {\r
-                               if(!modules.contains(config))\r
-                                       modules.add((Configuration)mapping.map(graph, config));\r
-                       }\r
-                       \r
-                       HashSet<Configuration> toBeRemoved = null;\r
-                       for(Configuration module : modules) {\r
-                           if(!configs.contains(mapping.inverseGet(module))) {\r
-                               if(toBeRemoved == null)\r
-                                   toBeRemoved = new HashSet<Configuration>();\r
-                               toBeRemoved.add(module);\r
-                           }\r
-                       }\r
-                       if(toBeRemoved != null)\r
-                           modules.removeAll(toBeRemoved);\r
-                       return true;\r
-               }\r
-               else\r
-                       return false;\r
-       }\r
-       \r
-       public synchronized boolean update() throws DatabaseException {\r
-               if(mapping.isDomainModified()) {\r
-                       session.syncRequest(new ReadRequest() {\r
-                               @Override\r
-                               public void run(ReadGraph graph) throws DatabaseException {\r
-                                       mapping.updateRange(graph);\r
-                           Set<Resource> configs = readModules(graph, configurationResource); \r
-                           for(Resource config : configs) {\r
-                               if(!modules.contains(config))\r
-                                   modules.add((Configuration)mapping.map(graph, config));\r
-                           }\r
-                           \r
-                           HashSet<Configuration> toBeRemoved = null;\r
-                           for(Configuration module : modules) {\r
-                               if(!configs.contains(mapping.inverseGet(module))) {\r
-                                   if(toBeRemoved == null)\r
-                                       toBeRemoved = new HashSet<Configuration>();\r
-                                   toBeRemoved.add(module);\r
-                               }\r
-                           }\r
-                           if(toBeRemoved != null)\r
-                               modules.removeAll(toBeRemoved);\r
-                               }\r
-                       });\r
-                       return true;\r
-               }\r
-               else\r
-                       return false;\r
-       }\r
-\r
-       public SimulationResult getSimulationResult() {\r
-               return result;\r
-       }\r
-\r
-       public SysdynResult getSysdynResult() {\r
-               return sysdynResult;\r
-       }\r
-\r
-       public void addResultListener(Runnable listener) {\r
-               synchronized(resultListeners) {\r
-                       resultListeners.add(listener);\r
-               }\r
-       }\r
-\r
-       public void removeResultListener(Runnable listener) {\r
-               synchronized(resultListeners) {\r
-                       resultListeners.remove(listener);\r
-               }\r
-       }\r
-       \r
-       public void resultChanged() {\r
-               synchronized(resultListeners) {\r
-                       for(Runnable listener : resultListeners) {\r
-                               listener.run();\r
-                       }\r
-               }\r
-               \r
-               updateSubscriptions();\r
-       }\r
-\r
-       public void addModificationListener(Runnable listener) {\r
-               synchronized(modificationListeners) {\r
-                       modificationListeners.add(listener);\r
-               }\r
-       }\r
-\r
-       public void removeModificationListener(Runnable listener) {\r
-               synchronized(modificationListeners) {\r
-                       modificationListeners.remove(listener);\r
-               }\r
-       }\r
-\r
-       @Override\r
-       public void domainModified() {\r
-               synchronized(modificationListeners) {\r
-                       for(Runnable listener : modificationListeners)\r
-                               listener.run();\r
-               }\r
-       }\r
-\r
-       @Override\r
-       public void rangeModified() {\r
-       }\r
-\r
-       public Configuration getConfiguration() {\r
-               return configuration;\r
-       }\r
-       \r
-       public Resource getConfigurationResource() {\r
-               return configurationResource;\r
-       }\r
-\r
-       public IMapping getMapping() {\r
-               return mapping;\r
-       }\r
-\r
-       public synchronized IElement getElement(Resource resource) {\r
-               return (IElement)mapping.get(resource);\r
-       }\r
-\r
-       public <T> T getService(Class<T> clazz) {\r
-               synchronized(services) {\r
-                       return clazz.cast(services.get(clazz));\r
-               }\r
-       }\r
-\r
-       public <T> void addService(Class<T> clazz, T service) {\r
-               synchronized(services) {\r
-                       services.put(clazz, service);\r
-               }\r
-       }\r
-\r
-       @Override\r
-       public IExperiment loadExperiment(ReadGraph g, Resource experiment, IExperimentActivationListener listener) {\r
-               \r
-               // Not good. IModel pushes only modelResource and it is assumed that\r
-               // SysdynModel is based on configuration\r
-               if(configurationResource == null && modelResource != null) {\r
-                       SimulationResource simu = SimulationResource.getInstance(g);\r
-                       try {\r
-                               configurationResource = g.getPossibleObject(modelResource, simu.HasConfiguration);\r
-                       } catch (ManyObjectsForFunctionalRelationException e) {\r
-                               e.printStackTrace();\r
-                       } catch (ServiceException e) {\r
-                               e.printStackTrace();\r
-                       } \r
-               }\r
-               \r
-\r
-               try {\r
-                   \r
-                     SysdynResource sr = SysdynResource.getInstance(g);\r
-                       IDynamicExperiment exp;\r
-                       if(g.isInstanceOf(experiment, sr.PlaybackExperiment)) {\r
-                           exp = new SysdynPlaybackExperiment(experiment, modelResource);\r
-                           ((SysdynPlaybackExperiment)exp).init(g);\r
-                       } else if(g.isInstanceOf(experiment, sr.BasicExperiment)) {\r
-                           exp = new SysdynExperiment(experiment, modelResource);\r
-                           ((SysdynExperiment)exp).init(g);\r
-                       } else {\r
-                           return null;\r
-                       }\r
-                       \r
-                       ExperimentRuns.createRun(g.getSession(), experiment, exp, listener, null);\r
-                       if(listener != null)\r
-                               listener.onExperimentActivated(exp);\r
-                       return exp;\r
-               } catch(Exception e) {\r
-                       if(listener != null)\r
-                               listener.onFailure(e);\r
-                       return null;\r
-               }\r
-       }\r
-\r
-       public Collection<SysdynResult> getActiveResults(ReadGraph graph) {\r
-               ArrayList<SysdynResult> results = new ArrayList<SysdynResult>();\r
-\r
-               try {\r
-                       Layer0 l0 = Layer0.getInstance(graph);\r
-                       SysdynResource sr = SysdynResource.getInstance(graph);\r
-                       SimulationResource SIMU = SimulationResource.getInstance(graph);\r
-                       Resource model = graph.getSingleObject(configurationResource, SIMU.IsConfigurationOf);\r
-                       Collection<Resource> experiments = graph.getObjects(model, l0.ConsistsOf);\r
-                       for(Resource experiment : experiments) {\r
-                               Collection<Resource> experimentResults = graph.getObjects(experiment, sr.HasResult);\r
-                               for(Resource result : experimentResults) {\r
-                                       if(graph.hasStatement(result, SIMU.IsActive)) {\r
-                                               SysdynResult sysdynResult = new SysdynResult(\r
-                                                               (String) graph.getPossibleRelatedValue(result, l0.HasLabel),\r
-                                                               (String) graph.getPossibleRelatedValue(result, sr.HasResultFile));\r
-                                               results.add(sysdynResult);\r
-                                       }\r
-                               }\r
-                       }\r
-               } catch (Exception e) {\r
-                       e.printStackTrace();\r
-               }\r
-\r
-               if(getSysdynResult() != null)\r
-                       results.add(0, getSysdynResult() );\r
-\r
-\r
-\r
-               return results;\r
-       }\r
-\r
-       private HashMap<String, String> getInits(Configuration configuration, String prefix) {\r
-               HashMap<String, String> inits = new HashMap<String, String>();\r
-               for (IElement element : configuration.getElements()) {\r
-                       if (element instanceof Module) {\r
-                               Module module = (Module) element;\r
-                               Configuration conf = module.getType().getConfiguration();\r
-                               inits.putAll(getInits(conf, prefix + module.getName() + "."));\r
-                       } else if (element instanceof IndependentVariable) {\r
-                               IndependentVariable variable = (IndependentVariable) element;\r
-                               //FIXME: more general solution?\r
-                               IExpression expression = variable.getExpressions().getExpressions().get(0);\r
-                               if (expression instanceof ParameterExpression) {\r
-                                       Double value = ((ParameterExpression)expression).getValue();\r
-                                       if(value != null)\r
-                                               inits.put(prefix + variable.getName(), "" + value);\r
-                               }\r
-                       }\r
-               }\r
-               return inits;\r
-       }\r
-       \r
-       public File getSimulationDir() {\r
-               if(simulationDir == null) {\r
-                       File modelsDir = Activator.getBundleContext().getDataFile("models");\r
-                       String configName = configuration.getName();\r
-                       List<String> files = Arrays.asList(modelsDir.list());\r
-                       if (files.contains(configName)) {\r
-                               int i = 2;\r
-                               while (files.contains(configName + "_" + i)){\r
-                                       i++;\r
-                               }\r
-                               configName += "_" + i;\r
-                       }\r
-\r
-                       simulationDir  = Activator.getBundleContext().getDataFile("models/" + configName);\r
-                       if (!simulationDir.exists()) {\r
-                               simulationDir.mkdir();\r
-                       }\r
-               }\r
-               return simulationDir;\r
-       }\r
-       \r
-       \r
-       \r
-       \r
-       \r
+//                     System.out.println("== Modelica ends == ");\r
+\r
+            try {\r
+                simulationLocation.exeFile.delete();\r
+                ModelicaManager.buildModel(simulationLocation, monitor);\r
+                previousImportantInits.clear();\r
+                previousImportantInits.put("start value", startTime.toString());\r
+                previousImportantInits.put("stop value", stopTime.toString());\r
+                previousImportantInits.put("method", method);\r
+                previousImportantInits.put("outputFormat", outputFormat);\r
+            } catch (ModelicaException e) {\r
+                if(e.getMessage() != null)\r
+                    monitor.message(e.getMessage());\r
+                monitor.showConsole();\r
+                canceled = true;\r
+                previousModelStructure = "";\r
+            }\r
+        }\r
+\r
+        progressMonitor.worked(1);\r
+\r
+        if(simulationLocation != null && !canceled) {\r
+            // Simulate the model\r
+            progressMonitor.subTask("Simulate model");\r
+            process = ModelicaManager.runModelica(\r
+                    simulationLocation,\r
+                    monitor,\r
+                    inits\r
+                    );\r
+            ModelicaManager.printProcessOutput(process, monitor);\r
+\r
+            Thread resultThread = new Thread() {\r
+                @Override\r
+                public void run() {\r
+                    try {\r
+                        process.waitFor();\r
+\r
+                        if(!canceled) {\r
+                            // Get and store results \r
+                            progressMonitor.worked(1);\r
+                            progressMonitor.subTask("Read results");\r
+                            if(simulationLocation.outputFile.getName().endsWith(".csv"))\r
+                                result = new CSVSimulationResult();\r
+                            else if(simulationLocation.outputFile.getName().endsWith(".plt"))\r
+                                result = new SimulationResult();\r
+                            else\r
+                                result = new MatSimulationResult(); // The latest format\r
+                            result.read(simulationLocation.outputFile);\r
+                            result.readInits(simulationLocation.initFile);\r
+                            result.filter();\r
+                            sysdynResult.setResult(result);\r
+                            progressMonitor.worked(1);\r
+                            resultChanged();\r
+\r
+                            setExperimentStopped(experiment);\r
+\r
+                            String errorString = result.getResultReadErrors();\r
+                            if(errorString != null && !errorString.isEmpty()) \r
+                                monitor.message(errorString);\r
+                        }\r
+                    } catch (FileNotFoundException e) {\r
+                        e.printStackTrace();\r
+                    } catch (IOException e) {\r
+                        e.printStackTrace();\r
+                    } catch (InterruptedException e) {\r
+                        e.printStackTrace();\r
+                    }\r
+                }\r
+            };\r
+            resultThread.run();\r
+        }\r
+        if(canceled)\r
+            setExperimentStopped(experiment);\r
+        process = null;\r
+    }\r
+\r
+    /**\r
+     * Stop an experiment\r
+     * \r
+     * @param experiment Experiment to be stopped\r
+     */\r
+    private void setExperimentStopped(Experiment experiment) {\r
+        if(experiment instanceof SysdynExperiment) {\r
+            SysdynExperiment e = (SysdynExperiment)experiment;\r
+            if(e.getState() != ExperimentState.DISPOSED)\r
+                e.simulate(false);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Method that compares given modelText and inits to previous model and inits \r
+     * @param modelText Textual representation of a model (Modelica code)\r
+     * @param inits map of init parameters\r
+     * @return true if the model has changed, false otherwise\r
+     */\r
+    private boolean hasStructureChanged(String modelText, Map<String, String> inits) {\r
+\r
+        // Compare inits first because it is faster\r
+        for(String key : previousImportantInits.keySet()) {\r
+            if(!inits.containsKey(key) || !previousImportantInits.get(key).equals(inits.get(key)))\r
+                return true;\r
+        }          \r
+\r
+        // Then compare the actual model structure\r
+        BufferedReader current = new BufferedReader(\r
+                new StringReader(modelText));\r
+        BufferedReader previous = new BufferedReader(\r
+                new StringReader(previousModelStructure));\r
+\r
+        String c, p;\r
+        try {\r
+            // Read both current and previous model texts at the same time\r
+            c = current.readLine();\r
+            p = previous.readLine();\r
+\r
+            while (c != null && p != null) {\r
+                // if the lines are the same, no need for further examination\r
+                if(!c.equals(p)) {\r
+                    if(c.contains("parameter") && p.contains("parameter")) {\r
+                        /*\r
+                         *  The line is a parameter definition.\r
+                         *  In this case only what is before '=' matters\r
+                         *  \r
+                         *  parameter Real Var = 1;\r
+                         *     is structurally same as\r
+                         *  parameter Real Var = 2;  \r
+                         */\r
+                        int i = c.indexOf("=");\r
+                        if(!c.substring(0, i).equals(p.substring(0, i))) {\r
+                            // different parameter definition\r
+                            return true;\r
+                        }\r
+                    } else {\r
+                        // other than a line containing parameters differs\r
+                        return true;\r
+                    }\r
+                }\r
+                c = current.readLine();\r
+                p = previous.readLine();\r
+            }\r
+\r
+            if((c == null && p != null) || (c != null && p == null)) {\r
+                // different lengths\r
+                return true;\r
+            }\r
+\r
+        } catch(IOException e) {\r
+            // Something went wrong in the comparison, it is safer to say that the structure has changed \r
+            return true;\r
+        }\r
+        return false;\r
+    }\r
+\r
+    /**\r
+     * Cancel a possible ongoing simulation\r
+     */\r
+    public void cancelSimulation() {\r
+        canceled = true;\r
+        if(process != null) {\r
+            process.destroy();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Update mapping.\r
+     * \r
+     * Use this if inside a transaction.\r
+     * \r
+     * @param graph ReadGraph\r
+     * @return has the range been modified\r
+     * @throws DatabaseException\r
+     */\r
+    public synchronized boolean update(ReadGraph graph) throws DatabaseException {\r
+        if(mapping.isDomainModified()) {\r
+            mapping.updateRange(graph);\r
+\r
+            // Remove all unnecessary module configurations from modules \r
+            Set<Resource> configs = readModules(graph, configurationResource); \r
+            for(Resource config : configs) {\r
+                if(!modules.contains(config))\r
+                    modules.add((Configuration)mapping.map(graph, config));\r
+            }\r
+\r
+            HashSet<Configuration> toBeRemoved = null;\r
+            for(Configuration module : modules) {\r
+                if(!configs.contains(mapping.inverseGet(module))) {\r
+                    if(toBeRemoved == null)\r
+                        toBeRemoved = new HashSet<Configuration>();\r
+                    toBeRemoved.add(module);\r
+                }\r
+            }\r
+            if(toBeRemoved != null)\r
+                modules.removeAll(toBeRemoved);\r
+            return true;\r
+        }\r
+        else\r
+            return false;\r
+    }\r
+\r
+    /**\r
+     * Update mapping.\r
+     * \r
+     * Use only if not inside a transaction\r
+     * @return has range been updated\r
+     * @throws DatabaseException\r
+     */\r
+    public boolean update() throws DatabaseException {\r
+        return session.syncRequest(new Read<Boolean>() {\r
+            @Override\r
+            public Boolean perform(ReadGraph graph) throws DatabaseException {\r
+                return update(graph);\r
+            }\r
+        });\r
+    }\r
+\r
+    public SimulationResult getSimulationResult() {\r
+        return result;\r
+    }\r
+\r
+    public SysdynResult getSysdynResult() {\r
+        return sysdynResult;\r
+    }\r
+\r
+    public void addResultListener(Runnable listener) {\r
+        synchronized(resultListeners) {\r
+            resultListeners.add(listener);\r
+        }\r
+    }\r
+\r
+    public void removeResultListener(Runnable listener) {\r
+        synchronized(resultListeners) {\r
+            resultListeners.remove(listener);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Fires an update to all result listeners and subscriptions\r
+     * after results have changed\r
+     */\r
+    public void resultChanged() {\r
+        synchronized(resultListeners) {\r
+            for(Runnable listener : resultListeners) {\r
+                listener.run();\r
+            }\r
+        }\r
+\r
+        updateSubscriptions();\r
+    }\r
+\r
+    public void addModificationListener(Runnable listener) {\r
+        synchronized(modificationListeners) {\r
+            modificationListeners.add(listener);\r
+        }\r
+    }\r
+\r
+    public void removeModificationListener(Runnable listener) {\r
+        synchronized(modificationListeners) {\r
+            modificationListeners.remove(listener);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Fires all modification listeners after a change in the domain\r
+     */\r
+    @Override\r
+    public void domainModified() {\r
+        synchronized(modificationListeners) {\r
+            for(Runnable listener : modificationListeners)\r
+                listener.run();\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void rangeModified() {\r
+    }\r
+\r
+    public Configuration getConfiguration() {\r
+        return configuration;\r
+    }\r
+\r
+    public Resource getConfigurationResource() {\r
+        return configurationResource;\r
+    }\r
+\r
+    public IMapping getMapping() {\r
+        return mapping;\r
+    }\r
+\r
+    public synchronized IElement getElement(Resource resource) {\r
+        return (IElement)mapping.get(resource);\r
+    }\r
+\r
+    public <T> T getService(Class<T> clazz) {\r
+        synchronized(services) {\r
+            return clazz.cast(services.get(clazz));\r
+        }\r
+    }\r
+\r
+    public <T> void addService(Class<T> clazz, T service) {\r
+        synchronized(services) {\r
+            services.put(clazz, service);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public IExperiment loadExperiment(ReadGraph g, Resource experiment, IExperimentActivationListener listener) {\r
+\r
+        // Make sure that configurationResource exists\r
+        if(configurationResource == null && modelResource != null) {\r
+            SimulationResource simu = SimulationResource.getInstance(g);\r
+            try {\r
+                configurationResource = g.getPossibleObject(modelResource, simu.HasConfiguration);\r
+            } catch (ManyObjectsForFunctionalRelationException e) {\r
+                e.printStackTrace();\r
+            } catch (ServiceException e) {\r
+                e.printStackTrace();\r
+            } \r
+        }\r
+\r
+\r
+        try {\r
+            // Create a new experiment based on the experiment resource type\r
+            SysdynResource sr = SysdynResource.getInstance(g);\r
+            IDynamicExperiment exp;\r
+            if(g.isInstanceOf(experiment, sr.PlaybackExperiment)) {\r
+                exp = new SysdynPlaybackExperiment(experiment, modelResource);\r
+            } else if(g.isInstanceOf(experiment, sr.BasicExperiment)) {\r
+                exp = new SysdynExperiment(experiment, modelResource);\r
+            } else {\r
+                return null;\r
+            }\r
+            \r
+            ((SysdynExperiment)exp).init(g);\r
+\r
+            ExperimentRuns.createRun(g.getSession(), experiment, exp, listener, null);\r
+            if(listener != null)\r
+                listener.onExperimentActivated(exp);\r
+            return exp;\r
+        } catch(Exception e) {\r
+            if(listener != null)\r
+                listener.onFailure(e);\r
+            return null;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Get all active results for this model including the current result and \r
+     * all saved results that are active \r
+     * @param graph ReadGraph\r
+     * @return all active SysdynResults\r
+     */\r
+    public Collection<SysdynResult> getActiveResults(ReadGraph graph) {\r
+        ArrayList<SysdynResult> results = new ArrayList<SysdynResult>();\r
+\r
+        try {\r
+            // Find all active saved results\r
+            Layer0 l0 = Layer0.getInstance(graph);\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            SimulationResource SIMU = SimulationResource.getInstance(graph);\r
+            Resource model = graph.getSingleObject(configurationResource, SIMU.IsConfigurationOf);\r
+            Collection<Resource> experiments = graph.getObjects(model, l0.ConsistsOf);\r
+            for(Resource experiment : experiments) {\r
+                Collection<Resource> experimentResults = graph.getObjects(experiment, sr.HasResult);\r
+                for(Resource result : experimentResults) {\r
+                    if(graph.hasStatement(result, SIMU.IsActive)) {\r
+                        SysdynResult sysdynResult = new SysdynResult(\r
+                                (String) graph.getPossibleRelatedValue(result, l0.HasLabel),\r
+                                (String) graph.getPossibleRelatedValue(result, sr.HasResultFile));\r
+                        results.add(sysdynResult);\r
+                    }\r
+                }\r
+            }\r
+        } catch (Exception e) {\r
+            e.printStackTrace();\r
+        }\r
+\r
+        // Add the current result if there is one\r
+        if(getSysdynResult() != null)\r
+            results.add(0, getSysdynResult() );\r
+\r
+        return results;\r
+    }\r
+\r
+    /**\r
+     * Get all parameters for Configuration\r
+     * \r
+     * @param configuration Configuration\r
+     * @param prefix String prefix of configuration in this model (Module1.Module2...)\r
+     * @return\r
+     */\r
+    private HashMap<String, String> getInits(Configuration configuration, String prefix) {\r
+        HashMap<String, String> inits = new HashMap<String, String>();\r
+        for (IElement element : configuration.getElements()) {\r
+            if (element instanceof Module) {\r
+                Module module = (Module) element;\r
+                Configuration conf = module.getType().getConfiguration();\r
+                inits.putAll(getInits(conf, prefix + module.getName() + "."));\r
+            } else if (element instanceof IndependentVariable) {\r
+                IndependentVariable variable = (IndependentVariable) element;\r
+                //FIXME: more general solution for finding out if the variable is a parameter\r
+                IExpression expression = variable.getExpressions().getExpressions().get(0);\r
+                if (expression instanceof ParameterExpression) {\r
+                    Double value = ((ParameterExpression)expression).getValue();\r
+                    if(value != null)\r
+                        inits.put(prefix + variable.getName(), "" + value);\r
+                }\r
+            }\r
+        }\r
+        return inits;\r
+    }\r
+\r
+    /**\r
+     * Get a simulation directory for this model\r
+     * @return File directory\r
+     */\r
+    public File getSimulationDir() {\r
+        if(simulationDir == null) {\r
+            File modelsDir = Activator.getBundleContext().getDataFile("models");\r
+            String configName = configuration.getName();\r
+            List<String> files = Arrays.asList(modelsDir.list());\r
+            if (files.contains(configName)) {\r
+                int i = 2;\r
+                while (files.contains(configName + "_" + i)){\r
+                    i++;\r
+                }\r
+                configName += "_" + i;\r
+            }\r
+\r
+            simulationDir  = Activator.getBundleContext().getDataFile("models/" + configName);\r
+            if (!simulationDir.exists()) {\r
+                simulationDir.mkdir();\r
+            }\r
+        }\r
+        return simulationDir;\r
+    }\r
+\r
+\r
     /**\r
      * Copy from AprosExperiment\r
      * @param subscription\r
@@ -629,7 +716,7 @@ public class SysdynModel implements IMappingListener, IModel {
             variableValueSubscriptionsSnapshot = null;\r
         }\r
     }\r
-    \r
+\r
     /**\r
      * Copy from AprosExperiment\r
      * @param subscription\r
index 3b41fedae6e5223f7a7bac90da3e060c6f11f93e..9fbacbb3aceca83c76bdd16317eccd357d7d1a77 100644 (file)
@@ -14,7 +14,6 @@ package org.simantics.sysdyn.manager;
 \r
 import java.io.File;\r
 import java.io.IOException;\r
-import java.util.ArrayList;\r
 import java.util.List;\r
 import java.util.TreeMap;\r
 \r
@@ -44,15 +43,27 @@ import org.simantics.databoard.type.Datatype;
 import org.simantics.modelica.data.DataSet;\r
 import org.simantics.modelica.data.SimulationResult;\r
 \r
+/**\r
+ * Class for containing the accessor for a sysdyn simulation result\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
 public class SysdynResult {\r
 \r
     RecordAccessor accessor;\r
     String resultName;\r
 \r
+    /**\r
+     * Create an empty result\r
+     */\r
     public SysdynResult() {\r
 \r
     }\r
 \r
+    /**\r
+     * Create a sysdynresult accessor using a {@link SimulationResult}\r
+     * @param result\r
+     */\r
     public SysdynResult(SimulationResult result) {\r
         if(result != null)\r
             setResult(result);\r
@@ -76,10 +87,18 @@ public class SysdynResult {
         } \r
     }\r
 \r
+    /**\r
+     * Get the {@link RecordAccessor} of this result\r
+     * @return {@link RecordAccessor} for this result\r
+     */\r
     public Accessor getAccessor() {\r
         return accessor;\r
     }\r
 \r
+    /**\r
+     * Create a {@link RecordAccessor} for this result based on a {@link SimulationResult}\r
+     * @param result {@link SimulationResult}\r
+     */\r
     public void setResult(SimulationResult result) {\r
         try {\r
             // Create Memory Historian\r
@@ -114,6 +133,12 @@ public class SysdynResult {
         } \r
     }\r
 \r
+    /**\r
+     * Create a recording for a variable to this result's {@link RecordAccessor} \r
+     * @param ds {@link DataSet} for the variable\r
+     * @return {@link Recording}\r
+     * @throws BindingException\r
+     */\r
     @SuppressWarnings("unchecked")\r
     Recording createRecording(DataSet ds) throws BindingException {\r
         RecordBinding recordingBinding = (RecordBinding) Bindings.getBindingUnchecked( Recording.class );\r
@@ -125,15 +150,20 @@ public class SysdynResult {
         TreeMap<Double, Double> segment = new TreeMap<Double, Double>();\r
         recording.segments = new TreeMap[] { segment };\r
 \r
-        int length = ds.values.size();\r
+        int length = ds.values.length;\r
         for (int i=0; i<length; i++) {\r
-            double time = ds.times.get(i);\r
-            double value = ds.values.get(i);\r
+            double time = ds.times[i];\r
+            double value = ds.values[i];\r
             segment.put(time, value);                      \r
         }\r
         return recording;\r
     }\r
 \r
+    /**\r
+     * Save current {@link RecordAccessor} to a {@link File}\r
+     * \r
+     * @param file {@link File} where the {@link RecordAccessor} is saved\r
+     */\r
     public void saveToFile(File file) {\r
         if(accessor == null) return;\r
         try {\r
@@ -160,12 +190,22 @@ public class SysdynResult {
 \r
     }\r
 \r
+    /**\r
+     * Class representing a recording for a variable\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
     public static class Recording {\r
         public Variant nodeId;\r
         public @Arguments({String.class, String.class}) TreeMap<String, String> labels;\r
         public @Arguments({TreeMap.class, Double.class, Double.class}) TreeMap<Double, Double>[] segments;\r
     }\r
 \r
+    /**\r
+     * Get dataset for a named variable\r
+     * @param variable The name of the variable\r
+     * @return {@link SysdynDataSet}\r
+     */\r
     public SysdynDataSet getDataSet(String variable) {\r
         if(accessor != null) {\r
             try {\r
@@ -184,11 +224,11 @@ public class SysdynResult {
 \r
                 ma.getAll(Bindings.DOUBLE, Bindings.DOUBLE, times, values);\r
 \r
-                List<Double> times_ = new ArrayList<Double>(size);\r
-                List<Double> values_ = new ArrayList<Double>(size);\r
+                double[] times_ = new double[size];\r
+                double[] values_ = new double[size];\r
                 for (int i=0; i<size; i++) {\r
-                    times_.add(i, times[i]);\r
-                    values_.add(i, values[i]);\r
+                    times_[i] = times[i];\r
+                    values_[i] = values[i];\r
                 }\r
 \r
                 return new SysdynDataSet(variable, resultName, times_, values_);\r