Timeline

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: id: Unique identifier for this timeline. unit: The time unit for coordinates (e.g., seconds, quarters, pixels). number_type: The numeric type for coordinates (int, float, Fraction). domain: The temporal domain (derived from unit). origin: The start coordinate (always 0). length: The end coordinate. is_locked: Whether the timeline can be modified. is_discrete: Whether the timeline uses discrete coordinates. is_continuous: 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)

Attributes

Name Description
class_name The class name of this timeline.
domain The temporal domain (derived from unit).
end Alias for length.
events The underlying EventData (read-only access).
id Unique identifier for this timeline.
is_continuous Whether this timeline uses continuous (real-valued) coordinates.
is_discrete Whether this timeline uses discrete (integer) coordinates.
is_locked Whether this timeline is locked (cannot expand).
length The end coordinate (length of the timeline).
meta Metadata dictionary.
n_children Number of direct child timelines.
n_conversion_maps Number of attached conversion maps.
n_events Number of events (excluding segment events).
n_flow_maps Number of attached FlowMaps.
n_regions Number of regions on this timeline.
name Human-readable name for display.
number_type The number type for coordinates.
origin The start coordinate (always 0).
start Alias for origin.
unit The time unit for coordinates.

Methods

Name Description
add_break Add a Break (contiguity void) at the specified coordinate.
add_child Embed a child timeline at the specified offset.
add_conversion_map Add a ConversionMap to this timeline.
add_events Add events to the timeline.
add_flow_map Add a FlowMap to this timeline.
add_jump Add a Jump (non-linear contiguity) between coordinates.
add_match Add an alignment Match to this timeline.
add_region Add or create a named Region on this timeline.
attach_flow_map Deprecated alias for add_flow_map.
convert_to Convert coordinates to another unit using attached C-Maps.
create_child Create a new child timeline and embed it at the specified offset.
create_child_from_region Create a child timeline from a named region (partitioning).
create_children_from_regions Create children from multiple regions (batch partitioning).
create_region Create a new named Region and attach it to this timeline.
create_regions_by_grouping Create regions by grouping adjacent events on a column value.
create_regions_by_splitting Create contiguous regions by splitting at events matching a predicate.
create_regions_from_boundaries Create contiguous regions from boundary coordinates.
create_segment_line Create a SegmentLine by segmenting at boundary coordinates.
create_segment_line_by_grouping Create a SegmentLine by grouping adjacent events on a column value.
create_segment_line_by_splitting Create a SegmentLine by splitting at events matching a predicate.
create_segment_line_from_regions Create a SegmentLine from contiguous regions.
derive Create a derivative timeline in a different unit via C-Map conversion.
diagram Generate ASCII diagram for this timeline.
empty Create an empty Timeline with length 0.
export_to_csv Export timeline data to a CSV file.
fold Convert an unfolded coordinate to a folded coordinate.
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.
get_boundary_table Get timestamps for timeline boundaries only.
get_child Retrieve a child timeline by ID.
get_child_offset Get the offset of a child timeline.
get_children_at Return all children whose extent contains the given coordinate.
get_conversion_map Get a conversion map by target unit or by name/id.
get_event Look up a single event by its id field.
get_events Filter and retrieve events.
get_events_at Get all events active at a specific coordinate.
get_flow_map Get an attached FlowMap by id.
get_interval_stamp Get a TimeIntervalStamp for a coordinate range.
get_region Get a Region by name.
get_regions_at Return all regions containing the given coordinate.
get_slice Extract a portion of this timeline as a new, independent timeline.
get_timestamp Get a TimeStamp at a specific coordinate.
get_timestamp_at Alias for get_timestamp() for API consistency with TimelineGroup.
get_timestamp_of Get the timestamp for a specific event by its ID.
get_timestamp_table Generate a timestamp table as a PyArrow Table.
get_timestamp_table_filtered Generate timestamps for filtered events only.
get_timestamps Generate timestamps as a pandas DataFrame with units in column names.
get_timestamps_filtered Generate timestamps for filtered events as a pandas DataFrame.
get_timestamps_of Get timestamps for multiple events, returned as a DataFrame.
has_child Check if a child with the given ID exists.
has_flow_map Check if a FlowMap with the given id is attached.
has_region Check if a region exists.
iter_children Iterate over child timelines.
iter_regions Iterate over all regions in insertion order.
list_children List child timeline IDs.
list_flow_maps List all attached FlowMap ids.
list_regions List all region names.
make_coordinate Create a Coordinate in this timeline’s unit.
query_events_hierarchical Query events across the timeline hierarchy.
resolve_subclass Return the canonical Timeline subclass for a unit/number_type pair.
summary Get a summary of the timeline.
to_dataframe Generate timestamps as a pandas DataFrame with formatted column names.
to_dict Convert timeline to a dictionary for serialization.
to_typed Return this timeline re-instantiated as the appropriate typed subclass.
unfold Convert a folded coordinate to unfolded coordinates.
validate_child Validate that a timeline can be added as a child.

add_break

Timeline.add_break(at)

Add a Break (contiguity void) at the specified coordinate.

Args: at: The coordinate for the break.

Raises: NotImplementedError: Breaks will be implemented in a future phase.

add_child

Timeline.add_child(
    child,
    offset,
    allow_expansion=False,
    use_conversion_map=None,
)

Embed a child timeline at the specified offset.

The child timeline will be locked after being added. Parent-child coordinate conversion uses exact offset arithmetic.

From the TTA manuscript (Section 3.4 - Nested Timelines): “A timeline can accommodate not only events but also other timelines, called Children, as long as they use the same measuring unit.”

When the child uses a different unit than the parent, set use_conversion_map to automatically convert the child to the parent’s unit via a C-Map. The parent must have a C-Map whose target_unit matches the child’s unit, so that inverting it yields the child_unit -> parent_unit conversion. The child’s events are copied with converted coordinates; the original child is NOT modified.

The converted child receives the ID {child.id}[{parent.unit}].

