1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright 2014-2021 Johannes Köster.
// Copyright 2024-2026 Guilhem Zeitoun
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.
//! Rust-Htslib provides a high level API to working with the common HTS file formats.
//!
//! Htslib itself is the *de facto* standard implementation for reading and writing files for
//! HTS alignments (SAM and BAM) as well as variant calls in VCF and BCF format.
//!
//! For example, let's say that we use samtools to view the header of a test file:
//!
//! ```bash
//! samtools view -H test/test.bam
//! @SQ SN:CHROMOSOME_I LN:15072423
//! @SQ SN:CHROMOSOME_II LN:15279345
//! @SQ SN:CHROMOSOME_III LN:13783700
//! @SQ SN:CHROMOSOME_IV LN:17493793
//! @SQ SN:CHROMOSOME_V LN:20924149
//! ```
//!
//! We can reproduce that with Rust-Htslib. Reading BAM files and printing the header
//! to the screen is as easy as
//!
//! ```
//! use extended_htslib::{bam, bam::Read};
//!
//!
//! let bam = bam::Reader::from_path(&"test/test.bam").unwrap();
//! let header = bam::Header::from_template(bam.header());
//!
//! // print header records to the terminal, akin to samtool
//! for (key, records) in header.to_hashmap() {
//! for record in records {
//! println!("@{}\tSN:{}\tLN:{}", key, record["SN"], record["LN"]);
//! }
//! }
//! ```
//!
//! which results in the following output, equivalent to samtools.
//!
//! ```bash
//! @SQ SN:CHROMOSOME_I LN:15072423
//! @SQ SN:CHROMOSOME_II LN:15279345
//! @SQ SN:CHROMOSOME_III LN:13783700
//! @SQ SN:CHROMOSOME_IV LN:17493793
//! @SQ SN:CHROMOSOME_V LN:20924149
//! ```
//!
//! We can also read directly from the BAM file and write to an output file
//!
//! ```
//! use extended_htslib::{bam, bam::Read};
//!
//! let mut bam = bam::Reader::from_path(&"test/test.bam").unwrap();
//! let header = bam::Header::from_template(bam.header());
//! let mut out = bam::Writer::from_path(&"test/out.bam", &header, bam::Format::Bam).unwrap();
//!
//! // copy reverse reads to new BAM file
//! for r in bam.records() {
//! let record = r.unwrap();
//! if record.is_reverse() {
//! out.write(&record).unwrap();
//! }
//! }
//! ```
//!
//! Pileups can be performed with (requires a RegionString region):
//!
//! ```
//! use extended_htslib::{bam::{self,pileup}, bam::Read};
//!
//! let mut path = "test/test.bam";
//!
//! let config = pileup::RustPileupConfig::default();
//! let pos = bam::FetchDefinition::RegionString("CHROMOSOME_I".as_bytes(), 1, 100);
//! let config = pileup::RustPileupConfig::default();
//! let mut po = pileup::RustPileups::new(path, None, None, None, pos, config).unwrap();
//! for pileup in po {
//! println!("Pileup is {}", pileup.to_string());
//! println!("Base is {}",pileup.getbase());
//! }
//! ```
//!
//! In both cases, indexed BAM files can be seeked for specific regions using [`fetch`](bam/struct.IndexedReader.html#method.fetch), constraining either the record iterator or the pileups:
//!
//! ```
//! use extended_htslib::{bam, bam::Read};
//!
//! let mut bam = bam::IndexedReader::from_path(&"test/test.bam").unwrap();
//!
//! bam.fetch(("CHROMOSOME_I", 0, 20)).unwrap();
//! // afterwards, read or pileup in this region
//! ```
//!
//! See
//! * [`fetch`](bam/struct.IndexedReader.html#method.fetch)
//! * [`records`](bam/struct.IndexedReader.html#method.records)
//! * [`read`](bam/struct.IndexedReader.html#method.read)
//! * [`pileup`](bam/struct.IndexedReader.html#method.pileup)
extern crate custom_derive;
extern crate newtype_derive;
extern crate serde;
// <-- not needed in examples + integration tests
extern crate pretty_assertions;
extern crate serde_json;