]> git.donarmstrong.com Git - samtools.git/blob - sample.c
95bec6887c488deb7d270403a88b40903ce5fa94
[samtools.git] / sample.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include "sample.h"
4 #include "khash.h"
5 KHASH_MAP_INIT_STR(sm, int)
6
7 bam_sample_t *bam_smpl_init(void)
8 {
9         bam_sample_t *s;
10         s = calloc(1, sizeof(bam_sample_t));
11         s->rg2smid = kh_init(sm);
12         return s;
13 }
14
15 void bam_smpl_destroy(bam_sample_t *sm)
16 {
17         int i;
18         khint_t k;
19         khash_t(sm) *rg2smid = (khash_t(sm)*)sm->rg2smid;
20         if (sm == 0) return;
21         for (i = 0; i < sm->n; ++i) free(sm->smpl[i]);
22         free(sm->smpl);
23         for (k = kh_begin(rg2smid); k != kh_end(rg2smid); ++k)
24                 if (kh_exist(rg2smid, k)) free((char*)kh_key(rg2smid, k));
25         kh_destroy(sm, sm->rg2smid);
26         free(sm);
27 }
28
29 static void add_pair(bam_sample_t *sm, khash_t(sm) *sm2id, const char *key, const char *val)
30 {
31         khint_t k_rg, k_sm;
32         int ret;
33         khash_t(sm) *rg2smid = (khash_t(sm)*)sm->rg2smid;
34         k_rg = kh_get(sm, rg2smid, key);
35         if (k_rg != kh_end(rg2smid)) return; // duplicated @RG-ID
36         k_rg = kh_put(sm, rg2smid, strdup(key), &ret);
37         k_sm = kh_get(sm, sm2id, val);
38         if (k_sm == kh_end(sm2id)) { // absent
39                 if (sm->n == sm->m) {
40                         sm->m = sm->m? sm->m<<1 : 1;
41                         sm->smpl = realloc(sm->smpl, sizeof(void*) * sm->m);
42                 }
43                 sm->smpl[sm->n] = strdup(val);
44                 k_sm = kh_put(sm, sm2id, sm->smpl[sm->n], &ret);
45                 kh_val(sm2id, k_sm) = sm->n++;
46         }
47         kh_val(rg2smid, k_rg) = kh_val(sm2id, k_sm);
48 }
49
50 int bam_smpl_add(bam_sample_t *sm, const char *fn, const char *txt)
51 {
52         const char *p = txt, *q, *r;
53         kstring_t buf;
54         int n = 0;
55         khash_t(sm) *sm2id;
56         sm2id = kh_init(sm);
57         memset(&buf, 0, sizeof(kstring_t));
58         while ((q = strstr(p, "@RG")) != 0) {
59                 p = q + 3;
60                 r = q = 0;
61                 if ((q = strstr(p, "\tID:")) != 0) q += 4;
62                 if ((r = strstr(p, "\tSM:")) != 0) r += 4;
63                 if (r && q) {
64                         char *u, *v;
65                         int oq, or;
66                         for (u = (char*)q; *u && *u != '\t' && *u != '\n'; ++u);
67                         for (v = (char*)r; *v && *v != '\t' && *v != '\n'; ++v);
68                         oq = *u; or = *v; *u = *v = '\0';
69                         buf.l = 0; kputs(fn, &buf); kputc('/', &buf); kputs(q, &buf);
70                         add_pair(sm, sm2id, buf.s, r);
71                         *u = oq; *v = or;
72                 } else break;
73                 p = q > r? q : r;
74                 ++n;
75         }
76         if (n == 0) add_pair(sm, sm2id, fn, fn);
77         free(buf.s);
78         kh_destroy(sm, sm2id);
79         return 0;
80 }
81
82 int bam_smpl_rg2smid(const bam_sample_t *sm, const char *fn, const char *rg, kstring_t *str)
83 {
84         khint_t k;
85         khash_t(sm) *rg2smid = (khash_t(sm)*)sm->rg2smid;
86         if (rg) {
87                 str->l = 0;
88                 kputs(fn, str); kputc('/', str); kputs(rg, str);
89                 k = kh_get(sm, rg2smid, str->s);
90         } else k = kh_get(sm, rg2smid, fn);
91         return k == kh_end(rg2smid)? -1 : kh_val(rg2smid, k);
92 }