Skip to content

Commit 3382b83

Browse files
Support migrations in sort.
Closes #22 Closes #117
1 parent e87e40a commit 3382b83

File tree

6 files changed

+264
-37
lines changed

6 files changed

+264
-37
lines changed

c/CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
- Removed a previous requirement on ``tsk_table_collection_union``, allowing for unioning of
1414
new information both above and below shared history (:user:`petrelharp`, :user:`mufernando`, :pr:`1108`).
1515

16+
- Support migrations in tsk_table_collection_sort. (:user:`jeromekelleher`,
17+
:issue:`22`, :issue:`117`, :pr:`1131`).
18+
1619
**Breaking changes**
1720

1821
- Method ``tsk_individual_table_add_row`` has an extra arguments ``parents`` and ``parents_length``.

c/tests/test_tables.c

Lines changed: 101 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,35 @@
2929
#include <unistd.h>
3030
#include <stdlib.h>
3131

32+
static void
33+
reverse_migrations(tsk_table_collection_t *tables)
34+
{
35+
int ret;
36+
tsk_migration_table_t migrations;
37+
tsk_migration_t migration;
38+
tsk_id_t j;
39+
40+
/* Easy way to copy the metadata schema */
41+
ret = tsk_migration_table_copy(&tables->migrations, &migrations, 0);
42+
CU_ASSERT_EQUAL_FATAL(ret, 0);
43+
ret = tsk_migration_table_clear(&migrations);
44+
CU_ASSERT_EQUAL_FATAL(ret, 0);
45+
46+
for (j = (tsk_id_t) tables->migrations.num_rows - 1; j >= 0; j--) {
47+
ret = tsk_migration_table_get_row(&tables->migrations, j, &migration);
48+
CU_ASSERT_EQUAL_FATAL(ret, 0);
49+
ret = tsk_migration_table_add_row(&migrations, migration.left, migration.right,
50+
migration.node, migration.source, migration.dest, migration.time,
51+
migration.metadata, migration.metadata_length);
52+
CU_ASSERT_FATAL(ret >= 0);
53+
}
54+
55+
ret = tsk_migration_table_copy(&migrations, &tables->migrations, TSK_NO_INIT);
56+
CU_ASSERT_EQUAL_FATAL(ret, 0);
57+
58+
tsk_migration_table_free(&migrations);
59+
}
60+
3261
static void
3362
reverse_edges(tsk_table_collection_t *tables)
3463
{
@@ -37,7 +66,10 @@ reverse_edges(tsk_table_collection_t *tables)
3766
tsk_edge_t edge;
3867
tsk_id_t j;
3968

40-
ret = tsk_edge_table_init(&edges, tables->edges.options);
69+
/* Easy way to copy the metadata schema */
70+
ret = tsk_edge_table_copy(&tables->edges, &edges, 0);
71+
CU_ASSERT_EQUAL_FATAL(ret, 0);
72+
ret = tsk_edge_table_clear(&edges);
4173
CU_ASSERT_EQUAL_FATAL(ret, 0);
4274

4375
for (j = (tsk_id_t) tables->edges.num_rows - 1; j >= 0; j--) {
@@ -3756,13 +3788,8 @@ test_sort_tables_offsets(void)
37563788
ret = tsk_treeseq_copy_tables(ts, &tables, 0);
37573789
CU_ASSERT_EQUAL_FATAL(ret, 0);
37583790

3759-
ret = tsk_table_collection_sort(&tables, NULL, 0);
3760-
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_SORT_MIGRATIONS_NOT_SUPPORTED);
3761-
3762-
tsk_migration_table_clear(&tables.migrations);
37633791
ret = tsk_table_collection_sort(&tables, NULL, 0);
37643792
CU_ASSERT_EQUAL_FATAL(ret, 0);
3765-
37663793
/* Check that setting edge offset = len(edges) does nothing */
37673794
reverse_edges(&tables);
37683795
ret = tsk_table_collection_copy(&tables, &copy, 0);
@@ -3773,6 +3800,18 @@ test_sort_tables_offsets(void)
37733800
CU_ASSERT_EQUAL_FATAL(ret, 0);
37743801
CU_ASSERT_FATAL(tsk_table_collection_equals(&tables, &copy, 0));
37753802

3803+
ret = tsk_table_collection_sort(&tables, NULL, 0);
3804+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3805+
/* Check that setting migration offset = len(migrations) does nothing */
3806+
reverse_migrations(&tables);
3807+
ret = tsk_table_collection_copy(&tables, &copy, TSK_NO_INIT);
3808+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3809+
memset(&bookmark, 0, sizeof(bookmark));
3810+
bookmark.migrations = tables.migrations.num_rows;
3811+
ret = tsk_table_collection_sort(&tables, &bookmark, 0);
3812+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3813+
CU_ASSERT_FATAL(tsk_table_collection_equals(&tables, &copy, 0));
3814+
37763815
ret = tsk_table_collection_sort(&tables, NULL, 0);
37773816
CU_ASSERT_EQUAL_FATAL(ret, 0);
37783817
CU_ASSERT_FATAL(tables.sites.num_rows > 2);
@@ -3942,6 +3981,15 @@ test_sort_tables_errors(void)
39423981
ret = tsk_table_collection_sort(&tables, &pos, 0);
39433982
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_EDGE_OUT_OF_BOUNDS);
39443983

