Metadata Schemas
A mapping layer that resolves semantic attribute names (:name, :unit, :desc, …) against metadata from heterogeneous data formats (ISTP, HAPI, Madrigal).
Components
MetadataSchema— abstract type. Concrete subtypes:DefaultSchema,ISTPSchema.rules(schema)— returns a mapping from semantic keys to lookup patterns.resolve(data, lookup)— evaluates a lookup pattern againstdata.SchemaLookup— lazy proxy returned byschema(data); resolves keys on access.SchemaDict—AbstractDictcarrying a schema.get_schema(data)— selects the appropriate schema fordata.
Lookup Patterns
resolve(data, lookup) accepts:
| Pattern | Meaning |
|---|---|
"key" / :key | direct metadata lookup |
("k1", "k2", ...) | priority lookup, first hit wins |
Via(f, sublookup) | apply f(data) then resolve sublookup |
lookup => default | use default (or default(data)) on miss |
f::Function | call f(data) |
Usage
schema = ISTPSchema()
attrs = schema(data) # SchemaLookup
attrs[:unit] # "km/s"
attrs[:depend_1_name] # resolves via Via(depend_1, ...)
get(attrs, :missing, "n/a") # default on missSchema Selection
get_schema(data) resolves in order:
- If metadata is a
SchemaDict, return itsschemafield. - Otherwise, infer from content (
haskey(meta, "CATDESC")⇒ISTPSchema). - Fall back to
DefaultSchema.
Tagging Metadata
Attach a schema at construction so it travels through type conversions:
meta = SchemaDict(ISTPSchema(), "UNITS" => "km/s", "CATDESC" => "velocity")
arr = DimArray(values; metadata = meta)
get_schema(arr) === meta.schema # trueDefining a New Schema
struct HAPISchema <: MetadataSchema end
rules(::HAPISchema) = (
name = "name",
unit = "units",
desc = "description",
)Producers in downstream packages attach it via SchemaDict(HAPISchema(), raw_dict).