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