Skip to content
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
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "chaintools"
version = "0.0.12"
version = "0.0.13"
edition = "2024"
authors = ["alejandrogzi <alejandrxgzi@gmail.com>"]
license = "MIT"
Expand All @@ -15,7 +15,7 @@ default-run = "chaintools"
default = ["mmap"]
cli = ["dep:clap", "dep:genepred", "dep:log", "dep:simple_logger", "sequence", "write", "dep:num_cpus", "dep:rust-lapper", "parallel"]
mmap = ["memmap2"]
gzip = ["dep:flate2", "flate2/zlib-rs"]
gzip = ["dep:flate2", "flate2/zlib-rs", "genepred?/gzip"]
parallel = ["rayon"]
index = []
write = []
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
</span>

<p align="center">
<a href="https://img.shields.io/badge/version-0.0.12-green" target="_blank">
<img alt="Version Badge" src="https://img.shields.io/badge/version-0.0.12-green">
<a href="https://img.shields.io/badge/version-0.0.13-green" target="_blank">
<img alt="Version Badge" src="https://img.shields.io/badge/version-0.0.13-green">
</a>
<a href="https://crates.io/crates/chaintools" target="_blank">
<img alt="Crates.io Version" src="https://img.shields.io/crates/v/chaintools">
Expand All @@ -29,7 +29,7 @@
<span>work with .chain files in Rust</span>
<br>
<br>
<a href="https://docs.rs/chaintools/0.0.12/chaintools/">docs</a> .
<a href="https://docs.rs/chaintools/0.0.13/chaintools/">docs</a> .
<a href="https://github.com/alejandrogzi/chaintools/tree/master/assets/usage/usage.md">usage</a> .
<a href="https://github.com/alejandrogzi/chaintools/tree/master/assets/tools">tools</a> .
<a href="https://genome.ucsc.edu/goldenpath/help/chain.html">chains</a>
Expand Down Expand Up @@ -60,7 +60,7 @@ Add this to your `Cargo.toml`:

```toml
[dependencies]
chaintools = { version = "0.0.12", features = ["mmap", "gzip", "parallel"] }
chaintools = { version = "0.0.13", features = ["mmap", "gzip", "parallel"] }
```

## Benchmarks
Expand Down
24 changes: 24 additions & 0 deletions assets/changelog/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,29 @@ All notable changes to **chaintools** are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.0.13] - 2026-08-25

### Added

- **`coverage` subcommand** — measures how much of a merged annotation feature
universe (`cds`, `exon`, `intron`, or `utr`) is covered by aligned chain
blocks on either the reference or forward-genomic query side. BED, GTF, and
GFF annotations are supported; output contains deterministic per-chromosome
rows plus a required total fraction.
- **Compact parallel coverage engine** — stores one atomic bit per unique
annotation base, skips genomic gaps, parses chains in parallel, and marks
ranges word-wise without materializing or sorting chain-derived intervals.

### Changed

- The existing `gzip` feature now also enables gzip annotation input in
`genepred`; builds without `gzip` remain compression-free.
- Package and documentation versions bumped to `0.0.13`.

### Documentation

- Added `assets/tools/coverage.md` and a coverage example to the usage guide.

## [0.0.12] - 2026-08-10

### Added
Expand Down Expand Up @@ -337,6 +360,7 @@ First stable release.
- Automatic gzip (`.chain.gz`) detection and decompression (`gzip` feature).
- Test suite, benchmark binary, CI workflows, Docker image, and rustdoc documentation.

[0.0.13]: https://github.com/alejandrogzi/chaintools/releases/tag/v0.0.13
[0.0.12]: https://github.com/alejandrogzi/chaintools/releases/tag/v0.0.12
[0.0.11]: https://github.com/alejandrogzi/chaintools/releases/tag/v0.0.11
[0.0.10]: https://github.com/alejandrogzi/chaintools/releases/tag/v0.0.10
Expand Down
107 changes: 107 additions & 0 deletions assets/tools/coverage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<p align="center">
<p align="center">
<img width=200 align="center" src="../logo.png" >
</p>

<span>
<h1 align="center">
chaintools
</h1>
</span>

<p align="center">
<a href="https://img.shields.io/badge/version-0.0.13-green" target="_blank">
<img alt="Version Badge" src="https://img.shields.io/badge/version-0.0.13-green">
</a>
<a href="https://crates.io/crates/chaintools" target="_blank">
<img alt="Crates.io Version" src="https://img.shields.io/crates/v/chaintools">
</a>
<a href="https://github.com/alejandrogzi/chaintools" target="_blank">
<img alt="GitHub License" src="https://img.shields.io/github/license/alejandrogzi/chaintools?color=blue">
</a>
<a href="https://crates.io/crates/chaintools" target="_blank">
<img alt="Crates.io Total Downloads" src="https://img.shields.io/crates/d/chaintools">
</a>
</p>
</p>


