6#ifndef GEMMI_MONLIB_HPP_
7#define GEMMI_MONLIB_HPP_
25 if (atom.altloc && altlocs.find(atom.altloc) == std::string::npos)
26 altlocs += atom.altloc;
44 if (
group == Group::Null)
52 return group == Group::PPeptide ||
group == Group::MPeptide ? 1 : 0;
111 for (
const auto&
row : block.
find(
"_lib_atom.",
112 {
"type",
"hb_type",
"vdw_radius",
"vdwh_radius",
113 "ion_radius",
"element",
"valency",
"sp"}))
117 for (
const auto&
row : block.
find(
"_lib_bond.",
118 {
"atom_type_1",
"atom_type_2",
"type",
"length",
"value_esd"}))
123 std::multimap<std::string, Bond>
bonds;
131 std::map<std::string, ChemLink>
links;
136 auto link = links.find(link_id);
137 return link != links.end() ? &
link->second :
nullptr;
140 auto modif = modifications.find(name);
141 return modif != modifications.end() ? &
modif->second :
nullptr;
146 std::tuple<const ChemLink*, bool, const ChemComp::Aliasing*, const ChemComp::Aliasing*>
148 const Residue& res2,
const std::string&
atom2,
char alt2,
151 bool inverted =
false;
157 for (
auto&
ml : links) {
165 if (link_side_matches_residue(
link.side1, res1.
name, &aliasing1) &&
166 link_side_matches_residue(
link.side2, res2.
name, &aliasing2) &&
169 int score =
link.calculate_score(res1, &res2, alt1, alt2, aliasing1, aliasing2);
178 if (link_side_matches_residue(
link.side1, res2.
name, &aliasing2) &&
179 link_side_matches_residue(
link.side2, res1.
name, &aliasing1) &&
182 int score =
link.calculate_score(res2, &res1, alt2, alt1, aliasing2, aliasing1);
196 if (block.
has_tag(
"_chem_comp_atom.atom_id")) {
198 if (cc.
group == ChemComp::Group::Null) {
199 auto it = cc_groups.find(cc.
name);
200 if (
it != cc_groups.end())
203 std::string name = cc.
name;
204 monomers.emplace(name, std::move(cc));
213 if (!
side.comp.empty())
216 if (
it != monomers.end()) {
217 if (
side.matches_group(
it->second.group))
220 if (
side.matches_group(a.group)) {
230 return monomer_dir + relative_monomer_path(
code);
242 if (
code.size() == 3)
261 if (!
doc.blocks.empty() &&
doc.blocks[0].name ==
"lib")
262 if (
const std::string*
ver =
doc.blocks[0].find_value(
"_lib.version"))
264 read_monomer_doc(
doc);
269 if (monomer_dir.back() !=
'/' && monomer_dir.back() !=
'\\')
276 const std::vector<std::string>&
resnames,
278 std::string*
error=
nullptr) {
280 fail(
"read_monomer_lib: monomer_dir not specified.");
283 read_monomer_cif(monomer_dir +
"list/mon_lib_list.cif",
read_cif);
284 ener_lib.
read((*
read_cif)(monomer_dir +
"ener_lib.cif"));
287 for (
const std::string& name :
resnames) {
288 if (monomers.find(name) != monomers.end())
292 read_monomer_doc(
doc);
293 }
catch (std::system_error& err) {
295 if (err.code().value() ==
ENOENT)
296 cat_to(*
error,
"Monomer not in the library: ", name,
".\n");
298 cat_to(*
error,
"Failed to read ", name,
": ", err.what(),
".\n");
301 }
catch (std::runtime_error& err) {
303 cat_to(*
error,
"Failed to read ", name,
": ", err.what(),
".\n");
316 const std::vector<std::string>&
resnames,
318 const std::string&
libin=
"",
326 fail(
error +
"Please create definitions for missing monomers.");
double as_number(const std::string &s, double nan=NAN)
int as_int(const std::string &str)
ChemComp make_chemcomp_from_block(const cif::Block &block_)
constexpr int ialpha3_id(const char *s)
void add_distinct_altlocs(const Residue &res, std::string &altlocs)
bool atom_match_with_alias(const std::string &atom_id, const std::string &atom, const ChemComp::Aliasing *aliasing)
constexpr float sq(float x)
void cat_to(std::string &)
bool starts_with(const std::string &str, const std::string &prefix)
void fail(const std::string &msg)
cif::Document(* read_cif_func)(const std::string &)
MonLib read_monomer_lib(const std::string &monomer_dir, const std::vector< std::string > &resnames, read_cif_func read_cif, const std::string &libin="", bool ignore_missing=false)
BondType bond_type_from_string(const std::string &s)
Represents atom site in macromolecular structure (~100 bytes).
static bool is_nucleotide_group(Group g)
Check if the group is DNA/RNA.
static bool is_peptide_group(Group g)
Check if the group (M-|P-)peptide.
bool matches_group(Group res) const
int calculate_score(const Residue &res1, const Residue *res2, char alt, char alt2, const ChemComp::Aliasing *aliasing1, const ChemComp::Aliasing *aliasing2) const
If multiple ChemLinks match a bond, the one with highest scores should be used.
void apply_to(ChemComp &chemcomp, ChemComp::Group alias_group) const
std::vector< AtomMod > atom_mods
std::multimap< std::string, Bond > bonds
std::map< std::string, Atom > atoms
void read(const cif::Document &doc)
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
std::map< std::string, ChemMod > modifications
bool read_monomer_lib(const std::string &monomer_dir_, const std::vector< std::string > &resnames, read_cif_func read_cif, std::string *error=nullptr)
Read mon_lib_list.cif, ener_lib.cif and required monomers.
static std::string relative_monomer_path(const std::string &code)
void read_monomer_cif(const std::string &path_, read_cif_func read_cif)
std::map< std::string, ChemLink > links
std::map< std::string, ChemComp::Group > cc_groups
void set_monomer_dir(const std::string &monomer_dir_)
void add_monomer_if_present(const cif::Block &block)
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
bool link_side_matches_residue(const ChemLink::Side &side, const std::string &res_name, ChemComp::Aliasing const **aliasing) const
std::string path(const std::string &code)
Returns path to the monomer cif file (the file may not exist).
std::map< std::string, ChemComp > monomers
const ChemMod * get_mod(const std::string &name) const
std::string update_old_atom_names(Structure &st) const
std::vector< Atom > atoms
Table find(const std::string &prefix, const std::vector< std::string > &tags)
bool has_tag(const std::string &tag) const