]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
* Optimized simulation result read: The result file is indexed after running the...
authormiettinen <miettinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Fri, 7 Dec 2012 12:12:13 +0000 (12:12 +0000)
committermiettinen <miettinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Fri, 7 Dec 2012 12:12:13 +0000 (12:12 +0000)
* Fixing a bug of output interval rounding up instead of rounding to the nearest.

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@26510 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.modelica/src/org/simantics/modelica/data/MatSimulationResult.java
org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java
org.simantics.modelica/src/org/simantics/modelica/reader/MatFileReader.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiment.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynResult.java

index 9e8a9c76e2705deacbc5cf0e5d4ce88d1a1705cc..d748ffe72d8c5a376bcd521067b8d8de00c057ed 100644 (file)
  *******************************************************************************/\r
 package org.simantics.modelica.data;\r
 \r
+import java.io.File;\r
+import java.io.FileNotFoundException;\r
 import java.io.IOException;\r
 import java.io.InputStream;\r
 import java.util.Map;\r
 \r
+import org.simantics.modelica.reader.MatFileReader;\r
+\r
 /**\r
  * SimulationResult for Mat-formatted simulations results\r
  *  \r
  * @author Teemu Lempinen\r
  *\r
  */\r
+\r
 public class MatSimulationResult extends SimulationResult {\r
     \r
     @Override\r
@@ -47,4 +52,10 @@ public class MatSimulationResult extends SimulationResult {
             }\r
         }\r
     }\r
+    \r
+    @Override\r
+    public void initRead(File file) throws FileNotFoundException, IOException {\r
+        super.initRead(file);\r
+        resultFileReader = new MatFileReader(file);\r
+    }\r
 }\r
index 03325da6f77947a199582532798c2cb0882f7714..355378778601e36b02e6125d91f0acedb934dd79 100644 (file)
@@ -33,6 +33,7 @@ import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathExpressionException;\r
 import javax.xml.xpath.XPathFactory;\r
 \r
+import org.simantics.modelica.reader.ResultFileReader;\r
 import org.w3c.dom.Document;\r
 import org.w3c.dom.Node;\r
 import org.w3c.dom.NodeList;\r