Args: child: The timeline to embed. offset: The start coordinate on this timeline, in the parent’s unit. When use_conversion_map is set, the offset must already be expressed in the parent’s unit (e.g. samples). allow_expansion: If True, expand this timeline if needed. use_conversion_map: Conversion map specification for unit conversion. Accepts the same formats as the conversion_maps parameter in timestamp functions: - None (default): No conversion; units must match. - True: Auto-select a parent C-Map whose target unit matches the child’s unit. - str: Look up by C-Map ID or target unit name. - TimeUnit: Find by target unit. - ConversionMap: Use directly.

Raises: TypeError: If child is not a Timeline. ValueError: If units don’t match (and no conversion map given) or would exceed bounds. RuntimeError: If this timeline is locked.

add_conversion_map

Timeline.add_conversion_map(cmap)

Add a ConversionMap to this timeline.

Any map with a target_unit is automatically registered in the unified timestamp system so that :meth:get_timestamp can resolve coordinates in that unit. TableMap instances are wrapped in an InterpolationMap for O(log n) lookup; analytical maps (e.g. ScalarMap, LinearMap) are stored directly.

Args: cmap: The ConversionMap to add.

Raises: ValueError: If the map’s source unit is incompatible.

add_events

Timeline.add_events(rows, allow_expansion=False)

Add events to the timeline.

Only event_type and a coordinate are strictly required per dict. Missing fields are filled in automatically:

  • id: auto-generated (e000001, e000002, …).
  • temporal_type: inferred from keys – "interval" when both start and end (or duration) are present, "instant" otherwise.

Args: rows: List of event dictionaries. Required keys: - event_type: class name (e.g. "Beat", "Note") - instant: coordinate (for instant events), or - start, end: coordinates (for interval events) allow_expansion: If True, expand timeline if events exceed length.

Raises: ValueError: If events exceed length and expansion not allowed. RuntimeError: If timeline is locked and expansion not allowed.

Examples: >>> tl.add_events([ … {“event_type”: “Beat”, “instant”: 0.0}, … {“event_type”: “Note”, “start”: 0.0, “end”: 0.5}, … ])

add_flow_map

Timeline.add_flow_map(flow_map, id=None)

Add a FlowMap to this timeline.

FlowMaps enable coordinate transformation for timelines with flow control (repeats, jumps, D.S., D.C., etc.). They are created by timetoalign.ScoreFlowController and added to the timeline for later use.

Design Decision: Timelines store FlowMaps, NOT FlowControllers. FlowControllers are factories that produce FlowMaps.

Args: flow_map: The FlowMap to add. id: Identifier for this FlowMap. If None, uses flow_map.id. Common values: “default”, “atomic”, “single”.

Examples: >>> controller = ScoreFlowController(measure_data) >>> flow_map = controller.create_flow_map() >>> timeline.add_flow_map(flow_map) >>> timeline.get_flow_map(“default”) # Retrieve later FlowMap(default: 5 sections)

add_jump

Timeline.add_jump(from_, to)

Add a Jump (non-linear contiguity) between coordinates.

Args: from_: The jump source coordinate. to: The jump target coordinate.

Raises: NotImplementedError: Jumps will be implemented in a future phase.

add_match

Timeline.add_match(match)

Add an alignment Match to this timeline.

Args: match: The Match to add.

Raises: NotImplementedError: Alignment is managed via AlignmentBundle.

add_region

Timeline.add_region(region_or_name, start=None, end=None, *, meta=None)

Add or create a named Region on this timeline.

Overloaded for backward compatibility: - add_region(Region) — attach a pre-existing Region object. - add_region(name, start, end) — delegate to :meth:create_region.

Under the unified verb×noun API, add means “attach an existing object” while create means “construct + attach + return”.

Args: region_or_name: A Region object (new) or a string name (legacy). start: Start coordinate (only when region_or_name is a string). end: End coordinate (only when region_or_name is a string). meta: Optional metadata dictionary.

Returns: The Region object (either the one passed in or the newly created one).

Raises: ValueError: If region name already exists, end < start, or arguments are inconsistent. RuntimeError: If timeline is locked.

Examples: >>> # New API — attach a pre-existing Region >>> r = Region(“Chorus”, Coordinate(10, TimeUnit.seconds), … Coordinate(30, TimeUnit.seconds)) >>> tl.add_region(r)

>>> # Legacy API (delegates to create_region)
>>> tl.add_region("Verse", 30, 50, meta={"repeat": 2})

attach_flow_map

Timeline.attach_flow_map(flow_map, id=None)

Deprecated alias for add_flow_map.

.. deprecated:: Use :meth:add_flow_map instead. This alias will be removed in a future version.

convert_to

Timeline.convert_to(values, target_unit)

Convert coordinates to another unit using attached C-Maps.

Args: values: Coordinate value(s) to convert. Can be: - Scalar (int, float, Fraction): Returns a Coordinate object - Coordinate: Returns a Coordinate object - numpy array: Returns a numpy array of converted values target_unit: Target unit.

Returns: - For scalar/Coordinate input: Coordinate object in the target unit - For array input: numpy array of converted values

Raises: ValueError: If no suitable map is found.

Examples: >>> timeline.add_conversion_map(ScalarMap(scalar=1/300, …)) >>> coord = timeline.convert_to(15343, “inches”) >>> coord Coordinate(51.1, inches) >>> arr = timeline.convert_to(np.array([100, 200]), “inches”) >>> arr array([0.333, 0.666])

create_child

Timeline.create_child(
    length,
    offset,
    uid=None,
    name=None,
    allow_expansion=False,
)

Create a new child timeline and embed it at the specified offset.

Convenience method that creates a new timeline with the same unit as the parent and immediately adds it as a child. This is equivalent to:

child = Timeline(length=length, unit=parent.unit, uid=uid, name=name)
parent.add_child(child, offset=offset)

From the TTA manuscript (Section 3.4 - Nested Timelines): “A timeline can accommodate not only events but also other timelines, called Children, as long as they use the same measuring unit.”

Args: length: Length of the child timeline (in parent’s unit). Can be a Coordinate object if its unit matches the parent. offset: The start coordinate on this timeline where the child begins. uid: Unique identifier for the child. Auto-generated if None. name: Human-readable name for the child. allow_expansion: If True, expand parent timeline if needed.

