Skip to content

Commit

Permalink
make horizon scanning intervention policies optional (#5880)
Browse files Browse the repository at this point in the history
Co-authored-by: Cole Blanchard <[email protected]>
  • Loading branch information
blanchco and Cole Blanchard authored Dec 20, 2024
1 parent 91c3af5 commit 1e886b1
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ export class HorizonScanningScenario extends BaseScenario {
!!this.workflowName &&
!!this.modelSpec.id &&
!!this.modelConfigSpec.id &&
!this.interventionSpecs.some((interventionSpec) => !interventionSpec.id) &&
!this.parameters.some((parameter) => !parameter) &&
!_.isEmpty(this.simulateSpec.ids)
);
Expand Down Expand Up @@ -291,75 +290,132 @@ export class HorizonScanningScenario extends BaseScenario {
const modelConfigNodes = (await Promise.all(modelConfigPromises)).flat();

// 3. Add intervention nodes for each intervention and attach them to the model node
const interventionPromises = this.interventionSpecs.map(async (interventionSpec) => {
const interventionPolicy = await getInterventionPolicyById(interventionSpec.id);
// filter out any interventions that don't have an id
const interventionPromises = this.interventionSpecs
.filter((spec) => !!spec.id)
.map(async (interventionSpec) => {
const interventionPolicy = await getInterventionPolicyById(interventionSpec.id);
const interventionNode = wf.addNode(
InterventionOp,
{ x: 0, y: 0 },
{
size: OperatorNodeSize.medium
}
);

wf.addEdge(modelNode.id, modelNode.outputs[0].id, interventionNode.id, interventionNode.inputs[0].id, [
{ x: 0, y: 0 },
{ x: 0, y: 0 }
]);

wf.updateNode(interventionNode, {
state: {
interventionPolicy
},
output: {
value: [interventionPolicy.id],
state: interventionNode.state
}
});

const interventionNode = wf.addNode(
InterventionOp,
return interventionNode;
});

// Wait for all interventionPromises to resolve
const interventionNodes = await Promise.all(interventionPromises);

// 4. Add simulate nodes for each model config and intervention and attach them to the model config and intervention nodes
// each intervention node will be connected to a simulate node along with each model config node
modelConfigNodes.forEach((modelConfigNode) => {
// For each model config node, we want to connect it to a simulate node, even if interventions aren't present
const simulateNode = wf.addNode(
SimulateCiemssOp,
{ x: 0, y: 0 },
{
size: OperatorNodeSize.medium
}
);

wf.addEdge(modelNode.id, modelNode.outputs[0].id, interventionNode.id, interventionNode.inputs[0].id, [
wf.updateNode(simulateNode, {
state: {
chartSettings: simulateChartSettings
}
});

wf.addEdge(modelConfigNode.id, modelConfigNode.outputs[0].id, simulateNode.id, simulateNode.inputs[0].id, [
{ x: 0, y: 0 },
{ x: 0, y: 0 }
]);

wf.updateNode(interventionNode, {
state: {
interventionPolicy
},
output: {
value: [interventionPolicy.id],
state: interventionNode.state
interventionNodes.forEach((interventionNode, index) => {
// If this is the first intervention node, connect it to the model config node and the already created simulate node
if (index === 0) {
wf.addEdge(interventionNode.id, interventionNode.outputs[0].id, simulateNode.id, simulateNode.inputs[1].id, [
{ x: 0, y: 0 },
{ x: 0, y: 0 }
]);
} else {
const additionalSimNode = wf.addNode(
SimulateCiemssOp,
{ x: 0, y: 0 },
{
size: OperatorNodeSize.medium
}
);

wf.updateNode(additionalSimNode, {
state: {
chartSettings: simulateChartSettings
}
});

wf.addEdge(
modelConfigNode.id,
modelConfigNode.outputs[0].id,
additionalSimNode.id,
additionalSimNode.inputs[0].id,
[
{ x: 0, y: 0 },
{ x: 0, y: 0 }
]
);
wf.addEdge(
interventionNode.id,
interventionNode.outputs[0].id,
additionalSimNode.id,
additionalSimNode.inputs[1].id,
[
{ x: 0, y: 0 },
{ x: 0, y: 0 }
]
);
wf.addEdge(
additionalSimNode.id,
additionalSimNode.outputs[0].id,
compareDatasetNode.id,
compareDatasetNode.inputs[compareDatasetIndex].id,
[
{ x: 0, y: 0 },
{ x: 0, y: 0 }
]
);
compareDatasetIndex++;
}
});

// each intervention node will be connected to a simulate node along with each model config node
modelConfigNodes.forEach((modelConfigNode) => {
const simulateNode = wf.addNode(
SimulateCiemssOp,
{ x: 0, y: 0 },
{
size: OperatorNodeSize.medium
}
);

wf.updateNode(simulateNode, {
state: {
chartSettings: simulateChartSettings
}
});

wf.addEdge(modelConfigNode.id, modelConfigNode.outputs[0].id, simulateNode.id, simulateNode.inputs[0].id, [
{ x: 0, y: 0 },
{ x: 0, y: 0 }
]);

wf.addEdge(interventionNode.id, interventionNode.outputs[0].id, simulateNode.id, simulateNode.inputs[1].id, [
wf.addEdge(
simulateNode.id,
simulateNode.outputs[0].id,
compareDatasetNode.id,
compareDatasetNode.inputs[compareDatasetIndex].id,
[
{ x: 0, y: 0 },
{ x: 0, y: 0 }
]);

wf.addEdge(
simulateNode.id,
simulateNode.outputs[0].id,
compareDatasetNode.id,
compareDatasetNode.inputs[compareDatasetIndex].id,
[
{ x: 0, y: 0 },
{ x: 0, y: 0 }
]
);
compareDatasetIndex++;
});
]
);
compareDatasetIndex++;
});

// Wait for all interventionPromises to resolve
await Promise.all(interventionPromises);

// 4. Run layout
wf.runDagreLayout();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
:options="interventionPolicies"
option-label="name"
option-value="id"
placeholder="Select an intervention policy"
placeholder="Select an intervention policy (optional)"
@update:model-value="scenario.setInterventionSpec($event, i)"
:key="i"
:disabled="isEmpty(interventionPolicies)"
Expand Down

0 comments on commit 1e886b1

Please sign in to comment.