Skip to content

Commit

Permalink
implement split merge logic (#25)
Browse files Browse the repository at this point in the history
* initial concept implementation

* implement split/merge logic and corresponding plots

* test fix

* test fix attempt 2

* test fix attempt 3

* attempt to ensure consitant ordering across platforms

* change test to normalize clusterids

* pre-sort test data

* add trackid column to test to fix ordering

* allow filtering and remapping from lineagetracker

* update lint

* fix nPrev issue with merge

* fix nprev

* fister small before split merge apply

* update lineage_plot
  • Loading branch information
bgraedel authored Dec 21, 2024
1 parent 17dbff3 commit ad53c09
Show file tree
Hide file tree
Showing 9 changed files with 1,415 additions and 33 deletions.
4 changes: 2 additions & 2 deletions arcos4py/plotting/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
__email__ = "[email protected]"
__version__ = '0.2.5'

from ._plotting import NoodlePlot, dataPlots, plotOriginalDetrended, statsPlots
from ._plotting import LineagePlot, NoodlePlot, dataPlots, plotOriginalDetrended, statsPlots

__all__ = ["plotOriginalDetrended", "dataPlots", "statsPlots", "NoodlePlot"]
__all__ = ["plotOriginalDetrended", "dataPlots", "statsPlots", "NoodlePlot", "LineagePlot"]
425 changes: 424 additions & 1 deletion arcos4py/plotting/_plotting.py

Large diffs are not rendered by default.

754 changes: 724 additions & 30 deletions arcos4py/tools/_detect_events.py

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions tests/test_event_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from pandas.testing import assert_frame_equal

from arcos4py import ARCOS
from arcos4py.tools import track_events_dataframe


@pytest.fixture
Expand Down Expand Up @@ -279,6 +280,34 @@ def test_split_from_2_objects():
assert_frame_equal(out, df_true, check_like=True)


def test_4_colliding_with_allow_merges():
"""Test colliding event detection on a simple image."""
test_df = pd.read_csv('tests/testdata/4obj_merge_allowed.csv')
true_df = pd.read_csv('tests/testdata/4obj_merge_allowed_res.csv')
# Sort the test data to ensure consistent order
test_df = test_df.sort_values(by=['T', 'X', 'Y', 'track_id']).reset_index(drop=True)

tracked_df, _ = track_events_dataframe(
test_df,
eps=2,
eps_prev=2,
min_clustersize=4,
n_prev=1,
position_columns=['X', 'Y'],
frame_column='T',
id_column='track_id',
allow_merges=True,
stability_threshold=1,
allow_splits=True,
)

# Sort by relevant columns
tracked_df = tracked_df.sort_values(by=['T', 'X', 'Y', 'track_id']).reset_index(drop=True)
true_df = true_df.sort_values(by=['T', 'X', 'Y', 'track_id']).reset_index(drop=True)

assert_frame_equal(tracked_df, true_df, check_dtype=False)


def test_cross_2_objects():
df_in = pd.read_csv('tests/testdata/2objCross_in.csv')
df_true = pd.read_csv('tests/testdata/2objCross_res.csv')
Expand Down
34 changes: 34 additions & 0 deletions tests/test_event_detection_pix.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,19 @@ def test_1_split():
assert_array_equal(tracked_img, true_img)


def test_1_split_with_splitting_allowed():
"""Test split event detection on a simple image."""
test_img = imread('tests/testdata/pix/1_split.tif')
true_img = imread('tests/testdata/pix/1_split_allowed_true.tif')
test_img = np.where(test_img == 255, 0, 1)
tracked_img, lineage_tracker = track_events_image(
test_img, eps=2, eps_prev=2, min_clustersize=4, dims="TXY", allow_splits=True, stability_threshold=2
)
cluster_history = lineage_tracker.get_cluster_history(2) # cluster id 2
assert_array_equal(tracked_img, true_img)
assert_array_equal([1, 2], [i.cluster_id for i in cluster_history[0]]) # compare cluster history of first parent


def test_2_colliding():
"""Test colliding event detection on a simple image."""
test_img = imread('tests/testdata/pix/2_colliding.tif')
Expand Down Expand Up @@ -89,6 +102,27 @@ def test_4_colliding():
assert_array_equal(tracked_img, true_img)


def test_4_colliding_with_allow_merges():
"""Test colliding event detection on a simple image."""
test_img = imread('tests/testdata/pix/4_colliding.tif')
true_img = imread('tests/testdata/pix/4_colliding_merge_allowed.tif')
test_img = np.where(test_img == 255, 0, 1)
tracked_img, lineage_tracker = track_events_image(
test_img,
eps=2,
eps_prev=2,
min_clustersize=4,
n_prev=1,
dims="TXY",
allow_merges=True,
stability_threshold=1,
allow_splits=True,
)
cluster_history = lineage_tracker.get_cluster_history(5) # cluster id 5, timepoint 7
assert_array_equal([1, 5], [i.cluster_id for i in cluster_history[0]]) # compare cluster history of first parent
assert_array_equal(tracked_img, true_img)


def test_4_colliding_transportaion():
"""Test colliding event detection on a simple image."""
test_img = imread('tests/testdata/pix/4_colliding.tif')
Expand Down
103 changes: 103 additions & 0 deletions tests/testdata/4obj_merge_allowed.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
T,X,Y,track_id
0,0,6,1
0,6,0,31
0,6,12,42
0,12,6,72
1,0,6,1
1,1,5,2
1,1,6,3
1,1,7,4
1,5,1,20
1,5,11,30
1,6,0,31
1,6,1,32
1,6,11,41
1,6,12,42
1,7,1,43
1,7,11,53
1,11,5,69
1,11,6,70
1,11,7,71
1,12,6,72
2,1,5,2
2,1,6,3
2,1,7,4
2,2,5,5
2,2,6,6
2,2,7,7
2,5,1,20
2,5,2,21
2,5,10,29
2,5,11,30
2,6,1,32
2,6,2,33
2,6,10,40
2,6,11,41
2,7,1,43
2,7,2,44
2,7,10,52
2,7,11,53
2,10,5,66
2,10,6,67
2,10,7,68
2,11,5,69
2,11,6,70
2,11,7,71
3,2,5,5
3,2,6,6
3,2,7,7
3,3,4,8
3,3,8,12
3,4,3,13
3,4,9,19
3,5,2,21
3,5,10,29
3,6,2,33
3,6,10,40
3,7,2,44
3,7,10,52
3,8,3,54
3,8,9,60
3,9,4,61
3,9,8,65
3,10,5,66
3,10,6,67
3,10,7,68
4,3,5,9
4,3,6,10
4,3,7,11
4,4,4,14
4,4,8,18
4,5,3,22
4,5,9,28
4,6,3,34
4,6,9,39
4,7,3,45
4,7,9,51
4,8,4,55
4,8,8,59
4,9,5,62
4,9,6,63
4,9,7,64
5,3,6,10
5,4,5,15
5,4,6,16
5,4,7,17
5,5,4,23
5,5,8,27
5,6,4,35
5,6,8,38
5,7,4,46
5,7,8,50
5,8,5,56
5,8,6,57
5,8,7,58
5,9,6,63
6,5,5,24
6,5,6,25
6,5,7,26
6,6,5,36
6,6,7,37
6,7,5,47
6,7,6,48
6,7,7,49
99 changes: 99 additions & 0 deletions tests/testdata/4obj_merge_allowed_res.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
T,X,Y,track_id,collid,lineage,parent_1,parent_2,parent_3,parent_4
1,0,6,1,1,1,,,,
1,1,5,2,1,1,,,,
1,1,6,3,1,1,,,,
1,1,7,4,1,1,,,,
1,5,1,20,2,2,,,,
1,5,11,30,3,3,,,,
1,6,0,31,2,2,,,,
1,6,1,32,2,2,,,,
1,6,11,41,3,3,,,,
1,6,12,42,3,3,,,,
1,7,1,43,2,2,,,,
1,7,11,53,3,3,,,,
1,11,5,69,4,4,,,,
1,11,6,70,4,4,,,,
1,11,7,71,4,4,,,,
1,12,6,72,4,4,,,,
2,1,5,2,1,1,,,,
2,1,6,3,1,1,,,,
2,1,7,4,1,1,,,,
2,2,5,5,1,1,,,,
2,2,6,6,1,1,,,,
2,2,7,7,1,1,,,,
2,5,1,20,2,2,,,,
2,5,2,21,2,2,,,,
2,5,10,29,3,3,,,,
2,5,11,30,3,3,,,,
2,6,1,32,2,2,,,,
2,6,2,33,2,2,,,,
2,6,10,40,3,3,,,,
2,6,11,41,3,3,,,,
2,7,1,43,2,2,,,,
2,7,2,44,2,2,,,,
2,7,10,52,3,3,,,,
2,7,11,53,3,3,,,,
2,10,5,66,4,4,,,,
2,10,6,67,4,4,,,,
2,10,7,68,4,4,,,,
2,11,5,69,4,4,,,,
2,11,6,70,4,4,,,,
2,11,7,71,4,4,,,,
3,2,5,5,1,1,,,,
3,2,6,6,1,1,,,,
3,2,7,7,1,1,,,,
3,3,4,8,1,1,,,,
3,3,8,12,1,1,,,,
3,4,3,13,2,2,,,,
3,4,9,19,3,3,,,,
3,5,2,21,2,2,,,,
3,5,10,29,3,3,,,,
3,6,2,33,2,2,,,,
3,6,10,40,3,3,,,,
3,7,2,44,2,2,,,,
3,7,10,52,3,3,,,,
3,8,3,54,2,2,,,,
3,8,9,60,3,3,,,,
3,9,4,61,4,4,,,,
3,9,8,65,4,4,,,,
3,10,5,66,4,4,,,,
3,10,6,67,4,4,,,,
3,10,7,68,4,4,,,,
4,3,5,9,1,1,,,,
4,3,6,10,1,1,,,,
4,3,7,11,1,1,,,,
4,4,4,14,1,1,,,,
4,4,8,18,1,1,,,,
4,5,3,22,2,2,,,,
4,5,9,28,3,3,,,,
4,6,3,34,2,2,,,,
4,6,9,39,3,3,,,,
4,7,3,45,2,2,,,,
4,7,9,51,3,3,,,,
4,8,4,55,2,2,,,,
4,8,8,59,3,3,,,,
4,9,5,62,4,4,,,,
4,9,6,63,4,4,,,,
4,9,7,64,4,4,,,,
5,3,6,10,5,1,1.0,2.0,3.0,4.0
5,4,5,15,5,1,1.0,2.0,3.0,4.0
5,4,6,16,5,1,1.0,2.0,3.0,4.0
5,4,7,17,5,1,1.0,2.0,3.0,4.0
5,5,4,23,5,1,1.0,2.0,3.0,4.0
5,5,8,27,5,1,1.0,2.0,3.0,4.0
5,6,4,35,5,1,1.0,2.0,3.0,4.0
5,6,8,38,5,1,1.0,2.0,3.0,4.0
5,7,4,46,5,1,1.0,2.0,3.0,4.0
5,7,8,50,5,1,1.0,2.0,3.0,4.0
5,8,5,56,5,1,1.0,2.0,3.0,4.0
5,8,6,57,5,1,1.0,2.0,3.0,4.0
5,8,7,58,5,1,1.0,2.0,3.0,4.0
5,9,6,63,5,1,1.0,2.0,3.0,4.0
6,5,5,24,5,1,1.0,2.0,3.0,4.0
6,5,6,25,5,1,1.0,2.0,3.0,4.0
6,5,7,26,5,1,1.0,2.0,3.0,4.0
6,6,5,36,5,1,1.0,2.0,3.0,4.0
6,6,7,37,5,1,1.0,2.0,3.0,4.0
6,7,5,47,5,1,1.0,2.0,3.0,4.0
6,7,6,48,5,1,1.0,2.0,3.0,4.0
6,7,7,49,5,1,1.0,2.0,3.0,4.0
Binary file added tests/testdata/pix/1_split_allowed_true.tif
Binary file not shown.
Binary file added tests/testdata/pix/4_colliding_merge_allowed.tif
Binary file not shown.

0 comments on commit ad53c09

Please sign in to comment.