1 |
tim |
741 |
/********************************************************************** |
2 |
|
|
rotor.h - Rotate torsional according to rotor rules. |
3 |
|
|
|
4 |
|
|
Copyright (C) 1998-2000 by OpenEye Scientific Software, Inc. |
5 |
|
|
Some portions Copyright (C) 2001-2005 by Geoffrey R. Hutchison |
6 |
|
|
|
7 |
|
|
This file is part of the Open Babel project. |
8 |
|
|
For more information, see <http://openbabel.sourceforge.net/> |
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_ROTOR_H |
21 |
|
|
#define OB_ROTOR_H |
22 |
|
|
|
23 |
|
|
#include "parsmart.hpp" |
24 |
|
|
#include "typer.hpp" |
25 |
|
|
|
26 |
|
|
namespace OpenBabel |
27 |
|
|
{ |
28 |
|
|
|
29 |
|
|
class OBRotor; |
30 |
|
|
class OBRotorList; |
31 |
|
|
class OBRotorRule; |
32 |
|
|
class OBRotorRules; |
33 |
|
|
|
34 |
|
|
//! \brief A rule for torsional conformer searching, defined by a SMARTS pattern |
35 |
|
|
//! |
36 |
|
|
//! Rules define a SMARTS pattern to match and a set of 4 reference atoms |
37 |
|
|
//! defining the dihedral angle. The rule can either define a set of possible |
38 |
|
|
//! dihedral angles in degrees or a "delta" (i.e., all multiples of delta will |
39 |
|
|
//! be considered) |
40 |
|
|
class OBAPI OBRotorRule |
41 |
|
|
{ |
42 |
|
|
int _ref[4]; |
43 |
|
|
double _delta; |
44 |
|
|
std::string _s; |
45 |
|
|
OBSmartsPattern* _sp; |
46 |
|
|
std::vector<double> _vals; |
47 |
|
|
public: |
48 |
|
|
|
49 |
|
|
OBRotorRule(char *buffer,int ref[4],std::vector<double> &vals,double d): |
50 |
|
|
_delta(d), _s(buffer), _vals(vals) |
51 |
|
|
{ |
52 |
|
|
_sp = new OBSmartsPattern; |
53 |
|
|
_sp->Init(buffer); |
54 |
|
|
memcpy(_ref,ref,sizeof(int)*4); |
55 |
|
|
} |
56 |
|
|
~OBRotorRule() |
57 |
|
|
{ |
58 |
|
|
if (_sp) |
59 |
|
|
{ |
60 |
|
|
delete _sp; |
61 |
|
|
_sp = NULL; |
62 |
|
|
} |
63 |
|
|
} |
64 |
|
|
|
65 |
|
|
bool IsValid() { return(_sp->IsValid()); } |
66 |
|
|
void GetReferenceAtoms(int ref[4]) { memcpy(ref,_ref,sizeof(int)*4); } |
67 |
|
|
void SetDelta(double d) { _delta = d; } |
68 |
|
|
double GetDelta() { return(_delta); } |
69 |
|
|
std::string &GetSmartsString(){ return(_s); } |
70 |
|
|
std::vector<double> &GetTorsionVals() { return(_vals); } |
71 |
|
|
OBSmartsPattern *GetSmartsPattern() { return(_sp); } |
72 |
|
|
}; |
73 |
|
|
|
74 |
|
|
//! Database of default hybridization torsional rules and SMARTS-defined OBRotorRule objects |
75 |
|
|
class OBAPI OBRotorRules : public OBGlobalDataBase |
76 |
|
|
{ |
77 |
|
|
bool _quiet; |
78 |
|
|
std::vector<OBRotorRule*> _vr; |
79 |
|
|
std::vector<double> _sp3sp3; |
80 |
|
|
std::vector<double> _sp3sp2; |
81 |
|
|
std::vector<double> _sp2sp2; |
82 |
|
|
public: |
83 |
|
|
OBRotorRules(); |
84 |
|
|
~OBRotorRules(); |
85 |
|
|
|
86 |
|
|
void ParseLine(const char*); |
87 |
|
|
//! \return the number of rotor rules |
88 |
|
|
unsigned int GetSize() { return _vr.size();} |
89 |
|
|
|
90 |
|
|
//! Set the filename to be used for the database. Default = torlib.txt |
91 |
|
|
void SetFilename(std::string &s) { _filename = s; } |
92 |
|
|
|
93 |
|
|
void GetRotorIncrements(OBMol&,OBBond*,int [4],std::vector<double>&,double &delta); |
94 |
|
|
void Quiet() { _quiet=true; } |
95 |
|
|
}; |
96 |
|
|
|
97 |
|
|
//! A single rotatable OBBond as part of rotomer searching |
98 |
|
|
class OBAPI OBRotor |
99 |
|
|
{ |
100 |
|
|
int _idx,_ref[4]; |
101 |
|
|
int *_rotatoms,_size,_numcoords; |
102 |
|
|
double _delta; |
103 |
|
|
double _imag,_refang; |
104 |
|
|
OBBond *_bond; |
105 |
|
|
std::vector<int> _torsion; |
106 |
|
|
OBBitVec _fixedatoms,_evalatoms; |
107 |
|
|
std::vector<double> _res; //!< torsion resolution |
108 |
|
|
std::vector<double> _invmag; |
109 |
|
|
std::vector<std::vector<double> > _sn,_cs,_t; |
110 |
|
|
public: |
111 |
|
|
OBRotor(); |
112 |
|
|
~OBRotor() |
113 |
|
|
{ |
114 |
|
|
if (_rotatoms) |
115 |
|
|
delete [] _rotatoms; |
116 |
|
|
} |
117 |
|
|
int Size() |
118 |
|
|
{ |
119 |
|
|
return((_res.empty())?0:_res.size()); |
120 |
|
|
} |
121 |
|
|
int GetIdx() const |
122 |
|
|
{ |
123 |
|
|
return(_idx); |
124 |
|
|
} |
125 |
|
|
void SetNumCoords(int nc) |
126 |
|
|
{ |
127 |
|
|
_numcoords = nc; |
128 |
|
|
} |
129 |
|
|
void SetBond(OBBond *bond) |
130 |
|
|
{ |
131 |
|
|
_bond = bond; |
132 |
|
|
} |
133 |
|
|
void SetEvalAtoms(OBBitVec &bv) |
134 |
|
|
{ |
135 |
|
|
_evalatoms = bv; |
136 |
|
|
} |
137 |
|
|
void SetDihedralAtoms(std::vector<int> &vi) |
138 |
|
|
{ |
139 |
|
|
_torsion = vi; |
140 |
|
|
} |
141 |
|
|
void SetDelta(double d) |
142 |
|
|
{ |
143 |
|
|
_delta = d; |
144 |
|
|
} |
145 |
|
|
void SetDihedralAtoms(int ref[4]); |
146 |
|
|
void SetRotAtoms(std::vector<int>&); |
147 |
|
|
inline void SetToAngle(double *c,double setang) |
148 |
|
|
{ |
149 |
|
|
double dx,dy,dz,sn,cs,t,ang,mag; |
150 |
|
|
ang = setang - CalcTorsion(c); |
151 |
|
|
if (fabs(ang) < 1e-5) |
152 |
|
|
return; |
153 |
|
|
|
154 |
|
|
sn = sin(ang); |
155 |
|
|
cs = cos(ang); |
156 |
|
|
t = 1 - cs; |
157 |
|
|
dx = c[_torsion[1]] - c[_torsion[2]]; |
158 |
|
|
dy = c[_torsion[1]+1] - c[_torsion[2]+1]; |
159 |
|
|
dz = c[_torsion[1]+2] - c[_torsion[2]+2]; |
160 |
|
|
mag = sqrt(SQUARE(dx) + SQUARE(dy) + SQUARE(dz)); |
161 |
|
|
Set(c,sn,cs,t,1.0/mag); |
162 |
|
|
} |
163 |
|
|
void SetRotor(double *,int,int prev=-1); |
164 |
|
|
void Set(double*,int); |
165 |
|
|
void Precompute(double*); |
166 |
|
|
void Set(double *c,int ridx,int cidx) |
167 |
|
|
{ |
168 |
|
|
Set(c,_sn[cidx][ridx],_cs[cidx][ridx],_t[cidx][ridx],_invmag[cidx]); |
169 |
|
|
} |
170 |
|
|
void Set(double*,double,double,double,double); |
171 |
|
|
void Precalc(std::vector<double*>&); |
172 |
|
|
void SetIdx(int idx) |
173 |
|
|
{ |
174 |
|
|
_idx = idx; |
175 |
|
|
} |
176 |
|
|
void SetFixedAtoms(OBBitVec &bv) |
177 |
|
|
{ |
178 |
|
|
_fixedatoms = bv; |
179 |
|
|
} |
180 |
|
|
void SetTorsionValues(std::vector<double> &tmp) |
181 |
|
|
{ |
182 |
|
|
_res = tmp; |
183 |
|
|
} |
184 |
|
|
void RemoveSymTorsionValues(int); |
185 |
|
|
void GetDihedralAtoms(int ref[4]) |
186 |
|
|
{ |
187 |
|
|
for (int i=0;i<4;i++) |
188 |
|
|
ref[i]=_ref[i]; |
189 |
|
|
} |
190 |
|
|
void *GetRotAtoms() |
191 |
|
|
{ |
192 |
|
|
return(_rotatoms); |
193 |
|
|
} |
194 |
|
|
double CalcTorsion(double *); |
195 |
|
|
double CalcBondLength(double*); |
196 |
|
|
double GetDelta() |
197 |
|
|
{ |
198 |
|
|
return(_delta); |
199 |
|
|
} |
200 |
|
|
OBBond *GetBond() |
201 |
|
|
{ |
202 |
|
|
return(_bond); |
203 |
|
|
} |
204 |
|
|
std::vector<int> &GetDihedralAtoms() |
205 |
|
|
{ |
206 |
|
|
return(_torsion); |
207 |
|
|
} |
208 |
|
|
std::vector<double> &GetResolution() |
209 |
|
|
{ |
210 |
|
|
return(_res); |
211 |
|
|
} |
212 |
|
|
std::vector<double>::iterator BeginTorIncrement() |
213 |
|
|
{ |
214 |
|
|
return(_res.begin()); |
215 |
|
|
} |
216 |
|
|
std::vector<double>::iterator EndTorIncrement() |
217 |
|
|
{ |
218 |
|
|
return(_res.end()); |
219 |
|
|
} |
220 |
|
|
OBBitVec &GetEvalAtoms() |
221 |
|
|
{ |
222 |
|
|
return(_evalatoms); |
223 |
|
|
} |
224 |
|
|
OBBitVec &GetFixedAtoms() |
225 |
|
|
{ |
226 |
|
|
return(_fixedatoms); |
227 |
|
|
} |
228 |
|
|
}; |
229 |
|
|
|
230 |
|
|
//! Given an OBMol, set up a list of possibly rotatable torsions, |
231 |
|
|
class OBAPI OBRotorList |
232 |
|
|
{ |
233 |
|
|
bool _quiet,_removesym; |
234 |
|
|
OBBitVec _fix; |
235 |
|
|
OBRotorRules _rr; |
236 |
|
|
std::vector<int> _dffv; //!< distance from fixed |
237 |
|
|
std::vector<OBRotor*> _rotor; |
238 |
|
|
std::vector<std::pair<OBSmartsPattern*,std::pair<int,int> > > _vsym2; |
239 |
|
|
std::vector<std::pair<OBSmartsPattern*,std::pair<int,int> > > _vsym3; |
240 |
|
|
public: |
241 |
|
|
OBRotorList(); |
242 |
|
|
~OBRotorList(); |
243 |
|
|
|
244 |
|
|
int Size() |
245 |
|
|
{ |
246 |
|
|
return((_rotor.empty()) ? 0: _rotor.size()); |
247 |
|
|
} |
248 |
|
|
void Init(std::string &fname) |
249 |
|
|
{ |
250 |
|
|
_rr.SetFilename(fname); |
251 |
|
|
_rr.Init(); |
252 |
|
|
} |
253 |
|
|
void SetFixAtoms(OBBitVec &fix) |
254 |
|
|
{ |
255 |
|
|
_fix = fix; |
256 |
|
|
} |
257 |
|
|
void SetQuiet() |
258 |
|
|
{ |
259 |
|
|
_quiet=true; |
260 |
|
|
_rr.Quiet(); |
261 |
|
|
} |
262 |
|
|
void IgnoreSymmetryRemoval() |
263 |
|
|
{ |
264 |
|
|
_removesym=false; |
265 |
|
|
} |
266 |
|
|
void Clear(); |
267 |
|
|
void RemoveSymVals(OBMol&); |
268 |
|
|
void SetRotAtomsByFix(OBMol&); |
269 |
|
|
bool SetRotAtoms(OBMol&); |
270 |
|
|
bool Setup(OBMol &); |
271 |
|
|
bool FindRotors(OBMol &); |
272 |
|
|
bool IdentifyEvalAtoms(OBMol &); |
273 |
|
|
bool SetEvalAtoms(OBMol&); |
274 |
|
|
bool AssignTorVals(OBMol &); |
275 |
|
|
bool IsFixedBond(OBBond*); |
276 |
|
|
bool HasFixedAtoms() |
277 |
|
|
{ |
278 |
|
|
return(!_fix.Empty()); |
279 |
|
|
} |
280 |
|
|
OBRotor *BeginRotor(std::vector<OBRotor*>::iterator &i) |
281 |
|
|
{ |
282 |
|
|
i = _rotor.begin(); |
283 |
|
|
return((i ==_rotor.end()) ? NULL:*i); |
284 |
|
|
} |
285 |
|
|
OBRotor *NextRotor(std::vector<OBRotor*>::iterator &i) |
286 |
|
|
{ |
287 |
|
|
i++; |
288 |
|
|
return((i ==_rotor.end()) ? NULL:*i); |
289 |
|
|
} |
290 |
|
|
std::vector<OBRotor*>::iterator BeginRotors() |
291 |
|
|
{ |
292 |
|
|
return(_rotor.begin()); |
293 |
|
|
} |
294 |
|
|
std::vector<OBRotor*>::iterator EndRotors() |
295 |
|
|
{ |
296 |
|
|
return(_rotor.end()); |
297 |
|
|
} |
298 |
|
|
}; |
299 |
|
|
|
300 |
|
|
} // end namespace OpenBabel |
301 |
|
|
|
302 |
|
|
#ifndef SQUARE |
303 |
|
|
#define SQUARE(x) ((x)*(x)) |
304 |
|
|
#endif |
305 |
|
|
|
306 |
|
|
#endif // OB_ROTOR_H |
307 |
|
|
|
308 |
|
|
//! \file rotor.h |
309 |
|
|
//! \brief Rotate torsional according to rotor rules. |