2 * This file is part of fastq-tools.
4 * Copyright (c) 2011 by Daniel C. Jones <dcjones@cs.washington.edu>
6 * This is a very simple, 'fast enough' implementation of the Smith-Waterman
7 * algorithm specifically for short nucleotide sequences, working in O(mn) time
8 * and O(m) space, implemented according to the original Gotoh paper and
9 * Phil Green's implementation in cross_match.
11 * There is no fancy bit packing or vectorization, but such features would offer
12 * diminishing returns when aligning short sequences such as high throughput
13 * sequencing data. For example the Farrar SSE2 algorithm might be a tiny bit
14 * faster, but would diminish portability.
20 #include "fastq-common.h"
25 static const int sw_default_d[25] =
33 static const int sw_mat50_d[25] =
40 static const int sw_mat70_d[25] =
48 static inline int imax(int a, int b)
53 static inline int imax4(int a, int b, int c, int d)
55 return imax(imax(a,b), imax(c,d));
60 void fastq_sw_conv_seq(unsigned char* seq, int n)
97 sw_t* fastq_alloc_sw(const unsigned char* subject, int size)
99 sw_t* sw = malloc_or_die(sizeof(sw_t));
100 memcpy(sw->subject, subject, size);
102 /* default cost matrix */
103 memcpy(sw->d, sw_default_d, 25 * sizeof(int));
105 /* default gap costs */
109 sw->work0 = malloc_or_die(size * sizeof(int));
110 sw->work1 = malloc_or_die(size * sizeof(int));
117 void fastq_free_sw(sw_t* sw)
127 int fastq_sw(sw_t* sw, const unsigned char* x, int n)
129 /*const int max_score = 65535;*/
132 int* maxstu = sw->work0;
135 const int* d = sw->d;
136 int gap_op = sw->gap_open;
137 int gap_ex = sw->gap_extend;
138 unsigned char* y = sw->subject;
142 /* zero maxstu row */
143 memset(maxstu, 0, m * sizeof(int));
145 /* initialize t row to a negative value to prohibit
146 * leading with gap extensions */
147 for (j = 0; j < m; j++) t[j] = -1;
152 for (i = 0; i < n; i++) {
154 /* special case for column 0 */
155 t[j] = imax(maxstu[j] + gap_op, t[j] + gap_ex);
157 maxstu[0] = imax4(0, d[5 * y[j] + x[j]], t[j], u);
161 for (j = 1; j < m; j++) {
162 t[j] = imax(maxstu[j] + gap_op, t[j] + gap_ex);
163 u = imax(maxstu[j-1] + gap_op, u + gap_ex);
164 s = maxstu0 + d[5 * y[j] + x[i]];
167 maxstu[j] = imax4(0, s, t[j], u);
171 /* return maximum from maxstu */
173 for (j = 0; j <m; j++) maxstu0 = imax(maxstu0, maxstu[j]);