Skip to content

Commit

Permalink
feat: remove simulation requests when adding new plots or sliders (#569)
Browse files Browse the repository at this point in the history
* feat: request all outputs from simulation except amounts

* feat: prevent re-simulating when adding sliders
  • Loading branch information
martinjrobins authored Nov 20, 2024
1 parent 6e93ea9 commit 5514893
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 69 deletions.
28 changes: 17 additions & 11 deletions frontend-v2/src/features/simulation/SimulationSliderView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,13 @@ const SimulationSliderView: FC<SimulationSliderProps> = ({
const [value, setValue] = useState<number>(defaultValue);

useEffect(() => {
setValue(defaultValue);
onChange(slider.variable, defaultValue);
}, [defaultValue, onChange, slider.variable]);
// don't set the value of the slider until the variable is loaded
if (variable) {
const defaultValue = variable.default_value || 1.0;
setValue(defaultValue);
onChange(slider.variable, defaultValue);
}
}, [onChange, variable]);

const handleSliderChange = (
event: Event | SyntheticEvent<Element, Event>,
Expand All @@ -78,8 +82,10 @@ const SimulationSliderView: FC<SimulationSliderProps> = ({
};

const handleReset = () => {
setValue(defaultValue);
onChange(slider.variable, defaultValue);
if (variable) {
setValue(defaultValue);
onChange(slider.variable, defaultValue);
}
};

const handleSave = () => {
Expand Down Expand Up @@ -145,9 +151,9 @@ const SimulationSliderView: FC<SimulationSliderProps> = ({
</Typography>
</Tooltip>
</Stack>
<Box sx={{ display: 'flex', justifyContent: 'flex-end'}}>
<Box sx={{ display: 'flex', justifyContent: 'flex-end' }}>
<Tooltip title={"Reset to saved default value"} placement="top">
<IconButton aria-label="reset" onClick={handleReset} sx={{ padding: '2px'}}>
<IconButton aria-label="reset" onClick={handleReset} sx={{ padding: '2px' }}>
<Replay fontSize="small" />
</IconButton>
</Tooltip>
Expand All @@ -156,18 +162,18 @@ const SimulationSliderView: FC<SimulationSliderProps> = ({
aria-label="save"
onClick={handleSave}
disabled={isSharedWithMe}
sx={{ padding: '2px'}}
sx={{ padding: '2px' }}
>
<Save fontSize="small" />
</IconButton>
</Tooltip>
<Tooltip title={"Widen range"} placement="top">
<IconButton aria-label="widen" onClick={handleWider} sx={{ padding: '2px'}}>
<IconButton aria-label="widen" onClick={handleWider} sx={{ padding: '2px' }}>
<OpenInFull fontSize="small" />
</IconButton>
</Tooltip>
<Tooltip title={"Narrow range"} placement="top">
<IconButton aria-label="restrict" onClick={handleNarrow} sx={{ padding: '2px'}}>
<IconButton aria-label="restrict" onClick={handleNarrow} sx={{ padding: '2px' }}>
<CloseFullscreen fontSize="small" />
</IconButton>
</Tooltip>
Expand All @@ -176,7 +182,7 @@ const SimulationSliderView: FC<SimulationSliderProps> = ({
aria-label="delete"
onClick={handleDelete}
disabled={isSharedWithMe}
sx={{ padding: '2px'}}
sx={{ padding: '2px' }}
>
<Delete fontSize="small" />
</IconButton>
Expand Down
10 changes: 4 additions & 6 deletions frontend-v2/src/features/simulation/Simulations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import {
import SimulationPlotView from "./SimulationPlotView";
import useSimulation from "./useSimulation";
import useSimulationInputs from "./useSimulationInputs";
import useSimulatedVariables from "./useSimulatedVariables";
import useDirty from "../../hooks/useDirty";
import paramPriority from "../model/paramPriority";
import { selectIsProjectShared } from "../login/loginSlice";
Expand Down Expand Up @@ -151,7 +150,9 @@ const Simulations: FC = () => {
const [sliderValues, setSliderValues] = useState<SliderValues | undefined>(
undefined,
);
console.log('sliderValues', sliderValues);
const handleChangeSlider = useCallback((variable: number, value: number) => {
console.log('handleChangeSlider', variable, value);
setSliderValues((prevSliderValues) => ({
...prevSliderValues,
[variable]: value,
Expand Down Expand Up @@ -196,12 +197,11 @@ const Simulations: FC = () => {
variables,
timeMax,
);
const simulatedVariables = useSimulatedVariables(variables, sliderValues);
const {
loadingSimulate,
data,
error: simulateError,
} = useSimulation(simInputs, simulatedVariables, model);
} = useSimulation(simInputs, model);

const refSimInputs = useSimulationInputs(
model,
Expand All @@ -210,10 +210,8 @@ const Simulations: FC = () => {
variables,
timeMax,
);
const referenceVariables = useSimulatedVariables(variables, EMPTY_OBJECT);
const { data: dataReference } = useSimulation(
refSimInputs,
referenceVariables,
showReference ? model : undefined
);

Expand Down Expand Up @@ -256,6 +254,7 @@ const Simulations: FC = () => {
// reset form and sliders if simulation changes
useEffect(() => {
if (simulation && variables) {
console.log('reset form and sliders if simulation changes');
setSliderValues((s) => {
const initialValues = getSliderInitialValues(simulation, s, variables);
return initialValues;
Expand All @@ -268,7 +267,6 @@ const Simulations: FC = () => {
const [exportSimulation, { error: exportSimulateErrorBase }] =
useExportSimulation({
simInputs,
simulatedVariables,
model,
project,
});
Expand Down
6 changes: 2 additions & 4 deletions frontend-v2/src/features/simulation/useExportSimulation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {

interface iExportSimulation {
simInputs: Simulate;
simulatedVariables: { qname: string; value: number | undefined }[];
model: CombinedModelRead | undefined;
project: ProjectRead | undefined;
}
Expand Down Expand Up @@ -41,7 +40,6 @@ const parseResponse = (data: any, timeCol: number, label: string) => {

export default function useExportSimulation({
simInputs,
simulatedVariables,
model,
project,
}: iExportSimulation): [() => void, { error: any }] {
Expand Down Expand Up @@ -70,12 +68,12 @@ export default function useExportSimulation({
project &&
groups
) {
console.log("Export to CSV: simulating with params", simulatedVariables);
console.log("Export to CSV: simulating with params", simInputs.variables);
simulate({
id: model.id,
simulate: simInputs,
}).then((response) => {
let rows = simulatedVariables.map((p) => [p.qname, p.value]);
let rows = Object.keys(simInputs.variables).map((key) => [key, simInputs.variables[key]]);
if (response?.data) {
const cols = Object.keys(response.data[0].outputs);
const vars = cols.map((vid) =>
Expand Down
34 changes: 0 additions & 34 deletions frontend-v2/src/features/simulation/useSimulatedVariables.ts

This file was deleted.

4 changes: 1 addition & 3 deletions frontend-v2/src/features/simulation/useSimulation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ const SIMULATION_PAGES = [PageName.SIMULATIONS, PageName.RESULTS];

export default function useSimulation(
simInputs: Simulate,
simulatedVariables: { qname: string; value: number | undefined }[],
model: CombinedModelRead | undefined,
) {
const { compound, protocols } = useProtocols();
Expand All @@ -46,7 +45,7 @@ export default function useSimulation(
SIMULATION_PAGES.includes(page)
) {
setLoadingSimulate(true);
console.log("Simulating with params", simulatedVariables);
console.log("Simulating with params", simInputs.variables);
simulate({
id: model.id,
simulate: simInputs,
Expand All @@ -70,7 +69,6 @@ export default function useSimulation(
protocols,
simulate,
JSON.stringify(simInputs),
JSON.stringify(simulatedVariables),
page,
]);

Expand Down
46 changes: 35 additions & 11 deletions frontend-v2/src/features/simulation/useSimulationInputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,55 @@ const DEFAULT_INPUTS = {
time_max: 0,
};

enum simulationInputMode {
REQUESTED_OUTPUTS = "REQUESTED",
ALL_OUTPUTS = "ALL",
ALL_OUTPUTS_NO_AMOUNTS = "ALL_NO_AMOUNTS",
}

const getSimulateInput = (
model: CombinedModelRead,
simulation: SimulationRead,
sliderValues: SliderValues,
variables?: VariableRead[],
timeMax?: number,
allOutputs: boolean = false,
mode: simulationInputMode = simulationInputMode.REQUESTED_OUTPUTS,
): Simulate => {
const outputs: string[] = [];

const constantVariables = variables?.filter((v) => v.constant) || [];
const simulateVariables: { [key: string]: number } = {};
for (const slider of simulation?.sliders || []) {
if (sliderValues[slider.variable]) {
const variable = variables?.find((v) => v.id === slider.variable);
if (variable) {
simulateVariables[variable.qname] = sliderValues[slider.variable];
}
constantVariables.forEach((v: VariableRead) => {
const result = { qname: v.qname, value: v.default_value || 0 };
if (sliderValues && sliderValues[v.id]) {
result.value = sliderValues[v.id];
}
}
if (allOutputs) {
simulateVariables[result.qname] = result.value;
});

if (mode == simulationInputMode.ALL_OUTPUTS) {
for (const v of variables || []) {
if (!v.constant) {
outputs.push(v.qname);
}
}
} else {
} else if (mode == simulationInputMode.ALL_OUTPUTS_NO_AMOUNTS) {
const amountNames = ["Aa", "A1", "A2", "A3"];
for (const v of variables || []) {
let isAmount = model.is_library_model && amountNames.includes(v.name);
if (!v.constant && !isAmount) {
outputs.push(v.qname);
}
}
for (const plot of simulation?.plots || []) {
for (const y_axis of plot.y_axes) {
const variable = variables?.find((v) => v.id === y_axis.variable);
if (variable && !outputs.includes(variable.qname)) {
outputs.push(variable.qname);
}
}
}
} else if (mode == simulationInputMode.REQUESTED_OUTPUTS) {
for (const plot of simulation?.plots || []) {
for (const y_axis of plot.y_axes) {
const variable = variables?.find((v) => v.id === y_axis.variable);
Expand Down Expand Up @@ -91,7 +115,7 @@ export default function useSimulationInputs(
return useMemo(
() =>
model && simulation && sliderValues
? getSimulateInput(model, simulation, sliderValues, variables, timeMax)
? getSimulateInput(model, simulation, sliderValues, variables, timeMax, simulationInputMode.ALL_OUTPUTS_NO_AMOUNTS)
: DEFAULT_INPUTS,
[simulation, sliderValues, variables, timeMax],
);
Expand Down

0 comments on commit 5514893

Please sign in to comment.