Returns: The newly created and embedded child Timeline.

Raises: ValueError: If offset is negative or child would exceed parent bounds. ValueError: If length/offset Coordinate has mismatched unit. RuntimeError: If this timeline is locked.

Examples: >>> # Create a child representing a region of interest >>> holes_region = image_timeline.create_child( … length=277776, … offset=15343, … uid=“dgt1_holes”, … name=“Musical Holes Region”, … ) >>> # Now add events to the child >>> holes_region.add_events(hole_events)

create_child_from_region

Timeline.create_child_from_region(region_name, *, copy_events=True, uid=None)

Create a child timeline from a named region (partitioning).

The child’s length = region duration, offset = region start. The child’s class matches the parent’s concrete class. If copy_events, events in [start, end) are copied with adjusted coordinates.

Args: region_name: Name of an existing region. copy_events: Copy events within the region to the child. uid: Explicit child ID. Defaults to region name.

Returns: The newly created and attached child timeline.

Raises: KeyError: If region_name not found. RuntimeError: If timeline is locked.

Examples: >>> tl.create_regions_by_splitting(“breaks”, prefix=“movement”) >>> mov4 = tl.create_child_from_region(“movement_4”)

create_children_from_regions

Timeline.create_children_from_regions(region_names=None, *, copy_events=True)

Create children from multiple regions (batch partitioning).

Each region becomes a child. Regions may overlap — resulting children are independent.

Args: region_names: Region names. None = all regions in insertion order. copy_events: Copy events to children.

Returns: List of child timelines in region order.

Raises: KeyError: If any region_name not found. RuntimeError: If timeline is locked.

Examples: >>> tl.create_regions_by_grouping(“@pageIndex”, … name_format=“page_{value}”) >>> tl.create_children_from_regions() # All pages as children

create_region

Timeline.create_region(name, start, end, *, meta=None)

Create a new named Region and attach it to this timeline.

Under the unified verb×noun API, create constructs a new object, attaches it, and returns it.

Args: name: Unique name for this region. start: Start coordinate. end: End coordinate (must be >= start). meta: Optional metadata dictionary.

Returns: The created Region object.

Raises: ValueError: If name already exists or end < start. RuntimeError: If timeline is locked.

Examples: >>> tl.create_region(“Chorus”, 10.0, 30.0) >>> tl.create_region(“Verse”, 30.0, 50.0, meta={“repeat”: 2})

create_regions_by_grouping

Timeline.create_regions_by_grouping(column, *, name_format='{value}')

Create regions by grouping adjacent events on a column value.

For each run of consecutive events that share the same value in the specified column, creates a region spanning the run’s coordinate extent [min_start, max_end). Only adjacent events with the same value are grouped — non-adjacent occurrences of the same value produce separate regions.

This “run-length” semantics is essential for musical data where, e.g., the same time signature may recur after a change (4/4 → 3/4 → 4/4) and each occurrence should be its own region.

Args: column: Event column name to group by. name_format: Format string. Placeholders: {value}, {i} (0-based), {n} (1-based), {run} (1-based run index for this value).

Returns: List of Region objects ordered by start coordinate.

Raises: ValueError: If column does not exist in events. RuntimeError: If timeline is locked.

Examples: >>> # Time-signature regions (adjacent grouping) >>> tl.create_regions_by_grouping(“timesig”) [Region(‘4/4’, 0-64), Region(‘3/4’, 64-88), Region(‘4/4’, 88-120)]

create_regions_by_splitting

Timeline.create_regions_by_splitting(
    predicate,
    *,
    names=None,
    name_format='{prefix}_{n}',
    prefix='section',
    include_before_first=True,
    include_after_last=True,
)

Create contiguous regions by splitting at events matching a predicate.

Finds events matching the predicate, uses their coordinates as split points, creates contiguous regions between consecutive split points.

The predicate can be: - A string: column name. Events where this column is truthy (non-null, non-empty, non-zero) are split points. - A dict: keyword filters in the same style as EventData.filter(). For example {"breaks": "section"} selects events whose breaks column equals "section". - A callable: receives event dict, returns True for split points.

For each matching event the split coordinate is the event’s end (interval events) or start/instant (instant events).

Args: predicate: Column name, filter dict, or callable identifying split-point events. names: Explicit region names. name_format: Format string. Placeholders: {prefix}, {i}, {n}. prefix: Prefix for auto-generated names. include_before_first: Create a region from timeline origin to first split point. include_after_last: Create a region from last split point to timeline end.

Returns: List of contiguous Region objects in coordinate order.

Raises: RuntimeError: If timeline is locked.

Examples: >>> # Split at section breaks >>> tl.create_regions_by_splitting(“breaks”, prefix=“movement”)

>>> # Split at specific break types
>>> tl.create_regions_by_splitting(
...     {"breaks": "section"}, prefix="movement"
... )

create_regions_from_boundaries

Timeline.create_regions_from_boundaries(
    boundaries,
    *,
    names=None,
    name_format='{prefix}_{n}',
    prefix='section',
)

Create contiguous regions from boundary coordinates.

Given k+1 sorted boundary coordinates, creates k regions where region_i spans [boundaries[i], boundaries[i+1]).

Args: boundaries: k+1 monotonically increasing coordinates. names: Explicit names for the k regions. Mutually exclusive with name_format/prefix. name_format: Format string. Placeholders: {prefix}, {i} (0-based), {n} (1-based). prefix: Prefix for auto-generated names.

Returns: List of k Region objects in boundary order.

Raises: ValueError: If fewer than 2 boundaries or not monotonically increasing. RuntimeError: If timeline is locked.

Examples: >>> tl.create_regions_from_boundaries( … [0, 30, 60, 90], … prefix=“movement”, … ) [Region(‘movement_1’, 0-30), Region(‘movement_2’, 30-60), Region(‘movement_3’, 60-90)]

create_segment_line

Timeline.create_segment_line(boundaries, *, copy_events=True)

Create a SegmentLine by segmenting at boundary coordinates.

Given k+1 sorted coordinates, produces a new SegmentLine with k contiguous segments. Each segment’s class matches self’s class.