# chaintools coverage

Measure the fraction of unique annotation feature bases covered by aligned
chain blocks. Chain gaps never count as coverage.

## Usage

```bash
chaintools coverage \
--chains hg38ToMm39.over.chain.gz \
--side reference \
--intervals gencode.v50.annotation.gtf.gz \
--feature cds \
> coverage.tsv
```

Several chain files can be passed to `--chains`, listed one per line with
`--file`, or read from standard input when neither option is present. Their
coverage is combined; duplicate and overlapping mappings count each base once.

## Options

- `--chains <PATH>...` / `-c`: one or more chain files.
- `--file <PATH>` / `-f`: file containing one chain path per line. Conflicts
with `--chains`.
- `--side reference|query`: chain side on which to measure coverage.
- `--intervals <PATH>`: BED, GTF, GFF, or GFF3 annotation.
- `--feature cds|exon|intron|utr`: required feature universe.
- `--threads <N>` / `-t`: global worker count; defaults to available CPUs.

`.gz` chain and annotation paths are supported when chaintools is built with
the `gzip` feature. `cargo install --all-features chaintools` enables it.

## Annotation semantics

Features are derived through `genepred`, then overlapping and book-ended
intervals are merged per chromosome before totals are calculated. Isoforms
therefore cannot double-count shared bases.

| Input | exon | cds / utr | intron |
|:---|:---:|:---:|:---:|
| BED3–6 | full interval | unavailable | unavailable |
| BED8/9 | full interval | thick bounds | unavailable |
| BED12 | blocks | blocks intersected with thick bounds | gaps between blocks |
| GTF/GFF | derived from transcript structure | derived from coding bounds | derived from exon structure |

A non-empty annotation that yields no requested intervals fails instead of
silently reporting zero coverage. Chromosomes are not filtered: the annotation
defines the complete denominator, including mitochondrial DNA and scaffolds.

## Chain coordinates

Only positive-length alignment blocks are marked. Full chain spans and the gaps
between blocks are never treated as aligned. `--side query` converts minus-strand
query blocks to forward genomic coordinates before intersecting the annotation.
The target/reference strand must be `+`, and malformed block spans are rejected.

## Output

Output is tab-separated and written to standard output:

```text
chrom total_bases covered_bases coverage_fraction
chr1 3894019 3585875 0.920867
chr2 2799576 2623407 0.937073
total 6693595 6209282 0.927645
```

Rows are sorted by chromosome name. Fractions use six decimal places, and the
final `total` row is always present. An empty annotation reports `0.000000`,
never `NaN`.

## Memory and parallelism

Merged annotation intervals are flattened into compact feature space with one
atomic bit per feature base, so genomic gaps use no bitmap memory. Annotation
normalization is serial; interval indexing, chain parsing and marking, and
bitmap counting use the global thread pool. Parsed chain files are held in
memory one input file at a time.
26 changes: 22 additions & 4 deletions assets/usage/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
</span>

<p align="center">
<a href="https://img.shields.io/badge/version-0.0.2-green" target="_blank">
<img alt="Version Badge" src="https://img.shields.io/badge/version-0.0.2-green">
<a href="https://img.shields.io/badge/version-0.0.13-green" target="_blank">
<img alt="Version Badge" src="https://img.shields.io/badge/version-0.0.13-green">
</a>
<a href="https://crates.io/crates/chaintools" target="_blank">
<img alt="Crates.io Version" src="https://img.shields.io/crates/v/chaintools">
Expand All @@ -36,7 +36,7 @@ Add this to your `Cargo.toml`:

```toml
[dependencies]
chaintools = { version = "0.0.2", features = ["mmap", "gzip"] }
chaintools = { version = "0.0.13", features = ["mmap", "gzip", "parallel"] }
```

### Features
Expand All @@ -51,6 +51,24 @@ chaintools = { version = "0.0.2", features = ["mmap", "gzip"] }

## Usage

### Annotation Coverage

Measure the fraction of unique annotation feature bases covered by aligned
chain blocks:

```bash
chaintools coverage \
--chains hg38ToMm39.over.chain.gz \
--side reference \
--intervals gencode.v50.annotation.gtf.gz \
--feature cds \
> coverage.tsv
```

Available features are `cds`, `exon`, `intron`, and `utr`. Use the global
`--threads` option to control parallel work. See the
[coverage tool guide](../tools/coverage.md) for input semantics and output.

### Basic File Reading

```rust
Expand Down Expand Up @@ -264,4 +282,4 @@ Run tests with all features:

```bash
cargo test --all-features
`
```
2 changes: 1 addition & 1 deletion src/cli/bed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ pub struct BedArgs {
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
enum BedSide {
pub(crate) enum BedSide {
Reference,
Query,
}
Expand Down
Loading
Loading