]> git.donarmstrong.com Git - fastq-tools.git/blob - src/fastq-qual.c
Much simpler faster code for parsing fastq files.
[fastq-tools.git] / src / fastq-qual.c
1
2 /*
3  * This file is part of fastq-tools.
4  *
5  * Copyright (c) 2011 by Daniel C. Jones <dcjones@cs.washington.edu>
6  *
7  * fastq-qual :
8  * Collect quality score statistics.
9  *
10  */
11
12 #include "common.h"
13 #include "parse.h"
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <getopt.h>
18
19
20 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
21 #  include <fcntl.h>
22 #  include <io.h>
23 #  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
24 #else
25 #  define SET_BINARY_MODE(file)
26 #endif
27
28 static const char* prog_name = "fastq-grep";
29
30 void print_help()
31 {
32     fprintf(stdout, 
33 "fastq-qual [OPTION]... [FILE]...\n"
34 "Output a tab-delimnated table such that row i, column j, given \n"
35 "the number of times that quality score i occured in read position j\n\n."
36 "Options:\n"
37 "  -h, --help              print this message\n"
38 "  -V, --version           output version information and exit\n");
39 }
40
41
42
43 void tally_quals(FILE* fin, unsigned int** xs, size_t* n)
44 {
45     seq_t* seq = seq_create();
46     fastq_t* fqf = fastq_create(fin);
47
48     size_t i;
49
50     while (fastq_read(fqf, seq)) {
51         if (seq->qual.n > *n) {
52             *xs = realloc_or_die(*xs, 255 * seq->qual.n * sizeof(unsigned int));
53             memset(*xs + *n, 0, 255 * (seq->qual.n - *n) * sizeof(unsigned int));
54             *n  = seq->qual.n;
55         }
56
57
58         for (i = 0; i < seq->qual.n; ++i) {
59             (*xs)[i * 255 + (int) seq->qual.s[i]] += 1;
60         }
61     }
62
63     seq_free(seq);
64     fastq_free(fqf);
65 }
66
67
68
69
70 void print_table(FILE* fout, unsigned int* xs, size_t n)
71 {
72     size_t i, j;
73
74     for (j = 0; j < 255; ++j) {
75         fprintf(fout, "%u", xs[j]);
76         for (i = 1; i < n; ++i) {
77             fprintf(fout, "\t%u", xs[i * 255 + j]);
78         }
79         fputc('\n', fout);
80     }
81 }
82
83
84
85 int main(int argc, char* argv[])
86 {
87     SET_BINARY_MODE(stdin);
88     SET_BINARY_MODE(stdout);
89
90     FILE* fin;
91
92     int opt;
93     int opt_idx;
94     static struct option long_options[] =
95         { 
96           {"help",    no_argument,    0, 'h'},
97           {"version", no_argument, 0, 'V'},
98           {0, 0, 0, 0}
99         };
100
101     while (1) {
102         opt = getopt_long(argc, argv, "hV", long_options, &opt_idx);
103
104         if( opt == -1 ) break;
105
106         switch (opt) {
107             case 'h':
108                 print_help();
109                 return 0;
110
111             case 'V':
112                 print_version(stdout, prog_name);
113                 return 0;
114
115             case '?':
116                 return 1;
117
118             default:
119                 abort();
120         }
121     }
122
123
124     size_t n = 0;
125     unsigned int* xs = NULL;
126
127     if (optind >= argc || (argc - optind == 1 && strcmp(argv[optind],"-") == 0)) {
128         tally_quals(stdin, &xs, &n);
129     }
130     else {
131         for (; optind < argc; optind++) {
132             fin = fopen(argv[optind], "rb");
133             if (fin == NULL) {
134                 fprintf(stderr, "No such file '%s'.\n", argv[optind]);
135                 continue;
136             }
137
138             tally_quals(fin, &xs, &n);
139         }
140     }
141
142     print_table(stdout, xs, n);
143
144     free(xs);
145
146     return 0;
147 }
148
149