Does NOT modify self. Returns a new independent SegmentLine.

Args: boundaries: k+1 monotonically increasing coordinates. copy_events: Copy events into their respective segments.

Returns: A new SegmentLine with k segments.

Raises: ValueError: If fewer than 2 boundaries or not monotonically increasing.

Examples: >>> measures = audio_tl.create_segment_line( … [0.0] + measure_times.tolist() + [float(audio_tl.length)] … )

create_segment_line_by_grouping

Timeline.create_segment_line_by_grouping(
    column,
    *,
    copy_events=True,
    name_format='{value}',
)

Create a SegmentLine by grouping adjacent events on a column value.

Groups must form contiguous, non-overlapping spans. This is validated and raises if not satisfied.

Does NOT modify self. Does NOT add intermediate regions to self.

Args: column: Event column to group by. copy_events: Copy events into segments. name_format: Format string for segment names.

Returns: A new SegmentLine.

Raises: ValueError: If groups are not contiguous.

Examples: >>> systems = page.create_segment_line_by_grouping(“spacing_run_id”)

create_segment_line_by_splitting

Timeline.create_segment_line_by_splitting(
    predicate,
    *,
    copy_events=True,
    names=None,
    name_format='{prefix}_{n}',
    prefix='section',
    include_before_first=True,
    include_after_last=True,
)

Create a SegmentLine by splitting at events matching a predicate.

Shortcut for finding split points and creating a SegmentLine directly. Does NOT modify self (no intermediate regions are created).

The predicate follows the same semantics as :meth:create_regions_by_splitting.

Args: predicate: Column name, filter dict, or callable identifying split-point events. copy_events: Copy events into segments. names: Explicit segment names. name_format: Format string for segment names. prefix: Prefix for auto-generated names. include_before_first: Include segment before first split point. include_after_last: Include segment after last split point.

Returns: A new SegmentLine.

Examples: >>> sl = tl.create_segment_line_by_splitting( … {“breaks”: “section”}, prefix=“movement” … )

create_segment_line_from_regions

Timeline.create_segment_line_from_regions(
    region_names=None,
    *,
    copy_events=True,
)

Create a SegmentLine from contiguous regions.

Validates that regions are contiguous and non-overlapping (each region’s end == next region’s start).

Does NOT modify self.

Args: region_names: Ordered region names. None = all regions sorted by start coordinate. copy_events: Copy events into segments.

Returns: A new SegmentLine.

Raises: ValueError: If regions are not contiguous or empty.

Examples: >>> tl.create_regions_by_grouping(“timesig”) >>> seg_line = tl.create_segment_line_from_regions()

derive

Timeline.derive(target_unit, name=None, copy_events=False)

Create a derivative timeline in a different unit via C-Map conversion.

From TTA manuscript (Section 3.3): “A ConversionMap implies the presence of a derived timeline in the target unit. The derive() method makes this implicit timeline explicit.”

The derived timeline: - Has coordinates in the target unit - Has length equal to the converted source length - Automatically has an inverse C-Map back to the source unit - Optionally copies and converts events from the source

This operation creates a NEW timeline, NOT a child timeline. The source and derived timelines have different units, so per TTA specification, they cannot be parent-child (children must share the parent’s unit). Use TimelineGroup to connect them.

Args: target_unit: The unit for the derived timeline. name: Optional name for the derived timeline. copy_events: If True, copy and convert events to the derived timeline.

Returns: A new Timeline in the target unit.

Raises: ValueError: If no C-Map exists for the target unit. ValueError: If C-Map is not invertible (needed for roundtrip).

Examples: >>> # Create physical timeline with tempo C-Map >>> audio = ContinuousPhysicalTimeline(length=60.0) >>> audio.add_conversion_map(LinearMap(2.0, 0.0, … source_unit=TimeUnit.seconds, target_unit=TimeUnit.quarters)) >>> # Derive a logical timeline >>> score = audio.derive(TimeUnit.quarters, name=“score”) >>> score.unit TimeUnit.quarters >>> score.length Coordinate(120.0, quarters) # 60 seconds * 2 q/s

diagram

Timeline.diagram(
    width=70,
    show_children=True,
    max_children=6,
    unicode=True,
    show=None,
)

Generate ASCII diagram for this timeline.

Args: width: Total width of the diagram in characters. show_children: Whether to show child timelines (one per row). max_children: Maximum children to show before truncating. unicode: Use Unicode characters (True) or ASCII fallback (False). show: Optional set controlling which elements appear. Supported values: "children", "regions", and "cmaps" (attached conversion maps). When None, behaviour is exactly as before.

Returns: 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

Timeline.empty(unit=None, number_type=None, **kwargs)

Create an empty Timeline with length 0.

Args: unit: The time unit. Defaults to class default. number_type: The number type. Defaults to class default. **kwargs: Additional arguments passed to init.

Returns: A new empty Timeline.

export_to_csv

Timeline.export_to_csv(
    filepath,
    coordinates=None,
    conversion_maps=True,
    recursion_limit=None,
    include_events=True,
    include_boundaries=False,
    *,
    columns=None,
    units=True,
    sep=',',
    header=True,
    index=False,
)

Export timeline data to a CSV file.

This is a convenience method that generates a timestamp DataFrame and writes it to a CSV file. For more control over the output, use to_dataframe() and save manually.

Args: filepath: Output CSV file path. coordinates: Explicit coordinates to use as the axis. conversion_maps: C-Maps to include as columns. Defaults to True (all). recursion_limit: Maximum depth for child traversal. include_events: If True and coordinates is None, extract from events. include_boundaries: If True, include timeline boundary coordinates. columns: How to name the columns (see to_dataframe). units: If True (default), append units to column names. sep: Field separator. Default “,” (comma). header: If True (default), write column headers. index: If True, write row indices. Default False.

Returns: Number of rows written.

Examples: >>> timeline.export_to_csv(“timestamps.csv”) 100

>>> # Tab-separated, no header
>>> timeline.export_to_csv("data.tsv", sep="\t", header=False)
100

fold

Timeline.fold(coord, id='default')

