import java.io.FileInputStream;\r
import java.io.FileNotFoundException;\r
import java.io.FileWriter;\r
-import java.io.FilenameFilter;\r
import java.io.IOException;\r
import java.io.InputStream;\r
import java.io.InputStreamReader;\r
import org.simantics.modelica.preferences.OpenModelicaPreferences;\r
import org.w3c.dom.Document;\r
import org.w3c.dom.Node;\r
-import org.xml.sax.InputSource;\r
import org.xml.sax.SAXException;\r
\r
/**\r
\r
public static final String OMC_VERSION = "OMC_VERSION"; \r
public static final String RESULT_FILE_NAME = "RESULT_FILE_NAME"; \r
-\r
- /**\r
- * Get operating system type\r
- * \r
- * @return OSType\r
- */\r
- private static OSType getOSType() {\r
- String osName = System.getProperty("os.name").toLowerCase();\r
- \r
- if (osName.startsWith("mac os x"))\r
- return OSType.APPLE;\r
- else if (osName.startsWith("linux"))\r
- return OSType.LINUX;\r
- else if (osName.startsWith("sun"))\r
- return OSType.SUN;\r
- else if (osName.startsWith("windows"))\r
- return OSType.WINDOWS;\r
- \r
- return OSType.UNKNOWN;\r
- }\r
\r
private static boolean onWindows() {\r
return System.getProperty("os.name").toLowerCase().startsWith("windows");\r
}\r
\r
public static boolean isOldOMVersion() {\r
- try {\r
- double version = Double.parseDouble(getOMVersion(getOMHome()).substring(0, 3));\r
- return version < 1.9;\r
- }\r
- catch (NumberFormatException e) {\r
- // if the version string could not be parsed, assume that the \r
- // version sufficiently new\r
- return false;\r
- }\r
+ // TODO: old versions are not supported anymore so any checks for them should be removed\r
+ return false;\r
}\r
\r
/**\r
thread.run();\r
}\r
\r
- public static SimulationLocation createSimulationLocation(File modelDir, String modelName, String modelContent, File omHome, boolean isOldOMVersion) { \r
+ public static SimulationLocation createSimulationLocation(File modelDir, String modelName, String modelContent) { \r
if (!modelDir.isDirectory()) {\r
return null;\r
}\r
}\r
\r
// full model files are (apparently) only needed for old parameter comparison routines\r
- if (isOldOMVersion) {\r
+ if (isOldOMVersion()) {\r
location.fullModelDir = new File(location.getModelDir(), "fullModel");\r
if (!location.fullModelDir.isDirectory()) {\r
location.fullModelDir.mkdir();\r
location.fullModelScriptFile = new File(location.fullModelDir, location.getModelName() + "_full.mos");\r
}\r
\r
- location.omHome = omHome;\r
+ location.omHome = getOMHome();\r
\r
return location;\r
}\r
*/\r
public static Process runModelica(SimulationLocation location, IModelicaMonitor monitor, HashMap<String, String> experimentParameters, HashMap<String, String> parameterChanges) throws IOException {\r
ArrayList<String> commands = new ArrayList<String>();\r
- try {\r
- if(experimentParameters.get(RESULT_FILE_NAME) != null) {\r
- commands.add("-r="+experimentParameters.get(RESULT_FILE_NAME));\r
- }\r
-\r
- // Write new initial values (parameters). No need to update xml if structure has changed. In that case also xml is up-to-date\r
- if(parameterChanges != null) {\r
- String version = experimentParameters.get(OMC_VERSION);\r
- // TODO: clean up\r
- if(version == null)\r
- version = getOMVersion(location.omHome);\r
-\r
- Double versionNumber = 1.9;\r
- try {\r
- versionNumber = Double.parseDouble(version.substring(0,3));\r
- } catch (NumberFormatException e) {}\r
-\r
- if(versionNumber < 1.9) {\r
- writeInits(location, experimentParameters, null);\r
- } else {\r
- // Handled in experiment\r
- if(parameterChanges.size() == 1) {\r
- commands.add("-override");\r
- commands.add(parameterChanges.keySet().iterator().next() + "=" + parameterChanges.values().iterator().next());\r
- } else {\r
- // FIXME: if you change 1 parameter AND some experiment parameters, only the parameter change takes effect\r
- updateInitFile(location, experimentParameters, parameterChanges);\r
- }\r
- }\r
-\r
- }\r
- \r
- }\r
- catch (Exception e) {\r
- e.printStackTrace();\r
+ \r
+ if(experimentParameters.get(RESULT_FILE_NAME) != null) {\r
+ commands.add("-r="+experimentParameters.get(RESULT_FILE_NAME));\r
}\r
\r
+ // update parameter changes\r
+ updateInitFile(location, experimentParameters, parameterChanges);\r
+ \r
// Commands to String[]\r
String[] commandString = new String[commands.size()];\r
for (int i = 0; i < commands.size(); ++i)\r
return result;\r
}\r
\r
-\r
- /**\r
- * Updates inits.xml with the latest values. This is not needed if the model structure\r
- * has changed. When model structure is changed, the model is compiled and a new xml is \r
- * created.\r
- * \r
- * Works with version 1.8.1 and previous versions. 1.9 version does not support this, since\r
- * the init.xml file format has been changed. With 1.9, use updateInitFile()\r
- * \r
- * @param simulationLocation Location of the model\r
- * @param monitor \r
- */\r
- private static void writeInits(SimulationLocation simulationLocation, HashMap<String, String> experimentParameters, IModelicaMonitor monitor) {\r
-\r
- try {\r
- // Create the full model code into one file\r
- buildFullModel(simulationLocation, null);\r
-\r
- // Create simulation files from the full description\r
- ArrayList<String> parameters = new ArrayList<String>();\r
- parameters.add("-s");\r
- parameters.add(simulationLocation.fullModelFile.getAbsolutePath());\r
-\r
- Process process = runOMC(simulationLocation.omHome, simulationLocation.fullModelDir, "-s", simulationLocation.fullModelFile.getAbsolutePath());\r
-\r
- process.waitFor();\r
-\r
- // Find the new init file\r
- FilenameFilter initFilter = new FilenameFilter() {\r
- @Override\r
- public boolean accept(File dir, String name) {\r
- if(name.endsWith("_init.xml"))\r
- return true;\r
- else\r
- return false;\r
- }\r
- };\r
-\r
- File initFile = null;\r
- for(File f : simulationLocation.fullModelDir.listFiles(initFilter)) {\r
- initFile = f;\r
- break;\r
- }\r
-\r
- if(initFile != null && initFile.isFile()) {\r
- // Replace original init contents with the new contents\r
- replaceInitFileContents(simulationLocation.initFile.getAbsolutePath(), initFile.getAbsolutePath(), experimentParameters);\r
- }\r
-\r
- } catch (ModelicaException e) {\r
- e.printStackTrace();\r
- } catch (InterruptedException e) {\r
- e.printStackTrace();\r
- }\r
- }\r
-\r
- /**\r
- * Replaces variable and experiment information from oldFile with contents of newFile.\r
- * \r
- * The file is not simply replaced because guid must match with guid in created exe.\r
- * \r
- * @param oldFile old init.xml\r
- * @param newFile new init.xml\r
- */\r
- private static void replaceInitFileContents(String oldFile, String newFile, HashMap<String, String> experimentParameters) {\r
- try {\r
- XPath xpath = XPathFactory.newInstance().newXPath();\r
-\r
- Document oldInit = DocumentBuilderFactory.newInstance()\r
- .newDocumentBuilder().parse(new InputSource(oldFile));\r
- Document newInit = DocumentBuilderFactory.newInstance()\r
- .newDocumentBuilder().parse(new InputSource(newFile));\r
-\r
- // Find the original model description. This will be modified\r
- Node oldModelDescription = (Node)xpath.evaluate("fmiModelDescription", oldInit, XPathConstants.NODE);\r
-\r
- //\r
- // VARIABLES\r
- //\r
- // First, remove old model variables\r
- Node oldModelVariables = (Node)xpath.evaluate("fmiModelDescription/ModelVariables", oldInit, XPathConstants.NODE);\r
- \r
- oldModelDescription.removeChild(oldModelVariables);\r
-\r
- // Second, find variables in the new model description\r
- Node newModelVariables = (Node)xpath.evaluate("fmiModelDescription/ModelVariables", newInit, XPathConstants.NODE);\r
-\r
- // Import new variables to old xml\r
- Node importedModelVariables = oldInit.importNode(newModelVariables, true);\r
- oldModelDescription.appendChild(importedModelVariables);\r
-\r
- //\r
- // EXPERIMENT PARAMETERS\r
- //\r
- for(String key : experimentParameters.keySet()) {\r
- // Find parameter\r
- Node parameter = (Node)xpath.evaluate\r
- ("fmiModelDescription/DefaultExperiment/@" + key,\r
- oldInit, \r
- XPathConstants.NODE);\r
-\r
- if(parameter != null) {\r
- // Change parameter value\r
- parameter.setNodeValue(experimentParameters.get(key));\r
- }\r
- }\r
-\r
- // Write transformed init.xml\r
- Transformer xformer = TransformerFactory.newInstance().newTransformer();\r
- xformer.transform(new DOMSource(oldInit), new StreamResult(new File(oldFile)));\r
-\r
- } catch (SAXException e) {\r
- e.printStackTrace();\r
- } catch (IOException e) {\r
- e.printStackTrace();\r
- } catch (ParserConfigurationException e) {\r
- e.printStackTrace();\r
- } catch (XPathExpressionException e) {\r
- e.printStackTrace();\r
- } catch (TransformerConfigurationException e) {\r
- e.printStackTrace();\r
- } catch (TransformerFactoryConfigurationError e) {\r
- e.printStackTrace();\r
- } catch (TransformerException e) {\r
- e.printStackTrace();\r
- }\r
- }\r
-\r
/**\r
* Updates init file contents with the given experiment and variable changes.\r
* \r
* @param simulationLocation Location of simulation files\r
* @param experimentParameters Experiment parameters\r
- * @param changes Parameter variable changes\r
+ * @param parameterChanges Parameter variable changes\r
*/\r
- public static void updateInitFile(SimulationLocation simulationLocation, HashMap<String, String> experimentParameters, HashMap<String, String> changes) {\r
+ public static void updateInitFile(SimulationLocation simulationLocation, HashMap<String, String> experimentParameters, HashMap<String, String> parameterChanges) {\r
try {\r
XPath xpath = XPathFactory.newInstance().newXPath();\r
\r
//\r
// PARAMETER VARIABLES\r
//\r
- for(String name : changes.keySet()) {\r
+ for(String name : parameterChanges.keySet()) {\r
Node node = (Node)xpath.evaluate\r
("//fmiModelDescription/ModelVariables/ScalarVariable[@name='" + name + "']/Real/@start",\r
init, \r
XPathConstants.NODE);\r
if(node != null) {\r
- node.setNodeValue(changes.get(name));\r
+ node.setNodeValue(parameterChanges.get(name));\r
}\r
} \r
\r
@SuppressWarnings("rawtypes")\r
protected volatile VariableValueSubscription[] variableValueSubscriptionsSnapshot = null;\r
\r
- protected String previousModelStructure;\r
- protected HashMap<String, String> previousParameters;\r
+ protected HashMap<String, String> defaultParameters;\r
protected Process process;\r
protected boolean canceled = false;\r
protected ExperimentState sysdynExperimentState;\r
monitor.message(e.getMessage());\r
monitor.showConsole();\r
canceled = true;\r
- previousModelStructure = "";\r
- previousParameters = null;\r
+ defaultParameters = null;\r
}\r
}\r
\r
* @param structureChanged \r
* @throws IOException\r
*/\r
- protected void runModelica(SimulationLocation simulationLocation, IModelicaMonitor monitor, IProgressMonitor progressMonitor, HashMap<String, String> experimentParameters, HashMap<String, String> changes) throws IOException {\r
+ protected void runModelica(SimulationLocation simulationLocation, IModelicaMonitor monitor, IProgressMonitor progressMonitor, HashMap<String, String> experimentParameters, HashMap<String, String> parameterChanges) throws IOException {\r
progressMonitor.subTask("Simulate model");\r
process = ModelicaManager.runModelica(\r
simulationLocation,\r
monitor,\r
experimentParameters, \r
- changes\r
+ parameterChanges\r
);\r
ModelicaManager.printProcessOutput(process, monitor);\r
\r
FunctionUtils.updateFunctionFilesForExperiment(this);\r
\r
\r
- SimulationLocation location = ModelicaManager.createSimulationLocation(simulationDir, sysdynModel.getConfiguration().getLabel(), modelText, ModelicaManager.getOMHome(), ModelicaManager.isOldOMVersion());\r
+ SimulationLocation location = ModelicaManager.createSimulationLocation(simulationDir, sysdynModel.getConfiguration().getLabel(), modelText);\r
if (fmu) {\r
ModelicaManager.createFMUSimulationScripts(location, inits, additionalScript);\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
String flatModelText = ModelicaManager.getFlatModelText(simulationLocation, monitor, FunctionUtils.getLibraryPathsForModelica(this));\r
+ \r
boolean structureChanged = sysdynModel.isStructureModified();\r
\r
if (!simulationLocation.executableFile.isFile() || structureChanged) {\r
progressMonitor.subTask("Build model");\r
- previousModelStructure = flatModelText;\r
- previousParameters = ModelicaManager.getModelParameters(previousModelStructure);\r
+ defaultParameters = ModelicaManager.getModelParameters(flatModelText);\r
\r
buildModel(simulationLocation, monitor);\r
}\r
\r
// Add changed parameters in case that structure has not changed\r
- HashMap<String, String> changes = structureChanged ? null : new HashMap<String, String>();\r
- if(!structureChanged && previousParameters != null && omcVersion.startsWith("1.9")) {\r
- HashMap<String, String> newParameters = ModelicaManager.getModelParameters(flatModelText);\r
- for(String key : previousParameters.keySet()) {\r
- if(!previousParameters.get(key).equals(newParameters.get(key))) {\r
- changes.put(key, newParameters.get(key));\r
+ HashMap<String, String> parameterChanges = new HashMap<String, String>();\r
+ if(!structureChanged && defaultParameters != null) {\r
+ HashMap<String, String> currentParameters = ModelicaManager.getModelParameters(flatModelText);\r
+ for(String key : defaultParameters.keySet()) {\r
+ if(!defaultParameters.get(key).equals(currentParameters.get(key))) {\r
+ parameterChanges.put(key, currentParameters.get(key));\r
}\r
}\r
- previousParameters = newParameters;\r
}\r
progressMonitor.worked(1);\r
\r
if(simulationLocation != null && !canceled) {\r
// Simulate the model\r
- runModelica(simulationLocation, monitor, progressMonitor, experimentParameters, changes);\r
+ runModelica(simulationLocation, monitor, progressMonitor, experimentParameters, parameterChanges);\r
}\r
\r
if(canceled)\r
return omVersion;\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
-// protected boolean hasStructureChanged(String modelText) {\r
-//\r
-// if(previousModelStructure == null)\r
-// return true;\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
* Destroy an ongoing simulation process\r
*/\r