Skip to content

Commit

Permalink
fixup! Testing corner cases.
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromekelleher committed Apr 23, 2020
1 parent 365296f commit a81bcd3
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 4 deletions.
1 change: 0 additions & 1 deletion _msprimemodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2016,7 +2016,6 @@ MutationModel_init(MutationModel *self, PyObject *args, PyObject *kwds)
"transition matrix must be a square matrix with num_alleles rows");
goto out;
}
assert(shape[0] == PyObject_Size(py_transition_matrix));

/* Note: it's important we zero out mutation_model here because
* we can error before we can mutation_model_alloc, leaving the
Expand Down
55 changes: 55 additions & 0 deletions lib/tests/tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -4742,15 +4742,51 @@ test_single_tree_mutgen_do_nothing_mutations(void)
ret = mutgen_generate(&mutgen, &tables, MSP_DISCRETE_SITES | MSP_KEEP_SITES);
CU_ASSERT_EQUAL_FATAL(ret, 0);
CU_ASSERT_TRUE(tsk_table_collection_equals(&tables, &copy));
mutgen_free(&mutgen);

ret = mutgen_alloc(&mutgen, rng, &rate_map, &mut_model, 100);
CU_ASSERT_EQUAL_FATAL(ret, 0);
ret = mutgen_generate(&mutgen, &tables, MSP_DISCRETE_SITES);
CU_ASSERT_EQUAL_FATAL(ret, 0);
CU_ASSERT_EQUAL_FATAL(tables.mutations.num_rows, 0);
CU_ASSERT_EQUAL_FATAL(tables.sites.num_rows, 0);
mutgen_free(&mutgen);

interval_map_free(&rate_map);
mutation_model_free(&mut_model);
tsk_table_collection_free(&tables);
tsk_table_collection_free(&copy);
gsl_rng_free(rng);
}

static void
test_single_tree_mutgen_many_mutations(void)
{
int ret = 0;
mutgen_t mutgen;
gsl_rng *rng = gsl_rng_alloc(gsl_rng_default);
tsk_table_collection_t tables;
interval_map_t rate_map;
mutation_model_t mut_model;

CU_ASSERT_FATAL(rng != NULL);
ret = mutation_model_factory(&mut_model, ALPHABET_BINARY);
CU_ASSERT_EQUAL_FATAL(ret, 0);
ret = interval_map_alloc_single(&rate_map, 1, 100);
CU_ASSERT_EQUAL_FATAL(ret, 0);

ret = tsk_table_collection_init(&tables, 0);
CU_ASSERT_EQUAL_FATAL(ret, 0);
insert_single_tree(&tables, ALPHABET_BINARY);

ret = mutgen_alloc(&mutgen, rng, &rate_map, &mut_model, 0);
CU_ASSERT_EQUAL_FATAL(ret, 0);
ret = mutgen_generate(&mutgen, &tables, MSP_DISCRETE_SITES);
CU_ASSERT_EQUAL_FATAL(ret, 0);
ret = mutgen_generate(&mutgen, &tables, MSP_DISCRETE_SITES | MSP_KEEP_SITES);
CU_ASSERT_EQUAL_FATAL(ret, MSP_ERR_MUTATION_GENERATION_OUT_OF_ORDER);
mutgen_free(&mutgen);

interval_map_free(&rate_map);
mutation_model_free(&mut_model);
tsk_table_collection_free(&tables);
Expand Down Expand Up @@ -5135,7 +5171,16 @@ test_mutation_model_errors(void)
CU_ASSERT_EQUAL_FATAL(ret, MSP_ERR_BAD_ROOT_PROBABILITIES);
mutation_model_free(&model);

/* Sums to 1, but bad values */
dist[0] = -1;
dist[1] = 2;
ret = mutation_model_alloc(&model, 2, (char **) (uintptr_t) alleles,
dist, matrix);
CU_ASSERT_EQUAL_FATAL(ret, MSP_ERR_BAD_ROOT_PROBABILITIES);
mutation_model_free(&model);

