Defining ArraySchema and AnnotatedArray’s

ArraySchema are dictionary objects that describe the requirements of an array structure. AnnotatedArray are xarray.DataArray’s that are expected to conform to a given ArraySchema - subclasses of xarray.DataArray.

import rmellipse as rme

Defining AnnotatedArrays

There are 2 required fields in a schema. The first is a shape and the second is a dimension specification.

class Array2x2(rme.AnnotatedArray):
    schema = rme.ArraySchema(
        shape=(2, 2),
        dims=('row', 'column'),
    )

Dimension and shape specifiers can also be alphabetical letters (lower or upper case) that indicate arbitrary dimensionality. If two specifiers are the same letter, that indicates they are the same shape. For example, a stack of square matrices might be defined as

class ArrayMxNxN(rme.AnnotatedArray):
    schema = rme.ArraySchema(
        shape=('M', 'N', 'N'),
        dims=('page', 'row', 'column'),
    )

It’s possible to define arbitary dimensionality or shape with ellipses. For example, the following schema is an array of arbitary leading dimensions ending in an NxN shape of rows and columns. If the shape is arbitary, then so are the dimension names in the same position. There can be only a single arbitrary specifier. So (…,’N’) is okay but (…,’N’,…) is not.

class ArrayLeadingNxN(rme.AnnotatedArray):
    schema = rme.ArraySchema(
        shape=(..., 'N', 'N'),
        dims=(..., 'row', 'column'),
    )

Data Types

By default, an ArraySchema has no dtype specifier (None) but one can be provided to identity what kind of data is expected in the values of the DataArray. An array is considered valid to a schema it it can be casted into that schema’s dtype using the numpy.can_cast() function.

class Array2x2Float(rme.AnnotatedArray):
    schema = rme.ArraySchema(shape=(2, 2), dims=('row', 'column'), dtype=float)

Coordinates

You can specify the expected coordinates of an AnnotatedArray by including a coords field with a CoordinateSchema.

class TimeDomainArray(rme.AnnotatedArray):
    schema = rme.ArraySchema(
        shape=('N',), dims=('time',), coords={'time': rme.CoordinateSchema(dtype=float)}
    )

If an array has a fixed dimension shape and coordinates, you can define the coordinate values by supplying values to the coordinate field.

class TimeDomainArray2x2(rme.AnnotatedArray):
    schema = rme.ArraySchema(
        shape=('N', 2, 2),
        dims=('time', 'row', 'col'),
        coords={
            'time': rme.CoordinateSchema(dtype=float),
            'row': rme.CoordinateSchema(dtype=int, values=[0, 1]),
            'col': rme.CoordinateSchema(dtype=int, values=[0, 1]),
        },
    )

Units

By default the units field is None (which means no specified units, not unitless). If your array contains values of a physical unit, it can be supplied as a string in the units field. This can be provided to both the array values themselves, and to individual coordinates.

class TimeDomainVoltage(rme.AnnotatedArray):
    schema = rme.ArraySchema(
        shape=('N',),
        dims=('time',),
        units='V',
        coords={'time': rme.CoordinateSchema(dtype=float, units='s')},
    )

Metadata

Metadata on xarray.DataArrays (and consequently AnnotatedArrays) are stored in the attrs attribute as a dictionary. If your data model is expecting specific structures of metadata, those can be defined using Pydantic datamodels. For example, you may be making a system that records DC measurments, and want to require that operator, temperature, and source current metadata fields are always present. It’s strongly recommended that extra metadata fields be allowed as well.

from pydantic import BaseModel, ConfigDict


class DCMeasurementMetadata(BaseModel):
    # Enable extra fields
    model_config = ConfigDict(extra='allow')
    operator: str
    temperature_celcius: float
    source_current_amps: float


class TimeDomainVoltageWithMetadata(rme.AnnotatedArray):
    schema = rme.ArraySchema(
        shape=('N',),
        dims=('time',),
        units='V',
        coords={'time': rme.CoordinateSchema(dtype=float, units='s')},
        attrs=DCMeasurementMetadata,
    )

Gallery generated by Sphinx-Gallery