Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
dgauldie committed Oct 10, 2024
2 parents 0dd1549 + 2ccdd44 commit f5a50b5
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 123 deletions.
39 changes: 32 additions & 7 deletions packages/client/hmi-client/src/components/widgets/VegaChart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,39 @@
</template>

<script setup lang="ts">
import embed, { Result, VisualizationSpec } from 'vega-embed';
import { Config as VgConfig } from 'vega';
import { Config as VlConfig } from 'vega-lite';
import { format } from 'd3';
import embed, { Config, Result, VisualizationSpec } from 'vega-embed';
import Button from 'primevue/button';
import Dialog from 'primevue/dialog';
import { countDigits, fixPrecisionError } from '@/utils/number';
import { ref, watch, toRaw, isRef, isReactive, isProxy, computed, h, render } from 'vue';
export type Config = VgConfig | VlConfig;
const NUMBER_FORMAT = '.3~s';
// Define the custom expression functions that can be registered and used in the Vega charts
const expressionFunctions = {
// chartNumberFormatter is a custom number format that will display numbers in a more readable format
chartNumberFormatter: (value: number) => {
const correctedValue = fixPrecisionError(value);
if (value > -1 && value < 1) {
return countDigits(correctedValue) > 6 ? correctedValue.toExponential(3) : correctedValue.toString();
}
return format(NUMBER_FORMAT)(correctedValue);
},
// Just show full value in tooltip
tooltipFormatter: (value) => fixPrecisionError(value)
};
// This config is default for all charts, but can be overridden by individual chart spec
const defaultChartConfig: Partial<Config> = {
customFormatTypes: true,
numberFormatType: 'chartNumberFormatter',
numberFormat: 'chartNumberFormatter',
tooltipFormat: {
numberFormat: 'tooltipFormatter',
numberFormatType: 'tooltipFormatter'
}
};
const props = withDefaults(
defineProps<{
Expand Down Expand Up @@ -138,8 +162,9 @@ async function createVegaVisualization(
container,
{ ...visualizationSpec },
{
config: config || {},
actions: options.actions === false ? false : undefined
config: { ...defaultChartConfig, ...config } as Config,
actions: options.actions === false ? false : undefined,
expressionFunctions // Register expression functions
}
);
props.intervalSelectionSignalNames.forEach((signalName) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
>
<template #content>
<div class="toolbar">
<p>Click Run to begin calibrating.</p>
<p>Set your mapping, calibration and visualization settings then click run.</p>
<span class="flex gap-2">
<tera-pyciemss-cancel-button class="mr-auto" :simulation-run-id="cancelRunId" />
<Button label="Run" icon="pi pi-play" @click="runCalibrate" :disabled="disableRunButton" />
Expand All @@ -26,12 +26,12 @@
<div class="form-section">
<h5 class="mb-1">Mapping</h5>
<p class="mb-2">
Select a subset of output variables of the model and individually assosiate them to columns in the
Select a subset of output variables of the model and individually associate them to columns in the
dataset.
</p>

<!-- Mapping table: Time variables -->
<div class="input-row">
<div class="input-row mapping-input">
<div class="label-and-input">
<label class="column-header">Model: Timeline variable</label>
<tera-input-text disabled model-value="timestamp" />
Expand Down Expand Up @@ -101,11 +101,19 @@
<!-- Mapping section -->
<section class="form-section">
<h5 class="mb-1">
Calibration settings
<i v-tooltip="calibrationSettingsToolTip" class="pi pi-info-circle info-circle" />
</h5>
<p class="mb-2">Select one of the presets or customize the settings below.</p>
<h5 class="mb-1">Calibration settings</h5>
<div class="input-row">
<div class="label-and-input">
<label>Start time</label>
<tera-input-text disabled model-value="0" />
</div>
<div class="label-and-input">
<label for="num-samples">End time</label>
<tera-input-number inputId="integeronly" v-model="knobs.endTime" />
</div>
</div>
<div class="spacer m-2" />
<p class="mb-1">Preset (optional)</p>
<div class="label-and-input">
<Dropdown
v-model="presetType"
Expand All @@ -114,28 +122,22 @@
@update:model-value="setPresetValues"
/>
</div>
<label class="mb-1 p-text-secondary text-sm">
<i class="pi pi-info-circle" />
This impacts solver method, iterations and learning rate.
</label>
<div class="mt-1 additional-settings">
<p>
Number of Samples
<i v-tooltip="numberOfSamplesTooltip" class="pi pi-info-circle info-circle" />
</p>
<div class="input-row">
<div class="label-and-input">
<tera-input-number
inputId="integeronly"
v-model="knobs.numSamples"
@update:model-value="updateState"
/>
</div>
<div class="label-and-input">
<label>Number of Samples</label>
<tera-input-number inputId="integeronly" v-model="knobs.numSamples" @update:model-value="updateState" />
</div>
<div class="spacer m-3" />
<p class="font-semibold">
ODE solver options
<i v-tooltip="odeSolverOptionsTooltip" class="pi pi-info-circle info-circle" />
</p>
<h6 class="mb-2">ODE solver options</h6>
<div class="input-row">
<div class="label-and-input">
<label for="5">Method</label>
<label for="5">Solver method</label>
<Dropdown
id="5"
v-model="knobs.method"
Expand All @@ -144,15 +146,12 @@
/>
</div>
<div class="label-and-input">
<label for="num-steps">Step size</label>
<label for="num-steps">Solver step size</label>
<tera-input-number inputId="integeronly" v-model="knobs.stepSize" />
</div>
</div>
<div class="spacer m-3" />
<p class="font-semibold">
Inference Options
<i v-tooltip="inferenceOptionsTooltip" class="pi pi-info-circle info-circle" />
</p>
<h6 class="mb-2">Inference Options</h6>
<div class="input-row">
<div class="label-and-input">
<label for="num-iterations">Number of solver iterations</label>
Expand All @@ -162,10 +161,6 @@
@update:model-value="updateState"
/>
</div>
<div class="label-and-input">
<label for="num-samples">End time for forecast</label>
<tera-input-number inputId="integeronly" v-model="knobs.endTime" />
</div>
<div class="label-and-input">
<label for="learning-rate">Learning rate</label>
<tera-input-number
Expand Down Expand Up @@ -324,6 +319,7 @@
<tera-slider-panel
v-model:is-open="isOutputSettingsPanelOpen"
direction="right"
class="input-config"
header="Output Settings"
content-width="360px"
>
Expand Down Expand Up @@ -562,11 +558,6 @@ const qualityPreset = Object.freeze({
learningRate: 0.03
});
const calibrationSettingsToolTip: string = 'TODO';
const numberOfSamplesTooltip: string = 'TODO';
const inferenceOptionsTooltip: string = 'TODO';
const odeSolverOptionsTooltip: string = 'TODO';
// Model variables checked in the model configuration will be options in the mapping dropdown
const modelStateOptions = ref<any[] | undefined>();
Expand Down Expand Up @@ -1220,7 +1211,7 @@ watch(
/* Mapping table */
.mapping-table:deep(td) {
border: none !important;
padding: 0 var(--gap-1) var(--gap-2) 0 !important;
padding: 0 var(--gap-2) var(--gap-2) 0 !important;
background: var(--surface-100);
}
Expand Down Expand Up @@ -1274,7 +1265,11 @@ img {
.label-and-input {
display: flex;
flex-direction: column;
gap: var(--gap-2);
gap: var(--gap-1);
:deep(input) {
text-align: left;
}
}
.info-circle {
color: var(--text-color-secondary);
Expand All @@ -1287,14 +1282,19 @@ img {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: var(--gap-3) var(--gap-2);
gap: var(--gap-2);
width: 100%;
& > * {
flex: 1;
}
}
/** Make inputs align with mapping table */
.mapping-input {
width: calc(100% - 40px);
}
.loss-chart {
background: var(--surface-a);
border: 1px solid var(--surface-border-light);
Expand Down Expand Up @@ -1348,6 +1348,11 @@ img {
.additional-settings {
background: var(--surface-200);
padding: var(--gap-2);
padding: var(--gap-3);
border-radius: var(--border-radius-medium);
}
input {
text-align: left;
}
</style>
7 changes: 0 additions & 7 deletions packages/client/hmi-client/src/services/charts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ const VEGALITE_SCHEMA = 'https://vega.github.io/schema/vega-lite/v5.json';

export const CATEGORICAL_SCHEME = ['#1B8073', '#6495E8', '#8F69B9', '#D67DBF', '#E18547', '#D2C446', '#84594D'];

export const NUMBER_FORMAT = '.3~s';
export const LABEL_EXPR = `
datum.value > -1 && datum.value < 1 ? format(datum.value, '.3~f') : format(datum.value, '${NUMBER_FORMAT}')
`;

interface BaseChartOptions {
title?: string;
width: number;
Expand Down Expand Up @@ -370,7 +365,6 @@ export function createForecastChart(
};
const yaxis = structuredClone(xaxis);
yaxis.title = options.yAxisTitle;
yaxis.labelExpr = LABEL_EXPR;

const translationMap = options.translationMap;
let labelExpr = '';
Expand Down Expand Up @@ -626,7 +620,6 @@ export function createSuccessCriteriaChart(
};
const yaxis = structuredClone(xaxis);
yaxis.title = options.yAxisTitle;
yaxis.labelExpr = LABEL_EXPR;

return {
$schema: VEGALITE_SCHEMA,
Expand Down
57 changes: 4 additions & 53 deletions packages/client/hmi-client/src/services/knowledge.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import API from '@/api/api';
import { AxiosResponse } from 'axios';
import { extractionStatusUpdateHandler, subscribe } from '@/services/ClientEventService';
import type { Code, Dataset, DocumentAsset, Model } from '@/types/Types';
import { ClientEventType } from '@/types/Types';
import { type Dataset, type DocumentAsset, type Model, ClientEventType } from '@/types/Types';
import { logger } from '@/utils/logger';
import { AxiosResponse } from 'axios';

/** Define the request type
/**
* Define the request type
* @param equations string[] - list of LaTeX or mathml strings representing a model
* @param framework string= - the framework to use for the extraction, default to 'petrinet'
* @param modelId string= - the model id to use for the extraction
Expand Down Expand Up @@ -55,70 +55,21 @@ export const profileDataset = async (datasetId: Dataset['id'], documentId: Docum

/** Extract text and artifacts from a PDF document */
export const extractPDF = async (documentId: DocumentAsset['id']) => {
console.group('PDF COSMOS Extraction');
if (documentId) {
const response = await API.post(`/knowledge/pdf-extractions?document-id=${documentId}`);
if (response?.status === 202) {
await subscribe(ClientEventType.Extraction, extractionStatusUpdateHandler);
} else {
console.debug('Failed — ', response);
}
} else {
console.debug('Failed — No documentId provided for pdf extraction.');
}
console.groupEnd();
};

/** Extract variables from a text document */
export const extractVariables = async (documentId: DocumentAsset['id'], modelIds: Array<Model['id']>) => {
console.group('SKEMA Variable extraction');
if (documentId) {
const url = `/knowledge/variable-extractions?document-id=${documentId}&model-ids=${modelIds}`;
const response = await API.post(url);
if (response?.status === 202) {
await subscribe(ClientEventType.Extraction, extractionStatusUpdateHandler);
} else {
console.debug('Failed — ', response);
}
} else {
console.debug('Failed — No documentId provided for variable extraction.');
}
console.groupEnd();
};

export async function codeToAMR(
codeId: string,
name: string = '',
description: string = '',
dynamicsOnly: boolean = false,
llmAssisted: boolean = false
): Promise<Model | null> {
const response = await API.post(
`/knowledge/code-to-amr?code-id=${codeId}&name=${name}&description=${description}&dynamics-only=${dynamicsOnly}&llm-assisted=${llmAssisted}`
);
if (response?.status === 200) {
return response.data;
}
logger.error(`Code to AMR request failed`, { toastTitle: 'Error' });
return null;
}

export async function codeBlocksToAmr(code: Code, file: File): Promise<Model | null> {
const formData = new FormData();
const blob = new Blob([JSON.stringify(code)], {
type: 'application/json'
});
formData.append('code', blob);
formData.append('file', file);
const response = await API.post(`/knowledge/code-blocks-to-model`, formData, {
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data'
}
});
if (response?.status === 200) {
return response.data;
}
logger.error(`Code to AMR request failed`, { toastTitle: 'Error' });
return null;
}
Loading

0 comments on commit f5a50b5

Please sign in to comment.