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 bothstartandend(orduration) 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:
- 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.
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.