Crate angsd_saf

source ·
Expand description

Reading and writing of the SAF format.

Examples

Read SAF v3 file:

//! Read a SAF file and print readable index and records.

use std::{
    env,
    io::{self, Write},
};

use angsd_saf as saf;

fn main() -> io::Result<()> {
    let path = env::args().nth(1).expect("missing path to SAF member file");
    let mut reader = saf::reader::Builder::v3().build_from_member_path(path)?;

    let stdout = io::stdout();
    let mut writer = stdout.lock();

    write!(writer, "{}", reader.index())?;

    let mut record = reader.create_record_buf();
    while reader.read_record(&mut record)?.is_not_done() {
        writeln!(writer, "{record:.2}")?;
    }

    Ok(())
}

Write SAF v3 file:

//! Read text-based SAF records and print as SAF files.

use std::{
    env,
    io::{self, BufRead},
};

use angsd_saf as saf;

fn main() -> io::Result<()> {
    let path = env::args().nth(1).expect("missing path to SAF member file");

    let stdin = io::stdin();
    let mut reader = stdin.lock();

    let mut buf = String::new();
    reader.read_line(&mut buf)?;
    let record: saf::Record<String, saf::record::Likelihoods> = buf.parse()?;

    let mut writer = saf::WriterV3::from_member_path(record.alleles(), path)?;
    writer.write_record(&record)?;

    while reader.read_line(&mut buf)? != 0 {
        buf.clear();
        let record: saf::Record<String, saf::record::Likelihoods> = buf.parse()?;
        writer.write_record(&record)?;
    }

    Ok(())
}

Read only intersecting sites in multiple SAF v3 files:

//! Read intersecting sites in two SAF files and print readable sites.

use std::{
    env,
    io::{self, Write},
};

use angsd_saf as saf;

fn main() -> io::Result<()> {
    let readers = env::args()
        .skip(1)
        .map(|p| saf::reader::Builder::v3().build_from_member_path(p))
        .collect::<io::Result<Vec<_>>>()?;

    // Note also the [`Reader::intersect`] and [`Intersect::intersect`] methods to construct
    // intersecting reader when the number of readers are statically known.
    let mut intersect = saf::Intersect::new(readers);

    let stdout = io::stdout();
    let mut writer = stdout.lock();

    let mut bufs = intersect.create_record_bufs();
    while intersect.read_records(&mut bufs)?.is_not_done() {
        for (reader, buf) in intersect.get_readers().iter().zip(bufs.iter()) {
            let contig = reader.index().records()[*buf.contig_id()].name();
            let position = buf.position();
            write!(writer, "{contig}\t{position}")?;

            for v in buf.item().iter() {
                write!(writer, "\t{v:.2}")?;
            }

            writeln!(writer)?;
        }
    }

    Ok(())
}

The above examples are also available as runnable binaries, see the repository examples/ folder.

Re-exports

pub use index::Index;
pub use reader::Reader;
pub use reader::ReaderV3;
pub use reader::ReaderV4;
pub use record::Record;
pub use writer::Writer;
pub use writer::WriterV3;
pub use writer::WriterV4;

Modules

SAF file name extensions.
A SAF index.
Reading of the SAF format.
A SAF record.
SAF file versions.
Writing of the SAF format.

Structs

An intersection of SAF file readers.

Enums

A read status.