Skip to content

Commit cc55ba9

Browse files
committed
kymotrack: "normalize" the y-data output from _histogram_binding_profile
Note that the output is no longer a true probability density, but is more useful for constructing plots
1 parent 9fa1779 commit cc55ba9

File tree

2 files changed

+30
-12
lines changed

2 files changed

+30
-12
lines changed

lumicks/pylake/kymotracker/kymotrack.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -814,15 +814,21 @@ def _histogram_binding_profile(self, n_time_bins, bandwidth, n_position_points,
814814
for bin_index in np.arange(n_time_bins) + 1:
815815
binned_positions = positions[bin_labels == bin_index][:, np.newaxis]
816816
try:
817+
# Each estimate is normalized to integrate to 1. For proper comparison
818+
# need to weight each by the number of data points used to estimate
817819
kde = KernelDensity(kernel="gaussian", bandwidth=bandwidth).fit(binned_positions)
818-
densities.append(np.exp(kde.score_samples(x)))
820+
densities.append(np.exp(kde.score_samples(x)) * binned_positions.size)
819821
except ValueError as err:
820822
if len(binned_positions) == 0:
821823
densities.append(np.zeros(x.size))
822824
else:
823825
raise err
824826

825-
return x.squeeze(), densities
827+
# "normalize" such that the highest peak == 1. This helps with plotting such that
828+
# the offset between bins does not strongly depend on the number of bins or data
829+
y = densities / np.max(densities)
830+
831+
return x.squeeze(), y
826832

827833
def estimate_diffusion(self, method, *args, min_length=None, **kwargs):
828834
r"""Estimate diffusion constant for each track in the group.

lumicks/pylake/kymotracker/tests/test_kymotrack.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -580,18 +580,30 @@ def test_binding_profile_histogram():
580580
k4 = KymoTrack(np.array([4, 5, 6]), np.array([5, 6, 7]), kymo, "red")
581581

582582
tracks = KymoTrackGroup([k1, k2, k3, k4])
583-
x, densities = tracks._histogram_binding_profile(3, 0.2, 4)
583+
584+
# full kymo
585+
x, y_data = tracks._histogram_binding_profile(3, 0.2, 4)
586+
y_ref = [
587+
[3.86752108e-022, 1.00000000e000, 4.14559001e-073, 3.96110737e-266],
588+
[8.32495048e-087, 2.32557804e-002, 1.55038536e-002, 5.54996698e-087],
589+
[1.98055368e-266, 2.07279501e-073, 5.00000000e-001, 2.77988974e-049],
590+
]
584591

585592
np.testing.assert_allclose(x, np.linspace(0, 10, 4))
586-
np.testing.assert_allclose(
587-
densities[0], [1.28243310e-022, 3.31590463e-001, 1.37463811e-073, 1.31346543e-266]
588-
)
589-
np.testing.assert_allclose(
590-
densities[1], [1.03517782e-87, 2.89177312e-03, 1.92784875e-03, 6.90118545e-88]
591-
)
592-
np.testing.assert_allclose(
593-
densities[2], [1.97019814e-266, 2.06195717e-073, 4.97385694e-001, 2.76535477e-049]
594-
)
593+
for j, (y, ref) in enumerate(zip(y_data, y_ref)):
594+
np.testing.assert_allclose(y, ref, err_msg=f"failed on item {j}")
595+
596+
# ROI
597+
x, y_data = tracks._histogram_binding_profile(3, 0.2, 4, roi=[[15, 3], [40, 6]])
598+
y_ref = [
599+
[1.24221001e-06, 6.42912623e-23, 4.62111561e-50, 4.61295977e-88],
600+
[6.66662526e-01, 2.48442002e-06, 1.28582525e-22, 9.24223122e-50],
601+
[3.72663003e-06, 9.99997516e-01, 1.00000000e00, 6.66667495e-01],
602+
]
603+
604+
np.testing.assert_allclose(x, np.linspace(3, 6, 4))
605+
for j, (y, ref) in enumerate(zip(y_data, y_ref)):
606+
np.testing.assert_allclose(y, ref, err_msg=f"failed on item {j}")
595607

596608
# test empty bin than frames
597609
x, densities = tracks._histogram_binding_profile(10, 0.2, 4)

0 commit comments

Comments
 (0)