diff --git a/modules/mol/alg/molalg.rst b/modules/mol/alg/molalg.rst index 2daf3ca7597bca27d86b9d86d53e7c67a33b5bb6..7758f3ff290de4812b9635514cf0f7a2f51e2f0a 100644 --- a/modules/mol/alg/molalg.rst +++ b/modules/mol/alg/molalg.rst @@ -40,4 +40,30 @@ :param ref: The index of the reference frame to use for superposition. If set to -1, the each frame is superposed to the previous frame. - :returns: A newly created coord group containing the superposed frames. \ No newline at end of file + :returns: A newly created coord group containing the superposed frames. + + +Steric Clashes +-------------------------------------------------------------------------------- + +The following function detects steric clashes in atomic structures. Two atoms are clashing if their euclidian distance is smaller than a threshold value. The threshold values are calculated from high-resolution X-ray structures for each possible element pair. The value is chosen such that 99.99% of observed distances between 0 and 5 Angstroem are above the threshold. + + +.. function:: FilterClashes(ent, tolerance=0.0) + + This function filters out residues with clashing atoms. If the clashing atom + is a backbone atom, the complete residue is removed, if the atom is part of + the sidechain, only the sidechain atoms are removed. + + Hydrogen and deuterium atoms are ignored. + + :param ent: The input entity + :type ent: :class:`~ost.mol.EntityView` or :class:`~ost.mol.EntityHandle` + :param tolerance: The tolerance in (Angstroem) is substracted from the + thresholds calculated from high resolution X-ray structures to make the + function less pedantic. Negative values are also allowed and make the + function more stringent. + + :returns: The filtered :class:`~ost.mol.EntityView` + + diff --git a/modules/mol/alg/pymod/wrap_mol_alg.cc b/modules/mol/alg/pymod/wrap_mol_alg.cc index 91a9a0904041a90bf502a8c4ecb00e7cbe99c7c0..a5db8de3560a56b1f31bead07cfc70b947850b79 100644 --- a/modules/mol/alg/pymod/wrap_mol_alg.cc +++ b/modules/mol/alg/pymod/wrap_mol_alg.cc @@ -21,6 +21,7 @@ #include <ost/config.hh> #include <ost/mol/alg/local_dist_test.hh> #include <ost/mol/alg/superpose_frames.hh> +#include <ost/mol/alg/filter_clashes.hh> using namespace boost::python; using namespace ost; @@ -34,6 +35,8 @@ namespace { Real (*ldt_a)(const mol::EntityView&, const mol::EntityView& ref, Real, Real)=&mol::alg::LocalDistTest; Real (*ldt_b)(const seq::AlignmentHandle&,Real, Real, int, int)=&mol::alg::LocalDistTest; +mol::EntityView (*fc_a)(const mol::EntityView&, Real)=&mol::alg::FilterClashes; +mol::EntityView (*fc_b)(const mol::EntityHandle&, Real)=&mol::alg::FilterClashes; } BOOST_PYTHON_MODULE(_mol_alg) @@ -45,6 +48,8 @@ BOOST_PYTHON_MODULE(_mol_alg) def("LocalDistTest", ldt_a); def("LocalDistTest", ldt_b, (arg("ref_index")=0, arg("mdl_index")=1)); + def("FilterClashes", fc_a, (arg("ent"), arg("tolerance")=0.1)); + def("FilterClashes", fc_b, (arg("ent"), arg("tolerance")=0.1)); def("SuperposeFrames", &ost::mol::alg::SuperposeFrames, (arg("source"), arg("sel")=ost::mol::EntityView(), arg("begin")=0, arg("end")=-1, arg("ref")=-1)); diff --git a/modules/mol/alg/src/CMakeLists.txt b/modules/mol/alg/src/CMakeLists.txt index 15e93c0e72ade2450464aaa55551828073dc1ce3..6d418a16c3691840dceb2eb4c33f968f6a6241e5 100644 --- a/modules/mol/alg/src/CMakeLists.txt +++ b/modules/mol/alg/src/CMakeLists.txt @@ -4,6 +4,7 @@ set(OST_MOL_ALG_HEADERS sec_structure_segments.hh local_dist_test.hh superpose_frames.hh + filter_clashes.hh ) set(OST_MOL_ALG_SOURCES @@ -11,6 +12,7 @@ set(OST_MOL_ALG_SOURCES sec_structure_segments.cc local_dist_test.cc superpose_frames.cc + filter_clashes.cc ) set(MOL_ALG_DEPS mol seq) diff --git a/modules/mol/alg/src/filter_clashes.cc b/modules/mol/alg/src/filter_clashes.cc new file mode 100644 index 0000000000000000000000000000000000000000..12c539b3ecdd76b7022bed31141675060fa0dd85 --- /dev/null +++ b/modules/mol/alg/src/filter_clashes.cc @@ -0,0 +1,144 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2010 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 <ost/log.hh> +#include <ost/mol/mol.hh> +#include "filter_clashes.hh" + +namespace ost { namespace mol { namespace alg { + +namespace { + +Real GetThreshold(const String& ele1, const String& ele2) { + if (ele1.length()!=1 || ele2.length()!=1) { + return 1.5; + } + switch (ele1[0]) { + case 'C' : + switch (ele2[0]) { + case 'C' : return 2.10; + case 'N' : return 2.10; + case 'S' : return 2.45; + case 'O' : return 2.25; + default: return 1.5; + } + case 'N': + switch (ele2[0]) { + case 'C' : return 2.10; + case 'N' : return 2.05; + case 'S' : return 2.55; + case 'O' : return 2.10; + default: return 1.5; + } + case 'O': + switch (ele2[0]) { + case 'C' : return 2.25; + case 'N' : return 2.10; + case 'S' : return 2.45; + case 'O' : return 2.05; + default: return 1.5; + } + case 'S': + switch (ele2[0]) { + case 'C' : return 2.45; + case 'N' : return 2.55; + case 'S' : return 1.80; + case 'O' : return 2.45; + default: return 1.5; + } + default: + return 1.5; + } +} + + +} + +EntityView FilterClashes(const EntityView& ent, Real tolerance) +{ + EntityView filtered=ent.CreateEmptyView(); + ResidueViewList residues=ent.GetResidueList(); + for (ResidueViewList::iterator + i=residues.begin(), e=residues.end(); i!=e; ++i) { + bool remove_sc=false, remove_bb=false; + ResidueView res=*i; + const AtomViewList& atoms=res.GetAtomList(); + for (AtomViewList::const_iterator + j=atoms.begin(), e2=atoms.end(); j!=e2; ++j) { + AtomView atom=*j; + String ele1=atom.GetElement(); + if (ele1=="H" || ele1=="D") { + continue; + } + AtomViewList within=ent.FindWithin(atom.GetPos(), 2.5-tolerance); + for (AtomViewList::iterator + k=within.begin(), e3=within.end(); k!=e3; ++k) { + AtomView atom2=*k; + if (atom2==atom) { + continue; + } + String ele2=atom2.GetElement(); + if (ele2=="H" || ele2=="D") { + continue; + } + // In theory, this should also trigger for disulfide bonds, but + // since we don't detect disulfides correctly, we can't count on that + // and we instead allow S-S distances down to 1.8. + if (atom.GetHandle().FindBondToAtom(atom2.GetHandle()).IsValid()) { + continue; + } + Real d=geom::Length2(atom.GetPos()-atom2.GetPos()); + Real threshold=GetThreshold(ele1, ele2)-tolerance; + if (d<threshold*threshold) { + remove_sc=true; + String name=atom.GetName(); + if (name=="CA" || name=="N" || name=="O" || name=="C") { + remove_bb=true; + } + } + } + } + if (remove_bb) { + LOG_VERBOSE("removing whole residue " << res); + continue; + } + if (remove_sc) { + LOG_VERBOSE("removing sidechain of residue " << res); + for (AtomViewList::const_iterator + j=atoms.begin(), e2=atoms.end(); j!=e2; ++j) { + AtomView atom=*j; + String name=atom.GetName(); + if (name=="CA" || name=="N" || name=="O" || name=="C") { + filtered.AddAtom(atom); + } + } + } + filtered.AddResidue(res, ViewAddFlag::INCLUDE_ATOMS); + } + return filtered; +} + + +EntityView FilterClashes(const EntityHandle& ent, Real tolerance) +{ + return FilterClashes(ent.CreateFullView(), tolerance); +} + + +}}} + diff --git a/modules/mol/alg/src/filter_clashes.hh b/modules/mol/alg/src/filter_clashes.hh new file mode 100644 index 0000000000000000000000000000000000000000..87fd770311435ec4115311c342aa2bec7fd4309f --- /dev/null +++ b/modules/mol/alg/src/filter_clashes.hh @@ -0,0 +1,36 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2010 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_ALG_FILTER_CLASHES_HH +#define OST_MOL_ALG_FILTER_CLASHES_HH + +#include <ost/mol/entity_view.hh> +#include <ost/mol/alg/module_config.hh> + +namespace ost { namespace mol { namespace alg { + + +EntityView DLLEXPORT_OST_MOL_ALG FilterClashes(const EntityView& ent, + Real tolerance=0.1); + +EntityView DLLEXPORT_OST_MOL_ALG FilterClashes(const EntityHandle& ent, + Real tolerance=0.1); +}}} + + +#endif diff --git a/modules/mol/alg/src/ldt.cc b/modules/mol/alg/src/ldt.cc index 589bd125f72b2abbba2921877a8b7b64618a3417..7a676b00ae74eceea3fa4cac96b7b18575896590 100644 --- a/modules/mol/alg/src/ldt.cc +++ b/modules/mol/alg/src/ldt.cc @@ -1,6 +1,26 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2010 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 <ost/mol/alg/local_dist_test.hh> +#include <ost/mol/alg/filter_clashes.hh> #include <ost/io/mol/pdb_reader.hh> #include <ost/io/io_exception.hh> +#include <ost/conop/conop.hh> using namespace ost; using namespace ost::io; using namespace ost::mol; @@ -12,6 +32,8 @@ EntityHandle load(const String& file) if (reader.HasNext()) { EntityHandle ent=CreateEntity(); reader.Import(ent); + conop::Conopology& conop_inst=conop::Conopology::Instance(); + conop_inst.ConnectAll(conop_inst.GetBuilder(), ent); return ent; } std::cerr << "ERROR: '" << file << "' does not contain any ATOM records. " @@ -82,6 +104,9 @@ int main (int argc, char* const *argv) continue; } EntityView v=model.CreateFullView(); + if (filter_clashes) { + v=alg::FilterClashes(v); + } float cutoffs[]={0.5,1,2,4}; float ldt=0.0; for (int n=0; n<4; ++n) { diff --git a/modules/mol/alg/src/local_dist_test.hh b/modules/mol/alg/src/local_dist_test.hh index ab7588cdf84d401aaee052bcfe2b390da8174b15..a4e645acce1e5ae8d490e34a52860af0ac9705b7 100644 --- a/modules/mol/alg/src/local_dist_test.hh +++ b/modules/mol/alg/src/local_dist_test.hh @@ -1,3 +1,21 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2010 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_ALG_LOCAL_DIST_TEST_HH #define OST_MOL_ALG_LOCAL_DIST_TEST_HH