Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d03ab1b
Add new request model. Rename response models.
jwasikpsnc Apr 17, 2026
5a1db85
Data smoothing (WIP)
jwasikpsnc Apr 24, 2026
a52b06a
Update docs
jwasikpsnc Apr 28, 2026
b1c3327
Add interpolation without data creation. Update docstrings.
jwasikpsnc May 4, 2026
279c759
Fix interpolation bugs. Update tests.
jwasikpsnc May 5, 2026
d1a410d
Update interpolation docs.
jwasikpsnc May 5, 2026
66018e2
Merge branch 'iterorganization:develop' into feature/data-smoothing-d…
jwasikpsnc May 8, 2026
7807d59
Merge data-smoothing-denoising into data-smoothing
jwasikpsnc May 11, 2026
8dfe769
Merge data-smoothing-denoising into data-smoothing
jwasikpsnc May 12, 2026
c2352ef
Merge branch 'develop' into feature/interpolation-without-new-values
olivhoenen May 12, 2026
d0959d0
Add models for data manipulation
jwasikpsnc May 12, 2026
9f0a1b8
Add missing interface def. Delete old, unused argument.
jwasikpsnc May 15, 2026
ad14563
Commit of shame - run linter
jwasikpsnc May 15, 2026
782d1d8
Delete missed argument
jwasikpsnc May 15, 2026
e4ddaf9
Merge branch 'feature/interpolation-without-new-values' into feature/…
jwasikpsnc May 15, 2026
ed502cb
Pass query object down to data source layer
jwasikpsnc May 18, 2026
4c30996
Add data smoothing
jwasikpsnc May 19, 2026
4cab041
Merge remote-tracking branch 'refs/remotes/origin/develop' into featu…
jwasikpsnc May 19, 2026
2e8bb56
Merge branch 'iterorganization:develop' into feature/data-smoothing
jwasikpsnc May 20, 2026
53958af
Update data manipulation docs
jwasikpsnc May 20, 2026
b9702f6
Delete unused models
jwasikpsnc May 20, 2026
7ac0dad
Add more underlines in adding_new_data_manipulation_method.rst
jwasikpsnc May 25, 2026
2368381
char encoding issue
olivhoenen May 29, 2026
03148dd
Set smoothing_method to None when interpolating
jwasikpsnc Jun 1, 2026
cc73e6a
Allow only time-based smoothing
jwasikpsnc Jun 2, 2026
59008f7
Add simple data operations
jwasikpsnc Jun 2, 2026
c86a6f2
Add subtraction. Check parameters before operation.
jwasikpsnc Jun 15, 2026
e67f0f1
Add operation priorities
jwasikpsnc Jun 15, 2026
fc9c0b3
Fix broken test
jwasikpsnc Jun 15, 2026
1c7e665
Apply linter
jwasikpsnc Jun 15, 2026
a105b66
Basic operations order (WIP)
jwasikpsnc Jun 16, 2026
f5da1cf
Fix wrong description
jwasikpsnc Jun 17, 2026
6639d45
Update docstring and test.
jwasikpsnc Jun 17, 2026
d79fac5
Update docs. Mini-fixes.
jwasikpsnc Jun 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
223 changes: 223 additions & 0 deletions backend/ibex/core/data_manipulation_methods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
from typing import Optional
from enum import Enum
from pydantic import BaseModel


class InterpolationMethod(str, Enum):
EXACT_VALUE = "exact_value"
LINEAR = "linear"
NEAREST = "nearest"


class SmoothingMethod(str, Enum):
GAUSSIAN_FILTER = "gaussian_filter"
SAVITZKY_GOLAY_FILTER = "savitzky-golay_filter"


class AdditionalParameter(BaseModel):
"""
Parameters for specific data manipulation methods. E.g. sigma -> for Gaussian smoothing
"""

name: str
human_readable_name: str
description: str
possible_values: Optional[list[str]] = None


class PossibleValue(BaseModel):
"""
Possible value for data manipulation method parameter. E.g. Gaussian smoothing
"""

value: str
description: str
additional_parameters: Optional[list[AdditionalParameter]] = None


class DataManipulationParameter(BaseModel):
"""
E.g. interpolate_over, type of filtering, binary operation
"""

human_readable_name: str
name: str
description: str
type: str
default: Optional[str] = None
possible_values: Optional[list[PossibleValue]] = None
group_label: Optional[str] = None
fields: Optional[list["DataManipulationParameter"]] = None


