diff --git a/modules/mol/base/pymod/export_bond.cc b/modules/mol/base/pymod/export_bond.cc index 5f7ab1154ad0c785cca591fd5ee47c5b01ee700c..da2a31509575f4a80de3104667cfa18a8a7d89ac 100644 --- a/modules/mol/base/pymod/export_bond.cc +++ b/modules/mol/base/pymod/export_bond.cc @@ -21,7 +21,6 @@ using namespace boost::python; - #include <ost/mol/mol.hh> using namespace ost; @@ -61,4 +60,5 @@ void export_Bond() .def(vector_indexing_suite<BondHandleList>()) .def(geom::VectorAdditions<BondHandleList>()); def("BondExists", &BondExists); + } diff --git a/modules/mol/base/src/CMakeLists.txt b/modules/mol/base/src/CMakeLists.txt index 8d206d3c61b193deb48942e563baadb31c4c5aa4..0a399125f5bbc75f3af8f7868d80cbff07dab30e 100644 --- a/modules/mol/base/src/CMakeLists.txt +++ b/modules/mol/base/src/CMakeLists.txt @@ -30,6 +30,7 @@ residue_handle.cc residue_view.cc surface_builder.cc surface_handle.cc +transfer_connectivity.cc torsion_handle.cc query_view_wrapper.cc view_op.cc @@ -87,6 +88,7 @@ builder.hh surface_handle.hh surface_prop.hh torsion_handle.hh +transfer_connectivity.hh query_view_wrapper.hh view_op.hh view_type_fw.hh diff --git a/modules/mol/base/src/builder.hh b/modules/mol/base/src/builder.hh index 0a652a8b010ac97182a50e79591c00f6c3c6b81d..d46ed485bbe0c8ebf3d2ccf54e62347034b66915 100644 --- a/modules/mol/base/src/builder.hh +++ b/modules/mol/base/src/builder.hh @@ -26,6 +26,7 @@ #include "residue_handle.hh" #include "chain_handle.hh" #include "entity_handle.hh" +#include "bond_handle.hh" #include "xcs_editor.hh" @@ -62,6 +63,27 @@ public: edi_.InsertAtom(res_, name, pos); return *this; } + Builder& Gly(bool connect=true) { + this->Residue("GLY"); + this->Atom("N"); + this->Atom("CA"); + this->Atom("C"); + this->Atom("O"); + if (connect) { + edi_.Connect(res_.FindAtom("N"), res_.FindAtom("CA")); + edi_.Connect(res_.FindAtom("CA"), res_.FindAtom("C")); + edi_.Connect(res_.FindAtom("C"), res_.FindAtom("O")); + } + return *this; + } + Builder& ConnectToPrev() { + AtomHandle ah = res_.FindAtom("N"); + AtomHandle pa = res_.GetPrev().FindAtom("C"); + if (pa) { + edi_.Connect(pa, ah); + } + return *this; + } private: EntityHandle ent_; ChainHandle chain_; diff --git a/modules/mol/base/src/transfer_connectivity.cc b/modules/mol/base/src/transfer_connectivity.cc new file mode 100644 index 0000000000000000000000000000000000000000..38b1d6f151043611eac09762f9fcf4ec2f00272c --- /dev/null +++ b/modules/mol/base/src/transfer_connectivity.cc @@ -0,0 +1,119 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ + +#include "transfer_connectivity.hh" +#include "entity_visitor.hh" +#include "residue_handle.hh" +#include "atom_handle.hh" +#include "bond_handle.hh" +#include "xcs_editor.hh" + + +namespace ost { namespace mol { + +namespace { + +class ConnectivityTransferVisitor : public EntityVisitor { +public: + ConnectivityTransferVisitor(EntityHandle dst, + const std::map<ResidueHandle, ResidueHandle>* to_from): + edi_(dst.EditXCS(mol::BUFFERED_EDIT)), to_from_(to_from) { + } + + bool VisitResidue(const ResidueHandle& dest_res) { + std::map<ResidueHandle, ResidueHandle>::const_iterator i = to_from_->find(dest_res); + if (i == to_from_->end()) { + return false; + } + const std::pair<ResidueHandle, ResidueHandle>& ft = *i; + if (!ft.second.IsValid()) { + return false; + } + + // define a map from atom name to atom handle for the dest residue. + std::map<String, AtomHandle> name_to_handle; + AtomHandleList dest_atoms = dest_res.GetAtomList(); + for (AtomHandleList::iterator j = dest_atoms.begin(), e = dest_atoms.end(); j !=e ; ++j) { + name_to_handle[j->GetName()] = *j; + } + + AtomHandleList src_atoms = ft.second.GetAtomList(); + for (AtomHandleList::iterator j = src_atoms.begin(), e = src_atoms.end(); j !=e ; ++j) { + BondHandleList bonds = j->GetBondList(); + for (BondHandleList::iterator k = bonds.begin(), e2 = bonds.end(); k !=e2; ++k) { + AtomHandle first = k->GetFirst(); + AtomHandle second = k->GetSecond(); + AtomHandle dst_frst = this->GetDestAtomForSrcAtom(first, ft.second, ft.first, + name_to_handle); + AtomHandle dst_scnd = this->GetDestAtomForSrcAtom(second, ft.second, ft.first, + name_to_handle); + // add bond... + if (!dst_frst || !dst_scnd) { + continue; + } + edi_.Connect(dst_frst, dst_scnd); + } + } + return false; + } + + AtomHandle GetDestAtomForSrcAtom(AtomHandle src_atom, ResidueHandle src_res, + ResidueHandle dst_res, + const std::map<String, AtomHandle>& name_to_atom) { + ResidueHandle r = src_atom.GetResidue(); + if (r == src_res) { + // fast track... + std::map<String, AtomHandle>::const_iterator i = name_to_atom.find(src_atom.GetName()); + return i == name_to_atom.end() ? AtomHandle() : i->second; + } + // educated guess: we are trying to connect to the previous/next residue + std::map<ResidueHandle, ResidueHandle>::const_iterator j; + j = to_from_->find(dst_res.GetPrev()); + if (j != to_from_->end()) { + if (j->second == r) { + return j->first.FindAtom(src_atom.GetName()); + } + } + j = to_from_->find(dst_res.GetNext()); + if (j != to_from_->end()) { + if (j->second == r) { + return j->first.FindAtom(src_atom.GetName()); + } + } + // still nothing. scan linearly through all residues. + for ( j = to_from_->begin(); j != to_from_->end(); ++j) { + if (j->second == r) { + return j->first.FindAtom(src_atom.GetName()); + } + } + return AtomHandle(); + } +private: + XCSEditor edi_; + const std::map<ResidueHandle, ResidueHandle>* to_from_; +}; + +} +void TransferConnectivity(EntityHandle dest, + const std::map<ResidueHandle, ResidueHandle>& to_from) { + ConnectivityTransferVisitor visitor(dest, &to_from); + dest.Apply(visitor); +} + +}} diff --git a/modules/mol/base/src/transfer_connectivity.hh b/modules/mol/base/src/transfer_connectivity.hh new file mode 100644 index 0000000000000000000000000000000000000000..e46691cd25d920ff1268f52d730ef70f2662d464 --- /dev/null +++ b/modules/mol/base/src/transfer_connectivity.hh @@ -0,0 +1,37 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#ifndef OST_MOL_TRANSFER_CONNECTIVITY_HH +#define OST_MOL_TRANSFER_CONNECTIVITY_HH + + +#include "module_config.hh" +#include "entity_handle.hh" +#include "residue_handle.hh" + +namespace ost { namespace mol { + +void DLLEXPORT_OST_MOL +TransferConnectivity(EntityHandle dest, const std::map<ResidueHandle, ResidueHandle>& to_from); + + +bool operator<(const ResidueHandle& lhs, const ResidueHandle& rhs) { + return lhs.GetHashCode()<rhs.GetHashCode(); +} +}} +#endif diff --git a/modules/mol/base/tests/CMakeLists.txt b/modules/mol/base/tests/CMakeLists.txt index 176f6ad2421f1d381eaf4800c4f2ec3ad2419325..20f039557801f6a0c672550fb230306f59b418ba 100644 --- a/modules/mol/base/tests/CMakeLists.txt +++ b/modules/mol/base/tests/CMakeLists.txt @@ -12,6 +12,7 @@ set(OST_MOL_BASE_UNIT_TESTS test_surface.cc test_residue.cc test_view.cc + test_transfer_connectivity.cc test_view_op.cc tests.cc ) diff --git a/modules/mol/base/tests/test_transfer_connectivity.cc b/modules/mol/base/tests/test_transfer_connectivity.cc new file mode 100644 index 0000000000000000000000000000000000000000..2f5dff1439bf64099a9e109d6336ac6dc54b8737 --- /dev/null +++ b/modules/mol/base/tests/test_transfer_connectivity.cc @@ -0,0 +1,78 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2011 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +/* + * Authors: Marco Biasini + */ + +#include <ost/mol/builder.hh> +#include <ost/mol/transfer_connectivity.hh> + +#define BOOST_TEST_DYN_LINK +#include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> + +using namespace ost; +using namespace ost::mol; + +BOOST_AUTO_TEST_SUITE( mol_transfer_conn ); + +BOOST_AUTO_TEST_CASE(test_transfer_conn) +{ + EntityHandle ent = Builder() + .Chain("A") + .Gly() + .Gly() + .ConnectToPrev() + .Gly() + .ConnectToPrev() + ; + + ent.EditXCS().Connect(ent.FindAtom("A", 1, "O"), ent.FindAtom("A", 3, "O")); + + EntityHandle ent2 = Builder() + .Chain("A") + .Gly(false) + .Gly(false) + .Gly(false) + ; + std::map<ResidueHandle, ResidueHandle> to_from; + ResidueHandleList r1 = ent.GetResidueList(); + ResidueHandleList r2 = ent2.GetResidueList(); + for (size_t i = 0;i<r1.size(); ++i) { + to_from[r2[i]] = r1[i]; + } + TransferConnectivity(ent2, to_from); + BOOST_CHECK(BondExists(ent2.FindAtom("A", 1, "N"), ent2.FindAtom("A", 1, "CA"))); + BOOST_CHECK(BondExists(ent2.FindAtom("A", 1, "CA"), ent2.FindAtom("A", 1, "C"))); + BOOST_CHECK(BondExists(ent2.FindAtom("A", 1, "C"), ent2.FindAtom("A", 1, "O"))); + BOOST_CHECK(BondExists(ent2.FindAtom("A", 1, "C"), ent2.FindAtom("A", 2, "N"))); + BOOST_CHECK(BondExists(ent2.FindAtom("A", 2, "N"), ent2.FindAtom("A", 2, "CA"))); + BOOST_CHECK(BondExists(ent2.FindAtom("A", 2, "CA"), ent2.FindAtom("A", 2, "C"))); + BOOST_CHECK(BondExists(ent2.FindAtom("A", 2, "C"), ent2.FindAtom("A", 2, "O"))); + BOOST_CHECK(BondExists(ent2.FindAtom("A", 2, "C"), ent2.FindAtom("A", 3, "N"))); + BOOST_CHECK(BondExists(ent2.FindAtom("A", 3, "N"), ent2.FindAtom("A", 3, "CA"))); + BOOST_CHECK(BondExists(ent2.FindAtom("A", 3, "CA"), ent2.FindAtom("A", 3, "C"))); + BOOST_CHECK(BondExists(ent2.FindAtom("A", 3, "C"), ent2.FindAtom("A", 3, "O"))); + BOOST_CHECK(BondExists(ent2.FindAtom("A", 1, "O"), ent2.FindAtom("A", 3, "O"))); + BOOST_CHECK_EQUAL(12, ent2.GetBondCount()); +} + + + +BOOST_AUTO_TEST_SUITE_END();