diff --git a/.gitignore b/.gitignore index c098dd22237c9f9158350a5ad6d819e262ee92fa..156016aab9ca7cd1aabb380eb0ecd78ba2cda2c0 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,7 @@ components.cif compounds.chemlib /deployment/macos/openstructure.dmg /scripts/dng +/modules/gui/src/module_config.hh *.vcproj /scripts/ost_config *.user @@ -65,3 +66,6 @@ Debug /modules/io/tests/temp_img.tmp PYTEST-*.xml ost_*_tests_log.xml +rules.ninja +build.ninja +modules/gui/src/dngr.qrc.depends diff --git a/CMakeLists.txt b/CMakeLists.txt index 78fd252a379bf5cb9fd0dec1492a54672e1171c9..34244717a2e4676c37d1499e6c175e53dd3930f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -195,6 +195,21 @@ if (ENABLE_INFO) find_package(Qt4 4.5.0 REQUIRED) endif() +if (OPTIMIZE) + if (CXX_FLAGS) + set (CMAKE_CXX_FLAGS_RELEASE ${CXX_FLAGS}) + endif() + if (C_FLAGS) + set (CMAKE_C_FLAGS_RELEASE ${C_FLAGS}) + endif() +else() + if (CXX_FLAGS) + set(CMAKE_CXX_FLAGS_DEBUG ${CXX_FLAGS}) + endif() + if (C_FLAGS) + set(CMAKE_C_FLAGS_DEBUG ${C_FLAGS}) + endif() +endif() if (ENABLE_GFX) if(USE_MESA) find_package(Mesa REQUIRED) @@ -312,6 +327,10 @@ set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES #ost_match_boost_python_version(${PYTHON_LIBRARIES}) +if (CMAKE_COMPILER_IS_GNUCXX) + set(HIDDEN_VIS_MSG + "\n Hidden object visibility (-DHIDDEN_VISIBILITY) : ${_HIDDEN_VIS}") +endif() message(STATUS "OpenStructure will be built with the following options:\n" " Install Prefix (-DPREFIX) : ${CMAKE_INSTALL_PREFIX}\n" @@ -330,9 +349,6 @@ message(STATUS " Compound Lib (-DCOMPOUND_LIB) : ${_COMP_LIB}\n" " TMAlign and TMScore (-DCOMPILE_TMTOOLS) : ${_TM_TOOLS}\n" " Static Libraries (-DENABLE_STATIC) : ${ENABLE_STATIC}\n" - " Debian-style 'libexec' (-DDEBIAN_STYLE_LIBEXEC) : ${_DEBIAN_STYLE_LIBEXEC}") -if (CMAKE_COMPILER_IS_GNUCXX) - message(STATUS - " Hidden object visibility (-DHIDDEN_VISIBILITY) : ${_HIDDEN_VIS}") -endif() + " Debian-style 'libexec' (-DDEBIAN_STYLE_LIBEXEC) : ${_DEBIAN_STYLE_LIBEXEC}" + ${HIDDEN_VIS_MSG}) diff --git a/modules/conop/doc/compoundlib.rst b/modules/conop/doc/compoundlib.rst index 3e0e70d41bc5484965f7e2e0fed8e9870c6e7186..bf14500361e7aafcb2060df321e8592fd8054fff 100644 --- a/modules/conop/doc/compoundlib.rst +++ b/modules/conop/doc/compoundlib.rst @@ -6,7 +6,7 @@ The compound library Compound libraries contain information on chemical compounds, such as their connectivity, chemical class and one-letter-code. The compound library has several uses, but the most important one is to provide the connectivy -information for the :class:`rule-based builder <RuleBasedBuilder>`. +information for the :class:`rule-based processor <RuleBasedBuilder>`. The compound definitions for standard PDB files are taken from the components.cif dictionary provided by the PDB. The dictionary is updated with diff --git a/modules/conop/doc/connectivity.rst b/modules/conop/doc/connectivity.rst index 98270b1aff31b7fa6d0f15f526e4dde56e8ef735..64a43bfd2e4060b6e8ce731242b5dbfcda484fd1 100644 --- a/modules/conop/doc/connectivity.rst +++ b/modules/conop/doc/connectivity.rst @@ -6,14 +6,16 @@ Connectivity Motivation -------------------------------------------------------------------------------- -Traditionally the connectivity between atoms has not been reliably described in -a PDB file. Different programs adopted various ways of finding out if two atoms -are connected. One way chosen is to rely on proper naming of the atoms. For -example, the backbone atoms of the standard amino acids are named as N, CA, C -and O and if atoms with these name appear in the same residue they are shown -connected. Another way is to apply additional heuristics to find out if a -peptide bond between two consecutive residues is formed. Breaks in the backbone -are indicated, e.g., by introducing a discontinuity in the numbering of the residue. + + +The connectivity of atoms is notoriously difficult to come by for biological +macromolecules. PDB files, the de-factor standard exchange format for structural +information allows bonds to be specified in CONECT records. However, they are not +mandatory. Many programs, especially the ones not requiring on connectivity of +atoms, do not write CONECT records. As a result, programs and structural biology +frameworks can't rely on connectivity information to be present. The connectivity +information needs to be derived in the program itself. + Loader heuristics are great if you are the one that implemented them but are problematic if you are just the user of a software that has them. As time goes @@ -25,248 +27,110 @@ software wants to read in a PDB files as is without making any changes. A script in an automated pipeline, however, does want to either strictly reject files that are incomplete or fill-in missing structural features. All these aspects are implemented in the conop module, separated from the loading of the -PDB file, giving clients a fine grained control over the loading process. +PDB file, giving clients a fine grained control over the loading process. The +conop logic can thus be reused in code requiring the presence of -The conop module defines a :class:`Builder` interface, to run connectivity +The conop module defines a :class:`Processor` interface, to run connectivity algorithms, that is to connect the atoms with bonds and perform basic clean up of erroneous structures. The clients of the conop module can specify how the -Builder should treat unknown amino acids, missing atoms and chemically +Processor should treat unknown amino acids, missing atoms and chemically infeasible bonds. -The high-level interface +Processors -------------------------------------------------------------------------------- +The exact behaviour for a processor is implementation-specific. So far, two +classes implement the processor interface: A heuristic and a rule-based processor. +The processor mainly differ in the source of their connectivity information. The +Heuristicprocessor uses a hard-coded heuristic connectivity table for the 20 +standard amino acids as well as nucleotides.For other compounds such as ligands +the HeuristicProcessor runs a distance-based connectivity algorithm that connects +two atoms if they are closer than a certain threshold. The RuleBasedProcessor +uses a connectivity library containing all molecular components present in the +PDB files on PDB.org. The library can easily be extended with custom +connectivity information, if required. If a :doc:`compound library <compoundlib>` is +present, the :class:`RuleBasedProcessor` is enabled by default, otherwise the +:class:`HeuristicProcessor` is used as a fallback. -.. autofunction:: ConnectAll() +The Processor base class +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. class:: Processor -A call to :func:`ConnectAll` is sufficient to assign residue and atoms -properties as well as to connect atoms with bonds. + .. attribute:: connect + Whether to connect atoms by bonds. Enabled by default. Turn this off if you + would like to speed up the loading process and do not require connectivity + information to be present in your structures. -.. code-block:: python + :type: :class:`bool` - # Suppose that BuildRawModel is a function that returns a protein structure - # with no atom properties assigned and no bonds formed. - ent=BuildRawModel(...) - print ent.bonds # will return an empty list - # Call ConnectAll() to assign properties/connect atoms - conop.ConnectAll(ent) - print ent.bonds # will print a list containing many bonds + .. attribute:: zero_occ_treatment -For a more fine-grained control, consider using the :class:`Builder` interface. + Controls the behaviour of importing atoms with zero occupancy. By default, this + is set to silent. -The builder interface --------------------------------------------------------------------------------- + :type: :class:`str` -The exact behaviour for a builder is implementation-specific. So far, two -classes implement the Builder interface: A heuristic and a rule-based builder. The builders mainly differ in the source of their connectivity information. The -HeuristicBuilder uses a hard-coded heuristic connectivity table for the 20 -standard amino acids as well as nucleotides.For other compounds such as ligands -the HeuristicBuilder runs a distance-based connectivity algorithm that connects -two atoms if they are closer than a certain threshold. The RuleBasedBuilder -uses a connectivity library containing all molecular components present in the -PDB files on PDB.org. The library can easily be extended with custom -connectivity information, if required. If a :doc:`compound library <compoundlib>` is present, the :class:`RuleBasedBuilder` is enabled by default, otherwise the :class:`HeuristicBuilder` is used as a fallback. + .. attribute:: check_bond_feasibility -The following 3 functions give you access to builders known to OpenStructure, -and allow you to set the default builder: + Whether an additional bond feasibility check is performed. Disabled by default. + Turn this on, if you would like to connect atoms by bonds only if they are + within a reasonable distance. + :type: :class:`bool` -.. autofunction:: GetBuilder() + .. attribute:: assign_torsions -.. autofunction:: RegisterBuilder() - -.. autofunction:: SetDefaultBuilder() + Whether backbone torsions should be added to the backbone. Disabled by default. + Set to true, to assign PHI, PSI and OMEGA torsions to the peptide residues. -The Builder baseclass -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + :type: :class:`bool` -.. class:: Builder - .. method:: CompleteAtoms(residue) - - add any missing atoms to the residue based on its key, with coordinates set - to zero. - - :param residue: must be a valid residue - :type residue: mol.ResidueHandle - - .. method:: CheckResidueCompleteness(residue) - - verify that the given residue has all atoms it is supposed to have based on - its key. - - :param residue: must be a valid residue - :type residue: mol.ResidueHandle - - .. method:: IsResidueComplete(residue) - - Check whether the residue has all atoms it is supposed to have. Hydrogen - atoms are not required for a residue to be complete. - - :param residue: must be a valid residue - :type residue: mol.ResidueHandle - - .. method:: IdentifyResidue(residue) - - attempt to identify the residue based on its atoms, and return a suggestion - for the proper residue key. - - :param residue: must be a valid residue - :type residue: mol.ResidueHandle - - .. method:: ConnectAtomsOfResidue(residue) - - Connects atoms of residue based on residue and atom name. This method does - not establish inter-residue bonds. To connect atoms that belong to - different residues, use :meth:`ConnectResidueToPrev`, or - :meth:`ConnectResidueToNext`. - - :param residue: must be a valid residue - :type residue: mol.ResidueHandle - - .. method:: ConnectResidueToPrev(residue, prev) - - Connect atoms of residue to previous. The order of the parameters is - important. In case of a polypeptide chain, the residues are thought to be - ordered from N- to C- terminus. - - :param residue: must be a valid residue - :type residue: mol.ResidueHandle - :param prev: valid or invalid residue - :type prev: mol.ResidueHandle - - - .. method:: DoesPeptideBondExist(n, c) - - Check if peptide bond should be formed between the `n` and `c` atom. This - method is called by ConnectResidueWithNext() after making sure that - both residues participating in the peptide bond are peptide linking - components. - - By default, :meth:`IsBondFeasible` is used to check whether the two atoms - form a peptide bond. - - :param n: backbone nitrogen atom (IUPAC name `N`). Must be valid. - :type n: mol.AtomHandle - :param c: backbone C-atom (IUPAC name `C`). Must be valid. - :type c: mol.AtomHandle - - .. method:: IsBondFeasible(atom_a, atom_b) - - Overloadable hook to check if bond between to atoms is feasible. The - default implementation uses a distance-based check to check if the - two atoms should be connected. The atoms are connected if they are in - the range of 0.8 to 1.2 times their van-der-WAALS radius. - - :param atom_a: a valid atom - :type atom_b: mol.AtomHandle - :param atom_a: a valid atom - :type atom_b: mol.AtomHandle - - .. method:: GuessAtomElement(atom_name, hetatm) + .. method:: Process(ent) - guess element of atom based on name and hetatm flag - - :param atom_name: IUPAC atom name, e.g. `CA`, `CB` or `N`. - :type atom_name: string - :param hetatm: Whether the atom is a hetatm or not - :type hetatm: bool - - .. method:: AssignBackboneTorsionsToResidue(residue) - - For :meth:`peptide-linking residues <mol.ResidueHandle.IsPeptideLinking>`, - residues, assigns phi, psi and omega torsions to amino acid. - - :param residue: must be a valid residue - :type residue: mol.ResidueHandle - - .. method:: GuessChemClass(residue) - - Guesses the chemical class of the residue based on its atom and - connectivity. - - So far, the method only guesses whether the residue is a peptide. A residue - is a peptide if all the backbone atoms N,CA,C,O are present, have the right - element and are in a suitable orientation to form bonds. + Processess the entity *ent* according to the current options. -The RuleBasedBuilder class +The RuleBasedProcessor class ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. class:: RuleBasedBuilder(compound_lib) +.. class:: RuleBasedProcessor(compound_lib) :param compound_lib: The compound library :type compound_lib: :class:`CompoundLib` - The :class:`RuleBasedBuilder` implements the :class:`Builder` interface. - Refer to its documentation for a basic description of the methods. - - .. method:: CheckResidueCompleteness(residue) - - By using the description of the chemical compound, the completeness of - the residue is verified. The method distinguishes between required atoms - and atoms that are optional, like `OXT` that is only present, if not - peptide bond is formed. Whenever an unknown atom is encountered, - :meth:`OnUnknownAtom` is invoked. Subclasses of the - :class:`RuleBasedBuilder` may implement some additional logic to deal with - unknown atom. Likewise, whenever a required atom is missing, - :meth:`OnMissingAtom` is invoked. Hydrogen atoms are not considered as - required by default. - - :param residue: must be a valid residue - :type residue: mol.ResidueHandle - - .. method:: IdentifyResidue(residue) - - Looks-up the residue in the database of chemical compounds and returns - the name of the residue or "UNK" if the residue has not been found in the - library. - - :param residue: must be a valid residue - :type residue: mol.ResidueHandle - - - .. method:: OnUnknownAtom(atom) - - Invoked whenever an unkknown atom has been encountered during a residue - completeness check. - - The default implementation guesses the atom properties based on the name - and returns false, meaning that it should be treated as an unknown atom. - - Custom implementations of this method may delete the atom, or modify it. - - :param atom: the unknown atom - :type atom: mol.AtomHandle - - .. method:: OnMissingAtom(atom) - - Invoked whenever an atom is missing. It is up to the overloaded method - to deal with the missing atom, either by ignoring it or by inserting a - dummy atom. - - :param atom: The missing atom's name - :type atom: string - - .. method:: GetUnknownAtoms(residue) + The :class:`RuleBasedProcessor` implements the :class:`Processor` interface. + Refer to its documentation for methods and accessors common to all processor. + - Returns the unknown atoms of this residue, that is all atoms that - are not part of the compound lib definition. - - :rtype: list of :class:`~ost.mol.AtomHandle` instances + .. attribute:: strict_hydrogens + + Whether to use strict hydrogen naming rules outlined in the compound library. + Disabled by default. + + :type: :class:`bool` + + .. attribute:: unk_atom_treatment + + Treatment upon encountering an unknown atom. Default: 'warn'. + + + :type: :class:`str` + + .. attribute:: unk_res_treatment + + Treatment upon encountering an unknown residue + + :type: :class:`str` + + .. attribute:: fix_elements -Changing the default builder ---------------------------------------------------------------------------------- + Whether the element of the atom should be changed to the atom defined in the + compound library. Enabled by default. -The default builder can be specified with :func:`SetDefaultBuilder`. Before being -able to set a builder, it needs to be registered with :func:`RegisterBuilder`. -By default, there is always a builder called "HEURISTIC" registered. If, for some -reason your are currently using the :class:`RuleBasedBuilder` and you would like -to switch to that builder, call + :type: :class:`bool` -.. code-block:: python - conop.SetDefaultBuilder("HEURISTIC") diff --git a/modules/conop/doc/conop.dox b/modules/conop/doc/conop.dox index c59b5a5b1a78ec2a90b48bdda556c29dd8042e27..ee071624521fdfb5a308abcf38001fd3fca7226c 100644 --- a/modules/conop/doc/conop.dox +++ b/modules/conop/doc/conop.dox @@ -40,7 +40,7 @@ Builder should treat unknown amino acids, missing atoms and chemically infeasible bonds. So far, two classes implement the Builder interface: A heuristic and a -rule-based builder. The builders mainly differ in the source of their +rule-based processor. The builders mainly differ in the source of their connectivity information. The HeuristicBuilder uses a hard-coded heuristic connectivity table for the 20 standard amino acids as well as nucleotides. For other compounds such as ligands the HeuristicBuilder runs a distance-based @@ -63,7 +63,7 @@ conop.Conopology.Instance().SetDefaultBuilder('rbb') All subsequent calls to io::LoadEntity will make use of the RuleBasedBuilder instead of the heuristic builder. See \ref convert_mmcif "here" for more -information on how to create the neccessary files to use the rule-based builder. +information on how to create the neccessary files to use the rule-based processor. \subsection connecting_atoms Connecting atoms diff --git a/modules/conop/doc/conop.rst b/modules/conop/doc/conop.rst index fb72db2645a92ea70f3db4f686c0f33a35c7e956..43cb41894f8c0ceab2392d04fe387025ac137da5 100644 --- a/modules/conop/doc/conop.rst +++ b/modules/conop/doc/conop.rst @@ -6,9 +6,10 @@ connectivity information of molecules. -The main task of the :mod:`~ost.conop` module is to connect atoms with bonds. -While the bond class is also part of the base module, the conop module deals -with setting up the correct bonds between atoms. + +The main task of the conop module is to interpret the topology and connectivity of +proteins, polynucleotides and small molecules, e.g. after importing a structure +from a PDB file. In addition, it provides an infrastructure for consistency checks. In this module @@ -20,4 +21,5 @@ In this module aminoacid connectivity compoundlib - cleanup \ No newline at end of file + cleanup + functions diff --git a/modules/conop/doc/functions.rst b/modules/conop/doc/functions.rst new file mode 100644 index 0000000000000000000000000000000000000000..ccd999f9b487fff58af3edc431eb29a6a4310d20 --- /dev/null +++ b/modules/conop/doc/functions.rst @@ -0,0 +1,34 @@ +Conop Functions +======================================================================= + + +.. function:: AssignBackboneTorsions(prev, res, next) + AssignBackboneTorsions(chain) + AssignBackboneTorsions(residues) + + Assigns the backbone torsions PHI, PSI and OMEGA. The backbone atoms + are required to be connected for the torsions to be added. In addition, + only residues for which :meth:`mol.ResidueHandle.IsPeptideLinking` returns + true are considered. + + The first signature assigns the torsions to *res*, assuming prev is + the amino acid before, and *next* is the amino acid next to *res*. + Both *next* and *prev* may be invalid residues. + + The second and third signature assign the torsions to all peptidic + residues of the chain/the residue list. The residues in the chain, + the residue list are thought to run from N to C terminus. + + :param prev: The amino acid before *res* + :type prev: :class:`~mol.ResidueHandle` + :type next: :class:`~mol.ResidueHandle` + :param next: The amino acid after *res* + :type res: :class:`~mol.ResidueHandle` + :type res: The central amino acid. Must be a valid handle + +.. function:: GetUnknownAtomsOfResidue(residue, compound, strict_hydrogens=False) + + Returns the list of atoms present in *residue* that are not part of the + atom specifications in compound. + + :param strict_hydrogens: When set to true, hydrogen atoms are checked as well. diff --git a/modules/conop/pymod/CMakeLists.txt b/modules/conop/pymod/CMakeLists.txt index c1bf89d0e29cda36f4b4bcb9b0b357449aaa8ad7..9c09906222fb97e1c935590ec22e81b536c94891 100644 --- a/modules/conop/pymod/CMakeLists.txt +++ b/modules/conop/pymod/CMakeLists.txt @@ -1,9 +1,13 @@ set(OST_CONOP_PYMOD_SOURCES wrap_conop.cc - export_builder.cc + # export_builder.cc export_compound.cc + export_processor.cc + export_heuristic.cc export_amino_acids.cc export_conop.cc + export_diag.cc + export_rule_based.cc export_non_standard.cc export_ring_finder.cc ) diff --git a/modules/conop/pymod/__init__.py b/modules/conop/pymod/__init__.py index a24f5d2ec21b9333c7548cce372739a3c1753e6d..3b7856fe1634cd5d9ec3dfb7e22218618ae2655e 100644 --- a/modules/conop/pymod/__init__.py +++ b/modules/conop/pymod/__init__.py @@ -29,47 +29,16 @@ STANDARD_AMINOACIDS=( 'HIS', 'PHE', ) -def ConnectAll(ent): +def SetDefaultLib(compound_lib): ''' - Uses the current default builder to connect the atoms of the entity, assign - torsions, and fill in missing or correct erroneous information such as the - chemical class of the residues and the atom's element. - - :param ent: A valid entity - :type ent: :class:`~ost.mol.EntityHandle` + Set the default compound library. The compound library is used by various + functions of the framework that requires knowledge of naming and + connectivity of residues. ''' conop_inst=Conopology.Instance() - conop_inst.ConnectAll(conop_inst.GetBuilder("DEFAULT"), ent, 0) - -def GetBuilder(name='DEFAULT'): - ''' - Get registered builder by name - - :param name: The name of the builder - - :returns: The builder or None, if the builder doesn't exist - ''' - return Conopology.Instance().GetBuilder(name) + conop_inst.SetDefaultLib(compound_lib) -def RegisterBuilder(builder, name): - ''' - Register builder to OpenStructure - - :param builder: A instance of :class:`Builder` - - :param name: The name of the builder - ''' +def GetDefaultLib(): conop_inst=Conopology.Instance() - conop_inst.RegisterBuilder(builder, name) - -def SetDefaultBuilder(builder_name): - ''' - Set the builder with the given name as the default. You will have to register - a builder with :func:`RegisterBuilder` before you will be able to set it as - the default. + return conop_inst.GetDefaultLib() - :raises: :exc:`RuntimeError` when trying to set a builder as the default that - has not been registered yet. - ''' - conop_inst=Conopology.Instance() - conop_inst.SetDefaultBuilder(builder_name) diff --git a/modules/conop/pymod/cleanup.py b/modules/conop/pymod/cleanup.py index 9ecf9c7ef12b8bb4fce889a5fb8062aab2364eda..1a51673d778e3e51237a3d576db8e67fca75279f 100644 --- a/modules/conop/pymod/cleanup.py +++ b/modules/conop/pymod/cleanup.py @@ -16,10 +16,9 @@ def Cleanup(entity, strip_water=True, canonicalize=True, remove_ligands=True): :return: a cleaned version of the entity """ #setup - builder = conop.GetBuilder() - if not hasattr(builder, "compound_lib") : - raise RuntimeError( "Cannot cleanup structure, since the default builder doesn't use the compound library") - compound_lib = builder.compound_lib + lib = conop.GetDefaultLib() + if not lib: + raise RuntimeError("Cleanup requires a compound library.") clean_entity = entity.Copy() ed = clean_entity.EditXCS() #remove water residues @@ -27,7 +26,7 @@ def Cleanup(entity, strip_water=True, canonicalize=True, remove_ligands=True): _StripWater(clean_entity, ed) #replace modified residues before removing ligands to avoid removing MSE and others if canonicalize: - _CanonicalizeResidues(clean_entity, ed, compound_lib) + _CanonicalizeResidues(clean_entity, ed, lib) #remove all hetatoms that are not water if remove_ligands: _RemoveLigands(clean_entity, ed) diff --git a/modules/conop/pymod/export_builder.cc b/modules/conop/pymod/export_builder.cc deleted file mode 100644 index 1897983f90b7c4065316633db738732c0ba4b93f..0000000000000000000000000000000000000000 --- a/modules/conop/pymod/export_builder.cc +++ /dev/null @@ -1,65 +0,0 @@ -//------------------------------------------------------------------------------ -// 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 <boost/python.hpp> -using namespace boost::python; -#include <ost/conop/builder.hh> -#include <ost/conop/heuristic_builder.hh> -#include <ost/conop/rule_based_builder.hh> - -using namespace ost::conop; - -void export_Builder() { - - enum_<Dialect>("Dialect") - .value("PDB_DIALECT", PDB_DIALECT) - .value("CHARMM_DIALECT", CHARMM_DIALECT) - .export_values() - ; - //TODO Export virtual calls as Default* (see export_visitor.cc) - class_<Builder>("Builder", no_init) - .add_property("dialect", &Builder::GetDialect, &Builder::SetDialect) - .add_property("strict_hydrogens", &Builder::GetStrictHydrogenMode, - &Builder::SetStrictHydrogenMode) - .add_property("bond_feasibility_check", &Builder::GetBondFeasibilityCheck, - &Builder::SetBondFeasibilityCheck) - .def("GetDialect", &Builder::GetDialect) - .def("SetDialect", &Builder::SetDialect) - .def("CompleteAtoms", &Builder::CompleteAtoms) - .def("CheckResidueCompleteness", &Builder::CheckResidueCompleteness) - .def("IdentifyResidue", &Builder::IdentifyResidue) - .def("ConnectAtomsOfResidue", &Builder::ConnectAtomsOfResidue) - .def("ConnectResidueToNext", &Builder::ConnectResidueToNext) - .def("ConnectResidueToPrev", &Builder::ConnectResidueToPrev) - .def("AssignTorsions", &Builder::AssignTorsions) - .def("AssignTorsionsToResidue", &Builder::AssignTorsionsToResidue) - .def("FillAtomProps", &Builder::FillAtomProps) - .def("IsResidueComplete", &Builder::IsResidueComplete) - .def("SetBondFeasibilityFlag", &Builder::SetBondFeasibilityCheck) - .def("GetBondFeasibilityFlag", &Builder::GetBondFeasibilityCheck) - ; - - class_<HeuristicBuilder, bases<Builder> >("HeuristicBuilder", init<>()) - ; - class_<RuleBasedBuilder, bases<Builder> >("RuleBasedBuilder", - init<const CompoundLibPtr&>()) - .add_property("compound_lib", &RuleBasedBuilder::GetCompoundLib) - .def("GetUnknownAtoms", &RuleBasedBuilder::GetUnknownAtoms) - - ; -} diff --git a/modules/conop/pymod/export_compound.cc b/modules/conop/pymod/export_compound.cc index 6b8196e6768a608745c9c83608a7ddffc6ef50d3..33cbe0536ae7490f14edc9116ef2ea25adf4d430 100644 --- a/modules/conop/pymod/export_compound.cc +++ b/modules/conop/pymod/export_compound.cc @@ -127,7 +127,7 @@ void export_Compound() { class_<BondSpec>("BondSpec", no_init) .def_readonly("atom_one", &BondSpec::atom_one) .def_readonly("atom_two", &BondSpec::atom_two) - .def_readonly("border", &BondSpec::order) + .def_readonly("order", &BondSpec::order) ; diff --git a/modules/conop/pymod/export_conop.cc b/modules/conop/pymod/export_conop.cc index 309ce86b3572987be230a6badeb519a252c073db..39f006b45f96fc41a83403ab9363c7e5568cbd20 100644 --- a/modules/conop/pymod/export_conop.cc +++ b/modules/conop/pymod/export_conop.cc @@ -22,20 +22,15 @@ using namespace boost::python; #include <ost/conop/conop.hh> #include <ost/mol/mol.hh> -#include <ost/conop/builder.hh> using namespace ost::conop; void export_Conop() { class_<Conopology, boost::noncopyable>("Conopology", no_init) .def("Instance", &Conopology::Instance, return_value_policy<reference_existing_object>()).staticmethod("Instance") - .def("ConnectAll", &Conopology::ConnectAll) - .def("GetBuilder", &Conopology::GetBuilder) - .def("ConnectAll", &Conopology::ConnectAll) - .def("RegisterBuilder", &Conopology::RegisterBuilder) - .def("SetDefaultBuilder", &Conopology::SetDefaultBuilder) + .def("SetDefaultLib", &Conopology::SetDefaultLib) + .def("GetDefaultLib", &Conopology::GetDefaultLib) ; - register_ptr_to_python<BuilderP>(); } diff --git a/modules/conop/pymod/export_diag.cc b/modules/conop/pymod/export_diag.cc new file mode 100644 index 0000000000000000000000000000000000000000..6155d63c71854e76517aa7a1732feb30ce352a72 --- /dev/null +++ b/modules/conop/pymod/export_diag.cc @@ -0,0 +1,44 @@ +//------------------------------------------------------------------------------ +// 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 <boost/python.hpp> +#include <ost/conop/diag.hh> +using namespace ost; + +using namespace boost::python; +using namespace ost::conop; + + +void export_diag() { + + enum_<DiagType>("DiagType") + .value("DIAG_UNK_ATOM", DIAG_UNK_ATOM) + .value("DIAG_UNK_RESIDUE", DIAG_UNK_RESIDUE) + .value("(DIAG_MISSING_ATOM", DIAG_MISSING_ATOM) + .value("DIAG_NONSTD_RESIDUE", DIAG_NONSTD_RESIDUE) + .export_values() + ; + + class_<Diag>("Diag", init<DiagType,const char*>()) + .def("__str__(self)__", &Diag::Format) + ; + class_<Diagnostics, DiagnosticsPtr>("Diagnostics") + ; +} + diff --git a/modules/conop/pymod/export_heuristic.cc b/modules/conop/pymod/export_heuristic.cc new file mode 100644 index 0000000000000000000000000000000000000000..f25ca9814bf0e7589d58fa2db35c261acafee8cc --- /dev/null +++ b/modules/conop/pymod/export_heuristic.cc @@ -0,0 +1,40 @@ + +//------------------------------------------------------------------------------ +// 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 <boost/python.hpp> +using namespace boost::python; +#include <ost/conop/heuristic.hh> + +using namespace ost::conop; + +void export_heuristic() { + + class_<HeuristicProcessor, HeuristicProcessorPtr, + boost::noncopyable, bases<Processor> >("HeuristicProcessor", + init<>()) + .def(init<bool,bool,bool,bool,ConopAction>( + (arg("check_bond_feasibility")=false, + arg("assign_torsions")=false, + arg("connect")=true, + arg("peptide_bonds")=true, + arg("zero_occ_treatment")=CONOP_WARN))) + ; +} + diff --git a/modules/conop/pymod/export_processor.cc b/modules/conop/pymod/export_processor.cc new file mode 100644 index 0000000000000000000000000000000000000000..27317133e9eee11d724045b77d31ba5a1296e607 --- /dev/null +++ b/modules/conop/pymod/export_processor.cc @@ -0,0 +1,89 @@ +//------------------------------------------------------------------------------ +// 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 <boost/python.hpp> +#include <ost/conop/processor.hh> +using namespace ost; + +using namespace ost::conop; +using namespace boost::python; + +struct PyProcessor : public Processor {}; +struct WrappedProcessor : public PyProcessor, public wrapper<WrappedProcessor> { + WrappedProcessor(PyObject* self): self_(self) + { } + virtual void DoProcess(DiagnosticsPtr diag, mol::EntityHandle ent) const + { + call_method<void>(self_, "DoProcess", diag, ent); + } + DiagnosticsPtr DoProcessDefault(DiagnosticsPtr diag, + mol::EntityHandle ent) const { + return DiagnosticsPtr(); + } + ProcessorPtr Copy() const { + return call_method<ProcessorPtr>(self_, "Copy"); + } + virtual String ToString() const { + return call_method<String>(self_, "ToString"); + } + String ToStringDefault() const { return ""; } + ProcessorPtr CopyDefault() const { return ProcessorPtr(); } + + PyObject* self_; +}; + + +void export_processor() { + + enum_<Dialect>("Dialect") + .value("PDB_DIALECT", PDB_DIALECT) + .value("CHARMM_DIALECT", CHARMM_DIALECT) + .export_values() + ; + enum_<ConopAction>("ConopAction") + .value("CONOP_WARN", CONOP_WARN) + .value("CONOP_SILENT", CONOP_SILENT) + .value("CONOP_REMOVE", CONOP_REMOVE) + .value("CONOP_REMOVE_ATOM", CONOP_REMOVE_ATOM) + .value("CONOP_REMOVE_RESIDUE", CONOP_REMOVE_RESIDUE) + .value("CONOP_FATAL", CONOP_FATAL) + .export_values() + ; + class_<Processor, ProcessorPtr, boost::noncopyable>("_Processor", no_init) + .def("Copy", &Processor::Copy) + .add_property("check_bond_feasibility", + &Processor::GetCheckBondFeasibility, + &Processor::SetCheckBondFeasibility) + .add_property("connect", &Processor::GetConnect, + &Processor::SetConnect) + .add_property("assign_torsions", &Processor::GetAssignTorsions, + &Processor::SetAssignTorsions) + .def("Process", &Processor::Process, + (arg("ent"), arg("log_diags")=true)) + ; + class_<PyProcessor, boost::noncopyable, + boost::shared_ptr<WrappedProcessor>, + bases<Processor> >("Processor") + .def("Copy", &WrappedProcessor::CopyDefault) + .def("DoProcess", &WrappedProcessor::DoProcessDefault) + .def("ToString", &WrappedProcessor::ToStringDefault) + ; + def("IsBondFeasible", &IsBondFeasible); +} + diff --git a/modules/conop/pymod/export_rule_based.cc b/modules/conop/pymod/export_rule_based.cc new file mode 100644 index 0000000000000000000000000000000000000000..6fef009a0bd22913a8c850246e71176ff529a295 --- /dev/null +++ b/modules/conop/pymod/export_rule_based.cc @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +// 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 <boost/python.hpp> +using namespace boost::python; +#include <ost/conop/rule_based.hh> + +using namespace ost::conop; + +void export_rule_based() { + + class_<RuleBasedProcessor, RuleBasedProcessorPtr, + boost::noncopyable, bases<Processor> >("RuleBasedProcessor", + init<CompoundLibPtr>()) + .def(init<CompoundLibPtr,bool,bool,ConopAction,ConopAction,bool,bool,bool,bool,ConopAction>( + (arg("lib"), arg("fix_elements")=true, arg("strict_hydrogens")=false, + arg("unknown_res_treatment")=CONOP_WARN, + arg("unknown_atom_treatment")=CONOP_WARN, + arg("check_bond_feasibility")=false, + arg("assign_torsions")=false, + arg("connect")=true, + arg("peptide_bonds")=true, + arg("zero_occ_treatment")=CONOP_WARN))) + .add_property("fix_element", &RuleBasedProcessor::GetFixElement, + &RuleBasedProcessor::SetFixElement) + .add_property("unk_res_treatment", &RuleBasedProcessor::GetUnkResidueTreatment, + &RuleBasedProcessor::SetUnkResidueTreatment) + .add_property("unk_atom_treatment", &RuleBasedProcessor::GetUnkAtomTreatment, + &RuleBasedProcessor::SetUnkAtomTreatment) + .add_property("strict_hydrogens", &RuleBasedProcessor::GetStrictHydrogens, + &RuleBasedProcessor::SetStrictHydrogens) + ; +} + diff --git a/modules/conop/pymod/wrap_conop.cc b/modules/conop/pymod/wrap_conop.cc index 6573bf41a7e6c8fcb471cbf25a79be77b1b03dfa..119c86c325f3ce6fc48cf88298838f441cb04a36 100644 --- a/modules/conop/pymod/wrap_conop.cc +++ b/modules/conop/pymod/wrap_conop.cc @@ -19,20 +19,28 @@ #include <boost/python.hpp> using namespace boost::python; -void export_Builder(); +//void export_Builder(); void export_Compound(); void export_Sanitizer(); void export_Conop(); void export_RingFinder(); void export_AminoAcids(); void export_NonStandard(); +void export_processor(); +void export_rule_based(); +void export_heuristic(); +void export_diag(); BOOST_PYTHON_MODULE(_ost_conop) { - export_Builder(); + // export_Builder(); export_Conop(); + export_processor(); + export_rule_based(); + export_heuristic(); export_Compound(); export_RingFinder(); export_AminoAcids(); export_NonStandard(); + export_diag(); } diff --git a/modules/conop/src/CMakeLists.txt b/modules/conop/src/CMakeLists.txt index 1ae86c86f85c83aad9559a5811b6e99072309510..3709e846aa244c06bc2fbca34e8e848fe95d8d22 100644 --- a/modules/conop/src/CMakeLists.txt +++ b/modules/conop/src/CMakeLists.txt @@ -1,30 +1,33 @@ set(OST_CONOP_HEADERS -builder.hh -builder_fw.hh conop.hh -heuristic_builder.hh +processor.hh amino_acids.hh diag.hh model_check.hh +heuristic.hh compound.hh compound_lib.hh module_config.hh +rule_based.hh nonstandard.hh -rule_based_builder.hh +minimal_compound_lib.hh +compound_lib_base.hh ring_finder.hh ) set(OST_CONOP_SOURCES -builder.cc +processor.cc amino_acids.cc conop.cc +minimal_compound_lib.cc +compound_lib_base.cc +heuristic.cc diag.cc +rule_based.cc model_check.cc -heuristic_builder.cc compound.cc compound_lib.cc nonstandard.cc -rule_based_builder.cc ring_finder.cc ) diff --git a/modules/conop/src/builder.cc b/modules/conop/src/builder.cc deleted file mode 100644 index 0a24cf56fa398f19fb61e6a37d181e2fbd5ebb95..0000000000000000000000000000000000000000 --- a/modules/conop/src/builder.cc +++ /dev/null @@ -1,246 +0,0 @@ -//------------------------------------------------------------------------------ -// 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 "builder.hh" - -/* - Author: Marco Biasini - */ - -namespace ost { namespace conop { - -Builder::~Builder() {} - -void Builder::CompleteAtoms(mol::ResidueHandle rh) {} - -void Builder::CheckResidueCompleteness(const mol::ResidueHandle& rh) {} - -mol::ResidueKey Builder::IdentifyResidue(const mol::ResidueHandle& rh) { - return mol::ResidueKey(); -} -void Builder::FillResidueProps(mol::ResidueHandle residue){}; -void Builder::ConnectAtomsOfResidue(mol::ResidueHandle rh) {} - -void Builder::ConnectResidueToPrev(mol::ResidueHandle rh, - mol::ResidueHandle p) { - this->ConnectResidueToNext(p, rh); -} - -bool Builder::IsResidueComplete(const mol::ResidueHandle& rh) -{ - return true; -} - -void Builder::ConnectResidueToNext(mol::ResidueHandle rh, - mol::ResidueHandle n) {} - -void Builder::AssignTorsions(mol::ChainHandle ch) {} -void Builder::AssignTorsionsToResidue(mol::ResidueHandle rh) {} - -void Builder::FillAtomProps(mol::AtomHandle atom) {} - -bool Builder::DoesPeptideBondExist(const mol::AtomHandle& n, - const mol::AtomHandle& c) -{ - return this->IsBondFeasible(n, c); -} - -bool Builder::IsBondFeasible(const mol::AtomHandle& atom_a, - const mol::AtomHandle& atom_b) -{ - Real radii=0.0; - if (atom_a.GetRadius()>0.0) { - radii=atom_a.GetRadius(); - } else { - return false; - } - if (atom_b.GetRadius()>0.0) { - radii+=atom_b.GetRadius(); - } else { - return false; - } - Real len=geom::Length2(atom_a.GetPos()-atom_b.GetPos()); - Real lower_bound=radii*radii*0.0625; - Real upper_bound=lower_bound*6.0; - return (len<=upper_bound && len>=lower_bound); -} - -String Builder::GuessAtomElement(const String& aname, bool hetatm) -{ - static String l1[] = { - "H","C","N","O","P","S","K" - }; - static int l1c=7; - static String l2[] = { - "NA","MG","AL","SI","CL", - "CA","CR","MN","FE","CO","NI","CU","ZN","AS","SE","BR","MO" - }; - static int l2c=17; - static String l3[] = { - "B","F","V" - }; - static int l3c=3; - static String l4[] = { - "HE","LI","BE","AR","SC","TI","GA","GE","KR" - }; - static int l4c=9; - - String ele=aname.substr(0,2); - // hydrogen hack - if(ele[0]=='H') { - return "H"; - } - if (hetatm==false) { - if (ele=="CA" || ele=="CB") { - return "C"; - } - } - - // two characters - if(aname.size()==2) { - for(int i=0;i<l2c;i++) { - if(ele==l2[i]) return ele; - } - // check second character for match - for(int i=0;i<l1c;i++) { - if(ele[1]==l1[i][0]) { - return l1[i]; - } - } - // still no match, repeat with less likely tables - for(int i=0;i<l4c;i++) { - if(ele==l4[i]) return ele; - } - // check second character for match - for(int i=0;i<l3c;i++) { - if(ele[1]==l3[i][0]) { - return l3[i]; - } - } - // check second character for match - for(int i=0;i<l1c;i++) { - if(ele[0]==l1[i][0]) { - return l1[i]; - } - } - } else { - for(int i=0;i<l1c;i++) { - if(ele==l1[i]) return ele; - } - for(int i=0;i<l3c;i++) { - if(ele==l3[i]) return ele; - } - } - size_t i=0; - while (i<aname.size() && isdigit(aname[i])) { - ++i; - } - return i<aname.size() ? String(1, aname[i]) : ""; -} - -bool Builder::AreResiduesConsecutive(const mol::ResidueHandle& r1, - const mol::ResidueHandle& r2) -{ - if (!r1 || !r2) return false; // protect against invalid handles - if(r1.GetChain() != r2.GetChain()) return false; - return r2.GetNumber().GetNum()==r1.GetNumber().GetNum()+1 || - r2.GetNumber().GetInsCode()==r1.GetNumber().NextInsertionCode().GetInsCode(); -} - -void Builder::GuessChemClass(mol::ResidueHandle res) -{ - // try peptide - res.SetChemClass(mol::ChemClass()); - mol::AtomHandle ca=res.FindAtom("CA"); - if (!ca.IsValid() || ca.GetElement()!="C") return; - mol::AtomHandle n=res.FindAtom("N"); - if (!n.IsValid() || n.GetElement()!="N") return; - mol::AtomHandle c=res.FindAtom("C"); - if (!c.IsValid() || c.GetElement()!="C") return; - mol::AtomHandle o=res.FindAtom("O"); - if (!o.IsValid() || o.GetElement()!="O") return; - if (this->IsBondFeasible(n, ca) && this->IsBondFeasible(ca, c) && - this->IsBondFeasible(c, o)) { - res.SetChemClass(mol::ChemClass(mol::ChemClass::PEPTIDE_LINKING)); - } -} - - -void Builder::AssignBackBoneTorsionsToResidue(mol::ResidueHandle res) -{ - - mol::ResidueHandle prev=res.GetPrev(); - mol::ResidueHandle next=res.GetNext(); - mol::XCSEditor e=res.GetEntity().EditXCS(mol::BUFFERED_EDIT); - //psi - if (next.IsValid() && next.IsPeptideLinking()){ - mol::AtomHandle ca_this=res.FindAtom("CA"); - mol::AtomHandle n_this=res.FindAtom("N"); - mol::AtomHandle c_this=res.FindAtom("C"); - mol::AtomHandle n_next=next.FindAtom("N"); - if ((ca_this && n_this && c_this && n_next && BondExists(c_this, n_next)) - && !res.GetPsiTorsion()) { - e.AddTorsion("PSI", n_this, ca_this, c_this, n_next); - } - }; - //phi - if (prev.IsValid() && prev.IsPeptideLinking()) { - mol::AtomHandle c_prev=prev.FindAtom("C"); - mol::AtomHandle n_this=res.FindAtom("N"); - mol::AtomHandle ca_this=res.FindAtom("CA"); - mol::AtomHandle c_this=res.FindAtom("C"); - if ((c_prev && n_this && ca_this && c_this && BondExists(c_prev, n_this)) - && !res.GetPhiTorsion()) { - e.AddTorsion("PHI", c_prev, n_this, ca_this, c_this); - } - } - //omega - if (prev.IsValid() && prev.IsPeptideLinking()) { - mol::AtomHandle ca_prev=prev.FindAtom("CA"); - mol::AtomHandle c_prev=prev.FindAtom("C"); - mol::AtomHandle n=res.FindAtom("N"); - mol::AtomHandle ca=res.FindAtom("CA"); - if ((ca_prev && c_prev && n && ca && BondExists(c_prev, n)) - && !res.GetOmegaTorsion()) { - e.AddTorsion("OMEGA",ca_prev , c_prev, n, ca); - } - } -} - - - -void Builder::DistanceBasedConnect(mol::AtomHandle atom) -{ - mol::EntityHandle ent=atom.GetEntity(); - mol::XCSEditor editor=ent.EditXCS(mol::BUFFERED_EDIT); - mol::AtomHandleList alist = ent.FindWithin(atom.GetPos(),4.0); - mol::ResidueHandle res_a=atom.GetResidue(); - for (mol::AtomHandleList::const_iterator it=alist.begin(), - e=alist.end();it!=e;++it) { - if (*it!=atom) { - if (this->IsBondFeasible(atom, *it)) { - if (Builder::AreResiduesConsecutive(res_a, it->GetResidue()) || - it->GetResidue()==res_a) { - editor.Connect(*it, atom); - } - } - } - } -} - -}} // ns diff --git a/modules/conop/src/builder.hh b/modules/conop/src/builder.hh deleted file mode 100644 index 5cf1f63026a95df93569be1698455451997bbd92..0000000000000000000000000000000000000000 --- a/modules/conop/src/builder.hh +++ /dev/null @@ -1,162 +0,0 @@ -//------------------------------------------------------------------------------ -// 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_CONOP_BUILDER_HH -#define OST_CONOP_BUILDER_HH - -/* - Author: Marco Biasini - */ -#include <ost/mol/mol.hh> - -#include <ost/conop/module_config.hh> -#include <ost/conop/builder_fw.hh> - -namespace ost { namespace conop { - -typedef enum { - PDB_DIALECT, - CHARMM_DIALECT -} Dialect; -/// \brief abstract builder interface -/// -/// A builder serves several purposes: \li knows how to connect atoms of -/// residues based on their name \li is able to identify as residue based on -/// its name \li knows whether a residue has all required atoms \li assigns -/// named torsions to residues \li knows when to connect two consecutive -/// residues. -/// -/// The exact behaviour for a builder is implementation-specific. While some -/// builders implement sophisticated checks to identity residues, other builders -/// may only perform a name lookup. For two specific implementations of -/// builders, HeuristicBuilder and RuleBasedBuilder. -/// -/// Custom builders can be registered with Conopology::RegisterBuilder(). The -/// default builder is set with Conopology::SetDefaultBuilder(). Since all -/// entity loaders make use of the default builder to infer connectivity of the -/// atoms, changing the default builder can largely affect the loading -/// behaviour. -class DLLEXPORT_OST_CONOP Builder { -public: - - Builder(): dialect_(PDB_DIALECT), strict_(false), bond_feasibility_check_(false) { } - virtual ~Builder(); - - /// \brief add any missing atoms to the residue based on its key, - /// with coordinates set to zero - virtual void CompleteAtoms(mol::ResidueHandle rh); - - virtual void SetDialect(Dialect dialect) { dialect_=dialect; } - - virtual void SetStrictHydrogenMode(bool strict) { strict_=strict; } - bool GetStrictHydrogenMode() const { return strict_; } - - Dialect GetDialect() const { return dialect_; } - /// \brief verify that the given residue has all atoms it - /// is supposed to have based on its key - virtual void CheckResidueCompleteness(const mol::ResidueHandle& rh); - - /// \brief Check whether the residue has all atoms it is supposed to have - /// \todo Add hydrogen flag - virtual bool IsResidueComplete(const mol::ResidueHandle& rh); - - /// \brief attempt to identify the residue based on its atoms, and return a - /// suggestion for the proper residue key - virtual mol::ResidueKey IdentifyResidue(const mol::ResidueHandle& rh); - - /// \brief Assign (correct) residue properties - /// - /// Assign chemical class of the residue and one letter code. - virtual void FillResidueProps(mol::ResidueHandle residue); - - virtual void FillAtomProps(mol::AtomHandle atom); - /// \brief connect atoms of one residue - /// - /// Connects atoms of residue based on residue and atom name. This method does - /// not establish inter-residue bonds. To connect atoms that belong to - /// different residues, use ConnectResidueToPrev(), or ConnectResidueToNext(). - virtual void ConnectAtomsOfResidue(mol::ResidueHandle rh); - /// \brief connect atoms of residue to previous - /// - /// The order of the parameters is important. In case of a polypeptide chain, - /// the residues are thought to be ordered from N- to C- terminus. - /// - /// \sa ConnectResidueToNext - virtual void ConnectResidueToPrev(mol::ResidueHandle rh, - mol::ResidueHandle prev); - /// \sa ConnectResidueToPrev - virtual void ConnectResidueToNext(mol::ResidueHandle rh, - mol::ResidueHandle next); - - /// \brief assign named torsions to a complete chain - virtual void AssignTorsions(mol::ChainHandle ch); - - /// \brief assign named torsions to single residue - virtual void AssignTorsionsToResidue(mol::ResidueHandle residue); - - /// \brief assign Backbone torsions to single residue - void AssignBackBoneTorsionsToResidue(mol::ResidueHandle res); - - /// \brief Check if peptide bond is formed between the two atoms. - /// - /// This method is called by ConnectResidueWithNext() after making sure that - /// both residues participating in the peptide bond are peptide linking - /// components. - /// - /// By default, IsBondFeasible() is used to check whether the two atoms form - /// a peptide bond. - virtual bool DoesPeptideBondExist(const mol::AtomHandle& n, - const mol::AtomHandle& c); - - /// \brief Overloadable hook to check if bond between to atoms is feasible - /// - /// The default implementation uses a distance-based check to check if the - /// two atoms should be connected. The atoms are connected if they are in - /// the range of 0.8 to 1.2 times their van-der-WAALS radius. - virtual bool IsBondFeasible(const mol::AtomHandle& atom_a, - const mol::AtomHandle& atom_b); - - /// \brief guess element of atom based on name and hetatm flag - static String GuessAtomElement(const String& atom_name, bool hetatm); - - /// \brief whether the r1 and r2 have consecutive residue numbers - static bool AreResiduesConsecutive(const mol::ResidueHandle& r1, - const mol::ResidueHandle& r2); - /// \brief guess and assign chemical class of residue based on atoms and - /// connectivity - void GuessChemClass(mol::ResidueHandle res); - /// |brief Connect \p atom with all atoms for whith IsBondFeasible() and - /// AreResiduesConsecutive() returns true - void DistanceBasedConnect(mol::AtomHandle atom); - - /// \brief Set bond feasibility check flag - void SetBondFeasibilityCheck(bool b_feas_flag) { bond_feasibility_check_ = b_feas_flag; } - - /// \brief Get bond feasibility check flag - bool GetBondFeasibilityCheck() const { return bond_feasibility_check_; } - -private: - Dialect dialect_; - bool strict_; - bool bond_feasibility_check_; -}; - - -}} // ns - -#endif diff --git a/modules/conop/src/compound.hh b/modules/conop/src/compound.hh index 7e8c424571967ea5a7b0e339323561488b598d1e..c62c1aa801323cd669eca94e4f6ee0a8c3974135 100644 --- a/modules/conop/src/compound.hh +++ b/modules/conop/src/compound.hh @@ -20,6 +20,7 @@ #define OST_CONOP_COMPOUND_HH #include <vector> +#include <map> #include <boost/shared_ptr.hpp> #include <ost/string_ref.hh> #include <ost/conop/module_config.hh> @@ -72,6 +73,9 @@ struct DLLEXPORT_OST_CONOP AtomSpec { AtomSpec() : ordinal(0), is_leaving(false) { } + AtomSpec(int o, const String& n, const String& a, const String& e, + bool l, bool r): ordinal(o), name(n), alt_name(a), element(e), + is_leaving(l), is_aromatic(r) {} int ordinal; String name; String alt_name; @@ -93,7 +97,7 @@ struct DLLEXPORT_OST_CONOP BondSpec { : atom_one(0), atom_two(0), order(1) { } - + BondSpec(int a, int b, int o): atom_one(a), atom_two(b), order(o) {} bool operator==(const BondSpec& rhs) const { return atom_one==rhs.atom_one && atom_two==rhs.atom_two; } @@ -247,6 +251,8 @@ private: Date mod_date_; }; +typedef std::map<String, CompoundPtr> CompoundMap; + }} #endif diff --git a/modules/conop/src/compound_lib.cc b/modules/conop/src/compound_lib.cc index bc73c9d13811cfac427ddcb64f50293d8c150fc0..90e5df87c00ecc2aa8714bcb6df499ad878d4c09 100644 --- a/modules/conop/src/compound_lib.cc +++ b/modules/conop/src/compound_lib.cc @@ -362,7 +362,7 @@ CompoundLibPtr CompoundLib::Load(const String& database, bool readonly) return lib; } -void CompoundLib::LoadAtomsFromDB(CompoundPtr comp, int pk) { +void CompoundLib::LoadAtomsFromDB(CompoundPtr comp, int pk) const { String aq=str(format("SELECT name, alt_name, element, ordinal, is_leaving " "FROM atoms WHERE compound_id=%d " "ORDER BY ordinal ASC") % pk); @@ -391,7 +391,7 @@ void CompoundLib::ClearCache() compound_cache_.clear(); } -void CompoundLib::LoadBondsFromDB(CompoundPtr comp, int pk) { +void CompoundLib::LoadBondsFromDB(CompoundPtr comp, int pk) const { sqlite3_stmt* stmt; String aq=str(format("SELECT a1.ordinal, a2.ordinal, b.bond_order FROM bonds AS b " "LEFT JOIN atoms AS a1 ON b.atom_one=a1.id " @@ -416,8 +416,8 @@ void CompoundLib::LoadBondsFromDB(CompoundPtr comp, int pk) { } CompoundPtr CompoundLib::FindCompound(const String& id, - Compound::Dialect dialect) { - CompoundMap::iterator i=compound_cache_.find(id); + Compound::Dialect dialect) const { + CompoundMap::const_iterator i=compound_cache_.find(id); if (i!=compound_cache_.end()) { return i->second; } diff --git a/modules/conop/src/compound_lib.hh b/modules/conop/src/compound_lib.hh index c79463a6f28857e813c7c0e57050d4459a7714f9..fef48b1a766899cff3e4097fe68e70a0031291b8 100644 --- a/modules/conop/src/compound_lib.hh +++ b/modules/conop/src/compound_lib.hh @@ -25,41 +25,42 @@ // our own local copy of sqlite3 #include <ost/db/sqlite3.h> -#include <ost/conop/module_config.hh> -#include <ost/conop/compound.hh> +#include "module_config.hh" +#include "compound.hh" +#include "compound_lib_base.hh" namespace ost { namespace conop { class CompoundLib; typedef boost::shared_ptr<CompoundLib> CompoundLibPtr; -typedef std::map<String, CompoundPtr> CompoundMap; -class DLLEXPORT_OST_CONOP CompoundLib { +class DLLEXPORT_OST_CONOP CompoundLib : public CompoundLibBase { public: static CompoundLibPtr Load(const String& database, bool readonly=true); static CompoundLibPtr Create(const String& database); ~CompoundLib(); - CompoundPtr FindCompound(const String& id, Compound::Dialect dialect); - Date GetCreationDate(void); - String GetOSTVersionUsed(void); + virtual CompoundPtr FindCompound(const String& id, + Compound::Dialect dialect) const; void AddCompound(const CompoundPtr& compound); CompoundLibPtr Copy(const String& filename) const; void ClearCache(); + Date GetCreationDate(void); + String GetOSTVersionUsed(void); void SetChemLibInfo(void); private: CompoundLib(); - void LoadAtomsFromDB(CompoundPtr comp, int pk); - void LoadBondsFromDB(CompoundPtr comp, int pk); + void LoadAtomsFromDB(CompoundPtr comp, int pk) const; + void LoadBondsFromDB(CompoundPtr comp, int pk) const; private: - CompoundMap compound_cache_; - sqlite3* conn_; - bool chem_type_available_; // weather pdbx_type is available in db - bool name_available_; // weather name is available in db - Date creation_date_; - String ost_version_used_; + mutable CompoundMap compound_cache_; + sqlite3* conn_; + bool chem_type_available_; // weather pdbx_type is available in db + bool name_available_; // weather name is available in db + Date creation_date_; + String ost_version_used_; }; }} diff --git a/modules/conop/src/compound_lib_base.cc b/modules/conop/src/compound_lib_base.cc new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/modules/conop/src/compound_lib_base.hh b/modules/conop/src/compound_lib_base.hh new file mode 100644 index 0000000000000000000000000000000000000000..350307eb52eb441aff4c4bac875a4344bbf5a319 --- /dev/null +++ b/modules/conop/src/compound_lib_base.hh @@ -0,0 +1,20 @@ +#ifndef OST_CONOP_COMPOUND_LIB_BASE_HH +#define OST_CONOP_COMPOUND_LIB_BASE_HH + +#include "compound.hh" + +namespace ost { namespace conop { + +class CompoundLibBase; +typedef boost::shared_ptr<CompoundLibBase> CompoundLibBasePtr; + +class DLLEXPORT_OST_CONOP CompoundLibBase { +public: + virtual ~CompoundLibBase() {} + virtual CompoundPtr FindCompound(const String& id, + Compound::Dialect dialect) const = 0; +}; + +}} +#endif + diff --git a/modules/conop/src/conop.cc b/modules/conop/src/conop.cc index e48b3444e16c4ac7bf1ba5ef70ea28ff8341f93a..58fc349b6df596e1bfc3de56396169ce2649eeef 100644 --- a/modules/conop/src/conop.cc +++ b/modules/conop/src/conop.cc @@ -21,7 +21,6 @@ #include <ost/log.hh> #include "conop.hh" -#include "heuristic_builder.hh" #include <ost/profile.hh> namespace ost { namespace conop { @@ -33,11 +32,8 @@ Conopology& Conopology::Instance() return impl; } -Conopology::Conopology(): - builder_map_() +Conopology::Conopology() { - builder_map_["HEURISTIC"]=BuilderP(new HeuristicBuilder()); - builder_map_["DEFAULT"]=builder_map_["HEURISTIC"]; known_elements_.insert("AC"); known_elements_.insert("AG"); @@ -152,146 +148,6 @@ Conopology::Conopology(): known_elements_.insert("ZR"); } -void Conopology::RegisterBuilder(const BuilderP& b, const String& name) { - if (!GetBuilder(name)) - builder_map_[name]=b; -} - -void Conopology::SetDefaultBuilder(const String& default_name) { - BuilderP builder=GetBuilder(default_name); - if (builder) - builder_map_["DEFAULT"]=builder; - else - throw ost::Error("trying to set unknown builder '"+ - default_name+"' as the default"); -} - -BuilderP Conopology::GetBuilder(const String& name) -{ - BuilderMap::iterator it=builder_map_.find(name); - if (it!=builder_map_.end()){ - return (*it).second; - } - return BuilderP(); -} - -namespace { - -class PropAssigner: public mol::EntityVisitor { -public: - PropAssigner(const BuilderP& builder): builder_(builder) {} - - virtual bool VisitResidue(const mol::ResidueHandle& res) - { - String key=builder_->IdentifyResidue(res); - if (key=="UNK" && res.GetKey()!="UNK" && res.GetKey()!="UNL") { - unk_res_[res.GetKey()]+=1; - } - builder_->FillResidueProps(res); - return true; - } - - virtual bool VisitAtom(const mol::AtomHandle& atom) - { - builder_->FillAtomProps(atom); - return false; - } - - virtual void OnExit() - { - for (std::map<String, int>::iterator i=unk_res_.begin(), - e=unk_res_.end(); i!=e; ++i) { - if (i->second>1) { - LOG_WARNING("structure contains unknown residues with name " << i->first - << " ("<< i->second << "x)"); - } else { - LOG_WARNING("structure contains unknown residue with name " << i->first); - } - - } - } -private: - BuilderP builder_; - std::map<String, int> unk_res_; -}; - -class ChemClassAssigner : public mol::EntityVisitor { -public: - ChemClassAssigner(BuilderP b): builder(b) { } - virtual bool VisitResidue(const mol::ResidueHandle& res) - { - if (res.GetChemClass()==mol::ChemClass()) { - builder->GuessChemClass(res); - } - return false; - } -private: - BuilderP builder; -}; -class Connector: public mol::EntityVisitor -{ -public: - Connector(const BuilderP& b, bool peptide_bonds): - builder_(b), - prev_(), - peptide_bonds_(peptide_bonds) - {} - - virtual bool VisitChain(const mol::ChainHandle& chain) { - prev_=mol::ResidueHandle(); // reset prev - return true; - } - - virtual bool VisitResidue(const mol::ResidueHandle& res) { - builder_->ConnectAtomsOfResidue(res); - if (peptide_bonds_ && prev_) { - builder_->ConnectResidueToPrev(res,prev_); - } - prev_=res; - return false; - } - -private: - BuilderP builder_; - mol::ResidueHandle prev_; - bool peptide_bonds_; -}; - -class TorsionMaker: public mol::EntityVisitor -{ -public: - TorsionMaker(const BuilderP& b): - builder_(b) - {} - - virtual bool VisitChain(const mol::ChainHandle& chain) { - builder_->AssignTorsions(chain); - return false; - } - -private: - BuilderP builder_; -}; -} // ns - -void Conopology::ConnectAll(const BuilderP& b, mol::EntityHandle eh, int flags) -{ - Profile profile_connect("ConnectAll"); - LOG_DEBUG("Conopology: ConnectAll: building internal coordinate system"); - mol::XCSEditor xcs_e=eh.EditXCS(mol::BUFFERED_EDIT); - PropAssigner a(b); - eh.Apply(a); - ChemClassAssigner cca(b); - eh.Apply(cca); - LOG_DEBUG("Conopology: ConnectAll: connecting all bonds"); - Connector connector(b, !(flags & NO_PEPTIDE_BONDS)); - eh.Apply(connector); - - LOG_DEBUG("Conopology: ConnectAll: assigning all torsions"); - TorsionMaker tmaker(b); - eh.Apply(tmaker); -} - bool Conopology::IsValidElement(const String& ele) const { String upper_ele=ele; diff --git a/modules/conop/src/conop.hh b/modules/conop/src/conop.hh index 1234a30fd0ae024a69eeeb0d2a4fa9227bdcb73a..34f58e080f97384df0bfc9ca7db6ee2ab3f6220c 100644 --- a/modules/conop/src/conop.hh +++ b/modules/conop/src/conop.hh @@ -22,8 +22,8 @@ #include <map> #include <ost/conop/module_config.hh> #include <ost/mol/entity_handle.hh> -#include "builder_fw.hh" - +#include "processor.hh" +#include "compound_lib.hh" namespace ost { namespace conop { @@ -33,35 +33,23 @@ typedef enum { class DLLEXPORT_OST_CONOP Conopology { - typedef std::map<String,BuilderP> BuilderMap; - public: // singleton static Conopology& Instance(); - // retrieve a builder by name - BuilderP GetBuilder(const String& name="DEFAULT"); - - /* - convenience function, connect all atoms with given coordinates, - such as after coordinate file import, based on a given builder + // returns the default compound library (if any) + CompoundLibPtr GetDefaultLib() const { return lib_; } + void SetDefaultLib(const CompoundLibPtr& lib) { lib_ = lib; } - does this need to live within Conopology ? - */ - void ConnectAll(const BuilderP& b, mol::EntityHandle eh, - int flags=0); - - void RegisterBuilder(const BuilderP& b, const String& name); - void SetDefaultBuilder(const String& default_name); - bool IsValidElement(const String& element) const; + private: Conopology(); Conopology(const Conopology&) {} Conopology& operator=(const Conopology&) {return *this;} - BuilderMap builder_map_; std::set<String> known_elements_; + CompoundLibPtr lib_; }; }} // diff --git a/modules/conop/src/diag.cc b/modules/conop/src/diag.cc index 75245fc93aa9414b0a8e1229a3b106957dd8ec30..470673bf73f3c6bcb7acc0836839c25c7d740336 100644 --- a/modules/conop/src/diag.cc +++ b/modules/conop/src/diag.cc @@ -29,7 +29,7 @@ String Diag::Format(bool colored) const switch (i->type) { case DIAG_ARG_TYPE_ATOM: if (colored) { - strings.push_back("\033[0;30m"+ + strings.push_back("\033[0;32m"+ atoms_[i->index].GetQualifiedName()+"\033[0m"); } else { strings.push_back(atoms_[i->index].GetQualifiedName()); @@ -37,7 +37,7 @@ String Diag::Format(bool colored) const break; case DIAG_ARG_TYPE_RESIDUE: if (colored) { - strings.push_back("\033[0;30m"+ + strings.push_back("\033[0;32m"+ residues_[i->index].GetQualifiedName()+"\033[0m"); } else { strings.push_back(residues_[i->index].GetQualifiedName()); @@ -45,7 +45,7 @@ String Diag::Format(bool colored) const break; case DIAG_ARG_TYPE_CHAIN: if (colored) { - strings.push_back("\033[0;30m"+ + strings.push_back("\033[0;32m"+ chains_[i->index].GetName()+"\033[0m"); } else { strings.push_back(chains_[i->index].GetName()); diff --git a/modules/conop/src/diag.hh b/modules/conop/src/diag.hh index 58f4765543c389b27c5925c9df7068bc2708e9dd..ba7297dd63766ede1e5dd067852b99b61fd14cae 100644 --- a/modules/conop/src/diag.hh +++ b/modules/conop/src/diag.hh @@ -1,4 +1,4 @@ -#//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // This file is part of the OpenStructure project <www.openstructure.org> // // Copyright (C) 2008-2011 by the OpenStructure authors @@ -18,6 +18,7 @@ //------------------------------------------------------------------------------ #ifndef OST_CONOP_DIAG_HH #define OST_CONOP_DIAG_HH + #include <ost/mol/atom_handle.hh> #include <ost/mol/residue_handle.hh> #include <ost/mol/chain_handle.hh> @@ -26,11 +27,11 @@ namespace ost { namespace conop { typedef enum { - DIAG_ARG_TYPE_ATOM, - DIAG_ARG_TYPE_RESIDUE, - DIAG_ARG_TYPE_CHAIN, - DIAG_ARG_TYPE_STRING, - DIAG_ARG_TYPE_INT + DIAG_ARG_TYPE_ATOM, + DIAG_ARG_TYPE_RESIDUE, + DIAG_ARG_TYPE_CHAIN, + DIAG_ARG_TYPE_STRING, + DIAG_ARG_TYPE_INT } DiagArgType; typedef enum { @@ -42,39 +43,39 @@ typedef enum { class DLLEXPORT_OST_CONOP Diag { public: - Diag(DiagType typ, const char* fmt): type_(typ), format_(fmt) {} + Diag(DiagType typ, const char* fmt): type_(typ), format_(fmt) {} DiagType GetType() const { return type_; } - Diag& AddAtom(mol::AtomHandle atom) - { - atoms_.push_back(atom); - args_.push_back(ArgDesc(atoms_.size()-1, DIAG_ARG_TYPE_ATOM)); - return *this; - } + Diag& AddAtom(mol::AtomHandle atom) + { + atoms_.push_back(atom); + args_.push_back(ArgDesc(atoms_.size()-1, DIAG_ARG_TYPE_ATOM)); + return *this; + } - Diag& AddResidue(mol::ResidueHandle res) - { - residues_.push_back(res); - args_.push_back(ArgDesc(residues_.size()-1, DIAG_ARG_TYPE_RESIDUE)); - return *this; - } - Diag& AddChain(mol::ChainHandle chain) - { - chains_.push_back(chain); - args_.push_back(ArgDesc(chains_.size()-1, DIAG_ARG_TYPE_CHAIN)); - return *this; - } - Diag& AddInt(int int_val) - { - ints_.push_back(int_val); - args_.push_back(ArgDesc(ints_.size()-1, DIAG_ARG_TYPE_INT)); - return *this; - } - Diag& AddString(const String& str) - { - strings_.push_back(str); - args_.push_back(ArgDesc(strings_.size()-1, DIAG_ARG_TYPE_STRING)); - return *this; - } + Diag& AddResidue(mol::ResidueHandle res) + { + residues_.push_back(res); + args_.push_back(ArgDesc(residues_.size()-1, DIAG_ARG_TYPE_RESIDUE)); + return *this; + } + Diag& AddChain(mol::ChainHandle chain) + { + chains_.push_back(chain); + args_.push_back(ArgDesc(chains_.size()-1, DIAG_ARG_TYPE_CHAIN)); + return *this; + } + Diag& AddInt(int int_val) + { + ints_.push_back(int_val); + args_.push_back(ArgDesc(ints_.size()-1, DIAG_ARG_TYPE_INT)); + return *this; + } + Diag& AddString(const String& str) + { + strings_.push_back(str); + args_.push_back(ArgDesc(strings_.size()-1, DIAG_ARG_TYPE_STRING)); + return *this; + } mol::AtomHandle GetAtom(size_t index) const { assert(index<args_.size()); @@ -90,44 +91,59 @@ public: assert(index<args_.size()); return chains_[args_[index].index]; } - String Format(bool colored=true) const; + String Format(bool colored=true) const; private: - struct ArgDesc { - ArgDesc(size_t i, DiagArgType t): index(i), type(t) { } - size_t index; - DiagArgType type; - }; - DiagType type_; - String format_; - mol::AtomHandleList atoms_; - mol::ResidueHandleList residues_; + struct ArgDesc { + ArgDesc(size_t i, DiagArgType t): index(i), type(t) { } + size_t index; + DiagArgType type; + }; + DiagType type_; + String format_; + mol::AtomHandleList atoms_; + mol::ResidueHandleList residues_; mol::ChainHandleList chains_; - std::vector<String> strings_; - std::vector<int> ints_; - std::vector<ArgDesc> args_; + std::vector<String> strings_; + std::vector<int> ints_; + std::vector<ArgDesc> args_; }; -class DLLEXPORT_OST_CONOP DiagEngine { +class Diagnostics; + +typedef boost::shared_ptr<Diagnostics> DiagnosticsPtr; + + +class DLLEXPORT DiagError : public Error { public: - DiagEngine() {} + DiagError(const Diag& diag) : Error(diag.Format(false)) {} +}; - ~DiagEngine() - { - for(std::vector<Diag*>::iterator - i=diags_.begin(), e=diags_.end(); i!=e;++i) { - delete *i; - } - } +class DLLEXPORT_OST_CONOP Diagnostics { +public: + typedef std::vector<Diag*>::iterator diag_iterator; + typedef std::vector<Diag*>::const_iterator const_diag_iterator; + Diagnostics() {} - Diag& AddDiag(DiagType type, const char* fmt) - { - diags_.push_back(new Diag(type, fmt)); - return *diags_.back(); - } + ~Diagnostics() + { + for(std::vector<Diag*>::iterator + i=diags_.begin(), e=diags_.end(); i!=e;++i) { + delete *i; + } + } - const std::vector<Diag*>& GetDiags() const { return diags_; } + Diag& AddDiag(DiagType type, const char* fmt) + { + diags_.push_back(new Diag(type, fmt)); + return *diags_.back(); + } + diag_iterator diags_begin() { return diags_.begin(); } + diag_iterator diags_end() { return diags_.end(); } + const_diag_iterator diags_begin() const { return diags_.begin(); } + const_diag_iterator diags_end() const { return diags_.end(); } + size_t diag_count() const { return diags_.size(); } private: - std::vector<Diag*> diags_; + std::vector<Diag*> diags_; }; }} /* ost::conop */ diff --git a/modules/conop/src/heuristic.cc b/modules/conop/src/heuristic.cc new file mode 100644 index 0000000000000000000000000000000000000000..cecf6dcb2df8996a41b7685877e5c40518bac4b5 --- /dev/null +++ b/modules/conop/src/heuristic.cc @@ -0,0 +1,98 @@ +//------------------------------------------------------------------------------ +// 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 <ost/log.hh> +#include <ost/profile.hh> +#include <ost/mol/xcs_editor.hh> +#include <ost/mol/bond_handle.hh> +#include <ost/mol/torsion_handle.hh> +#include <ost/mol/impl/residue_impl.hh> +#include <ost/mol/impl/atom_impl.hh> +#include <ost/mol/residue_handle.hh> +#include "heuristic.hh" +#include "conop.hh" + +namespace ost { namespace conop { + +void HeuristicProcessor::ProcessUnkResidue(DiagnosticsPtr diags, + mol::ResidueHandle res) const { + res.SetChemClass(GuessChemClass(res)); + mol::AtomHandleList atoms = res.GetAtomList(); + for (mol::AtomHandleList::iterator + i = atoms.begin(), e = atoms.end(); i != e; ++i) { + mol::AtomHandle a = *i; + if (!Conopology::Instance().IsValidElement(a.GetElement())) + a.SetElement(GuessAtomElement(a.GetName(), a.IsHetAtom())); + } + if (!this->GetConnect()) { return; } + for (mol::AtomHandleList::iterator + i = atoms.begin(), e = atoms.end(); i != e; ++i) { + this->DistanceBasedConnect(*i); + } +} + +void HeuristicProcessor::DoProcess(DiagnosticsPtr diags, + mol::EntityHandle ent) const +{ + Profile prof("HeuristicProcessor::Process"); + mol::ChainHandleList chains=ent.GetChainList(); + for (mol::ChainHandleList::iterator + i = chains.begin(), e = chains.end(); i!= e; ++i) { + mol::ChainHandle& chain = *i; + mol::ResidueHandleList residues = chain.GetResidueList(); + mol::ResidueHandle prev; + for (mol::ResidueHandleList::iterator + j = residues.begin(), e2 = residues.end(); j != e2; ++j) { + mol::ResidueHandle residue = *j; + CompoundPtr compound = lib_.FindCompound(residue.GetName(), Compound::PDB); + if (!compound) { + // process unknown residue... + this->ProcessUnkResidue(diags, residue); + continue; + } + this->ReorderAtoms(residue, compound, true); + this->FillResidueProps(residue, compound); + if (this->GetConnect()) { + this->ConnectAtomsOfResidue(residue, compound, false); + if (this->GetConnectAminoAcids()) + this->ConnectResidues(prev, residue); + } + prev = residue; + if (!this->GetConnect()) { continue; } + mol::AtomHandleList atoms = residue.GetAtomList(); + for (mol::AtomHandleList::iterator + i = atoms.begin(), e = atoms.end(); i != e; ++i) { + if (i->GetBondCount() == 0) + this->DistanceBasedConnect(*i); + } + } + if (residues.empty() || !this->GetAssignTorsions()) { + continue; + } + AssignBackboneTorsions(residues); + } +} + +String HeuristicProcessor::ToString() const { + std::stringstream ss; + ss << "HeuristicProcessor(" << this->OptionsToString() << ")"; + return ss.str(); +} + +}} diff --git a/modules/conop/src/heuristic.hh b/modules/conop/src/heuristic.hh new file mode 100644 index 0000000000000000000000000000000000000000..a0a7b60ff626b9e72c10f41b09237d14e00f8a6d --- /dev/null +++ b/modules/conop/src/heuristic.hh @@ -0,0 +1,57 @@ +//------------------------------------------------------------------------------ +// 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_CONOP_HEURISTIC_HH +#define OST_CONOP_HEURISTIC_HH + +#include <ost/mol/entity_handle.hh> +#include "minimal_compound_lib.hh" +#include "diag.hh" +#include "processor.hh" + +namespace ost { namespace conop { + + +class HeuristicProcessor; + +typedef boost::shared_ptr<HeuristicProcessor> HeuristicProcessorPtr; + +class DLLEXPORT_OST_CONOP HeuristicProcessor : public Processor { +public: + HeuristicProcessor() { + } + virtual ProcessorPtr Copy() const { + return ProcessorPtr(new HeuristicProcessor(*this)); + } + HeuristicProcessor(bool bf, bool at, bool cn, bool aa, ConopAction zo): + Processor(bf, at, cn, aa, zo) {} + + virtual String ToString() const; +protected: + void ProcessUnkResidue(DiagnosticsPtr diags, mol::ResidueHandle res) const; + virtual void DoProcess(DiagnosticsPtr diags, + mol::EntityHandle ent) const; +private: + MinimalCompoundLib lib_; +}; + + +}} + +#endif + diff --git a/modules/conop/src/heuristic_builder.cc b/modules/conop/src/heuristic_builder.cc deleted file mode 100644 index 07922d6a2dab0aa5fd162323749ebb4c9a4efaaa..0000000000000000000000000000000000000000 --- a/modules/conop/src/heuristic_builder.cc +++ /dev/null @@ -1,531 +0,0 @@ -//------------------------------------------------------------------------------ -// 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 <boost/algorithm/string/trim.hpp> - -#include <ost/log.hh> -#include <ost/geom/geom.hh> -#include "conop.hh" -#include "heuristic_builder.hh" -#include "heuristic_connect_table.hh" -#include <ost/mol/residue_handle.hh> - - -namespace ost { namespace conop { - -namespace detail { - -// internal helper class -ConnResEntry::ConnResEntry(const String& rname, char single, - const mol::ChemClass& chem_class): - rkey_(rname), - abbrev_(single), - chem_class_(chem_class), - pset_(), - prev_(""), - next_(""), - torsion_entry_list_() -{} - -int ConnResEntry::Check(const String& name1, const String& name2) const -{ - NamePair np1(name1,name2); - NamePair np2(name2,name1); - // does this pair exist? - if(pset_.find(np1)!=pset_.end()) { - return 1; - } else if(pset_.find(np2)!=pset_.end()) { - return 2; - } - - return 0; -} - -bool ConnResEntry::HasAtom(const String& name) -{ - for(PairSet::const_iterator it=pset_.begin();it!=pset_.end();++it) { - if(it->first==name || it->second==name) return true; - } - return false; -} - -// add a connection entry -void ConnResEntry::AddConn(const String& n1, const String& n2) -{ - pset_.insert(std::make_pair(n1,n2)); -} - -void ConnResEntry::AddTors(const String& a1, const String& a2, const String& a3, - const String& a4, const String& name) -{ - TorsionEntry te={{a1,a2,a3,a4},name}; - torsion_entry_list_.push_back(te); -} - -// atom that connects to previous residue in chain -void ConnResEntry::SetPrev(const String& n) -{ - prev_=n; -} - -const String& ConnResEntry::GetPrev() const -{ - return prev_; -} - -// atom that connects to next residue in chain -void ConnResEntry::SetNext(const String& n) -{ - next_=n; -} - -const String& ConnResEntry::GetNext() const -{ - return next_; -} - -ConnResEntry::TorsionEntryList ConnResEntry::GetTorsionList() const -{ - return torsion_entry_list_; -} - -} // ns - -// actual builder - -HeuristicBuilder::HeuristicBuilder(): - emap_(), - default_peptide_() -{ - int def_entry_count = sizeof(heuristic_connect::def_entry_table)/sizeof(heuristic_connect::CONN_DEF_ENTRY); - - LOG_DEBUG("importing internal connectivity tables"); - for(int ec=0;ec<def_entry_count;++ec) { - heuristic_connect::CONN_DEF_ENTRY& def_entry = heuristic_connect::def_entry_table[ec]; - detail::ConnResEntry entry(def_entry.abbrev, def_entry.single, - def_entry.chem_class); - LOG_TRACE("creating table entry for " << def_entry.abbrev); - LOG_TRACE("working on bond entries"); - for (int xx=0;xx<def_entry.name_count;++xx) { - String name=def_entry.name_list[xx]; - if (name!="OXT") - entry.AddAtom(name); - } - // first the connectivity entries - for(int cc=0;cc<def_entry.conn_count;++cc) { - int conn_id[] = {def_entry.conn_list[cc][0],def_entry.conn_list[cc][1]}; - String conn_nam[] = {"",""}; - bool special=false; - for(int cid=0;cid<2;++cid) { - if(conn_id[cid]>0) { - conn_nam[cid]=def_entry.name_list[conn_id[cid]-1]; - } else if (conn_id[cid]==-2) { - // PREV key - conn_nam[cid]="-"; - special=true; - } else if (conn_id[cid]==-3) { - // NEXT key - conn_nam[cid]="+"; - special=true; - } else { - // ignore - continue; - } - } - if(special) { - if(conn_nam[0]==String("-")) { entry.SetPrev(conn_nam[1]);} - else if(conn_nam[1]==String("-")) { entry.SetPrev(conn_nam[0]);} - else if(conn_nam[0]==String("+")) { entry.SetNext(conn_nam[1]);} - else if(conn_nam[1]==String("+")) { entry.SetNext(conn_nam[0]);} - LOG_TRACE(" " << conn_nam[0] << " " << conn_nam[1]); - } else { - LOG_TRACE(" " << conn_nam[0] << " " << conn_nam[1]); - entry.AddConn(conn_nam[0],conn_nam[1]); - } - } - // then the torsion entries - LOG_DEBUG("working on torsion entries"); - for(int cc=0;cc<def_entry.tor_count;++cc) { - int tor_id[] = {def_entry.tor_list[cc].n1, - def_entry.tor_list[cc].n2, - def_entry.tor_list[cc].n3, - def_entry.tor_list[cc].n4}; - String tor_nam[] = {"","","",""}; - String tor_nam2(def_entry.tor_list[cc].name); - for(int cid=0;cid<4;++cid) { - if(tor_id[cid]>0) { - tor_nam[cid]=def_entry.name_list[tor_id[cid]-1]; - } else if (tor_id[cid]==-2) { - tor_nam[cid]="-"; - } else if (tor_id[cid]==-3) { - tor_nam[cid]="+"; - } else if (tor_id[cid]==-4) { - tor_nam[cid]=":"; - } - } - - entry.AddTors(tor_nam[0],tor_nam[1],tor_nam[2],tor_nam[3],tor_nam2); - } - if(ec==0) { - default_peptide_=entry; - } else { - emap_[def_entry.abbrev]=entry; - } - } - default_nucleotide_=LookupResEntry("G").first; - LOG_DEBUG("done importing internal tables"); -} - -HeuristicBuilder::~HeuristicBuilder() -{} - - -void HeuristicBuilder::ConnectivityFromAtomNames(const mol::ResidueHandle& res, - detail::ConnResEntry& centry, - mol::AtomHandleList& unknown_atoms) { - unknown_atoms.clear(); - mol::AtomHandleList atomlist=res.GetAtomList(); - mol::XCSEditor editor=res.GetEntity().EditXCS(mol::BUFFERED_EDIT); - for (mol::AtomHandleList::iterator it1=atomlist.begin();it1!=atomlist.end();++it1) { - if (centry.HasAtom(it1->GetName())) { - mol::AtomHandleList::iterator it2=it1; - ++it2; - for (;it2!=atomlist.end();++it2) { - LOG_TRACE("checking for atom pair (" << it1->GetName() << "," - << it2->GetName() << ") in connectivity table of " - << res.GetKey() << "... "); - int conn=centry.Check(it1->GetName(),it2->GetName()); - if (conn==1) { - if (this->GetBondFeasibilityCheck()==false) { - LOG_TRACE( "found"); - editor.Connect(*it1,*it2); - } else { - if (this->IsBondFeasible(*it1, *it2)) { - LOG_TRACE( "found"); - editor.Connect(*it1,*it2); - } else { - LOG_TRACE( "not found"); - } - } - } else if (conn==2) { - if (this->GetBondFeasibilityCheck()==false) { - LOG_TRACE( "found (reversed)"); - editor.Connect(*it2,*it1); - } else { - if(this->IsBondFeasible(*it2, *it1)) { - LOG_TRACE( "found (reversed)"); - editor.Connect(*it2,*it1); - } - } - } else { - LOG_TRACE( "not found"); - } - } - } else { - unknown_atoms.push_back(*it1); - LOG_TRACE( "atom not found, pushing it to unknown atoms"); - } - } -} - -void HeuristicBuilder::ConnectAtomsOfResidue(mol::ResidueHandle res) -{ - LOG_TRACE("HeuristicBuilder: ConnectAtomsOfResidue on " << res.GetKey() << " " << res.GetNumber()); - - mol::AtomHandleList atomlist = res.GetAtomList(); - mol::AtomHandleList unk_atomlist; -#if !defined(NDEBUG) - std::stringstream ss; - ss << "using atom list:"; - for(mol::AtomHandleList::iterator it=atomlist.begin();it!=atomlist.end();++it) { - ss << " " << it->GetName() << " @" << it->GetPos(); - } - LOG_TRACE(ss.str()); -#endif - std::pair<detail::ConnResEntry,bool> ret = LookupResEntry(res.GetKey()); - - if(ret.second) { - // residue entry found - this->ConnectivityFromAtomNames(res, ret.first, unk_atomlist); - // only run the distance based connectivity after the rest is done - for(mol::AtomHandleList::iterator it1=unk_atomlist.begin(); - it1!=unk_atomlist.end(); - ++it1) { - LOG_TRACE( "atom " << it1->GetName() << " not found, using distance based connect"); - Builder::DistanceBasedConnect(*it1); - } - } else { - LOG_TRACE("no residue entry found, using distance based connect"); - for(mol::AtomHandleList::iterator it1=atomlist.begin(); - it1!=atomlist.end(); - ++it1) { - Builder::DistanceBasedConnect(*it1); - } - } -} - -namespace { - -template<bool flag> // false:=prev, true:=next -void ConnectPrevNext(HeuristicBuilder* builder,mol::ResidueHandle res0, - mol::ResidueHandle res1) -{ - static String fname=flag ? "HeuristicBuilder: ConnectNextXCS" : "HeuristicBuilder: ConnectPrevXCS"; - if(!res0) return; // return if invalid - mol::XCSEditor editor=res0.GetEntity().EditXCS(mol::BUFFERED_EDIT); - LOG_TRACE(fname << " on " << res0.GetKey() << " " << res0.GetNumber()); - - if(!res1) { - // auto-detect prev or next residue in chain - // and perform sequence check - if(flag) { - LOG_TRACE(fname << " autodecting next residue"); - res1 = res0.GetChain().GetNext(res0); - } else { - LOG_TRACE(fname << " autodecting next residue"); - res1 = res0.GetChain().GetPrev(res0); - } - } else { - if(res0.GetEntity() != res1.GetEntity()) return; // different entity handles - } - if (flag) { - if(!Builder::AreResiduesConsecutive(res0,res1)) return; - } else { - if(!Builder::AreResiduesConsecutive(res1, res0)) return; - } - - if(!res1) return; // ignore if prev/next residue is invalid - LOG_TRACE(fname << " found second residue " << res1.GetKey() - << " " << res1.GetNumber()); - - std::pair<detail::ConnResEntry,bool> res0_ret = builder->LookupResEntry(res0.GetKey()); - std::pair<detail::ConnResEntry,bool> res1_ret = builder->LookupResEntry(res1.GetKey()); - - if(!res0_ret.second) { - if(res0.FindAtom("N") && res0.FindAtom("CA") && res0.FindAtom("C")) { - LOG_TRACE("using default peptide for " << res0.GetKey()); - res0_ret.first=builder->DefaultPeptide(); - res0_ret.second=true; - } - if (res0.FindAtom("C3'") && res0.FindAtom("P")) { - res0_ret.first=builder->DefaultNucleotide(); - res0_ret.second=true; - } - } - - if(!res1_ret.second) { - if(res1.FindAtom("N") && res1.FindAtom("CA") && res1.FindAtom("C")) { - LOG_TRACE("using default peptide for " << res1.GetKey()); - res1_ret.first=builder->DefaultPeptide(); - res1_ret.second=true; - } - if (res1.FindAtom("C3'") && res1.FindAtom("P")) { - res1_ret.first=builder->DefaultNucleotide(); - res1_ret.second=true; - } - } - - if(res0_ret.second && res1_ret.second) { - detail::ConnResEntry& res0_centry=res0_ret.first; - detail::ConnResEntry& res1_centry=res1_ret.first; - String res0_atom_name = res0_centry.GetPrev(); - String res1_atom_name = res1_centry.GetNext(); - - if(res0_atom_name.empty() || res1_atom_name.empty()) return; - LOG_TRACE(fname << ": looking up atom names " << res0_atom_name << " " << res1_atom_name); - - // lookup both atoms in their respective residues - mol::AtomHandle res0_atom = res0.FindAtom(res0_atom_name); - mol::AtomHandle res1_atom = res1.FindAtom(res1_atom_name); - if(res0_atom && res1_atom) { - LOG_TRACE(fname << ": found atoms, connecting"); - if(flag) { - if (builder->DoesPeptideBondExist(res0_atom, res1_atom)) { - editor.Connect(res0_atom,res1_atom); - if (res0_ret.first.GetChemClass().IsPeptideLinking()) { - res0.SetIsProtein(true); - res1.SetIsProtein(true); - } - } - } else { - if (builder->DoesPeptideBondExist(res1_atom, res0_atom)) { - editor.Connect(res1_atom, res0_atom); - if (res0_ret.first.GetChemClass().IsPeptideLinking()) { - res0.SetIsProtein(true); - res1.SetIsProtein(true); - } - } - } - } - } else { - // could implement some sort of distance based heuristics here - } -} - -} - -void HeuristicBuilder::AssignTorsionsToResidue(mol::ResidueHandle res) -{ - - mol::XCSEditor editor=res.GetEntity().EditXCS(mol::BUFFERED_EDIT); - mol::ChainHandle chain=res.GetChain(); - std::pair<detail::ConnResEntry,bool> centry2 = LookupResEntry(res.GetKey()); - if (centry2.second) { - // residue entry found - detail::ConnResEntry& centry=centry2.first; - - detail::ConnResEntry::TorsionEntryList tel=centry.GetTorsionList(); - // for each entry in torsion list - for (unsigned int ti=0;ti<tel.size();++ti) { - // assign the four atom handles - mol::AtomHandle ah[4]; - for (unsigned int ahi=0;ahi<4;++ahi) { - mol::ResidueHandle search_in=res; - String cur_name=tel[ti].a[ahi]; - bool flag=false; - if (cur_name=="+") { - mol::ResidueHandle next=res.GetNext(); - // NEXT - if (Builder::AreResiduesConsecutive(res, next)) { - centry2=LookupResEntry(next.GetKey()); - if (centry2.second) { - cur_name=centry2.first.GetPrev(); - search_in=next; - flag=true; - } - } - } else if (cur_name=="-") { - mol::ResidueHandle prev=res.GetPrev(); - if (Builder::AreResiduesConsecutive(prev, res)) { - centry2=LookupResEntry(prev.GetKey()); - if (centry2.second) { - cur_name=centry2.first.GetNext(); - search_in=prev; - flag=true; - } - } - } else { - flag=true; - } - if (flag) { - // lookup atom based on cur_residue and cur_name - mol::AtomHandle a=search_in.FindAtom(cur_name); - if (!a.IsValid()) - continue; - ah[ahi]=a; - } - } // ahi - if (ah[0] && ah[1] && ah[2] && ah[3]) { - mol::TorsionHandle th = editor.AddTorsion(tel[ti].name, ah[0], ah[1], - ah[2], ah[3]); - if(th) { - LOG_TRACE("added torsion entry for " << tel[ti].a[0] << " " - << tel[ti].a[1] << " " << tel[ti].a[2] << " " - << tel[ti].a[3]); - } else { - LOG_TRACE("no torsion entry for " << tel[ti].a[0] << " " - << tel[ti].a[1] << " " << tel[ti].a[2] - << " " << tel[ti].a[3]); - } - } - } - } -} - -void HeuristicBuilder::AssignTorsions(mol::ChainHandle chain) -{ - if (chain.GetResidueCount()==0) - return; - std::vector<mol::ResidueHandle> rlist = chain.GetResidueList(); - for(unsigned int ri=0;ri<rlist.size();++ri) { - mol::ResidueHandle res=rlist[ri]; - this->AssignTorsionsToResidue(res); - if (!res.IsPeptideLinking()) { - return; - } - Builder::AssignBackBoneTorsionsToResidue(res); - } -} - -void HeuristicBuilder::ConnectResidueToPrev(mol::ResidueHandle rh, - mol::ResidueHandle prev) { - ConnectPrevNext<false>(this, rh, prev); -} - -void HeuristicBuilder::ConnectResidueToNext(mol::ResidueHandle rh, - mol::ResidueHandle next) { - ConnectPrevNext<true>(this, rh, next); -} - -void HeuristicBuilder::FillResidueProps(mol::ResidueHandle residue) { - std::pair<detail::ConnResEntry,bool> ret = LookupResEntry(residue.GetKey()); - if (ret.second) { - residue.SetChemClass(mol::ChemClass(ret.first.GetChemClass())); - residue.SetOneLetterCode(ret.first.GetOneLetterCode()); - } else { - if (residue.FindAtom("N") && residue.FindAtom("CA") && - residue.FindAtom("C") && residue.FindAtom("O")) { - residue.SetChemClass(mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING)); - } else { - residue.SetChemClass(mol::ChemClass(mol::ChemClass::UNKNOWN)); - } - - residue.SetOneLetterCode('?'); - } - -} - -std::pair<detail::ConnResEntry,bool> HeuristicBuilder::LookupResEntry(const mol::ResidueKey& key) -{ - static detail::ConnResEntry dummy; - - - - detail::ConnResEntryMap::iterator pos = emap_.find(key); - if(pos!=emap_.end()) { - LOG_TRACE("reskey '" << key << "' found in connectivity map"); - return std::make_pair(pos->second,true); - } - LOG_TRACE("reskey '" << key << "' not found connectivity map"); - return std::make_pair(dummy,false); -} - -bool HeuristicBuilder::IsResidueComplete(const mol::ResidueHandle& rh) -{ - std::pair<detail::ConnResEntry,bool> ret=LookupResEntry(rh.GetKey()); - if (!ret.second) { - // if the residue is unknown we return false... - return false; - } - for (std::vector<String>::const_iterator i=ret.first.GetReqAtoms().begin(), - e=ret.first.GetReqAtoms().end(); i!=e; ++i) { - if (!rh.FindAtom(*i)) { - return false; - } - } - return true; -} - -void HeuristicBuilder::FillAtomProps(mol::AtomHandle atom) -{ - if (atom.GetElement()=="") { - atom.SetElement(Builder::GuessAtomElement(atom.GetName(), atom.IsHetAtom())); - } -} - -}} // ns diff --git a/modules/conop/src/heuristic_builder.hh b/modules/conop/src/heuristic_builder.hh deleted file mode 100644 index 09a991345264b6031265c9bf2505a874f730daac..0000000000000000000000000000000000000000 --- a/modules/conop/src/heuristic_builder.hh +++ /dev/null @@ -1,127 +0,0 @@ -//------------------------------------------------------------------------------ -// 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_CONOP_HEURISTIC_BUILDER_HH -#define OST_CONOP_HEURISTIC_BUILDER_HH - -#include <set> -#include <map> - -#include <ost/mol/chem_class.hh> - -#include "builder.hh" - -namespace ost { namespace conop { - -namespace detail { - -// internally used class -class DLLEXPORT_OST_CONOP ConnResEntry { -public: - typedef std::pair<String,String> NamePair; - typedef std::multiset<NamePair> PairSet; - struct TorsionEntry { - String a[4]; - String name; - }; - typedef std::vector<TorsionEntry> TorsionEntryList; - -public: - ConnResEntry(const String& rname="", char single='\0', - const mol::ChemClass& chem_class=mol::ChemClass(mol::ChemClass::UNKNOWN)); - int Check(const String& name1, const String& name2) const; - bool HasAtom(const String& name); - void AddAtom(const String& atom) { required_atoms_.push_back(atom); } - void AddConn(const String& n1, const String& n2); - void AddTors(const String& a1, const String& a2, - const String& a3, const String& a4, const String& name); - void SetPrev(const String& n); - const String& GetPrev() const; - void SetNext(const String& n); - const String& GetNext() const; - TorsionEntryList GetTorsionList() const; - char GetOneLetterCode() const {return abbrev_;} - mol::ChemClass GetChemClass() const { return chem_class_; } - - std::vector<String> GetReqAtoms() const { return required_atoms_;} -private: - mol::ResidueKey rkey_; - char abbrev_; - mol::ChemClass chem_class_; - PairSet pset_; - String prev_; - String next_; - std::vector<String> required_atoms_; - TorsionEntryList torsion_entry_list_; -}; - -typedef std::map<mol::ResidueKey,ConnResEntry> ConnResEntryMap; - -} // ns - -class DLLEXPORT_OST_CONOP HeuristicBuilder: public Builder { -public: - HeuristicBuilder(); - virtual ~HeuristicBuilder(); - - virtual void AssignTorsions(mol::ChainHandle ch); - - //! \brief connect by using information in the heuristic connectivity table. - // - // This does not make any assumption on the correctness of internal or external - // coordinates. Only the atom names and residue need to be known. - virtual void ConnectAtomsOfResidue(mol::ResidueHandle rh); - - virtual bool IsResidueComplete(const mol::ResidueHandle& rh); -// virtual char GetOneLetterCode(const mol::ResidueKey& residue) const; - - //!\brief connect to previous residue in chain. - virtual void ConnectResidueToPrev(mol::ResidueHandle rh, - mol::ResidueHandle prev); - //! - virtual void AssignTorsionsToResidue(mol::ResidueHandle residue); - - virtual void FillResidueProps(mol::ResidueHandle residue); - - //!\brief connect to next residue in chain. - virtual void ConnectResidueToNext(mol::ResidueHandle rh, - mol::ResidueHandle next); - - //!\brief get connectivity table for residues - // Retrieve connectiviy information based on residue key. The returned - // \c pair->second is true, if an entry has been found and and false otherwise. - std::pair<detail::ConnResEntry,bool> LookupResEntry(const mol::ResidueKey& key); - - virtual void FillAtomProps(mol::AtomHandle atom); - - const detail::ConnResEntry& DefaultPeptide() const {return default_peptide_;} - const detail::ConnResEntry& DefaultNucleotide() const {return default_nucleotide_;} -protected: - void ConnectivityFromAtomNames(const mol::ResidueHandle& res, - detail::ConnResEntry& centry, - mol::AtomHandleList& unknown_atoms); -private: - detail::ConnResEntryMap emap_; - detail::ConnResEntry default_peptide_; - detail::ConnResEntry default_nucleotide_; -}; - - -}} // ns - -#endif diff --git a/modules/conop/src/heuristic_connect_table.hh b/modules/conop/src/heuristic_connect_table.hh deleted file mode 100644 index 15e0f1a25eeada4159f10cc60140eeaa4bea55fc..0000000000000000000000000000000000000000 --- a/modules/conop/src/heuristic_connect_table.hh +++ /dev/null @@ -1,304 +0,0 @@ -//------------------------------------------------------------------------------ -// 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_HEURISTIC_CONNECT_TABLE_HH -#define OST_HEURISTIC_CONNECT_TABLE_HH - -#include <string> - -namespace ost { namespace conop { namespace heuristic_connect { - -struct CONN_DEF_ENTRY { - char name[256]; - char abbrev[16],single; - mol::ChemClass chem_class; - char name_list[48][8]; - int name_count; - int conn_list[48][2]; - int conn_count; - struct CONN_TORSION_TMP { - int n1,n2,n3,n4; - String name; - }tor_list[8]; - int tor_count; - int flag_list[128]; - int flag_count; -}; - -CONN_DEF_ENTRY def_entry_table[]={ - // the first entry must be this generic one - {"Generic","___",'_', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C"},3, - {{-2,1}, {1,2}, {2,3}, {3,-3}},4, - { - },0, - {0, 0, 0, 0, 0, 0},6 - }, - {"Alanine","ALA",'A', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","OXT"},6, - {{-2,1}, {1,2}, {2,3}, {3,4}, {2,5}, {3,-3}, {6, 3}},7, - { - },0, - {0, 0, 0, 0, 0, 0},6 - }, - {"Cystein","CYS",'C', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","SG","OXT"},7, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{3,-3},{8, 3}},8, - {{1,2,5,6,"CHI1"} - },1, - {0, 0, 0, 0, 0, 0, 0},7 - }, - {"Aspartate","ASP",'D', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG","OD1","OD2","OXT"},9, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{6,7},{6,8},{3,-3},{9, 3}},10, - { - {1,2,5,6,"CHI1"},{2,5,6,7,"CHI2"} - },2, - {0, 0, 0, 0, 0, 0, 0, 0, 0},9 - }, - {"Glutamate","GLU",'E', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG","CD","OE1","OE2","OXT"},10, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{6,7},{7,8},{7,9},{3,-3},{10, 3}},11, - { - {1,2,5,6,"CHI1"},{2,5,6,7,"CHI2"},{5,6,7,8,"CHI3"} - },3, - {0},1 - }, - {"Phenylalanine","PHE",'F', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG","CD1","CD2","CE1","CE2","CZ","OXT"},12, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{6,7},{6,8},{7,9},{8,10},{9,11},{10,11},{3,-3},{12, 3}},14, - { - {1,2,5,6,"CHI1"},{2,5,6,7,"CHI2"} - },2, - {0},1 - }, - {"Glycin","GLY",'G', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","OXT"},5, - {{-2,1},{1,2},{2,3},{3,4},{3,-3},{5, 3}},6, - { - },0, - {0},1 - }, - {"Histidine","HIS",'H', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG","ND1","CD2","CE1","NE2","OXT"},11, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{6,7},{6,8},{7,9},{8,10},{9,10},{3,-3},{11, 3}},13, - { - {1,2,5,6,"CHI1"},{2,5,6,7,"CHI2"} - },2, - {0},1 - }, - {"Isoleucine","ILE",'I', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG1","CG2","CD1","OXT"},9, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{5,7},{6,8},{3,-3},{9, 3}},10, - { - {1,2,5,6,"CHI1"},{2,5,6,8,"CHI2"} - },2, - {0},1 - }, - {"Lysin","LYS",'K', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG","CD","CE","NZ","OXT"},10, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{6,7},{7,8},{8,9},{3,-3},{10, 3}},11, - { - {1,2,5,6,"CHI1"},{2,5,6,7,"CHI2"},{5,6,7,8,"CHI3"},{6,7,8,9,"CHI4"} - },4, - {0},1 - }, - {"Leucin","LEU",'L', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG","CD1","CD2","OXT"},9, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{6,7},{6,8},{3,-3},{9, 3}},10, - { - {1,2,5,6,"CHI1"},{2,5,6,7,"CHI2"} - },2, - {0},1 - }, - {"Methionine","MET",'M', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG","SD","CE","OXT"},9, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{6,7},{7,8},{3,-3},{10, 3}},10, - { - {1,2,5,6,"CHI1"},{2,5,6,7,"CHI2"},{5,6,7,8,"CHI3"} - },3, - {0},1 - }, - {"Asparagine","ASN",'N', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG","OD1","ND2","OXT"},9, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{6,7},{6,8},{3,-3},{9, 3}},10, - { - {1,2,5,6,"CHI1"},{2,5,6,7,"CHI2"} - },2, - {0},1 - }, - {"Proline","PRO",'P', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG","CD","OXT"},8, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{6,7},{3,-3},{1,7},{8, 3}},10, - { - {1,2,5,6,"CHI1"},{2,5,6,7,"CHI2"} - },2, - {0},1 - }, - {"Glutamine","GLN",'Q', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG","CD","OE1","NE2","OXT"},10, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{6,7},{7,8},{7,9},{3,-3},{10, 3}},11, - { - {1,2,5,6,"CHI1"},{2,5,6,7,"CHI2"},{5,6,7,8,"CHI3"} - },3, - {0},1 - }, - {"Arginine","ARG",'R', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG","CD","NE","CZ","NH1","NH2","OXT"},12, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{6,7},{7,8},{8,9},{9,10},{9,11},{3,-3},{12, 3}},13, - { - {1,2,5,6,"CHI1"},{2,5,6,7,"CHI2"},{5,6,7,8,"CHI3"},{6,7,8,9,"CHI4"},{7,8,9,10,"CHI5"} - },5, - {0},1 - }, - {"Serine","SER",'S', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","OG","OXT"},7, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{3,-3},{7, 3}},8, - { - {1,2,5,6,"CHI1"} - },1, - {0},1 - }, - {"Threonine","THR",'T', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","OG1","CG2","OXT"},8, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{5,7},{3,-3},{8, 3}},9, - { - {1,2,5,6,"CHI1"} - },1, - {0},1 - }, - {"Valine","VAL",'V', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG1","CG2","OXT"},8, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{5,7},{3,-3},{8, 3}},9, - { - {1,2,5,6,"CHI1"} - },1, - {0},1 - }, - {"Tryptophan","TRP",'W', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG","CD1","CD2","NE1","CE2","CE3","CZ2","CZ3","CH2","OXT"},15, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{6,7},{6,8},{7,9},{8,10},{9,10},{8,11},{10,12},{11,13},{12,14},{13,14},{3,-3},{15, 3}},18, - { - {1,2,5,6,"CHI1"},{2,5,6,7,"CHI2"} - },2, - {0},1 - }, - {"Tyrosin","TYR",'Y', mol::ChemClass(mol::ChemClass::L_PEPTIDE_LINKING), - {"N","CA","C","O","CB","CG","CD1","CD2","CE1","CE2","CZ","OH","OXT"},13, - {{-2,1},{1,2},{2,3},{3,4},{2,5},{5,6},{6,7},{6,8},{7,9},{8,10},{9,11},{10,11},{11,12},{3,-3},{13, 3}},15, - { - {1,2,5,6,"CHI1"},{2,5,6,7,"CHI2"} - },2, - {0},1 - }, - /* NUCLEIC ACIDS */ - {"Adenosin","A",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","N9","C8","N7","C5","C6","N6","N1","C2","N3","C4","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{1,10},{1,11},{8,22},{7,-3}},14, - {{0,0,0,0,""}},1, - {0},1 - }, - {"Cytosin","C",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{1,10},{1,11},{8,12},{7,-3}},14, - {{0,0,0,0,""}},1, - {0},1 - }, - {"Guanidin","G",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{7,-3},{1,10},{1,11},{8,12}},14, - {{0,0,0,0,""}},1, - {0},1 - }, - {"Thymidin","T",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{7,-3},{1,10},{8,12},{1,11}},15, - {{0,0,0,0,""}},1, - {0},1 - }, - {"Uracil","U",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{7,-3},{1,10},{1,11},{8,12}},14, - {{0,0,0,0,""}},1, - {0},1 - }, - {"Adenosin","ADE",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","N9","C8","N7","C5","C6","N6","N1","C2","N3","C4","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{1,10},{1,11},{8,22},{9,12},{7,-3}},15, - {{0,0,0,0,""}},1, - {0},1 - }, - {"Cytosin","CYT",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{1,10},{1,11},{8,12},{7,-3}},14, - {{0,0,0,0,""}},1, - {0},1 - }, - {"Guanidin","GUA",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{7,-3},{1,10},{1,11},{8,12}},14, - {{0,0,0,0,""}},1, - {0},1 - }, - {"Thymidin","THY",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{7,-3},{1,10},{8,12},{1,11}},15, - {{0,0,0,0,""}},1, - {0},1 - }, - {"Uracil","URI",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{7,-3},{1,10},{1,11},{8,12}},14, - {{0,0,0,0,""}},1, - {0},1 - }, - {"Adenosin","DA",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","N9","C8","N7","C5","C6","N6","N1","C2","N3","C4","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{1,10},{1,11},{8,22},{9,12},{7,-3}},15, - {{0,0,0,0,""}},1, - {0},1 - }, - {"Cytosin","DC",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{1,10},{1,11},{8,12},{7,-3}},14, - {{0,0,0,0,""}},1, - {0},1 - }, - {"Guanidin","DG",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{7,-3},{1,10},{1,11},{8,12}},14, - {{0,0,0,0,""}},1, - {0},1 - }, - {"Thymidin","DT",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{7,-3},{1,10},{8,12},{1,11}},15, - {{0,0,0,0,""}},1, - {0},1 - }, - {"Uracil","DU",'?', mol::ChemClass(mol::ChemClass::DNA_LINKING), - {"P","O5'","C5'","C4'","O4'","C3'","O3'","C2'","C1'","O1P","O2P","O2'"},12, - {{-2,1},{1,2},{2,3},{3,4},{4,5},{4,6},{6,7},{6,8},{8,9},{5,9},{7,-3},{1,10},{1,11},{8,12}},14, - {{0,0,0,0,""}},1, - {0},1 - } -}; - -}}} // ns - -#endif diff --git a/modules/conop/src/minimal_compound_lib.cc b/modules/conop/src/minimal_compound_lib.cc new file mode 100644 index 0000000000000000000000000000000000000000..9eeb107539e70a34bcdfe9f66ec4917d8b2bcc56 --- /dev/null +++ b/modules/conop/src/minimal_compound_lib.cc @@ -0,0 +1,54 @@ +#include "minimal_compound_lib.hh" +namespace ost { namespace conop { + +#include "standard_compounds.cc" + +CompoundMap MinimalCompoundLib::compounds_ = MinimalCompoundLib::InitCompounds(); + +CompoundMap MinimalCompoundLib::InitCompounds() { + CompoundMap c; + c["ALA"] = MakeALACompound(); + c["CYS"] = MakeCYSCompound(); + c["ASP"] = MakeASPCompound(); + c["GLU"] = MakeGLUCompound(); + c["PHE"] = MakePHECompound(); + c["GLY"] = MakeGLYCompound(); + c["HIS"] = MakeHISCompound(); + c["ILE"] = MakeILECompound(); + c["LYS"] = MakeLYSCompound(); + c["LEU"] = MakeLEUCompound(); + c["MET"] = MakeMETCompound(); + c["ASN"] = MakeASNCompound(); + c["PRO"] = MakePROCompound(); + c["GLN"] = MakeGLNCompound(); + c["ARG"] = MakeARGCompound(); + c["SER"] = MakeSERCompound(); + c["THR"] = MakeTHRCompound(); + c["VAL"] = MakeVALCompound(); + c["TRP"] = MakeTRPCompound(); + c["TYR"] = MakeTYRCompound(); + c["G"] = MakeGCompound(); + c["T"] = MakeTCompound(); + c["A"] = MakeACompound(); + c["C"] = MakeCCompound(); + c["U"] = MakeUCompound(); + c["DG"] = MakeDGCompound(); + c["DT"] = MakeDTCompound(); + c["DU"] = MakeDUCompound(); + c["DC"] = MakeDCCompound(); + c["DA"] = MakeDACompound(); + return c; +} + + +CompoundPtr MinimalCompoundLib::FindCompound(const String& id, + Compound::Dialect dialect) const +{ + CompoundMap::const_iterator i = MinimalCompoundLib::compounds_.find(id); + if (i != MinimalCompoundLib::compounds_.end()) { + return i->second; + } + return CompoundPtr(); +} + +}} diff --git a/modules/conop/src/minimal_compound_lib.hh b/modules/conop/src/minimal_compound_lib.hh new file mode 100644 index 0000000000000000000000000000000000000000..208011545b6c7405c932207fdb2f5b2d83b4c289 --- /dev/null +++ b/modules/conop/src/minimal_compound_lib.hh @@ -0,0 +1,28 @@ + +#ifndef OST_CONOP_MINIMAL_COMPOUND_LIB_HH +#define OST_CONOP_MINIMAL_COMPOUND_LIB_HH + +#include "compound_lib_base.hh" + +namespace ost { namespace conop { + +class MinimalCompoundLib; +typedef boost::shared_ptr<MinimalCompoundLib> MinimalCompoundLibPtr; + +// a minimal compound lib containing the definitions of the 20 standard +// amino acids and standard nucleotides +class DLLEXPORT_OST_CONOP MinimalCompoundLib : public CompoundLibBase { +public: + MinimalCompoundLib() {} + virtual CompoundPtr FindCompound(const String& id, + Compound::Dialect dialect) const; +private: + static CompoundMap InitCompounds(); + // since this information is never going to change, it is shared + // between instances of minimal compound lib. + static CompoundMap compounds_; +}; + + +}} +#endif diff --git a/modules/conop/src/model_check.hh b/modules/conop/src/model_check.hh index 3e56f45e97de7929177d5016396e15ecb821fcba..aedd7a0f54155d789bdde1766d72a4b7a1210936 100644 --- a/modules/conop/src/model_check.hh +++ b/modules/conop/src/model_check.hh @@ -9,21 +9,19 @@ namespace ost { namespace conop { class DLLEXPORT_OST_CONOP Checker { public: Checker(CompoundLibPtr lib, const mol::EntityHandle& ent, - DiagEngine& diags): lib_(lib), ent_(ent), diags_(diags), - checked_unk_res_(false), - residues_(ent_.GetResidueList()) - { } + Diagnostics& diags): lib_(lib), ent_(ent), diags_(diags), + checked_unk_res_(false), residues_(ent_.GetResidueList()) + {} void CheckForUnknownAtoms(); void CheckForCompleteness(bool require_hydrogens=false); void CheckForNonStandard(); mol::AtomHandleList GetHydrogens(); mol::AtomHandleList GetZeroOccupancy(); - const std::vector<Diag*>& GetDiags() const { return diags_.GetDiags(); } private: CompoundLibPtr lib_; mol::EntityHandle ent_; - DiagEngine& diags_; + Diagnostics& diags_; bool checked_unk_res_; mol::ResidueHandleList residues_; }; diff --git a/modules/conop/src/nonstandard.cc b/modules/conop/src/nonstandard.cc index eeccdb60d16425dd1107629e41fb075100a7c0c3..eaf06680d087c05080f0e578828c7bad3fd68c66 100644 --- a/modules/conop/src/nonstandard.cc +++ b/modules/conop/src/nonstandard.cc @@ -26,7 +26,6 @@ #include <ost/conop/conop.hh> #include <ost/mol/mol.hh> #include <ost/mol/alg/construct_cbeta.hh> -#include <ost/conop/rule_based_builder.hh> #include <ost/conop/compound_lib.hh> #include "nonstandard.hh" using namespace ost::mol; @@ -39,18 +38,19 @@ namespace ost { namespace conop { bool CopyResidue(ResidueHandle src_res, ResidueHandle dst_res, XCSEditor& edi) { // first let's get our hands on the component library - conop::BuilderP builder=conop::Conopology::Instance().GetBuilder("DEFAULT"); - conop::RuleBasedBuilderPtr rbb=dyn_cast<conop::RuleBasedBuilder>(builder); - conop::CompoundLibPtr comp_lib=rbb->GetCompoundLib(); + conop::CompoundLibPtr comp_lib=conop::Conopology::Instance().GetDefaultLib(); return CopyResidue(src_res, dst_res, edi, comp_lib); } -bool CopyResidue(ResidueHandle src_res, ResidueHandle dst_res, XCSEditor& edi, CompoundLibPtr comp_lib) +bool CopyResidue(ResidueHandle src_res, ResidueHandle dst_res, + XCSEditor& edi, CompoundLibPtr comp_lib) { bool has_cbeta = false; bool ret; - char parent_src = (comp_lib->FindCompound(src_res.GetName(),Compound::PDB))->GetOneLetterCode (); - char parent_dst = (comp_lib->FindCompound(dst_res.GetName(),Compound::PDB))->GetOneLetterCode (); + char parent_src = (comp_lib->FindCompound(src_res.GetName(), + Compound::PDB))->GetOneLetterCode (); + char parent_dst = (comp_lib->FindCompound(dst_res.GetName(), + Compound::PDB))->GetOneLetterCode (); if (parent_src==parent_dst) { ret = CopyConserved(src_res, dst_res, edi, has_cbeta, comp_lib); } else { @@ -69,9 +69,7 @@ bool CopyConserved(ResidueHandle src_res, ResidueHandle dst_res, XCSEditor& edi, bool& has_cbeta) { // first let's get our hands on the component library - conop::BuilderP builder=conop::Conopology::Instance().GetBuilder("DEFAULT"); - conop::RuleBasedBuilderPtr rbb=dyn_cast<conop::RuleBasedBuilder>(builder); - conop::CompoundLibPtr comp_lib=rbb->GetCompoundLib(); + conop::CompoundLibPtr comp_lib=conop::Conopology::Instance().GetDefaultLib(); return CopyConserved(src_res,dst_res,edi,has_cbeta,comp_lib); } diff --git a/modules/conop/src/processor.cc b/modules/conop/src/processor.cc new file mode 100644 index 0000000000000000000000000000000000000000..d8f5c269837dd4f38a892b5fc8996ee4e9986656 --- /dev/null +++ b/modules/conop/src/processor.cc @@ -0,0 +1,455 @@ +//------------------------------------------------------------------------------ +// 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 <limits> +#include <ost/log.hh> +#include <ost/mol/xcs_editor.hh> +#include <ost/mol/bond_handle.hh> +#include <ost/mol/torsion_handle.hh> +#include <ost/mol/impl/residue_impl.hh> +#include <ost/mol/impl/atom_impl.hh> +#include <ost/mol/residue_handle.hh> +#include "processor.hh" + +namespace ost { namespace conop { + +struct OrdinalAtomComp { + bool operator()(const mol::impl::AtomImplPtr& a, + const mol::impl::AtomImplPtr& b) const { + return a->GetState()<b->GetState(); + } +}; +DiagnosticsPtr Processor::Process(mol::EntityHandle ent, + bool log_diags) const +{ + DiagnosticsPtr diags(new Diagnostics); + if (!this->BeginProcessing(diags, ent)) { + return diags; + } + this->DoProcess(diags, ent); + + this->EndProcessing(diags, ent); + if (log_diags) { + for (Diagnostics::diag_iterator i = diags->diags_begin(), + e = diags->diags_end(); i != e; ++i) { + LOG_WARNING((*i)->Format(false)); + } + } + return diags; +} + +void AssignBackboneTorsions(mol::ChainHandle chain) +{ + AssignBackboneTorsions(chain.GetResidueList()); +} + +void AssignBackboneTorsions(mol::ResidueHandleList residues) +{ + if (residues.empty()) { return; } + mol::ResidueHandle r1; + mol::ResidueHandle r2; + mol::ResidueHandle r3 = residues.front(); + for (mol::ResidueHandleList::iterator + j = residues.begin()+1, e2 = residues.end(); j != e2; ++j) { + r1 = r2; + r2 = r3; + r3 = *j; + AssignBackboneTorsions(r1, r2, r3); + } + AssignBackboneTorsions(r2, r3, mol::ResidueHandle()); +} + + +void AssignBackboneTorsions(mol::ResidueHandle prev, + mol::ResidueHandle res, + mol::ResidueHandle next) +{ + + mol::XCSEditor e=res.GetEntity().EditXCS(mol::BUFFERED_EDIT); + //psi + if (next.IsValid() && next.IsPeptideLinking()){ + mol::AtomHandle ca_this=res.FindAtom("CA"); + mol::AtomHandle n_this=res.FindAtom("N"); + mol::AtomHandle c_this=res.FindAtom("C"); + mol::AtomHandle n_next=next.FindAtom("N"); + if ((ca_this && n_this && c_this && n_next && BondExists(c_this, n_next)) + && !res.GetPsiTorsion()) { + e.AddTorsion("PSI", n_this, ca_this, c_this, n_next); + } + }; + //phi + if (prev.IsValid() && prev.IsPeptideLinking()) { + mol::AtomHandle c_prev=prev.FindAtom("C"); + mol::AtomHandle n_this=res.FindAtom("N"); + mol::AtomHandle ca_this=res.FindAtom("CA"); + mol::AtomHandle c_this=res.FindAtom("C"); + if ((c_prev && n_this && ca_this && c_this && BondExists(c_prev, n_this)) + && !res.GetPhiTorsion()) { + e.AddTorsion("PHI", c_prev, n_this, ca_this, c_this); + } + } + //omega + if (prev.IsValid() && prev.IsPeptideLinking()) { + mol::AtomHandle ca_prev=prev.FindAtom("CA"); + mol::AtomHandle c_prev=prev.FindAtom("C"); + mol::AtomHandle n=res.FindAtom("N"); + mol::AtomHandle ca=res.FindAtom("CA"); + if ((ca_prev && c_prev && n && ca && BondExists(c_prev, n)) + && !res.GetOmegaTorsion()) { + e.AddTorsion("OMEGA",ca_prev , c_prev, n, ca); + } + } +} +mol::ChemClass GuessChemClass(mol::ResidueHandle res) +{ + mol::AtomHandle ca=res.FindAtom("CA"); + if (!ca.IsValid() || ca.GetElement()!="C") return mol::ChemClass(); + mol::AtomHandle n=res.FindAtom("N"); + if (!n.IsValid() || n.GetElement()!="N") return mol::ChemClass(); + mol::AtomHandle c=res.FindAtom("C"); + if (!c.IsValid() || c.GetElement()!="C") return mol::ChemClass(); + mol::AtomHandle o=res.FindAtom("O"); + if (!o.IsValid() || o.GetElement()!="O") return mol::ChemClass(); + if (IsBondFeasible(n, ca) && IsBondFeasible(ca, c) && + IsBondFeasible(c, o)) { + return mol::ChemClass(mol::ChemClass::PEPTIDE_LINKING); + } + return mol::ChemClass(); +} +String GuessAtomElement(const String& aname, bool hetatm) +{ + static String l1[] = { + "H","C","N","O","P","S","K" + }; + static int l1c=7; + static String l2[] = { + "NA","MG","AL","SI","CL", + "CA","CR","MN","FE","CO","NI","CU","ZN","AS","SE","BR","MO" + }; + static int l2c=17; + static String l3[] = { + "B","F","V" + }; + static int l3c=3; + static String l4[] = { + "HE","LI","BE","AR","SC","TI","GA","GE","KR" + }; + static int l4c=9; + + String ele=aname.substr(0,2); + // hydrogen hack + if(ele[0]=='H') { + return "H"; + } + if (hetatm==false) { + if (ele=="CA" || ele=="CB") { + return "C"; + } + } + + // two characters + if(aname.size()==2) { + for(int i=0;i<l2c;i++) { + if(ele==l2[i]) return ele; + } + // check second character for match + for(int i=0;i<l1c;i++) { + if(ele[1]==l1[i][0]) { + return l1[i]; + } + } + // still no match, repeat with less likely tables + for(int i=0;i<l4c;i++) { + if(ele==l4[i]) return ele; + } + // check second character for match + for(int i=0;i<l3c;i++) { + if(ele[1]==l3[i][0]) { + return l3[i]; + } + } + // check second character for match + for(int i=0;i<l1c;i++) { + if(ele[0]==l1[i][0]) { + return l1[i]; + } + } + } else { + for(int i=0;i<l1c;i++) { + if(ele==l1[i]) return ele; + } + for(int i=0;i<l3c;i++) { + if(ele==l3[i]) return ele; + } + } + size_t i=0; + while (i<aname.size() && isdigit(aname[i])) { + ++i; + } + return i<aname.size() ? String(1, aname[i]) : ""; +} + +bool IsBondFeasible(const mol::AtomHandle& atom_a, + const mol::AtomHandle& atom_b) +{ + Real radii=0.0; + if (atom_a.GetRadius()>0.0) { + radii=atom_a.GetRadius(); + } else { + return false; + } + if (atom_b.GetRadius()>0.0) { + radii+=atom_b.GetRadius(); + } else { + return false; + } + Real len=geom::Length2(atom_a.GetPos()-atom_b.GetPos()); + Real lower_bound=radii*radii*0.0625; + Real upper_bound=lower_bound*6.0; + return (len<=upper_bound && len>=lower_bound); +} + +void Processor::ConnectResidues(mol::ResidueHandle rh, + mol::ResidueHandle next) const +{ + if (!next.IsValid() || !rh.IsValid()) { + return; + } + + mol::XCSEditor e=rh.GetEntity().EditXCS(mol::BUFFERED_EDIT); + + // check if both of the residues are able to form a peptide bond. + if (rh.IsPeptideLinking() && next.IsPeptideLinking()) { + // If we have an OXT then there is no peptide bond connecting the two + // residues. + if (rh.FindAtom("OXT")) + return; + mol::AtomHandle c=rh.FindAtom("C"); + mol::AtomHandle n=next.FindAtom("N"); + // Give subclasses a chance to give us their opinions on the feasibility of + // the peptide bond. + if (c.IsValid() && n.IsValid() && IsBondFeasible(c, n)) { + e.Connect(c, n, 1); + rh.SetIsProtein(true); + next.SetIsProtein(true); + } + } else if (rh.IsNucleotideLinking() && next.IsNucleotideLinking()) { + mol::AtomHandle c=rh.FindAtom("O3'"); + mol::AtomHandle n=next.FindAtom("P"); + if (c.IsValid() && n.IsValid() && IsBondFeasible(c, n)) { + e.Connect(c, n, 1); + } + } +} + + +mol::AtomHandle Processor::LocateAtom(const mol::AtomHandleList& ahl, + int ordinal) const +{ + if (ahl.empty()) + return mol::AtomHandle(); + const mol::AtomHandle* r_it=&ahl.back(); + if (static_cast<int>(ahl.size())>ordinal) { + r_it=&ahl.front()+ordinal; + } + while ((r_it>=&ahl.front()) && + (static_cast<int>(r_it->Impl()->GetState())>ordinal)) { + --r_it; + } + bool not_found=(r_it<&ahl.front() || + static_cast<int>(r_it->Impl()->GetState())!=ordinal); + return not_found ? mol::AtomHandle() : *r_it; +} + +void Processor::FillResidueProps(mol::ResidueHandle residue, + CompoundPtr compound) const +{ + residue.SetChemClass(compound->GetChemClass()); + residue.SetChemType(compound->GetChemType()); + residue.SetOneLetterCode(compound->GetOneLetterCode()); +} + +void Processor::ConnectAtomsOfResidue(mol::ResidueHandle rh, + CompoundPtr compound, + bool strict_hydrogens) const +{ + + //if (!compound) { + // dist_connect(this, rh.GetAtomList()); + // return; + //} + //if (unknown_atoms_) { + // dist_connect(this, rh.GetAtomList()); + // return; + //} + mol::XCSEditor e=rh.GetEntity().EditXCS(mol::BUFFERED_EDIT); + BondSpecList::const_iterator j=compound->GetBondSpecs().begin(); + mol::AtomHandleList atoms=rh.GetAtomList(); + for(; j!=compound->GetBondSpecs().end(); ++j) { + const BondSpec& bond=*j; + mol::AtomHandle a1=this->LocateAtom(atoms, bond.atom_one); + mol::AtomHandle a2=this->LocateAtom(atoms, bond.atom_two); + if (a1.IsValid() && a2.IsValid()) { + if (!this->GetCheckBondFeasibility()) { + if (strict_hydrogens && (a1.GetElement()=="H" || + a2.GetElement()=="D")) { + continue; + } + e.Connect(a1, a2, bond.order); + } else { + if (IsBondFeasible(a1, a2)) { + if (strict_hydrogens && (a1.GetElement()=="H" || + a2.GetElement()=="D")) { + continue; + } + e.Connect(a1, a2, bond.order); + } + } + } + } +} + + +void Processor::ReorderAtoms(mol::ResidueHandle residue, + CompoundPtr compound, + bool fix_element) const +{ + mol::impl::ResidueImplPtr impl=residue.Impl(); + mol::impl::AtomImplList::iterator i=impl->GetAtomList().begin(); + for (; i!=impl->GetAtomList().end(); ++i) { + mol::impl::AtomImplPtr atom=*i; + atom->SetState(std::numeric_limits<unsigned int>::max()); + int index=compound->GetAtomSpecIndex(atom->GetName()); + if (index==-1) { + atom->SetState(std::numeric_limits<unsigned int>::max()); + continue; + } + atom->SetState((compound->GetAtomSpecs())[index].ordinal); + // override element + if (fix_element) { + atom->SetElement((compound->GetAtomSpecs())[index].element); + } + } + std::sort(impl->GetAtomList().begin(), impl->GetAtomList().end(), + OrdinalAtomComp()); +} + +bool Processor::HasUnknownAtoms(mol::ResidueHandle res, + CompoundPtr compound, + bool strict_hydrogens) const +{ + AtomSpecList::const_iterator j=compound->GetAtomSpecs().begin(); + mol::AtomHandleList atoms=res.GetAtomList(); + mol::AtomHandleList::iterator i=atoms.begin(); + for (mol::AtomHandleList::iterator + i=atoms.begin(), e=atoms.end(); i!=e; ++i) { + if ((*i).Impl()->GetState()==std::numeric_limits<unsigned int>::max()) { + if (((*i).GetElement()=="H" || (*i).GetElement()=="D") && + !strict_hydrogens) { + continue; + } + return true; + } + } + return false; +} + +mol::AtomHandleList GetUnknownAtomsOfResidue(mol::ResidueHandle res, + CompoundPtr compound, + bool strict_hydrogens) +{ + mol::AtomHandleList atoms=res.GetAtomList(); + mol::AtomHandleList unks; + const AtomSpecList& atom_specs=compound->GetAtomSpecs(); + for (mol::AtomHandleList::const_iterator + j=atoms.begin(), e2=atoms.end(); j!=e2; ++j) { + bool found=false; + for (AtomSpecList::const_iterator + k=atom_specs.begin(), e3=atom_specs.end(); k!=e3; ++k) { + if (k->name==j->GetName() || k->alt_name==j->GetName()) { + found=true; + break; + } + } + if (!found) { + unks.push_back(*j); + } + } + return unks; +} + +void Processor::DistanceBasedConnect(mol::AtomHandle atom) const +{ + mol::EntityHandle ent=atom.GetEntity(); + mol::XCSEditor editor=ent.EditXCS(mol::BUFFERED_EDIT); + mol::AtomHandleList alist = ent.FindWithin(atom.GetPos(),4.0); + mol::ResidueHandle res_a=atom.GetResidue(); + for (mol::AtomHandleList::const_iterator it=alist.begin(), + e=alist.end();it!=e;++it) { + if (*it!=atom) { + if (IsBondFeasible(atom, *it)) { + if (Processor::AreResiduesConsecutive(res_a, it->GetResidue()) || + it->GetResidue()==res_a) { + editor.Connect(*it, atom); + } + } + } + } +} + +String StringFromConopAction(ConopAction action) { + switch (action) { + case CONOP_FATAL: + return "fatal"; + case CONOP_SILENT: + return "silent"; + case CONOP_REMOVE: + return "rm"; + case CONOP_REMOVE_RESIDUE: + return "rm_residue"; + case CONOP_REMOVE_ATOM: + return "rm_atom"; + case CONOP_WARN: + return "warn"; + } + assert(0 && "unhandled conop action"); + return "unhandled conop action"; +} + +bool Processor::AreResiduesConsecutive(mol::ResidueHandle r1, + mol::ResidueHandle r2) +{ + if (!r1 || !r2) return false; // protect against invalid handles + if(r1.GetChain() != r2.GetChain()) return false; + return r2.GetNumber().GetNum()==r1.GetNumber().GetNum()+1 || + r2.GetNumber().GetInsCode()==r1.GetNumber().NextInsertionCode().GetInsCode(); +} + + +String Processor::OptionsToString() const { + std::stringstream ss; + ss << "check_bond_feasibility=" << (check_bond_feasibility_ ? "True" : "False") << ", " + << "assign_torsions=" << (assign_torsions_ ? "True" : "False") << ", " + << "connect=" << (connect_ ? "True" : "False") << ", " + << "connect_peptides=" << (connect_aa_ ? "True" : "False") << ", " + << "zero_occ_treatment='" << StringFromConopAction(zero_occ_treatment_) << "'"; + return ss.str(); +} + + +}} diff --git a/modules/conop/src/processor.hh b/modules/conop/src/processor.hh new file mode 100644 index 0000000000000000000000000000000000000000..6001b5cbfa32b8610ef73753256515276f583f43 --- /dev/null +++ b/modules/conop/src/processor.hh @@ -0,0 +1,152 @@ +//------------------------------------------------------------------------------ +// 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_CONOP_PROCESSOR_HH +#define OST_CONOP_PROCESSOR_HH + +#include <ost/mol/entity_handle.hh> +#include "module_config.hh" +#include "diag.hh" +#include "compound.hh" +namespace ost { namespace conop { + +typedef enum { + PDB_DIALECT, + CHARMM_DIALECT +} Dialect; + +enum ConopAction { + CONOP_WARN = 0, + CONOP_SILENT, + CONOP_REMOVE, + CONOP_REMOVE_ATOM, + CONOP_REMOVE_RESIDUE, + CONOP_FATAL +}; + +class Processor; +typedef boost::shared_ptr<Processor> ProcessorPtr; +// the base class for all options +class DLLEXPORT_OST_CONOP Processor { +public: + DiagnosticsPtr Process(mol::EntityHandle ent, bool log_diags=true) const; + virtual ProcessorPtr Copy() const = 0; + virtual ~Processor() {} +protected: + virtual void DoProcess(DiagnosticsPtr diags, + mol::EntityHandle ent) const = 0; + virtual bool BeginProcessing(DiagnosticsPtr diags, + mol::EntityHandle ent) const { return true; } + virtual bool EndProcessing(DiagnosticsPtr diags, + mol::EntityHandle ent) const { return true; } + bool HasUnknownAtoms(mol::ResidueHandle residue, CompoundPtr compound, + bool strict_hydrogens) const; + void ReorderAtoms(mol::ResidueHandle residue, CompoundPtr compound, + bool fix_element) const; + void FillResidueProps(mol::ResidueHandle residue, CompoundPtr compound) const; + void ConnectAtomsOfResidue(mol::ResidueHandle residue, + CompoundPtr compound, bool strict_hydrogens) const; + void ConnectResidues(mol::ResidueHandle residue, mol::ResidueHandle next) const; + static bool AreResiduesConsecutive(mol::ResidueHandle a, mol::ResidueHandle b); + void DistanceBasedConnect(mol::AtomHandle atom) const; + mol::AtomHandle LocateAtom(const mol::AtomHandleList&, int ordinal) const; +public: + Processor(bool bf, bool at, bool cn, bool aa, ConopAction zo): check_bond_feasibility_(bf), + assign_torsions_(at), connect_(cn), connect_aa_(aa), + zero_occ_treatment_(zo) {} + Processor(): check_bond_feasibility_(false), + assign_torsions_(false), connect_(true), connect_aa_(true), + zero_occ_treatment_(CONOP_SILENT) {} + void SetConnect(bool connect) { + connect_ = connect; + } + + bool GetConnect() const { + return connect_; + } + void SetAssignTorsions(bool flag) { + assign_torsions_ = flag; + } + bool GetAssignTorsions() const { + return assign_torsions_; + } + + bool GetConnectAminoAcids() const { + return connect_aa_; + } + void SetConnectAminoAcids(bool c) { + connect_aa_ = c; + } + bool GetCheckBondFeasibility() const { + return check_bond_feasibility_; + } + + + void SetCheckBondFeasibility(bool flag) { + check_bond_feasibility_ = flag; + } + + + ConopAction GetZeroOccTreatment() const { + return zero_occ_treatment_; + } + + void SetZeroOccTreatment(ConopAction action) { + zero_occ_treatment_ = action; + } + virtual String ToString() const = 0; +protected: + String OptionsToString() const; +private: + bool check_bond_feasibility_; + bool assign_torsions_; + bool connect_; + bool connect_aa_; + ConopAction zero_occ_treatment_; +}; + +ConopAction DLLEXPORT_OST_CONOP ConopActionFromString(const String& name); + +String DLLEXPORT_OST_CONOP StringFromConopAction(ConopAction action); + + +/// \brief guess element of atom based on name and hetatm flag +String DLLEXPORT_OST_CONOP GuessAtomElement(const String& atom_name, bool hetatm); + +/// \brief guess chemclass based on atoms of residue +mol::ChemClass DLLEXPORT_OST_CONOP GuessChemClass(mol::ResidueHandle res); + +/// \brief assigns phi/psi/omega to all residues marked peptide-linking of +/// the chain +/// +/// Requires the atoms to be connected +void DLLEXPORT_OST_CONOP AssignBackboneTorsions(mol::ChainHandle chain); +void DLLEXPORT_OST_CONOP AssignBackboneTorsions(mol::ResidueHandleList residues); +void DLLEXPORT_OST_CONOP AssignBackboneTorsions(mol::ResidueHandle prev, + mol::ResidueHandle res, + mol::ResidueHandle next); + +bool DLLEXPORT_OST_CONOP IsBondFeasible(const mol::AtomHandle&, + const mol::AtomHandle&); +mol::AtomHandleList DLLEXPORT_OST_CONOP +GetUnknownAtomsOfResidue(mol::ResidueHandle residue, + CompoundPtr compound, + bool strict_hydrogens=false); +}} + +#endif diff --git a/modules/conop/src/rule_based.cc b/modules/conop/src/rule_based.cc new file mode 100644 index 0000000000000000000000000000000000000000..11dac390e7cec4d3a773a6080ff0852040a6944d --- /dev/null +++ b/modules/conop/src/rule_based.cc @@ -0,0 +1,193 @@ +//------------------------------------------------------------------------------ +// 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 <limits> +#include <ost/log.hh> +#include <ost/profile.hh> +#include <ost/mol/xcs_editor.hh> +#include <ost/mol/bond_handle.hh> +#include <ost/mol/torsion_handle.hh> +#include <ost/mol/impl/residue_impl.hh> +#include <ost/mol/impl/atom_impl.hh> +#include <ost/mol/residue_handle.hh> +#include "rule_based.hh" +#include "conop.hh" + +namespace ost { namespace conop { + + + +void RuleBasedProcessor::DoProcess(DiagnosticsPtr diags, + mol::EntityHandle ent) const +{ + Profile prof("RuleBasedProcessor::Process"); + mol::ChainHandleList chains=ent.GetChainList(); + for (mol::ChainHandleList::iterator + i = chains.begin(), e = chains.end(); i!= e; ++i) { + mol::ChainHandle& chain = *i; + mol::ResidueHandleList residues = chain.GetResidueList(); + mol::ResidueHandle prev; + for (mol::ResidueHandleList::iterator + j = residues.begin(), e2 = residues.end(); j != e2; ++j) { + mol::ResidueHandle residue = *j; + mol::AtomHandleList atoms_to_connect; + CompoundPtr compound = lib_->FindCompound(residue.GetName(), Compound::PDB); + if (!compound) { + // process unknown residue... + this->ProcessUnkResidue(diags, residue, atoms_to_connect); + for (mol::AtomHandleList::iterator k = atoms_to_connect.begin(), + e3=atoms_to_connect.end(); k!= e3; ++k) { + this->DistanceBasedConnect(*k); + } + continue; + } + this->ReorderAtoms(residue, compound, this->GetFixElement()); + bool unks = this->HasUnknownAtoms(residue, compound, + this->GetStrictHydrogens()); + if (unks) { + mol::AtomHandleList unk_atoms; + unk_atoms = GetUnknownAtomsOfResidue(residue, compound, + this->GetStrictHydrogens()); + this->ProcessUnkAtoms(diags, unk_atoms, atoms_to_connect); + residue.SetChemClass(mol::ChemClass(mol::ChemClass::UNKNOWN)); + residue.SetChemType(mol::ChemType(mol::ChemType::UNKNOWN)); + residue.SetOneLetterCode('?'); + } else { + this->FillResidueProps(residue, compound); + } + if (this->GetConnect()) { + this->ConnectAtomsOfResidue(residue, compound, + this->GetStrictHydrogens()); + if (this->GetConnectAminoAcids()) + this->ConnectResidues(prev, residue); + for (mol::AtomHandleList::iterator k = atoms_to_connect.begin(), + e3=atoms_to_connect.end(); k!= e3; ++k) { + this->DistanceBasedConnect(*k); + } + } + prev = residue; + } + if (residues.empty() || !this->GetAssignTorsions()) { + continue; + } + AssignBackboneTorsions(residues); + } +} + +void RuleBasedProcessor::ProcessUnkResidue(DiagnosticsPtr diags, + mol::ResidueHandle res, + mol::AtomHandleList& remaining_atoms) const +{ + mol::AtomHandleList atoms = res.GetAtomList(); + if (this->GetUnkResidueTreatment() == CONOP_SILENT || + this->GetUnkResidueTreatment() == CONOP_WARN) { + res.SetOneLetterCode('?'); + res.SetChemClass(mol::ChemClass(mol::ChemClass::UNKNOWN)); + for (mol::AtomHandleList::iterator i = atoms.begin(), + e = atoms.end(); i !=e; ++i) { + remaining_atoms.push_back(*i); + if (!Conopology::Instance().IsValidElement(i->GetElement())) + i->SetElement(GuessAtomElement(i->GetName(), i->IsHetAtom())); + } + } + // Don't do anything if treatment is set to SILENT + if (this->GetUnkResidueTreatment() == CONOP_SILENT) { + return; + } + switch (this->GetUnkResidueTreatment()) { + case CONOP_WARN: + diags->AddDiag(DIAG_UNK_RESIDUE, "unknown residue %0") + .AddResidue(res); + break; + case CONOP_FATAL: + throw DiagError(Diag(DIAG_UNK_RESIDUE, "unknown residue %0").AddResidue(res)); + break; + case CONOP_REMOVE_RESIDUE: + case CONOP_REMOVE: + diags->AddDiag(DIAG_UNK_RESIDUE, "removed unknown residue %0") + .AddResidue(res); + res.GetEntity().EditXCS().DeleteResidue(res); + return; + default: + assert(0 && "unhandled switch"); + } +} + +void RuleBasedProcessor::ProcessUnkAtoms(DiagnosticsPtr diags, + mol::AtomHandleList unks, + mol::AtomHandleList& remaining_atoms) const +{ + if (this->GetUnkAtomTreatment() == CONOP_SILENT || + this->GetUnkAtomTreatment() == CONOP_WARN) { + for (mol::AtomHandleList::iterator i = unks.begin(), + e = unks.end(); i !=e; ++i) { + remaining_atoms.push_back(*i); + if (!Conopology::Instance().IsValidElement(i->GetElement())) + i->SetElement(GuessAtomElement(i->GetName(), i->IsHetAtom())); + } + } + + // Don't do anything if treatment is set to SILENT + if (this->GetUnkAtomTreatment() == CONOP_SILENT) { + return; + } + + assert(!unks.empty() && "empty unk list"); + mol::XCSEditor edi = unks.front().GetEntity().EditXCS(); + for (mol::AtomHandleList::iterator + i = unks.begin(), e = unks.end(); i != e; ++i) { + switch (this->GetUnkAtomTreatment()) { + case CONOP_REMOVE_ATOM: + case CONOP_REMOVE: + edi.DeleteAtom(*i); + diags->AddDiag(DIAG_UNK_ATOM, "removed unknown atom %0 from residue %1") + .AddString(i->GetName()).AddResidue(i->GetResidue()); + break; + case CONOP_WARN: + diags->AddDiag(DIAG_UNK_ATOM, "residue %0 contains unknown atom %1") + .AddResidue(i->GetResidue()).AddString(i->GetName()); + break; + case CONOP_FATAL: + throw DiagError(Diag(DIAG_UNK_ATOM, "unknown atom %0").AddAtom(*i)); + break; + case CONOP_REMOVE_RESIDUE: + diags->AddDiag(DIAG_UNK_ATOM, "removed residue %0 with unknown atom %1") + .AddString(i->GetResidue().GetQualifiedName()) + .AddString(i->GetName()); + edi.DeleteResidue(i->GetResidue()); + return; + default: + assert(0 && "unhandled switch"); + } + } +} + +String RuleBasedProcessor::ToString() const { + std::stringstream ss; + ss << "RuleBasedProcesor(" << this->OptionsToString() + << ", fix_element=" << (fix_element_ ? "True" : "False") + << ", strict_hydrogens=" << (strict_hydrogens_ ? "True" : "False") + << ", unk_res_treatment='" << StringFromConopAction(unk_res_treatment_) + << ", unk_atom_treatment'=" << StringFromConopAction(unk_atom_treatment_) + << "')"; + return ss.str(); +} + + + +}} diff --git a/modules/conop/src/rule_based.hh b/modules/conop/src/rule_based.hh new file mode 100644 index 0000000000000000000000000000000000000000..4275d7e40e15dfdd7b088fe5ceae437a32095aaa --- /dev/null +++ b/modules/conop/src/rule_based.hh @@ -0,0 +1,104 @@ +//------------------------------------------------------------------------------ +// 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_CONOP_RULE_BASED_HH +#define OST_CONOP_RULE_BASED_HH + +#include <ost/mol/entity_handle.hh> +#include "compound_lib.hh" +#include "diag.hh" +#include "processor.hh" + +namespace ost { namespace conop { + +/// \brief returns all atoms not listed in the specifictaion of compound +mol::AtomHandleList DLLEXPORT_OST_CONOP GetUnknownAtoms(mol::ResidueHandle res, + CompoundPtr compound); + +class RuleBasedProcessor; + +typedef boost::shared_ptr<RuleBasedProcessor> RuleBasedProcessorPtr; + +class DLLEXPORT_OST_CONOP RuleBasedProcessor : public Processor { +public: + RuleBasedProcessor(CompoundLibPtr compound_lib): + lib_(compound_lib), fix_element_(true), strict_hydrogens_(false), + unk_res_treatment_(CONOP_WARN), unk_atom_treatment_(CONOP_WARN) + { + } + + RuleBasedProcessor(CompoundLibPtr compound_lib, bool fe, bool sh, ConopAction ur, + ConopAction ua, bool bf, bool at, bool cn, bool aa, ConopAction zo): + Processor(bf, at, cn, aa, zo), lib_(compound_lib), fix_element_(fe), + strict_hydrogens_(sh), unk_res_treatment_(ur), + unk_atom_treatment_(ua) {} + ConopAction GetUnkResidueTreatment() const { + return unk_res_treatment_; + } + + ConopAction GetUnkAtomTreatment() const { + return unk_atom_treatment_; + } + + bool GetFixElement() const { + return fix_element_; + } + void SetFixElement(bool flag) { + fix_element_ = flag; + } + bool GetStrictHydrogens() const { + return strict_hydrogens_; + } + + void SetStrictHydrogens(bool flag) { + strict_hydrogens_ = flag; + } + void SetUnkResidueTreatment(ConopAction action) { + unk_res_treatment_ = action; + } + + void SetUnkAtomTreatment(ConopAction action) { + unk_atom_treatment_ = action; + } + virtual ProcessorPtr Copy() const { + return ProcessorPtr(new RuleBasedProcessor(*this)); + } + + virtual String ToString() const; +protected: + void ProcessUnkResidue(DiagnosticsPtr diags, + mol::ResidueHandle res, + mol::AtomHandleList& remaining) const; + void ProcessUnkAtoms(DiagnosticsPtr diags, + mol::AtomHandleList unks, + mol::AtomHandleList& remaining) const; + virtual void DoProcess(DiagnosticsPtr diags, + mol::EntityHandle ent) const; +private: + CompoundLibPtr lib_; + bool fix_element_; + bool strict_hydrogens_; + ConopAction unk_res_treatment_; + ConopAction unk_atom_treatment_; +}; + + + +}} +#endif + diff --git a/modules/conop/src/rule_based_builder.cc b/modules/conop/src/rule_based_builder.cc deleted file mode 100644 index 529fbcbc65f29be69c4b6391b346e45d9f382e3a..0000000000000000000000000000000000000000 --- a/modules/conop/src/rule_based_builder.cc +++ /dev/null @@ -1,379 +0,0 @@ -//------------------------------------------------------------------------------ -// 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 -//------------------------------------------------------------------------------ -/* - Author: Marco Biasini - */ -#include <ost/log.hh> -#include <ost/geom/geom.hh> -#include <ost/mol/impl/atom_impl.hh> -#include <ost/mol/impl/residue_impl.hh> -#include <ost/conop/conop.hh> -#include <limits> -#include "rule_based_builder.hh" - - -namespace ost { namespace conop { - - -void RuleBasedBuilder::CompleteAtoms(mol::ResidueHandle rh) {} - -void RuleBasedBuilder::CheckResidueCompleteness(const mol::ResidueHandle& rh) -{ - this->LookupCompound(rh); - if (!last_compound_) { - mol::AtomHandleList atoms=rh.GetAtomList(); - for (mol::AtomHandleList::const_iterator i=atoms.begin(), - e=atoms.end(); i!=e; ++i) { - this->OnUnknownAtom(*i); - } - return; - } - this->ReorderAtoms(rh , last_compound_); - AtomSpecList::const_iterator j=last_compound_->GetAtomSpecs().begin(); - mol::AtomHandleList atoms=rh.GetAtomList(); - mol::AtomHandleList::iterator i=atoms.begin(); - for (; j!=last_compound_->GetAtomSpecs().end() && i!=atoms.end(); ++j) { - if ((*j).is_leaving || (*j).element=="H" || (*j).element=="D") - continue; - if ((*j).ordinal!=static_cast<int>((*i).Impl()->GetState())) { - this->OnMissingAtom(rh, (*j).name); - } else { - ++i; - } - } -} - -bool RuleBasedBuilder::HasUnknownAtoms(mol::ResidueHandle res) -{ - this->LookupCompound(res); - if (!last_compound_) { - return true; - } - this->ReorderAtoms(res, last_compound_); - AtomSpecList::const_iterator j=last_compound_->GetAtomSpecs().begin(); - mol::AtomHandleList atoms=res.GetAtomList(); - mol::AtomHandleList::iterator i=atoms.begin(); - for (mol::AtomHandleList::iterator - i=atoms.begin(), e=atoms.end(); i!=e; ++i) { - if ((*i).Impl()->GetState()==std::numeric_limits<unsigned int>::max()) { - if (((*i).GetElement()=="H" || (*i).GetElement()=="D") && - this->GetStrictHydrogenMode()==false) { - continue; - } - return true; - } - } - return false; -} - -mol::AtomHandleList RuleBasedBuilder::GetUnknownAtoms(mol::ResidueHandle res) -{ - mol::AtomHandleList unknown; - this->LookupCompound(res); - if (!last_compound_) { - return unknown; - } - mol::AtomHandleList atoms=res.GetAtomList(); - last_residue_=mol::ResidueHandle(); - this->ReorderAtoms(res, last_compound_); - AtomSpecList::const_iterator j=last_compound_->GetAtomSpecs().begin(); - mol::AtomHandleList::iterator i=atoms.begin(); - for (mol::AtomHandleList::iterator - i=atoms.begin(), e=atoms.end(); i!=e; ++i) { - if ((*i).Impl()->GetState()==std::numeric_limits<unsigned int>::max()) { - if (((*i).GetElement()=="H" || (*i).GetElement()=="D") && - this->GetStrictHydrogenMode()==false) { - continue; - } - unknown.push_back(*i); - } - } - return unknown; -} - -void RuleBasedBuilder::FillAtomProps(mol::AtomHandle atom, const AtomSpec& spec) -{ - Conopology& conop_inst=Conopology::Instance(); - if (!conop_inst.IsValidElement(atom.GetElement())) { - atom.SetElement(spec.element); - } -} - -void RuleBasedBuilder::FillResidueProps(mol::ResidueHandle residue) -{ - this->LookupCompound(residue); - if (!last_compound_) - return; - residue.SetChemClass(last_compound_->GetChemClass()); - residue.SetChemType(last_compound_->GetChemType()); - residue.SetOneLetterCode(last_compound_->GetOneLetterCode()); -}; - -struct OrdinalComp { - bool operator()(const mol::impl::AtomImplPtr& a, - const mol::impl::AtomImplPtr& b) const { - return a->GetState()<b->GetState(); - } -}; - - -void RuleBasedBuilder::LookupCompound(const mol::ResidueHandle& rh) -{ - Compound::Dialect dialect=this->GetDialect()==PDB_DIALECT ? Compound::PDB : Compound::CHARMM; - if ((last_compound_) && (rh.GetName()==last_compound_->GetID())) { - return; - } - last_compound_=compound_lib_->FindCompound(rh.GetName(), dialect); - if (!last_compound_ && this->GetDialect()!=PDB_DIALECT) { - last_compound_=compound_lib_->FindCompound(rh.GetName(), Compound::PDB); - } -} - -void RuleBasedBuilder::ReorderAtoms(mol::ResidueHandle residue, - CompoundPtr compound) -{ - if (last_residue_==residue) { - return; - } - mol::impl::ResidueImplPtr impl=residue.Impl(); - mol::impl::AtomImplList::iterator i=impl->GetAtomList().begin(); - for (; i!=impl->GetAtomList().end(); ++i) { - mol::impl::AtomImplPtr atom=*i; - atom->SetState(std::numeric_limits<unsigned int>::max()); - int index=compound->GetAtomSpecIndex(atom->GetName()); - if (index==-1) { - if (!this->OnUnknownAtom(mol::AtomHandle(atom))) { - atom->SetState(std::numeric_limits<unsigned int>::max()); - } - continue; - } - atom->SetState((compound->GetAtomSpecs())[index].ordinal); - } - std::sort(impl->GetAtomList().begin(), impl->GetAtomList().end(), - OrdinalComp()); - last_residue_=residue; - unknown_atoms_=this->HasUnknownAtoms(residue); - if (unknown_atoms_) { - LOG_WARNING("residue " << residue << " doesn't look like a standard " - << residue.GetKey() << " (" << compound->GetFormula() << ")"); - residue.SetChemClass(mol::ChemClass(mol::ChemClass::UNKNOWN)); - residue.SetChemType(mol::ChemType(mol::ChemType::UNKNOWN)); - residue.SetOneLetterCode('?'); - } -} - - - -mol::ResidueKey RuleBasedBuilder::IdentifyResidue(const mol::ResidueHandle& rh) -{ - LookupCompound(rh); - if (last_compound_) { - return last_compound_->GetID(); - } else { - return "UNK"; - } -} - -mol::AtomHandle RuleBasedBuilder::LocateAtom(const mol::AtomHandleList& ahl, - int ordinal) -{ - if (ahl.empty()) - return mol::AtomHandle(); - const mol::AtomHandle* r_it=&ahl.back(); - if (static_cast<int>(ahl.size())>ordinal) { - r_it=&ahl.front()+ordinal; - } - while ((r_it>=&ahl.front()) && - (static_cast<int>(r_it->Impl()->GetState())>ordinal)) { - --r_it; - } - bool not_found=(r_it<&ahl.front() || - static_cast<int>(r_it->Impl()->GetState())!=ordinal); - return not_found ? mol::AtomHandle() : *r_it; -} - - -inline void dist_connect(RuleBasedBuilder* b, mol::AtomHandleList atoms) -{ - for (mol::AtomHandleList::const_iterator i=atoms.begin(), - e=atoms.end(); i!=e; ++i) { - b->DistanceBasedConnect(*i); - } -} -void RuleBasedBuilder::ConnectAtomsOfResidue(mol::ResidueHandle rh) -{ - - LookupCompound(rh); - - if (!last_compound_) { - dist_connect(this, rh.GetAtomList()); - return; - } - this->ReorderAtoms(rh, last_compound_); - if (unknown_atoms_) { - dist_connect(this, rh.GetAtomList()); - return; - } - mol::XCSEditor e=rh.GetEntity().EditXCS(mol::BUFFERED_EDIT); - BondSpecList::const_iterator j=last_compound_->GetBondSpecs().begin(); - mol::AtomHandleList atoms=rh.GetAtomList(); - for(; j!=last_compound_->GetBondSpecs().end(); ++j) { - const BondSpec& bond=*j; - mol::AtomHandle a1=this->LocateAtom(atoms, bond.atom_one); - mol::AtomHandle a2=this->LocateAtom(atoms, bond.atom_two); - if (a1.IsValid() && a2.IsValid()) { - if (this->GetBondFeasibilityCheck()==false) { - if (this->GetStrictHydrogenMode() && (a1.GetElement()=="H" || - a2.GetElement()=="D")) { - continue; - } - e.Connect(a1, a2, bond.order); - } else { - if (IsBondFeasible(a1, a2)) { - if (this->GetStrictHydrogenMode() && (a1.GetElement()=="H" || - a2.GetElement()=="D")) { - continue; - } - e.Connect(a1, a2, bond.order); - } - } - } - } - for (mol::AtomHandleList::iterator i=atoms.begin(), e=atoms.end(); i!=e; ++i) { - if (((*i).GetElement()=="H" || (*i).GetElement()=="D") && - (*i).GetBondCount()==0) { - this->DistanceBasedConnect(*i); - } - } -} - -void RuleBasedBuilder::ConnectResidueToNext(mol::ResidueHandle rh, - mol::ResidueHandle next) -{ - if (!next.IsValid()) { - return; - } - - Compound::Dialect dialect=this->GetDialect()==PDB_DIALECT ? Compound::PDB : Compound::CHARMM; - - mol::XCSEditor e=rh.GetEntity().EditXCS(mol::BUFFERED_EDIT); - CompoundPtr mc=compound_lib_->FindCompound(rh.GetName(), dialect); - CompoundPtr nc=compound_lib_->FindCompound(next.GetName(), dialect); - if (!(mc && nc)) - return; - - // check if both of the residues are able to form a peptide bond. - if (mc->IsPeptideLinking() && nc->IsPeptideLinking()) { - // If we have an OXT then there is no peptide bond connecting the two - // residues. - if (rh.FindAtom("OXT")) - return; - mol::AtomHandle c=rh.FindAtom("C"); - mol::AtomHandle n=next.FindAtom("N"); - // Give subclasses a chance to give us their opinions on the feasibility of - // the peptide bond. - if (c.IsValid() && n.IsValid() && this->DoesPeptideBondExist(c, n)) { - e.Connect(c, n, 1); - rh.SetIsProtein(true); - next.SetIsProtein(true); - } - } else if (mc->IsNucleotideLinking() && nc->IsNucleotideLinking()) { - mol::AtomHandle c=rh.FindAtom("O3'"); - mol::AtomHandle n=next.FindAtom("P"); - if (c.IsValid() && n.IsValid() && this->IsBondFeasible(c, n)) { - e.Connect(c, n, 1); - } - } -} - - -void RuleBasedBuilder::AssignTorsions(mol::ChainHandle chain) -{ - if (chain.GetResidueCount()==0) - return; - std::vector<mol::ResidueHandle> rlist = chain.GetResidueList(); - mol::AtomHandleList atom_list = rlist[0].GetAtomList(); - for(unsigned int ri=0;ri<rlist.size();++ri) { - mol::ResidueHandle res=rlist[ri]; - this->AssignTorsionsToResidue(res); - } -} - -void RuleBasedBuilder::AssignTorsionsToResidue(mol::ResidueHandle residue) -{ - /// The only components having named torsions are the standard set of amino - /// acids, plus some of compounds derived from them such as selenium - /// methionine. Things are simplified a lot by only storing the torsions - /// of the side chains in the database. PHI, PSI and OMEGA torsions are - /// checked without a lookup in the database. - LookupCompound(residue); - if (!last_compound_) - return; - if (!last_compound_->IsPeptideLinking()) { - return; - } - Builder::AssignBackBoneTorsionsToResidue(residue); -} - -bool RuleBasedBuilder::IsResidueComplete(const mol::ResidueHandle& residue) -{ - LookupCompound(residue); - if (!last_compound_) - return false; - mol::AtomHandleList atoms=residue.GetAtomList(); - mol::AtomHandleList::iterator i=atoms.begin(); - for (AtomSpecList::const_iterator j=last_compound_->GetAtomSpecs().begin(), - e=last_compound_->GetAtomSpecs().end(); j!=e; ++j) { - if ((*j).is_leaving || (*j).element=="H" || (*j).element=="D") { - continue; - } - if (!(residue.FindAtom(j->name) || residue.FindAtom(j->alt_name))) { - return false; - } - } - return true; -} - - -void RuleBasedBuilder::FillAtomProps(mol::AtomHandle atom) -{ - LookupCompound(atom.GetResidue()); - if (!last_compound_) { - this->OnUnknownAtom(atom); - return; - } - int index=last_compound_->GetAtomSpecIndex(atom.GetName()); - if (index==-1) { - this->OnUnknownAtom(atom); - return; - } - const AtomSpec& atom_spec=last_compound_->GetAtomSpecs()[index]; - this->FillAtomProps(atom, atom_spec); -} - -bool RuleBasedBuilder::OnUnknownAtom(mol::AtomHandle atom) -{ - Conopology& conop_inst=Conopology::Instance(); - if (!conop_inst.IsValidElement(atom.GetElement())) { - atom.SetElement(Builder::GuessAtomElement(atom.GetName(), atom.IsHetAtom())); - } - return false; -} - -}} diff --git a/modules/conop/src/rule_based_builder.hh b/modules/conop/src/rule_based_builder.hh deleted file mode 100644 index 71a6fd03453ba9c418a6e39d8c0e011161f13be6..0000000000000000000000000000000000000000 --- a/modules/conop/src/rule_based_builder.hh +++ /dev/null @@ -1,150 +0,0 @@ -//------------------------------------------------------------------------------ -// 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_CONOP_RULE_BASED_BUILDER_HH -#define OST_CONOP_RULE_BASED_BUILDER_HH - -/* - Author: Marco Biasini - */ -#include <set> -#include <map> - -#include "builder.hh" -#include "compound_lib.hh" - -namespace ost { namespace conop { - -/// \brief Use library of chemical compounds to derive bonds and clean-up -/// structural problems -/// -/// \todo Sorting of the residues directly uses impl layer of the base module. -/// Would be much nicer if the order could be assigned in the public -/// interface and then tell the residues to sort the atoms in ascending -/// order. -class DLLEXPORT_OST_CONOP RuleBasedBuilder: public Builder { -public: - RuleBasedBuilder(const CompoundLibPtr& compound_lib) - : compound_lib_(compound_lib), last_compound_() { - } - - virtual void SetDialect(Dialect dialect) { - if (this->GetDialect()!=dialect) { - Builder::SetDialect(dialect); - last_compound_=CompoundPtr(); - compound_lib_->ClearCache(); - } - } - - /// \brief fill atom properties such as element and radius - virtual void FillAtomProps(mol::AtomHandle atom); - - virtual void CompleteAtoms(mol::ResidueHandle rh); - - /// \brief Check residue completeness - /// - /// By using the description of the chemical compound, the completeness of - /// the residue is verified. The method distinguishes between required atoms - /// and atoms that are optional, like OXT that is only present, if not peptide - /// bond is formed. Whenever an unknown atom is encountered, OnUnknownAtom() - /// is invoked. Subclasses of the RuleBasedBuilder may implement some - /// additional logic to deal with unknown atom. Likewise, whenever a required - /// atom is missing, OnMissingAtom() is invoked. Hydrogen atoms are not - /// considered as required by default - virtual void CheckResidueCompleteness(const mol::ResidueHandle& rh); - - /// \brief Identify residue by name - /// - /// Looks-up the residue in the database of chemical compounds and returns the - /// name of the residue or "UNK" if the residue has not been found in the - /// library. - virtual mol::ResidueKey IdentifyResidue(const mol::ResidueHandle& rh); - - - virtual void ConnectAtomsOfResidue(mol::ResidueHandle rh); - - /// \brief Connects the two residues together. - /// - /// Connections are established if both of the residues are peptide-linking - /// components and when PeptideBondExists() returns true. - /// \param rh - /// is the N-terminal partner donating the C and O for the peptide - /// bond. - /// \param next - /// is the C-terminal partner, donating the nitrogen to the bond. - virtual void ConnectResidueToNext(mol::ResidueHandle rh, - mol::ResidueHandle next); - /// \brief requires chemical types - virtual void AssignTorsions(mol::ChainHandle ch); - virtual void AssignTorsionsToResidue(mol::ResidueHandle residue); - /// \brief Invoked whenever an unkknown atom has been encountered during a - /// residue completeness check. - /// - /// The default implementation guesses the atom properties based on the name - /// and returns false, meaning that it should be treated as an unknown atom. - /// - /// Custom implementations of this method may delete the atom, or modify it. - /// \todo what should be done when the atom name is changed? it would be - /// neccessary to rerun CheckResidueCompleteness(). - virtual bool OnUnknownAtom(mol::AtomHandle atom); - - /// \brief Invoked whenever an atom is missing - /// - /// It is up to the overloaded method to deal with the missing atom, either - /// by ignoring it or by inserting a dummy atom. - virtual void OnMissingAtom(const mol::ResidueHandle& residue, - const String& atom_name) { } - - /// \brief Fill in missing information based on atom name. - virtual void FillAtomProps(mol::AtomHandle atom, const AtomSpec& spec); - - /// \brief Set residue properties such as chemical class - virtual void FillResidueProps(mol::ResidueHandle residue); - - mol::AtomHandleList GetUnknownAtoms(mol::ResidueHandle res); - - /// \brief Check whether the residue has all required atoms. This does not - /// include hydrogens and leaving atoms such as the terminal OXT. - virtual bool IsResidueComplete(const mol::ResidueHandle& residue); - - CompoundLibPtr GetCompoundLib() const { return compound_lib_; } - -private: - CompoundLibPtr compound_lib_; - CompoundPtr last_compound_; - mol::ResidueHandle last_residue_; - bool unknown_atoms_; - /// \brief whether the residue has unknown atoms - bool HasUnknownAtoms(mol::ResidueHandle res); - - void LookupCompound(const mol::ResidueHandle& rh); - /// Change internal order of atoms in residue to the order given by compound - void ReorderAtoms(mol::ResidueHandle residue, CompoundPtr compound); - - mol::AtomHandle LocateAtom(const mol::AtomHandleList& ahl, int ordinal); - - void AssignBackBoneTorsionsToResidue(mol::ResidueHandle residue); - -}; - -typedef boost::shared_ptr<RuleBasedBuilder> RuleBasedBuilderPtr; - -}} - -#endif - diff --git a/modules/conop/src/standard_compounds.cc b/modules/conop/src/standard_compounds.cc new file mode 100644 index 0000000000000000000000000000000000000000..7ce7302ffcc4f90e37a1f59e80595e54efbb4f24 --- /dev/null +++ b/modules/conop/src/standard_compounds.cc @@ -0,0 +1,1906 @@ +CompoundPtr MakeALACompound() { + CompoundPtr c( new Compound("ALA")); + c->SetOneLetterCode('A'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C3 H7 N O2"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "OXT", "OXT", "O", true, true), + AtomSpec(6, "H", "H", "H", false, true), + AtomSpec(7, "H2", "HN2", "H", true, true), + AtomSpec(8, "HA", "HA", "H", false, true), + AtomSpec(9, "HB1", "1HB", "H", false, true), + AtomSpec(10, "HB2", "2HB", "H", false, true), + AtomSpec(11, "HB3", "3HB", "H", false, true), + AtomSpec(12, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<13; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 6, 1), + BondSpec(0, 7, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 8, 1), + BondSpec(2, 3, 2), + BondSpec(2, 5, 1), + BondSpec(4, 9, 1), + BondSpec(4, 10, 1), + BondSpec(4, 11, 1), + BondSpec(5, 12, 1) + }; + for (int i=0; i<12; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeCYSCompound() { + CompoundPtr c( new Compound("CYS")); + c->SetOneLetterCode('C'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C3 H7 N O2 S"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "SG", "SG", "S", false, true), + AtomSpec(6, "OXT", "OXT", "O", true, true), + AtomSpec(7, "H", "H", "H", false, true), + AtomSpec(8, "H2", "HN2", "H", true, true), + AtomSpec(9, "HA", "HA", "H", false, true), + AtomSpec(10, "HB2", "1HB", "H", false, true), + AtomSpec(11, "HB3", "2HB", "H", false, true), + AtomSpec(12, "HG", "HG", "H", false, true), + AtomSpec(13, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<14; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 7, 1), + BondSpec(0, 8, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 9, 1), + BondSpec(2, 3, 2), + BondSpec(2, 6, 1), + BondSpec(4, 5, 1), + BondSpec(4, 10, 1), + BondSpec(4, 11, 1), + BondSpec(5, 12, 1), + BondSpec(6, 13, 1) + }; + for (int i=0; i<13; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeASPCompound() { + CompoundPtr c( new Compound("ASP")); + c->SetOneLetterCode('D'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C4 H7 N O4"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG", "CG", "C", false, true), + AtomSpec(6, "OD1", "OD1", "O", false, true), + AtomSpec(7, "OD2", "OD2", "O", false, true), + AtomSpec(8, "OXT", "OXT", "O", true, true), + AtomSpec(9, "H", "H", "H", false, true), + AtomSpec(10, "H2", "HN2", "H", true, true), + AtomSpec(11, "HA", "HA", "H", false, true), + AtomSpec(12, "HB2", "HB1", "H", false, true), + AtomSpec(13, "HB3", "HB2", "H", false, true), + AtomSpec(14, "HD2", "HD2", "H", false, true), + AtomSpec(15, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<16; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 9, 1), + BondSpec(0, 10, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 11, 1), + BondSpec(2, 3, 2), + BondSpec(2, 8, 1), + BondSpec(4, 5, 1), + BondSpec(4, 12, 1), + BondSpec(4, 13, 1), + BondSpec(5, 6, 2), + BondSpec(5, 7, 1), + BondSpec(7, 14, 1), + BondSpec(8, 15, 1) + }; + for (int i=0; i<15; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeGLUCompound() { + CompoundPtr c( new Compound("GLU")); + c->SetOneLetterCode('E'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C5 H9 N O4"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG", "CG", "C", false, true), + AtomSpec(6, "CD", "CD", "C", false, true), + AtomSpec(7, "OE1", "OE1", "O", false, true), + AtomSpec(8, "OE2", "OE2", "O", false, true), + AtomSpec(9, "OXT", "OXT", "O", true, true), + AtomSpec(10, "H", "H", "H", false, true), + AtomSpec(11, "H2", "HN2", "H", true, true), + AtomSpec(12, "HA", "HA", "H", false, true), + AtomSpec(13, "HB2", "HB1", "H", false, true), + AtomSpec(14, "HB3", "HB2", "H", false, true), + AtomSpec(15, "HG2", "HG1", "H", false, true), + AtomSpec(16, "HG3", "HG2", "H", false, true), + AtomSpec(17, "HE2", "HE2", "H", false, true), + AtomSpec(18, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<19; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 10, 1), + BondSpec(0, 11, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 12, 1), + BondSpec(2, 3, 2), + BondSpec(2, 9, 1), + BondSpec(4, 5, 1), + BondSpec(4, 13, 1), + BondSpec(4, 14, 1), + BondSpec(5, 6, 1), + BondSpec(5, 15, 1), + BondSpec(5, 16, 1), + BondSpec(6, 7, 2), + BondSpec(6, 8, 1), + BondSpec(8, 17, 1), + BondSpec(9, 18, 1) + }; + for (int i=0; i<18; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakePHECompound() { + CompoundPtr c( new Compound("PHE")); + c->SetOneLetterCode('F'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C9 H11 N O2"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG", "CG", "C", false, true), + AtomSpec(6, "CD1", "CD1", "C", false, true), + AtomSpec(7, "CD2", "CD2", "C", false, true), + AtomSpec(8, "CE1", "CE1", "C", false, true), + AtomSpec(9, "CE2", "CE2", "C", false, true), + AtomSpec(10, "CZ", "CZ", "C", false, true), + AtomSpec(11, "OXT", "OXT", "O", true, true), + AtomSpec(12, "H", "H", "H", false, true), + AtomSpec(13, "H2", "HN2", "H", true, true), + AtomSpec(14, "HA", "HA", "H", false, true), + AtomSpec(15, "HB2", "1HB", "H", false, true), + AtomSpec(16, "HB3", "2HB", "H", false, true), + AtomSpec(17, "HD1", "HD1", "H", false, true), + AtomSpec(18, "HD2", "HD2", "H", false, true), + AtomSpec(19, "HE1", "HE1", "H", false, true), + AtomSpec(20, "HE2", "HE2", "H", false, true), + AtomSpec(21, "HZ", "HZ", "H", false, true), + AtomSpec(22, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<23; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 12, 1), + BondSpec(0, 13, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 14, 1), + BondSpec(2, 3, 2), + BondSpec(2, 11, 1), + BondSpec(4, 5, 1), + BondSpec(4, 15, 1), + BondSpec(4, 16, 1), + BondSpec(5, 6, 2), + BondSpec(5, 7, 1), + BondSpec(6, 8, 1), + BondSpec(6, 17, 1), + BondSpec(7, 9, 2), + BondSpec(7, 18, 1), + BondSpec(8, 10, 2), + BondSpec(8, 19, 1), + BondSpec(9, 10, 1), + BondSpec(9, 20, 1), + BondSpec(10, 21, 1), + BondSpec(11, 22, 1) + }; + for (int i=0; i<23; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeGLYCompound() { + CompoundPtr c( new Compound("GLY")); + c->SetOneLetterCode('G'); + c->SetChemClass(mol::ChemClass('P')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C2 H5 N O2"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "OXT", "OXT", "O", true, true), + AtomSpec(5, "H", "H", "H", false, true), + AtomSpec(6, "H2", "HN2", "H", true, true), + AtomSpec(7, "HA2", "HA1", "H", false, true), + AtomSpec(8, "HA3", "HA2", "H", false, true), + AtomSpec(9, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<10; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 5, 1), + BondSpec(0, 6, 1), + BondSpec(1, 2, 1), + BondSpec(1, 7, 1), + BondSpec(1, 8, 1), + BondSpec(2, 3, 2), + BondSpec(2, 4, 1), + BondSpec(4, 9, 1) + }; + for (int i=0; i<9; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeHISCompound() { + CompoundPtr c( new Compound("HIS")); + c->SetOneLetterCode('H'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C6 H10 N3 O2"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG", "CG", "C", false, true), + AtomSpec(6, "ND1", "ND1", "N", false, true), + AtomSpec(7, "CD2", "CD2", "C", false, true), + AtomSpec(8, "CE1", "CE1", "C", false, true), + AtomSpec(9, "NE2", "NE2", "N", false, true), + AtomSpec(10, "OXT", "OXT", "O", true, true), + AtomSpec(11, "H", "H", "H", false, true), + AtomSpec(12, "H2", "HN2", "H", true, true), + AtomSpec(13, "HA", "HA", "H", false, true), + AtomSpec(14, "HB2", "1HB", "H", false, true), + AtomSpec(15, "HB3", "2HB", "H", false, true), + AtomSpec(16, "HD1", "HD1", "H", false, true), + AtomSpec(17, "HD2", "HD2", "H", false, true), + AtomSpec(18, "HE1", "HE1", "H", false, true), + AtomSpec(19, "HE2", "HE2", "H", false, true), + AtomSpec(20, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<21; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 11, 1), + BondSpec(0, 12, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 13, 1), + BondSpec(2, 3, 2), + BondSpec(2, 10, 1), + BondSpec(4, 5, 1), + BondSpec(4, 14, 1), + BondSpec(4, 15, 1), + BondSpec(5, 6, 1), + BondSpec(5, 7, 2), + BondSpec(6, 8, 2), + BondSpec(6, 16, 1), + BondSpec(7, 9, 1), + BondSpec(7, 17, 1), + BondSpec(8, 9, 1), + BondSpec(8, 18, 1), + BondSpec(9, 19, 1), + BondSpec(10, 20, 1) + }; + for (int i=0; i<21; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeILECompound() { + CompoundPtr c( new Compound("ILE")); + c->SetOneLetterCode('I'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C6 H13 N O2"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG1", "CG1", "C", false, true), + AtomSpec(6, "CG2", "CG2", "C", false, true), + AtomSpec(7, "CD1", "CD1", "C", false, true), + AtomSpec(8, "OXT", "OXT", "O", true, true), + AtomSpec(9, "H", "H", "H", false, true), + AtomSpec(10, "H2", "HN2", "H", true, true), + AtomSpec(11, "HA", "HA", "H", false, true), + AtomSpec(12, "HB", "HB", "H", false, true), + AtomSpec(13, "HG12", "1HG1", "H", false, true), + AtomSpec(14, "HG13", "2HG1", "H", false, true), + AtomSpec(15, "HG21", "1HG2", "H", false, true), + AtomSpec(16, "HG22", "2HG2", "H", false, true), + AtomSpec(17, "HG23", "3HG2", "H", false, true), + AtomSpec(18, "HD11", "1HD1", "H", false, true), + AtomSpec(19, "HD12", "2HD1", "H", false, true), + AtomSpec(20, "HD13", "3HD1", "H", false, true), + AtomSpec(21, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<22; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 9, 1), + BondSpec(0, 10, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 11, 1), + BondSpec(2, 3, 2), + BondSpec(2, 8, 1), + BondSpec(4, 5, 1), + BondSpec(4, 6, 1), + BondSpec(4, 12, 1), + BondSpec(5, 7, 1), + BondSpec(5, 13, 1), + BondSpec(5, 14, 1), + BondSpec(6, 15, 1), + BondSpec(6, 16, 1), + BondSpec(6, 17, 1), + BondSpec(7, 18, 1), + BondSpec(7, 19, 1), + BondSpec(7, 20, 1), + BondSpec(8, 21, 1) + }; + for (int i=0; i<21; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeLYSCompound() { + CompoundPtr c( new Compound("LYS")); + c->SetOneLetterCode('K'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C6 H15 N2 O2"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG", "CG", "C", false, true), + AtomSpec(6, "CD", "CD", "C", false, true), + AtomSpec(7, "CE", "CE", "C", false, true), + AtomSpec(8, "NZ", "NZ", "N", false, true), + AtomSpec(9, "OXT", "OXT", "O", true, true), + AtomSpec(10, "H", "H", "H", false, true), + AtomSpec(11, "H2", "HN2", "H", true, true), + AtomSpec(12, "HA", "HA", "H", false, true), + AtomSpec(13, "HB2", "1HB", "H", false, true), + AtomSpec(14, "HB3", "2HB", "H", false, true), + AtomSpec(15, "HG2", "1HG", "H", false, true), + AtomSpec(16, "HG3", "2HG", "H", false, true), + AtomSpec(17, "HD2", "1HD", "H", false, true), + AtomSpec(18, "HD3", "2HD", "H", false, true), + AtomSpec(19, "HE2", "1HE", "H", false, true), + AtomSpec(20, "HE3", "2HE", "H", false, true), + AtomSpec(21, "HZ1", "1HZ", "H", false, true), + AtomSpec(22, "HZ2", "2HZ", "H", false, true), + AtomSpec(23, "HZ3", "3HZ", "H", false, true), + AtomSpec(24, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<25; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 10, 1), + BondSpec(0, 11, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 12, 1), + BondSpec(2, 3, 2), + BondSpec(2, 9, 1), + BondSpec(4, 5, 1), + BondSpec(4, 13, 1), + BondSpec(4, 14, 1), + BondSpec(5, 6, 1), + BondSpec(5, 15, 1), + BondSpec(5, 16, 1), + BondSpec(6, 7, 1), + BondSpec(6, 17, 1), + BondSpec(6, 18, 1), + BondSpec(7, 8, 1), + BondSpec(7, 19, 1), + BondSpec(7, 20, 1), + BondSpec(8, 21, 1), + BondSpec(8, 22, 1), + BondSpec(8, 23, 1), + BondSpec(9, 24, 1) + }; + for (int i=0; i<24; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeLEUCompound() { + CompoundPtr c( new Compound("LEU")); + c->SetOneLetterCode('L'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C6 H13 N O2"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG", "CG", "C", false, true), + AtomSpec(6, "CD1", "CD1", "C", false, true), + AtomSpec(7, "CD2", "CD2", "C", false, true), + AtomSpec(8, "OXT", "OXT", "O", true, true), + AtomSpec(9, "H", "H", "H", false, true), + AtomSpec(10, "H2", "HN2", "H", true, true), + AtomSpec(11, "HA", "HA", "H", false, true), + AtomSpec(12, "HB2", "1HB", "H", false, true), + AtomSpec(13, "HB3", "2HB", "H", false, true), + AtomSpec(14, "HG", "HG", "H", false, true), + AtomSpec(15, "HD11", "1HD1", "H", false, true), + AtomSpec(16, "HD12", "2HD1", "H", false, true), + AtomSpec(17, "HD13", "3HD1", "H", false, true), + AtomSpec(18, "HD21", "1HD2", "H", false, true), + AtomSpec(19, "HD22", "2HD2", "H", false, true), + AtomSpec(20, "HD23", "3HD2", "H", false, true), + AtomSpec(21, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<22; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 9, 1), + BondSpec(0, 10, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 11, 1), + BondSpec(2, 3, 2), + BondSpec(2, 8, 1), + BondSpec(4, 5, 1), + BondSpec(4, 12, 1), + BondSpec(4, 13, 1), + BondSpec(5, 6, 1), + BondSpec(5, 7, 1), + BondSpec(5, 14, 1), + BondSpec(6, 15, 1), + BondSpec(6, 16, 1), + BondSpec(6, 17, 1), + BondSpec(7, 18, 1), + BondSpec(7, 19, 1), + BondSpec(7, 20, 1), + BondSpec(8, 21, 1) + }; + for (int i=0; i<21; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeMETCompound() { + CompoundPtr c( new Compound("MET")); + c->SetOneLetterCode('M'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C5 H11 N O2 S"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG", "CG", "C", false, true), + AtomSpec(6, "SD", "SD", "S", false, true), + AtomSpec(7, "CE", "CE", "C", false, true), + AtomSpec(8, "OXT", "OXT", "O", true, true), + AtomSpec(9, "H", "H", "H", false, true), + AtomSpec(10, "H2", "HN2", "H", true, true), + AtomSpec(11, "HA", "HA", "H", false, true), + AtomSpec(12, "HB2", "1HB", "H", false, true), + AtomSpec(13, "HB3", "2HB", "H", false, true), + AtomSpec(14, "HG2", "1HG", "H", false, true), + AtomSpec(15, "HG3", "2HG", "H", false, true), + AtomSpec(16, "HE1", "1HE", "H", false, true), + AtomSpec(17, "HE2", "2HE", "H", false, true), + AtomSpec(18, "HE3", "3HE", "H", false, true), + AtomSpec(19, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<20; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 9, 1), + BondSpec(0, 10, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 11, 1), + BondSpec(2, 3, 2), + BondSpec(2, 8, 1), + BondSpec(4, 5, 1), + BondSpec(4, 12, 1), + BondSpec(4, 13, 1), + BondSpec(5, 6, 1), + BondSpec(5, 14, 1), + BondSpec(5, 15, 1), + BondSpec(6, 7, 1), + BondSpec(7, 16, 1), + BondSpec(7, 17, 1), + BondSpec(7, 18, 1), + BondSpec(8, 19, 1) + }; + for (int i=0; i<19; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeASNCompound() { + CompoundPtr c( new Compound("ASN")); + c->SetOneLetterCode('N'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C4 H8 N2 O3"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG", "CG", "C", false, true), + AtomSpec(6, "OD1", "OD1", "O", false, true), + AtomSpec(7, "ND2", "ND2", "N", true, true), + AtomSpec(8, "OXT", "OXT", "O", true, true), + AtomSpec(9, "H", "H", "H", false, true), + AtomSpec(10, "H2", "HN2", "H", true, true), + AtomSpec(11, "HA", "HA", "H", false, true), + AtomSpec(12, "HB2", "HB1", "H", false, true), + AtomSpec(13, "HB3", "HB2", "H", false, true), + AtomSpec(14, "HD21", "HD21", "H", true, true), + AtomSpec(15, "HD22", "HD22", "H", true, true), + AtomSpec(16, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<17; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 9, 1), + BondSpec(0, 10, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 11, 1), + BondSpec(2, 3, 2), + BondSpec(2, 8, 1), + BondSpec(4, 5, 1), + BondSpec(4, 12, 1), + BondSpec(4, 13, 1), + BondSpec(5, 6, 2), + BondSpec(5, 7, 1), + BondSpec(7, 14, 1), + BondSpec(7, 15, 1), + BondSpec(8, 16, 1) + }; + for (int i=0; i<16; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakePROCompound() { + CompoundPtr c( new Compound("PRO")); + c->SetOneLetterCode('P'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C5 H9 N O2"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG", "CG", "C", false, true), + AtomSpec(6, "CD", "CD", "C", false, true), + AtomSpec(7, "OXT", "OXT", "O", true, true), + AtomSpec(8, "H", "HT1", "H", true, true), + AtomSpec(9, "HA", "HA", "H", false, true), + AtomSpec(10, "HB2", "1HB", "H", false, true), + AtomSpec(11, "HB3", "2HB", "H", false, true), + AtomSpec(12, "HG2", "1HG", "H", false, true), + AtomSpec(13, "HG3", "2HG", "H", false, true), + AtomSpec(14, "HD2", "1HD", "H", false, true), + AtomSpec(15, "HD3", "2HD", "H", false, true), + AtomSpec(16, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<17; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 6, 1), + BondSpec(0, 8, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 9, 1), + BondSpec(2, 3, 2), + BondSpec(2, 7, 1), + BondSpec(4, 5, 1), + BondSpec(4, 10, 1), + BondSpec(4, 11, 1), + BondSpec(5, 6, 1), + BondSpec(5, 12, 1), + BondSpec(5, 13, 1), + BondSpec(6, 14, 1), + BondSpec(6, 15, 1), + BondSpec(7, 16, 1) + }; + for (int i=0; i<17; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeGLNCompound() { + CompoundPtr c( new Compound("GLN")); + c->SetOneLetterCode('Q'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C5 H10 N2 O3"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG", "CG", "C", false, true), + AtomSpec(6, "CD", "CD", "C", false, true), + AtomSpec(7, "OE1", "OE1", "O", false, true), + AtomSpec(8, "NE2", "NE2", "N", false, true), + AtomSpec(9, "OXT", "OXT", "O", true, true), + AtomSpec(10, "H", "H", "H", false, true), + AtomSpec(11, "H2", "HN2", "H", true, true), + AtomSpec(12, "HA", "HA", "H", false, true), + AtomSpec(13, "HB2", "1HB", "H", false, true), + AtomSpec(14, "HB3", "2HB", "H", false, true), + AtomSpec(15, "HG2", "1HG", "H", false, true), + AtomSpec(16, "HG3", "2HG", "H", false, true), + AtomSpec(17, "HE21", "1HE2", "H", false, true), + AtomSpec(18, "HE22", "2HE2", "H", false, true), + AtomSpec(19, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<20; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 10, 1), + BondSpec(0, 11, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 12, 1), + BondSpec(2, 3, 2), + BondSpec(2, 9, 1), + BondSpec(4, 5, 1), + BondSpec(4, 13, 1), + BondSpec(4, 14, 1), + BondSpec(5, 6, 1), + BondSpec(5, 15, 1), + BondSpec(5, 16, 1), + BondSpec(6, 7, 2), + BondSpec(6, 8, 1), + BondSpec(8, 17, 1), + BondSpec(8, 18, 1), + BondSpec(9, 19, 1) + }; + for (int i=0; i<19; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeARGCompound() { + CompoundPtr c( new Compound("ARG")); + c->SetOneLetterCode('R'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C6 H15 N4 O2"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG", "CG", "C", false, true), + AtomSpec(6, "CD", "CD", "C", false, true), + AtomSpec(7, "NE", "NE", "N", false, true), + AtomSpec(8, "CZ", "CZ", "C", false, true), + AtomSpec(9, "NH1", "NH1", "N", false, true), + AtomSpec(10, "NH2", "NH2", "N", false, true), + AtomSpec(11, "OXT", "OXT", "O", true, true), + AtomSpec(12, "H", "H", "H", false, true), + AtomSpec(13, "H2", "HN2", "H", true, true), + AtomSpec(14, "HA", "HA", "H", false, true), + AtomSpec(15, "HB2", "1HB", "H", false, true), + AtomSpec(16, "HB3", "2HB", "H", false, true), + AtomSpec(17, "HG2", "1HG", "H", false, true), + AtomSpec(18, "HG3", "2HG", "H", false, true), + AtomSpec(19, "HD2", "1HD", "H", false, true), + AtomSpec(20, "HD3", "2HD", "H", false, true), + AtomSpec(21, "HE", "HE", "H", false, true), + AtomSpec(22, "HH11", "1HH1", "H", false, true), + AtomSpec(23, "HH12", "2HH1", "H", false, true), + AtomSpec(24, "HH21", "1HH2", "H", false, true), + AtomSpec(25, "HH22", "2HH2", "H", false, true), + AtomSpec(26, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<27; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 12, 1), + BondSpec(0, 13, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 14, 1), + BondSpec(2, 3, 2), + BondSpec(2, 11, 1), + BondSpec(4, 5, 1), + BondSpec(4, 15, 1), + BondSpec(4, 16, 1), + BondSpec(5, 6, 1), + BondSpec(5, 17, 1), + BondSpec(5, 18, 1), + BondSpec(6, 7, 1), + BondSpec(6, 19, 1), + BondSpec(6, 20, 1), + BondSpec(7, 8, 1), + BondSpec(7, 21, 1), + BondSpec(8, 9, 1), + BondSpec(8, 10, 2), + BondSpec(9, 22, 1), + BondSpec(9, 23, 1), + BondSpec(10, 24, 1), + BondSpec(10, 25, 1), + BondSpec(11, 26, 1) + }; + for (int i=0; i<26; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeSERCompound() { + CompoundPtr c( new Compound("SER")); + c->SetOneLetterCode('S'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C3 H7 N O3"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "OG", "OG", "O", false, true), + AtomSpec(6, "OXT", "OXT", "O", true, true), + AtomSpec(7, "H", "H", "H", false, true), + AtomSpec(8, "H2", "HN2", "H", true, true), + AtomSpec(9, "HA", "HA", "H", false, true), + AtomSpec(10, "HB2", "1HB", "H", false, true), + AtomSpec(11, "HB3", "2HB", "H", false, true), + AtomSpec(12, "HG", "HG", "H", false, true), + AtomSpec(13, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<14; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 7, 1), + BondSpec(0, 8, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 9, 1), + BondSpec(2, 3, 2), + BondSpec(2, 6, 1), + BondSpec(4, 5, 1), + BondSpec(4, 10, 1), + BondSpec(4, 11, 1), + BondSpec(5, 12, 1), + BondSpec(6, 13, 1) + }; + for (int i=0; i<13; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeTHRCompound() { + CompoundPtr c( new Compound("THR")); + c->SetOneLetterCode('T'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C4 H9 N O3"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "OG1", "OG1", "O", false, true), + AtomSpec(6, "CG2", "CG2", "C", false, true), + AtomSpec(7, "OXT", "OXT", "O", true, true), + AtomSpec(8, "H", "H", "H", false, true), + AtomSpec(9, "H2", "HN2", "H", true, true), + AtomSpec(10, "HA", "HA", "H", false, true), + AtomSpec(11, "HB", "HB", "H", false, true), + AtomSpec(12, "HG1", "HG1", "H", false, true), + AtomSpec(13, "HG21", "1HG2", "H", false, true), + AtomSpec(14, "HG22", "2HG2", "H", false, true), + AtomSpec(15, "HG23", "3HG2", "H", false, true), + AtomSpec(16, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<17; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 8, 1), + BondSpec(0, 9, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 10, 1), + BondSpec(2, 3, 2), + BondSpec(2, 7, 1), + BondSpec(4, 5, 1), + BondSpec(4, 6, 1), + BondSpec(4, 11, 1), + BondSpec(5, 12, 1), + BondSpec(6, 13, 1), + BondSpec(6, 14, 1), + BondSpec(6, 15, 1), + BondSpec(7, 16, 1) + }; + for (int i=0; i<16; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeVALCompound() { + CompoundPtr c( new Compound("VAL")); + c->SetOneLetterCode('V'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C5 H11 N O2"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG1", "CG1", "C", false, true), + AtomSpec(6, "CG2", "CG2", "C", false, true), + AtomSpec(7, "OXT", "OXT", "O", true, true), + AtomSpec(8, "H", "H", "H", false, true), + AtomSpec(9, "H2", "HN2", "H", true, true), + AtomSpec(10, "HA", "HA", "H", false, true), + AtomSpec(11, "HB", "HB", "H", false, true), + AtomSpec(12, "HG11", "1HG1", "H", false, true), + AtomSpec(13, "HG12", "2HG1", "H", false, true), + AtomSpec(14, "HG13", "3HG1", "H", false, true), + AtomSpec(15, "HG21", "1HG2", "H", false, true), + AtomSpec(16, "HG22", "2HG2", "H", false, true), + AtomSpec(17, "HG23", "3HG2", "H", false, true), + AtomSpec(18, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<19; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 8, 1), + BondSpec(0, 9, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 10, 1), + BondSpec(2, 3, 2), + BondSpec(2, 7, 1), + BondSpec(4, 5, 1), + BondSpec(4, 6, 1), + BondSpec(4, 11, 1), + BondSpec(5, 12, 1), + BondSpec(5, 13, 1), + BondSpec(5, 14, 1), + BondSpec(6, 15, 1), + BondSpec(6, 16, 1), + BondSpec(6, 17, 1), + BondSpec(7, 18, 1) + }; + for (int i=0; i<18; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeTRPCompound() { + CompoundPtr c( new Compound("TRP")); + c->SetOneLetterCode('W'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C11 H12 N2 O2"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG", "CG", "C", false, true), + AtomSpec(6, "CD1", "CD1", "C", false, true), + AtomSpec(7, "CD2", "CD2", "C", false, true), + AtomSpec(8, "NE1", "NE1", "N", false, true), + AtomSpec(9, "CE2", "CE2", "C", false, true), + AtomSpec(10, "CE3", "CE3", "C", false, true), + AtomSpec(11, "CZ2", "CZ2", "C", false, true), + AtomSpec(12, "CZ3", "CZ3", "C", false, true), + AtomSpec(13, "CH2", "CH2", "C", false, true), + AtomSpec(14, "OXT", "OXT", "O", true, true), + AtomSpec(15, "H", "H", "H", false, true), + AtomSpec(16, "H2", "HN2", "H", true, true), + AtomSpec(17, "HA", "HA", "H", false, true), + AtomSpec(18, "HB2", "1HB", "H", false, true), + AtomSpec(19, "HB3", "2HB", "H", false, true), + AtomSpec(20, "HD1", "HD1", "H", false, true), + AtomSpec(21, "HE1", "HE1", "H", false, true), + AtomSpec(22, "HE3", "HE3", "H", false, true), + AtomSpec(23, "HZ2", "HZ2", "H", false, true), + AtomSpec(24, "HZ3", "HZ3", "H", false, true), + AtomSpec(25, "HH2", "HH2", "H", false, true), + AtomSpec(26, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<27; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 15, 1), + BondSpec(0, 16, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 17, 1), + BondSpec(2, 3, 2), + BondSpec(2, 14, 1), + BondSpec(4, 5, 1), + BondSpec(4, 18, 1), + BondSpec(4, 19, 1), + BondSpec(5, 6, 2), + BondSpec(5, 7, 1), + BondSpec(6, 8, 1), + BondSpec(6, 20, 1), + BondSpec(7, 9, 2), + BondSpec(7, 10, 1), + BondSpec(8, 9, 1), + BondSpec(8, 21, 1), + BondSpec(9, 11, 1), + BondSpec(10, 12, 2), + BondSpec(10, 22, 1), + BondSpec(11, 13, 2), + BondSpec(11, 23, 1), + BondSpec(12, 13, 1), + BondSpec(12, 24, 1), + BondSpec(13, 25, 1), + BondSpec(14, 26, 1) + }; + for (int i=0; i<28; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeTYRCompound() { + CompoundPtr c( new Compound("TYR")); + c->SetOneLetterCode('Y'); + c->SetChemClass(mol::ChemClass('L')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C9 H11 N O3"); + AtomSpec atoms[] = { + AtomSpec(0, "N", "N", "N", false, true), + AtomSpec(1, "CA", "CA", "C", false, true), + AtomSpec(2, "C", "C", "C", false, true), + AtomSpec(3, "O", "O", "O", false, true), + AtomSpec(4, "CB", "CB", "C", false, true), + AtomSpec(5, "CG", "CG", "C", false, true), + AtomSpec(6, "CD1", "CD1", "C", false, true), + AtomSpec(7, "CD2", "CD2", "C", false, true), + AtomSpec(8, "CE1", "CE1", "C", false, true), + AtomSpec(9, "CE2", "CE2", "C", false, true), + AtomSpec(10, "CZ", "CZ", "C", false, true), + AtomSpec(11, "OH", "OH", "O", false, true), + AtomSpec(12, "OXT", "OXT", "O", true, true), + AtomSpec(13, "H", "H", "H", false, true), + AtomSpec(14, "H2", "HN2", "H", true, true), + AtomSpec(15, "HA", "HA", "H", false, true), + AtomSpec(16, "HB2", "1HB", "H", false, true), + AtomSpec(17, "HB3", "2HB", "H", false, true), + AtomSpec(18, "HD1", "HD1", "H", false, true), + AtomSpec(19, "HD2", "HD2", "H", false, true), + AtomSpec(20, "HE1", "HE1", "H", false, true), + AtomSpec(21, "HE2", "HE2", "H", false, true), + AtomSpec(22, "HH", "HH", "H", false, true), + AtomSpec(23, "HXT", "HXT", "H", true, true) + }; + for (int i=0; i<24; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 13, 1), + BondSpec(0, 14, 1), + BondSpec(1, 2, 1), + BondSpec(1, 4, 1), + BondSpec(1, 15, 1), + BondSpec(2, 3, 2), + BondSpec(2, 12, 1), + BondSpec(4, 5, 1), + BondSpec(4, 16, 1), + BondSpec(4, 17, 1), + BondSpec(5, 6, 2), + BondSpec(5, 7, 1), + BondSpec(6, 8, 1), + BondSpec(6, 18, 1), + BondSpec(7, 9, 2), + BondSpec(7, 19, 1), + BondSpec(8, 10, 2), + BondSpec(8, 20, 1), + BondSpec(9, 10, 1), + BondSpec(9, 21, 1), + BondSpec(10, 11, 1), + BondSpec(11, 22, 1), + BondSpec(12, 23, 1) + }; + for (int i=0; i<24; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeGCompound() { + CompoundPtr c( new Compound("G")); + c->SetOneLetterCode('Y'); + c->SetChemClass(mol::ChemClass('R')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C10 H14 N5 O8 P"); + AtomSpec atoms[] = { + AtomSpec(0, "OP3", "O3P", "O", true, true), + AtomSpec(1, "P", "P", "P", false, true), + AtomSpec(2, "OP1", "O1P", "O", false, true), + AtomSpec(3, "OP2", "O2P", "O", false, true), + AtomSpec(4, "O5'", "O5*", "O", false, true), + AtomSpec(5, "C5'", "C5*", "C", false, true), + AtomSpec(6, "C4'", "C4*", "C", false, true), + AtomSpec(7, "O4'", "O4*", "O", false, true), + AtomSpec(8, "C3'", "C3*", "C", false, true), + AtomSpec(9, "O3'", "O3*", "O", false, true), + AtomSpec(10, "C2'", "C2*", "C", false, true), + AtomSpec(11, "O2'", "O2*", "O", false, true), + AtomSpec(12, "C1'", "C1*", "C", false, true), + AtomSpec(13, "N9", "N9", "N", false, true), + AtomSpec(14, "C8", "C8", "C", false, true), + AtomSpec(15, "N7", "N7", "N", false, true), + AtomSpec(16, "C5", "C5", "C", false, true), + AtomSpec(17, "C6", "C6", "C", false, true), + AtomSpec(18, "O6", "O6", "O", false, true), + AtomSpec(19, "N1", "N1", "N", false, true), + AtomSpec(20, "C2", "C2", "C", false, true), + AtomSpec(21, "N2", "N2", "N", false, true), + AtomSpec(22, "N3", "N3", "N", false, true), + AtomSpec(23, "C4", "C4", "C", false, true), + AtomSpec(24, "HOP3", "3HOP", "H", false, true), + AtomSpec(25, "HOP2", "2HOP", "H", false, true), + AtomSpec(26, "H5'", "1H5*", "H", false, true), + AtomSpec(27, "H5''", "2H5*", "H", false, true), + AtomSpec(28, "H4'", "H4*", "H", false, true), + AtomSpec(29, "H3'", "H3*", "H", false, true), + AtomSpec(30, "HO3'", "H3T", "H", true, true), + AtomSpec(31, "H2'", "H2*", "H", false, true), + AtomSpec(32, "HO2'", "2HO*", "H", false, true), + AtomSpec(33, "H1'", "H1*", "H", false, true), + AtomSpec(34, "H8", "H8", "H", false, true), + AtomSpec(35, "H1", "H1", "H", false, true), + AtomSpec(36, "H21", "1H2", "H", false, true), + AtomSpec(37, "H22", "2H2", "H", false, true) + }; + for (int i=0; i<38; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 24, 1), + BondSpec(1, 2, 2), + BondSpec(1, 3, 1), + BondSpec(1, 4, 1), + BondSpec(3, 25, 1), + BondSpec(4, 5, 1), + BondSpec(5, 6, 1), + BondSpec(5, 26, 1), + BondSpec(5, 27, 1), + BondSpec(6, 7, 1), + BondSpec(6, 8, 1), + BondSpec(6, 28, 1), + BondSpec(7, 12, 1), + BondSpec(8, 9, 1), + BondSpec(8, 10, 1), + BondSpec(8, 29, 1), + BondSpec(9, 30, 1), + BondSpec(10, 11, 1), + BondSpec(10, 12, 1), + BondSpec(10, 31, 1), + BondSpec(11, 32, 1), + BondSpec(12, 13, 1), + BondSpec(12, 33, 1), + BondSpec(13, 14, 1), + BondSpec(13, 23, 1), + BondSpec(14, 15, 2), + BondSpec(14, 34, 1), + BondSpec(15, 16, 1), + BondSpec(16, 17, 1), + BondSpec(16, 23, 2), + BondSpec(17, 18, 2), + BondSpec(17, 19, 1), + BondSpec(19, 20, 1), + BondSpec(19, 35, 1), + BondSpec(20, 21, 1), + BondSpec(20, 22, 2), + BondSpec(21, 36, 1), + BondSpec(21, 37, 1), + BondSpec(22, 23, 1) + }; + for (int i=0; i<40; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeTCompound() { + CompoundPtr c( new Compound("T")); + c->SetOneLetterCode('Y'); + c->SetChemClass(mol::ChemClass('S')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C10 H15 N2 O8 P"); + AtomSpec atoms[] = { + AtomSpec(0, "OP3", "O3P", "O", true, true), + AtomSpec(1, "P", "P", "P", false, true), + AtomSpec(2, "OP1", "O1P", "O", false, true), + AtomSpec(3, "OP2", "O2P", "O", false, true), + AtomSpec(4, "O5'", "O5*", "O", false, true), + AtomSpec(5, "C5'", "C5*", "C", false, true), + AtomSpec(6, "C4'", "C4*", "C", false, true), + AtomSpec(7, "O4'", "O4*", "O", false, true), + AtomSpec(8, "C3'", "C3*", "C", false, true), + AtomSpec(9, "O3'", "O3*", "O", false, true), + AtomSpec(10, "C2'", "C2*", "C", false, true), + AtomSpec(11, "C1'", "C1*", "C", false, true), + AtomSpec(12, "N1", "N1", "N", false, true), + AtomSpec(13, "C2", "C2", "C", false, true), + AtomSpec(14, "O2", "O2", "O", false, true), + AtomSpec(15, "N3", "N3", "N", false, true), + AtomSpec(16, "C4", "C4", "C", false, true), + AtomSpec(17, "O4", "O4", "O", false, true), + AtomSpec(18, "C5", "C5", "C", false, true), + AtomSpec(19, "C7", "C5M", "C", false, true), + AtomSpec(20, "C6", "C6", "C", false, true), + AtomSpec(21, "HOP3", "3HOP", "H", false, true), + AtomSpec(22, "HOP2", "2HOP", "H", false, true), + AtomSpec(23, "H5'", "1H5*", "H", false, true), + AtomSpec(24, "H5''", "2H5*", "H", false, true), + AtomSpec(25, "H4'", "H4*", "H", false, true), + AtomSpec(26, "H3'", "H3*", "H", false, true), + AtomSpec(27, "HO3'", "H3T", "H", true, true), + AtomSpec(28, "H2'", "1H2*", "H", false, true), + AtomSpec(29, "H2''", "2H2*", "H", false, true), + AtomSpec(30, "H1'", "H1*", "H", false, true), + AtomSpec(31, "H3", "H3", "H", false, true), + AtomSpec(32, "H71", "1H5M", "H", false, true), + AtomSpec(33, "H72", "2H5M", "H", false, true), + AtomSpec(34, "H73", "3H5M", "H", false, true), + AtomSpec(35, "H6", "H6", "H", false, true) + }; + for (int i=0; i<36; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 21, 1), + BondSpec(1, 2, 2), + BondSpec(1, 3, 1), + BondSpec(1, 4, 1), + BondSpec(3, 22, 1), + BondSpec(4, 5, 1), + BondSpec(5, 6, 1), + BondSpec(5, 23, 1), + BondSpec(5, 24, 1), + BondSpec(6, 7, 1), + BondSpec(6, 8, 1), + BondSpec(6, 25, 1), + BondSpec(7, 11, 1), + BondSpec(8, 9, 1), + BondSpec(8, 10, 1), + BondSpec(8, 26, 1), + BondSpec(9, 27, 1), + BondSpec(10, 11, 1), + BondSpec(10, 28, 1), + BondSpec(10, 29, 1), + BondSpec(11, 12, 1), + BondSpec(11, 30, 1), + BondSpec(12, 13, 1), + BondSpec(12, 20, 1), + BondSpec(13, 14, 2), + BondSpec(13, 15, 1), + BondSpec(15, 16, 1), + BondSpec(15, 31, 1), + BondSpec(16, 17, 2), + BondSpec(16, 18, 1), + BondSpec(18, 19, 1), + BondSpec(18, 20, 2), + BondSpec(19, 32, 1), + BondSpec(19, 33, 1), + BondSpec(19, 34, 1), + BondSpec(20, 35, 1) + }; + for (int i=0; i<37; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeACompound() { + CompoundPtr c( new Compound("A")); + c->SetOneLetterCode('Y'); + c->SetChemClass(mol::ChemClass('R')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C10 H14 N5 O7 P"); + AtomSpec atoms[] = { + AtomSpec(0, "OP3", "O3P", "O", true, true), + AtomSpec(1, "P", "P", "P", false, true), + AtomSpec(2, "OP1", "O1P", "O", false, true), + AtomSpec(3, "OP2", "O2P", "O", false, true), + AtomSpec(4, "O5'", "O5*", "O", false, true), + AtomSpec(5, "C5'", "C5*", "C", false, true), + AtomSpec(6, "C4'", "C4*", "C", false, true), + AtomSpec(7, "O4'", "O4*", "O", false, true), + AtomSpec(8, "C3'", "C3*", "C", false, true), + AtomSpec(9, "O3'", "O3*", "O", false, true), + AtomSpec(10, "C2'", "C2*", "C", false, true), + AtomSpec(11, "O2'", "O2*", "O", false, true), + AtomSpec(12, "C1'", "C1*", "C", false, true), + AtomSpec(13, "N9", "N9", "N", false, true), + AtomSpec(14, "C8", "C8", "C", false, true), + AtomSpec(15, "N7", "N7", "N", false, true), + AtomSpec(16, "C5", "C5", "C", false, true), + AtomSpec(17, "C6", "C6", "C", false, true), + AtomSpec(18, "N6", "N6", "N", false, true), + AtomSpec(19, "N1", "N1", "N", false, true), + AtomSpec(20, "C2", "C2", "C", false, true), + AtomSpec(21, "N3", "N3", "N", false, true), + AtomSpec(22, "C4", "C4", "C", false, true), + AtomSpec(23, "HOP3", "3HOP", "H", false, true), + AtomSpec(24, "HOP2", "2HOP", "H", false, true), + AtomSpec(25, "H5'", "1H5*", "H", false, true), + AtomSpec(26, "H5''", "2H5*", "H", false, true), + AtomSpec(27, "H4'", "H4*", "H", false, true), + AtomSpec(28, "H3'", "H3*", "H", false, true), + AtomSpec(29, "HO3'", "H3T", "H", true, true), + AtomSpec(30, "H2'", "H2*", "H", false, true), + AtomSpec(31, "HO2'", "2HO*", "H", false, true), + AtomSpec(32, "H1'", "H1*", "H", false, true), + AtomSpec(33, "H8", "H8", "H", false, true), + AtomSpec(34, "H61", "1H6", "H", false, true), + AtomSpec(35, "H62", "2H6", "H", false, true), + AtomSpec(36, "H2", "H2", "H", false, true) + }; + for (int i=0; i<37; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 23, 1), + BondSpec(1, 2, 2), + BondSpec(1, 3, 1), + BondSpec(1, 4, 1), + BondSpec(3, 24, 1), + BondSpec(4, 5, 1), + BondSpec(5, 6, 1), + BondSpec(5, 25, 1), + BondSpec(5, 26, 1), + BondSpec(6, 7, 1), + BondSpec(6, 8, 1), + BondSpec(6, 27, 1), + BondSpec(7, 12, 1), + BondSpec(8, 9, 1), + BondSpec(8, 10, 1), + BondSpec(8, 28, 1), + BondSpec(9, 29, 1), + BondSpec(10, 11, 1), + BondSpec(10, 12, 1), + BondSpec(10, 30, 1), + BondSpec(11, 31, 1), + BondSpec(12, 13, 1), + BondSpec(12, 32, 1), + BondSpec(13, 14, 1), + BondSpec(13, 22, 1), + BondSpec(14, 15, 2), + BondSpec(14, 33, 1), + BondSpec(15, 16, 1), + BondSpec(16, 17, 1), + BondSpec(16, 22, 2), + BondSpec(17, 18, 1), + BondSpec(17, 19, 2), + BondSpec(18, 34, 1), + BondSpec(18, 35, 1), + BondSpec(19, 20, 1), + BondSpec(20, 21, 2), + BondSpec(20, 36, 1), + BondSpec(21, 22, 1) + }; + for (int i=0; i<39; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeCCompound() { + CompoundPtr c( new Compound("C")); + c->SetOneLetterCode('Y'); + c->SetChemClass(mol::ChemClass('R')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C9 H14 N3 O8 P"); + AtomSpec atoms[] = { + AtomSpec(0, "OP3", "O3P", "O", true, true), + AtomSpec(1, "P", "P", "P", false, true), + AtomSpec(2, "OP1", "O1P", "O", false, true), + AtomSpec(3, "OP2", "O2P", "O", false, true), + AtomSpec(4, "O5'", "O5*", "O", false, true), + AtomSpec(5, "C5'", "C5*", "C", false, true), + AtomSpec(6, "C4'", "C4*", "C", false, true), + AtomSpec(7, "O4'", "O4*", "O", false, true), + AtomSpec(8, "C3'", "C3*", "C", false, true), + AtomSpec(9, "O3'", "O3*", "O", false, true), + AtomSpec(10, "C2'", "C2*", "C", false, true), + AtomSpec(11, "O2'", "O2*", "O", false, true), + AtomSpec(12, "C1'", "C1*", "C", false, true), + AtomSpec(13, "N1", "N1", "N", false, true), + AtomSpec(14, "C2", "C2", "C", false, true), + AtomSpec(15, "O2", "O2", "O", false, true), + AtomSpec(16, "N3", "N3", "N", false, true), + AtomSpec(17, "C4", "C4", "C", false, true), + AtomSpec(18, "N4", "N4", "N", false, true), + AtomSpec(19, "C5", "C5", "C", false, true), + AtomSpec(20, "C6", "C6", "C", false, true), + AtomSpec(21, "HOP3", "3HOP", "H", false, true), + AtomSpec(22, "HOP2", "2HOP", "H", false, true), + AtomSpec(23, "H5'", "1H5*", "H", false, true), + AtomSpec(24, "H5''", "2H5*", "H", false, true), + AtomSpec(25, "H4'", "H4*", "H", false, true), + AtomSpec(26, "H3'", "H3*", "H", false, true), + AtomSpec(27, "HO3'", "H3T", "H", true, true), + AtomSpec(28, "H2'", "H2*", "H", false, true), + AtomSpec(29, "HO2'", "2HO*", "H", false, true), + AtomSpec(30, "H1'", "H1*", "H", false, true), + AtomSpec(31, "H41", "1H4", "H", false, true), + AtomSpec(32, "H42", "2H4", "H", false, true), + AtomSpec(33, "H5", "H5", "H", false, true), + AtomSpec(34, "H6", "H6", "H", false, true) + }; + for (int i=0; i<35; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 21, 1), + BondSpec(1, 2, 2), + BondSpec(1, 3, 1), + BondSpec(1, 4, 1), + BondSpec(3, 22, 1), + BondSpec(4, 5, 1), + BondSpec(5, 6, 1), + BondSpec(5, 23, 1), + BondSpec(5, 24, 1), + BondSpec(6, 7, 1), + BondSpec(6, 8, 1), + BondSpec(6, 25, 1), + BondSpec(7, 12, 1), + BondSpec(8, 9, 1), + BondSpec(8, 10, 1), + BondSpec(8, 26, 1), + BondSpec(9, 27, 1), + BondSpec(10, 11, 1), + BondSpec(10, 12, 1), + BondSpec(10, 28, 1), + BondSpec(11, 29, 1), + BondSpec(12, 13, 1), + BondSpec(12, 30, 1), + BondSpec(13, 14, 1), + BondSpec(13, 20, 1), + BondSpec(14, 15, 2), + BondSpec(14, 16, 1), + BondSpec(16, 17, 2), + BondSpec(17, 18, 1), + BondSpec(17, 19, 1), + BondSpec(18, 31, 1), + BondSpec(18, 32, 1), + BondSpec(19, 20, 2), + BondSpec(19, 33, 1), + BondSpec(20, 34, 1) + }; + for (int i=0; i<36; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeUCompound() { + CompoundPtr c( new Compound("U")); + c->SetOneLetterCode('Y'); + c->SetChemClass(mol::ChemClass('R')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C9 H13 N2 O9 P"); + AtomSpec atoms[] = { + AtomSpec(0, "OP3", "O3P", "O", true, true), + AtomSpec(1, "P", "P", "P", false, true), + AtomSpec(2, "OP1", "O1P", "O", false, true), + AtomSpec(3, "OP2", "O2P", "O", false, true), + AtomSpec(4, "O5'", "O5*", "O", false, true), + AtomSpec(5, "C5'", "C5*", "C", false, true), + AtomSpec(6, "C4'", "C4*", "C", false, true), + AtomSpec(7, "O4'", "O4*", "O", false, true), + AtomSpec(8, "C3'", "C3*", "C", false, true), + AtomSpec(9, "O3'", "O3*", "O", false, true), + AtomSpec(10, "C2'", "C2*", "C", false, true), + AtomSpec(11, "O2'", "O2*", "O", false, true), + AtomSpec(12, "C1'", "C1*", "C", false, true), + AtomSpec(13, "N1", "N1", "N", false, true), + AtomSpec(14, "C2", "C2", "C", false, true), + AtomSpec(15, "O2", "O2", "O", false, true), + AtomSpec(16, "N3", "N3", "N", false, true), + AtomSpec(17, "C4", "C4", "C", false, true), + AtomSpec(18, "O4", "O4", "O", false, true), + AtomSpec(19, "C5", "C5", "C", false, true), + AtomSpec(20, "C6", "C6", "C", false, true), + AtomSpec(21, "HOP3", "3HOP", "H", false, true), + AtomSpec(22, "HOP2", "2HOP", "H", false, true), + AtomSpec(23, "H5'", "1H5*", "H", false, true), + AtomSpec(24, "H5''", "2H5*", "H", false, true), + AtomSpec(25, "H4'", "H4*", "H", false, true), + AtomSpec(26, "H3'", "H3*", "H", false, true), + AtomSpec(27, "HO3'", "H3T", "H", true, true), + AtomSpec(28, "H2'", "H2*", "H", false, true), + AtomSpec(29, "HO2'", "2HO*", "H", false, true), + AtomSpec(30, "H1'", "H1*", "H", false, true), + AtomSpec(31, "H3", "H3", "H", false, true), + AtomSpec(32, "H5", "H5", "H", false, true), + AtomSpec(33, "H6", "H6", "H", false, true) + }; + for (int i=0; i<34; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 21, 1), + BondSpec(1, 2, 2), + BondSpec(1, 3, 1), + BondSpec(1, 4, 1), + BondSpec(3, 22, 1), + BondSpec(4, 5, 1), + BondSpec(5, 6, 1), + BondSpec(5, 23, 1), + BondSpec(5, 24, 1), + BondSpec(6, 7, 1), + BondSpec(6, 8, 1), + BondSpec(6, 25, 1), + BondSpec(7, 12, 1), + BondSpec(8, 9, 1), + BondSpec(8, 10, 1), + BondSpec(8, 26, 1), + BondSpec(9, 27, 1), + BondSpec(10, 11, 1), + BondSpec(10, 12, 1), + BondSpec(10, 28, 1), + BondSpec(11, 29, 1), + BondSpec(12, 13, 1), + BondSpec(12, 30, 1), + BondSpec(13, 14, 1), + BondSpec(13, 20, 1), + BondSpec(14, 15, 2), + BondSpec(14, 16, 1), + BondSpec(16, 17, 1), + BondSpec(16, 31, 1), + BondSpec(17, 18, 2), + BondSpec(17, 19, 1), + BondSpec(19, 20, 2), + BondSpec(19, 32, 1), + BondSpec(20, 33, 1) + }; + for (int i=0; i<35; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeDGCompound() { + CompoundPtr c( new Compound("DG")); + c->SetOneLetterCode('Y'); + c->SetChemClass(mol::ChemClass('S')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C10 H14 N5 O7 P"); + AtomSpec atoms[] = { + AtomSpec(0, "OP3", "O3P", "O", true, true), + AtomSpec(1, "P", "P", "P", false, true), + AtomSpec(2, "OP1", "O1P", "O", false, true), + AtomSpec(3, "OP2", "O2P", "O", false, true), + AtomSpec(4, "O5'", "O5*", "O", false, true), + AtomSpec(5, "C5'", "C5*", "C", false, true), + AtomSpec(6, "C4'", "C4*", "C", false, true), + AtomSpec(7, "O4'", "O4*", "O", false, true), + AtomSpec(8, "C3'", "C3*", "C", false, true), + AtomSpec(9, "O3'", "O3*", "O", false, true), + AtomSpec(10, "C2'", "C2*", "C", false, true), + AtomSpec(11, "C1'", "C1*", "C", false, true), + AtomSpec(12, "N9", "N9", "N", false, true), + AtomSpec(13, "C8", "C8", "C", false, true), + AtomSpec(14, "N7", "N7", "N", false, true), + AtomSpec(15, "C5", "C5", "C", false, true), + AtomSpec(16, "C6", "C6", "C", false, true), + AtomSpec(17, "O6", "O6", "O", false, true), + AtomSpec(18, "N1", "N1", "N", false, true), + AtomSpec(19, "C2", "C2", "C", false, true), + AtomSpec(20, "N2", "N2", "N", false, true), + AtomSpec(21, "N3", "N3", "N", false, true), + AtomSpec(22, "C4", "C4", "C", false, true), + AtomSpec(23, "HOP3", "3HOP", "H", false, true), + AtomSpec(24, "HOP2", "2HOP", "H", false, true), + AtomSpec(25, "H5'", "1H5*", "H", false, true), + AtomSpec(26, "H5''", "2H5*", "H", false, true), + AtomSpec(27, "H4'", "H4*", "H", false, true), + AtomSpec(28, "H3'", "H3*", "H", false, true), + AtomSpec(29, "HO3'", "H3T", "H", true, true), + AtomSpec(30, "H2'", "1H2*", "H", false, true), + AtomSpec(31, "H2''", "2H2*", "H", false, true), + AtomSpec(32, "H1'", "H1*", "H", false, true), + AtomSpec(33, "H8", "H8", "H", false, true), + AtomSpec(34, "H1", "H1", "H", false, true), + AtomSpec(35, "H21", "1H2", "H", false, true), + AtomSpec(36, "H22", "2H2", "H", false, true) + }; + for (int i=0; i<37; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 23, 1), + BondSpec(1, 2, 2), + BondSpec(1, 3, 1), + BondSpec(1, 4, 1), + BondSpec(3, 24, 1), + BondSpec(4, 5, 1), + BondSpec(5, 6, 1), + BondSpec(5, 25, 1), + BondSpec(5, 26, 1), + BondSpec(6, 7, 1), + BondSpec(6, 8, 1), + BondSpec(6, 27, 1), + BondSpec(7, 11, 1), + BondSpec(8, 9, 1), + BondSpec(8, 10, 1), + BondSpec(8, 28, 1), + BondSpec(9, 29, 1), + BondSpec(10, 11, 1), + BondSpec(10, 30, 1), + BondSpec(10, 31, 1), + BondSpec(11, 12, 1), + BondSpec(11, 32, 1), + BondSpec(12, 13, 1), + BondSpec(12, 22, 1), + BondSpec(13, 14, 2), + BondSpec(13, 33, 1), + BondSpec(14, 15, 1), + BondSpec(15, 16, 1), + BondSpec(15, 22, 2), + BondSpec(16, 17, 2), + BondSpec(16, 18, 1), + BondSpec(18, 19, 1), + BondSpec(18, 34, 1), + BondSpec(19, 20, 1), + BondSpec(19, 21, 2), + BondSpec(20, 35, 1), + BondSpec(20, 36, 1), + BondSpec(21, 22, 1) + }; + for (int i=0; i<39; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeDTCompound() { + CompoundPtr c( new Compound("DT")); + c->SetOneLetterCode('Y'); + c->SetChemClass(mol::ChemClass('S')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C10 H15 N2 O8 P"); + AtomSpec atoms[] = { + AtomSpec(0, "OP3", "O3P", "O", true, true), + AtomSpec(1, "P", "P", "P", false, true), + AtomSpec(2, "OP1", "O1P", "O", false, true), + AtomSpec(3, "OP2", "O2P", "O", false, true), + AtomSpec(4, "O5'", "O5*", "O", false, true), + AtomSpec(5, "C5'", "C5*", "C", false, true), + AtomSpec(6, "C4'", "C4*", "C", false, true), + AtomSpec(7, "O4'", "O4*", "O", false, true), + AtomSpec(8, "C3'", "C3*", "C", false, true), + AtomSpec(9, "O3'", "O3*", "O", false, true), + AtomSpec(10, "C2'", "C2*", "C", false, true), + AtomSpec(11, "C1'", "C1*", "C", false, true), + AtomSpec(12, "N1", "N1", "N", false, true), + AtomSpec(13, "C2", "C2", "C", false, true), + AtomSpec(14, "O2", "O2", "O", false, true), + AtomSpec(15, "N3", "N3", "N", false, true), + AtomSpec(16, "C4", "C4", "C", false, true), + AtomSpec(17, "O4", "O4", "O", false, true), + AtomSpec(18, "C5", "C5", "C", false, true), + AtomSpec(19, "C7", "C5M", "C", false, true), + AtomSpec(20, "C6", "C6", "C", false, true), + AtomSpec(21, "HOP3", "3HOP", "H", false, true), + AtomSpec(22, "HOP2", "2HOP", "H", false, true), + AtomSpec(23, "H5'", "1H5*", "H", false, true), + AtomSpec(24, "H5''", "2H5*", "H", false, true), + AtomSpec(25, "H4'", "H4*", "H", false, true), + AtomSpec(26, "H3'", "H3*", "H", false, true), + AtomSpec(27, "HO3'", "H3T", "H", true, true), + AtomSpec(28, "H2'", "1H2*", "H", false, true), + AtomSpec(29, "H2''", "2H2*", "H", false, true), + AtomSpec(30, "H1'", "H1*", "H", false, true), + AtomSpec(31, "H3", "H3", "H", false, true), + AtomSpec(32, "H71", "1H5M", "H", false, true), + AtomSpec(33, "H72", "2H5M", "H", false, true), + AtomSpec(34, "H73", "3H5M", "H", false, true), + AtomSpec(35, "H6", "H6", "H", false, true) + }; + for (int i=0; i<36; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 21, 1), + BondSpec(1, 2, 2), + BondSpec(1, 3, 1), + BondSpec(1, 4, 1), + BondSpec(3, 22, 1), + BondSpec(4, 5, 1), + BondSpec(5, 6, 1), + BondSpec(5, 23, 1), + BondSpec(5, 24, 1), + BondSpec(6, 7, 1), + BondSpec(6, 8, 1), + BondSpec(6, 25, 1), + BondSpec(7, 11, 1), + BondSpec(8, 9, 1), + BondSpec(8, 10, 1), + BondSpec(8, 26, 1), + BondSpec(9, 27, 1), + BondSpec(10, 11, 1), + BondSpec(10, 28, 1), + BondSpec(10, 29, 1), + BondSpec(11, 12, 1), + BondSpec(11, 30, 1), + BondSpec(12, 13, 1), + BondSpec(12, 20, 1), + BondSpec(13, 14, 2), + BondSpec(13, 15, 1), + BondSpec(15, 16, 1), + BondSpec(15, 31, 1), + BondSpec(16, 17, 2), + BondSpec(16, 18, 1), + BondSpec(18, 19, 1), + BondSpec(18, 20, 2), + BondSpec(19, 32, 1), + BondSpec(19, 33, 1), + BondSpec(19, 34, 1), + BondSpec(20, 35, 1) + }; + for (int i=0; i<37; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeDUCompound() { + CompoundPtr c( new Compound("DU")); + c->SetOneLetterCode('Y'); + c->SetChemClass(mol::ChemClass('S')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C9 H13 N2 O8 P"); + AtomSpec atoms[] = { + AtomSpec(0, "OP3", "O3P", "O", true, true), + AtomSpec(1, "P", "P", "P", false, true), + AtomSpec(2, "OP1", "O1P", "O", false, true), + AtomSpec(3, "OP2", "O2P", "O", false, true), + AtomSpec(4, "O5'", "O5*", "O", false, true), + AtomSpec(5, "C5'", "C5*", "C", false, true), + AtomSpec(6, "C4'", "C4*", "C", false, true), + AtomSpec(7, "O4'", "O4*", "O", false, true), + AtomSpec(8, "C3'", "C3*", "C", false, true), + AtomSpec(9, "O3'", "O3*", "O", false, true), + AtomSpec(10, "C2'", "C2*", "C", false, true), + AtomSpec(11, "C1'", "C1*", "C", false, true), + AtomSpec(12, "N1", "N1", "N", false, true), + AtomSpec(13, "C2", "C2", "C", false, true), + AtomSpec(14, "O2", "O2", "O", false, true), + AtomSpec(15, "N3", "N3", "N", false, true), + AtomSpec(16, "C4", "C4", "C", false, true), + AtomSpec(17, "O4", "O4", "O", false, true), + AtomSpec(18, "C5", "C5", "C", false, true), + AtomSpec(19, "C6", "C6", "C", false, true), + AtomSpec(20, "HOP3", "3HOP", "H", false, true), + AtomSpec(21, "HOP2", "2HOP", "H", false, true), + AtomSpec(22, "H5'", "1H5*", "H", false, true), + AtomSpec(23, "H5''", "2H5*", "H", false, true), + AtomSpec(24, "H4'", "H4*", "H", false, true), + AtomSpec(25, "H3'", "H3*", "H", false, true), + AtomSpec(26, "HO3'", "H3T", "H", true, true), + AtomSpec(27, "H2'", "1H2*", "H", false, true), + AtomSpec(28, "H2''", "2H2*", "H", false, true), + AtomSpec(29, "H1'", "H1*", "H", false, true), + AtomSpec(30, "H3", "H3", "H", false, true), + AtomSpec(31, "H5", "H5", "H", false, true), + AtomSpec(32, "H6", "H6", "H", false, true) + }; + for (int i=0; i<33; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 20, 1), + BondSpec(1, 2, 2), + BondSpec(1, 3, 1), + BondSpec(1, 4, 1), + BondSpec(3, 21, 1), + BondSpec(4, 5, 1), + BondSpec(5, 6, 1), + BondSpec(5, 22, 1), + BondSpec(5, 23, 1), + BondSpec(6, 7, 1), + BondSpec(6, 8, 1), + BondSpec(6, 24, 1), + BondSpec(7, 11, 1), + BondSpec(8, 9, 1), + BondSpec(8, 10, 1), + BondSpec(8, 25, 1), + BondSpec(9, 26, 1), + BondSpec(10, 11, 1), + BondSpec(10, 27, 1), + BondSpec(10, 28, 1), + BondSpec(11, 12, 1), + BondSpec(11, 29, 1), + BondSpec(12, 13, 1), + BondSpec(12, 19, 1), + BondSpec(13, 14, 2), + BondSpec(13, 15, 1), + BondSpec(15, 16, 1), + BondSpec(15, 30, 1), + BondSpec(16, 17, 2), + BondSpec(16, 18, 1), + BondSpec(18, 19, 2), + BondSpec(18, 31, 1), + BondSpec(19, 32, 1) + }; + for (int i=0; i<34; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeDCCompound() { + CompoundPtr c( new Compound("DC")); + c->SetOneLetterCode('Y'); + c->SetChemClass(mol::ChemClass('S')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C9 H14 N3 O7 P"); + AtomSpec atoms[] = { + AtomSpec(0, "OP3", "O3P", "O", true, true), + AtomSpec(1, "P", "P", "P", false, true), + AtomSpec(2, "OP1", "O1P", "O", false, true), + AtomSpec(3, "OP2", "O2P", "O", false, true), + AtomSpec(4, "O5'", "O5*", "O", false, true), + AtomSpec(5, "C5'", "C5*", "C", false, true), + AtomSpec(6, "C4'", "C4*", "C", false, true), + AtomSpec(7, "O4'", "O4*", "O", false, true), + AtomSpec(8, "C3'", "C3*", "C", false, true), + AtomSpec(9, "O3'", "O3*", "O", false, true), + AtomSpec(10, "C2'", "C2*", "C", false, true), + AtomSpec(11, "C1'", "C1*", "C", false, true), + AtomSpec(12, "N1", "N1", "N", false, true), + AtomSpec(13, "C2", "C2", "C", false, true), + AtomSpec(14, "O2", "O2", "O", false, true), + AtomSpec(15, "N3", "N3", "N", false, true), + AtomSpec(16, "C4", "C4", "C", false, true), + AtomSpec(17, "N4", "N4", "N", false, true), + AtomSpec(18, "C5", "C5", "C", false, true), + AtomSpec(19, "C6", "C6", "C", false, true), + AtomSpec(20, "HOP3", "3HOP", "H", false, true), + AtomSpec(21, "HOP2", "2HOP", "H", false, true), + AtomSpec(22, "H5'", "1H5*", "H", false, true), + AtomSpec(23, "H5''", "2H5*", "H", false, true), + AtomSpec(24, "H4'", "H4*", "H", false, true), + AtomSpec(25, "H3'", "H3*", "H", false, true), + AtomSpec(26, "HO3'", "H3T", "H", true, true), + AtomSpec(27, "H2'", "1H2*", "H", false, true), + AtomSpec(28, "H2''", "2H2*", "H", false, true), + AtomSpec(29, "H1'", "H1*", "H", false, true), + AtomSpec(30, "H41", "1H4", "H", false, true), + AtomSpec(31, "H42", "2H4", "H", false, true), + AtomSpec(32, "H5", "H5", "H", false, true), + AtomSpec(33, "H6", "H6", "H", false, true) + }; + for (int i=0; i<34; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 20, 1), + BondSpec(1, 2, 2), + BondSpec(1, 3, 1), + BondSpec(1, 4, 1), + BondSpec(3, 21, 1), + BondSpec(4, 5, 1), + BondSpec(5, 6, 1), + BondSpec(5, 22, 1), + BondSpec(5, 23, 1), + BondSpec(6, 7, 1), + BondSpec(6, 8, 1), + BondSpec(6, 24, 1), + BondSpec(7, 11, 1), + BondSpec(8, 9, 1), + BondSpec(8, 10, 1), + BondSpec(8, 25, 1), + BondSpec(9, 26, 1), + BondSpec(10, 11, 1), + BondSpec(10, 27, 1), + BondSpec(10, 28, 1), + BondSpec(11, 12, 1), + BondSpec(11, 29, 1), + BondSpec(12, 13, 1), + BondSpec(12, 19, 1), + BondSpec(13, 14, 2), + BondSpec(13, 15, 1), + BondSpec(15, 16, 2), + BondSpec(16, 17, 1), + BondSpec(16, 18, 1), + BondSpec(17, 30, 1), + BondSpec(17, 31, 1), + BondSpec(18, 19, 2), + BondSpec(18, 32, 1), + BondSpec(19, 33, 1) + }; + for (int i=0; i<35; ++i) { c->AddBond(bonds[i]); } + return c; +} +CompoundPtr MakeDACompound() { + CompoundPtr c( new Compound("DA")); + c->SetOneLetterCode('Y'); + c->SetChemClass(mol::ChemClass('S')); + c->SetChemType(mol::ChemType('U')); + c->SetFormula("C10 H14 N5 O6 P"); + AtomSpec atoms[] = { + AtomSpec(0, "OP3", "O3P", "O", true, true), + AtomSpec(1, "P", "P", "P", false, true), + AtomSpec(2, "OP1", "O1P", "O", false, true), + AtomSpec(3, "OP2", "O2P", "O", false, true), + AtomSpec(4, "O5'", "O5*", "O", false, true), + AtomSpec(5, "C5'", "C5*", "C", false, true), + AtomSpec(6, "C4'", "C4*", "C", false, true), + AtomSpec(7, "O4'", "O4*", "O", false, true), + AtomSpec(8, "C3'", "C3*", "C", false, true), + AtomSpec(9, "O3'", "O3*", "O", false, true), + AtomSpec(10, "C2'", "C2*", "C", false, true), + AtomSpec(11, "C1'", "C1*", "C", false, true), + AtomSpec(12, "N9", "N9", "N", false, true), + AtomSpec(13, "C8", "C8", "C", false, true), + AtomSpec(14, "N7", "N7", "N", false, true), + AtomSpec(15, "C5", "C5", "C", false, true), + AtomSpec(16, "C6", "C6", "C", false, true), + AtomSpec(17, "N6", "N6", "N", false, true), + AtomSpec(18, "N1", "N1", "N", false, true), + AtomSpec(19, "C2", "C2", "C", false, true), + AtomSpec(20, "N3", "N3", "N", false, true), + AtomSpec(21, "C4", "C4", "C", false, true), + AtomSpec(22, "HOP3", "3HOP", "H", false, true), + AtomSpec(23, "HOP2", "2HOP", "H", false, true), + AtomSpec(24, "H5'", "1H5*", "H", false, true), + AtomSpec(25, "H5''", "2H5*", "H", false, true), + AtomSpec(26, "H4'", "H4*", "H", false, true), + AtomSpec(27, "H3'", "H3*", "H", false, true), + AtomSpec(28, "HO3'", "H3T", "H", true, true), + AtomSpec(29, "H2'", "1H2*", "H", false, true), + AtomSpec(30, "H2''", "2H2*", "H", false, true), + AtomSpec(31, "H1'", "H1*", "H", false, true), + AtomSpec(32, "H8", "H8", "H", false, true), + AtomSpec(33, "H61", "1H6", "H", false, true), + AtomSpec(34, "H62", "2H6", "H", false, true), + AtomSpec(35, "H2", "H2", "H", false, true) + }; + for (int i=0; i<36; ++i) { c->AddAtom(atoms[i]); } + BondSpec bonds[] = { + BondSpec(0, 1, 1), + BondSpec(0, 22, 1), + BondSpec(1, 2, 2), + BondSpec(1, 3, 1), + BondSpec(1, 4, 1), + BondSpec(3, 23, 1), + BondSpec(4, 5, 1), + BondSpec(5, 6, 1), + BondSpec(5, 24, 1), + BondSpec(5, 25, 1), + BondSpec(6, 7, 1), + BondSpec(6, 8, 1), + BondSpec(6, 26, 1), + BondSpec(7, 11, 1), + BondSpec(8, 9, 1), + BondSpec(8, 10, 1), + BondSpec(8, 27, 1), + BondSpec(9, 28, 1), + BondSpec(10, 11, 1), + BondSpec(10, 29, 1), + BondSpec(10, 30, 1), + BondSpec(11, 12, 1), + BondSpec(11, 31, 1), + BondSpec(12, 13, 1), + BondSpec(12, 21, 1), + BondSpec(13, 14, 2), + BondSpec(13, 32, 1), + BondSpec(14, 15, 1), + BondSpec(15, 16, 1), + BondSpec(15, 21, 2), + BondSpec(16, 17, 1), + BondSpec(16, 18, 2), + BondSpec(17, 33, 1), + BondSpec(17, 34, 1), + BondSpec(18, 19, 1), + BondSpec(19, 20, 2), + BondSpec(19, 35, 1), + BondSpec(20, 21, 1) + }; + for (int i=0; i<38; ++i) { c->AddBond(bonds[i]); } + return c; +} diff --git a/modules/conop/tests/CMakeLists.txt b/modules/conop/tests/CMakeLists.txt index 6a832115b5933b66241c9dec5ce23c21dd532c48..29140807826e25e812d312371013f9ca96e2b3bd 100644 --- a/modules/conop/tests/CMakeLists.txt +++ b/modules/conop/tests/CMakeLists.txt @@ -1,10 +1,11 @@ set(OST_CONOP_UNIT_TESTS - test_heuristic_builder.cc - test_rule_based_builder.cc + test_heuristic_conop.cc tests.cc - test_builder.cc + test_rule_based_conop.cc + helper.cc test_compound.py test_cleanup.py + test_processor.py test_nonstandard.py ) diff --git a/modules/conop/tests/test_rule_based_builder.cc b/modules/conop/tests/helper.cc similarity index 77% rename from modules/conop/tests/test_rule_based_builder.cc rename to modules/conop/tests/helper.cc index a287bc12426bf68e863be6388717855970fa14ee..bc3b4af781adbda8eae79437d0b9d552b28cb0fa 100644 --- a/modules/conop/tests/test_rule_based_builder.cc +++ b/modules/conop/tests/helper.cc @@ -1,38 +1,13 @@ -// ----------------------------------------------------------------------------- -// 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 <ost/mol/mol.hh> -#include <ost/platform.hh> -#include <ost/conop/rule_based_builder.hh> -#include <ost/conop/conop.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> -#include <boost/test/auto_unit_test.hpp> +#include <ost/mol/xcs_editor.hh> +#include <ost/mol/bond_handle.hh> + +#include "helper.hh" -#include <ost/log.hh> -using boost::unit_test_framework::test_suite; -using namespace ost; -using namespace ost::conop; -//using namespace ost::io; using namespace ost::mol; -namespace { -} // anon ns + +namespace ost { namespace conop { ResidueHandle make_cytosine(ChainHandle chain) { @@ -148,7 +123,6 @@ ResidueHandle make_defective_uracil2(ChainHandle chain) return res; } - ResidueHandle make_1zk(ChainHandle chain) { XCSEditor edi=chain.GetEntity().EditXCS(); @@ -215,73 +189,6 @@ ResidueHandle make_1zk(ChainHandle chain) return r; } -void verify_1zk_connectivity(const ResidueHandle& r1) -{ - BOOST_CHECK(BondExists(r1.FindAtom("C"), r1.FindAtom("CA"))); - BOOST_CHECK(BondExists(r1.FindAtom("C"), r1.FindAtom("O"))); - BOOST_CHECK(BondExists(r1.FindAtom("CA"), r1.FindAtom("O1"))); - BOOST_CHECK(BondExists(r1.FindAtom("C1"), r1.FindAtom("C2"))); - BOOST_CHECK(BondExists(r1.FindAtom("C1"), r1.FindAtom("C1A"))); - BOOST_CHECK(BondExists(r1.FindAtom("C1"), r1.FindAtom("O1"))); - BOOST_CHECK(BondExists(r1.FindAtom("C2"), r1.FindAtom("C3"))); - BOOST_CHECK(BondExists(r1.FindAtom("C3"), r1.FindAtom("C4"))); - BOOST_CHECK(BondExists(r1.FindAtom("C4"), r1.FindAtom("C4A"))); - BOOST_CHECK(BondExists(r1.FindAtom("C4A"), r1.FindAtom("C5"))); - BOOST_CHECK(BondExists(r1.FindAtom("C4A"), r1.FindAtom("C1A"))); - BOOST_CHECK(BondExists(r1.FindAtom("C5"), r1.FindAtom("C6"))); - BOOST_CHECK(BondExists(r1.FindAtom("C6"), r1.FindAtom("C7"))); - BOOST_CHECK(BondExists(r1.FindAtom("C7"), r1.FindAtom("C8"))); - BOOST_CHECK(BondExists(r1.FindAtom("C8"), r1.FindAtom("C1A"))); - BOOST_CHECK(BondExists(r1.FindAtom("N"), r1.FindAtom("CA1"))); - BOOST_CHECK(BondExists(r1.FindAtom("CA1"), r1.FindAtom("C9"))); - BOOST_CHECK(BondExists(r1.FindAtom("CA1"), r1.FindAtom("CB"))); - BOOST_CHECK(BondExists(r1.FindAtom("C9"), r1.FindAtom("O2"))); - BOOST_CHECK(BondExists(r1.FindAtom("CB"), r1.FindAtom("CG"))); - BOOST_CHECK(BondExists(r1.FindAtom("CG"), r1.FindAtom("ND1"))); - BOOST_CHECK(BondExists(r1.FindAtom("CG"), r1.FindAtom("CD2"))); - BOOST_CHECK(BondExists(r1.FindAtom("ND1"), r1.FindAtom("CE1"))); - BOOST_CHECK(BondExists(r1.FindAtom("CD2"), r1.FindAtom("NE2"))); - BOOST_CHECK(BondExists(r1.FindAtom("CE1"), r1.FindAtom("NE2"))); - BOOST_CHECK(BondExists(r1.FindAtom("N1"), r1.FindAtom("CA2"))); - BOOST_CHECK(BondExists(r1.FindAtom("CA2"), r1.FindAtom("CB1"))); - BOOST_CHECK(BondExists(r1.FindAtom("CA2"), r1.FindAtom("CH"))); - BOOST_CHECK(BondExists(r1.FindAtom("CB1"), r1.FindAtom("CG1"))); - BOOST_CHECK(BondExists(r1.FindAtom("CG1"), r1.FindAtom("CD1"))); - BOOST_CHECK(BondExists(r1.FindAtom("CG1"), r1.FindAtom("CD21"))); - BOOST_CHECK(BondExists(r1.FindAtom("CD1"), r1.FindAtom("CE11"))); - BOOST_CHECK(BondExists(r1.FindAtom("CD21"), r1.FindAtom("CE2"))); - BOOST_CHECK(BondExists(r1.FindAtom("CE11"), r1.FindAtom("CZ"))); - BOOST_CHECK(BondExists(r1.FindAtom("CE2"), r1.FindAtom("CZ"))); - BOOST_CHECK(BondExists(r1.FindAtom("CH"), r1.FindAtom("OH"))); - BOOST_CHECK(BondExists(r1.FindAtom("CH"), r1.FindAtom("CB11"))); - BOOST_CHECK(BondExists(r1.FindAtom("CB11"), r1.FindAtom("CA'"))); - BOOST_CHECK(BondExists(r1.FindAtom("CB11"), r1.FindAtom("OB1"))); - BOOST_CHECK(BondExists(r1.FindAtom("CA'"), r1.FindAtom("CB'"))); - BOOST_CHECK(BondExists(r1.FindAtom("CA'"), r1.FindAtom("CC"))); - BOOST_CHECK(BondExists(r1.FindAtom("CB'"), r1.FindAtom("CG11"))); - BOOST_CHECK(BondExists(r1.FindAtom("CB'"), r1.FindAtom("CG2"))); - BOOST_CHECK(BondExists(r1.FindAtom("CC"), r1.FindAtom("O3"))); - BOOST_CHECK(BondExists(r1.FindAtom("N2"), r1.FindAtom("CA3"))); - BOOST_CHECK(BondExists(r1.FindAtom("CA3"), r1.FindAtom("CD"))); - BOOST_CHECK(BondExists(r1.FindAtom("CA3"), r1.FindAtom("CB2"))); - BOOST_CHECK(BondExists(r1.FindAtom("CD"), r1.FindAtom("O4"))); - BOOST_CHECK(BondExists(r1.FindAtom("CB2"), r1.FindAtom("CG12"))); - BOOST_CHECK(BondExists(r1.FindAtom("CB2"), r1.FindAtom("CG21"))); - BOOST_CHECK(BondExists(r1.FindAtom("CG12"), r1.FindAtom("CD11"))); - BOOST_CHECK(BondExists(r1.FindAtom("N3"), r1.FindAtom("CM"))); - BOOST_CHECK(BondExists(r1.FindAtom("CM"), r1.FindAtom("C21"))); - BOOST_CHECK(BondExists(r1.FindAtom("C21"), r1.FindAtom("C31"))); - BOOST_CHECK(BondExists(r1.FindAtom("C21"), r1.FindAtom("N11"))); - BOOST_CHECK(BondExists(r1.FindAtom("C31"), r1.FindAtom("C41"))); - BOOST_CHECK(BondExists(r1.FindAtom("C41"), r1.FindAtom("C51"))); - BOOST_CHECK(BondExists(r1.FindAtom("C51"), r1.FindAtom("C61"))); - BOOST_CHECK(BondExists(r1.FindAtom("C61"), r1.FindAtom("N11"))); - BOOST_CHECK(BondExists(r1.FindAtom("C"), r1.FindAtom("N"))); - BOOST_CHECK(BondExists(r1.FindAtom("C9"), r1.FindAtom("N1"))); - BOOST_CHECK(BondExists(r1.FindAtom("CC"), r1.FindAtom("N2"))); - BOOST_CHECK(BondExists(r1.FindAtom("CD"), r1.FindAtom("N3"))); -} - void verify_nucleotide_connectivity(const ResidueHandle& res) { BOOST_CHECK(BondExists(res.FindAtom("P"), @@ -353,106 +260,122 @@ void verify_nucleotide_connectivity(const ResidueHandle& res) // TODO: Check that no other atoms are connected! } } -void verify_nucleotide_link(const ResidueHandle& p3, const ResidueHandle& p5) +void verify_1zk_connectivity(const ResidueHandle& r1) { - BOOST_CHECK(BondExists(p3.FindAtom("O3'"), - p5.FindAtom("P"))); + BOOST_CHECK(BondExists(r1.FindAtom("C"), r1.FindAtom("CA"))); + BOOST_CHECK(BondExists(r1.FindAtom("C"), r1.FindAtom("O"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA"), r1.FindAtom("O1"))); + BOOST_CHECK(BondExists(r1.FindAtom("C1"), r1.FindAtom("C2"))); + BOOST_CHECK(BondExists(r1.FindAtom("C1"), r1.FindAtom("C1A"))); + BOOST_CHECK(BondExists(r1.FindAtom("C1"), r1.FindAtom("O1"))); + BOOST_CHECK(BondExists(r1.FindAtom("C2"), r1.FindAtom("C3"))); + BOOST_CHECK(BondExists(r1.FindAtom("C3"), r1.FindAtom("C4"))); + BOOST_CHECK(BondExists(r1.FindAtom("C4"), r1.FindAtom("C4A"))); + BOOST_CHECK(BondExists(r1.FindAtom("C4A"), r1.FindAtom("C5"))); + BOOST_CHECK(BondExists(r1.FindAtom("C4A"), r1.FindAtom("C1A"))); + BOOST_CHECK(BondExists(r1.FindAtom("C5"), r1.FindAtom("C6"))); + BOOST_CHECK(BondExists(r1.FindAtom("C6"), r1.FindAtom("C7"))); + BOOST_CHECK(BondExists(r1.FindAtom("C7"), r1.FindAtom("C8"))); + BOOST_CHECK(BondExists(r1.FindAtom("C8"), r1.FindAtom("C1A"))); + BOOST_CHECK(BondExists(r1.FindAtom("N"), r1.FindAtom("CA1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA1"), r1.FindAtom("C9"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA1"), r1.FindAtom("CB"))); + BOOST_CHECK(BondExists(r1.FindAtom("C9"), r1.FindAtom("O2"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB"), r1.FindAtom("CG"))); + BOOST_CHECK(BondExists(r1.FindAtom("CG"), r1.FindAtom("ND1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CG"), r1.FindAtom("CD2"))); + BOOST_CHECK(BondExists(r1.FindAtom("ND1"), r1.FindAtom("CE1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CD2"), r1.FindAtom("NE2"))); + BOOST_CHECK(BondExists(r1.FindAtom("CE1"), r1.FindAtom("NE2"))); + BOOST_CHECK(BondExists(r1.FindAtom("N1"), r1.FindAtom("CA2"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA2"), r1.FindAtom("CB1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA2"), r1.FindAtom("CH"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB1"), r1.FindAtom("CG1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CG1"), r1.FindAtom("CD1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CG1"), r1.FindAtom("CD21"))); + BOOST_CHECK(BondExists(r1.FindAtom("CD1"), r1.FindAtom("CE11"))); + BOOST_CHECK(BondExists(r1.FindAtom("CD21"), r1.FindAtom("CE2"))); + BOOST_CHECK(BondExists(r1.FindAtom("CE11"), r1.FindAtom("CZ"))); + BOOST_CHECK(BondExists(r1.FindAtom("CE2"), r1.FindAtom("CZ"))); + BOOST_CHECK(BondExists(r1.FindAtom("CH"), r1.FindAtom("OH"))); + BOOST_CHECK(BondExists(r1.FindAtom("CH"), r1.FindAtom("CB11"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB11"), r1.FindAtom("CA'"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB11"), r1.FindAtom("OB1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA'"), r1.FindAtom("CB'"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA'"), r1.FindAtom("CC"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB'"), r1.FindAtom("CG11"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB'"), r1.FindAtom("CG2"))); + BOOST_CHECK(BondExists(r1.FindAtom("CC"), r1.FindAtom("O3"))); + BOOST_CHECK(BondExists(r1.FindAtom("N2"), r1.FindAtom("CA3"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA3"), r1.FindAtom("CD"))); + BOOST_CHECK(BondExists(r1.FindAtom("CA3"), r1.FindAtom("CB2"))); + BOOST_CHECK(BondExists(r1.FindAtom("CD"), r1.FindAtom("O4"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB2"), r1.FindAtom("CG12"))); + BOOST_CHECK(BondExists(r1.FindAtom("CB2"), r1.FindAtom("CG21"))); + BOOST_CHECK(BondExists(r1.FindAtom("CG12"), r1.FindAtom("CD11"))); + BOOST_CHECK(BondExists(r1.FindAtom("N3"), r1.FindAtom("CM"))); + BOOST_CHECK(BondExists(r1.FindAtom("CM"), r1.FindAtom("C21"))); + BOOST_CHECK(BondExists(r1.FindAtom("C21"), r1.FindAtom("C31"))); + BOOST_CHECK(BondExists(r1.FindAtom("C21"), r1.FindAtom("N11"))); + BOOST_CHECK(BondExists(r1.FindAtom("C31"), r1.FindAtom("C41"))); + BOOST_CHECK(BondExists(r1.FindAtom("C41"), r1.FindAtom("C51"))); + BOOST_CHECK(BondExists(r1.FindAtom("C51"), r1.FindAtom("C61"))); + BOOST_CHECK(BondExists(r1.FindAtom("C61"), r1.FindAtom("N11"))); + BOOST_CHECK(BondExists(r1.FindAtom("C"), r1.FindAtom("N"))); + BOOST_CHECK(BondExists(r1.FindAtom("C9"), r1.FindAtom("N1"))); + BOOST_CHECK(BondExists(r1.FindAtom("CC"), r1.FindAtom("N2"))); + BOOST_CHECK(BondExists(r1.FindAtom("CD"), r1.FindAtom("N3"))); } -void verify_nucleotide_nolink(const ResidueHandle& p3, const ResidueHandle& p5) +ResidueHandle make_arg(ChainHandle chain) { - BOOST_CHECK(!BondExists(p3.FindAtom("O3'"), - p5.FindAtom("P"))); + XCSEditor e=chain.GetEntity().EditXCS(); + ResidueHandle res = e.AppendResidue(chain, "ARG"); + e.InsertAtom(res, "N",geom::Vec3(20.202,33.112,58.011)); + e.InsertAtom(res, "CA",geom::Vec3(19.396,31.903,58.033)); + e.InsertAtom(res, "C",geom::Vec3(18.608,31.739,59.328)); + e.InsertAtom(res, "O",geom::Vec3(17.651,30.965,59.381)); + e.InsertAtom(res, "CB",geom::Vec3(20.284,30.681,57.801)); + e.InsertAtom(res, "CG",geom::Vec3(20.665,30.488,56.342)); + e.InsertAtom(res, "CD",geom::Vec3(21.557,29.281,56.154)); + e.InsertAtom(res, "NE",geom::Vec3(22.931,29.557,56.551)); + e.InsertAtom(res, "CZ",geom::Vec3(23.901,28.653,56.528)); + e.InsertAtom(res, "NH1",geom::Vec3(23.640,27.417,56.130)); + e.InsertAtom(res, "NH2",geom::Vec3(25.132,28.980,56.893)); + return res; } -BOOST_AUTO_TEST_SUITE( conop ); - - -BOOST_AUTO_TEST_CASE(nucleotide_based_connect) +ResidueHandle make_leu(ChainHandle chain) { - SetPrefixPath(getenv("OST_ROOT")); - String lib_path=GetSharedDataPath()+"/compounds.chemlib"; - CompoundLibPtr compound_lib=CompoundLib::Load(lib_path); - if (!compound_lib) { - std::cout << "WARNING: skipping NUCLEOTIDE_BASED connect unit test. " - << "Rule-based builder is required" << std::endl; - return; - } - RuleBasedBuilder rb_builder = RuleBasedBuilder(compound_lib); - - RuleBasedBuilder drb_builder = RuleBasedBuilder(compound_lib); - drb_builder.SetBondFeasibilityCheck(false); - - EntityHandle e=CreateEntity(); - ChainHandle c=e.EditXCS().InsertChain("A"); - ResidueHandle c0=make_cytosine(c); - ResidueHandle u1=make_uracil1(c); - ResidueHandle u2=make_uracil2(c); - - EntityHandle de=CreateEntity(); - ChainHandle dc=de.EditXCS().InsertChain("A"); - ResidueHandle du2=make_defective_uracil2(dc); - - - AtomHandleList atoms = e.GetAtomList(); - for (AtomHandleList::const_iterator i = atoms.begin(), e = atoms.end(); i!=e; ++i ){ - rb_builder.FillAtomProps(*i); - } - - atoms = de.GetAtomList(); - for (AtomHandleList::const_iterator i = atoms.begin(), e = atoms.end(); i!=e; ++i ){ - drb_builder.FillAtomProps(*i); - } - - // running positive test - BOOST_MESSAGE("running distance based checks on cytosine"); - rb_builder.ConnectAtomsOfResidue(c0); - verify_nucleotide_connectivity(c0); - BOOST_MESSAGE("running distance based checks on first uracil"); - rb_builder.ConnectAtomsOfResidue(u1); - verify_nucleotide_connectivity(u1); - BOOST_MESSAGE("running distance based checks on second uracil"); - rb_builder.ConnectAtomsOfResidue(u2); - verify_nucleotide_connectivity(u2); - BOOST_MESSAGE("connecting cytosine to first uracil"); - rb_builder.ConnectResidueToNext(c0, u1); - verify_nucleotide_link(c0, u1); - BOOST_MESSAGE("connecting first uracil to second uracil"); - rb_builder.ConnectResidueToNext(u1, u2); - verify_nucleotide_link(u1, u2); - // one negative test - BOOST_MESSAGE("connecting cytosine to second uracil"); - rb_builder.ConnectResidueToNext(c0, u2); - verify_nucleotide_nolink(c0, u2); - - // running positive test - BOOST_MESSAGE("running distance based checks on defective uracil"); - drb_builder.ConnectAtomsOfResidue(du2); - verify_nucleotide_connectivity(du2); - + XCSEditor e=chain.GetEntity().EditXCS(); + ResidueHandle res=e.AppendResidue(chain, "LEU"); + + e.InsertAtom(res, "N", geom::Vec3(19.003,32.473,60.366)); + e.InsertAtom(res, "CA", geom::Vec3(18.330,32.402,61.664)); + e.InsertAtom(res, "C", geom::Vec3(17.884,33.787,62.117)); + e.InsertAtom(res, "O", geom::Vec3(17.853,34.091,63.308)); + e.InsertAtom(res, "CB", geom::Vec3(19.269,31.793,62.710)); + e.InsertAtom(res, "CG", geom::Vec3(19.695,30.340,62.501)); + e.InsertAtom(res, "CD1", geom::Vec3(20.585,29.897,63.648)); + e.InsertAtom(res, "CD2", geom::Vec3(18.461,29.459,62.420)); + return res; } -BOOST_AUTO_TEST_CASE(rule_based_connect_1zk) +ResidueHandle make_defective_leu(ChainHandle chain) { - SetPrefixPath(getenv("OST_ROOT")); - String lib_path=GetSharedDataPath()+"/compounds.chemlib"; - CompoundLibPtr compound_lib=CompoundLib::Load(lib_path); - if (!compound_lib) { - std::cout << "WARNING: skipping NUCLEOTIDE_BASED connect unit test. " - << "Rule-based builder is required" << std::endl; - return; - } - - boost::shared_ptr<RuleBasedBuilder> drb_builder(new RuleBasedBuilder(compound_lib)); - Conopology::Instance().RegisterBuilder(drb_builder, "RBB"); - Conopology::Instance().SetDefaultBuilder("RBB"); - drb_builder->SetBondFeasibilityCheck(false); - EntityHandle e=CreateEntity(); - ChainHandle c=e.EditXCS().InsertChain("A"); - ResidueHandle r1=make_1zk(c); - Conopology::Instance().ConnectAll(drb_builder, e); - Conopology::Instance().SetDefaultBuilder("HEURISTIC"); - verify_1zk_connectivity(r1); + XCSEditor e=chain.GetEntity().EditXCS(); + ResidueHandle res=e.AppendResidue(chain, "LEU"); + + e.InsertAtom(res, "N", geom::Vec3(19.003,32.473,60.366)); + e.InsertAtom(res, "CA", geom::Vec3(18.330,32.402,61.664)); + e.InsertAtom(res, "C", geom::Vec3(17.884,33.787,62.117)); + e.InsertAtom(res, "O", geom::Vec3(17.853,34.091,63.308)); + e.InsertAtom(res, "CB", geom::Vec3(19.269,31.793,102.710)); + e.InsertAtom(res, "CG", geom::Vec3(19.695,30.340,62.501)); + e.InsertAtom(res, "CD1", geom::Vec3(20.585,29.897,63.648)); + e.InsertAtom(res, "CD2", geom::Vec3(18.461,29.459,62.420)); + return res; } -BOOST_AUTO_TEST_SUITE_END( ); +}} + diff --git a/modules/conop/tests/helper.hh b/modules/conop/tests/helper.hh new file mode 100644 index 0000000000000000000000000000000000000000..a4ad2309c340f35149579c58dc872ced07c27cf6 --- /dev/null +++ b/modules/conop/tests/helper.hh @@ -0,0 +1,27 @@ +#ifndef OST_CONOP_TEST_HELPERS_HH +#define OST_CONOP_TEST_HELPERS_HH + +#include <ost/mol/entity_handle.hh> +#include <ost/mol/residue_handle.hh> + +namespace ost { namespace conop { + +mol::ResidueHandle make_uracyl(mol::ChainHandle chain); +void verify_1zk_connectivity(const mol::ResidueHandle& r1); +mol::ResidueHandle make_cytosine(mol::ChainHandle chain); +mol::ResidueHandle make_uracil1(mol::ChainHandle chain); +mol::ResidueHandle make_uracil2(mol::ChainHandle chain); +mol::ResidueHandle make_defective_uracil2(mol::ChainHandle chain); +mol::ResidueHandle make_leu(mol::ChainHandle chain); +mol::ResidueHandle make_arg(mol::ChainHandle chain); +mol::ResidueHandle make_defective_leu(mol::ChainHandle chain); +mol::ResidueHandle make_1zk(mol::ChainHandle chain); +void verify_1zk_connectivity(const mol::ResidueHandle& r1); +void verify_nucleotide_connectivity(const mol::ResidueHandle& res); +void verify_nucleotide_link(const mol::ResidueHandle& p3, + const mol::ResidueHandle& p5); +void verify_nucleotide_nolink(const mol::ResidueHandle& p3, + const mol::ResidueHandle& p5); +}} + +#endif diff --git a/modules/conop/tests/test_builder.cc b/modules/conop/tests/test_builder.cc deleted file mode 100644 index 0d5d6537145ea27dc63cbe2960afe7f9e6b293a2..0000000000000000000000000000000000000000 --- a/modules/conop/tests/test_builder.cc +++ /dev/null @@ -1,76 +0,0 @@ -//------------------------------------------------------------------------------ -// 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 <ost/mol/mol.hh> -#include <ost/conop/builder.hh> -#include <ost/conop/heuristic_builder.hh> -#define BOOST_TEST_DYN_LINK -#include <boost/test/unit_test.hpp> -#include <boost/test/auto_unit_test.hpp> - - -// using boost::unit_test_framework::test_suite; -using namespace ost; -using namespace ost::conop; -using namespace ost::mol; - -BOOST_AUTO_TEST_SUITE( conop ); - -BOOST_AUTO_TEST_CASE(test_guess_chem_class) -{ - HeuristicBuilder h; - EntityHandle ent=mol::CreateEntity(); - XCSEditor edi=ent.EditXCS(); - ChainHandle chain=edi.InsertChain("A"); - ResidueHandle res=edi.AppendResidue(chain, "DUMMY"); - AtomHandle n=edi.InsertAtom(res, "N", geom::Vec3(1, 0, 0), "N"); - AtomHandle ca=edi.InsertAtom(res, "CA", geom::Vec3(2, 0, 0), "C"); - AtomHandle c=edi.InsertAtom(res, "C", geom::Vec3(3, 0, 0), "C"); - AtomHandle o=edi.InsertAtom(res, "O", geom::Vec3(4, 0, 0), "O"); - h.GuessChemClass(res); - BOOST_CHECK(res.IsPeptideLinking()); - res.SetChemClass(ChemClass()); - edi.SetAtomPos(n, geom::Vec3(-1,0,0)); - h.GuessChemClass(res); - BOOST_CHECK(!res.IsPeptideLinking()); -} - -BOOST_AUTO_TEST_CASE( test_builder ) -{ - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("CA", false), "C"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("CB", false), "C"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("N", false), "N"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("O", false), "O"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("CG1", false), "C"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("CG2", false), "C"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("OG1", false), "O"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("SG", false), "S"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("1HA", false), "H"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("1HB", false), "H"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("1DA", false), "D"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("1DB", false), "D"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("1HA", true), "H"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("1HB", true), "H"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("1DA", true), "D"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("1DB", true), "D"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("CA", true), "CA"); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("11", true), ""); - BOOST_CHECK_EQUAL(Builder::GuessAtomElement("11", false), ""); -} - -BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/conop/tests/test_cleanup.py b/modules/conop/tests/test_cleanup.py index 11df64187377f67f636813c2218fb37256a449cd..9c5f0cf27fc1f340aef4b48c7753b1671bd86e04 100644 --- a/modules/conop/tests/test_cleanup.py +++ b/modules/conop/tests/test_cleanup.py @@ -6,7 +6,7 @@ from ost.conop import cleanup class TestCleanUp(unittest.TestCase): def setUp(self): - self.comp_lib=conop.GetBuilder().compound_lib + self.comp_lib=conop.GetDefaultLib() self.ent = io.LoadPDB("sample_test_cleanup.pdb") self.ent_no_wat = io.LoadPDB("sample_nowater.pdb") self.ent_no_lig = io.LoadPDB("sample_noligands.pdb") @@ -156,8 +156,8 @@ class TestCleanUp(unittest.TestCase): self.assertFalse(self.new_ent.residues[6].IsPeptideLinking()) # here assertFalse instead of assertTrue self.assertTrue(self.new_ent.residues[6].atoms[0].is_hetatom) -if not hasattr(conop.GetBuilder(), 'compound_lib'): - print 'Default builder without compound lib. Ignoring test_cleanup.py tests' +if not conop.GetDefaultLib(): + print 'No compound library available. Ignoring test_cleanup.py tests' sys.exit() if __name__== '__main__': diff --git a/modules/conop/tests/test_compound.py b/modules/conop/tests/test_compound.py index a215a78f7a5dd966c2619346aaabf0f084b7bbd7..700f52b286d6e7f842cd004c2dffff6006603436 100644 --- a/modules/conop/tests/test_compound.py +++ b/modules/conop/tests/test_compound.py @@ -5,7 +5,7 @@ from ost import conop class TestCompound(unittest.TestCase): def setUp(self): - self.compound_lib=conop.GetBuilder().compound_lib + self.compound_lib=conop.GetDefaultLib() def testFindCompound(self): compound=self.compound_lib.FindCompound('***') @@ -22,9 +22,8 @@ class TestCompound(unittest.TestCase): if __name__=='__main__': - builder=conop.GetBuilder() - if not hasattr(builder, 'compound_lib'): - print 'default builder does not use compound library. ignoring unit tests' + if not conop.GetDefaultLib(): + print 'No compound library available. ignoring compound unit tests' else: from ost import testutils testutils.RunTests() diff --git a/modules/conop/tests/test_heuristic_conop.cc b/modules/conop/tests/test_heuristic_conop.cc new file mode 100644 index 0000000000000000000000000000000000000000..4943393161d1e3f8911073d67a6f261ccc091f2f --- /dev/null +++ b/modules/conop/tests/test_heuristic_conop.cc @@ -0,0 +1,144 @@ +// ------------------------------------------------------------------------------ +// 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 <ost/log.hh> +#include <ost/mol/mol.hh> +#include <ost/conop/heuristic.hh> + +#define BOOST_TEST_DYN_LINK +#include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> +#include "helper.hh" +using boost::unit_test_framework::test_suite; +using namespace ost; +using namespace ost::conop; +using namespace ost::mol; + + + +void verify_connectivity_x(const ResidueHandle& res) +{ + BOOST_CHECK(BondExists(res.FindAtom("XN"), + res.FindAtom("XCA"))); + BOOST_CHECK(BondExists(res.FindAtom("XCA"), + res.FindAtom("XC"))); + BOOST_CHECK(BondExists(res.FindAtom("XC"), + res.FindAtom("XO"))); + BOOST_CHECK(BondExists(res.FindAtom("XCA"), + res.FindAtom("XCB"))); + BOOST_CHECK(BondExists(res.FindAtom("XCB"), + res.FindAtom("XCG"))); + if (res.GetKey()=="ARG") { + + BOOST_CHECK(BondExists(res.FindAtom("XCB"), + res.FindAtom("XCG"))); + BOOST_CHECK(BondExists(res.FindAtom("XCG"), + res.FindAtom("XCD"))); + BOOST_CHECK(BondExists(res.FindAtom("XCD"), + res.FindAtom("XNE"))); + BOOST_CHECK(BondExists(res.FindAtom("XNE"), + res.FindAtom("XCZ"))); + BOOST_CHECK(BondExists(res.FindAtom("XCZ"), + res.FindAtom("XNH1"))); + BOOST_CHECK(BondExists(res.FindAtom("XCZ"), + res.FindAtom("XNH2"))); + // TODO: Check that no other atoms are connected! + } + if (res.GetKey()=="ILE") { + BOOST_CHECK(BondExists(res.FindAtom("XCG"), + res.FindAtom("XCD1"))); + BOOST_CHECK(BondExists(res.FindAtom("XCG"), + res.FindAtom("XCD2"))); + // TODO: Check that no other atoms are connected! + } +} + +void verify_connectivity(const ResidueHandle& res) +{ + BOOST_CHECK(BondExists(res.FindAtom("N"), + res.FindAtom("CA"))); + BOOST_CHECK(BondExists(res.FindAtom("CA"), + res.FindAtom("C"))); + BOOST_CHECK(BondExists(res.FindAtom("C"), + res.FindAtom("O"))); + BOOST_CHECK(BondExists(res.FindAtom("CA"), + res.FindAtom("CB"))); + BOOST_CHECK(BondExists(res.FindAtom("CB"), + res.FindAtom("CG"))); + if (res.GetKey()=="ARG") { + + BOOST_CHECK(BondExists(res.FindAtom("CB"), + res.FindAtom("CG"))); + BOOST_CHECK(BondExists(res.FindAtom("CG"), + res.FindAtom("CD"))); + BOOST_CHECK(BondExists(res.FindAtom("CD"), + res.FindAtom("NE"))); + BOOST_CHECK(BondExists(res.FindAtom("NE"), + res.FindAtom("CZ"))); + BOOST_CHECK(BondExists(res.FindAtom("CZ"), + res.FindAtom("NH1"))); + BOOST_CHECK(BondExists(res.FindAtom("CZ"), + res.FindAtom("NH2"))); + // TODO: Check that no other atoms are connected! + } + if (res.GetKey()=="ILE") { + BOOST_CHECK(BondExists(res.FindAtom("CG"), + res.FindAtom("CD1"))); + BOOST_CHECK(BondExists(res.FindAtom("CG"), + res.FindAtom("CD2"))); + // TODO: Check that no other atoms are connected! + } +} + +BOOST_AUTO_TEST_SUITE( conop ); + + +BOOST_AUTO_TEST_CASE(does_name_based_connect) +{ + EntityHandle e=CreateEntity(); + ChainHandle c=e.EditXCS().InsertChain("A"); + ResidueHandle ile=make_leu(c); + ResidueHandle arg=make_arg(c); + HeuristicProcessor proc; + proc.Process(e); + + verify_connectivity(arg); + verify_connectivity(ile); +} + +BOOST_AUTO_TEST_CASE(does_assign_torsions) { + EntityHandle e=CreateEntity(); + ChainHandle c=e.EditXCS().InsertChain("A"); + ResidueHandle l1=make_leu(c); + ResidueHandle a2=make_arg(c); + ResidueHandle l3=make_leu(c); + e.EditXCS().Connect(l1.FindAtom("C"), a2.FindAtom("N")); + e.EditXCS().Connect(a2.FindAtom("C"), l3.FindAtom("N")); + HeuristicProcessor proc; + proc.SetAssignTorsions(true); + proc.Process(e); + BOOST_CHECK(a2.GetPhiTorsion().IsValid()); + BOOST_CHECK(l3.GetPhiTorsion().IsValid()); + + BOOST_CHECK(l1.GetPsiTorsion().IsValid()); + BOOST_CHECK(a2.GetPsiTorsion().IsValid()); +} + +BOOST_AUTO_TEST_SUITE_END(); + diff --git a/modules/conop/tests/test_nonstandard.py b/modules/conop/tests/test_nonstandard.py index 170749c6eacd73bc64f4b6826e4df5d80f104512..f10b7d9d0324b5783a8ad6b0e0c162c8b818c828 100644 --- a/modules/conop/tests/test_nonstandard.py +++ b/modules/conop/tests/test_nonstandard.py @@ -117,9 +117,8 @@ class TestNonStandard(unittest.TestCase): if __name__ == "__main__": - builder=conop.GetBuilder() - if not hasattr(builder, 'compound_lib'): - print 'default builder does not use compound library. ignoring unit tests' + if not conop.GetDefaultLib(): + print 'No compound library available. Ignoring unit tests' else: from ost import testutils testutils.RunTests() diff --git a/modules/conop/tests/test_processor.py b/modules/conop/tests/test_processor.py new file mode 100644 index 0000000000000000000000000000000000000000..94a1a7c27d4009a86feeb5d97c671e0e6b5038f5 --- /dev/null +++ b/modules/conop/tests/test_processor.py @@ -0,0 +1,22 @@ +import unittest +from ost import conop, mol + + +class TestProcessor(unittest.TestCase): + def testPyWrap(self): + class MyProc(conop.Processor): + def __init__(self): + conop.Processor.__init__(self) + self.count =0 + def DoProcess(self, diag, ent): + self.count+=1 + p = MyProc() + ent = mol.CreateEntity() + p.Process(ent) + self.assertEqual(p.count, 1) + +if __name__ == "__main__": + from ost import testutils + testutils.RunTests() + + diff --git a/modules/conop/tests/test_rule_based_conop.cc b/modules/conop/tests/test_rule_based_conop.cc new file mode 100644 index 0000000000000000000000000000000000000000..6444695d9f85cece9e06c9b4c6153ec8645963ba --- /dev/null +++ b/modules/conop/tests/test_rule_based_conop.cc @@ -0,0 +1,200 @@ + +// ----------------------------------------------------------------------------- +// 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 +// ----------------------------------------------------------------------------- + +#define BOOST_TEST_DYN_LINK +#include <boost/test/unit_test.hpp> +#include <boost/test/auto_unit_test.hpp> + +#include <ost/mol/mol.hh> +#include <ost/platform.hh> +#include <ost/log.hh> +#include <ost/conop/rule_based.hh> +#include <ost/conop/conop.hh> +#include "helper.hh" + +using boost::unit_test_framework::test_suite; +using namespace ost; +using namespace ost::conop; +//using namespace ost::io; +using namespace ost::mol; + +CompoundLibPtr load_lib() +{ + if (!getenv("OST_ROOT")) { + LOG_ERROR("OST_ROOT environment variable not set. Can't load " + "compound library without a proper OST_ROOT"); + return CompoundLibPtr(); + } + SetPrefixPath(getenv("OST_ROOT")); + String lib_path=GetSharedDataPath()+"/compounds.chemlib"; + CompoundLibPtr compound_lib=CompoundLib::Load(lib_path); + return compound_lib; +} + +BOOST_AUTO_TEST_SUITE(conop); + +BOOST_AUTO_TEST_CASE(rule_based_set_get_flags) +{ + CompoundLibPtr lib=load_lib(); + if (!lib) { return; } + RuleBasedProcessor rbc(lib); + // check the defaults + BOOST_CHECK_EQUAL(rbc.GetConnect(), true); + BOOST_CHECK_EQUAL(rbc.GetCheckBondFeasibility(), false); + BOOST_CHECK_EQUAL(rbc.GetUnkAtomTreatment(), CONOP_WARN); + BOOST_CHECK_EQUAL(rbc.GetUnkResidueTreatment(), CONOP_WARN); + BOOST_CHECK_EQUAL(rbc.GetStrictHydrogens(), false); + rbc.SetConnect(false); + rbc.SetStrictHydrogens(true); + rbc.SetCheckBondFeasibility(true); + rbc.SetUnkResidueTreatment(CONOP_FATAL); + rbc.SetUnkAtomTreatment(CONOP_REMOVE); + BOOST_CHECK_EQUAL(rbc.GetConnect(), false); + BOOST_CHECK_EQUAL(rbc.GetStrictHydrogens(), true); + BOOST_CHECK_EQUAL(rbc.GetCheckBondFeasibility(),true); + BOOST_CHECK_EQUAL(rbc.GetUnkResidueTreatment(),CONOP_FATAL); + BOOST_CHECK_EQUAL(rbc.GetUnkAtomTreatment(),CONOP_REMOVE); +} + + +BOOST_AUTO_TEST_CASE(rule_based_connect) +{ + CompoundLibPtr lib=load_lib(); + if (!lib) { return; } + RuleBasedProcessor rbc(lib); + EntityHandle ent = CreateEntity(); + ChainHandle ch=ent.EditXCS().InsertChain("A"); + ResidueHandle r = make_cytosine(ch); + rbc.SetConnect(false); + rbc.Process(ent); + BOOST_CHECK_EQUAL(static_cast<size_t>(0), + ent.GetBondList().size()); + rbc.SetConnect(true); + rbc.Process(ent); + verify_nucleotide_connectivity(r); +} + + +BOOST_AUTO_TEST_CASE(rule_based_unk_atoms) +{ + CompoundLibPtr lib = load_lib(); + if (!lib) { return; } + RuleBasedProcessor rbc(lib); + EntityHandle ent = CreateEntity(); + XCSEditor edi=ent.EditXCS(); + ChainHandle ch = edi.InsertChain("A"); + ResidueHandle gly = edi.AppendResidue(ch, "GLY"); + edi.InsertAtom(gly, "N", geom::Vec3()); + edi.InsertAtom(gly, "CA", geom::Vec3()); + edi.InsertAtom(gly, "C", geom::Vec3()); + edi.InsertAtom(gly, "O", geom::Vec3()); + edi.InsertAtom(gly, "CB", geom::Vec3()); + EntityHandle ent2 = ent.Copy(); + rbc.SetUnkAtomTreatment(CONOP_SILENT); + DiagnosticsPtr diags=rbc.Process(ent2); + BOOST_CHECK_EQUAL(diags->diag_count(), static_cast<size_t>(0)); + rbc.SetUnkAtomTreatment(CONOP_WARN); + diags = rbc.Process(ent2); + BOOST_CHECK_EQUAL(diags->diag_count(), static_cast<size_t>(1)); + ent2 = ent.Copy(); + rbc.SetUnkAtomTreatment(CONOP_REMOVE); + rbc.Process(ent2); + BOOST_CHECK(!ent2.FindAtom("A", 1, "CB")); + ent2 = ent.Copy(); + rbc.SetUnkAtomTreatment(CONOP_REMOVE_RESIDUE); + rbc.Process(ent2); + BOOST_CHECK_EQUAL(ent2.GetResidueCount(), 0); +} + +BOOST_AUTO_TEST_CASE(guesses_elements_of_unknown_atoms) +{ + CompoundLibPtr lib = load_lib(); + if (!lib) { return; } + RuleBasedProcessor rbc(lib); + EntityHandle ent = CreateEntity(); + XCSEditor edi=ent.EditXCS(); + ChainHandle ch = edi.InsertChain("A"); + ResidueHandle gly = edi.AppendResidue(ch, "???"); + ResidueHandle gly2 = edi.AppendResidue(ch, "GLY"); + AtomHandle ca1 = edi.InsertAtom(gly, "CA", geom::Vec3(0,0,0)); + AtomHandle ca2 = edi.InsertAtom(gly2, "CX", geom::Vec3(0,0,0)); + DiagnosticsPtr diags=rbc.Process(ent); + BOOST_CHECK_EQUAL(ca1.GetElement(), "C"); + BOOST_CHECK_EQUAL(ca2.GetElement(), "C"); +} + +BOOST_AUTO_TEST_CASE(fills_properties_of_unknown_residues) +{ + CompoundLibPtr lib = load_lib(); + if (!lib) { return; } + RuleBasedProcessor rbc(lib); + EntityHandle ent = CreateEntity(); + XCSEditor edi=ent.EditXCS(); + ChainHandle ch = edi.InsertChain("A"); + ResidueHandle gly = edi.AppendResidue(ch, "???"); + gly.SetOneLetterCode('G'); + gly.SetChemClass(ChemClass(ChemClass::PEPTIDE_LINKING)); + DiagnosticsPtr diags=rbc.Process(ent); + BOOST_CHECK_EQUAL(gly.GetOneLetterCode(), '?'); + BOOST_CHECK_EQUAL(gly.GetName(), "???"); + BOOST_CHECK_EQUAL(gly.GetChemClass(), ChemClass(ChemClass::UNKNOWN)); +} + +BOOST_AUTO_TEST_CASE(connects_atoms_of_unknown_residues_based_on_distance) +{ + + CompoundLibPtr lib = load_lib(); + if (!lib) { return; } + RuleBasedProcessor rbc(lib); + EntityHandle ent = CreateEntity(); + XCSEditor edi=ent.EditXCS(); + ChainHandle ch = edi.InsertChain("A"); + ResidueHandle gly = edi.AppendResidue(ch, "???"); + AtomHandle ca = edi.InsertAtom(gly, "CA", geom::Vec3(0,0,0)); + AtomHandle c = edi.InsertAtom(gly, "C", geom::Vec3(1.54,0,0)); + AtomHandle o = edi.InsertAtom(gly, "O", geom::Vec3(1.54,3,0)); + DiagnosticsPtr diags=rbc.Process(ent); + BOOST_CHECK(BondExists(ca, c)); + BOOST_CHECK(!BondExists(c, o)); +} + +BOOST_AUTO_TEST_CASE(rule_based_unk_res) +{ + CompoundLibPtr lib = load_lib(); + if (!lib) { return; } + RuleBasedProcessor rbc(lib); + EntityHandle ent = CreateEntity(); + XCSEditor edi=ent.EditXCS(); + ChainHandle ch = edi.InsertChain("A"); + ResidueHandle gly = edi.AppendResidue(ch, "???"); + EntityHandle ent2 = ent.Copy(); + rbc.SetUnkResidueTreatment(CONOP_SILENT); + DiagnosticsPtr diags=rbc.Process(ent2); + BOOST_CHECK_EQUAL(diags->diag_count(), static_cast<size_t>(0)); + rbc.SetUnkResidueTreatment(CONOP_WARN); + diags = rbc.Process(ent2); + BOOST_CHECK_EQUAL(diags->diag_count(), static_cast<size_t>(1)); + ent2 = ent.Copy(); + rbc.SetUnkResidueTreatment(CONOP_REMOVE); + rbc.Process(ent2); + BOOST_CHECK(!ent2.FindResidue("A", 1)); +} + +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/geom/pymod/export_mat4.cc b/modules/geom/pymod/export_mat4.cc index ec003a0e36105c29014fc8c93c1c80845cf5b805..c457eb2618833c699cc8dd925ee235dcb015d0ff 100644 --- a/modules/geom/pymod/export_mat4.cc +++ b/modules/geom/pymod/export_mat4.cc @@ -18,10 +18,12 @@ //------------------------------------------------------------------------------ #define BOOST_PYTHON_MAX_ARITY 20 #include <boost/python.hpp> +#include <boost/python/suite/indexing/vector_indexing_suite.hpp> #include <boost/python/slice.hpp> using namespace boost::python; #include <ost/geom/geom.hh> +#include <ost/geom/export_helper/vector.hh> using namespace geom; @@ -138,4 +140,9 @@ void export_Mat4() .def("PasteTranslation",&Mat4::PasteTranslation) .add_property("data",mat4_data) ; + + class_<Mat4List>("Mat4List", init<>()) + .def(vector_indexing_suite<Mat4List>()) + .def(geom::VectorAdditions<Mat4List>()) + ; } diff --git a/modules/geom/src/mat4.hh b/modules/geom/src/mat4.hh index 998bbc485fe885d0f3734ef543dc4dec724d0a2c..95ca3d63270923145c57d0e56f61889ae31741d4 100644 --- a/modules/geom/src/mat4.hh +++ b/modules/geom/src/mat4.hh @@ -22,6 +22,7 @@ #include <cassert> #include <cstddef> // for size_t #include <ostream> +#include <vector> #include <boost/operators.hpp> @@ -136,6 +137,8 @@ double i32, double i33); }; +typedef std::vector<Mat4> Mat4List; + DLLEXPORT_OST_GEOM std::ostream& operator<<(std::ostream& os, const Mat4& m); } // ns geom diff --git a/modules/gui/pymod/dng/init.py b/modules/gui/pymod/dng/init.py index ffe73d8b77d085e6c9aeb6c0cbd4a0ea8d894b6f..4be7ed291f886c072dc9198d2ddbaf11dac9f438 100644 --- a/modules/gui/pymod/dng/init.py +++ b/modules/gui/pymod/dng/init.py @@ -35,17 +35,17 @@ def _my_exit(code): sys._exit=sys.exit sys.exit=_my_exit -def _InitRuleBasedBuilder(): +def _InitRuleBasedProcessor(): compound_lib_path=os.path.join(ost.GetSharedDataPath(), 'compounds.chemlib') if os.path.exists(compound_lib_path): conop_inst=conop.Conopology.Instance() compound_lib=conop.CompoundLib.Load(compound_lib_path) - conop_inst.RegisterBuilder(conop.RuleBasedBuilder(compound_lib), 'RBB') - conop_inst.SetDefaultBuilder('RBB') + conop_inst.SetDefaultLib(compound_lib) + io.profiles['DEFAULT'].processor = conop.RuleBasedProcessor(compound_lib) -# switch to rule-based builder for high fidelity if compounds.chemlib is +# switch to rule-based processor for high fidelity if compounds.chemlib is # available -_InitRuleBasedBuilder() +_InitRuleBasedProcessor() def _CheckRestore(): settings = QtCore.QSettings() @@ -165,8 +165,8 @@ parser.add_option("-v", "--verbosity_level", action="store", type="int", dest="v help="sets the verbosity level [default: %default]") parser.add_option("-s", "--script", action="callback", default=[], dest="script", type="string", callback=parse_script_option, help="executes a script (syntax: -s SCRIPT [options] [args]) Anything that follows this option is passed to the script") parser.add_option("-p", "--pdb_id", dest="pdb_ids", default=[],action="append", help="PDB file ID. The file will be retrieved from PDB") -parser.add_option("-b", "--builder", dest="builder", default="HEURISTIC", help="Type of builder used by the progam (either RULE_BASED or HEURISTIC) [default: %default]") -parser.add_option("-c", "--compound_library", dest="complib", default="compounds.chemlib", help="Compound library for the RULE_BASED builder (only used if --builder option is set to RULE_BASED, otherwise ignored [default: %default]") +parser.add_option("-b", "--processor", dest="processor", default="HEURISTIC", help="Type of processor used by the progam (either RULE_BASED or HEURISTIC) [default: %default]") +parser.add_option("-c", "--compound_library", dest="complib", default="compounds.chemlib", help="Compound library for the RULE_BASED processor (only used if --processor option is set to RULE_BASED, otherwise ignored [default: %default]") parser.add_option("-q", "--query", dest="query", default="", help="Selection query to be highlighted automatically upon loading (only used together with -p option or when a PDB file is loaded, otherwise ignored [default: None]") parser.add_option("-S","--stereo", dest="try_stereo", default=False, action="store_true",help="try to get a quad-buffer stereo visual") parser.disable_interspersed_args() @@ -184,12 +184,12 @@ if len(parser.rargs)!=0: if len(options.script)!=0: script_argv=options.script -if options.builder=="RULE_BASED": +if options.processor=="RULE_BASED": from ost import conop - compound_lib=conop.CompoundLib.Load(options.complib) - rbb=conop.RuleBasedBuilder(compound_lib) - conop.Conopology.Instance().RegisterBuilder(rbb,'rbb') - conop.Conopology.Instance().SetDefaultBuilder('rbb') + if os.path.exists(options.complib): + compound_lib=conop.CompoundLib.Load(options.complib) + conop.SetDefaultLib(compound_lib) + io.profiles['DEFAULT'].processor = conop.RuleBasedProcessor(compound_lib) home = os.getenv('HOME') or os.getenv('USERPROFILE') _ostrc=os.path.join(home, '.ostrc') diff --git a/modules/gui/src/file_loader.cc b/modules/gui/src/file_loader.cc index bc69ba7b852e035afa0c9417b46f2c4217d39f03..99a3da1f03ac99aa56bb75839c591db9b5159437 100644 --- a/modules/gui/src/file_loader.cc +++ b/modules/gui/src/file_loader.cc @@ -25,6 +25,7 @@ #include <ost/io/io_manager.hh> #include <ost/io/mol/pdb_reader.hh> +#include <ost/io/mol/io_profile.hh> #include <ost/io/mol/load_entity.hh> #include <ost/io/mol/load_surface.hh> #include <ost/io/mol/entity_io_pdb_handler.hh> @@ -220,9 +221,11 @@ gfx::GfxObjP FileLoader::TryLoadEntity(const QString& filename, io::EntityIOHand mol::EntityHandle eh=mol::CreateEntity(); mol::XCSEditor xcs_lock=eh.EditXCS(mol::BUFFERED_EDIT); handler->Import(eh,filename.toStdString()); - if(handler->RequiresBuilder()) { - conop::BuilderP builder = conop::Conopology::Instance().GetBuilder(); - conop::Conopology::Instance().ConnectAll(builder,eh,0); + if(handler->RequiresProcessor()) { + io::IOProfile& prof = io::IOProfileRegistry::Instance().GetDefault(); + if (prof.processor) { + prof.processor->Process(eh); + } } gfx::GfxObjP obj(new gfx::Entity(file_info.baseName().toStdString(), eh, mol::Query(selection.toStdString()))); @@ -353,7 +356,6 @@ void FileLoader::LoadPDB(const QString& filename, const QString& selection) { io::PDBReader reader(filename.toStdString(), io::IOProfile()); QList<mol::EntityHandle> entities; - conop::BuilderP builder=conop::Conopology::Instance().GetBuilder("DEFAULT"); while (reader.HasNext()){ mol::EntityHandle ent=mol::CreateEntity(); try { @@ -362,7 +364,10 @@ void FileLoader::LoadPDB(const QString& filename, const QString& selection) LOG_ERROR(e.what()); continue; } - conop::Conopology::Instance().ConnectAll(builder,ent,0); + io::IOProfile& prof = io::IOProfileRegistry::Instance().GetDefault(); + if (prof.processor) { + prof.processor->Process(ent); + } entities.append(ent); } QFileInfo file_info(filename); diff --git a/modules/io/doc/mmcif.rst b/modules/io/doc/mmcif.rst index 50eb8cffed40ff887c236aa266a4f2304456a785..b8c63d9dedf7b0184ca835713de65b4ea5116f35 100644 --- a/modules/io/doc/mmcif.rst +++ b/modules/io/doc/mmcif.rst @@ -607,8 +607,7 @@ of the annotation available. Since this function is at the moment mainly used to create biounits from mmCIF files to be saved as PDBs, the function assumes that the - :ref:`ChainType` properties are set correctly. :func:`ost.conop.ConnectAll` - is used to derive connectivity. + :ref:`ChainType` properties are set correctly. :param asu: Asymmetric unit to work on. Should be created from a mmCIF file. @@ -994,6 +993,7 @@ of the annotation available. .. LocalWords: auth GetMMCifPDBChainTr AddPDBCMMCifhainTr GetPDBMMCifChainTr .. LocalWords: GetRevisions AddRevision SetRevisionsDateOriginal GetSize .. LocalWords: GetNum num GetStatus GetLastDate GetFirstRelease storable +.. LocalWords: cas isbn pubmed asu seqres conop casp COMPND OBSLTE .. LocalWords: SetChainList MMCifInfoTransOp ChainTypes MMCifInfoStructRef .. LocalWords: MMCifInfoRevisions bool difs MMCifInfoStructRefSeqDif rnum .. LocalWords: SetDateOriginal GetDateOriginal yyyy operationsintervalls diff --git a/modules/io/pymod/__init__.py b/modules/io/pymod/__init__.py index 179808c8d6452832329617ac22f86678cf556fdd..7fcf429230c8eeddcd1a5873286d0312a056c239 100644 --- a/modules/io/pymod/__init__.py +++ b/modules/io/pymod/__init__.py @@ -19,7 +19,7 @@ import os, tempfile, ftplib, httplib from _ost_io import * -from ost import mol, geom, conop +from ost import mol, geom, conop, seq profiles=None @@ -44,14 +44,16 @@ class IOProfiles: if not profiles: profiles=IOProfiles() + if conop.GetDefaultLib(): + processor = conop.RuleBasedProcessor(conop.GetDefaultLib()) + else: + processor = conop.HeuristicProcessor() profiles['STRICT']=IOProfile(dialect='PDB', fault_tolerant=False, - strict_hydrogens=False, quack_mode=False) + quack_mode=False, processor=processor.Copy()) profiles['SLOPPY']=IOProfile(dialect='PDB', fault_tolerant=True, - strict_hydrogens=False, quack_mode=True, - bond_feasibility_check=True) + quack_mode=True, processor=processor.Copy()) profiles['CHARMM']=IOProfile(dialect='CHARMM', fault_tolerant=True, - strict_hydrogens=False, quack_mode=False, - bond_feasibility_check=True) + quack_mode=False, processor=processor.Copy()) profiles['DEFAULT']='STRICT' def _override(val1, val2): @@ -64,7 +66,7 @@ def LoadPDB(filename, restrict_chains="", no_hetatms=None, fault_tolerant=None, load_multi=False, quack_mode=None, join_spread_atom_records=None, calpha_only=None, profile='DEFAULT', remote=False, dialect=None, - strict_hydrogens=None, seqres=False, bond_feasibility_check=None): + seqres=False, bond_feasibility_check=None): """ Load PDB file from disk and return one or more entities. Several options allow to customize the exact behaviour of the PDB import. For more information @@ -102,8 +104,6 @@ def LoadPDB(filename, restrict_chains="", no_hetatms=None, :type dialect: :class:`str` - :param strict_hydrogens: If set, overrides the value of - :attr:`IOProfile.strict_hydrogens`. :raises: :exc:`~ost.io.IOException` if the import fails due to an erroneous or inexistent file @@ -126,9 +126,10 @@ def LoadPDB(filename, restrict_chains="", no_hetatms=None, prof.no_hetatms=_override(prof.no_hetatms, no_hetatms) prof.dialect=_override(prof.dialect, dialect) prof.quack_mode=_override(prof.quack_mode, quack_mode) - prof.strict_hydrogens=_override(prof.strict_hydrogens, strict_hydrogens) + if prof.processor: + prof.processor.check_bond_feasibility=_override(prof.processor.check_bond_feasibility, + bond_feasibility_check) prof.fault_tolerant=_override(prof.fault_tolerant, fault_tolerant) - prof.bond_feasibility_check=_override(prof.bond_feasibility_check, bond_feasibility_check) prof.join_spread_atom_records=_override(prof.join_spread_atom_records, join_spread_atom_records) @@ -139,13 +140,11 @@ def LoadPDB(filename, restrict_chains="", no_hetatms=None, filename = tmp_file.name conop_inst=conop.Conopology.Instance() - builder=conop_inst.GetBuilder("DEFAULT") - if prof.dialect=='PDB': - builder.dialect=conop.PDB_DIALECT - elif prof.dialect=='CHARMM': - builder.dialect=conop.CHARMM_DIALECT - builder.strict_hydrogens=prof.strict_hydrogens - builder.bond_feasibility_check=prof.bond_feasibility_check + if prof.processor: + if prof.dialect=='PDB': + prof.processor.dialect=conop.PDB_DIALECT + elif prof.dialect=='CHARMM': + prof.processor.dialect=conop.CHARMM_DIALECT reader=PDBReader(filename, prof) reader.read_seqres=seqres try: @@ -154,7 +153,8 @@ def LoadPDB(filename, restrict_chains="", no_hetatms=None, while reader.HasNext(): ent=mol.CreateEntity() reader.Import(ent, restrict_chains) - conop_inst.ConnectAll(builder, ent, 0) + if prof.processor: + prof.processor.Process(ent) ent_list.append(ent) if len(ent_list)==0: raise IOError("File '%s' doesn't contain any entities" % filename) @@ -163,7 +163,8 @@ def LoadPDB(filename, restrict_chains="", no_hetatms=None, ent=mol.CreateEntity() if reader.HasNext(): reader.Import(ent, restrict_chains) - conop_inst.ConnectAll(builder, ent, 0) + if prof.processor: + prof.processor.Process(ent) else: raise IOError("File '%s' doesn't contain any entities" % filename) if seqres: @@ -255,7 +256,7 @@ def LoadCHARMMTraj(crd, dcd_file=None, profile='CHARMM', raise ValueError("No DCD filename given") return LoadCHARMMTraj_(crd, dcd_file, stride, lazy_load, detect_swap, swap_bytes) -def LoadMMCIF(filename, restrict_chains="", fault_tolerant=None, calpha_only=None, profile='DEFAULT', remote=False, strict_hydrogens=None, seqres=False, info=False): +def LoadMMCIF(filename, restrict_chains="", fault_tolerant=None, calpha_only=None, profile='DEFAULT', remote=False, seqres=False, info=False): """ Load MMCIF file from disk and return one or more entities. Several options allow to customize the exact behaviour of the MMCIF import. For more @@ -275,9 +276,6 @@ def LoadMMCIF(filename, restrict_chains="", fault_tolerant=None, calpha_only=Non :rtype: :class:`~ost.mol.EntityHandle`. - :param strict_hydrogens: If set, overrides the value of - :attr:`IOProfile.strict_hydrogens`. - :param seqres: Whether to read SEQRES records. If set to True, the loaded entity and seqres entry will be returned as second item. @@ -298,7 +296,6 @@ def LoadMMCIF(filename, restrict_chains="", fault_tolerant=None, calpha_only=Non prof = profile.Copy() prof.calpha_only=_override(prof.calpha_only, calpha_only) - prof.strict_hydrogens=_override(prof.strict_hydrogens, strict_hydrogens) prof.fault_tolerant=_override(prof.fault_tolerant, fault_tolerant) if remote: @@ -308,18 +305,14 @@ def LoadMMCIF(filename, restrict_chains="", fault_tolerant=None, calpha_only=Non else: raise IOError('Can not load PDB %s from www.pdb.org'%filename) - conop_inst = conop.Conopology.Instance() - builder = conop_inst.GetBuilder("DEFAULT") - - builder.strict_hydrogens = prof.strict_hydrogens - try: ent = mol.CreateEntity() reader = MMCifReader(filename, ent, prof) reader.read_seqres = seqres #if reader.HasNext(): reader.Parse() - conop_inst.ConnectAll(builder, ent, 0) + if prof.processor: + prof.processor.Process(ent) #else: # raise IOError("File doesn't contain any entities") if seqres and info: @@ -340,39 +333,21 @@ def LoadMMCIF(filename, restrict_chains="", fault_tolerant=None, calpha_only=Non # MMCifInfoBioUnit.PDBize, since this function is not included in SPHINX. def _PDBize(biounit, asu, seqres=None, min_polymer_size=10, transformation=False): - def _CopyAtoms(src_res, dst_res, edi, trans=geom.Mat4()): - atom_pos_wrong = False - for atom in src_res.atoms: - tmp_pos = geom.Vec4(atom.pos) - new_atom=edi.InsertAtom(dst_res, atom.name, geom.Vec3(trans*tmp_pos), - element=atom.element, - occupancy=atom.occupancy, - b_factor=atom.b_factor, - is_hetatm=atom.is_hetatom) - for p in range(0,3): - if new_atom.pos[p] <= -1000: - atom_pos_wrong = True - elif new_atom.pos[p] >= 10000: - atom_pos_wrong = True - return atom_pos_wrong - - chain_names='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz' - cur_chain_name = 0 - water_chain = mol.ChainHandle() - ligand_chain = mol.ChainHandle() - a_pos_wrong = False - pdb_bu = mol.CreateEntity() - edi = pdb_bu.EditXCS(mol.BUFFERED_EDIT) + pdbizer = mol.alg.PDBize(min_polymer_size=min_polymer_size) + chains = biounit.GetChainList() c_intvls = biounit.GetChainIntervalList() o_intvls = biounit.GetOperationsIntervalList() + ss = seqres + if not ss: + ss = seq.CreateSequenceList() # create list of operations # for cartesian products, operations are stored in a list, multiplied with # the next list of operations and re-stored... until all lists of operations # are multiplied in an all-against-all manner. operations = biounit.GetOperations() for i in range(0,len(c_intvls)): - trans_matrices = list() + trans_matrices = geom.Mat4List() l_operations = operations[o_intvls[i][0]:o_intvls[i][1]] if len(l_operations) > 0: for op in l_operations[0]: @@ -398,95 +373,10 @@ def _PDBize(biounit, asu, seqres=None, min_polymer_size=10, trans_matrices = tmp_ops # select chains into a view as basis for each transformation assu = asu.Select('cname='+','.join(chains[c_intvls[i][0]:c_intvls[i][1]])) - # use each transformation on the view, store as entity and transform, PDBize - # the result while adding everything to one large entity - for tr in trans_matrices: - # do a PDBize, add each new entity to the end product - for chain in assu.chains: - residue_count = len(chain.residues) - if seqres: - seqres_chain = seqres.FindSequence(chain.name) - if seqres_chain.IsValid(): - residue_count = len(seqres_chain) - if chain.is_polymer and residue_count >= min_polymer_size: - if len(chain_names) == cur_chain_name: - raise RuntimeError('Running out of chain names') - new_chain = edi.InsertChain(chain_names[cur_chain_name]) - cur_chain_name += 1 - edi.SetChainDescription(new_chain, chain.description) - edi.SetChainType(new_chain, chain.type) - new_chain.SetStringProp('original_name', chain.name) - if chain.HasProp("pdb_auth_chain_name"): - new_chain.SetStringProp("pdb_auth_chain_name", - chain.GetStringProp("pdb_auth_chain_name")) - for res in chain.residues: - new_res = edi.AppendResidue(new_chain, res.name, res.number) - a_b = _CopyAtoms(res, new_res, edi, tr) - if not a_pos_wrong: - a_pos_wrong = a_b - elif chain.type == mol.CHAINTYPE_WATER: - if not water_chain.IsValid(): - # water gets '-' as name - water_chain = edi.InsertChain('-') - edi.SetChainDescription(water_chain, chain.description) - edi.SetChainType(water_chain, chain.type) - for res in chain.residues: - new_res = edi.AppendResidue(water_chain, res.name) - new_res.SetStringProp('type', mol.StringFromChainType(chain.type)) - new_res.SetStringProp('description', chain.description) - a_b = _CopyAtoms(res, new_res, edi, tr) - if not a_pos_wrong: - a_pos_wrong = a_b - else: - if not ligand_chain.IsValid(): - # all ligands, put in one chain, are named '_' - ligand_chain = edi.InsertChain('_') - last_rnum = 0 - else: - last_rnum = ligand_chain.residues[-1].number.num - residues=chain.residues - ins_code='\0' - if len(residues)>1: - ins_code='A' - for res in chain.residues: - new_res = edi.AppendResidue(ligand_chain, res.name, - mol.ResNum(last_rnum+1, ins_code)) - new_res.SetStringProp('description', chain.description) - new_res.SetStringProp('type', mol.StringFromChainType(chain.type)) - new_res.SetStringProp("original_name", chain.name) - if chain.HasProp("pdb_auth_chain_name"): - new_res.SetStringProp("pdb_auth_chain_name", - chain.GetStringProp("pdb_auth_chain_name")) - ins_code = chr(ord(ins_code)+1) - a_b = _CopyAtoms(res, new_res, edi, tr) - if not a_pos_wrong: - a_pos_wrong = a_b - move_to_origin = None - if a_pos_wrong: - start = pdb_bu.bounds.min - move_to_origin = geom.Mat4(1,0,0,(-999 - start[0]), - 0,1,0,(-999 - start[1]), - 0,0,1,(-999 - start[2]), - 0,0,0,1) - edi = pdb_bu.EditXCS(mol.UNBUFFERED_EDIT) - edi.ApplyTransform(move_to_origin) - conop.ConnectAll(pdb_bu) + pdbizer.Add(assu, trans_matrices, ss) + pdb_bu = pdbizer.Finish(transformation) if transformation: - return pdb_bu, move_to_origin + return pdb_bu, pdb_bu.GetTransformationMatrix() return pdb_bu MMCifInfoBioUnit.PDBize = _PDBize - -## \example fft_li.py -# -# This scripts loads one or more images and shows their Fourier Transforms on -# the screen. A viewer is opened for each loaded image. The Fourier Transform -# honors the origin of the reference system, which is assumed to be at the -# center of the image. -# -# Usage: -# -# \code giplt view_ft.py <image1> [<image2> <image3> .... ] \endcode -# -# <BR> -# <BR> diff --git a/modules/io/pymod/export_pdb_io.cc b/modules/io/pymod/export_pdb_io.cc index 7d97682df3f006fc41959edc3f9c4e623041031e..c5062e20d92694a84a029346764bc55cbe4d41fe 100644 --- a/modules/io/pymod/export_pdb_io.cc +++ b/modules/io/pymod/export_pdb_io.cc @@ -36,22 +36,22 @@ void (PDBWriter::*write_b)(const mol::EntityView&)=&PDBWriter::Write; void export_pdb_io() { class_<IOProfile>("IOProfile", - init<String,bool,bool,bool,bool,bool,bool,bool>((arg("dialect")="PDB", - arg("strict_hydrogens")=false, - arg("quack_mode")=false, - arg("fault_tolerant")=false, - arg("join_spread_atom_records")=false, - arg("no_hetatms")=false, - arg("calpha_only")=false, - arg("bond_feasibility_check")=false))) + init<String,bool,bool,bool,bool,bool, + conop::ProcessorPtr>((arg("dialect")="PDB", + arg("quack_mode")=false, + arg("fault_tolerant")=false, + arg("join_spread_atom_records")=false, + arg("no_hetatms")=false, + arg("calpha_only")=false, + arg("processor")=conop::ProcessorPtr()))) + .def(init<const IOProfile&>()) .def_readwrite("dialect", &IOProfile::dialect) .def_readwrite("fault_tolerant", &IOProfile::fault_tolerant) .def_readwrite("quack_mode", &IOProfile::quack_mode) - .def_readwrite("strict_hydrogens", &IOProfile::strict_hydrogens) .def_readwrite("no_hetatms", &IOProfile::no_hetatms) .def_readwrite("calpha_only", &IOProfile::calpha_only) .def_readwrite("join_spread_atom_records", &IOProfile::join_spread_atom_records) - .def_readwrite("bond_feasibility_check", &IOProfile::bond_feasibility_check) + .def_readwrite("processor", &IOProfile::processor) .def("Copy", &IOProfile::Copy) .def(self_ns::str(self)) ; diff --git a/modules/io/src/mol/entity_io_crd_handler.cc b/modules/io/src/mol/entity_io_crd_handler.cc index d27feab99e3a5441eaf98b2f12c84f9e3d565bea..3d858fcc6243f21e7125234548e43e297892763c 100644 --- a/modules/io/src/mol/entity_io_crd_handler.cc +++ b/modules/io/src/mol/entity_io_crd_handler.cc @@ -36,6 +36,7 @@ #include <ost/boost_filesystem_helper.hh> #include <ost/io/io_exception.hh> +#include <ost/io/mol/io_profile.hh> #include <ost/io/swap_util.hh> #include "entity_io_crd_handler.hh" @@ -345,8 +346,8 @@ bool CRDWriter::VisitAtom(const mol::AtomHandle& atom) return true; } -/// \brief CHARMM file format requires builder -bool EntityIOCRDHandler::RequiresBuilder() const +/// \brief CHARMM file format requires processor +bool EntityIOCRDHandler::RequiresProcessor() const { return true; } @@ -406,12 +407,14 @@ bool EntityIOCRDHandler::ProvidesExport(const boost::filesystem::path& loc, mol::EntityHandle LoadCRD(const String& file_name) { Profile profile_load("LoadCRD"); - conop::BuilderP builder = conop::Conopology::Instance().GetBuilder(); CRDReader reader(file_name); mol::EntityHandle ent=mol::CreateEntity(); mol::XCSEditor editor=ent.EditXCS(mol::BUFFERED_EDIT); reader.Import(ent); - conop::Conopology::Instance().ConnectAll(builder,ent); + IOProfile& prof = IOProfileRegistry::Instance().GetDefault(); + if (prof.processor) { + prof.processor->Process(ent); + } return ent; } diff --git a/modules/io/src/mol/entity_io_crd_handler.hh b/modules/io/src/mol/entity_io_crd_handler.hh index c0d625a804258e7bd8b16d547d228bf5589ed6d2..3781fcda4e3305307c7bf61b6fb65f38ed27736a 100644 --- a/modules/io/src/mol/entity_io_crd_handler.hh +++ b/modules/io/src/mol/entity_io_crd_handler.hh @@ -99,7 +99,7 @@ public: const String& format="auto"); static bool ProvidesExport(const boost::filesystem::path& loc, const String& format="auto"); - virtual bool RequiresBuilder() const; + virtual bool RequiresProcessor() const; static String GetFormatName() { return String("Crd"); } static String GetFormatDescription() { return String("CARD format file used by the Charmm software package"); } diff --git a/modules/io/src/mol/entity_io_handler.hh b/modules/io/src/mol/entity_io_handler.hh index c65137e185e017ad01ec1d629c1b4dd88b453c0c..709b0762317192d4c6488534b1a52d03f3c6fd56 100644 --- a/modules/io/src/mol/entity_io_handler.hh +++ b/modules/io/src/mol/entity_io_handler.hh @@ -57,7 +57,7 @@ public: // export data from entity view to provided stream virtual void Export(const mol::EntityView& ent, std::ostream& stream) const=0; - virtual bool RequiresBuilder() const=0; + virtual bool RequiresProcessor() const=0; }; typedef boost::shared_ptr<EntityIOHandler> EntityIOHandlerP; diff --git a/modules/io/src/mol/entity_io_mae_handler.cc b/modules/io/src/mol/entity_io_mae_handler.cc index f52a9b6b8681fc395590bf7d5f1bbaef758a7615..ca9590169c4b69e2399183a6fade389665789184 100644 --- a/modules/io/src/mol/entity_io_mae_handler.cc +++ b/modules/io/src/mol/entity_io_mae_handler.cc @@ -36,10 +36,9 @@ #include <ost/log.hh> #include <ost/conop/conop.hh> -#include <ost/conop/heuristic_builder.hh> #include <ost/mol/xcs_editor.hh> #include <ost/profile.hh> - +#include <ost/io/mol/io_profile.hh> #include <ost/io/io_exception.hh> #include <ost/io/swap_util.hh> @@ -331,7 +330,7 @@ void MAEReader::parse_and_add_atom(mol::EntityHandle ent, -bool EntityIOMAEHandler::RequiresBuilder() const +bool EntityIOMAEHandler::RequiresProcessor() const { return true; } @@ -381,13 +380,14 @@ bool EntityIOMAEHandler::ProvidesExport(const boost::filesystem::path& loc, mol::EntityHandle LoadMAE(const String& file_name) { - //conop::BuilderP builder = conop::Conopology::Instance().GetBuilder(); - conop::BuilderP builder(new conop::HeuristicBuilder); MAEReader reader(file_name); mol::EntityHandle ent=mol::CreateEntity(); mol::XCSEditor editor=ent.EditXCS(mol::BUFFERED_EDIT); reader.Import(ent); - conop::Conopology::Instance().ConnectAll(builder,ent); + IOProfile& prof = IOProfileRegistry::Instance().GetDefault(); + if (prof.processor) { + prof.processor->Process(ent); + } return ent; } diff --git a/modules/io/src/mol/entity_io_mae_handler.hh b/modules/io/src/mol/entity_io_mae_handler.hh index 8f09c375e7b3021073cc599ed524bda130c59900..7f923d3453ed60090a615b14fa2d44c20996d817 100644 --- a/modules/io/src/mol/entity_io_mae_handler.hh +++ b/modules/io/src/mol/entity_io_mae_handler.hh @@ -73,7 +73,7 @@ public: const String& format="auto"); static bool ProvidesExport(const boost::filesystem::path& loc, const String& format="auto"); - virtual bool RequiresBuilder() const; + virtual bool RequiresProcessor() const; static String GetFormatName() { return String("Mae"); } static String GetFormatDescription() { return String("MAEstro coordinate file format"); } diff --git a/modules/io/src/mol/entity_io_mmcif_handler.cc b/modules/io/src/mol/entity_io_mmcif_handler.cc index 23e9ff3c52a1fd2652b1bbf7c1b7995eac487a11..a86d1dcebda7cc5ec73791d706b482bd6ecdb9e7 100644 --- a/modules/io/src/mol/entity_io_mmcif_handler.cc +++ b/modules/io/src/mol/entity_io_mmcif_handler.cc @@ -38,7 +38,7 @@ namespace ost { namespace io { using boost::format; -bool EntityIOMMCIFHandler::RequiresBuilder() const +bool EntityIOMMCIFHandler::RequiresProcessor() const { return true; } diff --git a/modules/io/src/mol/entity_io_mmcif_handler.hh b/modules/io/src/mol/entity_io_mmcif_handler.hh index 2fa262156d4867f665a8fc3f4d5ea8e71877f16f..e55a409b850f5ceae92f3b62830a8e895c0f4930 100644 --- a/modules/io/src/mol/entity_io_mmcif_handler.hh +++ b/modules/io/src/mol/entity_io_mmcif_handler.hh @@ -42,7 +42,7 @@ public: const String& format="auto"); static bool ProvidesExport(const boost::filesystem::path& loc, const String& format="auto"); - virtual bool RequiresBuilder() const; + virtual bool RequiresProcessor() const; static String GetFormatName() { return String("mmCIF"); } static String GetFormatDescription() { diff --git a/modules/io/src/mol/entity_io_pdb_handler.cc b/modules/io/src/mol/entity_io_pdb_handler.cc index fe70388346cf08c24c84bdb705774ec2cf4420b7..69e466a23b0c092aef483c7e1c62e18b719d2a2b 100644 --- a/modules/io/src/mol/entity_io_pdb_handler.cc +++ b/modules/io/src/mol/entity_io_pdb_handler.cc @@ -39,7 +39,7 @@ namespace ost { namespace io { using boost::format; -bool EntityIOPDBHandler::RequiresBuilder() const +bool EntityIOPDBHandler::RequiresProcessor() const { return true; } diff --git a/modules/io/src/mol/entity_io_pdb_handler.hh b/modules/io/src/mol/entity_io_pdb_handler.hh index 3ceea37f79a88fc7eac60a31e06e28adbcf93b4c..07bfca81e49714d6aaa5b5440820b30815baf1f0 100644 --- a/modules/io/src/mol/entity_io_pdb_handler.hh +++ b/modules/io/src/mol/entity_io_pdb_handler.hh @@ -45,7 +45,7 @@ public: const String& format="auto"); static bool ProvidesExport(const boost::filesystem::path& loc, const String& format="auto"); - virtual bool RequiresBuilder() const; + virtual bool RequiresProcessor() const; static String GetFormatName() { return String("Pdb"); } static String GetFormatDescription() { return String("Protein Data Bank file format"); } diff --git a/modules/io/src/mol/entity_io_pqr_handler.cc b/modules/io/src/mol/entity_io_pqr_handler.cc index 5d2941c3351d9f9dd5bae11606044d742dc115bd..f1efaee3cc9da176584382cee45d26b2d530ed45 100644 --- a/modules/io/src/mol/entity_io_pqr_handler.cc +++ b/modules/io/src/mol/entity_io_pqr_handler.cc @@ -39,6 +39,7 @@ #include <ost/io/io_exception.hh> #include <ost/io/swap_util.hh> +#include <ost/io/mol/io_profile.hh> #include "entity_io_pqr_handler.hh" @@ -315,12 +316,13 @@ bool EntityIOPQRHandler::ProvidesExport(const boost::filesystem::path& loc, mol::EntityHandle LoadPQR(const String& file_name) { Profile profile_load("LoadPQR"); - conop::BuilderP builder = conop::Conopology::Instance().GetBuilder(); + IOProfile default_profile=IOProfileRegistry::Instance().GetDefault(); PQRReader reader(file_name); mol::EntityHandle ent=mol::CreateEntity(); mol::XCSEditor editor=ent.EditXCS(mol::BUFFERED_EDIT); reader.Import(ent); - conop::Conopology::Instance().ConnectAll(builder,ent); + if (default_profile.processor) + default_profile.processor->Process(ent); return ent; } diff --git a/modules/io/src/mol/entity_io_sdf_handler.cc b/modules/io/src/mol/entity_io_sdf_handler.cc index 5a81405682952a05dd5452ddbae1c11e13af2fc7..31ba544b0214906993ae1fced35ebf1cbd6feffb 100644 --- a/modules/io/src/mol/entity_io_sdf_handler.cc +++ b/modules/io/src/mol/entity_io_sdf_handler.cc @@ -29,7 +29,7 @@ namespace ost { namespace io { -bool EntityIOSDFHandler::RequiresBuilder() const +bool EntityIOSDFHandler::RequiresProcessor() const { return false; } diff --git a/modules/io/src/mol/entity_io_sdf_handler.hh b/modules/io/src/mol/entity_io_sdf_handler.hh index 66333e8d3c687fea30ad870ae7218e01ec40a9ec..55c20fc9675ed0df36494b11c456e7e8e4b49e0b 100644 --- a/modules/io/src/mol/entity_io_sdf_handler.hh +++ b/modules/io/src/mol/entity_io_sdf_handler.hh @@ -40,7 +40,7 @@ public: static bool ProvidesExport(const boost::filesystem::path& loc, const String& format="auto"); - virtual bool RequiresBuilder() const; + virtual bool RequiresProcessor() const; static String GetFormatName() { return String("Sdf"); } static String GetFormatDescription() { return String("Structure-data format from Molecular Design Limited"); } diff --git a/modules/io/src/mol/io_profile.hh b/modules/io/src/mol/io_profile.hh index ee880e31bb781681fbd244283f709a70a2d74ad9..abf37a6b22a2c1e389b9d58d1179e858ca9fe14a 100644 --- a/modules/io/src/mol/io_profile.hh +++ b/modules/io/src/mol/io_profile.hh @@ -23,47 +23,51 @@ #include <map> #include <ost/mol/entity_handle.hh> #include <ost/io/module_config.hh> +#include <ost/conop/processor.hh> + namespace ost { namespace io { + struct DLLEXPORT IOProfile { public: - IOProfile(String d, bool sh, bool qm, bool ft, bool js, bool nh, bool co, bool bf): - dialect(d), strict_hydrogens(sh), quack_mode(qm), fault_tolerant(ft), - join_spread_atom_records(js), no_hetatms(nh), calpha_only(co), bond_feasibility_check(bf) - { } - IOProfile(): dialect("PDB"), strict_hydrogens(true), quack_mode(false), - fault_tolerant(false), join_spread_atom_records(false), no_hetatms(false), - calpha_only(false), bond_feasibility_check(false) + IOProfile(String d, bool qm, bool ft, bool js, bool nh, + bool co, conop::ProcessorPtr proc=conop::ProcessorPtr()): + dialect(d), quack_mode(qm), fault_tolerant(ft), join_spread_atom_records(js), + no_hetatms(nh), calpha_only(co), processor(proc) + { + } + + IOProfile(): dialect("PDB"), quack_mode(false), fault_tolerant(false), + join_spread_atom_records(false), no_hetatms(false), + calpha_only(false), processor() { } - virtual ~IOProfile() { } - String dialect; - bool strict_hydrogens; - bool quack_mode; - bool fault_tolerant; - bool join_spread_atom_records; - bool no_hetatms; - bool calpha_only; - bool bond_feasibility_check; + String dialect; + bool quack_mode; + bool fault_tolerant; + bool join_spread_atom_records; + bool no_hetatms; + bool calpha_only; + conop::ProcessorPtr processor; IOProfile Copy() { - return IOProfile(dialect, strict_hydrogens, quack_mode, fault_tolerant, - join_spread_atom_records, no_hetatms, calpha_only, bond_feasibility_check); + return IOProfile(dialect, quack_mode, fault_tolerant, join_spread_atom_records, + no_hetatms, calpha_only, + processor ? processor->Copy() : conop::ProcessorPtr()); } - virtual void PostImport(mol::EntityHandle ent) { } }; + inline std::ostream& operator<<(std::ostream& stream, const IOProfile& p) { - stream << "IOProfile(dialect='" << p.dialect << "', strict_hydrogens=" - << (p.strict_hydrogens ? "True" : "False") << ", quack_mode=" - << (p.quack_mode ? "True" : "False") << ", join_spread_atom_records=" - << (p.join_spread_atom_records ? "True" : "False") << ", no_hetatms=" - << (p.no_hetatms ? "True" : "False") << ", calpha_only=" - << (p.calpha_only ? "True" : "False") << ", fault_tolerant=" - << (p.fault_tolerant ? "True" : "False") << ", bond_feasibility_check=" - << (p.bond_feasibility_check ? "True" : "False") << ")"; + stream << "IOProfile(dialect='" << p.dialect + << "', quack_mode=" << (p.quack_mode ? "True" : "False") << ", " + << "join_spread_atom_records=" << (p.join_spread_atom_records ? "True" : "False") << ", " + << "calpha_only=" << (p.calpha_only ? "True" : "False") << ", " + << "fault_tolerant=" << (p.fault_tolerant ? "True" : "False") << ", " + << "no_hetatms=" << (p.no_hetatms ? "True" : "False") << ", " + << "processor=" << (p.processor ? p.processor->ToString() : "None") << ")"; return stream; } diff --git a/modules/io/src/mol/load_entity.cc b/modules/io/src/mol/load_entity.cc index 6fdfa57576b4c655b744955ae02dd30809cd100e..98eea40f861a728340b8ad97b79997800bbd6119 100644 --- a/modules/io/src/mol/load_entity.cc +++ b/modules/io/src/mol/load_entity.cc @@ -22,6 +22,7 @@ #include "load_entity.hh" #include <ost/mol/xcs_editor.hh> #include <ost/io/io_manager.hh> +#include <ost/io/mol/io_profile.hh> #include <ost/io/mol/entity_io_handler.hh> #include <ost/profile.hh> @@ -38,19 +39,15 @@ void Import(mol::EntityHandle& eh, const String& filename, int flag) // TODO: proper error handling LOG_DEBUG("calling import on entity io handle"); - /* - This should probably allow various parameters to be passed - to adjust the loading behaviour for a particular filter. - Alternatively, these settings could be done outside via - the main IOManager interface, as global settings per import plugin - */ ent_io->Import(eh,filename); LOG_DEBUG("running conopology"); - if(ent_io->RequiresBuilder()) { - conop::BuilderP builder = conop::Conopology::Instance().GetBuilder(); - conop::Conopology::Instance().ConnectAll(builder,eh,flag); + if(ent_io->RequiresProcessor()) { + IOProfile& prof = IOProfileRegistry::Instance().GetDefault(); + if (prof.processor) { + prof.processor->Process(eh); + } } } diff --git a/modules/io/src/mol/mmcif_reader.cc b/modules/io/src/mol/mmcif_reader.cc index 91d46cb9b86646add1832a8ea972b6c316a3cba7..cd21e62a1318d4b93f77c8f3fb2d1d4a57f2c4cc 100644 --- a/modules/io/src/mol/mmcif_reader.cc +++ b/modules/io/src/mol/mmcif_reader.cc @@ -25,7 +25,6 @@ #include <ost/mol/xcs_editor.hh> #include <ost/conop/conop.hh> -#include <ost/conop/rule_based_builder.hh> #include <ost/io/mol/mmcif_reader.hh> namespace ost { namespace io { @@ -678,17 +677,17 @@ void MMCifReader::ParseEntityPoly(const std::vector<StringRef>& columns) } } else if (indices_[PDBX_SEQ_ONE_LETTER_CODE] != -1) { seqres=columns[indices_[PDBX_SEQ_ONE_LETTER_CODE]]; - conop::BuilderP builder=conop::Conopology::Instance().GetBuilder("DEFAULT"); - conop::RuleBasedBuilderPtr rbb=dyn_cast<conop::RuleBasedBuilder>(builder); - if (!rbb) { + + conop::CompoundLibPtr comp_lib=conop::Conopology::Instance() + .GetDefaultLib(); + if (!comp_lib) { if (!warned_rule_based_) { - LOG_WARNING("SEQRES import requires the rule-based builder. Ignoring " - "SEQRES records"); + LOG_WARNING("SEQRES import requires a compound library. " + "Ignoring SEQRES records"); } warned_rule_based_=true; return; } - conop::CompoundLibPtr comp_lib=rbb->GetCompoundLib(); edm_it->second.seqres = this->ConvertSEQRES(seqres.str_no_whitespace(), comp_lib); } else { diff --git a/modules/io/src/mol/pdb_reader.cc b/modules/io/src/mol/pdb_reader.cc index 9f389786616e2437f4d96712390b2b99ff187f1b..ea81f65c1614de11d645e0d90e5412f41072a7c3 100644 --- a/modules/io/src/mol/pdb_reader.cc +++ b/modules/io/src/mol/pdb_reader.cc @@ -29,7 +29,6 @@ #include <ost/message.hh> #include <ost/conop/conop.hh> -#include <ost/conop/rule_based_builder.hh> #include <ost/geom/mat3.hh> #include <ost/io/io_exception.hh> #include "pdb_reader.hh" @@ -235,17 +234,17 @@ void PDBReader::ParseCompndEntry (const StringRef& line, int line_num) void PDBReader::ParseSeqRes(const StringRef& line, int line_num) { - conop::BuilderP builder=conop::Conopology::Instance().GetBuilder("DEFAULT"); - conop::RuleBasedBuilderPtr rbb=dyn_cast<conop::RuleBasedBuilder>(builder); - if (!rbb) { + conop::CompoundLibPtr comp_lib; + comp_lib = conop::Conopology::Instance().GetDefaultLib(); + + if (!comp_lib) { if (!warned_rule_based_) { - LOG_WARNING("SEQRES import requires the rule-based builder. Ignoring " + LOG_WARNING("SEQRES import requires a compound library. Ignoring" "SEQRES records"); } warned_rule_based_=true; return; } - conop::CompoundLibPtr comp_lib=rbb->GetCompoundLib(); if (!seqres_.IsValid()) { seqres_=seq::CreateSequenceList(); } diff --git a/modules/io/tests/test_io_mmcif.py b/modules/io/tests/test_io_mmcif.py index 313235d791e1921bf1bdb8d7b9d1756f33512425..4b64aa554988b298d3b8fd75a47d6f74f1d0dca0 100644 --- a/modules/io/tests/test_io_mmcif.py +++ b/modules/io/tests/test_io_mmcif.py @@ -199,9 +199,9 @@ class TestMMCifInfo(unittest.TestCase): seqres=True, info=True) pdb_ent, t = info.GetBioUnits()[0].PDBize(ent, transformation=True) - self.assertAlmostEquals(pdb_ent.GetCenterOfAtoms()[0], -915.8, 1) - self.assertAlmostEquals(pdb_ent.GetCenterOfAtoms()[1], -952.345, 2) - self.assertAlmostEquals(pdb_ent.GetCenterOfAtoms()[2], 3221.75, 2) + self.assertAlmostEquals(pdb_ent.GetCenterOfAtoms()[0], -915.759, 1) + self.assertAlmostEquals(pdb_ent.GetCenterOfAtoms()[1], -952.345, 1) + self.assertAlmostEquals(pdb_ent.GetCenterOfAtoms()[2], 3221.75, 1) self.assertEquals(geom.Equal(t, geom.Mat4(1,0,0,-920.462, 0,1,0,-966.654, diff --git a/modules/io/tests/test_io_pdb.cc b/modules/io/tests/test_io_pdb.cc index 9268778ff080c3eb4b9ad071a492fe16bd9f5735..7d33d8bce38ecc45702b190cbb37439b2b94960d 100644 --- a/modules/io/tests/test_io_pdb.cc +++ b/modules/io/tests/test_io_pdb.cc @@ -29,7 +29,7 @@ using boost::unit_test_framework::test_suite; #include <ost/dyn_cast.hh> #include <ost/mol/mol.hh> #include <ost/conop/conop.hh> -#include <ost/conop/rule_based_builder.hh> +#include <ost/conop/heuristic.hh> #include <ost/io/mol/entity_io_pdb_handler.hh> #include <ost/io/pdb_reader.hh> @@ -426,8 +426,8 @@ BOOST_AUTO_TEST_CASE(deuterium_import) mol::EntityHandle ent=mol::CreateEntity(); reader.Import(ent); // we use conopology to mark amino acids as peptide-linking. - conop::Conopology& conop_inst=conop::Conopology::Instance(); - conop_inst.ConnectAll(conop_inst.GetBuilder(), ent); + conop::HeuristicProcessor heu_proc; + heu_proc.Process(ent); // this check makes sure that we correctly detect deal with the deuterium // atoms in the residue. BOOST_CHECK(ent.FindResidue("A", 297).IsPeptideLinking()); @@ -440,8 +440,8 @@ BOOST_AUTO_TEST_CASE(bzdng_318) mol::EntityHandle ent=mol::CreateEntity(); reader.Import(ent); // we use conopology to mark amino acids as peptide-linking. - conop::Conopology& conop_inst=conop::Conopology::Instance(); - conop_inst.ConnectAll(conop_inst.GetBuilder(), ent); + conop::HeuristicProcessor heu_proc; + heu_proc.Process(ent); { PDBWriter writer(std::string("testfiles/pdb/bzdng-318-out.pdb"), IOProfile()); @@ -614,8 +614,9 @@ BOOST_AUTO_TEST_CASE(write_ter) reader.Import(ent); // we use conopology to mark amino acids as peptide-linking. this is require // for proper TER output - conop::Conopology& conop_inst=conop::Conopology::Instance(); - conop_inst.ConnectAll(conop_inst.GetBuilder(), ent); + conop::HeuristicProcessor heu_proc; + + heu_proc.Process(ent); writer.Write(ent); } BOOST_CHECK(compare_files("testfiles/pdb/ter.pdb", @@ -635,8 +636,8 @@ BOOST_AUTO_TEST_CASE(write_ter2) reader.Import(ent); // we use conopology to mark amino acids as peptide-linking. this is // require for proper TER output - conop::Conopology& conop_inst=conop::Conopology::Instance(); - conop_inst.ConnectAll(conop_inst.GetBuilder(), ent); + conop::HeuristicProcessor heu_proc; + heu_proc.Process(ent); writer.Write(ent); } BOOST_CHECK(compare_files("testfiles/pdb/ter2.pdb", @@ -656,8 +657,8 @@ BOOST_AUTO_TEST_CASE(write_ter3) reader.Import(ent); // we use conopology to mark amino acids as peptide-linking. this is // require for proper TER output - conop::Conopology& conop_inst=conop::Conopology::Instance(); - conop_inst.ConnectAll(conop_inst.GetBuilder(), ent); + conop::HeuristicProcessor heu_proc; + heu_proc.Process(ent); writer.Write(ent); } BOOST_CHECK(compare_files("testfiles/pdb/ter3.pdb", @@ -677,8 +678,8 @@ BOOST_AUTO_TEST_CASE(write_ter4) mol::ResidueHandle r2=edi.AppendResidue(ch, "GLY"); mol::AtomHandle a2=edi.InsertAtom(r2, "N", geom::Vec3(35.0, -99.0, -10.5)); mol::ChainHandle ch2=edi.InsertChain("B"); - conop::Conopology& conop_inst=conop::Conopology::Instance(); - conop_inst.ConnectAll(conop_inst.GetBuilder(), ent); + conop::HeuristicProcessor heu_proc; + heu_proc.Process(ent); writer.Write(ent); } BOOST_CHECK(compare_files("testfiles/pdb/ter_emptychain.pdb", @@ -698,8 +699,8 @@ BOOST_AUTO_TEST_CASE(write_ter5) mol::ResidueHandle r2=edi.AppendResidue(ch, "GLY"); mol::AtomHandle a2=edi.InsertAtom(r2, "N", geom::Vec3(35.0, -99.0, -10.5)); mol::ChainHandle ch2=edi.InsertChain("B"); - conop::Conopology& conop_inst=conop::Conopology::Instance(); - conop_inst.ConnectAll(conop_inst.GetBuilder(), ent); + conop::HeuristicProcessor heu_proc; + heu_proc.Process(ent); writer.Write(ent.Select("")); } BOOST_CHECK(compare_files("testfiles/pdb/ter_view-emptychain.pdb", @@ -717,8 +718,8 @@ BOOST_AUTO_TEST_CASE(write_ter6) mol::EntityHandle ent=mol::CreateEntity(); reader.Import(ent); - conop::Conopology& conop_inst=conop::Conopology::Instance(); - conop_inst.ConnectAll(conop_inst.GetBuilder(), ent); + conop::HeuristicProcessor heu_proc; + heu_proc.Process(ent); writer.Write(ent); } BOOST_CHECK(compare_files("testfiles/pdb/ter4.pdb", @@ -734,8 +735,8 @@ BOOST_AUTO_TEST_CASE(write_conect) PDBWriter writer(String("testfiles/pdb/conect-out.pdb"), IOProfile()); mol::EntityHandle ent=mol::CreateEntity(); reader.Import(ent); - conop::Conopology& conop_inst=conop::Conopology::Instance(); - conop_inst.ConnectAll(conop_inst.GetBuilder(), ent); + conop::HeuristicProcessor heu_proc; + heu_proc.Process(ent); writer.Write(ent); } BOOST_CHECK(compare_files("testfiles/pdb/conect.pdb", @@ -855,21 +856,18 @@ BOOST_AUTO_TEST_CASE(seqres_import) char * ost_root=getenv("OST_ROOT"); if(!ost_root){ std::cout << "WARNING: skipping SEQRES import unit test. " - << "Rule-based builder is required" << std::endl; + << "Rule-based processor is required" << std::endl; return; } SetPrefixPath(ost_root); String lib_path=GetSharedDataPath()+"/compounds.chemlib"; conop::CompoundLibPtr compound_lib=conop::CompoundLib::Load(lib_path); if (!compound_lib) { - std::cout << "WARNING: skipping SEQRES import unit test. " - << "Rule-based builder is required" << std::endl; + std::cout << "WARNING: skipping SEQRES import unit test. Compound lib is " + << "required" << std::endl; return; } - conop::RuleBasedBuilderPtr rbb(new conop::RuleBasedBuilder(compound_lib)); - conop::Conopology::Instance().RegisterBuilder(rbb, "RBB"); - conop::Conopology::Instance().SetDefaultBuilder("RBB"); - + conop::Conopology::Instance().SetDefaultLib(compound_lib); String fname("testfiles/pdb/seqres.pdb"); IOProfile profile; PDBReader reader(fname, profile); @@ -927,8 +925,7 @@ BOOST_AUTO_TEST_CASE(charmm_rname) { { PDBWriter writer(String("testfiles/pdb/charmm_rname-out.pdb"), - IOProfile("CHARMM", true, false, false, - false, false, false, true)); + IOProfile("CHARMM", false, false, false, false, false)); mol::EntityHandle ent=mol::CreateEntity(); mol::XCSEditor edi=ent.EditXCS(); @@ -947,8 +944,7 @@ BOOST_AUTO_TEST_CASE(charmm_longcname) { { PDBWriter writer(String("testfiles/pdb/charmm_longcname-out.pdb"), - IOProfile("CHARMM", true, false, false, - false, false, false, true)); + IOProfile("CHARMM", false, false, false, false, false)); mol::EntityHandle ent=mol::CreateEntity(); mol::XCSEditor edi=ent.EditXCS(); @@ -967,8 +963,7 @@ BOOST_AUTO_TEST_CASE(write_charmm_ter) { { PDBWriter writer(String("testfiles/pdb/charmm_ter-out.pdb"), - IOProfile("CHARMM", true, false, false, - false, false, false, true)); + IOProfile("CHARMM", false, false, false, false, false)); mol::EntityHandle ent=mol::CreateEntity(); mol::XCSEditor edi=ent.EditXCS(); @@ -977,8 +972,8 @@ BOOST_AUTO_TEST_CASE(write_charmm_ter) mol::AtomHandle a=edi.InsertAtom(r, "N", geom::Vec3(32.0, -128.0, -2.5)); mol::ResidueHandle r2=edi.AppendResidue(ch, "GLY"); mol::AtomHandle a2=edi.InsertAtom(r2, "N", geom::Vec3(35.0, -99.0, -10.5)); - conop::Conopology& conop_inst=conop::Conopology::Instance(); - conop_inst.ConnectAll(conop_inst.GetBuilder(), ent); + conop::HeuristicProcessor heu_proc; + heu_proc.Process(ent); writer.Write(ent); } BOOST_CHECK(compare_files("testfiles/pdb/charmm_ter.pdb", diff --git a/modules/io/tests/test_io_pdb.py b/modules/io/tests/test_io_pdb.py index 17933f35a93f8c14b513c5bc417e186b4283dbdf..9beb684d952f60bbbaf35e4b9b2369ddc896395c 100644 --- a/modules/io/tests/test_io_pdb.py +++ b/modules/io/tests/test_io_pdb.py @@ -11,14 +11,9 @@ class TestPDB(unittest.TestCase): ch = e.FindChain("A"); self.assertEquals(ch.GetIntProp("mol_id"), 1) -class TestPDB(unittest.TestCase): - def setUp(self): - pass - - def test_compnd_parser(self): - profiles=io.IOProfiles() - profiles['FEAS_CHECK']=io.IOProfile(bond_feasibility_check=True) - profiles['NO_FEAS_CHECK']=io.IOProfile(bond_feasibility_check=False) + def test_no_bond_feasibility(self): + io.profiles['FEAS_CHECK']=io.IOProfile(processor=conop.HeuristicProcessor(check_bond_feasibility=True)) + io.profiles['NO_FEAS_CHECK']=io.IOProfile(processor=conop.HeuristicProcessor(check_bond_feasibility=False)) e1=io.LoadPDB('testfiles/pdb/simple_defective.pdb', restrict_chains="A",profile='FEAS_CHECK') e2=io.LoadPDB('testfiles/pdb/simple_defective.pdb', restrict_chains="A",profile='NO_FEAS_CHECK') diff --git a/modules/io/tests/test_mmcif_reader.cc b/modules/io/tests/test_mmcif_reader.cc index 67ef53d8754fecc59ad3a7f61e87fdb755c61c02..0b9e94b5868815cb514d48c6a710711b49cf63c9 100644 --- a/modules/io/tests/test_mmcif_reader.cc +++ b/modules/io/tests/test_mmcif_reader.cc @@ -27,7 +27,6 @@ #include <ost/io/io_exception.hh> #include <ost/io/mol/mmcif_reader.hh> #include <ost/conop/conop.hh> -#include <ost/conop/rule_based_builder.hh> @@ -143,20 +142,18 @@ BOOST_AUTO_TEST_CASE(mmcif_convert_seqres) char * ost_root=getenv("OST_ROOT"); if(!ost_root){ std::cout << "WARNING: skipping SEQRES import unit test. " - << "Rule-based builder is required" << std::endl; + << "Rule-based processor is required" << std::endl; return; } SetPrefixPath(ost_root); String lib_path=GetSharedDataPath()+"/compounds.chemlib"; conop::CompoundLibPtr compound_lib=conop::CompoundLib::Load(lib_path); if (!compound_lib) { - std::cout << "WARNING: skipping SEQRES import unit test. " - << "Rule-based builder is required" << std::endl; + std::cout << "WARNING: skipping SEQRES import unit test. Compound " + << "library is required" << std::endl; return; } - conop::RuleBasedBuilderPtr rbb(new conop::RuleBasedBuilder(compound_lib)); - conop::Conopology::Instance().RegisterBuilder(rbb, "RBB"); - conop::Conopology::Instance().SetDefaultBuilder("RBB"); + conop::Conopology::Instance().SetDefaultLib(compound_lib); mol::EntityHandle eh=mol::CreateEntity(); TestMMCifReaderProtected tmmcif_p("testfiles/mmcif/atom_site.mmcif", eh); @@ -165,7 +162,6 @@ BOOST_AUTO_TEST_CASE(mmcif_convert_seqres) BOOST_CHECK_EQUAL(tmmcif_p.ConvertSEQRES("A(MSE)Y", compound_lib), "AMY"); BOOST_CHECK_THROW(tmmcif_p.ConvertSEQRES("A(MSEY", compound_lib), IOException); - conop::Conopology::Instance().SetDefaultBuilder("HEURISTIC"); } BOOST_AUTO_TEST_CASE(mmcif_onbeginloop) @@ -409,18 +405,18 @@ BOOST_AUTO_TEST_CASE(mmcif_entity_poly_tests) char * ost_root=getenv("OST_ROOT"); if(!ost_root){ std::cout << "WARNING: skipping SEQRES import unit test. " - << "Rule-based builder is required" << std::endl; + << "Rule-based processor is required" << std::endl; return; } SetPrefixPath(ost_root); String lib_path=GetSharedDataPath()+"/compounds.chemlib"; conop::CompoundLibPtr compound_lib=conop::CompoundLib::Load(lib_path); if (!compound_lib) { - std::cout << "WARNING: skipping SEQRES import unit test. " - << "Rule-based builder is required" << std::endl; + std::cout << "WARNING: skipping SEQRES import unit test. Compound " + << "lib is required" << std::endl; return; } - conop::Conopology::Instance().SetDefaultBuilder("RBB"); + conop::Conopology::Instance().SetDefaultLib(compound_lib); BOOST_MESSAGE(" Running mmcif_entity_poly_tests..."); mol::ChainHandle ch; IOProfile profile; @@ -575,7 +571,6 @@ columns.push_back(StringRef("polydeoxyribonucleotide/polyribonucleotide hybrid", BOOST_MESSAGE(" done."); BOOST_MESSAGE(" done."); - conop::Conopology::Instance().SetDefaultBuilder("HEURISTIC"); } BOOST_AUTO_TEST_CASE(mmcif_citation_tests) diff --git a/modules/io/tests/testfiles/mmcif/3T6C.cif.gz b/modules/io/tests/testfiles/mmcif/3T6C.cif.gz index afda31f696dd24fcbecee1d652b7431b93d5dca4..34c71d22898472c0415c49ce327c0e2e4a673281 100644 Binary files a/modules/io/tests/testfiles/mmcif/3T6C.cif.gz and b/modules/io/tests/testfiles/mmcif/3T6C.cif.gz differ diff --git a/modules/io/tests/testfiles/pdb/ter4.pdb b/modules/io/tests/testfiles/pdb/ter4.pdb index a088dd23a776b33aacab610917ab1cbb5b99c53a..cb2209f24a71bd13022a324d48fbeaafd679b6d6 100644 --- a/modules/io/tests/testfiles/pdb/ter4.pdb +++ b/modules/io/tests/testfiles/pdb/ter4.pdb @@ -1,24 +1,24 @@ -ATOM 1 CB ARG A 5 54.221 28.817 46.886 1.00 80.23 C -ATOM 2 CG ARG A 5 54.014 28.661 48.384 1.00 79.76 C -ATOM 3 CD ARG A 5 53.901 29.993 49.091 1.00 79.93 C -ATOM 4 NE ARG A 5 55.153 30.743 49.053 1.00 79.60 N -ATOM 5 CZ ARG A 5 55.375 31.851 49.753 1.00 79.44 C -ATOM 6 NH1 ARG A 5 54.425 32.333 50.545 1.00 79.21 N -ATOM 7 NH2 ARG A 5 56.543 32.475 49.661 1.00 79.57 N -ATOM 8 C ARG A 5 54.203 27.642 44.665 1.00 80.18 C -ATOM 9 O ARG A 5 54.697 26.854 43.860 1.00 80.24 O -ATOM 10 N ARG A 5 55.792 26.946 46.486 1.00 80.39 N -ATOM 11 CA ARG A 5 54.437 27.479 46.167 1.00 80.33 C +ATOM 1 N ARG A 5 55.792 26.946 46.486 1.00 80.39 N +ATOM 2 CA ARG A 5 54.437 27.479 46.167 1.00 80.33 C +ATOM 3 C ARG A 5 54.203 27.642 44.665 1.00 80.18 C +ATOM 4 O ARG A 5 54.697 26.854 43.860 1.00 80.24 O +ATOM 5 CB ARG A 5 54.221 28.817 46.886 1.00 80.23 C +ATOM 6 CG ARG A 5 54.014 28.661 48.384 1.00 79.76 C +ATOM 7 CD ARG A 5 53.901 29.993 49.091 1.00 79.93 C +ATOM 8 NE ARG A 5 55.153 30.743 49.053 1.00 79.60 N +ATOM 9 CZ ARG A 5 55.375 31.851 49.753 1.00 79.44 C +ATOM 10 NH1 ARG A 5 54.425 32.333 50.545 1.00 79.21 N +ATOM 11 NH2 ARG A 5 56.543 32.475 49.661 1.00 79.57 N ATOM 12 N SER A 6 53.441 28.666 44.297 1.00 80.44 N ATOM 13 CA SER A 6 53.129 28.922 42.897 1.00 80.22 C -ATOM 14 CB SER A 6 52.450 30.285 42.745 1.00 79.46 C -ATOM 15 OG SER A 6 52.075 30.513 41.398 1.00 79.08 O -ATOM 16 C SER A 6 54.371 28.872 42.015 1.00 80.20 C -ATOM 17 O SER A 6 54.274 28.620 40.812 1.00 80.66 O +ATOM 14 C SER A 6 54.371 28.872 42.015 1.00 80.20 C +ATOM 15 O SER A 6 54.274 28.620 40.812 1.00 80.66 O +ATOM 16 CB SER A 6 52.450 30.285 42.745 1.00 79.46 C +ATOM 17 OG SER A 6 52.075 30.513 41.398 1.00 79.08 O TER 18 SER A 6 ATOM 19 C44 MC3 B 264 39.239 27.459 24.810 1.00 79.54 C ATOM 20 C43 MC3 B 264 38.743 26.476 23.747 1.00 80.47 C ATOM 21 C44 MC3 C 265 62.635 29.009 23.846 1.00 81.10 C ATOM 22 C43 MC3 C 265 63.065 29.658 22.529 1.00 79.41 C ATOM 23 C42 MC3 C 265 61.857 29.941 21.636 1.00 79.32 C -END \ No newline at end of file +END diff --git a/modules/mol/alg/pymod/wrap_mol_alg.cc b/modules/mol/alg/pymod/wrap_mol_alg.cc index 248923beb4fb9598b4c3c918b106932532cd681e..a65e95457400b5ee4806c49e4bf0dc666ba398ad 100644 --- a/modules/mol/alg/pymod/wrap_mol_alg.cc +++ b/modules/mol/alg/pymod/wrap_mol_alg.cc @@ -26,6 +26,7 @@ #include <ost/mol/alg/superpose_frames.hh> #include <ost/mol/alg/filter_clashes.hh> #include <ost/mol/alg/consistency_checks.hh> +#include <ost/mol/alg/pdbize.hh> #include <ost/export_helper/pair_to_tuple_conv.hh> #include <ost/export_helper/vec_to_list_conv.hh> @@ -165,6 +166,14 @@ BOOST_PYTHON_MODULE(_ost_mol_alg) def("PrintGlobalRDMap",&mol::alg::PrintGlobalRDMap); def("PrintResidueRDMap",&mol::alg::PrintResidueRDMap); + + class_<mol::alg::PDBize>("PDBize", + init<int>(arg("min_polymer_size")=10)) + .def("Add", &mol::alg::PDBize::Add, + (arg("asu"), arg("transformations"), arg("seqres"))) + .def("Finish", &mol::alg::PDBize::Finish, arg("shift_to_fit")=true) + ; + def("ResidueNamesMatch",&mol::alg::ResidueNamesMatch, (arg("probe"), arg("reference"), arg("log_as_error")=false)); diff --git a/modules/mol/alg/src/CMakeLists.txt b/modules/mol/alg/src/CMakeLists.txt index f5df9362a0b02cdda2c32ca1057732947be452fa..b6a7f28922257cd548acd6355a0d8387a4a9f8d6 100644 --- a/modules/mol/alg/src/CMakeLists.txt +++ b/modules/mol/alg/src/CMakeLists.txt @@ -12,6 +12,7 @@ set(OST_MOL_ALG_HEADERS trajectory_analysis.hh structure_analysis.hh consistency_checks.hh + pdbize.hh ) set(OST_MOL_ALG_SOURCES @@ -27,6 +28,7 @@ set(OST_MOL_ALG_SOURCES trajectory_analysis.cc structure_analysis.cc consistency_checks.cc + pdbize.cc ) set(MOL_ALG_DEPS ost_mol ost_seq) diff --git a/modules/mol/alg/src/lddt.cc b/modules/mol/alg/src/lddt.cc index da1d8b311eb4103f664eef7bf24d0eaff2f2aa46..2509a0af9371ef15d6ec18d9d744bc916340893d 100644 --- a/modules/mol/alg/src/lddt.cc +++ b/modules/mol/alg/src/lddt.cc @@ -25,25 +25,33 @@ #include <boost/filesystem/convenience.hpp> #include <ost/base.hh> #include <ost/boost_filesystem_helper.hh> +#include <ost/mol/chain_view.hh> #include <ost/mol/alg/local_dist_diff_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> +#include <ost/conop/compound_lib.hh> #include <ost/string_ref.hh> #include <ost/conop/amino_acids.hh> +#include <ost/conop/rule_based.hh> #include <ost/platform.hh> #include <ost/log.hh> #include <ost/mol/alg/consistency_checks.hh> -#include <ost/conop/rule_based_builder.hh> +#if defined(__APPLE__) +#include <mach-o/dyld.h> +#endif #include <ost/dyn_cast.hh> using namespace ost; using namespace ost::io; +using namespace ost::conop; using namespace ost::mol; using namespace ost::mol::alg; + namespace po=boost::program_options; +namespace fs=boost::filesystem; // loads a file EntityHandle load(const String& file, const IOProfile& profile) @@ -53,9 +61,10 @@ EntityHandle load(const String& file, const IOProfile& profile) if (reader.HasNext()) { EntityHandle ent=CreateEntity(); reader.Import(ent); - conop::Conopology& conop_inst=conop::Conopology::Instance(); - conop_inst.GetBuilder()->SetBondFeasibilityCheck(profile.bond_feasibility_check); - conop_inst.ConnectAll(conop_inst.GetBuilder(), ent); + if (profile.processor) { + profile.processor->Process(ent); + } + if (ent.GetChainList().size()!=1) { std::cout << "WARNING: File " << file << " has more than one chain" << std::endl; } @@ -113,6 +122,51 @@ std::pair<int,int> compute_coverage (const EntityView& v,const GlobalRDMap& glob return std::make_pair(first,second); } +CompoundLibPtr load_compound_lib(const String& custom_path) +{ + if (custom_path!="") { + if (fs::exists(custom_path)) { + return CompoundLib::Load(custom_path); + } else { + std::cerr << "Could not find compounds.chemlib at the provided location, trying other options" << std::endl; + } + } + if (fs::exists("compounds.chemlib")) { + return CompoundLib::Load("compounds.chemlib"); + } + char result[ 1024 ]; + CompoundLibPtr lib; + String exe_path; + #if defined(__APPLE__) + uint32_t size=1023; + if (!_NSGetExecutablePath(result, &size)) { + exe_path=String(result); + } + #else + ssize_t count = readlink( "/proc/self/exe", result, 1024 ); + exe_path = std::string( result, (count > 0) ? count : 0 ); + #endif + if (exe_path.empty()) { + std::cerr << "Could not determine the path of the molck executable. Will only " + "look for compounds.chemlib in the current working directory" << std::endl; + } else { + fs::path path_and_exe(exe_path); + fs::path path_only=path_and_exe.branch_path(); + fs::path share_path = path_only.branch_path(); + share_path = share_path / "share" / "openstructure" / "compounds.chemlib"; + + String share_path_string=BFPathToString(share_path); + + if (fs::exists(share_path_string)) { + return CompoundLib::Load(share_path_string); + } + } + if (!lib) { + std::cerr << "Could not load compounds.chemlib" << std::endl; + exit(-1); + } + return CompoundLibPtr(); +} bool is_resnum_in_globalrdmap(const ResNum& resnum, const GlobalRDMap& glob_dist_list) { for (GlobalRDMap::const_iterator i=glob_dist_list.begin(), e=glob_dist_list.end(); i!=e; ++i) { @@ -135,10 +189,9 @@ int main (int argc, char **argv) // creates the required loading profile IOProfile profile; - profile.bond_feasibility_check=false; - // parses options String sel; + String custom_path; bool structural_checks=false; bool consistency_checks=true; po::options_description desc("Options"); @@ -152,6 +205,7 @@ int main (int argc, char **argv) ("parameter-file,p", po::value<String>(), "stereo-chemical parameter file") ("verbosity,v", po::value<int>(), "verbosity level") ("bond_tolerance,b", po::value<Real>(), "tolerance in stddev for bonds") + ("complib", po::value<String>(&custom_path)->default_value(""),"location of the compound library file") ("angle_tolerance,a", po::value<Real>(), "tolerance in stddev for angles") ("inclusion_radius,r", po::value<Real>(), "distance inclusion radius") ("sequence_separation,i", po::value<int>(), "sequence separation") @@ -170,6 +224,12 @@ int main (int argc, char **argv) usage(); exit(-1); } + conop::CompoundLibPtr lib = load_compound_lib(custom_path); + if (!lib) { + exit(0); + } + profile.processor = conop::RuleBasedProcessorPtr(new conop::RuleBasedProcessor(lib)); + profile.processor->SetCheckBondFeasibility(false); po::notify(vm); if (vm.count("version")) { std::cout << "Version: " << version << std::endl; diff --git a/modules/mol/alg/src/pdbize.cc b/modules/mol/alg/src/pdbize.cc new file mode 100644 index 0000000000000000000000000000000000000000..c06dfa23057998368e64eb04545810d06c8a7188 --- /dev/null +++ b/modules/mol/alg/src/pdbize.cc @@ -0,0 +1,158 @@ +//------------------------------------------------------------------------------ +// 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 "pdbize.hh" +#include <ost/mol/residue_handle.hh> +#include <ost/mol/residue_view.hh> +#include <ost/mol/atom_handle.hh> +#include <ost/mol/atom_view.hh> +#include <ost/mol/transfer_connectivity.hh> +#include <ost/mol/chain_handle.hh> +#include <ost/mol/chain_view.hh> +#include <ost/mol/xcs_editor.hh> +#include <ost/seq/sequence_handle.hh> + +namespace ost { namespace mol { namespace alg { + +DLLEXPORT const char* POLYPEPTIDE_CHAIN_NAMES="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"; +DLLEXPORT const char* LIGAND_CHAIN_NAME="_"; +DLLEXPORT const char* WATER_CHAIN_NAME="-"; + + +namespace { + +bool copy_atoms(ResidueView src_res, ResidueHandle dst_res, XCSEditor& edi, + const geom::Mat4 transform) { + bool needs_adjustment_ = false; + for (AtomViewList::const_iterator + i = src_res.GetAtomList().begin(), + e = src_res.GetAtomList().end(); i != e; ++i) { + + AtomHandle new_atom = edi.InsertAtom(dst_res, i->GetName(), + geom::Vec3(transform*i->GetPos()), + i->GetName(), i->GetOccupancy(), + i->GetBFactor(), i->IsHetAtom()); + geom::Vec3 pos = new_atom.GetPos(); + for (int j = 0; j<3; ++j) { + needs_adjustment_|= pos[j]<=-1000 || pos[j]>=10000; + } + } + return needs_adjustment_; +} + +} + +void PDBize::Add(EntityView asu, const geom::Mat4List& transforms, + seq::SequenceList seqres) +{ + XCSEditor edi = ent_.EditXCS(BUFFERED_EDIT); + + ChainHandle ligand_chain; + ChainHandle water_chain; + int last_rnum = 0; + for (geom::Mat4List::const_iterator i = transforms.begin(), + e = transforms.end(); i != e; ++i) { + for (ChainViewList::const_iterator j = asu.GetChainList().begin(), + e2 =asu.GetChainList().end(); j != e2; ++j) { + ChainView chain = *j; + int chain_length = chain.GetResidueCount(); + if (chain_length < min_polymer_size_ && seqres.IsValid()) { + seq::SequenceHandle s = seqres.FindSequence(chain.GetName()); + if (s.IsValid()) + chain_length = s.GetLength(); + } + if (chain.IsPolymer() && chain_length >= min_polymer_size_) { + if (*curr_chain_name_ == 0) { + throw std::runtime_error("running out of chain names"); + } + ChainHandle new_chain = edi.InsertChain(String(1, curr_chain_name_[0])); + curr_chain_name_++; + edi.SetChainDescription(new_chain, chain.GetDescription()); + edi.SetChainType(new_chain, chain.GetType()); + new_chain.SetStringProp("original_name", chain.GetName()); + if (chain.HasProp("pdb_auth_chain_name")) + new_chain.SetStringProp("pdb_auth_chain_name", + chain.GetStringProp("pdb_auth_chain_name")); + + for (ResidueViewList::const_iterator k = chain.GetResidueList().begin(), + e3 = chain.GetResidueList().end(); k != e3; ++k) { + ResidueHandle new_res = edi.AppendResidue(new_chain, k->GetName(), + k->GetNumber()); + dst_to_src_map_[new_res] = k->GetHandle(); + needs_adjustment_ |= copy_atoms(*k, new_res, edi, *i); + } + continue; + } + if (chain.GetType() == CHAINTYPE_WATER) { + if (!water_chain) { + water_chain = edi.InsertChain(WATER_CHAIN_NAME); + edi.SetChainDescription(water_chain, chain.GetDescription()); + edi.SetChainType(water_chain, chain.GetType()); + } + for (ResidueViewList::const_iterator k = chain.GetResidueList().begin(), + e3 = chain.GetResidueList().end(); k != e3; ++k) { + ResidueHandle new_res = edi.AppendResidue(water_chain, k->GetName()); + new_res.SetStringProp("type", StringFromChainType(chain.GetType())); + new_res.SetStringProp("description", chain.GetDescription()); + dst_to_src_map_[new_res] = k->GetHandle(); + needs_adjustment_ |= copy_atoms(*k, new_res, edi, *i); + } + continue; + } + // deal with ligands... + if (!ligand_chain) { + ligand_chain = edi.InsertChain(LIGAND_CHAIN_NAME); + last_rnum = 0; + } + char ins_code = chain.GetResidueCount()>1 ? 'A' : '\0'; + + for (ResidueViewList::const_iterator k = chain.GetResidueList().begin(), + e3 = chain.GetResidueList().end(); k != e3; ++k) { + ResidueHandle new_res = edi.AppendResidue(ligand_chain, k->GetName(), + ResNum(last_rnum+1, ins_code)); + new_res.SetStringProp("type", StringFromChainType(chain.GetType())); + new_res.SetStringProp("description", chain.GetDescription()); + new_res.SetStringProp("original_name", chain.GetName()); + if (chain.HasProp("pdb_auth_chain_name")) + new_res.SetStringProp("pdb_auth_chain_name", + chain.GetStringProp("pdb_auth_chain_name")); + dst_to_src_map_[new_res] = k->GetHandle(); + ins_code += 1; + needs_adjustment_ |= copy_atoms(*k, new_res, edi, *i); + } + last_rnum+=1; + } + } +} + +EntityHandle PDBize::Finish(bool shift_to_fit) { + + if (needs_adjustment_ && shift_to_fit) { + geom::Vec3 min_coord = ent_.GetBounds().GetMin(); + geom::Mat4 tf(1, 0, 0, -999 - min_coord[0], + 0, 1, 0, -999 - min_coord[1], + 0, 0, 1, -999 - min_coord[2], + 0, 0, 0, 1); + XCSEditor edi = ent_.EditXCS(); + edi.ApplyTransform(tf); + } + TransferConnectivity(ent_, dst_to_src_map_); + return ent_; +} + +}}} diff --git a/modules/mol/alg/src/pdbize.hh b/modules/mol/alg/src/pdbize.hh new file mode 100644 index 0000000000000000000000000000000000000000..92c5cbfc4408899df4c830849a94ba2f618b3afb --- /dev/null +++ b/modules/mol/alg/src/pdbize.hh @@ -0,0 +1,56 @@ +//------------------------------------------------------------------------------ +// 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_ALG_PDBIZE_HH +#define OST_MOL_ALG_PDBIZE_HH + +#include <ost/mol/entity_view.hh> +#include <ost/mol/entity_handle.hh> +#include <ost/mol/residue_handle.hh> +#include <ost/seq/sequence_list.hh> +#include "module_config.hh" + +namespace ost { namespace mol { namespace alg { + + +extern const char* POLYPEPTIDE_CHAIN_NAMES; +extern const char* LIGAND_CHAIN_NAME; +extern const char* WATER_CHAIN_NAME; + +class DLLEXPORT_OST_MOL_ALG PDBize { +public: + explicit PDBize(int min_polymer_size=10): + min_polymer_size_(min_polymer_size), ent_(mol::CreateEntity()), + curr_chain_name_(POLYPEPTIDE_CHAIN_NAMES), needs_adjustment_(false) + {} + + void Add(mol::EntityView asu, const geom::Mat4List& transforms, + seq::SequenceList seqres); + + EntityHandle Finish(bool shift_to_fit=true); +private: + int min_polymer_size_; + EntityHandle ent_; + const char* curr_chain_name_; + bool needs_adjustment_; + std::map<ResidueHandle,ResidueHandle> dst_to_src_map_; +}; + +}}} +#endif + diff --git a/modules/mol/base/pymod/export_bond.cc b/modules/mol/base/pymod/export_bond.cc index fcad815704b856e8a86363e66c30f5cf18dfdb9b..c95268df47468b0ad1c717032091c7b35600d989 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; @@ -62,4 +61,5 @@ void export_Bond() .def(vector_indexing_suite<BondHandleList>()) .def(geom::VectorAdditions<BondHandleList>()); def("BondExists", &BondExists); + } diff --git a/modules/mol/base/pymod/export_editors.cc b/modules/mol/base/pymod/export_editors.cc index 7ac51a75e0fe8459604c7fa90b23eafaeb26c45f..6a659d286e095a8436dc338b9f9492f70e857f45 100644 --- a/modules/mol/base/pymod/export_editors.cc +++ b/modules/mol/base/pymod/export_editors.cc @@ -83,6 +83,8 @@ void (ICSEditor::*rotate_torsion_b)(const AtomHandle&, const AtomHandle&, const AtomHandle&, const AtomHandle&, Real, bool)=&ICSEditor::RotateTorsionAngle; +void (EditorBase::*renumber_chain_a)(ChainHandle,const ResNumList&)=&EditorBase::RenumberChain; +void (EditorBase::*renumber_chain_b)(const ChainHandle&,int, bool)=&EditorBase::RenumberChain; #if OST_NUMPY_SUPPORT_ENABLED template<typename T, bool O> void set_pos2_nc_t(XCSEditor& e, const AtomHandleList& alist, PyArrayObject* na) @@ -261,7 +263,8 @@ void export_Editors() .def("ReorderResidues",&EditorBase::ReorderResidues) .def("ReorderAllResidues",&EditorBase::ReorderAllResidues) .def("RenumberAllResidues",&EditorBase::RenumberAllResidues) - .def("RenumberChain",&EditorBase::RenumberChain) + .def("RenumberChain",renumber_chain_a) + .def("RenumberChain",renumber_chain_b) ; void (XCSEditor::*apply_transform1)(const geom::Mat4&) = &XCSEditor::ApplyTransform; diff --git a/modules/mol/base/pymod/export_residue.cc b/modules/mol/base/pymod/export_residue.cc index 284c2f0bc294825e5751a3f441e377d1d1666517..8f0e169944f856f6f47a0e6e37cf2068ddad9177 100644 --- a/modules/mol/base/pymod/export_residue.cc +++ b/modules/mol/base/pymod/export_residue.cc @@ -122,6 +122,10 @@ void export_Residue() .def(self+int()) .def(self-int()) ; + class_<ResNumList>("ResNumList", init<>()) + .def(vector_indexing_suite<ResNumList>()) + .def(geom::VectorAdditions<ResNumList>()) + ; implicitly_convertible<int, ResNum>(); scope().attr("PEPTIDE_LINKING")=char(ChemClass::PEPTIDE_LINKING); diff --git a/modules/mol/base/src/CMakeLists.txt b/modules/mol/base/src/CMakeLists.txt index 86d5ccca6dc92350f948990f833e84f18f5d9da9..9434837dd7901790ba4103a6665c837f63934db8 100644 --- a/modules/mol/base/src/CMakeLists.txt +++ b/modules/mol/base/src/CMakeLists.txt @@ -29,6 +29,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 @@ -84,6 +85,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/editor_base.cc b/modules/mol/base/src/editor_base.cc index 9e8729d9374391321f511f8e17e1bef79b81d327..b6cc4ab455036672b612e2d37f4ccfa93414b9c5 100644 --- a/modules/mol/base/src/editor_base.cc +++ b/modules/mol/base/src/editor_base.cc @@ -180,6 +180,14 @@ void EditorBase::DeleteChain(const ChainHandle& chain) ent_.Impl()->DeleteChain(chain.Impl()); } +void EditorBase::DeleteAtoms(const AtomHandleList& atoms) +{ + for (AtomHandleList::const_iterator i = atoms.begin(), e = atoms.end(); + i != e; ++i) { + i->GetResidue().Impl()->DeleteAtom(i->Impl()); + } +} + void EditorBase::DeleteAtom(const AtomHandle& atom_handle) { CheckHandleValidity(atom_handle); @@ -246,6 +254,12 @@ BondHandle EditorBase::Connect(const AtomHandle& first, return this->Connect(first,second,0.0, 0.0, 0.0, 1); } +void EditorBase::RenumberChain(ChainHandle chain, const ResNumList& new_numbers) +{ + CheckHandleValidity(chain); + chain.Impl()->RenumberAllResidues(new_numbers); +} + BondHandle EditorBase::Connect(const AtomHandle& first, const AtomHandle& second, Real len, Real theta, Real phi, diff --git a/modules/mol/base/src/editor_base.hh b/modules/mol/base/src/editor_base.hh index 05d82ddb0682e12737b629947f010947cb009842..255390c29dc3f3e7e286ad5ea966748b75ab72b2 100644 --- a/modules/mol/base/src/editor_base.hh +++ b/modules/mol/base/src/editor_base.hh @@ -216,7 +216,7 @@ public: void RenameResidue(ResidueHandle res, const String& new_name); void SetResidueNumber(ResidueHandle res, const ResNum& num); - + void RenameChain(ChainHandle chain, const String& new_name); /// \brief Assign type of chain according to ChainType. @@ -244,6 +244,10 @@ public: /// is the atom to remove. If no such atom exists, this method will /// have no effect void DeleteAtom(const AtomHandle& atom); + /// \ brief Delete a set of atoms + /// + /// All associated torsions and bonds will be removed as well + void DeleteAtoms(const AtomHandleList& atoms); /// \brief Add named torsion to entity TorsionHandle AddTorsion(const String& name, const AtomHandle& a1, @@ -279,6 +283,7 @@ public: void RenumberAllResidues(int start, bool keep_spacing); + void RenumberChain(ChainHandle chain, const ResNumList& new_numbers); /// \brief renumber residues of one chain /// diff --git a/modules/mol/base/src/impl/chain_impl.cc b/modules/mol/base/src/impl/chain_impl.cc index 8b3cbe271eef0e860d78ea5039ac7f00a35e191e..2ec5b8694668d91c207679a99de9c0b2a80157f9 100644 --- a/modules/mol/base/src/impl/chain_impl.cc +++ b/modules/mol/base/src/impl/chain_impl.cc @@ -516,6 +516,17 @@ void ChainImpl::RenumberAllResidues(int start, bool keep_spacing) UpdateShifts(); } +void ChainImpl::RenumberAllResidues(const ResNumList& new_numbers) +{ + if (new_numbers.size() != residue_list_.size()) { + throw Error("number of residues and residue numbers must match"); + } + for (size_t i = 0; i<new_numbers.size(); ++i) { + residue_list_[i]->SetNumber(new_numbers[i]); + } + this->UpdateShifts(); +} + void ChainImpl::SetInSequence(const int index) { ResNum num=residue_list_[index]->GetNumber(); diff --git a/modules/mol/base/src/impl/chain_impl.hh b/modules/mol/base/src/impl/chain_impl.hh index a2c607ec4e2df3cca3783a8a14532e795536593e..82334c6fbb054eb200db5dacaec0587c9d5511d1 100644 --- a/modules/mol/base/src/impl/chain_impl.hh +++ b/modules/mol/base/src/impl/chain_impl.hh @@ -175,6 +175,8 @@ public: void RenumberAllResidues(int start, bool keep_spacing); + void RenumberAllResidues(const ResNumList& new_numbers); + int GetIndex(const ResidueImplPtr& res) const; void AssignSecondaryStructure(SecStructure ss, const ResNum& start, diff --git a/modules/mol/base/src/impl/entity_impl.cc b/modules/mol/base/src/impl/entity_impl.cc index 852b9bebb1653110cde6610f94ef3a620f09c8b6..865ef7172ebf5452e9acdc737ea170f068ad01f3 100644 --- a/modules/mol/base/src/impl/entity_impl.cc +++ b/modules/mol/base/src/impl/entity_impl.cc @@ -35,6 +35,7 @@ #include <ost/geom/geom.hh> #include <ost/log.hh> +#include <ost/profile.hh> #include "atom_impl.hh" #include "entity_impl.hh" #include <ost/mol/entity_visitor.hh> @@ -114,6 +115,7 @@ int EntityImpl::GetResidueCount() const EntityImplPtr EntityImpl::Copy() { + Profile prof("EntityImpl::Copy"); #if MAKE_SHARED_AVAILABLE EntityImplPtr ent_p=boost::make_shared<EntityImpl>(); #else diff --git a/modules/mol/base/src/residue_prop.hh b/modules/mol/base/src/residue_prop.hh index 4a411cca6e27250fdd23d4b538ffea6064b8d106..d4d79fd688ed96cf6f197f13e4116270e84ff212 100644 --- a/modules/mol/base/src/residue_prop.hh +++ b/modules/mol/base/src/residue_prop.hh @@ -19,6 +19,7 @@ #ifndef OST_RESIDUE_PROP_HH #define OST_RESIDUE_PROP_HH +#include <vector> #include <boost/operators.hpp> #include <ost/mol/module_config.hh> @@ -122,6 +123,7 @@ private: }; typedef String ResidueKey; +typedef std::vector<ResNum> ResNumList; inline std::ostream& operator<<(std::ostream& os, const ResNum& n) { 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/conop/src/builder_fw.hh b/modules/mol/base/src/transfer_connectivity.hh similarity index 70% rename from modules/conop/src/builder_fw.hh rename to modules/mol/base/src/transfer_connectivity.hh index c61de7becda4a9e3476a620a71da563d0c4c2f5c..e46691cd25d920ff1268f52d730ef70f2662d464 100644 --- a/modules/conop/src/builder_fw.hh +++ b/modules/mol/base/src/transfer_connectivity.hh @@ -16,16 +16,22 @@ // 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_CONOP_BUILDER_FW_HH -#define OST_CONOP_BUILDER_FW_HH +#ifndef OST_MOL_TRANSFER_CONNECTIVITY_HH +#define OST_MOL_TRANSFER_CONNECTIVITY_HH -#include <boost/shared_ptr.hpp> -namespace ost { namespace conop { +#include "module_config.hh" +#include "entity_handle.hh" +#include "residue_handle.hh" -class Builder; -typedef boost::shared_ptr<Builder> BuilderP; +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 de287b52cde367342ae188049c79d8c176dc4e12..1aa275c1adca3bbc7afed1f34b4b3518fcfa6593 100644 --- a/modules/mol/base/tests/CMakeLists.txt +++ b/modules/mol/base/tests/CMakeLists.txt @@ -11,6 +11,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(); diff --git a/modules/seq/alg/pymod/renumber.py b/modules/seq/alg/pymod/renumber.py index f715f0bd6f1ef9dbbc60b3afc316502a9d462398..22873111e877c66da19ee2af80f49ce169ccd4ef 100644 --- a/modules/seq/alg/pymod/renumber.py +++ b/modules/seq/alg/pymod/renumber.py @@ -1,6 +1,43 @@ from ost import io, seq, mol, conop from ost import * + +def _RenumberSeq(seq_handle): + if not seq_handle.HasAttachedView(): + raise RuntimeError("Sequence Handle has no attached view") + ev = seq_handle.attached_view.CreateEmptyView() + new_numbers = mol.ResNumList() + for pos in range(len(seq_handle)): + if seq_handle[pos]!='-': + r=seq_handle.GetResidue(pos) + if r.IsValid(): + #print seq_handle[pos],r.number.num,pos+1 + ev.AddResidue(r, mol.INCLUDE_ALL) + new_numbers.append(pos+1) + else: + raise RuntimeError('Error: renumbering failed at position %s' %pos) + return ev, new_numbers + +def _RenumberAln(aln, seq_index): + if not aln.sequences[seq_index].HasAttachedView(): + raise RuntimeError("Sequence Handle has no attached view") + counter=0 + ev = aln.sequences[seq_index].attached_view.CreateEmptyView() + new_numbers = mol.ResNumList() + for col in aln: + if col[0]!='-' and col[seq_index]!='-': + if col[0]!=col[seq_index]: + raise RuntimeError("residue mismatch at position %d (%s vs %s) (renumbering failed)"%(counter, col[0],col[1])) + rnum=aln.GetSequence(seq_index).GetResidueIndex(counter) + r=aln.GetSequence(seq_index).GetResidue(counter) + if not r.IsValid(): + raise RuntimeError("invalid residue at postion %s (renumbering failed)" %(counter)) + ev.AddResidue(r, mol.INCLUDE_ALL) + new_numbers.append(counter+1) + counter+=1 + return ev, new_numbers + + def Renumber(seq_handle, sequence_number_with_attached_view=1): """ Function to renumber an entity according to an alignment between the model sequence @@ -21,65 +58,11 @@ def Renumber(seq_handle, sequence_number_with_attached_view=1): """ if isinstance(seq_handle, seq.SequenceHandle): - if seq_handle.HasAttachedView()==False: - raise RuntimeError, "Sequence Handle has no attached view" - changed_residue_count=0 - renumberingFlag = False - ent_n=mol.CreateEntity() - ed=ent_n.EditXCS() - c=ed.InsertChain(" ") - for pos in range(len(seq_handle)): - if seq_handle[pos]!='-': - r=seq_handle.GetResidue(pos) - if r.IsValid(): - #print seq_handle[pos],r.number.num,pos+1 - if r.number.num!=pos+1: - changed_residue_count+=1 - renumberingFlag = True - r_n=ed.AppendResidue(c,r.name, mol.ResNum(pos+1)) - for atom in r.atoms: - ed.InsertAtom(r_n,atom.name,atom.pos,element=atom.element) - else: - err='Error: renumbering failed at position %s' %pos - raise RuntimeError, err - if renumberingFlag == True: - err = 'Warning: %s residues have been renumbered!' %changed_residue_count - LogInfo(err) - conop.ConnectAll(ent_n) - return ent_n - + ev, new_numbers = _RenumberSeq(seq_handle) elif isinstance(seq_handle, seq.AlignmentHandle): - if seq_handle.GetSequence(sequence_number_with_attached_view).HasAttachedView()==False: - raise RuntimeError, "Sequence Handle has no attached view" - dir(seq_handle) - counter=0 - changed_residue_count=0 - renumberingFlag = False - ent_n=mol.CreateEntity() - ed=ent_n.EditXCS() - c=ed.InsertChain(seq_handle.GetSequence(sequence_number_with_attached_view).GetAttachedView().chains[0].name) - for col in seq_handle: - if col[0]!='-' and col[1]!='-': - if col[0]==col[1]: - rnum=seq_handle.GetSequence(sequence_number_with_attached_view).GetResidueIndex(counter) - r=seq_handle.GetSequence(sequence_number_with_attached_view).GetResidue(counter) - if r.IsValid(): - if r.number.num!=counter+1: - changed_residue_count+=1 - renumberingFlag = True - r_n=ed.AppendResidue(c,r.name, mol.ResNum(counter+1)) - for atom in r.atoms: - ed.InsertAtom(r_n,atom.name,atom.pos,atom.element, atom.b_factor, - atom.occupancy, atom.is_hetatom) - - else: - raise RuntimeError("invalide residue at postion %s (renumbering failed)" %(counter)) - else: - raise RuntimeError("residue mismatch at position %d (%s vs %s) (renumbering failed)"%(counter, col[0],col[1])) - counter+=1 - if renumberingFlag == True: - err = 'Warning: %s residues have been renumbered!' %changed_residue_count - LogInfo(err) - conop.ConnectAll(ent_n) - return ent_n + ev, new_numbers = _RenumberAln(seq_handle, sequence_number_with_attached_view) + ev.AddAllInclusiveBonds() + new_ent = mol.CreateEntityFromView(ev,False); + new_ent.EditXCS().RenumberChain(new_ent.chains[0], new_numbers) + return new_ent diff --git a/modules/seq/alg/tests/test_aligntoseqres.py b/modules/seq/alg/tests/test_aligntoseqres.py index 6c390008e69d81d2613337a863503769b6da1872..126c7f0471b43b1898f0b010d73847a00aed7f92 100644 --- a/modules/seq/alg/tests/test_aligntoseqres.py +++ b/modules/seq/alg/tests/test_aligntoseqres.py @@ -68,9 +68,8 @@ class TestAlignToSeqRes(unittest.TestCase): self.assertEqual(seq.alg.ValidateSEQRESAlignment(seqres_aln, chain), False) if __name__ == "__main__": - builder=conop.GetBuilder() - if not hasattr(builder, 'compound_lib'): - print 'default builder does not use compound library. ignoring unit tests' + if not conop.GetDefaultLib(): + print 'No compound library available. Ignoring unit tests' else: from ost import testutils testutils.RunTests() diff --git a/modules/seq/alg/tests/test_renumber.py b/modules/seq/alg/tests/test_renumber.py index 8f234f859624416d2533d8a9de3d0c9b6d5c86c2..0309f5a1b9166f1a2e4a2febd947832c06487218 100644 --- a/modules/seq/alg/tests/test_renumber.py +++ b/modules/seq/alg/tests/test_renumber.py @@ -6,6 +6,11 @@ from ost import seq from ost.bindings.clustalw import * from ost.seq.alg import renumber +try: + clustalw_path=settings.Locate(('clustalw', 'clustalw2')) +except(settings.FileNotFound): + clustalw_path=None + class TestRenumber(unittest.TestCase): def setUp(self): @@ -17,14 +22,53 @@ class TestRenumber(unittest.TestCase): self.peptide_del_4 = io.LoadEntity("testfiles/peptide_del_4.pdb") self.peptide_mutation_3 = io.LoadEntity("testfiles/peptide_mutation_3.pdb") + def testRenumbersChainsBasedOnSequence(self): + aln_seq = seq.CreateSequence('A', 'MP-T---NA') + aln_seq.AttachView(self.peptide_original.Select('')) + + renumbered = renumber.Renumber(aln_seq) + + res = renumbered.residues + self.assertEqual(len(res), 5) + self.assertEqual(res[0].number, 1) + self.assertEqual(res[1].number, 2) + self.assertEqual(res[2].number, 4) + self.assertEqual(res[3].number, 8) + self.assertEqual(res[4].number, 9) + + def testRenumbersChainsBasedOnAlignment(self): + aln_seq = seq.CreateSequence('A', 'MP-T---NA') + aln_seq.AttachView(self.peptide_original.Select('')) + aln = seq.CreateAlignment(seq.CreateSequence('A', 'MP-T-XXNA'), aln_seq) + + renumbered = renumber.Renumber(aln) + + res = renumbered.residues + self.assertEqual(len(res), 5) + self.assertEqual(res[0].number, 1) + self.assertEqual(res[1].number, 2) + self.assertEqual(res[2].number, 4) + self.assertEqual(res[3].number, 8) + self.assertEqual(res[4].number, 9) + + def testRenumberPreservesBonds(self): + aln_seq = seq.CreateSequence('A', 'MP-T---NA') + aln_seq.AttachView(self.peptide_original.Select('')) + + renumbered = renumber.Renumber(aln_seq) + + self.assertTrue(mol.BondExists(renumbered.chains[0].FindAtom(1, 'N'), + renumbered.chains[0].FindAtom(1, 'CA'))) - def testPeptidePlusFive(self): + def testClustalWPeptidePlusFive(self): """ All residue numbers shifted by 5. Check whether internal atom order changes while renumbering (a new entity is generated in the edit_mode) TODO: add more basic tests: are all properties preserved? """ + if not clustalw_path: + return model_seq=seq.SequenceFromChain(" ", self.peptide_plus_5.chains[0]) model_seq.name="model" aln=ClustalW(self.target_seq,model_seq) @@ -39,10 +83,12 @@ class TestRenumber(unittest.TestCase): "Renumbering failed on atom level: restoring from ResNum+5" - def testPeptideRandom(self): + def testClustalWPeptideRandom(self): """ Change residue names in random order """ + if not clustalw_path: + return model_seq=seq.SequenceFromChain(" ", self.peptide_random.chains[0]) model_seq.name="model" aln=ClustalW(self.target_seq,model_seq) @@ -57,10 +103,12 @@ class TestRenumber(unittest.TestCase): "Renumbering failed on atom level: restoring from random residue numbers" - def testPeptideDel_1_2(self): + def testClustalWPeptideDel_1_2(self): """ First two residues were removed """ + if not clustalw_path: + return model_seq=seq.SequenceFromChain(" ", self.peptide_del_1_2.chains[0]) model_seq.name="model" aln=ClustalW(self.target_seq,model_seq) @@ -77,10 +125,12 @@ class TestRenumber(unittest.TestCase): "Renumbering failed on atom level: restoring from random residue numbers" - def testPeptideDel_4(self): + def testClustalWPeptideDel_4(self): """ Residues in the middle (position 4) was removed """ + if not clustalw_path: + return model_seq=seq.SequenceFromChain(" ", self.peptide_del_4.chains[0]) model_seq.name="model" aln=ClustalW(self.target_seq,model_seq) @@ -99,10 +149,12 @@ class TestRenumber(unittest.TestCase): "Renumbering failed on atom level: restoring from random residue numbers" - def testPeptideMutation_3(self): + def testClustalWPeptideMutation_3(self): """ Mutation to GLY at postion 3 """ + if not clustalw_path: + return model_seq=seq.SequenceFromChain(" ", self.peptide_mutation_3.chains[0]) model_seq.name="model" aln=ClustalW(self.target_seq,model_seq) @@ -114,10 +166,7 @@ class TestRenumber(unittest.TestCase): if __name__ == "__main__": # test renumbering # test if clustalw package is available on system, otherwise ignore tests - try: - clustalw_path=settings.Locate(('clustalw', 'clustalw2')) - except(settings.FileNotFound): - print "Could not find clustalw executable: ignoring unit tests" - sys.exit(0) + if not clustalw_path: + print "Could not find clustalw executable: ignoring some renumber unit tests" from ost import testutils testutils.RunTests() diff --git a/modules/seq/base/src/sequence_handle.hh b/modules/seq/base/src/sequence_handle.hh index 937387c797bc42f28b0fe902f1e9af256d6fa416..d7247cbd10abca25bdc9fc3c00b60dac7c6e9915 100644 --- a/modules/seq/base/src/sequence_handle.hh +++ b/modules/seq/base/src/sequence_handle.hh @@ -284,7 +284,7 @@ public: /// /// The sequence is mapped onto the chain with given name void AttachView(const mol::EntityView& view, const String& chain_name); - + /// \internal SequenceHandle(const impl::SequenceImplPtr& impl); diff --git a/scripts/ost_startup.py b/scripts/ost_startup.py index 6671b51643e299cb81645fa9707ae4a714bb3d95..553d54cb906aa6a86e534881c181077f3d007e0e 100644 --- a/scripts/ost_startup.py +++ b/scripts/ost_startup.py @@ -37,16 +37,16 @@ from ost import * import ost ost.SetPrefixPath(_base_dir) -def _InitRuleBasedBuilder(): + +def _InitRuleBasedProcessor(): compound_lib_path=os.path.join(ost.GetSharedDataPath(), 'compounds.chemlib') if os.path.exists(compound_lib_path): compound_lib=conop.CompoundLib.Load(compound_lib_path) - conop.RegisterBuilder(conop.RuleBasedBuilder(compound_lib), 'RBB') - conop.SetDefaultBuilder('RBB') + conop.SetDefaultLib(compound_lib) + io.profiles['DEFAULT'].processor = conop.RuleBasedProcessor(compound_lib) -# switch to rule-based builder for high fidelity if compounds.chemlib is -# available -_InitRuleBasedBuilder() +# switch to rule-based processor, if compound library is available +_InitRuleBasedProcessor() import os.path HistoryFile=os.path.expanduser('~/.ost_history') diff --git a/tools/molck/main.cc b/tools/molck/main.cc index 94e5a97f5120b9522a3d8678518c44fbe84f4cb7..09251bcfb6a29a38c36ba902498745bbf8ec23e5 100644 --- a/tools/molck/main.cc +++ b/tools/molck/main.cc @@ -67,14 +67,13 @@ CompoundLibPtr load_compound_lib(const String& custom_path) exe_path = std::string( result, (count > 0) ? count : 0 ); #endif if (exe_path.empty()) { - std::cerr << "Could not determine the path of the molck executable. Will only look for compounds.chemlib in the current working directory" << std::endl; + std::cerr << "Could not determine the path of the molck executable. Will only " + "look for compounds.chemlib in the current working directory" << std::endl; } else { fs::path path_and_exe(exe_path); fs::path path_only=path_and_exe.branch_path(); fs::path share_path = path_only.branch_path(); - share_path/="share"; - share_path/="openstructure"; - share_path/="compounds.chemlib"; + share_path = share_path / "share" / "openstructure" / "compounds.chemlib"; String share_path_string=BFPathToString(share_path); @@ -89,37 +88,33 @@ CompoundLibPtr load_compound_lib(const String& custom_path) return CompoundLibPtr(); } +const char* USAGE= +"this is molck - the molecule checker\n" +"usage: molck [options] file1.pdb [file2.pdb [...]]\n" +"options \n" +" --complib=path location of the compound library file. If not provided, the \n" +" following locations are searched in this order: \n" +" 1. Working directory, 2. OpenStructure standard library location (if the \n" +" executable is part of a standard OpenStructure installation) \n" +" --rm=<a>,<b> remove atoms and residues matching some criteria \n" +" zeroocc - Remove atoms with zero occupancy \n" +" hyd - Remove hydrogen atoms \n" +" oxt - Remove terminal oxygens \n" +" nonstd - Remove all residues not one of the 20 standard amino acids \n" +" unk - Remove unknown and atoms not following the nomenclature\n" +" --fix-ele clean up element column\n" +" --stdout write cleaned file(s) to stdout \n" +" --out=filename write cleaned file(s) to disk. % characters in the filename are \n" +" replaced with the basename of the input file without extension. \n" +" Default: %-molcked.pdb \n" +" --color=auto|on|off \n" +" whether output should be colored\n" +" --map-nonstd maps modified residues back to the parent amino acid, for example\n" +" MSE -> MET, SEP -> SER.\n"; + void usage() { - std::cerr << "usage: molck [options] file1.pdb [file2.pdb [...]]" << std::endl; - std::cerr << "options" << std::endl; - std::cerr << " --complib=path location of the compound library file" << std::endl; - std::cerr << " If not provided, the following locations are searched" << std::endl; - std::cerr << " in this order:" << std::endl; - std::cerr << " 1. Working directory" << std::endl; - std::cerr << " 2. OpenStructure standard library location" << std::endl; - std::cerr << " (if the executable is part of a standard" << std::endl; - std::cerr << " OpenStructure installation)" << std::endl; - std::cerr << " --rm=<a>,<b> remove atoms and residues matching some criteria" << std::endl; - std::cerr << " zeroocc - Remove atoms with zero occupancy" << std::endl; - std::cerr << " hyd - Remove hydrogen atoms" << std::endl; - std::cerr << " oxt - Remove terminal oxygens" << std::endl; - std::cerr << " nonstd - Remove all residues not " << std::endl - << " one of the 20 standard amino acids" << std::endl; - std::cerr << " unk - Remove unknown atoms and atoms that " << std::endl - << " are not supposed to be part of a residue" << std::endl; - std::cerr << " --fix-ele clean up element column" << std::endl; - std::cerr << " --stdout write cleaned file(s) to stdout" << std::endl; - std::cerr << " --fileout=blueprint write cleaned file(s) to disk" << std::endl; - std::cerr << " The blueprint string, which must contain a % character," << std::endl; - std::cerr << " is used to generate the output filename and path" << std::endl; - std::cerr << " by replacing % with the input file name without" << std::endl; - std::cerr << " the extension. Output files automatically add" << std::endl; - std::cerr << " '.pdb' extension" << std::endl; - std::cerr << " --color=auto|on|off " << std::endl - << " whether output should be colored" << std::endl; - std::cerr << " --map-nonstd maps modified residues back to the parent amino " << std::endl - << " acid, e.g. MSE -> MET, SEP -> SER." << std::endl; + std::cerr << USAGE << std::endl; exit(0); } @@ -153,7 +148,8 @@ int main(int argc, char *argv[]) "whether the output should be colored.") ("files", po::value< std::vector<String> >(), "input file(s)") ("stdout", "write cleaned file(s) to stdout") - ("fileout", po::value<String>(&output_blueprint_string), "write cleaned file to output using blueprint to determine path") + ("out,o", po::value<String>(&output_blueprint_string)->default_value("%-molcked.pdb"), + "write cleaned file to output using blueprint to determine path") ("map-nonstd", "map non standard residues back to standard ones (e.g.: MSE->MET,SEP->SER,etc.)") ("fix-ele", "insert element") ("complib", po::value<String>(&custom_path)->default_value(""),"location of the compound library file") @@ -184,11 +180,10 @@ int main(int argc, char *argv[]) } if (vm.count("stdout")) { write_to_stdout = true; - } - if (vm.count("fileout")) { + } else { write_to_file = true; - output_blueprint_string = vm["fileout"].as<String>(); - } + output_blueprint_string = vm["out"].as<String>(); + } if (vm.count("map-nonstd")) { map_nonstd_res = true; } @@ -266,7 +261,7 @@ int main(int argc, char *argv[]) } XCSEditor edi=ent.EditXCS(); - DiagEngine diags; + Diagnostics diags; Checker checker(lib, ent, diags); if (rm_zero_occ_atoms) { std::cerr << "removing atoms with zero occupancy" << std::endl; @@ -306,8 +301,9 @@ int main(int argc, char *argv[]) checker.CheckForCompleteness(); checker.CheckForUnknownAtoms(); checker.CheckForNonStandard(); - for (size_t j=0; j<diags.GetDiags().size(); ++j) { - const Diag* diag=diags.GetDiags()[j]; + for (Diagnostics::const_diag_iterator + j = diags.diags_begin(), e = diags.diags_end(); j != e; ++j) { + const Diag* diag=*j; std::cerr << diag->Format(colored); switch (diag->GetType()) { case DIAG_UNK_ATOM: @@ -360,24 +356,17 @@ int main(int argc, char *argv[]) if (write_to_file) { fs::path input_file_path(files[i]); fs::path input_filename = BFPathStem(input_file_path); - - String input_filename_string=BFPathToString(input_filename); - size_t replstart =output_blueprint_string.find('%'); - - if (replstart == String::npos) { - std::cerr << "The output blueprint string does not contain a % character" << std::endl; - exit(-1); - } String output_blueprint_string_copy = output_blueprint_string; - output_blueprint_string_copy.replace(replstart,1,input_filename_string); - output_blueprint_string_copy+=".pdb"; - + if (replstart != String::npos) { + output_blueprint_string_copy.replace(replstart,1,input_filename_string); + } try { fs::path out_path(output_blueprint_string_copy); - if (!exists(out_path)) { - std::cerr << "Output path does not exist: " << output_blueprint_string_copy << std::endl; + if (out_path.has_parent_path() && !exists(out_path.parent_path())) { + std::cerr << "Output path does not exist: " + << output_blueprint_string_copy << std::endl; exit(-1); } } catch (std::exception& e) { @@ -385,7 +374,8 @@ int main(int argc, char *argv[]) size_t perden = String(e.what()).find("Permission denied"); if (perden != String::npos) { - std::cerr << "Cannot write into output directory: " << output_blueprint_string_copy << std::endl; + std::cerr << "Cannot write into output directory: " + << output_blueprint_string_copy << std::endl; exit(-1); } else { std::cerr << e.what() << std::endl; @@ -394,7 +384,7 @@ int main(int argc, char *argv[]) } std::cerr << "Writing out file: " << output_blueprint_string_copy << std::endl; PDBWriter writer(output_blueprint_string_copy, prof); - writer.Write(ent); + writer.Write(ent); } }