OpenMS
Loading...
Searching...
No Matches
Residue.h
Go to the documentation of this file.
1// Copyright (c) 2002-present, OpenMS Inc. -- EKU Tuebingen, ETH Zurich, and FU Berlin
2// SPDX-License-Identifier: BSD-3-Clause
3//
4// --------------------------------------------------------------------------
5// $Maintainer: Timo Sachsenberg $
6// $Authors: Andreas Bertsch, Jang Jang Jin$
7// --------------------------------------------------------------------------
8//
9
10#pragma once
11
17
18#include <array>
19#include <functional>
20#include <iosfwd>
21#include <set>
22#include <vector>
23
24namespace OpenMS
25{
26 class ResidueModification;
27
40 class OPENMS_DLLAPI Residue
41 {
42 friend class ResidueDB;
43
44public:
45
62
63 inline static const EmpiricalFormula& getInternalToFull()
64 {
65 static const EmpiricalFormula to_full = EmpiricalFormula("H2O");
66 return to_full;
67 }
68
69 inline static const EmpiricalFormula& getInternalToNTerm()
70 {
71 static const EmpiricalFormula to_full = EmpiricalFormula("H");
72 return to_full;
73 }
74
75 inline static const EmpiricalFormula& getInternalToCTerm()
76 {
77 static const EmpiricalFormula to_full = EmpiricalFormula("OH");
78 return to_full;
79 }
80
81 inline static const EmpiricalFormula& getInternalToAIon()
82 {
83 // Mind the "-"
84 static const EmpiricalFormula to_full =
85 getInternalToNTerm() - EmpiricalFormula("CHO");
86 return to_full;
87 }
88
89 inline static const EmpiricalFormula& getInternalToBIon()
90 {
91 // Mind the "-"
92 static const EmpiricalFormula to_full =
93 getInternalToNTerm() - EmpiricalFormula("H");
94 return to_full;
95 }
96
97 inline static const EmpiricalFormula& getInternalToCIon()
98 {
99 static const EmpiricalFormula to_full =
100 getInternalToNTerm() + EmpiricalFormula("NH2");
101 return to_full;
102 }
103
104 inline static const EmpiricalFormula& getInternalToXIon()
105 {
106 // Mind the "-"
107 static const EmpiricalFormula to_full =
108 getInternalToCTerm() + EmpiricalFormula("CO") - EmpiricalFormula("H");
109 return to_full;
110 }
111
112 inline static const EmpiricalFormula& getInternalToYIon()
113 {
114 static const EmpiricalFormula to_full =
115 getInternalToCTerm() + EmpiricalFormula("H");
116 return to_full;
117 }
118
119 inline static const EmpiricalFormula& getInternalToZIon()
120 {
121 // Mind the "-"
122 static const EmpiricalFormula to_full =
123 getInternalToCTerm() - EmpiricalFormula("NH2");
124 return to_full;
125 }
126
128 {
129 // Mind the "-"
130 static const EmpiricalFormula to_full =
131 getInternalToCTerm() - EmpiricalFormula("NH");
132 return to_full;
133 }
134
136 {
137 // Mind the "-"
138 static const EmpiricalFormula to_full =
139 getInternalToCTerm() - EmpiricalFormula("N");
140 return to_full;
141 }
142
144
148
179
181 static inline std::array<std::string_view, Residue::ResidueType::SizeOfResidueType> names_of_residuetype {
182 "full",
183 "internal",
184 "N-terminal",
185 "C-terminal",
186 "a-ion",
187 "b-ion",
188 "c-ion",
189 "x-ion",
190 "y-ion",
191 "z-ion",
192 "z+1-ion",
193 "z+2-ion",
194 "precursor-ion",
195 "b-H2O-ion",
196 "y-H2O-ion",
197 "b-NH3-ion",
198 "y-NH3-ion",
199 "Non-identified ion",
200 "unannotated",
201 "d-ion",
202 "v-ion",
203 "w-ion"
204 };
205
207 static std::string getResidueTypeName(const ResidueType res_type);
208
212
215
217 Residue(const Residue&) = default;
218
220 Residue(Residue&&) = default;
221
222 // Detailed constructor
223 Residue(const std::string& name,
224 const std::string& three_letter_code,
225 const std::string& one_letter_code,
226 const EmpiricalFormula& formula,
227 double pka = 0,
228 double pkb = 0,
229 double pkc = -1,
230 double gb_sc = 0,
231 double gb_bb_l = 0,
232 double gb_bb_r = 0,
233 const std::set<std::string>& synonyms = std::set<std::string>());
234
236 virtual ~Residue();
238
242
244 Residue& operator=(const Residue&) = default;
245
247 Residue& operator=(Residue&&) & = default;
249
254 void setName(const std::string& name);
255
257 const std::string& getName() const;
258
260 void setSynonyms(const std::set<std::string>& synonyms);
261
263 void addSynonym(const std::string& synonym);
264
266 const std::set<std::string>& getSynonyms() const;
267
269 void setThreeLetterCode(const std::string& three_letter_code);
270
272 const std::string& getThreeLetterCode() const;
273
275 void setOneLetterCode(const std::string& one_letter_code);
276
278 const std::string& getOneLetterCode() const;
279
282
284 void setLossFormulas(const std::vector<EmpiricalFormula>&);
285
288
290 void setNTermLossFormulas(const std::vector<EmpiricalFormula>&);
291
293 const std::vector<EmpiricalFormula>& getLossFormulas() const;
294
296 const std::vector<EmpiricalFormula>& getNTermLossFormulas() const;
297
299 void setLossNames(const std::vector<std::string>& name);
300
302 void setNTermLossNames(const std::vector<std::string>& name);
303
305 void addLossName(const std::string& name);
306
308 void addNTermLossName(const std::string& name);
309
311 const std::vector<std::string>& getLossNames() const;
312
314 const std::vector<std::string>& getNTermLossNames() const;
315
317 void setFormula(const EmpiricalFormula& formula);
318
322
324 void setAverageWeight(double weight);
325
328 double getAverageWeight(ResidueType res_type = Full) const;
329
331 void setMonoWeight(double weight);
332
335 double getMonoWeight(ResidueType res_type = Full) const;
336
339
341 void setModification(const std::string& name);
342
356
360
363 void setModificationByDiffMonoMass(double diffMonoMass);
364
366 const std::string& getModificationName() const;
367
369 void setLowMassIons(const std::vector<EmpiricalFormula>& low_mass_ions);
370
372 const std::vector<EmpiricalFormula>& getLowMassIons() const;
373
375 void setResidueSets(const std::set<std::string>& residues_sets);
376
378 void addResidueSet(const std::string& residue_sets);
379
381 const std::set<std::string>& getResidueSets() const;
382
384 double getPka() const;
385
387 double getPkb() const;
388
390 double getPkc() const;
391
393 double getPiValue() const;
394
396 void setPka(double value);
397
399 void setPkb(double value);
400
402 void setPkc(double value);
403
405 double getSideChainBasicity() const;
406
408 void setSideChainBasicity(double gb_sc);
409
412
414 void setBackboneBasicityLeft(double gb_bb_l);
415
418
420 void setBackboneBasicityRight(double gb_bb_r);
422
427 bool hasNeutralLoss() const;
428
431
433 bool operator==(const Residue& residue) const;
434
436 bool operator!=(const Residue& residue) const;
437
439 bool operator==(char one_letter_code) const;
440
442 bool operator!=(char one_letter_code) const;
443
445 bool isModified() const;
446
448 bool isInResidueSet(const std::string& residue_set);
449
451 bool hasVLoss() const;
452
457
460 bool hasSatelliteLoss(char subtype = '\0') const;
461
464 EmpiricalFormula getSatelliteLossFormula(char subtype = '\0') const;
466
468 static std::string residueTypeToIonLetter(const ResidueType& res_type);
469
472 std::string toString() const;
473
475 friend OPENMS_DLLAPI std::ostream& operator<<(std::ostream& os, const Residue& residue);
476
487
488protected:
491
492
494 std::string name_ = "unknown";
495
496 std::set<std::string> synonyms_;
497
499
500 std::string one_letter_code_;
501
503
505
506 double average_weight_ = 0;
507
508 double mono_weight_ = 0;
509
511 const ResidueModification* modification_ = nullptr;
512
513 // loss
514 std::vector<std::string> loss_names_;
515
516 std::vector<EmpiricalFormula> loss_formulas_;
517
518 std::vector<std::string> NTerm_loss_names_;
519
520 std::vector<EmpiricalFormula> NTerm_loss_formulas_;
521
523 std::vector<EmpiricalFormula> low_mass_ions_;
524
525 // pka values
526 double pka_ = 0;
527
528 // pkb values
529 double pkb_ = 0;
530
531 // pkc values
532 double pkc_ = -1.0;
533
535 double gb_sc_ = 0;
536
538 double gb_bb_l_ = 0;
539
541 double gb_bb_r_ = 0;
542
544 std::set<std::string> residue_sets_;
545
546 // pre-calculated residue type delta weights for more efficient weight calculation
547 static const double internal_to_full_monoweight_;
548 static const double internal_to_nterm_monoweight_;
549 static const double internal_to_cterm_monoweight_;
550 static const double internal_to_a_monoweight_;
551 static const double internal_to_b_monoweight_;
552 static const double internal_to_c_monoweight_;
553 static const double internal_to_x_monoweight_;
554 static const double internal_to_y_monoweight_;
555 static const double internal_to_z_monoweight_;
556 static const double internal_to_zp1_monoweight_;
557 static const double internal_to_zp2_monoweight_;
558 };
559
560 // write 'name threelettercode onelettercode formula'
561 OPENMS_DLLAPI std::ostream& operator<<(std::ostream& os, const Residue& residue);
562
563} // namespace OpenMS
564
565namespace std
566{
569 template<>
570 struct hash<OpenMS::Residue>
571 {
572 std::size_t operator()(const OpenMS::Residue& r) const noexcept
573 {
574 std::size_t seed = 0;
575
576 // Hash name_
578
579 // Hash synonyms_ (std::set<std::string>)
580 for (const auto& syn : r.getSynonyms())
581 {
583 }
584
585 // Hash three_letter_code_
586 OpenMS::hash_combine(seed, OpenMS::fnv1a_hash_string(r.getThreeLetterCode()));
587
588 // Hash one_letter_code_
589 OpenMS::hash_combine(seed, OpenMS::fnv1a_hash_string(r.getOneLetterCode()));
590
591 // Hash formula_
592 OpenMS::hash_combine(seed, std::hash<OpenMS::EmpiricalFormula>{}(r.getFormula()));
593
594 // Hash average_weight_
595 OpenMS::hash_combine(seed, OpenMS::hash_float(r.getAverageWeight()));
596
597 // Hash mono_weight_
598 OpenMS::hash_combine(seed, OpenMS::hash_float(r.getMonoWeight()));
599
600 // Hash modification_ (pointer comparison in operator==)
601 OpenMS::hash_combine(seed, OpenMS::hash_int(reinterpret_cast<std::uintptr_t>(r.getModification())));
602
603 // Hash loss_names_ (std::vector<std::string>)
604 for (const auto& name : r.getLossNames())
605 {
607 }
608
609 // Hash loss_formulas_ (std::vector<EmpiricalFormula>)
610 for (const auto& formula : r.getLossFormulas())
611 {
612 OpenMS::hash_combine(seed, std::hash<OpenMS::EmpiricalFormula>{}(formula));
613 }
614
615 // Hash NTerm_loss_names_ (std::vector<std::string>)
616 for (const auto& name : r.getNTermLossNames())
617 {
619 }
620
621 // Hash NTerm_loss_formulas_ (std::vector<EmpiricalFormula>)
622 for (const auto& formula : r.getNTermLossFormulas())
623 {
624 OpenMS::hash_combine(seed, std::hash<OpenMS::EmpiricalFormula>{}(formula));
625 }
626
627 // Hash low_mass_ions_ (std::vector<EmpiricalFormula>)
628 for (const auto& formula : r.getLowMassIons())
629 {
630 OpenMS::hash_combine(seed, std::hash<OpenMS::EmpiricalFormula>{}(formula));
631 }
632
633 // Hash pka_
634 OpenMS::hash_combine(seed, OpenMS::hash_float(r.getPka()));
635
636 // Hash pkb_
637 OpenMS::hash_combine(seed, OpenMS::hash_float(r.getPkb()));
638
639 // Hash pkc_
640 OpenMS::hash_combine(seed, OpenMS::hash_float(r.getPkc()));
641
642 // Hash gb_sc_
643 OpenMS::hash_combine(seed, OpenMS::hash_float(r.getSideChainBasicity()));
644
645 // Hash gb_bb_l_
646 OpenMS::hash_combine(seed, OpenMS::hash_float(r.getBackboneBasicityLeft()));
647
648 // Hash gb_bb_r_
649 OpenMS::hash_combine(seed, OpenMS::hash_float(r.getBackboneBasicityRight()));
650
651 // Hash residue_sets_ (std::set<std::string>)
652 for (const auto& rs : r.getResidueSets())
653 {
655 }
656
657 return seed;
658 }
659 };
660} // namespace std
Representation of an empirical formula.
Definition EmpiricalFormula.h:62
OpenMS stores a central database of all residues in the ResidueDB. All (unmodified) residues are adde...
Definition ResidueDB.h:40
Representation of a modification on an amino acid residue.
Definition ResidueModification.h:55
Representation of an amino acid residue.
Definition Residue.h:41
static const double internal_to_b_monoweight_
Definition Residue.h:551
static const double internal_to_x_monoweight_
Definition Residue.h:553
void setPkb(double value)
sets the pkb of the residue
static const EmpiricalFormula & getInternalToZp2Ion()
Definition Residue.h:135
void setResidueSets(const std::set< std::string > &residues_sets)
sets the residue sets the amino acid is contained in (e.g. Natural20)
bool hasNTermNeutralLosses() const
true if N-terminal neutral losses are set
void validateSatelliteIon_(ResidueType type) const
Reject satellite ions whose cleavage residue has no supported loss.
static const double internal_to_z_monoweight_
Definition Residue.h:555
std::string toString() const
double getBackboneBasicityRight() const
returns the C-terminal direction backbone basicity
static const double internal_to_a_monoweight_
Definition Residue.h:550
static const double internal_to_zp1_monoweight_
Definition Residue.h:556
const std::vector< EmpiricalFormula > & getLowMassIons() const
returns a vector of formulas with the low mass markers of the residue
Residue()
Default constructor (needed by pyOpenMS)
bool hasVLoss() const
true if the residue can produce a v-ion via complete side-chain loss
std::vector< EmpiricalFormula > NTerm_loss_formulas_
Definition Residue.h:520
std::set< std::string > synonyms_
Definition Residue.h:496
bool operator==(char one_letter_code) const
equality operator for one letter code
static const double internal_to_nterm_monoweight_
Definition Residue.h:548
static const double internal_to_zp2_monoweight_
Definition Residue.h:557
void setSynonyms(const std::set< std::string > &synonyms)
sets the synonyms
bool hasNeutralLoss() const
true if the residue has neutral loss
const std::string & getName() const
returns the name of the residue
std::vector< std::string > loss_names_
Definition Residue.h:514
EmpiricalFormula getFormula(ResidueType res_type=Full) const
const std::string & getThreeLetterCode() const
returns the name of the residue as three letter code (std::string of size 3)
double getPiValue() const
calculates the isoelectric point using the pk* values
const ResidueModification * getModification() const
returns a pointer to the modification, or a null pointer if none is set
void setPkc(double value)
sets the pkc of the residue
void addSynonym(const std::string &synonym)
adds a synonym
static const double internal_to_full_monoweight_
Definition Residue.h:547
static const double internal_to_y_monoweight_
Definition Residue.h:554
Residue & operator=(const Residue &)=default
Assignment operator.
static const double internal_to_cterm_monoweight_
Definition Residue.h:549
const std::vector< EmpiricalFormula > & getLossFormulas() const
returns the neutral loss formulas
bool operator==(const Residue &residue) const
equality operator
bool isModified() const
true if the residue is a modified one
const std::vector< std::string > & getLossNames() const
gets neutral loss name (if there is one, else returns an empty string)
bool isInResidueSet(const std::string &residue_set)
true if the residue is contained in the set
void setPka(double value)
sets the pka of the residue
std::vector< EmpiricalFormula > loss_formulas_
Definition Residue.h:516
double getPkb() const
returns the pkb of the residue
ResidueType
Definition Residue.h:153
@ CTerminal
only C-terminus
Definition Residue.h:157
@ YIon
MS:1001220 peptide bond up to the C-terminus.
Definition Residue.h:162
@ XIon
MS:1001228 amide/C-alpha bond up to the C-terminus.
Definition Residue.h:161
@ Zp2Ion
MS:1001230 C-alpha/carbonyl carbon bond (free radical, z+2 "ion" with additional abstracted hydrogen)...
Definition Residue.h:165
@ ZIon
MS:1001230 C-alpha/carbonyl carbon bond [CID fragment].
Definition Residue.h:163
@ WIon
MS:1001238 z ion with partial side-chain loss.
Definition Residue.h:175
@ BIonMinusH20
MS:1001222 b ion without water.
Definition Residue.h:167
@ NTerminal
only N-terminus
Definition Residue.h:156
@ BIonMinusNH3
MS:1001232 b ion without ammonia.
Definition Residue.h:169
@ AIon
MS:1001229 N-terminus up to the C-alpha/carbonyl carbon bond.
Definition Residue.h:158
@ Precursor
MS:1001523 Precursor ion.
Definition Residue.h:166
@ YIonMinusH20
MS:1001223 y ion without water.
Definition Residue.h:168
@ NonIdentified
MS:1001240 Non-identified ion.
Definition Residue.h:171
@ VIon
MS:1001237 y ion with complete side-chain loss.
Definition Residue.h:174
@ BIon
MS:1001224 N-terminus up to the peptide bond.
Definition Residue.h:159
@ Zp1Ion
MS:1001230 C-alpha/carbonyl carbon bond (free radical, z+1 "ion") [main EAD fragment].
Definition Residue.h:164
@ CIon
MS:1001231 N-terminus up to the amide/C-alpha bond.
Definition Residue.h:160
@ YIonMinusNH3
MS:1001233 y ion without ammonia.
Definition Residue.h:170
@ Internal
internal residue, without any termini
Definition Residue.h:155
@ Unannotated
no stored annotation
Definition Residue.h:172
@ DIon
MS:1001236 a ion with partial side-chain loss.
Definition Residue.h:173
void setBackboneBasicityRight(double gb_bb_r)
sets the C-terminal direction backbone basicity
friend std::ostream & operator<<(std::ostream &os, const Residue &residue)
ostream iterator to write the residue to a stream
void setSideChainBasicity(double gb_sc)
sets the side chain basicity
Residue & operator=(Residue &&) &=default
Move assignment operator.
std::vector< EmpiricalFormula > low_mass_ions_
low mass markers like immonium ions
Definition Residue.h:523
void setOneLetterCode(const std::string &one_letter_code)
sets the name as one letter code (std::string of size 1)
void setModification(const ResidueModification &mod)
void setLowMassIons(const std::vector< EmpiricalFormula > &low_mass_ions)
sets the low mass marker ions as a vector of formulas
void setLossNames(const std::vector< std::string > &name)
set the neutral loss molecule name
static const EmpiricalFormula & getInternalToZp1Ion()
Definition Residue.h:127
double getSideChainBasicity() const
returns the side chain basicity
static std::string residueTypeToIonLetter(const ResidueType &res_type)
helper for mapping residue types to letters for Text annotations and labels
EmpiricalFormula getVLossFormula() const
Residue(Residue &&)=default
Move constructor.
static const double internal_to_c_monoweight_
Definition Residue.h:552
virtual ~Residue()
Destructor.
const std::vector< EmpiricalFormula > & getNTermLossFormulas() const
returns N-terminal loss formulas
std::vector< std::string > NTerm_loss_names_
Definition Residue.h:518
double getHydrophobicity(const HydrophobicityScaleMethod scale) const
returns the hydrophobicity value of the residue
std::string one_letter_code_
Definition Residue.h:500
static const EmpiricalFormula & getInternalToYIon()
Definition Residue.h:112
void setName(const std::string &name)
sets the name of the residue
void addResidueSet(const std::string &residue_sets)
adds a residue set to the residue sets (e.g. Natural20)
void setModification(const std::string &name)
sets the modification by name; the mod should be present in ModificationsDB
const std::set< std::string > & getResidueSets() const
returns the residue sets this residue is contained in (e.g. Natural20)
bool hasSatelliteLoss(char subtype='\0') const
static const EmpiricalFormula & getInternalToAIon()
Definition Residue.h:81
void setThreeLetterCode(const std::string &three_letter_code)
sets the name of the residue as three letter code (std::string of size 3)
Residue(const std::string &name, const std::string &three_letter_code, const std::string &one_letter_code, const EmpiricalFormula &formula, double pka=0, double pkb=0, double pkc=-1, double gb_sc=0, double gb_bb_l=0, double gb_bb_r=0, const std::set< std::string > &synonyms=std::set< std::string >())
double getBackboneBasicityLeft() const
returns the backbone basicity if located in N-terminal direction
void addLossName(const std::string &name)
add neutral loss molecule name
void setModification(const ResidueModification *mod)
sets the modification by existing ResMod (make sure it exists in ModificationsDB)
static const EmpiricalFormula & getInternalToZIon()
Definition Residue.h:119
void setModificationByDiffMonoMass(double diffMonoMass)
void setAverageWeight(double weight)
sets average weight of the residue (must be full, with N and C-terminus)
static const EmpiricalFormula & getInternalToNTerm()
Definition Residue.h:69
void addNTermLossName(const std::string &name)
adds a N-terminal loss name
double getPka() const
returns the pka of the residue
const std::vector< std::string > & getNTermLossNames() const
returns the N-terminal loss names
static const EmpiricalFormula & getInternalToFull()
Definition Residue.h:63
EmpiricalFormula getSatelliteLossFormula(char subtype='\0') const
static const EmpiricalFormula & getInternalToCIon()
Definition Residue.h:97
bool operator!=(char one_letter_code) const
equality operator for one letter code
void addNTermLossFormula(const EmpiricalFormula &)
adds N-terminal losses
void addLossFormula(const EmpiricalFormula &)
adds a neutral loss formula
double getAverageWeight(ResidueType res_type=Full) const
Residue(const Residue &)=default
Copy constructor.
EmpiricalFormula internal_formula_
Definition Residue.h:504
void setNTermLossFormulas(const std::vector< EmpiricalFormula > &)
sets the N-terminal losses
EmpiricalFormula formula_
Definition Residue.h:502
const std::set< std::string > & getSynonyms() const
returns the synonyms
std::set< std::string > residue_sets_
residue sets this amino acid is contained in
Definition Residue.h:544
void setBackboneBasicityLeft(double gb_bb_l)
sets the N-terminal direction backbone basicity
static const EmpiricalFormula & getInternalToCTerm()
Definition Residue.h:75
void setNTermLossNames(const std::vector< std::string > &name)
sets the N-terminal loss names
static const EmpiricalFormula & getInternalToBIon()
Definition Residue.h:89
const std::string & getModificationName() const
returns the name (ID) of the modification, or an empty string if none is set
double getPkc() const
returns the pkc of the residue if it exists otherwise -1
void setFormula(const EmpiricalFormula &formula)
set empirical formula of the residue (must be full, with N and C-terminus)
double getMonoWeight(ResidueType res_type=Full) const
static std::string getResidueTypeName(const ResidueType res_type)
returns the ion name given as a residue type
void setLossFormulas(const std::vector< EmpiricalFormula > &)
sets the neutral loss formulas
void setMonoWeight(double weight)
sets monoisotopic weight of the residue (must be full, with N and C-terminus)
bool operator!=(const Residue &residue) const
inequality operator
const std::string & getOneLetterCode() const
returns the name as one letter code (std::string of size 1)
static const EmpiricalFormula & getInternalToXIon()
Definition Residue.h:104
std::string three_letter_code_
Definition Residue.h:498
Main OpenMS namespace.
Definition openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19
std::ostream & operator<<(std::ostream &os, const AccurateMassSearchResult &amsr)
std::size_t hash_int(T value) noexcept
Hash for an integer type.
Definition HashUtils.h:107
void hash_combine(std::size_t &seed, std::size_t value) noexcept
Combine a hash value with additional data using golden ratio mixing.
Definition HashUtils.h:87
std::size_t hash_float(T value) noexcept
Hash for a floating point type (float or double).
Definition HashUtils.h:142
std::size_t fnv1a_hash_string(const std::string &s) noexcept
FNV-1a hash for a string.
Definition HashUtils.h:70
HydrophobicityScaleMethod
Enum for different hydrophobicity scales.
Definition CommonEnums.h:50
STL namespace.
std::size_t operator()(const OpenMS::Residue &r) const noexcept
Definition Residue.h:572