or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

conformance-checking.mdfiltering.mdindex.mdml-organizational.mdobject-centric.mdprocess-discovery.mdreading-writing.mdstatistics-analysis.mdutilities-conversion.mdvisualization.md

object-centric.mddocs/

0

# Object-Centric Operations

1

2

Specialized operations for Object-Centric Event Logs (OCEL) that handle multi-dimensional process data with objects, relationships, and complex event-object interactions. OCEL extends traditional process mining to scenarios with multiple interacting business objects.

3

4

## Capabilities

5

6

### Core OCEL Operations

7

8

Basic operations for extracting information from Object-Centric Event Logs.

9

10

```python { .api }

11

def ocel_get_object_types(ocel):

12

"""

13

Get list of object types present in the OCEL.

14

15

Parameters:

16

- ocel (OCEL): Object-centric event log

17

18

Returns:

19

List[str]: List of object type names

20

"""

21

22

def ocel_get_attribute_names(ocel):

23

"""

24

Get all attribute names from events and objects in OCEL.

25

26

Parameters:

27

- ocel (OCEL): Object-centric event log

28

29

Returns:

30

List[str]: List of attribute names

31

"""

32

33

def ocel_flattening(ocel, object_type):

34

"""

35

Flatten OCEL to traditional event log based on specific object type.

36

Creates a traditional case-activity-timestamp log from object lifecycle.

37

38

Parameters:

39

- ocel (OCEL): Object-centric event log

40

- object_type (str): Object type to use for flattening

41

42

Returns:

43

pd.DataFrame: Traditional event log format

44

"""

45

46

def ocel_object_type_activities(ocel):

47

"""

48

Get activities performed for each object type.

49

50

Parameters:

51

- ocel (OCEL): Object-centric event log

52

53

Returns:

54

Dict[str, Collection[str]]: Activities per object type

55

"""

56

57

def ocel_objects_ot_count(ocel):

58

"""

59

Get count of objects per object type.

60

61

Parameters:

62

- ocel (OCEL): Object-centric event log

63

64

Returns:

65

Dict[str, int]: Object counts per type

66

"""

67

```

68

69

### OCEL Analysis Functions

70

71

Analytical operations for understanding OCEL characteristics and patterns.

72

73

```python { .api }

74

def ocel_objects_interactions_summary(ocel):

75

"""

76

Get comprehensive summary of object interactions in OCEL.

77

Analyzes how different object types interact through events.

78

79

Parameters:

80

- ocel (OCEL): Object-centric event log

81

82

Returns:

83

Dict[str, Any]: Interaction summary including frequencies and patterns

84

"""

85

86

def ocel_temporal_summary(ocel):

87

"""

88

Get temporal summary showing time-based patterns in OCEL.

89

90

Parameters:

91

- ocel (OCEL): Object-centric event log

92

93

Returns:

94

Dict[str, Any]: Temporal patterns including event frequencies over time

95

"""

96

97

def ocel_objects_summary(ocel):

98

"""

99

Get comprehensive summary of objects in OCEL.

100

101

Parameters:

102

- ocel (OCEL): Object-centric event log

103

104

Returns:

105

Dict[str, Any]: Object statistics including lifecycle information

106

"""

107

```

108

109

### OCEL Discovery Algorithms

110

111

Discover process models from Object-Centric Event Logs using specialized algorithms.

112

113

```python { .api }

114

def discover_ocdfg(ocel, **kwargs):

115

"""

116

Discover Object-Centric Directly-Follows Graph.

117

Shows relationships between activities considering object interactions.

118

119

Parameters:

120

- ocel (OCEL): Object-centric event log

121

- **kwargs: Additional parameters for discovery algorithm

122

123

Returns:

124

Dict[str, Any]: Object-centric DFG structure with object type information

125

"""

126

127

def discover_oc_petri_net(ocel, **kwargs):

128

"""

129

Discover Object-Centric Petri Net from OCEL.

130

Creates Petri net that models object lifecycles and interactions.

131

132

Parameters:

133

- ocel (OCEL): Object-centric event log

134

- **kwargs: Additional parameters for discovery algorithm

135

136

Returns:

137

Tuple[PetriNet, Marking, Marking]: Object-centric Petri net model

138

"""

139

140

def discover_objects_graph(ocel, **kwargs):

141

"""

142

Discover object interaction graph showing object relationships.

143

144

Parameters:

145

- ocel (OCEL): Object-centric event log

146

- **kwargs: Additional parameters for graph construction

147

148

Returns:

149

Dict[str, Any]: Object interaction graph structure

150

"""

151

```

152

153

### OCEL Manipulation Functions

154

155

Transform and modify OCEL data for specific analysis needs.

156

157

```python { .api }

158

def sample_ocel_objects(ocel, num_objects, object_type=None):

159

"""

160

Sample OCEL by selecting specific number of objects.

161

162

Parameters:

163

- ocel (OCEL): Object-centric event log

164

- num_objects (int): Number of objects to sample

165

- object_type (Optional[str]): Specific object type to sample from

166

167

Returns:

168

OCEL: Sampled object-centric event log

169

"""

170

171

def sample_ocel_connected_components(ocel, num_cc):

172

"""

173

Sample OCEL by selecting connected components.

174

Maintains object relationships within components.

175

176

Parameters:

177

- ocel (OCEL): Object-centric event log

178

- num_cc (int): Number of connected components to sample

179

180

Returns:

181

OCEL: Sampled object-centric event log

182

"""

183

184

def ocel_drop_duplicates(ocel):

185

"""

186

Remove duplicate events from OCEL based on event attributes.

187

188

Parameters:

189

- ocel (OCEL): Object-centric event log

190

191

Returns:

192

OCEL: Cleaned object-centric event log

193

"""

194

195

def ocel_merge_duplicates(ocel):

196

"""

197

Merge duplicate events in OCEL by combining their attributes.

198

199

Parameters:

200

- ocel (OCEL): Object-centric event log

201

202

Returns:

203

OCEL: Merged object-centric event log

204

"""

205

206

def ocel_sort_by_additional_column(ocel, column):

207

"""

208

Sort OCEL events by additional column while preserving temporal order.

209

210

Parameters:

211

- ocel (OCEL): Object-centric event log

212

- column (str): Column name to sort by

213

214

Returns:

215

OCEL: Sorted object-centric event log

216

"""

217

218

def ocel_add_index_based_timedelta(ocel):

219

"""

220

Add index-based time delta to OCEL for synthetic temporal ordering.

221

222

Parameters:

223

- ocel (OCEL): Object-centric event log

224

225

Returns:

226

OCEL: Enhanced object-centric event log with time deltas

227

"""

228

```

229

230

### OCEL Enrichment Functions

231

232

Enrich OCEL with additional information about object relationships and lifecycles.

233

234

```python { .api }

235

def ocel_o2o_enrichment(ocel, **kwargs):

236

"""

237

Add object-to-object relationships to OCEL.

238

Discovers and adds relationships between objects based on event co-occurrence.

239

240

Parameters:

241

- ocel (OCEL): Object-centric event log

242

- **kwargs: Parameters for relationship discovery

243

244

Returns:

245

OCEL: Enriched OCEL with object relationships

246

"""

247

248

def ocel_e2o_lifecycle_enrichment(ocel, **kwargs):

249

"""

250

Add event-to-object lifecycle information to OCEL.

251

Enriches events with object lifecycle context.

252

253

Parameters:

254

- ocel (OCEL): Object-centric event log

255

- **kwargs: Parameters for lifecycle enrichment

256

257

Returns:

258

OCEL: Enriched OCEL with lifecycle information

259

"""

260

261

def cluster_equivalent_ocel(ocel, **kwargs):

262

"""

263

Cluster equivalent objects in OCEL based on behavior patterns.

264

Groups objects with similar lifecycles and interaction patterns.

265

266

Parameters:

267

- ocel (OCEL): Object-centric event log

268

- **kwargs: Parameters for clustering algorithm

269

270

Returns:

271

OCEL: OCEL with clustered object information

272

"""

273

```

