/src/openbabel/include/openbabel/builder.h
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************** |
2 | | builder.h - OBBuilder class. |
3 | | |
4 | | Copyright (C) 2007-2008 by Tim Vandermeersch |
5 | | <tim.vandermeersch@gmail.com> |
6 | | |
7 | | This file is part of the Open Babel project. |
8 | | For more information, see <http://openbabel.org/> |
9 | | |
10 | | This program is free software; you can redistribute it and/or modify |
11 | | it under the terms of the GNU General Public License as published by |
12 | | the Free Software Foundation version 2 of the License. |
13 | | |
14 | | This program is distributed in the hope that it will be useful, |
15 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | | GNU General Public License for more details. |
18 | | ***********************************************************************/ |
19 | | |
20 | | #ifndef OB_BUILDER_H |
21 | | #define OB_BUILDER_H |
22 | | |
23 | | #include <vector> |
24 | | #include <string> |
25 | | #include <map> |
26 | | |
27 | | #include <list> |
28 | | #include <set> |
29 | | |
30 | | #include <openbabel/stereo/stereo.h> |
31 | | |
32 | | namespace OpenBabel |
33 | | { |
34 | | class OBMol; |
35 | | class OBAtom; |
36 | | class OBSmartsPattern; |
37 | | class vector3; |
38 | | class OBBitVec; |
39 | | |
40 | | //! \class OBBuilder builder.h <openbabel/builder.h> |
41 | | //! \brief Class to build 3D structures |
42 | | class OBAPI OBBuilder { |
43 | | public: |
44 | | |
45 | 0 | OBBuilder(): _keeprings(false) {} |
46 | | |
47 | | ///@name Call the build algorithm |
48 | | //@{ |
49 | | /*! The mol object contains all connectivity information (atomic numbers, bonds, bond orders, ..) |
50 | | * but no 3D coordinates. Build generates these coordinates and assigns them. |
51 | | * \param mol Molecule with the connectivity (from SMILES for example). The coordinates are also |
52 | | * changed in this mol. |
53 | | * \param stereoWarnings Warn if the stereochemistry is incorrect (default is true) |
54 | | */ |
55 | | bool Build(OBMol &mol, bool stereoWarnings = true); |
56 | | //@} |
57 | | |
58 | | ///@name Setup build parameters |
59 | | //@{ |
60 | | /*! If the molecule already contains 3D coordinates, if you set KeepRings to true it will use |
61 | | * retain the 3D coordinates of the rings. By default KeepRings is false, and ring conformations |
62 | | * are obtained by lookup in a library of ring conformers. However, since the ring conformer library |
63 | | * is not exhaustive, if the ring system is not found in the library, the resulting 3D structure can |
64 | | * be poor, and require geometry optimisation before it is reasonable. If your starting point is |
65 | | * a 3D structure, you can set KeepRings to true, and the conformation will be taken from the input. |
66 | | * The remaining (acyclic) bonds will still all be built by the builder. |
67 | | */ |
68 | 0 | void SetKeepRings() { _keeprings = true; } |
69 | 0 | void UnsetKeepRings() { _keeprings = false; } |
70 | | //@} |
71 | | |
72 | | |
73 | | //! Used by LoadFragments to check for invalid (all zero coordinates) fragments |
74 | | void AddRingFragment(OBSmartsPattern *sp, const std::vector<vector3> &coords); |
75 | | //! Load fragment info from file, if is it has not already been done |
76 | | void LoadFragments(); |
77 | | std::vector<vector3> GetFragmentCoord(std::string smiles); |
78 | | |
79 | | /*! Get the position for a new neighbour on atom. Returns |
80 | | * non-finite vector if there is no reasonable location. |
81 | | * \param atom Atom for which we want a new neighbour location. |
82 | | * \returns The position for the new atom. |
83 | | */ |
84 | | static vector3 GetNewBondVector(OBAtom *atom); |
85 | | static vector3 GetNewBondVector(OBAtom *atom, double length); |
86 | | |
87 | | /*! Atoms a and b are part of two fragments that are not connected in mol. |
88 | | * Connect will translate and rotate the fragment that contains b so that |
89 | | * a and b are separated by a bond. This bond is also added. |
90 | | * \param mol The molecule to be modified |
91 | | * \param a Index for atom in fragment that should not be rotated. |
92 | | * \param b Index for atom in fragment that should be rotated. |
93 | | * \param newpos Direction for new bond between a and b |
94 | | * \param bondOrder Bond order of the new bond between a and b. |
95 | | * \returns true if successful or fails when failed (most likely cause |
96 | | * for failing: a and b are in the same fragment, they are connected) |
97 | | */ |
98 | | static bool Connect(OBMol &mol, int a, int b, vector3 &newpos, int bondOrder = 1); |
99 | | /*! Atoms a and b are part of two fragments that are not connected in mol. |
100 | | * Connect will translate and rotate the fragment that contains b so that |
101 | | * a and b are separated by a bond. This bond is also added. |
102 | | * \param mol The molecule to be modified |
103 | | * \param a Index for atom in fragment that should not be rotated. |
104 | | * \param b Index for atom in fragment that should be rotated. |
105 | | * \param bondOrder Bond order of the new bond bewtween a and b. |
106 | | * \returns true if successful or fails when failed (most likely cause |
107 | | * for failing: a and b are in the same fragment, they are connected) |
108 | | */ |
109 | | static bool Connect(OBMol &mol, int a, int b, int bondOrder = 1); |
110 | | /*! Swap group b, bonded to a with group d, bonded to c. The bonds a-b and b-c cannot be |
111 | | * part of a ring. Atoms a and b will not be moved. Atoms b, d and their connected atoms |
112 | | * (after deleting bonds ab and cd) will be translated/rotated. |
113 | | * |
114 | | * Example: |
115 | | * \code |
116 | | * \ / / |
117 | | * b d |
118 | | * \ / Swap(a,b,c,d) \ / |
119 | | * a---x ----> a---x |
120 | | * / \ / / \ / |
121 | | * x c---d x c---b |
122 | | * \ |
123 | | * \endcode |
124 | | * |
125 | | * |
126 | | * This function can also be used to invert chiral centers if a and c are the same atom. |
127 | | * |
128 | | * Example |
129 | | * \code |
130 | | * 1 3 |
131 | | * | Swap(C,1,C,3) | |
132 | | * 2>-C-<3 -----> 2>-C-<1 |
133 | | * | | |
134 | | * 4 4 |
135 | | * \endcode |
136 | | */ |
137 | | static bool Swap(OBMol &mol, int a, int b, int c, int d); |
138 | | /*! Atoms a and b must be bonded and this bond cannot be part of a ring. The bond will |
139 | | * be broken and the smiles fragment will be inserted bewteen the two remaining fragments. |
140 | | * The fragment that contains a will not be translated or rotated. Parameters c and d are |
141 | | * the index in the smiles to which atoms a and b will be connected respectivly. |
142 | | * |
143 | | */ |
144 | | //bool Insert(OBMol &mol, int a, int b, std::string smiles, int c, int d); |
145 | | /*! Correct double bond stereochemistry |
146 | | * |
147 | | * \returns Success or failure |
148 | | */ |
149 | | static bool CorrectStereoBonds(OBMol &mol); |
150 | | /*! Correct stereochemistry at tetrahedral atoms with at least two non-ring |
151 | | * bonds. It also works for spiro atoms. |
152 | | * |
153 | | * \returns Success or failure |
154 | | */ |
155 | | static bool CorrectStereoAtoms(OBMol &mol, bool warn = true); |
156 | | /*! Does this atom connect two rings which are not otherwise connected? |
157 | | */ |
158 | | static bool IsSpiroAtom(unsigned long atomId, OBMol &mol); |
159 | | /*! Get the fragment to which this atom belongs. |
160 | | * \param atom Atom in the fragment. |
161 | | * \returns The OBBitVec defining the fragment to which a belongs. |
162 | | */ |
163 | | static OBBitVec GetFragment(OBAtom *atom); |
164 | | static void AddNbrs(OBBitVec &fragment, OBAtom *atom); |
165 | | |
166 | | private: |
167 | | //! used to hold the fragments loaded in the constructor |
168 | | //static std::map<std::string, double> _torsion; |
169 | | static std::vector<std::string> _rigid_fragments; |
170 | | static std::vector<std::pair<OBSmartsPattern*, std::vector<vector3> > > _ring_fragments; |
171 | | static std::map<std::string, int> _rigid_fragments_index; |
172 | | static std::map<std::string, std::vector<vector3> > _rigid_fragments_cache; |
173 | | //! Connect a ring fragment to an already matched fragment. Currently only |
174 | | // supports the case where the fragments overlap at a spiro atom only. |
175 | | static void ConnectFrags(OBMol &mol, OBMol &workmol, std::vector<int> match, std::vector<vector3> coords, |
176 | | std::vector<int> pivot); |
177 | | //! Rotate one of the spiro rings 180 degrees |
178 | | static void FlipSpiro(OBMol &mol, int idx); |
179 | | static bool FixRingStereo(std::vector<std::pair<OBStereo::Ref, bool> > atomIds, |
180 | | OBMol &mol, OBStereo::Refs &unfixedcenters); |
181 | | static void AddRingNbrs(OBBitVec &fragment, OBAtom *atom, OBMol &mol); |
182 | | static bool SwapWithVector(OBMol &mol, int a, int b, int c, const vector3 &newlocation); |
183 | | bool _keeprings; |
184 | | }; // class OBBuilder |
185 | | |
186 | | }// namespace OpenBabel |
187 | | |
188 | | #endif // OB_BUILDER_H |
189 | | |
190 | | //! \file builder.h |
191 | | //! \brief Class to build 3D structures |