Timeline
timelines.Timeline(
length=0,
unit=None,
number_type=None,
id_prefix='tl',
uid=None,
name=None,
locked=False,
meta=None,
)A positive coordinate axis with events and nested child timelines.
A Timeline represents a temporal dimension in one of three domains (Logical, Physical, Graphical) with either continuous or discrete coordinates. It stores events in an EventData and can contain nested child timelines (segments) at specified offsets.
Intended usage: This base class provides the full Timeline API but does not enforce domain or modality constraints. For typical usage, prefer one of the six concrete subclasses or the create_timeline() factory function:
ContinuousLogicalTimeline– beats, quarters, measures (Fraction)DiscreteLogicalTimeline– ticks (int)ContinuousPhysicalTimeline– seconds, ms, minutes (float)DiscretePhysicalTimeline– samples, frames (int)ContinuousGraphicalTimeline– cm, inches, points (float)DiscreteGraphicalTimeline– pixels (int)
These subclasses restrict allowed units and number types to prevent accidental cross-domain errors and provide sensible defaults.
Direct instantiation of Timeline is appropriate for internal use, generic algorithms that operate across domains, or advanced scenarios where domain constraints are intentionally relaxed.
If you have a Timeline instance and need the appropriate typed subclass, use :meth:to_typed.
Attributes
| Name | Type | Description |
|---|---|---|
| id | str |
Unique identifier for this timeline. |
| unit | TimeUnit |
The time unit for coordinates (e.g., seconds, quarters, pixels). |
| number_type | NumberType |
The numeric type for coordinates (int, float, Fraction). |
| domain | Domain |
The temporal domain (derived from unit). |
| origin | Coordinate |
The start coordinate (always 0). |
| length | Coordinate |
The end coordinate. |
| is_locked | bool |
Whether the timeline can be modified. |
| is_discrete | bool |
Whether the timeline uses discrete coordinates. |
| is_continuous | bool |
Whether the timeline uses continuous coordinates. |
Examples
>>> # Preferred: use concrete subclasses
>>> from timetoalign.timelines import ContinuousPhysicalTimeline
>>> audio = ContinuousPhysicalTimeline(length=180.0)>>> # Or use the factory to auto-select the right subclass
>>> from timetoalign.timelines import create_timeline
>>> tl = create_timeline(loader)>>> # Direct base class (internal/advanced use)
>>> from timetoalign.core import TimeUnit
>>> tl = Timeline(length=100, unit=TimeUnit.seconds)Methods
| Name | Description |
|---|---|
| diagram | Generate ASCII diagram for this timeline. |
| empty | Create an empty Timeline with length 0. |
| from_dict | Create a Timeline from a dictionary. |
| from_event_data | Create a Timeline from an existing EventData. |
| from_events | Create a Timeline from event dictionaries. |
| make_coordinate | Create a Coordinate in this timeline’s unit. |
| resolve_subclass | Return the canonical Timeline subclass for a unit/number_type pair. |
| summary | Get a summary of the timeline. |
| to_dict | Convert timeline to a dictionary for serialization. |
| to_typed | Return this timeline re-instantiated as the appropriate typed subclass. |
diagram
timelines.Timeline.diagram(
width=70,
show_children=True,
max_children=6,
unicode=True,
show=None,
)Generate ASCII diagram for this timeline.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| width | int |
Total width of the diagram in characters. | 70 |
| show_children | bool |
Whether to show child timelines (one per row). | True |
| max_children | int |
Maximum children to show before truncating. | 6 |
| unicode | bool |
Use Unicode characters (True) or ASCII fallback (False). | True |
| show | set[str] | None |
Optional set controlling which elements appear. Supported values: "children", "regions", and "cmaps" (attached conversion maps). When None, behaviour is exactly as before. |
None |
Returns
| Name | Type | Description |
|---|---|---|
| 'Diagram' | Diagram object (displays as ASCII in terminal, rich HTML in Jupyter). |
Examples
>>> print(timeline.diagram())
DiscreteGraphicalTimeline[dgt1:1] (11 events, 5 children)
0 ∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶∶ 4835 pixels
├─ system_1 0 ∶∶∶∶∶∶∶ 967
├─ system_2 967 ∶∶∶∶∶∶∶∶ 1934
└─ ...empty
timelines.Timeline.empty(unit=None, number_type=None, **kwargs)Create an empty Timeline with length 0.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| unit | TimeUnit | str | None |
The time unit. Defaults to class default. | None |
| number_type | NumberType | str | None |
The number type. Defaults to class default. | None |
| **kwargs | Any |
Additional arguments passed to init. | {} |
Returns
| Name | Type | Description |
|---|---|---|
Self |
A new empty Timeline. |
from_dict
timelines.Timeline.from_dict(data)Create a Timeline from a dictionary.
Every rational wire dict in data — length, the child offsets, and the event coordinate structs — is decoded by :func:~timetoalign.core.wire_to_rational, so an exact ratio comes back as a Fraction and an inexact one as a float. Feeding the result back through :meth:to_dict with the same flags reproduces the input dictionary.
The "events" and "external_references" keys are optional: a dictionary produced without them reconstructs a timeline with zero events and an empty reference table. External references are restored without event validation, so a payload carrying references but no events round-trips intact.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| data | dict[str, Any] |
Dictionary from to_dict(). | required |
Returns
| Name | Type | Description |
|---|---|---|
Self |
A new Timeline instance. |
from_event_data
timelines.Timeline.from_event_data(data, **kwargs)Create a Timeline from an existing EventData.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| data | EventData |
The EventData containing events. | required |
| **kwargs | Any |
Additional arguments passed to init (except unit/number_type). | {} |
Returns
| Name | Type | Description |
|---|---|---|
Self |
A new Timeline wrapping the EventData. |
from_events
timelines.Timeline.from_events(rows, unit=None, number_type=None, **kwargs)Create a Timeline from event dictionaries.
The timeline length is automatically set to accommodate all events.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| rows | list[dict[str, Any]] |
List of event dictionaries with keys: - id: unique identifier - temporal_type: “instant” or “interval” - event_type: class name (e.g., “Note”, “Beat”) - instant: coordinate (for instant events) - start, end: coordinates (for interval events) | required |
| unit | TimeUnit | str | None |
The time unit. Defaults to class default. | None |
| number_type | NumberType | str | None |
The number type. Defaults to class default. | None |
| **kwargs | Any |
Additional arguments passed to init. | {} |
Returns
| Name | Type | Description |
|---|---|---|
Self |
A new Timeline containing the events. |
make_coordinate
timelines.Timeline.make_coordinate(value)Create a Coordinate in this timeline’s unit.
Public API for creating coordinates compatible with this timeline.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| value | CoordinateValue |
The numeric value for the coordinate. | required |
Returns
| Name | Type | Description |
|---|---|---|
Coordinate |
A Coordinate with this timeline’s unit. |
resolve_subclass
timelines.Timeline.resolve_subclass(unit, number_type=None)Return the canonical Timeline subclass for a unit/number_type pair.
Inspects all subclasses and selects the one whose _allowed_units includes unit. Among candidates the selection prefers, in order:
- A class whose
_default_number_typematches number_type (when supplied). - The class with the smallest
_allowed_unitsset (most specific domain).
This ensures the six concrete types from timetoalign.timelines.types are returned rather than further-derived specialisations like BeatGrid.
Falls back to the base Timeline if no subclass claims the unit.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| unit | TimeUnit | str |
The time unit to look up. | required |
| number_type | NumberType | str | None |
Optional number type for disambiguation (e.g. NumberType.fraction selects ContinuousLogicalTimeline over DiscreteLogicalTimeline). |
None |
Returns
| Name | Type | Description |
|---|---|---|
type[Timeline] |
The canonical Timeline subclass that accepts unit. |
Examples
>>> Timeline.resolve_subclass(TimeUnit.quarters, NumberType.fraction)
<class '...ContinuousLogicalTimeline'>
>>> Timeline.resolve_subclass(TimeUnit.pixels)
<class '...DiscreteGraphicalTimeline'>summary
timelines.Timeline.summary()Get a summary of the timeline.
Returns
| Name | Type | Description |
|---|---|---|
dict[str, Any] |
Dict with timeline information. |
to_dict
timelines.Timeline.to_dict(events=False, external_references=False)Convert timeline to a dictionary for serialization.
The default output describes the timeline’s structure only: the "events" and "external_references" keys are absent unless explicitly requested, which keeps the payload small for the common case of persisting a hierarchy rather than its contents.
Coordinate-valued members — length and every child offset — are emitted as the canonical rational wire dict (:func:~timetoalign.core.rational_to_wire), so the result is JSON-serializable whatever the timeline’s number type, and Fraction coordinates survive the round trip exactly.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| events | bool |
If True, include an "events" key holding this timeline’s event rows. |
False |
| external_references | bool |
If True, include an "external_references" key holding the reference table as a list of row dicts (access_points as a nested list of {"uri": ..., "kind": ...} dicts). Included even when the table is empty. |
False |
Returns
| Name | Type | Description |
|---|---|---|
dict[str, Any] |
A JSON-serializable dictionary representation of the timeline. |
Examples
>>> "events" in tl.to_dict()
False
>>> "events" in tl.to_dict(events=True)
Trueto_typed
timelines.Timeline.to_typed()Return this timeline re-instantiated as the appropriate typed subclass.
Uses the timeline’s unit and number type to determine the correct concrete subclass (e.g., ContinuousPhysicalTimeline for seconds/float). If the timeline is already an instance of the correct subclass, returns self unchanged.
This is useful after deserialization (e.g., Timeline.from_dict()) or when working with generic Timeline instances that should carry domain-specific type information.
Note: Only the timeline object itself is re-typed. Events, external references, children, conversion maps, regions, and metadata are preserved. Children are transferred as-is (not recursively re-typed).
Returns
| Name | Type | Description |
|---|---|---|
| 'Timeline' | A Timeline instance of the appropriate typed subclass, or self |
|
| 'Timeline' | if it is already the correct type. |
Examples
>>> tl = Timeline(length=10.0, unit=TimeUnit.seconds)
>>> typed = tl.to_typed()
>>> type(typed).__name__
'ContinuousPhysicalTimeline'
>>> typed.is_continuous
True>>> # Already typed -- returns self
>>> cpt = ContinuousPhysicalTimeline(length=10.0)
>>> cpt.to_typed() is cpt
True