Column propagation
Analysis of data column propagation timing across the 128 column subnets in PeerDAS.
View query
Show code
# Load column propagation data
df_col_first_seen = load_parquet("col_first_seen", target_date)
print(f"Slots with column data: {len(df_col_first_seen)}")
Column first seenΒΆ
Heatmap showing when each of the 128 data columns was first observed, measured in milliseconds from slot start. Consistent patterns across columns indicate healthy propagation; outliers may signal network issues.
Show code
# Panel 1: Column first seen (ms into slot start) - 128 columns heatmap
# Reshape for heatmap: rows = columns (c0-c127), columns = time
col_names = [f"c{i}" for i in range(NUM_COLUMNS)]
df_cols = df_col_first_seen[col_names].T
df_cols.columns = df_col_first_seen["time"]
# Create slot lookup for hover data
slot_values = df_col_first_seen["slot"].values
# Build customdata: slot number for each column in the heatmap
customdata = np.array([[slot_values[j] for j in range(len(slot_values))] for _ in range(NUM_COLUMNS)])
fig = go.Figure(
data=go.Heatmap(
z=df_cols.values,
x=df_cols.columns,
y=[str(i) for i in range(NUM_COLUMNS)],
zmin=1500,
zmax=4000,
colorbar=horizontal_colorbar("ms"),
customdata=customdata,
hovertemplate="<b>Slot:</b> %{customdata}<br><b>Time:</b> %{x}<br><b>Column Index:</b> %{y}<br><b>First Seen:</b> %{z} ms<extra></extra>",
)
)
fig.update_layout(
margin=dict(l=10, r=10, t=10, b=80),
xaxis=dict(automargin=True),
yaxis=dict(title="Column", automargin=True, autorange="reversed"),
height=800,
)
fig.show()
Delta from fastest column (intraslot, ms)ΒΆ
Shows how much slower each column arrived compared to the fastest column in that slot. Highlights columns that consistently lag behind, which may indicate propagation bottlenecks.
Show code
# Compute delta from min value per slot for each column
col_names = [f"c{i}" for i in range(NUM_COLUMNS)]
df_delta = df_col_first_seen.copy()
# Calculate row-wise minimum and subtract from each column
row_mins = df_delta[col_names].min(axis=1)
for col in col_names:
df_delta[col] = df_delta[col] - row_mins
# Reshape for heatmap
df_delta_cols = df_delta[col_names].T
df_delta_cols.columns = df_delta["time"]
# Create slot lookup for hover data
slot_values = df_delta["slot"].values
# Build customdata: slot number for each column in the heatmap
customdata = np.array([[slot_values[j] for j in range(len(slot_values))] for _ in range(NUM_COLUMNS)])
fig = go.Figure(
data=go.Heatmap(
z=df_delta_cols.values,
x=df_delta_cols.columns,
y=[str(i) for i in range(NUM_COLUMNS)],
colorscale="Inferno",
reversescale=False,
zmin=0,
zmax=250,
colorbar=horizontal_colorbar("ms"),
customdata=customdata,
hovertemplate="<b>Slot:</b> %{customdata}<br><b>Time:</b> %{x}<br><b>Column Index:</b> %{y}<br><b>Delta:</b> %{z} ms<extra></extra>",
)
)
fig.update_layout(
margin=dict(l=10, r=10, t=10, b=80),
xaxis=dict(automargin=True),
yaxis=dict(title="Column", automargin=True, autorange="reversed"),
height=800,
)
fig.show()
Delta normalized (0-1)ΒΆ
Same delta data normalized to a 0β1 scale per slot, making it easier to compare relative propagation order regardless of absolute timing. Columns closer to 0 arrived first; those near 1 arrived last.
Show code
# Normalize delta values to 0-1 range per slot
col_names = [f"c{i}" for i in range(NUM_COLUMNS)]
df_normalized = df_col_first_seen.copy()
# Calculate row-wise min and max, then normalize
row_mins = df_normalized[col_names].min(axis=1)
row_maxs = df_normalized[col_names].max(axis=1)
row_ranges = row_maxs - row_mins
for col in col_names:
df_normalized[col] = (df_normalized[col] - row_mins) / row_ranges.replace(0, np.nan)
# Reshape for heatmap
df_norm_cols = df_normalized[col_names].T
df_norm_cols.columns = df_normalized["time"]
# Create slot lookup for hover data
slot_values = df_normalized["slot"].values
# Build customdata: slot number for each column in the heatmap
customdata = np.array([[slot_values[j] for j in range(len(slot_values))] for _ in range(NUM_COLUMNS)])
fig = go.Figure(
data=go.Heatmap(
z=df_norm_cols.values,
x=df_norm_cols.columns,
y=[str(i) for i in range(NUM_COLUMNS)],
colorscale="YlGnBu",
reversescale=True,
zmin=0,
zmax=1,
colorbar=horizontal_colorbar("Normalized"),
customdata=customdata,
hovertemplate="<b>Slot:</b> %{customdata}<br><b>Time:</b> %{x}<br><b>Column Index:</b> %{y}<br><b>Normalized:</b> %{z:.2f}<extra></extra>",
)
)
fig.update_layout(
margin=dict(l=10, r=10, t=10, b=80),
xaxis=dict(automargin=True),
yaxis=dict(title="Column", automargin=True, autorange="reversed"),
height=800,
)
fig.show()