Skip to content

Commit

Permalink
Add get_acedrg_atom_types_for_ligand() to the api
Browse files Browse the repository at this point in the history
  • Loading branch information
pemsley committed Sep 16, 2024
1 parent 643a206 commit 872a90d
Show file tree
Hide file tree
Showing 12 changed files with 188 additions and 9 deletions.
9 changes: 9 additions & 0 deletions api/coot-molecule.cc
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,15 @@ coot::molecule_t::cid_to_residues(const std::string &atom_selection_cids) const
return v;
}

// can return null
mmdb::Residue *
coot::molecule_t::get_residue(const std::string &residue_cid) const {

mmdb::Residue *residue_p = cid_to_residue(residue_cid);
return residue_p;
}




// restore from (previous) backup
Expand Down
3 changes: 3 additions & 0 deletions api/coot-molecule.hh
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,9 @@ namespace coot {
// returns either the specified residue or null if not found
mmdb::Residue *get_residue(const residue_spec_t &residue_spec) const;

// can return null
mmdb::Residue *get_residue(const std::string &residue_cid) const;

std::string get_residue_name(const residue_spec_t &residue_spec) const;

bool have_unsaved_changes() const { return modification_info.have_unsaved_changes(); }
Expand Down
20 changes: 16 additions & 4 deletions api/molecules-container-nanobind.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
#include <nanobind/ndarray.h>
#include <nanobind/operators.h>

#include "molecules-container.hh"
#include "mini-mol/mini-mol-utils.hh"

#include "clipper/core/ramachandran.h"
#include "clipper/clipper-ccp4.h"

#include "coot-utils/g_triangle.hh"
#include "coords/mmdb-crystal.h"
#include "coot-utils/acedrg-types-for-residue.hh"
#include "coot-utils/g_triangle.hh"
#include "mini-mol/mini-mol-utils.hh"
#include "molecules-container.hh"


namespace nb = nanobind;

Expand Down Expand Up @@ -257,6 +258,7 @@ NB_MODULE(chapi, m) {
.def("geometry_init_standard",&molecules_container_t::geometry_init_standard)
.def("get_active_atom",&molecules_container_t::get_active_atom)
.def("get_acedrg_atom_types",&molecules_container_t::get_acedrg_atom_types)
.def("get_acedrg_atom_types_for_ligand",&molecules_container_t::get_acedrg_atom_types_for_ligand)
.def("get_atom",&molecules_container_t::get_atom, nb::rv_policy::reference)
.def("get_atom_using_cid",&molecules_container_t::get_atom_using_cid, nb::rv_policy::reference)
.def("get_bonds_mesh",&molecules_container_t::get_bonds_mesh)
Expand Down Expand Up @@ -556,6 +558,16 @@ NB_MODULE(chapi, m) {
.def_ro("geom", &coot::instanced_mesh_t::geom)
.def_ro("markup", &coot::instanced_mesh_t::markup)
;
nb::class_<coot::acedrg_types_for_bond_t>(m,"acedrg_types_for_bond_t")
.def_ro("atom_id_1", &coot::acedrg_types_for_bond_t::atom_id_1)
.def_ro("atom_id_2", &coot::acedrg_types_for_bond_t::atom_id_2)
.def_ro("atom_type_1", &coot::acedrg_types_for_bond_t::atom_type_1)
.def_ro("atom_type_2", &coot::acedrg_types_for_bond_t::atom_type_2)
.def_ro("bond_length", &coot::acedrg_types_for_bond_t::bond_length)
;
nb::class_<coot::acedrg_types_for_residue_t>(m,"acedrg_types_for_residue_t")
.def_ro("bond_types", &coot::acedrg_types_for_residue_t::bond_types)
;
nb::class_<coot::util::phi_psi_t>(m,"phi_psi_t")
.def("phi", &coot::util::phi_psi_t::phi)
.def("psi", &coot::util::phi_psi_t::psi)
Expand Down
18 changes: 18 additions & 0 deletions api/molecules-container.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5405,6 +5405,24 @@ molecules_container_t::get_acedrg_atom_types(const std::string &compound_id, int

}

//! get acedrg types for ligand bonds
//! @return a vector of `acedrg_types_for_residue_t`
coot::acedrg_types_for_residue_t
molecules_container_t::get_acedrg_atom_types_for_ligand(int imol, const std::string &residue_cid) const {

coot::acedrg_types_for_residue_t types;

if (is_valid_model_molecule(imol)) {
mmdb::Residue *residue_p = molecules[imol].get_residue(residue_cid);
if (residue_p) {
int imol_enc = imol;
types = coot::get_acedrg_types_for_residue(residue_p, imol_enc, geom);
}
}
return types;
}




//! export map molecule as glTF
Expand Down
4 changes: 4 additions & 0 deletions api/molecules-container.hh
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,10 @@ public:
//! on failure (atoms types are not in the dictionary or atom failure to look up the compound id)l
std::vector<std::pair<std::string, std::string> > get_acedrg_atom_types(const std::string &compound_id, int imol_enc) const;

//! get acedrg types for ligand bonds
//! @return a vector of `acedrg_types_for_residue_t`
coot::acedrg_types_for_residue_t get_acedrg_atom_types_for_ligand(int imol, const std::string &residue_cid) const;

//! write a PNG for the given compound_id. imol can be IMOL_ENC_ANY
//!
//! Currently this function does nothing (drawing is done with the not-allowed cairo)
Expand Down
30 changes: 26 additions & 4 deletions api/test-molecules-container.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
#include <iostream>
#include <iomanip>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/string_cast.hpp>
#include "MoleculesToTriangles/CXXClasses/MyMolecule.h"
#include "molecules-container.hh"
#include "coot-utils/acedrg-types-for-residue.hh"
#include "filo-tests.hh"
#include "lucrezia-tests.hh"

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

void starting_test(const char *func) {
std::cout << "\nStarting " << func << "()" << std::endl;
}
Expand Down Expand Up @@ -5933,6 +5934,26 @@ int test_dictionary_acedrg_atom_types(molecules_container_t &mc) {
return status;
}

int test_dictionary_acedrg_atom_types_for_ligand(molecules_container_t &mc) {

starting_test(__FUNCTION__);
int status = 0;

mc.import_cif_dictionary("YXG-as-LIG.cif", coot::protein_geometry::IMOL_ENC_ANY);
int imol = mc.get_monomer_from_dictionary("LIG", coot::protein_geometry::IMOL_ENC_ANY, false);
coot::acedrg_types_for_residue_t types = mc.get_acedrg_atom_types_for_ligand(imol, "//A/1");

std::cout << "------------- types (bond) ----------- " << std::endl;
for (unsigned int i=0; i<types.bond_types.size(); i++) {
const auto &bond_types = types.bond_types[i];
std::cout << "bond_type "
<< bond_types.atom_id_1 << " " << bond_types.atom_type_1 << " "
<< bond_types.atom_id_2 << " " << bond_types.atom_type_2
<< " bond-length: " << bond_types.bond_length << std::endl;
}
if (types.bond_types.size() > 10) status = 1;
return status;
}


int test_template(molecules_container_t &mc) {
Expand Down Expand Up @@ -6247,6 +6268,7 @@ int main(int argc, char **argv) {
// status += run_test(test_import_LIG_dictionary, "Import LIG.cif", mc);
// status += run_test(test_tricky_ligand_problem, "Tricky Ligand import/refine", mc);
status += run_test(test_dictionary_acedrg_atom_types, "Acedrg atom types", mc);
status += run_test(test_dictionary_acedrg_atom_types_for_ligand, "Acedrg atom types for ligand", mc);

if (status == n_tests) all_tests_status = 0;

Expand Down
3 changes: 2 additions & 1 deletion coot-utils/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ pkginclude_HEADERS = peak-search.hh coot-trim.hh \
atom-tree.hh jed-flip.hh atom-vertex.hh merge-C-and-N-terminii.hh simple-mesh.hh vertex.hh g_triangle.hh \
cylinder.hh cylinder-with-rotation-translation.hh oct.hh prideout-octasphere.hh cmtz-interface.hh mtz-column-auto-read.hh \
pugixml.hpp pugiconfig.hpp find-water-baddies.hh voidp-buffer.hh parse-pisa.hh diff-diff-map-peaks.hh tiny_gltf.h json.hpp \
stb_image.h stb_image_write.h glyco-tree.hh positron.hh mini-texture.hh texture-as-floats.hh pae.hh q-score.hh
stb_image.h stb_image_write.h glyco-tree.hh positron.hh mini-texture.hh texture-as-floats.hh pae.hh q-score.hh \
acedrg-types-for-residue.hh


pkgincludedir = $(includedir)/coot/coot-utils
Expand Down
46 changes: 46 additions & 0 deletions coot-utils/acedrg-types-for-residue.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

#ifndef ACEDRG_TYPES_FOR_RESIDUE_HH
#define ACEDRG_TYPES_FOR_RESIDUE_HH

#include <string>
#include <vector>

namespace coot {

class acedrg_types_for_bond_t {
public:
std::string atom_id_1;
std::string atom_id_2;
std::string atom_type_1;
std::string atom_type_2;
double bond_length;
acedrg_types_for_bond_t() : bond_length(-1) {}
acedrg_types_for_bond_t(const std::string &a11, const std::string &a12, const std::string &a21, const std::string &a22,
double bl) : atom_id_1(a11), atom_id_2(a12), atom_type_1(a21), atom_type_2(a22),
bond_length(bl) {}
};

class acedrg_types_for_angle_t {
public:
std::string atom_id_1;
std::string atom_id_2;
std::string atom_id_3;
std::string atom_type_1;
std::string atom_type_2;
std::string atom_type_3;
double angle; // radians
acedrg_types_for_angle_t(const std::string &a11, const std::string &a12, const std::string &a13,
const std::string &a21, const std::string &a22, const std::string &a23,
double a) : atom_id_1(a11), atom_id_2(a12), atom_id_3(a13),
atom_type_1(a21), atom_type_2(a22), atom_type_3(a23),
angle(a) {}
};

class acedrg_types_for_residue_t {
public:
std::vector<acedrg_types_for_bond_t> bond_types;
};

}

#endif // ACEDRG_TYPES_FOR_RESIDUE_HH
56 changes: 56 additions & 0 deletions coot-utils/coot-coord-extras.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@
*/


#include <cmath>
#include <stdexcept>
#include <iomanip>
#include <algorithm> // for std::find
#include <queue>
#include <string>
#include <functional>

#include "acedrg-types-for-residue.hh"
#include "string.h"

#include "compat/coot-sysdep.h"
Expand Down Expand Up @@ -2005,3 +2007,57 @@ coot::util::mutate_by_overlap(mmdb::Residue *residue_p, mmdb::Manager *mol,
return status;
}

coot::acedrg_types_for_residue_t
coot::get_acedrg_types_for_residue(mmdb::Residue *residue_p, int imol_enc,
const coot::protein_geometry &geom) {

coot::acedrg_types_for_residue_t types;
std::string residue_type = residue_p->GetResName();
auto r = geom.get_monomer_restraints(residue_type, imol_enc);
if (r.first) {
const auto &restraints = r.second;
for (unsigned int ib=0; ib<restraints.bond_restraint.size(); ib++) {
const auto &bond_restraint = restraints.bond_restraint[ib];
const std::string &atom_name_1 = bond_restraint.atom_id_1();
const std::string &atom_name_2 = bond_restraint.atom_id_2();
mmdb::Atom **residue_atoms = 0;
int n_residue_atoms = 0;
int idx_1 = -1;
int idx_2 = -1;
residue_p->GetAtomTable(residue_atoms, n_residue_atoms);
for (int iat=0; iat<n_residue_atoms; iat++) {
mmdb::Atom *at = residue_atoms[iat];
if (! at->isTer()) {
std::string atom_name = at->GetAtomName();
if (atom_name == atom_name_1) idx_1 = iat;
if (atom_name == atom_name_2) idx_2 = iat;
}
}
if (idx_1 != -1) {
if (idx_2 != -1) {
clipper::Coord_orth at_pos_1 = co(residue_atoms[idx_1]);
clipper::Coord_orth at_pos_2 = co(residue_atoms[idx_2]);
double bb = (at_pos_2 - at_pos_1).lengthsq();
double bond_length = std::sqrt(bb);

std::string type_1;
std::string type_2;

for (unsigned int ii=0; ii<restraints.atom_info.size(); ii++) {
const auto &atom = restraints.atom_info[ii];
if (atom.atom_id_4c == atom_name_1) type_1 = atom.acedrg_atom_type;
if (atom.atom_id_4c == atom_name_2) type_2 = atom.acedrg_atom_type;
}

if (! type_1.empty()) {
if (! type_2.empty()) {
acedrg_types_for_bond_t bt(atom_name_1, atom_name_2, type_1, type_2, bond_length);
types.bond_types.push_back(bt);
}
}
}
}
}
}
return types;
}
5 changes: 5 additions & 0 deletions coot-utils/coot-coord-extras.hh
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "mini-mol/atom-quads.hh"
#include "mini-mol/mini-mol.hh"
#include "bonded-pairs.hh"
#include "acedrg-types-for-residue.hh"

// functions and classes here (in extras) can use protein_geometry.

Expand Down Expand Up @@ -372,6 +373,10 @@ namespace coot {
const protein_geometry *geom_p,
bool strictly_cis_flag = false);


acedrg_types_for_residue_t get_acedrg_types_for_residue(mmdb::Residue *residue_p, int imol_enc,
const protein_geometry &geom);

}

#endif // HAVE_COOT_COORD_EXTRAS_HH
2 changes: 2 additions & 0 deletions coot-utils/coot-coord-utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9583,3 +9583,5 @@ coot::util::split_multi_model_molecule(mmdb::Manager *mol) {

return v;
}


1 change: 1 addition & 0 deletions rel-todo-gtk4
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

chapi: a function to return a list of tuples atom types for ligand:
get_acedrg_atom_types(comp_id, imol_enc);
* Done.

chapi: a function to return a list of tuples atom types for ligand:
(name_1, name_2, type_1, type_2, bond_length)
Expand Down

0 comments on commit 872a90d

Please sign in to comment.