]> git.donarmstrong.com Git - samtools.git/blobdiff - bam_plcmd.c
* samtools-0.1.8-21 (r780)
[samtools.git] / bam_plcmd.c
index 4bdc351e18a38322bd39dac30433aea3212b3b5a..6d42471c007a6b34d5b7b1db3ee535c974564839 100644 (file)
@@ -91,6 +91,21 @@ static khash_t(64) *load_pos(const char *fn, bam_header_t *h)
        return hash;
 }
 
+static inline int printw(int c, FILE *fp)
+{
+       char buf[16];
+       int l, x;
+       if (c == 0) return fputc('0', fp);
+       for (l = 0, x = c < 0? -c : c; x > 0; x /= 10) buf[l++] = x%10 + '0';
+       if (c < 0) buf[l++] = '-';
+       buf[l] = 0;
+       for (x = 0; x < l/2; ++x) {
+               int y = buf[x]; buf[x] = buf[l-1-x]; buf[l-1-x] = y;
+       }
+       fputs(buf, fp);
+       return 0;
+}
+
 // an analogy to pileup_func() below
 static int glt3_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pu, void *data)
 {
@@ -160,29 +175,38 @@ static int glt3_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pu,
        return 0;
 }
 
-static void pileup_seq(const bam_pileup1_t *p, int pos, int ref_len, const char *ref)
+static inline void pileup_seq(const bam_pileup1_t *p, int pos, int ref_len, const char *ref)
 {
-       if (p->is_head) printf("^%c", p->b->core.qual > 93? 126 : p->b->core.qual + 33);
+       int j;
+       if (p->is_head) {
+               putchar('^');
+               putchar(p->b->core.qual > 93? 126 : p->b->core.qual + 33);
+       }
        if (!p->is_del) {
-               int j, rb, c = bam_nt16_rev_table[bam1_seqi(bam1_seq(p->b), p->qpos)];
-               rb = (ref && pos < ref_len)? ref[pos] : 'N';
-               if (c == '=' || toupper(c) == toupper(rb)) c = bam1_strand(p->b)? ',' : '.';
-               else c = bam1_strand(p->b)? tolower(c) : toupper(c);
+               int c = bam_nt16_rev_table[bam1_seqi(bam1_seq(p->b), p->qpos)];
+               if (ref) {
+                       int rb = pos < ref_len? ref[pos] : 'N';
+                       if (c == '=' || bam_nt16_table[c] == bam_nt16_table[rb]) c = bam1_strand(p->b)? ',' : '.';
+                       else c = bam1_strand(p->b)? tolower(c) : toupper(c);
+               } else {
+                       if (c == '=') c = bam1_strand(p->b)? ',' : '.';
+                       else c = bam1_strand(p->b)? tolower(c) : toupper(c);
+               }
                putchar(c);
-               if (p->indel > 0) {
-                       printf("+%d", p->indel);
-                       for (j = 1; j <= p->indel; ++j) {
-                               c = bam_nt16_rev_table[bam1_seqi(bam1_seq(p->b), p->qpos + j)];
-                               putchar(bam1_strand(p->b)? tolower(c) : toupper(c));
-                       }
-               } else if (p->indel < 0) {
-                       printf("%d", p->indel);
-                       for (j = 1; j <= -p->indel; ++j) {
-                               c = (ref && (int)pos+j < ref_len)? ref[pos+j] : 'N';
-                               putchar(bam1_strand(p->b)? tolower(c) : toupper(c));
-                       }
+       } else putchar(p->is_refskip? (bam1_strand(p->b)? '<' : '>') : '*');
+       if (p->indel > 0) {
+               putchar('+'); printw(p->indel, stdout);
+               for (j = 1; j <= p->indel; ++j) {
+                       int c = bam_nt16_rev_table[bam1_seqi(bam1_seq(p->b), p->qpos + j)];
+                       putchar(bam1_strand(p->b)? tolower(c) : toupper(c));
                }
-       } else putchar('*');
+       } else if (p->indel < 0) {
+               printw(p->indel, stdout);
+               for (j = 1; j <= -p->indel; ++j) {
+                       int c = (ref && (int)pos+j < ref_len)? ref[pos+j] : 'N';
+                       putchar(bam1_strand(p->b)? tolower(c) : toupper(c));
+               }
+       }
        if (p->is_tail) putchar('$');
 }
 
@@ -256,22 +280,29 @@ static int pileup_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *p
                }
        }
        // print the first 3 columns
-       printf("%s\t%d\t%c\t", d->h->target_name[tid], pos + 1, rb);
+       fputs(d->h->target_name[tid], stdout); putchar('\t');
+       printw(pos+1, stdout); putchar('\t'); putchar(rb); putchar('\t');
        // print consensus information if required
-       if (d->format & BAM_PLF_CNS)
-               printf("%c\t%d\t%d\t%d\t", bam_nt16_rev_table[cns>>28], cns>>8&0xff, cns&0xff, cns>>16&0xff);
-       // print pileup sequences
-       printf("%d\t", n);
-       rms_aux = 0; // we need to recalculate rms_mapq when -c is not flagged on the command line
-       for (i = 0; i < n; ++i) {
-               const bam_pileup1_t *p = pu + i;
-               int tmp = p->b->core.qual < d->c->cap_mapQ? p->b->core.qual : d->c->cap_mapQ;
-               rms_aux += tmp * tmp;
-               pileup_seq(p, pos, d->len, d->ref);
+       if (d->format & BAM_PLF_CNS) {
+               putchar(bam_nt16_rev_table[cns>>28]); putchar('\t');
+               printw(cns>>8&0xff, stdout); putchar('\t');
+               printw(cns&0xff, stdout); putchar('\t');
+               printw(cns>>16&0xff, stdout); putchar('\t');
        }
+       // print pileup sequences
+       printw(n, stdout); putchar('\t');
+       for (i = 0; i < n; ++i)
+               pileup_seq(pu + i, pos, d->len, d->ref);
        // finalize rms_mapq
-       rms_aux = (uint64_t)(sqrt((double)rms_aux / n) + .499);
-       if (rms_mapq < 0) rms_mapq = rms_aux;
+       if (d->format & BAM_PLF_CNS) {
+               for (i = rms_aux = 0; i < n; ++i) {
+                       const bam_pileup1_t *p = pu + i;
+                       int tmp = p->b->core.qual < d->c->cap_mapQ? p->b->core.qual : d->c->cap_mapQ;
+                       rms_aux += tmp * tmp;
+               }
+               rms_aux = (uint64_t)(sqrt((double)rms_aux / n) + .499);
+               if (rms_mapq < 0) rms_mapq = rms_aux;
+       }
        putchar('\t');
        // print quality
        for (i = 0; i < n; ++i) {
@@ -310,7 +341,7 @@ static int pileup_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *p
                for (i = 0; i < n; ++i) {
                        int x = pu[i].qpos;
                        int l = pu[i].b->core.l_qseq;
-                       printf("%d,", x < l/2? x+1 : -((l-1)-x+1));
+                       printw(x < l/2? x+1 : -((l-1)-x+1), stdout); putchar(',');
                }
        }
        putchar('\n');