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 datalength, 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:

  1. A class whose _default_number_type matches number_type (when supplied).
  2. The class with the smallest _allowed_units set (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)
True

to_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