PatchAttrs

PatchAttrs stores non-coordinate metadata about a Patch, including measurement labels, instrument identity, data units, processing history, and format-specific fields. Coordinate values and summaries are deliberately owned elsewhere.

This note explains how DASCore interprets a few important attributes, and its internal policies around these attributes.

Metadata boundaries

Patch.coords is the authoritative source for coordinate values, dimensions, units, and sampling. Patch.summary combines PatchAttrs with CoordSummary envelopes derived from those live coordinates. Scan-created PatchSummary objects additionally carry reload provenance in source_path, source_format, source_version, and source_patch_key.

PatchAttrs rejects nested coordinate payloads and does not own dims or coordinate-summary fields such as time_min and distance_step. Keeping these values out of attrs prevents coordinate edits from leaving stale duplicated metadata. Use coordinate APIs for structural changes and Patch.summary.get_coord_summary(...) or PatchSummary.flat_dump(...) for summary/index views.

data_type

data_type is an optional label for the kind of data contained in a patch. It is useful for display defaults, plotting choices, grouping, and quick inspection, but it is not the canonical source of physical meaning, rather the data and coordinate units, as well as the patch history serve this purpose.

Note

A stale or misleading data_type is much worse than an empty one.

Situation data_type behavior
Output is still the same measured quantity, just filtered/resampled/selected/reordered Preserve existing data_type.
Output is a known derived product with a stable meaning Set a specific snake_case data_type.
Output changes physical meaning but no stable label is appropriate Clear data_type to "".

DASCore-assigned data_type values should be snake_case and listed in VALID_DATA_TYPES in dascore.constants. Correctness-critical code should prefer units, coordinates, and explicit validation.

Patch functions

patch_function can manage output data_type for patch methods.

Decorator value Behavior
data_type=None Preserve the returned patch’s data_type. This is the default for backward compatibility.
data_type="" Clear the returned patch’s data_type.
data_type="some_value" Set the returned patch’s data_type to that value.

Functions may still require a specific input label with required_attrs, for example required_attrs={"data_type": "velocity"}. This should only be used when the function’s assumptions truly depend on that label and are documented.

Format-specific subclasses

A format whose files carry fields the base class does not model declares a PatchAttrs subclass for them; there are more than a dozen under dascore/io/. Since the fields are declared, they are validated and coerced like any other, rather than surviving as untyped extras.

A serialized patch names the class it holds, so the subclass comes back:

import dascore as dc
from dascore.io.odh4.core import ODH4PatchAttrs

patch = dc.get_example_patch()
patch = patch.update(attrs=ODH4PatchAttrs(**dict(patch.attrs), gauge_length=10.0))
patch.io.write("example.h5", "dasdae")

type(dc.read("example.h5")[0].attrs)  # ODH4PatchAttrs

The name is a registered one rather than an import path, so moving a class between modules does not break files already written, and reading a file never imports a path it names. A file naming a class which is not installed — written, say, by a plugin this environment lacks — reads as the base PatchAttrs with a warning rather than failing.

Spelling an optional number

An absent number is spelled OptionalFiniteFloat, defaulting to None:

from dascore.models import OptionalFiniteFloat

class JingleV1PatchAttrs(dc.PatchAttrs):
    """Attrs for the jingle format."""

    gauge_length: OptionalFiniteFloat = None

Not float = np.nan, and not float = np.inf. JSON spells neither, so such a field writes null and then refuses to read it back, which means the class cannot reconstruct from its own model_dump_json(). A non-finite value read from a file is taken as an absent one rather than refused.