Update debian changelog
[pysam.git] / samtools / bam_color.c.pysam.c
1 #include "pysam.h"
2
3 #include <ctype.h>
4 #include "bam.h"
5
6 /*!
7  @abstract     Get the color encoding the previous and current base
8  @param b      pointer to an alignment
9  @param i      The i-th position, 0-based
10  @return       color
11
12  @discussion   Returns 0 no color information is found.
13  */
14 char bam_aux_getCSi(bam1_t *b, int i)
15 {
16         uint8_t *c = bam_aux_get(b, "CS");
17         char *cs = NULL;
18
19         // return the base if the tag was not found
20         if(0 == c) return 0;
21
22         cs = bam_aux2Z(c);
23         // adjust for strandedness and leading adaptor
24         if(bam1_strand(b)) i = strlen(cs) - 1 - i;
25         else i++;
26         return cs[i];
27 }
28
29 /*!
30  @abstract     Get the color quality of the color encoding the previous and current base
31  @param b      pointer to an alignment
32  @param i      The i-th position, 0-based
33  @return       color quality
34
35  @discussion   Returns 0 no color information is found.
36  */
37 char bam_aux_getCQi(bam1_t *b, int i)
38 {
39         uint8_t *c = bam_aux_get(b, "CQ");
40         char *cq = NULL;
41         
42         // return the base if the tag was not found
43         if(0 == c) return 0;
44
45         cq = bam_aux2Z(c);
46         // adjust for strandedness
47         if(bam1_strand(b)) i = strlen(cq) - 1 - i;
48         return cq[i];
49 }
50
51 char bam_aux_nt2int(char a)
52 {
53         switch(toupper(a)) {
54                 case 'A':
55                         return 0;
56                         break;
57                 case 'C':
58                         return 1;
59                         break;
60                 case 'G':
61                         return 2;
62                         break;
63                 case 'T':
64                         return 3;
65                         break;
66                 default:
67                         return 4;
68                         break;
69         }
70 }
71
72 char bam_aux_ntnt2cs(char a, char b)
73 {
74         a = bam_aux_nt2int(a);
75         b = bam_aux_nt2int(b);
76         if(4 == a || 4 == b) return '4';
77         return "0123"[(int)(a ^ b)];
78 }
79
80 /*!
81  @abstract     Get the color error profile at the give position    
82  @param b      pointer to an alignment
83  @return       the original color if the color was an error, '-' (dash) otherwise
84
85  @discussion   Returns 0 no color information is found.
86  */
87 char bam_aux_getCEi(bam1_t *b, int i)
88 {
89         int cs_i;
90         uint8_t *c = bam_aux_get(b, "CS");
91         char *cs = NULL;
92         char prev_b, cur_b;
93         char cur_color, cor_color;
94
95         // return the base if the tag was not found
96         if(0 == c) return 0;
97         
98         cs = bam_aux2Z(c);
99
100         // adjust for strandedness and leading adaptor
101         if(bam1_strand(b)) { //reverse strand
102                 cs_i = strlen(cs) - 1 - i;
103                 // get current color
104                 cur_color = cs[cs_i];
105                 // get previous base.  Note: must rc adaptor
106                 prev_b = (cs_i == 1) ? "TGCAN"[(int)bam_aux_nt2int(cs[0])] : bam_nt16_rev_table[bam1_seqi(bam1_seq(b), i+1)];
107                 // get current base
108                 cur_b = bam_nt16_rev_table[bam1_seqi(bam1_seq(b), i)]; 
109         }
110         else {
111                 cs_i=i+1;
112                 // get current color
113                 cur_color = cs[cs_i];
114                 // get previous base
115                 prev_b = (0 == i) ? cs[0] : bam_nt16_rev_table[bam1_seqi(bam1_seq(b), i-1)];
116                 // get current base
117                 cur_b = bam_nt16_rev_table[bam1_seqi(bam1_seq(b), i)];
118         }
119
120         // corrected color
121         cor_color = bam_aux_ntnt2cs(prev_b, cur_b);
122
123         if(cur_color == cor_color) { 
124                 return '-';
125         }
126         else {
127                 return cur_color;
128         }
129 }