Skip to content

Commit

Permalink
Allow for a single unit column
Browse files Browse the repository at this point in the history
- When there's a single unit column, use that column for both dosing and observations.
- Split the CSV data into dosing rows and observation rows.
- Add administration route to the Map Dosing screen.
- Allow for dimensionless observation units.
- Filter mapped observation variables for compatibility with the observation unit value.
  • Loading branch information
eatyourgreens committed Mar 4, 2024
1 parent 0341d5b commit 9574b76
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 43 deletions.
65 changes: 29 additions & 36 deletions frontend-v2/src/features/data/MapDosing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,22 @@ const MapDosing: FC<IMapDosing> = ({ state, firstTime }: IMapDosing) => {
const amountField = state.fields.find(
(field, i) => state.normalisedFields[i] === 'Amount'
);
const dosingRows = amountField ? state.data.filter(row => row[amountField] && row[amountField] !== '.') : [];
const amountValues = amountField ?
state.data.map(row => row[amountField]) :
dosingRows.map(row => row[amountField]) :
[];
const amountUnitField = state.fields.find(
(field, i) => state.normalisedFields[i] === 'Amount Unit'
(field, i) => ['Amount Unit', 'Unit'].includes(state.normalisedFields[i])
);
const amountUnits = state.data.map(row => row[amountUnitField || 'Amount Unit']);
const amountUnits = dosingRows.map(row => row[amountUnitField || 'Amount Unit']);
const administrationIdField = state.fields.find(
(field, i) => state.normalisedFields[i] === 'Administration ID'
);
const administrationIds = administrationIdField ?
state.data.map(row => row[administrationIdField]) :
dosingRows.map(row => row[administrationIdField]) :
[];
const uniqueAdministrationIds = [...new Set(administrationIds)];
const amountVariables = state.data.map(row => row['Dosing Variable']);
const amountVariables = dosingRows.map(row => row['Dosing Variable']);

const isAmount = (variable: VariableRead) => {
const amountUnits = units?.find(
Expand Down Expand Up @@ -112,6 +113,16 @@ const MapDosing: FC<IMapDosing> = ({ state, firstTime }: IMapDosing) => {
{administrationIdField}
</Typography>
</TableCell>
<TableCell>
<Typography>
Amount
</Typography>
</TableCell>
<TableCell>
<Typography>
Route
</Typography>
</TableCell>
<TableCell>
<Typography>
Unit
Expand All @@ -126,15 +137,27 @@ const MapDosing: FC<IMapDosing> = ({ state, firstTime }: IMapDosing) => {
</TableHead>
<TableBody>
{uniqueAdministrationIds.map((adminId, index) => {
const currentRow = state.data.find(row => administrationIdField ? row[administrationIdField] === adminId : true);
const currentRow = dosingRows.find(row => administrationIdField ? row[administrationIdField] === adminId : true);
const selectedVariable = variables?.find(variable => variable.qname === currentRow?.['Dosing Variable']);
const compatibleUnits = units?.find(unit => unit.id === selectedVariable?.unit)?.compatible_units;
const adminUnit = amountUnitField && currentRow && currentRow[amountUnitField];
const amount = amountField && currentRow?.[amountField];
const route = currentRow?.['ROUTE'];
return (
<TableRow>
<TableCell>
{adminId}
</TableCell>
<TableCell>
<Typography>
{amount}
</Typography>
</TableCell>
<TableCell>
<Typography>
{route}
</Typography>
</TableCell>
<TableCell>
{adminUnit ?
adminUnit :
Expand Down Expand Up @@ -175,36 +198,6 @@ const MapDosing: FC<IMapDosing> = ({ state, firstTime }: IMapDosing) => {
})}
</TableBody>
</Table>
<Table>
<TableHead>
<TableRow>
<TableCell>
<Typography>
Amount
</Typography>
</TableCell>
<TableCell>
<Typography>
Unit
</Typography>
</TableCell>
<TableCell>
<Typography>
Mapping
</Typography>
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{amountValues.map((amount, index) => (
<TableRow key={index}>
<TableCell>{amount}</TableCell>
<TableCell>{amountUnits[index]}</TableCell>
<TableCell>{amountVariables[index]}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Box>
</>
)
Expand Down
26 changes: 19 additions & 7 deletions frontend-v2/src/features/data/MapObservations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,19 @@ const MapObservations: FC<IMapObservations> = ({state}: IMapObservations) => {
const observationIdField = state.fields.find(
(field, i) => state.normalisedFields[i] === 'Observation ID'
);
const observationRows = observationField ? state.data.filter(row => row[observationField] !== '.') : [];
const observationIds = observationIdField ?
state.data.map(row => row[observationIdField]) :
observationRows.map(row => row[observationIdField]) :
[observationField];
const uniqueObservationIds = [...new Set(observationIds)];
const observationValues = observationField ?
state.data.map(row => row[observationField]) :
observationRows.map(row => row[observationField]) :
[];
const observationUnitField = state.fields.find(
(field, i) => state.normalisedFields[i] === 'Observation Unit'
(field, i) => ['Observation Unit', 'Unit'].includes(state.normalisedFields[i])
);
const observationUnits = state.data.map(row => row[observationUnitField || 'Observation Unit']);
const observationVariables = state.data.map(row => row['Observation Variable']);
const observationUnits = observationRows.map(row => row[observationUnitField || 'Observation Unit']);
const observationVariables = observationRows.map(row => row['Observation Variable']);

const filterOutputs = model?.is_library_model
? ["environment.t", "PDCompartment.C_Drug"]
Expand Down Expand Up @@ -114,10 +115,21 @@ const MapObservations: FC<IMapObservations> = ({state}: IMapObservations) => {
</TableHead>
<TableBody>
{uniqueObservationIds.map((obsId) => {
const currentRow = state.data.find(row => observationIdField ? row[observationIdField] === obsId : true);
const currentRow = observationRows.find(row => observationIdField ? row[observationIdField] === obsId : true);
const selectedVariable = variables?.find(variable => variable.qname === currentRow?.['Observation Variable']);
const compatibleUnits = units?.find(unit => unit.id === selectedVariable?.unit)?.compatible_units;
const obsUnit = observationUnitField && currentRow && currentRow[observationUnitField];
let obsUnitSymbol = obsUnit;
['%', 'fraction', 'ratio'].forEach(token => {
if (obsUnitSymbol?.toLowerCase().includes(token)) {
obsUnitSymbol = '';
}
});
const compatibleVariables = modelOutputs.filter(variable => {
const variableUnit = units?.find(unit => unit.id === variable.unit);
const compatibleSymbols = variableUnit?.compatible_units.map(u => u.symbol);
return compatibleSymbols?.includes(obsUnitSymbol || '');
});
return (
<TableRow>
<TableCell>
Expand Down Expand Up @@ -152,7 +164,7 @@ const MapObservations: FC<IMapObservations> = ({state}: IMapObservations) => {
value={selectedVariable?.qname}
onChange={handleObservationChange(obsId)}
>
{modelOutputs?.map((variable) => (
{compatibleVariables?.map((variable) => (
<MenuItem key={variable.name} value={variable.qname}>{variable.name}</MenuItem>
))}
</Select>
Expand Down
1 change: 1 addition & 0 deletions frontend-v2/src/features/data/normaliseDataHeaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const normalisation = {
'Regressor': ['x', 'regressor'],
'Time': ['time', 't', 'ivar'],
'Time Unit': ['time_unit', 'time_units', 't_units', 'tunit'],
'Unit': ['unit', 'units'],
}

export const manditoryHeaders = ['ID', 'Time', 'Observation', 'Administration ID', 'Amount']
Expand Down

0 comments on commit 9574b76

Please sign in to comment.