Skip to content

Commit a2f0379

Browse files
Added interface for setting TableCollection.sequence_length
Closes #107.
1 parent 3b9882e commit a2f0379

File tree

4 files changed

+84
-2
lines changed

4 files changed

+84
-2
lines changed

python/_tskitmodule.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5372,6 +5372,25 @@ TableCollection_get_sequence_length(TableCollection *self, void *closure)
53725372
return Py_BuildValue("f", self->tables->sequence_length);
53735373
}
53745374

5375+
static int
5376+
TableCollection_set_sequence_length(TableCollection *self, PyObject *value, void *closure)
5377+
{
5378+
int ret = -1;
5379+
5380+
if (value == NULL) {
5381+
PyErr_SetString(PyExc_TypeError, "Cannot delete the sequence_length attribute");
5382+
goto out;
5383+
}
5384+
if (! PyNumber_Check(value)) {
5385+
PyErr_SetString(PyExc_TypeError, "sequence_length must be a number");
5386+
goto out;
5387+
}
5388+
self->tables->sequence_length = PyFloat_AsDouble(value);
5389+
ret = 0;
5390+
out:
5391+
return ret;
5392+
}
5393+
53755394
static PyObject *
53765395
TableCollection_get_file_uuid(TableCollection *self, void *closure)
53775396
{
@@ -5564,8 +5583,9 @@ static PyGetSetDef TableCollection_getsetters[] = {
55645583
{"mutations", (getter) TableCollection_get_mutations, NULL, "The mutation table."},
55655584
{"populations", (getter) TableCollection_get_populations, NULL, "The population table."},
55665585
{"provenances", (getter) TableCollection_get_provenances, NULL, "The provenance table."},
5567-
{"sequence_length", (getter) TableCollection_get_sequence_length, NULL,
5568-
"The sequence length."},
5586+
{"sequence_length",
5587+
(getter) TableCollection_get_sequence_length,
5588+
(setter) TableCollection_set_sequence_length, "The sequence length."},
55695589
{"file_uuid", (getter) TableCollection_get_file_uuid, NULL,
55705590
"The UUID of the corresponding file."},
55715591
{NULL} /* Sentinel */

python/tests/test_lowlevel.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,21 @@ def test_reference_deletion(self):
156156
for table in tables:
157157
self.assertGreater(len(str(table)), 0)
158158

159+
def test_set_sequence_length_errors(self):
160+
tables = _tskit.TableCollection(1)
161+
with self.assertRaises(TypeError):
162+
del tables.sequence_length
163+
for bad_value in ["sdf", None, []]:
164+
with self.assertRaises(TypeError):
165+
tables.sequence_length = bad_value
166+
167+
def test_set_sequence_length(self):
168+
tables = _tskit.TableCollection(1)
169+
self.assertEqual(tables.sequence_length, 1)
170+
for value in [-1, 1e6, 1e-22, 1000, 2**32, -10000]:
171+
tables.sequence_length = value
172+
self.assertEqual(tables.sequence_length, value)
173+
159174

160175
class TestTreeSequence(LowLevelTestCase):
161176
"""

python/tests/test_tables.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,49 @@ def test_index_from_ts(self):
15761576
self.assertEqual(ts.tables, tables)
15771577
self.assertFalse(tables.has_index())
15781578

1579+
def test_set_sequence_length_errors(self):
1580+
tables = tskit.TableCollection(1)
1581+
with self.assertRaises(AttributeError):
1582+
del tables.sequence_length
1583+
for bad_value in ["asdf", None, []]:
1584+
with self.assertRaises(TypeError):
1585+
tables.sequence_length = bad_value
1586+
1587+
def test_set_sequence_length(self):
1588+
tables = tskit.TableCollection(1)
1589+
for value in [-1, 100, 2**32, 1e-6]:
1590+
tables.sequence_length = value
1591+
self.assertEqual(tables.sequence_length, value)
1592+
1593+
def test_bad_sequence_length(self):
1594+
tables = msprime.simulate(10, random_seed=1).dump_tables()
1595+
self.assertEqual(tables.sequence_length, 1)
1596+
for value in [-1, 0, -0.99, 0.9999]:
1597+
tables.sequence_length = value
1598+
with self.assertRaises(tskit.LibraryError):
1599+
tables.tree_sequence()
1600+
with self.assertRaises(tskit.LibraryError):
1601+
tables.sort()
1602+
with self.assertRaises(tskit.LibraryError):
1603+
tables.build_index()
1604+
with self.assertRaises(tskit.LibraryError):
1605+
tables.compute_mutation_parents()
1606+
with self.assertRaises(tskit.LibraryError):
1607+
tables.simplify()
1608+
self.assertEqual(tables.sequence_length, value)
1609+
1610+
def test_sequence_length_longer_than_edges(self):
1611+
tables = msprime.simulate(10, random_seed=1).dump_tables()
1612+
tables.sequence_length = 2
1613+
ts = tables.tree_sequence()
1614+
self.assertEqual(ts.sequence_length, 2)
1615+
self.assertEqual(ts.num_trees, 2)
1616+
trees = ts.trees()
1617+
tree = next(trees)
1618+
self.assertGreater(len(tree.parent_dict), 0)
1619+
tree = next(trees)
1620+
self.assertEqual(len(tree.parent_dict), 0)
1621+
15791622

15801623
class TestTableCollectionPickle(unittest.TestCase):
15811624
"""

python/tskit/tables.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,6 +1517,10 @@ def provenances(self):
15171517
def sequence_length(self):
15181518
return self.ll_tables.sequence_length
15191519

1520+
@sequence_length.setter
1521+
def sequence_length(self, sequence_length):
1522+
self.ll_tables.sequence_length = sequence_length
1523+
15201524
@property
15211525
def file_uuid(self):
15221526
return self.ll_tables.file_uuid

0 commit comments

Comments
 (0)