1 |
/********************************************************************** |
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. |