Skip to content

Commit

Permalink
Initial high-level stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromekelleher committed Nov 26, 2021
1 parent bc58e75 commit d2034bf
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 2 deletions.
2 changes: 1 addition & 1 deletion python/_tskitmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -5864,7 +5864,7 @@ ReferenceSequence_check_write(ReferenceSequence *self)
}
if (self->read_only) {
PyErr_SetString(PyExc_AttributeError,
"ReferenceSequence is read-only mode and can only be modified "
"ReferenceSequence is read-only and can only be modified "
"in a TableCollection");
ret = -1;
goto out;
Expand Down
2 changes: 1 addition & 1 deletion python/tests/test_lowlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -3280,7 +3280,7 @@ def test_state(self):
refseq.data = ""
assert refseq.state != 0

@pytest.mark.parametrize("ref_data", ["", "abc", "A" * 1000, "🎄🌳🌴🌲🎋"])
@pytest.mark.parametrize("ref_data", ["", "abc", "A" * 10, "🎄🌳🌴🌲🎋"])
def test_data(self, ref_data):
tables = _tskit.TableCollection()
refseq = tables.reference_sequence
Expand Down
70 changes: 70 additions & 0 deletions python/tests/test_reference_sequence.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# MIT License
#
# Copyright (c) 2021 Tskit Developers
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""
Tests for reference sequence support.
"""
import pytest

import tskit


class TestTablesProperties:
def test_initially_unset(self):
tables = tskit.TableCollection(1)
assert tables.reference_sequence.is_unset()
tables.reference_sequence.data = "ABCDEF"
assert tables.reference_sequence.data == "ABCDEF"

def test_same_object(self):
tables = tskit.TableCollection(1)
refseq = tables.reference_sequence
tables.reference_sequence.data = "asdf"
assert refseq.data == "asdf"
# Not clear we want to do this, but keeping the same pattern as the
# tables for now.
assert tables.reference_sequence is not refseq

def test_write_object_fails(self):
tables = tskit.TableCollection(1)
with pytest.raises(AttributeError):
tables.reference_sequence = None


class TestTreeSequenceProperties:
@pytest.mark.parametrize("data", ["", "abcd", "🎄🌳🌴"])
def test_data_inherited_from_tables(self, data):
tables = tskit.TableCollection(1)
tables.reference_sequence.data = data
ts = tables.tree_sequence()
assert ts.reference_sequence.data == data

def test_write_data_fails(self):
tables = tskit.TableCollection(1)
ts = tables.tree_sequence()
with pytest.raises(AttributeError, match="read-only"):
ts.reference_sequence.data = "xyz"

def test_write_object_fails(self):
tables = tskit.TableCollection(1)
ts = tables.tree_sequence()
with pytest.raises(AttributeError):
ts.reference_sequence = None
25 changes: 25 additions & 0 deletions python/tskit/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -2520,6 +2520,23 @@ def __len__(self):
return self.num_pairs


# TODO move to reference_sequence.py
class ReferenceSequence:
def __init__(self, ll_reference_sequence):
self._ll_reference_sequence = ll_reference_sequence

def is_unset(self) -> bool:
return self._ll_reference_sequence.state == 0

@property
def data(self) -> str:
return self._ll_reference_sequence.data

@data.setter
def data(self, value):
self._ll_reference_sequence.data = value


class TableCollection:
"""
A collection of mutable tables defining a tree sequence. See the
Expand Down Expand Up @@ -2561,6 +2578,14 @@ class TableCollection:
def __init__(self, sequence_length=0):
self._ll_tables = _tskit.TableCollection(sequence_length)

@property
def reference_sequence(self):
# NOTE: arguably we should cache the reference to this object
# during init, rather than creating a new instance each time.
# However, following the pattern of the Table classes for now
# for consistency.
return ReferenceSequence(self._ll_tables.reference_sequence)

@property
def individuals(self):
return IndividualTable(ll_table=self._ll_tables.individuals)
Expand Down
4 changes: 4 additions & 0 deletions python/tskit/trees.py
Original file line number Diff line number Diff line change
Expand Up @@ -3630,6 +3630,10 @@ def dump(self, file_or_path, zlib_compression=False):
if local_file:
file.close()

@property
def reference_sequence(self):
return tables.ReferenceSequence(self._ll_tree_sequence.reference_sequence)

@property
def tables_dict(self):
"""
Expand Down

0 comments on commit d2034bf

Please sign in to comment.