create_unfolded_timeline

timelines.create_unfolded_timeline(
    source_timeline,
    flow,
    flow_controller=None,
    *,
    uid=None,
    target_unit=None,
    include_children=True,
)

Create an unfolded timeline from a folded source via structural slicing.

Computes QB-space boundaries for each PlaythroughSection in the Flow, extracts a slice from the source timeline at each boundary, and appends the slices, in target (unfolded) order, as children of a new timeline of the source’s concrete type. Unfolding assembles a new timeline by selecting and concatenating contiguous portions of the folded source. See the Conceptual Model documentation (https://timetoalign.github.io/concepts.html).

The returned timeline has:

  • The same concrete class as source_timeline (unless target_unit selects another), with correct QB-space coordinates.
  • One appended child per playthrough section, each named after the section (repeats add a -rend2, -rend3 … suffix).
  • A matching Region per child, in unfolded coordinates.
  • A reverse FlowMap attached (id "source") for folded ↔︎ unfolded conversion, and a forward FlowMap (id f"forward_{flow.id}").
  • Events structurally copied via Timeline.get_slice() (including truncation of interval events at section boundaries); the flattened coordinates remain reachable via get_events(include_children=True).

Unfolding uses structural slicing because QB-space section boundaries preserve correct coordinates for scores with non-uniform measure durations.

Parameters

Name Type Description Default
source_timeline 'Timeline' The folded source timeline. required
flow Flow The computed Flow (sequence of sections). required
flow_controller FlowControllerBase | None The controller that computed the flow. Required for QB-space boundary computation. If None, the function raises ValueError because no QB-space boundaries can be computed. None
uid str | None Optional identifier for the returned timeline. None
target_unit 'TimeUnit | str | None' Optional unit for the unfolded timeline. When given, Timeline.resolve_subclass(target_unit, number_type) selects the timeline type; otherwise type(source_timeline) is used. None
include_children bool If True (default), child timelines are recursively sliced and included in each section. True

Returns

Name Type Description
'Timeline' New Timeline of the source’s concrete type, with one appended child
'Timeline' (plus matching Region) per playthrough section, a reverse FlowMap
'Timeline' (id "source"), and a forward FlowMap (id f"forward_{flow.id}").

Raises

Name Type Description
ValueError If flow_controller is None and QB-space boundaries cannot be computed.

Examples

>>> controller = ScoreFlowController(measure_data)
>>> flow = controller.compute_flow(FlowMode.default)
>>> unfolded = create_unfolded_timeline(source_tl, flow, controller)
>>> type(unfolded).__name__  # preserves source type
'ContinuousLogicalTimeline'
>>> unfolded.get_flow_map("source")  # Reverse map to trace back
FlowMap(default_inverse: 5 sections)

See Also

compute_qb_sections: Computes QB boundaries from Flow + controller. Timeline.get_slice: Extracts a portion of a timeline.