Types¶
TimeF value types live in timenet.types. Wire-facing types are Pydantic models; other runtime
objects use typed dataclasses and enums. The full
object model is split across these focused pages:
- TimeFDataset covers the complete in-memory hierarchy.
- Annotations covers reusable content and occurrences.
- Tasks covers modelling problems and targets.
This page describes the shared value types used by those objects.
Version¶
Version is an ordered semantic version with non-negative major, minor, and patch parts.
from timenet.types import Version
version = Version.parse("1.2.3")
assert str(version) == "1.2.3"
assert version > Version(1, 2, 0)
IDs¶
Records, Signals, and Tasks have a read-only, positive int64 id (EntityId). When you add the
object to a dataset, the dataset sets the ID. When the reader reads the object back, the reader
sets it. You cannot set an ID. The dataset ID is the exception and stays an org/name string.
If an object is not in a dataset, reading its id raises TimeFValidationError.
IDs carry no meaning. Store upstream identifiers in metadata or in an annotation. To refer to
another object, use the object itself. For example, a span holds Signal objects.
Only a few APIs use Record IDs:
TimeFReader.record_ids(), and therecord_idsargument ofiter_records(),task_table(), andtarget_table().remove_records()andedit_version()intimenet.dataset.edit.
IDs are unique per kind within one dataset, and they stay the same across edits. Two datasets can use the same ID.
Sources, axes, and annotations have no ID. The writer stores equal annotation contents once. Two
annotation contents are equal if the name, the value and its type, the unit, the description, and
the metadata are equal. 0.0 and -0.0 are not equal. All NaN values are equal. True, 1, and
1.0 are not equal.
Units¶
TimeNet uses one pint registry named ureg. Use this registry for
units stored in TimeF objects. A second registry creates units that do not compare reliably with
TimeNet units.
TimeNet serializes unit names and restores them through ureg. It does not replace pint's global
application registry during import.
TimeSeriesSpec.unit_value is required. Set it to None when the source does not establish a
unit. Use ureg.dimensionless only when the values have a known dimensionless meaning.
Call use_as_application_registry() only when your application pickles bare pint units or
quantities. This call changes process-wide pint state.
TimeSeriesSpec¶
TimeSeriesSpec describes one measurement modality. A Signal stores its own identity, display
name, axis, and values. Several Signals can share one specification.
from timenet.types import TimeSeriesSpec, ureg
vibration = TimeSeriesSpec(
spec_type="vibration",
name="Vibration",
unit_value=ureg.standard_gravity,
dtype="float32",
)
| Field | Description |
|---|---|
spec_type |
Dataset-unique modality tag. |
name |
Human-readable modality name. |
unit_value |
Physical unit of each value, or None when unknown. |
dtype |
NumPy scalar dtype, "str", or "enum". |
categories |
Allowed labels for an enum specification. |
value_shape |
Shape of one timestep, without the time dimension. |
dimension_names |
Optional names for every dimension in value_shape. |
nullable |
Whether a complete timestep can be missing. |
modality |
Input kind used for Task inference. Defaults to TIME_SERIES; also accepts IMAGE, AUDIO, or TEXT. |
The full logical shape is (n_steps, *value_shape). Parquet stores scalar values. Use the Zarr
backend for multidimensional values.
Missing values¶
Pass None for a missing timestep when nullable=True. Arrow stores missingness in a validity
bitmap. This keeps a missing value distinct from a valid floating-point NaN.
Signal.to_arrow() preserves nulls. Signal.to_numpy() rejects an array that contains nulls.
The PyTorch adapter also rejects actual nulls, even when nullable=True. Consumers must handle
missing data before tensor conversion.
Nullability applies to the complete timestep. TimeF rejects a partially missing multidimensional value.
Spans¶
A span identifies one region for an annotation or task. Its type defines both its shape and its coordinate frame.
| Type | Meaning |
|---|---|
TimePoint |
One microsecond position on a recording timeline. |
TimeInterval |
One half-open time range, [start_us, end_us). |
StepPoint |
One ordinal position in a Signal without a clock. |
StepInterval |
One half-open ordinal range, [start, stop). |
Task time spans can select Signals through time_series, a tuple of Signal objects. Each task span
must identify exactly one input Record. Annotation spans cannot select Signals. The owner of an
annotation sets its scope.
Step spans always name exactly one Signal through time_series. The writer stores the IDs of these
Signals. The reader replaces these IDs with the Signals that it reads back.
import numpy as np
from timenet.dataset import Signal
from timenet.dataset.axis import OrdinalAxis, RegularAxis
from timenet.types import StepInterval, TimeInterval, TimePoint
accelerometer = Signal(
name="Accelerometer",
spec=vibration,
time_axis=RegularAxis.from_rate_hz(100),
data=np.zeros(1000, dtype=np.float32),
)
text_series = Signal(
name="Transcript",
spec=TimeSeriesSpec(
spec_type="token", name="Token", unit_value=None, dtype="str"
),
time_axis=OrdinalAxis(),
data=["token"] * 200,
)
event = TimePoint.seconds(1.2)
window = TimeInterval.seconds(
5.0,
8.0,
time_series=(accelerometer,),
)
tokens = StepInterval(time_series=text_series, start=132, stop=144)
Use record.time_point() or record.time_interval() to convert wall-clock values through a
Record's known origin. Relative spans also work when its absolute timestamp is unknown.
DatasetMetadata¶
DatasetMetadata contains the descriptive identity authored in dataset.yaml.
| Field | Required | Description |
|---|---|---|
dataset_id |
yes | One org/name identifier. |
dataset_version |
yes | Semantic version of the source dataset. |
name |
yes | Display name. |
description |
yes | Short dataset description. |
license |
yes | Known SPDX-style license value, OTHER, or NONE. |
domains |
no | Searchable application domains. See Domains. |
tags |
no | Searchable free-form labels. |
source_url |
no | Canonical source location. |
license_url |
conditional | License text when license is OTHER. |
citation |
no | Citation requested by the source. |
access |
no | OPEN, CREDENTIALED, or RESTRICTED. |
access_url |
conditional | Access page for non-open data. |
DatasetMetadata.from_yaml() validates a card against the packaged JSON Schema.
A card keeps the access and the access_url that its author declared. An import into a child
dataset does not change them. The effective access level of a dataset is the strictest level of its
own card and of the cards in its lineage. effective_access(metadata, lineage) in
timenet.types.access returns this level. access_requirements(metadata, lineage) lists each of
these cards whose access is not OPEN, with its access_url.
DatasetSchema¶
DatasetSchema is the type summary that TimeNet derives from a populated dataset. Do not author it
by hand. The schema contains:
- one
TimeSeriesSpecfor each measurement modality; - one
AnnotationDescriptorfor each annotation key and shape; - the concrete Task classes present in the dataset.
The writer stores this schema in manifest.json. The reader uses it to reconstruct the same public
types.
Enums¶
The main string enums are:
Domainfor application areas such as health, sleep, finance, and general data;Licensefor supported SPDX-style identifiers;Accessfor open, credentialed, and restricted data;TaskTypefor the built-in task classes;LocalizationModefor sparse or exhaustive temporal localization.
They are StrEnum values and compare equal to their stored string values.
Domains¶
A card declares every domain that a substantial part of its records belongs to.
Finer labels, such as a sensor or a benchmark name, belong in tags.
The Covers column presents typical examples, and does not claim to be an exhaustive list.
| Value | Covers |
|---|---|
health |
Human physiology and clinical care. Declare it alongside cardiology, respiratory, and sleep. |
cardiology |
The heart: ECG, heart rate, heart sounds. |
respiratory |
Breathing and the lungs: respiration, airflow, oxygen saturation, cough. |
sleep |
Sleep studies: polysomnography and sleep staging. |
activity |
Labeled human activities and daily behavior. Add motion when the signals are the movement. |
motion |
Movement of a body or object: IMU channels and motion capture. |
economics |
Macroeconomic indicators, prices, sales, and demand. |
finance |
Asset prices, returns, trading volumes, and exchange rates. |
environment |
Weather, climate, air quality, and hydrology. |
energy |
Electricity load, generation, power grids, and transformers. |
transport |
Transport networks: road traffic, congestion, ridership. Not a vehicle's own machinery. |
observability |
Software and IT infrastructure: service metrics and cloud monitoring. |
audio |
Recorded sound as content. |
industrial |
Machines and industrial processes: condition monitoring, faults, remaining useful life. |
general |
Synthetic, demo, or generic data without a stated field. |
Errors and warnings¶
TimeNet raises its own exceptions from timenet.errors.
| Exception | Meaning |
|---|---|
TimeNetError |
Base class for TimeNet failures. |
TimeNetRegistryError |
A registry cannot complete an operation. |
TimeNetDatasetNotFoundError |
A dataset ID or version does not exist. |
TimeFValidationError |
Input violates a TimeF invariant. |
TimeFNullValuesError |
Values contain nulls that NumPy cannot hold. A TimeFValidationError. |
TimeFNotFoundError |
An ID, parent alias, or parent release names nothing in the dataset, or the stored object has another kind. A TimeFValidationError and a LookupError. |
TimeFFormatError |
A stored TimeF artifact is corrupt or unsupported. |
TimeNetFileError |
A file of a release is missing, or does not match its manifest record. A TimeFFormatError. |
TimeFReaderError |
A reader could not complete a read, e.g. its connection was closed while the read ran. |
TimeNetInvalidCardError |
dataset.yaml cannot be read or is not a mapping. |
TimeNetConnectorError |
A connector found that an assumption about its source data, a download, or a parent does not hold. TimeNetDownloadError is a TimeNetConnectorError. |
Pydantic ValidationError reports field and schema errors in a dataset card. The error includes the
native field location and details.
Manifest parsing uses the same error for invalid JSON and invalid fields.
TimeFValidationError also subclasses ValueError. Existing input-validation handlers can catch it
without losing the TimeNet-specific error type.
SpanOutsideWindowWarning reports a span outside a Signal window when the caller has chosen warning
behavior. It derives from TimeNetWarning and UserWarning.
See the API reference for timenet.types for all symbols.