pub struct Record {
pub inner: *mut bcf1_t,
/* private fields */
}
Expand description
A VCF/BCF record.
New records can be created by the empty_record
methods of bcf::Reader
and bcf::Writer
.
§Example
use rust_htslib::bcf::{Format, Writer};
use rust_htslib::bcf::header::Header;
// Create minimal VCF header with a single sample
let mut header = Header::new();
header.push_sample("sample".as_bytes());
// Write uncompressed VCF to stdout with above header and get an empty record
let mut vcf = Writer::from_stdout(&header, true, Format::Vcf).unwrap();
let mut record = vcf.empty_record();
Fields§
§inner: *mut bcf1_t
Implementations§
Source§impl Record
impl Record
Sourcepub fn header(&self) -> &HeaderView
pub fn header(&self) -> &HeaderView
Return associated header.
Sourcepub fn inner(&self) -> &bcf1_t
pub fn inner(&self) -> &bcf1_t
Return reference to the inner C struct.
§Remarks
Note that this function is only required as long as Rust-Htslib does not provide full access to all aspects of Htslib.
Sourcepub fn inner_mut(&mut self) -> &mut bcf1_t
pub fn inner_mut(&mut self) -> &mut bcf1_t
Return mutable reference to inner C struct.
§Remarks
Note that this function is only required as long as Rust-Htslib does not provide full access to all aspects of Htslib.
Sourcepub fn rid(&self) -> Option<u32>
pub fn rid(&self) -> Option<u32>
Get the reference id of the record.
To look up the contig name,
use HeaderView::rid2name
.
§Returns
Some(rid)
if the internalrid
is set to a value that is not-1
None
if the internalrid
is set to-1
Sourcepub fn set_rid(&mut self, rid: Option<u32>)
pub fn set_rid(&mut self, rid: Option<u32>)
Update the reference id of the record.
To look up reference id for a contig name,
use HeaderView::name2rid
.
§Example
Example assumes we have a Record record
from a VCF with a header containing region
named 1
. See module documentation for how to set
up VCF, header, and record.
let rid = record.header().name2rid(b"1").ok();
record.set_rid(rid);
assert_eq!(record.rid(), rid);
let name = record.header().rid2name(record.rid().unwrap()).ok();
assert_eq!(Some("1".as_bytes()), name);
Sourcepub fn end(&self) -> i64
pub fn end(&self) -> i64
Return the 0-based, exclusive end position
§Example
let alleles: &[&[u8]] = &[b"AGG", b"TG"];
record.set_alleles(alleles).expect("Failed to set alleles");
record.set_pos(5);
assert_eq!(record.end(), 8)
Sourcepub fn id(&self) -> Vec<u8> ⓘ
pub fn id(&self) -> Vec<u8> ⓘ
Return the value of the ID column.
When empty, returns b".".to_vec()
.
Sourcepub fn push_id(&mut self, id: &[u8]) -> Result<()>
pub fn push_id(&mut self, id: &[u8]) -> Result<()>
Add the ID string (the ID field is semicolon-separated), checking for duplicates.
Sourcepub fn filters(&self) -> Filters<'_> ⓘ
pub fn filters(&self) -> Filters<'_> ⓘ
Return Filters
iterator for enumerating all filters that have been set.
A record having the PASS
filter will return an empty Filter
here.
Sourcepub fn has_filter<T: FilterId + ?Sized>(&self, flt_id: &T) -> bool
pub fn has_filter<T: FilterId + ?Sized>(&self, flt_id: &T) -> bool
Query whether the filter with the given ID has been set.
This method can be used to check if a record passes filtering by using either Id(0)
,
PASS
or .
§Example
let mut header = Header::new();
header.push_record(br#"##FILTER=<ID=foo,Description="sample is a foo fighter">"#);
assert!(record.has_filter("PASS".as_bytes()));
assert!(record.has_filter(".".as_bytes()));
assert!(record.has_filter(&Id(0)));
record.push_filter("foo".as_bytes()).unwrap();
assert!(record.has_filter("foo".as_bytes()));
assert!(!record.has_filter("PASS".as_bytes()))
Sourcepub fn set_filters<T: FilterId + ?Sized>(
&mut self,
flt_ids: &[&T],
) -> Result<()>
pub fn set_filters<T: FilterId + ?Sized>( &mut self, flt_ids: &[&T], ) -> Result<()>
Set the given filter IDs to the FILTER column.
Setting an empty slice removes all filters and sets PASS
.
§Example
let mut header = Header::new();
header.push_record(br#"##FILTER=<ID=foo,Description="sample is a foo fighter">"#);
header.push_record(br#"##FILTER=<ID=bar,Description="a horse walks into...">"#);
let foo = record.header().name_to_id(b"foo").unwrap();
let bar = record.header().name_to_id(b"bar").unwrap();
assert!(record.has_filter("PASS".as_bytes()));
let mut filters = vec![&foo, &bar];
record.set_filters(&filters).unwrap();
assert!(record.has_filter(&foo));
assert!(record.has_filter(&bar));
assert!(!record.has_filter("PASS".as_bytes()));
filters.clear();
record.set_filters(&filters).unwrap();
assert!(record.has_filter("PASS".as_bytes()));
assert!(!record.has_filter("foo".as_bytes()));
// 'baz' isn't in the header
assert!(record.set_filters(&["baz".as_bytes()]).is_err())
§Errors
If any of the filter IDs do not exist in the header, an Error::BcfUnknownID
is returned.
Sourcepub fn push_filter<T: FilterId + ?Sized>(&mut self, flt_id: &T) -> Result<()>
pub fn push_filter<T: FilterId + ?Sized>(&mut self, flt_id: &T) -> Result<()>
Add the given filter to the FILTER column.
If flt_id
is PASS
or .
then all existing filters are removed first. Otherwise,
any existing PASS
filter is removed.
§Example
let mut header = Header::new();
header.push_record(br#"##FILTER=<ID=foo,Description="sample is a foo fighter">"#);
header.push_record(br#"##FILTER=<ID=bar,Description="dranks">"#);
let foo = "foo".as_bytes();
let bar = record.header().name_to_id(b"bar").unwrap();
assert!(record.has_filter("PASS".as_bytes()));
record.push_filter(foo).unwrap();
record.push_filter(&bar).unwrap();
assert!(record.has_filter(foo));
assert!(record.has_filter(&bar));
// filter must exist in the header
assert!(record.push_filter("baz".as_bytes()).is_err())
§Errors
If the flt_id
does not exist in the header, an Error::BcfUnknownID
is returned.
Sourcepub fn remove_filter<T: FilterId + ?Sized>(
&mut self,
flt_id: &T,
pass_on_empty: bool,
) -> Result<()>
pub fn remove_filter<T: FilterId + ?Sized>( &mut self, flt_id: &T, pass_on_empty: bool, ) -> Result<()>
Remove the given filter from the FILTER column.
§Arguments
flt_id
- The corresponding filter ID to remove.pass_on_empty
- Set toPASS
when removing the last filter.
§Example
let mut header = Header::new();
header.push_record(br#"##FILTER=<ID=foo,Description="sample is a foo fighter">"#);
header.push_record(br#"##FILTER=<ID=bar,Description="a horse walks into...">"#);
let foo = "foo".as_bytes();
let bar = "bar".as_bytes();
record.set_filters(&[foo, bar]).unwrap();
assert!(record.has_filter(foo));
assert!(record.has_filter(bar));
record.remove_filter(foo, true).unwrap();
assert!(!record.has_filter(foo));
assert!(record.has_filter(bar));
// 'baz' is not in the header
assert!(record.remove_filter("baz".as_bytes(), true).is_err());
record.remove_filter(bar, true).unwrap();
assert!(!record.has_filter(bar));
assert!(record.has_filter("PASS".as_bytes()));
§Errors
If the flt_id
does not exist in the header, an Error::BcfUnknownID
is returned.
Sourcepub fn alleles(&self) -> Vec<&[u8]>
pub fn alleles(&self) -> Vec<&[u8]>
Get alleles strings.
The first allele is the reference allele.
Sourcepub fn set_alleles(&mut self, alleles: &[&[u8]]) -> Result<()>
pub fn set_alleles(&mut self, alleles: &[&[u8]]) -> Result<()>
Set alleles. The first allele is the reference allele.
§Example
assert_eq!(record.allele_count(), 0);
let alleles: &[&[u8]] = &[b"A", b"TG"];
record.set_alleles(alleles).expect("Failed to set alleles");
assert_eq!(record.allele_count(), 2)
pub fn info<'a>(&'a self, tag: &'a [u8]) -> Info<'a, Buffer>
Get the value of the given info tag.
Sourcepub fn sample_count(&self) -> u32
pub fn sample_count(&self) -> u32
Get the number of samples in the record.
Sourcepub fn allele_count(&self) -> u32
pub fn allele_count(&self) -> u32
Get the number of alleles, including reference allele.
Sourcepub fn push_genotypes(&mut self, genotypes: &[GenotypeAllele]) -> Result<()>
pub fn push_genotypes(&mut self, genotypes: &[GenotypeAllele]) -> Result<()>
Add/replace genotypes in FORMAT GT tag.
§Arguments
genotypes
- a flattened, two-dimensional array of GenotypeAllele, the first dimension contains one array for each sample.
§Errors
Returns error if GT tag is not present in header.
§Example
Example assumes we have a Record record
from a VCF with a GT
FORMAT
tag.
See module documentation for how to set up
VCF, header, and record.
let alleles = &[GenotypeAllele::Unphased(1), GenotypeAllele::Unphased(1)];
record.push_genotypes(alleles);
assert_eq!("1/1", &format!("{}", record.genotypes().unwrap().get(0)));
Sourcepub fn genotypes(&self) -> Result<Genotypes<'_, Buffer>>
pub fn genotypes(&self) -> Result<Genotypes<'_, Buffer>>
Get genotypes as vector of one Genotype
per sample.
§Example
Parsing genotype field (GT
tag) from a VCF record:
use crate::rust_htslib::bcf::{Reader, Read};
let mut vcf = Reader::from_path(&"test/test_string.vcf").expect("Error opening file.");
let expected = ["./1", "1|1", "0/1", "0|1", "1|.", "1/1"];
for (rec, exp_gt) in vcf.records().zip(expected.iter()) {
let mut rec = rec.expect("Error reading record.");
let genotypes = rec.genotypes().expect("Error reading genotypes");
assert_eq!(&format!("{}", genotypes.get(0)), exp_gt);
}
Get genotypes as vector of one Genotype
per sample, using a given shared buffer
to avoid unnecessary allocations.
Sourcepub fn format<'a>(&'a self, tag: &'a [u8]) -> Format<'a, Buffer>
pub fn format<'a>(&'a self, tag: &'a [u8]) -> Format<'a, Buffer>
Retrieve data for a FORMAT
field
§Example
Note: some boilerplate for the example is hidden for clarity. See module documentation for an example of the setup used here.
header.push_sample(b"sample1").push_sample(b"sample2").push_record(br#"##FORMAT=<ID=DP,Number=1,Type=Integer,Description="Read Depth">"#);
record.push_format_integer(b"DP", &[20, 12]).expect("Failed to set DP format field");
let read_depths = record.format(b"DP").integer().expect("Couldn't retrieve DP field");
let sample1_depth = read_depths[0];
assert_eq!(sample1_depth, &[20]);
let sample2_depth = read_depths[1];
assert_eq!(sample2_depth, &[12])
§Errors
Attention: the returned BufferBacked
from integer()
(read_depths
), which holds the data, has to be kept in scope as long as the data is
accessed. If parts of the data are accessed after the BufferBacked
object is been
dropped, you will access unallocated memory.
Get the value of the given format tag for each sample.
Sourcepub fn push_format_float(&mut self, tag: &[u8], data: &[f32]) -> Result<()>
pub fn push_format_float(&mut self, tag: &[u8], data: &[f32]) -> Result<()>
Add/replace a float-typed FORMAT tag.
§Arguments
tag
- The tag’s string.data
- a flattened, two-dimensional array, the first dimension contains one array for each sample.
§Errors
Returns error if tag is not present in header.
§Example
Example assumes we have a Record record
from a VCF with an AF
FORMAT
tag.
See module documentation for how to set up
VCF, header, and record.
record.push_format_float(b"AF", &[0.5]);
assert_eq!(0.5, record.format(b"AF").float().unwrap()[0][0]);
Sourcepub fn push_format_string<D: Borrow<[u8]>>(
&mut self,
tag: &[u8],
data: &[D],
) -> Result<()>
pub fn push_format_string<D: Borrow<[u8]>>( &mut self, tag: &[u8], data: &[D], ) -> Result<()>
Add a string-typed FORMAT tag. Note that genotypes are treated as a special case and cannot be added with this method. See instead push_genotypes.
§Arguments
tag
- The tag’s string.data
- a two-dimensional array, the first dimension contains one array for each sample. Must be non-empty.
§Errors
Returns error if tag is not present in header.
Sourcepub fn push_info_integer(&mut self, tag: &[u8], data: &[i32]) -> Result<()>
pub fn push_info_integer(&mut self, tag: &[u8], data: &[i32]) -> Result<()>
Add/replace an integer-typed INFO entry.
Sourcepub fn clear_info_integer(&mut self, tag: &[u8]) -> Result<()>
pub fn clear_info_integer(&mut self, tag: &[u8]) -> Result<()>
Remove the integer-typed INFO entry.
Sourcepub fn push_info_float(&mut self, tag: &[u8], data: &[f32]) -> Result<()>
pub fn push_info_float(&mut self, tag: &[u8], data: &[f32]) -> Result<()>
Add/replace a float-typed INFO entry.
Sourcepub fn clear_info_float(&mut self, tag: &[u8]) -> Result<()>
pub fn clear_info_float(&mut self, tag: &[u8]) -> Result<()>
Remove the float-typed INFO entry.
Sourcepub fn push_info_flag(&mut self, tag: &[u8]) -> Result<()>
pub fn push_info_flag(&mut self, tag: &[u8]) -> Result<()>
Set flag into the INFO column.
Sourcepub fn clear_info_flag(&mut self, tag: &[u8]) -> Result<()>
pub fn clear_info_flag(&mut self, tag: &[u8]) -> Result<()>
Remove the flag from the INFO column.
Sourcepub fn push_info_string(&mut self, tag: &[u8], data: &[&[u8]]) -> Result<()>
pub fn push_info_string(&mut self, tag: &[u8], data: &[&[u8]]) -> Result<()>
Add/replace a string-typed INFO entry.
Sourcepub fn clear_info_string(&mut self, tag: &[u8]) -> Result<()>
pub fn clear_info_string(&mut self, tag: &[u8]) -> Result<()>
Remove the string field from the INFO column.
Sourcepub fn trim_alleles(&mut self) -> Result<()>
pub fn trim_alleles(&mut self) -> Result<()>
Remove unused alleles.
pub fn remove_alleles(&mut self, remove: &[bool]) -> Result<()>
Sourcepub fn rlen(&self) -> i64
pub fn rlen(&self) -> i64
Get the length of the reference allele. If the record has no reference allele, then the
result will be 0
.
§Example
let alleles: &[&[u8]] = &[b"AGG", b"TG"];
record.set_alleles(alleles).expect("Failed to set alleles");
assert_eq!(record.rlen(), 3)
Sourcepub fn clear(&self)
pub fn clear(&self)
Clear all parts of the record. Useful if you plan to reuse a record object multiple times.
§Example
let alleles: &[&[u8]] = &[b"AGG", b"TG"];
record.set_alleles(alleles).expect("Failed to set alleles");
record.set_pos(6);
record.clear();
assert_eq!(record.rlen(), 0);
assert_eq!(record.pos(), 0)
Sourcepub fn desc(&self) -> String
pub fn desc(&self) -> String
Provide short description of record for locating it in the BCF/VCF file.
Sourcepub fn to_vcf_string(&self) -> Result<String>
pub fn to_vcf_string(&self) -> Result<String>
Convert to VCF String
Intended for debug only. Use Writer for efficient VCF output.