Skip to content

Commit

Permalink
feat: add aggregates to raw data and update Hydro matrices
Browse files Browse the repository at this point in the history
  • Loading branch information
hdinia committed Sep 16, 2024
1 parent 182e984 commit c7afb81
Show file tree
Hide file tree
Showing 16 changed files with 214 additions and 77 deletions.
14 changes: 14 additions & 0 deletions antarest/study/web/raw_studies_blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import typing as t
from pathlib import Path, PurePosixPath

import numpy as np
from fastapi import APIRouter, Body, Depends, File, HTTPException
from fastapi.params import Param, Query
from starlette.responses import FileResponse, JSONResponse, PlainTextResponse, Response, StreamingResponse
Expand Down Expand Up @@ -114,6 +115,7 @@ def get_study(
path: str = Param("/", examples=get_path_examples()), # type: ignore
depth: int = 3,
formatted: bool = True,
aggregates: bool = False,
current_user: JWTUser = Depends(auth.get_current_user),
) -> t.Any:
"""
Expand All @@ -136,6 +138,17 @@ def get_study(
parameters = RequestParameters(user=current_user)
output = study_service.get(uuid, path, depth=depth, formatted=formatted, params=parameters)

# Temporary workaround to calculate aggregates for 2D matrices
if aggregates and isinstance(output, dict) and "data" in output:
matrix = np.asarray(output["data"])
if matrix.ndim == 2:
aggregate_values = {
"min": np.nanmin(matrix, axis=1).tolist(),
"max": np.nanmax(matrix, axis=1).tolist(),
"avg": np.nanmean(matrix, axis=1).tolist(),
}
output["aggregates"] = aggregate_values

if isinstance(output, bytes):
# Guess the suffix form the target data
resource_path = PurePosixPath(path)
Expand Down Expand Up @@ -189,6 +202,7 @@ def get_study(
indent=None,
separators=(",", ":"),
).encode("utf-8")

return Response(content=json_response, media_type="application/json")

@bp.get(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import {
StudyMetadata,
Area,
MatrixType,
} from "../../../../../../../../common/types";
import { StudyMetadata, Area } from "../../../../../../../../common/types";
import client from "../../../../../../../../services/api/client";
import { MatrixDataDTO } from "../../../../../../../common/MatrixGrid/types";
import { AreaCoefficientItem } from "../utils";

////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -44,7 +41,7 @@ export async function setAllocationFormFields(

export const getAllocationMatrix = async (
studyId: StudyMetadata["id"],
): Promise<MatrixType> => {
): Promise<MatrixDataDTO> => {
const res = await client.get(
`v1/studies/${studyId}/areas/hydro/allocation/matrix`,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import {
StudyMetadata,
Area,
MatrixType,
} from "../../../../../../../../common/types";
import { StudyMetadata, Area } from "../../../../../../../../common/types";
import client from "../../../../../../../../services/api/client";
import { MatrixDataDTO } from "../../../../../../../common/MatrixGrid/types";
import { AreaCoefficientItem } from "../utils";

////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -44,7 +41,7 @@ export async function setCorrelationFormFields(

export async function getCorrelationMatrix(
studyId: StudyMetadata["id"],
): Promise<MatrixType> {
): Promise<MatrixDataDTO> {
const res = await client.get(
`v1/studies/${studyId}/areas/hydro/correlation/matrix`,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import useAppSelector from "../../../../../../../redux/hooks/useAppSelector";
import { getCurrentAreaId } from "../../../../../../../redux/selectors";
import { MATRICES, HydroMatrixType } from "./utils";
import Matrix from "../../../../../../common/MatrixGrid/Matrix";
import { Box } from "@mui/material";

interface Props {
type: HydroMatrixType;
Expand All @@ -17,14 +18,18 @@ function HydroMatrix({ type }: Props) {
////////////////////////////////////////////////////////////////

return (
<Matrix
title={hydroMatrix.title}
url={hydroMatrix.url.replace("{areaId}", areaId)}
customColumns={hydroMatrix.columns}
rowHeaders={hydroMatrix.rowHeaders}
enableReadOnly={hydroMatrix.enableReadOnly}
enablePercentDisplay={hydroMatrix.enablePercentDisplay}
/>
<Box sx={{ width: 1, height: 1, p: 2 }}>
<Matrix
title={hydroMatrix.title}
url={hydroMatrix.url.replace("{areaId}", areaId)}
customColumns={hydroMatrix.columns}
customRowHeaders={hydroMatrix.rowHeaders}
enableDateTimeColumn={hydroMatrix.enableDateTimeColumn}
enableReadOnly={hydroMatrix.enableReadOnly}
enablePercentDisplay={hydroMatrix.enablePercentDisplay}
fetchMatrixData={hydroMatrix.fetchFn}
/>
</Box>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ function Hydro() {
// JSX
////////////////////////////////////////////////////////////////

return <TabWrapper study={study} tabList={tabList} />;
return (
<TabWrapper study={study} tabList={tabList} tabStyle="withoutBorder" />
);
}

export default Hydro;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MatrixType } from "../../../../../../../common/types";
import { MatrixDataDTO } from "../../../../../../common/MatrixGrid/types";
import { SplitViewProps } from "../../../../../../common/SplitView";
import { getAllocationMatrix } from "./Allocation/utils";
import { getCorrelationMatrix } from "./Correlation/utils";
Expand Down Expand Up @@ -26,7 +26,7 @@ export const HydroMatrix = {
// Types
////////////////////////////////////////////////////////////////

export type fetchMatrixFn = (studyId: string) => Promise<MatrixType>;
export type fetchMatrixFn = (studyId: string) => Promise<MatrixDataDTO>;
export type HydroMatrixType = (typeof HydroMatrix)[keyof typeof HydroMatrix];

export interface HydroMatrixProps {
Expand All @@ -35,6 +35,7 @@ export interface HydroMatrixProps {
columns?: string[];
rowHeaders?: string[];
fetchFn?: fetchMatrixFn;
enableDateTimeColumn?: boolean;
enableReadOnly?: boolean;
enablePercentDisplay?: boolean;
}
Expand Down Expand Up @@ -112,6 +113,7 @@ export const MATRICES: Matrices = {
url: "input/hydro/common/capacity/creditmodulations_{areaId}",
columns: generateColumns("%"),
rowHeaders: ["Generating Power", "Pumping Power"],
enableDateTimeColumn: false,
enablePercentDisplay: true,
},
[HydroMatrix.EnergyCredits]: {
Expand All @@ -133,7 +135,7 @@ export const MATRICES: Matrices = {
[HydroMatrix.WaterValues]: {
title: "Water Values",
url: "input/hydro/common/capacity/waterValues_{areaId}",
// columns: generateColumns("%"), // TODO this causes the data is undefined error
// columns: generateColumns("%"), // TODO this causes Runtime error to be fixed
},
[HydroMatrix.HydroStorage]: {
title: "Hydro Storage",
Expand Down Expand Up @@ -181,13 +183,15 @@ export const MATRICES: Matrices = {
title: "Allocation",
url: "",
fetchFn: getAllocationMatrix,
enableDateTimeColumn: false,
enableReadOnly: true,
enablePercentDisplay: true,
},
[HydroMatrix.Correlation]: {
title: "Correlation",
url: "",
fetchFn: getCorrelationMatrix,
enableDateTimeColumn: false,
enableReadOnly: true,
enablePercentDisplay: true,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function Load() {
// JSX
////////////////////////////////////////////////////////////////

return <Matrix url={url} />;
return <Matrix url={url} enableAggregateColumns />;
}

export default Load;
17 changes: 13 additions & 4 deletions webapp/src/components/common/MatrixGrid/Matrix.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,44 @@ import { StudyMetadata } from "../../../common/types";
import { MatrixContainer, MatrixHeader, MatrixTitle } from "./style";
import MatrixActions from "./MatrixActions";
import EmptyView from "../page/SimpleContent";
import { fetchMatrixFn } from "../../App/Singlestudy/explore/Modelization/Areas/Hydro/utils";

interface MatrixProps {
url: string;
title?: string;
rowHeaders?: string[];
customRowHeaders?: string[];
enableDateTimeColumn?: boolean;
enableTimeSeriesColumns?: boolean;
enableAggregateColumns?: boolean;
enableRowHeaders?: boolean;
enablePercentDisplay?: boolean;
enableReadOnly?: boolean;
customColumns?: string[] | readonly string[];
colWidth?: number;
fetchMatrixData?: fetchMatrixFn;
}

function Matrix({
url,
title = "global.timeSeries",
rowHeaders = [],
customRowHeaders = [],
enableDateTimeColumn = true,
enableTimeSeriesColumns = true,
enableAggregateColumns = false,
enableRowHeaders = rowHeaders.length > 0,
enableRowHeaders = customRowHeaders.length > 0,
enablePercentDisplay = false,
enableReadOnly = false,
customColumns,
colWidth,
fetchMatrixData,
}: MatrixProps) {
const { t } = useTranslation();
const { study } = useOutletContext<{ study: StudyMetadata }>();
const [openImportDialog, setOpenImportDialog] = useState(false);

const {
data,
aggregates,
error,
isLoading,
isSubmitting,
Expand All @@ -58,11 +64,13 @@ function Matrix({
} = useMatrix(
study.id,
url,
enableDateTimeColumn,
enableTimeSeriesColumns,
enableAggregateColumns,
enableRowHeaders,
customColumns,
colWidth,
fetchMatrixData,
);

////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -102,9 +110,10 @@ function Matrix({
<Divider sx={{ width: 1, mt: 1, mb: 2 }} />
<MatrixGrid
data={data}
aggregates={aggregates}
columns={columns}
rows={data.length}
rowHeaders={rowHeaders}
rowHeaders={customRowHeaders}
dateTime={dateTime}
onCellEdit={handleCellEdit}
onMultipleCellsEdit={handleMultipleCellsEdit}
Expand Down
4 changes: 2 additions & 2 deletions webapp/src/components/common/MatrixGrid/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import DataEditor, {
} from "@glideapps/glide-data-grid";
import { useGridCellContent } from "./useGridCellContent";
import { useMemo, useState } from "react";
import { EnhancedGridColumn, GridUpdate } from "./types";
import { EnhancedGridColumn, GridUpdate, MatrixAggregates } from "./types";
import { darkTheme, readOnlyDarkTheme } from "./utils";
import { useColumnMapping } from "./useColumnMapping";

Expand All @@ -18,7 +18,7 @@ export interface MatrixGridProps {
rows: number;
columns: EnhancedGridColumn[];
dateTime?: string[];
aggregates?: Record<string, number[]>;
aggregates?: MatrixAggregates;
rowHeaders?: string[];
width?: string;
height?: string;
Expand Down
9 changes: 9 additions & 0 deletions webapp/src/components/common/MatrixGrid/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,20 @@ export interface EnhancedGridColumn extends BaseGridColumn {
type: ColumnType;
editable: boolean;
}

export interface MatrixAggregates {
min: number[];
max: number[];
avg: number[];
total?: number[];
}

// Represents data coming from the API
export interface MatrixDataDTO {
data: number[][];
columns: number[];
index: number[];
aggregates?: MatrixAggregates;
}

export type Coordinates = [number, number];
Expand Down
17 changes: 15 additions & 2 deletions webapp/src/components/common/MatrixGrid/useGridCellContent.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { renderHook } from "@testing-library/react";
import { useGridCellContent } from "./useGridCellContent";
import { ColumnTypes, type EnhancedGridColumn } from "./types";
import {
ColumnTypes,
MatrixAggregates,
type EnhancedGridColumn,
} from "./types";
import { useColumnMapping } from "./useColumnMapping";

// Mocking i18next
Expand Down Expand Up @@ -41,7 +45,7 @@ function renderGridCellContent(
data: number[][],
columns: EnhancedGridColumn[],
dateTime?: string[],
aggregates?: Record<string, number[]>,
aggregates?: MatrixAggregates,
rowHeaders?: string[],
) {
const { result: mappingResult } = renderHook(() => useColumnMapping(columns));
Expand Down Expand Up @@ -116,6 +120,9 @@ describe("useGridCellContent", () => {
];

const aggregates = {
min: [5, 15, 25],
max: [15, 25, 35],
avg: [10, 20, 30],
total: [60, 75, 45],
};

Expand Down Expand Up @@ -186,6 +193,9 @@ describe("useGridCellContent", () => {
];

const aggregates = {
min: [100, 200],
max: [150, 250],
avg: [125, 225],
total: [300, 400],
};

Expand Down Expand Up @@ -272,6 +282,9 @@ describe("useGridCellContent with mixed column types", () => {
[150, 250],
];
const aggregates = {
min: [100, 200],
max: [150, 250],
avg: [125, 225],
total: [300, 400],
};

Expand Down
Loading

0 comments on commit c7afb81

Please sign in to comment.