00001 /********************************************************************** 00002 rotor.h - Rotate torsional according to rotor rules. 00003 00004 Copyright (C) 1998-2000 by OpenEye Scientific Software, Inc. 00005 Some portions Copyright (C) 2001-2005 by Geoffrey R. Hutchison 00006 00007 This file is part of the Open Babel project. 00008 For more information, see <http://openbabel.sourceforge.net/> 00009 00010 This program is free software; you can redistribute it and/or modify 00011 it under the terms of the GNU General Public License as published by 00012 the Free Software Foundation version 2 of the License. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 ***********************************************************************/ 00019 00020 #ifndef OB_ROTOR_H 00021 #define OB_ROTOR_H 00022 00023 #include <openbabel/parsmart.h> 00024 #include <openbabel/typer.h> 00025 00026 namespace OpenBabel 00027 { 00028 00029 #ifndef SQUARE 00030 #define SQUARE(x) ((x)*(x)) 00031 #endif 00032 00040 class OBAPI OBRotorRule 00041 { 00042 int _ref[4]; 00043 double _delta; 00044 std::string _s; 00045 OBSmartsPattern* _sp; 00046 std::vector<double> _vals; 00047 public: 00048 00049 OBRotorRule(char *buffer,int ref[4],std::vector<double> &vals,double d): 00050 _delta(d), _s(buffer), _vals(vals) 00051 { 00052 _sp = new OBSmartsPattern; 00053 _sp->Init(buffer); 00054 memcpy(_ref,ref,sizeof(int)*4); 00055 } 00056 00057 ~OBRotorRule() 00058 { 00059 if (_sp) 00060 { 00061 delete _sp; 00062 _sp = NULL; 00063 } 00064 } 00065 00067 bool IsValid() { return(_sp->IsValid()); } 00071 void GetReferenceAtoms(int ref[4]) { memcpy(ref,_ref,sizeof(int)*4); } 00073 void SetDelta(double d) { _delta = d; } 00075 double GetDelta() { return(_delta); } 00077 std::vector<double> &GetTorsionVals() { return(_vals); } 00079 std::string &GetSmartsString(){ return(_s); } 00081 OBSmartsPattern *GetSmartsPattern() { return(_sp); } 00082 }; 00083 00090 class OBAPI OBRotorRules : public OBGlobalDataBase 00091 { 00092 bool _quiet; 00093 std::vector<OBRotorRule*> _vr; 00094 std::vector<double> _sp3sp3; 00095 std::vector<double> _sp3sp2; 00096 std::vector<double> _sp2sp2; 00097 public: 00098 OBRotorRules(); 00099 ~OBRotorRules(); 00100 00101 void ParseLine(const char*); 00103 unsigned int GetSize() { return _vr.size();} 00104 00106 void SetFilename(std::string &s) { _filename = s; } 00107 00114 void GetRotorIncrements(OBMol& mol,OBBond* bond,int refs[4], 00115 std::vector<double> &vals,double &delta); 00117 void Quiet() { _quiet=true; } 00118 }; 00119 00122 class OBAPI OBRotor 00123 { 00124 int _idx,_ref[4]; 00125 int *_rotatoms,_size,_numcoords; 00126 double _delta; 00127 double _imag,_refang; 00128 OBBond *_bond; 00129 std::vector<int> _torsion; 00130 OBBitVec _fixedatoms,_evalatoms; 00131 std::vector<double> _res; 00132 std::vector<double> _invmag; 00133 std::vector<std::vector<double> > _sn,_cs,_t; 00134 public: 00135 OBRotor(); 00136 ~OBRotor() 00137 { 00138 if (_rotatoms) 00139 delete [] _rotatoms; 00140 } 00141 int Size() 00142 { 00143 return((_res.empty())?0:_res.size()); 00144 } 00145 int GetIdx() const 00146 { 00147 return(_idx); 00148 } 00149 void SetNumCoords(int nc) 00150 { 00151 _numcoords = nc; 00152 } 00153 void SetBond(OBBond *bond) 00154 { 00155 _bond = bond; 00156 } 00157 void SetEvalAtoms(OBBitVec &bv) 00158 { 00159 _evalatoms = bv; 00160 } 00161 void SetDihedralAtoms(std::vector<int> &vi) 00162 { 00163 _torsion = vi; 00164 } 00165 void SetDelta(double d) 00166 { 00167 _delta = d; 00168 } 00169 void SetDihedralAtoms(int ref[4]); 00170 void SetRotAtoms(std::vector<int>&); 00171 00172 inline void SetToAngle(double *c,double setang) 00173 { 00174 double dx,dy,dz,sn,cs,t,ang,mag; 00175 ang = setang - CalcTorsion(c); 00176 if (fabs(ang) < 1e-5) 00177 return; 00178 00179 sn = sin(ang); 00180 cs = cos(ang); 00181 t = 1 - cs; 00182 dx = c[_torsion[1]] - c[_torsion[2]]; 00183 dy = c[_torsion[1]+1] - c[_torsion[2]+1]; 00184 dz = c[_torsion[1]+2] - c[_torsion[2]+2]; 00185 mag = sqrt(SQUARE(dx) + SQUARE(dy) + SQUARE(dz)); 00186 Set(c,sn,cs,t,1.0/mag); 00187 } 00188 00189 void SetRotor(double *,int,int prev=-1); 00190 void Set(double*,int); 00191 void Precompute(double*); 00192 void Set(double *c,int ridx,int cidx) 00193 { 00194 Set(c,_sn[cidx][ridx],_cs[cidx][ridx],_t[cidx][ridx],_invmag[cidx]); 00195 } 00196 void Set(double*,double,double,double,double); 00197 void Precalc(std::vector<double*>&); 00198 void SetIdx(int idx) 00199 { 00200 _idx = idx; 00201 } 00202 void SetFixedAtoms(OBBitVec &bv) 00203 { 00204 _fixedatoms = bv; 00205 } 00206 void SetTorsionValues(std::vector<double> &tmp) 00207 { 00208 _res = tmp; 00209 } 00210 void RemoveSymTorsionValues(int); 00211 void GetDihedralAtoms(int ref[4]) 00212 { 00213 for (int i=0;i<4;++i) 00214 ref[i]=_ref[i]; 00215 } 00216 void *GetRotAtoms() 00217 { 00218 return(_rotatoms); 00219 } 00220 double CalcTorsion(double *); 00221 double CalcBondLength(double*); 00222 double GetDelta() 00223 { 00224 return(_delta); 00225 } 00226 OBBond *GetBond() 00227 { 00228 return(_bond); 00229 } 00230 std::vector<int> &GetDihedralAtoms() 00231 { 00232 return(_torsion); 00233 } 00234 std::vector<double> &GetResolution() 00235 { 00236 return(_res); 00237 } 00238 std::vector<double>::iterator BeginTorIncrement() 00239 { 00240 return(_res.begin()); 00241 } 00242 std::vector<double>::iterator EndTorIncrement() 00243 { 00244 return(_res.end()); 00245 } 00246 OBBitVec &GetEvalAtoms() 00247 { 00248 return(_evalatoms); 00249 } 00250 OBBitVec &GetFixedAtoms() 00251 { 00252 return(_fixedatoms); 00253 } 00254 }; 00255 00256 00258 typedef std::vector<OBRotor*>::iterator OBRotorIterator; 00259 00262 class OBAPI OBRotorList 00263 { 00264 bool _quiet; 00265 bool _removesym; 00266 OBBitVec _fix; 00267 OBRotorRules _rr; 00268 std::vector<int> _dffv; 00269 std::vector<OBRotor*> _rotor; 00270 00271 std::vector<std::pair<OBSmartsPattern*,std::pair<int,int> > > _vsym2; 00273 std::vector<std::pair<OBSmartsPattern*,std::pair<int,int> > > _vsym3; 00274 public: 00275 00276 OBRotorList(); 00277 ~OBRotorList(); 00278 00280 void Clear(); 00281 00283 int Size() 00284 { 00285 return((_rotor.empty()) ? 0: _rotor.size()); 00286 } 00288 void Init(std::string &fname) 00289 { 00290 _rr.SetFilename(fname); 00291 _rr.Init(); 00292 } 00294 void SetQuiet() { _quiet=true; _rr.Quiet(); } 00295 00297 void SetFixAtoms(OBBitVec &fix) { _fix = fix; } 00298 00301 bool IsFixedBond(OBBond*); 00303 bool HasFixedAtoms() 00304 { 00305 return(!_fix.Empty()); 00306 } 00307 00311 void SetRotAtomsByFix(OBMol&); 00312 00317 bool SetRotAtoms(OBMol&); 00318 00322 bool Setup(OBMol &); 00326 bool FindRotors(OBMol &); 00330 bool SetEvalAtoms(OBMol&); 00333 bool AssignTorVals(OBMol &); 00334 00337 void IgnoreSymmetryRemoval() { _removesym = false;} 00341 void RemoveSymVals(OBMol&); 00342 00344 00345 OBRotor *BeginRotor(OBRotorIterator &i) 00346 { i = _rotor.begin(); return((i ==_rotor.end()) ? NULL:*i); } 00347 OBRotor *NextRotor(OBRotorIterator &i) 00348 { ++i; return((i ==_rotor.end()) ? NULL:*i); } 00349 OBRotorIterator BeginRotors() { return(_rotor.begin()); } 00350 OBRotorIterator EndRotors() { return(_rotor.end()); } 00352 00353 // Not declared 00355 bool IdentifyEvalAtoms(OBMol &mol) { return SetEvalAtoms(mol); } 00356 }; 00357 00359 class rotor_digit { 00360 public: 00361 rotor_digit(unsigned int rs) 00362 { 00363 resolution_size = rs; 00364 state = 0; 00365 } 00366 00367 rotor_digit() 00368 { 00369 resolution_size = 0; 00370 state = 0; 00371 } 00372 00373 void set_size(unsigned int rs) 00374 { 00375 resolution_size = rs; 00376 state = 0; 00377 } 00378 00379 void set_state(int st) 00380 { 00381 state = st; 00382 } 00383 00384 int get_state() 00385 { 00386 return state; 00387 } 00388 00389 unsigned int size() 00390 { 00391 return resolution_size; 00392 } 00393 00394 bool next() 00395 { 00396 if (state<resolution_size - 1) { 00397 state++; 00398 return false; 00399 } else 00400 state = 0; 00401 00402 return true; 00403 } 00404 private: 00405 unsigned int resolution_size; 00406 int state; 00407 } typedef rotor_digit; 00409 00412 class OBAPI OBRotorKeys 00413 { 00459 public: 00461 OBRotorKeys() 00462 { 00463 _vr.clear(); 00464 } 00465 00467 void Clear(){ 00468 _vr.clear(); 00469 } 00470 00472 unsigned int NumKeys() 00473 { 00474 unsigned int numKeys = 0; 00475 00476 while (Next()) 00477 numKeys++; 00478 00479 return numKeys; 00480 } 00481 00484 void AddRotor(unsigned int size) 00485 { 00486 rotor_digit *rd; 00487 rd = new rotor_digit(size); 00488 _vr.push_back(*rd); 00489 } 00490 00493 bool Next() 00494 { 00495 if(_vr.size() == 0) 00496 return false; 00497 00498 bool carry = _vr[0].next(); 00499 unsigned int i = 1; 00500 while (carry) { 00501 if(i == _vr.size()) 00502 return false; 00503 00504 carry = _vr[i].next(); 00505 i++; 00506 } 00507 return true; 00508 } 00509 00512 std::vector<int> GetKey() 00513 { 00514 std::vector<int> rt; 00515 rt.clear(); 00516 rt.push_back(0); 00517 for(unsigned int i = 0; i < _vr.size(); i++){ 00518 rt.push_back(_vr[i].get_state()); 00519 } 00520 00521 return rt; 00522 } 00523 00524 private: 00525 std::vector<rotor_digit> _vr; 00526 }; 00527 00528 00529 } // end namespace OpenBabel 00530 00531 #endif // OB_ROTOR_H 00532
This file is part of the documentation for Open Babel, version 2.2.0.