dist[0] = 1.1;
dist[1] = 0.5;
ret = mutation_model_alloc(&model, 2, (char **) (uintptr_t) alleles,
dist, matrix);
CU_ASSERT_EQUAL_FATAL(ret, MSP_ERR_BAD_ROOT_PROBABILITIES);
Expand Down Expand Up @@ -5168,7 +5213,16 @@ test_mutation_model_errors(void)
CU_ASSERT_EQUAL_FATAL(ret, MSP_ERR_BAD_TRANSITION_MATRIX);
mutation_model_free(&model);

/* Sums to 1, but bad values */
matrix[0] = -1;
matrix[1] = 2;
ret = mutation_model_alloc(&model, 2, (char **) (uintptr_t) alleles,
dist, matrix);
CU_ASSERT_EQUAL_FATAL(ret, MSP_ERR_BAD_TRANSITION_MATRIX);
mutation_model_free(&model);

matrix[0] = 1.1;
matrix[1] = 1.0;
ret = mutation_model_alloc(&model, 2, (char **) (uintptr_t) alleles,
dist, matrix);
CU_ASSERT_EQUAL_FATAL(ret, MSP_ERR_BAD_TRANSITION_MATRIX);
Expand Down Expand Up @@ -5374,6 +5428,7 @@ main(int argc, char **argv)
{"test_single_tree_mutgen_interval", test_single_tree_mutgen_interval},
{"test_single_tree_mutgen_empty_site", test_single_tree_mutgen_empty_site},
{"test_single_tree_mutgen_do_nothing_mutations", test_single_tree_mutgen_do_nothing_mutations},
{"test_single_tree_mutgen_many_mutations", test_single_tree_mutgen_many_mutations},

{"test_genic_selection_trajectory", test_genic_selection_trajectory},
{"test_sweep_genic_selection_bad_parameters",
Expand Down
2 changes: 1 addition & 1 deletion msprime/mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def __init__(self):

class InfiniteSites(MutationModel):
# This mutation model is defined for backwards compatability, and is a remnant
# avoid confusion. The class should be formally deprecated and removed at
# of an earlier design. The class should be formally deprecated and removed at
# some point.
def __init__(self, alphabet=BINARY):
self.alphabet = alphabet
Expand Down
5 changes: 3 additions & 2 deletions tests/test_mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ def validate_model(self, model):
self.assertEqual(sum(model.root_distribution), 1.0)
for j in range(num_alleles):
self.assertEqual(sum(model.transition_matrix[j]), 1.0)
s = model.__str__()
self.assertIsInstance(s, str)
self.assertTrue(s.startswith("Mutation model with alleles"))

def validate_stationary(self, model):
# for most models, the root distribution should be the
Expand Down Expand Up @@ -868,9 +871,7 @@ def verify_model(self, model, verify_roots=True):
self.chisquare(row, sum(row) * p)

def example_models(self):
print("MM")
yield msprime.BinaryMutations()
print("JK")
yield msprime.JukesCantor()
model = msprime.MutationModel(
alleles=[b"abc", b"", b"x"],
Expand Down
25 changes: 25 additions & 0 deletions tests/test_provenance.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,31 @@ def test_mutate(self):
'msprime.mutations.BinaryMutations'
)

def test_mutate_model(self):
ts = msprime.simulate(5, random_seed=1)
ts = msprime.mutate(ts, model=msprime.JukesCantor())
decoded = self.decode(ts.provenance(1).record)
self.assertEqual(decoded.schema_version, "1.0.0")
self.assertEqual(decoded.parameters.command, "mutate")
self.assertEqual(
decoded.parameters.model['__class__'],
'msprime.mutations.JukesCantor'
)

def test_mutate_map(self):
ts = msprime.simulate(5, random_seed=1)
rate_map = msprime.MutationMap(position=[0, 0.5, 1], rate=[0, 1, 0])
ts = msprime.mutate(ts, rate=rate_map)
decoded = self.decode(ts.provenance(1).record)
self.assertEqual(decoded.schema_version, "1.0.0")
self.assertEqual(decoded.parameters.command, "mutate")
self.assertEqual(
decoded.parameters.rate['__class__'],
'msprime.mutations.MutationMap'
)
self.assertEqual(decoded.parameters.rate["position"], rate_map.position)
self.assertEqual(decoded.parameters.rate["rate"], rate_map.rate)

def test_mutate_numpy(self):
ts = msprime.simulate(5, random_seed=1)
ts = msprime.mutate(
Expand Down

0 comments on commit a81bcd3

Please sign in to comment.