Skip to content

doc: start book sections on tree sequences #381

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@
- [Accessing table columns](./table_collection_column_access.md)
- [Accessing table rows](./table_collection_row_access.md)
- [Validating table collection contents](./table_collection_validation.md)

- [Working with tree sequences](./working_with_tree_sequences.md)
- [Initialization from a table collection](./tree_sequence_from_table_collection.md)
- [Iterating over trees](./tree_sequence_iterate_trees.md)
45 changes: 45 additions & 0 deletions book/src/tree_sequence_from_table_collection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
## Initialization from a table collection

The steps are:

* Add rows to a table
* Sort the table
* Index the table
* Create the tree sequence

For brevity, we skip careful pattern matching of return values
and instead just unwrap them.

### Adding rows

```rust, noplaygound, ignore
{{#include ../../tests/book_trees.rs:build_tables}}
```

### Sorting

```rust, noplaygound, ignore
{{#include ../../tests/book_trees.rs:sort_tables}}
```

See the [API docs](https://docs.rs) for the details of sorting.
The behavior of this function can be confusing at first.
Only tables with strict sorting requirements are affected.

### Indexing

```rust, noplaygound, ignore
{{#include ../../tests/book_trees.rs:index_tables}}
```

### Create the tree sequence

```rust, noplaygound, ignore
{{#include ../../tests/book_trees.rs:create_tree_sequence}}
```

Notes:

* We could have skipped `tables.build_index()` and passed `TreeSquenceFlags::BUILD_INDEXES` instead of the default flags.
* Creating a tree sequence from a table collection takes ownership of the table data and consumes the table collection variable.
Any further attempts to manipulate the table collection variable will result in a compiler error.
17 changes: 17 additions & 0 deletions book/src/tree_sequence_iterate_trees.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Iterating over trees

To iterate over trees left-to-right:

```rust, noplaygound, ignore
{{#include ../../tests/book_trees.rs:iterate_trees}}
```

This API depends on traits most easily brought into scope via the crate prelude:

```rust, noplayground, ignore
use tskit::prelude::*;
```

A `next_back()` function allows iteration to the next tree left of the current tree.
We currently do not have an API expressing "build me an iterator starting from the rightmost tree".
Such an thing is certainly doable.
21 changes: 21 additions & 0 deletions book/src/working_with_tree_sequences.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Working with tree sequences <img align="right" width="73" height="45" src="https://raw.githubusercontent.com/tskit-dev/administrative/main/logos/svg/tskit-rust/Tskit_rust_logo.eps.svg">

The next several sections provide examples based on a tree sequence with two trees.

The first tree is:

0
+++
| | 1
| | +++
2 3 4 5

The second tree is:

0
+-+-+
1 |
+-+-+ |
2 4 5 3


76 changes: 76 additions & 0 deletions tests/book_trees.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#[test]
fn initialize_from_table_collection() {
// ANCHOR: build_tables
use tskit::prelude::*;
use tskit::TableCollection;
use tskit::TableSortOptions;
use tskit::TreeFlags;
use tskit::TreeSequenceFlags;

let mut tables = TableCollection::new(1000.).unwrap();
tables
.add_node(0, 2.0, PopulationId::NULL, IndividualId::NULL)
.unwrap();
tables
.add_node(0, 1.0, PopulationId::NULL, IndividualId::NULL)
.unwrap();
tables
.add_node(
TSK_NODE_IS_SAMPLE,
0.0,
PopulationId::NULL,
IndividualId::NULL,
)
.unwrap();
tables
.add_node(
TSK_NODE_IS_SAMPLE,
0.0,
PopulationId::NULL,
IndividualId::NULL,
)
.unwrap();
tables
.add_node(
TSK_NODE_IS_SAMPLE,
0.0,
PopulationId::NULL,
IndividualId::NULL,
)
.unwrap();
tables
.add_node(
TSK_NODE_IS_SAMPLE,
0.0,
PopulationId::NULL,
IndividualId::NULL,
)
.unwrap();
tables.add_edge(500., 1000., 0, 1).unwrap();
tables.add_edge(0., 500., 0, 2).unwrap();
tables.add_edge(0., 1000., 0, 3).unwrap();
tables.add_edge(500., 1000., 1, 2).unwrap();
tables.add_edge(0., 1000., 1, 4).unwrap();
tables.add_edge(0., 1000., 1, 5).unwrap();
// ANCHOR_END: build_tables

// ANCHOR: sort_tables
tables.full_sort(TableSortOptions::default()).unwrap();
// ANCHOR_END: sort_tables

// ANCHOR: index_tables
tables.build_index().unwrap();
// ANCHOR_END: index_tables

// ANCHOR: create_tree_sequence
let treeseq = tables.tree_sequence(TreeSequenceFlags::default()).unwrap();
// ANCHOR_END: create_tree_sequence

// ANCHOR: iterate_trees
let mut tree_iterator = treeseq.tree_iterator(TreeFlags::default()).unwrap();

while let Some(_tree) = tree_iterator.next() {
// _tree is a tskit::Tree
}
// ANCHOR_END: iterate_trees
}