1 package org.simantics.simulation.export;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.Collections;
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;
43 * Common mechanism for CSV and Chart exports.
45 * @author toni.kalajainen@semantum.fi
47 public abstract class ExperimentExportClass implements ExportClass {
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");
53 public RecordType options(ExportContext context, Collection<String> content)
54 throws ExportException
57 RecordType experimentOptions;
59 Datatype second = new DoubleType("s");
61 experimentOptions = new RecordType();
62 experimentOptions.addComponent("Start Time", second);
63 experimentOptions.addComponent("End Time", second);
66 List<Resource> models = context.session.syncRequest( ExportQueries.toModels(content) );
67 for (Resource model : models) {
68 List<Resource> runs = context.session.syncRequest( getExperimentRuns(model) );
70 String modelLabel = context.session.syncRequest( ExportQueries.label( model ) );
71 if ( modelLabel==null ) continue;
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);
80 Collections.sort( runLabels, AlphanumComparator.CASE_INSENSITIVE_COMPARATOR );
82 RecordType modelRunSelection = new RecordType();
83 modelRunSelection.metadata.put("style", "dialog");
84 for ( String runLabel : runLabels ) {
85 modelRunSelection.addComponent(runLabel, Datatypes.BOOLEAN);
88 experimentOptions.addComponent(modelLabel+", experiment runs", modelRunSelection);
90 } catch (DatabaseException e) {
91 throw new ExportException( e );
94 options = new RecordType();
95 options.addComponent("Experiment", experimentOptions);
100 public void fillDefaultPrefs(final ExportContext ctx, final Variant options) throws ExportException {
103 RecordAccessor ra = Accessors.getAccessor(options);
105 ra.setValue(P_EXPERIMENT_END, Bindings.DOUBLE, 86400.0);
107 } catch (AccessorConstructionException e) {
108 throw new ExportException(e);
109 } catch (AccessorException e) {
110 throw new ExportException(e);
113 // Select the most latest experiments
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 ) {
122 BooleanAccessor ba = ra.getComponent(runRef.optionsRef);
124 } catch(AccessorConstructionException ae) {}
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 );
141 public void savePref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException {
143 RecordAccessor ra = Accessors.getAccessor(options);
145 Double startTime = (Double) ra.getValue(P_EXPERIMENT_START, Bindings.DOUBLE );
146 if ( startTime != null ) contentScopeNode.putDouble(P_EXPERIMENT_START.tail().toString(), startTime);
148 Double endTime = (Double) ra.getValue(P_EXPERIMENT_END, Bindings.DOUBLE );
149 if ( endTime != null ) contentScopeNode.putDouble(P_EXPERIMENT_END.tail().toString(), endTime);
151 } catch (AccessorConstructionException e) {
152 throw new ExportException(e);
153 } catch (AccessorException e) {
154 throw new ExportException(e);
158 public void loadPref(Variant options, Preferences contentScopeNode, Preferences workbenchScopeNode) throws ExportException {
160 RecordAccessor ra = Accessors.getAccessor(options);
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 );
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 );
168 } catch (AccessorConstructionException e) {
169 throw new ExportException(e);
170 } catch (AccessorException e) {
171 throw new ExportException(e);
176 * Get a request that returns experiments runs in format of
177 * "Experiment\Experiment Runs".
182 public static Read<List<Resource>> getExperimentRuns(final Resource model) {
183 return new Read<List<Resource>>() {
185 public List<Resource> perform(ReadGraph graph) throws DatabaseException {
186 List<Resource> result = new ArrayList<Resource>();
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)) {
205 * Returns a label in format of "Experiment\Run"
208 * @return the label or null
210 public static Read<String> getRunLabel(final Resource run) {
211 return new Read<String>() {
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;
219 String experimentLabel = NameLabelUtil.modalName(graph, experiment);
220 String runLabel = NameLabelUtil.modalName(graph, run);
222 if ( experimentLabel == null || runLabel == null ) return null;
224 return experimentLabel+"\\"+runLabel;
230 * Get Run resource using a label "Experiment\Run"
236 public static Read<Resource> getRunByLabel(final Resource model, final String runLabel) {
237 return new Read<Resource>() {
239 public Resource perform(ReadGraph graph) throws DatabaseException {
240 Layer0 L0 = Layer0.getInstance(graph);
241 SimulationResource SIMU = SimulationResource.getInstance(graph);
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;
262 public static Read<List<Resource>> getChildByLabelAndType(final Resource subject, final Resource type, final String label)
264 return new Read<List<Resource>>() {
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 );
281 * Read Model/Experiment/Run from options
284 * @param optionsBinding
286 * @param returnOnlyEnabledInOptions
288 * @throws DatabaseException
290 public static List<ModelRef> getResult(final ExportContext ctx, final Variant options, final boolean returnOnlyEnabledInOptions) throws DatabaseException {
292 return ctx.session.syncRequest( new Read<List<ModelRef>>() {
294 public List<ModelRef> perform(ReadGraph graph) throws DatabaseException {
296 List<ModelRef> result = new ArrayList<ModelRef>();
297 Layer0 L0 = Layer0.getInstance(graph);
298 SimulationResource SIMU = SimulationResource.getInstance(graph);
300 Resource project = graph.getResource( ctx.project );
301 Accessor ra = Accessors.getAccessor(options);
302 ra = ra.getComponent(P_EXPERIMENT);
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);
318 if ( c.type instanceof RecordType == false ) continue;
319 RecordType rt = (RecordType) c.type;
320 for (Component cc : rt.getComponents()) {
322 String[] parts = pp.split("\\\\");
323 if ( parts.length!=2 ) continue;
324 String experimentLabel = parts[0];
325 String runLabel = parts[1];
327 for ( Resource experiment : graph.syncRequest( getChildByLabelAndType(model, SIMU.Experiment, experimentLabel) ) )
329 ExperimentRef experimentRef = new ExperimentRef();
330 experimentRef.resource = experiment;
331 experimentRef.label = experimentLabel;
332 experimentRef.uri = graph.getURI(experiment);
334 for ( Resource run : graph.syncRequest( getChildByLabelAndType(experiment, SIMU.Run, runLabel) ) )
336 RunRef runRef = new RunRef();
337 runRef.optionsRef = new LabelReference(c.name, new LabelReference(experimentLabel+"\\"+runLabel));;
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;
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);
354 if ( !experimentRef.runs.isEmpty() ) modelRef.experiments.add(experimentRef);
359 if ( !modelRef.experiments.isEmpty() ) result.add( modelRef );
365 } catch (AccessorConstructionException e) {
366 throw new DatabaseException( e );
371 public static ModelRef getModelRefByResource(List<ModelRef> modelRefs, Resource model) {
372 for (ModelRef modelRef : modelRefs) if ( modelRef.resource.equals(model) ) return modelRef;
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);
384 return getWorkspacePath(false, dirs);
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
392 * @return the designated path within the workspace
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]);
399 return finalPath.toFile();
403 * @return the workspace root path as a File
405 public static File getWorkspacePath() {
406 return getWorkspacePath(false);
410 public static class ModelRef {
412 public Resource resource;
414 public List<ExperimentRef> experiments = new ArrayList<ExperimentRef>();
416 public int runCount() {
418 for ( ExperimentRef er : experiments ) count += er.runs.size();
422 public int enabledRunCount() {
424 for ( ExperimentRef er : experiments ) count += er.enabledRunCount();
428 public List<RunRef> getRunRefs() {
429 List<RunRef> result = new ArrayList<RunRef>();
430 for ( ExperimentRef er : experiments ) result.addAll( er.runs );
436 public static class ExperimentRef {
438 public Resource resource;
440 public List<RunRef> runs = new ArrayList<RunRef>();
442 public int enabledRunCount() {
444 for ( RunRef rr : runs ) if ( rr.isEnabled ) count++;
449 public static class RunRef {
451 public Resource resource;
453 public ChildReference optionsRef;
454 public boolean isActive;
455 public boolean isEnabled;
456 public File historyFolder;
457 public String identifier;