-
How to update an existing tag (e.g. cell barcode tag) in a BAM record? I only found a way to read the value of a tag, but not how to write/update one: use std::{env, io};
use noodles::bam;
use noodles::sam;
use noodles::sam::alignment::io::Write;
use noodles::sam::alignment::record::data::field::{Tag, Value};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let src = env::args().nth(1).expect("missing src");
let mut reader = bam::io::reader::Builder.build_from_path(src)?;
let header = reader.read_header()?;
let stdout = io::stdout().lock();
let mut writer = sam::io::Writer::new(stdout);
for result in reader.records() {
let record = result?;
if let Some(Value::String(cb)) = record.data().get(&Tag::CELL_BARCODE_ID).transpose()?
{
// e.g. Add something to cell barcode before writing the record.
// record.data().set(&Tag::CELL_BARCODE_ID, format!("{}-sample", cb));
writer.write_alignment_record(&header, &record)?;
};
}
writer.finish(&header)?;
Ok(())
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
From my reading of the API/internals, the bam When editing/updating/persisting/caching records, I've been converting them to the sam |
Beta Was this translation helpful? Give feedback.
-
As @d-cameron mentioned, for result in reader.records() {
let record = result?;
let mut record_buf = RecordBuf::try_from_alignment_record(&header, &record)?;
// ...
} Alternatively, the reader supports reading records as record buffers via Here's a full example: // cargo add [email protected] --features bam,sam
use std::{env, io};
use noodles::{
bam,
sam::{
self,
alignment::{io::Write, record::data::field::Tag, record_buf::data::field::Value},
},
};
fn main() -> io::Result<()> {
let src = env::args().nth(1).expect("missing src");
let mut reader = bam::io::reader::Builder.build_from_path(src)?;
let header = reader.read_header()?;
let stdout = io::stdout().lock();
let mut writer = sam::io::Writer::new(stdout);
writer.write_header(&header)?;
for result in reader.record_bufs(&header) {
let mut record = result?;
let data = record.data_mut();
let cell_barcode_id = data.remove(&Tag::CELL_BARCODE_ID).map(|(_, value)| value);
if let Some(Value::String(mut id)) = cell_barcode_id {
id.extend(b"-sample");
data.insert(Tag::CELL_BARCODE_ID, Value::String(id));
writer.write_alignment_record(&header, &record)?;
}
}
writer.finish(&header)?;
Ok(())
} |
Beta Was this translation helpful? Give feedback.
As @d-cameron mentioned,
bam::Record
is immutable.sam::alignment::RecordBuf
is the mutable form of an alignment record. You can convert abam::Record
to asam::alignment::RecordBuf
usingRecordBuf::try_from_alignment_record
.Alternatively, the reader supports reading records as record buffers via
Reader::read_record_buf
andReader::record_bufs
.Here's a full example: