From 1ba8095cb2343adb8c16a012f8f5932259d470f3 Mon Sep 17 00:00:00 2001 From: Kurt Wilson Date: Sat, 22 Mar 2025 19:46:27 -0400 Subject: [PATCH] add analysis script for the demo experiment --- analysis/analysis.ipynb | 442 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 442 insertions(+) create mode 100644 analysis/analysis.ipynb diff --git a/analysis/analysis.ipynb b/analysis/analysis.ipynb new file mode 100644 index 0000000..131dea5 --- /dev/null +++ b/analysis/analysis.ipynb @@ -0,0 +1,442 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import json\n", + "\n", + "import matplotlib.pyplot as plt\n", + "from dataclasses import dataclass\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [], + "source": [ + "this_dir = os.path.dirname(os.path.abspath(''))\n", + "# results is in \"../results\"\n", + "results_dir = os.path.join(this_dir, \"results\")" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [], + "source": [ + "experiment_folder = \"casestudy_example\"\n", + "experiment_name = \"cs_example_edf\"\n", + "\n", + "experiment_file = os.path.join(results_dir, experiment_folder, experiment_name + \".json\")\n", + "if not os.path.exists(experiment_file):\n", + " print(\"Experiment file not found: \", experiment_file)" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [], + "source": [ + "with open(experiment_file) as f:\n", + " experiment_data_raw = json.load(f)" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7146948, 'on_time': 1, 'time_diff': -73, 'periods_late': 0, 'thread_id': 1}, 'time': 0.000127}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7146948, 'on_time': 1, 'time_diff': 0, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0002}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7147048, 'on_time': 1, 'time_diff': -71, 'periods_late': 0, 'thread_id': 1}, 'time': 0.000229}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7147148, 'on_time': 1, 'time_diff': -157, 'periods_late': 0, 'thread_id': 0}, 'time': 0.000243}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7147048, 'on_time': 1, 'time_diff': 0, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0003}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7147148, 'on_time': 1, 'time_diff': -57, 'periods_late': 0, 'thread_id': 1}, 'time': 0.000343}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7147248, 'on_time': 1, 'time_diff': -100, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0004}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7147248, 'on_time': 1, 'time_diff': -57, 'periods_late': 0, 'thread_id': 0}, 'time': 0.000443}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7147348, 'on_time': 1, 'time_diff': -100, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0005}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7147348, 'on_time': 1, 'time_diff': -57, 'periods_late': 0, 'thread_id': 1}, 'time': 0.000543}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7147448, 'on_time': 1, 'time_diff': -100, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0006}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7147448, 'on_time': 1, 'time_diff': -57, 'periods_late': 0, 'thread_id': 0}, 'time': 0.000643}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7147548, 'on_time': 1, 'time_diff': -100, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0007}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7147648, 'on_time': 1, 'time_diff': -157, 'periods_late': 0, 'thread_id': 1}, 'time': 0.000743}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7147548, 'on_time': 1, 'time_diff': 0, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0008}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7147648, 'on_time': 1, 'time_diff': -57, 'periods_late': 0, 'thread_id': 0}, 'time': 0.000843}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7147748, 'on_time': 1, 'time_diff': -100, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0009}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7147848, 'on_time': 1, 'time_diff': -157, 'periods_late': 0, 'thread_id': 0}, 'time': 0.000943}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7147748, 'on_time': 1, 'time_diff': 0, 'periods_late': 0, 'thread_id': 1}, 'time': 0.001}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7147948, 'on_time': 1, 'time_diff': -157, 'periods_late': 0, 'thread_id': 0}, 'time': 0.001043}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7147848, 'on_time': 1, 'time_diff': 0, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0011}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7147948, 'on_time': 1, 'time_diff': -70, 'periods_late': 0, 'thread_id': 1}, 'time': 0.00113}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7148048, 'on_time': 1, 'time_diff': -157, 'periods_late': 0, 'thread_id': 0}, 'time': 0.001143}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7148048, 'on_time': 1, 'time_diff': -100, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0012}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7148148, 'on_time': 1, 'time_diff': -157, 'periods_late': 0, 'thread_id': 1}, 'time': 0.001243}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7148148, 'on_time': 1, 'time_diff': -100, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0013}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7148248, 'on_time': 1, 'time_diff': -157, 'periods_late': 0, 'thread_id': 1}, 'time': 0.001343}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7148248, 'on_time': 1, 'time_diff': -100, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0014}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7148348, 'on_time': 1, 'time_diff': -157, 'periods_late': 0, 'thread_id': 0}, 'time': 0.001443}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7148348, 'on_time': 1, 'time_diff': -100, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0015}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7148448, 'on_time': 1, 'time_diff': -157, 'periods_late': 0, 'thread_id': 0}, 'time': 0.001543}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7148448, 'on_time': 1, 'time_diff': -100, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0016}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7148548, 'on_time': 1, 'time_diff': -170, 'periods_late': 0, 'thread_id': 0}, 'time': 0.00163}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7148648, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 1}, 'time': 0.001643}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7148548, 'on_time': 1, 'time_diff': -100, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0017}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7148648, 'on_time': 1, 'time_diff': -157, 'periods_late': 0, 'thread_id': 0}, 'time': 0.001743}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7148748, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0018}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7148848, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 1}, 'time': 0.001843}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7148748, 'on_time': 1, 'time_diff': -100, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0019}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7148948, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 1}, 'time': 0.001943}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7148848, 'on_time': 1, 'time_diff': -100, 'periods_late': 0, 'thread_id': 0}, 'time': 0.002}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7148948, 'on_time': 1, 'time_diff': -157, 'periods_late': 0, 'thread_id': 1}, 'time': 0.002043}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7149048, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0021}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7149048, 'on_time': 1, 'time_diff': -157, 'periods_late': 0, 'thread_id': 0}, 'time': 0.002143}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7149148, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0022}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7149148, 'on_time': 1, 'time_diff': -157, 'periods_late': 0, 'thread_id': 1}, 'time': 0.002243}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7149248, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0023}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7149248, 'on_time': 1, 'time_diff': -157, 'periods_late': 0, 'thread_id': 0}, 'time': 0.002343}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7149348, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0024}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7149348, 'on_time': 1, 'time_diff': -170, 'periods_late': 0, 'thread_id': 1}, 'time': 0.00243}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7149448, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 0}, 'time': 0.002443}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7149448, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0025}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7149548, 'on_time': 1, 'time_diff': -256, 'periods_late': 0, 'thread_id': 1}, 'time': 0.002544}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7149548, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0026}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7149648, 'on_time': 1, 'time_diff': -259, 'periods_late': 0, 'thread_id': 1}, 'time': 0.002641}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7149648, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0027}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7149748, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 1}, 'time': 0.002743}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7149748, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0028}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7149848, 'on_time': 1, 'time_diff': -256, 'periods_late': 0, 'thread_id': 1}, 'time': 0.002844}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7149848, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0029}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7149948, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 0}, 'time': 0.002943}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7149948, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 1}, 'time': 0.003}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7150048, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 1}, 'time': 0.003043}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7150048, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0031}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7150148, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 0}, 'time': 0.003143}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7150148, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0032}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7150248, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 0}, 'time': 0.003243}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7150248, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0033}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7150348, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 0}, 'time': 0.003343}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7150348, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0034}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7150448, 'on_time': 1, 'time_diff': -270, 'periods_late': 0, 'thread_id': 0}, 'time': 0.00343}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7150548, 'on_time': 1, 'time_diff': -357, 'periods_late': 0, 'thread_id': 1}, 'time': 0.003443}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7150448, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0035}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7150548, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 0}, 'time': 0.003543}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7150648, 'on_time': 1, 'time_diff': -300, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0036}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7150748, 'on_time': 1, 'time_diff': -357, 'periods_late': 0, 'thread_id': 0}, 'time': 0.003643}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7150648, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0037}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7150748, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 1}, 'time': 0.003743}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7150848, 'on_time': 1, 'time_diff': -300, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0038}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7150948, 'on_time': 1, 'time_diff': -358, 'periods_late': 0, 'thread_id': 1}, 'time': 0.003842}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7150848, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0039}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7150948, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 0}, 'time': 0.003943}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7151048, 'on_time': 1, 'time_diff': -300, 'periods_late': 0, 'thread_id': 1}, 'time': 0.004}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7151148, 'on_time': 1, 'time_diff': -356, 'periods_late': 0, 'thread_id': 1}, 'time': 0.004044}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7151048, 'on_time': 1, 'time_diff': -200, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0041}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7151148, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 0}, 'time': 0.004143}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7151248, 'on_time': 1, 'time_diff': -300, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0042}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7151248, 'on_time': 1, 'time_diff': -257, 'periods_late': 0, 'thread_id': 0}, 'time': 0.004243}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7151348, 'on_time': 1, 'time_diff': -300, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0043}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7151348, 'on_time': 1, 'time_diff': -270, 'periods_late': 0, 'thread_id': 1}, 'time': 0.00433}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7151448, 'on_time': 1, 'time_diff': -357, 'periods_late': 0, 'thread_id': 0}, 'time': 0.004343}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7151448, 'on_time': 1, 'time_diff': -300, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0044}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7151548, 'on_time': 1, 'time_diff': -370, 'periods_late': 0, 'thread_id': 0}, 'time': 0.00443}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7151648, 'on_time': 1, 'time_diff': -457, 'periods_late': 0, 'thread_id': 1}, 'time': 0.004443}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7151548, 'on_time': 1, 'time_diff': -300, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0045}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7151648, 'on_time': 1, 'time_diff': -357, 'periods_late': 0, 'thread_id': 0}, 'time': 0.004543}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7151748, 'on_time': 1, 'time_diff': -400, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0046}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7151748, 'on_time': 1, 'time_diff': -357, 'periods_late': 0, 'thread_id': 1}, 'time': 0.004643}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7151848, 'on_time': 1, 'time_diff': -400, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0047}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7151848, 'on_time': 1, 'time_diff': -370, 'periods_late': 0, 'thread_id': 1}, 'time': 0.00473}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7151948, 'on_time': 1, 'time_diff': -457, 'periods_late': 0, 'thread_id': 0}, 'time': 0.004743}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7151948, 'on_time': 1, 'time_diff': -400, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0048}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7152048, 'on_time': 1, 'time_diff': -457, 'periods_late': 0, 'thread_id': 0}, 'time': 0.004843}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7152048, 'on_time': 1, 'time_diff': -400, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0049}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7152148, 'on_time': 1, 'time_diff': -457, 'periods_late': 0, 'thread_id': 0}, 'time': 0.004943}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7152148, 'on_time': 1, 'time_diff': -400, 'periods_late': 0, 'thread_id': 1}, 'time': 0.005}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7152248, 'on_time': 1, 'time_diff': -457, 'periods_late': 0, 'thread_id': 1}, 'time': 0.005043}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7152248, 'on_time': 1, 'time_diff': -400, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0051}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7152348, 'on_time': 1, 'time_diff': -457, 'periods_late': 0, 'thread_id': 0}, 'time': 0.005143}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7152348, 'on_time': 1, 'time_diff': -400, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0052}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7152448, 'on_time': 1, 'time_diff': -473, 'periods_late': 0, 'thread_id': 1}, 'time': 0.005227}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7152448, 'on_time': 1, 'time_diff': -400, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0053}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7152548, 'on_time': 1, 'time_diff': -456, 'periods_late': 0, 'thread_id': 0}, 'time': 0.005344}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7152548, 'on_time': 1, 'time_diff': -456, 'periods_late': 0, 'thread_id': 1}, 'time': 0.005344}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7152648, 'on_time': 1, 'time_diff': -457, 'periods_late': 0, 'thread_id': 1}, 'time': 0.005443}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7152648, 'on_time': 1, 'time_diff': -400, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0055}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7152748, 'on_time': 1, 'time_diff': -457, 'periods_late': 0, 'thread_id': 0}, 'time': 0.005543}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7152748, 'on_time': 1, 'time_diff': -400, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0056}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7152848, 'on_time': 1, 'time_diff': -457, 'periods_late': 0, 'thread_id': 1}, 'time': 0.005643}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7152848, 'on_time': 1, 'time_diff': -400, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0057}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7152948, 'on_time': 1, 'time_diff': -457, 'periods_late': 0, 'thread_id': 0}, 'time': 0.005743}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7152948, 'on_time': 1, 'time_diff': -400, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0058}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7153048, 'on_time': 1, 'time_diff': -457, 'periods_late': 0, 'thread_id': 0}, 'time': 0.005843}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7153048, 'on_time': 1, 'time_diff': -400, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0059}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7153148, 'on_time': 1, 'time_diff': -470, 'periods_late': 0, 'thread_id': 0}, 'time': 0.00593}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7153248, 'on_time': 1, 'time_diff': -557, 'periods_late': 0, 'thread_id': 1}, 'time': 0.005943}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7153148, 'on_time': 1, 'time_diff': -400, 'periods_late': 0, 'thread_id': 0}, 'time': 0.006}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7153248, 'on_time': 1, 'time_diff': -470, 'periods_late': 0, 'thread_id': 0}, 'time': 0.00603}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7153348, 'on_time': 1, 'time_diff': -557, 'periods_late': 0, 'thread_id': 1}, 'time': 0.006043}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7153348, 'on_time': 1, 'time_diff': -500, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0061}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7153448, 'on_time': 1, 'time_diff': -557, 'periods_late': 0, 'thread_id': 0}, 'time': 0.006143}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7153448, 'on_time': 1, 'time_diff': -500, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0062}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7153548, 'on_time': 1, 'time_diff': -563, 'periods_late': 0, 'thread_id': 1}, 'time': 0.006237}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7153548, 'on_time': 1, 'time_diff': -500, 'periods_late': 0, 'thread_id': 0}, 'time': 0.0063}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7153648, 'on_time': 1, 'time_diff': -560, 'periods_late': 0, 'thread_id': 0}, 'time': 0.00634}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7153648, 'on_time': 1, 'time_diff': -500, 'periods_late': 0, 'thread_id': 1}, 'time': 0.0064}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7153748, 'on_time': 1, 'time_diff': -557, 'periods_late': 0, 'thread_id': 1}, 'time': 0.006443}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7153748, 'on_time': 1, 'time_diff': -504, 'periods_late': 0, 'thread_id': 0}, 'time': 0.006496}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 0, 'deadline': 7146848}, 'time': 0.0}\n", + "Record: {'entry': {'operation': 'next_deadline', 'chain_id': 1, 'deadline': 7146848}, 'time': 0.0}\n", + "Number of records: 1542\n", + "First record: {'entry': {'operation': 'start_work', 'chain': 0, 'node': 'node_0', 'count': 500, 'next_release_us': 99910}, 'time': 0.0001}\n", + "Operation types: ['end_work', 'next_deadline', 'get_next_executable', 'wait_for_work', 'start_work']\n" + ] + } + ], + "source": [ + "def pre_process_data(data):\n", + " for record in data:\n", + " record[\"time\"] = int(record[\"time\"])\n", + "\n", + " min_time = min([record[\"time\"] for record in data])\n", + " for record in data:\n", + " record[\"time\"] -= min_time\n", + " record[\"time\"] /= (1000 * 1000)\n", + "\n", + " if record[\"entry\"][\"operation\"] == \"next_deadline\":\n", + " print(\"Record: \", record)\n", + " record[\"entry\"][\"deadline\"] = int(record[\"entry\"][\"deadline\"])\n", + " record[\"entry\"][\"deadline\"] -= min_time\n", + " record[\"entry\"][\"deadline\"] /= (1000 * 1000)\n", + "\n", + " # data = sorted(data, key=lambda x: x[\"time\"])\n", + " return data\n", + "\n", + "experiment_data = pre_process_data(experiment_data_raw)\n", + "\n", + "print(\"Number of records: \", len(experiment_data))\n", + "print(\"First record: \", experiment_data[0])\n", + "operation_types = list(set([record[\"entry\"][\"operation\"] for record in experiment_data]))\n", + "print(\"Operation types: \", operation_types)" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [], + "source": [ + "@dataclass\n", + "class Record:\n", + " start_time: float\n", + " end_time: float\n", + " node_name: str\n", + "\n", + "@dataclass\n", + "class RecordLine:\n", + " node_name: str\n", + " count: int\n", + "\n", + " def __eq__(self, other):\n", + " return self.node_name == other.node_name and self.count == other.count\n", + "\n", + " def __hash__(self):\n", + " return hash((self.node_name, self.count))\n", + "\n", + "def get_records(data) -> list[Record]:\n", + " # used to match start_work and end_work records\n", + " current_records: dict[RecordLine, Record] = {}\n", + " records = []\n", + " for record in data:\n", + " if record[\"entry\"][\"operation\"] == \"start_work\":\n", + " current_record = Record(start_time=record[\"time\"], node_name=record[\"entry\"][\"node\"], end_time=None)\n", + " current_record_line = RecordLine(node_name=record[\"entry\"][\"node\"], count=record[\"entry\"][\"count\"])\n", + " if current_record_line in current_records:\n", + " raise Exception(\"Overlapping records\")\n", + " current_records[current_record_line] = current_record\n", + " elif record[\"entry\"][\"operation\"] == \"end_work\":\n", + " current_record_line = RecordLine(node_name=record[\"entry\"][\"node\"], count=record[\"entry\"][\"count\"])\n", + " if current_record_line not in current_records:\n", + " raise Exception(\"No start record\")\n", + " current_record = current_records[current_record_line]\n", + " current_record.end_time = record[\"time\"]\n", + " records.append(current_record)\n", + " del current_records[current_record_line]\n", + " return records\n", + "\n", + "records = get_records(experiment_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of nodes: 4\n" + ] + } + ], + "source": [ + "num_nodes = len(set([record.node_name for record in records]))\n", + "print(\"Number of nodes: \", num_nodes)" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "ea1129c959df4732a9cb712543ecf881", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "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xYwZMw45Nnjw4F6eDQBAcTkhA7C8vDzKy8sLPQ0AgKJ0Qr4EDABA9wQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgRgH5dlfX/scIpprtbfu2PFNh/r792xwymWuebrY3g4xbL+fI2RXwIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAwo9AbqXy0VkWfdjEYce72tjxTYf6y+esWKbj/X37lixzae7sXx9nc7HXPvSWHfj9AxnAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQAS02cCsL6+Pi666KJCTwMAoM/rMwHY095///24/vrro6ysLMrKyuL666+PX/ziF4WeFgBA3iUbgL/7u78bW7dujWeeeSaeeeaZ2Lp1a1x//fWFnhYAQN7lJQCnTJkSCxYsiMWLF0d5eXmMGDEi6uvrO8dbWlri6quvjmHDhkVpaWnMmDEj3nnnnS6PsXLlyqioqIjhw4fHnDlzYt++fQc9z5o1a6K6ujoGDRoUY8aMifvvv/+I5tfU1BTPPPNMPPTQQ1FXVxd1dXWxevXq+Md//Md47bXXjmvtAADFLm9nANeuXRtDhw6NTZs2xb333ht33313NDY2RpZlcc0118SePXtiw4YN0djYGM3NzTFz5szO+z722GOxdOnSWL58eWzZsiUqKysPirvVq1fHHXfcEcuXL4+mpqZoaGiIO++8M9auXXvYuf34xz+OsrKymDBhQudtl156aZSVlcWLL77Yc5sAAFCEBuTrgWtqamLp0qUREXHuuefGt771rfjBD34QERGvvPJKvPnmm1FVVRUREY888kicf/758ZOf/CQuueSSWLVqVdx4440x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j1NHR0fs2rUrhg8fHrlc7qju29bWFlVVVbFz584oLS3N0wz7LvvTPXvTPXvTPXvTPXvTvRN1b7Isi71798bpp58e/fql+dNwzgAeh379+sWZZ555XI9RWlp6Qv2h6mn2p3v2pnv2pnv2pnv2pnsn4t6keuZvvzSzFwAgYQIQACAxArBASkpKYunSpVFSUlLoqRQl+9M9e9M9e9M9e9M9e9M9e3Pi8iYQAIDEOAMIAJAYAQgAkBgBCACQGAEIAJAYAXiM7r///hg5cmQMGjQoxo8fHz/60Y8+8fgNGzbE+PHjY9CgQTFq1Kj467/+64OOefzxx2Ps2LFRUlISY8eOjSeffPK4n7cQCrE3P/zhD+O3fuu34vTTT49cLhdPPfVUTy6pRxVif1asWBGXXHJJDB8+PE477bS45ppr4rXXXuvRdfWEQuzNAw88EDU1NZ2/6Lauri7++Z//uUfX1RMK9TVnvxUrVkQul4tbbrnleJfS4wqxN/X19ZHL5bpcRowY0aPr6gmF+rz5+c9/Hr/3e78Xn/rUp2LIkCFx0UUXxUsvvdRj66IHZBy1Rx99NBs4cGC2evXqbPv27dnChQuzoUOHZm+99dYhj9+xY0c2ZMiQbOHChdn27duz1atXZwMHDsz+/u//vvOYF198Mevfv3/W0NCQNTU1ZQ0NDdmAAQOyjRs3HvPzFkKh9ub73/9+dscdd2SPP/54FhHZk08+me+lHpNC7c9VV12VrVmzJnv11VezrVu3Zp/73Oeys846K/uf//mfvK/5SBVqb55++unsn/7pn7LXXnste+2117KvfvWr2cCBA7NXX30172s+UoXam/02b96cffrTn85qamqyhQsX5muZx6RQe7N06dLs/PPPz/7rv/6r87J79+68r/doFGpv9uzZk5199tnZ7//+72ebNm3K3nzzzey5557L3njjjbyvmSMnAI/BZz/72WzevHldbhszZkx22223HfL4xYsXZ2PGjOly2x/+4R9ml156aef1GTNmZNOmTetyzFVXXZV96UtfOubnLYRC7c2BijkAi2F/sizLdu/enUVEtmHDhqNdQt4Uy95kWZadcsop2UMPPXQ008+rQu7N3r17s3PPPTdrbGzMJk+eXHQBWKi9Wbp0aXbhhRce5+zzq1B7s2TJkmzSpEnHO33yzEvAR+mDDz6Il156Ka688sout1955ZXx4osvHvI+P/7xjw86/qqrrootW7bEr371q088Zv9jHsvz9rZC7U1fUUz709raGhER5eXlR72OfCiWvfnoo4/i0UcfjV/+8pdRV1d3rMvpUYXemz/6oz+Kz33uczF16tTjXUqPK/TevP7663H66afHyJEj40tf+lLs2LHjeJfUYwq5N08//XTU1tbGddddF6eddlpcfPHFsXr16p5YFj1IAB6l9957Lz766KOoqKjocntFRUW8/fbbh7zP22+/fcjjP/zww3jvvfc+8Zj9j3ksz9vbCrU3fUWx7E+WZbFo0aKYNGlSXHDBBce6nB5V6L356U9/GsOGDYuSkpKYN29ePPnkkzF27NjjXVaPKOTePProo/Hv//7vsWLFip5YSo8r5N5MmDAhvvvd78azzz4bq1evjrfffjsmTpwY//3f/90TSztuhdybHTt2xAMPPBDnnntuPPvsszFv3rxYsGBBfPe73+2JpdFDBhR6An1VLpfrcj3LsoNuO9zx//f2I3nMo33eQijU3vQVhd6fr3zlK/HKK6/Ev/7rvx7VvHtDofbmvPPOi61bt8YvfvGLePzxx2P27NmxYcOGoonAiN7fm507d8bChQtj/fr1MWjQoOOae74V4vNm+vTpnf8/bty4qKuri3POOSfWrl0bixYtOvpF5Ekh9qajoyNqa2ujoaEhIiIuvvji2LZtWzzwwANxww03HNtC6HHOAB6lU089Nfr373/Q36B279590N+K9hsxYsQhjx8wYEB86lOf+sRj9j/msTxvbyvU3vQVxbA/N998czz99NPx/PPPx5lnnnk8y+lRhd6bk046KUaPHh21tbWxYsWKuPDCC+Mv/uIvjndZPaJQe/PSSy/F7t27Y/z48TFgwIAYMGBAbNiwIf7yL/8yBgwYEB999FFPLfGYFfrz5kBDhw6NcePGxeuvv34sS+lxhdybysrKg/7yVF1dHS0tLce8HnqeADxKJ510UowfPz4aGxu73N7Y2BgTJ0485H3q6uoOOn79+vVRW1sbAwcO/MRj9j/msTxvbyvU3vQVhdyfLMviK1/5SjzxxBPxL//yLzFy5MieWFKPKbbPnSzLor29/WiXkReF2psrrrgifvrTn8bWrVs7L7W1tTFr1qzYunVr9O/fv6eWeMyK6fOmvb09mpqaorKy8liW0uMKuTe/8Ru/cdCvmfrP//zPOPvss495PeRBr73d5ASy/6313/nOd7Lt27dnt9xySzZ06NDsZz/7WZZlWXbbbbdl119/fefx+99af+utt2bbt2/PvvOd7xz01vp/+7d/y/r375+tXLkya2pqylauXNntr4Hp7nmLQaH2Zu/evdnLL7+cvfzyy1lEZH/+53+evfzyy0X1K3KyrHD7M3/+/KysrCx74YUXuvzaiv/93//tvcUfRqH25vbbb89++MMfZm+++Wb2yiuvZF/96lezfv36ZevXr++9xR9Gofbm/yrGdwEXam/++I//OHvhhReyHTt2ZBs3bsw+//nPZ8OHD/f1OPv41wYNGDAgW758efb6669n69aty4YMGZL9zd/8Te8tnsMSgMfor/7qr7Kzzz47O+mkk7LPfOYzXX6dxuzZs7PJkyd3Of6FF17ILr744uykk07KPv3pT2cPPPDAQY/5d3/3d9l5552XDRw4MBszZkz2+OOPH9XzFotC7M3zzz+fRcRBl9mzZ+djicelEPtzqL2JiGzNmjX5WOIxK8Te3HjjjZ3P+Wu/9mvZFVdcUVTxt1+hvuYcqBgDMMsKszczZ87MKisrs4EDB2ann356du2112bbtm3Ly/qOR6E+b/7hH/4hu+CCC7KSkpJszJgx2be//e0eXxvHJ5dl//8nPAEASIKfAQQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASMz/A2FKvAESEvRzAAAAAElFTkSuQmCC", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%matplotlib widget\n", + "\n", + "# swimlane plot\n", + "name_to_id = {name: i for i, name in enumerate(set([record.node_name for record in records]))}\n", + "fig, ax = plt.subplots()\n", + "for i, record in enumerate(records):\n", + " # ax.plot([record.start_time, record.end_time], [name_to_id[record.node_name], name_to_id[record.node_name]], label=record.node_name)\n", + " ax.broken_barh([(record.start_time, record.end_time - record.start_time)], (name_to_id[record.node_name] - 0.4, 0.8), facecolors='blue')\n", + "ax.set_yticks(range(num_nodes))\n", + "ax.set_yticklabels(name_to_id.keys())\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [], + "source": [ + "@dataclass\n", + "class Deadline:\n", + " chain_id: int\n", + " deadline: float\n", + " on_time: bool\n", + "\n", + "def get_deadlines(data) -> list[Deadline]:\n", + " deadlines = []\n", + " for record in data:\n", + " if record[\"entry\"][\"operation\"] == \"next_deadline\" and \"on_time\" in record[\"entry\"]:\n", + " deadlines.append(Deadline(chain_id=record[\"entry\"][\"chain_id\"], deadline=record[\"entry\"][\"deadline\"], on_time=record[\"entry\"][\"on_time\"]))\n", + " return deadlines\n", + "\n", + "deadlines = get_deadlines(experiment_data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d7a21561dee14bb3bb4b56b83e7a86af", + "version_major": 2, + "version_minor": 0 + }, + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAJtRJREFUeJzt3X901fV9+PFX+GH4GTC1QtCgoEyCkuKI0zCO4JGjcOwqx07ogSkeoCvYCso2UDyaVPmlrTtsOh1FD1DlHOumous2FZzQbRYUJ4dKMqaBCqdMwKHA2oHVfL5/+DWHlB+SkOQmvB+Pc+453B/v+3m/Pgnhyb0k5GVZlgUAAMlol+sNAADQsgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiOuR6A21ZbW1t7Nq1K7p37x55eXm53g4AcBKyLIuDBw9Gnz59ol27NF8LE4CnYNeuXVFcXJzrbQAAjbBz584499xzc72NnBCAp6B79+4R8fknUEFBQY53AwCcjAMHDkRxcXHdn+MpEoCn4Iu3fQsKCgQgALQxKf/zrTTf+AYASJgABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjP8L+HRQWxvx4Yef//qssyLatfvy+9rimlwfP5U9m7P1Ht+c5sz18VvDnDSNjEbbv39/FhHZ/v37c7uR3buzLOLzy+7dJ3dfW1yT6+Onsmdztt7jm9OcuT5+a5izCbSaP79zSFIDACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGALZBeXmfX47lq72Ov+5497WGNbk+fkusyfXxG7sm18c3Z9OuyfXxm3LNiaTw+7OlPjc4PQlAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxLSZAKysrIwhQ4bkehsAAG1emwnApvTLX/4ypkyZEv369YvOnTvHBRdcEBUVFfHJJ5/kemsAAM2uQ643kAv/+Z//GbW1tbFkyZK48MIL45133olvf/vb8etf/zp++MMf5np7AADNqlleARw5cmTMmDEjZs+eHYWFhdG7d++orKysu3/Hjh1x/fXXR7du3aKgoCDGjRsXu3fvrvccixYtil69ekX37t1jypQpcejQoaOOs2zZsigpKYlOnTrFwIED49FHHz2p/Y0ePTqWLVsW11xzTfTv3z++8Y1vxJ//+Z/Hc889d0pzAwC0Bc32FvCKFSuia9eusWHDhnjwwQfjvvvui9WrV0eWZTF27NjYt29frFu3LlavXh01NTUxfvz4urXPPPNMVFRUxPz582Pjxo1RVFR0VNwtXbo07r777pg/f35UV1fHggUL4p577okVK1Y0ar/79++PwsLCU5oZAKAtaLa3gEtLS6OioiIiIgYMGBCPPPJIvPrqqxERsXnz5ti+fXsUFxdHRMSTTz4ZF198cbz55ptx2WWXxeLFi2Py5MkxderUiIiYN29erFmzpt6rgPfff3889NBDccMNN0RERL9+/aKqqiqWLFkSkyZNatBea2pq4uGHH46HHnrohI87fPhwHD58uO76gQMHGnQcAIDWoNleASwtLa13vaioKPbs2RPV1dVRXFxcF38REYMGDYqePXtGdXV1RERUV1dHeXl5vfVHXt+7d2/s3LkzpkyZEt26dau7zJs3L2pqahq0z127dsXo0aPjxhtvrAvO41m4cGH06NGj7nLkDAAAbUWzvQLYsWPHetfz8vKitrY2siyLvLy8ox5/vNuPpba2NiI+fxv48ssvr3df+/btT3qPu3btiquuuirKy8vjRz/60Zc+/q677opZs2bVXT9w4IAIBADanBb/LuBBgwbFjh07YufOnXXxVFVVFfv374+SkpKIiCgpKYn169fHzTffXLdu/fr1db/u1atXnHPOObFt27aYOHFio/bxq1/9Kq666qoYOnRoLFu2LNq1+/IXQ/Pz8yM/P79RxwMAaC1aPABHjRoVpaWlMXHixFi8eHF8+umnceutt8aIESOirKwsIiJmzpwZkyZNirKyshg+fHisXLkytmzZEv379697nsrKypgxY0YUFBTEmDFj4vDhw7Fx48b46KOP6r1Kdyy7du2KkSNHRt++feOHP/xh7N27t+6+3r17N8/gAACtRIsHYF5eXqxatSpuu+22uPLKK6Ndu3YxevToePjhh+seM378+KipqYk5c+bEoUOH4pvf/GZMnz49Xn755brHTJ06Nbp06RI/+MEPYvbs2dG1a9cYPHhw3H777V+6h1deeSXee++9eO+99+Lcc8+td1+WZU02KwBAa9QsAbh27dqjblu1alXdr/v27RsvvPDCCZ9j7ty5MXfu3Hq3PfDAA/WuT5gwISZMmNDg/d1yyy1xyy23NHgdAMDpIMn/Cg4AIGWnZQAuWLCg3o+HOfIyZsyYXG8PACCnTsv/C3jatGkxbty4Y97XuXPnFt4NAEDrcloGYGFhof/WDQDgOE7Lt4ABADg+AQgAkBgBCACQGAEIAJAYAQgAkBgBCACQGAEIAJAYAQgAkBgBCACQGAEIAJAYAQgAkBgBCACQGAEIAJAYAQgAkBgBCACQGAEIAJAYAQgAkBgBCACQGAEIAJAYAQgAkJgOud4ADZdlx79v7+6G39ca1uT6+C2xJtfHb+yaXB/fnE27JtfHb8o1J5LC78+W+tzg9OQVQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIwFYsL69x959oXUutaehzfbVX0x6/JfbcmDU+NuY0Z9PNeaJZTqS1fmwas6aljs/pRwACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkRgACACRGAAIAJEYAAgAkps0EYGVlZQwZMiTX2wAAaPPaTAA2tfnz58ewYcOiS5cu0bNnz1xvBwCgxSQbgJ988knceOONMX369FxvBQCgRTVLAI4cOTJmzJgRs2fPjsLCwujdu3dUVlbW3b9jx464/vrro1u3blFQUBDjxo2L3bt313uORYsWRa9evaJ79+4xZcqUOHTo0FHHWbZsWZSUlESnTp1i4MCB8eijj570Hr///e/HHXfcEYMHD270nAAAbVGzvQK4YsWK6Nq1a2zYsCEefPDBuO+++2L16tWRZVmMHTs29u3bF+vWrYvVq1dHTU1NjB8/vm7tM888ExUVFTF//vzYuHFjFBUVHRV3S5cujbvvvjvmz58f1dXVsWDBgrjnnntixYoVzTVSHD58OA4cOFDvAgDQ1nRoricuLS2NioqKiIgYMGBAPPLII/Hqq69GRMTmzZtj+/btUVxcHBERTz75ZFx88cXx5ptvxmWXXRaLFy+OyZMnx9SpUyMiYt68ebFmzZp6rwLef//98dBDD8UNN9wQERH9+vWLqqqqWLJkSUyaNKlZZlq4cGF8//vfb5bnBgBoKc32CmBpaWm960VFRbFnz56orq6O4uLiuviLiBg0aFD07NkzqqurIyKiuro6ysvL660/8vrevXtj586dMWXKlOjWrVvdZd68eVFTU9NcI8Vdd90V+/fvr7vs3Lmz2Y4FANBcmu0VwI4dO9a7npeXF7W1tZFlWeTl5R31+OPdfiy1tbUR8fnbwJdffnm9+9q3b9/IHX+5/Pz8yM/Pb7bnBwBoCS3+XcCDBg2KHTt21Hv1rKqqKvbv3x8lJSUREVFSUhLr16+vt+7I67169Ypzzjkntm3bFhdeeGG9S79+/VpmEACANqrZXgE8nlGjRkVpaWlMnDgxFi9eHJ9++mnceuutMWLEiCgrK4uIiJkzZ8akSZOirKwshg8fHitXrowtW7ZE//79656nsrIyZsyYEQUFBTFmzJg4fPhwbNy4MT766KOYNWvWl+5jx44dsW/fvtixY0d89tlnsWnTpoiIuPDCC6Nbt27NMjsAQGvQ4gGYl5cXq1atittuuy2uvPLKaNeuXYwePToefvjhuseMHz8+ampqYs6cOXHo0KH45je/GdOnT4+XX3657jFTp06NLl26xA9+8IOYPXt2dO3aNQYPHhy33377Se3j3nvvrfcdw5deemlERLz22msxcuTIJpkVAKA1apYAXLt27VG3rVq1qu7Xffv2jRdeeOGEzzF37tyYO3duvdseeOCBetcnTJgQEyZMaNQely9fHsuXL2/UWgCAtizZ/wkEACBVp2UALliwoN6PhznyMmbMmFxvDwAgp1r83wC2hGnTpsW4ceOOeV/nzp1beDcAAK3LaRmAhYWFUVhYmOttAAC0SqflW8AAAByfAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwAbMWyrHH3n2hdS61p6HPt3d20x2+JPTdmjY+NOc3ZdHOeaJYTaa0fm8asaanjc/oRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYBtUF7e55dj+Wqv46873n2tYU2uj98Sa3J9/MauyfXxzdm0a3J9/KZccyIp/P5sqc8NTk8CEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDFtJgArKytjyJAhud4GAECb12YCsKl99NFHcdNNN0WPHj2iR48ecdNNN8XHH3+c620BADS7ZANwwoQJsWnTpnjppZfipZdeik2bNsVNN92U620BADS7ZgnAkSNHxowZM2L27NlRWFgYvXv3jsrKyrr7d+zYEddff31069YtCgoKYty4cbF79+56z7Fo0aLo1atXdO/ePaZMmRKHDh066jjLli2LkpKS6NSpUwwcODAeffTRk9pfdXV1vPTSS/H4449HeXl5lJeXx9KlS+OnP/1pbN269ZRmBwBo7ZrtFcAVK1ZE165dY8OGDfHggw/GfffdF6tXr44sy2Ls2LGxb9++WLduXaxevTpqampi/PjxdWufeeaZqKioiPnz58fGjRujqKjoqLhbunRp3H333TF//vyorq6OBQsWxD333BMrVqz40r39/Oc/jx49esTll19ed9sVV1wRPXr0iNdff/246w4fPhwHDhyodwEAaGs6NNcTl5aWRkVFRUREDBgwIB555JF49dVXIyJi8+bNsX379iguLo6IiCeffDIuvvjiePPNN+Oyyy6LxYsXx+TJk2Pq1KkRETFv3rxYs2ZNvVcB77///njooYfihhtuiIiIfv36RVVVVSxZsiQmTZp0wr198MEHcfbZZx91+9lnnx0ffPDBcdctXLgwvv/97zfgLAAAtD7N9gpgaWlpvetFRUWxZ8+eqK6ujuLi4rr4i4gYNGhQ9OzZM6qrqyPi87doy8vL660/8vrevXtj586dMWXKlOjWrVvdZd68eVFTU3NS+8vLyzvqtizLjnn7F+66667Yv39/3WXnzp0ndSwAgNak2V4B7NixY73reXl5UVtbe9zI+rL4OlJtbW1EfP428JFv40ZEtG/f/kvX9+7d+6h/cxjxeVj26tXruOvy8/MjPz//pPYIANBatfh3AQ8aNCh27NhR79Wzqqqq2L9/f5SUlERERElJSaxfv77euiOv9+rVK84555zYtm1bXHjhhfUu/fr1+9I9lJeXx/79++ONN96ou23Dhg2xf//+GDZs2KmOCADQqjXbK4DHM2rUqCgtLY2JEyfG4sWL49NPP41bb701RowYEWVlZRERMXPmzJg0aVKUlZXF8OHDY+XKlbFly5bo379/3fNUVlbGjBkzoqCgIMaMGROHDx+OjRs3xkcffRSzZs064R5KSkpi9OjR8e1vfzuWLFkSERF/+qd/Gl//+tfjoosuar7hAQBagRZ/BTAvLy9WrVoVZ555Zlx55ZUxatSo6N+/f/zkJz+pe8z48ePj3nvvjTlz5sTQoUPj/fffj+nTp9d7nqlTp8bjjz8ey5cvj8GDB8eIESNi+fLlJ/UKYETEypUrY/DgwXHNNdfENddcE6WlpfHkk0826awAAK1Rs7wCuHbt2qNuW7VqVd2v+/btGy+88MIJn2Pu3Lkxd+7cerc98MAD9a5PmDAhJkyY0Kg9FhYWxlNPPdWotQAAbVmy/xMIAECqTssAXLBgQb0fD3PkZcyYMbneHgBATrX4N4G0hGnTpsW4ceOOeV/nzp1beDcAAK3LaRmAhYWFUVhYmOttAAC0SqflW8AAAByfAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASEyHXG+Ahsuy49+3d3fD72sNa3J9/JZYk+vjN3ZNro9vzqZdk+vjN+WaE0nh92dLfW5wevIKIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBCAAQGIEIABAYgQgAEBiBGArlpfXuPtPtK6l1jT0ub7aq2mP3xJ7bswaHxtzmrPp5jzRLCfSWj82jVnTUsfn9CMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEtNmArCysjKGDBmS620AALR5bSYAm9o3vvGN6Nu3b3Tq1CmKioripptuil27duV6WwAAzS7ZALzqqqvimWeeia1bt8azzz4bNTU18cd//Me53hYAQLNrlgAcOXJkzJgxI2bPnh2FhYXRu3fvqKysrLt/x44dcf3110e3bt2ioKAgxo0bF7t37673HIsWLYpevXpF9+7dY8qUKXHo0KGjjrNs2bIoKSmJTp06xcCBA+PRRx896T3ecccdccUVV8R5550Xw4YNizvvvDPWr18fv/3tbxs9NwBAW9BsrwCuWLEiunbtGhs2bIgHH3ww7rvvvli9enVkWRZjx46Nffv2xbp162L16tVRU1MT48ePr1v7zDPPREVFRcyfPz82btwYRUVFR8Xd0qVL4+6774758+dHdXV1LFiwIO65555YsWJFg/e6b9++WLlyZQwbNiw6dux4yrMDALRmHZrriUtLS6OioiIiIgYMGBCPPPJIvPrqqxERsXnz5ti+fXsUFxdHRMSTTz4ZF198cbz55ptx2WWXxeLFi2Py5MkxderUiIiYN29erFmzpt6rgPfff3889NBDccMNN0RERL9+/aKqqiqWLFkSkyZNOqk9zpkzJx555JH4zW9+E1dccUX89Kc/PeHjDx8+HIcPH667fuDAgZM8GwAArUezvQJYWlpa73pRUVHs2bMnqquro7i4uC7+IiIGDRoUPXv2jOrq6oiIqK6ujvLy8nrrj7y+d+/e2LlzZ0yZMiW6detWd5k3b17U1NSc9B7/4i/+It5+++145ZVXon379nHzzTdHlmXHffzChQujR48edZcjZwAAaCua7RXA330rNS8vL2prayPLssjLyzvq8ce7/Vhqa2sj4vO3gS+//PJ697Vv3/6k93jWWWfFWWedFb/3e78XJSUlUVxcHOvXrz8qPr9w1113xaxZs+quHzhwoHVE4FlnRXzxbyjPOuvk7mtlaz7sdRJrWtmeT2pNro/fBGtO24+NOdvMno+3pt4sjTlOG5mzVR2/NcxJk8jLTvSSVyONHDkyhgwZEosXL667bezYsdGzZ8+YOHFijBkzpt5bwFVVVXVvAZeVlcWwYcNiyJAh9f7dX3l5efzf//1fbNq0KSIizj333PjOd74T99xzT5PseefOndG3b9947bXXYuTIkSe15sCBA9GjR4/Yv39/FBQUNMk+jpSXF3Gij87x7j/RupZaczyn054bs6Ytztka9mxOczbkeRq7Ltcfm8asaanjn26a+8/vtqBDSx9w1KhRUVpaGhMnTozFixfHp59+GrfeemuMGDEiysrKIiJi5syZMWnSpCgrK4vhw4fHypUrY8uWLdG/f/+656msrIwZM2ZEQUFBjBkzJg4fPhwbN26Mjz76qN6rdMfyxhtvxBtvvBHDhw+PM888M7Zt2xb33ntvXHDBBcd99Q8A4HTR4j8HMC8vL1atWhVnnnlmXHnllTFq1Kjo379//OQnP6l7zPjx4+Pee++NOXPmxNChQ+P999+P6dOn13ueqVOnxuOPPx7Lly+PwYMHx4gRI2L58uXRr1+/L91D586d47nnnourr746Lrroopg8eXJccsklsW7dusjPz2/ymQEAWpNmeQs4Fd4CPr3eljqe1OdsDXs2pzkb8jyNXZfrj01j1ngLuHG8BZzw/wQCAJCq0zIAFyxYUO/Hwxx5GTNmTK63BwCQUy3+TSAtYdq0aTFu3Lhj3te5c+cW3g0AQOtyWgZgYWFhFBYW5nobAACt0mn5FjAAAMcnAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAW7Esa9z9J1rXUmtyffyW2HNj1rTFOVvDns15/DW5Pn4u52zMeWns8dvi15SmPD6nHwEIAJAYAQgAkBgBCACQGAEIAJAYAQgAkBgBCACQGAEIAJAYAQgAkBgBCACQGAEIAJAYAQgAkBgBCACQGAEIAJAYAQgAkBgBCACQmA653kBblmVZREQcOHAgxzsBAE7WF39uf/HneIoE4Ck4ePBgREQUFxfneCcAQEMdPHgwevTokett5ERelnL+nqLa2trYtWtXdO/ePfLy8hq8/sCBA1FcXBw7d+6MgoKCZthh65f6OTB/2vNHOAepzx/hHORi/izL4uDBg9GnT59o1y7Nfw3nFcBT0K5duzj33HNP+XkKCgqS/E1/pNTPgfnTnj/COUh9/gjnoKXnT/WVvy+kmb0AAAkTgAAAiRGAOZSfnx8VFRWRn5+f663kTOrnwPxpzx/hHKQ+f4RzkPr8ueKbQAAAEuMVQACAxAhAAIDECEAAgMQIQACAxAjAU/Doo49Gv379olOnTjF06ND413/91xM+ft26dTF06NDo1KlT9O/fP/72b//2qMc8++yzMWjQoMjPz49BgwbF888/f8rHbS65mP9nP/tZ/NEf/VH06dMn8vLyYtWqVU05UoPl4hwsXLgwLrvssujevXucffbZMXbs2Ni6dWuTznWycjH/Y489FqWlpXU/NLa8vDz++Z//uUnnaohcfR34wsKFCyMvLy9uv/32Ux2lUXIxf2VlZeTl5dW79O7du0nnaohcfQ786le/ij/5kz+Jr3zlK9GlS5cYMmRIvPXWW00218nKxfznn3/+UZ8DeXl58d3vfrdJZzutZTTK008/nXXs2DFbunRpVlVVlc2cOTPr2rVr9v777x/z8du2bcu6dOmSzZw5M6uqqsqWLl2adezYMfv7v//7use8/vrrWfv27bMFCxZk1dXV2YIFC7IOHTpk69evb/Rxm0uu5v+nf/qn7O67786effbZLCKy559/vrlHPa5cnYNrr702W7ZsWfbOO+9kmzZtyq677rqsb9++2f/+7/82+8xHytX8L774YvaP//iP2datW7OtW7dmc+fOzTp27Ji98847zT7z78rVOfjCG2+8kZ1//vlZaWlpNnPmzOYa87hyNX9FRUV2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", + "text/html": [ + "\n", + "
\n", + "
\n", + " Figure\n", + "
\n", + " \n", + "
\n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# plot with lines for deadlines\n", + "fig, ax = plt.subplots()\n", + "for i, record in enumerate(records):\n", + " ax.broken_barh([(record.start_time, record.end_time - record.start_time)], (name_to_id[record.node_name] - 0.4, 0.8), facecolors='blue')\n", + "\n", + "# draw a vertical line for each deadline\n", + "for deadline in deadlines:\n", + " # may have to adjust the y value depending on your chain layout\n", + " ax.plot([deadline.deadline, deadline.deadline], [0, num_nodes], color='red')\n", + "\n", + "ax.set_yticks(range(num_nodes))\n", + "ax.set_yticklabels(name_to_id.keys())\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}