Skip to content

Commit

Permalink
refactor: add thresholds to variable model
Browse files Browse the repository at this point in the history
Add `variable.lower_threshold` and `variable.upper_threshold` to the variable model, so that thresholds are savedin the app database.
  • Loading branch information
eatyourgreens committed Nov 25, 2024
1 parent 4f1692a commit b0395db
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 69 deletions.
12 changes: 0 additions & 12 deletions frontend-v2/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,15 @@ import "react-toastify/dist/ReactToastify.css";
import { SimulationContext } from "./contexts/SimulationContext";
import { SimulateResponse } from "./app/backendApi";
import { CollapsibleSidebarProvider } from "./shared/contexts/CollapsibleSidebarContext";
import { useModelTimeIntervals } from "./hooks/useModelTimeIntervals";

type Threshold = { lower: number; upper: number };
export type Thresholds = { [key: string]: Threshold };

const THRESHOLDS: Thresholds = {};

function App() {
const dispatch = useAppDispatch();
const isAuth = useSelector(isAuthenticated);
const error = useSelector((state: RootState) => state.login.error);
const [intervals, setIntervals] = useModelTimeIntervals();
const [simulations, setSimulations] = useState<SimulateResponse[]>([]);
const [thresholds, setThresholds] = useState<Thresholds>(THRESHOLDS);
const simulationContext = {
simulations,
setSimulations,
intervals,
setIntervals,
thresholds,
setThresholds,
};

const onLogin = (username: string, password: string) => {
Expand Down
16 changes: 16 additions & 0 deletions frontend-v2/src/app/backendApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3507,6 +3507,10 @@ export type Variable = {
upper_bound?: number | null;
/** default value for this variable */
default_value?: number;
/** lower threshold for this variable */
lower_threshold?: number | null;
/** upper threshold for this variable */
upper_threshold?: number | null;
/** True if default_value is stored as the log of this value */
is_log?: boolean;
/** name of the variable */
Expand Down Expand Up @@ -3553,6 +3557,10 @@ export type VariableRead = {
upper_bound?: number | null;
/** default value for this variable */
default_value?: number;
/** lower threshold for this variable */
lower_threshold?: number | null;
/** upper threshold for this variable */
upper_threshold?: number | null;
/** True if default_value is stored as the log of this value */
is_log?: boolean;
/** name of the variable */
Expand Down Expand Up @@ -3598,6 +3606,10 @@ export type PatchedVariable = {
upper_bound?: number | null;
/** default value for this variable */
default_value?: number;
/** lower threshold for this variable */
lower_threshold?: number | null;
/** upper threshold for this variable */
upper_threshold?: number | null;
/** True if default_value is stored as the log of this value */
is_log?: boolean;
/** name of the variable */
Expand Down Expand Up @@ -3644,6 +3656,10 @@ export type PatchedVariableRead = {
upper_bound?: number | null;
/** default value for this variable */
default_value?: number;
/** lower threshold for this variable */
lower_threshold?: number | null;
/** upper threshold for this variable */
upper_threshold?: number | null;
/** True if default_value is stored as the log of this value */
is_log?: boolean;
/** name of the variable */
Expand Down
5 changes: 1 addition & 4 deletions frontend-v2/src/contexts/SimulationContext.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { createContext } from "react";
import { SimulateResponse, TimeIntervalRead } from "../app/backendApi";
import { Thresholds } from "../App";
import { SimulateResponse } from "../app/backendApi";

export const SimulationContext = createContext({
simulations: [] as SimulateResponse[],
setSimulations: (simulations: SimulateResponse[]) => {},
thresholds: {} as Thresholds,
setThresholds: (thresholds: Thresholds) => {},
});
14 changes: 1 addition & 13 deletions frontend-v2/src/features/model/VariableRow.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// src/components/ProjectTable.tsx
import { FC, useEffect, useContext } from "react";
import { FC, useEffect } from "react";
import { Control, useFieldArray, useForm } from "react-hook-form";
import {
TableCell,
Expand All @@ -25,7 +25,6 @@ import { useSelector } from "react-redux";
import { RootState } from "../../app/store";
import { selectIsProjectShared } from "../login/loginSlice";
import useEditProtocol from "./useEditProtocol";
import { SimulationContext } from "../../contexts/SimulationContext";

interface Props {
project: ProjectRead;
Expand Down Expand Up @@ -80,7 +79,6 @@ const VariableRow: FC<Props> = ({
control,
name: "model.derived_variables",
});
const { thresholds, setThresholds } = useContext(SimulationContext);

const {
handleSubmit,
Expand Down Expand Up @@ -246,16 +244,6 @@ const VariableRow: FC<Props> = ({
pkpd_model: model.id,
type,
});

if (type === "AUC") {
setThresholds({
...thresholds,
[variable.name]: {
lower: 0,
upper: Infinity,
},
});
}
};

const removeDerived = (index: number | number[]) => {
Expand Down
32 changes: 15 additions & 17 deletions frontend-v2/src/features/model/secondary/ThresholdsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeEvent, FC, useContext, useState } from "react";
import { ChangeEvent, FC, useState } from "react";
import {
MenuItem,
Select,
Expand All @@ -21,9 +21,9 @@ import {
useProjectRetrieveQuery,
useUnitListQuery,
useVariableListQuery,
useVariableUpdateMutation,
VariableRead,
} from "../../../app/backendApi";
import { SimulationContext } from "../../../contexts/SimulationContext";

function VariableRow({
variable,
Expand All @@ -32,32 +32,30 @@ function VariableRow({
variable: VariableRead;
unit: UnitRead | undefined;
}) {
const { thresholds, setThresholds } = useContext(SimulationContext);
const [updateVariable] = useVariableUpdateMutation();
const [unitSymbol, setUnitSymbol] = useState<string | undefined>(
unit?.symbol,
);
function onChangeLowerThreshold(event: ChangeEvent<HTMLInputElement>) {
const newValue = parseFloat(event.target.value);
const oldThresholds = thresholds[variable.name];
if (!isNaN(newValue)) {
setThresholds({
...thresholds,
[variable.name]: {
...oldThresholds,
lower: newValue,
updateVariable({
id: variable.id,
variable: {
...variable,
lower_threshold: newValue,
},
});
}
}
function onChangeUpperThreshold(event: ChangeEvent<HTMLInputElement>) {
const newValue = parseFloat(event.target.value);
const oldThresholds = thresholds[variable.name];
if (!isNaN(newValue)) {
setThresholds({
...thresholds,
[variable.name]: {
...oldThresholds,
upper: newValue,
updateVariable({
id: variable.id,
variable: {
...variable,
upper_threshold: newValue,
},
});
}
Expand All @@ -76,14 +74,14 @@ function VariableRow({
<TableCell>
<TextField
type="number"
defaultValue={thresholds[variable.name]?.lower}
defaultValue={variable.lower_threshold || 0}
onChange={onChangeLowerThreshold}
/>
</TableCell>
<TableCell>
<TextField
type="number"
defaultValue={thresholds[variable.name]?.upper}
defaultValue={variable.upper_threshold || Infinity}
onChange={onChangeUpperThreshold}
/>
</TableCell>
Expand Down
27 changes: 4 additions & 23 deletions frontend-v2/src/features/results/useParameters.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useContext } from "react";

import {
SimulateResponse,
TimeIntervalRead,
Expand All @@ -11,9 +9,7 @@ import {
timesPerInterval,
valuesPerInterval,
} from "./utils";
import { SimulationContext } from "../../contexts/SimulationContext";
import { useVariables } from "./useVariables";
import { Thresholds } from "../../App";
import { useModelTimeIntervals } from "../../hooks/useModelTimeIntervals";
import { useUnits } from "./useUnits";

Expand Down Expand Up @@ -66,32 +62,21 @@ const timeOverLowerThresholdPerInterval = (
intervalValues: number[],
intervalTimes: number[],
variable: VariableRead,
thresholds: Thresholds,
) => {
const threshold = variable && thresholds[variable.name];
return timeOverThreshold(
intervalTimes,
intervalValues,
threshold?.lower || 0,
);
const threshold = variable?.lower_threshold || 0;
return timeOverThreshold(intervalTimes, intervalValues, threshold);
};

const timeOverUpperThresholdPerInterval = (
intervalValues: number[],
intervalTimes: number[],
variable: VariableRead,
thresholds: Thresholds,
) => {
const threshold = variable && thresholds[variable.name];
return timeOverThreshold(
intervalTimes,
intervalValues,
threshold?.upper || Infinity,
);
const threshold = variable?.upper_threshold || Infinity;
return timeOverThreshold(intervalTimes, intervalValues, threshold);
};

export function useParameters() {
const { thresholds } = useContext(SimulationContext);
const [baseIntervals] = useModelTimeIntervals();
const variables = useVariables();
const intervals = useNormalisedIntervals(baseIntervals);
Expand Down Expand Up @@ -176,7 +161,6 @@ export function useParameters() {
intervalValues,
intervalTimes,
variable,
thresholds,
),
)
: 0;
Expand Down Expand Up @@ -205,7 +189,6 @@ export function useParameters() {
intervalValues,
intervalTimes,
variable,
thresholds,
),
)
: 0;
Expand Down Expand Up @@ -234,13 +217,11 @@ export function useParameters() {
intervalValues,
intervalTimes,
variable,
thresholds,
) -
timeOverUpperThresholdPerInterval(
intervalValues,
intervalTimes,
variable,
thresholds,
),
)
: 0;
Expand Down
23 changes: 23 additions & 0 deletions pkpdapp/pkpdapp/migrations/0017_auto_20241125_1415.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.2.25 on 2024-11-25 14:15

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('pkpdapp', '0016_auto_20241122_1523'),
]

operations = [
migrations.AddField(
model_name='variable',
name='lower_threshold',
field=models.FloatField(blank=True, help_text='lower threshold for this variable', null=True),
),
migrations.AddField(
model_name='variable',
name='upper_threshold',
field=models.FloatField(blank=True, help_text='upper threshold for this variable', null=True),
),
]
8 changes: 8 additions & 0 deletions pkpdapp/pkpdapp/models/variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ class Variable(StoredModel):
default_value = models.FloatField(
default=1, help_text="default value for this variable"
)
lower_threshold = models.FloatField(
blank=True, null=True, help_text="lower threshold for this variable"
)
upper_threshold = models.FloatField(
blank=True, null=True, help_text="upper threshold for this variable"
)

is_log = models.BooleanField(
default=False,
Expand Down Expand Up @@ -411,4 +417,6 @@ def copy(self, variable, new_project):
self.unit_symbol = variable.unit_symbol
self.constant = variable.constant
self.protocol = new_protocol
self.lower_threshold = variable.lower_threshold
self.upper_threshold = variable.upper_threshold
self.save()
20 changes: 20 additions & 0 deletions pkpdapp/schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4847,6 +4847,16 @@ components:
type: number
format: double
description: default value for this variable
lower_threshold:
type: number
format: double
nullable: true
description: lower threshold for this variable
upper_threshold:
type: number
format: double
nullable: true
description: upper threshold for this variable
is_log:
type: boolean
description: True if default_value is stored as the log of this value
Expand Down Expand Up @@ -5656,6 +5666,16 @@ components:
type: number
format: double
description: default value for this variable
lower_threshold:
type: number
format: double
nullable: true
description: lower threshold for this variable
upper_threshold:
type: number
format: double
nullable: true
description: upper threshold for this variable
is_log:
type: boolean
description: True if default_value is stored as the log of this value
Expand Down

0 comments on commit b0395db

Please sign in to comment.