Convert an unfolded coordinate to a folded coordinate.

Convenience method that delegates to the attached FlowMap.

Args: coord: Coordinate in the unfolded timeline. id: Which FlowMap to use.

Returns: Coordinate in the folded timeline.

Raises: ValueError: If no FlowMap with the given id is attached, or if the coordinate is outside the flow range.

from_dict

Timeline.from_dict(data)

Create a Timeline from a dictionary.

Args: data: Dictionary from to_dict().

Returns: A new Timeline instance.

from_event_data

Timeline.from_event_data(data, **kwargs)

Create a Timeline from an existing EventData.

Args: data: The EventData containing events. **kwargs: Additional arguments passed to init (except unit/number_type).

Returns: A new Timeline wrapping the EventData.

from_events

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.

Args: rows: 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) unit: The time unit. Defaults to class default. number_type: The number type. Defaults to class default. **kwargs: Additional arguments passed to init.

Returns: A new Timeline containing the events.

get_boundary_table

Timeline.get_boundary_table(conversion_maps=True, recursion_limit=None)

Get timestamps for timeline boundaries only.

Returns a timestamp table containing only start (0) and end (length) coordinates for this timeline and all children.

Args: conversion_maps: C-Maps to include as columns (see get_timestamp_table). recursion_limit: Maximum depth for child traversal.

Returns: PyArrow Table with boundary timestamps.

Examples: >>> table = timeline.get_boundary_table() >>> table.to_pandas() axis tl:1 child:1 0 0.0 0.0 NaN 1 10.0 10.0 10.0 2 50.0 NaN 0.0 3 60.0 NaN 10.0

get_child

Timeline.get_child(child_id)

Retrieve a child timeline by ID.

Args: child_id: The ID of the child to retrieve.

Returns: The child Timeline.

Raises: KeyError: If no child with that ID exists.

get_child_offset

Timeline.get_child_offset(child_id)

Get the offset of a child timeline.

Args: child_id: The ID of the child.

Returns: The offset Coordinate.

Raises: KeyError: If no child with that ID exists.

get_children_at

Timeline.get_children_at(coord)

Return all children whose extent contains the given coordinate.

A child contains coord if offset <= coord < offset + child.length.

Args: coord: The coordinate to query.

Returns: List of child Timeline objects, ordered by offset. Empty list if no children contain coord.

get_conversion_map

Timeline.get_conversion_map(target_unit)

Get a conversion map by target unit or by name/id.

When target_unit is a valid TimeUnit value (or an alias such as "seconds"), the method returns the first attached map whose target_unit matches.

When target_unit is a string that does not correspond to any TimeUnit member, the method falls back to a name-based lookup: it searches first by cmap.id, then by cmap.name. This is useful for maps where source and target units are identical (e.g. a ShiftMap named "raw_quarters" that maps normalised quarters back to raw partitura quarters).

Args: target_unit: A TimeUnit member, a unit alias string, or a conversion-map name/id string.

Returns: A matching ConversionMap, or None if not found.

Examples: >>> timeline.get_conversion_map(TimeUnit.seconds) ScalarMap(…) >>> timeline.get_conversion_map(“raw_quarters”) ShiftMap(offset=-0.5, …)

get_event

Timeline.get_event(event_id)

Look up a single event by its id field.

Searches this timeline’s events first, then recursively searches all children. When found in a child, coordinates are adjusted to the root timeline’s coordinate system.

Args: event_id: The event identifier to search for.

Returns: A dictionary representing the event row, or None if not found anywhere in the hierarchy.

Examples: >>> event = timeline.get_event(“notes:note:000001”) >>> event[“id”] ‘notes:note:000001’ >>> timeline.get_event(“nonexistent”) is None True

get_events

Timeline.get_events(
    temporal_type=None,
    event_type=None,
    include_children=True,
    min_coord=None,
    max_coord=None,
    **column_filters,
)

Filter and retrieve events.

When include_children=True (the default), events from all children are included with their coordinates adjusted to the root timeline’s coordinate system. Segment events (internal bookkeeping) are always excluded.

Args: temporal_type: Filter by “instant” or “interval”. event_type: Filter by event type name. include_children: If True (default), include events from all children with root-relative coordinates. min_coord: Minimum coordinate (inclusive). Can be a float in native units or a Coordinate with a different unit (converted via inverse C-Map). max_coord: Maximum coordinate (exclusive). Same conversion rules as min_coord. **column_filters: Additional column equality filters. Each kwarg name is a column name, and the value is the required value (or a list of values for OR logic).

Returns: A filtered EventData with all matching events.

Examples: >>> # Filter by coordinate range >>> events = tl.get_events(min_coord=10.0, max_coord=20.0)

>>> # Filter with a Coordinate in a different unit
>>> from timetoalign import Coordinate, TimeUnit
>>> coord = Coordinate(5.0, TimeUnit.seconds)
>>> events = tl.get_events(min_coord=coord)

>>> # Arbitrary column filters
>>> events = tl.get_events(pitch=60)  # Only middle C
>>> events = tl.get_events(pitch=[60, 62, 64])  # C, D, E

get_events_at

Timeline.get_events_at(coord, tolerance=0.0, include_children=True)

Get all events active at a specific coordinate.

Returns events from this timeline and all children that are active (containing or at) the specified coordinate.

For instant events, an event is “at” the coordinate if its instant is within tolerance of the query coordinate.

For interval events, an event is “active” if the coordinate falls within [start, end).

Args: coord: Coordinate to query (in this timeline’s unit). tolerance: Tolerance for instant event matching (default 0). include_children: If True, include events from children.

Returns: Dict mapping timeline_id to list of events active at that coordinate. Child events have coordinates in their local coordinate system.

Examples: >>> events = score.get_events_at(50.0) >>> events[“score:1”] # Events in root at coord 50 [{“id”: “n1”, “event_type”: “Note”, …}] >>> events[“measure_5”] # Events in measure 5 […]

get_flow_map

Timeline.get_flow_map(id='default')

Get an attached FlowMap by id.

Args: id: Identifier of the FlowMap. Default is “default”.