274

275

## Usage Examples

276

277

### Basic OCEL Operations

278

279

```python

280

import pm4py

281

282

# Load OCEL

283

ocel = pm4py.read_ocel('ocel_data.csv', objects_path='objects.csv')

284

285

# Get basic information

286

object_types = pm4py.ocel_get_object_types(ocel)

287

print(f"Object types: {object_types}")

288

289

attributes = pm4py.ocel_get_attribute_names(ocel)

290

print(f"Attributes: {attributes}")

291

292

# Get object counts per type

293

object_counts = pm4py.ocel_objects_ot_count(ocel)

294

print(f"Object counts: {object_counts}")

295

296

# Get activities per object type

297

activities_per_type = pm4py.ocel_object_type_activities(ocel)

298

for obj_type, activities in activities_per_type.items():

299

print(f"{obj_type}: {list(activities)}")

300

```

301

302

### OCEL Analysis and Summaries

303

304

```python

305

import pm4py

306

307

# Get comprehensive summaries

308

objects_summary = pm4py.ocel_objects_summary(ocel)

309

print("Objects Summary:")

310

print(f" Total objects: {objects_summary['total_objects']}")

311

print(f" Average lifecycle length: {objects_summary['avg_lifecycle_length']}")

312

313

interactions_summary = pm4py.ocel_objects_interactions_summary(ocel)

314

print("Interactions Summary:")

315

for interaction, count in interactions_summary['interaction_counts'].items():

316

print(f" {interaction}: {count}")

317

318

temporal_summary = pm4py.ocel_temporal_summary(ocel)

319

print("Temporal Summary:")

320

print(f" Time span: {temporal_summary['time_span']}")

321

print(f" Peak activity period: {temporal_summary['peak_period']}")

322

```

323

324

### Flattening OCEL to Traditional Logs

325

326

```python

327

import pm4py

328

329

# Flatten OCEL for each object type

330

object_types = pm4py.ocel_get_object_types(ocel)

331

332

flattened_logs = {}

333

for obj_type in object_types:

334

flattened_log = pm4py.ocel_flattening(ocel, obj_type)

335

flattened_logs[obj_type] = flattened_log

336

337

print(f"Flattened log for {obj_type}:")

338

print(f" Cases: {flattened_log['case:concept:name'].nunique()}")

339

print(f" Events: {len(flattened_log)}")

340

print(f" Activities: {flattened_log['concept:name'].nunique()}")

341

342

# Apply traditional process mining to flattened logs

343

for obj_type, log in flattened_logs.items():

344

print(f"\nProcess discovery for {obj_type}:")

345

net, im, fm = pm4py.discover_petri_net_inductive(log)

346

fitness = pm4py.fitness_alignments(log, net, im, fm)

347

print(f" Fitness: {fitness['log_fitness']:.3f}")

348

```

349

350

### Object-Centric Discovery

351

352

```python

353

import pm4py

354

355

# Discover Object-Centric DFG

356

ocdfg = pm4py.discover_ocdfg(ocel)

357

print("OC-DFG discovered")

358

359

# Visualize OC-DFG

360

pm4py.view_ocdfg(ocdfg)

361

pm4py.save_vis_ocdfg(ocdfg, 'ocdfg.png')

362

363

# Discover Object-Centric Petri Net

364

ocpn = pm4py.discover_oc_petri_net(ocel)

365

print("OC Petri Net discovered")

366

367

# Visualize OC Petri Net

368

pm4py.view_ocpn(ocpn)

369

pm4py.save_vis_ocpn(ocpn, 'ocpn.png')

370

371

# Discover object interaction graph

372

obj_graph = pm4py.discover_objects_graph(ocel)

373

pm4py.view_object_graph(ocel)

374

pm4py.save_vis_object_graph(ocel, 'object_graph.png')

375

```

