Multi-dimensional data arrays with labeled dimensions for scientific computing
—
Foundation classes for multi-dimensional labeled arrays with physical units, uncertainty propagation, and comprehensive metadata handling. These classes form the core of scipp's data model and enable all higher-level functionality.
The fundamental data structure in scipp, representing a multi-dimensional array with labeled dimensions, physical units, and optional variances for uncertainty propagation.
class Variable:
"""Multi-dimensional array with labeled dimensions, units, and variances"""
def __init__(self, *, dims=None, values=None, variances=None, unit=None, dtype=None):
"""
Create a Variable
Args:
dims (Sequence[str]): Dimension labels
values (array-like): Data values
variances (array-like, optional): Variance values for uncertainty
unit (Unit or str, optional): Physical unit
dtype (DType or str, optional): Data type
"""
@property
def dims(self) -> Tuple[str, ...]:
"""Dimension labels"""
@property
def shape(self) -> Tuple[int, ...]:
"""Shape of the data"""
@property
def unit(self) -> Unit:
"""Physical unit"""
@property
def dtype(self) -> DType:
"""Data type"""
@property
def values(self) -> np.ndarray:
"""Data values as numpy array"""
@property
def variances(self) -> Optional[np.ndarray]:
"""Variance values if present"""
def copy(self, deep: bool = True) -> Variable:
"""Create a copy of the variable"""
def rename_dims(self, mapping: Dict[str, str]) -> Variable:
"""Rename dimensions"""
def to(self, /, *, unit=None, dtype=None, copy=True) -> Variable:
"""Convert unit or dtype"""A Variable with associated coordinate variables and masks, providing enhanced data organization and metadata management for scientific datasets.
class DataArray:
"""Variable with coordinates and masks for enhanced data organization"""
def __init__(self, data=None, *, coords=None, masks=None, name=None):
"""
Create a DataArray
Args:
data (Variable): The data variable
coords (Dict[str, Variable], optional): Coordinate variables
masks (Dict[str, Variable], optional): Mask variables
name (str, optional): Name of the data array
"""
@property
def data(self) -> Variable:
"""The data variable"""
@property
def coords(self) -> Coords:
"""Dictionary-like access to coordinates"""
@property
def masks(self) -> Masks:
"""Dictionary-like access to masks"""
@property
def dims(self) -> Tuple[str, ...]:
"""Dimension labels"""
@property
def shape(self) -> Tuple[int, ...]:
"""Shape of the data"""
@property
def unit(self) -> Unit:
"""Physical unit of the data"""
@property
def dtype(self) -> DType:
"""Data type"""
def copy(self, deep: bool = True) -> DataArray:
"""Create a copy of the data array"""
def rename_dims(self, mapping: Dict[str, str]) -> DataArray:
"""Rename dimensions"""A dictionary-like container for multiple related DataArrays sharing coordinate systems, enabling analysis of multi-variate scientific data.
class Dataset:
"""Dictionary-like container for multiple DataArrays"""
def __init__(self, data=None, *, coords=None, name=None):
"""
Create a Dataset
Args:
data (Dict[str, DataArray or Variable], optional): Data variables
coords (Dict[str, Variable], optional): Shared coordinates
name (str, optional): Name of the dataset
"""
@property
def coords(self) -> Coords:
"""Dictionary-like access to shared coordinates"""
@property
def dims(self) -> Tuple[str, ...]:
"""All dimension labels in the dataset"""
def copy(self, deep: bool = True) -> Dataset:
"""Create a copy of the dataset"""
def rename_dims(self, mapping: Dict[str, str]) -> Dataset:
"""Rename dimensions"""
def __getitem__(self, key: str) -> DataArray:
"""Get data array by name"""
def __setitem__(self, key: str, value: Union[DataArray, Variable]):
"""Set data array by name"""
def __delitem__(self, key: str):
"""Delete data array by name"""
def keys(self) -> KeysView[str]:
"""Data array names"""
def values(self) -> ValuesView[DataArray]:
"""Data arrays"""
def items(self) -> ItemsView[str, DataArray]:
"""Name, data array pairs"""A hierarchical container for complex, nested data structures, enabling organization of related datasets and metadata in tree-like structures.
class DataGroup:
"""Hierarchical container for nested data structures"""
def __init__(self, data=None):
"""
Create a DataGroup
Args:
data (Dict[str, Any], optional): Initial data
"""
def __getitem__(self, key: str):
"""Get item by name"""
def __setitem__(self, key: str, value):
"""Set item by name"""
def __delitem__(self, key: str):
"""Delete item by name"""
def keys(self) -> KeysView[str]:
"""Item names"""
def values(self) -> ValuesView:
"""Items"""
def items(self) -> ItemsView:
"""Name, item pairs"""
def copy(self, deep: bool = True) -> DataGroup:
"""Create a copy of the data group"""Physical unit representation with arithmetic operations and automatic propagation through mathematical operations.
class Unit:
"""Physical unit with arithmetic operations"""
def __init__(self, unit_string: str):
"""
Create a Unit from string representation
Args:
unit_string (str): Unit string (e.g., 'm', 'kg*m/s^2', 'mm')
"""
def __mul__(self, other: Unit) -> Unit:
"""Multiply units"""
def __truediv__(self, other: Unit) -> Unit:
"""Divide units"""
def __pow__(self, exponent: Union[int, float]) -> Unit:
"""Raise unit to power"""
def __eq__(self, other: Unit) -> bool:
"""Check unit equality"""
def __str__(self) -> str:
"""String representation"""
def __repr__(self) -> str:
"""String representation"""Data type enumeration for scipp arrays, providing type safety and consistency across operations.
class DType:
"""Data type enumeration for scipp arrays"""
# Numeric types
int32: DType
int64: DType
float32: DType
float64: DType
bool: DType
# String type
string: DType
# Time types
datetime64: DType
# Vector types
vector3: DType
# Transformation types
linear_transform3: DType
affine_transform3: DType
rotation3: DType
translation3: DType
def __eq__(self, other: DType) -> bool:
"""Check dtype equality"""
def __str__(self) -> str:
"""String representation"""Dictionary-like access to coordinate variables with automatic dimension consistency checking.
class Coords:
"""Dictionary-like access to coordinates"""
def __getitem__(self, key: str) -> Variable:
"""Get coordinate by name"""
def __setitem__(self, key: str, value: Variable):
"""Set coordinate by name"""
def __delitem__(self, key: str):
"""Delete coordinate by name"""
def keys(self) -> KeysView[str]:
"""Coordinate names"""
def values(self) -> ValuesView[Variable]:
"""Coordinate variables"""
def items(self) -> ItemsView[str, Variable]:
"""Name, variable pairs"""Dictionary-like access to mask variables for data filtering and selection.
class Masks:
"""Dictionary-like access to masks"""
def __getitem__(self, key: str) -> Variable:
"""Get mask by name"""
def __setitem__(self, key: str, value: Variable):
"""Set mask by name"""
def __delitem__(self, key: str):
"""Delete mask by name"""
def keys(self) -> KeysView[str]:
"""Mask names"""
def values(self) -> ValuesView[Variable]:
"""Mask variables"""
def items(self) -> ItemsView[str, Variable]:
"""Name, variable pairs"""Access to binned/event data content with operations for bin manipulation and event data handling.
class Bins:
"""Access to binned/event data content"""
@property
def constituents(self) -> Dict[str, Variable]:
"""Access to bin contents"""
@property
def coords(self) -> Coords:
"""Coordinates of bin contents"""
def copy(self, deep: bool = True) -> Bins:
"""Create copy of binned data"""import scipp as sc
# Create a simple variable
temp = sc.array(dims=['x'], values=[273.15, 298.15, 373.15], unit='K')
# Create with uncertainties
measurement = sc.array(
dims=['time'],
values=[1.0, 2.1, 3.0],
variances=[0.01, 0.04, 0.09],
unit='m/s'
)
# Create multi-dimensional data
image = sc.zeros(dims=['y', 'x'], shape=[100, 200], unit='counts')import numpy as np
# Create coordinate arrays
x = sc.linspace(dim='x', start=0, stop=10, num=11, unit='mm')
y = sc.linspace(dim='y', start=0, stop=5, num=6, unit='mm')
# Create 2D data
data = sc.array(dims=['y', 'x'], values=np.random.random((6, 11)), unit='counts')
# Combine into DataArray
da = sc.DataArray(data=data, coords={'x': x, 'y': y})
# Add masks
mask = sc.array(dims=['y', 'x'], values=np.random.random((6, 11)) > 0.9)
da.masks['random_mask'] = mask# Create multiple related measurements
temperature = sc.DataArray(
data=sc.array(dims=['time'], values=[295, 300, 305], unit='K'),
coords={'time': sc.arange(dim='time', start=0, stop=3, unit='s')}
)
pressure = sc.DataArray(
data=sc.array(dims=['time'], values=[1.0, 1.1, 1.2], unit='bar'),
coords={'time': sc.arange(dim='time', start=0, stop=3, unit='s')}
)
# Combine into dataset
experiment = sc.Dataset({'temperature': temperature, 'pressure': pressure})
# Access data
print(experiment['temperature'])
print(experiment.coords['time'])Install with Tessl CLI
npx tessl i tessl/pypi-scipp