项目作者: sstadick

项目描述 :
Rust UMI Directional Adjacency Deduplicator
高级语言: Rust
项目地址: git://github.com/sstadick/rumi.git
创建时间: 2019-11-25T18:00:07Z
项目社区:https://github.com/sstadick/rumi

开源协议:MIT License

下载


docs
crates.io

This is beta software, use at your own risk

rumi

Rust UMI based PCR deduplication based on the directional adjacency
as UMI-tools but with a constant time hamming distance implementation.

Install

For now this relies on the rust toolchain. There are excellent docs on
how to set that up.

  1. cargo install rumi

Usage

  1. $ rumi --help
  2. rumi-dedup 0.1.0
  3. Seth Stadick <sstadick@gmail.com>
  4. Deduplicate reads based on umis
  5. USAGE:
  6. rumi [FLAGS] [OPTIONS] <INBAM> --output <OUTBAM> --umi_tag <umi_tag>
  7. FLAGS:
  8. --group_only Don't deduplicate reads, just group them given them agroup id, and print them. Rules
  9. for filtering out unpaired reads, etc, will still be applied.
  10. -h, --help Prints help information
  11. --ignore_splice_pos If two reads have the same start pos, and contain a splice site, they will be
  12. grouped together, instead of further splitting them based on the
  13. splice site
  14. --is_paired Input is paired end. Read pairs with unmapped read1 will be ignored.
  15. --umi_in_read_id The UMI is located in the read id after the last '_'. Otherwise use the RX tag.
  16. -V, --version Prints version information
  17. OPTIONS:
  18. -o, --output <OUTBAM> Output bam file. Use - if stdout [default: -]
  19. -c, --allowed_count_factor <allowed_count_factor>
  20. The factor to multiply the count of a umi by when determining whether or not to group it with other umis
  21. within allowed_read_dist. include umi_b as adjacent to umi_a if: umi_a.counts >= allowed_count_factor *
  22. umi_b.counts [default: 2]
  23. -n, --allowed_network_depth <allowed_network_depth>
  24. The number of nodes deep to go when creating a group. If allowed_read_dist 1, then allowed_network_depth of
  25. 2 will enable getting all umis with hamming distance of 2 from current umi. [default: 2]
  26. -d, --allowed_read_dist <allowed_read_dist>
  27. The distance between umis that will allow them to be counted as adjacent. [default: 1]
  28. -u, --umi_tag <umi_tag> The tag holding the umi information. [default: RX]
  29. ARGS:
  30. <INBAM> Input bam file. Use - if stdin [default: -]

Performance

I have not sat down and done any serious benchmarking yet. Anecdotally
this is at least 4X faster than umi_tools on small datasets. There are
A LOT of low hanging fruit in terms of optimizations to apply though.

I would fully expect that this implementation should be capable of at
least a 10x performance boost once it’s been smoothed out. The large
advantage this has over umi_tools is that it can take advantage of
multiple cores. umi_tools has already shifted a large amount of it’s
work into C code, so just having a compiled language isn’t a huge
advantage.

Known differences from umi_tools

  • The criteria for choosing what read to use is different, and in my
    opinion more extensive. For example, if two reads are the same mapq,
    edit distance, etc, it will come down to read length, keeping the
    longer. In cases of an absolute tie, the incumbant read wins. This can
    lead to differences in results, especially among reverse reads.

TODO

  • Clean up the lib and split out into multiple modules
  • Add better (any) error handling
  • Figure out how to reduce allocations / string clones
  • Clarify the workflow / what actually happens in docs
  • Allow for selection of number of cores to use

Prior Art

Notes

First pass: Collect all reads into a dict that is keyed on position.
Track metrics like umi freq, and extracted umis while building this.
Then iter over that dict and deduplicate at each position.

Diffs in example.bam (from umi_tools)

  • SRR2057595.3354975_CGGGTTGGT: rumi correctly uses the umi starting
    with C since there are two reads with that umi. umi_tools uses the umi
    with only a feq of 1.
  • SRR2057595.4915638_TTGGTTAAA: rumi correctly chooses the read with the
    decided upon umi as the best read.
  • SRR2057595.5405752_AACGGTTGG: rumi correctly leaves as it’s own group.
    umi_tools corrects it dist 3 away to ATTGGTTCG. I expect this to be
    the end source of the 30 extra reads in rumi’s output. What causes
    this in umi_tools?