]> git.donarmstrong.com Git - fastq-tools.git/blob - src/fastq-qualadj.c
Much simpler faster code for parsing fastq files.
[fastq-tools.git] / src / fastq-qualadj.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-qualadj:
8  * Adjust quality scores by a given offset.
9  *
10  */
11
12
13 #include "common.h"
14 #include "parse.h"
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <getopt.h>
19 #include <zlib.h>
20
21
22 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
23 #  include <fcntl.h>
24 #  include <io.h>
25 #  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
26 #else
27 #  define SET_BINARY_MODE(file)
28 #endif
29
30
31 static const char* prog_name = "fastq-grep";
32
33 void print_help()
34 {
35     fprintf(stdout, 
36 "fastq-qualadj [OPTION]... OFFSET [FILE]...\n"
37 "The given offset is added to each and every quality score, where\n"
38 "the offset may be negative.\n"
39 "Options:\n"
40 "  -h, --help              print this message\n"
41 "  -V, --version           output version information and exit\n"
42     );
43 }
44
45 void fastq_qualadj(FILE* fin, FILE* fout, int offset)
46 {
47     fastq_t* fqf = fastq_create(fin);
48     seq_t* seq = seq_create();
49     size_t i;
50     int c;
51
52     while (fastq_read(fqf, seq)) {
53         for (i = 0; i < seq->qual.n; ++i) {
54             c = (int) seq->qual.s[i] + offset;
55             c = c < 0 ? 0 : (c > 126 ? 126: c);
56             seq->qual.s[i] = (char) c;
57         }
58
59         fastq_print(fout, seq);
60     }
61
62     seq_free(seq);
63     fastq_free(fqf);
64 }
65
66
67 int main(int argc, char* argv[])
68 {
69     SET_BINARY_MODE(stdin);
70     SET_BINARY_MODE(stdout);
71
72     char offset = 0;
73
74     static struct option long_options[] =
75         { 
76           {"help",         no_argument, NULL, 'h'},
77           {"version",      no_argument, NULL, 'V'},
78           {0, 0, 0, 0}
79         };
80
81     int opt;
82     int opt_idx;
83
84     char* tmp;
85     size_t tmplen;
86
87     while (1) {
88         opt = getopt_long(argc, argv, "hV0:1::2::3::4::5::6::7::8::9::", long_options, &opt_idx);
89
90         if (opt == -1) break;
91
92         switch(opt) {
93
94             /* this is a bit of a hack to prevent getopt from choking on
95              * negative numbers. */
96             case '0':
97             case '1':
98             case '2':
99             case '3':
100             case '4':
101             case '5':
102             case '6':
103             case '7':
104             case '8':
105             case '9':
106                 tmplen = 2;
107                 if (optarg) tmplen += strlen(optarg);
108                 tmp = malloc(tmplen + 1);
109
110                 if (optarg) snprintf(tmp, tmplen + 1, "-%c%s", (char) opt, optarg);
111                 else        snprintf(tmp, tmplen + 1, "-%c",   (char) opt);
112
113                 offset = atoi(tmp);
114                 free(tmp);
115                 break;
116
117
118             case 'h':
119                 print_help();
120                 return 0;
121
122             case 'V':
123                 print_version(stdout, prog_name);
124                 return 0;
125
126             case '?':
127                 return 1;
128
129             default:
130                 abort();
131         }
132     }
133
134     if (offset == 0 && optind >= argc) {
135         fprintf(stderr, "An offset must be specified.\n");
136         return 1;
137     }
138     else if (offset == 0) offset = atoi(argv[optind++]);
139
140     FILE* fin;
141
142     if (optind >= argc || (argc - optind == 1 && strcmp(argv[optind],"-") == 0)) {
143         fastq_qualadj(stdin, stdout, offset);
144     }
145     else {
146         for (; optind < argc; optind++) {
147             fin = fopen(argv[optind], "rb");
148             if (fin == NULL) {
149                 fprintf(stderr, "No such file '%s'.\n", argv[optind]);
150                 continue;
151             }
152
153             fastq_qualadj(fin, stdout, offset);
154
155             fclose(fin);
156         }
157     }
158
159     return 0;
160 }
161
162