ProteoWizard
PeptideTest.cpp
Go to the documentation of this file.
1//
2// $Id$
3//
4//
5// Original author: Darren Kessner <darren@proteowizard.org>
6//
7// Copyright 2006 Louis Warschaw Prostate Cancer Center
8// Cedars Sinai Medical Center, Los Angeles, California 90048
9//
10// Licensed under the Apache License, Version 2.0 (the "License");
11// you may not use this file except in compliance with the License.
12// You may obtain a copy of the License at
13//
14// http://www.apache.org/licenses/LICENSE-2.0
15//
16// Unless required by applicable law or agreed to in writing, software
17// distributed under the License is distributed on an "AS IS" BASIS,
18// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19// See the License for the specific language governing permissions and
20// limitations under the License.
21//
22
23
25#include "Peptide.hpp"
27#include "boost/thread/thread.hpp"
28#include "boost/thread/barrier.hpp"
29
30
31using namespace pwiz::util;
32using namespace pwiz::proteome;
33using namespace pwiz::chemistry;
34
35
36ostream* os_ = 0;
37
38
39void test()
40{
41 Peptide angiotensin("DRVYIHPF");
42 if (os_) *os_ << "angiotensin: " << angiotensin.sequence() << " " << angiotensin.formula() << endl;
43
44 Peptide alpha16("WHWLQL");
45 if (os_) *os_ << "alpha16: " << alpha16.sequence() << " " << alpha16.formula() << endl;
46}
47
48
49const char* sequences[] =
50{
51 "CLPMILDNK",
52 "AVSNPFQQR",
53 "CELLFFFK",
54 "AGASIVGVNCR",
55 "QPTPPFFGR",
56 "AVFHMQSVK",
57 "TRUCKER"
58};
59
60
67
69{
70 { "ELK", 388.2322, 389.24005, 195.12396, 388.45918, 389.4665, 195.2369 },
71 { "DEERLICKER", 1289.6398, 1290.6477, 645.8278, 1290.44644, 1291.4537, 646.2305 },
72 { "ELVISLIVES", 1100.6329, 1101.6408, 551.3243, 1101.29052, 1102.2978, 551.6525 },
73 { "THEQUICKRWNFUMPSVERTHELAYDG", 3348.3249, 3349.3328, 1675.17035, 3348.44626, 3349.45416, 1675.23103 },
74 { "No?PepTidE...", 0, 0, 0, 0, 0, 0 }
75};
76
77const size_t testPeptidesSize = sizeof(testPeptides)/sizeof(TestPeptide);
78
80{
81 for (size_t i=0; i < testPeptidesSize; ++i)
82 {
83 const TestPeptide& p = testPeptides[i];
84 double BIG_EPSILON = 0.001;
85
86 Peptide peptide(p.sequence);
87 if (os_) *os_ << peptide.sequence() << ": " << peptide.formula() <<
88 " " << peptide.monoisotopicMass() <<
89 " " << peptide.molecularWeight() << endl;
90 unit_assert_equal(peptide.formula().monoisotopicMass(), p.monoMassNeutral, BIG_EPSILON);
91 unit_assert_equal(peptide.formula().molecularWeight(), p.avgMassNeutral, BIG_EPSILON);
92 unit_assert_equal(peptide.monoisotopicMass(), p.monoMassNeutral, BIG_EPSILON);
93 unit_assert_equal(peptide.molecularWeight(), p.avgMassNeutral, BIG_EPSILON);
94 unit_assert_equal(peptide.monoisotopicMass(1, true), p.monoMassPlus1, BIG_EPSILON);
95 unit_assert_equal(peptide.molecularWeight(1, true), p.avgMassPlus1, BIG_EPSILON);
96 unit_assert_equal(peptide.monoisotopicMass(2, true), p.monoMassPlus2, BIG_EPSILON);
97 unit_assert_equal(peptide.molecularWeight(2, true), p.avgMassPlus2, BIG_EPSILON);
98
99 peptide = p.sequence; // test assignment
100 if (os_) *os_ << peptide.sequence() << ": " << peptide.formula() <<
101 " " << peptide.monoisotopicMass() <<
102 " " << peptide.molecularWeight() << endl;
103 unit_assert_equal(peptide.formula().monoisotopicMass(), p.monoMassNeutral, BIG_EPSILON);
104 unit_assert_equal(peptide.formula().molecularWeight(), p.avgMassNeutral, BIG_EPSILON);
105 unit_assert_equal(peptide.monoisotopicMass(), p.monoMassNeutral, BIG_EPSILON);
106 unit_assert_equal(peptide.molecularWeight(), p.avgMassNeutral, BIG_EPSILON);
107 }
108}
109
110
112{
113 const char* motif;
114 const char* formula;
118};
119
121{
122 { "M", "O1", 15.9949, 15.9994, true }, // Oxidation of M
123 { "C", "C2H3N1O1", 57.02146, 57.052, false }, // Carboxyamidomethylation of C
124 { "(Q", "N-1H-3", -17.02655, -17.0306, false }, // Pyroglutamic acid from Q at the N terminus
125 { "(E", "N-1H-3", -17.02655, -17.0306, true }, // Pyroglutamic acid from E at the N terminus
126 { "N!G", "N-1H-3", -17.02655, -17.0306, true }, // Succinimide from N when N terminal to G
127 //{ "[NQ]", "O1N-1H-2", 0.98402, 0.9847, true }, // Deamidation of N or Q
128 { "[STY]!{STY}", "H1P1O3", 79.96633, 79.9799, true }, // Phosphorylation of S, T, or Y when not N terminal to S, T, or Y
129 { "(", "C2H2O1", 42.010565, 42.0367, true }, // N-terminal acetylation
130 { "[ED)]", "C2H5N1", 43.042199, 43.0678, true }, // Carboxyl modification with ethanolamine
131};
132
134{
135 const char* sequence;
136 const char* mods; // index pairs
138 ModificationParsing mp;
139 ModificationDelimiter md;
140 double monoMass;
141 double avgMass;
142 int exception; // if non-zero, test should cause this exception
143};
144
146{
147 // M+16
148 { "MEERKAT",
149 "0 0",
150 false,
153 879.41205, 879.97844,
154 0
155 },
156
157 // M+16
158 { "M[O1]EERKAT",
159 "0 0",
160 true,
163 879.41205, 879.97844,
164 0
165 },
166
167 // M+16
168 { "M[O1]EERKAT",
169 "0 0",
170 true,
171 ModificationParsing_Auto,
173 879.41205, 879.97844,
174 0
175 },
176
177 // M+16
178 { "M(15.9949,15.9994)EERKAT",
179 "0 0",
180 false,
183 879.41205, 879.97844,
184 1 //"[Peptide::Impl::parse()] Expected a chemical formula for all modifications in sequence "
185 },
186
187 // M+16
188 { "M[15.9949,15.9994]EERKAT",
189 "0 0",
190 false,
193 879.41205, 879.97844,
194 0
195 },
196
197 // M+16
198 { "M(15.9949,15.9994)EERKAT",
199 "0 0",
200 false,
201 ModificationParsing_Auto,
203 879.41205, 879.97844,
204 0
205 },
206
207 // M+16
208 { "M[O1)EERKAT",
209 "0 0",
210 true,
213 879.41205, 879.97844,
214 1 //"[Peptide::Impl::parse()] Modification started but not ended in sequence "
215 },
216
217 // C+57
218 { "THEQICKRWNFMPSVERTHELAYDG",
219 "1 5",
220 false,
223 3103.43929, 3105.4218,
224 0
225 },
226
227 // C+57, M+16
228 { "THEQICKRWNFMPSVERTHELAYDG",
229 "0 11 1 5",
230 false,
233 3119.43419, 3121.4212,
234 0
235 },
236
237 // C+57, M+16
238 { "THEQIC{C2H3N1O1}KRWNFM{O1}PSVERTHELAYDG",
239 "0 11 1 5",
240 true,
242 ModificationDelimiter_Braces,
243 3119.43419, 3121.4212,
244 0
245 },
246
247 // C+57, M+16
248 { "THEQIC{C2H3N1O1}KRWNFM{15.9949,15.9994}PSVERTHELAYDG",
249 "0 11 1 5",
250 false,
251 ModificationParsing_Auto,
252 ModificationDelimiter_Braces,
253 3119.43419, 3121.4212,
254 0
255 },
256
257 // C+57, Q-17
258 { "QICKRWNFMPSVERTHELAYDG",
259 "2 0 1 2",
260 false,
263 2719.26356, 2721.0341,
264 0
265 },
266
267 // no mods
268 { "ELVISLIVES",
269 0,
270 false,
273 1100.63293, 1101.29052,
274 0
275 },
276
277 // E-17
278 { "ELVISLIVES",
279 "3 0",
280 false,
283 1083.60638, 1084.26,
284 0
285 },
286
287 // E-17
288 { "E(N-1H-3)LVISLIVES",
289 "3 0",
290 true,
293 1083.60638, 1084.26,
294 0
295 },
296
297 // E-17
298 { "E(N-1H-3)LVISLIVES",
299 "3 0",
300 true,
303 1083.60638, 1084.26,
304 1 //"[Peptide::Impl::parse()] Expected one or two comma-separated numbers in sequence "
305 },
306
307 // E-17
308 { "E(N-1H-3)LVISLIVES",
309 "3 0",
310 true,
311 ModificationParsing_Auto,
313 1083.60638, 1084.26,
314 0
315 },
316
317 // E-17
318 { "E(-17.02655,-17.0306)LVISLIVES",
319 "3 0",
320 false,
323 1083.60638, 1084.26,
324 0
325 },
326
327 // E-17
328 { "E(-17.02655,-17.0306)LVISLIVES",
329 "3 0",
330 false,
331 ModificationParsing_Auto,
333 1083.60638, 1084.26,
334 0
335 },
336
337 // no mods
338 { "PINGPNG",
339 0,
340 false,
343 667.32898, 667.7112,
344 0
345 },
346
347 // N-17
348 { "PINGPNG",
349 "4 2",
350 false,
353 650.30243, 650.6807,
354 0
355 },
356
357 // no mods
358 { "MISSISSIPPI",
359 0,
360 false,
363 1143.62099, 1144.3815,
364 0
365 },
366
367 // no mods
368 { "MISSISSIPPI",
369 0,
370 false,
371 ModificationParsing_Auto,
373 1143.62099, 1144.3815,
374 0
375 },
376
377 // S+80, S+80
378 { "MISSISSIPPI",
379 "5 3 5 5",
380 true,
383 1303.55365, 1304.3413,
384 0
385 },
386
387 // N-terminal +42
388 { "PINGPNG",
389 "6 n",
390 true,
393 709.339545, 709.7479,
394 0
395 },
396
397 // C-terminal +43
398 { "PINGPNG",
399 "7 c",
400 true,
403 710.371179, 710.779,
404 0
405 }
406};
407
410
412{
413 for (size_t i=0; i < testModifiedPeptidesSize; ++i)
414 {
416 try
417 {
418 Peptide peptide;
419 double monoDeltaMass = 0;
420 double avgDeltaMass = 0;
421 double BIG_EPSILON = 0.001;
422
423 if (p.exception != 0)
424 {
425 //unit_assert_throws_what(Peptide(p.sequence, p.mp, p.md), exception, string(p.exception)+p.sequence);
426 continue;
427 }
428
429 if (p.mp == ModificationParsing_Off || p.mods == NULL)
430 {
431 peptide = Peptide(p.sequence);
432
433 if (p.mods != NULL)
434 {
435 ModificationMap& modMap = peptide.modifications();
436 vector<string> tokens;
437 boost::split(tokens, p.mods, boost::is_space());
438 for (size_t i=0; i < tokens.size(); i+=2)
439 {
440 TestModification& mod = testModifications[lexical_cast<size_t>(tokens[i])];
441
442 int modOffset;
443 if (tokens[i+1] == "n")
444 modOffset = ModificationMap::NTerminus();
445 else if (tokens[i+1] == "c")
446 modOffset = ModificationMap::CTerminus();
447 else
448 modOffset = lexical_cast<int>(tokens[i+1]);
449
450 if (p.modsHaveFormulas)
451 modMap[modOffset].push_back(Modification(mod.formula));
452 else
453 modMap[modOffset].push_back(Modification(mod.deltaMonoMass, mod.deltaAvgMass));
454 monoDeltaMass += mod.deltaMonoMass;
455 avgDeltaMass += mod.deltaAvgMass;
456 }
457 }
458 }
459 else
460 {
461 peptide = Peptide(p.sequence, p.mp, p.md);
462
463 ModificationMap& modMap = peptide.modifications();
464 vector<string> tokens;
465 boost::split(tokens, p.mods, boost::is_space());
466 for (size_t i=0; i < tokens.size(); i+=2)
467 {
468 TestModification& mod = testModifications[lexical_cast<size_t>(tokens[i])];
469
470 int modOffset;
471 if (tokens[i+1] == "n")
472 modOffset = ModificationMap::NTerminus();
473 else if (tokens[i+1] == "c")
474 modOffset = ModificationMap::CTerminus();
475 else
476 modOffset = lexical_cast<int>(tokens[i+1]);
477
478 ModificationMap::const_iterator itr = modMap.find(modOffset);
479 unit_assert(itr != modMap.end());
480 const ModificationList& modList = itr->second;
481 if (p.modsHaveFormulas)
482 {
483 unit_assert(modList[0].hasFormula());
484 unit_assert(modList[0].formula() == mod.formula);
485 }
486 unit_assert_equal(modList[0].monoisotopicDeltaMass(), mod.deltaMonoMass, BIG_EPSILON);
487 unit_assert_equal(modList[0].averageDeltaMass(), mod.deltaAvgMass, BIG_EPSILON);
488 monoDeltaMass += mod.deltaMonoMass;
489 avgDeltaMass += mod.deltaAvgMass;
490 }
491 }
492
493 if (os_) *os_ << peptide.sequence() << ": " << peptide.monoisotopicMass() << " " << peptide.molecularWeight() << endl;
494
495 if (p.modsHaveFormulas)
496 {
497 unit_assert_equal(peptide.formula(true).monoisotopicMass(), p.monoMass, BIG_EPSILON);
498 unit_assert_equal(peptide.formula(true).molecularWeight(), p.avgMass, BIG_EPSILON);
499 } else if (p.mods != NULL)
500 unit_assert_throws_what(peptide.formula(true), runtime_error,
501 "[Peptide::formula()] peptide formula cannot be generated when any modifications have no formula info");
502
503 unit_assert_equal(peptide.formula(false).monoisotopicMass(), p.monoMass-monoDeltaMass, BIG_EPSILON);
504 unit_assert_equal(peptide.formula(false).molecularWeight(), p.avgMass-avgDeltaMass, BIG_EPSILON);
505 unit_assert_equal(peptide.monoisotopicMass(0, true), p.monoMass, BIG_EPSILON);
506 unit_assert_equal(peptide.molecularWeight(0, true), p.avgMass, BIG_EPSILON);
507 unit_assert_equal(peptide.monoisotopicMass(0, false), p.monoMass-monoDeltaMass, BIG_EPSILON);
508 unit_assert_equal(peptide.molecularWeight(0, false), p.avgMass-avgDeltaMass, BIG_EPSILON);
509 }
510 catch (exception& e)
511 {
512 cout << "Unit test " << lexical_cast<string>(i+1) << " on modified peptide \"" << p.sequence << "\" failed:\n" << e.what() << endl;
513 }
514 }
515}
516
517
519{
520 const char* lhsPeptide;
521 const char* rhsPeptide;
522 int compare; // 0:lhs==rhs -1:lhs<rhs 1:lhs>rhs
523};
524
526{
527 {"PEPTIDE", "PEPTIDE", 0},
528 {"PEPTIDE", "PEPTIDEK", -1},
529 {"PEPTIDEK", "PEPTIDE", 1},
530
531 {"(42)PEPTIDE", "(42)PEPTIDE", 0},
532 {"PEP(42)TIDE", "PEP(42)TIDE", 0},
533 {"PEPTIDE(42)", "PEPTIDE(42)", 0},
534 {"PEPTIDE", "(42)PEPTIDE", -1},
535 {"(42)PEPTIDE", "PEPTIDE", 1},
536 {"PEPTIDE(41)", "PEPTIDE(42)", -1},
537 {"PEPTIDE(42)", "PEPTIDE(41)", 1},
538 {"(42)PEPTIDE(42)", "(42)PEPTIDE(42)", 0},
539 {"(42)PEPTIDE(41)", "(42)PEPTIDE(42)", -1},
540 {"(42)PEPTIDE(42)", "(42)PEPTIDE(41)", 1},
541 {"(42)PEPTIDE", "(42)PEPTIDE(42)", -1},
542 {"(42)PEPTIDE(42)", "PEPTIDE(42)", 1},
543 {"P(42)EPTIDE(42)", "PEPTIDE(42)", 1},
544 {"(42)PEPTIDE", "P(42)EPTIDE", -1},
545 {"P(42)EPTIDE", "(42)PEPTIDE", 1},
546};
547
548const size_t testOperatorsSize = sizeof(testOperators)/sizeof(TestOperator);
549
551{
552 for (size_t i=0; i < testOperatorsSize; ++i)
553 {
554 const TestOperator& p = testOperators[i];
555 try
556 {
557 Peptide lhs(p.lhsPeptide);
558 Peptide rhs(p.rhsPeptide);
559
560 switch(p.compare)
561 {
562 case 0:
563 unit_assert(lhs == rhs);
564 unit_assert(!(lhs < rhs));
566 unit_assert(!(lhs.modifications() < rhs.modifications()));
567 break;
568
569 case -1:
570 unit_assert(lhs < rhs);
571 unit_assert(!(lhs == rhs));
572 if (!lhs.modifications().empty() || !rhs.modifications().empty())
573 {
575 unit_assert(!(lhs.modifications() == rhs.modifications()));
576 }
577 break;
578
579 case 1:
580 unit_assert(!(lhs == rhs));
581 unit_assert(!(lhs < rhs));
582 if (!lhs.modifications().empty() || !rhs.modifications().empty())
583 {
584 unit_assert(!(lhs.modifications() == rhs.modifications()));
585 unit_assert(!(lhs.modifications() < rhs.modifications()));
586 }
587 break;
588 }
589 }
590 catch (exception& e)
591 {
592 cout << "Unit test " << lexical_cast<string>(i+1) << " comparing \"" << p.lhsPeptide << "\" and \"" << p.rhsPeptide << "\" failed:\n" << e.what() << endl;
593 }
594 }
595}
596
597
599{
600 const char* sequence;
601 double a1, aN, a1Plus2, aNPlus2;
602 double b1, bN, b1Plus2, bNPlus2;
603 double c1, cN, c1Plus2, cNPlus2;
604 double x1, xN, x1Plus2, xNPlus2;
605 double y1, yN, y1Plus2, yNPlus2;
606 double z1, zN, z1Plus2, zNPlus2;
607};
608
609// test masses calculated at:
610// $Id$tml
612{
613 { "MEERKAT",
614 104.05344, 818.41949, 52.53066, 409.71368,
615 132.04836, 846.41441, 66.52811, 423.71114,
616 149.07490, 762.39328, 75.04139, 381.70057,
617 146.04538, 759.36375, 73.52662, 380.18581,
618 120.06611, 864.42497, 60.53699, 432.71642,
619 103.03956, 847.39842, 52.02372, 424.20315
620 },
621
622 { "THEQICKRWNFMPSVERTHELAYDG",
623 74.06063, 3001.42018, 37.53425, 1501.21402,
624 102.05555, 3029.41509, 51.53171, 1515.21148,
625 119.08210, 2989.42018, 60.04498, 1495.21402,
626 102.01916, 2972.35724, 51.51352, 1486.68256,
627 76.03990, 3047.42566, 38.52388, 1524.21676,
628 59.01335, 3030.39911, 30.01061, 1515.70349
629 },
630};
631
633
634void writeFragmentation(const Peptide& p, const Fragmentation& f, ostream& os)
635{
636 size_t length = p.sequence().length();
637
638 os << "a:";
639 for (size_t i=1; i <= length; ++i)
640 os << " " << f.a(i);
641 os << endl;
642
643 os << "b:";
644 for (size_t i=1; i <= length; ++i)
645 os << " " << f.b(i);
646 os << endl;
647
648 os << "c:";
649 for (size_t i=1; i < length; ++i)
650 os << " " << f.c(i);
651 os << endl;
652
653 os << "x:";
654 for (size_t i=1; i < length; ++i)
655 os << " " << f.x(i);
656 os << endl;
657
658 os << "y:";
659 for (size_t i=1; i <= length; ++i)
660 os << " " << f.y(i);
661 os << endl;
662
663 os << "z:";
664 for (size_t i=1; i <= length; ++i)
665 os << " " << f.z(i);
666 os << endl;
667}
668
670{
671 const double EPSILON = 0.005;
672
673 for (size_t i=0; i < testFragmentationsSize; ++i)
674 {
676 size_t length = string(tf.sequence).length();
677 Peptide peptide(tf.sequence);
678 if (os_) *os_ << peptide.sequence() << ": " << peptide.monoisotopicMass() << endl;
679
680 Fragmentation f = peptide.fragmentation();
681 if (os_) writeFragmentation(peptide, f, *os_);
682
683 unit_assert_equal(tf.a1 - Proton, f.a(1), EPSILON);
684 unit_assert_equal(tf.b1 - Proton, f.b(1), EPSILON);
685 unit_assert_equal(tf.c1 - Proton, f.c(1), EPSILON);
686 unit_assert_equal(tf.x1 - Proton, f.x(1), EPSILON);
687 unit_assert_equal(tf.y1 - Proton, f.y(1), EPSILON);
688 unit_assert_equal(tf.z1 - Proton, f.z(1), EPSILON);
689
690 unit_assert_equal(tf.aN - Proton, f.a(length), EPSILON);
691 unit_assert_equal(tf.bN - Proton, f.b(length), EPSILON);
692 unit_assert_equal(tf.cN - Proton, f.c(length-1), EPSILON);
693 unit_assert_equal(tf.xN - Proton, f.x(length-1), EPSILON);
694 unit_assert_equal(tf.yN - Proton, f.y(length), EPSILON);
695 unit_assert_equal(tf.zN - Proton, f.z(length), EPSILON);
696
697 unit_assert_equal(tf.a1, f.a(1, 1), EPSILON);
698 unit_assert_equal(tf.b1, f.b(1, 1), EPSILON);
699 unit_assert_equal(tf.c1, f.c(1, 1), EPSILON);
700 unit_assert_equal(tf.x1, f.x(1, 1), EPSILON);
701 unit_assert_equal(tf.y1, f.y(1, 1), EPSILON);
702 unit_assert_equal(tf.z1, f.z(1, 1), EPSILON);
703
704 unit_assert_equal(tf.aN, f.a(length, 1), EPSILON);
705 unit_assert_equal(tf.bN, f.b(length, 1), EPSILON);
706 unit_assert_equal(tf.cN, f.c(length-1, 1), EPSILON);
707 unit_assert_equal(tf.xN, f.x(length-1, 1), EPSILON);
708 unit_assert_equal(tf.yN, f.y(length, 1), EPSILON);
709 unit_assert_equal(tf.zN, f.z(length, 1), EPSILON);
710
711 unit_assert_equal(tf.a1Plus2, f.a(1, 2), EPSILON);
712 unit_assert_equal(tf.b1Plus2, f.b(1, 2), EPSILON);
713 unit_assert_equal(tf.c1Plus2, f.c(1, 2), EPSILON);
714 unit_assert_equal(tf.x1Plus2, f.x(1, 2), EPSILON);
715 unit_assert_equal(tf.y1Plus2, f.y(1, 2), EPSILON);
716 unit_assert_equal(tf.z1Plus2, f.z(1, 2), EPSILON);
717
718 unit_assert_equal(tf.aNPlus2, f.a(length, 2), EPSILON);
719 unit_assert_equal(tf.bNPlus2, f.b(length, 2), EPSILON);
720 unit_assert_equal(tf.cNPlus2, f.c(length-1, 2), EPSILON);
721 unit_assert_equal(tf.xNPlus2, f.x(length-1, 2), EPSILON);
722 unit_assert_equal(tf.yNPlus2, f.y(length, 2), EPSILON);
723 unit_assert_equal(tf.zNPlus2, f.z(length, 2), EPSILON);
724 }
725
726 // test fragmentation with mods
727 {
728 Peptide p("THEQICKRWNFMPSVERTHELAYDG");
729 Modification C57("C2H3N1O1"), M16("O1");
730 (p.modifications())[5].push_back(C57);
731 (p.modifications())[11].push_back(M16);
732 Fragmentation f = p.fragmentation(true, false);
733 Fragmentation fWithMods = p.fragmentation(true, true);
734 if (os_) writeFragmentation(p, f, *os_);
735 if (os_) writeFragmentation(p, fWithMods, *os_);
736 double EPSILON = 0.00000001;
737 for (size_t i=1; i <= 5; ++i)
738 {
739 unit_assert_equal(f.a(i), fWithMods.a(i), EPSILON);
740 unit_assert_equal(f.b(i), fWithMods.b(i), EPSILON);
741 unit_assert_equal(f.c(i), fWithMods.c(i), EPSILON);
742 }
743
744 for (size_t i=6; i <= 11; ++i)
745 {
746 double deltaMass = C57.monoisotopicDeltaMass();
747 unit_assert_equal(f.a(i)+deltaMass, fWithMods.a(i), EPSILON);
748 unit_assert_equal(f.b(i)+deltaMass, fWithMods.b(i), EPSILON);
749 unit_assert_equal(f.c(i)+deltaMass, fWithMods.c(i), EPSILON);
750 }
751
752 for (size_t i=12; i <= p.sequence().length(); ++i)
753 {
754 double deltaMass = C57.monoisotopicDeltaMass() + M16.monoisotopicDeltaMass();
755 unit_assert_equal(f.a(i)+deltaMass, fWithMods.a(i), EPSILON);
756 unit_assert_equal(f.b(i)+deltaMass, fWithMods.b(i), EPSILON);
757 if (i < p.sequence().length())
758 unit_assert_equal(f.c(i)+deltaMass, fWithMods.c(i), EPSILON);
759 }
760
761 for (size_t i=1; i <= 13; ++i)
762 {
763 unit_assert_equal(f.x(i), fWithMods.x(i), EPSILON);
764 unit_assert_equal(f.y(i), fWithMods.y(i), EPSILON);
765 unit_assert_equal(f.z(i), fWithMods.z(i), EPSILON);
766 }
767
768 for (size_t i=14; i <= 19; ++i)
769 {
770 double deltaMass = M16.monoisotopicDeltaMass();
771 unit_assert_equal(f.x(i)+deltaMass, fWithMods.x(i), EPSILON);
772 unit_assert_equal(f.y(i)+deltaMass, fWithMods.y(i), EPSILON);
773 unit_assert_equal(f.z(i)+deltaMass, fWithMods.z(i), EPSILON);
774 }
775
776 for (size_t i=20; i <= p.sequence().length(); ++i)
777 {
778 double deltaMass = C57.monoisotopicDeltaMass() + M16.monoisotopicDeltaMass();
779 if (i < p.sequence().length())
780 unit_assert_equal(f.x(i)+deltaMass, fWithMods.x(i), EPSILON);
781 unit_assert_equal(f.y(i)+deltaMass, fWithMods.y(i), EPSILON);
782 unit_assert_equal(f.z(i)+deltaMass, fWithMods.z(i), EPSILON);
783 }
784 }
785
786 {
787 Peptide p("QICKRWNFMPSVERTHELAYDG");
788 Modification Q17("N-1H-3"), S80("H1P1O3");
789 (p.modifications())[ModificationMap::NTerminus()].push_back(Q17); // close enough
790 (p.modifications())[10].push_back(S80);
791 Fragmentation f = p.fragmentation(true, false);
792 Fragmentation fWithMods = p.fragmentation(true, true);
793 if (os_) writeFragmentation(p, f, *os_);
794 if (os_) writeFragmentation(p, fWithMods, *os_);
795 double EPSILON = 0.00000001;
796
797 for (size_t i=0; i <= 10; ++i)
798 {
799 double deltaMass = Q17.monoisotopicDeltaMass();
800 unit_assert_equal(f.a(i)+deltaMass, fWithMods.a(i), EPSILON);
801 unit_assert_equal(f.b(i)+deltaMass, fWithMods.b(i), EPSILON);
802 unit_assert_equal(f.c(i)+deltaMass, fWithMods.c(i), EPSILON);
803 }
804
805 for (size_t i=11; i <= p.sequence().length(); ++i)
806 {
807 double deltaMass = Q17.monoisotopicDeltaMass() + S80.monoisotopicDeltaMass();
808 unit_assert_equal(f.a(i)+deltaMass, fWithMods.a(i), EPSILON);
809 unit_assert_equal(f.b(i)+deltaMass, fWithMods.b(i), EPSILON);
810 if (i < p.sequence().length())
811 unit_assert_equal(f.c(i)+deltaMass, fWithMods.c(i), EPSILON);
812 }
813
814 for (size_t i=1; i <= 11; ++i)
815 {
816 unit_assert_equal(f.x(i), fWithMods.x(i), EPSILON);
817 unit_assert_equal(f.y(i), fWithMods.y(i), EPSILON);
818 unit_assert_equal(f.z(i), fWithMods.z(i), EPSILON);
819 }
820
821 for (size_t i=12; i <= p.sequence().length(); ++i)
822 {
823 double deltaMass = S80.monoisotopicDeltaMass();
824 if (i < p.sequence().length())
825 unit_assert_equal(f.x(i)+deltaMass, fWithMods.x(i), EPSILON);
826 unit_assert_equal(f.y(i)+deltaMass, fWithMods.y(i), EPSILON);
827 unit_assert_equal(f.z(i)+deltaMass, fWithMods.z(i), EPSILON);
828 }
829 }
830}
831
832
833void testThreadSafetyWorker(boost::barrier* testBarrier)
834{
835 testBarrier->wait(); // wait until all threads have started
836
837 try
838 {
839 peptideTest();
841 operatorTest();
842 fragmentTest();
843 }
844 catch (exception& e)
845 {
846 cerr << "Exception in worker thread: " << e.what() << endl;
847 }
848 catch (...)
849 {
850 cerr << "Unhandled exception in worker thread." << endl;
851 }
852}
853
854void testThreadSafety(const int& testThreadCount)
855{
856 boost::barrier testBarrier(testThreadCount);
857 boost::thread_group testThreadGroup;
858 for (int i=0; i < testThreadCount; ++i)
859 testThreadGroup.add_thread(new boost::thread(&testThreadSafetyWorker, &testBarrier));
860 testThreadGroup.join_all();
861}
862
863
864int main(int argc, char* argv[])
865{
866 TEST_PROLOG(argc, argv)
867
868 try
869 {
870 if (argc>1 && !strcmp(argv[1],"-v")) os_ = &cout;
871 if (os_) *os_ << "PeptideTest\n";
872 //test();
873 //isotopeTest();
874
875 //testThreadSafety(1); // does not test thread-safety of singleton initialization
880 }
881 catch (exception& e)
882 {
883 TEST_FAILED(e.what())
884 }
885 catch (...)
886 {
887 TEST_FAILED("Caught unknown exception.")
888 }
889
891}
892
void testThreadSafety()
ModificationDelimiter_Parentheses
Definition Peptide.hpp:51
ModificationParsing_ByMass
oxidized P in peptide: PEP(O)TIDE
Definition Peptide.hpp:44
ModificationParsing_ByFormula
any non-AA characters will cause an exception
Definition Peptide.hpp:43
ModificationParsing_Off
Definition Peptide.hpp:42
ModificationDelimiter_Brackets
'(' and ')'
Definition Peptide.hpp:52
int main(int argc, char *argv[])
void operatorTest()
const TestOperator testOperators[]
void testThreadSafetyWorker(boost::barrier *testBarrier)
const TestFragmentation testFragmentations[]
void writeFragmentation(const Peptide &p, const Fragmentation &f, ostream &os)
void peptideTest()
void fragmentTest()
const size_t testPeptidesSize
const size_t testOperatorsSize
const size_t testFragmentationsSize
void modificationTest()
TestModifiedPeptide testModifiedPeptides[]
TestPeptide testPeptides[]
const char * sequences[]
TestModification testModifications[]
ostream * os_
const size_t testModificationsSize
void test()
const size_t testModifiedPeptidesSize
double monoisotopicMass() const
double molecularWeight() const
provides fragment ion masses for a peptide
Definition Peptide.hpp:121
double x(size_t length, size_t charge=0) const
returns the x ion of length <length> example: x(1) returns the x1 ion if <charge> = 0: returns neutra...
double c(size_t length, size_t charge=0) const
returns the c ion of length <length> example: c(1) returns the c1 ion if <charge> = 0: returns neutra...
double z(size_t length, size_t charge=0) const
returns the z ion of length <length> example: z(1) returns the z1 ion if <charge> = 0: returns neutra...
double b(size_t length, size_t charge=0) const
returns the b ion of length <length> example: b(1) returns the b1 ion if <charge> = 0: returns neutra...
double a(size_t length, size_t charge=0) const
returns the a ion of length <length>; example: a(1) returns the a1 ion if <charge> = 0: returns neutr...
double y(size_t length, size_t charge=0) const
returns the y ion of length <length> example: y(1) returns the y1 ion if <charge> = 0: returns neutra...
represents a post-translational modification (PTM) modification formula or masses must be provided at...
double monoisotopicDeltaMass() const
represents a list of modifications on a single amino acid
maps peptide/protein sequence indexes (0-based) to a modification list
virtual iterator end()
Returns an iterator pointing to the last element stored in the map; in other words,...
virtual iterator find(const key_type &x)
Searches the map for a pair with the key value x and returns an iterator to that pair if it is found....
represents a peptide or polypeptide (a sequence of amino acids)
Definition Peptide.hpp:62
const std::string & sequence() const
returns the sequence of amino acids making up the peptide
chemistry::Formula formula(bool modified=false) const
if modified = false: returns the composition formula of sequence()+water if modified = true: returns ...
double molecularWeight(int charge=0, bool modified=true) const
if charge = 0: returns neutral mass if charge > 0: returns charged m/z if modified = false: returns t...
double monoisotopicMass(int charge=0, bool modified=true) const
if charge = 0: returns neutral mass if charge > 0: returns charged m/z if modified = false: returns t...
Fragmentation fragmentation(bool monoisotopic=true, bool modified=true) const
returns a fragmentation model for the peptide; fragment masses can calculated as mono/avg and as modi...
ModificationMap & modifications()
the map of sequence offsets (0-based) to modifications; modifications can be added or removed from th...
virtual bool empty() const
Returns true if the map is empty, false otherwise.
const double Proton
the mass of a proton in unified atomic mass units
Definition Chemistry.hpp:41
const char * sequence
const char * formula
const char * motif
ModificationParsing mp
ModificationDelimiter md
const char * sequence
const char * rhsPeptide
const char * lhsPeptide
double avgMassNeutral
double avgMassPlus2
double monoMassPlus2
const char * sequence
double monoMassNeutral
double monoMassPlus1
double avgMassPlus1
#define unit_assert(x)
Definition unit.hpp:85
#define TEST_EPILOG
Definition unit.hpp:183
#define TEST_FAILED(x)
Definition unit.hpp:177
#define unit_assert_equal(x, y, epsilon)
Definition unit.hpp:99
#define unit_assert_throws_what(x, exception, whatStr)
Definition unit.hpp:119
#define TEST_PROLOG(argc, argv)
Definition unit.hpp:175