Skip to content

Commit

Permalink
Fix simulation dataset creation (#1658)
Browse files Browse the repository at this point in the history
  • Loading branch information
dvince2 authored Aug 3, 2023
1 parent d35a165 commit 0212252
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,28 @@
/>
<Button
class="add-chart"
text
:outlined="true"
@click="saveDataset(projectId, completedRunId)"
:disabled="true"
label="Save as Dataset"
icon="pi pi-save"
/>
title="Saves the current version of the model as a new Terarium asset"
@click="showSaveInput = !showSaveInput"
>
<span class="pi pi-save p-button-icon p-button-icon-left"></span>
<span class="p-button-text">Save as</span>
</Button>
<span v-if="showSaveInput" style="padding-left: 1em; padding-right: 2em">
<InputText v-model="saveAsName" class="post-fix" placeholder="New dataset name" />
<i
class="pi pi-times i"
:class="{ clear: hasValidDatasetName }"
@click="saveAsName = ''"
></i>
<i
class="pi pi-check i"
:class="{ save: hasValidDatasetName }"
@click="
saveDataset(projectId, completedRunId, saveAsName);
showSaveInput = false;
"
></i>
</span>
</div>

<div v-else-if="activeTab === EnsembleTabs.input && node" class="simulate-container">
Expand Down Expand Up @@ -245,6 +260,10 @@ const CATEGORYPERCENTAGE = 0.9;
const BARPERCENTAGE = 0.6;
const MINBARLENGTH = 1;
const showSaveInput = ref(<boolean>false);
const saveAsName = ref(<string | null>'');
const hasValidDatasetName = computed<boolean>(() => saveAsName.value !== '');
const activeTab = ref(EnsembleTabs.input);
const listModelIds = computed<string[]>(() => props.node.state.modelConfigIds);
const datasetId = computed(() => props.node.inputs[1].value?.[0] as string | undefined);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,28 @@
/>
<Button
class="add-chart"
text
:outlined="true"
@click="saveDataset(projectId, completedRunId)"
label="Save as Dataset"
icon="pi pi-save"
/>
title="Saves the current version of the model as a new Terarium asset"
@click="showSaveInput = !showSaveInput"
>
<span class="pi pi-save p-button-icon p-button-icon-left"></span>
<span class="p-button-text">Save as</span>
</Button>
<span v-if="showSaveInput" style="padding-left: 1em; padding-right: 2em">
<InputText v-model="saveAsName" class="post-fix" placeholder="New dataset name" />
<i
class="pi pi-times i"
:class="{ clear: hasValidDatasetName }"
@click="saveAsName = ''"
></i>
<i
class="pi pi-check i"
:class="{ save: hasValidDatasetName }"
@click="
saveDataset(projectId, completedRunId, saveAsName);
showSaveInput = false;
"
></i>
</span>
</div>
<div v-else-if="activeTab === SimulateTabs.input && node" class="simulate-container">
<div class="simulate-model">
Expand Down Expand Up @@ -171,12 +187,15 @@ import { WorkflowNode } from '@/types/workflow';
import { workflowEventBus } from '@/services/workflow';
import { IProject } from '@/types/Project';
import { saveDataset } from '@/services/dataset';
import InputText from 'primevue/inputtext';
const props = defineProps<{
node: WorkflowNode;
project: IProject;
}>();
const hasValidDatasetName = computed<boolean>(() => saveAsName.value !== '');
const timespan = ref<TimeSpan>(props.node.state.currentTimespan);
const numSamples = ref<number>(props.node.state.numSamples);
Expand All @@ -191,7 +210,8 @@ const model = ref<Model | null>(null);
const parsedRawData = ref<any>();
const runConfigs = ref<any>({});
const runResults = ref<RunResults>({});
const showSaveInput = ref(<boolean>false);
const saveAsName = ref(<string | null>'');
const selectedCols = ref<string[]>([]);
const paginatorRows = ref(10);
const paginatorFirst = ref(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,28 @@
/>
<Button
class="add-chart"
text
:outlined="true"
@click="saveDataset(projectId, completedRunId)"
:disabled="true"
label="Save as Dataset"
icon="pi pi-save"
/>
title="Saves the current version of the model as a new Terarium asset"
@click="showSaveInput = !showSaveInput"
>
<span class="pi pi-save p-button-icon p-button-icon-left"></span>
<span class="p-button-text">Save as</span>
</Button>
<span v-if="showSaveInput" style="padding-left: 1em; padding-right: 2em">
<InputText v-model="saveAsName" class="post-fix" placeholder="New dataset name" />
<i
class="pi pi-times i"
:class="{ clear: hasValidDatasetName }"
@click="saveAsName = ''"
></i>
<i
class="pi pi-check i"
:class="{ save: hasValidDatasetName }"
@click="
saveDataset(projectId, completedRunId, saveAsName);
showSaveInput = false;
"
></i>
</span>
</div>

<div v-else-if="activeTab === EnsembleTabs.input && node" class="simulate-container">
Expand Down Expand Up @@ -245,6 +260,10 @@ const completedRunId = computed<string>(
);
const projectId = ref<string>(props.project.id);
const hasValidDatasetName = computed<boolean>(() => saveAsName.value !== '');
const showSaveInput = ref(<boolean>false);
const saveAsName = ref(<string | null>'');
const customWeights = ref<boolean>(false);
// TODO: Does AMR contain weights? Can i check all inputs have the weights parameter filled in or the calibration boolean checked off?
const disabledCalibrationWeights = computed(() => true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,28 @@
/>
<Button
class="add-chart"
text
:outlined="true"
@click="saveDataset(projectId, completedRunId)"
label="Save as Dataset"
icon="pi pi-save"
/>
title="Saves the current version of the model as a new Terarium asset"
@click="showSaveInput = !showSaveInput"
>
<span class="pi pi-save p-button-icon p-button-icon-left"></span>
<span class="p-button-text">Save as</span>
</Button>
<span v-if="showSaveInput" style="padding-left: 1em; padding-right: 2em">
<InputText v-model="saveAsName" class="post-fix" placeholder="New dataset name" />
<i
class="pi pi-times i"
:class="{ clear: hasValidDatasetName }"
@click="saveAsName = ''"
></i>
<i
class="pi pi-check i"
:class="{ save: hasValidDatasetName }"
@click="
saveDataset(projectId, completedRunId, saveAsName);
showSaveInput = false;
"
></i>
</span>
</div>
<div v-else-if="activeTab === SimulateTabs.input && node" class="simulate-container">
<div class="simulate-model">
Expand Down Expand Up @@ -106,6 +122,7 @@ import { csvParse } from 'd3';
import { WorkflowNode } from '@/types/workflow';
import { workflowEventBus } from '@/services/workflow';
import { IProject } from '@/types/Project';
import InputText from 'primevue/inputtext';
import { SimulateJuliaOperationState } from './simulate-julia-operation';
import TeraSimulateChart from './tera-simulate-chart.vue';

Expand All @@ -128,6 +145,9 @@ const runResults = ref<RunResults>({});
const modelConfiguration = ref<ModelConfiguration | null>(null);
const projectId = ref<string>(props.project.id);
const completedRunId = computed<string | undefined>(() => props?.node?.outputs?.[0]?.value?.[0]);
const hasValidDatasetName = computed<boolean>(() => saveAsName.value !== '');
const showSaveInput = ref(<boolean>false);
const saveAsName = ref(<string | null>'');

const configurationChange = (index: number, config: ChartConfig) => {
const state: SimulateJuliaOperationState = _.cloneDeep(props.node.state);
Expand Down
15 changes: 10 additions & 5 deletions packages/client/hmi-client/src/services/dataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,14 @@ async function createNewDatasetFromCSV(

async function createDatasetFromSimulationResult(
projectId: string,
simulationId: string
simulationId: string,
datasetName: string | null
): Promise<boolean> {
try {
const response: AxiosResponse<Response> = await API.get(
`/simulations/${simulationId}/add-result-as-dataset-to-project/${projectId}`
`/simulations/${simulationId}/add-result-as-dataset-to-project/${projectId}?datasetName=${datasetName}`
);
if (response && response.status === 200) {
if (response && response.status === 201) {
return true;
}
logger.error(`Unable to create dataset from simulation result ${response.status}`, {
Expand All @@ -204,9 +205,13 @@ async function createDatasetFromSimulationResult(
}
}

export const saveDataset = async (projectId: string, simulationId: string | undefined) => {
export const saveDataset = async (
projectId: string,
simulationId: string | undefined,
datasetName: string | null
) => {
if (!simulationId) return;
if (await createDatasetFromSimulationResult(projectId, simulationId)) {
if (await createDatasetFromSimulationResult(projectId, simulationId, datasetName)) {
useResourcesStore().setActiveProject(await ProjectService.get(projectId, true));
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import software.uncharted.terarium.hmiserver.annotations.LogRestClientTime;
import software.uncharted.terarium.hmiserver.models.dataservice.Simulation;
import software.uncharted.terarium.hmiserver.models.dataservice.PresignedURL;
import software.uncharted.terarium.hmiserver.models.dataservice.dataset.Dataset;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
Expand Down Expand Up @@ -61,7 +62,7 @@ PresignedURL getDownloadURL(
@GET
@Path("/{id}/copy_results")
@LogRestClientTime
JsonNode copyResultsToDataset(
Dataset copyResultsToDataset(
@PathParam("id") String id
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
import software.uncharted.terarium.hmiserver.models.dataservice.PresignedURL;
import software.uncharted.terarium.hmiserver.models.dataservice.ResourceType;
import software.uncharted.terarium.hmiserver.models.dataservice.Simulation;
import software.uncharted.terarium.hmiserver.models.dataservice.dataset.Dataset;
import software.uncharted.terarium.hmiserver.proxies.dataservice.DatasetProxy;
import software.uncharted.terarium.hmiserver.proxies.dataservice.ProjectProxy;
import software.uncharted.terarium.hmiserver.proxies.dataservice.SimulationProxy;
import software.uncharted.terarium.hmiserver.resources.SnakeCaseResource;
import software.uncharted.terarium.hmiserver.utils.Converter;

import javax.inject.Inject;
Expand All @@ -26,7 +29,7 @@
@Produces(MediaType.APPLICATION_JSON)
@Tag(name = "Simulation REST Endpoints")
@Slf4j
public class SimulationResource {
public class SimulationResource implements SnakeCaseResource {

@Inject
@RestClient
Expand All @@ -36,6 +39,10 @@ public class SimulationResource {
@RestClient
ProjectProxy projectProxy;

@Inject
@RestClient
DatasetProxy datasetProxy;

@POST
public Simulation createSimulation(final Simulation simulation){
return proxy.createSimulation(Converter.convertObjectToSnakeCaseJsonNode(simulation));
Expand Down Expand Up @@ -99,27 +106,32 @@ public Response getSimulation(
@Path("/{id}/add-result-as-dataset-to-project/{projectId}")
public Response createFromSimulationResult(
@PathParam("id") final String id,
@PathParam("projectId") final String projectId
@PathParam("projectId") final String projectId,
@QueryParam("datasetName") final String datasetName
) {
// Duplicate the simulation results to a new dataset
final JsonNode jsonDatasetId = proxy.copyResultsToDataset(id);

// Test if dataset is null
if (jsonDatasetId == null) {
log.error("Failed to copy simulation {} result as dataset", id);
return Response
.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Failed to copy simulation result as dataset")
.type("text/plain")
.build();
final Dataset dataset = proxy.copyResultsToDataset(id);

if(datasetName != null){
try {
dataset.setName(datasetName);
JsonNode updatedDataset = convertObjectToSnakeCaseJsonNode(dataset);
datasetProxy.updateDataset(dataset.getId(), updatedDataset);

} catch (Exception e) {
log.error("Failed to update dataset {} name", dataset.getId());
return Response
.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Failed to update dataset name")
.type("text/plain")
.build();
}
}

// Get the Dataset Id returned by the dataservice
final String datasetId = jsonDatasetId.at("/id").asText();

// Add the dataset to the project as an asset
try {
return projectProxy.createAsset(projectId, "datasets", datasetId);
return projectProxy.createAsset(projectId, ResourceType.Type.DATASETS.type, dataset.getId());
} catch (Exception ignored) {
log.error("Failed to add simulation {} result as dataset to project {}", id, projectId);
return Response
Expand Down

0 comments on commit 0212252

Please sign in to comment.