1 /**
2 
3 SAMRecord and SAMFile are wrappers for htslib functions relating to SAM/BAM/CRAM* files
4 
5 SAMRecord is a structured representation of a SAM/BAM/CRAM* record,
6 backed internally by htslib's bam1_t, but with convenient getters and setters
7 for record attributes, including functions not included in vanilla htslib 
8 like returning the sequence or the qscore string (NB: actually char*)
9 
10 SAMFile is a structured representation of SAM/BAM/CRAM* file,
11 backed internally by htslib's htsFile and bam_hdr_t,
12 but with convenient getters and setters for file and header attributes,
13 as well as query functions accessible explicitly (`query("chr1:999-9999"`)
14 and by indexing (`samfile["chr1", 999 .. 9999]`).
15 The file object can be iterated as an InputRange to obtain every record in the file.
16 
17 Authors: James S Blachly, MD <james.blachly@gmail.com> ; Thomas Gregory <charles.gregory@osumc.edu>
18 
19 Bugs: SAMRecord and SAMFile function only as readers, rather than writers (i.e, cannot build SAMFile)
20 Bugs: (*CRAM functionality is limited and untested)
21 
22 Date: 2020-09-12
23 
24 License: Apache 2.0
25 
26 Standards: Sequence Alignment/Map Format Specification v1 14 Dec 2018 http://samtools.github.io/hts-specs/
27 
28 */
29 module dhtslib.sam;
30 
31 public import dhtslib.sam.header;
32 public import dhtslib.sam.record;
33 public import dhtslib.sam.cigar;
34 public import dhtslib.sam.md;
35 public import dhtslib.sam.tagvalue;
36 public import dhtslib.sam.reader;
37 public import dhtslib.sam.writer;
38 
39 import htslib.sam;
40 import htslib.hts : hts_reglist_t, hts_pair32_t;
41 
42 
43 /// Used in sorting
44 bool cmpInterval(hts_pair32_t a, hts_pair32_t b)
45 {
46     if (a.beg < b.beg)
47     {
48         return true;
49     }
50     if (a.end < b.end)
51     {
52         return true;
53     }
54     return false;
55 }
56 
57 /// Used in sorting
58 bool cmpRegList(hts_reglist_t a, hts_reglist_t b)
59 {
60     if (a.tid < b.tid)
61     {
62         return true;
63     }
64     return false;
65 }
66 
67 /// Parse text line of SAM; Used in unittest
68 int parseSam(string line, bam_hdr_t* header, bam1_t* b)
69 {
70     import htslib.kstring : kstring_t;
71     import std.utf : toUTFz;
72 
73     kstring_t k;
74     k.s = toUTFz!(char*)(line.dup);
75     k.m = line.length + 1;
76     k.l = line.length + 1;
77     return sam_parse1(&k, header, b);
78 }
79 
80 /// Nucleotide complement table; from samtools/sam_view.c
81 private const(char)[16] seq_comp_table = [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15];
82 
83 /// Reverse a string in place; from samtools/sam_view.c
84 //  TODO: Could be sped up, and potentially made safer? by passing strlen since already known
85 private char* reverse(char* str)
86 {
87     import core.stdc.string : strlen;
88 
89     auto i = strlen(str) - 1, j = 0;
90     char ch;
91     while (i > j)
92     {
93         ch = str[i];
94         str[i] = str[j];
95         str[j] = ch;
96         i--;
97         j++;
98     }
99     return str;
100 }
101