1 /*  bcftools.h -- utility function declarations.
2 
3     Copyright (C) 2013-2021 Genome Research Ltd.
4 
5     Author: Petr Danecek <pd3@sanger.ac.uk>
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 THE SOFTWARE.  */
24 
25 #ifndef BCFTOOLS_H
26 #define BCFTOOLS_H
27 
28 #include <stdarg.h>
29 #include <htslib/hts_defs.h>
30 #include <htslib/vcf.h>
31 #include <math.h>
32 
33 #define FT_TAB_TEXT 0       // custom tab-delimited text file
34 #define FT_GZ 1
35 #define FT_VCF 2
36 #define FT_VCF_GZ (FT_GZ|FT_VCF)
37 #define FT_BCF (1<<2)
38 #define FT_BCF_GZ (FT_GZ|FT_BCF)
39 #define FT_STDIN (1<<3)
40 
41 char *bcftools_version(void);
42 
43 /// Report an error and exit -1
44 void error(const char *format, ...) HTS_NORETURN HTS_FORMAT(HTS_PRINTF_FMT, 1, 2);
45 
46 /// Report an error and exit -1.  If errno != 0, appends strerror(errno).
47 //  Note: unlike error() above, the message should not end with "\n" as a
48 //  newline will be added by the function.
49 void error_errno(const char *format, ...) HTS_NORETURN HTS_FORMAT(HTS_PRINTF_FMT, 1, 2);
50 
51 void bcf_hdr_append_version(bcf_hdr_t *hdr, int argc, char **argv, const char *cmd);
52 const char *hts_bcf_wmode(int file_type);
53 const char *hts_bcf_wmode2(int file_type, char *fname);
54 void set_wmode(char dst[8], int file_type, char *fname, int compression_level);  // clevel: 0-9 with or zb type, -1 unset
55 char *init_tmp_prefix(const char *prefix);
56 
57 void *smalloc(size_t size);     // safe malloc
58 
iupac2bitmask(char iupac)59 static inline int iupac2bitmask(char iupac)
60 {
61     const int A = 1;
62     const int C = 2;
63     const int G = 4;
64     const int T = 8;
65     if ( iupac >= 97 ) iupac -= 32;
66     if ( iupac == 'A' ) return A;
67     if ( iupac == 'C' ) return C;
68     if ( iupac == 'G' ) return G;
69     if ( iupac == 'T' ) return T;
70     if ( iupac == 'M' ) return A|C;
71     if ( iupac == 'R' ) return A|G;
72     if ( iupac == 'W' ) return A|T;
73     if ( iupac == 'S' ) return C|G;
74     if ( iupac == 'Y' ) return C|T;
75     if ( iupac == 'K' ) return G|T;
76     if ( iupac == 'V' ) return A|C|G;
77     if ( iupac == 'H' ) return A|C|T;
78     if ( iupac == 'D' ) return A|G|T;
79     if ( iupac == 'B' ) return C|G|T;
80     if ( iupac == 'N' ) return A|C|G|T;
81     return -1;
82 }
bitmask2iupac(int bitmask)83 static inline char bitmask2iupac(int bitmask)
84 {
85     const char iupac[16] = {'.','A','C','M','G','R','S','V','T','W','Y','H','K','D','B','N'};
86     if ( bitmask <= 0 || bitmask > 15 ) return 0;
87     return iupac[bitmask];
88 }
89 
iupac_consistent(char iupac,char nt)90 static inline int iupac_consistent(char iupac, char nt)
91 {
92     static const char iupac_mask[90] = {
93         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
94         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
95         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,14,2,
96         13,0,0,4,11,0,0,12,0,3,15,0,0,0,5,6,8,0,7,9,0,10
97     };
98     if ( iupac > 89 ) return 0;
99     if ( nt > 90 ) nt -=  32;  // lowercase
100     if ( nt=='A' ) nt = 1;
101     else if ( nt=='C' ) nt = 2;
102     else if ( nt=='G' ) nt = 4;
103     else if ( nt=='T' ) nt = 8;
104     return iupac_mask[(int)iupac] & nt ? 1 : 0;
105 }
106 
nt_to_upper(char nt)107 static inline char nt_to_upper(char nt)
108 {
109     if ( nt < 97 ) return nt;
110     return nt - 32;
111 }
112 
phred_score(double prob)113 static inline double phred_score(double prob)
114 {
115     if ( prob==0 ) return 99;
116     prob = -4.3429*log(prob);
117     return prob>99 ? 99 : prob;
118 }
119 
120 static const uint64_t bcf_double_missing    = 0x7ff0000000000001;
121 static const uint64_t bcf_double_vector_end = 0x7ff0000000000002;
bcf_double_set(double * ptr,uint64_t value)122 static inline void bcf_double_set(double *ptr, uint64_t value)
123 {
124     union { uint64_t i; double d; } u;
125     u.i = value;
126     *ptr = u.d;
127 }
bcf_double_test(double d,uint64_t value)128 static inline int bcf_double_test(double d, uint64_t value)
129 {
130     union { uint64_t i; double d; } u;
131     u.d = d;
132     return u.i==value ? 1 : 0;
133 }
134 #define bcf_double_set_vector_end(x) bcf_double_set(&(x),bcf_double_vector_end)
135 #define bcf_double_set_missing(x)    bcf_double_set(&(x),bcf_double_missing)
136 #define bcf_double_is_vector_end(x)  bcf_double_test((x),bcf_double_vector_end)
137 #define bcf_double_is_missing(x)     bcf_double_test((x),bcf_double_missing)
138 #define bcf_double_is_missing_or_vector_end(x)     (bcf_double_test((x),bcf_double_missing) || bcf_double_test((x),bcf_double_vector_end))
139 
140 #endif
141