EventData

EventData(table, unit, number_type=NumberType.float)

PyArrow-based storage for timeline events.

EventData wraps a PyArrow table containing events. Events are rows in the table, not Python wrapper objects. The primary API is bulk operations:

  • from_dicts(): Create from list of row dictionaries
  • from_arrays(): Create from field-oriented arrays
  • from_dataframe(): Create from pandas DataFrame

The schema is fixed at class definition time but can be extended by subclasses to add domain-specific fields (e.g., pitch, velocity for notes).

NOTE: This class was renamed from EventStore to EventData in the 2026-01 API refactoring. EventStore now refers to the container class (formerly EventBundle) that holds one or more EventData tables.

Attributes

Name Type Description
table pa.Table The underlying PyArrow table.
unit TimeUnit The time unit for all coordinates.
number_type NumberType The number type used for coordinates.

Examples

>>> data = EventData.from_dicts([
...     {"id": "e1", "temporal_type": "instant", "event_type": "Beat",
...      "instant": 0.0},
...     {"id": "e2", "temporal_type": "interval", "event_type": "Note",
...      "start": 0.0, "end": 1.0},
... ], unit=TimeUnit.seconds)
>>> len(data)
2

Methods

Name Description
column_values Return a column’s values as plain, decoded Python objects.
concat Concatenate with other EventData, returning a new EventData.
coordinate_range Get the min and max coordinates across all events.
count_by Count events grouped by a field’s values.
create_timeline Create a Timeline from this EventData.
empty Create an empty EventData.
event_types Get the list of unique event types.
extend Extend this data with events from another EventData (in-place).
field_names Get the list of field names for this EventData class.
filter Filter events by criteria, returning a new EventData.
from_arrays Create EventData from field-oriented arrays (VECTORIZED).
from_dataframe Create EventData from a pandas DataFrame.
from_dicts Create EventData from a list of row dictionaries.
from_parquet Load EventData from a Parquet file.
get_schema Get the canonical PyArrow schema for this EventData class.
head Return the first n events as a pandas DataFrame.
prefix_ids Return a new EventData with all event IDs prefixed.
select Select specific fields from the table.
summary Get a comprehensive summary of the store.
to_dataframe Convert to a DataFrame in the specified format.
to_parquet Save the EventData to a Parquet file.
where Filter with a custom PyArrow compute expression.

column_values

EventData.column_values(name, *, default=None)

Return a column’s values as plain, decoded Python objects.

A rational-shaped column – any struct column carrying a value sub-field, such as the canonical {value, numerator, denominator} coordinate struct used by start, end, duration, and any extra field sharing that shape – decodes to an exact Fraction via struct_to_rational. When a row’s struct carries no exact ratio (missing or non-integral numerator/denominator), the float value member is used instead, wrapped in a Fraction. Every other column type is returned via to_pylist() unchanged, including None for a null cell – default only substitutes for a null rational-shaped struct or a column absent from this table entirely.

Parameters

Name Type Description Default
name str Field name in the underlying table. required
default Any Value substituted for every row when name is not a column of this table, and for individual null rational struct cells. None

Returns

Name Type Description
list[Any] A list of per-row values, one for each event.

concat

EventData.concat(*others)

Concatenate with other EventData, returning a new EventData.

Parameters

Name Type Description Default
*others 'EventData' Other EventData to concatenate (extra fields are allowed and will be merged using schema promotion). ()

Returns

Name Type Description
'EventData' A new EventData containing all events.

Raises

Name Type Description
ValueError If any units don’t match.

coordinate_range

EventData.coordinate_range()

Get the min and max coordinates across all events.

Returns

Name Type Description
tuple[float | Fraction, float | Fraction] | None Tuple of (min, max) coordinates, or None if store is empty.
tuple[float | Fraction, float | Fraction] | None Returns Fraction values when number_type is fraction.

count_by

EventData.count_by(field)

Count events grouped by a field’s values.

Parameters

Name Type Description Default
field str The field to group by. required

Returns

Name Type Description
dict[str, int] Dict mapping field values to counts.

create_timeline

EventData.create_timeline(uid=None, filters=None)

Create a Timeline from this EventData.

This is a convenience method that creates a timeline with the data’s events directly. The timeline class and number_type are inferred from the data’s unit (e.g., ticks -> DiscreteLogicalTimeline with int).

Parameters

Name Type Description Default
uid str | None Unique ID for the timeline. Auto-generated if None. None
filters dict[str, Any] | None Filter kwargs to apply before timeline creation. Example: {“event_type”: “Note”} to exclude rests. None

Returns

Name Type Description
'Timeline' A Timeline containing the (filtered) events.

Examples

>>> timeline = data.create_timeline(uid="notes")
>>> filtered = data.create_timeline(filters={"event_type": "Note"})

