Skip to content

Commit

Permalink
Observed variables draft
Browse files Browse the repository at this point in the history
  • Loading branch information
Manfred Cheung committed Aug 27, 2021
1 parent 94e2ade commit 884005c
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 35 deletions.
89 changes: 80 additions & 9 deletions client/src/store/modules/simulation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,19 @@ const getters: GetterTree<any, HMI.SimulationParameter[]> = {
};

const actions: ActionTree<HMI.SimulationState, HMI.SimulationParameter[]> = {
setVariableObservedId ({ commit }, args: {
setVariableObservedVariable ({ commit }, args: {
modelId: number,
uid: string,
observedObj: Model.SelectedNode,
}): void {
commit('setVariableObservedVariable', args);
},
setVariableObservedHistorical ({ commit }, args: {
modelId: number,
uid: string,
observedId: string,
}): void {
commit('setVariableObservedId', args);
commit('setVariableObservedHistorical', args);
},

setSimParameterValue ({ commit }, args: {
Expand Down Expand Up @@ -289,25 +296,81 @@ const mutations: MutationTree<HMI.SimulationState> = {
state.numberOfSavedRuns = count;
},

async setVariableObservedId (state: HMI.SimulationState, args: {
async setVariableObservedVariable (state: HMI.SimulationState, args: {
modelId: number,
uid: string,
observedObj: Model.SelectedNode,
}): Promise<void> {
const variable = getVariable(state, args.modelId, args.uid);
variable.observedId = args.observedObj;
variable.observedType = HMI.ObservedType.VARIABLE;

const observedVariable = getVariable(state, args.observedObj.model, args.observedObj.node);
const observedCurrentRun = observedVariable.values[observedVariable.values.length - 1];
// Build measures array for error calculation
const measures: Donu.Measure[] = [];
const model = getModel(state, args.modelId);
for (const variable of model.variables) {
const { observedId, observedType } = variable;
if (observedId && observedType === HMI.ObservedType.VARIABLE) {
const currentRunVariableValues = variable.values[variable.values.length - 1];

let observedVariableValues;
if (variable?.uid === args.uid) {
variable.observed = observedCurrentRun;
observedVariableValues = observedCurrentRun;
} else {
observedVariableValues = variable.observed;
}

measures.push({
uid: variable.uid,
observed: {
times: observedVariableValues.map(d => d.x),
values: observedVariableValues.map(d => d.y),
},
predicted: {
times: currentRunVariableValues.map(d => d.x),
values: currentRunVariableValues.map(d => d.y),
},
});
}
}

const currentRunErrors = await getSimulationError(
measures,
Donu.InterpolationModelTypes.Linear,
Donu.ErrorModelTypes.L2,
);
for (const variable of model.variables) {
variable.currentRunError = currentRunErrors.measures.find(m => m.uid === variable.uid)?.error_total;
}
model.aggregateError = currentRunErrors?.error_total;

// Force reactive update
state.models = [...state.models];
},

async setVariableObservedHistorical (state: HMI.SimulationState, args: {
modelId: number,
uid: string,
observedId: string,
}): Promise<void> {
const variable = getVariable(state, args.modelId, args.uid);
variable.observedId = args.observedId;
variable.observedType = HMI.ObservedType.HISTORICAL;

// Build measures array for error calculation
const allowedTimeColumnNames = ['date', 'time', 'Day', 'week', 'month', 'year'];
const measures: Donu.Measure[] = [];
const model = getModel(state, args.modelId);
for (const variable of model.variables) {
const observedId = variable.observedId;
if (observedId) {
const { observedId, observedType } = variable;
if (observedId && observedType === HMI.ObservedType.HISTORICAL) {
const currentRunVariableValues = variable.values[variable.values.length - 1];
const currentRunVariableValuesLen = currentRunVariableValues.length;

const result = await getDatasetResult(observedId);
const result = await getDatasetResult(observedId as string);
// TODO: Donu should indicate to us which column is time based and which should be used as a value
// Currently some datasets may contain multiple value columns, here we find the first one
const observedTimes = result.columns.find(column => allowedTimeColumnNames.some(timeName => timeName === column.name));
Expand All @@ -321,12 +384,20 @@ const mutations: MutationTree<HMI.SimulationState> = {
y: observedValues.values[i],
});
}
variable.observed = observed;

let observedVariableValues;
if (variable?.uid === args.uid) {
variable.observed = observed;
observedVariableValues = observed;
} else {
observedVariableValues = variable.observed;
}

measures.push({
uid: variable.uid,
observed: {
times: observedTimes.values.slice(0, currentRunVariableValuesLen),
values: observedValues.values.slice(0, currentRunVariableValuesLen),
times: observedVariableValues.map(d => d.x),
values: observedVariableValues.map(d => d.y),
},
predicted: {
times: currentRunVariableValues.map(d => d.x),
Expand Down
10 changes: 9 additions & 1 deletion client/src/types/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint camelcase: 0 */

import * as Model from '@/types/typesModel';
import * as Donu from '@/types/typesDonu';

interface ModelComponentMetadataInterface {
Expand Down Expand Up @@ -68,12 +69,18 @@ interface SimulationParameter extends Donu.ModelParameter {
// List of runs, containing a list of coordinates.
type SimulationVariableValues = Array<{x: number, y: number}>;

enum ObservedType {
HISTORICAL = 'historical',
VARIABLE = 'variable',
}

interface SimulationVariable extends Donu.ModelVariable {
displayed?: boolean,
aggregate: SimulationVariableValues,
values: SimulationVariableValues[],
polygon?: SimulationVariableValues,
observedId?: string,
observedType: ObservedType,
observedId?: string | Model.SelectedNode,
observed: SimulationVariableValues,
currentRunError?: number,
}
Expand Down Expand Up @@ -108,6 +115,7 @@ export {
SimulationParameter,
SimulationRun,
SimulationState,
ObservedType,
SimulationVariable,
SimulationVariableValues,
TabInterface,
Expand Down
102 changes: 87 additions & 15 deletions client/src/views/Simulation/components/ObservedModal.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,40 @@
<template>
<!-- Modal to configure Run configuration -->
<modal v-if="data" @close="$emit('close')">
<h5 slot="header">Select Observed Dataset</h5>
<div slot="body" v-for="(dataset, index) in datasets" :key="index">
<div class="form-check" @click="selectDataset(dataset.source.model)">
<input
class="form-check-input"
type="radio"
:checked="selectedObservedId === dataset.source.model"
/>
<label class="form-check-label">
{{dataset.description}}
</label>
<h4 slot="header">Select Observed Dataset</h4>
<div slot="body" class="d-flex">
<div class="media-body">
<h5>Observed data</h5>
<div v-for="(dataset, index) in datasets" :key="index">
<div class="form-check" @click="selectHistoricalDataset(dataset.source.model)">
<input
class="form-check-input"
type="radio"
:checked="isHistoricalChecked(dataset.source.model)"
/>
<label class="form-check-label">
{{dataset.description}}
</label>
</div>
</div>
</div>
<div class="media-body">
<h5>Variables</h5>
<div class="mb-2" v-for="(data, index) in modelDataList" :key="index">
<h6>{{getModelName(data.id)}}</h6>
<div v-for="(data2, index) in data.variables" :key="index">
<div class="form-check" @click="selectVariableDataset(data.id, data2.uid)">
<input
class="form-check-input"
type="radio"
:checked="isVariableChecked(data.id, data2.uid)"
/>
<label class="form-check-label">
{{data2.metadata.name}}
</label>
</div>
</div>
</div>
</div>
</div>
</modal>
Expand All @@ -21,33 +44,82 @@
import Vue from 'vue';
import Component from 'vue-class-component';
import { Prop } from 'vue-property-decorator';
import Modal from '@/components/Modal.vue';
import { Getter, Action } from 'vuex-class';
import { ObservedType } from '@/types/types';
import { SelectedNode } from '@/types/typesModel';
import { listDatasetsResult } from '@/services/DonuService';
import Modal from '@/components/Modal.vue';
const components = {
Modal,
};
@Component({ components })
export default class ObservedButton extends Vue {
@Prop({ default: false }) modelId: any;
@Prop({ default: false }) data: any;
@Getter getModelsList;
@Getter getSelectedModelIds;
@Getter getSimModel;
@Action setVariableObservedVariable;
@Action setVariableObservedHistorical;
datasets: any = [];
selectedObservedId: string = '';
selectedObservedType: ObservedType
selectedObservedId: string | SelectedNode = '';
async mounted (): Promise<void> {
this.datasets = await listDatasetsResult();
}
isHistoricalChecked (modelId: string): boolean {
return this.selectedObservedType === ObservedType.HISTORICAL &&
this.selectedObservedId === modelId;
}
isVariableChecked (modelId: number, nodeId: string): boolean {
return this.selectedObservedType === ObservedType.VARIABLE &&
(this.selectedObservedId as SelectedNode).model === modelId &&
(this.selectedObservedId as SelectedNode).node === nodeId;
}
get variableId (): string {
return this.data.uid;
}
selectDataset (observedId: string): void {
get modelDataList (): any {
return this.getSelectedModelIds.map(modelId => this.getSimModel(modelId));
}
getModelName (modelId: string): string {
return this.getModelsList.find(model => model.id === modelId)?.name;
}
selectVariableDataset (observedModel: string, observedId: string): void {
this.selectedObservedType = ObservedType.VARIABLE;
this.selectedObservedId = { model: observedModel as unknown as number, node: observedId };
this.setVariableObservedVariable({
modelId: this.modelId,
uid: this.data.uid,
observedObj: { model: observedModel, node: observedId },
});
}
selectHistoricalDataset (observedId: string): void {
this.selectedObservedType = ObservedType.HISTORICAL;
this.selectedObservedId = observedId !== this.selectedObservedId
? observedId
: '';
this.$emit('datasetSelected', this.selectedObservedId);
this.setVariableObservedHistorical({
modelId: this.modelId,
uid: this.data.uid,
observedId,
});
}
}
</script>
Expand Down
11 changes: 1 addition & 10 deletions client/src/views/Simulation/components/VariablesPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
</aside>
</multi-line-plot>
<observed-modal
@datasetSelected="setObservedId"
:modelId="modelId"
:data="plot.uid === variableOpen ? plot : false"
@close="variableOpen = ''"
:key="'modal' + index"
Expand Down Expand Up @@ -165,7 +165,6 @@
@Getter getVariablesRunsCount;
@Getter getSelectedNodes;
@Action hideVariable;
@Action setVariableObservedId;
variablesData: any = [];
variableOpen: string = '';
Expand Down Expand Up @@ -279,14 +278,6 @@
this.updateVariables();
return listDatasetsResult();
}
setObservedId (observedId: string): void {
this.setVariableObservedId({
modelId: this.modelId,
uid: this.variableOpen,
observedId,
});
}
}
</script>

Expand Down

0 comments on commit 884005c

Please sign in to comment.