@@ -53,6 +54,9 @@ public class SimulationResult {
     protected List<DataSet> variables = new ArrayList<DataSet>();\r
     protected List<DataSet> initials = new ArrayList<DataSet>();\r
     protected int numberOfLines = 0;\r
+    protected ResultFileReader resultFileReader;\r
+    protected double[] allTimes;\r
+    protected int skip;\r
 \r
     /**\r
      * Private class used in displaying errors\r
@@ -263,8 +267,6 @@ public class SimulationResult {
         }\r
     }\r
 \r
-\r
-\r
     /**\r
      * Read result file. Read all values in the result file.\r
      * \r
@@ -276,16 +278,28 @@ public class SimulationResult {
         read(file, 1);\r
     }\r
 \r
-\r
     /**\r
-     * Read result file\r
+     * Initialize result file reading and read the whole result file\r
      * \r
      * @param file result file\r
      * @param interval the interval of results to be read. 1 reads all time steps, 2 reads every other time step, etc...\r
      * @throws FileNotFoundException\r
      * @throws IOException\r
      */\r
-    public void read(File file, int interval) throws FileNotFoundException, IOException {\r
+   public void read(File file, int interval) throws FileNotFoundException, IOException {\r
+        initRead(file);\r
+        readAll(file, interval);\r
+    }\r
+\r
+   /**\r
+    * Initialize result file reading\r
+    * \r
+    * @param file result file\r
+    * @param interval the interval of results to be read. 1 reads all time steps, 2 reads every other time step, etc...\r
+    * @throws FileNotFoundException\r
+    * @throws IOException\r
+    */\r
+  public void initRead(File file) throws FileNotFoundException, IOException {\r
         // First check the number of time steps.\r
         // With *.mat result file this is not necessary\r
         if (!(this instanceof MatSimulationResult)) {\r
@@ -296,13 +310,24 @@ public class SimulationResult {
             lnr.close();\r
             fr.close();\r
         }\r
+    }\r
+    \r
+    /**\r
+     * Read the whole result file\r
+     * \r
+     * @param file result file\r
+     * @param interval the interval of results to be read. 1 reads all time steps, 2 reads every other time step, etc...\r
+     * @throws FileNotFoundException\r
+     * @throws IOException\r
+     */\r
+   public void readAll(File file, int interval)  throws FileNotFoundException, IOException {\r
         InputStream is = openStream(file);\r
-        //InputStream is = new FileInputStream(file);\r
         read(is, interval);\r
         is.close();\r
     }\r
 \r
-    private InputStream openStream(File file) throws FileNotFoundException {\r
+\r
+    protected InputStream openStream(File file) throws FileNotFoundException {\r
         return new BufferedInputStream(new FileInputStream(file));\r
     }\r
 \r
@@ -410,4 +435,40 @@ public class SimulationResult {
         }\r
         return errorString.toString();\r
     }\r
+\r
+    /**\r
+     * Read a defined variable from result file\r
+     * \r
+     * @param file result file\r
+     * @param interval the interval of results to be read. 1 reads all time steps, 2 reads every other time step, etc...\r
+     * @throws FileNotFoundException\r
+     * @throws IOException\r
+     */\r
+    public void readVariable(String variable, File file) throws FileNotFoundException, IOException {\r
+        DataSet ds;\r
+        List<String> names = resultFileReader.getNames();\r
+        if (names.contains(variable)) {\r
+            double[] resArray = resultFileReader.readData(variable, 0, allTimes.length, skip);\r
+            ds = new DataSet(variable, allTimes, resArray);\r
+            variables.add(ds);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Read time array from result file\r
+     * \r
+     * @param file result file\r
+     * @param interval the interval of results to be read. 1 reads all time steps, 2 reads every other time step, etc...\r
+     * @throws FileNotFoundException\r
+     * @throws IOException\r
+     */\r
+    public void readTime(File file, int interval) throws FileNotFoundException, IOException {\r
+        skip = interval - 1;\r
+        int totalCount = resultFileReader.getCount("time");\r
+        int count = totalCount / interval;\r
+        if (totalCount % interval != 0)\r
+            count++;\r
+        allTimes = resultFileReader.readData("time", 0, count, skip); \r
+    }\r
+\r
 }\r
index 111842798ade82bd5924efbe52e8323550e2d665..afb7a0b7a45ee713b026f9d8a02c7db4cbbedec5 100644 (file)
@@ -19,10 +19,12 @@ import org.simantics.modelica.data.StringMatrix;
 import org.simantics.utils.datastructures.MapList;\r
 \r
 public class MatFileReader implements ResultFileReader {\r
-       private File file;\r
+       private final File file;\r
        \r
-       private List<String> names = new ArrayList<String>();\r
-       private Map<String, Integer> indices = new HashMap<String, Integer>();\r
+       private final List<String> names = new ArrayList<String>();\r
+       private final Map<String, Integer> indices = new HashMap<String, Integer>();\r
+       \r
+       private HashMap<String, double[]> parameterValues;\r
        \r
        \r
        long readBytes = 0; // tracking read data\r
@@ -38,22 +40,29 @@ public class MatFileReader implements ResultFileReader {
                readVariables();\r
        }\r
        \r
-       public List<String> getNames() {\r
+       @Override\r
+    public List<String> getNames() {\r
                return names;\r
        }\r
        \r
        \r
-       public int getCount(String item) {\r
+       @Override\r
+    public int getCount(String item) {\r
                return dataHeader.columns;\r
        }\r
        /**\r
         * Reads all data of a given item\r
         */\r
-       public double[] readData(String item) throws IOException {\r
+       @Override\r
+    public double[] readData(String item) throws IOException {\r
                readBytes = 0;\r
                Integer index = indices.get(item);\r
                if (index == null)\r
-                       throw new IOException("Unknown item: " + item);\r
+                   if (parameterValues.containsKey(item)) {\r
+                       return parameterValues.get(item);\r
+                   } else {\r
+                       throw new IOException("Unknown item: " + item);\r
+                   }\r
                InputStream in = openStream();\r
                skip(dataMark, in);\r
                \r
@@ -74,11 +83,16 @@ public class MatFileReader implements ResultFileReader {
         * @return\r
         * @throws IOException\r
         */\r
-       public double[] readData(String item, int start, int count, int skip) throws IOException {\r
+       @Override\r
+    public double[] readData(String item, int start, int count, int skip) throws IOException {\r
                readBytes = 0;\r
                Integer index = indices.get(item);\r
                if (index == null)\r
-                       throw new IOException("Unknown item: " + item);\r
+               if (parameterValues.containsKey(item)) {\r
+                       return parameterValues.get(item);\r
+               } else {\r
+                   throw new IOException("Unknown item: " + item);\r
+               }\r
                InputStream in = openStream();\r
                skip(dataMark, in);\r
                \r
@@ -90,13 +104,16 @@ public class MatFileReader implements ResultFileReader {
 \r
        }\r
        \r
-       public double[][] readData(List<String> items) throws IOException {\r
-               readBytes = 0;\r
+       @Override\r
+    public double[][] readData(List<String> items) throws IOException {\r
+           readBytes = 0;\r
                List<Integer> indexes = new ArrayList<Integer>(items.size());\r
                for (String item : items) {\r
                        Integer index = indices.get(item);\r
                        if (index == null)\r
-                               throw new IOException("Unknown item: " + item);\r
+                           // Parameters cannot be accessed via this method; instead, \r
+                           // methods with only a single item should be used\r
+                       throw new IOException("Unknown item: " + item);\r
                        indexes.add(index);\r
                }\r
                \r
@@ -126,7 +143,9 @@ public class MatFileReader implements ResultFileReader {
                for (String item : items) {\r
                        Integer index = indices.get(item);\r
                        if (index == null)\r
-                               throw new IOException("Unknown item: " + item);\r
+                           // Parameters cannot be accessed via this method; instead, \r
+                // methods with only a single item should be used\r
+                throw new IOException("Unknown item: " + item);\r
                        indexes.add(index);\r
                }\r
                \r
@@ -164,7 +183,10 @@ public class MatFileReader implements ResultFileReader {
        \r
         infoData = info.data;\r
         \r
-        readMatrix(in); // Some result data matrix?\r
+        //Read parameters\r
+        parameterValues = new HashMap<String, double[]>();\r
+        DoubleMatrix parameters = (DoubleMatrix)readMatrix(in); // Some result data matrix?\r
+        readDoubleMatrix(parameters, names, 1, 1, info, 1, parameterValues);\r
         \r
         dataHeader = new MatrixHeader(in);\r
         \r
@@ -175,7 +197,8 @@ public class MatFileReader implements ResultFileReader {
         // filter incompatible? data.\r
         for (int i = this.names.size() -1; i >=  0; i--) {\r
                if (infoData[i * 4] != 2) {\r
-                       String name = this.names.remove(i);\r
+                       String name = this.names.get(i);\r
+                       // Remove parameters from indices but not from names list\r
                        this.indices.remove(name);\r
                }\r
                        \r
@@ -340,7 +363,7 @@ public class MatFileReader implements ResultFileReader {
                if (infoData[row * 4] != 2)\r
                        throw new IOException();  // this is checked in initialization phase.\r
                int size = header.columns;\r
-               if (start+count*(skip+1) > size)\r
+               if (start+count*(skip+1)-skip > size)\r
                        throw new IndexOutOfBoundsException(); // TODO: we could just read available data, instead of throwing exception.\r
                int rows = header.rows;\r
                double[] v = new double[count];\r
@@ -413,7 +436,7 @@ public class MatFileReader implements ResultFileReader {
                \r
                \r
 \r
-       skip((long)c[0] * 8L, in);\r
+       skip(c[0] * 8L, in);\r
        for (int j = 0; j < size; ++j) {\r
                for (int index = 0; index < sortedRows.size(); index++) {\r
                                \r
@@ -533,7 +556,7 @@ public class MatFileReader implements ResultFileReader {
                \r
                \r
                long s = start;\r
-               s *= (long)rows;\r
+               s *= rows;\r
                s *= 8L;\r
                skip(s, in);\r
        skip(c[0] * 8, in);\r
@@ -592,6 +615,31 @@ public class MatFileReader implements ResultFileReader {
        }\r
     }\r
     \r
+    private static void readDoubleMatrix(DoubleMatrix matrix, StringMatrix names, int dataMatrixNumber, int startIndex, IntMatrix info, int outputInterval, HashMap<String, double[]> result) {\r
+        double[] valueData = matrix.data;\r
+        int[] infoData = info.data;\r
+        int rows = matrix.rows;\r
+        //System.out.println("cols="+values.columns+", rows=" +values.rows+ ", data.length="+valueData.length);\r
+\r
+        for(int i=startIndex;i<info.columns;++i) {\r
+            if(infoData[i*4] != dataMatrixNumber)\r
+                continue;\r
+            // If values.columns % outputInterval != 0, the value in the last time step would not be displayed without adding a +1;\r
+            int size = matrix.columns % outputInterval != 0 ? matrix.columns / outputInterval + 1 : matrix.columns; \r
+            double[] v = new double[size];\r
+            int sc = infoData[i*4+1];\r
+            int c = sc > 0 ? sc-1 : -sc-1;\r
+            //System.out.println("i=" + i + ", sc=" + sc + ", c=" + c);\r
+            for(int j=0;j<v.length;++j) {\r
+                int adjusted = j * outputInterval;\r
+                if(adjusted >= matrix.columns) adjusted = matrix.columns - 1;\r
+                v[j] = valueData[rows * adjusted + 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
+    }\r
     \r
     private class MatrixHeader {\r
        \r
index 1337083c4a326929956f11bb6e7813d06a3948e1..11ed3155e7f1f484a3545d6a44be843b0700d58e 100644 (file)
@@ -316,19 +316,25 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment,
                         String outputInterval = experimentParameters.get(ModelicaKeys.OUTPUT_INTERVAL);\r
                         if(outputInterval != null) {\r
                             String stepTime = experimentParameters.get(ModelicaKeys.STEP_VALUE);\r
-\r
+                            String stopTime = experimentParameters.get(ModelicaKeys.STOP_VALUE);\r
+                            \r
                             Double step = Double.parseDouble(stepTime);\r
+                            Double stop = Double.parseDouble(stopTime);\r
                             Double outInterval = Double.parseDouble(outputInterval);\r
 \r
-                            double nearest = roundUp(outInterval, step);\r
-                            outIntervalInt = (int)(nearest / step);\r
-                            if(outIntervalInt <= 0) outIntervalInt = 1;\r
+                            outIntervalInt = (int)getInterval(outInterval, step);\r
+                            // Actually you might be able to use an outInterval one or two longer. \r
+                            int maxIntervalInt = (int)Math.round(stop / step);\r
+                            if (outIntervalInt > maxIntervalInt)\r
+                                outIntervalInt = maxIntervalInt;\r
                         }\r
 \r
-                        result.read(simulationLocation.resFile, outIntervalInt);\r
+                        result.initRead(simulationLocation.resFile);\r
+                        result.readTime(simulationLocation.resFile, outIntervalInt);\r
                         //result.readInits(simulationLocation.initFile); // Parameter values are read from .mat\r
                         result.filter();\r
                         getCurrentResult().setResult(result);\r
+                        getCurrentResult().setResultFile(simulationLocation.resFile);\r
                         progressMonitor.worked(1);\r
                         resultsChanged();\r
 \r
@@ -349,15 +355,11 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment,
         };\r
     }\r
 \r
-    protected static double roundUp(double numToRound, double multiple) {\r
-        if(multiple == 0) {\r
-            return numToRound;\r
-        }\r
-        double remainder = numToRound % multiple;\r
-        if (remainder == 0) {\r
-            return numToRound;\r
-        }\r
-        return numToRound + multiple - remainder;\r
+    protected static long getInterval(double outputLength, double stepLength) {\r
+        double interval = outputLength / stepLength;\r
+        if (interval <= 1)\r
+            return 1;\r
+        return Math.round(interval);\r
     }\r
 \r
 \r
index 11706465ab9fab0f1ad7cb31b9fabad855dfeeac..defa0977607a26a0b15a1c622dfa0fff34882130 100644 (file)
@@ -25,12 +25,12 @@ import org.simantics.db.Resource;
 import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.db.procedure.AsyncListener;\r
 import org.simantics.db.request.Read;\r
+import org.simantics.fmu.FMUControlJNI;\r
+import org.simantics.fmu.FMUJNIException;\r
 import org.simantics.modelica.IModelicaMonitor;\r
 import org.simantics.modelica.SimulationLocation;\r
 import org.simantics.modelica.data.DataSet;\r
 import org.simantics.modelica.data.SimulationResult;\r
-import org.simantics.fmu.FMUControlJNI;\r
-import org.simantics.fmu.FMUJNIException;\r
 import org.simantics.simulation.experiment.ExperimentState;\r
 import org.simantics.sysdyn.SysdynResource;\r
 import org.simantics.utils.datastructures.Triple;\r
@@ -113,9 +113,7 @@ public class SysdynGameExperiment extends SysdynExperiment {
                                if(result.third == null) {\r
                                        setOutputInterval(DEFAULT_OUTPUT_INTERVAL);\r
                                } else {\r
-                                       double nearest = roundUp(result.third, getStepLength());\r
-                                       int interval = (int)(nearest / getStepLength());\r
-                                       if(interval <= 0) interval = 1;\r
+                                       int interval = (int)getInterval(result.third, getStepLength());\r
                                        setOutputInterval(interval);\r
                                }\r
                        }\r
@@ -229,7 +227,7 @@ public class SysdynGameExperiment extends SysdynExperiment {
        private class simulateDurationJob extends Job {\r
 \r
                private double duration;\r
-               private SysdynGameExperiment experiment;\r
+               private final SysdynGameExperiment experiment;\r
                public simulateDurationJob(String name, SysdynGameExperiment experiment, double duration) {\r
                        super(name);\r
                        this.duration = duration;\r
index 3533d6a981f1f059183a865ccf5c5ad050216ec4..7a1b29c94d12e555c7b7c9ef81286600a465f9e0 100644 (file)
@@ -13,6 +13,7 @@ package org.simantics.sysdyn.manager;
 \r
 \r
 import java.io.File;\r
+import java.io.FileNotFoundException;\r
 import java.io.IOException;\r
 import java.util.List;\r
 import java.util.TreeMap;\r
@@ -54,6 +55,7 @@ public class SysdynResult {
        protected RecordAccessor accessor;\r
        protected String resultName;\r
     private SimulationResult simulationResult;\r
+    private File resultFile;\r
 \r
        /**\r
         * Create an empty result\r
@@ -301,7 +303,20 @@ public class SysdynResult {
                            try {\r
                                         ma = accessor.getComponent( ref );\r
                                } catch (AccessorConstructionException e) {\r
-                                       // Variable was not found, so add it and try again\r
+                                       // Variable was not found, so read it from file\r
+                                   try {\r
+                        simulationResult.readVariable(variable, resultFile);\r
+                    } catch (FileNotFoundException e1) {\r
+                        // Unable to read data from OpenModelica result file\r
+                        System.err.println("Variable " + variable + " not found in OpenModelica result file");\r
+                        return null;\r
+                    } catch (IOException e1) {\r
+                        // IoFail\r
+                        e1.printStackTrace();\r
+                        return null;\r
+                    }\r
+                                   \r
+                                   // Add the read item\r
                                    addDataSet(variable);\r
                        try {\r
                            ma = accessor.getComponent( ref );\r
@@ -339,4 +354,8 @@ public class SysdynResult {
     public int numberOfVariables() {\r
         return simulationResult.getVariableDataSets().size();\r
     }\r
+\r
+    public void setResultFile(File resFile) {\r
+        this.resultFile = resFile;\r
+    }\r
 }\r