zaeleus / noodles

Bioinformatics I/O libraries in Rust
MIT License
515 stars 53 forks source link

How to set tag with value in noodles::bam? #258

Closed Crispy13 closed 6 months ago

Crispy13 commented 7 months ago

I've read the doc of Data,

but it seems that no set method is there.

zaeleus commented 7 months ago

Alignment format records (sam::Record, bam::Record, and cram::Record) are immutable.

You can convert these to alignment record buffers (sam::alignment::RecordBuf) using RecordBuf::try_from_alignment_record to mutate the record, e.g.,

// cargo add noodles@0.70.0 --features bam,sam

use std::io;

use noodles::{
    bam,
    sam::{
        self,
        alignment::{record::data::field::Tag, record_buf::data::field::Value},
    },
};

fn main() -> io::Result<()> {
    let header = sam::Header::default();
    let record = bam::Record::default();

    let mut record_buf = sam::alignment::RecordBuf::try_from_alignment_record(&header, &record)?;

    record_buf
        .data_mut()
        .insert(Tag::COMMENT, Value::from("noodles"));

    Ok(())
}

If you are going to mutate every record, consider reading records as RecordBuf using Reader::read_record_buf/Reader::record_bufs, e.g.,

// cargo add noodles@0.70.0 --features bam,sam

use std::io;

use noodles::{
    bam,
    sam::alignment::{record::data::field::Tag, record_buf::data::field::Value},
};

fn main() -> io::Result<()> {
    let mut reader = bam::io::reader::Builder.build_from_path("in.bam")?;
    let header = reader.read_header()?;

    for result in reader.record_bufs(&header) {
        let mut record = result?;

        record
            .data_mut()
            .insert(Tag::COMMENT, Value::from("noodles"));
    }

    Ok(())
}

For future questions, consider posting a discussion under the Q&A category.

Crispy13 commented 6 months ago

Thanks