empty

EventData.empty(unit, number_type=NumberType.float)

Create an empty EventData.

Parameters

Name Type Description Default
unit TimeUnit The time unit for coordinates. required
number_type NumberType The number type for coordinates. NumberType.float

Returns

Name Type Description
Self An empty EventData with the appropriate schema.

event_types

EventData.event_types()

Get the list of unique event types.

Returns

Name Type Description
list[str] List of event type names.

extend

EventData.extend(other)

Extend this data with events from another EventData (in-place).

Parameters

Name Type Description Default
other 'EventData' Another EventData with compatible schema (extra fields are allowed and will be merged using schema promotion). required

Raises

Name Type Description
ValueError If units don’t match.

field_names

EventData.field_names()

Get the list of field names for this EventData class.

Returns

Name Type Description
list[str] List of all field names (base + extra).

filter

EventData.filter(
    temporal_type=None,
    event_type=None,
    min_coord=None,
    max_coord=None,
    **kwargs,
)

Filter events by criteria, returning a new EventData.

All criteria are AND-ed together.

Parameters

Name Type Description Default
temporal_type Literal['instant', 'interval'] | None Filter by “instant” or “interval”. None
event_type str | None Filter by event type name. None
min_coord CoordinateSpec | None Minimum coordinate (inclusive), optionally with a unit. None
max_coord CoordinateSpec | None Maximum coordinate (exclusive), optionally with a unit. None
**kwargs Any Exact match filters for other fields (e.g. event_category=“note”). {}

Coordinate bounds are compared against the stored float coordinate representation. Fraction bounds are converted to float for this comparison; integer and float bounds retain their respective types. The minimum remains inclusive and the maximum remains exclusive.

Returns

Name Type Description
'EventData' A new EventData with filtered events.

from_arrays

EventData.from_arrays(
    fields,
    unit,
    number_type=NumberType.float,
    *,
    validate=True,
    extra_fields=None,
    interval_policy=IntervalPolicy.warn,
)

Create EventData from field-oriented arrays (VECTORIZED).

This is the PRIMARY construction method for loaders. All operations are vectorized - NO row iteration occurs.

Missing end or duration values are computed automatically from the other (end = start + duration or duration = end - start). Behaviour when both are present but inconsistent is controlled by interval_policy.

Parameters

Name Type Description Default
fields dict[str, np.ndarray | pa.Array | list[Any]] Dict mapping field names to arrays. Supports: - np.ndarray: NumPy arrays - pa.Array: PyArrow arrays (including StructArray for coords) - list: Python lists (converted to numpy) For coordinate fields (start, end, duration): - If pa.StructArray: used directly - If numeric/string array: parsed via CoordinateParser required
unit TimeUnit The time unit for coordinates. required
number_type NumberType The number type for coordinates. NumberType.float
validate bool Whether to validate arrays before table construction. True
extra_fields list[pa.Field] | None Optional list of PyArrow fields for extra data. These fields include metadata (e.g., unit for CoordinateFields). If not provided, fields are inferred from the data arrays. None
interval_policy IntervalPolicy How to handle end/duration inconsistencies. See IntervalPolicy for options. IntervalPolicy.warn

Returns

Name Type Description
Self A new EventData containing the events.

Raises

Name Type Description
ValueError If validation fails (missing fields, length mismatch, etc.)

Examples

>>> # Vectorized construction from arrays
>>> data = EventData.from_arrays({
...     "id": np.array(["e1", "e2"]),
...     "temporal_type": np.array(["instant", "instant"]),
...     "event_type": np.array(["Beat", "Beat"]),
...     "start": CoordinateParser.parse([0, 480], NumberType.int, unit),
... }, unit=TimeUnit.ticks)
>>> # Direct from loader output (StructArrays already parsed)
>>> data = EventData.from_arrays(loader_fields, unit=TimeUnit.quarters)

from_dataframe

EventData.from_dataframe(df, unit, number_type=NumberType.float)

Create EventData from a pandas DataFrame.

Parameters

Name Type Description Default
df pd.DataFrame DataFrame with event data. Field names should match the schema. required
unit TimeUnit The time unit for coordinates. required
number_type NumberType The number type for coordinates. NumberType.float

Returns

Name Type Description
Self A new EventData containing the events.

from_dicts

EventData.from_dicts(
    rows,
    unit,
    number_type=NumberType.float,
    *,
    interval_policy=IntervalPolicy.warn,
)

Create EventData from a list of row dictionaries.

Coordinate values (instant, start, end, duration) are automatically converted to the internal struct format. Convenience defaults are applied so that callers can omit boilerplate fields:

  • id: Auto-generated as {event_type}:{counter} if missing, e.g. note:000001, rest:000001, beat:000001. When events are placed on a timeline, the timeline’s ID is prepended, yielding e.g. clt:1:note:000001.
  • temporal_type: Inferred from the keys present in the dict – "interval" when both start and end (or duration) are given, "instant" otherwise.