Returns: The FlowMap if found, None otherwise.

get_interval_stamp

Timeline.get_interval_stamp(start, end, unit=None)

Get a TimeIntervalStamp for a coordinate range.

Args: start: Start coordinate. end: End coordinate. unit: If provided, interpret both coords as being in this unit.

Returns: TimeIntervalStamp with start and end TimeStamps.

Examples: >>> interval = timeline.get_interval_stamp(0.0, 10.0) >>> interval.duration 10.0 >>> interval[“child:1”] # Get (start, end) tuple for child (0.0, 7.5)

get_region

Timeline.get_region(name)

Get a Region by name.

Args: name: The region name.

Returns: The Region object.

Raises: KeyError: If no region with that name exists.

get_regions_at

Timeline.get_regions_at(coord)

Return all regions containing the given coordinate.

A region contains coord if region.start <= coord < region.end (left-inclusive, right-exclusive).

Args: coord: The coordinate to query.

Returns: List of Region objects containing coord, ordered by start coordinate. Empty list if no regions contain coord.

Examples: >>> tl.get_regions_at(75.0) [Region(‘verse_1’, 30-90), Region(‘chorus’, 60-120)]

get_slice

Timeline.get_slice(
    start,
    end,
    *,
    truncate_events=True,
    include_children=True,
    copy_cmaps=True,
)

Extract a portion of this timeline as a new, independent timeline.

Returns a new timeline containing all events within [start, end). The returned timeline has its coordinate origin at 0, with all coordinates shifted by -start.

From the TTA manuscript: slicing creates a new timeline that is a structural copy of the specified interval of the source.

Args: start: Start coordinate (inclusive). end: End coordinate (exclusive). truncate_events: If True (default), interval events straddling the slice boundaries are clipped to [start, end). If False, events must be fully contained to be included. include_children: If True (default), child timelines whose span overlaps [start, end) are recursively sliced and included. copy_cmaps: If True (default), ConversionMaps are bounded-copied for the slice range.

Returns: New Timeline (same concrete subclass) with length = end - start, coordinates shifted to [0, end-start).

Raises: ValueError: If start >= end or either is outside timeline bounds.

Examples: >>> source = ContinuousLogicalTimeline(length=100) >>> source.add_events([ … {“event_type”: “Note”, “start”: 10, “end”: 30}, … {“event_type”: “Beat”, “instant”: 25}, … ]) >>> sliced = source.get_slice(20, 40) >>> sliced.length.value # 40 - 20 = 20 Fraction(20, 1)

get_timestamp

Timeline.get_timestamp(coord, unit=None)

Get a TimeStamp at a specific coordinate.

This is the primary coordinate resolution API. The TimeStamp provides access to all equivalent coordinates across children and C-Map units.

Uses InterpolationMaps for O(log n) coordinate conversion.

Args: coord: Coordinate value. Can be: - int/float/Fraction: Value in timeline’s native unit - Coordinate: Must match unit or specify via unit param unit: If provided, interpret coord as being in this unit. The coordinate is first converted via inverse C-Map.

Returns: TimeStamp object for the resolved coordinate.

Raises: ValueError: If unit specified but no inverse C-Map available.

Examples: >>> ts = timeline.get_timestamp(5.0) >>> ts[“child_a”] # Get coordinate on child_a 2.5

>>> # Query with unit conversion
>>> ts = timeline.get_timestamp(10.5, unit=TimeUnit.seconds)
>>> ts.axis  # Converted from seconds to timeline's unit
5.0

get_timestamp_at

Timeline.get_timestamp_at(coord, unit=None)

Alias for get_timestamp() for API consistency with TimelineGroup.

TimelineGroup uses get_timestamp_at(coord, tl_id) with an additional timeline_id parameter. This alias provides a consistent verb across the hierarchy.

Args: coord: Coordinate value (see get_timestamp() for details). unit: Optional unit for coordinate interpretation.

Returns: TimeStamp object for the resolved coordinate.

See Also: get_timestamp: The primary coordinate resolution method. timetoalign.TimelineGroup.get_timestamp_at: Group-level version.

get_timestamp_of

Timeline.get_timestamp_of(event_id)

Get the timestamp for a specific event by its ID.

Returns a TimeStamp for instant events, or a TimeIntervalStamp for interval events. Searches recursively through children if the event is not found on this timeline directly.

Args: event_id: The event identifier to look up.

Returns: TimeStamp for instant events, TimeIntervalStamp for interval events.

Raises: KeyError: If no event with the given ID exists.

Examples: >>> ts = timeline.get_timestamp_of(“note:000001”) >>> ts.axis # For instant events 5.0

>>> ts = timeline.get_timestamp_of("clt1:note:000001")
>>> ts.start.axis  # For interval events
0.0
>>> ts.end.axis
2.5

See Also: get_timestamp: Get timestamp by coordinate. get_event: Get the raw event dict by ID.

get_timestamp_table

Timeline.get_timestamp_table(
    coordinates=None,
    conversion_maps=True,
    recursion_limit=None,
    include_events=True,
    include_boundaries=False,
)

Generate a timestamp table as a PyArrow Table.

A Timestamp is a cross-section through the timeline hierarchy showing synchronous coordinates. This method computes local coordinates for each timeline in the hierarchy at each axis coordinate.

Supports IdCoordinate for automatic child offset resolution:

>>> # IdCoordinates from child timeline - offsets auto-applied!
>>> child_coords = [IdCoordinate(v, unit, "child_id") for v in values]
>>> df = parent.get_timestamps(coordinates=child_coords)

Args: coordinates: Explicit coordinates to use as the axis. If None, coordinates are extracted from events (and optionally boundaries). Accepts IdCoordinate objects - if timeline_id matches a child, the offset is automatically applied. conversion_maps: C-Maps to include as columns. Flexible input: - True: Include all attached conversion maps - str: Map ID or target unit name (e.g., “inches”, “seconds”) - TimeUnit: Find map by target unit enum - ConversionMap: Include the specific map - list: Mix of the above - None/False: No conversion maps recursion_limit: Maximum depth for child traversal. None = unlimited. include_events: If True and coordinates is None, extract from events. include_boundaries: If True, include timeline boundary coordinates.

