libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
aamodification.cpp
Go to the documentation of this file.
1/**
2 * \file pappsomspp/amino_acid/aamodification.h
3 * \date 7/3/2015
4 * \author Olivier Langella
5 * \brief amino acid modification model
6 */
7
8/*******************************************************************************
9 * Copyright (c) 2015 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
10 *
11 * This file is part of the PAPPSOms++ library.
12 *
13 * PAPPSOms++ is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * PAPPSOms++ is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with PAPPSOms++. If not, see <http://www.gnu.org/licenses/>.
25 *
26 * Contributors:
27 * Olivier Langella <Olivier.Langella@moulon.inra.fr> - initial API and
28 *implementation
29 ******************************************************************************/
30
31#include <QRegularExpression>
32#include <QDebug>
33#include <cmath>
34
35#include "aamodification.h"
36#include "aa.h"
37#include "../pappsoexception.h"
38#include "../mzrange.h"
39#include "../peptide/peptide.h"
43
44/*
45
46inline void initMyResource() {
47 Q_INIT_RESOURCE(resources);
48}
49*/
50
51namespace pappso
52{
53
55
56AaModification::AaModification(const QString &accession, pappso_double mass)
57 : m_accession(accession), m_mass(mass)
58{
64
66 {Isotope::H2, 0},
67 {Isotope::N15, 0},
68 {Isotope::O17, 0},
69 {Isotope::O18, 0},
70 {Isotope::S33, 0},
71 {Isotope::S34, 0},
72 {Isotope::S36, 0}};
73}
74
75
77 : m_accession(toCopy.m_accession),
78 m_name(toCopy.m_name),
79 m_mass(toCopy.m_mass),
80 m_atomCount(std::move(toCopy.m_atomCount)),
81 m_mapIsotope(toCopy.m_mapIsotope)
82{
83 m_origin = toCopy.m_origin;
84}
85
89
90const QString &
92{
93
94 // qDebug();
95 return m_accession;
96}
97
98
99const QString
101{
102 QString str_return;
103 // qDebug();
104 if(m_accession.startsWith("MOD:"))
105 return m_accession;
106
107 if(m_accession.startsWith("internal:"))
108 return str_return;
109
110 if(m_accession.startsWith("MUTATION:"))
111 {
112 // MUTATION:%1=>%2
113 QStringList aa_list = m_accession.mid(9).split("=>");
114 // first, find removal accession
115 return QString("%1][%2")
116 .arg(getInstanceRemovalAccessionByAaLetter(aa_list[0].at(0))
117 ->getAccession())
118 .arg(getInstanceInsertionAccessionByAaLetter(aa_list[1].at(0))
119 ->getAccession());
120 }
121
122 if(m_mass > 0)
123 {
124 return QString("+%1").arg(QString::number(m_mass, 'f', 4));
125 }
126 else
127 {
128 return QString("%1").arg(QString::number(m_mass, 'f', 4));
129 }
130 return str_return;
131}
132
133const QString &
135{
136 return m_name;
137}
138
139const QString &
141{
142 return m_origin;
143}
144
147 MapAccessionModifications ret;
148
149 return ret;
150 }();
151
154{
155 AaModification *new_mod;
156 // qDebug() << " AaModification::createInstance begin";
157 new_mod = new AaModification(term.m_accession, term.m_diffMono);
158 // xref: DiffFormula: "C 0 H 0 N 0 O 1 S 0"
159 new_mod->setDiffFormula(term.m_diffFormula);
160 new_mod->setXrefOrigin(term.m_origin);
161 new_mod->m_name = term.m_name;
162
163 qDebug() << "is_a " << term.m_isA.join(" ");
164 if(term.isA("MOD:01441"))
165 {
166 qDebug() << "term.isA(MOD:01441)";
167 if(term.m_origin.isEmpty())
168 {
169 throw ExceptionNotFound(
170 QObject::tr("origin not found for term : [%1]")
171 .arg(term.m_accession));
172 }
173
174 new_mod->setDiffFormula(term.m_formula);
175 // new_mod->m_mass = AaBase::getAaMass(term.m_origin[0].toLatin1());
176 }
177 qDebug() << new_mod->m_mass;
178 return new_mod;
179}
180
182AaModification::createInstance(const QString &accession)
183{
184 if(accession == "internal:Nter_hydrolytic_cleavage_H")
185 {
186 OboPsiModTerm term;
187 term.m_accession = accession;
188 term.m_diffFormula = "H 1";
189 term.m_diffMono = MPROTIUM;
190 term.m_name = "Nter hydrolytic cleavage H+";
191 return (AaModification::createInstance(term));
192 }
193 if(accession == "internal:Cter_hydrolytic_cleavage_HO")
194 {
195 OboPsiModTerm term;
196 term.m_accession = accession;
197 term.m_diffFormula = "H 1 O 1";
199 term.m_name = "Cter hydrolytic cleavage HO";
200 return (AaModification::createInstance(term));
201 }
202 if(accession.startsWith("MUTATION:"))
203 {
204 QRegularExpression regexp_mutation("^MUTATION:([A-Z])=>([A-Z])$");
205 QRegularExpressionMatch match = regexp_mutation.match(accession);
206 if(match.hasMatch())
207 {
208 qDebug() << match.capturedTexts()[1].at(0) << " "
209 << match.capturedTexts()[2].at(0);
210
211 Aa aa_from(match.capturedTexts()[1].toStdString().c_str()[0]);
212 Aa aa_to(match.capturedTexts()[2].toStdString().c_str()[0]);
213 AaModificationP instance_mutation =
214 createInstanceMutation(aa_from, aa_to);
215 return instance_mutation;
216 // m_psiModLabel<<"|";
217 }
218 }
219 if(accession.startsWith("C13N15:"))
220 {
221 QRegularExpression regexp_label("^C13N15:([A-Z])$");
222 QRegularExpressionMatch match = regexp_label.match(accession);
223 if(match.hasMatch())
224 {
225 char labelled_aa(match.capturedTexts()[1].toStdString().c_str()[0]);
226
227 AaModificationP instance_labelled_aa_p =
228 createInstanceC13N15LabelledAminoAcid(QChar(labelled_aa));
229
230
231 return instance_labelled_aa_p;
232 // m_psiModLabel<<"|";
233 }
234 }
235 // initMyResource();
236 FilterOboPsiModSink term_list;
237 FilterOboPsiModTermAccession filterm_accession(term_list, accession);
238
239 OboPsiMod psimod(filterm_accession);
240
241 try
242 {
243 return (AaModification::createInstance(term_list.getOne()));
244 }
245 catch(ExceptionNotFound &e)
246 {
247 throw ExceptionNotFound(QObject::tr("modification not found : [%1]\n%2")
248 .arg(accession)
249 .arg(e.qwhat()));
250 }
251}
252
253void
254AaModification::setXrefOrigin(const QString &origin)
255{
256 // xref: Origin: "N"
257 // xref: Origin: "X"
258 m_origin = origin;
259}
260void
261AaModification::setDiffFormula(const QString &diff_formula)
262{
263 QRegularExpression rx("(^|\\s)([C,H,O,N,H,S])\\s([-]{0,1}\\d+)");
264 QRegularExpressionMatchIterator i = rx.globalMatch(diff_formula);
265
266 while(i.hasNext())
267 {
268 QRegularExpressionMatch match = i.next();
269
270 qDebug() << match.captured(2) << " " << match.captured(2) << " "
271 << match.captured(3);
272
273 if(match.captured(2) == "C")
274 {
275 m_atomCount[AtomIsotopeSurvey::C] = match.captured(3).toInt();
276 }
277 else if(match.captured(2) == "H")
278 {
279 m_atomCount[AtomIsotopeSurvey::H] = match.captured(3).toInt();
280 }
281 else if(match.captured(2) == "N")
282 {
283 m_atomCount[AtomIsotopeSurvey::N] = match.captured(3).toInt();
284 }
285 else if(match.captured(2) == "O")
286 {
287 m_atomCount[AtomIsotopeSurvey::O] = match.captured(3).toInt();
288 }
289 else if(match.captured(2) == "S")
290 {
291 m_atomCount[AtomIsotopeSurvey::S] = match.captured(3).toInt();
292 }
293 }
294
295 // look for isotopes :
296 rx.setPattern("\\(([-]{0,1}\\d+)\\)([C,H,O,N,H,S])\\s([-]{0,1}\\d+)");
297
298 i = rx.globalMatch(diff_formula);
299
300 while(i.hasNext())
301 {
302 QRegularExpressionMatch match = i.next();
303
304 qDebug() << match.captured(1) << " " << match.captured(2) << " "
305 << match.captured(3);
306
307 int number_of_isotopes = match.captured(3).toInt();
308
309 if(match.captured(2) == "C")
310 {
311 if(match.captured(1) == "13")
312 {
313 m_mapIsotope.at(Isotope::C13) = number_of_isotopes;
314 }
315 m_atomCount[AtomIsotopeSurvey::C] += number_of_isotopes;
316 }
317 else if(match.captured(2) == "H")
318 {
319 if(match.captured(1) == "2")
320 {
321 m_mapIsotope.at(Isotope::H2) = number_of_isotopes;
322 }
323 m_atomCount[AtomIsotopeSurvey::H] += number_of_isotopes;
324 }
325 else if(match.captured(2) == "N")
326 {
327 if(match.captured(1) == "15")
328 {
329 m_mapIsotope.at(Isotope::N15) = number_of_isotopes;
330 }
331 m_atomCount[AtomIsotopeSurvey::N] += number_of_isotopes;
332 }
333 else if(match.captured(2) == "O")
334 {
335 if(match.captured(1) == "17")
336 {
337 m_mapIsotope.at(Isotope::O17) = number_of_isotopes;
338 }
339 else if(match.captured(1) == "18")
340 {
341 m_mapIsotope.at(Isotope::O18) = number_of_isotopes;
342 }
343 m_atomCount[AtomIsotopeSurvey::O] += number_of_isotopes;
344 }
345 else if(match.captured(2) == "S")
346 {
347 if(match.captured(1) == "33")
348 {
349 m_mapIsotope.at(Isotope::S33) = number_of_isotopes;
350 }
351 else if(match.captured(1) == "34")
352 {
353 m_mapIsotope.at(Isotope::S34) = number_of_isotopes;
354 }
355 else if(match.captured(1) == "36")
356 {
357 m_mapIsotope.at(Isotope::S36) = number_of_isotopes;
358 }
359 m_atomCount[AtomIsotopeSurvey::S] += number_of_isotopes;
360 }
361 }
362
364}
365
366
367void
369{
370 pappso_double theoreticalm_mass = 0;
371 std::map<AtomIsotopeSurvey, int>::const_iterator it_atom =
373 if(it_atom != m_atomCount.end())
374 {
375 theoreticalm_mass += MASSCARBON * (it_atom->second);
376 }
377 it_atom = m_atomCount.find(AtomIsotopeSurvey::H);
378 if(it_atom != m_atomCount.end())
379 {
380 theoreticalm_mass += MPROTIUM * (it_atom->second);
381 }
382
383 it_atom = m_atomCount.find(AtomIsotopeSurvey::O);
384 if(it_atom != m_atomCount.end())
385 {
386 theoreticalm_mass += MASSOXYGEN * (it_atom->second);
387 }
388
389 it_atom = m_atomCount.find(AtomIsotopeSurvey::N);
390 if(it_atom != m_atomCount.end())
391 {
392 theoreticalm_mass += MASSNITROGEN * (it_atom->second);
393 }
394 it_atom = m_atomCount.find(AtomIsotopeSurvey::S);
395 if(it_atom != m_atomCount.end())
396 {
397 theoreticalm_mass += MASSSULFUR * (it_atom->second);
398 }
399
400 qDebug() << theoreticalm_mass;
401
402 theoreticalm_mass += DIFFC12C13 * m_mapIsotope.at(Isotope::C13);
403 theoreticalm_mass += DIFFH1H2 * m_mapIsotope.at(Isotope::H2);
404 theoreticalm_mass += DIFFN14N15 * m_mapIsotope.at(Isotope::N15);
405 theoreticalm_mass += DIFFO16O17 * m_mapIsotope.at(Isotope::O17);
406 theoreticalm_mass += DIFFO16O18 * m_mapIsotope.at(Isotope::O18);
407 theoreticalm_mass += DIFFS32S33 * m_mapIsotope.at(Isotope::S33);
408 theoreticalm_mass += DIFFS32S34 * m_mapIsotope.at(Isotope::S34);
409 theoreticalm_mass += DIFFS32S36 * m_mapIsotope.at(Isotope::S36);
410
411
412 if(m_mass == 0.0)
413 {
414 m_mass = theoreticalm_mass;
415 }
416 else
417 {
418 pappso_double diff = std::fabs((pappso_double)m_mass - theoreticalm_mass);
419 if(diff < 0.001)
420 {
421 m_mass = theoreticalm_mass;
422 qDebug() << diff;
423 }
424 else
425 {
426 qDebug()
427 << "ERROR in AaModification::calculateMassFromChemicalComponents "
428 "theo="
429 << theoreticalm_mass << " m=" << m_mass << " diff=" << diff
430 << " accession=" << m_accession;
431 }
432 }
433}
434
437{
438 QString accession = QString("%1").arg(modificationMass);
439 qDebug() << accession;
440 QMutexLocker locker(&m_mutex);
441 if(m_mapAccessionModifications.find(accession) ==
443 {
444 // not found
445 m_mapAccessionModifications.insert(std::pair<QString, AaModification *>(
446 accession, new AaModification(accession, modificationMass)));
447 }
448 else
449 {
450 // found
451 }
452 return m_mapAccessionModifications.at(accession);
453}
454
456AaModification::getInstance(const QString &accession)
457{
458 try
459 {
460 QMutexLocker locker(&m_mutex);
461 MapAccessionModifications::iterator it =
462 m_mapAccessionModifications.find(accession);
463 if(it == m_mapAccessionModifications.end())
464 {
465
466 // not found
467 std::pair<MapAccessionModifications::iterator, bool> insert_res =
469 std::pair<QString, AaModificationP>(
470 accession, AaModification::createInstance(accession)));
471 it = insert_res.first;
472 }
473 else
474 {
475 // found
476 }
477 return it->second;
478 }
479 catch(ExceptionNotFound &e)
480 {
481 throw ExceptionNotFound(
482 QObject::tr("ERROR getting instance of : %1 NOT FOUND\n%2")
483 .arg(accession)
484 .arg(e.qwhat()));
485 }
486 catch(PappsoException &e)
487 {
488 throw PappsoException(QObject::tr("ERROR getting instance of %1\n%2")
489 .arg(accession)
490 .arg(e.qwhat()));
491 }
492 catch(std::exception &e)
493 {
494 throw PappsoException(QObject::tr("ERROR getting instance of %1\n%2")
495 .arg(accession)
496 .arg(e.what()));
497 }
498}
499
502{
503 switch(amino_acid.toLatin1())
504 {
505 // AminoAcidChar::alanine
506 case 'A':
507 return getInstance("MOD:01631");
508 break;
509 // AminoAcidChar::arginine,
510 case 'R':
511 return getInstance("MOD:01632");
512 break;
513 // AminoAcidChar::cysteine,
514 case 'C':
515 return getInstance("MOD:01635");
516 break;
517 // AminoAcidChar::aspartic_acid,
518 case 'D':
519 return getInstance("MOD:01634");
520 break;
521 // AminoAcidChar::glutamic_acid,
522 case 'E':
523 return getInstance("MOD:01636");
524 break;
525
526 // AminoAcidChar::phenylalanine,
527 case 'F':
528 return getInstance("MOD:01644");
529 break;
530 // AminoAcidChar::glycine,
531 case 'G':
532 return getInstance("MOD:01638");
533 break;
534 // AminoAcidChar::histidine,
535 case 'H':
536 return getInstance("MOD:01639");
537 break;
538
539 // AminoAcidChar::isoleucine,
540 case 'I':
541 return getInstance("MOD:01640");
542 break;
543
544 // AminoAcidChar::lysine,
545 case 'K':
546 return getInstance("MOD:01642");
547 break;
548 // AminoAcidChar::leucine,
549 case 'L':
550 return getInstance("MOD:01641");
551 break;
552
553 // AminoAcidChar::methionine,
554 case 'M':
555 return getInstance("MOD:01643");
556 break;
557
558 // AminoAcidChar::asparagine,
559 case 'N':
560 return getInstance("MOD:01633");
561 break;
562
563 // AminoAcidChar::proline,
564 case 'P':
565 return getInstance("MOD:01645");
566 break;
567
568 // AminoAcidChar::glutamine,
569 case 'Q':
570 return getInstance("MOD:01637");
571 break;
572 // AminoAcidChar::serine,
573 case 'S':
574 return getInstance("MOD:01646");
575 break;
576
577 // AminoAcidChar::threonine,
578 case 'T':
579 return getInstance("MOD:01647");
580 break;
581
582
583 // AminoAcidChar::valine,
584 case 'V':
585 return getInstance("MOD:01650");
586 break;
587
588 // AminoAcidChar::tryptophan,
589 case 'W':
590 return getInstance("MOD:01648");
591 break;
592
593 // AminoAcidChar::tyrosine,
594 case 'Y':
595 return getInstance("MOD:01649");
596 break;
597
598 default:
599 throw ExceptionNotFound(
600 QObject::tr("ERROR getting removal accession instance of amino acid: "
601 "%1 NOT FOUND")
602 .arg(amino_acid));
603 }
604}
605
608{
609 pappso::AaModificationP aa_insert = nullptr;
610 switch(amino_acid.toLatin1())
611 {
612 // AminoAcidChar::alanine
613 case 'A':
614 aa_insert = getInstance("MOD:00010");
615 break;
616
617 // AminoAcidChar::arginine,
618 case 'R':
619 aa_insert = getInstance("MOD:00011");
620 break;
621
622 // AminoAcidChar::cysteine,
623 case 'C':
624 aa_insert = getInstance("MOD:00014");
625 break;
626
627 // AminoAcidChar::aspartic_acid,
628 case 'D':
629 aa_insert = getInstance("MOD:00013");
630 break;
631
632 // AminoAcidChar::glutamic_acid,
633 case 'E':
634 aa_insert = getInstance("MOD:00015");
635 break;
636
637 // AminoAcidChar::phenylalanine,
638 case 'F':
639 aa_insert = getInstance("MOD:00023");
640 break;
641
642 // AminoAcidChar::glycine,
643 case 'G':
644 aa_insert = getInstance("MOD:00017");
645 break;
646
647 // AminoAcidChar::histidine,
648 case 'H':
649 aa_insert = getInstance("MOD:00018");
650 break;
651
652 // AminoAcidChar::isoleucine,
653 case 'I':
654 aa_insert = getInstance("MOD:00019");
655 break;
656
657 // AminoAcidChar::lysine,
658 case 'K':
659 aa_insert = getInstance("MOD:00021");
660 break;
661 // AminoAcidChar::leucine,
662 case 'L':
663 aa_insert = getInstance("MOD:00020");
664 break;
665
666 // AminoAcidChar::methionine,
667 case 'M':
668 aa_insert = getInstance("MOD:00022");
669 break;
670
671 // AminoAcidChar::asparagine,
672 case 'N':
673 aa_insert = getInstance("MOD:00012");
674 break;
675
676 // AminoAcidChar::proline,
677 case 'P':
678 aa_insert = getInstance("MOD:00024");
679 break;
680
681 // AminoAcidChar::glutamine,
682 case 'Q':
683 aa_insert = getInstance("MOD:00016");
684 break;
685 // AminoAcidChar::serine,
686 case 'S':
687 aa_insert = getInstance("MOD:00025");
688 break;
689
690 // AminoAcidChar::threonine,
691 case 'T':
692 aa_insert = getInstance("MOD:00026");
693 break;
694
695
696 // AminoAcidChar::valine,
697 case 'V':
698 aa_insert = getInstance("MOD:00029");
699 break;
700
701 // AminoAcidChar::tryptophan,
702 case 'W':
703 aa_insert = getInstance("MOD:00027");
704 break;
705
706 // AminoAcidChar::tyrosine,
707 case 'Y':
708 aa_insert = getInstance("MOD:00028");
709 break;
710 // AminoAcidChar::selenocysteine,
711 case 'U':
712 aa_insert = getInstance("MOD:00031");
713 break;
714 default:
715 throw ExceptionNotFound(
716 QObject::tr("ERROR getting removal accession instance of amino acid: "
717 "%1 NOT FOUND")
718 .arg(amino_acid));
719 }
720
721 return aa_insert;
722}
723
726{
727
728 QMutexLocker locker(&m_mutex);
729
730 std::pair<MapAccessionModifications::iterator, bool> insert_res =
732 std::pair<QString, AaModificationP>(oboterm.m_accession, nullptr));
733
734 if(!insert_res.second)
735 {
736 // Failed to insert, was there already by same key.
737 }
738 else
739 {
740 // Could insert (albeit with nullptr), was not there already by same key.
741 // Just assign to the *correct* pair member the pointer to an
742 // extemporaneously allocated AaModification.
743 insert_res.first->second = AaModification::createInstance(oboterm);
744 }
745
746 return insert_res.first->second;
747}
748
749
752 pappso_double mass,
753 const PeptideSp &peptide_sp,
754 unsigned int position)
755{
757 if(MzRange(mass, precision).contains(getInstance("MOD:00719")->getMass()))
758 {
759 if(type == "M")
760 {
761 return getInstance("MOD:00719");
762 }
763 if(type == "K")
764 {
765 return getInstance("MOD:01047");
766 }
767 }
768 // accession== "MOD:00057"
769 if(MzRange(mass, precision).contains(getInstance("MOD:00408")->getMass()))
770 {
771 // id: MOD:00394
772 // name: acetylated residue
773 // potential N-terminus modifications
774 if(position == 0)
775 {
776 return getInstance("MOD:00408");
777 }
778 }
779 if(MzRange(mass, precision).contains(getInstance("MOD:01160")->getMass()))
780 {
781 //-17.02655
782 // loss of ammonia [MOD:01160] -17.026549
783 return getInstance("MOD:01160");
784 }
785
786 if(MzRange(mass, precision).contains(getInstance("MOD:01060")->getMass()))
787 {
788 //// iodoacetamide [MOD:00397] 57.021464
789 if(type == "C")
790 {
791 return getInstance("MOD:01060");
792 }
793 else
794 {
795 return getInstance("MOD:00397");
796 }
797 }
798 if(MzRange(mass, precision).contains(getInstance("MOD:00704")->getMass()))
799 {
800 // loss of water
801 /*
802 if (position == 0) {
803 if (peptide_sp.get()->getSequence().startsWith("EG")) {
804 return getInstance("MOD:00365");
805 }
806 if (peptide_sp.get()->getSequence().startsWith("ES")) {
807 return getInstance("MOD:00953");
808 }
809 if (type == "E") {
810 return getInstance("MOD:00420");
811 }
812 }
813 */
814 // dehydrated residue [MOD:00704] -18.010565
815 return getInstance("MOD:00704");
816 }
817 if(MzRange(mass, precision).contains(getInstance("MOD:00696")->getMass()))
818 {
819 // phosphorylated residue [MOD:00696] 79.966330
820 return getInstance("MOD:00696");
821 }
822 bool isCter = false;
823 if(peptide_sp.get()->size() == (position + 1))
824 {
825 isCter = true;
826 }
827 if((position == 0) || isCter)
828 {
829 if(MzRange(mass, precision).contains(getInstance("MOD:00429")->getMass()))
830 {
831 // dimethyl
832 return getInstance("MOD:00429");
833 }
834 if(MzRange(mass, precision).contains(getInstance("MOD:00552")->getMass()))
835 {
836 // 4x(2)H labeled dimethyl residue
837 return getInstance("MOD:00552");
838 }
839 if(MzRange(mass, precision).contains(getInstance("MOD:00638")->getMass()))
840 {
841 // 2x(13)C,6x(2)H-dimethylated arginine
842 return getInstance("MOD:00638");
843 }
844 }
845 throw PappsoException(
846 QObject::tr("tandem modification not found : %1 %2 %3 %4")
847 .arg(type)
848 .arg(mass)
849 .arg(peptide_sp.get()->getSequence())
850 .arg(position));
851}
852
855{
856 return m_mass;
857}
858
859
860int
862{
863 // qDebug() << "AaModification::getNumberOfAtom(AtomIsotopeSurvey atom) NOT
864 // IMPLEMENTED";
865 return m_atomCount.at(atom);
866}
867
868
869int
871{
872 try
873 {
874 return m_mapIsotope.at(isotope);
875 }
876 catch(std::exception &e)
877 {
878 throw PappsoException(
879 QObject::tr("ERROR in AaModification::getNumberOfIsotope %2")
880 .arg(e.what()));
881 }
882}
883
884
885bool
887{
888 if(m_accession.startsWith("internal:"))
889 {
890 return true;
891 }
892 return false;
893}
894
896AaModification::createInstanceMutation(const Aa &aa_from, const Aa &aa_to)
897{
898 QString accession(
899 QString("MUTATION:%1=>%2").arg(aa_from.getLetter()).arg(aa_to.getLetter()));
900 double diffMono = aa_to.getMass() - aa_from.getMass();
901 // not found
902 AaModification *instance_mutation;
903 // qDebug() << " AaModification::createInstance begin";
904 instance_mutation = new AaModification(accession, diffMono);
905 // xref: DiffFormula: "C 0 H 0 N 0 O 1 S 0"
906
907 for(std::int8_t atomInt = (std::int8_t)AtomIsotopeSurvey::C;
908 atomInt != (std::int8_t)AtomIsotopeSurvey::last;
909 atomInt++)
910 {
911 AtomIsotopeSurvey atom = static_cast<AtomIsotopeSurvey>(atomInt);
912 instance_mutation->m_atomCount[atom] =
913 aa_to.getNumberOfAtom(atom) - aa_from.getNumberOfAtom(atom);
914 }
915 instance_mutation->m_name = QString("mutation from %1 to %2")
916 .arg(aa_from.getLetter())
917 .arg(aa_to.getLetter());
918 return instance_mutation;
919}
920
921
923AaModification::getInstanceMutation(const QChar &mut_from, const QChar &mut_to)
924{
925 QString accession(QString("MUTATION:%1=>%2").arg(mut_from).arg(mut_to));
926 try
927 {
928 QMutexLocker locker(&m_mutex);
929 MapAccessionModifications::iterator it =
930 m_mapAccessionModifications.find(accession);
931 if(it == m_mapAccessionModifications.end())
932 {
933 Aa aa_from(mut_from.toLatin1());
934 Aa aa_to(mut_to.toLatin1());
935 AaModificationP instance_mutation =
936 createInstanceMutation(aa_from, aa_to);
937
938 std::pair<MapAccessionModifications::iterator, bool> insert_res =
940 std::pair<QString, AaModificationP>(accession,
941 instance_mutation));
942 it = insert_res.first;
943 }
944 else
945 {
946 // found
947 }
948 return it->second;
949 }
950 catch(ExceptionNotFound &e)
951 {
952 throw ExceptionNotFound(
953 QObject::tr("ERROR getting instance of : %1 NOT FOUND\n%2")
954 .arg(accession)
955 .arg(e.qwhat()));
956 }
957 catch(PappsoException &e)
958 {
959 throw PappsoException(QObject::tr("ERROR getting instance of %1\n%2")
960 .arg(accession)
961 .arg(e.qwhat()));
962 }
963 catch(std::exception &e)
964 {
965 throw PappsoException(QObject::tr("ERROR getting instance of %1\n%2")
966 .arg(accession)
967 .arg(e.what()));
968 }
969}
970
973{
974 switch(from_aa.toLatin1())
975 {
976 case 'R':
977 return createInstance("MOD:00587");
978 break;
979 case 'K':
980 return createInstance("MOD:00582");
981 break;
982 case 'F':
983 return createInstance("MOD:00589");
984 break;
985 }
986
987 // At this point we have no MOD ontology term for all the other amino-acid
988 // residue, we need to craft the stuff ourselves.
989
990 QString accession(QString("C13N15:%1").arg(from_aa));
991
992 // Define the diff formula for each amino acid code not handled above.
993
994 QString diff_formula;
995
996 switch(from_aa.toLatin1())
997 {
998 case 'G':
999 diff_formula = "(12)C -2 (13)C 2 (14)N -1 (15)N 1";
1000 break;
1001 case 'A':
1002 diff_formula = "(12)C -3 (13)C 3 (14)N -1 (15)N 1";
1003 break;
1004 case 'V':
1005 diff_formula = "(12)C -5 (13)C 5 (14)N -1 (15)N 1";
1006 break;
1007 case 'I':
1008 diff_formula = "(12)C -6 (13)C 6 (14)N -1 (15)N 1";
1009 break;
1010 case 'L':
1011 diff_formula = "(12)C -6 (13)C 6 (14)N -1 (15)N 1";
1012 break;
1013 case 'S':
1014 diff_formula = "(12)C -3 (13)C 3 (14)N -1 (15)N 1";
1015 break;
1016 case 'T':
1017 diff_formula = "(12)C -4 (13)C 4 (14)N -1 (15)N 1";
1018 break;
1019 case 'C':
1020 diff_formula = "(12)C -3 (13)C 3 (14)N -1 (15)N 1";
1021 break;
1022 case 'M':
1023 diff_formula = "(12)C -5 (13)C 5 (14)N -1 (15)N 1";
1024 break;
1025 case 'D':
1026 diff_formula = "(12)C -4 (13)C 4 (14)N -1 (15)N 1";
1027 break;
1028 case 'E':
1029 diff_formula = "(12)C -5 (13)C 5 (14)N -1 (15)N 1";
1030 break;
1031 case 'N':
1032 diff_formula = "(12)C -4 (13)C 4 (14)N -2 (15)N 2";
1033 break;
1034 case 'Q':
1035 diff_formula = "(12)C -5 (13)C 5 (14)N -2 (15)N 2";
1036 break;
1037 case 'W':
1038 diff_formula = "(12)C -11 (13)C 11 (14)N -2 (15)N 2";
1039 break;
1040 case 'Y':
1041 diff_formula = "(12)C -9 (13)C 9 (14)N -1 (15)N 1";
1042 break;
1043 case 'H':
1044 diff_formula = "(12)C -6 (13)C 6 (14)N -3 (15)N 3";
1045 break;
1046 case 'P':
1047 diff_formula = "(12)C -5 (13)C 5 (14)N -1 (15)N 1";
1048 break;
1049 default:
1050 throw PappsoException(
1051 QObject::tr("ERROR creating C13N15-labelled amino acid residue %1\n")
1052 .arg(from_aa));
1053 }
1054
1055 OboPsiModTerm obo_psi_term;
1056 obo_psi_term.m_accession = accession;
1057 obo_psi_term.m_diffFormula = diff_formula;
1058 obo_psi_term.m_name = QString("Fully C13N15-labelled %1").arg(from_aa);
1059 obo_psi_term.m_diffMono = 0;
1060
1061 qDebug() << "obo_psi_term.m_diffFormula: " << obo_psi_term.m_diffFormula;
1062 return AaModification::createInstance(obo_psi_term);
1063}
1064
1065} // namespace pappso
amino acid modification model
virtual const char & getLetter() const
Definition aabase.cpp:436
const QString & getName() const
static AaModificationP getInstanceMutation(const QChar &mut_from, const QChar &mut_to)
get a fake modification coding a mutation from an amino acid to an other
static AaModificationP createInstance(const QString &saccession)
std::map< Isotope, int > m_mapIsotope
const QString & getAccession() const
const QString & getXrefOrigin() const
get list of amino acid on which this modification takes place
static AaModificationP getInstanceXtandemMod(const QString &type, pappso_double mass, const PeptideSp &peptide_sp, unsigned int position)
AaModification(AaModification &&toCopy)
std::map< AtomIsotopeSurvey, int > m_atomCount
int getNumberOfAtom(AtomIsotopeSurvey atom) const override final
get the number of atom C, O, N, H in the molecule
pappso_double getMass() const
void setXrefOrigin(const QString &origin)
set list of amino acid on which this modification takes place
std::map< QString, AaModificationP > MapAccessionModifications
static AaModificationP getInstance(const QString &accession)
static AaModificationP getInstanceRemovalAccessionByAaLetter(const QChar &amino_acid)
get a PSI MOD instance corresponding to the removal of the given amino acid find the modifications th...
static AaModificationP createInstanceC13N15LabelledAminoAcid(const QChar &aa_from)
get heavy amino acid modification C13 N15
static AaModificationP getInstanceCustomizedMod(pappso_double modificationMass)
const QString toProForma() const
get the amino acid in ProForma notation https://github.com/HUPO-PSI/ProForma/blob/master/README....
static AaModificationP getInstanceInsertionAccessionByAaLetter(const QChar &amino_acid)
get a PSI MOD instance corresponding to the insertion of the given amino acid find the modifications.
void setDiffFormula(const QString &diff_formula)
static AaModificationP createInstanceMutation(const Aa &aa_from, const Aa &aa_to)
static MapAccessionModifications m_mapAccessionModifications
int getNumberOfIsotope(Isotope isotope) const override final
get the number of isotopes C13, H2, O17, O18, N15, S33, S34, S36 in the molecule
int getNumberOfAtom(AtomIsotopeSurvey atom) const override final
get the number of atom C, O, N, H in the molecule
Definition aa.cpp:207
pappso_double getMass() const override
Definition aa.cpp:90
const OboPsiModTerm & getOne()
bool isA(const QString &accession) const
tells if this term "is_a" another accession
const char * what() const noexcept override
virtual const QString & qwhat() const
static PrecisionPtr getDaltonInstance(pappso_double value)
get a Dalton precision pointer
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition aa.cpp:39
const pappso_double DIFFS32S33(32.9714589101 - MASSSULFUR)
const pappso_double DIFFS32S34(33.9678670300 - MASSSULFUR)
const pappso_double DIFFO16O17(16.99913150 - MASSOXYGEN)
const pappso_double MASSCARBON(12)
const pappso_double MASSSULFUR(31.9720711741)
std::shared_ptr< const Peptide > PeptideSp
const pappso_double DIFFS32S36(35.9670812000 - MASSSULFUR)
const AaModification * AaModificationP
AtomIsotopeSurvey
Definition types.h:89
double pappso_double
A type definition for doubles.
Definition types.h:50
Isotope
Definition types.h:104
const pappso_double MPROTIUM(1.007825032241)
const pappso_double MASSNITROGEN(14.0030740048)
const pappso_double MASSOXYGEN(15.99491461956)
const pappso_double DIFFO16O18(17.9991610 - MASSOXYGEN)
const pappso_double DIFFN14N15(15.0001088982 - MASSNITROGEN)
const pappso_double DIFFC12C13(1.0033548378)
const pappso_double DIFFH1H2(2.0141017778 - MPROTIUM)
peptide model