diff --git a/packages/client/hmi-client/src/components/workflow/ops/calibrate-ciemss/tera-calibrate-node-ciemss.vue b/packages/client/hmi-client/src/components/workflow/ops/calibrate-ciemss/tera-calibrate-node-ciemss.vue index cabf84a5b9..c88a6c1d1b 100644 --- a/packages/client/hmi-client/src/components/workflow/ops/calibrate-ciemss/tera-calibrate-node-ciemss.vue +++ b/packages/client/hmi-client/src/components/workflow/ops/calibrate-ciemss/tera-calibrate-node-ciemss.vue @@ -125,7 +125,6 @@ watch( console.log('dill URL is', dillURL); const forecastResponse = await makeForecastJobCiemss({ - projectId: '', modelConfigId: modelConfigId.value as string, timespan: { start: 0, diff --git a/packages/client/hmi-client/src/components/workflow/ops/optimize-ciemss/optimize-ciemss-operation.ts b/packages/client/hmi-client/src/components/workflow/ops/optimize-ciemss/optimize-ciemss-operation.ts index 15b7a955a4..314bf05118 100644 --- a/packages/client/hmi-client/src/components/workflow/ops/optimize-ciemss/optimize-ciemss-operation.ts +++ b/packages/client/hmi-client/src/components/workflow/ops/optimize-ciemss/optimize-ciemss-operation.ts @@ -107,14 +107,16 @@ export async function getOptimizedInterventions(optimizeRunId: string) { // Get the interventionPolicyGroups from the simulation object. // This will prevent any inconsistencies being passed via knobs or state when matching with result file. const simulation = await getSimulation(optimizeRunId); - const interventions = simulation?.executionPayload?.interventions; - const interventionType = interventions.selection ?? ''; - const paramNames: string[] = interventions.param_names ?? []; - const paramValue: number[] = interventions.param_values ?? []; - const startTime: number[] = interventions.start_time ?? []; + const simulationIntervetions: SimulationIntervention[] = + simulation?.executionPayload.fixed_static_parameter_interventions ?? []; + const policyInterventions = simulation?.executionPayload?.policy_interventions; + const interventionType = policyInterventions.selection ?? ''; + const paramNames: string[] = policyInterventions.param_names ?? []; + const paramValue: number[] = policyInterventions.param_values ?? []; + const startTime: number[] = policyInterventions.start_time ?? []; const policyResult = await getRunResult(optimizeRunId, 'policy.json'); - const simulationIntervetions: SimulationIntervention[] = []; + if (interventionType === InterventionTypes.paramValue && startTime.length !== 0) { // intervention type == parameter value for (let i = 0; i < paramNames.length; i++) { diff --git a/packages/client/hmi-client/src/components/workflow/ops/optimize-ciemss/tera-optimize-ciemss-node.vue b/packages/client/hmi-client/src/components/workflow/ops/optimize-ciemss/tera-optimize-ciemss-node.vue index d7abf1abb8..cc724d607a 100644 --- a/packages/client/hmi-client/src/components/workflow/ops/optimize-ciemss/tera-optimize-ciemss-node.vue +++ b/packages/client/hmi-client/src/components/workflow/ops/optimize-ciemss/tera-optimize-ciemss-node.vue @@ -111,7 +111,6 @@ const pollResult = async (runId: string) => { const startForecast = async (simulationIntervetions) => { const simulationPayload: SimulationRequest = { - projectId: '', modelConfigId: modelConfigId.value as string, timespan: { start: 0, diff --git a/packages/client/hmi-client/src/components/workflow/ops/optimize-ciemss/tera-optimize-ciemss.vue b/packages/client/hmi-client/src/components/workflow/ops/optimize-ciemss/tera-optimize-ciemss.vue index cdd92b07df..1af78ef303 100644 --- a/packages/client/hmi-client/src/components/workflow/ops/optimize-ciemss/tera-optimize-ciemss.vue +++ b/packages/client/hmi-client/src/components/workflow/ops/optimize-ciemss/tera-optimize-ciemss.vue @@ -122,7 +122,7 @@
- { listBoundsInterventions.push([ele.upperBound]); }); - const optimizeInterventions: OptimizedIntervention = { - selection: knobs.value.interventionType, + const optimizeInterventions: PolicyInterventions = { + interventionType: knobs.value.interventionType, paramNames, startTime, paramValues @@ -560,7 +561,7 @@ const runOptimize = async () => { start: 0, end: knobs.value.endTime }, - interventions: optimizeInterventions, + policyInterventions: optimizeInterventions, qoi: { contexts: knobs.value.targetVariables, method: knobs.value.qoiMethod @@ -581,7 +582,6 @@ const runOptimize = async () => { if (inferredParameters.value) { optimizePayload.extra.inferredParameters = inferredParameters.value[0]; } - const optResult = await makeOptimizeJobCiemss(optimizePayload); const state = _.cloneDeep(props.node.state); state.inProgressOptimizeId = optResult.simulationId; diff --git a/packages/client/hmi-client/src/components/workflow/ops/simulate-ciemss/tera-simulate-ciemss.vue b/packages/client/hmi-client/src/components/workflow/ops/simulate-ciemss/tera-simulate-ciemss.vue index 305be94a4c..e09ca88bf9 100644 --- a/packages/client/hmi-client/src/components/workflow/ops/simulate-ciemss/tera-simulate-ciemss.vue +++ b/packages/client/hmi-client/src/components/workflow/ops/simulate-ciemss/tera-simulate-ciemss.vue @@ -260,7 +260,6 @@ const makeForecastRequest = async () => { const state = props.node.state; const payload: SimulationRequest = { - projectId: '', modelConfigId, timespan: { start: state.currentTimespan.start, diff --git a/packages/client/hmi-client/src/components/workflow/ops/simulate-julia/tera-simulate-julia.vue b/packages/client/hmi-client/src/components/workflow/ops/simulate-julia/tera-simulate-julia.vue index 734d82577e..1b899117a5 100644 --- a/packages/client/hmi-client/src/components/workflow/ops/simulate-julia/tera-simulate-julia.vue +++ b/packages/client/hmi-client/src/components/workflow/ops/simulate-julia/tera-simulate-julia.vue @@ -220,7 +220,6 @@ const makeForecastRequest = async (): Promise => { const state = props.node.state; const payload: SimulationRequest = { - projectId: useProjects().activeProject.value?.id as string, modelConfigId: configId, timespan: { start: state.currentTimespan.start, diff --git a/packages/client/hmi-client/src/types/Types.ts b/packages/client/hmi-client/src/types/Types.ts index 01e35075df..d76bf87c1f 100644 --- a/packages/client/hmi-client/src/types/Types.ts +++ b/packages/client/hmi-client/src/types/Types.ts @@ -651,6 +651,7 @@ export interface CalibrationRequestCiemss { modelConfigId: string; extra: any; timespan?: TimeSpan; + interventions?: Intervention[]; dataset: DatasetLocation; engine: string; } @@ -687,7 +688,8 @@ export interface EnsembleSimulationCiemssRequest { export interface OptimizeRequestCiemss { modelConfigId: string; timespan: TimeSpan; - interventions?: OptimizedIntervention; + policyInterventions?: PolicyInterventions; + fixedStaticParameterInterventions?: Intervention[]; stepSize?: number; qoi: OptimizeQoi; riskBound: number; @@ -712,7 +714,6 @@ export interface SimulationRequest { timespan: TimeSpan; extra: any; engine: string; - projectId: string; interventions?: Intervention[]; } @@ -749,8 +750,8 @@ export interface OptimizeQoi { method: string; } -export interface OptimizedIntervention { - selection: string; +export interface PolicyInterventions { + interventionType: string; paramNames: string[]; paramValues?: number[]; startTime?: number[]; diff --git a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/controller/simulationservice/SimulationRequestController.java b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/controller/simulationservice/SimulationRequestController.java index 26a135c077..b31a462e88 100644 --- a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/controller/simulationservice/SimulationRequestController.java +++ b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/controller/simulationservice/SimulationRequestController.java @@ -109,7 +109,7 @@ public ResponseEntity makeForecastRun( sim.setStatus(ProgressState.QUEUED); // FIXME: These fiels are arguable unnecessary - final Optional project = projectService.getProject(request.getProjectId()); + final Optional project = projectService.getProject(projectId); if (project.isPresent()) { sim.setProjectId(project.get().getId()); sim.setUserId(project.get().getUserId()); @@ -155,7 +155,7 @@ public ResponseEntity makeForecastRunCiemss( request.setInterventions(allInterventions); } } catch (IOException e) { - String error = "Unable to find model configuration"; + String error = "Server error has occured while fetching the model configuration"; log.error(error, e); throw new ResponseStatusException(org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR, error); } @@ -174,7 +174,7 @@ public ResponseEntity makeForecastRunCiemss( sim.setExecutionPayload(objectMapper.convertValue(request, JsonNode.class)); sim.setStatus(ProgressState.QUEUED); - final Optional project = projectService.getProject(request.getProjectId()); + final Optional project = projectService.getProject(projectId); if (project.isPresent()) { sim.setProjectId(project.get().getId()); sim.setUserId(project.get().getUserId()); @@ -205,7 +205,32 @@ public ResponseEntity makeCalibrateJob(@RequestBody final Calibrati @PostMapping("ciemss/calibrate") @Secured(Roles.USER) - public ResponseEntity makeCalibrateJobCiemss(@RequestBody final CalibrationRequestCiemss request) { + public ResponseEntity makeCalibrateJobCiemss( + @RequestBody final CalibrationRequestCiemss request, @RequestParam("project-id") final UUID projectId) { + Schema.Permission permission = + projectService.checkPermissionCanWrite(currentUserService.get().getId(), projectId); + // Get model config's interventions and append them to requests: + try { + final Optional modelConfiguration = + modelConfigService.getAsset(request.getModelConfigId(), permission); + if (modelConfiguration.isEmpty()) { + return ResponseEntity.notFound().build(); + } + final List modelInterventions = + modelConfiguration.get().getInterventions(); + if (modelInterventions != null) { + List allInterventions = request.getInterventions(); + if (allInterventions == null) { + allInterventions = new ArrayList(); + } + allInterventions.addAll(modelInterventions); + request.setInterventions(allInterventions); + } + } catch (IOException e) { + String error = "Server error has occured while fetching the model configuration"; + log.error(error, e); + throw new ResponseStatusException(org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR, error); + } return ResponseEntity.ok(simulationCiemssServiceProxy .makeCalibrateJob(convertObjectToSnakeCaseJsonNode(request)) .getBody()); @@ -213,7 +238,33 @@ public ResponseEntity makeCalibrateJobCiemss(@RequestBody final Cal @PostMapping("ciemss/optimize") @Secured(Roles.USER) - public ResponseEntity makeOptimizeJobCiemss(@RequestBody final OptimizeRequestCiemss request) { + public ResponseEntity makeOptimizeJobCiemss( + @RequestBody final OptimizeRequestCiemss request, @RequestParam("project-id") final UUID projectId) { + Schema.Permission permission = + projectService.checkPermissionCanWrite(currentUserService.get().getId(), projectId); + + // Get model config's interventions and append them to requests: + try { + final Optional modelConfiguration = + modelConfigService.getAsset(request.getModelConfigId(), permission); + if (modelConfiguration.isEmpty()) { + return ResponseEntity.notFound().build(); + } + final List modelInterventions = + modelConfiguration.get().getInterventions(); + if (modelInterventions != null) { + List allInterventions = request.getFixedStaticParameterInterventions(); + if (allInterventions == null) { + allInterventions = new ArrayList(); + } + allInterventions.addAll(modelInterventions); + request.setFixedStaticParameterInterventions(allInterventions); + } + } catch (IOException e) { + String error = "Server error has occured while fetching the model configuration"; + log.error(error, e); + throw new ResponseStatusException(org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR, error); + } return ResponseEntity.ok(simulationCiemssServiceProxy .makeOptimizeJob(convertObjectToSnakeCaseJsonNode(request)) .getBody()); diff --git a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/CalibrationRequestCiemss.java b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/CalibrationRequestCiemss.java index 51ae1b22f1..a76dd72589 100644 --- a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/CalibrationRequestCiemss.java +++ b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/CalibrationRequestCiemss.java @@ -2,11 +2,14 @@ import com.fasterxml.jackson.annotation.JsonAlias; import java.io.Serializable; +import java.util.List; +import java.util.UUID; import lombok.Data; import lombok.experimental.Accessors; import software.uncharted.terarium.hmiserver.annotations.TSModel; import software.uncharted.terarium.hmiserver.annotations.TSOptional; import software.uncharted.terarium.hmiserver.models.simulationservice.parts.DatasetLocation; +import software.uncharted.terarium.hmiserver.models.simulationservice.parts.Intervention; import software.uncharted.terarium.hmiserver.models.simulationservice.parts.TimeSpan; @Data @@ -15,13 +18,16 @@ // Used to kick off a calibration job in simulation-service public class CalibrationRequestCiemss implements Serializable { @JsonAlias("model_config_id") - private String modelConfigId; + private UUID modelConfigId; private Object extra; @TSOptional private TimeSpan timespan; + @TSOptional + private List interventions; + private DatasetLocation dataset; private String engine; } diff --git a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/OptimizeRequestCiemss.java b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/OptimizeRequestCiemss.java index 62868371f3..c17ff81ae3 100644 --- a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/OptimizeRequestCiemss.java +++ b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/OptimizeRequestCiemss.java @@ -3,13 +3,15 @@ import com.fasterxml.jackson.annotation.JsonAlias; import java.io.Serializable; import java.util.List; +import java.util.UUID; import lombok.Data; import lombok.experimental.Accessors; import software.uncharted.terarium.hmiserver.annotations.TSModel; import software.uncharted.terarium.hmiserver.annotations.TSOptional; +import software.uncharted.terarium.hmiserver.models.simulationservice.parts.Intervention; import software.uncharted.terarium.hmiserver.models.simulationservice.parts.OptimizeExtra; import software.uncharted.terarium.hmiserver.models.simulationservice.parts.OptimizeQoi; -import software.uncharted.terarium.hmiserver.models.simulationservice.parts.OptimizedIntervention; +import software.uncharted.terarium.hmiserver.models.simulationservice.parts.PolicyInterventions; import software.uncharted.terarium.hmiserver.models.simulationservice.parts.TimeSpan; @Data @@ -18,14 +20,17 @@ // Used to kick off a Optimize job in simulation-service public class OptimizeRequestCiemss implements Serializable { @JsonAlias("model_config_id") - private String modelConfigId; + private UUID modelConfigId; private TimeSpan timespan; @TSOptional - // FIXME: make pluraal more consistent here: // https://github.com/DARPA-ASKEM/pyciemss-service/blob/main/service/models/operations/optimize.py#L80 - private OptimizedIntervention interventions; + private PolicyInterventions policyInterventions; + + @TSOptional + // The interventions provided via the model config which are not being optimized on + private List fixedStaticParameterInterventions; @JsonAlias("step_size") @TSOptional diff --git a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/SimulationRequest.java b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/SimulationRequest.java index ff7c00b522..657791e1b2 100644 --- a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/SimulationRequest.java +++ b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/SimulationRequest.java @@ -27,8 +27,6 @@ public class SimulationRequest implements Serializable { private String engine; - private UUID projectId; - @TSOptional private List interventions; @@ -44,7 +42,6 @@ public SimulationRequest clone() { : null); clone.setExtra(this.extra.deepCopy()); clone.setEngine(this.engine); - clone.setProjectId(this.projectId); clone.setInterventions(new ArrayList<>()); for (final Intervention intervention : this.interventions) { clone.getInterventions() diff --git a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/parts/OptimizedIntervention.java b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/parts/PolicyInterventions.java similarity index 69% rename from packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/parts/OptimizedIntervention.java rename to packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/parts/PolicyInterventions.java index 9f650680be..5bea755217 100644 --- a/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/parts/OptimizedIntervention.java +++ b/packages/server/src/main/java/software/uncharted/terarium/hmiserver/models/simulationservice/parts/PolicyInterventions.java @@ -10,9 +10,11 @@ @Data @Accessors(chain = true) @TSModel -// Used to specify any interventions provided by the AMR and given to the simulation-service. -public class OptimizedIntervention { - private String selection; +// Interventions applied by the user within the optimization box. +public class PolicyInterventions { + // This denotes whether the intervention is on a start date, or a parameter value. + // https://github.com/DARPA-ASKEM/pyciemss-service/blob/main/service/models/operations/optimize.py#L99 + private String interventionType; @JsonAlias("param_names") private List paramNames;