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