6#ifndef GEMMI_CHEMCOMP_HPP_
7#define GEMMI_CHEMCOMP_HPP_
46 if (
comp == 2 && res2 !=
nullptr) {
54 if (a ==
nullptr &&
alt !=
'\0' && residue->
group_idx > 0)
59 char alt,
char alt2)
const {
65 const std::string&
name2) {
72 static const char*
what() {
return "bond"; }
95 static const char*
what() {
return "angle"; }
106 static const char*
what() {
return "torsion"; }
118 static const char*
what() {
return "chirality"; }
132 static const char*
what() {
return "plane"; }
154 return std::find_if(
bonds.begin(),
bonds.end(), [&](
const Bond& b) {
155 return (b.id1 == a1 && b.id2 == a2) || (b.id1 == a2 && b.id2 == a1);
165 fail(
"Bond restraint not found: ",
a1.atom,
'-',
a2.atom);
184 std::vector<AtomId>
visited)
const {
188 std::vector<int> parent(
visited.size(), -1);
189 for (
int n = start; end == -1 && n != (
int)
visited.size(); ++n) {
200 std::vector<AtomId> path;
201 for (
int n = end; n != -1; n = parent[n])
207 std::vector<Angle>::iterator
find_angle(
const T& a,
const T& b,
const T& c) {
209 return ang.id2 == b && ((ang.id1 == a && ang.id3 == c) ||
210 (ang.id1 == c && ang.id3 == a));
213 template<
typename T> std::vector<Angle>::const_iterator
226 const T& c,
const T&
d) {
229 return (t.id1 == a && t.id2 == b && t.id3 == c && t.id4 == d) ||
230 (t.id1 == d && t.id2 == c && t.id3 == b && t.id4 == a);
233 template<
typename T> std::vector<Torsion>::const_iterator
240 const T& b,
const T& c) {
242 return t.id_ctr == ctr && ((t.id1 == a && t.id2 == b && t.id3 == c) ||
243 (t.id1 == b && t.id2 == c && t.id3 == a) ||
244 (t.id1 == c && t.id2 == a && t.id3 == b));
247 template<
typename T> std::vector<Chirality>::const_iterator
254 std::vector<Plane>::iterator
get_plane(
const std::string& label) {
256 [&label](
const Plane&
p) { return p.label == label; });
260 std::vector<Plane>::iterator
it =
get_plane(label);
299template<
typename Restr>
310 double cosine = a == 90. ? 0. : std::cos(
rad(a));
314 return mult * std::sqrt(std::max(0., x + y));
359 std::vector<std::pair<std::string, std::string>>
related;
362 for (
const auto& item :
related)
381 fail(
"aliasing not found");
385 if (str.size() >= 3) {
386 const char*
cstr = str.c_str();
387 if ((str[0] ==
'\'' || str[0] ==
'"') && str.size() >= 5)
429 return std::find_if(
atoms.begin(),
atoms.end(),
430 [&](
const Atom& a) { return a.id == atom_id; });
440 return std::find_if(
atoms.begin(),
atoms.end(),
441 [&](
const Atom& a) { return a.old_id == old_id; });
447 return std::any_of(
atoms.begin(),
atoms.end(),
448 [&](
const Atom& a) { return !a.old_id.empty() && a.old_id != a.id; });
474 return !has_atom(x.id1.atom) ||
475 !has_atom(x.id2.atom);
478 return !has_atom(x.id1.atom) ||
479 !has_atom(x.id2.atom) ||
480 !has_atom(x.id3.atom);
483 return !has_atom(x.id1.atom) ||
484 !has_atom(x.id2.atom) ||
485 !has_atom(x.id3.atom) ||
486 !has_atom(x.id4.atom);
489 return !has_atom(x.id_ctr.atom) ||
490 !has_atom(x.id1.atom) ||
491 !has_atom(x.id2.atom) ||
492 !has_atom(x.id3.atom);
524 throw std::out_of_range(
"Unexpected bond type: " + s);
555 switch (s[0] | 0x20) {
560 default:
throw std::out_of_range(
"Unexpected chirality: " + s);
566 switch (s[0] | 0x20) {
570 default:
throw std::out_of_range(
"Unexpected volume_flag: " + s);
594 for (
auto row : block.
find(
"_chem_comp_atom.",
595 {
"atom_id",
"type_symbol",
"?type_energy",
596 "?charge",
"?partial_charge",
"?alt_atom_id"}))
598 row.has(5) ?
row.str(5) :
"",
601 row.has(2) ?
row.str(2) :
"",
603 for (
auto row : block.
find(
"_chem_comp_bond.",
604 {
"atom_id_1",
"atom_id_2",
605 "?type",
"?value_order",
606 "?aromatic",
"?pdbx_aromatic_flag",
607 "?value_dist",
"?value_dist_esd",
608 "?value_dist_nucleus",
"?value_dist_nucleus_esd"})) {
618 for (
auto row : block.
find(
"_chem_comp_angle.",
619 {
"atom_id_1",
"atom_id_2",
"atom_id_3",
620 "value_angle",
"value_angle_esd"}))
623 for (
auto row : block.
find(
"_chem_comp_tor.",
625 "atom_id_1",
"atom_id_2",
626 "atom_id_3",
"atom_id_4",
627 "value_angle",
"value_angle_esd",
630 {1,
row.str(1)}, {1,
row.str(2)},
631 {1,
row.str(3)}, {1,
row.str(4)},
634 for (
auto row : block.
find(
"_chem_comp_chir.",
636 "atom_id_1",
"atom_id_2",
"atom_id_3",
638 if (
row[4][0] !=
'c')
640 {1,
row.str(1)}, {1,
row.str(2)}, {1,
row.str(3)},
644 {
"chir_id",
"atom_id"});
646 std::map<std::string, std::vector<std::string>>
chir_atoms;
649 for (
auto row : block.
find(
"_chem_comp_chir.",
650 {
"id",
"atom_id",
"volume_flag",
"volume_three"})) {
652 if (atoms !=
chir_atoms.end() && atoms->second.size() == 3)
654 {1, atoms->second[0]}, {1, atoms->second[1]},
655 {1, atoms->second[2]},
660 for (
auto row : block.find(
"_chem_comp_plane_atom.",
661 {
"plane_id",
"atom_id" ,
"dist_esd"})) {
662 Restraints::Plane& plane = cc.rt.get_or_add_plane(row.str(0));
663 if (plane.esd == 0.0)
664 plane.esd = cif::as_number(row[2]);
665 plane.ids.push_back({1, row.str(1)});
667 for (
auto row : block.find(
"_chem_comp_alias.",
668 {
"group",
"atom_id",
"atom_id_standard"})) {
669 ChemComp::Group group = ChemComp::read_group(row.str(0));
670 if (cc.aliases.empty() || cc.aliases.back().group != group) {
671 cc.aliases.emplace_back();
672 cc.aliases.back().group = group;
674 cc.aliases.back().related.emplace_back(row.str(1), row.str(2));
double as_number(const std::string &s, double nan=NAN)
bool is_null(const std::string &value)
int as_int(const std::string &str)
void vector_remove_if(std::vector< T > &v, F &&condition)
double chiral_abs_volume(double bond1, double bond2, double bond3, double angle1, double angle2, double angle3)
constexpr double deg(double angle)
ChemComp make_chemcomp_from_block(const cif::Block &block_)
const char * chirality_to_string(ChiralityType chir_type)
ChiralityType chirality_from_flag_and_volume(const std::string &s, double volume)
std::string join_str(T begin, T end, const S &sep, const F &getter)
bool in_vector(const T &x, const std::vector< T > &v)
double angle_abs_diff(double a, double b, double full=360.0)
constexpr double rad(double angle)
std::string cat(Args const &... args)
const char * bond_type_to_string(BondType btype)
double angle_z(double value_rad, const Restr &restr, double full=360.)
bool starts_with(const std::string &str, const std::string &prefix)
void fail(const std::string &msg)
float order_of_bond_type(BondType btype)
ChiralityType chirality_from_string(const std::string &s)
constexpr int ialpha4_id(const char *s)
BondType bond_type_from_string(const std::string &s)
Represents atom site in macromolecular structure (~100 bytes).
const std::string * name_from_alias(const std::string &atom_id) const
std::vector< std::pair< std::string, std::string > > related
void set_group(const std::string &s)
ChemComp & remove_hydrogens()
int get_atom_index(const std::string &atom_id) const
std::vector< Atom >::const_iterator find_atom(const std::string &atom_id) const
bool has_old_names() const
static const char * group_str(Group g)
std::vector< Atom >::iterator find_atom_by_old_name(const std::string &old_id)
const Aliasing & get_aliasing(Group g) const
void remove_nonmatching_restraints()
std::vector< Atom >::const_iterator find_atom_by_old_name(const std::string &old_id) const
static Group read_group(const std::string &str)
const Atom & get_atom(const std::string &atom_id) const
std::vector< Atom > atoms
static bool is_nucleotide_group(Group g)
Check if the group is DNA/RNA.
bool has_atom(const std::string &atom_id) const
std::vector< Aliasing > aliases
std::string type_or_group
std::vector< Atom >::iterator find_atom(const std::string &atom_id)
static bool is_peptide_group(Group g)
Check if the group (M-|P-)peptide.
Coordinates in Angstroms - orthogonal (Cartesian) coordinates.
Atom * find_atom(const std::string &atom_name, char altloc, El el=El::X)
static const char * what()
bool operator<(const AtomId &o) const
const Atom * get_from(const Residue &res1, const Residue *res2, char alt, char alt2) const
bool operator==(const AtomId &o) const
bool operator!=(const std::string &name) const
Atom * get_from(Residue &res1, Residue *res2, char alt, char altloc2) const
bool operator==(const std::string &name) const
bool operator!=(const AtomId &o) const
static const char * what()
double distance(DistanceOf of) const
const AtomId * other(const T &a) const
std::string lexicographic_str() const
static const char * what()
bool is_wrong(double volume) const
std::vector< AtomId > ids
static const char * what()
static const char * what()
std::vector< Chirality >::const_iterator find_chir(const T &ctr, const T &a, const T &b, const T &c) const
bool are_bonded(const T &a1, const T &a2) const
std::vector< Bond >::iterator find_bond(const T &a1, const T &a2)
std::vector< Bond > bonds
std::vector< Bond >::const_iterator find_bond(const T &a1, const T &a2) const
void rename_atom(const AtomId &atom_id, const std::string &new_name)
const AtomId * first_bonded_atom(const T &a) const
std::vector< Plane >::iterator get_plane(const std::string &label)
std::vector< Torsion >::const_iterator find_torsion(const T &a, const T &b, const T &c, const T &d) const
std::vector< Chirality > chirs
std::vector< Torsion >::iterator find_torsion(const T &a, const T &b, const T &c, const T &d)
std::vector< Angle >::iterator find_angle(const T &a, const T &b, const T &c)
const Bond & get_bond(const AtomId &a1, const AtomId &a2) const
std::vector< Angle >::const_iterator find_angle(const T &a, const T &b, const T &c) const
std::vector< Angle > angles
Plane & get_or_add_plane(const std::string &label)
std::vector< AtomId > find_shortest_path(const AtomId &a, const AtomId &b, std::vector< AtomId > visited) const
std::vector< Plane > planes
std::vector< Torsion > torsions
const Angle & get_angle(const AtomId &a, const AtomId &b, const AtomId &c) const
static std::string lexicographic_str(const std::string &name1, const std::string &name2)
std::vector< Chirality >::iterator find_chir(const T &ctr, const T &a, const T &b, const T &c)
double chiral_abs_volume(const Restraints::Chirality &ch) const
Column find_values(const std::string &tag)
Table find(const std::string &prefix, const std::vector< std::string > &tags)