mol.h
Go to the documentation of this file.
00001 /********************************************************************** 00002 mol.h - Handle molecules. Declarations of OBMol, OBAtom, OBBond, OBResidue. 00003 (the main header for Open Babel) 00004 00005 Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc. 00006 Some portions Copyright (C) 2001-2006 by Geoffrey R. Hutchison 00007 Some portions Copyright (C) 2003 by Michael Banck 00008 00009 This file is part of the Open Babel project. 00010 For more information, see <http://openbabel.org/> 00011 00012 This program is free software; you can redistribute it and/or modify 00013 it under the terms of the GNU General Public License as published by 00014 the Free Software Foundation version 2 of the License. 00015 00016 This program is distributed in the hope that it will be useful, 00017 but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 GNU General Public License for more details. 00020 ***********************************************************************/ 00021 00022 #ifndef OB_MOL_H 00023 #define OB_MOL_H 00024 00025 #include <openbabel/babelconfig.h> 00026 00027 #ifndef EXTERN 00028 # define EXTERN extern 00029 #endif 00030 00031 #include <math.h> 00032 #include <float.h> 00033 00034 #include <vector> 00035 #include <string> 00036 #include <map> 00037 00038 // Currently includes many headers for 2.x backwards compatibility 00039 // \deprecated -- this will be cleaned up in 3.0 efforts 00040 // to improve compile time significantly. 00041 // Only include necessary headers and class declaration stubs. 00042 #include <openbabel/atom.h> 00043 #include <openbabel/bond.h> 00044 #include <openbabel/base.h> 00045 #include <openbabel/data.h> 00046 #include <openbabel/chains.h> 00047 #include <openbabel/math/vector3.h> 00048 #include <openbabel/bitvec.h> 00049 #include <openbabel/residue.h> 00050 #include <openbabel/ring.h> 00051 #include <openbabel/generic.h> 00052 #include <openbabel/typer.h> 00053 #include <openbabel/oberror.h> 00054 #include <openbabel/obiter.h> 00055 #include <openbabel/internalcoord.h> 00056 00057 namespace OpenBabel 00058 { 00059 00060 class OBAtom; 00061 class OBBond; 00062 class OBInternalCoord; 00063 class OBConversion; //used only as a pointer 00064 00065 // Class OBMol 00066 //MOL Property Macros (flags) -- 32+ bits 00068 #define OB_SSSR_MOL (1<<1) 00069 00070 #define OB_RINGFLAGS_MOL (1<<2) 00071 00072 #define OB_AROMATIC_MOL (1<<3) 00073 00074 #define OB_ATOMTYPES_MOL (1<<4) 00075 00076 #define OB_CHIRALITY_MOL (1<<5) 00077 00078 #define OB_PCHARGE_MOL (1<<6) 00079 00080 #define OB_HYBRID_MOL (1<<8) 00081 00082 #define OB_IMPVAL_MOL (1<<9) 00083 00084 #define OB_KEKULE_MOL (1<<10) 00085 00086 #define OB_CLOSURE_MOL (1<<11) 00087 00088 #define OB_H_ADDED_MOL (1<<12) 00089 00090 #define OB_PH_CORRECTED_MOL (1<<13) 00091 00092 #define OB_AROM_CORRECTED_MOL (1<<14) 00093 00094 #define OB_CHAINS_MOL (1<<15) 00095 00096 #define OB_TCHARGE_MOL (1<<16) 00097 00098 #define OB_TSPIN_MOL (1<<17) 00099 00100 #define OB_RINGTYPES_MOL (1<<18) 00101 00102 #define OB_PATTERN_STRUCTURE (1<<19) 00103 00104 #define OB_LSSR_MOL (1<<20) 00105 00106 #define OB_ATOMSPIN_MOL (1<<21) 00107 // flags 22-32 unspecified 00108 #define OB_CURRENT_CONFORMER -1 00109 00110 // class introduction in mol.cpp 00111 class OBAPI OBMol: public OBBase 00112 { 00113 protected: 00114 int _flags; 00115 bool _autoPartialCharge; 00116 bool _autoFormalCharge; 00117 std::string _title; 00118 std::vector<OBAtom*> _vatom; 00119 std::vector<OBAtom*> _atomIds; 00120 std::vector<OBBond*> _vbond; 00121 std::vector<OBBond*> _bondIds; 00122 unsigned short int _dimension; 00123 int _totalCharge; 00124 unsigned int _totalSpin; 00125 double *_c; 00126 std::vector<double*> _vconf; 00127 double _energy; 00128 unsigned int _natoms; 00129 unsigned int _nbonds; 00130 std::vector<OBResidue*> _residue; 00131 std::vector<OBInternalCoord*> _internals; 00132 unsigned short int _mod; 00133 00134 bool HasFlag(int flag) { return((_flags & flag) ? true : false); } 00135 void SetFlag(int flag) { _flags |= flag; } 00136 00138 00139 void start_kekulize(std::vector <OBAtom*> &cycle, std::vector<int> &electron); 00140 bool expand_kekulize(int bond_idx, std::vector<int> &atomState, std::vector<int> &bondState); 00141 bool has_no_leftover_electrons(std::vector<int> &atomState); 00142 int getorden(OBAtom *atom); 00143 bool expandcycle(OBAtom *atom, OBBitVec &avisit, const OBBitVec &potAromBonds); 00145 00146 public: 00147 00149 00150 00151 OBMol(); 00153 OBMol(const OBMol &); 00155 virtual ~OBMol(); 00157 OBMol &operator=(const OBMol &mol); 00159 OBMol &operator+=(const OBMol &mol); 00160 00163 void ReserveAtoms(int natoms) 00164 { 00165 if (natoms > 0 && _mod) { 00166 _vatom.reserve(natoms); 00167 _atomIds.reserve(natoms); 00168 } 00169 } 00170 00173 virtual OBAtom *CreateAtom(void); 00176 virtual OBBond *CreateBond(void); 00179 virtual OBResidue *CreateResidue(void); 00182 virtual void DestroyAtom(OBAtom*); 00185 virtual void DestroyBond(OBBond*); 00188 virtual void DestroyResidue(OBResidue*); 00189 00192 bool AddAtom(OBAtom&); 00195 bool InsertAtom(OBAtom &); 00203 bool AddBond(int beginIdx, int endIdx, int order, 00204 int flags=0,int insertpos=-1); 00207 bool AddBond(OBBond&); 00210 bool AddResidue(OBResidue&); 00211 00215 OBAtom *NewAtom(); 00219 OBAtom *NewAtom(unsigned long id); 00223 OBBond *NewBond(); 00227 OBBond *NewBond(unsigned long id); 00229 OBResidue *NewResidue(); 00234 bool DeleteAtom(OBAtom*, bool destroyAtom = true); 00237 bool DeleteBond(OBBond*, bool destroyBond = true); 00240 bool DeleteResidue(OBResidue*, bool destroyResidue = true); 00242 00244 00245 00246 00247 00248 virtual void BeginModify(void); 00252 virtual void EndModify(bool nukePerceivedData=true); 00254 int GetMod() { return(_mod); } 00257 void IncrementMod() { _mod++; } 00260 void DecrementMod() { _mod--; } 00262 00264 00265 00266 int GetFlags() { return(_flags); } 00269 const char *GetTitle(bool replaceNewlines = true) const; 00271 unsigned int NumAtoms() const { return(_natoms); } 00273 unsigned int NumBonds() const { return(_nbonds); } 00275 unsigned int NumHvyAtoms(); 00277 unsigned int NumResidues() const { return(static_cast<unsigned int> (_residue.size())); } 00279 unsigned int NumRotors(); 00280 00283 OBAtom *GetAtom(int idx) const; 00285 OBAtom *GetAtomById(unsigned long id) const; 00288 OBAtom *GetFirstAtom() const; 00291 OBBond *GetBond(int idx) const; 00293 OBBond *GetBondById(unsigned long id) const; 00296 OBBond *GetBond(int a, int b) const; 00297 // The safer version of the above method 00299 OBBond *GetBond(OBAtom* bgn, OBAtom* end) const; 00302 OBResidue *GetResidue(int idx) const; 00303 std::vector<OBInternalCoord*> GetInternalCoord(); 00308 double GetTorsion(int,int,int,int); 00313 double GetTorsion(OBAtom* a,OBAtom* b,OBAtom* c,OBAtom* d); 00316 double GetAngle(OBAtom* a, OBAtom* b, OBAtom* c); 00318 std::string GetFormula(); 00320 std::string GetSpacedFormula(int ones=0, const char* sp=" ", bool implicitH = true); 00322 double GetEnergy() const { return _energy; } 00324 double GetMolWt(bool implicitH = true); 00326 double GetExactMass(bool implicitH = true); 00328 int GetTotalCharge(); 00330 unsigned int GetTotalSpinMultiplicity(); 00332 unsigned short int GetDimension() const { return _dimension; } 00334 double *GetCoordinates() { return(_c); } 00336 std::vector<OBRing*> &GetSSSR(); 00338 std::vector<OBRing*> &GetLSSR(); 00340 bool AutomaticFormalCharge() { return(_autoFormalCharge); } 00342 bool AutomaticPartialCharge() { return(_autoPartialCharge); } 00344 00345 00347 00348 00349 void SetTitle(const char *title); 00351 void SetTitle(std::string &title); 00353 void SetFormula(std::string molFormula); 00355 void SetEnergy(double energy) { _energy = energy; } 00357 void SetDimension(unsigned short int d) { _dimension = d; } 00359 void SetTotalCharge(int charge); 00362 void SetTotalSpinMultiplicity(unsigned int spinMultiplicity); 00368 void SetInternalCoord(std::vector<OBInternalCoord*> int_coord); 00370 void SetAutomaticFormalCharge(bool val) 00371 { _autoFormalCharge=val; } 00373 void SetAutomaticPartialCharge(bool val) 00374 { _autoPartialCharge=val; } 00375 00377 void SetAromaticPerceived() { SetFlag(OB_AROMATIC_MOL); } 00379 void SetSSSRPerceived() { SetFlag(OB_SSSR_MOL); } 00381 void SetLSSRPerceived() { SetFlag(OB_LSSR_MOL); } 00383 void SetRingAtomsAndBondsPerceived(){SetFlag(OB_RINGFLAGS_MOL);} 00385 void SetAtomTypesPerceived() { SetFlag(OB_ATOMTYPES_MOL); } 00387 void SetRingTypesPerceived() { SetFlag(OB_RINGTYPES_MOL); } 00389 void SetChainsPerceived() { SetFlag(OB_CHAINS_MOL); } 00391 void SetChiralityPerceived() { SetFlag(OB_CHIRALITY_MOL); } 00393 void SetPartialChargesPerceived(){ SetFlag(OB_PCHARGE_MOL); } 00395 void SetHybridizationPerceived() { SetFlag(OB_HYBRID_MOL); } 00397 void SetImplicitValencePerceived(){ SetFlag(OB_IMPVAL_MOL); } 00399 void SetKekulePerceived() { SetFlag(OB_KEKULE_MOL); } 00401 void SetClosureBondsPerceived(){ SetFlag(OB_CLOSURE_MOL); } 00403 void SetHydrogensAdded() { SetFlag(OB_H_ADDED_MOL); } 00404 void SetCorrectedForPH() { SetFlag(OB_PH_CORRECTED_MOL);} 00405 void SetAromaticCorrected() { SetFlag(OB_AROM_CORRECTED_MOL);} 00406 void SetSpinMultiplicityAssigned(){ SetFlag(OB_ATOMSPIN_MOL); } 00407 void SetFlags(int flags) { _flags = flags; } 00408 00409 void UnsetAromaticPerceived() { _flags &= (~(OB_AROMATIC_MOL)); } 00410 void UnsetSSSRPerceived() { _flags &= (~(OB_SSSR_MOL)); } 00412 void UnsetLSSRPerceived() { _flags &= (~(OB_LSSR_MOL)); } 00413 void UnsetRingTypesPerceived() { _flags &= (~(OB_RINGTYPES_MOL)); } 00414 void UnsetPartialChargesPerceived(){ _flags &= (~(OB_PCHARGE_MOL));} 00415 void UnsetImplicitValencePerceived(){_flags &= (~(OB_IMPVAL_MOL)); } 00416 void UnsetHydrogensAdded() { UnsetFlag(OB_H_ADDED_MOL); } 00417 void UnsetFlag(int flag) { _flags &= (~(flag)); } 00419 00421 00422 // Description in transform.cpp (command-line transformations to this molecule) 00423 virtual OBBase* DoTransformations(const std::map<std::string,std::string>* pOptions,OBConversion* pConv); 00424 // Ditto (documentation on transformation options) 00425 static const char* ClassDescription(); 00427 bool Clear(); 00429 void RenumberAtoms(std::vector<OBAtom*>&); 00431 void RenumberAtoms(std::vector<int>); 00434 void SetCoordinates(double *c); 00436 void ToInertialFrame(int conf, double *rmat); 00438 void ToInertialFrame(); 00440 void Translate(const vector3 &v); 00442 void Translate(const vector3 &v, int conf); 00444 void Rotate(const double u[3][3]); 00446 void Rotate(const double m[9]); 00448 void Rotate(const double m[9],int nconf); 00450 void Center(); 00452 00453 bool Kekulize(); 00454 bool PerceiveKekuleBonds(); 00455 00456 void NewPerceiveKekuleBonds(); 00457 00460 bool DeleteHydrogens(); 00463 bool DeleteHydrogens(OBAtom*); 00466 bool DeleteNonPolarHydrogens(); 00469 bool DeleteHydrogen(OBAtom*); 00476 bool AddHydrogens(bool polaronly=false,bool correctForPH=false, double pH=7.4); 00478 bool AddHydrogens(OBAtom*); 00480 bool AddPolarHydrogens(); 00481 00485 bool StripSalts(int threshold=0); 00487 std::vector<OBMol> Separate(int StartIndex=1); 00489 bool GetNextFragment( OpenBabel::OBMolAtomDFSIter& iter, OBMol& newMol ); 00491 bool ConvertDativeBonds(); 00492 00494 bool CorrectForPH(double pH=7.4); 00495 // docs in mol.cpp 00496 bool AssignSpinMultiplicity(bool NoImplicitH=false); 00498 void SetIsPatternStructure() { SetFlag(OB_PATTERN_STRUCTURE);} 00499 00502 vector3 Center(int nconf); 00508 void SetTorsion(OBAtom*,OBAtom*,OBAtom*,OBAtom*,double ang); 00510 00512 00513 00514 void FindSSSR(); 00516 void FindLSSR(); 00518 void FindRingAtomsAndBonds(); 00521 void FindChiralCenters() { IsChiral(); } 00522 // documented in mol.cpp -- locates all atom indexes which can reach 'end' 00523 void FindChildren(std::vector<int> & children,int bgnIdx,int endIdx); 00524 // documented in mol.cpp -- locates all atoms which can reach 'end' 00525 void FindChildren(std::vector<OBAtom*>& children,OBAtom* bgn,OBAtom* end); 00530 void FindLargestFragment(OBBitVec &frag); 00533 void ContigFragList(std::vector<std::vector<int> >&); 00535 void Align(OBAtom*,OBAtom*,vector3&,vector3&); 00537 void ConnectTheDots(); 00539 void PerceiveBondOrders(); 00541 void FindAngles(); 00543 void FindTorsions(); 00544 // documented in mol.cpp: graph-theoretical distance for each atom 00545 bool GetGTDVector(std::vector<int> &); 00546 // documented in mol.cpp: graph-invariant index for each atom 00547 void GetGIVector(std::vector<unsigned int> &); 00548 // documented in mol.cpp: calculate symmetry-unique identifiers 00549 void GetGIDVector(std::vector<unsigned int> &); 00551 00553 00554 00555 bool Has2D(bool Not3D=false); 00557 bool Has3D(); 00559 bool HasNonZeroCoords(); 00561 bool HasAromaticPerceived() { return(HasFlag(OB_AROMATIC_MOL)); } 00563 bool HasSSSRPerceived() { return(HasFlag(OB_SSSR_MOL)); } 00565 bool HasLSSRPerceived() { return(HasFlag(OB_LSSR_MOL)); } 00567 bool HasRingAtomsAndBondsPerceived(){return(HasFlag(OB_RINGFLAGS_MOL));} 00569 bool HasAtomTypesPerceived() { return(HasFlag(OB_ATOMTYPES_MOL));} 00571 bool HasRingTypesPerceived() { return(HasFlag(OB_RINGTYPES_MOL));} 00573 bool HasChiralityPerceived() { return(HasFlag(OB_CHIRALITY_MOL));} 00575 bool HasPartialChargesPerceived() { return(HasFlag(OB_PCHARGE_MOL));} 00577 bool HasHybridizationPerceived() { return(HasFlag(OB_HYBRID_MOL)); } 00579 bool HasImplicitValencePerceived() { return(HasFlag(OB_IMPVAL_MOL));} 00581 bool HasKekulePerceived() { return(HasFlag(OB_KEKULE_MOL)); } 00583 bool HasClosureBondsPerceived() { return(HasFlag(OB_CLOSURE_MOL)); } 00585 bool HasChainsPerceived() { return(HasFlag(OB_CHAINS_MOL)); } 00587 bool HasHydrogensAdded() { return(HasFlag(OB_H_ADDED_MOL)); } 00589 bool HasAromaticCorrected() { return(HasFlag(OB_AROM_CORRECTED_MOL));} 00591 bool IsCorrectedForPH() { return(HasFlag(OB_PH_CORRECTED_MOL)); } 00593 bool HasSpinMultiplicityAssigned() { return(HasFlag(OB_ATOMSPIN_MOL)); } 00595 bool IsChiral(); 00597 bool Empty() { return(_natoms == 0); } 00599 00601 00602 00603 int NumConformers() { return((_vconf.empty())?0:static_cast<int> (_vconf.size())); } 00605 void SetConformers(std::vector<double*> &v); 00607 void AddConformer(double *f) { _vconf.push_back(f); } 00610 void SetConformer(int i); 00613 void CopyConformer(double* c,int nconf); 00615 void DeleteConformer(int nconf); 00617 double *GetConformer(int i) { return(_vconf[i]); } 00619 void SetEnergies(std::vector<double> &energies); 00621 std::vector<double> GetEnergies(); 00624 double GetEnergy(int ci); 00627 double *BeginConformer(std::vector<double*>::iterator&i) 00628 { i = _vconf.begin(); 00629 return((i == _vconf.end()) ? NULL:*i); } 00632 double *NextConformer(std::vector<double*>::iterator&i) 00633 { ++i; 00634 return((i == _vconf.end()) ? NULL:*i); } 00636 std::vector<double*> &GetConformers() { return(_vconf); } 00638 00640 00641 00642 OBAtomIterator BeginAtoms() { return _vatom.begin(); } 00644 OBAtomIterator EndAtoms() { return _vatom.begin() + NumAtoms() ; } 00646 OBBondIterator BeginBonds() { return _vbond.begin(); } 00648 OBBondIterator EndBonds() { return _vbond.begin() + NumBonds() ; } 00650 OBResidueIterator BeginResidues() { return _residue.begin(); } 00652 OBResidueIterator EndResidues() { return _residue.end(); } 00653 00656 OBAtom *BeginAtom(OBAtomIterator &i); 00659 OBAtom *NextAtom(OBAtomIterator &i); 00662 OBBond *BeginBond(OBBondIterator &i); 00665 OBBond *NextBond(OBBondIterator &i); 00668 OBResidue *BeginResidue(OBResidueIterator &i) 00669 { 00670 i = _residue.begin(); 00671 return((i == _residue.end()) ? NULL:*i); 00672 } 00675 OBResidue *NextResidue(OBResidueIterator &i) 00676 { 00677 ++i; 00678 return((i == _residue.end()) ? NULL:*i); 00679 } 00683 OBInternalCoord *BeginInternalCoord(std::vector<OBInternalCoord*>::iterator &i) 00684 { 00685 i = _internals.begin(); 00686 return((i == _internals.end()) ? NULL:*i); 00687 } 00691 OBInternalCoord *NextInternalCoord(std::vector<OBInternalCoord*>::iterator &i) 00692 { 00693 ++i; 00694 return((i == _internals.end()) ? NULL:*i); 00695 } 00697 00698 }; 00699 00700 // Utility function prototypes 00701 //tokenize and Trim declarations moved to base.h 00702 // Deprecated -- use OBMessageHandler class instead (docs in obutil.cpp) 00703 OBAPI void ThrowError(char *str); 00704 // Deprecated -- use OBMessageHandler class instead (docs in obutil.cpp) 00705 OBAPI void ThrowError(std::string &str); 00707 OBAPI void CartesianToInternal(std::vector<OBInternalCoord*>&,OBMol&); 00709 OBAPI void InternalToCartesian(std::vector<OBInternalCoord*>&,OBMol&); 00710 // Replace the last extension in str with a new one (docs in obutil.cpp) 00711 OBAPI std::string NewExtension(std::string&,char*); 00712 00713 //global definitions 00715 EXTERN OBElementTable etab; 00718 EXTERN OBTypeTable ttab; 00720 EXTERN OBIsotopeTable isotab; 00722 EXTERN OBAromaticTyper aromtyper; 00725 EXTERN OBAtomTyper atomtyper; 00727 EXTERN OBChainsParser chainsparser; 00729 OBERROR extern OBMessageHandler obErrorLog; 00731 EXTERN OBResidueData resdat; 00732 00734 namespace detail { 00737 template<typename T, int size = sizeof(T)> 00738 struct max_value 00739 { 00740 static const T result = (static_cast<T>(0xFF) << (size-1)*8) + max_value<T, size-1>::result; 00741 }; 00742 00744 template<typename T> 00745 struct max_value<T, 0> 00746 { 00747 static const T result = 0; 00748 }; 00749 } 00750 00751 // No unique id 00752 static const unsigned long NoId = detail::max_value<unsigned long>::result; 00753 00754 //Utility Macros 00755 00756 #ifndef BUFF_SIZE 00757 #define BUFF_SIZE 32768 00758 #endif 00759 00760 #ifndef EQ 00761 #define EQ(a,b) (!strcmp((a), (b))) 00762 #endif 00763 00764 #ifndef EQn 00765 #define EQn(a,b,n) (!strncmp((a), (b), (n))) 00766 #endif 00767 00768 #ifndef SQUARE 00769 #define SQUARE(x) ((x)*(x)) 00770 #endif 00771 00772 #ifndef IsUnsatType 00773 #define IsUnsatType(x) (EQ(x,"Car") || EQ(x,"C2") || EQ(x,"Sox") || EQ(x,"Sac") || EQ(x,"Pac") || EQ(x,"So2")) 00774 #endif 00775 00776 #ifndef __KCC 00777 extern "C" 00778 { 00779 OBAPI void get_rmat(double*,double*,double*,int); 00780 OBAPI void ob_make_rmat(double mat[3][3],double rmat[9]); 00781 OBAPI void qtrfit (double *r,double *f,int size,double u[3][3]); 00782 OBAPI double superimpose(double*,double*,int); 00783 } 00784 #else 00785 OBAPI void get_rmat(double*,double*,double*,int); 00786 OBAPI void ob_make_rmat(double mat[3][3],double rmat[9]); 00787 OBAPI void qtrfit (double *r,double *f,int size,double u[3][3]); 00788 OBAPI double superimpose(double*,double*,int); 00789 #endif // __KCC 00790 00791 // extern OBMol* (*CreateMolecule) (void); 00792 00793 } // end namespace OpenBabel 00794 00795 #endif // OB_MOL_H 00796