Skip to content

Object-centric data (OCEL 2)

Conventional event logs assume every event belongs to exactly one case. That works cleanly for a process like a single support ticket’s lifecycle. It works less cleanly for something like order-to-cash: an order can contain several items, each item might ship in a separate delivery, and a delivery might later trigger a separate return process. Which one is “the case”?

Pick the order, and you either drop item- and delivery-level events or duplicate them across every order that shares a delivery. Pick the item, and you lose the fact that several items were consolidated into one delivery. There’s no correct single answer, because the process genuinely involves several related kinds of entities, not one.

OCEL 2 (Object-Centric Event Log, version 2) drops the single-case assumption. An event can relate to any number of objects, each with its own object type (order, item, delivery, …) and its own attributes. Instead of one case identifier per event, an event carries a set of object references, and relationships between objects (an order contains items; a delivery fulfills items) are recorded explicitly.

Structurally, an OCEL 2 log (as JSON or SQLite) has:

  • Object types and event types, each with typed attributes.
  • Objects, each with an object type and attribute values (which may change over time).
  • Events, each with an event type, a timestamp, and references to the objects involved.
  • Object relationships, both between objects (order → item) and, in OCEL 2 specifically, qualified relationships between events and objects (this event’s role for that object was “resource” vs. “target”).

Object-centric artifacts get their own set of views, distinct from the single-case ones:

  • Object-centric directly-follows graphs (OC-DFGs) show control flow per object type, with edges annotated by which relationship drove them.
  • Object-centric Petri nets (OCPNs) extend Petri nets with per-object-type token flows sharing transitions.
  • Case/variant views can still be produced by flattening an object-centric log onto a chosen object type (for example, treating each order as a case again) when you specifically want the conventional view for one entity.

You don’t need to choose between object-centric and conventional analysis up front — a flattened, single-case view of an OCEL 2 log is a fine starting point, and you can move to the full object-centric views (in the Model and Conformance tabs) once you need to reason about how object types relate.

Promenade reads OCEL 2’s JSON and SQLite serializations directly. If your source system exports conventional event logs per entity (one CSV per object type, say), Promenade does not merge them for you. Join them into a single event table first — one row per event, with one column per object type holding the ids of the objects that event touches — and import that CSV. Each such column becomes an object type:

Event,Activity,Timestamp,Order,Item,price
e1,Place order,2026-03-02T09:14:00Z,o1,i1|i2,49.90
e2,Pick item,2026-03-02T11:30:00Z,,i1,
e3,Pick item,2026-03-02T11:42:00Z,,i2,
e4,Ship order,2026-03-03T08:05:00Z,o1,i1|i2,

This yields two object types, Order and Item, and three event types. e1 and e4 each relate to the order and both items, while each Pick item event relates to a single item. A few rules decide how columns are read:

  • Activity and Timestamp are required (concept:name and time:timestamp work too); Event is optional and becomes the event id.
  • A Case ID (or case:concept:name) column becomes a Case object type, so a conventional case-centric CSV imports with each case as an object — next to a Resource column, if it has one.
  • A column whose name starts with a capital letter, or with ot: (ot:order), is an object type. Separate several ids in one cell with |, and leave the cell empty when the event touches no object of that type.
  • A column named <object column>-<attribute> sets that attribute on the objects instead: Item-weight holding 1.2;0.4 gives i1 a weight of 1.2 and i2 one of 0.4 — values separated by ;, in the same order as the ids.
  • Every other column — price here — is an event attribute, so give attributes lowercase names: a column called Price would be read as an object type.