3984+
memset(&pos, 0, sizeof(pos));
3985+
pos.migrations = (tsk_size_t) -1;
3986+
ret = tsk_table_collection_sort(&tables, &pos, 0);
3987+
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_MIGRATION_OUT_OF_BOUNDS);
3988+
3989+
pos.migrations = tables.migrations.num_rows + 1;
3990+
ret = tsk_table_collection_sort(&tables, &pos, 0);
3991+
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_MIGRATION_OUT_OF_BOUNDS);
3992+
39453993
/* Individual, node, population and provenance positions are ignored */
39463994
memset(&pos, 0, sizeof(pos));
39473995
pos.individuals = 1;
@@ -3963,13 +4011,8 @@ test_sort_tables_errors(void)
39634011
ret = tsk_table_collection_sort(&tables, &pos, 0);
39644012
CU_ASSERT_EQUAL_FATAL(ret, 0);
39654013

3966-
/* Setting migrations, sites or mutations gives a BAD_PARAM. See
4014+
/* Setting sites or mutations gives a BAD_PARAM. See
39674015
* github.com/tskit-dev/tskit/issues/101 */
3968-
memset(&pos, 0, sizeof(pos));
3969-
pos.migrations = 1;
3970-
ret = tsk_table_collection_sort(&tables, &pos, 0);
3971-
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_MIGRATIONS_NOT_SUPPORTED);
3972-
39734016
memset(&pos, 0, sizeof(pos));
39744017
pos.sites = 1;
39754018
ret = tsk_table_collection_sort(&tables, &pos, 0);
@@ -3980,12 +4023,6 @@ test_sort_tables_errors(void)
39804023
ret = tsk_table_collection_sort(&tables, &pos, 0);
39814024
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_SORT_OFFSET_NOT_SUPPORTED);
39824025

3983-
/* Migrations are not supported */
3984-
tsk_migration_table_add_row(&tables.migrations, 0, 1, 0, 0, 0, 0, NULL, 0);
3985-
CU_ASSERT_EQUAL_FATAL(tables.migrations.num_rows, 1);
3986-
ret = tsk_table_collection_sort(&tables, NULL, 0);
3987-
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_SORT_MIGRATIONS_NOT_SUPPORTED);
3988-
39894026
tsk_table_collection_free(&tables);
39904027
tsk_treeseq_free(&ts);
39914028
}
@@ -4179,6 +4216,51 @@ test_sort_tables_canonical(void)
41794216
tsk_table_collection_free(&t1);
41804217
}
41814218