376

377

### OCEL Sampling and Manipulation

378

379

```python

380

import pm4py

381

382

# Sample OCEL by number of objects

383

sampled_ocel = pm4py.sample_ocel_objects(ocel, 100)

384

print(f"Sampled OCEL: {len(sampled_ocel.events)} events")

385

386

# Sample by specific object type

387

order_sample = pm4py.sample_ocel_objects(ocel, 50, object_type='Order')

388

print(f"Order sample: {len(order_sample.events)} events")

389

390

# Sample by connected components

391

cc_sample = pm4py.sample_ocel_connected_components(ocel, 10)

392

print(f"Connected component sample: {len(cc_sample.events)} events")

393

394

# Clean OCEL data

395

clean_ocel = pm4py.ocel_drop_duplicates(ocel)

396

print(f"After removing duplicates: {len(clean_ocel.events)} events")

397

398

merged_ocel = pm4py.ocel_merge_duplicates(ocel)

399

print(f"After merging duplicates: {len(merged_ocel.events)} events")

400

```

401

402

### OCEL Enrichment

403

404

```python

405

import pm4py

406

407

# Add object-to-object relationships

408

enriched_ocel = pm4py.ocel_o2o_enrichment(

409

ocel,

410

min_support=0.1, # Minimum support for relationship

411

window_size=5 # Event window for relationship detection

412

)

413

print("Added object-to-object relationships")

414

415

# Add lifecycle enrichment

416

lifecycle_ocel = pm4py.ocel_e2o_lifecycle_enrichment(

417

ocel,

418

lifecycle_stages=['start', 'active', 'complete']

419

)

420

print("Added lifecycle information")

421

422

# Cluster equivalent objects

423

clustered_ocel = pm4py.cluster_equivalent_ocel(

424

ocel,

425

similarity_threshold=0.8,

426

clustering_method='kmeans'

427

)

428

print("Clustered equivalent objects")

429

```

430

431

### OCEL Filtering and Analysis Pipeline

432

433

```python

434

import pm4py

435

436

def analyze_ocel_object_type(ocel, object_type):

437

"""Complete analysis pipeline for specific object type."""

438

439

print(f"Analyzing object type: {object_type}")

440

441

# Filter OCEL to focus on specific object type

442

filtered_ocel = pm4py.filter_ocel_object_types(ocel, [object_type])

443

444

# Get basic statistics

445

obj_count = pm4py.ocel_objects_ot_count(filtered_ocel)[object_type]

446

activities = pm4py.ocel_object_type_activities(filtered_ocel)[object_type]

447

448

print(f" Objects: {obj_count}")

449

print(f" Activities: {len(activities)} - {list(activities)}")

450

451

# Flatten for traditional analysis

452

flattened = pm4py.ocel_flattening(filtered_ocel, object_type)

453

454

# Discover process model

455

net, im, fm = pm4py.discover_petri_net_inductive(flattened)

456

457

# Measure quality

458

fitness = pm4py.fitness_alignments(flattened, net, im, fm)

459

precision = pm4py.precision_alignments(flattened, net, im, fm)

460

461

print(f" Model Quality - Fitness: {fitness['log_fitness']:.3f}, Precision: {precision:.3f}")

462

463

# Create visualizations

464

pm4py.save_vis_petri_net(net, im, fm, f'{object_type}_petri_net.png')

465

466

# Discover OC-DFG for this subset

467

ocdfg = pm4py.discover_ocdfg(filtered_ocel)

468

pm4py.save_vis_ocdfg(ocdfg, f'{object_type}_ocdfg.png')

469

470

return {

471

'object_count': obj_count,

472

'activities': list(activities),

473

'fitness': fitness['log_fitness'],

474

'precision': precision,

475

'flattened_log': flattened,

476

'petri_net': (net, im, fm)

477

}

478

479

# Analyze each object type

480

object_types = pm4py.ocel_get_object_types(ocel)

481

results = {}

482

483

for obj_type in object_types:

484

results[obj_type] = analyze_ocel_object_type(ocel, obj_type)

485

486

# Compare results

487

print("\nComparison across object types:")

488

for obj_type, result in results.items():

489

print(f"{obj_type}: {result['object_count']} objects, "

490

f"fitness={result['fitness']:.3f}, "

491

f"precision={result['precision']:.3f}")

492

```

