Skip to content

Commit a1b8505

Browse files
committed
Added child_left, child_right columns to nodes_df and tests for these.
1 parent e85d3b7 commit a1b8505

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

model.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,8 @@ def nodes_df(self):
449449
"time": ts.nodes_time,
450450
"num_mutations": self.nodes_num_mutations,
451451
"ancestors_span": child_right - child_left,
452+
"child_left": child_left, # FIXME add test for this
453+
"child_right": child_right, # FIXME add test for this
452454
"is_sample": is_sample,
453455
}
454456
)
@@ -458,6 +460,8 @@ def nodes_df(self):
458460
"time": "float64",
459461
"num_mutations": "int",
460462
"ancestors_span": "float64",
463+
"child_left": "float64",
464+
"child_right": "float64",
461465
"is_sample": "bool",
462466
}
463467
)
@@ -584,3 +588,48 @@ def calc_mutations_per_tree(self):
584588
mutations_per_tree = np.zeros(self.ts.num_trees, dtype=np.int64)
585589
mutations_per_tree[unique_values] = counts
586590
return mutations_per_tree
591+
592+
def compute_ancestor_spans_heatmap_data(self, win_x_size=1_000_000, win_y_size=500):
593+
"""
594+
Calculates the average ancestor span in a genomic-time window
595+
"""
596+
nodes_df = self.nodes_df[self.nodes_df.ancestors_span != -np.inf]
597+
nodes_df = nodes_df.reset_index(drop=True)
598+
nodes_left = nodes_df.child_left
599+
nodes_right = nodes_df.child_right
600+
nodes_time = nodes_df.time
601+
ancestors_span = nodes_df.ancestors_span
602+
603+
num_x_wins = int(np.ceil(nodes_right.max() - nodes_left.min()) / win_x_size)
604+
num_y_wins = int(np.ceil(nodes_time.max() / win_y_size))
605+
heatmap_sums = np.zeros((num_x_wins, num_y_wins))
606+
heatmap_counts = np.zeros((num_x_wins, num_y_wins))
607+
608+
for u in range(len(nodes_left)):
609+
x_start = int(
610+
np.floor(nodes_left[u] / win_x_size)
611+
) # map the node span to the x-axis bins it overlaps
612+
x_end = int(np.floor(nodes_right[u] / win_x_size))
613+
y = max(0, int(np.floor(nodes_time[u] / win_y_size)) - 1)
614+
heatmap_sums[x_start:x_end, y] += min(ancestors_span[u], win_x_size)
615+
heatmap_counts[x_start:x_end, y] += 1
616+
617+
avg_spans = heatmap_sums / heatmap_counts
618+
indices = np.indices((num_x_wins, num_y_wins))
619+
x_coords = indices[0] * win_x_size
620+
y_coords = indices[1] * win_y_size
621+
622+
df = pd.DataFrame(
623+
{
624+
"genomic_position": x_coords.flatten(),
625+
"time": y_coords.flatten(),
626+
"average_ancestor_span": avg_spans.flatten(),
627+
}
628+
)
629+
return df.astype(
630+
{
631+
"genomic_position": "int",
632+
"time": "int",
633+
"average_ancestor_span": "float64",
634+
}
635+
)

pages/nodes.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,13 @@ def make_node_hist_panel(tsm, log_y):
5757
pn.pane.Markdown("# Plot Options"),
5858
log_y_checkbox,
5959
)
60-
return pn.Column(main, hist_panel, plot_options)
60+
61+
anc_span_data = tsm.compute_ancestor_spans_heatmap_data()
62+
heatmap = hv.HeatMap(anc_span_data).opts(
63+
width=config.PLOT_WIDTH,
64+
height=config.PLOT_HEIGHT,
65+
tools=["hover"],
66+
colorbar=True,
67+
)
68+
69+
return pn.Column(main, hist_panel, heatmap, plot_options)

tests/test_data_model.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ def test_single_tree_example(self):
168168
nt.assert_array_equal(df.time, [0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0])
169169
nt.assert_array_equal(df.num_mutations, [1, 1, 1, 1, 1, 1, 1])
170170
nt.assert_array_equal(df.ancestors_span, [10, 10, 10, 10, 10, 10, -np.inf])
171+
nt.assert_array_equal(df.child_left, [0, 0, 0, 0, 0, 0, np.inf])
172+
nt.assert_array_equal(df.child_right, [10, 10, 10, 10, 10, 10, 0])
171173
nt.assert_array_equal(df.is_sample, [1, 1, 1, 1, 0, 0, 0])
172174

173175
def test_multiple_tree_example(self):
@@ -178,6 +180,8 @@ def test_multiple_tree_example(self):
178180
nt.assert_array_equal(df.time, [0.0, 0.0, 0.0, 1.0, 2.0])
179181
nt.assert_array_equal(df.num_mutations, [0, 0, 0, 0, 0])
180182
nt.assert_array_equal(df.ancestors_span, [10, 10, 10, 10, -np.inf])
183+
nt.assert_array_equal(df.child_left, [0, 0, 0, 0, np.inf])
184+
nt.assert_array_equal(df.child_right, [10, 10, 10, 10, 0])
181185
nt.assert_array_equal(df.is_sample, [1, 1, 1, 0, 0])
182186

183187

0 commit comments

Comments
 (0)