libpappsomspp
Library for mass spectrometry
peptide.cpp
Go to the documentation of this file.
1 /**
2  * \file pappsomspp/peptide/peptide.cpp
3  * \date 7/3/2015
4  * \author Olivier Langella
5  * \brief peptide 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 <QDebug>
32 #include <algorithm>
33 #include "peptide.h"
34 #include "../pappsoexception.h"
35 #include "../exception/exceptionoutofrange.h"
36 #include "../exception/exceptionnotpossible.h"
38 
39 namespace pappso
40 {
41 
42 bool
44 {
45  if(peptideIonIsNter(ion_type))
46  std::swap(ion_type_ref, ion_type);
47  if(peptideIonIsNter(ion_type))
48  return false;
49  if((ion_type_ref == PeptideIon::b) && (ion_type == PeptideIon::y))
50  return true;
51  if((ion_type_ref == PeptideIon::ao) && (ion_type == PeptideIon::yo))
52  return true;
53  if((ion_type_ref == PeptideIon::bstar) && (ion_type == PeptideIon::ystar))
54  return true;
55 
56  return false;
57 }
58 
59 bool
61 {
62  if((std::int8_t)ion_type < (std::int8_t)8)
63  {
64  return true;
65  }
66  return false;
67 }
68 
71 {
72  if(peptideIonIsNter(ion_type))
73  {
75  }
77 }
78 
79 Peptide::Peptide(const QString &pepstr)
80 {
81 
82  QString::const_iterator it(pepstr.begin());
83  if(it != pepstr.end())
84  {
85  // first amino acid is the Nter one
86  // by default, it is obtained by hydrolytic cleavage in normal water
87  // and it is loaded with one Hydrogen
88  Aa nter_aa(it->toLatin1());
89  nter_aa.addAaModification(
90  AaModification::getInstance("internal:Nter_hydrolytic_cleavage_H"));
91  m_aaVec.push_back(nter_aa);
92  it++;
93 
94  while(it != pepstr.end())
95  {
96  m_aaVec.push_back(Aa(it->toLatin1()));
97  it++;
98  }
99  // by default, Nter aa is obtained by hydrolytic cleavage in normal water
100  // and it is loaded with Hydrogen + Oxygen
101  m_aaVec.back().addAaModification(
102  AaModification::getInstance("internal:Cter_hydrolytic_cleavage_HO"));
103  getMass();
104  qDebug() << "blabla " << m_aaVec.back().toString();
105  }
106 }
107 
109 {
110 }
111 
112 Peptide::Peptide(const Peptide &peptide)
113  : m_aaVec(peptide.m_aaVec), m_proxyMass(peptide.m_proxyMass)
114 {
115 }
116 
117 
118 Peptide::Peptide(Peptide &&toCopy) // move constructor
119  : m_aaVec(std::move(toCopy.m_aaVec)), m_proxyMass(toCopy.m_proxyMass)
120 {
121 }
122 
123 
124 PeptideSp
126 {
127  return std::make_shared<const Peptide>(*this);
128 }
129 
132 {
133  return std::make_shared<Peptide>(*this);
134 }
135 
136 void
138  unsigned int position)
139 {
140  if(position >= size())
141  {
142  throw ExceptionOutOfRange(
143  QObject::tr("position (%1) > size (%2)").arg(position).arg(size()));
144  }
145  m_proxyMass = -1;
146  qDebug() << "Peptide::addAaModification begin " << position;
147  std::vector<Aa>::iterator it = m_aaVec.begin() + position;
148  it->addAaModification(aaModification);
149  getMass();
150  qDebug() << "Peptide::addAaModification end";
151 }
152 
153 
154 const QString
156 {
157  QString seq = "";
158  std::vector<Aa>::const_iterator it(m_aaVec.begin());
159  while(it != m_aaVec.end())
160  {
161  seq += it->getLetter();
162  it++;
163  }
164  return seq;
165 }
166 const QString
168 {
169  QString seq = "";
170  std::vector<Aa>::const_iterator it(m_aaVec.begin());
171  while(it != m_aaVec.end())
172  {
173  seq += it->toAbsoluteString();
174  it++;
175  }
176  return seq;
177 }
178 
179 const QString
181 {
182  QString seq = "";
183  std::vector<Aa>::const_iterator it(m_aaVec.begin());
184  while(it != m_aaVec.end())
185  {
186  seq += it->toAbsoluteString();
187  it++;
188  }
189  return seq.replace("L", "I");
190 }
191 
192 
193 const QString
195 {
196  QString seq = "";
197  std::vector<Aa>::const_iterator it(m_aaVec.begin());
198  while(it != m_aaVec.end())
199  {
200  seq += it->toString();
201  it++;
202  }
203  return seq;
204 }
205 
208 {
209  qDebug() << "Aa::getMass() begin";
210  if(m_proxyMass < 0)
211  {
212  m_proxyMass = 0;
213  for(auto aa : m_aaVec)
214  {
215  m_proxyMass += aa.getMass();
216  }
217  }
218  qDebug() << "Aa::getMass() end " << m_proxyMass;
219  return m_proxyMass;
220 }
221 
222 int
224 {
225  int number = 0;
226  std::vector<Aa>::const_iterator it(m_aaVec.begin());
227  while(it != m_aaVec.end())
228  {
229  number += it->getNumberOfAtom(atom);
230  it++;
231  }
232  // qDebug() << "Aa::getMass() end " << mass;
233  return number;
234 }
235 
236 int
238 {
239  int number = 0;
240  std::vector<Aa>::const_iterator it(m_aaVec.begin());
241  while(it != m_aaVec.end())
242  {
243  number += it->getNumberOfIsotope(isotope);
244  it++;
245  }
246  // qDebug() << "Aa::getMass() end " << mass;
247  return number;
248 }
249 
250 
251 unsigned int
253 {
254  unsigned int number = 0;
255  std::vector<Aa>::const_iterator it(m_aaVec.begin());
256  while(it != m_aaVec.end())
257  {
258  number += it->getNumberOfModification(mod);
259  it++;
260  }
261  // qDebug() << "Aa::getMass() end " << mass;
262  return number;
263 }
264 
265 unsigned int
267  const std::vector<char> &aa_list) const
268 {
269  unsigned int number = 0;
270  std::vector<Aa>::const_iterator it(m_aaVec.begin());
271  while(it != m_aaVec.end())
272  {
273  if(std::find(aa_list.begin(), aa_list.end(), it->getLetter()) !=
274  aa_list.end())
275  {
276  number += it->getNumberOfModification(mod);
277  }
278  it++;
279  }
280  // qDebug() << "Aa::getMass() end " << mass;
281  return number;
282 }
283 
284 void
286 {
287  if(oldmod == newmod)
288  return;
289  std::vector<Aa>::iterator it(m_aaVec.begin());
290  while(it != m_aaVec.end())
291  {
292  it->replaceAaModification(oldmod, newmod);
293  it++;
294  }
295  m_proxyMass = -1;
296  getMass();
297 }
298 void
300 {
301  std::vector<Aa>::iterator it(m_aaVec.begin());
302  while(it != m_aaVec.end())
303  {
304  it->removeAaModification(mod);
305  qDebug() << it->toString() << " " << toAbsoluteString();
306  it++;
307  }
308  m_proxyMass = -1;
309  getMass();
310  // qDebug() << "Aa::getMass() end " << mass;
311 }
312 std::vector<unsigned int>
314 {
315  std::vector<unsigned int> position_list;
316  unsigned int position = 0;
317  std::vector<Aa>::const_iterator it(m_aaVec.begin());
318  while(it != m_aaVec.end())
319  {
320  unsigned int number = 0;
321  number += it->getNumberOfModification(mod);
322  for(unsigned int j = 0; j < number; j++)
323  {
324  position_list.push_back(position);
325  }
326  it++;
327  position++;
328  }
329  // qDebug() << "Aa::getMass() end " << mass;
330  return position_list;
331 }
332 
333 std::vector<unsigned int>
335  const std::vector<char> &aa_list) const
336 {
337  std::vector<unsigned int> position_list;
338  unsigned int position = 0;
339  std::vector<Aa>::const_iterator it(m_aaVec.begin());
340  while(it != m_aaVec.end())
341  {
342  if(std::find(aa_list.begin(), aa_list.end(), it->getLetter()) !=
343  aa_list.end())
344  {
345  unsigned int number = 0;
346  number += it->getNumberOfModification(mod);
347  for(unsigned int j = 0; j < number; j++)
348  {
349  position_list.push_back(position);
350  }
351  }
352  it++;
353  position++;
354  }
355  // qDebug() << "Aa::getMass() end " << mass;
356  return position_list;
357 }
358 
359 std::vector<unsigned int>
361 {
362  std::vector<unsigned int> position_list;
363  unsigned int number = 0;
364  std::vector<Aa>::const_iterator it(m_aaVec.begin());
365  while(it != m_aaVec.end())
366  {
367  if(it->getLetter() == aa)
368  position_list.push_back(number);
369  number++;
370  it++;
371  }
372  // qDebug() << "Aa::getMass() end " << mass;
373  return position_list;
374 }
375 
376 std::vector<unsigned int>
377 Peptide::getAaPositionList(std::list<char> list_aa) const
378 {
379  std::vector<unsigned int> position_list;
380  unsigned int number = 0;
381  std::vector<Aa>::const_iterator it(m_aaVec.begin());
382  while(it != m_aaVec.end())
383  {
384 
385  bool found =
386  (std::find(list_aa.begin(), list_aa.end(), it->getLetter()) !=
387  list_aa.end());
388  if(found)
389  {
390  position_list.push_back(number);
391  }
392  number++;
393  it++;
394  }
395  // qDebug() << "Aa::getMass() end " << mass;
396  return position_list;
397 }
398 
401 {
402  std::vector<Aa>::const_iterator it(m_aaVec.begin());
403  if(it != m_aaVec.end())
404  {
405  return it->getInternalNterModification();
406  }
407 
408  return nullptr;
409 }
412 {
413  std::vector<Aa>::const_iterator it(m_aaVec.end());
414  it--;
415  if(it != m_aaVec.end())
416  {
417  return it->getInternalCterModification();
418  }
419  return nullptr;
420 }
421 void
423 {
424  std::vector<Aa>::iterator it(m_aaVec.begin());
425  if(it != m_aaVec.end())
426  {
427  m_proxyMass -= it->getMass();
428  it->removeInternalNterModification();
429  m_proxyMass += it->getMass();
430  }
431 }
432 void
434 {
435  std::vector<Aa>::iterator it(m_aaVec.end());
436  it--;
437  if(it != m_aaVec.end())
438  {
439  m_proxyMass -= it->getMass();
440  it->removeInternalCterModification();
441  m_proxyMass += it->getMass();
442  }
443 }
444 
445 
446 void
448 {
449  if(mod->getAccession().startsWith("internal:Nter_"))
450  {
452  std::vector<Aa>::iterator it(m_aaVec.begin());
453  if(it != m_aaVec.end())
454  {
455  it->addAaModification(mod);
456  }
457  else
458  {
459  throw ExceptionOutOfRange(QObject::tr("peptide is empty"));
460  }
461  }
462  else
463  {
464  throw ExceptionNotPossible(
465  QObject::tr("modification is not an internal Nter modification : %1")
466  .arg(mod->getAccession()));
467  }
468 }
469 void
471 {
472  if(mod->getAccession().startsWith("internal:Cter_"))
473  {
475  std::vector<Aa>::iterator it(m_aaVec.end());
476  it--;
477  if(it != m_aaVec.end())
478  {
479  it->addAaModification(mod);
480  }
481  else
482  {
483  throw ExceptionOutOfRange(QObject::tr("peptide is empty"));
484  }
485  }
486  else
487  {
488  throw ExceptionNotPossible(
489  QObject::tr("modification is not an internal Cter modification : %1")
490  .arg(mod->getAccession()));
491  }
492 }
493 
494 void
496 {
499  m_aaVec.begin()->removeInternalNterModification();
501  std::rotate(m_aaVec.begin(), m_aaVec.begin() + 1, m_aaVec.end());
502  m_aaVec.begin()->addAaModification(modNter);
503  (m_aaVec.end() - 1)->addAaModification(modCter);
504 }
505 
506 void
508 {
511  m_aaVec.begin()->removeInternalNterModification();
513  std::reverse(m_aaVec.begin(), m_aaVec.end());
514  m_aaVec.begin()->addAaModification(modNter);
515  (m_aaVec.end() - 1)->addAaModification(modCter);
516 }
517 
518 
519 bool
521 {
522  std::size_t size = m_aaVec.size();
523  std::size_t k = (size - 1);
524  for(std::size_t i = 0; i < (size / 2); i++, k--)
525  {
526  if(m_aaVec[i].getLetter() != m_aaVec[k].getLetter())
527  {
528  return false;
529  }
530  }
531  return true;
532 }
533 
534 Aa &
535 Peptide::getAa(unsigned int position)
536 {
537  if(position >= m_aaVec.size())
538  {
539  throw ExceptionOutOfRange(
540  QObject::tr("no AA at position %1").arg(position));
541  }
542  return m_aaVec.at(position);
543 }
544 const Aa &
545 Peptide::getConstAa(unsigned int position) const
546 {
547  if(position >= m_aaVec.size())
548  {
549  throw ExceptionOutOfRange(
550  QObject::tr("no AA at position %1").arg(position));
551  }
552  return m_aaVec.at(position);
553 }
554 
555 
556 void
558 {
559 
560  std::vector<Aa>::iterator it(m_aaVec.begin());
561  std::vector<Aa>::iterator itend(m_aaVec.end());
562  for(; it != itend; it++)
563  {
564  it->replaceLeucineIsoleucine();
565  }
566 }
567 
568 
569 void
571 {
572  std::vector<Aa>::iterator it(m_aaVec.begin());
573  if(it != m_aaVec.end())
574  {
575  AaModificationP nter_modification = getInternalNterModification();
576  m_aaVec.erase(it);
577  if(nter_modification != nullptr)
578  {
579  m_aaVec.begin()->addAaModification(nter_modification);
580  }
581 
582  m_proxyMass = -1;
583  getMass();
584  }
585  else
586  {
587  throw ExceptionOutOfRange(QObject::tr("peptide is empty"));
588  }
589 }
590 
591 
592 void
594 {
595  std::vector<Aa>::iterator it(m_aaVec.end());
596  it--;
597  if(it != m_aaVec.end())
598  {
599  AaModificationP cter_modification = getInternalCterModification();
600  m_aaVec.erase(it);
601  if(cter_modification != nullptr)
602  {
603  it = m_aaVec.end();
604  it--;
605  it->addAaModification(cter_modification);
606  }
607  m_proxyMass = -1;
608  getMass();
609  }
610  else
611  {
612  throw ExceptionOutOfRange(QObject::tr("peptide is empty"));
613  }
614 }
615 
616 } // namespace pappso
const QString & getAccession() const
static AaModificationP getInstance(const QString &accession)
Definition: aa.h:45
void addAaModification(AaModificationP aaModification)
Definition: aa.cpp:150
void replaceLeucineIsoleucine()
Definition: peptide.cpp:557
PeptideSp makePeptideSp() const
Definition: peptide.cpp:125
Peptide(const QString &pepstr)
Definition: peptide.cpp:79
AaModificationP getInternalNterModification() const
Definition: peptide.cpp:400
virtual int getNumberOfIsotope(Isotope isotope) const override
get the number of isotopes C13, H2, O17, O18, N15, S33, S34, S36 in the molecule
Definition: peptide.cpp:237
void replaceAaModification(AaModificationP oldmod, AaModificationP newmod)
replaces all occurences of a modification by a new one
Definition: peptide.cpp:285
void removeNterAminoAcid()
Definition: peptide.cpp:570
std::vector< unsigned int > getModificationPositionList(AaModificationP mod) const
get modification positions
Definition: peptide.cpp:313
NoConstPeptideSp makeNoConstPeptideSp() const
Definition: peptide.cpp:131
virtual bool isPalindrome() const override
tells if the peptide sequence is a palindrome
Definition: peptide.cpp:520
const QString getLiAbsoluteString() const
get all sequence string with modifications and converting Leucine to Isoleucine
Definition: peptide.cpp:180
void removeCterAminoAcid()
Definition: peptide.cpp:593
void setInternalCterModification(AaModificationP mod)
Definition: peptide.cpp:470
const QString toAbsoluteString() const
print all modifications
Definition: peptide.cpp:167
pappso_double m_proxyMass
Definition: peptide.h:103
void removeInternalNterModification()
Definition: peptide.cpp:422
void setInternalNterModification(AaModificationP mod)
Definition: peptide.cpp:447
virtual ~Peptide()
Definition: peptide.cpp:108
void removeInternalCterModification()
Definition: peptide.cpp:433
unsigned int getNumberOfModification(AaModificationP mod) const
count modification occurence
Definition: peptide.cpp:252
const QString toString() const
print modification except internal modifications
Definition: peptide.cpp:194
AaModificationP getInternalCterModification() const
Definition: peptide.cpp:411
void removeAaModification(AaModificationP mod)
removes all occurences of a modification
Definition: peptide.cpp:299
unsigned int size() const override
Definition: peptide.h:185
Aa & getAa(unsigned int position)
Definition: peptide.cpp:535
virtual int getNumberOfAtom(AtomIsotopeSurvey atom) const override
get the number of atom C, O, N, H in the molecule
Definition: peptide.cpp:223
std::vector< unsigned int > getAaPositionList(char aa) const
get positions of one amino acid in peptide
Definition: peptide.cpp:360
void reverse()
Definition: peptide.cpp:507
pappso_double getMass()
Definition: peptide.cpp:207
const QString getSequence() const override
print amino acid sequence without modifications
Definition: peptide.cpp:155
void addAaModification(AaModificationP aaModification, unsigned int position)
adds a modification to amino acid sequence
Definition: peptide.cpp:137
std::vector< Aa > m_aaVec
Definition: peptide.h:102
unsigned int countModificationOnAa(AaModificationP mod, const std::vector< char > &aa_list) const
count modification occurence
Definition: peptide.cpp:266
const Aa & getConstAa(unsigned int position) const
Definition: peptide.cpp:545
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition: aa.cpp:39
PeptideIon
PeptideIon enum defines all types of ions (Nter or Cter)
Definition: types.h:386
@ y
Cter amino ions.
@ ystar
Cter amino ions + NH3 loss.
@ yo
Cter amino ions + H2O loss.
@ bstar
Nter acylium ions + NH3 loss.
@ b
Nter acylium ions.
@ ao
Nter aldimine ions + H2O loss.
PeptideDirection getPeptideIonDirection(PeptideIon ion_type)
get the direction of a peptide ion
Definition: peptide.cpp:70
std::shared_ptr< const Peptide > PeptideSp
PeptideDirection
Definition: peptide.h:46
AtomIsotopeSurvey
Definition: types.h:77
double pappso_double
A type definition for doubles.
Definition: types.h:49
Isotope
Definition: types.h:92
bool peptideIonTypeIsComplement(PeptideIon ion_type_ref, PeptideIon ion_type)
tells if an ion type is the complement ion of the other
Definition: peptide.cpp:43
bool peptideIonIsNter(PeptideIon ion_type)
tells if an ion is Nter
Definition: peptide.cpp:60
std::shared_ptr< Peptide > NoConstPeptideSp
Definition: peptide.h:97
peptide model
peptide natural isotope model