class DataManipulationOperation(BaseModel):
"""
Type of data manipulation method. E.g. data-smoothing, data-interpolation, binary-operation
"""

name: str
description: str
method_parameters: list[DataManipulationParameter]


class DataManipulationMethodsResponse(BaseModel):
data_manipulation_methods: list[DataManipulationOperation]


DataManipulationParameter.model_rebuild()
available_methods = DataManipulationMethodsResponse(data_manipulation_methods=[])

# ====================== DATA INTERPOLATION ======================

data_interpolation_description = DataManipulationOperation(
name="Data interpolation",
description="Operation performed in order to represent dataset over different set of coordinates",
method_parameters=[],
)

# ====================== DATA INTERPOLATION PARAMETERS ======================

data_interpolation_interpolate_over_parameter = DataManipulationParameter(
human_readable_name="Interpolate over",
name="interpolate_over",
description="List of URIs to gather coordinates from, for interpolation",
type="list[string]",
)

data_interpolation_method_parameter = DataManipulationParameter(
human_readable_name="Interpolation method",
name="interpolation_method",
description="Method used during data interpolation",
type="string",
default=InterpolationMethod.EXACT_VALUE,
possible_values=[
PossibleValue(
value=InterpolationMethod.EXACT_VALUE,
description="values are present only on data points where they were originally. Rest of the data grid is filled with NaNs",
),
PossibleValue(
value=InterpolationMethod.LINEAR,
description="see scipy.interpolate.RegularGridInterpolator documentation",
),
PossibleValue(
value=InterpolationMethod.NEAREST,
description="see scipy.interpolate.RegularGridInterpolator documentation",
),
],
)

data_interpolation_description.method_parameters.append(data_interpolation_interpolate_over_parameter)
data_interpolation_description.method_parameters.append(data_interpolation_method_parameter)
available_methods.data_manipulation_methods.append(data_interpolation_description)

# ====================== DATA SMOOTHING ======================

data_smoothing_description = DataManipulationOperation(
name="Data smoothing/denoising",
description="Operation performed in order to eliminate noise from data",
method_parameters=[],
)

# ====================== DATA SMOOTHING PARAMETERS ======================

data_smoothing_method_parameter = DataManipulationParameter(
human_readable_name="Smoothing method",
name="smoothing_method",
description="Method to be used in data smoothing process",
type="string",
possible_values=[
PossibleValue(
value=SmoothingMethod.GAUSSIAN_FILTER,
description="see scipy.ndimage.gaussian_filter documentation",
additional_parameters=[
AdditionalParameter(
name="gaussian_smoothing_sigma",
human_readable_name="Sigma",
description="Standard deviation for Gaussian kernel.",
)
],
),
PossibleValue(
value=SmoothingMethod.SAVITZKY_GOLAY_FILTER,
description="see scipy.signal.savgol_filter documentation",
additional_parameters=[
AdditionalParameter(
name="savgol_smoothing_window_length",
human_readable_name="Window length",
description="The length of the filter window (i.e., the number of coefficients). If mode is ‘interp’, window_length must be less than or equal to the size of x.",
),
AdditionalParameter(
name="savgol_smoothing_polyorder",
human_readable_name="Polyorder",
description="The order of the polynomial used to fit the samples. polyorder must be less than window_length.",
),
AdditionalParameter(
name="savgol_smoothing_deriv",
human_readable_name="Deriv",
description="The order of the derivative to compute. This must be a nonnegative integer. The default is 0, which means to filter the data without differentiating.",
),
AdditionalParameter(
name="savgol_smoothing_delta",
human_readable_name="Window delta",
description="The spacing of the samples to which the filter will be applied. This is only used if deriv > 0. Default is 1.0.",
),
AdditionalParameter(
name="savgol_smoothing_mode",
human_readable_name="Mode",
description="This determines the type of extension to use for the padded signal to which the filter is applied.",
possible_values=["mirror", "constant", "nearest", "wrap", "interp"],
),
AdditionalParameter(
name="savgol_smoothing_cval",
human_readable_name="C-Val",
description="Value to fill past the edges of the input if mode is ‘constant’. Default is 0.0.",
),
],
),
],
)

data_smoothing_description.method_parameters.append(data_smoothing_method_parameter)
available_methods.data_manipulation_methods.append(data_smoothing_description)

