Gemmi C++ API
Loading...
Searching...
No Matches
monlib.hpp
Go to the documentation of this file.
1// Copyright 2018 Global Phasing Ltd.
2//
3// Monomer library - (Refmac) restraints dictionary,
4// which consists of monomers (chemical components), links, and modifications.
5
6#ifndef GEMMI_MONLIB_HPP_
7#define GEMMI_MONLIB_HPP_
8
9#include <map>
10#include <string>
11#include <vector>
12#include "cifdoc.hpp"
13#include "elem.hpp" // for Element
14#include "fail.hpp" // for fail, unreachable
15#include "model.hpp" // for Residue, Atom
16#include "chemcomp.hpp" // for ChemComp
17#include "logger.hpp" // for Logger
18
19namespace gemmi {
20
21inline bool atom_match_with_alias(const std::string& atom_id, const std::string& atom,
23 if (aliasing)
24 if (const std::string* real_id = aliasing->name_from_alias(atom_id))
25 return *real_id == atom;
26 return atom_id == atom;
27}
28
30 struct Side {
32 std::string comp;
33 std::string mod;
34 Group group = Group::Null;
35 bool matches_group(Group res) const {
36 if (group == Group::Null)
37 return false;
38 return res == group || (group == Group::Peptide && ChemComp::is_peptide_group(res))
39 || (group == Group::DnaRna && ChemComp::is_nucleotide_group(res));
40 }
41 int specificity() const {
42 if (!comp.empty())
43 return 3;
44 return group == Group::PPeptide || group == Group::MPeptide ? 1 : 0;
45 }
46 };
47 std::string id;
48 std::string name;
52 cif::Block block; // temporary, until we have ChemLink->Block function
53
55 int calculate_score(const Residue& res1, const Residue* res2,
56 char alt, char alt2,
57 const ChemComp::Aliasing* aliasing1,
58 const ChemComp::Aliasing* aliasing2) const;
59};
60
62 struct AtomMod {
63 int func;
64 std::string old_id;
65 std::string new_id;
67 float charge;
68 std::string chem_type;
69 };
70
71 std::string id;
72 std::string name;
73 std::string comp_id;
74 std::string group_id;
75 std::vector<AtomMod> atom_mods;
77 cif::Block block; // temporary, until we have ChemMod->Block function
78
80};
81
82struct EnerLib {
83 enum class RadiusType {Vdw, Vdwh, Ion};
84 struct Atom {
86 char hb_type;
87 double vdw_radius;
89 double ion_radius;
91 int sp;
92 };
93 struct Bond {
94 std::string atom_type_2;
96 double length;
97 double value_esd;
98 };
99
101 void read(const cif::Document& doc);
102 std::map<std::string, Atom> atoms; // type->Atom
103 std::multimap<std::string, Bond> bonds; // atom_type_1->Bond
104};
105
107 std::string monomer_dir;
108 std::map<std::string, ChemComp> monomers;
109 std::map<std::string, ChemLink> links;
110 std::map<std::string, ChemMod> modifications;
111 std::map<std::string, ChemComp::Group> cc_groups;
113
114 const ChemLink* get_link(const std::string& link_id) const {
115 auto link = links.find(link_id);
116 return link != links.end() ? &link->second : nullptr;
117 }
118 const ChemMod* get_mod(const std::string& name) const {
119 auto modif = modifications.find(name);
120 return modif != modifications.end() ? &modif->second : nullptr;
121 }
122
123 // Returns the most specific link and a flag that is true
124 // if the order is comp2-comp1 in the link definition.
125 std::tuple<const ChemLink*, bool, const ChemComp::Aliasing*, const ChemComp::Aliasing*>
126 match_link(const Residue& res1, const std::string& atom1, char alt1,
127 const Residue& res2, const std::string& atom2, char alt2,
128 double min_bond_sq=0) const {
129 const ChemLink* best_link = nullptr;
130 bool inverted = false;
131 const ChemComp::Aliasing* aliasing1 = nullptr;
132 const ChemComp::Aliasing* aliasing2 = nullptr;
133 const ChemComp::Aliasing* aliasing1_final = nullptr;
134 const ChemComp::Aliasing* aliasing2_final = nullptr;
135 int best_score = -1000;
136 for (const auto& ml : links) {
137 const ChemLink& link = ml.second;
138 if (link.rt.bonds.empty() || starts_with(link.name, "auto-"))
139 continue;
140 // for now we don't have link definitions with >1 bonds
141 const Restraints::Bond& bond = link.rt.bonds[0];
142 if (sq(bond.value) < min_bond_sq)
143 continue;
144 if (link_side_matches_residue(link.side1, res1.name, &aliasing1) &&
145 link_side_matches_residue(link.side2, res2.name, &aliasing2) &&
146 atom_match_with_alias(bond.id1.atom, atom1, aliasing1) &&
147 atom_match_with_alias(bond.id2.atom, atom2, aliasing2)) {
148 int score = link.calculate_score(res1, &res2, alt1, alt2, aliasing1, aliasing2);
149 if (score > best_score) {
150 best_link = &link;
151 best_score = score;
152 aliasing1_final = aliasing1;
153 aliasing2_final = aliasing2;
154 inverted = false;
155 }
156 }
157 if (link_side_matches_residue(link.side1, res2.name, &aliasing2) &&
158 link_side_matches_residue(link.side2, res1.name, &aliasing1) &&
159 atom_match_with_alias(bond.id1.atom, atom2, aliasing2) &&
160 atom_match_with_alias(bond.id2.atom, atom1, aliasing1)) {
161 // NOLINTNEXTLINE(readability-suspicious-call-argument)
162 int score = link.calculate_score(res2, &res1, alt2, alt1, aliasing2, aliasing1);
163 if (score > best_score) {
164 best_link = &link;
165 best_score = score;
166 aliasing1_final = aliasing1;
167 aliasing2_final = aliasing2;
168 inverted = true;
169 }
170 }
171 }
172 return std::make_tuple(best_link, inverted, aliasing1_final, aliasing2_final);
173 }
174
176 if (block.has_tag("_chem_comp_atom.atom_id")) {
178 if (cc.group == ChemComp::Group::Null) {
179 auto it = cc_groups.find(cc.name);
180 if (it != cc_groups.end())
181 cc.group = it->second;
182 }
183 std::string name = cc.name;
184 monomers.emplace(name, std::move(cc));
185 }
186 }
187
189 const std::string& res_name,
190 ChemComp::Aliasing const** aliasing) const {
192 *aliasing = nullptr;
193 if (!side.comp.empty())
194 return side.comp == res_name;
195 auto it = monomers.find(res_name);
196 if (it != monomers.end()) {
197 if (side.matches_group(it->second.group))
198 return true;
199 for (const ChemComp::Aliasing& a : it->second.aliases)
200 if (side.matches_group(a.group)) {
201 *aliasing = &a;
202 return true;
203 }
204 }
205 return false;
206 }
207
209 std::string path(const std::string& code) const {
210 return monomer_dir + relative_monomer_path(code);
211 }
212
213 static std::string relative_monomer_path(const std::string& code);
214
216
217 void read_monomer_cif(const std::string& path_);
218
219 void set_monomer_dir(const std::string& monomer_dir_) {
220 monomer_dir = monomer_dir_;
221 if (!monomer_dir.empty() && monomer_dir.back() != '/' && monomer_dir.back() != '\\')
222 monomer_dir += '/';
223 }
224
227 bool read_monomer_lib(const std::string& monomer_dir_,
228 const std::vector<std::string>& resnames,
229 const Logger& logger);
230
231 double find_ideal_distance(const const_CRA& cra1, const const_CRA& cra2) const;
232 void update_old_atom_names(Structure& st, const Logger& logger) const;
233};
234
235// to be deprecated
236inline MonLib read_monomer_lib(const std::string& monomer_dir,
237 const std::vector<std::string>& resnames,
238 const std::string& libin="",
239 bool ignore_missing=false) {
241 if (!libin.empty())
242 monlib.read_monomer_cif(libin);
243 std::string error;
244 Logger logger;
245 if (!ignore_missing)
246 logger.callback = [&error](const std::string& s) { cat_to(error, s, '\n'); };
247 bool ok = monlib.read_monomer_lib(monomer_dir, resnames, logger);
248 if (!ignore_missing && !ok) {
249 error += "Please create definitions for missing monomers.";
250 fail(error);
251 }
252 return monlib;
253}
254
255} // namespace gemmi
256#endif
ChemComp - chemical component that represents a monomer from Refmac monomer library,...
struct Document that represents the CIF file (but can also be read from a different representation,...
Elements from the periodic table.
fail(), unreachable() and __declspec/__attribute__ macros
#define GEMMI_DLL
Definition fail.hpp:53
Logger - a tiny utility for passing messages through a callback.
Data structures to store macromolecular structure models.
MonLib read_monomer_lib(const std::string &monomer_dir, const std::vector< std::string > &resnames, const std::string &libin="", bool ignore_missing=false)
Definition monlib.hpp:236
ChemComp make_chemcomp_from_block(const cif::Block &block_)
Definition chemcomp.hpp:583
bool atom_match_with_alias(const std::string &atom_id, const std::string &atom, const ChemComp::Aliasing *aliasing)
Definition monlib.hpp:21
constexpr float sq(float x)
Definition math.hpp:34
void cat_to(std::string &)
Definition util.hpp:26
bool starts_with(const std::string &str, const std::string &prefix)
Definition util.hpp:39
void fail(const std::string &msg)
Definition fail.hpp:59
std::string name
Definition chemcomp.hpp:369
std::string chem_type
Definition monlib.hpp:68
void apply_to(ChemComp &chemcomp, ChemComp::Group alias_group) const
std::string id
Definition monlib.hpp:71
std::vector< AtomMod > atom_mods
Definition monlib.hpp:75
std::string name
Definition monlib.hpp:72
std::string comp_id
Definition monlib.hpp:73
std::string group_id
Definition monlib.hpp:74
Restraints rt
Definition monlib.hpp:76
cif::Block block
Definition monlib.hpp:77
std::string atom_type_2
Definition monlib.hpp:94
std::multimap< std::string, Bond > bonds
Definition monlib.hpp:103
std::map< std::string, Atom > atoms
Definition monlib.hpp:102
void read(const cif::Document &doc)
Passes messages (including warnings/errors) to a callback function.
Definition logger.hpp:23
std::function< void(const std::string &)> callback
A function that handles messages.
Definition logger.hpp:25
EnerLib ener_lib
Definition monlib.hpp:112
bool read_monomer_lib(const std::string &monomer_dir_, const std::vector< std::string > &resnames, const Logger &logger)
Read mon_lib_list.cif, ener_lib.cif and required monomers.
void read_monomer_doc(const cif::Document &doc)
double find_ideal_distance(const const_CRA &cra1, const const_CRA &cra2) const
const ChemLink * get_link(const std::string &link_id) const
Definition monlib.hpp:114
std::map< std::string, ChemMod > modifications
Definition monlib.hpp:110
static std::string relative_monomer_path(const std::string &code)
std::map< std::string, ChemLink > links
Definition monlib.hpp:109
std::map< std::string, ChemComp::Group > cc_groups
Definition monlib.hpp:111
void set_monomer_dir(const std::string &monomer_dir_)
Definition monlib.hpp:219
void add_monomer_if_present(const cif::Block &block)
Definition monlib.hpp:175
std::tuple< const ChemLink *, bool, const ChemComp::Aliasing *, const ChemComp::Aliasing * > match_link(const Residue &res1, const std::string &atom1, char alt1, const Residue &res2, const std::string &atom2, char alt2, double min_bond_sq=0) const
Definition monlib.hpp:126
bool link_side_matches_residue(const ChemLink::Side &side, const std::string &res_name, ChemComp::Aliasing const **aliasing) const
Definition monlib.hpp:188
std::string monomer_dir
Definition monlib.hpp:107
void update_old_atom_names(Structure &st, const Logger &logger) const
std::map< std::string, ChemComp > monomers
Definition monlib.hpp:108
const ChemMod * get_mod(const std::string &name) const
Definition monlib.hpp:118
void read_monomer_cif(const std::string &path_)
std::string path(const std::string &code) const
Returns path to the monomer cif file (the file may not exist).
Definition monlib.hpp:209
std::string name
Definition seqid.hpp:93
bool has_tag(const std::string &tag) const
Definition cifdoc.hpp:464