source: branches/ralph/src/main/java/de/ugoe/cs/autoquest/tasktrees/alignment/algorithms/SmithWatermanRepeated.java @ 1558

Last change on this file since 1558 was 1558, checked in by rkrimmel, 10 years ago

new Smith waterman variant

File size: 6.4 KB
Line 
1package de.ugoe.cs.autoquest.tasktrees.alignment.algorithms;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import de.ugoe.cs.autoquest.tasktrees.alignment.substitution.SubstitutionMatrix;
7
8public class SmithWatermanRepeated implements Alignment {
9
10        /**
11         * The first input
12         */
13        private int[] input1;
14
15        /**
16         * The second input String
17         */
18        private int[] input2;
19
20        /**
21         * The lengths of the input
22         */
23        private int length1, length2;
24
25        /**
26         * The score matrix. The true scores should be divided by the normalization
27         * factor.
28         */
29        private MatrixEntry[][] matrix;
30
31       
32       
33        private float scoreThreshold;
34
35        /**
36         * Substitution matrix to calculate scores
37         */
38        private SubstitutionMatrix submat;
39
40        public SmithWatermanRepeated(int[] input1, int[] input2, SubstitutionMatrix submat,float threshold) {
41                this.input1 = input1;
42                this.input2 = input2;
43                length1 = input1.length;
44                length2 = input2.length;
45                this.submat = submat;
46
47                //System.out.println("Starting SmithWaterman algorithm with a "
48                //              + submat.getClass() + " Substitution Matrix: " + submat.getClass().getCanonicalName());
49                this.scoreThreshold = threshold;
50               
51                matrix = new MatrixEntry[length1+2][length2+1];
52               
53                for (int i = 0; i <= length1; i++) {
54                        for(int j = 0; j< length2; j++) {
55                                matrix[i][j] = new MatrixEntry();
56                        }
57                }
58       
59
60                buildMatrix();
61        }
62
63        /**
64         * Compute the similarity score of substitution The position of the first
65         * character is 1. A position of 0 represents a gap.
66         *
67         * @param i
68         *            Position of the character in str1
69         * @param j
70         *            Position of the character in str2
71         * @return Cost of substitution of the character in str1 by the one in str2
72         */
73        private float similarity(int i, int j) {
74                if (i == 0 || j == 0) {
75                        // it's a gap
76                        return submat.getGapPenalty();
77                }
78                // System.out.println("Diag letters: " + input1[i-1] + " " +
79                // input2[j-1]);
80                // return (input1[i - 1] == input2[j - 1]) ? MATCH_SCORE :
81                // MISMATCH_SCORE;
82                return submat.getDistance(input1[i - 1], input2[j - 1]);
83        }
84
85        /**
86         * Build the score matrix using dynamic programming. Note: The indel scores
87         * must be negative. Otherwise, the part handling the first row and column
88         * has to be modified.
89         */
90        private void buildMatrix() {
91                if (submat.getGapPenalty() >= 0) {
92                        throw new Error("Indel score must be negative");
93                }
94               
95
96                // base case
97                matrix[0][0].setScore(0);
98                matrix[0][0].setPrevious(null); // starting point
99
100                // the first column
101                for (int j = 1; j < length2; j++) {
102                        matrix[0][j].setScore(0);
103                        matrix[0][j].setPrevious(matrix[0][j-1]);
104                       
105                }
106               
107               
108               
109                for (int i = 1; i <= length1; i++) {
110               
111                        // Formula for first row:
112                        // F(i,0) = max { F(i-1,0), F(i-1,j)-T  j=1,...,m
113                       
114                        float firstRowLeftScore = matrix[i-1][0].getScore();
115                        float tempMax = matrix[i-1][1].getScore();
116                       
117                        //position of the maximal score of the previous row
118                        int maxRowIndex = 1;
119                       
120                        for(int j = 2; j < length2;j++) {
121                                if(matrix[i-1][j].getScore() > tempMax) {
122                                        tempMax = matrix[i-1][j].getScore();
123                                        maxRowIndex = j;
124                                }
125                        }
126                       
127                        tempMax -= scoreThreshold;
128                        matrix[i][0].setScore(Math.max(firstRowLeftScore, tempMax));
129                       
130                       
131                        for (int j = 1; j < length2; j++) {
132                                float diagScore = matrix[i - 1][j - 1].getScore() + similarity(i, j);
133                                float upScore = matrix[i][j - 1].getScore() + similarity(0, j);
134                                float leftScore = matrix[i - 1][j].getScore() + similarity(i, 0);
135
136                                matrix[i][j].setScore(Math.max(diagScore,Math.max(upScore, Math.max(leftScore,matrix[i][0].getScore()))));
137
138                                // find the directions that give the maximum scores.
139                                // Multiple directions are ignored TODO
140                                if (diagScore == matrix[i][j].getScore()) {
141                                        matrix[i][j].setPrevious(matrix[i-1][j-1]);
142                                }
143                                if (leftScore == matrix[i][j].getScore()) {
144                                        matrix[i][j].setPrevious(matrix[i-1][j]);
145                                }
146                                if (upScore == matrix[i][j].getScore()) {
147                                        matrix[i][j].setPrevious(matrix[i][j-1]);
148                                }
149                                if (matrix[i][0].getScore() == matrix[i][j].getScore()) {
150                                        matrix[i][j].setPrevious(matrix[i-1][maxRowIndex]);
151                                }
152                        }
153                }
154        }
155
156        /**
157         * Get the maximum value in the score matrix.
158         */
159        public double getMaxScore() {
160                double maxScore = 0;
161
162                // skip the first row and column
163                for (int i = 1; i <= length1; i++) {
164                        for (int j = 1; j < length2; j++) {
165                                if (matrix[i][j].getScore() > maxScore) {
166                                        maxScore = matrix[i][j].getScore();
167                                }
168                        }
169                }
170
171                return maxScore;
172        }
173
174        /**
175         * Get the alignment score between the two input strings.
176         */
177        public double getAlignmentScore() {
178                return getMaxScore();
179        }
180
181       
182       
183       
184        /**
185         * given the bottom right corner point trace back the top left conrner. at
186         * entry: i, j hold bottom right (end of Aligment coords) at return: hold
187         * top left (start of Alignment coords)
188         */
189        private int[] traceback(int i, int j) {
190
191                return null;
192        }
193
194       
195        /**
196         * print the dynmaic programming matrix
197         */
198        public void printDPMatrix() {
199                System.out.print("          ");
200                for (int i = 1; i <= length1; i++)
201                        System.out.format("%5d", input1[i - 1]);
202                System.out.println();
203                for (int j = 0; j < length2; j++) {
204                        if (j > 0)
205                                System.out.format("%5d ",input2[j - 1]);
206                        else{
207                                System.out.print("      ");
208                        }
209                        for (int i = 0; i <= length1; i++) {
210                                System.out.format("%4.1f ",matrix[i][j].getScore());
211                        }
212                        System.out.println();
213                }
214        }
215
216        /**
217         * Return a set of Matches identified in Dynamic programming matrix. A match
218         * is a pair of subsequences whose score is higher than the preset
219         * scoreThreshold
220         **/
221        public List<Match> getMatches() {
222                ArrayList<Match> matchList = new ArrayList();
223                int fA = 0, fB = 0;
224                // skip the first row and column, find the next maxScore after
225                // prevmaxScore
226                for (int i = 1; i <= length1; i++) {
227                        for (int j = 1; j <= length2; j++) {
228                                if (matrix[i][j].getScore() > scoreThreshold
229                                                && matrix[i][j].getScore() > matrix[i - 1][j - 1].getScore()
230                                                && matrix[i][j].getScore() > matrix[i - 1][j].getScore()
231                                                && matrix[i][j].getScore() > matrix[i][j - 1].getScore()) {
232                                        if (i == length1 || j == length2
233                                                        || matrix[i][j].getScore() > matrix[i + 1][j + 1].getScore()) {
234                                                // should be lesser than prev maxScore
235                                                fA = i;
236                                                fB = j;
237                                                int[] f = traceback(fA, fB); // sets the x, y to
238                                                                                                                // startAlignment
239                                                                                                                // coordinates
240                                                System.out.println(f[0] + " " + i + " " + f[1] + " "
241                                                                + j + " " + matrix[i][j].getScore());
242                                                // TODO Add matches to matchList
243                                        }
244                                }
245                        }
246                }
247                return matchList;
248        }
249
250}
Note: See TracBrowser for help on using the repository browser.