/usr/include/anfo/trim.h is in libanfo0-dev 0.98-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | // Copyright 2009 Udo Stenzel
// This file is part of ANFO
//
// ANFO is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Anfo is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Anfo. If not, see <http://www.gnu.org/licenses/>.
#ifndef INCLUDED_TRIM_H
#define INCLUDED_TRIM_H
#include <algorithm>
#include <vector>
#include "sequence.h"
namespace {
template< typename T > T max3( T a, T b, T c )
{ return std::max( std::max( a, b ), c ) ; }
}
inline bool match( char a, char b ) { return to_ambicode(a) & to_ambicode(b) ; }
inline bool match( Ambicode a, char b ) { return a & to_ambicode(b) ; }
inline bool match( char a, Ambicode b ) { return to_ambicode(a) & b ; }
inline bool match( Ambicode a, Ambicode b ) { return a & b ; }
inline bool match( const QSequence::Base &a, char b ) { return a.ambicode & to_ambicode(b) ; }
inline bool match( char a, const QSequence::Base &b ) { return to_ambicode(a) & b.ambicode ; }
/*! \brief aligns two sequences to find an adapter sequence.
The alignment algorithm following Eugene W. Myers: "An O(ND)
Difference Algorithm and Its Variations", adapted to 'overlap
alignment'.
We want to align two sequences so they overlap with maximum score.
This is not possible with the plain "minimum distance" method, since
no overlap always results in the minimum distance of zero. We do
need to score the overlapping part, but not the same as an ordinary
difference. Now suppose you have an alignment:
xxxxxx--
--yyyyzz
It scores (k * mat/2 - d * (mat-mis)), where k is |x|+|y| (see the
megablast paper by Zhang for an explanation; we stop keeping score
once we reach the end of x). Suppose x is longer:
xxxxxxx--
---yyyyzzz
This scores ((k+1) * mat/2 - (d+D) * (mat-mis)), and we want to set
D such that this is the same as before. This gives:
D = 1/2 * mat / (mat-mis)
and for typical parameters mat=1 and mis=-3 it equals D=1/8.
Therefore, end gaps should score 1/8 (but not for local alignments
(not implemented here), where only an X-drop algorithm would be
appropriate).
To implement this, the following changes to the original algorithm
are necessary:
- allow a start gap that grows 8x quicker than a normal gap,
consider the many more involved diagonals,
- once finished, prefer alignments on lower numbered diagonals.
This function will try to overlap the left end of sequence A (query
sequence) with the right end of sequence B (adapter sequence).
(Typical adapter trimming therefore requires the sequences to be
passed in in reverse.) It returns the score of the resulting
alignment, which will be positive, or -1 if the alignment would be
too bad. The number of characters in sequence A that are overlapped
is returned in *yout.
\param seq_a iterator to beginning of sequence A.
\param seq_a_end iterator to end of sequence A.
\param seq_b iterator to beginning of sequence B.
\param seq_b_end iterator to end of sequence B.
\param yout pointer to location where number of trimmed chars is stores.
\return alignment score.
*/
template< typename A, typename B >
int overlap_align( A seq_a, A seq_a_end, B seq_b, B seq_b_end, int*yout )
{
static const int discount = 8 ;
using namespace std ;
int len_a = seq_a_end - seq_a ;
int len_b = seq_b_end - seq_b ;
int maxd = 2 * len_b / discount ; // makes sure that score>=0
int dim = discount*maxd + discount-1 ;
vector<int> v_d( dim+maxd+1 ), v_dm1( dim+maxd+1 ) ; // v[d] & v[d-1]
for( int d = 0 ; d != maxd ; ++d, swap( v_d, v_dm1 ) ) { // D-paths in order of increasing D
int dm = discount*d + discount-1 ;
for( int k = -d ; k <= dm ; ++k ) { // diagonals
int x = 0 == d ? k :
1 == d && 0 == k ? v_dm1[ k +maxd ]+1 :
k == -d ? v_dm1[ k+1 +maxd ] :
k > dm-discount+1 ? k :
k == -d+1 ? max( v_dm1[ k +maxd ]+1, v_dm1[ k+1 +maxd ] ) :
k == dm-discount+1 ? max( v_dm1[ k-1 +maxd ]+1, k ) :
k == dm-discount ? max3( v_dm1[ k-1 +maxd ]+1, v_dm1[ k +maxd ]+1, k ) :
max3( v_dm1[ k-1 +maxd ]+1, v_dm1[ k +maxd ]+1, v_dm1[ k+1 +maxd ] ) ;
int y = x - k ;
while( x < len_b && y < len_a && match( seq_b[x], seq_a[y] ) ) ++x, ++y ;
v_d[ k +maxd ] = x ;
if( x == len_b )
{
*yout = y ;
return x + y - discount * d ; // computes score.
}
}
}
return -1 ;
}
#endif
|