1 // ==========================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ==========================================================================
4 // Copyright (c) 2006-2018, Knut Reinert, FU Berlin
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // * Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
16 // its contributors may be used to endorse or promote products derived
17 // from this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
23 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 // DAMAGE.
30 //
31 // ==========================================================================
32 // Author: Manuel Holtgrewe <manuel.holtgrew@fu-berlin.de>
33 // Author: Andreas Gogol-Doering <andreas.doering@mdc-berlin.de>
34 // ==========================================================================
35 // Tests for the SeqAn module score.
36 // ==========================================================================
37
38 // TODO(holtgrew): There could be one test header for each module header.
39 // TODO(holtgrew): Write-out-read-in only necessary once.
40
41 #include <iostream>
42 #include <fstream>
43 #include <sstream>
44
45 #define SEQAN_DEBUG
46
47
48 #include <seqan/basic.h>
49 #include <seqan/sequence.h>
50 #include <seqan/score.h>
51 // TODO(rmaerker): Remove when done with the tests.
52 #include <seqan/align.h>
53
54 using namespace std;
55 using namespace seqan;
56
57 // Helper function that compares two amino acid matrices for equality.
58 // TODO(holtgrew): If used somewhere else, put into some place to share.
59 template <typename TScore1, typename TScore2>
assertAminoAcidMatricesAreEqual(TScore1 const & mat1,TScore2 const & mat2)60 void assertAminoAcidMatricesAreEqual(TScore1 const & mat1, TScore2 const & mat2) {
61 for (AminoAcid a = 'A'; a <= '*'; ++a) {
62 for (AminoAcid b = 'A'; b <= '*'; ++b) {
63 SEQAN_ASSERT_EQ_MSG(
64 score(mat1, a, b), score(mat2, a, b),
65 "a = %c, b = %c", static_cast<char>(a),
66 static_cast<char>(b));
67 }
68 }
69 }
70
71
72 // Performs SEQAN_ASSERT_EQ(0, x) for all cells x in matrix.
73 template<typename TScore>
assertAminoAcidMatrixIsDefaultInitialized(const TScore & matrix)74 void assertAminoAcidMatrixIsDefaultInitialized(const TScore &matrix) {
75 for (AminoAcid a = 'A'; a <= '*'; ++a) {
76 for (AminoAcid b = 'A'; b <= '*'; ++b) {
77 SEQAN_ASSERT_EQ(0, score(matrix, a, b));
78 }
79 }
80 }
81
82
83 // Test the default implementation for scoreGap* from score_base.h.
SEQAN_DEFINE_TEST(test_score_gap_open)84 SEQAN_DEFINE_TEST(test_score_gap_open) {
85 // TODO(holtgrew): The following *crashes* with edit distance score! References to temporaries returned.
86 // We simply test this with an simple score, test default implementation.
87 SimpleScore simpleScore;
88 const CharString kSeq1 = "A";
89 const CharString kSeq2 = "A";
90 typedef Position<CharString>::Type TPos;
91 const TPos kPos1 = 0;
92 const TPos kPos2 = 0;
93
94 SEQAN_ASSERT_EQ(scoreGapOpen(simpleScore),
95 scoreGapOpenHorizontal(simpleScore, sequenceEntryForScore(simpleScore, kSeq1, kPos1),
96 sequenceEntryForScore(simpleScore, kSeq2, kPos2)));
97 SEQAN_ASSERT_EQ(scoreGapOpen(simpleScore),
98 scoreGapOpenVertical(simpleScore, sequenceEntryForScore(simpleScore, kSeq1, kPos1),
99 sequenceEntryForScore(simpleScore, kSeq2, kPos2)));
100 SEQAN_ASSERT_EQ(scoreGapExtend(simpleScore),
101 scoreGapExtendHorizontal(simpleScore, sequenceEntryForScore(simpleScore, kSeq1, kPos1),
102 sequenceEntryForScore(simpleScore, kSeq2, kPos2)));
103 SEQAN_ASSERT_EQ(scoreGapExtend(simpleScore),
104 scoreGapExtendVertical(simpleScore, sequenceEntryForScore(simpleScore, kSeq1, kPos1),
105 sequenceEntryForScore(simpleScore, kSeq2, kPos2)));
106 SEQAN_ASSERT_EQ(scoreGap(simpleScore),
107 scoreGapHorizontal(simpleScore, sequenceEntryForScore(simpleScore, kSeq1, kPos1),
108 sequenceEntryForScore(simpleScore, kSeq2, kPos2)));
109 SEQAN_ASSERT_EQ(scoreGap(simpleScore),
110 scoreGapVertical(simpleScore, sequenceEntryForScore(simpleScore, kSeq1, kPos1),
111 sequenceEntryForScore(simpleScore, kSeq2, kPos2)));
112 SEQAN_ASSERT_EQ(score(simpleScore, kSeq1[kPos1], kSeq2[kPos2]),
113 score(simpleScore, sequenceEntryForScore(simpleScore, kSeq1, kPos1),
114 sequenceEntryForScore(simpleScore, kSeq2, kPos2)));
115 }
116
117
118 // Compare the built-in Blosum matrices against matrices from
119 // reference files.
SEQAN_DEFINE_TEST(test_score_matrix)120 SEQAN_DEFINE_TEST(test_score_matrix) {
121 // We test the scoring matrix with amino acids as the underlying
122 // sequence. This should be the most common case.
123 typedef int TValue;
124 typedef Score<TValue, ScoreMatrix<AminoAcid, Default> > TScore;
125
126 // Define path to BLOSUM62 matrix that we want to load.
127 // TODO(holtgrew): It should be easier to construct these paths.
128 String<char> pathToTestSrc = getAbsolutePath("/tests/score/");
129 String<char> pathToBlosum62(pathToTestSrc);
130 append(pathToBlosum62, "BLOSUM62");
131
132 // Test with default constructor.
133 {
134 // Call appropriate constructor.
135 TScore matrixScore;
136 // Assert score state.
137 SEQAN_ASSERT_EQ(-1, scoreGap(matrixScore));
138 SEQAN_ASSERT_EQ(-1, scoreGapExtend(matrixScore));
139 SEQAN_ASSERT_EQ(-1, scoreGapOpen(matrixScore));
140 // Test function score(). The default score is TValue() == 0
141 // for all matches.
142 assertAminoAcidMatrixIsDefaultInitialized(matrixScore);
143 }
144
145 // Test the const accessor functions.
146 {
147 // Call appropriate constructor.
148 const TScore matrixScore;
149 // Assert score state.
150 SEQAN_ASSERT_EQ(-1, scoreGap(matrixScore));
151 SEQAN_ASSERT_EQ(-1, scoreGapExtend(matrixScore));
152 SEQAN_ASSERT_EQ(-1, scoreGapOpen(matrixScore));
153 // Test function score(). The default score is TValue() == 0
154 // for all matches.
155 assertAminoAcidMatrixIsDefaultInitialized(matrixScore);
156 }
157
158 // Test the setter functions.
159 {
160 // The test score value for the test.
161 const TValue kScoreValue = 42;
162 // Create a new score matrix.
163 TScore matrixScore;
164 // Test function score(). The default score is TValue() == 0
165 // for all matches.
166 assertAminoAcidMatrixIsDefaultInitialized(matrixScore);
167 // Set the score for a substitution and check the result.
168 setScore(matrixScore, AminoAcid('A'), AminoAcid('X'), kScoreValue);
169 SEQAN_ASSERT_EQ(kScoreValue,
170 score(matrixScore, AminoAcid('A'), AminoAcid('X')));
171 }
172
173 // Test with gap extension constructor.
174 {
175 // Define constant test data and call appropriate constructor.
176 const TValue kGapScore = 1;
177 TScore matrixScore(kGapScore);
178 // Assert score state.
179 SEQAN_ASSERT_EQ(kGapScore, scoreGap(matrixScore));
180 SEQAN_ASSERT_EQ(kGapScore, scoreGapExtend(matrixScore));
181 SEQAN_ASSERT_EQ(kGapScore, scoreGapOpen(matrixScore));
182 // Test function score(). The default score is TValue() == 0
183 // for all matches.
184 assertAminoAcidMatrixIsDefaultInitialized(matrixScore);
185 }
186
187 // Test with gap extension and gap open constructor.
188 {
189 // Define constant test data and call appropriate constructor.
190 const TValue kGapExtensionScore = 1;
191 const TValue kGapOpenScore = 2;
192 TScore matrixScore(kGapExtensionScore, kGapOpenScore);
193 // Assert score state.
194 SEQAN_ASSERT_EQ(kGapExtensionScore, scoreGap(matrixScore));
195 SEQAN_ASSERT_EQ(kGapExtensionScore, scoreGapExtend(matrixScore));
196 SEQAN_ASSERT_EQ(kGapOpenScore, scoreGapOpen(matrixScore));
197 // Test function score(). The default score is TValue() == 0
198 // for all matches.
199 assertAminoAcidMatrixIsDefaultInitialized(matrixScore);
200 }
201
202 // Test with path to file constructor.
203 {
204 // Call appropriate constructor.
205 const TScore matrixScore(toCString(pathToBlosum62));
206 // Assert score state.
207 SEQAN_ASSERT_EQ(-1, scoreGap(matrixScore));
208 SEQAN_ASSERT_EQ(-1, scoreGapExtend(matrixScore));
209 SEQAN_ASSERT_EQ(-1, scoreGapOpen(matrixScore));
210 // The resulting matrix from the file should be equal to the
211 // built-in BLOSUM62 matrix.
212 Blosum62 blosum62;
213 assertAminoAcidMatricesAreEqual(blosum62, matrixScore);
214 }
215
216 // Test with path to file, gap extension constructor.
217 {
218 // Call appropriate constructor.
219 const TValue kGapScore = 1;
220 TScore matrixScore(toCString(pathToBlosum62), kGapScore);
221 // Assert score state.
222 SEQAN_ASSERT_EQ(kGapScore, scoreGap(matrixScore));
223 SEQAN_ASSERT_EQ(kGapScore, scoreGapExtend(matrixScore));
224 SEQAN_ASSERT_EQ(kGapScore, scoreGapOpen(matrixScore));
225 // The resulting matrix from the file should be equal to the
226 // built-in BLOSUM62 matrix.
227 Blosum62 blosum62;
228 assertAminoAcidMatricesAreEqual(blosum62, matrixScore);
229 }
230
231 // Test with path to file, gap extension and gap open constructor.
232 {
233 // Define constant test data and call appropriate constructor.
234 const TValue kGapExtensionScore = 1;
235 const TValue kGapOpenScore = 2;
236 TScore matrixScore(toCString(pathToBlosum62), kGapExtensionScore, kGapOpenScore);
237 // Assert score state.
238 SEQAN_ASSERT_EQ(kGapExtensionScore, scoreGap(matrixScore));
239 SEQAN_ASSERT_EQ(kGapExtensionScore, scoreGapExtend(matrixScore));
240 SEQAN_ASSERT_EQ(kGapOpenScore, scoreGapOpen(matrixScore));
241 // The resulting matrix from the file should be equal to the
242 // built-in BLOSUM62 matrix.
243 Blosum62 blosum62;
244 assertAminoAcidMatricesAreEqual(blosum62, matrixScore);
245 }
246 }
247
248
249 // Test the File I/O code for score matrices.
SEQAN_DEFINE_TEST(test_score_matrix_file)250 SEQAN_DEFINE_TEST(test_score_matrix_file) {
251 // TODO(holtgrew): It should be easier to construct these paths.
252 // The path to the directory with the test's sources and fixtures.
253 String<char> pathToTestSrc = getAbsolutePath("/tests/score/");
254
255 // Load fixture BLOSUM62 matrix.
256 // TODO(holtgrew): Should be done in a function.
257 Score<int, ScoreMatrix<> > sc;
258 String<char> meta;
259 String<char> pathToBlosum62(pathToTestSrc);
260 append(pathToTestSrc, "BLOSUM62");
261 // TODO(holtgrew): If the file does not exist, a bus error occurs, code should catch this case and print an error.
262 loadScoreMatrix(meta, sc, toCString(pathToTestSrc));
263
264 // Compare fixture BLOSUM62 matrix to built-in one.
265 {
266 Blosum62 blosum62;
267 assertAminoAcidMatricesAreEqual(blosum62, sc);
268 }
269
270 // Perform assertions on scores of the built-in Blosum62 matrix.
271 {
272 Blosum62 blosum62;
273 SEQAN_ASSERT_EQ(scoreGapExtend(blosum62), -1);
274 SEQAN_ASSERT_EQ(scoreGapOpen(blosum62), scoreGapExtend(blosum62));
275 SEQAN_ASSERT_EQ(scoreGap(blosum62), scoreGapExtend(blosum62));
276 }
277
278 // Store and load the fixture BLOSUM62 matrix again.
279 {
280 const char *temp_filename = SEQAN_TEMP_FILENAME();
281 {
282 std::ofstream fl(temp_filename);
283 typename DirectionIterator<std::ofstream, Output>::Type it = directionIterator(fl, Output());
284 write(it, sc, meta);
285 }
286
287 Score<int, ScoreMatrix<> > sc2;
288 String<char> meta2;
289 SEQAN_ASSERT(loadScoreMatrix(meta2, sc2, temp_filename));
290 assertAminoAcidMatricesAreEqual(sc, sc2);
291 SEQAN_ASSERT_EQ(meta, meta2);
292 }
293
294 // Store and load the built-in matrix again.
295 {
296 const char *temp_filename = SEQAN_TEMP_FILENAME();
297 {
298 std::ofstream fl(temp_filename);
299 typename DirectionIterator<std::ofstream, Output>::Type it = directionIterator(fl, Output());
300 write(it, Blosum62());
301 }
302
303 Score<int, ScoreMatrix<> > sc2;
304 SEQAN_ASSERT(loadScoreMatrix(sc2, temp_filename));
305 assertAminoAcidMatricesAreEqual(sc2, Blosum62());
306 }
307
308 // Test setScore()
309 {
310 setScore(sc, 'A', '*', 100);
311 SEQAN_ASSERT_EQ(score(sc, 'A', '*'), 100);
312 }
313 }
314
315
316 // Testing the edit distance score is simple, the functions simply
317 // return the edit distance values.
SEQAN_DEFINE_TEST(test_score_edit)318 SEQAN_DEFINE_TEST(test_score_edit) {
319 // TODO(holtgrew): Break out each block into a test of its own.
320 // We will only test with int scores, the most common case.
321 typedef int TValue;
322 typedef Score<TValue, EditDistance> TScore;
323
324 // Test the default constructor.
325 {
326 TScore editDistanceScore;
327 SEQAN_ASSERT_EQ(0, scoreMatch(editDistanceScore));
328 SEQAN_ASSERT_EQ(-1, scoreMismatch(editDistanceScore));
329 // TODO(holtgrew): FIXME! Does not compile because of reference to temporary.
330 // SEQAN_ASSERT_EQ(-1, scoreGap(editDistanceScore));
331 SEQAN_ASSERT_EQ(-1, scoreGapExtend(editDistanceScore));
332 SEQAN_ASSERT_EQ(-1, scoreGapOpen(editDistanceScore));
333 // Test function score().
334 SEQAN_ASSERT_EQ(0, score(editDistanceScore, 'A', 'A'));
335 SEQAN_ASSERT_EQ(-1, score(editDistanceScore, 'A', 'C'));
336 }
337
338 // Test the const accessor functions.
339 {
340 const TScore editDistanceScore;
341 SEQAN_ASSERT_EQ(0, scoreMatch(editDistanceScore));
342 SEQAN_ASSERT_EQ(-1, scoreMismatch(editDistanceScore));
343 // TODO(holtgrew): FIXME! Does not compile because of reference to temporary.
344 // SEQAN_ASSERT_EQ(-1, scoreGap(editDistanceScore));
345 SEQAN_ASSERT_EQ(-1, scoreGapExtend(editDistanceScore));
346 SEQAN_ASSERT_EQ(-1, scoreGapOpen(editDistanceScore));
347 // Test function score().
348 SEQAN_ASSERT_EQ(0, score(editDistanceScore, 'A', 'A'));
349 SEQAN_ASSERT_EQ(-1, score(editDistanceScore, 'A', 'C'));
350 }
351
352 // Test the shortcut. Since the assignment operator is not
353 // overloaded, the following should not compile if the shortcut is
354 // not defined appropriately.
355 {
356 // TODO(holtgrew): Use a metaprogramming for type equality instead?, something like SEQAN_ASSERT(type-equals(x, y));?
357 Score<int, EditDistance> scoreEditDistance;
358 EditDistanceScore editDistanceScore;
359 scoreEditDistance = editDistanceScore;
360 }
361 }
362
363
364 // Score<TValue, Simple> is, you have guessed it, very simple. Thus,
365 // we will simply use different constructors to construct Simple Score
366 // objects and call the scoring functions on them.
SEQAN_DEFINE_TEST(test_score_simple)367 SEQAN_DEFINE_TEST(test_score_simple) {
368 // TODO(holtgrew): Break out each block into a test of its own.
369 // We will only test with int scores, the most common case.
370 typedef int TValue;
371 typedef Score<TValue, Simple> TScore;
372
373 // Test the default constructor.
374 {
375 TScore simpleScore;
376 SEQAN_ASSERT_EQ(0, scoreMatch(simpleScore));
377 SEQAN_ASSERT_EQ(-1, scoreMismatch(simpleScore));
378 SEQAN_ASSERT_EQ(-1, scoreGap(simpleScore));
379 SEQAN_ASSERT_EQ(-1, scoreGapExtend(simpleScore));
380 SEQAN_ASSERT_EQ(-1, scoreGapOpen(simpleScore));
381 // Test function score().
382 SEQAN_ASSERT_EQ(0, score(simpleScore, 'A', 'A'));
383 SEQAN_ASSERT_EQ(-1, score(simpleScore, 'A', 'C'));
384 }
385
386 // Test the const member retrieval functions.
387 // TODO(holtgrew): Should these functions not be called getFUNCNAME?
388 {
389 const TScore simpleScore;
390 SEQAN_ASSERT_EQ(0, scoreMatch(simpleScore));
391 SEQAN_ASSERT_EQ(-1, scoreMismatch(simpleScore));
392 SEQAN_ASSERT_EQ(-1, scoreGap(simpleScore));
393 SEQAN_ASSERT_EQ(-1, scoreGapExtend(simpleScore));
394 SEQAN_ASSERT_EQ(-1, scoreGapOpen(simpleScore));
395 // Test function score().
396 SEQAN_ASSERT_EQ(0, score(simpleScore, 'A', 'A'));
397 SEQAN_ASSERT_EQ(-1, score(simpleScore, 'A', 'C'));
398 }
399
400 // Test the non-const member retrieval functions with assignments.
401 {
402 const int kMatch = 1;
403 const int kMismatch = 2;
404 const int kGapExtension = 3;
405 const int kGapOpen = 4;
406 // Perform assignments.
407 TScore simpleScore;
408 setScoreMatch(simpleScore, kMatch);
409 setScoreMismatch(simpleScore, kMismatch);
410 setScoreGap(simpleScore, kGapExtension);
411 setScoreGapExtend(simpleScore, kGapExtension);
412 setScoreGapOpen(simpleScore, kGapOpen);
413 // Check results.
414 SEQAN_ASSERT_EQ(kMatch, scoreMatch(simpleScore));
415 SEQAN_ASSERT_EQ(kMismatch, scoreMismatch(simpleScore));
416 SEQAN_ASSERT_EQ(kGapExtension, scoreGap(simpleScore));
417 SEQAN_ASSERT_EQ(kGapExtension, scoreGapExtend(simpleScore));
418 SEQAN_ASSERT_EQ(kGapOpen, scoreGapOpen(simpleScore));
419 }
420
421 // Test the constructor with match, mismatch, gap arguments.
422 {
423 // Define constant test data.
424 const int kMatch = 1;
425 const int kMismatch = 2;
426 const int kGap = 3;
427 // Construct the score and make assertions about its state.
428 TScore simpleScore(kMatch, kMismatch, kGap);
429 SEQAN_ASSERT_EQ(kMatch, scoreMatch(simpleScore));
430 SEQAN_ASSERT_EQ(kMismatch, scoreMismatch(simpleScore));
431 SEQAN_ASSERT_EQ(kGap, scoreGap(simpleScore));
432 SEQAN_ASSERT_EQ(kGap, scoreGapExtend(simpleScore));
433 SEQAN_ASSERT_EQ(kGap, scoreGapOpen(simpleScore));
434 // Test function score().
435 SEQAN_ASSERT_EQ(kMatch, score(simpleScore, 'A', 'A'));
436 SEQAN_ASSERT_EQ(kMismatch, score(simpleScore, 'A', 'C'));
437 }
438
439 // Test the constructor with match, mismatch, gap extension, gap
440 // open arguments.
441 {
442 // Define constant test data.
443 const int kMatch = 1;
444 const int kMismatch = 2;
445 const int kGapExtension = 3;
446 const int kGapOpen = 4;
447 // Construct the score and make assertions about its state.
448 TScore simpleScore(kMatch, kMismatch, kGapExtension, kGapOpen);
449 SEQAN_ASSERT_EQ(kMatch, scoreMatch(simpleScore));
450 SEQAN_ASSERT_EQ(kMismatch, scoreMismatch(simpleScore));
451 SEQAN_ASSERT_EQ(kGapExtension, scoreGap(simpleScore));
452 SEQAN_ASSERT_EQ(kGapExtension, scoreGapExtend(simpleScore));
453 SEQAN_ASSERT_EQ(kGapOpen, scoreGapOpen(simpleScore));
454 // Test function score().
455 SEQAN_ASSERT_EQ(kMatch, score(simpleScore, 'A', 'A'));
456 SEQAN_ASSERT_EQ(kMismatch, score(simpleScore, 'A', 'C'));
457 }
458
459 // Test the shortcut. Since the assignment operator is not
460 // overloaded, the following should not compile if the shortcut is
461 // not defined appropriately.
462 {
463 // TODO(holtgrew): Use a metaprogramming for type equality instead?, something like SEQAN_ASSERT(type-equals(x, y));?
464 Score<int, Simple> scoreSimple;
465 SimpleScore simpleScore;
466 simpleScore = scoreSimple;
467 }
468 }
469
470
471 // Test the built-in data matrices by comparing them to the matrices
472 // from test data files.
SEQAN_DEFINE_TEST(test_score_matrix_data)473 SEQAN_DEFINE_TEST(test_score_matrix_data) {
474 // We test the scoring matrix with amino acids as the underlying
475 // sequence. This should be the most common case.
476 typedef int TValue;
477 typedef Score<TValue, ScoreMatrix<AminoAcid, ScoreMatrixFile> > TScore;
478
479 // TODO(holtgrew): It should be easier to construct these paths.
480 String<char> pathToTestSrc = getAbsolutePath("/tests/score/");
481
482 // Test with BLOSUM30.
483 {
484 // The built-in BLOSUM30 matrix.
485 Blosum30 blosum30;
486 // Use a quick-and-dirty test that the matrix indeed is BLOSUM30.
487 SEQAN_ASSERT_EQ(0, score(blosum30, AminoAcid('A'), AminoAcid('N')));
488 SEQAN_ASSERT_EQ(1, score(blosum30, AminoAcid('V'), AminoAcid('A')));
489
490 // Build path to BLOSUM30 matrix.
491 String<char> pathToBlosum30(pathToTestSrc);
492 append(pathToBlosum30, "BLOSUM30");
493 // Load matrix.
494 TScore loadedBlosum30(toCString(pathToBlosum30));
495 // Compare loaded with built-in matrix.
496 assertAminoAcidMatricesAreEqual(loadedBlosum30, blosum30);
497 }
498
499 // Test with BLOSUM45.
500 {
501 // The built-in BLOSUM45 matrix.
502 Blosum45 blosum45;
503 // Use a quick-and-dirty test that the matrix indeed is BLOSUM45.
504 SEQAN_ASSERT_EQ(-1, score(blosum45, AminoAcid('A'), AminoAcid('N')));
505 SEQAN_ASSERT_EQ(0, score(blosum45, AminoAcid('V'), AminoAcid('A')));
506
507 // Build path to BLOSUM45 matrix.
508 String<char> pathToBlosum45(pathToTestSrc);
509 append(pathToBlosum45, "BLOSUM45");
510 // Load matrix.
511 TScore loadedBlosum45(toCString(pathToBlosum45));
512 // Compare loaded with built-in matrix.
513 assertAminoAcidMatricesAreEqual(loadedBlosum45, blosum45);
514 }
515
516 // Test with BLOSUM62.
517 {
518 // The built-in BLOSUM62 matrix.
519 Blosum62 blosum62;
520 // Use a quick-and-dirty test that the matrix indeed is BLOSUM62.
521 SEQAN_ASSERT_EQ(-2, score(blosum62, AminoAcid('A'), AminoAcid('N')));
522 SEQAN_ASSERT_EQ(0, score(blosum62, AminoAcid('V'), AminoAcid('A')));
523
524 // Build path to BLOSUM62 matrix.
525 String<char> pathToBlosum62(pathToTestSrc);
526 append(pathToBlosum62, "BLOSUM62");
527 // Load matrix.
528 TScore loadedBlosum62(toCString(pathToBlosum62));
529 // Compare loaded with built-in matrix.
530 assertAminoAcidMatricesAreEqual(loadedBlosum62, blosum62);
531 }
532
533 // Test with BLOSUM80.
534 {
535 // The built-in BLOSUM80 matrix.
536 Blosum80 blosum80;
537 // Use a quick-and-dirty test that the matrix indeed is BLOSUM80.
538 SEQAN_ASSERT_EQ(-3, score(blosum80, AminoAcid('A'), AminoAcid('N')));
539 SEQAN_ASSERT_EQ(-1, score(blosum80, AminoAcid('V'), AminoAcid('A')));
540
541 // Build path to BLOSUM80 matrix.
542 String<char> pathToBlosum80(pathToTestSrc);
543 append(pathToBlosum80, "BLOSUM80");
544 // Load matrix.
545 TScore loadedBlosum80(toCString(pathToBlosum80));
546 // Compare loaded with built-in matrix.
547 assertAminoAcidMatricesAreEqual(loadedBlosum80, blosum80);
548 }
549
550 // Test with PAM40.
551 {
552 // The built-in PAM40 matrix.
553 Pam40 pam40;
554 // Use a quick-and-dirty test that the matrix indeed is PAM40.
555 SEQAN_ASSERT_EQ(-3, score(pam40, AminoAcid('A'), AminoAcid('N')));
556 SEQAN_ASSERT_EQ(-2, score(pam40, AminoAcid('V'), AminoAcid('A')));
557
558 // Build path to PAM40 matrix.
559 String<char> pathToPam40(pathToTestSrc);
560 append(pathToPam40, "PAM40");
561 // Load matrix.
562 TScore loadedPam40(toCString(pathToPam40));
563 // Compare loaded with built-in matrix.
564 assertAminoAcidMatricesAreEqual(loadedPam40, pam40);
565 }
566
567 // Test with PAM120.
568 {
569 // The built-in PAM120 matrix.
570 Pam120 pam120;
571 // Use a quick-and-dirty test that the matrix indeed is PAM120.
572 SEQAN_ASSERT_EQ(-1, score(pam120, AminoAcid('A'), AminoAcid('N')));
573 SEQAN_ASSERT_EQ(0, score(pam120, AminoAcid('V'), AminoAcid('A')));
574
575 // Build path to PAM120 matrix.
576 String<char> pathToPam120(pathToTestSrc);
577 append(pathToPam120, "PAM120");
578 // Load matrix.
579 TScore loadedPam120(toCString(pathToPam120));
580 // Compare loaded with built-in matrix.
581 assertAminoAcidMatricesAreEqual(loadedPam120, pam120);
582 }
583
584 // Test with PAM200.
585 {
586 // The built-in PAM200 matrix.
587 Pam200 pam200;
588 // Use a quick-and-dirty test that the matrix indeed is PAM200.
589 SEQAN_ASSERT_EQ(0, score(pam200, AminoAcid('A'), AminoAcid('N')));
590 SEQAN_ASSERT_EQ(0, score(pam200, AminoAcid('V'), AminoAcid('A')));
591
592 // Build path to PAM200 matrix.
593 String<char> pathToPam200(pathToTestSrc);
594 append(pathToPam200, "PAM200");
595 // Load matrix.
596 TScore loadedPam200(toCString(pathToPam200));
597 // Compare loaded with built-in matrix.
598 assertAminoAcidMatricesAreEqual(loadedPam200, pam200);
599 }
600
601 // Test with PAM250.
602 {
603 // The built-in PAM250 matrix.
604 Pam250 pam250;
605 // Use a quick-and-dirty test that the matrix indeed is PAM250.
606 SEQAN_ASSERT_EQ(0, score(pam250, AminoAcid('A'), AminoAcid('N')));
607 SEQAN_ASSERT_EQ(0, score(pam250, AminoAcid('V'), AminoAcid('A')));
608
609 // Build path to PAM250 matrix.
610 String<char> pathToPam250(pathToTestSrc);
611 append(pathToPam250, "PAM250");
612 // Load matrix.
613 TScore loadedPam250(toCString(pathToPam250));
614 // Compare loaded with built-in matrix.
615 assertAminoAcidMatricesAreEqual(loadedPam250, pam250);
616 }
617
618 // Test with VTML200.
619 {
620 // The built-in VTML200 matrix.
621 Vtml200 vtml200;
622 // Use a quick-and-dirty test that the matrix indeed is VTML200.
623 SEQAN_ASSERT_EQ(-1, score(vtml200, AminoAcid('A'), AminoAcid('N')));
624 SEQAN_ASSERT_EQ(0, score(vtml200, AminoAcid('V'), AminoAcid('A')));
625
626 // Build path to VTML200 matrix.
627 String<char> pathToVTML200(pathToTestSrc);
628 append(pathToVTML200, "VTML200I");
629 // Load matrix.
630 TScore loadedVTML200(toCString(pathToVTML200));
631 // Compare loaded with built-in matrix.
632 assertAminoAcidMatricesAreEqual(loadedVTML200, vtml200);
633 }
634 }
635
636 template <typename TScoreSpec>
testScoreSequenceEntryForScore()637 void testScoreSequenceEntryForScore()
638 {
639 typedef Score<int, TScoreSpec> TScoringScheme;
640 typedef typename SequenceEntryForScore<TScoringScheme, DnaString>::Type TEntry1;
641
642 DnaString seq1 = "ACGTACG";
643 Dna5String seq2 = "ACGTNACNA";
644
645 TScoringScheme scoringScheme;
646
647 TEntry1 val1 = sequenceEntryForScore(scoringScheme, seq1, 0);
648 TEntry1 val2 = sequenceEntryForScore(scoringScheme, seq2, 0);
649
650 SEQAN_ASSERT_EQ(val1, 'A');
651 SEQAN_ASSERT_EQ(val2, 'A');
652
653 val1 = sequenceEntryForScore(scoringScheme, seq1, 4);
654 val2 = sequenceEntryForScore(scoringScheme, seq2, 4);
655
656 SEQAN_ASSERT_EQ(val1, 'A');
657 SEQAN_ASSERT_EQ(val2, 'N');
658 }
659
SEQAN_DEFINE_TEST(test_score_sequence_entry_for_score)660 SEQAN_DEFINE_TEST(test_score_sequence_entry_for_score)
661 {
662 testScoreSequenceEntryForScore<Simple>();
663 testScoreSequenceEntryForScore<ScoreMatrix<AminoAcid, Blosum62_> >();
664 }
665
SEQAN_DEFINE_TEST(test_score_dynamic_score_matrix)666 SEQAN_DEFINE_TEST(test_score_dynamic_score_matrix)
667 {
668 Blosum62 blo;
669 SelectableAminoAcidMatrix sel;
670 SEQAN_ASSERT(getScoreMatrixId(sel) != AminoAcidScoreMatrixID::BLOSUM62);
671
672 setScoreMatrixById(sel, AminoAcidScoreMatrixID::BLOSUM62);
673 SEQAN_ASSERT(getScoreMatrixId(sel) == AminoAcidScoreMatrixID::BLOSUM62);
674
675 for (unsigned i = 0; i < ValueSize<AminoAcid>::VALUE; ++i)
676 for (unsigned j = 0; j < ValueSize<AminoAcid>::VALUE; ++j)
677 SEQAN_ASSERT_EQ(score(blo, static_cast<AminoAcid>(i), static_cast<AminoAcid>(j)),
678 score(sel, static_cast<AminoAcid>(i), static_cast<AminoAcid>(j)));
679 }
680
SEQAN_BEGIN_TESTSUITE(test_score)681 SEQAN_BEGIN_TESTSUITE(test_score) {
682 // Call the tests for this module.
683 SEQAN_CALL_TEST(test_score_gap_open);
684 SEQAN_CALL_TEST(test_score_simple);
685 SEQAN_CALL_TEST(test_score_edit);
686 SEQAN_CALL_TEST(test_score_matrix);
687 SEQAN_CALL_TEST(test_score_matrix_file);
688 SEQAN_CALL_TEST(test_score_matrix_data);
689 SEQAN_CALL_TEST(test_score_sequence_entry_for_score);
690 SEQAN_CALL_TEST(test_score_dynamic_score_matrix);
691 }
692 SEQAN_END_TESTSUITE
693