[−][src]Crate bam
bam is a crate that allows to read BAM files, written completely in Rust.
Why?
Having a crate written completely in Rust reduces the number of dependencies and compilation time. Additionally, it removes the need to install additional C libraries.
Errors produced by this crate are more readable and easier to catch and fix on-the-fly.
Overview
Currently, there are three readers and two writers:
- bam::IndexedReader - fetches records from random genomic regions.
- bam::BamReader - reads a BAM file consecutively.
- bam::SamReader - reads a SAM file consecutively.
- bam::BamWriter - writes a BAM file.
- bam::SamWriter - writes a SAM file.
The bgzip module contains bgzip readers and writers.
The crate also allows to conviniently work with SAM/BAM records and their fields, such as CIGAR or tags.
Usage
The following code would load BAM file in.bam
and its index in.bam.bai
, take all records
from 3:600001-700000
and print them on the stdout.
extern crate bam; use std::io; use bam::RecordWriter; fn main() { let mut reader = bam::IndexedReader::from_path("in.bam").unwrap(); let output = io::BufWriter::new(io::stdout()); let mut writer = bam::SamWriter::build() .header(reader.header().clone()) .write_header(false) .from_stream(output).unwrap(); for record in reader.fetch(2, 600_000, 700_000).unwrap() { let record = record.unwrap(); writer.write(&record).unwrap(); } }
More complicated example with completely created header and record:
extern crate bam; use std::io; use bam::RecordWriter; use bam::header::{Header, HeaderEntry}; fn main() { // Creating a header. let mut header = Header::new(); // Header line "@HD VN:1.6 SO:Coordinate". let mut header_line = HeaderEntry::header_line("1.6".to_string()); header_line.push(b"SO", "Coordinate".to_string()); header.push_entry(header_line).unwrap(); // Reference line "@SQ SN:chr1 LN:10000". header.push_entry(HeaderEntry::ref_sequence("chr1".to_string(), 10000)).unwrap(); // Write SAM to stdout. let output = io::BufWriter::new(io::stdout()); let mut writer = bam::SamWriter::from_stream(output, header).unwrap(); // Create a new record, set its name to "Read_1", // reference id to 0, start to 10 (both 0-based). let mut record = bam::Record::new(); record.set_name("Read_1".bytes()); record.set_ref_id(0).unwrap(); record.set_start(10).unwrap(); // Set the record to be on reverse strand. record.flag_mut().set_strand(false); // Set sequence and qualities (qualities without +33), and cigar. record.set_seq_qual("ACGT".bytes(), [10_u8, 20, 30, 10].iter().cloned()).unwrap(); record.set_cigar("2M1I1M".bytes()).unwrap(); // Add NM tag. record.tags_mut().push(b"NM", 1).unwrap(); writer.write(&record).unwrap(); writer.finish().unwrap(); // Above code would print the following SAM file: // @HD VN:1.6 SO:Coordinate // @SQ SN:chr1 LN:10000 // Read_1 16 chr1 11 0 2M1I1M * 0 0 ACGT +5?+ NM:i:1 println!("Aligned pairs:"); for (read_pos, ref_pos) in record.aligned_pairs() { println!(" {:?} {:?}", read_pos, ref_pos); } // Aligned pairs: // Some(0) Some(10) // Some(1) Some(11) // Some(2) None // Some(3) Some(12) }
Re-exports
pub use bam_reader::IndexedReader; |
pub use bam_reader::BamReader; |
pub use bam_writer::BamWriter; |
pub use header::Header; |
pub use record::Record; |
pub use record::Error; |
pub use sam::SamWriter; |
pub use sam::SamReader; |
Modules
bam_reader | Indexed and consecutive BAM readers. |
bam_writer | BAM writer. |
bgzip | Bgzip files (BGZF) and bgzip blocks. |
header | SAM/BAM header. |
index | BAI index, virtual offset and bgzip chunks. |
record | SAM/BAM record, sequence, qualities and operations on them. |
sam | SAM reader and writer. |
Traits
RecordReader | A trait for reading BAM/SAM records. |
RecordWriter | A trait for writing BAM/SAM records. |