mirror of
https://github.com/logos-co/nomos-simulations.git
synced 2025-01-11 19:24:31 +00:00
78 lines
2.6 KiB
Python
78 lines
2.6 KiB
Python
from datetime import datetime
|
|
from enum import Enum
|
|
|
|
import matplotlib.pyplot as plt
|
|
import pandas
|
|
|
|
|
|
class NodeState(Enum):
|
|
"""
|
|
A state of node at a certain time.
|
|
For now, we assume that the node cannot send and receive messages at the same time for simplicity.
|
|
"""
|
|
|
|
SENDING = -1
|
|
IDLE = 0
|
|
RECEIVING = 1
|
|
|
|
|
|
class NodeStateTable:
|
|
def __init__(self, num_nodes: int, duration_sec: int):
|
|
# Create a table to store the state of each node at each millisecond
|
|
self.__table = [
|
|
[NodeState.IDLE] * (duration_sec * 1000) for _ in range(num_nodes)
|
|
]
|
|
|
|
def __getitem__(self, idx: int) -> list[NodeState]:
|
|
return self.__table[idx]
|
|
|
|
def analyze(self):
|
|
df = pandas.DataFrame(self.__table).transpose()
|
|
df.columns = [f"Node-{i}" for i in range(len(self.__table))]
|
|
# Convert NodeState enum to their integer values
|
|
df = df.map(lambda state: state.value)
|
|
print("==========================================")
|
|
print("Node States of All Nodes over Time")
|
|
print(", ".join(f"{state.name}:{state.value}" for state in NodeState))
|
|
print("==========================================")
|
|
print(f"{df}\n")
|
|
|
|
csv_path = f"all_node_states_{datetime.now().isoformat(timespec="seconds")}.csv"
|
|
df.to_csv(csv_path)
|
|
print(f"Saved DataFrame to {csv_path}\n")
|
|
|
|
# Count/print the number of each state for each node
|
|
# because the df is usually too big to print
|
|
state_counts = df.apply(pandas.Series.value_counts).fillna(0)
|
|
print("State Counts per Node:")
|
|
print(f"{state_counts}\n")
|
|
|
|
# Draw a dot plot
|
|
plt.figure(figsize=(15, 8))
|
|
for node in df.columns:
|
|
times = df.index
|
|
states = df[node]
|
|
sending_times = times[states == NodeState.SENDING.value]
|
|
receiving_times = times[states == NodeState.RECEIVING.value]
|
|
plt.scatter(
|
|
sending_times,
|
|
[node] * len(sending_times),
|
|
color="red",
|
|
marker="o",
|
|
s=10,
|
|
label="SENDING" if node == df.columns[0] else "",
|
|
)
|
|
plt.scatter(
|
|
receiving_times,
|
|
[node] * len(receiving_times),
|
|
color="blue",
|
|
marker="x",
|
|
s=10,
|
|
label="RECEIVING" if node == df.columns[0] else "",
|
|
)
|
|
plt.xlabel("Time")
|
|
plt.ylabel("Node")
|
|
plt.title("Node States Over Time")
|
|
plt.legend(loc="upper right")
|
|
plt.draw()
|