# ====================== SIMPLE DATA OPERATIONS ======================

simple_data_operations_description = DataManipulationOperation(
name="Simple Data Operations",
description="Ordered list of scalar operations applied to the dataset. "
"Execution order is determined by the order of parameters in the request.",
method_parameters=[],
)

data_operations_parameter = DataManipulationParameter(
human_readable_name="Operations",
name="operations",
description="Ordered list of scalar operations applied to every data point.",
type="list[object]",
group_label="Operation",
fields=[
DataManipulationParameter(
human_readable_name="Type",
name="operation_type",
description="Type of operation",
type="string",
possible_values=[
PossibleValue(value="add", description="Addition"),
PossibleValue(value="sub", description="Subtraction"),
PossibleValue(value="mul", description="Multiplication"),
PossibleValue(value="div", description="Division"),
PossibleValue(value="pow", description="Exponentiation"),
PossibleValue(value="root", description="Nth root"),
],
),
DataManipulationParameter(
human_readable_name="Value",
name="operation_value",
description="Scalar value for the operation",
type="number",
),
],
)

simple_data_operations_description.method_parameters.append(data_operations_parameter)
available_methods.data_manipulation_methods.append(simple_data_operations_description)
23 changes: 4 additions & 19 deletions backend/ibex/core/ibex_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import time
from pathlib import Path
from functools import wraps # for measure_execution_time()
from typing import Any, Callable, Optional, Sequence, List
from typing import Any, Callable, Optional, Sequence

from ibex.data_source.imas_python_source import IMASPythonSource
from ibex.data_source.exception import CannotGenerateUriException
from ibex.core.utils import IMAS_URI
from ibex.endpoints.schemas.request_data_schemas import PlotDataRequestModel


# helper decorator used during development
Expand Down Expand Up @@ -114,21 +115,5 @@ def get_multiple_node_data(uri: str) -> dict:
)


def get_plot_data(
uri: str,
interpolate_over: List[str] | None,
interpolation_method: str | None,
downsampling_method: str | None,
downsampled_size: int,
) -> dict:
uri_obj = IMAS_URI(uri)
return data_source.get_plot_data(
uri=uri_obj.uri_entry_identifiers,
ids=uri_obj.ids_name,
node_path=uri_obj.node_path,
occurrence=uri_obj.occurrence,
interpolate_over=interpolate_over,
interpolation_method=interpolation_method,
downsampling_method=downsampling_method,
downsampled_size=downsampled_size,
)
def get_plot_data(plot_data_query: PlotDataRequestModel) -> dict:
return data_source.get_plot_data(plot_data_query)
25 changes: 5 additions & 20 deletions backend/ibex/data_source/data_source_interface.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Interface for all data sources"""

from abc import ABC, abstractmethod
from typing import Sequence, Optional, List
from typing import Sequence, Optional
from ibex.endpoints.schemas.request_data_schemas import PlotDataRequestModel


class DataSourceInterface(ABC):
Expand Down Expand Up @@ -123,28 +124,12 @@ def list_db_entries(
"""
...

def get_plot_data(
self,
uri: str,
ids: str,
node_path: str,
occurrence: int = 0,
interpolate_over: List[str] | None = None,
interpolation_method: str | None = None,
downsampling_method: str | None = None,
downsampled_size: int = 1000,
) -> dict:
def get_plot_data(self, plot_data_query: PlotDataRequestModel) -> dict:
"""
Returns all data used to plot selected quantity. Result contains data values, metadata and coordinates.

:param uri: imas URI
:param ids: name of ids e.g. core_profiles
:param node_path: path to ids node e.g. ids_properties/version_put
:param occurrence: ids occurrence number
:param interpolate_over: list of uris used in interpolation
:param interpolation_method: method to be used in data interpolation; one from scipy.interpolate.RegularGridInterpolator or 'exact_value'
:param downsampling_method: one of the downsampling metods returend by :func:`~ibex.endpoints.info.downsampling_methods` endpoint, or None
:param downsampled_size: target size of downsampled data
:param plot_data_query: See :class:`ibex.endpoints.schemas.request_data_schemas.PlotDataRequestModel`
:type plot_data_query: :class:`ibex.endpoints.schemas.request_data_schemas.PlotDataRequestModel`
:return: Dictionary containing data values, metadata and coordinates.
"""
...
Loading