]> git.donarmstrong.com Git - samtools.git/blob - bam_aux.c
* samtools-0.1.3-2 (r239)
[samtools.git] / bam_aux.c
1 #include <ctype.h>
2 #include "bam.h"
3 #include "khash.h"
4 KHASH_MAP_INIT_STR(s, int)
5
6 uint8_t *bam_aux_get(bam1_t *b, const char tag[2])
7 {
8         uint8_t *s;
9         int y = tag[0]<<8 | tag[1];
10         s = bam1_aux(b);
11         while (s < b->data + b->data_len) {
12                 int type, x = (int)s[0]<<8 | s[1];
13                 s += 2;
14                 if (x == y) return s;
15                 type = toupper(*s); ++s;
16                 if (type == 'C') ++s;
17                 else if (type == 'S') s += 2;
18                 else if (type == 'I' || type == 'F') s += 4;
19                 else if (type == 'D') s += 8;
20                 else if (type == 'Z' || type == 'H') { while (*s) putchar(*s++); ++s; }
21         }
22         return 0;
23 }
24
25 void bam_init_header_hash(bam_header_t *header)
26 {
27         if (header->hash == 0) {
28                 int ret, i;
29                 khiter_t iter;
30                 khash_t(s) *h;
31                 header->hash = h = kh_init(s);
32                 for (i = 0; i < header->n_targets; ++i) {
33                         iter = kh_put(s, h, header->target_name[i], &ret);
34                         kh_value(h, iter) = i;
35                 }
36         }
37 }
38
39 void bam_destroy_header_hash(bam_header_t *header)
40 {
41         if (header->hash)
42                 kh_destroy(s, (khash_t(s)*)header->hash);
43 }
44
45 int32_t bam_get_tid(const bam_header_t *header, const char *seq_name)
46 {
47         khint_t k;
48         khash_t(s) *h = (khash_t(s)*)header->hash;
49         k = kh_get(s, h, seq_name);
50         return k == kh_end(h)? -1 : kh_value(h, k);
51 }
52
53 void bam_parse_region(bam_header_t *header, const char *str, int *ref_id, int *begin, int *end)
54 {
55         char *s, *p;
56         int i, l, k;
57         khiter_t iter;
58         khash_t(s) *h;
59
60         bam_init_header_hash(header);
61         h = (khash_t(s)*)header->hash;
62         
63         l = strlen(str);
64         p = s = (char*)malloc(l+1);
65         /* squeeze out "," */
66         for (i = k = 0; i != l; ++i)
67                 if (str[i] != ',' && !isspace(str[i])) s[k++] = str[i];
68         s[k] = 0;
69         for (i = 0; i != k; ++i) if (s[i] == ':') break;
70         s[i] = 0;
71         iter = kh_get(s, h, s); /* get the ref_id */
72         if (iter == kh_end(h)) { // name not found
73                 *ref_id = -1; free(s);
74                 return;
75         }
76         *ref_id = kh_value(h, iter);
77         if (i == k) { /* dump the whole sequence */
78                 *begin = 0; *end = 1<<29; free(s);
79                 return;
80         }
81         for (p = s + i + 1; i != k; ++i) if (s[i] == '-') break;
82         *begin = atoi(p);
83         if (i < k) {
84                 p = s + i + 1;
85                 *end = atoi(p);
86         } else *end = 1<<29;
87         if (*begin > 0) --*begin;
88         assert(*begin <= *end);
89         free(s);
90 }
91
92 int32_t bam_aux2i(const uint8_t *s)
93 {
94         int type;
95         if (s == 0) return 0;
96         type = *s++;
97         if (type == 'c') return (int32_t)*(int8_t*)s;
98         else if (type == 'C') return (int32_t)*(uint8_t*)s;
99         else if (type == 's') return (int32_t)*(int16_t*)s;
100         else if (type == 'S') return (int32_t)*(uint16_t*)s;
101         else if (type == 'i' || type == 'I') return *(int32_t*)s;
102         else return 0;
103 }
104
105 float bam_aux2f(const uint8_t *s)
106 {
107         int type;
108         type = *s++;
109         if (s == 0) return 0.0;
110         if (type == 'f') return *(float*)s;
111         else return 0.0;
112 }
113
114 double bam_aux2d(const uint8_t *s)
115 {
116         int type;
117         type = *s++;
118         if (s == 0) return 0.0;
119         if (type == 'd') return *(double*)s;
120         else return 0.0;
121 }
122
123 char bam_aux2A(const uint8_t *s)
124 {
125         int type;
126         type = *s++;
127         if (s == 0) return 0;
128         if (type == 'A') return *(char*)s;
129         else return 0;
130 }
131
132 char *bam_aux2Z(const uint8_t *s)
133 {
134         int type;
135         type = *s++;
136         if (s == 0) return 0;
137         if (type == 'Z' || type == 'H') return (char*)s;
138         else return 0;
139 }