]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.simulation/src/org/simantics/simulation/export/ExperimentExportClass.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.simulation / src / org / simantics / simulation / export / ExperimentExportClass.java
1 package org.simantics.simulation.export;\r
2 \r
3 import java.io.File;\r
4 import java.util.ArrayList;\r
5 import java.util.Collection;\r
6 import java.util.Collections;\r
7 import java.util.List;\r
8 \r
9 import org.eclipse.core.runtime.IPath;\r
10 import org.eclipse.core.runtime.Platform;\r
11 import org.osgi.service.prefs.Preferences;\r
12 import org.simantics.NameLabelUtil;\r
13 import org.simantics.databoard.Accessors;\r
14 import org.simantics.databoard.Bindings;\r
15 import org.simantics.databoard.Datatypes;\r
16 import org.simantics.databoard.accessor.Accessor;\r
17 import org.simantics.databoard.accessor.BooleanAccessor;\r
18 import org.simantics.databoard.accessor.RecordAccessor;\r
19 import org.simantics.databoard.accessor.error.AccessorConstructionException;\r
20 import org.simantics.databoard.accessor.error.AccessorException;\r
21 import org.simantics.databoard.accessor.reference.ChildReference;\r
22 import org.simantics.databoard.accessor.reference.LabelReference;\r
23 import org.simantics.databoard.binding.mutable.Variant;\r
24 import org.simantics.databoard.type.Component;\r
25 import org.simantics.databoard.type.Datatype;\r
26 import org.simantics.databoard.type.DoubleType;\r
27 import org.simantics.databoard.type.RecordType;\r
28 import org.simantics.databoard.util.URIUtil;\r
29 import org.simantics.db.ReadGraph;\r
30 import org.simantics.db.Resource;\r
31 import org.simantics.db.common.request.PossibleObjectWithType;\r
32 import org.simantics.db.exception.DatabaseException;\r
33 import org.simantics.db.request.Read;\r
34 import org.simantics.export.core.ExportContext;\r
35 import org.simantics.export.core.error.ExportException;\r
36 import org.simantics.export.core.intf.ExportClass;\r
37 import org.simantics.export.core.util.ExportQueries;\r
38 import org.simantics.layer0.Layer0;\r
39 import org.simantics.simulation.ontology.SimulationResource;\r
40 import org.simantics.utils.strings.AlphanumComparator;\r
41 \r
42 /**\r
43  * Common mechanism for CSV and Chart exports.\r
44  *\r
45  * @author toni.kalajainen@semantum.fi\r
46  */\r
47 public abstract class ExperimentExportClass implements ExportClass {\r
48 \r
49         public static ChildReference P_EXPERIMENT = new LabelReference("Experiment");   \r
50         public static ChildReference P_EXPERIMENT_START = ChildReference.parsePath("Experiment/Start Time");\r
51         public static ChildReference P_EXPERIMENT_END = ChildReference.parsePath("Experiment/End Time");        \r
52 \r
53         public RecordType options(ExportContext context, Collection<String> content) \r
54                         throws ExportException \r
55         {\r
56                 RecordType options;\r
57             RecordType experimentOptions;\r
58             \r
59             Datatype second = new DoubleType("s");\r
60 \r
61         experimentOptions = new RecordType();\r
62         experimentOptions.addComponent("Start Time", second);\r
63         experimentOptions.addComponent("End Time", second);\r
64         \r
65         try {\r
66                         List<Resource> models = context.session.syncRequest( ExportQueries.toModels(content) );\r
67                         for (Resource model : models) {\r
68                                 List<Resource> runs = context.session.syncRequest( getExperimentRuns(model) );\r
69                                 \r
70                                 String modelLabel = context.session.syncRequest( ExportQueries.label( model ) );\r
71                                 if ( modelLabel==null ) continue;\r
72                                 \r
73                                 List<String> runLabels = new ArrayList<String>();\r
74                                 for ( Resource run : runs ) {\r
75                                         String runLabel = context.session.syncRequest( getRunLabel(run) );\r
76                                         if ( runLabel == null ) continue;\r
77                                         runLabels.add(runLabel);\r
78                                 }                               \r
79                                 \r
80                                 Collections.sort( runLabels, AlphanumComparator.CASE_INSENSITIVE_COMPARATOR );\r
81                                 \r
82                                 RecordType modelRunSelection = new RecordType();\r
83                                 modelRunSelection.metadata.put("style", "dialog");\r
84                                 for ( String runLabel : runLabels ) {\r
85                                         modelRunSelection.addComponent(runLabel, Datatypes.BOOLEAN);\r
86                                 }                               \r
87                                 \r
88                                 experimentOptions.addComponent(modelLabel+", experiment runs", modelRunSelection);\r
89                         }\r
90                 } catch (DatabaseException e) {\r
91                         throw new ExportException( e );\r
92                 }\r
93         \r
94         options = new RecordType();\r
95         options.addComponent("Experiment", experimentOptions);\r
96         \r
97         return options;\r
98         }\r
99 \r
100         public void fillDefaultPrefs(final ExportContext ctx, final Variant options) throws ExportException {\r
101                 \r
102         try {\r
103                         RecordAccessor ra = Accessors.getAccessor(options);\r
104                         \r
105                 ra.setValue(P_EXPERIMENT_END, Bindings.DOUBLE, 86400.0);\r
106                         \r
107                 } catch (AccessorConstructionException e) {\r
108                         throw new ExportException(e);\r
109                 } catch (AccessorException e) {\r
110                         throw new ExportException(e);\r
111                 }\r
112                 \r
113                 // Select the most latest experiments\r
114                 try {\r
115                         Accessor ra = Accessors.getAccessor( options );\r
116                         ra = ra.getComponent( P_EXPERIMENT );\r
117                         for (ModelRef modelRef : getResult(ctx, options, false)) {\r
118                                 for (ExperimentRef experimentRef : modelRef.experiments) {\r
119                                         for (RunRef runRef : experimentRef.runs) {\r
120                                                 if ( runRef.isActive ) {\r
121                                                         try {\r
122                                                                 BooleanAccessor ba = ra.getComponent(runRef.optionsRef);\r
123                                                                 ba.setValue(true);\r
124                                                         } catch(AccessorConstructionException ae) {}\r
125                                                 }\r
126                                         }\r
127                                 }\r
128                         }\r
129                         \r
130                 } catch (AccessorConstructionException e) {\r
131                         throw new ExportException(e);\r
132                 } catch (AccessorException e) {\r
133                         throw new ExportException(e);\r
134                 } catch (DatabaseException e1) {\r
135                         throw new ExportException( e1 );\r
136                 }\r
137 \r
138         \r
139         }\r
140 \r
141         public void savePref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException {\r
142                 try {\r
143                         RecordAccessor ra = Accessors.getAccessor(options);\r
144                                                 \r
145                         Double startTime = (Double) ra.getValue(P_EXPERIMENT_START, Bindings.DOUBLE );\r
146                         if ( startTime != null ) contentScopeNode.putDouble(P_EXPERIMENT_START.tail().toString(), startTime);                   \r
147 \r
148                         Double endTime = (Double) ra.getValue(P_EXPERIMENT_END, Bindings.DOUBLE );\r
149                         if ( endTime != null ) contentScopeNode.putDouble(P_EXPERIMENT_END.tail().toString(), endTime);                 \r
150                         \r
151                 } catch (AccessorConstructionException e) {\r
152                         throw new ExportException(e);\r
153                 } catch (AccessorException e) {\r
154                         throw new ExportException(e);\r
155                 }               \r
156         }\r
157 \r
158         public void loadPref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException {\r
159                 try {\r
160                         RecordAccessor ra = Accessors.getAccessor(options);\r
161                         \r
162                         double startTime = contentScopeNode.getDouble(P_EXPERIMENT_START.tail().toString(), -Double.MAX_VALUE); \r
163                         if ( startTime != -Double.MAX_VALUE ) ra.setValue(P_EXPERIMENT_START, Bindings.DOUBLE, startTime );                                                     \r
164                         \r
165                         double endTime = contentScopeNode.getDouble(P_EXPERIMENT_END.tail().toString(), -Double.MAX_VALUE); \r
166                         if ( endTime != -Double.MAX_VALUE ) ra.setValue(P_EXPERIMENT_END, Bindings.DOUBLE, endTime );                                                   \r
167                         \r
168                 } catch (AccessorConstructionException e) {\r
169                         throw new ExportException(e);\r
170                 } catch (AccessorException e) {\r
171                         throw new ExportException(e);\r
172                 }\r
173         }\r
174 \r
175         /**\r
176          * Get a request that returns experiments runs in format of \r
177          * "Experiment\Experiment Runs". \r
178          * \r
179          * @param model\r
180          * @return\r
181          */\r
182         public static Read<List<Resource>> getExperimentRuns(final Resource model) {\r
183                 return new Read<List<Resource>>() {\r
184                         @Override\r
185                         public List<Resource> perform(ReadGraph graph) throws DatabaseException {\r
186                                 List<Resource> result = new ArrayList<Resource>();\r
187                                 \r
188                         Layer0 b = Layer0.getInstance(graph);\r
189                         SimulationResource SIMU = SimulationResource.getInstance(graph);\r
190                         for (Resource config : graph.getObjects(model, b.ConsistsOf)) {\r
191                             if (graph.isInstanceOf(config, SIMU.Experiment)) {\r
192                                 for (Resource run : graph.getObjects(config, b.ConsistsOf)) {\r
193                                     if (graph.isInstanceOf(run, SIMU.Run)) {\r
194                                         result.add( run );\r
195                                     }\r
196                                 }\r
197                             }\r
198                         }\r
199                                 return result;\r
200                         }\r
201                 };              \r
202         }\r
203         \r
204         /**\r
205          * Returns a label in format of "Experiment\Run"\r
206          * \r
207          * @param run\r
208          * @return the label or null \r
209          */\r
210         public static Read<String> getRunLabel(final Resource run) {\r
211                 return new Read<String>() {\r
212                         @Override\r
213                         public String perform(ReadGraph graph) throws DatabaseException {\r
214                         Layer0 L0 = Layer0.getInstance(graph);\r
215                         SimulationResource SIMU = SimulationResource.getInstance(graph);\r
216                                 Resource experiment = graph.syncRequest( new PossibleObjectWithType(run, L0.PartOf, SIMU.Experiment) );\r
217                                 if ( experiment == null ) return null;\r
218                                 \r
219                                 String experimentLabel = NameLabelUtil.modalName(graph, experiment);\r
220                                 String runLabel = NameLabelUtil.modalName(graph, run);\r
221                                 \r
222                                 if ( experimentLabel == null || runLabel == null ) return null;\r
223                                 \r
224                                 return experimentLabel+"\\"+runLabel;\r
225                         }\r
226                 };\r
227         }\r
228         \r
229         /**\r
230          * Get Run resource using a label "Experiment\Run"\r
231          * \r
232          * @param model\r
233          * @param runLabel\r
234          * @return resource\r
235          */\r
236         public static Read<Resource> getRunByLabel(final Resource model, final String runLabel) {\r
237                 return new Read<Resource>() {\r
238                         @Override\r
239                         public Resource perform(ReadGraph graph) throws DatabaseException {\r
240                         Layer0 L0 = Layer0.getInstance(graph);\r
241                         SimulationResource SIMU = SimulationResource.getInstance(graph);\r
242 \r
243                         for (Resource config : graph.getObjects(model, L0.ConsistsOf)) {\r
244                             if (graph.isInstanceOf(config, SIMU.Experiment)) {\r
245                                                 String experimentLabel = NameLabelUtil.modalName(graph, config);\r
246                                                 if ( experimentLabel == null ) continue;\r
247                                                 if ( !runLabel.startsWith(experimentLabel) ) continue;\r
248                                 for (Resource run : graph.getObjects(config, L0.ConsistsOf)) {\r
249                                     if (graph.isInstanceOf(run, SIMU.Run)) {\r
250                                                         String lbl2 = NameLabelUtil.modalName(graph, run);\r
251                                                         if ( lbl2 == null ) continue;\r
252                                         if ( runLabel.equals( experimentLabel+"\\"+lbl2 ) ) return run;\r
253                                     }\r
254                                 }\r
255                             }\r
256                         }\r
257                         return null;\r
258                         }\r
259                 };              \r
260         }\r
261         \r
262         public static Read<List<Resource>> getChildByLabelAndType(final Resource subject, final Resource type, final String label)\r
263         {\r
264                 return new Read<List<Resource>>() {\r
265                         @Override\r
266                         public List<Resource> perform(ReadGraph graph) throws DatabaseException {\r
267                                 List<Resource> result = new ArrayList<Resource>();\r
268                                 Layer0 L0 = Layer0.getInstance(graph);\r
269                                 for ( Resource child : graph.getObjects(subject, L0.ConsistsOf )) {\r
270                                         if ( !graph.isInstanceOf(child, type) ) continue;\r
271                                         String lbl = NameLabelUtil.modalName(graph, child);\r
272                                         if ( lbl==null ) continue;\r
273                                         if ( lbl.equals(label)) result.add( child );\r
274                                 }\r
275                                 return result;\r
276                         }\r
277                 };\r
278         }\r
279 \r
280         /**\r
281          * Read Model/Experiment/Run from options\r
282          * \r
283          * @param ctx\r
284          * @param optionsBinding\r
285          * @param options\r
286          * @param returnOnlyEnabledInOptions\r
287          * @return\r
288          * @throws DatabaseException \r
289          */\r
290         public static List<ModelRef> getResult(final ExportContext ctx, final Variant options, final boolean returnOnlyEnabledInOptions) throws DatabaseException {\r
291 \r
292                         return ctx.session.syncRequest( new Read<List<ModelRef>>() {\r
293                                 @Override\r
294                                 public List<ModelRef> perform(ReadGraph graph) throws DatabaseException {\r
295                                 try {\r
296                                                 List<ModelRef> result = new ArrayList<ModelRef>();\r
297                                                 Layer0 L0 = Layer0.getInstance(graph);\r
298                                         SimulationResource SIMU = SimulationResource.getInstance(graph);\r
299         \r
300                                         Resource project = graph.getResource( ctx.project );\r
301                                                 Accessor ra = Accessors.getAccessor(options);\r
302                                                 ra = ra.getComponent(P_EXPERIMENT);\r
303                                 \r
304                                         RecordType type = (RecordType)((RecordType) options.type()).getComponentType("Experiment");\r
305                                         if ( type != null ) {\r
306                                                 for ( Component c : type.getComponents() ) {\r
307                                                         int endIndex = c.name.length() - ", experiment runs".length();\r
308                                                         if ( endIndex <= 0 ) continue;\r
309                                                         String modelName = c.name.substring(0, endIndex);\r
310                                                         if ( modelName.isEmpty() ) continue;\r
311                                                         List<Resource> models = graph.syncRequest( getChildByLabelAndType(project, SIMU.Model, modelName) );\r
312                                                         for (Resource model : models ) {\r
313                                                                 ModelRef modelRef = new ModelRef();\r
314                                                                 modelRef.resource = model;\r
315                                                                 modelRef.label = modelName;\r
316                                                                 modelRef.uri = graph.getURI(model);\r
317                                                                 \r
318                                                                 if ( c.type instanceof RecordType == false ) continue;\r
319                                                                 RecordType rt = (RecordType) c.type;\r
320                                                                 for (Component cc : rt.getComponents()) {\r
321                                                                         String pp = cc.name;\r
322                                                                         String[] parts = pp.split("\\\\");\r
323                                                                         if ( parts.length!=2 ) continue;\r
324                                                                         String experimentLabel = parts[0];\r
325                                                                         String runLabel = parts[1];\r
326                                                                                                                                 \r
327                                                                         for ( Resource experiment : graph.syncRequest( getChildByLabelAndType(model, SIMU.Experiment, experimentLabel) ) )\r
328                                                                         {\r
329                                                                                 ExperimentRef experimentRef = new ExperimentRef();\r
330                                                                                 experimentRef.resource = experiment;\r
331                                                                                 experimentRef.label = experimentLabel;\r
332                                                                                 experimentRef.uri = graph.getURI(experiment);\r
333                                                                                 \r
334                                                                                 for ( Resource run : graph.syncRequest( getChildByLabelAndType(experiment, SIMU.Run, runLabel) ) ) \r
335                                                                                 {\r
336                                                                                         RunRef runRef = new RunRef();   \r
337                                                                                         runRef.optionsRef = new LabelReference(c.name, new LabelReference(experimentLabel+"\\"+runLabel));;\r
338                                                                                                 try {\r
339                                                                                                         BooleanAccessor ba = ra.getComponent( runRef.optionsRef );\r
340                                                                                                         runRef.isEnabled = ba.getValue();\r
341                                                                                                         if ( !runRef.isEnabled && returnOnlyEnabledInOptions ) continue;\r
342                                                                                                 } catch (AccessorException e) {\r
343                                                                                                         if ( returnOnlyEnabledInOptions ) continue;\r
344                                                                                                 }\r
345                                                                                         runRef.resource = run;\r
346                                                                                         runRef.label = runLabel;\r
347                                                                                         runRef.uri = graph.getURI(run);\r
348                                                                                         runRef.isActive = graph.hasStatement(run, SIMU.IsActive);\r
349                                                                                         runRef.identifier = graph.getRelatedValue(run, L0.HasName, Bindings.STRING);                                                                                    \r
350                                                                                                 runRef.historyFolder = getExperimentDirectory(modelRef.resource, experimentRef.resource, "result-" + runRef.identifier);\r
351                                                                                         experimentRef.runs.add(runRef);\r
352                                                                                 }\r
353                                                                                 \r
354                                                                                 if ( !experimentRef.runs.isEmpty() ) modelRef.experiments.add(experimentRef);\r
355                                                                         }\r
356                                                                         \r
357                                                                 }\r
358                                                                 \r
359                                                                 if ( !modelRef.experiments.isEmpty() ) result.add( modelRef );\r
360                                                         }\r
361                                                 }\r
362                                         }\r
363                                         \r
364                                         return result;\r
365                                         } catch (AccessorConstructionException e) {\r
366                                                 throw new DatabaseException( e );\r
367                                         }\r
368                         }});\r
369         }\r
370         \r
371         public static ModelRef getModelRefByResource(List<ModelRef> modelRefs, Resource model) {\r
372                 for (ModelRef modelRef : modelRefs) if ( modelRef.resource.equals(model) ) return modelRef;\r
373                 return null;\r
374         }\r
375         \r
376     public static File getExperimentDirectory(Resource model, Resource experiment, String... subdirs) throws DatabaseException {\r
377         String[] dirs = new String[4 + subdirs.length];\r
378         dirs[0] = "resources";\r
379         dirs[1] = "model-" + model.getResourceId();\r
380         dirs[2] = "experiments";\r
381         dirs[3] = "" + experiment.getResourceId();\r
382         System.arraycopy(subdirs, 0, dirs, 4, subdirs.length);\r
383 \r
384         return getWorkspacePath(false, dirs);\r
385     }\r
386         \r
387     /**\r
388      * @param escapeNames <code>true</code> to run each path segment through\r
389      *        {@link URIUtil#encodeFilename(String)}\r
390      * @param relativeSegments path segments to append to the workspace root\r
391      *        path\r
392      * @return the designated path within the workspace\r
393      */\r
394     public static File getWorkspacePath(boolean escapeNames, String... relativeSegments) {\r
395         IPath finalPath = Platform.getLocation();\r
396         for (int i = 0; i < relativeSegments.length; ++i)\r
397             finalPath = finalPath.append(escapeNames ? URIUtil.encodeFilename(relativeSegments[i]) : relativeSegments[i]);\r
398 \r
399         return finalPath.toFile();\r
400     }    \r
401     \r
402     /**\r
403      * @return the workspace root path as a File\r
404      */\r
405     public static File getWorkspacePath() {\r
406         return getWorkspacePath(false);\r
407     }\r
408         \r
409         \r
410         public static class ModelRef {\r
411                 public String uri;\r
412                 public Resource resource;\r
413                 public String label;\r
414                 public List<ExperimentRef> experiments = new ArrayList<ExperimentRef>();\r
415                 \r
416                 public int runCount() {\r
417                         int count = 0;\r
418                         for ( ExperimentRef er : experiments ) count += er.runs.size();\r
419                         return count;\r
420                 }\r
421                 \r
422                 public int enabledRunCount() {\r
423                         int count = 0;\r
424                         for ( ExperimentRef er : experiments ) count += er.enabledRunCount();\r
425                         return count;\r
426                 }\r
427                 \r
428                 public List<RunRef> getRunRefs() {\r
429                         List<RunRef> result = new ArrayList<RunRef>();\r
430                         for ( ExperimentRef er : experiments ) result.addAll( er.runs );\r
431                         return result;\r
432                 }\r
433                 \r
434         }\r
435         \r
436         public static class ExperimentRef {\r
437                 public String uri;\r
438                 public Resource resource;\r
439                 public String label;\r
440                 public List<RunRef> runs = new ArrayList<RunRef>();\r
441                 \r
442                 public int enabledRunCount() {\r
443                         int count = 0;\r
444                         for ( RunRef rr : runs ) if ( rr.isEnabled ) count++;\r
445                         return count;\r
446                 }\r
447         }\r
448         \r
449         public static class RunRef {            \r
450                 public String uri;\r
451                 public Resource resource;\r
452                 public String label;\r
453                 public ChildReference optionsRef;\r
454                 public boolean isActive;\r
455                 public boolean isEnabled;\r
456                 public File historyFolder;\r
457                 public String identifier;\r
458         }\r
459         \r
460 }\r