Returns: PyArrow Table with schema: - axis: float64 (root coordinate) - {timeline_id}: float64 (nullable, local coordinate per timeline) - {cmap_id}: varies (converted value per C-Map)

Each field includes metadata:
    - unit: TimeUnit.value string (e.g., "seconds", "pixels")
    - timeline_id: Timeline ID (for timeline columns)
    - cmap_id: C-Map ID (for C-Map columns)

Access metadata via: ``table.schema.field(col_name).metadata``

Examples: >>> table = timeline.get_timestamp_table() >>> table.column_names [‘axis’, ‘tl:1’, ‘notes’, ‘measures’]

>>> # Include all attached C-Maps
>>> table = timeline.get_timestamp_table(conversion_maps=True)

>>> # Include specific C-Maps by target unit
>>> table = timeline.get_timestamp_table(conversion_maps=["inches", "cm"])

>>> # Access unit metadata
>>> table.schema.field('axis').metadata[b'unit']
b'seconds'

get_timestamp_table_filtered

Timeline.get_timestamp_table_filtered(
    event_filter,
    conversion_maps=True,
    recursion_limit=None,
    include_boundaries=False,
)

Generate timestamps for filtered events only.

.. deprecated:: This method is deprecated. Use get_events(**filters) combined with get_timestamp_table() instead. The get_events() method now supports arbitrary column filters via **kwargs.

Applies an event filter before extracting coordinates from EventData. This enables efficient timestamp generation for subsets of events (e.g., only Note events, events above a certain duration, etc.).

The filter is applied to each timeline in the hierarchy using either EventData.filter() (for dict filters) or EventData.where() (for PyArrow compute expressions).

Args: event_filter: Filter to apply before extracting coordinates. - dict: Passed to EventData.filter() for simple filters. Example: {“event_type”: “Note”} or {“temporal_type”: “interval”} - pc.Expression: Passed to EventData.where() for complex filters. Example: pc.greater(pc.struct_field(pc.field(“start”), “value”), 10.0) conversion_maps: C-Maps to include as columns (see get_timestamp_table). recursion_limit: Maximum depth for child traversal. include_boundaries: If True, also include timeline boundary coordinates.

Returns: PyArrow Table with timestamp data for filtered events only.

Examples: >>> # Dict filter: only Note events >>> table = timeline.get_timestamp_table_filtered( … {“event_type”: “Note”} … )

>>> # Dict filter: only interval events
>>> table = timeline.get_timestamp_table_filtered(
...     {"temporal_type": "interval"}
... )

>>> # PyArrow Expression: events starting after coordinate 10
>>> import pyarrow.compute as pc
>>> expr = pc.greater(
...     pc.struct_field(pc.field("start"), "value"),
...     10.0
... )
>>> table = timeline.get_timestamp_table_filtered(expr)

>>> # Combine with C-Maps
>>> table = timeline.get_timestamp_table_filtered(
...     {"event_type": "Note"},
...     conversion_maps=["seconds"],
... )

get_timestamps

Timeline.get_timestamps(
    coordinates=None,
    conversion_maps=True,
    recursion_limit=None,
    include_events=True,
    include_boundaries=False,
    *,
    units=True,
    include_ids=True,
    as_fractions=None,
)

Generate timestamps as a pandas DataFrame with units in column names.

Convenience wrapper around get_timestamp_table() for users who prefer working with pandas.

IdCoordinate support: When passing IdCoordinate objects whose timeline_id matches a child timeline, the offset is automatically applied. This enables the dead-simple pattern::

child_coords = [IdCoordinate(v, unit, "dgt_holes") for v in values]
df = parent.get_timestamps(coordinates=child_coords)

Args: coordinates: CoordinateSpec or sequence of CoordinateSpec. Accepts IdCoordinate - if timeline_id matches a child, offset is auto-applied. conversion_maps: C-Maps to include as columns. Flexible input: - True: Include all attached conversion maps - str: Map ID or target unit name (e.g., “inches”, “seconds”) - TimeUnit: Find map by target unit enum - ConversionMap: Include the specific map - list: Mix of the above - None/False: No conversion maps recursion_limit: Maximum depth for child traversal. include_events: If True and coordinates is None, extract from events. include_boundaries: If True, include timeline boundary coordinates. units: If True (default), append units to column names like “name (unit)”. include_ids: If True (default), add event IDs as the DataFrame index. Each coordinate is matched to the nearest event at that coordinate, showing what each timestamp row corresponds to. as_fractions: If True, convert float values to Fraction objects for fraction number-type timelines. If None (default), auto-detect based on the timeline’s number_type.

Returns: pandas DataFrame with units in column names (if units=True) and event IDs as the index (if include_ids=True). For fraction number-type timelines with as_fractions=True, coordinate columns contain Fraction objects instead of floats.

Examples: >>> df = timeline.get_timestamps() >>> df.index.name ‘id’

get_timestamps_filtered

Timeline.get_timestamps_filtered(
    event_filter,
    conversion_maps=True,
    recursion_limit=None,
    include_boundaries=False,
)

Generate timestamps for filtered events as a pandas DataFrame.

.. deprecated:: This method is deprecated. Use get_events(**filters) combined with get_timestamps() instead. The get_events() method now supports arbitrary column filters via **kwargs.

Convenience wrapper around get_timestamp_table_filtered() for users who prefer working with pandas.

Args: event_filter: Filter to apply (dict for simple, pc.Expression for complex). conversion_maps: C-Maps to include as columns (see get_timestamp_table). recursion_limit: Maximum depth for child traversal. include_boundaries: If True, include timeline boundary coordinates.

Returns: pandas DataFrame with timestamps for filtered events.

Examples: >>> df = timeline.get_timestamps_filtered({“event_type”: “Note”}) >>> df.head()

get_timestamps_of

Timeline.get_timestamps_of(event_ids)

Get timestamps for multiple events, returned as a DataFrame.

For each event, includes columns for start coordinate, end coordinate (if interval), event type, and temporal type.

Args: event_ids: Sequence of event identifiers to look up.

