Source code for piblin_jax.data.datasets.three_dimensional

"""
Three-dimensional dataset with three independent variables and 3D dependent data.

Used for volumetric data, 3D imaging, or data varying with three parameters.
"""

from typing import Any

import numpy as np

from piblin_jax.backend import jnp, to_numpy

from .base import Dataset


[docs] class ThreeDimensionalDataset(Dataset): """ Three-dimensional dataset with three independent variables and a 3D dependent array. This dataset type represents volumetric or 3D data: - 3D microscopy/imaging (confocal, CT, MRI) - Volumetric spectroscopy - Three-parameter experiments (e.g., temperature, pressure, time) - Computational fluid dynamics results - Molecular dynamics trajectories Parameters ---------- independent_variable_data_1 : array_like 1D array of first independent variable (e.g., x-coordinate, temperature). independent_variable_data_2 : array_like 1D array of second independent variable (e.g., y-coordinate, pressure). independent_variable_data_3 : array_like 1D array of third independent variable (e.g., z-coordinate, time). dependent_variable_data : array_like 3D array of dependent variable values with shape (len(var1), len(var2), len(var3)). conditions : dict[str, Any] | None, optional Experimental conditions. details : dict[str, Any] | None, optional Additional metadata. Attributes ---------- independent_variable_data_1 : np.ndarray First independent variable as NumPy array. independent_variable_data_2 : np.ndarray Second independent variable as NumPy array. independent_variable_data_3 : np.ndarray Third independent variable as NumPy array. dependent_variable_data : np.ndarray 3D dependent variable as NumPy array. conditions : dict[str, Any] Experimental conditions. details : dict[str, Any] Additional metadata. Raises ------ ValueError If dimension compatibility is violated. Examples -------- >>> import numpy as np >>> from piblin_jax.data.datasets import ThreeDimensionalDataset >>> # 3D confocal microscopy data >>> x = np.linspace(0, 100, 64) # microns >>> y = np.linspace(0, 100, 64) # microns >>> z = np.linspace(0, 50, 32) # microns (z-stack) >>> intensity = np.random.rand(64, 64, 32) >>> volume = ThreeDimensionalDataset( ... independent_variable_data_1=x, ... independent_variable_data_2=y, ... independent_variable_data_3=z, ... dependent_variable_data=intensity, ... conditions={"wavelength": 488, "objective": "40x"}, ... details={"voxel_size": "1.56 x 1.56 x 1.56 um"} ... ) >>> volume.dependent_variable_data.shape (64, 64, 32) >>> # Three-parameter experiment (T, P, t) >>> temperatures = np.array([25, 50, 75, 100]) >>> pressures = np.array([1, 5, 10, 15, 20]) >>> times = np.array([0, 60, 120, 180]) >>> conversion = np.random.rand(4, 5, 4) >>> experiment = ThreeDimensionalDataset( ... independent_variable_data_1=temperatures, ... independent_variable_data_2=pressures, ... independent_variable_data_3=times, ... dependent_variable_data=conversion, ... conditions={"catalyst": "Pt/Al2O3", "reactant": "H2 + CO"}, ... details={"experiment": "Fischer-Tropsch"} ... ) Notes ----- The dependent variable must have shape (len(var1), len(var2), len(var3)). Arrays are stored internally as backend arrays and converted to NumPy when accessed. """
[docs] def __init__( self, independent_variable_data_1: Any, independent_variable_data_2: Any, independent_variable_data_3: Any, dependent_variable_data: Any, conditions: dict[str, Any] | None = None, details: dict[str, Any] | None = None, ): """ Initialize three-dimensional dataset. Parameters ---------- independent_variable_data_1 : array_like 1D array of first independent variable. independent_variable_data_2 : array_like 1D array of second independent variable. independent_variable_data_3 : array_like 1D array of third independent variable. dependent_variable_data : array_like 3D array of dependent variable. conditions : dict[str, Any] | None, optional Experimental conditions. details : dict[str, Any] | None, optional Additional metadata. Raises ------ ValueError If dimension compatibility is violated. """ super().__init__(conditions=conditions, details=details) # Convert to backend arrays self._independent_variable_data_1 = jnp.asarray(independent_variable_data_1) self._independent_variable_data_2 = jnp.asarray(independent_variable_data_2) self._independent_variable_data_3 = jnp.asarray(independent_variable_data_3) self._dependent_variable_data = jnp.asarray(dependent_variable_data) # Validation: check dimension compatibility expected_shape = ( self._independent_variable_data_1.shape[0], self._independent_variable_data_2.shape[0], self._independent_variable_data_3.shape[0], ) if self._dependent_variable_data.shape != expected_shape: raise ValueError( f"Dependent variable dimension mismatch. " f"Expected shape {expected_shape} based on independent variables " f"(len={self._independent_variable_data_1.shape[0]}, " f"len={self._independent_variable_data_2.shape[0]}, " f"len={self._independent_variable_data_3.shape[0]}), " f"but got {self._dependent_variable_data.shape}" )
@property def independent_variable_data_1(self) -> np.ndarray: """ Get first independent variable as NumPy array. Returns ------- np.ndarray 1D NumPy array of first independent variable values. Examples -------- >>> dataset.independent_variable_data_1 array([0., 1.59, 3.17, ..., 98.41, 100.]) """ return to_numpy(self._independent_variable_data_1) @property def independent_variable_data_2(self) -> np.ndarray: """ Get second independent variable as NumPy array. Returns ------- np.ndarray 1D NumPy array of second independent variable values. Examples -------- >>> dataset.independent_variable_data_2 array([0., 1.59, 3.17, ..., 98.41, 100.]) """ return to_numpy(self._independent_variable_data_2) @property def independent_variable_data_3(self) -> np.ndarray: """ Get third independent variable as NumPy array. Returns ------- np.ndarray 1D NumPy array of third independent variable values. Examples -------- >>> dataset.independent_variable_data_3 array([0., 1.61, 3.23, ..., 48.39, 50.]) """ return to_numpy(self._independent_variable_data_3) @property def dependent_variable_data(self) -> np.ndarray: """ Get dependent variable data as NumPy array. Returns ------- np.ndarray 3D NumPy array of dependent variable values with shape (len(var1), len(var2), len(var3)). Examples -------- >>> dataset.dependent_variable_data.shape (64, 64, 32) >>> dataset.dependent_variable_data[0, 0, 0] # Value at first point 0.456 """ return to_numpy(self._dependent_variable_data)