4219+
static void
4220+
test_sort_tables_migrations(void)
4221+
{
4222+
int ret;
4223+
tsk_treeseq_t *ts;
4224+
tsk_table_collection_t tables, copy;
4225+
4226+
ts = caterpillar_tree(13, 1, 1);
4227+
ret = tsk_treeseq_copy_tables(ts, &tables, 0);
4228+
CU_ASSERT_EQUAL_FATAL(ret, 0);
4229+
CU_ASSERT_FATAL(tables.migrations.num_rows > 0);
4230+
4231+
ret = tsk_table_collection_copy(&tables, &copy, 0);
4232+
CU_ASSERT_EQUAL_FATAL(ret, 0);
4233+
CU_ASSERT_FATAL(tsk_table_collection_equals(&tables, &copy, 0));
4234+
4235+
reverse_migrations(&tables);
4236+
CU_ASSERT_FATAL(!tsk_table_collection_equals(&tables, &copy, 0));
4237+
ret = tsk_table_collection_sort(&tables, NULL, 0);
4238+
CU_ASSERT_EQUAL_FATAL(ret, 0);
4239+
CU_ASSERT_FATAL(tsk_migration_table_equals(&tables.migrations, &copy.migrations, 0));
4240+
CU_ASSERT_FATAL(tsk_table_collection_equals(&tables, &copy, 0));
4241+
4242+
/* Make sure we test the deeper comparison keys. The full key is
4243+
* (time, source, dest, left, node) */
4244+
tsk_migration_table_clear(&tables.migrations);
4245+
4246+
/* params = left, right, node, source, dest, time */
4247+
tsk_migration_table_add_row(&tables.migrations, 0, 1, 0, 0, 1, 0, NULL, 0);
4248+
tsk_migration_table_add_row(&tables.migrations, 0, 1, 1, 0, 1, 0, NULL, 0);
4249+
ret = tsk_migration_table_copy(&tables.migrations, &copy.migrations, TSK_NO_INIT);
4250+
CU_ASSERT_EQUAL_FATAL(ret, 0);
4251+
4252+
reverse_migrations(&tables);
4253+
CU_ASSERT_FATAL(!tsk_table_collection_equals(&tables, &copy, 0));
4254+
ret = tsk_table_collection_sort(&tables, NULL, 0);
4255+
CU_ASSERT_EQUAL_FATAL(ret, 0);
4256+
CU_ASSERT_FATAL(tsk_migration_table_equals(&tables.migrations, &copy.migrations, 0));
4257+
4258+
tsk_table_collection_free(&tables);
4259+
tsk_table_collection_free(&copy);
4260+
tsk_treeseq_free(ts);
4261+
free(ts);
4262+
}
4263+
41824264
static void
41834265
test_sorter_interface(void)
41844266
{
@@ -5942,6 +6024,7 @@ main(int argc, char **argv)
59426024
{ "test_sort_tables_edge_metadata", test_sort_tables_edge_metadata },
59436025
{ "test_sort_tables_no_edge_metadata", test_sort_tables_no_edge_metadata },
59446026
{ "test_sort_tables_mutation_times", test_sort_tables_mutation_times },
6027+
{ "test_sort_tables_migrations", test_sort_tables_migrations },
59456028
{ "test_edge_update_invalidates_index", test_edge_update_invalidates_index },
59466029
{ "test_copy_table_collection", test_copy_table_collection },
59476030
{ "test_sort_tables_errors", test_sort_tables_errors },

c/tests/testlib.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -821,19 +821,16 @@ caterpillar_tree(tsk_size_t n, tsk_size_t num_sites, tsk_size_t num_mutations)
821821
strlen(prov_timestamp), prov_record, strlen(prov_record));
822822
CU_ASSERT_EQUAL_FATAL(ret, 0);
823823

824-
ret = tsk_table_collection_sort(&tables, 0, 0);
825-
CU_ASSERT_EQUAL_FATAL(ret, 0);
826-
827-
/* Add in some mock migrations. Must be done after sort as it doesn't support
828-
* migrations.
829-
* TODO make these consistent with the caterpillar tree topology. */
824+
/* TODO make these consistent with the caterpillar tree topology. */
830825
for (j = 0; j < n - 1; j++) {
831826
m = j % num_metadatas;
832827
ret = tsk_migration_table_add_row(&tables.migrations, 0, 1, j, j, j + 1, j + 1.5,
833828
metadata[m], strlen(metadata[m]));
834829
CU_ASSERT_FATAL(ret >= 0);
835830
}
836831

832+
ret = tsk_table_collection_sort(&tables, 0, 0);
833+
CU_ASSERT_EQUAL_FATAL(ret, 0);
837834
ret = tsk_table_collection_build_index(&tables, 0);
838835
CU_ASSERT_EQUAL_FATAL(ret, 0);
839836
ret = tsk_table_collection_compute_mutation_parents(&tables, 0);

0 commit comments

Comments
 (0)