493

494

### Cross-Object Type Analysis

495

496

```python

497

import pm4py

498

499

def analyze_object_interactions(ocel):

500

"""Analyze interactions between different object types."""

501

502

interactions = pm4py.ocel_objects_interactions_summary(ocel)

503

504

print("Object Type Interactions:")

505

for interaction, metrics in interactions['interaction_matrix'].items():

506

obj_type1, obj_type2 = interaction

507

frequency = metrics['frequency']

508

strength = metrics['strength']

509

print(f" {obj_type1} <-> {obj_type2}: {frequency} interactions (strength: {strength:.3f})")

510

511

# Discover object graph

512

obj_graph = pm4py.discover_objects_graph(ocel)

513

pm4py.save_vis_object_graph(ocel, 'full_object_graph.png')

514

515

# Create connected component analysis

516

object_types = pm4py.ocel_get_object_types(ocel)

517

518

for obj_type in object_types:

519

# Filter by connected components containing this object type

520

cc_filtered = pm4py.filter_ocel_cc_otype(ocel, obj_type)

521

522

# Analyze component characteristics

523

summary = pm4py.ocel_objects_summary(cc_filtered)

524

525

print(f"Connected components with {obj_type}:")

526

print(f" Components: {summary['num_components']}")

527

print(f" Avg component size: {summary['avg_component_size']:.1f}")

528

529

# Run interaction analysis

530

analyze_object_interactions(ocel)

531

```

532

533

### OCEL Data Quality Assessment

534

535

```python

536

import pm4py

537

538

def assess_ocel_quality(ocel):

539

"""Comprehensive OCEL data quality assessment."""

540

541

print("OCEL Data Quality Assessment")

542

print("="*40)

543

544

# Basic statistics

545

object_types = pm4py.ocel_get_object_types(ocel)

546

object_counts = pm4py.ocel_objects_ot_count(ocel)

547

548

print(f"Object Types: {len(object_types)}")

549

for obj_type in object_types:

550

count = object_counts[obj_type]

551

activities = pm4py.ocel_object_type_activities(ocel)[obj_type]

552

print(f" {obj_type}: {count} objects, {len(activities)} activities")

553

554

# Temporal quality

555

temporal_summary = pm4py.ocel_temporal_summary(ocel)

556

print(f"\nTemporal Span: {temporal_summary['time_span']}")

557

print(f"Event Rate: {temporal_summary['avg_events_per_day']:.1f} events/day")

558

559

# Object interactions

560

interactions = pm4py.ocel_objects_interactions_summary(ocel)

561

print(f"\nObject Interactions: {interactions['total_interactions']}")

562

print(f"Interaction Density: {interactions['interaction_density']:.3f}")

563

564

# Check for duplicates

565

original_events = len(ocel.events)

566

deduplicated = pm4py.ocel_drop_duplicates(ocel)

567

duplicate_events = original_events - len(deduplicated.events)

568

569

print(f"\nData Quality:")

570

print(f" Total Events: {original_events}")

571

print(f" Duplicate Events: {duplicate_events} ({100*duplicate_events/original_events:.1f}%)")

572

573

# Completeness check

574

attributes = pm4py.ocel_get_attribute_names(ocel)

575

print(f" Attributes: {len(attributes)}")

576

577

return {

578

'object_types': len(object_types),

579

'total_objects': sum(object_counts.values()),

580

'total_events': original_events,

581

'duplicate_rate': duplicate_events/original_events,

582

'interaction_density': interactions['interaction_density']

583

}

584

585

# Assess quality

586

quality_metrics = assess_ocel_quality(ocel)

587

```