[][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:

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.