Missing end or duration values are computed automatically from the other (end = start + duration or duration = end - start). Behaviour when both are present but inconsistent is controlled by interval_policy.

Parameters

Name Type Description Default
rows list[dict[str, Any]] List of event dictionaries. At minimum each dict needs a coordinate (instant or start/end) and an event_type. All other fields have sensible defaults. required
unit TimeUnit The time unit for coordinates. required
number_type NumberType The number type for coordinates. NumberType.float
interval_policy IntervalPolicy How to handle end/duration inconsistencies. See IntervalPolicy for options. IntervalPolicy.warn

Returns

Name Type Description
Self A new EventData containing the events.

Examples

>>> data = EventData.from_dicts([
...     {"event_type": "Beat", "instant": 0},
...     {"event_type": "Note", "start": 0, "end": 0.5},
... ], unit=TimeUnit.seconds)

from_parquet

EventData.from_parquet(path)

Load EventData from a Parquet file.

Parameters

Name Type Description Default
path Path | str Path to the Parquet file. required

Returns

Name Type Description
Self An EventData loaded from the file.

Raises

Name Type Description
ValueError If the file lacks required TimeToAlign! metadata.

get_schema

EventData.get_schema(unit, number_type=None)

Get the canonical PyArrow schema for this EventData class.

This is a class-level method that returns the schema for a given unit, independent of any specific instance. Useful for constructing empty tables or validating incoming data.

Parameters

Name Type Description Default
unit TimeUnit The time unit for coordinate fields. required
number_type NumberType | None The number type for coordinate fields. None

Returns

Name Type Description
pa.Schema The complete schema including base and extra fields.

head

EventData.head(n=5)

Return the first n events as a pandas DataFrame.

A pandas-style preview of the stored rows. Coordinate columns render as their native numbers — the same conversion :meth:to_dataframe applies — so events.head() shows the leading events directly, without reaching for the raw PyArrow table.

Parameters

Name Type Description Default
n int Number of leading events to include. Values larger than the event count return every event; n <= 0 returns an empty frame. 5

Returns

Name Type Description
pd.DataFrame A pandas DataFrame of the first n events.

Examples

>>> events.head()      # first five events
>>> events.head(3)     # first three events

prefix_ids

EventData.prefix_ids(prefix)

Return a new EventData with all event IDs prefixed.

Prepends prefix: to every event ID. Used when events are placed onto a timeline so that IDs become globally unique and informative, e.g. clt1:note:000001.

If the IDs already start with the prefix, they are left unchanged.

Parameters

Name Type Description Default
prefix str The prefix to prepend (without trailing colon). required

Returns

Name Type Description
'EventData' A new EventData with prefixed IDs.

select

EventData.select(fields)

Select specific fields from the table.

Parameters

Name Type Description Default
fields list[str] List of field names to select. required

Returns

Name Type Description
pa.Table A PyArrow table with only the selected fields.

summary

EventData.summary()

Get a comprehensive summary of the store.

Returns

Name Type Description
dict[str, Any] Dict with count, temporal type counts, event type counts,
dict[str, Any] coordinate range, unit, and number type.

to_dataframe

EventData.to_dataframe(format='pandas', *, raw=False, coordinates=False)

Convert to a DataFrame in the specified format.

Higher-level method that dispatches to format-specific implementations. Currently supports pandas; polars support can be added later.

Parameters

Name Type Description Default
format str DataFrame format (“pandas”). Default “pandas”. 'pandas'
raw bool If True, return raw conversion with struct dicts for coordinates. False
coordinates bool If True, wrap values in Coordinate objects with unit info. False

Returns

Name Type Description
pd.DataFrame A DataFrame in the requested format.

Raises

Name Type Description
ValueError If format is not supported.

Examples

>>> df = events.to_dataframe()  # pandas DataFrame
>>> df.iloc[0]['start']  # Fraction(1, 4) or 0.25
>>> df = events.to_dataframe("pandas", raw=True)
>>> df.iloc[0]['start']  # {'value': 0.25, 'numerator': 1, 'denominator': 4}
>>> df = events.to_dataframe(coordinates=True)
>>> df.iloc[0]['start']  # Coordinate(value=Fraction(1, 4), unit=quarters)

to_parquet

EventData.to_parquet(path)

Save the EventData to a Parquet file.

Parameters

Name Type Description Default
path Path | str Path to write the Parquet file. required

where

EventData.where(expression)

Filter with a custom PyArrow compute expression.

Parameters

Name Type Description Default
expression pc.Expression A PyArrow compute expression. required

Returns

Name Type Description
'EventData' A new EventData with filtered events.