Returns: DataFrame indexed by event_id with columns: - start: Start coordinate value - end: End coordinate value (NaN for instant events) - event_type: The event type name - temporal_type: “instant” or “interval”

Raises: KeyError: If any event ID is not found.

Examples: >>> df = timeline.get_timestamps_of([“note:000001”, “note:000002”]) >>> df.loc[“note:000001”, “start”] 0.0

See Also: get_timestamp_of: Get a single event’s timestamp. get_events: Filter events by type or coordinate range.

has_child

Timeline.has_child(child_id)

Check if a child with the given ID exists.

Args: child_id: The child ID to check.

Returns: True if such a child exists.

has_flow_map

Timeline.has_flow_map(id='default')

Check if a FlowMap with the given id is attached.

Args: id: Identifier to check.

Returns: True if a FlowMap with that id exists.

has_region

Timeline.has_region(name)

Check if a region exists.

Args: name: Name of the region.

Returns: True if the region exists.

iter_children

Timeline.iter_children(order='sorted', recursion_limit=None, include_self=False)

Iterate over child timelines.

Args: order: Traversal order - “sorted” (by offset), “depth_first”, or “breadth_first”. recursion_limit: Maximum recursion depth. None for unlimited. include_self: If True, yield this timeline first.

Yields: Tuples of (offset_coordinate, child_timeline).

iter_regions

Timeline.iter_regions()

Iterate over all regions in insertion order.

Yields: Region objects.

list_children

Timeline.list_children()

List child timeline IDs.

Returns: List of child IDs in insertion order.

list_flow_maps

Timeline.list_flow_maps()

List all attached FlowMap ids.

Returns: List of id strings.

list_regions

Timeline.list_regions()

List all region names.

Returns: List of region names in insertion order.

make_coordinate

Timeline.make_coordinate(value)

Create a Coordinate in this timeline’s unit.

Public API for creating coordinates compatible with this timeline.

Args: value: The numeric value for the coordinate.

Returns: A Coordinate with this timeline’s unit.

query_events_hierarchical

Timeline.query_events_hierarchical(
    coord_range=None,
    event_types=None,
    include_children=True,
    recursion_limit=None,
)

Query events across the timeline hierarchy.

Returns events from this timeline and all children, with coordinates adjusted to the root timeline’s coordinate system.

From TTA manuscript: Hierarchical timelines should support querying events across the entire hierarchy with root-relative coordinates.

Args: coord_range: Optional (min, max) range filter in ROOT coordinates. event_types: Optional set of event types to include. include_children: If True, include events from children. recursion_limit: Maximum depth for child traversal. None = unlimited.

Returns: List of event dictionaries, each augmented with: - “source_timeline”: ID of the timeline containing the event - “root_start”: Root-relative start coordinate - “root_end”: Root-relative end coordinate (for intervals)

Examples: >>> # Get all notes in a range >>> events = score.query_events_hierarchical( … coord_range=(16.0, 40.0), … event_types={“Note”}, … ) >>> len(events) 127

resolve_subclass

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.

Args: unit: The time unit to look up. number_type: Optional number type for disambiguation (e.g. NumberType.fraction selects ContinuousLogicalTimeline over DiscreteLogicalTimeline).

Returns: 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

Timeline.summary()

Get a summary of the timeline.

Returns: Dict with timeline information.

to_dataframe

Timeline.to_dataframe(
    coordinates=None,
    conversion_maps=True,
    recursion_limit=None,
    include_events=True,
    include_boundaries=False,
    *,
    columns=None,
    units=True,
    format='pandas',
)

Generate timestamps as a pandas DataFrame with formatted column names.

This is the recommended high-level method for getting timestamp data. It builds on get_timestamp_table() and applies column formatting.

Args: coordinates: Explicit coordinates to use as the axis. conversion_maps: C-Maps to include as columns. Defaults to True (all). recursion_limit: Maximum depth for child traversal. include_events: If True and coordinates is None, extract from events. include_boundaries: If True, include timeline boundary coordinates. columns: How to name the columns. Options: - None or ColumnNaming.name (default): Use timeline/cmap name - ColumnNaming.id: Use timeline/cmap id - Callable: Function taking (name, metadata_dict) -> new_name - list[str]: Explicit column names units: If True (default), append units to column names like “name (unit)”. format: Output format. Currently only “pandas” is supported.

Returns: pandas DataFrame with: - Columns named according to the columns parameter - Units appended if units=True - Integer columns using pandas nullable Int64 dtype

Examples: >>> df = timeline.to_dataframe() >>> df.columns Index([‘axis (pixels)’, ‘dgt1 (pixels)’, ‘pixels_to_inches (inches)’])

>>> # Without units in column names
>>> df = timeline.to_dataframe(units=False)
>>> df.columns
Index(['axis', 'dgt1', 'pixels_to_inches'])

to_dict

Timeline.to_dict()

Convert timeline to a dictionary for serialization.

Returns: A dictionary representation of the timeline.

to_typed

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, children, conversion maps, regions, and metadata are preserved. Children are transferred as-is (not recursively re-typed).

Returns: A Timeline instance of the appropriate typed subclass, or self 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

unfold

Timeline.unfold(coord, id='default')

Convert a folded coordinate to unfolded coordinates.

Convenience method that delegates to the attached FlowMap. Since repeats can cause a folded coordinate to appear multiple times in the unfolded timeline, this returns a list.

Args: coord: Coordinate in the folded timeline. id: Which FlowMap to use.

Returns: List of coordinates in the unfolded timeline.

Raises: ValueError: If no FlowMap with the given id is attached.

validate_child

Timeline.validate_child(child, offset)

Validate that a timeline can be added as a child.

From the TTA manuscript (Section 3.4 - Nested Timelines): “A timeline can accommodate not only events but also other timelines, called Children, as long as they use the same measuring unit.”

For cross-domain relationships (e.g., physical to logical), use TimelineGroup instead of parent-child nesting.

Args: child: The timeline to validate. offset: The proposed start coordinate.

Raises: TypeError: If child is not a Timeline. ValueError: If units don’t match or child already has a parent.